Discussion:
Adding Hdf5 Plugin, cant see _matrixlist
Manuel Ilg
2017-09-01 14:53:00 UTC
Permalink
Hi,

I am trying to add Hdf5 as Datasource to kst. It already works with
vectors. So if i open a hdf5 file it recursively searches the file for 1
dimensional Datasets. I can select all these Datasets and plot them.

After this worked fine, i looked at the matlab.cpp and netcdfsource.cpp
files again and tried to copy their matrix interfaces but i cant get it
to work. i save all the matrices in the _matrixList but appearently kst
never uses the list() of my matrixdatainterface class. So i cant select
the datasets in the kst gui.

this is my matrix interface class:

/**********************
Matrix Interface
***********************/
class DataInterfaceHdf5Matrix : public DataSource::DataInterface<DataMatrix>
{
public:

DataInterfaceHdf5Matrix(Hdf5Source& s) : Hdf5(s) {qDebug()<< "matrix";}

// read one element
int read(const QString&, DataMatrix::ReadInfo&);

// named elements
QStringList list() const { qDebug() << "list() mat" << endl; return
Hdf5._matrixList; }
bool isListComplete() const { return true; }
bool isValid(const QString&) const;

// T specific
const DataMatrix::DataInfo dataInfo (const QString&) const;
void setDataInfo(const QString&, const DataMatrix::DataInfo&) {}

// meta data
QMap<QString, double> metaScalars(const QString&) { return
QMap<QString, double>(); }
QMap<QString, QString> metaStrings(const QString&) { return
QMap<QString, QString>(); }


private:
Hdf5Source& Hdf5;
};


const DataMatrix::DataInfo DataInterfaceHdf5Matrix::dataInfo(const
QString& matrix) const
{
qDebug() << "im info" << endl;
if (!Hdf5._matrixList.contains( matrix ) ) {
return DataMatrix::DataInfo();
}

QByteArray bytes = matrix.toLatin1();
hid_t dataset = H5Dopen(Hdf5._Hdf5file, bytes.data(), H5P_DEFAULT);
hid_t dspace = H5Dget_space(dataset);
const int ndims = H5Sget_simple_extent_ndims(dspace);
hsize_t dims[ndims];
H5Sget_simple_extent_dims(dspace, dims, NULL);
H5Dclose(dataset);
H5Sclose(dspace);
if (!ndims) {
return DataMatrix::DataInfo();
}

if (ndims != 2) {
return DataMatrix::DataInfo();
}

DataMatrix::DataInfo info;
info.samplesPerFrame = 1;
info.xSize = dims[0];
info.ySize = dims[1];

return info;
}

int DataInterfaceHdf5Matrix::read(const QString& field,
DataMatrix::ReadInfo& p)
{qDebug() << "im read" << endl;
int count = Hdf5.readMatrix(p.data->z, field);

p.data->xMin = 0;
p.data->yMin = 0;
p.data->xStepSize = 1;
p.data->yStepSize = 1;

return count;
}


bool DataInterfaceHdf5Matrix::isValid(const QString& field) const {
qDebug() << "im valid" << endl;
return Hdf5._matrixList.contains( field );
}

the only method beeing used is:
DataInterfaceHdf5Matrix(Hdf5Source& s) : Hdf5(s) {qDebug()<< "matrix";}
all others were never used. I hope you can give me a hint, what im doing
wrong. Like i said i can see and plot all 1 dimensional Datasets, they
are stored in _fieldList and use the DataVector DataInterface. But i
cant see or plot the 2 dimensional Data in the DataMatrix DataInterface.
i cant even display the names that are stored in the _matrixList in kst.

here is my header file:

#ifndef Hdf5_H
#define Hdf5_H

#include <datasource.h>
#include <dataplugin.h>
#include "H5Cpp.h"

class DataInterfaceHdf5Vector;
class DataInterfaceHdf5Matrix;


class Hdf5Source : public Kst::DataSource {
Q_OBJECT

public:
Hdf5Source(Kst::ObjectStore *store, QSettings *cfg, const QString&
filename, const QString& type, const QDomElement& e);

~Hdf5Source();

bool init();
virtual void reset();

Kst::Object::UpdateType internalDataSourceUpdate();

int readField(double *v, const QString& field, int s, int n);

int readMatrix(double *v, const QString& field);

static herr_t file_info(hid_t o_id, const char *name, const
H5O_info_t *object_info, void *op_data);

int samplesPerFrame(const QString& field);
int frameCount(const QString& field = QString()) const;

QString fileType() const;

void save(QXmlStreamWriter &streamWriter);


private:
QMap<QString, int> _frameCounts;
int _maxFrameCount;

hid_t _Hdf5file;
QStringList _fieldList;
QStringList _matrixList;

friend class DataInterfaceHdf5Vector;
friend class DataInterfaceHdf5Matrix;

DataInterfaceHdf5Vector* iv;
DataInterfaceHdf5Matrix* im;
};

if u need more Details just ask.

Have a nice Weekend :)
Nicolas Brisset
2017-10-10 20:49:02 UTC
Permalink
Hi Manuel,

Sorry for the slow answer, I hope you haven't lost interest! This is in fact pretty cool, adding support for HDF5 has been on the todo list for a while.
In fact as you may have seen on the mailing list there have been discussions in the past regarding the use of netCDF to read in HDF5 files. Supposedly, if you compile the netCDF lib with HDF5 support it should work but it seems many netCDF libs are not built in that way. A proper HDF5 datasource is probably nicer :-)

