Coverage for tests/test_inject_engine.py: 30%

55 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-02-09 14:08 +0000

1# This file is part of source_injection. 

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 unittest 

23from types import GeneratorType 

24 

25import galsim 

26import lsst.utils.tests 

27import numpy as np 

28from galsim import BoundsI, GSObject 

29from lsst.geom import Point2D, SpherePoint, degrees 

30from lsst.source.injection.inject_engine import ( 

31 generate_galsim_objects, 

32 inject_galsim_objects_into_exposure, 

33 make_galsim_object, 

34) 

35from lsst.source.injection.utils.test_utils import make_test_exposure, make_test_injection_catalog 

36from lsst.utils.tests import MemoryTestCase, TestCase 

37 

38 

39class InjectEngineTestCase(TestCase): 

40 """Test the inject_engine.py module.""" 

41 

42 def setUp(self): 

43 """Set up synthetic source injection inputs. 

44 

45 This method sets up a noisy synthetic image with Gaussian PSFs injected 

46 into the frame, an example source injection catalog, and a generator of 

47 GalSim objects intended for injection. 

48 """ 

49 self.exposure = make_test_exposure() 

50 self.injection_catalog = make_test_injection_catalog( 

51 self.exposure.getWcs(), 

52 self.exposure.getBBox(), 

53 ) 

54 self.galsim_objects = generate_galsim_objects( 

55 injection_catalog=self.injection_catalog, 

56 photo_calib=self.exposure.photoCalib, 

57 wcs=self.exposure.wcs, 

58 fits_alignment="wcs", 

59 stamp_prefix="", 

60 ) 

61 

62 def tearDown(self): 

63 del self.exposure 

64 del self.injection_catalog 

65 del self.galsim_objects 

66 

67 def test_make_galsim_object(self): 

68 source_data = self.injection_catalog[0] 

69 sky_coords = SpherePoint(float(source_data["ra"]), float(source_data["dec"]), degrees) 

70 pixel_coords = self.exposure.wcs.skyToPixel(sky_coords) 

71 inst_flux = self.exposure.photoCalib.magnitudeToInstFlux(source_data["mag"], pixel_coords) 

72 object = make_galsim_object( 

73 source_data=source_data, 

74 source_type=source_data["source_type"], 

75 inst_flux=inst_flux, 

76 ) 

77 self.assertIsInstance(object, GSObject) 

78 self.assertIsInstance(object, getattr(galsim, source_data["source_type"])) 

79 

80 def test_generate_galsim_objects(self): 

81 self.assertTrue(isinstance(self.galsim_objects, GeneratorType)) 

82 for galsim_object in self.galsim_objects: 

83 self.assertIsInstance(galsim_object, tuple) 

84 self.assertEqual(len(galsim_object), 4) 

85 self.assertIsInstance(galsim_object[0], SpherePoint) # RA/Dec 

86 self.assertIsInstance(galsim_object[1], Point2D) # x/y 

87 self.assertIsInstance(galsim_object[2], int) # draw size 

88 self.assertIsInstance(galsim_object[3], GSObject) # GSObject 

89 

90 def test_inject_galsim_objects_into_exposure(self): 

91 flux0 = np.sum(self.exposure.image.array) 

92 injected_outputs = inject_galsim_objects_into_exposure( 

93 exposure=self.exposure, 

94 objects=self.galsim_objects, 

95 mask_plane_name="INJECTED", 

96 calib_flux_radius=12.0, 

97 draw_size_max=1000, 

98 ) 

99 pc = self.exposure.getPhotoCalib() 

100 inst_fluxes = [float(pc.magnitudeToInstFlux(mag)) for mag in self.injection_catalog["mag"]] 

101 self.assertAlmostEqual( 

102 np.sum(self.exposure.image.array) - flux0, 

103 np.sum(inst_fluxes), 

104 delta=0.00015 * np.sum(inst_fluxes), 

105 ) 

106 self.assertEqual(len(injected_outputs[0]), len(self.injection_catalog["ra"])) 

107 self.assertTrue(all(isinstance(injected_output, list) for injected_output in injected_outputs)) 

108 self.assertTrue(all(isinstance(item, int) for item in injected_outputs[0])) # draw sizes 

109 self.assertTrue(all(isinstance(item, BoundsI) for item in injected_outputs[1])) # common bounds 

110 self.assertTrue(all(isinstance(item, bool) for item in injected_outputs[2])) # FFT size errors 

111 self.assertTrue(all(isinstance(item, bool) for item in injected_outputs[3])) # PSF compute errors 

112 

113 

114class MemoryTestCase(MemoryTestCase): 

115 """Test memory usage of functions in this script.""" 

116 

117 pass 

118 

119 

120def setup_module(module): 

121 """Configure pytest.""" 

122 lsst.utils.tests.init() 

123 

124 

125if __name__ == "__main__": 125 ↛ 126line 125 didn't jump to line 126, because the condition on line 125 was never true

126 lsst.utils.tests.init() 

127 unittest.main()