From f5ebf465c81296f05ec1ea69544f86ccd3dd4315 Mon Sep 17 00:00:00 2001 From: Tyler Hughes Date: Tue, 7 Nov 2023 14:31:07 -0500 Subject: [PATCH] proper equality checking between tidy3d base model --- CHANGELOG.md | 1 + tests/sims/simulation_2_5_0rc3.h5 | Bin 0 -> 451528 bytes tests/sims/simulation_2_5_0rc3.json | 2153 ++++++++++++++++++++++++++ tests/test_components/test_IO.py | 12 +- tests/test_components/test_base.py | 9 + tidy3d/components/base.py | 44 +- tidy3d/components/data/data_array.py | 4 + 7 files changed, 2218 insertions(+), 5 deletions(-) create mode 100644 tests/sims/simulation_2_5_0rc3.h5 create mode 100644 tests/sims/simulation_2_5_0rc3.json diff --git a/CHANGELOG.md b/CHANGELOG.md index b3e851eb2..a73ffaf5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed the duplication of log messages in Jupyter when `set_logging_file` is used. - If input to circular filters in adjoint have size smaller than the diameter, instead of erroring, warn user and truncate the filter kernel accordingly. - When writing the json string of a model to an `hdf5` file, the string is split into chunks if it has more than a set (very large) number of characters. This fixes potential error if the string size is more than 4GB. +- Proper equality checking between `Tidy3dBaseModel` instances, which takes `DataArray` values and coords into account and handles `np.ndarray` types. ## [2.5.0rc2] - 2023-10-30 diff --git a/tests/sims/simulation_2_5_0rc3.h5 b/tests/sims/simulation_2_5_0rc3.h5 new file mode 100644 index 0000000000000000000000000000000000000000..a5cf8c5443fb7cb8548b09aea8833b0762ff5a24 GIT binary patch literal 451528 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 bool: + """Check if two dictionaries are equal, with special handlings.""" + + # if different keys, automatically fail + if not dict1.keys() == dict2.keys(): + return False + + # loop through elements in each dict + for key in dict1.keys(): + val1 = dict1[key] + val2 = dict2[key] + + # if one of val1 or val2 is None (exclusive OR) + if (val1 is None) != (val2 is None): + return False + + # convert tuple to dict to use this recursive function + if isinstance(val1, tuple) or isinstance(val2, tuple): + val1 = dict(zip(range(len(val1)), val1)) + val2 = dict(zip(range(len(val2)), val2)) + + # if dictionaries, recurse + if isinstance(val1, dict) or isinstance(val2, dict): + are_equal = check_equal(val1, val2) + if not are_equal: + return False + + # if numpy arrays, use numpy to do equality check + elif isinstance(val1, np.ndarray) or isinstance(val2, np.ndarray): + if not np.array_equal(val1, val2): + return False + + # everything else + else: + + # note: this logic is because != is handled differently in DataArrays apparently + if not val1 == val2: + return False + + return True + + return check_equal(self.dict(), other.dict()) @cached_property def _json_string(self) -> str: diff --git a/tidy3d/components/data/data_array.py b/tidy3d/components/data/data_array.py index a1e9274c2..b0282c1c4 100644 --- a/tidy3d/components/data/data_array.py +++ b/tidy3d/components/data/data_array.py @@ -115,6 +115,10 @@ def _json_encoder(cls, val): def __eq__(self, other) -> bool: """Whether two data array objects are equal.""" + + if not isinstance(other, xr.DataArray): + return False + if not self.data.shape == other.data.shape or not np.all(self.data == other.data): return False for key, val in self.coords.items():