2011-10-29 49 views
19

Sử dụng HDF5DotNet, bất kỳ ai có thể chỉ cho tôi mã ví dụ, sẽ mở tệp hdf5, trích xuất nội dung của tập dữ liệu và in nội dung thành đầu ra tiêu chuẩn?HDF5 Ví dụ mã

Cho đến nay tôi có như sau:

 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); 

Sau đó, nó được một chút bối rối.

Tôi thực sự muốn thực hiện một số xử lý về nội dung của tập dữ liệu nhưng tôi nghĩ rằng một khi tôi đã kết xuất thành đầu ra tiêu chuẩn, tôi có thể làm việc từ đó.

CẬP NHẬT: Tôi đã hack xung quanh vấn đề này đủ để giải quyết vấn đề của riêng tôi. Tôi không thể nhận ra một tập dữ liệu là một mảng đa mảng - tôi nghĩ nó giống như một bảng db. Trong trường hợp không có ai quan tâm,

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]); 
+8

tôi muốn chỉ ra rằng có 'H5', 'h5',' H5F', 'H5S' và' H5D' như tên biến là hình thức xấu. Hai trường hợp đầu tiên chỉ khác nhau theo từng trường hợp. Những người khác chỉ bằng một lá thư. – Amy

+7

Có. H5, H5F, H5S và H5D đều được API cung cấp - [HDF5DotNet - C++/CLI Wrapper của Thư viện HDF5] (http://hdf5.net/). Nếu bạn theo liên kết, bạn cũng có thể thưởng thức H5A, H5E, H5G, H5I, H5L, H5O, H5P và H5R. Tôi đang tìm kiếm một mẫu mã vì tôi không muốn dành nhiều thời gian nghiên cứu giao diện này. – Crosbie

+3

Tại sao bạn không thêm hack/giải pháp của mình làm câu trả lời và chấp nhận? – rene

Trả lời

12

Hãy thử điều này:

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(); 
    } 
} 
} 
+0

+1 cho hướng dẫn rất hữu ích và phức tạp này. –

+0

Tôi đã chỉnh sửa ví dụ vì nó không biên dịch: H5G.create -> bỏ qua đối số thứ ba, H5S.create_simple phải dài [] thay vì ulong [] làm đối số thứ hai, H5T.getSize trả về int thay vì uint – Sebastian

5

Vì vậy, bắt đầu của bạn thật tuyệt vời. Tôi đã tạo một số tiện ích mở rộng sẽ giúp bạn. Sử dụng điều này trong mã của bạn, bạn sẽ có thể điều đó có ý nghĩa hơn trong một ngôn ngữ hướng đối tượng, chẳng hạn như (trong trường hợp của bạn):

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"); 

Dưới đây là các phần mở rộng không đầy đủ, tôi sẽ xem xét thêm chúng vào 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; 
    } 
} 
+0

Đây là nhiều hữu ích hơn câu trả lời được chấp nhận. – kdbanman

2

đây là một mẫu làm việc:

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(); 

     } 
    } 
} 
Các vấn đề liên quan