2017-04-19 1 views
1

J'essaye d'écrire un jeu de données 3D dans un fichier HDF5. L'écriture réussit et les dimensions sont toutes correctes dans le fichier, cependant, lorsque vous utilisez l'outil HDFView, les données sont faussées, mais ont une structure reconnaissable, donc je dois être proche. Je n'arrive pas à comprendre ce qui me manque et je ne trouve pas un bon exemple pour écrire des données 3D.Ecriture d'un tableau 3D en HDF5

Les données sont une partie de mémoire contiguë indexée en tant que telle: data[layer][row][col] ou data[layer*rows*cols + row*cols + col]

Voici le code que je utilise, où HDF5_CHECK est une macro qui jette une exception en cas d'erreur.

const hsize_t dim[] = { rows, cols, layers }; 
hid_t space = H5Screate_simple(3, dim, NULL); 

hid_t dataset = H5Dcreate(file, "dataset", type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); 
HDF5_CHECK(dataset); 
HDF5_CHECK(H5Dwrite(dataset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, data)); 

HDF5_CHECK(H5Sclose(space)); 
HDF5_CHECK(H5Dclose(dataset)); 

EDIT

Je crois que le problème est lié à l'indexation. Le tableau en C++ est correct. Cependant, je crois que je veux stocker les données Z, Y, X comme Y, X, Z dans le conteneur HDF5. Cela doit être possible en utilisant hyperslabs, mais je ne suis pas sûr comment

EDIT 2

Puisque les données a la structure, je peux voir les données d'une image dans HDFView. Les éléments suivants devraient aider à montrer la question:

EDIT 3

Contacté le groupe HDF et a trouvé décalage dimensions est pas possible dans la mise en œuvre actuelle. Cela doit être fait avant d'écrire l'ensemble de données.

Expected vs Actual results

+0

Comment est 'data' déclarée? Quel est le type primitif prévu pour chaque élément? –

+0

Le type est réellement modélisé.'data' est déclaré comme un vecteur, cependant, dans le contexte de cette méthode un' const T * ' – steveo225

+0

Comme les données sont modélisées, comment définissez-vous' type'? Pouvons-nous également voir un échantillon des données et sa forme "brouillée"? –

Répondre

0

Les éléments de l'ensemble de données ne sont pas dans l'ordre attendu parce qu'un espace de données de mémoire incorrecte a été spécifiée.

La section user guide de la section 4 montre comment HDF5 peut lire entre deux espaces de données de même taille, mais avec des dimensions permutées du fichier à la mémoire. Dans la pratique, la fonction H5Dwrite est déclarée comme ceci:

herr_t H5Dwrite(hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t xfer_plist_id, const void * buf) 

Le troisième paramètre fait référence à la mémoire DataSpace , qui dans notre cas n'est pas le même que celui du fichier (précédemment défini comme (row, col, layer)). Il devrait plutôt être défini comme (layer, row, col). La même page dans le guide précise que HDF5 suit la même convention de stockage matriciel que dans C:

Les dimensions de l'espace de données sont numérotées de 1 au rang. HDF5 utilise des conventions de stockage C, en supposant que la dernière dimension répertoriée est la dimension qui change le plus rapidement et que la première dimension répertoriée est la plus lente. La spécification de format de stockage de format de fichier HDF5 adhère à la convention C et la bibliothèque HDF5 adhère à la même convention lors du stockage des dimensions de l'espace de données dans le fichier.

Le code corrigé doit être quelque chose comme ceci:

const hsize_t dim[] = { rows, cols, layers }; 
hid_t space = H5Screate_simple(3, dim, NULL); 

hid_t dataset = H5Dcreate(file, "dataset", type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); 

HDF5_CHECK(dataset); 

const hsize_t mem_dim[] = { layers, rows, cols }; 
hid_t mem_space = H5Screate_simple(3, dim, NULL); 
HDF5_CHECK(H5Dwrite(dataset, type, mem_space, H5S_ALL, H5P_DEFAULT, data)); 
+0

Cela n'a pas fonctionné non plus. En fait, il a donné (apparemment) la même réponse. J'ai ajouté une image montrant ce qui se passe et ce qui est attendu. J'avais oublié que vous pouviez spécifier l'espace mémoire différemment et vraiment pensé que cela allait fonctionner. – steveo225

+0

J'ai essayé de changer l'espace mem_space pour tester ce qui se passerait. Cela ne semble pas important ce que j'utilise comme mem_space, la sortie est la même, même 'const hsize_t mem_dim [3] = {layers * rows * cols, 1, 1};' – steveo225

+0

Cela intrigue en effet. HDFView devrait vous permettre d'assigner chaque dimension d'image lors de l'ouverture d'un ensemble de données en tant qu'image. Avez-vous essayé toutes les combinaisons possibles à partir de là? Nous ne pouvons pas être si loin de résoudre cette "énigme". :) –