Skip to content

Commit

Permalink
add pixel scale factor to metadata and API translation (spacetelescop…
Browse files Browse the repository at this point in the history
…e#2752)

* add pixel scale factor to metadata

* add change log

* remove change log and update to  use flux cube metadata

* add translation functionality to API, and test two-way test functionality

* move scale factor to collapsed_spec, combine sci notation and pixar_sr with scale factor

* unexpose translate_units() from user

* remove hard-coded sci notation, add additional flux/sb units

* removing unit dictionary, multiply/divide by sr

* moving metadata addition to before add_results_from_plugin
  • Loading branch information
gibsongreen authored Mar 25, 2024
1 parent d3dcfa5 commit d007a4b
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import numpy as np
import astropy
from astropy import units as u
from astropy.utils.decorators import deprecated
from astropy.nddata import (
NDDataArray, StdDevUncertainty
Expand Down Expand Up @@ -332,6 +333,10 @@ def collapse_to_spectrum(self, add_data=True, **kwargs):
fname_label = self.dataset_selected.replace("[", "_").replace("]", "")
self.filename = f"extracted_{selected_func}_{fname_label}.fits"

# per https://jwst-docs.stsci.edu/jwst-near-infrared-camera/nircam-performance/nircam-absolute-flux-calibration-and-zeropoints # noqa
pix_scale_factor = self.aperture.scale_factor * spectral_cube.meta.get('PIXAR_SR', 1.0)
collapsed_spec.meta['_pixel_scale_factor'] = pix_scale_factor

if add_data:
self.add_results.add_results_from_plugin(
collapsed_spec, label=self.results_label, replace=False
Expand Down Expand Up @@ -519,3 +524,13 @@ def _live_update(self, event={}):
for mark in self.marks.values():
mark.update_xy(sp.spectral_axis.value, sp.flux.value)
mark.visible = True

def translate_units(self, collapsed_spec):
# remove sr
if u.sr in collapsed_spec._unit.bases:
collapsed_spec._data *= collapsed_spec.meta['_pixel_scale_factor']
collapsed_spec._unit *= u.sr
# add sr
elif u.sr not in collapsed_spec._unit.bases:
collapsed_spec._data /= collapsed_spec.meta['_pixel_scale_factor']
collapsed_spec._unit /= u.sr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from regions import (CirclePixelRegion, CircleAnnulusPixelRegion, EllipsePixelRegion,
RectanglePixelRegion, PixCoord)
from specutils import Spectrum1D
from astropy.wcs import WCS


def test_version_after_nddata_update(cubeviz_helper, spectrum1d_cube_with_uncerts):
Expand Down Expand Up @@ -370,3 +371,50 @@ def test_cube_extraction_with_nan(cubeviz_helper, image_cube_hdu_obj):
extract_plg.aperture = 'Subset 1'
sp_subset = extract_plg.collapse_to_spectrum() # Default settings but on Subset
assert_allclose(sp_subset.flux.value, 12) # (4 x 4) - 4


def test_unit_translation(cubeviz_helper):
# custom cube so we have PIXAR_SR in metadata, and flux units = Jy/pix
wcs_dict = {"CTYPE1": "WAVE-LOG", "CTYPE2": "DEC--TAN", "CTYPE3": "RA---TAN",
"CRVAL1": 4.622e-7, "CRVAL2": 27, "CRVAL3": 205,
"CDELT1": 8e-11, "CDELT2": 0.0001, "CDELT3": -0.0001,
"CRPIX1": 0, "CRPIX2": 0, "CRPIX3": 0, "PIXAR_SR": 8e-11}
w = WCS(wcs_dict)
flux = np.zeros((30, 20, 3001), dtype=np.float32)
flux[5:15, 1:11, :] = 1
cube = Spectrum1D(flux=flux * u.MJy, wcs=w, meta=wcs_dict)
cubeviz_helper.load_data(cube, data_label="test")

center = PixCoord(5, 10)
cubeviz_helper.load_regions(CirclePixelRegion(center, radius=2.5))

extract_plg = cubeviz_helper.plugins['Spectral Extraction']

extract_plg.aperture = extract_plg.aperture.choices[-1]
extract_plg.aperture_method.selected = 'Exact'
extract_plg.wavelength_dependent = True
extract_plg.function = 'Sum'
# set so pixel scale factor != 1
extract_plg.reference_wavelength = 0.000001

# collapse to spectrum, now we can get pixel scale factor
collapsed_spec = extract_plg.collapse_to_spectrum()

assert collapsed_spec.meta['_pixel_scale_factor'] != 1

# store to test second time after calling translate_units
mjy_sr_data1 = collapsed_spec._data[0]

extract_plg._obj.translate_units(collapsed_spec)

assert collapsed_spec._unit == u.MJy / u.sr
# some value in MJy/sr that we know the outcome after translation
assert np.allclose(collapsed_spec._data[0], 8.7516529e10)

extract_plg._obj.translate_units(collapsed_spec)

# translating again returns the original units
assert collapsed_spec._unit == u.MJy
# returns to the original values
# which is a value in Jy/pix that we know the outcome after translation
assert np.allclose(collapsed_spec._data[0], mjy_sr_data1)

0 comments on commit d007a4b

Please sign in to comment.