/// <summary> /// Reads an n-dimensional dataset. /// </summary> /// <typeparam name="T">Generic parameter strings or primitive type</typeparam> /// <param name="groupId">id of the group. Can also be a file Id</param> /// <param name="name">name of the dataset</param> /// <returns>The n-dimensional dataset</returns> public static Array ReadDatasetToArray <T>(hid_t groupId, string name) //where T : struct { var datatype = GetDatatype(typeof(T)); var datasetId = H5D.open(groupId, name); var spaceId = H5D.get_space(datasetId); int rank = H5S.get_simple_extent_ndims(spaceId); long count = H5S.get_simple_extent_npoints(spaceId); Array dset; Type type = typeof(T); if (rank >= 0 && count >= 0) { int rankChunk; ulong[] maxDims = new ulong[rank]; ulong[] dims = new ulong[rank]; ulong[] chunkDims = new ulong[rank]; hid_t memId = H5S.get_simple_extent_dims(spaceId, dims, maxDims); long[] lengths = dims.Select(d => Convert.ToInt64(d)).ToArray(); dset = Array.CreateInstance(type, lengths); var typeId = H5D.get_type(datasetId); var mem_type = H5T.copy(datatype); if (datatype == H5T.C_S1) { H5T.set_size(datatype, new IntPtr(2)); } var propId = H5D.get_create_plist(datasetId); if (H5D.layout_t.CHUNKED == H5P.get_layout(propId)) { rankChunk = H5P.get_chunk(propId, rank, chunkDims); } memId = H5S.create_simple(rank, dims, maxDims); GCHandle hnd = GCHandle.Alloc(dset, GCHandleType.Pinned); H5D.read(datasetId, datatype, memId, spaceId, H5P.DEFAULT, hnd.AddrOfPinnedObject()); hnd.Free(); } else { dset = Array.CreateInstance(type, new long[1] { 0 }); } H5D.close(datasetId); H5S.close(spaceId); return(dset); }
public static T[,] ReadDataset <T>(int groupId, string name) where T : struct { var datatype = GetDatatype(typeof(T)); name = ToHdf5Name(name); var datasetId = H5D.open(groupId, name); var spaceId = H5D.get_space(datasetId); int rank = H5S.get_simple_extent_ndims(spaceId); long count = H5S.get_simple_extent_npoints(spaceId); int rankChunk; ulong[] maxDims = new ulong[rank]; ulong[] dims = new ulong[rank]; ulong[] chunkDims = new ulong[rank]; var memId = H5S.get_simple_extent_dims(spaceId, dims, maxDims); T[,] dset = new T[dims[0], dims[1]]; var typeId = H5D.get_type(datasetId); var mem_type = H5T.copy(datatype); if (datatype == H5T.C_S1) { H5T.set_size(datatype, new IntPtr(2)); } var propId = H5D.get_create_plist(datasetId); if (H5D.layout_t.CHUNKED == H5P.get_layout(propId)) { rankChunk = H5P.get_chunk(propId, rank, chunkDims); } memId = H5S.create_simple(rank, dims, maxDims); GCHandle hnd = GCHandle.Alloc(dset, GCHandleType.Pinned); H5D.read(datasetId, datatype, memId, spaceId, H5P.DEFAULT, hnd.AddrOfPinnedObject()); hnd.Free(); H5D.close(typeId); H5D.close(datasetId); H5S.close(spaceId); return(dset); }
/// <summary> /// Appends a dataset to a hdf5 file. If called the first time a dataset is created /// </summary> /// <typeparam name="T">Generic parameter only primitive types are allowed</typeparam> /// <param name="groupId">id of the group. Can also be a file Id</param> /// <param name="name">name of the dataset</param> /// <param name="dset">The dataset</param> /// <returns>status of the write method</returns> public static hid_t AppendDataset <T>(hid_t groupId, string name, Array dset, ulong chunkX = 200) where T : struct { var rank = dset.Rank; ulong[] dimsExtend = Enumerable.Range(0, rank).Select(i => { return((ulong)dset.GetLength(i)); }).ToArray(); ulong[] maxDimsExtend = null; ulong[] dimsChunk = new ulong[] { chunkX }.Concat(dimsExtend.Skip(1)).ToArray(); ulong[] zeros = Enumerable.Range(0, rank).Select(z => (ulong)0).ToArray(); hid_t status, spaceId, datasetId; // name = ToHdf5Name(name); var datatype = GetDatatype(typeof(T)); var typeId = H5T.copy(datatype); var datasetExists = H5L.exists(groupId, name) > 0; /* Create a new dataset within the file using chunk * creation properties. */ if (!datasetExists) { spaceId = H5S.create_simple(dset.Rank, dimsExtend, maxDimsExtend); var propId = H5P.create(H5P.DATASET_CREATE); status = H5P.set_chunk(propId, rank, dimsChunk); datasetId = H5D.create(groupId, name, datatype, spaceId, H5P.DEFAULT, propId, H5P.DEFAULT); /* Write data to dataset */ GCHandle hnd = GCHandle.Alloc(dset, GCHandleType.Pinned); status = H5D.write(datasetId, datatype, H5S.ALL, H5S.ALL, H5P.DEFAULT, hnd.AddrOfPinnedObject()); hnd.Free(); H5P.close(propId); } else { datasetId = H5D.open(groupId, name); spaceId = H5D.get_space(datasetId); var rank_old = H5S.get_simple_extent_ndims(spaceId); ulong[] maxDims = new ulong[rank_old]; ulong[] dims = new ulong[rank_old]; var memId1 = H5S.get_simple_extent_dims(spaceId, dims, maxDims); ulong[] oldChunk = null; int chunkDims = 0; var propId = H5P.create(H5P.DATASET_ACCESS); status = H5P.get_chunk(propId, chunkDims, oldChunk); /* Extend the dataset. */ var size = new ulong[] { dims[0] + dimsExtend[0] }.Concat(dims.Skip(1)).ToArray(); status = H5D.set_extent(datasetId, size); /* Select a hyperslab in extended portion of dataset */ var filespaceId = H5D.get_space(datasetId); var offset = new ulong[] { dims[0] }.Concat(zeros.Skip(1)).ToArray(); status = H5S.select_hyperslab(filespaceId, H5S.seloper_t.SET, offset, null, dimsExtend, null); /* Define memory space */ var memId2 = H5S.create_simple(rank, dimsExtend, null); /* Write the data to the extended portion of dataset */ GCHandle hnd = GCHandle.Alloc(dset, GCHandleType.Pinned); status = H5D.write(datasetId, datatype, memId2, spaceId, H5P.DEFAULT, hnd.AddrOfPinnedObject()); hnd.Free(); H5S.close(memId1); H5S.close(memId2); H5D.close(filespaceId); } H5D.close(datasetId); H5S.close(spaceId); return(status); }