-
Notifications
You must be signed in to change notification settings - Fork 10
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
Some plotting and representation improvements #260
Changes from 5 commits
2f39b67
50f92de
92de6b4
f416ded
fd72a2e
331e12a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,8 +7,10 @@ | |
|
||
from pathlib import Path | ||
import logging | ||
from itertools import cycle | ||
|
||
import numpy as np | ||
from matplotlib import pyplot as plt | ||
|
||
from astropy.io import fits | ||
from astropy.table import Table | ||
|
@@ -179,7 +181,7 @@ | |
ex_vol["meta"].update(vol) | ||
ex_vol["meta"].pop("wave_min") | ||
ex_vol["meta"].pop("wave_max") | ||
new_vols_list += extracted_vols | ||
new_vols_list.extend(extracted_vols) | ||
|
||
obj.volumes = new_vols_list | ||
|
||
|
@@ -195,8 +197,7 @@ | |
logging.info("Making cube") | ||
obj.cube = obj.make_cube_hdu() | ||
|
||
trace_id = obj.meta["trace_id"] | ||
spt = self.spectral_traces[trace_id] | ||
spt = self.spectral_traces[obj.meta["trace_id"]] | ||
obj.hdu = spt.map_spectra_to_focal_plane(obj) | ||
|
||
return obj | ||
|
@@ -208,11 +209,11 @@ | |
xfoot, yfoot = [], [] | ||
for spt in self.spectral_traces.values(): | ||
xtrace, ytrace = spt.footprint() | ||
xfoot += xtrace | ||
yfoot += ytrace | ||
xfoot.extend(xtrace) | ||
yfoot.extend(ytrace) | ||
|
||
xfoot = [np.min(xfoot), np.max(xfoot), np.max(xfoot), np.min(xfoot)] | ||
yfoot = [np.min(yfoot), np.min(yfoot), np.max(yfoot), np.max(yfoot)] | ||
xfoot = [min(xfoot), max(xfoot), max(xfoot), min(xfoot)] | ||
yfoot = [min(yfoot), min(yfoot), max(yfoot), max(yfoot)] | ||
|
||
return xfoot, yfoot | ||
|
||
|
@@ -299,42 +300,61 @@ | |
#pdu.header['FILTER'] = from_currsys("!OBS.filter_name_fw1") | ||
outhdul = fits.HDUList([pdu]) | ||
|
||
for i, trace_id in enumerate(self.spectral_traces): | ||
for i, trace_id in enumerate(self.spectral_traces, start=1): | ||
hdu = self[trace_id].rectify(hdulist, | ||
interps=interps, | ||
bin_width=bin_width, | ||
xi_min=xi_min, xi_max=xi_max, | ||
wave_min=wave_min, wave_max=wave_max) | ||
if hdu is not None: # ..todo: rectify does not do that yet | ||
outhdul.append(hdu) | ||
outhdul[0].header[f"EXTNAME{i+1}"] = trace_id | ||
outhdul[0].header[f"EXTNAME{i}"] = trace_id | ||
|
||
outhdul[0].header.update(inhdul[0].header) | ||
|
||
return outhdul | ||
|
||
|
||
def rectify_cube(self, hdulist): | ||
"""Rectify traces and combine into a cube""" | ||
raise(NotImplementedError) | ||
|
||
def plot(self, wave_min=None, wave_max=None, **kwargs): | ||
def plot(self, wave_min=None, wave_max=None, axes=None, **kwargs): | ||
"""Plot every spectral trace in the spectral trace list. | ||
|
||
Parameters | ||
---------- | ||
wave_min : float, optional | ||
Minimum wavelength, if any. If None, value from_currsys is used. | ||
wave_max : float, optional | ||
Maximum wavelength, if any. If None, value from_currsys is used. | ||
axes : matplotlib axes, optional | ||
The axes object to use for the plot. If None (default), a new | ||
figure with one axes will be created. | ||
**kwargs : dict | ||
Any other parameters passed along to the plot method of the | ||
individual spectral traces. | ||
|
||
Returns | ||
------- | ||
fig : matplotlib figure | ||
DESCRIPTION. | ||
|
||
""" | ||
if wave_min is None: | ||
wave_min = from_currsys("!SIM.spectral.wave_min") | ||
if wave_max is None: | ||
wave_max = from_currsys("!SIM.spectral.wave_max") | ||
|
||
from matplotlib import pyplot as plt | ||
from matplotlib._pylab_helpers import Gcf | ||
if len(Gcf.figs) == 0: | ||
plt.figure(figsize=(12, 12)) | ||
if axes is None: | ||
fig, axes = plt.subplots(figsize=(12, 12)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we keep the absolute figsize or should we leave that to the user? While 12in x 12in makes a nice LP cover, it is a tad too large for my computer screens. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know what the original motivation was for this giant plot, but I thought there might have been a good reason, so I left it in. That said, working on the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Giant plots are needed to see where the spectral traces are actually positioned on the detector plane. However this should only be a default if someone hasn't already generated a figure or passed an Axes object. |
||
else: | ||
fig = axes.figure | ||
|
||
if self.spectral_traces is not None: | ||
clrs = "rgbcymk" * (1 + len(self.spectral_traces) // 7) | ||
for spt, c in zip(self.spectral_traces.values(), clrs): | ||
spt.plot(wave_min, wave_max, c=c) | ||
for spt, c in zip(self.spectral_traces.values(), cycle("rgbcymk")): | ||
spt.plot(wave_min, wave_max, c=c, axes=axes, **kwargs) | ||
|
||
return plt.gcf() | ||
return fig | ||
|
||
def __repr__(self): | ||
# "\n".join([spt.__repr__() for spt in self.spectral_traces]) | ||
|
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
is in the range[0, len(spec traces)]
from the enumerate call in line 302The primary header
EXTNAME0
will (should) never contain trace data.Trace data should only be held in the additional FITS extensions 1..N, i.e.
EXTNAME[1 ... len(spec traces)]
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 you look a few lines further up, I also changed the enumerate to
enumerate(self.spectral_traces, start=1)
, which meansi
is inrange(1, len(self.spectral_traces) + 1)
. This (in general, not only in this example) has the benefits of more clearly marking the purpose ofi
(we want values from 1, not 0) and saving to type+1
every time (which may cause bugs if forgotten once). Of course, this only makes sense ifi
is only used asi+1
within that particular scope (which is the case 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.
Today I learned ... :)