Skip to content

Fix for single frequency FieldMonitor #2697

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 12, 2025
Merged

Conversation

FilipeFcp
Copy link
Contributor

@FilipeFcp FilipeFcp commented Jul 24, 2025

I just added an if condition to not interpolate the coordinates if it is a single frequency monitor to avoid interpolation data.

This issue was reported by a user today.

Greptile Summary

This PR fixes a bug in the ZBF export functionality for single-frequency FieldMonitor data. The issue occurs in the to_zbf_file method within monitor_data.py where xarray's interp() method produces NaN values when interpolating single-frequency datasets.

The change adds a conditional check if len(e_x.f) > 1: before interpolating the E-field components (e_x and e_y) to a specific frequency. This prevents unnecessary interpolation when only one frequency point exists, since the data already exists at the target frequency. The fix specifically addresses lines 1169-1171 where E-field interpolation occurs.

This change integrates with the existing ZBF export pipeline, which is used to convert Tidy3D field monitor data into the ZBF (Zemax Beam File) format for interoperability with Zemax optical design software. The ZBF export functionality is part of the monitor data processing workflow that handles various electromagnetic field data types.

Confidence score: 4/5

• This is a safe, targeted bugfix that resolves a specific interpolation issue without affecting other functionality
• The fix follows sound logic by avoiding unnecessary operations that introduce numerical artifacts, though there's a potential inconsistency with mode_area interpolation handling
• The mode_area interpolation on line 1166 should be reviewed for consistency, as it lacks the same conditional check

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, 1 comment

Edit Code Review Bot Settings | Greptile

@FilipeFcp
Copy link
Contributor Author

Regarding mode_area (bot reminded me that): The interpolation seems necessary to adjust the data type, and for some reason, the value is slightly different (on the numerical error) from the one assigned to the monitor, so it doesn't generate the nans.

Copy link
Contributor

github-actions bot commented Jul 24, 2025

Diff Coverage

Diff: origin/develop...HEAD, staged and unstaged changes

  • tidy3d/components/data/monitor_data.py (100%)
  • tidy3d/components/data/zbf.py (100%)

Summary

  • Total: 11 lines
  • Missing: 0 lines
  • Coverage: 100%

@lucas-flexcompute
Copy link
Collaborator

Regarding mode_area (bot reminded me that): The interpolation seems necessary to adjust the data type, and for some reason, the value is slightly different (on the numerical error) from the one assigned to the monitor, so it doesn't generate the nans.

Either way, does it hurt to include the mode area under the same conditional? If it also works, I think it's the safer choice.

@lucas-flexcompute
Copy link
Collaborator

It's probably a good idea to include a short test case with a single frequency to guarantee the problem doesn't happen again in the future…

@FilipeFcp
Copy link
Contributor Author

Hi @lucas-flexcompute,

I just included the mode_area, it works well (not sure why I thought it wouldn’t in the first place).

Anyway, the user added another frequency to the monitor and could load the file, but mentioned that “Tidy3D and Zemax have a 90-degree difference.”

I’m not sure if this is a true rotation or just a transposition. Do you think transposing the data would fix it?

e_x = self._tangential_fields["E" + dim1].T
e_y = self._tangential_fields["E" + dim2].T

Or is this likely specific to this case?

@bzhangflex
Copy link
Contributor

Thanks @FilipeFcp! It looks good, I agree with @lucas-flexcompute that it would be good to include a single frequency test case. The tests are here, let me know if you need any help.

Anyway, the user added another frequency to the monitor and could load the file, but mentioned that “Tidy3D and Zemax have a 90-degree difference.”

By 90-degree difference do they mean the x and y coordinates are swapped? It might be case dependent but it's hard to tell without more context, would the user be able to share more information?

@FilipeFcp
Copy link
Contributor Author

Thanks @bzhangflex.
It is my first time implementing a test. I will take a look at it and give it a try. If I need any help, I will ask you, thanks!

I will ask the user for some more context and let you know. Hi is from Japan, so probably he will reply just on Monday.

@lucas-flexcompute
Copy link
Collaborator

Hi @lucas-flexcompute,

I just included the mode_area, it works well (not sure why I thought it wouldn’t in the first place).

Anyway, the user added another frequency to the monitor and could load the file, but mentioned that “Tidy3D and Zemax have a 90-degree difference.”

I’m not sure if this is a true rotation or just a transposition. Do you think transposing the data would fix it?

e_x = self._tangential_fields["E" + dim1].T e_y = self._tangential_fields["E" + dim2].T

Or is this likely specific to this case?

This is a good question, since we did not have the opportunity to test or compare this code at all so far! We should try to work with the user to find out more.

@bzhangflex
Copy link
Contributor

bzhangflex commented Jul 25, 2025

Regarding the coordinate rotation I think I might see the issue, here instead of
e_flat = e.values.flatten(order="C")

I think it might need to be
e_flat = e.values.flatten(order="F")

If that's the case then read_zbf() probably needs to be updated too.

One test is if the user sets different values for n_x and n_y in to_zbf(), do they run into any errors or weird field profiles when they load the zbf into Zemax? If so I think it might be the flatten ordering causing the problem.

@FilipeFcp
Copy link
Contributor Author

Hi @bzhangflex and @lucas-flexcompute.

I have added the tests, and also implemented the option to pass the argument for the flatten order to 'A' or 'F', which hopefully can help us to debug it in the future.
@bzhangflex, I have added the FlattenOrders type, following the UnitsZBF model. Let me know if I need to change something or use a different approach. And thanks for your help so far!

@tomflexcompute, this is the PR I mentioned today

Copy link
Collaborator

@lucas-flexcompute lucas-flexcompute left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this flatten_order something that we need to make available? My understanding was that, once we confirmed the expected ordering in Zenmax, we could just set it here and not have the user worrying about it…

@bzhangflex bzhangflex force-pushed the filipe/to_zbf_patch branch 3 times, most recently from 6cbed0e to d025074 Compare August 11, 2025 14:18
Copy link
Contributor

@bzhangflex bzhangflex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @FilipeFcp! Looks great to me. @lucas-flexcompute would you like to have a quick look as well?

@lucas-flexcompute
Copy link
Collaborator

I think it looks good as well!

@bzhangflex bzhangflex force-pushed the filipe/to_zbf_patch branch from d025074 to ead7345 Compare August 12, 2025 00:21
@bzhangflex bzhangflex enabled auto-merge August 12, 2025 00:22
@bzhangflex bzhangflex added this pull request to the merge queue Aug 12, 2025
Merged via the queue into develop with commit 9b686b9 Aug 12, 2025
24 checks passed
@bzhangflex bzhangflex deleted the filipe/to_zbf_patch branch August 12, 2025 01:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants