Import Geant4 11.0.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2021-06-25 16:12:29 +02:00
parent c968e26a39
commit 6399a014b6
4200 changed files with 207479 additions and 237366 deletions
+76
View File
@@ -0,0 +1,76 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_axes
#define tools_histo_axes
#include "axis"
namespace tools {
namespace histo {
//TC is for a coordinate.
//TO is for an offset used to identify a bin.
template <class TC,class TO>
inline bool is_out(const std::vector< axis<TC,TO> >& a_axes,TO a_offset) {
TO offset = a_offset;
int index;
typename std::vector< axis<TC,TO> >::size_type dimension = a_axes.size();
for(int iaxis=int(dimension)-1;iaxis>=0;iaxis--) {
index = int(offset/a_axes[iaxis].m_offset);
if(index==0) return true;
if(index==(int(a_axes[iaxis].m_number_of_bins)+1)) return true;
offset -= index * a_axes[iaxis].m_offset;
}
return false;
}
template <class TC,class TO>
inline void get_indices(const std::vector< axis<TC,TO> >& a_axes,TO a_offset,std::vector<int>& a_is) {
TO offset = a_offset;
typename std::vector< axis<TC,TO> >::size_type dimension = a_axes.size();
{for(int iaxis=int(dimension)-1;iaxis>=0;iaxis--) {
a_is[iaxis] = int(offset/a_axes[iaxis].m_offset);
offset -= a_is[iaxis] * a_axes[iaxis].m_offset;
}}
typedef unsigned int dim_t;
for(dim_t iaxis=0;iaxis<dimension;iaxis++) {
if(a_is[iaxis]==0) {
a_is[iaxis] = axis_UNDERFLOW_BIN;
} else if(a_is[iaxis]==int(a_axes[iaxis].m_number_of_bins)+1) {
a_is[iaxis] = axis_OVERFLOW_BIN;
} else {
a_is[iaxis]--;
}
}
}
template <class TC,class TO>
inline bool get_offset(const std::vector< axis<TC,TO> >& a_axes,const std::vector<int>& a_is,TO& a_offset) {
// a_is[iaxis] is given in in-range indexing :
// - [0,n[iaxis]-1] for in-range bins
// - UNDERFLOW_BIN for the iaxis underflow bin
// - OVERFLOW_BIN for the iaxis overflow bin
a_offset = 0;
if(a_axes.empty()) return false;
typename std::vector< axis<TC,TO> >::size_type dimension = a_axes.size();
typename axis<TC,TO>::bn_t ibin;
typedef unsigned int dim_t;
for(dim_t iaxis=0;iaxis<dimension;iaxis++) {
if(!a_axes[iaxis].in_range_to_absolute_index(a_is[iaxis],ibin)) {
a_offset = 0;
return false;
}
a_offset += ibin * a_axes[iaxis].m_offset;
}
return true;
}
}}
#endif
+281
View File
@@ -0,0 +1,281 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_axis
#define tools_histo_axis
#include <string>
#include <vector>
namespace tools {
namespace histo {
enum { axis_UNDERFLOW_BIN = -2, axis_OVERFLOW_BIN = -1 }; //AIDA casing.
//TC is for a coordinate.
//TO is for an offset used to identify a bin.
template <class TC,class TO>
class axis {
public:
typedef unsigned int bn_t;
public:
enum { UNDERFLOW_BIN = axis_UNDERFLOW_BIN, OVERFLOW_BIN = axis_OVERFLOW_BIN };
public:
bool is_fixed_binning() const {return m_fixed;}
TC lower_edge() const {return m_minimum_value;}
TC upper_edge() const {return m_maximum_value;}
bn_t bins() const {return m_number_of_bins;}
const std::vector<TC>& edges() const {return m_edges;}
TC bin_width(int a_bin) const {
if(a_bin==UNDERFLOW_BIN) {
return 0; //FIXME return DBL_MAX;
} else if(a_bin==OVERFLOW_BIN) {
return 0; //FIXME return DBL_MAX;
} else if((a_bin<0) ||(a_bin>=(int)m_number_of_bins)) {
return 0;
} else {
if(m_fixed) {
return m_bin_width;
} else {
return (m_edges[a_bin+1]-m_edges[a_bin]);
}
}
}
TC bin_lower_edge(int a_bin) const {
if(a_bin==UNDERFLOW_BIN) {
return 0; //FIXME return -DBL_MAX;
} else if(a_bin==OVERFLOW_BIN) {
return 0; //FIXME return bin_upper_edge(m_number_of_bins-1);
} else if((a_bin<0) ||(a_bin>=(int)m_number_of_bins)) {
return 0;
} else {
if(m_fixed) {
return (m_minimum_value + a_bin * m_bin_width);
} else {
return m_edges[a_bin];
}
}
}
TC bin_upper_edge(int a_bin) const {
if(a_bin==UNDERFLOW_BIN) {
return 0; //FIXME bin_lower_edge(0)
} else if(a_bin==OVERFLOW_BIN) {
return 0; //FIXME return DBL_MAX;
} else if((a_bin<0) ||(a_bin>=(int)m_number_of_bins)) {
return 0;
} else {
if(m_fixed) {
return (m_minimum_value + (a_bin + 1) * m_bin_width);
} else {
return m_edges[a_bin+1];
}
}
}
TC bin_center(int a_bin) const {
if(a_bin==UNDERFLOW_BIN) {
return 0; //FIXME : -INF
} else if(a_bin==OVERFLOW_BIN) {
return 0; //FIXME : +INF
} else if(a_bin<0) {
return 0; //FIXME : -INF
} else if(a_bin>=(int)m_number_of_bins) {
return 0; //FIXME : +INF
} else {
if(m_fixed) {
return (m_minimum_value + (a_bin + 0.5) * m_bin_width);
} else {
return (m_edges[a_bin] + m_edges[a_bin+1])/2.;
}
}
}
int coord_to_index(TC a_value) const {
if( a_value < m_minimum_value) {
return UNDERFLOW_BIN;
} else if( a_value >= m_maximum_value) {
return OVERFLOW_BIN;
} else {
if(m_fixed) {
return (int)((a_value - m_minimum_value)/m_bin_width);
} else {
for(bn_t index=0;index<m_number_of_bins;index++) {
if((m_edges[index]<=a_value)&&(a_value<m_edges[index+1])) {
return index;
}
}
// Should never pass here...
return UNDERFLOW_BIN;
}
}
}
bool coord_to_absolute_index(TC a_value,bn_t& a_index) const {
if( a_value < m_minimum_value) {
a_index = 0;
return true;
} else if( a_value >= m_maximum_value) {
a_index = m_number_of_bins+1;
return true;
} else {
if(m_fixed) {
a_index = (bn_t)((a_value - m_minimum_value)/m_bin_width)+1;
return true;
} else {
for(bn_t index=0;index<m_number_of_bins;index++) {
if((m_edges[index]<=a_value)&&(a_value<m_edges[index+1])) {
a_index = index+1;
return true;
}
}
// Should never pass here...
a_index = 0;
return false;
}
}
}
bool in_range_to_absolute_index(int a_in,bn_t& a_out) const {
// a_in is given in in-range indexing :
// - [0,n-1] for in-range bins
// - UNDERFLOW_BIN for the iaxis underflow bin
// - OVERFLOW_BIN for the iaxis overflow bin
// Return the absolute indexing in [0,n+1].
if(a_in==UNDERFLOW_BIN) {
a_out = 0;
return true;
} else if(a_in==OVERFLOW_BIN) {
a_out = m_number_of_bins+1;
return true;
} else if((a_in>=0)&&(a_in<(int)m_number_of_bins)){
a_out = a_in + 1;
return true;
} else {
return false;
}
}
public:
// Partition :
bool configure(const std::vector<TC>& a_edges) {
// init :
m_number_of_bins = 0;
m_minimum_value = 0;
m_maximum_value = 0;
m_fixed = true;
m_bin_width = 0;
m_edges.clear();
// setup :
if(a_edges.size()<=1) return false;
bn_t number = (bn_t)a_edges.size()-1;
for(bn_t index=0;index<number;index++) {
if((a_edges[index]>=a_edges[index+1])) {
return false;
}
}
m_edges = a_edges;
m_number_of_bins = number;
m_minimum_value = a_edges[0];
m_maximum_value = a_edges[m_number_of_bins];
m_fixed = false;
return true;
}
bool configure(bn_t aNumber,TC aMin,TC aMax) {
// init :
m_number_of_bins = 0;
m_minimum_value = 0;
m_maximum_value = 0;
m_fixed = true;
m_bin_width = 0;
m_edges.clear();
// setup :
if(aNumber<=0) return false;
if(aMax<=aMin) return false;
m_number_of_bins = aNumber;
m_minimum_value = aMin;
m_maximum_value = aMax;
m_bin_width = (aMax - aMin)/ aNumber;
m_fixed = true;
return true;
}
bool is_compatible(const axis& a_axis) const {
if(m_number_of_bins!=a_axis.m_number_of_bins) return false;
if(m_minimum_value!=a_axis.m_minimum_value) return false;
if(m_maximum_value!=a_axis.m_maximum_value) return false;
return true;
}
public:
axis()
:m_offset(0)
,m_number_of_bins(0)
,m_minimum_value(0)
,m_maximum_value(0)
,m_fixed(true)
,m_bin_width(0)
{}
virtual ~axis(){}
public:
axis(const axis& a_from)
:m_offset(a_from.m_offset)
,m_number_of_bins(a_from.m_number_of_bins)
,m_minimum_value(a_from.m_minimum_value)
,m_maximum_value(a_from.m_maximum_value)
,m_fixed(a_from.m_fixed)
,m_bin_width(a_from.m_bin_width)
,m_edges(a_from.m_edges)
{}
axis& operator=(const axis& a_from) {
if(&a_from==this) return *this;
m_offset = a_from.m_offset;
m_number_of_bins = a_from.m_number_of_bins;
m_minimum_value = a_from.m_minimum_value;
m_maximum_value = a_from.m_maximum_value;
m_fixed = a_from.m_fixed;
m_bin_width = a_from.m_bin_width;
m_edges = a_from.m_edges;
return *this;
}
public:
bool equals(const axis& a_from) const {
if(&a_from==this) return true;
if(m_offset!=a_from.m_offset) return false;
if(m_number_of_bins!=a_from.m_number_of_bins) return false;
if(m_minimum_value!=a_from.m_minimum_value) return false;
if(m_maximum_value!=a_from.m_maximum_value) return false;
if(m_fixed!=a_from.m_fixed) return false;
if(m_bin_width!=a_from.m_bin_width) return false;
if(m_edges!=a_from.m_edges) return false;
return true;
}
bool operator==(const axis& a_from) const {return equals(a_from);}
bool operator!=(const axis& a_from) const {return !equals(a_from);}
public:
TO m_offset;
bn_t m_number_of_bins;
TC m_minimum_value;
TC m_maximum_value;
bool m_fixed;
// Fixed size bins :
TC m_bin_width;
// Variable size bins :
std::vector<TC> m_edges;
};
}}
#endif
+206
View File
@@ -0,0 +1,206 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_b1
#define tools_histo_b1
#include "base_histo"
#include <ostream>
namespace tools {
namespace histo {
template <class TC,class TO,class TN,class TW,class TH>
class b1 : public base_histo<TC,TO,TN,TW,TH> {
typedef base_histo<TC,TO,TN,TW,TH> parent;
protected:
enum {AxisX=0};
public:
typedef base_histo<TC,TO,TN,TW,TH> base_histo_t;
typedef typename parent::axis_t axis_t;
typedef typename parent::bn_t bn_t;
public:
virtual TH bin_error(int) const = 0; //for print
public:
// Partition :
int coord_to_index(TC aCoord) const {
return axis().coord_to_index(aCoord);
}
TC mean() const {
//TC value;
//parent::get_ith_axis_mean(AxisX,value); //can return false.
//return value;
if(parent::m_in_range_Sw==0) return 0;
return parent::m_in_range_Sxw[0]/parent::m_in_range_Sw;
}
TC rms() const {
//TC value;
//parent::get_ith_axis_rms(AxisX,value); //can return false.
//return value;
if(parent::m_in_range_Sw==0) return 0;
TC _mean = parent::m_in_range_Sxw[0]/parent::m_in_range_Sw;
return ::sqrt(::fabs((parent::m_in_range_Sx2w[0] / parent::m_in_range_Sw) - _mean * _mean));
}
// bins :
TN bin_entries(int aI) const {
TO offset;
if(!_find_offset(aI,offset)) return 0;
return parent::m_bin_entries[offset];
}
TW bin_Sw(int aI) const {
TO offset;
if(!_find_offset(aI,offset)) return 0;
return parent::m_bin_Sw[offset];
}
TW bin_Sw2(int aI) const {
TO offset;
if(!_find_offset(aI,offset)) return 0;
return parent::m_bin_Sw2[offset];
}
TC bin_Sxw(int aI) const {
TO offset;
if(!_find_offset(aI,offset)) return 0;
return parent::m_bin_Sxw[offset][AxisX];
}
TC bin_Sx2w(int aI) const {
TO offset;
if(!_find_offset(aI,offset)) return 0;
return parent::m_bin_Sx2w[offset][AxisX];
}
TH bin_height(int aI) const {
TO offset;
if(!_find_offset(aI,offset)) return 0;
return this->get_bin_height(offset);
}
TC bin_center(int aI) const {return parent::m_axes[0].bin_center(aI);}
TC bin_mean(int aI) const {
TO offset;
if(!_find_offset(aI,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
return parent::m_bin_Sxw[offset][AxisX]/sw;
}
TC bin_rms(int aI) const {
TO offset;
if(!_find_offset(aI,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TC sxw = parent::m_bin_Sxw[offset][AxisX];
TC sx2w = parent::m_bin_Sx2w[offset][AxisX];
TC _mean = sxw/sw;
return ::sqrt(::fabs((sx2w / sw) - _mean * _mean));
}
// Axis :
const axis_t& axis() const {return parent::m_axes[0];}
axis_t& axis() {return parent::m_axes[0];} //touchy
public:
//NOTE : print is a Python keyword.
void hprint(std::ostream& a_out) {
// A la HPRINT.
a_out << parent::dimension() << parent::title() << std::endl;
a_out
<< " * ENTRIES = " << parent::all_entries()
<< " * ALL CHANNELS = " << parent::sum_bin_heights()
<< " * UNDERFLOW = " << bin_height(axis_t::UNDERFLOW_BIN)
<< " * OVERFLOW = " << bin_height(axis_t::OVERFLOW_BIN)
<< std::endl;
a_out
<< " * BIN WID = " << axis().bin_width(0)
<< " * MEAN VALUE = " << mean()
<< " * R . M . S = " << rms()
<< std::endl;
// Some bins :
bn_t bins = axis().bins();
a_out
<< " * ENTRIES[0] = "
<< bin_entries(0)
<< " * HEIGHT[0] = "
<< bin_height(0)
<< " * ERROR[0] = "
<< bin_error(0)
<< std::endl;
a_out
<< " * ENTRIES[N/2] = "
<< bin_entries(bins/2)
<< " * HEIGHT[N/2] = "
<< bin_height(bins/2)
<< " * ERROR[N/2] = "
<< bin_error(bins/2)
<< std::endl;
a_out
<< " * ENTRIES[N-1] = "
<< bin_entries(bins-1)
<< " * HEIGHT[N-1] = "
<< bin_height(bins-1)
<< " * ERROR[N-1] = "
<< bin_error(bins-1)
<< std::endl;
}
protected:
b1(const std::string& a_title,bn_t aXnumber,TC aXmin,TC aXmax) {
parent::m_title = a_title;
std::vector<bn_t> nbins;
nbins.push_back(aXnumber);
std::vector<TC> mins;
mins.push_back(aXmin);
std::vector<TC> maxs;
maxs.push_back(aXmax);
parent::configure(1,nbins,mins,maxs);
}
b1(const std::string& a_title,const std::vector<TC>& a_edges) {
parent::m_title = a_title;
std::vector< std::vector<TC> > edges(1);
edges[0] = a_edges;
parent::configure(1,edges);
}
virtual ~b1(){}
protected:
b1(const b1& a_from):parent(a_from){}
b1& operator=(const b1& a_from) {
if(&a_from==this) return *this;
parent::operator=(a_from);
return *this;
}
public:
bool configure(bn_t aXnumber,TC aXmin,TC aXmax){
std::vector<bn_t> nbins;
nbins.push_back(aXnumber);
std::vector<TC> mins;
mins.push_back(aXmin);
std::vector<TC> maxs;
maxs.push_back(aXmax);
return parent::configure(1,nbins,mins,maxs);
}
bool configure(const std::vector<TC>& a_edges) {
std::vector< std::vector<TC> > edges(1);
edges[0] = a_edges;
return parent::configure(1,edges);
}
protected:
bool _find_offset(int aI,TO& a_offset) const {
if(parent::m_dimension!=1) {a_offset=0;return false;}
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) {a_offset=0;return false;}
a_offset = ibin;
return true;
}
};
}}
#endif
+356
View File
@@ -0,0 +1,356 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_b2
#define tools_histo_b2
#include "base_histo"
#include <ostream>
namespace tools {
namespace histo {
template <class TC,class TO,class TN,class TW,class TH>
class b2 : public base_histo<TC,TO,TN,TW,TH> {
typedef base_histo<TC,TO,TN,TW,TH> parent;
protected:
enum {AxisX=0,AxisY=1};
public:
typedef base_histo<TC,TO,TN,TW,TH> base_histo_t;
typedef typename parent::axis_t axis_t;
typedef typename parent::bn_t bn_t;
public:
virtual TH bin_error(int,int) const = 0; //for print
public:
// Partition :
TC mean_x() const {
if(parent::m_in_range_Sw==0) return 0;
return parent::m_in_range_Sxw[0]/parent::m_in_range_Sw;
}
TC mean_y() const {
if(parent::m_in_range_Sw==0) return 0;
return parent::m_in_range_Sxw[1]/parent::m_in_range_Sw;
}
TC rms_x() const {
if(parent::m_in_range_Sw==0) return 0;
TC mean = parent::m_in_range_Sxw[0]/parent::m_in_range_Sw;
return ::sqrt(::fabs((parent::m_in_range_Sx2w[0] / parent::m_in_range_Sw) - mean * mean));
}
TC rms_y() const {
if(parent::m_in_range_Sw==0) return 0;
TC mean = parent::m_in_range_Sxw[1]/parent::m_in_range_Sw;
return ::sqrt(::fabs((parent::m_in_range_Sx2w[1] / parent::m_in_range_Sw) - mean * mean));
}
int coord_to_index_x(TC aCoord) const {
return axis_x().coord_to_index(aCoord);
}
int coord_to_index_y(TC aCoord) const {
return axis_y().coord_to_index(aCoord);
}
// bins :
TN bin_entries(int aI,int aJ) const {
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
return parent::m_bin_entries[offset];
}
TW bin_Sw(int aI,int aJ) const {
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
return parent::m_bin_Sw[offset];
}
TW bin_Sw2(int aI,int aJ) const {
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
return parent::m_bin_Sw2[offset];
}
TC bin_Sxw(int aI,int aJ) const {
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
return parent::m_bin_Sxw[offset][AxisX];
}
TC bin_Sx2w(int aI,int aJ) const {
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
return parent::m_bin_Sx2w[offset][AxisX];
}
TC bin_Syw(int aI,int aJ) const {
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
return parent::m_bin_Sxw[offset][AxisY];
}
TC bin_Sy2w(int aI,int aJ) const {
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
return parent::m_bin_Sx2w[offset][AxisY];
}
TH bin_height(int aI,int aJ) const {
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
return this->get_bin_height(offset);
}
TC bin_center_x(int aI) const {
return parent::m_axes[0].bin_center(aI);
}
TC bin_center_y(int aJ) const {
return parent::m_axes[1].bin_center(aJ);
}
TC bin_mean_x(int aI,int aJ) const {
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
return parent::m_bin_Sxw[offset][AxisX]/sw;
}
TC bin_mean_y(int aI,int aJ) const {
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
return parent::m_bin_Sxw[offset][AxisY]/sw;
}
TC bin_rms_x(int aI,int aJ) const {
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TC sxw = parent::m_bin_Sxw[offset][AxisX];
TC sx2w = parent::m_bin_Sx2w[offset][AxisX];
TC mean = sxw/sw;
return ::sqrt(::fabs((sx2w / sw) - mean * mean));
}
TC bin_rms_y(int aI,int aJ) const {
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TC sxw = parent::m_bin_Sxw[offset][AxisY];
TC sx2w = parent::m_bin_Sx2w[offset][AxisY];
TC mean = sxw/sw;
return ::sqrt(::fabs((sx2w / sw) - mean * mean));
}
// Axes :
const axis_t& axis_x() const {return parent::m_axes[0];}
const axis_t& axis_y() const {return parent::m_axes[1];}
axis_t& axis_x() {return parent::m_axes[0];} //touchy
axis_t& axis_y() {return parent::m_axes[1];} //touchy
// Projection :
TN bin_entries_x(int aI) const {
if(!parent::m_dimension) return 0;
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
bn_t ybins = parent::m_axes[1].bins()+2;
TO offset;
TN _entries = 0;
for(bn_t jbin=0;jbin<ybins;jbin++) {
offset = ibin + jbin * parent::m_axes[1].m_offset;
_entries += parent::m_bin_entries[offset];
}
return _entries;
}
TW bin_height_x(int aI) const {
if(!parent::m_dimension) return 0;
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
bn_t ybins = parent::m_axes[1].bins()+2;
TO offset;
TW sw = 0;
for(bn_t jbin=0;jbin<ybins;jbin++) {
offset = ibin + jbin * parent::m_axes[1].m_offset;
sw += this->get_bin_height(offset);
}
return sw;
}
TN bin_entries_y(int aJ) const {
if(!parent::m_dimension) return 0;
bn_t jbin;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t xbins = parent::m_axes[0].bins()+2;
TO offset;
TN _entries = 0;
for(bn_t ibin=0;ibin<xbins;ibin++) {
offset = ibin + jbin * parent::m_axes[1].m_offset;
_entries += parent::m_bin_entries[offset];
}
return _entries;
}
TW bin_height_y(int aJ) const {
if(!parent::m_dimension) return 0;
bn_t jbin;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t xbins = parent::m_axes[0].bins()+2;
TO offset;
TW sw = 0;
for(bn_t ibin=0;ibin<xbins;ibin++) {
offset = ibin + jbin * parent::m_axes[1].m_offset;
sw += this->get_bin_height(offset);
}
return sw;
}
TC Sxyw() const {return parent::m_in_range_plane_Sxyw[0];}
public:
//NOTE : print is a Python keyword.
void hprint(std::ostream& a_out) {
// A la HPRINT.
a_out << parent::dimension() << parent::title() << std::endl;
a_out
<< " * ENTRIES = " << parent::all_entries() << std::endl;
// 6 | 7 | 8
// -----------
// 3 | 4 | 5
// -----------
// 0 | 1 | 2
TW height_0 = bin_height(axis_t::UNDERFLOW_BIN,
axis_t::UNDERFLOW_BIN);
TW height_2 = bin_height(axis_t::OVERFLOW_BIN,
axis_t::UNDERFLOW_BIN);
TW height_6 = bin_height(axis_t::UNDERFLOW_BIN,
axis_t::OVERFLOW_BIN);
TW height_8 = bin_height(axis_t::OVERFLOW_BIN,
axis_t::OVERFLOW_BIN);
bn_t i,j;
TW height_1 = 0;
TW height_7 = 0;
for(i=0;i<axis_x().bins();i++){
height_1 += bin_height(i,axis_t::UNDERFLOW_BIN);
height_7 += bin_height(i,axis_t::OVERFLOW_BIN);
}
TW height_3 = 0;
TW height_5 = 0;
for(j=0;j<axis_y().bins();j++){
height_3 += bin_height(axis_t::UNDERFLOW_BIN,j);
height_5 += bin_height(axis_t::OVERFLOW_BIN,j);
}
TW height_4 = 0;
for(i=0;i<axis_x().bins();i++){
for(j=0;j<axis_y().bins();j++){
height_4 += bin_height(i,j);
}
}
a_out
<< " " << height_6 << " " << height_7 << " " << height_8 << std::endl;
a_out
<< " " << height_3 << " " << height_4 << " " << height_5 << std::endl;
a_out
<< " " << height_0 << " " << height_1 << " " << height_2 << std::endl;
// Some bins :
bn_t xbins = axis_x().bins();
bn_t ybins = axis_y().bins();
a_out
<< " * ENTRIES[0,0] = "
<< bin_entries(0,0)
<< " * HEIGHT[0,0] = "
<< bin_height(0,0)
<< " * ERROR[0,0] = "
<< bin_error(0,0)
<< std::endl;
a_out
<< " * ENTRIES[N/2,N/2] = "
<< bin_entries(xbins/2,ybins/2)
<< " * HEIGHT[N/2,N/2] = "
<< bin_height(xbins/2,ybins/2)
<< " * ERROR[N/2,N/2] = "
<< bin_error(xbins/2,ybins/2)
<< std::endl;
a_out
<< " * ENTRIES[N-1,N-1] = "
<< bin_entries(xbins-1,ybins-1)
<< " * HEIGHT[N-1,N-1] = "
<< bin_height(xbins-1,ybins-1)
<< " * ERROR[N-1,N-1] = "
<< bin_error(xbins-1,ybins-1)
<< std::endl;
}
protected:
b2(const std::string& a_title,bn_t aXnumber,TC aXmin,TC aXmax,bn_t aYnumber,TC aYmin,TC aYmax) {
parent::m_title = a_title;
std::vector<bn_t> nbins;
nbins.push_back(aXnumber);
nbins.push_back(aYnumber);
std::vector<TC> mins;
mins.push_back(aXmin);
mins.push_back(aYmin);
std::vector<TC> maxs;
maxs.push_back(aXmax);
maxs.push_back(aYmax);
parent::configure(2,nbins,mins,maxs);
}
b2(const std::string& a_title,const std::vector<TC>& a_edges_x,const std::vector<TC>& a_edges_y) {
parent::m_title = a_title;
std::vector< std::vector<TC> > edges(2);
edges[0] = a_edges_x;
edges[1] = a_edges_y;
parent::configure(2,edges);
}
virtual ~b2(){}
protected:
b2(const b2& a_from):parent(a_from) {}
b2& operator=(const b2& a_from) {parent::operator=(a_from);return *this;}
public:
bool configure(bn_t aXnumber,TC aXmin,TC aXmax,bn_t aYnumber,TC aYmin,TC aYmax){
std::vector<bn_t> nbins;
nbins.push_back(aXnumber);
nbins.push_back(aYnumber);
std::vector<TC> mins;
mins.push_back(aXmin);
mins.push_back(aYmin);
std::vector<TC> maxs;
maxs.push_back(aXmax);
maxs.push_back(aYmax);
return parent::configure(2,nbins,mins,maxs);
}
bool configure(const std::vector<TC>& a_edges_x,const std::vector<TC>& a_edges_y){
std::vector< std::vector<TC> > edges(2);
edges[0] = a_edges_x;
edges[1] = a_edges_y;
return parent::configure(2,edges);
}
protected:
bool _find_offset(int aI,int aJ,TO& a_offset) const {
if(parent::m_dimension!=2) {a_offset=0;return false;}
bn_t ibin,jbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) {a_offset=0;return false;}
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) {a_offset=0;return false;}
a_offset = ibin + jbin * parent::m_axes[1].m_offset;
return true;
}
};
}}
#endif
+395
View File
@@ -0,0 +1,395 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_b3
#define tools_histo_b3
#include "base_histo"
#include <ostream>
namespace tools {
namespace histo {
template <class TC,class TO,class TN,class TW,class TH>
class b3 : public base_histo<TC,TO,TN,TW,TH> {
typedef base_histo<TC,TO,TN,TW,TH> parent;
public:
typedef base_histo<TC,TO,TN,TW,TH> base_histo_t;
typedef typename parent::axis_t axis_t;
typedef typename parent::bn_t bn_t;
protected:
enum {AxisX=0,AxisY=1,AxisZ=2};
public:
virtual TH bin_error(int,int,int) const = 0; //for print
public:
// Partition :
int coord_to_index_x(TC aCoord) const {
return axis_x().coord_to_index(aCoord);
}
int coord_to_index_y(TC aCoord) const {
return axis_y().coord_to_index(aCoord);
}
int coord_to_index_z(TC aCoord) const {
return axis_z().coord_to_index(aCoord);
}
TC mean_x() const {
if(parent::m_in_range_Sw==0) return 0;
return parent::m_in_range_Sxw[0]/parent::m_in_range_Sw;
}
TC mean_y() const {
if(parent::m_in_range_Sw==0) return 0;
return parent::m_in_range_Sxw[1]/parent::m_in_range_Sw;
}
TC mean_z() const {
if(parent::m_in_range_Sw==0) return 0;
return parent::m_in_range_Sxw[2]/parent::m_in_range_Sw;
}
TC rms_x() const {
if(parent::m_in_range_Sw==0) return 0;
TC mean = parent::m_in_range_Sxw[0]/parent::m_in_range_Sw;
return ::sqrt(::fabs((parent::m_in_range_Sx2w[0] / parent::m_in_range_Sw) - mean * mean));
}
TC rms_y() const {
if(parent::m_in_range_Sw==0) return 0;
TC mean = parent::m_in_range_Sxw[1]/parent::m_in_range_Sw;
return ::sqrt(::fabs((parent::m_in_range_Sx2w[1] / parent::m_in_range_Sw) - mean * mean));
}
TC rms_z() const {
if(parent::m_in_range_Sw==0) return 0;
TC mean = parent::m_in_range_Sxw[2]/parent::m_in_range_Sw;
return ::sqrt(::fabs((parent::m_in_range_Sx2w[2] / parent::m_in_range_Sw) - mean * mean));
}
// bins :
TN bin_entries(int aI,int aJ,int aK) const {
TO offset;
if(!_find_offset(aI,aJ,aK,offset)) return 0;
return parent::m_bin_entries[offset];
}
TH bin_height(int aI,int aJ,int aK) const {
TO offset;
if(!_find_offset(aI,aJ,aK,offset)) return 0;
return this->get_bin_height(offset);
}
TC bin_center_x(int aI) const {return parent::m_axes[0].bin_center(aI);}
TC bin_center_y(int aJ) const {return parent::m_axes[1].bin_center(aJ);}
TC bin_center_z(int aK) const {return parent::m_axes[2].bin_center(aK);}
TC bin_mean_x(int aI,int aJ,int aK) const {
TO offset;
if(!_find_offset(aI,aJ,aK,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
return parent::m_bin_Sxw[offset][AxisX]/sw;
}
TC bin_mean_y(int aI,int aJ,int aK) const {
TO offset;
if(!_find_offset(aI,aJ,aK,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
return parent::m_bin_Sxw[offset][AxisY]/sw;
}
TC bin_mean_z(int aI,int aJ,int aK) const {
TO offset;
if(!_find_offset(aI,aJ,aK,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
return parent::m_bin_Sxw[offset][AxisZ]/sw;
}
TC bin_rms_x(int aI,int aJ,int aK) const {
TO offset;
if(!_find_offset(aI,aJ,aK,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TC sxw = parent::m_bin_Sxw[offset][AxisX];
TC sx2w = parent::m_bin_Sx2w[offset][AxisX];
TC mean = sxw/sw;
return ::sqrt(::fabs((sx2w / sw) - mean * mean));
}
TC bin_rms_y(int aI,int aJ,int aK) const {
TO offset;
if(!_find_offset(aI,aJ,aK,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TC sxw = parent::m_bin_Sxw[offset][AxisY];
TC sx2w = parent::m_bin_Sx2w[offset][AxisY];
TC mean = sxw/sw;
return ::sqrt(::fabs((sx2w / sw) - mean * mean));
}
TC bin_rms_z(int aI,int aJ,int aK) const {
TO offset;
if(!_find_offset(aI,aJ,aK,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TC sxw = parent::m_bin_Sxw[offset][AxisZ];
TC sx2w = parent::m_bin_Sx2w[offset][AxisZ];
TC mean = sxw/sw;
return ::sqrt(::fabs((sx2w / sw) - mean * mean));
}
// Axes :
const axis_t& axis_x() const {return parent::m_axes[0];}
const axis_t& axis_y() const {return parent::m_axes[1];}
const axis_t& axis_z() const {return parent::m_axes[2];}
axis_t& axis_x() {return parent::m_axes[0];} //touchy
axis_t& axis_y() {return parent::m_axes[1];} //touchy
axis_t& axis_z() {return parent::m_axes[2];} //touchy
// Projection :
TN bin_entries_x(int aI) const {
if(!parent::m_dimension) return 0;
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
bn_t jbin,kbin,offset;
bn_t ybins = parent::m_axes[1].bins()+2;
bn_t zbins = parent::m_axes[2].bins()+2;
TO yoffset = parent::m_axes[1].m_offset;
TO zoffset = parent::m_axes[2].m_offset;
TO joffset = ibin;
TN _entries = 0;
for(jbin=0;jbin<ybins;jbin++) {
//joffset = ibin + jbin * parent::m_axes[1].m_offset;
offset = joffset;
for(kbin=0;kbin<zbins;kbin++) {
//offset = joffset + kbin * parent::m_axes[2].m_offset;
_entries += parent::m_bin_entries[offset];
offset += zoffset;
}
joffset += yoffset;
}
return _entries;
}
TN bin_entries_y(int aJ) const {
if(!parent::m_dimension) return 0;
bn_t jbin;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t ibin,kbin;
TO offset;
bn_t xbins = parent::m_axes[0].bins()+2;
bn_t zbins = parent::m_axes[2].bins()+2;
TO yoffset = parent::m_axes[1].m_offset;
TO zoffset = parent::m_axes[2].m_offset;
TO joffset = jbin * yoffset;
TN _entries = 0;
for(ibin=0;ibin<xbins;ibin++) {
//joffset = ibin + jbin * parent::m_axes[1].m_offset;
offset = joffset;
for(kbin=0;kbin<zbins;kbin++) {
//offset = joffset + kbin * parent::m_axes[2].m_offset;
_entries += parent::m_bin_entries[offset];
offset += zoffset;
}
joffset++;
}
return _entries;
}
TN bin_entries_z(int aK) const {
if(!parent::m_dimension) return 0;
bn_t kbin;
if(!parent::m_axes[2].in_range_to_absolute_index(aK,kbin)) return 0;
bn_t ibin,jbin;
TO offset;
bn_t xbins = parent::m_axes[0].bins()+2;
bn_t ybins = parent::m_axes[1].bins()+2;
TO yoffset = parent::m_axes[1].m_offset;
TO zoffset = parent::m_axes[2].m_offset;
TO koffset = kbin * zoffset;
TN _entries = 0;
for(ibin=0;ibin<xbins;ibin++) {
//koffset = ibin + kbin * parent::m_axes[2].m_offset;
offset = koffset;
for(jbin=0;jbin<ybins;jbin++) {
//offset = koffset + jbin * parent::m_axes[1].m_offset;
_entries += parent::m_bin_entries[offset];
offset += yoffset;
}
koffset++;
}
return _entries;
}
TW bin_height_x(int aI) const {
//to slow : return get_ith_axis_bin_height(0,aI);
if(!parent::m_dimension) return 0;
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
bn_t ybins = parent::m_axes[1].bins()+2;
bn_t zbins = parent::m_axes[2].bins()+2;
TO yoffset = parent::m_axes[1].m_offset;
TO zoffset = parent::m_axes[2].m_offset;
TO joffset = ibin;
TW sw = 0;
for(bn_t jbin=0;jbin<ybins;jbin++) {
//joffset = ibin + jbin * parent::m_axes[1].m_offset;
TO offset = joffset;
for(bn_t kbin=0;kbin<zbins;kbin++) {
//offset = joffset + kbin * parent::m_axes[2].m_offset;
sw += this->get_bin_height(offset);
offset += zoffset;
}
joffset += yoffset;
}
return sw;
}
TW bin_height_y(int aJ) const {
if(!parent::m_dimension) return 0;
bn_t jbin;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t xbins = parent::m_axes[0].bins()+2;
bn_t zbins = parent::m_axes[2].bins()+2;
TO yoffset = parent::m_axes[1].m_offset;
TO zoffset = parent::m_axes[2].m_offset;
TO joffset = jbin * yoffset;
TW sw = 0;
for(bn_t ibin=0;ibin<xbins;ibin++) {
//joffset = ibin + jbin * parent::m_axes[1].m_offset;
TO offset = joffset;
for(bn_t kbin=0;kbin<zbins;kbin++) {
//offset = joffset + kbin * parent::m_axes[2].m_offset;
sw += this->get_bin_height(offset);
offset += zoffset;
}
joffset++;
}
return sw;
}
TW bin_height_z(int aK) const {
if(!parent::m_dimension) return 0;
bn_t kbin;
if(!parent::m_axes[2].in_range_to_absolute_index(aK,kbin)) return 0;
bn_t xbins = parent::m_axes[0].bins()+2;
bn_t ybins = parent::m_axes[1].bins()+2;
TO yoffset = parent::m_axes[1].m_offset;
TO zoffset = parent::m_axes[2].m_offset;
TO koffset = kbin * zoffset;
TW sw = 0;
for(bn_t ibin=0;ibin<xbins;ibin++) {
//koffset = ibin + kbin * parent::m_axes[2].m_offset;
TO offset = koffset;
for(bn_t jbin=0;jbin<ybins;jbin++) {
//offset = koffset + jbin * parent::m_axes[1].m_offset;
sw += this->get_bin_height(offset);
offset += yoffset;
}
koffset++;
}
return sw;
}
TC Sxyw() const {return parent::m_in_range_plane_Sxyw[0];}
TC Syzw() const {return parent::m_in_range_plane_Sxyw[1];}
TC Szxw() const {return parent::m_in_range_plane_Sxyw[2];}
public:
//NOTE : print is a Python keyword.
void hprint(std::ostream& a_out) {
// A la HPRINT.
a_out << parent::dimension() << parent::title() << std::endl;
a_out
<< " * ENTRIES = " << parent::all_entries() << std::endl;
}
public:
b3(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax,
bn_t aYnumber,TC aYmin,TC aYmax,
bn_t aZnumber,TC aZmin,TC aZmax)
{
parent::m_title = a_title;
std::vector<bn_t> nbins;
nbins.push_back(aXnumber);
nbins.push_back(aYnumber);
nbins.push_back(aZnumber);
std::vector<TC> mins;
mins.push_back(aXmin);
mins.push_back(aYmin);
mins.push_back(aZmin);
std::vector<TC> maxs;
maxs.push_back(aXmax);
maxs.push_back(aYmax);
maxs.push_back(aZmax);
parent::configure(3,nbins,mins,maxs);
}
b3(const std::string& a_title,
const std::vector<TC>& a_edges_x,
const std::vector<TC>& a_edges_y,
const std::vector<TC>& a_edges_z)
{
parent::m_title = a_title;
std::vector< std::vector<TC> > edges(3);
edges[0] = a_edges_x;
edges[1] = a_edges_y;
edges[2] = a_edges_z;
parent::configure(3,edges);
}
virtual ~b3(){}
protected:
b3(const b3& a_from):parent(a_from) {}
b3& operator=(const b3& a_from){parent::operator=(a_from);return *this;}
public:
bool configure(bn_t aXnumber,TC aXmin,TC aXmax,
bn_t aYnumber,TC aYmin,TC aYmax,
bn_t aZnumber,TC aZmin,TC aZmax){
std::vector<bn_t> nbins;
nbins.push_back(aXnumber);
nbins.push_back(aYnumber);
nbins.push_back(aZnumber);
std::vector<TC> mins;
mins.push_back(aXmin);
mins.push_back(aYmin);
mins.push_back(aZmin);
std::vector<TC> maxs;
maxs.push_back(aXmax);
maxs.push_back(aYmax);
maxs.push_back(aZmax);
return parent::configure(3,nbins,mins,maxs);
}
bool configure(const std::vector<TC>& a_edges_x,
const std::vector<TC>& a_edges_y,
const std::vector<TC>& a_edges_z){
std::vector< std::vector<TC> > edges(3);
edges[0] = a_edges_x;
edges[1] = a_edges_y;
edges[2] = a_edges_z;
return parent::configure(3,edges);
}
protected:
bool _find_offset(int aI,int aJ,int aK,TO& a_offset) const {
if(parent::m_dimension!=3) {a_offset=0;return false;}
bn_t ibin,jbin,kbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) {a_offset=0;return false;}
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) {a_offset=0;return false;}
if(!parent::m_axes[2].in_range_to_absolute_index(aK,kbin)) {a_offset=0;return false;}
a_offset = ibin + jbin * parent::m_axes[1].m_offset + kbin * parent::m_axes[2].m_offset;
return true;
}
};
}}
#endif
+70
View File
@@ -0,0 +1,70 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_base_cloud
#define tools_histo_base_cloud
#include <string>
#include <vector>
#ifdef TOOLS_MEM
#include "../mem"
#endif
namespace tools {
namespace histo {
class base_cloud {
static const std::string& s_class() {
static const std::string s_v("tools::histo::base_cloud");
return s_v;
}
protected:
base_cloud(int aLimit)
:m_limit(aLimit)
,m_Sw(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~base_cloud(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
base_cloud(const base_cloud& a_from)
:m_title(a_from.m_title)
,m_limit(a_from.m_limit)
,m_Sw(a_from.m_Sw)
,m_ws(a_from.m_ws)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
base_cloud& operator=(const base_cloud& a_from){
m_title = a_from.m_title;
m_limit = a_from.m_limit;
m_Sw = a_from.m_Sw;
m_ws = a_from.m_ws;
return *this;
}
public:
const std::string& title() const {return m_title;}
int max_entries() const {return m_limit;}
protected:
static int UNLIMITED() {return -1;}
static unsigned int BINS() {return 100;}
protected:
std::string m_title;
int m_limit;
double m_Sw;
std::vector<double> m_ws;
};
}}
#endif
+668
View File
@@ -0,0 +1,668 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_base_histo
#define tools_histo_base_histo
#ifdef TOOLS_MEM
#include "../mem"
#endif
#include "histo_data"
#include <cmath>
#include <map> //for annotations
#include <ostream>
namespace tools {
namespace histo {
//TC is for a coordinate.
//TO is for an offset used to identify a bin.
//TN is for a number of entries.
//TW is for a weight.
//TH is for a height.
template <class TC,class TO,class TN,class TW,class TH>
class base_histo : protected histo_data<TC,TO,TN,TW> {
typedef histo_data<TC,TO,TN,TW> parent;
private:
static const std::string& s_class() {
static const std::string s_v("tools::histo::base_histo");
return s_v;
}
public:
typedef histo_data<TC,TO,TN,TW> hd_t;
typedef axis<TC,TO> axis_t;
typedef typename axis_t::bn_t bn_t;
typedef unsigned int dim_t;
typedef TC coordinate_t;
typedef TO offset_t;
typedef TN num_entries_t;
typedef TW weight_t;
typedef TH height_t;
protected:
virtual TH get_bin_height(TO) const = 0; //histo/profile
protected:
void base_from_data(const hd_t& a_from) {parent::operator=(a_from);}
#ifdef tools_histo_base_histo //for backward compatibility with tools
hd_t base_get_data() const {
hd_t hd;
hd = *this;
return hd;
}
#endif
public:
const hd_t& dac() const {return *this;} //data accessor.
protected:
base_histo():parent() {
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
protected:
virtual ~base_histo() {
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
base_histo(const base_histo& a_from):parent(a_from) {
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
base_histo& operator=(const base_histo& a_from) {
if(&a_from==this) return *this;
parent::operator=(a_from);
return *this;
}
public:
bool equals(const base_histo& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
return parent::equals(a_from,a_prec,a_fabs);
}
const std::string& title() const {return parent::m_title;}
bool set_title(const std::string& a_title){parent::m_title = a_title;return true;}
dim_t dimension() const {return parent::m_dimension;}
dim_t number_of_planes() const {return dim_planes(parent::m_dimension);}
TN entries() const {
return parent::m_in_range_entries; //not set if reading a TH from a CERN-ROOT file.
}
TN all_entries() const {
return parent::m_all_entries; //works also is reading histo from a CERN-ROOT file.
}
TN extra_entries() const {
return parent::m_all_entries-parent::m_in_range_entries; //works also is reading histo from a CERN-ROOT file.
}
TW equivalent_bin_entries() const {
TW sw = 0;
TW sw2 = 0;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin)) {
sw += parent::m_bin_Sw[ibin];
sw2 += parent::m_bin_Sw2[ibin];
}
}
if(sw2==0) return 0;
return (sw * sw)/sw2;
}
TH sum_bin_heights() const {
TH sh = 0;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin)) {
sh += get_bin_height(ibin);
}
}
return sh;
}
TH sum_all_bin_heights() const {
TH sh = 0;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
sh += get_bin_height(ibin);
}
return sh;
}
TH sum_extra_bin_heights() const {
TH sh = 0;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(histo::is_out(parent::m_axes,ibin)) {
sh += get_bin_height(ibin);
}
}
return sh;
}
TH min_bin_height() const {
TH value = 0;
bool first = true;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin)) {
TH vbin = get_bin_height(ibin);
if(first) {
first = false;
value = vbin;
} else {
if(vbin<=value) value = vbin;
}
}
}
return value;
}
TH max_bin_height() const {
TH value = 0;
bool first = true;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin)) {
TH vbin = get_bin_height(ibin);
if(first) {
first = false;
value = vbin;
} else {
if(vbin>=value) value = vbin;
}
}
}
return value;
}
bool min_bin_height_with_entries(TH& a_value) const {
TH value = 0;
bool first = true;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin) && (parent::m_bin_entries[ibin]>0) ) {
TH vbin = get_bin_height(ibin);
if(first) {
first = false;
value = vbin;
} else {
if(vbin<=value) value = vbin;
}
}
}
a_value = value;
return first?false:true; //return true if at least one bin with entries processed.
}
bool max_bin_height_with_entries(TH& a_value) const {
TH value = 0;
bool first = true;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin) && (parent::m_bin_entries[ibin]>0) ) {
TH vbin = get_bin_height(ibin);
if(first) {
first = false;
value = vbin;
} else {
if(vbin>=value) value = vbin;
}
}
}
a_value = value;
return first?false:true; //return true if at least one bin with entries processed.
}
bool has_entries_per_bin() const { //to detect histos coming from TH streaming out of a root file.
// it assumes that update_fast_getters() had been applied.
if(parent::m_in_range_entries) return true;
// may be a from-root histo :
if(parent::m_in_range_Sw) return false;
// no in range entries and weight :
return true; //for exa not filled = ok.
}
public: //histo_data
bool get_ith_axis_Sxw(dim_t a_axis,TC& a_value) const {
a_value = 0;
if(a_axis>=parent::m_dimension) return false;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin)) {
a_value += parent::m_bin_Sxw[ibin][a_axis];
}
}
return true;
}
bool get_ith_axis_Sx2w(dim_t a_axis,TC& a_value) const {
a_value = 0;
if(a_axis>=parent::m_dimension) return false;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin)) {
a_value += parent::m_bin_Sx2w[ibin][a_axis];
}
}
return true;
}
TW get_in_range_Sw() const {return parent::m_in_range_Sw;} //for CERN-ROOT file writing.
TW get_in_range_Sw2() const {return parent::m_in_range_Sw2;} //for CERN-ROOT file writing.
void get_Sw_Sw2(TW& a_sw,TW& a_sw2) const {
a_sw = 0;
a_sw2 = 0;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin)) {
a_sw += parent::m_bin_Sw[ibin];
a_sw2 += parent::m_bin_Sw2[ibin];
}
}
}
void get_all_Sw_Sw2(TW& a_sw,TW& a_sw2) const {
a_sw = 0;
a_sw2 = 0;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
a_sw += parent::m_bin_Sw[ibin];
a_sw2 += parent::m_bin_Sw2[ibin];
}
}
/*
TW get_all_Sw() const {
TW sw = 0;
for(TO ibin=0;ibin<m_bin_number;ibin++) sw += m_bin_Sw[ibin];
return sw;
}
TN get_all_entries() const {
TN number = 0;
for(TO ibin=0;ibin<m_bin_number;ibin++) {
number += m_bin_entries[ibin];
}
return number;
}
// for inlib/wroot/streamers :
TN get_entries() const {
TN number = 0;
for(TO ibin=0;ibin<m_bin_number;ibin++) {
if(!histo::is_out(m_axes,ibin)) {
number += m_bin_entries[ibin];
}
}
return number;
}
*/
protected:
enum {AxisX=0,AxisY=1,AxisZ=2};
bool configure(dim_t a_dim,
const std::vector<bn_t>& aNumbers,
const std::vector<TC>& aMins,
const std::vector<TC>& aMaxs) {
// Clear :
parent::m_bin_entries.clear();
parent::m_bin_Sw.clear();
parent::m_bin_Sw2.clear();
parent::m_bin_Sxw.clear();
parent::m_bin_Sx2w.clear();
parent::m_in_range_Sxw.clear();
parent::m_in_range_Sx2w.clear();
parent::m_axes.clear();
parent::m_in_range_plane_Sxyw.clear();
parent::m_annotations.clear();
parent::m_bin_number = 0;
parent::m_dimension = 0;
parent::m_all_entries = 0;
parent::m_in_range_entries = 0;
parent::m_in_range_Sw = 0;
parent::m_in_range_Sw2 = 0;
parent::m_in_range_Sxw.resize(a_dim,0);
parent::m_in_range_Sx2w.resize(a_dim,0);
// Some checks :
if(!a_dim) return false;
parent::m_axes.resize(a_dim);
// Setup axes :
for(dim_t iaxis=0;iaxis<a_dim;iaxis++) {
if(!parent::m_axes[iaxis].configure(aNumbers[iaxis],aMins[iaxis],aMaxs[iaxis])) {
// do not do :
// m_axes.clear()
// so that :
// b1::axis(),b2::axis_[x,y]()
// do not crash in case of a bad booking.
//m_axes.clear();
return false;
}
}
parent::m_dimension = a_dim;
base_allocate(); //set m_bin_number.
return true;
}
bool configure(dim_t a_dim,const std::vector< std::vector<TC> >& a_edges) {
// Clear :
parent::m_bin_entries.clear();
parent::m_bin_Sw.clear();
parent::m_bin_Sw2.clear();
parent::m_bin_Sxw.clear();
parent::m_bin_Sx2w.clear();
parent::m_in_range_Sxw.clear();
parent::m_in_range_Sx2w.clear();
parent::m_axes.clear();
parent::m_in_range_plane_Sxyw.clear();
parent::m_annotations.clear();
parent::m_bin_number = 0;
parent::m_dimension = 0;
parent::m_all_entries = 0;
parent::m_in_range_entries = 0;
parent::m_in_range_Sw = 0;
parent::m_in_range_Sw2 = 0;
parent::m_in_range_Sxw.resize(a_dim,0);
parent::m_in_range_Sx2w.resize(a_dim,0);
// Some checks :
if(!a_dim) return false;
parent::m_axes.resize(a_dim);
// Setup axes :
for(dim_t iaxis=0;iaxis<a_dim;iaxis++) {
if(!parent::m_axes[iaxis].configure(a_edges[iaxis])) {
//m_axes.clear();
return false;
}
}
parent::m_dimension = a_dim;
base_allocate(); //set m_bin_number.
return true;
}
void base_reset() {
// Reset content (different of clear that deallocate all internal things).
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
parent::m_bin_entries[ibin] = 0;
parent::m_bin_Sw[ibin] = 0;
parent::m_bin_Sw2[ibin] = 0;
for(dim_t iaxis=0;iaxis<parent::m_dimension;iaxis++) {
parent::m_bin_Sxw[ibin][iaxis] = 0;
parent::m_bin_Sx2w[ibin][iaxis] = 0;
}
}
parent::m_in_range_plane_Sxyw.assign(dim_planes(parent::m_dimension),0);
//profile not done here.
parent::reset_fast_getters();
}
protected:
void base_allocate() {
dim_t iaxis;
// Add two bins for the [under,out]flow data.
TO n_bin = 1;
for(iaxis=0;iaxis<parent::m_dimension;iaxis++) {
n_bin *= (parent::m_axes[iaxis].bins() + 2);
}
parent::m_bin_entries.resize(n_bin,0);
parent::m_bin_Sw.resize(n_bin,0);
parent::m_bin_Sw2.resize(n_bin,0);
std::vector<TC> empty;
empty.resize(parent::m_dimension,0);
parent::m_bin_Sxw.resize(n_bin,empty);
parent::m_bin_Sx2w.resize(n_bin,empty);
parent::m_bin_number = n_bin; // All bins : [in-range, underflow, outflow] bins.
parent::m_axes[0].m_offset = 1;
for(iaxis=1;iaxis<parent::m_dimension;iaxis++) {
parent::m_axes[iaxis].m_offset = parent::m_axes[iaxis-1].m_offset * (parent::m_axes[iaxis-1].bins()+2);
}
parent::m_in_range_plane_Sxyw.resize(dim_planes(parent::m_dimension),0);
}
public:
// to access data from methods :
const std::vector<TN>& bins_entries() const {return parent::m_bin_entries;}
const std::vector<TW>& bins_sum_w() const {return parent::m_bin_Sw;}
const std::vector<TW>& bins_sum_w2() const {return parent::m_bin_Sw2;}
const std::vector< std::vector<TC> >& bins_sum_xw() const {return parent::m_bin_Sxw;}
const std::vector< std::vector<TC> >& bins_sum_x2w() const {return parent::m_bin_Sx2w;}
const std::vector<TC>& in_range_planes_xyw() const {return parent::m_in_range_plane_Sxyw;}
public:
const axis_t& get_axis(int a_index) const {return parent::m_axes[a_index];}
offset_t get_bins() const {return parent::m_bin_number;}
const std::string& get_title() const {return parent::m_title;}
dim_t get_dimension() const {return parent::m_dimension;}
bool is_valid() const {return (parent::m_dimension?true:false);}
public: //annotations :
typedef std::map<std::string,std::string> annotations_t;
const annotations_t& annotations() const {return parent::m_annotations;}
annotations_t annotations() {return parent::m_annotations;}
void add_annotation(const std::string& a_key,const std::string& a_value) {
parent::m_annotations[a_key] = a_value; //override if a_key already exists.
}
bool annotation(const std::string& a_key,std::string& a_value) const {
annotations_t::const_iterator it = parent::m_annotations.find(a_key);
if(it==parent::m_annotations.end()) {a_value.clear();return false;}
a_value = (*it).second;
return true;
}
void set_annotations(const annotations_t& a_annotations) {parent::m_annotations = a_annotations;}
void hprint_annotations(std::ostream& a_out) {
a_out << " * ANNOTATIONS :" << std::endl;
annotations_t::const_iterator it;
for(it=parent::m_annotations.begin();it!=parent::m_annotations.end();++it) {
//out << " * (" << index << ") "
a_out << " * " << (*it).first << " = " << (*it).second << std::endl;
}
}
protected:
bool is_compatible(const base_histo& a_histo){
if(parent::m_dimension!=a_histo.m_dimension) return false;
for(dim_t iaxis=0;iaxis<parent::m_dimension;iaxis++) {
if(!parent::m_axes[iaxis].is_compatible(a_histo.m_axes[iaxis])) return false;
}
return true;
}
void base_add(const base_histo& a_histo){
// The only histogram operation that makes sense.
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
parent::m_bin_entries[ibin] += a_histo.m_bin_entries[ibin];
parent::m_bin_Sw[ibin] += a_histo.m_bin_Sw[ibin];
parent::m_bin_Sw2[ibin] += a_histo.m_bin_Sw2[ibin];
for(dim_t iaxis=0;iaxis<parent::m_dimension;iaxis++) {
parent::m_bin_Sxw[ibin][iaxis] += a_histo.m_bin_Sxw[ibin][iaxis];
parent::m_bin_Sx2w[ibin][iaxis] += a_histo.m_bin_Sx2w[ibin][iaxis];
}
}
{size_t nplane = parent::m_in_range_plane_Sxyw.size();
for(size_t iplane=0;iplane<nplane;iplane++)
parent::m_in_range_plane_Sxyw[iplane] += a_histo.m_in_range_plane_Sxyw[iplane];}
parent::update_fast_getters();
}
void base_subtract(const base_histo& a_histo) {
//ill-defined operation. We keep that because of the "ill-defined past".
// We build a new histo with one entry in each bin.
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
parent::m_bin_entries[ibin] = 1;
parent::m_bin_Sw[ibin] -= a_histo.m_bin_Sw[ibin];
// Yes, it is a += in the below.
parent::m_bin_Sw2[ibin] += a_histo.m_bin_Sw2[ibin];
for(dim_t iaxis=0;iaxis<parent::m_dimension;iaxis++) {
parent::m_bin_Sxw[ibin][iaxis] -= a_histo.m_bin_Sxw[ibin][iaxis];
parent::m_bin_Sx2w[ibin][iaxis] -= a_histo.m_bin_Sx2w[ibin][iaxis];
}
}
//{for(dim_t iplane=0;iplane<nplane;iplane++) parent::m_in_range_plane_Sxyw[iplane] ??? a_histo.m_in_range_plane_Sxyw[iplane];}
parent::update_fast_getters();
}
bool base_multiply(const base_histo& a_histo) {
//ill-defined operation. We keep that because of the "ill-defined past".
// We build a new histo with one entry in each bin of weight :
// this.w * a_histo.w
// The current histo is overriden with this new histo.
// The m_bin_Sw2 computation is consistent with FreeHEP and CERN-ROOT.
if(!is_compatible(a_histo)) return false;
std::vector<int> is(parent::m_dimension);
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
TW swa = parent::m_bin_Sw[ibin];
TW sw2a = parent::m_bin_Sw2[ibin];
TW swb = a_histo.m_bin_Sw[ibin];
TW sw2b = a_histo.m_bin_Sw2[ibin];
TW sw = swa * swb;
parent::m_bin_entries[ibin] = 1;
parent::m_bin_Sw[ibin] = sw;
parent::m_bin_Sw2[ibin] = sw2a * swb * swb + sw2b * swa * swa;
histo::get_indices(parent::m_axes,ibin,is);
for(dim_t iaxis=0;iaxis<parent::m_dimension;iaxis++) {
TC x = parent::m_axes[iaxis].bin_center(is[iaxis]);
parent::m_bin_Sxw[ibin][iaxis] = x * sw;
parent::m_bin_Sx2w[ibin][iaxis] = x * x * sw;
}
}
//{for(dim_t iplane=0;iplane<nplane;iplane++) parent::m_in_range_plane_Sxyw[iplane] ??? a_histo.m_in_range_plane_Sxyw[iplane];}
parent::update_fast_getters();
return true;
}
bool base_divide(const base_histo& a_histo) {
//ill-defined operation. We keep that because of the "ill-defined past".
// We build a new histo with one entry in each bin of weight :
// this.w / a_histo.w
// The current histo is overriden with this new histo.
// The m_bin_Sw2 computation is consistent with FreeHEP and ROOT.
if(!is_compatible(a_histo)) return false;
std::vector<int> is(parent::m_dimension);
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
histo::get_indices(parent::m_axes,ibin,is);
TW swa = parent::m_bin_Sw[ibin];
TW swb = a_histo.m_bin_Sw[ibin];
TW sw2a = parent::m_bin_Sw2[ibin];
TW sw2b = a_histo.m_bin_Sw2[ibin];
if(swb!=0) {
parent::m_bin_entries[ibin] = 1;
TW sw = swa / swb;
parent::m_bin_Sw[ibin] = sw;
TW swb2 = swb * swb;
parent::m_bin_Sw2[ibin] = sw2a / swb2 + sw2b * swa * swa /(swb2*swb2);
for(dim_t iaxis=0;iaxis<parent::m_dimension;iaxis++) {
TC x = parent::m_axes[iaxis].bin_center(is[iaxis]);
parent::m_bin_Sxw[ibin][iaxis] = x * sw;
parent::m_bin_Sx2w[ibin][iaxis] = x * x * sw;
}
} else {
parent::m_bin_entries[ibin] = 0;
parent::m_bin_Sw[ibin] = 0;
parent::m_bin_Sw2[ibin] = 0;
for(dim_t iaxis=0;iaxis<parent::m_dimension;iaxis++) {
parent::m_bin_Sxw[ibin][iaxis] = 0;
parent::m_bin_Sx2w[ibin][iaxis] = 0;
}
}
}
//{for(dim_t iplane=0;iplane<nplane;iplane++) parent::m_in_range_plane_Sxyw[iplane] ??? a_histo.m_in_range_plane_Sxyw[iplane];}
parent::update_fast_getters();
return true;
}
bool base_multiply(TW a_factor) {
if(a_factor<0) return false;
TW factor2 = a_factor * a_factor;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
parent::m_bin_Sw[ibin] *= a_factor;
parent::m_bin_Sw2[ibin] *= factor2;
for(dim_t iaxis=0;iaxis<parent::m_dimension;iaxis++) {
parent::m_bin_Sxw[ibin][iaxis] *= a_factor;
parent::m_bin_Sx2w[ibin][iaxis] *= a_factor;
}
}
{size_t nplane = parent::m_in_range_plane_Sxyw.size();
for(size_t iplane=0;iplane<nplane;iplane++) parent::m_in_range_plane_Sxyw[iplane] *= a_factor;}
parent::update_fast_getters();
return true;
}
bool get_ith_axis_mean(dim_t a_axis,TC& a_value) const {
a_value = 0;
if(a_axis>=parent::m_dimension) return false;
TW sw = 0;
TC sxw = 0;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin)) {
sw += parent::m_bin_Sw[ibin];
sxw += parent::m_bin_Sxw[ibin][a_axis];
}
}
if(sw==0) return false;
a_value = sxw/sw;
return true;
}
bool get_ith_axis_rms(dim_t a_axis,TC& a_value) const {
a_value = 0;
if(a_axis>=parent::m_dimension) return false;
TW sw = 0;
TC sxw = 0;
TC sx2w = 0;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin)) {
sw += parent::m_bin_Sw[ibin];
sxw += parent::m_bin_Sxw[ibin][a_axis];
sx2w += parent::m_bin_Sx2w[ibin][a_axis];
}
}
if(sw==0) return false;
TC mean = sxw/sw;
a_value = ::sqrt(::fabs((sx2w / sw) - mean * mean));
return true;
}
TN get_bin_entries(const std::vector<int>& aIs) const {
if(parent::m_bin_number==0) return 0;
TO offset;
if(!histo::get_offset(parent::m_axes,aIs,offset)) return 0;
return parent::m_bin_entries[offset];
}
};
// predefined annotation keys :
inline const std::string& key_axis_x_title() {
static const std::string s_v("axis_x.title");
return s_v;
}
inline const std::string& key_axis_y_title() {
static const std::string s_v("axis_y.title");
return s_v;
}
inline const std::string& key_axis_z_title() {
static const std::string s_v("axis_z.title");
return s_v;
}
}}
#endif
+250
View File
@@ -0,0 +1,250 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_c1d
#define tools_histo_c1d
#include "base_cloud"
#include "../mnmx"
#include "h1d"
namespace tools {
namespace histo {
class c1d : public base_cloud {
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::c1d");
return s_v;
}
public:
bool set_title(const std::string& a_title){
m_title = a_title;
if(m_histo) m_histo->set_title(a_title);
return true;
}
unsigned int dimension() const {return 1;}
bool reset() {
clear();
delete m_histo;
m_histo = 0;
return true;
}
unsigned int entries() const {
return m_histo ? m_histo->all_entries() : (unsigned int)m_ws.size();
}
public:
double sum_of_weights() const {
return (m_histo ? m_histo->sum_bin_heights() : m_Sw);
}
bool convert_to_histogram(){
if( (m_cnv_x_num<=0) || (m_cnv_x_max<=m_cnv_x_min) ) {
// Cloud min, max should be included in the histo.
double dx = 0.01 * (upper_edge() - lower_edge())/BINS();
return convert(BINS(),lower_edge(),upper_edge() + dx);
} else {
return convert(m_cnv_x_num,m_cnv_x_min,m_cnv_x_max);
}
}
bool is_converted() const {return m_histo ? true : false;}
bool scale(double a_scale) {
if(m_histo) {
return m_histo->scale(a_scale);
} else {
size_t number = m_ws.size();
for(size_t index=0;index<number;index++) m_ws[index] *= a_scale;
m_Sw *= a_scale;
m_Sxw *= a_scale;
m_Sx2w *= a_scale;
return true;
}
}
bool set_histogram(h1d* a_histo){ //we take ownership of a_histo.
reset();
m_histo = a_histo;
return true;
}
public:
bool fill(double aX,double aW = 1){
if(!m_histo && (m_limit!=UNLIMITED()) &&
((int)m_xs.size()>=m_limit)){
convert_to_histogram();
}
if(m_histo) {
return m_histo->fill(aX,aW);
} else {
if(m_xs.size()) {
m_lower_x = mn<double>(aX,m_lower_x);
m_upper_x = mx<double>(aX,m_upper_x);
} else {
m_lower_x = aX;
m_upper_x = aX;
}
m_xs.push_back(aX);
m_ws.push_back(aW);
m_Sw += aW;
double xw = aX * aW;
m_Sxw += xw;
m_Sx2w += aX * xw;
return true;
}
}
double lower_edge() const {
return (m_histo ? m_histo->axis().lower_edge() : m_lower_x);
}
double upper_edge() const {
return (m_histo ? m_histo->axis().upper_edge() : m_upper_x);
}
double value(unsigned int a_index) const {return (m_histo ?0:m_xs[a_index]);}
double weight(unsigned int a_index) const {return (m_histo ?0:m_ws[a_index]);}
double mean() const {
return (m_histo ? m_histo->mean() : (m_Sw?m_Sxw/m_Sw:0));
}
double rms() const {
double _rms = 0; //FIXME nan.
if(m_histo) {
_rms = m_histo->rms();
} else {
if(m_Sw==0) {
} else {
double _mean = m_Sxw / m_Sw;
_rms = ::sqrt(::fabs( (m_Sx2w / m_Sw) - _mean * _mean));
}
}
return _rms;
}
bool convert(unsigned int a_bins,double a_lower_edge,double a_upper_edge){
if(m_histo) return true;
m_histo = new histo::h1d(base_cloud::title(),a_bins,a_lower_edge,a_upper_edge);
if(!m_histo) return false;
bool status = fill_histogram(*m_histo);
clear();
return status;
}
bool convert(const std::vector<double>& a_edges) {
if(m_histo) return true;
m_histo = new histo::h1d(base_cloud::title(),a_edges);
if(!m_histo) return false;
bool status = fill_histogram(*m_histo);
clear();
return status;
}
const histo::h1d& histogram() const {
if(!m_histo) const_cast<c1d&>(*this).convert_to_histogram();
return *m_histo;
}
template <class HISTO>
bool fill_histogram(HISTO& a_histo) const {
size_t number = m_xs.size();
for(size_t index=0;index<number;index++) {
if(!a_histo.fill(m_xs[index],m_ws[index])) return false;
}
return true;
}
bool set_conversion_parameters(unsigned int aCnvXnumber,
double aCnvXmin,double aCnvXmax){
m_cnv_x_num = aCnvXnumber;
m_cnv_x_min = aCnvXmin;
m_cnv_x_max = aCnvXmax;
return true;
}
public:
c1d()
:base_cloud(UNLIMITED())
,m_lower_x(0),m_upper_x(0)
,m_Sxw(0),m_Sx2w(0)
,m_cnv_x_num(0),m_cnv_x_min(0),m_cnv_x_max(0),m_histo(0)
{}
c1d(const std::string& a_title,int aLimit = base_cloud::UNLIMITED())
:base_cloud(aLimit)
,m_lower_x(0),m_upper_x(0)
,m_Sxw(0),m_Sx2w(0)
,m_cnv_x_num(0),m_cnv_x_min(0),m_cnv_x_max(0),m_histo(0)
{
set_title(a_title);
}
virtual ~c1d(){delete m_histo;}
public:
c1d(const c1d& a_from)
:base_cloud(a_from)
,m_xs(a_from.m_xs)
,m_lower_x(a_from.m_lower_x)
,m_upper_x(a_from.m_upper_x)
,m_Sxw(a_from.m_Sxw)
,m_Sx2w(a_from.m_Sx2w)
,m_cnv_x_num(a_from.m_cnv_x_num)
,m_cnv_x_min(a_from.m_cnv_x_min)
,m_cnv_x_max(a_from.m_cnv_x_max)
,m_histo(0)
{
if(a_from.m_histo) {
m_histo = new histo::h1d(*a_from.m_histo);
}
}
c1d& operator=(const c1d& a_from){
base_cloud::operator=(a_from);
if(&a_from==this) return *this;
m_xs = a_from.m_xs;
m_lower_x = a_from.m_lower_x;
m_upper_x = a_from.m_upper_x;
m_Sxw = a_from.m_Sxw;
m_Sx2w = a_from.m_Sx2w;
m_cnv_x_num = a_from.m_cnv_x_num;
m_cnv_x_min = a_from.m_cnv_x_min;
m_cnv_x_max = a_from.m_cnv_x_max;
delete m_histo;
m_histo = 0;
if(a_from.m_histo) {
m_histo = new histo::h1d(*a_from.m_histo);
}
return *this;
}
public: //AIDA API
double lowerEdge() const {return lower_edge();}
double upperEdge() const {return upper_edge();}
template <class HISTO>
bool fillHistogram(HISTO& a_histo) const {return fill_histogram<HISTO>(a_histo);}
protected:
void clear(){
m_lower_x = 0;
m_upper_x = 0;
m_Sw = 0;
m_Sxw = 0;
m_Sx2w = 0;
m_xs.clear();
m_ws.clear();
}
protected:
std::vector<double> m_xs;
double m_lower_x;
double m_upper_x;
double m_Sxw;
double m_Sx2w;
//
unsigned int m_cnv_x_num;
double m_cnv_x_min;
double m_cnv_x_max;
histo::h1d* m_histo;
};
}}
#endif
+372
View File
@@ -0,0 +1,372 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_c2d
#define tools_histo_c2d
#include "base_cloud"
#include "../mnmx"
#include "h2d"
namespace tools {
namespace histo {
class c2d : public base_cloud {
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::c2d");
return s_v;
}
public:
bool set_title(const std::string&);
unsigned int dimension() const {return 2;}
bool reset();
unsigned int entries() const { return m_histo ? m_histo->all_entries() : (unsigned int)m_ws.size();}
public:
double sum_of_weights() const { return (m_histo ? m_histo->sum_bin_heights() : m_Sw);}
bool convert_to_histogram();
bool is_converted() const {return m_histo ? true : false;}
bool scale(double);
public:
bool fill(double,double,double = 1);
double lower_edge_x() const {return m_histo ? m_histo->axis_x().lower_edge() : m_lower_x;}
double lower_edge_y() const { return m_histo ? m_histo->axis_y().lower_edge() : m_lower_y;}
double upper_edge_x() const { return m_histo ? m_histo->axis_x().upper_edge() : m_upper_x;}
double upper_edge_y() const { return m_histo ? m_histo->axis_y().upper_edge() : m_upper_y;}
double value_x(unsigned int a_index) const { return m_histo ? 0 : m_xs[a_index];}
double value_y(unsigned int a_index) const { return m_histo ? 0 : m_ys[a_index];}
double weight(unsigned int a_index) const { return m_histo ? 0 : m_ws[a_index];}
double mean_x() const {return m_histo ? m_histo->mean_x() : (m_Sw?m_Sxw/m_Sw:0);}
double mean_y() const {return m_histo ? m_histo->mean_y() : (m_Sw?m_Syw/m_Sw:0);}
double rms_x() const;
double rms_y() const;
bool convert(unsigned int,double,double,unsigned int,double,double);
bool convert(const std::vector<double>&,const std::vector<double>&);
const histo::h2d& histogram() const;
template <class HISTO>
bool fill_histogram(HISTO& a_histo) const {
size_t number = m_xs.size();
for(size_t index=0;index<number;index++) {
if(!a_histo.fill(m_xs[index],m_ys[index],m_ws[index])) return false;
}
return true;
}
bool set_conversion_parameters(unsigned int,double,double,unsigned int,double,double);
bool set_histogram(h2d* a_histo){ //we take ownership of a_histo.
reset();
m_histo = a_histo;
return true;
}
public:
c2d();
c2d(const std::string&,int=base_cloud::UNLIMITED());
virtual ~c2d(){delete m_histo;}
public:
c2d(const c2d& a_from)
:base_cloud(a_from)
,m_xs(a_from.m_xs)
,m_ys(a_from.m_ys)
,m_lower_x(a_from.m_lower_x)
,m_upper_x(a_from.m_upper_x)
,m_lower_y(a_from.m_lower_y)
,m_upper_y(a_from.m_upper_y)
,m_Sxw(a_from.m_Sxw)
,m_Sx2w(a_from.m_Sx2w)
,m_Syw(a_from.m_Syw)
,m_Sy2w(a_from.m_Sy2w)
,m_cnv_x_num(a_from.m_cnv_x_num)
,m_cnv_x_min(a_from.m_cnv_x_min)
,m_cnv_x_max(a_from.m_cnv_x_max)
,m_cnv_y_num(a_from.m_cnv_y_num)
,m_cnv_y_min(a_from.m_cnv_y_min)
,m_cnv_y_max(a_from.m_cnv_y_max)
,m_histo(0)
{
if(a_from.m_histo) {
m_histo = new histo::h2d(*a_from.m_histo);
}
}
c2d& operator=(const c2d& a_from) {
base_cloud::operator=(a_from);
if(&a_from==this) return *this;
m_xs = a_from.m_xs;
m_ys = a_from.m_ys;
m_lower_x = a_from.m_lower_x;
m_upper_x = a_from.m_upper_x;
m_lower_y = a_from.m_lower_y;
m_upper_y = a_from.m_upper_y;
m_Sxw = a_from.m_Sxw;
m_Sx2w = a_from.m_Sx2w;
m_Syw = a_from.m_Syw;
m_Sy2w = a_from.m_Sy2w;
m_cnv_x_num = a_from.m_cnv_x_num;
m_cnv_x_min = a_from.m_cnv_x_min;
m_cnv_x_max = a_from.m_cnv_x_max;
m_cnv_y_num = a_from.m_cnv_y_num;
m_cnv_y_min = a_from.m_cnv_y_min;
m_cnv_y_max = a_from.m_cnv_y_max;
delete m_histo;
m_histo = 0;
if(a_from.m_histo) {
m_histo = new histo::h2d(*a_from.m_histo);
}
return *this;
}
public: //AIDA API
double lowerEdgeX() const {return lower_edge_x();}
double lowerEdgeY() const {return lower_edge_y();}
double upperEdgeX() const {return upper_edge_x();}
double upperEdgeY() const {return upper_edge_y();}
template <class HISTO>
bool fillHistogram(HISTO& a_histo) const {return fill_histogram<HISTO>(a_histo);}
protected:
void clear();
protected:
std::vector<double> m_xs;
std::vector<double> m_ys;
double m_lower_x;
double m_upper_x;
double m_lower_y;
double m_upper_y;
double m_Sxw;
double m_Sx2w;
double m_Syw;
double m_Sy2w;
//
unsigned int m_cnv_x_num;
double m_cnv_x_min;
double m_cnv_x_max;
unsigned int m_cnv_y_num;
double m_cnv_y_min;
double m_cnv_y_max;
histo::h2d* m_histo;
};
}}
namespace tools {
namespace histo {
inline
c2d::c2d()
:base_cloud(UNLIMITED())
,m_lower_x(0)
,m_upper_x(0)
,m_lower_y(0)
,m_upper_y(0)
,m_Sxw(0)
,m_Sx2w(0)
,m_Syw(0)
,m_Sy2w(0)
,m_cnv_x_num(0)
,m_cnv_x_min(0)
,m_cnv_x_max(0)
,m_cnv_y_num(0)
,m_cnv_y_min(0)
,m_cnv_y_max(0)
,m_histo(0)
{}
inline
c2d::c2d(const std::string& a_title,int aLimit)
:base_cloud(aLimit)
,m_lower_x(0)
,m_upper_x(0)
,m_lower_y(0)
,m_upper_y(0)
,m_Sxw(0)
,m_Sx2w(0)
,m_Syw(0)
,m_Sy2w(0)
,m_cnv_x_num(0)
,m_cnv_x_min(0)
,m_cnv_x_max(0)
,m_cnv_y_num(0)
,m_cnv_y_min(0)
,m_cnv_y_max(0)
,m_histo(0)
{
set_title(a_title);
}
inline
void c2d::clear(){
m_lower_x = 0;
m_upper_x = 0;
m_lower_y = 0;
m_upper_y = 0;
m_Sw = 0;
m_Sxw = 0;
m_Sx2w = 0;
m_Syw = 0;
m_Sy2w = 0;
m_xs.clear();
m_ys.clear();
m_ws.clear();
}
inline
bool c2d::convert(
unsigned int a_bins_x,double a_lower_edge_x,double a_upper_edge_x
,unsigned int a_bins_y,double a_lower_edge_y,double a_upper_edge_y
) {
if(m_histo) return true; // Done.
m_histo = new histo::h2d(base_cloud::title(),
a_bins_x,a_lower_edge_x,a_upper_edge_x,
a_bins_y,a_lower_edge_y,a_upper_edge_y);
if(!m_histo) return false;
bool status = fill_histogram(*m_histo);
clear();
return status;
}
inline
bool c2d::convert_to_histogram(){
if( (m_cnv_x_num<=0) || (m_cnv_x_max<=m_cnv_x_min) ||
(m_cnv_y_num<=0) || (m_cnv_y_max<=m_cnv_y_min) ) {
double dx = 0.01 * (upper_edge_x() - lower_edge_x())/BINS();
double dy = 0.01 * (upper_edge_y() - lower_edge_y())/BINS();
return convert(BINS(),lower_edge_x(),upper_edge_x()+dx,
BINS(),lower_edge_y(),upper_edge_y()+dy);
} else {
return convert(m_cnv_x_num,m_cnv_x_min,m_cnv_x_max,
m_cnv_y_num,m_cnv_y_min,m_cnv_y_max);
}
}
inline
bool c2d::set_title(const std::string& a_title){
m_title = a_title;
if(m_histo) m_histo->set_title(a_title);
return true;
}
inline
bool c2d::scale(double a_scale) {
if(m_histo) {
return m_histo->scale(a_scale);
} else {
size_t number = m_ws.size();
for(size_t index=0;index<number;index++) m_ws[index] *= a_scale;
m_Sw *= a_scale;
m_Sxw *= a_scale;
m_Sx2w *= a_scale;
m_Syw *= a_scale;
m_Sy2w *= a_scale;
return true;
}
}
inline
bool c2d::reset() {
clear();
delete m_histo;
m_histo = 0;
return true;
}
inline
bool c2d::fill(double aX,double aY,double aW){
if(!m_histo && (m_limit!=UNLIMITED()) && ((int)m_xs.size()>=m_limit)){
convert_to_histogram();
}
if(m_histo) {
return m_histo->fill(aX,aY,aW);
} else {
if(m_xs.size()) {
m_lower_x = mn<double>(aX,m_lower_x);
m_upper_x = mx<double>(aX,m_upper_x);
} else {
m_lower_x = aX;
m_upper_x = aX;
}
if(m_ys.size()) {
m_lower_y = mn<double>(aY,m_lower_y);
m_upper_y = mx<double>(aY,m_upper_y);
} else {
m_lower_y = aY;
m_upper_y = aY;
}
m_xs.push_back(aX);
m_ys.push_back(aY);
m_ws.push_back(aW);
m_Sw += aW;
double xw = aX * aW;
m_Sxw += xw;
m_Sx2w += aX * xw;
double yw = aY * aW;
m_Syw += yw;
m_Sy2w += aY * yw;
return true;
}
}
inline
bool c2d::convert(const std::vector<double>& a_edges_x,const std::vector<double>& a_edges_y) {
if(m_histo) return true;
m_histo = new histo::h2d(base_cloud::title(),
a_edges_x,a_edges_y);
if(!m_histo) return false;
bool status = fill_histogram(*m_histo);
clear();
return status;
}
inline
bool c2d::set_conversion_parameters(
unsigned int aCnvXnumber,double aCnvXmin,double aCnvXmax
,unsigned int aCnvYnumber,double aCnvYmin,double aCnvYmax
){
m_cnv_x_num = aCnvXnumber;
m_cnv_x_min = aCnvXmin;
m_cnv_x_max = aCnvXmax;
m_cnv_y_num = aCnvYnumber;
m_cnv_y_min = aCnvYmin;
m_cnv_y_max = aCnvYmax;
return true;
}
inline
const h2d& c2d::histogram() const {
if(!m_histo) const_cast<c2d&>(*this).convert_to_histogram();
return *m_histo;
}
inline
double c2d::rms_x() const {
double rms = 0; //FIXME nan.
if(m_histo) {
rms = m_histo->rms_x();
} else {
if(m_Sw==0) {
} else {
double mean = m_Sxw / m_Sw;
rms = ::sqrt(::fabs( (m_Sx2w / m_Sw) - mean * mean));
}
}
return rms;
}
inline
double c2d::rms_y() const {
double rms = 0; //FIXME nan.
if(m_histo) {
rms = m_histo->rms_y();
} else {
if(m_Sw==0) {
} else {
double mean = m_Syw / m_Sw;
rms = ::sqrt(::fabs( (m_Sy2w / m_Sw) - mean * mean));
}
}
return rms;
}
}}
#endif
+525
View File
@@ -0,0 +1,525 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_c3d
#define tools_histo_c3d
#include "base_cloud"
#include "../mnmx"
#include "h3d"
namespace tools {
namespace histo {
class c3d : public base_cloud {
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::c3d");
return s_v;
}
public:
bool set_title(const std::string&);
unsigned int dimension() const {return 3;}
bool reset();
unsigned int entries() const;
public:
double sum_of_weights() const;
bool convert_to_histogram();
bool is_converted() const;
bool scale(double);
public:
bool fill(double,double,double,double = 1);
double lower_edge_x() const;
double upper_edge_x() const;
double lower_edge_y() const;
double upper_edge_y() const;
double lower_edge_z() const;
double upper_edge_z() const;
double value_x(unsigned int) const;
double value_y(unsigned int) const;
double value_z(unsigned int) const;
double weight(unsigned int) const;
double mean_x() const;
double mean_y() const;
double mean_z() const;
double rms_x() const;
double rms_y() const;
double rms_z() const;
bool convert(unsigned int,double,double,
unsigned int,double,double,
unsigned int,double,double);
bool convert(const std::vector<double>&,
const std::vector<double>&,
const std::vector<double>&);
const histo::h3d& histogram() const;
bool fill_histogram(histo::h3d& a_histo) const {
size_t number = m_xs.size();
for(size_t index=0;index<number;index++) {
if(!a_histo.fill(m_xs[index],m_ys[index],m_zs[index],m_ws[index])) return false;
}
return true;
}
bool set_conversion_parameters(unsigned int,double,double,
unsigned int,double,double,
unsigned int,double,double);
bool set_histogram(h3d* a_histo){ //we take ownership of a_histo.
reset();
m_histo = a_histo;
return true;
}
public:
c3d();
c3d(const std::string&,int=base_cloud::UNLIMITED());
virtual ~c3d(){delete m_histo;}
public:
c3d(const c3d& a_from)
:base_cloud(a_from)
,m_xs(a_from.m_xs)
,m_ys(a_from.m_ys)
,m_zs(a_from.m_zs)
,m_lower_x(a_from.m_lower_x)
,m_upper_x(a_from.m_upper_x)
,m_lower_y(a_from.m_lower_y)
,m_upper_y(a_from.m_upper_y)
,m_lower_z(a_from.m_lower_z)
,m_upper_z(a_from.m_upper_z)
,m_Sxw(a_from.m_Sxw)
,m_Sx2w(a_from.m_Sx2w)
,m_Syw(a_from.m_Syw)
,m_Sy2w(a_from.m_Sy2w)
,m_Szw(a_from.m_Szw)
,m_Sz2w(a_from.m_Sz2w)
,m_cnv_x_num(a_from.m_cnv_x_num)
,m_cnv_x_min(a_from.m_cnv_x_min)
,m_cnv_x_max(a_from.m_cnv_x_max)
,m_cnv_y_num(a_from.m_cnv_y_num)
,m_cnv_y_min(a_from.m_cnv_y_min)
,m_cnv_y_max(a_from.m_cnv_y_max)
,m_cnv_z_num(a_from.m_cnv_z_num)
,m_cnv_z_min(a_from.m_cnv_z_min)
,m_cnv_z_max(a_from.m_cnv_z_max)
,m_histo(0)
{
if(a_from.m_histo) {
m_histo = new histo::h3d(*a_from.m_histo);
}
}
c3d& operator=(const c3d& a_from) {
base_cloud::operator=(a_from);
if(&a_from==this) return *this;
m_xs = a_from.m_xs;
m_ys = a_from.m_ys;
m_zs = a_from.m_zs;
m_lower_x = a_from.m_lower_x;
m_upper_x = a_from.m_upper_x;
m_lower_y = a_from.m_lower_y;
m_upper_y = a_from.m_upper_y;
m_lower_z = a_from.m_lower_z;
m_upper_z = a_from.m_upper_z;
m_Sxw = a_from.m_Sxw;
m_Sx2w = a_from.m_Sx2w;
m_Syw = a_from.m_Syw;
m_Sy2w = a_from.m_Sy2w;
m_Szw = a_from.m_Szw;
m_Sz2w = a_from.m_Sz2w;
m_cnv_x_num = a_from.m_cnv_x_num;
m_cnv_x_min = a_from.m_cnv_x_min;
m_cnv_x_max = a_from.m_cnv_x_max;
m_cnv_y_num = a_from.m_cnv_y_num;
m_cnv_y_min = a_from.m_cnv_y_min;
m_cnv_y_max = a_from.m_cnv_y_max;
m_cnv_z_num = a_from.m_cnv_z_num;
m_cnv_z_min = a_from.m_cnv_z_min;
m_cnv_z_max = a_from.m_cnv_z_max;
delete m_histo;
m_histo = 0;
if(a_from.m_histo) {
m_histo = new histo::h3d(*a_from.m_histo);
}
return *this;
}
protected:
void clear();
protected:
std::vector<double> m_xs;
std::vector<double> m_ys;
std::vector<double> m_zs;
double m_lower_x;
double m_upper_x;
double m_lower_y;
double m_upper_y;
double m_lower_z;
double m_upper_z;
double m_Sxw;
double m_Sx2w;
double m_Syw;
double m_Sy2w;
double m_Szw;
double m_Sz2w;
//
unsigned int m_cnv_x_num;
double m_cnv_x_min;
double m_cnv_x_max;
unsigned int m_cnv_y_num;
double m_cnv_y_min;
double m_cnv_y_max;
unsigned int m_cnv_z_num;
double m_cnv_z_min;
double m_cnv_z_max;
histo::h3d* m_histo;
};
}}
namespace tools {
namespace histo {
inline
c3d::c3d()
:base_cloud(UNLIMITED())
,m_lower_x(0)
,m_upper_x(0)
,m_lower_y(0)
,m_upper_y(0)
,m_lower_z(0)
,m_upper_z(0)
,m_Sxw(0)
,m_Sx2w(0)
,m_Syw(0)
,m_Sy2w(0)
,m_Szw(0)
,m_Sz2w(0)
,m_cnv_x_num(0)
,m_cnv_x_min(0)
,m_cnv_x_max(0)
,m_cnv_y_num(0)
,m_cnv_y_min(0)
,m_cnv_y_max(0)
,m_cnv_z_num(0)
,m_cnv_z_min(0)
,m_cnv_z_max(0)
,m_histo(0)
{}
inline
c3d::c3d(const std::string& a_title,int aLimit)
:base_cloud(aLimit)
,m_lower_x(0)
,m_upper_x(0)
,m_lower_y(0)
,m_upper_y(0)
,m_lower_z(0)
,m_upper_z(0)
,m_Sxw(0)
,m_Sx2w(0)
,m_Syw(0)
,m_Sy2w(0)
,m_Szw(0)
,m_Sz2w(0)
,m_cnv_x_num(0)
,m_cnv_x_min(0)
,m_cnv_x_max(0)
,m_cnv_y_num(0)
,m_cnv_y_min(0)
,m_cnv_y_max(0)
,m_cnv_z_num(0)
,m_cnv_z_min(0)
,m_cnv_z_max(0)
,m_histo(0)
{
set_title(a_title);
}
inline
bool c3d::is_converted() const {return m_histo ? true : false;}
inline
void c3d::clear(){
m_lower_x = 0;
m_upper_x = 0;
m_lower_y = 0;
m_upper_y = 0;
m_lower_z = 0;
m_upper_z = 0;
m_Sw = 0;
m_Sxw = 0;
m_Sx2w = 0;
m_Syw = 0;
m_Sy2w = 0;
m_Szw = 0;
m_Sz2w = 0;
m_xs.clear();
m_ys.clear();
m_zs.clear();
m_ws.clear();
}
inline
bool c3d::convert(
unsigned int a_bins_x,double a_lower_edge_x,double a_upper_edge_x
,unsigned int a_bins_y,double a_lower_edge_y,double a_upper_edge_y
,unsigned int a_bins_z,double a_lower_edge_z,double a_upper_edge_z
) {
if(m_histo) return true; // Done.
m_histo = new histo::h3d(base_cloud::title(),
a_bins_x,a_lower_edge_x,a_upper_edge_x,
a_bins_y,a_lower_edge_y,a_upper_edge_y,
a_bins_z,a_lower_edge_z,a_upper_edge_z);
if(!m_histo) return false;
bool status = fill_histogram(*m_histo);
clear();
return status;
}
inline
bool c3d::convert_to_histogram(){
if( (m_cnv_x_num<=0) || (m_cnv_x_max<=m_cnv_x_min) ||
(m_cnv_y_num<=0) || (m_cnv_y_max<=m_cnv_y_min) ||
(m_cnv_z_num<=0) || (m_cnv_z_max<=m_cnv_z_min) ) {
double dx = 0.01 * (upper_edge_x() - lower_edge_x())/BINS();
double dy = 0.01 * (upper_edge_y() - lower_edge_y())/BINS();
double dz = 0.01 * (upper_edge_z() - lower_edge_z())/BINS();
return convert(BINS(),lower_edge_x(),upper_edge_x()+dx,
BINS(),lower_edge_y(),upper_edge_y()+dy,
BINS(),lower_edge_z(),upper_edge_z()+dz);
} else {
return convert(m_cnv_x_num,m_cnv_x_min,m_cnv_x_max,
m_cnv_y_num,m_cnv_y_min,m_cnv_y_max,
m_cnv_z_num,m_cnv_z_min,m_cnv_z_max);
}
}
inline
bool c3d::set_title(const std::string& a_title){
m_title = a_title;
if(m_histo) m_histo->set_title(a_title);
return true;
}
inline
bool c3d::scale(double a_scale) {
if(m_histo) {
return m_histo->scale(a_scale);
} else {
size_t number = m_ws.size();
for(size_t index=0;index<number;index++) m_ws[index] *= a_scale;
m_Sw *= a_scale;
m_Sxw *= a_scale;
m_Sx2w *= a_scale;
m_Syw *= a_scale;
m_Sy2w *= a_scale;
m_Szw *= a_scale;
m_Sz2w *= a_scale;
return true;
}
}
inline
bool c3d::set_conversion_parameters(
unsigned int aCnvXnumber,double aCnvXmin,double aCnvXmax
,unsigned int aCnvYnumber,double aCnvYmin,double aCnvYmax
,unsigned int aCnvZnumber,double aCnvZmin,double aCnvZmax
){
m_cnv_x_num = aCnvXnumber;
m_cnv_x_min = aCnvXmin;
m_cnv_x_max = aCnvXmax;
m_cnv_y_num = aCnvYnumber;
m_cnv_y_min = aCnvYmin;
m_cnv_y_max = aCnvYmax;
m_cnv_z_num = aCnvZnumber;
m_cnv_z_min = aCnvZmin;
m_cnv_z_max = aCnvZmax;
return true;
}
inline
const h3d& c3d::histogram() const {
if(!m_histo) const_cast<c3d&>(*this).convert_to_histogram();
return *m_histo;
}
inline
bool c3d::reset() {
clear();
delete m_histo;
m_histo = 0;
return true;
}
inline
bool c3d::fill(double aX,double aY,double aZ,double aW){
if(!m_histo && (m_limit!=UNLIMITED()) && ((int)m_xs.size()>=m_limit)){
convert_to_histogram();
}
if(m_histo) {
return m_histo->fill(aX,aY,aZ,aW);
} else {
if(m_xs.size()) {
m_lower_x = mn<double>(aX,m_lower_x);
m_upper_x = mx<double>(aX,m_upper_x);
} else {
m_lower_x = aX;
m_upper_x = aX;
}
if(m_ys.size()) {
m_lower_y = mn<double>(aY,m_lower_y);
m_upper_y = mx<double>(aY,m_upper_y);
} else {
m_lower_y = aY;
m_upper_y = aY;
}
if(m_zs.size()) {
m_lower_z = mn<double>(aZ,m_lower_z);
m_upper_z = mx<double>(aZ,m_upper_z);
} else {
m_lower_z = aZ;
m_upper_z = aZ;
}
m_xs.push_back(aX);
m_ys.push_back(aY);
m_zs.push_back(aZ);
m_ws.push_back(aW);
m_Sw += aW;
double xw = aX * aW;
m_Sxw += xw;
m_Sx2w += aX * xw;
double yw = aY * aW;
m_Syw += yw;
m_Sy2w += aY * yw;
double zw = aZ * aW;
m_Szw += zw;
m_Sz2w += aZ * zw;
return true;
}
}
inline
bool c3d::convert(
const std::vector<double>& a_edges_x
,const std::vector<double>& a_edges_y
,const std::vector<double>& a_edges_z
) {
if(m_histo) return true;
m_histo = new histo::h3d(base_cloud::title(),
a_edges_x,a_edges_y,a_edges_z);
if(!m_histo) return false;
bool status = fill_histogram(*m_histo);
clear();
return status;
}
inline
double c3d::sum_of_weights() const {
return (m_histo ? m_histo->sum_bin_heights() : m_Sw);
}
inline
unsigned int c3d::entries() const {
return m_histo ? m_histo->all_entries() : (unsigned int)m_ws.size();
}
inline
double c3d::lower_edge_x() const {
return m_histo ? m_histo->axis_x().lower_edge() : m_lower_x;
}
inline
double c3d::lower_edge_y() const {
return m_histo ? m_histo->axis_y().lower_edge() : m_lower_y;
}
inline
double c3d::lower_edge_z() const {
return m_histo ? m_histo->axis_z().lower_edge() : m_lower_z;
}
inline
double c3d::upper_edge_x() const {
return m_histo ? m_histo->axis_x().upper_edge() : m_upper_x;
}
inline
double c3d::upper_edge_y() const {
return m_histo ? m_histo->axis_y().upper_edge() : m_upper_y;
}
inline
double c3d::upper_edge_z() const {
return m_histo ? m_histo->axis_z().upper_edge() : m_upper_z;
}
inline
double c3d::value_x(unsigned int a_index) const {
return m_histo ? 0 : m_xs[a_index];
}
inline
double c3d::value_y(unsigned int a_index) const {
return m_histo ? 0 : m_ys[a_index];
}
inline
double c3d::value_z(unsigned int a_index) const {
return m_histo ? 0 : m_zs[a_index];
}
inline
double c3d::weight(unsigned int a_index) const {
return m_histo ? 0 : m_ws[a_index];
}
inline
double c3d::mean_x() const {
return m_histo ? m_histo->mean_x() : (m_Sw?m_Sxw/m_Sw:0);
}
inline
double c3d::mean_y() const {
return m_histo ? m_histo->mean_y() : (m_Sw?m_Syw/m_Sw:0);
}
inline
double c3d::mean_z() const {
return m_histo ? m_histo->mean_z() : (m_Sw?m_Szw/m_Sw:0);
}
inline
double c3d::rms_x() const {
double rms = 0; //FIXME nan.
if(m_histo) {
rms = m_histo->rms_x();
} else {
if(m_Sw==0) {
} else {
double mean = m_Sxw / m_Sw;
rms = ::sqrt(::fabs( (m_Sx2w / m_Sw) - mean * mean));
}
}
return rms;
}
inline
double c3d::rms_y() const {
double rms = 0; //FIXME nan.
if(m_histo) {
rms = m_histo->rms_y();
} else {
if(m_Sw==0) {
} else {
double mean = m_Syw / m_Sw;
rms = ::sqrt(::fabs( (m_Sy2w / m_Sw) - mean * mean));
}
}
return rms;
}
inline
double c3d::rms_z() const {
double rms = 0; //FIXME nan.
if(m_histo) {
rms = m_histo->rms_z();
} else {
if(m_Sw==0) {
} else {
double mean = m_Szw / m_Sw;
rms = ::sqrt(::fabs( (m_Sz2w / m_Sw) - mean * mean));
}
}
return rms;
}
}}
#endif
+249
View File
@@ -0,0 +1,249 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_dps
#define tools_histo_dps
// data point set.
#include <vector>
#include <string>
#include "../mnmx"
#ifdef TOOLS_MEM
#include "../mem"
#endif
namespace tools {
namespace histo {
class measurement {
static const std::string& s_class() {
static const std::string s_v("tools::histo::measurement");
return s_v;
}
public:
measurement():m_value(0),m_error_plus(0),m_error_minus(0){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
measurement(double a_value,double a_error_plus,double a_error_minus)
:m_value(a_value)
,m_error_plus(a_error_plus)
,m_error_minus(a_error_minus)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~measurement(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
measurement(const measurement& a_from)
:m_value(a_from.m_value)
,m_error_plus(a_from.m_error_plus)
,m_error_minus(a_from.m_error_minus)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
measurement& operator=(const measurement& a_from) {
if(&a_from==this) return *this;
m_value = a_from.m_value;
m_error_plus = a_from.m_error_plus;
m_error_minus = a_from.m_error_minus;
return *this;
}
public:
double value() const {return m_value;}
double error_plus() const {return m_error_plus;}
double error_minus() const {return m_error_minus;}
void set_value(double a_v) {m_value = a_v;}
void set_error_plus(double a_v) {m_error_plus = a_v;}
void set_error_minus(double a_v) {m_error_minus = a_v;}
protected:
double m_value;
double m_error_plus;
double m_error_minus;
};
class data_point {
static const std::string& s_class() {
static const std::string s_v("tools::histo::data_point");
return s_v;
}
public:
data_point(unsigned int a_dim):m_measurements(a_dim){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~data_point() {
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
data_point(const data_point& a_from)
:m_measurements(a_from.m_measurements)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
data_point& operator=(const data_point& a_from) {
if(&a_from==this) return *this;
m_measurements = a_from.m_measurements;
return *this;
}
public: //AIDA/Idata_point
size_t dimension() const {return m_measurements.size();}
measurement& coordinate(unsigned int a_coord) {
//WARNING : no check done on a_coord vs m_dim.
return m_measurements[a_coord];
}
const measurement& coordinate(unsigned int a_coord) const {
//WARNING : no check done on a_coord vs m_dim.
return m_measurements[a_coord];
}
protected:
std::vector<measurement> m_measurements;
};
class dps {
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::dps");
return s_v;
}
public:
dps():m_dim(0){}
dps(const std::string& a_title,unsigned int a_dim)
:m_title(a_title),m_dim(a_dim)
{}
virtual ~dps(){}
public:
dps(const dps& a_from)
:m_title(a_from.m_title)
,m_dim(a_from.m_dim)
,m_points(a_from.m_points)
{}
dps& operator=(const dps& a_from) {
if(&a_from==this) return *this;
m_title = a_from.m_title;
m_dim = a_from.m_dim;
m_points = a_from.m_points;
return *this;
}
public:
const std::string& title() const {return m_title;}
void set_title(const std::string& a_s) {m_title = a_s;}
unsigned int dimension() const {return m_dim;}
void clear() {m_points.clear();}
size_t size() const {return m_points.size();}
const data_point& point(size_t a_index) const {
//WARNING : no check done on a_index.
return m_points[a_index];
}
data_point& point(size_t a_index) {
//WARNING : no check done on a_index.
return m_points[a_index];
}
data_point& add_point() {
m_points.push_back(data_point(m_dim));
return m_points.back();
}
bool remove_point(size_t a_index) {
bool done = false;
if(a_index<m_points.size()){
std::vector<data_point>::iterator it = m_points.begin();
it += a_index;
m_points.erase(it);
done = true;
}
return done;
}
bool lower_extent(unsigned int a_coord,double& a_value) const {
if(m_points.empty()||(a_coord>=m_dim)){
a_value = 0;
return false;
}
std::vector<data_point>::const_iterator it = m_points.begin();
a_value = (*it).coordinate(a_coord).value();
++it;
for(;it!=m_points.end();++it) {
a_value = mn<double>(a_value,(*it).coordinate(a_coord).value());
}
return true;
}
bool upper_extent(unsigned int a_coord,double& a_value) const {
if(m_points.empty()||(a_coord>=m_dim)){
a_value = 0;
return false;
}
std::vector<data_point>::const_iterator it = m_points.begin();
a_value = (*it).coordinate(a_coord).value();
++it;
for(;it!=m_points.end();++it) {
a_value = mx<double>(a_value,(*it).coordinate(a_coord).value());
}
return true;
}
void scale(double a_scale) {
std::vector<data_point>::iterator it;
for(it=m_points.begin();it!=m_points.end();++it) {
for(unsigned int coord=0;coord<m_dim;coord++) {
measurement& m = (*it).coordinate(coord);
m.set_value(m.value() * a_scale);
m.set_error_plus(m.error_plus() * a_scale);
m.set_error_minus(m.error_minus() * a_scale);
}
}
}
void scale_value(double a_scale) {
std::vector<data_point>::iterator it;
for(it=m_points.begin();it!=m_points.end();++it) {
for(unsigned int coord=0;coord<m_dim;coord++) {
measurement& m = (*it).coordinate(coord);
m.set_value(m.value() * a_scale);
}
}
}
void scale_errors(double a_scale) {
std::vector<data_point>::iterator it;
for(it=m_points.begin();it!=m_points.end();++it) {
for(unsigned int coord=0;coord<m_dim;coord++) {
measurement& m = (*it).coordinate(coord);
m.set_error_plus(m.error_plus() * a_scale);
m.set_error_minus(m.error_minus() * a_scale);
}
}
}
protected:
std::string m_title;
unsigned int m_dim;
std::vector<data_point> m_points;
};
}}
#endif
+257
View File
@@ -0,0 +1,257 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h1
#define tools_histo_h1
#include "b1"
namespace tools {
namespace histo { //have that for h1 ?
//TC is for a coordinate.
//TO is for an offset used to identify a bin.
//TN is for a number of entries.
//TW is for a weight.
//TH is for a height. Should be the same as TW.
template <class TC,class TO,class TN,class TW,class TH>
class h1 : public b1<TC,TO,TN,TW,TH> {
typedef b1<TC,TO,TN,TW,TH> parent;
public:
typedef histo_data<TC,TO,TN,TW> hd_t;
typedef typename parent::bn_t bn_t;
typedef typename parent::axis_t axis_t;
protected:
virtual TH get_bin_height(TO a_offset) const { //TH should be the same as TW
return parent::m_bin_Sw[a_offset];
}
public:
virtual TH bin_error(int aI) const { //TH should be the same as TW
TO offset;
if(!parent::_find_offset(aI,offset)) return 0;
return ::sqrt(parent::m_bin_Sw2[offset]);
}
public:
bool multiply(TW a_factor){return parent::base_multiply(a_factor);}
bool scale(TW a_factor) {return multiply(a_factor);}
void copy_from_data(const hd_t& a_from) {parent::base_from_data(a_from);}
hd_t get_histo_data() const {return *this;} //deprecated. Keep it for g4tools.
bool reset() {
parent::base_reset();
return true;
}
bool fill(TC aX,TW aWeight = 1) {
if(parent::m_dimension!=1) return false;
bn_t ibin;
if(!parent::m_axes[0].coord_to_absolute_index(aX,ibin)) return false;
TO offset = ibin;
parent::m_bin_entries[offset]++;
parent::m_bin_Sw[offset] += aWeight;
parent::m_bin_Sw2[offset] += aWeight * aWeight;
TC xw = aX * aWeight;
TC x2w = aX * xw;
parent::m_bin_Sxw[offset][0] += xw;
parent::m_bin_Sx2w[offset][0] += x2w;
bool inRange = true;
if(ibin==0) inRange = false;
else if(ibin==(parent::m_axes[0].m_number_of_bins+1)) inRange = false;
parent::m_all_entries++;
if(inRange) {
// fast getters :
parent::m_in_range_entries++;
parent::m_in_range_Sw += aWeight;
parent::m_in_range_Sw2 += aWeight*aWeight;
parent::m_in_range_Sxw[0] += xw;
parent::m_in_range_Sx2w[0] += x2w;
}
return true;
}
bool set_bin_content(bn_t a_ibin,TN a_entries,TW a_Sw,TW a_Sw2,TC a_Sxw,TC a_Sx2w) {
if(parent::m_dimension!=1) return false;
if(a_ibin>(parent::m_axes[0].m_number_of_bins+1)) return false;
bool inRange = true;
if(a_ibin==0) inRange = false;
else if(a_ibin==(parent::m_axes[0].m_number_of_bins+1)) inRange = false;
TO offset = a_ibin;
parent::m_all_entries -= parent::m_bin_entries[offset];
if(inRange) {
parent::m_in_range_entries -= parent::m_bin_entries[offset];
parent::m_in_range_Sw -= parent::m_bin_Sw[offset];
parent::m_in_range_Sw2 -= parent::m_bin_Sw2[offset];
parent::m_in_range_Sxw[0] -= parent::m_bin_Sxw[offset][0];
parent::m_in_range_Sx2w[0] -= parent::m_bin_Sx2w[offset][0];
}
parent::m_bin_entries[offset] = a_entries;
parent::m_bin_Sw[offset] = a_Sw;
parent::m_bin_Sw2[offset] = a_Sw2;
parent::m_bin_Sxw[offset][0] = a_Sxw;
parent::m_bin_Sx2w[offset][0] = a_Sx2w;
parent::m_all_entries += a_entries;
if(inRange) {
parent::m_in_range_entries += a_entries;
parent::m_in_range_Sw += a_Sw;
parent::m_in_range_Sw2 += a_Sw2;
parent::m_in_range_Sxw[0] += a_Sxw;
parent::m_in_range_Sx2w[0] += a_Sx2w;
}
return true;
}
bool get_bin_content(bn_t a_ibin,TN& a_entries,TW& a_Sw,TW& a_Sw2,TC& a_Sxw,TC& a_Sx2w) {
if(parent::m_dimension!=1) {
a_entries = 0;a_Sw = 0;a_Sw2 = 0;a_Sxw = 0;a_Sx2w = 0;
return false;
}
if(a_ibin>(parent::m_axes[0].m_number_of_bins+1)) {
a_entries = 0;a_Sw = 0;a_Sw2 = 0;a_Sxw = 0;a_Sx2w = 0;
return false;
}
TO offset = a_ibin;
a_entries = parent::m_bin_entries[offset];
a_Sw = parent::m_bin_Sw[offset];
a_Sw2 = parent::m_bin_Sw2[offset];
a_Sxw = parent::m_bin_Sxw[offset][0];
a_Sx2w = parent::m_bin_Sx2w[offset][0];
return true;
}
bool add(const h1& a_histo){
parent::base_add(a_histo);
return true;
}
bool subtract(const h1& a_histo){
parent::base_subtract(a_histo);
return true;
}
bool multiply(const h1& a_histo) {
return parent::base_multiply(a_histo);
}
bool divide(const h1& a_histo) {
return parent::base_divide(a_histo);
}
bool gather_bins(unsigned int a_factor) { //for exa 2,3.
if(!a_factor) return false;
// actual bin number must be a multiple of a_factor.
const axis_t& _axis = parent::axis();
bn_t n = _axis.bins();
if(!n) return false;
bn_t new_n = n/a_factor;
if(a_factor*new_n!=n) return false;
h1* new_h = 0;
if(_axis.is_fixed_binning()) {
new_h = new h1(parent::m_title,new_n,_axis.lower_edge(),_axis.upper_edge());
} else {
const std::vector<TC>& _edges = _axis.edges();
std::vector<TC> new_edges(new_n+1);
for(bn_t ibin=0;ibin<new_n;ibin++) {
new_edges[ibin] = _edges[ibin*a_factor];
}
new_edges[new_n] = _edges[n]; //upper edge.
new_h = new h1(parent::m_title,new_edges);
}
if(!new_h) return false;
TO offset,new_offset,offac;
for(bn_t ibin=0;ibin<new_n;ibin++) {
new_offset = ibin+1;
offset = a_factor*ibin+1;
for(unsigned int ifac=0;ifac<a_factor;ifac++) {
offac = offset+ifac;
new_h->m_bin_entries[new_offset] += parent::m_bin_entries[offac];
new_h->m_bin_Sw[new_offset] += parent::m_bin_Sw[offac];
new_h->m_bin_Sw2[new_offset] += parent::m_bin_Sw2[offac];
new_h->m_bin_Sxw[new_offset][0] += parent::m_bin_Sxw[offac][0];
new_h->m_bin_Sx2w[new_offset][0] += parent::m_bin_Sx2w[offac][0];
}
}
//underflow :
new_offset = 0;
offac = 0;
new_h->m_bin_entries[new_offset] = parent::m_bin_entries[offac];
new_h->m_bin_Sw[new_offset] = parent::m_bin_Sw[offac];
new_h->m_bin_Sw2[new_offset] = parent::m_bin_Sw2[offac];
new_h->m_bin_Sxw[new_offset][0] = parent::m_bin_Sxw[offac][0];
new_h->m_bin_Sx2w[new_offset][0] = parent::m_bin_Sx2w[offac][0];
//overflow :
new_offset = new_n+1;
offac = n+1;
new_h->m_bin_entries[new_offset] = parent::m_bin_entries[offac];
new_h->m_bin_Sw[new_offset] = parent::m_bin_Sw[offac];
new_h->m_bin_Sw2[new_offset] = parent::m_bin_Sw2[offac];
new_h->m_bin_Sxw[new_offset][0] = parent::m_bin_Sxw[offac][0];
new_h->m_bin_Sx2w[new_offset][0] = parent::m_bin_Sx2w[offac][0];
*this = *new_h;
return true;
}
bool equals_TH(const h1& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
if(!parent::equals_TH(a_from,a_prec,a_fabs,true)) return false;
return true;
}
void not_a_profile() const {}
public: //CERN-ROOT API (for MEMPHYS sim).
bool Fill(TC aX,TW aWeight = 1) {return fill(aX,aWeight);}
public:
h1(const std::string& a_title,bn_t aXnumber,TC aXmin,TC aXmax)
:parent(a_title,aXnumber,aXmin,aXmax){}
h1(const std::string& a_title,const std::vector<TC>& a_edges)
:parent(a_title,a_edges){}
virtual ~h1(){}
public:
h1(const h1& a_from):parent(a_from){}
h1& operator=(const h1& a_from){
if(&a_from==this) return *this;
parent::operator=(a_from);
return *this;
}
};
}}
#endif
+49
View File
@@ -0,0 +1,49 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h1d
#define tools_histo_h1d
#include "h1"
namespace tools {
namespace histo {
// d in h1d is for double (and not dimension).
class h1d : public h1<double,unsigned int,unsigned int,double,double> {
typedef h1<double,unsigned int,unsigned int,double,double> parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::h1d");
return s_v;
}
const std::string& s_cls() const {return s_class();}
public:
h1d():parent("",10,0,1){} //for I/O when reading.
h1d(const std::string& a_title,unsigned int aXnumber,double aXmin,double aXmax)
:parent(a_title,aXnumber,aXmin,aXmax){}
h1d(const std::string& a_title,const std::vector<double>& a_edges)
:parent(a_title,a_edges){}
virtual ~h1d(){}
public:
h1d(const h1d& a_from):parent(a_from){}
h1d& operator=(const h1d& a_from){
if(&a_from==this) return *this;
parent::operator=(a_from);
return *this;
}
private:static void check_instantiation() {h1d h("",10,0,1);h.gather_bins(5);}
};
}}
#endif
+47
View File
@@ -0,0 +1,47 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h1df
#define tools_histo_h1df
// coord is in double.
// weight is in float.
#include "h1"
namespace tools {
namespace histo {
class h1df : public h1<double,unsigned int,unsigned int,float,float> {
typedef h1<double,unsigned int,unsigned int,float,float> parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::h1df");
return s_v;
}
const std::string& s_cls() const {return s_class();}
public:
h1df(const std::string& a_title,unsigned int aXnumber,float aXmin,float aXmax)
:parent(a_title,aXnumber,aXmin,aXmax){}
h1df(const std::string& a_title,const std::vector<double>& a_edges)
:parent(a_title,a_edges){}
virtual ~h1df(){}
public:
h1df(const h1df& a_from): parent(a_from){}
h1df& operator=(const h1df& a_from){
parent::operator=(a_from);
return *this;
}
private:static void check_instantiation() {h1df h("",10,0,1);h.gather_bins(5);}
};
}}
#endif
+226
View File
@@ -0,0 +1,226 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h2
#define tools_histo_h2
#include "b2"
namespace tools {
namespace histo {
template <class TC,class TO,class TN,class TW,class TH>
class h2 : public b2<TC,TO,TN,TW,TH> {
typedef b2<TC,TO,TN,TW,TH> parent;
public:
typedef histo_data<TC,TO,TN,TW> hd_t;
typedef typename b2<TC,TO,TN,TW,TH>::bn_t bn_t;
protected:
virtual TH get_bin_height(TO a_offset) const { //TH should be the same as TW
return parent::m_bin_Sw[a_offset];
}
public:
virtual TH bin_error(int aI,int aJ) const {
TO offset;
if(!parent::_find_offset(aI,aJ,offset)) return 0;
return ::sqrt(parent::m_bin_Sw2[offset]);
}
public:
bool multiply(TW a_factor){return parent::base_multiply(a_factor);}
bool scale(TW a_factor) {return multiply(a_factor);}
void copy_from_data(const hd_t& a_from) {parent::base_from_data(a_from);}
hd_t get_histo_data() const {return *this;} //deprecated. Keep it for g4tools.
bool reset() {
parent::base_reset();
return true;
}
bool fill(TC aX,TC aY,TW aWeight = 1) {
if(parent::m_dimension!=2) return false;
bn_t ibin,jbin;
if(!parent::m_axes[0].coord_to_absolute_index(aX,ibin)) return false;
if(!parent::m_axes[1].coord_to_absolute_index(aY,jbin)) return false;
TO offset = ibin + jbin * parent::m_axes[1].m_offset;
parent::m_bin_entries[offset]++;
parent::m_bin_Sw[offset] += aWeight;
parent::m_bin_Sw2[offset] += aWeight * aWeight;
TC xw = aX * aWeight;
TC x2w = aX * xw;
parent::m_bin_Sxw[offset][0] += xw;
parent::m_bin_Sx2w[offset][0] += x2w;
TC yw = aY * aWeight;
TC y2w = aY * yw;
parent::m_bin_Sxw[offset][1] += yw;
parent::m_bin_Sx2w[offset][1] += y2w;
bool inRange = true;
if(ibin==0) inRange = false;
else if(ibin==(parent::m_axes[0].m_number_of_bins+1)) inRange = false;
if(jbin==0) inRange = false;
else if(jbin==(parent::m_axes[1].m_number_of_bins+1)) inRange = false;
parent::m_all_entries++;
if(inRange) {
parent::m_in_range_plane_Sxyw[0] += aX * aY * aWeight;
// fast getters :
parent::m_in_range_entries++;
parent::m_in_range_Sw += aWeight;
parent::m_in_range_Sw2 += aWeight*aWeight;
parent::m_in_range_Sxw[0] += xw;
parent::m_in_range_Sx2w[0] += x2w;
parent::m_in_range_Sxw[1] += yw;
parent::m_in_range_Sx2w[1] += y2w;
}
return true;
}
bool set_bin_content(bn_t a_ibin,bn_t a_jbin,
TN a_entries,TW a_Sw,TW a_Sw2,
TC a_Sxw,TC a_Sx2w,TC a_Syw,TC a_Sy2w) {
if(parent::m_dimension!=2) return false;
if(a_ibin>(parent::m_axes[0].m_number_of_bins+1)) return false;
if(a_jbin>(parent::m_axes[1].m_number_of_bins+1)) return false;
bool inRange = true;
if(a_ibin==0) inRange = false;
else if(a_ibin==(parent::m_axes[0].m_number_of_bins+1)) inRange = false;
if(a_jbin==0) inRange = false;
else if(a_jbin==(parent::m_axes[1].m_number_of_bins+1)) inRange = false;
TO offset = a_ibin + a_jbin * parent::m_axes[1].m_offset;
parent::m_all_entries -= parent::m_bin_entries[offset];
if(inRange) {
parent::m_in_range_entries -= parent::m_bin_entries[offset];
parent::m_in_range_Sw -= parent::m_bin_Sw[offset];
parent::m_in_range_Sw2 -= parent::m_bin_Sw2[offset];
parent::m_in_range_Sxw[0] -= parent::m_bin_Sxw[offset][0];
parent::m_in_range_Sx2w[0] -= parent::m_bin_Sx2w[offset][0];
parent::m_in_range_Sxw[1] -= parent::m_bin_Sxw[offset][1];
parent::m_in_range_Sx2w[1] -= parent::m_bin_Sx2w[offset][1];
}
parent::m_bin_entries[offset] = a_entries;
parent::m_bin_Sw[offset] = a_Sw;
parent::m_bin_Sw2[offset] = a_Sw2;
parent::m_bin_Sxw[offset][0] = a_Sxw;
parent::m_bin_Sx2w[offset][0] = a_Sx2w;
parent::m_bin_Sxw[offset][1] = a_Syw;
parent::m_bin_Sx2w[offset][1] = a_Sy2w;
parent::m_all_entries += a_entries;
if(inRange) {
//parent::m_in_range_plane_Sxyw[0] ??? ill-defined.
parent::m_in_range_entries += a_entries;
parent::m_in_range_Sw += a_Sw;
parent::m_in_range_Sw2 += a_Sw2;
parent::m_in_range_Sxw[0] += a_Sxw;
parent::m_in_range_Sx2w[0] += a_Sx2w;
parent::m_in_range_Sxw[1] += a_Syw;
parent::m_in_range_Sx2w[1] += a_Sy2w;
}
return true;
}
bool get_bin_content(bn_t a_ibin,bn_t a_jbin,
TN& a_entries,TW& a_Sw,TW& a_Sw2,
TC& a_Sxw,TC& a_Sx2w,
TC& a_Syw,TC& a_Sy2w) {
if(parent::m_dimension!=2) {
a_entries = 0;a_Sw = 0;a_Sw2 = 0;
a_Sxw = 0;a_Sx2w = 0;
a_Syw = 0;a_Sy2w = 0;
return false;
}
if(a_ibin>(parent::m_axes[0].m_number_of_bins+1)) {
a_entries = 0;a_Sw = 0;a_Sw2 = 0;
a_Sxw = 0;a_Sx2w = 0;
a_Syw = 0;a_Sy2w = 0;
return false;
}
if(a_jbin>(parent::m_axes[1].m_number_of_bins+1)) {
a_entries = 0;a_Sw = 0;a_Sw2 = 0;
a_Sxw = 0;a_Sx2w = 0;
a_Syw = 0;a_Sy2w = 0;
return false;
}
TO offset = a_ibin + a_jbin * parent::m_axes[1].m_offset;
a_entries = parent::m_bin_entries[offset];
a_Sw = parent::m_bin_Sw[offset];
a_Sw2 = parent::m_bin_Sw2[offset];
a_Sxw = parent::m_bin_Sxw[offset][0];
a_Sx2w = parent::m_bin_Sx2w[offset][0];
a_Syw = parent::m_bin_Sxw[offset][1];
a_Sy2w = parent::m_bin_Sx2w[offset][1];
return true;
}
bool add(const h2& a_histo){
parent::base_add(a_histo);
return true;
}
bool subtract(const h2& a_histo){
parent::base_subtract(a_histo);
return true;
}
bool multiply(const h2& a_histo) {
return parent::base_multiply(a_histo);
}
bool divide(const h2& a_histo) {
return parent::base_divide(a_histo);
}
bool equals_TH(const h2& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
if(!parent::equals_TH(a_from,a_prec,a_fabs,true)) return false;
return true;
}
void not_a_profile() const {}
public: //CERN-ROOT API
bool Fill(TC aX,TC aY,TW aWeight = 1) {return fill(aX,aY,aWeight);}
public:
h2(const std::string& a_title,bn_t aXnumber,TC aXmin,TC aXmax,bn_t aYnumber,TC aYmin,TC aYmax)
:parent(a_title,aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax)
{}
h2(const std::string& a_title,const std::vector<TC>& a_edges_x,const std::vector<TC>& a_edges_y)
:parent(a_title,a_edges_x,a_edges_y)
{}
virtual ~h2(){}
public:
h2(const h2& a_from): parent(a_from){}
h2& operator=(const h2& a_from){
parent::operator=(a_from);
return *this;
}
};
}}
#endif
+51
View File
@@ -0,0 +1,51 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h2d
#define tools_histo_h2d
#include "h2"
namespace tools {
namespace histo {
class h2d : public h2<double,unsigned int,unsigned int,double,double> {
typedef h2<double,unsigned int,unsigned int,double,double> parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::h2d");
return s_v;
}
const std::string& s_cls() const {return s_class();}
public:
h2d():parent("",10,0,1,10,0,1){} //for I/O when reading.
h2d(const std::string& a_title,
unsigned int aXnumber,double aXmin,double aXmax,
unsigned int aYnumber,double aYmin,double aYmax)
:parent(a_title,aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax)
{}
h2d(const std::string& a_title,
const std::vector<double>& a_edges_x,
const std::vector<double>& a_edges_y)
:parent(a_title,a_edges_x,a_edges_y)
{}
virtual ~h2d(){}
public:
h2d(const h2d& a_from): parent(a_from){}
h2d& operator=(const h2d& a_from){
parent::operator=(a_from);
return *this;
}
private:static void check_instantiation() {h2d dummy("",10,0,1,10,0,1);}
};
}}
#endif
+54
View File
@@ -0,0 +1,54 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h2df
#define tools_histo_h2df
// coord is in double.
// weight is in float.
#include "h2"
namespace tools {
namespace histo {
class h2df : public h2<double,unsigned int,unsigned int,float,float> {
typedef h2<double,unsigned int,unsigned int,float,float> parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::h2df");
return s_v;
}
const std::string& s_cls() const {return s_class();}
public:
h2df():parent("",10,0,1,10,0,1){} //for I/O when reading.
h2df(const std::string& a_title,
unsigned int aXnumber,float aXmin,float aXmax,
unsigned int aYnumber,float aYmin,float aYmax)
:parent(a_title,aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax)
{}
h2df(const std::string& a_title,
const std::vector<double>& a_edges_x,
const std::vector<double>& a_edges_y)
:parent(a_title,a_edges_x,a_edges_y)
{}
virtual ~h2df(){}
public:
h2df(const h2df& a_from):parent(a_from){}
h2df& operator=(const h2df& a_from){
parent::operator=(a_from);
return *this;
}
private:static void check_instantiation() {h2df dummy("",10,0,1,10,0,1);}
};
}}
#endif
+281
View File
@@ -0,0 +1,281 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h3
#define tools_histo_h3
#include "b3"
namespace tools {
namespace histo {
template <class TC,class TO,class TN,class TW,class TH>
class h3 : public b3<TC,TO,TN,TW,TH> {
typedef b3<TC,TO,TN,TW,TH> parent;
public:
typedef histo_data<TC,TO,TN,TW> hd_t;
typedef typename parent::bn_t bn_t;
protected:
virtual TH get_bin_height(TO a_offset) const { //TH should be the same as TW
return parent::m_bin_Sw[a_offset];
}
public:
virtual TH bin_error(int aI,int aJ,int aK) const {
TO offset;
if(!parent::_find_offset(aI,aJ,aK,offset)) return 0;
return ::sqrt(parent::m_bin_Sw2[offset]);
}
public:
bool multiply(TW a_factor){return parent::base_multiply(a_factor);}
bool scale(TW a_factor) {return multiply(a_factor);}
void copy_from_data(const hd_t& a_from) {parent::base_from_data(a_from);}
hd_t get_histo_data() const {return *this;} //deprecated. Keep it for g4tools.
bool reset() {
parent::base_reset();
return true;
}
bool fill(TC aX,TC aY,TC aZ,TW aWeight = 1) {
if(parent::m_dimension!=3) return false;
bn_t ibin,jbin,kbin;
if(!parent::m_axes[0].coord_to_absolute_index(aX,ibin)) return false;
if(!parent::m_axes[1].coord_to_absolute_index(aY,jbin)) return false;
if(!parent::m_axes[2].coord_to_absolute_index(aZ,kbin)) return false;
TO offset = ibin + jbin * parent::m_axes[1].m_offset + kbin * parent::m_axes[2].m_offset;
parent::m_bin_entries[offset]++;
parent::m_bin_Sw[offset] += aWeight;
parent::m_bin_Sw2[offset] += aWeight * aWeight;
TC xw = aX * aWeight;
TC x2w = aX * xw;
parent::m_bin_Sxw[offset][0] += xw;
parent::m_bin_Sx2w[offset][0] += x2w;
TC yw = aY * aWeight;
TC y2w = aY * yw;
parent::m_bin_Sxw[offset][1] += yw;
parent::m_bin_Sx2w[offset][1] += y2w;
TC zw = aZ * aWeight;
TC z2w = aZ * zw;
parent::m_bin_Sxw[offset][2] += zw;
parent::m_bin_Sx2w[offset][2] += z2w;
bool inRange = true;
if(ibin==0) inRange = false;
else if(ibin==(parent::m_axes[0].m_number_of_bins+1)) inRange = false;
if(jbin==0) inRange = false;
else if(jbin==(parent::m_axes[1].m_number_of_bins+1)) inRange = false;
if(kbin==0) inRange = false;
else if(kbin==(parent::m_axes[2].m_number_of_bins+1)) inRange = false;
parent::m_all_entries++;
if(inRange) {
parent::m_in_range_plane_Sxyw[0] += aX * aY * aWeight;
parent::m_in_range_plane_Sxyw[1] += aY * aZ * aWeight;
parent::m_in_range_plane_Sxyw[2] += aZ * aX * aWeight;
// fast getters :
parent::m_in_range_entries++;
parent::m_in_range_Sw += aWeight;
parent::m_in_range_Sw2 += aWeight*aWeight;
parent::m_in_range_Sxw[0] += xw;
parent::m_in_range_Sx2w[0] += x2w;
parent::m_in_range_Sxw[1] += yw;
parent::m_in_range_Sx2w[1] += y2w;
parent::m_in_range_Sxw[2] += zw;
parent::m_in_range_Sx2w[2] += z2w;
}
return true;
}
bool set_bin_content(bn_t a_ibin,bn_t a_jbin,bn_t a_kbin,
TN a_entries,TW a_Sw,TW a_Sw2,
TC a_Sxw,TC a_Sx2w,TC a_Syw,TC a_Sy2w,TC a_Szw,TC a_Sz2w) {
if(parent::m_dimension!=3) return false;
if(a_ibin>(parent::m_axes[0].m_number_of_bins+1)) return false;
if(a_jbin>(parent::m_axes[1].m_number_of_bins+1)) return false;
if(a_kbin>(parent::m_axes[2].m_number_of_bins+1)) return false;
bool inRange = true;
if(a_ibin==0) inRange = false;
else if(a_ibin==(parent::m_axes[0].m_number_of_bins+1)) inRange = false;
if(a_jbin==0) inRange = false;
else if(a_jbin==(parent::m_axes[1].m_number_of_bins+1)) inRange = false;
if(a_kbin==0) inRange = false;
else if(a_kbin==(parent::m_axes[2].m_number_of_bins+1)) inRange = false;
TO offset = a_ibin + a_jbin * parent::m_axes[1].m_offset + a_kbin * parent::m_axes[2].m_offset;
parent::m_all_entries -= parent::m_bin_entries[offset];
if(inRange) {
parent::m_in_range_entries -= parent::m_bin_entries[offset];
parent::m_in_range_Sw -= parent::m_bin_Sw[offset];
parent::m_in_range_Sw2 -= parent::m_bin_Sw2[offset];
parent::m_in_range_Sxw[0] -= parent::m_bin_Sxw[offset][0];
parent::m_in_range_Sx2w[0] -= parent::m_bin_Sx2w[offset][0];
parent::m_in_range_Sxw[1] -= parent::m_bin_Sxw[offset][1];
parent::m_in_range_Sx2w[1] -= parent::m_bin_Sx2w[offset][1];
parent::m_in_range_Sxw[2] -= parent::m_bin_Sxw[offset][2];
parent::m_in_range_Sx2w[2] -= parent::m_bin_Sx2w[offset][2];
}
parent::m_bin_entries[offset] = a_entries;
parent::m_bin_Sw[offset] = a_Sw;
parent::m_bin_Sw2[offset] = a_Sw2;
parent::m_bin_Sxw[offset][0] = a_Sxw;
parent::m_bin_Sx2w[offset][0] = a_Sx2w;
parent::m_bin_Sxw[offset][1] = a_Syw;
parent::m_bin_Sx2w[offset][1] = a_Sy2w;
parent::m_bin_Sxw[offset][2] = a_Szw;
parent::m_bin_Sx2w[offset][2] = a_Sz2w;
parent::m_all_entries += a_entries;
if(inRange) {
//parent::m_in_range_plane_Sxyw[0,1,2] ??? ill-defined.
parent::m_in_range_entries += a_entries;
parent::m_in_range_Sw += a_Sw;
parent::m_in_range_Sw2 += a_Sw2;
parent::m_in_range_Sxw[0] += a_Sxw;
parent::m_in_range_Sx2w[0] += a_Sx2w;
parent::m_in_range_Sxw[1] += a_Syw;
parent::m_in_range_Sx2w[1] += a_Sy2w;
parent::m_in_range_Sxw[2] += a_Szw;
parent::m_in_range_Sx2w[2] += a_Sz2w;
}
return true;
}
bool get_bin_content(bn_t a_ibin,bn_t a_jbin,bn_t a_kbin,
TN& a_entries,TW& a_Sw,TW& a_Sw2,
TC& a_Sxw,TC& a_Sx2w,
TC& a_Syw,TC& a_Sy2w,
TC& a_Szw,TC& a_Sz2w) {
if(parent::m_dimension!=3) {
a_entries = 0;a_Sw = 0;a_Sw2 = 0;
a_Sxw = 0;a_Sx2w = 0;
a_Syw = 0;a_Sy2w = 0;
a_Szw = 0;a_Sz2w = 0;
return false;
}
if(a_ibin>(parent::m_axes[0].m_number_of_bins+1)) {
a_entries = 0;a_Sw = 0;a_Sw2 = 0;
a_Sxw = 0;a_Sx2w = 0;
a_Syw = 0;a_Sy2w = 0;
a_Szw = 0;a_Sz2w = 0;
return false;
}
if(a_jbin>(parent::m_axes[1].m_number_of_bins+1)) {
a_entries = 0;a_Sw = 0;a_Sw2 = 0;
a_Sxw = 0;a_Sx2w = 0;
a_Syw = 0;a_Sy2w = 0;
a_Szw = 0;a_Sz2w = 0;
return false;
}
if(a_kbin>(parent::m_axes[2].m_number_of_bins+1)) {
a_entries = 0;a_Sw = 0;a_Sw2 = 0;
a_Sxw = 0;a_Sx2w = 0;
a_Syw = 0;a_Sy2w = 0;
a_Szw = 0;a_Sz2w = 0;
return false;
}
TO offset = a_ibin + a_jbin * parent::m_axes[1].m_offset + a_kbin * parent::m_axes[2].m_offset;
a_entries = parent::m_bin_entries[offset];
a_Sw = parent::m_bin_Sw[offset];
a_Sw2 = parent::m_bin_Sw2[offset];
a_Sxw = parent::m_bin_Sxw[offset][0];
a_Sx2w = parent::m_bin_Sx2w[offset][0];
a_Syw = parent::m_bin_Sxw[offset][1];
a_Sy2w = parent::m_bin_Sx2w[offset][1];
a_Szw = parent::m_bin_Sxw[offset][2];
a_Sz2w = parent::m_bin_Sx2w[offset][2];
return true;
}
bool add(const h3& a_histo){
parent::base_add(a_histo);
return true;
}
bool subtract(const h3& a_histo){
parent::base_subtract(a_histo);
return true;
}
bool multiply(const h3& a_histo) {
return parent::base_multiply(a_histo);
}
bool divide(const h3& a_histo) {
return parent::base_divide(a_histo);
}
bool equals_TH(const h3& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
if(!parent::equals_TH(a_from,a_prec,a_fabs,true)) return false;
return true;
}
void not_a_profile() const {}
public: //CERN-ROOT API
bool Fill(TC aX,TC aY,TC aZ,TW aWeight = 1) {return fill(aX,aY,aZ,aWeight);}
public:
/*
// Slices :
h2d* slice_xy(int aKbeg,int aKend) const;
h2d* slice_yz(int aIbeg,int aIend) const;
h2d* slice_xz(int aJbeg,int aJend) const;
*/
public:
h3(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax,
bn_t aYnumber,TC aYmin,TC aYmax,
bn_t aZnumber,TC aZmin,TC aZmax)
:parent(a_title,aXnumber,aXmin,aXmax,
aYnumber,aYmin,aYmax,
aZnumber,aZmin,aZmax)
{}
h3(const std::string& a_title,
const std::vector<TC>& a_edges_x,
const std::vector<TC>& a_edges_y,
const std::vector<TC>& a_edges_z)
:parent(a_title,a_edges_x,a_edges_y,a_edges_z)
{}
virtual ~h3(){}
public:
h3(const h3& a_from): parent(a_from){}
h3& operator=(const h3& a_from){
parent::operator=(a_from);
return *this;
}
};
}}
#endif
+56
View File
@@ -0,0 +1,56 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h3d
#define tools_histo_h3d
#include "h3"
namespace tools {
namespace histo {
class h3d : public h3<double,unsigned int,unsigned int,double,double> {
typedef h3<double,unsigned int,unsigned int,double,double> parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::h3d");
return s_v;
}
const std::string& s_cls() const {return s_class();}
public:
h3d():parent("",10,0,1,10,0,1,10,0,1){} //for I/O when reading.
h3d(const std::string& a_title,
unsigned int aXnumber,double aXmin,double aXmax,
unsigned int aYnumber,double aYmin,double aYmax,
unsigned int aZnumber,double aZmin,double aZmax)
:parent(a_title,aXnumber,aXmin,aXmax,
aYnumber,aYmin,aYmax,
aZnumber,aZmin,aZmax)
{}
h3d(const std::string& a_title,
const std::vector<double>& a_edges_x,
const std::vector<double>& a_edges_y,
const std::vector<double>& a_edges_z)
:parent(a_title,a_edges_x,a_edges_y,a_edges_z)
{}
virtual ~h3d(){}
public:
h3d(const h3d& a_from): parent(a_from){}
h3d& operator=(const h3d& a_from){
parent::operator=(a_from);
return *this;
}
private:static void check_instantiation() {h3d dummy("",10,0,1,10,0,1,10,0,1);}
};
}}
#endif
+59
View File
@@ -0,0 +1,59 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h3df
#define tools_histo_h3df
// coord is in double.
// weight is in float.
#include "h3"
namespace tools {
namespace histo {
class h3df : public h3<double,unsigned int,unsigned int,float,float> {
typedef h3<double,unsigned int,unsigned int,float,float> parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::h3df");
return s_v;
}
const std::string& s_cls() const {return s_class();}
public:
h3df():parent("",10,0,1,10,0,1,10,0,1){} //for I/O when reading.
h3df(const std::string& a_title,
unsigned int aXnumber,float aXmin,float aXmax,
unsigned int aYnumber,float aYmin,float aYmax,
unsigned int aZnumber,float aZmin,float aZmax)
:parent(a_title,aXnumber,aXmin,aXmax,
aYnumber,aYmin,aYmax,
aZnumber,aZmin,aZmax)
{}
h3df(const std::string& a_title,
const std::vector<double>& a_edges_x,
const std::vector<double>& a_edges_y,
const std::vector<double>& a_edges_z)
:parent(a_title,a_edges_x,a_edges_y,a_edges_z)
{}
virtual ~h3df(){}
public:
h3df(const h3df& a_from):parent(a_from){}
h3df& operator=(const h3df& a_from){
parent::operator=(a_from);
return *this;
}
private:static void check_instantiation() {h3df dummy("",10,0,1,10,0,1,10,0,1);}
};
}}
#endif
+208
View File
@@ -0,0 +1,208 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_hd2mpi
#define tools_histo_hd2mpi
// code to MPI_Pack, MPI_Unpack histos without having to include mpi.h.
#include "../impi"
#include "histo_data"
#include "../forit"
namespace tools {
namespace histo {
/////////////////////////////////////////////////////////////////////////////
/// hist_data to mpi ////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
inline bool axis_dui_pack(impi& a_mpi,const axis<double,unsigned int>& a_axis) {
//typedef double TC;
//typedef unsigned int TO;
//typedef unsigned int bn_t;
if(!a_mpi.pack(a_axis.m_offset)) return false; //TO
if(!a_mpi.pack(a_axis.m_number_of_bins)) return false; //bn_t
if(!a_mpi.pack(a_axis.m_minimum_value)) return false; //TC
if(!a_mpi.pack(a_axis.m_maximum_value)) return false; //TC
if(!a_mpi.bpack(a_axis.m_fixed)) return false;
if(!a_mpi.pack(a_axis.m_bin_width)) return false; //TC
if(!a_mpi.vpack(a_axis.m_edges)) return false; //TC
return true;
}
inline bool histo_data_duiuid_pack(impi& a_mpi,const histo_data<double,unsigned int,unsigned int,double>& a_hd) {
//typedef double TC;
//typedef unsigned int TO;
//typedef unsigned int TN;
//typedef double TW;
//typedef unsigned int dim_t;
typedef unsigned int num_t;
if(!a_mpi.spack(a_hd.m_title)) return false;
if(!a_mpi.pack(a_hd.m_dimension)) return false; //dim_t
if(!a_mpi.pack(a_hd.m_bin_number)) return false; //TO
if(!a_mpi.vpack(a_hd.m_bin_entries)) return false; //TN
if(!a_mpi.vpack(a_hd.m_bin_Sw)) return false; //TW
if(!a_mpi.vpack(a_hd.m_bin_Sw2)) return false; //TW
{for(unsigned int ibin=0;ibin<a_hd.m_bin_number;ibin++) {
if(!a_mpi.vpack(a_hd.m_bin_Sxw[ibin])) return false;
}}
{for(unsigned int ibin=0;ibin<a_hd.m_bin_number;ibin++) {
if(!a_mpi.vpack(a_hd.m_bin_Sx2w[ibin])) return false;
}}
// Axes :
{for(unsigned int iaxis=0;iaxis<a_hd.m_dimension;iaxis++) {
if(!axis_dui_pack(a_mpi,a_hd.m_axes[iaxis])) return false;
}}
// etc :
if(!a_mpi.vpack(a_hd.m_in_range_plane_Sxyw)) return false; //TC
// Annotations :
{if(!a_mpi.pack((num_t)a_hd.m_annotations.size())) return false; //num_t
tools_mforcit(std::string,std::string,a_hd.m_annotations,it) {
if(!a_mpi.spack((*it).first)) return false;
if(!a_mpi.spack((*it).second)) return false;
}}
// fast getters :
if(!a_mpi.pack(a_hd.m_all_entries)) return false; //TN
if(!a_mpi.pack(a_hd.m_in_range_entries)) return false; //TN
if(!a_mpi.pack(a_hd.m_in_range_Sw)) return false; //TW
if(!a_mpi.pack(a_hd.m_in_range_Sw2)) return false; //TW
if(!a_mpi.vpack(a_hd.m_in_range_Sxw)) return false; //TC
if(!a_mpi.vpack(a_hd.m_in_range_Sx2w)) return false; //TC
return true;
}
/////////////////////////////////////////////////////////////////////////////
/// mpi to hist_data ////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
inline bool axis_dui_unpack(impi& a_mpi,axis<double,unsigned int>& a_axis) {
//typedef double TC;
//typedef unsigned int TO;
//typedef unsigned int bn_t;
if(!a_mpi.unpack(a_axis.m_offset)) return false; //TO
if(!a_mpi.unpack(a_axis.m_number_of_bins)) return false; //bn_t
if(!a_mpi.unpack(a_axis.m_minimum_value)) return false; //TC
if(!a_mpi.unpack(a_axis.m_maximum_value)) return false; //TC
if(!a_mpi.bunpack(a_axis.m_fixed)) return false;
if(!a_mpi.unpack(a_axis.m_bin_width)) return false; //TC
if(!a_mpi.vunpack(a_axis.m_edges)) return false; //TC
return true;
}
inline bool histo_data_duiuid_unpack(impi& a_mpi,histo_data<double,unsigned int,unsigned int,double>& a_hd) {
//typedef double TC;
//typedef unsigned int TO;
//typedef unsigned int TN;
//typedef double TW;
//typedef unsigned int dim_t;
typedef unsigned int num_t;
if(!a_mpi.sunpack(a_hd.m_title)) return false;
if(!a_mpi.unpack(a_hd.m_dimension)) return false; //dim_t
if(!a_mpi.unpack(a_hd.m_bin_number)) return false; //TO
if(!a_mpi.vunpack(a_hd.m_bin_entries)) return false; //TN
if(!a_mpi.vunpack(a_hd.m_bin_Sw)) return false; //TW
if(!a_mpi.vunpack(a_hd.m_bin_Sw2)) return false; //TW
{a_hd.m_bin_Sxw.resize(a_hd.m_bin_number);
for(unsigned int ibin=0;ibin<a_hd.m_bin_number;ibin++) {
if(!a_mpi.vunpack(a_hd.m_bin_Sxw[ibin])) return false;
}}
{a_hd.m_bin_Sx2w.resize(a_hd.m_bin_number);
for(unsigned int ibin=0;ibin<a_hd.m_bin_number;ibin++) {
if(!a_mpi.vunpack(a_hd.m_bin_Sx2w[ibin])) return false;
}}
// Axes :
{a_hd.m_axes.resize(a_hd.m_dimension);
for(unsigned int iaxis=0;iaxis<a_hd.m_dimension;iaxis++) {
if(!axis_dui_unpack(a_mpi,a_hd.m_axes[iaxis])) return false;
}}
// etc :
if(!a_mpi.vunpack(a_hd.m_in_range_plane_Sxyw)) return false; //TC
// Annotations :
{a_hd.m_annotations.clear();
num_t num;
if(!a_mpi.unpack(num)) return false;
for(unsigned int index=0;index<num;index++) {
std::string k,v;
if(!a_mpi.sunpack(k)) return false;
if(!a_mpi.sunpack(v)) return false;
a_hd.m_annotations[k] = v;
}}
// fast getters :
if(!a_mpi.unpack(a_hd.m_all_entries)) return false; //TN
if(!a_mpi.unpack(a_hd.m_in_range_entries)) return false; //TN
if(!a_mpi.unpack(a_hd.m_in_range_Sw)) return false; //TW
if(!a_mpi.unpack(a_hd.m_in_range_Sw2)) return false; //TW
if(!a_mpi.vunpack(a_hd.m_in_range_Sxw)) return false; //TC
if(!a_mpi.vunpack(a_hd.m_in_range_Sx2w)) return false; //TC
return true;
}
}}
#include "profile_data"
namespace tools {
namespace histo {
/////////////////////////////////////////////////////////////////////////////
/// profile_data to C struct ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
inline bool profile_data_duiuidd_pack(impi& a_mpi,const profile_data<double,unsigned int,unsigned int,double,double>& a_pd) {
if(!histo_data_duiuid_pack(a_mpi,a_pd)) return false;
//typedef double TV;
if(!a_mpi.bpack(a_pd.m_is_profile)) return false;
if(!a_mpi.vpack(a_pd.m_bin_Svw)) return false; //TV
if(!a_mpi.vpack(a_pd.m_bin_Sv2w)) return false; //TV
if(!a_mpi.bpack(a_pd.m_cut_v)) return false;
if(!a_mpi.pack(a_pd.m_min_v)) return false; //TV
if(!a_mpi.pack(a_pd.m_max_v)) return false; //TV
return true;
}
/////////////////////////////////////////////////////////////////////////////
/// mpi to profile_data /////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
inline bool profile_data_duiuidd_unpack(impi& a_mpi,profile_data<double,unsigned int,unsigned int,double,double>& a_pd) {
if(!histo_data_duiuid_unpack(a_mpi,a_pd)) return false;
//typedef double TV;
if(!a_mpi.bunpack(a_pd.m_is_profile)) return false;
if(!a_mpi.vunpack(a_pd.m_bin_Svw)) return false; //TV
if(!a_mpi.vunpack(a_pd.m_bin_Sv2w)) return false; //TV
if(!a_mpi.bunpack(a_pd.m_cut_v)) return false;
if(!a_mpi.unpack(a_pd.m_min_v)) return false; //TV
if(!a_mpi.unpack(a_pd.m_max_v)) return false; //TV
return true;
}
}}
#endif
+196
View File
@@ -0,0 +1,196 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_histo_data
#define tools_histo_histo_data
#include <vector>
#include <map> //for annotations
#include "axes"
#include "../eqT"
//#include "../vmanip" //vequ
namespace tools {
namespace histo {
inline unsigned int dim_planes(unsigned int a_dim) {
// m_dim = 1 -> 0
// m_dim = 2 -> 0+1=1
// m_dim = 3 -> 0+1+2=3
// m_dim = 4 -> 0+1+2+3=6
typedef unsigned int dim_t;
dim_t n = 0;
for(dim_t i=0;i<a_dim;i++) n += i;
return n;
}
//TC is for a coordinate.
//TO is for an offset used to identify a bin.
//TN is for a number of entries.
//TW is for a weight.
template <class TC,class TO,class TN,class TW>
class histo_data {
public:
typedef axis<TC,TO> axis_t;
typedef unsigned int dim_t;
typedef std::map<std::string,std::string> annotations_t;
public:
histo_data()
:m_dimension(0)
,m_bin_number(0)
,m_all_entries(0)
,m_in_range_entries(0)
,m_in_range_Sw(0)
,m_in_range_Sw2(0)
{}
public:
histo_data(const histo_data& a_from)
:m_title(a_from.m_title)
,m_dimension(a_from.m_dimension)
,m_bin_number(a_from.m_bin_number)
,m_bin_entries(a_from.m_bin_entries)
,m_bin_Sw(a_from.m_bin_Sw)
,m_bin_Sw2(a_from.m_bin_Sw2)
,m_bin_Sxw(a_from.m_bin_Sxw)
,m_bin_Sx2w(a_from.m_bin_Sx2w)
,m_axes(a_from.m_axes)
,m_in_range_plane_Sxyw(a_from.m_in_range_plane_Sxyw)
,m_annotations(a_from.m_annotations)
,m_all_entries(a_from.m_all_entries)
,m_in_range_entries(a_from.m_in_range_entries)
,m_in_range_Sw(a_from.m_in_range_Sw)
,m_in_range_Sw2(a_from.m_in_range_Sw2)
,m_in_range_Sxw(a_from.m_in_range_Sxw)
,m_in_range_Sx2w(a_from.m_in_range_Sx2w)
{}
histo_data& operator=(const histo_data& a_from) {
if(&a_from==this) return *this;
m_title = a_from.m_title;
m_dimension = a_from.m_dimension;
m_bin_number = a_from.m_bin_number;
m_bin_entries = a_from.m_bin_entries;
m_bin_Sw = a_from.m_bin_Sw;
m_bin_Sw2 = a_from.m_bin_Sw2;
m_bin_Sxw = a_from.m_bin_Sxw;
m_bin_Sx2w = a_from.m_bin_Sx2w;
m_axes = a_from.m_axes;
m_in_range_plane_Sxyw = a_from.m_in_range_plane_Sxyw;
m_annotations = a_from.m_annotations;
m_all_entries = a_from.m_all_entries;
m_in_range_entries = a_from.m_in_range_entries;
m_in_range_Sw = a_from.m_in_range_Sw;
m_in_range_Sw2 = a_from.m_in_range_Sw2;
m_in_range_Sxw = a_from.m_in_range_Sxw;
m_in_range_Sx2w = a_from.m_in_range_Sx2w;
return *this;
}
virtual ~histo_data(){}
protected:
void reset_fast_getters(){
//m_in_range_plane_Sxyw is not a fast getter.
m_all_entries = 0;
m_in_range_entries = 0;
m_in_range_Sw = 0;
m_in_range_Sw2 = 0;
m_in_range_Sxw.assign(m_dimension,0);
m_in_range_Sx2w.assign(m_dimension,0);
}
public:
void update_fast_getters() {
reset_fast_getters();
{for(TO ibin=0;ibin<m_bin_number;ibin++) {
if(!histo::is_out(m_axes,ibin)) {
m_in_range_entries += m_bin_entries[ibin];
m_in_range_Sw += m_bin_Sw[ibin];
m_in_range_Sw2 += m_bin_Sw2[ibin];
for(dim_t iaxis=0;iaxis<m_dimension;iaxis++) {
m_in_range_Sxw[iaxis] += m_bin_Sxw[ibin][iaxis];
m_in_range_Sx2w[iaxis] += m_bin_Sx2w[ibin][iaxis];
}
}
m_all_entries += m_bin_entries[ibin];
}}
}
bool equals(const histo_data& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
if(&a_from==this) return true;
if(m_title!=a_from.m_title) return false;
if(m_dimension!=a_from.m_dimension) return false;
if(m_bin_number!=a_from.m_bin_number) return false;
if(m_bin_entries!=a_from.m_bin_entries) return false;
//if(!vequ(m_bin_entries,a_from.m_bin_entries)) return false;
if(!vectors_are_equal(m_bin_Sw,a_from.m_bin_Sw,a_prec,a_fabs)) return false;
if(!vectors_are_equal(m_bin_Sw2,a_from.m_bin_Sw2,a_prec,a_fabs)) return false;
if(!vecvecs_are_equal(m_bin_Sxw,a_from.m_bin_Sxw,a_prec,a_fabs)) return false;
if(!vecvecs_are_equal(m_bin_Sx2w,a_from.m_bin_Sx2w,a_prec,a_fabs)) return false;
if(m_axes!=a_from.m_axes) return false;
if(!vectors_are_equal(m_in_range_plane_Sxyw,a_from.m_in_range_plane_Sxyw,a_prec,a_fabs)) return false;
if(m_annotations!=a_from.m_annotations) return false;
if(m_all_entries!=a_from.m_all_entries) return false;
if(m_in_range_entries!=a_from.m_in_range_entries) return false;
if(!numbers_are_equal(m_in_range_Sw,a_from.m_in_range_Sw,a_prec,a_fabs)) return false;
if(!numbers_are_equal(m_in_range_Sw2,a_from.m_in_range_Sw2,a_prec,a_fabs)) return false;
if(!vectors_are_equal(m_in_range_Sxw,a_from.m_in_range_Sxw,a_prec,a_fabs)) return false;
if(!vectors_are_equal(m_in_range_Sx2w,a_from.m_in_range_Sx2w,a_prec,a_fabs)) return false;
return true;
}
bool equals_TH(const histo_data& a_from,const TW& a_prec,TW(*a_fabs)(TW),bool a_cmp_bin_Sw2) const {
// used to compare with an histo built from a TH stream out from a CERN-ROOT file.
if(&a_from==this) return true;
if(m_title!=a_from.m_title) return false;
if(m_dimension!=a_from.m_dimension) return false;
if(m_bin_number!=a_from.m_bin_number) return false;
//if(m_bin_entries!=a_from.m_bin_entries) return false;
if(!vectors_are_equal(m_bin_Sw,a_from.m_bin_Sw,a_prec,a_fabs)) return false;
if(a_cmp_bin_Sw2) if(!vectors_are_equal(m_bin_Sw2,a_from.m_bin_Sw2,a_prec,a_fabs)) return false;
//if(!vecvecs_are_equal(m_bin_Sxw,a_from.m_bin_Sxw,a_prec,a_fabs)) return false;
//if(!vecvecs_are_equal(m_bin_Sx2w,a_from.m_bin_Sx2w,a_prec,a_fabs)) return false;
if(m_axes!=a_from.m_axes) return false;
if(!vectors_are_equal(m_in_range_plane_Sxyw,a_from.m_in_range_plane_Sxyw,a_prec,a_fabs)) return false;
//if(m_annotations!=a_from.m_annotations) return false;
if(m_all_entries!=a_from.m_all_entries) return false;
//if(m_in_range_entries!=a_from.m_in_range_entries) return false;
if(!numbers_are_equal(m_in_range_Sw,a_from.m_in_range_Sw,a_prec,a_fabs)) return false;
if(!numbers_are_equal(m_in_range_Sw2,a_from.m_in_range_Sw2,a_prec,a_fabs)) return false;
//if(!vectors_are_equal(m_in_range_Sxw,a_from.m_in_range_Sxw,a_prec,a_fabs)) return false;
//if(!vectors_are_equal(m_in_range_Sx2w,a_from.m_in_range_Sx2w,a_prec,a_fabs)) return false;
return true;
}
public:
// General :
std::string m_title;
dim_t m_dimension;
// Bins :
TO m_bin_number;
std::vector<TN> m_bin_entries;
std::vector<TW> m_bin_Sw;
std::vector<TW> m_bin_Sw2;
std::vector< std::vector<TC> > m_bin_Sxw;
std::vector< std::vector<TC> > m_bin_Sx2w;
// Axes :
std::vector<axis_t> m_axes;
// etc :
std::vector<TC> m_in_range_plane_Sxyw; // ill-defined relative to slicing, sub, div, mult operations. Handled because of CERN-ROOT.
std::map<std::string,std::string> m_annotations;
// fast getters :
TN m_all_entries; //used if reading from a ROOT file.
TN m_in_range_entries;
TW m_in_range_Sw;
TW m_in_range_Sw2;
std::vector<TC> m_in_range_Sxw;
std::vector<TC> m_in_range_Sx2w;
};
}}
#endif
+49
View File
@@ -0,0 +1,49 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_histos
#define tools_histo_histos
#include "h1d"
#include "h2d"
#include "h3d"
#include "p1d"
#include "p2d"
#include "../forit"
namespace tools {
namespace histo {
inline void delete_histos(std::vector< std::pair<std::string,void*> >& a_hists) {
typedef std::pair<std::string,void*> class_pointer;
tools_vforit(class_pointer,a_hists,it) {
const std::string& scls = (*it).first;
if(scls==h1d::s_class()) {
h1d* h = (h1d*)(*it).second;
delete h;
} else if(scls==h2d::s_class()) {
h2d* h = (h2d*)(*it).second;
delete h;
} else if(scls==h3d::s_class()) {
h3d* h = (h3d*)(*it).second;
delete h;
} else if(scls==p1d::s_class()) {
p1d* h = (p1d*)(*it).second;
delete h;
} else if(scls==p2d::s_class()) {
p2d* h = (p2d*)(*it).second;
delete h;
}
}
a_hists.clear();
}
}}
#endif
+44
View File
@@ -0,0 +1,44 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_hmpi
#define tools_histo_hmpi
namespace tools {
namespace histo {
class h1d;
class h2d;
class h3d;
class p1d;
class p2d;
}}
#include <string>
#include <vector>
namespace tools {
namespace histo {
class hmpi {
public:
virtual ~hmpi(){}
public:
virtual bool pack(const h1d&) = 0;
virtual bool pack(const h2d&) = 0;
virtual bool pack(const h3d&) = 0;
virtual bool pack(const p1d&) = 0;
virtual bool pack(const p2d&) = 0;
virtual bool beg_send(unsigned int /*a_nhist*/) = 0;
virtual bool send(int /*a_dest*/) = 0;
virtual bool wait_histos(int /*a_src*/,std::vector< std::pair<std::string,void*> >& /*a_hists*/) = 0;
virtual int rank() const = 0;
virtual bool comm_rank(int&) const = 0;
virtual bool comm_size(int&) const = 0;
};
}}
#endif
+338
View File
@@ -0,0 +1,338 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_htoc
#define tools_histo_htoc
struct caxis_dui { //d=double, ui=unsigned int
typedef double TC;
typedef unsigned int TO;
typedef unsigned int bn_t;
TO m_offset;
bn_t m_number_of_bins;
TC m_minimum_value;
TC m_maximum_value;
unsigned char m_fixed;
TC m_bin_width;
unsigned int m_number_of_edges;
TC* m_edges; //[m_number_of_edges]
};
struct chisto_duiuid {
typedef double TC;
typedef unsigned int TO;
typedef unsigned int TN;
typedef double TW;
typedef unsigned int dim_t;
// General :
char* m_title;
dim_t m_dimension;
// Bins :
TO m_bin_number;
TN* m_bin_entries; //[m_bin_number]
TW* m_bin_Sw; //[m_bin_number]
TW* m_bin_Sw2; //[m_bin_number]
TC** m_bin_Sxw; //[m_bin_number][m_dimension]
TC** m_bin_Sx2w; //[m_bin_number][m_dimension]
// Axes :
caxis_dui** m_axes; //[m_dimension]
// etc :
TC* m_in_range_plane_Sxyw; //(dim,size) (1,0) (2,1) (3,3)
unsigned int m_number_of_annotations;
char** m_annotations; //[m_number_of_annotations]
// fast getters :
TN m_all_entries; //used if reading from a ROOT file.
TN m_in_range_entries;
TW m_in_range_Sw;
TW m_in_range_Sw2;
TC* m_in_range_Sxw; //[m_dimension]
TC* m_in_range_Sx2w; //[m_dimension]
};
struct cprofile_duiuidd {
typedef double TV;
chisto_duiuid m_histo;
unsigned char m_is_profile;
TV* m_bin_Svw; //[m_bin_number]
TV* m_bin_Sv2w; //[m_bin_number]
unsigned char m_cut_v;
TV m_min_v;
TV m_max_v;
};
#include "histo_data"
#include "../cstr"
#include "../cmemT"
#include "../vdata"
#include "../forit"
namespace tools {
namespace histo {
/////////////////////////////////////////////////////////////////////////////
/// hist_data to C struct ///////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
inline caxis_dui* caxis_dui_alloc(const axis<double,unsigned int>& a_axis) {
caxis_dui* a_cp = cmem_alloc<caxis_dui>(1);
if(!a_cp) return NULL;
caxis_dui& a_c = *a_cp;
typedef double TC;
a_c.m_offset = a_axis.m_offset;
a_c.m_number_of_bins = a_axis.m_number_of_bins;
a_c.m_minimum_value = a_axis.m_minimum_value;
a_c.m_maximum_value = a_axis.m_maximum_value;
a_c.m_fixed = a_axis.m_fixed?1:0;
a_c.m_bin_width = a_axis.m_bin_width;
a_c.m_number_of_edges = (unsigned int)a_axis.m_edges.size();
a_c.m_edges = cmem_alloc_copy<TC>(vec_data(a_axis.m_edges),a_axis.m_edges.size());
return a_cp;
}
inline void caxis_dui_free(caxis_dui*& a_cp) {
if(!a_cp) return;
caxis_dui& a_c = *a_cp;
cmem_free(a_c.m_edges);
a_c.m_offset = 0;
a_c.m_number_of_bins = 0;
a_c.m_minimum_value = 0;
a_c.m_maximum_value = 0;
a_c.m_fixed = 1;
a_c.m_bin_width = 0;
a_c.m_number_of_edges = 0;
cmem_free(a_cp);
}
inline void chisto_duiuid_assign(chisto_duiuid& a_c,const histo_data<double,unsigned int,unsigned int,double>& a_hd) {
typedef double TC;
typedef unsigned int TN;
typedef double TW;
a_c.m_title = str_dup(a_hd.m_title.c_str());
a_c.m_dimension = a_hd.m_dimension;
a_c.m_bin_number = a_hd.m_bin_number;
a_c.m_bin_entries = cmem_alloc_copy<TN>(vec_data(a_hd.m_bin_entries),a_hd.m_bin_number);
a_c.m_bin_Sw = cmem_alloc_copy<TW>(vec_data(a_hd.m_bin_Sw),a_hd.m_bin_number);
a_c.m_bin_Sw2 = cmem_alloc_copy<TW>(vec_data(a_hd.m_bin_Sw2),a_hd.m_bin_number);
{a_c.m_bin_Sxw = cmem_alloc<TC*>(a_hd.m_bin_number);
for(unsigned int ibin=0;ibin<a_hd.m_bin_number;ibin++) {
a_c.m_bin_Sxw[ibin] = cmem_alloc_copy<TC>(vec_data(a_hd.m_bin_Sxw[ibin]),a_hd.m_dimension);
}}
{a_c.m_bin_Sx2w = cmem_alloc<TC*>(a_hd.m_bin_number);
for(unsigned int ibin=0;ibin<a_hd.m_bin_number;ibin++) {
a_c.m_bin_Sx2w[ibin] = cmem_alloc_copy<TC>(vec_data(a_hd.m_bin_Sx2w[ibin]),a_hd.m_dimension);
}}
// Axes :
{a_c.m_axes = cmem_alloc<caxis_dui*>(a_hd.m_dimension);
for(unsigned int iaxis=0;iaxis<a_hd.m_dimension;iaxis++) {
a_c.m_axes[iaxis] = caxis_dui_alloc(a_hd.m_axes[iaxis]);
}}
// etc :
a_c.m_in_range_plane_Sxyw = cmem_alloc_copy<TC>(vec_data(a_hd.m_in_range_plane_Sxyw),dim_planes(a_hd.m_dimension));
{a_c.m_number_of_annotations = (unsigned int)a_hd.m_annotations.size();
a_c.m_annotations = cmem_alloc<char*>(2*a_hd.m_annotations.size());
unsigned int index = 0;
tools_mforcit(std::string,std::string,a_hd.m_annotations,it) {
a_c.m_annotations[index] = str_dup((*it).first.c_str());index++;
a_c.m_annotations[index] = str_dup((*it).second.c_str());index++;
}}
// fast getters :
a_c.m_all_entries = a_hd.m_all_entries;
a_c.m_in_range_entries = a_hd.m_in_range_entries;
a_c.m_in_range_Sw = a_hd.m_in_range_Sw;
a_c.m_in_range_Sw2 = a_hd.m_in_range_Sw2;
a_c.m_in_range_Sxw = cmem_alloc_copy<TC>(vec_data(a_hd.m_in_range_Sxw),a_hd.m_dimension);
a_c.m_in_range_Sx2w = cmem_alloc_copy<TC>(vec_data(a_hd.m_in_range_Sx2w),a_hd.m_dimension);
//FIXME : should check all sub pointers.
//if(to_del {cmem_free(a_cp);return NULL;}
}
inline chisto_duiuid* chisto_duiuid_alloc(const histo_data<double,unsigned int,unsigned int,double>& a_hd) {
chisto_duiuid* a_cp = cmem_alloc<chisto_duiuid>(1);
if(!a_cp) return NULL;
chisto_duiuid_assign(*a_cp,a_hd);
return a_cp;
}
inline void chisto_duiuid_clear(chisto_duiuid& a_c) {
str_del(a_c.m_title);
cmem_free(a_c.m_bin_entries);
cmem_free(a_c.m_bin_Sw);
cmem_free(a_c.m_bin_Sw2);
{for(unsigned int ibin=0;ibin<a_c.m_bin_number;ibin++) cmem_free(a_c.m_bin_Sxw[ibin]);
cmem_free(a_c.m_bin_Sxw);}
{for(unsigned int ibin=0;ibin<a_c.m_bin_number;ibin++) cmem_free(a_c.m_bin_Sx2w[ibin]);
cmem_free(a_c.m_bin_Sx2w);}
cmem_free(a_c.m_in_range_plane_Sxyw);
{for(unsigned int iaxis=0;iaxis<a_c.m_dimension;iaxis++) caxis_dui_free(a_c.m_axes[iaxis]);
cmem_free(a_c.m_axes);}
{for(unsigned int i=0;i<(2*a_c.m_number_of_annotations);i++) str_del(a_c.m_annotations[i]);
cmem_free(a_c.m_annotations);}
cmem_free(a_c.m_in_range_Sxw);
cmem_free(a_c.m_in_range_Sx2w);
a_c.m_dimension = 0;
a_c.m_bin_number = 0;
a_c.m_number_of_annotations = 0;
a_c.m_all_entries = 0;
a_c.m_in_range_entries = 0;
a_c.m_in_range_Sw = 0;
a_c.m_in_range_Sw2 = 0;
}
inline void chisto_duiuid_free(chisto_duiuid*& a_cp) {
if(!a_cp) return;
chisto_duiuid_clear(*a_cp);
cmem_free(a_cp);
}
/////////////////////////////////////////////////////////////////////////////
/// C struct to hist_data ///////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
template <class T>
inline void vec_assign(std::vector<T>& a_v,unsigned int a_number,const T* a_c) {
a_v.resize(a_number);
for(unsigned int i=0;i<a_number;i++) a_v[i] = a_c[i];
}
inline void axis_dui_assign(axis<double,unsigned int>& a_axis,const caxis_dui& a_c) {
a_axis.m_offset = a_c.m_offset;
a_axis.m_number_of_bins = a_c.m_number_of_bins;
a_axis.m_minimum_value = a_c.m_minimum_value;
a_axis.m_maximum_value = a_c.m_maximum_value;
a_axis.m_fixed = a_c.m_fixed==1?true:false;
a_axis.m_bin_width = a_c.m_bin_width;
vec_assign(a_axis.m_edges,a_c.m_number_of_edges,a_c.m_edges);
}
inline void histo_data_duiuid_assign(histo_data<double,unsigned int,unsigned int,double>& a_hd,const chisto_duiuid& a_c) {
a_hd.m_title = std::string(a_c.m_title);
a_hd.m_dimension = a_c.m_dimension;
a_hd.m_bin_number = a_c.m_bin_number;
vec_assign(a_hd.m_bin_entries,a_c.m_bin_number,a_c.m_bin_entries);
vec_assign(a_hd.m_bin_Sw,a_c.m_bin_number,a_c.m_bin_Sw);
vec_assign(a_hd.m_bin_Sw2,a_c.m_bin_number,a_c.m_bin_Sw2);
{a_hd.m_bin_Sxw.resize(a_c.m_bin_number);
for(unsigned int ibin=0;ibin<a_c.m_bin_number;ibin++) {
vec_assign(a_hd.m_bin_Sxw[ibin],a_c.m_dimension,a_c.m_bin_Sxw[ibin]);
}}
{a_hd.m_bin_Sx2w.resize(a_c.m_bin_number);
for(unsigned int ibin=0;ibin<a_c.m_bin_number;ibin++) {
vec_assign(a_hd.m_bin_Sx2w[ibin],a_c.m_dimension,a_c.m_bin_Sx2w[ibin]);
}}
{a_hd.m_axes.resize(a_c.m_dimension);
for(unsigned int iaxis=0;iaxis<a_c.m_dimension;iaxis++) {
axis_dui_assign(a_hd.m_axes[iaxis],*(a_c.m_axes[iaxis]));
}}
vec_assign(a_hd.m_in_range_plane_Sxyw,dim_planes(a_c.m_dimension),a_c.m_in_range_plane_Sxyw);
{a_hd.m_annotations.clear();
for(unsigned int i=0;i<a_c.m_number_of_annotations;i++) {
a_hd.m_annotations[a_c.m_annotations[2*i+0]] = a_c.m_annotations[2*i+1];
}}
a_hd.m_all_entries = a_c.m_all_entries;
a_hd.m_in_range_entries = a_c.m_in_range_entries;
a_hd.m_in_range_Sw = a_c.m_in_range_Sw;
a_hd.m_in_range_Sw2 = a_c.m_in_range_Sw2;
vec_assign(a_hd.m_in_range_Sxw,a_c.m_dimension,a_c.m_in_range_Sxw);
vec_assign(a_hd.m_in_range_Sx2w,a_c.m_dimension,a_c.m_in_range_Sx2w);
}
}}
#include "profile_data"
namespace tools {
namespace histo {
/////////////////////////////////////////////////////////////////////////////
/// profile_data to C struct ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
inline cprofile_duiuidd* cprofile_duiuidd_alloc(const profile_data<double,unsigned int,unsigned int,double,double>& a_pd) {
cprofile_duiuidd* a_cp = cmem_alloc<cprofile_duiuidd>(1);
if(!a_cp) return NULL;
cprofile_duiuidd& a_c = *a_cp;
chisto_duiuid_assign(a_c.m_histo,a_pd);
typedef double TV;
// profile part :
a_c.m_is_profile = a_pd.m_is_profile?1:0;
a_c.m_bin_Svw = cmem_alloc_copy<TV>(vec_data(a_pd.m_bin_Svw),a_pd.m_bin_number);
a_c.m_bin_Sv2w = cmem_alloc_copy<TV>(vec_data(a_pd.m_bin_Sv2w),a_pd.m_bin_number);
a_c.m_cut_v = a_pd.m_cut_v?1:0;
a_c.m_min_v = a_pd.m_min_v;
a_c.m_max_v = a_pd.m_max_v;
return a_cp;
}
inline void cprofile_duiuidd_free(cprofile_duiuidd*& a_cp) {
if(!a_cp) return;
cprofile_duiuidd& a_c = *a_cp;
chisto_duiuid_clear(a_c.m_histo);
cmem_free(a_c.m_bin_Svw);
cmem_free(a_c.m_bin_Sv2w);
a_c.m_is_profile = 1;
a_c.m_cut_v = 0;
a_c.m_min_v = 0;
a_c.m_max_v = 0;
cmem_free(a_cp);
}
/////////////////////////////////////////////////////////////////////////////
/// C struct to profile_data ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
inline void profile_data_duiuidd_assign(profile_data<double,unsigned int,unsigned int,double,double>& a_pd,const cprofile_duiuidd& a_c) {
histo_data_duiuid_assign(a_pd,a_c.m_histo);
a_pd.m_is_profile = a_c.m_is_profile==1?true:false;
vec_assign(a_pd.m_bin_Svw,a_c.m_histo.m_bin_number,a_c.m_bin_Svw);
vec_assign(a_pd.m_bin_Sv2w,a_c.m_histo.m_bin_number,a_c.m_bin_Sv2w);
a_pd.m_cut_v = a_c.m_cut_v==1?true:false;
a_pd.m_min_v = a_c.m_min_v;
a_pd.m_max_v = a_c.m_max_v;
}
}}
#endif
+486
View File
@@ -0,0 +1,486 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_p1
#define tools_histo_p1
#include "b1"
#include "profile_data"
namespace tools {
namespace histo {
//TC is for a coordinate.
//TO is for an offset/index to identify/find a bind.
//TN is for a number of entries.
//TW is for a weight.
//TH is for a height. Should be the same as TV.
//TV is for a value (in general same as TC).
template <class TC,class TO,class TN,class TW,class TH,class TV>
class p1 : public b1<TC,TO,TN,TW,TH> {
typedef b1<TC,TO,TN,TW,TH> parent;
public:
typedef profile_data<TC,TO,TN,TW,TV> pd_t;
typedef typename parent::bn_t bn_t;
typedef typename parent::axis_t axis_t;
typedef std::vector<TV> vs_t;
protected:
virtual TH get_bin_height(TO a_offset) const {
return (parent::m_bin_Sw[a_offset] ? (m_bin_Svw[a_offset]/parent::m_bin_Sw[a_offset]):0);
}
public:
bool equals(const p1& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
if(!parent::equals(a_from,a_prec,a_fabs)) return false;
if(m_cut_v!=a_from.m_cut_v) return false;
if(!numbers_are_equal(m_min_v,a_from.m_min_v,a_prec,a_fabs)) return false;
if(!numbers_are_equal(m_max_v,a_from.m_max_v,a_prec,a_fabs)) return false;
if(!vectors_are_equal(m_bin_Svw,a_from.m_bin_Svw,a_prec,a_fabs)) return false;
if(!vectors_are_equal(m_bin_Sv2w,a_from.m_bin_Sv2w,a_prec,a_fabs)) return false;
return true;
}
bool equals_TH(const p1& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
if(!parent::equals_TH(a_from,a_prec,a_fabs,false)) return false;
if(m_cut_v!=a_from.m_cut_v) return false;
if(!numbers_are_equal(m_min_v,a_from.m_min_v,a_prec,a_fabs)) return false;
if(!numbers_are_equal(m_max_v,a_from.m_max_v,a_prec,a_fabs)) return false;
if(!vectors_are_equal(m_bin_Svw,a_from.m_bin_Svw,a_prec,a_fabs)) return false;
if(!vectors_are_equal(m_bin_Sv2w,a_from.m_bin_Sv2w,a_prec,a_fabs)) return false;
return true;
}
virtual TH bin_error(int aI) const { //TH should be the same as TV
TO offset;
if(!parent::_find_offset(aI,offset)) return 0;
//FIXME Is it correct ?
// TProfile::GetBinError with kERRORMEAN mode does :
// Stat_t cont = fArray[bin]; //Svw (see TProfile::Fill)
// Stat_t sum = parent::m_bin_entries.fArray[bin]; //Sw
// Stat_t err2 = fSumw2.fArray[bin]; //Sv2w
// if (sum == 0) return 0;
// Stat_t eprim;
// Stat_t contsum = cont/sum;
// Stat_t eprim2 = TMath::Abs(err2/sum - contsum*contsum);
// eprim = TMath::Sqrt(eprim2);
// ... ???
// if (fErrorMode == kERRORMEAN) return eprim/TMath::Sqrt(sum);
TW sw = parent::m_bin_Sw[offset]; //ROOT sum
if(sw==0) return 0;
TV svw = m_bin_Svw[offset]; //ROOT cont
TV sv2w = m_bin_Sv2w[offset]; //ROOT err2
TV _mean = (svw / sw); //ROOT contsum
TV _rms = ::sqrt(::fabs((sv2w/sw) - _mean * _mean)); //ROOT eprim
// rms = get_bin_rms_value.
return _rms/::sqrt(sw); //ROOT kERRORMEAN mode returned value
}
public:
bool multiply(TW a_factor){
if(!parent::base_multiply(a_factor)) return false;
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] *= a_factor;
}
return true;
}
bool scale(TW a_factor) {return multiply(a_factor);}
TV bin_Svw(int aI) const {
TO offset;
if(!parent::_find_offset(aI,offset)) return 0;
return m_bin_Svw[offset];
}
TV bin_Sv2w(int aI) const {
TO offset;
if(!parent::_find_offset(aI,offset)) return 0;
return m_bin_Sv2w[offset];
}
bool reset() {
parent::base_reset();
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] = 0;
m_bin_Sv2w[ibin] = 0;
}
return true;
}
void copy_from_data(const pd_t& a_from) {
parent::base_from_data(a_from);
m_bin_Svw = a_from.m_bin_Svw;
m_bin_Sv2w = a_from.m_bin_Sv2w;
m_cut_v = a_from.m_cut_v;
m_min_v = a_from.m_min_v;
m_max_v = a_from.m_max_v;
}
pd_t get_histo_data() const {
pd_t hd(parent::dac());
hd.m_is_profile = true;
hd.m_bin_Svw = m_bin_Svw;
hd.m_bin_Sv2w = m_bin_Sv2w;
hd.m_cut_v = m_cut_v;
hd.m_min_v = m_min_v;
hd.m_max_v = m_max_v;
return hd;
}
bool fill(TC aX,TV aV,TW aWeight = 1) {
if(parent::m_dimension!=1) return false;
if(m_cut_v) {
if( (aV<m_min_v) || (aV>=m_max_v) ) {
return true;
}
}
bn_t ibin;
if(!parent::m_axes[0].coord_to_absolute_index(aX,ibin)) return false;
TO offset = ibin;
parent::m_bin_entries[offset]++;
parent::m_bin_Sw[offset] += aWeight;
parent::m_bin_Sw2[offset] += aWeight * aWeight;
TC xw = aX * aWeight;
TC x2w = aX * xw;
parent::m_bin_Sxw[offset][0] += xw;
parent::m_bin_Sx2w[offset][0] += x2w;
bool inRange = true;
if(ibin==0) inRange = false;
else if(ibin==(parent::m_axes[0].m_number_of_bins+1)) inRange = false;
parent::m_all_entries++;
if(inRange) {
// fast getters :
parent::m_in_range_entries++;
parent::m_in_range_Sw += aWeight;
parent::m_in_range_Sw2 += aWeight*aWeight;
parent::m_in_range_Sxw[0] += xw;
parent::m_in_range_Sx2w[0] += x2w;
}
// Profile part :
TV vw = aV * aWeight;
m_bin_Svw[offset] += vw;
m_bin_Sv2w[offset] += aV * vw;
return true;
}
bool set_bin_content(bn_t a_ibin,TN a_entries,TW a_Sw,TW a_Sw2,TC a_Sxw,TC a_Sx2w,TC a_Svw,TC a_Sv2w) {
if(parent::m_dimension!=1) return false;
if(a_ibin>(parent::m_axes[0].m_number_of_bins+1)) return false;
bool inRange = true;
if(a_ibin==0) inRange = false;
else if(a_ibin==(parent::m_axes[0].m_number_of_bins+1)) inRange = false;
TO offset = a_ibin;
parent::m_all_entries -= parent::m_bin_entries[offset];
if(inRange) {
parent::m_in_range_entries -= parent::m_bin_entries[offset];
parent::m_in_range_Sw -= parent::m_bin_Sw[offset];
parent::m_in_range_Sw2 -= parent::m_bin_Sw2[offset];
parent::m_in_range_Sxw[0] -= parent::m_bin_Sxw[offset][0];
parent::m_in_range_Sx2w[0] -= parent::m_bin_Sx2w[offset][0];
}
parent::m_bin_entries[offset] = a_entries;
parent::m_bin_Sw[offset] = a_Sw;
parent::m_bin_Sw2[offset] = a_Sw2;
parent::m_bin_Sxw[offset][0] = a_Sxw;
parent::m_bin_Sx2w[offset][0] = a_Sx2w;
parent::m_all_entries += a_entries;
if(inRange) {
parent::m_in_range_entries += a_entries;
parent::m_in_range_Sw += a_Sw;
parent::m_in_range_Sw2 += a_Sw2;
parent::m_in_range_Sxw[0] += a_Sxw;
parent::m_in_range_Sx2w[0] += a_Sx2w;
}
// Profile part :
m_bin_Svw[offset] = a_Svw;
m_bin_Sv2w[offset] = a_Sv2w;
return true;
}
bool get_bin_content(bn_t a_ibin,TN& a_entries,TW& a_Sw,TW& a_Sw2,TC& a_Sxw,TC& a_Sx2w,TC& a_Svw,TC& a_Sv2w) {
if(parent::m_dimension!=1) {
a_entries = 0;a_Sw = 0;a_Sw2 = 0;a_Sxw = 0;a_Sx2w = 0;
return false;
}
if(a_ibin>(parent::m_axes[0].m_number_of_bins+1)) {
a_entries = 0;a_Sw = 0;a_Sw2 = 0;a_Sxw = 0;a_Sx2w = 0;
return false;
}
TO offset = a_ibin;
a_entries = parent::m_bin_entries[offset];
a_Sw = parent::m_bin_Sw[offset];
a_Sw2 = parent::m_bin_Sw2[offset];
a_Sxw = parent::m_bin_Sxw[offset][0];
a_Sx2w = parent::m_bin_Sx2w[offset][0];
// Profile part :
a_Svw = m_bin_Svw[offset];
a_Sv2w = m_bin_Sv2w[offset];
return true;
}
TV bin_rms_value(int aI) const {
TO offset;
if(!parent::_find_offset(aI,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TV svw = m_bin_Svw[offset];
TV sv2w = m_bin_Sv2w[offset];
TV _mean = (svw / sw);
return ::sqrt(::fabs((sv2w / sw) - _mean * _mean));
}
bool add(const p1& a_histo){
parent::base_add(a_histo);
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] += a_histo.m_bin_Svw[ibin];
m_bin_Sv2w[ibin] += a_histo.m_bin_Sv2w[ibin];
}
return true;
}
bool subtract(const p1& a_histo){
parent::base_subtract(a_histo);
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] -= a_histo.m_bin_Svw[ibin];
m_bin_Sv2w[ibin] -= a_histo.m_bin_Sv2w[ibin];
}
return true;
}
bool gather_bins(unsigned int a_factor) { //for exa 2,3.
if(!a_factor) return false;
// actual bin number must be a multiple of a_factor.
const axis_t& _axis = parent::axis();
bn_t n = _axis.bins();
if(!n) return false;
bn_t new_n = n/a_factor;
if(a_factor*new_n!=n) return false;
p1* new_h = 0;
if(_axis.is_fixed_binning()) {
new_h = new p1(parent::m_title,new_n,_axis.lower_edge(),_axis.upper_edge());
} else {
const std::vector<TC>& _edges = _axis.edges();
std::vector<TC> new_edges(new_n+1);
for(bn_t ibin=0;ibin<new_n;ibin++) {
new_edges[ibin] = _edges[ibin*a_factor];
}
new_edges[new_n] = _edges[n]; //upper edge.
new_h = new p1(parent::m_title,new_edges);
}
if(!new_h) return false;
new_h->m_cut_v = m_cut_v;
new_h->m_min_v = m_min_v;
new_h->m_max_v = m_max_v;
bn_t offset,new_offset,offac;
for(bn_t ibin=0;ibin<new_n;ibin++) {
new_offset = ibin+1;
offset = a_factor*ibin+1;
for(unsigned int ifac=0;ifac<a_factor;ifac++) {
offac = offset+ifac;
new_h->m_bin_entries[new_offset] += parent::m_bin_entries[offac];
new_h->m_bin_Sw[new_offset] += parent::m_bin_Sw[offac];
new_h->m_bin_Sw2[new_offset] += parent::m_bin_Sw2[offac];
new_h->m_bin_Sxw[new_offset][0] += parent::m_bin_Sxw[offac][0];
new_h->m_bin_Sx2w[new_offset][0] += parent::m_bin_Sx2w[offac][0];
new_h->m_bin_Svw[new_offset] += m_bin_Svw[offac];
new_h->m_bin_Sv2w[new_offset] += m_bin_Sv2w[offac];
}
}
//underflow :
new_offset = 0;
offac = 0;
new_h->m_bin_entries[new_offset] = parent::m_bin_entries[offac];
new_h->m_bin_Sw[new_offset] = parent::m_bin_Sw[offac];
new_h->m_bin_Sw2[new_offset] = parent::m_bin_Sw2[offac];
new_h->m_bin_Sxw[new_offset][0] = parent::m_bin_Sxw[offac][0];
new_h->m_bin_Sx2w[new_offset][0] = parent::m_bin_Sx2w[offac][0];
new_h->m_bin_Svw[new_offset] = m_bin_Svw[offac];
new_h->m_bin_Sv2w[new_offset] = m_bin_Sv2w[offac];
//overflow :
new_offset = new_n+1;
offac = n+1;
new_h->m_bin_entries[new_offset] = parent::m_bin_entries[offac];
new_h->m_bin_Sw[new_offset] = parent::m_bin_Sw[offac];
new_h->m_bin_Sw2[new_offset] = parent::m_bin_Sw2[offac];
new_h->m_bin_Sxw[new_offset][0] = parent::m_bin_Sxw[offac][0];
new_h->m_bin_Sx2w[new_offset][0] = parent::m_bin_Sx2w[offac][0];
new_h->m_bin_Svw[new_offset] = m_bin_Svw[offac];
new_h->m_bin_Sv2w[new_offset] = m_bin_Sv2w[offac];
*this = *new_h;
return true;
}
bool cut_v() const {return m_cut_v;}
TV min_v() const {return m_min_v;}
TV max_v() const {return m_max_v;}
public:
p1(const std::string& a_title,bn_t aXnumber,TC aXmin,TC aXmax)
:parent(a_title,aXnumber,aXmin,aXmax)
,m_cut_v(false)
,m_min_v(0)
,m_max_v(0)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
p1(const std::string& a_title,bn_t aXnumber,TC aXmin,TC aXmax,TV aVmin,TV aVmax)
:parent(a_title,aXnumber,aXmin,aXmax)
,m_cut_v(true)
,m_min_v(aVmin)
,m_max_v(aVmax)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
p1(const std::string& a_title,const std::vector<TC>& a_edges)
:parent(a_title,a_edges)
,m_cut_v(false)
,m_min_v(0)
,m_max_v(0)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
p1(const std::string& a_title,const std::vector<TC>& a_edges,TV aVmin,TV aVmax)
:parent(a_title,a_edges)
,m_cut_v(true)
,m_min_v(aVmin)
,m_max_v(aVmax)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
virtual ~p1(){}
public:
p1(const p1& a_from)
:parent(a_from)
,m_cut_v(a_from.m_cut_v)
,m_min_v(a_from.m_min_v)
,m_max_v(a_from.m_max_v)
,m_bin_Svw(a_from.m_bin_Svw)
,m_bin_Sv2w(a_from.m_bin_Sv2w)
{}
p1& operator=(const p1& a_from){
parent::operator=(a_from);
m_cut_v = a_from.m_cut_v;
m_min_v = a_from.m_min_v;
m_max_v = a_from.m_max_v;
m_bin_Svw = a_from.m_bin_Svw;
m_bin_Sv2w = a_from.m_bin_Sv2w;
return *this;
}
public:
bool configure(bn_t aXnumber,TC aXmin,TC aXmax){
if(!parent::configure(aXnumber,aXmin,aXmax)) return false;
m_bin_Svw.clear();
m_bin_Sv2w.clear();
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
m_cut_v = false;
m_min_v = 0;
m_max_v = 0;
return true;
}
bool configure(const std::vector<TC>& a_edges) {
if(!parent::configure(a_edges)) return false;
m_bin_Svw.clear();
m_bin_Sv2w.clear();
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
m_cut_v = false;
m_min_v = 0;
m_max_v = 0;
return true;
}
bool configure(bn_t aXnumber,TC aXmin,TC aXmax,TV aVmin,TV aVmax){
if(!parent::configure(aXnumber,aXmin,aXmax)) return false;
m_bin_Svw.clear();
m_bin_Sv2w.clear();
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
m_cut_v = true;
m_min_v = aVmin;
m_max_v = aVmax;
return true;
}
bool configure(const std::vector<TC>& a_edges,TV aVmin,TV aVmax) {
if(!parent::configure(a_edges)) return false;
m_bin_Svw.clear();
m_bin_Sv2w.clear();
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
m_cut_v = true;
m_min_v = aVmin;
m_max_v = aVmax;
return true;
}
public:
const vs_t& bins_sum_vw() const {return m_bin_Svw;}
const vs_t& bins_sum_v2w() const {return m_bin_Sv2w;}
TW get_Svw() const {
TW sw = 0;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin)) {
sw += m_bin_Svw[ibin];
}
}
return sw;
}
TW get_Sv2w() const {
TW sw = 0;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin)) {
sw += m_bin_Sv2w[ibin];
}
}
return sw;
}
protected:
bool m_cut_v;
TV m_min_v;
TV m_max_v;
vs_t m_bin_Svw;
vs_t m_bin_Sv2w;
};
}}
#endif
+56
View File
@@ -0,0 +1,56 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_p1d
#define tools_histo_p1d
#include "p1"
namespace tools {
namespace histo {
class p1d : public p1<double,unsigned int,unsigned int,double,double,double> {
typedef p1<double,unsigned int,unsigned int,double,double,double> parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::p1d");
return s_v;
}
const std::string& s_cls() const {return s_class();}
public:
p1d():parent("",10,0,1){} //for I/O when reading.
p1d(const std::string& a_title,unsigned int aXnumber,double aXmin,double aXmax)
:parent(a_title,aXnumber,aXmin,aXmax)
{}
p1d(const std::string& a_title,unsigned int aXnumber,double aXmin,double aXmax,double aVmin,double aVmax)
:parent(a_title,aXnumber,aXmin,aXmax,aVmin,aVmax)
{}
p1d(const std::string& a_title,const std::vector<double>& a_edges)
:parent(a_title,a_edges)
{}
p1d(const std::string& a_title,const std::vector<double>& a_edges,double aVmin,double aVmax)
:parent(a_title,a_edges,aVmin,aVmax)
{}
virtual ~p1d(){}
public:
p1d(const p1d& a_from): parent(a_from){}
p1d& operator=(const p1d& a_from){
parent::operator=(a_from);
return *this;
}
private:static void check_instantiation() {p1d p("",10,0,1);p.gather_bins(5);}
};
}}
#endif
+359
View File
@@ -0,0 +1,359 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_p2
#define tools_histo_p2
#include "b2"
#include "profile_data"
namespace tools {
namespace histo {
template <class TC,class TO,class TN,class TW,class TH,class TV>
class p2 : public b2<TC,TO,TN,TW,TH> {
typedef b2<TC,TO,TN,TW,TH> parent;
public:
typedef profile_data<TC,TO,TN,TW,TV> pd_t;
typedef typename parent::bn_t bn_t;
typedef std::vector<TV> vs_t;
protected:
virtual TH get_bin_height(TO a_offset) const {
return (parent::m_bin_Sw[a_offset] ? (m_bin_Svw[a_offset]/parent::m_bin_Sw[a_offset]):0);
}
public:
bool equals(const p2& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
if(!parent::equals(a_from,a_prec,a_fabs)) return false;
if(m_cut_v!=a_from.m_cut_v) return false;
if(!numbers_are_equal(m_min_v,a_from.m_min_v,a_prec,a_fabs)) return false;
if(!numbers_are_equal(m_max_v,a_from.m_max_v,a_prec,a_fabs)) return false;
if(!vectors_are_equal(m_bin_Svw,a_from.m_bin_Svw,a_prec,a_fabs)) return false;
if(!vectors_are_equal(m_bin_Sv2w,a_from.m_bin_Sv2w,a_prec,a_fabs)) return false;
return true;
}
bool equals_TH(const p2& a_from,const TW& a_prec,TW(*a_fabs)(TW)) const {
if(!parent::equals_TH(a_from,a_prec,a_fabs,false)) return false;
if(m_cut_v!=a_from.m_cut_v) return false;
if(!numbers_are_equal(m_min_v,a_from.m_min_v,a_prec,a_fabs)) return false;
if(!numbers_are_equal(m_max_v,a_from.m_max_v,a_prec,a_fabs)) return false;
if(!vectors_are_equal(m_bin_Svw,a_from.m_bin_Svw,a_prec,a_fabs)) return false;
if(!vectors_are_equal(m_bin_Sv2w,a_from.m_bin_Sv2w,a_prec,a_fabs)) return false;
return true;
}
virtual TH bin_error(int aI,int aJ) const { //TH should be the same as TV
TO offset;
if(!parent::_find_offset(aI,aJ,offset)) return 0;
//FIXME Is it correct ?
// TProfile::GetBinError with kERRORMEAN mode does :
// Stat_t cont = fArray[bin]; //Svw (see TProfile::Fill)
// Stat_t sum = parent::m_bin_entries.fArray[bin]; //Sw
// Stat_t err2 = fSumw2.fArray[bin]; //Sv2w
// if (sum == 0) return 0;
// Stat_t eprim;
// Stat_t contsum = cont/sum;
// Stat_t eprim2 = TMath::Abs(err2/sum - contsum*contsum);
// eprim = TMath::Sqrt(eprim2);
// ... ???
// if (fErrorMode == kERRORMEAN) return eprim/TMath::Sqrt(sum);
TW sw = parent::m_bin_Sw[offset]; //ROOT sum
if(sw==0) return 0;
TV svw = m_bin_Svw[offset]; //ROOT cont
TV sv2w = m_bin_Sv2w[offset]; //ROOT err2
TV mean = (svw / sw); //ROOT contsum
TV rms = ::sqrt(::fabs((sv2w/sw) - mean * mean)); //ROOT eprim
// rms = get_bin_rms_value.
return rms/::sqrt(sw); //ROOT kERRORMEAN mode returned value
}
public:
bool multiply(TW a_factor){
if(!parent::base_multiply(a_factor)) return false;
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] *= a_factor;
}
return true;
}
bool scale(TW a_factor) {return multiply(a_factor);}
TV bin_Svw(int aI,int aJ) const {
TO offset;
if(!parent::_find_offset(aI,aJ,offset)) return 0;
return m_bin_Svw[offset];
}
TV bin_Sv2w(int aI,int aJ) const {
TO offset;
if(!parent::_find_offset(aI,aJ,offset)) return 0;
return m_bin_Sv2w[offset];
}
bool reset() {
parent::base_reset();
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] = 0;
m_bin_Sv2w[ibin] = 0;
}
return true;
}
void copy_from_data(const pd_t& a_from) {
parent::base_from_data(a_from);
m_bin_Svw = a_from.m_bin_Svw;
m_bin_Sv2w = a_from.m_bin_Sv2w;
m_cut_v = a_from.m_cut_v;
m_min_v = a_from.m_min_v;
m_max_v = a_from.m_max_v;
}
pd_t get_histo_data() const {
pd_t hd(parent::dac());
hd.m_is_profile = true;
hd.m_bin_Svw = m_bin_Svw;
hd.m_bin_Sv2w = m_bin_Sv2w;
hd.m_cut_v = m_cut_v;
hd.m_min_v = m_min_v;
hd.m_max_v = m_max_v;
return hd;
}
bool fill(TC aX,TC aY,TV aV,TW aWeight = 1) {
if(parent::m_dimension!=2) return false;
if(m_cut_v) {
if( (aV<m_min_v) || (aV>=m_max_v) ) {
return true;
}
}
bn_t ibin,jbin;
if(!parent::m_axes[0].coord_to_absolute_index(aX,ibin)) return false;
if(!parent::m_axes[1].coord_to_absolute_index(aY,jbin)) return false;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
parent::m_bin_entries[offset]++;
parent::m_bin_Sw[offset] += aWeight;
parent::m_bin_Sw2[offset] += aWeight * aWeight;
TC xw = aX * aWeight;
TC x2w = aX * xw;
parent::m_bin_Sxw[offset][0] += xw;
parent::m_bin_Sx2w[offset][0] += x2w;
TC yw = aY * aWeight;
TC y2w = aY * yw;
parent::m_bin_Sxw[offset][1] += yw;
parent::m_bin_Sx2w[offset][1] += y2w;
bool inRange = true;
if(ibin==0) inRange = false;
else if(ibin==(parent::m_axes[0].m_number_of_bins+1)) inRange = false;
if(jbin==0) inRange = false;
else if(jbin==(parent::m_axes[1].m_number_of_bins+1)) inRange = false;
parent::m_all_entries++;
if(inRange) {
parent::m_in_range_plane_Sxyw[0] += aX * aY * aWeight;
// fast getters :
parent::m_in_range_entries++;
parent::m_in_range_Sw += aWeight;
parent::m_in_range_Sw2 += aWeight*aWeight;
parent::m_in_range_Sxw[0] += xw;
parent::m_in_range_Sx2w[0] += x2w;
parent::m_in_range_Sxw[1] += yw;
parent::m_in_range_Sx2w[1] += y2w;
}
// Profile part :
TV vw = aV * aWeight;
m_bin_Svw[offset] += vw;
m_bin_Sv2w[offset] += aV * vw;
return true;
}
TV bin_rms_value(int aI,int aJ) const {
TO offset;
if(!parent::_find_offset(aI,aJ,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TV svw = m_bin_Svw[offset];
TV sv2w = m_bin_Sv2w[offset];
TV mean = (svw / sw);
return ::sqrt(::fabs((sv2w / sw) - mean * mean));
}
bool add(const p2& a_histo){
parent::base_add(a_histo);
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] += a_histo.m_bin_Svw[ibin];
m_bin_Sv2w[ibin] += a_histo.m_bin_Sv2w[ibin];
}
return true;
}
bool subtract(const p2& a_histo){
parent::base_subtract(a_histo);
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] -= a_histo.m_bin_Svw[ibin];
m_bin_Sv2w[ibin] -= a_histo.m_bin_Sv2w[ibin];
}
return true;
}
bool cut_v() const {return m_cut_v;}
TV min_v() const {return m_min_v;}
TV max_v() const {return m_max_v;}
public:
p2(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax,
bn_t aYnumber,TC aYmin,TC aYmax)
:parent(a_title,aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax)
,m_cut_v(false)
,m_min_v(0)
,m_max_v(0)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
p2(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax,
bn_t aYnumber,TC aYmin,TC aYmax,
TV aVmin,TV aVmax)
:parent(a_title,aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax)
,m_cut_v(true)
,m_min_v(aVmin)
,m_max_v(aVmax)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
p2(const std::string& a_title,
const std::vector<TC>& a_edges_x,
const std::vector<TC>& a_edges_y)
:parent(a_title,a_edges_x,a_edges_y)
,m_cut_v(false)
,m_min_v(0)
,m_max_v(0)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
p2(const std::string& a_title,
const std::vector<TC>& a_edges_x,
const std::vector<TC>& a_edges_y,
TV aVmin,TV aVmax)
:parent(a_title,a_edges_x,a_edges_y)
,m_cut_v(true)
,m_min_v(aVmin)
,m_max_v(aVmax)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
virtual ~p2(){}
public:
p2(const p2& a_from)
:parent(a_from)
,m_cut_v(a_from.m_cut_v)
,m_min_v(a_from.m_min_v)
,m_max_v(a_from.m_max_v)
,m_bin_Svw(a_from.m_bin_Svw)
,m_bin_Sv2w(a_from.m_bin_Sv2w)
{}
p2& operator=(const p2& a_from){
parent::operator=(a_from);
m_cut_v = a_from.m_cut_v;
m_min_v = a_from.m_min_v;
m_max_v = a_from.m_max_v;
m_bin_Svw = a_from.m_bin_Svw;
m_bin_Sv2w = a_from.m_bin_Sv2w;
return *this;
}
public:
bool configure(bn_t aXnumber,TC aXmin,TC aXmax,bn_t aYnumber,TC aYmin,TC aYmax){
if(!parent::configure(aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax)) return false;
m_bin_Svw.clear();
m_bin_Sv2w.clear();
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
m_cut_v = false;
m_min_v = 0;
m_max_v = 0;
return true;
}
bool configure(const std::vector<TC>& a_edges_x,const std::vector<TC>& a_edges_y) {
if(!parent::configure(a_edges_x,a_edges_y)) return false;
m_bin_Svw.clear();
m_bin_Sv2w.clear();
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
m_cut_v = false;
m_min_v = 0;
m_max_v = 0;
return true;
}
bool configure(bn_t aXnumber,TC aXmin,TC aXmax,bn_t aYnumber,TC aYmin,TC aYmax,TV aVmin,TV aVmax){
if(!parent::configure(aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax)) return false;
m_bin_Svw.clear();
m_bin_Sv2w.clear();
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
m_cut_v = true;
m_min_v = aVmin;
m_max_v = aVmax;
return true;
}
bool configure(const std::vector<TC>& a_edges_x,const std::vector<TC>& a_edges_y,TV aVmin,TV aVmax) {
if(!parent::configure(a_edges_x,a_edges_y)) return false;
m_bin_Svw.clear();
m_bin_Sv2w.clear();
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
m_cut_v = true;
m_min_v = aVmin;
m_max_v = aVmax;
return true;
}
public:
const vs_t& bins_sum_vw() const {return m_bin_Svw;}
const vs_t& bins_sum_v2w() const {return m_bin_Sv2w;}
TW get_Svw() const {
TW sw = 0;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin)) {
sw += m_bin_Svw[ibin];
}
}
return sw;
}
TW get_Sv2w() const {
TW sw = 0;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(!histo::is_out(parent::m_axes,ibin)) {
sw += m_bin_Sv2w[ibin];
}
}
return sw;
}
protected:
bool m_cut_v;
TV m_min_v;
TV m_max_v;
vs_t m_bin_Svw;
vs_t m_bin_Sv2w;
};
}}
#endif
+66
View File
@@ -0,0 +1,66 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_p2d
#define tools_histo_p2d
#include "p2"
namespace tools {
namespace histo {
class p2d : public p2<double,unsigned int,unsigned int,double,double,double> {
typedef p2<double,unsigned int,unsigned int,double,double,double> parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::p2d");
return s_v;
}
const std::string& s_cls() const {return s_class();}
public:
p2d():parent("",10,0,1,10,0,1){} //for I/O when reading.
p2d(const std::string& a_title,
unsigned int aXnumber,double aXmin,double aXmax,
unsigned int aYnumber,double aYmin,double aYmax)
:parent(a_title,aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax)
{}
p2d(const std::string& a_title,
unsigned int aXnumber,double aXmin,double aXmax,
unsigned int aYnumber,double aYmin,double aYmax,
double aVmin,double aVmax)
:parent(a_title,aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax,aVmin,aVmax)
{}
p2d(const std::string& a_title,
const std::vector<double>& a_edges_x,
const std::vector<double>& a_edges_y)
:parent(a_title,a_edges_x,a_edges_y)
{}
p2d(const std::string& a_title,
const std::vector<double>& a_edges_x,
const std::vector<double>& a_edges_y,
double aVmin,double aVmax)
:parent(a_title,a_edges_x,a_edges_y,aVmin,aVmax)
{}
virtual ~p2d(){}
public:
p2d(const p2d& a_from): parent(a_from){}
p2d& operator=(const p2d& a_from){
parent::operator=(a_from);
return *this;
}
private: static void check_instantiation() {p2d dummy("",10,0,1,10,0,1);}
};
}}
#endif
@@ -0,0 +1,83 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_profile_data
#define tools_histo_profile_data
#include "histo_data"
namespace tools {
namespace histo {
template <class TC,class TO,class TN,class TW,class TV>
class profile_data : public histo_data<TC,TO,TN,TW> {
typedef histo_data<TC,TO,TN,TW> parent;
public:
typedef std::vector<TV> vs_t;
public:
profile_data()
:parent()
,m_is_profile(true)
,m_cut_v(false)
,m_min_v(0)
,m_max_v(0)
{}
profile_data(const histo_data<TC,TO,TN,TW>& a_from)
:parent(a_from)
,m_is_profile(false)
,m_cut_v(false)
,m_min_v(0)
,m_max_v(0)
{}
public:
profile_data(const profile_data& a_from)
:parent(a_from)
,m_is_profile(a_from.m_is_profile)
,m_bin_Svw(a_from.m_bin_Svw)
,m_bin_Sv2w(a_from.m_bin_Sv2w)
,m_cut_v(a_from.m_cut_v)
,m_min_v(a_from.m_min_v)
,m_max_v(a_from.m_max_v)
{}
profile_data& operator=(const profile_data& a_from) {
parent::operator=(a_from);
m_is_profile = a_from.m_is_profile;
m_bin_Svw = a_from.m_bin_Svw;
m_bin_Sv2w = a_from.m_bin_Sv2w;
m_cut_v = a_from.m_cut_v;
m_min_v = a_from.m_min_v;
m_max_v = a_from.m_max_v;
return *this;
}
virtual ~profile_data(){}
public:
profile_data& operator=(const histo_data<TC,TO,TN,TW>& a_from) {
//for Rio_THisogram.
histo_data<TC,TO,TN,TW>::operator=(a_from);
if(&a_from==this) return *this;
m_is_profile = false;
m_bin_Svw.clear();
m_bin_Sv2w.clear();
m_cut_v = false;
m_min_v = 0;
m_max_v = 0;
return *this;
}
public:
bool m_is_profile; //for Rio_THistogram.
std::vector<TV> m_bin_Svw;
std::vector<TV> m_bin_Sv2w;
bool m_cut_v;
TV m_min_v;
TV m_max_v;
};
}}
#endif
+509
View File
@@ -0,0 +1,509 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_slice
#define tools_histo_slice
#include "axis"
namespace tools {
namespace histo {
/////////////////////////////////////////////////////////////////////////////////
/// h2 -> h1 ////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
template <class H2,class H1>
inline bool fill_slice_x(const H2& a_from,int aJbeg,int aJend,H1& a_to) {
if(!a_from.dimension()) return false;
typedef typename H2::bn_t bn_t;
bn_t jbeg;
if(!a_from.axis_y().in_range_to_absolute_index(aJbeg,jbeg)) return false;
bn_t jend;
if(!a_from.axis_y().in_range_to_absolute_index(aJend,jend)) return false;
if(jbeg>jend) return false;
if(a_from.axis_x().bins()!=a_to.axis().bins()) return false;
typedef typename H1::hd_t hd_t;
hd_t hdata = a_to.dac();
bn_t aoffset,offset,jbin;
bn_t yoffset = a_from.axis_y().m_offset;
typedef typename H2::num_entries_t TN;
typedef typename H2::weight_t TW;
typedef typename H2::coordinate_t TC;
const std::vector<TN>& af_bin_entries = a_from.bins_entries();
const std::vector<TW>& af_bin_Sw = a_from.bins_sum_w();
const std::vector<TW>& af_bin_Sw2 = a_from.bins_sum_w2();
const std::vector< std::vector<TC> >& af_bin_Sxw = a_from.bins_sum_xw();
const std::vector< std::vector<TC> >& af_bin_Sx2w = a_from.bins_sum_x2w();
// Fill also the outflow.
bn_t abins = hdata.m_axes[0].bins()+2;
for(bn_t aibin=0;aibin<abins;aibin++) {
//offset1D = ibin
aoffset = aibin;
for(jbin=jbeg;jbin<=jend;jbin++) {
//offset2D = ibin + jbin * yoffset
// hdata booked with x then :
offset = aibin + jbin * yoffset;
// Bin :
hdata.m_bin_entries[aoffset] += af_bin_entries[offset];
hdata.m_bin_Sw[aoffset] += af_bin_Sw[offset];
hdata.m_bin_Sw2[aoffset] += af_bin_Sw2[offset];
hdata.m_bin_Sxw[aoffset][0] += af_bin_Sxw[offset][0];
hdata.m_bin_Sx2w[aoffset][0] += af_bin_Sx2w[offset][0];
}
}
hdata.m_in_range_plane_Sxyw.assign(a_to.number_of_planes(),0); //ill-defined.
hdata.update_fast_getters();
a_to.copy_from_data(hdata);
return true;
}
template <class H2,class H1>
inline H1* slice_x(const H2& a_from,int aJbeg,int aJend,const std::string& a_title) {
H1* slice = new H1(a_title,a_from.axis_x().bins(),a_from.axis_x().lower_edge(),a_from.axis_x().upper_edge());
if(!fill_slice_x(a_from,aJbeg,aJend,*slice)) {delete slice;return 0;}
return slice;
}
template <class H2,class H1>
inline H1* projection_x(const H2& a_from,const std::string& a_title) {
return slice_x(a_from,axis_UNDERFLOW_BIN,axis_OVERFLOW_BIN,a_title);
}
template <class H2,class H1>
inline bool fill_slice_y(const H2& a_from,int aIbeg,int aIend,H1& a_to) {
if(!a_from.dimension()) return false;
typedef typename H2::bn_t bn_t;
bn_t ibeg;
if(!a_from.axis_x().in_range_to_absolute_index(aIbeg,ibeg)) return false;
bn_t iend;
if(!a_from.axis_x().in_range_to_absolute_index(aIend,iend)) return false;
if(ibeg>iend) return false;
if(a_from.axis_y().bins()!=a_to.axis().bins()) return false;
typedef typename H1::hd_t hd_t;
hd_t hdata = a_to.dac();
bn_t aibin,aoffset,offset,ibin;
bn_t yoffset = a_from.axis_y().m_offset;
typedef typename H2::num_entries_t TN;
typedef typename H2::weight_t TW;
typedef typename H2::coordinate_t TC;
const std::vector<TN>& af_bin_entries = a_from.bins_entries();
const std::vector<TW>& af_bin_Sw = a_from.bins_sum_w();
const std::vector<TW>& af_bin_Sw2 = a_from.bins_sum_w2();
const std::vector< std::vector<TC> >& af_bin_Sxw = a_from.bins_sum_xw();
const std::vector< std::vector<TC> >& af_bin_Sx2w = a_from.bins_sum_x2w();
// Fill also the outflow.
bn_t abins = hdata.m_axes[0].bins()+2;
for(aibin=0;aibin<abins;aibin++) {
//offset1D = ibin
aoffset = aibin;
for(ibin=ibeg;ibin<=iend;ibin++) {
//offset2D = ibin + jbin * yoffset
// hdata booked with y then :
offset = ibin + aibin * yoffset;
// Bin :
hdata.m_bin_entries[aoffset] += af_bin_entries[offset];
hdata.m_bin_Sw[aoffset] += af_bin_Sw[offset];
hdata.m_bin_Sw2[aoffset] += af_bin_Sw2[offset];
hdata.m_bin_Sxw[aoffset][0] += af_bin_Sxw[offset][1];
hdata.m_bin_Sx2w[aoffset][0] += af_bin_Sx2w[offset][1];
}
}
hdata.m_in_range_plane_Sxyw.assign(a_to.number_of_planes(),0); //ill-defined.
hdata.update_fast_getters();
a_to.copy_from_data(hdata);
return true;
}
template <class H2,class H1>
inline H1* slice_y(const H2& a_from,int aIbeg,int aIend,const std::string& a_title) {
H1* slice = new H1(a_title,a_from.axis_y().bins(),a_from.axis_y().lower_edge(),a_from.axis_y().upper_edge());
if(!fill_slice_y(a_from,aIbeg,aIend,*slice)) {delete slice;return 0;}
return slice;
}
template <class H2,class H1>
inline H1* projection_y(const H2& a_from,const std::string& a_title) {
return slice_y(a_from,axis_UNDERFLOW_BIN,axis_OVERFLOW_BIN,a_title);
}
/////////////////////////////////////////////////////////////////////////////////
/// h2 -> p1 ////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
template <class H2,class P1>
inline bool fill_profile_x(const H2& a_from,int aJbeg,int aJend,P1& a_to) {
if(!a_from.dimension()) return false;
typedef typename H2::bn_t bn_t;
bn_t jbeg;
if(!a_from.axis_y().in_range_to_absolute_index(aJbeg,jbeg)) return false;
bn_t jend;
if(!a_from.axis_y().in_range_to_absolute_index(aJend,jend)) return false;
if(jbeg>jend) return false;
if(a_from.axis_x().bins()!=a_to.axis().bins()) return false;
typedef typename P1::pd_t pd_t;
pd_t hdata = a_to.get_histo_data();
bn_t aoffset,offset,jbin;
bn_t yoffset = a_from.axis_y().m_offset;
typedef typename H2::num_entries_t TN;
typedef typename H2::weight_t TW;
typedef typename H2::coordinate_t TC;
const std::vector<TN>& af_bin_entries = a_from.bins_entries();
const std::vector<TW>& af_bin_Sw = a_from.bins_sum_w();
const std::vector<TW>& af_bin_Sw2 = a_from.bins_sum_w2();
const std::vector< std::vector<TC> >& af_bin_Sxw = a_from.bins_sum_xw();
const std::vector< std::vector<TC> >& af_bin_Sx2w = a_from.bins_sum_x2w();
// Fill also the outflow.
bn_t abins = hdata.m_axes[0].bins()+2;
for(bn_t aibin=0;aibin<abins;aibin++) {
//offset1D = ibin
aoffset = aibin;
for(jbin=jbeg;jbin<=jend;jbin++) {
//offset2D = ibin + jbin * yoffset
// hdata booked with x then :
offset = aibin + jbin * yoffset;
// Bin :
hdata.m_bin_entries[aoffset] += af_bin_entries[offset];
hdata.m_bin_Sw[aoffset] += af_bin_Sw[offset];
hdata.m_bin_Sw2[aoffset] += af_bin_Sw2[offset];
hdata.m_bin_Sxw[aoffset][0] += af_bin_Sxw[offset][0];
hdata.m_bin_Sx2w[aoffset][0] += af_bin_Sx2w[offset][0];
hdata.m_bin_Svw[aoffset] += af_bin_Sxw[offset][1];
hdata.m_bin_Sv2w[aoffset] += af_bin_Sx2w[offset][1];
}
}
hdata.m_in_range_plane_Sxyw.assign(a_to.number_of_planes(),0); //ill-defined.
hdata.update_fast_getters();
a_to.copy_from_data(hdata);
return true;
}
template <class H2,class P1>
inline bool fill_profile_y(const H2& a_from,int aIbeg,int aIend,P1& a_to) {
if(!a_from.dimension()) return false;
typedef typename H2::bn_t bn_t;
bn_t ibeg;
if(!a_from.axis_x().in_range_to_absolute_index(aIbeg,ibeg)) return false;
bn_t iend;
if(!a_from.axis_x().in_range_to_absolute_index(aIend,iend)) return false;
if(ibeg>iend) return false;
if(a_from.axis_y().bins()!=a_to.axis().bins()) return false;
typedef typename P1::pd_t pd_t;
pd_t hdata = a_to.get_histo_data();
bn_t aibin,aoffset,offset,ibin;
bn_t yoffset = a_from.axis_y().m_offset;
typedef typename H2::num_entries_t TN;
typedef typename H2::weight_t TW;
typedef typename H2::coordinate_t TC;
const std::vector<TN>& af_bin_entries = a_from.bins_entries();
const std::vector<TW>& af_bin_Sw = a_from.bins_sum_w();
const std::vector<TW>& af_bin_Sw2 = a_from.bins_sum_w2();
const std::vector< std::vector<TC> >& af_bin_Sxw = a_from.bins_sum_xw();
const std::vector< std::vector<TC> >& af_bin_Sx2w = a_from.bins_sum_x2w();
// Fill also the outflow.
bn_t abins = hdata.m_axes[0].bins()+2;
for(aibin=0;aibin<abins;aibin++) {
//offset1D = ibin
aoffset = aibin;
for(ibin=ibeg;ibin<=iend;ibin++) {
//offset2D = ibin + jbin * yoffset
// hdata booked with y then :
offset = ibin + aibin * yoffset;
// Bin :
hdata.m_bin_entries[aoffset] += af_bin_entries[offset];
hdata.m_bin_Sw[aoffset] += af_bin_Sw[offset];
hdata.m_bin_Sw2[aoffset] += af_bin_Sw2[offset];
hdata.m_bin_Sxw[aoffset][0] += af_bin_Sxw[offset][1];
hdata.m_bin_Sx2w[aoffset][0] += af_bin_Sx2w[offset][1];
hdata.m_bin_Svw[aoffset] += af_bin_Sxw[offset][0];
hdata.m_bin_Sv2w[aoffset] += af_bin_Sx2w[offset][0];
}
}
hdata.m_in_range_plane_Sxyw.assign(a_to.number_of_planes(),0); //ill-defined.
hdata.update_fast_getters();
a_to.copy_from_data(hdata);
return true;
}
/////////////////////////////////////////////////////////////////////////////////
/// h3 -> h2 ////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
template <class H3,class H2>
inline bool fill_slice_yz(const H3& a_from,int aIbeg,int aIend,H2& a_to) {
if(!a_from.dimension()) return false;
typedef typename H3::bn_t bn_t;
bn_t ibeg;
if(!a_from.axis_x().in_range_to_absolute_index(aIbeg,ibeg)) return false;
bn_t iend;
if(!a_from.axis_x().in_range_to_absolute_index(aIend,iend)) return false;
if(ibeg>iend) return false;
if(a_from.axis_y().bins()!=a_to.axis_x().bins()) return false;
if(a_from.axis_z().bins()!=a_to.axis_y().bins()) return false;
typedef typename H2::hd_t hd_t;
hd_t hdata = a_to.dac();
bn_t aibin,ajbin,aoffset,offset,ibin;
bn_t ayoffset = hdata.m_axes[1].m_offset;
bn_t yoffset = a_from.axis_y().m_offset;
bn_t zoffset = a_from.axis_z().m_offset;
bn_t axbins = hdata.m_axes[0].bins()+2;
bn_t aybins = hdata.m_axes[1].bins()+2;
typedef typename H3::num_entries_t TN;
typedef typename H3::weight_t TW;
typedef typename H3::coordinate_t TC;
const std::vector<TN>& af_bin_entries = a_from.bins_entries();
const std::vector<TW>& af_bin_Sw = a_from.bins_sum_w();
const std::vector<TW>& af_bin_Sw2 = a_from.bins_sum_w2();
const std::vector< std::vector<TC> >& af_bin_Sxw = a_from.bins_sum_xw();
const std::vector< std::vector<TC> >& af_bin_Sx2w = a_from.bins_sum_x2w();
// Fill also the outflow.
for(aibin=0;aibin<axbins;aibin++) {
for(ajbin=0;ajbin<aybins;ajbin++) {
//offset2D = ibin + jbin * m_axes[1].m_offset
aoffset = aibin + ajbin * ayoffset;
for(ibin=ibeg;ibin<=iend;ibin++) {
//offset3D = ibin + jbin * m_axes[1].m_offset + kbin*m_axes[2].m_offset;
// hdata booked with y-z then :
offset = ibin + aibin * yoffset + ajbin * zoffset;
// Bin :
hdata.m_bin_entries[aoffset] += af_bin_entries[offset];
hdata.m_bin_Sw[aoffset] += af_bin_Sw[offset];
hdata.m_bin_Sw2[aoffset] += af_bin_Sw2[offset];
hdata.m_bin_Sxw[aoffset][0] += af_bin_Sxw[offset][1];
hdata.m_bin_Sxw[aoffset][1] += af_bin_Sxw[offset][2];
hdata.m_bin_Sx2w[aoffset][0] += af_bin_Sx2w[offset][1];
hdata.m_bin_Sx2w[aoffset][1] += af_bin_Sx2w[offset][2];
}
}
}
hdata.m_in_range_plane_Sxyw.assign(a_to.number_of_planes(),0); //ill-defined.
hdata.update_fast_getters();
a_to.copy_from_data(hdata);
return true;
}
template <class H3,class H2>
inline bool fill_slice_xy(const H3& a_from,int aKbeg,int aKend,H2& a_to) {
if(!a_from.dimension()) return false;
typedef typename H3::bn_t bn_t;
bn_t kbeg;
if(!a_from.axis_z().in_range_to_absolute_index(aKbeg,kbeg)) return false;
bn_t kend;
if(!a_from.axis_z().in_range_to_absolute_index(aKend,kend)) return false;
if(kbeg>kend) return false;
if(a_from.axis_x().bins()!=a_to.axis_x().bins()) return false;
if(a_from.axis_y().bins()!=a_to.axis_y().bins()) return false;
typedef typename H2::hd_t hd_t;
hd_t hdata = a_to.dac();
bn_t kbin;
bn_t aibin,ajbin,aoffset,offset;
bn_t ayoffset = hdata.m_axes[1].m_offset;
bn_t yoffset = a_from.axis_y().m_offset;
bn_t zoffset = a_from.axis_z().m_offset;
bn_t axbins = hdata.m_axes[0].bins()+2;
bn_t aybins = hdata.m_axes[1].bins()+2;
typedef typename H3::num_entries_t TN;
typedef typename H3::weight_t TW;
typedef typename H3::coordinate_t TC;
const std::vector<TN>& af_bin_entries = a_from.bins_entries();
const std::vector<TW>& af_bin_Sw = a_from.bins_sum_w();
const std::vector<TW>& af_bin_Sw2 = a_from.bins_sum_w2();
const std::vector< std::vector<TC> >& af_bin_Sxw = a_from.bins_sum_xw();
const std::vector< std::vector<TC> >& af_bin_Sx2w = a_from.bins_sum_x2w();
// Fill also the outflow.
for(aibin=0;aibin<axbins;aibin++) {
for(ajbin=0;ajbin<aybins;ajbin++) {
//offset2D = ibin + jbin * m_axes[1].m_offset
aoffset = aibin + ajbin * ayoffset;
for(kbin=kbeg;kbin<=kend;kbin++) {
//offset3D = ibin + jbin * m_axes[1].m_offset + kbin*m_axes[2].m_offset;
// hdata booked with x-y then :
offset = aibin + ajbin * yoffset + kbin * zoffset;
// Bin :
hdata.m_bin_entries[aoffset] += af_bin_entries[offset];
hdata.m_bin_Sw[aoffset] += af_bin_Sw[offset];
hdata.m_bin_Sw2[aoffset] += af_bin_Sw2[offset];
hdata.m_bin_Sxw[aoffset][0] += af_bin_Sxw[offset][0];
hdata.m_bin_Sxw[aoffset][1] += af_bin_Sxw[offset][1];
hdata.m_bin_Sx2w[aoffset][0] += af_bin_Sx2w[offset][0];
hdata.m_bin_Sx2w[aoffset][1] += af_bin_Sx2w[offset][1];
}
}
}
hdata.m_in_range_plane_Sxyw.assign(a_to.number_of_planes(),0); //ill-defined.
hdata.update_fast_getters();
a_to.copy_from_data(hdata);
return true;
}
template <class H3,class H2>
inline bool fill_slice_xz(const H3& a_from,int aJbeg,int aJend,H2& a_to) {
if(!a_from.dimension()) return false;
typedef typename H3::bn_t bn_t;
bn_t jbeg;
if(!a_from.axis_y().in_range_to_absolute_index(aJbeg,jbeg)) return false;
bn_t jend;
if(!a_from.axis_y().in_range_to_absolute_index(aJend,jend)) return false;
if(jbeg>jend) return false;
if(a_from.axis_x().bins()!=a_to.axis_x().bins()) return false;
if(a_from.axis_z().bins()!=a_to.axis_y().bins()) return false;
typedef typename H2::hd_t hd_t;
hd_t hdata = a_to.dac();
bn_t aibin,ajbin,aoffset,offset,jbin;
bn_t ayoffset = hdata.m_axes[1].m_offset;
bn_t yoffset = a_from.axis_y().m_offset;
bn_t zoffset = a_from.axis_z().m_offset;
bn_t axbins = hdata.m_axes[0].bins()+2;
bn_t aybins = hdata.m_axes[1].bins()+2;
typedef typename H3::num_entries_t TN;
typedef typename H3::weight_t TW;
typedef typename H3::coordinate_t TC;
const std::vector<TN>& af_bin_entries = a_from.bins_entries();
const std::vector<TW>& af_bin_Sw = a_from.bins_sum_w();
const std::vector<TW>& af_bin_Sw2 = a_from.bins_sum_w2();
const std::vector< std::vector<TC> >& af_bin_Sxw = a_from.bins_sum_xw();
const std::vector< std::vector<TC> >& af_bin_Sx2w = a_from.bins_sum_x2w();
// Fill also the outflow.
for(aibin=0;aibin<axbins;aibin++) {
for(ajbin=0;ajbin<aybins;ajbin++) {
//offset2D = ibin + jbin * m_axes[1].m_offset
aoffset = aibin + ajbin * ayoffset;
for(jbin=jbeg;jbin<=jend;jbin++) {
//offset3D = ibin + jbin * m_axes[1].m_offset + kbin*m_axes[2].m_offset;
// hdata booked with x-z then :
offset = aibin + jbin * yoffset + ajbin * zoffset;
// Bin :
hdata.m_bin_entries[aoffset] += af_bin_entries[offset];
hdata.m_bin_Sw[aoffset] += af_bin_Sw[offset];
hdata.m_bin_Sw2[aoffset] += af_bin_Sw2[offset];
hdata.m_bin_Sxw[aoffset][0] += af_bin_Sxw[offset][0];
hdata.m_bin_Sxw[aoffset][1] += af_bin_Sxw[offset][2];
hdata.m_bin_Sx2w[aoffset][0] += af_bin_Sx2w[offset][0];
hdata.m_bin_Sx2w[aoffset][1] += af_bin_Sx2w[offset][2];
}
}
}
hdata.m_in_range_plane_Sxyw.assign(a_to.number_of_planes(),0); //ill-defined.
hdata.update_fast_getters();
a_to.copy_from_data(hdata);
return true;
}
template <class H3,class H2>
inline H2* slice_xy(const H3& a_from,int aKbeg,int aKend,const std::string& a_title) {
H2* slice = new H2(a_title,
a_from.axis_x().bins(),a_from.axis_x().lower_edge(),a_from.axis_x().upper_edge(),
a_from.axis_y().bins(),a_from.axis_y().lower_edge(),a_from.axis_y().upper_edge());
if(!fill_slice_xy(a_from,aKbeg,aKend,*slice)) {delete slice;return 0;}
return slice;
}
template <class H3,class H2>
inline H2* slice_yz(const H3& a_from,int aIbeg,int aIend,const std::string& a_title) {
H2* slice = new H2(a_title,
a_from.axis_y().bins(),a_from.axis_y().lower_edge(),a_from.axis_y().upper_edge(),
a_from.axis_z().bins(),a_from.axis_z().lower_edge(),a_from.axis_z().upper_edge());
if(!fill_slice_yz(a_from,aIbeg,aIend,*slice)) {delete slice;return 0;}
return slice;
}
template <class H3,class H2>
inline H2* slice_xz(const H3& a_from,int aJbeg,int aJend,const std::string& a_title) {
H2* slice = new H2(a_title,
a_from.axis_x().bins(),a_from.axis_x().lower_edge(),a_from.axis_x().upper_edge(),
a_from.axis_z().bins(),a_from.axis_z().lower_edge(),a_from.axis_z().upper_edge());
if(!fill_slice_xz(a_from,aJbeg,aJend,*slice)) {delete slice;return 0;}
return slice;
}
}}
#endif
+121
View File
@@ -0,0 +1,121 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_sliced
#define tools_histo_sliced
#include "slice"
#include "h1d"
#include "h2d"
/////////////////////////////////////////////////////////////////////////////////
/// h2 -> h1 ////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
namespace tools {
namespace histo {
inline h1d* slice_x(const h2d& a_from,int aJbeg,int aJend,const std::string& a_title) {
h1d* slice_x = new h1d(a_title,
a_from.axis_x().bins(),a_from.axis_x().lower_edge(),a_from.axis_x().upper_edge());
if(!fill_slice_x(a_from,aJbeg,aJend,*slice_x)) {delete slice_x;return 0;}
return slice_x;
}
inline h1d* projection_x(const h2d& a_from,const std::string& a_title) {
return slice_x(a_from,axis_UNDERFLOW_BIN,axis_OVERFLOW_BIN,a_title);
}
inline h1d* slice_y(const h2d& a_from,int aIbeg,int aIend,const std::string& a_title) {
h1d* slice_y = new h1d(a_title,
a_from.axis_y().bins(),a_from.axis_y().lower_edge(),a_from.axis_y().upper_edge());
if(!fill_slice_y(a_from,aIbeg,aIend,*slice_y)) {delete slice_y;return 0;}
return slice_y;
}
inline h1d* projection_y(const h2d& a_from,const std::string& a_title) {
return slice_y(a_from,axis_UNDERFLOW_BIN,axis_OVERFLOW_BIN,a_title);
}
}}
/////////////////////////////////////////////////////////////////////////////////
/// h2 -> p1 ////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
#include "p1d"
namespace tools {
namespace histo {
inline p1d* profile_x(const h2d& a_from,int aJbeg,int aJend,const std::string& a_title) {
p1d* slice_x = new p1d(a_title,
a_from.axis_x().bins(),a_from.axis_x().lower_edge(),a_from.axis_x().upper_edge());
if(!fill_profile_x(a_from,aJbeg,aJend,*slice_x)) {delete slice_x;return 0;}
return slice_x;
}
inline p1d* profile_x(const h2d& a_from,const std::string& a_title) {
return profile_x(a_from,axis_UNDERFLOW_BIN,axis_OVERFLOW_BIN,a_title);
}
inline p1d* profile_y(const h2d& a_from,int aIbeg,int aIend,const std::string& a_title) {
p1d* slice_y = new p1d(a_title,
a_from.axis_y().bins(),a_from.axis_y().lower_edge(),a_from.axis_y().upper_edge());
if(!fill_profile_y(a_from,aIbeg,aIend,*slice_y)) {delete slice_y;return 0;}
return slice_y;
}
inline p1d* profile_y(const h2d& a_from,const std::string& a_title) {
return profile_y(a_from,axis_UNDERFLOW_BIN,axis_OVERFLOW_BIN,a_title);
}
}}
/////////////////////////////////////////////////////////////////////////////////
/// h3 -> h2 ////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
#include "h3d"
namespace tools {
namespace histo {
inline h2d* slice_xy(const h3d& a_from,int aKbeg,int aKend,const std::string& a_title) {
h2d* slice = new h2d(a_title,
a_from.axis_x().bins(),a_from.axis_x().lower_edge(),a_from.axis_x().upper_edge(),
a_from.axis_y().bins(),a_from.axis_y().lower_edge(),a_from.axis_y().upper_edge());
if(!fill_slice_xy(a_from,aKbeg,aKend,*slice)) {delete slice;return 0;}
return slice;
}
inline h2d* projection_xy(const h3d& a_from,const std::string& a_title) {
return slice_xy(a_from,axis_UNDERFLOW_BIN,axis_OVERFLOW_BIN,a_title);
}
inline h2d* slice_yz(const h3d& a_from,int aIbeg,int aIend,const std::string& a_title) {
h2d* slice = new h2d(a_title,
a_from.axis_y().bins(),a_from.axis_y().lower_edge(),a_from.axis_y().upper_edge(),
a_from.axis_z().bins(),a_from.axis_z().lower_edge(),a_from.axis_z().upper_edge());
if(!fill_slice_yz(a_from,aIbeg,aIend,*slice)) {delete slice;return 0;}
return slice;
}
inline h2d* projection_yz(const h3d& a_from,const std::string& a_title) {
return slice_yz(a_from,axis_UNDERFLOW_BIN,axis_OVERFLOW_BIN,a_title);
}
inline h2d* slice_xz(const h3d& a_from,int aJbeg,int aJend,const std::string& a_title) {
h2d* slice = new h2d(a_title,
a_from.axis_x().bins(),a_from.axis_x().lower_edge(),a_from.axis_x().upper_edge(),
a_from.axis_z().bins(),a_from.axis_z().lower_edge(),a_from.axis_z().upper_edge());
if(!fill_slice_xz(a_from,aJbeg,aJend,*slice)) {delete slice;return 0;}
return slice;
}
inline h2d* projection_xz(const h3d& a_from,const std::string& a_title) {
return slice_xz(a_from,axis_UNDERFLOW_BIN,axis_OVERFLOW_BIN,a_title);
}
}}
#endif