Coverage for tests/test_inject_engine.py: 30%
55 statements
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-20 14:02 +0000
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-20 14:02 +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/>.
22import unittest
23from types import GeneratorType
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
39class InjectEngineTestCase(TestCase):
40 """Test the inject_engine.py module."""
42 def setUp(self):
43 """Set up synthetic source injection inputs.
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 )
62 def tearDown(self):
63 del self.exposure
64 del self.injection_catalog
65 del self.galsim_objects
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"]))
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
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
114class MemoryTestCase(MemoryTestCase):
115 """Test memory usage of functions in this script."""
117 pass
120def setup_module(module):
121 """Configure pytest."""
122 lsst.utils.tests.init()
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()