Import Geant4 10.4.0 source tree
This commit is contained in:
@@ -0,0 +1,975 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_T_tools
|
||||
#define tools_hdf5_T_tools
|
||||
|
||||
#include "hdf5_h"
|
||||
|
||||
#include <tools/typedefs>
|
||||
#include <tools/forit>
|
||||
#include <tools/num2s>
|
||||
#include <tools/vdata>
|
||||
//#include <map>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline hid_t to_T_file_type(char) {return H5T_STD_I8LE;} //H5T_STD_I8XX()
|
||||
inline hid_t to_T_file_type(short) {return H5T_STD_I16LE;} //HST_STD_I16XX()
|
||||
inline hid_t to_T_file_type(int) {return H5T_STD_I32LE;} //H5T_STD_I32XX()
|
||||
inline hid_t to_T_file_type(tools::int64) {return H5T_STD_I64LE;} //H5T_STD_I64XX()
|
||||
|
||||
inline hid_t to_T_file_type(float) {return H5T_IEEE_F32LE;} //H5T_IEEE_F32XX()
|
||||
inline hid_t to_T_file_type(double) {return H5T_IEEE_F64LE;} //H5T_IEEE_F64XX()
|
||||
|
||||
inline hid_t to_T_file_type(unsigned char) {return H5T_STD_U8LE;}
|
||||
inline hid_t to_T_file_type(unsigned short) {return H5T_STD_U16LE;}
|
||||
inline hid_t to_T_file_type(unsigned int) {return H5T_STD_U32LE;}
|
||||
inline hid_t to_T_file_type(tools::uint64) {return H5T_STD_U64LE;}
|
||||
|
||||
inline hid_t to_T_mem_type(char) {return H5T_NATIVE_CHAR;}
|
||||
inline hid_t to_T_mem_type(short) {return H5T_NATIVE_SHORT;}
|
||||
inline hid_t to_T_mem_type(int) {return H5T_NATIVE_INT;}
|
||||
inline hid_t to_T_mem_type(tools::int64) {return H5T_NATIVE_INT64;}
|
||||
|
||||
inline hid_t to_T_mem_type(float) {return H5T_NATIVE_FLOAT;}
|
||||
inline hid_t to_T_mem_type(double) {return H5T_NATIVE_DOUBLE;}
|
||||
|
||||
inline hid_t to_T_mem_type(unsigned char) {return H5T_NATIVE_UCHAR;}
|
||||
inline hid_t to_T_mem_type(unsigned short) {return H5T_NATIVE_USHORT;}
|
||||
inline hid_t to_T_mem_type(unsigned int) {return H5T_NATIVE_UINT;}
|
||||
inline hid_t to_T_mem_type(tools::uint64) {return H5T_NATIVE_UINT64;}
|
||||
|
||||
template <class T>
|
||||
inline bool write_array(hid_t a_loc,const std::string& a_name,
|
||||
hid_t a_file_type,hid_t a_mem_type,
|
||||
unsigned int a_chunked,unsigned int a_compress,
|
||||
unsigned int a_size,const T a_array[]) {
|
||||
if(!a_size) return false;
|
||||
|
||||
hid_t cpt = -1;
|
||||
if(a_compress || a_chunked) {
|
||||
cpt = ::H5Pcreate(H5P_DATASET_CREATE);
|
||||
if(cpt<0) return false;
|
||||
if(a_chunked) {
|
||||
if(H5Pset_layout(cpt,H5D_CHUNKED)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
hsize_t cdims[1];
|
||||
cdims[0] = a_chunked;
|
||||
if(H5Pset_chunk(cpt,1,cdims)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(H5Pset_layout(cpt,H5D_COMPACT)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(a_compress) {
|
||||
if(H5Pset_deflate(cpt,a_compress>9?9:a_compress)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cpt = H5P_DEFAULT;
|
||||
}
|
||||
|
||||
hid_t dataset = -1;
|
||||
|
||||
{hsize_t dims[1];
|
||||
dims[0] = a_size;
|
||||
hid_t file_space = -1;
|
||||
if(a_chunked) {
|
||||
hsize_t mx_dims[1];
|
||||
mx_dims[0] = H5S_UNLIMITED; //extendable.
|
||||
file_space = ::H5Screate_simple(1,dims,mx_dims);
|
||||
} else {
|
||||
file_space = ::H5Screate_simple(1,dims,NULL);
|
||||
}
|
||||
if(file_space<0) {if(cpt>=0) ::H5Pclose(cpt);return false;}
|
||||
dataset = tools_H5Dcreate(a_loc,a_name.c_str(),a_file_type,file_space,cpt);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
::H5Sclose(file_space);
|
||||
if(dataset<0) return false;}
|
||||
|
||||
if(H5Dwrite(dataset,a_mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,a_array)<0) {
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
::H5Dclose(dataset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool write_sub_array(hid_t a_loc,const std::string& a_name,
|
||||
hid_t a_file_type,hid_t a_mem_type,
|
||||
bool a_create,
|
||||
unsigned int a_chunked,unsigned int a_compress, // used if a_creat = true;
|
||||
unsigned int a_size,
|
||||
unsigned int a_offset,unsigned int a_number,const T a_array[]) {
|
||||
|
||||
int remain = a_size-a_offset;
|
||||
int number = (int(a_number)<=remain) ? int(a_number) : remain;
|
||||
if(number<=0) return false;
|
||||
|
||||
hid_t cpt = -1;
|
||||
|
||||
if(a_create) {
|
||||
if(a_compress || a_chunked) {
|
||||
cpt = ::H5Pcreate(H5P_DATASET_CREATE);
|
||||
if(cpt<0) return false;
|
||||
if(a_chunked) {
|
||||
if(H5Pset_layout(cpt,H5D_CHUNKED)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
hsize_t cdims[1];
|
||||
//cdims[0] = (a_size<=32?a_size:32);
|
||||
cdims[0] = a_chunked;
|
||||
if(H5Pset_chunk(cpt,1,cdims)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(H5Pset_layout(cpt,H5D_COMPACT)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(a_compress) {
|
||||
if(H5Pset_deflate(cpt,a_compress>9?9:a_compress)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cpt = H5P_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
hid_t dataset = -1;
|
||||
|
||||
hid_t file_space = -1;
|
||||
|
||||
if(a_create) {
|
||||
hsize_t dims[1];
|
||||
dims[0] = a_size;
|
||||
file_space = ::H5Screate_simple(1,dims,NULL);
|
||||
if(file_space<0) {
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
{hsize_t offset[1];
|
||||
offset[0] = a_offset;
|
||||
hsize_t count[1];
|
||||
count[0] = number;
|
||||
if(H5Sselect_hyperslab(file_space,H5S_SELECT_SET,offset,NULL,count,NULL)<0) {
|
||||
::H5Sclose(file_space);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}}
|
||||
|
||||
dataset = tools_H5Dcreate(a_loc,a_name.c_str(),a_file_type,file_space,cpt);
|
||||
if(dataset<0) {
|
||||
::H5Sclose(file_space);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
} else { //open an existing dataset :
|
||||
dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) {
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
file_space = H5Dget_space(dataset);
|
||||
if(file_space<0) {
|
||||
::H5Dclose(dataset);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
{hsize_t offset[1];
|
||||
offset[0] = a_offset;
|
||||
hsize_t count[1];
|
||||
count[0] = number;
|
||||
if(H5Sselect_hyperslab(file_space,H5S_SELECT_SET,offset,NULL,count,NULL)<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}}
|
||||
|
||||
}
|
||||
|
||||
hsize_t dims[1];
|
||||
dims[0] = number;
|
||||
hid_t mem_space = ::H5Screate_simple(1,dims,NULL);
|
||||
if(mem_space<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Dwrite(dataset,a_mem_type,mem_space,file_space,H5P_DEFAULT,a_array)<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool write_append_array_dataset(hid_t a_dataset,hid_t /*a_file_type*/,hid_t a_mem_type,
|
||||
unsigned int a_number,const T a_array[]) {
|
||||
hsize_t old_size = 0;
|
||||
|
||||
{hid_t dataspace = H5Dget_space(a_dataset);
|
||||
if(dataspace<0) return false;
|
||||
hsize_t dims[1];
|
||||
if(H5Sget_simple_extent_dims(dataspace,dims,NULL)<0) {
|
||||
::H5Sclose(dataspace);
|
||||
return false;
|
||||
}
|
||||
old_size = dims[0];
|
||||
::H5Sclose(dataspace);}
|
||||
|
||||
{hsize_t exts[1];
|
||||
exts[0] = old_size+a_number;
|
||||
// if(H5Dextend(dataset,exts)<0) {
|
||||
if(H5Dset_extent(a_dataset,exts)<0) return false;}
|
||||
|
||||
hid_t file_space = H5Dget_space(a_dataset);
|
||||
if(file_space<0) return false;
|
||||
|
||||
{hsize_t offset[1];
|
||||
offset[0] = old_size;
|
||||
hsize_t count[1];
|
||||
count[0] = a_number;
|
||||
if(H5Sselect_hyperslab(file_space,H5S_SELECT_SET,offset,NULL,count,NULL)<0) {
|
||||
::H5Sclose(file_space);
|
||||
return false;
|
||||
}}
|
||||
|
||||
hsize_t dims[1];
|
||||
dims[0] = a_number;
|
||||
hid_t mem_space = ::H5Screate_simple(1,dims,NULL);
|
||||
if(mem_space<0) {
|
||||
::H5Sclose(file_space);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Dwrite(a_dataset,a_mem_type,mem_space,file_space,H5P_DEFAULT,a_array)<0) {
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool write_append_array(hid_t a_loc,const std::string& a_name,hid_t a_file_type,hid_t a_mem_type,
|
||||
unsigned int a_number,const T a_array[]) {
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) return false;
|
||||
bool status = write_append_array_dataset(dataset,a_file_type,a_mem_type,a_number,a_array);
|
||||
::H5Dclose(dataset);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
template <class T>
|
||||
inline bool write_array_struct(
|
||||
hid_t a_loc
|
||||
,const std::string& a_name
|
||||
,hid_t a_create_type
|
||||
,hid_t aWriteType
|
||||
,unsigned int a_size
|
||||
,const T a_array[]
|
||||
){
|
||||
hsize_t dims[1];
|
||||
dims[0] = a_size;
|
||||
hid_t dataspace = ::H5Screate_simple(1,dims,NULL);
|
||||
if(dataspace<0) return false;
|
||||
|
||||
hid_t dataset = tools_H5Dcreate(a_loc,a_name.c_str(),a_create_type,dataspace,H5P_DEFAULT);
|
||||
if(dataset<0) {
|
||||
::H5Sclose(dataspace);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Dwrite(dataset,aWriteType,H5S_ALL,H5S_ALL,H5P_DEFAULT,a_array)<0) {
|
||||
::H5Dclose(dataset);
|
||||
::H5Sclose(dataspace);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Dclose(dataset);
|
||||
::H5Sclose(dataspace);
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
inline bool read_scalar(hid_t a_loc,const std::string& a_name,hid_t a_mem_type,T& a_data) {
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) return false;
|
||||
|
||||
hid_t file_space = H5Dget_space(dataset);
|
||||
if(file_space<0) {
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t mem_space = ::H5Screate(H5S_SCALAR);
|
||||
if(mem_space<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Dread(dataset,a_mem_type,mem_space,file_space,H5P_DEFAULT,&a_data)<0) {
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool read_array(hid_t a_loc,const std::string& a_name,hid_t a_mem_type,unsigned int& a_size,T*& a_array,bool a_alloc = true) {
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) {
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return false; // data set not found.
|
||||
}
|
||||
|
||||
hid_t file_space = H5Dget_space(dataset);
|
||||
if(file_space<0) {
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
{int dimn = H5Sget_simple_extent_ndims(file_space);
|
||||
if(dimn<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return false;
|
||||
}
|
||||
if(dimn!=1) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return false;
|
||||
}
|
||||
//printf("debug : read dimn %d\n",dimn);
|
||||
}
|
||||
|
||||
hsize_t dims[1];
|
||||
{if(H5Sget_simple_extent_dims(file_space,dims,NULL)<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return false;
|
||||
}}
|
||||
|
||||
a_size = (unsigned int)dims[0];
|
||||
if(!a_size) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return true; //It is ok.
|
||||
}
|
||||
|
||||
hid_t mem_space = ::H5Screate_simple(1,dims,NULL);
|
||||
if(mem_space<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(a_alloc) a_array = new T[a_size];
|
||||
if(H5Dread(dataset,a_mem_type,mem_space,file_space,H5P_DEFAULT,a_array)<0) {
|
||||
if(a_alloc) delete [] a_array;
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
if(a_alloc) a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool read_sub_array(hid_t a_loc,const std::string& a_name,hid_t a_mem_type,
|
||||
unsigned int a_offset,unsigned int a_number,
|
||||
unsigned int& a_size,T*& a_array) {
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) {
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false; // data set not found.
|
||||
}
|
||||
|
||||
hid_t file_space = H5Dget_space(dataset);
|
||||
if(file_space<0) {
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
{int dimn = H5Sget_simple_extent_ndims(file_space);
|
||||
if(dimn<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
if(dimn!=1) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
//printf("debug : read dimn %d\n",dimn);
|
||||
}
|
||||
|
||||
hsize_t dims[1];
|
||||
{if(H5Sget_simple_extent_dims(file_space,dims,NULL)<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}}
|
||||
|
||||
unsigned int sz = (unsigned int)dims[0];
|
||||
if(!sz) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return true; //It is ok.
|
||||
}
|
||||
|
||||
// abcdef
|
||||
// 012345
|
||||
int remain = sz-a_offset;
|
||||
int number = (int(a_number)<=remain) ? int(a_number) : remain;
|
||||
if(number<=0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return true; //It is ok.
|
||||
}
|
||||
|
||||
{hsize_t offset[1];
|
||||
offset[0] = a_offset;
|
||||
hsize_t count[1];
|
||||
count[0] = number;
|
||||
if(H5Sselect_hyperslab(file_space,H5S_SELECT_SET,offset,NULL,count,NULL)<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}}
|
||||
|
||||
dims[0] = number;
|
||||
hid_t mem_space = ::H5Screate_simple(1,dims,NULL);
|
||||
if(mem_space<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
a_array = new T[number];
|
||||
if(H5Dread(dataset,a_mem_type,mem_space,file_space,H5P_DEFAULT,a_array)<0) {
|
||||
delete [] a_array;
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
|
||||
a_size = number;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool read_scalar(hid_t a_loc,const std::string& a_name,TYPE& aValue) {
|
||||
return read_scalar<TYPE>(a_loc,a_name,to_T_mem_type(TYPE()),aValue);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool read_std_vec(hid_t a_loc,const std::string& a_name,hid_t a_mem_type,std::vector<T>& a_vec) {
|
||||
tools::uint64 sz;
|
||||
if(!read_scalar<tools::uint64>(a_loc,a_name+"_size",sz)) return false;
|
||||
if(!sz) {a_vec.clear();return true;} //it is ok.
|
||||
a_vec.resize((size_t)sz);
|
||||
T* data = tools::vec_data(a_vec);
|
||||
unsigned int _sz;
|
||||
if(!read_array(a_loc,a_name,a_mem_type,_sz,data,false)) return false; //false = do not alloc.
|
||||
if(tools::uint64(_sz)!=sz) {a_vec.clear();return false;}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool read_std_vec_vec(hid_t a_loc,const std::string& a_name,hid_t a_mem_type,std::vector< std::vector<TYPE> >& a_vec_vec) {
|
||||
tools::uint64 sz;
|
||||
if(!read_scalar<tools::uint64>(a_loc,a_name+"_size",sz)) {a_vec_vec.clear();return false;}
|
||||
a_vec_vec.resize((size_t)sz);
|
||||
std::string scount;
|
||||
for(size_t count=0;count<(size_t)sz;count++) {
|
||||
tools::num2s(count,scount);
|
||||
if(!read_std_vec<TYPE>(a_loc,a_name+"_elem_"+scount,a_mem_type,a_vec_vec[count])) {a_vec_vec.clear();return false;}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
template <class T>
|
||||
inline bool read_array_struct(
|
||||
hid_t a_loc
|
||||
,const std::string& a_name
|
||||
,hid_t aReadType
|
||||
,unsigned int& a_size
|
||||
,T*& a_array
|
||||
){
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) {
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false; // data set not found.
|
||||
}
|
||||
|
||||
hid_t dataspace = H5Dget_space(dataset);
|
||||
if(dataspace<0) {
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
int dimn = H5Sget_simple_extent_ndims(dataspace);
|
||||
if(dimn<0) {
|
||||
::H5Sclose(dataspace);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
//printf("debug : read dimn %d\n",dimn);
|
||||
|
||||
hsize_t* dims = new hsize_t[dimn];
|
||||
{int rdimn = H5Sget_simple_extent_dims(dataspace,dims,NULL);
|
||||
if(rdimn<0) {
|
||||
delete [] dims;
|
||||
::H5Sclose(dataspace);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}}
|
||||
|
||||
hid_t memspace = ::H5Screate_simple(dimn,dims,NULL);
|
||||
if(memspace<0) {
|
||||
delete [] dims;
|
||||
::H5Sclose(dataspace);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
a_size = (unsigned int)dims[0];
|
||||
delete [] dims;
|
||||
if(!a_size) {
|
||||
::H5Sclose(memspace);
|
||||
::H5Sclose(dataspace);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
a_array = new T[a_size];
|
||||
if(H5Dread(dataset,aReadType,memspace,dataspace,H5P_DEFAULT,a_array)<0) {
|
||||
delete [] a_array;
|
||||
::H5Sclose(memspace);
|
||||
::H5Sclose(dataspace);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
a_array = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(memspace);
|
||||
::H5Sclose(dataspace);
|
||||
::H5Dclose(dataset);
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
inline bool read_struct(hid_t a_loc,const std::string& a_name,hid_t aReadType,T& a_data) {
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) return false;
|
||||
|
||||
hid_t file_space = H5Dget_space(dataset);
|
||||
if(file_space<0) {
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t mem_space = ::H5Screate(H5S_SCALAR);
|
||||
if(mem_space<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Dread(dataset,aReadType,mem_space,file_space,H5P_DEFAULT,&a_data)<0) {
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(mem_space);
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool write_scalar(hid_t a_loc,const std::string& a_name,const TYPE& aData) {
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) return false;
|
||||
|
||||
hid_t compact = ::H5Pcreate(H5P_DATASET_CREATE);
|
||||
if(compact<0) {
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Pset_layout(compact,H5D_COMPACT)<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t dataset = tools_H5Dcreate(a_loc,a_name.c_str(),to_T_file_type(TYPE()),scalar,compact);
|
||||
if(dataset<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(::H5Dwrite(dataset,to_T_mem_type(TYPE()),H5S_ALL,H5S_ALL,H5P_DEFAULT,&aData)<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool write_struct(hid_t a_loc,const std::string& a_name,
|
||||
hid_t a_create_type,hid_t aWriteType,const T& aData) {
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) return false;
|
||||
|
||||
hid_t compact = ::H5Pcreate(H5P_DATASET_CREATE);
|
||||
if(compact<0) {
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Pset_layout(compact,H5D_COMPACT)<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t dataset = tools_H5Dcreate(a_loc,a_name.c_str(),a_create_type,scalar,compact);
|
||||
if(dataset<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Dwrite(dataset,aWriteType,H5S_ALL,H5S_ALL,H5P_DEFAULT,&aData)<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
template <class TYPE>
|
||||
inline bool write_array(hid_t a_loc,const std::string& a_name,
|
||||
unsigned int a_size,const TYPE a_array[],
|
||||
unsigned int a_chunked = 0,unsigned int a_compress = 0) {
|
||||
return hdf5::write_array<TYPE>(a_loc,a_name,to_T_file_type(TYPE()),to_T_mem_type(TYPE()),
|
||||
a_chunked,a_compress,a_size,a_array);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool write_std_vec(hid_t a_loc,const std::string& a_name,
|
||||
hid_t a_file_type,hid_t a_mem_type,
|
||||
unsigned int a_chunked,unsigned int a_compress,
|
||||
const std::vector<T>& a_vec) {
|
||||
if(!write_scalar<tools::uint64>(a_loc,a_name+"_size",a_vec.size())) return false;
|
||||
if(a_vec.empty()) return true; //it is ok.
|
||||
const T* data = tools::vec_data(a_vec);
|
||||
return write_array(a_loc,a_name,a_file_type,a_mem_type,a_chunked,a_compress,a_vec.size(),data);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool write_std_vec(hid_t a_loc,const std::string& a_name,const std::vector<TYPE>& a_array,
|
||||
unsigned int a_chunked = 0,unsigned int a_compress = 0) {
|
||||
return hdf5::write_std_vec<TYPE>(a_loc,a_name,to_T_file_type(TYPE()),to_T_mem_type(TYPE()),a_chunked,a_compress,a_array);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool write_std_vec_vec(hid_t a_loc,const std::string& a_name,const std::vector< std::vector<TYPE> >& a_vec_vec,
|
||||
unsigned int /*a_chunked*/ = 0,unsigned int /*a_compress*/ = 0) {
|
||||
if(!write_scalar<tools::uint64>(a_loc,a_name+"_size",a_vec_vec.size())) return false;
|
||||
size_t count = 0;
|
||||
std::string scount;
|
||||
tools_typename_vforcit(std::vector<TYPE>,a_vec_vec,it) {
|
||||
tools::num2s(count,scount);
|
||||
if(!write_std_vec<TYPE>(a_loc,a_name+"_elem_"+scount,*it)) return false;
|
||||
count++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//template <class TKEY,class TVALUE>
|
||||
//inline bool write_std_map(hid_t a_loc,const std::string& a_name,const std::map<TKEY,TVALUE>& a_map,
|
||||
// unsigned int a_chunked = 0,unsigned int a_compress = 0) {
|
||||
// if(!write_scalar<tools::uint64>(a_loc,a_name+"_size",a_map.size())) return false;
|
||||
// size_t count = 0;
|
||||
// std::string scount;
|
||||
// inlib_typename_mforcit(TKEY,TVALUE,a_map,it) {
|
||||
// tools::num2s(count,scount);
|
||||
// if(!write_scalar<TKEY>(a_loc,a_name+"_elem_"+scount+"_first",(*it).first)) return false;
|
||||
// if(!write_scalar<TVALUE>(a_loc,a_name+"_elem_"+scount+"_secon",(*it).second)) return false;
|
||||
// count++;
|
||||
// }
|
||||
// return true;
|
||||
//}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool write_sub_array(hid_t a_loc,const std::string& a_name,
|
||||
unsigned int a_size,unsigned int a_offset,unsigned int a_number,const TYPE a_array[],
|
||||
bool a_create = true,unsigned int a_chunked = 0,unsigned int a_compress = 0) {
|
||||
return hdf5::write_sub_array<TYPE>(a_loc,a_name,to_T_file_type(TYPE()),to_T_mem_type(TYPE()),
|
||||
a_create,a_chunked,a_compress,
|
||||
a_size,a_offset,a_number,a_array);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool write_append_array_dataset(hid_t a_dataset,unsigned int a_number,const TYPE a_array[]) {
|
||||
return hdf5::write_append_array_dataset<TYPE>(a_dataset,to_T_file_type(TYPE()),to_T_mem_type(TYPE()),a_number,a_array);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool write_append_array(hid_t a_loc,const std::string& a_name,unsigned int a_number,const TYPE a_array[]) {
|
||||
return hdf5::write_append_array<TYPE>(a_loc,a_name,to_T_file_type(TYPE()),to_T_mem_type(TYPE()),a_number,a_array);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool read_array(hid_t a_loc,const std::string& a_name,unsigned int& a_size,TYPE*& a_array) {
|
||||
return read_array<TYPE>(a_loc,a_name,to_T_mem_type(TYPE()),a_size,a_array);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool read_std_vec(hid_t a_loc,const std::string& a_name,std::vector<TYPE>& a_vec) {
|
||||
return read_std_vec<TYPE>(a_loc,a_name,to_T_mem_type(TYPE()),a_vec);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool read_std_vec_vec(hid_t a_loc,const std::string& a_name,std::vector< std::vector<TYPE> >& a_vec_vec) {
|
||||
return read_std_vec_vec<TYPE>(a_loc,a_name,to_T_mem_type(TYPE()),a_vec_vec);
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
inline bool read_sub_array(hid_t a_loc,const std::string& a_name,unsigned int a_offset,unsigned int a_number,
|
||||
unsigned int& a_size,TYPE*& a_array) {
|
||||
return read_sub_array<TYPE>(a_loc,a_name,to_T_mem_type(TYPE()),a_offset,a_number,a_size,a_array);
|
||||
}
|
||||
|
||||
inline bool read_bool(hid_t a_loc,const std::string& a_name,bool& aValue) {
|
||||
unsigned char value = 0;
|
||||
if(!read_scalar<unsigned char>(a_loc,a_name,H5T_NATIVE_UCHAR,value)) {
|
||||
aValue = false;
|
||||
return false;
|
||||
}
|
||||
if((value!=0) && (value!=1)) {
|
||||
aValue = false;
|
||||
return false;
|
||||
}
|
||||
aValue = (value==1?true:false);
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#include "atb"
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
template <class TYPE>
|
||||
inline bool write_scalar_atb(hid_t aDS,const std::string& a_name,const TYPE& aData) {
|
||||
int has_attr = H5LT_find_attribute(aDS,a_name.c_str());
|
||||
if(has_attr==1) {
|
||||
if(H5Adelete(aDS,a_name.c_str())<0) return false;
|
||||
}
|
||||
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) return false;
|
||||
|
||||
hid_t aid = tools_H5Acreate(aDS,a_name.c_str(),H5T_STD_I32LE,scalar,H5P_DEFAULT);
|
||||
if(aid<0) {
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Awrite(aid,H5T_NATIVE_INT,&aData)<0) {
|
||||
::H5Sclose(scalar);
|
||||
::H5Aclose(aid);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(scalar);
|
||||
::H5Aclose(aid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
/*
|
||||
#include <tools/buf2lines>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline bool write_strings(hid_t a_loc,const std::string& a_name,
|
||||
size_t a_number,const char** a_strings,
|
||||
unsigned int a_chunked = 0,unsigned int a_compress = 0) {
|
||||
size_t sz;char* buffer;
|
||||
if(!tools::strings2buf(a_number,a_strings,sz,buffer)) return false;
|
||||
sz--;
|
||||
bool status = hdf5::write_array<char>(a_loc,a_name,to_T_file_type(char()),to_T_mem_type(char()),
|
||||
a_chunked,a_compress,(unsigned int)sz,buffer);
|
||||
delete [] buffer;
|
||||
return status;
|
||||
}
|
||||
|
||||
inline bool write_strings(hid_t a_loc,const std::string& a_name,
|
||||
const std::vector<std::string>& a_strings,
|
||||
unsigned int a_chunked = 0,unsigned int a_compress = 0) {
|
||||
size_t sz;char* buffer;
|
||||
if(!tools::strings2buf(a_strings,sz,buffer)) return false;
|
||||
sz--;
|
||||
bool status = hdf5::write_array<char>(a_loc,a_name,to_T_file_type(char()),to_T_mem_type(char()),
|
||||
a_chunked,a_compress,(unsigned int)sz,buffer);
|
||||
delete [] buffer;
|
||||
return status;
|
||||
}
|
||||
|
||||
inline bool write_append_strings(hid_t a_loc,const std::string& a_name,size_t a_number,const char** a_strings) {
|
||||
size_t sz;char* buffer;
|
||||
if(!tools::strings2buf(a_number,a_strings,sz,buffer)) return false;
|
||||
sz--;
|
||||
bool status = hdf5::write_append_array<char>(a_loc,a_name,to_T_file_type(char()),to_T_mem_type(char()),(unsigned int)sz,buffer);
|
||||
delete [] buffer;
|
||||
return status;
|
||||
}
|
||||
|
||||
inline bool write_append_strings(hid_t a_loc,const std::string& a_name,const std::vector<std::string>& a_strings) {
|
||||
size_t sz;char* buffer;
|
||||
if(!tools::strings2buf(a_strings,sz,buffer)) return false;
|
||||
sz--;
|
||||
bool status = hdf5::write_append_array<char>(a_loc,a_name,to_T_file_type(char()),to_T_mem_type(char()),(unsigned int)sz,buffer);
|
||||
delete [] buffer;
|
||||
return status;
|
||||
}
|
||||
|
||||
}}
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_atb
|
||||
#define tools_hdf5_atb
|
||||
|
||||
// The below is internal methods in the HDF5 lib.
|
||||
|
||||
#include "hdf5_h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline herr_t H5LT_get_attribute_mem(hid_t obj_id,const char *attr_name,hid_t mem_type_id,void *data ) {
|
||||
hid_t attr_id;
|
||||
if ( ( attr_id = ::H5Aopen_name( obj_id, attr_name ) ) < 0 ) return -1;
|
||||
if ( ::H5Aread( attr_id, mem_type_id, data ) < 0 ) {
|
||||
::H5Aclose( attr_id );
|
||||
return -1;
|
||||
}
|
||||
if ( ::H5Aclose( attr_id ) < 0 ) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline herr_t find_attr( hid_t loc_id, const char *name, void *op_data) {
|
||||
int ret = 0;
|
||||
char *attr_name = (char*)op_data;
|
||||
if( ::strcmp( name, attr_name ) == 0 ) ret = 1;
|
||||
(void)loc_id;
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline herr_t H5LT_find_attribute( hid_t loc_id, const char* attr_name ) {
|
||||
unsigned int attr_num;
|
||||
attr_num = 0;
|
||||
return tools_H5Aiterate( loc_id, &attr_num, find_attr, (void *)attr_name );
|
||||
}
|
||||
|
||||
inline herr_t H5LT_get_attribute_disk( hid_t loc_id,const char *attr_name,void *attr_out ) {
|
||||
hid_t attr_id;
|
||||
if ( ( attr_id = ::H5Aopen_name( loc_id, attr_name ) ) < 0 ) return -1;
|
||||
|
||||
hid_t attr_type;
|
||||
if ( (attr_type = ::H5Aget_type( attr_id )) < 0 ) {
|
||||
::H5Tclose( attr_type );
|
||||
::H5Aclose( attr_id );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( ::H5Aread( attr_id, attr_type, attr_out ) < 0 ) {
|
||||
::H5Tclose( attr_type );
|
||||
::H5Aclose( attr_id );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( ::H5Tclose( attr_type ) < 0 ) {
|
||||
::H5Tclose( attr_type );
|
||||
::H5Aclose( attr_id );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( ::H5Aclose( attr_id ) < 0 ) return -1;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,304 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_h2file
|
||||
#define tools_hdf5_h2file
|
||||
|
||||
#include "tools"
|
||||
#include "T_tools"
|
||||
|
||||
#include <tools/histo/histo_data>
|
||||
#include <tools/sout>
|
||||
#include <ostream>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
}}
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline bool write_std_map_ss(hid_t a_loc,const std::string& a_name,const std::map<std::string,std::string>& a_map,
|
||||
unsigned int /*a_chunked*/ = 0,unsigned int /*a_compress*/ = 0) {
|
||||
if(!write_scalar<tools::uint64>(a_loc,a_name+"_size",a_map.size())) return false;
|
||||
size_t count = 0;
|
||||
std::string scount;
|
||||
tools_mforcit(std::string,std::string,a_map,it) {
|
||||
tools::num2s(count,scount);
|
||||
if(!write_string(a_loc,a_name+"_elem_"+scount+"_first",(*it).first)) return false;
|
||||
if(!write_string(a_loc,a_name+"_elem_"+scount+"_secon",(*it).second)) return false;
|
||||
count++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_std_map_ss(hid_t a_loc,const std::string& a_name,std::map<std::string,std::string>& a_map,
|
||||
unsigned int /*a_chunked*/ = 0,unsigned int /*a_compress*/ = 0) {
|
||||
a_map.clear();
|
||||
tools::uint64 sz;
|
||||
if(!read_scalar<tools::uint64>(a_loc,a_name+"_size",sz)) return false;
|
||||
std::string scount,key,value;
|
||||
for(tools::uint64 count=0;count<sz;count++) {
|
||||
tools::num2s(count,scount);
|
||||
if(!read_string(a_loc,a_name+"_elem_"+scount+"_first",key)) return false;
|
||||
if(!read_string(a_loc,a_name+"_elem_"+scount+"_secon",value)) return false;
|
||||
a_map[key] = value;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef tools::histo::histo_data<double,unsigned int,unsigned int,double> histo_data_t;
|
||||
|
||||
inline bool write_hdata(hid_t a_loc,const histo_data_t& a_hdata) {
|
||||
|
||||
if(!write_string(a_loc,"title",a_hdata.m_title)) return false;
|
||||
if(!write_scalar<unsigned int>(a_loc,"dimension",a_hdata.m_dimension)) return false;
|
||||
if(!write_scalar<unsigned int>(a_loc,"bin_number",a_hdata.m_bin_number)) return false;
|
||||
|
||||
if(!write_std_vec<unsigned int>(a_loc,"bin_entries",a_hdata.m_bin_entries)) return false;
|
||||
if(!write_std_vec<double>(a_loc,"bin_Sw",a_hdata.m_bin_Sw)) return false;
|
||||
if(!write_std_vec<double>(a_loc,"bin_Sw2",a_hdata.m_bin_Sw2)) return false;
|
||||
if(!write_std_vec_vec<double>(a_loc,"bin_Sxw",a_hdata.m_bin_Sxw)) return false;
|
||||
if(!write_std_vec_vec<double>(a_loc,"bin_Sx2w",a_hdata.m_bin_Sx2w)) return false;
|
||||
|
||||
// axes :
|
||||
{std::string name,saxis;
|
||||
for(unsigned int iaxis=0;iaxis<a_hdata.m_dimension;iaxis++) {
|
||||
tools::num2s(iaxis,saxis);
|
||||
name = "axis_"+saxis+"_";
|
||||
const histo_data_t::axis_t& _axis = a_hdata.m_axes[iaxis];
|
||||
if(!write_scalar<unsigned int>(a_loc,name+"offset",_axis.m_offset)) return false;
|
||||
if(!write_scalar<unsigned int>(a_loc,name+"number_of_bins",_axis.m_number_of_bins)) return false;
|
||||
if(!write_scalar<double>(a_loc,name+"minimum_value",_axis.m_minimum_value)) return false;
|
||||
if(!write_scalar<double>(a_loc,name+"maximum_value",_axis.m_maximum_value)) return false;
|
||||
if(!write_scalar<bool>(a_loc,name+"fixed",_axis.m_fixed)) return false;
|
||||
if(!write_scalar<double>(a_loc,name+"bin_width",_axis.m_bin_width)) return false;
|
||||
if(!write_std_vec<double>(a_loc,name+"edges",_axis.m_edges)) return false;
|
||||
}}
|
||||
|
||||
// etc :
|
||||
if(!write_std_vec<double>(a_loc,"in_range_plane_Sxyw",a_hdata.m_in_range_plane_Sxyw)) return false;
|
||||
|
||||
// m_annotations :
|
||||
if(!write_std_map_ss(a_loc,"annotations",a_hdata.m_annotations)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class HISTO>
|
||||
inline bool write_histo(std::ostream& a_out,hid_t a_loc,const std::string& a_name,const HISTO& a_histo) {
|
||||
|
||||
hid_t histo = tools_H5Gcreate(a_loc,a_name.c_str(),0);
|
||||
if(histo<0) {
|
||||
a_out << "tools::hdf5::write_histo : can't create group for histo " << tools::sout(a_name) << "." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!write_atb(histo,"type","object")) {
|
||||
a_out << "tools::hdf5::write_histo : write_atb() class failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
if(!write_atb(histo,"class",a_histo.s_cls())) {
|
||||
a_out << "tools::hdf5::write_histo : write_atb() class failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
int v = 1;
|
||||
if(!write_scalar_atb<int>(histo,"version",v)) {
|
||||
a_out << "tools::hdf5::write_histo : write_scalar_atb() version failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!write_hdata(histo,a_histo.dac())) {::H5Gclose(histo);return false;}
|
||||
|
||||
::H5Gclose(histo);
|
||||
|
||||
a_histo.not_a_profile(); //trick to be sure to use this function on an histo and not a profile.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class PROFILE>
|
||||
inline bool write_profile(std::ostream& a_out,hid_t a_loc,const std::string& a_name,const PROFILE& a_histo) {
|
||||
|
||||
hid_t histo = tools_H5Gcreate(a_loc,a_name.c_str(),0);
|
||||
if(histo<0) {
|
||||
a_out << "tools::hdf5::write_profile : can't create group for histo " << tools::sout(a_name) << "." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!write_atb(histo,"type","object")) {
|
||||
a_out << "tools::hdf5::write_profile : write_atb() class failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
if(!write_atb(histo,"class",a_histo.s_cls())) {
|
||||
a_out << "tools::hdf5::write_profile : write_atb() class failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
int v = 1;
|
||||
if(!write_scalar_atb<int>(histo,"version",v)) {
|
||||
a_out << "tools::hdf5::write_profile : write_scalar_atb() version failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
typename PROFILE::pd_t pdata = a_histo.get_histo_data();
|
||||
|
||||
if(!write_hdata(histo,pdata)) {::H5Gclose(histo);return false;}
|
||||
|
||||
if(!write_bool(histo,"is_profile",pdata.m_is_profile)) {::H5Gclose(histo);return false;}
|
||||
if(!write_std_vec<double>(histo,"bin_Svw",pdata.m_bin_Svw)) {::H5Gclose(histo);return false;}
|
||||
if(!write_std_vec<double>(histo,"bin_Sv2w",pdata.m_bin_Sv2w)) {::H5Gclose(histo);return false;}
|
||||
if(!write_bool(histo,"cut_v",pdata.m_cut_v)) {::H5Gclose(histo);return false;}
|
||||
if(!write_scalar<double>(histo,"min_v",pdata.m_min_v)) {::H5Gclose(histo);return false;}
|
||||
if(!write_scalar<double>(histo,"max_v",pdata.m_max_v)) {::H5Gclose(histo);return false;}
|
||||
|
||||
::H5Gclose(histo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_hdata(hid_t a_loc,histo_data_t& a_hdata) {
|
||||
if(!read_string(a_loc,"title",a_hdata.m_title)) return false;
|
||||
if(!read_scalar<unsigned int>(a_loc,"dimension",a_hdata.m_dimension)) return false;
|
||||
if(!read_scalar<unsigned int>(a_loc,"bin_number",a_hdata.m_bin_number)) return false;
|
||||
|
||||
if(!read_std_vec<unsigned int>(a_loc,"bin_entries",a_hdata.m_bin_entries)) return false;
|
||||
if(!read_std_vec<double>(a_loc,"bin_Sw",a_hdata.m_bin_Sw)) return false;
|
||||
if(!read_std_vec<double>(a_loc,"bin_Sw2",a_hdata.m_bin_Sw2)) return false;
|
||||
|
||||
if(!read_std_vec_vec<double>(a_loc,"bin_Sxw",a_hdata.m_bin_Sxw)) return false;
|
||||
if(!read_std_vec_vec<double>(a_loc,"bin_Sx2w",a_hdata.m_bin_Sx2w)) return false;
|
||||
|
||||
// axes :
|
||||
{a_hdata.m_axes.resize(a_hdata.m_dimension);
|
||||
std::string name,saxis;
|
||||
for(unsigned int iaxis=0;iaxis<a_hdata.m_dimension;iaxis++) {
|
||||
tools::num2s(iaxis,saxis);
|
||||
name = "axis_"+saxis+"_";
|
||||
histo_data_t::axis_t& _axis = a_hdata.m_axes[iaxis];
|
||||
if(!read_scalar<unsigned int>(a_loc,name+"offset",_axis.m_offset)) return false;
|
||||
if(!read_scalar<unsigned int>(a_loc,name+"number_of_bins",_axis.m_number_of_bins)) return false;
|
||||
if(!read_scalar<double>(a_loc,name+"minimum_value",_axis.m_minimum_value)) return false;
|
||||
if(!read_scalar<double>(a_loc,name+"maximum_value",_axis.m_maximum_value)) return false;
|
||||
if(!read_scalar<bool>(a_loc,name+"fixed",_axis.m_fixed)) return false;
|
||||
if(!read_scalar<double>(a_loc,name+"bin_width",_axis.m_bin_width)) return false;
|
||||
if(!read_std_vec<double>(a_loc,name+"edges",_axis.m_edges)) return false;
|
||||
}}
|
||||
|
||||
// etc :
|
||||
if(!read_std_vec<double>(a_loc,"in_range_plane_Sxyw",a_hdata.m_in_range_plane_Sxyw)) return false;
|
||||
|
||||
// m_annotations :
|
||||
if(!read_std_map_ss(a_loc,"annotations",a_hdata.m_annotations)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class HISTO>
|
||||
inline bool read_histo(std::ostream& a_out,hid_t a_loc,const std::string& a_name,HISTO*& a_histo) {
|
||||
a_histo = 0;
|
||||
|
||||
hid_t histo = tools_H5Gopen(a_loc,a_name.c_str());
|
||||
if(histo<0) {
|
||||
a_out << "tools::hdf5::read_histo : can't open group." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string sclass;
|
||||
if(!read_atb(histo,"class",sclass)) {
|
||||
a_out << "tools::hdf5::read_histo : can't read_atb() class." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(sclass!=HISTO::s_class()) {
|
||||
a_out << "tools::hdf5::read_histo : unknown class : " << sclass << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
int v;
|
||||
if(!read_atb(histo,"version",v)) {
|
||||
a_out << "tools::hdf5::read_histo : read_atb version failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
histo_data_t hdata;
|
||||
|
||||
if(!read_hdata(histo,hdata)) {::H5Gclose(histo);return false;}
|
||||
|
||||
::H5Gclose(histo);
|
||||
|
||||
hdata.update_fast_getters();
|
||||
|
||||
a_histo = new HISTO;
|
||||
a_histo->copy_from_data(hdata);
|
||||
a_histo->not_a_profile(); //trick to be sure to use this function on an histo and not a profile.
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class PROFILE>
|
||||
inline bool read_profile(std::ostream& a_out,hid_t a_loc,const std::string& a_name,PROFILE*& a_histo) {
|
||||
a_histo = 0;
|
||||
|
||||
hid_t histo = tools_H5Gopen(a_loc,a_name.c_str());
|
||||
if(histo<0) {
|
||||
a_out << "tools::hdf5::read_profile : can't open group." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string sclass;
|
||||
if(!read_atb(histo,"class",sclass)) {
|
||||
a_out << "tools::hdf5::read_profile : can't read_atb() class." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(sclass!=PROFILE::s_class()) {
|
||||
a_out << "tools::hdf5::read_profile : unknown class : " << sclass << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
int v;
|
||||
if(!read_atb(histo,"version",v)) {
|
||||
a_out << "tools::hdf5::read_profile : read_atb version failed." << std::endl;
|
||||
::H5Gclose(histo);
|
||||
return false;
|
||||
}
|
||||
|
||||
typename PROFILE::pd_t pdata;
|
||||
|
||||
if(!read_hdata(histo,pdata)) {::H5Gclose(histo);return false;}
|
||||
|
||||
if(!read_bool(histo,"is_profile",pdata.m_is_profile)) {::H5Gclose(histo);return false;}
|
||||
if(!read_std_vec<double>(histo,"bin_Svw",pdata.m_bin_Svw)) {::H5Gclose(histo);return false;}
|
||||
if(!read_std_vec<double>(histo,"bin_Sv2w",pdata.m_bin_Sv2w)) {::H5Gclose(histo);return false;}
|
||||
if(!read_bool(histo,"cut_v",pdata.m_cut_v)) {::H5Gclose(histo);return false;}
|
||||
if(!read_scalar<double>(histo,"min_v",pdata.m_min_v)) {::H5Gclose(histo);return false;}
|
||||
if(!read_scalar<double>(histo,"max_v",pdata.m_max_v)) {::H5Gclose(histo);return false;}
|
||||
|
||||
::H5Gclose(histo);
|
||||
|
||||
pdata.update_fast_getters();
|
||||
|
||||
a_histo = new PROFILE;
|
||||
a_histo->copy_from_data(pdata);
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_h
|
||||
#define tools_hdf5_h
|
||||
|
||||
#ifndef TOOLS_USE_OUREX_HDF5
|
||||
#include <hdf5.h>
|
||||
#else
|
||||
#include <ourex_hdf5.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if (H5_VERS_MAJOR>=1) && (H5_VERS_MINOR<=6)
|
||||
#define tools_H5Dopen H5Dopen
|
||||
#define tools_H5Dcreate H5Dcreate
|
||||
#define tools_H5Acreate H5Acreate
|
||||
#define tools_H5Tarray_create H5Tarray_create
|
||||
#define tools_H5Tget_array_dims H5Tget_array_dims
|
||||
#define tools_H5Gcreate H5Gcreate
|
||||
#define tools_H5Gopen H5Gopen
|
||||
#define tools_H5Aiterate H5Aiterate
|
||||
#else
|
||||
#define tools_H5Dopen H5Dopen1
|
||||
#define tools_H5Dcreate H5Dcreate1
|
||||
#define tools_H5Acreate H5Acreate1
|
||||
#define tools_H5Tarray_create H5Tarray_create1
|
||||
#define tools_H5Tget_array_dims H5Tget_array_dims1
|
||||
#define tools_H5Gcreate H5Gcreate1
|
||||
#define tools_H5Gopen H5Gopen1
|
||||
#define tools_H5Aiterate H5Aiterate1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_header
|
||||
#define tools_hdf5_header
|
||||
|
||||
#include "tools"
|
||||
#include "T_tools"
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline bool write_header(hid_t a_file,int a_version = 1) {
|
||||
hid_t header = tools_H5Gcreate(a_file,"header",0);
|
||||
if(header<0) return false;
|
||||
if(!write_atb(header,"writer","exlib")) {::H5Gclose(header);return false;}
|
||||
if(!write_scalar_atb<int>(header,"data_schema_version",a_version)) {::H5Gclose(header);return false;}
|
||||
::H5Gclose(header);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_header(hid_t a_file,std::string& a_writer,int& a_data_schema_version) {
|
||||
hid_t header = tools_H5Gopen(a_file,"header");
|
||||
if(header<0) {a_writer.clear();a_data_schema_version=0;return false;}
|
||||
if(!read_atb(header,"writer",a_writer)) {::H5Gclose(header);a_writer.clear();a_data_schema_version=0;return false;}
|
||||
if(!read_atb(header,"data_schema_version",a_data_schema_version)) {
|
||||
::H5Gclose(header);
|
||||
a_writer.clear();a_data_schema_version=0;
|
||||
return false;
|
||||
}
|
||||
::H5Gclose(header);
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,929 @@
|
||||
// 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
|
||||
@@ -0,0 +1,234 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_pages
|
||||
#define tools_hdf5_pages
|
||||
|
||||
#include "T_tools"
|
||||
#include "tools"
|
||||
|
||||
#include <tools/S_STRING>
|
||||
|
||||
#ifdef TOOLS_MEM
|
||||
#include <tools/mem>
|
||||
#endif
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
TOOLS_GLOBAL_STRING(pages)
|
||||
TOOLS_GLOBAL_STRING(entries)
|
||||
TOOLS_GLOBAL_STRING(columns)
|
||||
TOOLS_GLOBAL_STRING(names)
|
||||
TOOLS_GLOBAL_STRING(forms)
|
||||
|
||||
class pages {
|
||||
TOOLS_SCLASS(tools::hdf5::pages)
|
||||
public:
|
||||
pages(std::ostream& a_out,
|
||||
hid_t a_group,const std::string& a_name,const std::string& a_form,
|
||||
bool a_write,unsigned int a_compress)
|
||||
:m_out(a_out),m_name(a_name),m_form(a_form)
|
||||
//,m_type(0),m_size(0)
|
||||
,m_group(-1),m_dataset(-1),m_write(a_write),m_compress(a_compress),m_entries(0),m_pos(0){
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
if(m_write) {
|
||||
m_group = tools_H5Gcreate(a_group,m_name.c_str(),0);
|
||||
if(m_group<0) {
|
||||
m_out << "pages::pages : can't create group for column " << m_name << "." << std::endl;
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
if(!write_atb(m_group,"class",s_class())) {
|
||||
m_out << "pages::pages : write_atb(class) failed." << std::endl;
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
int v = 1;
|
||||
if (!write_scalar_atb<int>(m_group,"version",v)) {
|
||||
m_out << "pages::pages : write_scalar_atb(version) failed." << std::endl;
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
m_group = tools_H5Gopen(a_group,m_name.c_str());
|
||||
if(m_group<0) {
|
||||
m_out << "pages::pages : can't open group for column " << m_name << "." << std::endl;
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
if(!read_scalar<tools::uint64>(m_group,s_entries(),m_entries)) {
|
||||
m_out << "pages::pages : read_scalar(entries) failed." << std::endl;
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual ~pages(){
|
||||
if(m_write) {
|
||||
if(!write_scalar<tools::uint64>(m_group,s_entries(),m_entries)) {
|
||||
m_out << "pages::~pages : write_scalar(entries) failed." << std::endl;
|
||||
}
|
||||
if(m_dataset>=0) ::H5Dclose(m_dataset);
|
||||
}
|
||||
::H5Gclose(m_group);
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
protected:
|
||||
pages(const pages& a_from):m_out(a_from.m_out){
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
pages& operator=(const pages&){return *this;}
|
||||
public:
|
||||
bool is_valid() const {return m_group<0?false:true;}
|
||||
|
||||
const std::string& name() const {return m_name;}
|
||||
const std::string& form() const {return m_form;}
|
||||
//int type() const {return m_type;}
|
||||
//unsigned int size() const {return m_size;}
|
||||
tools::uint64 entries() const {return m_entries;}
|
||||
tools::uint64 pos() const {return m_pos;}
|
||||
void reset_pos() {m_pos = 0;}
|
||||
|
||||
template <class TYPE>
|
||||
bool write_page(size_t a_size,void* a_array) {
|
||||
if(!m_pos) {
|
||||
if(!write_array<TYPE>(m_group,s_pages(),a_size,(TYPE*)a_array,a_size,m_compress)) {
|
||||
m_out << "pages::write_page : write_array<TYPE>() failed. Pos " << m_pos << std::endl;
|
||||
return false;
|
||||
}
|
||||
m_dataset = tools_H5Dopen(m_group,s_pages().c_str());
|
||||
if(m_dataset<0) {
|
||||
m_out << "pages::write_page : H5Dopen failed. Pos " << m_pos << std::endl;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(!write_append_array_dataset<TYPE>(m_dataset,a_size,(TYPE*)a_array)) {
|
||||
m_out << "pages::write_page : write_append_array<TYPE>() failed. Pos " << m_pos << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
m_pos += a_size;
|
||||
m_entries = m_pos;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class TYPE>
|
||||
bool read_page(size_t a_size,void* a_array) {
|
||||
//it is assumed that a_array can contain a_size*sizeof(TYPE) bytes.
|
||||
unsigned int _size = a_size;
|
||||
unsigned int n = 0;
|
||||
TYPE* array = 0;
|
||||
if(!read_sub_array<TYPE>(m_group,s_pages(),(unsigned int)m_pos,(unsigned int)_size,n,array)) {
|
||||
m_out << "pages::read_page : read_sub_array<TYPE>() failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
if(n!=_size) {
|
||||
m_out << "pages::read_page : size mismatch. Requested " << _size << ", got "<< n << "." << std::endl;
|
||||
delete [] array;
|
||||
return false;
|
||||
}
|
||||
|
||||
{TYPE* rpos = (TYPE*)array;
|
||||
TYPE* wpos = (TYPE*)a_array;
|
||||
for(size_t i=0;i<n;i++,rpos++,wpos++) *wpos = *rpos;
|
||||
for(size_t i=n;i<_size;i++,rpos++,wpos++) *wpos = TYPE();}
|
||||
|
||||
delete [] array;
|
||||
|
||||
m_pos += n;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
bool write_strings(size_t a_number,void* a_array) {
|
||||
size_t sz = m_size*a_number;
|
||||
char* buffer = new char[sz];
|
||||
{char* pos = buffer;
|
||||
for(size_t index=0;index<sz;index++,pos++) *pos = ' ';}
|
||||
|
||||
{char** strings = (char**)a_array;
|
||||
char* pos = buffer;
|
||||
size_t ls;
|
||||
for(size_t index=0;index<a_number;index++) {
|
||||
char* ss = strings[index];
|
||||
ls = ::strlen(ss);
|
||||
::memcpy(pos,ss,ls); //do not copy the ending 0.
|
||||
*(pos+m_size-1) = 0;
|
||||
pos += m_size;
|
||||
}}
|
||||
|
||||
if(!m_pos) {
|
||||
unsigned int chunked = 32*m_size; //<size>A strings.
|
||||
if(!write_array<char>(m_group,s_pages(),sz,buffer,chunked,m_compress)) {
|
||||
m_out << "pages::write_strings : write_strings() failed. Pos " << m_pos << std::endl;
|
||||
return false;
|
||||
}
|
||||
m_dataset = tools_H5Dopen(m_group,s_pages().c_str());
|
||||
if(m_dataset<0) {
|
||||
m_out << "pages::write_strings : H5Dopen failed. Pos " << m_pos << std::endl;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(!write_append_array_dataset<char>(m_dataset,sz,buffer)) {
|
||||
m_out << "pages::write_strings : write_append_strings() failed. Pos " << m_pos << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
m_pos += a_number;
|
||||
m_entries = m_pos;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool read_strings(size_t a_size,void* a_array) {
|
||||
unsigned int _size = a_size*m_size;
|
||||
unsigned int n = 0;
|
||||
char* array = 0;
|
||||
if(!read_sub_array<char>(m_group,s_pages(),m_pos,_size,n,array)) {
|
||||
m_out << "pages::read_strings : read_sub_array<char>() failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
if(n!=_size) {
|
||||
m_out << "pages::read_strings : size mismatch. Requested " << _size << ", got "<< n << "." << std::endl;
|
||||
delete [] array;
|
||||
return false;
|
||||
}
|
||||
char* pos = array;
|
||||
{char** strings = (char**)a_array;
|
||||
for(size_t index=0;index<a_size;index++) {
|
||||
::memcpy(strings[index],pos,m_size*sizeof(char));
|
||||
pos += m_size;
|
||||
}}
|
||||
delete [] array;
|
||||
m_pos += n;
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
protected:
|
||||
std::ostream& m_out;
|
||||
std::string m_name;
|
||||
std::string m_form;
|
||||
//int m_type;
|
||||
//unsigned int m_size;
|
||||
hid_t m_group;
|
||||
hid_t m_dataset;
|
||||
bool m_write;
|
||||
unsigned int m_compress; //if write.
|
||||
tools::uint64 m_entries;
|
||||
tools::uint64 m_pos;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,193 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_store
|
||||
#define tools_hdf5_store
|
||||
|
||||
#include "pages"
|
||||
|
||||
#include <tools/vmanip>
|
||||
#include <tools/sout>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
class store {
|
||||
public:
|
||||
TOOLS_SCLASS(tools::hdf5::store)
|
||||
public:
|
||||
store(std::ostream& a_out,hid_t a_group,const std::string& a_name,bool a_write,unsigned int a_compress)
|
||||
:m_out(a_out)
|
||||
,m_write(a_write)
|
||||
,m_compress(a_compress) //used at write.
|
||||
,m_group(-1)
|
||||
{
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
if(m_write) {
|
||||
if(a_name.empty()) {
|
||||
a_out << "tools::hdf5::store::store : string a_name is empty." << std::endl;
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
m_group = tools_H5Gcreate(a_group,a_name.c_str(),0);
|
||||
if(m_group<0) {
|
||||
a_out << "tools::hdf5::store::store : can't create " << a_name << " group." << std::endl;
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
if(!write_atb(m_group,"class",s_class())) {
|
||||
m_out << "tools::hdf5::store::store : write_atb(class) failed." << std::endl;
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
int v = 1;
|
||||
if(!write_scalar_atb<int>(m_group,"version",v)) {
|
||||
m_out << "tools::hdf5::store::store : write_scalar_atb(version) failed." << std::endl;
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
} else { // to read.
|
||||
m_group = tools_H5Gopen(a_group,a_name.c_str());
|
||||
if(m_group<0) {
|
||||
a_out << "tools::hdf5::store::store : can't open " << a_name << " group." << std::endl;
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> names;
|
||||
if(!read_array_string(m_group,s_names(),names)) {
|
||||
m_out << "tools::hdf5::store::store : read_array_string(names) failed." << std::endl;
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> TFORMs;
|
||||
if(!read_array_string(m_group,s_forms(),TFORMs)) {
|
||||
m_out << "tools::hdf5::store::store : read_array_string(tforms) failed." << std::endl;
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
if(names.size()!=TFORMs.size()) {
|
||||
m_out << "tools::hdf5::store::store : names/TFORMs size mismatch." << std::endl;
|
||||
m_out << "names :" << std::endl;
|
||||
{tools_vforcit(std::string,names,it) m_out << *it << std::endl;}
|
||||
m_out << "TFORMs :" << std::endl;
|
||||
{tools_vforcit(std::string,TFORMs,it) m_out << *it << std::endl;}
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
for(size_t index=0;index<names.size();index++) {
|
||||
if(!create_pages(names[index],TFORMs[index])) {
|
||||
m_out << "tools::hdf5::store::store : can't create hdf5_column "
|
||||
<< tools::sout(names[index]) << "." << std::endl;
|
||||
tools::safe_clear(m_pagess);
|
||||
::H5Gclose(m_group);
|
||||
m_group = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual ~store(){
|
||||
if(m_write) {
|
||||
tools::uint64 _entries;
|
||||
if(!entries(_entries)) {
|
||||
m_out << "tools::hdf5::store::~store : not same entries on all columns. Write 0." << std::endl;
|
||||
}
|
||||
if(!write_scalar<tools::uint64>(m_group,s_entries(),_entries)) {
|
||||
m_out << "tools::hdf5::store::~store : write_scalar(entries) failed." << std::endl;
|
||||
}
|
||||
if(!write_scalar<unsigned int>(m_group,s_columns(),m_pagess.size())) {
|
||||
m_out << "tools::hdf5::store::~store : write_scalar(columns) failed." << std::endl;
|
||||
}
|
||||
{std::vector<std::string> names;
|
||||
tools_vforcit(pages*,m_pagess,it) names.push_back((*it)->name());
|
||||
//{m_out << "debug : write : names :" << std::endl;
|
||||
// tools_vforcit(std::string,names,it) m_out << *it << std::endl;}
|
||||
if(!write_array_string(m_group,s_names(),names)) {
|
||||
m_out << "tools::hdf5::store::~store : write_array_string(names) failed." << std::endl;
|
||||
}}
|
||||
{std::vector<std::string> TFORMs;
|
||||
tools_vforcit(pages*,m_pagess,it) TFORMs.push_back((*it)->form());
|
||||
//{m_out << "debug : write : TFORMs :" << std::endl;
|
||||
// tools_vforcit(std::string,TFORMs,it) m_out << *it << std::endl;}
|
||||
if(!write_array_string(m_group,s_forms(),TFORMs)) {
|
||||
m_out << "tools::hdf5::store::~store : write_array_string(tforms) failed." << std::endl;
|
||||
}}
|
||||
}
|
||||
tools::safe_clear(m_pagess);
|
||||
::H5Gclose(m_group);
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
protected:
|
||||
store(const store& a_from)
|
||||
:m_out(a_from.m_out)
|
||||
,m_name(a_from.m_name)
|
||||
,m_compress(a_from.m_compress)
|
||||
,m_group(-1)
|
||||
{
|
||||
#ifdef TOOLS_MEM
|
||||
tools::mem::increment(s_class().c_str());
|
||||
#endif
|
||||
}
|
||||
store& operator=(const store&){return *this;}
|
||||
public:
|
||||
std::ostream& out() const {return m_out;}
|
||||
//bool fill(tools::uint32 &a_n){a_n = 0;return true;}
|
||||
|
||||
bool entries(tools::uint64& a_entries) const {
|
||||
if(m_pagess.empty()) {a_entries = 0;return true;}
|
||||
a_entries = m_pagess.front()->entries();
|
||||
tools_vforcit(pages*,m_pagess,it) {
|
||||
if((*it)->entries()!=a_entries) {
|
||||
m_out << "tools::hdf5::store::entries : not same entries on all columns."
|
||||
<< " Front " << a_entries << ", it " << (*it)->entries() << "." << std::endl;
|
||||
a_entries = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
pages* create_pages(const std::string& a_name,const std::string& a_form) {
|
||||
//::printf("debug : create_pages %s %s\n",a_name.c_str(),a_form.c_str());
|
||||
pages* _pages = new pages(m_out,m_group,a_name,a_form,m_write,m_compress);
|
||||
if(!_pages->is_valid()) {
|
||||
m_out << "tools::hdf5::store::create_column : can't create pages." << std::endl;
|
||||
delete _pages;
|
||||
return 0;
|
||||
}
|
||||
m_pagess.push_back(_pages);
|
||||
return _pages;
|
||||
}
|
||||
/*
|
||||
pages* find_column(unsigned int a_index) {
|
||||
if(a_index>=m_pagess.size()) {
|
||||
m_out << "tools::hdf5::store::find_column : out of range index." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
return m_pagess[a_index];
|
||||
}
|
||||
const std::vector<pages*>& columns() const {return m_pagess;}*/
|
||||
|
||||
hid_t group() const {return m_group;}
|
||||
unsigned int compress_level() const {return m_compress;}
|
||||
protected:
|
||||
std::ostream& m_out;
|
||||
std::string m_name;
|
||||
bool m_write;
|
||||
unsigned int m_compress;
|
||||
hid_t m_group;
|
||||
std::vector<pages*> m_pagess;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,749 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_hdf5_tools
|
||||
#define tools_hdf5_tools
|
||||
|
||||
#include "hdf5_h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline bool check_sizes(){
|
||||
if(sizeof(bool)!=1) return false;
|
||||
if(sizeof(char)!=1) return false;
|
||||
if(sizeof(short)!=2) return false;
|
||||
if(sizeof(int)!=4) return false;
|
||||
if(sizeof(float)!=4) return false;
|
||||
if(sizeof(double)!=8) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline int failure() {return -1;}
|
||||
|
||||
inline hid_t string_datatype(size_t aSize){
|
||||
// aSize should include the trailing null char.
|
||||
hid_t datatype = ::H5Tcopy(H5T_C_S1);
|
||||
if(datatype<0) return failure();
|
||||
|
||||
if(::H5Tset_size(datatype,aSize)<0) {
|
||||
::H5Tclose(datatype);
|
||||
return failure();
|
||||
}
|
||||
|
||||
if(::H5Tset_strpad(datatype,H5T_STR_NULLTERM)<0) {
|
||||
::H5Tclose(datatype);
|
||||
return failure();
|
||||
}
|
||||
|
||||
return datatype;
|
||||
}
|
||||
|
||||
inline hid_t basic_mem_type(hid_t a_file_type){
|
||||
H5T_class_t mclass = H5Tget_class(a_file_type);
|
||||
size_t msize = H5Tget_size(a_file_type);
|
||||
if(mclass==H5T_INTEGER) {
|
||||
H5T_sign_t msign = H5Tget_sign(a_file_type);
|
||||
if(msize==1) {
|
||||
if(msign==H5T_SGN_NONE) {
|
||||
return H5Tcopy(H5T_NATIVE_UCHAR);
|
||||
} else {
|
||||
return H5Tcopy(H5T_NATIVE_CHAR);
|
||||
}
|
||||
} else if(msize==4) {
|
||||
if(msign==H5T_SGN_NONE) {
|
||||
return H5Tcopy(H5T_NATIVE_UINT);
|
||||
} else {
|
||||
return H5Tcopy(H5T_NATIVE_INT);
|
||||
}
|
||||
} else if(msize==8) { //for osc_file::header::fDate.
|
||||
if(msign==H5T_SGN_NONE) {
|
||||
return H5Tcopy(H5T_NATIVE_UINT64);
|
||||
} else {
|
||||
return H5Tcopy(H5T_NATIVE_INT64);
|
||||
}
|
||||
} else {
|
||||
return failure();
|
||||
}
|
||||
} else if(mclass==H5T_FLOAT) {
|
||||
if(msize==4) {
|
||||
return H5Tcopy(H5T_NATIVE_FLOAT);
|
||||
} else if(msize==8) {
|
||||
return H5Tcopy(H5T_NATIVE_DOUBLE);
|
||||
} else {
|
||||
return failure();
|
||||
}
|
||||
} else if(mclass==H5T_STRING) {
|
||||
return H5Tcopy(a_file_type);
|
||||
}
|
||||
|
||||
return failure();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline hid_t compound_mem_type(hid_t a_file_type){
|
||||
// FIXME : In principle H5T_get_native_type should do the job but it crashes.
|
||||
|
||||
H5T_class_t t_class = H5Tget_class(a_file_type);
|
||||
if(t_class!=H5T_COMPOUND) return failure();
|
||||
|
||||
size_t sz = H5Tget_size(a_file_type);
|
||||
//printf("debug : compound_mem_type : sz %lu\n",sz);
|
||||
|
||||
hid_t memtype = ::H5Tcreate(H5T_COMPOUND,sz);
|
||||
if(memtype<0) return failure();
|
||||
|
||||
//FIXME : WARNING : is order the booked order ?
|
||||
|
||||
int mn = H5Tget_nmembers(a_file_type);
|
||||
std::vector<unsigned int> szs(mn);
|
||||
//printf("debug : members : %d\n",mn);
|
||||
for(int index=0;index<mn;index++) {
|
||||
char* mname = H5Tget_member_name(a_file_type,index);
|
||||
size_t moffset = H5Tget_member_offset(a_file_type,index);
|
||||
hid_t mtype = H5Tget_member_type(a_file_type,index);
|
||||
//printf("debug : members : %d (%d) : %s : begin\n",index,mn,mname);
|
||||
|
||||
{H5T_class_t mclass = H5Tget_class(mtype);
|
||||
if( (mclass==H5T_INTEGER) ||
|
||||
(mclass==H5T_STRING) ||
|
||||
(mclass==H5T_FLOAT) ) {
|
||||
hid_t mmemtype = basic_mem_type(mtype);
|
||||
if(mmemtype<0) {
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
if(H5Tinsert(memtype,mname,moffset,mmemtype)<0) {
|
||||
::H5Tclose(mmemtype);
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
::H5Tclose(mmemtype);
|
||||
|
||||
} else if(mclass==H5T_ARRAY) {
|
||||
int dimn = ::H5Tget_array_ndims(mtype); //Should be 1;
|
||||
hsize_t* dims = new hsize_t[dimn];
|
||||
int* perms = new int[dimn];
|
||||
if(tools_H5Tget_array_dims(mtype,dims,perms)<0) {
|
||||
delete [] dims;
|
||||
delete [] perms;
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
hid_t base_type = H5Tget_super(mtype);
|
||||
if(base_type<0) {
|
||||
delete [] dims;
|
||||
delete [] perms;
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
hid_t mmemtype = basic_mem_type(base_type);
|
||||
if(mmemtype<0) {
|
||||
delete [] dims;
|
||||
delete [] perms;
|
||||
::H5Tclose(base_type);
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
::H5Tclose(base_type);
|
||||
hid_t array_type = tools_H5Tarray_create(mmemtype,dimn,dims,perms);
|
||||
delete [] dims;
|
||||
delete [] perms;
|
||||
if(array_type<0) {
|
||||
::H5Tclose(mmemtype);
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
::H5Tclose(mmemtype);
|
||||
|
||||
if(H5Tinsert(memtype,mname,moffset,array_type)<0) {
|
||||
::H5Tclose(array_type);
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
::H5Tclose(array_type);
|
||||
|
||||
} else if(mclass==H5T_COMPOUND) {
|
||||
hid_t mmemtype = compound_mem_type(mtype);
|
||||
if(memtype<0) {
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
if(H5Tinsert(memtype,mname,moffset,mmemtype)<0) {
|
||||
::H5Tclose(mmemtype);
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}
|
||||
::H5Tclose(mmemtype);
|
||||
} else {
|
||||
::H5Tclose(mtype);
|
||||
if(mname) ::free(mname);
|
||||
::H5Tclose(memtype);
|
||||
return failure();
|
||||
}}
|
||||
::H5Tclose(mtype);
|
||||
//printf("debug : compound_mem_type : %d (%d) : %s : end\n",index,mn,mname);
|
||||
if(mname) ::free(mname);
|
||||
}
|
||||
|
||||
return memtype;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#include "atb"
|
||||
#include <string>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline bool read_atb(hid_t aID,const std::string& a_name,std::string& aData,unsigned int aSize = 100){
|
||||
// From H5LT.c/H5LTget_attribute_string.
|
||||
if(!H5LT_find_attribute(aID,a_name.c_str())) {aData.clear();return false;}
|
||||
char* b = new char[aSize];
|
||||
if(H5LT_get_attribute_disk(aID,a_name.c_str(),b)<0) {
|
||||
delete [] b;
|
||||
return false;
|
||||
}
|
||||
aData = std::string(b);
|
||||
delete [] b;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_atb(hid_t aID,const std::string& a_name,unsigned int& aData){
|
||||
if(!H5LT_find_attribute(aID,a_name.c_str())) {aData=0;return false;}
|
||||
if(H5LT_get_attribute_mem(aID,a_name.c_str(),H5T_NATIVE_UINT,&aData)<0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_atb(hid_t aID,const std::string& a_name,int& aData){
|
||||
if(!H5LT_find_attribute(aID,a_name.c_str())) {aData=0;return false;}
|
||||
if(H5LT_get_attribute_mem(aID,a_name.c_str(),H5T_NATIVE_INT,&aData)<0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline hid_t H5T_STD_U8XX() {return H5T_STD_U8LE;}
|
||||
inline hid_t H5T_STD_U32XX() {return H5T_STD_U32LE;}
|
||||
inline hid_t H5T_STD_U64XX() {return H5T_STD_U64LE;}
|
||||
inline hid_t H5T_STD_I8XX() {return H5T_STD_I8LE;}
|
||||
inline hid_t H5T_STD_I16XX() {return H5T_STD_I16LE;}
|
||||
inline hid_t H5T_STD_I32XX() {return H5T_STD_I32LE;}
|
||||
inline hid_t H5T_STD_I64XX() {return H5T_STD_I64LE;}
|
||||
inline hid_t H5T_IEEE_F32XX() {return H5T_IEEE_F32LE;}
|
||||
inline hid_t H5T_IEEE_F64XX() {return H5T_IEEE_F64LE;}
|
||||
|
||||
inline bool dataset_vec_size(hid_t a_loc,const std::string& a_name,hsize_t& a_size) {
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) {
|
||||
a_size = 0;
|
||||
return false; // data set not found.
|
||||
}
|
||||
|
||||
hid_t file_space = H5Dget_space(dataset);
|
||||
if(file_space<0) {
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
int dimn = H5Sget_simple_extent_ndims(file_space);
|
||||
if(dimn<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
return false;
|
||||
}
|
||||
if(dimn!=1) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
return false;
|
||||
}
|
||||
//printf("debug : read dimn %d\n",dimn);
|
||||
|
||||
hsize_t dims[1];
|
||||
{if(H5Sget_simple_extent_dims(file_space,dims,NULL)<0) {
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
return false;
|
||||
}}
|
||||
|
||||
::H5Sclose(file_space);
|
||||
::H5Dclose(dataset);
|
||||
|
||||
a_size = dims[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool write_atb(hid_t aDS,const std::string& a_name,const std::string& aData){
|
||||
// From H5LT.c/H5LTset_attribute_string.
|
||||
int has_attr = H5LT_find_attribute(aDS,a_name.c_str());
|
||||
if(has_attr==1) {
|
||||
if(H5Adelete(aDS,a_name.c_str())<0) return false;
|
||||
}
|
||||
|
||||
hid_t datatype = string_datatype(aData.size()+1);
|
||||
if(datatype<0) return false;
|
||||
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) {
|
||||
::H5Tclose(datatype);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t aid = tools_H5Acreate(aDS,a_name.c_str(),datatype,scalar,H5P_DEFAULT);
|
||||
if(aid<0) {
|
||||
::H5Sclose(scalar);
|
||||
::H5Tclose(datatype);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Awrite(aid,datatype,aData.c_str())<0) {
|
||||
::H5Aclose(aid);
|
||||
::H5Sclose(scalar);
|
||||
::H5Tclose(datatype);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Aclose(aid);
|
||||
::H5Sclose(scalar);
|
||||
::H5Tclose(datatype);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool write_bool(hid_t a_loc,const std::string& a_name,bool aData) {
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) return false;
|
||||
|
||||
hid_t compact = ::H5Pcreate(H5P_DATASET_CREATE);
|
||||
if(compact<0) {
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
if(H5Pset_layout(compact,H5D_COMPACT)<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t dataset = tools_H5Dcreate(a_loc,a_name.c_str(),H5T_STD_U8XX(),scalar,compact);
|
||||
if(dataset<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char data = aData?1:0;
|
||||
if(::H5Dwrite(dataset,H5T_NATIVE_UCHAR,H5S_ALL,H5S_ALL,H5P_DEFAULT,&data)<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool write_string(hid_t a_loc,const std::string& a_name,const std::string& aString) {
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) return false;
|
||||
|
||||
hid_t compact = ::H5Pcreate(H5P_DATASET_CREATE);
|
||||
if(compact<0) {
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Pset_layout(compact,H5D_COMPACT)<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
// From H5LTmakge_dataset_string.
|
||||
hid_t filetype = string_datatype(aString.size()+1);
|
||||
if(filetype<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t dataset = tools_H5Dcreate(a_loc,a_name.c_str(),filetype,scalar,compact);
|
||||
if(dataset<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Tclose(filetype);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t memtype = filetype;
|
||||
if(H5Dwrite(dataset,memtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,aString.c_str())<0) {
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
::H5Tclose(filetype);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Pclose(compact);
|
||||
::H5Sclose(scalar);
|
||||
::H5Dclose(dataset);
|
||||
::H5Tclose(filetype);
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#include <tools/buf2lines>
|
||||
|
||||
namespace tools {
|
||||
namespace hdf5 {
|
||||
|
||||
inline bool write_array_string(hid_t a_loc,const std::string& a_name,const std::vector<std::string>& a_array) {
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) return false;
|
||||
|
||||
// From H5LTmake_dataset_string.
|
||||
size_t sz;
|
||||
char* buffer;
|
||||
if(!tools::strings2buf(a_array,sz,buffer)) {
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t filetype = string_datatype(sz);
|
||||
if(filetype<0) {
|
||||
delete [] buffer;
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t dataset = tools_H5Dcreate(a_loc,a_name.c_str(),filetype,scalar,H5P_DEFAULT);
|
||||
if(dataset<0) {
|
||||
delete [] buffer;
|
||||
::H5Tclose(filetype);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t memtype = filetype;
|
||||
if(H5Dwrite(dataset,memtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,buffer)<0) {
|
||||
delete [] buffer;
|
||||
::H5Dclose(dataset);
|
||||
::H5Tclose(filetype);
|
||||
::H5Sclose(scalar);
|
||||
return false;
|
||||
}
|
||||
|
||||
delete [] buffer;
|
||||
|
||||
::H5Dclose(dataset);
|
||||
::H5Tclose(filetype);
|
||||
::H5Sclose(scalar);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool write_object(hid_t a_loc,const std::string& a_name,hid_t a_file_type,char* aData) {
|
||||
unsigned int chunked = 0;
|
||||
unsigned int compress = 0;
|
||||
|
||||
hid_t cpt = -1;
|
||||
if(compress || chunked) {
|
||||
cpt = ::H5Pcreate(H5P_DATASET_CREATE);
|
||||
if(cpt<0) return false;
|
||||
if(chunked) {
|
||||
if(H5Pset_layout(cpt,H5D_CHUNKED)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
hsize_t cdims[1];
|
||||
cdims[0] = chunked;
|
||||
if(H5Pset_chunk(cpt,1,cdims)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(H5Pset_layout(cpt,H5D_COMPACT)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(compress) {
|
||||
if(H5Pset_deflate(cpt,compress>9?9:compress)<0) {
|
||||
::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cpt = H5P_DEFAULT;
|
||||
}
|
||||
|
||||
hsize_t dims[1];
|
||||
dims[0] = 1;
|
||||
hid_t simple = ::H5Screate_simple(1,dims,NULL);
|
||||
if(simple<0) {
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t mem_type = compound_mem_type(a_file_type);
|
||||
if(mem_type<0) {
|
||||
::H5Sclose(simple);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t dataset = tools_H5Dcreate(a_loc,a_name.c_str(),a_file_type,simple,cpt);
|
||||
if(dataset<0) {
|
||||
::H5Tclose(mem_type);
|
||||
::H5Sclose(simple);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(H5Dwrite(dataset,mem_type,H5S_ALL,H5S_ALL,H5P_DEFAULT,aData)<0) {
|
||||
::H5Dclose(dataset);
|
||||
::H5Tclose(mem_type);
|
||||
::H5Sclose(simple);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Dclose(dataset);
|
||||
::H5Tclose(mem_type);
|
||||
::H5Sclose(simple);
|
||||
if(cpt>=0) ::H5Pclose(cpt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_string(hid_t a_loc,const std::string& a_name,std::string& aString) {
|
||||
// From H5LTread_dataset_string.
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) {
|
||||
aString.clear();
|
||||
return false; // data set not found.
|
||||
}
|
||||
|
||||
hid_t filetype = H5Dget_type(dataset);
|
||||
if(filetype<0) {
|
||||
::H5Dclose(dataset);
|
||||
aString.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
H5T_class_t t_class = H5Tget_class(filetype);
|
||||
if(t_class!=H5T_STRING) {
|
||||
::H5Tclose(filetype);
|
||||
::H5Dclose(dataset);
|
||||
aString.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t sz = H5Tget_size(filetype);
|
||||
::H5Tclose(filetype);
|
||||
if(!sz) {
|
||||
::H5Dclose(dataset);
|
||||
aString.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
// We could have use filetype since, for string,
|
||||
// file type is the same than memory type.
|
||||
hid_t memtype = string_datatype(sz);
|
||||
if(memtype<0) {
|
||||
::H5Dclose(dataset);
|
||||
aString.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
char* buff = new char[sz];
|
||||
herr_t stat = H5Dread(dataset,memtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,buff);
|
||||
::H5Tclose(memtype);
|
||||
::H5Dclose(dataset);
|
||||
if(stat<0) {
|
||||
delete [] buff;
|
||||
aString.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t len = sz-1;
|
||||
aString.resize(len,0);
|
||||
for(size_t index=0;index<len;index++) aString[index] = buff[index];
|
||||
|
||||
delete [] buff;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_object(hid_t a_loc,const std::string& a_name,size_t& a_size,char*& aData) {
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) {
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t filetype = H5Dget_type(dataset);
|
||||
if(filetype<0) {
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
H5T_class_t t_class = H5Tget_class(filetype);
|
||||
if(t_class!=H5T_COMPOUND) {
|
||||
::H5Tclose(filetype);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t sz = H5Tget_size(filetype);
|
||||
if(!sz) {
|
||||
::H5Tclose(filetype);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t memtype = compound_mem_type(filetype);
|
||||
if(memtype<0) {
|
||||
::H5Tclose(filetype);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Tclose(filetype);
|
||||
|
||||
hid_t dataspace = H5Dget_space(dataset);
|
||||
if(dataspace<0) {
|
||||
::H5Tclose(memtype);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
hid_t scalar = ::H5Screate(H5S_SCALAR);
|
||||
if(scalar<0) {
|
||||
::H5Sclose(dataspace);
|
||||
::H5Tclose(memtype);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
char* buffer = new char[sz];
|
||||
if(H5Dread(dataset,memtype,scalar,dataspace,H5P_DEFAULT,buffer)<0) {
|
||||
delete [] buffer;
|
||||
::H5Sclose(scalar);
|
||||
::H5Sclose(dataspace);
|
||||
::H5Tclose(memtype);
|
||||
::H5Dclose(dataset);
|
||||
a_size = 0;
|
||||
aData = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
::H5Sclose(scalar);
|
||||
::H5Sclose(dataspace);
|
||||
::H5Tclose(memtype);
|
||||
::H5Dclose(dataset);
|
||||
|
||||
a_size = sz;
|
||||
aData = buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool read_array_string(hid_t a_loc,const std::string& a_name,std::vector<std::string>& a_array) {
|
||||
a_array.clear();
|
||||
hid_t dataset = tools_H5Dopen(a_loc,a_name.c_str());
|
||||
if(dataset<0) return false;
|
||||
|
||||
hid_t filetype = H5Dget_type(dataset);
|
||||
if(filetype<0) {
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
H5T_class_t t_class = H5Tget_class(filetype);
|
||||
if(t_class!=H5T_STRING) {
|
||||
::H5Tclose(filetype);
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t sz = H5Tget_size(filetype);
|
||||
::H5Tclose(filetype);
|
||||
if(!sz) {
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
// We could have use filetype since, for string,
|
||||
// file type is the same than memory type.
|
||||
hid_t memtype = string_datatype(sz);
|
||||
if(memtype<0) {
|
||||
::H5Dclose(dataset);
|
||||
return false;
|
||||
}
|
||||
|
||||
char* buffer = new char[sz];
|
||||
herr_t stat = H5Dread(dataset,memtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,buffer);
|
||||
::H5Tclose(memtype);
|
||||
::H5Dclose(dataset);
|
||||
if(stat<0) {
|
||||
delete [] buffer;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!tools::buf2strings(sz,buffer,a_array)) {
|
||||
delete [] buffer;
|
||||
return false;
|
||||
}
|
||||
|
||||
delete [] buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user