Anyway, regarding your question I suspect you haven't tried the right tool. If you use the datawizard it won't look for matrices. Have you tried the Create -> Matrix menu? Directly or from the Create -> Image and then clicking on the matrix with a small star? Once you've created a matrix, it should be possible to visualize with the View -> Matrices menu.

If you have a working HDF5 datasource, it would be nice to provide it to the community! HDF5 has become so widespread these last years, that I'm sure there will be many interested people.

Hoping to hear back from you soon,

Nicolas

----- Mail original -----
Envoyé: Vendredi 1 Septembre 2017 16:53:00
Objet: Adding Hdf5 Plugin, cant see _matrixlist
Hi,
I am trying to add Hdf5 as Datasource to kst. It already works with
vectors. So if i open a hdf5 file it recursively searches the file
for 1
dimensional Datasets. I can select all these Datasets and plot them.
After this worked fine, i looked at the matlab.cpp and
netcdfsource.cpp
files again and tried to copy their matrix interfaces but i cant get
it
to work. i save all the matrices in the _matrixList but appearently
kst
never uses the list() of my matrixdatainterface class. So i cant
select
the datasets in the kst gui.
/**********************
Matrix Interface
***********************/
class DataInterfaceHdf5Matrix : public
DataSource::DataInterface<DataMatrix>
{
DataInterfaceHdf5Matrix(Hdf5Source& s) : Hdf5(s) {qDebug()<<
"matrix";}
// read one element
int read(const QString&, DataMatrix::ReadInfo&);
// named elements
QStringList list() const { qDebug() << "list() mat" << endl; return
Hdf5._matrixList; }
bool isListComplete() const { return true; }
bool isValid(const QString&) const;
// T specific
const DataMatrix::DataInfo dataInfo (const QString&) const;
void setDataInfo(const QString&, const DataMatrix::DataInfo&) {}
// meta data
QMap<QString, double> metaScalars(const QString&) { return
QMap<QString, double>(); }
QMap<QString, QString> metaStrings(const QString&) { return
QMap<QString, QString>(); }
Hdf5Source& Hdf5;
};
const DataMatrix::DataInfo DataInterfaceHdf5Matrix::dataInfo(const
QString& matrix) const
{
qDebug() << "im info" << endl;
if (!Hdf5._matrixList.contains( matrix ) ) {
return DataMatrix::DataInfo();
}
QByteArray bytes = matrix.toLatin1();
hid_t dataset = H5Dopen(Hdf5._Hdf5file, bytes.data(), H5P_DEFAULT);
hid_t dspace = H5Dget_space(dataset);
const int ndims = H5Sget_simple_extent_ndims(dspace);
hsize_t dims[ndims];
H5Sget_simple_extent_dims(dspace, dims, NULL);
H5Dclose(dataset);
H5Sclose(dspace);
if (!ndims) {
return DataMatrix::DataInfo();
}
if (ndims != 2) {
return DataMatrix::DataInfo();
}
DataMatrix::DataInfo info;
info.samplesPerFrame = 1;
info.xSize = dims[0];
info.ySize = dims[1];
return info;
}
int DataInterfaceHdf5Matrix::read(const QString& field,
DataMatrix::ReadInfo& p)
{qDebug() << "im read" << endl;
int count = Hdf5.readMatrix(p.data->z, field);
p.data->xMin = 0;
p.data->yMin = 0;
p.data->xStepSize = 1;
p.data->yStepSize = 1;
return count;
}
bool DataInterfaceHdf5Matrix::isValid(const QString& field) const {
qDebug() << "im valid" << endl;
return Hdf5._matrixList.contains( field );
}
DataInterfaceHdf5Matrix(Hdf5Source& s) : Hdf5(s) {qDebug()<<
"matrix";}
all others were never used. I hope you can give me a hint, what im
doing
wrong. Like i said i can see and plot all 1 dimensional Datasets,
they
are stored in _fieldList and use the DataVector DataInterface. But i
cant see or plot the 2 dimensional Data in the DataMatrix
DataInterface.
i cant even display the names that are stored in the _matrixList in
kst.
#ifndef Hdf5_H
#define Hdf5_H
#include <datasource.h>
#include <dataplugin.h>
#include "H5Cpp.h"
class DataInterfaceHdf5Vector;
class DataInterfaceHdf5Matrix;
class Hdf5Source : public Kst::DataSource {
Q_OBJECT
Hdf5Source(Kst::ObjectStore *store, QSettings *cfg, const QString&
filename, const QString& type, const QDomElement& e);
~Hdf5Source();
bool init();
virtual void reset();
Kst::Object::UpdateType internalDataSourceUpdate();
int readField(double *v, const QString& field, int s, int n);
int readMatrix(double *v, const QString& field);
static herr_t file_info(hid_t o_id, const char *name, const
H5O_info_t *object_info, void *op_data);
int samplesPerFrame(const QString& field);
int frameCount(const QString& field = QString()) const;
QString fileType() const;
void save(QXmlStreamWriter &streamWriter);
QMap<QString, int> _frameCounts;
int _maxFrameCount;
hid_t _Hdf5file;
QStringList _fieldList;
QStringList _matrixList;
friend class DataInterfaceHdf5Vector;
friend class DataInterfaceHdf5Matrix;
DataInterfaceHdf5Vector* iv;
DataInterfaceHdf5Matrix* im;
};
if u need more Details just ask.
Have a nice Weekend :)
Loading...