LSST Applications g0b6bd0c080+a72a5dd7e6,g1182afd7b4+2a019aa3bb,g17e5ecfddb+2b8207f7de,g1d67935e3f+06cf436103,g38293774b4+ac198e9f13,g396055baef+6a2097e274,g3b44f30a73+6611e0205b,g480783c3b1+98f8679e14,g48ccf36440+89c08d0516,g4b93dc025c+98f8679e14,g5c4744a4d9+a302e8c7f0,g613e996a0d+e1c447f2e0,g6c8d09e9e7+25247a063c,g7271f0639c+98f8679e14,g7a9cd813b8+124095ede6,g9d27549199+a302e8c7f0,ga1cf026fa3+ac198e9f13,ga32aa97882+7403ac30ac,ga786bb30fb+7a139211af,gaa63f70f4e+9994eb9896,gabf319e997+ade567573c,gba47b54d5d+94dc90c3ea,gbec6a3398f+06cf436103,gc6308e37c7+07dd123edb,gc655b1545f+ade567573c,gcc9029db3c+ab229f5caf,gd01420fc67+06cf436103,gd877ba84e5+06cf436103,gdb4cecd868+6f279b5b48,ge2d134c3d5+cc4dbb2e3f,ge448b5faa6+86d1ceac1d,gecc7e12556+98f8679e14,gf3ee170dca+25247a063c,gf4ac96e456+ade567573c,gf9f5ea5b4d+ac198e9f13,gff490e6085+8c2580be5c,w.2022.27
LSST Data Management Base Package
isrQa.py
Go to the documentation of this file.
1# This file is part of ip_isr.
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
23import errno
24
25import lsst.afw.display.rgb as afwRGB
26import lsst.afw.math as afwMath
27import lsst.pex.config as pexConfig
28
29
30class IsrQaFlatnessConfig(pexConfig.Config):
31 meshX = pexConfig.Field(
32 dtype=int,
33 doc="Mesh size in X for flatness statistics",
34 default=256,
35 )
36 meshY = pexConfig.Field(
37 dtype=int,
38 doc="Mesh size in Y for flatness statistics",
39 default=256,
40 )
41 doClip = pexConfig.Field(
42 dtype=bool,
43 doc="Clip outliers for flatness statistics?",
44 default=True,
45 )
46 clipSigma = pexConfig.Field(
47 dtype=float,
48 doc="Number of sigma deviant a pixel must be to be clipped from flatness statistics.",
49 default=3.0,
50 )
51 nIter = pexConfig.Field(
52 dtype=int,
53 doc="Number of iterations used for outlier clipping in flatness statistics.",
54 default=3,
55 )
56
57
58class IsrQaConfig(pexConfig.Config):
59 saveStats = pexConfig.Field(
60 dtype=bool,
61 doc="Calculate ISR statistics while processing?",
62 default=True,
63 )
64
65 flatness = pexConfig.ConfigField(
66 dtype=IsrQaFlatnessConfig,
67 doc="Flatness statistics configuration.",
68 )
69
70 doWriteOss = pexConfig.Field(
71 dtype=bool,
72 doc="Write overscan subtracted image?",
73 default=False,
74 )
75 doThumbnailOss = pexConfig.Field(
76 dtype=bool,
77 doc="Write overscan subtracted thumbnail?",
78 default=False,
79 )
80
81 doWriteFlattened = pexConfig.Field(
82 dtype=bool,
83 doc="Write image after flat-field correction?",
84 default=False,
85 )
86 doThumbnailFlattened = pexConfig.Field(
87 dtype=bool,
88 doc="Write thumbnail after flat-field correction?",
89 default=False,
90 )
91
92 thumbnailBinning = pexConfig.Field(
93 dtype=int,
94 doc="Thumbnail binning factor.",
95 default=4,
96 )
97 thumbnailStdev = pexConfig.Field(
98 dtype=float,
99 doc="Number of sigma below the background to set the thumbnail minimum.",
100 default=3.0,
101 )
102 thumbnailRange = pexConfig.Field(
103 dtype=float,
104 doc="Total range in sigma for thumbnail mapping.",
105 default=5.0,
106 )
107 thumbnailQ = pexConfig.Field(
108 dtype=float,
109 doc="Softening parameter for thumbnail mapping.",
110 default=20.0,
111 )
112 thumbnailSatBorder = pexConfig.Field(
113 dtype=int,
114 doc="Width of border around saturated pixels in thumbnail.",
115 default=2,
116 )
117
118
119def makeThumbnail(exposure, isrQaConfig=None):
120 """Create a snapshot thumbnail from input exposure.
121
122 The output thumbnail image is constructed based on the parameters
123 in the configuration file. Currently, the asinh mapping is the
124 only mapping method used.
125
126 Parameters
127 ----------
128 exposure : `lsst.afw.image.Exposure`
129 The exposure to be converted into a thumbnail.
130 isrQaConfig : `Config`
131 Configuration object containing all parameters to control the
132 thumbnail generation.
133
134 Returns
135 -------
136 rgbImage : `numpy.ndarray`
137 Binned and scaled version of the exposure, converted to an
138 integer array to allow it to be written as PNG.
139 """
140 if isrQaConfig is not None:
141 binning = isrQaConfig.thumbnailBinning
142 binnedImage = afwMath.binImage(exposure.getMaskedImage(), binning, binning, afwMath.MEAN)
143
144 statsCtrl = afwMath.StatisticsControl()
145 statsCtrl.setAndMask(binnedImage.getMask().getPlaneBitMask(["SAT", "BAD", "INTRP"]))
146 stats = afwMath.makeStatistics(binnedImage,
147 afwMath.MEDIAN | afwMath.STDEVCLIP | afwMath.MAX, statsCtrl)
148
149 low = stats.getValue(afwMath.MEDIAN) - isrQaConfig.thumbnailStdev*stats.getValue(afwMath.STDEVCLIP)
150
151 if isrQaConfig.thumbnailSatBorder:
152 afwRGB.replaceSaturatedPixels(binnedImage, binnedImage, binnedImage,
153 isrQaConfig.thumbnailSatBorder, stats.getValue(afwMath.MAX))
154
155 asinhMap = afwRGB.AsinhMapping(low, isrQaConfig.thumbnailRange, Q=isrQaConfig.thumbnailQ)
156 rgbImage = asinhMap.makeRgbImage(binnedImage)
157
158 return rgbImage
159
160
161def writeThumbnail(dataRef, thumb, dataset):
162 """Write snapshot thumbnail to disk.
163
164 Parameters
165 ----------
167 Butler dataref to use to construct the output filename.
168 thumb : `numpy.ndarray`
169 Binned and scaled image to be written as a PNG.
170 dataset : `str`
171 String containing the dataset for this thumbnail.
172
173 Raises
174 ------
175 OSError
176 Raised if the output directory cannot be created and does not
177 exist.
178 """
179 filename = dataRef.get(dataset + "_filename")[0]
180 directory = os.path.dirname(filename)
181 if not os.path.exists(directory):
182 try:
183 os.makedirs(directory)
184 except OSError as e:
185 # Don't fail if directory exists due to race condition.
186 if e.errno != errno.EEXIST:
187 raise e
188 afwRGB.writeRGB(filename, thumb)
A class to contain the data, WCS, and other information needed to describe an image of the sky.
Definition: Exposure.h:72
Pass parameters to a Statistics object.
Definition: Statistics.h:92
Statistics makeStatistics(lsst::afw::image::Image< Pixel > const &img, lsst::afw::image::Mask< image::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl=StatisticsControl())
Handle a watered-down front-end to the constructor (no variance)
Definition: Statistics.h:359
std::shared_ptr< ImageT > binImage(ImageT const &inImage, int const binX, int const binY, lsst::afw::math::Property const flags=lsst::afw::math::MEAN)
Definition: binImage.cc:44
def makeThumbnail(exposure, isrQaConfig=None)
Definition: isrQa.py:119
def writeThumbnail(dataRef, thumb, dataset)
Definition: isrQa.py:161