KaliVeda  1.12/06
Heavy-Ion Analysis Toolkit
KVIDLine.h
Go to the documentation of this file.
1 /***************************************************************************
2  KVIDLine.h - description
3  -------------------
4  begin : Nov 10 2004
5  copyright : (C) 2004 by J.D. Frankland
6  email : frankland@ganil.fr
7 
8 $Id: KVIDLine.h,v 1.16 2009/03/03 14:27:15 franklan Exp $
9 ***************************************************************************/
10 
11 #ifndef KVIDLine_H
12 #define KVIDLine_H
13 
14 #include "TVector2.h"
15 #include "TMath.h"
16 #include "TH2.h"
17 #include "KVIDentifier.h"
18 
143 class KVIDLine : public KVIDentifier {
144 
145 public:
146 
147  KVIDLine();
148  KVIDLine(const TGraph& gr);
149  KVIDLine(const KVIDLine&);
150 
151  virtual ~ KVIDLine();
152 
153  virtual void WaitForPrimitive();
154  virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py);
155 
156  inline Double_t DistanceToLine(Double_t px, Double_t py, Int_t&);
157  inline Double_t DistanceToLine(Double_t px, Double_t py, Double_t xp1,
158  Double_t yp1, Double_t xp2, Double_t yp2,
159  Int_t&);
160  inline Bool_t WhereAmI(Double_t px, Double_t py, Option_t* opt);
161  inline Bool_t PosRelToLine(Option_t* opt, Double_t px, Double_t py,
162  Double_t xp1, Double_t yp1, Double_t xp2,
163  Double_t yp2);
164 
165  inline void GetStartPoint(Double_t& x, Double_t& y) const;
166  inline void GetEndPoint(Double_t& x, Double_t& y) const;
168  const Char_t* axis = "") const;
169 
170  static KVIDLine* MakeIDLine(TObject* obj, Double_t xdeb = -1., Double_t xfin = -1., Double_t np = 1., Bool_t save = kFALSE);
172 
173  ClassDef(KVIDLine, 2) //Base class for lines/cuts used for particle identification
174 };
175 
177 
179  Int_t& i_near)
180 {
199 
200  Double_t distance, dist2;
201  Int_t i;
202  Double_t d;
203  distance = dist2 = 9999.;
204  Int_t i_nearest_point = 0, inear1 = 0, inear2 = 0;
208 
209  for (i = 0; i < fNpoints - 1; i++) {
210  d = DistanceToLine(px, py, fX[i], fY[i], fX[i + 1], fY[i + 1],
211  i_nearest_point);
213  if (d >= 0.) {
214  if (d < distance) {
215  distance = d;
216  inear1 = i;
217  }
218  }
219  else {
221  if (-d < dist2) {
222  dist2 = -d;
223  inear2 = i + i_nearest_point;
224  }
225  }
226  }
227 
228  i_near = inear1;
229  if (distance < 9999.)
230  return distance;
231  i_near = inear2;
233  if (inear2 > 0 && inear2 < (fNpoints - 1))
234  return dist2;
236  return -dist2;
237 }
238 
239 
241 
243  Double_t xp1, Double_t yp1,
244  Double_t xp2, Double_t yp2,
245  Int_t& i_nearest_point)
246 {
267 
268  TVector2 P1(xp1, yp1), P2(xp2, yp2), P(px, py);
269  TVector2 P1P2 = P2 - P1;
270  TVector2 P1P = P - P1;
271  TVector2 P2P = P - P2;
272  TVector2 MP = P1P.Norm((P1P2));
273  i_nearest_point = 0;
275  Double_t sum = (P1P - MP).Mod() + (P2P - MP).Mod();
277  if (TMath::Abs(sum - P1P2.Mod()) > 1.e-06) {
279  if (P1P.Mod() < P2P.Mod()) {
280  i_nearest_point = 0;
281  return -(P1P.Mod());
282  }
283  i_nearest_point = 1;
284  return -(P2P.Mod());
285  }
287  return MP.Mod();
288 }
289 
290 
292 
294  Double_t py, Double_t xp1,
295  Double_t yp1, Double_t xp2,
296  Double_t yp2)
297 {
320 
321  TVector2 P1(xp1, yp1), P2(xp2, yp2), P(px, py);
322  TVector2 P1P2 = P2 - P1;
323  TVector2 P1P = P - P1;
324  TVector2 MP = P1P.Norm((P1P2));
325  Double_t phi = MP.Phi() * TMath::RadToDeg();
330  Bool_t result = kFALSE;
331  if (!strcmp(opt, "left")) {
332  result = (phi > 90. && phi < 270.);
333  }
334  else if (!strcmp(opt, "right")) {
335  result = (phi < 90. || phi > 270.);
336  }
337  else if (!strcmp(opt, "above")) {
338  result = (phi > 0. && phi < 180.);
339  }
340  else if (!strcmp(opt, "below")) {
341  result = (phi > 180. && phi < 360.);
342  }
343  return result;
344 }
345 
347 
349 {
356 
357  Double_t* XX, *YY;
358  Double_t xx, yy;
359  Int_t sign = 1;
360 
361  if (!strcmp(opt, "left")) {
362  XX = fY;
363  xx = py;
364  YY = fX;
365  yy = px;
366  }
367  else if (!strcmp(opt, "right")) {
368  XX = fY;
369  xx = py;
370  YY = fX;
371  yy = px;
372  sign = -1;
373  }
374  else if (!strcmp(opt, "above")) {
375  XX = fX;
376  xx = px;
377  YY = fY;
378  yy = py;
379  sign = -1;
380  }
381  else if (!strcmp(opt, "below")) {
382  XX = fX;
383  xx = px;
384  YY = fY;
385  yy = py;
386  }
387  else return kFALSE;
388 
389  Int_t i_start = 0;
390  Int_t i_stop = fNpoints - 1;
391  Int_t prev_i_stop = 0;
392  Bool_t same_sign = TMath::Sign(1., XX[i_start] - xx) == TMath::Sign(1., XX[i_stop] - xx);
393  while ((i_start < i_stop - 1) || same_sign) {
394 
395  if (same_sign && (prev_i_stop == 0)) break;
396  else if (same_sign) {
397  i_start = i_stop;
398  i_stop = prev_i_stop;
399  }
400  else {
401  prev_i_stop = i_stop;
402  i_stop = (Int_t)((i_start + i_stop) / 2 + 0.5);
403  }
404 
405  same_sign = TMath::Sign(1., XX[i_start] - xx) == TMath::Sign(1., XX[i_stop] - xx);
406  }
407 
408  Double_t a = (YY[i_stop] - YY[i_start]) / (XX[i_stop] - XX[i_start]);
409  Double_t b = YY[i_start] - a * XX[i_start];
410 
411  Bool_t res = (sign * yy < sign * (a * xx + b));
412 
413  return res;
414 }
415 
417 
418 inline void KVIDLine::GetStartPoint(Double_t& x, Double_t& y) const
419 {
421 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,3)
422  GetPoint(0, x, y);
423 #else
424  const_cast < KVIDLine* >(this)->GetPoint(0, x, y);
425 #endif
426 }
427 
429 
430 inline void KVIDLine::GetEndPoint(Double_t& x, Double_t& y) const
431 {
433 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,3)
434  GetPoint((GetN() - 1), x, y);
435 #else
436  const_cast < KVIDLine* >(this)->GetPoint((GetN() - 1), x, y);
437 #endif
438 }
439 
441 
443  const Char_t* axis) const
444 {
449 
450  TString ax(axis);
451  ax.ToUpper();
452  Double_t x1, y1, x2, y2;
453  GetStartPoint(x1, y1);
454  GetEndPoint(x2, y2);
455  Double_t xmin = TMath::Min(x1, x2);
456  Double_t xmax = TMath::Max(x1, x2);
457  Double_t ymin = TMath::Min(y1, y2);
458  Double_t ymax = TMath::Max(y1, y2);
459 
460  Bool_t in_range_x = (x <= xmax && x >= xmin);
461  Bool_t in_range_y = (y <= ymax && y >= ymin);
462  if (ax == "X") {
463  return in_range_x;
464  }
465  else if (ax == "Y") {
466  return in_range_y;
467  }
468 
469  return (in_range_x && in_range_y);
470 }
471 
472 #endif
int Int_t
#define d(i)
#define b(i)
char Char_t
const Bool_t kFALSE
bool Bool_t
double Double_t
const char Option_t
#define ClassDef(name, id)
float xmin
float ymin
float xmax
float ymax
Base class for lines/cuts used for particle identification in 2D data maps.
Definition: KVIDLine.h:143
static KVIDLine * MakeIDLine(TObject *obj, Double_t xdeb=-1., Double_t xfin=-1., Double_t np=1., Bool_t save=kFALSE)
Definition: KVIDLine.cpp:88
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Definition: KVIDLine.cpp:226
Bool_t PosRelToLine(Option_t *opt, Double_t px, Double_t py, Double_t xp1, Double_t yp1, Double_t xp2, Double_t yp2)
Definition: KVIDLine.h:293
virtual ~ KVIDLine()
Double_t DistanceToLine(Double_t px, Double_t py, Int_t &)
Definition: KVIDLine.h:178
Bool_t WhereAmI(Double_t px, Double_t py, Option_t *opt)
Definition: KVIDLine.h:348
void GetStartPoint(Double_t &x, Double_t &y) const
Definition: KVIDLine.h:418
Bool_t IsBetweenEndPoints(Double_t x, Double_t y, const Char_t *axis="") const
Definition: KVIDLine.h:442
KVIDLine()
Default ctor.
Definition: KVIDLine.cpp:38
void GetEndPoint(Double_t &x, Double_t &y) const
Definition: KVIDLine.h:430
virtual void WaitForPrimitive()
Definition: KVIDLine.cpp:194
Base class for graphical cuts used in particle identification.
Definition: KVIDentifier.h:27
Int_t fNpoints
Int_t GetN() const
Double_t * fY
Double_t * fX
virtual Int_t GetPoint(Int_t i, Double_t &x, Double_t &y) const
void ToUpper()
Double_t Phi() const
TVector2 Norm(const TVector2 &v) const
Double_t Mod() const
Double_t y[n]
Double_t x[n]
TGraphErrors * gr
Double_t Min(Double_t a, Double_t b)
Double_t Sign(Double_t a, Double_t b)
Double_t Abs(Double_t d)
Double_t Max(Double_t a, Double_t b)
constexpr Double_t RadToDeg()
auto * a