Import Geant4 10.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-10 11:51:14 +02:00
parent e2d2f9810a
commit 286caacf06
12421 changed files with 730077 additions and 502383 deletions
@@ -0,0 +1,53 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_S_STRING
#define tools_S_STRING
// a few place in which a cpp macro help the readability.
#define TOOLS_CLASS_STRING(a_name)\
static const std::string& s_##a_name() {\
static const std::string s_v(#a_name);\
return s_v;\
}
#define TOOLS_CLASS_STRING_VALUE(a_name,a_value)\
static const std::string& s_##a_name() {\
static const std::string s_v(#a_value);\
return s_v;\
}
#define TOOLS_GLOBAL_STRING(a_name)\
inline const std::string& s_##a_name() {\
static const std::string s_v(#a_name);\
return s_v;\
}
#define TOOLS_GLOBAL_ARG(a_name)\
inline const std::string& s_##a_name() {\
static const std::string s_v(std::string("-")+std::string(#a_name));\
return s_v;\
}
#define TOOLS_SCLASS(a_name)\
static const std::string& s_class() {\
static const std::string s_v(#a_name);\
return s_v;\
}\
static void check_class_name() {a_name::s_class();}
#define TOOLS_T_SCLASS(a_T,a_name)\
static const std::string& s_class() {\
static const std::string s_v(#a_name);\
return s_v;\
}\
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
+518
View File
@@ -0,0 +1,518 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_args
#define tools_args
#include "sout"
#include "strip"
#include "words"
#include "sto"
#include <ostream>
namespace tools {
class args {
public:
typedef std::pair<std::string,std::string> arg;
public:
args(){}
args(int a_argc,char* a_argv[]){
for(int index=0;index<a_argc;index++) {
std::string s(a_argv[index]);
std::string::size_type pos = s.find('=');
if(pos==std::string::npos) {
m_args.push_back(arg(s,""));
} else {
std::string key = s.substr(0,pos);
pos++;
std::string value = s.substr(pos,s.size()-pos);
m_args.push_back(arg(key,value));
}
}
}
args(const std::vector<std::string>& a_args){add(a_args);}
args(const std::vector<arg>& a_args):m_args(a_args){}
//args(const std::string& a_args,const std::string& a_sep = " ",bool a_strip = false){
args(const std::string& a_args,const std::string& a_sep,bool a_strip){
std::vector<std::string> _args;
words(a_args,a_sep,false,_args);
add(_args,a_strip);
}
virtual ~args(){}
public:
args(const args& a_from):m_args(a_from.m_args){}
args& operator=(const args& a_from){
m_args = a_from.m_args;
return *this;
}
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) {
if((*it).first==a_string) return true;
}
return false;
}
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) {
if((*it).first==a_key) {
a_value = (*it).second;
return true;
}
}
a_value.clear();
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) {
if((*it).first==a_key) vals.push_back((*it).second);
}
return vals;
}
bool find(const std::string& a_string,bool& a_value) const {
std::string s;
if(!find(a_string,s)) {a_value = false;return false;}
return to(s,a_value);
}
template <class aT>
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);
}
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) {
std::string s;
if((*it).second.empty()) {
s = (*it).first;
} else {
s = (*it).first;
s += "=";
s += (*it).second;
}
vec.push_back(s);
}
return vec;
}
bool add(const std::string& a_key,
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) {
if((*it).first==a_key) {
(*it).second = a_value;
return true;
}
}
}
if(a_key.empty()) return false;
m_args.push_back(arg(a_key,a_value));
return true;
}
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) {
std::vector<std::string> ws;
words((*it),"=",false,ws);
if(ws.size()==1) {
if(a_strip) {
m_args.push_back(arg(strp(ws[0]),""));
} else {
m_args.push_back(arg(ws[0],""));
}
} else if(ws.size()>=2) {
if(a_strip) {
m_args.push_back(arg(strp(ws[0]),strp(ws[1])));
} else {
m_args.push_back(arg(ws[0],ws[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);
}
int remove(const std::string& a_key){
unsigned int nbeg = m_args.size();
for(std::vector<arg>::iterator it = m_args.begin();it!=m_args.end();) {
if(a_key==(*it).first) {
it = m_args.erase(it);
} else {
++it;
}
}
return nbeg - m_args.size();
}
void remove_first(){m_args.erase(m_args.begin());}
bool last(std::string& a_key,std::string& a_value) const {
a_key.clear();
a_value.clear();
if(m_args.empty()) return false;
a_key = m_args.back().first;
a_value = m_args.back().second;
return true;
}
bool file(std::string& a_file) const {
std::string slast;
std::string s;
if((m_args.size()>1) //first arg is the program name !
&& last(slast,s)
&& (slast.find('-')!=0)
&& (s.empty()) ) {
a_file = slast; //Last argument is not an option.
return true;
} else {
a_file.clear();
return false;
}
}
std::vector<std::string> files(bool a_skip_first = true) const {
// Get the serie of trailing args not beginning with '-'
// and without a value (not of the form [-]xxx=yyy).
// Note that an argument like that in between arguments
// is NOT taken into account.
std::vector<std::string> _files;
if(m_args.empty()) return _files;
std::vector<arg>::const_iterator it = m_args.begin();
if(a_skip_first) it++;
for(;it!=m_args.end();++it) {
if( ((*it).first.find('-')==0) || (*it).second.size() ) {
_files.clear();
} else {
_files.push_back((*it).first);
}
}
return _files;
}
bool argcv(int& a_argc,char**& a_argv) const {
// If using with :
// int argc;
// char** argv;
// args.argcv(argc,argv);
// you can delete with :
// args.delete_argcv(argc,argv);
if(m_args.empty()) {a_argc = 0;a_argv = 0;return true;}
typedef char* _cstr_t;
_cstr_t* av = new _cstr_t[m_args.size()];
if(!av) {a_argc = 0;a_argv = 0;return false;}
a_argv = av;
for(std::vector<arg>::const_iterator it = m_args.begin();
it!=m_args.end();++it,av++) {
std::string::size_type lf = (*it).first.length();
std::string::size_type ls = (*it).second.length();
std::string::size_type sz = 0;
if(ls) {
sz = lf + 1 + ls;
} else {
sz = lf;
}
char* p = new char[sz+1];
if(!p) {a_argc = 0;a_argv = 0;return false;} //some delete are lacking.
*av = p;
{char* pf = (char*)(*it).first.c_str();
for(std::string::size_type i=0;i<lf;i++,p++,pf++) {*p = *pf;}
*p = 0;}
if(ls) {*p = '=';p++;}
{char* ps = (char*)(*it).second.c_str();
for(std::string::size_type i=0;i<ls;i++,p++,ps++) {*p = *ps;}
*p = 0;}
}
a_argc = (int)m_args.size();
return true;
}
static void delete_argcv(int& a_argc,char**& a_argv) {
for(int index=0;index<a_argc;index++) delete [] a_argv[index];
delete [] a_argv;
a_argc = 0;
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) {
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) {
if((*it).first==(*it2)) {
found = true;
break;
}
}
if(!found) return false;
}
}
return true;
}
void files_at_end(bool a_skip_first = true) {
// reorder to have "file" arguments at end.
if(m_args.empty()) return;
std::vector<arg> _args;
if(a_skip_first) _args.push_back(*(m_args.begin()));
//first pass :
{std::vector<arg>::const_iterator it = m_args.begin();
if(a_skip_first) it++;
for(;it!=m_args.end();++it) {
if( ((*it).first.find('-')==0) || (*it).second.size() ) {
_args.push_back(*it);
}
}}
//second pass :
{std::vector<arg>::const_iterator it = m_args.begin();
if(a_skip_first) it++;
for(;it!=m_args.end();++it) {
if( ((*it).first.find('-')==0) || (*it).second.size() ) {
} else {
_args.push_back(*it);
}
}}
m_args = _args;
}
//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) {
a_out << "key = " << sout((*it).first)
<< " value = " << sout((*it).second)
<< std::endl;
}
}
public: //backcomp (for Panoramix).
bool isAnArgument(const std::string& a_key) const {return is_arg(a_key);}
protected:
std::vector<arg> m_args;
};
inline bool check_args(const std::vector<std::string>& a_args,unsigned int a_number,std::ostream& a_out){
if(a_args.size()==a_number) return true;
a_out << "bad argument number."
<< " Given " << (unsigned int)a_args.size()
<< " whilst " << a_number << " expected."
<< std::endl;
return false;
}
inline bool check_min(const std::vector<std::string>& a_args,unsigned int a_number,std::string& a_last,std::ostream& a_out){
if(a_args.size()>=a_number) {
if(a_number==0) {
if(a_args.empty()) {
a_last.clear();
} else {
a_last = a_args[0];
for(unsigned int index=1;index<a_args.size();index++) {
a_last += " " + a_args[index];
}
}
} else {
a_last = a_args[a_number-1];
for(unsigned int index=a_number;index<a_args.size();index++) {
a_last += " " + a_args[index];
}
}
return true;
}
a_out << "bad argument number."
<< " Given " << (unsigned int)a_args.size()
<< " whilst at least " << a_number << " expected."
<< std::endl;
return false;
}
inline bool check_min_args(const std::vector<std::string>& aArgs,unsigned int a_number,std::ostream& a_out){
if(aArgs.size()>=a_number) return true;
a_out << "bad argument number."
<< " Given " << (unsigned int)aArgs.size()
<< " whilst at least " << a_number << " expected."
<< std::endl;
return false;
}
inline bool check_or_args(const std::vector<std::string>& aArgs,unsigned int a_1,unsigned int a_2,std::ostream& a_out){
if((aArgs.size()==a_1)||(aArgs.size()==a_2)) return true;
a_out << "bad argument number."
<< " Given " << (unsigned int)aArgs.size()
<< " whilst " << a_1 << " or " << a_2 << " expected."
<< std::endl;
return false;
}
template <class T>
inline bool to(std::ostream& a_out,const std::string& a_string,T& a_value){
if(!to<T>(a_string,a_value)) {
a_out << "Passed value " << sout(a_string)
<< " is of bad type."
<< std::endl;
return false;
}
return true;
}
inline bool to(std::ostream& a_out,const std::string& a_string,bool& a_value){
if(!to(a_string,a_value)) {
a_out << "Passed value " << sout(a_string)
<< " is not a boolean."
<< std::endl;
return false;
}
return true;
}
inline std::string gui_toolkit(args& a_args,bool a_rm_in_args){
std::string driver;
a_args.find("-toolkit",driver);
if(a_rm_in_args) a_args.remove("-toolkit");
if(driver.empty()) {
if(a_args.is_arg("-Xt")||
a_args.is_arg("-xt")||
a_args.is_arg("-Xm")||
a_args.is_arg("-xm")||
a_args.is_arg("-Motif")||
a_args.is_arg("-motif")) {
driver = "Xt";
if(a_rm_in_args) {
a_args.remove("-Xt");
a_args.remove("-xt");
a_args.remove("-Xm");
a_args.remove("-xm");
a_args.remove("-Motif");
a_args.remove("-motif");
}
} else if(a_args.is_arg("-Win")||
a_args.is_arg("-win")||
a_args.is_arg("-Win32")||
a_args.is_arg("-win32")) {
driver = "Win";
if(a_rm_in_args) {
a_args.remove("-Win");
a_args.remove("-win");
a_args.remove("-Win32");
a_args.remove("-win32");
}
} else if(a_args.is_arg("-NextStep")||
a_args.is_arg("-nextstep")) {
driver = "NextStep";
if(a_rm_in_args) {
a_args.remove("-NextStep");
a_args.remove("-nextstep");
}
} else if(a_args.is_arg("-Gtk")||
a_args.is_arg("-gtk")) {
driver = "Gtk";
if(a_rm_in_args) {
a_args.remove("-Gtk");
a_args.remove("-gtk");
}
} else if(a_args.is_arg("-Qt")||
a_args.is_arg("-qt")) {
driver = "Qt";
if(a_rm_in_args) {
a_args.remove("-Qt");
a_args.remove("-qt");
}
} else if(a_args.is_arg("-SDL")||
a_args.is_arg("-sdl")) {
driver = "SDL";
if(a_rm_in_args) {
a_args.remove("-SDL");
a_args.remove("-sdl");
}
} else if(a_args.is_arg("-Net")||
a_args.is_arg("-net")) {
driver = "Net";
if(a_rm_in_args) {
a_args.remove("-Net");
a_args.remove("-net");
}
}
}
return driver;
}
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;
a_wh = 480;
} else if(a_args.is_arg("-iPad")) {
a_ww = 768;
a_wh = 1024;
} else if(a_args.is_arg("-iPhone4")) {
a_ww = 640;
a_wh = 960;
} else if(a_args.is_arg("-SGS")) { //Samsung Galaxy S
//a_ww = 320;
//a_wh = 533;
a_ww = 480;
a_wh = 800;
} else {
if(a_args.find<unsigned int>("-ww",a_ww)) {
if(a_args.find<unsigned int>("-wh",a_wh)) return;
//A4 : we have ww but not wh :
a_wh = (unsigned int)(a_ww*(29.7f/21.0f)); //29.7/21 = 1.414
} else { //we don't have ww.
if(a_args.find<unsigned int>("-wh",a_wh)) {
//A4 : we have wh but not ww :
a_ww = (unsigned int)(a_wh*(21.0f/29.7f));
} else {
//we have nothing. Take a ww of 700. With A4 wh is then 990.
a_ww = 700;
a_wh = (unsigned int)(a_ww*(29.7f/21.0f)); //29.7/21 = 1.414
}
}
}
if(a_args.is_arg("-land")){
unsigned int tmp = a_ww;
a_ww = a_wh;
a_wh = tmp;
}
}
inline void remove_window_size_args(args& a_args) {
//use with Wt apps.
a_args.remove("-iPod");
a_args.remove("-iPhone");
a_args.remove("-iPad");
a_args.remove("-iPhone4");
a_args.remove("-SGS");
a_args.remove("-ww");
a_args.remove("-wh");
a_args.remove("-land");
}
inline std::vector<std::string> to(int a_argc,char** a_argv) {
std::vector<std::string> v;
for(int index=0;index<a_argc;index++) v.push_back(a_argv[index]);
return v;
}
}
#endif
@@ -0,0 +1,152 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_charmanip
#define tools_charmanip
namespace tools {
// some char ASCII code :
// \0 : 0
// \n = LF : 10
// \r = CR : 13
// \t = HT : 9
// , : 44
inline bool is_upper(char a_char) {
// do it myself: due to problem with ctype.h and
// isxxx macros on different platforms.
switch(a_char) {
case 'A':return true;
case 'B':return true;
case 'C':return true;
case 'D':return true;
case 'E':return true;
case 'F':return true;
case 'G':return true;
case 'H':return true;
case 'I':return true;
case 'J':return true;
case 'K':return true;
case 'L':return true;
case 'M':return true;
case 'N':return true;
case 'O':return true;
case 'P':return true;
case 'Q':return true;
case 'R':return true;
case 'S':return true;
case 'T':return true;
case 'U':return true;
case 'V':return true;
case 'W':return true;
case 'X':return true;
case 'Y':return true;
case 'Z':return true;
default:return false;
}
return false;
}
inline bool is_lower(char a_char) {
switch(a_char) {
case 'a':return true;
case 'b':return true;
case 'c':return true;
case 'd':return true;
case 'e':return true;
case 'f':return true;
case 'g':return true;
case 'h':return true;
case 'i':return true;
case 'j':return true;
case 'k':return true;
case 'l':return true;
case 'm':return true;
case 'n':return true;
case 'o':return true;
case 'p':return true;
case 'q':return true;
case 'r':return true;
case 's':return true;
case 't':return true;
case 'u':return true;
case 'v':return true;
case 'w':return true;
case 'x':return true;
case 'y':return true;
case 'z':return true;
default:return false;
}
return false;
}
inline bool is_digit(char a_char) {
switch(a_char){
case '0':return true;
case '1':return true;
case '2':return true;
case '3':return true;
case '4':return true;
case '5':return true;
case '6':return true;
case '7':return true;
case '8':return true;
case '9':return true;
default:return false;
}
return false;
}
inline bool is_letter(char a_char) {
return (is_lower(a_char)||is_upper(a_char)) ? true : false;
}
//inline bool is_alpha(char a_char) {
// return (is_lower(a_char)||is_upper(a_char)||is_digit(a_char)) ? true : false;
//}
inline bool is_printable(char a_char) {
if(is_lower(a_char)||is_upper(a_char)||is_digit(a_char)) return true;
switch(a_char) {
case ' ':return true;
case '!':return true;
case '"':return true;
case '#':return true;
case '$':return true;
case '%':return true;
case '&':return true;
case '\'':return true;
case '(':return true;
case ')':return true;
case '*':return true;
case '+':return true;
case ',':return true;
case '-':return true;
case '.':return true;
case '/':return true;
case ':':return true;
case ';':return true;
case '<':return true;
case '=':return true;
case '>':return true;
case '?':return true;
case '@':return true;
case '[':return true;
case '\\':return true;
case ']':return true;
case '^':return true;
case '_':return true;
case '`':return true;
case '{':return true;
case '|':return true;
case '}':return true;
case '~':return true;
default:return false;
}
return false;
}
}
#endif
+13
View File
@@ -0,0 +1,13 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_cid
#define tools_cid
namespace tools {
typedef unsigned short cid;
}
#endif
@@ -0,0 +1,58 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_cids
#define tools_cids
#include "cid"
#include <string>
#include "typedefs" //byte
namespace tools {
inline cid _cid(byte) {return 1;}
inline cid _cid(char) {return 2;}
inline cid _cid(unsigned short) {return 3;}
inline cid _cid(short) {return 4;}
inline cid _cid(unsigned int) {return 5;}
inline cid _cid(int) {return 6;}
inline cid _cid(float) {return 7;}
inline cid _cid(double) {return 8;}
inline cid _cid(bool) {return 9;}
// not compiler types :
inline cid _cid(uint64) {return 10;}
inline cid _cid(int64) {return 11;}
inline cid _cid(const std::string&) {return 12;}
inline cid _cid(fits_bit) {return 13;}
inline cid _cid(csv_time) {return 14;}
//NOTE : avoid time_t which is defined in general as a long
// and is then ambiguous relative to int/int64.
//NOTE : if adding some, it must not exceed 20. Else, you have to change
// the below for std::vector.
}
#include <vector>
namespace tools {
// For rntuple and rroot::ntuple::column_element.
// The read::icolumn<T> needs a _cid(T) with T :
// std::vector< [basic_type, std::vector<basic_type>] >
template <class T>
inline cid _cid(const std::vector<T>&) {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)
//WARNING : rroot/cids start at 100.
//WARNING : rroot/geo_cids start at 1000.
}
#endif
+31
View File
@@ -0,0 +1,31 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_cmp
#define tools_cmp
#include <ostream>
namespace tools {
template <class T>
inline bool cmp(std::ostream& a_out,
const T& a_what,
const T& a_ref,const T& a_error = T()) {
if(a_what>a_ref) {
if((a_what-a_ref)>a_error) {
a_out << a_ref << " expected. Got " << a_what << std::endl;
return false;
}
} else {
if((a_ref-a_what)>a_error) {
a_out << a_ref << " expected. Got " << a_what << std::endl;
return false;
}
}
return true;
}
}
#endif
@@ -0,0 +1,46 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_fmath
#define tools_fmath
#include <cmath>
namespace tools {
//have : static const fpi = (float)3.1415926535897931160E0; ???
inline float fpi() {return (float)3.1415926535897931160E0;}
inline float ftwo_pi() {return (float)6.2831853071795862320E0;}
inline float fhalf_pi() {return (float)1.5707963267948965580E0;}
inline float fcos(float x) {return (float)::cos(double(x));}
inline float fsin(float x) {return (float)::sin(double(x));}
inline float facos(float x) {return (float)::acos(double(x));}
inline float fasin(float x) {return (float)::asin(double(x));}
inline float ftan(float x) {return (float)::tan(double(x));}
inline float fatan(float x) {return (float)::atan(double(x));}
inline float fatan2(float x,float y) {return (float)::atan2(double(x),double(y));}
inline float fsqrt(float x) {return (float)::sqrt(double(x));}
inline float fpow(float x,float y) {return (float)::pow(double(x),(double)(y));}
inline float fexp(float x) {return (float)::exp(double(x));}
inline float flog(float x) {return (float)::log(double(x));}
inline float flog10(float x) {return (float)::log10(double(x));}
inline float ffloor(float x) {return (float)::floor(double(x));}
inline float ffabs(float x) {return (float)::fabs(double(x));}
inline float fceil(float x) {return (float)::ceil(double(x));}
inline float fdeg2rad() {return fpi()/180.0f;} //0.0174f
inline float frad2deg() {return 180.0f/fpi();}
inline int fround(float a_x) {
// From CoinGL/src/base/SbViewportRegion.cpp.
if (a_x == (float) (int(a_x))) return int(a_x);
else return (a_x>0.0f) ? int(a_x+0.5f) : -int(0.5f-a_x);
}
inline float fstep(float a_x) {return a_x<0.0f?0.0f:1.0f;}
}
#endif
@@ -0,0 +1,105 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_gzip_buffer
#define tools_gzip_buffer
// what is needed for root file compression with zlib.
// The gzip library is libz.
// Someone must not confuse zlib with zip.
// In particular to use zip someone has to
// link to -lz that contains inflate, deflate.
#include <zlib.h>
#include <ostream>
namespace tools {
inline bool gzip_buffer(std::ostream& a_out,
unsigned int a_level,
unsigned int a_srcsize,const char* a_src,
unsigned int a_tgtsize,char* a_tgt,
unsigned int& a_irep) {
z_stream stream; // decompression stream
stream.next_in = (Bytef*)(a_src);
stream.avail_in = (uInt)(a_srcsize);
stream.next_out = (Bytef*)a_tgt;
stream.avail_out = (uInt)(a_tgtsize);
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
int err = deflateInit(&stream,a_level);
if(err!=Z_OK) {
a_out << "tools::wroot::zip :"
<< " error in zlib/deflateInit." << std::endl;
a_irep = 0;
return false;
}
err = deflate(&stream, Z_FINISH);
if(err!=Z_STREAM_END) {
deflateEnd(&stream);
a_out << "tools::wroot::zip :"
<< " error in zlib/deflate." << std::endl;
a_irep = 0;
return false;
}
deflateEnd(&stream);
//a_out << "tools::gzip_buffer : ok "
// << stream.total_out << std::endl;
a_irep = stream.total_out;
return true;
}
inline bool gunzip_buffer(std::ostream& a_out,
unsigned int a_srcsize,const char* a_src,
unsigned int a_tgtsize,char* a_tgt,
unsigned int& a_irep) {
z_stream stream; // decompression stream
stream.next_in = (Bytef*)(a_src);
stream.avail_in = (uInt)(a_srcsize);
stream.next_out = (Bytef*)a_tgt;
stream.avail_out = (uInt)(a_tgtsize);
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
int err = inflateInit(&stream);
if (err != Z_OK) {
a_out << "tools::gunzip_buffer :"
<< " error " << err << " in zlib/inflateInit." << std::endl;
return false;
}
err = inflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
inflateEnd(&stream);
a_out << "tools::gunzip_buffer :"
<< " error " << err << " in zlib/inflate." << std::endl;
return false;
}
inflateEnd(&stream);
//a_out << "tools::gunzip_buffer : zlib : ok "
// << stream.total_out << std::endl;
a_irep = stream.total_out;
return true;
}
}
#endif
@@ -0,0 +1,944 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_hbook_CHBOOK
#define tools_hbook_CHBOOK
// A C interface to HBOOK.
// It is done in way that limits the number of #define.
// Only two remains for WIN32.
#ifdef WIN32
#include <cstring>
#endif
namespace tools {
namespace hbook {
#ifdef TOOLS_HBOOK_F2C_RET_DOUBLE
typedef double rret;
#else
typedef float rret;
#endif
#ifdef TOOLS_HBOOK_F2C_ARG_DOUBLE
typedef double rarg;
#else
typedef float rarg;
#endif
/////////////////////////////////////////////////////////////////
/// functions with only a different name WIN32 versus UNIX //////
/////////////////////////////////////////////////////////////////
#ifdef WIN32
extern "C" void __stdcall ZITOH(int*,int*,int*);
extern "C" void __stdcall RZINK(int*,int*,const char *,int);
extern "C" void __stdcall HLIMIT(int*);
extern "C" void __stdcall HFILL(int*,rarg*,rarg*,rarg*);
extern "C" void __stdcall HRIN(int*,int*,int*);
extern "C" void __stdcall HNOENT(int*,int*);
extern "C" void __stdcall HFNT(int*);
extern "C" void __stdcall HGNPAR(int*,const char *,int);
extern "C" void __stdcall HGNT(int*,int*,int*);
extern "C" void __stdcall HDCOFL();
extern "C" void __stdcall HDELET(int*);
extern "C" void __stdcall HIJXY(int*,int*,int*,rarg*,rarg*);
extern "C" rret __stdcall HIJE(int*,int*,int*);
extern "C" rret __stdcall HIJ(int*,int*,int*);
extern "C" rret __stdcall HIE(int*,int*);
extern "C" void __stdcall HIX(int*,int*,rarg*);
extern "C" void __stdcall HXI(int*,rarg*,int*);
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);
extern "C" void hlimit_(int*);
extern "C" void hfill_(int*,rarg*,rarg*,rarg*);
extern "C" void hrin_(int*,int*,int*);
extern "C" void hnoent_(int*,int*);
extern "C" void hfnt_(int*);
extern "C" void hgnpar_(int*,const char *,int);
extern "C" void hgnt_(int*,int*,int*);
extern "C" void hdcofl_();
extern "C" void hdelet_(int*);
extern "C" void hijxy_(int*,int*,int*,rarg*,rarg*);
extern "C" rret hije_(int*,int*,int*);
extern "C" rret hij_(int*,int*,int*);
extern "C" rret hie_(int*,int*);
extern "C" void hix_(int*,int*,rarg*);
extern "C" void hxi_(int*,rarg*,int*);
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
/////////////////////////////////////////////////////////////////
/// functions with a different signature WIN32 versus UNIX //////
/////////////////////////////////////////////////////////////////
#ifdef WIN32
#define DEFCHAR const char*,const int
extern "C" void __stdcall UHTOC(int*,int*,const char*,const int,int*);
extern "C" void __stdcall HROPEN(int*,DEFCHAR,DEFCHAR,DEFCHAR,int*,int*);
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*);
extern "C" void __stdcall HBOOK1(int*,DEFCHAR,int*,rarg*,rarg*,rarg*);
extern "C" void __stdcall HBOOK2(int*,DEFCHAR,int*,rarg*,rarg*,int*,rarg*,rarg*,rarg*);
extern "C" void __stdcall HBOOKB(int*,DEFCHAR,int*,rarg*,rarg*);
extern "C" void __stdcall HBPROF(int*,DEFCHAR,int*,rarg*,rarg*,rarg*,rarg*,DEFCHAR);
extern "C" void __stdcall HCDIR(DEFCHAR,DEFCHAR);
extern "C" void __stdcall HLDIR(DEFCHAR,DEFCHAR);
extern "C" void __stdcall HMDIR(DEFCHAR,DEFCHAR);
extern "C" void __stdcall HDDIR(DEFCHAR);
extern "C" rret __stdcall HSTATI(int*,int*,DEFCHAR,int*);
extern "C" void __stdcall HRESET(int*,DEFCHAR);
extern "C" void __stdcall HOPERA(int*,DEFCHAR,int*,int*,rarg*,rarg*);
extern "C" void __stdcall HKIND(int*,int*,DEFCHAR);
#undef DEFCHAR
#define PASSCHAR(a_string) a_string,::strlen(a_string)
#else
typedef const char* DEFCHAR;
extern "C" void uhtoc_(int*,int*,const char*,int*,int);
extern "C" void hropen_(int*,DEFCHAR,DEFCHAR,DEFCHAR,int*,int*,int,int,int);
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);
extern "C" void hbook1_(int*,DEFCHAR,int*,rarg*,rarg*,rarg*,int);
extern "C" void hbook2_(int*,DEFCHAR,int*,rarg*,rarg*,int*,rarg*,rarg*,rarg*,int);
extern "C" void hbookb_(int*,DEFCHAR,int*,rarg*,rarg*,int);
extern "C" void hbprof_(int*,DEFCHAR,int*,rarg*,rarg*,rarg*,rarg*,DEFCHAR,int,int);
extern "C" void hcdir_(DEFCHAR,DEFCHAR ,int,int);
extern "C" void hldir_(DEFCHAR,DEFCHAR ,int,int);
extern "C" void hmdir_(DEFCHAR,DEFCHAR ,int,int);
extern "C" void hddir_(DEFCHAR,int);
extern "C" rret hstati_(int*,int*,DEFCHAR,int*,int);
extern "C" void hreset_(int*,DEFCHAR,int);
extern "C" void hopera_(int*,DEFCHAR,int*,int*,rarg*,rarg*,int);
extern "C" void hkind_(int*,int*,DEFCHAR,int);
#endif
#ifdef WIN32
extern "C" int PAWC[1];
extern "C" int QUEST[100];
extern "C" int HCBOOK[51];
extern "C" int RZCL[11];
//extern "C" int HCBITS[37];
#else
extern "C" int pawc_[1];
extern "C" int quest_[100];
extern "C" int hcbook_[51];
extern "C" int rzcl_[11];
//extern "C" int hcbits_[37];
#endif
}}
//////////////////////////////////////////////////////////////////////////////
/// our wrapping /////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#include <string>
#include <vector>
#include <cstring> //memset
namespace tools {
namespace hbook {
//////////////////////////////////////////////////////////////////////////////
/// package //////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
inline void CHLIMIT(int a_num) {
#ifdef WIN32
HLIMIT(&a_num);
#else
hlimit_(&a_num);
#endif
}
inline void CHDELET(int a_id){
#ifdef WIN32
HDELET(&a_id);
#else
hdelet_(&a_id);
#endif
}
inline void CHDCOFL() {
#ifdef WIN32
HDCOFL();
#else
hdcofl_();
#endif
}
inline void CRZINK(int a_key,int a_cycle,const std::string& a_opts) {
#ifdef WIN32
RZINK(&a_key,&a_cycle,PASSCHAR(a_opts.c_str()));
#else
rzink_(&a_key,&a_cycle,a_opts.c_str(),a_opts.size());
#endif
}
inline void CZITOH(int* a1,int* a2,int* a3) {
#ifdef WIN32
ZITOH(a1,a2,a3);
#else
zitoh_(a1,a2,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;
#else
return pawc_;
#endif
}
inline int* get_quest() {
#ifdef WIN32
return QUEST;
#else
return quest_;
#endif
}
//inline int* get_hcbits() {
//#ifdef WIN32
// return HCBITS;
//#else
// return hcbits_;
//#endif
//}
inline int* get_hcbook() {
#ifdef WIN32
return HCBOOK;
#else
return hcbook_;
#endif
}
inline int* get_rzcl() {
#ifdef WIN32
return RZCL;
#else
return rzcl_;
#endif
}
//////////////////////////////////////////////////////////////////////////////
/// file /////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
inline int CHROPEN(int a1,const std::string& a2,const std::string& a3,const std::string& a4,int a5) {
int ier = 0;
#ifdef WIN32
HROPEN(&a1,PASSCHAR(a2.c_str()),PASSCHAR(a3.c_str()),PASSCHAR(a4.c_str()),&a5,&ier);
#else
hropen_(&a1,a2.c_str(),a3.c_str(),a4.c_str(),&a5,&ier,a2.size(),a3.size(),a4.size());
#endif
return ier;
}
inline void CHRIN(int a_id,int a_cycle,int a_offset){
#ifdef WIN32
HRIN(&a_id,&a_cycle,&a_offset);
#else
hrin_(&a_id,&a_cycle,&a_offset);
#endif
}
inline void CHROUT(int a1,int a2,const std::string& a3) {
#ifdef WIN32
HROUT(&a1,&a2,PASSCHAR(a3.c_str()));
#else
hrout_(&a1,&a2,a3.c_str(),a3.size());
#endif
}
inline void CHREND(const std::string& a1) {
#ifdef WIN32
HREND(PASSCHAR(a1.c_str()));
#else
hrend_(a1.c_str(),a1.size());
#endif
}
inline void CHCDIR(const std::string& a1,const std::string& a2) {
#ifdef WIN32
HCDIR(PASSCHAR(a1.c_str()),PASSCHAR(a2.c_str()));
#else
hcdir_(a1.c_str(),a2.c_str(),a1.size(),a2.size());
#endif
}
inline void CHLDIR(const std::string& a1,const std::string& a2) {
#ifdef WIN32
HLDIR(PASSCHAR(a1.c_str()),PASSCHAR(a2.c_str()));
#else
hldir_(a1.c_str(),a2.c_str(),a1.size(),a2.size());
#endif
}
inline void CHPWDF(char* a_pwd) { //must be 1024 allocated.
int l = 1024;
{for(int i=0;i<l;i++) a_pwd[i] = 0;}
static const char a2[] = "R";
#ifdef WIN32
HCDIR(a_pwd,l,a2,1);
#else
hcdir_(a_pwd,a2,l,1);
#endif
/*int len=0;*/
{for(int i=l-1;i>0;i--) {
if(a_pwd[i]==0) continue;
if(a_pwd[i]!=' ') {/*len=i;*/break;}
a_pwd[i] = 0;
}}
}
inline std::string CHPWD() {
char pwd[1024];
CHPWDF(pwd);
return pwd;
}
inline void CHMDIR(const std::string& a1,const std::string& a2) {
#ifdef WIN32
HMDIR(PASSCHAR(a1.c_str()),PASSCHAR(a2.c_str()));
#else
hmdir_(a1.c_str(),a2.c_str(),a1.size(),a2.size());
#endif
}
inline void CHDDIR(const std::string& a1) {
#ifdef WIN32
HDDIR(PASSCHAR(a1.c_str()));
#else
hddir_(a1.c_str(),a1.size());
#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();
int* pawc = get_pawc();
if(a_PAWC) {
int* iq = &(pawc[17]);
int* lq = &(pawc[9]);
int lcdir = get_hcbook()[6];
int lf = lq[lcdir-1];
while(lf!=0) {
int ncw = 4;
//int ihdir[4];
//CZITOH(iq+lf+1,ihdir,&ncw);
int* ihdir = iq+lf+1;
char chdir[17];
{for(int i=0;i<17;i++) chdir[i] = 0;}
int nch=16;
#ifdef WIN32
UHTOC(ihdir,&ncw,chdir,16,&nch);
#else
uhtoc_(ihdir,&ncw,chdir,&nch,16);
#endif
{for(int i=17-1;i>0;i--) {
if(chdir[i]==0) continue;
if(chdir[i]!=' ') break;
chdir[i] = 0;
}}
a_dirs.push_back(chdir);
lf = lq[lf];
}
} else { //On a UNIT.
int* iq = &(pawc[17]);
const int KLS = 26;
const int KNSD = 23;
int lcdir = get_rzcl()[2];
int ls = iq[lcdir+KLS];
int ndir = iq[lcdir+KNSD];
for (int k=0;k<ndir;k++) {
lcdir = get_rzcl()[2];
int ncw = 4;
int ihdir[4];
CZITOH(iq+(lcdir+ls+7*k),ihdir,&ncw);
char chdir[17];
{for(int i=0;i<17;i++) chdir[i] = 0;}
int nch=16;
#ifdef WIN32
UHTOC(ihdir,&ncw,chdir,16,&nch);
#else
uhtoc_(ihdir,&ncw,chdir,&nch,16);
#endif
{for(int i=17-1;i>0;i--) {
if(chdir[i]==0) continue;
if(chdir[i]!=' ') break;
chdir[i] = 0;
}}
a_dirs.push_back(chdir);
}
}
}
inline std::vector<int> CHKEYS(){
// Apply on a //LUN<unit> directory.
std::vector<int> keys;
int* quest = get_quest();
for (int key=1;key<1000000;key++) {
CRZINK(key,0,"S");
if(quest[0]) break;
if(quest[13] & 8) continue;
int id = quest[20];
keys.push_back(id);
}
return keys;
}
inline bool CHEDIR(const std::string& a_dir,bool a_PAWC){
std::vector<std::string> drs;
CHDIRS(a_PAWC,drs);
std::vector<std::string>::iterator it;
for(it=drs.begin();it!=drs.end();++it){
if(a_dir==(*it)) return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////////
/// histogram ////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
inline void CHBOOK1(int a_id,const std::string& a_title,int a_xnum,rarg a_xmin,rarg a_xmax,rarg a_vmx = 0) {
#ifdef WIN32
HBOOK1(&a_id,PASSCHAR(a_title.c_str()),&a_xnum,&a_xmin,&a_xmax,&a_vmx);
#else
hbook1_(&a_id,a_title.c_str(),&a_xnum,&a_xmin,&a_xmax,&a_vmx,a_title.size());
#endif
}
inline void CHBOOK2(int a_id,const std::string& a_title,int a_xnum,rarg a_xmin,rarg a_xmax,int a_ynum,rarg a_ymin,rarg a_ymax,rarg a_vmx = 0) {
#ifdef WIN32
HBOOK2(&a_id,PASSCHAR(a_title.c_str()),
&a_xnum,&a_xmin,&a_xmax,&a_ynum,&a_ymin,&a_ymax,&a_vmx);
#else
hbook2_(&a_id,a_title.c_str(),
&a_xnum,&a_xmin,&a_xmax,&a_ynum,&a_ymin,&a_ymax,&a_vmx,
a_title.size());
#endif
}
inline bool CHBOOKB(
int a_id
,const std::string& a_title
,const std::vector<rarg>& a_edges
,rarg a_vmx = 0
) {
if(!a_edges.size()) return false;
int edgen = (int)a_edges.size();
rarg* edges = new rarg[edgen];
for(int i=0;i<edgen;i++) edges[i] = a_edges[i];
int ncx = edgen-1;
#ifdef WIN32
HBOOKB(&a_id,PASSCHAR(a_title.c_str()),&ncx,edges,&a_vmx);
#else
hbookb_(&a_id,a_title.c_str(),&ncx,edges,&a_vmx,a_title.size());
#endif
delete [] edges;
return true;
}
inline void CHBPROF(
int a_id
,const std::string& a_title
,int a_xnum,rarg a_xmin,rarg a_xmax
,rarg a_ymin,rarg a_ymax
,const std::string& a_opts
) {
#ifdef WIN32
HBPROF(&a_id,PASSCHAR(a_title.c_str()),
&a_xnum,&a_xmin,&a_xmax,&a_ymin,&a_ymax,
PASSCHAR(a_opts.c_str()));
#else
hbprof_(&a_id,a_title.c_str(),
&a_xnum,&a_xmin,&a_xmax,&a_ymin,&a_ymax,
a_opts.c_str(),a_title.size(),a_opts.size());
#endif
}
inline void CHGIVE(
int a_id
,std::string& a_title
,int& a_xnum
,rarg& a_xmin
,rarg& a_xmax
,int& a_ynum
,rarg& a_ymin
,rarg& a_ymax
){
char chtitl[128];
int ncx,ncy;
rarg xmin,xmax,ymin,ymax;
int nwt,idb;
#ifdef WIN32
HGIVE(&a_id,chtitl,80,&ncx,&xmin,&xmax,&ncy,&ymin,&ymax,&nwt,&idb);
#else
hgive_(&a_id,chtitl,&ncx,&xmin,&xmax,&ncy,&ymin,&ymax,&nwt,&idb,80);
#endif
chtitl[4*nwt] = 0;
a_title = chtitl;
a_xnum = ncx;
a_xmin = xmin;
a_xmax = xmax;
a_ynum = ncy;
a_ymin = ymin;
a_ymax = ymax;
}
inline void CHGIVE( //without title.
int a_id
,int& a_xnum
,rarg& a_xmin
,rarg& a_xmax
,int& a_ynum
,rarg& a_ymin
,rarg& a_ymax
){
char chtitl[128];
int ncx,ncy;
rarg xmin,xmax,ymin,ymax;
int nwt,idb;
#ifdef WIN32
HGIVE(&a_id,chtitl,80,&ncx,&xmin,&xmax,&ncy,&ymin,&ymax,&nwt,&idb);
#else
hgive_(&a_id,chtitl,&ncx,&xmin,&xmax,&ncy,&ymin,&ymax,&nwt,&idb,80);
#endif
a_xnum = ncx;
a_xmin = xmin;
a_xmax = xmax;
a_ynum = ncy;
a_ymin = ymin;
a_ymax = ymax;
}
inline int CHNOENT(int a_id){
int nentries;
#ifdef WIN32
HNOENT(&a_id,&nentries);
#else
hnoent_(&a_id,&nentries);
#endif
return nentries;
}
inline void CHFILL(int a_id,rarg a_x,rarg a_y,rarg a_w){
#ifdef WIN32
HFILL(&a_id,&a_x,&a_y,&a_w);
#else
hfill_(&a_id,&a_x,&a_y,&a_w);
#endif
}
inline rret CHI(int a_id,int a_i){
#ifdef WIN32
return HI(&a_id,&a_i);
#else
return hi_(&a_id,&a_i);
#endif
}
inline rret CHIE(int a_id,int a_i){
#ifdef WIN32
return HIE(&a_id,&a_i);
#else
return hie_(&a_id,&a_i);
#endif
}
inline rret CHIJ(int a_id,int a_i,int a_j){
#ifdef WIN32
return HIJ(&a_id,&a_i,&a_j);
#else
return hij_(&a_id,&a_i,&a_j);
#endif
}
inline rret CHIJE(int a_id,int a_i,int a_j){
#ifdef WIN32
return HIJE(&a_id,&a_i,&a_j);
#else
return hije_(&a_id,&a_i,&a_j);
#endif
}
inline rret CHIX(int a_id,int a_i){
rarg x;
#ifdef WIN32
HIX(&a_id,&a_i,&x);
#else
hix_(&a_id,&a_i,&x);
#endif
return x;
}
inline void CHIJXY(int a_id,int a_i,int a_j,rarg& aX,rarg& aY){
rarg x,y;
#ifdef WIN32
HIJXY(&a_id,&a_i,&a_j,&x,&y);
#else
hijxy_(&a_id,&a_i,&a_j,&x,&y);
#endif
aX = x;
aY = y;
}
inline int CHXI(int a_id,rarg a_x){
int i;
#ifdef WIN32
HXI(&a_id,&a_x,&i);
#else
hxi_(&a_id,&a_x,&i);
#endif
return i;
}
inline void CHXYIJ(int a_id,rarg a_x,rarg a_y,int& aI,int& aJ){
int i,j;
#ifdef WIN32
HXYIJ(&a_id,&a_x,&a_y,&i,&j);
#else
hxyij_(&a_id,&a_x,&a_y,&i,&j);
#endif
aI = i;
aJ = j;
}
inline rret CHMIN(int a_id){
#ifdef WIN32
return HMIN(&a_id);
#else
return hmin_(&a_id);
#endif
}
inline rret CHMAX(int a_id){
#ifdef WIN32
return HMAX(&a_id);
#else
return hmax_(&a_id);
#endif
}
inline rret CHSTATI(int a_id,int a_what,const std::string& aChoice,int a_num){
#ifdef WIN32
return HSTATI(&a_id,&a_what,PASSCHAR(aChoice.c_str()),&a_num);
#else
return hstati_(&a_id,&a_what,aChoice.c_str(),&a_num,aChoice.size());
#endif
}
inline void CHRESET(int a_id,const std::string& a_title){
#ifdef WIN32
HRESET(&a_id,PASSCHAR(a_title.c_str()));
#else
hreset_(&a_id,a_title.c_str(),a_title.size());
#endif
}
//////////////////////////////////////////////////////////////////////////////
/// Tuple ////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
inline void CHBNT(int a1,const std::string& a2,const std::string& a3) {
#ifdef WIN32
HBNT(&a1,PASSCHAR(a2.c_str()),PASSCHAR(a3.c_str()));
#else
hbnt_(&a1,a2.c_str(),a3.c_str(),a2.size(),a3.size());
#endif
}
inline void CHBNAME(int a1,const std::string& a2,void* a3,const std::string& a4) {
#ifdef WIN32
HBNAME(&a1,PASSCHAR(a2.c_str()),(int*)a3,PASSCHAR(a4.c_str()));
#else
hbname_(&a1,a2.c_str(),(int*)a3,a4.c_str(),a2.size(),a4.size());
#endif
}
inline void CHBNAM(int a1,const std::string& a2,void* a3,const std::string& a4,int a5) {
#ifdef WIN32
HBNAM(&a1,PASSCHAR(a2.c_str()),(int*)a3,PASSCHAR(a4.c_str()),&a5);
#else
hbnam_(&a1,a2.c_str(),(int*)a3,a4.c_str(),&a5,a2.size(),a4.size());
#endif
}
inline void CHGNPAR(int a1,const std::string& a2) {
#ifdef WIN32
HGNPAR(&a1,PASSCHAR(a2.c_str()));
#else
hgnpar_(&a1,a2.c_str(),a2.size());
#endif
}
inline void CHFNT(int a1) {
#ifdef WIN32
HFNT(&a1);
#else
hfnt_(&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
,std::vector<std::string>& aColumns
){
// Get number of columns :
char chtitl[128];
int nvar = 0;
rarg rmin[1000],rmax[1000];
#ifdef WIN32
HGIVEN(&a_id,chtitl,80,&nvar,PASSCHAR(""),rmin,rmax);
#else
hgiven_(&a_id,chtitl,&nvar,"",rmin,rmax,80,0);
#endif
// Get title and columns name :
const int Nchar = 9;
char* chtag_out = new char[nvar*Nchar+1];
chtag_out[nvar*Nchar]=0;
int i;
for (i=0;i<=80;i++)chtitl[i]=0;
#ifdef WIN32
HGIVEN(&a_id,chtitl,80,&nvar,chtag_out,Nchar,rmin,rmax);
#else
hgiven_(&a_id,chtitl,&nvar,chtag_out,rmin,rmax,80,Nchar);
#endif
for (i=80;i>0;i--) {if (chtitl[i] == ' ') chtitl[i] = 0; }
a_title = chtitl;
aColumns.clear();
char* name = chtag_out;
for(i=0; i<nvar;i++) {
name[Nchar-1] = 0;
int first = 0;
int last = 0;
// suppress trailing blanks
int j;
for (j=Nchar-2;j>0;j--) {
if (name[j] == ' ' && last == 0) name[j] = 0;
else last = j;
}
// suppress heading blanks
for (j=0;j<Nchar;j++) {
if (name[j] != ' ') break;
first = j+1;
}
aColumns.push_back(name+first);
name += Nchar;
}
return nvar;
}
inline int CHGNT(int a_id,int a_row){
int ier = 0;
#ifdef WIN32
HGNT(&a_id,&a_row,&ier);
#else
hgnt_(&a_id,&a_row,&ier);
#endif
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);
#else
hopera_(&a_id1,a_opts.c_str(),&a_id2,&a_id3,&a_c1,&a_c2,a_opts.size());
#endif
}
}}
#ifdef WIN32
#undef PASSCHAR
#endif
#endif
@@ -0,0 +1,158 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_hbook_axis
#define tools_hbook_axis
#include "CHBOOK"
namespace tools {
namespace hbook {
class axis {
public:
enum { UNDERFLOW_BIN = -2, OVERFLOW_BIN = -1 };
public:
axis(const std::string& a_path,int aID,
int aDimension,bool aIsX,bool aFixed)
:m_path(a_path),m_id(aID)
,m_dimension(aDimension),m_is_x(aIsX),m_fixed(aFixed)
{}
virtual ~axis(){}
public:
axis(const axis& a_from)
:m_path(a_from.m_path),m_id(a_from.m_id),m_dimension(a_from.m_dimension)
,m_is_x(a_from.m_is_x),m_fixed(a_from.m_fixed)
{}
axis& operator=(const axis& a_from){
m_path = a_from.m_path;
m_id = a_from.m_id;
m_dimension = a_from.m_dimension;
m_is_x = a_from.m_is_x;
m_fixed = a_from.m_fixed;
return *this;
}
public:
bool is_fixed_binning() const {return m_fixed;}
rarg lower_edge() const {
int xn,yn;
rarg xmin,xmax,ymin,ymax;
cd_beg();
CHGIVE(m_id,xn,xmin,xmax,yn,ymin,ymax);
cd_end();
return m_is_x?xmin:ymin;
}
rarg upper_edge() const {
int xn,yn;
rarg xmin,xmax,ymin,ymax;
cd_beg();
CHGIVE(m_id,xn,xmin,xmax,yn,ymin,ymax);
cd_end();
return m_is_x?xmax:ymax;
}
int bins() const {
int xn,yn;
rarg xmin,xmax,ymin,ymax;
cd_beg();
CHGIVE(m_id,xn,xmin,xmax,yn,ymin,ymax);
cd_end();
return m_is_x?xn:yn;
}
rret bin_lower_edge(int a_index) const {
int index = a_index + 1; //HBOOK counts in [1,NX]
if(m_dimension==1) {
cd_beg();
rret v = CHIX(m_id,index);
cd_end();
return v;
} else { //dimension 2
rarg x,y;
if(m_is_x) {
cd_beg();
CHIJXY(m_id,index,1,x,y);
cd_end();
return x;
} else {
cd_beg();
CHIJXY(m_id,1,index,x,y);
cd_end();
return y;
}
}
}
rret bin_upper_edge(int a_index) const {
//FIXME : is it correct to ask for the lower bound of the next bin ?
int index = a_index + 1 + 1; //HBOOK counts in [1,NX]
if(m_dimension==1) {
cd_beg();
rret v = CHIX(m_id,index);
cd_end();
return v;
} else { //dimension 2
rarg x,y;
if(m_is_x) {
cd_beg();
CHIJXY(m_id,index,1,x,y);
cd_end();
return x;
} else {
cd_beg();
CHIJXY(m_id,1,index,x,y);
cd_end();
return y;
}
}
}
rret bin_width(int a_index) const {
return bin_upper_edge(a_index) - bin_lower_edge(a_index);
}
int coord_to_index(rarg aCoord) const {
if(m_dimension==1) {
cd_beg();
int v = CHXI(m_id,aCoord)-1; //HBOOK counts in [1,NX]
cd_end();
return v;
} else { //dimension 2
int i,j;
if(m_is_x) {
cd_beg();
CHXYIJ(m_id,aCoord,0,i,j);
cd_end();
return i-1;
} else {
cd_beg();
CHXYIJ(m_id,0,aCoord,i,j);
cd_end();
return j-1;
}
}
}
rret bin_center(int a_index) const {
return (bin_lower_edge(a_index) + bin_upper_edge(a_index))/2;
}
private:
void cd_beg() const {
axis& self = const_cast<axis&>(*this);
CHPWDF(self.m_tmp);
CHCDIR(m_path," ");
}
void cd_end() const {CHCDIR(m_tmp," ");}
private:
std::string m_path;
int m_id;
int m_dimension;
bool m_is_x;
bool m_fixed;
char m_tmp[1024];
};
}}
#endif
@@ -0,0 +1,155 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_hbook_base_histo
#define tools_hbook_base_histo
#include "axis"
#include <map> //for annotations
namespace tools {
namespace hbook {
class base_histo {
protected:
base_histo(int aID):m_path(CHPWD()),m_id(aID){}
virtual ~base_histo(){}
protected:
base_histo(const base_histo& a_from)
:m_path(a_from.m_path)
,m_id(a_from.m_id)
,m_annotations(a_from.m_annotations)
{}
base_histo& operator=(const base_histo& a_from){
m_path = a_from.m_path;
m_id = a_from.m_id;
m_annotations = a_from.m_annotations;
return *this;
}
public:
int hbook_id() const {return m_id;}
bool scale(rarg aScale) {
//FIXME : Do we want the E option ?
cd_beg();
CHOPERA(m_id,"+E",m_id,m_id,aScale,0);
cd_end();
return true;
}
bool add(const base_histo& a_histo,rarg a_1 = 1,rarg a_2 = 1){
// this = a_1*this + a_2*a_histo
//NOTE : it is assumed that m_id and a_histo.m_id are in the
// same HBOOK directory.
cd_beg();
CHOPERA(m_id,"+E",a_histo.m_id,m_id,a_1,a_2);
cd_end();
return true;
}
bool subtract(const base_histo& a_histo,rarg a_1 = 1,rarg a_2 = 1){
// this = a_1*this - a_2*a_histo
//NOTE : it is assumed that m_id and a_histo.m_id are in the
// same HBOOK directory.
cd_beg();
CHOPERA(m_id,"-E",a_histo.m_id,m_id,a_1,a_2);
cd_end();
return true;
}
bool multiply(const base_histo& a_histo,rarg a_1 = 1,rarg a_2 = 1){
// this = a_1*this * a_2*a_histo
//NOTE : it is assumed that m_id and a_histo.m_id are in the
// same HBOOK directory.
cd_beg();
CHOPERA(m_id,"*E",a_histo.m_id,m_id,a_1,a_2);
cd_end();
return true;
}
bool divide(const base_histo& a_histo,rarg a_1 = 1,rarg a_2 = 1){
// this = a_1*this / a_2*a_histo
//NOTE : it is assumed that m_id and a_histo.m_id are in the
// same HBOOK directory.
cd_beg();
CHOPERA(m_id,"/E",a_histo.m_id,m_id,a_1,a_2);
cd_end();
return true;
}
std::string title() const {
std::string _title;
int ncx,ncy;
rarg xmin,xmax,ymin,ymax;
cd_beg();
CHGIVE(m_id,_title,ncx,xmin,xmax,ncy,ymin,ymax);
cd_end();
return _title;
}
bool reset() {
cd_beg();
CHRESET(m_id," ");
cd_end();
return true;
}
int all_entries() const {
cd_beg();
int v = CHNOENT(m_id);
cd_end();
return v;
}
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;}
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.
}
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;}
a_value = (*it).second;
return true;
}
protected:
void cd_beg() const{
base_histo& self = const_cast<base_histo&>(*this);
CHPWDF(self.m_tmp);
CHCDIR(m_path," ");
}
void cd_end() const {CHCDIR(m_tmp," ");}
protected:
static int hindex(int aIndex,const hbook::axis& aAxis){
if(aIndex==hbook::axis::UNDERFLOW_BIN)
return 0;
else if(aIndex==hbook::axis::OVERFLOW_BIN)
return aAxis.bins()+1;
else
return aIndex+1;
}
protected:
std::string m_path;
int m_id;
char m_tmp[1024];
// etc :
annotations_t m_annotations;
};
// predefined annotation keys :
inline const std::string& key_axis_x_title() {
static const std::string s_v("axis_x.title");
return s_v;
}
inline const std::string& key_axis_y_title() {
static const std::string s_v("axis_y.title");
return s_v;
}
inline const std::string& key_axis_z_title() {
static const std::string s_v("axis_z.title");
return s_v;
}
}}
#endif
@@ -0,0 +1,6 @@
SUBROUTINE OCLOSE(IUNIT)
IMPLICIT NONE
INTEGER IUNIT
CLOSE(IUNIT)
RETURN
END
@@ -0,0 +1,160 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_hbook_h1
#define tools_hbook_h1
#include "base_histo"
namespace tools {
namespace hbook {
class h1 : public base_histo {
public:
h1(int aID,const std::string& a_title,
int aXnumber,rarg aXmin,rarg aXmax)
:base_histo(aID)
,m_axis(m_path,aID,1,true,true)
{
//m_axis.copy(fHistogram.getAxis(0));
cd_beg();
CHBOOK1(m_id,a_title,aXnumber,aXmin,aXmax);
cd_end();
}
h1(int aID,const std::string& a_title,
const std::vector<rarg>& a_edges)
:base_histo(aID)
,m_axis(m_path,aID,1,true,false)
{
cd_beg();
CHBOOKB(m_id,a_title,a_edges);
cd_end();
}
virtual ~h1(){
cd_beg();
CHDELET(m_id);
cd_end();
}
private:
h1(const h1& a_from)
:base_histo(a_from)
,m_axis(a_from.m_axis)
{}
h1& operator=(const h1& a_from){
base_histo::operator=(a_from);
m_axis = a_from.m_axis;
return *this;
}
public:
bool configure(int aXnumber,rarg aXmin,rarg aXmax){
cd_beg();
CHBOOK1(m_id,title(),aXnumber,aXmin,aXmax);
cd_end();
return true;
}
bool configure(const std::vector<rarg>& a_edges){
cd_beg();
CHBOOKB(m_id,title(),a_edges);
cd_end();
return true;
}
public:
//bool set_title(const std::string& a_title) {
// return false;
//}
int dimension() const {return 1;}
rret sum_bin_heights() const {
int NX = axis().bins();
rret w = 0;
cd_beg();
for(int i=1;i<=NX;i++) {
w += CHI(m_id,i);
}
cd_end();
return w;
}
rret sum_all_bin_heights() const {
int NX1 = axis().bins()+1;
rret w = 0;
cd_beg();
for(int i=0;i<=NX1;i++) {
w += CHI(m_id,i);
}
cd_end();
return w;
}
rret sum_extra_bin_heights() const {
int NX1 = axis().bins()+1;
rret w = 0;
cd_beg();
w += CHI(m_id,0);
w += CHI(m_id,NX1);
cd_end();
return w;
}
rret min_bin_height() const {
cd_beg();
rret v = CHMIN(m_id);
cd_end();
return v;
}
rret max_bin_height() const {
cd_beg();
rret v = CHMAX(m_id);
cd_end();
return v;
}
void fill(rarg aX,rarg aWeight = 1) {
cd_beg();
CHFILL(m_id,aX,0,aWeight);
cd_end();
}
// optimization :
void fill_beg() const {cd_beg();}
void fill_fast(rarg aX,rarg aWeight = 1) {
CHFILL(m_id,aX,0,aWeight);
}
void fill_end() const {cd_end();}
rret bin_height(int aIndex) const {
cd_beg();
rret v = CHI(m_id,hindex(aIndex,axis()));
cd_end();
return v;
}
rret bin_error(int aIndex) const {
cd_beg();
rret v = CHIE(m_id,aIndex+1);
cd_end();
return v;
}
rret mean() const {
cd_beg();
rret v = CHSTATI(m_id,1," ",0);
cd_end();
return v;
}
rret rms() const {
cd_beg();
rret v = CHSTATI(m_id,2," ",0);
cd_end();
return v;
}
hbook::axis& axis() {return m_axis;}
const hbook::axis& axis() const {return m_axis;}
int coord_to_index(rarg aCoord) const {
return m_axis.coord_to_index(aCoord);
}
protected:
hbook::axis m_axis;
};
}}
#endif
@@ -0,0 +1,202 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_hbook_h2
#define tools_hbook_h2
#include "base_histo"
namespace tools {
namespace hbook {
class h2 : public base_histo {
public:
h2(int aID,const std::string& aTitle,
int aXnumber,rarg aXmin,rarg aXmax,
int aYnumber,rarg aYmin,rarg aYmax)
:base_histo(aID)
,m_axis_x(m_path,aID,2,true,true)
,m_axis_y(m_path,aID,2,false,true)
{
//m_axis_x.copy(fHistogram.getAxis(0));
//m_axis_y.copy(fHistogram.getAxis(1));
cd_beg();
CHBOOK2(m_id,aTitle,aXnumber,aXmin,aXmax,
aYnumber,aYmin,aYmax);
cd_end();
}
virtual ~h2(){
cd_beg();
CHDELET(m_id);
cd_end();
}
private:
h2(const h2& a_from)
:base_histo(a_from)
,m_axis_x(a_from.m_axis_x)
,m_axis_y(a_from.m_axis_y)
{}
h2& operator=(const h2& a_from){
base_histo::operator=(a_from);
m_axis_x = a_from.m_axis_x;
m_axis_y = a_from.m_axis_y;
return *this;
}
public:
bool configure(int aXnumber,rarg aXmin,rarg aXmax,
int aYnumber,rarg aYmin,rarg aYmax){
cd_beg();
CHBOOK2(m_id,title(),aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax);
cd_end();
return true;
}
public:
void fill(rarg aX,rarg aY,rarg aWeight = 1) {
cd_beg();
CHFILL(m_id,aX,aY,aWeight);
cd_end();
}
// optimization :
void fill_beg() const {cd_beg();}
void fill_fast(rarg aX,rarg aY,rarg aWeight = 1) {
CHFILL(m_id,aX,aY,aWeight);
}
void fill_end() const {cd_end();}
int dimension() const {return 2;}
rret mean_x() const {
cd_beg();
rret v = CHSTATI(m_id,1,"PROX",0);
cd_end();
return v;
}
rret mean_y() const{
cd_beg();
rret v = CHSTATI(m_id,1,"PROY",0);
cd_end();
return v;
}
rret rms_x() const {
cd_beg();
rret v = CHSTATI(m_id,2,"PROX",0);
cd_end();
return v;
}
rret rms_y() const {
cd_beg();
rret v = CHSTATI(m_id,2,"PROY",0);
cd_end();
return v;
}
const hbook::axis& axis_x() const {return m_axis_x;}
hbook::axis& axis_x() {return m_axis_x;}
const hbook::axis& axis_y() const {return m_axis_y;}
hbook::axis& axis_y() {return m_axis_y;}
int coord_to_index_x(rarg aCoordX) const {
return m_axis_x.coord_to_index(aCoordX);
}
int coord_to_index_y(rarg aCoordY) const {
return m_axis_y.coord_to_index(aCoordY);
}
rret min_bin_height() const {
cd_beg();
rret v = CHMIN(m_id);
cd_end();
return v;
}
rret max_bin_height() const {
cd_beg();
rret v = CHMAX(m_id);
cd_end();
return v;
}
rret bin_height(int aIndexX,int aIndexY) const {
cd_beg();
rret v = CHIJ(m_id,hindex(aIndexX,axis_x()),hindex(aIndexY,axis_y()));
cd_end();
return v;
}
rret sum_bin_heights() const {
int NX = axis_x().bins();
int NY = axis_y().bins();
rret w = 0;
cd_beg();
for(int i=1;i<=NX;i++) {
for(int j=1;j<=NY;j++) {
w += CHIJ(m_id,i,j);
}
}
cd_end();
return w;
}
rret sum_all_bin_heights() const {
int NX1 = axis_x().bins()+1;
int NY1 = axis_y().bins()+1;
rret w = 0;
cd_beg();
for(int i=0;i<=NX1;i++) {
for(int j=0;j<=NY1;j++) {
w += CHIJ(m_id,i,j);
}
}
cd_end();
return w;
}
rret sum_extra_bin_heights() const {
int NX = axis_x().bins();
int NY = axis_y().bins();
int NX1 = NX+1;
int NY1 = NY+1;
rret w = 0;
cd_beg();
{for(int j=0;j<=NY1;j++) {
w += CHIJ(m_id,0,j);
}}
for(int i=1;i<=NX;i++) {
w += CHIJ(m_id,i,0);
w += CHIJ(m_id,i,NY1);
}
{for(int j=0;j<=NY1;j++) {
w += CHIJ(m_id,NX1,j);
}}
cd_end();
return w;
}
rret bin_error(int aIndexX,int aIndexY) const {
cd_beg();
rret v = CHIJE(m_id,aIndexX+1,aIndexY+1);
cd_end();
return v;
}
rret bin_height_x(int aIndexX) const {
int i = hindex(aIndexX,axis_x());
int NY1 = axis_y().bins()+1;
rret w = 0;
cd_beg();
for(int j=0;j<=NY1;j++) {
w += CHIJ(m_id,i,j);
}
cd_end();
return w;
}
rret bin_height_y(int aIndexY) const {
int j = hindex(aIndexY,axis_y());
int NX1 = axis_x().bins()+1;
rret w = 0;
cd_beg();
for(int i=0;i<=NX1;i++) {
w += CHIJ(m_id,i,j);
}
cd_end();
return w;
}
protected:
hbook::axis m_axis_x;
hbook::axis m_axis_y;
};
}}
#endif
@@ -0,0 +1,72 @@
/* 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_(){}
@@ -0,0 +1,44 @@
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
@@ -0,0 +1,10 @@
INTEGER FUNCTION HISID(ID)
IMPLICIT NONE
INTEGER ID
LOGICAL HEXIST
IF(HEXIST(ID).EQV..TRUE.) THEN
HISID = 1
ELSE
HISID = 0
ENDIF
END
@@ -0,0 +1,164 @@
*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
@@ -0,0 +1,80 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_hbook_p1
#define tools_hbook_p1
#include "base_histo"
namespace tools {
namespace hbook {
class p1 : public base_histo {
public:
p1(int aID,const std::string& aTitle,
int aXnumber,rarg aXmin,rarg aXmax,
rarg aVmin,rarg aVmax)
:base_histo(aID)
,m_axis(m_path,aID,1,true,true)
{
cd_beg();
CHBPROF(m_id,aTitle,
aXnumber,aXmin,aXmax,
aVmin,aVmax,
""); //FIXME : or "S" or "T" ?
cd_end();
}
virtual ~p1(){
cd_beg();
CHDELET(m_id);
cd_end();
}
private:
p1(const p1& a_from)
:base_histo(a_from)
,m_axis(a_from.m_axis)
{}
p1& operator=(const p1& a_from){
base_histo::operator=(a_from);
m_axis = a_from.m_axis;
return *this;
}
public:
bool configure(int aXnumber,rarg aXmin,rarg aXmax,rarg aVmin,rarg aVmax){
cd_beg();
CHBPROF(m_id,title(),
aXnumber,aXmin,aXmax,
aVmin,aVmax,
""); //FIXME : or "S" or "T" ?
cd_end();
return true;
}
public:
void fill(rarg aX,rarg aY,rarg aWeight = 1) {
cd_beg();
CHFILL(m_id,aX,aY,aWeight);
cd_end();
}
// optimization :
void fill_beg() const {cd_beg();}
void fill_fast(rarg aX,rarg aY,rarg aWeight = 1) {
CHFILL(m_id,aX,aY,aWeight);
}
void fill_end() const {cd_end();}
int dimension() const {return 1;}
const hbook::axis& axis() const {return m_axis;}
hbook::axis& axis() {return m_axis;}
int coord_to_index(rarg aCoord) const {
return m_axis.coord_to_index(aCoord);
}
protected:
hbook::axis m_axis;
};
}}
#endif
@@ -0,0 +1,9 @@
INTEGER*4 FUNCTION SETNTUC()
INTEGER NNTUC
PARAMETER (NNTUC = 200)
INTEGER*4 NVAR,P
COMMON /NTUC/ NVAR,P(NNTUC)
NVAR = 0
SETNTUC = NNTUC
RETURN
END
@@ -0,0 +1,10 @@
INTEGER*4 FUNCTION SETPAWC()
INTEGER NPAWC
PARAMETER (NPAWC = 1000000)
INTEGER P
COMMON /PAWC/ P(NPAWC)
INTEGER IQUEST
COMMON/QUEST/IQUEST(100)
SETPAWC = NPAWC
RETURN
END
@@ -0,0 +1,263 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_hbook_wfile
#define tools_hbook_wfile
#include <sstream>
#include <ostream>
#include "CHBOOK"
#include <tools/srep>
#include <tools/sout>
#ifdef WIN32
extern "C" void __stdcall OCLOSE(int*);
#else
extern "C" void oclose_(int*);
#endif
namespace tools {
namespace hbook {
class wfile {
public:
wfile(std::ostream& a_out,const std::string& a_file,
unsigned int a_unit = 1,bool a_verbose = false)
:m_out(a_out)
,m_verbose(a_verbose)
,m_file_name(a_file)
,m_is_valid(false)
,m_unit(0)
{
std::string opts("NQ");
// maximum number of records
get_quest()[9] = 65000;
int record_size = 1024;
m_dir = "LUN";
{std::ostringstream strm;
strm << a_unit;
m_dir += strm.str();}
//FIXME : we should check if m_dir already exists.
int ier = CHROPEN(a_unit,m_dir,m_file_name,opts,record_size);
if(ier) {
m_out << "tools::hbook::wfile :"
<< " error on hropen, code " << ier
<< std::endl;
return;
}
if(get_quest()[0]) {
m_out << "tools::hbook::wfile :"
<< " error, cannot open file " << a_file
<< std::endl;
return;
}
if(m_verbose) {
m_out << "tools::hbook::wfile :"
<< " file " << a_file << " opened."
<< std::endl;
}
CHCDIR("//PAWC"," ");
if(CHEDIR(m_dir,true)) CHDDIR(m_dir);
CHMDIR(m_dir," ");
CHCDIR("//PAWC/"+m_dir," ");
m_unit = a_unit;
m_is_valid = true;
}
virtual ~wfile() {
if(m_verbose) {
m_out << "tools::hbook::wfile::~wfile : cleanup..." << std::endl;
}
//rootFolder().clear();
if(m_is_valid) {
//CHDELET(0);
if(m_verbose) {
m_out << "tools::hbook::wfile::~wfile : hrend..." << std::endl;
}
CHREND(m_dir);
#ifdef WIN32
OCLOSE(&m_unit);
#else
oclose_(&m_unit);
#endif
m_unit = 0;
CHCDIR("//PAWC"," ");
if(CHEDIR(m_dir,true)) CHDDIR(m_dir);
}
if(m_verbose) {
m_out << "tools::hbook::wfile::~wfile : end." << std::endl;
}
}
private:
wfile(const wfile& a_from):m_out(a_from.m_out){}
wfile& operator=(const wfile&){return *this;}
public:
const std::string& store_name() const {return m_file_name;}
bool is_valid() const {return m_is_valid;}
bool write() {
if(!m_is_valid) return false;
std::string pwd = CHPWD();
CHCDIR("//PAWC/"+m_dir," ");
CHCDIR("//"+m_dir," ");
CHROUT(0,0,"T");
//CHLDIR("//PAWC/"+m_dir,"T");
//CHLDIR("//"+m_dir,"T");
CHCDIR(pwd," ");
return true;
}
bool close() {
if(!m_is_valid) return true; //done or not opened.
CHREND(m_dir);
#ifdef WIN32
OCLOSE(&m_unit);
#else
oclose_(&m_unit);
#endif
m_unit = 0;
m_is_valid = false;
return true;
}
bool cd_home(){
if(!m_is_valid) return false;
CHCDIR("//PAWC/"+m_dir," ");
return true;
}
bool cd_up(){
if(!m_is_valid) return false;
std::string pwd = CHPWD(); // pwd should be //PAWC/LUN<unit>/<something>
if(pwd.substr(0,10)!="//PAWC/LUN") {
m_out << "tools::hbook::wfile::cd_up :"
<< " current directory " << tools::sout(pwd)
<< " is not under //PAWC/LUN."
<< std::endl;
return false;
}
// look if not under //PAWC/LUN<unit> :
{std::string s = pwd;
tools::replace(s,"//PAWC/LUN","");
if(s.find('/')==std::string::npos) return true;} //Can't cd. But it is ok.
CHCDIR("\\"," "); //cd up under //PAWC/LUN<unit>/<something>
std::string pwd2 = CHPWD();
std::string s = pwd;
tools::replace(s,"//PAWC","/");
// s should be //LUN<unit>/<something>
CHCDIR(s," ");
CHCDIR("\\"," "); //cd up under //LUN<unit>/<something>
CHCDIR(pwd2," ");
return true;
}
bool mkdir(const std::string& a_name){
// create a directory under
// //LUN<unit>/<something>
// and
// //PAWC/LUN<unit>/<something>
if(!m_is_valid) return false;
// a_name should not be a path.
if(a_name.find('/')!=std::string::npos) {
m_out << "tools::hbook::wfile::mkdir :"
<< " " << tools::sout(a_name) << " should not be a path."
<< std::endl;
return false;
}
if(a_name.find('.')!=std::string::npos) {
m_out << "tools::hbook::wfile::mkdir :"
<< " " << tools::sout(a_name) << " should not be a path."
<< std::endl;
return false;
}
if(a_name.empty()) return true;
std::string pwd = CHPWD(); // pwd should be //PAWC/LUN<unit>/<something>
if(pwd.substr(0,10)!="//PAWC/LUN") {
m_out << "tools::hbook::wfile::mkdir :"
<< " current directory " << tools::sout(pwd)
<< " is not under //PAWC/LUN."
<< std::endl;
return false;
}
if(CHEDIR(a_name,true)) {
//we assume that a_name is also here under //LUN<unit>/<something>
return true;
}
CHMDIR(a_name," ");
std::string s = pwd;
tools::replace(s,"//PAWC","/");
// s should be //LUN<unit>/<something>
CHCDIR(s," ");
CHMDIR(a_name," ");
CHCDIR(pwd," ");
return true;
}
bool mkcd(const std::string& a_name){
if(!mkdir(a_name)) return false;
CHCDIR(a_name," ");
return true;
}
bool cd(const std::string& a_name){
CHCDIR(a_name," ");
return true;
}
private:
std::ostream& m_out;
bool m_verbose;
std::string m_file_name;
bool m_is_valid;
std::string m_dir;
int m_unit;
};
}}
#endif
// NOTE :
// For doing RZ write :
// - A //LUN<unit> has to be open.
// - We create a //PAWC/LUN<unit> under //PAWC.
// - The hierarchy is done in //PAWC/LUN<unit> and histos
// are booked here. (A HBOOK1 books anyway in a directory under //PAWC).
// - The //PAWC/LUN<unit> structure has to be duplicated under //LUN<unit>.
// - Then a global CHROUT(0,0,"T") can be done after doing :
// CHCDIR("//PAWC/LUN<unit>"," ")
// CHCDIR("//LUN<unit>"," ")
@@ -0,0 +1,237 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_hbook_wntuple
#define tools_hbook_wntuple
// A class to write an HBOOK ntuple.
#include <tools/vmanip>
#include <tools/vfind>
#include <tools/srep>
#include <tools/sto>
#include <tools/scast>
#include <tools/stype>
#include <tools/ntuple_booking>
#include "CHBOOK"
#ifdef WIN32
extern "C" int NTUC[1];
#else
extern "C" int ntuc_[1];
#endif
namespace tools {
namespace hbook {
class wntuple {
protected:
class icol {
public:
virtual ~icol(){}
public:
virtual void* cast(const std::string&) const = 0;
virtual const std::string& s_cls() const = 0;
public:
virtual const std::string& name() const = 0; //for find_named
};
public:
template <class T>
class column : public virtual icol {
public:
static const std::string& s_class() {
static const std::string s_v
("tools::hbook::wntuple::column<"+tools::stype(T())+">");
return s_v;
}
public: //icol
virtual void* cast(const std::string& a_class) const {
if(void* p = tools::cmp_cast< column<T> >(this,a_class)) return p;
else return 0;
}
virtual const std::string& s_cls() const {return s_class();}
virtual const std::string& name() const {return m_name;}
public:
column(const std::string& a_name)
:m_name(a_name),m_tmp(0)
{}
virtual ~column(){}
protected:
column(const column& a_from)
:icol(a_from),m_name(a_from.m_name),m_tmp(a_from.m_tmp)
{}
column& operator=(const column& a_from){
m_name = a_from.m_name;
m_tmp = a_from.m_tmp;
return *this;
}
public:
void set_address(T* a_pos) {m_tmp = a_pos;}
bool fill(const T& a_value) {*m_tmp = a_value;return true;}
protected:
std::string m_name;
T* m_tmp;
};
public:
wntuple(int a_id,const std::string& a_title)
:m_path(CHPWD()),m_id(a_id),m_path_file(CHPWD())
{
// WARNING : the below assumes that we are under //PAWC/<something>
// and that a //<something> exists and is attached to a file.
tools::replace(m_path_file,"//PAWC","/");
cd_beg();
CHBNT(m_id,a_title," ");
cd_end();
}
wntuple(int a_id,std::ostream& a_out,const tools::ntuple_booking& a_bkg)
:m_path(CHPWD()),m_id(a_id),m_path_file(CHPWD())
{
// WARNING : the below assumes that we are under //PAWC/<something>
// 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," ");
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;
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);
} else {
a_out << "tools::hbook::wntuple :"
<< " for column " << tools::sout((*it).first)
<< ", type with cid " << (*it).second << " not yet handled."
<< std::endl;
//throw
tools::clear<icol>(m_cols);
//FIXME : should undo the calls to CHBNAME.
return;
}
}
}
virtual ~wntuple(){
cd_beg();
CHDELET(m_id);
cd_end();
tools::clear<icol>(m_cols);
}
protected:
//Can we copy the HBOOK object ?
wntuple(const wntuple& a_from)
:m_path(a_from.m_path),m_id(a_from.m_id)
{}
wntuple& operator=(const wntuple& a_from){
m_path = a_from.m_path;
m_id = a_from.m_id;
return *this;
}
public:
template <class T>
column<T>* create_column(const std::string& a_name) {
if(tools::find_named<icol>(m_cols,a_name)) return 0;
std::string block("blk"); //8 chars max.
block += tools::to<unsigned int>(m_cols.size());
if(block.size()>8) return 0;
column<T>* col = new column<T>(a_name);
#ifdef WIN32
int nvar = NTUC[0];
char* pos = ((char*)NTUC)+8+8*nvar;
NTUC[0]++;
#else
int nvar = ntuc_[0];
char* pos = ((char*)ntuc_)+8+8*nvar;
ntuc_[0]++;
#endif
col->set_address((T*)pos);
cd_beg();
CHBNAME(m_id,block,pos,a_name+":"+h_type(T()));
cd_end();
m_cols.push_back(col);
return col;
}
bool add_row() {
cd_beg();
CHFNT(m_id);
cd_end();
return true;
}
// optimization :
void add_row_beg() const {cd_beg();}
bool add_row_fast() {CHFNT(m_id);return true;}
void add_row_end() const {cd_end();}
template <class T>
column<T>* find_column(const std::string& a_name) {
icol* col = tools::find_named<icol>(m_cols,a_name);
if(!col) return 0;
return tools::safe_cast<icol, column<T> >(*col);
}
//std::string title() const {
// std::string title;
// int ncx,ncy;
// rarg xmin,xmax,ymin,ymax;
// cd_beg();
// CHGIVE(m_id,title,ncx,xmin,xmax,ncy,ymin,ymax);
// cd_end();
// return title;
//}
const std::vector<icol*>& columns() const {return m_cols;}
protected:
static const std::string& h_type(int) {
static const std::string s_v("I*4");
return s_v;
}
static const std::string& h_type(float) {
static const std::string s_v("R*4");
return s_v;
}
static const std::string& h_type(double) {
static const std::string s_v("R*8");
return s_v;
}
protected:
void cd_beg() const{
wntuple& self = const_cast<wntuple&>(*this);
CHPWDF(self.m_tmp);
CHCDIR(m_path," ");
CHCDIR(m_path_file," "); // cd on file.
}
void cd_end() const {CHCDIR(m_tmp," ");}
protected:
std::string m_path;
int m_id;
std::string m_path_file;
char m_tmp[1024];
std::vector<icol*> m_cols;
};
}}
#endif
@@ -0,0 +1,262 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_axis
#define tools_histo_axis
#include <string>
#include <vector>
namespace tools {
namespace histo {
//TC is for a coordinate.
template <class TC>
class axis {
public:
typedef unsigned int bn_t;
public:
enum { UNDERFLOW_BIN = -2, OVERFLOW_BIN = -1 }; //AIDA casing.
public:
bool is_fixed_binning() const {return m_fixed;}
TC lower_edge() const {return m_minimum_value;}
TC upper_edge() const {return m_maximum_value;}
bn_t bins() const {return m_number_of_bins;}
const std::vector<TC>& edges() const {return m_edges;}
TC bin_width(int aBin) const {
if(aBin==UNDERFLOW_BIN) {
return 0; //FIXME return DBL_MAX;
} else if(aBin==OVERFLOW_BIN) {
return 0; //FIXME return DBL_MAX;
} else if((aBin<0) ||(aBin>=(int)m_number_of_bins)) {
return 0;
} else {
if(m_fixed) {
return m_bin_width;
} else {
return (m_edges[aBin+1]-m_edges[aBin]);
}
}
}
TC bin_lower_edge(int aBin) const {
if(aBin==UNDERFLOW_BIN) {
return 0; //FIXME return -DBL_MAX;
} else if(aBin==OVERFLOW_BIN) {
return 0; //FIXME return bin_upper_edge(m_number_of_bins-1);
} else if((aBin<0) ||(aBin>=(int)m_number_of_bins)) {
return 0;
} else {
if(m_fixed) {
return (m_minimum_value + aBin * m_bin_width);
} else {
return m_edges[aBin];
}
}
}
TC bin_upper_edge(int aBin) const {
if(aBin==UNDERFLOW_BIN) {
return 0; //FIXME bin_lower_edge(0)
} else if(aBin==OVERFLOW_BIN) {
return 0; //FIXME return DBL_MAX;
} else if((aBin<0) ||(aBin>=(int)m_number_of_bins)) {
return 0;
} else {
if(m_fixed) {
return (m_minimum_value + (aBin + 1) * m_bin_width);
} else {
return m_edges[aBin+1];
}
}
}
TC bin_center(int aBin) const {
if(aBin==UNDERFLOW_BIN) {
return 0; //FIXME : -INF
} else if(aBin==OVERFLOW_BIN) {
return 0; //FIXME : +INF
} else if(aBin<0) {
return 0; //FIXME : -INF
} else if(aBin>=(int)m_number_of_bins) {
return 0; //FIXME : +INF
} else {
if(m_fixed) {
return (m_minimum_value + (aBin + 0.5) * m_bin_width);
} else {
return (m_edges[aBin] + m_edges[aBin+1])/2.;
}
}
}
int coord_to_index(TC aValue) const {
if( aValue < m_minimum_value) {
return UNDERFLOW_BIN;
} else if( aValue >= m_maximum_value) {
return OVERFLOW_BIN;
} else {
if(m_fixed) {
return (int)((aValue - m_minimum_value)/m_bin_width);
} else {
for(bn_t index=0;index<m_number_of_bins;index++) {
if((m_edges[index]<=aValue)&&(aValue<m_edges[index+1])) {
return index;
}
}
// Should never pass here...
return UNDERFLOW_BIN;
}
}
}
bool coord_to_absolute_index(TC aValue,bn_t& a_index) const {
if( aValue < m_minimum_value) {
a_index = 0;
return true;
} else if( aValue >= m_maximum_value) {
a_index = m_number_of_bins+1;
return true;
} else {
if(m_fixed) {
a_index = (bn_t)((aValue - m_minimum_value)/m_bin_width)+1;
return true;
} else {
for(bn_t index=0;index<m_number_of_bins;index++) {
if((m_edges[index]<=aValue)&&(aValue<m_edges[index+1])) {
a_index = index+1;
return true;
}
}
// Should never pass here...
a_index = 0;
return false;
}
}
}
bool in_range_to_absolute_index(int a_in,bn_t& a_out) const {
// a_in is given in in-range indexing :
// - [0,n-1] for in-range bins
// - UNDERFLOW_BIN for the iaxis underflow bin
// - OVERFLOW_BIN for the iaxis overflow bin
// Return the absolute indexing in [0,n+1].
if(a_in==UNDERFLOW_BIN) {
a_out = 0;
return true;
} else if(a_in==OVERFLOW_BIN) {
a_out = m_number_of_bins+1;
return true;
} else if((a_in>=0)&&(a_in<(int)m_number_of_bins)){
a_out = a_in + 1;
return true;
} else {
return false;
}
}
public:
// Partition :
bool configure(const std::vector<TC>& aEdges) {
// init :
m_number_of_bins = 0;
m_minimum_value = 0;
m_maximum_value = 0;
m_fixed = true;
m_bin_width = 0;
m_edges.clear();
// setup :
if(aEdges.size()<=1) return false;
bn_t number = aEdges.size()-1;
for(bn_t index=0;index<number;index++) {
if((aEdges[index]>=aEdges[index+1])) {
return false;
}
}
m_edges = aEdges;
m_number_of_bins = number;
m_minimum_value = aEdges[0];
m_maximum_value = aEdges[m_number_of_bins];
m_fixed = false;
return true;
}
bool configure(bn_t aNumber,TC aMin,TC aMax) {
// init :
m_number_of_bins = 0;
m_minimum_value = 0;
m_maximum_value = 0;
m_fixed = true;
m_bin_width = 0;
m_edges.clear();
// setup :
if(aNumber<=0) return false;
if(aMax<=aMin) return false;
m_number_of_bins = aNumber;
m_minimum_value = aMin;
m_maximum_value = aMax;
m_bin_width = (aMax - aMin)/ aNumber;
m_fixed = true;
return true;
}
bool is_compatible(const axis& a_axis) const {
if(m_number_of_bins!=a_axis.m_number_of_bins) return false;
if(m_minimum_value!=a_axis.m_minimum_value) return false;
if(m_maximum_value!=a_axis.m_maximum_value) return false;
return true;
}
public:
axis()
:m_offset(0)
,m_number_of_bins(0)
,m_minimum_value(0)
,m_maximum_value(0)
,m_fixed(true)
,m_bin_width(0)
{}
virtual ~axis(){}
public:
axis(const axis& a_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_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;
return *this;
}
public:
bn_t m_offset;
bn_t m_number_of_bins;
TC m_minimum_value;
TC m_maximum_value;
bool m_fixed;
// Fixed size bins :
TC m_bin_width;
// Variable size bins :
std::vector<TC> m_edges;
};
}}
#endif
@@ -0,0 +1,206 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_b1
#define tools_histo_b1
#include "base_histo"
#include <ostream>
namespace tools {
namespace histo {
template <class TC,class TN,class TW,class TH>
class b1 : public base_histo<TC,TN,TW,TH> {
typedef base_histo<TC,TN,TW,TH> parent;
protected:
enum {AxisX=0};
public:
typedef typename base_histo<TC,TN,TW,TH>::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 rms() const {
TC value;
parent::get_ith_axis_rms(AxisX,value); //can return false.
return value;
}
// 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;
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;
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;
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;
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;
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;
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;
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;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TC sxw = parent::m_bin_Sxw[offset][AxisX];
TC sx2w = parent::m_bin_Sx2w[offset][AxisX];
TC _mean = sxw/sw;
return ::sqrt(::fabs((sx2w / sw) - _mean * _mean));
}
// Axis :
const histo::axis<TC>& axis() const {return parent::m_axes[0];}
histo::axis<TC>& axis() {return parent::m_axes[0];} //touchy
public:
//NOTE : print is a Python keyword.
void hprint(std::ostream& a_out) {
// A la HPRINT.
a_out << parent::dimension() << parent::title() << std::endl;
a_out
<< " * ENTRIES = " << parent::all_entries()
<< " * ALL CHANNELS = " << parent::sum_bin_heights()
<< " * UNDERFLOW = " << bin_height(histo::axis<TC>::UNDERFLOW_BIN)
<< " * OVERFLOW = " << bin_height(histo::axis<TC>::OVERFLOW_BIN)
<< std::endl;
a_out
<< " * BIN WID = " << axis().bin_width(0)
<< " * MEAN VALUE = " << mean()
<< " * R . M . S = " << rms()
<< std::endl;
// Some bins :
bn_t bins = axis().bins();
a_out
<< " * ENTRIES[0] = "
<< bin_entries(0)
<< " * HEIGHT[0] = "
<< bin_height(0)
<< " * ERROR[0] = "
<< bin_error(0)
<< std::endl;
a_out
<< " * ENTRIES[N/2] = "
<< bin_entries(bins/2)
<< " * HEIGHT[N/2] = "
<< bin_height(bins/2)
<< " * ERROR[N/2] = "
<< bin_error(bins/2)
<< std::endl;
a_out
<< " * ENTRIES[N-1] = "
<< bin_entries(bins-1)
<< " * HEIGHT[N-1] = "
<< bin_height(bins-1)
<< " * ERROR[N-1] = "
<< bin_error(bins-1)
<< std::endl;
}
protected:
b1(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax){
parent::m_title = a_title;
std::vector<bn_t> nbins;
nbins.push_back(aXnumber);
std::vector<TC> mins;
mins.push_back(aXmin);
std::vector<TC> maxs;
maxs.push_back(aXmax);
parent::configure(1,nbins,mins,maxs);
}
b1(const std::string& a_title,const std::vector<TC>& aEdges) {
parent::m_title = a_title;
std::vector< std::vector<TC> > edges(1);
edges[0] = aEdges;
parent::configure(1,edges);
}
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;
}
public:
bool configure(bn_t aXnumber,TC aXmin,TC aXmax){
std::vector<bn_t> nbins;
nbins.push_back(aXnumber);
std::vector<TC> mins;
mins.push_back(aXmin);
std::vector<TC> maxs;
maxs.push_back(aXmax);
return parent::configure(1,nbins,mins,maxs);
}
bool configure(const std::vector<TC>& aEdges) {
std::vector< std::vector<TC> > edges(1);
edges[0] = aEdges;
return parent::configure(1,edges);
}
};
}}
#endif
@@ -0,0 +1,472 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_b2
#define tools_histo_b2
#include "base_histo"
#include <ostream>
namespace tools {
namespace histo {
template <class TC,class 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;
protected:
enum {AxisX=0,AxisY=1};
public:
typedef typename base_histo<TC,TN,TW,TH>::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;
}
TC mean_y() const {
if(m_in_range_Sw==0) return 0;
return m_in_range_Syw/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));
}
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));
}
int coord_to_index_x(TC aCoord) const {
return axis_x().coord_to_index(aCoord);
}
int coord_to_index_y(TC aCoord) const {
return axis_y().coord_to_index(aCoord);
}
// bins :
TN bin_entries(int aI,int aJ) const {
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;
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;
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;
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;
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;
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;
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;
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;
return this->get_bin_height(offset);
}
TC bin_center_x(int aI) const {
return parent::m_axes[0].bin_center(aI);
}
TC bin_center_y(int aJ) const {
return parent::m_axes[1].bin_center(aJ);
}
TC bin_mean_x(int aI,int aJ) const {
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;
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;
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;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TC sxw = parent::m_bin_Sxw[offset][AxisX];
TC sx2w = parent::m_bin_Sx2w[offset][AxisX];
TC mean = sxw/sw;
return ::sqrt(::fabs((sx2w / sw) - mean * mean));
}
TC bin_rms_y(int aI,int aJ) const {
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;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TC sxw = parent::m_bin_Sxw[offset][AxisY];
TC sx2w = parent::m_bin_Sx2w[offset][AxisY];
TC mean = sxw/sw;
return ::sqrt(::fabs((sx2w / sw) - mean * mean));
}
// Axes :
const axis<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
// Projection :
TN bin_entries_x(int aI) const {
if(!parent::m_dimension) return 0;
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
bn_t ybins = parent::m_axes[1].bins()+2;
bn_t offset;
TN _entries = 0;
for(bn_t jbin=0;jbin<ybins;jbin++) {
offset = ibin + jbin * parent::m_axes[1].m_offset;
_entries += parent::m_bin_entries[offset];
}
return _entries;
}
TW bin_height_x(int aI) const {
if(!parent::m_dimension) return 0;
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
bn_t ybins = parent::m_axes[1].bins()+2;
bn_t offset;
TW sw = 0;
for(bn_t jbin=0;jbin<ybins;jbin++) {
offset = ibin + jbin * parent::m_axes[1].m_offset;
sw += this->get_bin_height(offset);
}
return sw;
}
TN bin_entries_y(int aJ) const {
if(!parent::m_dimension) return 0;
bn_t jbin;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t xbins = parent::m_axes[0].bins()+2;
bn_t offset;
TN _entries = 0;
for(bn_t ibin=0;ibin<xbins;ibin++) {
offset = ibin + jbin * parent::m_axes[1].m_offset;
_entries += parent::m_bin_entries[offset];
}
return _entries;
}
TW bin_height_y(int aJ) const {
if(!parent::m_dimension) return 0;
bn_t jbin;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t xbins = parent::m_axes[0].bins()+2;
bn_t offset;
TW sw = 0;
for(bn_t ibin=0;ibin<xbins;ibin++) {
offset = ibin + jbin * parent::m_axes[1].m_offset;
sw += this->get_bin_height(offset);
}
return sw;
}
public:
//NOTE : print is a Python keyword.
void hprint(std::ostream& a_out) {
// A la HPRINT.
a_out << parent::dimension() << parent::title() << std::endl;
a_out
<< " * ENTRIES = " << parent::all_entries() << std::endl;
// 6 | 7 | 8
// -----------
// 3 | 4 | 5
// -----------
// 0 | 1 | 2
TW height_0 = bin_height(axis_t::UNDERFLOW_BIN,
axis_t::UNDERFLOW_BIN);
TW height_2 = bin_height(axis_t::OVERFLOW_BIN,
axis_t::UNDERFLOW_BIN);
TW height_6 = bin_height(axis_t::UNDERFLOW_BIN,
axis_t::OVERFLOW_BIN);
TW height_8 = bin_height(axis_t::OVERFLOW_BIN,
axis_t::OVERFLOW_BIN);
bn_t i,j;
TW height_1 = 0;
TW height_7 = 0;
for(i=0;i<axis_x().bins();i++){
height_1 += bin_height(i,axis_t::UNDERFLOW_BIN);
height_7 += bin_height(i,axis_t::OVERFLOW_BIN);
}
TW height_3 = 0;
TW height_5 = 0;
for(j=0;j<axis_y().bins();j++){
height_3 += bin_height(axis_t::UNDERFLOW_BIN,j);
height_5 += bin_height(axis_t::OVERFLOW_BIN,j);
}
TW height_4 = 0;
for(i=0;i<axis_x().bins();i++){
for(j=0;j<axis_y().bins();j++){
height_4 += bin_height(i,j);
}
}
a_out
<< " " << height_6 << " " << height_7 << " " << height_8 << std::endl;
a_out
<< " " << height_3 << " " << height_4 << " " << height_5 << std::endl;
a_out
<< " " << height_0 << " " << height_1 << " " << height_2 << std::endl;
// Some bins :
bn_t xbins = axis_x().bins();
bn_t ybins = axis_y().bins();
a_out
<< " * ENTRIES[0,0] = "
<< bin_entries(0,0)
<< " * HEIGHT[0,0] = "
<< bin_height(0,0)
<< " * ERROR[0,0] = "
<< bin_error(0,0)
<< std::endl;
a_out
<< " * ENTRIES[N/2,N/2] = "
<< bin_entries(xbins/2,ybins/2)
<< " * HEIGHT[N/2,N/2] = "
<< bin_height(xbins/2,ybins/2)
<< " * ERROR[N/2,N/2] = "
<< bin_error(xbins/2,ybins/2)
<< std::endl;
a_out
<< " * ENTRIES[N-1,N-1] = "
<< bin_entries(xbins-1,ybins-1)
<< " * HEIGHT[N-1,N-1] = "
<< bin_height(xbins-1,ybins-1)
<< " * ERROR[N-1,N-1] = "
<< bin_error(xbins-1,ybins-1)
<< std::endl;
}
protected:
b2(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax,
bn_t aYnumber,TC aYmin,TC aYmax)
: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)
{
parent::m_title = a_title;
std::vector<bn_t> nbins;
nbins.push_back(aXnumber);
nbins.push_back(aYnumber);
std::vector<TC> mins;
mins.push_back(aXmin);
mins.push_back(aYmin);
std::vector<TC> maxs;
maxs.push_back(aXmax);
maxs.push_back(aYmax);
parent::configure(2,nbins,mins,maxs);
}
b2(const std::string& a_title,
const std::vector<TC>& 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)
{
parent::m_title = a_title;
std::vector< std::vector<TC> > edges(2);
edges[0] = aEdgesX;
edges[1] = aEdgesY;
parent::configure(2,edges);
}
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;
}
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;
std::vector<bn_t> nbins;
nbins.push_back(aXnumber);
nbins.push_back(aYnumber);
std::vector<TC> mins;
mins.push_back(aXmin);
mins.push_back(aYmin);
std::vector<TC> maxs;
maxs.push_back(aXmax);
maxs.push_back(aYmax);
return parent::configure(2,nbins,mins,maxs);
}
bool configure(const std::vector<TC>& 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;
std::vector< std::vector<TC> > edges(2);
edges[0] = aEdgesX;
edges[1] = aEdgesY;
return parent::configure(2,edges);
}
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;
};
}}
#endif
@@ -0,0 +1,518 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_b3
#define tools_histo_b3
#include "base_histo"
#include <ostream>
namespace tools {
namespace histo {
template <class TC,class TN,class TW,class TH>
class b3 : public base_histo<TC,TN,TW,TH> {
typedef base_histo<TC,TN,TW,TH> parent;
public:
typedef axis<TC> axis_t;
typedef typename base_histo<TC,TN,TW,TH>::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);
}
int coord_to_index_y(TC aCoord) const {
return axis_y().coord_to_index(aCoord);
}
int coord_to_index_z(TC aCoord) const {
return axis_z().coord_to_index(aCoord);
}
TC mean_x() const {
if(m_in_range_Sw==0) return 0;
return m_in_range_Sxw/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;
}
TC mean_z() const {
if(m_in_range_Sw==0) return 0;
return m_in_range_Szw/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));
}
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));
}
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));
}
// 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;
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;
return this->get_bin_height(offset);
}
TC bin_center_x(int aI) const {return parent::m_axes[0].bin_center(aI);}
TC bin_center_y(int aJ) const {return parent::m_axes[1].bin_center(aJ);}
TC bin_center_z(int aK) const {return parent::m_axes[2].bin_center(aK);}
TC bin_mean_x(int aI,int aJ,int aK) const {
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;
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;
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;
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;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TC sxw = parent::m_bin_Sxw[offset][AxisX];
TC sx2w = parent::m_bin_Sx2w[offset][AxisX];
TC mean = sxw/sw;
return ::sqrt(::fabs((sx2w / sw) - mean * mean));
}
TC bin_rms_y(int aI,int aJ,int aK) const {
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;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TC sxw = parent::m_bin_Sxw[offset][AxisY];
TC sx2w = parent::m_bin_Sx2w[offset][AxisY];
TC mean = sxw/sw;
return ::sqrt(::fabs((sx2w / sw) - mean * mean));
}
TC bin_rms_z(int aI,int aJ,int aK) const {
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;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TC sxw = parent::m_bin_Sxw[offset][AxisZ];
TC sx2w = parent::m_bin_Sx2w[offset][AxisZ];
TC mean = sxw/sw;
return ::sqrt(::fabs((sx2w / sw) - mean * mean));
}
// Axes :
const axis_t& axis_x() const {return parent::m_axes[0];}
const axis_t& axis_y() const {return parent::m_axes[1];}
const axis_t& axis_z() const {return parent::m_axes[2];}
axis_t& axis_x() {return parent::m_axes[0];} //touchy
axis_t& axis_y() {return parent::m_axes[1];} //touchy
axis_t& axis_z() {return parent::m_axes[2];} //touchy
// Projection :
TN bin_entries_x(int aI) const {
if(!parent::m_dimension) return 0;
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
bn_t jbin,kbin,offset;
bn_t ybins = parent::m_axes[1].bins()+2;
bn_t zbins = parent::m_axes[2].bins()+2;
bn_t yoffset = parent::m_axes[1].m_offset;
bn_t zoffset = parent::m_axes[2].m_offset;
bn_t joffset = ibin;
TN _entries = 0;
for(jbin=0;jbin<ybins;jbin++) {
//joffset = ibin + jbin * parent::m_axes[1].m_offset;
offset = joffset;
for(kbin=0;kbin<zbins;kbin++) {
//offset = joffset + kbin * parent::m_axes[2].m_offset;
_entries += parent::m_bin_entries[offset];
offset += zoffset;
}
joffset += yoffset;
}
return _entries;
}
TN bin_entries_y(int aJ) const {
if(!parent::m_dimension) return 0;
bn_t jbin;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t ibin,kbin,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;
TN _entries = 0;
for(ibin=0;ibin<xbins;ibin++) {
//joffset = ibin + jbin * parent::m_axes[1].m_offset;
offset = joffset;
for(kbin=0;kbin<zbins;kbin++) {
//offset = joffset + kbin * parent::m_axes[2].m_offset;
_entries += parent::m_bin_entries[offset];
offset += zoffset;
}
joffset++;
}
return _entries;
}
TN bin_entries_z(int aK) const {
if(!parent::m_dimension) return 0;
bn_t kbin;
if(!parent::m_axes[2].in_range_to_absolute_index(aK,kbin)) return 0;
bn_t ibin,jbin,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;
TN _entries = 0;
for(ibin=0;ibin<xbins;ibin++) {
//koffset = ibin + kbin * parent::m_axes[2].m_offset;
offset = koffset;
for(jbin=0;jbin<ybins;jbin++) {
//offset = koffset + jbin * parent::m_axes[1].m_offset;
_entries += parent::m_bin_entries[offset];
offset += yoffset;
}
koffset++;
}
return _entries;
}
TW bin_height_x(int aI) const {
//to slow : return get_ith_axis_bin_height(0,aI);
if(!parent::m_dimension) return 0;
bn_t ibin;
if(!parent::m_axes[0].in_range_to_absolute_index(aI,ibin)) return 0;
bn_t ybins = parent::m_axes[1].bins()+2;
bn_t zbins = parent::m_axes[2].bins()+2;
bn_t yoffset = parent::m_axes[1].m_offset;
bn_t zoffset = parent::m_axes[2].m_offset;
bn_t 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;
for(bn_t kbin=0;kbin<zbins;kbin++) {
//offset = joffset + kbin * parent::m_axes[2].m_offset;
sw += this->get_bin_height(offset);
offset += zoffset;
}
joffset += yoffset;
}
return sw;
}
TW bin_height_y(int aJ) const {
if(!parent::m_dimension) return 0;
bn_t jbin;
if(!parent::m_axes[1].in_range_to_absolute_index(aJ,jbin)) return 0;
bn_t xbins = parent::m_axes[0].bins()+2;
bn_t zbins = parent::m_axes[2].bins()+2;
bn_t yoffset = parent::m_axes[1].m_offset;
bn_t zoffset = parent::m_axes[2].m_offset;
bn_t 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;
for(bn_t kbin=0;kbin<zbins;kbin++) {
//offset = joffset + kbin * parent::m_axes[2].m_offset;
sw += this->get_bin_height(offset);
offset += zoffset;
}
joffset++;
}
return sw;
}
TW bin_height_z(int aK) const {
if(!parent::m_dimension) return 0;
bn_t kbin;
if(!parent::m_axes[2].in_range_to_absolute_index(aK,kbin)) return 0;
bn_t xbins = parent::m_axes[0].bins()+2;
bn_t ybins = parent::m_axes[1].bins()+2;
bn_t yoffset = parent::m_axes[1].m_offset;
bn_t zoffset = parent::m_axes[2].m_offset;
bn_t 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;
for(bn_t jbin=0;jbin<ybins;jbin++) {
//offset = koffset + jbin * parent::m_axes[1].m_offset;
sw += this->get_bin_height(offset);
offset += yoffset;
}
koffset++;
}
return sw;
}
public:
//NOTE : print is a Python keyword.
void hprint(std::ostream& a_out) {
// A la HPRINT.
a_out << parent::dimension() << parent::title() << std::endl;
a_out
<< " * ENTRIES = " << parent::all_entries() << std::endl;
}
public:
b3(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax,
bn_t aYnumber,TC aYmin,TC aYmax,
bn_t aZnumber,TC aZmin,TC aZmax)
: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)
{
parent::m_title = a_title;
std::vector<bn_t> nbins;
nbins.push_back(aXnumber);
nbins.push_back(aYnumber);
nbins.push_back(aZnumber);
std::vector<TC> mins;
mins.push_back(aXmin);
mins.push_back(aYmin);
mins.push_back(aZmin);
std::vector<TC> maxs;
maxs.push_back(aXmax);
maxs.push_back(aYmax);
maxs.push_back(aZmax);
parent::configure(3,nbins,mins,maxs);
}
b3(const std::string& a_title,
const std::vector<TC>& 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)
{
parent::m_title = a_title;
std::vector< std::vector<TC> > edges(3);
edges[0] = aEdgesX;
edges[1] = aEdgesY;
edges[2] = aEdgesZ;
parent::configure(3,edges);
}
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;
}
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);
nbins.push_back(aZnumber);
std::vector<TC> mins;
mins.push_back(aXmin);
mins.push_back(aYmin);
mins.push_back(aZmin);
std::vector<TC> maxs;
maxs.push_back(aXmax);
maxs.push_back(aYmax);
maxs.push_back(aZmax);
return parent::configure(3,nbins,mins,maxs);
}
bool configure(const std::vector<TC>& 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;
edges[2] = aEdgesZ;
return parent::configure(3,edges);
}
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;
};
}}
#endif
@@ -0,0 +1,71 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_base_cloud
#define tools_histo_base_cloud
#include <string>
#include <vector>
#ifdef TOOLS_MEM
#include "../mem"
#endif
namespace tools {
namespace histo {
class base_cloud {
static const std::string& s_class() {
static const std::string s_v("tools::histo::base_cloud");
return s_v;
}
protected:
base_cloud(int aLimit)
:m_limit(aLimit)
,m_Sw(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~base_cloud(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
base_cloud(const base_cloud& a_from)
:m_title(a_from.m_title)
,m_limit(a_from.m_limit)
,m_Sw(a_from.m_Sw)
,m_ws(a_from.m_ws)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
base_cloud& operator=(const base_cloud& a_from){
m_title = a_from.m_title;
m_limit = a_from.m_limit;
m_Sw = a_from.m_Sw;
m_ws = a_from.m_ws;
return *this;
}
public:
const std::string& title() const {return m_title;}
std::string title() {return m_title;}
int max_entries() const {return m_limit;}
protected:
static int UNLIMITED() {return -1;}
static unsigned int BINS() {return 100;}
protected:
std::string m_title;
int m_limit;
double m_Sw;
std::vector<double> m_ws;
};
}}
#endif
@@ -0,0 +1,659 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_base_histo
#define tools_histo_base_histo
#ifdef TOOLS_MEM
#include "../mem"
#endif
#include "histo_data"
#include <cmath>
#include <map> //for annotations
namespace tools {
namespace histo {
//TC is for a coordinate.
//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 {
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 unsigned int dim_t;
protected:
virtual TH get_bin_height(int) 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;
return hd;
}
protected:
base_histo()
:m_dimension(0)
,m_bin_number(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
protected:
virtual ~base_histo(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
base_histo(const base_histo& a_from)
: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)
{
#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;
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;}
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 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];
}
}
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];
}
}
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)) {
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++) {
sh += get_bin_height(ibin);
}
return sh;
}
TH sum_extra_bin_heights() const {
TH sh = 0;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(is_out(ibin)) {
sh += get_bin_height(ibin);
}
}
return sh;
}
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)) {
TH vbin = get_bin_height(ibin);
if(first) {
first = false;
value = vbin;
} else {
if(vbin<=value) value = vbin;
}
}
}
return value;
}
TH max_bin_height() const {
TH value = 0;
bool first = true;
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
if(!is_out(ibin)) {
TH vbin = get_bin_height(ibin);
if(first) {
first = false;
value = vbin;
} else {
if(vbin>=value) value = vbin;
}
}
}
return value;
}
protected:
enum {AxisX=0,AxisY=1,AxisZ=2};
bool configure(dim_t a_dim,
const std::vector<bn_t>& aNumbers,
const std::vector<TC>& aMins,
const std::vector<TC>& aMaxs) {
// Clear :
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();
// Some checks :
if(!a_dim) return false;
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])) {
// do not do :
// m_axes.clear()
// so that :
// b1::axis(),b2::axis_[x,y]()
// do not crash in case of a bad booking.
//m_axes.clear();
return false;
}
}
m_dimension = a_dim;
base_allocate(); //set m_bin_number.
return true;
}
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();
// Some checks :
if(!a_dim) return false;
m_axes.resize(a_dim);
// Setup axes :
for(dim_t iaxis=0;iaxis<a_dim;iaxis++) {
if(!m_axes[iaxis].configure(aEdges[iaxis])) {
//m_axes.clear();
return false;
}
}
m_dimension = a_dim;
base_allocate(); //set m_bin_number.
return true;
}
void base_reset() {
// Reset content (different of clear that deallocate all internal things).
for(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;
}
}
//profile not done here.
}
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);
}
m_bin_entries.resize(n_bin,0);
m_bin_Sw.resize(n_bin,0);
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);
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);
}
}
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;}
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);}
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;}
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.
}
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;}
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;
}
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];
}
}
}
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;
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];
}
}
}
bool base_multiply(const base_histo& a_histo) {
//ill-defined operation. We keep that because of the "ill-defined past".
// We build a new histo with one entry in each bin of weight :
// this.w * a_histo.w
// The current histo is overriden with this new histo.
// The m_bin_Sw2 computation is consistent with FreeHEP and ROOT.
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];
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;
}
}
return true;
}
bool base_divide(const base_histo& a_histo) {
//ill-defined operation. We keep that because of the "ill-defined past".
// We build a new histo with one entry in each bin of weight :
// this.w / a_histo.w
// The current histo is overriden with this new histo.
// The m_bin_Sw2 computation is consistent with FreeHEP and ROOT.
if(!is_compatible(a_histo)) return false;
std::vector<int> is(m_dimension);
for(bn_t ibin=0;ibin<m_bin_number;ibin++) {
get_indices(ibin,is);
TW swa = m_bin_Sw[ibin];
TW swb = a_histo.m_bin_Sw[ibin];
TW sw2a = m_bin_Sw2[ibin];
TW sw2b = a_histo.m_bin_Sw2[ibin];
if(swb!=0) {
m_bin_entries[ibin] = 1;
TW sw = swa / swb;
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;
}
} 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;
}
}
}
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;
}
}
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;
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];
}
}
if(sw==0) return false;
a_value = sxw/sw;
return true;
}
bool get_ith_axis_rms(dim_t a_axis,TC& a_value) const {
a_value = 0;
if(a_axis>=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];
}
}
if(sw==0) return false;
TC mean = sxw/sw;
a_value = ::sqrt(::fabs((sx2w / sw) - mean * mean));
return true;
}
TN get_bin_entries(const std::vector<int>& aIs) const {
if(m_bin_number==0) return 0;
bn_t offset;
if(!get_offset(aIs,offset)) return 0;
return 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 :
inline const std::string& key_axis_x_title() {
static const std::string s_v("axis_x.title");
return s_v;
}
inline const std::string& key_axis_y_title() {
static const std::string s_v("axis_y.title");
return s_v;
}
inline const std::string& key_axis_z_title() {
static const std::string s_v("axis_z.title");
return s_v;
}
}}
#endif
@@ -0,0 +1,244 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_c1d
#define tools_histo_cld
#include "base_cloud"
#include "../mnmx"
#include "h1d"
namespace tools {
namespace histo {
class c1d : public base_cloud {
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::c1d");
return s_v;
}
public:
bool set_title(const std::string& a_title){
m_title = a_title;
if(m_histo) m_histo->set_title(a_title);
return true;
}
unsigned int dimension() const {return 1;}
bool reset() {
clear();
delete m_histo;
m_histo = 0;
return true;
}
unsigned int entries() const {
return m_histo ? m_histo->all_entries() : m_ws.size();
}
public:
double sum_of_weights() const {
return (m_histo ? m_histo->sum_bin_heights() : m_Sw);
}
bool convert_to_histogram(){
if( (m_cnv_x_num<=0) || (m_cnv_x_max<=m_cnv_x_min) ) {
// Cloud min, max should be included in the histo.
double dx = 0.01 * (upper_edge() - lower_edge())/BINS();
return convert(BINS(),lower_edge(),upper_edge() + dx);
} else {
return convert(m_cnv_x_num,m_cnv_x_min,m_cnv_x_max);
}
}
bool is_converted() const {return m_histo ? true : false;}
bool scale(double a_scale) {
if(m_histo) {
return m_histo->scale(a_scale);
} else {
unsigned int number = m_ws.size();
for(unsigned int index=0;index<number;index++) m_ws[index] *= a_scale;
m_Sw *= a_scale;
m_Sxw *= a_scale;
m_Sx2w *= a_scale;
return true;
}
}
bool set_histogram(h1d* a_histo){ //we take ownership of a_histo.
reset();
m_histo = a_histo;
return true;
}
public:
bool fill(double aX,double aW = 1){
if(!m_histo && (m_limit!=UNLIMITED()) &&
((int)m_xs.size()>=m_limit)){
convert_to_histogram();
}
if(m_histo) {
return m_histo->fill(aX,aW);
} else {
if(m_xs.size()) {
m_lower_x = mn<double>(aX,m_lower_x);
m_upper_x = mx<double>(aX,m_upper_x);
} else {
m_lower_x = aX;
m_upper_x = aX;
}
m_xs.push_back(aX);
m_ws.push_back(aW);
m_Sw += aW;
double xw = aX * aW;
m_Sxw += xw;
m_Sx2w += aX * xw;
return true;
}
}
double lower_edge() const {
return (m_histo ? m_histo->axis().lower_edge() : m_lower_x);
}
double upper_edge() const {
return (m_histo ? m_histo->axis().upper_edge() : m_upper_x);
}
double value(unsigned int aIndex) const {return (m_histo ?0:m_xs[aIndex]);}
double weight(unsigned int aIndex) const {return (m_histo ?0:m_ws[aIndex]);}
double mean() const {
return (m_histo ? m_histo->mean() : (m_Sw?m_Sxw/m_Sw:0));
}
double rms() const {
double _rms = 0; //FIXME nan.
if(m_histo) {
_rms = m_histo->rms();
} else {
if(m_Sw==0) {
} else {
double _mean = m_Sxw / m_Sw;
_rms = ::sqrt(::fabs( (m_Sx2w / m_Sw) - _mean * _mean));
}
}
return _rms;
}
bool convert(unsigned int aBins,double aLowerEdge,double aUpperEdge){
if(m_histo) return true;
m_histo = new histo::h1d(base_cloud::title(),aBins,aLowerEdge,aUpperEdge);
if(!m_histo) return false;
bool status = fill_histogram(*m_histo);
clear();
return status;
}
bool convert(const std::vector<double>& aEdges) {
if(m_histo) return true;
m_histo = new histo::h1d(base_cloud::title(),aEdges);
if(!m_histo) return false;
bool status = fill_histogram(*m_histo);
clear();
return status;
}
const histo::h1d& histogram() const {
if(!m_histo) const_cast<c1d&>(*this).convert_to_histogram();
return *m_histo;
}
bool fill_histogram(histo::h1d& a_histo) const {
unsigned int number = m_xs.size();
for(unsigned int index=0;index<number;index++) {
if(!a_histo.fill(m_xs[index],m_ws[index])) return false;
}
return true;
}
bool set_conversion_parameters(unsigned int aCnvXnumber,
double aCnvXmin,double aCnvXmax){
m_cnv_x_num = aCnvXnumber;
m_cnv_x_min = aCnvXmin;
m_cnv_x_max = aCnvXmax;
return true;
}
public:
c1d()
:base_cloud(UNLIMITED())
,m_lower_x(0),m_upper_x(0)
,m_Sxw(0),m_Sx2w(0)
,m_cnv_x_num(0),m_cnv_x_min(0),m_cnv_x_max(0),m_histo(0)
{}
c1d(const std::string& a_title,int aLimit = -1)
:base_cloud(aLimit)
,m_lower_x(0),m_upper_x(0)
,m_Sxw(0),m_Sx2w(0)
,m_cnv_x_num(0),m_cnv_x_min(0),m_cnv_x_max(0),m_histo(0)
{
set_title(a_title);
}
virtual ~c1d(){delete m_histo;}
public:
c1d(const c1d& a_from)
:base_cloud(a_from)
,m_xs(a_from.m_xs)
,m_lower_x(a_from.m_lower_x)
,m_upper_x(a_from.m_upper_x)
,m_Sxw(a_from.m_Sxw)
,m_Sx2w(a_from.m_Sx2w)
,m_cnv_x_num(a_from.m_cnv_x_num)
,m_cnv_x_min(a_from.m_cnv_x_min)
,m_cnv_x_max(a_from.m_cnv_x_max)
,m_histo(0)
{
if(a_from.m_histo) {
m_histo = new histo::h1d(*a_from.m_histo);
}
}
c1d& operator=(const c1d& a_from){
base_cloud::operator=(a_from);
if(&a_from==this) return *this;
m_xs = a_from.m_xs;
m_lower_x = a_from.m_lower_x;
m_upper_x = a_from.m_upper_x;
m_Sxw = a_from.m_Sxw;
m_Sx2w = a_from.m_Sx2w;
m_cnv_x_num = a_from.m_cnv_x_num;
m_cnv_x_min = a_from.m_cnv_x_min;
m_cnv_x_max = a_from.m_cnv_x_max;
delete m_histo;
m_histo = 0;
if(a_from.m_histo) {
m_histo = new histo::h1d(*a_from.m_histo);
}
return *this;
}
protected:
void clear(){
m_lower_x = 0;
m_upper_x = 0;
m_Sw = 0;
m_Sxw = 0;
m_Sx2w = 0;
m_xs.clear();
m_ws.clear();
}
protected:
std::vector<double> m_xs;
double m_lower_x;
double m_upper_x;
double m_Sxw;
double m_Sx2w;
//
unsigned int m_cnv_x_num;
double m_cnv_x_min;
double m_cnv_x_max;
histo::h1d* m_histo;
};
}}
#endif
@@ -0,0 +1,416 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_c2d
#define tools_histo_c2d
#include "base_cloud"
#include "../mnmx"
#include "h2d"
namespace tools {
namespace histo {
class c2d : public base_cloud {
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::c2d");
return s_v;
}
public:
bool set_title(const std::string&);
unsigned int dimension() const {return 2;}
bool reset();
unsigned int entries() const;
public:
double sum_of_weights() const;
bool convert_to_histogram();
bool is_converted() const;
bool scale(double);
public:
bool fill(double,double,double = 1);
double lower_edge_x() const;
double upper_edge_x() const;
double lower_edge_y() const;
double upper_edge_y() const;
double value_x(unsigned int) const;
double value_y(unsigned int) const;
double weight(unsigned int) const;
double mean_x() const;
double mean_y() const;
double rms_x() const;
double rms_y() const;
bool convert(unsigned int,double,double,
unsigned int,double,double);
bool convert(const std::vector<double>&,const std::vector<double>&);
const histo::h2d& histogram() const;
bool fill_histogram(histo::h2d& a_histo) const {
unsigned int number = m_xs.size();
for(unsigned int index=0;index<number;index++) {
if(!a_histo.fill(m_xs[index],m_ys[index],m_ws[index])) return false;
}
return true;
}
bool set_conversion_parameters(unsigned int,double,double,
unsigned int,double,double);
bool set_histogram(h2d* a_histo){ //we take ownership of a_histo.
reset();
m_histo = a_histo;
return true;
}
public:
c2d();
c2d(const std::string&,int=-1);
virtual ~c2d(){delete m_histo;}
public:
c2d(const c2d& a_from)
:base_cloud(a_from)
,m_xs(a_from.m_xs)
,m_ys(a_from.m_ys)
,m_lower_x(a_from.m_lower_x)
,m_upper_x(a_from.m_upper_x)
,m_lower_y(a_from.m_lower_y)
,m_upper_y(a_from.m_upper_y)
,m_Sxw(a_from.m_Sxw)
,m_Sx2w(a_from.m_Sx2w)
,m_Syw(a_from.m_Syw)
,m_Sy2w(a_from.m_Sy2w)
,m_cnv_x_num(a_from.m_cnv_x_num)
,m_cnv_x_min(a_from.m_cnv_x_min)
,m_cnv_x_max(a_from.m_cnv_x_max)
,m_cnv_y_num(a_from.m_cnv_y_num)
,m_cnv_y_min(a_from.m_cnv_y_min)
,m_cnv_y_max(a_from.m_cnv_y_max)
,m_histo(0)
{
if(a_from.m_histo) {
m_histo = new histo::h2d(*a_from.m_histo);
}
}
c2d& operator=(const c2d& a_from) {
base_cloud::operator=(a_from);
if(&a_from==this) return *this;
m_xs = a_from.m_xs;
m_ys = a_from.m_ys;
m_lower_x = a_from.m_lower_x;
m_upper_x = a_from.m_upper_x;
m_lower_y = a_from.m_lower_y;
m_upper_y = a_from.m_upper_y;
m_Sxw = a_from.m_Sxw;
m_Sx2w = a_from.m_Sx2w;
m_Syw = a_from.m_Syw;
m_Sy2w = a_from.m_Sy2w;
m_cnv_x_num = a_from.m_cnv_x_num;
m_cnv_x_min = a_from.m_cnv_x_min;
m_cnv_x_max = a_from.m_cnv_x_max;
m_cnv_y_num = a_from.m_cnv_y_num;
m_cnv_y_min = a_from.m_cnv_y_min;
m_cnv_y_max = a_from.m_cnv_y_max;
delete m_histo;
m_histo = 0;
if(a_from.m_histo) {
m_histo = new histo::h2d(*a_from.m_histo);
}
return *this;
}
protected:
void clear();
protected:
std::vector<double> m_xs;
std::vector<double> m_ys;
double m_lower_x;
double m_upper_x;
double m_lower_y;
double m_upper_y;
double m_Sxw;
double m_Sx2w;
double m_Syw;
double m_Sy2w;
//
unsigned int m_cnv_x_num;
double m_cnv_x_min;
double m_cnv_x_max;
unsigned int m_cnv_y_num;
double m_cnv_y_min;
double m_cnv_y_max;
histo::h2d* m_histo;
};
}}
namespace tools {
namespace histo {
inline
c2d::c2d()
:base_cloud(UNLIMITED())
,m_lower_x(0)
,m_upper_x(0)
,m_lower_y(0)
,m_upper_y(0)
,m_Sxw(0)
,m_Sx2w(0)
,m_Syw(0)
,m_Sy2w(0)
,m_cnv_x_num(0)
,m_cnv_x_min(0)
,m_cnv_x_max(0)
,m_cnv_y_num(0)
,m_cnv_y_min(0)
,m_cnv_y_max(0)
,m_histo(0)
{}
inline
c2d::c2d(const std::string& a_title,int aLimit)
:base_cloud(aLimit)
,m_lower_x(0)
,m_upper_x(0)
,m_lower_y(0)
,m_upper_y(0)
,m_Sxw(0)
,m_Sx2w(0)
,m_Syw(0)
,m_Sy2w(0)
,m_cnv_x_num(0)
,m_cnv_x_min(0)
,m_cnv_x_max(0)
,m_cnv_y_num(0)
,m_cnv_y_min(0)
,m_cnv_y_max(0)
,m_histo(0)
{
set_title(a_title);
}
inline
bool c2d::is_converted() const {return m_histo ? true : false;}
inline
void c2d::clear(){
m_lower_x = 0;
m_upper_x = 0;
m_lower_y = 0;
m_upper_y = 0;
m_Sw = 0;
m_Sxw = 0;
m_Sx2w = 0;
m_Syw = 0;
m_Sy2w = 0;
m_xs.clear();
m_ys.clear();
m_ws.clear();
}
inline
bool c2d::convert(
unsigned int aBinsX,double aLowerEdgeX,double aUpperEdgeX
,unsigned int aBinsY,double aLowerEdgeY,double aUpperEdgeY
) {
if(m_histo) return true; // Done.
m_histo = new histo::h2d(base_cloud::title(),
aBinsX,aLowerEdgeX,aUpperEdgeX,
aBinsY,aLowerEdgeY,aUpperEdgeY);
if(!m_histo) return false;
bool status = fill_histogram(*m_histo);
clear();
return status;
}
inline
bool c2d::convert_to_histogram(){
if( (m_cnv_x_num<=0) || (m_cnv_x_max<=m_cnv_x_min) ||
(m_cnv_y_num<=0) || (m_cnv_y_max<=m_cnv_y_min) ) {
double dx = 0.01 * (upper_edge_x() - lower_edge_x())/BINS();
double dy = 0.01 * (upper_edge_y() - lower_edge_y())/BINS();
return convert(BINS(),lower_edge_x(),upper_edge_x()+dx,
BINS(),lower_edge_y(),upper_edge_y()+dy);
} else {
return convert(m_cnv_x_num,m_cnv_x_min,m_cnv_x_max,
m_cnv_y_num,m_cnv_y_min,m_cnv_y_max);
}
}
inline
bool c2d::set_title(const std::string& a_title){
m_title = a_title;
if(m_histo) m_histo->set_title(a_title);
return true;
}
inline
bool c2d::scale(double a_scale) {
if(m_histo) {
return m_histo->scale(a_scale);
} else {
unsigned int number = m_ws.size();
for(unsigned int index=0;index<number;index++) m_ws[index] *= a_scale;
m_Sw *= a_scale;
m_Sxw *= a_scale;
m_Sx2w *= a_scale;
m_Syw *= a_scale;
m_Sy2w *= a_scale;
return true;
}
}
inline
bool c2d::reset() {
clear();
delete m_histo;
m_histo = 0;
return true;
}
inline
bool c2d::fill(double aX,double aY,double aW){
if(!m_histo && (m_limit!=UNLIMITED()) && ((int)m_xs.size()>=m_limit)){
convert_to_histogram();
}
if(m_histo) {
return m_histo->fill(aX,aY,aW);
} else {
if(m_xs.size()) {
m_lower_x = mn<double>(aX,m_lower_x);
m_upper_x = mx<double>(aX,m_upper_x);
} else {
m_lower_x = aX;
m_upper_x = aX;
}
if(m_ys.size()) {
m_lower_y = mn<double>(aY,m_lower_y);
m_upper_y = mx<double>(aY,m_upper_y);
} else {
m_lower_y = aY;
m_upper_y = aY;
}
m_xs.push_back(aX);
m_ys.push_back(aY);
m_ws.push_back(aW);
m_Sw += aW;
double xw = aX * aW;
m_Sxw += xw;
m_Sx2w += aX * xw;
double yw = aY * aW;
m_Syw += yw;
m_Sy2w += aY * yw;
return true;
}
}
inline
bool c2d::convert(const std::vector<double>& aEdgesX,const std::vector<double>& aEdgesY) {
if(m_histo) return true;
m_histo = new histo::h2d(base_cloud::title(),
aEdgesX,aEdgesY);
if(!m_histo) return false;
bool status = fill_histogram(*m_histo);
clear();
return status;
}
inline
bool c2d::set_conversion_parameters(
unsigned int aCnvXnumber,double aCnvXmin,double aCnvXmax
,unsigned int aCnvYnumber,double aCnvYmin,double aCnvYmax
){
m_cnv_x_num = aCnvXnumber;
m_cnv_x_min = aCnvXmin;
m_cnv_x_max = aCnvXmax;
m_cnv_y_num = aCnvYnumber;
m_cnv_y_min = aCnvYmin;
m_cnv_y_max = aCnvYmax;
return true;
}
inline
const h2d& c2d::histogram() const {
if(!m_histo) const_cast<c2d&>(*this).convert_to_histogram();
return *m_histo;
}
inline
unsigned int c2d::entries() const {
return m_histo ? m_histo->all_entries() : m_ws.size();
}
inline
double c2d::sum_of_weights() const {
return (m_histo ? m_histo->sum_bin_heights() : m_Sw);
}
inline
double c2d::lower_edge_x() const {
return m_histo ? m_histo->axis_x().lower_edge() : m_lower_x;
}
inline
double c2d::lower_edge_y() const {
return m_histo ? m_histo->axis_y().lower_edge() : m_lower_y;
}
inline
double c2d::upper_edge_x() const {
return m_histo ? m_histo->axis_x().upper_edge() : m_upper_x;
}
inline
double c2d::upper_edge_y() const {
return m_histo ? m_histo->axis_y().upper_edge() : m_upper_y;
}
inline
double c2d::value_x(unsigned int aIndex) const {
return m_histo ? 0 : m_xs[aIndex];
}
inline
double c2d::value_y(unsigned int aIndex) const {
return m_histo ? 0 : m_ys[aIndex];
}
inline
double c2d::weight(unsigned int aIndex) const {
return m_histo ? 0 : m_ws[aIndex];
}
inline
double c2d::mean_x() const {
return m_histo ? m_histo->mean_x() : (m_Sw?m_Sxw/m_Sw:0);
}
inline
double c2d::mean_y() const {
return m_histo ? m_histo->mean_y() : (m_Sw?m_Syw/m_Sw:0);
}
inline
double c2d::rms_x() const {
double rms = 0; //FIXME nan.
if(m_histo) {
rms = m_histo->rms_x();
} else {
if(m_Sw==0) {
} else {
double mean = m_Sxw / m_Sw;
rms = ::sqrt(::fabs( (m_Sx2w / m_Sw) - mean * mean));
}
}
return rms;
}
inline
double c2d::rms_y() const {
double rms = 0; //FIXME nan.
if(m_histo) {
rms = m_histo->rms_y();
} else {
if(m_Sw==0) {
} else {
double mean = m_Syw / m_Sw;
rms = ::sqrt(::fabs( (m_Sy2w / m_Sw) - mean * mean));
}
}
return rms;
}
}}
#endif
@@ -0,0 +1,526 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_c3d
#define tools_histo_c3d
#include "base_cloud"
#include "../mnmx"
#include "h3d"
namespace tools {
namespace histo {
class c3d : public base_cloud {
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::c3d");
return s_v;
}
public:
bool set_title(const std::string&);
unsigned int dimension() const {return 3;}
bool reset();
unsigned int entries() const;
public:
double sum_of_weights() const;
bool convert_to_histogram();
bool is_converted() const;
bool scale(double);
public:
bool fill(double,double,double,double = 1);
double lower_edge_x() const;
double upper_edge_x() const;
double lower_edge_y() const;
double upper_edge_y() const;
double lower_edge_z() const;
double upper_edge_z() const;
double value_x(unsigned int) const;
double value_y(unsigned int) const;
double value_z(unsigned int) const;
double weight(unsigned int) const;
double mean_x() const;
double mean_y() const;
double mean_z() const;
double rms_x() const;
double rms_y() const;
double rms_z() const;
bool convert(unsigned int,double,double,
unsigned int,double,double,
unsigned int,double,double);
bool convert(const std::vector<double>&,
const std::vector<double>&,
const std::vector<double>&);
const histo::h3d& histogram() const;
bool fill_histogram(histo::h3d& a_histo) const {
unsigned int number = m_xs.size();
for(unsigned int index=0;index<number;index++) {
if(!a_histo.fill(m_xs[index],m_ys[index],m_zs[index],m_ws[index]))
return false;
}
return true;
}
bool set_conversion_parameters(unsigned int,double,double,
unsigned int,double,double,
unsigned int,double,double);
bool set_histogram(h3d* a_histo){ //we take ownership of a_histo.
reset();
m_histo = a_histo;
return true;
}
public:
c3d();
c3d(const std::string&,int=-1);
virtual ~c3d(){delete m_histo;}
public:
c3d(const c3d& a_from)
:base_cloud(a_from)
,m_xs(a_from.m_xs)
,m_ys(a_from.m_ys)
,m_zs(a_from.m_zs)
,m_lower_x(a_from.m_lower_x)
,m_upper_x(a_from.m_upper_x)
,m_lower_y(a_from.m_lower_y)
,m_upper_y(a_from.m_upper_y)
,m_lower_z(a_from.m_lower_z)
,m_upper_z(a_from.m_upper_z)
,m_Sxw(a_from.m_Sxw)
,m_Sx2w(a_from.m_Sx2w)
,m_Syw(a_from.m_Syw)
,m_Sy2w(a_from.m_Sy2w)
,m_Szw(a_from.m_Szw)
,m_Sz2w(a_from.m_Sz2w)
,m_cnv_x_num(a_from.m_cnv_x_num)
,m_cnv_x_min(a_from.m_cnv_x_min)
,m_cnv_x_max(a_from.m_cnv_x_max)
,m_cnv_y_num(a_from.m_cnv_y_num)
,m_cnv_y_min(a_from.m_cnv_y_min)
,m_cnv_y_max(a_from.m_cnv_y_max)
,m_cnv_z_num(a_from.m_cnv_z_num)
,m_cnv_z_min(a_from.m_cnv_z_min)
,m_cnv_z_max(a_from.m_cnv_z_max)
,m_histo(0)
{
if(a_from.m_histo) {
m_histo = new histo::h3d(*a_from.m_histo);
}
}
c3d& operator=(const c3d& a_from) {
base_cloud::operator=(a_from);
if(&a_from==this) return *this;
m_xs = a_from.m_xs;
m_ys = a_from.m_ys;
m_zs = a_from.m_zs;
m_lower_x = a_from.m_lower_x;
m_upper_x = a_from.m_upper_x;
m_lower_y = a_from.m_lower_y;
m_upper_y = a_from.m_upper_y;
m_lower_z = a_from.m_lower_z;
m_upper_z = a_from.m_upper_z;
m_Sxw = a_from.m_Sxw;
m_Sx2w = a_from.m_Sx2w;
m_Syw = a_from.m_Syw;
m_Sy2w = a_from.m_Sy2w;
m_Szw = a_from.m_Szw;
m_Sz2w = a_from.m_Sz2w;
m_cnv_x_num = a_from.m_cnv_x_num;
m_cnv_x_min = a_from.m_cnv_x_min;
m_cnv_x_max = a_from.m_cnv_x_max;
m_cnv_y_num = a_from.m_cnv_y_num;
m_cnv_y_min = a_from.m_cnv_y_min;
m_cnv_y_max = a_from.m_cnv_y_max;
m_cnv_z_num = a_from.m_cnv_z_num;
m_cnv_z_min = a_from.m_cnv_z_min;
m_cnv_z_max = a_from.m_cnv_z_max;
delete m_histo;
m_histo = 0;
if(a_from.m_histo) {
m_histo = new histo::h3d(*a_from.m_histo);
}
return *this;
}
protected:
void clear();
protected:
std::vector<double> m_xs;
std::vector<double> m_ys;
std::vector<double> m_zs;
double m_lower_x;
double m_upper_x;
double m_lower_y;
double m_upper_y;
double m_lower_z;
double m_upper_z;
double m_Sxw;
double m_Sx2w;
double m_Syw;
double m_Sy2w;
double m_Szw;
double m_Sz2w;
//
unsigned int m_cnv_x_num;
double m_cnv_x_min;
double m_cnv_x_max;
unsigned int m_cnv_y_num;
double m_cnv_y_min;
double m_cnv_y_max;
unsigned int m_cnv_z_num;
double m_cnv_z_min;
double m_cnv_z_max;
histo::h3d* m_histo;
};
}}
namespace tools {
namespace histo {
inline
c3d::c3d()
:base_cloud(UNLIMITED())
,m_lower_x(0)
,m_upper_x(0)
,m_lower_y(0)
,m_upper_y(0)
,m_lower_z(0)
,m_upper_z(0)
,m_Sxw(0)
,m_Sx2w(0)
,m_Syw(0)
,m_Sy2w(0)
,m_Szw(0)
,m_Sz2w(0)
,m_cnv_x_num(0)
,m_cnv_x_min(0)
,m_cnv_x_max(0)
,m_cnv_y_num(0)
,m_cnv_y_min(0)
,m_cnv_y_max(0)
,m_cnv_z_num(0)
,m_cnv_z_min(0)
,m_cnv_z_max(0)
,m_histo(0)
{}
inline
c3d::c3d(const std::string& a_title,int aLimit)
:base_cloud(aLimit)
,m_lower_x(0)
,m_upper_x(0)
,m_lower_y(0)
,m_upper_y(0)
,m_lower_z(0)
,m_upper_z(0)
,m_Sxw(0)
,m_Sx2w(0)
,m_Syw(0)
,m_Sy2w(0)
,m_Szw(0)
,m_Sz2w(0)
,m_cnv_x_num(0)
,m_cnv_x_min(0)
,m_cnv_x_max(0)
,m_cnv_y_num(0)
,m_cnv_y_min(0)
,m_cnv_y_max(0)
,m_cnv_z_num(0)
,m_cnv_z_min(0)
,m_cnv_z_max(0)
,m_histo(0)
{
set_title(a_title);
}
inline
bool c3d::is_converted() const {return m_histo ? true : false;}
inline
void c3d::clear(){
m_lower_x = 0;
m_upper_x = 0;
m_lower_y = 0;
m_upper_y = 0;
m_lower_z = 0;
m_upper_z = 0;
m_Sw = 0;
m_Sxw = 0;
m_Sx2w = 0;
m_Syw = 0;
m_Sy2w = 0;
m_Szw = 0;
m_Sz2w = 0;
m_xs.clear();
m_ys.clear();
m_zs.clear();
m_ws.clear();
}
inline
bool c3d::convert(
unsigned int aBinsX,double aLowerEdgeX,double aUpperEdgeX
,unsigned int aBinsY,double aLowerEdgeY,double aUpperEdgeY
,unsigned int aBinsZ,double aLowerEdgeZ,double aUpperEdgeZ
) {
if(m_histo) return true; // Done.
m_histo = new histo::h3d(base_cloud::title(),
aBinsX,aLowerEdgeX,aUpperEdgeX,
aBinsY,aLowerEdgeY,aUpperEdgeY,
aBinsZ,aLowerEdgeZ,aUpperEdgeZ);
if(!m_histo) return false;
bool status = fill_histogram(*m_histo);
clear();
return status;
}
inline
bool c3d::convert_to_histogram(){
if( (m_cnv_x_num<=0) || (m_cnv_x_max<=m_cnv_x_min) ||
(m_cnv_y_num<=0) || (m_cnv_y_max<=m_cnv_y_min) ||
(m_cnv_z_num<=0) || (m_cnv_z_max<=m_cnv_z_min) ) {
double dx = 0.01 * (upper_edge_x() - lower_edge_x())/BINS();
double dy = 0.01 * (upper_edge_y() - lower_edge_y())/BINS();
double dz = 0.01 * (upper_edge_z() - lower_edge_z())/BINS();
return convert(BINS(),lower_edge_x(),upper_edge_x()+dx,
BINS(),lower_edge_y(),upper_edge_y()+dy,
BINS(),lower_edge_z(),upper_edge_z()+dz);
} else {
return convert(m_cnv_x_num,m_cnv_x_min,m_cnv_x_max,
m_cnv_y_num,m_cnv_y_min,m_cnv_y_max,
m_cnv_z_num,m_cnv_z_min,m_cnv_z_max);
}
}
inline
bool c3d::set_title(const std::string& a_title){
m_title = a_title;
if(m_histo) m_histo->set_title(a_title);
return true;
}
inline
bool c3d::scale(double a_scale) {
if(m_histo) {
return m_histo->scale(a_scale);
} else {
unsigned int number = m_ws.size();
for(unsigned int index=0;index<number;index++) m_ws[index] *= a_scale;
m_Sw *= a_scale;
m_Sxw *= a_scale;
m_Sx2w *= a_scale;
m_Syw *= a_scale;
m_Sy2w *= a_scale;
m_Szw *= a_scale;
m_Sz2w *= a_scale;
return true;
}
}
inline
bool c3d::set_conversion_parameters(
unsigned int aCnvXnumber,double aCnvXmin,double aCnvXmax
,unsigned int aCnvYnumber,double aCnvYmin,double aCnvYmax
,unsigned int aCnvZnumber,double aCnvZmin,double aCnvZmax
){
m_cnv_x_num = aCnvXnumber;
m_cnv_x_min = aCnvXmin;
m_cnv_x_max = aCnvXmax;
m_cnv_y_num = aCnvYnumber;
m_cnv_y_min = aCnvYmin;
m_cnv_y_max = aCnvYmax;
m_cnv_z_num = aCnvZnumber;
m_cnv_z_min = aCnvZmin;
m_cnv_z_max = aCnvZmax;
return true;
}
inline
const h3d& c3d::histogram() const {
if(!m_histo) const_cast<c3d&>(*this).convert_to_histogram();
return *m_histo;
}
inline
bool c3d::reset() {
clear();
delete m_histo;
m_histo = 0;
return true;
}
inline
bool c3d::fill(double aX,double aY,double aZ,double aW){
if(!m_histo && (m_limit!=UNLIMITED()) && ((int)m_xs.size()>=m_limit)){
convert_to_histogram();
}
if(m_histo) {
return m_histo->fill(aX,aY,aZ,aW);
} else {
if(m_xs.size()) {
m_lower_x = mn<double>(aX,m_lower_x);
m_upper_x = mx<double>(aX,m_upper_x);
} else {
m_lower_x = aX;
m_upper_x = aX;
}
if(m_ys.size()) {
m_lower_y = mn<double>(aY,m_lower_y);
m_upper_y = mx<double>(aY,m_upper_y);
} else {
m_lower_y = aY;
m_upper_y = aY;
}
if(m_zs.size()) {
m_lower_z = mn<double>(aZ,m_lower_z);
m_upper_z = mx<double>(aZ,m_upper_z);
} else {
m_lower_z = aZ;
m_upper_z = aZ;
}
m_xs.push_back(aX);
m_ys.push_back(aY);
m_zs.push_back(aZ);
m_ws.push_back(aW);
m_Sw += aW;
double xw = aX * aW;
m_Sxw += xw;
m_Sx2w += aX * xw;
double yw = aY * aW;
m_Syw += yw;
m_Sy2w += aY * yw;
double zw = aZ * aW;
m_Szw += zw;
m_Sz2w += aZ * zw;
return true;
}
}
inline
bool c3d::convert(
const std::vector<double>& aEdgesX
,const std::vector<double>& aEdgesY
,const std::vector<double>& aEdgesZ
) {
if(m_histo) return true;
m_histo = new histo::h3d(base_cloud::title(),
aEdgesX,aEdgesY,aEdgesZ);
if(!m_histo) return false;
bool status = fill_histogram(*m_histo);
clear();
return status;
}
inline
double c3d::sum_of_weights() const {
return (m_histo ? m_histo->sum_bin_heights() : m_Sw);
}
inline
unsigned int c3d::entries() const {
return m_histo ? m_histo->all_entries() : m_ws.size();
}
inline
double c3d::lower_edge_x() const {
return m_histo ? m_histo->axis_x().lower_edge() : m_lower_x;
}
inline
double c3d::lower_edge_y() const {
return m_histo ? m_histo->axis_y().lower_edge() : m_lower_y;
}
inline
double c3d::lower_edge_z() const {
return m_histo ? m_histo->axis_z().lower_edge() : m_lower_z;
}
inline
double c3d::upper_edge_x() const {
return m_histo ? m_histo->axis_x().upper_edge() : m_upper_x;
}
inline
double c3d::upper_edge_y() const {
return m_histo ? m_histo->axis_y().upper_edge() : m_upper_y;
}
inline
double c3d::upper_edge_z() const {
return m_histo ? m_histo->axis_z().upper_edge() : m_upper_z;
}
inline
double c3d::value_x(unsigned int aIndex) const {
return m_histo ? 0 : m_xs[aIndex];
}
inline
double c3d::value_y(unsigned int aIndex) const {
return m_histo ? 0 : m_ys[aIndex];
}
inline
double c3d::value_z(unsigned int aIndex) const {
return m_histo ? 0 : m_zs[aIndex];
}
inline
double c3d::weight(unsigned int aIndex) const {
return m_histo ? 0 : m_ws[aIndex];
}
inline
double c3d::mean_x() const {
return m_histo ? m_histo->mean_x() : (m_Sw?m_Sxw/m_Sw:0);
}
inline
double c3d::mean_y() const {
return m_histo ? m_histo->mean_y() : (m_Sw?m_Syw/m_Sw:0);
}
inline
double c3d::mean_z() const {
return m_histo ? m_histo->mean_z() : (m_Sw?m_Szw/m_Sw:0);
}
inline
double c3d::rms_x() const {
double rms = 0; //FIXME nan.
if(m_histo) {
rms = m_histo->rms_x();
} else {
if(m_Sw==0) {
} else {
double mean = m_Sxw / m_Sw;
rms = ::sqrt(::fabs( (m_Sx2w / m_Sw) - mean * mean));
}
}
return rms;
}
inline
double c3d::rms_y() const {
double rms = 0; //FIXME nan.
if(m_histo) {
rms = m_histo->rms_y();
} else {
if(m_Sw==0) {
} else {
double mean = m_Syw / m_Sw;
rms = ::sqrt(::fabs( (m_Sy2w / m_Sw) - mean * mean));
}
}
return rms;
}
inline
double c3d::rms_z() const {
double rms = 0; //FIXME nan.
if(m_histo) {
rms = m_histo->rms_z();
} else {
if(m_Sw==0) {
} else {
double mean = m_Szw / m_Sw;
rms = ::sqrt(::fabs( (m_Sz2w / m_Sw) - mean * mean));
}
}
return rms;
}
}}
#endif
@@ -0,0 +1,183 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h1
#define tools_histo_h1
#include "b1"
namespace tools {
namespace histo { //have that for h1 ?
//TC is for a coordinate.
//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;
public:
typedef typename b1<TC,TN,TW,TH>::bn_t bn_t;
protected:
virtual TH get_bin_height(int 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;
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);}
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();
}
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;
bn_t offset;
if(!parent::m_axes[0].coord_to_absolute_index(aX,offset)) return false;
parent::m_bin_entries[offset]++;
parent::m_bin_Sw[offset] += aWeight;
parent::m_bin_Sw2[offset] += aWeight * aWeight;
TC xw = aX * aWeight;
TC x2w = aX * xw;
parent::m_bin_Sxw[offset][0] += xw;
parent::m_bin_Sx2w[offset][0] += x2w;
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;
}
bool divide(const h1& a_histo) {
if(!parent::base_divide(a_histo)) return false;
parent::update_fast_getters();
return true;
}
bool gather_bins(unsigned int a_factor) { //for exa 2,3.
if(!a_factor) return false;
// actual bin number must be a multiple of a_factor.
const histo::axis<TC>& _axis = parent::axis();
bn_t n = _axis.bins();
if(!n) return false;
bn_t new_n = n/a_factor;
if(a_factor*new_n!=n) return false;
h1* new_h = 0;
if(_axis.is_fixed_binning()) {
new_h = new h1(parent::m_title,
new_n,_axis.lower_edge(),_axis.upper_edge());
} else {
const std::vector<TC>& _edges = _axis.edges();
std::vector<TC> new_edges(new_n+1);
for(bn_t ibin=0;ibin<new_n;ibin++) {
new_edges[ibin] = _edges[ibin*a_factor];
}
new_edges[new_n] = _edges[n]; //upper edge.
new_h = new h1(parent::m_title,new_edges);
}
if(!new_h) return false;
bn_t offset,new_offset,offac;
for(bn_t ibin=0;ibin<new_n;ibin++) {
new_offset = ibin+1;
offset = a_factor*ibin+1;
for(unsigned int ifac=0;ifac<a_factor;ifac++) {
offac = offset+ifac;
new_h->m_bin_entries[new_offset] += parent::m_bin_entries[offac];
new_h->m_bin_Sw[new_offset] += parent::m_bin_Sw[offac];
new_h->m_bin_Sw2[new_offset] += parent::m_bin_Sw2[offac];
new_h->m_bin_Sxw[new_offset][0] += parent::m_bin_Sxw[offac][0];
new_h->m_bin_Sx2w[new_offset][0] += parent::m_bin_Sx2w[offac][0];
}
}
//underflow :
new_offset = 0;
offac = 0;
new_h->m_bin_entries[new_offset] = parent::m_bin_entries[offac];
new_h->m_bin_Sw[new_offset] = parent::m_bin_Sw[offac];
new_h->m_bin_Sw2[new_offset] = parent::m_bin_Sw2[offac];
new_h->m_bin_Sxw[new_offset][0] = parent::m_bin_Sxw[offac][0];
new_h->m_bin_Sx2w[new_offset][0] = parent::m_bin_Sx2w[offac][0];
//overflow :
new_offset = new_n+1;
offac = n+1;
new_h->m_bin_entries[new_offset] = parent::m_bin_entries[offac];
new_h->m_bin_Sw[new_offset] = parent::m_bin_Sw[offac];
new_h->m_bin_Sw2[new_offset] = parent::m_bin_Sw2[offac];
new_h->m_bin_Sxw[new_offset][0] = parent::m_bin_Sxw[offac][0];
new_h->m_bin_Sx2w[new_offset][0] = parent::m_bin_Sx2w[offac][0];
*this = *new_h;
return true;
}
public:
h1(const std::string& a_title,bn_t aXnumber,TC aXmin,TC aXmax)
:parent(a_title,aXnumber,aXmin,aXmax){}
h1(const std::string& a_title,const std::vector<TC>& aEdges)
:parent(a_title,aEdges){}
virtual ~h1(){}
public:
h1(const h1& a_from): parent(a_from){}
h1& operator=(const h1& a_from){
parent::operator=(a_from);
return *this;
}
};
}}
#endif
@@ -0,0 +1,54 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h1d
#define tools_histo_h1d
#include "h1"
namespace tools {
namespace histo {
// d in h1d is for double (and not dimension).
class h1d : public h1<double,unsigned int,double,double> {
typedef h1<double,unsigned int,double,double> parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::h1d");
return s_v;
}
public:
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)
:parent(a_title,aEdges){}
virtual ~h1d(){}
public:
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);}
};
}}
#endif
@@ -0,0 +1,149 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h2
#define tools_histo_h2
#include "b2"
namespace tools {
namespace histo {
template <class TC,class TN,class TW,class TH>
class h2 : public b2<TC,TN,TW,TH> {
typedef b2<TC,TN,TW,TH> parent;
public:
typedef typename b2<TC,TN,TW,TH>::bn_t bn_t;
protected:
virtual TH get_bin_height(int 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;
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);}
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();
}
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;
bn_t ibin,jbin;
if(!parent::m_axes[0].coord_to_absolute_index(aX,ibin)) return false;
if(!parent::m_axes[1].coord_to_absolute_index(aY,jbin)) return false;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
parent::m_bin_entries[offset]++;
parent::m_bin_Sw[offset] += aWeight;
parent::m_bin_Sw2[offset] += aWeight * aWeight;
TC xw = aX * aWeight;
TC x2w = aX * xw;
parent::m_bin_Sxw[offset][0] += xw;
parent::m_bin_Sx2w[offset][0] += x2w;
TC yw = aY * aWeight;
TC y2w = aY * yw;
parent::m_bin_Sxw[offset][1] += yw;
parent::m_bin_Sx2w[offset][1] += y2w;
bool inRange = true;
if(ibin==0) inRange = false;
else if(ibin==(parent::m_axes[0].m_number_of_bins+1)) inRange = false;
if(jbin==0) inRange = false;
else if(jbin==(parent::m_axes[1].m_number_of_bins+1)) inRange = false;
if(inRange) {
parent::m_in_range_entries++;
parent::m_in_range_Sw += 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;
}
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;
}
bool divide(const h2& a_histo) {
if(!parent::base_divide(a_histo)) return false;
parent::update_fast_getters();
return true;
}
public:
h2(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax,
bn_t aYnumber,TC aYmin,TC aYmax)
: parent(a_title,aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax)
{}
h2(const std::string& a_title,
const std::vector<TC>& aEdgesX,
const std::vector<TC>& aEdgesY)
: parent(a_title,aEdgesX,aEdgesY)
{}
virtual ~h2(){}
public:
h2(const h2& a_from): parent(a_from){}
h2& operator=(const h2& a_from){
parent::operator=(a_from);
return *this;
}
};
}}
#endif
@@ -0,0 +1,54 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h2d
#define tools_histo_h2d
#include "h2"
namespace tools {
namespace histo {
class h2d : public h2<double,unsigned int,double,double> {
typedef h2<double,unsigned int,double,double> parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::h2d");
return s_v;
}
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)
{}
h2d(const std::string& a_title,
const std::vector<double>& aEdgesX,
const std::vector<double>& aEdgesY)
: parent(a_title,aEdgesX,aEdgesY)
{}
virtual ~h2d(){}
public:
h2d(const h2d& a_from): parent(a_from){}
h2d& operator=(const h2d& a_from){
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);}
};
}}
#endif
@@ -0,0 +1,182 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h3
#define tools_histo_h3
#include "b3"
namespace tools {
namespace histo {
template <class TC,class TN,class TW,class TH>
class h3 : public b3<TC,TN,TW,TH> {
typedef b3<TC,TN,TW,TH> parent;
public:
typedef typename b3<TC,TN,TW,TH>::bn_t bn_t;
protected:
virtual TH get_bin_height(int 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;
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);}
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();
}
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;
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;
parent::m_bin_entries[offset]++;
parent::m_bin_Sw[offset] += aWeight;
parent::m_bin_Sw2[offset] += aWeight * aWeight;
TC xw = aX * aWeight;
TC x2w = aX * xw;
parent::m_bin_Sxw[offset][0] += xw;
parent::m_bin_Sx2w[offset][0] += x2w;
TC yw = aY * aWeight;
TC y2w = aY * yw;
parent::m_bin_Sxw[offset][1] += yw;
parent::m_bin_Sx2w[offset][1] += y2w;
TC zw = aZ * aWeight;
TC z2w = aZ * zw;
parent::m_bin_Sxw[offset][2] += zw;
parent::m_bin_Sx2w[offset][2] += z2w;
bool inRange = true;
if(ibin==0) inRange = false;
else if(ibin==(parent::m_axes[0].m_number_of_bins+1)) inRange = false;
if(jbin==0) inRange = false;
else if(jbin==(parent::m_axes[1].m_number_of_bins+1)) inRange = false;
if(kbin==0) inRange = false;
else if(kbin==(parent::m_axes[2].m_number_of_bins+1)) inRange = false;
if(inRange) {
parent::m_in_range_entries++;
parent::m_in_range_Sw += 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;
}
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;
}
bool divide(const h3& a_histo) {
if(!parent::base_divide(a_histo)) return false;
parent::update_fast_getters();
return true;
}
public:
/*
// Slices :
h2d* slice_xy(int aKbeg,int aKend) const;
h2d* slice_yz(int aIbeg,int aIend) const;
h2d* slice_xz(int aJbeg,int aJend) const;
*/
public:
h3(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax,
bn_t aYnumber,TC aYmin,TC aYmax,
bn_t aZnumber,TC aZmin,TC aZmax)
: parent(a_title,aXnumber,aXmin,aXmax,
aYnumber,aYmin,aYmax,
aZnumber,aZmin,aZmax)
{}
h3(const std::string& a_title,
const std::vector<TC>& aEdgesX,
const std::vector<TC>& aEdgesY,
const std::vector<TC>& aEdgesZ)
: parent(a_title,aEdgesX,aEdgesY,aEdgesZ)
{}
virtual ~h3(){}
public:
h3(const h3& a_from): parent(a_from){}
h3& operator=(const h3& a_from){
parent::operator=(a_from);
return *this;
}
};
}}
#endif
@@ -0,0 +1,60 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_h3d
#define tools_histo_h3d
#include "h3"
namespace tools {
namespace histo {
class h3d : public h3<double,unsigned int,double,double> {
typedef h3<double,unsigned int,double,double> parent;
public:
static const std::string& s_class() {
static const std::string s_v("tools::histo::h3d");
return s_v;
}
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,
aYnumber,aYmin,aYmax,
aZnumber,aZmin,aZmax)
{}
h3d(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 ~h3d(){}
public:
h3d(const h3d& a_from): parent(a_from){}
h3d& operator=(const h3d& a_from){
parent::operator=(a_from);
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);}
};
}}
#endif
@@ -0,0 +1,206 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_histo_data
#define tools_histo_histo_data
#include <vector>
#include <map> //for annotations
#include "axis"
namespace tools {
namespace histo {
//TC is for a coordinate.
//TN is for a number of entries.
//TW is for a weight.
template <class TC,class TN,class TW>
class histo_data {
public:
typedef typename axis<TC>::bn_t bn_t;
typedef unsigned int dim_t;
public:
histo_data()
:m_dimension(0)
,m_bin_number(0)
//,m_mode(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)
,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& operator=(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;
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;
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;
}
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;
}
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;
}}
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:
// 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 :
std::map<std::string,std::string> m_annotations;
};
}}
#endif
@@ -0,0 +1,332 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_p1
#define tools_histo_p1
#include "b1"
#include "profile_data"
namespace tools {
namespace histo {
//TC is for a coordinate.
//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;
public:
typedef typename base_histo<TC,TN,TW,TH>::bn_t bn_t;
protected:
virtual TH get_bin_height(int 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;
//FIXME Is it correct ?
// TProfile::GetBinError with kERRORMEAN mode does :
// Stat_t cont = fArray[bin]; //Svw (see TProfile::Fill)
// Stat_t sum = parent::m_bin_entries.fArray[bin]; //Sw
// Stat_t err2 = fSumw2.fArray[bin]; //Sv2w
// if (sum == 0) return 0;
// Stat_t eprim;
// Stat_t contsum = cont/sum;
// Stat_t eprim2 = TMath::Abs(err2/sum - contsum*contsum);
// eprim = TMath::Sqrt(eprim2);
// ... ???
// if (fErrorMode == kERRORMEAN) return eprim/TMath::Sqrt(sum);
TW sw = parent::m_bin_Sw[offset]; //ROOT sum
if(sw==0) return 0;
TV svw = m_bin_Svw[offset]; //ROOT cont
TV sv2w = m_bin_Sv2w[offset]; //ROOT err2
TV _mean = (svw / sw); //ROOT contsum
TV _rms = ::sqrt(::fabs((sv2w/sw) - _mean * _mean)); //ROOT eprim
// rms = get_bin_rms_value.
return _rms/::sqrt(sw); //ROOT kERRORMEAN mode returned value
}
public:
bool multiply(TW aFactor){
if(!parent::base_multiply(aFactor)) return false;
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] *= aFactor;
}
parent::update_fast_getters();
return true;
}
bool scale(TW aFactor) {return multiply(aFactor);}
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;
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;
return m_bin_Sv2w[offset];
}
bool reset() {
parent::base_reset();
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] = 0;
m_bin_Sv2w[ibin] = 0;
}
parent::update_fast_getters();
return true;
}
void copy_from_data(const profile_data<TC,TN,TW,TV>& a_from) {
parent::base_from_data(a_from);
m_bin_Svw = a_from.m_bin_Svw;
m_bin_Sv2w = a_from.m_bin_Sv2w;
m_cut_v = a_from.m_cut_v;
m_min_v = a_from.m_min_v;
m_max_v = a_from.m_max_v;
}
profile_data<TC,TN,TW,TV> get_histo_data() const {
profile_data<TC,TN,TW,TV> hd(parent::base_get_data());
hd.m_is_profile = true;
hd.m_bin_Svw = m_bin_Svw;
hd.m_bin_Sv2w = m_bin_Sv2w;
hd.m_cut_v = m_cut_v;
hd.m_min_v = m_min_v;
hd.m_max_v = m_max_v;
return hd;
}
bool fill(TC aX,TV aV,TW aWeight = 1) {
//m_coords[0] = aX;
//return fill_bin(m_coords,aV,aWeight);
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;
parent::m_bin_entries[offset]++;
parent::m_bin_Sw[offset] += aWeight;
parent::m_bin_Sw2[offset] += aWeight * aWeight;
TC xw = aX * aWeight;
TC x2w = aX * xw;
parent::m_bin_Sxw[offset][0] += xw;
parent::m_bin_Sx2w[offset][0] += x2w;
// Profile part :
TV vw = aV * aWeight;
m_bin_Svw[offset] += vw;
m_bin_Sv2w[offset] += aV * vw;
return true;
}
TV bin_rms_value(int aI) 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;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TV svw = m_bin_Svw[offset];
TV sv2w = m_bin_Sv2w[offset];
TV _mean = (svw / sw);
return ::sqrt(::fabs((sv2w / sw) - _mean * _mean));
}
bool add(const p1& a_histo){
parent::base_add(a_histo);
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] += a_histo.m_bin_Svw[ibin];
m_bin_Sv2w[ibin] += a_histo.m_bin_Sv2w[ibin];
}
parent::update_fast_getters();
return true;
}
bool subtract(const p1& a_histo){
parent::base_subtract(a_histo);
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] -= a_histo.m_bin_Svw[ibin];
m_bin_Sv2w[ibin] -= a_histo.m_bin_Sv2w[ibin];
}
parent::update_fast_getters();
return true;
}
bool gather_bins(unsigned int a_factor) { //for exa 2,3.
if(!a_factor) return false;
// actual bin number must be a multiple of a_factor.
const histo::axis<TC>& _axis = parent::axis();
bn_t n = _axis.bins();
if(!n) return false;
bn_t new_n = n/a_factor;
if(a_factor*new_n!=n) return false;
p1* new_h = 0;
if(_axis.is_fixed_binning()) {
new_h = new p1(parent::m_title,
new_n,_axis.lower_edge(),_axis.upper_edge());
} else {
const std::vector<TC>& _edges = _axis.edges();
std::vector<TC> new_edges(new_n+1);
for(bn_t ibin=0;ibin<new_n;ibin++) {
new_edges[ibin] = _edges[ibin*a_factor];
}
new_edges[new_n] = _edges[n]; //upper edge.
new_h = new p1(parent::m_title,new_edges);
}
if(!new_h) return false;
new_h->m_cut_v = m_cut_v;
new_h->m_min_v = m_min_v;
new_h->m_max_v = m_max_v;
bn_t offset,new_offset,offac;
for(bn_t ibin=0;ibin<new_n;ibin++) {
new_offset = ibin+1;
offset = a_factor*ibin+1;
for(unsigned int ifac=0;ifac<a_factor;ifac++) {
offac = offset+ifac;
new_h->m_bin_entries[new_offset] += parent::m_bin_entries[offac];
new_h->m_bin_Sw[new_offset] += parent::m_bin_Sw[offac];
new_h->m_bin_Sw2[new_offset] += parent::m_bin_Sw2[offac];
new_h->m_bin_Sxw[new_offset][0] += parent::m_bin_Sxw[offac][0];
new_h->m_bin_Sx2w[new_offset][0] += parent::m_bin_Sx2w[offac][0];
new_h->m_bin_Svw[new_offset] += m_bin_Svw[offac];
new_h->m_bin_Sv2w[new_offset] += m_bin_Sv2w[offac];
}
}
//underflow :
new_offset = 0;
offac = 0;
new_h->m_bin_entries[new_offset] = parent::m_bin_entries[offac];
new_h->m_bin_Sw[new_offset] = parent::m_bin_Sw[offac];
new_h->m_bin_Sw2[new_offset] = parent::m_bin_Sw2[offac];
new_h->m_bin_Sxw[new_offset][0] = parent::m_bin_Sxw[offac][0];
new_h->m_bin_Sx2w[new_offset][0] = parent::m_bin_Sx2w[offac][0];
new_h->m_bin_Svw[new_offset] = m_bin_Svw[offac];
new_h->m_bin_Sv2w[new_offset] = m_bin_Sv2w[offac];
//overflow :
new_offset = new_n+1;
offac = n+1;
new_h->m_bin_entries[new_offset] = parent::m_bin_entries[offac];
new_h->m_bin_Sw[new_offset] = parent::m_bin_Sw[offac];
new_h->m_bin_Sw2[new_offset] = parent::m_bin_Sw2[offac];
new_h->m_bin_Sxw[new_offset][0] = parent::m_bin_Sxw[offac][0];
new_h->m_bin_Sx2w[new_offset][0] = parent::m_bin_Sx2w[offac][0];
new_h->m_bin_Svw[new_offset] = m_bin_Svw[offac];
new_h->m_bin_Sv2w[new_offset] = m_bin_Sv2w[offac];
*this = *new_h;
return true;
}
bool cut_v() const {return m_cut_v;}
TV min_v() const {return m_min_v;}
TV max_v() const {return m_max_v;}
public:
p1(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax)
: parent(a_title,aXnumber,aXmin,aXmax)
,m_cut_v(false)
,m_min_v(0)
,m_max_v(0)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
p1(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax,
TV aVmin,TV aVmax)
: parent(a_title,aXnumber,aXmin,aXmax)
,m_cut_v(true)
,m_min_v(aVmin)
,m_max_v(aVmax)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
p1(const std::string& a_title,
const std::vector<TC>& aEdges)
: parent(a_title,aEdges)
,m_cut_v(false)
,m_min_v(0)
,m_max_v(0)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
p1(const std::string& a_title,
const std::vector<TC>& aEdges,
TV aVmin,TV aVmax)
: parent(a_title,aEdges)
,m_cut_v(true)
,m_min_v(aVmin)
,m_max_v(aVmax)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
virtual ~p1(){}
public:
p1(const p1& a_from)
: parent(a_from)
,m_cut_v(a_from.m_cut_v)
,m_min_v(a_from.m_min_v)
,m_max_v(a_from.m_max_v)
,m_bin_Svw(a_from.m_bin_Svw)
,m_bin_Sv2w(a_from.m_bin_Sv2w)
{}
p1& operator=(const p1& a_from){
parent::operator=(a_from);
m_cut_v = a_from.m_cut_v;
m_min_v = a_from.m_min_v;
m_max_v = a_from.m_max_v;
m_bin_Svw = a_from.m_bin_Svw;
m_bin_Sv2w = a_from.m_bin_Sv2w;
return *this;
}
public:
const std::vector<TV>& bins_sum_vw() const {return m_bin_Svw;}
const std::vector<TV>& bins_sum_v2w() const {return m_bin_Sv2w;}
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;
};
}}
#endif
@@ -0,0 +1,63 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_p1d
#define tools_histo_p1d
#include "p1"
namespace tools {
namespace histo {
class p1d : public p1<double,unsigned int,double,double,double> {
typedef p1<double,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;
}
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,
double aVmin,double aVmax)
: parent(a_title,aXnumber,aXmin,aXmax,aVmin,aVmax)
{}
p1d(const std::string& a_title,
const std::vector<double>& aEdges)
: parent(a_title,aEdges)
{}
p1d(const std::string& a_title,
const std::vector<double>& aEdges,
double aVmin,double aVmax)
: parent(a_title,aEdges,aVmin,aVmax)
{}
virtual ~p1d(){}
public:
p1d(const p1d& a_from): parent(a_from){}
p1d& operator=(const p1d& a_from){
parent::operator=(a_from);
return *this;
}
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);}
};
}}
#endif
@@ -0,0 +1,294 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_p2
#define tools_histo_p2
#include "b2"
#include "profile_data"
namespace tools {
namespace histo {
template <class TC,class TN,class TW,class TH,class TV>
class p2 : public b2<TC,TN,TW,TH> {
typedef b2<TC,TN,TW,TH> parent;
public:
typedef typename base_histo<TC,TN,TW,TH>::bn_t bn_t;
protected:
virtual TH get_bin_height(int 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;
//FIXME Is it correct ?
// TProfile::GetBinError with kERRORMEAN mode does :
// Stat_t cont = fArray[bin]; //Svw (see TProfile::Fill)
// Stat_t sum = parent::m_bin_entries.fArray[bin]; //Sw
// Stat_t err2 = fSumw2.fArray[bin]; //Sv2w
// if (sum == 0) return 0;
// Stat_t eprim;
// Stat_t contsum = cont/sum;
// Stat_t eprim2 = TMath::Abs(err2/sum - contsum*contsum);
// eprim = TMath::Sqrt(eprim2);
// ... ???
// if (fErrorMode == kERRORMEAN) return eprim/TMath::Sqrt(sum);
TW sw = parent::m_bin_Sw[offset]; //ROOT sum
if(sw==0) return 0;
TV svw = m_bin_Svw[offset]; //ROOT cont
TV sv2w = m_bin_Sv2w[offset]; //ROOT err2
TV mean = (svw / sw); //ROOT contsum
TV rms = ::sqrt(::fabs((sv2w/sw) - mean * mean)); //ROOT eprim
// rms = get_bin_rms_value.
return rms/::sqrt(sw); //ROOT kERRORMEAN mode returned value
}
public:
bool multiply(TW aFactor){
if(!parent::base_multiply(aFactor)) return false;
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] *= aFactor;
}
parent::update_fast_getters();
return true;
}
bool scale(TW aFactor) {return multiply(aFactor);}
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;
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;
return m_bin_Sv2w[offset];
}
bool reset() {
parent::base_reset();
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] = 0;
m_bin_Sv2w[ibin] = 0;
}
parent::update_fast_getters();
return true;
}
void copy_from_data(const profile_data<TC,TN,TW,TV>& a_from) {
parent::base_from_data(a_from);
m_bin_Svw = a_from.m_bin_Svw;
m_bin_Sv2w = a_from.m_bin_Sv2w;
m_cut_v = a_from.m_cut_v;
m_min_v = a_from.m_min_v;
m_max_v = a_from.m_max_v;
}
profile_data<TC,TN,TW,TV> get_histo_data() const {
profile_data<TC,TN,TW,TV> hd(parent::base_get_data());
hd.m_is_profile = true;
hd.m_bin_Svw = m_bin_Svw;
hd.m_bin_Sv2w = m_bin_Sv2w;
hd.m_cut_v = m_cut_v;
hd.m_min_v = m_min_v;
hd.m_max_v = m_max_v;
return hd;
}
bool fill(TC aX,TC aY,TV aV,TW aWeight = 1) {
//m_coords[0] = aX;
//m_coords[1] = aY;
//return fill_bin(m_coords,aV,aWeight);
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;
bn_t offset = ibin + jbin * parent::m_axes[1].m_offset;
parent::m_bin_entries[offset]++;
parent::m_bin_Sw[offset] += aWeight;
parent::m_bin_Sw2[offset] += aWeight * aWeight;
TC xw = aX * aWeight;
TC x2w = aX * xw;
parent::m_bin_Sxw[offset][0] += xw;
parent::m_bin_Sx2w[offset][0] += x2w;
TC yw = aY * aWeight;
TC y2w = aY * yw;
parent::m_bin_Sxw[offset][1] += yw;
parent::m_bin_Sx2w[offset][1] += y2w;
bool inRange = true;
if(ibin==0) inRange = false;
else if(ibin==(parent::m_axes[0].m_number_of_bins+1)) inRange = false;
if(jbin==0) inRange = false;
else if(jbin==(parent::m_axes[1].m_number_of_bins+1)) inRange = false;
if(inRange) {
parent::m_in_range_entries++;
parent::m_in_range_Sw += 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;
}
// Profile part :
TV vw = aV * aWeight;
m_bin_Svw[offset] += vw;
m_bin_Sv2w[offset] += aV * vw;
return true;
}
TV bin_rms_value(int aI,int aJ) const {
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;
TW sw = parent::m_bin_Sw[offset];
if(sw==0) return 0;
TV svw = m_bin_Svw[offset];
TV sv2w = m_bin_Sv2w[offset];
TV mean = (svw / sw);
return ::sqrt(::fabs((sv2w / sw) - mean * mean));
}
bool add(const p2& a_histo){
parent::base_add(a_histo);
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] += a_histo.m_bin_Svw[ibin];
m_bin_Sv2w[ibin] += a_histo.m_bin_Sv2w[ibin];
}
parent::update_fast_getters();
return true;
}
bool subtract(const p2& a_histo){
parent::base_subtract(a_histo);
for(bn_t ibin=0;ibin<parent::m_bin_number;ibin++) {
m_bin_Svw[ibin] -= a_histo.m_bin_Svw[ibin];
m_bin_Sv2w[ibin] -= a_histo.m_bin_Sv2w[ibin];
}
parent::update_fast_getters();
return true;
}
bool cut_v() const {return m_cut_v;}
TV min_v() const {return m_min_v;}
TV max_v() const {return m_max_v;}
public:
p2(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax,
bn_t aYnumber,TC aYmin,TC aYmax)
: parent(a_title,aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax)
,m_cut_v(false)
,m_min_v(0)
,m_max_v(0)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
p2(const std::string& a_title,
bn_t aXnumber,TC aXmin,TC aXmax,
bn_t aYnumber,TC aYmin,TC aYmax,
TV aVmin,TV aVmax)
: parent(a_title,aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax)
,m_cut_v(true)
,m_min_v(aVmin)
,m_max_v(aVmax)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
p2(const std::string& a_title,
const std::vector<TC>& aEdgesX,
const std::vector<TC>& aEdgesY)
: parent(a_title,aEdgesX,aEdgesY)
,m_cut_v(false)
,m_min_v(0)
,m_max_v(0)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
p2(const std::string& a_title,
const std::vector<TC>& 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)
{
m_bin_Svw.resize(parent::m_bin_number,0);
m_bin_Sv2w.resize(parent::m_bin_number,0);
}
virtual ~p2(){}
public:
p2(const p2& a_from)
: parent(a_from)
,m_cut_v(a_from.m_cut_v)
,m_min_v(a_from.m_min_v)
,m_max_v(a_from.m_max_v)
,m_bin_Svw(a_from.m_bin_Svw)
,m_bin_Sv2w(a_from.m_bin_Sv2w)
{}
p2& operator=(const p2& a_from){
parent::operator=(a_from);
m_cut_v = a_from.m_cut_v;
m_min_v = a_from.m_min_v;
m_max_v = a_from.m_max_v;
m_bin_Svw = a_from.m_bin_Svw;
m_bin_Sv2w = a_from.m_bin_Sv2w;
return *this;
}
public:
const std::vector<TV>& bins_sum_vw() const {return m_bin_Svw;}
const std::vector<TV>& bins_sum_v2w() const {return m_bin_Sv2w;}
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;
};
}}
#endif
@@ -0,0 +1,64 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_p2d
#define tools_histo_p2d
#include "p2"
namespace tools {
namespace histo {
class p2d : public p2<double,unsigned int,double,double,double> {
typedef p2<double,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;
}
public:
p2d(const std::string& a_title,
unsigned int aXnumber,double aXmin,double aXmax,
unsigned int aYnumber,double aYmin,double aYmax)
: parent(a_title,aXnumber,aXmin,aXmax,
aYnumber,aYmin,aYmax)
{}
p2d(const std::string& a_title,
unsigned int aXnumber,double aXmin,double aXmax,
unsigned int aYnumber,double aYmin,double aYmax,
double aVmin,double aVmax)
: parent(a_title,aXnumber,aXmin,aXmax,aYnumber,aYmin,aYmax,aVmin,aVmax)
{}
p2d(const std::string& a_title,
const std::vector<double>& aEdgesX,
const std::vector<double>& aEdgesY)
: parent(a_title,aEdgesX,aEdgesY)
{}
p2d(const std::string& a_title,
const std::vector<double>& aEdgesX,
const std::vector<double>& aEdgesY,
double aVmin,double aVmax)
: parent(a_title,aEdgesX,aEdgesY,aVmin,aVmax)
{}
virtual ~p2d(){}
public:
p2d(const p2d& a_from): parent(a_from){}
p2d& operator=(const p2d& a_from){
parent::operator=(a_from);
return *this;
}
private: static void check_instantiation() {p2d dummy("",10,0,1,10,0,1);}
};
}}
#endif
@@ -0,0 +1,79 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_profile_data
#define tools_histo_profile_data
#include "histo_data"
namespace tools {
namespace histo {
template <class TC,class TN,class TW,class TV>
class profile_data : public histo_data<TC,TN,TW> {
public:
profile_data()
: histo_data<TC,TN,TW>()
,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)
,m_is_profile(false)
,m_cut_v(false)
,m_min_v(0)
,m_max_v(0)
{}
public:
profile_data(const profile_data& a_from)
: histo_data<TC,TN,TW>(a_from)
,m_is_profile(a_from.m_is_profile)
,m_bin_Svw(a_from.m_bin_Svw)
,m_bin_Sv2w(a_from.m_bin_Sv2w)
,m_cut_v(a_from.m_cut_v)
,m_min_v(a_from.m_min_v)
,m_max_v(a_from.m_max_v)
{}
profile_data& operator=(const profile_data& a_from) {
histo_data<TC,TN,TW>::operator=(a_from);
m_is_profile = a_from.m_is_profile;
m_bin_Svw = a_from.m_bin_Svw;
m_bin_Sv2w = a_from.m_bin_Sv2w;
m_cut_v = a_from.m_cut_v;
m_min_v = a_from.m_min_v;
m_max_v = a_from.m_max_v;
return *this;
}
virtual ~profile_data(){}
public:
profile_data& operator=(const histo_data<TC,TN,TW>& a_from) {
//for Rio_THisogram.
histo_data<TC,TN,TW>::operator=(a_from);
m_is_profile = false;
m_bin_Svw.clear();
m_bin_Sv2w.clear();
m_cut_v = false;
m_min_v = 0;
m_max_v = 0;
return *this;
}
public:
bool m_is_profile; //for Rio_THistogram.
std::vector<TV> m_bin_Svw;
std::vector<TV> m_bin_Sv2w;
bool m_cut_v;
TV m_min_v;
TV m_max_v;
};
}}
#endif
@@ -0,0 +1,379 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_slice
#define tools_histo_slice
#include "h1"
#include "h2"
#include "h3"
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,
int aJbeg,int aJend,
h1<TC,TN,TW,TH>& a_to) {
if(!a_from.dimension()) return false;
typedef typename axis<TC>::bn_t bn_t;
bn_t jbeg;
if(!a_from.axis_y().in_range_to_absolute_index(aJbeg,jbeg)) return false;
bn_t jend;
if(!a_from.axis_y().in_range_to_absolute_index(aJend,jend)) return false;
if(jbeg>jend) return false;
if(a_from.axis_x().bins()!=a_to.axis().bins()) return false;
histo_data<TC,TN,TW> hdata = a_to.get_histo_data();
bn_t aoffset,offset,jbin;
bn_t yoffset = a_from.axis_y().m_offset;
const std::vector<TN>& af_bin_entries = a_from.bins_entries();
const std::vector<TW>& af_bin_Sw = a_from.bins_sum_w();
const std::vector<TW>& af_bin_Sw2 = a_from.bins_sum_w2();
const std::vector< std::vector<TC> >& af_bin_Sxw = a_from.bins_sum_xw();
const std::vector< std::vector<TC> >& af_bin_Sx2w = a_from.bins_sum_x2w();
// Fill also the outflow.
bn_t abins = hdata.m_axes[0].bins()+2;
for(bn_t aibin=0;aibin<abins;aibin++) {
//offset1D = ibin
aoffset = aibin;
for(jbin=jbeg;jbin<=jend;jbin++) {
//offset2D = ibin + jbin * yoffset
// hdata booked with x then :
offset = aibin + jbin * yoffset;
// Bin :
hdata.m_bin_entries[aoffset] += af_bin_entries[offset];
hdata.m_bin_Sw[aoffset] += af_bin_Sw[offset];
hdata.m_bin_Sw2[aoffset] += af_bin_Sw2[offset];
hdata.m_bin_Sxw[aoffset][0] += af_bin_Sxw[offset][0];
hdata.m_bin_Sx2w[aoffset][0] += af_bin_Sx2w[offset][0];
}
}
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,
int aJbeg,int aJend,
const std::string& a_title) {
h1<TC,TN,TW,TH>* slice = new h1<TC,TN,TW,TH>(a_title,
a_from.axis_x().bins(),
a_from.axis_x().lower_edge(),
a_from.axis_x().upper_edge());
if(!fill_slice_x(a_from,aJbeg,aJend,*slice)) {delete slice;return 0;}
return slice;
}
template <class 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 TN,class TW,class TH>
inline bool fill_slice_y(const h2<TC,TN,TW,TH>& a_from,
int aIbeg,int aIend,
h1<TC,TN,TW,TH>& a_to) {
if(!a_from.dimension()) return false;
typedef typename axis<TC>::bn_t bn_t;
bn_t ibeg;
if(!a_from.axis_x().in_range_to_absolute_index(aIbeg,ibeg)) return false;
bn_t iend;
if(!a_from.axis_x().in_range_to_absolute_index(aIend,iend)) return false;
if(ibeg>iend) return false;
if(a_from.axis_y().bins()!=a_to.axis().bins()) return false;
histo_data<TC,TN,TW> hdata = a_to.get_histo_data();
bn_t aibin,aoffset,offset,ibin;
bn_t yoffset = a_from.axis_y().m_offset;
const std::vector<TN>& af_bin_entries = a_from.bins_entries();
const std::vector<TW>& af_bin_Sw = a_from.bins_sum_w();
const std::vector<TW>& af_bin_Sw2 = a_from.bins_sum_w2();
const std::vector< std::vector<TC> >& af_bin_Sxw = a_from.bins_sum_xw();
const std::vector< std::vector<TC> >& af_bin_Sx2w = a_from.bins_sum_x2w();
// Fill also the outflow.
bn_t abins = hdata.m_axes[0].bins()+2;
for(aibin=0;aibin<abins;aibin++) {
//offset1D = ibin
aoffset = aibin;
for(ibin=ibeg;ibin<=iend;ibin++) {
//offset2D = ibin + jbin * yoffset
// hdata booked with y then :
offset = ibin + aibin * yoffset;
// Bin :
hdata.m_bin_entries[aoffset] += af_bin_entries[offset];
hdata.m_bin_Sw[aoffset] += af_bin_Sw[offset];
hdata.m_bin_Sw2[aoffset] += af_bin_Sw2[offset];
hdata.m_bin_Sxw[aoffset][0] += af_bin_Sxw[offset][1];
hdata.m_bin_Sx2w[aoffset][0] += af_bin_Sx2w[offset][1];
}
}
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,
int aIbeg,int aIend,
const std::string& a_title) {
h1<TC,TN,TW,TH>* slice = new h1<TC,TN,TW,TH>(a_title,
a_from.axis_y().bins(),
a_from.axis_y().lower_edge(),
a_from.axis_y().upper_edge());
if(!fill_slice_y(a_from,aIbeg,aIend,*slice)) {delete slice;return 0;}
return slice;
}
template <class 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 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) {
if(!a_from.dimension()) return false;
typedef typename axis<TC>::bn_t bn_t;
bn_t ibeg;
if(!a_from.axis_x().in_range_to_absolute_index(aIbeg,ibeg)) return false;
bn_t iend;
if(!a_from.axis_x().in_range_to_absolute_index(aIend,iend)) return false;
if(ibeg>iend) return false;
if(a_from.axis_y().bins()!=a_to.axis_x().bins()) return false;
if(a_from.axis_z().bins()!=a_to.axis_y().bins()) return false;
histo_data<TC,TN,TW> hdata = a_to.get_histo_data();
bn_t aibin,ajbin,aoffset,offset,ibin;
bn_t ayoffset = hdata.m_axes[1].m_offset;
bn_t yoffset = a_from.axis_y().m_offset;
bn_t zoffset = a_from.axis_z().m_offset;
bn_t axbins = hdata.m_axes[0].bins()+2;
bn_t aybins = hdata.m_axes[1].bins()+2;
const std::vector<TN>& af_bin_entries = a_from.bins_entries();
const std::vector<TW>& af_bin_Sw = a_from.bins_sum_w();
const std::vector<TW>& af_bin_Sw2 = a_from.bins_sum_w2();
const std::vector< std::vector<TC> >& af_bin_Sxw = a_from.bins_sum_xw();
const std::vector< std::vector<TC> >& af_bin_Sx2w = a_from.bins_sum_x2w();
// Fill also the outflow.
for(aibin=0;aibin<axbins;aibin++) {
for(ajbin=0;ajbin<aybins;ajbin++) {
//offset2D = ibin + jbin * m_axes[1].m_offset
aoffset = aibin + ajbin * ayoffset;
for(ibin=ibeg;ibin<=iend;ibin++) {
//offset3D = ibin + jbin * m_axes[1].m_offset + kbin*m_axes[2].m_offset;
// hdata booked with y-z then :
offset = ibin + aibin * yoffset + ajbin * zoffset;
// Bin :
hdata.m_bin_entries[aoffset] += af_bin_entries[offset];
hdata.m_bin_Sw[aoffset] += af_bin_Sw[offset];
hdata.m_bin_Sw2[aoffset] += af_bin_Sw2[offset];
hdata.m_bin_Sxw[aoffset][0] += af_bin_Sxw[offset][1];
hdata.m_bin_Sxw[aoffset][1] += af_bin_Sxw[offset][2];
hdata.m_bin_Sx2w[aoffset][0] += af_bin_Sx2w[offset][1];
hdata.m_bin_Sx2w[aoffset][1] += af_bin_Sx2w[offset][2];
}
}
}
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) {
if(!a_from.dimension()) return false;
typedef typename axis<TC>::bn_t bn_t;
bn_t kbeg;
if(!a_from.axis_z().in_range_to_absolute_index(aKbeg,kbeg)) return false;
bn_t kend;
if(!a_from.axis_z().in_range_to_absolute_index(aKend,kend)) return false;
if(kbeg>kend) return false;
if(a_from.axis_x().bins()!=a_to.axis_x().bins()) return false;
if(a_from.axis_y().bins()!=a_to.axis_y().bins()) return false;
histo_data<TC,TN,TW> hdata = a_to.get_histo_data();
bn_t kbin;
bn_t aibin,ajbin,aoffset,offset;
bn_t ayoffset = hdata.m_axes[1].m_offset;
bn_t yoffset = a_from.axis_y().m_offset;
bn_t zoffset = a_from.axis_z().m_offset;
bn_t axbins = hdata.m_axes[0].bins()+2;
bn_t aybins = hdata.m_axes[1].bins()+2;
const std::vector<TN>& af_bin_entries = a_from.bins_entries();
const std::vector<TW>& af_bin_Sw = a_from.bins_sum_w();
const std::vector<TW>& af_bin_Sw2 = a_from.bins_sum_w2();
const std::vector< std::vector<TC> >& af_bin_Sxw = a_from.bins_sum_xw();
const std::vector< std::vector<TC> >& af_bin_Sx2w = a_from.bins_sum_x2w();
// Fill also the outflow.
for(aibin=0;aibin<axbins;aibin++) {
for(ajbin=0;ajbin<aybins;ajbin++) {
//offset2D = ibin + jbin * m_axes[1].m_offset
aoffset = aibin + ajbin * ayoffset;
for(kbin=kbeg;kbin<=kend;kbin++) {
//offset3D = ibin + jbin * m_axes[1].m_offset + kbin*m_axes[2].m_offset;
// hdata booked with x-y then :
offset = aibin + ajbin * yoffset + kbin * zoffset;
// Bin :
hdata.m_bin_entries[aoffset] += af_bin_entries[offset];
hdata.m_bin_Sw[aoffset] += af_bin_Sw[offset];
hdata.m_bin_Sw2[aoffset] += af_bin_Sw2[offset];
hdata.m_bin_Sxw[aoffset][0] += af_bin_Sxw[offset][0];
hdata.m_bin_Sxw[aoffset][1] += af_bin_Sxw[offset][1];
hdata.m_bin_Sx2w[aoffset][0] += af_bin_Sx2w[offset][0];
hdata.m_bin_Sx2w[aoffset][1] += af_bin_Sx2w[offset][1];
}
}
}
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) {
if(!a_from.dimension()) return false;
typedef typename axis<TC>::bn_t bn_t;
bn_t jbeg;
if(!a_from.axis_y().in_range_to_absolute_index(aJbeg,jbeg)) return false;
bn_t jend;
if(!a_from.axis_y().in_range_to_absolute_index(aJend,jend)) return false;
if(jbeg>jend) return false;
if(a_from.axis_x().bins()!=a_to.axis_x().bins()) return false;
if(a_from.axis_z().bins()!=a_to.axis_y().bins()) return false;
histo_data<TC,TN,TW> hdata = a_to.get_histo_data();
bn_t aibin,ajbin,aoffset,offset,jbin;
bn_t ayoffset = hdata.m_axes[1].m_offset;
bn_t yoffset = a_from.axis_y().m_offset;
bn_t zoffset = a_from.axis_z().m_offset;
bn_t axbins = hdata.m_axes[0].bins()+2;
bn_t aybins = hdata.m_axes[1].bins()+2;
const std::vector<TN>& af_bin_entries = a_from.bins_entries();
const std::vector<TW>& af_bin_Sw = a_from.bins_sum_w();
const std::vector<TW>& af_bin_Sw2 = a_from.bins_sum_w2();
const std::vector< std::vector<TC> >& af_bin_Sxw = a_from.bins_sum_xw();
const std::vector< std::vector<TC> >& af_bin_Sx2w = a_from.bins_sum_x2w();
// Fill also the outflow.
for(aibin=0;aibin<axbins;aibin++) {
for(ajbin=0;ajbin<aybins;ajbin++) {
//offset2D = ibin + jbin * m_axes[1].m_offset
aoffset = aibin + ajbin * ayoffset;
for(jbin=jbeg;jbin<=jend;jbin++) {
//offset3D = ibin + jbin * m_axes[1].m_offset + kbin*m_axes[2].m_offset;
// hdata booked with x-z then :
offset = aibin + jbin * yoffset + ajbin * zoffset;
// Bin :
hdata.m_bin_entries[aoffset] += af_bin_entries[offset];
hdata.m_bin_Sw[aoffset] += af_bin_Sw[offset];
hdata.m_bin_Sw2[aoffset] += af_bin_Sw2[offset];
hdata.m_bin_Sxw[aoffset][0] += af_bin_Sxw[offset][0];
hdata.m_bin_Sxw[aoffset][1] += af_bin_Sxw[offset][2];
hdata.m_bin_Sx2w[aoffset][0] += af_bin_Sx2w[offset][0];
hdata.m_bin_Sx2w[aoffset][1] += af_bin_Sx2w[offset][2];
}
}
}
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,
int aKbeg,int aKend,
const std::string& a_title) {
h2<TC,TN,TW,TH>* slice = new h2<TC,TN,TW,TH>(a_title,
a_from.axis_x().bins(),
a_from.axis_x().lower_edge(),
a_from.axis_x().upper_edge(),
a_from.axis_y().bins(),
a_from.axis_y().lower_edge(),
a_from.axis_y().upper_edge());
if(!fill_slice_xy(a_from,aKbeg,aKend,*slice)) {delete slice;return 0;}
return slice;
}
template <class TC,class TN,class TW,class TH>
inline h2<TC,TN,TW,TH>* slice_yz(const h3<TC,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,
a_from.axis_y().bins(),
a_from.axis_y().lower_edge(),
a_from.axis_y().upper_edge(),
a_from.axis_z().bins(),
a_from.axis_z().lower_edge(),
a_from.axis_z().upper_edge());
if(!fill_slice_yz(a_from,aIbeg,aIend,*slice)) {delete slice;return 0;}
return slice;
}
template <class TC,class TN,class TW,class TH>
inline h2<TC,TN,TW,TH>* slice_xz(const h3<TC,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,
a_from.axis_x().bins(),
a_from.axis_x().lower_edge(),
a_from.axis_x().upper_edge(),
a_from.axis_z().bins(),
a_from.axis_z().lower_edge(),
a_from.axis_z().upper_edge());
if(!fill_slice_xz(a_from,aJbeg,aJend,*slice)) {delete slice;return 0;}
return slice;
}
}}
#endif
@@ -0,0 +1,101 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_histo_sliced
#define tools_histo_sliced
#include "slice"
#include "h1d"
#include "h2d"
#include "h3d"
namespace tools {
namespace histo {
inline h1d* slice_x(const h2d& a_from,
int aJbeg,int aJend,
const std::string& a_title) {
h1d* slice_x = new h1d(a_title,
a_from.axis_x().bins(),
a_from.axis_x().lower_edge(),
a_from.axis_x().upper_edge());
if(!fill_slice_x(a_from,aJbeg,aJend,*slice_x)) {delete slice_x;return 0;}
return slice_x;
}
inline h1d* projection_x(const h2d& a_from,const std::string& a_title) {
return slice_x(a_from,axis<double>::UNDERFLOW_BIN,axis<double>::OVERFLOW_BIN,a_title);
}
inline h1d* slice_y(const h2d& a_from,
int aIbeg,int aIend,
const std::string& a_title) {
h1d* slice_y = new h1d(a_title,
a_from.axis_y().bins(),
a_from.axis_y().lower_edge(),
a_from.axis_y().upper_edge());
if(!fill_slice_y(a_from,aIbeg,aIend,*slice_y)) {delete slice_y;return 0;}
return slice_y;
}
inline h1d* projection_y(const h2d& a_from,const std::string& a_title) {
return slice_y(a_from,axis<double>::UNDERFLOW_BIN,axis<double>::OVERFLOW_BIN,a_title);
}
inline h2d* slice_xy(const h3d& a_from,
int aKbeg,int aKend,
const std::string& a_title) {
h2d* slice = new h2d(a_title,
a_from.axis_x().bins(),
a_from.axis_x().lower_edge(),
a_from.axis_x().upper_edge(),
a_from.axis_y().bins(),
a_from.axis_y().lower_edge(),
a_from.axis_y().upper_edge());
if(!fill_slice_xy(a_from,aKbeg,aKend,*slice)) {delete slice;return 0;}
return slice;
}
inline h2d* projection_xy(const h3d& a_from,const std::string& a_title) {
return slice_xy(a_from,axis<double>::UNDERFLOW_BIN,axis<double>::OVERFLOW_BIN,a_title);
}
inline h2d* slice_yz(const h3d& a_from,
int aIbeg,int aIend,
const std::string& a_title) {
h2d* slice = new h2d(a_title,
a_from.axis_y().bins(),
a_from.axis_y().lower_edge(),
a_from.axis_y().upper_edge(),
a_from.axis_z().bins(),
a_from.axis_z().lower_edge(),
a_from.axis_z().upper_edge());
if(!fill_slice_yz(a_from,aIbeg,aIend,*slice)) {delete slice;return 0;}
return slice;
}
inline h2d* projection_yz(const h3d& a_from,const std::string& a_title) {
return slice_yz(a_from,axis<double>::UNDERFLOW_BIN,axis<double>::OVERFLOW_BIN,a_title);
}
inline h2d* slice_xz(const h3d& a_from,
int aJbeg,int aJend,
const std::string& a_title) {
h2d* slice = new h2d(a_title,
a_from.axis_x().bins(),
a_from.axis_x().lower_edge(),
a_from.axis_x().upper_edge(),
a_from.axis_z().bins(),
a_from.axis_z().lower_edge(),
a_from.axis_z().upper_edge());
if(!fill_slice_xz(a_from,aJbeg,aJend,*slice)) {delete slice;return 0;}
return slice;
}
inline h2d* projection_xz(const h3d& a_from,const std::string& a_title) {
return slice_xz(a_from,axis<double>::UNDERFLOW_BIN,axis<double>::OVERFLOW_BIN,a_title);
}
}}
#endif
@@ -0,0 +1,71 @@
// 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
@@ -0,0 +1,48 @@
// 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
@@ -0,0 +1,45 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_math
#define tools_math
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;}
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);}
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;
}
}
#endif
+139
View File
@@ -0,0 +1,139 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_mem
#define tools_mem
#ifdef TOOLS_MEM
// to count instances.
// WARNING : it uses writable static data, then it is NOT thread safe.
// This class must be used for debugging only.
#include <ostream>
#include <list>
#include <string>
#include <cstring> //strcmp
namespace tools {
class mem {
protected:
mem(){increment();}
virtual ~mem(){decrement();}
mem(const mem&){}
mem& operator=(const mem&){return *this;}
public:
static void increment(){counter()++;}
static void decrement(){counter()--;}
static void increment(const char* a_class){
counter()++;
if(check_by_class()) {
mem_list::iterator it;
for(it=list().begin();it!=list().end();++it) {
if(!::strcmp((*it).first.c_str(),a_class)) {
(*it).second++;
return;
}
}
list().push_back(std::pair<std::string,int>(std::string(a_class),1));
}
}
static void decrement(const char* a_class){
counter()--;
if(check_by_class()) {
mem_list::iterator it;
for(it=list().begin();it!=list().end();++it) {
if(!::strcmp((*it).first.c_str(),a_class)) {
(*it).second--;
return;
}
}
list().push_back(std::pair<std::string,int>(std::string(a_class),-1));
}
}
static void set_check_by_class(bool a_value) {
check_by_class() = a_value;
}
/*
static void reset();
*/
static void balance(std::ostream& a_out){
if(counter()) {
a_out << "tools::mem::balance :"
<< " bad global object balance : " << counter()
<< std::endl;
if(check_by_class()) {
a_out << "tools::mem::balance :"
<< " check by class was enabled."
<< std::endl;
} else {
a_out << "tools::mem::balance :"
<< " check by class was disabled."
<< std::endl;
}
}
mem_list::iterator it;
for(it=list().begin();it!=list().end();++it) {
if((*it).second) {
a_out << "tools::mem::balance :"
<< " for class " << (*it).first
<< ", bad object balance : " << (*it).second
<< std::endl;
}
}
list().clear();
}
static int& counter() {
static int s_count = 0;
return s_count;
}
protected:
static bool& check_by_class() {
static bool s_check_by_class = false;
return s_check_by_class;
}
typedef std::list< std::pair<std::string,int> > mem_list;
static mem_list& list() {
static mem_list s_list;
return s_list;
}
};
inline const std::string& s_new() {
static const std::string s_v("new");
return s_v;
}
inline const std::string& s_malloc() {
static const std::string s_v("malloc");
return s_v;
}
inline const std::string& s_tex() {
static const std::string s_v("tex");
return s_v;
}
inline const std::string& s_gsto() {
static const std::string s_v("gsto");
return s_v;
}
}
#endif
#endif
@@ -0,0 +1,21 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_mnmx
#define tools_mnmx
namespace tools {
template <class T>
inline T mn(const T& a,const T& b) {
return (a<b?a:b);
}
template <class T>
inline T mx(const T& a,const T& b) {
return (a>b?a:b);
}
}
#endif
@@ -0,0 +1,44 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_ntuple_booking
#define tools_ntuple_booking
// a little class to capture booking parameters
// to create an ntuple.
#include "cids"
namespace tools {
class ntuple_booking {
public:
ntuple_booking(){}
virtual ~ntuple_booking(){}
public:
ntuple_booking(const ntuple_booking& a_from)
:m_name(a_from.m_name)
,m_title(a_from.m_title)
,m_columns(a_from.m_columns)
{}
ntuple_booking& operator=(const ntuple_booking& a_from){
m_name = a_from.m_name;
m_title = a_from.m_title;
m_columns = a_from.m_columns;
return *this;
}
public:
template <class T>
void add_column(const std::string& a_name) {
m_columns.push_back(col_t(a_name,_cid(T())));
}
public:
std::string m_name;
std::string m_title;
typedef std::pair<std::string,cid> col_t;
std::vector<col_t> m_columns;
};
}
#endif
@@ -0,0 +1,657 @@
// 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
+202
View File
@@ -0,0 +1,202 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_path
#define tools_path
#include <string>
namespace tools {
inline std::string suffix(const std::string& a_string,bool a_back = true) {
// If a_string = dir0/dir1/dir2/dir3/name.xxx
// return xxx
std::string::size_type pos = a_back?a_string.rfind('.'):a_string.find('.');
if(pos==std::string::npos) return "";
pos++;
return a_string.substr(pos,a_string.size()-pos);
}
inline std::string nosuffix(const std::string& a_string,bool a_back = true){
// If a_string = dir0/dir1/dir2/dir3/name.xxx
// return name
// Start searching after the last / (or last \ for Windows).
std::string::size_type pos = a_string.rfind('/');
if(pos==std::string::npos) pos = a_string.rfind('\\');
if(pos==std::string::npos) pos = 0;
else pos++;
std::string s = a_string.substr(pos,a_string.size()-pos);
std::string::size_type dot_pos = a_back?s.rfind('.'):s.find('.');
if(dot_pos==std::string::npos) return s;
return s.substr(0,dot_pos);
}
inline std::string base_name(const std::string& a_path) {
std::string::size_type pos_slash = a_path.rfind('/');
std::string::size_type pos_bslash = a_path.rfind('\\');
std::string::size_type pos = 0;
if(pos_slash==std::string::npos) {
if(pos_bslash==std::string::npos) {
pos = std::string::npos;
} else {
pos = pos_bslash;
}
} else {
if(pos_bslash==std::string::npos) {
pos = pos_slash;
} else {
if(pos_slash<=pos_bslash) {
pos = pos_bslash;
} else {
pos = pos_slash;
}
}
}
if(pos==std::string::npos) return a_path;
pos++;
return a_path.substr(pos,a_path.size()-pos);
}
inline bool is_absolute_path(const std::string& a_path) {
if(a_path.find('\\')!=std::string::npos) { //Windows path.
if(a_path.find(':')!=std::string::npos) return true;
return (a_path.size()&&(a_path[0]=='\\')?true:false);
} else { //UNIX path
return (a_path.size()&&(a_path[0]=='/')?true:false);
}
}
inline bool path_name_suffix(
const std::string& a_string
,std::string& a_path
,std::string& a_name
,std::string& a_suffix
){
// If a_string = dir0/dir1/dir2/dir3/name.xxx
// a_path = dir0/dir1/dir2/dir3
// a_name = name.xxx
// a_suffix = xxx
// If a_string = dir0/name.xxx
// a_path = dir0
// a_name = name.xxx
// a_suffix = xxx
// If a_string = name.xxx
// a_path.clear()
// a_name = name.xxx
// a_suffix = xxx
// If a_string = /name.xxx
// a_path = "/"
// a_name = name.xxx
// a_suffix = xxx
// If a_string = .
// a_path = "."
// a_name.clear()
// a_suffix.clear()
// If a_string = ..
// a_path = ".."
// a_name.clear()
// a_suffix.clear()
if(a_string==".") {
a_path = ".";
a_name.clear();
a_suffix.clear();
return true;
} else if(a_string=="..") {
a_path = "..";
a_name.clear();
a_suffix.clear();
return true;
}
std::string::size_type pos_slash = a_string.rfind('/');
std::string::size_type pos_bslash = a_string.rfind('\\');
std::string::size_type pos = 0;
if(pos_slash==std::string::npos) {
if(pos_bslash==std::string::npos) {
pos = std::string::npos;
} else {
pos = pos_bslash;
}
} else {
if(pos_bslash==std::string::npos) {
pos = pos_slash;
} else {
if(pos_slash<=pos_bslash) {
pos = pos_bslash;
} else {
pos = pos_slash;
}
}
}
if(pos==std::string::npos) {
a_path.clear();
pos = 0;
} else if(pos==0) {
a_path = "/";
pos++;
} else {
a_path = a_string.substr(0,pos);
pos++;
}
std::string s = a_string.substr(pos,a_string.size()-pos);
pos = s.rfind('.');
if(pos==std::string::npos) {
a_name = s;
a_suffix.clear();
} else {
a_name = s;
pos++;
a_suffix = s.substr(pos,s.size()-pos);
}
return true;
}
inline std::string dir_name(const std::string& a_path,unsigned int a_num = 1){
std::string path = a_path;
for(unsigned int index=0;index<a_num;index++) {
std::string p,n,s;
path_name_suffix(path,p,n,s);
path = p;
}
return path;
}
//used in OpenPAW, BatchLab.
inline bool is_f77(const std::string& a_path){
std::string sfx = suffix(a_path);
//tolowercase(sfx);
for(std::string::iterator it=sfx.begin();it!=sfx.end();++it) {
char c = *it;
*it = ((c) >= 'A' && (c) <= 'Z' ? c - 'A' + 'a' : c);
}
if(sfx=="f") return true; //the standard.
if(sfx=="for") return true; //for opaw. Known by g77.
if(sfx=="ftn") return true; //for opaw.
if(sfx=="fortran") return true; //for opaw.
if(sfx=="f77") return true;
return false;
}
//used in OpenPAW, BatchLab.
inline bool is_cpp(const std::string& a_path){
std::string sfx = suffix(a_path);
//tolowercase(sfx);
for(std::string::iterator it=sfx.begin();it!=sfx.end();++it) {
char c = *it;
*it = ((c) >= 'A' && (c) <= 'Z' ? c - 'A' + 'a' : c);
}
if(sfx=="c") return true;
if(sfx=="cxx") return true;
if(sfx=="cpp") return true;
if(sfx=="C") return true;
return false;
}
}
#endif
@@ -0,0 +1,101 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_platform
#define tools_platform
// We do not byteswap on intel (LE) (common platform).
// We have then a better compression on these machines.
// NOTE : this is the contrary to what is done in ROOT (and Rio).
namespace tools {
inline bool is_little_endian() {
unsigned int i = 1;
unsigned char* b = (unsigned char*)&i;
// BE = Big Endian, LE = Little Endian.
// The Intels x86 are LE.
// Mac PPC b[3] is 1 (BE)
// Mac Intel b[0] is 1 (LE)
// Linux i386 b[0] is 1 (LE)
// Linux x86_64 b[0] is 1 (LE)
return (b[0]==1?true:false);
}
}
#if defined(__APPLE__)
#include <TargetConditionals.h>
#endif
namespace tools {
namespace device {
#if TARGET_OS_IPHONE
inline bool is_iOS() {return true;}
#else
inline bool is_iOS() {return false;}
#endif
#if ANDROID
inline bool is_Android() {return true;}
#else
inline bool is_Android() {return false;}
#endif
#if ANDROID || TARGET_OS_IPHONE
inline bool small_screen() {return true;}
inline bool no_cursor() {return true;}
inline bool stop_app_button() {return true;}
#else
inline bool small_screen() {return false;}
inline bool no_cursor() {return false;}
inline bool stop_app_button() {return false;}
#endif
#if TARGET_OS_IPHONE
inline bool slow_cpu() {return true;}
#else
inline bool slow_cpu() {return false;}
#endif
inline unsigned int tex_mem_limit() {
// glGet(GL_MAX_TEXTURE_SIZE) :
// MacBookPro : it returns 8192.
// SGS : it returns 2048.
// iPad1 : it returns 2048.
// iPod : it returns ?
// Nexus 10 : it returns ?
// 1024*1024 //*3 = 3 145 728
// 2048*2048 //*3 = 12 582 912
// 4096*4096 //*3 = 50 331 648
// 8192*8192 //*3 = 201 326 592
// 8192*4096 //*3 = 100 663 296
if(small_screen()) {
//iOS : Apple says that max 2D tex size is 1024*1024 with two units
// texture available. From doc on PowerVR MBX.
return 2048*2048*3;
} else {
//limit = 4096*4096*3; //=8192*2048 //permit to pass ATLAS big image.
//permit to pass fete_science_2010/power2/image_0.jpg
return 8192*4096*3;
}
}
}}
#endif
/* We prefer to handle endianity dynamically, but with cpp macro
it would looks like (from luaconf.h) :
#if defined(__i386__) || defined(__i386) || \
defined(__X86__) || defined (__x86_64)
#define TOOLS_IS_BE 0
#define TOOLS_IS_LE 1
#elif defined(__POWERPC__) || defined(__ppc__)
#define TOOLS_IS_BE 1
#define TOOLS_IS_LE 0
#endif
*/
@@ -0,0 +1,56 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_pointer
#define tools_pointer
//WARNING : touchy
//NOTE : on 32 or 64 bits machine, a pointer matches an unsigned long.
#include "typedefs"
#include "snpf"
#include <string>
namespace tools {
inline bool to_pointer(const std::string& a_string,void*& a_value){
unsigned long v = 0L;
if(::sscanf(a_string.c_str(),"0x%lx",&v)!=1) {
if(::sscanf(a_string.c_str(),"%lu",&v)!=1) {
a_value = 0;
return false;
}
}
a_value = (void*)v;
return true;
}
inline std::string p2s(const void* a_value){
char s[512];
snpf(s,sizeof(s),"%lu",(unsigned long)a_value);
return s;
}
inline std::string p2sx(const void* a_value){
char s[512];
snpf(s,sizeof(s),"0x%lx",(unsigned long)a_value);
return s;
}
inline std::string char_p2s(const char* a_value) {
char s[512];
snpf(s,sizeof(s),"%lu",(unsigned long)a_value);
return std::string(s);
}
inline std::string long2s(const long a_value) {
char s[512];
snpf(s,sizeof(s),"%ld",a_value);
return std::string(s);
}
}
#endif
@@ -0,0 +1,99 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_randf
#define tools_randf
#include <cstdlib> //::rand, RAND_MAX
#include "fmath"
namespace tools {
namespace randf {
class flat {
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 {
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;
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;
};
class bw {
public:
bw(float a_mean = 0,float a_gamma = 1)
:m_mean(a_mean),m_gamma(a_gamma){}
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:
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;
};
class exp {
public:
exp(float a_rate = 1):m_rate(a_rate){}
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;
}
protected:
flat m_flat;
float m_rate;
};
}}
#endif
@@ -0,0 +1,101 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_random
#define tools_random
#include <cstdlib> //::rand, RAND_MAX
#include <cmath> //::sqrt, ::log
#include "math"
namespace tools {
namespace random {
class flat {
public:
double shoot() const {
// Shoot random numbers in [0,1] according a flat distribution.
double value = (double)::rand();
value /= (double)RAND_MAX;
return value;
}
};
class gauss {
public:
gauss(double a_mean = 0,double 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;
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;
};
class bw {
public:
bw(double a_mean = 0,double a_gamma = 1)
:m_mean(a_mean),m_gamma(a_gamma){}
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;
};
class exp {
public:
exp(double a_rate = 1):m_rate(a_rate){}
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;
};
}}
#endif
@@ -0,0 +1,76 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rcmp
#define tools_rcmp
// used in safe cast.
#include <string>
#include <cstring>
namespace tools {
inline bool rcmp(const char* a_1,const char* a_2) {
size_t l1 = ::strlen(a_1);
size_t l2 = ::strlen(a_2);
if(l1!=l2) return false;
if(!l1) return true;
const char* p1 = a_1+l1-1;
const char* p2 = a_2+l2-1;
//ab
//012
for(size_t index=0;index<l1;index++,p1--,p2--) {
if(*p1!=*p2) return false;
}
return true;
}
inline bool rcmp(const std::string& a_1,const char* a_2) {
std::string::size_type l1 = a_1.size();
size_t l2 = ::strlen(a_2);
if(size_t(l1)!=l2) return false;
if(!l1) return true;
const char* p1 = a_1.c_str()+l1-1;
const char* p2 = a_2+l2-1;
//ab
//012
for(std::string::size_type index=0;index<l1;index++,p1--,p2--) {
if(*p1!=*p2) return false;
}
return true;
}
inline bool rcmp(const char* a_1,const std::string& a_2) {
size_t l1 = ::strlen(a_1);
std::string::size_type l2 = a_2.size();
if(l1!=size_t(l2)) return false;
if(!l1) return true;
const char* p1 = a_1+l1-1;
const char* p2 = a_2.c_str()+l2-1;
//ab
//012
for(size_t index=0;index<l1;index++,p1--,p2--) {
if(*p1!=*p2) return false;
}
return true;
}
inline bool rcmp(const std::string& a_1,const std::string& a_2) {
std::string::size_type l1 = a_1.size();
std::string::size_type l2 = a_2.size();
if(l1!=l2) return false;
if(!l1) return true;
const char* p1 = a_1.c_str()+l1-1;
const char* p2 = a_2.c_str()+l2-1;
//ab
//012
for(std::string::size_type index=0;index<l1;index++,p1--,p2--) {
if(*p1!=*p2) return false;
}
return true;
}
}
#endif
@@ -0,0 +1,45 @@
#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) {
if(!a_new_size) {
delete [] a_pointer;
a_pointer = 0;
return true;
}
if(!a_pointer) {
a_pointer = new T[a_new_size];
return true;
}
if(a_old_size==a_new_size) return true;
T* pointer = new T[a_new_size];
if(!pointer) {
delete [] a_pointer;
a_pointer = 0;
return false;
}
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;
T* pos = pointer+a_old_size;
for(uint32 i=0;i<num;i++,pos++) *pos = T();
}
} else {
::memcpy(pointer,a_pointer,a_new_size*sizeof(T));
}
delete [] a_pointer;
a_pointer = pointer;
return true;
}
}
#endif
@@ -0,0 +1,33 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_safe_cast
#define tools_safe_cast
#include "cid"
namespace tools {
template <class FROM,class TO>
inline TO* safe_cast(FROM& a_o) {
return (TO*)a_o.cast(TO::s_class());
}
template <class FROM,class TO>
inline const TO* safe_cast(const FROM& a_o) {
return (const TO*)a_o.cast(TO::s_class());
}
template <class FROM,class TO>
inline TO* id_cast(FROM& a_o) {
return (TO*)a_o.cast(TO::id_class());
}
template <class FROM,class TO>
inline const TO* id_cast(const FROM& a_o) {
return (const TO*)a_o.cast(TO::id_class());
}
}
#endif
@@ -0,0 +1,28 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_scast
#define tools_scast
// For implementations of cast methods.
#include "safe_cast"
#include "rcmp"
namespace tools {
template <class TO>
inline void* cmp_cast(const TO* a_this,const std::string& a_class) {
if(!tools::rcmp(a_class,TO::s_class())) return 0;
return (void*)static_cast<const TO*>(a_this);
}
template <class TO>
inline void* cmp_cast(const TO* a_this,cid a_id) {
if(TO::id_class()!=a_id) return 0;
return (void*)static_cast<const TO*>(a_this);
}
}
#endif
@@ -0,0 +1,31 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_snpf
#define tools_snpf
#include <cstdarg>
#include <cstdio>
namespace tools {
inline int vsnpf(char* a_s,size_t a_n,const char* a_fmt,va_list args){
#ifdef WIN32
return _vsnprintf(a_s,a_n,a_fmt,args);
#else
return ::vsnprintf(a_s,a_n,a_fmt,args);
#endif
}
inline int snpf(char* a_s,size_t a_n,const char* a_fmt,...){
va_list args;
va_start(args,a_fmt);
int n = vsnpf(a_s,a_n,a_fmt,args);
va_end(args);
return n;
}
}
#endif
@@ -0,0 +1,17 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sout
#define tools_sout
#include <string>
namespace tools {
inline std::string sout(const std::string& a_string) {
return std::string("\"")+a_string+"\"";
}
}
#endif
@@ -0,0 +1,61 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sprintf
#define tools_sprintf
#include <string>
#include "snpf"
namespace tools {
inline bool vsprintf(std::string& a_string,int a_length,const char* a_format,va_list a_args){
a_string.clear();
if(a_length<0) return false;
if(!a_format) return false;
char* s = new char[a_length+1];
if(!s) return false;
s[a_length] = '\0';
int n = vsnpf(s,a_length+1,a_format,a_args);
if(n>a_length) {
delete [] s;
return false;
}
if(s[a_length]!='\0') {
delete [] s;
return false;
}
a_string = s;
delete [] s;
return true;
}
inline bool sprintf(std::string& a_string,int a_length,const char* a_format,...){
a_string.clear();
if(a_length<0) return false;
if(!a_format) return false;
char* s = new char[a_length+1];
if(!s) return false;
s[a_length] = '\0';
va_list args;
va_start(args,a_format);
int n = vsnpf(s,a_length+1,a_format,args);
va_end(args);
if(n>a_length) {
delete [] s;
return false;
}
if(s[a_length]!='\0') {
delete [] s;
return false;
}
a_string = s;
delete [] s;
return true;
}
}
#endif
@@ -0,0 +1,67 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_srep
#define tools_srep
#include <string>
#include <vector>
namespace tools {
inline void replace(std::string& a_string,char a_old,char a_new){
for(std::string::iterator it=a_string.begin();it!=a_string.end();++it) {
if((*it)==a_old) *it = a_new;
}
}
inline bool replace(std::string& a_string,const std::string& a_old,const std::string& a_new){
// return true : some replacement done.
// return false : nothing replaced.
if(a_old.empty()) return false;
std::string snew;
std::string::size_type lold = a_old.length();
bool status = false;
std::string stmp = a_string;
while(true) {
std::string::size_type pos = stmp.find(a_old);
if(pos==std::string::npos){
snew += stmp;
break;
} else {
snew += stmp.substr(0,pos);
snew += a_new;
stmp = stmp.substr(pos+lold,stmp.length()-(pos+lold));
status = true;
}
}
a_string = snew;
return status;
}
inline bool replace(std::vector<std::string>& a_strings,const std::string& a_old,const std::string& a_new){
std::vector<std::string>::iterator it;
for(it=a_strings.begin();it!=a_strings.end();++it) {
if(!replace(*it,a_old,a_new)) return false;
}
return true;
}
inline std::string to_xml(const std::string& a_string){
// > : &lt;
// < : &gt;
// & : &amp;
// " : &quot;
// ' : &apos;
std::string s = a_string;
replace(s,"<","&lt;");
replace(s,">","&gt;");
replace(s,"&","&amp;");
replace(s,"\"","&quot;");
replace(s,"'","&apos;");
return s;
}
}
#endif
+83
View File
@@ -0,0 +1,83 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_sto
#define tools_sto
#include <string>
namespace tools {
inline std::string to(bool a_value){return a_value?"true":"false";}
inline bool to(const std::string& a_string,bool& a_value){
if( (a_string=="1")
||(a_string=="true")||(a_string=="TRUE")||(a_string=="True")
||(a_string=="yes")||(a_string=="YES")||(a_string=="Yes")
||(a_string=="on")||(a_string=="ON")||(a_string=="On")
){
a_value = true;
return true;
} else if((a_string=="0")
||(a_string=="false")||(a_string=="FALSE")||(a_string=="False")
||(a_string=="no")||(a_string=="NO")||(a_string=="No")
||(a_string=="off")||(a_string=="OFF")||(a_string=="Off")
){
a_value = false;
return true;
} else {
a_value = false;
return false;
}
}
}
#include <sstream>
namespace tools {
template <class T>
inline bool to(const std::string& a_s,T& a_v,const T& a_def = T()) {
if(a_s.empty()) {a_v = a_def;return false;} //for TOOLS_STL istringstream.
std::istringstream strm(a_s.c_str());
strm >> a_v;
if(strm.fail()) {a_v = a_def;return false;}
return strm.eof();
}
template <class T>
inline std::string to(const T& a_v) {
std::ostringstream strm;
strm << a_v;
return strm.str();
}
inline std::string d2s(double a_value){
std::ostringstream strm;
strm.precision(25);
strm << a_value;
return strm.str();
}
inline std::string soutd(double a_value) {
return std::string("\"")+d2s(a_value)+"\"";
}
// for BatchLab/XML
template <class T>
inline std::string sout(const T& a_value) {
return std::string("\"")+to<T>(a_value)+"\"";
}
template <class T>
inline bool to(T& a_field,const std::string& a_s,bool& a_changed){
T old = a_field;
if(!tools::to(a_s,a_field)) {a_field = old;a_changed=false;return false;}
a_changed = a_field==old?false:true;
return true;
}
}
#endif
@@ -0,0 +1,71 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_store_iobj_const_visitor
#define tools_store_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 const std::string& store_cls() const = 0;
virtual bool visit(iobj_const_visitor&) const = 0;
// virtual bool read(iobj_visitor&) = 0;
};
class iobj_const_visitor {
public:
virtual ~iobj_const_visitor() {}
public:
typedef bool(*local_func)(const istorable&,iobj_const_visitor&);
public:
virtual bool begin(const istorable&,const std::string&,local_func) = 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
@@ -0,0 +1,48 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_store_iobj_visitor
#define tools_store_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
@@ -0,0 +1,881 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_store_osc_streamers
#define tools_store_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"
#include "../S_STRING"
#include "../scast"
namespace tools {
namespace osc {
inline const std::string& s_axis() {
static const std::string s_v("BatchLab::Axis");
return s_v;
}
inline const std::string& s_annotation() {
static const std::string s_v("BatchLab::Annotation");
return s_v;
}
inline const std::string& s_base_histogram() {
static const std::string s_v("BatchLab::BaseHistogram");
return s_v;
}
inline const std::string& s_item() {
static const std::string s_v("BatchLab::Item");
return s_v;
}
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;
}
class Axis : public virtual istorable {
public:
TOOLS_SCLASS(tools::osc::Axis)
protected:
virtual void* cast(const std::string& a_class) const {
if(void* p = tools::cmp_cast<Axis>(this,a_class)) return p;
return 0;
}
virtual const std::string& store_cls() const {return s_axis();}
virtual bool visit(iobj_const_visitor& a_v) const {
if(!a_v.begin(*this,s_axis(),Axis::s_visit)) return false;
int version = 1;
if(!a_v.visit("fVersion",version)) return false;
if(!a_v.visit("fOffset",m_axis.m_offset)) return false;
if(!a_v.visit("fNumberOfBins",(int)m_axis.m_number_of_bins)) return false;
if(!a_v.visit("fMinimumValue",m_axis.m_minimum_value)) return false;
if(!a_v.visit("fMaximumValue",m_axis.m_maximum_value)) return false;
if(!a_v.visit("fFixed",m_axis.m_fixed)) return false;
if(!a_v.visit("fBinWidth",m_axis.m_bin_width)) return false;
if(!a_v.visit("fEdges",m_axis.m_edges)) return false;
if(!a_v.end(*this)) return false;
return true;
}
static bool s_visit(const istorable& a_o,iobj_const_visitor& a_v){
const Axis* local = tools::safe_cast<istorable,Axis>(a_o);
if(!local) return false;
return local->Axis::visit(a_v); //IMPORTANT : have Axis::
}
public:
Axis(const histo::axis<double>& a_axis):m_axis(a_axis){}
virtual ~Axis(){}
private:
Axis(const Axis& a_from):istorable(a_from),m_axis(a_from.m_axis){}
Axis& operator=(const Axis&){return *this;}
protected:
const histo::axis<double>& m_axis;
};
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:
TOOLS_SCLASS(tools::osc::Item)
protected:
virtual void* cast(const std::string& a_class) const {
if(void* p = tools::cmp_cast<Item>(this,a_class)) return p;
return 0;
}
public:
virtual const std::string& store_cls() const {return s_item();}
virtual bool visit(iobj_const_visitor& a_visitor) const {
if(!a_visitor.begin(*this,s_item(),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;
}
static bool s_visit(const istorable& a_o,iobj_const_visitor& a_v){
const Item* local = tools::safe_cast<istorable,Item>(a_o);
if(!local) return false;
return local->Item::visit(a_v); //IMPORTANT : have Item::
}
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>
class Vector : public virtual istorable {
public:
TOOLS_T_SCLASS(T,tools::osc::Vector)
protected:
virtual void* cast(const std::string& a_class) const {
if(void* p = tools::cmp_cast<Vector>(this,a_class)) return p;
return 0;
}
virtual const std::string& store_cls() const {
static const std::string s_v("BatchLab::Vector<"+m_T+">");
return s_v;
}
virtual bool visit(iobj_const_visitor& a_v) const {
if(!a_v.begin
(*this,Vector<T>::store_cls(),Vector<T>::s_visit)) return false;
int version = 1;
if(!a_v.visit("fVersion",version)) return false;
unsigned int number = m_vec.size();
if(!a_v.visit("fSize",number)) return false;
for(unsigned int index=0;index<number;index++) {
const T& elem = m_vec[index];
if(!a_v.visit(to<int>(index),elem)) return false;
}
if(!a_v.end(*this)) return false;
return true;
}
static bool s_visit(const istorable& a_o,iobj_const_visitor& a_v){
const Vector* local = tools::safe_cast<istorable,Vector>(a_o);
if(!local) return false;
return local->Vector<T>::visit(a_v); //IMPORTANT : have Vector::
}
public:
Vector(const std::vector<T>& a_vec,const std::string& a_T)
:m_vec(a_vec),m_T(a_T){}
virtual ~Vector(){}
private:
Vector(const Vector& a_from)
:istorable(a_from),m_vec(a_from.m_vec),m_T(a_from.m_T){}
Vector& operator=(const Vector&){return *this;}
protected:
const std::vector<T>& m_vec;
std::string m_T;
};
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;
}
class Annotation : public virtual istorable {
public:
TOOLS_SCLASS(tools::osc::Annotation)
protected:
virtual void* cast(const std::string& a_class) const {
if(void* p = tools::cmp_cast<Annotation>(this,a_class)) return p;
return 0;
}
virtual const std::string& store_cls() const {return s_annotation();}
virtual bool visit(iobj_const_visitor& a_v) const {
if(!a_v.begin(*this,s_annotation(),Annotation::s_visit)) return false;
int version = 1;
if(!a_v.visit("fVersion",version)) return false;
Vector<Item> v(m_items,s_item());
if(!a_v.visit("fItems",v)) return false;
if(!a_v.end(*this)) return false;
return true;
}
static bool s_visit(const istorable& a_o,iobj_const_visitor& a_v){
const Annotation* local = tools::safe_cast<istorable,Annotation>(a_o);
if(!local) return false;
return local->Annotation::visit(a_v); //IMPORTANT : have Annotation::
}
public:
Annotation(){}
virtual ~Annotation(){}
private:
Annotation(const Annotation& a_from):istorable(a_from){}
Annotation& operator=(const Annotation&){return *this;}
public:
std::vector<Item> m_items;
};
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;
class BaseHistogram : public virtual istorable {
public:
TOOLS_SCLASS(tools::osc::BaseHistogram)
protected:
virtual void* cast(const std::string& a_class) const {
if(void* p = tools::cmp_cast<BaseHistogram>(this,a_class)) return p;
return 0;
}
public:
virtual const std::string& store_cls() const {return s_base_histogram();}
virtual bool visit(iobj_const_visitor& a_v) const {
if(!a_v.begin
(*this,s_base_histogram(),BaseHistogram::s_visit)) return false;
int version = 1;
if(!a_v.visit("fVersion",version)) return false;
Annotation ano;
map2vec(m_data.m_annotations,ano.m_items);
if(!a_v.visit("fAnnotation",ano)) return false;
if(!a_v.end(*this)) return false;
return true;
}
protected:
static bool s_visit(const istorable& a_o,iobj_const_visitor& a_v){
const BaseHistogram* local =
tools::safe_cast<istorable,BaseHistogram>(a_o);
if(!local) return false;
return local->BaseHistogram::visit(a_v); //IMPORTANT : have BaseHistogram::
}
public:
BaseHistogram(const hd_data& a_data):m_data(a_data){}
virtual ~BaseHistogram(){}
private:
BaseHistogram(const BaseHistogram& a_from)
:istorable(a_from),m_data(a_from.m_data)
{}
BaseHistogram& operator=(const BaseHistogram&){return *this;}
protected:
const hd_data& m_data;
};
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);
Axis axis(aData.m_axes[iaxis]);
if(!a_visitor.visit(name,axis)) 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;
}
class Histogram : public virtual istorable {
public:
TOOLS_SCLASS(tools::osc::Histogram)
protected:
virtual void* cast(const std::string& a_class) const {
if(void* p = tools::cmp_cast<Histogram>(this,a_class)) return p;
return 0;
}
public:
virtual const std::string& store_cls() const {return m_cls;}
virtual bool visit(iobj_const_visitor& a_v) const {
if(!a_v.begin(*this,m_cls,Histogram::s_visit)) return false;
int version = 1;
if(!a_v.visit("fVersion",version)) return false;
BaseHistogram bh(m_data);
if(!bh.visit(a_v)) return false;
if(!visitHistogram(m_data,a_v)) return false;
if(!a_v.end(*this)) return false;
return true;
}
protected:
static bool s_visit(const istorable& a_o,iobj_const_visitor& a_v){
const Histogram* local = tools::safe_cast<istorable,Histogram>(a_o);
if(!local) return false;
return local->Histogram::visit(a_v); //IMPORTANT : have Histogram::
}
public:
Histogram(const hd_data& a_data,const std::string& a_cls)
:m_data(a_data),m_cls(a_cls){}
virtual ~Histogram(){}
public:
Histogram(const Histogram& a_from)
:istorable(a_from)
,m_data(a_from.m_data)
,m_cls(a_from.m_cls)
{}
Histogram& operator=(const Histogram& a_from){
m_cls = a_from.m_cls;
return *this;
}
protected:
const hd_data& m_data;
std::string m_cls;
};
inline bool visit(iobj_const_visitor& a_v,const histo::h1d& a_histo) {
hd_data d = a_histo.get_histo_data();
Histogram h(d,s_h1d());
return h.visit(a_v);
}
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_v,const histo::h2d& a_histo) {
hd_data d = a_histo.get_histo_data();
Histogram h(d,s_h2d());
return h.visit(a_v);
}
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_v,const histo::h3d& a_histo) {
hd_data d = a_histo.get_histo_data();
Histogram h(d,s_h3d());
return h.visit(a_v);
}
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);
Axis axis(aData.m_axes[iaxis]);
if(!a_visitor.visit(name,axis)) 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;
}
class Profile : public virtual istorable {
public:
TOOLS_SCLASS(tools::osc::Profile)
protected:
virtual void* cast(const std::string& a_class) const {
if(void* p = tools::cmp_cast<Profile>(this,a_class)) return p;
return 0;
}
public:
virtual const std::string& store_cls() const {return m_cls;}
virtual bool visit(iobj_const_visitor& a_v) const {
if(!a_v.begin(*this,m_cls,Profile::s_visit)) return false;
int version = 1;
if(!a_v.visit("fVersion",version)) return false;
BaseHistogram bh(m_data);
if(!bh.visit(a_v)) return false;
if(!visitProfile(m_data,a_v)) return false;
if(!a_v.end(*this)) return false;
return true;
}
protected:
static bool s_visit(const istorable& a_o,iobj_const_visitor& a_v){
const Profile* local = tools::safe_cast<istorable,Profile>(a_o);
if(!local) return false;
return local->Profile::visit(a_v); //IMPORTANT : have Profile::
}
public:
Profile(const pd_data& a_data,const std::string& a_cls)
:m_data(a_data),m_cls(a_cls){}
virtual ~Profile(){}
public:
Profile(const Profile& a_from)
:istorable(a_from)
,m_data(a_from.m_data)
,m_cls(a_from.m_cls)
{}
Profile& operator=(const Profile& a_from){
m_cls = a_from.m_cls;
return *this;
}
protected:
const pd_data& m_data;
std::string m_cls;
};
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_v,const histo::p1d& a_histo) {
pd_data d = a_histo.get_histo_data();
Profile h(d,s_p1d());
return h.visit(a_v);
}
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_v,const histo::p2d& a_histo) {
pd_data d = a_histo.get_histo_data();
Profile h(d,s_p2d());
return h.visit(a_v);
}
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;
}
class Histogram_cp : public Histogram {
public:
Histogram_cp(const hd_data& a_data,const std::string& a_cls)
:Histogram(m_cp,a_cls) //give ref of m_cp to Histogram.
,m_cp(a_data) //do a local copy.
//WARNING : the upper is ok as long as Histogram constructor does nothing
// else than keeping the ref to m_cp. Else it would do
// something on an empty histo (and not on a copy of the
// passed a_data).
{}
virtual ~Histogram_cp(){}
public:
Histogram_cp(const Histogram_cp& a_from)
:istorable(a_from)
,Histogram(m_cp,a_from.m_cls)
,m_cp(a_from.m_cp)
{}
Histogram_cp& operator=(const Histogram_cp& a_from){
Histogram::operator=(a_from);
m_cp = a_from.m_cp;
return *this;
}
protected:
hd_data m_cp;
};
class Profile_cp : public Profile {
public:
Profile_cp(const pd_data& a_data,const std::string& a_cls)
:Profile(m_cp,a_cls) //give ref of m_cp to Profile.
,m_cp(a_data) //do a local copy.
//WARNING : the upper is ok as long as Profile constructor does nothing
// else than keeping the ref to m_cp. Else it would do
// something on an empty histo (and not on a copy of the
// passed a_data).
{}
virtual ~Profile_cp(){}
public:
Profile_cp(const Profile_cp& a_from)
:istorable(a_from)
,Profile(m_cp,a_from.m_cls)
,m_cp(a_from.m_cp)
{}
Profile_cp& operator=(const Profile_cp& a_from){
Profile::operator=(a_from);
m_cp = a_from.m_cp;
return *this;
}
protected:
pd_data m_cp;
};
}}
#endif
@@ -0,0 +1,68 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_strip
#define tools_strip
#include <vector>
#include <string>
namespace tools {
enum what { leading, trailing, both };
inline bool strip(std::string& a_string,what a_type = both,char a_char = ' '){
//return true = some stripping had been done.
std::string::size_type l = a_string.length();
if(l==0) return false;
switch ( a_type ) {
case leading:{
char* pos = (char*)a_string.c_str();
for(std::string::size_type i=0;i<l;i++,pos++) {
if(*pos!=a_char) {
a_string = a_string.substr(i,l-i);
return (i?true:false); //i=0 : same string.
}
}
}break;
case trailing:{
char* pos = (char*)a_string.c_str();
pos += (l-1);
for(std::string::size_type i=l-1;;i--,pos--) {
if(*pos!=a_char) {
a_string = a_string.substr(0,i+1);
return (i==(l-1)?false:true); //i==l-1 : same string.
}
}
}break;
case both:{
bool stat_lead = strip(a_string,leading,a_char);
bool stat_trail = strip(a_string,trailing,a_char);
if(stat_lead) return true;
if(stat_trail) return true;
}break;
//default:break;
}
return false; //nothing done.
}
inline std::string strp(const std::string& a_string,what a_type = both,char a_char = ' '){
std::string s(a_string);
strip(s,a_type,a_char);
return s;
}
inline bool strip(std::vector<std::string>& a_strings,what a_type = both,char a_char = ' ') {
bool some_done = false;
std::vector<std::string>::iterator it;
for(it=a_strings.begin();it!=a_strings.end();++it) {
if(strip(*it,a_type,a_char)) some_done = true;
}
return some_done;
}
}
#endif
@@ -0,0 +1,71 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_stype
#define tools_stype
//used in rroot leaf template.
#include "typedefs"
#include <string>
namespace tools {
inline const std::string& stype(unsigned char) {
static const std::string s_v("unsigned char");
return s_v;
}
inline const std::string& stype(char) {
static const std::string s_v("char");
return s_v;
}
inline const std::string& stype(unsigned short) {
static const std::string s_v("unsigned short");
return s_v;
}
inline const std::string& stype(short) {
static const std::string s_v("short");
return s_v;
}
inline const std::string& stype(int) {
static const std::string s_v("int");
return s_v;
}
inline const std::string& stype(unsigned int) {
static const std::string s_v("unsigned int");
return s_v;
}
inline const std::string& stype(float) {
static const std::string s_v("float");
return s_v;
}
inline const std::string& stype(double) {
static const std::string s_v("double");
return s_v;
}
// for inlib::mcol<T> :
inline const std::string& stype(int64) {
static const std::string s_v("tools::int64");
return s_v;
}
inline const std::string& stype(uint64) {
static const std::string s_v("tools::uint64");
return s_v;
}
inline const std::string& stype(const std::string&) {
static const std::string s_v("std::string");
return s_v;
}
}
#endif
+125
View File
@@ -0,0 +1,125 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_tos
#define tools_tos
// Used in BatchLab/MemoryTuple and Rio_Tuple.
// We need something different than the to<T>
// to handle std::vector<> and bool.
#include "sprintf"
#include "charmanip"
#include "typedefs"
#include <vector>
namespace tools {
inline std::string tos(unsigned char a_value){
std::string s;
if(is_printable(a_value))
sprintf(s,32,"%c",a_value);
else
sprintf(s,32,"%d",a_value);
return s;
}
inline std::string tos(char a_value){
std::string s;
if(is_printable(a_value))
sprintf(s,32,"%c",a_value);
else
sprintf(s,32,"%d",a_value);
return s;
}
inline std::string tos(unsigned short a_value) {
std::string s;
sprintf(s,32,"%d",a_value);
return s;
}
inline std::string tos(short a_value){
std::string s;
sprintf(s,32,"%d",a_value);
return s;
}
inline std::string tos(unsigned int a_value) {
std::string s;
sprintf(s,32,"%u",a_value);
return s;
}
inline std::string tosx(unsigned int a_value) {
std::string s;
sprintf(s,32,"%x",a_value);
return s;
}
inline std::string tos(int a_value){
std::string s;
sprintf(s,32,"%d",a_value);
return s;
}
inline std::string tos(uint64 a_value) {
std::string s;
sprintf(s,32,uint64_format(),a_value);
return s;
}
inline std::string tos(int64 a_value){
std::string s;
sprintf(s,32,int64_format(),a_value);
return s;
}
inline std::string tos(float a_value){
std::string s;
sprintf(s,32,"%g",a_value);
return s;
}
inline std::string tos(double a_value){
std::string s;
sprintf(s,32,"%g",a_value);
return s;
}
inline std::string tos(bool a_value){
return std::string(a_value?"true":"false");
}
inline std::string tos(const std::string& a_value){return a_value;}
template <class T>
inline std::string tos(const std::vector<T>& a_vals,
const std::string& a_sep = "\n",
bool a_sep_at_end = false) {
unsigned int number = a_vals.size();
if(number<=0) return "";
std::string result;
number--;
for(unsigned int index=0;index<number;index++) {
result += tos(a_vals[index]);
result += a_sep;
}
result += tos(a_vals[number]);
if(a_sep_at_end) result += a_sep;
return result;
}
inline std::string tos(unsigned int a_linen,const char* a_lines[]) {
std::string s;
for(unsigned int index=0;index<a_linen;index++) {
s += std::string(a_lines[index]);
s += "\n";
}
return s;
}
}
#endif
@@ -0,0 +1,94 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_typedefs
#define tools_typedefs
// Similar to AIDA/v3r3p0/Types.h
//NOTE : we avoid to have std includes here to be sure
// that in the below ifdef things come only from the compiler.
//NOTE : if adding new platform here, look at ./s2int64 too.
namespace tools {
#if defined(WIN32) && !defined(GNU_GCC)
// WIN32 and NOT GNU_GCC
typedef int int32;
typedef __int64 int64;
inline const char* int32_format() {static const char s[] = "%d";return s;}
inline const char* int64_format() {static const char s[] = "%ld";return s;}
typedef unsigned int uint32;
typedef unsigned __int64 uint64;
inline const char* uint32_format() {static const char s[] = "%u";return s;}
inline const char* uint64_format() {static const char s[] = "%lu";return s;}
#elif defined(_LP64)
// 64 Bit Platforms
typedef int int32;
typedef long int64;
inline const char* int32_format() {static const char s[] = "%d";return s;}
inline const char* int64_format() {static const char s[] = "%ld";return s;}
typedef unsigned int uint32;
typedef unsigned long uint64;
inline const char* uint32_format() {static const char s[] = "%u";return s;}
inline const char* uint64_format() {static const char s[] = "%lu";return s;}
#else
// 32-Bit Platforms
typedef int int32;
typedef long long int64;
inline const char* int32_format() {static const char s[] = "%d";return s;}
inline const char* int64_format() {static const char s[] = "%lld";return s;}
typedef unsigned int uint32;
typedef unsigned long long uint64;
inline const char* uint32_format() {static const char s[] = "%u";return s;}
inline const char* uint64_format() {static const char s[] = "%llu";return s;}
#endif
inline uint32 uint32_mx() { //4 294 967 295
uint32 n = 0;
for(unsigned int i=0;i<32;i++) n += 1<<i;
return n;
}
inline uint64 uint64_mx() { //18 446 744 073 709 551 615
uint64 one = 1;
uint64 n = 0;
for(unsigned int i=0;i<64;i++) n += one<<i;
return n;
}
typedef unsigned char byte;
//for ./io :
typedef unsigned char uchar;
typedef short int16;
typedef unsigned short ushort;
typedef unsigned short uint16;
typedef uint32 ref;
// sizeof(long)==sizeof(void*) on all platforms.
typedef unsigned long diff_pointer_t;
typedef char* cstr_t;
typedef const char* const_cstr_t;
class fits_bit {public:char m_c;}; //for exlib/cfitsio
class csv_time {public:long m_l;}; //for inlib/rcsv_ntuple
inline unsigned int size_char() {return 1;}
inline unsigned int size_short() {return 2;}
inline unsigned int size_int() {return 4;}
inline unsigned int size_int64() {return 8;}
inline unsigned int size_float() {return 4;}
inline unsigned int size_double() {return 8;}
}
#endif
@@ -0,0 +1,17 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_version
#define tools_version
#define TOOLS_MAJOR_VERSION 1
#define TOOLS_MINOR_VERSION 7
#define TOOLS_PATCH_VERSION 0
#define TOOLS_VERSION "1.7.0"
#define TOOLS_VERSION_VRP "v1r7p0"
namespace tools {
inline unsigned int version() {return 10700;}
}
#endif
@@ -0,0 +1,37 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_vfind
#define tools_vfind
#include <vector>
#include <string>
namespace tools {
template <class T>
inline T* find_named(const std::vector<T*>& a_vec,const std::string& a_name) {
typedef typename std::vector<T*>::const_iterator it_t;
it_t it;
for(it=a_vec.begin();it!=a_vec.end();++it) {
if((*it)->name()==a_name) return *it;
}
return 0;
}
/*
template <class T>
inline const T* find_named_(const std::vector<T>& a_vec,
const std::string& a_name) {
typedef typename std::vector<T>::const_iterator it_t;
it_t it;
for(it=a_vec.begin();it!=a_vec.end();++it) {
if((*it).name()==a_name) return &(*it);
}
return 0;
}
*/
}
#endif
@@ -0,0 +1,317 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_vmanip
#define tools_vmanip
#include <vector>
namespace tools {
//////////////////////////////////////////////////////////
/// manipulations that induces no intermediate vector : //
//////////////////////////////////////////////////////////
template <class T>
inline void clear(std::vector<T*>& a_vec){
// the below takes into account the case in
// which "delete entry" could modify a_vec.
typedef typename std::vector<T*>::iterator it_t;
while(!a_vec.empty()) {
it_t it = a_vec.begin();
T* entry = *it;
a_vec.erase(it);
delete entry;
}
}
template <class T>
inline void raw_clear(std::vector<T*>& a_vec){
typedef typename std::vector<T*>::iterator it_t;
for(it_t it = a_vec.begin();it!=a_vec.end();++it) delete *it;
a_vec.clear();
}
template <class T>
inline void copy(std::vector<T*>& a_to,const std::vector<T*>& a_from){
raw_clear<T>(a_to);
typedef typename std::vector<T*>::const_iterator it_t;
for(it_t it = a_from.begin();it!=a_from.end();++it) {
a_to.push_back((*it)->copy());
}
}
template <class T>
inline void append(std::vector<T>& a_vec,const std::vector<T>& a_from) {
typedef typename std::vector<T>::size_type sz_t;
sz_t vsize = a_vec.size();
sz_t number = a_from.size();
a_vec.resize(vsize+number);
sz_t offset = vsize;
for(sz_t index=0;index<number;index++,offset++) {
a_vec[offset] = a_from[index];
}
}
template <class T>
inline void append(std::vector<T>& a_vec,unsigned int a_num,const T* a_from) {
typedef typename std::vector<T>::size_type sz_t;
sz_t vsize = a_vec.size();
a_vec.resize(vsize+a_num);
sz_t offset = vsize;
for(sz_t index=0;index<a_num;index++,offset++) {
a_vec[offset] = a_from[index];
}
}
template <class T>
inline void removep(std::vector<T*>& a_vec,T* a_elem) {
typedef typename std::vector<T*>::iterator it_t;
it_t it;
for(it=a_vec.begin();it!=a_vec.end();) {
if(*it==a_elem) {
it = a_vec.erase(it);
} else {
++it;
}
}
}
template <class T>
inline void push_back_unique(std::vector<T>& a_vec,const T& a_v) {
typedef typename std::vector<T>::const_iterator it_t;
for(it_t it=a_vec.begin();it!=a_vec.end();++it) {if(*it==a_v) return;}
a_vec.push_back(a_v);
}
template <class T>
inline bool remove(std::vector<T>& a_vals,const T& a_elem){
bool found_some = false;
//std::vector<T>::iterator it;
//for(it=a_vals.begin();it!=a_vals.end();) {
// if(*it==a_elem) {
// it = a_vals.erase(it);
// found_some = true;
// } else {
// ++it;
// }
//}
//TOOLS_STL : brut force avoiding erase() :
std::vector<T> vs;
typedef typename std::vector<T>::iterator it_t;
for(it_t it=a_vals.begin();it!=a_vals.end();++it) {
if(*it==a_elem) {
found_some = true;
} else {
vs.push_back(*it);
}
}
a_vals = vs;
return found_some;
}
template <class T>
inline void unique(std::vector<T>& a_vec) {
typedef typename std::vector<T>::iterator it_t;
it_t it,it2;
for(it=a_vec.begin();it!=a_vec.end();++it) {
it2 = it;it2++; //TOOLS_STL : it2=it+1 does not compile.
for(;it2!=a_vec.end();) {
if(*it2==*it) {
it2 = a_vec.erase(it2);
} else {
++it2;
}
}
}
}
template <class T>
inline bool item_index(const std::vector<T>& a_vec,const T& a_item,unsigned int& a_index){
a_index = 0;
typedef typename std::vector<T>::const_iterator it_t;
it_t it;
for(it=a_vec.begin();it!=a_vec.end();++it,a_index++) {
if(*it==a_item) return true;
}
a_index = 0;
return false;
}
template <class T>
inline bool belong(const std::vector<T>& a_vec,const T& a_item){
typedef typename std::vector<T>::const_iterator it_t;
it_t it;
for(it=a_vec.begin();it!=a_vec.end();++it) {
if(*it==a_item) return true;
}
return false;
}
template <class T>
inline bool minimum(const std::vector<T>& a_vec,T& a_value) {
if(a_vec.empty()) {a_value = T();return false;}
a_value = a_vec[0];
typedef typename std::vector<T>::const_iterator it_t;
for(it_t it = a_vec.begin();it!=a_vec.end();++it) {
a_value = (a_value<(*it)?a_value:(*it));
}
return true;
}
template <class T>
inline bool maximum(const std::vector<T>& a_vec,T& a_value) {
if(a_vec.empty()) {a_value = T();return false;}
a_value = a_vec[0];
typedef typename std::vector<T>::const_iterator it_t;
for(it_t it = a_vec.begin();it!=a_vec.end();++it) {
a_value = (a_value>(*it)?a_value:(*it));
}
return true;
}
template <class T>
inline T sum(const std::vector<T>& a_vec) {
T sum = T();
typedef typename std::vector<T>::const_iterator it_t;
for(it_t it = a_vec.begin();it!=a_vec.end();++it) sum += *it;
return sum;
}
template <class T>
inline void filter(std::vector<T>& a_vec,
unsigned int a_mn,unsigned int a_mx){
unsigned int imx = a_vec.size()-1;
unsigned int mx = a_mx<imx?a_mx:imx;
unsigned int i = 0;
for(unsigned int index=a_mn;index<=mx;index++) {
a_vec[i] = a_vec[index];i++;
}
a_vec.resize(i);
}
template <class T>
inline void steps(std::vector<T>& a_vec,unsigned int a_number){
a_vec.resize(a_number);
for(unsigned int index=0;index<a_number;index++) a_vec[index] = T(index);
}
template <class T>
inline bool add(std::vector<T>& a_vec,const std::vector<T>& a_v){
if(a_vec.size()!=a_v.size()) return false;
typedef typename std::vector<T>::iterator it_t;
typedef typename std::vector<T>::const_iterator cit_t;
it_t it = a_vec.begin();
cit_t vit = a_v.begin();
for(;it!=a_vec.end();++it,++vit) *it += *vit;
return true;
}
template <class T>
inline bool sub(std::vector<T>& a_vec,const std::vector<T>& a_v){
if(a_vec.size()!=a_v.size()) return false;
typedef typename std::vector<T>::iterator it_t;
typedef typename std::vector<T>::const_iterator cit_t;
it_t it = a_vec.begin();
cit_t vit = a_v.begin();
for(;it!=a_vec.end();++it,++vit) *it -= *vit;
return true;
}
template <class T>
inline bool div(std::vector<T>& a_vec,const std::vector<T>& a_v){
if(a_vec.size()!=a_v.size()) return false;
typedef typename std::vector<T>::iterator it_t;
typedef typename std::vector<T>::const_iterator cit_t;
it_t it = a_vec.begin();
cit_t vit = a_v.begin();
bool errors = false;
for(;it!=a_vec.end();++it,++vit) {
if(*vit==T()) {
errors = true;
} else {
*it /= *vit;
}
}
return errors;
}
template <class T>
inline void add(std::vector<T>& a_vec,const T& a_v){
typedef typename std::vector<T>::iterator it_t;
for(it_t it=a_vec.begin();it!=a_vec.end();++it) *it += a_v;
}
template <class T>
inline void sub(std::vector<T>& a_vec,const T& a_v){
typedef typename std::vector<T>::iterator it_t;
for(it_t it=a_vec.begin();it!=a_vec.end();++it) *it -= a_v;
}
template <class T>
inline void mul(std::vector<T>& a_vec,const T& a_v){
typedef typename std::vector<T>::iterator it_t;
for(it_t it=a_vec.begin();it!=a_vec.end();++it) *it *= a_v;
}
template <class T>
inline void div(std::vector<T>& a_vec,const T& a_v){
typedef typename std::vector<T>::iterator it_t;
for(it_t it=a_vec.begin();it!=a_vec.end();++it) *it /= a_v;
}
template <class FROM,class TO>
inline std::vector<TO> convert(const std::vector<FROM>& a_from){
typedef typename std::vector<FROM>::const_iterator const_it_t;
typedef typename std::vector<TO>::iterator it_t;
std::vector<TO> to(a_from.size());
const_it_t ait = a_from.begin();
it_t toit = to.begin();
for(;ait!=a_from.end();++ait,++toit) {*toit = (TO)*ait;}
return to;
}
}
///////////////////////////////////////////////////////////
/// manipulations that induces other includes : ///////////
///////////////////////////////////////////////////////////
#include <ostream>
namespace tools {
//NOTE : print is a Python keyword.
template <class T>
inline void dump(const std::vector<T>& a_vec,std::ostream& a_out){
typedef typename std::vector<T>::const_iterator it_t;
it_t it;
for(it=a_vec.begin();it!=a_vec.end();++it) {
a_out << *it << std::endl;
}
}
}
#include <cmath>
namespace tools {
template <class T>
inline bool mean_rms(const std::vector<T>& a_vec,T& a_mean,T& a_rms) {
if(a_vec.empty()) {a_mean=T();a_rms=T();return false;}
T S = T();
T S2 = T();
typedef typename std::vector<T>::const_iterator it_t;
for(it_t it = a_vec.begin();it!=a_vec.end();++it) {
S += *it;
S2 += (*it) * (*it);
}
a_mean = S/T(a_vec.size());
//NOTE : should use a templated sqrt and fabs.
a_rms = ::sqrt(::fabs(S2/T(a_vec.size()) - a_mean * a_mean));
return true;
}
}
#endif
@@ -0,0 +1,37 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_waxml_begend
#define tools_waxml_begend
#include <fstream>
#include "../sout"
#include "../version"
namespace tools {
namespace waxml {
inline void begin(std::ostream& a_writer){
// Header :
a_writer << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
a_writer << "<!DOCTYPE aida SYSTEM"
<< " \"http://aida.freehep.org/schemas/3.0/aida.dtd\">"
<< std::endl;
std::string sAIDA_VERSION("3.2.1");
a_writer << "<aida version=" << sout(sAIDA_VERSION) << ">"
<< std::endl;
a_writer << " <implementation package=" << sout("tools")
<< " version=" << sout(TOOLS_VERSION) << "/>"
<< std::endl;
}
inline void end(std::ostream& a_writer){
a_writer << "</aida>" << std::endl;
}
}}
#endif
@@ -0,0 +1,718 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_waxml_histos
#define tools_waxml_histos
#include "../histo/h1d"
#include "../histo/h2d"
#include "../histo/h3d"
#include "../histo/p1d"
#include "../histo/p2d"
#include "../sout"
#include "../sto"
namespace tools {
namespace waxml {
inline std::string bin_to_string(int a_index) {
if(a_index==histo::axis<double>::UNDERFLOW_BIN) {
return "UNDERFLOW";
} else if(a_index==histo::axis<double>::OVERFLOW_BIN) {
return "OVERFLOW";
} else {
std::ostringstream strm;
strm << a_index;
return strm.str();
}
}
typedef std::map<std::string,std::string> annotations_t;
inline void write_annotations(
const annotations_t& a_annotations
,std::ostream& a_writer
,int aShift
){
if(a_annotations.empty()) return;
std::string spaces;
for(int i=0;i<aShift;i++) spaces += " ";
a_writer << spaces << " <annotation>" << std::endl;
annotations_t::const_iterator it;
for(it=a_annotations.begin();it!=a_annotations.end();++it){
a_writer << spaces << " <item"
<< " key=" << sout((*it).first)
<< " value=" << sout((*it).second)
<< "/>" << std::endl;
}
a_writer << spaces << " </annotation>" << std::endl;
}
inline void write_axis(
const histo::axis<double>& aAxis
,const std::string& aDirection
,std::ostream& a_writer
,int aShift
){
typedef histo::axis<double>::bn_t bn_t;
std::string spaces;
for(int i=0;i<aShift;i++) spaces += " ";
if(aAxis.is_fixed_binning()) {
a_writer << spaces << " <axis"
<< " direction=" << sout(aDirection)
<< " numberOfBins=" << sout<bn_t>(aAxis.bins())
<< " min=" << soutd(aAxis.lower_edge())
<< " max=" << soutd(aAxis.upper_edge())
<< "/>" << std::endl;
} else {
a_writer << spaces << " <axis"
<< " direction=" << sout(aDirection)
<< " numberOfBins=" << sout<bn_t>(aAxis.bins())
<< " min=" << soutd(aAxis.lower_edge())
<< " max=" << soutd(aAxis.upper_edge())
<< ">" << std::endl;
bn_t number = aAxis.bins()-1;
for(bn_t index=0;index<number;index++) {
a_writer << spaces << " <binBorder"
<< " value=" << soutd(aAxis.bin_upper_edge(index))
<< "/>" << std::endl;
}
a_writer << spaces << " </axis>" << std::endl;
}
}
inline void write_bin(
std::ostream& a_writer
,const histo::h1d& aObject
,const std::string& aSpaces
,int aIndex
){
unsigned int entries = aObject.bin_entries(aIndex);
if(entries) {
a_writer << aSpaces << " <bin1d"
<< " binNum=" << sout(bin_to_string(aIndex))
<< " entries=" << sout<unsigned int>(entries)
<< " height=" << soutd(aObject.bin_height(aIndex))
<< " error=" << soutd(aObject.bin_error(aIndex));
double mean = aObject.bin_mean(aIndex);
if(mean!=0) {
a_writer << " weightedMean=" << soutd(mean);
}
double stddev = aObject.bin_rms(aIndex);
if(stddev!=0) {
a_writer << " weightedRms=" << soutd(stddev);
}
a_writer << "/>" << std::endl;
}
}
inline void write_bin(
std::ostream& a_writer
,const histo::h2d& aObject
,const std::string& aSpaces
,int aIndexX
,int aIndexY
){
unsigned int entries = aObject.bin_entries(aIndexX,aIndexY);
if(entries) {
a_writer << aSpaces << " <bin2d"
<< " binNumX=" << sout(bin_to_string(aIndexX))
<< " binNumY=" << sout(bin_to_string(aIndexY))
<< " entries=" << sout<unsigned int>(entries)
<< " height=" << soutd(aObject.bin_height(aIndexX,aIndexY))
<< " error=" << soutd(aObject.bin_error(aIndexX,aIndexY));
double mean_x = aObject.bin_mean_x(aIndexX,aIndexY);
if(mean_x!=0) {
a_writer << " weightedMeanX=" << soutd(mean_x);
}
double mean_y = aObject.bin_mean_y(aIndexX,aIndexY);
if(mean_y!=0) {
a_writer << " weightedMeanY=" << soutd(mean_y);
}
double stddevX = aObject.bin_rms_x(aIndexX,aIndexY);
if(stddevX!=0) {
a_writer << " weightedRmsX=" << soutd(stddevX);
}
double stddevY = aObject.bin_rms_y(aIndexX,aIndexY);
if(stddevY!=0) {
a_writer << " weightedRmsY=" << soutd(stddevY);
}
a_writer << "/>" << std::endl;
}
}
inline void write_bin(
std::ostream& a_writer
,const histo::h3d& aObject
,const std::string& aSpaces
,int aIndexX
,int aIndexY
,int aIndexZ
){
unsigned int entries = aObject.bin_entries(aIndexX,aIndexY,aIndexZ);
if(entries) {
a_writer << aSpaces << " <bin3d"
<< " binNumX=" << sout(bin_to_string(aIndexX))
<< " binNumY=" << sout(bin_to_string(aIndexY))
<< " binNumZ=" << sout(bin_to_string(aIndexZ))
<< " entries=" << sout<unsigned int>(entries)
<< " height=" << soutd(aObject.bin_height(aIndexX,aIndexY,aIndexZ))
<< " error=" << soutd(aObject.bin_error(aIndexX,aIndexY,aIndexZ));
double mean_x = aObject.bin_mean_x(aIndexX,aIndexY,aIndexZ);
if(mean_x!=0) {
a_writer << " weightedMeanX=" << soutd(mean_x);
}
double mean_y = aObject.bin_mean_y(aIndexX,aIndexY,aIndexZ);
if(mean_y!=0) {
a_writer << " weightedMeanY=" << soutd(mean_y);
}
double mean_z = aObject.bin_mean_z(aIndexX,aIndexY,aIndexZ);
if(mean_y!=0) {
a_writer << " weightedMeanZ=" << soutd(mean_z);
}
double stddevX = aObject.bin_rms_x(aIndexX,aIndexY,aIndexZ);
if(stddevX!=0) {
a_writer << " weightedRmsX=" << soutd(stddevX);
}
double stddevY = aObject.bin_rms_y(aIndexX,aIndexY,aIndexZ);
if(stddevY!=0) {
a_writer << " weightedRmsY=" << soutd(stddevY);
}
double stddevZ = aObject.bin_rms_z(aIndexX,aIndexY,aIndexZ);
if(stddevZ!=0) {
a_writer << " weightedRmsZ=" << soutd(stddevZ);
}
a_writer << "/>" << std::endl;
}
}
inline void write_bin(
std::ostream& a_writer
,const histo::p1d& aObject
,const std::string& aSpaces
,int aIndex
){
if(aObject.bin_entries(aIndex)) {
a_writer << aSpaces << " <bin1d"
<< " binNum=" << sout(bin_to_string(aIndex))
<< " entries=" << sout<unsigned int>(aObject.bin_entries(aIndex))
<< " height=" << soutd(aObject.bin_height(aIndex))
<< " error=" << soutd(aObject.bin_error(aIndex))
<< " weightedMean=" << soutd(aObject.bin_mean(aIndex));
double stddev = aObject.bin_rms(aIndex);
if(stddev!=0) {
a_writer << " weightedRms=" << soutd(stddev);
}
a_writer << " rms=" << soutd(aObject.bin_rms_value(aIndex));
a_writer << "/>" << std::endl;
}
}
inline void write_bin(
std::ostream& a_writer
,const histo::p2d& aObject
,const std::string& aSpaces
,int aIndexX
,int aIndexY
){
if(aObject.bin_entries(aIndexX,aIndexY)) {
a_writer << aSpaces << " <bin2d"
<< " binNumX=" << sout(bin_to_string(aIndexX))
<< " binNumY=" << sout(bin_to_string(aIndexY))
<< " entries=" << sout<unsigned int>(aObject.bin_entries(aIndexX,aIndexY))
<< " height=" << soutd(aObject.bin_height(aIndexX,aIndexY))
<< " error=" << soutd(aObject.bin_error(aIndexX,aIndexY))
<< " weightedMeanX=" << soutd(aObject.bin_mean_x(aIndexX,aIndexY))
<< " weightedMeanY=" << soutd(aObject.bin_mean_y(aIndexX,aIndexY));
double stddevX = aObject.bin_rms_x(aIndexX,aIndexY);
if(stddevX!=0) {
a_writer << " weightedRmsX=" << soutd(stddevX);
}
double stddevY = aObject.bin_rms_y(aIndexX,aIndexY);
if(stddevY!=0) {
a_writer << " weightedRmsY=" << soutd(stddevY);
}
a_writer << " rms=" << soutd(aObject.bin_rms_value(aIndexX,aIndexY));
a_writer << "/>" << std::endl;
}
}
inline bool write(
std::ostream& a_writer
,const histo::h1d& aObject
,const std::string& aPath
,const std::string& aName
,int aShift = 0
){
typedef histo::axis<double>::bn_t bn_t;
std::ostream& writer = a_writer;
std::string spaces;
for(int i=0;i<aShift;i++) spaces += " ";
// <histogram1d> :
writer << spaces << " <histogram1d"
<< " path=" << sout(aPath)
<< " name=" << sout(aName)
<< " title=" << sout(aObject.title())
<< ">" << std::endl;
// <annotations> :
write_annotations(aObject.annotations(),writer,aShift);
// <axis> :
write_axis(aObject.axis(),"x",writer,aShift);
// <statistics> :
writer << spaces << " <statistics"
<< " entries=" << sout<unsigned int>(aObject.entries())
<< ">" << std::endl;
writer << spaces << " <statistic"
<< " direction=" << sout("x")
<< " mean=" << soutd(aObject.mean())
<< " rms=" << soutd(aObject.rms())
<< "/>" << std::endl;
writer << spaces << " </statistics>" << std::endl;
// bins :
writer << spaces << " <data1d>" << std::endl;
bn_t xbins = aObject.axis().bins();
for(bn_t index=0;index<xbins;index++)
write_bin(writer,aObject,spaces,index);
write_bin(writer,aObject,spaces,histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,histo::axis<double>::OVERFLOW_BIN);
writer << spaces << " </data1d>" << std::endl;
writer << spaces << " </histogram1d>" << std::endl;
return true;
}
inline bool write(
std::ostream& a_writer
,const histo::h2d& aObject
,const std::string& aPath
,const std::string& aName
,int aShift = 0
){
typedef histo::axis<double>::bn_t bn_t;
std::ostream& writer = a_writer;
std::string spaces;
for(int i=0;i<aShift;i++) spaces += " ";
// <histogram2d> :
writer << spaces << " <histogram2d"
<< " path=" << sout(aPath)
<< " name=" << sout(aName)
<< " title=" << sout(aObject.title())
<< ">" << std::endl;
// <annotations> :
write_annotations(aObject.annotations(),writer,aShift);
// <axis> :
write_axis(aObject.axis_x(),"x",writer,aShift);
write_axis(aObject.axis_y(),"y",writer,aShift);
// <statistics> :
writer << spaces << " <statistics"
<< " entries=" << sout<unsigned int>(aObject.entries())
<< ">" << std::endl;
writer << spaces << " <statistic"
<< " direction=" << sout("x")
<< " mean=" << soutd(aObject.mean_x())
<< " rms=" << soutd(aObject.rms_x())
<< "/>" << std::endl;
writer << spaces << " <statistic"
<< " direction=" << sout("y")
<< " mean=" << soutd(aObject.mean_y())
<< " rms=" << soutd(aObject.rms_y())
<< "/>" << std::endl;
writer << spaces << " </statistics>" << std::endl;
// bins :
writer << spaces << " <data2d>" << std::endl;
bn_t xbins = aObject.axis_x().bins();
bn_t ybins = aObject.axis_y().bins();
bn_t indexX,indexY;
for(indexX=0;indexX<xbins;indexX++) {
for(indexY=0;indexY<ybins;indexY++) {
write_bin(writer,aObject,spaces,indexX,indexY);
}
}
write_bin(writer,aObject,spaces,
histo::axis<double>::UNDERFLOW_BIN,histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::OVERFLOW_BIN,histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::UNDERFLOW_BIN,histo::axis<double>::OVERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::OVERFLOW_BIN,histo::axis<double>::OVERFLOW_BIN);
for(indexX=0;indexX<xbins;indexX++){
write_bin(writer,aObject,spaces,indexX,histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,indexX,histo::axis<double>::OVERFLOW_BIN);
}
for(indexY=0;indexY<ybins;indexY++){
write_bin(writer,aObject,spaces,histo::axis<double>::UNDERFLOW_BIN,indexY);
write_bin(writer,aObject,spaces,histo::axis<double>::OVERFLOW_BIN,indexY);
}
writer << spaces << " </data2d>" << std::endl;
writer << spaces << " </histogram2d>" << std::endl;
return true;
}
inline bool write(
std::ostream& a_writer
,const histo::h3d& aObject
,const std::string& aPath
,const std::string& aName
,int aShift = 0
){
typedef histo::axis<double>::bn_t bn_t;
std::ostream& writer = a_writer;
std::string spaces;
for(int i=0;i<aShift;i++) spaces += " ";
// <histogram3d> :
writer << spaces << " <histogram3d"
<< " path=" << sout(aPath)
<< " name=" << sout(aName)
<< " title=" << sout(aObject.title())
<< ">" << std::endl;
// <annotations> :
write_annotations(aObject.annotations(),writer,aShift);
// <axis> :
write_axis(aObject.axis_x(),"x",writer,aShift);
write_axis(aObject.axis_y(),"y",writer,aShift);
write_axis(aObject.axis_z(),"z",writer,aShift);
// <statistics> :
writer << spaces << " <statistics"
<< " entries=" << sout<unsigned int>(aObject.entries())
<< ">" << std::endl;
writer << spaces << " <statistic"
<< " direction=" << sout("x")
<< " mean=" << soutd(aObject.mean_x())
<< " rms=" << soutd(aObject.rms_x())
<< "/>" << std::endl;
writer << spaces << " <statistic"
<< " direction=" << sout("y")
<< " mean=" << soutd(aObject.mean_y())
<< " rms=" << soutd(aObject.rms_y())
<< "/>" << std::endl;
writer << spaces << " <statistic"
<< " direction=" << sout("z")
<< " mean=" << soutd(aObject.mean_z())
<< " rms=" << soutd(aObject.rms_z())
<< "/>" << std::endl;
writer << spaces << " </statistics>" << std::endl;
// bins :
writer << spaces << " <data3d>" << std::endl;
bn_t xbins = aObject.axis_x().bins();
bn_t ybins = aObject.axis_y().bins();
bn_t zbins = aObject.axis_z().bins();
bn_t indexX,indexY,indexZ;
for(indexX=0;indexX<xbins;indexX++) {
for(indexY=0;indexY<ybins;indexY++) {
for(indexZ=0;indexZ<zbins;indexZ++) {
write_bin(writer,aObject,spaces,indexX,indexY,indexZ);
}
}
}
// Corners :
write_bin(writer,aObject,spaces,
histo::axis<double>::UNDERFLOW_BIN,
histo::axis<double>::UNDERFLOW_BIN,
histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::OVERFLOW_BIN,
histo::axis<double>::UNDERFLOW_BIN,
histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::UNDERFLOW_BIN,
histo::axis<double>::OVERFLOW_BIN,
histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::OVERFLOW_BIN,
histo::axis<double>::OVERFLOW_BIN,
histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::UNDERFLOW_BIN,
histo::axis<double>::UNDERFLOW_BIN,
histo::axis<double>::OVERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::OVERFLOW_BIN,
histo::axis<double>::UNDERFLOW_BIN,
histo::axis<double>::OVERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::UNDERFLOW_BIN,
histo::axis<double>::OVERFLOW_BIN,
histo::axis<double>::OVERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::OVERFLOW_BIN,
histo::axis<double>::OVERFLOW_BIN,
histo::axis<double>::OVERFLOW_BIN);
// Edges :
for(indexX=0;indexX<xbins;indexX++){
write_bin(writer,aObject,spaces,
indexX,
histo::axis<double>::UNDERFLOW_BIN,
histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,
indexX,
histo::axis<double>::OVERFLOW_BIN,
histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,
indexX,
histo::axis<double>::UNDERFLOW_BIN,
histo::axis<double>::OVERFLOW_BIN);
write_bin(writer,aObject,spaces,
indexX,
histo::axis<double>::OVERFLOW_BIN,
histo::axis<double>::OVERFLOW_BIN);
}
for(indexY=0;indexY<ybins;indexY++){
write_bin(writer,aObject,spaces,
histo::axis<double>::UNDERFLOW_BIN,
indexY,
histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::OVERFLOW_BIN,
indexY,
histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::UNDERFLOW_BIN,
indexY,
histo::axis<double>::OVERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::OVERFLOW_BIN,
indexY,
histo::axis<double>::OVERFLOW_BIN);
}
for(indexZ=0;indexZ<zbins;indexZ++){
write_bin(writer,aObject,spaces,
histo::axis<double>::UNDERFLOW_BIN,
histo::axis<double>::UNDERFLOW_BIN,
indexZ);
write_bin(writer,aObject,spaces,
histo::axis<double>::OVERFLOW_BIN,
histo::axis<double>::UNDERFLOW_BIN,
indexZ);
write_bin(writer,aObject,spaces,
histo::axis<double>::UNDERFLOW_BIN,
histo::axis<double>::OVERFLOW_BIN,
indexZ);
write_bin(writer,aObject,spaces,
histo::axis<double>::OVERFLOW_BIN,
histo::axis<double>::OVERFLOW_BIN,
indexZ);
}
// Faces :
for(indexX=0;indexX<xbins;indexX++) {
for(indexY=0;indexY<ybins;indexY++) {
write_bin(writer,aObject,spaces,
indexX,indexY,histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,
indexX,indexY,histo::axis<double>::OVERFLOW_BIN);
}
}
for(indexY=0;indexY<ybins;indexY++) {
for(indexZ=0;indexZ<zbins;indexZ++) {
write_bin(writer,aObject,spaces,
histo::axis<double>::UNDERFLOW_BIN,indexY,indexZ);
write_bin(writer,aObject,spaces,
histo::axis<double>::OVERFLOW_BIN,indexY,indexZ);
}
}
for(indexX=0;indexX<xbins;indexX++) {
for(indexZ=0;indexZ<zbins;indexZ++) {
write_bin(writer,aObject,spaces,
indexX,histo::axis<double>::UNDERFLOW_BIN,indexZ);
write_bin(writer,aObject,spaces,
indexX,histo::axis<double>::OVERFLOW_BIN,indexZ);
}
}
writer << spaces << " </data3d>" << std::endl;
writer << spaces << " </histogram3d>" << std::endl;
return true;
}
inline bool write(
std::ostream& a_writer
,const histo::p1d& aObject
,const std::string& aPath
,const std::string& aName
,int aShift = 0
){
typedef histo::axis<double>::bn_t bn_t;
std::ostream& writer = a_writer;
std::string spaces;
for(int i=0;i<aShift;i++) spaces += " ";
// <profile1d> :
writer << spaces << " <profile1d"
<< " path=" << sout(aPath)
<< " name=" << sout(aName)
<< " title=" << sout(aObject.title())
<< ">" << std::endl;
// <annotations> :
write_annotations(aObject.annotations(),writer,aShift);
// <axis> :
write_axis(aObject.axis(),"x",writer,aShift);
// <statistics> :
writer << spaces << " <statistics"
<< " entries=" << sout<unsigned int>(aObject.entries())
<< ">" << std::endl;
writer << spaces << " <statistic"
<< " direction=" << sout("x")
<< " mean=" << soutd(aObject.mean())
<< " rms=" << soutd(aObject.rms())
<< "/>" << std::endl;
writer << spaces << " </statistics>" << std::endl;
// bins :
writer << spaces << " <data1d>" << std::endl;
bn_t xbins = aObject.axis().bins();
for(bn_t index=0;index<xbins;index++) {
write_bin(writer,aObject,spaces,index);
}
write_bin(writer,aObject,spaces,histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,histo::axis<double>::OVERFLOW_BIN);
writer << spaces << " </data1d>" << std::endl;
writer << spaces << " </profile1d>" << std::endl;
return true;
}
inline bool write(
std::ostream& a_writer
,const histo::p2d& aObject
,const std::string& aPath
,const std::string& aName
,int aShift = 0
){
typedef histo::axis<double>::bn_t bn_t;
std::ostream& writer = a_writer;
std::string spaces;
for(int i=0;i<aShift;i++) spaces += " ";
// <profile2d> :
writer << spaces << " <profile2d"
<< " path=" << sout(aPath)
<< " name=" << sout(aName)
<< " title=" << sout(aObject.title())
<< ">" << std::endl;
// <annotations> :
write_annotations(aObject.annotations(),writer,aShift);
// <axis> :
write_axis(aObject.axis_x(),"x",writer,aShift);
write_axis(aObject.axis_y(),"y",writer,aShift);
// <statistics> :
writer << spaces << " <statistics"
<< " entries=" << sout<unsigned int>(aObject.entries())
<< ">" << std::endl;
writer << spaces << " <statistic"
<< " direction=" << sout("x")
<< " mean=" << soutd(aObject.mean_x())
<< " rms=" << soutd(aObject.rms_x())
<< "/>" << std::endl;
writer << spaces << " <statistic"
<< " direction=" << sout("y")
<< " mean=" << soutd(aObject.mean_y())
<< " rms=" << soutd(aObject.rms_y())
<< "/>" << std::endl;
writer << spaces << " </statistics>" << std::endl;
// bins :
writer << spaces << " <data2d>" << std::endl;
{bn_t xbins = aObject.axis_x().bins();
bn_t ybins = aObject.axis_y().bins();
for(bn_t indexX=0;indexX<xbins;indexX++) {
for(bn_t indexY=0;indexY<ybins;indexY++) {
write_bin(writer,aObject,spaces,indexX,indexY);
}
}}
write_bin(writer,aObject,spaces,
histo::axis<double>::UNDERFLOW_BIN,histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::OVERFLOW_BIN,histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::UNDERFLOW_BIN,histo::axis<double>::OVERFLOW_BIN);
write_bin(writer,aObject,spaces,
histo::axis<double>::OVERFLOW_BIN,histo::axis<double>::OVERFLOW_BIN);
for(bn_t indexX=0;indexX<aObject.axis_x().bins();indexX++){
write_bin(writer,aObject,spaces,indexX,histo::axis<double>::UNDERFLOW_BIN);
write_bin(writer,aObject,spaces,indexX,histo::axis<double>::OVERFLOW_BIN);
}
for(bn_t indexY=0;indexY<aObject.axis_y().bins();indexY++){
write_bin(writer,aObject,spaces,histo::axis<double>::UNDERFLOW_BIN,indexY);
write_bin(writer,aObject,spaces,histo::axis<double>::OVERFLOW_BIN,indexY);
}
writer << spaces << " </data2d>" << std::endl;
writer << spaces << " </profile2d>" << std::endl;
return true;
}
}}
#endif
@@ -0,0 +1,363 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_waxml_ntuple
#define tools_waxml_ntuple
// A ntuple class to write at the aida tuple format.
// Each add_row() write a row at the aida tuple format.
#include "../vfind"
#include "../vmanip"
#include "../sout"
#include "../tos"
#include <ostream>
// for sub_ntuple :
#include "../scast"
#include <sstream>
#include "../ntuple_booking"
namespace tools {
namespace waxml {
class ntuple {
protected:
class iobj {
public:
virtual ~iobj(){}
public:
virtual void* cast(cid) const = 0;
virtual const std::string& name() const = 0;
virtual std::string aida_type() const = 0;
};
class leaf : public virtual iobj {
public:
static cid id_class() {return 100;}
public: //iobj
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<leaf>(this,a_class)) {return p;}
return 0;
}
public:
virtual std::string s_def() const = 0;
virtual std::string s_value() const = 0;
public:
leaf(){}
virtual ~leaf(){}
leaf(const leaf& a_from):iobj(a_from){}
leaf& operator=(const leaf&){return *this;}
};
static const std::string& s_aida_type(int) {
static const std::string s_v("int");
return s_v;
}
static const std::string& s_aida_type(float) {
static const std::string s_v("float");
return s_v;
}
static const std::string& s_aida_type(double) {
static const std::string s_v("double");
return s_v;
}
public:
template <class T>
class column : public leaf {
public:
static cid id_class() {return 200+_cid(T());}
public: //iobj
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast< column<T> >(this,a_class)) {return p;}
return leaf::cast(a_class);
}
virtual const std::string& name() const {return m_name;}
virtual std::string aida_type() const {return s_aida_type(T());}
public: //leaf
virtual std::string s_def() const {return tos(m_def);}
virtual std::string s_value() const {return tos(m_tmp);}
public:
column(const std::string& a_name,const T& a_def)
:m_name(a_name),m_def(a_def),m_tmp(a_def)
{}
virtual ~column(){}
protected:
column(const column& a_from)
:leaf(a_from)
,m_name(a_from.m_name)
,m_def(a_from.m_def)
,m_tmp(a_from.m_tmp)
{}
column& operator=(const column& a_from){
m_name = a_from.m_name;
m_def = a_from.m_def;
m_tmp = a_from.m_tmp;
return *this;
}
public:
bool fill(const T& a_value) {m_tmp = a_value;return true;}
protected:
std::string m_name;
T m_def;
T m_tmp;
};
class sub_ntuple : public virtual iobj {
public:
static cid id_class() {return 300;}
public: //iobj
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<sub_ntuple>(this,a_class)) {return p;}
return 0;
}
virtual const std::string& name() const {return m_name;}
virtual std::string aida_type() const {return "ITuple";}
public:
sub_ntuple(const std::string& a_name,
const std::string& a_spaces)
:m_name(a_name),m_spaces(a_spaces){}
virtual ~sub_ntuple(){}
protected:
sub_ntuple(const sub_ntuple& a_from)
:iobj(a_from),m_name(a_from.m_name){}
sub_ntuple& operator=(const sub_ntuple&){return *this;}
public:
template <class T>
column<T>* create_column(const std::string& a_name,
const T& a_def = T()) {
if(find_named<iobj>(m_cols,a_name)) return 0;
column<T>* col = new column<T>(a_name,a_def);
if(!col) return 0;
m_cols.push_back(col);
return col;
}
sub_ntuple* create_sub_ntuple(const std::string& a_name){
if(find_named<iobj>(m_cols,a_name)) return 0;
std::string spaces;
for(unsigned int i=0;i<4;i++) spaces += " ";
sub_ntuple* col = new sub_ntuple(a_name,m_spaces+spaces);
if(!col) return 0;
m_cols.push_back(col);
return col;
}
const std::vector<iobj*>& columns() const {return m_cols;}
std::string booking() const {
std::string s;
get_booking(m_cols,s);
return s;
}
void reset() {m_tmp.clear();}
const std::string& value() const {return m_tmp;}
bool add_row() {
if(m_cols.empty()) return false;
std::ostringstream sout;
sout << m_spaces << "<row>" << std::endl;
std::vector<iobj*>::const_iterator it;
for(it=m_cols.begin();it!=m_cols.end();++it) {
if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))) {
sout << m_spaces << " <entryITuple>" << std::endl;
sout << sub->value();
sout << m_spaces << " </entryITuple>" << std::endl;
sub->reset();
} else if(leaf* lf = id_cast<iobj,leaf>(*(*it))){
sout << m_spaces << " <entry"
<< " value=\"" << lf->s_value().c_str()
<< "\"/>" << std::endl;
}
}
sout << m_spaces << "</row>" << std::endl;
m_tmp += sout.str();
return true;
}
protected:
std::string m_name;
std::string m_spaces;
std::vector<iobj*> m_cols;
std::string m_tmp;
};
public:
ntuple(std::ostream& a_writer,unsigned int a_spaces = 0)
:m_writer(a_writer){
for(unsigned int i=0;i<a_spaces;i++) m_spaces += " ";
}
ntuple(std::ostream& a_writer,
std::ostream& a_out,
const ntuple_booking& a_bkg,
unsigned int a_spaces = 0)
:m_writer(a_writer){
for(unsigned int i=0;i<a_spaces;i++) m_spaces += " ";
const std::vector<ntuple_booking::col_t>& cols = a_bkg.m_columns;
std::vector<ntuple_booking::col_t>::const_iterator it;
for(it=cols.begin();it!=cols.end();++it){
if((*it).second==_cid(int(0))) {
create_column<int>((*it).first);
} else if((*it).second==_cid(float(0))) {
create_column<float>((*it).first);
} else if((*it).second==_cid(double(0))) {
create_column<double>((*it).first);
} else {
a_out << "tools::waxml::ntuple :"
<< " for column " << sout((*it).first)
<< ", type with cid " << (*it).second << " not yet handled."
<< std::endl;
//throw
tools::clear<iobj>(m_cols);
return;
}
}
}
virtual ~ntuple() {
tools::clear<iobj>(m_cols);
}
protected:
ntuple(const ntuple& a_from)
:m_writer(a_from.m_writer)
,m_spaces(a_from.m_spaces)
{}
ntuple& operator=(const ntuple& a_from){
m_spaces = a_from.m_spaces;
return *this;
}
public:
const std::vector<iobj*>& columns() const {return m_cols;}
template <class T>
column<T>* create_column(const std::string& a_name,const T& a_def = T()) {
if(find_named<iobj>(m_cols,a_name)) return 0;
column<T>* col = new column<T>(a_name,a_def);
if(!col) return 0;
m_cols.push_back(col);
return col;
}
template <class T>
column<T>* find_column(const std::string& a_name) {
iobj* col = find_named<iobj>(m_cols,a_name);
if(!col) return 0;
return id_cast<iobj, column<T> >(*col);
}
sub_ntuple* create_sub_ntuple(const std::string& a_name){
if(find_named<iobj>(m_cols,a_name)) return 0;
std::string spaces;
for(unsigned int i=0;i<10;i++) spaces += " ";
sub_ntuple* col = new sub_ntuple(a_name,m_spaces+spaces);
if(!col) return 0;
m_cols.push_back(col);
return col;
}
void write_header(const std::string& a_path,
const std::string& a_name,
const std::string& a_title){
// <tuple> :
m_writer << m_spaces << " <tuple"
<< " path=" << sout(a_path)
<< " name=" << sout(a_name)
<< " title=" << sout(a_title)
<< ">" << std::endl;
// <columns> :
m_writer << m_spaces << " <columns>" << std::endl;
std::vector<iobj*>::iterator it;
for(it=m_cols.begin();it!=m_cols.end();++it) {
if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))){
m_writer << m_spaces << " <column"
<< " name=" << sout((*it)->name())
<< " type=" << sout("ITuple")
<< " booking=" << sout(sub->booking())
<< "/>" << std::endl;
} else if(/*leaf* lf =*/ id_cast<iobj,leaf>(*(*it))){
m_writer << m_spaces << " <column"
<< " name=" << sout((*it)->name())
<< " type=" << sout((*it)->aida_type())
//<< " default=" << sout(lf->s_def()) //not understood by jas3
<< "/>" << std::endl;
}
}
m_writer << m_spaces << " </columns>" << std::endl;
// rows :
m_writer << m_spaces << " <rows>" << std::endl;
}
bool add_row() {
if(m_cols.empty()) return false;
m_writer << m_spaces << " <row>" << std::endl;
std::vector<iobj*>::const_iterator it;
for(it=m_cols.begin();it!=m_cols.end();++it) {
if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))){
m_writer << m_spaces << " <entryITuple>" << std::endl;
m_writer << sub->value();
m_writer << m_spaces << " </entryITuple>" << std::endl;
sub->reset();
} else if(leaf* lf = id_cast<iobj,leaf>(*(*it))){
m_writer << m_spaces << " <entry"
<< " value=" << sout(lf->s_value())
<< "/>" << std::endl;
}
}
m_writer << m_spaces << " </row>" << std::endl;
return true;
}
void write_trailer() {
m_writer << m_spaces << " </rows>" << std::endl;
m_writer << m_spaces << " </tuple>" << std::endl;
}
protected:
static void get_booking(const std::vector<iobj*>& a_cols,
std::string& a_string) {
a_string += "{"; //we need the + because of the tuple in tuple.
std::vector<iobj*>::const_iterator it;
for(it=a_cols.begin();it!=a_cols.end();++it) {
if(it!=a_cols.begin()) a_string += ",";
std::string type = (*it)->aida_type();
a_string += type + " ";
std::string name = (*it)->name();
a_string += name + " = ";
if(sub_ntuple* sub = id_cast<iobj,sub_ntuple>(*(*it))){
get_booking(sub->columns(),a_string);
} else if(leaf* lf = id_cast<iobj,leaf>(*(*it))){
a_string += lf->s_def();
}
}
a_string += "}";
}
protected:
std::ostream& m_writer;
std::string m_path;
std::string m_name;
std::string m_title;
std::string m_spaces;
std::vector<iobj*> m_cols;
};
}}
#endif
@@ -0,0 +1,186 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wcsv_ntuple
#define tools_wcsv_ntuple
// A simple ntuple class to write at the csv format.
// (csv = comma separated value).
// Each add_row() write a row at the csv format.
#include "vfind"
#include "vmanip"
#include <ostream>
#include "scast"
#include "ntuple_booking"
#include "sout"
namespace tools {
namespace wcsv {
class ntuple {
protected:
class icol {
public:
virtual ~icol(){}
public:
virtual void* cast(cid) const = 0;
virtual cid id_cls() const = 0;
public:
virtual void add() = 0;
virtual const std::string& name() const = 0;
};
public:
template <class T>
class column : public virtual icol {
public:
static cid id_class() {
static const T s_v = T(); //do that for T = std::string.
return _cid(s_v);
}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<column>(this,a_class)) {return p;}
else return 0;
}
virtual cid id_cls() const {return id_class();}
public: //icol
virtual void add() {
m_writer << m_tmp;
m_tmp = m_def;
}
virtual const std::string& name() const {return m_name;}
public:
column(std::ostream& a_writer,const std::string& a_name,const T& a_def)
:m_writer(a_writer)
,m_name(a_name),m_def(a_def),m_tmp(a_def)
{}
virtual ~column(){}
protected:
column(const column& a_from)
:icol(a_from)
,m_writer(a_from.m_writer)
,m_name(a_from.m_name)
,m_def(a_from.m_def)
,m_tmp(a_from.m_tmp)
{}
column& operator=(const column& a_from){
m_name = a_from.m_name;
m_def = a_from.m_def;
m_tmp = a_from.m_tmp;
return *this;
}
public:
bool fill(const T& a_value) {m_tmp = a_value;return true;}
protected:
std::ostream& m_writer;
std::string m_name;
T m_def;
T m_tmp;
};
public:
ntuple(std::ostream& a_writer,char a_sep = ',')
:m_writer(a_writer)
,m_sep(a_sep)
{}
ntuple(std::ostream& a_writer,
std::ostream& a_out, //for errors.
const ntuple_booking& a_bkg,
char a_sep = ',')
:m_writer(a_writer)
,m_sep(a_sep){
const std::vector<ntuple_booking::col_t>& cols = a_bkg.m_columns;
std::vector<ntuple_booking::col_t>::const_iterator it;
for(it=cols.begin();it!=cols.end();++it){
if((*it).second==_cid(char(0))) {
create_column<char>((*it).first);
} else if((*it).second==_cid(short(0))) {
create_column<short>((*it).first);
} else if((*it).second==_cid(int(0))) {
create_column<int>((*it).first);
} else if((*it).second==_cid(float(0))) {
create_column<float>((*it).first);
} else if((*it).second==_cid(double(0))) {
create_column<double>((*it).first);
} else if((*it).second==_cid(byte(0))) {
create_column<byte>((*it).first);
} else if((*it).second==_cid((unsigned short)0)) {
create_column<unsigned short>((*it).first);
} else if((*it).second==_cid((unsigned int)0)) {
create_column<unsigned int>((*it).first);
} else if((*it).second==_cid(bool(true))) {
create_column<bool>((*it).first);
} else if((*it).second==_cid(uint64(0))) {
create_column<uint64>((*it).first);
} else {
a_out << "tools::wcsv::ntuple :"
<< " for column " << sout((*it).first)
<< ", type with cid " << (*it).second << " not yet handled."
<< std::endl;
//throw
tools::clear<icol>(m_cols);
return;
}
}
}
virtual ~ntuple() {
tools::clear<icol>(m_cols);
}
protected:
ntuple(const ntuple& a_from)
:m_writer(a_from.m_writer)
,m_sep(a_from.m_sep)
{}
ntuple& operator=(const ntuple& a_from){
m_sep = a_from.m_sep;
return *this;
}
public:
template <class T>
column<T>* create_column(const std::string& a_name,const T& a_def = T()) {
if(find_named<icol>(m_cols,a_name)) return 0;
column<T>* col = new column<T>(m_writer,a_name,a_def);
if(!col) return 0;
m_cols.push_back(col);
return col;
}
template <class T>
column<T>* find_column(const std::string& a_name) {
icol* col = find_named<icol>(m_cols,a_name);
if(!col) return 0;
return id_cast<icol, column<T> >(*col);
}
bool add_row() {
if(m_cols.empty()) return false;
std::vector<icol*>::iterator it;
it=m_cols.begin();
(*it)->add();
it++;
for(;it!=m_cols.end();++it) {
m_writer << m_sep;
(*it)->add();
}
m_writer << std::endl;
return true;
}
const std::vector<icol*>& columns() const {return m_cols;}
protected:
std::ostream& m_writer;
char m_sep;
std::vector<icol*> m_cols;
};
}}
#endif
@@ -0,0 +1,93 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_words
#define tools_words
#include <string>
#include <vector>
namespace tools {
inline void words(const std::string& a_string,const std::string& a_sep,bool a_take_empty,std::vector<std::string>& a_words){
// If a_sep is for exa "|" and for "xxx||xxx" :
// - a_take_empty false : {"xxx","xxx"} will be created
// (and NOT {"xxx","","xxx"}).
// - a_take_empty true : {"xxx","","xxx"} will be created.
a_words.clear();
if(a_string.empty()) return;
std::string::size_type lim = (a_take_empty?0:1);
if(a_sep.empty()) {
a_words.push_back(a_string);
} else {
std::string::size_type l = a_string.length();
std::string::size_type llimiter = a_sep.length();
std::string::size_type pos = 0;
while(true) {
std::string::size_type index = a_string.find(a_sep,pos);
if(index==std::string::npos){ // Last word.
if((l-pos)>=lim) a_words.push_back(a_string.substr(pos,l-pos));
break;
} else {
// abcxxxef
// 0 3 67
if((index-pos)>=lim) a_words.push_back(a_string.substr(pos,index-pos));
pos = index + llimiter;
}
}
}
}
inline std::vector<std::string> words(const std::string& a_string,const std::string& a_limiter,bool a_take_empty = false){
std::vector<std::string> v;
words(a_string,a_limiter,a_take_empty,v);
return v;
}
inline void words(const std::string& a_string,
const std::string& a_sep,bool a_take_empty,
//output :
unsigned int& a_wn,
std::string::size_type* a_wps,
std::string::size_type* a_wls){
//used to optimize inlib::match().
a_wn = 0;
if(a_string.empty()) return;
std::string::size_type lim = (a_take_empty?0:1);
if(a_sep.empty()) {
//a_words.push_back(a_string);
a_wps[a_wn] = 0;
a_wls[a_wn] = a_string.length();
a_wn++;
} else {
std::string::size_type l = a_string.length();
std::string::size_type llimiter = a_sep.length();
std::string::size_type pos = 0;
while(true) {
std::string::size_type index = a_string.find(a_sep,pos);
if(index==std::string::npos){ // Last word.
if((l-pos)>=lim) {
//a_words.push_back(a_string.substr(pos,l-pos));
a_wps[a_wn] = pos;
a_wls[a_wn] = l-pos;
a_wn++;
}
break;
} else {
// abcxxxef
// 0 3 67
if((index-pos)>=lim) {
//a_words.push_back(a_string.substr(pos,index-pos));
a_wps[a_wn] = pos;
a_wls[a_wn] = index-pos;
a_wn++;
}
pos = index + llimiter;
}
}
}
}
}
#endif
@@ -0,0 +1,97 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_base_leaf
#define tools_wroot_base_leaf
#ifdef TOOLS_MEM
#include "../mem"
#endif
#include "named"
namespace tools {
namespace wroot {
class branch;
}}
namespace tools {
namespace wroot {
class base_leaf : public virtual ibo {
static unsigned int kNullTag() {return 0;}
#ifdef TOOLS_MEM
public:
static const std::string& s_class() {
static const std::string s_v("tools::wroot::base_leaf");
return s_v;
}
#endif
public: //ibo
virtual bool stream(buffer& a_buffer) const {
unsigned int c;
if(!a_buffer.write_version(2,c)) return false;
if(!Named_stream(a_buffer,m_name,m_title)) return false;
if(!a_buffer.write(m_length)) return false;
if(!a_buffer.write(m_length_type)) return false;
uint32 fOffset = 0;
if(!a_buffer.write(fOffset)) return false;
bool fIsRange = false;
if(!a_buffer.write(fIsRange)) return false;
bool fIsUnsigned = false;
if(!a_buffer.write(fIsUnsigned)) return false;
//if(!a_buffer.write_object(m_leaf_count)) return false;
if(!a_buffer.write(kNullTag())) return false;
if(!a_buffer.set_byte_count(c)) return false;
return true;
}
public:
virtual bool fill_basket(buffer&) const = 0;
public:
base_leaf(std::ostream& a_out,
wroot::branch& a_branch,
const std::string& a_name,
const std::string& a_title)
:m_out(a_out)
,m_branch(a_branch)
,m_name(a_name)
,m_title(a_title)
,m_length(0)
,m_length_type(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~base_leaf(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
base_leaf(const base_leaf& a_from)
: ibo(a_from)
,m_out(a_from.m_out)
,m_branch(a_from.m_branch)
{}
base_leaf& operator=(const base_leaf&){return *this;}
public:
wroot::branch& branch() {return m_branch;}
const std::string& name() const {return m_name;}
//const std::string& title() const {return m_title;}
protected:
std::ostream& m_out;
wroot::branch& m_branch;
protected: //Named
std::string m_name;
std::string m_title;
uint32 m_length; // Number of fixed length elements
uint32 m_length_type; // Number of bytes for this data type
};
}}
#endif
@@ -0,0 +1,359 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_basket
#define tools_wroot_basket
#include "ibo"
#include "key"
#include "buffer"
namespace tools {
namespace wroot {
class basket : public virtual ibo, public key {
static uint32 START_BIG_FILE() {return 2000000000;}
public:
static const std::string& s_class() {
static const std::string s_v("tools::wroot::basket");
return s_v;
}
public: //ibo
virtual const std::string& store_cls() const {
static const std::string s_v("TBasket");
return s_v;
}
virtual bool stream(buffer& a_buffer) const {
// in principle we pass here only for the last basket
// of a branch when it is streamed from branch::stream().
// some consitency checks :
//G.Barrand : the below test is "too much". Someone
// may have to write a tree (and then a basket)
// which had been never filled.
// Moreover with the today branch code, a
// basket.write_on_file()
// happens only in a branch.fill() that deletes
// the basket just after the call.
//if(!m_data.length()) {
// // to be sure to not work on a basket already written
// // with write_on_file()
// m_file.out() << "tools::wroot::basket::stream :"
// << " m_data.length() is null."
// << std::endl;
// return false;
//}
if(m_seek_key) {
m_file.out() << "tools::wroot::basket::stream :"
<< " m_seek_key is not null."
<< std::endl;
return false;
}
if(m_last) {
m_file.out() << "tools::wroot::basket::stream :"
<< " m_last is not null."
<< std::endl;
return false;
}
if(!m_entry_offset) {
m_file.out() << "tools::wroot::basket::stream :"
<< " m_entry_offset is null."
<< std::endl;
return false;
}
{uint32 last = m_data.length()+m_key_length;
if(last>m_last) {
const_cast<basket&>(*this).m_last = last;
}}
if(m_last>m_buf_size) {
const_cast<basket&>(*this).m_buf_size = m_last;
}
char flag = 11;
if(m_displacement) flag += 40;
if(!_stream_header(a_buffer,flag)) return false;
if(m_entry_offset && m_nev) {
if(!a_buffer.write_array(m_entry_offset,m_nev)) return false;
if(m_displacement) {
if(!a_buffer.write_array(m_displacement,m_nev)) return false;
}
}
if(m_data.to_displace()) {
//NOTE : how / when handle the displacements ?
m_file.out() << "tools::wroot::basket::stream :"
<< " WARNING : m_data buffer has offsets to displace."
<< std::endl;
//if(!const_cast<basket&>(*this).m_data.displace_mapped(m_key_length))
// return false; //???
}
buffer bref(m_file.out(),m_file.byte_swap(),256);
if(!_stream_header(bref)) return false; //then header stored twice !
//if(bref.length()!=m_key_length) {}
if(!bref.write_fast_array(m_data.buf(),m_data.length())) return false;
if(!a_buffer.write_fast_array(bref.buf(),bref.length())) return false;
return true;
}
public:
basket(ifile& a_file,
seek a_seek_parent_dir,
const std::string& a_object_name,
const std::string& a_object_title,
const std::string& a_object_class,
uint32 a_basket_size)
:key(a_file,a_seek_parent_dir,
a_object_name,a_object_title,a_object_class,0)
,m_data(a_file.out(),a_file.byte_swap(),a_basket_size)
,m_nev_buf_size(1000)
,m_nev(0)
,m_last(0)
,m_entry_offset(0)
,m_displacement(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_key_length = header_record_size(m_version);
initialize(0);
if(m_nev_buf_size) m_entry_offset = new uint32[m_nev_buf_size];
}
virtual ~basket(){
delete [] m_entry_offset;
delete [] m_displacement;
m_entry_offset = 0;
m_displacement = 0;
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
basket(const basket& a_from)
:ibo(a_from)
,key(a_from)
,m_data(m_file.out(),m_file.byte_swap(),256)
,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
}
basket& operator=(const basket& a_from){
key::operator=(a_from);
m_nev_buf_size = a_from.m_nev_buf_size;
m_nev = a_from.m_nev;
m_last = a_from.m_last;
return *this;
}
public:
buffer& datbuf() {return m_data;}
bool update(uint32 a_offset) {
if(m_entry_offset) {
if((m_nev+1)>=m_nev_buf_size) { //why +1 ?
uint32 newsize = mx<uint32>(10,2*m_nev_buf_size);
if(!realloc<uint32>(m_entry_offset,newsize,m_nev_buf_size,true)){
m_file.out() << "tools::wroot::basket::update : realloc failed."
<< std::endl;
return false;
}
if(m_displacement) {
if(!realloc<int>(m_displacement,newsize,m_nev_buf_size,true)){
m_file.out() << "tools::wroot::basket::update : realloc failed."
<< std::endl;
return false;
}
}
m_nev_buf_size = newsize;
// Update branch only for the first 10 baskets
//if (fBranch.writeBasket() < 10)
// fBranch.setEntryOffsetLength(newsize);
}
m_entry_offset[m_nev] = a_offset;
//if (skipped!=offset && !m_displacement){
// m_displacement = new int[m_nevSize];
// for(int i=0;i<m_nev_buf_size;i++)
// m_displacement[i] = m_entry_offset[i];
//}
//if (m_displacement) {
// m_displacement[m_nev] = skipped;
// fBufferRef->setDisplacement(skipped);
//}
}
m_nev++;
return true;
}
bool write_on_file(uint16 a_cycle,uint32& a_nbytes) {
// write m_data buffer into file.
//NOTE : m_data does not contain the key at its head.
// At this point m_seek_key should be 0.
a_nbytes = 0;
if(m_seek_key) {
m_file.out() << "tools::wroot::basket::write_on_file :"
<< " m_seek_key should be 0."
<< std::endl;
return false;
}
if(m_version>1000) {
} else {
if(m_file.END()>START_BIG_FILE()) {
//GB : enforce m_version>1000 if m_version is still 2 but
// seek_key>START_BIG_FILE. If not doing that we shall
// write a big m_seek_key on a seek32 and then have
// a problem when reading.
//m_file.out() << "tools::wroot::basket::write_on_file : "
// << " WARNING : pos>START_BIG_FILE."
// << std::endl;
m_version += 1000;
m_key_length += 8;
if(m_entry_offset) {
for(uint32 i=0;i<m_nev;i++) m_entry_offset[i] += 8;
if(m_displacement) {
//??? Do we have to shift them ?
m_file.out() << "tools::wroot::basket::write_on_file : "
<< " displace logic : m_displacement not null."
<< std::endl;
}
}
}
}
// Transfer m_entry_offset table at the end of fBuffer. Offsets to fBuffer
// are transformed in entry length to optimize compression algorithm.
m_last = m_key_length+m_data.length();
if(m_entry_offset) {
if(!m_data.write_array<uint32>(m_entry_offset,m_nev+1)) { //GB : why +1 ?
delete [] m_entry_offset;
m_entry_offset = 0;
return false;
}
delete [] m_entry_offset;
m_entry_offset = 0;
if(m_displacement) {
if(!m_data.write_array<int>(m_displacement,m_nev+1)) {
delete [] m_displacement;
m_displacement = 0;
return false;
}
delete [] m_displacement;
m_displacement = 0;
}
}
m_object_size = m_data.length(); //uncompressed size.
m_cycle = a_cycle;
if(!m_data.displace_mapped(m_key_length)) return false;
char* kbuf = 0;
uint32 klen = 0;
bool kdelete = false;
m_file.compress_buffer(m_data,kbuf,klen,kdelete);
if(klen>m_object_size) {
m_file.out() << "tools::wroot::basket::write_on_file :"
<< " compression anomaly "
<< " m_object_size " << m_object_size
<< " klen " << klen
<< std::endl;
if(kdelete) delete [] kbuf;
return false;
}
if(!initialize(klen)) { //it will do a file.set_END()
m_file.out() << "tools::wroot::basket::write_on_file :"
<< " initialize() failed."
<< std::endl;
if(kdelete) delete [] kbuf;
return false;
}
//write header of the key :
{buffer bref(m_file.out(),m_file.byte_swap(),256);
if(!_stream_header(bref)) return false;
if(bref.length()!=m_key_length) {
m_file.out() << "tools::wroot::basket::write_on_file :"
<< " key len anomaly " << bref.length()
<< " m_key_length " << m_key_length
<< std::endl;
if(kdelete) delete [] kbuf;
return false;
}
::memcpy(m_buffer,bref.buf(),m_key_length);}
::memcpy(m_buffer+m_key_length,kbuf,klen);
if(kdelete) delete [] kbuf;
uint32 nbytes;
if(!key::write_file(nbytes)) return false;
m_data.pos() = m_data.buf(); //empty m_data.
a_nbytes = m_key_length + klen;
return true;
}
protected:
uint32 header_record_size(uint32 a_version) const {
// header only.
uint32 nbytes = key::record_size(a_version);
nbytes += sizeof(short); //version
nbytes += sizeof(uint32); //m_buf_size
nbytes += sizeof(uint32); //m_nev_buf_size
nbytes += sizeof(uint32); //m_nev
nbytes += sizeof(uint32); //m_last
nbytes += sizeof(char); //flag
return nbytes;
}
bool _stream_header(buffer& a_buffer,char a_flag = 0) const {
{uint32 l = key::record_size(m_version);
if((a_buffer.length()+l)>a_buffer.size()) {
if(!a_buffer.expand(a_buffer.size()+l)) return false;
}
wbuf wb(m_file.out(),m_file.byte_swap(),a_buffer.max_pos(),a_buffer.pos());
if(!key::to_buffer(wb)) return false;}
if(!a_buffer.write_version(2)) return false;
if(!a_buffer.write(m_buf_size)) return false;
if(!a_buffer.write(m_nev_buf_size)) return false;
if(!a_buffer.write(m_nev)) return false;
if(!a_buffer.write(m_last)) return false;
if(!a_buffer.write(a_flag)) return false;
return true;
}
protected:
buffer m_data;
protected:
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
uint32* 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,306 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_branch
#define tools_wroot_branch
#include "leaf"
#include "basket"
#include "itree"
#include "idir"
namespace tools {
namespace wroot {
class branch : public virtual ibo {
static uint32 START_BIG_FILE() {return 2000000000;}
//static uint32 kDoNotProcess() {return (1<<10);} // Active bit for branches
#ifdef TOOLS_MEM
static const std::string& s_class() {
static const std::string s_v("tools::wroot::branch");
return s_v;
}
#endif
public: //ibo
virtual const std::string& store_cls() const {
static const std::string s_v("TBranch");
return s_v;
}
virtual bool stream(buffer& a_buffer) const {
unsigned int c;
if(!a_buffer.write_version(8,c)) return false;
if(!Named_stream(a_buffer,m_name,m_title)) return false;
if(!AttFill_stream(a_buffer)) return false;
int fCompress = m_tree.dir().file().compression();
int fEntryOffsetLen = 1000;
int fOffset = 0;
int fSplitLevel = 0;
if(!a_buffer.write(fCompress)) return false;
if(!a_buffer.write(m_basket_size)) return false;
if(!a_buffer.write(fEntryOffsetLen)) return false;
if(!a_buffer.write(m_write_basket)) return false;
int fEntryNumber = (int)m_entry_number;
if(!a_buffer.write(fEntryNumber)) return false;
if(!a_buffer.write(fOffset)) return false;
if(!a_buffer.write(m_max_baskets)) return false;
if(!a_buffer.write(fSplitLevel)) return false;
double fEntries = (double)m_entries;
if(!a_buffer.write(fEntries)) return false;
double fTotBytes = (double)m_tot_bytes;
double fZipBytes = (double)m_zip_bytes;
if(!a_buffer.write(fTotBytes)) return false;
if(!a_buffer.write(fZipBytes)) return false;
if(!m_branches.stream(a_buffer)) return false;
if(!m_leaves.stream(a_buffer)) return false;
if(!m_baskets.stream(a_buffer)) return false;
// See TStreamerInfo::ReadBuffer::WriteBasicPointer
if(!a_buffer.write((char)1)) return false;
if(!a_buffer.write_fast_array(fBasketBytes,m_max_baskets)) return false;
if(!a_buffer.write((char)1)) return false;
if(!a_buffer.write_fast_array(fBasketEntry,m_max_baskets)) return false;
char isBigFile = 1;
//GB : begin
//if(fTree.directory().file().end()>RIO_START_BIG_FILE()) isBigFile = 2;
{for(uint32 i=0;i<m_max_baskets;i++) {
if(fBasketSeek[i]>START_BIG_FILE()) {
isBigFile = 2;
break;
}
}}
//GB : end
if(!a_buffer.write(isBigFile)) return false;
if(isBigFile==2) {
if(!a_buffer.write_fast_array(fBasketSeek,m_max_baskets)) return false;
} else {
for(uint32 i=0;i<m_max_baskets;i++) {
if(fBasketSeek[i]>START_BIG_FILE()) { //G.Barrand : add this test.
m_out << "tools::wroot::branch::stream :"
<< " attempt to write big Seek "
<< fBasketSeek[i] << " on 32 bits."
<< std::endl;
return false;
}
if(!a_buffer.write((seek32)fBasketSeek[i])) return false;
}
}
// fFileName
if(!a_buffer.write(std::string(""))) return false;
if(!a_buffer.set_byte_count(c)) return false;
return true;
}
public:
branch(itree& a_tree,
const std::string& a_name,
const std::string& a_title)
:m_tree(a_tree)
,m_out(a_tree.dir().file().out())
,m_name(a_name)
,m_title(a_title)
,fAutoDelete(false)
//,m_branches(true)
//,m_leaves(true)
,m_basket_size(32000)
,m_write_basket(0)
,m_entry_number(0)
,m_entries(0)
,m_tot_bytes(0)
,m_zip_bytes(0)
,m_max_baskets(10)
,fBasketBytes(0)
,fBasketEntry(0)
,fBasketSeek(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
fBasketBytes = new uint32[m_max_baskets];
fBasketEntry = new uint32[m_max_baskets];
fBasketSeek = new seek[m_max_baskets];
{for(uint32 i=0;i<m_max_baskets;i++) {
fBasketBytes[i] = 0;
fBasketEntry[i] = 0;
fBasketSeek[i] = 0;
}}
m_baskets.push_back(new basket(m_tree.dir().file(),
m_tree.dir().seek_directory(),
m_name,m_title,"TBasket",
m_basket_size));
}
virtual ~branch(){
delete [] fBasketBytes;
delete [] fBasketEntry;
delete [] fBasketSeek;
fBasketBytes = 0;
fBasketEntry = 0;
fBasketSeek = 0;
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
branch(const branch& a_from)
: ibo(a_from)
,m_tree(a_from.m_tree)
,m_out(a_from.m_out)
{}
branch& operator=(const branch&){return *this;}
public:
void set_basket_size(uint32 a_size) {m_basket_size = a_size;}
template <class T>
leaf<T>* create_leaf(const std::string& a_name,
const std::string& a_title){
leaf<T>* lf = new leaf<T>(m_out,*this,a_name,a_title);
m_leaves.push_back(lf);
return lf;
}
const std::vector<base_leaf*>& leaves() const {return m_leaves;}
bool fill(uint32& a_nbytes) {
a_nbytes = 0;
//FIXME if (TestBit(kDoNotProcess)) return 0;
basket* bk = m_baskets[m_write_basket];
if(!bk) {
m_out << "tools::wroot::branch::fill :"
<< " get_basket failed."
<< std::endl;
return false;
}
buffer& buf = bk->datbuf();
uint32 lold = buf.length();
bk->update(bk->key_length()+lold);
m_entries++;
m_entry_number++;
if(!fill_leaves(buf)) return false;
uint32 lnew = buf.length();
uint32 nbytes = lnew - lold;
uint32 nsize = 0;
// Should we create a new basket?
// Compare expected next size with m_basket_size.
if((lnew+2*nsize+nbytes)>=m_basket_size) {
uint32 nout;
if(!bk->write_on_file(m_write_basket,nout)) {
m_out << "tools::wroot::branch::fill :"
<< " basket.write_buffer() failed."
<< std::endl;
return false;
}
fBasketBytes[m_write_basket] = bk->number_of_bytes();
//fBasketEntry[m_write_basket] //can't be set here.
fBasketSeek[m_write_basket] = bk->seek_key();
uint32 add_bytes = bk->object_size() + bk->key_length();
delete bk;
m_baskets[m_write_basket] = 0;
m_tot_bytes += add_bytes;
m_zip_bytes += nout;
m_tree.add_tot_bytes(add_bytes);
m_tree.add_zip_bytes(nout);
bk = new basket(m_tree.dir().file(),m_tree.dir().seek_directory(),
m_name,m_title,"TBasket",m_basket_size);
m_write_basket++;
if(m_write_basket>=m_baskets.size()) {
m_baskets.resize(2*m_write_basket,0);
}
m_baskets[m_write_basket] = bk;
if(m_write_basket>=m_max_baskets) {
//Increase BasketEntry buffer of a minimum of 10 locations
// and a maximum of 50 per cent of current size
uint32 newsize = mx<uint32>(10,uint32(1.5*m_max_baskets));
if(newsize>=START_BIG_FILE()) {
//we are going to have pb with uint32[] indexing.
m_out << "tools::wroot::branch::fill :"
<< " new size for fBasket[Bytes,Entry,Seek] arrays"
<< " is too close of 32 bits limit."
<< std::endl;
m_out << "tools::wroot::branch::fill :"
<< " you have to work with larger basket size."
<< std::endl;
return false;
}
if(!realloc<uint32>(fBasketBytes,newsize,m_max_baskets,true)) {
m_out << "tools::wroot::branch::fill : realloc failed." << std::endl;
return false;
}
if(!realloc<uint32>(fBasketEntry,newsize,m_max_baskets,true)){
m_out << "tools::wroot::branch::fill : realloc failed." << std::endl;
return false;
}
if(!realloc<seek>(fBasketSeek,newsize,m_max_baskets,true)){
m_out << "tools::wroot::branch::fill : realloc failed." << std::endl;
return false;
}
m_max_baskets = newsize;
}
fBasketBytes[m_write_basket] = 0;
fBasketEntry[m_write_basket] = (uint32)m_entry_number;
fBasketSeek[m_write_basket] = 0;
}
a_nbytes = nbytes;
return true;
}
protected:
bool fill_leaves(buffer& a_buffer) {
std::vector<base_leaf*>::iterator it;
for(it=m_leaves.begin();it!=m_leaves.end();++it) {
if(!(*it)->fill_basket(a_buffer)) return false;
}
return true;
}
protected:
itree& m_tree;
std::ostream& m_out;
ObjArray<basket> m_baskets;
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 m_basket_size; // Initial Size of Basket Buffer
uint32 m_write_basket; // Last basket number written
uint64 m_entry_number; // Current entry number (last one filled in this branch)
uint64 m_entries; // Number of entries
uint64 m_tot_bytes;
uint64 m_zip_bytes;
uint32 m_max_baskets;
uint32* fBasketBytes; //[m_max_baskets] Lenght of baskets on file
uint32* fBasketEntry; //[m_max_baskets] Table of first entry in eack basket
seek* fBasketSeek; //[m_max_baskets] Addresses of baskets on file
};
}}
#endif
@@ -0,0 +1,409 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_buffer
#define tools_wroot_buffer
// class used for serializing objects.
#include "wbuf"
#include "ibo"
#include "../realloc"
#include "../mnmx"
#ifdef TOOLS_MEM
#include "../mem"
#endif
#include <string>
#include <vector>
#include <ostream>
#include <map>
namespace tools {
namespace wroot {
class buffer {
static const std::string& s_class() {
static const std::string s_v("tools::wroot::buffer");
return s_v;
}
public:
buffer(std::ostream& a_out,
bool a_byte_swap,
uint32 a_size) // we expect a not zero value.
:m_out(a_out)
,m_byte_swap(a_byte_swap)
,m_size(0)
,m_buffer(0)
,m_max(0)
,m_pos(0)
,m_wb(a_out,a_byte_swap,0,m_pos) //it holds a ref on m_pos.
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_size = a_size;
m_buffer = new char[m_size];
//if(!m_buffer) {}
m_max = m_buffer+m_size;
m_pos = m_buffer;
m_wb.set_eob(m_max);
}
virtual ~buffer(){
m_objs.clear();
m_obj_mapped.clear();
m_clss.clear();
m_cls_mapped.clear();
delete [] m_buffer;
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
buffer(const buffer& a_from)
:m_out(a_from.m_out)
,m_byte_swap(a_from.m_byte_swap)
,m_size(0)
,m_buffer(0)
,m_max(0)
,m_pos(0)
,m_wb(a_from.m_out,a_from.m_byte_swap,0,m_pos)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
buffer& operator=(const buffer&){return *this;}
public:
std::ostream& out() const {return m_out;}
//void set_offset(unsigned int a_off) {m_pos = m_buffer+a_off;}
char* buf() {return m_buffer;}
const char* buf() const {return m_buffer;}
uint32 length() const {return m_pos-m_buffer;}
uint32 size() const {return m_size;}
char*& pos() {return m_pos;} //used in basket.
char* max_pos() const {return m_max;} //used in basket.
public:
template <class T>
bool write(T x){
if(m_pos+sizeof(T)>m_max) {
if(!expand(m_size+sizeof(T))) return false;
}
return m_wb.write(x);
}
bool write(bool x){
return write<unsigned char>(x?1:0);
}
bool write(const std::string& x) {
uint32 sz = (uint32)(x.size() + sizeof(int) + 1);
if((m_pos+sz)>m_max) {
if(!expand(m_size+sz)) return false;
}
return m_wb.write(x);
}
bool write_fast_array(const char* a_a,uint32 a_n) {
if(!a_n) return true;
uint32 l = a_n * sizeof(char);
if((m_pos+l)>m_max) {
if(!expand(m_size+l)) return false;
}
::memcpy(m_pos,a_a,l);
m_pos += l;
return true;
}
bool write_cstring(const char* a_s) {
return write_fast_array(a_s,(::strlen(a_s)+1)*sizeof(char));
}
template <class T>
bool write_fast_array(const T* a_a,uint32 a_n) {
if(!a_n) return true;
uint32 l = a_n * sizeof(T);
if((m_pos+l)>m_max) {
if(!expand(m_size+l)) return false;
}
return m_wb.write<T>(a_a,a_n);
}
template <class T>
bool write_fast_array(const std::vector<T>& a_v) {
if(a_v.empty()) return true;
uint32 l = a_v.size() * sizeof(T);
if((m_pos+l)>m_max) {
if(!expand(m_size+l)) return false;
}
return m_wb.write<T>(a_v);
}
template <class T>
bool write_array(const T* a_a,uint32 a_n) {
if(!write(a_n)) return false;
return write_fast_array(a_a,a_n);
}
template <class T>
bool write_array(const std::vector<T> a_v) {
if(!write((uint32)a_v.size())) return false;
return write_fast_array(a_v);
}
template <class T>
bool write_array2(const std::vector< std::vector<T> > a_v) {
if(!write((uint32)a_v.size())) return false;
for(unsigned int index=0;index<a_v.size();index++) {
if(!write_array(a_v[index])) return false;
}
return true;
}
public:
bool write_version(short a_version){
if(a_version>kMaxVersion()) {
m_out << "tools::wroot::buffer::write_version :"
<< " version number " << a_version
<< " cannot be larger than " << kMaxVersion() << "."
<< std::endl;
return false;
}
return write(a_version);
}
bool write_version(short a_version,uint32& a_pos){
// reserve space for leading byte count
a_pos = (uint32)(m_pos-m_buffer);
//NOTE : the below test is lacking in CERN-ROOT !
if((m_pos+sizeof(unsigned int))>m_max) {
if(!expand(m_size+sizeof(unsigned int))) return false;
}
m_pos += sizeof(unsigned int);
if(a_version>kMaxVersion()) {
m_out << "tools::wroot::buffer::write_version :"
<< " version number " << a_version
<< " cannot be larger than " << kMaxVersion() << "."
<< std::endl;
return false;
}
return write(a_version);
}
bool set_byte_count(uint32 a_pos){
uint32 cnt = (uint32)(m_pos-m_buffer) - a_pos - sizeof(unsigned int);
if(cnt>=kMaxMapCount()) {
m_out << "tools::wroot::buffer::set_byte_count :"
<< " bytecount too large (more than "
<< kMaxMapCount() << ")."
<< std::endl;
return false;
}
union {
uint32 cnt;
short vers[2];
} v;
v.cnt = cnt;
char* opos = m_pos;
m_pos = (char*)(m_buffer+a_pos);
if(m_byte_swap) {
if(!m_wb.write(short(v.vers[1]|kByteCountVMask())))
{m_pos = opos;return false;}
if(!m_wb.write(v.vers[0])) {m_pos = opos;return false;}
} else {
if(!m_wb.write(short(v.vers[0]|kByteCountVMask())))
{m_pos = opos;return false;}
if(!m_wb.write(v.vers[1])) {m_pos = opos;return false;}
}
m_pos = opos;
return true;
}
bool write_object(const ibo& a_obj){
//GB : if adding a write map logic, think to have a displace_mapped()
// in basket::write_on_file().
std::map<ibo*,uint32>::const_iterator it = m_objs.find((ibo*)&a_obj);
if(it!=m_objs.end()) {
uint32 objIdx = (*it).second;
unsigned int offset = (unsigned int)(m_pos-m_buffer);
// save index of already stored object
if(!write(objIdx)) return false;
m_obj_mapped.push_back(std::pair<uint32,uint32>(offset,objIdx));
} else {
// reserve space for leading byte count
uint32 cntpos = (unsigned int)(m_pos-m_buffer);
//NOTE : the below test is lacking in CERN-ROOT !
if((m_pos+sizeof(unsigned int))>m_max) {
if(!expand(m_size+sizeof(unsigned int))) return false;
}
m_pos += sizeof(unsigned int);
// write class of object first
if(!write_class(a_obj.store_cls())) return false;
// add to map before writing rest of object (to handle self reference)
// (+kMapOffset so it's != kNullTag)
m_objs[(ibo*)&a_obj] = cntpos + kMapOffset();
// let the object write itself :
if(!a_obj.stream(*this)) return false;
// write byte count
if(!set_byte_count_obj(cntpos)) return false;
}
return true;
}
bool expand(uint32 a_new_size) {
unsigned long len = m_pos-m_buffer;
if(!realloc<char>(m_buffer,a_new_size,m_size)) {
m_out << "tools::wroot::buffer::expand :"
<< " can't realloc " << a_new_size << " bytes."
<< std::endl;
m_size = 0;
m_max = 0;
m_pos = 0;
m_wb.set_eob(m_max);
return false;
}
m_size = a_new_size;
m_max = m_buffer + m_size;
m_pos = m_buffer + len;
m_wb.set_eob(m_max);
return true;
}
unsigned int to_displace() const {
return m_cls_mapped.size()+m_obj_mapped.size();
}
bool displace_mapped(unsigned int a_num){
char* opos = m_pos;
//m_out << "tools::wroot::buffer::displace_mapped :"
// << " cls num " << m_cls_mapped.size()
// << std::endl;
{std::vector< std::pair<uint32,uint32> >::const_iterator it;
for(it=m_cls_mapped.begin();it!=m_cls_mapped.end();++it) {
unsigned int offset = (*it).first;
unsigned int id = (*it).second;
//m_out << "displace " << offset << " " << id << std::endl;
m_pos = m_buffer+offset;
unsigned int clIdx = id+a_num;
if(!write(uint32(clIdx|kClassMask()))) {m_pos = opos;return false;}
}}
//m_out << "tools::wroot::buffer::displace_mapped :"
// << " obj num " << m_obj_mapped.size()
// << std::endl;
{std::vector< std::pair<uint32,uint32> >::const_iterator it;
for(it=m_obj_mapped.begin();it!=m_obj_mapped.end();++it) {
uint32 offset = (*it).first;
uint32 id = (*it).second;
//m_out << "displace at " << offset
// << " the obj pos " << id
// << " by " << a_num
// << std::endl;
m_pos = m_buffer+offset;
unsigned int objIdx = id+a_num;
if(!write(objIdx)) {m_pos = opos;return false;}
}}
m_pos = opos;
return true;
}
protected:
static short kMaxVersion() {return 0x3FFF;}
static uint32 kMaxMapCount() {return 0x3FFFFFFE;}
static short kByteCountVMask() {return 0x4000;}
static uint32 kNewClassTag() {return 0xFFFFFFFF;}
static int kMapOffset() {return 2;}
static unsigned int kClassMask() {return 0x80000000;}
static uint32 kByteCountMask() {return 0x40000000;}
bool write_class(const std::string& a_cls){
std::map<std::string,uint32>::const_iterator it = m_clss.find(a_cls);
if(it!=m_clss.end()) {
uint32 clIdx = (*it).second;
unsigned int offset = (unsigned int)(m_pos-m_buffer);
// save index of already stored class
if(!write(uint32(clIdx|kClassMask()))) return false;
m_cls_mapped.push_back(std::pair<uint32,uint32>(offset,clIdx));
} else {
unsigned int offset = (unsigned int)(m_pos-m_buffer);
if(!write(kNewClassTag())) return false;
if(!write_cstring(a_cls.c_str())) return false;
m_clss[a_cls] = offset + kMapOffset();
}
return true;
}
bool set_byte_count_obj(uint32 a_pos){
uint32 cnt = (uint32)(m_pos-m_buffer) - a_pos - sizeof(unsigned int);
if(cnt>=kMaxMapCount()) {
m_out << "tools::wroot::buffer::set_byte_count_obj :"
<< " bytecount too large (more than "
<< kMaxMapCount() << ")."
<< std::endl;
return false;
}
char* opos = m_pos;
m_pos = (char*)(m_buffer+a_pos);
if(!m_wb.write(uint32(cnt|kByteCountMask()))) {m_pos = opos;return false;}
m_pos = opos;
return true;
}
static std::string sout(const std::string& a_string) {
return std::string("\"")+a_string+"\"";
}
protected:
std::ostream& m_out;
bool m_byte_swap;
uint32 m_size;
char* m_buffer;
char* m_max;
char* m_pos;
wbuf m_wb;
std::map<ibo*,uint32> m_objs;
std::vector< std::pair<uint32,uint32> > m_obj_mapped;
std::map<std::string,uint32> m_clss;
std::vector< std::pair<uint32,uint32> > m_cls_mapped;
};
}}
#endif
@@ -0,0 +1,62 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_bufobj
#define tools_wroot_bufobj
#include "iobject"
#include "buffer"
namespace tools {
namespace wroot {
class bufobj : public virtual iobject,public buffer {
public:
static const std::string& s_class() {
static const std::string s_v("tools::wroot::bufobj");
return s_v;
}
public:
virtual const std::string& name() const {return m_name;}
virtual const std::string& title() const {return m_title;}
virtual const std::string& store_class_name() const {
return m_store_cls;
}
virtual bool stream(buffer& a_buffer) const {
return a_buffer.write_fast_array(m_buffer,length());
}
public:
bufobj(std::ostream& a_out,bool a_byte_swap,uint32 a_size,
const std::string& a_name,
const std::string& a_title,
const std::string& a_store_cls)
: buffer(a_out,a_byte_swap,a_size)
,m_name(a_name)
,m_title(a_title)
,m_store_cls(a_store_cls)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~bufobj(){
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
bufobj(const bufobj& a_from): iobject(a_from),buffer(a_from){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
bufobj& operator=(const bufobj &){return *this;}
protected:
std::string m_name;
std::string m_title;
std::string m_store_cls;
};
}}
#endif
@@ -0,0 +1,49 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_date
#define tools_wroot_date
//NOTE : no need to have to include windows.h here, time.h does the job.
//#ifdef WIN32
//#include <windows.h>
//#else
#include <time.h>
//#endif
namespace tools {
namespace wroot {
typedef unsigned int date;
inline date get_date(){
// Set Date/Time to current time as reported by the system.
// Date and Time are encoded into one single unsigned 32 bit word.
// Date is stored with the origin being the 1st january 1995.
// Time has 1 second precision.
//#ifdef WIN32
// SYSTEMTIME tp;
// ::GetLocalTime(&tp);
// unsigned int year = tp.wYear-1900;
// unsigned int month = tp.wMonth;
// unsigned int day = tp.wDay;
// unsigned int hour = tp.wHour;
// unsigned int min = tp.wMinute;
// unsigned int sec = tp.wSecond;
//#else
time_t tloc = ::time(0);
struct tm *tp = (tm*)::localtime(&tloc);
unsigned int year = tp->tm_year;
unsigned int month = tp->tm_mon + 1;
unsigned int day = tp->tm_mday;
unsigned int hour = tp->tm_hour;
unsigned int min = tp->tm_min;
unsigned int sec = tp->tm_sec;
//#endif
return ((year-95)<<26 | month<<22 | day<<17 | hour<<12 | min<<6 | sec);
}
}}
#endif
@@ -0,0 +1,583 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_directory
#define tools_wroot_directory
#include "idir"
#include "date"
#include "key"
#include "ifile"
#include "date"
#include "buffer"
#include "iobject"
#include "../strip"
#include "../vmanip"
#include <vector>
#include <list>
namespace tools {
namespace wroot {
class directory : public virtual idir {
static uint32 class_version() {return 1;}
public:
static const std::string& s_class() {
static const std::string s_v("tools::wroot::directory");
return s_v;
}
public: //idir
virtual ifile& file() {return m_file;}
virtual seek seek_directory() const {return m_seek_directory;}
virtual void append_object(iobject* a_object) {
//take ownership of a_object
m_objs.push_back(a_object);
}
public:
directory(ifile& a_file)
:m_file(a_file)
,m_parent(0)
,m_is_valid(false)
,m_date_C(0)
,m_date_M(0)
,m_nbytes_keys(0)
,m_nbytes_name(0)
,m_seek_directory(0)
,m_seek_parent(0)
,m_seek_keys(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
directory(ifile& a_file,
const std::string& a_name,
const std::string& a_title)
:m_file(a_file)
,m_parent(0)
,m_is_valid(false)
,m_name(a_name)
,m_title(a_title)
,m_nbytes_keys(0)
,m_nbytes_name(0)
,m_seek_directory(0)
,m_seek_parent(0)
,m_seek_keys(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_date_C = get_date();
m_date_M = get_date();
if(m_name.empty()) {
m_file.out() << "tools::wroot::directory::directory :"
<< " directory name cannot be \"\"."
<< std::endl;
return; //FIXME : throw
}
if(m_name.find('/')!=std::string::npos) {
m_file.out() << "tools::wroot::directory::directory :"
<< " directory name " << sout(m_name)
<< " cannot contain a slash."
<< std::endl;
return; //FIXME : throw
}
if(m_title.empty()) m_title = m_name;
m_is_valid = true;
}
directory(ifile& a_file,
directory* a_parent, //assume a_parent not nul.
const std::string& a_name,
const std::string& a_title)
:m_file(a_file)
,m_parent(a_parent)
,m_is_valid(false)
,m_name(a_name)
,m_title(a_title)
,m_nbytes_keys(0)
,m_nbytes_name(0)
,m_seek_directory(0)
,m_seek_parent(0)
,m_seek_keys(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_date_C = get_date();
m_date_M = get_date();
if(m_name.empty()) {
m_file.out() << "tools::wroot::directory::directory :"
<< " directory name cannot be \"\"."
<< std::endl;
return; //FIXME : throw
}
if(m_name.find('/')!=std::string::npos) {
m_file.out() << "tools::wroot::directory::directory :"
<< " directory name " << sout(m_name)
<< " cannot contain a slash."
<< std::endl;
return; //FIXME : throw
}
if(m_title.empty()) m_title = m_name;
if(m_parent->find_key(m_name)) {
m_file.out() << "tools::wroot::directory::directory :"
<< " directory " << sout(m_name) << " exists already."
<< std::endl;
return; //FIXME : throw
}
m_seek_parent = m_parent->seek_directory();
uint32 nbytes = record_size();
wroot::key* key =
new wroot::key(m_file,m_parent->seek_directory(),
m_name,m_title,"TDirectory",nbytes); //set m_END
m_nbytes_name = key->key_length();
m_seek_directory = key->seek_key(); //at EOF
if(!m_seek_directory) {
m_file.out() << "tools::wroot::directory::directory :"
<< " bad key."
<< std::endl;
delete key;
return; //FIXME : throw
}
{char* buffer = key->data_buffer();
wbuf wb(m_file.out(),m_file.byte_swap(),key->eob(),buffer);
if(!to_buffer(wb)) {
m_file.out() << "tools::wroot::directory::directory :"
<< " directory name " << sout(m_name)
<< " cannot fill buffer."
<< std::endl;
delete key;
return; //FIXME : throw
}}
uint16 cycle = m_parent->append_key(key);
key->set_cycle(cycle);
if(!key->write_self()) {
m_file.out() << "tools::wroot::directory::directory :"
<< " key.write_self() failed."
<< std::endl;
return; //FIXME : throw
}
uint32 n;
if(!key->write_file(n)) {
m_file.out() << "tools::wroot::directory::directory :"
<< " directory name " << sout(m_name)
<< " cannot write key to file."
<< std::endl;
return; //FIXME : throw
}
m_is_valid = true;
}
virtual ~directory(){
clear_dirs();
clear_objs();
clear_keys();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
directory(const directory& a_from)
:idir(a_from)
,m_file(a_from.m_file)
,m_parent(0)
,m_is_valid(false){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
directory& operator=(const directory &){
m_is_valid = false;
return *this;
}
public:
bool is_valid() const {return m_is_valid;}
void set_seek_directory(seek a_seek) {m_seek_directory = a_seek;}
directory* mkdir(const std::string& a_name,
const std::string& a_title = ""){
// Create a sub-directory and return a pointer to the created directory.
// Note that the directory name cannot contain slashes.
if(a_name.empty()) {
m_file.out() << "tools::wroot::directory::mkdir :"
<< " directory name cannot be \"\"."
<< std::endl;
return 0;
}
if(a_name.find('/')!=std::string::npos) {
m_file.out() << "tools::wroot::directory::mkdir :"
<< " " << sout(a_name)
<< " cannot contain a slash."
<< std::endl;
return 0;
}
directory* dir =
new directory(m_file,this,a_name,a_title.empty()?a_name:a_title);
if(!dir->is_valid()) {
m_file.out() << "tools::wroot::directory::mkdir :"
<< " directory badly created."
<< std::endl;
delete dir;
return 0;
}
m_dirs.push_back(dir);
return dir;
}
//uint32 nbytes_name() const {return m_nbytes_name;}
void set_nbytes_name(uint32 a_n) {m_nbytes_name = a_n;}
uint32 record_size() 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);
//ROOT version >= 40000:
nbytes += sizeof(seek);
nbytes += sizeof(seek);
nbytes += sizeof(seek);
return nbytes;
}
bool close() {
if(!save()) return false;
clear_dirs();
clear_objs();
clear_keys();
return true;
}
bool to_buffer(wbuf& a_wb){
// Decode input buffer.
// (Name, title) are stored in the (name, title) of the associated key.
short version = class_version();
version += 1000; //GB : enforce writing on seek (and not seek32).
if(!a_wb.write(version)) return false;
if(!a_wb.write(m_date_C)) return false;
if(!a_wb.write(m_date_M)) return false;
if(!a_wb.write(m_nbytes_keys)) return false;
if(!a_wb.write(m_nbytes_name)) return false;
if(!a_wb.write(m_seek_directory)) return false;
if(!a_wb.write(m_seek_parent)) return false;
if(!a_wb.write(m_seek_keys)) return false;
if(m_file.verbose()) {
m_file.out() << "tools::wroot::key::to_buffer :"
<< " nbytes keys : " << m_nbytes_keys
<< ", pos keys : " << m_seek_keys
<< std::endl;
}
return true;
}
bool write(uint32& a_nbytes){
// Write all objects in memory to disk.
// Loop on all objects in memory (including subdirectories).
// A new key is created in the m_keys linked list for each object.
// For allowed options see TObject::Write().
// The directory header info is rewritten on the directory header record
a_nbytes = 0;
if(m_file.verbose()) {
m_file.out() << "tools::wroot::directory::write :"
<< " " << sout(m_name)
<< " : " << long2s(m_dirs.size())
<< " : " << long2s(m_objs.size())
<< " objects."
<< std::endl;
}
uint32 nbytes = 0;
{std::vector<directory*>::iterator it;
for(it=m_dirs.begin();it!=m_dirs.end();++it) {
uint32 n;
if(!(*it)->write(n)) return false;
nbytes += n;
}}
{std::vector<iobject*>::iterator it;
for(it=m_objs.begin();it!=m_objs.end();++it) {
uint32 n;
if(!write_object(*(*it),n)) {
m_file.out() << "tools::wroot::directory::write :"
<< " for directory " << sout(m_name)
<< ", write_object " << sout((*it)->name())
<< " failed."
<< std::endl;
return false;
}
nbytes += n;
}}
if(!save_self()) {
m_file.out() << "tools::wroot::directory::write :"
<< " for directory " << sout(m_name)
<< ", save_self failed."
<< std::endl;
return false; //it will write keys of objects.
}
a_nbytes = nbytes;
return true;
}
void clear_dirs() {clear<directory>(m_dirs);}
void clear_objs() {clear<iobject>(m_objs);}
protected:
void clear_keys() {
std::list<key*>::iterator it;
for(it=m_keys.begin();it!=m_keys.end();) {
key* k = *it;
it = m_keys.erase(it);
delete k;
}
m_keys.clear();
}
bool save(){
if(!save_self()) return false;
{std::vector<directory*>::iterator it;
for(it=m_dirs.begin();it!=m_dirs.end();++it) {
if(!(*it)->save()) return false;
}}
return true;
}
bool save_self() {
// Save Directory keys and header :
// If the directory has been modified (fModified set), write the keys
// and the directory header.
//if (fModified || aForce) {
// if(!fFile.freeSegments().empty()) {
// if(!writeKeys()) return false; // Write keys record.
// if(!writeHeader()) return false; // Update directory record.
// }
//}
if(!write_keys()) return false;
if(!write_header()) return false;
return true;
}
//const std::list<key*>& keys() const {return m_keys;}
//std::list<key*>& keys() {return m_keys;}
key* find_key(const std::string& a_name) {
if(m_file.verbose()) {
m_file.out() << "tools::wroot::directory::find_key :"
<< " " << sout(a_name) << " ..."
<< std::endl;
}
std::list<key*>::const_iterator it;
for(it=m_keys.begin();it!=m_keys.end();++it) {
if((*it)->object_name()==a_name) return *it;
}
return 0;
}
seek seek_keys() const {return m_seek_keys;}
uint16 append_key(key* a_key){ //take ownership of a_key
std::list<key*>::iterator itk;
for(itk=m_keys.begin();itk!=m_keys.end();++itk) {
if((*itk)->object_name()==a_key->object_name()) {
m_keys.insert(itk,a_key); //a_key will be before *itk.
return ((*itk)->cycle() + 1);
}
}
// Not found :
m_keys.push_back(a_key);
return 1;
}
bool write_keys(){
// The list of keys (m_keys) is written as a single data record
// Delete the old keys structure if it exists
//if(fSeekKeys) {
// if(!fFile.makeFreeSegment
// (fSeekKeys, fSeekKeys + fNbytesKeys -1)) return false;
//}
// Write new keys record :
uint32 nkeys = m_keys.size();
// Compute size of all keys
uint32 nbytes = sizeof(nkeys);
{std::list<key*>::iterator it;
for(it=m_keys.begin();it!=m_keys.end();++it) {
nbytes += (*it)->key_length();
}}
key headerkey(m_file,m_seek_directory,
m_name,m_title,"TDirectory",nbytes);
if(!headerkey.seek_key()) return false;
{char* buffer = headerkey.data_buffer();
wbuf wb(m_file.out(),m_file.byte_swap(),headerkey.eob(),buffer);
if(!wb.write(nkeys)) return false;
{std::list<key*>::iterator it;
for(it=m_keys.begin();it!=m_keys.end();++it) {
if(!((*it)->to_buffer(wb))) return false;
}}}
m_seek_keys = headerkey.seek_key();
m_nbytes_keys = headerkey.number_of_bytes();
if(m_file.verbose()) {
m_file.out() << "tools::wroot::directory::write_keys :"
<< " write header key"
<< " " << sout(m_name)
<< " " << sout(m_title)
<< " (" << nkeys
<< ", " << nbytes
<< ", " << m_seek_keys
<< ", " << m_nbytes_keys
<< "):"
<< std::endl;
}
headerkey.set_cycle(1);
if(!headerkey.write_self()) {
m_file.out() << "tools::wroot::directory::write_keys :"
<< " key.write_self() failed."
<< std::endl;
return false;
}
uint32 n;
return headerkey.write_file(n);
}
bool write_header(){
// Overwrite the Directory header record.
uint32 nbytes = record_size();
char* header = new char[nbytes];
char* buffer = header;
m_date_M = get_date();
wbuf wb(m_file.out(),m_file.byte_swap(),header+nbytes,buffer);
if(!to_buffer(wb)) {
delete [] header;
return false;
}
// do not overwrite the name/title part
seek pointer = m_seek_directory + m_nbytes_name;
//fModified = false;
if(!m_file.set_pos(pointer)) {
delete [] header;
return false;
}
if(!m_file.write_buffer(header,nbytes)) {
delete [] header;
return false;
}
if(!m_file.synchronize()) {
delete [] header;
return false;
}
delete [] header;
return true;
}
bool write_object(iobject& a_obj,uint32& a_nbytes){
buffer bref(m_file.out(),m_file.byte_swap(),256*128); //32768
if(!a_obj.stream(bref)) {
m_file.out() << "tools::wroot::directory::write_object :"
<< " cannot stream object of store class name "
<< " " << sout(a_obj.store_class_name()) << "."
<< std::endl;
a_nbytes = 0;
return false;
}
std::string name = a_obj.name();
strip(name);
//first create the key to get key_length();
wroot::key* key = new wroot::key(m_file,m_seek_directory,
name,
a_obj.title(),a_obj.store_class_name(),
bref.length()); //set m_END
if(!key->seek_key()) {
delete key;
return false;
}
if(!bref.displace_mapped(key->key_length())) { //done before compression.
delete key;
return false;
}
char* kbuf = 0;
uint32 klen = 0;
bool kdelete = false;
m_file.compress_buffer(bref,kbuf,klen,kdelete);
::memcpy(key->data_buffer(),kbuf,klen);
if(kdelete) delete [] kbuf;
{uint32 nkey = key->key_length()+klen;
m_file.set_END(key->seek_key()+nkey);
key->set_number_of_bytes(nkey);}
uint16 cycle = append_key(key);
key->set_cycle(cycle);
if(!key->write_self()) {
m_file.out() << "tools::wroot::directory::write_object :"
<< " key.write_self() failed."
<< std::endl;
return false;
}
//FIXME m_file.sumBuffer(key->object_size()); //uncompressed data size.
if(m_file.verbose()) {
m_file.out() << "tools::wroot::directory::_write_buffer :"
<< " " << sout(a_obj.name()) << "."
<< std::endl;
}
return key->write_file(a_nbytes);
}
protected:
static std::string sout(const std::string& a_string) {
return std::string("\"")+a_string+"\"";
}
protected:
ifile& m_file;
directory* m_parent;
bool m_is_valid;
std::string m_name;
std::string m_title;
std::vector<directory*> m_dirs;
std::vector<iobject*> m_objs;
std::list<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,476 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_element
#define tools_wroot_element
#include "buffer"
#include "named"
#include "../snpf"
namespace tools {
namespace wroot {
namespace streamer_info {
enum Type { // sizeof :
BASE = 0, // x
ARRAY = 20, // ?
POINTER = 40, // 4
POINTER_INT = 43, // 4
POINTER_FLOAT = 45, // 4
POINTER_DOUBLE = 48, // 4
COUNTER = 6, // 4
CHAR = 1, // 1
SHORT = 2, // 2
INT = 3, // 4
FLOAT = 5, // 4
DOUBLE = 8, // 8
UNSIGNED_CHAR = 11, // 1
UNSIGNED_SHORT = 12, // 2
UNSIGNED_INT = 13, // 4
BOOL = 18, // 1 ?
OBJECT = 61, // ?
OBJECT_ANY = 62, // ?
OBJECT_ARROW = 63, // ?
OBJECT_POINTER = 64, // ?
TSTRING = 65, // 8
TOBJECT = 66, // 12
TNAMED = 67 // 28
};
}
class streamer_element : public virtual ibo {
static const std::string& s_class() {
static const std::string s_v("tools::wroot::streamer_element");
return s_v;
}
public: //ibo
virtual const std::string& store_cls() const {
static const std::string s_v("TStreamerElement");
return s_v;
}
virtual bool stream(buffer& aBuffer) const {
unsigned int c;
if(!aBuffer.write_version(2,c)) return false;
if(!Named_stream(aBuffer,fName,fTitle)) return false;
if(!aBuffer.write(fType)) return false;
if(!aBuffer.write(fSize)) return false;
if(!aBuffer.write(fArrayLength)) return false;
if(!aBuffer.write(fArrayDim)) return false;
if(!aBuffer.write_fast_array<int>(fMaxIndex,5)) return false;
if(!aBuffer.write(fTypeName)) return false;
if(!aBuffer.set_byte_count(c)) return false;
return true;
}
public:
virtual streamer_element* copy() const = 0;
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(const std::string& aName,const std::string& aTitle,
int aOffset,int aType,const std::string& aTypeName)
:fName(aName),fTitle(aTitle),fType(aType)
,fSize(0),fArrayLength(0),fArrayDim(0),fOffset(aOffset)
,fTypeName(aTypeName){
#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)
:ibo(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 void setArrayDimension(int aDimension){
fArrayDim = aDimension;
if(aDimension) fType += streamer_info::ARRAY;
//fNewType = fType;
}
virtual void setMaxIndex(int aDimension,int aMaximum){
//set maximum index for array with dimension dim
if (aDimension < 0 || aDimension > 4) return;
fMaxIndex[aDimension] = aMaximum;
if (fArrayLength == 0) fArrayLength = aMaximum;
else fArrayLength *= aMaximum;
}
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 streamer_base : public streamer_element {
public: //ibo
virtual const std::string& store_cls() const {
static const std::string s_v("TStreamerBase");
return s_v;
}
virtual bool stream(buffer& aBuffer) const {
unsigned int c;
if(!aBuffer.write_version(3,c)) return false;
if(!streamer_element::stream(aBuffer)) return false;
if(!aBuffer.write(fBaseVersion)) return false;
if(!aBuffer.set_byte_count(c)) return false;
return true;
}
public: //streamer_element
virtual streamer_element* copy() const {return new streamer_base(*this);}
public:
streamer_base(const std::string& aName,const std::string& aTitle,
int aOffset,int aBaseVersion)
:streamer_element(aName,aTitle,aOffset,streamer_info::BASE,"BASE")
,fBaseVersion(aBaseVersion){
if (aName=="TObject") fType = streamer_info::TOBJECT;
if (aName=="TNamed") fType = streamer_info::TNAMED;
}
virtual ~streamer_base(){}
public:
streamer_base(const streamer_base& a_from)
:ibo(a_from)
,streamer_element(a_from)
,fBaseVersion(a_from.fBaseVersion)
{}
streamer_base& operator=(const streamer_base& a_from){
streamer_element::operator=(a_from);
fBaseVersion = a_from.fBaseVersion;
return *this;
}
protected:
int fBaseVersion; //version number of the base class
};
class streamer_basic_type : public streamer_element {
public: //ibo
virtual const std::string& store_cls() const {
static const std::string s_v("TStreamerBasicType");
return s_v;
}
virtual bool stream(buffer& aBuffer) const {
unsigned int c;
if(!aBuffer.write_version(2,c)) return false;
if(!streamer_element::stream(aBuffer)) return false;
if(!aBuffer.set_byte_count(c)) return false;
return true;
}
public: //streamer_element
virtual streamer_element* copy() const {
return new streamer_basic_type(*this);
}
public:
streamer_basic_type(const std::string& aName,const std::string& aTitle,
int aOffset,int aType,const std::string& aTypeName)
:streamer_element(aName,aTitle,aOffset,aType,aTypeName)
{}
virtual ~streamer_basic_type(){}
public:
streamer_basic_type(const streamer_basic_type& a_from)
:ibo(a_from),streamer_element(a_from)
{}
streamer_basic_type& operator=(const streamer_basic_type& a_from){
streamer_element::operator=(a_from);
return *this;
}
};
class streamer_basic_pointer : public streamer_element {
public: //ibo
virtual const std::string& store_cls() const {
static const std::string s_v("TStreamerBasicPointer");
return s_v;
}
virtual bool stream(buffer& aBuffer) const {
unsigned int c;
if(!aBuffer.write_version(2,c)) return false;
if(!streamer_element::stream(aBuffer)) return false;
if(!aBuffer.write(fCountVersion)) return false;
if(!aBuffer.write(fCountName)) return false;
if(!aBuffer.write(fCountClass)) return false;
if(!aBuffer.set_byte_count(c)) return false;
return true;
}
public: //streamer_element
virtual streamer_element* copy() const {
return new streamer_basic_pointer(*this);
}
public:
streamer_basic_pointer(const std::string& aName,const std::string& aTitle,
int aOffset,int aType,
const std::string& aCountName,
const std::string& aCountClass,
int aCountVersion,
const std::string& aTypeName)
:streamer_element(aName,aTitle,aOffset,
aType+streamer_info::POINTER,aTypeName)
,fCountVersion(aCountVersion)
,fCountName(aCountName)
,fCountClass(aCountClass)
{}
virtual ~streamer_basic_pointer(){}
public:
streamer_basic_pointer(const streamer_basic_pointer& a_from)
:ibo(a_from),streamer_element(a_from)
,fCountVersion(a_from.fCountVersion)
,fCountName(a_from.fCountName)
,fCountClass(a_from.fCountClass)
{}
streamer_basic_pointer& operator=(const streamer_basic_pointer& a_from){
streamer_element::operator=(a_from);
fCountVersion = a_from.fCountVersion;
fCountName = a_from.fCountName;
fCountClass = a_from.fCountClass;
return *this;
}
protected:
int fCountVersion; //version number of the class with the counter
std::string fCountName; //name of data member holding the array count
std::string fCountClass; //name of the class with the counter
};
class streamer_string : public streamer_element {
public: //ibo
virtual const std::string& store_cls() const {
static const std::string s_v("TStreamerString");
return s_v;
}
virtual bool stream(buffer& aBuffer) const {
unsigned int c;
if(!aBuffer.write_version(2,c)) return false;
if(!streamer_element::stream(aBuffer)) return false;
if(!aBuffer.set_byte_count(c)) return false;
return true;
}
public: //streamer_element
virtual streamer_element* copy() const {
return new streamer_string(*this);
}
public:
streamer_string(const std::string& aName,const std::string& aTitle,
int aOffset)
:streamer_element(aName,aTitle,aOffset,streamer_info::TSTRING,"TString")
{}
virtual ~streamer_string(){}
public:
streamer_string(const streamer_string& a_from)
:ibo(a_from),streamer_element(a_from)
{}
streamer_string& operator=(const streamer_string& a_from){
streamer_element::operator=(a_from);
return *this;
}
};
class streamer_object : public streamer_element {
public: //ibo
virtual const std::string& store_cls() const {
static const std::string s_v("TStreamerObject");
return s_v;
}
virtual bool stream(buffer& aBuffer) const {
unsigned int c;
if(!aBuffer.write_version(2,c)) return false;
if(!streamer_element::stream(aBuffer)) return false;
if(!aBuffer.set_byte_count(c)) return false;
return true;
}
public: //streamer_element
virtual streamer_element* copy() const {
return new streamer_object(*this);
}
public:
streamer_object(const std::string& aName,const std::string& aTitle,
int aOffset,const std::string& aTypeName)
:streamer_element(aName,aTitle,aOffset,0,aTypeName){
fType = streamer_info::OBJECT;
if (aName=="TObject") fType = streamer_info::TOBJECT;
if (aName=="TNamed") fType = streamer_info::TNAMED;
}
virtual ~streamer_object(){}
public:
streamer_object(const streamer_object& a_from)
:ibo(a_from),streamer_element(a_from){}
streamer_object& operator=(const streamer_object& a_from){
streamer_element::operator=(a_from);
return *this;
}
};
class streamer_object_pointer : public streamer_element {
public: //ibo
virtual const std::string& store_cls() const {
static const std::string s_v("TStreamerObjectPointer");
return s_v;
}
virtual bool stream(buffer& aBuffer) const {
unsigned int c;
if(!aBuffer.write_version(2,c)) return false;
if(!streamer_element::stream(aBuffer)) return false;
if(!aBuffer.set_byte_count(c)) return false;
return true;
}
public: //streamer_element
virtual streamer_element* copy() const {
return new streamer_object_pointer(*this);
}
public:
streamer_object_pointer(const std::string& aName,const std::string& aTitle,
int aOffset,const std::string& aTypeName)
:streamer_element(aName,aTitle,aOffset,
streamer_info::OBJECT_POINTER,aTypeName){
if(aTitle.substr(0,2)=="->") fType = streamer_info::OBJECT_ARROW;
}
virtual ~streamer_object_pointer(){}
public:
streamer_object_pointer(const streamer_object_pointer& a_from)
:ibo(a_from),streamer_element(a_from){}
streamer_object_pointer& operator=(const streamer_object_pointer& a_from){
streamer_element::operator=(a_from);
return *this;
}
};
class streamer_object_any : public streamer_element {
public: //ibo
virtual const std::string& store_cls() const {
static const std::string s_v("TStreamerObjectAny");
return s_v;
}
virtual bool stream(buffer& aBuffer) const {
unsigned int c;
if(!aBuffer.write_version(2,c)) return false;
if(!streamer_element::stream(aBuffer)) return false;
if(!aBuffer.set_byte_count(c)) return false;
return true;
}
public: //streamer_element
virtual streamer_element* copy() const {
return new streamer_object_any(*this);
}
public:
streamer_object_any(const std::string& aName,const std::string& aTitle,
int aOffset,const std::string& aTypeName)
:streamer_element(aName,aTitle,aOffset,streamer_info::OBJECT_ANY,aTypeName)
{}
virtual ~streamer_object_any(){}
public:
streamer_object_any(const streamer_object_any& a_from)
:ibo(a_from),streamer_element(a_from){}
streamer_object_any& operator=(const streamer_object_any& a_from){
streamer_element::operator=(a_from);
return *this;
}
};
class streamer_STL : public streamer_element {
public: //ibo
virtual const std::string& store_cls() const {
static const std::string s_v("TStreamerSTL");
return s_v;
}
virtual bool stream(buffer& aBuffer) const {
unsigned int c;
if(!aBuffer.write_version(2,c)) return false;
if(!streamer_element::stream(aBuffer)) return false;
if(!aBuffer.write(fSTLtype)) return false;
if(!aBuffer.write(fCtype)) return false;
if(!aBuffer.set_byte_count(c)) return false;
return true;
}
public: //streamer_element
virtual streamer_element* copy() const {
return new streamer_STL(*this);
}
protected:
enum ESTLtype { kSTL = 300, kSTLstring =365, kSTLvector = 1,
kSTLlist = 2, kSTLdeque = 3, kSTLmap = 4,
kSTLset = 5, kSTLmultimap=6, kSTLmultiset=7};
// Instead of EDataType, we use the Streamer_Info::Type.
//enum EDataType {
// kChar_t = 1, kUChar_t = 11, kShort_t = 2, kUShort_t = 12,
// kInt_t = 3, kUInt_t = 13, kLong_t = 4, kULong_t = 14,
// kFloat_t = 5, kDouble_t = 8, kchar = 10, kOther_t = -1
//};
public:
streamer_STL(const std::string& aName,const std::string& aTitle,
int aOffset,
streamer_info::Type aType, //Must match TDataType/EDataType
const std::string& aTypeName)
:streamer_element(aName,aTitle,aOffset,kSTL,aTypeName){
fSTLtype = kSTLvector;
fCtype = aType;
}
virtual ~streamer_STL(){}
public:
streamer_STL(const streamer_STL& a_from)
:ibo(a_from),streamer_element(a_from)
,fSTLtype(a_from.fSTLtype)
,fCtype(a_from.fCtype)
{}
streamer_STL& operator=(const streamer_STL& a_from){
streamer_element::operator=(a_from);
fSTLtype = a_from.fSTLtype;
fCtype = a_from.fCtype;
return *this;
}
protected:
int fSTLtype; //type of STL vector
int fCtype; //STL contained type
};
}}
#endif
@@ -0,0 +1,830 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_file
#define tools_wroot_file
#include "ifile"
#include "directory"
#include "infos"
#include "free_seg"
#include "../platform"
#include "../path"
#include <map>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#ifdef WIN32
#ifndef __GNUC__
#include <direct.h>
#include <io.h>
// disable the warning about the usage of "this" in the constructor.
#pragma warning(disable:4355)
#endif
#else
#include <unistd.h>
#endif
namespace tools {
namespace wroot {
class file : public virtual ifile {
static const std::string& s_class() {
static const std::string s_v("tools::wroot::file");
return s_v;
}
static int not_open() {return -1;}
static uint32 kBegin() {return 64;}
static uint32 START_BIG_FILE() {return 2000000000;}
public: //ifile
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::wroot::file::set_pos :"
<< " cannot set position " << a_offset
<< " in file " << sout(m_path) << "."
<< std::endl;
return false;
}
return true;
}
virtual seek END() const {return m_END;}
virtual void set_END(seek a_end){
m_END = a_end;
if(m_free_segs.empty()) {
m_out << "tools::wroot::file::set_END :"
<< " free_seg list should not be empty here."
<< std::endl;
} else {
free_seg* end_seg = m_free_segs.back();
if(end_seg->last()!=START_BIG_FILE()) {
m_out << "tools::wroot::file::set_END :"
<< " last free_seg is not the ending of file one."
<< " free_seg list looks corrupted."
<< std::endl;
} else {
m_free_segs.back()->set_first(m_END);
}
}
}
virtual bool write_buffer(const char* a_buffer,uint32 a_length) {
// Write a buffer to the file. This is the basic low level write operation.
#ifdef WIN32
typedef int ssize_t;
#endif
ssize_t siz;
while ((siz = ::write(m_file,a_buffer,a_length)) < 0 &&
error_number() == EINTR) reset_error_number();
if(siz < 0) {
m_out << "tools::wroot::file::write_buffer :"
<< " error writing to file " << sout(m_path) << "."
<< std::endl;
return false;
}
if(siz!=(ssize_t)a_length) {
m_out << "tools::wroot::file::write_buffer :"
<< "error writing all requested bytes to file " << sout(m_path)
<< ", wrote " << long2s(siz) << " of " << a_length
<< std::endl;
return false;
}
//m_bytes_write += siz;
return true;
}
virtual uint32 version() const {
// Return version id as an integer, i.e. "2.22/04" -> 22204.
static const uint32 ROOT_MAJOR_VERSION = 4;
static const uint32 ROOT_MINOR_VERSION = 0;
static const uint32 ROOT_PATCH_VERSION = 0;
return
10000 * ROOT_MAJOR_VERSION +
100 * ROOT_MINOR_VERSION +
ROOT_PATCH_VERSION;
}
virtual bool synchronize(){
// Synchornize a file's in-core and on-disk states.
#ifdef WIN32
return true;
#else
if (::fsync(m_file) < 0) {
m_out << "tools::wroot::file::synchronize :"
<< " error flushing file " << sout(m_path) << "."
<< std::endl;
return false;
}
return true;
#endif
}
virtual bool ziper(char a_key,zip_func& a_func) const {
std::map<char,zip_func>::const_iterator it = m_zipers.find(a_key);
if(it==m_zipers.end()) {
a_func = 0;
return false;
}
a_func = (*it).second;
return true;
}
virtual uint32 compression() const {return m_compress;}
virtual void compress_buffer(const buffer& a_buffer,
char*& a_kbuf,uint32& a_klen,bool& a_kdel){
//NOTE : if(kdelete) delete [] kbuf;
a_kbuf = 0;
a_klen = 0;
a_kdel = false;
uint32 nbytes = a_buffer.length();
uint32 cxlevel = m_compress;
if(cxlevel && (nbytes>256)) {
tools::zip_func func;
if(!ziper('Z',func)) {
//m_out << "tools::wroot::directory::write_object :"
// << " zlib ziper not found."
// << std::endl;
a_kbuf = (char*)a_buffer.buf();
a_klen = a_buffer.length();
a_kdel = false;
} else {
const uint32 kMAXBUF = 0xffffff;
const uint32 HDRSIZE = 9;
uint32 nbuffers = nbytes/kMAXBUF;
uint32 buflen = nbytes+HDRSIZE*(nbuffers+1);
a_kbuf = new char[buflen];
a_kdel = true;
char* src = (char*)a_buffer.buf();
char* tgt = a_kbuf;
uint32 nzip = 0;
for(uint32 i=0;i<=nbuffers;i++) {
uint32 bufmax = ((i == nbuffers) ? nbytes - nzip : kMAXBUF);
uint32 nout;
if(!zip(m_out,func,cxlevel,bufmax,src,bufmax,tgt,nout)) {
delete [] a_kbuf;
a_kbuf = (char*)a_buffer.buf();
a_klen = a_buffer.length();
a_kdel = false;
break;
}
tgt += nout; //nout includes HDRSIZE
a_klen += nout;
src += kMAXBUF;
nzip += kMAXBUF;
}
//::printf("debug : compress : end : %u %u\n",nbytes,klen);
}
} else {
a_kbuf = (char*)a_buffer.buf();
a_klen = a_buffer.length();
a_kdel = false;
}
}
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_write(0)
,m_root_directory(*this,nosuffix(a_path),m_title)
// begin of record :
,m_version(0)
,m_BEGIN(0)
,m_END(0)
,m_seek_free(0)
,m_nbytes_free(0)
,m_nbytes_name(0)
,m_units(4)
,m_compress(1)
,m_seek_info(0)
,m_nbytes_info(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_version = version();
if(access_path(m_path,kFileExists)) unlink(m_path);
if(!m_root_directory.is_valid()) {
m_out << "tools::wroot::file::file :"
<< " " << sout(m_path) << " root directory badly created."
<< std::endl;
return;
}
m_file = _open(a_path.c_str(),
#ifdef WIN32
O_RDWR | O_CREAT | O_BINARY,S_IREAD | S_IWRITE
#else
O_RDWR | O_CREAT,0644
#endif
);
if(m_file==not_open()) {
m_out << "tools::wroot::file::file :"
<< " can't open " << sout(a_path) << "."
<< std::endl;
return;
}
//initialize :
m_BEGIN = kBegin(); // First used word in file following the file header.
m_END = m_BEGIN; // Pointer to end of file.
m_free_segs.push_back(new free_seg(m_out,m_BEGIN,START_BIG_FILE()));
// Write Directory info :
uint32 namelen =
key::std_string_record_size(m_path) +
key::std_string_record_size(m_title);
uint32 nbytes = namelen + m_root_directory.record_size();
wroot::key key(*this,0,m_path,m_title,"TFile",nbytes); //set m_END.
// m_nbytes_name = start point of directory info from key head.
m_nbytes_name = key.key_length() + namelen;
m_root_directory.set_nbytes_name(m_nbytes_name);
m_root_directory.set_seek_directory(key.seek_key()); //at EOF.
//the below write 45 bytes at BOF (Begin Of File).
if(!write_header()) { //need m_nbytes_name, m_END after key written.
m_out << "tools::wroot::file::file :"
<< " can't write file header."
<< std::endl;
return;
}
{char* pos = key.data_buffer();
wbuf wb(m_out,byte_swap(),key.eob(),pos);
if(!wb.write(m_path)) return;
if(!wb.write(m_title)) return;
if(!m_root_directory.to_buffer(wb)) return;}
if(m_verbose) {
m_out << "tools::wroot::file::file :"
<< " write key ("
<< namelen
<< ", "
<< m_root_directory.record_size()
<< ", "
<< nbytes
<< ", "
<< m_nbytes_name
<< ", "
<< key.seek_key()
<< ")."
<< std::endl;
}
key.set_cycle(1);
if(!key.write_self()) {
m_out << "tools::wroot::file::file :"
<< " key.write_self() failed."
<< std::endl;
return;
}
//the below write at kBegin + nbytes.
//64+52
uint32 n;
if(!key.write_file(n)) {
m_out << "tools::wroot::file::file :"
<< " can't write key in file."
<< std::endl;
return;
}
//::printf("debug : file::file : write key : %d\n",n);
}
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)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
file& operator=(const file&){return *this;}
public:
void set_compression(uint32 a_level) {
// level = 0 objects written to this file will not be compressed.
// level = 1 minimal compression level but fast.
// ....
// level = 9 maximal compression level but slow.
m_compress = a_level;
if(m_compress>9) m_compress = 9;
}
bool is_open() const {
return (m_file==not_open()?false:true);
}
void close() {
if(m_file==not_open()) return;
m_root_directory.close();
if(m_free_segs.size()) {
if(!write_free_segments()) {
m_out << "tools::wroot::file::close :"
<< " can't write free segments."
<< std::endl;
}
if(!write_header()) { // Now write file header
m_out << "tools::wroot::file::close :"
<< " can't write file header."
<< std::endl;
}
}
{std::list<free_seg*>::iterator it;
for(it=m_free_segs.begin();
it!=m_free_segs.end();
it = m_free_segs.erase(it)) {
delete (*it);
}}
::close(m_file);
m_file = not_open();
}
directory& dir() {return m_root_directory;}
const directory& dir() const {return m_root_directory;}
bool write(uint32& a_nbytes){
// Write memory objects to this file :
// Loop on all objects in m_root_directory (including subdirectories).
// A new key is created in the directories m_keys linked list
// for each object.
// The list of keys is then saved on the file (via write_keys)
// as a single data record.
// The directory header info is rewritten on the directory header record.
// //The linked list of FREE segments is written.
// The file header is written (bytes 1->m_BEGIN).
a_nbytes = 0;
if(m_verbose) {
m_out << "tools::wroot::file::write :"
<< " writing Name=" << sout(m_path)
<< " Title=" << sout(m_title) << "."
<< std::endl;
}
uint32 nbytes;
if(!m_root_directory.write(nbytes)) return false; // Write directory tree
if(!write_streamer_infos()) {
m_out << "tools::wroot::file::write :"
<< " write_streamer_infos failed."
<< std::endl;
return false;
}
if(!write_free_segments()) {
m_out << "tools::wroot::file::write :"
<< " can't write free segments."
<< std::endl;
return false;
}
if(!write_header()) { //write 45 bytes at BOF.
m_out << "tools::wroot::file::write :"
<< " can't write file header."
<< std::endl;
return false;
}
a_nbytes = nbytes;
return true;
}
bool add_ziper(char a_key,zip_func a_func){
std::map<char,zip_func>::const_iterator it = m_zipers.find(a_key);
if(it!=m_zipers.end()) {
//(*it).second = a_func; //override ?
return false;
} else {
m_zipers[a_key] = a_func;
return true;
}
}
protected:
enum EAccessMode {
kFileExists = 0,
kExecutePermission = 1,
kWritePermission = 2,
kReadPermission = 4
};
static bool access_path(const std::string& a_path,EAccessMode a_mode){
// Returns true if one can access a file using the specified access mode.
// Mode is the same as for the WinNT access(2) function.
#ifdef WIN32
return (::_access(a_path.c_str(),a_mode) == 0) ? true : false;
#else
return (::access(a_path.c_str(),a_mode) == 0) ? true : false;
#endif
}
static bool unlink(const std::string& a_path){
// Unlink, i.e. remove, a file or directory. Returns true when succesfull,
// false in case of failure.
struct stat finfo;
if (::stat(a_path.c_str(),&finfo) < 0) return false;
#ifdef WIN32
if (finfo.st_mode & S_IFDIR)
return (::_rmdir(a_path.c_str())==-1 ? false : true);
else
return (::unlink(a_path.c_str())==-1 ? false : true);
#else
if (S_ISDIR(finfo.st_mode))
return (::rmdir(a_path.c_str())==-1 ? false : true);
else
return (::unlink(a_path.c_str())==-1 ? false : true);
#endif
}
static int _open(const char* a_name,int a_flags,unsigned int 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 write_header() {
const char root[] = "root";
//char psave[kBegin()];
char psave[128];
const char* eob = psave + kBegin();
char* pos = psave;
::memcpy(pos,root,4); pos += 4;
uint32 vers = m_version;
if((m_END>START_BIG_FILE()) ||
(m_seek_free>START_BIG_FILE()) ||
(m_seek_info>START_BIG_FILE()) ){
vers += 1000000;
m_units = 8;
}
wbuf wb(m_out,byte_swap(),eob,pos);
if(!wb.write(vers)) return false;
if(!wb.write((seek32)m_BEGIN)) return false;
if(vers>1000000) {
if(!wb.write(m_END)) return false;
if(!wb.write(m_seek_free)) return false;
} else {
if(!wb.write((seek32)m_END)) return false;
if(!wb.write((seek32)m_seek_free)) return false;
}
if(!wb.write(m_nbytes_free)) return false;
//int nfree = fFreeSegments.size();
uint32 nfree = 0; //FIXME
if(!wb.write(nfree)) return false;
if(!wb.write(m_nbytes_name)) return false;
if(!wb.write(m_units)) return false;
if(!wb.write(m_compress)) return false;
if(vers>1000000) {
if(!wb.write(m_seek_info)) return false;
} else {
if(!wb.write((seek32)m_seek_info)) return false;
}
if(!wb.write(m_nbytes_info)) return false;
if(!set_pos()) return false; //BOF
uint32 nbytes = pos - psave;
//::printf("debug : write_header : %d\n",nbytes);
if(!write_buffer(psave,nbytes)) return false;
if(!synchronize()) return false;
return true;
}
bool write_streamer_infos() {
List<StreamerInfo> sinfos;
fill_infos(sinfos,m_out);
if(sinfos.empty()) return false;
buffer bref(m_out,byte_swap(),256);
if(!sinfos.stream(bref)) {
m_out << "tools::wroot::file::write_streamer_infos :"
<< " cannot stream List<StreamerInfo>."
<< std::endl;
return false;
}
uint32 nbytes = bref.length();
wroot::key key(*this,
m_root_directory.seek_directory(),
"StreamerInfo","",
sinfos.store_cls(),
nbytes); //set m_END
if(!key.seek_key()) return false;
if(!bref.displace_mapped(key.key_length())) return false;
::memcpy(key.data_buffer(),bref.buf(),nbytes);
//key.set_cycle(1);
if(!key.write_self()) {
m_out << "tools::wroot::file::write_streamer_infos :"
<< " key.write_self() failed."
<< std::endl;
return false;
}
m_seek_info = key.seek_key();
m_nbytes_info = key.number_of_bytes();
//FIXME sumBuffer(key.objectSize());
uint32 n;
if(!key.write_file(n)) return false;
if(!n) return false;
return true;
}
bool make_free_seg(seek a_first,seek a_last) {
// Mark unused bytes on the file :
// The list of free segments is in the m_free_segs list
// When an object is deleted from the file, the freed space is added
// into the FREE linked list (m_free_segs). The FREE list consists
// of a chain of consecutive free segments on the file. At the same
// time, the first 4 bytes of the freed record on the file
// are overwritten by GAPSIZE where
// GAPSIZE = -(Number of bytes occupied by the record).
if(m_free_segs.empty()) {
m_out << "tools::wroot::file::make_free_seg :"
<< " free_seg list should not be empty here."
<< std::endl;
return false;
}
free_seg* newfree = add_free(m_free_segs,a_first,a_last);
if(!newfree) {
m_out << "tools::wroot::file::make_free_seg :"
<< " add_free failed."
<< std::endl;
return false;
}
seek nfirst = newfree->first();
seek nlast = newfree->last();
seek _nbytes = nlast-nfirst+1;
if(_nbytes>START_BIG_FILE()) _nbytes = START_BIG_FILE();
int nbytes = -int(_nbytes);
int nb = sizeof(int);
char psave[128];
const char* eob = psave + nb;
char* pos = psave;
wbuf wb(m_out,byte_swap(),eob,pos);
if(!wb.write(nbytes)) return false;
if(nlast == (m_END-1)) m_END = nfirst;
if(!set_pos(nfirst)) return false;
if(!write_buffer(psave,nb)) return false;
if(!synchronize()) return false;
return true;
}
bool write_free_segments(){
// The linked list of FREE segments (fFree) is written as a single data
// record.
// Delete old record if it exists :
if(m_seek_free){
if(!make_free_seg(m_seek_free, m_seek_free + m_nbytes_free -1)) {
m_out << "tools::wroot::file::write_free_segments :"
<< " key.write_self() failed."
<< std::endl;
return false;
}
}
//::printf("debug : write_free_segments : seg list :\n");
uint32 nbytes = 0;
{std::list<free_seg*>::const_iterator it;
for(it=m_free_segs.begin();it!=m_free_segs.end();++it) {
nbytes += (*it)->record_size();
//::printf("debug : write_free_segments : %lu %lu\n",
// (*it)->first(),(*it)->last());
}}
if(!nbytes) return true;
wroot::key key(*this,
m_root_directory.seek_directory(),
m_path,m_title,"TFile",
nbytes); //set m_END
if(!key.seek_key()) return false;
{char* pos = key.data_buffer();
wbuf wb(m_out,byte_swap(),key.eob(),pos);
std::list<free_seg*>::const_iterator it;
for(it=m_free_segs.begin();it!=m_free_segs.end();++it) {
if(!(*it)->fill_buffer(wb)) return false;
}}
//key.set_cycle(1);
if(!key.write_self()) {
m_out << "tools::wroot::file::write_free_segments :"
<< " key.write_self() failed."
<< std::endl;
return false;
}
m_seek_free = key.seek_key();
m_nbytes_free = key.number_of_bytes();
if(m_verbose) {
m_out << "tools::wroot::file::write_free_segments :"
<< " write key." << std::endl;
}
uint32 n;
if(!key.write_file(n)) return false;
if(!n) return false;
return true;
}
static bool zip(std::ostream& a_out,
tools::zip_func a_func,
int a_level,
uint32 a_srcsize,char* a_src,
uint32 a_tgtsize,char* a_tgt,
uint32& a_irep){
// from Rio/Bits/R__zip using zlib.
const uint32 HDRSIZE = 9;
if(a_tgtsize<HDRSIZE) {
a_out << "tools::rroot::directory::zip :"
<< " target buffer too small."
<< std::endl;
a_irep = 0;
return false;
}
if(a_srcsize>0xffffff) {
a_out << "tools::rroot::directory::zip :"
<< " source buffer too big."
<< std::endl;
a_irep = 0;
return false;
}
uint32 out_size;
if(!a_func(a_out,a_level,
a_srcsize,a_src,
a_tgtsize,a_tgt+HDRSIZE,
out_size)) {
a_out << "tools::rroot::directory::zip :"
<< " zipper failed."
<< std::endl;
a_irep = 0;
return false;
}
if((HDRSIZE+out_size)>a_tgtsize) {
a_out << "tools::rroot::directory::zip :"
<< " target buffer overflow."
<< std::endl;
a_irep = 0;
return false;
}
// HEADER :
a_tgt[0] = 'Z'; // Signature ZLib
a_tgt[1] = 'L';
a_tgt[2] = 8; //DEFLATE
a_tgt[3] = (char)(out_size & 0xff);
a_tgt[4] = (char)((out_size >> 8) & 0xff);
a_tgt[5] = (char)((out_size >> 16) & 0xff);
a_tgt[6] = (char)(a_srcsize & 0xff);
a_tgt[7] = (char)((a_srcsize >> 8) & 0xff);
a_tgt[8] = (char)((a_srcsize >> 16) & 0xff);
a_irep = HDRSIZE+out_size;
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;
//uint64 m_bytes_write; //Number of bytes write in this file
std::string m_title; //must be before the below.
directory m_root_directory;
std::map<char,zip_func> m_zipers;
std::list<free_seg*> m_free_segs; //Free segments linked list table
// begin of record :
// "root"
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
uint32 m_nbytes_free; //Number of bytes for free segments structure
//int nfree
uint32 m_nbytes_name; //Number of bytes in TNamed at creation time
char m_units; //Number of bytes for file pointers
uint32 m_compress; //(=1 file is compressed, 0 otherwise)
seek m_seek_info; //Location on disk of StreamerInfo record
uint32 m_nbytes_info; //Number of bytes for StreamerInfo record
};
}}
#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,177 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_free_seg
#define tools_wroot_free_seg
#include "seek"
#include "wbuf"
#include <ostream>
namespace tools {
namespace wroot {
class free_seg {
static uint32 START_BIG_FILE() {return 2000000000;}
public:
free_seg(std::ostream& a_out,seek a_first,seek a_last)
:m_out(a_out),m_first(a_first),m_last(a_last){}
virtual ~free_seg(){}
public:
free_seg(const free_seg& a_from)
:m_out(a_from.m_out),m_first(a_from.m_first),m_last(a_from.m_last)
{}
free_seg& operator=(const free_seg& a_from){
m_first = a_from.m_first;
m_last = a_from.m_last;
return *this;
}
public:
std::ostream& out() const {return m_out;}
seek first() const {return m_first;}
seek last() const {return m_last;}
void set_first(seek a_v) {m_first = a_v;}
void set_last(seek a_v) {m_last = a_v;}
unsigned int record_size() const {
//GB if(fLast>RIO_START_BIG_FILE) {
if((m_first>START_BIG_FILE())|| //GB
(m_last>START_BIG_FILE()) ){
return sizeof(short) + 2 * sizeof(seek);
} else {
return sizeof(short) + 2 * sizeof(seek32);
}
}
bool fill_buffer(wbuf& a_wb) {
short version = 1;
//GB if(fLast>START_BIG_FILE()) version += 1000;
if((m_first>START_BIG_FILE())||
(m_last>START_BIG_FILE())) version += 1000;
if(!a_wb.write(version)) return false;
if(version>1000) {
if(!a_wb.write(m_first)) return false;
if(!a_wb.write(m_last)) return false;
} else {
if(m_first>START_BIG_FILE()) { //GB
m_out << "tools::wroot::free_seg::fill_buffer :"
<< " attempt to write big Seek "
<< m_first << " on 32 bits."
<< std::endl;
return false;
}
if(!a_wb.write((seek32)m_first)) return false;
if(m_last>START_BIG_FILE()) { //GB
m_out << "tools::wroot::free_seg::fill_buffer :"
<< " attempt to write big seek "
<< m_last << " on 32 bits."
<< std::endl;
return false;
}
if(!a_wb.write((seek32)m_last)) return false;
}
return true;
}
protected:
std::ostream& m_out;
seek m_first; //First free word of segment
seek m_last; //Last free word of segment
};
}}
#include <list>
namespace tools {
namespace wroot {
inline free_seg* find_after(const std::list<free_seg*>& a_list,
free_seg* a_what) {
std::list<free_seg*>::const_iterator it;
for(it=a_list.begin();it!=a_list.end();++it) {
if((*it)==a_what) {
it++;
if(it==a_list.end()) return 0;
return *it;
}
}
return 0;
}
inline void remove(std::list<free_seg*>& a_list,free_seg* a_what) {
//NOTE : it does not delete a_what.
std::list<free_seg*>::iterator it;
for(it=a_list.begin();it!=a_list.end();++it) {
if((*it)==a_what) {
a_list.erase(it);
return;
}
}
}
inline void add_before(std::list<free_seg*>& a_list,
free_seg* a_what,free_seg* a_new) {
std::list<free_seg*>::iterator it;
for(it=a_list.begin();it!=a_list.end();++it) {
if((*it)==a_what) {
a_list.insert(it,a_new);
return;
}
}
}
inline free_seg* add_free(std::list<free_seg*>& a_list,
seek a_first,seek a_last) {
// Add a new free segment to the list of free segments
// ===================================================
// If last just preceedes an existing free segment, then first becomes
// the new starting location of the free segment.
// if first just follows an existing free segment, then last becomes
// the new ending location of the free segment.
// if first just follows an existing free segment AND last just preceedes
// an existing free segment, these two segments are merged into
// one single segment.
//
free_seg* idcur = a_list.front();
while (idcur) {
seek curfirst = idcur->first();
seek curlast = idcur->last();
if (curlast == (a_first-1)) {
idcur->set_last(a_last);
free_seg* idnext = find_after(a_list,idcur);
if (idnext == 0) return idcur;
if (idnext->first() > (a_last+1)) return idcur;
idcur->set_last(idnext->last());
remove(a_list,idnext); //idnext not deleted.
delete idnext;
return idcur;
}
if (curfirst == (a_last+1)) {
idcur->set_first(a_first);
return idcur;
}
if (a_first < curfirst) {
free_seg* newfree = new free_seg(idcur->out(),a_first,a_last);
add_before(a_list,idcur,newfree);
return newfree;
}
idcur = find_after(a_list,idcur);
}
return 0;
}
}}
#endif
@@ -0,0 +1,27 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_ibo
#define tools_wroot_ibo
#include <string>
namespace tools {
namespace wroot {
class buffer;
}}
namespace tools {
namespace wroot {
class ibo {
public:
virtual ~ibo() {}
public:
virtual const std::string& store_cls() const = 0;
virtual bool stream(buffer&) const = 0;
};
}}
#endif
@@ -0,0 +1,29 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_idir
#define tools_wroot_idir
#include "seek"
namespace tools {
namespace wroot {
class ifile;
class iobject;
}}
namespace tools {
namespace wroot {
class idir {
public:
virtual ~idir(){}
public:
virtual ifile& file() = 0;
virtual seek seek_directory() const = 0;
virtual void append_object(iobject*) = 0; //for tree.
};
}}
#endif
@@ -0,0 +1,50 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_ifile
#define tools_wroot_ifile
#include "seek"
#include "../zfunc"
namespace tools {
namespace wroot {
class buffer;
}}
namespace tools {
namespace wroot {
class ifile {
public:
virtual ~ifile(){}
public:
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 seek END() const = 0;
virtual void set_END(seek) = 0;
virtual bool write_buffer(const char*,uint32) = 0;
virtual uint32 version() const = 0;
virtual bool synchronize() = 0;
virtual bool ziper(char,zip_func&) const = 0;
virtual uint32 compression() const = 0;
virtual void compress_buffer(const buffer&,char*&,uint32&,bool&) = 0;
};
}}
#endif
@@ -0,0 +1,109 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_info
#define tools_wroot_info
#include "buffer"
#include "element"
#include "named"
namespace tools {
namespace wroot {
// sizeof(vtbl) = 4
// sizeof(unsigned int) = 4
// sizeof(TObject) = 12 = 2 * (unsigned int) + vtbl.
// sizeof(TString) = 8 = char* + vtbl.
// sizeof(TNamed) = 28 = TObject + 2 * TString.
// sizeof(TObjArray) = 40
class StreamerInfo : public virtual ibo {
static const std::string& s_class() {
static const std::string s_v("tools::wroot::StreamerInfo");
return s_v;
}
public: //ibo
virtual const std::string& store_cls() const {
static const std::string s_v("TStreamerInfo");
return s_v;
}
virtual bool stream(buffer& a_buffer) const {
unsigned int c;
if(!a_buffer.write_version(2,c)) return false;
if(!Named_stream(a_buffer,fName,fTitle)) return false;
if(!a_buffer.write(fCheckSum)) return false;
if(!a_buffer.write(fStreamedClassVersion)) return false;
//ObjArray
if(!a_buffer.write_object(fElements)) return false;
if(!a_buffer.set_byte_count(c)) return false;
return true;
}
public:
virtual void out(std::ostream& a_out) const {
a_out << "StreamerInfo for class :"
<< " " << fName << ", version=" << fStreamedClassVersion
<< std::endl;
std::vector<streamer_element*>::const_iterator it;
for(it=fElements.begin();it!=fElements.end();++it) {
(*it)->out(a_out);
}
}
public:
StreamerInfo(const std::string& a_cls_store_name,
int a_cls_vers,
unsigned int a_cls_check_sum)
:fName(a_cls_store_name)
,fTitle("")
,fCheckSum(a_cls_check_sum)
,fStreamedClassVersion(a_cls_vers)
{
#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)
: ibo(a_from)
,fName(a_from.fName)
,fTitle(a_from.fName)
,fCheckSum(a_from.fCheckSum)
,fStreamedClassVersion(a_from.fStreamedClassVersion)
,fElements(a_from.fElements)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
StreamerInfo& operator=(const StreamerInfo& a_from){
fName = a_from.fName;
fTitle = a_from.fName;
fCheckSum = a_from.fCheckSum;
fStreamedClassVersion = a_from.fStreamedClassVersion;
fElements = a_from.fElements;
return *this;
}
public:
void add(streamer_element* a_elem){fElements.push_back(a_elem);}
protected: //Named
std::string fName;
std::string fTitle;
protected:
unsigned int fCheckSum; //checksum of original class
int fStreamedClassVersion; //Class version identifier
//int fNumber; //!Unique identifier
ObjArray<streamer_element> fElements; //Array of TStreamerElements
};
}}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,29 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_iobject
#define tools_wroot_iobject
#include <string>
namespace tools {
namespace wroot {
class buffer;
}}
namespace tools {
namespace wroot {
class iobject {
public:
virtual ~iobject() {}
public:
virtual const std::string& name() const = 0;
virtual const std::string& title() const = 0;
virtual const std::string& store_class_name() const = 0;
virtual bool stream(buffer&) const = 0;
};
}}
#endif
@@ -0,0 +1,29 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_itree
#define tools_wroot_itree
#include "../typedefs"
namespace tools {
namespace wroot {
class idir;
}}
namespace tools {
namespace wroot {
class itree {
public:
virtual ~itree(){}
public:
virtual void add_tot_bytes(uint32) = 0;
virtual void add_zip_bytes(uint32) = 0;
virtual idir& dir() = 0;
virtual const idir& dir() const = 0;
};
}}
#endif
@@ -0,0 +1,290 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_wroot_key
#define tools_wroot_key
#include "seek"
#include "date"
#include "ifile"
#include "wbuf"
#ifdef TOOLS_MEM
#include "../mem"
#endif
#include <ostream>
namespace tools {
namespace wroot {
class key {
static uint32 class_version() {return 2;}
static uint32 START_BIG_FILE() {return 2000000000;}
static const std::string& s_class() {
static const std::string s_v("tools::wroot::key");
return s_v;
}
public:
static unsigned int 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,
seek a_seek_parent_dir,
const std::string& a_object_name,
const std::string& a_object_title,
const std::string& a_object_class,
uint32 a_object_size) //uncompressed data size.
:m_file(a_file)
,m_buf_size(0)
,m_buffer(0)
// Record :
,m_nbytes(0)
,m_version(class_version())
,m_object_size(a_object_size)
,m_date(0)
,m_key_length(0)
,m_cycle(0)
,m_seek_key(0)
,m_seek_parent_dir(0)
,m_object_class(a_object_class)
,m_object_name(a_object_name)
,m_object_title(a_object_title)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
if(a_object_size) {
if(m_file.END()>START_BIG_FILE()) m_version += 1000;
}
if(m_version>1000) {
} else {
if(a_seek_parent_dir>START_BIG_FILE()) m_version += 1000;
}
m_key_length = record_size(m_version);
initialize(a_object_size);
m_seek_parent_dir = a_seek_parent_dir;
}
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){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
key& operator=(const key &){return *this;}
public:
uint16 cycle() const {return m_cycle;}
void set_cycle(uint16 a_cycle) {m_cycle = a_cycle;}
const std::string& object_name() const {return m_object_name;}
std::string object_name() {return m_object_name;}
const std::string& object_class() const {return m_object_class;}
std::string object_class() {return m_object_class;}
bool write_self() {
char* buffer = m_buffer;
wbuf wb(m_file.out(),m_file.byte_swap(),eob(),buffer);
return to_buffer(wb);
}
bool write_file(uint32& a_nbytes){
if(!m_file.set_pos(m_seek_key)) {
a_nbytes = 0;
return false;
}
if(!m_file.write_buffer(m_buffer,m_nbytes)) {
a_nbytes = 0;
return false;
}
if(m_file.verbose()) {
m_file.out() << "tools::wroot::key::write_file :"
<< " writing " << m_nbytes << " bytes"
<< " at address " << m_seek_key
<< " for ID=" << sout(m_object_name)
<< " Title=" << sout(m_object_title) << "."
<< std::endl;
}
delete [] m_buffer; //???
m_buffer = 0;
m_buf_size = 0;
a_nbytes = m_nbytes;
return true;
}
void set_number_of_bytes(uint32 a_n) {m_nbytes = a_n;}
uint32 number_of_bytes() const {return m_nbytes;}
uint32 object_size() const {return m_object_size;}
seek seek_key() const {return m_seek_key;}
short key_length() const {return m_key_length;}
char* data_buffer() {return m_buffer + m_key_length;}
const char* eob() const {return m_buffer + m_buf_size;}
bool to_buffer(wbuf& a_wb) const {
if(!a_wb.write(m_nbytes)) return false;
short version = m_version;
if(!a_wb.write(version)) return false;
if(!a_wb.write(m_object_size)) return false;
unsigned int _date = 0; //FIXME
if(!a_wb.write(_date)) return false;
if(!a_wb.write(m_key_length)) return false;
if(!a_wb.write(m_cycle)) return false;
if(version>1000) {
if(!a_wb.write(m_seek_key)) return false;
if(!a_wb.write(m_seek_parent_dir)) return false;
} else {
if(m_seek_key>START_BIG_FILE()) {
m_file.out() << "tools::wroot::key::to_buffer :"
<< " attempt to write big seek "
<< m_seek_key << " on 32 bits."
<< std::endl;
return false;
}
if(!a_wb.write((seek32)m_seek_key)) return false;
if(m_seek_parent_dir>START_BIG_FILE()) {
m_file.out() << "tools::wroot::key::to_buffer :"
<< " (2) attempt to write big seek "
<< m_seek_parent_dir << " on 32 bits."
<< std::endl;
return false;
}
if(!a_wb.write((seek32)m_seek_parent_dir)) return false;
}
if(!a_wb.write(m_object_class)) return false;
if(!a_wb.write(m_object_name)) return false;
if(!a_wb.write(m_object_title)) return false;
if(m_file.verbose()) {
m_file.out() << "tools::wroot::key::to_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;
}
protected:
static std::string sout(const std::string& a_string) {
return std::string("\"")+a_string+"\"";
}
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);
nbytes += sizeof(m_object_size);
nbytes += sizeof(date);
nbytes += sizeof(m_key_length);
nbytes += sizeof(m_cycle);
if(a_version>1000) {
nbytes += sizeof(seek);
nbytes += sizeof(seek);
} else {
nbytes += sizeof(seek32);
nbytes += sizeof(seek32);
}
nbytes += std_string_record_size(m_object_class);
nbytes += std_string_record_size(m_object_name);
nbytes += std_string_record_size(m_object_title);
return nbytes;
}
bool initialize(uint32 a_nbytes) {
uint32 nsize = m_key_length+a_nbytes;
m_date = get_date();
if(a_nbytes) {//GB
m_seek_key = m_file.END();
m_file.set_END(m_seek_key+nsize);
//NOTE : the free segment logic found in ROOT/TKey
// is not yet needed right now for us, since
// we always write at end of file. The update
// of the eof free_seg is done in set_END.
} else { //basket
m_seek_key = 0;
}
delete [] m_buffer;
m_buffer = new char[nsize];
m_buf_size = nsize;
m_nbytes = nsize;
return true;
}
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 //
// //
//////////////////////////////////////////////////////////////////////////

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