55"""Tests the schema v1 dataset_serializer public API."""
66
77import pytest
8+ from dask import array as dask_array
9+ from numpy import array as np_array
810from numpy import dtype as np_dtype
9- from numpy import nan as np_nan
1011from numpy import isnan as np_isnan
12+ from numpy import zeros as np_zeros
13+ from xarray import DataArray as xr_DataArray
14+ from zarr import zeros as zarr_zeros
1115
1216from mdio .constants import fill_value_map
1317from mdio .schemas .chunk_grid import RegularChunkGrid
@@ -158,9 +162,7 @@ def test__get_np_datatype() -> None:
158162 ]
159163
160164 for scalar_type , expected_numpy_type in scalar_type_tests :
161- variable = Variable (name = "test_var" , dimensions = [], data_type = scalar_type )
162-
163- result = _get_np_datatype (variable )
165+ result = _get_np_datatype (scalar_type )
164166 expected = np_dtype (expected_numpy_type )
165167
166168 assert result == expected
@@ -176,12 +178,7 @@ def test__get_np_datatype() -> None:
176178 StructuredField (name = "valid" , format = ScalarType .BOOL ),
177179 ]
178180 structured_multi = StructuredType (fields = multi_fields )
179-
180- variable_multi_struct = Variable (
181- name = "multi_struct_var" , dimensions = [], data_type = structured_multi
182- )
183-
184- result_multi = _get_np_datatype (variable_multi_struct )
181+ result_multi = _get_np_datatype (structured_multi )
185182 expected_multi = np_dtype (
186183 [("x" , "float64" ), ("y" , "float64" ), ("z" , "float64" ), ("id" , "int32" ), ("valid" , "bool" )]
187184 )
@@ -254,7 +251,8 @@ def test__get_fill_value() -> None:
254251 ScalarType .INT32 ,
255252 ]
256253 for scalar_type in scalar_types :
257- assert fill_value_map [scalar_type ] == _get_fill_value (scalar_type )
254+ fill_value = _get_fill_value (scalar_type )
255+ assert fill_value_map [scalar_type ] == fill_value
258256
259257 scalar_types = [
260258 ScalarType .COMPLEX64 ,
@@ -265,16 +263,23 @@ def test__get_fill_value() -> None:
265263 val = _get_fill_value (scalar_type )
266264 assert isinstance (val , complex )
267265 assert np_isnan (val .real )
268- assert np_isnan (val .imag )
266+ assert np_isnan (val .imag )
269267
270268 # Test 2: StructuredType
271269 f1 = StructuredField (name = "cdp-x" , format = ScalarType .INT32 )
272270 f2 = StructuredField (name = "cdp-y" , format = ScalarType .INT32 )
273271 f3 = StructuredField (name = "elevation" , format = ScalarType .FLOAT16 )
274272 f4 = StructuredField (name = "some_scalar" , format = ScalarType .FLOAT16 )
275273 structured_type = StructuredType (fields = [f1 , f2 , f3 , f4 ])
276- result_structured = _get_fill_value (structured_type )
277- assert result_structured == (2147483647 , 2147483647 , np_nan , np_nan )
274+
275+ expected = np_array (
276+ (0 , 0 , 0.0 , 0.0 ),
277+ dtype = np_dtype (
278+ [("cdp-x" , "<i4" ), ("cdp-y" , "<i4" ), ("elevation" , "<f2" ), ("some_scalar" , "<f2" )]
279+ ),
280+ )
281+ result = _get_fill_value (structured_type )
282+ assert expected == result
278283
279284 # Test 3: String type - should return empty string
280285 result_string = _get_fill_value ("string_type" )
@@ -382,5 +387,107 @@ def test_seismic_poststack_3d_acceptance_to_xarray_dataset(tmp_path) -> None: #
382387
383388 xr_ds = to_xarray_dataset (dataset )
384389
385- file_path = output_path (tmp_path , f"{ xr_ds .attrs ['name' ]} " , debugging = True )
390+ file_path = output_path (tmp_path , f"{ xr_ds .attrs ['name' ]} " , debugging = False )
386391 to_zarr (xr_ds , file_path , mode = "w" )
392+
393+
394+ @pytest .mark .skip (reason = "Issues serializing dask arrays of structured types to dask." )
395+ def test_to_zarr_dask (tmp_path ) -> None : # noqa: ANN001
396+ """Test writing XArray dataset with data as dask array to Zar."""
397+ # Create a data type and the fill value
398+ dtype = np_dtype ([("inline" , "int32" ), ("cdp-x" , "float64" )])
399+ dtype_fill_value = np_zeros ((), dtype = dtype )
400+
401+ # Use '_FillValue' instead of 'fill_value'
402+ # 'fill_value' is not a valid encoding key in Zarr v2
403+ my_attr_encoding = {
404+ "_FillValue" : dtype_fill_value ,
405+ "chunk_key_encoding" : {"name" : "v2" , "separator" : "/" },
406+ }
407+
408+ # Create a dask array using the data type
409+ # Do not specify encoding as the array attribute
410+ data = dask_array .zeros ((36 ,), dtype = dtype , chunks = (36 ,))
411+ aa = xr_DataArray (name = "myattr" , data = data )
412+
413+ # Specify encoding per array
414+ encoding = {"myattr" : my_attr_encoding }
415+ file_path = output_path (tmp_path , "to_zarr/zarr_dask" , debugging = False )
416+ aa .to_zarr (file_path , mode = "w" , zarr_format = 2 , encoding = encoding , compute = False )
417+
418+
419+ def test_to_zarr_zarr_zerros_1 (tmp_path ) -> None : # noqa: ANN001
420+ """Test writing XArray dataset with data as Zarr zero array to Zar.
421+
422+ Set encoding in as DataArray attributes
423+ """
424+ # Create a data type and the fill value
425+ dtype = np_dtype ([("inline" , "int32" ), ("cdp-x" , "float64" )])
426+ dtype_fill_value = np_zeros ((), dtype = dtype )
427+
428+ # Use '_FillValue' instead of 'fill_value'
429+ # 'fill_value' is not a valid encoding key in Zarr v2
430+ my_attr_encoding = {
431+ "_FillValue" : dtype_fill_value ,
432+ "chunk_key_encoding" : {"name" : "v2" , "separator" : "/" },
433+ }
434+
435+ # Create a zarr array using the data type,
436+ # Specify encoding as the array attribute
437+ data = zarr_zeros ((36 , 36 ), dtype = dtype , zarr_format = 2 )
438+ aa = xr_DataArray (name = "myattr" , data = data )
439+ aa .encoding = my_attr_encoding
440+
441+ file_path = output_path (tmp_path , "to_zarr/zarr_zarr_zerros_1" , debugging = False )
442+ aa .to_zarr (file_path , mode = "w" , zarr_format = 2 , compute = False )
443+
444+
445+ def test_to_zarr_zarr_zerros_2 (tmp_path ) -> None : # noqa: ANN001
446+ """Test writing XArray dataset with data as Zarr zero array to Zar.
447+
448+ Set encoding in the to_zar method
449+ """
450+ # Create a data type and the fill value
451+ dtype = np_dtype ([("inline" , "int32" ), ("cdp-x" , "float64" )])
452+ dtype_fill_value = np_zeros ((), dtype = dtype )
453+
454+ # Use '_FillValue' instead of 'fill_value'
455+ # 'fill_value' is not a valid encoding key in Zarr v2
456+ my_attr_encoding = {
457+ "_FillValue" : dtype_fill_value ,
458+ "chunk_key_encoding" : {"name" : "v2" , "separator" : "/" },
459+ }
460+
461+ # Create a zarr array using the data type,
462+ # Do not specify encoding as the array attribute
463+ data = zarr_zeros ((36 , 36 ), dtype = dtype , zarr_format = 2 )
464+ aa = xr_DataArray (name = "myattr" , data = data )
465+
466+ file_path = output_path (tmp_path , "to_zarr/zarr_zarr_zerros_2" , debugging = False )
467+ # Specify encoding per array
468+ encoding = {"myattr" : my_attr_encoding }
469+ aa .to_zarr (file_path , mode = "w" , zarr_format = 2 , encoding = encoding , compute = False )
470+
471+
472+ def test_to_zarr_np (tmp_path ) -> None : # noqa: ANN001
473+ """Test writing XArray dataset with data as NumPy array to Zar."""
474+ # Create a data type and the fill value
475+ dtype = np_dtype ([("inline" , "int32" ), ("cdp-x" , "float64" )])
476+ dtype_fill_value = np_zeros ((), dtype = dtype )
477+
478+ # Use '_FillValue' instead of 'fill_value'
479+ # 'fill_value' is not a valid encoding key in Zarr v2
480+ my_attr_encoding = {
481+ "_FillValue" : dtype_fill_value ,
482+ "chunk_key_encoding" : {"name" : "v2" , "separator" : "/" },
483+ }
484+
485+ # Create a zarr array using the data type
486+ # Do not specify encoding as the array attribute
487+ data = np_zeros ((36 , 36 ), dtype = dtype )
488+ aa = xr_DataArray (name = "myattr" , data = data )
489+
490+ file_path = output_path (tmp_path , "to_zarr/zarr_np" , debugging = False )
491+ # Specify encoding per array
492+ encoding = {"myattr" : my_attr_encoding }
493+ aa .to_zarr (file_path , mode = "w" , zarr_format = 2 , encoding = encoding , compute = False )
0 commit comments