-
Notifications
You must be signed in to change notification settings - Fork 50
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
Add adaptive scientific notation for frequency range #2196
Add adaptive scientific notation for frequency range #2196
Conversation
@rahul-flex actually I think we should at least display a certain number of digitals like 5 for example. Since in most materials, the f_min and f_max differ in the first significant digital already. Could you test it on the test model and see how the output warning looks like? |
@tomflexcompute The warning message for the test setup you provided looks like this:
|
Yeah I think we do need more significant digitals otherwise the numbers are too crude. Fyi this pr is to address #1086 |
tidy3d/components/simulation.py
Outdated
@@ -2805,6 +2805,34 @@ def warn(istruct, side): | |||
|
|||
return val | |||
|
|||
def _scientific_notation(fmin_med: float, fmax_med: float) -> Tuple[str, str]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this shouldn't be a Simulation level method. Maybe Tidy3dBaseModel? Let's also change the variable names to not specifically refer to frequency, more like min_val, max_val
? And then regarding @tomflexcompute's point, add an extra argument like min_digits=4
? Looking at the code it seems that this number would refer not to the total number of significant digits, but to the digits after the decimal, e.g. 1.1234e12 to 250.1234e12
right? I think that's fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree with Tidy3dBaseModel
(here). also decorate this with a staticmethod
and change the below calls to self._scientific_notation
instead of cls._scientific_notation
, otherwise this will error when called on a class instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @rahul-flex this looks pretty good overall. Don't forget to add a unit test and a changelog entry though, this is a nicely testable function.
tidy3d/components/simulation.py
Outdated
@@ -2805,6 +2805,34 @@ def warn(istruct, side): | |||
|
|||
return val | |||
|
|||
def _scientific_notation(fmin_med: float, fmax_med: float) -> Tuple[str, str]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree with Tidy3dBaseModel
(here). also decorate this with a staticmethod
and change the below calls to self._scientific_notation
instead of cls._scientific_notation
, otherwise this will error when called on a class instance.
tidy3d/components/simulation.py
Outdated
while round(normalized_fmin, precision) == round(normalized_fmax, precision): | ||
precision += 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edge case: this will cause an infinite loop if normalized_fmin == normalized_fmax
. Not very likely to happen, but should be handled
Thanks, @momchil-flex, @tomflexcompute, and @yaugenst-flex for the review comments. I have updated the function and added test cases. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @rahul-flex I think it should work very well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @rahul-flex almost good to go :)
tests/test_components/test_base.py
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @rahul-flex the test is great, only request I have is could you turn this into a parameterized test instead? That makes them run as separate tests so it will be easier to debug in case something fails. Also note that you generally don't need to add assertion messages in pytest
because they are a bit redundant as you will get a summary of the failed tests and their parameters.
Here is how to convert to a parameterized test:
@pytest.mark.parametrize(
"min_val, max_val, min_digits, expected",
[
(1234567, 1234577, 4, ("1.23457e6", "1.23458e6")),
(1234567, 1234577, 6, ("1.234567e6", "1.234577e6")),
(1.23e-3, 1.28e-3, 4, ("1.2300e-3", "1.2800e-3")),
(123456789012345, 123456789012346, 4, ("1.23456789012345e14", "1.23456789012346e14")),
(123656789012345, 123756789012346, 4, ("1.2366e14", "1.2376e14")),
(123, 123, 4, ("1.2300e2", "1.2300e2")),
],
ids=[
"default_min_digits",
"increased_min_digits",
"small_numbers",
"large_numbers_precise",
"large_numbers_rounded",
"identical_numbers"
]
)
def test_scientific_notation(min_val, max_val, min_digits, expected):
"""Test the _scientific_notation method with various inputs."""
result = Tidy3dBaseModel._scientific_notation(min_val, max_val, min_digits=min_digits)
assert result == expected
tidy3d/components/simulation.py
Outdated
@@ -2833,6 +2833,10 @@ def _warn_monitor_mediums_frequency_range(cls, val, values): | |||
|
|||
# make sure medium frequency range includes all monitor frequencies | |||
fmin_med, fmax_med = medium.frequency_range | |||
sci_fmin_med, sci_fmax_med = Tidy3dBaseModel._scientific_notation( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simulation
is a subclass of Tidy3dBaseModel
, so just call self._scientific_notation()
here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, looks great @rahul-flex!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good after small changelog comment, and eventually squashing all commits.
CHANGELOG.md
Outdated
@@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
## [2.8.0rc1] - 2024-12-17 | |||
|
|||
### Added | |||
- Scientific notation for frequency range warnings. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changelog item should be in Unreleased not in 2.8.0rc1. Also generally we tend to put new things at the bottom of the list (Added/Fixed/Changed), not at the top.
132a8fc
to
034ba05
Compare
As discussed with @tomflexcompute we want to include as many significant digits as possible, provided the two numbers (frequency range: fmin_med and fmax_med) remain identical up to that point.
Once a differing digit is encountered, the output rounds off subsequent digits.
Also, the function returns the min and max values with same exponent.
Below are few test examples:
inputs are fmin_med and fmax_med
`Input: 1234567.56, 1234577.34
Output: 1.23457e6, 1.23458e6
Input: 1234567.56, 211234577.34
Output: 1e6, 211e6
Input: 1234567, 1934577
Output: 1e6, 2e6
Input: 1234567, 1284577
Output: 1.2e6, 1.3e6
Input: 123, 128
Output: 1.2e2, 1.3e2
Input: 0.00123, 0.00128
Output: 1.2e-3, 1.3e-3
Input: 0, 10
Output: 0e+00, 1e+01
Input: 123456789012345, 123456789012346
Output: 1.23456789012345e14, 1.23456789012346e14`