Skip to content

Commit b2b5097

Browse files
authored
Merge pull request #299 from PowerGridModel/feature/copy-isnan-functionality
PGM-IO internal import resolution: Copy is_nan functionality from PGM, Step 4
2 parents 1cdfb55 + 033b7cf commit b2b5097

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

src/power_grid_model_io/converters/pgm_json_converter.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
import numpy as np
1515
from power_grid_model import initialize_array
16-
from power_grid_model._utils import is_nan
1716
from power_grid_model.data_types import ComponentList, Dataset, SingleDataset, SinglePythonDataset
1817
from power_grid_model.utils import json_deserialize, json_serialize
1918

@@ -22,6 +21,12 @@
2221
from power_grid_model_io.data_types import ExtraInfo, StructuredData
2322
from power_grid_model_io.utils.dict import merge_dicts
2423

24+
_NAN_FUNC = {
25+
np.dtype("f8"): lambda x: np.all(np.isnan(x)),
26+
np.dtype("i4"): lambda x: np.all(x == np.iinfo(np.dtype("i4")).min),
27+
np.dtype("i1"): lambda x: np.all(x == np.iinfo(np.dtype("i1")).min),
28+
}
29+
2530

2631
class PgmJsonConverter(BaseConverter[StructuredData]):
2732
"""
@@ -216,8 +221,7 @@ def _is_batch(data: Dataset) -> bool:
216221
is_batch = is_dense_batch or is_sparse_batch
217222
return bool(is_batch)
218223

219-
@staticmethod
220-
def _serialize_dataset(data: SingleDataset, extra_info: Optional[ExtraInfo] = None) -> SinglePythonDataset:
224+
def _serialize_dataset(self, data: SingleDataset, extra_info: Optional[ExtraInfo] = None) -> SinglePythonDataset:
221225
"""This function converts a single power-grid-model dataset to a structured dataset
222226
223227
Args:
@@ -248,7 +252,7 @@ def _serialize_dataset(data: SingleDataset, extra_info: Optional[ExtraInfo] = No
248252
{
249253
attribute: obj[attribute].tolist()
250254
for attribute in objects.dtype.names
251-
if not is_nan(obj[attribute])
255+
if not self._is_nan(obj[attribute])
252256
},
253257
extra_info.get(obj["id"], {}),
254258
)
@@ -296,3 +300,16 @@ def _get_first_by(data: List[Dict[str, Any]], field: str, value: Any) -> Optiona
296300
return entry
297301

298302
return None
303+
304+
@staticmethod
305+
def _is_nan(data: np.ndarray) -> bool:
306+
"""
307+
Determine whether the data point is valid
308+
Args:
309+
data: a single scalar or numpy array
310+
311+
Returns:
312+
True when all the data points are invalid
313+
False otherwise
314+
"""
315+
return bool(_NAN_FUNC[data.dtype](data))

tests/unit/converters/test_pgm_json_converter.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,16 @@ def test_serialize_dataset(converter: PgmJsonConverter, pgm_input_data: SingleDa
155155
extra_info: ExtraInfo = {1: {"dummy": "data"}}
156156
structured_data_with_extra_info = converter._serialize_dataset(data=pgm_input_data, extra_info=extra_info)
157157
assert structured_data_with_extra_info == {"node": [{"id": 1, "dummy": "data"}, {"id": 2}]}
158+
159+
160+
def test_is_nan(converter: PgmJsonConverter):
161+
single_value = np.array([np.nan])
162+
assert converter._is_nan(single_value)
163+
array_f8 = np.array([0.1, 0.2, np.nan], dtype=np.dtype("f8"))
164+
assert not converter._is_nan(array_f8)
165+
array_i4 = np.array([10, 2, -(2**31), 40], dtype=np.dtype("i4"))
166+
assert not converter._is_nan(array_i4)
167+
array_i1 = np.array([1, 0, -(2**7), 1], dtype=np.dtype("i1"))
168+
assert not converter._is_nan(array_i1)
169+
nan_array = np.array([np.nan, np.nan, np.nan])
170+
assert converter._is_nan(nan_array)

0 commit comments

Comments
 (0)