pub struct ArrayBuilder { /* private fields */ }Expand description
An Array builder.
ArrayBuilder is initialised from an array shape, data type, chunk grid, and fill value.
- The default array-to-bytes codec is dependent on the data type:
bytesfor fixed-length data types,vlen-utf8for theStringDataTypevariable-length data type,vlen-bytesfor theBytesDataTypevariable-length data type, andvlenfor any other variable-length data type.
- Array-to-array and bytes-to-bytes codecs are empty by default.
- The default chunk key encoding is
defaultwith the/chunk key separator. - Attributes, storage transformers, and dimension names are empty.
Use the methods in the array builder to change the configuration away from these defaults, and then build the array at a path of some storage with ArrayBuilder::build.
build does not modify the store! Array metadata has to be explicitly written with Array::store_metadata.
§Simple Example
This array is uncompressed, and has no dimension names or attributes.
use zarrs::array::{ArrayBuilder, DataType, FillValue, ZARR_NAN_F32, data_type};
let mut array = ArrayBuilder::new(
vec![8, 8], // array shape
vec![4, 4], // regular chunk shape
data_type::float32(), // data type
f32::NAN, // fill value
)
.build(store.clone(), "/group/array")?;
array.store_metadata()?; // write metadata to the store§Advanced Example
The array is compressed with the zstd codec, dimension names are set, and the experimental rectangular chunk grid is used.
This example uses alternative types to specify the array shape, data type, chunk grid, and fill value.
In general you don’t want to use strings, prefer concrete types (like RectangularChunkGridConfiguration, for example).
use zarrs::array::{ArrayBuilder, DataType, FillValue, ZARR_NAN_F32};
let mut array = ArrayBuilder::new(
[8, 8],
r#"{"name":"rectangular","configuration":{"chunk_shape": [[1, 2, 5], 4]}}"#,
"float32",
"NaN",
)
.bytes_to_bytes_codecs(vec![
#[cfg(feature = "zstd")]
Arc::new(zarrs::array::codec::ZstdCodec::new(5, false)),
])
.dimension_names(Some(["y", "x"]))
.build(store.clone(), "/group/array")?;
array.store_metadata()?; // write metadata to the storeImplementations§
Source§impl ArrayBuilder
impl ArrayBuilder
Sourcepub fn new(
shape: impl Into<ArrayShape>,
chunk_grid_metadata: impl Into<ArrayBuilderChunkGridMetadata>,
data_type: impl Into<ArrayBuilderDataType>,
fill_value: impl Into<ArrayBuilderFillValue>,
) -> Self
pub fn new( shape: impl Into<ArrayShape>, chunk_grid_metadata: impl Into<ArrayBuilderChunkGridMetadata>, data_type: impl Into<ArrayBuilderDataType>, fill_value: impl Into<ArrayBuilderFillValue>, ) -> Self
Create a new array builder for an array at path from an array shape and chunk grid metadata.
The length of the array shape must match the dimensionality of the intended array.
Some chunk grids (e.g. regular) support all zero shape, indicating the shape is unbounded.
Examples found in repository?
157fn main() {
158 let store = std::sync::Arc::new(MemoryStore::default());
159 let array_path = "/array";
160 let array = ArrayBuilder::new(
161 vec![4, 1], // array shape
162 vec![3, 1], // regular chunk shape
163 Arc::new(CustomDataTypeVariableSize),
164 [],
165 )
166 .array_to_array_codecs(vec![
167 #[cfg(feature = "transpose")]
168 Arc::new(zarrs::array::codec::TransposeCodec::new(
169 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
170 )),
171 ])
172 .bytes_to_bytes_codecs(vec![
173 #[cfg(feature = "gzip")]
174 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
175 #[cfg(feature = "crc32c")]
176 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
177 ])
178 // .storage_transformers(vec![].into())
179 .build(store, array_path)
180 .unwrap();
181 println!("{}", array.metadata().to_string_pretty());
182
183 let data = [
184 CustomDataTypeVariableSizeElement::from(Some(1.0)),
185 CustomDataTypeVariableSizeElement::from(None),
186 CustomDataTypeVariableSizeElement::from(Some(3.0)),
187 ];
188 array.store_chunk(&[0, 0], &data).unwrap();
189
190 let data: Vec<CustomDataTypeVariableSizeElement> =
191 array.retrieve_array_subset(&array.subset_all()).unwrap();
192
193 assert_eq!(data[0], CustomDataTypeVariableSizeElement::from(Some(1.0)));
194 assert_eq!(data[1], CustomDataTypeVariableSizeElement::from(None));
195 assert_eq!(data[2], CustomDataTypeVariableSizeElement::from(Some(3.0)));
196 assert_eq!(data[3], CustomDataTypeVariableSizeElement::from(None));
197
198 println!("{data:#?}");
199}More examples
280fn main() {
281 let store = std::sync::Arc::new(MemoryStore::default());
282 let array_path = "/array";
283 let fill_value = CustomDataTypeFixedSizeElement { x: 1, y: 2.3 };
284 let array = ArrayBuilder::new(
285 vec![4, 1], // array shape
286 vec![2, 1], // regular chunk shape
287 Arc::new(CustomDataTypeFixedSize),
288 FillValue::new(fill_value.to_ne_bytes().to_vec()),
289 )
290 .array_to_array_codecs(vec![
291 #[cfg(feature = "transpose")]
292 Arc::new(zarrs::array::codec::TransposeCodec::new(
293 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
294 )),
295 ])
296 .bytes_to_bytes_codecs(vec![
297 #[cfg(feature = "gzip")]
298 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
299 #[cfg(feature = "crc32c")]
300 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
301 ])
302 // .storage_transformers(vec![].into())
303 .build(store, array_path)
304 .unwrap();
305 println!("{}", array.metadata().to_string_pretty());
306
307 let data = [
308 CustomDataTypeFixedSizeElement { x: 3, y: 4.5 },
309 CustomDataTypeFixedSizeElement { x: 6, y: 7.8 },
310 ];
311 array.store_chunk(&[0, 0], &data).unwrap();
312
313 let data: Vec<CustomDataTypeFixedSizeElement> =
314 array.retrieve_array_subset(&array.subset_all()).unwrap();
315
316 assert_eq!(data[0], CustomDataTypeFixedSizeElement { x: 3, y: 4.5 });
317 assert_eq!(data[1], CustomDataTypeFixedSizeElement { x: 6, y: 7.8 });
318 assert_eq!(data[2], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
319 assert_eq!(data[3], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
320
321 println!("{data:#?}");
322}192fn main() {
193 let store = std::sync::Arc::new(MemoryStore::default());
194 let array_path = "/array";
195 let fill_value = CustomDataTypeUInt12Element::try_from(15).unwrap();
196 let array = ArrayBuilder::new(
197 vec![4096, 1], // array shape
198 vec![5, 1], // regular chunk shape
199 Arc::new(CustomDataTypeUInt12),
200 FillValue::new(fill_value.into_le_bytes().to_vec()),
201 )
202 .array_to_array_codecs(vec![
203 #[cfg(feature = "transpose")]
204 Arc::new(zarrs::array::codec::TransposeCodec::new(
205 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
206 )),
207 ])
208 .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
209 .bytes_to_bytes_codecs(vec![
210 #[cfg(feature = "gzip")]
211 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
212 #[cfg(feature = "crc32c")]
213 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
214 ])
215 // .storage_transformers(vec![].into())
216 .build(store, array_path)
217 .unwrap();
218 println!("{}", array.metadata().to_string_pretty());
219
220 let data: Vec<CustomDataTypeUInt12Element> = (0..4096)
221 .map(|i| CustomDataTypeUInt12Element::try_from(i).unwrap())
222 .collect();
223
224 array
225 .store_array_subset(&array.subset_all(), &data)
226 .unwrap();
227
228 let mut data: Vec<CustomDataTypeUInt12Element> =
229 array.retrieve_array_subset(&array.subset_all()).unwrap();
230
231 for (i, d) in data.drain(0..4096).enumerate() {
232 let element = CustomDataTypeUInt12Element::try_from(i as u64).unwrap();
233 assert_eq!(d, element);
234 let element_pd: Vec<CustomDataTypeUInt12Element> = array
235 .retrieve_array_subset(&[(i as u64)..i as u64 + 1, 0..1])
236 .unwrap();
237 assert_eq!(element_pd[0], element);
238 }
239}203fn main() {
204 let store = std::sync::Arc::new(MemoryStore::default());
205 let array_path = "/array";
206 let fill_value = CustomDataTypeFloat8e3m4Element::from(1.23);
207 let array = ArrayBuilder::new(
208 vec![6, 1], // array shape
209 vec![5, 1], // regular chunk shape
210 Arc::new(CustomDataTypeFloat8e3m4),
211 FillValue::new(fill_value.into_ne_bytes().to_vec()),
212 )
213 .array_to_array_codecs(vec![
214 #[cfg(feature = "transpose")]
215 Arc::new(zarrs::array::codec::TransposeCodec::new(
216 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
217 )),
218 ])
219 .bytes_to_bytes_codecs(vec![
220 #[cfg(feature = "gzip")]
221 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
222 #[cfg(feature = "crc32c")]
223 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
224 ])
225 // .storage_transformers(vec![].into())
226 .build(store, array_path)
227 .unwrap();
228 println!("{}", array.metadata().to_string_pretty());
229
230 let data = [
231 CustomDataTypeFloat8e3m4Element::from(2.34),
232 CustomDataTypeFloat8e3m4Element::from(3.45),
233 CustomDataTypeFloat8e3m4Element::from(f32::INFINITY),
234 CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY),
235 CustomDataTypeFloat8e3m4Element::from(f32::NAN),
236 ];
237 array.store_chunk(&[0, 0], &data).unwrap();
238
239 let data: Vec<CustomDataTypeFloat8e3m4Element> =
240 array.retrieve_array_subset(&array.subset_all()).unwrap();
241
242 for f in &data {
243 println!(
244 "float8_e3m4: {:08b} f32: {}",
245 f.into_ne_bytes()[0],
246 f.into_f32()
247 );
248 }
249
250 assert_eq!(data[0], CustomDataTypeFloat8e3m4Element::from(2.34));
251 assert_eq!(data[1], CustomDataTypeFloat8e3m4Element::from(3.45));
252 assert_eq!(
253 data[2],
254 CustomDataTypeFloat8e3m4Element::from(f32::INFINITY)
255 );
256 assert_eq!(
257 data[3],
258 CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY)
259 );
260 assert_eq!(data[4], CustomDataTypeFloat8e3m4Element::from(f32::NAN));
261 assert_eq!(data[5], CustomDataTypeFloat8e3m4Element::from(1.23));
262}194fn main() {
195 let store = std::sync::Arc::new(MemoryStore::default());
196 let array_path = "/array";
197 let fill_value = CustomDataTypeUInt4Element::try_from(15).unwrap();
198 let array = ArrayBuilder::new(
199 vec![6, 1], // array shape
200 vec![5, 1], // regular chunk shape
201 Arc::new(CustomDataTypeUInt4),
202 FillValue::new(fill_value.into_ne_bytes().to_vec()),
203 )
204 .array_to_array_codecs(vec![
205 #[cfg(feature = "transpose")]
206 Arc::new(zarrs::array::codec::TransposeCodec::new(
207 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
208 )),
209 ])
210 .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
211 .bytes_to_bytes_codecs(vec![
212 #[cfg(feature = "gzip")]
213 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
214 #[cfg(feature = "crc32c")]
215 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
216 ])
217 // .storage_transformers(vec![].into())
218 .build(store, array_path)
219 .unwrap();
220 println!("{}", array.metadata().to_string_pretty());
221
222 let data = [
223 CustomDataTypeUInt4Element::try_from(1).unwrap(),
224 CustomDataTypeUInt4Element::try_from(2).unwrap(),
225 CustomDataTypeUInt4Element::try_from(3).unwrap(),
226 CustomDataTypeUInt4Element::try_from(4).unwrap(),
227 CustomDataTypeUInt4Element::try_from(5).unwrap(),
228 ];
229 array.store_chunk(&[0, 0], &data).unwrap();
230
231 let data: Vec<CustomDataTypeUInt4Element> =
232 array.retrieve_array_subset(&array.subset_all()).unwrap();
233
234 for f in &data {
235 println!("uint4: {:08b} u8: {}", f.into_u8(), f.into_u8());
236 }
237
238 assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(1).unwrap());
239 assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(2).unwrap());
240 assert_eq!(data[2], CustomDataTypeUInt4Element::try_from(3).unwrap());
241 assert_eq!(data[3], CustomDataTypeUInt4Element::try_from(4).unwrap());
242 assert_eq!(data[4], CustomDataTypeUInt4Element::try_from(5).unwrap());
243 assert_eq!(data[5], CustomDataTypeUInt4Element::try_from(15).unwrap());
244
245 let data: Vec<CustomDataTypeUInt4Element> = array.retrieve_array_subset(&[1..3, 0..1]).unwrap();
246 assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(2).unwrap());
247 assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(3).unwrap());
248}11fn main() -> Result<(), Box<dyn std::error::Error>> {
12 // Create an in-memory store
13 // let store = Arc::new(zarrs::filesystem::FilesystemStore::new(
14 // "zarrs/tests/data/v3/array_optional_nested.zarr",
15 // )?);
16 let store = Arc::new(zarrs::storage::store::MemoryStore::new());
17
18 // Build the codec chains for the optional codec
19 let array = ArrayBuilder::new(
20 vec![4, 4], // 4x4 array
21 vec![2, 2], // 2x2 chunks
22 data_type::uint8().to_optional().to_optional(), // Optional optional uint8 => Option<Option<u8>>
23 FillValue::new_optional_null().into_optional(), // Fill value => Some(None)
24 )
25 .dimension_names(["y", "x"].into())
26 .attributes(
27 serde_json::json!({
28 "description": r#"A 4x4 array of optional optional uint8 values with some missing data.
29The fill value is null on the inner optional layer, i.e. Some(None).
30N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values:
31 N SN 2 3
32 N 5 N 7
33 SN SN N N
34 SN SN N N"#,
35 })
36 .as_object()
37 .unwrap()
38 .clone(),
39 )
40 .build(store.clone(), "/array")?;
41 array.store_metadata_opt(
42 &zarrs::array::ArrayMetadataOptions::default().with_include_zarrs_metadata(false),
43 )?;
44
45 println!("Array metadata:\n{}", array.metadata().to_string_pretty());
46
47 // Create some data with missing values
48 let data = ndarray::array![
49 [None, Some(None), Some(Some(2u8)), Some(Some(3u8))],
50 [None, Some(Some(5u8)), None, Some(Some(7u8))],
51 [Some(None), Some(None), None, None],
52 [Some(None), Some(None), None, None],
53 ]
54 .into_dyn();
55
56 // Write the data
57 array.store_array_subset(&array.subset_all(), data.clone())?;
58 println!("Data written to array.");
59
60 // Read back the data
61 let data_read: ArrayD<Option<Option<u8>>> = array.retrieve_array_subset(&array.subset_all())?;
62
63 // Verify data integrity
64 assert_eq!(data, data_read);
65
66 // Display the data in a grid format
67 println!(
68 "Data grid. N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values"
69 );
70 println!(" 0 1 2 3");
71 for y in 0..4 {
72 print!("{} ", y);
73 for x in 0..4 {
74 match data_read[[y, x]] {
75 Some(Some(value)) => print!("{:3} ", value),
76 Some(None) => print!(" SN "),
77 None => print!(" N "),
78 }
79 }
80 println!();
81 }
82 Ok(())
83}Sourcepub fn new_with_chunk_grid(
chunk_grid: impl Into<ChunkGrid>,
data_type: impl Into<ArrayBuilderDataType>,
fill_value: impl Into<ArrayBuilderFillValue>,
) -> Self
pub fn new_with_chunk_grid( chunk_grid: impl Into<ChunkGrid>, data_type: impl Into<ArrayBuilderDataType>, fill_value: impl Into<ArrayBuilderFillValue>, ) -> Self
Create a new array builder with a concrete chunk grid (with an associated array shape).
Sourcepub fn from_array<T: ?Sized>(array: &Array<T>) -> Self
pub fn from_array<T: ?Sized>(array: &Array<T>) -> Self
Create a new builder copying the configuration of an existing array.
Sourcepub fn shape(&mut self, shape: impl Into<ArrayShape>) -> &mut Self
pub fn shape(&mut self, shape: impl Into<ArrayShape>) -> &mut Self
Set the shape.
Sourcepub fn data_type(
&mut self,
data_type: impl Into<ArrayBuilderDataType>,
) -> &mut Self
pub fn data_type( &mut self, data_type: impl Into<ArrayBuilderDataType>, ) -> &mut Self
Set the data type.
Sourcepub fn chunk_grid_metadata(
&mut self,
chunk_grid_metadata: impl Into<ArrayBuilderChunkGridMetadata>,
) -> &mut Self
pub fn chunk_grid_metadata( &mut self, chunk_grid_metadata: impl Into<ArrayBuilderChunkGridMetadata>, ) -> &mut Self
Set the chunk grid metadata.
Sourcepub fn chunk_grid(&mut self, chunk_grid: impl Into<ChunkGrid>) -> &mut Self
pub fn chunk_grid(&mut self, chunk_grid: impl Into<ChunkGrid>) -> &mut Self
Set the chunk grid. This may also change the array shape.
Sourcepub fn fill_value(
&mut self,
fill_value: impl Into<ArrayBuilderFillValue>,
) -> &mut Self
pub fn fill_value( &mut self, fill_value: impl Into<ArrayBuilderFillValue>, ) -> &mut Self
Set the fill value.
Sourcepub fn chunk_key_encoding(
&mut self,
chunk_key_encoding: impl Into<ChunkKeyEncoding>,
) -> &mut Self
pub fn chunk_key_encoding( &mut self, chunk_key_encoding: impl Into<ChunkKeyEncoding>, ) -> &mut Self
Set the chunk key encoding.
If left unmodified, the array will use default chunk key encoding with the / chunk key separator.
Sourcepub fn chunk_key_encoding_default_separator(
&mut self,
separator: ChunkKeySeparator,
) -> &mut Self
pub fn chunk_key_encoding_default_separator( &mut self, separator: ChunkKeySeparator, ) -> &mut Self
Set the chunk key encoding to default with separator.
If left unmodified, the array will use default chunk key encoding with the / chunk key separator.
Sourcepub fn array_to_array_codecs(
&mut self,
array_to_array_codecs: Vec<Arc<dyn ArrayToArrayCodecTraits>>,
) -> &mut Self
pub fn array_to_array_codecs( &mut self, array_to_array_codecs: Vec<Arc<dyn ArrayToArrayCodecTraits>>, ) -> &mut Self
Set the array-to-array codecs.
If left unmodified, the array will have no array-to-array codecs.
Examples found in repository?
157fn main() {
158 let store = std::sync::Arc::new(MemoryStore::default());
159 let array_path = "/array";
160 let array = ArrayBuilder::new(
161 vec![4, 1], // array shape
162 vec![3, 1], // regular chunk shape
163 Arc::new(CustomDataTypeVariableSize),
164 [],
165 )
166 .array_to_array_codecs(vec![
167 #[cfg(feature = "transpose")]
168 Arc::new(zarrs::array::codec::TransposeCodec::new(
169 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
170 )),
171 ])
172 .bytes_to_bytes_codecs(vec![
173 #[cfg(feature = "gzip")]
174 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
175 #[cfg(feature = "crc32c")]
176 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
177 ])
178 // .storage_transformers(vec![].into())
179 .build(store, array_path)
180 .unwrap();
181 println!("{}", array.metadata().to_string_pretty());
182
183 let data = [
184 CustomDataTypeVariableSizeElement::from(Some(1.0)),
185 CustomDataTypeVariableSizeElement::from(None),
186 CustomDataTypeVariableSizeElement::from(Some(3.0)),
187 ];
188 array.store_chunk(&[0, 0], &data).unwrap();
189
190 let data: Vec<CustomDataTypeVariableSizeElement> =
191 array.retrieve_array_subset(&array.subset_all()).unwrap();
192
193 assert_eq!(data[0], CustomDataTypeVariableSizeElement::from(Some(1.0)));
194 assert_eq!(data[1], CustomDataTypeVariableSizeElement::from(None));
195 assert_eq!(data[2], CustomDataTypeVariableSizeElement::from(Some(3.0)));
196 assert_eq!(data[3], CustomDataTypeVariableSizeElement::from(None));
197
198 println!("{data:#?}");
199}More examples
280fn main() {
281 let store = std::sync::Arc::new(MemoryStore::default());
282 let array_path = "/array";
283 let fill_value = CustomDataTypeFixedSizeElement { x: 1, y: 2.3 };
284 let array = ArrayBuilder::new(
285 vec![4, 1], // array shape
286 vec![2, 1], // regular chunk shape
287 Arc::new(CustomDataTypeFixedSize),
288 FillValue::new(fill_value.to_ne_bytes().to_vec()),
289 )
290 .array_to_array_codecs(vec![
291 #[cfg(feature = "transpose")]
292 Arc::new(zarrs::array::codec::TransposeCodec::new(
293 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
294 )),
295 ])
296 .bytes_to_bytes_codecs(vec![
297 #[cfg(feature = "gzip")]
298 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
299 #[cfg(feature = "crc32c")]
300 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
301 ])
302 // .storage_transformers(vec![].into())
303 .build(store, array_path)
304 .unwrap();
305 println!("{}", array.metadata().to_string_pretty());
306
307 let data = [
308 CustomDataTypeFixedSizeElement { x: 3, y: 4.5 },
309 CustomDataTypeFixedSizeElement { x: 6, y: 7.8 },
310 ];
311 array.store_chunk(&[0, 0], &data).unwrap();
312
313 let data: Vec<CustomDataTypeFixedSizeElement> =
314 array.retrieve_array_subset(&array.subset_all()).unwrap();
315
316 assert_eq!(data[0], CustomDataTypeFixedSizeElement { x: 3, y: 4.5 });
317 assert_eq!(data[1], CustomDataTypeFixedSizeElement { x: 6, y: 7.8 });
318 assert_eq!(data[2], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
319 assert_eq!(data[3], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
320
321 println!("{data:#?}");
322}192fn main() {
193 let store = std::sync::Arc::new(MemoryStore::default());
194 let array_path = "/array";
195 let fill_value = CustomDataTypeUInt12Element::try_from(15).unwrap();
196 let array = ArrayBuilder::new(
197 vec![4096, 1], // array shape
198 vec![5, 1], // regular chunk shape
199 Arc::new(CustomDataTypeUInt12),
200 FillValue::new(fill_value.into_le_bytes().to_vec()),
201 )
202 .array_to_array_codecs(vec![
203 #[cfg(feature = "transpose")]
204 Arc::new(zarrs::array::codec::TransposeCodec::new(
205 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
206 )),
207 ])
208 .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
209 .bytes_to_bytes_codecs(vec![
210 #[cfg(feature = "gzip")]
211 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
212 #[cfg(feature = "crc32c")]
213 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
214 ])
215 // .storage_transformers(vec![].into())
216 .build(store, array_path)
217 .unwrap();
218 println!("{}", array.metadata().to_string_pretty());
219
220 let data: Vec<CustomDataTypeUInt12Element> = (0..4096)
221 .map(|i| CustomDataTypeUInt12Element::try_from(i).unwrap())
222 .collect();
223
224 array
225 .store_array_subset(&array.subset_all(), &data)
226 .unwrap();
227
228 let mut data: Vec<CustomDataTypeUInt12Element> =
229 array.retrieve_array_subset(&array.subset_all()).unwrap();
230
231 for (i, d) in data.drain(0..4096).enumerate() {
232 let element = CustomDataTypeUInt12Element::try_from(i as u64).unwrap();
233 assert_eq!(d, element);
234 let element_pd: Vec<CustomDataTypeUInt12Element> = array
235 .retrieve_array_subset(&[(i as u64)..i as u64 + 1, 0..1])
236 .unwrap();
237 assert_eq!(element_pd[0], element);
238 }
239}203fn main() {
204 let store = std::sync::Arc::new(MemoryStore::default());
205 let array_path = "/array";
206 let fill_value = CustomDataTypeFloat8e3m4Element::from(1.23);
207 let array = ArrayBuilder::new(
208 vec![6, 1], // array shape
209 vec![5, 1], // regular chunk shape
210 Arc::new(CustomDataTypeFloat8e3m4),
211 FillValue::new(fill_value.into_ne_bytes().to_vec()),
212 )
213 .array_to_array_codecs(vec![
214 #[cfg(feature = "transpose")]
215 Arc::new(zarrs::array::codec::TransposeCodec::new(
216 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
217 )),
218 ])
219 .bytes_to_bytes_codecs(vec![
220 #[cfg(feature = "gzip")]
221 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
222 #[cfg(feature = "crc32c")]
223 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
224 ])
225 // .storage_transformers(vec![].into())
226 .build(store, array_path)
227 .unwrap();
228 println!("{}", array.metadata().to_string_pretty());
229
230 let data = [
231 CustomDataTypeFloat8e3m4Element::from(2.34),
232 CustomDataTypeFloat8e3m4Element::from(3.45),
233 CustomDataTypeFloat8e3m4Element::from(f32::INFINITY),
234 CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY),
235 CustomDataTypeFloat8e3m4Element::from(f32::NAN),
236 ];
237 array.store_chunk(&[0, 0], &data).unwrap();
238
239 let data: Vec<CustomDataTypeFloat8e3m4Element> =
240 array.retrieve_array_subset(&array.subset_all()).unwrap();
241
242 for f in &data {
243 println!(
244 "float8_e3m4: {:08b} f32: {}",
245 f.into_ne_bytes()[0],
246 f.into_f32()
247 );
248 }
249
250 assert_eq!(data[0], CustomDataTypeFloat8e3m4Element::from(2.34));
251 assert_eq!(data[1], CustomDataTypeFloat8e3m4Element::from(3.45));
252 assert_eq!(
253 data[2],
254 CustomDataTypeFloat8e3m4Element::from(f32::INFINITY)
255 );
256 assert_eq!(
257 data[3],
258 CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY)
259 );
260 assert_eq!(data[4], CustomDataTypeFloat8e3m4Element::from(f32::NAN));
261 assert_eq!(data[5], CustomDataTypeFloat8e3m4Element::from(1.23));
262}194fn main() {
195 let store = std::sync::Arc::new(MemoryStore::default());
196 let array_path = "/array";
197 let fill_value = CustomDataTypeUInt4Element::try_from(15).unwrap();
198 let array = ArrayBuilder::new(
199 vec![6, 1], // array shape
200 vec![5, 1], // regular chunk shape
201 Arc::new(CustomDataTypeUInt4),
202 FillValue::new(fill_value.into_ne_bytes().to_vec()),
203 )
204 .array_to_array_codecs(vec![
205 #[cfg(feature = "transpose")]
206 Arc::new(zarrs::array::codec::TransposeCodec::new(
207 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
208 )),
209 ])
210 .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
211 .bytes_to_bytes_codecs(vec![
212 #[cfg(feature = "gzip")]
213 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
214 #[cfg(feature = "crc32c")]
215 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
216 ])
217 // .storage_transformers(vec![].into())
218 .build(store, array_path)
219 .unwrap();
220 println!("{}", array.metadata().to_string_pretty());
221
222 let data = [
223 CustomDataTypeUInt4Element::try_from(1).unwrap(),
224 CustomDataTypeUInt4Element::try_from(2).unwrap(),
225 CustomDataTypeUInt4Element::try_from(3).unwrap(),
226 CustomDataTypeUInt4Element::try_from(4).unwrap(),
227 CustomDataTypeUInt4Element::try_from(5).unwrap(),
228 ];
229 array.store_chunk(&[0, 0], &data).unwrap();
230
231 let data: Vec<CustomDataTypeUInt4Element> =
232 array.retrieve_array_subset(&array.subset_all()).unwrap();
233
234 for f in &data {
235 println!("uint4: {:08b} u8: {}", f.into_u8(), f.into_u8());
236 }
237
238 assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(1).unwrap());
239 assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(2).unwrap());
240 assert_eq!(data[2], CustomDataTypeUInt4Element::try_from(3).unwrap());
241 assert_eq!(data[3], CustomDataTypeUInt4Element::try_from(4).unwrap());
242 assert_eq!(data[4], CustomDataTypeUInt4Element::try_from(5).unwrap());
243 assert_eq!(data[5], CustomDataTypeUInt4Element::try_from(15).unwrap());
244
245 let data: Vec<CustomDataTypeUInt4Element> = array.retrieve_array_subset(&[1..3, 0..1]).unwrap();
246 assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(2).unwrap());
247 assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(3).unwrap());
248}Sourcepub fn array_to_bytes_codec(
&mut self,
array_to_bytes_codec: Arc<dyn ArrayToBytesCodecTraits>,
) -> &mut Self
pub fn array_to_bytes_codec( &mut self, array_to_bytes_codec: Arc<dyn ArrayToBytesCodecTraits>, ) -> &mut Self
Set the array-to-bytes codec.
If left unmodified, the array will default to using the bytes codec with native endian encoding.
Examples found in repository?
192fn main() {
193 let store = std::sync::Arc::new(MemoryStore::default());
194 let array_path = "/array";
195 let fill_value = CustomDataTypeUInt12Element::try_from(15).unwrap();
196 let array = ArrayBuilder::new(
197 vec![4096, 1], // array shape
198 vec![5, 1], // regular chunk shape
199 Arc::new(CustomDataTypeUInt12),
200 FillValue::new(fill_value.into_le_bytes().to_vec()),
201 )
202 .array_to_array_codecs(vec![
203 #[cfg(feature = "transpose")]
204 Arc::new(zarrs::array::codec::TransposeCodec::new(
205 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
206 )),
207 ])
208 .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
209 .bytes_to_bytes_codecs(vec![
210 #[cfg(feature = "gzip")]
211 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
212 #[cfg(feature = "crc32c")]
213 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
214 ])
215 // .storage_transformers(vec![].into())
216 .build(store, array_path)
217 .unwrap();
218 println!("{}", array.metadata().to_string_pretty());
219
220 let data: Vec<CustomDataTypeUInt12Element> = (0..4096)
221 .map(|i| CustomDataTypeUInt12Element::try_from(i).unwrap())
222 .collect();
223
224 array
225 .store_array_subset(&array.subset_all(), &data)
226 .unwrap();
227
228 let mut data: Vec<CustomDataTypeUInt12Element> =
229 array.retrieve_array_subset(&array.subset_all()).unwrap();
230
231 for (i, d) in data.drain(0..4096).enumerate() {
232 let element = CustomDataTypeUInt12Element::try_from(i as u64).unwrap();
233 assert_eq!(d, element);
234 let element_pd: Vec<CustomDataTypeUInt12Element> = array
235 .retrieve_array_subset(&[(i as u64)..i as u64 + 1, 0..1])
236 .unwrap();
237 assert_eq!(element_pd[0], element);
238 }
239}More examples
194fn main() {
195 let store = std::sync::Arc::new(MemoryStore::default());
196 let array_path = "/array";
197 let fill_value = CustomDataTypeUInt4Element::try_from(15).unwrap();
198 let array = ArrayBuilder::new(
199 vec![6, 1], // array shape
200 vec![5, 1], // regular chunk shape
201 Arc::new(CustomDataTypeUInt4),
202 FillValue::new(fill_value.into_ne_bytes().to_vec()),
203 )
204 .array_to_array_codecs(vec![
205 #[cfg(feature = "transpose")]
206 Arc::new(zarrs::array::codec::TransposeCodec::new(
207 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
208 )),
209 ])
210 .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
211 .bytes_to_bytes_codecs(vec![
212 #[cfg(feature = "gzip")]
213 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
214 #[cfg(feature = "crc32c")]
215 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
216 ])
217 // .storage_transformers(vec![].into())
218 .build(store, array_path)
219 .unwrap();
220 println!("{}", array.metadata().to_string_pretty());
221
222 let data = [
223 CustomDataTypeUInt4Element::try_from(1).unwrap(),
224 CustomDataTypeUInt4Element::try_from(2).unwrap(),
225 CustomDataTypeUInt4Element::try_from(3).unwrap(),
226 CustomDataTypeUInt4Element::try_from(4).unwrap(),
227 CustomDataTypeUInt4Element::try_from(5).unwrap(),
228 ];
229 array.store_chunk(&[0, 0], &data).unwrap();
230
231 let data: Vec<CustomDataTypeUInt4Element> =
232 array.retrieve_array_subset(&array.subset_all()).unwrap();
233
234 for f in &data {
235 println!("uint4: {:08b} u8: {}", f.into_u8(), f.into_u8());
236 }
237
238 assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(1).unwrap());
239 assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(2).unwrap());
240 assert_eq!(data[2], CustomDataTypeUInt4Element::try_from(3).unwrap());
241 assert_eq!(data[3], CustomDataTypeUInt4Element::try_from(4).unwrap());
242 assert_eq!(data[4], CustomDataTypeUInt4Element::try_from(5).unwrap());
243 assert_eq!(data[5], CustomDataTypeUInt4Element::try_from(15).unwrap());
244
245 let data: Vec<CustomDataTypeUInt4Element> = array.retrieve_array_subset(&[1..3, 0..1]).unwrap();
246 assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(2).unwrap());
247 assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(3).unwrap());
248}Sourcepub fn bytes_to_bytes_codecs(
&mut self,
bytes_to_bytes_codecs: Vec<Arc<dyn BytesToBytesCodecTraits>>,
) -> &mut Self
pub fn bytes_to_bytes_codecs( &mut self, bytes_to_bytes_codecs: Vec<Arc<dyn BytesToBytesCodecTraits>>, ) -> &mut Self
Set the bytes-to-bytes codecs.
If left unmodified, the array will have no bytes-to-bytes codecs.
Examples found in repository?
157fn main() {
158 let store = std::sync::Arc::new(MemoryStore::default());
159 let array_path = "/array";
160 let array = ArrayBuilder::new(
161 vec![4, 1], // array shape
162 vec![3, 1], // regular chunk shape
163 Arc::new(CustomDataTypeVariableSize),
164 [],
165 )
166 .array_to_array_codecs(vec![
167 #[cfg(feature = "transpose")]
168 Arc::new(zarrs::array::codec::TransposeCodec::new(
169 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
170 )),
171 ])
172 .bytes_to_bytes_codecs(vec![
173 #[cfg(feature = "gzip")]
174 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
175 #[cfg(feature = "crc32c")]
176 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
177 ])
178 // .storage_transformers(vec![].into())
179 .build(store, array_path)
180 .unwrap();
181 println!("{}", array.metadata().to_string_pretty());
182
183 let data = [
184 CustomDataTypeVariableSizeElement::from(Some(1.0)),
185 CustomDataTypeVariableSizeElement::from(None),
186 CustomDataTypeVariableSizeElement::from(Some(3.0)),
187 ];
188 array.store_chunk(&[0, 0], &data).unwrap();
189
190 let data: Vec<CustomDataTypeVariableSizeElement> =
191 array.retrieve_array_subset(&array.subset_all()).unwrap();
192
193 assert_eq!(data[0], CustomDataTypeVariableSizeElement::from(Some(1.0)));
194 assert_eq!(data[1], CustomDataTypeVariableSizeElement::from(None));
195 assert_eq!(data[2], CustomDataTypeVariableSizeElement::from(Some(3.0)));
196 assert_eq!(data[3], CustomDataTypeVariableSizeElement::from(None));
197
198 println!("{data:#?}");
199}More examples
280fn main() {
281 let store = std::sync::Arc::new(MemoryStore::default());
282 let array_path = "/array";
283 let fill_value = CustomDataTypeFixedSizeElement { x: 1, y: 2.3 };
284 let array = ArrayBuilder::new(
285 vec![4, 1], // array shape
286 vec![2, 1], // regular chunk shape
287 Arc::new(CustomDataTypeFixedSize),
288 FillValue::new(fill_value.to_ne_bytes().to_vec()),
289 )
290 .array_to_array_codecs(vec![
291 #[cfg(feature = "transpose")]
292 Arc::new(zarrs::array::codec::TransposeCodec::new(
293 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
294 )),
295 ])
296 .bytes_to_bytes_codecs(vec![
297 #[cfg(feature = "gzip")]
298 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
299 #[cfg(feature = "crc32c")]
300 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
301 ])
302 // .storage_transformers(vec![].into())
303 .build(store, array_path)
304 .unwrap();
305 println!("{}", array.metadata().to_string_pretty());
306
307 let data = [
308 CustomDataTypeFixedSizeElement { x: 3, y: 4.5 },
309 CustomDataTypeFixedSizeElement { x: 6, y: 7.8 },
310 ];
311 array.store_chunk(&[0, 0], &data).unwrap();
312
313 let data: Vec<CustomDataTypeFixedSizeElement> =
314 array.retrieve_array_subset(&array.subset_all()).unwrap();
315
316 assert_eq!(data[0], CustomDataTypeFixedSizeElement { x: 3, y: 4.5 });
317 assert_eq!(data[1], CustomDataTypeFixedSizeElement { x: 6, y: 7.8 });
318 assert_eq!(data[2], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
319 assert_eq!(data[3], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
320
321 println!("{data:#?}");
322}192fn main() {
193 let store = std::sync::Arc::new(MemoryStore::default());
194 let array_path = "/array";
195 let fill_value = CustomDataTypeUInt12Element::try_from(15).unwrap();
196 let array = ArrayBuilder::new(
197 vec![4096, 1], // array shape
198 vec![5, 1], // regular chunk shape
199 Arc::new(CustomDataTypeUInt12),
200 FillValue::new(fill_value.into_le_bytes().to_vec()),
201 )
202 .array_to_array_codecs(vec![
203 #[cfg(feature = "transpose")]
204 Arc::new(zarrs::array::codec::TransposeCodec::new(
205 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
206 )),
207 ])
208 .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
209 .bytes_to_bytes_codecs(vec![
210 #[cfg(feature = "gzip")]
211 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
212 #[cfg(feature = "crc32c")]
213 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
214 ])
215 // .storage_transformers(vec![].into())
216 .build(store, array_path)
217 .unwrap();
218 println!("{}", array.metadata().to_string_pretty());
219
220 let data: Vec<CustomDataTypeUInt12Element> = (0..4096)
221 .map(|i| CustomDataTypeUInt12Element::try_from(i).unwrap())
222 .collect();
223
224 array
225 .store_array_subset(&array.subset_all(), &data)
226 .unwrap();
227
228 let mut data: Vec<CustomDataTypeUInt12Element> =
229 array.retrieve_array_subset(&array.subset_all()).unwrap();
230
231 for (i, d) in data.drain(0..4096).enumerate() {
232 let element = CustomDataTypeUInt12Element::try_from(i as u64).unwrap();
233 assert_eq!(d, element);
234 let element_pd: Vec<CustomDataTypeUInt12Element> = array
235 .retrieve_array_subset(&[(i as u64)..i as u64 + 1, 0..1])
236 .unwrap();
237 assert_eq!(element_pd[0], element);
238 }
239}203fn main() {
204 let store = std::sync::Arc::new(MemoryStore::default());
205 let array_path = "/array";
206 let fill_value = CustomDataTypeFloat8e3m4Element::from(1.23);
207 let array = ArrayBuilder::new(
208 vec![6, 1], // array shape
209 vec![5, 1], // regular chunk shape
210 Arc::new(CustomDataTypeFloat8e3m4),
211 FillValue::new(fill_value.into_ne_bytes().to_vec()),
212 )
213 .array_to_array_codecs(vec![
214 #[cfg(feature = "transpose")]
215 Arc::new(zarrs::array::codec::TransposeCodec::new(
216 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
217 )),
218 ])
219 .bytes_to_bytes_codecs(vec![
220 #[cfg(feature = "gzip")]
221 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
222 #[cfg(feature = "crc32c")]
223 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
224 ])
225 // .storage_transformers(vec![].into())
226 .build(store, array_path)
227 .unwrap();
228 println!("{}", array.metadata().to_string_pretty());
229
230 let data = [
231 CustomDataTypeFloat8e3m4Element::from(2.34),
232 CustomDataTypeFloat8e3m4Element::from(3.45),
233 CustomDataTypeFloat8e3m4Element::from(f32::INFINITY),
234 CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY),
235 CustomDataTypeFloat8e3m4Element::from(f32::NAN),
236 ];
237 array.store_chunk(&[0, 0], &data).unwrap();
238
239 let data: Vec<CustomDataTypeFloat8e3m4Element> =
240 array.retrieve_array_subset(&array.subset_all()).unwrap();
241
242 for f in &data {
243 println!(
244 "float8_e3m4: {:08b} f32: {}",
245 f.into_ne_bytes()[0],
246 f.into_f32()
247 );
248 }
249
250 assert_eq!(data[0], CustomDataTypeFloat8e3m4Element::from(2.34));
251 assert_eq!(data[1], CustomDataTypeFloat8e3m4Element::from(3.45));
252 assert_eq!(
253 data[2],
254 CustomDataTypeFloat8e3m4Element::from(f32::INFINITY)
255 );
256 assert_eq!(
257 data[3],
258 CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY)
259 );
260 assert_eq!(data[4], CustomDataTypeFloat8e3m4Element::from(f32::NAN));
261 assert_eq!(data[5], CustomDataTypeFloat8e3m4Element::from(1.23));
262}194fn main() {
195 let store = std::sync::Arc::new(MemoryStore::default());
196 let array_path = "/array";
197 let fill_value = CustomDataTypeUInt4Element::try_from(15).unwrap();
198 let array = ArrayBuilder::new(
199 vec![6, 1], // array shape
200 vec![5, 1], // regular chunk shape
201 Arc::new(CustomDataTypeUInt4),
202 FillValue::new(fill_value.into_ne_bytes().to_vec()),
203 )
204 .array_to_array_codecs(vec![
205 #[cfg(feature = "transpose")]
206 Arc::new(zarrs::array::codec::TransposeCodec::new(
207 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
208 )),
209 ])
210 .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
211 .bytes_to_bytes_codecs(vec![
212 #[cfg(feature = "gzip")]
213 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
214 #[cfg(feature = "crc32c")]
215 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
216 ])
217 // .storage_transformers(vec![].into())
218 .build(store, array_path)
219 .unwrap();
220 println!("{}", array.metadata().to_string_pretty());
221
222 let data = [
223 CustomDataTypeUInt4Element::try_from(1).unwrap(),
224 CustomDataTypeUInt4Element::try_from(2).unwrap(),
225 CustomDataTypeUInt4Element::try_from(3).unwrap(),
226 CustomDataTypeUInt4Element::try_from(4).unwrap(),
227 CustomDataTypeUInt4Element::try_from(5).unwrap(),
228 ];
229 array.store_chunk(&[0, 0], &data).unwrap();
230
231 let data: Vec<CustomDataTypeUInt4Element> =
232 array.retrieve_array_subset(&array.subset_all()).unwrap();
233
234 for f in &data {
235 println!("uint4: {:08b} u8: {}", f.into_u8(), f.into_u8());
236 }
237
238 assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(1).unwrap());
239 assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(2).unwrap());
240 assert_eq!(data[2], CustomDataTypeUInt4Element::try_from(3).unwrap());
241 assert_eq!(data[3], CustomDataTypeUInt4Element::try_from(4).unwrap());
242 assert_eq!(data[4], CustomDataTypeUInt4Element::try_from(5).unwrap());
243 assert_eq!(data[5], CustomDataTypeUInt4Element::try_from(15).unwrap());
244
245 let data: Vec<CustomDataTypeUInt4Element> = array.retrieve_array_subset(&[1..3, 0..1]).unwrap();
246 assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(2).unwrap());
247 assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(3).unwrap());
248}10fn rectilinear_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
11 use rayon::prelude::{IntoParallelIterator, ParallelIterator};
12 use zarrs::array::{ArraySubset, ZARR_NAN_F32, codec, data_type};
13 use zarrs::node::Node;
14 use zarrs::storage::store;
15
16 // Create a store
17 // let path = tempfile::TempDir::new()?;
18 // let mut store: ReadableWritableListableStorage =
19 // Arc::new(zarrs::filesystem::FilesystemStore::new(path.path())?);
20 let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new());
21 if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
22 && arg1 == "--usage-log"
23 {
24 let log_writer = Arc::new(std::sync::Mutex::new(
25 // std::io::BufWriter::new(
26 std::io::stdout(),
27 // )
28 ));
29 store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
30 chrono::Utc::now().format("[%T%.3f] ").to_string()
31 }));
32 }
33
34 // Create the root group
35 zarrs::group::GroupBuilder::new()
36 .build(store.clone(), "/")?
37 .store_metadata()?;
38
39 // Create a group with attributes
40 let group_path = "/group";
41 let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
42 group
43 .attributes_mut()
44 .insert("foo".into(), serde_json::Value::String("bar".into()));
45 group.store_metadata()?;
46
47 println!(
48 "The group metadata is:\n{}\n",
49 group.metadata().to_string_pretty()
50 );
51
52 // Create an array
53 let array_path = "/group/array";
54 let array = zarrs::array::ArrayBuilder::new(
55 vec![8, 8], // array shape
56 MetadataV3::new_with_configuration(
57 "rectilinear",
58 RectilinearChunkGridConfiguration::Inline {
59 chunk_shapes: vec![
60 // Varying: chunk sizes [1, 1, 1, 3, 2] (run-length encoded as [[1,3], 3, 2])
61 ChunkEdgeLengths::Varying(serde_json::from_str("[[1,3], 3, 2]").unwrap()),
62 // Scalar: regular 4-element chunks
63 ChunkEdgeLengths::Scalar(NonZeroU64::new(4).unwrap()),
64 ],
65 },
66 ),
67 data_type::float32(),
68 ZARR_NAN_F32,
69 )
70 .bytes_to_bytes_codecs(vec![
71 #[cfg(feature = "gzip")]
72 Arc::new(codec::GzipCodec::new(5)?),
73 ])
74 .dimension_names(["y", "x"].into())
75 // .storage_transformers(vec![].into())
76 .build(store.clone(), array_path)?;
77
78 // Write array metadata to store
79 array.store_metadata()?;
80
81 // Write some chunks (in parallel)
82 (0..4).into_par_iter().try_for_each(|i| {
83 let chunk_grid = array.chunk_grid();
84 let chunk_indices = vec![i, 0];
85 if let Some(chunk_shape) = chunk_grid.chunk_shape(&chunk_indices)? {
86 let chunk_array = ndarray::ArrayD::<f32>::from_elem(
87 chunk_shape
88 .iter()
89 .map(|u| u.get() as usize)
90 .collect::<Vec<_>>(),
91 i as f32,
92 );
93 array.store_chunk(&chunk_indices, chunk_array)
94 } else {
95 Err(zarrs::array::ArrayError::InvalidChunkGridIndicesError(
96 chunk_indices.to_vec(),
97 ))
98 }
99 })?;
100
101 println!(
102 "The array metadata is:\n{}\n",
103 array.metadata().to_string_pretty()
104 );
105
106 // Write a subset spanning multiple chunks, including updating chunks already written
107 array.store_array_subset(
108 &[3..6, 3..6], // start
109 ndarray::ArrayD::<f32>::from_shape_vec(
110 vec![3, 3],
111 vec![0.1f32, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9],
112 )?,
113 )?;
114
115 // Store elements directly, in this case set the 7th column to 123.0
116 array.store_array_subset(&[0..8, 6..7], &[123.0f32; 8])?;
117
118 // Store elements directly in a chunk, in this case set the last row of the bottom right chunk
119 array.store_chunk_subset(
120 // chunk indices
121 &[3, 1],
122 // subset within chunk
123 &[1..2, 0..4],
124 &[-4.0f32; 4],
125 )?;
126
127 // Read the whole array
128 let data_all: ndarray::ArrayD<f32> = array.retrieve_array_subset(&array.subset_all())?;
129 println!("The whole array is:\n{data_all}\n");
130
131 // Read a chunk back from the store
132 let chunk_indices = vec![1, 0];
133 let data_chunk: ndarray::ArrayD<f32> = array.retrieve_chunk(&chunk_indices)?;
134 println!("Chunk [1,0] is:\n{data_chunk}\n");
135
136 // Read the central 4x2 subset of the array
137 let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
138 let data_4x2: ndarray::ArrayD<f32> = array.retrieve_array_subset(&subset_4x2)?;
139 println!("The middle 4x2 subset is:\n{data_4x2}\n");
140
141 // Show the hierarchy
142 let node = Node::open(&store, "/").unwrap();
143 let tree = node.hierarchy_tree();
144 println!("The Zarr hierarchy tree is:\n{tree}");
145
146 Ok(())
147}Sourcepub fn subchunk_shape(
&mut self,
subchunk_shape: impl Into<Option<ArrayShape>>,
) -> &mut Self
Available on crate feature sharding only.
pub fn subchunk_shape( &mut self, subchunk_shape: impl Into<Option<ArrayShape>>, ) -> &mut Self
sharding only.Set the subchunk (inner chunk) shape for sharding.
When set, the array will use the sharding codec.
The chunk shape is the shard shape, and subchunk_shape is the shape of the subchunks within each shard.
If left unmodified or set to None, the array will not use sharding, unless configured manually via array_to_bytes_codec.
The subchunk shape must have all non-zero elements (validated during build).
§Sharding Configuration
This method uses a default ShardingCodecBuilder configuration:
- No array-to-array codecs preceding the sharding codec
- No bytes-to-bytes codecs following the sharding codec
- The shard index is encoded with
crc32cchecksum (if thecrc32cfeature is enabled)
The codecs specified via array_to_array_codecs,
array_to_bytes_codec, and
bytes_to_bytes_codecs are used internally
for encoding the subchunks within each shard.
For more advanced usage (e.g., compressing an entire shard), set
array_to_bytes_codec explicitly with a sharding codec
built using ShardingCodecBuilder.
§Example
let array = ArrayBuilder::new(
vec![64, 64], // array shape
vec![16, 16], // chunk (shard) shape
data_type::float32(),
0.0f32,
)
.subchunk_shape(vec![4, 4]) // subchunk shape within each shard
.build(store, "/array")
.unwrap();Examples found in repository?
10fn sharded_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
11 use std::sync::Arc;
12
13 use rayon::prelude::{IntoParallelIterator, ParallelIterator};
14 use zarrs::array::{ArraySubset, codec, data_type};
15 use zarrs::node::Node;
16 use zarrs::storage::store;
17
18 // Create a store
19 // let path = tempfile::TempDir::new()?;
20 // let mut store: ReadableWritableListableStorage =
21 // Arc::new(zarrs::filesystem::FilesystemStore::new(path.path())?);
22 // let mut store: ReadableWritableListableStorage = Arc::new(
23 // zarrs::filesystem::FilesystemStore::new("zarrs/tests/data/sharded_array_write_read.zarr")?,
24 // );
25 let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new());
26 if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
27 && arg1 == "--usage-log"
28 {
29 let log_writer = Arc::new(std::sync::Mutex::new(
30 // std::io::BufWriter::new(
31 std::io::stdout(),
32 // )
33 ));
34 store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
35 chrono::Utc::now().format("[%T%.3f] ").to_string()
36 }));
37 }
38
39 // Create the root group
40 zarrs::group::GroupBuilder::new()
41 .build(store.clone(), "/")?
42 .store_metadata()?;
43
44 // Create a group with attributes
45 let group_path = "/group";
46 let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
47 group
48 .attributes_mut()
49 .insert("foo".into(), serde_json::Value::String("bar".into()));
50 group.store_metadata()?;
51
52 // Create an array
53 let array_path = "/group/array";
54 let subchunk_shape = vec![4, 4];
55 let array = zarrs::array::ArrayBuilder::new(
56 vec![8, 8], // array shape
57 vec![4, 8], // chunk (shard) shape
58 data_type::uint16(),
59 0u16,
60 )
61 .subchunk_shape(subchunk_shape.clone())
62 .bytes_to_bytes_codecs(vec![
63 #[cfg(feature = "gzip")]
64 Arc::new(codec::GzipCodec::new(5)?),
65 ])
66 .dimension_names(["y", "x"].into())
67 // .storage_transformers(vec![].into())
68 .build(store.clone(), array_path)?;
69
70 // Write array metadata to store
71 array.store_metadata()?;
72
73 // The array metadata is
74 println!(
75 "The array metadata is:\n{}\n",
76 array.metadata().to_string_pretty()
77 );
78
79 // Use default codec options (concurrency etc)
80 let options = CodecOptions::default();
81
82 // Write some shards (in parallel)
83 (0..2).into_par_iter().try_for_each(|s| {
84 let chunk_grid = array.chunk_grid();
85 let chunk_indices = vec![s, 0];
86 if let Some(chunk_shape) = chunk_grid.chunk_shape(&chunk_indices)? {
87 let chunk_array = ndarray::ArrayD::<u16>::from_shape_fn(
88 chunk_shape
89 .iter()
90 .map(|u| u.get() as usize)
91 .collect::<Vec<_>>(),
92 |ij| {
93 (s * chunk_shape[0].get() * chunk_shape[1].get()
94 + ij[0] as u64 * chunk_shape[1].get()
95 + ij[1] as u64) as u16
96 },
97 );
98 array.store_chunk(&chunk_indices, chunk_array)
99 } else {
100 Err(zarrs::array::ArrayError::InvalidChunkGridIndicesError(
101 chunk_indices.to_vec(),
102 ))
103 }
104 })?;
105
106 // Read the whole array
107 let data_all: ArrayD<u16> = array.retrieve_array_subset(&array.subset_all())?;
108 println!("The whole array is:\n{data_all}\n");
109
110 // Read a shard back from the store
111 let shard_indices = vec![1, 0];
112 let data_shard: ArrayD<u16> = array.retrieve_chunk(&shard_indices)?;
113 println!("Shard [1,0] is:\n{data_shard}\n");
114
115 // Read a subchunk from the store
116 let subset_chunk_1_0 = ArraySubset::new_with_ranges(&[4..8, 0..4]);
117 let data_chunk: ArrayD<u16> = array.retrieve_array_subset(&subset_chunk_1_0)?;
118 println!("Chunk [1,0] is:\n{data_chunk}\n");
119
120 // Read the central 4x2 subset of the array
121 let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
122 let data_4x2: ArrayD<u16> = array.retrieve_array_subset(&subset_4x2)?;
123 println!("The middle 4x2 subset is:\n{data_4x2}\n");
124
125 // Decode subchunks
126 // In some cases, it might be preferable to decode subchunks in a shard directly.
127 // If using the partial decoder, then the shard index will only be read once from the store.
128 let partial_decoder = array.partial_decoder(&[0, 0])?;
129 println!("Decoded subchunks:");
130 for subchunk_subset in [
131 ArraySubset::new_with_start_shape(vec![0, 0], subchunk_shape.clone())?,
132 ArraySubset::new_with_start_shape(vec![0, 4], subchunk_shape.clone())?,
133 ] {
134 println!("{subchunk_subset}");
135 let decoded_subchunk_bytes = partial_decoder.partial_decode(&subchunk_subset, &options)?;
136 let ndarray = bytes_to_ndarray::<u16>(
137 &subchunk_shape,
138 decoded_subchunk_bytes.into_fixed()?.into_owned(),
139 )?;
140 println!("{ndarray}\n");
141 }
142
143 // Show the hierarchy
144 let node = Node::open(&store, "/").unwrap();
145 let tree = node.hierarchy_tree();
146 println!("The Zarr hierarchy tree is:\n{}", tree);
147
148 println!(
149 "The keys in the store are:\n[{}]",
150 store.list().unwrap_or_default().iter().format(", ")
151 );
152
153 Ok(())
154}Sourcepub fn attributes(&mut self, attributes: Map<String, Value>) -> &mut Self
pub fn attributes(&mut self, attributes: Map<String, Value>) -> &mut Self
Set the user defined attributes.
If left unmodified, the user defined attributes of the array will be empty.
Examples found in repository?
11fn main() -> Result<(), Box<dyn std::error::Error>> {
12 // Create an in-memory store
13 // let store = Arc::new(zarrs::filesystem::FilesystemStore::new(
14 // "zarrs/tests/data/v3/array_optional_nested.zarr",
15 // )?);
16 let store = Arc::new(zarrs::storage::store::MemoryStore::new());
17
18 // Build the codec chains for the optional codec
19 let array = ArrayBuilder::new(
20 vec![4, 4], // 4x4 array
21 vec![2, 2], // 2x2 chunks
22 data_type::uint8().to_optional().to_optional(), // Optional optional uint8 => Option<Option<u8>>
23 FillValue::new_optional_null().into_optional(), // Fill value => Some(None)
24 )
25 .dimension_names(["y", "x"].into())
26 .attributes(
27 serde_json::json!({
28 "description": r#"A 4x4 array of optional optional uint8 values with some missing data.
29The fill value is null on the inner optional layer, i.e. Some(None).
30N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values:
31 N SN 2 3
32 N 5 N 7
33 SN SN N N
34 SN SN N N"#,
35 })
36 .as_object()
37 .unwrap()
38 .clone(),
39 )
40 .build(store.clone(), "/array")?;
41 array.store_metadata_opt(
42 &zarrs::array::ArrayMetadataOptions::default().with_include_zarrs_metadata(false),
43 )?;
44
45 println!("Array metadata:\n{}", array.metadata().to_string_pretty());
46
47 // Create some data with missing values
48 let data = ndarray::array![
49 [None, Some(None), Some(Some(2u8)), Some(Some(3u8))],
50 [None, Some(Some(5u8)), None, Some(Some(7u8))],
51 [Some(None), Some(None), None, None],
52 [Some(None), Some(None), None, None],
53 ]
54 .into_dyn();
55
56 // Write the data
57 array.store_array_subset(&array.subset_all(), data.clone())?;
58 println!("Data written to array.");
59
60 // Read back the data
61 let data_read: ArrayD<Option<Option<u8>>> = array.retrieve_array_subset(&array.subset_all())?;
62
63 // Verify data integrity
64 assert_eq!(data, data_read);
65
66 // Display the data in a grid format
67 println!(
68 "Data grid. N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values"
69 );
70 println!(" 0 1 2 3");
71 for y in 0..4 {
72 print!("{} ", y);
73 for x in 0..4 {
74 match data_read[[y, x]] {
75 Some(Some(value)) => print!("{:3} ", value),
76 Some(None) => print!(" SN "),
77 None => print!(" N "),
78 }
79 }
80 println!();
81 }
82 Ok(())
83}More examples
18fn main() -> Result<(), Box<dyn std::error::Error>> {
19 // Create an in-memory store
20 // let store = Arc::new(zarrs::filesystem::FilesystemStore::new(
21 // "zarrs/tests/data/v3/array_optional.zarr",
22 // )?);
23 let store = Arc::new(zarrs::storage::store::MemoryStore::new());
24
25 // Build the codec chains for the optional codec
26 let array = ArrayBuilder::new(
27 vec![4, 4], // 4x4 array
28 vec![2, 2], // 2x2 chunks
29 data_type::uint8().to_optional(), // Optional uint8
30 FillValue::new_optional_null(), // Null fill value: [0]
31 )
32 .dimension_names(["y", "x"].into())
33 .attributes(
34 serde_json::json!({
35 "description": r#"A 4x4 array of optional uint8 values with some missing data.
36N marks missing (`None`=`null`) values:
37 0 N 2 3
38 N 5 N 7
39 8 9 N N
4012 N N N"#,
41 })
42 .as_object()
43 .unwrap()
44 .clone(),
45 )
46 .build(store.clone(), "/array")?;
47 array.store_metadata_opt(
48 &zarrs::array::ArrayMetadataOptions::default().with_include_zarrs_metadata(false),
49 )?;
50
51 println!("Array metadata:\n{}", array.metadata().to_string_pretty());
52
53 // Create some data with missing values
54 let data = ndarray::array![
55 [Some(0u8), None, Some(2u8), Some(3u8)],
56 [None, Some(5u8), None, Some(7u8)],
57 [Some(8u8), Some(9u8), None, None],
58 [Some(12u8), None, None, None],
59 ]
60 .into_dyn();
61
62 // Write the data
63 array.store_array_subset(&array.subset_all(), data.clone())?;
64
65 // Read back the data
66 let data_read: ArrayD<Option<u8>> = array.retrieve_array_subset(&array.subset_all())?;
67
68 // Verify data integrity
69 assert_eq!(data, data_read);
70
71 // Display the data in a grid format
72 println!("Data grid, N marks missing (`None`=`null`) values");
73 println!(" 0 1 2 3");
74 for y in 0..4 {
75 print!("{} ", y);
76 for x in 0..4 {
77 match data_read[[y, x]] {
78 Some(value) => print!("{:2} ", value),
79 None => print!(" N "),
80 }
81 }
82 println!();
83 }
84
85 // Print the raw bytes in all chunks
86 println!("Raw bytes in all chunks:");
87 let chunk_grid_shape = array.chunk_grid_shape();
88 for chunk_y in 0..chunk_grid_shape[0] {
89 for chunk_x in 0..chunk_grid_shape[1] {
90 let chunk_indices = vec![chunk_y, chunk_x];
91 let chunk_key = array.chunk_key(&chunk_indices);
92 println!(" Chunk [{}, {}] (key: {}):", chunk_y, chunk_x, chunk_key);
93
94 if let Some(chunk_bytes) = store.get(&chunk_key)? {
95 println!(" Size: {} bytes", chunk_bytes.len());
96
97 if chunk_bytes.len() >= 16 {
98 // Parse first 8 bytes as mask size (little-endian u64)
99 let mask_size = u64::from_le_bytes([
100 chunk_bytes[0],
101 chunk_bytes[1],
102 chunk_bytes[2],
103 chunk_bytes[3],
104 chunk_bytes[4],
105 chunk_bytes[5],
106 chunk_bytes[6],
107 chunk_bytes[7],
108 ]) as usize;
109
110 // Parse second 8 bytes as data size (little-endian u64)
111 let data_size = u64::from_le_bytes([
112 chunk_bytes[8],
113 chunk_bytes[9],
114 chunk_bytes[10],
115 chunk_bytes[11],
116 chunk_bytes[12],
117 chunk_bytes[13],
118 chunk_bytes[14],
119 chunk_bytes[15],
120 ]) as usize;
121
122 // Display mask size header with raw bytes
123 print!(" Mask size: 0b");
124 for byte in &chunk_bytes[0..8] {
125 print!("{:08b}", byte);
126 }
127 println!(" -> {} bytes", mask_size);
128
129 // Display data size header with raw bytes
130 print!(" Data size: 0b");
131 for byte in &chunk_bytes[8..16] {
132 print!("{:08b}", byte);
133 }
134 println!(" -> {} bytes", data_size);
135
136 // Show mask and data sections separately
137 if chunk_bytes.len() >= 16 + mask_size + data_size {
138 let mask_start = 16;
139 let data_start = 16 + mask_size;
140
141 // Show mask as binary
142 if mask_size > 0 {
143 println!(" Mask (binary):");
144 print!(" ");
145 for byte in &chunk_bytes[mask_start..mask_start + mask_size] {
146 print!("0b{:08b} ", byte);
147 }
148 println!();
149 }
150
151 // Show data as binary
152 if data_size > 0 {
153 println!(" Data (binary):");
154 print!(" ");
155 for byte in &chunk_bytes[data_start..data_start + data_size] {
156 print!("0b{:08b} ", byte);
157 }
158 println!();
159 }
160 }
161 } else {
162 panic!(" Chunk too small to parse headers");
163 }
164 } else {
165 println!(" Chunk missing (fill value chunk)");
166 }
167 }
168 }
169 Ok(())
170}Sourcepub fn attributes_mut(&mut self) -> &mut Map<String, Value>
pub fn attributes_mut(&mut self) -> &mut Map<String, Value>
Return a mutable reference to the attributes.
Sourcepub fn additional_fields(
&mut self,
additional_fields: AdditionalFieldsV3,
) -> &mut Self
pub fn additional_fields( &mut self, additional_fields: AdditionalFieldsV3, ) -> &mut Self
Set the additional fields.
Set additional fields not defined in the Zarr specification.
Use this cautiously. In general, store user defined attributes using ArrayBuilder::attributes.
zarrs and other implementations are expected to error when opening an array with unsupported additional fields, unless they are a JSON object containing "must_understand": false.
Sourcepub fn dimension_names<I, D>(&mut self, dimension_names: Option<I>) -> &mut Selfwhere
I: IntoIterator<Item = D>,
D: IntoDimensionName,
pub fn dimension_names<I, D>(&mut self, dimension_names: Option<I>) -> &mut Selfwhere
I: IntoIterator<Item = D>,
D: IntoDimensionName,
Set the dimension names.
If left unmodified, all dimension names are “unnamed”.
Examples found in repository?
11fn main() -> Result<(), Box<dyn std::error::Error>> {
12 // Create an in-memory store
13 // let store = Arc::new(zarrs::filesystem::FilesystemStore::new(
14 // "zarrs/tests/data/v3/array_optional_nested.zarr",
15 // )?);
16 let store = Arc::new(zarrs::storage::store::MemoryStore::new());
17
18 // Build the codec chains for the optional codec
19 let array = ArrayBuilder::new(
20 vec![4, 4], // 4x4 array
21 vec![2, 2], // 2x2 chunks
22 data_type::uint8().to_optional().to_optional(), // Optional optional uint8 => Option<Option<u8>>
23 FillValue::new_optional_null().into_optional(), // Fill value => Some(None)
24 )
25 .dimension_names(["y", "x"].into())
26 .attributes(
27 serde_json::json!({
28 "description": r#"A 4x4 array of optional optional uint8 values with some missing data.
29The fill value is null on the inner optional layer, i.e. Some(None).
30N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values:
31 N SN 2 3
32 N 5 N 7
33 SN SN N N
34 SN SN N N"#,
35 })
36 .as_object()
37 .unwrap()
38 .clone(),
39 )
40 .build(store.clone(), "/array")?;
41 array.store_metadata_opt(
42 &zarrs::array::ArrayMetadataOptions::default().with_include_zarrs_metadata(false),
43 )?;
44
45 println!("Array metadata:\n{}", array.metadata().to_string_pretty());
46
47 // Create some data with missing values
48 let data = ndarray::array![
49 [None, Some(None), Some(Some(2u8)), Some(Some(3u8))],
50 [None, Some(Some(5u8)), None, Some(Some(7u8))],
51 [Some(None), Some(None), None, None],
52 [Some(None), Some(None), None, None],
53 ]
54 .into_dyn();
55
56 // Write the data
57 array.store_array_subset(&array.subset_all(), data.clone())?;
58 println!("Data written to array.");
59
60 // Read back the data
61 let data_read: ArrayD<Option<Option<u8>>> = array.retrieve_array_subset(&array.subset_all())?;
62
63 // Verify data integrity
64 assert_eq!(data, data_read);
65
66 // Display the data in a grid format
67 println!(
68 "Data grid. N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values"
69 );
70 println!(" 0 1 2 3");
71 for y in 0..4 {
72 print!("{} ", y);
73 for x in 0..4 {
74 match data_read[[y, x]] {
75 Some(Some(value)) => print!("{:3} ", value),
76 Some(None) => print!(" SN "),
77 None => print!(" N "),
78 }
79 }
80 println!();
81 }
82 Ok(())
83}More examples
8fn array_write_read() -> Result<(), Box<dyn std::error::Error>> {
9 use std::sync::Arc;
10
11 use zarrs::array::{ArrayBytes, data_type};
12 use zarrs::storage::store;
13
14 // Create a store
15 // let path = tempfile::TempDir::new()?;
16 // let mut store: ReadableWritableListableStorage =
17 // Arc::new(zarrs::filesystem::FilesystemStore::new(path.path())?);
18 // let mut store: ReadableWritableListableStorage = Arc::new(
19 // zarrs::filesystem::FilesystemStore::new("zarrs/tests/data/array_write_read.zarr")?,
20 // );
21 let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new());
22 if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
23 && arg1 == "--usage-log"
24 {
25 let log_writer = Arc::new(std::sync::Mutex::new(
26 // std::io::BufWriter::new(
27 std::io::stdout(),
28 // )
29 ));
30 store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
31 chrono::Utc::now().format("[%T%.3f] ").to_string()
32 }));
33 }
34
35 // Create the root group
36 zarrs::group::GroupBuilder::new()
37 .build(store.clone(), "/")?
38 .store_metadata()?;
39
40 // Create a group with attributes
41 let group_path = "/group";
42 let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
43 group
44 .attributes_mut()
45 .insert("foo".into(), serde_json::Value::String("bar".into()));
46 group.store_metadata()?;
47
48 println!(
49 "The group metadata is:\n{}\n",
50 group.metadata().to_string_pretty()
51 );
52
53 // Create an array
54 let array_path = "/group/array";
55 let array = zarrs::array::ArrayBuilder::new(
56 vec![4, 4], // array shape
57 vec![2, 2], // regular chunk shape
58 data_type::string(),
59 "_",
60 )
61 // .bytes_to_bytes_codecs(vec![]) // uncompressed
62 .dimension_names(["y", "x"].into())
63 // .storage_transformers(vec![].into())
64 .build(store.clone(), array_path)?;
65
66 // Write array metadata to store
67 array.store_metadata()?;
68
69 println!(
70 "The array metadata is:\n{}\n",
71 array.metadata().to_string_pretty()
72 );
73
74 // Write some chunks
75 array.store_chunk(
76 &[0, 0],
77 ArrayD::<&str>::from_shape_vec(vec![2, 2], vec!["a", "bb", "ccc", "dddd"]).unwrap(),
78 )?;
79 array.store_chunk(
80 &[0, 1],
81 ArrayD::<&str>::from_shape_vec(vec![2, 2], vec!["4444", "333", "22", "1"]).unwrap(),
82 )?;
83 let subset_all = array.subset_all();
84 let data_all: ArrayD<String> = array.retrieve_array_subset(&subset_all)?;
85 println!("store_chunk [0, 0] and [0, 1]:\n{data_all}\n");
86
87 // Write a subset spanning multiple chunks, including updating chunks already written
88 let ndarray_subset: Array2<&str> = array![["!", "@@"], ["###", "$$$$"]];
89 array.store_array_subset(&[1..3, 1..3], ndarray_subset)?;
90 let data_all: ArrayD<String> = array.retrieve_array_subset(&subset_all)?;
91 println!("store_array_subset [1..3, 1..3]:\nndarray::ArrayD<String>\n{data_all}");
92
93 // Retrieve bytes directly, convert into a single string allocation, create a &str ndarray
94 // TODO: Add a convenience function for this?
95 let data_all: ArrayBytes = array.retrieve_array_subset(&subset_all)?;
96 let (bytes, offsets) = data_all.into_variable()?.into_parts();
97 let string = String::from_utf8(bytes.into_owned())?;
98 let elements = offsets
99 .iter()
100 .tuple_windows()
101 .map(|(&curr, &next)| &string[curr..next])
102 .collect::<Vec<&str>>();
103 let ndarray = ArrayD::<&str>::from_shape_vec(subset_all.shape_usize(), elements)?;
104 println!("ndarray::ArrayD<&str>:\n{ndarray}");
105
106 Ok(())
107}10fn rectilinear_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
11 use rayon::prelude::{IntoParallelIterator, ParallelIterator};
12 use zarrs::array::{ArraySubset, ZARR_NAN_F32, codec, data_type};
13 use zarrs::node::Node;
14 use zarrs::storage::store;
15
16 // Create a store
17 // let path = tempfile::TempDir::new()?;
18 // let mut store: ReadableWritableListableStorage =
19 // Arc::new(zarrs::filesystem::FilesystemStore::new(path.path())?);
20 let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new());
21 if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
22 && arg1 == "--usage-log"
23 {
24 let log_writer = Arc::new(std::sync::Mutex::new(
25 // std::io::BufWriter::new(
26 std::io::stdout(),
27 // )
28 ));
29 store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
30 chrono::Utc::now().format("[%T%.3f] ").to_string()
31 }));
32 }
33
34 // Create the root group
35 zarrs::group::GroupBuilder::new()
36 .build(store.clone(), "/")?
37 .store_metadata()?;
38
39 // Create a group with attributes
40 let group_path = "/group";
41 let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
42 group
43 .attributes_mut()
44 .insert("foo".into(), serde_json::Value::String("bar".into()));
45 group.store_metadata()?;
46
47 println!(
48 "The group metadata is:\n{}\n",
49 group.metadata().to_string_pretty()
50 );
51
52 // Create an array
53 let array_path = "/group/array";
54 let array = zarrs::array::ArrayBuilder::new(
55 vec![8, 8], // array shape
56 MetadataV3::new_with_configuration(
57 "rectilinear",
58 RectilinearChunkGridConfiguration::Inline {
59 chunk_shapes: vec![
60 // Varying: chunk sizes [1, 1, 1, 3, 2] (run-length encoded as [[1,3], 3, 2])
61 ChunkEdgeLengths::Varying(serde_json::from_str("[[1,3], 3, 2]").unwrap()),
62 // Scalar: regular 4-element chunks
63 ChunkEdgeLengths::Scalar(NonZeroU64::new(4).unwrap()),
64 ],
65 },
66 ),
67 data_type::float32(),
68 ZARR_NAN_F32,
69 )
70 .bytes_to_bytes_codecs(vec![
71 #[cfg(feature = "gzip")]
72 Arc::new(codec::GzipCodec::new(5)?),
73 ])
74 .dimension_names(["y", "x"].into())
75 // .storage_transformers(vec![].into())
76 .build(store.clone(), array_path)?;
77
78 // Write array metadata to store
79 array.store_metadata()?;
80
81 // Write some chunks (in parallel)
82 (0..4).into_par_iter().try_for_each(|i| {
83 let chunk_grid = array.chunk_grid();
84 let chunk_indices = vec![i, 0];
85 if let Some(chunk_shape) = chunk_grid.chunk_shape(&chunk_indices)? {
86 let chunk_array = ndarray::ArrayD::<f32>::from_elem(
87 chunk_shape
88 .iter()
89 .map(|u| u.get() as usize)
90 .collect::<Vec<_>>(),
91 i as f32,
92 );
93 array.store_chunk(&chunk_indices, chunk_array)
94 } else {
95 Err(zarrs::array::ArrayError::InvalidChunkGridIndicesError(
96 chunk_indices.to_vec(),
97 ))
98 }
99 })?;
100
101 println!(
102 "The array metadata is:\n{}\n",
103 array.metadata().to_string_pretty()
104 );
105
106 // Write a subset spanning multiple chunks, including updating chunks already written
107 array.store_array_subset(
108 &[3..6, 3..6], // start
109 ndarray::ArrayD::<f32>::from_shape_vec(
110 vec![3, 3],
111 vec![0.1f32, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9],
112 )?,
113 )?;
114
115 // Store elements directly, in this case set the 7th column to 123.0
116 array.store_array_subset(&[0..8, 6..7], &[123.0f32; 8])?;
117
118 // Store elements directly in a chunk, in this case set the last row of the bottom right chunk
119 array.store_chunk_subset(
120 // chunk indices
121 &[3, 1],
122 // subset within chunk
123 &[1..2, 0..4],
124 &[-4.0f32; 4],
125 )?;
126
127 // Read the whole array
128 let data_all: ndarray::ArrayD<f32> = array.retrieve_array_subset(&array.subset_all())?;
129 println!("The whole array is:\n{data_all}\n");
130
131 // Read a chunk back from the store
132 let chunk_indices = vec![1, 0];
133 let data_chunk: ndarray::ArrayD<f32> = array.retrieve_chunk(&chunk_indices)?;
134 println!("Chunk [1,0] is:\n{data_chunk}\n");
135
136 // Read the central 4x2 subset of the array
137 let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
138 let data_4x2: ndarray::ArrayD<f32> = array.retrieve_array_subset(&subset_4x2)?;
139 println!("The middle 4x2 subset is:\n{data_4x2}\n");
140
141 // Show the hierarchy
142 let node = Node::open(&store, "/").unwrap();
143 let tree = node.hierarchy_tree();
144 println!("The Zarr hierarchy tree is:\n{tree}");
145
146 Ok(())
147}8fn array_write_read() -> Result<(), Box<dyn std::error::Error>> {
9 use std::sync::Arc;
10
11 use zarrs::array::{ArraySubset, ZARR_NAN_F32, data_type};
12 use zarrs::node::Node;
13 use zarrs::storage::store;
14
15 // Create a store
16 // let path = tempfile::TempDir::new()?;
17 // let mut store: ReadableWritableListableStorage =
18 // Arc::new(zarrs::filesystem::FilesystemStore::new(path.path())?);
19 // let mut store: ReadableWritableListableStorage = Arc::new(
20 // zarrs::filesystem::FilesystemStore::new("zarrs/tests/data/array_write_read.zarr")?,
21 // );
22 let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new());
23 if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
24 && arg1 == "--usage-log"
25 {
26 let log_writer = Arc::new(std::sync::Mutex::new(
27 // std::io::BufWriter::new(
28 std::io::stdout(),
29 // )
30 ));
31 store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
32 chrono::Utc::now().format("[%T%.3f] ").to_string()
33 }));
34 }
35
36 // Create the root group
37 zarrs::group::GroupBuilder::new()
38 .build(store.clone(), "/")?
39 .store_metadata()?;
40
41 // Create a group with attributes
42 let group_path = "/group";
43 let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
44 group
45 .attributes_mut()
46 .insert("foo".into(), serde_json::Value::String("bar".into()));
47 group.store_metadata()?;
48
49 println!(
50 "The group metadata is:\n{}\n",
51 group.metadata().to_string_pretty()
52 );
53
54 // Create an array
55 let array_path = "/group/array";
56 let array = zarrs::array::ArrayBuilder::new(
57 vec![8, 8], // array shape
58 vec![4, 4], // regular chunk shape
59 data_type::float32(),
60 ZARR_NAN_F32,
61 )
62 // .bytes_to_bytes_codecs(vec![]) // uncompressed
63 .dimension_names(["y", "x"].into())
64 // .storage_transformers(vec![].into())
65 .build(store.clone(), array_path)?;
66
67 // Write array metadata to store
68 array.store_metadata()?;
69
70 println!(
71 "The array metadata is:\n{}\n",
72 array.metadata().to_string_pretty()
73 );
74
75 // Write some chunks
76 (0..2).into_par_iter().try_for_each(|i| {
77 let chunk_indices: Vec<u64> = vec![0, i];
78 let chunk_subset = array.chunk_grid().subset(&chunk_indices)?.ok_or_else(|| {
79 zarrs::array::ArrayError::InvalidChunkGridIndicesError(chunk_indices.to_vec())
80 })?;
81 array.store_chunk(
82 &chunk_indices,
83 vec![i as f32 * 0.1; chunk_subset.num_elements() as usize],
84 )
85 })?;
86
87 let subset_all = array.subset_all();
88 let data_all: ArrayD<f32> = array.retrieve_array_subset(&subset_all)?;
89 println!("store_chunk [0, 0] and [0, 1]:\n{data_all:+4.1}\n");
90
91 // Store multiple chunks
92 array.store_chunks(
93 &[1..2, 0..2],
94 &[
95 //
96 1.0f32, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1, 1.0, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1,
97 //
98 1.0, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1, 1.0, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1,
99 ],
100 )?;
101 let data_all: ArrayD<f32> = array.retrieve_array_subset(&subset_all)?;
102 println!("store_chunks [1..2, 0..2]:\n{data_all:+4.1}\n");
103
104 // Write a subset spanning multiple chunks, including updating chunks already written
105 array.store_array_subset(
106 &[3..6, 3..6],
107 &[-3.3f32, -3.4, -3.5, -4.3, -4.4, -4.5, -5.3, -5.4, -5.5],
108 )?;
109 let data_all: ArrayD<f32> = array.retrieve_array_subset(&subset_all)?;
110 println!("store_array_subset [3..6, 3..6]:\n{data_all:+4.1}\n");
111
112 // Store array subset
113 array.store_array_subset(
114 &[0..8, 6..7],
115 &[-0.6f32, -1.6, -2.6, -3.6, -4.6, -5.6, -6.6, -7.6],
116 )?;
117 let data_all: ArrayD<f32> = array.retrieve_array_subset(&subset_all)?;
118 println!("store_array_subset [0..8, 6..7]:\n{data_all:+4.1}\n");
119
120 // Store chunk subset
121 array.store_chunk_subset(
122 // chunk indices
123 &[1, 1],
124 // subset within chunk
125 &[3..4, 0..4],
126 &[-7.4f32, -7.5, -7.6, -7.7],
127 )?;
128 let data_all: ArrayD<f32> = array.retrieve_array_subset(&subset_all)?;
129 println!("store_chunk_subset [3..4, 0..4] of chunk [1, 1]:\n{data_all:+4.1}\n");
130
131 // Erase a chunk
132 array.erase_chunk(&[0, 0])?;
133 let data_all: ArrayD<f32> = array.retrieve_array_subset(&subset_all)?;
134 println!("erase_chunk [0, 0]:\n{data_all:+4.1}\n");
135
136 // Read a chunk
137 let chunk_indices = vec![0, 1];
138 let data_chunk: ArrayD<f32> = array.retrieve_chunk(&chunk_indices)?;
139 println!("retrieve_chunk [0, 1]:\n{data_chunk:+4.1}\n");
140
141 // Read chunks
142 let chunks = ArraySubset::new_with_ranges(&[0..2, 1..2]);
143 let data_chunks: ArrayD<f32> = array.retrieve_chunks(&chunks)?;
144 println!("retrieve_chunks [0..2, 1..2]:\n{data_chunks:+4.1}\n");
145
146 // Retrieve an array subset
147 let subset = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
148 let data_subset: ArrayD<f32> = array.retrieve_array_subset(&subset)?;
149 println!("retrieve_array_subset [2..6, 3..5]:\n{data_subset:+4.1}\n");
150
151 // Show the hierarchy
152 let node = Node::open(&store, "/").unwrap();
153 let tree = node.hierarchy_tree();
154 println!("hierarchy_tree:\n{}", tree);
155
156 Ok(())
157}10fn sharded_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
11 use std::sync::Arc;
12
13 use rayon::prelude::{IntoParallelIterator, ParallelIterator};
14 use zarrs::array::{ArraySubset, codec, data_type};
15 use zarrs::node::Node;
16 use zarrs::storage::store;
17
18 // Create a store
19 // let path = tempfile::TempDir::new()?;
20 // let mut store: ReadableWritableListableStorage =
21 // Arc::new(zarrs::filesystem::FilesystemStore::new(path.path())?);
22 // let mut store: ReadableWritableListableStorage = Arc::new(
23 // zarrs::filesystem::FilesystemStore::new("zarrs/tests/data/sharded_array_write_read.zarr")?,
24 // );
25 let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new());
26 if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
27 && arg1 == "--usage-log"
28 {
29 let log_writer = Arc::new(std::sync::Mutex::new(
30 // std::io::BufWriter::new(
31 std::io::stdout(),
32 // )
33 ));
34 store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
35 chrono::Utc::now().format("[%T%.3f] ").to_string()
36 }));
37 }
38
39 // Create the root group
40 zarrs::group::GroupBuilder::new()
41 .build(store.clone(), "/")?
42 .store_metadata()?;
43
44 // Create a group with attributes
45 let group_path = "/group";
46 let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
47 group
48 .attributes_mut()
49 .insert("foo".into(), serde_json::Value::String("bar".into()));
50 group.store_metadata()?;
51
52 // Create an array
53 let array_path = "/group/array";
54 let subchunk_shape = vec![4, 4];
55 let array = zarrs::array::ArrayBuilder::new(
56 vec![8, 8], // array shape
57 vec![4, 8], // chunk (shard) shape
58 data_type::uint16(),
59 0u16,
60 )
61 .subchunk_shape(subchunk_shape.clone())
62 .bytes_to_bytes_codecs(vec![
63 #[cfg(feature = "gzip")]
64 Arc::new(codec::GzipCodec::new(5)?),
65 ])
66 .dimension_names(["y", "x"].into())
67 // .storage_transformers(vec![].into())
68 .build(store.clone(), array_path)?;
69
70 // Write array metadata to store
71 array.store_metadata()?;
72
73 // The array metadata is
74 println!(
75 "The array metadata is:\n{}\n",
76 array.metadata().to_string_pretty()
77 );
78
79 // Use default codec options (concurrency etc)
80 let options = CodecOptions::default();
81
82 // Write some shards (in parallel)
83 (0..2).into_par_iter().try_for_each(|s| {
84 let chunk_grid = array.chunk_grid();
85 let chunk_indices = vec![s, 0];
86 if let Some(chunk_shape) = chunk_grid.chunk_shape(&chunk_indices)? {
87 let chunk_array = ndarray::ArrayD::<u16>::from_shape_fn(
88 chunk_shape
89 .iter()
90 .map(|u| u.get() as usize)
91 .collect::<Vec<_>>(),
92 |ij| {
93 (s * chunk_shape[0].get() * chunk_shape[1].get()
94 + ij[0] as u64 * chunk_shape[1].get()
95 + ij[1] as u64) as u16
96 },
97 );
98 array.store_chunk(&chunk_indices, chunk_array)
99 } else {
100 Err(zarrs::array::ArrayError::InvalidChunkGridIndicesError(
101 chunk_indices.to_vec(),
102 ))
103 }
104 })?;
105
106 // Read the whole array
107 let data_all: ArrayD<u16> = array.retrieve_array_subset(&array.subset_all())?;
108 println!("The whole array is:\n{data_all}\n");
109
110 // Read a shard back from the store
111 let shard_indices = vec![1, 0];
112 let data_shard: ArrayD<u16> = array.retrieve_chunk(&shard_indices)?;
113 println!("Shard [1,0] is:\n{data_shard}\n");
114
115 // Read a subchunk from the store
116 let subset_chunk_1_0 = ArraySubset::new_with_ranges(&[4..8, 0..4]);
117 let data_chunk: ArrayD<u16> = array.retrieve_array_subset(&subset_chunk_1_0)?;
118 println!("Chunk [1,0] is:\n{data_chunk}\n");
119
120 // Read the central 4x2 subset of the array
121 let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
122 let data_4x2: ArrayD<u16> = array.retrieve_array_subset(&subset_4x2)?;
123 println!("The middle 4x2 subset is:\n{data_4x2}\n");
124
125 // Decode subchunks
126 // In some cases, it might be preferable to decode subchunks in a shard directly.
127 // If using the partial decoder, then the shard index will only be read once from the store.
128 let partial_decoder = array.partial_decoder(&[0, 0])?;
129 println!("Decoded subchunks:");
130 for subchunk_subset in [
131 ArraySubset::new_with_start_shape(vec![0, 0], subchunk_shape.clone())?,
132 ArraySubset::new_with_start_shape(vec![0, 4], subchunk_shape.clone())?,
133 ] {
134 println!("{subchunk_subset}");
135 let decoded_subchunk_bytes = partial_decoder.partial_decode(&subchunk_subset, &options)?;
136 let ndarray = bytes_to_ndarray::<u16>(
137 &subchunk_shape,
138 decoded_subchunk_bytes.into_fixed()?.into_owned(),
139 )?;
140 println!("{ndarray}\n");
141 }
142
143 // Show the hierarchy
144 let node = Node::open(&store, "/").unwrap();
145 let tree = node.hierarchy_tree();
146 println!("The Zarr hierarchy tree is:\n{}", tree);
147
148 println!(
149 "The keys in the store are:\n[{}]",
150 store.list().unwrap_or_default().iter().format(", ")
151 );
152
153 Ok(())
154}18fn main() -> Result<(), Box<dyn std::error::Error>> {
19 // Create an in-memory store
20 // let store = Arc::new(zarrs::filesystem::FilesystemStore::new(
21 // "zarrs/tests/data/v3/array_optional.zarr",
22 // )?);
23 let store = Arc::new(zarrs::storage::store::MemoryStore::new());
24
25 // Build the codec chains for the optional codec
26 let array = ArrayBuilder::new(
27 vec![4, 4], // 4x4 array
28 vec![2, 2], // 2x2 chunks
29 data_type::uint8().to_optional(), // Optional uint8
30 FillValue::new_optional_null(), // Null fill value: [0]
31 )
32 .dimension_names(["y", "x"].into())
33 .attributes(
34 serde_json::json!({
35 "description": r#"A 4x4 array of optional uint8 values with some missing data.
36N marks missing (`None`=`null`) values:
37 0 N 2 3
38 N 5 N 7
39 8 9 N N
4012 N N N"#,
41 })
42 .as_object()
43 .unwrap()
44 .clone(),
45 )
46 .build(store.clone(), "/array")?;
47 array.store_metadata_opt(
48 &zarrs::array::ArrayMetadataOptions::default().with_include_zarrs_metadata(false),
49 )?;
50
51 println!("Array metadata:\n{}", array.metadata().to_string_pretty());
52
53 // Create some data with missing values
54 let data = ndarray::array![
55 [Some(0u8), None, Some(2u8), Some(3u8)],
56 [None, Some(5u8), None, Some(7u8)],
57 [Some(8u8), Some(9u8), None, None],
58 [Some(12u8), None, None, None],
59 ]
60 .into_dyn();
61
62 // Write the data
63 array.store_array_subset(&array.subset_all(), data.clone())?;
64
65 // Read back the data
66 let data_read: ArrayD<Option<u8>> = array.retrieve_array_subset(&array.subset_all())?;
67
68 // Verify data integrity
69 assert_eq!(data, data_read);
70
71 // Display the data in a grid format
72 println!("Data grid, N marks missing (`None`=`null`) values");
73 println!(" 0 1 2 3");
74 for y in 0..4 {
75 print!("{} ", y);
76 for x in 0..4 {
77 match data_read[[y, x]] {
78 Some(value) => print!("{:2} ", value),
79 None => print!(" N "),
80 }
81 }
82 println!();
83 }
84
85 // Print the raw bytes in all chunks
86 println!("Raw bytes in all chunks:");
87 let chunk_grid_shape = array.chunk_grid_shape();
88 for chunk_y in 0..chunk_grid_shape[0] {
89 for chunk_x in 0..chunk_grid_shape[1] {
90 let chunk_indices = vec![chunk_y, chunk_x];
91 let chunk_key = array.chunk_key(&chunk_indices);
92 println!(" Chunk [{}, {}] (key: {}):", chunk_y, chunk_x, chunk_key);
93
94 if let Some(chunk_bytes) = store.get(&chunk_key)? {
95 println!(" Size: {} bytes", chunk_bytes.len());
96
97 if chunk_bytes.len() >= 16 {
98 // Parse first 8 bytes as mask size (little-endian u64)
99 let mask_size = u64::from_le_bytes([
100 chunk_bytes[0],
101 chunk_bytes[1],
102 chunk_bytes[2],
103 chunk_bytes[3],
104 chunk_bytes[4],
105 chunk_bytes[5],
106 chunk_bytes[6],
107 chunk_bytes[7],
108 ]) as usize;
109
110 // Parse second 8 bytes as data size (little-endian u64)
111 let data_size = u64::from_le_bytes([
112 chunk_bytes[8],
113 chunk_bytes[9],
114 chunk_bytes[10],
115 chunk_bytes[11],
116 chunk_bytes[12],
117 chunk_bytes[13],
118 chunk_bytes[14],
119 chunk_bytes[15],
120 ]) as usize;
121
122 // Display mask size header with raw bytes
123 print!(" Mask size: 0b");
124 for byte in &chunk_bytes[0..8] {
125 print!("{:08b}", byte);
126 }
127 println!(" -> {} bytes", mask_size);
128
129 // Display data size header with raw bytes
130 print!(" Data size: 0b");
131 for byte in &chunk_bytes[8..16] {
132 print!("{:08b}", byte);
133 }
134 println!(" -> {} bytes", data_size);
135
136 // Show mask and data sections separately
137 if chunk_bytes.len() >= 16 + mask_size + data_size {
138 let mask_start = 16;
139 let data_start = 16 + mask_size;
140
141 // Show mask as binary
142 if mask_size > 0 {
143 println!(" Mask (binary):");
144 print!(" ");
145 for byte in &chunk_bytes[mask_start..mask_start + mask_size] {
146 print!("0b{:08b} ", byte);
147 }
148 println!();
149 }
150
151 // Show data as binary
152 if data_size > 0 {
153 println!(" Data (binary):");
154 print!(" ");
155 for byte in &chunk_bytes[data_start..data_start + data_size] {
156 print!("0b{:08b} ", byte);
157 }
158 println!();
159 }
160 }
161 } else {
162 panic!(" Chunk too small to parse headers");
163 }
164 } else {
165 println!(" Chunk missing (fill value chunk)");
166 }
167 }
168 }
169 Ok(())
170}Sourcepub fn storage_transformers(
&mut self,
storage_transformers: StorageTransformerChain,
) -> &mut Self
pub fn storage_transformers( &mut self, storage_transformers: StorageTransformerChain, ) -> &mut Self
Set the storage transformers.
If left unmodified, there are no storage transformers.
Sourcepub fn build_metadata(&self) -> Result<ArrayMetadataV3, ArrayCreateError>
pub fn build_metadata(&self) -> Result<ArrayMetadataV3, ArrayCreateError>
Get the metadata of an array that would be created with the current builder state.
§Errors
Returns an ArrayCreateError if this metadata is invalid/unsupported by zarrs.
Sourcepub fn build<TStorage: ?Sized>(
&self,
storage: Arc<TStorage>,
path: &str,
) -> Result<Array<TStorage>, ArrayCreateError>
pub fn build<TStorage: ?Sized>( &self, storage: Arc<TStorage>, path: &str, ) -> Result<Array<TStorage>, ArrayCreateError>
Build into an Array.
§Errors
Returns ArrayCreateError if there is an error creating the array.
This can be due to a storage error, an invalid path, or a problem with array configuration.
Examples found in repository?
157fn main() {
158 let store = std::sync::Arc::new(MemoryStore::default());
159 let array_path = "/array";
160 let array = ArrayBuilder::new(
161 vec![4, 1], // array shape
162 vec![3, 1], // regular chunk shape
163 Arc::new(CustomDataTypeVariableSize),
164 [],
165 )
166 .array_to_array_codecs(vec![
167 #[cfg(feature = "transpose")]
168 Arc::new(zarrs::array::codec::TransposeCodec::new(
169 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
170 )),
171 ])
172 .bytes_to_bytes_codecs(vec![
173 #[cfg(feature = "gzip")]
174 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
175 #[cfg(feature = "crc32c")]
176 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
177 ])
178 // .storage_transformers(vec![].into())
179 .build(store, array_path)
180 .unwrap();
181 println!("{}", array.metadata().to_string_pretty());
182
183 let data = [
184 CustomDataTypeVariableSizeElement::from(Some(1.0)),
185 CustomDataTypeVariableSizeElement::from(None),
186 CustomDataTypeVariableSizeElement::from(Some(3.0)),
187 ];
188 array.store_chunk(&[0, 0], &data).unwrap();
189
190 let data: Vec<CustomDataTypeVariableSizeElement> =
191 array.retrieve_array_subset(&array.subset_all()).unwrap();
192
193 assert_eq!(data[0], CustomDataTypeVariableSizeElement::from(Some(1.0)));
194 assert_eq!(data[1], CustomDataTypeVariableSizeElement::from(None));
195 assert_eq!(data[2], CustomDataTypeVariableSizeElement::from(Some(3.0)));
196 assert_eq!(data[3], CustomDataTypeVariableSizeElement::from(None));
197
198 println!("{data:#?}");
199}More examples
280fn main() {
281 let store = std::sync::Arc::new(MemoryStore::default());
282 let array_path = "/array";
283 let fill_value = CustomDataTypeFixedSizeElement { x: 1, y: 2.3 };
284 let array = ArrayBuilder::new(
285 vec![4, 1], // array shape
286 vec![2, 1], // regular chunk shape
287 Arc::new(CustomDataTypeFixedSize),
288 FillValue::new(fill_value.to_ne_bytes().to_vec()),
289 )
290 .array_to_array_codecs(vec![
291 #[cfg(feature = "transpose")]
292 Arc::new(zarrs::array::codec::TransposeCodec::new(
293 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
294 )),
295 ])
296 .bytes_to_bytes_codecs(vec![
297 #[cfg(feature = "gzip")]
298 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
299 #[cfg(feature = "crc32c")]
300 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
301 ])
302 // .storage_transformers(vec![].into())
303 .build(store, array_path)
304 .unwrap();
305 println!("{}", array.metadata().to_string_pretty());
306
307 let data = [
308 CustomDataTypeFixedSizeElement { x: 3, y: 4.5 },
309 CustomDataTypeFixedSizeElement { x: 6, y: 7.8 },
310 ];
311 array.store_chunk(&[0, 0], &data).unwrap();
312
313 let data: Vec<CustomDataTypeFixedSizeElement> =
314 array.retrieve_array_subset(&array.subset_all()).unwrap();
315
316 assert_eq!(data[0], CustomDataTypeFixedSizeElement { x: 3, y: 4.5 });
317 assert_eq!(data[1], CustomDataTypeFixedSizeElement { x: 6, y: 7.8 });
318 assert_eq!(data[2], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
319 assert_eq!(data[3], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
320
321 println!("{data:#?}");
322}192fn main() {
193 let store = std::sync::Arc::new(MemoryStore::default());
194 let array_path = "/array";
195 let fill_value = CustomDataTypeUInt12Element::try_from(15).unwrap();
196 let array = ArrayBuilder::new(
197 vec![4096, 1], // array shape
198 vec![5, 1], // regular chunk shape
199 Arc::new(CustomDataTypeUInt12),
200 FillValue::new(fill_value.into_le_bytes().to_vec()),
201 )
202 .array_to_array_codecs(vec![
203 #[cfg(feature = "transpose")]
204 Arc::new(zarrs::array::codec::TransposeCodec::new(
205 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
206 )),
207 ])
208 .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
209 .bytes_to_bytes_codecs(vec![
210 #[cfg(feature = "gzip")]
211 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
212 #[cfg(feature = "crc32c")]
213 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
214 ])
215 // .storage_transformers(vec![].into())
216 .build(store, array_path)
217 .unwrap();
218 println!("{}", array.metadata().to_string_pretty());
219
220 let data: Vec<CustomDataTypeUInt12Element> = (0..4096)
221 .map(|i| CustomDataTypeUInt12Element::try_from(i).unwrap())
222 .collect();
223
224 array
225 .store_array_subset(&array.subset_all(), &data)
226 .unwrap();
227
228 let mut data: Vec<CustomDataTypeUInt12Element> =
229 array.retrieve_array_subset(&array.subset_all()).unwrap();
230
231 for (i, d) in data.drain(0..4096).enumerate() {
232 let element = CustomDataTypeUInt12Element::try_from(i as u64).unwrap();
233 assert_eq!(d, element);
234 let element_pd: Vec<CustomDataTypeUInt12Element> = array
235 .retrieve_array_subset(&[(i as u64)..i as u64 + 1, 0..1])
236 .unwrap();
237 assert_eq!(element_pd[0], element);
238 }
239}203fn main() {
204 let store = std::sync::Arc::new(MemoryStore::default());
205 let array_path = "/array";
206 let fill_value = CustomDataTypeFloat8e3m4Element::from(1.23);
207 let array = ArrayBuilder::new(
208 vec![6, 1], // array shape
209 vec![5, 1], // regular chunk shape
210 Arc::new(CustomDataTypeFloat8e3m4),
211 FillValue::new(fill_value.into_ne_bytes().to_vec()),
212 )
213 .array_to_array_codecs(vec![
214 #[cfg(feature = "transpose")]
215 Arc::new(zarrs::array::codec::TransposeCodec::new(
216 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
217 )),
218 ])
219 .bytes_to_bytes_codecs(vec![
220 #[cfg(feature = "gzip")]
221 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
222 #[cfg(feature = "crc32c")]
223 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
224 ])
225 // .storage_transformers(vec![].into())
226 .build(store, array_path)
227 .unwrap();
228 println!("{}", array.metadata().to_string_pretty());
229
230 let data = [
231 CustomDataTypeFloat8e3m4Element::from(2.34),
232 CustomDataTypeFloat8e3m4Element::from(3.45),
233 CustomDataTypeFloat8e3m4Element::from(f32::INFINITY),
234 CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY),
235 CustomDataTypeFloat8e3m4Element::from(f32::NAN),
236 ];
237 array.store_chunk(&[0, 0], &data).unwrap();
238
239 let data: Vec<CustomDataTypeFloat8e3m4Element> =
240 array.retrieve_array_subset(&array.subset_all()).unwrap();
241
242 for f in &data {
243 println!(
244 "float8_e3m4: {:08b} f32: {}",
245 f.into_ne_bytes()[0],
246 f.into_f32()
247 );
248 }
249
250 assert_eq!(data[0], CustomDataTypeFloat8e3m4Element::from(2.34));
251 assert_eq!(data[1], CustomDataTypeFloat8e3m4Element::from(3.45));
252 assert_eq!(
253 data[2],
254 CustomDataTypeFloat8e3m4Element::from(f32::INFINITY)
255 );
256 assert_eq!(
257 data[3],
258 CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY)
259 );
260 assert_eq!(data[4], CustomDataTypeFloat8e3m4Element::from(f32::NAN));
261 assert_eq!(data[5], CustomDataTypeFloat8e3m4Element::from(1.23));
262}194fn main() {
195 let store = std::sync::Arc::new(MemoryStore::default());
196 let array_path = "/array";
197 let fill_value = CustomDataTypeUInt4Element::try_from(15).unwrap();
198 let array = ArrayBuilder::new(
199 vec![6, 1], // array shape
200 vec![5, 1], // regular chunk shape
201 Arc::new(CustomDataTypeUInt4),
202 FillValue::new(fill_value.into_ne_bytes().to_vec()),
203 )
204 .array_to_array_codecs(vec![
205 #[cfg(feature = "transpose")]
206 Arc::new(zarrs::array::codec::TransposeCodec::new(
207 zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
208 )),
209 ])
210 .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
211 .bytes_to_bytes_codecs(vec![
212 #[cfg(feature = "gzip")]
213 Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
214 #[cfg(feature = "crc32c")]
215 Arc::new(zarrs::array::codec::Crc32cCodec::new()),
216 ])
217 // .storage_transformers(vec![].into())
218 .build(store, array_path)
219 .unwrap();
220 println!("{}", array.metadata().to_string_pretty());
221
222 let data = [
223 CustomDataTypeUInt4Element::try_from(1).unwrap(),
224 CustomDataTypeUInt4Element::try_from(2).unwrap(),
225 CustomDataTypeUInt4Element::try_from(3).unwrap(),
226 CustomDataTypeUInt4Element::try_from(4).unwrap(),
227 CustomDataTypeUInt4Element::try_from(5).unwrap(),
228 ];
229 array.store_chunk(&[0, 0], &data).unwrap();
230
231 let data: Vec<CustomDataTypeUInt4Element> =
232 array.retrieve_array_subset(&array.subset_all()).unwrap();
233
234 for f in &data {
235 println!("uint4: {:08b} u8: {}", f.into_u8(), f.into_u8());
236 }
237
238 assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(1).unwrap());
239 assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(2).unwrap());
240 assert_eq!(data[2], CustomDataTypeUInt4Element::try_from(3).unwrap());
241 assert_eq!(data[3], CustomDataTypeUInt4Element::try_from(4).unwrap());
242 assert_eq!(data[4], CustomDataTypeUInt4Element::try_from(5).unwrap());
243 assert_eq!(data[5], CustomDataTypeUInt4Element::try_from(15).unwrap());
244
245 let data: Vec<CustomDataTypeUInt4Element> = array.retrieve_array_subset(&[1..3, 0..1]).unwrap();
246 assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(2).unwrap());
247 assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(3).unwrap());
248}11fn main() -> Result<(), Box<dyn std::error::Error>> {
12 // Create an in-memory store
13 // let store = Arc::new(zarrs::filesystem::FilesystemStore::new(
14 // "zarrs/tests/data/v3/array_optional_nested.zarr",
15 // )?);
16 let store = Arc::new(zarrs::storage::store::MemoryStore::new());
17
18 // Build the codec chains for the optional codec
19 let array = ArrayBuilder::new(
20 vec![4, 4], // 4x4 array
21 vec![2, 2], // 2x2 chunks
22 data_type::uint8().to_optional().to_optional(), // Optional optional uint8 => Option<Option<u8>>
23 FillValue::new_optional_null().into_optional(), // Fill value => Some(None)
24 )
25 .dimension_names(["y", "x"].into())
26 .attributes(
27 serde_json::json!({
28 "description": r#"A 4x4 array of optional optional uint8 values with some missing data.
29The fill value is null on the inner optional layer, i.e. Some(None).
30N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values:
31 N SN 2 3
32 N 5 N 7
33 SN SN N N
34 SN SN N N"#,
35 })
36 .as_object()
37 .unwrap()
38 .clone(),
39 )
40 .build(store.clone(), "/array")?;
41 array.store_metadata_opt(
42 &zarrs::array::ArrayMetadataOptions::default().with_include_zarrs_metadata(false),
43 )?;
44
45 println!("Array metadata:\n{}", array.metadata().to_string_pretty());
46
47 // Create some data with missing values
48 let data = ndarray::array![
49 [None, Some(None), Some(Some(2u8)), Some(Some(3u8))],
50 [None, Some(Some(5u8)), None, Some(Some(7u8))],
51 [Some(None), Some(None), None, None],
52 [Some(None), Some(None), None, None],
53 ]
54 .into_dyn();
55
56 // Write the data
57 array.store_array_subset(&array.subset_all(), data.clone())?;
58 println!("Data written to array.");
59
60 // Read back the data
61 let data_read: ArrayD<Option<Option<u8>>> = array.retrieve_array_subset(&array.subset_all())?;
62
63 // Verify data integrity
64 assert_eq!(data, data_read);
65
66 // Display the data in a grid format
67 println!(
68 "Data grid. N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values"
69 );
70 println!(" 0 1 2 3");
71 for y in 0..4 {
72 print!("{} ", y);
73 for x in 0..4 {
74 match data_read[[y, x]] {
75 Some(Some(value)) => print!("{:3} ", value),
76 Some(None) => print!(" SN "),
77 None => print!(" N "),
78 }
79 }
80 println!();
81 }
82 Ok(())
83}Sourcepub fn build_arc<TStorage: ?Sized>(
&self,
storage: Arc<TStorage>,
path: &str,
) -> Result<Arc<Array<TStorage>>, ArrayCreateError>
pub fn build_arc<TStorage: ?Sized>( &self, storage: Arc<TStorage>, path: &str, ) -> Result<Arc<Array<TStorage>>, ArrayCreateError>
Build into an Arc<Array>.
§Errors
Returns ArrayCreateError if there is an error creating the array.
This can be due to a storage error, an invalid path, or a problem with array configuration.
Examples found in repository?
8async fn async_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
9 use std::sync::Arc;
10
11 use futures::StreamExt;
12 use zarrs::array::{ArraySubset, ZARR_NAN_F32, data_type};
13 use zarrs::node::Node;
14
15 // Create a store
16 let mut store: AsyncReadableWritableListableStorage = Arc::new(
17 zarrs_object_store::AsyncObjectStore::new(object_store::memory::InMemory::new()),
18 );
19 if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
20 && arg1 == "--usage-log"
21 {
22 let log_writer = Arc::new(std::sync::Mutex::new(
23 // std::io::BufWriter::new(
24 std::io::stdout(),
25 // )
26 ));
27 store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
28 chrono::Utc::now().format("[%T%.3f] ").to_string()
29 }));
30 }
31
32 // Create the root group
33 zarrs::group::GroupBuilder::new()
34 .build(store.clone(), "/")?
35 .async_store_metadata()
36 .await?;
37
38 // Create a group with attributes
39 let group_path = "/group";
40 let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
41 group
42 .attributes_mut()
43 .insert("foo".into(), serde_json::Value::String("bar".into()));
44 group.async_store_metadata().await?;
45
46 println!(
47 "The group metadata is:\n{}\n",
48 group.metadata().to_string_pretty()
49 );
50
51 // Create an array
52 let array_path = "/group/array";
53 let array = zarrs::array::ArrayBuilder::new(
54 vec![8, 8], // array shape
55 vec![4, 4], // regular chunk shape
56 data_type::float32(),
57 ZARR_NAN_F32,
58 )
59 // .bytes_to_bytes_codecs(vec![]) // uncompressed
60 .dimension_names(["y", "x"].into())
61 // .storage_transformers(vec![].into())
62 .build_arc(store.clone(), array_path)?;
63
64 // Write array metadata to store
65 array.async_store_metadata().await?;
66
67 println!(
68 "The array metadata is:\n{}\n",
69 array.metadata().to_string_pretty()
70 );
71
72 // Write some chunks
73 let store_chunk = |i: u64| {
74 let array = array.clone();
75 async move {
76 let chunk_indices: Vec<u64> = vec![0, i];
77 let chunk_subset = array.chunk_grid().subset(&chunk_indices)?.ok_or_else(|| {
78 zarrs::array::ArrayError::InvalidChunkGridIndicesError(chunk_indices.to_vec())
79 })?;
80 array
81 .async_store_chunk(
82 &chunk_indices,
83 vec![i as f32 * 0.1; chunk_subset.num_elements() as usize],
84 )
85 .await
86 }
87 };
88 futures::stream::iter(0..2)
89 .map(Ok)
90 .try_for_each_concurrent(None, store_chunk)
91 .await?;
92
93 let subset_all = array.subset_all();
94 let data_all: ArrayD<f32> = array.async_retrieve_array_subset(&subset_all).await?;
95 println!("async_store_chunk [0, 0] and [0, 1]:\n{data_all:+4.1}\n");
96
97 // Store multiple chunks
98 array
99 .async_store_chunks(
100 &[1..2, 0..2],
101 &[
102 //
103 1.0f32, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1, 1.0, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1,
104 //
105 1.0, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1, 1.0, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1,
106 ],
107 )
108 .await?;
109 let data_all: ArrayD<f32> = array.async_retrieve_array_subset(&subset_all).await?;
110 println!("async_store_chunks [1..2, 0..2]:\n{data_all:+4.1}\n");
111
112 // Write a subset spanning multiple chunks, including updating chunks already written
113 array
114 .async_store_array_subset(
115 &[3..6, 3..6],
116 &[-3.3, -3.4, -3.5, -4.3, -4.4, -4.5, -5.3, -5.4, -5.5],
117 )
118 .await?;
119 let data_all: ArrayD<f32> = array.async_retrieve_array_subset(&subset_all).await?;
120 println!("async_store_array_subset [3..6, 3..6]:\n{data_all:+4.1}\n");
121
122 // Store array subset
123 array
124 .async_store_array_subset(
125 &[0..8, 6..7],
126 &[-0.6f32, -1.6, -2.6, -3.6, -4.6, -5.6, -6.6, -7.6],
127 )
128 .await?;
129 let data_all: ArrayD<f32> = array.async_retrieve_array_subset(&subset_all).await?;
130 println!("async_store_array_subset [0..8, 6..7]:\n{data_all:+4.1}\n");
131
132 // Store chunk subset
133 array
134 .async_store_chunk_subset(
135 // chunk indices
136 &[1, 1],
137 // subset within chunk
138 &[3..4, 0..4],
139 &[-7.4f32, -7.5, -7.6, -7.7],
140 )
141 .await?;
142 let data_all: ArrayD<f32> = array.async_retrieve_array_subset(&subset_all).await?;
143 println!("async_store_chunk_subset [3..4, 0..4] of chunk [1, 1]:\n{data_all:+4.1}\n");
144
145 // Erase a chunk
146 array.async_erase_chunk(&[0, 0]).await?;
147 let data_all: ArrayD<f32> = array.async_retrieve_array_subset(&subset_all).await?;
148 println!("async_erase_chunk [0, 0]:\n{data_all:+4.1}\n");
149
150 // Read a chunk
151 let chunk_indices = vec![0, 1];
152 let data_chunk: ArrayD<f32> = array.async_retrieve_chunk(&chunk_indices).await?;
153 println!("async_retrieve_chunk [0, 1]:\n{data_chunk:+4.1}\n");
154
155 // Read chunks
156 let chunks = ArraySubset::new_with_ranges(&[0..2, 1..2]);
157 let data_chunks: ArrayD<f32> = array.async_retrieve_chunks(&chunks).await?;
158 println!("async_retrieve_chunks [0..2, 1..2]:\n{data_chunks:+4.1}\n");
159
160 // Retrieve an array subset
161 let subset = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
162 let data_subset: ArrayD<f32> = array.async_retrieve_array_subset(&subset).await?;
163 println!("async_retrieve_array_subset [2..6, 3..5]:\n{data_subset:+4.1}\n");
164
165 // Show the hierarchy
166 let node = Node::async_open(store, "/").await.unwrap();
167 let tree = node.hierarchy_tree();
168 println!("hierarchy_tree:\n{}", tree);
169
170 Ok(())
171}Trait Implementations§
Auto Trait Implementations§
impl Freeze for ArrayBuilder
impl Send for ArrayBuilder
impl Sync for ArrayBuilder
impl !RefUnwindSafe for ArrayBuilder
impl Unpin for ArrayBuilder
impl UnsafeUnpin for ArrayBuilder
impl !UnwindSafe for ArrayBuilder
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more