33import  pytest 
44
55import  iris 
6+ 
7+ iris .FUTURE .save_split_attrs  =  True 
68from  iris .coords  import  AuxCoord , DimCoord 
79from  iris .cube  import  Cube 
810
911NX , N_STRLEN  =  3 , 64 
1012TEST_STRINGS  =  ["Münster" , "London" , "Amsterdam" ]
1113TEST_COORD_VALS  =  ["bun" , "éclair" , "sandwich" ]
1214
15+ # VARS_COORDS_SHARE_STRING_DIM = True 
16+ VARS_COORDS_SHARE_STRING_DIM  =  False 
17+ if  VARS_COORDS_SHARE_STRING_DIM :
18+     TEST_COORD_VALS [- 1 ] =  "Xsandwich"   # makes the max coord strlen same as data one 
19+ 
1320
1421def  convert_strings_to_chararray (string_array_1d , maxlen , encoding = "utf-8" ):
1522    bbytes  =  [text .encode (encoding ) for  text  in  string_array_1d ]
@@ -19,18 +26,33 @@ def convert_strings_to_chararray(string_array_1d, maxlen, encoding="utf-8"):
1926    return  chararray 
2027
2128
22- # def convert_chararray_to_strings(char_array_2d, maxlen: int | None =0, encoding="utf-8"): 
23- #     strings = [bytes.decode(encoding) for bytes in char_array_2d] 
24- #     if not maxlen: 
25- #         maxlen = max(len(string) for string in strings) 
26- #     dtype_str = f"S{maxlen}" 
27- #     string_array = np.array(strings, dtype=dtype_str) 
28- #     return string_array 
29+ def  convert_bytesarray_to_strings (
30+     byte_array , encoding = "utf-8" , string_length : int  |  None  =  None 
31+ ):
32+     """Convert bytes to strings. 
33+ 
34+     N.B. for now at least, we assume the string dim is **always the last one**. 
35+     """ 
36+     bytes_shape  =  byte_array .shape 
37+     var_shape  =  bytes_shape [:- 1 ]
38+     if  string_length  is  None :
39+         string_length  =  bytes_shape [- 1 ]
40+     string_dtype  =  f"U{ string_length }  
41+     result  =  np .empty (var_shape , dtype = string_dtype )
42+     for  ndindex  in  np .ndindex (var_shape ):
43+         element_bytes  =  byte_array [ndindex ]
44+         bytes  =  b"" .join ([b  if  b  else  b"\0 "  for  b  in  element_bytes ])
45+         string  =  bytes .decode (encoding )
46+         result [ndindex ] =  string 
47+     return  result 
2948
3049
3150INCLUDE_COORD  =  True 
3251# INCLUDE_COORD = False 
3352
53+ INCLUDE_NUMERIC_AUXCOORD  =  True 
54+ # INCLUDE_NUMERIC_AUXCOORD = False 
55+ 
3456
3557def  make_testfile (filepath , chararray , coordarray , encoding_str = None ):
3658    with  nc .Dataset (filepath , "w" ) as  ds :
@@ -51,6 +73,13 @@ def make_testfile(filepath, chararray, coordarray, encoding_str=None):
5173            v_co [:] =  coordarray 
5274            if  encoding_str  is  not None :
5375                v_co ._Encoding  =  encoding_str 
76+             if  INCLUDE_NUMERIC_AUXCOORD :
77+                 v_num  =  ds .createVariable (
78+                     "v_num" ,
79+                     float ,
80+                     dimensions = ("x" ,),
81+                 )
82+                 v_num [:] =  np .arange (NX )
5483        v  =  ds .createVariable (
5584            "v" ,
5685            "S1" ,
@@ -63,7 +92,10 @@ def make_testfile(filepath, chararray, coordarray, encoding_str=None):
6392        if  encoding_str  is  not None :
6493            v ._Encoding  =  encoding_str 
6594        if  INCLUDE_COORD :
66-             v .coordinates  =  "v_co" 
95+             coords_str  =  "v_co" 
96+             if  INCLUDE_NUMERIC_AUXCOORD :
97+                 coords_str  +=  " v_num" 
98+             v .coordinates  =  coords_str 
6799
68100
69101def  make_testcube (
@@ -111,8 +143,10 @@ def show_result(filepath):
111143            )
112144        print ("-data-" )
113145        print (repr (cube .data ))
146+         print ("-numeric auxcoord data-" )
147+         print (repr (cube .coord ("x" ).points ))
114148        if  INCLUDE_COORD :
115-             print ("-coord  data-" )
149+             print ("-string auxcoord  data-" )
116150            try :
117151                print (repr (cube .coord ("v_co" ).points ))
118152            except  Exception  as  err2 :
@@ -160,3 +194,19 @@ def test_save_encodings(encoding):
160194    filepath  =  f"tmp_save_{ str (encoding )}  
161195    iris .save (cube , filepath )
162196    show_result (filepath )
197+ 
198+ 
199+ # @pytest.mark.parametrize("ndim", [1, 2]) 
200+ # def test_convert_bytes_to_strings(ndim: int): 
201+ #     if ndim == 1: 
202+ #         source = convert_strings_to_chararray(TEST_STRINGS, 16) 
203+ #     elif ndim == 2: 
204+ #         source = np.stack([ 
205+ #             convert_strings_to_chararray(TEST_STRINGS, 16), 
206+ #             convert_strings_to_chararray(TEST_COORD_VALS, 16), 
207+ #         ]) 
208+ #     else: 
209+ #         raise ValueError(f"Unexpected param ndim={ndim}.") 
210+ #     # convert the strings to bytes 
211+ #     result = convert_bytesarray_to_strings(source) 
212+ #     print(result) 
0 commit comments