-
Notifications
You must be signed in to change notification settings - Fork 49
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 make_pretty_from_fits file to develop #319
Conversation
*creates norm variable *checks wcs (issue) *changed cmap from cubealpha_r to inferno
Thanks @jermainegug. So when I told you to develop it I had you work with a separate script because you didn't have POCS installed yet. But know that you do... What we want to do is take your |
You can just keep working in the same branch and any new changes you push will automatically become part of this PR. |
*using the function in make_pretty_from_fits file *delete make_pretty_from_fits file
Ah, OK, going to need to try something else to check for a valid WCS. Seems Also, for the plot using WCS use RA & dec for the axes (not an overlay) and don't bother with Galactic coordinates, at least not by default. Could make the choice of coordinate systems an option, of course. |
Just about to put the comment in review for WCS. We do this elsewhere. Basically:
|
pocs/utils/images/__init__.py
Outdated
wcs = False | ||
|
||
""" | ||
try: |
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.
try:
w = wcs.WCS(filename)
assert w.is_celestial
except AssertionError:
pass
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.
Or just skip the try
and use if wcs.is_celstial
below.
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.
Get this error message AttributeError: 'bool' object has no attribute 'WCS'
for w = wcs.WCS(filename)
.
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.
@jermainegug That's because in your code you're setting wcs
to False
, whereas @wtgee's code suggestion is assuming that wcs
is astropy.wcs
(i.e. you're doing from astropy import wcs
)
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.
Yes, I didn't adjust it for your code, I just copied what we have elsewhere.
You import WCS
directly so use that instead of wcs.WCS
.
But, you are also mixing types. You create wcs = False
(a boolean) up above and then assign wcs=WCS(filename)
(a WCS
class) to it. I would just skip the try
and use the is_celestial
in the if
statement directly after getting the wcs.
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.
What is wcs
in this case? wcs=WCS(fname)
?
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.
R.T.D.
It's a WCS
object, i.e. an instance of the astropy.wcs.WCS
class.
http://docs.astropy.org/en/stable/api/astropy.wcs.WCS.html#astropy.wcs.WCS
In retrospect, probably best to use a more distinct variable name for it, e.g. image_wcs
.
pocs/utils/images/__init__.py
Outdated
@@ -6,7 +6,10 @@ | |||
from matplotlib import pyplot as plt | |||
from warnings import warn | |||
|
|||
from astropy.io import fits |
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 don't think you are using this.
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.
Nope, using that in my jupyter notebook.
*fixed check for wcs *not sure about RA & dec axes
Codecov Report
@@ Coverage Diff @@
## develop #319 +/- ##
===========================================
- Coverage 83.81% 83.06% -0.76%
===========================================
Files 51 51
Lines 3367 3454 +87
Branches 422 439 +17
===========================================
+ Hits 2822 2869 +47
- Misses 404 440 +36
- Partials 141 145 +4
Continue to review full report at Codecov.
|
*just set axis labels to RA and dec
@jermainegug Have a look through the documentation on this under the For this you should be using That will then make it easier to properly format the tick labels for axis, see: http://docs.astropy.org/en/stable/visualization/wcsaxes/ticks_labels_grid.html You're going to want to do this in order to make the Right Ascension axis use hour units instead of the default degrees. Also, you need to make the axis labels more explicit. I'd prefer to spell out Right Ascension & declination (if there's room) but more importantly you should specify the coordinate system and (if applicable) equinox that are being used. The WCS object should have this information (and also allow you to transform to others). It's probably either FK5 J2000 or ICRS. EDIT: There's an example of setting tick label format via the object orientated interface in the Huntsman |
*descriptive axes *coordinate system in title? *how to get equinox?
pocs/utils/images/__init__.py
Outdated
@@ -89,7 +90,7 @@ def make_pretty_image(fname, timeout=15, **kwargs): # pragma: no cover | |||
def _make_pretty_from_fits(fname, **kwargs): | |||
config = load_config() | |||
|
|||
title = '{} {}'.format(kwargs.get('title', ''), current_time().isot) | |||
title = '{} {} {}'.format(kwargs.get('title', ''), current_time().isot, 'WCS') # is WCS the coordinate system? |
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 can do current_time(pretty=True)
for a better time output 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.
And WCS = "world coordinate system", but you don't just want the string there unless you are only putting it there when is_celestial
is true or 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.
Even then it will be obvious from the rest of the plot whether a WCS from the FITS image has been used or not, from the axis labels, tick labels and grid. Don't need to put it in the title too.
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.
So we will just be able to tell the coordinate system based off what the image looks like? Thus no need to have anything writing out that it uses WCS.
pocs/utils/images/__init__.py
Outdated
ax.set_xlabel('RA') | ||
ax.set_ylabel('Dec') | ||
|
||
ra = ax.coords[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.
This is not really an ra
, it is an ra_axis
. Same with the dec. Better to be explicit about the name because if you had another variable (which maybe you will in future) that actually holds an RA value you would get confused by this.
pocs/utils/images/__init__.py
Outdated
ra = ax.coords[0] | ||
dec = ax.coords[1] | ||
|
||
ra.set_axislabel('Right Ascension') |
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 tend to do label [units]
(although I think @AnthonyHorton does something different), in which case this would be Right Ascension [hms]
and Declination [dms]
.
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.
Yes, I tend to prefer the label / units
convention (i.e. the numbers are the quantity in question divided by the given unit). Either is fine, though.
In this particular case putting units in the axis labels should be redundant though, the tick label formats include units, see https://github.com/AstroHuntsman/HuntsmanPOCSLegacy/blob/develop/examples/notebooks/dice9.png for an example.
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 have written them in for now. Will make sure that the units are in the axis label when I run the code with a fits file that has wcs., then I will get rid of the units in the label.
pocs/utils/images/__init__.py
Outdated
ax.set_xlabel('Pixel x-axis') | ||
ax.set_ylabel('Pixel y-axis') | ||
|
||
ax.coords[0].set_axislabel('Pixel x-axis') |
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.
As per comments above, I would just do X [pixels]
and Y [pixels]
.
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.
Or X / pixels
, Y / pixels
;-)
pocs/utils/images/__init__.py
Outdated
@@ -103,14 +104,22 @@ def _make_pretty_from_fits(fname, **kwargs): | |||
ax = plt.subplot(projection=wcs) | |||
|
|||
ax.coords.grid(True, color='white', ls='solid') |
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 line could be moved below if
clause so it is not repeated.
pocs/utils/images/__init__.py
Outdated
dec.set_axislabel('Declination') | ||
|
||
ra.set_major_formatter('hh:mm:ss') | ||
dec.set_major_formatter('dd:mm:ss') |
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 Huntsman, PANOPTES or in fact most other optical instruments the field of view will be large enough that including seconds in the major tick labels is unnecessary. hh:mm
and dd:mm
is probably better.
pocs/utils/images/__init__.py
Outdated
|
||
new_filename = fname.replace('.fits', '.jpg') | ||
|
||
data = getdata(fname) | ||
plt.imshow(data, cmap='cubehelix_r', origin='lower') | ||
|
||
norm = ImageNormalize(interval=MinMaxInterval(), stretch=LogStretch()) |
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.
Might be better to set the interval to trim off a (very) small percentage at either end, so that the normalisation doesn't get driven by dead pixels, hot pixels, cosmic rays and saturated stars.
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.
What sort of percentage are we thinking? Something like 0.1%?
*for lines with (?) contents should be added to config? *change from minmax to percentile interval *add alpha option for grid (transparent lines)
pocs/utils/images/__init__.py
Outdated
wcs = WCS(fname) | ||
ax = plt.subplot(projection=wcs) |
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 line might need to stay inside the if
. I'm not sure what happens if you pass a projection
but don't have a valid WCS. Have you tried on the original images that weren't solved yet?
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.
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.
There's a lot of dead white space in there around the edges. I think you can do a fig.tight_layout()
to get rid of some of that.
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 tested it on my Jupyter notebook and it seems to work just fine. If I don't assign anything to projection
then I can't use coords[]
for the pixel coordinates. I would have to use this for else
ax = plt.subplot()
ax.set_xlabel('X / pixels')
ax.set_xlabel('Y / pixels')
But I think what I have should work just fine :)
If not then we can change it to this.
Awesome, image looks good, is this with percent_value = 99.81
? Only asking because maybe we should make that value able to be modified since when I was trying different percentages, and even changing it by 0.1% it changes quite drastically.
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.
And I will add the fig.tight_layout()
soon and let you know how it looks.
This has nothing to do with your code as it was already in the function, but we shouldn't actually be doing the symlink stuff here since we don't do it in |
pocs/utils/images/__init__.py
Outdated
@@ -87,12 +90,34 @@ def make_pretty_image(fname, timeout=15, **kwargs): # pragma: no cover | |||
def _make_pretty_from_fits(fname, **kwargs): | |||
config = load_config() | |||
|
|||
title = '{} {}'.format(kwargs.get('title', ''), current_time().isot) | |||
title = '{} {}'.format(kwargs.get('title', ''), current_time(pretty=True).isot) |
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.
Tests are failing on this. Doing the pretty=True
turns it into a string, so then you can't call .isot
on it. You want one or the other. They are basically the same except pretty
has spaces for easier reading.
Yes, that image is from using your branch directly (I removed the isot
thing to make it work). So yes, using that same percentage. It's to some
extent going to depend on each image but we probably want to find
something that works most of the time and then pass an option via kwargs.
…On 13 Jan 2018 10:36 AM, "jermainegug" ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In pocs/utils/images/__init__.py
<#319 (comment)>:
> wcs = WCS(fname)
+ ax = plt.subplot(projection=wcs)
I tested it on my Jupyter notebook and it seems to work just fine. If I
don't assign anything to projection then I can't use coords[] for the
pixel coordinates. I would have to use this for else
ax.set_xlabel('X / pixels')
ax.set_xlabel('X / pixels')```
But I think what I have should work just fine :)
If not then we can change it to this.
Awesome, image looks good, is this with `percent_value = 99.81`? Only asking because maybe we should make that value able to be modified since when I was trying different percentages, and even changing it by 0.1% it changes quite drastically.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#319 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAEUUMndOSrI4n8AeKUaKsgZGyAw8t83ks5tJ-xhgaJpZM4RbqTp>
.
|
I used the example image and the wcs is working great! Like @AnthonyHorton mentioned, we wont need the units in the axis label since they are written to values on the image. |
Note that you are failing on some codestyle issues. See https://travis-ci.org/panoptes/POCS/builds/328330892#L4924 With atom or sublime you can use an autopep8 tool that should correct most things. |
autopep8 doesn't change anything in my file.. |
They were related to the comments you deleted anyway. Can you post a pic with the tight_layout? Also, in pick above I see the title but not a date. Seems like there should be both from this code. |
Check seems to give us this:
|
See my comment above about removing all the link stuff: #319 (comment) |
Oh yes, I forgot to delete those. Thanks. |
There is other stuff that goes with it. For instance once you delete that I don't think you need the |
Regarding the title and time from the fits headers, yes I would think so. The example I showed up lets a |
Ignore the recent commit. |
You want to keep the kwargs. That lets someone pass something in to override. So if I am using |
Too late. :) |
(?) I am not sure if I should use the imported current time or use the DATE-OBS from the header.
*change title
pocs/utils/images/__init__.py
Outdated
|
||
image_dir = config['directories']['images'] | ||
percent_value = 99.9 |
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.
Just to make it flexible for the future I would pull this from kwargs too. So kwargs.get('normalize_clip_percent', 99.9)
pocs/utils/images/__init__.py
Outdated
ax.set_xlabel('X / pixels') | ||
ax.set_ylabel('Y / pixels') | ||
|
||
ax.imshow(data, norm=norm, cmap='inferno', origin='lower') |
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.
Also make this slightly more flexible by doing a cmap=kwargs.get('cmap', 'inferno')
. Then you can play with different colormaps in runtime without touching code.
*allow for selection of percent, color map *neaten up code
Yay! All checks passed :) |
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.
One more small change and then I think it's good.
pocs/utils/images/__init__.py
Outdated
|
||
title = '{} {}'.format(kwargs.get('title', ''), current_time().isot) | ||
title = kwargs.get('title', header.get('FIELD', '')) | ||
date_time = header.get('DATE-OBS', current_time()).replace('T', ' ', 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.
This might need to be tested. current_time
will return a time object and then the replace
will probably fail. If you leave at current_time(pretty=True)
it will return a string and the replace will work on a string (it just won't replace anything since the T
has already been removed, but that's fine), which is probably safer and means you don't need to bother testing that.
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 have changed it now but I will test anyways (want to make sure that it doesn't get rid of the T in UTC).
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, current_time doesn't print out UTC. So it is all good then. Works just 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.
LGTM! We've beat this PR to death so any additional items can be fixed via an Issue.
@jermainegug I'll let you do the honors of merging your own PR. Make sure to select the Squash option and to say "Fixes #232" in merge commit. You are also okay to delete the branch after (it will show you a button). Thanks!
Indeed we have! No problem but I do not have write access so the merge button does not show up. Not sure if you can do this but did you want me to say it also fixes #43 along with #232 ? |
Ok, I'll go ahead and merge. #43 stays open as it is more of a question of what we want to do with the pretty pictures than it is about getting pretty pictures working. |
*creates norm variable
*checks wcs (**issue)
*changed cmap from cubealpha_r to inferno
try: wcs = WCS(fname) except: wcs = False
This does not work as expected.
If we do:
wcs = WCS(fname) print(wcs)
We get this as a result: