Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F8308993
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
46 KB
Subscribers
None
View Options
diff --git a/include/YODA/Point1D.h b/include/YODA/Point1D.h
--- a/include/YODA/Point1D.h
+++ b/include/YODA/Point1D.h
@@ -1,366 +1,369 @@
// -*- C++ -*-
//
// This file is part of YODA -- Yet more Objects for Data Analysis
// Copyright (C) 2008-2018 The YODA collaboration (see AUTHORS for details)
//
#ifndef YODA_POINT1D_H
#define YODA_POINT1D_H
#include "YODA/Point.h"
#include "YODA/Exceptions.h"
#include "YODA/Utils/MathUtils.h"
#include <utility>
namespace YODA {
/// A 1D data point to be contained in a Scatter1D
class Point1D : public Point {
public:
/// @name Constructors
//@{
// Default constructor
Point1D() { }
/// Constructor from values with optional symmetric errors
Point1D(double x, double ex=0.0, std::string source="")
: _x(x)
{
_ex[source] = std::make_pair(ex, ex);
}
/// Constructor from values with explicit asymmetric errors
Point1D(double x, double exminus, double explus, std::string source="")
: _x(x)
{
_ex[source] = std::make_pair(exminus, explus);
}
/// Constructor from values with asymmetric errors
Point1D(double x, const std::pair<double,double>& ex, std::string source="")
: _x(x)
{
_ex[source] = ex;
}
/// Copy constructor
Point1D(const Point1D& p)
: _x(p._x), _ex(p._ex)
{
this->setParentAO( p.getParentAO());
}
/// Copy assignment
Point1D& operator = (const Point1D& p) {
_x = p._x;
_ex = p._ex;
this->setParentAO( p.getParentAO());
return *this;
}
//@}
public:
/// Space dimension of the point
size_t dim() { return 1; }
/// @name Value accessors
//@{
/// Get x value
double x() const { return _x; }
/// Set x value
void setX(double x) { _x = x; }
/// @todo Uniform "coords" accessor across all Scatters: returning fixed-size tuple?
//@}
/// @name x error accessors
//@{
/// Get x-error values
const std::pair<double,double>& xErrs( std::string source="") const {
+ if (source!="") getVariationsFromParent();
if (!_ex.count(source)) throw RangeError("xErrs has no such key: "+source);
return _ex.at(source);
}
/// Get negative x-error value
double xErrMinus( std::string source="") const {
+ if (source!="") getVariationsFromParent();
if (!_ex.count(source)) throw RangeError("xErrs has no such key: "+source);
return _ex.at(source).first;
}
/// Get positive x-error value
double xErrPlus( std::string source="") const {
+ if (source!="") getVariationsFromParent();
if (!_ex.count(source)) throw RangeError("xErrs has no such key: "+source);
return _ex.at(source).second;
}
/// Get average x-error value
double xErrAvg( std::string source="") const {
+ if (source!="") getVariationsFromParent();
if (!_ex.count(source)) throw RangeError("xErrs has no such key: "+source);
return (_ex.at(source).first + _ex.at(source).second)/2.0;
}
/// Set negative x error
void setXErrMinus(double exminus, std::string source="") {
- if (source!="") getVariationsFromParent();
if (!_ex.count(source)) _ex[source] = std::make_pair(0.,0.);
_ex.at(source).first = exminus;
}
/// Set positive x error
void setXErrPlus(double explus, std::string source="") {
- if (source!="") getVariationsFromParent();
if (!_ex.count(source)) _ex[source] = std::make_pair(0.,0.);
_ex.at(source).second = explus;
}
/// Set symmetric x error
void setXErr(double ex, std::string source="") {
setXErrMinus(ex, source);
setXErrPlus(ex, source);
}
/// Set symmetric x error (alias)
void setXErrs(double ex, std::string source="") {
setXErr(ex, source);
}
/// Set asymmetric x error
void setXErrs(double exminus, double explus, std::string source="") {
setXErrMinus(exminus, source);
setXErrPlus(explus, source);
}
/// Set asymmetric x error
void setXErrs(const std::pair<double,double>& ex, std::string source="") {
- if (source!="") getVariationsFromParent();
_ex[source] = ex;
}
/// Get value minus negative x-error
double xMin(std::string source="") const {
+ if (source!="") getVariationsFromParent();
if (!_ex.count(source)) throw RangeError("xErrs has no such key: "+source);
return _x - _ex.at(source).first;
}
/// Get value plus positive x-error
double xMax(std::string source="") const {
+ if (source!="") getVariationsFromParent();
if (!_ex.count(source)) throw RangeError("xErrs has no such key: "+source);
return _x + _ex.at(source).second;
}
//@}
/// @name Combined x value and error setters
//@{
/// Set x value and symmetric error
void setX(double x, double ex, std::string source="") {
setX(x);
setXErr(ex, source);
}
/// Set x value and asymmetric error
void setX(double x, double exminus, double explus, std::string source="") {
setX(x);
setXErrs(exminus, explus, source);
}
/// Set x value and asymmetric error
void setX(double x, std::pair<double,double>& ex, std::string source="") {
setX(x);
setXErrs(ex, source);
}
//@}
// @name Manipulations
//@{
/// Scaling of x axis
void scaleX(double scalex) {
setX(x()*scalex);
for (const auto &source : _ex){
setXErrs(xErrMinus()*scalex, xErrPlus()*scalex, source.first);
}
}
//@}
/// @name Integer axis accessor equivalents
//@{
/// Get the point value for direction @a i
double val(size_t i) const {
if (i == 0 || i > 1) throw RangeError("Invalid axis int, must be in range 1..dim");
return x();
}
/// Set the point value for direction @a i
void setVal(size_t i, double val) {
if (i != 1) throw RangeError("Invalid axis int, must be in range 1..dim");
setX(val);
}
/// Get error map for direction @a i
const std::map< std::string, std::pair<double,double>> & errMap() const {
getVariationsFromParent();
return _ex;
}
// Parse the variations from the parent AO if it exists
void getVariationsFromParent() const;
/// Get error values for direction @a i
const std::pair<double,double>& errs(size_t i, std::string source="") const {
if (i != 1) throw RangeError("Invalid axis int, must be in range 1..dim");
return xErrs(source);
}
/// Get negative error value for direction @a i
double errMinus(size_t i, std::string source="") const {
if (i != 1) throw RangeError("Invalid axis int, must be in range 1..dim");
return xErrMinus(source);
}
/// Get positive error value for direction @a i
double errPlus(size_t i, std::string source="") const {
if (i != 1) throw RangeError("Invalid axis int, must be in range 1..dim");
return xErrPlus(source);
}
/// Get average error value for direction @a i
double errAvg(size_t i, std::string source="") const {
if (i != 1) throw RangeError("Invalid axis int, must be in range 1..dim");
return xErrAvg(source);
}
/// Set negative error for direction @a i
void setErrMinus(size_t i, double eminus, std::string source="") {
if (i != 1) throw RangeError("Invalid axis int, must be in range 1..dim");
setXErrMinus(eminus, source);
}
/// Set positive error for direction @a i
void setErrPlus(size_t i, double eplus, std::string source="") {
if (i != 1) throw RangeError("Invalid axis int, must be in range 1..dim");
setXErrPlus(eplus, source);
}
/// Set symmetric error for direction @a i
void setErr(size_t i, double e, std::string source="") {
if (i != 1) throw RangeError("Invalid axis int, must be in range 1..dim");
setXErr(e, source);
}
/// Set asymmetric error for direction @a i
void setErrs(size_t i, double eminus, double eplus, std::string source="") {
if (i != 1) throw RangeError("Invalid axis int, must be in range 1..dim");
setXErrs(eminus, eplus, source);
}
/// Set asymmetric error for direction @a i
void setErrs(size_t i, std::pair<double,double>& e, std::string source="") {
if (i != 1) throw RangeError("Invalid axis int, must be in range 1..dim");
setXErrs(e, source);
}
/// Set value and symmetric error for direction @a i
void set(size_t i, double val, double e, std::string source="") {
if (i != 1) throw RangeError("Invalid axis int, must be in range 1..dim");
setX(val, e, source);
}
/// Set value and asymmetric error for direction @a i
void set(size_t i, double val, double eminus, double eplus, std::string source="") {
if (i != 1) throw RangeError("Invalid axis int, must be in range 1..dim");
setX(val, eminus, eplus, source);
}
/// Set value and asymmetric error for direction @a i
void set(size_t i, double val, std::pair<double,double>& e, std::string source="") {
if (i != 1) throw RangeError("Invalid axis int, must be in range 1..dim");
setX(val, e, source);
}
//@}
protected:
/// @name Value and error variables
//@{
double _x;
// a map of the errors for each source. Nominal stored under ""
// to ensure backward compatibility
std::map< std::string, std::pair<double,double> > _ex;
//@}
};
/// @name Comparison operators
//@{
/// Equality test of x characteristics only
/// @todo Base on a named fuzzyEquals(a,b,tol=1e-3) unbound function
inline bool operator==(const YODA::Point1D& a, const YODA::Point1D& b) {
if (!YODA::fuzzyEquals(a.x(), b.x()) ||
!YODA::fuzzyEquals(a.xErrMinus(), b.xErrMinus()) ||
!YODA::fuzzyEquals(a.xErrPlus(), b.xErrPlus()) ) return false;
return true;
}
/// Equality test of x characteristics only
inline bool operator != (const YODA::Point1D& a, const YODA::Point1D& b) {
return !(a == b);
}
/// Less-than operator used to sort bins by x-ordering
inline bool operator < (const YODA::Point1D& a, const YODA::Point1D& b) {
if (!YODA::fuzzyEquals(a.x(), b.x())) {
return a.x() < b.x();
}
if (!YODA::fuzzyEquals(a.xErrMinus(), b.xErrMinus())) {
return a.xErrMinus() < b.xErrMinus();
}
if (!YODA::fuzzyEquals(a.xErrPlus(), b.xErrPlus())) {
return a.xErrPlus() < b.xErrPlus();
}
return false;
}
/// Less-than-or-equals operator used to sort bins by x-ordering
inline bool operator <= (const YODA::Point1D& a, const YODA::Point1D& b) {
if (a == b) return true;
return a < b;
}
/// Greater-than operator used to sort bins by x-ordering
inline bool operator > (const YODA::Point1D& a, const YODA::Point1D& b) {
return !(a <= b);
}
/// Greater-than-or-equals operator used to sort bins by x-ordering
inline bool operator >= (const YODA::Point1D& a, const YODA::Point1D& b) {
return !(a < b);
}
//@}
}
#endif
diff --git a/include/YODA/Point3D.h b/include/YODA/Point3D.h
--- a/include/YODA/Point3D.h
+++ b/include/YODA/Point3D.h
@@ -1,695 +1,692 @@
// -*- C++ -*-
//
// This file is part of YODA -- Yet more Objects for Data Analysis
// Copyright (C) 2008-2018 The YODA collaboration (see AUTHORS for details)
//
#ifndef YODA_POINT3D_H
#define YODA_POINT3D_H
#include "YODA/Point.h"
#include "YODA/Exceptions.h"
#include "YODA/Utils/MathUtils.h"
#include <utility>
namespace YODA {
/// A 3D data point to be contained in a Scatter3D
class Point3D : public Point {
public:
/// @name Constructors
//@{
// Default constructor
Point3D() { }
/// Constructor from values with optional symmetric errors
Point3D(double x, double y, double z, double ex=0.0, double ey=0.0, double ez=0.0, std::string source="")
: _x(x), _y(y), _z(z)
{
_ex = std::make_pair(ex, ex);
_ey = std::make_pair(ey, ey);
_ez[source] = std::make_pair(ez, ez);
}
/// Constructor from values with explicit asymmetric errors
Point3D(double x, double y, double z,
double exminus,
double explus,
double eyminus,
double eyplus,
double ezminus,
double ezplus, std::string source="")
: _x(x), _y(y), _z(z)
{
_ex = std::make_pair(exminus, explus);
_ey = std::make_pair(eyminus, eyplus);
_ez[source] = std::make_pair(ezminus, ezplus);
}
/// Constructor from asymmetric errors given as vectors
Point3D(double x, double y, double z,
const std::pair<double,double>& ex,
const std::pair<double,double>& ey,
const std::pair<double,double>& ez, std::string source="")
: _x(x), _y(y), _z(z),
_ex(ex), _ey(ey)
{
_ez[source] = ez;
}
/// Copy constructor
Point3D(const Point3D& p)
: _x(p._x), _y(p._y), _z(p._z),
_ex(p._ex), _ey(p._ey), _ez(p._ez)
{
this->setParentAO( p.getParentAO());
}
/// Copy assignment
Point3D& operator = (const Point3D& p) {
_x = p._x;
_y = p._y;
_z = p._z;
_ex = p._ex;
_ey = p._ey;
_ez = p._ez;
this->setParentAO( p.getParentAO());
return *this;
}
//@}
public:
/// Space dimension of the point
size_t dim() { return 3; }
/// @name Value and error accessors
//@{
/// Get x value
double x() const { return _x; }
/// Set x value
void setX(double x) { _x = x; }
/// Get y value
double y() const { return _y; }
/// Set y value
void setY(double y) { _y = y; }
/// Get z value
double z() const { return _z;}
/// Set z value
void setZ(double z) { _z = z;}
/// @todo Uniform "coords" accessor across all Scatters: returning fixed-size tuple?
// /// Get x,y,z value tuple
// triple<double,double,double> xyz() const { return std::triple(_x, _y, _z); }
/// Set x, y and z values
void setXYZ(double x, double y, double z) { setX(x); setY(y); setZ(z); }
// /// Set x and y values
// void setXY(triple<double,double,double> xyz) { setX(xy.first); setY(xy.second); setZ(xy.third); }
//@}
/// @name x error accessors
//@{
/// Get x-error values
const std::pair<double,double>& xErrs() const {
return _ex;
}
/// Get negative x-error value
double xErrMinus() const {
return _ex.first;
}
/// Get positive x-error value
double xErrPlus() const {
return _ex.second;
}
/// Get average x-error value
double xErrAvg() const {
return (_ex.first + _ex.second)/2.0;
}
/// Set negative x error
void setXErrMinus(double exminus) {
_ex.first = exminus;
}
/// Set positive x error
void setXErrPlus(double explus) {
_ex.second = explus;
}
/// Set symmetric x error
void setXErr(double ex) {
setXErrMinus(ex);
setXErrPlus(ex);
}
/// Set symmetric x error (alias)
void setXErrs(double ex) {
setXErr(ex);
}
/// Set asymmetric x error
void setXErrs(double exminus, double explus) {
setXErrMinus(exminus);
setXErrPlus(explus);
}
/// Set asymmetric x error
void setXErrs(const std::pair<double,double>& ex) {
_ex = ex;
}
/// Get value minus negative x-error
double xMin() const {
return _x - _ex.first;
}
/// Get value plus positive x-error
double xMax() const {
return _x + _ex.second;
}
//@}
/// @name y error accessors
//@{
/// Get y-error values
const std::pair<double,double>& yErrs() const {
return _ey;
}
/// Get negative y-error value
double yErrMinus() const {
return _ey.first;
}
/// Get positive y-error value
double yErrPlus() const {
return _ey.second;
}
/// Get average y-error value
double yErrAvg() const {
return (_ey.first + _ey.second)/2.0;
}
/// Set negative y error
void setYErrMinus(double eyminus) {
_ey.first = eyminus;
}
/// Set positive y error
void setYErrPlus(double eyplus) {
_ey.second = eyplus;
}
/// Set symmetric y error
void setYErr(double ey) {
setYErrMinus(ey);
setYErrPlus(ey);
}
/// Set symmetric y error (alias)
void setYErrs(double ey) {
setYErr(ey);
}
/// Set asymmetric y error
void setYErrs(double eyminus, double eyplus) {
setYErrMinus(eyminus);
setYErrPlus(eyplus);
}
/// Set asymmetric y error
void setYErrs(const std::pair<double,double>& ey) {
_ey = ey;
}
/// Get value minus negative y-error
double yMin() const {
return _y - _ey.first;
}
/// Get value plus positive y-error
double yMax() const {
return _y + _ey.second;
}
//@}
/// @name z error accessors
//@{
/// Get z-error values
const std::pair<double,double>& zErrs( std::string source="") const {
if (source!="") getVariationsFromParent();
if (!_ez.count(source)) throw RangeError("zErrs has no such key: "+source);
return _ez.at(source);
}
/// Get negative z-error value
double zErrMinus( std::string source="") const {
if (source!="") getVariationsFromParent();
if (!_ez.count(source)) throw RangeError("zErrs has no such key: "+source);
return _ez.at(source).first;
}
/// Get positive z-error value
double zErrPlus( std::string source="") const {
if (source!="") getVariationsFromParent();
if (!_ez.count(source)) throw RangeError("zErrs has no such key: "+source);
return _ez.at(source).second;
}
/// Get average z-error value
double zErrAvg( std::string source="") const {
if (source!="") getVariationsFromParent();
if (!_ez.count(source)) throw RangeError("zErrs has no such key: "+source);
return (_ez.at(source).first + _ez.at(source).second)/2.0;
}
/// Set negative z error
void setZErrMinus(double ezminus, std::string source="") {
- if (source!="") getVariationsFromParent();
if (!_ez.count(source)) _ez[source] = std::make_pair(0.,0.);
_ez.at(source).first = ezminus;
}
/// Set positive z error
void setZErrPlus(double ezplus, std::string source="") {
- if (source!="") getVariationsFromParent();
if (!_ez.count(source)) _ez[source] = std::make_pair(0.,0.);
_ez.at(source).second = ezplus;
}
/// Set symmetric z error
void setZErr(double ez, std::string source="") {
setZErrMinus(ez, source);
setZErrPlus(ez, source);
}
/// Set symmetric z error (alias)
void setZErrs(double ez, std::string source="") {
setZErr(ez, source);
}
/// Set asymmetric z error
void setZErrs(double ezminus, double ezplus, std::string source="") {
setZErrMinus(ezminus, source);
setZErrPlus(ezplus, source);
}
/// Set asymmetric z error
void setZErrs(const std::pair<double,double>& ez, std::string source="") {
- if (source!="") getVariationsFromParent();
_ez[source] = ez;
}
/// Get value minus negative z-error
double zMin( std::string source="") const {
if (source!="") getVariationsFromParent();
if (!_ez.count(source)) throw RangeError("zErrs has no such key: "+source);
return _z - _ez.at(source).first;
}
/// Get value plus positive z-error
double zMax( std::string source="") const {
if (source!="") getVariationsFromParent();
if (!_ez.count(source)) throw RangeError("zErrs has no such key: "+source);
return _z + _ez.at(source).second;
}
//@}
/// @name Combined x/y value and error setters
//@{
/// Set x value and symmetric error
void setX(double x, double ex) {
setX(x);
setXErrs(ex);
}
/// Set x value and asymmetric error
void setX(double x, double exminus, double explus) {
setX(x);
setXErrs(exminus, explus);
}
/// Set x value and asymmetric error
void setX(double x, std::pair<double,double>& ex) {
setX(x);
setXErrs(ex);
}
/// Set y value and symmetric error
void setY(double y, double ey) {
setY(y);
setYErrs(ey);
}
/// Set y value and asymmetric error
void setY(double y, double eyminus, double eyplus) {
setY(y);
setYErrs(eyminus, eyplus);
}
/// Set y value and asymmetric error
void setY(double y, std::pair<double,double>& ey) {
setY(y);
setYErrs(ey);
}
/// Set z value and symmetric error
void setZ(double z, double ez, std::string source="") {
setZ(z);
setZErrs(ez, source);
}
/// Set z value and asymmetric error
void setZ(double z, double ezminus, double ezplus, std::string source="") {
setZ(z);
setZErrs(ezminus, ezplus, source);
}
/// Set z value and asymmetric error
void setZ(double z, std::pair<double,double>& ez, std::string source="") {
setZ(z);
setZErrs(ez, source);
}
//@}
// @name Manipulations
//@{
/// Scaling of x axis
void scaleX(double scalex) {
setX(x()*scalex);
setXErrs(xErrMinus()*scalex, xErrPlus()*scalex);
}
/// Scaling of y axis
void scaleY(double scaley) {
setY(y()*scaley);
setYErrs(yErrMinus()*scaley, yErrPlus()*scaley);
}
/// Scaling of z axis
void scaleZ(double scalez) {
setZ(z()*scalez);
for (const auto &source : _ez){
setZErrs(zErrMinus()*scalez, zErrPlus()*scalez, source.first);
}
}
/// Scaling of all three axes
void scaleXYZ(double scalex, double scaley, double scalez) {
scaleX(scalex);
scaleY(scaley);
scaleZ(scalez);
}
/// Scaling of both axes
/// @deprecated Use scaleXYZ
void scale(double scalex, double scaley, double scalez) {
scaleXYZ(scalex, scaley, scalez);
}
//@}
/// @name Integer axis accessor equivalents
//@{
/// Get the point value for direction @a i
double val(size_t i) const {
switch (i) {
case 1: return x();
case 2: return y();
case 3: return z();
default: throw RangeError("Invalid axis int, must be in range 1..dim");
}
}
/// Set the point value for direction @a i
void setVal(size_t i, double val) {
switch (i) {
case 1: setX(val); break;
case 2: setY(val); break;
case 3: setZ(val); break;
default: throw RangeError("Invalid axis int, must be in range 1..dim");
}
}
/// Get error map for direction @a i
const std::map< std::string, std::pair<double,double>> & errMap() const {
getVariationsFromParent();
return _ez;
}
// Parse the variations from the parent AO if it exists
void getVariationsFromParent() const;
/// Get error values for direction @a i
const std::pair<double,double>& errs(size_t i, std::string source="") const {
switch (i) {
case 1: return xErrs();
case 2: return yErrs();
case 3: return zErrs(source);
default: throw RangeError("Invalid axis int, must be in range 1..dim");
}
}
/// Get negative error value for direction @a i
double errMinus(size_t i, std::string source="") const {
switch (i) {
case 1: return xErrMinus();
case 2: return yErrMinus();
case 3: return zErrMinus(source);
default: throw RangeError("Invalid axis int, must be in range 1..dim");
}
}
/// Get positive error value for direction @a i
double errPlus(size_t i, std::string source="") const {
switch (i) {
case 1: return xErrPlus();
case 2: return yErrPlus();
case 3: return zErrPlus(source);
default: throw RangeError("Invalid axis int, must be in range 1..dim");
}
}
/// Get average error value for direction @a i
double errAvg(size_t i, std::string source="") const {
switch (i) {
case 1: return xErrAvg();
case 2: return yErrAvg();
case 3: return zErrAvg(source);
default: throw RangeError("Invalid axis int, must be in range 1..dim");
}
}
/// Set negative error for direction @a i
void setErrMinus(size_t i, double eminus, std::string source="") {
switch (i) {
case 1: setXErrMinus(eminus); break;
case 2: setYErrMinus(eminus); break;
case 3: setZErrMinus(eminus, source); break;
default: throw RangeError("Invalid axis int, must be in range 1..dim");
}
}
/// Set positive error for direction @a i
void setErrPlus(size_t i, double eplus, std::string source="") {
switch (i) {
case 1: setXErrPlus(eplus); break;
case 2: setYErrPlus(eplus); break;
case 3: setZErrPlus(eplus, source); break;
default: throw RangeError("Invalid axis int, must be in range 1..dim");
}
}
/// Set symmetric error for direction @a i
void setErr(size_t i, double e, std::string source="") {
switch (i) {
case 1: setXErrs(e); break;
case 2: setYErrs(e); break;
case 3: setZErrs(e, source); break;
default: throw RangeError("Invalid axis int, must be in range 1..dim");
}
}
/// Set asymmetric error for direction @a i
void setErrs(size_t i, double eminus, double eplus, std::string source="") {
switch (i) {
case 1: setXErrs(eminus, eplus); break;
case 2: setYErrs(eminus, eplus); break;
case 3: setZErrs(eminus, eplus, source); break;
default: throw RangeError("Invalid axis int, must be in range 1..dim");
}
}
/// Set asymmetric error for direction @a i
void setErrs(size_t i, std::pair<double,double>& e, std::string source="") {
switch (i) {
case 1: setXErrs(e); break;
case 2: setYErrs(e); break;
case 3: setZErrs(e, source); break;
default: throw RangeError("Invalid axis int, must be in range 1..dim");
}
}
/// Set value and symmetric error for direction @a i
void set(size_t i, double val, double e, std::string source="") {
switch (i) {
case 1: setX(val, e); break;
case 2: setY(val, e); break;
case 3: setZ(val, e, source); break;
default: throw RangeError("Invalid axis int, must be in range 1..dim");
}
}
/// Set value and asymmetric error for direction @a i
void set(size_t i, double val, double eminus, double eplus, std::string source="") {
switch (i) {
case 1: setX(val, eminus, eplus); break;
case 2: setY(val, eminus, eplus); break;
case 3: setZ(val, eminus, eplus, source); break;
default: throw RangeError("Invalid axis int, must be in range 1..dim");
}
}
/// Set value and asymmetric error for direction @a i
void set(size_t i, double val, std::pair<double,double>& e, std::string source="") {
switch (i) {
case 1: setX(val, e); break;
case 2: setY(val, e); break;
case 3: setZ(val, e, source); break;
default: throw RangeError("Invalid axis int, must be in range 1..dim");
}
}
//@}
protected:
/// @name Value and error variables
//@{
double _x;
double _y;
double _z;
std::pair<double,double> _ex;
std::pair<double,double> _ey;
// a map of the errors for each source. Nominal stored under ""
// to ensure backward compatibility
std::map< std::string, std::pair<double,double> >_ez;
//@}
};
/// @name Comparison operators
//@{
/// Equality test of x, y & z characteristics only
/// @todo Base on a named fuzzyEquals(a,b,tol=1e-3) unbound function
inline bool operator==(const Point3D& a, const YODA::Point3D& b) {
if (!YODA::fuzzyEquals(a.x(), b.x()) ||
!YODA::fuzzyEquals(a.xErrMinus(), b.xErrMinus()) ||
!YODA::fuzzyEquals(a.xErrPlus(), b.xErrPlus()) ) return false;
if (!YODA::fuzzyEquals(a.y(), b.y()) ||
!YODA::fuzzyEquals(a.yErrMinus(), b.yErrMinus()) ||
!YODA::fuzzyEquals(a.yErrPlus(), b.yErrPlus()) ) return false;
if (!YODA::fuzzyEquals(a.z(), b.z()) ||
!YODA::fuzzyEquals(a.zErrMinus(), b.zErrMinus()) ||
!YODA::fuzzyEquals(a.zErrPlus(), b.zErrPlus()) ) return false;
return true;
const bool same_val = fuzzyEquals(a.x(), b.x()) && fuzzyEquals(a.y(), b.y());
const bool same_eminus = fuzzyEquals(a.xErrMinus(), b.xErrMinus()) &&
fuzzyEquals(a.yErrMinus(), b.yErrMinus());
const bool same_eplus = fuzzyEquals(a.xErrPlus(), b.xErrPlus()) &&
fuzzyEquals(a.yErrPlus(), b.yErrPlus());
return same_val && same_eminus && same_eplus;
}
/// Inequality operator
inline bool operator != (const Point3D& a, const YODA::Point3D& b) {
return !(a == b);
}
/// Less-than operator used to sort bins by x-first ordering
inline bool operator < (const Point3D& a, const YODA::Point3D& b) {
if (! fuzzyEquals(a.x(), b.x())) {
return a.x() < b.x();
}
if (!fuzzyEquals(a.y(), b.y())) {
return a.y() < b.y();
}
if (! fuzzyEquals(a.xErrMinus(), b.xErrMinus())) {
return a.xErrMinus() < b.xErrMinus();
}
if (!fuzzyEquals(a.yErrMinus(), b.yErrMinus())) {
return a.yErrMinus() < b.yErrMinus();
}
if (! fuzzyEquals(a.xErrPlus(), b.xErrPlus())) {
return a.xErrPlus() < b.xErrPlus();
}
if (!fuzzyEquals(a.yErrPlus(), b.yErrPlus())) {
return a.yErrPlus() < b.yErrPlus();
}
return false;
}
/// Less-than-or-equals operator
inline bool operator <= (const Point3D& a, const YODA::Point3D& b) {
if (a == b) return true;
return a < b;
}
/// Greater-than operator
inline bool operator > (const Point3D& a, const YODA::Point3D& b) {
return !(a <= b);
}
/// Greater-than-or-equals operator
inline bool operator >= (const Point3D& a, const YODA::Point3D& b) {
return !(a < b);
}
//@}
}
#endif
diff --git a/src/WriterYODA.cc b/src/WriterYODA.cc
--- a/src/WriterYODA.cc
+++ b/src/WriterYODA.cc
@@ -1,385 +1,328 @@
// -*- C++ -*-
//
// This file is part of YODA -- Yet more Objects for Data Analysis
// Copyright (C) 2008-2018 The YODA collaboration (see AUTHORS for details)
//
#include "YODA/WriterYODA.h"
#include "yaml-cpp/yaml.h"
#ifdef YAML_NAMESPACE
#define YAML YAML_NAMESPACE
#endif
#include <iostream>
#include <iomanip>
using namespace std;
namespace YODA {
/// Singleton creation function
Writer& WriterYODA::create() {
static WriterYODA _instance;
_instance.setPrecision(6);
return _instance;
}
// Format version:
// - V1/empty = make-plots annotations style
// - V2 = YAML annotations
static const int YODA_FORMAT_VERSION = 2;
// Version-formatting helper function
inline string _iotypestr(const string& baseiotype) {
ostringstream os;
os << "YODA_" << Utils::toUpper(baseiotype) << "_V" << YODA_FORMAT_VERSION;
return os.str();
}
void WriterYODA::_writeAnnotations(std::ostream& os, const AnalysisObject& ao) {
os << scientific << setprecision(_precision);
for (const string& a : ao.annotations()) {
if (a.empty()) continue;
/// @todo Write out floating point annotations as scientific notation
string ann = ao.annotation(a);
// remove stpurious line returns at the end of a string so that we don't
// end up with two line returns.
ann.erase(std::remove(ann.begin(), ann.end(), '\n'), ann.end());
os << a << ": " << ann << "\n";
}
os << "---\n";
}
void WriterYODA::writeCounter(std::ostream& os, const Counter& c) {
ios_base::fmtflags oldflags = os.flags();
os << scientific << showpoint << setprecision(_precision);
os << "BEGIN " << _iotypestr("COUNTER") << " " << c.path() << "\n";
_writeAnnotations(os, c);
os << "# sumW\t sumW2\t numEntries\n";
os << c.sumW() << "\t" << c.sumW2() << "\t" << c.numEntries() << "\n";
os << "END " << _iotypestr("COUNTER") << "\n\n";
os.flags(oldflags);
}
void WriterYODA::writeHisto1D(std::ostream& os, const Histo1D& h) {
ios_base::fmtflags oldflags = os.flags();
os << scientific << showpoint << setprecision(_precision);
os << "BEGIN " << _iotypestr("HISTO1D") << " " << h.path() << "\n";
_writeAnnotations(os, h);
try {
//if ( h.totalDbn().effNumEntries() > 0 ) {
os << "# Mean: " << h.xMean() << "\n";
os << "# Area: " << h.integral() << "\n";
} catch (LowStatsError& e) {
//
}
os << "# ID\t ID\t sumw\t sumw2\t sumwx\t sumwx2\t numEntries\n";
os << "Total \tTotal \t";
os << h.totalDbn().sumW() << "\t" << h.totalDbn().sumW2() << "\t";
os << h.totalDbn().sumWX() << "\t" << h.totalDbn().sumWX2() << "\t";
os << h.totalDbn().numEntries() << "\n";
os << "Underflow\tUnderflow\t";
os << h.underflow().sumW() << "\t" << h.underflow().sumW2() << "\t";
os << h.underflow().sumWX() << "\t" << h.underflow().sumWX2() << "\t";
os << h.underflow().numEntries() << "\n";
os << "Overflow\tOverflow\t";
os << h.overflow().sumW() << "\t" << h.overflow().sumW2() << "\t";
os << h.overflow().sumWX() << "\t" << h.overflow().sumWX2() << "\t";
os << h.overflow().numEntries() << "\n";
os << "# xlow\t xhigh\t sumw\t sumw2\t sumwx\t sumwx2\t numEntries\n";
for (const HistoBin1D& b : h.bins()) {
os << b.xMin() << "\t" << b.xMax() << "\t";
os << b.sumW() << "\t" << b.sumW2() << "\t";
os << b.sumWX() << "\t" << b.sumWX2() << "\t";
os << b.numEntries() << "\n";
}
os << "END " << _iotypestr("HISTO1D") << "\n\n";
os.flags(oldflags);
}
void WriterYODA::writeHisto2D(std::ostream& os, const Histo2D& h) {
ios_base::fmtflags oldflags = os.flags();
os << scientific << showpoint << setprecision(_precision);
os << "BEGIN " << _iotypestr("HISTO2D") << " " << h.path() << "\n";
_writeAnnotations(os, h);
try {
//if ( h.totalDbn().numEntries() > 0 )
os << "# Mean: (" << h.xMean() << ", " << h.yMean() << ")\n";
os << "# Volume: " << h.integral() << "\n";
} catch (LowStatsError& e) {
//
}
os << "# ID\t ID\t sumw\t sumw2\t sumwx\t sumwx2\t sumwy\t sumwy2\t sumwxy\t numEntries\n";
// Total distribution
const Dbn2D& td = h.totalDbn();
os << "Total \tTotal \t";
os << td.sumW() << "\t" << td.sumW2() << "\t";
os << td.sumWX() << "\t" << td.sumWX2() << "\t";
os << td.sumWY() << "\t" << td.sumWY2() << "\t";
os << td.sumWXY() << "\t";
os << td.numEntries() << "\n";
// Outflows
/// @todo Disabled for now, reinstate with a *full* set of outflow info to allow marginalisation
os << "# 2D outflow persistency not currently supported until API is stable\n";
// for (int ix = -1; ix <= 1; ++ix) {
// for (int iy = -1; iy <= 1; ++iy) {
// if (ix == 0 && iy == 0) continue;
// os << "Outflow\t" << ix << ":" << iy << "\t";
// const Dbn2D& d = h.outflow(ix, iy);
// os << d.sumW() << "\t" << d.sumW2() << "\t";
// os << d.sumWX() << "\t" << d.sumWX2() << "\t";
// os << d.sumWY() << "\t" << d.sumWY2() << "\t";
// os << d.sumWXY() << "\t";
// os << d.numEntries() << "\n";
// }
// }
// Bins
os << "# xlow\t xhigh\t ylow\t yhigh\t sumw\t sumw2\t sumwx\t sumwx2\t sumwy\t sumwy2\t sumwxy\t numEntries\n";
for (const HistoBin2D& b : h.bins()) {
os << b.xMin() << "\t" << b.xMax() << "\t";
os << b.yMin() << "\t" << b.yMax() << "\t";
os << b.sumW() << "\t" << b.sumW2() << "\t";
os << b.sumWX() << "\t" << b.sumWX2() << "\t";
os << b.sumWY() << "\t" << b.sumWY2() << "\t";
os << b.sumWXY() << "\t";
os << b.numEntries() << "\n";
}
os << "END " << _iotypestr("HISTO2D") << "\n\n";
os.flags(oldflags);
}
void WriterYODA::writeProfile1D(std::ostream& os, const Profile1D& p) {
ios_base::fmtflags oldflags = os.flags();
os << scientific << showpoint << setprecision(_precision);
os << "BEGIN " << _iotypestr("PROFILE1D") << " " << p.path() << "\n";
_writeAnnotations(os, p);
os << "# ID\t ID\t sumw\t sumw2\t sumwx\t sumwx2\t sumwy\t sumwy2\t numEntries\n";
os << "Total \tTotal \t";
os << p.totalDbn().sumW() << "\t" << p.totalDbn().sumW2() << "\t";
os << p.totalDbn().sumWX() << "\t" << p.totalDbn().sumWX2() << "\t";
os << p.totalDbn().sumWY() << "\t" << p.totalDbn().sumWY2() << "\t";
os << p.totalDbn().numEntries() << "\n";
os << "Underflow\tUnderflow\t";
os << p.underflow().sumW() << "\t" << p.underflow().sumW2() << "\t";
os << p.underflow().sumWX() << "\t" << p.underflow().sumWX2() << "\t";
os << p.underflow().sumWY() << "\t" << p.underflow().sumWY2() << "\t";
os << p.underflow().numEntries() << "\n";
os << "Overflow\tOverflow\t";
os << p.overflow().sumW() << "\t" << p.overflow().sumW2() << "\t";
os << p.overflow().sumWX() << "\t" << p.overflow().sumWX2() << "\t";
os << p.overflow().sumWY() << "\t" << p.overflow().sumWY2() << "\t";
os << p.overflow().numEntries() << "\n";
os << "# xlow\t xhigh\t sumw\t sumw2\t sumwx\t sumwx2\t sumwy\t sumwy2\t numEntries\n";
for (const ProfileBin1D& b : p.bins()) {
os << b.xMin() << "\t" << b.xMax() << "\t";
os << b.sumW() << "\t" << b.sumW2() << "\t";
os << b.sumWX() << "\t" << b.sumWX2() << "\t";
os << b.sumWY() << "\t" << b.sumWY2() << "\t";
os << b.numEntries() << "\n";
}
os << "END " << _iotypestr("PROFILE1D") << "\n\n";
os.flags(oldflags);
}
void WriterYODA::writeProfile2D(std::ostream& os, const Profile2D& p) {
ios_base::fmtflags oldflags = os.flags();
os << scientific << showpoint << setprecision(_precision);
os << "BEGIN " << _iotypestr("PROFILE2D") << " " << p.path() << "\n";
_writeAnnotations(os, p);
os << "# sumw\t sumw2\t sumwx\t sumwx2\t sumwy\t sumwy2\t sumwz\t sumwz2\t sumwxy\t numEntries\n";
// Total distribution
const Dbn3D& td = p.totalDbn();
os << "Total \tTotal \t";
os << td.sumW() << "\t" << td.sumW2() << "\t";
os << td.sumWX() << "\t" << td.sumWX2() << "\t";
os << td.sumWY() << "\t" << td.sumWY2() << "\t";
os << td.sumWZ() << "\t" << td.sumWZ2() << "\t";
os << td.sumWXY() << "\t"; // << td.sumWXZ() << "\t" << td.sumWYZ() << "\t";
os << td.numEntries() << "\n";
// Outflows
/// @todo Disabled for now, reinstate with a *full* set of outflow info to allow marginalisation
os << "# 2D outflow persistency not currently supported until API is stable\n";
// for (int ix = -1; ix <= 1; ++ix) {
// for (int iy = -1; iy <= 1; ++iy) {
// if (ix == 0 && iy == 0) continue;
// os << "Outflow\t" << ix << ":" << iy << "\t";
// const Dbn3D& d = p.outflow(ix, iy);
// os << d.sumW() << "\t" << d.sumW2() << "\t";
// os << d.sumWX() << "\t" << d.sumWX2() << "\t";
// os << d.sumWY() << "\t" << d.sumWY2() << "\t";
// os << d.sumWZ() << "\t" << d.sumWZ2() << "\t";
// os << d.sumWXY() << "\t"; // << d.sumWXZ() << "\t" << d.sumWYZ() << "\t";
// os << d.numEntries() << "\n";
// }
// }
// Bins
os << "# xlow\t xhigh\t ylow\t yhigh\t sumw\t sumw2\t sumwx\t sumwx2\t sumwy\t sumwy2\t sumwz\t sumwz2\t sumwxy\t numEntries\n";
for (const ProfileBin2D& b : p.bins()) {
os << b.xMin() << "\t" << b.xMax() << "\t";
os << b.yMin() << "\t" << b.yMax() << "\t";
os << b.sumW() << "\t" << b.sumW2() << "\t";
os << b.sumWX() << "\t" << b.sumWX2() << "\t";
os << b.sumWY() << "\t" << b.sumWY2() << "\t";
os << b.sumWZ() << "\t" << b.sumWZ2() << "\t";
os << b.sumWXY() << "\t"; // << b.sumWXZ() << "\t" << b.sumWYZ() << "\t";
os << b.numEntries() << "\n";
}
os << "END " << _iotypestr("PROFILE2D") << "\n\n";
os.flags(oldflags);
}
void WriterYODA::writeScatter1D(std::ostream& os, const Scatter1D& s) {
ios_base::fmtflags oldflags = os.flags();
os << scientific << showpoint << setprecision(_precision);
os << "BEGIN " << _iotypestr("SCATTER1D") << " " << s.path() << "\n";
- //first write the Variations, a dummy annotation which
- //contains the additional columns which will be written out
- //for sytematic variations
- YAML::Emitter out;
- out << YAML::Flow ;
- out << s.variations();
- //os << "Variations" << ": " << out.c_str() << "\n";
- // then write the regular annotations
_writeAnnotations(os, s);
- std::vector<std::string> variations= s.variations();
-
//write headers
- std::string headers="# xval\t ";
- for (const auto &source : variations){
- headers+=" xerr-"+source+"\t xerr+"+source+"\t";
- }
+ std::string headers="# xval\t xerr-\t xerr+\t";
os << headers << "\n";
//write points
for (const Point1D& pt : s.points()) {
// fill central value
- os << pt.x();
- // fill errors for variations. The first should always be "" which is nominal.
- // Assumes here that all points in the Scatter have the same
- // variations... if not a range error will get thrown from
- // the point when the user tries to access a variation it
- // doesn't have... @todo maybe better way to do this?
- for (const auto &source : variations){
- os << "\t" << pt.xErrMinus(source) << "\t" << pt.xErrPlus(source) ;
- }
+ os << pt.x() << "\t" << pt.xErrMinus() << "\t" << pt.xErrPlus() ;
os << "\n";
}
os << "END " << _iotypestr("SCATTER1D") << "\n\n";
os << flush;
os.flags(oldflags);
}
void WriterYODA::writeScatter2D(std::ostream& os, const Scatter2D& s) {
ios_base::fmtflags oldflags = os.flags();
os << scientific << showpoint << setprecision(_precision);
os << "BEGIN " << _iotypestr("SCATTER2D") << " " << s.path() << "\n";
- //first write the Variations, a dummy annotation which
- //contains the additional columns which will be written out
- //for sytematic variations
- YAML::Emitter out;
- out << YAML::Flow << YAML::BeginMap;
- int counter=0;
- std::vector<std::string> variations= s.variations();
// write annotations
_writeAnnotations(os, s);
//write headers
/// @todo Change ordering to {vals} {errs} {errs} ...
std::string headers="# xval\t xerr-\t xerr+\t yval\t yerr-\t yerr+\t";
- //for (const auto &source : variations){
- // headers+=" yerr-"+source+"\t yerr+"+source+"\t";
- //}
os << headers << "\n";
//write points
for (const Point2D& pt : s.points()) {
/// @todo Change ordering to {vals} {errs} {errs} ...
// fill central value
os << pt.x() << "\t" << pt.xErrMinus() << "\t" << pt.xErrPlus() << "\t";
- os << pt.y();
- // fill errors for variations. The first should always be "" which is nominal.
- // Assumes here that all points in the Scatter have the same
- // variations... if not a range error will get thrown from
- // the point when the user tries to access a variation it
- // doesn't have... @todo maybe better way to do this?
- //for (const auto &source : variations){
- os << "\t" << pt.yErrMinus() << "\t" << pt.yErrPlus() ;
- // }
+ os << pt.y() << "\t" << pt.yErrMinus() << "\t" << pt.yErrPlus() ;
os << "\n";
}
os << "END " << _iotypestr("SCATTER2D") << "\n\n";
os << flush;
os.flags(oldflags);
}
void WriterYODA::writeScatter3D(std::ostream& os, const Scatter3D& s) {
ios_base::fmtflags oldflags = os.flags();
os << scientific << showpoint << setprecision(_precision);
-
os << "BEGIN " << _iotypestr("SCATTER3D") << " " << s.path() << "\n";
- //first write the Variations, a dummy annotation which
- //contains the additional columns which will be written out
- //for sytematic variations
- YAML::Emitter out;
- out << YAML::Flow ;
- out << s.variations();
- // then write the regular annotations
+ // write the annotations
_writeAnnotations(os, s);
- std::vector<std::string> variations= s.variations();
+ // std::vector<std::string> variations= s.variations();
//write headers
/// @todo Change ordering to {vals} {errs} {errs} ...
std::string headers="# xval\t xerr-\t xerr+\t yval\t yerr-\t yerr+\t zval\t ";
- for (const auto &source : variations){
- headers+=" zerr-"+source+"\t zerr+"+source+"\t";
- }
os << headers << "\n";
//write points
for (const Point3D& pt : s.points()) {
/// @todo Change ordering to {vals} {errs} {errs} ...
// fill central value
os << pt.x() << "\t" << pt.xErrMinus() << "\t" << pt.xErrPlus() << "\t";
os << pt.y() << "\t" << pt.yErrMinus() << "\t" << pt.yErrPlus() << "\t";
- os << pt.z();
- // fill errors for variations. The first should always be "" which is nominal.
- // Assumes here that all points in the Scatter have the same
- // variations... if not a range error will get thrown from
- // the point when the user tries to access a variation it
- // doesn't have... @todo maybe better way to do this?
- for (const auto &source : variations){
- os << "\t" << pt.zErrMinus(source) << "\t" << pt.zErrPlus(source) ;
- }
+ os << pt.z() << "\t" << pt.zErrMinus() << "\t" << pt.zErrPlus() ;
os << "\n";
}
os << "END " << _iotypestr("SCATTER3D") << "\n\n";
os << flush;
os.flags(oldflags);
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Dec 21, 1:53 PM (15 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4023032
Default Alt Text
(46 KB)
Attached To
rYODAHG yodahg
Event Timeline
Log In to Comment