2012-07-24 40 views
2
創建HDF5布爾枚舉

我創建了3個雙打和一個boolen使用numpy數組和書面他們使用h5py到文件:如何閱讀h5py用C

import numpy as np 
import h5py 

data = np.zeros(10, dtype=[("THETA",np.double),("PHI",np.double),("PSI",np. double),("FLAG",np.bool)]) 

with h5py.File("testout.h5") as f: 
    f.create_dataset("data", data=data) 

h5py爲創建一個枚舉類型布爾字段:

HDF5 "testout.h5" { 
GROUP "/" { 
    DATASET "data" { 
     DATATYPE H5T_COMPOUND { 
     H5T_IEEE_F64LE "THETA"; 
     H5T_IEEE_F64LE "PHI"; 
     H5T_IEEE_F64LE "PSI"; 
     H5T_ENUM { 
      H5T_STD_I8LE; 
      "FALSE"   0; 
      "TRUE"    1; 
     } "FLAG"; 
     } 
     DATASPACE SIMPLE { (10)/(10) } 
    } 
} 
} 

現在我需要閱讀用C這個文件,事情就變得複雜:

typedef enum { 
    false = 0; 
    true 
} bool; 

typedef struct { 
    double THETA, PHI, PSI; 
    bool FLAG; 
} pointing_t; 

我不知道如何定義一個擁有枚舉類型:

hid_t memtype = H5Tcreate (H5T_COMPOUND, sizeof(pointing_t)); 
H5Tinsert (memtype, "THETA", HOFFSET (pointing_t, THETA), H5T_NATIVE_DOUBLE); 
H5Tinsert (memtype, "PHI", HOFFSET (pointing_t, PHI), H5T_NATIVE_DOUBLE); 
H5Tinsert (memtype, "PSI", HOFFSET (pointing_t, PSI), H5T_NATIVE_DOUBLE); 
# this should be an ENUM!! 
H5Tinsert (memtype, "FLAG", HOFFSET (pointing_t, FLAG), H5T_NATIVE_DOUBLE); 

我粘貼要點一個完整的「不工作」的例子,試圖讀取與以往的Python代碼片段創建HDF5文件:

http://gist.github.com/3168909

有人有建議嗎? 謝謝!

回答

2

找到了解決辦法,你需要在HDF5創建一個枚舉類型:

#define CPTR(VAR,CONST) ((VAR)=(CONST),&(VAR)) 
hid_t boolenumtype = H5Tcreate(H5T_ENUM, sizeof(bool)); 
status = H5Tenum_insert(boolenumtype, "FALSE", CPTR(val, FALSE)); 
printf ("H5Tenum_insert (FALSE): %i\n", status); 
status = H5Tenum_insert(boolenumtype, "TRUE", CPTR(val, TRUE)); 
printf ("H5Tenum_insert (TRUE): %i\n", status); 

,然後將其添加到mem類型:

H5Tinsert (memtype, "FLAG", HOFFSET (pointing_t, FLAG), boolenumtype); 

在github的一例進行工作。

2

解決此問題的更簡單方法是使用1字節無符號字符來存儲布爾類型。在h5py,可以通過調用以下

import h5py 
import numpy as np 

# Generate some boolean data 

shape = (100, 100) 
data = np.zeros(shape, dtype=np.bool) 

# Save the boolean data as uchars 

f = h5py.File('foo.h5') 
dset = f.create_dataset('/bar', dtype='u1', shape=shape) 
dset[:] = data[:] 

在C/C++存儲布爾陣列,就可以讀取uchars成bool*陣列,並且它們將被正確地解釋。這是因爲它們是1字節,就像C/C++布爾值一樣,並且任何非零位的內容在C/C++中被解釋爲true