HDF5DotNet を使用して、hdf5ファイルを開き、データセットのコンテンツを抽出し、そのコンテンツを標準出力に出力するサンプルコードを誰かに教えてもらえますか?
これまでのところ、私は次のものを持っています:
H5.Open();
var h5 = H5F.open("example.h5", H5F.OpenMode.ACC_RDONLY);
var dataset = H5D.open(h5, "/Timings/aaPCBTimes");
var space = H5D.getSpace(dataset);
var size = H5S.getSimpleExtentDims(space);
それからそれは少し混乱します。
実際にデータセットの内容を処理したいのですが、標準出力にダンプしたら、そこから処理できると思います。
更新:私は自分の問題を解決するのに十分なほどこれをハックしました。データセットがマルチ配列であることに気づきませんでした-データベーステーブルのようなものだと思いました。万が一、誰かが興味を持った場合、
double[,] dataArray = new double[size[0], 6];
var wrapArray = new H5Array<double>(dataArray);
var dataType = H5D.getType(d);
H5D.read(dataset, dataType, wrapArray);
Console.WriteLine(dataArray[0, 0]);
これを試して:
using System;
using HDF5DotNet;
namespace CSharpExample1
{
class Program
{
// Function used with
static int myFunction(H5GroupId id, string objectName, Object param)
{
Console.WriteLine("The object name is {0}", objectName);
Console.WriteLine("The object parameter is {0}", param);
return 0;
}
static void Main(string[] args)
{
try
{
// We will write and read an int array of this length.
const int DATA_ARRAY_LENGTH = 12;
// Rank is the number of dimensions of the data array.
const int RANK = 1;
// Create an HDF5 file.
// The enumeration type H5F.CreateMode provides only the legal
// creation modes. Missing H5Fcreate parameters are provided
// with default values.
H5FileId fileId = H5F.create("myCSharp.h5",
H5F.CreateMode.ACC_TRUNC);
// Create a HDF5 group.
H5GroupId groupId = H5G.create(fileId, "/cSharpGroup", 0);
H5GroupId subGroup = H5G.create(groupId, "mySubGroup", 0);
// Demonstrate getObjectInfo
ObjectInfo info = H5G.getObjectInfo(fileId, "/cSharpGroup", true);
Console.WriteLine("cSharpGroup header size is {0}", info.headerSize);
Console.WriteLine("cSharpGroup nlinks is {0}", info.nHardLinks);
Console.WriteLine("cSharpGroup fileno is {0} {1}",
info.fileNumber[0], info.fileNumber[1]);
Console.WriteLine("cSharpGroup objno is {0} {1}",
info.objectNumber[0], info.objectNumber[1]);
Console.WriteLine("cSharpGroup type is {0}", info.objectType);
H5G.close(subGroup);
// Prepare to create a data space for writing a 1-dimensional
// signed integer array.
ulong[] dims = new ulong[RANK];
dims[0] = DATA_ARRAY_LENGTH;
// Put descending ramp data in an array so that we can
// write it to the file.
int[] dset_data = new int[DATA_ARRAY_LENGTH];
for (int i = 0; i < DATA_ARRAY_LENGTH; i++)
dset_data[i] = DATA_ARRAY_LENGTH - i;
// Create a data space to accommodate our 1-dimensional array.
// The resulting H5DataSpaceId will be used to create the
// data set.
H5DataSpaceId spaceId = H5S.create_simple(RANK, dims);
// Create a copy of a standard data type. We will use the
// resulting H5DataTypeId to create the data set. We could
// have used the HST.H5Type data directly in the call to
// H5D.create, but this demonstrates the use of H5T.copy
// and the use of a H5DataTypeId in H5D.create.
H5DataTypeId typeId = H5T.copy(H5T.H5Type.NATIVE_INT);
// Find the size of the type
uint typeSize = H5T.getSize(typeId);
Console.WriteLine("typeSize is {0}", typeSize);
// Set the order to big endian
H5T.setOrder(typeId, H5T.Order.BE);
// Set the order to little endian
H5T.setOrder(typeId, H5T.Order.LE);
// Create the data set.
H5DataSetId dataSetId = H5D.create(fileId, "/csharpExample",
typeId, spaceId);
// Write the integer data to the data set.
H5D.write(dataSetId, new H5DataTypeId(H5T.H5Type.NATIVE_INT),
new H5Array<int>(dset_data));
// If we were writing a single value it might look like this.
// int singleValue = 100;
// H5D.writeScalar(dataSetId, new H5DataTypeId(H5T.H5Type.NATIVE_INT),
// ref singleValue);
// Create an integer array to receive the read data.
int[] readDataBack = new int[DATA_ARRAY_LENGTH];
// Read the integer data back from the data set
H5D.read(dataSetId, new H5DataTypeId(H5T.H5Type.NATIVE_INT),
new H5Array<int>(readDataBack));
// Echo the data
for(int i=0;i<DATA_ARRAY_LENGTH;i++)
{
Console.WriteLine(readDataBack[i]);
}
// Close all the open resources.
H5D.close(dataSetId);
// Reopen and close the data sets to show that we can.
dataSetId = H5D.open(fileId, "/csharpExample");
H5D.close(dataSetId);
dataSetId = H5D.open(groupId, "/csharpExample");
H5D.close(dataSetId);
H5S.close(spaceId);
H5T.close(typeId);
H5G.close(groupId);
//int x = 10;
//H5T.enumInsert<int>(typeId, "myString", ref x);
//H5G.close(groupId);
H5GIterateDelegate myDelegate;
myDelegate = myFunction;
int x = 9;
int index = H5G.iterate(fileId, "/cSharpGroup",
myDelegate, x, 0);
// Reopen the group id to show that we can.
groupId = H5G.open(fileId, "/cSharpGroup");
H5G.close(groupId);
H5F.close(fileId);
// Reopen and reclose the file.
H5FileId openId = H5F.open("myCSharp.h5",
H5F.OpenMode.ACC_RDONLY);
H5F.close(openId);
}
// This catches all the HDF exception classes. Because each call
// generates unique exception, different exception can be handled
// separately. For example, to catch open errors we could have used
// catch (H5FopenException openException).
catch (HDFException e)
{
Console.WriteLine(e.Message);
}
Console.WriteLine("Processing complete!");
Console.ReadLine();
}
}
}
だから、あなたのスタートは素晴らしかった。私はあなたを助けるはずのいくつかの拡張機能を作成しました。これをコードで使用すると、(あなたの場合)次のようなオブジェクト指向言語でより意味のあることができるはずです。
H5.Open();
var h5FileId= H5F.open("example.h5");
double[,] dataArray = h5FileId.Read2DArray<double>("/Timings/aaPCBTimes");
// or more generically...
T[,] dataArray = h5FileId.Read2DArray<T>("/Timings/aaPCBTimes");
これが不完全な拡張機能です。HDF5Netに追加することを検討します...
public static class HdfExtensions
{
// thank you http://stackoverflow.com/questions/4133377/splitting-a-string-number-every-nth-character-number
public static IEnumerable<String> SplitInParts(this String s, Int32 partLength)
{
if (s == null)
throw new ArgumentNullException("s");
if (partLength <= 0)
throw new ArgumentException("Part length has to be positive.", "partLength");
for (var i = 0; i < s.Length; i += partLength)
yield return s.Substring(i, Math.Min(partLength, s.Length - i));
}
public static T[] Read1DArray<T>(this H5FileId fileId, string dataSetName)
{
var dataset = H5D.open(fileId, dataSetName);
var space = H5D.getSpace(dataset);
var dims = H5S.getSimpleExtentDims(space);
var dataType = H5D.getType(dataset);
if (typeof(T) == typeof(string))
{
int stringLength = H5T.getSize(dataType);
byte[] buffer = new byte[dims[0] * stringLength];
H5D.read(dataset, dataType, new H5Array<byte>(buffer));
string stuff = System.Text.ASCIIEncoding.ASCII.GetString(buffer);
return stuff.SplitInParts(stringLength).Select(ss => (T)(object)ss).ToArray();
}
T[] dataArray = new T[dims[0]];
var wrapArray = new H5Array<T>(dataArray);
H5D.read(dataset, dataType, wrapArray);
return dataArray;
}
public static T[,] Read2DArray<T>(this H5FileId fileId, string dataSetName)
{
var dataset = H5D.open(fileId, dataSetName);
var space = H5D.getSpace(dataset);
var dims = H5S.getSimpleExtentDims(space);
var dataType = H5D.getType(dataset);
if (typeof(T) == typeof(string))
{
// this will also need a string hack...
}
T[,] dataArray = new T[dims[0], dims[1]];
var wrapArray = new H5Array<T>(dataArray);
H5D.read(dataset, dataType, wrapArray);
return dataArray;
}
}
これが実用的なサンプルです:
using System.Collections.Generic;
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HDF5DotNet;
namespace HDF5Test
{
public class HDFTester
{
static int myFunction(H5GroupId id, string objectName, Object param)
{
Console.WriteLine("The object name is {0}", objectName);
Console.WriteLine("The object parameter is {0}", param);
return 0;
}
public static void runTest()
{
try
{
// We will write and read an int array of this length.
const int DATA_ARRAY_LENGTH = 12;
// Rank is the number of dimensions of the data array.
const int RANK = 1;
// Create an HDF5 file.
// The enumeration type H5F.CreateMode provides only the legal
// creation modes. Missing H5Fcreate parameters are provided
// with default values.
H5FileId fileId = H5F.create("myCSharp.h5",
H5F.CreateMode.ACC_TRUNC);
// Create a HDF5 group.
H5GroupId groupId = H5G.create(fileId, "/cSharpGroup");
H5GroupId subGroup = H5G.create(groupId, "mySubGroup");
// Demonstrate getObjectInfo
ObjectInfo info = H5G.getObjectInfo(fileId, "/cSharpGroup", true);
Console.WriteLine("cSharpGroup header size is {0}", info.headerSize);
Console.WriteLine("cSharpGroup nlinks is {0}", info.nHardLinks);
Console.WriteLine("cSharpGroup fileno is {0} {1}",
info.fileNumber[0], info.fileNumber[1]);
Console.WriteLine("cSharpGroup objno is {0} {1}",
info.objectNumber[0], info.objectNumber[1]);
Console.WriteLine("cSharpGroup type is {0}", info.objectType);
H5G.close(subGroup);
// Prepare to create a data space for writing a 1-dimensional
// signed integer array.
long[] dims = new long[RANK];
dims[0] = DATA_ARRAY_LENGTH;
// Put descending ramp data in an array so that we can
// write it to the file.
int[] dset_data = new int[DATA_ARRAY_LENGTH];
for (int i = 0; i < DATA_ARRAY_LENGTH; i++)
dset_data[i] = DATA_ARRAY_LENGTH - i;
// Create a data space to accommodate our 1-dimensional array.
// The resulting H5DataSpaceId will be used to create the
// data set.
H5DataSpaceId spaceId = H5S.create_simple(RANK, dims);
// Create a copy of a standard data type. We will use the
// resulting H5DataTypeId to create the data set. We could
// have used the HST.H5Type data directly in the call to
// H5D.create, but this demonstrates the use of H5T.copy
// and the use of a H5DataTypeId in H5D.create.
H5DataTypeId typeId = H5T.copy(H5T.H5Type.NATIVE_INT);
// Find the size of the type
int typeSize = H5T.getSize(typeId);
Console.WriteLine("typeSize is {0}", typeSize);
// Set the order to big endian
H5T.setOrder(typeId, H5T.Order.BE);
// Set the order to little endian
H5T.setOrder(typeId, H5T.Order.LE);
// Create the data set.
H5DataSetId dataSetId = H5D.create(fileId, "/csharpExample",
typeId, spaceId);
// Write the integer data to the data set.
H5D.write(dataSetId, new H5DataTypeId(H5T.H5Type.NATIVE_INT),
new H5Array<int>(dset_data));
// If we were writing a single value it might look like this.
// int singleValue = 100;
// H5D.writeScalar(dataSetId, new H5DataTypeId(H5T.H5Type.NATIVE_INT),
// ref singleValue);
// Create an integer array to receive the read data.
int[] readDataBack = new int[DATA_ARRAY_LENGTH];
// Read the integer data back from the data set
H5D.read(dataSetId, new H5DataTypeId(H5T.H5Type.NATIVE_INT),
new H5Array<int>(readDataBack));
// Echo the data
for (int i = 0; i < DATA_ARRAY_LENGTH; i++)
{
Console.WriteLine(readDataBack[i]);
}
// Close all the open resources.
H5D.close(dataSetId);
// Reopen and close the data sets to show that we can.
dataSetId = H5D.open(fileId, "/csharpExample");
H5D.close(dataSetId);
dataSetId = H5D.open(groupId, "/csharpExample");
H5D.close(dataSetId);
H5S.close(spaceId);
H5T.close(typeId);
H5G.close(groupId);
//int x = 10;
//H5T.enumInsert<int>(typeId, "myString", ref x);
//H5G.close(groupId);
H5GIterateCallback myDelegate;
myDelegate = myFunction;
int x = 9;
int start = 0;
int index = H5G.iterate(fileId, "/cSharpGroup",myDelegate, x, ref start);
// Reopen the group id to show that we can.
groupId = H5G.open(fileId, "/cSharpGroup");
H5G.close(groupId);
H5F.close(fileId);
// Reopen and reclose the file.
H5FileId openId = H5F.open("myCSharp.h5",
H5F.OpenMode.ACC_RDONLY);
H5F.close(openId);
}
// This catches all the HDF exception classes. Because each call
// generates unique exception, different exception can be handled
// separately. For example, to catch open errors we could have used
// catch (H5FopenException openException).
catch (HDFException e)
{
Console.WriteLine(e.Message);
}
Console.WriteLine("Processing complete!");
Console.ReadLine();
}
}
}
私はこれが古いことを知っていますが、HDF5ファイルで作業する必要がある人のために、 github (他の人による元の作業に基づく)でほとんどの操作をカプセル化したC#ラッパーを持っています。
ユニットテストプロジェクトには多くの例があります。