|
YODA - Yet more Objects for Data Analysis 2.1.0
|
Go to the documentation of this file.
28 template< class T, class U, typename = void>
29 struct HalfValsHalfPairs : std::false_type { };
31 template< class T, size_t... Is>
32 struct HalfValsHalfPairs<T, std::index_sequence<Is...>,
33 std::enable_if_t<( std::is_same<double,
34 std::common_type_t<std::tuple_element_t<Is,T>...,
36 std::is_same<std::pair<double,double>,
37 std::common_type_t<std::tuple_element_t<sizeof...(Is)+Is,T>...,
38 std::pair<double,double>>>::value
39 )>> : std::true_type { };
55 virtual size_t dim() const noexcept = 0;
84 virtual void rmPoints(std::vector< size_t> indices) {
86 std::sort(indices.begin(), indices.end(), std::greater<size_t>());
87 for ( size_t i : indices) rmPoint(i);
157 using Pair = std::pair<double,double>;
160 using ValList = std::initializer_list<double>;
164 template< typename Arr>
168 template< typename Arr>
173 template< typename T, typename U>
178 template< typename... Args>
179 using isAllVals = std::is_same<double, std::common_type_t<Args..., double>>;
184 template< typename... Args>
190 using NdVal = Utils::ndarray<double, N>;
191 using NdValPair = Utils::ndarray<std::pair<double,double>, N>;
194 using Ptr = std::shared_ptr<ScatterND>;
195 using AnalysisObject::operator =;
207 const std::string& path= "", const std::string& title= "")
213 const std::string& path= "", const std::string& title= "")
215 _points(std::move( points)) { }
218 template < typename ValRange = std::initializer_list<ValList>,
219 typename = std::enable_if_t<isIterable<ValRange, containedType<ValRange>>>>
222 for ( size_t i = 0; i < positions.size(); ++i) {
228 template < typename ValRange = std::initializer_list<ValList>,
229 typename = std::enable_if_t<isIterable<ValRange, containedType<ValRange>>>>
230 ScatterND(ValRange&& positions, ValRange&& errors, const std::string& path= "", const std::string& title= "")
232 if (positions.size() != errors.size()) throw RangeError( "Number of errors doesn't match number of positions");
233 for ( size_t i = 0; i < positions.size(); ++i) {
240 template < typename ValRange = std::initializer_list<ValList>,
241 typename PairRange = std::initializer_list<PairList>,
242 typename = enableIfNestedArrayWithPair<ValRange,PairRange>>
243 ScatterND(ValRange&& positions, PairRange&& errors, const std::string& path= "", const std::string& title= "")
245 if (positions.size() != errors.size()) throw RangeError( "Number of error pairs doesn't match number of positions");
246 for ( size_t i = 0; i < positions.size(); ++i) {
255 _points(s._points) { }
260 _points(std::move(s._points)) {
277 _points = std::move(s._points);
295 size_t dim() const noexcept { return N; }
307 for ( PointND<N>& p : _points) p.scale(scales);
310 void scale( const std::vector<double>& scales) {
311 if (scales.size() != N) throw RangeError( "Expected " + std::to_string(N) + " scale factors");
312 for ( PointND<N>& p : _points) p.scale(scales);
316 void scale( const size_t i, double factor) {
317 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
318 for ( PointND<N>& p : _points) p.scale(i, factor);
323 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
324 for ( PointND<N>& p : _points) p.scaleVal(i, factor);
329 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
330 for ( PointND<N>& p : _points) p.scaleErr(i, factor);
344 return _points.size();
362 return _points.at(index);
368 return _points.at(index);
379 _points.push_back(pt);
385 _points.push_back(std::move(pt));
390 template < typename ValRange = ValList,
391 typename = std::enable_if_t<isIterable<ValRange>>>
393 _points.push_back( PointND<N>(std::forward<ValRange>(pos)));
398 template < typename ValRange = ValList,
399 typename = std::enable_if_t<isIterable<ValRange>>>
401 _points.push_back( PointND<N>(std::forward<ValRange>(pos), std::forward<ValRange>(err)));
406 template < typename ValRange = ValList,
407 typename = std::enable_if_t<isIterable<ValRange>>>
409 _points.push_back( PointND<N>(std::forward<ValRange>(pos),
410 std::forward<ValRange>(errdn),
411 std::forward<ValRange>(errup)));
416 template < typename ValRange = ValList, typename PairRange = PairList>
444 template< typename... Args>
446 -> std::enable_if_t<( sizeof...(Args) == 2*N || sizeof...(Args) == 3*N), ScatterND<N>>& {
447 return addPoint_aux(std::make_tuple(std::forward<Args>(args)...), std::make_index_sequence<N>{});
467 template< typename... Args, size_t... Is>
470 if constexpr( sizeof...(Args) == 2*N) {
473 PairVec{{ static_cast<double>(std::get<N+Is>(t)),
474 static_cast<double>(std::get<N+Is>(t))}...} ));
477 _points.push_back( PointND<N>( ValVec{ static_cast<double>(std::get<Is>(t))...},
478 PairVec{{ static_cast<double>(std::get<N+2*Is>(t)),
479 static_cast<double>(std::get<N+2*Is+1>(t))}...} ));
498 template< typename... Args, size_t... Is>
501 _points.push_back( PointND<N>( ValVec{ static_cast<double>(std::get<Is>(t))...},
502 PairVec{ static_cast<Pair>(std::get<N+Is>(t))...} ));
516 _points.erase(_points.begin()+index);
525 if (fixed_length) return 0;
526 return numPoints() * Point::DataSize::value;
531 if (fixed_length) return { };
533 std::vector<double> rtn;
535 for ( size_t i = 0; i < numPoints(); ++i) {
536 std::vector<double> pdata = point(i)._serializeContent();
537 rtn.insert(std::end(rtn),
538 std::make_move_iterator(std::begin(pdata)),
539 std::make_move_iterator(std::end(pdata)));
546 if (data.size() % Point::DataSize::value)
547 throw UserError( "Length of serialized data should be a multiple of "+std::to_string(Point::DataSize::value)+ "!");
549 const size_t nPoints = data.size()/Point::DataSize::value;
550 const auto itr = data.cbegin();
552 for ( size_t i = 0; i < nPoints; ++i) {
554 auto first = itr + i*Point::DataSize::value;
555 auto last = first + Point::DataSize::value;
556 point(i)._deserializeContent(std::vector<double>{first, last});
597 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
598 ValVec rtn; rtn.reserve(_points.size());
599 for ( const auto& pt : _points) {
600 rtn.push_back( pt.val(i) );
607 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
608 ValVec rtn; rtn.reserve(_points.size());
609 for ( const auto& pt : _points) {
610 rtn.push_back( pt.min(i) );
617 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
618 ValVec rtn; rtn.reserve(_points.size());
619 for ( const auto& pt : _points) {
620 rtn.push_back( pt.max(i) );
626 double min( const size_t i) const {
627 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
629 return *std::min_element(cvals.begin(), cvals.end());
633 double max( const size_t i) const {
634 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
636 return *std::max_element(cvals.begin(), cvals.end());
641 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
642 PairVec rtn; rtn.reserve(_points.size());
643 for ( const auto& pt : _points) {
644 rtn.push_back( pt.errs(i) );
651 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
652 ValVec rtn; rtn.reserve(_points.size());
653 for ( const auto& pt : _points) {
654 rtn.push_back( pt.errAvg(i) );
663 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
667 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
674 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
678 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
685 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
689 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
696 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
700 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
707 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
711 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
718 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
722 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
729 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
733 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
742 void _renderYODA(std::ostream& os, const int width = 13) const noexcept {
745 for ( size_t i = 0; i < N; ++i) {
746 os << std::setw(width - int(i? 0 : 2)) << std::left << ( "val" + std::to_string(i+1)) << "\t"
747 << std::setw(width) << std::left << ( "err" + std::to_string(i+1) + "-") << "\t"
748 << std::setw(width) << std::left << ( "err" + std::to_string(i+1) + "+") << "\t";
752 for ( const auto& pt : _points) {
753 pt._renderYODA(os, width);
758 void _renderFLAT(std::ostream& os, const int width = 13) const noexcept { _renderYODA(os, width); }
765 std::vector<Pair> edges( const size_t i) const {
766 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
767 std::vector<Pair> rtn;
771 rtn[j++] = std::make_pair(p.min(i), p.max(i));
773 std::sort(rtn.begin(), rtn.end());
774 rtn.erase(std::unique(rtn.begin(), rtn.end()), rtn.end());
871 for ( auto& p : s. points()) {
876 template< size_t N, typename FN>
881 template< size_t N, typename FN>
886 template< size_t N, typename FN>
891 template< size_t N, typename FN>
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.
A generic data type which is just a collection of n-dim data points with errors.
auto addPoint_aux(std::tuple< Args... > &&t, std::index_sequence< Is... >) -> std::enable_if_t<(sizeof...(Args)==2 *N &&isHalfValsHalfPairs< Args... >::value), ScatterND< N > > &
typename std::is_same< containedType< Arr >, Pair > containsPair
std::decay_t< decltype(*std::declval< Arr >().begin())> containedType
std::vector< Pair > edges(const size_t i) const
double zMin() const Axis-specific alias.
size_t numPoints() const Number of points in the scatter.
double yMin() const Axis-specific alias.
ScatterND(const ScatterND< N > &s, const std::string &path="") Copy constructor with optional new path.
void scale(const size_t i, double factor) Scale value and error along direction i.
ScatterND< N > * newclone() const Make a copy on the heap, via 'new'.
PointND< N > & point(size_t index) Get a reference to the point with index index.
ValVec xErrAvgs() const Axis-specific alias.
std::enable_if_t<(isIterable< T, U, containedType< T >, containedType< U > > &&containsPair< containedType< U > >::value)> enableIfNestedArrayWithPair
double zMax() const Axis-specific alias.
size_t lengthContent(bool fixed_length=false) const noexcept Length of serialized content vector for MPI reduce operations.
ScatterND< N > & addPoint(ValRange &&pos, ValRange &&errdn, ValRange &&errup) Insert a new point from position and asymmetric error arrays (of N elements)
ValVec maxs(const size_t i) const Get the positive error vector along axis i.
ScatterND< N > clone() const Make a copy on the stack.
double max(const size_t i) const Get the largest central value along axis i.
ValVec yVals() const Axis-specific alias.
size_t dim() const noexcept Dimension of this data object.
HalfValsHalfPairs< std::tuple< Args... >, std::make_index_sequence< N > > isHalfValsHalfPairs
const PointND< N > & point(size_t index) const Get the point with index index (const version)
auto addPoint(Args &&... args) -> std::enable_if_t<(sizeof...(Args)==2 *N||sizeof...(Args)==3 *N), ScatterND< N > > &
ScatterND(ScatterND< N > &&s, const std::string &path="") Move constructor with optional new path.
std::initializer_list< Pair > PairList
PairVec zErrs() const Axis-specific alias.
ValVec vals(const size_t i) const Get the coordinate vector along axis i.
void rmPoint(size_t index) Remove the point with index index.
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.
ScatterND< N > & addPoint(const PointND< N > &pt) Insert a new point.
void scaleErr(const size_t i, double factor) Scale error along direction i.
const Points & points() const Get the collection of points (const version)
ScatterND< N > & combineWith(const ScatterND< N > &other)
Utils::ndarray< std::pair< double, double >, N > NdValPair
PairVec yErrs() const Axis-specific alias.
ValVec xMaxs() const Axis-specific alias.
ValVec mins(const size_t i) const Get the lowest value vector along axis i.
void scaleVal(const size_t i, double factor) Scale value along direction i.
ScatterND< N > & combineWith(std::vector< ScatterND< N > > &&others)
ScatterND< N > & operator=(const ScatterND< N > &s) Assignment operator.
Utils::ndarray< double, N > NdVal
ScatterND< N > & combineWith(const std::vector< ScatterND< N > > &others)
std::vector< Pair > PairVec
ScatterND(const std::string &path="", const std::string &title="") Empty constructor.
void deserializeContent(const std::vector< double > &data) Content deserialisation for MPI reduce operations.
ScatterND(Points &&points, const std::string &path="", const std::string &title="") Constructor from a set of rvalue points.
double min(const size_t i) const Get the smallest central value along axis i.
ValVec xMins() const Axis-specific alias.
PairVec errs(const size_t i) const Get the error pairs along axis i.
auto addPoint_aux(std::tuple< Args... > &&t, std::index_sequence< Is... >) -> std::enable_if_t<(isAllVals< Args... >::value), ScatterND< N > > &
Points & points() Get the collection of points.
std::vector< Point > Points
ScatterND(ValRange &&positions, const std::string &path="", const std::string &title="") Constructor from a vector of position values with no errors.
ValVec zErrAvgs() const Axis-specific alias.
ScatterND< N > & addPoint(ValRange &&pos) Insert a new point from a position array (of N elements)
double yMax() const Axis-specific alias.
ValVec xVals() const Axis-specific alias.
std::is_same< double, std::common_type_t< Args..., double > > isAllVals
ValVec errAvgs(const size_t i) const Get the average error along axis i.
ValVec zVals() const Axis-specific alias.
ScatterND< N > & addPoints(Points pts) Insert a collection of new points.
PairVec xErrs() const Axis-specific alias.
ValVec zMins() const Axis-specific alias.
void reset() Clear all points.
ScatterND< N > & combineWith(ScatterND< N > &&other)
void scale(const NdVal &scales) Scaling.
std::shared_ptr< ScatterND > Ptr
ScatterND< N > & addPoint(ValRange &&pos, ValRange &&err) Insert a new point from position and symmetric error arrays (of N elements)
ValVec yMins() const Axis-specific alias.
ScatterND(const Points &points, const std::string &path="", const std::string &title="") Constructor from a set of points.
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.
void scale(const std::vector< double > &scales)
std::pair< double, double > Pair
ValVec yMaxs() const Axis-specific alias.
std::initializer_list< double > ValList
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.
double xMin() const Axis-specific alias.
std::vector< double > ValVec
double xMax() const Axis-specific alias.
std::vector< double > serializeContent(bool fixed_length=false) const noexcept Content serialisation for MPI reduce operations.
ScatterND< N > & addPoint(PointND< N > &&pt) Insert a new rvalue point.
ValVec yErrAvgs() const Axis-specific alias.
ValVec zMaxs() const Axis-specific alias.
A base class for common operations on scatter types (Scatter1D, etc.)
virtual ~Scatter() Virtual destructor for inheritance.
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.
Error for problems introduced outside YODA, to put it nicely.
Anonymous namespace to limit visibility.
void transform(BinnedEstimate< AxisT... > &est, const Trf< 1 > &fn)
void transformX(ScatterND< N > &s, const FN &fn)
void transformY(ScatterND< N > &s, const FN &fn)
void transformZ(ScatterND< N > &s, const FN &fn)
ScatterND< N > combine(ScatterND< N > a, const ScatterND< N > &b)
|