33from pathlib import Path
44from typing import Any
55
6+ import numpy as np
67import xarray as xr
78import xattree
89from modflow_devtools .dfn .schema .block import block_sort_key
@@ -89,6 +90,16 @@ def _hack_structured_grid_dims(
8990 )
9091
9192
93+ def _hack_period_non_numeric (name , value ) -> dict :
94+ match value .dtype :
95+ case np .bool :
96+ data = {kper : "" for kper in range (value .sizes ["nper" ]) if value .values [kper ]}
97+ return name , data
98+ case np .dtypes .StringDType ():
99+ data = {kper : value .values [kper ] for kper in range (value .sizes ["nper" ])}
100+ return name .replace ("_" , " " ), data
101+
102+
92103def unstructure_component (value : Component ) -> dict [str , Any ]:
93104 blockspec = dict (sorted (value .dfn .blocks .items (), key = block_sort_key )) # type: ignore
94105 blocks : dict [str , dict [str , Any ]] = {}
@@ -157,10 +168,14 @@ def unstructure_component(value: Component) -> dict[str, Any]:
157168 structured_grid_dims = value .parent .data .dims , # type: ignore
158169 )
159170 if block_name == "period" :
160- period_data [field_name ] = {
161- kper : field_value .isel (nper = kper )
162- for kper in range (field_value .sizes ["nper" ])
163- }
171+ if not np .issubdtype (field_value .dtype , np .number ):
172+ n , v = _hack_period_non_numeric (field_name , field_value )
173+ period_data [n ] = v
174+ else :
175+ period_data [field_name ] = {
176+ kper : field_value .isel (nper = kper )
177+ for kper in range (field_value .sizes ["nper" ])
178+ }
164179 else :
165180 blocks [block_name ][field_name ] = field_value
166181
@@ -174,11 +189,19 @@ def unstructure_component(value: Component) -> dict[str, Any]:
174189 period_blocks [kper ] = {}
175190 period_blocks [kper ][arr_name ] = arr
176191
192+ # sort kper order
193+ period_blocks = dict (sorted (period_blocks .items ()))
194+
177195 # setup indexed period blocks, combine arrays into datasets
178196 for kper , block in period_blocks .items ():
179- blocks [f"period { kper + 1 } " ] = {
180- "period" : xr .Dataset (block , coords = block [arr_name ].coords )
181- }
197+ arr_name = list (block .keys ())[0 ]
198+ match block [arr_name ]:
199+ case str ():
200+ blocks [f"period { kper + 1 } " ] = {arr_name : block [arr_name ]}
201+ case xr .DataArray ():
202+ blocks [f"period { kper + 1 } " ] = {
203+ "period" : xr .Dataset (block , coords = block [arr_name ].coords )
204+ }
182205
183206 # combine "perioddata" block arrays (tdis, ats) into datasets
184207 # so they render as lists. temp hack TODO do this generically
0 commit comments