Skip to content

Commit 2f0cb5a

Browse files
emolterzacharyburnett
authored andcommitted
JP-4161: Fix SourceCatalogStep fluxes failing to convert from Mjy/sr to Jy (#9939)
1 parent 0c53afc commit 2f0cb5a

File tree

4 files changed

+40
-24
lines changed

4 files changed

+40
-24
lines changed

changes/9939.source_catalog.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a bug where fluxes were not being converted from Mjy/sr to Jy.
2+
Fix a bug where fluxes included background flux when they shouldn't.

jwst/source_catalog/source_catalog_step.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ def process(self, input_model):
104104

105105
coverage_mask = np.isnan(model.err) | (model.wht == 0)
106106

107+
# convert to Jy before calling make_tweakreg_catalog so the outputs end up in Jy
108+
JWSTSourceCatalog.convert_mjysr_to_jy(model)
109+
107110
starfinder_kwargs = {
108111
"sigma_radius": self.sigma_radius,
109112
"minsep_fwhm": self.minsep_fwhm,
@@ -139,7 +142,6 @@ def process(self, input_model):
139142
log.warning("No sources found in the image. Catalog will be empty.")
140143
return None
141144

142-
JWSTSourceCatalog.convert_mjysr_to_jy(model)
143145
ci_star_thresholds = (self.ci1_star_threshold, self.ci2_star_threshold)
144146
catobj = JWSTSourceCatalog(
145147
model,

jwst/source_catalog/tests/test_source_catalog.py

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import numpy as np
44
import pytest
55
import stdatamodels.jwst.datamodels as dm
6+
from astropy.modeling import models
67
from astropy.table import QTable
78
from numpy.testing import assert_allclose
89
from photutils.datasets import make_gwcs
@@ -29,7 +30,7 @@ def nircam_model():
2930
model = dm.ImageModel(data, wht=wht, err=err)
3031
model.meta.bunit_data = "MJy/sr"
3132
model.meta.bunit_err = "MJy/sr"
32-
model.meta.photometry.pixelarea_steradians = 1.0
33+
model.meta.photometry.pixelarea_steradians = 1.0e-13
3334
model.meta.wcs = make_gwcs(data.shape)
3435
model.meta.wcsinfo = {
3536
"ctype1": "RA---TAN",
@@ -80,7 +81,7 @@ def nircam_model_without_apcorr():
8081
model = dm.ImageModel(data, wht=wht, err=err)
8182
model.meta.bunit_data = "MJy/sr"
8283
model.meta.bunit_err = "MJy/sr"
83-
model.meta.photometry.pixelarea_steradians = 1.0
84+
model.meta.photometry.pixelarea_steradians = 1.0e-13
8485
model.meta.wcs = make_gwcs(data.shape)
8586
model.meta.wcsinfo = {
8687
"ctype1": "RA---TAN",
@@ -130,20 +131,22 @@ def test_source_catalog(nircam_model, npixels, nsources):
130131

131132
if npixels == 5 and nsources == 2:
132133
# test values of some specific computed quantities
133-
assert np.isclose(cat["xcentroid"][1], 19.46399720865899)
134-
assert np.isclose(cat["ycentroid"][1], 41.95288393407728)
135-
assert np.isclose(cat["aper_bkg_flux"][1].value, 1400000.0)
136-
assert np.isclose(cat["aper_bkg_flux_err"][1].value, 85223.70700074881)
137-
assert np.isclose(cat["CI_50_30"][1], 2.3342599432074653)
134+
assert np.isclose(cat["xcentroid"][1], 19.453064764431833)
135+
assert np.isclose(cat["ycentroid"][1], 41.963065678485115)
136+
assert np.isclose(cat["aper_bkg_flux"][1].value, 1.40e-7)
137+
assert np.isclose(cat["aper_bkg_flux_err"][1].value, 8.52237054e-09)
138+
assert np.isclose(cat["CI_50_30"][1], 2.352272196434725)
138139
assert np.isclose(cat["sharpness"][1], 0.9102634628764403)
139140
assert np.isclose(cat["roundness"][1], 1.5954264)
140-
assert np.isclose(cat["nn_dist"][1].value, 53.0737632103816)
141-
assert np.isclose(cat["isophotal_flux"][1], 930.9999841451645)
142-
assert np.isclose(cat["isophotal_flux_err"][1], 3.6102633)
143-
assert np.isclose(cat["semimajor_sigma"][1].value, 18.847635525516534)
144-
assert np.isclose(cat["semiminor_sigma"][1].value, 7.031371175038476)
145-
assert np.isclose(cat["ellipticity"][1], 0.626936165784871)
146-
assert np.isclose(cat["orientation"][1].value, -72.75413766990114)
141+
assert np.isclose(cat["nn_dist"][1].value, 53.07168773319497)
142+
assert np.isclose(cat["isophotal_flux"][1].value, 7.940753383195442e-05)
143+
assert cat["isophotal_flux_err"][1].unit == "Jy"
144+
assert np.isclose(cat["isophotal_flux_err"][1].value, 3.6102634e-07)
145+
assert np.isclose(cat["isophotal_abmag"][1], 19.150345729246215)
146+
assert np.isclose(cat["semimajor_sigma"][1].value, 18.84372169911978)
147+
assert np.isclose(cat["semiminor_sigma"][1].value, 7.024931388267103)
148+
assert np.isclose(cat["ellipticity"][1].value, 0.62720043)
149+
assert np.isclose(cat["orientation"][1].value, -72.78329207140818)
147150

148151

149152
def test_source_catalog_no_sources(nircam_model, monkeypatch):
@@ -191,14 +194,20 @@ def test_source_catalog_point_sources(finder, nircam_model, tmp_cwd):
191194
"""Test the three source finding algorithms with point sources."""
192195
data = np.random.default_rng(seed=123).normal(0, 0.5, size=(101, 101))
193196

194-
# make a point source with some size that looks a bit like a psf, no need to be realistic
195-
point_source = np.ones((7, 7))
196-
point_source[1:6, 1:6] = 3.0
197-
point_source[2:5, 2:5] = 5.0
198-
point_source[3, 3] = 10.0
197+
# Create coordinate grids for Airy disk models
198+
y, x = np.mgrid[0:101, 0:101]
199199

200-
data[30:37, 30:37] = point_source
201-
data[70:77, 70:77] = point_source
200+
# Create two Airy disk point sources
201+
# First source at position (33, 33)
202+
airy1 = models.AiryDisk2D(amplitude=10.0, x_0=33, y_0=33, radius=5.0)
203+
source1 = airy1(x, y)
204+
205+
# Second source at position (73, 73)
206+
airy2 = models.AiryDisk2D(amplitude=10.0, x_0=73, y_0=73, radius=5.0)
207+
source2 = airy2(x, y)
208+
209+
# Add the sources to the background
210+
data += source1 + source2
202211

203212
nircam_model.data = data
204213

@@ -210,6 +219,8 @@ def test_source_catalog_point_sources(finder, nircam_model, tmp_cwd):
210219
npixels=5,
211220
bkg_boxsize=50,
212221
kernel_fwhm=2.0,
222+
roundlo=-1.0,
223+
sharplo=0.0,
213224
starfinder=finder,
214225
save_results=True,
215226
)

jwst/tweakreg/tweakreg_catalog.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,8 @@ def make_tweakreg_catalog(
412412
with warnings.catch_warnings():
413413
# suppress warning about NaNs being automatically masked - this is desired
414414
warnings.simplefilter("ignore", AstropyUserWarning)
415-
threshold_img = bkg.background + (snr_threshold * bkg.background_rms)
415+
threshold_img = snr_threshold * bkg.background_rms
416+
data = model.data - bkg.background
416417
except ValueError as e:
417418
log.warning(f"Error determining sky background: {e.args[0]}")
418419
sources = _empty_table()
@@ -425,7 +426,7 @@ def make_tweakreg_catalog(
425426
"ignore", category=NoDetectionsWarning, message="No sources were found"
426427
)
427428
sources, segmentation_image = starfinder(
428-
model.data,
429+
data,
429430
threshold_img,
430431
kernel_fwhm,
431432
mask=coverage_mask,

0 commit comments

Comments
 (0)