Skip to content

Commit e935491

Browse files
committed
Add multiband catalog tests for PSF matching
1 parent 33b6b30 commit e935491

File tree

1 file changed

+216
-1
lines changed

1 file changed

+216
-1
lines changed

romancal/multiband_catalog/tests/test_multiband_catalog.py

Lines changed: 216 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,17 +95,41 @@ def shared_tests(
9595
library_model.shelve(input_model, modify=False)
9696

9797
assert len(cat.meta["aperture_radii"]["circle_pix"]) > 0
98+
99+
# Check for original (non-PSF-matched) columns
98100
assert sum(
99101
1 for name in cat.colnames if match(r"^aper\d+_f158_flux$", name)
100102
) == len(cat.meta["aperture_radii"]["circle_pix"])
101103
assert sum(
102104
1 for name in cat.colnames if match(r"^aper\d+_f184_flux$", name)
103105
) == len(cat.meta["aperture_radii"]["circle_pix"])
106+
107+
# Check for PSF-matched columns
108+
# Target filter (F184) should NOT have PSF-matched columns
109+
assert sum(
110+
1 for name in cat.colnames if match(r"^aper\d+_f158m_flux$", name)
111+
) == len(cat.meta["aperture_radii"]["circle_pix"])
112+
assert sum(1 for name in cat.colnames if match(r"^aper\d+_f184m_flux$", name)) == 0
104113
assert "ee_fractions" in cat.meta
105114
assert isinstance(cat.meta["ee_fractions"], dict)
115+
# f158, f184 (no PSF-matched bands)
106116
assert len(cat.meta["ee_fractions"]) == 2
117+
118+
# check that sharpness, roundness1, is_extended, and
119+
# fluxfrac_radius_50 columns are not present for matched bands
120+
assert all(
121+
f"{param}_f158m" not in cat.colnames
122+
for param in ["sharpness", "roundness1", "is_extended", "fluxfrac_radius_50"]
123+
)
124+
125+
# Check metadata for PSF match reference filter
126+
assert "psf_match_reference_filter" in cat.meta
127+
assert cat.meta["psf_match_reference_filter"] == "f184"
107128
assert "f158" in cat.meta["ee_fractions"]
108129
assert "f184" in cat.meta["ee_fractions"]
130+
# PSF-matched bands should not have ee_fractions
131+
assert "f158m" not in cat.meta["ee_fractions"]
132+
assert "f184m" not in cat.meta["ee_fractions"]
109133
for value in cat.meta["ee_fractions"].values():
110134
assert len(value) == len(cat.meta["aperture_radii"]["circle_pix"])
111135

@@ -379,7 +403,7 @@ def test_multiband_source_injection_catalog(
379403
result,
380404
cat,
381405
library_model2,
382-
test_multiband_catalog,
406+
save_results,
383407
function_jail,
384408
shape=(5000, 5000),
385409
)
@@ -453,3 +477,194 @@ def test_match_recovered_sources():
453477
# Test columns included or excluded as expected
454478
assert "one" in rec_table.colnames
455479
assert "empty" not in rec_table.colnames
480+
481+
482+
@pytest.fixture
483+
def library_model_three_filters(mosaic_model):
484+
"""
485+
Library with F062, F158, F184.
486+
"""
487+
model1 = mosaic_model.copy()
488+
model1.meta.instrument.optical_element = "F062"
489+
490+
model2 = mosaic_model.copy()
491+
model2.meta.instrument.optical_element = "F158"
492+
493+
model3 = mosaic_model.copy()
494+
model3.meta.instrument.optical_element = "F184"
495+
496+
# input models not in wavelength order to test sorting
497+
return ModelLibrary([model2, model3, model1])
498+
499+
500+
@pytest.mark.parametrize("fit_psf", (True, False))
501+
def test_multiband_catalog_reddest_reference(
502+
library_model_three_filters, fit_psf, function_jail
503+
):
504+
"""
505+
Test PSF matching when reference filter is the reddest.
506+
507+
This tests the case where we have [F062, F158, F184] and F184 is
508+
selected as the reference (longest wavelength). F062 and F158 get
509+
PSF-matched to F184. Because F184 is the reference, no PSF-matched
510+
columns are created for F184.
511+
"""
512+
step = MultibandCatalogStep()
513+
514+
result = step.call(
515+
library_model_three_filters,
516+
bkg_boxsize=50,
517+
snr_threshold=3,
518+
npixels=10,
519+
fit_psf=fit_psf,
520+
deblend=True,
521+
save_results=False,
522+
)
523+
524+
cat = result.source_catalog
525+
assert isinstance(cat, Table)
526+
assert len(cat) == 7
527+
528+
# Check metadata for PSF match reference filter
529+
assert "psf_match_reference_filter" in cat.meta
530+
assert cat.meta["psf_match_reference_filter"] == "f184"
531+
532+
# F062 and F158 should have PSF-matched columns (matched to F184)
533+
assert sum(
534+
1 for name in cat.colnames if match(r"^aper\d+_f062m_flux$", name)
535+
) == len(cat.meta["aperture_radii"]["circle_pix"])
536+
assert sum(
537+
1 for name in cat.colnames if match(r"^aper\d+_f158m_flux$", name)
538+
) == len(cat.meta["aperture_radii"]["circle_pix"])
539+
540+
# F184 (reference) should NOT have PSF-matched columns
541+
assert sum(1 for name in cat.colnames if match(r"^aper\d+_f184m_flux$", name)) == 0
542+
543+
# Check ee_fractions - should have 3 keys: f062, f158, f184 (no
544+
# PSF-matched bands)
545+
assert "ee_fractions" in cat.meta
546+
assert len(cat.meta["ee_fractions"]) == 3
547+
assert "f062" in cat.meta["ee_fractions"]
548+
assert "f158" in cat.meta["ee_fractions"]
549+
assert "f184" in cat.meta["ee_fractions"]
550+
# PSF-matched bands should not have ee_fractions
551+
assert "f062m" not in cat.meta["ee_fractions"]
552+
assert "f158m" not in cat.meta["ee_fractions"]
553+
assert "f184m" not in cat.meta["ee_fractions"]
554+
555+
556+
def test_multiband_catalog_middle_reference(library_model_three_filters, function_jail):
557+
"""
558+
Test PSF matching when reference filter is in the middle.
559+
560+
This tests the case where we have [F062, F158, F184] and F158 is
561+
selected as the reference (middle wavelength). F062 gets normal
562+
PSF-matching (convolved to F158), while F184 gets synthetic
563+
PSF-matching (correction factors). F158 has no PSF-matched columns
564+
as it is the reference.
565+
"""
566+
step = MultibandCatalogStep()
567+
568+
result = step.call(
569+
library_model_three_filters,
570+
bkg_boxsize=50,
571+
snr_threshold=3,
572+
npixels=10,
573+
fit_psf=False,
574+
deblend=True,
575+
reference_filter="F158",
576+
save_results=False,
577+
)
578+
579+
cat = result.source_catalog
580+
assert isinstance(cat, Table)
581+
assert len(cat) == 7
582+
583+
# Check metadata for PSF match reference filter
584+
assert "psf_match_reference_filter" in cat.meta
585+
assert cat.meta["psf_match_reference_filter"] == "f158"
586+
587+
# F062 (bluer) should have PSF-matched columns (normal convolution
588+
# to F158)
589+
assert sum(
590+
1 for name in cat.colnames if match(r"^aper\d+_f062m_flux$", name)
591+
) == len(cat.meta["aperture_radii"]["circle_pix"])
592+
593+
# F158 (reference) should NOT have PSF-matched columns
594+
assert sum(1 for name in cat.colnames if match(r"^aper\d+_f158m_flux$", name)) == 0
595+
596+
# F184 (redder) should have PSF-matched columns (synthetic via
597+
# correction factors)
598+
assert sum(
599+
1 for name in cat.colnames if match(r"^aper\d+_f184m_flux$", name)
600+
) == len(cat.meta["aperture_radii"]["circle_pix"])
601+
602+
# Check ee_fractions - should have 3 keys: f062, f158, f184 (no
603+
# PSF-matched bands)
604+
assert "ee_fractions" in cat.meta
605+
assert len(cat.meta["ee_fractions"]) == 3
606+
assert "f062" in cat.meta["ee_fractions"]
607+
assert "f158" in cat.meta["ee_fractions"]
608+
assert "f184" in cat.meta["ee_fractions"]
609+
# PSF-matched bands should not have ee_fractions
610+
assert "f062m" not in cat.meta["ee_fractions"]
611+
assert "f158m" not in cat.meta["ee_fractions"]
612+
assert "f184m" not in cat.meta["ee_fractions"]
613+
614+
615+
def test_multiband_catalog_bluest_reference(library_model_three_filters, function_jail):
616+
"""
617+
Test PSF matching when reference filter is the bluest.
618+
619+
This tests the case where we have [F062, F158, F184] and F062 is
620+
selected as the reference (shortest wavelength). Both F158 and
621+
F184 get synthetic PSF-matching (correction factors). F062 has no
622+
PSF-matched columns as it is the reference.
623+
"""
624+
step = MultibandCatalogStep()
625+
626+
result = step.call(
627+
library_model_three_filters,
628+
bkg_boxsize=50,
629+
snr_threshold=3,
630+
npixels=10,
631+
fit_psf=False,
632+
deblend=True,
633+
reference_filter="F062",
634+
save_results=False,
635+
)
636+
637+
cat = result.source_catalog
638+
assert isinstance(cat, Table)
639+
assert len(cat) == 7
640+
641+
# Check metadata for PSF match reference filter
642+
assert "psf_match_reference_filter" in cat.meta
643+
assert cat.meta["psf_match_reference_filter"] == "f062"
644+
645+
# F062 (reference) should NOT have PSF-matched columns
646+
assert sum(1 for name in cat.colnames if match(r"^aper\d+_f062m_flux$", name)) == 0
647+
648+
# F158 (redder) should have PSF-matched columns (synthetic via
649+
# correction factors)
650+
assert sum(
651+
1 for name in cat.colnames if match(r"^aper\d+_f158m_flux$", name)
652+
) == len(cat.meta["aperture_radii"]["circle_pix"])
653+
654+
# F184 (reddest) should have PSF-matched columns (synthetic via
655+
# correction factors)
656+
assert sum(
657+
1 for name in cat.colnames if match(r"^aper\d+_f184m_flux$", name)
658+
) == len(cat.meta["aperture_radii"]["circle_pix"])
659+
660+
# Check ee_fractions - should have 3 keys: f062, f158, f184 (no
661+
# PSF-matched bands)
662+
assert "ee_fractions" in cat.meta
663+
assert len(cat.meta["ee_fractions"]) == 3
664+
assert "f062" in cat.meta["ee_fractions"]
665+
assert "f158" in cat.meta["ee_fractions"]
666+
assert "f184" in cat.meta["ee_fractions"]
667+
# PSF-matched bands should not have ee_fractions
668+
assert "f062m" not in cat.meta["ee_fractions"]
669+
assert "f158m" not in cat.meta["ee_fractions"]
670+
assert "f184m" not in cat.meta["ee_fractions"]

0 commit comments

Comments
 (0)