Coverage for python/lsst/source/injection/inject_coadd.py: 44%
35 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-20 10:20 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-20 10:20 +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/>.
22from __future__ import annotations
24__all__ = ["CoaddInjectConnections", "CoaddInjectConfig", "CoaddInjectTask"]
26import dataclasses
27from typing import cast
29from lsst.pex.config import Field
30from lsst.pipe.base.connectionTypes import Input, Output
32from .inject_base import BaseInjectConfig, BaseInjectConnections, BaseInjectTask
35class CoaddInjectConnections(
36 BaseInjectConnections,
37 dimensions=("skymap", "tract", "patch", "band"),
38 defaultTemplates={
39 "coadd_name": "deep",
40 },
41):
42 """Coadd-level connections for source injection tasks."""
44 input_exposure = Input(
45 doc="Exposure to inject synthetic sources into.",
46 name="{coadd_name}_coadd_predetection",
47 storageClass="ExposureF",
48 dimensions=("skymap", "tract", "patch", "band"),
49 )
50 output_exposure = Output(
51 doc="Injected Exposure.",
52 name="{injected_prefix}{coadd_name}_coadd_predetection",
53 storageClass="ExposureF",
54 dimensions=("skymap", "tract", "patch", "band"),
55 )
56 output_catalog = Output(
57 doc="Catalog of injected sources.",
58 name="{injected_prefix}{coadd_name}_coadd_predetection_catalog",
59 storageClass="ArrowAstropy",
60 dimensions=("skymap", "tract", "patch", "band"),
61 )
63 def __init__(self, *, config: CoaddInjectConfig | None = None):
64 super().__init__(config=config)
66 if not self.config:
67 return
69 if self.config.use_cell_coadds:
70 self.input_exposure = dataclasses.replace(self.input_exposure, storageClass="CellCoadd")
71 self.output_exposure = dataclasses.replace(self.output_exposure, storageClass="CellCoadd")
74class CoaddInjectConfig( # type: ignore [call-arg]
75 BaseInjectConfig,
76 pipelineConnections=CoaddInjectConnections,
77):
78 """Coadd-level configuration for source injection tasks."""
80 use_cell_coadds = Field(dtype=bool, default=False, doc="Whether to use cell coadds?")
83class CoaddInjectTask(BaseInjectTask):
84 """Coadd-level class for injecting sources into images."""
86 _DefaultName = "coaddInjectTask"
87 ConfigClass = CoaddInjectConfig
89 def runQuantum(self, butler_quantum_context, input_refs, output_refs):
90 inputs = butler_quantum_context.get(input_refs)
92 config = cast(self.ConfigClass, self.config)
93 exposure = inputs["input_exposure"]
94 if config.use_cell_coadds:
95 exposure.apply_background(None)
96 else:
97 inputs["psf"] = exposure.getPsf()
98 inputs["photo_calib"] = exposure.getPhotoCalib()
99 inputs["wcs"] = exposure.getWcs()
101 input_keys = ["injection_catalogs", "input_exposure", "sky_map", "psf", "photo_calib", "wcs"]
102 outputs = self.run(**{key: value for (key, value) in inputs.items() if key in input_keys})
103 butler_quantum_context.put(outputs, output_refs)