Skip to content
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 pixel scale factor to metadata and API translation #2752

Merged
merged 9 commits into from
Mar 25, 2024
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):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is probably fine for this PR to demonstrate the translation, but when we connect a switch, we'll want to have the ability to change the entry already loaded in the data-collection (preferably in-place without having to re-parse).

# 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)
Loading