2013-08-05 1 views
2

C++에서 읽어야하는 HDF5 파일이 있는데 파일 형식이 약간 복잡해 보이는 데 문제가 있습니다 ...C++에서 HDF5 데이터 읽기 :이 특정 형식을 읽는 방법?

HDF5 파일에는 두 장치에서 저장 한 데이터가 포함되어 있습니다. 데이터는 시계열입니다. 두 개의 어레이, 즉 하나는 시간에, 두 번째는 실제 출력을위한 것으로 볼 수 있습니다. 획득 수는 사용자가 정의하지만 두 장치의 획득 횟수는 동일합니다 (데이터를 동시에 수집하므로). 시간 어레이 및 데이터 배열을 포함

/Device1/Acquisition_000 
/Device1/Acquisition_001 
[...] 
/Device2/Acquisition_000 
/Device2/Acquisition_001 
[...] 

각 인수 :

예를 들어, 하나 개의 파일은 유사한 구성, 10 개 인수에서 데이터를 포함의 말을하게됩니다. 는 "경로"/ 디바이스 2/Acquisition_000이 데이터 집합을이고 같은 그것을 읽으려고 I 불구하고 File opened in HDFView

,하지만 난 데 문제 :

여기 HDFView 파일에 보는 것을의 스크린 샷입니다. h5dump를 사용하여 .h5 파일을 버리고 다음을 얻었습니다.

HDF5 "data.h5" { 
GROUP "/" { 
GROUP "Device1" { 
    DATASET "Acquisition_000" { 
     DATATYPE H5T_COMPOUND { 
      H5T_IEEE_F64BE "Time"; 
      H5T_IEEE_F64BE "Signal"; 
     } 
     DATASPACE SIMPLE { (270000)/(270000) } 
     DATA { 
     (0): { 
      0, 
      -0.0933597 
      }, 
     (1): { 
      2e-05, 
      -0.0476648 
      }, 
     (2): { 
      4e-05, 
      -0.0628964 
      }, 
[...] 

이제는 어떻게 구조를 읽어야할지 모르겠군요. H5T_COMPOUND를 보았으므로 http://www.hdfgroup.org/HDF5/doc/cpplus_RM/compound_8cpp-example.html에서 복합 예제를 시도했지만 데이터 세트 -> 읽기()가 데이터를 읽을 수없는 것 같습니다. valgrind는 루프에서 데이터를 std :: couting 할 때 초기화되지 않은 데이터에 액세스하는 것을보고합니다.

또 다른 혼란의 원인은 덤프의 "H5T_IEEE_F64BE"입니다. 빅 엔디안의 BE 파트가 아닌가? 데이터를 생성하는 머신과 읽는 머신이 모두 x86_64 ...

"시간"및 "신호"어레이를 C/C++ 어레이로 어떻게 읽습니까? 참고로

, 여기에 예를 적응에서 내 시도입니다 :

const H5std_string FILE_NAME("data.h5"); 
const H5std_string DATASET_NAME("/Device1/Acquisition_000/"); 
H5File file(FILE_NAME, H5F_ACC_RDONLY); 
DataSet dataset = file.openDataSet(DATASET_NAME); 
const H5std_string MEMBER_TIME("time_name"); 
const H5std_string MEMBER_SIGN("signal_name"); 
// Try reading a single array: 
CompType mtype3(sizeof(double)); 
mtype3.insertMember(MEMBER_SIGN, 0, PredType::NATIVE_DOUBLE); 
double *data_signal = new double[270000]; 
memset(data_signal, 0, 270000); 
dataset.read(data_signal, mtype3); 
// Print the data 
for (int i = 0 ; i < 10 ; i++) 
{ 
    std::cout << "data_signal[i=" << i << "] = " << data_signal[i] << std::endl; 
} 

및 출력 : 또한

data_signal[i=0] = 0 
data_signal[i=1] = 0 
data_signal[i=2] = 0 
data_signal[i=3] = 0 
data_signal[i=4] = 0 
data_signal[i=5] = 0 
data_signal[i=6] = 0 
data_signal[i=7] = 0 
data_signal[i=8] = 0 
data_signal[i=9] = 0 

, 매트랩 사용하여 파일을 읽을 수 있습니다

data = h5read('data.h5', '/Device1/Acquisition_000') 
data = 

     Time: [270000x1 double] 
    Signal: [270000x1 double] 

감사합니다 많이.

+0

정말 도움이 안되지만, HDF5 파일을 사용하는 것이 얼마나 실망 스러운지 기억하고 있으며, 행운을 빈다. – Cameron

답변

2

구성원 이름은 올바른 데이터 필드를 파일에서 가져 오는 데 사용됩니다. "signal_name"이 (가) 파일의 데이터 이름과 일치하지 않습니다. MATLAB과 GUI 뷰어에서 볼 수있는 "신호"를 사용해보십시오.

결국에는 화합물 예와 마찬가지로 시간/신호 쌍을 나타내는 C++ 구조체를 정의 할 것이다 :

struct dataPoint 
{ 
    double timePoint; 
    double signal; 
}; 

CompType hdf5DataPointType(sizeof(dataPoint)); 
hdf5DataPointType.insertMember(MEMBER_TIME, 0, PredType::NATIVE_DOUBLE); 
hdf5DataPointType.insertMember(MEMBER_SIGN, sizeof(double), PredType::NATIVE_DOUBLE); 

이어서 데이터 포인트의 어레이에 직접 읽기.

+0

와우 정말 간단했습니다 ... 내 하루를 많이 만들어 줘서 고마워.) 처음에는 구조 (예 : 온라인)를 사용했지만 작동하지 않는 것을 보았을 때 더 간단한 방법을 시도했습니다.한 번에 모든 데이터를 읽는 것이 더 빠를 것이라고 생각하십니까? –