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
Fixed Gaussian2D model #2038
Fixed Gaussian2D model #2038
Conversation
b * (x - x_mean) * (y - y_mean) + | ||
c * (y - y_mean) ** 2)) | ||
c * (y - y_mean)**2)) |
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.
Kind of annoying, but I wonder if it might also be worth saving x - x_mean
and y - y_mean
in temporary variable since they're computed twice.
@larrybradley Looks good to me. Just one minor comment. To be consistent with the rest of the code could you insert space between operators, things like |
Should we consider this a bug fix and tag it 0.3.1 or is it too late for that? |
I don't think it's too late. I'm still a little stuck on 0.3.1 in getting all the tests to pass so the release has been delayed a bit by that. This should merge uncontroversially. Please just include a changelog entry under the 0.3.1 section. |
@larrybradley Can you add a unit test that would fail without your fix but now succeeds? (For me it's hard seeing which formulas are correct from just looking at the code.) I think the travis-ci test failure in |
@cdeil I've added the test. |
Thanks for adding the test! With the hardcoded result numbers you have its still hard to see if the model now is correct, right? An alternative (or addition) could be to test that a rotated model gives the same result at a rotated point ... something like this (untested): from numpy.testing import assert_allclose
from astropy.coordinates import Angle
from astropy.modeling.models import MatrixRotation2D
from astropy.modeling.models import Gaussian2D
amplitude = 42
x_mean, y_mean = 43, 44
x_stddev, y_stddev = 2, 3
theta = Angle(10, 'deg')
pars = dict(amplitude=amplitude, x_mean=x_mean, y_mean=y_mean,
x_stddev=x_stddev, y_stddev=y_stddev)
rotation_matrix = MatrixRotation2D(angle=theta.degree)
point1 = (x_mean + 2 * x_stddev, y_mean + 2 * y_stddev)
point2 = rotation_matrix(*point1)
g1 = Gaussian2D(theta=0, **pars)
g2 = Gaussian2D(theta=theta.radian, **pars)
value1 = g1(*point1)
value2 = g2(*point2)
assert_allclose(value1, value2) Actually this could be easily extended to test all models that can be rotated and a few rotation angles (e.g. a negative one, and one larger than 360 deg). @larrybradley If you don't want to add this here, I'm 👍 to merge this now and I can make a new pull request with this more generic test for rotated models. |
I'd say not as an alternative, perhaps in addition to, though it is hard to see how it adds any real new test to the existing one. As an alternative, it is vulnerable to a change to the function that makes it not a correct 2D gaussian. It only tests that the rotation is applied correctly to the functional form. On the other hand, if the rotation is being computed incorrectly, the existing test is very unlikely to get the right answer, and it ensures that the functional form is right at the same time. Whether the answers in the test are obviously right is a different matter, but that's what external validation of the test is for. |
I've added an additional, alternative test. Thanks, @cdeil. But note that since Thanks, @perrygreenfield. Actually the way the |
@perrygreenfield Agreed that the test I suggested only tests the rotation part of the model evaluation. But I believe the other parts were already covered by this test. Concerning the point of "external validation" you mention, here is a check of @larrybradley's numbers against Sherpa: import numpy as np
from sherpa.models import Gauss2D
sigma_to_fwhm = np.sqrt(8 * np.log(2))
g = Gauss2D()
g.ampl = 100
g.xpos = 1.7
g.ypos = 3.1
g.fwhm = sigma_to_fwhm * 5.0
g.ellip = 1 - 3.3 / 5.0
g.theta = np.pi/6.
g.integrate = False
x, y = np.mgrid[0:5, 0:5]
g(x.flatten(), y.flatten()).reshape(x.shape) I get these numbers which are different:
Probably I made a mistake ... I'll sleep on it and have a fresh look tomorrow. |
In any case I'm wondering if "hard-coding" the rotation and stretching into the At the moment |
@cdeil I quickly noticed that I exactly reproduce your Sherpa results if I use |
@larrybradley OK, so one of us is confused about One thought I had: Shouldn't it be
instead of
because isn't this correct
? What would help IMO would be a description of the axis order and rotation angle sense with a few examples of how they relate to the numpy axis order in the astropy docs ... like what @kbarbary proposes here: astropy/photutils#32 |
@cdeil - I think the convention should probably be that the orientation should be 'correct' when output to a FITS file or displayed in a matplotlib image (which I think is the same). |
This should help understand what is going on (I used this branch to run this example) My conclusion:
This |
@larrybradley This needs to be rebased against master, the |
d_y_mean = amplitude * (+(x - x_mean) * b + 2 * (y - y_mean) * c) * d_A | ||
d_x_mean = amplitude * ((y - y_mean) * b + 2 * (x - x_mean) * a) * d_A | ||
return [d_A, d_x_mean, d_y_mean, d_x_stddev, d_y_stddev, d_theta] | ||
cost = np.cos(theta) |
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 was trying to find out if the deriv
method is covered by the unit tests.
Turns out it is, but the only way I was able to find this coverage information for this pull request was via the travis-ci log, which seems overly complicated:
https://travis-ci.org/astropy/astropy/jobs/18914850#L1843
https://coveralls.io/files/137268781#L229
@astrofrog Is there a better way of browsing to coverage information for astropy pull requests?
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.
@cdeil - you can run:
python setup.py test --coverage
or go directly to https://coveralls.io/r/astropy/astropy
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.
But the https://coveralls.io/r/astropy/astropy page just has the builds in order, so it's very hard to find the coverage report for a given pull request if the build isn't very recent, no?
(Am I missing something?)
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.
Ah right yes - in that case there is no easy way. The issue numbers are listed on coveralls though, but I agree it'd be nice to have an easier way.
@cdeil Yes, I agree! I actually suspected last night that the |
I've updated the test and rebased on the current master. Hopefully this is ready to be merged now. |
👍 to merge this now. |
Fixed Gaussian2D model Conflicts: astropy/modeling/functional_models.py
These are fixes to the
Gaussian2D
model. Specifically, theb
parameter was incorrect in the code (but correct in the docs). Also, thea
parameter was incorrect in the docs (but correct in the code). This PR also updates the derivatives based on the correctb
value. The other changes represent some refactoring to hopefully make things a little clearer/cleaner.