2013-08-05 5 views
2

У меня есть файл HDF5, который мне нужно прочитать на C++, но у меня проблемы, так как формат файла кажется немного сложным ...Чтение данных HDF5 из C++: как читать этот конкретный формат?

Файл HDF5 содержит данные, сохраненные с двух устройств. Данные представляют собой временные ряды; его можно рассматривать как два массива, один для времени и второй для фактического вывода с устройства. Количество приобретений определяется пользователем, но количество приобретений одинаково для обоих устройств (так как их данные приобретаются одновременно).

Например, один файл будет содержать данные, скажем, 10 приобретений, организованных в нечто похожее на:

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

Каждое приобретение будет содержать массив времени и массив данных.

Вот скриншот того, что видит HDFView в файле: File opened in HDFView

Я хоть «путь»/устройство2/Acquisition_000 был массив данных и пытался читать его как таковой, но у меня возникают проблемы. Затем я бросил файл .h5 с помощью h5dump и получил следующее:

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, но dataat-> read(), похоже, не умеет читать данные; valgrind сообщает о доступе к неинициализированным данным, когда std :: cout'ing данные в цикле.

Другим источником путаницы является «H5T_IEEE_F64BE» в свалке; не является частью BE для big-endian? Как машина, генерирующая данные, так и считывающая ее - 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 

Кроме того, Matlab можно прочитать файл с помощью:

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

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

Спасибо много.

+0

Я не могу помочь, но я помню, как было сложно работать с файлами HDF5 и просто хотел пожелать вам удачи :-) +1 для корректного вопроса. – Cameron

ответ

2

Имена членов используются для вытягивания правильных полей данных из файла. «signal_name» не соответствует имени данных в файле. Попробуйте использовать «Сигнал», как видно из MATLAB и из средства просмотра графического интерфейса.

В конце концов, вы хотите, чтобы определить 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); 

Затем считывается непосредственно в массив DataPoint.

+0

Ничего себе это было так просто ... Спасибо, что вы сделали мой день;) Я использовал структуру сначала (как в примере онлайн), но попробовал более простой способ, когда увидел, что он не работает.Думаю, это быстрее, если все данные будут прочитаны сразу? –

Смежные вопросы