Coverage for tests/test_measure.py: 27%
44 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-19 10:38 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-19 10:38 +0000
1# This file is part of lsst.scarlet.lite.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
22import os
24import numpy as np
25from lsst.scarlet.lite import Blend, Image, Observation, Source, io
26from lsst.scarlet.lite.component import default_adaprox_parameterization
27from lsst.scarlet.lite.initialization import FactorizedChi2Initialization
28from lsst.scarlet.lite.measure import calculate_snr
29from lsst.scarlet.lite.operators import Monotonicity
30from lsst.scarlet.lite.utils import integrated_circular_gaussian
31from utils import ScarletTestCase
34class TestMeasurements(ScarletTestCase):
35 def test_snr(self):
36 psfs = np.array(
37 [
38 integrated_circular_gaussian(sigma=1.0),
39 integrated_circular_gaussian(sigma=0.85),
40 integrated_circular_gaussian(sigma=1.8),
41 ]
42 )
44 bands = tuple("gri")
45 images = np.zeros((3, 51, 51), dtype=float)
46 images[:, 20:35, 10:25] = psfs * np.arange(1, 4)[:, None, None]
47 images = Image(images, bands=bands)
48 variance = np.zeros(images.shape, dtype=images.dtype)
49 variance[0] = 0.2
50 variance[1] = 0.1
51 variance[2] = 0.05
52 variance = Image(variance, bands=bands)
53 snr = calculate_snr(images, variance, psfs, (27, 17))
55 numerator = np.sum(images.data[:, 20:35, 10:25] * psfs)
56 denominator = np.sqrt(np.sum(psfs**2 * np.array([0.2, 0.1, 0.05])[:, None, None]))
57 truth = numerator / denominator
58 self.assertAlmostEqual(snr, truth)
60 def test_conserve_flux(self):
61 filename = os.path.join(__file__, "..", "..", "data", "hsc_cosmos_35.npz")
62 filename = os.path.abspath(filename)
63 data = np.load(filename)
64 model_psf = integrated_circular_gaussian(sigma=0.8)
65 centers = tuple(np.array([data["catalog"]["y"], data["catalog"]["x"]]).T.astype(int))
66 bands = data["filters"]
67 observation = Observation(
68 Image(data["images"], bands=bands),
69 Image(data["variance"], bands=bands),
70 Image(1 / data["variance"], bands=bands),
71 data["psfs"],
72 model_psf[None],
73 bands=bands,
74 )
75 monotonicity = Monotonicity((101, 101))
76 init = FactorizedChi2Initialization(observation, centers, monotonicity=monotonicity)
78 blend = Blend(init.sources, observation).fit_spectra()
79 blend.sources.append(Source([]))
80 blend.parameterize(default_adaprox_parameterization)
81 blend.fit(100, e_rel=1e-4)
83 # Insert a flat source to pickup the background flux
84 blend.sources.append(
85 Source(
86 [
87 io.ComponentCube(
88 bands=observation.bands,
89 bbox=observation.bbox,
90 model=Image(
91 np.ones(observation.shape, dtype=observation.dtype),
92 observation.bands,
93 yx0=(0, 0),
94 ),
95 peak=(0, 0),
96 )
97 ]
98 )
99 )
101 blend.conserve_flux(blend)
102 flux_model = blend.get_model(use_flux=True)
104 self.assertImageAlmostEqual(flux_model, observation.images, decimal=1)