diff --git a/_config.yml b/_config.yml
index c2ba711e2..17952b3e2 100644
--- a/_config.yml
+++ b/_config.yml
@@ -50,7 +50,6 @@ exclude_patterns: [notebooks/DrizzlePac/align_mosaics/align_mosaics.ipynb,
notebooks/WFC3/exception_report/wfc3_exception_report.ipynb,
notebooks/WFC3/filter_transformations/filter_transformations.ipynb,
notebooks/WFC3/flux_conversion_tool/flux_conversion_tool.ipynb,
- notebooks/WFC3/image_displayer_analyzer/wfc3_image_displayer_analyzer.ipynb,
notebooks/WFC3/ir_ima_visualization/IR_IMA_Visualization_with_an_Example_of_Time_Variable_Background.ipynb,
notebooks/WFC3/ir_scattered_light_calwf3_corrections/Correcting_for_Scattered_Light_in_IR_Exposures_Using_calwf3_to_Mask_Bad_Reads.ipynb,
notebooks/WFC3/ir_scattered_light_manual_corrections/Correcting_for_Scattered_Light_in_IR_Exposures_by_Manually_Subtracting_Bad_Reads.ipynb,
diff --git a/_toc.yml b/_toc.yml
index b381f5262..9a55f87e7 100644
--- a/_toc.yml
+++ b/_toc.yml
@@ -65,7 +65,7 @@ parts:
# - file: notebooks/WFC3/exception_report/wfc3_exception_report.ipynb
# - file: notebooks/WFC3/filter_transformations/filter_transformations.ipynb
# - file: notebooks/WFC3/flux_conversion_tool/flux_conversion_tool.ipynb
-# - file: notebooks/WFC3/image_displayer_analyzer/wfc3_image_displayer_analyzer.ipynb
+ - file: notebooks/WFC3/image_displayer_analyzer/wfc3_image_displayer_analyzer.ipynb
# - file: notebooks/WFC3/ir_ima_visualization/IR_IMA_Visualization_with_an_Example_of_Time_Variable_Background.ipynb
# - file: notebooks/WFC3/ir_scattered_light_calwf3_corrections/Correcting_for_Scattered_Light_in_IR_Exposures_Using_calwf3_to_Mask_Bad_Reads.ipynb
# - file: notebooks/WFC3/ir_scattered_light_manual_corrections/Correcting_for_Scattered_Light_in_IR_Exposures_by_Manually_Subtracting_Bad_Reads.ipynb
diff --git a/notebooks/WFC3/image_displayer_analyzer/README.md b/notebooks/WFC3/image_displayer_analyzer/README.md
index 4525ced2c..a7540300f 100755
--- a/notebooks/WFC3/image_displayer_analyzer/README.md
+++ b/notebooks/WFC3/image_displayer_analyzer/README.md
@@ -1,21 +1,26 @@
-In this tutorial, we present `display_image`, a tool for displaying full images with metadata, individual WFC3/UVIS chip images, a section of an image with various colormaps/scaling, and individual WFC3/IR `ima` reads. In addition, we present `row_column_stats`, a tool for computing row and column statistics for the types of WFC3 images previously mentioned.
+In this tutorial, we present `display_image`, a tool for displaying full images with metadata, individual WFC3/UVIS chip images,
+a section of an image with various colormaps/scaling, and individual WFC3/IR `ima` reads. In addition, we present
+`row_column_stats`, a tool for computing row and column statistics for the types of WFC3 images previously mentioned.
This directory, once unzipped, should contain this `README.md`,
the image displayer tool `display_image.py`, the row and column statistic
-tool `row_column_stats.py`, and the Jupyter Notebook tutorial
-`wfc3_imageanalysis.ipynb`. Both of these tools are meant to be used inside of
-a Jupyter Notebook.
+tool `row_column_stats.py`, a `requirements.txt` file for creating a virtual
+environment, and the Jupyter Notebook tutorial `wfc3_imageanalysis.ipynb`.
+These tools are meant to be used inside a Jupyter Notebook.
-In order to run the Jupyter Notebook you must create the virtual
-environment in [WFC3 Library's](https://github.com/spacetelescope/WFC3Library)
-installation instructions. No additional packages are required to run this
-Jupyter Notebook.
+To run this Jupyter Notebook, you must have created a virtual environment that contains (at minimum) the packages listed in the
+requirements.txt file that is included within the repository. We recommend creating a new conda environment using the requirements file:
-These tools (specifically `display_image`) look much better in Jupyter Lab
-rather than the classic Jupyter Notebook. If your environment has Jupyter Lab
-installed it's recommended you use that to run the `.ipynb` file. If you're
-interested in adding Jupyter Lab to your environment see the install
-instructions on the [Jupyter website](https://jupyter.org/install).
+```
+$ conda create -n img_disp python=3.11
+$ conda activate img_disp
+$ pip install -r requirements.txt
+```
-Questions or concerns should be sent to the [HST Help Desk](https://stsci.service-now.com/hst).
+The tools in this notebook (specifically `display_image`) look much
+better in Jupyter Lab rather than in the classic Jupyter Notebook. If your
+environment has Jupyter Lab installed it's recommended you use that to run the
+.ipynb file. See the [Jupyter website](https://jupyter.org/install) for more info.
+
+Please submit any questions or comments to the [WFC3 Help Desk](https://stsci.service-now.com/hst).
---------------------------------------------------------------------
diff --git a/notebooks/WFC3/image_displayer_analyzer/display_image.py b/notebooks/WFC3/image_displayer_analyzer/display_image.py
index 922479239..b9f046808 100755
--- a/notebooks/WFC3/image_displayer_analyzer/display_image.py
+++ b/notebooks/WFC3/image_displayer_analyzer/display_image.py
@@ -1,23 +1,23 @@
#! /usr/bin/env python
-
-import numpy as np
import sys
from astropy.io import fits
-from ginga.util import zscale
+from astropy.visualization import ZScaleInterval
import matplotlib.pyplot as plt
+import numpy as np
+
def display_image(filename,
- colormaps=['Greys_r','Greys_r','inferno_r'],
- scaling=[(None,None),(None,None),(None,None)],
+ colormaps=['Greys_r', 'Greys_r', 'inferno_r'],
+ scaling=[(None, None), (None, None), (None, None)],
printmeta=False,
ima_multiread=False,
- figsize=(18,18),
+ figsize=(18, 18),
dpi=200):
-
- """ A function to display the 'SCI', 'ERR/WHT', and 'DQ/CTX' arrays
- of any WFC3 fits image. This function returns nothing, but will display
- the requested image on the screen when called.
+ """
+ A function to display the 'SCI', 'ERR/WHT', and 'DQ/CTX' arrays
+ of any WFC3 fits image. This function returns nothing, but will display
+ the requested image on the screen when called.
Authors
-------
@@ -51,8 +51,8 @@ def display_image(filename,
List of real numbers to act as scalings for the SCI, ERR, and DQ arrays.
The first element in the list is for the SCI array the second is for the
ERR array and the third element in the list is for the DQ extension. If
- no scalings are given the default scaling will use
- ginga.util.zscale.zscale(). All three scalings must be provided even if
+ no scalings are given the default scaling will use astropy.visualization
+ ZScaleInterval.get_limits(). All three scalings must be provided even if
only changing 1-2 scalings. E.g. to change SCI array scaling:
scaling = [(5E4,8E4),(None,None),(None,None)]
@@ -66,11 +66,11 @@ def display_image(filename,
plotted. If ima_multiread is set to False only the final read of the ima
(ext 1) will be plotted.
- figsize: (float,float)
- The width, height of the figure. Default is (18,18)
+ figsize: (Float,Float)
+ The width, height of the figure. Default is (18,18).
- dpi: float
- The resolution of the figure in dots-per-inch. Default is 200
+ dpi: Float
+ The resolution of the figure in dots-per-inch. Default is 200.
Returns
-------
@@ -108,7 +108,7 @@ def display_image(filename,
print("Invalid image section specified")
return 0, 0
try:
- xstart = int(xsec[: xs])
+ xstart = int(xsec[:xs])
except ValueError:
print("Problem getting xstart")
return
@@ -132,7 +132,6 @@ def display_image(filename,
print("Problem getting yend")
return
- bunit = get_bunit(h1)
detector = h['detector']
issubarray = h['subarray']
si = h['primesi']
@@ -151,33 +150,32 @@ def display_image(filename,
print('-'*44)
print(f"Filter = {h['filter']}, Date-Obs = {h['date-obs']} T{h['time-obs']},\nTarget = {h['targname']}, Exptime = {h['exptime']}, Subarray = {issubarray}, Units = {h1['bunit']}\n")
-
if detector == 'UVIS':
- if ima_multiread == True:
+ if ima_multiread is True:
sys.exit("keyword argument 'ima_multiread' can only be set to True for 'ima.fits' files")
try:
if all_pixels:
xstart = 0
ystart = 0
- xend = naxis1 # full x size
+ xend = naxis1 # full x size
yend = naxis2*2 # full y size
with fits.open(imagename) as hdu:
- uvis2_sci = hdu["SCI",1].data
+ uvis2_sci = hdu["SCI", 1].data
uvis2_err = hdu[2].data
uvis2_dq = hdu[3].data
- uvis1_sci = hdu["SCI",2].data
+ uvis1_sci = hdu["SCI", 2].data
uvis1_err = hdu[5].data
uvis1_dq = hdu[6].data
try:
- fullsci = np.concatenate([uvis2_sci,uvis1_sci])
- fulldq = np.concatenate([uvis2_dq,uvis1_dq])
- fullerr = np.concatenate([uvis2_err,uvis1_err])
+ fullsci = np.concatenate([uvis2_sci, uvis1_sci])
+ fulldq = np.concatenate([uvis2_dq, uvis1_dq])
+ fullerr = np.concatenate([uvis2_err, uvis1_err])
- fullsci = fullsci[ystart:yend,xstart:xend]
- fulldq = fulldq[ystart:yend,xstart:xend]
- fullerr = fullerr[ystart:yend,xstart:xend]
+ fullsci = fullsci[ystart:yend, xstart:xend]
+ fulldq = fulldq[ystart:yend, xstart:xend]
+ fullerr = fullerr[ystart:yend, xstart:xend]
make1x3plot(scaling, colormaps, fullsci, fullerr, fulldq,
xstart, xend, ystart, yend,
@@ -185,26 +183,26 @@ def display_image(filename,
figsize, dpi)
except ValueError:
- fullsci = np.concatenate([uvis2_sci,uvis1_sci])
- fullsci = fullsci[ystart:yend,xstart:xend]
+ fullsci = np.concatenate([uvis2_sci, uvis1_sci])
+ fullsci = fullsci[ystart:yend, xstart:xend]
- z1_sci, z2_sci = get_scale_limits(scaling[0],fullsci,'SCI')
+ z1_sci, z2_sci = get_scale_limits(scaling[0], fullsci, 'SCI')
- fig, ax1 = plt.subplots(1,1,figsize=figsize,dpi=dpi)
- im1 = ax1.imshow(fullsci,origin='lower',extent=(xstart,xend,ystart,yend),cmap=colormaps[0],vmin=z1_sci, vmax=z2_sci)
+ fig, ax1 = plt.subplots(1, 1, figsize=figsize, dpi=dpi)
+ im1 = ax1.imshow(fullsci, origin='lower', extent=(xstart, xend, ystart, yend), cmap=colormaps[0], vmin=z1_sci, vmax=z2_sci)
if len(fname) > 18:
ax1.set_title(f"WFC3/{detector} {fname}\n{h1['extname']} ext")
else:
ax1.set_title(f"WFC3/{detector} {fname} {h1['extname']} ext")
- fig.colorbar(im1, ax=ax1,shrink=.75,pad=.03)
+ fig.colorbar(im1, ax=ax1, shrink=.75, pad=.03)
- except (IndexError,KeyError):
+ except (IndexError, KeyError):
if all_pixels:
- xstart = 0
- ystart = 0
- xend = naxis1 # full x size
- yend = naxis2 # full y size
+ xstart = 0
+ ystart = 0
+ xend = naxis1 # full x size
+ yend = naxis2 # full y size
with fits.open(imagename) as hdu:
uvis_ext1 = hdu[1].data
@@ -212,35 +210,34 @@ def display_image(filename,
uvis_ext3 = hdu[3].data
try:
- uvis_ext1 = uvis_ext1[ystart:yend,xstart:xend]
- uvis_ext2 = uvis_ext2[ystart:yend,xstart:xend]
- uvis_ext3 = uvis_ext3[ystart:yend,xstart:xend]
+ uvis_ext1 = uvis_ext1[ystart:yend, xstart:xend]
+ uvis_ext2 = uvis_ext2[ystart:yend, xstart:xend]
+ uvis_ext3 = uvis_ext3[ystart:yend, xstart:xend]
make1x3plot(scaling, colormaps, uvis_ext1, uvis_ext2, uvis_ext3,
xstart, xend, ystart, yend,
detector, fname, h1, h2, h3,
figsize, dpi)
- except (TypeError,IndexError,AttributeError):
+ except (TypeError, IndexError, AttributeError):
- z1_sci, z2_sci = get_scale_limits(scaling[0],uvis_ext1,'SCI')
- fig, ax1 = plt.subplots(1,1,figsize=figsize,dpi=dpi)
- im1 = ax1.imshow(uvis_ext1,origin='lower',extent=(xstart,xend,ystart,yend),cmap=colormaps[0],vmin=z1_sci, vmax=z2_sci)
+ z1_sci, z2_sci = get_scale_limits(scaling[0], uvis_ext1, 'SCI')
+ fig, ax1 = plt.subplots(1, 1, figsize=figsize, dpi=dpi)
+ im1 = ax1.imshow(uvis_ext1, origin='lower', extent=(xstart, xend, ystart, yend), cmap=colormaps[0], vmin=z1_sci, vmax=z2_sci)
if len(fname) > 18:
ax1.set_title(f"WFC3/{detector} {fname}\n{h1['extname']} ext")
else:
ax1.set_title(f"WFC3/{detector} {fname} {h1['extname']} ext")
- fig.colorbar(im1, ax=ax1,shrink=.75,pad=.03)
-
+ fig.colorbar(im1, ax=ax1, shrink=.75, pad=.03)
if detector == 'IR' and '_ima.fits' not in fname:
- if ima_multiread == True:
+ if ima_multiread is True:
sys.exit("keyword argument 'ima_multiread' can only be set to True for 'ima.fits' files")
if all_pixels:
xstart = 0
ystart = 0
- xend = naxis1 # full x size
- yend = naxis2 # full y size
+ xend = naxis1 # full x size
+ yend = naxis2 # full y size
try:
with fits.open(imagename) as hdu:
@@ -248,9 +245,9 @@ def display_image(filename,
data_err = hdu[2].data
data_dq = hdu[3].data
- data_sci = data_sci[ystart:yend,xstart:xend]
- data_err = data_err[ystart:yend,xstart:xend]
- data_dq = data_dq[ystart:yend,xstart:xend]
+ data_sci = data_sci[ystart:yend, xstart:xend]
+ data_err = data_err[ystart:yend, xstart:xend]
+ data_dq = data_dq[ystart:yend, xstart:xend]
make1x3plot(scaling, colormaps, data_sci, data_err, data_dq,
xstart, xend, ystart, yend,
@@ -258,49 +255,48 @@ def display_image(filename,
figsize, dpi)
except (AttributeError, TypeError, ValueError):
- z1_sci, z2_sci = get_scale_limits(scaling[0],data_sci,'SCI')
- fig, ax1 = plt.subplots(1,1,figsize=figsize,dpi=dpi)
- im1 = ax1.imshow(data_sci,origin='lower',extent=(xstart,xend,ystart,yend),cmap=colormaps[0],vmin=z1_sci, vmax=z2_sci)
- if len(fname) > 18:
- ax1.set_title(f"WFC3/{detector} {fname}\n{h1['extname']} ext")
- else:
- ax1.set_title(f"WFC3/{detector} {fname} {h1['extname']} ext")
- fig.colorbar(im1, ax=ax1,shrink=.75,pad=.03)
-
+ z1_sci, z2_sci = get_scale_limits(scaling[0], data_sci, 'SCI')
+ fig, ax1 = plt.subplots(1, 1, figsize=figsize, dpi=dpi)
+ im1 = ax1.imshow(data_sci, origin='lower', extent=(xstart, xend, ystart, yend), cmap=colormaps[0], vmin=z1_sci, vmax=z2_sci)
+ if len(fname) > 18:
+ ax1.set_title(f"WFC3/{detector} {fname}\n{h1['extname']} ext")
+ else:
+ ax1.set_title(f"WFC3/{detector} {fname} {h1['extname']} ext")
+ fig.colorbar(im1, ax=ax1, shrink=.75, pad=.03)
if '_ima.fits' in fname:
if all_pixels:
xstart = 0
ystart = 0
- xend = naxis1 # full x size
- yend = naxis2 # full y size
+ xend = naxis1 # full x size
+ yend = naxis2 # full y size
- if ima_multiread == True:
+ if ima_multiread is True:
nsamps = h['NSAMP']
- for ext in reversed(range(1,nsamps+1)):
+ for ext in reversed(range(1, nsamps+1)):
with fits.open(imagename) as hdu:
- data_sci = hdu['SCI',ext].data
- data_err = hdu['ERR',ext].data
- data_dq = hdu['DQ',ext].data
+ data_sci = hdu['SCI', ext].data
+ data_err = hdu['ERR', ext].data
+ data_dq = hdu['DQ', ext].data
- data_sci = data_sci[ystart:yend,xstart:xend]
- data_err = data_err[ystart:yend,xstart:xend]
- data_dq = data_dq[ystart:yend,xstart:xend]
+ data_sci = data_sci[ystart:yend, xstart:xend]
+ data_err = data_err[ystart:yend, xstart:xend]
+ data_dq = data_dq[ystart:yend, xstart:xend]
makeIR1x3plot(scaling, colormaps, data_sci, data_err, data_dq,
- xstart, xend, ystart, yend,
- detector, fname, h1, h2, h3, nsamps, ext,
- figsize, dpi)
+ xstart, xend, ystart, yend,
+ detector, fname, h1, h2, h3, nsamps, ext,
+ figsize, dpi)
- if ima_multiread == False:
+ if ima_multiread is False:
with fits.open(imagename) as hdu:
- data_sci = hdu['SCI',1].data
- data_err = hdu['ERR',1].data
- data_dq = hdu['DQ',1].data
+ data_sci = hdu['SCI', 1].data
+ data_err = hdu['ERR', 1].data
+ data_dq = hdu['DQ', 1].data
- data_sci = data_sci[ystart:yend,xstart:xend]
- data_err = data_err[ystart:yend,xstart:xend]
- data_dq = data_dq[ystart:yend,xstart:xend]
+ data_sci = data_sci[ystart:yend, xstart:xend]
+ data_err = data_err[ystart:yend, xstart:xend]
+ data_dq = data_dq[ystart:yend, xstart:xend]
make1x3plot(scaling, colormaps, data_sci, data_err, data_dq,
xstart, xend, ystart, yend,
@@ -308,37 +304,9 @@ def display_image(filename,
figsize, dpi)
-def get_bunit(ext1header):
- """ Get the brightness unit for the plot axis label
-
- Parameters
- ----------
- ext1header: Header
- The extension 1 header of the fits file being displayed. This is the
- extension that contains the brightness unit keyword
-
- Returns
- -------
- The string of the brightness unit for the axis label
- {'counts', 'counts/s','e$^-$', 'e$^-$/s'}
-
- """
- units = ext1header['bunit']
-
- if units == 'COUNTS':
- return 'counts'
- elif units == 'COUNTS/S':
- return 'counts/s'
- elif units == 'ELECTRONS':
- return 'e$^-$'
- elif units == 'ELECTRONS/S':
- return 'e$^-$/s'
- else:
- return units
-
-
def get_scale_limits(scaling, array, extname):
- """ Get the scale limits to use for the image extension being displayed
+ """
+ Get the scale limits to use for the image extension being displayed.
Parameters
----------
@@ -346,8 +314,8 @@ def get_scale_limits(scaling, array, extname):
List of real numbers to act as scalings for the SCI, ERR, and DQ arrays.
The first element in the list is for the SCI array the second is for the
ERR array and the third element in the list is for the DQ extension. If
- no scalings are given the default scaling will use
- ginga.util.zscale.zscale(). All three scalings must be provided even if
+ no scalings are given the default scaling will use astropy.visualization
+ ZScaleInterval.get_limits(). All three scalings must be provided even if
only changing 1-2 scalings. E.g. to change SCI array scaling:
scaling = [(5E4,8E4),(None,None),(None,None)]
@@ -355,40 +323,42 @@ def get_scale_limits(scaling, array, extname):
The ImageHDU array that is being displayed.
extname: String {"SCI", "ERR", "DQ"}
- The name of the extension of which the scale is being determined
+ The name of the extension of which the scale is being determined.
Returns
-------
z1: Float
- The minimum value for the image scale
+ The minimum value for the image scale.
z2: Float
- The maximum value for the image scale
+ The maximum value for the image scale.
"""
+
+ z = ZScaleInterval()
if extname == 'DQ':
- if scaling[0] == None and scaling[1] == None:
+ if scaling[0] is None and scaling[1] is None:
z1, z2 = array.min(), array.max()
- elif scaling[0] == None and scaling[1] != None:
+ elif scaling[0] is None and scaling[1] is not None:
z1 = array.min()
z2 = scaling[1]
- elif scaling[0] != None and scaling[1] == None:
+ elif scaling[0] is not None and scaling[1] is None:
z1 = scaling[0]
z2 = array.max()
- elif scaling[0] != None and scaling[1] != None:
+ elif scaling[0] is not None and scaling[1] is not None:
z1 = scaling[0]
z2 = scaling[1]
-
+
elif extname == 'SCI' or extname == 'ERR':
- if scaling[0] == None and scaling[1] == None:
- z1, z2 = zscale.zscale(array)
- elif scaling[0] == None and scaling[1] != None:
- z1 = zscale.zscale(array)[0]
+ if scaling[0] is None and scaling[1] is None:
+ z1, z2 = z.get_limits(array)
+ elif scaling[0] is None and scaling[1] is not None:
+ z1 = z.get_limits(array)[0]
z2 = scaling[1]
- elif scaling[0] != None and scaling[1] == None:
+ elif scaling[0] is not None and scaling[1] is None:
z1 = scaling[0]
- z2 = zscale.zscale(array)[1]
- elif scaling[0] != None and scaling[1] != None:
+ z2 = z.get_limits(array)[1]
+ elif scaling[0] is not None and scaling[1] is not None:
z1 = scaling[0]
z2 = scaling[1]
else:
@@ -401,8 +371,8 @@ def get_scale_limits(scaling, array, extname):
def make1x3plot(scaling, colormaps, fullsci, fullerr, fulldq,
xstart, xend, ystart, yend,
detector, fname, h1, h2, h3,
- figsize, dpi):
- """ Make a 3 column figure to display any WFC3 image or image section
+ figsize=(9, 6), dpi=100):
+ """ Make a 3 column figure to display any WFC3 image or image section.
Parameters
----------
@@ -410,8 +380,8 @@ def make1x3plot(scaling, colormaps, fullsci, fullerr, fulldq,
List of real numbers to act as scalings for the SCI, ERR, and DQ arrays.
The first element in the list is for the SCI array the second is for the
ERR array and the third element in the list is for the DQ extension. If
- no scalings are given the default scaling will use
- ginga.util.zscale.zscale(). All three scalings must be provided even if
+ no scalings are given the default scaling will use astropy.visualization
+ ZScaleInterval.get_limits(). All three scalings must be provided even if
only changing 1-2 scalings. E.g. to change SCI array scaling:
scaling = [(5E4,8E4),(None,None),(None,None)]
@@ -451,10 +421,10 @@ def make1x3plot(scaling, colormaps, fullsci, fullerr, fulldq,
The ending index value for the y-axis of the image.
detector: String {"UVIS", "IR"}
- The detector used for the image
+ The detector used for the image.
fname: String
- The name of the file being plotted
+ The name of the file being plotted.
h1: Header
The extension 1 header of the fits file being displayed.
@@ -466,10 +436,10 @@ def make1x3plot(scaling, colormaps, fullsci, fullerr, fulldq,
The extension 3 header of the fits file being displayed.
figsize: (float,float)
- The width, height of the figure. Default is (9,6)
+ The width, height of the figure. Default is (9,6).
dpi: float
- The resolution of the figure in dots-per-inch. Default is 100
+ The resolution of the figure in dots-per-inch. Default is 100.
Returns
-------
@@ -477,15 +447,15 @@ def make1x3plot(scaling, colormaps, fullsci, fullerr, fulldq,
"""
- z1_sci, z2_sci = get_scale_limits(scaling[0],fullsci,'SCI')
- z1_err, z2_err = get_scale_limits(scaling[1],fullerr,'ERR')
- z1_dq, z2_dq = get_scale_limits(scaling[2],fulldq,'DQ')
+ z1_sci, z2_sci = get_scale_limits(scaling[0], fullsci, 'SCI')
+ z1_err, z2_err = get_scale_limits(scaling[1], fullerr, 'ERR')
+ z1_dq, z2_dq = get_scale_limits(scaling[2], fulldq, 'DQ')
- fig, [ax1,ax2,ax3] = plt.subplots(1,3,figsize=figsize,dpi=dpi)
+ fig, [ax1, ax2, ax3] = plt.subplots(1, 3, figsize=figsize, dpi=dpi)
- im1 = ax1.imshow(fullsci,origin='lower',extent=(xstart,xend,ystart,yend),cmap=colormaps[0],vmin=z1_sci, vmax=z2_sci)
- im2 = ax2.imshow(fullerr,origin='lower',extent=(xstart,xend,ystart,yend),cmap=colormaps[1],vmin=z1_err, vmax=z2_err)
- im3 = ax3.imshow(fulldq, origin='lower',extent=(xstart,xend,ystart,yend),cmap=colormaps[2],vmin=z1_dq, vmax=z2_dq)
+ im1 = ax1.imshow(fullsci, origin='lower', extent=(xstart, xend, ystart, yend), cmap=colormaps[0], vmin=z1_sci, vmax=z2_sci)
+ im2 = ax2.imshow(fullerr, origin='lower', extent=(xstart, xend, ystart, yend), cmap=colormaps[1], vmin=z1_err, vmax=z2_err)
+ im3 = ax3.imshow(fulldq, origin='lower', extent=(xstart, xend, ystart, yend), cmap=colormaps[2], vmin=z1_dq, vmax=z2_dq)
if len(fname) > 18:
ax1.set_title(f"WFC3/{detector} {fname}\n{h1['extname']} ext")
@@ -495,15 +465,16 @@ def make1x3plot(scaling, colormaps, fullsci, fullerr, fulldq,
ax1.set_title(f"WFC3/{detector} {fname} {h1['extname']} ext")
ax2.set_title(f"WFC3/{detector} {fname} {h2['extname']} ext")
ax3.set_title(f"WFC3/{detector} {fname} {h3['extname']} ext")
- fig.colorbar(im1, ax=ax1,shrink=.25,pad=.03)
- fig.colorbar(im2, ax=ax2,shrink=.25,pad=.03)
- fig.colorbar(im3, ax=ax3,shrink=.25,pad=.03)
+ fig.colorbar(im1, ax=ax1, shrink=.25, pad=.03)
+ fig.colorbar(im2, ax=ax2, shrink=.25, pad=.03)
+ fig.colorbar(im3, ax=ax3, shrink=.25, pad=.03)
+
def makeIR1x3plot(scaling, colormaps, data_sci, data_err, data_dq,
xstart, xend, ystart, yend,
detector, fname, h1, h2, h3, nsamps, ext,
- figsize, dpi):
- """ Make a 3 column figure to display any WFC3 IMA image or image section
+ figsize=(9, 6), dpi=100):
+ """ Make a 3 column figure to display any WFC3 IMA image or image section.
Parameters
----------
@@ -511,8 +482,8 @@ def makeIR1x3plot(scaling, colormaps, data_sci, data_err, data_dq,
List of real numbers to act as scalings for the SCI, ERR, and DQ arrays.
The first element in the list is for the SCI array the second is for the
ERR array and the third element in the list is for the DQ extension. If
- no scalings are given the default scaling will use
- ginga.util.zscale.zscale(). All three scalings must be provided even if
+ no scalings are given the default scaling will use astropy.visualization
+ ZScaleInterval.get_limits(). All three scalings must be provided even if
only changing 1-2 scalings. E.g. to change SCI array scaling:
scaling = [(5E4,8E4),(None,None),(None,None)]
@@ -552,10 +523,10 @@ def makeIR1x3plot(scaling, colormaps, data_sci, data_err, data_dq,
The ending index value for the y-axis of the image.
detector: String {"UVIS", "IR"}
- The detector used for the image
+ The detector used for the image.
fname: String
- The name of the file being plotted
+ The name of the file being plotted.
h1: Header
The extension 1 header of the fits file being displayed.
@@ -567,16 +538,16 @@ def makeIR1x3plot(scaling, colormaps, data_sci, data_err, data_dq,
The extension 3 header of the fits file being displayed.
nsamps: Integer
- The number of samples (readouts) contained in the file
+ The number of samples (readouts) contained in the file.
ext: Integer
- The extension to be displayed. Ranges from 1 to nsamp
+ The extension to be displayed. Ranges from 1 to nsamp.
figsize: (float,float)
- The width, height of the figure. Default is (9,6)
+ The width, height of the figure. Default is (9,6).
dpi: float
- The resolution of the figure in dots-per-inch. Default is 100
+ The resolution of the figure in dots-per-inch. Default is 100.
Returns
-------
@@ -584,17 +555,17 @@ def makeIR1x3plot(scaling, colormaps, data_sci, data_err, data_dq,
"""
- z1_sci, z2_sci = get_scale_limits(scaling[0],data_sci,'SCI')
- z1_err, z2_err = get_scale_limits(scaling[1],data_err,'ERR')
- z1_dq, z2_dq = get_scale_limits(scaling[2],data_dq,'DQ')
-
- fig, [ax1,ax2,ax3] = plt.subplots(1,3,figsize = figsize,dpi=dpi)
- im1 = ax1.imshow(data_sci,origin='lower',extent=(xstart,xend,ystart,yend),cmap=colormaps[0],vmin=z1_sci, vmax=z2_sci)
- im2 = ax2.imshow(data_err,origin='lower',extent=(xstart,xend,ystart,yend),cmap=colormaps[1],vmin=z1_err, vmax=z2_err)
- im3 = ax3.imshow(data_dq, origin='lower',extent=(xstart,xend,ystart,yend),cmap=colormaps[2],vmin=z1_dq, vmax=z2_dq)
- fig.colorbar(im1, ax=ax1,shrink=.25,pad=.03)
- fig.colorbar(im2, ax=ax2,shrink=.25,pad=.03)
- fig.colorbar(im3, ax=ax3,shrink=.25,pad=.03)
+ z1_sci, z2_sci = get_scale_limits(scaling[0], data_sci, 'SCI')
+ z1_err, z2_err = get_scale_limits(scaling[1], data_err, 'ERR')
+ z1_dq, z2_dq = get_scale_limits(scaling[2], data_dq, 'DQ')
+
+ fig, [ax1, ax2, ax3] = plt.subplots(1, 3, figsize=figsize, dpi=dpi)
+ im1 = ax1.imshow(data_sci, origin='lower', extent=(xstart, xend, ystart, yend), cmap=colormaps[0], vmin=z1_sci, vmax=z2_sci)
+ im2 = ax2.imshow(data_err, origin='lower', extent=(xstart, xend, ystart, yend), cmap=colormaps[1], vmin=z1_err, vmax=z2_err)
+ im3 = ax3.imshow(data_dq, origin='lower', extent=(xstart, xend, ystart, yend), cmap=colormaps[2], vmin=z1_dq, vmax=z2_dq)
+ fig.colorbar(im1, ax=ax1, shrink=.25, pad=.03)
+ fig.colorbar(im2, ax=ax2, shrink=.25, pad=.03)
+ fig.colorbar(im3, ax=ax3, shrink=.25, pad=.03)
if len(fname) > 18:
ax1.set_title(f"WFC3/{detector} {fname}\n {h1['extname']} read {(nsamps+1)-ext}")
diff --git a/notebooks/WFC3/image_displayer_analyzer/requirements.txt b/notebooks/WFC3/image_displayer_analyzer/requirements.txt
index a624b7053..65f7c3c7c 100644
--- a/notebooks/WFC3/image_displayer_analyzer/requirements.txt
+++ b/notebooks/WFC3/image_displayer_analyzer/requirements.txt
@@ -1,2 +1,6 @@
-astroquery==0.4.6
-matplotlib==3.7.0
+astropy
+astroquery
+jupyter
+matplotlib
+numpy
+scipy
diff --git a/notebooks/WFC3/image_displayer_analyzer/row_column_stats.py b/notebooks/WFC3/image_displayer_analyzer/row_column_stats.py
index da71d38e3..d26b619fc 100755
--- a/notebooks/WFC3/image_displayer_analyzer/row_column_stats.py
+++ b/notebooks/WFC3/image_displayer_analyzer/row_column_stats.py
@@ -1,5 +1,4 @@
#! /usr/bin/env python
-
import sys
import numpy as np
@@ -7,6 +6,7 @@
import matplotlib.pyplot as plt
from scipy.stats import mode as mode
+
def get_bunit(ext1header):
""" Get the brightness unit for the plot axis label
@@ -35,6 +35,7 @@ def get_bunit(ext1header):
else:
return units
+
def get_yaxis_and_label(stat, scidata, axes):
""" Get the y-axis values and the y axis label for the plot
@@ -78,8 +79,9 @@ def get_yaxis_and_label(stat, scidata, axes):
return yaxis, ylabel
+
def makeplot(xaxis, yaxis, axlabel, ylabel,
- bunit,detector, fname, h1, ylim,
+ bunit, detector, fname, h1, ylim,
figsize, dpi):
""" Make and display the plot for WFC3 UVIS or IR images
@@ -121,26 +123,26 @@ def makeplot(xaxis, yaxis, axlabel, ylabel,
N/A
"""
- fig, ax1 = plt.subplots(1, 1, figsize = figsize, dpi=dpi)
- # ax1.scatter(xaxis,yaxis,10,alpha=0.75)
- ax1.plot(xaxis,yaxis,marker='o',markersize=5,ls='-',alpha=0.75)
+ fig, ax1 = plt.subplots(1, 1, figsize=figsize, dpi=dpi)
+ ax1.plot(xaxis, yaxis, marker='o', markersize=5, ls='-', alpha=0.75)
- ax1.set_xlabel(f"{axlabel} Number",size=13)
- ax1.set_ylabel(f"{axlabel} {ylabel} [{bunit}]",size=13)
+ ax1.set_xlabel(f"{axlabel} Number", size=13)
+ ax1.set_ylabel(f"{axlabel} {ylabel} [{bunit}]", size=13)
ax1.grid(alpha=.75)
ax1.minorticks_on()
- ax1.yaxis.set_ticks_position('both'),ax1.xaxis.set_ticks_position('both')
- ax1.tick_params(axis='both',which='minor',direction='in',labelsize = 12,length=4)
- ax1.tick_params(axis='both',which='major',direction='in',labelsize = 12,length=7)
+ ax1.yaxis.set_ticks_position('both'), ax1.xaxis.set_ticks_position('both')
+ ax1.tick_params(axis='both', which='minor', direction='in', labelsize=12, length=4)
+ ax1.tick_params(axis='both', which='major', direction='in', labelsize=12, length=7)
if len(fname) > 18:
- ax1.set_title(f"WFC3/{detector} {fname}\n {h1['extname']} ext",size=14)
+ ax1.set_title(f"WFC3/{detector} {fname}\n {h1['extname']} ext", size=14)
else:
- ax1.set_title(f"WFC3/{detector} {fname} {h1['extname']} ext",size=14)
- if ylim != None:
- ax1.set_ylim(ylim[0],ylim[1])
+ ax1.set_title(f"WFC3/{detector} {fname} {h1['extname']} ext", size=14)
+ if ylim is not None:
+ ax1.set_ylim(ylim[0], ylim[1])
+
def make_ima_plot(xaxis, yaxis, axlabel, ylabel,
- bunit, detector, fname,h1, ylim, nsamps, ext,
+ bunit, detector, fname, h1, ylim, nsamps, ext,
figsize, dpi):
""" Make and display the plot for WFC3 IR IMA images
@@ -188,27 +190,27 @@ def make_ima_plot(xaxis, yaxis, axlabel, ylabel,
N/A
"""
- fig, ax1 = plt.subplots(1,1,figsize=figsize,dpi=dpi)
- # ax1.scatter(xaxis,yaxis,10,alpha=0.75)
- ax1.plot(xaxis,yaxis,marker='o',markersize=5,ls='-',alpha=0.75)
+ fig, ax1 = plt.subplots(1, 1, figsize=figsize, dpi=dpi)
+ ax1.plot(xaxis, yaxis, marker='o', markersize=5, ls='-', alpha=0.75)
- ax1.set_xlabel(f"{axlabel} Number",size=13)
- ax1.set_ylabel(f"{axlabel} {ylabel} [{bunit}]",size=13)
+ ax1.set_xlabel(f"{axlabel} Number", size=13)
+ ax1.set_ylabel(f"{axlabel} {ylabel} [{bunit}]", size=13)
ax1.grid(alpha=.75)
ax1.minorticks_on()
- ax1.yaxis.set_ticks_position('both'),ax1.xaxis.set_ticks_position('both')
- ax1.tick_params(axis='both',which='minor',direction='in',labelsize = 12,length=4)
- ax1.tick_params(axis='both',which='major',direction='in',labelsize = 12,length=7)
+ ax1.yaxis.set_ticks_position('both'), ax1.xaxis.set_ticks_position('both')
+ ax1.tick_params(axis='both', which='minor', direction='in', labelsize=12, length=4)
+ ax1.tick_params(axis='both', which='major', direction='in', labelsize=12, length=7)
if len(fname) > 18:
- ax1.set_title(f"WFC3/{detector} {fname}\n {h1['extname']} read {(nsamps+1)-ext}",size=14)
+ ax1.set_title(f"WFC3/{detector} {fname}\n {h1['extname']} read {(nsamps+1)-ext}", size=14)
else:
- ax1.set_title(f"WFC3/{detector} {fname} {h1['extname']} read {(nsamps+1)-ext}",size=14)
- if ylim != None:
- ax1.set_ylim(ylim[0],ylim[1])
+ ax1.set_title(f"WFC3/{detector} {fname} {h1['extname']} read {(nsamps+1)-ext}", size=14)
+ if ylim is not None:
+ ax1.set_ylim(ylim[0], ylim[1])
-def row_column_stats(filename, stat='median', axis='column', ylim=(None,None),
+
+def row_column_stats(filename, stat='median', axis='column', ylim=(None, None),
printmeta=False, ima_multiread=False, plot=True,
- figsize=(9,6), dpi=120):
+ figsize=(9, 6), dpi=120):
""" A function to plot the column median vs column number for
the 'SCI' data of any WFC3 fits image.
@@ -296,7 +298,7 @@ def row_column_stats(filename, stat='median', axis='column', ylim=(None,None),
print("Invalid image section specified")
return 0, 0
try:
- xstart = int(xsec[: xs])
+ xstart = int(xsec[:xs])
except ValueError:
print("Problem getting xstart")
return
@@ -351,69 +353,66 @@ def row_column_stats(filename, stat='median', axis='column', ylim=(None,None),
sys.exit("keyword argument 'axis' must be set to 'column' or 'row' ")
if printmeta:
- print(f"\t{si}/{detector} {fname} ")
+ print(f"\t{si}/{detector} {fname}")
print('-'*44)
print(f"Filter = {h['filter']}, Date-Obs = {h['date-obs']} T{h['time-obs']},\nTarget = {h['targname']}, Exptime = {h['exptime']}, Subarray = {issubarray}, Units = {h1['bunit']}\n")
-
-
if detector == 'UVIS':
- if ima_multiread == True:
+ if ima_multiread is True:
sys.exit("keyword argument 'ima_multiread' can only be set to True for 'ima.fits' files")
try:
with fits.open(imagename) as hdu:
- uvis1_sci = hdu['SCI',2].data
- uvis2_sci = hdu['SCI',1].data
+ uvis1_sci = hdu['SCI', 2].data
+ uvis2_sci = hdu['SCI', 1].data
- uvis_sci = np.concatenate([uvis2_sci,uvis1_sci])
+ uvis_sci = np.concatenate([uvis2_sci, uvis1_sci])
if all_pixels:
- uvis_sci = uvis_sci[ystart:yend*2,xstart:xend]
+ uvis_sci = uvis_sci[ystart:yend*2, xstart:xend]
if axis == 'row':
xaxis = range(ystart, yend*2)
else:
- uvis_sci = uvis_sci[ystart:yend,xstart:xend]
+ uvis_sci = uvis_sci[ystart:yend, xstart:xend]
except KeyError:
with fits.open(imagename) as hdu:
- uvis_sci = hdu['SCI',1].data
+ uvis_sci = hdu['SCI', 1].data
if all_pixels:
- uvis_sci = uvis_sci[ystart:yend,xstart:xend]
+ uvis_sci = uvis_sci[ystart:yend, xstart:xend]
if axis == 'row':
xaxis = range(ystart, yend)
else:
- uvis_sci = uvis_sci[ystart:yend,xstart:xend]
+ uvis_sci = uvis_sci[ystart:yend, xstart:xend]
- yaxis, ylabel = get_yaxis_and_label(stat,uvis_sci,axes)
+ yaxis, ylabel = get_yaxis_and_label(stat, uvis_sci, axes)
if plot:
makeplot(xaxis, yaxis, axlabel, ylabel,
bunit, detector, fname, h1,
ylim, figsize, dpi)
-
if detector == 'IR':
- if ima_multiread == True:
+ if ima_multiread is True:
nsamps = fits.getheader(imagename)['NSAMP']
- for ext in reversed(range(1,nsamps+1)):
+ for ext in reversed(range(1, nsamps+1)):
with fits.open(imagename) as hdu:
- scidata = hdu['SCI',ext].data
+ scidata = hdu['SCI', ext].data
- scidata = scidata[ystart:yend,xstart:xend]
+ scidata = scidata[ystart:yend, xstart:xend]
- yaxis, ylabel = get_yaxis_and_label(stat,scidata,axes)
+ yaxis, ylabel = get_yaxis_and_label(stat, scidata, axes)
if plot:
make_ima_plot(xaxis, yaxis, axlabel, ylabel,
- bunit, detector, fname,h1, ylim,
+ bunit, detector, fname, h1, ylim,
nsamps, ext, figsize, dpi)
- if ima_multiread == False:
+ if ima_multiread is False:
with fits.open(imagename) as hdu:
- scidata = hdu['SCI',1].data
+ scidata = hdu['SCI', 1].data
- scidata = scidata[ystart:yend,xstart:xend]
+ scidata = scidata[ystart:yend, xstart:xend]
- yaxis, ylabel = get_yaxis_and_label(stat,scidata,axes)
+ yaxis, ylabel = get_yaxis_and_label(stat, scidata, axes)
if plot:
makeplot(xaxis, yaxis, axlabel, ylabel,
bunit, detector, fname, h1,
diff --git a/notebooks/WFC3/image_displayer_analyzer/wfc3_image_displayer_analyzer.ipynb b/notebooks/WFC3/image_displayer_analyzer/wfc3_image_displayer_analyzer.ipynb
index aa95e3e0b..06ed259e1 100755
--- a/notebooks/WFC3/image_displayer_analyzer/wfc3_image_displayer_analyzer.ipynb
+++ b/notebooks/WFC3/image_displayer_analyzer/wfc3_image_displayer_analyzer.ipynb
@@ -8,6 +8,8 @@
"# WFC3 Image Displayer & Analyzer \n",
"***\n",
"## Learning Goals\n",
+ "This notebook provides a method to quickly display images from the Hubble Space Telescope’s Wide Field
\n",
+ "Camera 3 (WFC3) instrument. This tool also allows the user to derive statistics by row or column in the image.
\n",
"\n",
"By the end of this tutorial, you will:\n",
"\n",
@@ -15,14 +17,11 @@
"- Learn how to use the `display_image` tool to display any WFC3 fits file.\n",
"- Learn how to use the `row_column_stats` tool to plot row or column statistics for any WFC3 fits file.\n",
"\n",
- "This notebook provides a method to quickly display images from the Hubble Space Telescope’s Wide Field Camera 3 (WFC3) instrument. This tool also allows the user to derive statistics by row or column in the image.
\n",
- "Please make sure you have read the `README.md` file before continuing. \n",
- "\n",
"## Table of Contents\n",
" [Introduction](#intro)
\n",
" [1. Imports](#imports)
\n",
" [2. Query MAST and download a WFC3 `flt.fits` and `ima.fits` image](#download)
\n",
- " [3. display_image](#display)
\n",
+ " [3. `display_image`](#display)
\n",
" [3.1 Display the full images with metadata](#displayfull)
\n",
" [3.2 Display UVIS1 & UVIS2 separately](#perchip)
\n",
" [3.3 Display an image section and change the `SCI` array colormap](#colormap)
\n",
@@ -81,17 +80,18 @@
"\n",
"## 1. Imports\n",
"\n",
- "This notebook assumes you have created the virtual environment in [WFC3 Library's](https://github.com/spacetelescope/WFC3Library) installation instructions.\n",
+ "