Class: HDF5::Dataset

Inherits:
Object
  • Object
show all
Defined in:
lib/hdf5/dataset.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent_id, name) ⇒ Dataset

Returns a new instance of Dataset.



101
102
103
# File 'lib/hdf5/dataset.rb', line 101

def initialize(parent_id, name)
  initialize_from_id(HDF5::FFI.H5Dopen2(parent_id, name, HDF5::DEFAULT_PROPERTY_LIST), name)
end

Class Method Details

.create(parent_id, name, data) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/hdf5/dataset.rb', line 57

def create(parent_id, name, data)
  values = DataHelpers.normalize_data(data)
  dims = ::FFI::MemoryPointer.new(:ulong_long, 1)
  dims.write_array_of_ulong_long([values.length])
  datatype_id = DataHelpers.datatype_id_for(values)
  dataspace_id = HDF5::FFI.H5Screate_simple(1, dims, nil)
  raise HDF5::Error, "Failed to create dataspace for dataset: #{name}" if dataspace_id < 0

  dataset = from_id(
    HDF5::FFI.H5Dcreate2(parent_id, name, datatype_id, dataspace_id, HDF5::DEFAULT_PROPERTY_LIST,
                         HDF5::DEFAULT_PROPERTY_LIST, HDF5::DEFAULT_PROPERTY_LIST), name
  )
  dataset.write(values)
  return dataset unless block_given?

  begin
    yield dataset
  ensure
    dataset.close
  end
ensure
  HDF5::FFI.H5Sclose(dataspace_id) if dataspace_id && dataspace_id >= 0
end

.open(parent_id, name) ⇒ Object



81
82
83
84
85
86
87
88
89
90
# File 'lib/hdf5/dataset.rb', line 81

def open(parent_id, name)
  dataset = from_id(HDF5::FFI.H5Dopen2(parent_id, name, HDF5::DEFAULT_PROPERTY_LIST), name)
  return dataset unless block_given?

  begin
    yield dataset
  ensure
    dataset.close
  end
end

Instance Method Details

#attrsObject



105
106
107
# File 'lib/hdf5/dataset.rb', line 105

def attrs
  @attrs ||= AttributeManager.new(@dataset_id)
end

#closeObject



120
121
122
123
124
125
# File 'lib/hdf5/dataset.rb', line 120

def close
  return if @dataset_id.nil?

  HDF5::FFI.H5Dclose(@dataset_id)
  @dataset_id = nil
end

#dtypeObject



127
128
129
130
131
132
133
134
# File 'lib/hdf5/dataset.rb', line 127

def dtype
  datatype_id = HDF5::FFI.H5Dget_type(@dataset_id)
  raise HDF5::Error, 'Failed to get datatype' if datatype_id < 0

  HDF5::FFI.H5Tget_class(datatype_id)
ensure
  HDF5::FFI.H5Tclose(datatype_id) if datatype_id && datatype_id >= 0
end

#readObject



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/hdf5/dataset.rb', line 151

def read
  current_dtype = dtype
  current_shape = shape

  total_elements = current_shape.inject(:*)
  case current_dtype
  when :H5T_INTEGER
    read_integer_data(total_elements)
  when :H5T_FLOAT
    read_float_data(total_elements)
  when :H5T_STRING
    read_string_data(total_elements)
  else
    raise HDF5::Error, 'Unsupported datatype'
  end
end

#read_float_data(total_elements) ⇒ Object

Raises:



177
178
179
180
181
182
183
184
# File 'lib/hdf5/dataset.rb', line 177

def read_float_data(total_elements)
  buffer = ::FFI::MemoryPointer.new(:double, total_elements)
  status = HDF5::FFI.H5Dread(@dataset_id, HDF5::FFI.H5T_NATIVE_DOUBLE, HDF5::DEFAULT_PROPERTY_LIST,
                             HDF5::DEFAULT_PROPERTY_LIST, HDF5::DEFAULT_PROPERTY_LIST, buffer)
  raise HDF5::Error, 'Failed to read float dataset' if status < 0

  buffer.read_array_of_double(total_elements)
end

#read_integer_data(total_elements) ⇒ Object

Raises:



168
169
170
171
172
173
174
175
# File 'lib/hdf5/dataset.rb', line 168

def read_integer_data(total_elements)
  buffer = ::FFI::MemoryPointer.new(:int, total_elements)
  status = HDF5::FFI.H5Dread(@dataset_id, HDF5::FFI.H5T_NATIVE_INT, HDF5::DEFAULT_PROPERTY_LIST,
                             HDF5::DEFAULT_PROPERTY_LIST, HDF5::DEFAULT_PROPERTY_LIST, buffer)
  raise HDF5::Error, 'Failed to read integer dataset' if status < 0

  buffer.read_array_of_int(total_elements)
end

#read_string_data(_total_elements) ⇒ Object

Raises:



186
187
188
# File 'lib/hdf5/dataset.rb', line 186

def read_string_data(_total_elements)
  raise HDF5::Error, 'String dataset reading is not supported yet'
end

#shapeObject



136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/hdf5/dataset.rb', line 136

def shape
  dataspace_id = HDF5::FFI.H5Dget_space(@dataset_id)
  raise HDF5::Error, 'Failed to get dataspace' if dataspace_id < 0

  ndims = HDF5::FFI.H5Sget_simple_extent_ndims(dataspace_id)
  raise HDF5::Error, 'Failed to get number of dimensions' if ndims < 0

  dims = ::FFI::MemoryPointer.new(:ulong_long, ndims)
  HDF5::FFI.H5Sget_simple_extent_dims(dataspace_id, dims, nil)

  dims.read_array_of_uint64(ndims)
ensure
  HDF5::FFI.H5Sclose(dataspace_id) if dataspace_id && dataspace_id >= 0
end

#write(data) ⇒ Object

Raises:



109
110
111
112
113
114
115
116
117
118
# File 'lib/hdf5/dataset.rb', line 109

def write(data)
  values = DataHelpers.normalize_data(data)
  mem_type_id = DataHelpers.datatype_id_for(values)
  buffer = DataHelpers.buffer_for(values)
  status = HDF5::FFI.H5Dwrite(@dataset_id, mem_type_id, HDF5::DEFAULT_PROPERTY_LIST, HDF5::DEFAULT_PROPERTY_LIST,
                              HDF5::DEFAULT_PROPERTY_LIST, buffer)
  raise HDF5::Error, 'Failed to write dataset' if status < 0

  data
end