Coverage for tests / test_componentconfig.py: 22%

55 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-17 08:58 +0000

1# This file is part of multiprofit. 

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 lsst.gauss2d.fit as g2f 

23from lsst.multiprofit.componentconfig import ( 

24 EllipticalComponentConfig, 

25 GaussianComponentConfig, 

26 ParameterConfig, 

27 SersicComponentConfig, 

28 SersicIndexParameterConfig, 

29) 

30from lsst.multiprofit.utils import get_params_uniq, set_config_from_dict 

31import numpy as np 

32import pytest 

33 

34 

35@pytest.fixture(scope="module") 

36def centroid_limits(): 

37 limits = g2f.LimitsD(min=-np.inf, max=np.inf) 

38 return limits 

39 

40 

41@pytest.fixture(scope="module") 

42def centroid(centroid_limits): 

43 cenx = g2f.CentroidXParameterD(0, limits=centroid_limits, fixed=True) 

44 ceny = g2f.CentroidYParameterD(0, limits=centroid_limits, fixed=True) 

45 centroid = g2f.CentroidParameters(cenx, ceny) 

46 return centroid 

47 

48 

49@pytest.fixture(scope="module") 

50def channels(): 

51 return {band: g2f.Channel.get(band) for band in ("R", "G", "B")} 

52 

53 

54def test_EllipticalComponentConfig(): 

55 config = EllipticalComponentConfig() 

56 config2 = EllipticalComponentConfig() 

57 set_config_from_dict(config2, config.toDict()) 

58 assert config == config2 

59 

60 

61def test_GaussianComponentConfig(centroid): 

62 config = GaussianComponentConfig( 

63 rho=ParameterConfig(value_initial=0), 

64 size_x=ParameterConfig(value_initial=1.4), 

65 size_y=ParameterConfig(value_initial=1.6), 

66 ) 

67 channel = g2f.Channel.NONE 

68 component_data1 = config.make_component( 

69 centroid=centroid, 

70 integral_model=g2f.FractionalIntegralModel( 

71 [(channel, g2f.ProperFractionParameterD(0.5, fixed=False))], 

72 model=config.make_linear_integral_model({channel: 1.0}), 

73 ), 

74 ) 

75 component_data2 = config.make_component( 

76 centroid=centroid, 

77 integral_model=g2f.FractionalIntegralModel( 

78 [(channel, g2f.ProperFractionParameterD(1.0, fixed=True))], 

79 model=component_data1.integral_model, 

80 is_final=True, 

81 ), 

82 ) 

83 components = (component_data1, component_data2) 

84 n_components = len(components) 

85 for idx, component_data in enumerate(components): 

86 component = component_data.component 

87 assert component.centroid is centroid 

88 assert len(component_data.priors) == 0 

89 fluxes = list(get_params_uniq(component, nonlinear=False)) 

90 assert len(fluxes) == 1 

91 assert isinstance(fluxes[0], g2f.IntegralParameterD) 

92 fracs = [ 

93 param 

94 for param in get_params_uniq(component, linear=False) 

95 if isinstance(param, g2f.ProperFractionParameterD) 

96 ] 

97 assert len(fracs) == (idx + (idx == 0) - (idx == n_components)) 

98 

99 

100def test_SersicConfig(centroid, channels): 

101 rho, size_x, size_y, sersic_index = -0.3, 1.4, 1.6, 3.2 

102 config = SersicComponentConfig( 

103 rho=ParameterConfig(value_initial=rho), 

104 size_x=ParameterConfig(value_initial=size_x), 

105 size_y=ParameterConfig(value_initial=size_y), 

106 sersic_index=SersicIndexParameterConfig(value_initial=sersic_index), 

107 ) 

108 fluxes = {channel: 1.0 + idx for idx, channel in enumerate(channels.values())} 

109 integral_model = config.make_linear_integral_model(fluxes) 

110 component_data = config.make_component( 

111 centroid=centroid, 

112 integral_model=integral_model, 

113 ) 

114 assert component_data.component is not None 

115 # As long as there's a default Sersic index prior 

116 assert len(component_data.priors) == 1 

117 params = get_params_uniq(component_data.component) 

118 values_init = { 

119 g2f.RhoParameterD: rho, 

120 g2f.ReffXParameterD: size_x, 

121 g2f.ReffYParameterD: size_y, 

122 g2f.SersicIndexParameterD: sersic_index, 

123 } 

124 fluxes_label = { 

125 config.format_label(config.get_integral_label_default(), name_channel=channel.name): fluxes[channel] 

126 for channel in fluxes.keys() 

127 } 

128 for param in params: 

129 if isinstance(param, g2f.IntegralParameterD): 

130 assert fluxes_label[param.label] == param.value 

131 elif value_init := values_init.get(param.__class__): 

132 assert param.value == value_init