yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis  1.9.0
Scatter2D.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // This file is part of YODA -- Yet more Objects for Data Analysis
4 // Copyright (C) 2008-2021 The YODA collaboration (see AUTHORS for details)
5 //
6 #ifndef YODA_Scatter2D_h
7 #define YODA_Scatter2D_h
8 
9 #include "YODA/AnalysisObject.h"
10 #include "YODA/Scatter.h"
11 #include "YODA/Point2D.h"
13 #include <utility>
14 #include <memory>
15 
16 namespace YODA {
17 
18 
19  // Forward declarations
20  class Histo1D;
21  class Profile1D;
22 
23 
25  class Scatter2D : public AnalysisObject, public Scatter {
26  public:
27 
29  typedef Point2D Point;
30  typedef Utils::sortedvector<Point2D> Points;
31  typedef std::shared_ptr<Scatter2D> Ptr;
32 
33 
36 
38  Scatter2D(const std::string& path="", const std::string& title="")
39  : AnalysisObject("Scatter2D", path, title)
40  { }
41 
42 
44  Scatter2D(const Points& points,
45  const std::string& path="", const std::string& title="")
46  : AnalysisObject("Scatter2D", path, title),
47  _points(points)
48  { }
49 
50 
52  Scatter2D(const std::vector<double>& x, const std::vector<double>& y,
53  const std::string& path="", const std::string& title="")
54  : AnalysisObject("Scatter2D", path, title)
55  {
56  if (x.size() != y.size()) throw UserError("x and y vectors must have same length");
57  for (size_t i = 0; i < x.size(); ++i) addPoint(x[i], y[i]);
58  }
59 
60 
62  Scatter2D(const std::vector<double>& x, const std::vector<double>& y,
63  const std::vector<double>& ex, const std::vector<double>& ey,
64  const std::string& path="", const std::string& title="")
65  : AnalysisObject("Scatter2D", path, title)
66  {
67  if (x.size() != y.size()) throw UserError("x and y vectors must have same length");
68  if (x.size() != ex.size()) throw UserError("x and ex vectors must have same length");
69  if (y.size() != ey.size()) throw UserError("y and ey vectors must have same length");
70  for (size_t i = 0; i < x.size(); ++i) addPoint(x[i], y[i], ex[i], ey[i]);
71  }
72 
73 
75  Scatter2D(const std::vector<double>& x, const std::vector<double>& y,
76  const std::vector<std::pair<double,double> >& ex, const std::vector<std::pair<double,double> >& ey,
77  const std::string& path="", const std::string& title="")
78  : AnalysisObject("Scatter2D", path, title)
79  {
80  if (x.size() != y.size()) throw UserError("x and y vectors must have same length");
81  if (x.size() != ex.size()) throw UserError("x and ex vectors must have same length");
82  if (y.size() != ey.size()) throw UserError("y and ey vectors must have same length");
83  for (size_t i = 0; i < x.size(); ++i) addPoint(Point2D(x[i], y[i], ex[i], ey[i]));
84  }
85 
86 
88  Scatter2D(const std::vector<double>& x, const std::vector<double>& y,
89  const std::vector<double>& exminus, const std::vector<double>& explus,
90  const std::vector<double>& eyminus, const std::vector<double>& eyplus,
91  const std::string& path="", const std::string& title="")
92  : AnalysisObject("Scatter2D", path, title)
93  {
94  if (x.size() != y.size()) throw UserError("x and y vectors must have same length");
95  if (x.size() != exminus.size()) throw UserError("x and ex vectors must have same length");
96  if (y.size() != eyminus.size()) throw UserError("y and ey vectors must have same length");
97  if (exminus.size() != explus.size()) throw UserError("ex plus and minus vectors must have same length");
98  if (eyminus.size() != eyplus.size()) throw UserError("ey plus and minus vectors must have same length");
99  for (size_t i = 0; i < x.size(); ++i) addPoint(Point2D(x[i], y[i], exminus[i], explus[i], eyminus[i], eyplus[i]));
100  }
101 
102 
105  Scatter2D(const Scatter2D& s2, const std::string& path="")
106  : AnalysisObject("Scatter2D", (path.size() == 0) ? s2.path() : path, s2, s2.title()),
107  _points(s2._points)
108  {
109  for ( auto &ann : annotations()){
110  setAnnotation(ann, annotation(ann));
111  }
112  }
113 
114 
117  AnalysisObject::operator = (s2); //< AO treatment of paths etc.
118  _points = s2._points;
119  return *this;
120  }
121 
123  Scatter2D clone() const {
124  return Scatter2D(*this);
125  }
126 
128  Scatter2D* newclone() const {
129  return new Scatter2D(*this);
130  }
131 
133 
134 
136  size_t dim() const { return 2; }
137 
138 
141 
143  void reset() {
144  _points.clear();
145  }
146 
148  void scaleX(double scalex) {
149  for (Point2D& p : _points) p.scaleX(scalex);
150  }
151 
153  void scaleY(double scaley) {
154  for (Point2D& p : _points) p.scaleY(scaley);
155  }
156 
158  void scaleXY(double scalex, double scaley) {
159  for (Point2D& p : _points) p.scaleXY(scalex, scaley);
160  }
161 
163  void scale(size_t i, double scale) {
164  switch (i) {
165  case 1: scaleX(scale); break;
166  case 2: scaleY(scale); break;
167  default: throw RangeError("Invalid axis int, must be in range 1..dim");
168  }
169  }
170 
172 
173 
175 
176  void parseVariations();
177 
179  std::vector<std::string> variations() const;
180 
181  // Construct a covariance matrix from the error breakdown
182  std::vector<std::vector<double> > covarianceMatrix(bool ignoreOffDiagonalTerms=false);
183 
186 
188  size_t numPoints() const {
189  return _points.size();
190  }
191 
192 
194  Points& points() {
195  return _points;
196  }
197 
198 
200  const Points& points() const {
201  return _points;
202  }
203 
204 
206  Point2D& point(size_t index) {
207  if (index >= numPoints()) throw RangeError("There is no point with this index");
208  return _points.at(index);
209  }
210 
211 
213  const Point2D& point(size_t index) const {
214  if (index >= numPoints()) throw RangeError("There is no point with this index");
215  return _points.at(index);
216  }
217 
219 
220 
223 
225  void addPoint(const Point2D& pt) {
226  _points.insert(pt);
227  }
228 
230  void addPoint(double x, double y) {
231  Point2D thisPoint = Point2D(x, y);
232  thisPoint.setParent(this);
233  _points.insert(thisPoint);
234  }
235 
237  void addPoint(double x, double y,
238  double ex, double ey) {
239  Point2D thisPoint = Point2D(x, y, ex, ey);
240  thisPoint.setParent(this);
241  _points.insert(thisPoint);
242  }
243 
245  void addPoint(double x, double y,
246  const std::pair<double,double>& ex, const std::pair<double,double>& ey) {
247  Point2D thisPoint = Point2D(x, y, ex, ey);
248  thisPoint.setParent(this);
249  _points.insert(thisPoint);
250  }
251 
253  void addPoint(double x, double y,
254  double exminus, double explus,
255  double eyminus, double eyplus) {
256  Point2D thisPoint = Point2D(x, y, exminus, explus, eyminus, eyplus);
257  thisPoint.setParent(this);
258  _points.insert(thisPoint);
259  }
260 
262  void addPoints(const Points& pts) {
263  for (const Point2D& pt : pts) addPoint(pt);
264  }
265 
267 
268 
271 
273  void rmPoint(size_t index) {
274  _points.erase(_points.begin()+index);
275  }
276 
277  // /// Remove the points with indices @a indices
278  // void rmPoints(std::vector<size_t> indices) {
279  // // reverse-sort so the erasure-loop doesn't invalidate the indices
280  // std::sort(indices.begin(), indices.end(), std::greater<size_t>());
281  // for (size_t i : indices) rmPoint(i);
282  // }
283 
285 
286 
287 
290 
292  void combineWith(const Scatter2D& other) {
293  addPoints(other.points());
294  //return *this;
295  }
296 
299  void combineWith(const std::vector<Scatter2D>& others) {
300  for (const Scatter2D& s : others) combineWith(s);
301  //return *this;
302  }
303 
305 
306 
308  bool operator == (const Scatter2D& other) {
309  return _points == other._points;
310  }
311 
313  bool operator != (const Scatter2D& other) {
314  return ! operator == (other);
315  }
316 
317 
318 
320 
321 
322  private:
323 
324  Points _points;
325 
326  bool _variationsParsed =false ;
327 
328  };
329 
330 
332  typedef Scatter2D S2D;
333 
334 
337 
338  inline Scatter2D combine(const Scatter2D& a, const Scatter2D& b) {
339  Scatter2D rtn = a;
340  rtn.combineWith(b);
341  return rtn;
342  }
343 
344  inline Scatter2D combine(const std::vector<Scatter2D>& scatters) {
345  Scatter2D rtn;
346  rtn.combineWith(scatters);
347  return rtn;
348  }
349 
351 
352 
354 
355 
358 
365  Scatter2D mkScatter(const Histo1D& h, bool usefocus=false, bool binwidthdiv=true);
366 
373  Scatter2D mkScatter(const Profile1D& p, bool usefocus=false, bool usestddev=false);
374 
377  inline Scatter2D mkScatter(const Scatter2D& s) { return Scatter2D(s); }
378  // /// @note The usefocus arg is just for consistency and has no effect for Scatter -> Scatter
379  // inline Scatter2D mkScatter(const Scatter2D& s, bool) { return mkScatter(s); }
380 
382 
383 
385 
386 
389 
393  template<typename FNX>
394  inline void transformX(Scatter2D& s, FNX fx) {
395  for (size_t i = 0; i < s.numPoints(); ++i) {
396  Point2D& p = s.point(i);
397  const double newx = fx(p.x());
398  const double fx_xmin = fx(p.xMin());
399  const double fx_xmax = fx(p.xMax());
400  // Deal with possible inversions of min/max ordering under the transformation
401  const double newxmin = std::min(fx_xmin, fx_xmax);
402  const double newxmax = std::max(fx_xmin, fx_xmax);
403  // Set new point x values
404  p.setX(newx);
406  p.setXErrMinus(newx - newxmin);
407  p.setXErrPlus(newxmax - newx);
408  }
409  }
410 
411 
415  template<typename FNY>
416  inline void transformY(Scatter2D& s, FNY fy) {
417  for (size_t i = 0; i < s.numPoints(); ++i) {
418  Point2D& p = s.point(i);
419  const double newy = fy(p.y());
420  const double fy_ymin = fy(p.yMin());
421  const double fy_ymax = fy(p.yMax());
422  // Deal with possible inversions of min/max ordering under the transformation
423  const double newymin = std::min(fy_ymin, fy_ymax);
424  const double newymax = std::max(fy_ymin, fy_ymax);
425  // Set new point y values
426  p.setY(newy);
428  p.setYErrMinus(newy - newymin);
429  p.setYErrPlus(newymax - newy);
430  }
431  }
432 
433 
435 
436 
438  inline void flip(Scatter2D& s) {
439  for (size_t i = 0; i < s.numPoints(); ++i) {
440  Point2D& p = s.point(i);
441  const double newx = p.y();
442  const double newy = p.x();
443  const double newxmin = p.yMin();
444  const double newxmax = p.yMax();
445  const double newymin = p.xMin();
446  const double newymax = p.xMax();
447  p.setX(newx);
448  p.setY(newy);
450  p.setXErrMinus(newx - newxmin);
451  p.setXErrPlus(newxmax - newx);
452  p.setYErrMinus(newy - newymin);
453  p.setYErrPlus(newymax - newy);
454  }
455  }
456 
458 
459 
460 }
461 
462 #endif
void parseVariations()
Definition: Scatter2D.cc:79
void setY(double y)
Set y value.
Definition: Point2D.h:118
Scatter2D(const std::vector< double > &x, const std::vector< double > &y, const std::vector< std::pair< double, double > > &ex, const std::vector< std::pair< double, double > > &ey, const std::string &path="", const std::string &title="")
Constructor from values with asymmetric errors on both x and y.
Definition: Scatter2D.h:75
Scatter1D combine(const Scatter1D &a, const Scatter1D &b)
Definition: Scatter1D.h:307
double x() const
Get x value.
Definition: Point2D.h:109
void addPoint(double x, double y)
Insert a new point, defined as the x/y value pair and no errors.
Definition: Scatter2D.h:230
Scatter2D * newclone() const
Make a copy on the heap, via &#39;new&#39;.
Definition: Scatter2D.h:128
const std::string path() const
Get the AO path.
void addPoint(const Point2D &pt)
Insert a new point.
Definition: Scatter2D.h:225
A very generic data type which is just a collection of 2D data points with errors.
Definition: Scatter2D.h:25
void setYErrPlus(double eyplus, std::string source="")
Set positive y error.
Definition: Point2D.h:251
double y() const
Get y value.
Definition: Point2D.h:115
void combineWith(const Scatter2D &other)
Definition: Scatter2D.h:292
Scatter2D(const Scatter2D &s2, const std::string &path="")
Definition: Scatter2D.h:105
double xMax() const
Definition: Point2D.h:203
Error for e.g. use of invalid bin ranges.
Definition: Exceptions.h:34
Scatter2D(const Points &points, const std::string &path="", const std::string &title="")
Constructor from a set of points.
Definition: Scatter2D.h:44
void scale(size_t i, double scale)
Scaling along direction i.
Definition: Scatter2D.h:163
void rmPoint(size_t index)
Remove the point with index index.
Definition: Scatter2D.h:273
A one-dimensional histogram.
Definition: Histo1D.h:28
void scaleX(double scalex)
Scaling of x axis.
Definition: Scatter2D.h:148
void setXErrPlus(double explus)
Set positive x error.
Definition: Point2D.h:165
void setParent(Scatter *parent)
Definition: Point.h:114
void scaleY(double scaley)
Scaling of y axis.
Definition: Scatter2D.h:153
Scatter2D & operator=(const Scatter2D &s2)
Assignment operator.
Definition: Scatter2D.h:116
bool operator==(const Scatter2D &other)
Equality operator.
Definition: Scatter2D.h:308
Error for problems introduced outside YODA, to put it nicely.
Definition: Exceptions.h:100
Scatter2D(const std::vector< double > &x, const std::vector< double > &y, const std::string &path="", const std::string &title="")
Constructor from a vector of values with no errors.
Definition: Scatter2D.h:52
Scatter2D clone() const
Make a copy on the stack.
Definition: Scatter2D.h:123
Point2D Point
Type of the native Point2D collection.
Definition: Scatter2D.h:29
Point2D & point(size_t index)
Get a reference to the point with index index (non-const)
Definition: Scatter2D.h:206
size_t numPoints() const
Number of points in the scatter.
Definition: Scatter2D.h:188
double yMax(std::string source="") const
Get value plus positive y-error.
Definition: Point2D.h:286
size_t dim() const
Dimension of this data object.
Definition: Scatter2D.h:136
double xMin() const
Definition: Point2D.h:195
void setYErrMinus(double eyminus, std::string source="")
Set negative y error.
Definition: Point2D.h:243
bool operator!=(const Scatter2D &other)
Non-equality operator.
Definition: Scatter2D.h:313
Scatter2D(const std::vector< double > &x, const std::vector< double > &y, const std::vector< double > &exminus, const std::vector< double > &explus, const std::vector< double > &eyminus, const std::vector< double > &eyplus, const std::string &path="", const std::string &title="")
Constructor from values with completely explicit asymmetric errors.
Definition: Scatter2D.h:88
const std::string & annotation(const std::string &name) const
Get an annotation by name (as a string)
Scatter2D(const std::string &path="", const std::string &title="")
Empty constructor.
Definition: Scatter2D.h:38
void addPoint(double x, double y, double ex, double ey)
Insert a new point, defined as the x/y value pair and symmetric errors.
Definition: Scatter2D.h:237
Scatter1D mkScatter(const Counter &c)
Make a Scatter1D representation of a Histo1D.
Definition: Scatter1D.cc:13
const std::string title() const
Get the AO title.
Scatter2D S2D
Convenience typedef.
Definition: Scatter2D.h:332
void setX(double x)
Set x value.
Definition: Point2D.h:112
const Point2D & point(size_t index) const
Get a reference to the point with index index (const)
Definition: Scatter2D.h:213
void addPoint(double x, double y, const std::pair< double, double > &ex, const std::pair< double, double > &ey)
Insert a new point, defined as the x/y value pair and asymmetric error pairs.
Definition: Scatter2D.h:245
AnalysisObject is the base class for histograms and scatters.
A base class for common operations on scatter types (Scatter1D, etc.)
Definition: Scatter.h:15
const Points & points() const
Get the collection of points (const)
Definition: Scatter2D.h:200
void flip(Scatter2D &s)
Exchange the x and y axes (operates in-place on s)
Definition: Scatter2D.h:438
std::vector< std::string > variations() const
Get the list of variations stored in the points.
Definition: Scatter2D.cc:102
Utils::sortedvector< Point2D > Points
Definition: Scatter2D.h:30
void reset()
Clear all points.
Definition: Scatter2D.h:143
std::vector< std::vector< double > > covarianceMatrix(bool ignoreOffDiagonalTerms=false)
Definition: Scatter2D.cc:116
Scatter2D(const std::vector< double > &x, const std::vector< double > &y, const std::vector< double > &ex, const std::vector< double > &ey, const std::string &path="", const std::string &title="")
Constructor from vectors of values with symmetric errors on x and y.
Definition: Scatter2D.h:62
void addPoint(double x, double y, double exminus, double explus, double eyminus, double eyplus)
Insert a new point, defined as the x/y value pair and asymmetric errors.
Definition: Scatter2D.h:253
void transformX(Scatter1D &s, FNX fx)
Apply transformation fx(x) to all values and error positions (operates in-place on s) ...
Definition: Scatter1D.h:349
A one-dimensional profile histogram.
Definition: Profile1D.h:35
double yMin(std::string source="") const
Get value minus negative y-error.
Definition: Point2D.h:279
void setAnnotation(const std::string &name, const std::string &value)
Add or set a string-valued annotation by name.
void addPoints(const Points &pts)
Insert a collection of new points.
Definition: Scatter2D.h:262
void scaleXY(double scalex, double scaley)
Scaling of both axes.
Definition: Scatter2D.h:158
std::vector< std::string > annotations() const
void setXErrMinus(double exminus)
Set negative x error.
Definition: Point2D.h:160
virtual AnalysisObject & operator=(const AnalysisObject &ao)
Default copy assignment operator.
void transformY(Scatter2D &s, FNY fy)
Apply transformation fy(y) to all values and error positions (operates in-place on s) ...
Definition: Scatter2D.h:416
void combineWith(const std::vector< Scatter2D > &others)
Definition: Scatter2D.h:299
Points & points()
Get the collection of points (non-const)
Definition: Scatter2D.h:194
std::shared_ptr< Scatter2D > Ptr
Definition: Scatter2D.h:31
A 2D data point to be contained in a Scatter2D.
Definition: Point2D.h:19