如何在 HDF5 C# 上创建复合数据集

Posted

技术标签:

【中文标题】如何在 HDF5 C# 上创建复合数据集【英文标题】:How to Create Compound Dataset on HDF5 C# 【发布时间】:2018-11-20 22:25:31 【问题描述】:

我需要将一些数据写入 HDF5 文件,我在“BV”类中有一个“OPC_UA”类的对象列表,我想创建一个具有 BV 名称的数据集,并在数据集 i想要拥有“OPC_UA”对象的列表,OPC_UA 类有 3 个属性,一个 Long int,一个浮点值和一个我将转换为时间戳的 Datetime,我似乎无法让它工作,Marshal。 SizeOf() 不适用于类,但我不能将其作为结构来使用...这是我的代码:

 public void CriaHDF5Customizado(PackingConfigFile pf)
    
        H5FileId fileId = H5F.create("pmdfq.h5", H5F.CreateMode.ACC_TRUNC);

        H5GroupId infoGroupId = H5G.create(fileId, "informations");
        H5G.close(infoGroupId);
        H5GroupId datasetGroupId = H5G.create(fileId, "datasets");

        long[] dims = new long[1];


        foreach(BasicVariable bv in pf.basicVariableList.bvList)
        
            OPC_UA aux = new OPC_UA();
            var xx = bv.bvData;
            int tamanho = Marshal.SizeOf(typeof(OPC_UA));
            dims[0] = (long)bv.bvData.Count;
            // dims[1] = (long)4;
            H5DataSpaceId spaceId = H5S.create(H5S.H5SClass.SCALAR);
            H5DataTypeId dataTypeId = H5T.create(H5T.CreateClass.COMPOUND, Marshal.SizeOf(typeof(OPC_UA)));

            H5T.insert(dataTypeId, "TimeStamp", 0, new H5DataTypeId(H5T.H5Type.NATIVE_UINT));
            H5T.insert(dataTypeId, "Quality", Marshal.SizeOf(H5T.H5Type.NATIVE_UINT), new H5DataTypeId(H5T.H5Type.NATIVE_UINT));
            H5T.insert(dataTypeId, "Value", 2* Marshal.SizeOf(H5T.H5Type.NATIVE_UINT), new H5DataTypeId(H5T.H5Type.NATIVE_INT));

            H5DataSetId dataSetId = H5D.create(datasetGroupId, bv.bvTag, dataTypeId, spaceId);


            //H5D.write(dataSetId, new H5DataTypeId(H5T.H5Type.STD_REF_OBJ), new H5Array<OPC_UA>(bv.bvData.ToArray()));
            H5D.writeScalar(dataSetId, dataTypeId, ref xx);
            H5D.close(dataSetId);
        
        H5G.close(datasetGroupId);


        H5F.close(fileId);
    

这就是 OPC UA 类

   public class OPC_UA

    public DateTime timeStamp  get; set;  
    public string data  get; set; 
    public Int64 quality  get; set; 

    public OPC_UA(DateTime? ts = null ,string dt = "",Int64 qlt = -99)
    
        if (!ts.HasValue)
        
            timeStamp = DateTime.Now;
        
        data = dt;
        quality = qlt;
    

【问题讨论】:

【参考方案1】:
public DateTime timeStamp  get; set;   

DateTime 不是原子数据类型。将其转换为 long/Int64 刻度。那你也许能写出来。

public DateTime timeStamp 
    
        get  return new DateTime(StartTimeTicks); 
        set
        
            StartTimeTicks = value.Ticks;
        
    
public long StartTimeTicks;

构造函数也可能在阻碍它。

解决方法是制作一个结构。注意:根据您将在反射中使用的 (GetFields) 字段或 (GetProperties) 属性来构建字段或属性的结构。

 public structure OPC_UA
 

    public string data;
    public Int64 quality ;
    public DateTime timeStamp 
    
        get  return new DateTime(StartTimeTicks); 
        set
        
            StartTimeTicks = value.Ticks;
        
    
    public long StartTimeTicks;
 

Hdf5DotnetTools 是Hdf.PInvoke 上的一个工作 C# 包装器。您可以使用 C# 结构列表编写复合数据集。

如果您在使用 Hdf.PInvoke 或 Hdf5DotnetTools 的功能有任何困难,您可以使用它的 UnitTest 项目。

【讨论】:

以上是关于如何在 HDF5 C# 上创建复合数据集的主要内容,如果未能解决你的问题,请参考以下文章

通过 h5py (HDF5) 写入具有可变长度字符串的复合数据集

HDF5 C# pinvoke 读取数据集名称列表

连接大量 HDF5 文件

将多个数据集读/写到单个 HDF5 文件

C++ 代码创建空 HDF5 文件而不是数据集

大 HDF5 数据集,如何在每个 epoch 后有效地洗牌