Coverage for tests/test_measure.py: 27%

44 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-03-20 03:40 -0700

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/>. 

21 

22import os 

23 

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 

32 

33 

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 ) 

43 

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

54 

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) 

59 

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) 

77 

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) 

82 

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 ) 

100 

101 blend.conserve_flux(blend) 

102 flux_model = blend.get_model(use_flux=True) 

103 

104 self.assertImageAlmostEqual(flux_model, observation.images, decimal=1)