Import Geant4 10.0.0 source tree
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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){
|
||||
// > : <
|
||||
// < : >
|
||||
// & : &
|
||||
// " : "
|
||||
// ' : '
|
||||
std::string s = a_string;
|
||||
replace(s,"<","<");
|
||||
replace(s,">",">");
|
||||
replace(s,"&","&");
|
||||
replace(s,"\"",""");
|
||||
replace(s,"'","'");
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -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
Reference in New Issue
Block a user