930 lines
31 KiB
Plaintext
930 lines
31 KiB
Plaintext
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
|
// See the file tools.license for terms.
|
|
|
|
#ifndef tools_hdf5_ntuple
|
|
#define tools_hdf5_ntuple
|
|
|
|
#include "store"
|
|
|
|
#include <tools/vfind>
|
|
#include <tools/vmanip>
|
|
#include <tools/ntuple_binding>
|
|
#include <tools/ntuple_booking>
|
|
#include <tools/sout>
|
|
#include <tools/scast>
|
|
#include <tools/forit>
|
|
#include <tools/stype>
|
|
#include <tools/mnmx>
|
|
#include <tools/vdata>
|
|
|
|
#ifdef TOOLS_MEM
|
|
#include <tools/mem>
|
|
#include <tools/stype>
|
|
#endif
|
|
|
|
namespace tools {
|
|
namespace hdf5 {
|
|
|
|
class ntuple : public store {
|
|
public:
|
|
class icol {
|
|
public:
|
|
virtual ~icol(){}
|
|
public:
|
|
virtual void* cast(tools::cid) const = 0;
|
|
virtual tools::cid id_cls() const = 0;
|
|
public:
|
|
virtual bool set_basket_size(size_t a_size) = 0;
|
|
virtual bool add() = 0;
|
|
virtual bool fetch_entry() = 0;
|
|
virtual const std::string& name() const = 0;
|
|
virtual void reset() = 0;
|
|
};
|
|
public:
|
|
|
|
template <class T>
|
|
class column_ref : public virtual icol {
|
|
#ifdef TOOLS_MEM
|
|
static const std::string& s_class() {
|
|
static const std::string s_v("tools::hdf5::ntuple::column_ref<"+tools::stype(T())+">");
|
|
return s_v;
|
|
}
|
|
#endif
|
|
public:
|
|
static tools::cid id_class() {
|
|
static const T s_v = T(); //do that for T = std::string.
|
|
return tools::_cid(s_v)+10000;
|
|
}
|
|
virtual void* cast(tools::cid a_class) const {
|
|
if(void* p = tools::cmp_cast<column_ref>(this,a_class)) {return p;}
|
|
else return 0;
|
|
}
|
|
virtual tools::cid id_cls() const {return id_class();}
|
|
public: //icol
|
|
virtual bool add() { //write.
|
|
if(!m_write) return false;
|
|
if(m_basket_pos>=m_basket_size) {
|
|
if(!m_branch.write_page<T>(m_basket_size,m_basket)) {
|
|
m_store.out() << "tools::hdf5::ntuple::column_ref::add : write_page() failed." << std::endl;
|
|
m_basket_pos = 0;
|
|
return false;
|
|
}
|
|
m_basket_pos = 0;
|
|
if(m_want_new_basket_size) {
|
|
delete [] m_basket;
|
|
m_basket = new T[m_want_new_basket_size];
|
|
m_basket_pos = 0;
|
|
m_basket_size = m_want_new_basket_size;
|
|
m_want_new_basket_size = 0;
|
|
}
|
|
}
|
|
m_basket[m_basket_pos] = m_ref;
|
|
m_basket_pos++;
|
|
return true;
|
|
}
|
|
virtual bool fetch_entry() { //read.
|
|
if(m_write) return false;
|
|
if(m_basket_pos>=m_basket_end) { //we need more data.
|
|
if(m_branch.pos()>=m_branch.entries()) {
|
|
m_store.out() << "tools::hdf5::ntuple::column_ref:fetch_entry : no more data." << std::endl;
|
|
m_basket_pos = 0;
|
|
m_basket_end = 0;
|
|
return false;
|
|
}
|
|
if(m_want_new_basket_size) {
|
|
delete [] m_basket;
|
|
m_basket = new T[m_want_new_basket_size];
|
|
m_basket_pos = 0;
|
|
m_basket_size = m_want_new_basket_size;
|
|
m_want_new_basket_size = 0;
|
|
}
|
|
tools::uint64 remain = m_branch.entries()-m_branch.pos();
|
|
size_t n = tools::mn<size_t>((size_t)remain,m_basket_size);
|
|
if(!m_branch.read_page<T>(n,m_basket)) {
|
|
m_store.out() << "tools::hdf5::ntuple::column_ref:fetch_entry : read_page() failed." << std::endl;
|
|
m_basket_pos = 0;
|
|
m_basket_end = 0;
|
|
return false;
|
|
}
|
|
m_basket_pos = 0;
|
|
m_basket_end = n;
|
|
}
|
|
m_ref = m_basket[m_basket_pos];
|
|
m_basket_pos++;
|
|
return true;
|
|
}
|
|
virtual void reset() {m_branch.reset_pos();}
|
|
virtual const std::string& name() const {return m_name;}
|
|
virtual bool set_basket_size(size_t a_size) {
|
|
if(!a_size) return false;
|
|
m_want_new_basket_size = a_size;
|
|
return true;
|
|
}
|
|
public:
|
|
column_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size,T& a_ref)
|
|
:m_store(a_store)
|
|
,m_branch(a_pages)
|
|
,m_write(a_write)
|
|
,m_name(a_name)
|
|
,m_ref(a_ref)
|
|
,m_basket_size(a_basket_size?a_basket_size:32000)
|
|
,m_basket_pos(0)
|
|
,m_basket_end(0) //read.
|
|
,m_basket(0)
|
|
,m_want_new_basket_size(0)
|
|
{
|
|
#ifdef TOOLS_MEM
|
|
tools::mem::increment(s_class().c_str());
|
|
#endif
|
|
m_basket = new T[m_basket_size];
|
|
if(m_write) {
|
|
} else { //read.
|
|
size_t n = tools::mn<size_t>((size_t)m_branch.entries(),m_basket_size);
|
|
if(!m_branch.read_page<T>(n,m_basket)) {
|
|
m_store.out() << "tools::hdf5::ntuple::column_ref:column_ref : read_page() failed." << std::endl;
|
|
m_basket_pos = 0;
|
|
m_basket_end = 0;
|
|
return;
|
|
}
|
|
m_basket_pos = 0;
|
|
m_basket_end = n;
|
|
}
|
|
}
|
|
virtual ~column_ref(){
|
|
if(m_write && m_basket_pos) {
|
|
if(!m_branch.write_page<T>(m_basket_pos,m_basket)) {
|
|
m_store.out() << "tools::hdf5::ntuple::column_ref::~column_ref : write_page() failed." << std::endl;
|
|
}
|
|
}
|
|
delete [] m_basket;
|
|
#ifdef TOOLS_MEM
|
|
tools::mem::decrement(s_class().c_str());
|
|
#endif
|
|
}
|
|
protected:
|
|
column_ref(const column_ref& a_from)
|
|
:icol(a_from)
|
|
,m_store(a_from.m_store)
|
|
,m_branch(a_from.m_branch)
|
|
,m_write(a_from.m_write)
|
|
,m_name(a_from.m_name)
|
|
,m_ref(a_from.m_ref)
|
|
,m_basket_size(a_from.m_basket_size)
|
|
,m_basket_pos(0)
|
|
,m_basket_end(0)
|
|
,m_basket(0)
|
|
,m_want_new_basket_size(0)
|
|
{}
|
|
column_ref& operator=(const column_ref& a_from){
|
|
if(&a_from==this) return *this;
|
|
m_name = a_from.m_name;
|
|
m_basket_size = a_from.m_basket_size;
|
|
m_basket_pos = 0;
|
|
m_basket_end = 0;
|
|
m_want_new_basket_size = 0;
|
|
return *this;
|
|
}
|
|
protected:
|
|
store& m_store;
|
|
pages& m_branch;
|
|
bool m_write;
|
|
std::string m_name;
|
|
T& m_ref;
|
|
size_t m_basket_size;
|
|
size_t m_basket_pos;
|
|
size_t m_basket_end;
|
|
T* m_basket;
|
|
size_t m_want_new_basket_size;
|
|
};
|
|
|
|
template <class T>
|
|
class column : public column_ref<T> {
|
|
typedef column_ref<T> parent;
|
|
#ifdef TOOLS_MEM
|
|
static const std::string& s_class() {
|
|
static const std::string s_v("tools::hdf5::ntuple::column<"+tools::stype(T())+">");
|
|
return s_v;
|
|
}
|
|
#endif
|
|
public:
|
|
static tools::cid id_class() {
|
|
static const T s_v = T(); //do that for T = std::string.
|
|
return tools::_cid(s_v);
|
|
}
|
|
virtual void* cast(tools::cid a_class) const {
|
|
if(void* p = tools::cmp_cast<column>(this,a_class)) {return p;}
|
|
else return 0;
|
|
}
|
|
virtual tools::cid id_cls() const {return id_class();}
|
|
public:
|
|
column(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size)
|
|
:parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp)
|
|
,m_tmp(T())
|
|
{
|
|
#ifdef TOOLS_MEM
|
|
tools::mem::increment(s_class().c_str());
|
|
#endif
|
|
}
|
|
virtual ~column(){
|
|
#ifdef TOOLS_MEM
|
|
tools::mem::decrement(s_class().c_str());
|
|
#endif
|
|
}
|
|
protected:
|
|
column(const column& a_from)
|
|
:icol(a_from)
|
|
,parent(a_from)
|
|
,m_tmp(a_from.m_tmp)
|
|
{}
|
|
column& operator=(const column& a_from){
|
|
if(&a_from==this) return *this;
|
|
parent::operator=(a_from);
|
|
m_tmp = a_from.m_tmp;
|
|
return *this;
|
|
}
|
|
public:
|
|
bool fill(const T& a_value) {m_tmp = a_value;return true;} //write.
|
|
bool get_entry(T& a_v) const {a_v = m_tmp;return true;} //read.
|
|
protected:
|
|
T m_tmp;
|
|
};
|
|
|
|
TOOLS_CLASS_STRING_VALUE(vector_char,vector<char>)
|
|
TOOLS_CLASS_STRING_VALUE(vector_short,vector<short>)
|
|
TOOLS_CLASS_STRING_VALUE(vector_int,vector<int>)
|
|
TOOLS_CLASS_STRING_VALUE(vector_float,vector<float>)
|
|
TOOLS_CLASS_STRING_VALUE(vector_double,vector<double>)
|
|
|
|
TOOLS_CLASS_STRING_VALUE(string,string)
|
|
|
|
TOOLS_CLASS_STRING_VALUE(vector_int64,vector<tools::int64>)
|
|
TOOLS_CLASS_STRING_VALUE(vector_uchar,vector<tools::uchar>)
|
|
TOOLS_CLASS_STRING_VALUE(vector_ushort,vector<tools::ushort>)
|
|
TOOLS_CLASS_STRING_VALUE(vector_uint32,vector<tools::uint32>)
|
|
TOOLS_CLASS_STRING_VALUE(vector_uint64,vector<tools::uint64>)
|
|
|
|
template <class T>
|
|
class std_vector_column_ref : public column<unsigned int> {
|
|
typedef column<unsigned int> parent;
|
|
#ifdef TOOLS_MEM
|
|
static const std::string& s_class() {
|
|
static const std::string s_v("tools::hdf5::ntuple::std_vector_column_ref<"+tools::stype(T())+">");
|
|
return s_v;
|
|
}
|
|
#endif
|
|
public:
|
|
static tools::cid id_class() {return tools::_cid_std_vector<T>()+10000;}
|
|
virtual void* cast(tools::cid a_class) const {
|
|
if(void* p = tools::cmp_cast<std_vector_column_ref>(this,a_class)) {return p;}
|
|
else return 0;
|
|
}
|
|
virtual tools::cid id_cls() const {return id_class();}
|
|
public: //icol
|
|
virtual void reset() {
|
|
m_branch.reset_pos();
|
|
m_data_pages.reset_pos();
|
|
}
|
|
virtual bool add() { //write.
|
|
if(!m_write) return false;
|
|
if(m_ref.size()) {
|
|
const T* _data = tools::vec_data(m_ref);
|
|
if(!m_data_pages.write_page<T>(m_ref.size(),(void*)_data)) return false;
|
|
}
|
|
if(!parent::fill((unsigned int)m_ref.size())) return false;
|
|
if(!parent::add()) return false;
|
|
return true;
|
|
}
|
|
virtual bool fetch_entry() { //read.
|
|
if(m_write) return false;
|
|
if(!parent::fetch_entry()) return false;
|
|
unsigned int sz;
|
|
if(!parent::get_entry(sz)) return false;
|
|
m_ref.resize(sz,T());
|
|
if(sz) {
|
|
T* _data = tools::vec_data(m_ref);
|
|
if(!m_data_pages.read_page<T>(sz,_data)) {m_ref.clear();return false;}
|
|
}
|
|
return true;
|
|
}
|
|
virtual const std::string& name() const {return m_name;}
|
|
virtual bool set_basket_size(size_t /*a_size*/) {
|
|
//m_branch->set_basket_size(a_size);
|
|
return true;
|
|
}
|
|
public:
|
|
std_vector_column_ref(store& a_store,pages& a_pages,bool a_write,
|
|
const std::string& a_name,size_t a_basket_size,
|
|
std::vector<T>& a_ref)
|
|
:parent(a_store,a_pages,a_write,a_name,a_basket_size)
|
|
,m_ref(a_ref)
|
|
,m_data_pages(a_store.out(),a_store.group(),a_name+"_data",tools::stype(T()),a_write,a_store.compress_level())
|
|
{
|
|
#ifdef TOOLS_MEM
|
|
tools::mem::increment(s_class().c_str());
|
|
#endif
|
|
if(!m_data_pages.is_valid()) {
|
|
m_store.out() << "tools::hdf5::std_vector_column_ref::std_vector_column_ref :"
|
|
<< " can't create data pages." << std::endl;
|
|
}
|
|
}
|
|
virtual ~std_vector_column_ref(){
|
|
#ifdef TOOLS_MEM
|
|
tools::mem::decrement(s_class().c_str());
|
|
#endif
|
|
}
|
|
protected:
|
|
std_vector_column_ref(const std_vector_column_ref& a_from)
|
|
:icol(a_from)
|
|
,parent(a_from)
|
|
,m_ref(a_from.m_ref)
|
|
,m_data_pages(a_from.m_store.out(),a_from.m_store.group(),a_from.m_name+"_data",
|
|
tools::stype(T()),a_from.m_write,a_from.m_store.compress_level())
|
|
{}
|
|
std_vector_column_ref& operator=(const std_vector_column_ref& a_from){
|
|
if(&a_from==this) return *this;
|
|
m_name = a_from.m_name;
|
|
return *this;
|
|
}
|
|
public:
|
|
//const std::vector<T>& ref() const {return m_ref;}
|
|
protected:
|
|
std::vector<T>& m_ref;
|
|
pages m_data_pages;
|
|
};
|
|
|
|
template <class T>
|
|
class std_vector_column : public std_vector_column_ref<T> {
|
|
typedef std_vector_column_ref<T> parent;
|
|
#ifdef TOOLS_MEM
|
|
static const std::string& s_class() {
|
|
static const std::string s_v("tools::hdf5::ntuple::std_vector_column<"+tools::stype(T())+">");
|
|
return s_v;
|
|
}
|
|
#endif
|
|
public:
|
|
static tools::cid id_class() {return tools::_cid_std_vector<T>();}
|
|
virtual void* cast(tools::cid a_class) const {
|
|
if(void* p = tools::cmp_cast<std_vector_column>(this,a_class)) {return p;}
|
|
else return 0;
|
|
}
|
|
virtual tools::cid id_cls() const {return id_class();}
|
|
public:
|
|
std_vector_column(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size)
|
|
:parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp)
|
|
{}
|
|
virtual ~std_vector_column(){}
|
|
protected:
|
|
std_vector_column(const std_vector_column& a_from)
|
|
:icol(a_from)
|
|
,parent(a_from)
|
|
{}
|
|
std_vector_column& operator=(const std_vector_column& a_from){
|
|
parent::operator=(a_from);
|
|
return *this;
|
|
}
|
|
public:
|
|
//bool get_entry(std::vector<T>& a_v) const {
|
|
// a_v = m_tmp;
|
|
// return true;
|
|
//}
|
|
const std::vector<T>& data() const {return m_tmp;}
|
|
protected:
|
|
std::vector<T> m_tmp;
|
|
};
|
|
|
|
class column_string_ref : public column<unsigned int> {
|
|
typedef column<unsigned int> parent;
|
|
#ifdef TOOLS_MEM
|
|
TOOLS_SCLASS(tools::hdf5::ntuple::column_string_ref)
|
|
#endif
|
|
public:
|
|
static tools::cid id_class() {
|
|
static const std::string s_v;
|
|
return tools::_cid(s_v)+10000;
|
|
}
|
|
virtual void* cast(tools::cid a_class) const {
|
|
if(void* p = tools::cmp_cast<column_string_ref>(this,a_class)) {return p;}
|
|
else return 0;
|
|
}
|
|
virtual tools::cid id_cls() const {return id_class();}
|
|
public: //icol
|
|
virtual void reset() {
|
|
m_branch.reset_pos();
|
|
m_data_pages.reset_pos();
|
|
}
|
|
virtual bool add() { //write.
|
|
if(!m_write) return false;
|
|
if(m_ref.size()) {
|
|
const char* _data = m_ref.c_str();
|
|
if(!m_data_pages.write_page<char>(m_ref.size(),(void*)_data)) return false;
|
|
}
|
|
if(!parent::fill((unsigned int)m_ref.size())) return false;
|
|
if(!parent::add()) return false;
|
|
return true;
|
|
}
|
|
virtual bool fetch_entry() { //read.
|
|
if(m_write) return false;
|
|
if(!parent::fetch_entry()) return false;
|
|
unsigned int sz;
|
|
if(!parent::get_entry(sz)) return false;
|
|
m_ref.resize(sz);
|
|
if(sz) {
|
|
char* _data = (char*)m_ref.c_str();
|
|
if(!m_data_pages.read_page<char>(sz,_data)) {m_ref.clear();return false;}
|
|
}
|
|
return true;
|
|
}
|
|
virtual const std::string& name() const {return m_name;}
|
|
virtual bool set_basket_size(size_t /*a_size*/) {
|
|
//m_branch->set_basket_size(a_size);
|
|
return true;
|
|
}
|
|
public:
|
|
column_string_ref(store& a_store,pages& a_pages,bool a_write,
|
|
const std::string& a_name,size_t a_basket_size,
|
|
std::string& a_ref)
|
|
:parent(a_store,a_pages,a_write,a_name,a_basket_size)
|
|
,m_ref(a_ref)
|
|
,m_data_pages(a_store.out(),a_store.group(),a_name+"_data",tools::stype(char()),a_write,a_store.compress_level())
|
|
{
|
|
#ifdef TOOLS_MEM
|
|
tools::mem::increment(s_class().c_str());
|
|
#endif
|
|
if(!m_data_pages.is_valid()) {
|
|
m_store.out() << "tools::hdf5::column_string_ref::column_string_ref :"
|
|
<< " can't create data pages." << std::endl;
|
|
}
|
|
}
|
|
virtual ~column_string_ref(){
|
|
#ifdef TOOLS_MEM
|
|
tools::mem::decrement(s_class().c_str());
|
|
#endif
|
|
}
|
|
protected:
|
|
column_string_ref(const column_string_ref& a_from)
|
|
:icol(a_from)
|
|
,parent(a_from)
|
|
,m_ref(a_from.m_ref)
|
|
,m_data_pages(a_from.m_store.out(),a_from.m_store.group(),a_from.m_name+"_data",
|
|
tools::stype(char()),a_from.m_write,a_from.m_store.compress_level())
|
|
{}
|
|
column_string_ref& operator=(const column_string_ref& a_from){
|
|
if(&a_from==this) return *this;
|
|
m_name = a_from.m_name;
|
|
return *this;
|
|
}
|
|
public:
|
|
//const std::string& ref() const {return m_ref;}
|
|
protected:
|
|
std::string& m_ref;
|
|
pages m_data_pages;
|
|
};
|
|
|
|
class column_string : public column_string_ref {
|
|
typedef column_string_ref parent;
|
|
#ifdef TOOLS_MEM
|
|
TOOLS_SCLASS(tools::hdf5::ntuple::column_string)
|
|
#endif
|
|
public:
|
|
static tools::cid id_class() {
|
|
static const std::string s_v;
|
|
return tools::_cid(s_v);
|
|
}
|
|
virtual void* cast(tools::cid a_class) const {
|
|
if(void* p = tools::cmp_cast<column_string>(this,a_class)) {return p;}
|
|
else return 0;
|
|
}
|
|
virtual tools::cid id_cls() const {return id_class();}
|
|
public:
|
|
column_string(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,tools::uint32 a_basket_size)
|
|
:parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp)
|
|
{
|
|
#ifdef TOOLS_MEM
|
|
tools::mem::increment(s_class().c_str());
|
|
#endif
|
|
}
|
|
virtual ~column_string(){
|
|
#ifdef TOOLS_MEM
|
|
tools::mem::decrement(s_class().c_str());
|
|
#endif
|
|
}
|
|
protected:
|
|
column_string(const column_string& a_from)
|
|
:icol(a_from)
|
|
,parent(a_from)
|
|
{}
|
|
column_string& operator=(const column_string& a_from){
|
|
if(&a_from==this) return *this;
|
|
parent::operator=(a_from);
|
|
return *this;
|
|
}
|
|
public:
|
|
bool fill(const std::string& a_value) {m_tmp = a_value;return true;}
|
|
bool get_entry(std::string& a_value) const {a_value = m_tmp;return true;}
|
|
protected:
|
|
std::string m_tmp;
|
|
};
|
|
|
|
public:
|
|
ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name,
|
|
unsigned int a_compress,size_t /*a_basket_size*//* = 32000*/)
|
|
:store(a_out,a_group,a_name,true,a_compress) //true=write
|
|
{}
|
|
|
|
ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name)
|
|
:store(a_out,a_group,a_name,false,0) //false=read
|
|
{
|
|
tools_vforcit(pages*,m_pagess,it){
|
|
|
|
#define TOOLS_HDF5_NTUPLE_READ_CREATE_COL(a__type) \
|
|
if((*it)->form()==tools::stype(a__type())) {\
|
|
column<a__type>* col = new column<a__type>(*this,*(*it),false,(*it)->name(),0);\
|
|
if(!col) {tools::safe_clear<icol>(m_cols);return;}\
|
|
m_cols.push_back(col);\
|
|
}
|
|
|
|
#define TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(a__vec_type,a__type) \
|
|
if((*it)->form()==s_vector_##a__vec_type()) {\
|
|
std_vector_column<a__type>* col = new std_vector_column<a__type>(*this,*(*it),false,(*it)->name(),0);\
|
|
if(!col) {tools::safe_clear<icol>(m_cols);return;}\
|
|
m_cols.push_back(col);\
|
|
}
|
|
|
|
TOOLS_HDF5_NTUPLE_READ_CREATE_COL(char)
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(short)
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(int)
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(tools::int64)
|
|
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(float)
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(double)
|
|
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(tools::byte)
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(tools::ushort)
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(tools::uint32)
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(tools::uint64)
|
|
|
|
//else TOOLS_HDF5_NTUPLE_READ_CREATE_COL(bool) //use byte=uchar.
|
|
|
|
else
|
|
if((*it)->form()==s_string()) {
|
|
column_string* col = new column_string(*this,*(*it),false,(*it)->name(),0);
|
|
if(!col) {tools::safe_clear<icol>(m_cols);return;}
|
|
m_cols.push_back(col);
|
|
}
|
|
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(char,char)
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(short,short)
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(int,int)
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(int64,tools::int64)
|
|
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(float,float)
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(double,double)
|
|
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(uchar,tools::uchar)
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(ushort,tools::ushort)
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(uint32,tools::uint32)
|
|
else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(uint64,tools::uint64)
|
|
|
|
// else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(std::string)
|
|
// else TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL(bool) //use byte=uchar.
|
|
|
|
else {
|
|
m_out << "tools::hdf5::ntuple::ntuple(read) :"
|
|
<< " for column " << tools::sout((*it)->name())
|
|
<< ", type " << tools::sout((*it)->form()) << " not yet handled."
|
|
<< std::endl;
|
|
//throw
|
|
tools::safe_clear<icol>(m_cols);
|
|
return;
|
|
}
|
|
}
|
|
#undef TOOLS_HDF5_NTUPLE_READ_CREATE_VEC_COL
|
|
#undef TOOLS_HDF5_NTUPLE_READ_CREATE_COL
|
|
}
|
|
|
|
ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name,const tools::ntuple_binding& a_bd)
|
|
:store(a_out,a_group,a_name,false,0) //false=read
|
|
{
|
|
if(!initialize(a_out,a_bd)) {}
|
|
}
|
|
|
|
ntuple(std::ostream& a_out,hid_t a_group,const tools::ntuple_booking& a_bkg,
|
|
unsigned int a_compress,size_t a_basket_size/* = 32000*/)
|
|
:store(a_out,a_group,a_bkg.name(),true,a_compress) //true=write
|
|
,m_title(a_bkg.title())
|
|
{
|
|
const std::vector<tools::column_booking>& cols = a_bkg.columns();
|
|
tools_vforcit(tools::column_booking,cols,it){
|
|
|
|
#define TOOLS_HDF5_NTUPLE_CREATE_COL(a__type) \
|
|
if((*it).cls_id()==tools::_cid(a__type())) {\
|
|
a__type* user = (a__type*)(*it).user_obj();\
|
|
if(user) {\
|
|
if(!create_column_ref<a__type>((*it).name(),a_basket_size,*user)) {\
|
|
m_out << "tools::hdf5::ntuple :"\
|
|
<< " can't create column_ref " << tools::sout((*it).name()) << "."\
|
|
<< std::endl;\
|
|
tools::safe_clear<icol>(m_cols);\
|
|
return;\
|
|
}\
|
|
} else {\
|
|
if(!create_column<a__type>((*it).name(),a_basket_size)) {\
|
|
m_out << "tools::hdf5::ntuple :"\
|
|
<< " can't create column " << tools::sout((*it).name()) << "."\
|
|
<< std::endl;\
|
|
tools::safe_clear<icol>(m_cols);\
|
|
return;\
|
|
}\
|
|
}\
|
|
}
|
|
|
|
#define TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(a__type) \
|
|
if((*it).cls_id()==tools::_cid_std_vector<a__type>()) {\
|
|
std::vector<a__type>* vec = (std::vector<a__type>*)(*it).user_obj();\
|
|
if(!vec) {\
|
|
m_out << "tools::hdf5::ntuple :"\
|
|
<< " for std::vector column " << tools::sout((*it).name())\
|
|
<< ", the user vector pointer is null."\
|
|
<< std::endl;\
|
|
tools::safe_clear<icol>(m_cols);\
|
|
return;\
|
|
}\
|
|
if(!create_std_column_ref<a__type>((*it).name(),a_basket_size,*vec)) {\
|
|
m_out << "tools::hdf5::ntuple :"\
|
|
<< " can't create std::vector column " << tools::sout((*it).name()) << "."\
|
|
<< std::endl;\
|
|
tools::safe_clear<icol>(m_cols);\
|
|
return;\
|
|
}\
|
|
}
|
|
|
|
TOOLS_HDF5_NTUPLE_CREATE_COL(char)
|
|
else TOOLS_HDF5_NTUPLE_CREATE_COL(short)
|
|
else TOOLS_HDF5_NTUPLE_CREATE_COL(int)
|
|
else TOOLS_HDF5_NTUPLE_CREATE_COL(tools::int64)
|
|
|
|
else TOOLS_HDF5_NTUPLE_CREATE_COL(float)
|
|
else TOOLS_HDF5_NTUPLE_CREATE_COL(double)
|
|
|
|
else TOOLS_HDF5_NTUPLE_CREATE_COL(tools::byte)
|
|
else TOOLS_HDF5_NTUPLE_CREATE_COL(tools::ushort)
|
|
else TOOLS_HDF5_NTUPLE_CREATE_COL(tools::uint32)
|
|
else TOOLS_HDF5_NTUPLE_CREATE_COL(tools::uint64)
|
|
|
|
//else TOOLS_HDF5_NTUPLE_CREATE_COL(bool) //use byte=uchar.
|
|
|
|
else if((*it).cls_id()==tools::_cid(std::string())) {
|
|
if(!create_column_string((*it).name(),a_basket_size)) {
|
|
m_out << "tools::hdf5::ntuple :"
|
|
<< " can't create string column " << tools::sout((*it).name()) << "."
|
|
<< std::endl;
|
|
tools::safe_clear<icol>(m_cols);
|
|
return;
|
|
}
|
|
|
|
} else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(char)
|
|
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(short)
|
|
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(int)
|
|
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(tools::int64)
|
|
|
|
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(float)
|
|
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(double)
|
|
|
|
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(tools::uchar)
|
|
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(tools::ushort)
|
|
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(tools::uint32)
|
|
else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(tools::uint64)
|
|
|
|
// else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(std::string)
|
|
// else TOOLS_HDF5_NTUPLE_CREATE_VEC_COL(bool) //use byte=uchar.
|
|
|
|
else {
|
|
m_out << "tools::hdf5::ntuple :"
|
|
<< " for column " << tools::sout((*it).name())
|
|
<< ", type with cid " << (*it).cls_id() << " not yet handled."
|
|
<< std::endl;
|
|
tools::safe_clear<icol>(m_cols);
|
|
return;
|
|
}
|
|
}
|
|
#undef TOOLS_HDF5_NTUPLE_CREATE_COL
|
|
#undef TOOLS_HDF5_NTUPLE_CREATE_VEC_COL
|
|
|
|
}
|
|
|
|
virtual ~ntuple() {
|
|
tools::safe_clear<icol>(m_cols);
|
|
}
|
|
protected:
|
|
ntuple(const ntuple& a_from):store(a_from),m_title(a_from.m_title){}
|
|
ntuple& operator=(const ntuple&){return *this;}
|
|
public:
|
|
bool initialize(std::ostream& a_out,const tools::ntuple_binding& a_bd = tools::ntuple_binding()) {
|
|
tools::safe_clear<icol>(m_cols);
|
|
{tools_vforcit(pages*,m_pagess,it) (*it)->reset_pos();}
|
|
|
|
tools_vforcit(pages*,m_pagess,it) {
|
|
|
|
#define TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(a__type) \
|
|
if((*it)->form()==tools::stype(a__type())) {\
|
|
a__type* user_var = a_bd.find_variable<a__type>((*it)->name());\
|
|
if(user_var) {\
|
|
column_ref<a__type>* col = new column_ref<a__type>(*this,*(*it),false,(*it)->name(),0,*user_var);\
|
|
if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
|
|
m_cols.push_back(col);\
|
|
} else {\
|
|
column<a__type>* col = new column<a__type>(*this,*(*it),false,(*it)->name(),0);\
|
|
if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
|
|
m_cols.push_back(col);\
|
|
}\
|
|
}
|
|
|
|
#define TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(a__vec_type,a__type) \
|
|
if((*it)->form()==s_vector_##a__vec_type()) {\
|
|
std::vector<a__type>* user_var = a_bd.find_variable< std::vector<a__type> >((*it)->name());\
|
|
if(user_var) {\
|
|
std_vector_column_ref<a__type>* col = \
|
|
new std_vector_column_ref<a__type>(*this,*(*it),false,(*it)->name(),0,*user_var);\
|
|
if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
|
|
m_cols.push_back(col);\
|
|
} else {\
|
|
std_vector_column<a__type>* col = new std_vector_column<a__type>(*this,*(*it),false,(*it)->name(),0);\
|
|
if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
|
|
m_cols.push_back(col);\
|
|
}\
|
|
}
|
|
|
|
TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(char)
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(short)
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(int)
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::int64)
|
|
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(float)
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(double)
|
|
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::byte)
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::ushort)
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::uint32)
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::uint64)
|
|
|
|
//else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL(bool) //use byte=uchar.
|
|
|
|
else
|
|
if((*it)->form()==s_string()) {
|
|
std::string* user_var = a_bd.find_variable<std::string>((*it)->name());
|
|
if(user_var) {
|
|
column_string_ref* col = new column_string_ref(*this,*(*it),false,(*it)->name(),0,*user_var);
|
|
if(!col) {tools::safe_clear<icol>(m_cols);return false;}
|
|
m_cols.push_back(col);
|
|
} else {
|
|
column_string* col = new column_string(*this,*(*it),false,(*it)->name(),0);
|
|
if(!col) {tools::safe_clear<icol>(m_cols);return false;}
|
|
m_cols.push_back(col);
|
|
}
|
|
}
|
|
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(char,char)
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(short,short)
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(int,int)
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(int64,tools::int64)
|
|
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(float,float)
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(double,double)
|
|
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uchar,tools::uchar)
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(ushort,tools::ushort)
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uint32,tools::uint32)
|
|
else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uint64,tools::uint64)
|
|
|
|
// else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(std::string)
|
|
// else TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(bool) //use byte=uchar.
|
|
|
|
else {
|
|
a_out << "tools::hdf5::ntuple::ntuple(read with binding) :"
|
|
<< " for column " << tools::sout((*it)->name())
|
|
<< ", type " << tools::sout((*it)->form()) << " not yet handled."
|
|
<< std::endl;
|
|
tools::safe_clear<icol>(m_cols);
|
|
return false;
|
|
}
|
|
}
|
|
#undef TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_COL
|
|
#undef TOOLS_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL
|
|
return true;
|
|
}
|
|
|
|
const std::vector<icol*>& columns() const {return m_cols;}
|
|
std::vector<icol*>& columns() {return m_cols;}
|
|
|
|
template <class T>
|
|
column_ref<T>* create_column_ref(const std::string& a_name,size_t a_basket_size,T& a_user_var) {
|
|
if(tools::find_named<icol>(m_cols,a_name)) return 0;
|
|
pages* _pages = create_pages(a_name,tools::stype(T()));
|
|
if(!_pages) return 0;
|
|
column_ref<T>* col = new column_ref<T>(*this,*_pages,true,a_name,a_basket_size,a_user_var);
|
|
if(!col) return 0;
|
|
m_cols.push_back(col);
|
|
return col;
|
|
}
|
|
|
|
template <class T>
|
|
column<T>* create_column(const std::string& a_name,size_t a_basket_size) {
|
|
if(tools::find_named<icol>(m_cols,a_name)) return 0;
|
|
pages* _pages = create_pages(a_name,tools::stype(T()));
|
|
if(!_pages) return 0;
|
|
column<T>* col = new column<T>(*this,*_pages,true,a_name,a_basket_size);
|
|
if(!col) return 0;
|
|
m_cols.push_back(col);
|
|
return col;
|
|
}
|
|
|
|
column_string* create_column_string(const std::string& a_name,size_t a_basket_size) {
|
|
if(tools::find_named<icol>(m_cols,a_name)) return 0;
|
|
pages* _pages = create_pages(a_name,s_string());
|
|
if(!_pages) return 0;
|
|
column_string* col = new column_string(*this,*_pages,true,a_name,a_basket_size);
|
|
if(!col) return 0;
|
|
m_cols.push_back(col);
|
|
return col;
|
|
}
|
|
|
|
template <class T>
|
|
std_vector_column_ref<T>* create_std_column_ref(const std::string& a_name,size_t a_basket_size,std::vector<T>& a_user_vec) {
|
|
//NOTE : to optimize, we do not handle a default std::vector value logic.
|
|
if(tools::find_named<icol>(m_cols,a_name)) return 0;
|
|
pages* _pages = create_pages(a_name,"vector<"+tools::stype(T())+">");
|
|
if(!_pages) return 0;
|
|
std_vector_column_ref<T>* col = new std_vector_column_ref<T>(*this,*_pages,true,a_name,a_basket_size,a_user_vec);
|
|
if(!col) return 0;
|
|
m_cols.push_back(col);
|
|
return col;
|
|
}
|
|
|
|
template <class T>
|
|
column_ref<T>* find_column_ref(const std::string& a_name) {
|
|
icol* col = tools::find_named<icol>(m_cols,a_name);
|
|
if(!col) return 0;
|
|
return tools::id_cast<icol, column_ref<T> >(*col);
|
|
}
|
|
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::id_cast<icol, column<T> >(*col);
|
|
}
|
|
|
|
template <class T>
|
|
std_vector_column_ref<T>* find_std_vector_column_ref(const std::string& a_name) {
|
|
icol* col = tools::find_named<icol>(m_cols,a_name);
|
|
if(!col) return 0;
|
|
return tools::id_cast<icol, std_vector_column_ref<T> >(*col);
|
|
}
|
|
template <class T>
|
|
std_vector_column<T>* find_std_vector_column(const std::string& a_name) {
|
|
icol* col = tools::find_named<icol>(m_cols,a_name);
|
|
if(!col) return 0;
|
|
return tools::id_cast<icol, std_vector_column<T> >(*col);
|
|
}
|
|
|
|
column_string* find_column_string(const std::string& a_name) {
|
|
icol* col = tools::find_named<icol>(m_cols,a_name);
|
|
if(!col) return 0;
|
|
return tools::id_cast<icol, column_string >(*col);
|
|
}
|
|
|
|
bool add_row() { //write.
|
|
if(m_cols.empty()) return false;
|
|
bool status = true;
|
|
tools_vforit(icol*,m_cols,it) {if(!(*it)->add()) status = false;}
|
|
//tools::uint32 n;
|
|
//bool status = store::fill(n);
|
|
//tools_vforit(icol*,m_cols,it) (*it)->set_def();
|
|
return status;
|
|
}
|
|
|
|
bool get_row() { //read.
|
|
bool status = true;
|
|
tools_vforcit(icol*,m_cols,it) {
|
|
if(!(*it)->fetch_entry()) status = false;
|
|
}
|
|
return status;
|
|
}
|
|
|
|
bool set_basket_size(size_t a_size) {
|
|
tools_vforit(icol*,m_cols,it) {if(!(*it)->set_basket_size(a_size)) return false;}
|
|
return true;
|
|
}
|
|
|
|
void reset() { //read.
|
|
tools_vforit(icol*,m_cols,it) (*it)->reset();
|
|
}
|
|
|
|
protected:
|
|
std::string m_title;
|
|
std::vector<icol*> m_cols;
|
|
};
|
|
|
|
}}
|
|
|
|
#endif
|