Skip to content

Commit f86f3fd

Browse files
committed
fix: outer_dot output frequencies order not matching input
1 parent 9d08f9e commit f86f3fd

3 files changed

Lines changed: 29 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
- Added optional `max_results` handling to the kLayout `DRCLoader` and `DRCRunner` and speeded up parsing of big result sets.
1818

1919
### Fixed
20+
- Fix to `outer_dot` when frequencies stored in the data were not in increasing order. Previously, the result would be provided with re-sorted frequencies, which would not match the order of the original data.
2021
- Fixed bug where an extra spatial coordinate could appear in `complex_flux` and `ImpedanceCalculator` results.
2122

2223
## [2.10.0rc3] - 2025-11-26

tests/test_data/test_monitor_data.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,22 @@ def isel(data, freqs):
850850

851851
dot = mode_data.outer_dot(field_data)
852852

853-
assert len(dot.f) == 2
853+
expected_freqs = [freq for freq in mode_data.Ex.f.values if freq in field_data.Ex.f.values]
854+
assert dot.sizes["f"] == len(expected_freqs)
855+
assert np.array_equal(dot.f.values, np.array(expected_freqs))
856+
857+
# ensure frequency order follows the first dataset when the other is unordered
858+
field_data_full = make_field_data_2d()
859+
reversed_inds = list(range(field_data_full.Ex.sizes["f"] - 1, -1, -1))
860+
field_data_reordered = field_data_full.copy(
861+
update={
862+
name: component.isel(f=reversed_inds)
863+
for name, component in field_data_full.field_components.items()
864+
}
865+
)
866+
867+
dot_ordered = field_data_full.outer_dot(field_data_reordered)
868+
assert np.array_equal(dot_ordered.f.values, field_data_full.Ex.f.values)
854869

855870

856871
def test_translated_copy():
@@ -1118,7 +1133,7 @@ def test_tozbf_modedata(
11181133

11191134
def test_tozbf_modedata_fails(self, tmp_path, mode_data):
11201135
"""Asserts that Modedata.to_zbf() fails if mode_index is not specified"""
1121-
with pytest.raises(ValueError) as e:
1136+
with pytest.raises(ValueError):
11221137
_ = mode_data.to_zbf(
11231138
fname=tmp_path / "testzbf_modedata_fail.zbf",
11241139
background_refractive_index=1,
@@ -1133,7 +1148,7 @@ def test_tozbf_modedata_fails(self, tmp_path, mode_data):
11331148
@pytest.mark.parametrize("n_y", [16, 2**14, 33])
11341149
def test_tozbf_nxny_fails(self, tmp_path, field_data, n_x, n_y):
11351150
"""Asserts that to_zbf() fails when n_x and n_y are invalid values."""
1136-
with pytest.raises(ValueError) as e:
1151+
with pytest.raises(ValueError):
11371152
_ = field_data.to_zbf(
11381153
fname=tmp_path / "testzbf_nxny_fail.zbf",
11391154
background_refractive_index=1,
@@ -1146,7 +1161,7 @@ def test_tozbf_nxny_fails(self, tmp_path, field_data, n_x, n_y):
11461161
@pytest.mark.parametrize("units", ["mmm", "123"])
11471162
def test_tozbf_units_fails(self, tmp_path, field_data, units):
11481163
"""Asserts that to_zbf() fails when units are invalid."""
1149-
with pytest.raises(ValueError) as e:
1164+
with pytest.raises(ValueError):
11501165
_ = field_data.to_zbf(
11511166
fname=tmp_path / "testzbf_nxny_fail.zbf",
11521167
background_refractive_index=1,
@@ -1190,7 +1205,7 @@ def test_from_zbf_dimsfail(self, tmp_path, field_data, dim1, dim2):
11901205
units="mm",
11911206
)
11921207
# this should fail
1193-
with pytest.raises(ValueError) as e:
1208+
with pytest.raises(ValueError):
11941209
_ = td.FieldDataset.from_zbf(filename=zbf_filename, dim1=dim1, dim2=dim2)
11951210

11961211

tidy3d/components/data/monitor_data.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import autograd.numpy as np
1313
import pydantic.v1 as pd
1414
import xarray as xr
15-
from pandas import DataFrame
15+
from pandas import DataFrame, Index
1616

1717
from tidy3d.components.base import cached_property, skip_if_fields_missing
1818
from tidy3d.components.base_sim.data.monitor_data import AbstractMonitorData
@@ -916,9 +916,13 @@ def outer_dot(
916916
coords = (arrays[0].coords, arrays[1].coords)
917917

918918
# Common frequencies to both data arrays
919-
f = np.array(sorted(set(coords[0]["f"].values).intersection(coords[1]["f"].values)))
920-
isel1 = [list(coords[0]["f"].values).index(freq) for freq in f]
921-
isel2 = [list(coords[1]["f"].values).index(freq) for freq in f]
919+
freq_self = Index(coords[0]["f"].values)
920+
freq_other = Index(coords[1]["f"].values)
921+
common_freqs = freq_self.intersection(freq_other, sort=False)
922+
f = common_freqs.to_numpy()
923+
# Keep frequency order consistent with the current data while aligning the other dataset.
924+
isel1 = freq_self.get_indexer(common_freqs)
925+
isel2 = freq_other.get_indexer(common_freqs)
922926

923927
# Mode indices, if available
924928
modes_in_self = "mode_index" in coords[0]

0 commit comments

Comments
 (0)