; docformat = 'rst' ;+ ; Write a variable or attribute to an HDF 5 file with a simple notation. ; ; :Categories: ; file i/o, hdf5, sdf ; ; :Examples: ; For example, the following creates an HDF5 file:: ; ; IDL> filename = 'test.h5' ; IDL> mg_h5_putdata, filename, 'scalar', 1.0 ; IDL> mg_h5_putdata, fid, 'array', findgen(10) ; IDL> mg_h5_putdata, filename, 'group/another_scalar', 1.0 ; IDL> mg_h5_putdata, filename, 'group/another_array', findgen(10) ; IDL> mg_h5_putdata, filename, 'array.attribute', 'Attribute of an array' ; ; To browse the results:: ; ; IDL> ok = h5_browser(filename) ; ; :Author: ; Michael Galloy ; ; :Copyright: ; This library is released under a BSD-type license. ; ; Copyright (c) 2007-2010, Michael Galloy <mgalloy@idldev.com> ; ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are ; met: ; ; a. Redistributions of source code must retain the above copyright ; notice, this list of conditions and the following disclaimer. ; b. Redistributions in binary form must reproduce the above copyright ; notice, this list of conditions and the following disclaimer in ; the documentation and/or other materials provided with the ; distribution. ; c. Neither the name of Michael Galloy nor the names of its ; contributors may be used to endorse or promote products derived ; from this software without specific prior written permission. ; ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS ; IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR ; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;- ;+ ; Determines if an object with a given name exists at a given location. ; ; :Private: ; ; :Returns: ; 1 if exists, 0 if it doesn't ; ; :Params: ; loc : in, required, type=long ; file or group identifier ; name : in, required, type=string ; name of object to check ;- function mg_h5_putdata_varexists, loc, name compile_opt strictarr nobjs = h5g_get_num_objs(loc) for o = 0L, nobjs - 1L do begin if (name eq h5g_get_obj_name_by_idx(loc, o)) then return, 1 endfor return, 0 end ; + ; Write a variable to a file. ; ; :Private: ; ; :Params: ; fildename : in, required, type=long ; HDF5 filename to write variable into ; name : in, required, type=string ; name of variable in HDF5 file ; data : in, optional, type=any ; IDL variable to write ;- pro mg_h5_putdata_putvariable, filename, name, data compile_opt strictarr if (file_test(filename)) then begin fileId = h5f_open(filename, /write) endif else begin fileId = h5f_create(filename) endelse tokens = strsplit(name, '/', /extract, /preserve_null, count=ntokens) loc = fileId ; loop over tokens except last one groups = lonarr(ntokens) ; one too big, but makes sure not zero-length for t = 0L, ntokens - 2L do begin if (mg_h5_putdata_varexists(loc, tokens[t])) then begin loc = h5g_open(loc, tokens[t]) endif else begin loc = h5g_create(loc, tokens[t]) endelse groups[t] = loc endfor if (tokens[ntokens - 1L] ne '') then begin ; get the HDF5 type from the IDL variable datatypeId = h5t_idl_create(data) ; scalars and arrays are created differently if (size(data, /n_dimensions) eq 0L) then begin dataspaceId = h5s_create_scalar() endif else begin dataspaceId = h5s_create_simple(size(data, /dimensions)) endelse if (~mg_h5_putdata_varexists(loc, tokens[ntokens - 1L])) then begin datasetId = h5d_create(loc, tokens[ntokens - 1L], datatypeId, dataspaceId) endif else begin datasetId = h5d_open(loc, tokens[ntokens - 1L]) endelse h5d_write, datasetId, data h5d_close, datasetId h5s_close, dataspaceId h5t_close, datatypeId endif for t = ntokens - 2L, 0L, -1L do h5g_close, groups[t] h5f_close, fileId end ;+ ; Write an attribute to a specific group, dataset, or type in a file. ; ; :Private: ; ; :Params: ; id : in, required, type=long ; identifier of group, dataset, or type to attach the attribute to ; attname : in, required, type=string ; name of attribute to write ; attvalue : in, required, type=any ; value of attribute to write ;- pro mg_h5_putdata_putattributedata, id, attname, attvalue compile_opt strictarr datatypeId = h5t_idl_create(attvalue) ; scalars and arrays are created differently if (size(data, /n_dimensions) eq 0L) then begin dataspaceId = h5s_create_scalar() endif else begin dataspaceId = h5s_create_simple(size(attvalue, /dimensions)) endelse attributeId = h5a_create(id, attname, datatypeId, dataspaceId) h5a_write, attributeId, attvalue h5a_close, attributeId end ;+ ; Write an attribute to a file. ; ; :Private: ; ; :Params: ; filename : in, required, type=long ; HDF5 filename to write variable into ; loc : in, required, type=string ; name of variable in HDF5 file ; attname : in, required, type=string ; name of attribute to write ; attvalue : in, optional, type=any ; IDL variable to write ;- pro mg_h5_putdata_putattribute, filename, loc, attname, attvalue compile_opt strictarr on_error, 2 if (file_test(filename)) then begin fileId = h5f_open(filename, /write) endif else begin fileId = h5f_create(filename) endelse objInfo = h5g_get_objinfo(fileId, loc) case objInfo.type of 'LINK': message, 'Cannot handle an attribute of a reference' 'GROUP': begin group = h5g_open(fileId, loc) mg_h5_putdata_putattributedata, group, attname, attvalue h5g_close, group end 'DATASET': begin dataset = h5d_open(fileId, loc) mg_h5_putdata_putattributedata, dataset, attname, attvalue h5d_close, dataset end 'TYPE': begin type = h5t_open(fileId, loc) mg_h5_putdata_putattributedata, type, attname, attvalue h5t_close, type end 'UNKNOWN': message, 'Unknown item' endcase h5f_close, fileId end ;+ ; Write data to a file. ; ; :Params: ; filename : in, required, type=long ; HDF5 filename to write variable into ; name : in, required, type=string ; name of variable in HDF5 file ; data : in, optional, type=any ; IDL variable to write ;- pro mg_h5_putdata, filename, name, data compile_opt strictarr on_error, 2 dotPos = strpos(name, '.', /reverse_search) if (dotPos eq -1L) then begin ; write variable mg_h5_putdata_putvariable, filename, name, data endif else begin ; write attribute path = strmid(name, 0, dotPos) attname = strmid(name, dotPos + 1L) mg_h5_putdata_putattribute, filename, path, attname, data endelse end ; main-level example program filename = 'test.h5' mg_h5_putdata, filename, 'scalar', 1.0 mg_h5_putdata, filename, 'array', findgen(10) mg_h5_putdata, filename, 'group/another_scalar', 1.0 mg_h5_putdata, filename, 'group/another_array', findgen(10) mg_h5_putdata, filename, 'array.attribute', 'Attribute of an array' mg_h5_dump, 'test.h5' end