KaliVeda  1.13/01
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"
142 class KVIDLine : public KVIDentifier {
143 
155  class MyVector2 {
156  double x, y;
157  public:
158  MyVector2(double X, double Y) : x(X), y(Y) {}
160  {
161  *this = T;
162  }
164  {
165  if (this != &T) {
166  x = T.x;
167  y = T.y;
168  }
169  return *this;
170  }
171  friend MyVector2 operator-(const MyVector2& a, const MyVector2& b)
172  {
173  return {a.x - b.x, a.y - b.y};
174  }
175  friend double operator*(const MyVector2& a, const MyVector2& b)
176  {
177  return a.x * b.x + a.y * b.y;
178  }
179  friend MyVector2 operator*(const MyVector2& a, double s)
180  {
181  return {a.x * s, a.y * s};
182  }
183  friend MyVector2 operator*(double s, const MyVector2& a)
184  {
185  return a * s;
186  }
187  double Mod2() const
188  {
189  return (*this) * (*this);
190  }
191  double Mod() const
192  {
193  return sqrt(Mod2());
194  }
195  MyVector2 Proj(const MyVector2& v) const
196  {
197  double scalar = v * (*this);
198  scalar /= v.Mod2();
199  return v * scalar;
200  }
201  MyVector2 Norm(const MyVector2& v) const
202  {
203  return (*this) - Proj(v);
204  }
205  Double_t Phi() const
206  {
207  return TMath::Pi() + TMath::ATan2(-y, -x);
208  }
209  };
210 
211 public:
212 
213  KVIDLine();
214  KVIDLine(const TGraph& gr);
215  KVIDLine(const KVIDLine&);
216 
217  virtual ~ KVIDLine();
218 
219  virtual void WaitForPrimitive();
220  virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py);
221 
222  inline Double_t DistanceToLine(Double_t px, Double_t py, Int_t&);
223  inline Double_t DistanceToLine(Double_t px, Double_t py, Double_t xp1,
224  Double_t yp1, Double_t xp2, Double_t yp2,
225  Int_t&);
226  inline Bool_t WhereAmI(Double_t px, Double_t py, Option_t* opt);
228  Double_t xp1, Double_t yp1, Double_t xp2,
229  Double_t yp2);
230 
231  inline void GetStartPoint(Double_t& x, Double_t& y) const;
232  inline void GetEndPoint(Double_t& x, Double_t& y) const;
234  const Char_t* axis = "") const;
235 
236  static KVIDLine* MakeIDLine(TObject* obj, Double_t xdeb = -1., Double_t xfin = -1., Double_t np = 1., Bool_t save = kFALSE);
238 
239  ClassDef(KVIDLine, 2) //Base class for lines/cuts used for particle identification
240 };
241 
243 
245  Int_t& i_near)
246 {
265 
266  Double_t distance, dist2;
267  Int_t i;
268  Double_t d;
269  distance = dist2 = 9999.;
270  Int_t i_nearest_point = 0, inear1 = 0, inear2 = 0;
274 
275  for (i = 0; i < fNpoints - 1; i++) {
276  d = DistanceToLine(px, py, fX[i], fY[i], fX[i + 1], fY[i + 1],
277  i_nearest_point);
279  if (d >= 0.) {
280  if (d < distance) {
281  distance = d;
282  inear1 = i;
283  }
284  }
285  else {
287  if (-d < dist2) {
288  dist2 = -d;
289  inear2 = i + i_nearest_point;
290  }
291  }
292  }
293 
294  i_near = inear1;
295  if (distance < 9999.)
296  return distance;
297  i_near = inear2;
299  if (inear2 > 0 && inear2 < (fNpoints - 1))
300  return dist2;
302  return -dist2;
303 }
304 
305 
307 
309  Double_t xp1, Double_t yp1,
310  Double_t xp2, Double_t yp2,
311  Int_t& i_nearest_point)
312 {
335 
336  MyVector2 P1(xp1, yp1), P2(xp2, yp2), P(px, py);
337  MyVector2 P1P2 = P2 - P1;
338  MyVector2 P1P = P - P1;
339  MyVector2 P2P = P - P2;
340  MyVector2 MP = P1P.Norm((P1P2));
341  i_nearest_point = 0;
343  Double_t sum = (P1P - MP).Mod() + (P2P - MP).Mod();
345  if (TMath::Abs(sum - P1P2.Mod()) > 1.e-06) {
347  if (P1P.Mod() < P2P.Mod()) {
348  i_nearest_point = 0;
349  return -(P1P.Mod());
350  }
351  i_nearest_point = 1;
352  return -(P2P.Mod());
353  }
355  return MP.Mod();
356 }
357 
358 
360 
362  Double_t py, Double_t xp1,
363  Double_t yp1, Double_t xp2,
364  Double_t yp2)
365 {
389 
390  MyVector2 P1(xp1, yp1), P2(xp2, yp2), P(px, py);
391  MyVector2 P1P2 = P2 - P1;
392  MyVector2 P1P = P - P1;
393  MyVector2 MP = P1P.Norm((P1P2));
394  Double_t phi = MP.Phi() * TMath::RadToDeg();
399  Bool_t result = kFALSE;
400  if (!strcmp(opt, "left")) {
401  result = (phi > 90. && phi < 270.);
402  }
403  else if (!strcmp(opt, "right")) {
404  result = (phi < 90. || phi > 270.);
405  }
406  else if (!strcmp(opt, "above")) {
407  result = (phi > 0. && phi < 180.);
408  }
409  else if (!strcmp(opt, "below")) {
410  result = (phi > 180. && phi < 360.);
411  }
412  return result;
413 }
414 
416 
418 {
425 
426  Double_t* XX, *YY;
427  Double_t xx, yy;
428  Int_t sign = 1;
429 
430  if (!strcmp(opt, "left")) {
431  XX = fY;
432  xx = py;
433  YY = fX;
434  yy = px;
435  }
436  else if (!strcmp(opt, "right")) {
437  XX = fY;
438  xx = py;
439  YY = fX;
440  yy = px;
441  sign = -1;
442  }
443  else if (!strcmp(opt, "above")) {
444  XX = fX;
445  xx = px;
446  YY = fY;
447  yy = py;
448  sign = -1;
449  }
450  else if (!strcmp(opt, "below")) {
451  XX = fX;
452  xx = px;
453  YY = fY;
454  yy = py;
455  }
456  else return kFALSE;
457 
458  Int_t i_start = 0;
459  Int_t i_stop = fNpoints - 1;
460  Int_t prev_i_stop = 0;
461  Bool_t same_sign = TMath::Sign(1., XX[i_start] - xx) == TMath::Sign(1., XX[i_stop] - xx);
462  while ((i_start < i_stop - 1) || same_sign) {
463 
464  if (same_sign && (prev_i_stop == 0)) break;
465  else if (same_sign) {
466  i_start = i_stop;
467  i_stop = prev_i_stop;
468  }
469  else {
470  prev_i_stop = i_stop;
471  i_stop = (Int_t)((i_start + i_stop) / 2 + 0.5);
472  }
473 
474  same_sign = TMath::Sign(1., XX[i_start] - xx) == TMath::Sign(1., XX[i_stop] - xx);
475  }
476 
477  Double_t a = (YY[i_stop] - YY[i_start]) / (XX[i_stop] - XX[i_start]);
478  Double_t b = YY[i_start] - a * XX[i_start];
479 
480  Bool_t res = (sign * yy < sign * (a * xx + b));
481 
482  return res;
483 }
484 
486 
487 inline void KVIDLine::GetStartPoint(Double_t& x, Double_t& y) const
488 {
490 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,3)
491  GetPoint(0, x, y);
492 #else
493  const_cast < KVIDLine* >(this)->GetPoint(0, x, y);
494 #endif
495 }
496 
498 
499 inline void KVIDLine::GetEndPoint(Double_t& x, Double_t& y) const
500 {
502 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,3)
503  GetPoint((GetN() - 1), x, y);
504 #else
505  const_cast < KVIDLine* >(this)->GetPoint((GetN() - 1), x, y);
506 #endif
507 }
508 
510 
512  const Char_t* axis) const
513 {
518 
519  TString ax(axis);
520  ax.ToUpper();
521  Double_t x1, y1, x2, y2;
522  GetStartPoint(x1, y1);
523  GetEndPoint(x2, y2);
524  Double_t xmin = TMath::Min(x1, x2);
525  Double_t xmax = TMath::Max(x1, x2);
526  Double_t ymin = TMath::Min(y1, y2);
527  Double_t ymax = TMath::Max(y1, y2);
528 
529  Bool_t in_range_x = (x <= xmax && x >= xmin);
530  Bool_t in_range_y = (y <= ymax && y >= ymin);
531  if (ax == "X") {
532  return in_range_x;
533  }
534  else if (ax == "Y") {
535  return in_range_y;
536  }
537 
538  return (in_range_x && in_range_y);
539 }
540 
541 #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
A lightweight replacement for the TVector2 class.
Definition: KVIDLine.h:155
MyVector2(const MyVector2 &T)
Definition: KVIDLine.h:159
friend MyVector2 operator*(const MyVector2 &a, double s)
Definition: KVIDLine.h:179
friend MyVector2 operator*(double s, const MyVector2 &a)
Definition: KVIDLine.h:183
double Mod() const
Definition: KVIDLine.h:191
friend double operator*(const MyVector2 &a, const MyVector2 &b)
Definition: KVIDLine.h:175
MyVector2 Proj(const MyVector2 &v) const
Definition: KVIDLine.h:195
double Mod2() const
Definition: KVIDLine.h:187
Double_t Phi() const
Definition: KVIDLine.h:205
friend MyVector2 operator-(const MyVector2 &a, const MyVector2 &b)
Definition: KVIDLine.h:171
MyVector2(double X, double Y)
Definition: KVIDLine.h:158
MyVector2 Norm(const MyVector2 &v) const
Definition: KVIDLine.h:201
MyVector2 & operator=(const MyVector2 &T)
Definition: KVIDLine.h:163
Base class for lines/cuts used for particle identification in 2D data maps.
Definition: KVIDLine.h:142
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)
virtual ~ KVIDLine()
Double_t DistanceToLine(Double_t px, Double_t py, Int_t &)
Definition: KVIDLine.h:244
Bool_t WhereAmI(Double_t px, Double_t py, Option_t *opt)
void GetStartPoint(Double_t &x, Double_t &y) const
Bool_t IsBetweenEndPoints(Double_t x, Double_t y, const Char_t *axis="") const
KVIDLine()
Default ctor.
Definition: KVIDLine.cpp:38
void GetEndPoint(Double_t &x, Double_t &y) const
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
VecExpr< UnaryOp< Sqrt< T >, SVector< T, D >, T >, T, D > sqrt(const SVector< T, D > &rhs)
Double_t y[n]
Double_t x[n]
const long double s
Definition: KVUnits.h:94
double T(double x)
Double_t Min(Double_t a, Double_t b)
Double_t Sign(Double_t a, Double_t b)
Double_t ATan2(Double_t y, Double_t x)
constexpr Double_t Pi()
Double_t Abs(Double_t d)
Double_t Max(Double_t a, Double_t b)
constexpr Double_t RadToDeg()
v
auto * a