-
Notifications
You must be signed in to change notification settings - Fork 9
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
Added F99 model #30
Added F99 model #30
Conversation
Codecov Report
@@ Coverage Diff @@
## master #30 +/- ##
==========================================
+ Coverage 99.35% 99.45% +0.09%
==========================================
Files 4 4
Lines 155 182 +27
==========================================
+ Hits 154 181 +27
Misses 1 1
Continue to review full report at Codecov.
|
I'm not at the computer right now, but if I remember correctly Dierckx.jl is based on an external C library, right? If so, yeah, Measurements.jl can't propagate the uncertainty through |
This is so cool! >>> @uncertain F99()(wave_unc[1])
0.08548387096774193 ± 0.0 but I think I am having trouble broadcasting this when I try: >>> @uncertain F99().([wave_unc[1], wave_unc[2]])
ERROR: MethodError: no method matching measurement(::Tuple{Array{Measurement{Float64},1}}) for example. |
See #30 (comment) 😉 |
hahaha, was just about to respond. Thanks! It's like you read my mind |
re: JuliaAstro#30 (comment) Co-authored-by: Mosè Giordano <giordano@users.noreply.github.com>
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 for the contribution- I've got some comments about the internals, but the documentation and testing looks good at first glance.
First, I think if we can make the interpolation work using Interpolations.jl instead of Dierckx.jl we'd be better off because as a pure-julia library we avoid issues like you saw with Measurements.jl as well as auto-differentiation. However, currently Interpolations only manages gridded interpolation up to Linear degree and requires an equally-spaced grid for BSplines up to Cubic. I have no issues including this now but I think we will want to note that it is not AD friendly.
Second, keep an eye out for moving calculations earlier. This can be achieved by the use of const
variables as well as putting more calculations into the F99
struct. What I mean by this is anything that can be fully specified using Rv
only (such as opt_axebv_y
can be added as a field to the struct- e.g. F99(Rv) = F99(Rv, f99_opt_coeff(rv))
where that function calls what you've written out. This way, even something as innocuous as F99().(wavelengths)
saves by doing that calculation once instead of every iterated method call.
Also, in general, using static data structures like Tuple
is better for static data, although I know not all of this code follows that. It would be useful to check performance using Vector
vs Tuple
vs SVector
from StaticArrays for the internals some day.
src/color_laws.jl
Outdated
# x value above which FM90 parametrization used | ||
x_cutval_uv = 10000.0 / 2700.0 | ||
|
||
# required UV points for spline interpolation | ||
x_splineval_uv = 10000.0 ./ [2700.0, 2600.0] | ||
|
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.
if these are constants, I think we should move them outside the function definition and declare as constants like so
const x_cutval_uv = aa_to_invum(2700)
const x_splineval_uv = aa_to_invum.((2700, 2600))
additionally by manually writing out a Tuple, we avoid allocating an array each method call.
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.
src/color_laws.jl
Outdated
optnir_axav_x::Vector{<:Real}, | ||
optnir_axav_y::Vector{<:Real}, |
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.
In general we want to use abstract types for function dispatch, such as AbstractVector{<:Real}
here. However, you don't really need to type any of these variables because they're constrained by their behavior already in the code- the most generic program actually has no types!
I would remove all the type specializations here, and you can callback @code_warntype _curve_F99_method(x, Rv, ...)
from the REPL to see if you have type-stability, which is what matters.
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.
src/color_laws.jl
Outdated
# FM90 model and values | ||
fm90_model = FM90(c1=c1, c2=c2, c3=c3, c4=c4, x0=x0, gamma=gamma) | ||
# evaluate model and get results in A(x)/A(V) | ||
axav_fm90 = fm90_model.(10000.0 ./ xuv) / Rv .+ 1.0 # Expects xuv in Å |
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.
style: using the @.
macro makes this line simpler and avoids bugs like the missing ./
before Rv
axav_fm90 = fm90_model.(10000.0 ./ xuv) / Rv .+ 1.0 # Expects xuv in Å | |
axav_fm90 = @. fm90_model(aa_to_invum(xuv)) / Rv + 1 # Expects xuv in Å |
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.
src/color_laws.jl
Outdated
optnir_axav_x = 10000.0 ./ | ||
[26500.0, 12200.0, 6000.0, 5470.0, 4670.0, 4110.0] |
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.
Similar to others- make const if possible and use tuples to avoid allocations
const optnir_axav_x = aa_to_invum.((26500, 12200, 6000, 5470, 4670, 4110))
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.
src/color_laws.jl
Outdated
0.701 + 1.0016 * Rv, | ||
1.208 + 1.0032 * Rv - 0.00033 * (Rv^2), | ||
] | ||
nir_axebv_y = [0.265, 0.829] * Rv / 3.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.
you'll want to make use of broadcasting here-
nir_axebv_y = @. (0.264, 0.829) * Rv / 3.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.
Thanks so much for these comments, @mileslucas! I was trying to strike a balance between doing a 1-1 translation from the original astropy code and making things more Julian. Your suggestions have helped answer a lot of "best practices" questions I've had when starting with this language and I'll start implementing them ASAP |
… macro, switched to Tuples
Sorry, not sure why this latest commit failed on some platforms while working on others. The local tests I ran before committing all passed. |
Ahh, didn't realize https://docs.julialang.org/en/v1/base/math/#Base.Math.evalpoly That's a bummer. Being able to broadcast was super useful for re-writing this opt_axebv_y = (
-0.426 + 1.0044 * Rv,
-0.050 + 1.0016 * Rv,
0.701 + 1.0016 * Rv,
1.208 + 1.0032 * Rv - 0.00033 * (Rv^2),
) as opt_axebv_y = evalpoly.(Rv, opt_axebv_y_params) and just pack all those constants into a nested Tuple outside the main function. Is there a way to broadcast with (@evalpoly Rv param... for param in opt_axebv_y_params) might work, but I am pretty sure I am butchering the syntax here. |
src/color_laws.jl
Outdated
end | ||
|
||
# terms depending on Rv | ||
c2 = @evalpoly (1. / Rv) f99_Rv_params... |
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 cannot work with this macro, you need to list the elements of the vector one by one. That's why the function was introduced
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.
Oh, just saw your comment! Yep, just realized that when I looked at Travis. Oh well =\
That's neat though that you can do exactly that in v1.4
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.
Alrighty, everything should be switched over now. I've never had to think about things like backwards compatibility before, so this has been an extremely useful lesson for me, thanks!
Ah, I see now it's failing because you can't splat a Tuple into @evalpoly in Julia v1.0.5 |
I was just going through |
Right, so my understanding was that the issue was with the next part down, which I believe @mileslucas mentions here, re: cubic splines on a non-uniform grid? I added using Interpolations.jl to my general TODO for #10. It would be awesome if we could use it in the future! Although, it looks like it is not being actively maintained right now =\ Found an open issue here! |
Following up on the spline issue, there is this package that could be useful!
I have no experience using Akima splines, but it looks like it may actually perform better than traditional cubic B-splines. I guess it comes down to: should DustExtinction.jl exactly reproduce its Python cousin's results, or should it use the "latest and greatest" technology? tbh, I can see arguments for both. |
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.
Things are looking pretty good, keep an eye out for re-ordering the computations like I mentioned in the previous review.
src/color_laws.jl
Outdated
# x value above which FM90 parametrization used | ||
const f99_x_cutval_uv = aa_to_invum(2700) | ||
|
||
# required UV points for spline interpolation | ||
const f99_x_splineval_uv = aa_to_invum.((2700, 2600)) | ||
|
||
# spline points | ||
const f99_optnir_axav_x = aa_to_invum.((26500, 12200, 6000, 5470, 4670, 4110)) | ||
const f99_nir_axebv_y_params = @. (0.265, 0.829) / 3.1 | ||
|
||
# c1-c2 correlation terms | ||
const f99_c3 = 3.23 | ||
const f99_c4 = 0.41 | ||
const f99_x0 = 4.596 | ||
const f99_gamma = 0.99 | ||
|
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 think these would fit in better closer to the F99 definition- you'll see things are generally clustered by law already
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.
For sure 804fb33
It looks like the CI sporadically fails when installing Julia, but otherwise I think everything should be addressed now for another review. 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 looking good! Thanks again for the contribution. The only changes left are completely internal and I'm not too concerned. Unless anybody else has concerns I'll merge this later tonight and do a new release.
src/color_laws.jl
Outdated
# using cubic spline anchored in UV, optical, and IR | ||
|
||
# optical/NIR points in input x | ||
|
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.
not really following the comments 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.
Oh, whoops! That's from some leftover Python styling before I switched to thinking in terms of "kernels". Thanks for catching that, should be fixed now! (5a6b6fd)
Actually, if you want to go ahead and edit |
Awesome, thanks! I opened up a separate PR for F04 (#31) and F19 (#32) as well. I tried to keep in mind everything y'all have taught me =] |
Contributing to #10