yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis 2.0.2
Scatter.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-2024 The YODA collaboration (see AUTHORS for details)
5//
6#ifndef YODA_Scatter_h
7#define YODA_Scatter_h
8
10#include "YODA/Point.h"
11#include "YODA/Transformation.h"
12#include "YODA/Utils/Traits.h"
14#include "YODA/Utils/ndarray.h"
15#include <vector>
16#include <set>
17#include <string>
18#include <utility>
19#include <memory>
20
21namespace YODA {
22
24 namespace {
25
26 // Checks that the first half of tuple arguments
27 // can be cast to double and the second half
28 // to pair<double,double>
29 template<class T, class U, typename = void>
30 struct HalfValsHalfPairs : std::false_type { };
31 //
32 template<class T, size_t... Is>
33 struct HalfValsHalfPairs<T, std::index_sequence<Is...>,
34 std::enable_if_t<( std::is_same<double,
35 std::common_type_t<std::tuple_element_t<Is,T>...,
36 double>>::value && // first half double
37 std::is_same<std::pair<double,double>,
38 std::common_type_t<std::tuple_element_t<sizeof...(Is)+Is,T>...,
39 std::pair<double,double>>>::value // second half pair<double,double>
40 )>> : std::true_type { };
41 }
42
44 class Scatter {
45 public:
46
48
50 virtual ~Scatter() {}
51
53
54
56 virtual size_t dim() const noexcept = 0;
57
58
60
61
63 virtual void reset() = 0;
64
66 //virtual void scale(size_t i, double scale) = 0;
67
69
70
72
73
75 virtual size_t numPoints() const = 0;
76
77
80
82 virtual void rmPoint(size_t index) = 0;
83
85 virtual void rmPoints(std::vector<size_t> indices) {
86 // remove points in decreasing order, so the numbering isn't invalidated mid-loop:
87 std::sort(indices.begin(), indices.end(), std::greater<size_t>()); //< reverse-sort
88 for (size_t i : indices) rmPoint(i);
89 }
90
92
93
100
101 // /// Insert a new point, defined as the x value and no errors
102 // void addPoint(double x) {
103 // Point1D thisPoint=Point1D(x);
104 // thisPoint.setParentAO(this);
105 // _points.insert(thisPoint);
106 // }
107
108 // /// Insert a new point, defined as the x value and symmetric errors
109 // void addPoint(double x, double ex) {
110 // Point1D thisPoint=Point1D(x, ex);
111 // thisPoint.setParentAO(this);
112 // _points.insert(thisPoint);
113 // }
114
115 // /// Insert a new point, defined as the x value and an asymmetric error pair
116 // void addPoint(double x, const std::pair<double,double>& ex) {
117 // Point1D thisPoint=Point1D(x, ex);
118 // thisPoint.setParentAO(this);
119 // _points.insert(thisPoint);
120 // }
121
122 // /// Insert a new point, defined as the x value and explicit asymmetric errors
123 // void addPoint(double x, double exminus, double explus) {
124 // Point1D thisPoint=Point1D(x, exminus, explus);
125 // thisPoint.setParentAO(this);
126 // _points.insert(thisPoint);
127 // }
128
129 // /// Insert a collection of new points
130 // void addPoints(const Points& pts) {
131 // for (const Point1D& pt : pts) addPoint(pt);
132 // }
133
135
136
137 // /// Equality operator
138 // bool operator == (const Scatter1D& other) {
139 // return _points == other._points;
140 // }
141
142 // /// Non-equality operator
143 // bool operator != (const Scatter1D& other) {
144 // return ! operator == (other);
145 // }
146
147 };
148
149
150
151
153 template <size_t N>
154 class ScatterND : public AnalysisObject, public Scatter {
155 protected:
156
157 // Convenient aliases
158 using Pair = std::pair<double,double>;
159 using ValVec = std::vector<double>;
160 using PairVec = std::vector<Pair>;
161 using ValList = std::initializer_list<double>;
162 using PairList = std::initializer_list<Pair>;
163
164 // extract the content type of an array Arr
165 template<typename Arr>
166 using containedType = std::decay_t<decltype(*std::declval<Arr>().begin())>;
167
168 // check if content type of an array Arr is Pair
169 template<typename Arr>
170 using containsPair = typename std::is_same<containedType<Arr>, Pair>;
171
172 // succeeds if the first argument is vector<vector<double> (or similar iterable)
173 // and the second argument is vector<vector<Pair>> (or similar iterable)
174 template<typename T, typename U>
175 using enableIfNestedArrayWithPair = std::enable_if_t<(isIterable<T,U,containedType<T>,containedType<U>> &&
177
178 // check if every element in parameter pack can be cast to double
179 template<typename... Args>
180 using isAllVals = std::is_same<double, std::common_type_t<Args..., double>>;
181
182 // check if every element in first half of parameter pack can be
183 // cast to double and every element in the second half to Pair
184 // (based on helper struct defined at the top of the file)
185 template<typename... Args>
186 using isHalfValsHalfPairs = HalfValsHalfPairs<std::tuple<Args...>, std::make_index_sequence<N>>;
187
188 public:
189
190 // Typedefs
191 using NdVal = Utils::ndarray<double, N>;
192 using NdValPair = Utils::ndarray<std::pair<double,double>, N>;
194 using Points = Utils::sortedvector<Point>;
195 using Ptr = std::shared_ptr<ScatterND>;
196 using AnalysisObject::operator =;
197
198
201
203 ScatterND(const std::string& path = "", const std::string& title="")
204 : AnalysisObject("Scatter"+std::to_string(N)+"D", path, title) { }
205
208 const std::string& path="", const std::string& title="")
209 : AnalysisObject("Scatter"+std::to_string(N)+"D", path, title),
210 _points(points) { }
211
214 const std::string& path="", const std::string& title="")
215 : AnalysisObject("Scatter"+std::to_string(N)+"D", path, title),
216 _points(std::move(points)) { }
217
219 template <typename ValRange = std::initializer_list<ValList>,
220 typename = std::enable_if_t<isIterable<ValRange, containedType<ValRange>>>> // enable if is nested array
221 ScatterND(ValRange&& positions, const std::string& path="", const std::string& title="")
222 : AnalysisObject("Scatter"+std::to_string(N)+"D", path, title) {
223 for (size_t i = 0; i < positions.size(); ++i) {
224 addPoint(PointND<N>(std::forward<containedType<ValRange>>(positions[i])));
225 }
226 }
227
229 template <typename ValRange = std::initializer_list<ValList>,
230 typename = std::enable_if_t<isIterable<ValRange, containedType<ValRange>>>> // enable if is nested array
231 ScatterND(ValRange&& positions, ValRange&& errors, const std::string& path="", const std::string& title="")
232 : AnalysisObject("Scatter"+std::to_string(N)+"D", path, title) {
233 if (positions.size() != errors.size()) throw RangeError("Number of errors doesn't match number of positions");
234 for (size_t i = 0; i < positions.size(); ++i) {
235 addPoint(PointND<N>(std::forward<containedType<ValRange>>(positions[i]),
236 std::forward<containedType<ValRange>>(errors[i])));
237 }
238 }
239
241 template <typename ValRange = std::initializer_list<ValList>,
242 typename PairRange = std::initializer_list<PairList>,
243 typename = enableIfNestedArrayWithPair<ValRange,PairRange>>
244 ScatterND(ValRange&& positions, PairRange&& errors, const std::string& path="", const std::string& title="")
245 : AnalysisObject("Scatter"+std::to_string(N)+"D", path, title) {
246 if (positions.size() != errors.size()) throw RangeError("Number of error pairs doesn't match number of positions");
247 for (size_t i = 0; i < positions.size(); ++i) {
248 addPoint(PointND<N>(std::forward<containedType<ValRange>>(positions[i]),
249 std::forward<containedType<PairRange>>(errors[i])));
250 }
251 }
252
254 ScatterND(const ScatterND<N>& s, const std::string& path = "")
255 : AnalysisObject("Scatter"+std::to_string(N)+"D", (path != "")? path : s.path(), s, s.title()),
256 _points(s._points) { }
257
259 ScatterND(ScatterND<N>&& s, const std::string& path = "")
260 : AnalysisObject("Scatter"+std::to_string(N)+"D", (path != "")? path : s.path(), s, s.title()),
261 _points(std::move(s._points)) {
262 }
263
264
267 if (this != &s) {
269 _points = s._points;
270 }
271 return *this;
272 }
273
276 if (this != &s) {
278 _points = std::move(s._points);
279 }
280 return *this;
281 }
282
285 return ScatterND<N>(*this);
286 }
287
290 return new ScatterND<N>(*this);
291 }
292
294
296 size_t dim() const noexcept { return N; }
297
300
302 void reset() {
303 _points.clear();
304 }
305
307 void scale(const NdVal& scales) {
308 for (PointND<N>& p : _points) p.scale(scales);
309 }
310
311 void scale(const std::vector<double>& scales) {
312 if (scales.size() != N) throw RangeError("Expected " + std::to_string(N) + " scale factors");
313 for (PointND<N>& p : _points) p.scale(scales);
314 }
315
317 void scale(const size_t i, double factor) {
318 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
319 for (PointND<N>& p : _points) p.scale(i, factor);
320 }
321
323 void scaleVal(const size_t i, double factor) {
324 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
325 for (PointND<N>& p : _points) p.scaleVal(i, factor);
326 }
327
329 void scaleErr(const size_t i, double factor) {
330 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
331 for (PointND<N>& p : _points) p.scaleErr(i, factor);
332 }
333
335
336
338
339
342
344 size_t numPoints() const {
345 return _points.size();
346 }
347
348
351 return _points;
352 }
353
354
356 const Points& points() const {
357 return _points;
358 }
359
360
362 PointND<N>& point(size_t index) {
363 return _points.at(index);
364 }
365
366
368 const PointND<N>& point(size_t index) const {
369 return _points.at(index);
370 }
371
373
374
377
380 _points.insert(pt);
381 return *this;
382 }
383
386 _points.insert(std::move(pt));
387 return *this;
388 }
389
391 template <typename ValRange = ValList,
392 typename = std::enable_if_t<isIterable<ValRange>>>
393 ScatterND<N>& addPoint(ValRange&& pos) {
394 _points.insert(PointND<N>(std::forward<ValRange>(pos)));
395 return *this;
396 }
397
399 template <typename ValRange = ValList,
400 typename = std::enable_if_t<isIterable<ValRange>>>
401 ScatterND<N>& addPoint(ValRange&& pos, ValRange&& err) {
402 _points.insert(PointND<N>(std::forward<ValRange>(pos), std::forward<ValRange>(err)));
403 return *this;
404 }
405
407 template <typename ValRange = ValList,
408 typename = std::enable_if_t<isIterable<ValRange>>>
409 ScatterND<N>& addPoint(ValRange&& pos, ValRange&& errdn, ValRange&& errup) {
410 _points.insert(PointND<N>(std::forward<ValRange>(pos),
411 std::forward<ValRange>(errdn),
412 std::forward<ValRange>(errup)));
413 return *this;
414 }
415
417 template <typename ValRange = ValList, typename PairRange = PairList>
418 auto addPoint(ValRange&& pos, PairRange&& err)
419 -> std::enable_if_t<(isIterable<ValRange,PairRange> && containsPair<PairRange>::value), ScatterND<N>>& {
420 _points.insert(PointND<N>(pos, err));
421 return *this;
422 }
423
445 template<typename... Args>
446 auto addPoint(Args&&... args)
447 -> std::enable_if_t<(sizeof...(Args) == 2*N || sizeof...(Args) == 3*N), ScatterND<N>>& {
448 return addPoint_aux(std::make_tuple(std::forward<Args>(args)...), std::make_index_sequence<N>{});
449 }
450
451 protected:
452
468 template<typename... Args, size_t... Is>
469 auto addPoint_aux(std::tuple<Args...>&& t, std::index_sequence<Is...>)
470 -> std::enable_if_t<(isAllVals<Args...>::value), ScatterND<N>>& {
471 if constexpr(sizeof...(Args) == 2*N) { // Case 1: symmetric errors
472 _points.insert(
473 PointND<N>( ValVec{ static_cast<double>(std::get<Is>(t))...},
474 PairVec{{static_cast<double>(std::get<N+Is>(t)),
475 static_cast<double>(std::get<N+Is>(t))}...} ));
476 }
477 else { // Case 2: asymmetric errors
478 _points.insert(PointND<N>( ValVec{ static_cast<double>(std::get<Is>(t))...},
479 PairVec{{static_cast<double>(std::get<N+2*Is>(t)),
480 static_cast<double>(std::get<N+2*Is+1>(t))}...} ));
481 }
482 return *this;
483 }
484
485
499 template<typename... Args, size_t... Is>
500 auto addPoint_aux(std::tuple<Args...>&& t, std::index_sequence<Is...>) // Case 3: error pairs
501 -> std::enable_if_t<(sizeof...(Args) == 2*N && isHalfValsHalfPairs<Args...>::value), ScatterND<N>>& {
502 _points.insert(PointND<N>( ValVec{ static_cast<double>(std::get<Is>(t))...},
503 PairVec{ static_cast<Pair>(std::get<N+Is>(t))...} ));
504 return *this;
505 }
506
507
508 public:
509
512 for (const PointND<N>& pt : pts) addPoint(pt);
513 return *this;
514 }
515
516 void rmPoint(size_t index) {
517 _points.erase(_points.begin()+index);
518 }
519
521
523
524
525 size_t lengthContent(bool fixed_length = false) const noexcept {
526 if (fixed_length) return 0;
527 return numPoints() * Point::DataSize::value;
528 }
529
530 std::vector<double> serializeContent(bool fixed_length = false) const noexcept {
531
532 if (fixed_length) return { }; // cannot guarantee fixed length
533
534 std::vector<double> rtn;
535 rtn.reserve(numPoints() * Point::DataSize::value);
536 for (size_t i = 0; i < numPoints(); ++i) {
537 std::vector<double> pdata = point(i)._serializeContent();
538 rtn.insert(std::end(rtn),
539 std::make_move_iterator(std::begin(pdata)),
540 std::make_move_iterator(std::end(pdata)));
541 }
542 return rtn;
543 }
544
545 void deserializeContent(const std::vector<double>& data) {
546
547 if (data.size() % Point::DataSize::value)
548 throw UserError("Length of serialized data should be a multiple of "+std::to_string(Point::DataSize::value)+"!");
549
550 const size_t nPoints = data.size()/Point::DataSize::value;
551 const auto itr = data.cbegin();
552 reset();
553 for (size_t i = 0; i < nPoints; ++i) {
554 addPoint(Point());
555 auto first = itr + i*Point::DataSize::value;
556 auto last = first + Point::DataSize::value;
557 point(i)._deserializeContent(std::vector<double>{first, last});
558 }
559
560 }
561
562 // @}
563
566
569 addPoints(other.points());
570 return *this;
571 }
572
575 addPoints(std::move(other._points));
576 return *this;
577 }
578
580 ScatterND<N>& combineWith(const std::vector< ScatterND<N> >& others) {
581 for (const ScatterND<N>& s : others) combineWith(s);
582 return *this;
583 }
584
586 ScatterND<N>& combineWith(std::vector< ScatterND<N> >&& others) {
587 for (ScatterND<N>&& s : others) combineWith(std::move(s));
588 return *this;
589 }
590
592
595
597 ValVec vals(const size_t i) const {
598 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
599 ValVec rtn; rtn.reserve(_points.size());
600 for (const auto& pt : _points) {
601 rtn.push_back( pt.val(i) );
602 }
603 return rtn;
604 }
605
607 ValVec mins(const size_t i) const {
608 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
609 ValVec rtn; rtn.reserve(_points.size());
610 for (const auto& pt : _points) {
611 rtn.push_back( pt.min(i) );
612 }
613 return rtn;
614 }
615
617 ValVec maxs(const size_t i) const {
618 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
619 ValVec rtn; rtn.reserve(_points.size());
620 for (const auto& pt : _points) {
621 rtn.push_back( pt.max(i) );
622 }
623 return rtn;
624 }
625
627 double min(const size_t i) const {
628 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
629 const ValVec cvals = vals(i);
630 return *std::min_element(cvals.begin(), cvals.end());
631 }
632
634 double max(const size_t i) const {
635 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
636 const ValVec cvals = vals(i);
637 return *std::max_element(cvals.begin(), cvals.end());
638 }
639
641 PairVec errs(const size_t i) const {
642 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
643 PairVec rtn; rtn.reserve(_points.size());
644 for (const auto& pt : _points) {
645 rtn.push_back( pt.errs(i) );
646 }
647 return rtn;
648 }
649
651 ValVec errAvgs(const size_t i) const {
652 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
653 ValVec rtn; rtn.reserve(_points.size());
654 for (const auto& pt : _points) {
655 rtn.push_back( pt.errAvg(i) );
656 }
657 return rtn;
658 }
659
661 ValVec xVals() const { return vals(0); }
662
664 template<size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
665 ValVec yVals() const { return vals(1); }
666
668 template<size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
669 ValVec zVals() const { return vals(2); }
670
672 ValVec xMins() const { return mins(0); }
673
675 template<size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
676 ValVec yMins() const { return mins(1); }
677
679 template<size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
680 ValVec zMins() const { return mins(2); }
681
683 ValVec xMaxs() const { return maxs(0); }
684
686 template<size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
687 ValVec yMaxs() const { return maxs(1); }
688
690 template<size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
691 ValVec zMaxs() const { return maxs(2); }
692
694 double xMin() const { return min(0); }
695
697 template<size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
698 double yMin() const { return min(1); }
699
701 template<size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
702 double zMin() const { return min(2); }
703
705 double xMax() const { return max(0); }
706
708 template<size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
709 double yMax() const { return max(1); }
710
712 template<size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
713 double zMax() const { return max(2); }
714
716 PairVec xErrs() const { return errs(0); }
717
719 template<size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
720 PairVec yErrs() const { return errs(1); }
721
723 template<size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
724 PairVec zErrs() const { return errs(2); }
725
727 ValVec xErrAvgs() const { return errAvgs(0); }
728
730 template<size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
731 ValVec yErrAvgs() const { return errAvgs(1); }
732
734 template<size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
735 ValVec zErrAvgs() const { return errAvgs(2); }
736
738
741
742 // @brief Render information about this AO
743 void _renderYODA(std::ostream& os, const int width = 13) const noexcept {
744
745 os << "# ";
746 for (size_t i = 0; i < N; ++i) {
747 os << std::setw(width - int(i? 0 : 2)) << std::left << ("val" + std::to_string(i+1)) << "\t"
748 << std::setw(width) << std::left << ("err" + std::to_string(i+1) + "-") << "\t"
749 << std::setw(width) << std::left << ("err" + std::to_string(i+1) + "+") << "\t";
750 }
751 os << "\n";
752
753 for (const auto& pt : _points) {
754 pt._renderYODA(os, width);
755 }
756 }
757
758 // @brief Render information about this AO
759 void _renderFLAT(std::ostream& os, const int width = 13) const noexcept { _renderYODA(os, width); }
760
762
765
766 std::vector<Pair> edges(const size_t i) const {
767 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
768 std::vector<Pair> rtn;
769 rtn.resize(numPoints());
770 size_t j = 0;
771 for (const Point& p : points()) {
772 rtn[j++] = std::make_pair(p.min(i), p.max(i));
773 }
774 std::sort(rtn.begin(), rtn.end());
775 rtn.erase(std::unique(rtn.begin(), rtn.end()), rtn.end());
776 return rtn;
777 }
778
780
781 private:
782
783 Points _points;
784
785 };
786
787
790
791 template <int N>
793 a.combineWith(b);
794 return a;
795 }
796
797 template <int N>
799 a.combineWith(std::move(b));
800 return a;
801 }
802
803 template <int N>
804 inline ScatterND<N> combine(const std::vector< ScatterND<N> >& scatters) {
805 ScatterND<N> rtn;
806 rtn.combineWith(scatters);
807 return rtn;
808 }
809
810 template <int N>
811 inline ScatterND<N> combine(std::vector< ScatterND<N> >&& scatters) {
812 ScatterND<N> rtn;
813 rtn.combineWith(std::move(scatters));
814 return rtn;
815 }
816
818
819
821
822
823 // /// @name Combining scatters: global operators, assuming aligned points
824 // /// @{
825
826 // /// Add two scatters
827 // template <size_t N>
828 // Scatter add(const Scatter& first, const Scatter& second);
829
830
831 // /// Add two scatters
832 // template <size_t N>
833 // inline Scatter operator + (const Scatter& first, const Scatter& second) {
834 // return add(first, second);
835 // }
836
837
838 // /// Subtract two scatters
839 // template <size_t N>
840 // Scatter subtract(const Scatter& first, const Scatter& second);
841
842
843 // /// Subtract two scatters
844 // template <size_t N>
845 // inline Scatter operator - (const Scatter& first, const Scatter& second) {
846 // return subtract(first, second);
847 // }
848
849
850 // /// Divide two scatters
851 // template <size_t N>
852 // Scatter divide(const Scatter& numer, const Scatter& denom);
853
854
855 // /// Divide two scatters
856 // template <size_t N>
857 // inline Scatter operator / (const Scatter& numer, const Scatter& denom) {
858 // return divide(numer, denom);
859 // }
860
861 // /// @}
862
863
865
866
869
870 template<size_t N>
871 inline void transform(ScatterND<N>& s, const Trf<N>& fn, const size_t i) {
872 for (auto& p : s.points()) {
873 p.transform(i, fn);
874 }
875 }
876
877 template<size_t N, typename FN>
878 inline void transform(ScatterND<N>& s, const FN& fn, const size_t i) {
879 transform(s, Trf<N>(fn), i);
880 }
881
882 template<size_t N, typename FN>
883 inline void transformX(ScatterND<N>& s, const FN& fn) {
884 transform(s, fn, 0);
885 }
886
887 template<size_t N, typename FN>
888 inline void transformY(ScatterND<N>& s, const FN& fn) {
889 transform(s, fn, 1);
890 }
891
892 template<size_t N, typename FN>
893 inline void transformZ(ScatterND<N>& s, const FN& fn) {
894 transform(s, fn, 2);
895 }
896
898
901
906 using S1D = Scatter1D;
907 using S2D = Scatter2D;
908 using S3D = Scatter3D;
909 using S4D = Scatter4D;
910
912
913
914}
915
916#endif
AnalysisObject is the base class for histograms and scatters.
virtual AnalysisObject & operator=(const AnalysisObject &ao) noexcept
Default copy assignment operator.
const std::string title() const
Get the AO title.
const std::string path() const
Get the AO path.
Error for e.g. use of invalid bin ranges.
Definition Exceptions.h:34
A generic data type which is just a collection of n-dim data points with errors.
Definition Scatter.h:154
auto addPoint_aux(std::tuple< Args... > &&t, std::index_sequence< Is... >) -> std::enable_if_t<(sizeof...(Args)==2 *N &&isHalfValsHalfPairs< Args... >::value), ScatterND< N > > &
Definition Scatter.h:500
typename std::is_same< containedType< Arr >, Pair > containsPair
Definition Scatter.h:170
std::decay_t< decltype(*std::declval< Arr >().begin())> containedType
Definition Scatter.h:166
std::vector< Pair > edges(const size_t i) const
Definition Scatter.h:766
double zMin() const
Axis-specific alias.
Definition Scatter.h:702
size_t numPoints() const
Number of points in the scatter.
Definition Scatter.h:344
double yMin() const
Axis-specific alias.
Definition Scatter.h:698
ScatterND(const ScatterND< N > &s, const std::string &path="")
Copy constructor with optional new path.
Definition Scatter.h:254
void scale(const size_t i, double factor)
Scale value and error along direction i.
Definition Scatter.h:317
ScatterND< N > * newclone() const
Make a copy on the heap, via 'new'.
Definition Scatter.h:289
PointND< N > & point(size_t index)
Get a reference to the point with index index.
Definition Scatter.h:362
ValVec xErrAvgs() const
Axis-specific alias.
Definition Scatter.h:727
std::enable_if_t<(isIterable< T, U, containedType< T >, containedType< U > > &&containsPair< containedType< U > >::value)> enableIfNestedArrayWithPair
Definition Scatter.h:176
double zMax() const
Axis-specific alias.
Definition Scatter.h:713
size_t lengthContent(bool fixed_length=false) const noexcept
Length of serialized content vector for MPI reduce operations.
Definition Scatter.h:525
ScatterND< N > & addPoint(ValRange &&pos, ValRange &&errdn, ValRange &&errup)
Insert a new point from position and asymmetric error arrays (of N elements)
Definition Scatter.h:409
ValVec maxs(const size_t i) const
Get the positive error vector along axis i.
Definition Scatter.h:617
ScatterND< N > clone() const
Make a copy on the stack.
Definition Scatter.h:284
double max(const size_t i) const
Get the largest central value along axis i.
Definition Scatter.h:634
ValVec yVals() const
Axis-specific alias.
Definition Scatter.h:665
size_t dim() const noexcept
Dimension of this data object.
Definition Scatter.h:296
HalfValsHalfPairs< std::tuple< Args... >, std::make_index_sequence< N > > isHalfValsHalfPairs
Definition Scatter.h:186
Utils::sortedvector< Point > Points
Definition Scatter.h:194
const PointND< N > & point(size_t index) const
Get the point with index index (const version)
Definition Scatter.h:368
auto addPoint(Args &&... args) -> std::enable_if_t<(sizeof...(Args)==2 *N||sizeof...(Args)==3 *N), ScatterND< N > > &
Definition Scatter.h:446
ScatterND(ScatterND< N > &&s, const std::string &path="")
Move constructor with optional new path.
Definition Scatter.h:259
std::initializer_list< Pair > PairList
Definition Scatter.h:162
PairVec zErrs() const
Axis-specific alias.
Definition Scatter.h:724
ValVec vals(const size_t i) const
Get the coordinate vector along axis i.
Definition Scatter.h:597
void rmPoint(size_t index)
Remove the point with index index.
Definition Scatter.h:516
ScatterND(ValRange &&positions, PairRange &&errors, const std::string &path="", const std::string &title="")
Constructor from vectors of values for positions and a single set of symmetric errors.
Definition Scatter.h:244
ScatterND< N > & addPoint(const PointND< N > &pt)
Insert a new point.
Definition Scatter.h:379
void scaleErr(const size_t i, double factor)
Scale error along direction i.
Definition Scatter.h:329
const Points & points() const
Get the collection of points (const version)
Definition Scatter.h:356
ScatterND< N > & combineWith(const ScatterND< N > &other)
Definition Scatter.h:568
Utils::ndarray< std::pair< double, double >, N > NdValPair
Definition Scatter.h:192
PairVec yErrs() const
Axis-specific alias.
Definition Scatter.h:720
ValVec xMaxs() const
Axis-specific alias.
Definition Scatter.h:683
ValVec mins(const size_t i) const
Get the lowest value vector along axis i.
Definition Scatter.h:607
void scaleVal(const size_t i, double factor)
Scale value along direction i.
Definition Scatter.h:323
ScatterND< N > & combineWith(std::vector< ScatterND< N > > &&others)
Definition Scatter.h:586
ScatterND< N > & operator=(const ScatterND< N > &s)
Assignment operator.
Definition Scatter.h:266
Utils::ndarray< double, N > NdVal
Definition Scatter.h:191
ScatterND< N > & combineWith(const std::vector< ScatterND< N > > &others)
Definition Scatter.h:580
std::vector< Pair > PairVec
Definition Scatter.h:160
PointND< N > Point
Definition Scatter.h:193
ScatterND(const std::string &path="", const std::string &title="")
Empty constructor.
Definition Scatter.h:203
void deserializeContent(const std::vector< double > &data)
Content deserialisation for MPI reduce operations.
Definition Scatter.h:545
ScatterND(Points &&points, const std::string &path="", const std::string &title="")
Constructor from a set of rvalue points.
Definition Scatter.h:213
double min(const size_t i) const
Get the smallest central value along axis i.
Definition Scatter.h:627
ValVec xMins() const
Axis-specific alias.
Definition Scatter.h:672
PairVec errs(const size_t i) const
Get the error pairs along axis i.
Definition Scatter.h:641
auto addPoint_aux(std::tuple< Args... > &&t, std::index_sequence< Is... >) -> std::enable_if_t<(isAllVals< Args... >::value), ScatterND< N > > &
Definition Scatter.h:469
Points & points()
Get the collection of points.
Definition Scatter.h:350
ScatterND(ValRange &&positions, const std::string &path="", const std::string &title="")
Constructor from a vector of position values with no errors.
Definition Scatter.h:221
ValVec zErrAvgs() const
Axis-specific alias.
Definition Scatter.h:735
ScatterND< N > & addPoint(ValRange &&pos)
Insert a new point from a position array (of N elements)
Definition Scatter.h:393
double yMax() const
Axis-specific alias.
Definition Scatter.h:709
ValVec xVals() const
Axis-specific alias.
Definition Scatter.h:661
std::is_same< double, std::common_type_t< Args..., double > > isAllVals
Definition Scatter.h:180
ValVec errAvgs(const size_t i) const
Get the average error along axis i.
Definition Scatter.h:651
ValVec zVals() const
Axis-specific alias.
Definition Scatter.h:669
ScatterND< N > & addPoints(Points pts)
Insert a collection of new points.
Definition Scatter.h:511
PairVec xErrs() const
Axis-specific alias.
Definition Scatter.h:716
ValVec zMins() const
Axis-specific alias.
Definition Scatter.h:680
void reset()
Clear all points.
Definition Scatter.h:302
ScatterND< N > & combineWith(ScatterND< N > &&other)
Definition Scatter.h:574
void scale(const NdVal &scales)
Scaling.
Definition Scatter.h:307
std::shared_ptr< ScatterND > Ptr
Definition Scatter.h:195
ScatterND< N > & addPoint(ValRange &&pos, ValRange &&err)
Insert a new point from position and symmetric error arrays (of N elements)
Definition Scatter.h:401
ValVec yMins() const
Axis-specific alias.
Definition Scatter.h:676
ScatterND(const Points &points, const std::string &path="", const std::string &title="")
Constructor from a set of points.
Definition Scatter.h:207
auto addPoint(ValRange &&pos, PairRange &&err) -> std::enable_if_t<(isIterable< ValRange, PairRange > &&containsPair< PairRange >::value), ScatterND< N > > &
Insert a new point from a position and error-pair array.
Definition Scatter.h:418
void scale(const std::vector< double > &scales)
Definition Scatter.h:311
std::pair< double, double > Pair
Definition Scatter.h:158
ValVec yMaxs() const
Axis-specific alias.
Definition Scatter.h:687
std::initializer_list< double > ValList
Definition Scatter.h:161
ScatterND(ValRange &&positions, ValRange &&errors, const std::string &path="", const std::string &title="")
Constructor from vectors of values for positions and a single set of symmetric errors.
Definition Scatter.h:231
double xMin() const
Axis-specific alias.
Definition Scatter.h:694
std::vector< double > ValVec
Definition Scatter.h:159
double xMax() const
Axis-specific alias.
Definition Scatter.h:705
std::vector< double > serializeContent(bool fixed_length=false) const noexcept
Content serialisation for MPI reduce operations.
Definition Scatter.h:530
ScatterND< N > & addPoint(PointND< N > &&pt)
Insert a new rvalue point.
Definition Scatter.h:385
ValVec yErrAvgs() const
Axis-specific alias.
Definition Scatter.h:731
ValVec zMaxs() const
Axis-specific alias.
Definition Scatter.h:691
A base class for common operations on scatter types (Scatter1D, etc.)
Definition Scatter.h:44
virtual ~Scatter()
Virtual destructor for inheritance.
Definition Scatter.h:50
virtual size_t numPoints() const =0
Scaling along direction i.
virtual void reset()=0
Clear all points.
virtual size_t dim() const noexcept=0
Dimension of this data object.
virtual void rmPoint(size_t index)=0
Remove the point with index index.
virtual void rmPoints(std::vector< size_t > indices)
Safely remove the points with indices indices.
Definition Scatter.h:85
Error for problems introduced outside YODA, to put it nicely.
Definition Exceptions.h:100
Anonymous namespace to limit visibility.
void transform(BinnedEstimate< AxisT... > &est, const Trf< 1 > &fn)
ScatterND< 3 > Scatter3D
Definition Scatter.h:904
void transformX(ScatterND< N > &s, const FN &fn)
Definition Scatter.h:883
void transformY(ScatterND< N > &s, const FN &fn)
Definition Scatter.h:888
ScatterND< 4 > Scatter4D
Definition Scatter.h:905
void transformZ(ScatterND< N > &s, const FN &fn)
Definition Scatter.h:893
ScatterND< N > combine(ScatterND< N > a, const ScatterND< N > &b)
Definition Scatter.h:792
ScatterND< 1 > Scatter1D
Definition Scatter.h:902
ScatterND< 2 > Scatter2D
Definition Scatter.h:903