我正在使用 HDF.PInvoke 和 C#。
我已经开发了很多代码来保存 2D 数据集,一切都运行良好。
我现在希望将一系列 2D 数据集(大小恒定的宽度 * 宽度)写入 3D 数组,但我发现我无法首先创建 3D 数据集。数据采用节距线性数组的形式,我尝试做的第一件事是创建一个可在“Z”方向扩展的 width * width * 1 数据集。 该代码后面带有错误发生位置的指示符。 非常感激收到任何帮助...
using HDF.PInvoke;
using hid_t = System.Int64;
using hsize_t = System.UInt64;
public static void Create3DDataSet(hid_t gpID, string name, ushort[] im )
{
const int width = 2048;
System.Diagnostics.Trace.Assert(im.Length == width * width);
const int rank = 3;
hsize_t[] current_dims = new hsize_t[rank] { width, width, 1 };
hsize_t[] max_Dims = new hsize_t[rank] { width, width, H5S.UNLIMITED };
hid_t dataSpace = HDFErrChk(H5S.create(H5S.class_t.SIMPLE));//1S
HDFErrChk(H5S.set_extent_simple(dataSpace, rank, current_dims, max_Dims));
hid_t typeId = HDFErrChk(H5T.copy(H5T.NATIVE_USHORT));//2T
//Next line returns an error value of -1
hid_t datasetId = HDFErrChk(H5D.create(gpID, name, typeId, dataSpace, 0L, 0L, 0L));//3D
GCHandle pinnedArray = GCHandle.Alloc(im, GCHandleType.Pinned);
HDFErrChk(H5D.write(datasetId, typeId, H5S.ALL, H5S.ALL, H5P.DEFAULT, pinnedArray.AddrOfPinnedObject()));
pinnedArray.Free();
HDFErrChk(H5S.close(dataSpace));//1S
HDFErrChk(H5T.close(typeId));//2T
HDFErrChk(H5D.close(datasetId));//3D
}
public static long HDFErrChk(long err)
{
if (err < 0)
{
throw new HDF5Exception("Negative return value from HDF");
}
return err;
}
如果您没有绑定到特定的库,您可能想尝试HDFql,一种高级(声明性)编程语言,它可以帮助您摆脱 HDF5 低级细节的困扰。为了说明这一点,您的用例可以使用 C# 中的 HDFql 解决如下(假设
width
为 100):
// declare variables
ushort[,] data = new ushort[100, 100];
int number;
// create file 'test.h5' and use (i.e. open) it
HDFql.Execute("CREATE AND USE FILE test.h5");
// create dataset 'dset' of type unsigned short with three dimensions (last dimension is extendable)
HDFql.Execute("CREATE DATASET dset AS UNSIGNED SMALLINT(100, 100, 1 TO UNLIMITED)");
// register variable 'data' for subsequent use (by HDFql)
number = HDFql.VariableRegister(data);
// fill-up variable 'data' with some values
(...)
// write values stored in 'data' into dataset 'dset' in the last position of the third dimension (using an hyperslab)
HDFql.Execute("INSERT INTO dset[::-1] VALUES FROM MEMORY " + number);
// alter (i.e. change) last (third) dimension of dataset 'dset' with one more row
HDFql.Execute("ALTER DIMENSION dset TO ,,+1");
// fill-up variable 'data' with some new values
(...)
// write values stored in 'data' into dataset 'dset' in the last position of the third dimension (using an hyperslab)
HDFql.Execute("INSERT INTO dset[::-1] VALUES FROM MEMORY " + number);
// unregister variable 'data' as it is no longer used (by HDFql)
HDFql.VariableUnregister(data);
// close file in use (i.e. test.h5)
HDFql.Execute("CLOSE FILE");