Import Geant4 10.1.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-10 12:08:39 +02:00
parent 286caacf06
commit c9b32a6c0a
5770 changed files with 1050949 additions and 367105 deletions
@@ -6,6 +6,8 @@
// a few place in which a cpp macro help the readability.
#include <string>
#define TOOLS_CLASS_STRING(a_name)\
static const std::string& s_##a_name() {\
static const std::string s_v(#a_name);\
@@ -24,9 +26,9 @@ inline const std::string& s_##a_name() {\
return s_v;\
}
#define TOOLS_GLOBAL_ARG(a_name)\
#define TOOLS_GLOBAL_STRING_VALUE(a_name,a_value)\
inline const std::string& s_##a_name() {\
static const std::string s_v(std::string("-")+std::string(#a_name));\
static const std::string s_v(#a_value);\
return s_v;\
}
@@ -44,10 +46,4 @@ static const std::string& s_class() {\
}\
static void check_class_name() {a_name<a_T>::s_class();}
#define TOOLS_SCLASS_NO_CHECK(a_name)\
static const std::string& s_class() {\
static const std::string s_v(#a_name);\
return s_v;\
}
#endif
File diff suppressed because it is too large Load Diff
+53 -32
View File
@@ -8,6 +8,8 @@
#include "strip"
#include "words"
#include "sto"
#include "forit"
#include "mnmx"
#include <ostream>
@@ -51,8 +53,7 @@ public:
const std::vector<arg>& get_args() const {return m_args;}
bool is_arg(const std::string& a_string) const {
for(std::vector<arg>::const_iterator it = m_args.begin();
it!=m_args.end();++it) {
tools_vforcit(arg,m_args,it) {
if((*it).first==a_string) return true;
}
return false;
@@ -60,33 +61,30 @@ public:
bool is_empty() const {return m_args.size()?false:true;}
unsigned int size() const {return m_args.size();}
unsigned int number() const {return m_args.size();} //back comp.
bool find(const std::string& a_key,std::string& a_value) const {
for(std::vector<arg>::const_iterator it = m_args.begin();
it!=m_args.end();++it) {
bool find(const std::string& a_key,std::string& a_value,const std::string& a_def = "") const {
tools_vforcit(arg,m_args,it) {
if((*it).first==a_key) {
a_value = (*it).second;
return true;
}
}
a_value.clear();
a_value = a_def;
return false;
}
std::vector<std::string> find(const std::string& a_key) const {
std::vector<std::string> vals;
for(std::vector<arg>::const_iterator it = m_args.begin();
it!=m_args.end();++it) {
tools_vforcit(arg,m_args,it) {
if((*it).first==a_key) vals.push_back((*it).second);
}
return vals;
}
bool find(const std::string& a_string,bool& a_value) const {
bool find(const std::string& a_string,bool& a_value,const bool& a_def = false) const {
std::string s;
if(!find(a_string,s)) {a_value = false;return false;}
return to(s,a_value);
if(!find(a_string,s)) {a_value = a_def;return false;}
return to(s,a_value,a_def);
}
template <class aT>
bool find(const std::string& a_string,aT& a_value,
const aT& a_def = aT()) const {
bool find(const std::string& a_string,aT& a_value,const aT& a_def = aT()) const {
std::string _s;
if(!find(a_string,_s)) {a_value = a_def;return false;}
return to<aT>(_s,a_value,a_def);
@@ -94,8 +92,7 @@ public:
std::vector<std::string> tovector() const {
// Return a vector of string <name=value>
std::vector<std::string> vec;
for(std::vector<arg>::const_iterator it = m_args.begin();
it!=m_args.end();++it) {
tools_vforcit(arg,m_args,it) {
std::string s;
if((*it).second.empty()) {
s = (*it).first;
@@ -113,8 +110,7 @@ public:
const std::string& a_value = "",
bool a_override = true){
if(a_override) {
for(std::vector<arg>::iterator it = m_args.begin();
it!=m_args.end();++it) {
tools_vforit(arg,m_args,it) {
if((*it).first==a_key) {
(*it).second = a_value;
return true;
@@ -127,8 +123,7 @@ public:
}
void add(const std::vector<std::string>& a_args,bool a_strip = false) {
for(std::vector<std::string>::const_iterator it = a_args.begin();
it!=a_args.end();++it) {
tools_vforcit(std::string,a_args,it) {
std::vector<std::string> ws;
words((*it),"=",false,ws);
if(ws.size()==1) {
@@ -147,9 +142,22 @@ public:
}
}
void add_keyvals(const std::vector<std::string>& a_args,bool a_strip = false) {
//a_args must contain an even number of strings.
unsigned int sz_half = a_args.size()/2;
if((2*sz_half)!=a_args.size()) return;
for(std::vector<std::string>::const_iterator it = a_args.begin();
it!=a_args.end();it+=2) {
if(a_strip) {
m_args.push_back(arg(strp(*it),strp(*(it+1))));
} else {
m_args.push_back(arg(*it,*(it+1)));
}
}
}
void add(const std::vector<arg>& a_args){
std::vector<arg>::const_iterator it;
for(it=a_args.begin();it!=a_args.end();++it) m_args.push_back(*it);
tools_vforcit(arg,a_args,it) m_args.push_back(*it);
}
int remove(const std::string& a_key){
@@ -175,6 +183,13 @@ public:
return true;
}
bool prog_name(std::string& a_value){
if(m_args.empty()) {a_value.clear();return false;}
if(m_args[0].second.size()) {a_value.clear();return false;}
a_value = m_args[0].first;
return true;
}
bool file(std::string& a_file) const {
std::string slast;
std::string s;
@@ -251,12 +266,10 @@ public:
a_argv = 0;
}
bool known_options(const std::vector<std::string>& a_opts) const {
for(std::vector<arg>::const_iterator it = m_args.begin();
it!=m_args.end();++it) {
tools_vforcit(arg,m_args,it) {
if((*it).first.find('-')==0) { //find '-' at first pos.
bool found = false;
for(std::vector<std::string>::const_iterator it2 = a_opts.begin();
it2!=a_opts.end();++it2) {
tools_vforcit(std::string,a_opts,it2) {
if((*it).first==(*it2)) {
found = true;
break;
@@ -295,8 +308,7 @@ public:
//NOTE : print is a Python keyword.
void dump(std::ostream& a_out) const {
for(std::vector<arg>::const_iterator it = m_args.begin();
it!=m_args.end();++it) {
tools_vforcit(arg,m_args,it) {
a_out << "key = " << sout((*it).first)
<< " value = " << sout((*it).second)
<< std::endl;
@@ -455,8 +467,7 @@ inline std::string gui_toolkit(args& a_args,bool a_rm_in_args){
return driver;
}
inline void window_size_from_args(const args& a_args,
unsigned int& a_ww,unsigned int& a_wh) {
inline void window_size_from_args(const args& a_args,unsigned int& a_ww,unsigned int& a_wh) {
// return some common window size (in pixels).
if(a_args.is_arg("-iPod")||a_args.is_arg("-iPhone")) {
a_ww = 320;
@@ -467,6 +478,9 @@ inline void window_size_from_args(const args& a_args,
} else if(a_args.is_arg("-iPhone4")) {
a_ww = 640;
a_wh = 960;
} else if(a_args.is_arg("-wallino")) { //emulate LAL/wallino aspect ratio.
a_ww = 1024;
a_wh = 512;
} else if(a_args.is_arg("-SGS")) { //Samsung Galaxy S
//a_ww = 320;
//a_wh = 533;
@@ -489,9 +503,16 @@ inline void window_size_from_args(const args& a_args,
}
}
if(a_args.is_arg("-land")){
unsigned int tmp = a_ww;
a_ww = a_wh;
a_wh = tmp;
unsigned int _ww = a_ww;
unsigned int _wh = a_wh;
a_ww = mx(_ww,_wh);
a_wh = mn(_ww,_wh);
}
if(a_args.is_arg("-portrait")){
unsigned int _ww = a_ww;
unsigned int _wh = a_wh;
a_ww = mn(_ww,_wh);
a_wh = mx(_ww,_wh);
}
}
+623
View File
@@ -0,0 +1,623 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_array
#define tools_array
#ifdef TOOLS_MEM
#include "mem"
#endif
#include <vector>
#include <string>
namespace tools {
// array handles an hyperparallelepiped of cells of class T.
template <class T>
class array {
public:
static const std::string& s_class() {
static const std::string s_v("tools::array");
return s_v;
}
public:
typedef typename std::vector< std::pair<unsigned int,unsigned int> > cut_t;
typedef typename std::vector<unsigned int> uints_t;
typedef typename std::vector<T>::iterator vec_it_t;
typedef typename std::vector<T>::const_iterator cons_vec_it_t;
public:
array() {
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
array(const uints_t& a_orders) {
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
configure(a_orders);
}
array(unsigned int a_dimension,unsigned int a_order) {
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
// A hypercube of dimension "a_dimension" and size "a_order".
uints_t _orders(a_dimension);
for(unsigned int index=0;index<a_dimension;index++)
_orders[index] = a_order;
configure(_orders);
}
virtual ~array() {
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
array(const array& a_from)
:m_orders(a_from.m_orders)
,m_offsets(a_from.m_offsets)
,m_vector(a_from.m_vector)
,m_is(a_from.m_is){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
array& operator=(const array& a_from) {
m_orders = a_from.m_orders;
m_offsets = a_from.m_offsets;
m_vector = a_from.m_vector;
m_is = a_from.m_is;
return *this;
}
public: //operators:
array& operator*=(const T& a_T) {multiply(a_T);return *this;}
bool operator==(const array& a_array) const {
return equal(a_array);
}
bool operator!=(const array& a_array) const {
return !operator==(a_array);
}
array operator*(const T& a_T) const {
array a(*this);
a.multiply(a_T);
return a;
}
// the below would need exception to do it properly.
//array operator+(const array& a_array) const {
// array a(*this);
// if(!a.add(a_array)) {} //throw
// return a;
//}
//array& operator+=(const array& a_array) {
// if(!add(a_array)) {} //throw
// return *this;
//}
public:
void copy(const array& a_from) {
m_orders = a_from.m_orders;
m_offsets = a_from.m_offsets;
m_vector = a_from.m_vector;
m_is = a_from.m_is;
}
void clear() {
m_orders.clear();
m_offsets.clear();
m_vector.clear();
m_is.clear();
}
bool configure(const uints_t& a_orders) {
m_orders = a_orders;
unsigned int dim = m_orders.size();
if(dim==0) {
clear();
return false;
}
unsigned int _size = 1;
for(unsigned int index=0;index<dim;index++) {
//if(m_orders[index]<0) {
//clear();
//return false;
//}
_size *= m_orders[index];
}
m_vector.resize(_size,zero());
m_offsets.resize(dim,0);
m_offsets[0] = 1;
for(unsigned int iaxis=1;iaxis<dim;iaxis++)
m_offsets[iaxis] = m_offsets[iaxis-1] * m_orders[iaxis-1];
m_is.resize(dim,0);
return true;
}
unsigned int dimension() const { return m_orders.size();}
const uints_t& orders() const { return m_orders;}
unsigned int size() const {return m_vector.size();}
bool set_value(const uints_t& a_is,const T& a_value) {
unsigned int off = 0;
if(!offset(a_is,off)) return false;
m_vector[off] = a_value;
return true;
}
bool value(const uints_t& a_is,T& a_value) const {
unsigned int off = 0;
if(!offset(a_is,off)) {
a_value = 0;
return false;
}
a_value = m_vector[off];
return true;
}
T value_no_check(const uints_t& a_is) const { //TOUCHY
unsigned int off = 0;
if(!offset(a_is,off)) {}
return m_vector[off];
}
void reset() {
for(vec_it_t it=m_vector.begin();it!=m_vector.end();++it) *it = 0;
}
const std::vector<T>& vector() const { return m_vector;}
std::vector<T>& vector() { return m_vector;}
bool fill(const std::vector<T>& a_values,cut_t* a_cut = 0) {
unsigned int dsize = a_values.size();
unsigned int di = 0;
unsigned int index = 0;
for(vec_it_t it=m_vector.begin();it!=m_vector.end();++it,index++) {
if(!a_cut || (a_cut && accept(index,*a_cut)) ) {
if(di>=dsize) return false; //a_values exhausted too early
*it = a_values[di];
di++;
}
}
return true;
}
bool fill(unsigned int a_sz,const T* a_data,cut_t* a_cut = 0) {
unsigned int di = 0;
unsigned int index = 0;
for(vec_it_t it=m_vector.begin();it!=m_vector.end();++it,index++) {
if(!a_cut || (a_cut && accept(index,*a_cut)) ) {
if(di>=a_sz) return false; //a_values exhausted too early
*it = a_data[di];
di++;
}
}
return true;
}
// Related to other array :
bool equal(const array& a_array) const {
if(m_orders!=a_array.m_orders) return false;
cons_vec_it_t it = m_vector.begin();
cons_vec_it_t ait = a_array.m_vector.begin();
for(;it!=m_vector.end();++it,++ait) {
if((*it)!=(*ait)) return false;
}
return true;
}
bool equal(const array& a_array,T aEpsilon) const {
if(m_orders!=a_array.m_orders) return false;
cons_vec_it_t it = m_vector.begin();
cons_vec_it_t ait = a_array.m_vector.begin();
for(;it!=m_vector.end();++it,++ait) {
T diff = (*it) - (*ait);
if(diff<0) diff *= -1;
if(diff>=aEpsilon) return false;
}
return true;
}
bool is_proportional(const array& a_array,T& a_factor) const {
// If true, then : a_array = a_factor * this.
a_factor = zero();
if(m_orders!=a_array.m_orders) return false;
bool first = true;
cons_vec_it_t it = m_vector.begin();
cons_vec_it_t ait = a_array.m_vector.begin();
for(;it!=m_vector.end();++it,++ait) {
if( ((*it)==zero()) && ((*ait)==zero())) {
continue;
} else if( ((*it)!=zero()) && ((*ait)==zero())) {
return false;
} else if( ((*it)==zero()) && ((*ait)!=zero())) {
return false;
} else {
if(first) {
a_factor = (*ait)/(*it);
first = false;
} else {
if((*ait)!=(*it)*a_factor) return false;
}
}
}
return true;
}
bool add(const array& a_array,cut_t* a_cut = 0) {
if(m_orders!=a_array.m_orders) return false;
vec_it_t it = m_vector.begin();
cons_vec_it_t ait = a_array.m_vector.begin();
unsigned int index = 0;
for(;it!=m_vector.end();++it,++ait,index++) {
if(!a_cut || (a_cut && accept(index,*a_cut)) ) {
(*it) += (*ait);
}
}
return true;
}
bool subtract(const array& a_array) {
if(m_orders!=a_array.m_orders) return false;
vec_it_t it = m_vector.begin();
cons_vec_it_t ait = a_array.m_vector.begin();
for(;it!=m_vector.end();++it,++ait) (*it) -= (*ait);
return true;
}
bool multiply(const array& a_array) {
if(m_orders!=a_array.m_orders) return false;
vec_it_t it = m_vector.begin();
cons_vec_it_t ait = a_array.m_vector.begin();
for(;it!=m_vector.end();++it,++ait) (*it) *= (*ait);
return true;
}
bool divide(const array& a_array) {
if(m_orders!=a_array.m_orders) return false;
bool status = true;
vec_it_t it = m_vector.begin();
cons_vec_it_t ait = a_array.m_vector.begin();
for(;it!=m_vector.end();++it,++ait) {
if((*ait)==zero()) {
(*it) = zero(); //PAW convention.
status = false;
} else {
(*it) /= (*ait);
}
}
return status;
}
bool contract(const array& a_array,T& a_value) const {
a_value = zero();
if(m_orders!=a_array.m_orders) return false;
cons_vec_it_t it = m_vector.begin();
cons_vec_it_t ait = a_array.m_vector.begin();
for(;it!=m_vector.end();++it,++ait) a_value += (*it) * (*ait);
return true;
}
//Else:
void add(const T& a_T,cut_t* a_cut = 0) {
unsigned int index = 0;
for(vec_it_t it = m_vector.begin();it!=m_vector.end();++it,index++) {
if(!a_cut || (a_cut && accept(index,*a_cut)) ) {
(*it) += a_T;
}
}
}
void multiply(const T& a_T) {
for(vec_it_t it = m_vector.begin();it!=m_vector.end();++it) (*it) *= a_T;
}
bool divide(const T& a_T) {
if(a_T==zero()) return false;
for(vec_it_t it = m_vector.begin();it!=m_vector.end();++it) (*it) /= a_T;
return true;
}
bool invert() {
bool status = true;
T v_one = one();
for(vec_it_t it = m_vector.begin();it!=m_vector.end();++it) {
if((*it)==zero()) {
(*it) = zero(); //PAW convention.
status = false;
} else {
T _value = (*it);
(*it) = v_one/_value;
}
}
return status;
}
bool offset(const uints_t& a_is,unsigned int& a_offset) const {
unsigned int dim = m_orders.size();
a_offset = 0;
if(a_is.size()!=dim) return false;
if(dim==0) return false;
for(unsigned int iaxis=0;iaxis<dim;iaxis++) {
unsigned int i = a_is[iaxis];
if(i>=m_orders[iaxis]) {
a_offset = 0;
return false;
}
a_offset += i * m_offsets[iaxis];
}
return true;
}
bool indices(unsigned int a_offset,uints_t& a_is) const {
if(a_offset>=m_vector.size()) return false;
unsigned int dim = m_orders.size();
unsigned int off = a_offset;
for(int iaxis=dim-1;iaxis>=0;iaxis--) {
a_is[iaxis] = off/m_offsets[iaxis];
off -= a_is[iaxis] * m_offsets[iaxis];
}
return true;
}
bool accept(unsigned int a_index,const cut_t& a_cut) const {
unsigned int dim = m_orders.size();
if(a_cut.size()!=dim) return false;
if(!indices(a_index,const_cast<uints_t&>(m_is))) return false;
bool good = true;
for(unsigned int iaxis=0;iaxis<dim;iaxis++) {
if(m_is[iaxis]<a_cut[iaxis].first) {good = false;break;}
if(m_is[iaxis]>a_cut[iaxis].second) {good = false;break;}
}
return good;
}
void set_constant(const T& a_v) {
for(vec_it_t it = m_vector.begin();it!=m_vector.end();++it) (*it) = a_v;
}
void set_zero(){
set_constant(zero());
}
public:
static T zero() {
//return (T)0;
//return T(0);
return T();
}
static T one() {
//return (T)1;
return T(1);
}
static T minus_one() {
//return (T)-1;
return T(-1);
}
static T two() {
//return (T)2;
return T(2);
}
protected:
uints_t m_orders;
uints_t m_offsets;
std::vector<T> m_vector;
uints_t m_is;
};
}
#include <ostream>
// Helpers array<T> :
namespace tools {
template <class T>
inline bool contract(
const array<T>& aA
,unsigned int aIA
,const array<T>& aB
,unsigned int aIB
,array<T>& aR
){
// Contract a tensor (aA) with a vector (aB)
// on indice aIA of aA and aIB of aB.
// aA.dimension must be > 1.
// aB.dimension must be > 1.
if(&aR==&aA) return false;
if(&aR==&aB) return false;
if(aA.dimension()==0) return false;
if(aB.dimension()==0) return false;
if(aIA>=aA.dimension()) return false;
if(aIB>=aB.dimension()) return false;
if(aA.orders()[aIA]!=aB.orders()[aIB]) return false;
unsigned int rdima = aA.dimension()-1;
unsigned int rdimb = aB.dimension()-1;
if((rdima+rdimb)==0) {
std::vector<unsigned int> rorders(1);
rorders[0] = 1;
if(!aR.configure(rorders)) return false;
const std::vector<T>& vA = aA.vector();
const std::vector<T>& vB = aB.vector();
T value = array<T>::zero();
for(unsigned int index=0;index<vA.size();index++) {
value += vA[index]*vB[index];
}
aR.vector()[0] = value;
return true;
}
std::vector<unsigned int> rorders(rdima+rdimb);
unsigned int index;
for(index=0;index<aIA;index++)
rorders[index] = aA.orders()[index];
for(index=aIA;index<rdima;index++)
rorders[index] = aA.orders()[index+1];
for(index=0;index<aIB;index++)
rorders[rdima+index] = aB.orders()[index];
for(index=aIB;index<rdimb;index++)
rorders[rdima+index] = aB.orders()[index+1];
if(!aR.configure(rorders)) return false;
std::vector<unsigned int> ais(aA.dimension());
std::vector<unsigned int> bis(aB.dimension());
std::vector<unsigned int> ris(aR.dimension());
//FIXME : optimize the below.
unsigned int order = aA.orders()[aIA];
unsigned int rsize = aR.size();
std::vector<T>& rvec = aR.vector();
for(unsigned int roffset=0;roffset<rsize;roffset++) {
if(!aR.indices(roffset,ris)) return false;
for(index=0;index<aIA;index++) ais[index] = ris[index];
for(index=aIA;index<rdima;index++) ais[index+1] = ris[index];
for(index=0;index<aIB;index++) bis[index] = ris[rdima+index];
for(index=aIB;index<rdimb;index++) bis[index+1] = ris[rdima+index];
T value = 0;
for(index=0;index<order;index++) {
ais[aIA] = index;
T av;
if(!aA.value(ais,av)) return false;
bis[aIB] = index;
T bv;
if(!aB.value(bis,bv)) return false;
value += av * bv;
}
rvec[roffset] = value;
}
return true;
}
template <class T>
inline bool swap(
const array<T>& aV
,unsigned int aI1
,unsigned int aI2
,array<T>& aR
){
if(&aR==&aV) return false;
unsigned int dim = aV.dimension();
if(aI1>=dim) return false;
if(aI2>=dim) return false;
if(aI1==aI2) {
aR.copy(aV);
return true;
}
if(!aR.configure(aV.orders())) return false;
std::vector<unsigned int> vis(aV.dimension());
std::vector<unsigned int> ris(aV.dimension());
const std::vector<T>& vvec = aV.vector();
unsigned int size = aV.size();
for(unsigned int offset=0;offset<size;offset++) {
T value = vvec[offset];
if(!aV.indices(offset,vis)) return false;
unsigned int i = vis[aI1];
vis[aI1] = vis[aI2];
vis[aI2] = i;
if(!aR.set_value(vis,value)) return false;
}
return true;
}
//NOTE : print is a Python keyword.
template <class T>
inline void dump(std::ostream& a_out,const tools::array<T>& a_array,const std::string& a_title){
if(a_title.size()) a_out << a_title << std::endl;
const std::vector<T>& vec = a_array.vector();
typedef typename std::vector<T>::const_iterator cons_vec_it_t;
for(cons_vec_it_t it = vec.begin();it!=vec.end();++it) {
a_out << (*it) << std::endl;
}
}
template <class T>
inline void diff(std::ostream& a_out,const array<T>& aA,const array<T>& aB,T a_epsilon){
if(aA.orders()!=aB.orders()) {
a_out << "tools::arrays::diff : not same orders" << std::endl;
return;
}
bool header_done = false;
unsigned int dim = aA.dimension();
std::vector<unsigned int> is(dim);
unsigned int vsize = aA.vector().size();
for(unsigned int index=0;index<vsize;index++) {
T diff = aA.vector()[index]-aB.vector()[index];
if(diff<0) diff *= -1;
if(diff>=a_epsilon) {
aA.indices(index,is);
if(!header_done) {
a_out << "tools::arrays::diff :" << std::endl;
header_done = true;
}
for(unsigned int i=0;i<dim;i++) a_out << is[i] << " ";
a_out << aA.vector()[index] << " " << aB.vector()[index] << std::endl;
}
}
}
//////////////////////////////////////////////////////////////////////////////
/// common array /////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
template <class T>
class kronecker : public array<T> {
public:
kronecker(unsigned int a_order):array<T>(a_order,a_order){
// epsilon(i1,i2,....in) with n = a_order and i in [0,n[.
// Then an Array of a_order * a_order.
unsigned int index = 0;
typedef typename std::vector<unsigned int> _uints_t;
_uints_t is(a_order);
std::vector<T>& vec = array<T>::vector();
typedef typename std::vector<T>::iterator _vec_it_t;
_vec_it_t it = vec.begin();
for(;it!=vec.end();++it,index++) {
if(!array<T>::indices(index,is)) return; //FIXME throw.
bool good = true;
{for(unsigned int iaxis=0;iaxis<a_order;iaxis++) {
unsigned int ival = is[iaxis];
for(unsigned int iaxis2=iaxis+1;iaxis2<a_order;iaxis2++) {
if(is[iaxis2]==ival) {
good = false;
break;
}
}
if(!good) break;
}}
if(!good) continue;
// All indicies are different.
unsigned int n = 0;
for(unsigned int iaxis=0;iaxis<a_order;) {
unsigned int ival = is[iaxis];
if(ival!=iaxis) {
// Swap and add one permutation :
unsigned int old = is[ival];
is[ival] = ival;
is[iaxis] = old;
n +=1;
} else {
iaxis++;
}
}
{unsigned int n_2 = n/2;
if(2*n_2==n) (*it) = array<T>::one();
else (*it) = array<T>::minus_one();}
}
}
};
template <class T>
inline array<T> operator+(const array<T>& a1,const array<T>& a2) {
array<T> res(a1);
if(!res.add(a2)) {}
return res;
}
template <class T>
inline array<T> operator-(const array<T>& a1,const array<T>& a2) {
array<T> res(a1);
if(!res.subtract(a2)) {}
return res;
}
template <class T>
inline array<T> operator*(const T& a_fac,const array<T>& a_m) {
array<T> res(a_m);
res *= a_fac;
return res;
}
}
#endif
@@ -0,0 +1,21 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_chars
#define tools_chars
namespace tools {
// some char ASCII code :
// \0 : 0
// \n = LF : 10
// \r = CR : 13
// \t = HT : 9
// , : 44
inline char LF() {return 10;}
inline char CR() {return 13;}
}
#endif
@@ -47,6 +47,9 @@ namespace tools {
template <class T>
inline cid _cid(const std::vector<T>&) {return 20+_cid(T());}
template <class T>
inline cid _cid_std_vector() {return 20+_cid(T());}
// Then : cid for std::vector< std::vector<T> > is going to be :
// 20+_cid(std::vector<T>) = 2*20+_cid(T)
@@ -55,4 +58,30 @@ inline cid _cid(const std::vector<T>&) {return 20+_cid(T());}
}
namespace tools {
inline bool cid2s(cid a_id,std::string& a_s) {
// NOTE : the returned string must not contain space.
if(a_id==_cid(char(0))) {a_s = "char";return true;}
else if(a_id==_cid(short(0))) {a_s = "short";return true;}
else if(a_id==_cid(int(0))) {a_s = "int";return true;}
else if(a_id==_cid(float(0))) {a_s = "float";return true;}
else if(a_id==_cid(double(0))) {a_s = "double";return true;}
else if(a_id==_cid(std::string())) {a_s = "string";return true;}
// NOTE : the below do not follow the AIDA convention.
else if(a_id==_cid((unsigned char)0)) {a_s = "uchar";return true;} //AIDA=byte
else if(a_id==_cid((unsigned short)0)) {a_s = "ushort";return true;} //AIDA not defined
else if(a_id==_cid((unsigned int)0)) {a_s = "uint";return true;} //AIDA not defined
else if(a_id==_cid(bool(true))) {a_s = "bool";return true;} //AIDA=boolean
else if(a_id==_cid(int64(0))) {a_s = "int64";return true;} //AIDA=long
else if(a_id==_cid(uint64(0))) {a_s = "uint64";return true;} //AIDA=not defined
a_s.clear();
return false;
}
}
#endif
@@ -0,0 +1,54 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_cmathT
#define tools_cmathT
#include <cmath>
namespace tools {
//NOTE : const <type>& in args to be compatible and efficient with inlib::symbol.
//float
inline float _pow(const float& a_x,const float& a_y) {return ::powf(a_x,a_y);}
inline float _exp(const float& a_x) {return ::expf(a_x);}
inline float _log(const float& a_x) {return ::logf(a_x);}
inline float _sqrt(const float& a_x) {return ::sqrtf(a_x);}
inline float _cos(const float& a_x) {return ::cosf(a_x);}
inline float _sin(const float& a_x) {return ::sinf(a_x);}
inline float _fabs(const float& a_x) {return ::fabsf(a_x);}
inline float _tan(const float& a_x) {return ::tanf(a_x);}
inline void _half_pi(float& a_v) {a_v = float(1.5707963267948965580E0);}
inline void _pi(float& a_v) {a_v = float(3.1415926535897931160E0);}
//double
inline double _pow(const double& a_x,const double& a_y) {return ::pow(a_x,a_y);}
inline double _exp(const double& a_x) {return ::exp(a_x);}
inline double _log(const double& a_x) {return ::log(a_x);}
inline double _sqrt(const double& a_x) {return ::sqrt(a_x);}
inline double _cos(const double& a_x) {return ::cos(a_x);}
inline double _sin(const double& a_x) {return ::sin(a_x);}
inline double _fabs(const double& a_x) {return ::fabs(a_x);}
inline double _tan(const double& a_x) {return ::tan(a_x);}
inline void _half_pi(double& a_v) {a_v = 1.5707963267948965580E0;}
inline void _pi(double& a_v) {a_v = 3.1415926535897931160E0;}
//long double
#ifndef ANDROID
inline long double _pow(const long double& a_x,const long double& a_y) {return ::powl(a_x,a_y);}
inline long double _exp(const long double& a_x) {return ::expl(a_x);}
inline long double _log(const long double& a_x) {return ::logl(a_x);}
inline long double _sqrt(const long double& a_x) {return ::sqrtl(a_x);}
inline long double _cos(const long double& a_x) {return ::cosl(a_x);}
inline long double _sin(const long double& a_x) {return ::sinl(a_x);}
inline long double _fabs(const long double& a_x) {return ::fabsl(a_x);}
inline long double _tan(const long double& a_x) {return ::tanl(a_x);}
inline void _half_pi(long double& a_v) {a_v = 1.5707963267948965580E0;}
inline void _pi(long double& a_v) {a_v = 3.1415926535897931160E0;}
#endif
}
#endif
@@ -0,0 +1,607 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_columns
#define tools_columns
#include <vector>
#include <ostream>
#include "forit"
#ifdef TOOLS_MEM
#include "mem"
#include "S_STRING"
#endif
namespace tools {
namespace columns {
class tree {
#ifdef TOOLS_MEM
TOOLS_SCLASS(tools::columns::tree)
#endif
public:
tree(tree* a_parent):m_parent(a_parent){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~tree(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
tree(const tree& a_from)
:m_dcl(a_from.m_dcl)
,m_sub(a_from.m_sub)
,m_parent(a_from.m_parent)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
tree& operator=(const tree& a_from) {
if(&a_from==this) return *this;
m_dcl = a_from.m_dcl;
m_sub = a_from.m_sub;
m_parent = a_from.m_parent;
return *this;
}
public:
void clear(){
m_dcl.clear();
tools_vforit(tree,m_sub,it) (*it).clear();
}
void dump_tree(std::ostream& a_out,const std::string& a_margin) {
#ifdef WIN32
if(m_dcl.size()) a_out << a_margin.c_str() << m_dcl.c_str() << std::endl;
#else
if(m_dcl.size()) a_out << a_margin << m_dcl << std::endl;
#endif
{tools_vforit(tree,m_sub,it) {
#ifdef WIN32
std::string s = a_margin;s += " ";
(*it).dump_tree(a_out,s);
#else
(*it).dump_tree(a_out,a_margin+" ");
#endif
}}
}
public:
std::string m_dcl;
std::vector<tree> m_sub;
tree* m_parent;
};
}}
#include "strip"
namespace tools {
namespace columns {
class parser {
public:
parser():m_top(0){}
virtual ~parser(){m_top.clear();}
protected:
parser(const parser& a_from):m_top(a_from.m_top){}
parser& operator=(const parser&){return *this;}
public:
bool parse(const std::string& a_s){
m_top.clear();
tree* prev = &m_top;
{tree tmp(0);
std::string s;
for(std::string::const_iterator it=a_s.begin();;++it) {
if(it==a_s.end()) {
if(s.size()) {
tmp.m_dcl = s;
tmp.m_parent = prev;
prev->m_sub.push_back(tmp);
s.clear();
}
tmp.clear();
break;
} else {
const char& c = *it;
if(c==',') {
if(s.size()) {
tmp.m_dcl = s;
tmp.m_parent = prev;
prev->m_sub.push_back(tmp);
s.clear();
}
tmp.clear();
} else if(c=='{') {
tmp.clear();
if(s.size()) {
tmp.m_dcl = s;
s.clear();
}
tmp.m_parent = prev;
prev->m_sub.push_back(tmp);
prev = &(prev->m_sub.back());
} else if(c=='}') {
if(s.size()) {
tmp.m_dcl = s;
tmp.m_parent = prev;
prev->m_sub.push_back(tmp);
s.clear();
}
tmp.clear();
prev = prev->m_parent;
if(!prev) return false; //should not happen.
} else {
s += c;
}
}
}}
return true;
}
void dump(std::ostream& a_out) {m_top.dump_tree(a_out,"");}
protected:
tree m_top;
};
}}
#include "words"
#include "value"
namespace tools {
namespace columns {
inline void delete_columns(std::vector<value>& a_vars) {
tools_vforit(value,a_vars,it) {
if((*it).type()==value::VOID_STAR) {
std::vector<value>* vars =
(std::vector<value>*)(*it).get_void_star();
delete_columns(*vars);
delete vars;
}
}
a_vars.clear();
}
inline void copy_columns(const std::vector<value>& a_from,
std::vector<value>& a_to) {
std::vector<value>::const_iterator it;
for(it=a_from.begin();it!=a_from.end();++it) {
if((*it).type()==value::VOID_STAR) {
std::vector<value>* vars = new std::vector<value>();
value v((void*)vars);
v.set_label((*it).label());
a_to.push_back(v);
std::vector<value>* p =
(std::vector<value>*)(*it).get_void_star();
copy_columns(*p,*vars);
} else {
a_to.push_back(*it);
}
}
}
inline void dump_columns(std::ostream& a_out,
const std::vector<value>& a_vars,
const std::string& a_margin = "") {
std::vector<value>::const_iterator it;
for(it=a_vars.begin();it!=a_vars.end();++it) {
if((*it).type()==value::VOID_STAR) {
a_out << a_margin
<< "ITuple : " << (*it).label() << " : begin "
<< std::endl;
std::vector<value>* vars =
(std::vector<value>*)(*it).get_void_star();
dump_columns(a_out,*vars,a_margin+" ");
//a_out << a_margin
// << "ITuple : " << (*it).label() << " : end "
// << std::endl;
} else {
//(*it).print(a_out);
std::string stype;
(*it).s_type(stype);
std::string sval;
(*it).tos(sval);
a_out << a_margin
<< stype << " : "
<< (*it).label() << " : "
<< sval
<< std::endl;
}
}
}
class finder : public tools::columns::parser {
public:
finder(std::ostream& a_out,const std::string& a_script)
:m_out(a_out)
,m_script(a_script)
//,fSuccess(false)
,m_cur_type(value::NONE)
{}
virtual ~finder() {clear();}
protected:
finder(const finder& a_from):parser(a_from),m_out(a_from.m_out){}
finder& operator=(const finder&){return *this;}
public:
//void setScript(const std::string& a_string) { m_script = a_string;}
bool find_variables() {
clear();
if(m_script.empty()) return false; //keep old version logic.
if(!parse(m_script)) return false;
//dump(m_out);
//analyse m_top :
if(!analyse(m_top,m_stack)) {clear();return false;}
return true;
}
std::vector<value> result() const {
std::vector<value> vars;
copy_columns(m_stack,vars);
return vars;
}
void clear() {
m_top.clear();
delete_columns(m_stack);
m_cur_type = value::NONE;
}
/*
const std::string& script() const { return m_script;}
std::string script() { return m_script;}
//bool isSuccess() const { return fSuccess;}
std::ostream& out() const {return m_out;}
*/
protected:
bool analyse(tools::columns::tree& a_tree,
std::vector<value>& a_stack) {
if(a_tree.m_dcl.empty()) { //top
//std::cout << "debug : dcl empty" << std::endl;
tools_vforit(tools::columns::tree,a_tree.m_sub,it) {
if(!analyse(*it,a_stack)) return false;
}
} else {
//std::cout << "debug : dcl not empty" << std::endl;
value* v = analyse_dcl(a_tree.m_dcl);
if(!v) return false;
//std::cout << "debug : dcl label " << v->label() << std::endl;
if(a_tree.m_sub.size()) {
if(v->type()!=value::VOID_STAR) {
m_out << "tools::columns::finder::analyse :"
<< " Expect a VOID_STAR."
<< std::endl;
delete v;
return false;
}
m_cur_type = value::NONE;
std::vector<value>* stk = new std::vector<value>();
tools_vforit(tools::columns::tree,a_tree.m_sub,it) {
if(!analyse(*it,*stk)) {
delete v;
return false;
}
}
v->set((void*)stk);
} else {
m_cur_type = v->type();
}
a_stack.push_back(*v);
delete v;
}
return true;
}
value* analyse_dcl(const std::string& a_s) {
std::vector<std::string> words;
tools::words(a_s,"=",false,words);
if(words.size()==2) { //<type> <name>=<value>
std::vector<std::string> swords;
tools::words(words[0]," ",false,swords);
if(swords.size()==2) {
tools::strip(swords[0]);
tools::strip(swords[1]);
if(swords[0]=="ITuple") {
//create a value::VOID_STAR :
value* v = new value((void*)0);
v->set_label(swords[1]);
return v;
} else {
value::e_type type;
if(!s2type(swords[0],type)){
m_out << "tools::columns::finder::analyse_dcl :"
<< " s2type failed for " << tools::sout(swords[0]) << "."
<< std::endl;
return 0;
}
tools::strip(words[1]);
value* v = new_value(type,words[1]);
if(!v) {
m_out << "tools::columns::finder::analyse_dcl :"
<< " syntax error in " << tools::sout(a_s) << "."
<< " new_value() failed."
<< std::endl;
return 0;
}
v->set_label(swords[1]);
return v;
}
} else if(swords.size()==1) {
if(m_cur_type==value::NONE) {
m_out << "tools::columns::finder::analyse_dcl :"
<< " (1) current type is NONE."
<< std::endl;
return 0;
}
tools::strip(words[1]);
value* v = new_value(m_cur_type,words[1]);
if(!v) {
m_out << "tools::columns::finder::analyse_dcl :"
<< " syntax error in " << tools::sout(a_s) << "."
<< " Bad value " << tools::sout(words[1]) << "."
<< std::endl;
return 0;
}
v->set_label(swords[0]);
return v;
} else {
m_out << "tools::columns::finder::analyse_dcl :"
<< " syntax error in " << tools::sout(a_s)
<< ". Case 1."
<< std::endl;
return 0;
}
} else if(words.size()==1) {
//<type> <name>
//<type> <name>={
std::vector<std::string> swords;
tools::words(words[0]," ",false,swords);
if(swords.size()==2) {
tools::strip(swords[0]);
tools::strip(swords[1]);
if(swords[0]=="ITuple") {
//create a value::VOID_STAR :
value* v = new value((void*)0);
v->set_label(swords[1]);
return v;
} else {
value::e_type type;
if(!s2type(swords[0],type)){
m_out << "tools::columns::finder::analyse_dcl :"
<< " s2type failed for " << tools::sout(swords[0]) << "."
<< std::endl;
return 0;
}
value* v = new_value(type,"");
if(!v) {
m_out << "tools::columns::finder::analyse_dcl :"
<< " (2) syntax error in " << tools::sout(words[0]) << "."
<< " Unknown type " << tools::sout(swords[0]) << "."
<< std::endl;
return 0;
}
v->set_label(swords[1]);
return v;
}
} else if(swords.size()==1) {
if(m_cur_type==value::NONE) {
m_out << "tools::columns::finder::analyse_dcl :"
<< " (1) current type is NONE."
<< std::endl;
return 0;
}
value* v = new value();
v->set_type(m_cur_type);
v->set_label(swords[0]);
return v;
} else {
m_out << "tools::columns::finder::analyse_dcl :"
<< " syntax error in " << tools::sout(a_s)
<< ". Case 2."
<< std::endl;
return 0;
}
} else {
m_out << "tools::columns::finder::analyse_dcl :"
<< " syntax error in " << tools::sout(a_s)
<< ". Case 3."
<< std::endl;
return 0;
}
}
protected:
static bool s2type(const std::string& a_s,
value::e_type& a_type){
if(a_s=="float") {
a_type = value::FLOAT;
} else if(a_s=="double") {
a_type = value::DOUBLE;
//} else if(a_s=="char") {
// a_type = value::CHAR;
} else if(a_s=="short") {
a_type = value::SHORT;
} else if(a_s=="int") {
a_type = value::INT;
} else if(a_s=="long") {
a_type = value::INT64;
} else if((a_s=="bool")||(a_s=="boolean")) {
a_type = value::BOOL;
} else if((a_s=="string")||(a_s=="java.lang.String")){
a_type = value::STRING;
//} else if(a_s=="byte") {
// a_type = value::UNSIGNED_CHAR;
} else if(a_s=="float[]") {
a_type = value::ARRAY_FLOAT;
} else if(a_s=="double[]") {
a_type = value::ARRAY_DOUBLE;
//} else if(a_s=="char[]") {
// a_type = value::ARRAY_CHAR;
//} else if(a_s=="byte[]") {
// a_type = value::ARRAY_UNSIGNED_CHAR;
} else if(a_s=="short[]") {
a_type = value::ARRAY_SHORT;
} else if(a_s=="int[]") {
a_type = value::ARRAY_INT;
} else if(a_s=="long[]") {
a_type = value::ARRAY_INT64;
} else if((a_s=="bool[]")||(a_s=="boolean[]")) {
a_type = value::ARRAY_BOOL;
} else if((a_s=="string[]")||(a_s=="java.lang.String[]")){
a_type = value::ARRAY_STRING;
// not AIDA :
//} else if(a_s=="uchar") {
// a_type = value::UNSIGNED_CHAR;
} else if(a_s=="ushort") {
a_type = value::UNSIGNED_SHORT;
} else if(a_s=="uint") {
a_type = value::UNSIGNED_INT;
} else if(a_s=="ulong") {
a_type = value::UNSIGNED_INT64;
} else {
return false;
}
return true;
}
static value* new_value(value::e_type a_type,
const std::string& a_v) {
if(a_type==value::FLOAT) {
float v = 0;
if(a_v.size()) {if(!tools::to<float>(a_v,v)) return 0;}
return new value(v);
} else if(a_type==value::DOUBLE) {
double v = 0;
if(a_v.size()) {if(!tools::to<double>(a_v,v)) return 0;}
return new value(v);
//} else if(a_type==value::CHAR) {
// char v = 0;
// if(a_v.size()) {if(!tools::to<char>(a_v,v)) return 0;}
// return new value(v);
} else if(a_type==value::SHORT) {
short v = 0;
if(a_v.size()) {if(!tools::to<short>(a_v,v)) return 0;}
return new value(v);
} else if(a_type==value::INT) {
int v = 0;
if(a_v.size()) {if(!tools::to<int>(a_v,v)) return 0;}
return new value(v);
} else if(a_type==value::INT64) {
int64 v = 0;
if(a_v.size()) {if(!tools::to<int64>(a_v,v)) return 0;}
return new value(v);
} else if(a_type==value::BOOL) {
bool v = false;
if(a_v.size()) {if(!tools::to(a_v,v)) return 0;}
return new value(v);
} else if(a_type==value::STRING) {
if( (a_v.size()>=2) && (a_v[0]=='"') && (a_v[a_v.size()-1]=='"') ){
return new value(a_v.substr(1,a_v.size()-2));
} else {
return new value(a_v);
}
//} else if(a_type==value::UNSIGNED_CHAR) {
// unsigned short v = 0;
// if(a_v.size()) {if(!tools::to<unsigned short>(a_v,v)) return 0;}
// return new value((unsigned char)v);
} else if(a_type==value::UNSIGNED_SHORT) {
unsigned short v = 0;
if(a_v.size()) {if(!tools::to<unsigned short>(a_v,v)) return 0;}
return new value(v);
} else if(a_type==value::UNSIGNED_INT) {
unsigned int v = 0;
if(a_v.size()) {if(!tools::to<unsigned int>(a_v,v)) return 0;}
return new value(v);
} else if(a_type==value::UNSIGNED_INT64) {
uint64 v = 0;
if(a_v.size()) {if(!tools::to<uint64>(a_v,v)) return 0;}
return new value(v);
} else if(a_type==value::ARRAY_FLOAT) {
if(a_v.size()) return 0;
value* v = new value();
v->set_type(value::ARRAY_FLOAT);
return v;
} else if(a_type==value::ARRAY_DOUBLE) {
if(a_v.size()) return 0;
value* v = new value();
v->set_type(value::ARRAY_DOUBLE);
return v;
//} else if(a_type==value::ARRAY_UNSIGNED_CHAR) {
// if(a_v.size()) return 0;
// value* v = new value();
// v->set_type(value::ARRAY_UNSIGNED_CHAR);
// return v;
//} else if(a_type==value::ARRAY_CHAR) {
// if(a_v.size()) return 0;
// value* v = new value();
// v->set_type(value::ARRAY_CHAR);
// return v;
} else if(a_type==value::ARRAY_SHORT) {
if(a_v.size()) return 0;
value* v = new value();
v->set_type(value::ARRAY_SHORT);
return v;
} else if(a_type==value::ARRAY_INT) {
if(a_v.size()) return 0;
value* v = new value();
v->set_type(value::ARRAY_INT);
return v;
} else if(a_type==value::ARRAY_INT64) {
if(a_v.size()) return 0;
value* v = new value();
v->set_type(value::ARRAY_INT64);
return v;
} else if(a_type==value::ARRAY_BOOL) {
if(a_v.size()) return 0;
value* v = new value();
v->set_type(value::ARRAY_BOOL);
return v;
} else if(a_type==value::ARRAY_STRING) {
if(a_v.size()) return 0;
value* v = new value();
v->set_type(value::ARRAY_STRING);
return v;
} else {
return 0;
}
}
public:
std::ostream& m_out;
std::string m_script;
std::vector<value> m_stack;
value::e_type m_cur_type;
//bool fSuccess;
};
}}
#endif
+595
View File
@@ -0,0 +1,595 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_file
#define tools_file
#include "gzip"
#include "forit"
#include <vector>
#include <cstdlib>
#include <cstring>
#include "path" //suffix
#include "S_STRING"
#ifdef TOOLS_MEM
#include "mem"
#endif
namespace tools {
namespace file {
inline bool exists(const std::string& a_string) {
FILE* file = ::fopen(a_string.c_str(),"rb");
if(!file) return false;
::fclose(file);
return true;
}
inline bool size(const std::string& a_file,long& a_size){
FILE* file = ::fopen(a_file.c_str(),"rb");
if(!file) {
a_size = 0L;
return false;
}
//::rewind(file);
::fseek(file,0L,SEEK_END);
a_size = ::ftell(file);
::fclose(file);
return true;
}
inline bool is_empty(const std::string& a_file){
long sz;
if(!size(a_file,sz)) return true; //if not existing, consider it empty.
return (sz==0L)?true:false;
}
inline bool write(const std::string& a_file,const std::string& a_string) {
// a_string could contain \n separated lines.
FILE* file = ::fopen(a_file.c_str(),"wb");
if(!file) return false;
if(::fprintf(file,"%s",a_string.c_str())<0) {
::fclose(file);
return false;
}
::fclose(file);
return true;
}
inline bool write(const std::string& a_file,const std::vector<std::string>& a_text){
FILE* file = ::fopen(a_file.c_str(),"wb");
if(!file) return false;
tools_vforcit(std::string,a_text,it) {
if(::fprintf(file,"%s\n",(*it).c_str())<0) {
::fclose(file);
return false;
}
}
::fclose(file);
return true;
}
inline bool read_buff(FILE* a_file,char* a_buff,unsigned int a_lbuf,size_t& a_length) {
a_length = ::fread(a_buff,1,a_lbuf,a_file);
return true;
}
inline bool read_cstring(FILE* a_file,char* a_buff,unsigned int a_lbuf,size_t& a_length) {
if(::fgets(a_buff,a_lbuf,a_file)==NULL) {
a_length = 0;
return false; //EOF
}
size_t l = ::strlen(a_buff);
// On Windows, editors when saving binary files,
// put \r\n at place of \n ; we then look for \r\n.
if( (l>=2) && (a_buff[l-2]=='\r') && (a_buff[l-1]=='\n') ) {
a_buff[l-2] = '\0';
l -= 2;
} else if( (l>=1) && (a_buff[l-1]=='\n') ) {
a_buff[l-1] = '\0';
l -= 1;
}
a_length = l;
return true;
}
inline bool read(const std::string& a_file,std::vector<std::string>& a_text){
a_text.clear();
FILE* file = ::fopen(a_file.c_str(),"rb");
if(!file) return false;
unsigned int BUFSIZE = 65536;
char* buffer = new char[BUFSIZE+1];
if(!buffer) {::fclose(file);return false;}
while(true) {
size_t l;
if(!read_cstring(file,buffer,BUFSIZE,l)) break; // EOF.
a_text.push_back(buffer);
}
delete [] buffer;
::fclose(file);
return true;
}
inline bool read_num(const std::string& a_file,std::vector<std::string>::size_type a_num,std::vector<std::string>& a_text,const std::string& a_cmt = ""){
a_text.clear();
FILE* file = ::fopen(a_file.c_str(),"rb");
if(!file) return false;
unsigned int BUFSIZE = 65536;
char* buffer = new char[BUFSIZE+1];
if(!buffer) {::fclose(file);return false;}
while(true) {
size_t l;
if(!read_cstring(file,buffer,BUFSIZE,l)) break; // EOF.
if(a_cmt.size()&&(!strncmp(a_cmt.c_str(),buffer,a_cmt.size()))) continue;
if(a_text.size()<a_num) {
a_text.push_back(buffer);
} else {
break;
}
}
delete [] buffer;
::fclose(file);
return true;
}
inline bool read_bytes(const std::string& a_file,
char*& a_buffer,long& a_length){
// Returned buffer should be deleted with delete [].
FILE* file = ::fopen(a_file.c_str(),"rb");
if(!file) {
a_buffer = 0;
a_length = 0L;
return false;
}
// Get file size :
::fseek(file,0L,SEEK_END);
long filesize = ::ftell(file);
if(!filesize) {
::fclose(file);
a_buffer = new char[1];
#ifdef TOOLS_MEM
mem::increment(s_new().c_str());
#endif
a_length = 0L;
return true; //empty file.
}
// Add one byte to be able to add \n if file contain lines.
a_buffer = new char[filesize+1];
if(!a_buffer) {
::fclose(file);
a_buffer = 0;
a_length = 0L;
return false;
}
#ifdef TOOLS_MEM
mem::increment(s_new().c_str());
#endif
::rewind(file);
size_t nitem = ::fread(a_buffer,(size_t)filesize,(size_t)1,file);
if(nitem!=1){
::fclose(file);
delete [] a_buffer;
#ifdef TOOLS_MEM
mem::decrement(s_new().c_str());
#endif
a_buffer = 0;
a_length = 0L;
return false;
}
::fclose(file);
a_buffer[filesize] = 0;
a_length = filesize;
return true;
}
inline bool write_bytes(const std::string& a_file,const char* a_buffer,size_t a_length){
FILE* file = ::fopen(a_file.c_str(),"wb");
if(!file) return false;
if(!a_length) {
::fclose(file);
return true;
}
size_t nitem = ::fwrite((char*)a_buffer,a_length,(size_t)1,file);
::fclose(file);
return (nitem!=1?false:true);
}
inline bool is_aida(const std::string& a_file,bool& a_is){
long sz;
if(!size(a_file,sz)) {a_is = false;return false;}
//NOTE : it assumes that the file is not compressed.
unsigned char head[1024];
{unsigned int num = 1024;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=1024) {a_is = false;return true;}}
head[1023] = 0; //to have a C string.
a_is = ::strstr((const char*)head,"<aida")?true:false;
return true;
}
// NOTE : take care of the open in exlib/app/Wt/main_cpp which can't work
// by using suffix.
// NOTE : the below is_csv() does not take into account a column with strings.
inline bool is_csv(const std::vector<std::string>& a_txt,bool& a_is){
//a_sep = 0;
a_is = false;
if(a_txt.empty()) return true;
//guess sep from first data line :
char sep = 0;
{const char* buffer = a_txt[0].c_str();
//::printf("debug : |%s|\n",buffer);
const char* pos = buffer;
char* end;
{double d = ::strtod(pos,&end);(void)d;}
//::printf("debug : d first %g\n",d);
if(end==pos) return true; //not starting with a number.
//end==mx is ok, one column only.
sep = *end;}
//::printf("debug : %d\n",sep);
unsigned int first_coln = 0;
tools_vforcit(std::string,a_txt,it) {
const char* buffer = (*it).c_str();
//::printf("debug : |%s|\n",buffer);
const char* pos = buffer;
const char* mx = buffer+(*it).size();
unsigned int coln = 0;
while(true) {
char* end;
{double d = ::strtod(pos,&end);(void)d;}
if(end==pos) break;
//::printf("debug : d %g\n",d);
if(*end!=sep) return true;
coln++;
pos = end+1;
if(pos>mx) break;
}
//::printf("debug : coln %d\n",coln);
if(it==a_txt.begin()) {
first_coln = coln;
} else {
if(coln!=first_coln) return true;
}
}
//a_sep = sep;
a_is = true;
return true;
}
inline bool is_csv(const std::string& a_file,bool& a_is){
// look at suffix. Some file can't be guessed.
if(suffix(a_file)=="csv") {a_is = true;return true;}
//try to guess :
std::vector<std::string> txt;
if(!file::read_num(a_file,3,txt,"#")) {a_is=false;return false;}
return is_csv(txt,a_is);
}
inline bool is_hippo(const std::string& a_file,bool& a_is){
//if((suffix(a_file)=="hiptxt")||(suffix(a_file)=="tnt")) {
// a_is = true;
// return true;
//}
std::vector<std::string> txt;
if(!file::read_num(a_file,5,txt)) return false;
//skip two first lines (title and labels).
std::vector<std::string> htxt;
for(unsigned int i=2;i<txt.size();i++) htxt.push_back(txt[i]);
return is_csv(htxt,a_is);
}
}}
#include "fileis"
namespace tools {
namespace file {
inline bool mime_type(const std::string& a_file,std::string& a_mime){
////////////////
// binaries :
////////////////
{bool is;
if(is_jpeg(a_file,is)&&is) {
a_mime = "image/jpeg";
return true;
}}
{bool is;
if(is_png(a_file,is)&&is) {
a_mime = "image/png";
return true;
}}
{bool is;
if(is_fits(a_file,is)&&is) {
a_mime = "image/fits";
return true;
}}
{bool is;
if(is_gzip(a_file,is)&&is) {
a_mime = "application/gzip";
return true;
}}
{bool is;
if(is_zip(a_file,is)&&is) {
a_mime = "application/zip";
return true;
}}
{bool is;
if(is_root(a_file,is)&&is) {
a_mime = "application/octet-stream";
return true;
}}
////////////////
// text :
////////////////
{bool is;
if(is_aida(a_file,is)&&is) {
a_mime = "text/xml";
return true;
}}
{bool is;
if(is_exsg(a_file,is)&&is) {
a_mime = "text/xml";
return true;
}}
{bool is;
if(is_scenarios(a_file,is)&&is) {
a_mime = "text/xml";
return true;
}}
{bool is;
if(is_slides(a_file,is)&&is) {
a_mime = "text/xml";
return true;
}}
{bool is;
if(is_gdml(a_file,is)&&is) {
a_mime = "text/xml";
return true;
}}
{bool is;
if(is_ps(a_file,is)&&is) {
a_mime = "application/postscript";
return true;
}}
{bool is;
if(is_fog(a_file,is)&&is) {
a_mime = "text/plain";
return true;
}}
{bool is;
if(is_csv(a_file,is)&&is) {
a_mime = "text/csv";
return true;
}}
{bool is;
if(is_hippo(a_file,is)&&is) {
a_mime = "text/plain";
return true;
}}
{bool is;
if(is_dot(a_file,is)&&is) {
a_mime = "text/plain";
return true;
}}
{bool is;
if(is_iv(a_file,is)&&is) {
a_mime = "application/octet-stream";
return true;
}}
a_mime = "application/octet-stream";
return false;
}
/*
inline bool copy(const std::string& a_from,const std::string& a_to){
if(a_to==a_from) return true; //done
std::vector<std::string> text;
if(!file::read(a_from,text)) return false;
return file::write(a_to,text);
}
*/
inline bool found(const std::string& a_file,const std::string& a_what,std::vector<std::string>& a_found){
a_found.clear();
std::vector<std::string> text;
if(!file::read(a_file,text)) return false;
tools_vforcit(std::string,text,it) {
if((*it).find(a_what)!=std::string::npos) {
a_found.push_back(*it);
}
}
return true;
}
inline bool std_remove(const std::string& a_file) {
if(a_file.empty()) return true;
return (::remove(a_file.c_str()) ==0 ? true : false);
}
inline bool std_remove(std::vector<std::string>& a_files) {
bool status = true;
tools_vforit(std::string,a_files,it) {
if(!std_remove(*it)) status = false;
}
a_files.clear();
return status;
}
inline bool std_rename(const std::string& a_from,const std::string& a_to) {
//NOTE : a_from must not be a path !
// Darwin is ok with a path but not Linux !
// For example :
// ::rename("/tmp/tmp01"."x");
// return -1 on Linux.
// To do the upper then someone must use move.
// But there is no move in the standard lib C !
return (::rename(a_from.c_str(),a_to.c_str()) == 0 ? true : false);
}
//////////////////////////////////////////////////////////////////////////////
/// by using C system ////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
inline std::string quote(const std::string& a_path) {
if(a_path.find(' ')==std::string::npos) return a_path;
// path with spaces :
if(a_path[0]=='"') return a_path; //Already in double quote.
return std::string("\"")+a_path+"\"";
}
// used in OnX/BaseUI.
inline bool mv(const std::string& a_from,const std::string& a_to){
if(a_to==a_from) return true;
#ifdef WIN32
std::string cmd = "MOVE /Y";
#else
std::string cmd = "/bin/mv";
#endif
cmd += " ";
cmd += quote(a_from);
cmd += " ";
cmd += quote(a_to);
int ret = ::system(cmd.c_str());
return (ret==(-1)?false:true);
}
inline bool cp(const std::string& a_from,const std::string& a_to) {
if(a_to==a_from) return true;
#ifdef WIN32
std::string cmd = "COPY /Y";
#else
std::string cmd = "/bin/cp";
#endif
cmd += " ";
cmd += quote(a_from);
cmd += " ";
cmd += quote(a_to);
int ret = ::system(cmd.c_str());
return (ret==(-1)?false:true);
}
inline bool rm(const std::string& a_file){
// WARNING : do not confuse with file::std_remove which is
// an encapsulation of the remove of stdio.h that
// does not support wildcards.
#ifdef WIN32
std::string cmd = "DEL /Q";
#else
std::string cmd = "/bin/rm -f";
#endif
cmd += " ";
cmd += quote(a_file);
int ret = ::system(cmd.c_str());
return (ret==(-1)?false:true);
}
/*
class holder {
public:
TOOLS_SCLASS(tools::file::holder)
public:
holder(const std::string& a_path):m_path(a_path){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~holder() {
std_remove(m_path);
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
holder(const holder& a_from):m_path(a_from.m_path){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
holder& operator=(const holder& a_from){
m_path = a_from.m_path;
return *this;
}
protected:
std::string m_path;
};
*/
}}
#include "file_reader"
namespace tools {
class FILE_reader : public virtual file::reader {
public: //file_reader
virtual bool open(const std::string& a_file) {
if(m_FILE) return false;
m_FILE = ::fopen(a_file.c_str(),"rb");
if(!m_FILE) return false;
return true;
}
virtual void close() {
if(!m_FILE) return;
::fclose(m_FILE);
m_FILE = 0;
}
virtual bool is_open() const {return m_FILE?true:false;}
virtual bool read(char* a_buff,unsigned int a_lbuf,size_t& a_length) {
a_length = ::fread(a_buff,1,a_lbuf,m_FILE);
return true;
}
virtual bool get_line(char* a_buff,unsigned int a_lbuf) {
return ::fgets(a_buff,a_lbuf,m_FILE)==NULL?false:true;
}
virtual bool eof() const {
#if defined(_MSC_VER) && _MSC_VER <= 1400
return feof(m_FILE)?true:false;
#else
return ::feof(m_FILE)?true:false;
#endif
}
public:
FILE_reader():m_FILE(0){}
virtual ~FILE_reader() {if(m_FILE) ::fclose(m_FILE);}
protected:
FILE_reader(const FILE_reader& a_from)
:file::reader(a_from)
,m_FILE(0)
{}
FILE_reader& operator=(const FILE_reader&){return *this;}
protected:
FILE* m_FILE;
};
}
#include "file_format" //backcomp
#endif
@@ -0,0 +1,121 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_file_format
#define tools_file_format
#include "S_STRING"
#include <string>
#include <vector>
namespace tools {
namespace file {
TOOLS_GLOBAL_STRING(format_guessed)
TOOLS_GLOBAL_STRING(format_hdf5)
TOOLS_GLOBAL_STRING(format_fits)
TOOLS_GLOBAL_STRING(format_fog)
TOOLS_GLOBAL_STRING(format_dot)
TOOLS_GLOBAL_STRING(format_dcm)
TOOLS_GLOBAL_STRING(format_iv)
TOOLS_GLOBAL_STRING(format_jpeg)
TOOLS_GLOBAL_STRING(format_png)
TOOLS_GLOBAL_STRING(format_root)
TOOLS_GLOBAL_STRING(format_csv)
TOOLS_GLOBAL_STRING(format_hippo)
TOOLS_GLOBAL_STRING(format_scenarios)
TOOLS_GLOBAL_STRING(format_slides)
TOOLS_GLOBAL_STRING(format_zvid)
TOOLS_GLOBAL_STRING(format_exsg)
TOOLS_GLOBAL_STRING(format_gdml)
TOOLS_GLOBAL_STRING(format_mac)
TOOLS_GLOBAL_STRING(format_cmnd)
TOOLS_GLOBAL_STRING(format_aida)
TOOLS_GLOBAL_STRING(format_bsg)
#define TOOLS_GLOBAL_EXT(a_name)\
inline const std::string& s_ext_##a_name() {\
static const std::string s_v("."+std::string(#a_name));\
return s_v;\
}
TOOLS_GLOBAL_EXT(hdf5)
TOOLS_GLOBAL_EXT(fits)
TOOLS_GLOBAL_EXT(fog)
TOOLS_GLOBAL_EXT(dot)
TOOLS_GLOBAL_EXT(dcm)
TOOLS_GLOBAL_EXT(iv)
TOOLS_GLOBAL_EXT(hiv)
TOOLS_GLOBAL_EXT(jpg)
TOOLS_GLOBAL_EXT(png)
TOOLS_GLOBAL_EXT(root)
TOOLS_GLOBAL_EXT(csv)
TOOLS_GLOBAL_EXT(hiptxt)
TOOLS_GLOBAL_EXT(tnt)
TOOLS_GLOBAL_EXT(scenarios)
TOOLS_GLOBAL_EXT(slides)
TOOLS_GLOBAL_EXT(zvid)
TOOLS_GLOBAL_EXT(exsg)
TOOLS_GLOBAL_EXT(gdml)
TOOLS_GLOBAL_EXT(mac)
TOOLS_GLOBAL_EXT(cmnd)
TOOLS_GLOBAL_EXT(aida)
TOOLS_GLOBAL_EXT(bsg)
#undef TOOLS_GLOBAL_EXT
inline void formats(std::vector<std::string>& a_v) {
a_v.clear();
a_v.push_back(s_format_guessed());
a_v.push_back(s_format_hdf5());
a_v.push_back(s_format_fits());
a_v.push_back(s_format_fog());
a_v.push_back(s_format_dot());
a_v.push_back(s_format_dcm());
a_v.push_back(s_format_iv());
a_v.push_back(s_format_jpeg());
a_v.push_back(s_format_png());
a_v.push_back(s_format_root());
a_v.push_back(s_format_csv());
a_v.push_back(s_format_hippo());
a_v.push_back(s_format_scenarios());
a_v.push_back(s_format_slides());
a_v.push_back(s_format_zvid());
a_v.push_back(s_format_exsg());
a_v.push_back(s_format_bsg());
a_v.push_back(s_format_gdml());
a_v.push_back(s_format_mac());
a_v.push_back(s_format_cmnd());
a_v.push_back(s_format_aida());
}
inline std::string ext_fmt(const std::string& a_ext) {
if(a_ext==s_ext_fits()) return s_format_fits();
if(a_ext==s_ext_aida()) return s_format_aida();
if(a_ext==s_ext_root()) return s_format_root();
if(a_ext==s_ext_csv()) return s_format_csv();
if(a_ext==s_ext_tnt()) return s_format_hippo();
if(a_ext==s_ext_hiptxt()) return s_format_hippo();
if(a_ext==s_ext_hdf5()) return s_format_hdf5();
if(a_ext==s_ext_jpg()) return s_format_jpeg();
if(a_ext==s_ext_png()) return s_format_png();
if(a_ext==s_ext_fog()) return s_format_fog();
if(a_ext==s_ext_dot()) return s_format_dot();
if(a_ext==s_ext_dcm()) return s_format_dcm();
if(a_ext==s_ext_iv()) return s_format_iv();
if(a_ext==s_ext_hiv()) return s_format_iv();
if(a_ext==s_ext_exsg()) return s_format_exsg();
if(a_ext==s_ext_bsg()) return s_format_bsg();
if(a_ext==s_ext_scenarios()) return s_format_scenarios();
if(a_ext==s_ext_slides()) return s_format_slides();
if(a_ext==s_ext_zvid()) return s_format_zvid();
if(a_ext==s_ext_gdml()) return s_format_gdml();
if(a_ext==s_ext_mac()) return s_format_mac();
if(a_ext==s_ext_cmnd()) return s_format_cmnd();
return s_format_guessed();
}
}}
#endif
@@ -0,0 +1,27 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_file_reader
#define tools_file_reader
#include <string>
#include <cstdio>
namespace tools {
namespace file {
class reader {
public:
virtual ~reader() {}
public:
virtual bool open(const std::string&) = 0;
virtual void close() = 0;
virtual bool is_open() const = 0;
virtual bool read(char*,unsigned int,size_t&) = 0;
virtual bool get_line(char*,unsigned int) = 0;
virtual bool eof() const = 0;
};
}}
#endif
@@ -0,0 +1,246 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_fileis
#define tools_fileis
#include "signature"
#include <cstring>
namespace tools {
namespace file {
inline bool is_zip(const std::string& a_file,bool& a_is){
unsigned char head[4];
{unsigned int num = 4;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=4) {a_is = false;return true;}}
if(head[0]!='P') {a_is = false;return true;}
if(head[1]!='K') {a_is = false;return true;}
if(head[2]!=3) {a_is = false;return true;}
if(head[3]!=4) {a_is = false;return true;}
a_is = true;
return true;
}
inline bool is_jpeg(const std::string& a_file,bool& a_is){
unsigned char head[4];
{unsigned int num = 4;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=4) {a_is = false;return true;}}
if(head[0]!=255) {a_is = false;return true;}
if(head[1]!=216) {a_is = false;return true;}
if(head[2]!=255) {a_is = false;return true;}
//if(head[3]!=224) {a_is = false;return true;} //LRI.jpg is 225 !
a_is = true;
return true;
}
inline bool is_png(const std::string& a_file,bool& a_is){
unsigned char head[4];
{unsigned int num = 4;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=4) {a_is = false;return true;}}
if(head[0]!=137) {a_is = false;return true;}
if(head[1]!='P') {a_is = false;return true;}
if(head[2]!='N') {a_is = false;return true;}
if(head[3]!='G') {a_is = false;return true;}
a_is = true;
return true;
}
inline bool is_root(const std::string& a_file,bool& a_is){
unsigned char head[4];
{unsigned int num = 4;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=4) {a_is = false;return true;}}
if(head[0]!='r') {a_is = false;return true;}
if(head[1]!='o') {a_is = false;return true;}
if(head[2]!='o') {a_is = false;return true;}
if(head[3]!='t') {a_is = false;return true;}
// Aie, we are in a mess.
a_is = true;
return true;
}
inline bool is_iv(const std::string& a_file,bool& a_is){
unsigned char head[9];
{unsigned int num = 9;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=9) {a_is = false;return true;}}
if(head[0]!='#') {a_is = false;return true;}
if(head[1]!='I') {a_is = false;return true;}
if(head[2]!='n') {a_is = false;return true;}
if(head[3]!='v') {a_is = false;return true;}
if(head[4]!='e') {a_is = false;return true;}
if(head[5]!='n') {a_is = false;return true;}
if(head[6]!='t') {a_is = false;return true;}
if(head[7]!='o') {a_is = false;return true;}
if(head[8]!='r') {a_is = false;return true;}
a_is = true;
return true;
}
inline bool is_fog(const std::string& a_file,bool& a_is){
unsigned char head[256];
{unsigned int num = 256;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=256) {a_is = false;return true;}}
head[255] = 0; //to have a C string.
a_is = ::strstr((const char*)head,"#nb super-volumes")?true:false;
return true;
}
inline bool is_dot(const std::string& a_file,bool& a_is){
unsigned char head[8];
{unsigned int num = 7;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=7) {a_is = false;return true;}}
head[7] = 0; //to have a C string.
a_is = ::strcmp((const char*)head,"digraph")?false:true;
return true;
}
inline bool is_dcm(const std::string& a_file,bool& a_is){
unsigned char head[132];
{unsigned int num = 132;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=132) {a_is = false;return true;}}
if(head[128]!='D') {a_is = false;return true;}
if(head[129]!='I') {a_is = false;return true;}
if(head[130]!='C') {a_is = false;return true;}
if(head[131]!='M') {a_is = false;return true;}
a_is = true;
return true;
}
inline bool is_gdml(const std::string& a_file,bool& a_is){
//NOTE : it assumes that the file is not compressed.
unsigned char head[1024];
{unsigned int num = 1024;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=1024) {a_is = false;return true;}}
head[1023] = 0; //to have a C string.
a_is = ::strstr((const char*)head,"<gdml")?true:false;
return true;
}
inline bool is_exsg(unsigned int a_sz,const char* a_buffer){
if(a_sz<5) return false;
if(a_buffer[0]!='<') return false;
if(a_buffer[1]!='e') return false;
if(a_buffer[2]!='x') return false;
if(a_buffer[3]!='s') return false;
if(a_buffer[4]!='g') return false;
return true;
}
inline bool is_exsg(const std::string& a_file,bool& a_is){
unsigned char head[5];
{unsigned int num = 5;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=5) {a_is = false;return true;}}
a_is = is_exsg(5,(const char*)head);
return true;
}
inline bool is_bsg(unsigned int a_sz,const char* a_buffer){
if(a_sz<7) return false;
if(a_buffer[0]!='i') return false;
if(a_buffer[1]!='n') return false;
if(a_buffer[2]!='e') return false;
if(a_buffer[3]!='x') return false;
if(a_buffer[4]!='b') return false;
if(a_buffer[5]!='s') return false;
if(a_buffer[6]!='g') return false;
return true;
}
inline bool is_bsg(const std::string& a_file,bool& a_is){
unsigned char head[7];
{unsigned int num = 7;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=7) {a_is = false;return true;}}
a_is = is_bsg(7,(const char*)head);
return true;
}
inline bool is_scenarios(const std::string& a_file,bool& a_is){
unsigned char head[10];
{unsigned int num = 10;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=10) {a_is = false;return true;}}
if(head[0]!='<') {a_is = false;return true;}
if(head[1]!='s') {a_is = false;return true;}
if(head[2]!='c') {a_is = false;return true;}
if(head[3]!='e') {a_is = false;return true;}
if(head[4]!='n') {a_is = false;return true;}
if(head[5]!='a') {a_is = false;return true;}
if(head[6]!='r') {a_is = false;return true;}
if(head[7]!='i') {a_is = false;return true;}
if(head[8]!='o') {a_is = false;return true;}
if(head[9]!='s') {a_is = false;return true;}
a_is = true;
return true;
}
inline bool is_slides(const std::string& a_file,bool& a_is){
unsigned char head[7];
{unsigned int num = 7;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=7) {a_is = false;return true;}}
if(head[0]!='<') {a_is = false;return true;}
if(head[1]!='s') {a_is = false;return true;}
if(head[2]!='l') {a_is = false;return true;}
if(head[3]!='i') {a_is = false;return true;}
if(head[4]!='d') {a_is = false;return true;}
if(head[5]!='e') {a_is = false;return true;}
if(head[6]!='s') {a_is = false;return true;}
a_is = true;
return true;
}
inline bool is_fits(const std::string& a_file,bool& a_is){
unsigned char head[6];
{unsigned int num = 6;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=6) {a_is = false;return true;}}
if(head[0]!='S') {a_is = false;return true;}
if(head[1]!='I') {a_is = false;return true;}
if(head[2]!='M') {a_is = false;return true;}
if(head[3]!='P') {a_is = false;return true;}
if(head[4]!='L') {a_is = false;return true;}
if(head[5]!='E') {a_is = false;return true;}
a_is = true;
return true;
}
inline bool is_hdf(const std::string& a_file,bool& a_is){
unsigned char head[4];
{unsigned int num = 4;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=4) {a_is = false;return true;}}
if(head[0]!=137) {a_is = false;return true;}
if(head[1]!='H') {a_is = false;return true;}
if(head[2]!='D') {a_is = false;return true;}
if(head[3]!='F') {a_is = false;return true;}
a_is = true;
return true;
}
inline bool is_ps(const std::string& a_file,bool& a_is){
unsigned char head[4];
{unsigned int num = 4;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=4) {a_is = false;return true;}}
if(head[0]!='%') {a_is = false;return true;}
if(head[1]!='!') {a_is = false;return true;}
if(head[2]!='P') {a_is = false;return true;}
if(head[3]!='S') {a_is = false;return true;}
a_is = true;
return true;
}
}}
#endif
@@ -0,0 +1,52 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_forit
#define tools_forit
#define tools_vforcit(a__T,a__v,a__it) \
for(std::vector< a__T >::const_iterator (a__it) = (a__v).begin();\
(a__it)!=(a__v).end();++(a__it))
#define tools_vforit(a__T,a__v,a__it) \
for(std::vector< a__T >::iterator (a__it) = (a__v).begin();\
(a__it)!=(a__v).end();++(a__it))
#define tools_typename_vforcit(a__T,a__v,a__it_t,a__it) \
typedef typename std::vector< a__T >::const_iterator a__it_t;\
for(a__it_t (a__it) = (a__v).begin();(a__it)!=(a__v).end();++(a__it))
#define tools_sforcit(a__s,a__it) \
for(std::string::const_iterator (a__it) = (a__s).begin();\
(a__it)!=(a__s).end();++(a__it))
#define tools_sforit(a__s,a__it) \
for(std::string::iterator (a__it) = (a__s).begin();\
(a__it)!=(a__s).end();++(a__it))
#define tools_lforcit(a__T,a__l,a__it) \
for(std::list< a__T >::const_iterator (a__it) = (a__l).begin();\
(a__it)!=(a__l).end();++(a__it))
#define tools_lforit(a__T,a__l,a__it) \
for(std::list< a__T >::iterator (a__it) = (a__l).begin();\
(a__it)!=(a__l).end();++(a__it))
#define tools_mforcit(a__K,a__V,a__m,a__it) \
for(std::map< a__K , a__V >::const_iterator (a__it) = (a__m).begin();\
(a__it)!=(a__m).end();++(a__it))
#define tools_mforit(a__K,a__V,a__m,a__it) \
for(std::map< a__K , a__V >::iterator (a__it) = (a__m).begin();\
(a__it)!=(a__m).end();++(a__it))
#define tools_typename_mforcit(a__K,a__V,a__m,a__it_t,a__it) \
typedef typename std::map< a__K, a__V >::const_iterator a__it_t;\
for(a__it_t (a__it) = (a__m).begin();(a__it)!=(a__m).end();++(a__it))
#define tools_typename_mforit(a__K,a__V,a__m,a__it_t,a__it) \
typedef typename std::map< a__K, a__V >::iterator a__it_t;\
for(a__it_t (a__it) = (a__m).begin();(a__it)!=(a__m).end();++(a__it))
#endif
@@ -0,0 +1,46 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_gzip
#define tools_gzip
#include "signature"
namespace tools {
namespace file {
inline bool is_gzip(const std::string& a_file,bool& a_is){
unsigned char head[4];
{unsigned int num = 4;
if(!signature(a_file,head,num)) {a_is = false;return false;}
if(num!=4) {a_is = false;return true;}}
if(head[0]!=31) {a_is = false;return true;}
if(head[1]!=139) {a_is = false;return true;}
//if(head[2]!=8) {a_is = false;return true;}
//if(head[3]!=8) {a_is = false;return true;}
a_is = true;
return true;
}
inline bool gzip_usize(const std::string& a_file,unsigned int& a_usz){
bool is;
if(!is_gzip(a_file,is)) {a_usz=0;return false;}
if(!is) {a_usz=0;return false;}
FILE* file = ::fopen(a_file.c_str(),"rb");
if(!file) {a_usz=0;return false;}
::fseek(file,-4,SEEK_END);
unsigned char buf[4];
size_t n = ::fread(buf,1,4,file);
::fclose(file);
if(n!=4) {a_usz=0;return false;}
unsigned int b4 = buf[0];
unsigned int b3 = buf[1];
unsigned int b2 = buf[2];
unsigned int b1 = buf[3];
a_usz = (b1 << 24) | ((b2 << 16) + (b3 << 8) + b4);
return true;
}
}}
#endif
@@ -103,3 +103,5 @@ inline bool gunzip_buffer(std::ostream& a_out,
}
#endif
//exlib_build_use inlib zlib
@@ -0,0 +1,83 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_handle
#define tools_handle
#ifdef TOOLS_MEM
#include "mem"
#endif
#include <string>
namespace tools {
class base_handle {
static const std::string& s_class() {
static const std::string s_v("tools::handle");
return s_v;
}
public:
virtual void* object() const = 0;
virtual base_handle* copy() = 0; //can't be const.
virtual void disown() = 0;
public:
base_handle(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~base_handle(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
base_handle(base_handle&){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
private:
//base_handle(const base_handle&){}
//base_handle& operator=(const base_handle&){return *this;}
base_handle& operator=(base_handle&){return *this;}
};
template <class T>
class handle : public base_handle {
typedef base_handle parent;
public:
virtual void* object() const {return m_obj;}
virtual base_handle* copy() {return new handle<T>(*this);}
virtual void disown() {m_owner = false;}
public:
handle(T* a_obj,bool a_owner = true)
:parent()
,m_obj(a_obj),m_owner(a_owner){}
virtual ~handle(){if(m_owner) delete m_obj;}
private:
handle(handle& a_from):parent(a_from){
m_obj = a_from.m_obj;
if(a_from.m_owner) {
// this take ownership.
m_owner = true;
a_from.m_owner = false;
} else {
m_owner = false;
}
//a_from.m_obj = 0; //we do not remove the obj ref in a_from.
}
private:
// in principle the below are not used.
//handle(const handle& a_from){}
//handle& operator=(const handle&){return *this;}
handle& operator=(handle&){return *this;}
protected:
T* m_obj;
bool m_owner;
};
}
#endif
@@ -53,12 +53,6 @@ extern "C" rret __stdcall HI(int*,int*);
extern "C" void __stdcall HXYIJ(int*,rarg*,rarg*,int*,int*);
extern "C" rret __stdcall HMIN(int*);
extern "C" rret __stdcall HMAX(int*);
extern "C" int __stdcall HISID(int*);
//extern "C" void __stdcall HGNF(int*,int*,rarg*,int*);
//extern "C" void __stdcall HIDALL(int*,int*);
//extern "C" void __stdcall HID1(int*,int*);
//extern "C" void __stdcall HID2(int*,int*);
//extern "C" int __stdcall HEXIST(int*);
#else
extern "C" void zitoh_(int*,int*,int*);
extern "C" void rzink_(int*,int*,const char *,int);
@@ -81,12 +75,6 @@ extern "C" rret hi_(int*,int*);
extern "C" void hxyij_(int*,rarg*,rarg*,int*,int*);
extern "C" rret hmin_(int*);
extern "C" rret hmax_(int*);
extern "C" int hisid_(int*);
//extern "C" void hgnf_(int*,int*,rarg*,int*);
//extern "C" void hidall_(int*,int*);
//extern "C" void hid1_(int*,int*);
//extern "C" void hid2_(int*,int*);
//extern "C" int hexist_(int*);
#endif
/////////////////////////////////////////////////////////////////
@@ -101,7 +89,6 @@ extern "C" void __stdcall HREND(DEFCHAR);
extern "C" void __stdcall HROUT(int*,int*,DEFCHAR);
extern "C" void __stdcall HGIVE(int*,DEFCHAR,int*,rarg*,rarg*,int*,rarg*,rarg*,int*,int*);
extern "C" void __stdcall HGIVEN(int*,DEFCHAR,int*,DEFCHAR,rarg*,rarg*);
extern "C" void __stdcall HNTVAR2(int*,int*,DEFCHAR,DEFCHAR,DEFCHAR,int*,int*,int*,int*);
extern "C" void __stdcall HBNT(int*,DEFCHAR,DEFCHAR);
extern "C" void __stdcall HBNAME(int*,DEFCHAR,int*,DEFCHAR);
extern "C" void __stdcall HBNAM(int*,DEFCHAR,int*,DEFCHAR,int*);
@@ -130,7 +117,6 @@ extern "C" void hrend_(DEFCHAR,int);
extern "C" void hrout_(int*,int*,DEFCHAR,int);
extern "C" void hgive_(int*,DEFCHAR,int*,rarg*,rarg*,int*,rarg*,rarg*,int*,int*,int);
extern "C" void hgiven_(int*,DEFCHAR,int*,DEFCHAR,rarg*,rarg*,int,int);
extern "C" void hntvar2_(int*,int*,DEFCHAR,DEFCHAR,DEFCHAR,int*,int*,int*,int*,int,int,int);
extern "C" void hbnt_(int*,DEFCHAR,DEFCHAR,int,int);
extern "C" void hbname_(int*,DEFCHAR,int*,DEFCHAR,int,int);
extern "C" void hbnam_(int*,DEFCHAR,int*,DEFCHAR,int*,int,int);
@@ -218,76 +204,6 @@ inline void CZITOH(int* a1,int* a2,int* a3) {
#endif
}
/*
inline std::vector<int> CHIDALL() {
// We should use first a function getting the number of ids only.
// See hids.f in this directory and hidall.F code.
int ids[100000];
int n;
#ifdef WIN32
HIDALL(ids,&n);
#else
hidall_(ids,&n);
#endif
std::vector<int> r;
r.resize(n,0);
for(int i=0;i<n;i++) r[i] = ids[i];
return r;
}
inline std::vector<int> CHID1() {
// We should use first a function getting the number of 1D ids only.
// See hids.f in this directory and hid1.F code.
int ids[100000];
int n;
#ifdef WIN32
HID1(ids,&n);
#else
hid1_(ids,&n);
#endif
std::vector<int> r;
r.resize(n,0);
for(int i=0;i<n;i++) r[i] = ids[i];
return r;
}
inline std::vector<int> CHID2() {
// We should use first a function getting the number of 2D ids only.
// See hids.f in this directory and hid1.F code.
int ids[100000];
int n;
#ifdef WIN32
HID2(ids,&n);
#else
hid2_(ids,&n);
#endif
std::vector<int> r;
r.resize(n,0);
for(int i=0;i<n;i++) r[i] = ids[i];
return r;
}
inline bool CHEXIST(int a_id) {
int id = a_id;
// What is the mapping of F77 LOGICAL to C ?
#ifdef WIN32
logical l = HEXIST(&id);
#else
logical l = hexist_(&id);
#endif
}
inline void CHCLR() {
// Clear //PAWC structure.
//CHCDIR("//PAWC"," ");
std::vector<std::string> drs;
CHDIRS(true,drs);
{std::vector<std::string>::iterator it;
for(it=drs.begin();it!=drs.end();++it){
std::string& dir = *it;
CHDDIR(dir);
}}
CHDELET(0);
}
*/
inline int* get_pawc() {
#ifdef WIN32
return PAWC;
@@ -417,14 +333,6 @@ inline void CHDDIR(const std::string& a1) {
#endif
}
inline bool CHISID(int a_id) {
#ifdef WIN32
return (HISID(&a_id)==1?true:false);
#else
return (hisid_(&a_id)==1?true:false);
#endif
}
inline void CHDIRS(bool a_PAWC,std::vector<std::string>& a_dirs){
a_dirs.clear();
@@ -805,52 +713,6 @@ inline void CHFNT(int a1) {
#endif
}
inline void CHNTVAR2(
int a1,int a2
,std::string& a3,std::string& a4,std::string& a5
,int& a6,int& a7,int& a8,int& a9) {
char name[32];
::memset(name,' ',sizeof(name));
name[sizeof(name)-1] = 0;
char block[32];
::memset(block,' ',sizeof(block));
block[sizeof(block)-1] = 0;
char fullname[64];
::memset(fullname,' ',sizeof(fullname));
fullname[sizeof(fullname)-1]=0;
int v6,v7,v8,v9;
#ifdef WIN32
HNTVAR2(&a1,&a2,PASSCHAR(name),PASSCHAR(fullname),PASSCHAR(block),&v6,&v7,&v8,&v9);
#else
hntvar2_(&a1,&a2,name,fullname,block,&v6,&v7,&v8,&v9,32,64,32);
#endif
int j;
for (j=30;j>0;j--) {
if (name[j] == ' ') name[j] = 0;
}
for (j=62;j>0;j--) {
if (fullname[j] == ' ') fullname[j] = 0;
}
for (j=30;j>0;j--) {
if (block[j] == ' ') block[j] = 0;
else break;
}
a3 = name;
a4 = fullname;
a5 = block;
a6 = v6;
a7 = v7;
a8 = v8;
a9 = v9;
}
inline int CHGIVEN(
int a_id
,std::string& a_title
@@ -915,18 +777,6 @@ inline int CHGNT(int a_id,int a_row){
return ier;
}
//inline int CHGNF(int a_id,int aRow,rarg* aBuffer){
// int id = a_id;
// int row = aRow;
// int ier = 0;
//#ifdef WIN32
// HGNF(&id,&row,aBuffer,&ier);
//#else
// hgnf_(&id,&row,aBuffer,&ier);
//#endif
// return ier;
//}
inline void CHOPERA(int a_id1,const std::string& a_opts,int a_id2,int a_id3,rarg a_c1,rarg a_c2) {
#ifdef WIN32
HOPERA(&a_id1,PASSCHAR(a_opts.c_str()),&a_id2,&a_id3,&a_c1,&a_c2);
@@ -1,72 +0,0 @@
/* To resolve some HBOOK entry points used in CLHEP ! */
void hlimit_(){}
void hnoent_(){}
void hgnpar_(){}
void hgnf_(){}
void hdelet_(){}
void hbookn_(){}
void hfn_(){}
void hbook2_(){}
void hbook1_(){}
void hfill_(){}
void hx_(){}
void hcdir_(){}
void hmdir_(){}
void hddir_(){}
void hbprof_(){}
void hbname_(){}
void hbnt_(){}
void hfnt_(){}
void hropen_(){}
void hrout_(){}
void hrend_(){}
void hstati_(){}
void rzcl_(){}
void zitoh_(){}
void uhtoc_(){}
void rndm_(){}
/*commons :*/
int hcbook_[51];
/*minuit :*/
void mninit_(){}
void mnparm_(){}
void mnexcm_(){}
/* to link BatchLabZebra plugin : */
void hexist_(){}
void hitoc_(){}
void hbug_(){}
void hndesc_(){}
void hdcofl_(){}
void hrin_(){}
void hldir_(){}
void hbookb_(){}
void hgive_(){}
void hi_(){}
void hie_(){}
void hij_(){}
void hije_(){}
void hix_(){}
void hijxy_(){}
void hxi_(){}
void hxyij_(){}
void hmin_(){}
void hmax_(){}
void hreset_(){}
void hbnam_(){}
void hgiven_(){}
void hgnt_(){}
void hopera_(){}
void lenocc_(){}
void locati_(){}
void rzink_(){}
@@ -1,44 +0,0 @@
SUBROUTINE HIDS(N)
IMPLICIT NONE
*.==========>
*.
*. Returns the number of all IDS.
*. Inspired from hidall.F.
*. G.Barrand.
*
*KEEP,HCBOOK.
INTEGER NWPAW,IXPAWC,IHDIV,IXHIGZ,IXKU, LMAIN
REAL FENC , HCV
COMMON/PAWC/NWPAW,IXPAWC,IHDIV,IXHIGZ,IXKU,FENC(5),LMAIN,HCV(9989)
INTEGER IQ ,LQ
REAL Q
DIMENSION IQ(2),Q(2),LQ(8000)
EQUIVALENCE (LQ(1),LMAIN),(IQ(1),LQ(9)),(Q(1),IQ(1))
INTEGER HVERSN,IHWORK,LHBOOK,LHPLOT,LGTIT,LHWORK,
+LCDIR,LSDIR,LIDS,LTAB,LCID,LCONT,LSCAT,LPROX,LPROY,LSLIX,
+LSLIY,LBANX,LBANY,LPRX,LPRY,LFIX,LLID,LR1,LR2,LNAME,LCHAR,LINT,
+LREAL,LBLOK,LLBLK,LBUFM,LBUF,LTMPM,LTMP,LTMP1,LHPLIP,LHDUM,
+LHFIT,LFUNC,LHFCO,LHFNA,LCIDN
COMMON/HCBOOK/HVERSN,IHWORK,LHBOOK,LHPLOT,LGTIT,LHWORK,
+LCDIR,LSDIR,LIDS,LTAB,LCID,LCONT,LSCAT,LPROX,LPROY,LSLIX,
+LSLIY,LBANX,LBANY,LPRX,LPRY,LFIX,LLID,LR1,LR2,LNAME,LCHAR,LINT,
+LREAL,LBLOK,LLBLK,LBUFM,LBUF,LTMPM,LTMP,LTMP1,LHPLIP,LHDUM(9),
+LHFIT,LFUNC,LHFCO,LHFNA,LCIDN
*
INTEGER KNCX ,KXMIN ,KXMAX ,KMIN1 ,KMAX1 ,KNORM , KTIT1,
+ KNCY ,KYMIN ,KYMAX ,KMIN2 ,KMAX2 ,KSCAL2 , KTIT2,
+ KNBIT ,KNOENT ,KSTAT1 ,KNSDIR ,KNRH ,
+ KCON1 ,KCON2 ,KBITS ,KNTOT
PARAMETER(KNCX=3,KXMIN=4,KXMAX=5,KMIN1=7,KMAX1=8,KNORM=9,KTIT1=10,
+ KNCY=7,KYMIN=8,KYMAX=9,KMIN2=6,KMAX2=10,KSCAL2=11,
+ KTIT2=12,KNBIT=1,KNOENT=2,KSTAT1=3,KNSDIR=5,KNRH=6,
+ KCON1=9,KCON2=3,KBITS=1,KNTOT=2)
*
*KEND.
*
INTEGER N
*
N = IQ(LCDIR+KNRH)
RETURN
END
@@ -1,10 +0,0 @@
INTEGER FUNCTION HISID(ID)
IMPLICIT NONE
INTEGER ID
LOGICAL HEXIST
IF(HEXIST(ID).EQV..TRUE.) THEN
HISID = 1
ELSE
HISID = 0
ENDIF
END
@@ -1,164 +0,0 @@
*CMZ : 2.21/05 08/02/99 11.10.43 by Rene Brun
*CMZ : 0.90/10 09/12/96 17.08.32 by Rene Brun
*-- Author : Rene Brun 09/12/96
SUBROUTINE HNTVAR2(ID1,IVAR,CHTAG,CHFULL,BLOCK,NSUB,ITYPE,ISIZE
+ ,IELEM)
*.==========>
*.
*. Returns the tag, block, type, size and array length of the
*. variable with index IVAR in N-tuple ID1.
*. N-tuple must already be in memory.
*.
*. This routine is a modification of the HBOOK routine HNTVAR.
*.
*..=========> ( R.Brun, A.A.Rademakers )
*
*KEEP,HCNTPAR.
INTEGER ZBITS, ZNDIM, ZNOENT, ZNPRIM, ZNRZB, ZIFCON,
+ ZIFNAM, ZIFCHA, ZIFINT, ZIFREA, ZNWTIT, ZITIT1,
+ ZNCHRZ, ZDESC, ZLNAME, ZNAME, ZARIND, ZRANGE, ZNADDR,
+ ZIBLOK, ZNBLOK, ZLCONT, ZIFBIT, ZIBANK, ZIFTMP, ZITMP,
+ ZID, ZNTMP, ZNTMP1, ZLINK
PARAMETER(ZBITS=1, ZNDIM=2, ZNOENT=3, ZNPRIM=4, ZLCONT=6,
+ ZNRZB=5, ZIFCON=7, ZIFNAM=4, ZIFCHA=5, ZIFINT=6,
+ ZIFREA=7, ZNWTIT=8, ZITIT1=9, ZNCHRZ=13, ZIFBIT=8,
+ ZDESC=1, ZLNAME=2, ZNAME=3, ZRANGE=4, ZNADDR=12,
+ ZARIND=11, ZIBLOK=8, ZNBLOK=10, ZIBANK=9, ZIFTMP=11,
+ ZID=12, ZITMP=10, ZNTMP=6, ZNTMP1=3, ZLINK=6)
*
*KEEP,HCFLAG.
INTEGER ID ,IDBADD,LID ,IDLAST,IDHOLD,NBIT ,NBITCH,
+ NCHAR ,NRHIST,IERR ,NV
COMMON/HCFLAG/ID ,IDBADD,LID ,IDLAST,IDHOLD,NBIT ,NBITCH,
+ NCHAR ,NRHIST,IERR ,NV
*
*KEEP,HCBOOK.
INTEGER NWPAW,IXPAWC,IHDIV,IXHIGZ,IXKU, LMAIN
REAL FENC , HCV
COMMON/PAWC/NWPAW,IXPAWC,IHDIV,IXHIGZ,IXKU,FENC(5),LMAIN,HCV(9989)
INTEGER IQ ,LQ
REAL Q
DIMENSION IQ(2),Q(2),LQ(8000)
EQUIVALENCE (LQ(1),LMAIN),(IQ(1),LQ(9)),(Q(1),IQ(1))
INTEGER HVERSN,IHWORK,LHBOOK,LHPLOT,LGTIT,LHWORK,
+LCDIR,LSDIR,LIDS,LTAB,LCID,LCONT,LSCAT,LPROX,LPROY,LSLIX,
+LSLIY,LBANX,LBANY,LPRX,LPRY,LFIX,LLID,LR1,LR2,LNAME,LCHAR,LINT,
+LREAL,LBLOK,LLBLK,LBUFM,LBUF,LTMPM,LTMP,LTMP1,LHPLIP,LHDUM,
+LHFIT,LFUNC,LHFCO,LHFNA,LCIDN
COMMON/HCBOOK/HVERSN,IHWORK,LHBOOK,LHPLOT,LGTIT,LHWORK,
+LCDIR,LSDIR,LIDS,LTAB,LCID,LCONT,LSCAT,LPROX,LPROY,LSLIX,
+LSLIY,LBANX,LBANY,LPRX,LPRY,LFIX,LLID,LR1,LR2,LNAME,LCHAR,LINT,
+LREAL,LBLOK,LLBLK,LBUFM,LBUF,LTMPM,LTMP,LTMP1,LHPLIP,LHDUM(9),
+LHFIT,LFUNC,LHFCO,LHFNA,LCIDN
*
INTEGER KNCX ,KXMIN ,KXMAX ,KMIN1 ,KMAX1 ,KNORM , KTIT1,
+ KNCY ,KYMIN ,KYMAX ,KMIN2 ,KMAX2 ,KSCAL2 , KTIT2,
+ KNBIT ,KNOENT ,KSTAT1 ,KNSDIR ,KNRH ,
+ KCON1 ,KCON2 ,KBITS ,KNTOT
PARAMETER(KNCX=3,KXMIN=4,KXMAX=5,KMIN1=7,KMAX1=8,KNORM=9,KTIT1=10,
+ KNCY=7,KYMIN=8,KYMAX=9,KMIN2=6,KMAX2=10,KSCAL2=11,
+ KTIT2=12,KNBIT=1,KNOENT=2,KSTAT1=3,KNSDIR=5,KNRH=6,
+ KCON1=9,KCON2=3,KBITS=1,KNTOT=2)
*
*KEEP,HCBITS.
INTEGER I1, I2, I3, I4, I5, I6, I7, I8,
+ I9, I10, I11, I12, I13, I14, I15, I16,
+I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27,
+I28, I29, I30, I31, I32, I33, I34, I35, I123, I230
COMMON / HCBITS / I1, I2, I3, I4, I5, I6, I7, I8,
+ I9, I10, I11, I12, I13, I14, I15, I16,
+I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27,
+I28, I29, I30, I31, I32, I33, I34, I35, I123, I230
*
*KEND.
*
CHARACTER*(*) CHTAG, CHFULL, BLOCK
CHARACTER*80 VAR
CHARACTER*32 NAME, SUBS
LOGICAL LDUM
*
ID = ID1
IDPOS = LOCATI(IQ(LTAB+1),IQ(LCDIR+KNRH),ID)
IF (IDPOS .LE. 0) THEN
CALL HBUG('Unknown N-tuple','HNTVAR',ID1)
RETURN
ENDIF
LCID = LQ(LTAB-IDPOS)
*
CHTAG = ' '
NAME = ' '
BLOCK = ' '
NSUB = 0
ITYPE = 0
ISIZE = 0
IELEM = 0
*
ICNT = 0
*
*
IF (IVAR .GT. IQ(LCID+ZNDIM)) RETURN
*
LBLOK = LQ(LCID-1)
LCHAR = LQ(LCID-2)
LINT = LQ(LCID-3)
LREAL = LQ(LCID-4)
*
*-- loop over all blocks
*
5 LNAME = LQ(LBLOK-1)
*
IOFF = 0
NDIM = IQ(LBLOK+ZNDIM)
*
DO 10 I = 1, NDIM
ICNT = ICNT + 1
IF (ICNT .EQ. IVAR) THEN
*
CALL HNDESC(IOFF, NSUB, ITYPE, ISIZE, NBITS, LDUM)
*
LL = IQ(LNAME+IOFF+ZLNAME)
LV = IQ(LNAME+IOFF+ZNAME)
CALL UHTOC(IQ(LCHAR+LV), 4, NAME, LL)
CALL UHTOC(IQ(LBLOK+ZIBLOK), 4, BLOCK, 8)
*
IELEM = 1
IF (NSUB .GT. 0) THEN
VAR = NAME(1:LL)//'['
DO 25 J = NSUB,1,-1
LP = IQ(LINT+IQ(LNAME+IOFF+ZARIND)+(J-1))
IF (LP .LT. 0) THEN
IE = -LP
CALL HITOC(IE, SUBS, LL, IERR)
ELSE
LL = IQ(LNAME+LP-1+ZLNAME)
LV = IQ(LNAME+LP-1+ZNAME)
CALL UHTOC(IQ(LCHAR+LV), 4, SUBS, LL)
LL1 = IQ(LNAME+LP-1+ZRANGE)
IE = IQ(LINT+LL1+1)
ENDIF
IELEM = IELEM*IE
IF (J .EQ. NSUB) THEN
VAR = VAR(1:LENOCC(VAR))//SUBS(1:LL)
ELSE
VAR = VAR(1:LENOCC(VAR))//']['//SUBS(1:LL)
ENDIF
25 CONTINUE
*
VAR = VAR(1:LENOCC(VAR))//']'
ELSE
VAR = NAME(1:LL)
ENDIF
CHTAG = NAME
CHFULL = VAR
RETURN
*
ENDIF
*
IOFF = IOFF + ZNADDR
10 CONTINUE
*
LBLOK = LQ(LBLOK)
IF (LBLOK .NE. 0) GOTO 5
*
END
@@ -260,4 +260,4 @@ private:
// CHCDIR("//PAWC/LUN<unit>"," ")
// CHCDIR("//LUN<unit>"," ")
//exlib_build_use inlib
@@ -95,24 +95,24 @@ public:
// and that a //<something> exists and is attached to a file.
tools::replace(m_path_file,"//PAWC","/");
cd_beg();
CHBNT(m_id,a_bkg.m_title," ");
CHBNT(m_id,a_bkg.title()," ");
cd_end();
const std::vector<tools::ntuple_booking::col_t>& cols = a_bkg.m_columns;
std::vector<tools::ntuple_booking::col_t>::const_iterator it;
const std::vector<tools::column_booking>& cols = a_bkg.columns();
std::vector<tools::column_booking>::const_iterator it;
for(it=cols.begin();it!=cols.end();++it){
if((*it).second==tools::_cid(int(0))) {
create_column<int>((*it).first);
} else if((*it).second==tools::_cid(float(0))) {
create_column<float>((*it).first);
} else if((*it).second==tools::_cid(double(0))) {
create_column<double>((*it).first);
if((*it).cls_id()==tools::_cid(int(0))) {
create_column<int>((*it).name());
} else if((*it).cls_id()==tools::_cid(float(0))) {
create_column<float>((*it).name());
} else if((*it).cls_id()==tools::_cid(double(0))) {
create_column<double>((*it).name());
} else {
a_out << "tools::hbook::wntuple :"
<< " for column " << tools::sout((*it).first)
<< ", type with cid " << (*it).second << " not yet handled."
<< " for column " << tools::sout((*it).name())
<< ", type with cid " << (*it).cls_id() << " not yet handled."
<< std::endl;
//throw
tools::clear<icol>(m_cols);
@@ -235,3 +235,5 @@ protected:
}}
#endif
//exlib_build_use inlib
@@ -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
@@ -10,14 +10,17 @@
namespace tools {
namespace histo {
//TC is for a coordinate.
enum { axis_UNDERFLOW_BIN = -2, axis_OVERFLOW_BIN = -1 }; //AIDA casing.
template <class TC>
//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 = -2, OVERFLOW_BIN = -1 }; //AIDA casing.
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;}
@@ -168,7 +171,7 @@ public:
m_edges.clear();
// setup :
if(aEdges.size()<=1) return false;
bn_t number = aEdges.size()-1;
bn_t number = (bn_t)aEdges.size()-1;
for(bn_t index=0;index<number;index++) {
if((aEdges[index]>=aEdges[index+1])) {
return false;
@@ -220,29 +223,30 @@ public:
virtual ~axis(){}
public:
axis(const axis& a_axis)
:m_offset(a_axis.m_offset)
,m_number_of_bins(a_axis.m_number_of_bins)
,m_minimum_value(a_axis.m_minimum_value)
,m_maximum_value(a_axis.m_maximum_value)
,m_fixed(a_axis.m_fixed)
,m_bin_width(a_axis.m_bin_width)
,m_edges(a_axis.m_edges)
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_axis) {
m_offset = a_axis.m_offset;
m_number_of_bins = a_axis.m_number_of_bins;
m_minimum_value = a_axis.m_minimum_value;
m_maximum_value = a_axis.m_maximum_value;
m_fixed = a_axis.m_fixed;
m_bin_width = a_axis.m_bin_width;
m_edges = a_axis.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:
bn_t m_offset;
TO m_offset;
bn_t m_number_of_bins;
TC m_minimum_value;
TC m_maximum_value;
+47 -52
View File
@@ -11,89 +11,85 @@
namespace tools {
namespace histo {
template <class TC,class TN,class TW,class TH>
class b1 : public base_histo<TC,TN,TW,TH> {
typedef base_histo<TC,TN,TW,TH> parent;
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 typename base_histo<TC,TN,TW,TH>::bn_t bn_t;
typedef histo::axis<TC,TO> axis_t;
typedef typename parent::bn_t bn_t;
public:
virtual TH bin_error(int) const = 0; //for print
public:
void update_fast_getters(){}
// 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;
//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;
//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 {
if(parent::m_bin_number==0) return 0;
bn_t offset;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,offset)) return 0;
TO offset;
if(!_find_offset(aI,offset)) return 0;
return parent::m_bin_entries[offset];
}
TW bin_Sw(int aI) const {
if(parent::m_bin_number==0) return 0;
bn_t offset;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,offset)) return 0;
TO offset;
if(!_find_offset(aI,offset)) return 0;
return parent::m_bin_Sw[offset];
}
TW bin_Sw2(int aI) const {
if(parent::m_bin_number==0) return 0;
bn_t offset;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,offset)) return 0;
TO offset;
if(!_find_offset(aI,offset)) return 0;
return parent::m_bin_Sw2[offset];
}
TC bin_Sxw(int aI) const {
if(parent::m_bin_number==0) return 0;
bn_t offset;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,offset)) return 0;
TO offset;
if(!_find_offset(aI,offset)) return 0;
return parent::m_bin_Sxw[offset][AxisX];
}
TC bin_Sx2w(int aI) const {
if(parent::m_bin_number==0) return 0;
bn_t offset;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,offset)) return 0;
TO offset;
if(!_find_offset(aI,offset)) return 0;
return parent::m_bin_Sx2w[offset][AxisX];
}
TH bin_height(int aI) const {
if(parent::m_bin_number==0) return 0;
bn_t offset;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,offset)) return 0;
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 {
if(parent::m_bin_number==0) return 0;
bn_t offset;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,offset)) return 0;
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 {
if(parent::m_bin_number==0) return 0;
bn_t offset;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,offset)) return 0;
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];
@@ -103,8 +99,8 @@ public:
}
// Axis :
const histo::axis<TC>& axis() const {return parent::m_axes[0];}
histo::axis<TC>& axis() {return parent::m_axes[0];} //touchy
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) {
@@ -113,8 +109,8 @@ public:
a_out
<< " * ENTRIES = " << parent::all_entries()
<< " * ALL CHANNELS = " << parent::sum_bin_heights()
<< " * UNDERFLOW = " << bin_height(histo::axis<TC>::UNDERFLOW_BIN)
<< " * OVERFLOW = " << bin_height(histo::axis<TC>::OVERFLOW_BIN)
<< " * UNDERFLOW = " << bin_height(axis_t::UNDERFLOW_BIN)
<< " * OVERFLOW = " << bin_height(axis_t::OVERFLOW_BIN)
<< std::endl;
a_out
<< " * BIN WID = " << axis().bin_width(0)
@@ -150,8 +146,7 @@ public:
<< std::endl;
}
protected:
b1(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax){
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);
@@ -170,15 +165,8 @@ protected:
virtual ~b1(){}
protected:
b1(const b1& a_from): parent(a_from) {
update_fast_getters();
}
b1& operator=(const b1& a_from) {
parent::operator=(a_from);
update_fast_getters();
return *this;
}
b1(const b1& a_from):parent(a_from){}
b1& operator=(const b1& a_from) {parent::operator=(a_from);return *this;}
public:
bool configure(bn_t aXnumber,TC aXmin,TC aXmax){
std::vector<bn_t> nbins;
@@ -194,7 +182,14 @@ public:
edges[0] = aEdges;
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;
}
};
}}
+61 -179
View File
@@ -11,66 +11,38 @@
namespace tools {
namespace histo {
template <class TC,class TN,class TW,class TH>
class b2 : public base_histo<TC,TN,TW,TH> {
typedef base_histo<TC,TN,TW,TH> parent;
typedef axis<TC> axis_t;
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 typename base_histo<TC,TN,TW,TH>::bn_t bn_t;
typedef axis<TC,TO> axis_t;
typedef typename parent::bn_t bn_t;
public:
virtual TH bin_error(int,int) const = 0; //for print
public:
void update_fast_getters() {
m_in_range_entries = 0;
m_in_range_Sw = 0;
m_in_range_Sxw = 0;
m_in_range_Syw = 0;
m_in_range_Sx2w = 0;
m_in_range_Sy2w = 0;
bn_t ibin,jbin,offset;
bn_t xbins = parent::m_axes[0].bins();
bn_t ybins = parent::m_axes[1].bins();
bn_t yoffset = parent::m_axes[1].m_offset;
for(ibin=1;ibin<=xbins;ibin++) {
offset = ibin + yoffset;
for(jbin=1;jbin<=ybins;jbin++) {
//offset = ibin + jbin * m_axes[1].m_offset;
m_in_range_entries += parent::m_bin_entries[offset];
m_in_range_Sw += parent::m_bin_Sw[offset];
m_in_range_Sxw += parent::m_bin_Sxw[offset][0];
m_in_range_Syw += parent::m_bin_Sxw[offset][1];
m_in_range_Sx2w += parent::m_bin_Sx2w[offset][0];
m_in_range_Sy2w += parent::m_bin_Sx2w[offset][1];
offset += yoffset;
}
}
}
// Partition :
TC mean_x() const {
if(m_in_range_Sw==0) return 0;
return m_in_range_Sxw/m_in_range_Sw;
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(m_in_range_Sw==0) return 0;
return m_in_range_Syw/m_in_range_Sw;
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(m_in_range_Sw==0) return 0;
TC mean = m_in_range_Sxw/m_in_range_Sw;
return ::sqrt(::fabs((m_in_range_Sx2w / m_in_range_Sw) - mean * mean));
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(m_in_range_Sw==0) return 0;
TC mean = m_in_range_Syw/m_in_range_Sw;
return ::sqrt(::fabs((m_in_range_Sy2w / m_in_range_Sw) - mean * mean));
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 {
@@ -82,70 +54,46 @@ public:
// bins :
TN bin_entries(int aI,int aJ) const {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
return parent::m_bin_entries[offset];
}
TW bin_Sw(int aI,int aJ) const {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
return parent::m_bin_Sw[offset];
}
TW bin_Sw2(int aI,int aJ) const {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
return parent::m_bin_Sw2[offset];
}
TC bin_Sxw(int aI,int aJ) const {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
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 {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
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 {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
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 {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
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 {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
TO offset;
if(!_find_offset(aI,aJ,offset)) return 0;
return this->get_bin_height(offset);
}
@@ -157,33 +105,24 @@ public:
}
TC bin_mean_x(int aI,int aJ) const {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
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 {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
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 {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
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];
@@ -193,11 +132,8 @@ public:
}
TC bin_rms_y(int aI,int aJ) const {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
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];
@@ -207,10 +143,10 @@ public:
}
// Axes :
const axis<TC>& axis_x() const {return parent::m_axes[0];}
const axis<TC>& axis_y() const {return parent::m_axes[1];}
axis<TC>& axis_x() {return parent::m_axes[0];} //touchy
axis<TC>& axis_y() {return parent::m_axes[1];} //touchy
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 {
@@ -218,7 +154,7 @@ public:
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 offset;
TO offset;
TN _entries = 0;
for(bn_t jbin=0;jbin<ybins;jbin++) {
offset = ibin + jbin * parent::m_axes[1].m_offset;
@@ -232,7 +168,7 @@ public:
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 offset;
TO offset;
TW sw = 0;
for(bn_t jbin=0;jbin<ybins;jbin++) {
offset = ibin + jbin * parent::m_axes[1].m_offset;
@@ -246,7 +182,7 @@ public:
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 offset;
TO offset;
TN _entries = 0;
for(bn_t ibin=0;ibin<xbins;ibin++) {
offset = ibin + jbin * parent::m_axes[1].m_offset;
@@ -260,7 +196,7 @@ public:
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 offset;
TO offset;
TW sw = 0;
for(bn_t ibin=0;ibin<xbins;ibin++) {
offset = ibin + jbin * parent::m_axes[1].m_offset;
@@ -351,16 +287,7 @@ public:
<< std::endl;
}
protected:
b2(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax,
bn_t aYnumber,TC aYmin,TC aYmax)
:m_in_range_entries(0)
,m_in_range_Sw(0)
,m_in_range_Sxw(0)
,m_in_range_Syw(0)
,m_in_range_Sx2w(0)
,m_in_range_Sy2w(0)
{
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);
@@ -374,16 +301,7 @@ protected:
parent::configure(2,nbins,mins,maxs);
}
b2(const std::string& a_title,
const std::vector<TC>& aEdgesX,
const std::vector<TC>& aEdgesY)
:m_in_range_entries(0)
,m_in_range_Sw(0)
,m_in_range_Sxw(0)
,m_in_range_Syw(0)
,m_in_range_Sx2w(0)
,m_in_range_Sy2w(0)
{
b2(const std::string& a_title,const std::vector<TC>& aEdgesX,const std::vector<TC>& aEdgesY) {
parent::m_title = a_title;
std::vector< std::vector<TC> > edges(2);
edges[0] = aEdgesX;
@@ -393,40 +311,10 @@ protected:
virtual ~b2(){}
protected:
b2(const b2& a_from)
: parent(a_from)
,m_in_range_entries(a_from.m_in_range_entries)
,m_in_range_Sw(a_from.m_in_range_Sw)
,m_in_range_Sxw(a_from.m_in_range_Sxw)
,m_in_range_Syw(a_from.m_in_range_Syw)
,m_in_range_Sx2w(a_from.m_in_range_Sx2w)
,m_in_range_Sy2w(a_from.m_in_range_Sy2w)
{
update_fast_getters();
}
b2& operator=(const b2& a_from) {
parent::operator=(a_from);
m_in_range_entries = a_from.m_in_range_entries;
m_in_range_Sw = a_from.m_in_range_Sw;
m_in_range_Sxw = a_from.m_in_range_Sxw;
m_in_range_Syw = a_from.m_in_range_Syw;
m_in_range_Sx2w = a_from.m_in_range_Sx2w;
m_in_range_Sy2w = a_from.m_in_range_Sy2w;
update_fast_getters();
return *this;
}
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){
m_in_range_entries = 0;
m_in_range_Sw = 0;
m_in_range_Sxw = 0;
m_in_range_Syw = 0;
m_in_range_Sx2w = 0;
m_in_range_Sy2w = 0;
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);
@@ -439,15 +327,7 @@ public:
return parent::configure(2,nbins,mins,maxs);
}
bool configure(const std::vector<TC>& aEdgesX,
const std::vector<TC>& aEdgesY){
m_in_range_entries = 0;
m_in_range_Sw = 0;
m_in_range_Sxw = 0;
m_in_range_Syw = 0;
m_in_range_Sx2w = 0;
m_in_range_Sy2w = 0;
bool configure(const std::vector<TC>& aEdgesX,const std::vector<TC>& aEdgesY){
std::vector< std::vector<TC> > edges(2);
edges[0] = aEdgesX;
edges[1] = aEdgesY;
@@ -455,12 +335,14 @@ public:
}
protected:
TN m_in_range_entries;
TW m_in_range_Sw;
TC m_in_range_Sxw;
TC m_in_range_Syw;
TC m_in_range_Sx2w;
TC m_in_range_Sy2w;
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;
}
};
}}
+78 -205
View File
@@ -11,56 +11,17 @@
namespace tools {
namespace histo {
template <class TC,class TN,class TW,class TH>
class b3 : public base_histo<TC,TN,TW,TH> {
typedef base_histo<TC,TN,TW,TH> parent;
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 axis<TC> axis_t;
typedef typename base_histo<TC,TN,TW,TH>::bn_t bn_t;
typedef axis<TC,TO> 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:
void update_fast_getters() {
m_in_range_entries = 0;
m_in_range_Sw = 0;
m_in_range_Sxw = 0;
m_in_range_Syw = 0;
m_in_range_Szw = 0;
m_in_range_Sx2w = 0;
m_in_range_Sy2w = 0;
m_in_range_Sz2w = 0;
bn_t ibin,jbin,kbin,joffset,offset;
bn_t xbins = parent::m_axes[0].bins();
bn_t ybins = parent::m_axes[1].bins();
bn_t zbins = parent::m_axes[2].bins();
bn_t yoffset = parent::m_axes[1].m_offset;
bn_t zoffset = parent::m_axes[2].m_offset;
for(ibin=1;ibin<=xbins;ibin++) {
joffset = ibin + yoffset;
for(jbin=1;jbin<=ybins;jbin++) {
//joffset = ibin + jbin * parent::m_axes[1].m_offset;
offset = joffset + zoffset;
for(kbin=1;kbin<=zbins;kbin++) {
//offset = joffset + kbin * parent::m_axes[2].m_offset;
m_in_range_entries += parent::m_bin_entries[offset];
m_in_range_Sw += parent::m_bin_Sw[offset];
m_in_range_Sxw += parent::m_bin_Sxw[offset][0];
m_in_range_Syw += parent::m_bin_Sxw[offset][1];
m_in_range_Szw += parent::m_bin_Sxw[offset][2];
m_in_range_Sx2w += parent::m_bin_Sx2w[offset][0];
m_in_range_Sy2w += parent::m_bin_Sx2w[offset][1];
m_in_range_Sz2w += parent::m_bin_Sx2w[offset][2];
offset += zoffset;
}
joffset += yoffset;
}
}
}
// Partition :
int coord_to_index_x(TC aCoord) const {
return axis_x().coord_to_index(aCoord);
@@ -73,56 +34,48 @@ public:
}
TC mean_x() const {
if(m_in_range_Sw==0) return 0;
return m_in_range_Sxw/m_in_range_Sw;
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(m_in_range_Sw==0) return 0;
return m_in_range_Syw/m_in_range_Sw;
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(m_in_range_Sw==0) return 0;
return m_in_range_Szw/m_in_range_Sw;
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(m_in_range_Sw==0) return 0;
TC mean = m_in_range_Sxw/m_in_range_Sw;
return ::sqrt(::fabs((m_in_range_Sx2w / m_in_range_Sw) - mean * mean));
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(m_in_range_Sw==0) return 0;
TC mean = m_in_range_Syw/m_in_range_Sw;
return ::sqrt(::fabs((m_in_range_Sy2w / m_in_range_Sw) - mean * mean));
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(m_in_range_Sw==0) return 0;
TC mean = m_in_range_Szw/m_in_range_Sw;
return ::sqrt(::fabs((m_in_range_Sz2w / m_in_range_Sw) - mean * mean));
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 {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin,kbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
if(!parent::m_axes[2].in_range_to_absolute_index(aK,kbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset + kbin * parent::m_axes[2].m_offset;
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 {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin,kbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
if(!parent::m_axes[2].in_range_to_absolute_index(aK,kbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset + kbin * parent::m_axes[2].m_offset;
TO offset;
if(!_find_offset(aI,aJ,aK,offset)) return 0;
return this->get_bin_height(offset);
}
@@ -131,48 +84,32 @@ public:
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 {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin,kbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
if(!parent::m_axes[2].in_range_to_absolute_index(aK,kbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset + kbin * parent::m_axes[2].m_offset;
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 {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin,kbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
if(!parent::m_axes[2].in_range_to_absolute_index(aK,kbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset + kbin * parent::m_axes[2].m_offset;
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 {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin,kbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
if(!parent::m_axes[2].in_range_to_absolute_index(aK,kbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset + kbin * parent::m_axes[2].m_offset;
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 {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin,kbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
if(!parent::m_axes[2].in_range_to_absolute_index(aK,kbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset + kbin * parent::m_axes[2].m_offset;
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];
@@ -182,12 +119,8 @@ public:
}
TC bin_rms_y(int aI,int aJ,int aK) const {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin,kbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
if(!parent::m_axes[2].in_range_to_absolute_index(aK,kbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset + kbin * parent::m_axes[2].m_offset;
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];
@@ -197,12 +130,8 @@ public:
}
TC bin_rms_z(int aI,int aJ,int aK) const {
if(parent::m_bin_number==0) return 0;
bn_t ibin,jbin,kbin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
if(!parent::m_axes[2].in_range_to_absolute_index(aK,kbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset + kbin * parent::m_axes[2].m_offset;
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];
@@ -227,9 +156,9 @@ public:
bn_t jbin,kbin,offset;
bn_t ybins = parent::m_axes[1].bins()+2;
bn_t zbins = parent::m_axes[2].bins()+2;
bn_t yoffset = parent::m_axes[1].m_offset;
bn_t zoffset = parent::m_axes[2].m_offset;
bn_t joffset = ibin;
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;
@@ -248,12 +177,13 @@ public:
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,offset;
bn_t ibin,kbin;
TO offset;
bn_t xbins = parent::m_axes[0].bins()+2;
bn_t zbins = parent::m_axes[2].bins()+2;
bn_t yoffset = parent::m_axes[1].m_offset;
bn_t zoffset = parent::m_axes[2].m_offset;
bn_t joffset = jbin * yoffset;
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;
@@ -272,12 +202,13 @@ public:
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,offset;
bn_t ibin,jbin;
TO offset;
bn_t xbins = parent::m_axes[0].bins()+2;
bn_t ybins = parent::m_axes[1].bins()+2;
bn_t yoffset = parent::m_axes[1].m_offset;
bn_t zoffset = parent::m_axes[2].m_offset;
bn_t koffset = kbin * zoffset;
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;
@@ -299,13 +230,13 @@ public:
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;
bn_t yoffset = parent::m_axes[1].m_offset;
bn_t zoffset = parent::m_axes[2].m_offset;
bn_t joffset = ibin;
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;
bn_t offset = joffset;
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);
@@ -322,13 +253,13 @@ public:
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;
bn_t yoffset = parent::m_axes[1].m_offset;
bn_t zoffset = parent::m_axes[2].m_offset;
bn_t joffset = jbin * yoffset;
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;
bn_t offset = joffset;
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);
@@ -345,13 +276,13 @@ public:
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;
bn_t yoffset = parent::m_axes[1].m_offset;
bn_t zoffset = parent::m_axes[2].m_offset;
bn_t koffset = kbin * zoffset;
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;
bn_t offset = koffset;
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);
@@ -373,17 +304,9 @@ public:
}
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)
:m_in_range_entries(0)
,m_in_range_Sw(0)
,m_in_range_Sxw(0)
,m_in_range_Syw(0)
,m_in_range_Szw(0)
,m_in_range_Sx2w(0)
,m_in_range_Sy2w(0)
,m_in_range_Sz2w(0)
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;
@@ -402,17 +325,9 @@ public:
}
b3(const std::string& a_title,
const std::vector<TC>& aEdgesX,
const std::vector<TC>& aEdgesY,
const std::vector<TC>& aEdgesZ)
:m_in_range_entries(0)
,m_in_range_Sw(0)
,m_in_range_Sxw(0)
,m_in_range_Syw(0)
,m_in_range_Szw(0)
,m_in_range_Sx2w(0)
,m_in_range_Sy2w(0)
,m_in_range_Sz2w(0)
const std::vector<TC>& aEdgesX,
const std::vector<TC>& aEdgesY,
const std::vector<TC>& aEdgesZ)
{
parent::m_title = a_title;
std::vector< std::vector<TC> > edges(3);
@@ -424,46 +339,12 @@ public:
virtual ~b3(){}
protected:
b3(const b3& a_from)
: parent(a_from)
,m_in_range_entries(a_from.m_in_range_entries)
,m_in_range_Sw(a_from.m_in_range_Sw)
,m_in_range_Sxw(a_from.m_in_range_Sxw)
,m_in_range_Syw(a_from.m_in_range_Syw)
,m_in_range_Szw(a_from.m_in_range_Szw)
,m_in_range_Sx2w(a_from.m_in_range_Sx2w)
,m_in_range_Sy2w(a_from.m_in_range_Sy2w)
,m_in_range_Sz2w(a_from.m_in_range_Sz2w)
{
update_fast_getters();
}
b3& operator=(const b3& a_from){
parent::operator=(a_from);
m_in_range_entries = a_from.m_in_range_entries;
m_in_range_Sw = a_from.m_in_range_Sw;
m_in_range_Sxw = a_from.m_in_range_Sxw;
m_in_range_Syw = a_from.m_in_range_Syw;
m_in_range_Szw = a_from.m_in_range_Szw;
m_in_range_Sx2w = a_from.m_in_range_Sx2w;
m_in_range_Sy2w = a_from.m_in_range_Sy2w;
m_in_range_Sz2w = a_from.m_in_range_Sz2w;
update_fast_getters();
return *this;
}
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){
m_in_range_entries = 0;
m_in_range_Sw = 0;
m_in_range_Sxw = 0;
m_in_range_Syw = 0;
m_in_range_Szw = 0;
m_in_range_Sx2w = 0;
m_in_range_Sy2w = 0;
m_in_range_Sz2w = 0;
std::vector<bn_t> nbins;
nbins.push_back(aXnumber);
nbins.push_back(aYnumber);
@@ -482,15 +363,6 @@ public:
bool configure(const std::vector<TC>& aEdgesX,
const std::vector<TC>& aEdgesY,
const std::vector<TC>& aEdgesZ){
m_in_range_entries = 0;
m_in_range_Sw = 0;
m_in_range_Sxw = 0;
m_in_range_Syw = 0;
m_in_range_Szw = 0;
m_in_range_Sx2w = 0;
m_in_range_Sy2w = 0;
m_in_range_Sz2w = 0;
std::vector< std::vector<TC> > edges(3);
edges[0] = aEdgesX;
edges[1] = aEdgesY;
@@ -499,14 +371,15 @@ public:
}
protected:
TN m_in_range_entries;
TW m_in_range_Sw;
TC m_in_range_Sxw;
TC m_in_range_Syw;
TC m_in_range_Szw;
TC m_in_range_Sx2w;
TC m_in_range_Sy2w;
TC m_in_range_Sz2w;
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;
}
};
}}
@@ -17,148 +17,104 @@ 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 TN,class TW,class TH>
class base_histo {
template <class TC,class TO,class TN,class TW,class TH>
class base_histo : public 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 typename axis<TC>::bn_t bn_t;
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;
protected:
virtual TH get_bin_height(int) const = 0; //histo/profile
virtual TH get_bin_height(TO) const = 0; //histo/profile
protected:
void base_from_data(const histo_data<TC,TN,TW>& a_from) {
m_title = a_from.m_title;
m_dimension = a_from.m_dimension;
m_bin_number = a_from.m_bin_number;
// Arrays :
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_annotations = a_from.m_annotations;
}
histo_data<TC,TN,TW> base_get_data() const {
histo_data<TC,TN,TW> hd;
hd.m_title = m_title;
hd.m_dimension = m_dimension;
hd.m_bin_number = m_bin_number;
// Arrays :
hd.m_bin_entries = m_bin_entries;
hd.m_bin_Sw = m_bin_Sw;
hd.m_bin_Sw2 = m_bin_Sw2;
hd.m_bin_Sxw = m_bin_Sxw;
hd.m_bin_Sx2w = m_bin_Sx2w;
hd.m_axes = m_axes;
hd.m_annotations = m_annotations;
void base_from_data(const hd_t& a_from) {parent::operator=(a_from);}
hd_t base_get_data() const {
hd_t hd;
hd = *this;
return hd;
}
protected:
base_histo()
:m_dimension(0)
,m_bin_number(0)
{
base_histo():parent() {
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
protected:
virtual ~base_histo(){
virtual ~base_histo() {
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
base_histo(const base_histo& a_from)
:m_title(a_from.m_title)
,m_dimension(a_from.m_dimension)
,m_bin_number(a_from.m_bin_number)
// Arrays :
,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_annotations(a_from.m_annotations)
{
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) {
m_title = a_from.m_title;
m_dimension = a_from.m_dimension;
m_bin_number = a_from.m_bin_number;
// Arrays :
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_annotations = a_from.m_annotations;
parent::operator=(a_from);
return *this;
}
public:
const std::string& title() const {return m_title;}
std::string title() {return m_title;}
bool set_title(const std::string& a_title){m_title = a_title;return true;}
dim_t dimension() const {return m_dimension;}
const std::string& title() const {return parent::m_title;}
std::string title() {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;}
TN entries() const { return get_entries();}
TN all_entries() const {
TN number = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
number += m_bin_entries[ibin];
}
return number;
TN entries() const {
return parent::m_in_range_entries; //not set if reading a TH from a ROOT file.
}
TN all_entries() const {
return parent::m_all_entries; //works also is reading histo from a ROOT file.
}
/*
TN extra_entries() const {
TN number = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(is_out(ibin)) {
number += m_bin_entries[ibin];
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(histo::is_out(parent::m_axes,ibin)) {
number += parent::m_bin_entries[ibin];
}
}
return number;
}
*/
TW equivalent_bin_entries() const {
TW sw = 0;
TW sw2 = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
sw += m_bin_Sw[ibin];
sw2 += m_bin_Sw2[ibin];
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(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
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(bn_t ibin=0;ibin<m_bin_number;ibin++) {
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
sh += get_bin_height(ibin);
}
return sh;
@@ -166,8 +122,8 @@ public:
TH sum_extra_bin_heights() const {
TH sh = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(is_out(ibin)) {
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
if(histo::is_out(parent::m_axes,ibin)) {
sh += get_bin_height(ibin);
}
}
@@ -177,8 +133,8 @@ public:
TH min_bin_height() const {
TH value = 0;
bool first = true;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
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;
@@ -194,8 +150,8 @@ public:
TH max_bin_height() const {
TH value = 0;
bool first = true;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
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;
@@ -207,7 +163,6 @@ public:
}
return value;
}
protected:
enum {AxisX=0,AxisY=1,AxisZ=2};
@@ -216,22 +171,28 @@ protected:
const std::vector<TC>& aMins,
const std::vector<TC>& aMaxs) {
// Clear :
m_bin_entries.clear();
m_bin_Sw.clear();
m_bin_Sw2.clear();
m_bin_Sxw.clear();
m_bin_Sx2w.clear();
m_axes.clear();
m_bin_number = 0;
m_dimension = 0;
m_annotations.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_axes.clear();
parent::m_bin_number = 0;
parent::m_dimension = 0;
parent::m_annotations.clear();
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;
m_axes.resize(a_dim);
parent::m_axes.resize(a_dim);
// Setup axes :
for(dim_t iaxis=0;iaxis<a_dim;iaxis++) {
if(!m_axes[iaxis].configure(aNumbers[iaxis],aMins[iaxis],aMaxs[iaxis])) {
if(!parent::m_axes[iaxis].configure(aNumbers[iaxis],aMins[iaxis],aMaxs[iaxis])) {
// do not do :
// m_axes.clear()
// so that :
@@ -242,7 +203,7 @@ protected:
}
}
m_dimension = a_dim;
parent::m_dimension = a_dim;
base_allocate(); //set m_bin_number.
@@ -251,28 +212,34 @@ protected:
bool configure(dim_t a_dim,const std::vector< std::vector<TC> >& aEdges) {
// Clear :
m_bin_entries.clear();
m_bin_Sw.clear();
m_bin_Sw2.clear();
m_bin_Sxw.clear();
m_bin_Sx2w.clear();
m_axes.clear();
m_bin_number = 0;
m_dimension = 0;
m_annotations.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_axes.clear();
parent::m_bin_number = 0;
parent::m_dimension = 0;
parent::m_annotations.clear();
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;
m_axes.resize(a_dim);
parent::m_axes.resize(a_dim);
// Setup axes :
for(dim_t iaxis=0;iaxis<a_dim;iaxis++) {
if(!m_axes[iaxis].configure(aEdges[iaxis])) {
if(!parent::m_axes[iaxis].configure(aEdges[iaxis])) {
//m_axes.clear();
return false;
}
}
m_dimension = a_dim;
parent::m_dimension = a_dim;
base_allocate(); //set m_bin_number.
@@ -281,219 +248,114 @@ protected:
void base_reset() {
// Reset content (different of clear that deallocate all internal things).
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
m_bin_entries[ibin] = 0;
m_bin_Sw[ibin] = 0;
m_bin_Sw2[ibin] = 0;
for(dim_t iaxis=0;iaxis<m_dimension;iaxis++) {
m_bin_Sxw[ibin][iaxis] = 0;
m_bin_Sx2w[ibin][iaxis] = 0;
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;
}
}
//profile not done here.
parent::reset_fast_getters();
}
protected:
void base_allocate() {
dim_t iaxis;
// Add two bins for the [under,out]flow data.
bn_t n_bin = 1;
for(iaxis=0;iaxis<m_dimension;iaxis++) {
n_bin *= (m_axes[iaxis].bins() + 2);
TO n_bin = 1;
for(iaxis=0;iaxis<parent::m_dimension;iaxis++) {
n_bin *= (parent::m_axes[iaxis].bins() + 2);
}
m_bin_entries.resize(n_bin,0);
m_bin_Sw.resize(n_bin,0);
m_bin_Sw2.resize(n_bin,0);
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(m_dimension,0);
m_bin_Sxw.resize(n_bin,empty);
m_bin_Sx2w.resize(n_bin,empty);
empty.resize(parent::m_dimension,0);
parent::m_bin_Sxw.resize(n_bin,empty);
parent::m_bin_Sx2w.resize(n_bin,empty);
m_bin_number = n_bin; // All bins : [in-range, underflow, outflow] bins.
parent::m_bin_number = n_bin; // All bins : [in-range, underflow, outflow] bins.
m_axes[0].m_offset = 1;
for(iaxis=1;iaxis<m_dimension;iaxis++) {
m_axes[iaxis].m_offset =
m_axes[iaxis-1].m_offset * (m_axes[iaxis-1].bins()+2);
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);
}
}
public:
// for BatchLab::Rio::TH::streamTH1 :
TN get_entries() const {
TN number = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
number += m_bin_entries[ibin];
}
}
return number;
}
TW get_Sw() const {
TW sw = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
sw += m_bin_Sw[ibin];
}
}
return sw;
}
TW get_Sw2() const {
TW sw2 = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
sw2 += m_bin_Sw2[ibin];
}
}
return sw2;
}
bool get_ith_axis_Sxw(dim_t a_axis,TC& a_value) const {
a_value = 0;
if(a_axis>=m_dimension) return false;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
a_value += 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>=m_dimension) return false;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
a_value += m_bin_Sx2w[ibin][a_axis];
}
}
return true;
}
TN get_all_entries() const {
TN number = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
number += m_bin_entries[ibin];
}
return number;
}
void get_indices(bn_t aOffset,std::vector<int>& aIs) const {
int offset = aOffset;
{for(int iaxis=m_dimension-1;iaxis>=0;iaxis--) {
aIs[iaxis] = offset/m_axes[iaxis].m_offset;
offset -= aIs[iaxis] * m_axes[iaxis].m_offset;
}}
for(unsigned int iaxis=0;iaxis<m_dimension;iaxis++) {
if(aIs[iaxis]==0) {
aIs[iaxis] = axis<TC>::UNDERFLOW_BIN;
} else if(aIs[iaxis]==int(m_axes[iaxis].m_number_of_bins+1)) {
aIs[iaxis] = axis<TC>::OVERFLOW_BIN;
} else {
aIs[iaxis]--;
}
}
}
bool is_out(bn_t aOffset) const {
int offset = aOffset;
int index;
for(int iaxis=m_dimension-1;iaxis>=0;iaxis--) {
index = offset/m_axes[iaxis].m_offset;
if(index==0) return true;
if(index==(int(m_axes[iaxis].m_number_of_bins)+1)) return true;
offset -= index * m_axes[iaxis].m_offset;
}
return false;
}
bool get_offset(const std::vector<int>& aIs,bn_t& a_offset) const {
// aIs[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(!m_dimension) return false;
bn_t ibin;
for(dim_t iaxis=0;iaxis<m_dimension;iaxis++) {
if(!m_axes[iaxis].in_range_to_absolute_index(aIs[iaxis],ibin)) {
a_offset = 0;
return false;
}
a_offset += ibin * m_axes[iaxis].m_offset;
}
return true;
}
// to access data from methods :
const std::vector<TN>& bins_entries() const {return m_bin_entries;}
const std::vector<TW>& bins_sum_w() const {return m_bin_Sw;}
const std::vector<TW>& bins_sum_w2() const {return m_bin_Sw2;}
const std::vector< std::vector<TC> >& bins_sum_xw() const {return m_bin_Sxw;}
const std::vector< std::vector<TC> >& bins_sum_x2w() const {return m_bin_Sx2w;}
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;}
public:
const axis<TC>& get_axis(int aIndex) const {return m_axes[aIndex];}
bn_t get_bins() const {return m_bin_number;}
const std::string& get_title() const {return m_title;}
dim_t get_dimension() const {return m_dimension;}
bool is_valid() const {return (m_dimension?true:false);}
const axis_t& get_axis(int aIndex) const {return parent::m_axes[aIndex];}
TO 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 m_annotations;}
annotations_t annotations() {return m_annotations;}
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) {
m_annotations[a_key] = a_value; //override if a_key already exists.
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 = m_annotations.find(a_key);
if(it==m_annotations.end()) {a_value.clear();return false;}
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;
}
protected:
bool is_compatible(const base_histo& a_histo){
if(m_dimension!=a_histo.m_dimension) return false;
for(dim_t iaxis=0;iaxis<m_dimension;iaxis++) {
if(!m_axes[iaxis].is_compatible(a_histo.m_axes[iaxis])) return false;
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(bn_t ibin=0;ibin<m_bin_number;ibin++) {
m_bin_entries[ibin] += a_histo.m_bin_entries[ibin];
m_bin_Sw[ibin] += a_histo.m_bin_Sw[ibin];
m_bin_Sw2[ibin] += a_histo.m_bin_Sw2[ibin];
for(dim_t iaxis=0;iaxis<m_dimension;iaxis++) {
m_bin_Sxw[ibin][iaxis] += a_histo.m_bin_Sxw[ibin][iaxis];
m_bin_Sx2w[ibin][iaxis] += a_histo.m_bin_Sx2w[ibin][iaxis];
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];
}
}
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(bn_t ibin=0;ibin<m_bin_number;ibin++) {
m_bin_entries[ibin] = 1;
for(TO ibin=0;ibin<parent::m_bin_number;ibin++) {
parent::m_bin_entries[ibin] = 1;
m_bin_Sw[ibin] -= a_histo.m_bin_Sw[ibin];
parent::m_bin_Sw[ibin] -= a_histo.m_bin_Sw[ibin];
// Yes, it is a += in the below.
m_bin_Sw2[ibin] += a_histo.m_bin_Sw2[ibin];
for(dim_t iaxis=0;iaxis<m_dimension;iaxis++) {
m_bin_Sxw[ibin][iaxis] -= a_histo.m_bin_Sxw[ibin][iaxis];
m_bin_Sx2w[ibin][iaxis] -= a_histo.m_bin_Sx2w[ibin][iaxis];
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];
}
}
parent::update_fast_getters();
}
bool base_multiply(const base_histo& a_histo) {
@@ -506,26 +368,28 @@ protected:
if(!is_compatible(a_histo)) return false;
std::vector<int> is(m_dimension);
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
TW swa = m_bin_Sw[ibin];
TW sw2a = m_bin_Sw2[ibin];
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;
m_bin_entries[ibin] = 1;
m_bin_Sw[ibin] = sw;
m_bin_Sw2[ibin] = sw2a * swb * swb + sw2b * swa * swa;
get_indices(ibin,is);
for(dim_t iaxis=0;iaxis<m_dimension;iaxis++) {
TC x = m_axes[iaxis].bin_center(is[iaxis]);
m_bin_Sxw[ibin][iaxis] = x * sw;
m_bin_Sx2w[ibin][iaxis] = x * x * sw;
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;
}
}
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".
@@ -536,60 +400,62 @@ protected:
if(!is_compatible(a_histo)) return false;
std::vector<int> is(m_dimension);
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
get_indices(ibin,is);
TW swa = m_bin_Sw[ibin];
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 = m_bin_Sw2[ibin];
TW sw2a = parent::m_bin_Sw2[ibin];
TW sw2b = a_histo.m_bin_Sw2[ibin];
if(swb!=0) {
m_bin_entries[ibin] = 1;
parent::m_bin_entries[ibin] = 1;
TW sw = swa / swb;
m_bin_Sw[ibin] = sw;
parent::m_bin_Sw[ibin] = sw;
TW swb2 = swb * swb;
m_bin_Sw2[ibin] = sw2a / swb2 + sw2b * swa * swa /(swb2*swb2);
for(dim_t iaxis=0;iaxis<m_dimension;iaxis++) {
TC x = m_axes[iaxis].bin_center(is[iaxis]);
m_bin_Sxw[ibin][iaxis] = x * sw;
m_bin_Sx2w[ibin][iaxis] = x * x * sw;
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 {
m_bin_entries[ibin] = 0;
m_bin_Sw[ibin] = 0;
m_bin_Sw2[ibin] = 0;
for(dim_t iaxis=0;iaxis<m_dimension;iaxis++) {
m_bin_Sxw[ibin][iaxis] = 0;
m_bin_Sx2w[ibin][iaxis] = 0;
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::update_fast_getters();
return true;
}
bool base_multiply(TW aFactor) {
if(aFactor<0) return false;
TW factor2 = aFactor * aFactor;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
m_bin_Sw[ibin] *= aFactor;
m_bin_Sw2[ibin] *= factor2;
for(dim_t iaxis=0;iaxis<m_dimension;iaxis++) {
m_bin_Sxw[ibin][iaxis] *= aFactor;
m_bin_Sx2w[ibin][iaxis] *= aFactor;
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;
}
}
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>=m_dimension) return false;
if(a_axis>=parent::m_dimension) return false;
TW sw = 0;
TC sxw = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
sw += m_bin_Sw[ibin];
sxw += m_bin_Sxw[ibin][a_axis];
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;
@@ -599,15 +465,15 @@ protected:
bool get_ith_axis_rms(dim_t a_axis,TC& a_value) const {
a_value = 0;
if(a_axis>=m_dimension) return false;
if(a_axis>=parent::m_dimension) return false;
TW sw = 0;
TC sxw = 0;
TC sx2w = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
sw += m_bin_Sw[ibin];
sxw += m_bin_Sxw[ibin][a_axis];
sx2w += m_bin_Sx2w[ibin][a_axis];
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;
@@ -617,27 +483,11 @@ protected:
}
TN get_bin_entries(const std::vector<int>& aIs) const {
if(m_bin_number==0) return 0;
bn_t offset;
if(!get_offset(aIs,offset)) return 0;
return m_bin_entries[offset];
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];
}
protected:
// General :
std::string m_title;
dim_t m_dimension;
// Bins :
bn_t 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<TC> > m_axes;
// etc :
annotations_t m_annotations;
};
// predefined annotation keys :
@@ -2,7 +2,7 @@
// See the file tools.license for terms.
#ifndef tools_histo_c1d
#define tools_histo_cld
#define tools_histo_c1d
#include "base_cloud"
@@ -0,0 +1,250 @@
// 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
unsigned int 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;}
std::string title() {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();}
unsigned int size() const {return m_points.size();}
const data_point& point(unsigned int a_index) const {
//WARNING : no check done on a_index.
return m_points[a_index];
}
data_point& point(unsigned int 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(unsigned int 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
+79 -39
View File
@@ -10,55 +10,48 @@ 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 TN,class TW,class TH>
class h1 : public b1<TC,TN,TW,TH> {
typedef b1<TC,TN,TW,TH> parent;
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 typename b1<TC,TN,TW,TH>::bn_t bn_t;
typedef histo_data<TC,TO,TN,TW> hd_t;
typedef typename parent::bn_t bn_t;
typedef histo::axis<TC,TO> axis_t;
protected:
virtual TH get_bin_height(int a_offset) const { //TH should be the same as TW
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
if(parent::m_bin_number==0) return 0;
bn_t offset;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,offset)) return 0;
TO offset;
if(!parent::_find_offset(aI,offset)) return 0;
return ::sqrt(parent::m_bin_Sw2[offset]);
}
public:
bool multiply(TW aFactor){
if(!parent::base_multiply(aFactor)) return false;
parent::update_fast_getters();
return true;
}
bool scale(TW aFactor) {return multiply(aFactor);}
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 histo_data<TC,TN,TW>& a_from) {
parent::base_from_data(a_from);
}
histo_data<TC,TN,TW> get_histo_data() const {
return parent::base_get_data();
}
void copy_from_data(const hd_t& a_from) {parent::base_from_data(a_from);}
hd_t get_histo_data() const {return parent::base_get_data();}
bool reset() {
parent::base_reset();
parent::update_fast_getters();
return true;
}
bool fill(TC aX,TW aWeight = 1) {
//m_coords[0] = aX;
//return fill_bin(m_coords,aWeight);
if(parent::m_dimension<=0) return false;
if(parent::m_dimension!=1) return false;
bn_t offset;
if(!parent::m_axes[0].coord_to_absolute_index(aX,offset)) 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;
@@ -68,30 +61,78 @@ public:
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) {
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 add(const h1& a_histo){
parent::base_add(a_histo);
parent::update_fast_getters();
return true;
}
bool subtract(const h1& a_histo){
parent::base_subtract(a_histo);
parent::update_fast_getters();
return true;
}
bool multiply(const h1& a_histo) {
if(!parent::base_multiply(a_histo)) return false;
parent::update_fast_getters();
return true;
return parent::base_multiply(a_histo);
}
bool divide(const h1& a_histo) {
if(!parent::base_divide(a_histo)) return false;
parent::update_fast_getters();
return true;
return parent::base_divide(a_histo);
}
bool gather_bins(unsigned int a_factor) { //for exa 2,3.
@@ -99,7 +140,7 @@ public:
// actual bin number must be a multiple of a_factor.
const histo::axis<TC>& _axis = parent::axis();
const axis_t& _axis = parent::axis();
bn_t n = _axis.bins();
if(!n) return false;
@@ -109,8 +150,7 @@ public:
h1* new_h = 0;
if(_axis.is_fixed_binning()) {
new_h = new h1(parent::m_title,
new_n,_axis.lower_edge(),_axis.upper_edge());
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);
@@ -122,7 +162,7 @@ public:
}
if(!new_h) return false;
bn_t offset,new_offset,offac;
TO offset,new_offset,offac;
for(bn_t ibin=0;ibin<new_n;ibin++) {
new_offset = ibin+1;
offset = a_factor*ibin+1;
@@ -167,7 +207,7 @@ public:
virtual ~h1(){}
public:
h1(const h1& a_from): parent(a_from){}
h1(const h1& a_from):parent(a_from){}
h1& operator=(const h1& a_from){
parent::operator=(a_from);
return *this;
@@ -11,16 +11,16 @@ namespace histo {
// d in h1d is for double (and not dimension).
class h1d : public h1<double,unsigned int,double,double> {
typedef h1<double,unsigned int,double,double> parent;
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(const std::string& a_title,
unsigned int aXnumber,double aXmin,double aXmax)
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>& aEdges)
@@ -28,19 +28,11 @@ public:
virtual ~h1d(){}
public:
h1d(const h1d& a_from): parent(a_from){}
h1d(const h1d& a_from):parent(a_from){}
h1d& operator=(const h1d& a_from){
parent::operator=(a_from);
return *this;
}
public:
#ifdef __CINT__
bool fill(double aX,double aW = 1) {return parent::fill(aX,aW);}
double mean() const {return parent::mean();}
double rms() const {return parent::rms();}
unsigned int entries() const {return parent::entries();}
void hprint(std::ostream& a_out) {parent::hprint(a_out);}
#endif
private:static void check_instantiation() {h1d h("",10,0,1);h.gather_bins(5);}
};
@@ -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>& aEdges)
:parent(a_title,aEdges){}
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
+77 -52
View File
@@ -9,60 +9,43 @@
namespace tools {
namespace histo {
template <class TC,class TN,class TW,class TH>
class h2 : public b2<TC,TN,TW,TH> {
typedef b2<TC,TN,TW,TH> parent;
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 typename b2<TC,TN,TW,TH>::bn_t bn_t;
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(int a_offset) const { //TH should be the same as TW
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 {
if(parent::m_bin_number==0) return 0;
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
bn_t jbin;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
TO offset;
if(!parent::_find_offset(aI,aJ,offset)) return 0;
return ::sqrt(parent::m_bin_Sw2[offset]);
}
public:
bool multiply(TW aFactor){
if(!parent::base_multiply(aFactor)) return false;
parent::update_fast_getters();
return true;
}
bool scale(TW aFactor) {return multiply(aFactor);}
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 histo_data<TC,TN,TW>& a_from) {
parent::base_from_data(a_from);
}
histo_data<TC,TN,TW> get_histo_data() const {
return parent::base_get_data();
}
void copy_from_data(const hd_t& a_from) {parent::base_from_data(a_from);}
hd_t get_histo_data() const {return parent::base_get_data();}
bool reset() {
parent::base_reset();
parent::update_fast_getters();
return true;
}
bool fill(TC aX,TC aY,TW aWeight = 1) {
//m_coords[0] = aX;
//m_coords[1] = aY;
//return fill_bin(m_coords,aWeight);
if(parent::m_dimension<=0) return false;
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;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
TO offset = ibin + jbin * parent::m_axes[1].m_offset;
parent::m_bin_entries[offset]++;
parent::m_bin_Sw[offset] += aWeight;
@@ -85,53 +68,95 @@ public:
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_entries++;
parent::m_in_range_Sw += aWeight;
parent::m_in_range_Sw2 += aWeight*aWeight;
parent::m_in_range_Sxw += xw;
parent::m_in_range_Sx2w += x2w;
parent::m_in_range_Syw += yw;
parent::m_in_range_Sy2w += y2w;
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_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 add(const h2& a_histo){
parent::base_add(a_histo);
parent::update_fast_getters();
return true;
}
bool subtract(const h2& a_histo){
parent::base_subtract(a_histo);
parent::update_fast_getters();
return true;
}
bool multiply(const h2& a_histo) {
if(!parent::base_multiply(a_histo)) return false;
parent::update_fast_getters();
return true;
return parent::base_multiply(a_histo);
}
bool divide(const h2& a_histo) {
if(!parent::base_divide(a_histo)) return false;
parent::update_fast_getters();
return true;
return parent::base_divide(a_histo);
}
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,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>& aEdgesX,
const std::vector<TC>& aEdgesY)
: parent(a_title,aEdgesX,aEdgesY)
h2(const std::string& a_title,const std::vector<TC>& aEdgesX,const std::vector<TC>& aEdgesY)
:parent(a_title,aEdgesX,aEdgesY)
{}
virtual ~h2(){}
@@ -9,23 +9,24 @@
namespace tools {
namespace histo {
class h2d : public h2<double,unsigned int,double,double> {
typedef h2<double,unsigned int,double,double> parent;
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(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)
:parent(a_title,aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax)
{}
h2d(const std::string& a_title,
const std::vector<double>& aEdgesX,
const std::vector<double>& aEdgesY)
: parent(a_title,aEdgesX,aEdgesY)
:parent(a_title,aEdgesX,aEdgesY)
{}
virtual ~h2d(){}
@@ -35,12 +36,6 @@ public:
parent::operator=(a_from);
return *this;
}
#ifdef __CINT__
bool fill(double aX,double aY,double aW = 1) {
return parent::fill(aX,aY,aW);
}
void hprint(std::ostream& a_out) {parent::hprint(a_out);}
#endif
private:static void check_instantiation() {h2d dummy("",10,0,1,10,0,1);}
};
@@ -0,0 +1,52 @@
// 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(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>& aEdgesX,
const std::vector<double>& aEdgesY)
:parent(a_title,aEdgesX,aEdgesY)
{}
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
+93 -61
View File
@@ -9,67 +9,44 @@
namespace tools {
namespace histo {
template <class TC,class TN,class TW,class TH>
class h3 : public b3<TC,TN,TW,TH> {
typedef b3<TC,TN,TW,TH> parent;
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 typename b3<TC,TN,TW,TH>::bn_t bn_t;
typedef histo_data<TC,TO,TN,TW> hd_t;
typedef typename parent::bn_t bn_t;
protected:
virtual TH get_bin_height(int a_offset) const { //TH should be the same as TW
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 {
if(parent::m_bin_number==0) return 0;
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
bn_t jbin;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t kbin;
if(!parent::m_axes[2].in_range_to_absolute_index(aK,kbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset +
kbin * parent::m_axes[2].m_offset;
TO offset;
if(!parent::_find_offset(aI,aJ,aK,offset)) return 0;
return ::sqrt(parent::m_bin_Sw2[offset]);
}
public:
bool multiply(TW aFactor){
if(!parent::base_multiply(aFactor)) return false;
parent::update_fast_getters();
return true;
}
bool scale(TW aFactor) {return multiply(aFactor);}
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 histo_data<TC,TN,TW>& a_from) {
parent::base_from_data(a_from);
}
histo_data<TC,TN,TW> get_histo_data() const {
return parent::base_get_data();
}
void copy_from_data(const hd_t& a_from) {parent::base_from_data(a_from);}
hd_t get_histo_data() const {return parent::base_get_data();}
bool reset() {
parent::base_reset();
parent::update_fast_getters();
return true;
}
bool fill(TC aX,TC aY,TC aZ,TW aWeight = 1) {
//m_coords[0] = aX;
//m_coords[1] = aY;
//m_coords[2] = aZ;
//return fill_bin(m_coords,aWeight);
if(parent::m_dimension<=0) return false;
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;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset +
kbin * parent::m_axes[2].m_offset;
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;
@@ -100,44 +77,99 @@ public:
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_entries++;
parent::m_in_range_Sw += aWeight;
parent::m_in_range_Sw2 += aWeight*aWeight;
parent::m_in_range_Sxw += xw;
parent::m_in_range_Sx2w += x2w;
parent::m_in_range_Syw += yw;
parent::m_in_range_Sy2w += y2w;
parent::m_in_range_Szw += zw;
parent::m_in_range_Sz2w += z2w;
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_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 add(const h3& a_histo){
parent::base_add(a_histo);
parent::update_fast_getters();
return true;
}
bool subtract(const h3& a_histo){
parent::base_subtract(a_histo);
parent::update_fast_getters();
return true;
}
bool multiply(const h3& a_histo) {
if(!parent::base_multiply(a_histo)) return false;
parent::update_fast_getters();
return true;
return parent::base_multiply(a_histo);
}
bool divide(const h3& a_histo) {
if(!parent::base_divide(a_histo)) return false;
parent::update_fast_getters();
return true;
return parent::base_divide(a_histo);
}
public:
@@ -149,19 +181,19 @@ public:
*/
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,
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>& aEdgesX,
const std::vector<TC>& aEdgesY,
const std::vector<TC>& aEdgesZ)
: parent(a_title,aEdgesX,aEdgesY,aEdgesZ)
const std::vector<TC>& aEdgesX,
const std::vector<TC>& aEdgesY,
const std::vector<TC>& aEdgesZ)
:parent(a_title,aEdgesX,aEdgesY,aEdgesZ)
{}
virtual ~h3(){}
@@ -9,19 +9,20 @@
namespace tools {
namespace histo {
class h3d : public h3<double,unsigned int,double,double> {
typedef h3<double,unsigned int,double,double> parent;
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(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,
:parent(a_title,aXnumber,aXmin,aXmax,
aYnumber,aYmin,aYmax,
aZnumber,aZmin,aZmax)
{}
@@ -30,7 +31,7 @@ public:
const std::vector<double>& aEdgesX,
const std::vector<double>& aEdgesY,
const std::vector<double>& aEdgesZ)
: parent(a_title,aEdgesX,aEdgesY,aEdgesZ)
:parent(a_title,aEdgesX,aEdgesY,aEdgesZ)
{}
virtual ~h3d(){}
@@ -41,13 +42,6 @@ public:
return *this;
}
#ifdef __CINT__
bool fill(double aX,double aY,double aZ,double aW = 1) {
return parent::fill(aX,aY,aZ,aW);
}
void hprint(std::ostream& a_out) {parent::hprint(a_out);}
#endif
private:static void check_instantiation() {h3d dummy("",10,0,1,10,0,1,10,0,1);}
};
@@ -0,0 +1,57 @@
// 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(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>& aEdgesX,
const std::vector<double>& aEdgesY,
const std::vector<double>& aEdgesZ)
:parent(a_title,aEdgesX,aEdgesY,aEdgesZ)
{}
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
@@ -7,33 +7,35 @@
#include <vector>
#include <map> //for annotations
#include "axis"
#include "axes"
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.
template <class TC,class TN,class TW>
template <class TC,class TO,class TN,class TW>
class histo_data {
public:
typedef typename axis<TC>::bn_t bn_t;
typedef axis<TC,TO> axis_t;
typedef unsigned int dim_t;
public:
histo_data()
:m_dimension(0)
,m_bin_number(0)
//,m_mode(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_mode(a_from.m_mode)
// Arrays :
,m_bin_entries(a_from.m_bin_entries)
,m_bin_Sw(a_from.m_bin_Sw)
,m_bin_Sw2(a_from.m_bin_Sw2)
@@ -41,65 +43,79 @@ public:
,m_bin_Sx2w(a_from.m_bin_Sx2w)
,m_axes(a_from.m_axes)
,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_mode = a_from.m_mode;
// Arrays :
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_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(){}
public:
void base_reset() { //used in multiply,divide.
// Reset content (different of clear that deallocate all internal things).
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
m_bin_entries[ibin] = 0;
m_bin_Sw[ibin] = 0;
m_bin_Sw2[ibin] = 0;
for(dim_t iaxis=0;iaxis<m_dimension;iaxis++) {
m_bin_Sxw[ibin][iaxis] = 0;
m_bin_Sx2w[ibin][iaxis] = 0;
}
}
}
public:
// for BatchLab::Rio::TH::streamTH1 :
TN get_entries() const {
TN number = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
number += m_bin_entries[ibin];
}
}
return number;
}
// for inlib/rroot/streamers :
TW get_Sw() const {
TW sw = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
for(TO ibin=0;ibin<m_bin_number;ibin++) {
if(!histo::is_out(m_axes,ibin)) {
sw += m_bin_Sw[ibin];
}
}
return sw;
}
/*
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;
}
*/
TW get_Sw2() const {
TW sw2 = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
for(TO ibin=0;ibin<m_bin_number;ibin++) {
if(!histo::is_out(m_axes,ibin)) {
sw2 += m_bin_Sw2[ibin];
}
}
@@ -109,8 +125,8 @@ public:
bool get_ith_axis_Sxw(dim_t a_axis,TC& a_value) const {
a_value = 0;
if(a_axis>=m_dimension) return false;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
for(TO ibin=0;ibin<m_bin_number;ibin++) {
if(!histo::is_out(m_axes,ibin)) {
a_value += m_bin_Sxw[ibin][a_axis];
}
}
@@ -120,68 +136,38 @@ public:
bool get_ith_axis_Sx2w(dim_t a_axis,TC& a_value) const {
a_value = 0;
if(a_axis>=m_dimension) return false;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
for(TO ibin=0;ibin<m_bin_number;ibin++) {
if(!histo::is_out(m_axes,ibin)) {
a_value += m_bin_Sx2w[ibin][a_axis];
}
}
return true;
}
TN get_all_entries() const {
TN number = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
number += m_bin_entries[ibin];
}
return number;
protected:
void reset_fast_getters(){
m_all_entries = 0;
m_in_range_entries = 0;
m_in_range_Sw = 0;
m_in_range_Sw2 = 0;
m_in_range_Sxw.resize(m_dimension,0);
m_in_range_Sx2w.resize(m_dimension,0);
}
bool is_out(bn_t aOffset) const {
int offset = aOffset;
int index;
for(int iaxis=m_dimension-1;iaxis>=0;iaxis--) {
index = offset/m_axes[iaxis].m_offset;
if(index==0) return true;
if(index==(int(m_axes[iaxis].m_number_of_bins)+1)) return true;
offset -= index * m_axes[iaxis].m_offset;
}
return false;
}
void get_indices(bn_t aOffset,std::vector<int>& aIs) const {
int offset = aOffset;
{for(int iaxis=m_dimension-1;iaxis>=0;iaxis--) {
aIs[iaxis] = offset/m_axes[iaxis].m_offset;
offset -= aIs[iaxis] * m_axes[iaxis].m_offset;
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];
}}
for(dim_t iaxis=0;iaxis<m_dimension;iaxis++) {
if(aIs[iaxis]==0) {
aIs[iaxis] = axis<TC>::UNDERFLOW_BIN;
} else if(aIs[iaxis]==int(m_axes[iaxis].m_number_of_bins)+1) {
aIs[iaxis] = axis<TC>::OVERFLOW_BIN;
} else {
aIs[iaxis]--;
}
}
}
// for raxml :
bool get_offset(const std::vector<int>& aIs,bn_t& a_offset) const {
// aIs[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(!m_dimension) return false;
bn_t ibin;
for(dim_t iaxis=0;iaxis<m_dimension;iaxis++) {
if(!m_axes[iaxis].in_range_to_absolute_index(aIs[iaxis],ibin)) {
a_offset = 0;
return false;
}
a_offset += ibin * m_axes[iaxis].m_offset;
}
return true;
}
public:
@@ -189,16 +175,23 @@ public:
std::string m_title;
dim_t m_dimension;
// Bins :
bn_t m_bin_number;
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<TC> > m_axes;
std::vector<axis_t> m_axes;
// etc :
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;
};
}}
+114 -57
View File
@@ -11,25 +11,28 @@ namespace tools {
namespace histo {
//TC is for a coordinate.
//TO is for an offset/index to identify/find a bind.
//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 TN,class TW,class TH,class TV>
class p1 : public b1<TC,TN,TW,TH> {
typedef b1<TC,TN,TW,TH> parent;
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 typename base_histo<TC,TN,TW,TH>::bn_t bn_t;
typedef profile_data<TC,TO,TN,TW,TV> pd_t;
typedef typename parent::bn_t bn_t;
typedef histo::axis<TC,TO> axis_t;
typedef std::vector<TV> vs_t;
protected:
virtual TH get_bin_height(int a_offset) const {
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:
virtual TH bin_error(int aI) const { //TH should be the same as TV
if(parent::m_bin_number==0) return 0;
bn_t offset;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,offset)) return 0;
TO offset;
if(!parent::_find_offset(aI,offset)) return 0;
//FIXME Is it correct ?
// TProfile::GetBinError with kERRORMEAN mode does :
@@ -43,7 +46,7 @@ public:
// 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
@@ -55,26 +58,23 @@ public:
}
public:
bool multiply(TW aFactor){
if(!parent::base_multiply(aFactor)) return false;
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] *= aFactor;
m_bin_Svw[ibin] *= a_factor;
}
parent::update_fast_getters();
return true;
}
bool scale(TW aFactor) {return multiply(aFactor);}
bool scale(TW a_factor) {return multiply(a_factor);}
TV bin_Svw(int aI) const {
if(parent::m_bin_number==0) return 0;
bn_t offset;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,offset)) return 0;
TO offset;
if(!parent::_find_offset(aI,offset)) return 0;
return m_bin_Svw[offset];
}
TV bin_Sv2w(int aI) const {
if(parent::m_bin_number==0) return 0;
bn_t offset;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,offset)) return 0;
TO offset;
if(!parent::_find_offset(aI,offset)) return 0;
return m_bin_Sv2w[offset];
}
@@ -84,11 +84,10 @@ public:
m_bin_Svw[ibin] = 0;
m_bin_Sv2w[ibin] = 0;
}
parent::update_fast_getters();
return true;
}
void copy_from_data(const profile_data<TC,TN,TW,TV>& a_from) {
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;
@@ -96,8 +95,8 @@ public:
m_min_v = a_from.m_min_v;
m_max_v = a_from.m_max_v;
}
profile_data<TC,TN,TW,TV> get_histo_data() const {
profile_data<TC,TN,TW,TV> hd(parent::base_get_data());
pd_t get_histo_data() const {
pd_t hd(parent::base_get_data());
hd.m_is_profile = true;
hd.m_bin_Svw = m_bin_Svw;
hd.m_bin_Sv2w = m_bin_Sv2w;
@@ -108,18 +107,17 @@ public:
}
bool fill(TC aX,TV aV,TW aWeight = 1) {
//m_coords[0] = aX;
//return fill_bin(m_coords,aV,aWeight);
if(parent::m_dimension!=1) return false;
if(!parent::m_dimension) return false;
if(m_cut_v) {
if( (aV<m_min_v) || (aV>=m_max_v) ) {
return true;
}
}
bn_t offset;
if(!parent::m_axes[0].coord_to_absolute_index(aX,offset)) 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;
@@ -130,6 +128,20 @@ public:
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) {
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;
@@ -139,10 +151,8 @@ public:
}
TV bin_rms_value(int aI) const {
if(parent::m_bin_number==0) return 0;
bn_t offset;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,offset)) return 0;
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];
@@ -157,7 +167,6 @@ public:
m_bin_Svw[ibin] += a_histo.m_bin_Svw[ibin];
m_bin_Sv2w[ibin] += a_histo.m_bin_Sv2w[ibin];
}
parent::update_fast_getters();
return true;
}
bool subtract(const p1& a_histo){
@@ -166,7 +175,6 @@ public:
m_bin_Svw[ibin] -= a_histo.m_bin_Svw[ibin];
m_bin_Sv2w[ibin] -= a_histo.m_bin_Sv2w[ibin];
}
parent::update_fast_getters();
return true;
}
@@ -175,7 +183,7 @@ public:
// actual bin number must be a multiple of a_factor.
const histo::axis<TC>& _axis = parent::axis();
const axis_t& _axis = parent::axis();
bn_t n = _axis.bins();
if(!n) return false;
@@ -185,8 +193,7 @@ public:
p1* new_h = 0;
if(_axis.is_fixed_binning()) {
new_h = new p1(parent::m_title,
new_n,_axis.lower_edge(),_axis.upper_edge());
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);
@@ -250,9 +257,8 @@ public:
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)
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)
@@ -261,10 +267,8 @@ public:
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)
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)
@@ -273,9 +277,8 @@ public:
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
p1(const std::string& a_title,
const std::vector<TC>& aEdges)
: parent(a_title,aEdges)
p1(const std::string& a_title,const std::vector<TC>& aEdges)
:parent(a_title,aEdges)
,m_cut_v(false)
,m_min_v(0)
,m_max_v(0)
@@ -284,10 +287,8 @@ public:
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
p1(const std::string& a_title,
const std::vector<TC>& aEdges,
TV aVmin,TV aVmax)
: parent(a_title,aEdges)
p1(const std::string& a_title,const std::vector<TC>& aEdges,TV aVmin,TV aVmax)
:parent(a_title,aEdges)
,m_cut_v(true)
,m_min_v(aVmin)
,m_max_v(aVmax)
@@ -299,7 +300,7 @@ public:
virtual ~p1(){}
public:
p1(const p1& a_from)
: parent(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)
@@ -316,14 +317,70 @@ public:
return *this;
}
public:
const std::vector<TV>& bins_sum_vw() const {return m_bin_Svw;}
const std::vector<TV>& bins_sum_v2w() const {return m_bin_Sv2w;}
bool configure(bn_t aXnumber,TC aXmin,TC aXmax){
if(!parent::configure(aXnumber,aXmin,aXmax)) return false;
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>& aEdges) {
if(!parent::configure(aEdges)) return false;
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.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>& aEdges,TV aVmin,TV aVmax) {
if(!parent::configure(aEdges)) return false;
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;
std::vector<TV> m_bin_Svw;
std::vector<TV> m_bin_Sv2w;
vs_t m_bin_Svw;
vs_t m_bin_Sv2w;
};
}}
@@ -9,17 +9,17 @@
namespace tools {
namespace histo {
class p1d : public p1<double,unsigned int,double,double,double> {
typedef p1<double,unsigned int,double,double,double> parent;
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(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)
:parent(a_title,aXnumber,aXmin,aXmax)
{}
p1d(const std::string& a_title,
@@ -46,10 +46,6 @@ public:
parent::operator=(a_from);
return *this;
}
public:
#ifdef __CINT__
bool fill(double aX,double aY,double aW = 1) {return parent::fill(aX,aY,aW);}
#endif
private:static void check_instantiation() {p1d p("",10,0,1);p.gather_bins(5);}
};
+106 -70
View File
@@ -10,24 +10,22 @@
namespace tools {
namespace histo {
template <class TC,class TN,class TW,class TH,class TV>
class p2 : public b2<TC,TN,TW,TH> {
typedef b2<TC,TN,TW,TH> parent;
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 typename base_histo<TC,TN,TW,TH>::bn_t bn_t;
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(int a_offset) const {
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:
virtual TH bin_error(int aI,int aJ) const { //TH should be the same as TV
if(parent::m_bin_number==0) return 0;
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
bn_t jbin;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
TO offset;
if(!parent::_find_offset(aI,aJ,offset)) return 0;
//FIXME Is it correct ?
// TProfile::GetBinError with kERRORMEAN mode does :
@@ -53,32 +51,23 @@ public:
}
public:
bool multiply(TW aFactor){
if(!parent::base_multiply(aFactor)) return false;
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] *= aFactor;
m_bin_Svw[ibin] *= a_factor;
}
parent::update_fast_getters();
return true;
}
bool scale(TW aFactor) {return multiply(aFactor);}
bool scale(TW a_factor) {return multiply(a_factor);}
TV bin_Svw(int aI,int aJ) const {
if(parent::m_bin_number==0) return 0;
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
bn_t jbin;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
TO offset;
if(!parent::_find_offset(aI,aJ,offset)) return 0;
return m_bin_Svw[offset];
}
TV bin_Sv2w(int aI,int aJ) const {
if(parent::m_bin_number==0) return 0;
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
bn_t jbin;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
TO offset;
if(!parent::_find_offset(aI,aJ,offset)) return 0;
return m_bin_Sv2w[offset];
}
@@ -88,11 +77,10 @@ public:
m_bin_Svw[ibin] = 0;
m_bin_Sv2w[ibin] = 0;
}
parent::update_fast_getters();
return true;
}
void copy_from_data(const profile_data<TC,TN,TW,TV>& a_from) {
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;
@@ -100,8 +88,8 @@ public:
m_min_v = a_from.m_min_v;
m_max_v = a_from.m_max_v;
}
profile_data<TC,TN,TW,TV> get_histo_data() const {
profile_data<TC,TN,TW,TV> hd(parent::base_get_data());
pd_t get_histo_data() const {
pd_t hd(parent::base_get_data());
hd.m_is_profile = true;
hd.m_bin_Svw = m_bin_Svw;
hd.m_bin_Sv2w = m_bin_Sv2w;
@@ -112,18 +100,14 @@ public:
}
bool fill(TC aX,TC aY,TV aV,TW aWeight = 1) {
//m_coords[0] = aX;
//m_coords[1] = aY;
//return fill_bin(m_coords,aV,aWeight);
if(parent::m_dimension!=2) return false;
if(m_cut_v) {
if( (aV<m_min_v) || (aV>=m_max_v) ) {
return true;
}
}
if(parent::m_dimension<=0) 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;
@@ -150,15 +134,17 @@ public:
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_entries++;
parent::m_in_range_Sw += aWeight;
parent::m_in_range_Sw2 += aWeight*aWeight;
parent::m_in_range_Sxw += xw;
parent::m_in_range_Sx2w += x2w;
parent::m_in_range_Syw += yw;
parent::m_in_range_Sy2w += y2w;
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 :
@@ -170,12 +156,8 @@ public:
}
TV bin_rms_value(int aI,int aJ) const {
if(parent::m_bin_number==0) return 0;
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
bn_t jbin;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
TO offset;
if(!parent::_find_offset(aI,aJ,offset)) return 0;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
@@ -191,7 +173,6 @@ public:
m_bin_Svw[ibin] += a_histo.m_bin_Svw[ibin];
m_bin_Sv2w[ibin] += a_histo.m_bin_Sv2w[ibin];
}
parent::update_fast_getters();
return true;
}
bool subtract(const p2& a_histo){
@@ -200,7 +181,6 @@ public:
m_bin_Svw[ibin] -= a_histo.m_bin_Svw[ibin];
m_bin_Sv2w[ibin] -= a_histo.m_bin_Sv2w[ibin];
}
parent::update_fast_getters();
return true;
}
@@ -209,9 +189,9 @@ public:
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)
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)
@@ -221,10 +201,10 @@ public:
}
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)
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)
@@ -234,9 +214,9 @@ public:
}
p2(const std::string& a_title,
const std::vector<TC>& aEdgesX,
const std::vector<TC>& aEdgesY)
: parent(a_title,aEdgesX,aEdgesY)
const std::vector<TC>& aEdgesX,
const std::vector<TC>& aEdgesY)
:parent(a_title,aEdgesX,aEdgesY)
,m_cut_v(false)
,m_min_v(0)
,m_max_v(0)
@@ -246,10 +226,10 @@ public:
}
p2(const std::string& a_title,
const std::vector<TC>& aEdgesX,
const std::vector<TC>& aEdgesY,
TV aVmin,TV aVmax)
: parent(a_title,aEdgesX,aEdgesY)
const std::vector<TC>& aEdgesX,
const std::vector<TC>& aEdgesY,
TV aVmin,TV aVmax)
:parent(a_title,aEdgesX,aEdgesY)
,m_cut_v(true)
,m_min_v(aVmin)
,m_max_v(aVmax)
@@ -261,7 +241,7 @@ public:
virtual ~p2(){}
public:
p2(const p2& a_from)
: parent(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)
@@ -278,14 +258,70 @@ public:
return *this;
}
public:
const std::vector<TV>& bins_sum_vw() const {return m_bin_Svw;}
const std::vector<TV>& bins_sum_v2w() const {return m_bin_Sv2w;}
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.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>& aEdgesX,const std::vector<TC>& aEdgesY) {
if(!parent::configure(aEdgesX,aEdgesY)) return false;
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.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>& aEdgesX,const std::vector<TC>& aEdgesY,TV aVmin,TV aVmax) {
if(!parent::configure(aEdgesX,aEdgesY)) return false;
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;
std::vector<TV> m_bin_Svw;
std::vector<TV> m_bin_Sv2w;
vs_t m_bin_Svw;
vs_t m_bin_Sv2w;
};
}}
@@ -9,13 +9,14 @@
namespace tools {
namespace histo {
class p2d : public p2<double,unsigned int,double,double,double> {
typedef p2<double,unsigned int,double,double,double> parent;
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(const std::string& a_title,
unsigned int aXnumber,double aXmin,double aXmax,
@@ -9,19 +9,20 @@
namespace tools {
namespace histo {
template <class TC,class TN,class TW,class TV>
class profile_data : public histo_data<TC,TN,TW> {
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:
profile_data()
: histo_data<TC,TN,TW>()
:parent()
,m_is_profile(true)
,m_cut_v(false)
,m_min_v(0)
,m_max_v(0)
{}
profile_data(const histo_data<TC,TN,TW>& a_from)
: histo_data<TC,TN,TW>(a_from)
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)
@@ -30,7 +31,7 @@ public:
public:
profile_data(const profile_data& a_from)
: histo_data<TC,TN,TW>(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)
@@ -40,7 +41,7 @@ public:
{}
profile_data& operator=(const profile_data& a_from) {
histo_data<TC,TN,TW>::operator=(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;
@@ -53,9 +54,10 @@ public:
virtual ~profile_data(){}
public:
profile_data& operator=(const histo_data<TC,TN,TW>& a_from) {
profile_data& operator=(const histo_data<TC,TO,TN,TW>& a_from) {
//for Rio_THisogram.
histo_data<TC,TN,TW>::operator=(a_from);
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();
@@ -11,14 +11,14 @@
namespace tools {
namespace histo {
template <class TC,class TN,class TW,class TH>
inline bool fill_slice_x(const h2<TC,TN,TW,TH>& a_from,
template <class TC,class TO,class TN,class TW,class TH>
inline bool fill_slice_x(const h2<TC,TO,TN,TW,TH>& a_from,
int aJbeg,int aJend,
h1<TC,TN,TW,TH>& a_to) {
h1<TC,TO,TN,TW,TH>& a_to) {
if(!a_from.dimension()) return false;
typedef typename axis<TC>::bn_t bn_t;
typedef typename axis<TC,TO>::bn_t bn_t;
bn_t jbeg;
if(!a_from.axis_y().in_range_to_absolute_index(aJbeg,jbeg)) return false;
@@ -28,7 +28,7 @@ inline bool fill_slice_x(const h2<TC,TN,TW,TH>& a_from,
if(a_from.axis_x().bins()!=a_to.axis().bins()) return false;
histo_data<TC,TN,TW> hdata = a_to.get_histo_data();
histo_data<TC,TO,TN,TW> hdata = a_to.get_histo_data();
bn_t aoffset,offset,jbin;
bn_t yoffset = a_from.axis_y().m_offset;
@@ -56,16 +56,16 @@ inline bool fill_slice_x(const h2<TC,TN,TW,TH>& a_from,
hdata.m_bin_Sx2w[aoffset][0] += af_bin_Sx2w[offset][0];
}
}
hdata.update_fast_getters();
a_to.copy_from_data(hdata);
a_to.update_fast_getters();
return true;
}
template <class TC,class TN,class TW,class TH>
inline h1<TC,TN,TW,TH>* slice_x(const h2<TC,TN,TW,TH>& a_from,
template <class TC,class TO,class TN,class TW,class TH>
inline h1<TC,TO,TN,TW,TH>* slice_x(const h2<TC,TO,TN,TW,TH>& a_from,
int aJbeg,int aJend,
const std::string& a_title) {
h1<TC,TN,TW,TH>* slice = new h1<TC,TN,TW,TH>(a_title,
h1<TC,TO,TN,TW,TH>* slice = new h1<TC,TO,TN,TW,TH>(a_title,
a_from.axis_x().bins(),
a_from.axis_x().lower_edge(),
a_from.axis_x().upper_edge());
@@ -73,19 +73,19 @@ inline h1<TC,TN,TW,TH>* slice_x(const h2<TC,TN,TW,TH>& a_from,
return slice;
}
template <class TC,class TN,class TW,class TH>
inline h1<TC,TN,TW,TH>* projection_x(const h2<TC,TN,TW,TH>& a_from,const std::string& a_title) {
return slice_x(a_from,axis<TC>::UNDERFLOW_BIN,axis<TC>::OVERFLOW_BIN,a_title);
template <class TC,class TO,class TN,class TW,class TH>
inline h1<TC,TO,TN,TW,TH>* projection_x(const h2<TC,TO,TN,TW,TH>& a_from,const std::string& a_title) {
return slice_x(a_from,axis<TC,TO>::UNDERFLOW_BIN,axis<TC,TO>::OVERFLOW_BIN,a_title);
}
template <class TC,class TN,class TW,class TH>
inline bool fill_slice_y(const h2<TC,TN,TW,TH>& a_from,
template <class TC,class TO,class TN,class TW,class TH>
inline bool fill_slice_y(const h2<TC,TO,TN,TW,TH>& a_from,
int aIbeg,int aIend,
h1<TC,TN,TW,TH>& a_to) {
h1<TC,TO,TN,TW,TH>& a_to) {
if(!a_from.dimension()) return false;
typedef typename axis<TC>::bn_t bn_t;
typedef typename axis<TC,TO>::bn_t bn_t;
bn_t ibeg;
if(!a_from.axis_x().in_range_to_absolute_index(aIbeg,ibeg)) return false;
@@ -95,7 +95,7 @@ inline bool fill_slice_y(const h2<TC,TN,TW,TH>& a_from,
if(a_from.axis_y().bins()!=a_to.axis().bins()) return false;
histo_data<TC,TN,TW> hdata = a_to.get_histo_data();
histo_data<TC,TO,TN,TW> hdata = a_to.get_histo_data();
bn_t aibin,aoffset,offset,ibin;
bn_t yoffset = a_from.axis_y().m_offset;
@@ -123,16 +123,16 @@ inline bool fill_slice_y(const h2<TC,TN,TW,TH>& a_from,
hdata.m_bin_Sx2w[aoffset][0] += af_bin_Sx2w[offset][1];
}
}
hdata.update_fast_getters();
a_to.copy_from_data(hdata);
a_to.update_fast_getters();
return true;
}
template <class TC,class TN,class TW,class TH>
inline h1<TC,TN,TW,TH>* slice_y(const h2<TC,TN,TW,TH>& a_from,
template <class TC,class TO,class TN,class TW,class TH>
inline h1<TC,TO,TN,TW,TH>* slice_y(const h2<TC,TO,TN,TW,TH>& a_from,
int aIbeg,int aIend,
const std::string& a_title) {
h1<TC,TN,TW,TH>* slice = new h1<TC,TN,TW,TH>(a_title,
h1<TC,TO,TN,TW,TH>* slice = new h1<TC,TO,TN,TW,TH>(a_title,
a_from.axis_y().bins(),
a_from.axis_y().lower_edge(),
a_from.axis_y().upper_edge());
@@ -140,19 +140,19 @@ inline h1<TC,TN,TW,TH>* slice_y(const h2<TC,TN,TW,TH>& a_from,
return slice;
}
template <class TC,class TN,class TW,class TH>
inline h1<TC,TN,TW,TH>* projection_y(const h2<TC,TN,TW,TH>& a_from,const std::string& a_title) {
return slice_y(a_from,axis<TC>::UNDERFLOW_BIN,axis<TC>::OVERFLOW_BIN,a_title);
template <class TC,class TO,class TN,class TW,class TH>
inline h1<TC,TO,TN,TW,TH>* projection_y(const h2<TC,TO,TN,TW,TH>& a_from,const std::string& a_title) {
return slice_y(a_from,axis<TC,TO>::UNDERFLOW_BIN,axis<TC,TO>::OVERFLOW_BIN,a_title);
}
template <class TC,class TN,class TW,class TH>
inline bool fill_slice_yz(const h3<TC,TN,TW,TH>& a_from,
int aIbeg,int aIend,h2<TC,TN,TW,TH>& a_to) {
template <class TC,class TO,class TN,class TW,class TH>
inline bool fill_slice_yz(const h3<TC,TO,TN,TW,TH>& a_from,
int aIbeg,int aIend,h2<TC,TO,TN,TW,TH>& a_to) {
if(!a_from.dimension()) return false;
typedef typename axis<TC>::bn_t bn_t;
typedef typename axis<TC,TO>::bn_t bn_t;
bn_t ibeg;
if(!a_from.axis_x().in_range_to_absolute_index(aIbeg,ibeg)) return false;
@@ -163,7 +163,7 @@ inline bool fill_slice_yz(const h3<TC,TN,TW,TH>& a_from,
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;
histo_data<TC,TN,TW> hdata = a_to.get_histo_data();
histo_data<TC,TO,TN,TW> hdata = a_to.get_histo_data();
bn_t aibin,ajbin,aoffset,offset,ibin;
@@ -201,18 +201,18 @@ inline bool fill_slice_yz(const h3<TC,TN,TW,TH>& a_from,
}
}
}
hdata.update_fast_getters();
a_to.copy_from_data(hdata);
a_to.update_fast_getters();
return true;
}
template <class TC,class TN,class TW,class TH>
inline bool fill_slice_xy(const h3<TC,TN,TW,TH>& a_from,
int aKbeg,int aKend,h2<TC,TN,TW,TH>& a_to) {
template <class TC,class TO,class TN,class TW,class TH>
inline bool fill_slice_xy(const h3<TC,TO,TN,TW,TH>& a_from,
int aKbeg,int aKend,h2<TC,TO,TN,TW,TH>& a_to) {
if(!a_from.dimension()) return false;
typedef typename axis<TC>::bn_t bn_t;
typedef typename axis<TC,TO>::bn_t bn_t;
bn_t kbeg;
if(!a_from.axis_z().in_range_to_absolute_index(aKbeg,kbeg)) return false;
@@ -223,7 +223,7 @@ inline bool fill_slice_xy(const h3<TC,TN,TW,TH>& a_from,
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;
histo_data<TC,TN,TW> hdata = a_to.get_histo_data();
histo_data<TC,TO,TN,TW> hdata = a_to.get_histo_data();
bn_t kbin;
bn_t aibin,ajbin,aoffset,offset;
@@ -262,18 +262,18 @@ inline bool fill_slice_xy(const h3<TC,TN,TW,TH>& a_from,
}
}
}
hdata.update_fast_getters();
a_to.copy_from_data(hdata);
a_to.update_fast_getters();
return true;
}
template <class TC,class TN,class TW,class TH>
inline bool fill_slice_xz(const h3<TC,TN,TW,TH>& a_from,
int aJbeg,int aJend,h2<TC,TN,TW,TH>& a_to) {
template <class TC,class TO,class TN,class TW,class TH>
inline bool fill_slice_xz(const h3<TC,TO,TN,TW,TH>& a_from,
int aJbeg,int aJend,h2<TC,TO,TN,TW,TH>& a_to) {
if(!a_from.dimension()) return false;
typedef typename axis<TC>::bn_t bn_t;
typedef typename axis<TC,TO>::bn_t bn_t;
bn_t jbeg;
if(!a_from.axis_y().in_range_to_absolute_index(aJbeg,jbeg)) return false;
@@ -284,7 +284,7 @@ inline bool fill_slice_xz(const h3<TC,TN,TW,TH>& a_from,
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;
histo_data<TC,TN,TW> hdata = a_to.get_histo_data();
histo_data<TC,TO,TN,TW> hdata = a_to.get_histo_data();
bn_t aibin,ajbin,aoffset,offset,jbin;
@@ -323,17 +323,17 @@ inline bool fill_slice_xz(const h3<TC,TN,TW,TH>& a_from,
}
}
hdata.update_fast_getters();
a_to.copy_from_data(hdata);
a_to.update_fast_getters();
return true;
}
template <class TC,class TN,class TW,class TH>
inline h2<TC,TN,TW,TH>* slice_xy(const h3<TC,TN,TW,TH>& a_from,
template <class TC,class TO,class TN,class TW,class TH>
inline h2<TC,TO,TN,TW,TH>* slice_xy(const h3<TC,TO,TN,TW,TH>& a_from,
int aKbeg,int aKend,
const std::string& a_title) {
h2<TC,TN,TW,TH>* slice = new h2<TC,TN,TW,TH>(a_title,
h2<TC,TO,TN,TW,TH>* slice = new h2<TC,TO,TN,TW,TH>(a_title,
a_from.axis_x().bins(),
a_from.axis_x().lower_edge(),
a_from.axis_x().upper_edge(),
@@ -344,11 +344,11 @@ inline h2<TC,TN,TW,TH>* slice_xy(const h3<TC,TN,TW,TH>& a_from,
return slice;
}
template <class TC,class TN,class TW,class TH>
inline h2<TC,TN,TW,TH>* slice_yz(const h3<TC,TN,TW,TH>& a_from,
template <class TC,class TO,class TN,class TW,class TH>
inline h2<TC,TO,TN,TW,TH>* slice_yz(const h3<TC,TO,TN,TW,TH>& a_from,
int aIbeg,int aIend,
const std::string& a_title) {
h2<TC,TN,TW,TH>* slice = new h2<TC,TN,TW,TH>(a_title,
h2<TC,TO,TN,TW,TH>* slice = new h2<TC,TO,TN,TW,TH>(a_title,
a_from.axis_y().bins(),
a_from.axis_y().lower_edge(),
a_from.axis_y().upper_edge(),
@@ -359,11 +359,11 @@ inline h2<TC,TN,TW,TH>* slice_yz(const h3<TC,TN,TW,TH>& a_from,
return slice;
}
template <class TC,class TN,class TW,class TH>
inline h2<TC,TN,TW,TH>* slice_xz(const h3<TC,TN,TW,TH>& a_from,
template <class TC,class TO,class TN,class TW,class TH>
inline h2<TC,TO,TN,TW,TH>* slice_xz(const h3<TC,TO,TN,TW,TH>& a_from,
int aJbeg,int aJend,
const std::string& a_title) {
h2<TC,TN,TW,TH>* slice = new h2<TC,TN,TW,TH>(a_title,
h2<TC,TO,TN,TW,TH>* slice = new h2<TC,TO,TN,TW,TH>(a_title,
a_from.axis_x().bins(),
a_from.axis_x().lower_edge(),
a_from.axis_x().upper_edge(),
@@ -24,7 +24,8 @@ inline h1d* slice_x(const h2d& a_from,
}
inline h1d* projection_x(const h2d& a_from,const std::string& a_title) {
return slice_x(a_from,axis<double>::UNDERFLOW_BIN,axis<double>::OVERFLOW_BIN,a_title);
typedef axis<double,unsigned int> axis_t;
return slice_x(a_from,axis_t::UNDERFLOW_BIN,axis_t::OVERFLOW_BIN,a_title);
}
inline h1d* slice_y(const h2d& a_from,
@@ -39,7 +40,8 @@ inline h1d* slice_y(const h2d& a_from,
}
inline h1d* projection_y(const h2d& a_from,const std::string& a_title) {
return slice_y(a_from,axis<double>::UNDERFLOW_BIN,axis<double>::OVERFLOW_BIN,a_title);
typedef axis<double,unsigned int> axis_t;
return slice_y(a_from,axis_t::UNDERFLOW_BIN,axis_t::OVERFLOW_BIN,a_title);
}
inline h2d* slice_xy(const h3d& a_from,
@@ -57,7 +59,8 @@ inline h2d* slice_xy(const h3d& a_from,
}
inline h2d* projection_xy(const h3d& a_from,const std::string& a_title) {
return slice_xy(a_from,axis<double>::UNDERFLOW_BIN,axis<double>::OVERFLOW_BIN,a_title);
typedef axis<double,unsigned int> axis_t;
return slice_xy(a_from,axis_t::UNDERFLOW_BIN,axis_t::OVERFLOW_BIN,a_title);
}
inline h2d* slice_yz(const h3d& a_from,
@@ -75,7 +78,8 @@ inline h2d* slice_yz(const h3d& a_from,
}
inline h2d* projection_yz(const h3d& a_from,const std::string& a_title) {
return slice_yz(a_from,axis<double>::UNDERFLOW_BIN,axis<double>::OVERFLOW_BIN,a_title);
typedef axis<double,unsigned int> axis_t;
return slice_yz(a_from,axis_t::UNDERFLOW_BIN,axis_t::OVERFLOW_BIN,a_title);
}
inline h2d* slice_xz(const h3d& a_from,
@@ -93,7 +97,8 @@ inline h2d* slice_xz(const h3d& a_from,
}
inline h2d* projection_xz(const h3d& a_from,const std::string& a_title) {
return slice_xz(a_from,axis<double>::UNDERFLOW_BIN,axis<double>::OVERFLOW_BIN,a_title);
typedef axis<double,unsigned int> axis_t;
return slice_xz(a_from,axis_t::UNDERFLOW_BIN,axis_t::OVERFLOW_BIN,a_title);
}
}}
@@ -1,71 +0,0 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_iobj_const_visitor
#define tools_iobj_const_visitor
#include "typedefs"
#include <string>
#include <vector>
namespace tools {
class iobj_const_visitor;
class istorable {
public:
virtual ~istorable() {}
//public:
// virtual void* cast(const std::string&) const = 0;
public:
virtual bool visit(iobj_const_visitor&) const = 0;
// virtual bool read(IVisitor&) = 0;
};
class iobj_const_visitor {
public:
virtual ~iobj_const_visitor() {}
public:
//typedef bool(*Local)(const Slash::Store::istorable&,
// iobj_const_visitor&);
public:
//virtual bool begin(const istorable&,const std::string&,Local) = 0;
//virtual bool end(const istorable&) = 0;
virtual bool visit(const std::string&,bool) = 0;
virtual bool visit(const std::string&,char) = 0;
//virtual bool visit(const std::string&,unsigned char) = 0;
virtual bool visit(const std::string&,short) = 0;
//virtual bool visit(const std::string&,unsigned short) = 0;
virtual bool visit(const std::string&,int) = 0;
virtual bool visit(const std::string&,unsigned int) = 0;
virtual bool visit(const std::string&,int64) = 0;
virtual bool visit(const std::string&,uint64) = 0;
virtual bool visit(const std::string&,float) = 0;
virtual bool visit(const std::string&,double) = 0;
virtual bool visit(const std::string&,const std::string&) = 0;
//virtual bool visit(const std::string&,const char*) = 0;
virtual bool visit(const std::string&,const std::vector<bool>&) = 0;
virtual bool visit(const std::string&,const std::vector<char>&) = 0;
virtual bool visit(const std::string&,const std::vector<short>&) = 0;
virtual bool visit(const std::string&,const std::vector<int>&) = 0;
virtual bool visit(const std::string&,const std::vector<int64>&) = 0;
virtual bool visit(const std::string&,const std::vector<float>&) = 0;
virtual bool visit(const std::string&,const std::vector<double>&) = 0;
//virtual bool visit(const std::string&,const std::vector<unsigned char>&) = 0;
virtual bool visit(const std::string&,const std::vector<std::string>&) = 0;
virtual bool visit(const std::string&,const std::vector< std::vector<double> >&) = 0;
//virtual bool visit_double(const std::string&,const IArray&) = 0;
virtual bool visit(const std::string&,const istorable&) = 0;
};
}
#endif
@@ -1,48 +0,0 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_iobj_visitor
#define tools_iobj_visitor
#include "typedefs"
#include <string>
#include <vector>
#include <ostream>
namespace tools {
class iobj_visitor {
public:
virtual ~iobj_visitor() {}
public:
virtual std::ostream& out() = 0;
//virtual bool begin(IStorable&) = 0;
//virtual bool end(IStorable&) = 0;
virtual bool visit(bool&) = 0;
virtual bool visit(char&) = 0;
virtual bool visit(short&) = 0;
virtual bool visit(int&) = 0;
virtual bool visit(unsigned int&) = 0;
virtual bool visit(int64&) = 0;
virtual bool visit(uint64&) = 0;
virtual bool visit(float&) = 0;
virtual bool visit(double&) = 0;
virtual bool visit(std::string&) = 0;
virtual bool visit(std::vector<bool>&) = 0;
virtual bool visit(std::vector<char>&) = 0;
virtual bool visit(std::vector<short>&) = 0;
virtual bool visit(std::vector<int>&) = 0;
virtual bool visit(std::vector<int64>&) = 0;
virtual bool visit(std::vector<float>&) = 0;
virtual bool visit(std::vector<double>&) = 0;
virtual bool visit(std::vector<unsigned char>&) = 0;
virtual bool visit(std::vector<std::string>&) = 0;
virtual bool visit(std::vector< std::vector<double> >&) = 0;
//virtual bool visit_double(IArray&) = 0;
};
}
#endif
+2 -7
View File
@@ -20,13 +20,6 @@ inline double half_pi() {return 1.5707963267948965580E0;}
inline double deg2rad() {return pi()/180.0;}
template <class T>
inline T power(const T& a_A,unsigned int a_B){
T v = T(1);
for(unsigned int i=0;i<a_B;i++) v *= a_A;
return v;
}
// for Lib/ExpFunc.
inline bool in_domain_all(double){return true;}
inline bool in_domain_log(double a_x){return (a_x>0?true:false);}
@@ -42,4 +35,6 @@ inline bool in_domain_acos(double a_x){
}
//#include "power"
#endif
@@ -0,0 +1,40 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_mathd
#define tools_mathd
namespace tools {
//have : static const pi = 3.1415926535897931160E0; ???
//HEALPix lsconstants.h. Quite not the same as us.
//const double pi=3.141592653589793238462643383279502884197;
//const double twopi=6.283185307179586476925286766559005768394;
//const double fourpi=12.56637061435917295385057353311801153679;
//const double halfpi=1.570796326794896619231321691639751442099;
inline double pi() {return 3.1415926535897931160E0;}
inline double two_pi() {return 6.2831853071795862320E0;}
inline double half_pi() {return 1.5707963267948965580E0;}
inline double deg2rad() {return pi()/180.0;}
// for Lib/ExpFunc.
inline bool in_domain_all(double){return true;}
inline bool in_domain_log(double a_x){return (a_x>0?true:false);}
inline bool in_domain_tan(double a_x){
int n = int(a_x/half_pi());
if(a_x!=n*half_pi()) return true;
return (2*int(n/2)==n?true:false);
}
inline bool in_domain_acos(double a_x){
if((a_x<-1)||(1<a_x)) return false;
return true;
}
}
//#include "power"
#endif
@@ -0,0 +1,76 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_ntuple_binding
#define tools_ntuple_binding
// a little class to capture column binding parameters
// when reading an ntuple.
#include <string>
#include <vector>
#include "forit"
namespace tools {
class column_binding {
public:
column_binding(const std::string& a_name,void* a_user_obj)
:m_name(a_name)
,m_user_obj(a_user_obj) //WARNING : not owner.
{}
virtual ~column_binding() {}
public:
column_binding(const column_binding& a_from)
:m_name(a_from.m_name)
,m_user_obj(a_from.m_user_obj)
{}
column_binding& operator=(const column_binding& a_from) {
if(&a_from==this) return *this;
m_name = a_from.m_name;
m_user_obj = a_from.m_user_obj;
return *this;
}
public:
const std::string& name() const {return m_name;}
void* user_obj() const {return m_user_obj;}
protected:
std::string m_name;
void* m_user_obj;
};
class ntuple_binding {
public:
ntuple_binding()
{}
virtual ~ntuple_binding(){}
public:
ntuple_binding(const ntuple_binding& a_from)
:m_columns(a_from.m_columns)
{}
ntuple_binding& operator=(const ntuple_binding& a_from){
m_columns = a_from.m_columns;
return *this;
}
public:
template <class T>
void add_column(const std::string& a_name,T& a_user_var) {
m_columns.push_back(column_binding(a_name,(void*)&a_user_var));
}
const std::vector<column_binding>& columns() const {return m_columns;}
template <class T>
T* find_variable(const std::string& a_name) const {
tools_vforcit(column_binding,m_columns,it) {
if((*it).name()==a_name) return (T*)((*it).user_obj());
}
return 0;
}
protected:
std::vector<column_binding> m_columns;
};
}
#endif
@@ -11,9 +11,43 @@
namespace tools {
class column_booking {
public:
column_booking(const std::string& a_name,cid a_cid,void* a_user_obj)
:m_name(a_name)
,m_cid(a_cid)
,m_user_obj(a_user_obj) //WARNING : not owner.
{}
virtual ~column_booking() {}
public:
column_booking(const column_booking& a_from)
:m_name(a_from.m_name)
,m_cid(a_from.m_cid)
,m_user_obj(a_from.m_user_obj)
{}
column_booking& operator=(const column_booking& a_from) {
if(&a_from==this) return *this;
m_name = a_from.m_name;
m_cid = a_from.m_cid;
m_user_obj = a_from.m_user_obj;
return *this;
}
public:
const std::string& name() const {return m_name;}
cid cls_id() const {return m_cid;}
void* user_obj() const {return m_user_obj;}
protected:
std::string m_name;
cid m_cid;
void* m_user_obj;
};
class ntuple_booking {
public:
ntuple_booking(){}
ntuple_booking(const std::string& a_name = "",const std::string& a_title = "")
:m_name(a_name)
,m_title(a_title)
{}
virtual ~ntuple_booking(){}
public:
ntuple_booking(const ntuple_booking& a_from)
@@ -30,13 +64,23 @@ public:
public:
template <class T>
void add_column(const std::string& a_name) {
m_columns.push_back(col_t(a_name,_cid(T())));
m_columns.push_back(column_booking(a_name,_cid(T()),0));
}
public:
template <class T>
void add_column(const std::string& a_name,std::vector<T>& a_user_vec) {
m_columns.push_back(column_booking(a_name,_cid_std_vector<T>(),(void*)&a_user_vec));
}
const std::string& name() const {return m_name;}
const std::string& title() const {return m_title;}
const std::vector<column_booking>& columns() const {return m_columns;}
void set_name(const std::string& a_s) {m_name = a_s;}
void set_title(const std::string& a_s) {m_title = a_s;}
protected:
std::string m_name;
std::string m_title;
typedef std::pair<std::string,cid> col_t;
std::vector<col_t> m_columns;
std::vector<column_booking> m_columns;
};
}
@@ -1,657 +0,0 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_osc_streamers
#define tools_osc_streamers
#include "iobj_const_visitor"
#include "iobj_visitor"
#include "histo/h1d"
#include "histo/h2d"
#include "histo/h3d"
#include "histo/p1d"
#include "histo/p2d"
#include "vmanip"
#include "sto"
namespace tools {
namespace osc {
inline bool Axis_visit(iobj_const_visitor& a_v,
const std::string& /*a_field*/,
const histo::axis<double>& a_axis){
//SLASH_STORE_BEGIN(BatchLab::Axis)
int version = 1;
if(!a_v.visit("fVersion",version)) return false;
if(!a_v.visit("fOffset",a_axis.m_offset)) return false;
if(!a_v.visit("fNumberOfBins",(int)a_axis.m_number_of_bins)) return false;
if(!a_v.visit("fMinimumValue",a_axis.m_minimum_value)) return false;
if(!a_v.visit("fMaximumValue",a_axis.m_maximum_value)) return false;
if(!a_v.visit("fFixed",a_axis.m_fixed)) return false;
if(!a_v.visit("fBinWidth",a_axis.m_bin_width)) return false;
if(!a_v.visit("fEdges",a_axis.m_edges)) return false;
//if(!a_v.end(*this)) return false;
return true;
}
inline bool Axis_read(iobj_visitor& a_visitor,
histo::axis<double>& a_axis){
//if(!a_visitor.begin(*this)) return false;
int version;
if(!a_visitor.visit(version)) return false;
if(!a_visitor.visit(a_axis.m_offset)) return false;
{int nbin;
if(!a_visitor.visit(nbin)) return false;
a_axis.m_number_of_bins = nbin;}
if(!a_visitor.visit(a_axis.m_minimum_value)) return false;
if(!a_visitor.visit(a_axis.m_maximum_value)) return false;
if(!a_visitor.visit(a_axis.m_fixed)) return false;
if(!a_visitor.visit(a_axis.m_bin_width)) return false;
if(!a_visitor.visit(a_axis.m_edges)) return false;
//if(!a_visitor.end(*this)) return false;
return true;
}
class Item : public virtual istorable {
public:
virtual bool visit(iobj_const_visitor& a_visitor) const {
//if(!a_visitor.begin(*this,Item::s_class(),Item::s_visit)) return false;
int version = 1;
if(!a_visitor.visit("fVersion",version)) return false;
if(!a_visitor.visit("fKey",fKey)) return false;
if(!a_visitor.visit("fValue",fValue)) return false;
if(!a_visitor.visit("fSticky",fSticky)) return false;
//if(!a_visitor.end(*this)) return false;
return true;
}
public:
virtual bool read(iobj_visitor& a_visitor) {
//if(!a_visitor.begin(*this)) return false;
int version;
if(!a_visitor.visit(version)) return false;
if(!a_visitor.visit(fKey)) return false;
if(!a_visitor.visit(fValue)) return false;
if(!a_visitor.visit(fSticky)) return false;
//if(!a_visitor.end(*this)) return false;
return true;
}
public:
Item(){}
Item(const std::string& aKey,const std::string& aValue,bool aSticky)
:fKey(aKey),fValue(aValue),fSticky(aSticky){}
virtual ~Item(){}
public:
Item(const Item& aFrom)
:istorable(aFrom)
,fKey(aFrom.fKey)
,fValue(aFrom.fValue)
,fSticky(aFrom.fSticky)
{}
Item& operator=(const Item& aFrom) {
fKey = aFrom.fKey;
fValue = aFrom.fValue;
fSticky = aFrom.fSticky;
return *this;
}
public:
std::string fKey;
std::string fValue;
bool fSticky;
};
template <class T> //T must inherit istorable.
inline bool std_vector_visit(iobj_const_visitor& a_visitor,
const std::string& /*a_field*/,
const std::vector<T>& a_vec) {
//if(!a_visitor.begin(*this,"BatchLab::Vector<"+a_field+">",Vector<T>::visit))
// return false;
int version = 1;
if(!a_visitor.visit("fVersion",version)) return false;
unsigned int number = a_vec.size();
if(!a_visitor.visit("fSize",number)) return false;
for(unsigned int index=0;index<number;index++) {
const T& elem = a_vec[index];
if(!a_visitor.visit(to<int>(index),elem)) return false;
}
//if(!a_visitor.end(*this)) return false;
return true;
}
template <class T>
inline bool std_vector_read(iobj_visitor& a_visitor,
std::vector<T>& a_vec) {
a_vec.clear();
//if(!a_visitor.begin(*this)) return false;
int version;
if(!a_visitor.visit(version)) return false;
unsigned int number;
if(!a_visitor.visit(number)) return false;
a_vec.resize(number);
for(unsigned int index=0;index<number;index++) {
T& elem = a_vec[index];
if(!elem.read(a_visitor)) return false;
}
//if(!a_visitor.end(*this)) return false;
return true;
}
inline bool Annotation_visit(iobj_const_visitor& a_visitor,
const std::vector<Item>& a_items) {
//if(!a_visitor.begin(*this,Annotation::s_class(),Annotation::s_visit))
// return false;
int version = 1;
if(!a_visitor.visit("fVersion",version)) return false;
if(!std_vector_visit<Item>(a_visitor,"fItems",a_items)) return false;
//if(!a_visitor.end(*this)) return false;
return true;
}
inline bool Annotation_read(iobj_visitor& a_visitor) {
//if(!a_visitor.begin(*this)) return false;
int version;
if(!a_visitor.visit(version)) return false;
std::vector<Item> fItems;
if(!std_vector_read<Item>(a_visitor,fItems)) return false;
//if(!a_visitor.end(*this)) return false;
return true;
}
inline void map2vec(const std::map<std::string,std::string>& a_in,
std::vector<Item>& a_out) {
a_out.clear();
std::map<std::string,std::string>::const_iterator it;
for(it=a_in.begin();it!=a_in.end();++it) {
a_out.push_back(Item((*it).first,(*it).second,false));
}
}
typedef histo::histo_data<double,unsigned int,double> hd_data;
inline bool BaseHistogram_visit(const hd_data& aData,
iobj_const_visitor& a_visitor) {
//SLASH_STORE_BEGIN(BatchLab::BaseHistogram)
int version = 1;
if(!a_visitor.visit("fVersion",version)) return false;
//if(!a_visitor.visit("fAnnotation",fAnnotation)) return false;
std::vector<Item> items;
map2vec(aData.m_annotations,items);
if(!Annotation_visit(a_visitor,items)) return false;
//if(!a_visitor.end(*this)) return false;
return true;
}
inline bool BaseHistogram_read(iobj_visitor& a_visitor){
//if(!a_visitor.begin(*this)) return false;
int version;
if(!a_visitor.visit(version)) return false;
if(!Annotation_read(a_visitor)) return false;
//if(!a_visitor.end(*this)) return false;
return true;
}
inline bool visitHistogram(const hd_data& aData,
iobj_const_visitor& a_visitor){
if(!a_visitor.visit("fTitle",aData.m_title)) return false;
if(!a_visitor.visit("fDimension",(int)aData.m_dimension)) return false;
if(!a_visitor.visit("fBinNumber",(int)aData.m_bin_number)) return false;
if(!a_visitor.visit("fBinEntries",
convert<unsigned int,int>(aData.m_bin_entries))) return false;
if(!a_visitor.visit("fBinSw",aData.m_bin_Sw)) return false;
if(!a_visitor.visit("fBinSw2",aData.m_bin_Sw2)) return false;
if(!a_visitor.visit("fBinSxw",aData.m_bin_Sxw)) return false;
if(!a_visitor.visit("fBinSx2w",aData.m_bin_Sx2w)) return false;
{for(unsigned int iaxis=0;iaxis<aData.m_dimension;iaxis++) {
std::string name = "fAxes_" + to<int>(iaxis);
//BatchLab::Axis axis;
//axis.copy(aData.m_axes[iaxis]);
//if(!a_visitor.visit(name,axis)) return false;
if(!Axis_visit(a_visitor,name,aData.m_axes[iaxis])) return false;
}}
{int dummy = 0;
if(!a_visitor.visit("fMode",dummy)) return false;} //m_mode
if(!a_visitor.visit("fProfile",false)) return false;
{std::vector<double> dummy;
if(!a_visitor.visit("fBinSvw",dummy)) return false;
if(!a_visitor.visit("fBinSv2w",dummy)) return false;}
if(!a_visitor.visit("fCutV",false)) return false;
{double dummy = 0;
if(!a_visitor.visit("fMinV",dummy)) return false;
if(!a_visitor.visit("fMaxV",dummy)) return false;}
// Not written :
//aData.fDoubles
//aData.fInts
return true;
}
inline bool readHistogram(hd_data& aData,iobj_visitor& a_visitor){
if(!a_visitor.visit(aData.m_title)) return false;
{int dim;
if(!a_visitor.visit(dim)) return false;
aData.m_dimension = dim;}
{int nbin;
if(!a_visitor.visit(nbin)) return false;
aData.m_bin_number = nbin;}
{std::vector<int> vec;
if(!a_visitor.visit(vec)) return false;
aData.m_bin_entries = convert<int,unsigned int>(vec);}
if(!a_visitor.visit(aData.m_bin_Sw)) return false;
if(!a_visitor.visit(aData.m_bin_Sw2)) return false;
if(!a_visitor.visit(aData.m_bin_Sxw)) return false;
if(!a_visitor.visit(aData.m_bin_Sx2w)) return false;
aData.m_axes.clear();
for(unsigned int iaxis=0;iaxis<aData.m_dimension;iaxis++) {
histo::axis<double> baxis;
if(!Axis_read(a_visitor,baxis)) return false;
aData.m_axes.push_back(baxis);
}
{int dummy;
if(!a_visitor.visit(dummy)) return false;} //m_mode
{bool dummy;
if(!a_visitor.visit(dummy)) return false;} //m_is_profile
{std::vector<double> dummy;
if(!a_visitor.visit(dummy)) return false;} //m_bin_Svw
{std::vector<double> dummy;
if(!a_visitor.visit(dummy)) return false;} //m_bin_Sv2w
{bool dummy;
if(!a_visitor.visit(dummy)) return false;} //m_cut_v
{double dummy;
if(!a_visitor.visit(dummy)) return false;} //aData.m_min_v
{double dummy;
if(!a_visitor.visit(dummy)) return false;} //aData.m_max_v
//aData.fDoubles
//aData.fInts
//aData.m_coords.resize(aData.m_dimension,0);
//aData.m_ints.resize(aData.m_dimension,0);
return true;
}
inline bool visit(iobj_const_visitor& a_visitor,
const histo::h1d& a_histo) {
//SLASH_STORE_BEGIN(BatchLab::Histogram1D)
int version = 1;
if(!a_visitor.visit("fVersion",version)) return false;
if(!BaseHistogram_visit(a_histo.get_histo_data(),a_visitor)) return false;
if(!visitHistogram(a_histo.get_histo_data(),a_visitor)) return false;
//if(!a_visitor.visit("fAxis",fAxis)) return false;
//if(!a_visitor.end(*this)) return false;
return true;
}
inline bool read(iobj_visitor& a_visitor,histo::h1d& a_histo){
//if(!a_visitor.begin(*this)) return false;
int version;
if(!a_visitor.visit(version)) return false;
if(version!=1) {
//this may come from an unexpected byteswap.
a_visitor.out() << "tools::osc::read :"
<< " unexpected version " << version
<< std::endl;
return false;
}
if(!BaseHistogram_read(a_visitor)) return false;
hd_data hdata;
if(!readHistogram(hdata,a_visitor)) return false;
a_histo.copy_from_data(hdata);
//fAxis.copy(fHistogram.get_axis(0));
//if(!a_visitor.end(*this)) return false;
a_histo.update_fast_getters();
return true;
}
inline bool visit(iobj_const_visitor& a_visitor,
const histo::h2d& a_histo) {
//SLASH_STORE_BEGIN(BatchLab::Histogram2D)
int version = 1;
if(!a_visitor.visit("fVersion",version)) return false;
if(!BaseHistogram_visit(a_histo.get_histo_data(),a_visitor)) return false;
if(!visitHistogram(a_histo.get_histo_data(),a_visitor)) return false;
//if(!a_visitor.visit("fAxisX",fAxisX)) return false;
//if(!a_visitor.visit("fAxisY",fAxisY)) return false;
//if(!a_visitor.end(*this)) return false;
return true;
}
inline bool read(iobj_visitor& a_visitor,histo::h2d& a_histo){
//if(!a_visitor.begin(*this)) return false;
int version;
if(!a_visitor.visit(version)) return false;
if(version!=1) {
//this may come from an unexpected byteswap.
a_visitor.out() << "tools::osc::read :"
<< " unexpected version " << version
<< std::endl;
return false;
}
if(!BaseHistogram_read(a_visitor)) return false;
hd_data hdata;
if(!readHistogram(hdata,a_visitor)) return false;
a_histo.copy_from_data(hdata);
//fAxisX.copy(fHistogram.get_axis(0));
//fAxisY.copy(fHistogram.get_axis(1));
//if(!a_visitor.end(*this)) return false;
a_histo.update_fast_getters();
return true;
}
inline bool visit(iobj_const_visitor& a_visitor,
const histo::h3d& a_histo) {
//SLASH_STORE_BEGIN(BatchLab::Histogram3D)
int version = 1;
if(!a_visitor.visit("fVersion",version)) return false;
if(!BaseHistogram_visit(a_histo.get_histo_data(),a_visitor)) return false;
if(!visitHistogram(a_histo.get_histo_data(),a_visitor)) return false;
//if(!a_visitor.visit("fAxisX",fAxisX)) return false;
//if(!a_visitor.visit("fAxisY",fAxisY)) return false;
//if(!a_visitor.visit("fAxisZ",fAxisY)) return false;
//if(!a_visitor.end(*this)) return false;
return true;
}
inline bool read(iobj_visitor& a_visitor,histo::h3d& a_histo){
//if(!a_visitor.begin(*this)) return false;
int version;
if(!a_visitor.visit(version)) return false;
if(version!=1) {
//this may come from an unexpected byteswap.
a_visitor.out() << "tools::osc::read :"
<< " unexpected version " << version
<< std::endl;
return false;
}
if(!BaseHistogram_read(a_visitor)) return false;
hd_data hdata;
if(!readHistogram(hdata,a_visitor)) return false;
a_histo.copy_from_data(hdata);
//fAxisX.copy(fHistogram.get_axis(0));
//fAxisY.copy(fHistogram.get_axis(1));
//fAxisZ.copy(fHistogram.get_axis(2));
//if(!a_visitor.end(*this)) return false;
a_histo.update_fast_getters();
return true;
}
typedef histo::profile_data<double,unsigned int,double,double> pd_data;
inline bool visitProfile(const pd_data& aData,
iobj_const_visitor& a_visitor){
if(!a_visitor.visit("fTitle",aData.m_title)) return false;
if(!a_visitor.visit("fDimension",(int)aData.m_dimension)) return false;
if(!a_visitor.visit("fBinNumber",(int)aData.m_bin_number)) return false;
if(!a_visitor.visit("fBinEntries",
convert<unsigned int,int>(aData.m_bin_entries))) return false;
if(!a_visitor.visit("fBinSw",aData.m_bin_Sw)) return false;
if(!a_visitor.visit("fBinSw2",aData.m_bin_Sw2)) return false;
if(!a_visitor.visit("fBinSxw",aData.m_bin_Sxw)) return false;
if(!a_visitor.visit("fBinSx2w",aData.m_bin_Sx2w)) return false;
for(unsigned int iaxis=0;iaxis<aData.m_dimension;iaxis++) {
std::string name = "fAxes_" + to<int>(iaxis);
//BatchLab::Axis axis;
//axis.copy(aData.m_axes[iaxis]);
//if(!a_visitor.visit(name,axis)) return false;
if(!Axis_visit(a_visitor,name,aData.m_axes[iaxis])) return false;
}
{int dummy = 0;
if(!a_visitor.visit("fMode",dummy)) return false;} //m_mode
if(!a_visitor.visit("fProfile",true)) return false;
if(!a_visitor.visit("fBinSvw",aData.m_bin_Svw)) return false;
if(!a_visitor.visit("fBinSv2w",aData.m_bin_Sv2w)) return false;
if(!a_visitor.visit("fCutV",aData.m_cut_v)) return false;
if(!a_visitor.visit("fMinV",aData.m_min_v)) return false;
if(!a_visitor.visit("fMaxV",aData.m_max_v)) return false;
// Not written :
//aData.fDoubles
//aData.fInts
return true;
}
inline bool readProfile(pd_data& aData,iobj_visitor& a_visitor){
if(!a_visitor.visit(aData.m_title)) return false;
{int dim;
if(!a_visitor.visit(dim)) return false;
aData.m_dimension = dim;}
{int nbin;
if(!a_visitor.visit(nbin)) return false;
aData.m_bin_number = nbin;}
{std::vector<int> vec;
if(!a_visitor.visit(vec)) return false;
aData.m_bin_entries = convert<int,unsigned int>(vec);}
if(!a_visitor.visit(aData.m_bin_Sw)) return false;
if(!a_visitor.visit(aData.m_bin_Sw2)) return false;
if(!a_visitor.visit(aData.m_bin_Sxw)) return false;
if(!a_visitor.visit(aData.m_bin_Sx2w)) return false;
aData.m_axes.clear();
for(unsigned int iaxis=0;iaxis<aData.m_dimension;iaxis++) {
histo::axis<double> baxis;
if(!Axis_read(a_visitor,baxis)) return false;
aData.m_axes.push_back(baxis);
}
{int dummy;
if(!a_visitor.visit(dummy)) return false;} //m_mode
if(!a_visitor.visit(aData.m_is_profile)) return false;
if(!a_visitor.visit(aData.m_bin_Svw)) return false;
if(!a_visitor.visit(aData.m_bin_Sv2w)) return false;
if(!a_visitor.visit(aData.m_cut_v)) return false;
if(!a_visitor.visit(aData.m_min_v)) return false;
if(!a_visitor.visit(aData.m_max_v)) return false;
// Not written :
//aData.fDoubles
//aData.fInts
//aData.m_coords.resize(aData.m_dimension,0);
//aData.m_ints.resize(aData.m_dimension,0);
return true;
}
inline bool visit(iobj_const_visitor& a_visitor,
const histo::p1d& a_histo) {
//SLASH_STORE_BEGIN(BatchLab::Profile1D)
int version = 1;
if(!a_visitor.visit("fVersion",version)) return false;
if(!BaseHistogram_visit(a_histo.get_histo_data(),a_visitor)) return false;
if(!visitProfile(a_histo.get_histo_data(),a_visitor)) return false;
//if(!a_visitor.visit("fAxis",fAxis)) return false;
//if(!a_visitor.end(*this)) return false;
return true;
}
inline bool read(iobj_visitor& a_visitor,histo::p1d& a_histo){
//if(!a_visitor.begin(*this)) return false;
int version;
if(!a_visitor.visit(version)) return false;
if(version!=1) {
//this may come from an unexpected byteswap.
a_visitor.out() << "tools::osc::read :"
<< " unexpected version " << version
<< std::endl;
return false;
}
if(!BaseHistogram_read(a_visitor)) return false;
pd_data hdata;
if(!readProfile(hdata,a_visitor)) return false;
a_histo.copy_from_data(hdata);
//fAxis.copy(fHistogram.get_axis(0));
//if(!a_visitor.end(*this)) return false;
a_histo.update_fast_getters();
return true;
}
inline bool visit(iobj_const_visitor& a_visitor,
const histo::p2d& a_histo) {
//SLASH_STORE_BEGIN(BatchLab::Profile2D)
int version = 1;
if(!a_visitor.visit("fVersion",version)) return false;
if(!BaseHistogram_visit(a_histo.get_histo_data(),a_visitor)) return false;
if(!visitProfile(a_histo.get_histo_data(),a_visitor)) return false;
//if(!a_visitor.visit("fAxisX",fAxisX)) return false;
//if(!a_visitor.visit("fAxisY",fAxisY)) return false;
//if(!a_visitor.end(*this)) return false;
return true;
}
inline bool read(iobj_visitor& a_visitor,histo::p2d& a_histo){
//if(!a_visitor.begin(*this)) return false;
int version;
if(!a_visitor.visit(version)) return false;
if(version!=1) {
//this may come from an unexpected byteswap.
a_visitor.out() << "tools::osc::read :"
<< " unexpected version " << version
<< std::endl;
return false;
}
if(!BaseHistogram_read(a_visitor)) return false;
pd_data hdata;
if(!readProfile(hdata,a_visitor)) return false;
a_histo.copy_from_data(hdata);
//fAxisX.copy(a_histo.get_axis(0));
//fAxisY.copy(a_histo.get_axis(1));
//if(!a_visitor.end(*this)) return false;
a_histo.update_fast_getters();
return true;
}
inline const std::string& s_h1d() {
static const std::string s_v("BatchLab::Histogram1D");
return s_v;
}
inline const std::string& s_h2d() {
static const std::string s_v("BatchLab::Histogram2D");
return s_v;
}
inline const std::string& s_h3d() {
static const std::string s_v("BatchLab::Histogram3D");
return s_v;
}
inline const std::string& s_p1d() {
static const std::string s_v("BatchLab::Profile1D");
return s_v;
}
inline const std::string& s_p2d() {
static const std::string s_v("BatchLab::Profile2D");
return s_v;
}
}}
#endif
+100
View File
@@ -0,0 +1,100 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_randT
#define tools_randT
#include "cmathT"
#include "mathd"
namespace tools {
template <class FLAT,class REAL>
class rgauss {
public:
rgauss(FLAT& a_flat,REAL a_mean = 0,REAL a_std_dev = 1)
:m_flat(a_flat),m_mean(a_mean),m_std_dev(a_std_dev){}
virtual ~rgauss(){}
public:
rgauss(const rgauss& a_from):m_flat(a_from.m_flat),m_mean(a_from.m_mean),m_std_dev(a_from.m_std_dev){}
rgauss& operator=(const rgauss& a_from) {
m_mean = a_from.m_mean;
m_std_dev = a_from.m_std_dev;
return *this;
}
public:
REAL shoot() {
// Shoot random numbers according a
// rgaussian distribution of mean 0 and sigma 1.
REAL v1,v2,r,fac;
do {
v1 = REAL(2) * m_flat.shoot() - REAL(1);
v2 = REAL(2) * m_flat.shoot() - REAL(1);
r = v1*v1 + v2*v2;
} while (r>REAL(1));
fac = _sqrt(-REAL(2)*_log(r)/r);
return (v2 * fac) * m_std_dev + m_mean;
}
FLAT& flat() {return m_flat;}
protected:
FLAT& m_flat;
REAL m_mean;
REAL m_std_dev;
};
template <class FLAT,class REAL>
class rbw {
public:
rbw(FLAT& a_flat,REAL a_mean = 0,REAL a_gamma = 1)
:m_flat(a_flat),m_mean(a_mean),m_gamma(a_gamma){
_half_pi(m_half_pi);
}
virtual ~rbw(){}
public:
rbw(const rbw& a_from):m_flat(a_from.m_flat),m_mean(a_from.m_mean),m_gamma(a_from.m_gamma),m_half_pi(a_from.m_half_pi){}
rbw& operator=(const rbw& a_from) {
m_mean = a_from.m_mean;
m_gamma = a_from.m_gamma;
m_half_pi = a_from.m_half_pi;
return *this;
}
public:
REAL shoot() const {
REAL rval = REAL(2) * m_flat.shoot() - REAL(1);
REAL displ = (REAL(1)/REAL(2)) * m_gamma * _tan(rval * m_half_pi);
return m_mean + displ;
}
FLAT& flat() {return m_flat;}
protected:
FLAT& m_flat;
REAL m_mean;
REAL m_gamma;
REAL m_half_pi;
};
template <class FLAT,class REAL>
class rexp {
public:
rexp(FLAT& a_flat,REAL a_rate = 1):m_flat(a_flat),m_rate(a_rate){}
virtual ~rexp(){}
public:
rexp(const rexp& a_from):m_flat(a_from.m_flat),m_rate(a_from.m_rate){}
rexp& operator=(const rexp& a_from) {m_rate = a_from.m_rate;return *this;}
public:
REAL shoot() const {
REAL v;
do {
v = m_flat.shoot();
} while(v<=REAL(0));
return -_log(v)/m_rate;
}
FLAT& flat() {return m_flat;}
protected:
FLAT& m_flat;
REAL m_rate;
};
}
#endif
@@ -0,0 +1,62 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_randd
#define tools_randd
#include "randT"
#include "rtausmed"
namespace tools {
class rgaussd : public rgauss<rtausmed,double> {
typedef rgauss<rtausmed,double> parent;
public:
rgaussd(double a_mean = 0,double a_std_dev = 1):parent(m_flat,a_mean,a_std_dev),m_flat(){}
virtual ~rgaussd(){}
public:
rgaussd(const rgaussd& a_from):parent(m_flat),m_flat(a_from.m_flat){}
rgaussd& operator=(const rgaussd& a_from) {
parent::operator=(a_from);
m_flat = a_from.m_flat;
return *this;
}
protected:
rtausmed m_flat;
};
class rbwd : public rbw<rtausmed,double> {
typedef rbw<rtausmed,double> parent;
public:
rbwd(double a_mean = 0,double a_gamma = 1):parent(m_flat,a_mean,a_gamma),m_flat(){}
virtual ~rbwd(){}
public:
rbwd(const rbwd& a_from):parent(m_flat),m_flat(a_from.m_flat){}
rbwd& operator=(const rbwd& a_from) {
parent::operator=(a_from);
m_flat = a_from.m_flat;
return *this;
}
protected:
rtausmed m_flat;
};
class rexpd : public rexp<rtausmed,double> {
typedef rexp<rtausmed,double> parent;
public:
rexpd(double a_rate = 1):parent(m_flat,a_rate),m_flat(){}
virtual ~rexpd(){}
public:
rexpd(const rexpd& a_from):parent(m_flat),m_flat(a_from.m_flat){}
rexpd& operator=(const rexpd& a_from) {
parent::operator=(a_from);
m_flat = a_from.m_flat;
return *this;
}
protected:
rtausmed m_flat;
};
}
#endif
+31 -68
View File
@@ -4,96 +4,59 @@
#ifndef tools_randf
#define tools_randf
#include <cstdlib> //::rand, RAND_MAX
#include "fmath"
#include "randT"
#include "rtausmef"
namespace tools {
namespace randf {
class flat {
class rgaussf : public rgauss<rtausmef,float> {
typedef rgauss<rtausmef,float> parent;
public:
float shoot() const {
// Shoot random numbers in [0,1] according a flat distribution.
float value = (float)::rand();
value /= (float)RAND_MAX;
return value;
}
};
class gauss {
rgaussf(float a_mean = 0,float a_std_dev = 1):parent(m_flat,a_mean,a_std_dev),m_flat(){}
virtual ~rgaussf(){}
public:
gauss(float a_mean = 0,float a_std_dev = 1)
:m_mean(a_mean),m_std_dev(a_std_dev){}
public:
gauss(const gauss& a_from)
:m_mean(a_from.m_mean),m_std_dev(a_from.m_std_dev){}
gauss& operator=(const gauss& a_from) {
m_mean = a_from.m_mean;
m_std_dev = a_from.m_std_dev;
rgaussf(const rgaussf& a_from):parent(m_flat),m_flat(a_from.m_flat){}
rgaussf& operator=(const rgaussf& a_from) {
parent::operator=(a_from);
m_flat = a_from.m_flat;
return *this;
}
public:
float shoot() const {
// Shoot random numbers according a
// gaussian distribution of mean 0 and sigma 1.
float v1,v2,r,fac;
do {
v1 = 2 * m_flat.shoot() - 1;
v2 = 2 * m_flat.shoot() - 1;
r = v1*v1 + v2*v2;
} while ( r > 1 );
fac = fsqrt(-2*flog(r)/r);
return (v2 * fac) * m_std_dev + m_mean;
}
protected:
flat m_flat;
float m_mean;
float m_std_dev;
rtausmef m_flat;
};
class bw {
class rbwf : public rbw<rtausmef,float> {
typedef rbw<rtausmef,float> parent;
public:
bw(float a_mean = 0,float a_gamma = 1)
:m_mean(a_mean),m_gamma(a_gamma){}
rbwf(float a_mean = 0,float a_gamma = 1):parent(m_flat,a_mean,a_gamma),m_flat(){}
virtual ~rbwf(){}
public:
bw(const bw& a_from)
:m_mean(a_from.m_mean),m_gamma(a_from.m_gamma){}
bw& operator=(const bw& a_from) {
m_mean = a_from.m_mean;
m_gamma = a_from.m_gamma;
rbwf(const rbwf& a_from):parent(m_flat),m_flat(a_from.m_flat){}
rbwf& operator=(const rbwf& a_from) {
parent::operator=(a_from);
m_flat = a_from.m_flat;
return *this;
}
public:
float shoot() const {
float rval = 2 * m_flat.shoot() - 1;
float displ = 0.5f * m_gamma * ftan(rval * fhalf_pi());
return m_mean + displ;
}
protected:
flat m_flat;
float m_mean;
float m_gamma;
rtausmef m_flat;
};
class exp {
class rexpf : public rexp<rtausmef,float> {
typedef rexp<rtausmef,float> parent;
public:
exp(float a_rate = 1):m_rate(a_rate){}
rexpf(float a_rate = 1):parent(m_flat,a_rate),m_flat(){}
virtual ~rexpf(){}
public:
exp(const exp& a_from):m_rate(a_from.m_rate){}
exp& operator=(const exp& a_from) {m_rate = a_from.m_rate;return *this;}
public:
float shoot() const {
float v;
do {
v = m_flat.shoot();
} while(v<=0);
return -flog(v)/m_rate;
rexpf(const rexpf& a_from):parent(m_flat),m_flat(a_from.m_flat){}
rexpf& operator=(const rexpf& a_from) {
parent::operator=(a_from);
m_flat = a_from.m_flat;
return *this;
}
protected:
flat m_flat;
float m_rate;
rtausmef m_flat;
};
}}
}
#endif
+27 -72
View File
@@ -4,96 +4,51 @@
#ifndef tools_random
#define tools_random
#include <cstdlib> //::rand, RAND_MAX
#include <cmath> //::sqrt, ::log
// for backward compatibility.
#include "math"
#include "randd"
namespace tools {
namespace random {
class flat {
class gauss : public rgaussd {
typedef rgaussd parent;
public:
double shoot() const {
// Shoot random numbers in [0,1] according a flat distribution.
double value = (double)::rand();
value /= (double)RAND_MAX;
return value;
}
gauss(double a_mean = 0,double a_std_dev = 1):parent(a_mean,a_std_dev){}
virtual ~gauss(){}
public:
gauss(const gauss& a_from):parent(a_from){}
gauss& operator=(const gauss& a_from) {parent::operator=(a_from);return *this;}
};
class gauss {
class bw : public rbwd {
typedef rbwd parent;
public:
gauss(double a_mean = 0,double a_std_dev = 1)
:m_mean(a_mean),m_std_dev(a_std_dev){}
bw(double a_mean = 0,double a_gamma = 1):parent(a_mean,a_gamma){}
virtual ~bw(){}
public:
gauss(const gauss& a_from)
:m_mean(a_from.m_mean),m_std_dev(a_from.m_std_dev){}
gauss& operator=(const gauss& a_from) {
m_mean = a_from.m_mean;
m_std_dev = a_from.m_std_dev;
return *this;
}
public:
double shoot() const {
// Shoot random numbers according a
// gaussian distribution of mean 0 and sigma 1.
double v1,v2,r,fac;
do {
v1 = 2.0 * m_flat.shoot() - 1.0;
v2 = 2.0 * m_flat.shoot() - 1.0;
r = v1*v1 + v2*v2;
} while ( r > 1.0 );
fac = ::sqrt(-2.0*::log(r)/r);
return (v2 * fac) * m_std_dev + m_mean;
}
protected:
flat m_flat;
double m_mean;
double m_std_dev;
bw(const bw& a_from):parent(a_from){}
bw& operator=(const bw& a_from) {parent::operator=(a_from);return *this;}
};
class bw {
class exp : public rexpd {
typedef rexpd parent;
public:
bw(double a_mean = 0,double a_gamma = 1)
:m_mean(a_mean),m_gamma(a_gamma){}
exp(double a_rate = 1):parent(a_rate){}
virtual ~exp(){}
public:
bw(const bw& a_from)
:m_mean(a_from.m_mean),m_gamma(a_from.m_gamma){}
bw& operator=(const bw& a_from) {
m_mean = a_from.m_mean;
m_gamma = a_from.m_gamma;
return *this;
}
public:
double shoot() const {
double rval = 2.0 * m_flat.shoot() - 1.0;
double displ = 0.5 * m_gamma * ::tan(rval * half_pi());
return m_mean + displ;
}
protected:
flat m_flat;
double m_mean;
double m_gamma;
exp(const exp& a_from):parent(a_from){}
exp& operator=(const exp& a_from) {parent::operator=(a_from);return *this;}
};
class exp {
class flat : public rtausmed {
typedef rtausmed parent;
public:
exp(double a_rate = 1):m_rate(a_rate){}
flat():parent(){}
virtual ~flat(){}
public:
exp(const exp& a_from):m_rate(a_from.m_rate){}
exp& operator=(const exp& a_from) {m_rate = a_from.m_rate;return *this;}
public:
double shoot() const {
double v;
do {
v = m_flat.shoot();
} while(v<=0);
return -::log(v)/m_rate;
}
protected:
flat m_flat;
double m_rate;
flat(const flat& a_from):parent(a_from){}
flat& operator=(const flat& a_from) {parent::operator=(a_from);return *this;}
};
}}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,561 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rcsv_histo
#define tools_rcsv_histo
#include "sto"
#include "chars"
#include "words"
#include "forit"
#include "histo/h1d"
#include "histo/h2d"
#include "histo/h3d"
#include "histo/p1d"
#include "histo/p2d"
//#include "histo/h1df"
#ifdef TOOLS_MEM
#include "mem"
#endif
#include <istream>
namespace tools {
namespace rcsv {
class histo {
#ifdef TOOLS_MEM
public:
static const std::string& s_class() {
static const std::string s_v("tools::rcsv::histo");
return s_v;
}
#endif
public:
histo(std::istream& a_reader)
:m_reader(a_reader)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~histo() {
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
histo(const histo& a_from)
:m_reader(a_from.m_reader)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
histo& operator=(const histo&){return *this;}
public:
std::istream& istrm() {return m_reader;}
public:
bool read(std::ostream& a_out,std::string& a_class,void*& a_obj,bool a_verbose = false) {
a_class.clear();
a_obj = 0;
std::streampos file_sz = 0;
m_reader.clear();
m_reader.seekg(0,std::ios::end);
file_sz = m_reader.tellg();
m_reader.seekg(0,std::ios::beg);
if(!file_sz) {
a_out << "tools::rcsv::histo::read :"
<< " stream is empty."
<< std::endl;
return false;
}
if(a_verbose) a_out << "file size is " << file_sz << std::endl;
tools::histo::histo_data<double,unsigned int,unsigned int,double> hdata; //to be filled correctly.
hdata.m_dimension = 0;
hdata.m_bin_number = 0;
bool is_profile = false;
bool _cut_v = false;
double _min_v = 0;
double _max_v = 0;
// read commented header :
std::string _class;
typedef tools::histo::axis<double,unsigned int> axis_t;
{std::string line;
while(read_header_line(m_reader,file_sz,line)) {
// a_out << "line : " << sout(s) << std::endl;
std::vector<std::string> _words;
tools::words(line," ",false,_words);
if(!_words.size()) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error : empty header line."
<< std::endl;
return false;
}
if((_words[0]=="#class")) {
if(_words.size()!=2) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
_class = _words[1];
} else if(_words[0]=="#title") {
if(_words.size()<1) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
if(_words.size()==1) {
hdata.m_title.clear();
} else {
std::string::size_type pos = line.find(_words[0]);
pos += _words[0].size()+1;
hdata.m_title = line.substr(pos,line.size()-pos);
}
} else if(_words[0]=="#dimension") {
if(_words.size()!=2) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
to(_words[1],hdata.m_dimension);
} else if(_words[0]=="#annotation") {
if(_words.size()<2) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
if(_words.size()==2) {
hdata.m_annotations[_words[1]] = std::string();
} else {
std::string::size_type pos = line.find(_words[1]);
pos += _words[1].size()+1;
hdata.m_annotations[_words[1]] = line.substr(pos,line.size()-pos);
}
} else if(_words[0]=="#axis") {
if(_words.size()<2) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
if(_words[1]=="fixed") {
if(_words.size()!=5) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
unsigned int number_of_bins;
if(!to(_words[2],number_of_bins)) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
double minimum_value;
if(!to(_words[3],minimum_value)) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
double maximum_value;
if(!to(_words[4],maximum_value)) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
axis_t axis;
if(!axis.configure(number_of_bins,minimum_value,maximum_value)) {
a_out << "tools::rcsv::histo::read :"
<< " bad axis values in line " << sout(line)
<< std::endl;
return false;
}
hdata.m_axes.push_back(axis);
} else if(_words[1]=="edges") {
std::vector<double> edges;
double value;
for(unsigned int index=2;index<_words.size();index++) {
if(!to(_words[index],value)) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
edges.push_back(value);
}
axis_t axis;
if(!axis.configure(edges)) {
a_out << "tools::rcsv::histo::read :"
<< " bad axis values in line " << sout(line)
<< std::endl;
return false;
}
hdata.m_axes.push_back(axis);
} else {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
} else if(_words[0]=="#bin_number") {
if(_words.size()!=2) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
to(_words[1],hdata.m_bin_number);
} else if(_words[0]=="#cut_v") {
if(_words.size()!=2) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
if(!to(_words[1],_cut_v)) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
is_profile = true;
} else if(_words[0]=="#min_v") {
if(_words.size()!=2) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
if(!to(_words[1],_min_v)) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
} else if(_words[0]=="#max_v") {
if(_words.size()!=2) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
if(!to(_words[1],_max_v)) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
} else {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
}}
if(a_verbose) {
a_out << "class " << _class << std::endl;
a_out << "title " << hdata.m_title << std::endl;
tools_mforcit(std::string,std::string,hdata.m_annotations,it) {
a_out << "annotation " << (*it).first << " " << sout((*it).second) << std::endl;
}
}
if(!hdata.m_dimension) {
a_out << "tools::rcsv::histo::read :"
<< " null dimension."
<< std::endl;
return false;
}
// csv labels :
std::vector<std::string> labels;
{std::string line;
if(!read_line(m_reader,file_sz,line)) {
a_out << "tools::rcsv::histo::read :"
<< " syntax error in " << sout(line)
<< ". Can't read labels."
<< std::endl;
return false;
}
if(a_verbose) a_out << "labels " << sout(line) << std::endl;
tools::words(line,",",false,labels);}
unsigned int valn = 3+2*hdata.m_dimension;
if(is_profile) valn += 2;
std::vector<double> _bin_Svw;
std::vector<double> _bin_Sv2w;
if(labels.size()!=valn) {
a_out << "tools::rcsv::histo::read :"
<< " bad number of labels " << labels.size() << ". Expected " << valn << "."
<< std::endl;
return false;
}
// csv data (bins) :
{std::vector<double> vals;
unsigned int nline = 0;
std::vector<double> bin_Sxw(hdata.m_dimension);
std::vector<double> bin_Sx2w(hdata.m_dimension);
while(read_data_line(m_reader,file_sz,labels.size(),vals)) {
/*
for(unsigned int index=0;index<vals.size();index++) {
a_out << vals[index] << " ";
}
a_out << std::endl;
*/
if(vals.size()!=valn) {
a_out << "tools::rcsv::histo::read :"
<< " bad number of items in data line " << vals.size() << ". Expected " << valn << "."
<< std::endl;
return false;
}
unsigned int ival = 0;
hdata.m_bin_entries.push_back(static_cast<unsigned int>(vals[ival++]));
hdata.m_bin_Sw.push_back(vals[ival++]);
hdata.m_bin_Sw2.push_back(vals[ival++]);
if(is_profile) {
_bin_Svw.push_back(vals[ival++]);
_bin_Sv2w.push_back(vals[ival++]);
}
{for(unsigned int iaxis=0;iaxis<hdata.m_dimension;iaxis++) {
bin_Sxw[iaxis] = vals[ival++];
bin_Sx2w[iaxis] = vals[ival++];
}}
hdata.m_bin_Sxw.push_back(bin_Sxw);
hdata.m_bin_Sx2w.push_back(bin_Sx2w);
nline++;
}
if(nline!=hdata.m_bin_number) {
a_out << "tools::rcsv::histo::read :"
<< " bad data line number " << nline << ". Expected " << hdata.m_bin_number << "."
<< std::endl;
return false;
}}
if(hdata.m_axes.size()!=hdata.m_dimension) {
a_out << "tools::rcsv::histo::read :"
<< " inconsistent axes data."
<< std::endl;
return false;
}
hdata.m_axes[0].m_offset = 1;
{for(unsigned int iaxis=1;iaxis<hdata.m_dimension;iaxis++) {
hdata.m_axes[iaxis].m_offset = hdata.m_axes[iaxis-1].m_offset * (hdata.m_axes[iaxis-1].bins()+2);
}}
hdata.update_fast_getters(); //important.
tools::histo::profile_data<double,unsigned int,unsigned int,double,double> pdata(hdata); //to be filled correctly.
if(is_profile) {
pdata.m_is_profile = true;
pdata.m_bin_Svw = _bin_Svw;
pdata.m_bin_Sv2w = _bin_Sv2w;
pdata.m_cut_v = _cut_v;
pdata.m_min_v = _min_v;
pdata.m_max_v = _max_v;
}
if(_class==tools::histo::h1d::s_class()) {
if(hdata.m_dimension!=1) {
a_out << "tools::rcsv::histo::read :"
<< " inconsistent dimension data."
<< std::endl;
return false;
}
tools::histo::h1d* h = new tools::histo::h1d("",10,0,1);
h->copy_from_data(hdata);
//if(a_verbose) h->hprint(a_out);
if(a_verbose) {
a_out << "h1d : " << h->title()
<< ", all entries " << h->all_entries()
<< ", entries " << h->entries()
<< ", mean " << h->mean() << ", rms " << h->rms()
<< std::endl;
}
a_class = _class;
a_obj = h;
} else if(_class==tools::histo::h2d::s_class()) {
if(hdata.m_dimension!=2) {
a_out << "tools::rcsv::histo::read :"
<< " inconsistent dimension data."
<< std::endl;
return false;
}
tools::histo::h2d* h = new tools::histo::h2d("",10,0,1,10,0,1);
h->copy_from_data(hdata);
//if(a_verbose) h->hprint(a_out);
if(a_verbose) {
a_out << "h2d : " << h->title()
<< ", all entries " << h->all_entries()
<< ", entries " << h->entries()
<< ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
<< ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
<< std::endl;
}
a_class = _class;
a_obj = h;
} else if(_class==tools::histo::h3d::s_class()) {
if(hdata.m_dimension!=3) {
a_out << "tools::rcsv::histo::read :"
<< " inconsistent dimension data."
<< std::endl;
return false;
}
tools::histo::h3d* h = new tools::histo::h3d("",10,0,1,10,0,1,10,0,1);
h->copy_from_data(hdata);
//if(a_verbose) h->hprint(a_out);
if(a_verbose) {
a_out << "h3d : " << h->title()
<< ", all entries " << h->all_entries()
<< ", entries " << h->entries()
<< ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
<< ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
<< ", mean_z " << h->mean_z() << ", rms_z " << h->rms_z()
<< std::endl;
}
a_class = _class;
a_obj = h;
} else if(_class==tools::histo::p1d::s_class()) {
if(hdata.m_dimension!=1) {
a_out << "tools::rcsv::histo::read :"
<< " inconsistent dimension data."
<< std::endl;
return false;
}
tools::histo::p1d* h = new tools::histo::p1d("",10,0,1);
h->copy_from_data(pdata);
//if(a_verbose) h->hprint(a_out);
if(a_verbose) {
a_out << "p1d : " << h->title()
<< ", all entries " << h->all_entries()
<< ", entries " << h->entries()
<< ", mean " << h->mean() << ", rms " << h->rms()
<< std::endl;
}
a_class = _class;
a_obj = h;
} else if(_class==tools::histo::p2d::s_class()) {
if(hdata.m_dimension!=2) {
a_out << "tools::rcsv::histo::read :"
<< " inconsistent dimension data."
<< std::endl;
return false;
}
tools::histo::p2d* h = new tools::histo::p2d("",10,0,1,10,0,1);
h->copy_from_data(pdata);
//if(a_verbose) h->hprint(a_out);
if(a_verbose) {
a_out << "p2d : " << h->title()
<< ", all entries " << h->all_entries()
<< ", entries " << h->entries()
<< ", mean_x " << h->mean_x() << ", rms_x " << h->rms_x()
<< ", mean_y " << h->mean_y() << ", rms_y " << h->rms_y()
<< std::endl;
}
a_class = _class;
a_obj = h;
/*
} else if(_class==tools::histo::h1df::s_class()) {
if(hdata.m_dimension!=1) {
a_out << "tools::rcsv::histo::read :"
<< " inconsistent dimension data."
<< std::endl;
return false;
}
tools::histo::h1df* h = new tools::histo::h1df("",10,0,1);
h->copy_from_data(hdata);
//return h; //give ownership to caller.
if(a_verbose) h->hprint(a_out);
*/
} else {
a_out << "tools::rcsv::histo::read :"
<< " unknown class " << sout(_class)
<< std::endl;
return false;
}
return true;
}
protected:
static bool read_line(std::istream& a_reader,std::streampos a_sz,std::string& a_s){
a_s.clear();
char c;
while(true) {
if(a_reader.tellg()>=a_sz) {a_s.clear();return false;}
a_reader.get(c);
if(c==CR()) continue;
if(c==LF()) break; //eol.
a_s += c;
}
return true;
}
static bool read_header_line(std::istream& a_reader,std::streampos a_sz,std::string& a_s){
//we should be at bol.
//ret true = we had a commented line, false : a data line or nothing.
if(a_reader.tellg()>=a_sz) {a_s.clear();return false;}
char c;
a_reader.get(c);
a_reader.putback(c);
if(c!='#') {a_s.clear();return false;}
return read_line(a_reader,a_sz,a_s);
}
static bool _read(std::istream& a_reader,double& a_v) {
a_reader >> a_v;
if(a_reader.tellg()==std::streampos(-1)) {a_v = 0;return false;}
//std::cout << "debug : _read(double) " << a_v << std::endl;
return true;
}
static bool read_data_line(std::istream& a_reader,std::streampos a_sz,unsigned int a_number,std::vector<double>& a_vals) {
a_vals.clear();
for(unsigned int index=0;index<a_number;index++) {
double v;
if(!_read(a_reader,v)) return false;
a_vals.push_back(v);
if(index==(a_number-1)) { //read up to LF()
char c;
while(true){
if(a_reader.tellg()>=a_sz) break;
a_reader.get(c);
if(c==LF()) break;
}
} else { //read sep :
char sep;
a_reader.get(sep);
}
}
return true;
}
protected:
std::istream& m_reader;
};
}}
#endif
@@ -0,0 +1,952 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rcsv_ntuple
#define tools_rcsv_ntuple
// A simple ntuple class to read at the csv format.
// (csv = comma separated value).
// This reader can be use to read file at the hippodraw format
// which is :
// - one header line for the ntuple title.
// - one csv line for column names.
// - data at csv format.
#include "rntuple"
#include <istream>
#include <sstream>
#include "vfind"
#include "vmanip"
#include "words"
#include "sto"
#include "s2time"
#include "chars"
#include "strip"
#include "cids"
#include "ntuple_binding"
#ifdef TOOLS_MEM
#include "mem"
#endif
namespace tools {
namespace rcsv {
class ntuple : public virtual read::intuple {
public: //read::intuple
virtual void start() {
m_reader.clear();
m_reader.seekg(0,std::ios::beg);
if(m_hippo) {
skip_line(m_reader,m_sz);
skip_line(m_reader,m_sz);
}
}
virtual bool next() {
if(!m_sep) return false; //not inited.
if(m_reader.tellg()>=m_sz) return false;
// first time we are at bol but else we are at eol.
char c;
m_reader.get(c);
if(c==LF()){
if(m_reader.tellg()>=m_sz) {
//eof. Tell caller to stop looping on ntuple rows.
return false;
}
//eol. Next char read is going to be at bol.
} else {
m_reader.putback(c);
//bol
}
// ready for a new row :
while(skip_comment(m_reader,m_sz)){}
if(m_reader.tellg()>=m_sz) return false;
return _read_line();
}
virtual read::icol* find_icol(const std::string& a_name){
return find_named<read::icol>(m_cols,a_name);
}
virtual const std::vector<read::icol*>& columns() const {return m_cols;}
public:
template <class T>
class column : public virtual read::icolumn<T> {
typedef read::icolumn<T> parent;
public:
static cid id_class() {
static const T s_v = T(); //do that for T = std::string.
return 200+_cid(s_v);
}
public: //icol
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<column>(this,a_class)) {return p;}
return parent::cast(a_class);
}
virtual cid id_cls() const {return id_class();}
public: //icol
virtual const std::string& name() const {return m_name;}
virtual bool fetch_entry() const {
if(m_user_var) *m_user_var = m_tmp;
return true;
}
public: //icolumn<T>
virtual bool get_entry(T& a_v) const {
a_v = m_tmp;
return true;
}
public:
column(const std::string& a_name,T* a_user_var = 0)
:m_name(a_name)
,m_tmp(T())
,m_user_var(a_user_var) //not owner
{}
virtual ~column(){}
protected:
column(const column& a_from)
:read::intuple(a_from),parent(a_from)
,m_name(a_from.m_name)
,m_tmp(a_from.m_tmp)
,m_user_var(a_from.m_user_var)
{}
column& operator=(const column& a_from){
m_name = a_from.m_name;
m_tmp = a_from.m_tmp;
m_user_var = a_from.m_user_var;
return *this;
}
public:
// should be used in ntuple _read_line only :
void set_value(const T& a_v){m_tmp = a_v;}
protected:
std::string m_name;
T m_tmp;
T* m_user_var;
};
#ifdef TOOLS_MEM
public:
static const std::string& s_class() {
static const std::string s_v("tools::rcsv::ntuple");
return s_v;
}
#endif
public:
ntuple(std::istream& a_reader)
:m_reader(a_reader)
,m_title()
,m_sep(0)
,m_sz(0)
,m_hippo(false)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~ntuple() {
tools::clear<read::icol>(m_cols);
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
ntuple(const ntuple& a_from)
:read::intuple(a_from)
,m_reader(a_from.m_reader)
,m_title(a_from.m_title)
,m_sep(a_from.m_sep)
,m_sz(a_from.m_sz)
,m_hippo(a_from.m_hippo)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
ntuple& operator=(const ntuple& a_from){
m_title = a_from.m_title;
m_sep = a_from.m_sep;
m_hippo = a_from.m_hippo;
return *this;
}
public:
void set_hippo(bool a_hippo) {m_hippo = a_hippo;}
std::istream& istrm() {return m_reader;}
static bool is_hippo(std::ostream& a_out,std::istream& a_reader) {
// analyse two first data line.
a_reader.clear();
a_reader.seekg(0,std::ios::end);
std::streampos sz = a_reader.tellg();
a_reader.seekg(0,std::ios::beg);
if(!sz) {
a_out << "tools::rcsv::ntuple::is_hippo :"
<< " stream is empty."
<< std::endl;
return false;
} //file empty.
std::string title;
if(!read_line(a_reader,sz,title)) return false;
std::string s;
if(!read_line(a_reader,sz,s)) return false;
if(s.find('\t')==std::string::npos) return false;
/*
std::vector<std::string> labels;
tools::words(s,"\t",false,labels);
return labels.size()?true:false;
*/
return true;
}
static bool find_sep(std::ostream& a_out,
std::istream& a_reader,bool a_hippo,
bool a_verbose,
char& a_sep){
// analyse first data line to find the char separator.
a_reader.clear();
a_reader.seekg(0,std::ios::end);
std::streampos sz = a_reader.tellg();
a_reader.seekg(0,std::ios::beg);
if(!sz) {
a_out << "tools::rcsv::ntuple::find_sep :"
<< " stream is empty."
<< std::endl;
a_sep = 0;
return false;
} //file empty.
if(a_verbose) a_out << "file size " << sz << std::endl;
if(a_hippo) { //skip first two lines :
if(!skip_line(a_reader,sz)) {a_sep = 0;return false;}
if(!skip_line(a_reader,sz)) {a_sep = 0;return false;}
} else {
while(skip_comment(a_reader,sz)){}
}
if(a_reader.tellg()>=sz) {a_sep=0;return false;} //no data line.
// get first data line :
std::string sfirst;
{char c;
while(true) {
if(a_reader.tellg()>=sz) break;
a_reader.get(c);
if((c==CR())||(c==LF())) break;
sfirst += c;
}}
if(sfirst.empty()) {
a_out << "tools::rcsv::ntuple::find_set :"
<< " first datat line is empty."
<< std::endl;
a_sep = 0;
return false;
}
if(a_verbose) a_out << "first data line \"" << sfirst << "\"" << std::endl;
//guess sep from first data line :
std::istringstream strm(sfirst.c_str());
double d;
strm >> d;
std::streampos pos = strm.tellg();
if(pos==std::streampos(-1)) {
a_out << "tools::rcsv::ntuple::find_sep :"
<< " first line does not start with a number."
<< std::endl;
a_sep = 0;
return false;
} //not a number.
if(a_verbose) a_out << "first number " << d
<< " ending at pos " << pos << std::endl;
if(pos>=(std::streampos)sfirst.size()) {
a_out << "tools::rcsv::ntuple::find_sep :"
<< " no separator found in first line."
<< " pos " << pos
<< " sfirst.size() " << sfirst.size()
<< std::endl;
a_sep = 0;
return false;
} //no sep.
strm.get(a_sep);
return true;
}
public:
bool initialize(std::ostream& a_out,
char a_sep = 0, //guessed
const std::string& a_suffix = "x", //col suffix
bool a_verbose = false) {
tools::clear<read::icol>(m_cols);
m_sep = 0;
m_sz = 0;
if(a_suffix.empty()) {
a_out << "tools::rcsv::ntuple::initialize :"
<< " expect a column suffix."
<< std::endl;
return false;
}
m_reader.clear();
m_reader.seekg(0,std::ios::end);
m_sz = m_reader.tellg();
m_reader.seekg(0,std::ios::beg);
if(!m_sz) {
a_out << "tools::rcsv::ntuple::initialize :"
<< " stream is empty."
<< std::endl;
return false; //file empty.
}
if(a_verbose) a_out << "file size " << m_sz << std::endl;
std::vector<std::string> labels;
if(m_hippo) { //skip first two lines :
std::string title;
if(!read_line(m_reader,m_sz,title)) {a_sep = 0;return false;}
std::string s;
if(!read_line(m_reader,m_sz,s)) {a_sep = 0;return false;}
tools::words(s,"\t",false,labels);
} else {
while(skip_comment(m_reader,m_sz)){}
}
if(m_reader.tellg()>=m_sz) {m_sz=0;return false;}
// get first data line :
std::string sfirst;
{{char c;
while(true) {
if(m_reader.tellg()>=m_sz) break;
m_reader.get(c);
if((c==CR())||(c==LF())) break;
sfirst += c;
}}
if(sfirst.empty()) {
a_out << "tools::rcsv::ntuple::initialize :"
<< " first datat line is empty."
<< std::endl;
m_sz = 0;
return false;
}}
if(a_verbose) a_out << "first data line \"" << sfirst << "\"" << std::endl;
if(a_sep) {
m_sep = a_sep;
} else {
//guess sep from first data line :
std::istringstream strm(sfirst.c_str());
double d;
strm >> d;
std::streampos pos = strm.tellg();
if(pos==std::streampos(-1)) {
a_out << "tools::rcsv::ntuple::initialize :"
<< " first line does not start with a number."
<< std::endl;
m_sz = 0;
return false;
}
if(a_verbose) a_out << "first number " << d
<< " ending at pos " << pos << std::endl;
if(pos>=(std::streampos)sfirst.size()) {
a_out << "tools::rcsv::ntuple::initialize :"
<< " no separator found in first line."
<< std::endl;
m_sz = 0;
return false;
}
strm.get(m_sep);
}
if(a_verbose) a_out << "sep " << (int)m_sep << std::endl;
// in case sep is ' ', there is an ambiguity with some leading
// space in front of first number.
if(m_sep==' ') tools::strip(sfirst,leading,' ');
std::vector<std::string> words;
{std::string sep;
sep += m_sep;
tools::words(sfirst,sep,true,words);}
// look if words are numbers :
if(a_verbose) a_out << "words " << words.size() << std::endl;
unsigned int index = 0;
std::vector<std::string>::iterator it;
for(it=words.begin();it!=words.end();++it,index++) {
if(a_verbose) a_out << "word " << sout(*it) << "" << std::endl;
if((*it).empty()) {
// do not accept :
// <num><sep><num><sep><sep><num>...
// but accept a trailing <sep> (glast.tnt) :
// <num><sep><num>....<sep><num><sep>
if(index==(words.size()-1)) {
break;
} else {
a_out << "tools::rcsv::ntuple::initialize :"
<< " empty word."
<< std::endl;
tools::clear<read::icol>(m_cols);
m_sep = 0;
m_sz = 0;
return false;
}
}
std::string name(a_suffix+to<unsigned int>(m_cols.size()));
if(m_hippo) {
if(index>=labels.size()) {
a_out << "tools::rcsv::ntuple::initialize :"
<< " warning : not enough labels."
<< std::endl;
} else {
name = labels[index];
}
}
double d;
if(to<double>(*it,d)) {
if(a_verbose) a_out << "number " << d << std::endl;
create_column<double>(name);
} else {
time_t time;
if(s2time(*it,time)) {
create_column<csv_time>(name);
} else {
create_column<std::string>(name);
}
}
}
unsigned int num = m_cols.size();
if(!num) {
a_out << "tools::rcsv::ntuple::initialize :"
<< " zero columns."
<< std::endl;
m_sep = 0;
m_sz = 0;
return false;
}
return true;
}
static const std::string& s_cid(cid a_id) {
if(a_id==column<char>::id_class()) {
static const std::string s_v("char");
return s_v;
} else if(a_id==column<short>::id_class()) {
static const std::string s_v("short");
return s_v;
} else if(a_id==column<int>::id_class()) {
static const std::string s_v("int");
return s_v;
} else if(a_id==column<float>::id_class()) {
static const std::string s_v("float");
return s_v;
} else if(a_id==column<double>::id_class()) {
static const std::string s_v("double");
return s_v;
} else if(a_id==column<std::string>::id_class()) {
static const std::string s_v("string");
return s_v;
} else if(a_id==column<unsigned char>::id_class()) {
static const std::string s_v("uchar");
return s_v;
} else if(a_id==column<unsigned short>::id_class()) {
static const std::string s_v("ushort");
return s_v;
} else if(a_id==column<unsigned int>::id_class()) {
static const std::string s_v("uint");
return s_v;
} else if(a_id==column<bool>::id_class()) {
static const std::string s_v("bool");
return s_v;
} else if(a_id==column<int64>::id_class()) {
static const std::string s_v("int64");
return s_v;
} else if(a_id==column<uint64>::id_class()) {
static const std::string s_v("uint64");
return s_v;
} else if(a_id==column<csv_time>::id_class()) {
static const std::string s_v("time");
return s_v;
} else {
static const std::string s_v("unknown");
return s_v;
}
}
void dump_columns(std::ostream& a_out) const {
if((m_sep>=32)&&(m_sep<=126)) { //printable
a_out << "separator is '" << m_sep << "'" << std::endl;
} else {
a_out << "separator is " << (unsigned int)m_sep << std::endl;
}
std::vector<read::icol*>::const_iterator it;
for(it=m_cols.begin();it!=m_cols.end();++it) {
a_out << (*it)->name()
<< " " << s_cid((*it)->id_cls())
<< std::endl;
}
}
public:
typedef std::pair<std::string,std::string> col_desc;
bool initialize(std::ostream& a_out,const ntuple_binding& a_bd = ntuple_binding()) {
// it assumes a "commented header".
tools::clear<read::icol>(m_cols);
m_sep = 0;
m_sz = 0;
m_hippo = false;
m_reader.clear();
m_reader.seekg(0,std::ios::end);
m_sz = m_reader.tellg();
m_reader.seekg(0,std::ios::beg);
if(!m_sz) {
a_out << "tools::rcsv::ntuple::initialize(booking) :"
<< " stream is empty."
<< std::endl;
return false; //file empty.
}
//if(a_verbose) a_out << "file size " << m_sz << std::endl;
std::string _title;
char _sep;
std::vector<col_desc> _cols;
if(!read_commented_header(a_out,m_reader,_title,_sep,_cols)) return false;
m_sep = _sep;
m_title = _title;
tools_vforcit(col_desc,_cols,it) {
const std::string& type = (*it).first;
const std::string& name = (*it).second;
// see cid2s() for string types.
if(type=="char") create_column<char>(name,a_bd.find_variable<char>(name));
else if(type=="short") create_column<short>(name,a_bd.find_variable<short>(name));
else if(type=="int") create_column<int>(name,a_bd.find_variable<int>(name));
else if(type=="float") create_column<float>(name,a_bd.find_variable<float>(name));
else if(type=="double") create_column<double>(name,a_bd.find_variable<double>(name));
else if(type=="string") create_column<std::string>(name,a_bd.find_variable<std::string>(name));
else if(type=="uchar") create_column<unsigned char>(name,a_bd.find_variable<unsigned char>(name));
else if(type=="ushort") create_column<unsigned short>(name,a_bd.find_variable<unsigned short>(name));
else if(type=="uint") create_column<unsigned int>(name,a_bd.find_variable<unsigned int>(name));
else if(type=="bool") create_column<bool>(name,a_bd.find_variable<bool>(name));
else if(type=="int64") create_column<int64>(name,a_bd.find_variable<int64>(name));
else if(type=="uint64") create_column<uint64>(name,a_bd.find_variable<uint64>(name));
else {
a_out << "tools::rcsv::ntuple::initialize(booking) :"
<< " unhandled column type " << sout(type)
<< std::endl;
tools::clear<read::icol>(m_cols);
m_sep = 0;
m_sz = 0;
m_hippo = false;
return false;
}
}
unsigned int num = m_cols.size();
if(!num) {
a_out << "tools::rcsv::ntuple::initialize(booking) :"
<< " zero columns."
<< std::endl;
return false;
}
//a_out << "tools::rroot::ntuple::initialize :"
// << " number of columns " << num << "."
// << std::endl;
return true;
}
bool get_row() const {
bool status = true;
tools_vforcit(read::icol*,m_cols,it) {
if(!(*it)->fetch_entry()) status = false;
}
return status;
}
protected:
bool read_commented_header(std::ostream& a_out,std::istream& a_reader,
std::string& a_title,char& a_sep,std::vector<col_desc>& a_cols) {
// analyse first lines starting with '#'.
a_title.clear();
a_sep = 0;
a_cols.clear();
a_reader.clear();
a_reader.seekg(0,std::ios::end);
std::streampos sz = a_reader.tellg();
a_reader.seekg(0,std::ios::beg);
if(!sz) {
a_out << "tools::rcsv::ntuple::read_commented_header :"
<< " stream is empty."
<< std::endl;
return false;
} //file empty.
std::string _class;
while(true) {
if(a_reader.tellg()>=sz) break;
//we should be at bol :
char c;
a_reader.get(c);
a_reader.putback(c);
if(c!='#') break; //finished, probably a data line now.
std::string line;
if(!read_line(a_reader,sz,line)) break; //or return false ?
std::vector<std::string> _words;
tools::words(line," ",false,_words);
if(!_words.size()) {
a_out << "tools::rcsv::ntuple::read_commented_header :"
<< " syntax error : empty header line."
<< std::endl;
return false;
}
if((_words[0]=="#class")) {
if(_words.size()!=2) {
a_out << "tools::rcsv::ntuple::read_commented_header :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
_class = _words[1];
} else if(_words[0]=="#title") {
if(_words.size()<1) {
a_out << "tools::rcsv::ntuple::read_commented_header :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
if(_words.size()==1) {
a_title.clear();
} else {
std::string::size_type pos = line.find(_words[0]);
pos += _words[0].size()+1;
a_title = line.substr(pos,line.size()-pos);
}
} else if((_words[0]=="#separator")) {
if(_words.size()!=2) {
a_out << "tools::rcsv::ntuple::read_commented_header :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
unsigned int uisep;
if(!to(_words[1],uisep)) {
a_out << "tools::rcsv::ntuple::read_commented_header :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
a_sep = (char)uisep;
} else if((_words[0]=="#column")) {
if(_words.size()<2) {
a_out << "tools::rcsv::ntuple::read_commented_header :"
<< " syntax error in " << sout(line)
<< std::endl;
return false;
}
std::string stype = _words[1];
std::string label;
if(_words.size()==2) {
label.clear();
} else {
std::string::size_type pos = line.find(_words[1]);
pos += _words[1].size()+1;
label = line.substr(pos,line.size()-pos);
}
//a_out << "column " << stype << " " << sout(label) << std::endl;
a_cols.push_back(col_desc(stype,label));
} else {
a_out << "tools::rcsv::ntuple::read_commented_header :"
<< " syntax error in " << sout(line)
<< ", unknown keyword " << sout(_words[0])
<< std::endl;
//return false;
}
}
/*
a_out << "class " << _class << std::endl;
a_out << "title " << _title << std::endl;
a_out << "separator " << _separator << std::endl;
*/
return true;
}
protected:
template <class T>
column<T>* create_column(const std::string& a_name,T* a_user_var = 0){
if(find_named<read::icol>(m_cols,a_name)) return 0;
column<T>* col = new column<T>(a_name,a_user_var);
if(!col) return 0;
m_cols.push_back(col);
return col;
}
protected:
static bool read_line(std::istream& a_reader,std::streampos a_sz,
std::string& a_s){
a_s.clear();
char c;
while(true) {
if(a_reader.tellg()>=a_sz) {a_s.clear();return false;}
a_reader.get(c);
if(c==CR()) continue;
if(c==LF()) break; //eol.
a_s += c;
}
return true;
}
static bool skip_line(std::istream& a_reader,std::streampos a_sz){
char c;
while(true) {
if(a_reader.tellg()>=a_sz) return false;
a_reader.get(c);
if(c==LF()) break;
}
return true;
}
static bool skip_comment(std::istream& a_reader,std::streampos a_sz){
//ret true = we had a commented line, false : a data line or nothing.
if(a_reader.tellg()>=a_sz) return false;
//we should be at bol :
char c;
a_reader.get(c);
if(c=='#') {
return skip_line(a_reader,a_sz);
//eol. Next char should be bol.
} else {
a_reader.putback(c);
return false;
}
}
template <class T>
static bool _read(std::istream& a_reader,char,std::streampos,T& a_v) {
a_reader >> a_v;
if(a_reader.tellg()==std::streampos(-1)) {a_v = 0;return false;}
//std::cout << "debug : _read(double) " << a_v << std::endl;
return true;
}
static bool _read(std::istream& a_reader,char a_sep,std::streampos a_sz,time_t& a_v) {
std::string s;
char c;
while(true){
if(a_reader.tellg()>=a_sz) break;
a_reader.get(c);
if((c==a_sep)||(c==CR())||(c==LF())) {
a_reader.putback(c);
break;
}
s += c;
}
if(!s2time(s,a_v)) return false;
return true;
}
static bool _read(std::istream& a_reader,char a_sep,std::streampos a_sz,std::string& a_v) {
a_v.clear();
char c;
while(true){
if(a_reader.tellg()>=a_sz) break;
a_reader.get(c);
if((c==a_sep)||(c==CR())||(c==LF())) {
a_reader.putback(c);
break;
}
a_v += c;
}
return true;
}
protected:
bool _read_line() {
// have to loop on all columns !
typedef read::icol icol_t;
typedef ntuple::column<char> col_char;
typedef ntuple::column<short> col_short;
typedef ntuple::column<int> col_int;
typedef ntuple::column<float> col_float;
typedef ntuple::column<double> col_double;
typedef ntuple::column<std::string> col_string;
typedef ntuple::column<unsigned char> col_uchar;
typedef ntuple::column<unsigned short> col_ushort;
typedef ntuple::column<unsigned int> col_uint;
typedef ntuple::column<bool> col_bool;
typedef ntuple::column<int64> col_int64;
typedef ntuple::column<uint64> col_uint64;
typedef ntuple::column<csv_time> col_time;
unsigned int index = 0;
unsigned int num = m_cols.size();
std::vector<icol_t*>::const_iterator it;
for(it=m_cols.begin();it!=m_cols.end();++it,index++) {
if(col_char* _col_char = tools::id_cast<icol_t,col_char>(*(*it))) {
char v;
if(!_read(m_reader,m_sep,m_sz,v)) return false;
_col_char->set_value(v);
} else if(col_short* _col_short = tools::id_cast<icol_t,col_short>(*(*it))) {
short v;
if(!_read(m_reader,m_sep,m_sz,v)) return false;
_col_short->set_value(v);
} else if(col_int* _col_int = tools::id_cast<icol_t,col_int>(*(*it))) {
int v;
if(!_read(m_reader,m_sep,m_sz,v)) return false;
_col_int->set_value(v);
} else if(col_float* _col_float = tools::id_cast<icol_t,col_float>(*(*it))) {
float v;
if(!_read(m_reader,m_sep,m_sz,v)) return false;
_col_float->set_value(v);
} else if(col_double* _col_double = tools::id_cast<icol_t,col_double>(*(*it))) {
double v;
if(!_read(m_reader,m_sep,m_sz,v)) return false;
_col_double->set_value(v);
} else if(col_string* _col_string = tools::id_cast<icol_t,col_string>(*(*it))) {
std::string v;
if(!_read(m_reader,m_sep,m_sz,v)) return false;
_col_string->set_value(v);
} else if(col_uchar* _col_uchar = tools::id_cast<icol_t,col_uchar>(*(*it))) {
unsigned char v;
if(!_read(m_reader,m_sep,m_sz,v)) return false;
_col_uchar->set_value(v);
} else if(col_ushort* _col_ushort = tools::id_cast<icol_t,col_ushort>(*(*it))) {
ushort v;
if(!_read(m_reader,m_sep,m_sz,v)) return false;
_col_ushort->set_value(v);
} else if(col_uint* _col_uint = tools::id_cast<icol_t,col_uint>(*(*it))) {
unsigned int v;
if(!_read(m_reader,m_sep,m_sz,v)) return false;
_col_uint->set_value(v);
} else if(col_bool* _col_bool = tools::id_cast<icol_t,col_bool>(*(*it))) {
bool v;
if(!_read(m_reader,m_sep,m_sz,v)) return false;
_col_bool->set_value(v);
} else if(col_int64* _col_int64 = tools::id_cast<icol_t,col_int64>(*(*it))) {
int64 v;
if(!_read(m_reader,m_sep,m_sz,v)) return false;
_col_int64->set_value(v);
} else if(col_uint64* _col_uint64 = tools::id_cast<icol_t,col_uint64>(*(*it))) {
uint64 v;
if(!_read(m_reader,m_sep,m_sz,v)) return false;
_col_uint64->set_value(v);
} else if(col_time* _col_time = tools::id_cast<icol_t,col_time>(*(*it))) {
time_t v;
if(!_read(m_reader,m_sep,m_sz,v)) return false;
csv_time ct;ct.m_l = long(v);
_col_time->set_value(ct);
} else {
//std::cout << "column cast failed." << std::endl;
return false;
}
if(index==(num-1)) { //read up to LF()
char c;
while(true){
if(m_reader.tellg()>=m_sz) break;
m_reader.get(c);
if(c==LF()) break;
}
} else { //read sep :
char sep;
m_reader.get(sep);
}
}
return true;
}
protected:
std::istream& m_reader;
std::string m_title;
char m_sep;
std::vector<read::icol*> m_cols;
std::streampos m_sz;
bool m_hippo;
};
}}
#include <fstream>
namespace tools {
namespace rcsv {
class fntuple : public ntuple {
public:
static const std::string& s_class() {
static const std::string s_v("tools::rcsv::fntuple");
return s_v;
}
public:
fntuple(const std::string& a_file)
:ntuple(m_freader)
,m_file(a_file)
{}
virtual ~fntuple() {m_freader.close();}
protected:
fntuple(const fntuple& a_from)
:read::intuple(a_from),ntuple(a_from)
,m_file(a_from.m_file)
{}
fntuple& operator=(const fntuple& a_from){
m_file = a_from.m_file;
return *this;
}
public:
bool open(){
m_freader.open(m_file.c_str());
return m_freader.fail()?false:true;
}
bool initialize(std::ostream& a_out,
char a_sep = 0, //guessed
const std::string& a_suffix = "x", //col suffix
bool a_verbose = false) {
if(!m_freader.is_open()) {
m_freader.open(m_file.c_str());
if(m_freader.fail()) {
a_out << "tools::rcsv::ntuple::initialize :"
<< " can't open " << m_file << "."
<< std::endl;
return false;
}
}
return ntuple::initialize(a_out,a_sep,a_suffix,a_verbose);
}
protected:
std::string m_file;
std::ifstream m_freader;
};
}}
#endif
@@ -1,14 +1,14 @@
#ifndef tools_realloc
#define tools_realloc
#include "typedefs"
#include <cstring> //memcpy
namespace tools {
template <class T>
inline bool realloc(T*& a_pointer,uint32 a_new_size,uint32 a_old_size,bool a_init = false) {
inline bool realloc(T*& a_pointer,
unsigned int a_new_size,unsigned int a_old_size,
bool a_init = false) {
if(!a_new_size) {
delete [] a_pointer;
a_pointer = 0;
@@ -16,6 +16,7 @@ inline bool realloc(T*& a_pointer,uint32 a_new_size,uint32 a_old_size,bool a_ini
}
if(!a_pointer) {
a_pointer = new T[a_new_size];
if(!a_pointer) return false;
return true;
}
if(a_old_size==a_new_size) return true;
@@ -28,9 +29,9 @@ inline bool realloc(T*& a_pointer,uint32 a_new_size,uint32 a_old_size,bool a_ini
if(a_new_size>a_old_size) {
::memcpy(pointer,a_pointer,a_old_size*sizeof(T));
if(a_init){
uint32 num = a_new_size-a_old_size;
unsigned int num = a_new_size-a_old_size;
T* pos = pointer+a_old_size;
for(uint32 i=0;i<num;i++,pos++) *pos = T();
for(unsigned int i=0;i<num;i++,pos++) *pos = T();
}
} else {
::memcpy(pointer,a_pointer,a_new_size*sizeof(T));
@@ -0,0 +1,71 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rntuple
#define tools_rntuple
// interfaces to read ntuple.
#include "scast"
#include "cids"
#include <string>
#include <vector>
namespace tools {
namespace read {
class icol {
public:
virtual ~icol(){}
public:
virtual void* cast(cid) const = 0;
virtual cid id_cls() const = 0;
public:
virtual const std::string& name() const = 0;
public:
virtual void stop() {}
virtual bool fetch_entry() const {return false;} //for binded column API.
};
template <class T>
class icolumn : public virtual icol {
public:
static cid id_class() {
static const T s_v = T(); //do that for T = std::string.
return _cid(s_v);
}
public: //icol
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<icolumn>(this,a_class)) {return p;}
else return 0;
}
virtual cid id_cls() const {return id_class();}
public:
virtual ~icolumn(){}
public:
virtual bool get_entry(T&) const = 0;
};
class intuple {
public:
virtual ~intuple(){}
public:
virtual void start() = 0;
virtual bool next() = 0;
virtual icol* find_icol(const std::string&) = 0;
virtual const std::vector<icol*>& columns() const = 0;
public:
virtual void stop() {}
public:
template <class T>
icolumn<T>* find_column(const std::string& a_name){
read::icol* col = find_icol(a_name);
if(!col) return 0;
return id_cast<read::icol, icolumn<T> >(*col);
}
};
}}
#endif
@@ -0,0 +1,194 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_base_leaf
#define tools_rroot_base_leaf
#ifdef TOOLS_MEM
#include "../mem"
#endif
#include "named"
namespace tools {
namespace rroot {
class branch;
}}
namespace tools {
namespace rroot {
class base_leaf : public virtual iro {
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::base_leaf");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<base_leaf>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return base_leaf_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<base_leaf>(this,a_class)) {return p;}
else return 0;
}
public:
virtual bool stream(buffer& a_buffer) {
delete m_leaf_count;
m_leaf_count = 0;
int fLengthType;
int fOffset;
bool fIsRange;
bool fIsUnsigned;
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
//FIXME if (v > 1) {
//TLeaf::Class()->ReadBuffer(b, this, R__v, R__s, R__c);
//FIXME } else {
//====process old versions before automatic schema evolution
if(!Named_stream(a_buffer,m_name,m_title)) return false;
// Ok with v 1 & 2
if(!a_buffer.read(m_length)) return false;
if(!a_buffer.read(fLengthType)) return false;
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fIsRange)) return false;
if(!a_buffer.read(fIsUnsigned)) return false;
{ifac::args args;
args[ifac::arg_branch()] = &m_branch;
iro* obj;
if(!a_buffer.read_object(m_fac,args,obj)) {
m_out << "tools::rroot::base_leaf::stream :"
<< " can't read object."
<< std::endl;
return false;
}
if(!obj) {
//m_out << "tools::rroot::base_leaf::stream :"
// << " null leaf count object."
// << std::endl;
} else {
m_leaf_count = safe_cast<iro,base_leaf>(*obj);
if(!m_leaf_count) {
m_out << "tools::rroot::base_leaf::stream :"
<< " can't cast base_leaf."
<< std::endl;
m_leaf_count = 0;
delete obj;
return false;
}
}}
if(!a_buffer.check_byte_count(s,c,"TLeaf")) return false;
if(!m_length) m_length = 1;
/*
fNewValue = false;
if(!setAddress(0)) return false;
*/
return true;
}
public:
virtual bool read_basket(buffer&) = 0;
virtual bool print_value(std::ostream&,uint32) const = 0;
virtual uint32 num_elem() const = 0;
public:
base_leaf(std::ostream& a_out,rroot::branch& a_branch,ifac& a_fac)
:m_out(a_out)
,m_branch(a_branch)
,m_fac(a_fac)
,m_name("")
,m_title("")
//,fIndirectAddress(false)
//,fNewValue(false)
,m_ndata(0)
,m_length(0)
/*
,fLengthType(0)
,fOffset(0)
,fIsRange(false)
,fIsUnsigned(false)
*/
,m_leaf_count(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~base_leaf(){
delete m_leaf_count;
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
base_leaf(const base_leaf& a_from)
:iro(a_from)
,m_out(a_from.m_out)
,m_branch(a_from.m_branch)
,m_fac(a_from.m_fac)
,m_ndata(0)
,m_length(0)
,m_leaf_count(0)
{}
base_leaf& operator=(const base_leaf&){return *this;}
public:
rroot::branch& branch() {return m_branch;}
const std::string& name() const {return m_name;}
const std::string& title() const {return m_title;}
/*
uint32 length() const {
// Return the number of effective elements of this leaf.
if(m_leaf_count) {
m_out << "tools::rroot::base_leaf::length :"
<< " m_leaf_count not null. Case not yet handled."
<< std::endl;
return m_length;
//uint32 len = m_leaf_count->number();
//if (len > fLeafCount->maximum()) {
// m_out << "tools::rroot::base_leaf::length :"
// << fName << ", len=" << len << " and max="
// << fLeafCount->maximum()
// << std::endl;
// len = fLeafCount->maximum();
//}
//return len * fLength;
} else {
return m_length;
}
}
*/
protected:
std::ostream& m_out;
rroot::branch& m_branch;
ifac& m_fac;
protected: //Named
std::string m_name;
std::string m_title;
//bool fIndirectAddress;
//bool fNewValue;
uint32 m_ndata; //! Number of elements in fAddress data buffer
uint32 m_length; // Number of fixed length elements
/*
int fLengthType; // Number of bytes for this data type
int fOffset; // Offset in ClonesArray object (if one)
bool fIsRange; // (=true if leaf has a range, false otherwise)
bool fIsUnsigned; // (=kTRUE if unsigned, kFALSE otherwise)
*/
base_leaf* m_leaf_count; // Pointer to Leaf count if variable length
};
}}
#endif
@@ -0,0 +1,365 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_basket
#define tools_rroot_basket
#include "iro"
#include "key"
#include "../scast"
#include "buffer"
#include "cids"
namespace tools {
namespace rroot {
class basket : public virtual iro, public key {
static uint32 kDisplacementMask() {return 0xFF000000;}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::basket");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<basket>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return basket_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<basket>(this,a_class)) {return p;}
else return 0;
}
public:
virtual iro* copy() const {return new basket(*this);}
virtual bool stream(buffer& a_buffer) {
_clear();
uint32 startpos = a_buffer.length();
if(!key::from_buffer(a_buffer.eob(),a_buffer.pos())) return false;
uint32 fBufferSize;
short v;
if(!a_buffer.read_version(v)) return false;
if(!a_buffer.read(fBufferSize)) return false;
if(!a_buffer.read(m_nev_buf_size)) return false;
if(!a_buffer.read(m_nev)) return false;
if(!a_buffer.read(m_last)) return false;
char flag;
if(!a_buffer.read(flag)) return false;
if(m_last>fBufferSize) fBufferSize = m_last;
uint16 basket_key_length = a_buffer.length()-startpos;
if(basket_key_length!=m_key_length) {
//m_file.out() << "tools::rroot::basket::stream :"
// << " key length not consistent."
// << " read " << m_key_length
// << ", expected " << basket_key_length
// << ". Continue with " << basket_key_length
// << std::endl;
m_key_length = basket_key_length;
}
if(!m_object_size) {
//m_file.out() << "tools::rroot::basket::stream :"
// << " m_object_size is found to be zero."
// << " Continue with (m_nbytes-m_key_length) "
// << (m_nbytes-m_key_length)
// << std::endl;
m_object_size = m_nbytes-m_key_length;
}
if(!flag) return true; //fHeaderOnly
//G.Barrand : add the below test.
if( (flag!=1) &&(flag!=2) &&
(flag!=11)&&(flag!=12) &&
(flag!=41)&&(flag!=42) &&
(flag!=51)&&(flag!=52) ) {
m_file.out() << "tools::rroot::basket::stream :"
<< " bad flag " << (int)flag
<< std::endl;
return false;
}
if((flag%10)!=2) {
//due to the upper "G.Barrand if", flag is here in {1,11,41,51}
if(!m_nev_buf_size) {
m_file.out() << "tools::rroot::basket::stream :"
<< " m_nev_buf_size is zero." << std::endl;
return false;
}
if(m_nev>m_nev_buf_size) {
m_file.out() << "tools::rroot::basket::stream :"
<< " m_nev>m_nev_buf_size !"
<< " m_nev " << m_nev
<< " m_nev_buf_size " << m_nev_buf_size
<< std::endl;
return false;
}
m_entry_offset = new int[m_nev_buf_size];
if(m_nev) {
uint32 n;
if(!a_buffer.read_array<int>(m_nev_buf_size,m_entry_offset,n)) {
_clear();
return false;
}
if((n!=m_nev)&&(n!=(m_nev+1))) {
m_file.out() << "tools::rroot::basket::stream :"
<< " m_entry_offset read len mismatch."
<< " n " << n
<< " m_nev " << m_nev
<< std::endl;
_clear();
return false;
}
}
/* Due to the upper "G.Barrand if", flag can't be in ]20,40[, then to quiet Coverity we comment the below test.
if((20<flag)&&(flag<40)) {
for(uint32 i=0;i<m_nev;i++){
m_entry_offset[i] &= ~kDisplacementMask();
}
}
*/
if(flag>40) {
m_displacement = new int[m_nev_buf_size];
uint32 n;
if(!a_buffer.read_array<int>(m_nev_buf_size,m_displacement,n)) {
_clear();
return false;
}
if((n!=m_nev)&&(n!=(m_nev+1))) {
m_file.out() << "tools::rroot::basket::stream :"
<< " m_displacement read len mismatch."
<< " n " << n
<< " m_nev " << m_nev
<< std::endl;
_clear();
return false;
}
}
} else {
//m_nev_buf_size is the size in bytes of one entry.
}
if((flag==1)||(flag>10)) {
delete [] m_buffer;
m_buffer = 0;
m_buf_size = 0;
if(fBufferSize) {
char* _buf = new char[fBufferSize];
if(!_buf) {
m_file.out() << "tools::rroot::basket::stream :"
<< " can't alloc " << fBufferSize << std::endl;
_clear();
return false;
}
if(v>1) {
if(!a_buffer.read_fast_array(_buf,m_last)) {
_clear();
delete [] _buf;
return false;
}
} else {
uint32 n;
if(!a_buffer.read_array<char>(fBufferSize,_buf,n)) {
_clear();
delete [] _buf;
return false;
}
}
m_buffer = _buf;
m_buf_size = fBufferSize;
//fBufferRef->inline_setBufferOffset(m_last);
//fBranch.tree().incrementTotalBuffers(fBufferSize);
}
}
return true;
}
public:
basket(ifile& a_file)
:key(a_file)
,m_nev_buf_size(0)
,m_nev(0)
,m_last(0)
,m_entry_offset(0)
,m_displacement(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
basket(ifile& a_file,seek a_pos,uint32 a_nbytes)
:key(a_file,a_pos,a_nbytes)
,m_nev_buf_size(0)
,m_nev(0)
,m_last(0)
,m_entry_offset(0)
,m_displacement(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~basket(){
_clear();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
basket(const basket& a_from)
:iro(a_from)
,key(a_from)
,m_nev_buf_size(a_from.m_nev_buf_size)
,m_nev(a_from.m_nev)
,m_last(a_from.m_last)
,m_entry_offset(0)
,m_displacement(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
if(a_from.m_nev && a_from.m_entry_offset) {
m_entry_offset = new int[a_from.m_nev];
if(!m_entry_offset) {
m_file.out() << "tools::rroot::basket::basket(cpcstor) :"
<< " can't alloc " << a_from.m_nev << "."
<< std::endl;
} else {
uint32 len = a_from.m_nev*sizeof(int);
::memcpy(m_entry_offset,a_from.m_entry_offset,len);
}
}
if(a_from.m_nev && a_from.m_displacement) {
m_displacement = new int[a_from.m_nev];
if(!m_displacement) {
m_file.out() << "tools::rroot::basket::basket(cpcstor) :"
<< " can't alloc " << a_from.m_nev << "."
<< std::endl;
} else {
uint32 len = a_from.m_nev*sizeof(int);
::memcpy(m_displacement,a_from.m_displacement,len);
}
}
}
basket& operator=(const basket& a_from){
key::operator=(a_from);
if(&a_from==this) return *this;
m_nev_buf_size = a_from.m_nev_buf_size;
m_nev = a_from.m_nev;
m_last = a_from.m_last;
delete [] m_entry_offset;
m_entry_offset = 0;
delete [] m_displacement;
m_displacement = 0;
if(a_from.m_nev && a_from.m_entry_offset) {
m_entry_offset = new int[a_from.m_nev];
if(!m_entry_offset) {
m_file.out() << "tools::rroot::basket::operator=() :"
<< " can't alloc " << a_from.m_nev << "."
<< std::endl;
} else {
uint32 len = a_from.m_nev*sizeof(int);
::memcpy(m_entry_offset,a_from.m_entry_offset,len);
}
}
if(a_from.m_nev && a_from.m_displacement) {
m_displacement = new int[a_from.m_nev];
if(!m_displacement) {
m_file.out() << "tools::rroot::basket::operator=() :"
<< " can't alloc " << a_from.m_nev << "."
<< std::endl;
} else {
uint32 len = a_from.m_nev*sizeof(int);
::memcpy(m_displacement,a_from.m_displacement,len);
}
}
return *this;
}
public:
int* entry_offset() {return m_entry_offset;}
int* displacement() {return m_displacement;}
uint32 nev_buf_size() const {return m_nev_buf_size;}
uint32 nev() const {return m_nev;}
bool read_offset_tables() {
if(!m_buffer) return false;
if(!m_last) return false;
delete [] m_entry_offset;
m_entry_offset = 0;
rroot::buffer buffer(m_file.out(),m_file.byte_swap(),
m_buf_size,m_buffer,0,false);
buffer.set_offset(m_last);
{uint32 n;
if(!buffer.read_array<int>(0,m_entry_offset,n)) {
m_file.out() << "tools::rroot::basket::read_offset_tables :"
<< " read_array failed."
<< std::endl;
return false;
}
if((n!=m_nev)&&(n!=(m_nev+1))) {
m_file.out() << "tools::rroot::basket::read_offset_tables :"
<< " m_entry_offset read len mismatch."
<< " n " << n
<< " m_nev " << m_nev
<< std::endl;
return false;
}}
delete [] m_displacement;
m_displacement = 0;
if(buffer.length()!=buffer.size()) {
// There is more data in the buffer! It is the diplacement
// array.
uint32 n;
if(!buffer.read_array<int>(0,m_displacement,n)) {
m_file.out() << "tools::rroot::basket::read_offset_tables :"
<< " readArray(2) failed."
<< std::endl;
return false;
}
if((n!=m_nev)&&(n!=(m_nev+1))) {
m_file.out() << "tools::rroot::basket::read_offset_tables :"
<< " m_displacement read len mismatch."
<< " n " << n
<< " m_nev " << m_nev
<< std::endl;
return false;
}
}
return true;
}
protected:
void _clear(){
delete [] m_entry_offset;
delete [] m_displacement;
m_entry_offset = 0;
m_displacement = 0;
}
protected: //Named
uint32 m_nev_buf_size; //Length in Int_t of m_entry_offset
uint32 m_nev; //Number of entries in basket
uint32 m_last; //Pointer to last used byte in basket
int* m_entry_offset; //[m_nev] Offset of entries in fBuffer(TKey)
int* m_displacement; //![m_nev] Displacement of entries in fBuffer(TKey)
};
}}
#endif
@@ -0,0 +1,955 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_branch
#define tools_rroot_branch
#include "base_leaf"
#include "basket"
#include "named"
#include "seek"
#include "ifile"
#include "ifac"
#include "../mnmx"
#include "../forit"
#include <map>
namespace tools {
namespace rroot {
class branch : public virtual iro {
//static uint32 kDoNotProcess() {return (1<<10);} // Active bit for branches
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::branch");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<branch>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return branch_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<branch>(this,a_class)) {return p;}
else return 0;
}
public:
virtual iro* copy() const {return new branch(*this);}
virtual bool stream(buffer& a_buffer) {
_clear();
int fCompress;
int fBasketSize;
//int fNleaves;
//uint64 m_entries;
//uint64 m_tot_bytes;
//uint64 m_zip_bytes;
int fSplitLevel;
uint32 fMaxBaskets;
int fOffset;
unsigned int s,c;
//FIXME gROOT->SetReadingObject(kTRUE);
short vers;
if(!a_buffer.read_version(vers,s,c)) return false;
//::printf("debug : branch::stream : version %d count %d\n",vers,c);
if (vers > 5) {
//TBranch::Class()->ReadBuffer(b, this, v, s, c);
//gBranch = branchSave;
//fDirectory = gDirectory;
//fNleaves = m_leaves.GetEntriesFast();
//if (fFileName.Length() != 0) fDirectory = 0;
//gROOT->SetReadingObject(kFALSE);
//return;
}
//====process old versions before automatic schema evolution
{uint32 old = a_buffer.length();
uint32 id;
uint32 m_bits;
if(!Object_stream(a_buffer,id,m_bits)) return false;
a_buffer.set_offset(old);}
if(!Named_stream(a_buffer,m_name,m_title)) return false;
//::printf("debug : branch::stream %s %s\n",
// m_name.c_str(),m_title.c_str());
if(vers<=5) {
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(m_write_basket)) return false;
if(!a_buffer.read(m_entry_number)) return false;
{double v;
if(!a_buffer.read(v)) return false;
//m_entries = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
if(!a_buffer.read(fOffset)) return false;
} else if(vers<=6) {
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
if(!a_buffer.read(m_entry_number)) return false;
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
{double v;
if(!a_buffer.read(v)) return false;
//m_entries = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
} else if(vers<=7) {
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
if(!a_buffer.read(m_entry_number)) return false;
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(fSplitLevel)) return false;
{double v;
if(!a_buffer.read(v)) return false;
//m_entries = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
} else if(vers<=9) {
{short color,style;
if(!AttFill_stream(a_buffer,color,style)) return false;}
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
if(!a_buffer.read(m_entry_number)) return false;
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(fSplitLevel)) return false;
{double v;
if(!a_buffer.read(v)) return false;
//m_entries = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
} else if(vers<=10) {
{short color,style;
if(!AttFill_stream(a_buffer,color,style)) return false;}
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
{uint64 v;
if(!a_buffer.read(v)) return false;
m_entry_number = uint32(v);}
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(fSplitLevel)) return false;
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_entries = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = v;
}
} else { //vers>=11
{short color,style;
if(!AttFill_stream(a_buffer,color,style)) return false;}
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
{uint64 v;
if(!a_buffer.read(v)) return false;
m_entry_number = uint32(v);}
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(fSplitLevel)) return false;
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_entries = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;} //fFirstEntry
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = v;
}
}
//::printf("debug : branch::stream : %s : fSplitLevel %d\n",m_name.c_str(),fSplitLevel);
//TObjArray
//::printf("debug : branch::stream : branches : begin\n");
{ifac::args args;
if(!m_branches.stream(a_buffer,args)) {
m_out << "tools::rroot::branch::stream :"
<< " can't read branches."
<< std::endl;
return false;
}}
//::printf("debug : branch::stream : branches : end %d\n",
// m_branches.size());
/* We see that with LHCb files.
if(m_entry_number!=m_entries) {
m_out << "tools::rroot::branch::stream :"
<< " for branch " << sout(m_name) << " :"
<< " WARNING : m_entry_number!=m_entries."
<< " m_entry_number " << m_entry_number
<< " m_entries " << m_entries
<< std::endl;
//return false;
}
*/
//TObjArray
//::printf("debug : branch::stream : leaves : begin\n");
{ifac::args args;
args[ifac::arg_branch()] = this;
if(!m_leaves.stream(a_buffer,args)) {
m_out << "tools::rroot::branch::stream :"
<< " can't read leaves."
<< std::endl;
return false;
}}
//::printf("debug : branch::stream : leaves : end\n");
//TObjArray
//IMPORTANT : accept_null=true
//::printf("debug : branch::stream : streamed_baskets : begin\n");
{ifac::args args;
if(!m_streamed_baskets.stream(a_buffer,args,true)) {
m_out << "tools::rroot::branch::stream :"
<< " can't read baskets."
<< std::endl;
return false;
}}
//::printf("debug : branch::stream : streamed_baskets : end\n");
//fNleaves = m_leaves.size();
if(fMaxBaskets<=0) {
m_out << "tools::rroot::branch::stream :"
<< " fMaxBaskets null."
<< std::endl;
return false;
}
fBasketEntry = new int[fMaxBaskets];
fBasketBytes = new int[fMaxBaskets];
fBasketSeek = new seek[fMaxBaskets];
{for(uint32 i=0;i<fMaxBaskets;i++) {
fBasketEntry[i] = 0;
fBasketBytes[i] = 0;
fBasketSeek[i] = 0;
}}
if(vers<6) {
{uint32 n;
if(!a_buffer.read_array<int>(fMaxBaskets,fBasketEntry,n)) {
_clear();
return false;
}}
if(vers<=4) {
for (uint32 i=0;i<fMaxBaskets;i++) fBasketBytes[i] = 0;
} else {
uint32 n;
if(!a_buffer.read_array<int>(fMaxBaskets,fBasketBytes,n)) {
_clear();
return false;
}
}
if(vers<2) {
//GB : comment.
//for(int i=0;i<m_write_basket;i++) {
// fBasketSeek[i] = getBasket(i)->seekKey();
//}
m_out << "tools::rroot::branch::stream :"
<< " v < 2. Not (yet) handled."
<< std::endl;
_clear();
return false;
} else {
int n;
if(!a_buffer.read(n)) {
_clear();
return false;
}
for(int i=0;i<n;i++) {
seek32 _s;
if(!a_buffer.read(_s)) {
_clear();
return false;
}
fBasketSeek[i] = _s;
}
}
} else if(vers<=9) {
// See TStreamerInfo::ReadBuffer::ReadBasicPointer
//Int_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
if(!a_buffer.read_fast_array<int>(fBasketBytes,fMaxBaskets)) {
_clear();
return false;
}
}}
//Int_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
if(!a_buffer.read_fast_array<int>(fBasketEntry,fMaxBaskets)) {
_clear();
return false;
}
}}
//Seek_t[fMaxBaskets]
{char isBigFile;
if(!a_buffer.read(isBigFile)) {
_clear();
return false;
}
if(isBigFile==2) {
if(!a_buffer.read_fast_array<seek>(fBasketSeek,fMaxBaskets)) {
_clear();
return false;
}
} else {
for(uint32 i=0;i<fMaxBaskets;i++) {
seek32 _s;
if(!a_buffer.read(_s)) {
_clear();
return false;
}
fBasketSeek[i] = _s;
}
}}
} else { //vers>=10
// See TStreamerInfo::ReadBuffer::ReadBasicPointer
//Int_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
if(!a_buffer.read_fast_array<int>(fBasketBytes,fMaxBaskets)) {
_clear();
return false;
}
}}
//Long64_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
uint64* v = new uint64[fMaxBaskets];
if(!a_buffer.read_fast_array<uint64>(v,fMaxBaskets)) {
_clear();
return false;
}
for(uint32 i=0;i<fMaxBaskets;i++) fBasketEntry[i] = int(v[i]);
delete [] v;
}}
//Long64_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
uint64* v = new uint64[fMaxBaskets];
if(!a_buffer.read_fast_array<uint64>(v,fMaxBaskets)) {
_clear();
return false;
}
for(uint32 i=0;i<fMaxBaskets;i++) fBasketSeek[i] = v[i];
delete [] v;
}}
}
if(vers>2) {
//TString
std::string fileName;
if(!a_buffer.read(fileName)) {
_clear();
return false;
}
}
//FIXME if(vers<4) SetAutoDelete(kTRUE);
//FIXME gROOT->SetReadingObject(kFALSE);
if(!a_buffer.check_byte_count(s, c,"TBranch")) {
_clear();
return false;
}
//GB : analyse fBasketEntry.
m_first_last.clear();
{// There are (m_write_basket+1) sensitive elements in fBasketEntry :
// (Do we have to check that ?)
for(uint32 i=0;i<m_write_basket;i++) {
uint32 first = fBasketEntry[i];
uint32 last = fBasketEntry[i+1]-1;
m_first_last.push_back(std::pair<uint32,uint32>(first,last));
}
if(m_entry_number) {
uint32 first = fBasketEntry[m_write_basket];
uint32 last = m_entry_number-1;
m_first_last.push_back(std::pair<uint32,uint32>(first,last));
}}
//_dump_first_last();
//GB : analyse fBasketSeek :
{uint32 num = 0;
uint32 mxi = 0;
for(uint32 i=0;i<fMaxBaskets;i++) {
if(!fBasketSeek[i]) continue;
num++;
mxi = mx<uint32>(i,mxi);
}
if(m_write_basket) {
if((num!=m_write_basket)||(mxi!=(m_write_basket-1))) {
m_out << "tools::rroot::branch::stream :"
<< " fBasketSeek[] inconsistent with m_write_basket."
<< " m_write_basket " << m_write_basket
<< " num " << num
<< " mxi " << mxi
<< std::endl;
_clear();
return false;
}
}}
//GB : analyse m_streamed_baskets :
{int index = 0;
tools_vforcit(basket*,m_streamed_baskets,it) {
if(*it) {
if(!(*it)->buf()||!(*it)->buf_size()) {
m_out << "tools::rroot::branch::stream :"
<< " expect a basket with a not empty buffer."
<< std::endl;
return false;
}
//in the below, false is to say m_baskets is not owner of *it.
m_baskets[index] = std::pair<basket*,bool>(*it,false);
}
index++;
}}
return true;
}
public:
//virtual for branch_element
virtual bool read_leaves(buffer& a_buffer){
tools_vforcit(base_leaf*,m_leaves,it) {
if(!(*it)->read_basket(a_buffer)) {
m_out << "tools::rroot::branch::read_leaves :"
<< " read_basket failed."
<< std::endl;
return false;
}
}
return true;
}
virtual bool find_entry(uint32 a_entry,uint32& a_nbytes){
// Read all leaves of entry and return total number of bytes :
// The input argument entry is the entry serial number in the current tree.
a_nbytes = 0;
//if(_test_bit(kDoNotProcess())) return true;
//if(fReadEntry == (int)a_entry) return true;
if(a_entry>=m_entry_number) {
//m_out << "tools::rroot::branch::find_entry :"
// << " for branch " << sout(m_name) << " :"
// << " a_entry not within [0," << m_entry_number << "[."
// << std::endl;
//return false;
return true; //CERN-ROOT does not consider it is an error.
}
if(!m_entry_number || m_first_last.empty() ) { //GB
m_out << "tools::rroot::branch::find_entry :"
<< " nothing to read."
<< std::endl;
return false; //nothing to read.
}
if(m_read_basket>=m_first_last.size()) {
m_out << "tools::rroot::branch::find_entry :"
<< " bad m_first_last access."
<< std::endl;
return false;
}
uint32 first = m_first_last[m_read_basket].first;
uint32 last = m_first_last[m_read_basket].second;
// Are we still in the same ReadBasket?
if((a_entry<first)||(a_entry>last)) {
m__read_basket = 0;
uint32 old_read_basket = m_read_basket;
//look first in the next basket window :
bool found = false;
if((m_read_basket+1)<m_first_last.size()) {
first = m_first_last[m_read_basket+1].first;
last = m_first_last[m_read_basket+1].second;
if((a_entry>=first)&&(a_entry<=last)) {
m_read_basket++;
found = true;
}
}
if(!found) {
uint32 count = 0;
typedef std::pair<uint32,uint32> first_last;
tools_vforcit(first_last,m_first_last,it) {
first = (*it).first;
last = (*it).second;
if((a_entry>=first)&&(a_entry<=last)) {
m_read_basket = count;
found = true;
break;
}
count++;
}
}
if(!found) { //something weird in fBasketEntry.
m_out << "tools::rroot::branch::find_entry :"
<< " fancy fBasketEntry."
<< std::endl;
return false;
} else {
// if found, erase m_baskets[old_read_basket] to avoid
// having all data in memory !
std::map<uint32, std::pair<rroot::basket*,bool> >::iterator it =
m_baskets.find(old_read_basket);
if(it!=m_baskets.end()) {
if((*it).second.second) {
basket* bsk = (*it).second.first;
m_baskets.erase(it);
delete bsk;
//::printf("debug : erase basket %d\n",old_read_basket);
}
}
}
}
if(!m__read_basket) {
rroot::basket* bsk = 0;
std::map<uint32, std::pair<basket*,bool> >::iterator it =
m_baskets.find(m_read_basket);
if(it!=m_baskets.end()) {
bsk = (*it).second.first;
} else {
if(m_read_basket>=m_write_basket) {
m_out << "tools::rroot::branch::find_entry :"
<< " basket lacking !"
<< " wanting index " << m_read_basket
<< ". fBasketSeek entries " << m_write_basket
<< std::endl;
return false;
}
if(!fBasketSeek[m_read_basket]) {
m_out << "tools::rroot::branch::find_entry :"
<< " fBasketSeek is null for index " << m_read_basket
<< std::endl;
return false;
}
if(!fBasketBytes[m_read_basket]) {
m_out << "tools::rroot::branch::find_entry :"
<< " fBasketBytes is null for index " << m_read_basket
<< std::endl;
return false;
}
bsk = get_basket(fBasketSeek[m_read_basket],
fBasketBytes[m_read_basket]);
if(!bsk) {
m_out << "tools::rroot::branch::find_entry :"
<< " can't read basket " << m_read_basket
<< " at file pos " << fBasketSeek[m_read_basket]
<< " and size " << fBasketBytes[m_read_basket]
<< std::endl;
return false;
}
//m_out << "tools::rroot::branch::find_entry :"
// << " got basket " << m_read_basket
// << " of size " << fBasketBytes[m_read_basket]
// << std::endl;
m_baskets[m_read_basket] = std::pair<basket*,bool>(bsk,true);
}
m__read_basket = bsk;
}
// Set entry offset in buffer and read data from all leaves
//buf->resetMap();
uint32 bufbegin;
{int* entry_offset = m__read_basket->entry_offset();
if(entry_offset) {
uint32 index = a_entry-first;
if(index>=m__read_basket->nev()) {
m_out << "tools::rroot::branch::find_entry :"
<< " can't access entry offset " << index
<< ". nev " << m__read_basket->nev()
<< std::endl;
return false;
}
bufbegin = entry_offset[index];
//::printf("debug : xxx++ %u : %u\n",index,bufbegin);
} else {
bufbegin = m__read_basket->key_length() +
(a_entry-first)*m__read_basket->nev_buf_size();
}}
{int* displacement = m__read_basket->displacement();
if(displacement) {
m_out << "tools::rroot::branch::find_entry :"
<< " not null displacement. Not yet handled."
<< std::endl;
//buf->setDisplacement(displacement[a_entry-first]);
} else {
//buf->setDisplacement();
}}
/*
if(bufbegin>=m__read_basket->buf_size()) {
m_out << "tools::rroot::branch::find_entry :"
<< " bad buffer access for entry " << a_entry
<< ". bufbegin " << bufbegin
<< ", buf_size " << basket->buf_size()
<< ", (entry-first) " << (a_entry-first)
<< std::endl;
{int* entry_offset = m__read_basket->entry_offset();
if(entry_offset) {
uint32 nev = m__read_basket->nev();
::printf("debug : eoff : num %d\n",nev);
for(uint32 i=0;i<nev;i++){
::printf("debug : eoff %d : %d\n",i,entry_offset[i]);
}
}}
return false;
}
*/
rroot::buffer buffer(m_out,m_file.byte_swap(),
m__read_basket->buf_size(),m__read_basket->buf(),0,false);
buffer.set_offset(bufbegin);
if(!read_leaves(buffer)) {
m_out << "tools::rroot::branch::find_entry :"
<< " can't read leaves for entry " << a_entry
<< ". read_basket was " << m_read_basket
<< ", first " << first
<< ", last " << last
<< "."
<< std::endl;
return false;
}
//fReadEntry = a_entry;
a_nbytes = buffer.length() - bufbegin;
return true;
}
public:
branch(ifile& a_file,ifac& a_fac)
:m_file(a_file)
,m_out(a_file.out())
,m_fac(a_fac)
,m_streamed_baskets(m_fac,true)
,m__read_basket(0)
//,m_bits(0)
,m_name("")
,m_title("")
,fAutoDelete(false)
,m_branches(m_fac,true)
,m_leaves(m_fac,true)
,fEntryOffsetLen(0)
,m_write_basket(0)
,m_entry_number(0)
,m_read_basket(0)
,fBasketBytes(0)
,fBasketEntry(0)
,fBasketSeek(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~branch(){
_clear();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
branch(const branch& a_from)
:iro(a_from)
,m_file(a_from.m_file),m_out(a_from.m_out),m_fac(a_from.m_fac)
,m_streamed_baskets(m_fac,false),m__read_basket(0)
,fAutoDelete(false)
,m_branches(m_fac,false),m_leaves(m_fac,false)
,fEntryOffsetLen(1000)
,m_write_basket(0)
,m_entry_number(0)
,m_read_basket(0)
,fBasketBytes(0)
,fBasketEntry(0)
,fBasketSeek(0)
{}
branch& operator=(const branch&){return *this;}
public:
ifile& file() {return m_file;}
uint32 entry_number() const {return m_entry_number;}
const std::string& name() const {return m_name;}
const std::string& title() const {return m_title;}
const std::vector<base_leaf*>& leaves() const {return m_leaves;}
const std::vector<branch*>& branches() const {return m_branches;}
bool show(std::ostream& a_out,uint32 a_entry){
// Print values of all active leaves for entry :
// if entry==-1, print current entry (default)
uint32 n;
if(!find_entry(a_entry,n)) return false;
tools_vforcit(base_leaf*,m_leaves,it) {
base_leaf* bl = *it;
uint32 num = bl->num_elem();
num = mn<uint32>(num,10);
if(!num) continue;
{std::string s;
uint32 len = bl->name().size()+128;
sprintf(s,len," %-15s = ",bl->name().c_str());
a_out << s;}
for(uint32 i=0;i<num;i++) {
if(i) a_out << ", ";
bl->print_value(a_out,i);
}
a_out << std::endl;
}
return true;
}
protected:
basket* get_basket(seek a_pos,uint32 a_len) {
//if(fBranch.tree().memoryFull(fBufferSize)) fBranch.dropBaskets();
if(!a_len) return 0;
rroot::basket* basket =
new rroot::basket(m_file,a_pos,a_len); //basket is a key.
if(!basket->read_file()) {
m_out << "tools::rroot::branch::get_basket :"
<< " read_file() failed."
<< std::endl;
delete basket;
return 0;
}
{rroot::buffer buffer(m_out,m_file.byte_swap(),
a_len,basket->buf(),0,false);
if(!basket->stream(buffer)) {
m_out << "tools::rroot::branch::get_basket :"
<< " basket stream failed."
<< std::endl;
delete basket;
return 0;
}}
unsigned int sz;
char* buf = basket->get_object_buffer(sz); //basket owns buf.
if(!buf) {
m_out << "tools::rroot::branch::get_basket :"
<< " get_object_buffer() failed."
<< std::endl;
delete basket;
return 0;
}
if(basket->seek_key()!=a_pos) { //consistency check.
m_out << "tools::rroot::branch::get_basket :"
<< " seek anomaly."
<< " a_pos " << a_pos
<< " seek_key() " << basket->seek_key()
<< std::endl;
delete basket;
return 0;
}
//if(basket->nbytes()!=a_len) { //consistency check.
// m_out << "tools::rroot::branch::get_basket :"
// << " WARNING : length anomaly."
// << " a_len " << a_len
// << " nbytes() " << basket->nbytes()
// << std::endl;
//}
if(fEntryOffsetLen) {
if(!basket->read_offset_tables()) {
m_out << "tools::rroot::branch::get_basket :"
<< " read_offset_tables failed."
<< std::endl;
delete basket;
return 0;
}}
return basket;
}
protected:
void _clear() {
delete [] fBasketEntry;
delete [] fBasketBytes;
delete [] fBasketSeek;
fBasketEntry = 0;
fBasketBytes = 0;
fBasketSeek = 0;
{typedef std::pair<basket*,bool> basket_todel;
tools_mforit(uint32,basket_todel,m_baskets,it) {
if((*it).second.second) delete (*it).second.first;
}
m_baskets.clear();}
m_branches.cleanup();
m_leaves.cleanup();
m_streamed_baskets.cleanup();
}
void _dump_first_last() {
m_out << "tools::rroot::branch::_dump_first_last :"
<< " first_last " << m_first_last.size()
<< std::endl;
typedef std::pair<uint32,uint32> first_last;
tools_vforcit(first_last,m_first_last,it) {
uint32 first = (*it).first;
uint32 last = (*it).second;
m_out << "tools::rroot::branch::stream :"
<< " first " << first
<< " last " << last
<< std::endl;
}
}
//bool _test_bit(uint32 a_f) const {
// return (bool)(m_bits & a_f);
//}
static std::string sout(const std::string& a_string) {
return std::string("\"")+a_string+"\"";
}
protected:
//Tree& fTree;
ifile& m_file;
std::ostream& m_out;
ifac& m_fac;
std::vector< std::pair<uint32,uint32> > m_first_last;
std::map<uint32, std::pair<basket*,bool> > m_baskets;
ObjArray<basket> m_streamed_baskets;
basket* m__read_basket; //optimization
protected:
//Object
//uint32 m_bits;
//Named
std::string m_name;
std::string m_title;
bool fAutoDelete;
ObjArray<branch> m_branches;
ObjArray<base_leaf> m_leaves;
uint32 fEntryOffsetLen; // Initial Length of fEntryOffset table in the basket buffers
uint32 m_write_basket; // Last basket number written
uint32 m_entry_number; // Current entry number (last one filled in this branch)
uint32 m_read_basket; //! Current basket number when reading
int* fBasketBytes; //[fMaxBaskets] Lenght of baskets on file
int* fBasketEntry; //[fMaxBaskets] Table of first entry in eack basket
seek* fBasketSeek; //[fMaxBaskets] Addresses of baskets on file
};
}}
#endif
@@ -0,0 +1,319 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_branch_element
#define tools_rroot_branch_element
#include "branch"
namespace tools {
namespace rroot {
class branch_element : public branch {
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::branch_element");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<branch_element>(this,a_class)) return p;
return branch::cast(a_class);
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return branch_element_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<branch_element>(this,a_class)) {return p;}
return branch::cast(a_class);
}
public:
virtual bool stream(buffer& a_buffer) {
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!branch::stream(a_buffer)) return false;
if(v<=7) {
if(!a_buffer.read(fClassName)) return false;
if(!a_buffer.read(fClassVersion)) return false;
if(!a_buffer.read(fID)) return false;
if(!a_buffer.read(fType)) return false;
if(!a_buffer.read(fStreamerType)) return false;
} else { //v>=8
if(!a_buffer.read(fClassName)) return false;
std::string fParentName;
if(!a_buffer.read(fParentName)) return false;
std::string fCloneName;
if(!a_buffer.read(fCloneName)) return false;
int dummy_int;
if(!a_buffer.read(dummy_int)) return false; //fCheckSum
if(!a_buffer.read(dummy_int)) return false; //fClassVersion
if(!a_buffer.read(fID)) return false;
if(!a_buffer.read(fType)) return false;
if(!a_buffer.read(fStreamerType)) return false;
if(!a_buffer.read(dummy_int)) return false; //fMaximum
//TBranchElement* fBranchCount;
if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
m_out << "tools::rroot::base_element::stream : "
<< "can't read fBranchCount."
<< std::endl;
return false;
}
//TBranchElement* fBranchCount2;
if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
m_out << "tools::rroot::base_element::stream : "
<< "can't read fBranchCount2."
<< std::endl;
return false;
}
}
if(!a_buffer.check_byte_count(s,c,"TBranchElement")) return false;
return true;
}
public: //branch
virtual bool read_leaves(buffer& a_buffer){
// read object ?
if(!m_obj) {
ifac::args args;
m_obj = m_fac.create(fClassName,args);
if(!m_obj) return false;
}
if(!m_obj->stream(a_buffer)){
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName << " :"
<< " obj stream failed."
<< std::endl;
return false;
}
return true;
/*
///////////////////////////////////////////////////////
/// STL container /////////////////////////////////////
///////////////////////////////////////////////////////
if(fType==4) {
// STL container master branch (has only the number of elements).
//from v4-00-01
int n;
if(!a_buffer.read(n)) return false;
//fNdata = n;
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName
<< " : type " << fType << " not treated."
<< std::endl;
return false;
} else if(fType==41) {
// STL container sub-branch (contains the elements).
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName
<< " : type " << fType << " not treated."
<< std::endl;
return false;
///////////////////////////////////////////////////////
/// TClonesArray container ////////////////////////////
///////////////////////////////////////////////////////
} else if(fType==3) {
// TClonesArray master branch (has only the number of elements).
//from v4-00-01
int n;
if(!a_buffer.read(n)) return false;
//fNdata = n;
//TClonesArray *clones = (TClonesArray*)fObject;
//if (!clones) return;
//if (clones->IsZombie()) return;
//clones->Clear();
//clones->ExpandCreateFast(fNdata);
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName
<< " : type " << fType << " not treated."
<< std::endl;
return false;
} else if(fType==31) {
// TClonesArray sub-branch (contains the elements).
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName
<< " : type " << fType << " not treated."
<< std::endl;
return false;
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
} else if(fType<=2) {
// branch in split mode
//from v4-00-01
//if (fBranchCount) fNdata = (Int_t)fBranchCount->GetValue(0,0);
//else fNdata = 1;
//if (!fInfo) return;
//fInfo->ReadBuffer(b,fObject,fID);
//if (fStreamerType == 6) fNdata = (Int_t)GetValue(0,0);
//from 3.0.06
//if (fID >= 0) {
// fInfo->ReadBuffer(b,fAddress,fID);
//} else if (fID == -1) { // top level branch in non split mode
// char **ppointer = (char**)fAddress;
// fInfo->ReadBuffer(b,*ppointer,fID);
//}
//m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " type " << fType << " with ID " << fID << "."
// << " and then ?"
// << std::endl;
// read object ?
if(!m_obj) {
ifac::args args;
m_obj = m_fac.create(fClassName,args);
if(!m_obj) return false;
}
if(!m_obj->stream(a_buffer)){
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName << " :"
<< " obj stream failed."
<< std::endl;
return false;
}
//m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " obj streamed."
// << std::endl;
return true;
// } else if(fType==0) {
// if(fID>=0) {
// // branch in split mode
// m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " type 0 with ID " << fID << "."
// << std::endl;
// return true;
//
// } else if(fID==-1) {
// // top level branch in non split mode
// m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " type 0 with ID " << fID
// << " : fill object."
// << std::endl;
// if(!m_obj) {
// m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " m_obj is null."
// << std::endl;
// return false;
// }
// if(!m_obj->stream(a_buffer)){
// m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " obj stream failed."
// << std::endl;
// return false;
// }
// return true;
// } else {
// m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " type 0 with ID " << fID << " not treated."
// << std::endl;
// return false;
// }
// //LHCb files :
// } else if(fType==1) {
// // parent branch is a base class branch.
// // Ok, and then ?
// m_out << "tools::rroot::branch_element::read_leaves :"
// << " name " << m_name << " ref_cls " << fClassName << " :"
// << " type " << fType << " with ID " << fID << "."
// << std::endl;
// return true;
} else {
m_out << "tools::rroot::branch_element::read_leaves :"
<< " name " << m_name << " ref_cls " << fClassName << " :"
<< " type " << fType << " with ID " << fID << "."
<< " unknown case."
<< std::endl;
return false;
}
*/
}
virtual bool find_entry(uint32 a_entry,uint32& a_nbytes){
//The below line will call the upper read_leaves.
if(!branch::find_entry(a_entry,a_nbytes)) return false;
if(m_branches.size()) {
//if(!m_obj) {
// m_obj = m_fac.create(fClassName);
// if(!m_obj) return false;
//}
tools_vforcit(branch*,m_branches,it) {
uint32 n;
if(!(*it)->find_entry(a_entry,n)) return false;
a_nbytes += n;
}
}
return true;
}
public:
branch_element(ifile& a_file,ifac& a_fac)
: branch(a_file,a_fac)
,m_obj(0)
,fClassVersion(0)
,fID(0)
,fType(0)
,fStreamerType(-1)
{}
virtual ~branch_element(){delete m_obj;}
protected:
branch_element(const branch_element& a_from)
:iro(a_from),branch(a_from){}
branch_element& operator=(const branch_element&){return *this;}
public:
const std::string& class_name() const {return fClassName;}
int type() const {return fType;}
int streamer_type() const {return fStreamerType;}
int id() const {return fID;}
iro* object() {return m_obj;}
protected:
iro* m_obj;
protected:
std::string fClassName; //Class name of referenced object
int fClassVersion; //Version number of class
int fID; //element serial number in fInfo
int fType; //branch type
int fStreamerType; //branch streamer type
};
}}
#endif
@@ -0,0 +1,593 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_buffer
#define tools_rroot_buffer
#include "rbuf"
#include "ifac"
#include "iro"
#include "../tos"
#ifdef TOOLS_MEM
#include "../mem"
#endif
#include <string>
#include <vector>
#include <ostream>
// in TOOLS_STL, we don't have (yet) a performant map.
#ifdef inlib_stl_vector
#define TOOLS_RROOT_OBJ_MAP_HASH_TABLE
//#define TOOLS_RROOT_OBJ_MAP_OMAP
#else
#define TOOLS_RROOT_OBJ_MAP_STD_MAP
#endif
#ifdef TOOLS_RROOT_OBJ_MAP_STD_MAP
#include <map>
#endif
#ifdef TOOLS_RROOT_OBJ_MAP_OMAP
#include "../omap"
#endif
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
#include "../hash_table"
#include "../hash"
#endif
namespace tools {
namespace rroot {
class buffer : public rbuf {
static const std::string& s_class() {
static const std::string s_v("tools::rroot::buffer");
return s_v;
}
#ifdef TOOLS_RROOT_OBJ_MAP_STD_MAP
typedef std::map<uint32,iro*> obj_map;
#endif
#ifdef TOOLS_RROOT_OBJ_MAP_OMAP
typedef inlib::omap<uint32,iro*> obj_map;
#endif
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
class obj_map : public inlib::hash_table<uint32,iro*> {
typedef inlib::hash_table<uint32,iro*> parent;
protected:
virtual unsigned int hash(const uint32& a_key) {
return inlib::hash(&a_key,sizeof(uint32));
}
virtual bool cmp(const uint32& a_key1,const uint32& a_key2) {
return a_key1==a_key2?true:false;
}
public:
obj_map():parent(){}
virtual ~obj_map(){}
private:
obj_map(const obj_map& a_from):parent(a_from){}
obj_map& operator=(const obj_map& a_from){
parent::operator=(a_from);
return *this;
}
};
#endif
public:
buffer(std::ostream& a_out,bool a_byte_swap,
uint32 a_size,char* a_buffer,uint32 a_klen,bool a_verbose)
: rbuf(a_out,a_byte_swap,a_buffer+a_size,m_pos)
,m_byte_swap(a_byte_swap)
,m_verbose(a_verbose)
,m_size(a_size) //expect a not zero size.
,m_buffer(a_buffer) //don't get ownership.
,m_pos(a_buffer)
,m_klen(a_klen) //to compute refs (used in read_class, read_object)
,m_map_objs(false)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~buffer(){
m_objs.clear();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
buffer(const buffer& a_from)
: rbuf(a_from.m_out,a_from.m_byte_swap,0,m_pos)
,m_byte_swap(a_from.m_byte_swap)
,m_map_objs(a_from.m_map_objs)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
buffer& operator=(const buffer&){return *this;}
public:
void set_offset(unsigned int a_off) {m_pos = m_buffer+a_off;}
//char* buffer() const {return m_buffer;}
uint32 length() const {return m_pos-m_buffer;}
uint32 size() const {return m_size;}
void set_map_objs(bool a_value) {m_map_objs = a_value;}
protected:
// on first_int :
static uint32 kNullTag() {return 0;}
static uint32 kByteCountMask() {return 0x40000000;}
// on tag :
static uint32 kNewClassTag() {return 0xFFFFFFFF;}
static uint32 kClassMask() {return 0x80000000; }
static uint32 kMapOffset() {return 2;}
static short kByteCountVMask() {return 0x4000;}
bool read_class_tag(std::string& a_class) {
a_class.clear();
uint32 tag;
if(!rbuf::read(tag)) return false;
//m_out << "tag " << tag << " " << tosx(tag) << std::endl;
if(tag==kNewClassTag()) {
char s[80];
if(!read_string(s, 80)) {
m_out << "tools::rroot::read_class_tag :"
<< " read string." << std::endl;
return false;
}
//m_out << "tools::rroot::read_class_tag :"
// << " tag kNewClassTag"
// << " class " << s
// << std::endl;
a_class = s;
return true;
} else if(tag & kClassMask()) {
//m_out << "tools::rroot::read_class_tag :"
// << " tag & kClassMask"
// << " ref " << (uint32)(tag & ~kClassMask)
// << " recurse..."
// << std::endl;
unsigned int cl_offset = (tag & ~kClassMask());
cl_offset -= kMapOffset();
cl_offset -= m_klen;
char* old_pos = m_pos;
m_pos = m_buffer + cl_offset;
//std::string scls;
//uint32 ref;
if(!read_class_tag(a_class)) return false;
m_pos = old_pos;
return true;
} else {
m_out << "tools::rroot::read_class_tag :"
<< " tag unknown case ! "
<< tag << " hex " << tosx(tag)
<< std::endl;
return false;
}
}
bool read_class(std::string& a_class,uint32& a_bcnt,bool& a_is_ref){
//m_verbose = true;
a_class.clear();
a_bcnt = 0;
a_is_ref = false;
//uint32 fVersion = 0; //Buffer format version
// read byte count and/or tag (older files don't have byte count)
uint32 first_int = 0;
if(!rbuf::read(first_int)) return false;
if(m_verbose) {
m_out << "tools::rroot::read_class :"
<< " first_int " << tosx(first_int)
<< std::endl;
}
if(first_int==kNullTag()) { //GB
if(m_verbose) {
m_out << "tools::rroot::read_class :"
<< " first_int is kNullTag."
<< std::endl;
}
a_bcnt = 0;
return true;
//} else if(first_int==kNewClassTag()) { // class desc follows.
} else if(first_int & kByteCountMask()) {
// at write :
// skip int to store bcnt.
// + write class
// if(!write((clIdx | Rio_kClassMask))) return false;
// or
// if(!write(Rio_kNewClassTag)) return false;
// + write object
// + set byte cnt (cnt|kByteCountMask()) at skipped int.
if(m_verbose) {
m_out << "tools::rroot::read_class :"
<< " first_int & kByteCountMask."
<< std::endl;
}
uint32 bef_tag = m_pos-m_buffer;
//fVersion = 1;
std::string scls;
if(!read_class_tag(scls)) return false;
if(scls.empty()) {
m_out << "tools::rroot::buffer::read_class :"
<< " read_class_tag did not find a class name."
<< std::endl;
return false;
}
a_class = scls;
a_bcnt = (first_int & ~kByteCountMask());
if(m_verbose) {
m_out << "tools::rroot::read_class :"
<< " kNewClassTag : read class name " << sout(a_class)
<< " a_bcnt " << a_bcnt
<< " bef_tag " << bef_tag
<< "." << std::endl;
}
return true;
} else {
if(m_verbose) {
m_out << "tools::rroot::read_class :"
<< " first_int " << tosx(first_int)
<< ". first_int is position toward object."
<< std::endl;
}
a_bcnt = first_int; //pos toward object.
a_is_ref = true;
a_class.clear();
return true;
}
return false;
}
public:
bool read_object(ifac& a_fac,const ifac::args& a_args,iro*& a_obj){
a_obj = 0;
// before reading object save start position
uint32 startpos = (uint32)(m_pos-m_buffer);
uint32 bcnt;
std::string sclass;
bool is_ref;
if(!read_class(sclass,bcnt,is_ref)) {
m_out << "tools::rroot::buffer::read_object :"
<< " can't read class." << std::endl;
return false;
}
//::printf("debug : %d\n",length()-startpos);
if(m_verbose) {
m_out << "tools::rroot::buffer::read_object :"
<< " class " << sout(sclass)
<< " bcnt " << bcnt
<< std::endl;
}
if(is_ref) {
//bcnt is the position toward an object or an object ref.
//m_out << "tools::rroot::buffer::read_object :"
// << " is_ref : bcnt " << bcnt
// << std::endl;
unsigned int obj_offset = bcnt;
obj_offset -= kMapOffset();
obj_offset -= m_klen;
if(m_map_objs) {
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
if(m_objs.find(obj_offset,a_obj)) return true;
#else
obj_map::const_iterator it = m_objs.find(obj_offset);
if(it!=m_objs.end()) {
a_obj = (*it).second;
//::printf("debug : find : %d %lu\n",obj_offset,a_obj);
//stay at current m_pos ?
return true;
}
#endif
}
{char* old_pos = m_pos;
m_pos = m_buffer + obj_offset;
uint32 first_int;
if(!rbuf::read(first_int)) return false;
if(first_int & kByteCountMask()) {
std::string scls;
if(!read_class_tag(scls)) return false;
if(scls.empty()) {
m_out << "tools::rroot::buffer::read_object :"
<< " read_class_tag did not find a class name."
<< std::endl;
return false;
}
//m_out << "tools::rroot::buffer::read_object :"
// << " is_ref : class " << sout(scls)
// << std::endl;
iro* obj = a_fac.create(scls,a_args);
if(!obj) return false;
if(m_map_objs) {
//must be done before stream()
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
if(!m_objs.insert(obj_offset,obj)) {
m_out << "tools::rroot::buffer::read_object :"
<< " map insert failed."
<< std::endl;
}
#else
m_objs[obj_offset] = obj;
#endif
}
if(!obj->stream(*this)) {
m_out << "tools::rroot::buffer::read_object :"
<< " is_ref : streamed failed for class " << sout(scls)
<< std::endl;
//restore a good buffer position :
//m_pos = m_buffer+startpos+sizeof(unsigned int);
a_fac.destroy(obj);
return false;
}
//m_out << "tools::rroot::buffer::read_object :"
// << " is_ref : streamed ok for class " << sout(scls)
// << std::endl;
a_obj = obj;
} else {
m_out << "tools::rroot::buffer::read_object :"
<< " is_ref : zzz"
<< std::endl;
}
m_pos = old_pos;}
// in principle at this point m_pos should be
// m_buffer+startpos+sizeof(unsigned int)
// but enforce it anyway :
m_pos = m_buffer+startpos+sizeof(unsigned int);
//check_byte_count(startpos,0,sclass) would always be ok.
//a_obj = ???
} else {
if(sclass.empty()) {
//m_out << "tools::rroot::buffer::read_object :"
// << " found empty class name."
// << std::endl;
m_pos = m_buffer+startpos+bcnt+sizeof(unsigned int);
} else {
// Being not a ref, it must NOT be in the map.
// We gain a lot by not doing the below find.
/*
if(m_map_objs) {
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
if(m_objs.find(startpos,a_obj)) return true;
#else
obj_map::const_iterator it = m_objs.find(startpos);
if(it!=m_objs.end()) {
a_obj = (*it).second;
::printf("debug : find xxx : %d %lu\n",startpos,a_obj);
//stay at current m_pos ?
return true;
}
#endif
}
*/
iro* obj = a_fac.create(sclass,a_args);
if(!obj) return false;
if(m_map_objs) {
//must be done before stream()
#ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE
if(!m_objs.insert(startpos,obj)) {
m_out << "tools::rroot::buffer::read_object :"
<< " map insert failed."
<< std::endl;
}
#else
m_objs[startpos] = obj;
#endif
}
//::printf("debug : map : %d %lu\n",startpos,obj);
//NOTE : if class ref, "up there"-startpos = 8.
if(!obj->stream(*this)) {
//restore a good buffer position :
//m_pos = m_buffer+startpos+bcnt+sizeof(unsigned int);
a_fac.destroy(obj);
return false;
}
//NOTE : if obj stream ok, the below line is not needed.
//m_pos = m_buffer+startpos+bcnt+sizeof(unsigned int);
if(!check_byte_count(startpos,bcnt,sclass)) {
m_out << "tools::rroot::buffer::read_object :"
<< " check_byte_count failed "
<< "for object of class "
<< sout(sclass) << "." << std::endl;
a_fac.destroy(obj);
return false;
}
a_obj = obj;
}
}
if(m_verbose) {
m_out << "tools::rroot::buffer::read_object :"
<< " end : "
<< std::endl;
}
return true;
}
public:
bool read_version(short& a_version){
// Read class version from I/O buffer.
// Is read a short or three shorts.
a_version = 0;
short version = 0;
// not interested in byte count
if(!rbuf::read(version)) return false;
// if this is a byte count, then skip next short and read version
if(version & kByteCountVMask()) {
if(!rbuf::read(version)) return false;
if(!rbuf::read(version)) return false;
}
a_version = version;
return true;
}
bool read_version(short& a_version,uint32& a_start_pos,uint32& a_byte_count){
// Read class version from I/O buffer.
// Is read one or three shorts.
a_version = 0;
a_start_pos = 0;
a_byte_count = 0;
short version = 0;
// before reading object save start position
uint32 startpos = (uint32)(m_pos-m_buffer);
// read byte count (older files don't have byte count)
// byte count is packed in two individual shorts, this to be
// backward compatible with old files that have at this location
// only a single short (i.e. the version)
union {
unsigned int cnt;
short vers[2];
} v;
if(m_byte_swap) {
if(!rbuf::read(v.vers[1])) return false;
if(!rbuf::read(v.vers[0])) return false;
} else {
if(!rbuf::read(v.vers[0])) return false;
if(!rbuf::read(v.vers[1])) return false;
}
// no bytecount, backup and read version
uint32 bcnt = 0;
if(v.cnt & kByteCountMask()) {
bcnt = (v.cnt & ~kByteCountMask());
} else {
m_pos -= sizeof(unsigned int);
}
if(!rbuf::read(version)) return false;
//printf("Reading version=%d at pos=%d, bytecount=%d\n",
//version,*startpos,*bcnt);
a_version = version;
a_start_pos = startpos;
a_byte_count = bcnt;
return true;
}
bool check_byte_count(uint32 a_start_pos,
uint32 a_byte_count,
const std::string& a_store_cls){
if(!a_byte_count) return true;
unsigned long len = a_start_pos + a_byte_count + sizeof(unsigned int);
unsigned long diff = m_pos-m_buffer;
if(diff==len) return true;
if(diff<len) {
m_out << "tools::rroot::buffer::check_byte_count :"
<< " object of class " << sout(a_store_cls)
<< " read too few bytes ("
<< long2s(len-diff) << " missing)."
<< std::endl;
}
if(diff>len) {
m_out << "tools::rroot::buffer::check_byte_count :"
<< " object of class " << sout(a_store_cls)
<< " read too many bytes ("
<< long2s(diff-len) << " in excess)." << std::endl;
}
m_out << "tools::rroot::buffer::check_byte_count :"
<< " " << sout(a_store_cls)
<< " streamer not in sync with data on file, fix streamer."
<< std::endl;
m_pos = m_buffer+len;
return false;
}
protected:
bool read_string(char* a_string,uint32 a_max) {
// Read string from I/O buffer. String is read till 0 character is
// found or till max-1 characters are read (i.e. string s has max
// bytes allocated).
int nr = 0;
while (nr < int(a_max-1)) {
char ch;
if(!rbuf::read(ch)) return false;
// stop when 0 read
if(ch == 0) break;
a_string[nr++] = ch;
}
a_string[nr] = 0;
return true;
}
protected:
// buffer objects cannot be copied or assigned
//void checkCount(unsigned int);
//unsigned int checkObject(unsigned int,const IClass*,bool = false);
static std::string sout(const std::string& a_string) {
return std::string("\"")+a_string+"\"";
}
protected:
bool m_byte_swap;
bool m_verbose;
uint32 m_size;
char* m_buffer;
char* m_pos;
uint32 m_klen; //GB
bool m_map_objs;
obj_map m_objs;
};
}}
#endif
@@ -0,0 +1,45 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_cids
#define tools_rroot_cids
#include "../cid"
namespace tools {
namespace rroot {
inline cid base_cid() {return 100;} //must be > cids in ../cids.
inline cid iros_cid() {return base_cid()+0;}
inline cid List_cid() {return base_cid()+1;}
inline cid HashList_cid() {return base_cid()+2;}
inline cid ObjArray_cid() {return base_cid()+3;}
inline cid dummy_cid() {return base_cid()+4;}
inline cid basket_cid() {return base_cid()+5;}
inline cid branch_cid() {return base_cid()+6;}
inline cid branch_element_cid() {return base_cid()+7;}
inline cid tree_item() {return base_cid()+8;}
inline cid graph_cid() {return base_cid()+9;}
inline cid matrix_cid() {return base_cid()+10;}
inline cid leaf_string_cid() {return base_cid()+11;}
inline cid leaf_element_cid() {return base_cid()+12;}
inline cid StreamerInfo_cid() {return base_cid()+13;}
inline cid streamer_element_cid() {return base_cid()+14;}
inline cid stl_vector_string_cid() {return base_cid()+16;}
//base for templates :
inline cid base_leaf_cid() {return base_cid()+20;} //+12=32
//NOTE : leaf<T> = base_leaf_cid()+_cid(T)
inline cid stl_vector_cid() {return base_cid()+33;} //+12=45
inline cid stl_vector_vector_cid() {return base_cid()+46;} //+12=58
}}
#endif
@@ -0,0 +1,64 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_clss
#define tools_rroot_clss
#include <string>
namespace tools {
namespace rroot {
inline const std::string& TH1F_cls(){
static const std::string s_v("TH1F");
return s_v;
}
inline const std::string& TH1D_cls(){
static const std::string s_v("TH1D");
return s_v;
}
inline const std::string& TH2F_cls(){
static const std::string s_v("TH2F");
return s_v;
}
inline const std::string& TH2D_cls(){
static const std::string s_v("TH2D");
return s_v;
}
inline const std::string& TH3D_cls(){
static const std::string s_v("TH3D");
return s_v;
}
inline const std::string& TProfile_cls(){
static const std::string s_v("TProfile");
return s_v;
}
inline const std::string& TProfile2D_cls(){
static const std::string s_v("TProfile2D");
return s_v;
}
inline const std::string& TDirectory_cls(){
static const std::string s_v("TDirectory");
return s_v;
}
inline const std::string& TGeoManager_cls(){
static const std::string s_v("TGeoManager");
return s_v;
}
inline const std::string& TList_cls(){
static const std::string s_v("TList");
return s_v;
}
}}
#endif
@@ -0,0 +1,14 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_date
#define tools_rroot_date
namespace tools {
namespace rroot {
typedef unsigned int date;
}}
#endif
@@ -0,0 +1,199 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_directory
#define tools_rroot_directory
#include "seek"
#include "date"
#include "key"
#include "ifile"
#include "../forit"
#include "../vmanip"
namespace tools {
namespace rroot {
class directory {
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::directory");
return s_v;
}
public:
directory(ifile& a_file)
:m_file(a_file)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_date_C = 0; //.set();
m_date_M = 0; //.set();
m_nbytes_keys = 0;
m_nbytes_name = 0;
m_seek_directory = 0;
m_seek_parent = 0;
m_seek_keys = 0;
}
virtual ~directory(){
clear_keys();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
directory(const directory& a_from):m_file(a_from.m_file){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
directory& operator=(const directory &){return *this;}
public:
ifile& file() {return m_file;}
const std::vector<key*>& keys() const {return m_keys;}
std::vector<key*>& keys() {return m_keys;}
key* find_key(const std::string& a_name) {
if(m_file.verbose()) {
m_file.out() << "tools::rroot::directory::find_key :"
<< " " << sout(a_name) << " ..."
<< std::endl;
}
tools_vforcit(key*,m_keys,it) {
if((*it)->object_name()==a_name) return *it;
}
return 0;
}
key* find_key_from_class(const std::string& a_class) {
if(m_file.verbose()) {
m_file.out() << "tools::rroot::directory::find_key_from_class :"
<< " " << sout(a_class) << " ..."
<< std::endl;
}
tools_vforcit(key*,m_keys,it) {
if((*it)->object_class()==a_class) return *it;
}
return 0;
}
uint32 nbytes_name() const {return m_nbytes_name;}
seek seek_keys() const {return m_seek_keys;}
uint32 record_size(uint32 a_version) const {
uint32 nbytes = sizeof(short);
nbytes += sizeof(date); //m_date_C.record_size();
nbytes += sizeof(date); //m_date_M.record_size();
nbytes += sizeof(m_nbytes_keys);
nbytes += sizeof(m_nbytes_name);
if(a_version>=40000) {
nbytes += sizeof(seek);
nbytes += sizeof(seek);
nbytes += sizeof(seek);
} else {
nbytes += sizeof(seek32);
nbytes += sizeof(seek32);
nbytes += sizeof(seek32);
}
return nbytes;
}
bool from_buffer(const char* aEOB,char*& a_buffer){
// Decode input buffer.
// (Name, title) are stored in the (name, title) of the associated key.
rbuf rb(m_file.out(),m_file.byte_swap(),aEOB,a_buffer);
short versiondir;
if(!rb.read(versiondir)) return false;
unsigned int _date;
if(!rb.read(_date)) return false;
//fDateC.setDate(_date);
if(!rb.read(_date)) return false;
//fDateM.setDate(_date);
{int v;
if(!rb.read(v)) return false;
m_nbytes_keys = v;}
{int v;
if(!rb.read(v)) return false;
m_nbytes_name = v;}
if(versiondir>1000) {
if(!rb.read(m_seek_directory)) return false;
if(!rb.read(m_seek_parent)) return false;
if(!rb.read(m_seek_keys)) return false;
} else {
{seek32 i;
if(!rb.read(i)) return false;
m_seek_directory = i;}
{seek32 i;
if(!rb.read(i)) return false;
m_seek_parent = i;}
{seek32 i;
if(!rb.read(i)) return false;
m_seek_keys = i;}
}
if(m_file.verbose()) {
m_file.out() << "tools::rroot::key::from_buffer :"
<< " nbytes keys : " << m_nbytes_keys
<< ", pos keys : " << m_seek_keys
<< std::endl;
}
return true;
}
bool read_keys(uint32& a_number) {
// Read the KEYS :
// Every directory has a list (fKeys). This list has been
// written on the file via CERN-ROOT::TDirectory::writeKeys
// as a single data record.
a_number = 0;
clear_keys();
key headerkey(m_file,m_seek_keys,m_nbytes_keys);
if(!headerkey.read_file()) return false;
char* buffer = headerkey.data_buffer();
if(!headerkey.from_buffer(headerkey.eob(),buffer)) return false;
int nkeys = 0;
rbuf rb(m_file.out(),m_file.byte_swap(),headerkey.eob(),buffer);
if(!rb.read(nkeys)) return false;
if(m_file.verbose()) {
m_file.out() << "tools::rroot::directory::read_keys :"
<< " nkeys " << nkeys
<< "."
<< std::endl;
}
for(int i=0;i<nkeys;i++) {
key* k = new key(m_file);
if(!k->from_buffer(headerkey.eob(),buffer)) {
delete k;
return false;
}
m_keys.push_back(k);
}
a_number = nkeys;
return true;
}
void clear_keys() {
clear<key>(m_keys);
}
protected:
static std::string sout(const std::string& a_string) {
return std::string("\"")+a_string+"\"";
}
protected:
ifile& m_file;
std::vector<key*> m_keys;
// Record (stored in file):
date m_date_C; //Date and time when directory is created
date m_date_M; //Date and time of last modification
uint32 m_nbytes_keys; //Number of bytes for the keys
uint32 m_nbytes_name; //Number of bytes in TNamed at creation time
seek m_seek_directory; //Location of directory on file
seek m_seek_parent; //Location of parent directory on file
seek m_seek_keys; //Location of Keys record on file
};
}}
#endif
@@ -0,0 +1,74 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_dummy
#define tools_rroot_dummy
// dummy class with a generic streamer.
// It is used within the reading of a tree
// to create some generic object when we get
// from the file a class name which is unknown
// from the tree factory.
#include "iro"
#include "buffer"
#include "../scast"
#include "cids"
namespace tools {
namespace rroot {
class dummy : public virtual iro {
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::dummy");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<dummy>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return dummy_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<dummy>(this,a_class)) {return p;}
return 0;
}
public:
virtual iro* copy() const {return new dummy(*this);}
virtual bool stream(buffer& a_buffer) {
//the below code skips correctly the data in the file.
uint32 startpos = a_buffer.length();
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
a_buffer.set_offset(startpos+c+sizeof(unsigned int));
if(!a_buffer.check_byte_count(s,c,"dummy")) return false;
return true;
}
public:
dummy(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~dummy(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
dummy(const dummy& a_from): iro(a_from){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
dummy& operator=(const dummy&){return *this;}
};
}}
#endif
@@ -0,0 +1,152 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_fac
#define tools_rroot_fac
#include "../sout"
#include "branch_element"
#include "leaf"
#include "basket"
#include "tree_index"
#include "stl_vector"
#include "dummy"
namespace tools {
namespace rroot {
class fac : public virtual ifac {
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::fac");
return s_v;
}
public: //ifac
virtual iro* create(const std::string& a_class,const args& a_args) {
//m_file.out() << "tools::rroot::fac::create :"
// << " create object of class " << a_class << "..."
// << std::endl;
if(a_class=="TBranch") {
return new branch(m_file,*this);
} else if(a_class=="TBranchElement") {
return new branch_element(m_file,*this);
} else if(a_class=="TLeafB") {
branch* b = arg_branch(a_args);
if(!b) return 0;
return new leaf<char>(m_file.out(),*b,*this);
} else if(a_class=="TLeafS") {
branch* b = arg_branch(a_args);
if(!b) return 0;
return new leaf<short>(m_file.out(),*b,*this);
} else if(a_class=="TLeafI") {
branch* b = arg_branch(a_args);
if(!b) return 0;
return new leaf<int>(m_file.out(),*b,*this);
} else if(a_class=="TLeafF") {
branch* b = arg_branch(a_args);
if(!b) return 0;
return new leaf<float>(m_file.out(),*b,*this);
} else if(a_class=="TLeafD") {
branch* b = arg_branch(a_args);
if(!b) return 0;
return new leaf<double>(m_file.out(),*b,*this);
} else if(a_class=="TLeafO") {
branch* b = arg_branch(a_args);
if(!b) return 0;
return new leaf<bool>(m_file.out(),*b,*this);
} else if(a_class=="TLeafC") {
branch* b = arg_branch(a_args);
if(!b) return 0;
return new leaf_string(m_file.out(),*b,*this);
} else if(a_class=="TLeafElement") {
branch* b = arg_branch(a_args);
if(!b) return 0;
return new leaf_element(m_file.out(),*b,*this);
} else if(a_class=="TBasket") {
return new basket(m_file);
// L.Duflot ATLAS file :
} else if(a_class=="TTreeIndex") {
return new tree_index();
} else if(a_class=="TList") {
return new List(*this,true);
} else if(a_class=="vector<unsigned short>") {
return new stl_vector<unsigned short>();
} else if(a_class=="vector<short>") {
return new stl_vector<short>();
} else if(a_class=="vector<unsigned int>") {
return new stl_vector<unsigned int>();
} else if(a_class=="vector<int>") {
return new stl_vector<int>();
} else if(a_class=="vector<float>") {
return new stl_vector<float>();
} else if(a_class=="vector<double>") {
return new stl_vector<double>();
} else if(a_class=="vector<unsigned long>") { //beurk
return new stl_vector<uint64>(); //is it ok to map to an uint64 ?
} else if(a_class=="vector<string>") {
return new stl_vector_string();
} else if(a_class=="vector<vector<unsigned short> >") {
return new stl_vector_vector<unsigned short>();
} else if(a_class=="vector<vector<short> >") {
return new stl_vector_vector<short>();
} else if(a_class=="vector<vector<unsigned int> >") {
return new stl_vector_vector<unsigned int>();
} else if(a_class=="vector<vector<int> >") {
return new stl_vector_vector<int>();
} else if(a_class=="vector<vector<float> >") {
return new stl_vector_vector<float>();
} else if(a_class=="vector<vector<double> >") {
return new stl_vector_vector<double>();
} else if(a_class=="TBranchRef") {
return new dummy();
} else {
m_file.out() << "tools::rroot::fac::create :"
<< " unknown class " << sout(a_class) << "."
<< " Create a tools::rroot::dummy object."
<< std::endl;
return new dummy();
}
}
virtual void destroy(iro*& a_obj) {delete a_obj;a_obj = 0;}
public:
fac(ifile& a_file):m_file(a_file){}
virtual ~fac(){}
public:
fac(const fac& a_from): ifac(a_from),m_file(a_from.m_file){}
fac& operator=(const fac&){return *this;}
protected:
branch* arg_branch(const args& a_args) {
void* p = ifac::find_args(a_args,ifac::arg_branch());
if(!p) {
m_file.out() << "tools::rroot::fac::arg_branch :"
<< " branch not found in args."
<< std::endl;
return 0;
}
return (branch*)p;
}
protected:
ifile& m_file;
};
}}
#endif
@@ -0,0 +1,505 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_file
#define tools_rroot_file
#include "ifile"
#include "directory"
#include "../platform"
#include <string>
#include <fcntl.h>
#include <errno.h>
#ifdef WIN32
#include <io.h>
#include <sys/stat.h>
// disable the warning about the usage of "this" in the constructor.
#pragma warning(disable:4355)
#else
#include <unistd.h>
#endif
namespace tools {
namespace rroot {
class file : public virtual ifile {
static int not_open() {return -1;}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::file");
return s_v;
}
public: //ifile
virtual const std::string& path() const {return m_path;}
virtual std::string path() {return m_path;}
virtual bool verbose() const {return m_verbose;}
virtual std::ostream& out() {return m_out;}
virtual bool byte_swap() const {return is_little_endian();}
virtual bool set_pos(seek a_offset = 0,from a_from = begin){
int whence = 0;
switch(a_from) {
case begin:
whence = SEEK_SET;
break;
case current:
whence = SEEK_CUR;
break;
case end:
whence = SEEK_END;
break;
}
#if defined(__linux__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2)
if (::lseek64(m_file, a_offset, whence) < 0) {
#elif defined(WIN32)
if (::_lseeki64(m_file, a_offset, whence) < 0) {
#else
if (::lseek(m_file, a_offset, whence) < 0) {
#endif
m_out << "tools::rroot::file::set_pos :"
<< " cannot set position " << a_offset
<< " in file " << sout(m_path) << "."
<< std::endl;
return false;
}
return true;
}
virtual bool read_buffer(char* a_buffer,uint32 a_length) {
// Read a buffer from the file.
// This is the basic low level read operation.
#ifdef WIN32
typedef int ssize_t;
#endif
ssize_t siz;
while ((siz = ::read(m_file,a_buffer,a_length)) < 0 &&
error_number() == EINTR) reset_error_number();
if (siz < 0) {
m_out << "tools::rroot::file::read_buffer :"
<< " error reading from file " << sout(m_path) << "."
<< std::endl;
return false;
}
if (siz != ssize_t(a_length)) {
m_out << "tools::rroot::file::read_buffer :"
<< " error reading all requested bytes from file "
<< sout(m_path) << ", got " << long2s(siz)
<< " of " << a_length
<< std::endl;
return false;
}
m_bytes_read += siz;
return true;
}
virtual bool unziper(char a_key,unzip_func& a_func) const {
std::map<char,unzip_func>::const_iterator it = m_unzipers.find(a_key);
if(it==m_unzipers.end()) {
a_func = 0;
return false;
}
a_func = (*it).second;
return true;
}
virtual key& sinfos_key() {return m_streamer_info_key;}
public:
file(std::ostream& a_out,const std::string& a_path,bool a_verbose = false)
:m_out(a_out)
,m_path(a_path)
,m_verbose(a_verbose)
,m_file(not_open())
,m_bytes_read(0)
,m_root_directory(*this)
,m_streamer_info_key(*this)
// begin of record :
,m_version(0)
,m_BEGIN(0)
,m_END(0)
,m_seek_free(0)
,m_seek_info(0)
,m_nbytes_free(0)
,m_nbytes_info(0)
,m_nbytes_name(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_file = _open(a_path.c_str(),
#ifdef WIN32
O_RDONLY | O_BINARY,S_IREAD | S_IWRITE
#else
O_RDONLY,0644
#endif
);
if(m_file==not_open()) {
m_out << "tools::rroot::file::file :"
<< " can't open " << sout(a_path) << "."
<< std::endl;
return;
}
initialize();
}
virtual ~file() {
close();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
file(const file& a_from)
:ifile(a_from)
,m_out(a_from.m_out)
,m_root_directory(*this)
,m_streamer_info_key(*this)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
file& operator=(const file&){return *this;}
public:
uint32 version() const {return m_version;}
bool is_open() const {
return (m_file==not_open()?false:true);
}
void close() {
if(m_file!=not_open()) ::close(m_file);
m_file = not_open();
m_root_directory.clear_keys();
}
directory& dir() {return m_root_directory;}
const directory& dir() const {return m_root_directory;}
bool add_unziper(char a_key,unzip_func a_func){
std::map<char,unzip_func>::const_iterator it = m_unzipers.find(a_key);
if(it!=m_unzipers.end()) {
//(*it).second = a_func; //override ?
return false;
} else {
m_unzipers[a_key] = a_func;
return true;
}
}
protected:
static int _open(const char* a_name,int a_flags,uint32 a_mode) {
#if defined(__linux__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2)
return ::open64(a_name,a_flags,a_mode);
#else
return ::open(a_name,a_flags,a_mode);
#endif
}
static std::string sout(const std::string& a_string) {
return std::string("\"")+a_string+"\"";
}
bool initialize() {
if(!read_header()) {
m_out << "tools::rroot::file::initialize :"
<< " can't read header."
<< std::endl;
return false;
}
/*
fRootDirectory->setSeekDirectory(fBEGIN);
// Read Free segments structure if file is writable :
if (fWritable) {
if (fSeekFree > fBEGIN) {
if(!readFreeSegments()) {
m_out << "tools::rroot::file::initialize : Cannot read free segments."
<< std::endl;
return false;
}
} else {
m_out << "tools::rroot::file::initialize : file \"" << fName
<< "\" probably not closed, cannot read free segments" << std::endl;
}
}
*/
// Read Directory info :
uint32 nbytes = m_nbytes_name + m_root_directory.record_size(m_version);
char* header = new char[nbytes];
char* buffer = header;
if(!set_pos(m_BEGIN)) {
m_out << "tools::rroot::file::initialize :"
<< " can't set position."
<< std::endl;
delete [] header;
return false;
}
if(!read_buffer(buffer,nbytes)) {
m_out << "tools::rroot::file::initialize :"
<< " can't read buffer."
<< std::endl;
delete [] header;
return false;
}
buffer = header+m_nbytes_name;
const char* eob = header+nbytes;
if(!m_root_directory.from_buffer(eob,buffer)) {
m_out << "tools::rroot::file::initialize :"
<< " can't read buffer (2)."
<< std::endl;
delete [] header;
return false;
}
uint32 nk = //size of Key
sizeof(int) + //Key::fNumberOfBytes
sizeof(short) + //Key::fVersion
2*sizeof(int) + //Key::fObjectSize, Date
2*sizeof(short) + //Key::fKeyLength,fCycle
2*sizeof(seek32); //Key::fSeekKey,fSeekParentDirectory
//WARNING : the upper is seek32 since at begin of file.
buffer = header+nk;
std::string cname;
rbuf rb(m_out,byte_swap(),eob,buffer);
// Should be "TFile".
if(!rb.read(cname)) {
m_out << "tools::rroot::file::initialize :"
<< " can't read buffer (3)."
<< std::endl;
delete [] header;
return false;
}
if(cname!="TFile") {
m_out << "tools::rroot::file::initialize : TFile expected." << std::endl;
delete [] header;
return false;
}
if(m_verbose) {
m_out << "tools::rroot::file::initialize :"
<< " " << sout("TFile") << " found."
<< std::endl;
}
if(!rb.read(cname)) {
m_out << "tools::rroot::file::initialize :"
<< " can't read buffer (4)."
<< std::endl;
delete [] header;
return false;
}
if(m_verbose) {
m_out << "tools::rroot::file::initialize :"
<< " found file name " << sout(cname)
<< std::endl;
}
if(!rb.read(m_title)) {
m_out << "tools::rroot::file::initialize :"
<< " can't read buffer (5)."
<< std::endl;
delete [] header;
return false;
}
delete [] header;
if(m_verbose) {
m_out << "tools::rroot::file::initialize :"
<< " found title " << sout(m_title)
<< std::endl;
}
uint32 dirNbytesName = m_root_directory.nbytes_name();
if (dirNbytesName < 10 || dirNbytesName > 1000) {
m_out << "tools::rroot::file::initialize :"
<< " can't read directory info."
<< std::endl;
return false;
}
// Read keys of the top directory :
if(m_root_directory.seek_keys() > m_BEGIN) {
uint32 n;
if(!m_root_directory.read_keys(n)) {
m_out << "tools::rroot::file::initialize :"
<< " can't read keys."
<< std::endl;
return false;
}
} else {
m_out << "tools::rroot::file::initialize :"
<< " file " << sout(m_path)
<< " probably not closed."
<< std::endl;
return false;
}
// Create StreamerInfo index
if(m_seek_info > m_BEGIN) {
if(!read_streamer_infos()) {
m_out << "tools::rroot::file::initialize :"
<< " read_streamer_infos() failed."
<< std::endl;
return false;
}
} else {
m_out << "tools::rroot::file::initialize :"
<< " file " << sout(m_path)
<< " probably not closed."
<< std::endl;
return false;
}
return true;
}
bool read_header() {
static const uint32 kBegin = 64;
char header[kBegin];
if(!set_pos()) return false;
if(!read_buffer(header,kBegin)) return false;
// make sure this is a root file
if(::strncmp(header, "root", 4)) {
m_out << "tools::rroot::file::read_header :"
<< " " << sout(m_path) << " not a ROOT file."
<< std::endl;
return false;
}
if(m_verbose) {
m_out << "tools::rroot::file::read_header :"
<< " file signature is " << sout("root")
<< std::endl;
}
char* buffer = header + 4; // skip the "root" file identifier
const char* eob = header + kBegin;
rbuf rb(m_out,byte_swap(),eob,buffer);
{int v;
if(!rb.read(v)) return false;
m_version = v;}
{seek32 i;
if(!rb.read(i)) return false;
m_BEGIN = i;}
if(m_version>1000000) {
if(!rb.read(m_END)) return false;
if(!rb.read(m_seek_free)) return false;
} else {
{seek32 i;
if(!rb.read(i)) return false;
m_END = i;}
{seek32 i;
if(!rb.read(i)) return false;
m_seek_free = i;}
}
if(m_verbose) {
m_out << "tools::rroot::file::read_header :"
<< " begin " << m_BEGIN
<< " end " << m_END
<< std::endl;
}
{int v;
if(!rb.read(v)) return false;
m_nbytes_free = v;}
int nfree = 0;
if(!rb.read(nfree)) return false;
{int v;
if(!rb.read(v)) return false;
m_nbytes_name = v;}
//m_out << "debug : 1002 " << m_nbytes_name << std::endl;
{char fUnits;
if(!rb.read(fUnits)) return false;}
{int fCompress;
if(!rb.read(fCompress)) return false;}
if(m_version>1000000) {
if(!rb.read(m_seek_info)) return false;
} else {
{seek32 i;
if(!rb.read(i)) return false;
m_seek_info = i;}
}
if(!rb.read(m_nbytes_info)) return false;
//m_out << "debug : seek_info " << m_seek_info << " nbytes_info " << m_nbytes_info << std::endl;
return true;
}
bool read_streamer_infos() {
// Read the list of StreamerInfo from this file
// The key with name holding the list of TStreamerInfo objects is read.
// The corresponding TClass objects are updated.
if(m_seek_info<=0) return false;
if(m_seek_info>=m_END) return false;
if(!set_pos(m_seek_info)) return false;
char* buffer = new char[m_nbytes_info+1];
if(!read_buffer(buffer,m_nbytes_info)) {delete [] buffer;return false;}
char* buf = buffer;
if(!m_streamer_info_key.from_buffer(buffer+m_nbytes_info,buf)) {
delete [] buffer;
return false;
}
delete [] buffer;
return true;
}
#if defined(__sun) && !defined(__linux__) && (__SUNPRO_CC > 0x420)
int error_number() {return ::errno;}
void reset_error_number() {::errno = 0;}
#else
int error_number() {return errno;}
void reset_error_number() {errno = 0;}
#endif
protected:
std::ostream& m_out;
std::string m_path;
bool m_verbose;
int m_file;
tools::uint64 m_bytes_read; //Number of bytes read from this file
directory m_root_directory;
key m_streamer_info_key;
std::map<char,unzip_func> m_unzipers;
std::string m_title;
// begin of record :
uint32 m_version; //File format version
seek m_BEGIN; //First used byte in file
seek m_END; //Last used byte in file
seek m_seek_free; //Location on disk of free segments structure
seek m_seek_info; //Location on disk of StreamerInfo record
uint32 m_nbytes_free; //Number of bytes for free segments structure
uint32 m_nbytes_info; //Number of bytes for StreamerInfo record
//int nfree
uint32 m_nbytes_name; //Number of bytes in TNamed at creation time
};
}}
#endif
//doc
//
// A ROOT file is a suite of consecutive data records with the following
// format (see also the TKey class);
// TKey ---------------------
// byte 1->4 Nbytes = Length of compressed object (in bytes)
// 5->6 Version = TKey version identifier
// 7->10 ObjLen = Length of uncompressed object
// 11->14 Datime = Date and time when object was written to file
// 15->16 KeyLen = Length of the key structure (in bytes)
// 17->18 Cycle = Cycle of key
// 19->22 SeekKey = Pointer to record itself (consistency check)
// 23->26 SeekPdir = Pointer to directory header
// 27->27 lname = Number of bytes in the class name
// 28->.. ClassName = Object Class Name
// ..->.. lname = Number of bytes in the object name
// ..->.. Name = lName bytes with the name of the object
// ..->.. lTitle = Number of bytes in the object title
// ..->.. Title = Title of the object
// -----> DATA = Data bytes associated to the object
//
// The first data record starts at byte fBEGIN (currently set to kBegin)
// Bytes 1->kBegin contain the file description:
// byte 1->4 "root" = Root file identifier
// 5->8 fVersion = File format version
// 9->12 fBEGIN = Pointer to first data record
// 13->16 fEND = Pointer to first free word at the EOF
// 17->20 fSeekFree = Pointer to FREE data record
// 21->24 fNbytesFree = Number of bytes in FREE data record
// 25->28 nfree = Number of free data records
// 29->32 fNbytesName = Number of bytes in TNamed at creation time
// 33->33 fUnits = Number of bytes for file pointers
// 34->37 fCompress = Zip compression level
//
@@ -0,0 +1,66 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_graph
#define tools_rroot_graph
#include "../scast"
#include "buffer"
#include "cids"
namespace tools {
namespace rroot {
class graph : public virtual iro {
static const std::string& s_store_class() {
static const std::string s_v("TGraph");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::graph");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<graph>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return graph_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<graph>(this,a_class)) {return p;}
else return 0;
}
public:
virtual iro* copy() const {return new graph(*this);}
virtual bool stream(buffer& a_buffer) {
uint32 startpos = a_buffer.length();
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
a_buffer.set_offset(startpos+c+sizeof(unsigned int));
if(!a_buffer.check_byte_count(s,c,s_store_class())) return false;
return true;
}
public:
graph(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~graph(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
graph(const graph& a_from): iro(a_from){}
graph& operator=(const graph&){return *this;}
};
}}
#endif
@@ -0,0 +1,44 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_ifac
#define tools_rroot_ifac
#include <string>
#include <map>
namespace tools {
namespace rroot {
class iro;
}}
namespace tools {
namespace rroot {
class ifac {
public:
typedef std::map<char,void*> args;
public:
virtual ~ifac(){}
public:
virtual iro* create(const std::string& a_class,const args&) = 0;
virtual void destroy(iro*&) = 0;
public:
static void* find_args(const args& a_args,char a_key) {
std::map<char,void*>::const_iterator it = a_args.find(a_key);
if(it==a_args.end()) return 0;
return (*it).second;
}
static char arg_branch() {return 'B';}
static char arg_class() {return 'C';}
static std::string* arg_class(const args& a_args) {
void* p = ifac::find_args(a_args,ifac::arg_class());
if(!p) return 0;
return (std::string*)p;
}
};
}}
#endif
@@ -0,0 +1,40 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_ifile
#define tools_rroot_ifile
#include "seek"
#include "../zfunc"
namespace tools {
namespace rroot {
class key;
class ifile {
public:
virtual ~ifile(){}
public:
virtual const std::string& path() const = 0;
virtual std::string path() = 0;
virtual bool verbose() const = 0;
virtual std::ostream& out() = 0;
virtual bool byte_swap() const = 0;
enum from {
begin,
current,
end
};
virtual bool set_pos(seek = 0,from = begin) = 0;
virtual bool read_buffer(char*,uint32) = 0;
virtual bool unziper(char,unzip_func&) const = 0;
virtual key& sinfos_key() = 0;
};
}}
#endif
@@ -0,0 +1,258 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_info
#define tools_rroot_info
//#include "buffer"
//#include "element"
#include "named"
namespace tools {
namespace rroot {
class streamer_element : public virtual iro {
static const std::string& s_store_class() {
static const std::string s_v("TStreamerElement");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::streamer_element");
return s_v;
}
static cid id_class() {return streamer_element_cid();}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<streamer_element>(this,a_class)) return p;
return 0;
}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<streamer_element>(this,a_class)) {return p;}
else return 0;
}
virtual const std::string& s_cls() const {return s_class();}
virtual iro* copy() const {return new streamer_element(*this);}
virtual bool stream(buffer& a_buffer) {
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!Named_stream(a_buffer,fName,fTitle)) return false;
if(!a_buffer.read(fType)) return false;
if(!a_buffer.read(fSize)) return false;
if(!a_buffer.read(fArrayLength)) return false;
if(!a_buffer.read(fArrayDim)) return false;
if(!a_buffer.read_fast_array<int>(fMaxIndex,5)) return false;
if(!a_buffer.read(fTypeName)) return false;
return a_buffer.check_byte_count(s,c,s_store_class());
}
public:
virtual void out(std::ostream& aOut) const {
char s[128];
snpf(s,sizeof(s)," %-14s%-15s offset=%3d type=%2d %-20s",
fTypeName.c_str(),fullName().c_str(),fOffset,fType,fTitle.c_str());
aOut << s << std::endl;
}
public:
streamer_element()
:fName(),fTitle(),fType(-1)
,fSize(0),fArrayLength(0),fArrayDim(0),fOffset(0)
,fTypeName(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
for(int i=0;i<5;i++) fMaxIndex[i] = 0;
}
virtual ~streamer_element(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
streamer_element(const streamer_element& a_from)
:iro(a_from)
,fName(a_from.fName),fTitle(a_from.fTitle)
,fType(a_from.fType),fSize(a_from.fSize)
,fArrayLength(a_from.fArrayLength)
,fArrayDim(a_from.fArrayDim),fOffset(a_from.fOffset)
,fTypeName(a_from.fTypeName){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
for(int i=0;i<5;i++) fMaxIndex[i] = a_from.fMaxIndex[i];
}
streamer_element& operator=(const streamer_element& a_from){
fName = a_from.fName;
fTitle = a_from.fTitle;
fType = a_from.fType;
fSize = a_from.fSize;
fArrayLength = a_from.fArrayLength;
fArrayDim = a_from.fArrayDim;
fOffset = a_from.fOffset;
fTypeName = a_from.fTypeName;
for(int i=0;i<5;i++) fMaxIndex[i] = a_from.fMaxIndex[i];
return *this;
}
public:
virtual std::string fullName() const {
std::string s = fName;
for (int i=0;i<fArrayDim;i++) {
char cdim[32];
snpf(cdim,sizeof(cdim),"[%d]",fMaxIndex[i]);
s += cdim;
}
return s;
}
protected: //Named
std::string fName;
std::string fTitle;
protected:
int fType; //element type
int fSize; //sizeof element
int fArrayLength; //cumulative size of all array dims
int fArrayDim; //number of array dimensions
int fMaxIndex[5]; //Maximum array index for array dimension "dim"
int fOffset; //!element offset in class
//FIXME Int_t fNewType; //!new element type when reading
std::string fTypeName; //Data type name of data member
};
class dummy_streamer_element : public streamer_element {
typedef streamer_element parent;
public: //iro
virtual iro* copy() const {return new dummy_streamer_element(*this);}
virtual bool stream(buffer& a_buffer) {
//the below code skips correctly the data in the file.
uint32 startpos = a_buffer.length();
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!parent::stream(a_buffer)) return false;
a_buffer.set_offset(startpos+c+sizeof(unsigned int));
if(!a_buffer.check_byte_count(s,c,"dummy_streamer_element")) return false;
return true;
}
public:
dummy_streamer_element(){}
virtual ~dummy_streamer_element(){}
protected:
dummy_streamer_element(const dummy_streamer_element& a_from):iro(a_from),parent(a_from){}
dummy_streamer_element& operator=(const dummy_streamer_element& a_from){
parent::operator=(a_from);
return *this;
}
};
class StreamerInfo : public virtual iro {
static const std::string& s_store_class() {
static const std::string s_v("TStreamerInfo");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::StreamerInfo");
return s_v;
}
static cid id_class() {return StreamerInfo_cid();}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<StreamerInfo>(this,a_class)) return p;
return 0;
}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<StreamerInfo>(this,a_class)) {return p;}
else return 0;
}
virtual const std::string& s_cls() const {return s_class();}
virtual iro* copy() const {return new StreamerInfo(*this);}
virtual bool stream(buffer& a_buffer) {
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!Named_stream(a_buffer,m_name,m_title)) return false;
if(!a_buffer.read(m_check_sum)) return false;
if(!a_buffer.read(m_streamed_class_version)) return false;
//TObjArray *fElements; //Array of TStreamerElements
{ObjArray<streamer_element>* obj;
ifac::args args;
args[ifac::arg_class()] = (void*)&(streamer_element::s_class());
if(!pointer_stream(a_buffer,m_fac,args,obj)) {
a_buffer.out() << "tools::rroot::StreamerInfo::stream : "
<< "can't read fElements."
<< std::endl;
return false;
}
m_elements.operator=(*obj);
delete obj;}
return a_buffer.check_byte_count(s,c,s_store_class());
}
public:
void out(std::ostream& a_out) const {
a_out << "StreamerInfo for class :"
<< " " << m_name << ", version=" << m_streamed_class_version
<< std::endl;
tools_vforcit(streamer_element*,m_elements,it) (*it)->out(a_out);
}
public:
StreamerInfo(ifac& a_fac)
:m_fac(a_fac)
,m_name()
,m_title()
,m_check_sum(0)
,m_streamed_class_version(0)
,m_elements(a_fac,true)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~StreamerInfo(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
StreamerInfo(const StreamerInfo& a_from)
:iro(a_from)
,m_fac(a_from.m_fac)
,m_name(a_from.m_name)
,m_title(a_from.m_name)
,m_check_sum(a_from.m_check_sum)
,m_streamed_class_version(a_from.m_streamed_class_version)
,m_elements(a_from.m_elements)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
StreamerInfo& operator=(const StreamerInfo& a_from){
m_name = a_from.m_name;
m_title = a_from.m_name;
m_check_sum = a_from.m_check_sum;
m_streamed_class_version = a_from.m_streamed_class_version;
m_elements = a_from.m_elements;
return *this;
}
public:
protected:
ifac& m_fac;
protected: //Named
std::string m_name;
std::string m_title;
protected:
unsigned int m_check_sum; //checksum of original class
int m_streamed_class_version; //Class version identifier
//int fNumber; //!Unique identifier
ObjArray<streamer_element> m_elements; //Array of TStreamerElements
};
}}
#endif
@@ -0,0 +1,34 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_iro
#define tools_rroot_iro
#include <string>
namespace tools {
namespace rroot {
class buffer;
}}
#include "../cid"
namespace tools {
namespace rroot {
class iro {
public:
virtual ~iro(){}
public:
virtual void* cast(const std::string&) const = 0; //for ObjArray
virtual bool stream(buffer&) = 0;
virtual const std::string& s_cls() const = 0;
virtual iro* copy() const = 0;
virtual void* cast(cid) const = 0; //OPTIMIZATION (geo).
};
}}
#endif
@@ -0,0 +1,615 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_key
#define tools_rroot_key
#include "rbuf"
#include "seek"
#include "date"
#include "ifile"
#ifdef TOOLS_MEM
#include "../mem"
#endif
#include <map>
#include <ostream>
#include <cstring> //memcpy
//#include <zlib.h>
//FIXME : arrange to have csz coming from the "outside" (as zip).
extern "C" {
void csz__Init_Inflate(long,unsigned char*,long,unsigned char*);
int csz__Inflate();
unsigned char* csz__obufptr();
}
namespace tools {
namespace rroot {
class key {
static uint32 class_version() {return 2;}
public:
static uint32 std_string_record_size(const std::string& x) {
// Returns size string will occupy on I/O buffer.
if (x.size() > 254)
return x.size()+sizeof(unsigned char)+sizeof(int);
else
return x.size()+sizeof(unsigned char);
}
public:
key(ifile& a_file)
:m_file(a_file)
,m_buf_size(0)
,m_buffer(0)
// Record :
,m_nbytes(0)
,m_version(class_version())
,m_object_size(0)
,m_date(0)
,m_key_length(0)
,m_cycle(0)
,m_seek_key(0)
,m_seek_parent_dir(0)
//,m_object_class
//,m_object_name
//,m_object_title
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_key_length = record_size(m_version);
//fDate.setDate(0);
}
key(ifile& a_file,seek a_pos,uint32 a_nbytes)
:m_file(a_file)
,m_buf_size(0)
,m_buffer(0)
// Record :
,m_nbytes(a_nbytes) //key len + compressed object size
,m_version(class_version())
,m_object_size(0)
,m_date(0)
,m_key_length(0)
,m_cycle(0)
,m_seek_key(a_pos)
,m_seek_parent_dir(0)
//,m_object_class
//,m_object_name
//,m_object_title
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
if(a_pos>START_BIG_FILE) m_version += 1000;
m_buffer = new char[a_nbytes];
if(!m_buffer) {
m_file.out() << "tools::rroot::key::key(cpcstor) :"
<< " can't alloc " << a_nbytes << "."
<< std::endl;
} else {
m_buf_size = a_nbytes;
}
}
virtual ~key(){
delete [] m_buffer;
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
key(const key& a_from)
:m_file(a_from.m_file)
,m_buf_size(0)
,m_buffer(0)
,m_nbytes(a_from.m_nbytes)
,m_version(a_from.m_version)
,m_object_size(a_from.m_object_size)
,m_date(a_from.m_date)
,m_key_length(a_from.m_key_length)
,m_cycle(a_from.m_cycle)
,m_seek_key(a_from.m_seek_key)
,m_seek_parent_dir(a_from.m_seek_parent_dir)
,m_object_class(a_from.m_object_class)
,m_object_name(a_from.m_object_name)
,m_object_title(a_from.m_object_title)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
if(a_from.m_buf_size && a_from.m_buffer) {
m_buffer = new char[a_from.m_buf_size];
if(!m_buffer) {
m_file.out() << "tools::rroot::key::key(cpcstor) :"
<< " can't alloc " << a_from.m_buf_size << "."
<< std::endl;
} else {
m_buf_size = a_from.m_buf_size;
::memcpy(m_buffer,a_from.m_buffer,a_from.m_buf_size);
}
}
}
public:
key& operator=(const key& a_from){
if(&a_from==this) return *this;
m_nbytes = a_from.m_nbytes;
m_version = a_from.m_version;
m_object_size = a_from.m_object_size;
m_date = a_from.m_date;
m_key_length = a_from.m_key_length;
m_cycle = a_from.m_cycle;
m_seek_key = a_from.m_seek_key;
m_seek_parent_dir = a_from.m_seek_parent_dir;
m_object_class = a_from.m_object_class;
m_object_name = a_from.m_object_name;
m_object_title = a_from.m_object_title;
delete [] m_buffer;
m_buffer = 0;
m_buf_size = 0;
if(a_from.m_buf_size && a_from.m_buffer) {
m_buffer = new char[a_from.m_buf_size];
if(!m_buffer) {
m_file.out() << "tools::rroot::key::operator=() :"
<< " can't alloc " << a_from.m_buf_size << "."
<< std::endl;
} else {
m_buf_size = a_from.m_buf_size;
::memcpy(m_buffer,a_from.m_buffer,a_from.m_buf_size);
}
}
return *this;
}
public:
ifile& file() {return m_file;}
uint32 nbytes() const {return m_nbytes;}
seek seek_key() const {return m_seek_key;}
uint32 object_size() const {return m_object_size;}
const std::string& object_name() const {return m_object_name;}
std::string object_name() {return m_object_name;}
const std::string& object_title() const {return m_object_title;}
std::string object_title() {return m_object_title;}
const std::string& object_class() const {return m_object_class;}
std::string object_class() {return m_object_class;}
bool read_file(){
// Read the key structure from the file.
if(!m_file.set_pos(m_seek_key)) return false;
if(!m_file.read_buffer(m_buffer,m_nbytes)) return false;
if(m_file.verbose()) {
m_file.out() << "tools::rroot::key::read_file :"
<< " reading " << m_nbytes << " bytes"
<< " at position " << m_seek_key
<< "."
<< std::endl;
}
return true;
}
char* buf() const {return m_buffer;}
char* data_buffer() const {return m_buffer + m_key_length;}
const char* eob() const {return m_buffer + m_buf_size;}
uint32 buf_size() const {return m_buf_size;}
uint32 key_length() const {return m_key_length;}
bool from_buffer(const char* aEOB,char*& a_pos) {
rbuf rb(m_file.out(),m_file.byte_swap(),aEOB,a_pos);
int _nbytes;
if(!rb.read(_nbytes)) return false;
/*
if(m_nbytes) {
if(_nbytes!=int(m_nbytes)) {
out << "tools::rroot::key::from_buffer :"
<< " nbytes not consistent."
<< " read " << _nbytes
<< ", expected " << m_nbytes
<< ". Continue with " << _nbytes
<< std::endl;
m_nbytes = _nbytes;
}
} else {
*/
m_nbytes = _nbytes;
//}
short version;
if(!rb.read(version)) return false;
m_version = version;
{int v;
if(!rb.read(v)) return false;
m_object_size = v;}
unsigned int _date;
if(!rb.read(_date)) return false;
//fDate.setDate(_date);
{short v;
if(!rb.read(v)) return false;
m_key_length = v;}
{short v;
if(!rb.read(v)) return false;
m_cycle = v;}
if(version>1000) {
if(!rb.read(m_seek_key)) return false;
if(!rb.read(m_seek_parent_dir)) return false;
} else {
{seek32 i;
if(!rb.read(i)) return false;
m_seek_key = i;}
{seek32 i;
if(!rb.read(i)) return false;
m_seek_parent_dir = i;}
}
if(!rb.read(m_object_class)) return false;
if(!rb.read(m_object_name)) return false;
if(!rb.read(m_object_title)) return false;
if(m_file.verbose()) {
m_file.out() << "tools::rroot::key::from_buffer :"
<< " nbytes : " << m_nbytes
<< ", object class : " << sout(m_object_class)
<< ", object name : " << sout(m_object_name)
<< ", object title : " << sout(m_object_title)
<< ", object size : " << m_object_size
<< "."
<< std::endl;
}
return true;
}
char* get_object_buffer(uint32& a_size) {
if(!m_key_length) {
m_file.out() << "tools::rroot::key::get_object_buffer :"
<< " WARNING : m_key_length is zero."
<< std::endl;
//delete [] m_buffer;
//m_buffer = 0;
//m_buf_size = 0;
//a_size = 0;
//return 0;
}
if(!m_nbytes) {
m_file.out() << "tools::rroot::key::get_object_buffer :"
<< " m_nbytes is zero."
<< std::endl;
delete [] m_buffer;
m_buffer = 0;
m_buf_size = 0;
a_size = 0;
return 0;
}
if(!m_object_size) {
m_file.out() << "tools::rroot::key::get_object_buffer :"
<< " WARNING : m_object_size is zero."
<< std::endl;
}
if(m_file.verbose()) {
m_file.out() << "tools::rroot::key::get_object_buffer :"
<< " m_nbytes : " << m_nbytes
<< " m_key_length : " << m_key_length
<< " m_object_size : " << m_object_size << "."
<< " m_seek_key : " << m_seek_key << "."
<< std::endl;
}
if(m_object_size <= (m_nbytes-m_key_length)) {
delete [] m_buffer;
m_buf_size = m_key_length+m_object_size;
if(m_buf_size<m_nbytes) {
m_file.out() << "tools::rroot::key::get_object_buffer :"
<< " WARNING : m_buf_size<m_nbytes."
<< " m_buf_size " << m_buf_size
<< " m_nbytes " << m_nbytes
<< ". Raise m_buf_size to " << m_nbytes << "."
<< std::endl;
m_buf_size = m_nbytes; //for read_file()
}
m_buffer = new char[m_buf_size];
if(!m_buffer) {
m_file.out() << "tools::rroot::key::get_object_buffer :"
<< " can't alloc " << m_buf_size
<< std::endl;
m_buffer = 0;
m_buf_size = 0;
a_size = 0;
return 0;
}
if(!read_file()) {
delete [] m_buffer;
m_buffer = 0;
m_buf_size = 0;
a_size = 0;
return 0;
}
} else {
// have to decompress. Need a second buffer.
uint32 decsiz = m_key_length+m_object_size;
char* decbuf = new char[decsiz];
if(!decbuf) {
m_file.out() << "tools::rroot::key::get_object_buffer :"
<< " can't alloc " << decsiz
<< std::endl;
a_size = 0;
return 0;
}
delete [] m_buffer;
m_buffer = new char[m_nbytes];
m_buf_size = m_nbytes;
if(!read_file()) {
delete [] decbuf;
decbuf = 0;
delete [] m_buffer;
m_buffer = 0;
m_buf_size = 0;
a_size = 0;
return 0;
}
::memcpy(decbuf,m_buffer,m_key_length);
// decompress :
unsigned char* objbuf = (unsigned char*)(decbuf+m_key_length);
unsigned char* bufcur = (unsigned char*)(m_buffer+m_key_length);
int nout = 0;
uint32 noutot = 0;
while(true) {
int nin =
9 + ((int)bufcur[3] | ((int)bufcur[4] << 8) | ((int)bufcur[5] << 16));
int nbuf =
(int)bufcur[6] | ((int)bufcur[7] << 8) | ((int)bufcur[8] << 16);
if(!unzip(m_file.out(),nin,bufcur, nbuf,objbuf, nout)) break;
if(!nout) break;
noutot += nout;
if(noutot >= m_object_size) break;
bufcur += nin;
objbuf += nout;
}
delete [] m_buffer;
m_buffer = 0;
m_buf_size = 0;
if(!noutot) {
m_file.out() << "tools::rroot::key::get_object_buffer :"
<< " nothing from decompression."
<< std::endl;
delete [] decbuf;
decbuf = 0;
a_size = 0;
return 0;
}
if(noutot!=m_object_size) {
m_file.out() << "tools::rroot::key::get_object_buffer :"
<< " decompression mismatch."
<< " noutot " << noutot
<< " m_object_size " << m_object_size
<< std::endl;
delete [] decbuf;
decbuf = 0;
a_size = 0;
return 0;
}
m_buffer = decbuf;
m_buf_size = decsiz;
}
a_size = m_object_size;
return m_buffer+m_key_length;
}
//NOTE : print is a Python keyword.
void dump(std::ostream& a_out) const {
a_out << "class : " << sout(m_object_class)
<< ", name : " << sout(m_object_name)
<< ", title : " << sout(m_object_title)
<< ", size : " << m_object_size
<< "."
<< std::endl;
}
protected:
static const uint32 START_BIG_FILE = 2000000000;
protected:
uint32 record_size(uint32 a_version) const {
// Return the size in bytes of the key header structure.
uint32 _nbytes = sizeof(m_nbytes);
_nbytes += sizeof(short); //2
_nbytes += sizeof(m_object_size);
_nbytes += sizeof(date);
_nbytes += sizeof(m_key_length);
_nbytes += sizeof(m_cycle); //2+4*4=18
if(a_version>1000) {
_nbytes += sizeof(seek);
_nbytes += sizeof(seek); //18+2*8=34
} else {
_nbytes += sizeof(seek32);
_nbytes += sizeof(seek32); //18+2*4=26
}
_nbytes += std_string_record_size(m_object_class);
_nbytes += std_string_record_size(m_object_name);
_nbytes += std_string_record_size(m_object_title);
//::printf("debug : record_size %d\n",_nbytes);
return _nbytes;
}
static std::string sout(const std::string& a_string) {
return std::string("\"")+a_string+"\"";
}
bool unzip(std::ostream& a_out,
int a_srcsize,unsigned char* a_src,
int a_tgtsize,unsigned char* a_tgt,
int& a_irep) {
// Author: E.Chernyaev (IHEP/Protvino)
// Input: scrsize - size of input buffer
// src - input buffer
// tgtsize - size of target buffer
//
// Output: tgt - target buffer (decompressed)
// irep - size of decompressed data
// 0 - if error
a_irep = 0;
// C H E C K H E A D E R
const int HDRSIZE = 9;
if (a_srcsize < HDRSIZE) {
a_out << "tools::rroot::key::unzip : too small source" << std::endl;
return false;
}
unsigned char DEFLATE = 8;
if ((a_src[0] != 'C' && a_src[0] != 'Z') ||
(a_src[1] != 'S' && a_src[1] != 'L') ||
a_src[2] != DEFLATE) {
a_out << "tools::rroot::key::unzip : error in header" << std::endl;
return false;
}
long _ibufcnt =
(long)a_src[3] | ((long)a_src[4] << 8) | ((long)a_src[5] << 16);
long isize =
(long)a_src[6] | ((long)a_src[7] << 8) | ((long)a_src[8] << 16);
if(a_tgtsize<isize) {
a_out << "tools::rroot::key::unzip : too small target." << std::endl;
return false;
}
if(_ibufcnt + HDRSIZE != a_srcsize) {
a_out << "tools::rroot::key::unzip :"
<< " discrepancy in source length." << std::endl;
return false;
}
// D E C O M P R E S S D A T A
if (a_src[0] == 'Z' && a_src[1] == 'L') { //compressed with zlib.
tools::unzip_func func;
if(!m_file.unziper('Z',func)) {
a_out << "tools::rroot::key::unzip : "
<< " zlib unziper not found." << std::endl;
return false;
}
unsigned int irep;
char* src = (char*)(a_src + HDRSIZE);
if(!func(a_out,
(unsigned int)a_srcsize,src,
(unsigned int)a_tgtsize,(char*)a_tgt,irep)) {
a_out << "tools::rroot::key::unzip : "
<< " unzip function failed." << std::endl;
a_irep = 0;
return false;
}
a_irep = irep;
} else if (a_src[0] == 'C' && a_src[1] == 'S') {
//compressed with Chernyaev & Smirnov
csz__Init_Inflate(_ibufcnt,a_src + HDRSIZE,a_tgtsize,a_tgt);
if (csz__Inflate()) {
a_out << "tools::rroot::key::unzip :"
<< " error during decompression." << std::endl;
return false;
}
unsigned char* obufptr = csz__obufptr();
// if (obufptr - a_tgt != isize) {
// There are some rare cases when a few more bytes are required
if (obufptr - a_tgt > a_tgtsize) {
a_out << "tools::rroot::key::_unzip :"
<< " discrepancy " << (int)(obufptr - a_tgt)
<< " with initial size: " << (int)isize
<< ", tgtsize= " << a_tgtsize
<< std::endl;
a_irep = obufptr - a_tgt;
//return false;
}
a_irep = isize;
//a_out << "tools::rroot::key::unzip : CS : ok "
// << a_irep << std::endl;
} else {
a_out << "tools::rroot::key::_unzip : unknown a_src[0,1]."
<< " [0] = " << a_src[0] << ", [1] = " << a_src[1]
<< std::endl;
a_irep = 0;
return false;
}
return true;
}
static const std::string& s_class() {
static const std::string s_v("tools::rroot::key");
return s_v;
}
protected:
ifile& m_file;
uint32 m_buf_size;
char* m_buffer;
// Record (stored in file) :
uint32 m_nbytes; //Number of bytes for the object on file
uint32 m_version; //Key version identifier
uint32 m_object_size; //Length of uncompressed object in bytes
date m_date; //Date/Time of insertion in file
uint16 m_key_length; //Number of bytes for the key itself
uint16 m_cycle; //Cycle number
seek m_seek_key; //Location of object on file
seek m_seek_parent_dir; //Location of parent directory on file
std::string m_object_class; //Object Class name.
std::string m_object_name; //name of the object.
std::string m_object_title; //title of the object.
};
}}
#endif
//doc :
//////////////////////////////////////////////////////////////////////////
// //
// The Key class includes functions to book space on a file, //
// to create I/O buffers, to fill these buffers //
// to compress/uncompress data buffers. //
// //
// Before saving (making persistent) an object on a file, a key must //
// be created. The key structure contains all the information to //
// uniquely identify a persistent object on a file. //
// fNbytes = number of bytes for the compressed object+key //
// version of the Key class //
// fObjlen = Length of uncompressed object //
// fDatime = Date/Time when the object was written //
// fKeylen = number of bytes for the key structure //
// fCycle = cycle number of the object //
// fSeekKey = Address of the object on file (points to fNbytes) //
// This is a redundant information used to cross-check //
// the data base integrity. //
// fSeekPdir = Pointer to the directory supporting this object //
// fClassName = Object class name //
// fName = name of the object //
// fTitle = title of the object //
// //
// The Key class is used by ROOT to: //
// - to write an object in the Current Directory //
// - to write a new ntuple buffer //
// //
//////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,359 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_leaf
#define tools_rroot_leaf
#include "base_leaf"
#include "../stype"
#include "../cids"
namespace tools {
namespace rroot {
inline const std::string& leaf_store_class(char) {
static const std::string s_v("TLeafB");
return s_v;
}
inline const std::string& leaf_store_class(short) {
static const std::string s_v("TLeafS");
return s_v;
}
inline const std::string& leaf_store_class(int) {
static const std::string s_v("TLeafI");
return s_v;
}
inline const std::string& leaf_store_class(float) {
static const std::string s_v("TLeafF");
return s_v;
}
inline const std::string& leaf_store_class(double) {
static const std::string s_v("TLeafD");
return s_v;
}
inline const std::string& leaf_store_class(bool) {
static const std::string s_v("TLeafO");
return s_v;
}
inline const std::string& leaf_float_cls() {
static const std::string s_v("tools::rroot::leaf<float>");
return s_v;
}
inline const std::string& leaf_double_cls() {
static const std::string s_v("tools::rroot::leaf<double>");
return s_v;
}
inline const std::string& leaf_int_cls() {
static const std::string s_v("tools::rroot::leaf<int>");
return s_v;
}
inline const std::string& leaf_bool_cls() {
static const std::string s_v("tools::rroot::leaf<bool>");
return s_v;
}
template <class T>
class leaf : public base_leaf {
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::leaf<"+stype(T())+">");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast< leaf<T> >(this,a_class)) {return p;}
return base_leaf::cast(a_class);
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return base_leaf_cid()+_cid(T());}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<leaf>(this,a_class)) {return p;}
return base_leaf::cast(a_class);
}
public:
virtual iro* copy() const {return new leaf<T>(*this);}
virtual bool stream(buffer& a_buffer) {
delete [] m_value;
m_value = 0;
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!base_leaf::stream(a_buffer)) return false;
if(!a_buffer.read(m_min)) return false;
if(!a_buffer.read(m_max)) return false;
if(!a_buffer.check_byte_count(s,c,leaf_store_class(T()))) return false;
m_value = new T[m_length];
return true;
}
public: //base_leaf
virtual bool read_basket(buffer& a_buffer) {
if(!m_leaf_count && (m_ndata == 1)) {
/*
if(!aBuffer.read(m_value[0])) {
std::ostream& out = base_leaf::branch().out();
out << "Rio::Leaf::readBasket : \"" << name() << "\" :"
<< " read value failed."
<< std::endl;
return false;
}
return true;
*/
m_out << "tools::rroot::leaf::read_basket :"
<< " case(1) not yet handled."
<< std::endl;
return false;
}else {
if(m_leaf_count) {
m_out << "tools::rroot::leaf::read_basket :"
<< " case(2) not yet handled."
<< std::endl;
return false;
/*
int len = m_leaf_count->number();
if (len > m_leaf_count->maximum()) {
std::ostream& out = base_leaf::branch().out();
out << "Rio::Leaf::readBasket : \""
<< name() << "\", len = " << len << " and max = "
<< m_leaf_count->maximum() << std::endl;
len = m_leaf_count->maximum();
}
m_ndata = len * fLength;
if(!aBuffer.readFastArray(m_value,len * fLength)) {
std::ostream& out = base_leaf::branch().out();
out << "Rio::Leaf::readBasket : \"" << name() << "\" :"
<< " readFastArray failed."
<< std::endl;
return false;
}
return true;
*/
} else {
if(m_length) {
if(!m_value) {
delete [] m_value;
m_value = new T[m_length]; //we assume m_length is constant.
}
if(!a_buffer.read_fast_array<T>(m_value,m_length)) {
m_out << "tools::rroot::leaf::read_basket :"
<< " read_fast_array failed. m_length " << m_length
<< std::endl;
return false;
}
return true;
} else {
m_out << "tools::rroot::leaf::read_basket :"
<< " read_fast_array failed. m_length is zero."
<< std::endl;
return false;
}
//::printf("debug : value : %d %g\n",m_value[0],m_value[0]);
}
}
return true;
}
virtual bool print_value(std::ostream& a_out,uint32 a_index) const {
//if(!m_value) return false;
a_out << m_value[a_index];
return true;
}
virtual uint32 num_elem() const {return m_length;}
public:
leaf(std::ostream& a_out,rroot::branch& a_branch,ifac& a_fac)
:base_leaf(a_out,a_branch,a_fac)
,m_min(T()),m_max(T())
,m_value(0)
{}
virtual ~leaf(){
delete [] m_value;
}
protected:
leaf(const leaf& a_from):iro(a_from),base_leaf(a_from){}
leaf& operator=(const leaf&){return *this;}
public:
T value(uint32 a_index = 0) const {
//WARNING : fast getter. No check are done on m_value and a_index.
return m_value[a_index];
}
protected:
T m_min; //Minimum value if leaf range is specified
T m_max; //Maximum value if leaf range is specified
T* m_value; //!Pointer to data buffer
//T** fPointer; //!Addresss of pointer to data buffer!
};
class leaf_string : public base_leaf {
static const std::string& s_store_class() {
static const std::string s_v("TLeafC");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::leaf_string");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<leaf_string>(this,a_class)) {return p;}
return base_leaf::cast(a_class);
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return leaf_string_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<leaf_string>(this,a_class)) {return p;}
return base_leaf::cast(a_class);
}
public:
virtual iro* copy() const {return new leaf_string(*this);}
virtual bool stream(buffer& a_buffer) {
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!base_leaf::stream(a_buffer)) return false;
if(!a_buffer.read(m_min)) return false;
if(!a_buffer.read(m_max)) return false;
if(!a_buffer.check_byte_count(s,c,s_store_class())) return false;
return true;
}
public: //base_leaf
virtual bool read_basket(buffer& a_buffer) {
delete [] m_value;
m_value = 0;
unsigned char lenchar;
if(!a_buffer.read(lenchar)) {
m_out << "tools::rroot::leaf_string::read_basket :"
<< " read(uchar) failed."
<< std::endl;
return false;
}
uint32 len = 0;
if(lenchar < 255) {
len = lenchar;
} else {
if(!a_buffer.read(len)) {
m_out << "tools::rroot::leaf_string::read_basket :"
<< " read(int) failed."
<< std::endl;
return false;
}
}
if(len) {
if(!m_length) {
m_out << "tools::rroot::leaf_string::read_basket :"
<< " m_length is zero."
<< std::endl;
return false;
}
if(len >= m_length) len = m_length-1;
m_value = new char[len+1];
if(!a_buffer.read_fast_array(m_value,len)) {
m_out << "tools::rroot::leaf_string::read_basket :"
<< " read_fast_array failed."
<< std::endl;
delete [] m_value;
m_value = 0;
return false;
}
m_value[len] = 0;
} else {
}
return true;
}
virtual bool print_value(std::ostream& a_out,uint32) const {
if(m_value) a_out << m_value;
return true;
}
virtual uint32 num_elem() const {return 1;}
public:
leaf_string(std::ostream& a_out,rroot::branch& a_branch,ifac& a_fac)
:base_leaf(a_out,a_branch,a_fac)
,m_min(0),m_max(0),m_value(0){}
virtual ~leaf_string(){
delete [] m_value;
}
protected:
leaf_string(const leaf_string& a_from)
:iro(a_from),base_leaf(a_from)
,m_min(0),m_max(0),m_value(0){}
leaf_string& operator=(const leaf_string&){return *this;}
public:
const char* value() const {return m_value;}
protected:
int m_min;
int m_max;
char* m_value;
};
class leaf_element : public base_leaf {
static const std::string& s_store_class() {
static const std::string s_v("TLeafElement");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::leaf_element");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<leaf_element>(this,a_class)) {return p;}
return base_leaf::cast(a_class);
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return leaf_element_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<leaf_element>(this,a_class)) {return p;}
return base_leaf::cast(a_class);
}
public:
virtual iro* copy() const {return new leaf_element(*this);}
virtual bool stream(buffer& a_buffer) {
short v;
unsigned int s,c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!base_leaf::stream(a_buffer)) return false;
if(!a_buffer.read(fID)) return false;
if(!a_buffer.read(fType)) return false;
if(!a_buffer.check_byte_count(s,c,s_store_class())) return false;
return true;
}
public: //base_leaf
virtual bool read_basket(buffer&) {
m_out << "tools::rroot::leaf_element::read_basket :"
<< " dummy."
<< std::endl;
return false;
}
virtual bool print_value(std::ostream&,uint32) const {return true;}
virtual uint32 num_elem() const {return 0;}
public:
leaf_element(std::ostream& a_out,rroot::branch& a_branch,ifac& a_fac)
:base_leaf(a_out,a_branch,a_fac),fID(0),fType(0){}
virtual ~leaf_element(){}
protected:
leaf_element(const leaf_element& a_from)
:iro(a_from),base_leaf(a_from),fID(0),fType(0){}
leaf_element& operator=(const leaf_element&){return *this;}
public:
//int id() const {return fID;}
int leaf_type() const {return fType;}
protected:
int fID; //element serial number in fInfo
int fType; //leaf type
};
}}
#endif
@@ -0,0 +1,86 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_matrix
#define tools_rroot_matrix
//NOTE : not yet tested.
#include "../scast"
#include "buffer"
#include "named"
namespace tools {
namespace rroot {
class matrix : public virtual iro {
static const std::string& s_store_class() {
static const std::string s_v("TMatrix");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::matrix");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<matrix>(this,a_class)) return p;
return 0;
}
public:
static cid id_class() {return matrix_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<matrix>(this,a_class)) {return p;}
else return 0;
}
public:
virtual bool stream(buffer& a_buffer) {
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return false;
//printf("debug : BatchLab::Rio::TMatrix::stream : version %d\n",v);
// Version 2 streaming (ROOT/v3-00-6).
{uint32 id,bits;
if(!Object_stream(a_buffer,id,bits)) return false;}
int Nrows;
if(!a_buffer.read(Nrows)) return false;
int Ncols;
if(!a_buffer.read(Ncols)) return false;
int Nelems;
if(!a_buffer.read(Nelems)) return false;
int RowLwb;
if(!a_buffer.read(RowLwb)) return false;
int ColLwb;
if(!a_buffer.read(ColLwb)) return false;
//Real_t* Elements; //[fNelems]
if(!dummy_array_stream<float>(a_buffer,Nelems)) return false;
if(!a_buffer.check_byte_count(s,c,s_store_class())) return false;
return true;
}
public:
matrix(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~matrix(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
matrix(const matrix& a_from): iro(a_from){}
matrix& operator=(const matrix&){return *this;}
};
}}
#endif
@@ -0,0 +1,99 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_member_reader
#define tools_rroot_member_reader
#include "../store/iobj_visitor"
#include "buffer"
namespace tools {
namespace rroot {
class member_reader : public virtual iobj_visitor {
public:
virtual std::ostream& out() {return m_buf.out();}
virtual bool visit(bool& a_v){return m_buf.read(a_v);}
virtual bool visit(char& a_v){return m_buf.read(a_v);}
virtual bool visit(short& a_v){return m_buf.read(a_v);}
virtual bool visit(int& a_v){return m_buf.read(a_v);}
virtual bool visit(unsigned int& a_v){return m_buf.read(a_v);}
virtual bool visit(int64&){
m_buf.out() << "tools::rroot::member_reader::visit(int64) :"
<< " dummy." << std::endl;
return false; //FIXME
}
virtual bool visit(uint64&){
m_buf.out() << "tools::rroot::member_reader::visit(uint64) :"
<< " dummy." << std::endl;
return false; //FIXME
}
virtual bool visit(float& a_v){return m_buf.read(a_v);}
virtual bool visit(double& a_v){return m_buf.read(a_v);}
virtual bool visit(std::string& a_v){return m_buf.read(a_v);}
//virtual bool visit(const char* a_v){
// return m_buf.read(std::string(a_v));
//}
virtual bool visit(std::vector<bool>& a_v){
std::vector<unsigned char> data;
if(!m_buf.read_array(data)) {a_v.clear();return false;}
unsigned int number = data.size();
a_v.resize(number);
for(unsigned int index=0;index<number;index++) {
a_v[index] = (data[index]==1?true:false);
}
return true;
}
virtual bool visit(std::vector<char>& a_v){return m_buf.read_array(a_v);}
virtual bool visit(std::vector<short>& a_v){return m_buf.read_array(a_v);}
virtual bool visit(std::vector<int>& a_v){return m_buf.read_array(a_v);}
virtual bool visit(std::vector<int64>& /*a_v*/){
//FIXME return ::Rio::writeArray<Slash::int64>(fBuffer,a_v);
m_buf.out() << "tools::rroot::member_reader::visit(vector<int64>) :"
<< " dummy." << std::endl;
return false;
}
virtual bool visit(std::vector<float>& a_v){return m_buf.read_array(a_v);}
virtual bool visit(std::vector<double>& a_v){return m_buf.read_array(a_v);}
virtual bool visit(std::vector<unsigned char>& a_v){
return m_buf.read_array(a_v);
}
virtual bool visit(std::vector<std::string>& a_v){return m_buf.read(a_v);}
virtual bool visit(std::vector< std::vector<double> >& a_v){
return m_buf.read_array2(a_v);
}
public:
member_reader(buffer& a_buf):m_buf(a_buf){}
virtual ~member_reader(){}
private:
member_reader(const member_reader& a_from)
:iobj_visitor(a_from)
,m_buf(a_from.m_buf)
{}
member_reader& operator=(const member_reader&){return *this;}
protected:
buffer& m_buf;
};
}}
#endif
@@ -0,0 +1,702 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_named
#define tools_rroot_named
#include "buffer"
#include "../vdata"
#include "../vmanip"
#include "../forit"
#include "../scast" //for ObjArray
#include "cids"
namespace tools {
namespace rroot {
inline bool Object_stream(buffer& a_buffer,uint32& a_id,uint32& a_bits) {
short v;
if(!a_buffer.read_version(v)) return false;
if(!a_buffer.read(a_id)) return false;
if(!a_buffer.read(a_bits)) return false;
return true;
}
inline bool Named_stream(buffer& a_buffer,
std::string& a_name,
std::string& a_title) {
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
{uint32 id,bits;
if(!Object_stream(a_buffer,id,bits)) return false;}
if(!a_buffer.read(a_name)) return false;
if(!a_buffer.read(a_title)) return false;
if(!a_buffer.check_byte_count(s,c,"TNamed")) return false;
return true;
}
inline bool AttLine_stream(buffer& a_buffer,
short& a_color,
short& a_style,
short& a_width){
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!a_buffer.read(a_color)) return false;
if(!a_buffer.read(a_style)) return false;
if(!a_buffer.read(a_width)) return false;
if(!a_buffer.check_byte_count(s,c,"TAttLine")) return false;
return true;
}
inline bool AttFill_stream(buffer& a_buffer,
short& a_color,
short& a_style){
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!a_buffer.read(a_color)) return false;
if(!a_buffer.read(a_style)) return false;
if(!a_buffer.check_byte_count(s,c,"TAttFill")) return false;
return true;
}
inline bool AttMarker_stream(buffer& a_buffer) {
short fMarkerColor;
short fMarkerStyle;
float fMarkerWidth;
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!a_buffer.read(fMarkerColor)) return false;
if(!a_buffer.read(fMarkerStyle)) return false;
if(!a_buffer.read(fMarkerWidth)) return false;
if(!a_buffer.check_byte_count(s,c,"TAttMarker")) return false;
return true;
}
inline bool GeoAtt_stream(buffer& a_buffer) {
unsigned int fGeoAtt; // option flags
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!a_buffer.read(fGeoAtt)) return false;
if(!a_buffer.check_byte_count(s,c,"TGeoAtt")) return false;
return true;
}
inline bool Att3D_stream(buffer& a_buffer) {
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!a_buffer.check_byte_count(s,c,"TAtt3D")) return false;
return true;
}
template <class T>
inline bool Array_stream(buffer& a_buffer,std::vector<T>& a_v) {
a_v.clear();
int sz;
if(!a_buffer.read(sz)) return false;
//check sz is not crazy :
if(!a_buffer.check_eob(sz)) return false;
a_v.resize(sz);
if(!a_buffer.read_fast_array<T>(vec_data(a_v),sz)) return false;
return true;
}
template <class T>
inline bool dummy_array_stream(buffer& a_buffer,int a_n){
char is_array;
if(!a_buffer.read(is_array)) return false;
if(!is_array) return true;
if(!a_n) return true;
T* v = new T[a_n];
bool status = a_buffer.read_fast_array<T>(v,a_n);
delete [] v;
return status;
}
template <class T>
inline bool fixed_array_stream(buffer& a_buffer,int a_n,T*& a_v){
delete [] a_v;
a_v = 0;
char is_array;
if(!a_buffer.read(is_array)) return false;
if(!is_array) return true;
if(!a_n) return true;
a_v = new T[a_n];
if(!a_buffer.read_fast_array<T>(a_v,a_n)) {
delete [] a_v;
a_v = 0;
return false;
}
return true;
}
class iros : public virtual iro,public std::vector<iro*> {
static const std::string& s_store_class() {
static const std::string s_v("TObjArray");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::iros");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<iros>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return List_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<iros>(this,a_class)) {return p;}
else return 0;
}
public:
virtual iro* copy() const {return new iros(*this);}
virtual bool stream(buffer& a_buffer) {
ifac::args args;
bool accept_null = false;
return stream(a_buffer,args,accept_null);
}
public:
iros(ifac& a_fac,bool a_owner)
:m_fac(a_fac)
,m_owner(a_owner)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~iros(){
_clear();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
iros(const iros& a_from)
:iro(a_from)
,std::vector<iro*>()
,m_fac(a_from.m_fac)
,m_owner(a_from.m_owner)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
if(a_from.m_owner) {
tools_vforcit(iro*,a_from,it) push_back((*it)->copy());
} else {
tools_vforcit(iro*,a_from,it) push_back((*it));
}
}
iros& operator=(const iros& a_from){
if(&a_from==this) return *this;
_clear();
m_owner = a_from.m_owner;
if(a_from.m_owner) {
tools_vforcit(iro*,a_from,it) push_back((*it)->copy());
} else {
tools_vforcit(iro*,a_from,it) push_back((*it));
}
return *this;
}
public:
void cleanup() {_clear();}
void dump(std::ostream& a_out) {
a_out << " iros : size " << size() << std::endl;
tools_vforcit(iro*,*this,it) {
a_out << " class " << (*it)->s_cls() << std::endl;
}
}
public:
bool stream(buffer& a_buffer,
const ifac::args& a_args,bool a_accept_null = false) {
_clear();
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
//::printf("debug : iros::stream : version %d, byte count %d\n",v,c);
{uint32 id,bits;
if(!Object_stream(a_buffer,id,bits)) return false;}
std::string name;
if(!a_buffer.read(name)) return false;
int nobjects;
if(!a_buffer.read(nobjects)) return false;
int lowerBound;
if(!a_buffer.read(lowerBound)) return false;
//::printf("debug : iros : name \"%s\", nobject %d, lowerBound %d\n",
// name.c_str(),nobjects,lowerBound);
for (int i=0;i<nobjects;i++) {
//::printf("debug : iros : n=%d i=%d ...\n",nobjects,i);
iro* obj;
if(!a_buffer.read_object(m_fac,a_args,obj)){
a_buffer.out() << "tools::rroot::iros::stream :"
<< " can't read object."
<< std::endl;
return false;
}
//::printf("debug : iros : n=%d i=%d : ok\n",nobjects,i);
if(obj) {
push_back(obj);
} else {
//a_accept_null for branch::stream m_baskets.
if(a_accept_null) push_back(0);
}
}
return a_buffer.check_byte_count(s,c,s_store_class());
}
protected:
void _clear() {
if(m_owner) {
tools::clear<iro>(*this);
} else {
std::vector<iro*>::clear();
}
}
protected:
ifac& m_fac;
bool m_owner;
};
template <class T>
class ObjArray : public virtual iro,public std::vector<T*> {
static const std::string& s_store_class() {
static const std::string s_v("TObjArray");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::ObjArray<"+T::s_class()+">");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast< ObjArray<T> >(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return ObjArray_cid()+T::id_class();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<ObjArray>(this,a_class)) {return p;}
return 0;
}
virtual iro* copy() const {return new ObjArray<T>(*this);}
virtual bool stream(buffer& a_buffer) {
ifac::args args;
bool accept_null = false;
return stream(a_buffer,args,accept_null);
}
public:
ObjArray(ifac& a_fac,bool a_owner)
:m_fac(a_fac)
,m_owner(a_owner){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~ObjArray(){
_clear();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
ObjArray(const ObjArray& a_from)
:iro(a_from)
,std::vector<T*>()
,m_fac(a_from.m_fac)
,m_owner(a_from.m_owner)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
if(a_from.m_owner) {
typedef typename std::vector<T*>::const_iterator it_t;
for(it_t it=a_from.begin();it!=a_from.end();++it) {
if(!(*it)) {
std::vector<T*>::push_back(0);
} else {
iro* _obj = (*it)->copy();
T* obj = safe_cast<iro,T>(*_obj);
if(!obj) {
//a_buffer.out() << "tools::rroot::ObjArray::ObjArray :"
// << " inlib::cast failed."
// << std::endl;
delete _obj;
} else {
std::vector<T*>::push_back(obj);
}
}
}
} else {
std::vector<T*>::operator=(a_from);
}
}
ObjArray& operator=(const ObjArray& a_from){
if(&a_from==this) return *this;
_clear();
m_owner = a_from.m_owner;
if(a_from.m_owner) {
typedef typename std::vector<T*>::const_iterator it_t;
for(it_t it=a_from.begin();it!=a_from.end();++it) {
if(!(*it)) {
std::vector<T*>::push_back(0);
} else {
iro* _obj = (*it)->copy();
T* obj = safe_cast<iro,T>(*_obj);
if(!obj) {
//a_buffer.out() << "tools::rroot::ObjArray::operator= :"
// << " inlib::cast failed."
// << std::endl;
delete _obj;
} else {
std::vector<T*>::push_back(obj);
}
}
}
} else {
std::vector<T*>::operator=(a_from);
}
return *this;
}
public:
void cleanup() {_clear();}
public:
bool stream(buffer& a_buffer,const ifac::args& a_args,bool a_accept_null = false) {
_clear();
short v;
unsigned int sp, bc;
if(!a_buffer.read_version(v,sp,bc)) return false;
//::printf("debug : ObjArray::stream : version %d, byte count %d\n",v,c);
{uint32 id,bits;
if(!Object_stream(a_buffer,id,bits)) return false;}
std::string name;
if(!a_buffer.read(name)) return false;
int nobjects;
if(!a_buffer.read(nobjects)) return false;
int lowerBound;
if(!a_buffer.read(lowerBound)) return false;
//::printf("debug : ObjArray : name \"%s\", nobject %d, lowerBound %d\n",
// name.c_str(),nobjects,lowerBound);
for (int i=0;i<nobjects;i++) {
//::printf("debug : ObjArray : n=%d i=%d ...\n",nobjects,i);
iro* obj;
if(!a_buffer.read_object(m_fac,a_args,obj)){
a_buffer.out() << "tools::rroot::ObjArray::stream :"
<< " can't read object."
<< std::endl;
return false;
}
//::printf("debug : ObjArray : n=%d i=%d : ok\n",nobjects,i);
if(obj) {
T* to = safe_cast<iro,T>(*obj);
if(!to) {
a_buffer.out() << "tools::rroot::ObjArray::stream :"
<< " inlib::cast failed."
<< " " << obj->s_cls() << " is not a " << T::s_class() << "."
<< std::endl;
delete obj;
} else {
std::vector<T*>::push_back(to);
}
} else {
//a_accept_null for branch::stream m_baskets.
if(a_accept_null) std::vector<T*>::push_back(0);
}
}
return a_buffer.check_byte_count(sp,bc,s_store_class());
}
protected:
void _clear() {
if(m_owner) {
tools::clear<T>(*this);
} else {
std::vector<T*>::clear();
}
}
protected:
ifac& m_fac;
bool m_owner;
};
class List : public virtual iro, public std::vector<iro*> {
static const std::string& s_store_class() {
static const std::string s_v("TList");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::List");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<List>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return List_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<List>(this,a_class)) {return p;}
else return 0;
}
//virtual void* cast(cid) const {return List_cid();}
public:
virtual iro* copy() const {return new List(*this);}
virtual bool stream(buffer& a_buffer) {
_clear();
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
//::printf("debug : List::stream : version %d, byte count %d\n",v,c);
{uint32 id,bits;
if(!Object_stream(a_buffer,id,bits)) return false;}
std::string name;
if(!a_buffer.read(name)) return false;
int nobjects;
if(!a_buffer.read(nobjects)) return false;
//::printf("debug : List : name \"%s\", nobject %d\n",
// name.c_str(),nobjects);
ifac::args args;
for (int i=0;i<nobjects;i++) {
//::printf("debug : List : n=%d i=%d ...\n",nobjects,i);
iro* obj;
if(!a_buffer.read_object(m_fac,args,obj)){
a_buffer.out() << "tools::rroot::List::stream :"
<< " can't read object."
<< std::endl;
return false;
}
unsigned char nch;
if(!a_buffer.read(nch)) return false;
if(nch) {
char readOption[256];
if(!a_buffer.read_fast_array(readOption,nch)) return false;
readOption[nch] = 0;
}
if(obj) push_back(obj);
}
return a_buffer.check_byte_count(s,c,s_store_class());
}
public:
List(ifac& a_fac,bool a_owner)
:m_fac(a_fac)
,m_owner(a_owner)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~List(){
_clear();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
List(const List& a_from)
:iro(a_from)
,std::vector<iro*>()
,m_fac(a_from.m_fac)
,m_owner(a_from.m_owner)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
List& operator=(const List&){return *this;}
protected:
void _clear() {
if(m_owner) {
tools::clear<iro>(*this);
} else {
std::vector<iro*>::clear();
}
}
protected:
ifac& m_fac;
bool m_owner;
};
class HashList : public List {
static const std::string& s_store_class() {
static const std::string s_v("THashList");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::HashList");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<HashList>(this,a_class)) return p;
return List::cast(a_class);
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return HashList_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<HashList>(this,a_class)) {return p;}
return List::cast(a_class);
}
public:
virtual bool stream(buffer& a_buffer) {
uint32 startpos = a_buffer.length();
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return false;
//if(!List::stream(a_buffer)) return false;
a_buffer.set_offset(startpos+c+sizeof(unsigned int));
if(!a_buffer.check_byte_count(s,c,s_store_class())) return false;
return true;
}
public:
HashList(ifac& a_fac,bool a_owner):List(a_fac,a_owner){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~HashList(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
HashList(const HashList& a_from):iro(a_from),List(a_from){}
HashList& operator=(const HashList&){return *this;}
};
inline bool dummy_TXxx_pointer_stream(buffer& a_buffer,ifac& a_fac,bool a_del = true) {
ifac::args args;
iro* obj;
bool status = a_buffer.read_object(a_fac,args,obj);
if(a_del) delete obj;
return status;
}
template <class T>
inline bool pointer_stream(buffer& a_buffer,
ifac& a_fac,ifac::args& a_args,
const std::string& a_T_class,
T*& a_obj){
iro* obj;
if(!a_buffer.read_object(a_fac,a_args,obj)) {
a_buffer.out() << "tools::rroot::pointer_stream :"
<< " read_object failed."
<< std::endl;
a_obj = 0;
return false;
}
if(!obj) {
a_obj = 0;
} else {
a_obj = (T*)obj->cast(a_T_class);
if(!a_obj) {
a_buffer.out() << "tools::rroot::pointer_stream : "
<< " inlib::cast to " << a_T_class << " failed."
<< ". Object is a " << obj->s_cls() << "."
<< std::endl;
return false;
}
}
return true;
}
template <class T>
inline bool pointer_stream(buffer& a_buffer,
ifac& a_fac,ifac::args& a_args,
tools::cid a_T_class,
T*& a_obj){
iro* obj;
if(!a_buffer.read_object(a_fac,a_args,obj)) {
a_buffer.out() << "tools::rroot::pointer_stream :"
<< " read_object failed."
<< std::endl;
a_obj = 0;
return false;
}
if(!obj) {
a_obj = 0;
} else {
a_obj = (T*)obj->cast(a_T_class);
if(!a_obj) {
a_buffer.out() << "tools::rroot::pointer_stream : "
<< " inlib::cast to " << a_T_class << " failed."
<< ". Object is a " << obj->s_cls() << "."
<< std::endl;
return false;
}
}
return true;
}
template <class T>
inline bool pointer_stream(buffer& a_buffer,
ifac& a_fac,ifac::args& a_args,T*& a_obj){
//return pointer_stream(a_buffer,a_fac,a_args,T::s_class(),a_obj);
return pointer_stream(a_buffer,a_fac,a_args,T::id_class(),a_obj);
}
inline bool dummy_TObjArray_pointer_stream(buffer& a_buffer,ifac& a_fac,bool a_owner = true) {
iros oa(a_fac,a_owner);
ifac::args args;
return oa.stream(a_buffer,args);
}
inline bool dummy_TList_pointer_stream(buffer& a_buffer,ifac& a_fac,bool a_owner = true) {
List l(a_fac,a_owner);
return l.stream(a_buffer);
}
inline bool dummy_THashList_pointer_stream(buffer& a_buffer,ifac& a_fac,bool a_owner = true) {
HashList l(a_fac,a_owner);
return l.stream(a_buffer);
}
}}
#endif
@@ -0,0 +1,443 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_ntuple
#define tools_rroot_ntuple
// to have same API than rcsv::ntuple.
#include "../rntuple"
#include "tree"
#include "leaf"
#include "stl_vector"
#include "../cids"
#include "../vfind"
#include "../vmanip"
#include "../ntuple_binding"
#ifdef TOOLS_MEM
#include "../mem"
#endif
namespace tools {
namespace rroot {
class ntuple : public virtual read::intuple {
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::ntuple");
return s_v;
}
public: //intuple
virtual void start() {m_index = -1;}
virtual bool next() {
m_index++;
if((uint64)m_index>=m_tree.entries()) return false;
return true;
}
virtual read::icol* find_icol(const std::string& a_name){
return find_named<read::icol>(m_cols,a_name);
}
virtual const std::vector<read::icol*>& columns() const {return m_cols;}
public:
template <class T>
class column : public virtual read::icolumn<T> {
typedef read::icolumn<T> parent;
public:
static cid id_class() {return 200+_cid(T());}
public: //icol
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<column>(this,a_class)) {return p;}
return parent::cast(a_class);
}
virtual cid id_cls() const {return id_class();}
public: //icol
virtual const std::string& name() const {return m_leaf.name();}
public: //icolumn<T>
virtual bool get_entry(T& a_v) const {
unsigned int n;
if(!m_leaf.branch().find_entry(uint32(m_index),n)) {
a_v = T();
return false;
}
a_v = m_leaf.value();
return true;
}
virtual bool fetch_entry() const {
//NOTE : it is ok to have a NULL m_user_var.
unsigned int n;
if(!m_leaf.branch().find_entry(uint32(m_index),n)) {
if(m_user_var) *m_user_var = T();
return false;
}
if(m_user_var) *m_user_var = m_leaf.value();
return true;
}
public:
column(leaf<T>& a_leaf,int64& a_index,T* a_user_var = 0)
:m_leaf(a_leaf)
,m_index(a_index) //WARNING : we keep the ref !
,m_user_var(a_user_var) //not owner
{}
virtual ~column(){}
protected:
column(const column& a_from)
:read::intuple(a_from)
,parent(a_from)
,m_leaf(a_from.m_leaf)
,m_index(a_from.m_index)
,m_user_var(a_from.m_user_var)
{}
column& operator=(const column& a_from){
if(&a_from==this) return *this;
m_user_var = a_from.m_user_var;
return *this;
}
protected:
leaf<T>& m_leaf;
int64& m_index; //WARNING : a ref.
T* m_user_var;
};
class column_string : public virtual read::icol {
public:
static cid id_class() {
static const std::string s_v;
return _cid(s_v);
}
public: //icol
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<column_string>(this,a_class)) return p;
return 0;
}
virtual cid id_cls() const {return id_class();}
virtual const std::string& name() const {return m_leaf.name();}
public:
virtual bool fetch_entry() const {
//NOTE : it is ok to have a NULL m_user_var.
unsigned int n;
if(!m_leaf.branch().find_entry(uint32(m_index),n)) {
if(m_user_var) *m_user_var = std::string();
return false;
}
if(m_user_var) *m_user_var = m_leaf.value();
return true;
}
public:
column_string(leaf_string& a_leaf,int64& a_index,std::string* a_user_var = 0)
:m_leaf(a_leaf)
,m_index(a_index) //WARNING : we keep the ref !
,m_user_var(a_user_var) //not owner
{}
virtual ~column_string(){}
protected:
column_string(const column_string& a_from)
:read::icol(a_from)
,m_leaf(a_from.m_leaf)
,m_index(a_from.m_index)
,m_user_var(a_from.m_user_var)
{}
column_string& operator=(const column_string& a_from){
if(&a_from==this) return *this;
m_user_var = a_from.m_user_var;
return *this;
}
protected:
leaf_string& m_leaf;
int64& m_index; //WARNING : a ref.
std::string* m_user_var;
};
template <class RT,class T>
class column_element : public virtual read::icolumn<T> {
typedef read::icolumn<T> parent;
public:
static cid id_class() {return 300+_cid(T());}
public: //icol
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<column_element>(this,a_class)) {return p;}
return parent::cast(a_class);
}
virtual cid id_cls() const {return id_class();}
public: //icol
virtual const std::string& name() const {return m_leaf.name();}
public: //icolumn<T>
virtual bool get_entry(T& a_v) const {
unsigned int n;
if(!m_leaf.branch().find_entry(uint32(m_index),n)) {a_v = T();return false;}
if(!m_be) {a_v = T();return false;}
iro* obj = m_be->object(); //Not owner.
if(!obj) {a_v = T();return false;}
RT* v = id_cast<iro,RT>(*obj);
if(!v) {a_v = T();return false;}
a_v = *v; //it assumes a T::operator=(RT)
return true;
}
virtual bool fetch_entry() const {
unsigned int n;
if(!m_leaf.branch().find_entry(uint32(m_index),n)) {
if(m_user_var) *m_user_var = T();
return false;
}
if(!m_be) {
if(m_user_var) *m_user_var = T();
return false;
}
iro* obj = m_be->object(); //Not owner.
if(!obj) {
if(m_user_var) *m_user_var = T();
return false;
}
RT* v = id_cast<iro,RT>(*obj);
if(!v) {
if(m_user_var) *m_user_var = T();
return false;
}
if(m_user_var) *m_user_var = *v; //it assumes a T::operator=(RT)
return true;
}
public:
column_element(leaf_element& a_leaf,int64& a_index,T* a_user_var = 0)
:m_leaf(a_leaf)
,m_index(a_index) //WARNING : we keep the ref !
,m_be(0)
,m_user_var(a_user_var) //not owner
{
//WIN32 : cl.exe wants inlib:: in the below.
m_be = safe_cast<branch,branch_element>(m_leaf.branch());
}
virtual ~column_element(){}
protected:
column_element(const column_element& a_from)
:read::intuple(a_from),parent(a_from)
,m_leaf(a_from.m_leaf)
,m_index(a_from.m_index)
,m_be(a_from.m_be)
,m_user_var(a_from.m_user_var)
{}
column_element& operator=(const column_element& a_from){
if(&a_from==this) return *this;
m_be = a_from.m_be;
m_user_var = a_from.m_user_var;
return *this;
}
protected:
leaf_element& m_leaf;
int64& m_index; //WARNING : a ref.
branch_element* m_be;
T* m_user_var;
};
public:
ntuple(tree& a_tree):m_tree(a_tree),m_index(-1){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~ntuple() {
tools::clear<read::icol>(m_cols);
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
ntuple(const ntuple& a_from)
:read::intuple(a_from),m_tree(a_from.m_tree){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
ntuple& operator=(const ntuple&){return *this;}
public:
bool initialize(std::ostream& a_out,const ntuple_binding& a_bd = ntuple_binding()) {
tools::clear<read::icol>(m_cols);
std::vector<base_leaf*> leaves = m_tree.find_leaves();
tools_vforcit(base_leaf*,leaves,it) {
base_leaf* bl = (*it);
if(find_named<read::icol>(m_cols,bl->name())) {
a_out << "tools::rroot::ntuple::initialize :"
<< " column with name " << sout(bl->name())
<< " already exists."
<< std::endl;
tools::clear<read::icol>(m_cols);
return false;
}
//a_out << "tools::rroot::ntuple::initialize :"
// << " entries " << bl->branch().entry_number() << "."
// << std::endl;
if(leaf<float>* lf = safe_cast<base_leaf, leaf<float> >(*bl) ){
column<float>* col = new column<float>(*lf,m_index,a_bd.find_variable<float>(bl->name()));
m_cols.push_back(col);
} else if(leaf<double>* ld = safe_cast<base_leaf, leaf<double> >(*bl) ){
column<double>* col = new column<double>(*ld,m_index,a_bd.find_variable<double>(bl->name()));
m_cols.push_back(col);
} else if(leaf<int>* li = safe_cast<base_leaf, leaf<int> >(*bl) ){
column<int>* col = new column<int>(*li,m_index,a_bd.find_variable<int>(bl->name()));
m_cols.push_back(col);
} else if(leaf_string* ls = safe_cast<base_leaf, leaf_string >(*bl) ){
column_string* col = new column_string(*ls,m_index,a_bd.find_variable<std::string>(bl->name()));
m_cols.push_back(col);
} else if(leaf_element* le = safe_cast<base_leaf,leaf_element>(*bl) ){
branch_element* be = safe_cast<branch,branch_element>(le->branch());
if(be->class_name()=="vector<string>") {
typedef std::string el_t;
typedef column_element< stl_vector<el_t> , std::vector<el_t> > ce_t;
ce_t* col = new ce_t(*le,m_index,a_bd.find_variable< std::vector<el_t> >(bl->name()));
m_cols.push_back(col);
//unsigned int n;
//if(!be->find_entry(0,n)) {}
} else if(be->class_name()=="vector<unsigned short>") {
typedef unsigned short el_t;
typedef column_element< stl_vector<el_t> , std::vector<el_t> > ce_t;
ce_t* col = new ce_t(*le,m_index,a_bd.find_variable< std::vector<el_t> >(bl->name()));
m_cols.push_back(col);
} else if(be->class_name()=="vector<short>") {
typedef short el_t;
typedef column_element< stl_vector<el_t> , std::vector<el_t> > ce_t;
ce_t* col = new ce_t(*le,m_index,a_bd.find_variable< std::vector<el_t> >(bl->name()));
m_cols.push_back(col);
} else if(be->class_name()=="vector<unsigned int>") {
typedef unsigned int el_t;
typedef column_element< stl_vector<el_t> , std::vector<el_t> > ce_t;
ce_t* col = new ce_t(*le,m_index,a_bd.find_variable< std::vector<el_t> >(bl->name()));
m_cols.push_back(col);
} else if(be->class_name()=="vector<unsigned long>") { //beurk!
typedef uint64 el_t; //it is ok to map to an uint64 ?
typedef column_element< stl_vector<el_t> , std::vector<el_t> > ce_t;
ce_t* col = new ce_t(*le,m_index,a_bd.find_variable< std::vector<el_t> >(bl->name()));
m_cols.push_back(col);
//unsigned int n;
//if(!be->find_entry(0,n)) {}
} else if(be->class_name()=="vector<int>") {
typedef int el_t;
typedef column_element< stl_vector<el_t> , std::vector<el_t> > ce_t;
ce_t* col = new ce_t(*le,m_index,a_bd.find_variable< std::vector<el_t> >(bl->name()));
m_cols.push_back(col);
} else if(be->class_name()=="vector<float>") {
typedef float el_t;
typedef column_element< stl_vector<el_t> , std::vector<el_t> > ce_t;
ce_t* col = new ce_t(*le,m_index,a_bd.find_variable< std::vector<el_t> >(bl->name()));
m_cols.push_back(col);
} else if(be->class_name()=="vector<double>") {
typedef double el_t;
typedef column_element< stl_vector<el_t> , std::vector<el_t> > ce_t;
ce_t* col = new ce_t(*le,m_index,a_bd.find_variable< std::vector<el_t> >(bl->name()));
m_cols.push_back(col);
} else if(be->class_name()=="vector<vector<unsigned short> >") {
typedef std::vector<unsigned short> el_t;
typedef column_element< stl_vector_vector<unsigned short> , std::vector<el_t> > ce_t;
ce_t* col = new ce_t(*le,m_index,a_bd.find_variable< std::vector<el_t> >(bl->name()));
m_cols.push_back(col);
} else if(be->class_name()=="vector<vector<short> >") {
typedef std::vector<short> el_t;
typedef column_element< stl_vector_vector<short> , std::vector<el_t> > ce_t;
ce_t* col = new ce_t(*le,m_index,a_bd.find_variable< std::vector<el_t> >(bl->name()));
m_cols.push_back(col);
} else if(be->class_name()=="vector<vector<unsigned int> >") {
typedef std::vector<unsigned int> el_t;
typedef column_element< stl_vector_vector<unsigned int> , std::vector<el_t> > ce_t;
ce_t* col = new ce_t(*le,m_index,a_bd.find_variable< std::vector<el_t> >(bl->name()));
m_cols.push_back(col);
} else if(be->class_name()=="vector<vector<int> >") {
typedef std::vector<int> el_t;
typedef column_element< stl_vector_vector<int> , std::vector<el_t> > ce_t;
ce_t* col = new ce_t(*le,m_index,a_bd.find_variable< std::vector<el_t> >(bl->name()));
m_cols.push_back(col);
} else if(be->class_name()=="vector<vector<float> >") {
typedef std::vector<float> el_t;
typedef column_element< stl_vector_vector<float> , std::vector<el_t> > ce_t;
ce_t* col = new ce_t(*le,m_index,a_bd.find_variable< std::vector<el_t> >(bl->name()));
m_cols.push_back(col);
//unsigned int n;
//if(!be->find_entry(0,n)) {}
} else if(be->class_name()=="vector<vector<double> >") {
typedef std::vector<double> el_t;
typedef column_element< stl_vector_vector<double> , std::vector<el_t> > ce_t;
ce_t* col = new ce_t(*le,m_index,a_bd.find_variable< std::vector<el_t> >(bl->name()));
m_cols.push_back(col);
} else {
a_out << "tools::rroot::ntuple::initialize :"
<< " WARNING : leaf element"
<< " with name " << tools::sout(bl->name())
<< ",title " << tools::sout(bl->title())
<< " br_elem class name " << be->class_name() << "."
<< " entries " << be->entry_number() << "."
<< std::endl;
}
} else {
a_out << "tools::rroot::ntuple::initialize :"
<< " WARNING : column type not yet handled for leaf"
<< " with name " << tools::sout(bl->name())
<< " and title " << tools::sout(bl->title()) << "."
<< " s_cls() is " << tools::sout(bl->s_cls()) << "."
<< " Not fatal."
<< std::endl;
}
}
unsigned int num = m_cols.size();
if(!num) {
a_out << "tools::rroot::ntuple::initialize :"
<< " zero columns."
<< std::endl;
return false;
}
//a_out << "tools::rroot::ntuple::initialize :"
// << " number of columns " << num << "."
// << std::endl;
return true;
}
bool get_row() const {
bool status = true;
tools_vforcit(read::icol*,m_cols,it) {
if(!(*it)->fetch_entry()) status = false;
}
return status;
}
protected:
tree& m_tree;
std::vector<read::icol*> m_cols;
int64 m_index;
};
}}
#endif
@@ -0,0 +1,433 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_rall
#define tools_rroot_rall
#include "streamers"
#include "fac"
#include "tree"
#define TOOLS_RROOT_NOT_OSC
#ifndef TOOLS_RROOT_NOT_OSC
#include "osc"
#endif
namespace tools {
namespace rroot {
inline tools::rroot::TDirectory* find_dir(tools::rroot::directory& a_dir,const std::string& a_name) {
std::ostream& out = a_dir.file().out();
tools::rroot::key* k = a_dir.find_key(a_name);
if(!k) {
//out << "tools::rroot::find_dir :"
// << " " << a_name << " not a key."
// << std::endl;
return 0;
}
if(k->object_class()!=tools::rroot::TDirectory_cls()) {
out << "tools::rroot::find_dir :"
<< " key " << a_name << " not a TDirectory."
<< std::endl;
return 0;
}
uint32 sz;
char* buf = k->get_object_buffer(sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::find_dir :"
<< " can't get directory data buffer."
<< std::endl;
return 0;
}
tools::rroot::buffer b(out,a_dir.file().byte_swap(),sz,buf,k->key_length(),false);
tools::rroot::TDirectory* tdir = new tools::rroot::TDirectory(a_dir.file());
if(!tdir) return 0;
if(!tdir->stream(b)) {
out << "tools::rroot::find_dir :"
<< " can't stream TDirectory."
<< std::endl;
return 0;
}
return tdir;
}
inline bool read_key(std::ostream& a_out,
tools::rroot::key& a_key,
bool a_dump){
unsigned int sz;
char* buf = a_key.get_object_buffer(sz); //we don't have ownership of buf.
if(!buf) {
a_out << "tools::rroot::read_key :"
<< " can't get data buffer of " << a_key.object_name() << "."
<< std::endl;
return false;
}
//a_out << "tools::rroot::read_key :"
// << " get data buffer size " << sz << "."
// << std::endl;
tools::rroot::buffer b(a_out,a_key.file().byte_swap(),
sz,buf,a_key.key_length(),false);
if(a_key.object_class()==tools::rroot::TH1F_cls()) {
tools::histo::h1d* h = tools::rroot::TH1F_stream(b);
if(!h) {
a_out << "tools::rroot::read_key :"
<< " TH1F streaming failed"
<< std::endl;
} else {
if(a_dump) h->hprint(a_out);
}
delete h;
} else if(a_key.object_class()==tools::rroot::TH1D_cls()) {
tools::histo::h1d* h = tools::rroot::TH1D_stream(b);
if(!h) {
a_out << "tools::rroot::read_key :"
<< " TH1D streaming failed"
<< std::endl;
} else {
if(a_dump) h->hprint(a_out);
}
delete h;
} else if(a_key.object_class()==tools::rroot::TH2F_cls()) {
tools::histo::h2d* h = tools::rroot::TH2F_stream(b);
if(!h) {
a_out << "tools::rroot::read_key :"
<< " TH2F streaming failed"
<< std::endl;
} else {
if(a_dump) h->hprint(a_out);
}
delete h;
} else if(a_key.object_class()==tools::rroot::TH2D_cls()) {
tools::histo::h2d* h = tools::rroot::TH2D_stream(b); //we get ownership of h.
if(!h) {
a_out << "tools::rroot::read_key :"
<< " TH2D streaming failed"
<< std::endl;
} else {
if(a_dump) h->hprint(a_out);
}
delete h;
} else if(a_key.object_class()==tools::rroot::TH3D_cls()) {
tools::histo::h3d* h = tools::rroot::TH3D_stream(b); //we get ownership of h.
if(!h) {
a_out << "tools::rroot::read_key :"
<< " TH3D streaming failed"
<< std::endl;
} else {
if(a_dump) h->hprint(a_out);
}
delete h;
} else if(a_key.object_class()==tools::rroot::TProfile_cls()) {
tools::histo::p1d* p = tools::rroot::TProfile_stream(b);
if(!p) {
a_out << "tools::rroot::read_key :"
<< " TProfile streaming failed"
<< std::endl;
} else {
if(a_dump) p->hprint(a_out);
}
delete p;
} else if(a_key.object_class()==tools::rroot::TProfile2D_cls()) {
tools::histo::p2d* p = tools::rroot::TProfile2D_stream(b);
if(!p) {
a_out << "tools::rroot::read_key :"
<< " TProfile2D streaming failed"
<< std::endl;
} else {
if(a_dump) p->hprint(a_out);
}
delete p;
} else if(a_key.object_class()==TTree_cls()) {
tools::rroot::fac fac(a_key.file());
tools::rroot::tree tree(a_key.file(),fac);
if(!tree.stream(b)) {
a_out << "tools::rroot::read_key :"
<< " TTree streaming failed"
<< std::endl;
} else {
//tree->dump(a_out);
if(a_dump) {
tree.dump(a_out,""," ");
uint64 entries = tree.entries();
/*
{for(uint32 j=0;j<10;j++){ //to test memory.
for(uint32 i=0;i<entries;i++){
uint32 n;
if(!tree.find_entry(i,n)) {
a_out << " can't find entry " << i
<< std::endl;
}
}
}}
*/
{for(uint32 i=0;i<5;i++){
if(!tree.show(a_out,i)) {
a_out << " show failed for entry " << i
<< std::endl;
}
}}
{for(uint64 i=mx<int64>(5,entries-5);i<entries;i++){
if(!tree.show(a_out,(uint32)i)) {
a_out << " show failed for entry " << i
<< std::endl;
}
}}
}
}
#ifndef TOOLS_RROOT_NOT_OSC
} else if(a_key.object_class()==tools::osc::s_h1d()) {
tools::histo::h1d h("",10,0,1);
if(!from_osc(b,tools::osc::s_h1d(),h)) {
a_out << "tools::rroot::read_key :"
<< " " << tools::osc::s_h1d() << " streaming failed"
<< std::endl;
} else {
if(a_dump) h.hprint(a_out);
}
} else if(a_key.object_class()==tools::osc::s_h2d()) {
tools::histo::h2d h("",10,0,1,10,0,1);
if(!from_osc(b,tools::osc::s_h2d(),h)) {
a_out << "tools::rroot::read_key :"
<< " " << tools::osc::s_h2d() << " streaming failed"
<< std::endl;
} else {
if(a_dump) h.hprint(a_out);
}
} else if(a_key.object_class()==tools::osc::s_h3d()) {
tools::histo::h3d h("",10,0,1,10,0,1,10,0,1);
if(!from_osc(b,tools::osc::s_h3d(),h)) {
a_out << "tools::rroot::read_key :"
<< " " << tools::osc::s_h3d() << " streaming failed"
<< std::endl;
} else {
if(a_dump) h.hprint(a_out);
}
} else if(a_key.object_class()==tools::osc::s_p1d()) {
tools::histo::p1d h("",10,0,1);
if(!from_osc(b,tools::osc::s_p1d(),h)) {
a_out << "tools::rroot::read_key :"
<< " " << tools::osc::s_p1d() << " streaming failed"
<< std::endl;
} else {
if(a_dump) h.hprint(a_out);
}
} else if(a_key.object_class()==tools::osc::s_p2d()) {
tools::histo::p2d h("",10,0,1,10,0,1);
if(!from_osc(b,tools::osc::s_p2d(),h)) {
a_out << "tools::rroot::read_key :"
<< " " << tools::osc::s_p2d() << " streaming failed"
<< std::endl;
} else {
if(a_dump) h.hprint(a_out);
}
#endif
} else if(a_key.object_class()==tools::rroot::TDirectory_cls()) {
//we should not pass here.
} else {
a_out << "tools::rroot::read_key :"
<< " dont't know how to read key with object class "
<< tools::sout(a_key.object_class())
<< std::endl;
}
return true;
}
inline tools::histo::h1d* key_to_h1d(tools::rroot::key& a_key){
std::ostream& out = a_key.file().out();
if((a_key.object_class()!=tools::rroot::TH1D_cls())&&
(a_key.object_class()!=tools::rroot::TH1F_cls())
) {
out << "tools::rroot::from(h1d) :"
<< " key not a TH1D and not a TH1F."
<< std::endl;
return 0;
}
unsigned int sz;
char* buf = a_key.get_object_buffer(sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::from(h1d) :"
<< " can't get data buffer of " << a_key.object_name() << "."
<< std::endl;
return 0;
}
tools::rroot::buffer b(out,a_key.file().byte_swap(),sz,buf,a_key.key_length(),false);
if(a_key.object_class()==tools::rroot::TH1D_cls()) {
return tools::rroot::TH1D_stream(b);
} else {
return tools::rroot::TH1F_stream(b);
}
}
inline tools::histo::h2d* key_to_h2d(tools::rroot::key& a_key){
std::ostream& out = a_key.file().out();
if(a_key.object_class()!=tools::rroot::TH2D_cls()) {
out << "tools::rroot::from(h1d) :"
<< " key not a TH2D."
<< std::endl;
return 0;
}
unsigned int sz;
char* buf = a_key.get_object_buffer(sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::from(h2d) :"
<< " can't get data buffer of " << a_key.object_name() << "."
<< std::endl;
return 0;
}
tools::rroot::buffer b(out,a_key.file().byte_swap(),sz,buf,a_key.key_length(),false);
return tools::rroot::TH2D_stream(b);
}
inline tools::histo::h3d* key_to_h3d(tools::rroot::key& a_key){
std::ostream& out = a_key.file().out();
if(a_key.object_class()!=tools::rroot::TH3D_cls()) {
out << "tools::rroot::from(h1d) :"
<< " key not a TH3D."
<< std::endl;
return 0;
}
unsigned int sz;
char* buf = a_key.get_object_buffer(sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::from(h3d) :"
<< " can't get data buffer of " << a_key.object_name() << "."
<< std::endl;
return 0;
}
tools::rroot::buffer b(out,a_key.file().byte_swap(),sz,buf,a_key.key_length(),false);
return tools::rroot::TH3D_stream(b);
}
inline tools::histo::p1d* key_to_p1d(tools::rroot::key& a_key){
std::ostream& out = a_key.file().out();
if(a_key.object_class()!=tools::rroot::TProfile_cls()) {
out << "tools::rroot::from(p1d) :"
<< " key not a TProfile."
<< std::endl;
return 0;
}
unsigned int sz;
char* buf = a_key.get_object_buffer(sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::from(p1d) :"
<< " can't get data buffer of " << a_key.object_name() << "."
<< std::endl;
return 0;
}
tools::rroot::buffer b(out,a_key.file().byte_swap(),sz,buf,a_key.key_length(),false);
return tools::rroot::TProfile_stream(b);
}
inline tools::histo::p2d* key_to_p2d(tools::rroot::key& a_key){
std::ostream& out = a_key.file().out();
if(a_key.object_class()!=tools::rroot::TProfile2D_cls()) {
out << "tools::rroot::from(p2d) :"
<< " key not a TProfile2D."
<< std::endl;
return 0;
}
unsigned int sz;
char* buf = a_key.get_object_buffer(sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::from(p2d) :"
<< " can't get data buffer of " << a_key.object_name() << "."
<< std::endl;
return 0;
}
tools::rroot::buffer b(out,a_key.file().byte_swap(),sz,buf,a_key.key_length(),false);
return tools::rroot::TProfile2D_stream(b);
}
inline void read(std::ostream& a_out,
tools::rroot::ifile& a_file,
const std::vector<tools::rroot::key*>& a_keys,
bool a_recursive,
bool a_ls,
bool a_dump,
unsigned int a_spaces) {
{std::vector<tools::rroot::key*>::const_iterator it;
for(it=a_keys.begin();it!=a_keys.end();++it) {
tools::rroot::key& k = *(*it);
if(k.object_class()!=tools::rroot::TDirectory_cls()) {
if(a_ls||a_dump) {
{for(unsigned int index=0;index<a_spaces;index++) a_out << " ";}
std::string label = k.object_name();
a_out << "object : " << sout(label)
<< ", class : " << k.object_class()
<< std::endl;
//k.dump(a_out);
}
if(!read_key(a_out,k,a_dump)) return;
}
}}
{std::vector<tools::rroot::key*>::const_iterator it;
for(it=a_keys.begin();it!=a_keys.end();++it) {
tools::rroot::key& k = *(*it);
if(k.object_class()==tools::rroot::TDirectory_cls()) {
if(a_ls||a_dump) {
{for(unsigned int index=0;index<a_spaces;index++) a_out << " ";}
std::string label = k.object_name();
a_out << "directory : " << label << std::endl;
}
if(!a_recursive) continue;
tools::uint32 sz;
char* buf = k.get_object_buffer(sz);
if(!buf) {
a_out << "read :"
<< " can't get directory data buffer."
<< std::endl;
} else {
tools::rroot::buffer b(a_out,a_file.byte_swap(),
sz,buf,k.key_length(),false);
tools::rroot::TDirectory dir(a_file);
if(!dir.stream(b)) {
a_out << "read :"
<< " can't stream TDirectory."
<< std::endl;
} else {
const std::vector<tools::rroot::key*>& keys = dir.keys();
read(a_out,a_file,keys,a_recursive,a_ls,a_dump,a_spaces+1);
}
}
}
}}
}
}}
#endif
@@ -0,0 +1,411 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_rbuf
#define tools_rroot_rbuf
#include "../pointer"
#include "../stype"
#ifdef TOOLS_MEM
#include "../mem"
#endif
#include <ostream>
#include <vector>
#include <cstring> //memcpy
namespace tools {
namespace rroot {
class rbuf {
/////////////////////////////////////////////////////////
/// swap ////////////////////////////////////////////////
/////////////////////////////////////////////////////////
// NOTE : on most common platforms (including Android, iPad)
// CERN-ROOT byte swaps ! (Bad luck). We have arranged to
// optimize this operation. The below "_swap_" functions
// do not have local variables and manipulates pointers
// directly.
static void read_swap_2(char* a_pos,char* a_x) {
*a_x++ = *(a_pos+1);
*a_x++ = *a_pos;
}
static void read_swap_4(char* a_pos,char* a_x) {
a_pos += 3;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos;
}
static void read_swap_8(char* a_pos,char* a_x) {
a_pos += 7;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos--;
*a_x++ = *a_pos;
}
/////////////////////////////////////////////////////////
/// nswp ////////////////////////////////////////////////
/////////////////////////////////////////////////////////
static void read_nswp_2(char* a_pos,char* a_x) {
::memcpy(a_x,a_pos,2);
}
static void read_nswp_4(char* a_pos,char* a_x) {
::memcpy(a_x,a_pos,4);
}
static void read_nswp_8(char* a_pos,char* a_x) {
::memcpy(a_x,a_pos,8);
}
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
static const std::string& s_class() {
static const std::string s_v("tools::rroot::rbuf");
return s_v;
}
typedef void (*r_2_func)(char*,char*);
typedef void (*r_4_func)(char*,char*);
typedef void (*r_8_func)(char*,char*);
public:
rbuf(std::ostream& a_out,bool a_byte_swap,const char* a_eob,char*& a_pos)
:m_out(a_out)
,m_byte_swap(a_byte_swap)
,m_eob(a_eob)
,m_pos(a_pos)
,m_r_2_func(0)
,m_r_4_func(0)
,m_r_8_func(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
set_byte_swap(a_byte_swap);
}
virtual ~rbuf(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
rbuf(const rbuf& a_from)
:m_out(a_from.m_out)
,m_byte_swap(a_from.m_byte_swap)
,m_eob(a_from.m_eob)
,m_pos(a_from.m_pos)
,m_r_2_func(a_from.m_r_2_func)
,m_r_4_func(a_from.m_r_4_func)
,m_r_8_func(a_from.m_r_8_func)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
set_byte_swap(a_from.m_byte_swap);
}
rbuf& operator=(const rbuf& a_from){
set_byte_swap(a_from.m_byte_swap);
m_eob = a_from.m_eob;
//m_pos is a ref.
m_r_2_func = a_from.m_r_2_func;
m_r_4_func = a_from.m_r_4_func;
m_r_8_func = a_from.m_r_8_func;
return *this;
}
public:
std::ostream& out() const {return m_out;}
void skip(unsigned int a_num) {m_pos += a_num;}
void set_eob(const char* a_eob){m_eob = a_eob;}
char*& pos() {return m_pos;}
const char* eob() const {return m_eob;}
void set_byte_swap(bool a_value) {
m_byte_swap = a_value;
if(m_byte_swap) {
m_r_2_func = read_swap_2;
m_r_4_func = read_swap_4;
m_r_8_func = read_swap_8;
} else {
m_r_2_func = read_nswp_2;
m_r_4_func = read_nswp_4;
m_r_8_func = read_nswp_8;
}
}
public:
bool read(unsigned char& a_x) {
if(!_check_eob<unsigned char>(a_x)) return false;
a_x = *m_pos++;
return true;
}
bool read(unsigned short& a_x) {
if(!_check_eob<unsigned short>(a_x)) return false;
m_r_2_func(m_pos,(char*)&a_x);
m_pos += sizeof(unsigned short);
return true;
}
bool read(unsigned int& a_x) {
if(!_check_eob<unsigned int>(a_x)) return false;
m_r_4_func(m_pos,(char*)&a_x);
m_pos += sizeof(unsigned int);
return true;
}
bool read(uint64& a_x){
if(!_check_eob<uint64>(a_x)) return false;
m_r_8_func(m_pos,(char*)&a_x);
m_pos += 8;
return true;
}
bool read(float& a_x) {
if(!_check_eob<float>(a_x)) return false;
m_r_4_func(m_pos,(char*)&a_x);
m_pos += sizeof(float);
return true;
}
bool read(double& a_x) {
if(!_check_eob<double>(a_x)) return false;
m_r_8_func(m_pos,(char*)&a_x);
m_pos += sizeof(double);
return true;
}
bool read(char& a_x) {
if(!_check_eob<char>(a_x)) return false;
a_x = *m_pos++;
return true;
}
bool read(short& a_x) {
if(!_check_eob<short>(a_x)) return false;
m_r_2_func(m_pos,(char*)&a_x);
m_pos += sizeof(short);
return true;
}
bool read(int& a_x) {
if(!_check_eob<int>(a_x)) return false;
m_r_4_func(m_pos,(char*)&a_x);
m_pos += sizeof(int);
return true;
}
bool read(int64& a_x){
if(!_check_eob<int64>(a_x)) return false;
m_r_8_func(m_pos,(char*)&a_x);
m_pos += 8;
return true;
}
bool read(std::string& a_x) {
unsigned char nwh;
if(!read(nwh)) {a_x.clear();return false;}
int nchars;
if(nwh == 255) {
if(!read(nchars)) {a_x.clear();return false;}
} else {
nchars = nwh;
}
if(nchars<0) {
m_out << s_class() << "::read(string) :"
<< " negative char number " << nchars << "." << std::endl;
a_x.clear();
return false;
}
if((m_pos+nchars)>m_eob) {
m_out << s_class() << "::read(string) :"
<< " try to access out of buffer " << long2s(nchars) << " bytes "
<< " (pos=" << char_p2s(m_pos)
<< ", eob=" << char_p2s(m_eob) << ")." << std::endl;
a_x.clear();
return false;
}
a_x.resize(nchars);
::memcpy((char*)a_x.c_str(),m_pos,nchars);
m_pos += nchars;
return true;
}
bool read(bool& x){
unsigned char uc = 0;
bool status = read(uc);
x = uc?true:false;
return status;
}
bool read(std::vector<std::string>& a_a) {
int n;
if(!read(n)) {a_a.clear();return false;}
for(int index=0;index<n;index++) {
std::string s;
if(!read(s)) {a_a.clear();return false;}
a_a.push_back(s);
}
return true;
}
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
bool read_fast_array(bool* b,uint32 n){
if(!n) return true;
uint32 l = n * sizeof(unsigned char);
if(!check_eob(l)) return false;
for(uint32 i = 0; i < n; i++) {
unsigned char uc;
if(!read(uc)) return false;
b[i] = uc?true:false;
}
return true;
}
bool read_fast_array(char* c,uint32 n){
if(!n) return true;
uint32 l = n * sizeof(char);
if(!check_eob(l)) return false;
::memcpy(c,m_pos,l);
m_pos += l;
return true;
}
bool read_fast_array(unsigned char* c,uint32 n){
if(!n) return true;
uint32 l = n * sizeof(unsigned char);
if(!check_eob(l)) return false;
::memcpy(c, m_pos, l);
m_pos += l;
return true;
}
template <class T>
bool read_fast_array(T* a_a,uint32 a_n){
if(!a_n) return true;
uint32 l = a_n * sizeof(T);
if(!check_eob(l)) {
m_out << s_class() << "::read_fast_array :"
<< " try to access out of buffer " << long2s(l) << " bytes "
<< " (pos=" << char_p2s(m_pos)
<< ", eob=" << char_p2s(m_eob) << ")." << std::endl;
return false;
}
if(m_byte_swap) {
for(uint32 i=0;i<a_n;i++) {
if(!read(*(a_a+i))) return false;
}
} else {
::memcpy(a_a,m_pos,l);
m_pos += l;
}
return true;
}
template <class T>
bool read_array(uint32 a_sz,T*& a_a,uint32& a_n) {
a_n = 0;
{int n;
if(!read(n)) {a_n = 0;return false;}
a_n = n;}
if(!a_n) return true;
uint32 l = a_n * sizeof(T);
if(!check_eob(l)) return false;
bool owner = false;
if(!a_a) {
//ignore a_sz
a_a = new T[a_n];
if(!a_a) {a_n=0;return false;}
owner = true;
} else {
if(a_n>a_sz) return false;
}
if(m_byte_swap) {
for(uint32 i=0;i<a_n;i++) {
if(!read(*(a_a+i))) {
if(owner) {delete [] a_a;a_a = 0;}
a_n = 0;
return false;
}
}
} else {
::memcpy(a_a,m_pos,l);
m_pos += l;
}
return true;
}
template <class T>
bool read_array(std::vector<T>& a_v) {
a_v.clear();
T* buffer = 0;
uint32 n;
if(!read_array(0,buffer,n)) return false;
if(!buffer) return true;
a_v.resize(n);
for(uint32 index=0;index<n;index++) {
a_v[index] = buffer[index];
}
delete [] buffer;
return true;
}
template <class T>
bool read_array2(std::vector< std::vector<T> >& a_v) {
int n;
if(!read(n)) {a_v.clear();return false;}
a_v.resize(n);
for(int index=0;index<n;index++) {
if(!read_array(a_v[index])) return false;
}
return true;
}
bool check_eob(uint32 n){
if((m_pos+n)>m_eob) {
m_out << "tools::rroot::rbuf::check_eob :"
<< " try to access out of buffer " << n << " bytes."
<< std::endl;
return false;
}
return true;
}
protected:
template <class T>
bool _check_eob(T& a_x){
if((m_pos+sizeof(T))>m_eob) {
a_x = T();
m_out << s_class() << " : " << stype(T()) << " : "
<< " try to access out of buffer " << long2s(sizeof(T)) << " bytes"
<< " (pos=" << char_p2s(m_pos)
<< ", eob=" << char_p2s(m_eob) << ")." << std::endl;
return false;
}
return true;
}
protected:
std::ostream& m_out;
bool m_byte_swap;
const char* m_eob;
char*& m_pos;
r_2_func m_r_2_func;
r_4_func m_r_4_func;
r_8_func m_r_8_func;
};
}}
#endif
@@ -0,0 +1,21 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_seek
#define tools_rroot_seek
//////////////////////////////////////////////////////////////////////////
// Definition of a file pointer . //
//////////////////////////////////////////////////////////////////////////
#include "../typedefs"
namespace tools {
namespace rroot {
typedef tools::int64 seek;
typedef int seek32;
}}
#endif
@@ -0,0 +1,274 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_stl_vector
#define tools_rroot_stl_vector
#include "buffer"
#include "cids"
#include "../stype"
#include "../scast"
#include "../cids"
namespace tools {
namespace rroot {
template <class T>
class stl_vector : public virtual iro, public std::vector<T> {
static const std::string& s_store_class() {
static const std::string s_v("vector<"+stype(T())+">");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::stl_vector<"+stype(T())+">");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast< stl_vector<T> >(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return stl_vector_cid()+_cid(T());}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast< stl_vector<T> >(this,a_class)) {return p;}
return 0;
}
virtual iro* copy() const {return new stl_vector<T>(*this);}
virtual bool stream(buffer& a_buffer) {
std::vector<T>::clear();
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
//::printf("debug : stl_vector::stream<%s> : version %d, byte count %d\n",
// stype(T()).c_str(),v,c);
unsigned int num;
if(!a_buffer.read(num)) return false;
//::printf("debug : stl_vector : %d\n",num);
if(num) {
T* vec = new T[num];
if(!a_buffer.read_fast_array<T>(vec,num)) {
delete [] vec;
return false;
}
std::vector<T>::resize(num);
T* pos = vec;
for(unsigned int index=0;index<num;index++,pos++) {
std::vector<T>::operator[](index) = *pos;
}
delete [] vec;
}
return a_buffer.check_byte_count(s,c,s_store_class());
}
public:
stl_vector(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~stl_vector(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
stl_vector(const stl_vector& a_from)
:iro(a_from)
,std::vector<T>(a_from)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
stl_vector& operator=(const stl_vector& a_from){
std::vector<T>::operator=(a_from);
return *this;
}
};
template <class T>
class stl_vector_vector
:public virtual iro
,public std::vector< std::vector<T> >
{
static const std::string& s_store_class() {
static const std::string s_v("vector<vector<"+stype(T())+"> >");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v
("tools::rroot::stl_vector_vector<"+stype(T())+">");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p=cmp_cast< stl_vector_vector<T> >(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return stl_vector_vector_cid()+_cid(T());}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast< stl_vector_vector<T> >(this,a_class)) {return p;}
return 0;
}
virtual iro* copy() const {return new stl_vector_vector<T>(*this);}
virtual bool stream(buffer& a_buffer) {
typedef typename std::vector<T> vec_t;
std::vector<vec_t>::clear();
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
//::printf("debug : stl_vector_vector::stream<%s> : version %d, byte count %d\n",stype(T()).c_str(),v,c);
unsigned int vecn;
if(!a_buffer.read(vecn)) return false;
std::vector<vec_t>::resize(vecn);
//::printf("debug : stl_vector_vector : %d\n",vecn);
for(unsigned int veci=0;veci<vecn;veci++) {
vec_t& elem = std::vector<vec_t>::operator[](veci);
unsigned int num;
if(!a_buffer.read(num)) {
std::vector<vec_t>::clear();
return false;
}
//::printf("debug : stl_vector_vector : index %d num %d\n",veci,num);
if(num) {
T* vec = new T[num];
if(!a_buffer.read_fast_array<T>(vec,num)) {
delete [] vec;
std::vector<vec_t>::clear();
return false;
}
elem.resize(num);
T* pos = vec;
for(unsigned int index=0;index<num;index++,pos++) elem[index] = *pos;
delete [] vec;
}
}
return a_buffer.check_byte_count(s,c,s_store_class());
}
public:
stl_vector_vector(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~stl_vector_vector(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
stl_vector_vector(const stl_vector_vector& a_from)
:iro(a_from)
,std::vector< std::vector<T> >(a_from)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
stl_vector_vector& operator=(const stl_vector_vector& a_from){
std::vector< std::vector<T> >::operator=(a_from);
return *this;
}
};
class stl_vector_string : public virtual iro, public std::vector<std::string> {
static const std::string& s_store_class() {
static const std::string s_v("vector<string>");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::stl_vector_string");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<stl_vector_string>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return stl_vector_string_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<stl_vector_string>(this,a_class)) {return p;}
return 0;
}
virtual iro* copy() const {return new stl_vector_string(*this);}
virtual bool stream(buffer& a_buffer) {
std::vector<std::string>::clear();
//uint32 startpos = a_buffer.length();
//WARNING : not tested yet.
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
//::printf("debug : stl_vector_string::stream : version %d, byte count %d\n",v,c);
unsigned int num;
if(!a_buffer.read(num)) return false;
//::printf("debug : stl_vector_string : %d\n",num);
std::vector<std::string>::resize(num);
for(unsigned int index=0;index<num;index++) {
std::string& vs = std::vector<std::string>::operator[](index);
if(!a_buffer.read(vs)) {
std::vector<std::string>::clear();
return false;
}
}
//a_buffer.set_offset(startpos+c+sizeof(unsigned int));
return a_buffer.check_byte_count(s,c,s_store_class());
}
public:
stl_vector_string(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~stl_vector_string(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
stl_vector_string(const stl_vector_string& a_from)
:iro(a_from)
,std::vector<std::string>(a_from)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
stl_vector_string& operator=(const stl_vector_string& a_from){
std::vector<std::string>::operator=(a_from);
return *this;
}
};
}}
#endif
@@ -0,0 +1,980 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_streamers
#define tools_rroot_streamers
#include "named"
#include "date"
#include "directory"
#include "graph"
#include "clss"
#include "info"
#include "dummy"
#include "../sout"
#include "../vmanip"
//#include "../histo/histo_data"
#include "../histo/profile_data"
#include "../histo/h1d"
#include "../histo/h2d"
#include "../histo/h3d"
#include "../histo/p1d"
#include "../histo/p2d"
#include <list>
#include <cmath> //::log10, ::fabs.
//#include "../rtausmed"
namespace tools {
namespace rroot {
typedef tools::histo::histo_data<double,unsigned int,unsigned int,double> hd_data;
typedef tools::histo::profile_data<double,unsigned int,unsigned int,double,double> pd_data;
inline bool AttAxis_stream(buffer& a_buffer){
int fNdivisions = 510; //Number of divisions(10000*n3 + 100*n2 + n1)
short fAxisColor = 1; //color of the line axis
short fLabelColor = 1; //color of labels
short fLabelFont = 62; //font for labels
float fLabelOffset = 0.005F; //offset of labels
float fLabelSize = 0.04F; //size of labels
float fTickLength = 0.03F; //length of tick marks
float fTitleOffset = 1; //offset of axis title
float fTitleSize = 0.04F; //size of axis title
short fTitleColor = 1; //color of axis title
short fTitleFont = 62; //font for axis title
// Version 4 streaming (ROOT/v3-00-6).
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
if(!a_buffer.read(fNdivisions)) return false;
if(!a_buffer.read(fAxisColor)) return false;
if(!a_buffer.read(fLabelColor)) return false;
if(!a_buffer.read(fLabelFont)) return false;
if(!a_buffer.read(fLabelOffset)) return false;
if(!a_buffer.read(fLabelSize)) return false;
if(!a_buffer.read(fTickLength)) return false;
if(!a_buffer.read(fTitleOffset)) return false;
if(!a_buffer.read(fTitleSize)) return false;
if(!a_buffer.read(fTitleColor)) return false;
if(!a_buffer.read(fTitleFont)) return false;
if(!a_buffer.check_byte_count(s, c,"TAttAxis")) return false;
return true;
}
class dummy_fac : public virtual ifac {
public: //ifac
virtual iro* create(const std::string& a_class,const args& a_args) {
if(tools::rcmp(a_class,"TGraph")) { //for TH_read_1D/List.
return new graph();
// for read_sinfos() :
} else if(tools::rcmp(a_class,"TStreamerInfo")) {
return new StreamerInfo(*this);
} else if(tools::rcmp(a_class,"TObjArray")) {
std::string* sc = ifac::arg_class(a_args);
if(sc) {
if((*sc)==streamer_element::s_class()){
return new ObjArray<streamer_element>(*this,true);
} else {
m_out << "tools::rroot::dummy_fac::create :"
<< " Can't create TObjArray of " << *sc << "."
<< std::endl;
return 0;
}
} else {
return new iros(*this,true);
}
} else if(tools::rcmp(a_class,"TStreamerBase")
||tools::rcmp(a_class,"TStreamerBasicType")
||tools::rcmp(a_class,"TStreamerBasicPointer")
||tools::rcmp(a_class,"TStreamerObjectAny")
||tools::rcmp(a_class,"TStreamerObject")
||tools::rcmp(a_class,"TStreamerObjectPointer")
||tools::rcmp(a_class,"TStreamerString")
||tools::rcmp(a_class,"TStreamerSTL")
||tools::rcmp(a_class,"TStreamerLoop")
||tools::rcmp(a_class,"TList")
) {
return new dummy_streamer_element();
} else {
m_out << "tools::rroot::dummy_fac::create :"
<< " dummy. Can't create object of class " << sout(a_class) << "."
<< std::endl;
}
return 0;
}
virtual void destroy(iro*& a_obj) {delete a_obj;a_obj = 0;}
public:
dummy_fac(std::ostream& a_out):m_out(a_out){}
virtual ~dummy_fac(){}
protected:
dummy_fac(const dummy_fac& a_from): ifac(a_from),m_out(a_from.m_out){}
dummy_fac& operator=(const dummy_fac&){return *this;}
protected:
std::ostream& m_out;
};
inline bool Axis_stream(buffer& a_buffer,tools::histo::axis<double,unsigned int>& a_fAxis){
// Version 6 streaming (ROOT/v3-00-6).
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
std::string name;
std::string title;
if(!Named_stream(a_buffer,name,title)) return false;
if(!AttAxis_stream(a_buffer)) return false;
int number;
if(!a_buffer.read(number)) return false;
double min;
if(!a_buffer.read(min)) return false;
double max;
if(!a_buffer.read(max)) return false;
//printf("debug : BatchLab::RioTH::streamTAxis : %d %g %g\n",
// number,min,max);
std::vector<double> edges;
if(!Array_stream<double>(a_buffer,edges)) return false; //fXbins TArrayD
int edgen = edges.size();
if(edgen<=0) {
a_fAxis.configure(number,min,max);
} else {
std::vector<double> vedges;
for(int index=0;index<edgen;index++) {
vedges.push_back(edges[index]);
}
a_fAxis.configure(vedges);
}
int First;
if(!a_buffer.read(First)) return false;
int Last;
if(!a_buffer.read(Last)) return false;
if(v>=8) { //fBits2.
unsigned short dummy;
if(!a_buffer.read(dummy)) return false;
}
//Bool_t
unsigned char TimeDisplay;
if(!a_buffer.read(TimeDisplay)) return false;
//TString
std::string TimeFormat;
if(!a_buffer.read(TimeFormat)) return false;
if(v>=7) {
//THashList*
dummy_fac fac(a_buffer.out());
if(!dummy_TXxx_pointer_stream(a_buffer,fac)) return false;
}
if(!a_buffer.check_byte_count(s,c,"TAxis")) return false;
return true;
}
inline bool null_epsil(double a_1,double a_2,double a_prec = -5) {
return (::log10(::fabs(a_1-a_2))<a_prec?true:false);
}
inline bool TH_read_1D(buffer& a_buffer,hd_data& a_data,
double& a_entries,double& a_Sw,double& a_Sw2,double& a_Sxw,double& a_Sx2w){
a_entries = 0;
a_Sw = 0;
a_Sw2 = 0;
a_Sxw = 0;
a_Sx2w = 0;
unsigned int s, c;
short vers;
if(!a_buffer.read_version(vers,s,c)) return false;
//printf("debug : BatchLab::Rio::TH::streamTH1 : version %d\n",vers);
// Version 3 streaming (ROOT/v3-00-6).
std::string name;
std::string title;
if(!Named_stream(a_buffer,name,title)) return false;
a_data.m_title = title;
{short color,style,width;
if(!AttLine_stream(a_buffer,color,style,width)) return false;}
{short color,style;
if(!AttFill_stream(a_buffer,color,style)) return false;}
if(!AttMarker_stream(a_buffer)) return false;
int Ncells;
if(!a_buffer.read(Ncells)) return false;
//fXAxis
if(!Axis_stream(a_buffer,a_data.m_axes[0])) return false;
a_data.m_axes[0].m_offset = 1;
if(a_data.m_dimension==2) {
if(!Axis_stream(a_buffer,a_data.m_axes[1])) return false; //fYAxis
a_data.m_axes[1].m_offset =
a_data.m_axes[0].m_offset * (a_data.m_axes[0].bins()+2);
tools::histo::axis<double,unsigned int> dummy;
if(!Axis_stream(a_buffer,dummy)) return false; //fZAxis
} else {
tools::histo::axis<double,unsigned int> dummy;
if(!Axis_stream(a_buffer,dummy)) return false; //fYAxis
if(!Axis_stream(a_buffer,dummy)) return false; //fZAxis
}
short barOffset;
if(!a_buffer.read(barOffset)) return false;
short barWidth;
if(!a_buffer.read(barWidth)) return false;
if(!a_buffer.read(a_entries)) return false;
if(!a_buffer.read(a_Sw)) return false; //fTsumw
//printf("debug : BatchLab::Rio::TH::streamTH1 : \"%s\" %g %g\n",
// a_data.m_title.c_str(),fEntries,fSw);
if(!a_buffer.read(a_Sw2)) return false;
if(!a_buffer.read(a_Sxw)) return false;
if(!a_buffer.read(a_Sx2w)) return false;
double max;
if(!a_buffer.read(max)) return false;
double min;
if(!a_buffer.read(min)) return false;
double NormFactor;
if(!a_buffer.read(NormFactor)) return false;
{std::vector<double> v;
if(!Array_stream<double>(a_buffer,v)) return false;} //fContour TArrayD
std::vector<double> sumw2; //fSumw2 TArrayD
if(!Array_stream<double>(a_buffer,sumw2)) return false;
{std::string opt;
if(!a_buffer.read(opt)) return false; //TString fOption
//look if it is an "annotation trick" :
//if(opt.size()&&(opt[0]==0)) {
// fAnnotation = opt.substr(1,opt.size()-1);
//}
}
{dummy_fac fac(a_buffer.out());
List dummy(fac,true);
if(!dummy.stream(a_buffer)) {
a_buffer.out() << "tools::rroot::TH_read_1D :"
<< " List stream failed."
<< std::endl;
return false;
}} //Functions
if(vers>=4) {
int BufferSize;
if(!a_buffer.read(BufferSize)) return false;
//Double_t* Buffer; //[fBufferSize]
if(!dummy_array_stream<double>(a_buffer,BufferSize)) return false;
}
if(vers>=7) {
//EBinErrorOpt fBinStatErrOpt;
int dummy;
if(!a_buffer.read(dummy)) return false;
}
// Add two for outflows.
if(a_data.m_dimension==1) {
a_data.m_bin_number = a_data.m_axes[0].m_number_of_bins + 2;
} else if(a_data.m_dimension==2) {
a_data.m_bin_number =
(a_data.m_axes[0].m_number_of_bins + 2) *
(a_data.m_axes[1].m_number_of_bins + 2);
}
unsigned int binn = a_data.m_bin_number;
a_data.m_bin_Sw2.resize(binn,0);
if(binn==sumw2.size()) {
for(unsigned int index=0;index<binn;index++){
a_data.m_bin_Sw2[index] = sumw2[index];
}
}
if(!a_buffer.check_byte_count(s,c,"TH")) return false;
return true;
}
inline bool TH_read_2D(buffer& a_buffer,hd_data& a_data,
double& a_entries,double& a_Sw,double& a_Sw2,
double& a_Sxw,double& a_Sx2w,double& a_Syw,double& a_Sy2w){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return false;
//printf("debug : BatchLab::Rio::TH::streamTH2 : version %d\n",v);
// Version 3 streaming (ROOT/v3-00-6).
if(!TH_read_1D(a_buffer,a_data,a_entries,a_Sw,a_Sw2,a_Sxw,a_Sx2w)) return false;
// the upper set :
//data.m_title
//data.m_bin_number
//data.m_axes
//data.m_bin_Sw2
double ScaleFactor;
if(!a_buffer.read(ScaleFactor)) return false;
if(!a_buffer.read(a_Syw)) return false;
if(!a_buffer.read(a_Sy2w)) return false;
double Tsumwxy;
if(!a_buffer.read(Tsumwxy)) return false;
if(!a_buffer.check_byte_count(s,c,"TH2")) return false;
return true;
}
inline bool TH_read_3D(buffer& a_buffer,hd_data& a_data,
double& a_entries,double& a_Sw,double& a_Sw2,
double& a_Sxw,double& a_Sx2w,
double& a_Syw,double& a_Sy2w,
double& a_Szw,double& a_Sz2w){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return false;
if(!TH_read_1D(a_buffer,a_data,a_entries,a_Sw,a_Sw2,a_Sxw,a_Sx2w)) return false;
if(!Att3D_stream(a_buffer)) return false;
// the upper set :
//data.m_title
//data.m_bin_number
//data.m_axes
//data.m_bin_Sw2
if(!a_buffer.read(a_Syw)) return false;
if(!a_buffer.read(a_Sy2w)) return false;
double Tsumwxy;
if(!a_buffer.read(Tsumwxy)) return false;
if(!a_buffer.read(a_Szw)) return false;
if(!a_buffer.read(a_Sz2w)) return false;
double Tsumwxz;
if(!a_buffer.read(Tsumwxz)) return false;
double Tsumwyz;
if(!a_buffer.read(Tsumwyz)) return false;
if(!a_buffer.check_byte_count(s,c,"TH3")) return false;
return true;
}
inline tools::histo::h1d* TH1F_stream(buffer& a_buffer){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return 0;
//printf("debug : BatchLab::Rio::TH1F::stream : version %d\n",v);
// Version 1 streaming (ROOT/v3-00-6).
// Now we have to reconstruct a valid Histogram from a_buffer :
hd_data data;
data.m_dimension = 1;
//data.m_coords.resize(data.m_dimension,0);
//data.m_ints.resize(data.m_dimension,0);
data.m_axes.resize(1);
double fEntries; //in range + outflow.
double fSw; //in range.
double fSw2; //in range.
double fSxw; //in range.
double fSx2w; //in range.
if(!TH_read_1D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w)) return 0;
// the upper set :
//data.m_title
//data.m_bin_number
//data.m_axes
//data.m_bin_Sw2
std::vector<float> bins; //fArray TArrayF
if(!Array_stream<float>(a_buffer,bins)) return 0;
if(!a_buffer.check_byte_count(s,c,"TH1F")) return 0;
unsigned int binn = data.m_bin_number;
//printf("debug : BatchLab::Rio::TH1F::stream : histo bins %d\n",binn);
data.m_bin_Sw.resize(binn,0);
{for(unsigned int index=0;index<binn;index++){
data.m_bin_Sw[index] = double(bins[index]);
}}
data.m_bin_entries.resize(binn,0);
{std::vector<double> empty;
empty.resize(1,0);
data.m_bin_Sxw.resize(binn,empty);
data.m_bin_Sx2w.resize(binn,empty);}
data.m_all_entries = static_cast<unsigned int>(fEntries);
data.m_in_range_entries = 0;
data.m_in_range_Sw = fSw;
data.m_in_range_Sw2 = fSw2;
data.m_in_range_Sxw.resize(1,0);
data.m_in_range_Sx2w.resize(1,0);
data.m_in_range_Sxw[0] = fSxw;
data.m_in_range_Sx2w[0] = fSx2w;
tools::histo::h1d* h = new tools::histo::h1d("",10,0,1);
h->copy_from_data(data);
return h; //give ownership to caller.
}
inline tools::histo::h1d* TH1D_stream(buffer& a_buffer){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return 0;
//printf("debug : BatchLab::Rio::TH1D::stream : version %d\n",v);
// Version 1 streaming (ROOT/v3-00-6).
// Now we have to reconstruct a valid Histogram from a_buffer :
hd_data data;
data.m_dimension = 1;
data.m_axes.resize(1);
double fEntries; //in range + outflow.
double fSw; //in range.
double fSw2; //in range.
double fSxw; //in range.
double fSx2w; //in range.
if(!TH_read_1D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w)) return 0;
// the upper set :
//data.m_title
//data.m_bin_number
//data.m_axes
//data.m_bin_Sw2
std::vector<double> bins; //fArray TArrayD
if(!Array_stream<double>(a_buffer,bins)) return 0;
if(!a_buffer.check_byte_count(s,c,"TH1D")) return 0;
unsigned int binn = data.m_bin_number;
data.m_bin_Sw = bins;
data.m_bin_entries.resize(binn,0);
{std::vector<double> empty;
empty.resize(1,0);
data.m_bin_Sxw.resize(binn,empty);
data.m_bin_Sx2w.resize(binn,empty);}
data.m_all_entries = static_cast<unsigned int>(fEntries);
data.m_in_range_entries = 0;
data.m_in_range_Sw = fSw;
data.m_in_range_Sw2 = fSw2;
data.m_in_range_Sxw.resize(1,0);
data.m_in_range_Sx2w.resize(1,0);
data.m_in_range_Sxw[0] = fSxw;
data.m_in_range_Sx2w[0] = fSx2w;
tools::histo::h1d* h = new tools::histo::h1d("",10,0,1);
h->copy_from_data(data);
return h;
}
inline tools::histo::h2d* TH2F_stream(buffer& a_buffer){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return 0;
//printf("debug : BatchLab::Rio::TH2F::stream : version %d\n",v);
// Version 3 streaming (ROOT/v3-00-6).
// Now we have to reconstruct a valid Histogram from a_buffer :
hd_data data;
data.m_dimension = 2;
//data.m_coords.resize(data.m_dimension,0);
//data.m_ints.resize(data.m_dimension,0);
data.m_axes.resize(2);
double fEntries; //in range + outflow.
double fSw; //in range.
double fSw2; //in range.
double fSxw; //in range.
double fSx2w; //in range.
double fSyw; //in range.
double fSy2w; //in range.
if(!TH_read_2D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w,fSyw,fSy2w)) return 0;
// the upper set :
//data.m_title
//data.m_bin_number
//data.m_axes
//data.m_bin_Sw2
std::vector<float> bins; //fArray TArrayF
if(!Array_stream<float>(a_buffer,bins)) return 0;
if(!a_buffer.check_byte_count(s,c,"TH2F")) return 0;
//printf("debug : BatchLab::Rio::TH2F::stream : histo bins %d\n",n);
unsigned int binn = data.m_bin_number;
data.m_bin_Sw.resize(binn,0);
{for(unsigned int index=0;index<binn;index++){
data.m_bin_Sw[index] = double(bins[index]);
}}
data.m_bin_entries.resize(binn,0);
{std::vector<double> empty;
empty.resize(2,0);
data.m_bin_Sxw.resize(binn,empty);
data.m_bin_Sx2w.resize(binn,empty);}
data.m_all_entries = static_cast<unsigned int>(fEntries);
data.m_in_range_entries = 0;
data.m_in_range_Sw = fSw;
data.m_in_range_Sw2 = fSw2;
data.m_in_range_Sxw.resize(2,0);
data.m_in_range_Sx2w.resize(2,0);
data.m_in_range_Sxw[0] = fSxw;
data.m_in_range_Sx2w[0] = fSx2w;
data.m_in_range_Sxw[1] = fSyw;
data.m_in_range_Sx2w[1] = fSy2w;
tools::histo::h2d* h = new tools::histo::h2d("",10,0,1,10,0,1);
h->copy_from_data(data);
return h;
}
inline tools::histo::h2d* TH2D_stream(buffer& a_buffer){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return 0;
//printf("debug : BatchLab::Rio::TH2D::stream : version %d\n",v);
// Version 3 streaming (ROOT/v3-00-6).
// Now we have to reconstruct a valid Histogram from a_buffer :
hd_data data;
data.m_dimension = 2;
//data.m_coords.resize(data.m_dimension,0);
//data.m_ints.resize(data.m_dimension,0);
data.m_axes.resize(2);
double fEntries; //in range + outflow.
double fSw; //in range.
double fSw2; //in range.
double fSxw; //in range.
double fSx2w; //in range.
double fSyw; //in range.
double fSy2w; //in range.
if(!TH_read_2D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w,fSyw,fSy2w)) return 0;
// the upper set :
//data.m_title
//data.m_bin_number
//data.m_axes
//data.m_bin_Sw2
std::vector<double> bins; //fArray TArrayD
if(!Array_stream<double>(a_buffer,bins)) return 0;
if(!a_buffer.check_byte_count(s,c,"TH2D")) return 0;
unsigned int binn = data.m_bin_number;
data.m_bin_Sw = bins;
data.m_bin_entries.resize(binn,0);
{std::vector<double> empty;
empty.resize(2,0);
data.m_bin_Sxw.resize(binn,empty);
data.m_bin_Sx2w.resize(binn,empty);}
data.m_all_entries = static_cast<unsigned int>(fEntries);
data.m_in_range_entries = 0;
data.m_in_range_Sw = fSw;
data.m_in_range_Sw2 = fSw2;
data.m_in_range_Sxw.resize(2,0);
data.m_in_range_Sx2w.resize(2,0);
data.m_in_range_Sxw[0] = fSxw;
data.m_in_range_Sx2w[0] = fSx2w;
data.m_in_range_Sxw[1] = fSyw;
data.m_in_range_Sx2w[1] = fSy2w;
tools::histo::h2d* h = new tools::histo::h2d("",10,0,1,10,0,1);
h->copy_from_data(data);
return h;
}
inline tools::histo::h3d* TH3D_stream(buffer& a_buffer){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return 0;
//printf("debug : BatchLab::Rio::TH2D::stream : version %d\n",v);
// Now we have to reconstruct a valid Histogram from a_buffer :
hd_data data;
data.m_dimension = 3;
//data.m_coords.resize(data.m_dimension,0);
//data.m_ints.resize(data.m_dimension,0);
data.m_axes.resize(2);
double fEntries; //in range + outflow.
double fSw; //in range.
double fSw2; //in range.
double fSxw; //in range.
double fSx2w; //in range.
double fSyw; //in range.
double fSy2w; //in range.
double fSzw; //in range.
double fSz2w; //in range.
if(!TH_read_3D(a_buffer,data,fEntries,fSw,fSw2,fSxw,fSx2w,fSyw,fSy2w,fSzw,fSz2w)) return 0;
// the upper set :
//data.m_title
//data.m_bin_number
//data.m_axes
//data.m_bin_Sw2
std::vector<double> bins; //fArray TArrayD
if(!Array_stream<double>(a_buffer,bins)) return 0;
if(!a_buffer.check_byte_count(s,c,"TH3D")) return 0;
unsigned int binn = data.m_bin_number;
data.m_bin_Sw = bins;
data.m_bin_entries.resize(binn,0);
{std::vector<double> empty;
empty.resize(3,0);
data.m_bin_Sxw.resize(binn,empty);
data.m_bin_Sx2w.resize(binn,empty);}
data.m_all_entries = static_cast<unsigned int>(fEntries);
data.m_in_range_entries = 0;
data.m_in_range_Sw = fSw;
data.m_in_range_Sw2 = fSw2;
data.m_in_range_Sxw.resize(3,0);
data.m_in_range_Sx2w.resize(3,0);
data.m_in_range_Sxw[0] = fSxw;
data.m_in_range_Sx2w[0] = fSx2w;
data.m_in_range_Sxw[1] = fSyw;
data.m_in_range_Sx2w[1] = fSy2w;
data.m_in_range_Sxw[2] = fSzw;
data.m_in_range_Sx2w[2] = fSz2w;
tools::histo::h3d* h = new tools::histo::h3d("",10,0,1,10,0,1,10,0,1);
h->copy_from_data(data);
return h;
}
inline tools::histo::p1d* TProfile_stream(buffer& a_buffer){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return 0;
// Version 3 streaming (ROOT/v3-00-6).
//WARNING : the mapping tools::histo::p1d / TProfile is not obvious.
//p1d::m_bin_Svw <---> TProfile::fArray
//p1d::m_bin_Sv2w <---> TProfile::fSumw2
//p1d::m_bin_Sw <---> TProfile::fBinEntries
tools::histo::h1d* h = TH1D_stream(a_buffer);
if(!h) return 0;
//NOTE : histo.m_bin_Sw <---> TH1D::TArrayD::fArray
pd_data data(h->get_histo_data());
delete h;
std::vector<double> bins; //fBinEntries TArrayD
if(!Array_stream<double>(a_buffer,bins)) return 0;
int errorMode;
if(!a_buffer.read(errorMode)) return 0;
double ymin;
if(!a_buffer.read(ymin)) return 0;
double ymax;
if(!a_buffer.read(ymax)) return 0;
if(v>=4) {
double sumwy;
if(!a_buffer.read(sumwy)) return 0;
double sumwy2;
if(!a_buffer.read(sumwy2)) return 0;
}
if(v>=5) {
std::vector<double> bins_sumw2; //fBinSumw2 TArrayD
if(!Array_stream<double>(a_buffer,bins_sumw2)) return 0;
}
if(!a_buffer.check_byte_count(s,c,"TProfile")) return 0;
data.m_is_profile = true;
data.m_cut_v = true;
data.m_min_v = ymin;
data.m_max_v = ymax;
unsigned int binn = data.m_bin_number;
data.m_bin_Svw.resize(binn,0);
data.m_bin_Sv2w.resize(binn,0);
for(unsigned int index=0;index<binn;index++){
double svw = data.m_bin_Sw[index];
double sw = bins[index];
//data.m_bin_entries[index] = (int)sw; //FIXME : ok for w = 1 only !
data.m_bin_Sw[index] = (double)sw;
//FIXME : data.m_bin_Sxw
//FIXME : data.m_bin_Sx2w
data.m_bin_Svw[index] = svw;
//data.m_bin_Sv2w[index] = 0; //FIXME
}
tools::histo::p1d* p = new tools::histo::p1d("",10,0,1);
p->copy_from_data(data);
// We have now a valid tools::histo::p1d.
return p;
}
inline tools::histo::p2d* TProfile2D_stream(buffer& a_buffer){
unsigned int s, c;
short v;
if(!a_buffer.read_version(v,s,c)) return 0;
// Version 3 streaming (ROOT/v3-00-6).
//WARNING : the mapping tools::histo::p1d / TProfile is not obvious.
//p1d::m_bin_Svw <---> TProfile::fArray
//p1d::m_bin_Sv2w <---> TProfile::fSumw2
//p1d::m_bin_Sw <---> TProfile::fBinEntries
tools::histo::h2d* h = TH2D_stream(a_buffer);
if(!h) return 0;
//NOTE : histo.m_bin_Sw <---> TH2D::TArrayD::fArray
pd_data data(h->get_histo_data());
delete h;
std::vector<double> bins; //fBinEntries TArrayD
if(!Array_stream<double>(a_buffer,bins)) return 0;
int errorMode;
if(!a_buffer.read(errorMode)) return 0;
double zmin;
if(!a_buffer.read(zmin)) return 0;
double zmax;
if(!a_buffer.read(zmax)) return 0;
if(v>=5) {
double sumwz;
if(!a_buffer.read(sumwz)) return 0;
double sumwz2;
if(!a_buffer.read(sumwz2)) return 0;
}
if(v>=7) {
std::vector<double> bins_sumw2; //fBinSumw2 TArrayD
if(!Array_stream<double>(a_buffer,bins_sumw2)) return 0;
}
if(!a_buffer.check_byte_count(s,c,"TProfile2D")) return 0;
data.m_is_profile = true;
data.m_cut_v = true;
data.m_min_v = zmin;
data.m_max_v = zmax;
unsigned int binn = data.m_bin_number;
data.m_bin_Svw.resize(binn,0);
data.m_bin_Sv2w.resize(binn,0);
for(unsigned int index=0;index<binn;index++){
double svw = data.m_bin_Sw[index];
double sw = bins[index];
//data.m_bin_entries[index] = (int)sw; //FIXME : ok for w = 1 only !
data.m_bin_Sw[index] = (double)sw;
//FIXME : data.m_bin_Sxw
//FIXME : data.m_bin_Sx2w
data.m_bin_Svw[index] = svw;
//data.m_bin_Sv2w[index] = 0; //FIXME
}
tools::histo::p2d* p = new tools::histo::p2d("",10,0,1,10,0,1);
p->copy_from_data(data);
return p;
}
class TDirectory : public tools::rroot::directory {
//public:
// static const std::string& store_class() {return TDirectory_cls();}
public:
TDirectory(ifile& a_file)
:tools::rroot::directory(a_file)
{}
virtual ~TDirectory(){}
protected:
TDirectory(const TDirectory& a_from)
:tools::rroot::directory(a_from)
{}
TDirectory& operator=(const TDirectory&){return *this;}
public:
bool stream(buffer& a_buffer){
initialize();
short version;
if(!a_buffer.read_version(version)) return false;
unsigned int _date;
if(!a_buffer.read(_date)) return false;
//m_date_C.setDate(_date);
if(!a_buffer.read(_date)) return false;
//m_date_M.setDate(_date);
if(!a_buffer.read(m_nbytes_keys)) return false;
if(!a_buffer.read(m_nbytes_name)) return false;
if(version>1000) {
if(!a_buffer.read(m_seek_directory)) return false;
if(!a_buffer.read(m_seek_parent)) return false;
if(!a_buffer.read(m_seek_keys)) return false;
} else {
{seek32 i;
if(!a_buffer.read(i)) return false;
m_seek_directory = i;}
{seek32 i;
if(!a_buffer.read(i)) return false;
m_seek_parent = i;}
{seek32 i;
if(!a_buffer.read(i)) return false;
m_seek_keys = i;}
}
//short v = version%1000;
if (m_seek_keys) {
uint32 n;
if(!read_keys(n)) {
a_buffer.out() << "tools::rroot::TDirectory::stream :"
<< " cannot read keys."
<< std::endl;
return false;
}
}
return true;
}
protected:
void initialize(){
// Initialise directory to defaults :
// If directory is created via default ctor (when dir is read from file)
// don't add it here to the directory since its name is not yet known.
// It will be added to the directory in TKey::ReadObj().
m_date_C = 0;//m_date_C.set();
m_date_M = 0;//m_date_M.set();
m_nbytes_keys = 0;
m_seek_directory = 0;
m_seek_parent = 0;
m_seek_keys = 0;
}
};
inline void dump(std::ostream& a_out,
tools::rroot::ifile& a_file,
const std::vector<tools::rroot::key*>& a_keys,
bool a_recursive,
unsigned int a_spaces = 0) {
// dump non directory objects :
{std::vector<tools::rroot::key*>::const_iterator it;
for(it=a_keys.begin();it!=a_keys.end();++it) {
tools::rroot::key& k = *(*it);
if(k.object_class()==tools::rroot::TDirectory_cls()) continue;
{for(unsigned int index=0;index<a_spaces;index++) a_out << " ";}
k.dump(a_out);
}}
// dump directories :
{std::vector<tools::rroot::key*>::const_iterator it;
for(it=a_keys.begin();it!=a_keys.end();++it) {
tools::rroot::key& k = *(*it);
if(k.object_class()!=tools::rroot::TDirectory_cls()) continue;
std::string label = k.object_name();
{for(unsigned int index=0;index<a_spaces;index++) a_out << " ";}
a_out << "directory : " << label << std::endl;
if(!a_recursive) continue;
uint32 sz;
char* buf = k.get_object_buffer(sz);
//we don't have ownership of buf.
if(!buf) {
a_out << "tools::rroot::dump :"
<< " can't get directory data buffer."
<< std::endl;
} else {
tools::rroot::buffer b(a_out,a_file.byte_swap(),
sz,buf,k.key_length(),false);
tools::rroot::TDirectory tdir(a_file);
if(!tdir.stream(b)) {
a_out << "tools::rroot::dump :"
<< " can't stream TDirectory."
<< std::endl;
} else {
const std::vector<tools::rroot::key*>& keys = tdir.keys();
dump(a_out,a_file,keys,a_recursive,a_spaces+1);
}
}
}}
}
inline bool read_sinfos(tools::rroot::ifile& a_file){
key& k = a_file.sinfos_key();
std::ostream& out = k.file().out();
if(k.object_class()!=tools::rroot::TList_cls()) {
out << "tools::rroot::read_sinfos :"
<< " key not a TList."
<< std::endl;
return false;
}
unsigned int sz;
char* buf = k.get_object_buffer(sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::read_sinfos :"
<< " can't get data buffer of " << k.object_name() << "."
<< std::endl;
return false;
}
tools::rroot::buffer b(out,k.file().byte_swap(),sz,buf,k.key_length(),false);
dummy_fac fac(out);
List infos(fac,true);
if(!infos.stream(b)) return false;
tools_vforcit(iro*,infos,it) {
StreamerInfo* info = tools::safe_cast<iro,StreamerInfo>(*(*it));
if(!info) return false;
info->out(out);
}
return true;
}
}}
#endif
@@ -0,0 +1,465 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_tree
#define tools_rroot_tree
#include "ifac"
#include "branch_element"
#include "../sout"
namespace tools {
namespace rroot {
inline const std::string& TTree_cls(){
static const std::string s_v("TTree");
return s_v;
}
class tree {
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::tree");
return s_v;
}
public:
tree(ifile& a_file,ifac& a_fac)
:m_file(a_file)
,m_fac(a_fac)
,m_out(a_file.out())
,m_name("")
,m_title("")
,m_branches(a_fac,true)
,m_entries(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~tree(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
tree(const tree& a_from)
:m_file(a_from.m_file)
,m_fac(a_from.m_fac)
,m_out(a_from.m_out)
,m_branches(m_fac,false)
{}
tree& operator=(const tree&){return *this;}
public:
ifile& file() {return m_file;}
const std::string& name() const {return m_name;}
const std::string& title() const {return m_title;}
const std::vector<branch*>& branches() const {return m_branches;}
bool find_entry(uint32 a_entry,uint32& a_nbytes) {
a_nbytes = 0;
if(a_entry>=m_entries) return false;
int nbytes = 0;
//fReadEntry = a_entry;
tools_vforit(branch*,m_branches,it) {
uint32 n;
if(!(*it)->find_entry(a_entry,n)) return false;
nbytes += n;
}
a_nbytes = nbytes;
return true;
}
void dump(std::ostream& a_out,
const std::string& a_spaces = "",
const std::string& a_indent = " "){
a_out << a_spaces
<< "tree :"
<< " name=" << sout(m_name)
<< " title=" << sout(m_title)
<< " entries=" << m_entries
<< std::endl;
_dump_branches(a_out,m_branches,a_spaces+a_indent,a_indent);
}
branch* find_branch(const std::string& a_name,
bool a_recursive = false) const {
return _find_branch(m_branches,a_name,a_recursive);
}
std::vector<base_leaf*> find_leaves(){
std::vector<base_leaf*> leaves;
_find_leaves(m_branches,leaves);
return leaves;
}
std::vector<branch*> find_branches(){
std::vector<branch*> _branches;
_find_branches(m_branches,_branches);
return _branches;
}
//branch* find_leaf_branch(base_leaf* a_leaf){
// return _find_leaf_branch(m_branches,a_leaf);
//}
bool show(std::ostream& a_out,uint32 a_entry){
a_out << "======> EVENT:" << a_entry << std::endl;
tools_vforit(branch*,m_branches,it) {
if(!(*it)->show(a_out,a_entry)) return false;
}
return true;
}
uint64 entries() const {return m_entries;}
bool stream(buffer& a_buffer){
//uint64 m_tot_bytes;
//uint64 m_zip_bytes;
//uint64 m_saved_bytes;
short vers;
unsigned int s, c;
if(!a_buffer.read_version(vers,s,c)) return false;
//::printf("debug : tree::stream : version %d count %d\n",vers,c);
//if (vers > 4) {
//TTree::Class()->ReadBuffer(b, this, vers, s, c);
//if (fEstimate <= 10000) fEstimate = 1000000;
//m_saved_bytes = m_tot_bytes;
//fDirectory = gDirectory;
//gDirectory->Append(this);
//return;
//}
if(!Named_stream(a_buffer,m_name,m_title)) return false;
{short color,style,width;
if(!AttLine_stream(a_buffer,color,style,width)) return false;}
{short color,style;
if(!AttFill_stream(a_buffer,color,style)) return false;}
if(!AttMarker_stream(a_buffer)) return false;
if(vers<=4) {
int dummy_int;
if(!a_buffer.read(dummy_int)) return false; //fScanField
if(!a_buffer.read(dummy_int)) return false; //fMaxEntryLoop
{int fMaxVirtualSize;
if(!a_buffer.read(fMaxVirtualSize)) return false;}
{double v;
if(!a_buffer.read(v)) return false;
m_entries = uint64(v);}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
{int fAutoSave;
if(!a_buffer.read(fAutoSave)) return false;}
if(!a_buffer.read(dummy_int)) return false; //fEstimate
} else if(vers<=9) {
{double v;
if(!a_buffer.read(v)) return false;
m_entries = uint64(v);}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_saved_bytes = uint64(v);
}
int dummy_int;
if(!a_buffer.read(dummy_int)) return false; //fTimerInterval
if(!a_buffer.read(dummy_int)) return false; //fScanField
if(!a_buffer.read(dummy_int)) return false; //fUpdate
if(!a_buffer.read(dummy_int)) return false; //fMaxEntryLoop
{int fMaxVirtualSize;
if(!a_buffer.read(fMaxVirtualSize)) return false;}
{int fAutoSave;
if(!a_buffer.read(fAutoSave)) return false;}
if(!a_buffer.read(dummy_int)) return false; //fEstimate
} else if(vers<16) { //FIXME : what is the exact version ?
double dummy_double;
int dummy_int;
{double v;
if(!a_buffer.read(v)) return false;
m_entries = uint64(v);}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_saved_bytes = uint64(v);
}
if(!a_buffer.read(dummy_double)) return false; //fWeight
if(!a_buffer.read(dummy_int)) return false; //fTimerInterval
if(!a_buffer.read(dummy_int)) return false; //fScanField
if(!a_buffer.read(dummy_int)) return false; //fUpdate
if(!a_buffer.read(dummy_int)) return false; //fMaxEntryLoop
{int fMaxVirtualSize;
if(!a_buffer.read(fMaxVirtualSize)) return false;}
{int fAutoSave;
if(!a_buffer.read(fAutoSave)) return false;}
if(!a_buffer.read(dummy_int)) return false; //fEstimate
} else { //vers>=16
double dummy_double;
int dummy_int;
int64 dummy_int64;
{uint64 v;
if(!a_buffer.read(v)) return false;
m_entries = v;}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_saved_bytes = v;
}
if(vers>=18) {
if(!a_buffer.read(dummy_int64)) return false; //fFlushedBytes
}
if(!a_buffer.read(dummy_double)) return false; //fWeight
if(!a_buffer.read(dummy_int)) return false; //fTimerInterval
if(!a_buffer.read(dummy_int)) return false; //fScanField
if(!a_buffer.read(dummy_int)) return false; //fUpdate
if(vers>=18) {
if(!a_buffer.read(dummy_int)) return false; //fDefaultEntryOffsetLen
}
if(!a_buffer.read(dummy_int64)) return false; //fMaxEntries
if(!a_buffer.read(dummy_int64)) return false; //fMaxEntryLoop
{uint64 fMaxVirtualSize;
if(!a_buffer.read(fMaxVirtualSize)) return false;}
{uint64 fAutoSave;
if(!a_buffer.read(fAutoSave)) return false;}
if(vers>=18) {
if(!a_buffer.read(dummy_int64)) return false; //fAutoFlush
}
if(!a_buffer.read(dummy_int64)) return false; //fEstimate
}
//FIXME if (fEstimate <= 10000) fEstimate = 1000000;
//TObjArray
//The below m_branches.read will create leaves.
//::printf("debug : tree : read branches : begin\n");
{ifac::args args;
if(!m_branches.stream(a_buffer,args)) {
m_out << "tools::rroot::tree::stream : "
<< "can't read branches."
<< std::endl;
return false;
}}
//::printf("debug : tree : read branches : end\n");
//TObjArray
// We read leaves in order to keep streaming synchronisation.
// In fact m_leaves are references to existing leaves read by
// the branches in the upper line of code.
//::printf("debug : tree : read leaves : begin\n");
{ObjArray<base_leaf> m_leaves(m_fac,true);
branch b(m_file,m_fac);
ifac::args args;
args[ifac::arg_branch()] = &b;
if(!m_leaves.stream(a_buffer,args)) {
m_out << "tools::rroot::tree::stream : "
<< "can't read leaves."
<< std::endl;
return false;
}}
//::printf("debug : tree : read leaves : end\n");
if(vers>=10) {
//TList* fAliases
if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
m_out << "tools::rroot::tree::stream : "
<< "can't read fAliases."
<< std::endl;
return false;
}
}
//m_saved_bytes = m_tot_bytes;
{std::vector<double> v;
if(!Array_stream<double>(a_buffer,v)) return false;} //fIndexValues TArrayD
{std::vector<int> v;
if(!Array_stream<int>(a_buffer,v)) return false;} // fIndex (TArrayI).
if(vers>=16) {
//TVirtualIndex* fTreeIndex //FIXME ???
if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
m_out << "tools::rroot::tree::stream : "
<< "can't read fTreeIndex."
<< std::endl;
return false;
}
}
if(vers>=6) {
//TList* fFriends
if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
m_out << "tools::rroot::tree::stream : "
<< "can't read fFriends."
<< std::endl;
return false;
}
}
if(vers>=16) {
//TList* fUserInfo
if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
m_out << "tools::rroot::tree::stream : "
<< "can't read fUserInfo."
<< std::endl;
return false;
}
//TBranchRef* fBranchRef
if(!dummy_TXxx_pointer_stream(a_buffer,m_fac)) {
m_out << "tools::rroot::tree::stream : "
<< "can't read fBranchRef."
<< std::endl;
return false;
}
}
if(!a_buffer.check_byte_count(s,c,TTree_cls())) return false;
return true;
}
protected:
void _dump_branches(std::ostream& a_out,
const std::vector<branch*>& a_bs,
const std::string& a_spaces = "",
const std::string& a_indent = " "){
tools_vforcit(branch*,a_bs,it) {
if(branch_element* be = safe_cast<branch,branch_element>(*(*it))) {
a_out << a_spaces
<< "branch_element :"
<< " name=" << sout((*it)->name())
<< " title=" << sout((*it)->title())
<< " entry_number=" << be->entry_number()
<< " ref_cls=" << sout(be->class_name())
<< " (type=" << be->type()
<< ",id=" << be->id()
<< ",stype=" << be->streamer_type()
<< ")."
<< std::endl;
} else {
a_out << a_spaces
<< "branch :"
<< " name=" << sout((*it)->name())
<< " title=" << sout((*it)->title())
<< " entry_number=" << (*it)->entry_number()
<< std::endl;
}
{const std::vector<base_leaf*>& lvs = (*it)->leaves();
tools_vforcit(base_leaf*,lvs,itl) {
a_out << a_spaces << a_indent
<< "leave :"
<< " name=" << sout((*itl)->name())
<< " title=" << sout((*itl)->title())
<< " cls=" << sout((*itl)->s_cls())
<< std::endl;
}}
_dump_branches(a_out,(*it)->branches(),a_spaces+a_indent,a_indent);
}
}
branch* _find_branch(const std::vector<branch*>& a_bs,
const std::string& a_name,
bool a_recursive) const {
tools_vforcit(branch*,a_bs,it) {
if(tools::rcmp((*it)->name(),a_name)) return *it;
if(a_recursive) {
branch* br = _find_branch((*it)->branches(),a_name,a_recursive);
if(br) return br;
}
}
return 0;
}
void _find_leaves(const std::vector<branch*>& a_bs,
std::vector<base_leaf*>& a_leaves){
tools_vforcit(branch*,a_bs,it) {
{const std::vector<base_leaf*>& lvs = (*it)->leaves();
tools_vforcit(base_leaf*,lvs,itl) {
a_leaves.push_back(*itl);
}}
_find_leaves((*it)->branches(),a_leaves);
}
}
void _find_branches(const std::vector<branch*>& a_bs,
std::vector<branch*>& a_branches){
tools_vforcit(branch*,a_bs,it) {
a_branches.push_back(*it);
_find_branches((*it)->branches(),a_branches);
}
}
//branch* _find_leaf_branch(const std::vector<branch*>& a_bs,
// base_leaf* a_leaf){
// std::vector<branch*>::const_iterator it;
// for(it=a_bs.begin();it!=a_bs.end();++it) {
// {const std::vector<base_leaf*>& lvs = (*it)->leaves();
// std::vector<base_leaf*>::const_iterator itl;
// for(itl=lvs.begin();itl!=lvs.end();++itl) {
// if(*itl==a_leaf) return *it;
// }}
// {branch* br = _find_leaf_branch((*it)->branches(),a_leaf);
// if(br) return br;}
// }
// return 0;
//}
protected:
ifile& m_file;
ifac& m_fac;
std::ostream& m_out;
//Named
std::string m_name;
std::string m_title;
ObjArray<branch> m_branches;
uint64 m_entries; // Number of entries
};
}}
#endif
@@ -0,0 +1,105 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_tree_index
#define tools_rroot_tree_index
#include "named"
namespace tools {
namespace rroot {
class tree_index : public virtual iro {
static const std::string& s_store_class() {
static const std::string s_v("TTreeIndex");
return s_v;
}
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::tree_index");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<tree_index>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return branch_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<tree_index>(this,a_class)) {return p;}
else return 0;
}
public:
virtual iro* copy() const {return new tree_index(*this);}
virtual bool stream(buffer& a_buffer) {
uint32 startpos = a_buffer.length();
unsigned int s,c;
short v;
if(!a_buffer.read_version(v,s,c)) return false;
//::printf("debug : tree_index::stream : version %d count %d\n",v,c);
if(!virtual_index_stream(a_buffer)) return false;
std::string ds;
if(!a_buffer.read(ds)) return false; //fMajorName
//::printf("debug : tree_index::stream : fMajorName \"%s\"\n",ds.c_str());
if(!a_buffer.read(ds)) return false; //fMinorName
//::printf("debug : tree_index::stream : fMinorName \"%s\"\n",ds.c_str());
int64 m_n;
if(!a_buffer.read(m_n)) return false; //fN
//::printf("debug : tree_index::stream : fN %ld\n",m_n);
if(!dummy_array_stream<int64>(a_buffer,int(m_n))) return false;
if(!dummy_array_stream<int64>(a_buffer,int(m_n))) return false;
//FIXME : still problem with this streamer.
a_buffer.set_offset(startpos+c+sizeof(unsigned int));
if(!a_buffer.check_byte_count(s,c,s_store_class())) return false;
//::printf("debug : tree_index::stream : ok\n");
return true;
}
public:
tree_index()
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~tree_index(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
tree_index(const tree_index& a_from):iro(a_from){}
tree_index& operator=(const tree_index&){return *this;}
protected:
static const std::string& virtual_index_s_store_class() {
static const std::string s_v("TVirtualIndex");
return s_v;
}
bool virtual_index_stream(buffer& a_buffer){
short v;
unsigned int s, c;
if(!a_buffer.read_version(v,s,c)) return false;
//::printf("debug : virtual_index::stream : version %d count %d\n",v,c);
std::string ds;
if(!Named_stream(a_buffer,ds,ds)) return false;
if(!a_buffer.check_byte_count(s,c,virtual_index_s_store_class()))
return false;
return true;
}
};
}}
#endif
@@ -0,0 +1,111 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_tree_manip
#define tools_rroot_tree_manip
#include "file"
#include "tree"
#include "stl_vector"
namespace tools {
namespace rroot {
inline tree* find_tree(file& a_file,ifac& a_fac,const std::string& a_name) {
std::ostream& out = a_file.out();
//out << "tools::rroot::find_tree : name : " << file << std::endl;
key* key = a_file.dir().find_key(a_name);
if(!key) {
out << "tools::rroot::find_tree :"
<< " key " << sout(a_name) << " not found."
<< std::endl;
return 0;
}
unsigned int sz;
char* buf = key->get_object_buffer(sz); //we don't have ownership of buf.
if(!buf) {
out << "tools::rroot::find_tree :"
<< " can't get data buffer of "
<< sout(key->object_name()) << "."
<< std::endl;
return 0;
}
//out << "tools::rroot::find_tree :"
// << " get data buffer size " << sz << "."
// << std::endl;
buffer b(out,key->file().byte_swap(),sz,buf,key->key_length(),false);
if(key->object_class()!=TTree_cls()) {
out << "tools::rroot::find_tree :"
<< " key object class "
<< sout(key->object_class())
<< " is not a TTree."
<< std::endl;
return 0;
}
tree* _tree = new tree(a_file,a_fac);
if(!_tree->stream(b)) {
out << "tools::rroot::find_tree :"
<< " TTree streaming failed"
<< std::endl;
delete _tree;
return 0;
}
return _tree;
}
inline branch_element* find_be(tree& a_tree,const std::string& a_name){
std::ostream& out = a_tree.file().out();
branch* _branch = a_tree.find_branch(a_name,true);
if(!_branch) {
out << "tools::rroot::find_be :"
<< " branch not found."
<< std::endl;
return 0;
}
branch_element* be = id_cast<branch,branch_element>(*_branch);
if(!be) {
out << "tools::rroot::find_be :"
<< " branch not a branch_element."
<< std::endl;
return 0;
}
return be;
}
template <class T>
inline stl_vector<T>* find_vec(branch_element& a_be,unsigned int a_event){
std::ostream& out = a_be.file().out();
unsigned int n;
if(!a_be.find_entry(a_event,n)) {
out << "tools::rroot::find_vec :"
<< " find event failed."
<< std::endl;
return 0;
}
iro* o = a_be.object();
stl_vector<T>* od = id_cast<iro, stl_vector<T> >(*o);
if(!od) {
out << "tools::rroot::find_vec :"
<< " object not a tools::rroot::stl_vector<T>."
<< std::endl;
return 0;
}
return od; //WARNING : we are not owner.
}
}}
#endif
@@ -0,0 +1,34 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rtausmed
#define tools_rtausmed
#include "rtausmeui"
#include "S_STRING"
#include <cmath>
namespace tools {
class rtausmed : public rtausmeui {
public:
TOOLS_SCLASS(tools::rtausmed)
public:
rtausmed(unsigned int a_seed = 4357):rtausmeui(a_seed){}
virtual ~rtausmed(){}
public:
rtausmed(const rtausmed& a_from):rtausmeui(a_from){}
rtausmed& operator=(const rtausmed& a_from) {rtausmeui::operator=(a_from);return *this;}
protected:
static double two_to_minus_32() {
static const double s_v = std::ldexp(1.0,-32);
return s_v;
}
public:
double shoot() {return double(rtausmeui::shoot()) * two_to_minus_32();}
};
}
#endif
@@ -0,0 +1,34 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rtausmef
#define tools_rtausmef
#include "rtausmeui"
#include "S_STRING"
#include <cmath>
namespace tools {
class rtausmef : public rtausmeui {
public:
TOOLS_SCLASS(tools::rtausmef)
public:
rtausmef(unsigned int a_seed = 4357):rtausmeui(a_seed){}
virtual ~rtausmef(){}
public:
rtausmef(const rtausmef& a_from):rtausmeui(a_from){}
rtausmef& operator=(const rtausmef& a_from) {rtausmeui::operator=(a_from);return *this;}
protected:
static float two_to_minus_32() {
static const float s_v = ::ldexpf(1,-32);
return s_v;
}
public:
float shoot() {return float(rtausmeui::shoot()) * two_to_minus_32();}
};
}
#endif
@@ -0,0 +1,92 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rtausmeui
#define tools_rtausmeui
// tausme is for Tausworthe maxmally equidistributed.
// From logic and code of CERN-ROOT/TRandom2 class.
// Random number generator class based on the maximally quidistributed combined
// Tausworthe generator by L'Ecuyer.
//
// The period of the generator is 2**88 (about 10**26) and it uses only 3 words
// for the state.
//
// For more information see:
// P. L'Ecuyer, Mathematics of Computation, 65, 213 (1996)
// P. L'Ecuyer, Mathematics of Computation, 68, 225 (1999)
//
// The publication are available online at
// http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps
// http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps
namespace tools {
class rtausmeui {
public:
rtausmeui(unsigned int a_seed = 1):m_seed(0),m_seed1(0),m_seed2(0){set_seed(a_seed);}
virtual ~rtausmeui(){}
public:
rtausmeui(const rtausmeui& a_from):m_seed(a_from.m_seed),m_seed1(a_from.m_seed1),m_seed2(a_from.m_seed2){}
rtausmeui& operator=(const rtausmeui& a_from) {
m_seed = a_from.m_seed;
m_seed1 = a_from.m_seed1;
m_seed2 = a_from.m_seed2;
return *this;
}
public:
void set_seed(unsigned int a_seed) {
m_seed = a_seed?a_seed:1;
// Generate m_seed[1,2] needed for the generator state using
// a linear congruential generator
// The only condition, stated at the end of the 1999 L'Ecuyer paper is that the seeds
// must be greater than 1,7 and 15.
m_seed = LCG(m_seed);
if (m_seed < 2) m_seed += 2UL;
m_seed1 = LCG(m_seed);
if (m_seed1 < 8) m_seed1 += 8UL;
m_seed2 = LCG(m_seed1);
if (m_seed2 < 16) m_seed2 += 16UL;
// "warm it up" by calling it 6 times
for (unsigned int i = 0; i < 6; ++i) shoot();
}
unsigned int seed() const {return m_seed;}
unsigned int shoot() {
// TausWorth generator from L'Ecuyer, uses as seed 3x32bits integers
// Use a mask of 0xffffffffUL to make in work on 64 bit machines
// Periodicity of about 10**26
unsigned int y;
do {
m_seed = TAUSWORTHE (m_seed, 13, 19, 4294967294UL, 12);
m_seed1 = TAUSWORTHE (m_seed1, 2, 25, 4294967288UL, 4);
m_seed2 = TAUSWORTHE (m_seed2, 3, 11, 4294967280UL, 17);
y = m_seed ^ m_seed1 ^ m_seed2;
} while(!y);
return y;
}
protected:
static unsigned int LCG(unsigned int a_n) {
return ((69069 * a_n) & 0xffffffffUL); // linear congurential generator
}
static unsigned int TAUSWORTHE(unsigned int a_s,unsigned int a_a,unsigned int a_b,unsigned int a_c,unsigned int a_d) {
return (((a_s & a_c) << a_d) & 0xffffffffUL ) ^ ((((a_s << a_a) & 0xffffffffUL )^ a_s) >> a_b);
}
protected:
unsigned int m_seed;
unsigned int m_seed1;
unsigned int m_seed2;
};
}
#endif
@@ -0,0 +1,32 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_s2time
#define tools_s2time
#include <ctime>
#include <string>
#include <cstdio> //sscanf
namespace tools {
inline bool s2time(const std::string& a_string,time_t& a_time) {
int yy, mm, dd, hh, mi, ss;
if(::sscanf(a_string.c_str(),
"%d-%d-%d %d:%d:%d",
&yy,&mm,&dd,&hh,&mi,&ss)!=6) {a_time = 0;return false;}
struct tm tp;
tp.tm_year = yy-1900;
tp.tm_mon = mm-1;
tp.tm_mday = dd;
tp.tm_hour = hh;
tp.tm_min = mi;
tp.tm_sec = ss;
tp.tm_isdst = 0;
a_time = ::mktime(&tp);
return true;
}
}
#endif
@@ -0,0 +1,23 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_signature
#define tools_signature
#include <string>
#include <cstdio>
namespace tools {
namespace file {
inline bool signature(const std::string& a_file,unsigned char a_head[],unsigned int& a_num){ //it is assumed a_head[] can contain a_num chars.
FILE* file = ::fopen(a_file.c_str(),"rb");
if(!file) {a_num=0;return false;}
a_num = ::fread(a_head,1,a_num,file);
::fclose(file);
return true;
}
}}
#endif

Some files were not shown because too many files have changed in this diff Show More