|
YODA - Yet more Objects for Data Analysis 2.0.0
|
Go to the documentation of this file.
29 template< class T, class U, typename = void>
30 struct HalfValsHalfPairs : std::false_type { };
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>...,
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
40 )>> : std::true_type { };
56 virtual size_t dim() const noexcept = 0;
85 virtual void rmPoints(std::vector< size_t> indices) {
87 std::sort(indices.begin(), indices.end(), std::greater<size_t>());
88 for ( size_t i : indices) rmPoint(i);
158 using Pair = std::pair<double,double>;
161 using ValList = std::initializer_list<double>;
165 template< typename Arr>
169 template< typename Arr>
174 template< typename T, typename U>
179 template< typename... Args>
180 using isAllVals = std::is_same<double, std::common_type_t<Args..., double>>;
185 template< typename... Args>
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 =;
208 const std::string& path= "", const std::string& title= "")
214 const std::string& path= "", const std::string& title= "")
216 _points(std::move( points)) { }
219 template < typename ValRange = std::initializer_list<ValList>,
220 typename = std::enable_if_t<isIterable<ValRange, containedType<ValRange>>>>
223 for ( size_t i = 0; i < positions.size(); ++i) {
229 template < typename ValRange = std::initializer_list<ValList>,
230 typename = std::enable_if_t<isIterable<ValRange, containedType<ValRange>>>>
231 ScatterND(ValRange&& positions, ValRange&& errors, const std::string& path= "", const std::string& 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) {
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= "")
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) {
256 _points(s._points) { }
261 _points(std::move(s._points)) {
278 _points = std::move(s._points);
296 size_t dim() const noexcept { return N; }
308 for ( PointND<N>& p : _points) p.scale(scales);
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);
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 std::array<double,N> scales;
321 for ( PointND<N>& p : _points) p.scale(scales);
335 return _points.size();
353 return _points.at(index);
359 return _points.at(index);
376 _points.insert(std::move(pt));
381 template < typename ValRange = ValList,
382 typename = std::enable_if_t<isIterable<ValRange>>>
384 _points.insert( PointND<N>(std::forward<ValRange>(pos)));
389 template < typename ValRange = ValList,
390 typename = std::enable_if_t<isIterable<ValRange>>>
392 _points.insert( PointND<N>(std::forward<ValRange>(pos), std::forward<ValRange>(err)));
397 template < typename ValRange = ValList,
398 typename = std::enable_if_t<isIterable<ValRange>>>
400 _points.insert( PointND<N>(std::forward<ValRange>(pos),
401 std::forward<ValRange>(errdn),
402 std::forward<ValRange>(errup)));
407 template < typename ValRange = ValList, typename PairRange = PairList>
435 template< typename... Args>
437 -> std::enable_if_t<( sizeof...(Args) == 2*N || sizeof...(Args) == 3*N), ScatterND<N>>& {
438 return addPoint_aux(std::make_tuple(std::forward<Args>(args)...), std::make_index_sequence<N>{});
458 template< typename... Args, size_t... Is>
461 if constexpr( sizeof...(Args) == 2*N) {
464 PairVec{{ static_cast<double>(std::get<N+Is>(t)),
465 static_cast<double>(std::get<N+Is>(t))}...} ));
468 _points.insert( PointND<N>( ValVec{ static_cast<double>(std::get<Is>(t))...},
469 PairVec{{ static_cast<double>(std::get<N+2*Is>(t)),
470 static_cast<double>(std::get<N+2*Is+1>(t))}...} ));
489 template< typename... Args, size_t... Is>
492 _points.insert( PointND<N>( ValVec{ static_cast<double>(std::get<Is>(t))...},
493 PairVec{ static_cast<Pair>(std::get<N+Is>(t))...} ));
507 _points.erase(_points.begin()+index);
516 if (fixed_length) return 0;
517 return numPoints() * Point::DataSize::value;
522 if (fixed_length) return { };
524 std::vector<double> rtn;
525 rtn.reserve( numPoints() * Point::DataSize::value);
526 for ( size_t i = 0; i < numPoints(); ++i) {
527 std::vector<double> pdata = point(i)._serializeContent();
528 rtn.insert(std::end(rtn),
529 std::make_move_iterator(std::begin(pdata)),
530 std::make_move_iterator(std::end(pdata)));
537 if (data.size() % Point::DataSize::value)
538 throw UserError( "Length of serialized data should be a multiple of "+std::to_string(Point::DataSize::value)+ "!");
540 const size_t nPoints = data.size()/Point::DataSize::value;
541 const auto itr = data.cbegin();
543 for ( size_t i = 0; i < nPoints; ++i) {
545 auto first = itr + i*Point::DataSize::value;
546 auto last = first + Point::DataSize::value;
547 point(i)._deserializeContent(std::vector<double>{first, last});
588 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
589 ValVec rtn; rtn.reserve(_points.size());
590 for ( const auto& pt : _points) {
591 rtn.push_back( pt.val(i) );
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.min(i) );
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.max(i) );
617 double min( const size_t i) const {
618 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
620 return *std::min_element(cvals.begin(), cvals.end());
624 double max( const size_t i) const {
625 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
627 return *std::max_element(cvals.begin(), cvals.end());
632 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
633 PairVec rtn; rtn.reserve(_points.size());
634 for ( const auto& pt : _points) {
635 rtn.push_back( pt.errs(i) );
642 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
643 ValVec rtn; rtn.reserve(_points.size());
644 for ( const auto& pt : _points) {
645 rtn.push_back( pt.errAvg(i) );
654 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
658 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
665 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
669 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
676 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
680 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
687 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
691 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
698 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
702 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
709 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
713 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
722 void _renderYODA(std::ostream& os, const int width = 13) const noexcept {
725 for ( size_t i = 0; i < N; ++i) {
726 os << std::setw(width - int(i? 0 : 2)) << std::left << ( "val" + std::to_string(i+1)) << "\t"
727 << std::setw(width) << std::left << ( "err" + std::to_string(i+1) + "-") << "\t"
728 << std::setw(width) << std::left << ( "err" + std::to_string(i+1) + "+") << "\t";
732 for ( const auto& pt : _points) {
733 pt._renderYODA(os, width);
738 void _renderFLAT(std::ostream& os, const int width = 13) const noexcept { _renderYODA(os, width); }
745 std::vector<Pair> edges( const size_t i) const {
746 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
747 std::vector<Pair> rtn;
751 rtn[j++] = std::make_pair(p.min(i), p.max(i));
753 std::sort(rtn.begin(), rtn.end());
754 rtn.erase(std::unique(rtn.begin(), rtn.end()), rtn.end());
851 for ( auto& p : s. points()) {
856 template< size_t N, typename FN>
861 template< size_t N, typename FN>
866 template< size_t N, typename FN>
871 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)
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.
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
Utils::sortedvector< Point > Points
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 errsAvg(const size_t i) const Get the average error along axis i.
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.
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.
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.
ScatterND(ValRange &&positions, const std::string &path="", const std::string &title="") Constructor from a vector of position values with no errors.
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 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 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)
|