|
YODA - Yet more Objects for Data Analysis 2.0.2
|
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);
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);
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);
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);
345 return _points.size();
363 return _points.at(index);
369 return _points.at(index);
386 _points.insert(std::move(pt));
391 template < typename ValRange = ValList,
392 typename = std::enable_if_t<isIterable<ValRange>>>
394 _points.insert( PointND<N>(std::forward<ValRange>(pos)));
399 template < typename ValRange = ValList,
400 typename = std::enable_if_t<isIterable<ValRange>>>
402 _points.insert( PointND<N>(std::forward<ValRange>(pos), std::forward<ValRange>(err)));
407 template < typename ValRange = ValList,
408 typename = std::enable_if_t<isIterable<ValRange>>>
410 _points.insert( PointND<N>(std::forward<ValRange>(pos),
411 std::forward<ValRange>(errdn),
412 std::forward<ValRange>(errup)));
417 template < typename ValRange = ValList, typename PairRange = PairList>
445 template< typename... 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>{});
468 template< typename... Args, size_t... Is>
471 if constexpr( sizeof...(Args) == 2*N) {
474 PairVec{{ static_cast<double>(std::get<N+Is>(t)),
475 static_cast<double>(std::get<N+Is>(t))}...} ));
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))}...} ));
499 template< typename... Args, size_t... Is>
502 _points.insert( PointND<N>( ValVec{ static_cast<double>(std::get<Is>(t))...},
503 PairVec{ static_cast<Pair>(std::get<N+Is>(t))...} ));
517 _points.erase(_points.begin()+index);
526 if (fixed_length) return 0;
527 return numPoints() * Point::DataSize::value;
532 if (fixed_length) return { };
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)));
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)+ "!");
550 const size_t nPoints = data.size()/Point::DataSize::value;
551 const auto itr = data.cbegin();
553 for ( size_t i = 0; i < nPoints; ++i) {
555 auto first = itr + i*Point::DataSize::value;
556 auto last = first + Point::DataSize::value;
557 point(i)._deserializeContent(std::vector<double>{first, last});
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) );
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) );
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) );
627 double min( const size_t i) const {
628 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
630 return *std::min_element(cvals.begin(), cvals.end());
634 double max( const size_t i) const {
635 if (i >= N) throw RangeError( "Invalid axis int, must be in range 0..dim-1");
637 return *std::max_element(cvals.begin(), cvals.end());
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) );
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) );
664 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
668 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
675 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
679 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
686 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
690 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
697 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
701 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
708 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
712 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
719 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
723 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
730 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 2)>>
734 template< size_t axisN = N, typename = std::enable_if_t<(axisN >= 3)>>
743 void _renderYODA(std::ostream& os, const int width = 13) const noexcept {
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";
753 for ( const auto& pt : _points) {
754 pt._renderYODA(os, width);
759 void _renderFLAT(std::ostream& os, const int width = 13) const noexcept { _renderYODA(os, width); }
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;
772 rtn[j++] = std::make_pair(p.min(i), p.max(i));
774 std::sort(rtn.begin(), rtn.end());
775 rtn.erase(std::unique(rtn.begin(), rtn.end()), rtn.end());
872 for ( auto& p : s. points()) {
877 template< size_t N, typename FN>
882 template< size_t N, typename FN>
887 template< size_t N, typename FN>
892 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
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 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.
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)
|