Skip to content
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

Fitter improvement #198

Merged
merged 2 commits into from
Feb 15, 2022
Merged

Fitter improvement #198

merged 2 commits into from
Feb 15, 2022

Conversation

weiliangjin2021
Copy link
Collaborator

More error handling in StableDispersiveFitter
Allow to load dispersive data directly by providing URL to txt or csv file
Add tunable eps_inf as a variable for optimization
Allow to set frequency range for fitting

import numpy as np
import sys

sys.path.append("../tidy3d_client_revamp")
Copy link
Collaborator

Choose a reason for hiding this comment

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

we shouldn't have this ideally. In tests/init.py we have the importing of the tidy3d package.
https://github.com/flexcompute/tidy3d/blob/develop/tests/__init__.py#L3
so can you see if removing this line still works? also the name of the repo has changed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It is now removed, and it is still working.

self.n_data = self.n_data[ind_final]
self.k_data = self.k_data[ind_final]

if np.all(ind_final) is False:
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we can do if not np.all(...)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

revised

The beginning of wavelength range. Unit: micron
wvl_max : float
The end of wavelength range. Unit: micron
"""
Copy link
Collaborator

Choose a reason for hiding this comment

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

what does this return?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

removed

log.error("No data within [wvl_min,wvl_max]")
return

self.__init__(self.wvl_um, self.n_data, self.k_data)
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this supposed to return? I'm confused

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I suppose it just updates wvl_um, n_data, etc., but doesn't return anything.

Copy link
Collaborator

Choose a reason for hiding this comment

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

aren't the values updated above? is the call to init needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

there are several others to be updated, such as frequency_range, eps_data, etc.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

removed

def validate_url_load(data_load: List):
"""Validate if the loaded data from URL is valid
The data list should be in this format:
[["wl", "n"],
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we see whether this looks ok in the docs?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

in the from_url, now I format it as example

url_file : str
Url link to the csv file.
e.g. "https://refractiveindex.info/data_csv.php?datafile=data/main/Ag/Johnson.yml"
delimiter : str, optional
Copy link
Collaborator

@tylerflex tylerflex Feb 4, 2022

Choose a reason for hiding this comment

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

instead of str, optional, we do str = ","

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

resolved

cls.validate_url_load(data_url)
except ValidationError as e: # pylint:disable=unused-variable
# log.error(e)
return obj_failed
Copy link
Collaborator

Choose a reason for hiding this comment

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

what is this case? maybe we should just raise a Tidy3D exception from e?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

now all they are all handled by Tidy3D exception

Copy link
Collaborator

@tylerflex tylerflex left a comment

Choose a reason for hiding this comment

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

see comments, also let's put some lines in the CHANGELOG.md explaining the new features.

@flexcompute flexcompute deleted a comment from twhughes Feb 4, 2022
@weiliangjin2021 weiliangjin2021 force-pushed the weiliang/url_web branch 3 times, most recently from b6e470b to c34ed59 Compare February 7, 2022 19:13
Copy link
Collaborator

@tylerflex tylerflex left a comment

Choose a reason for hiding this comment

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

Let's do the final things to this and then wrap it up:

  1. Make these 6 functions at the beginning of the file (_unpack_complex, etc) into @staticmethod in DispersionFitter, change how they are called inside the code to add self. where necessary.
  2. Change DispersionFitter to a pydantic.BaseModel object. This will be good practice.
    a. wvl_um, n_data, k_data will be defined using pydantic.Field(). Can remove init method and docstring entirely.
    b. _validate_data can be written as a pydantic.validator (see other examples in code).
    c. k_data can also be handled using a pydantic.validator that ha the side effect of setting k_data if it's None.
    d. Make self.eps_data, self.lossy, self.freqs, self.frequency_range into @property types. Then if things are changed (someone sets the wvl_range, or changes k_data), these things will be updated.

I think this will be a few changes but will ultimately be much cleaner and I think it will be ready after this. Also it will get documented fine.

nlopt_maxeval : PositiveInt, optional
Maxeval in each optimization
advanced_param : AdvancedFitterParam, optional
Other advanced parameters.
Copy link
Collaborator

Choose a reason for hiding this comment

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

let's format this like

:class:`AdvancedFitterParam`

so it links in the docs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

All revised now.

try:
resp.raise_for_status()
except Exception as e:
log.error(e)
Copy link
Collaborator

Choose a reason for hiding this comment

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

we can remove this, when you raise a WebError it will log as well

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It has been updated.

log.error(e)
raise WebError( # pylint:disable=raise-missing-from
"Authorization to the server failed. Please try again."
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

we can raise WebError(...) from e to include the original exception.

Copy link
Collaborator Author

@weiliangjin2021 weiliangjin2021 Feb 14, 2022

Choose a reason for hiding this comment

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

revised.

@weiliangjin2021 weiliangjin2021 force-pushed the weiliang/url_web branch 2 times, most recently from 2c40af8 to 058cc88 Compare February 14, 2022 23:11
Copy link
Collaborator

@tylerflex tylerflex left a comment

Choose a reason for hiding this comment

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

A few minor comments and we can merge PR

if __name__ == "__main__":
test_dispersion_load_file()
Copy link
Collaborator

Choose a reason for hiding this comment

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

let's delete this entire code block unless we need it.

num_poles = 2
num_tries = 50
tolerance_rms = 1e-3
# best_medium, best_rms = fitter.fit(
Copy link
Collaborator

Choose a reason for hiding this comment

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

remove comments unless needed.

from .fit import DispersionFitter


class FitterData(BaseModel):
class AdvancedFitterParam(BaseModel):

Copy link
Collaborator

Choose a reason for hiding this comment

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

hm, probably shouldn't be a space here? Does black not re-format this?

"hard",
title="Type of constraint for stability",
description="Stability constraint that is hard but fast to compute, "
"or soft but slightly slower to compute.",
Copy link
Collaborator

Choose a reason for hiding this comment

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

when would user want "soft"? Could you explain just a little more? Seems like soft is less stable and slower to compute? but more likely to return a fit?

nlopt_maxeval: PositiveInt = Field(
5000,
title="Number of inner iterations",
description="Number of iterations in each inner optimization",
Copy link
Collaborator

Choose a reason for hiding this comment

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

period at end of description

Other advanced parameters.

Returns
-------
Tuple[``PoleResidue``, float]
Copy link
Collaborator

Choose a reason for hiding this comment

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

:class:`PoleResiude`

_url = self._set_url("default")
# set up bound_f, bound_amp
if advanced_param.bound_f is None:
advanced_param.bound_f = self.frequency_range[1] * 10
Copy link
Collaborator

Choose a reason for hiding this comment

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

instead of hardcoding this 10, let's make it either a constant BOUND_MAX_FACTOR = 10 defined somewhere or an argument to this function if it makes more sense.

if advanced_param.bound_f is None:
advanced_param.bound_f = self.frequency_range[1] * 10
if advanced_param.bound_amp is None:
advanced_param.bound_amp = self.frequency_range[1] * 10
Copy link
Collaborator

Choose a reason for hiding this comment

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

see comment above

Change DispersionFitter to a pydantic.BaseModel object.
Make eps_data, lossy, freqs, frequency_range into @Property types
More error handling in StableDispersiveFitter
Allow to load dispersive data directly by providing URL to txt or csv file
Allow to filter wavelength range for fitting
Add tunable eps_inf as a variable for optimization
@weiliangjin2021
Copy link
Collaborator Author

All the above comments have been addressed in this commit

@tylerflex tylerflex merged commit 344c7e6 into develop Feb 15, 2022
@tylerflex tylerflex deleted the weiliang/url_web branch March 25, 2022 02:01
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.

2 participants