From octave-sources-request at bevo dot che dot wisc dot edu Sat Nov 27 02:02:59 1999 Subject: Patch: HDF5 support in load/save From: stevenj at gil-galad dot mit dot edu To: octave-sources at bevo dot che dot wisc dot edu Date: Sat, 27 Nov 1999 03:03:15 -0500 (EST) This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. Send mail to mime at docserver dot cac dot washington dot edu for more info. --6689530-145257942-943689795=:846 Content-Type: TEXT/PLAIN; charset=US-ASCII Dear Octave Maintainers and Users, I have modified the Octave CVS sources to support the HDF5 format (a standard, free, portable binary format for scientific applications developed by NCSA) natively in its "load" and "save" commands. (See my previous post regarding HDF5 and Octave at http://www.che.wisc.edu/octave/mailing-lists/help-octave/1999/1576 ... see also my post of a utility to import HDF5 slices at http://www.che.wisc.edu/octave/mailing-lists/octave-sources/1999/93) Usage is simple: just use "save -hdf5" or "save -h", with the other arguments as usual. To load, just use the load command; it should automatically detect HDF5 files, although you can force it with -hdf5. I have tried to make the HDF5 load/save as full-featured as possible, so that it could potentially be used as a complete replacement for Octave's binary format. (Standard file formats are good!) Specifically, it supports: * all of the data types supported by Octave's binary format (string, string vector, real/complex arrays/matrices/scalars, and ranges). * all of the extra annotations added in Octave's binary format (documentation strings, and whether a variable is global) * saving in single precision (with save -hdf5-float). The one thing it doesn't support yet is using integer datatypes instead of floating-point when the data is integral. I have actually written the code to do this, but have #if'ed it out because HDF5 currently does not support automatic conversions between floating-point and integral types (although they mention this as a possibility for future versions in the HDF5 manual). In any case, this is not so much a question of functionality from a user perspective as it is of file-size optimization. (On the other hand, HDF5 does support automatic compression with zlib, I believe.) Each variable is stored in the HDF5 file as its own dataset, with the variable name as the dataset name. This should make it easy to browse and/or read the data with other tools that support HDF5 (or HDF, since hdf5->hdf conversion tools come with hdf5). Doc strings are stored as comments attached to the datasets. It should also be possible to use the load command to import HDF5 files not created with Octave, with the limitation that it can't read data not supported by Octave, in particular: datasets with dimensionality > 2; datasets with weird datatypes (e.g. hdf5 supports arbitrary compound data types), and datasets with names that aren't valid Octave identifiers. These datasets are simply skipped (a warning is printed), while other datasets from the file are still read in. You will need to have the HDF5 libraries installed; they are available from http://hdf.ncsa.uiuc.edu. I have modified Octave's configure.in to automatically detect when the HDF5 libraries are available and turn on HDF5 support (although it can be disabled via configure --without-hdf5). All of the code I added is surrounded by #ifdef HAVE_HDF5 directives. The diffs (produced with cvs diff -u) against the latest CVS tree are attached below. Please bang on it and let me know what you think. Cordially, Steven G. Johnson PS. HDF5 also comes with utilities h5ls and h5dump that you can use to examine HDF5 files (which end with .h5 typically). Beware, however, that h5dump has a bug that causes it to go into an infinite loop whenever it encounters scalar values (arrays and strings are fine). PPS. I hope that MIME/binary attachments are okay. The uncompressed diffs are 30kB, which seemed a little long for an email. --6689530-145257942-943689795=:846 Content-Type: APPLICATION/octet-stream; name="diff.out.gz" Content-Transfer-Encoding: BASE64 Content-ID: Content-Description: Content-Disposition: attachment; filename="diff.out.gz" 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 I8R0CqOkzJht0f4Fzy0zfId1AAA= --6689530-145257942-943689795=:846--