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
Replacing inaccurate Voigt1D algorithm with Humlicek approximation or scipy.special.wofz #11177
Conversation
Thanks, @dhomeier ! I am tentatively milestoning this for next release with no backport, given looks like a behavorial change that is not backward compatible (at a glance). Can you please elaborate the background for this PR, if the conversation has happened on Slack etc, for future reference? |
Sorry for pushing the |
Thanks for the clarification! I updated the milestone. |
Some numbers on the performance:
So for small |
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.
lgtm. I agree it would be better to avoid the duplication in __new__
and __init__
, but I don't know how to do that.
I've left some minor UI-related comments.
I haven't tested this. It might be nice to add a Voigt1D fitting example to the docs somewhere to showcase this?
You cannot use a class attribute to store the method, which should be specific to the instance. Otherwise you could get weird results:
Using |
|
The first docs build warning
seems to show up in other builds as well; not sure what to make of
is it complaining that the docstring mentions |
Yes, exactly what I was worrying about. It was not quite clear why the functions needed to be classmethods; but not sure if it's worth creating separate classes, if that is the only way to solve this. |
I would have been content to just handle |
@dhomeier I think the fact that evaluate was previously a class method is just a historical accident and isn't required to be (I haven't recently looked at the code, but I can't think of a reason it needs to be). There are other examples of models that define evaluate also as static methods or instance methods. Perhaps it is as simple as just trying it as an instance method. If that works then setting which algorithm becomes much simpler. |
Thanks for the clarification @perrygreenfield – using instance methods and setting the implementation method on |
@plim my understanding was that the changelog entry should go into section 4.3 here, since this will go directly into the master branch, and would be moved accordingly when preparing the backport to 4.0. Or should I move it into 4.0.5 here? The previous commit had 3 unrelated test failures in coordinates and other sub-packages, everything else passed. I'll look into an example for the docs as suggested by @keflavich ; functionally this should be ready now. |
@dhomeier , change log should be in the section that is defined by milestone. Thanks! |
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 is a great improvement! Just a couple of minor comments or questions.
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.
Somehow I missed that the last requested change had been made. Sorry for the late review.
@dhomeier Could you move the change log to the same section as the milestone. |
@nden I have apparently sufficiently clarified the definition of
The out-of-bounds |
FTR |
@kevlavich I have thought about your suggestion of adding a new example for |
Or should I rebase in case there is a fix in master that I have missed somehow? |
Co-authored-by: Nadia Dencheva <nadia.astropy@gmail.com>
Thanks @dhomeier! |
Thanks for troubleshooting, @nden! |
Replacing inaccurate Voigt1D algorithm with Humlicek approximation or scipy.special.wofz
Replacing inaccurate Voigt1D algorithm with Humlicek approximation or scipy.special.wofz
Description
This pull request is to address inaccuracies and errors in the McLean et al. algorithm used for
Voigt1D
as reported in https://dx.doi.org/10.1016/j.jqsrt.2018.03.019Hopes to fix #7256
This PR replaces the default algorithm with the complex error function computed from one of the 16-coefficient algorithms suggested by Franz Schreier in #7256 (comment) and available at https://atmos.eoc.dlr.de/tools/lbl4IR/ .
As an alternative implementation I have added the compiled Faddeeva function from
scipy.special.wofz
, which is still more accurate at almost the same speed, but of course depends on scipy – algorithms can be selected with the new optionmethod
.In addition I have added some clarification on the normalisation of the function discussed in #7256 (comment) and on Slack #general.
I could still need some advice on correctly implementing the new option. Originally I was hoping to simply set the method in
__init__
so that theVoigt1D
instance would call the appropriate function ascls._wofz
. But settings in__init__
are apparently not passed through to the classmethodsevaluate
andfit_deriv
, so I needed to set the whole stuff up in__new__
. This still looks messy and unnecessary convoluted, so I'd be grateful for suggestions for a cleaner solution.Moreover I was expecting this would at least create class instances with the given method set, e.g. for
voi_w(x)
would always compute profiles with the scipy function andvoi_h(x)
with the Humlicek algorithm;however after the second instantiation the method forvoi_w
is set tohumlicek2
as well!Otherwise it seems to work, but I am afraid the behaviour above could lead to confusion and unintended results.
Update: instantiation now works as desired; the respective algorithms can be queried with
voi_h.method
,voi_w.method
.