LSST Applications  21.0.0+04719a4bac,21.0.0-1-ga51b5d4+f5e6047307,21.0.0-11-g2b59f77+a9c1acf22d,21.0.0-11-ga42c5b2+86977b0b17,21.0.0-12-gf4ce030+76814010d2,21.0.0-13-g1721dae+760e7a6536,21.0.0-13-g3a573fe+768d78a30a,21.0.0-15-g5a7caf0+f21cbc5713,21.0.0-16-g0fb55c1+b60e2d390c,21.0.0-19-g4cded4ca+71a93a33c0,21.0.0-2-g103fe59+bb20972958,21.0.0-2-g45278ab+04719a4bac,21.0.0-2-g5242d73+3ad5d60fb1,21.0.0-2-g7f82c8f+8babb168e8,21.0.0-2-g8f08a60+06509c8b61,21.0.0-2-g8faa9b5+616205b9df,21.0.0-2-ga326454+8babb168e8,21.0.0-2-gde069b7+5e4aea9c2f,21.0.0-2-gecfae73+1d3a86e577,21.0.0-2-gfc62afb+3ad5d60fb1,21.0.0-25-g1d57be3cd+e73869a214,21.0.0-3-g357aad2+ed88757d29,21.0.0-3-g4a4ce7f+3ad5d60fb1,21.0.0-3-g4be5c26+3ad5d60fb1,21.0.0-3-g65f322c+e0b24896a3,21.0.0-3-g7d9da8d+616205b9df,21.0.0-3-ge02ed75+a9c1acf22d,21.0.0-4-g591bb35+a9c1acf22d,21.0.0-4-g65b4814+b60e2d390c,21.0.0-4-gccdca77+0de219a2bc,21.0.0-4-ge8a399c+6c55c39e83,21.0.0-5-gd00fb1e+05fce91b99,21.0.0-6-gc675373+3ad5d60fb1,21.0.0-64-g1122c245+4fb2b8f86e,21.0.0-7-g04766d7+cd19d05db2,21.0.0-7-gdf92d54+04719a4bac,21.0.0-8-g5674e7b+d1bd76f71f,master-gac4afde19b+a9c1acf22d,w.2021.13
LSST Data Management Base Package
gaussianPsfFactory.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 #
4 # Copyright 2008-2017 AURA/LSST.
5 #
6 # This product includes software developed by the
7 # LSST Project (http://www.lsst.org/).
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 LSST License Statement and
20 # the GNU General Public License along with this program. If not,
21 # see <https://www.lsstcorp.org/LegalNotices/>.
22 #
23 
24 __all__ = ["GaussianPsfFactory", "SigmaPerFwhm"]
25 
26 import math
27 
28 from lsst.pex.config import Config, Field, ConfigurableField
29 from .singleGaussianPsf import SingleGaussianPsf
30 from .doubleGaussianPsf import DoubleGaussianPsf
31 
32 SigmaPerFwhm = 1.0 / (2.0 * math.sqrt(2.0 * math.log(2.0)))
33 
34 
35 def isPositive(x):
36  return x > 0
37 
38 
40  """Factory for simple Gaussian PSF models
41 
42  Provides a high-level interface to DoubleGaussianPsf and SingleGaussianPsf
43  by specifying Gaussian PSF model width in FWHM instead of sigma,
44  and supporting computing kernel size as a multiple of PSF width.
45  This makes it suitable for tasks where PSF width is not known in advance.
46  """
47  size = Field(
48  doc="Kernel size (width and height) (pixels); if None then sizeFactor is used",
49  dtype=int,
50  optional=True,
51  default=None,
52  check=isPositive,
53  )
54  sizeFactor = Field(
55  doc="Kernel size as a factor of fwhm (dimensionless); "
56  "size = sizeFactor * fwhm; ignored if size is not None",
57  dtype=float,
58  optional=False,
59  default=3.0,
60  check=isPositive,
61  )
62  minSize = Field(
63  doc="Minimum kernel size if using sizeFactor (pixels); ignored if size is not None",
64  dtype=int,
65  optional=True,
66  default=5,
67  check=isPositive,
68  )
69  maxSize = Field(
70  doc="Maximum kernel size if using sizeFactor (pixels); ignored if size is not None",
71  dtype=int,
72  optional=True,
73  default=None,
74  check=isPositive,
75  )
76  defaultFwhm = Field(
77  doc="Default FWHM of Gaussian model of core of star (pixels)",
78  dtype=float,
79  default=3.0,
80  check=isPositive,
81  )
82  addWing = Field(
83  doc="Add a Gaussian to represent wings?",
84  dtype=bool,
85  optional=False,
86  default=True,
87  )
88  wingFwhmFactor = Field(
89  doc="wing width, as a multiple of core width (dimensionless); ignored if addWing false",
90  dtype=float,
91  optional=False,
92  default=2.5,
93  check=isPositive,
94  )
95  wingAmplitude = Field(
96  doc="wing amplitude, as a multiple of core amplitude (dimensionless); ignored if addWing false",
97  dtype=float,
98  optional=False,
99  default=0.1,
100  check=isPositive,
101  )
102 
103  def computeSizeAndSigma(self, fwhm=None):
104  """Compute kernel size and star width as sigma. The kernel size will be
105  odd unless minSize or maxSize is used and that value is even. Assumes
106  a valid config.
107 
108  Parameters
109  ----------
110  fwhm : `float`
111  FWHM of core star (pixels); if None then defaultFwhm is used
112 
113  Returns
114  -------
115  size : `int`
116  Kernel size (width == height) in pixels
117  sigma : `float`
118  Sigma equivalent to supplied FWHM, assuming a Gaussian (pixels)
119  """
120  if fwhm is None:
121  fwhm = self.defaultFwhmdefaultFwhm
122 
123  if self.sizesize is not None:
124  size = self.sizesize
125  else:
126  desSize = (int(self.sizeFactorsizeFactor * fwhm) // 2) * 2 + 1 # make result odd
127  if self.minSizeminSize and self.minSizeminSize > desSize:
128  size = self.minSizeminSize
129  elif self.maxSizemaxSize and self.maxSizemaxSize < desSize:
130  size = self.maxSizemaxSize
131  else:
132  size = desSize
133 
134  return size, fwhm * SigmaPerFwhm
135 
136  def validate(self):
137  Config.validate(self)
138  if self.minSizeminSize and self.maxSizemaxSize and self.minSizeminSize > self.maxSizemaxSize:
139  raise RuntimeError("minSize=%s > maxSize=%s" % (self.minSizeminSize, self.maxSizemaxSize))
140 
141  def apply(self, fwhm=None):
142  """Construct a GaussianPsf
143 
144  Parameters
145  ----------
146  fwhm : `float`
147  FWHM of core of star (pixels); if None then self.defaultFwhm is used
148 
149  Returns
150  -------
151  DoubleGaussianPsf : ``lsst.meas.algorithms.DoubleGaussianPsf``
152  Returns if self.addWing is True
153  SingleGaussianPsf : ``lsst.meas.algorithms.SingleGaussianPsf``
154  Returns if self.addWing is False
155  """
156  kernelSize, sigma = self.computeSizeAndSigmacomputeSizeAndSigma(fwhm)
157  if self.addWingaddWing:
158  wingsSigma = sigma * self.wingFwhmFactorwingFwhmFactor
159  return DoubleGaussianPsf(kernelSize, kernelSize, sigma, wingsSigma, self.wingAmplitudewingAmplitude)
160  else:
161  return SingleGaussianPsf(kernelSize, kernelSize, sigma)
162 
163  @classmethod
164  def makeField(cls, doc):
165  """Make an lsst.pex.config.ConfigurableField
166  """
167  def applyWrapper(config, **kwargs):
168  """Construct a Gaussian PSF
169 
170  Parameters
171  ----------
172  config : instance of ``GaussianPsfFactory``
173  """
174  return config.apply(**kwargs)
175  return ConfigurableField(
176  doc=doc,
177  target=applyWrapper,
178  ConfigClass=cls
179  )