KaliVeda
Toolkit for HIC analysis
KVIDLine.h
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 #include <optional>
14 #include "TVector2.h"
15 #include "TMath.h"
16 #include "TH2.h"
17 #include "KVIDentifier.h"
143 class KVIDLine : public KVIDentifier {
144 
157  class MyVector2 {
158  double x, y;
159  public:
160  MyVector2(double X, double Y) : x(X), y(Y) {}
162  {
163  *this = T;
164  }
166  {
167  if (this != &T) {
168  x = T.x;
169  y = T.y;
170  }
171  return *this;
172  }
173  friend MyVector2 operator-(const MyVector2& a, const MyVector2& b)
174  {
175  return {a.x - b.x, a.y - b.y};
176  }
177  friend double operator*(const MyVector2& a, const MyVector2& b)
178  {
179  return a.x * b.x + a.y * b.y;
180  }
181  friend MyVector2 operator*(const MyVector2& a, double s)
182  {
183  return {a.x * s, a.y * s};
184  }
185  friend MyVector2 operator*(double s, const MyVector2& a)
186  {
187  return a * s;
188  }
189  double Mod2() const
190  {
191  return (*this) * (*this);
192  }
193  double Mod() const
194  {
195  return sqrt(Mod2());
196  }
197  MyVector2 Proj(const MyVector2& v) const
198  {
199  double scalar = v * (*this);
200  scalar /= v.Mod2();
201  return v * scalar;
202  }
203  MyVector2 Norm(const MyVector2& v) const
204  {
205  return (*this) - Proj(v);
206  }
207  Double_t Phi() const
208  {
209  return TMath::Pi() + TMath::ATan2(-y, -x);
210  }
211  };
212 
213 public:
214 
215  KVIDLine();
216  KVIDLine(const TGraph& gr);
217  KVIDLine(const KVIDLine&);
218 
219  virtual ~ KVIDLine();
220 
221  void WaitForPrimitive() override;
222  void ExecuteEvent(Int_t event, Int_t px, Int_t py) override;
223 
224  inline Double_t DistanceToLine(Double_t px, Double_t py, Int_t&);
225  inline Double_t DistanceToLine(Double_t px, Double_t py, Double_t xp1,
226  Double_t yp1, Double_t xp2, Double_t yp2,
227  Int_t&);
228  inline Bool_t WhereAmI(Double_t px, Double_t py, Option_t* opt) const;
230  Double_t xp1, Double_t yp1, Double_t xp2,
231  Double_t yp2);
232 
233  inline void GetStartPoint(Double_t& x, Double_t& y) const;
234  inline void GetEndPoint(Double_t& x, Double_t& y) const;
235  inline Bool_t IsBetweenEndPoints(Double_t x, Double_t y, std::optional<TString> axis = {}) const;
236 
237  static KVIDLine* MakeIDLine(TObject* obj, Double_t xdeb = -1., Double_t xfin = -1., Double_t np = 1., Bool_t save = kFALSE);
239 
240  Bool_t WhereAmI(const KVIDLine&, const TString& tested_direction) const;
241 
242  ClassDefOverride(KVIDLine, 2) //Base class for lines/cuts used for particle identification
243 };
244 
246 
248  Int_t& i_near)
249 {
268 
269  Double_t distance, dist2;
270  Int_t i;
271  Double_t d;
272  distance = dist2 = 9999.;
273  Int_t i_nearest_point = 0, inear1 = 0, inear2 = 0;
277 
278  for (i = 0; i < fNpoints - 1; i++) {
279  d = DistanceToLine(px, py, fX[i], fY[i], fX[i + 1], fY[i + 1],
280  i_nearest_point);
282  if (d >= 0.) {
283  if (d < distance) {
284  distance = d;
285  inear1 = i;
286  }
287  }
288  else {
290  if (-d < dist2) {
291  dist2 = -d;
292  inear2 = i + i_nearest_point;
293  }
294  }
295  }
296 
297  i_near = inear1;
298  if (distance < 9999.)
299  return distance;
300  i_near = inear2;
302  if (inear2 > 0 && inear2 < (fNpoints - 1))
303  return dist2;
305  return -dist2;
306 }
307 
308 
310 
312  Double_t xp1, Double_t yp1,
313  Double_t xp2, Double_t yp2,
314  Int_t& i_nearest_point)
315 {
338 
339  MyVector2 P1(xp1, yp1), P2(xp2, yp2), P(px, py);
340  MyVector2 P1P2 = P2 - P1;
341  MyVector2 P1P = P - P1;
342  MyVector2 P2P = P - P2;
343  MyVector2 MP = P1P.Norm((P1P2));
344  i_nearest_point = 0;
346  Double_t sum = (P1P - MP).Mod() + (P2P - MP).Mod();
348  if (TMath::Abs(sum - P1P2.Mod()) > 1.e-06) {
350  if (P1P.Mod() < P2P.Mod()) {
351  i_nearest_point = 0;
352  return -(P1P.Mod());
353  }
354  i_nearest_point = 1;
355  return -(P2P.Mod());
356  }
358  return MP.Mod();
359 }
360 
361 
363 
365  Double_t py, Double_t xp1,
366  Double_t yp1, Double_t xp2,
367  Double_t yp2)
368 {
392 
393  MyVector2 P1(xp1, yp1), P2(xp2, yp2), P(px, py);
394  MyVector2 P1P2 = P2 - P1;
395  MyVector2 P1P = P - P1;
396  MyVector2 MP = P1P.Norm((P1P2));
397  Double_t phi = MP.Phi() * TMath::RadToDeg();
402  Bool_t result = kFALSE;
403  if (!strcmp(opt, "left")) {
404  result = (phi > 90. && phi < 270.);
405  }
406  else if (!strcmp(opt, "right")) {
407  result = (phi < 90. || phi > 270.);
408  }
409  else if (!strcmp(opt, "above")) {
410  result = (phi > 0. && phi < 180.);
411  }
412  else if (!strcmp(opt, "below")) {
413  result = (phi > 180. && phi < 360.);
414  }
415  return result;
416 }
417 
419 
420 inline Bool_t KVIDLine::WhereAmI(Double_t px, Double_t py, Option_t* opt) const
421 {
430 
431  Double_t* XX, *YY;
432  Double_t xx, yy;
433  Int_t sign = 1;
434 
435  if (!strcmp(opt, "left")) {
436  XX = fY;
437  xx = py;
438  YY = fX;
439  yy = px;
440  }
441  else if (!strcmp(opt, "right")) {
442  XX = fY;
443  xx = py;
444  YY = fX;
445  yy = px;
446  sign = -1;
447  }
448  else if (!strcmp(opt, "above")) {
449  XX = fX;
450  xx = px;
451  YY = fY;
452  yy = py;
453  sign = -1;
454  }
455  else if (!strcmp(opt, "below")) {
456  XX = fX;
457  xx = px;
458  YY = fY;
459  yy = py;
460  }
461  else return kFALSE;
462 
463  Int_t i_start = 0;
464  Int_t i_stop = fNpoints - 1;
465  Int_t prev_i_stop = 0;
466  Bool_t same_sign = TMath::Sign(1., XX[i_start] - xx) == TMath::Sign(1., XX[i_stop] - xx);
467  while ((i_start < i_stop - 1) || same_sign) {
468 
469  if (same_sign && (prev_i_stop == 0)) break;
470  else if (same_sign) {
471  i_start = i_stop;
472  i_stop = prev_i_stop;
473  }
474  else {
475  prev_i_stop = i_stop;
476  i_stop = (Int_t)((i_start + i_stop) / 2 + 0.5);
477  }
478 
479  same_sign = TMath::Sign(1., XX[i_start] - xx) == TMath::Sign(1., XX[i_stop] - xx);
480  }
481 
482  Double_t a = (YY[i_stop] - YY[i_start]) / (XX[i_stop] - XX[i_start]);
483  Double_t b = YY[i_start] - a * XX[i_start];
484 
485  Bool_t res = (sign * yy < sign * (a * xx + b));
486 
487  return res;
488 }
489 
491 
492 inline void KVIDLine::GetStartPoint(Double_t& x, Double_t& y) const
493 {
495 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,3)
496  GetPoint(0, x, y);
497 #else
498  const_cast < KVIDLine* >(this)->GetPoint(0, x, y);
499 #endif
500 }
501 
503 
504 inline void KVIDLine::GetEndPoint(Double_t& x, Double_t& y) const
505 {
507 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,3)
508  GetPoint((GetN() - 1), x, y);
509 #else
510  const_cast < KVIDLine* >(this)->GetPoint((GetN() - 1), x, y);
511 #endif
512 }
513 
515 
516 inline Bool_t KVIDLine::IsBetweenEndPoints(Double_t x, Double_t y, std::optional<TString> axis) const
517 {
522 
523  TString ax = axis.value_or("");
524  ax.ToUpper();
525  Double_t x1, y1, x2, y2;
526  GetStartPoint(x1, y1);
527  GetEndPoint(x2, y2);
528  Double_t xmin = TMath::Min(x1, x2);
529  Double_t xmax = TMath::Max(x1, x2);
530  Double_t ymin = TMath::Min(y1, y2);
531  Double_t ymax = TMath::Max(y1, y2);
532 
533  Bool_t in_range_x = (x <= xmax && x >= xmin);
534  Bool_t in_range_y = (y <= ymax && y >= ymin);
535  if (ax == "X") {
536  return in_range_x;
537  }
538  else if (ax == "Y") {
539  return in_range_y;
540  }
541 
542  return (in_range_x && in_range_y);
543 }
544 
545 #endif
int Int_t
#define d(i)
bool Bool_t
constexpr Bool_t kFALSE
double Double_t
const char Option_t
#define ClassDefOverride(name, id)
#define X(type, name)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char y1
float xmin
float ymin
float xmax
float ymax
A lightweight replacement for the TVector2 class.
Definition: KVIDLine.h:157
MyVector2(const MyVector2 &T)
Definition: KVIDLine.h:161
friend MyVector2 operator*(const MyVector2 &a, double s)
Definition: KVIDLine.h:181
friend MyVector2 operator*(double s, const MyVector2 &a)
Definition: KVIDLine.h:185
double Mod() const
Definition: KVIDLine.h:193
friend double operator*(const MyVector2 &a, const MyVector2 &b)
Definition: KVIDLine.h:177
MyVector2 Proj(const MyVector2 &v) const
Definition: KVIDLine.h:197
double Mod2() const
Definition: KVIDLine.h:189
Double_t Phi() const
Definition: KVIDLine.h:207
friend MyVector2 operator-(const MyVector2 &a, const MyVector2 &b)
Definition: KVIDLine.h:173
MyVector2(double X, double Y)
Definition: KVIDLine.h:160
MyVector2 Norm(const MyVector2 &v) const
Definition: KVIDLine.h:203
MyVector2 & operator=(const MyVector2 &T)
Definition: KVIDLine.h:165
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
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:247
Bool_t WhereAmI(Double_t px, Double_t py, Option_t *opt) const
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Definition: KVIDLine.cpp:255
Bool_t IsBetweenEndPoints(Double_t x, Double_t y, std::optional< TString > axis={}) const
void GetStartPoint(Double_t &x, Double_t &y) const
KVIDLine()
Default ctor.
Definition: KVIDLine.cpp:38
void GetEndPoint(Double_t &x, Double_t &y) const
void WaitForPrimitive() override
Definition: KVIDLine.cpp:223
Base class for graphical cuts used in particle identification.
Definition: KVIDentifier.h:28
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()
Expr< UnaryOp< Sqrt< T >, SMatrix< T, D, D2, R >, T >, T, D, D2, R > sqrt(const SMatrix< T, D, D2, R > &rhs)
Double_t y[n]
Double_t x[n]
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
TArc a