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
Functions | Variables
lsst.ip.diffim.makeKernelBasisList Namespace Reference

Functions

def makeKernelBasisList (config, targetFwhmPix=None, referenceFwhmPix=None, basisDegGauss=None, basisSigmaGauss=None, metadata=None)
 
def generateAlardLuptonBasisList (config, targetFwhmPix=None, referenceFwhmPix=None, basisDegGauss=None, basisSigmaGauss=None, metadata=None)
 

Variables

int sigma2fwhm = 2. * np.sqrt(2. * np.log(2.))
 

Function Documentation

◆ generateAlardLuptonBasisList()

def lsst.ip.diffim.makeKernelBasisList.generateAlardLuptonBasisList (   config,
  targetFwhmPix = None,
  referenceFwhmPix = None,
  basisDegGauss = None,
  basisSigmaGauss = None,
  metadata = None 
)
Generate an Alard-Lupton kernel basis list based upon the Config and
the input FWHM of the science and template images.

Parameters
----------
config : `lsst.ip.diffim.PsfMatchConfigAL`
    Configuration object for the Alard-Lupton algorithm.
targetFwhmPix : `float`, optional
    Fwhm width (pixel) of the template exposure characteristic psf.
    This is the _target_ that will be matched to the science exposure.
referenceFwhmPix : `float`, optional
    Fwhm width (pixel) of the science exposure characteristic psf.
basisDegGauss : `list` of `int`, optional
    Polynomial degree of each Gaussian (sigma) basis. If None, defaults to `config.alardDegGauss`.
basisSigmaGauss : `list` of `int`, optional
    Sigmas of each Gaussian basis. If None, defaults to `config.alardSigGauss`.
metadata : `lsst.daf.base.PropertySet`, optional
    If specified, object to collect metadata fields about the kernel basis list.

Returns
-------
basisList : `list` of `lsst.afw.math.kernel.FixedKernel`
    List of basis kernels. For each degree value ``n`` in ``config.basisDegGauss`` (n+2)(n+1)/2 kernels
    are generated and appended to the list in the order of the polynomial parameter number.
    See `lsst.afw.math.polynomialFunction2D` documentation for more details.

Raises
------
RuntimeError
    - if ``config.kernelBasisSet`` is not equal to "alard-lupton"
ValueError
    - if ``config.kernelSize`` is even
    - if the number of Gaussians and the number of given
      sigma values are not equal or
    - if the number of Gaussians and the number of given
      polynomial degree values are not equal

Notes
-----
The polynomial functions (``f``) are always evaluated in the -1.0, +1.0 range in both x, y directions,
edge to edge, with ``f(0,0)`` evaluated at the kernel center pixel, ``f(-1.0,-1.0)`` at the kernel
``(0,0)`` pixel. They are not scaled by the sigmas of the Gaussians.

Base Gaussian widths (sigmas in pixels) of the kernels are determined as:
    - If not all fwhm parameters are provided or ``config.scaleByFwhm==False``
      then ``basisSigmaGauss`` is used. If ``basisSigmaGauss`` is not
      provided, then ``config.alardSigGauss`` is used. In both cases, the
      length of sigmas must be equal to ``config.alardNGauss``.
    - If ``targetFwhmPix<referenceFwhmPix`` (normal convolution):
      First sigma ``Sig_K`` is determined to satisfy: ``Sig_reference**2 = Sig_target**2 + Sig_K**2``.
      If it's larger than ``config.alardMinSig * config.alardGaussBeta``, make it the
      second kernel. Else make it the smallest kernel, unless only 1 kernel is asked for.
    - If ``referenceFwhmPix < targetFwhmPix`` (deconvolution):
      Define the progression of Gaussians using a
      method to derive a deconvolution sum-of-Gaussians from it's
      convolution counterpart. [1]_ Only use 3 since the algorithm
      assumes 3 components.

**Metadata fields**

ALBasisNGauss : `int`
    The number of base Gaussians in the AL basis functions.
ALBasisDegGauss : `list` of `int`
    Polynomial order of spatial modification of the base Gaussian functions.
ALBasisSigGauss : `list` of `float`
    Sigmas in pixels of the base Gaussians.
ALKernelSize : `int`
    Kernel stamp size is (ALKernelSize pix, ALKernelSize pix).
ALBasisMode : `str`, either of ``config``, ``convolution``, ``deconvolution``
    Indicates whether the config file values, the convolution or deconvolution algorithm
    was used to determine the base Gaussian sigmas and the kernel stamp size.

References
----------
.. [1] Ulmer, W.: Inverse problem of linear combinations of Gaussian convolution kernels
   (deconvolution) and some applications to proton/photon dosimetry and image
   processing. http://iopscience.iop.org/0266-5611/26/8/085002  Equation 40

Definition at line 87 of file makeKernelBasisList.py.

88 basisDegGauss=None, basisSigmaGauss=None, metadata=None):
89 """Generate an Alard-Lupton kernel basis list based upon the Config and
90 the input FWHM of the science and template images.
91
92 Parameters
93 ----------
95 Configuration object for the Alard-Lupton algorithm.
96 targetFwhmPix : `float`, optional
97 Fwhm width (pixel) of the template exposure characteristic psf.
98 This is the _target_ that will be matched to the science exposure.
99 referenceFwhmPix : `float`, optional
100 Fwhm width (pixel) of the science exposure characteristic psf.
101 basisDegGauss : `list` of `int`, optional
102 Polynomial degree of each Gaussian (sigma) basis. If None, defaults to `config.alardDegGauss`.
103 basisSigmaGauss : `list` of `int`, optional
104 Sigmas of each Gaussian basis. If None, defaults to `config.alardSigGauss`.
105 metadata : `lsst.daf.base.PropertySet`, optional
106 If specified, object to collect metadata fields about the kernel basis list.
107
108 Returns
109 -------
110 basisList : `list` of `lsst.afw.math.kernel.FixedKernel`
111 List of basis kernels. For each degree value ``n`` in ``config.basisDegGauss`` (n+2)(n+1)/2 kernels
112 are generated and appended to the list in the order of the polynomial parameter number.
113 See `lsst.afw.math.polynomialFunction2D` documentation for more details.
114
115 Raises
116 ------
117 RuntimeError
118 - if ``config.kernelBasisSet`` is not equal to "alard-lupton"
119 ValueError
120 - if ``config.kernelSize`` is even
121 - if the number of Gaussians and the number of given
122 sigma values are not equal or
123 - if the number of Gaussians and the number of given
124 polynomial degree values are not equal
125
126 Notes
127 -----
128 The polynomial functions (``f``) are always evaluated in the -1.0, +1.0 range in both x, y directions,
129 edge to edge, with ``f(0,0)`` evaluated at the kernel center pixel, ``f(-1.0,-1.0)`` at the kernel
130 ``(0,0)`` pixel. They are not scaled by the sigmas of the Gaussians.
131
132 Base Gaussian widths (sigmas in pixels) of the kernels are determined as:
133 - If not all fwhm parameters are provided or ``config.scaleByFwhm==False``
134 then ``basisSigmaGauss`` is used. If ``basisSigmaGauss`` is not
135 provided, then ``config.alardSigGauss`` is used. In both cases, the
136 length of sigmas must be equal to ``config.alardNGauss``.
137 - If ``targetFwhmPix<referenceFwhmPix`` (normal convolution):
138 First sigma ``Sig_K`` is determined to satisfy: ``Sig_reference**2 = Sig_target**2 + Sig_K**2``.
139 If it's larger than ``config.alardMinSig * config.alardGaussBeta``, make it the
140 second kernel. Else make it the smallest kernel, unless only 1 kernel is asked for.
141 - If ``referenceFwhmPix < targetFwhmPix`` (deconvolution):
142 Define the progression of Gaussians using a
143 method to derive a deconvolution sum-of-Gaussians from it's
144 convolution counterpart. [1]_ Only use 3 since the algorithm
145 assumes 3 components.
146
147 **Metadata fields**
148
149 ALBasisNGauss : `int`
150 The number of base Gaussians in the AL basis functions.
151 ALBasisDegGauss : `list` of `int`
152 Polynomial order of spatial modification of the base Gaussian functions.
153 ALBasisSigGauss : `list` of `float`
154 Sigmas in pixels of the base Gaussians.
155 ALKernelSize : `int`
156 Kernel stamp size is (ALKernelSize pix, ALKernelSize pix).
157 ALBasisMode : `str`, either of ``config``, ``convolution``, ``deconvolution``
158 Indicates whether the config file values, the convolution or deconvolution algorithm
159 was used to determine the base Gaussian sigmas and the kernel stamp size.
160
161 References
162 ----------
163 .. [1] Ulmer, W.: Inverse problem of linear combinations of Gaussian convolution kernels
164 (deconvolution) and some applications to proton/photon dosimetry and image
165 processing. http://iopscience.iop.org/0266-5611/26/8/085002 Equation 40
166 """
167
168 if config.kernelBasisSet != "alard-lupton":
169 raise RuntimeError("Cannot generate %s basis within generateAlardLuptonBasisList" %
170 config.kernelBasisSet)
171
172 kernelSize = config.kernelSize
173 fwhmScaling = config.kernelSizeFwhmScaling
174 basisNGauss = config.alardNGauss
175 basisGaussBeta = config.alardGaussBeta
176 basisMinSigma = config.alardMinSig
177 if basisDegGauss is None:
178 basisDegGauss = config.alardDegGauss
179 if basisSigmaGauss is None:
180 basisSigmaGauss = config.alardSigGauss
181
182 if len(basisDegGauss) != basisNGauss:
183 raise ValueError("len(basisDegGauss) != basisNGauss : %d vs %d" % (len(basisDegGauss), basisNGauss))
184 if len(basisSigmaGauss) != basisNGauss:
185 raise ValueError("len(basisSigmaGauss) != basisNGauss : %d vs %d" %
186 (len(basisSigmaGauss), basisNGauss))
187 if (kernelSize % 2) != 1:
188 raise ValueError("Only odd-sized Alard-Lupton bases allowed")
189
190 logger = getLogger("lsst.ip.diffim.generateAlardLuptonBasisList")
191 if (targetFwhmPix is None) or (referenceFwhmPix is None) or (not config.scaleByFwhm):
192 logger.info("PSF sigmas are not available or scaling by fwhm disabled, "
193 "falling back to config values")
194 if metadata is not None:
195 metadata.add("ALBasisNGauss", basisNGauss)
196 metadata.add("ALBasisDegGauss", basisDegGauss)
197 metadata.add("ALBasisSigGauss", basisSigmaGauss)
198 metadata.add("ALKernelSize", kernelSize)
199 metadata.add("ALBasisMode", "config")
200
201 return diffimLib.makeAlardLuptonBasisList(kernelSize//2, basisNGauss, basisSigmaGauss, basisDegGauss)
202
203 targetSigma = targetFwhmPix / sigma2fwhm
204 referenceSigma = referenceFwhmPix / sigma2fwhm
205 logger.debug("Generating matching bases for sigma %.2f pix -> %.2f pix", targetSigma, referenceSigma)
206
207 # Modify the size of Alard Lupton kernels based upon the images FWHM
208 #
209 # Note the operation is : template.x.kernel = science
210 #
211 # Assuming the template and science image Psfs are Gaussians with
212 # the Fwhm above, Fwhm_T **2 + Fwhm_K **2 = Fwhm_S **2
213 #
214 if targetSigma == referenceSigma:
215 # Leave defaults as-is
216 logger.debug("Target and reference psf fwhms are equal, falling back to config values")
217 basisMode = "config"
218 elif referenceSigma > targetSigma:
219 # Normal convolution
220
221 # First Gaussian has the sigma that comes from the convolution
222 # of two Gaussians : Sig_S**2 = Sig_T**2 + Sig_K**2
223 #
224 # If it's larger than basisMinSigma * basisGaussBeta, make it the
225 # second kernel. Else make it the smallest kernel. Unless
226 # only 1 kernel is asked for.
227 logger.debug("Reference psf fwhm is the greater, normal convolution mode")
228 basisMode = "convolution"
229 kernelSigma = np.sqrt(referenceSigma**2 - targetSigma**2)
230 if kernelSigma < basisMinSigma:
231 kernelSigma = basisMinSigma
232
233 basisSigmaGauss = []
234 if basisNGauss == 1:
235 basisSigmaGauss.append(kernelSigma)
236 nAppended = 1
237 else:
238 if (kernelSigma/basisGaussBeta) > basisMinSigma:
239 basisSigmaGauss.append(kernelSigma/basisGaussBeta)
240 basisSigmaGauss.append(kernelSigma)
241 nAppended = 2
242 else:
243 basisSigmaGauss.append(kernelSigma)
244 nAppended = 1
245
246 # Any other Gaussians above basisNGauss=1 come from a scaling
247 # relationship: Sig_i+1 / Sig_i = basisGaussBeta
248 for i in range(nAppended, basisNGauss):
249 basisSigmaGauss.append(basisSigmaGauss[-1]*basisGaussBeta)
250
251 kernelSize = int(fwhmScaling * basisSigmaGauss[-1])
252 kernelSize += 0 if kernelSize%2 else 1 # Make sure it's odd
253 kernelSize = min(config.kernelSizeMax, max(kernelSize, config.kernelSizeMin))
254
255 else:
256 # Deconvolution; Define the progression of Gaussians using a
257 # method to derive a deconvolution sum-of-Gaussians from it's
258 # convolution counterpart. Only use 3 since the algorithm
259 # assumes 3 components.
260 #
261 # http://iopscience.iop.org/0266-5611/26/8/085002 Equation 40
262
263 # Use specializations for deconvolution
264 logger.debug("Target psf fwhm is the greater, deconvolution mode")
265 basisMode = "deconvolution"
266 basisNGauss = config.alardNGaussDeconv
267 basisMinSigma = config.alardMinSigDeconv
268
269 kernelSigma = np.sqrt(targetSigma**2 - referenceSigma**2)
270 if kernelSigma < basisMinSigma:
271 kernelSigma = basisMinSigma
272
273 basisSigmaGauss = []
274 if (kernelSigma/basisGaussBeta) > basisMinSigma:
275 basisSigmaGauss.append(kernelSigma/basisGaussBeta)
276 basisSigmaGauss.append(kernelSigma)
277 nAppended = 2
278 else:
279 basisSigmaGauss.append(kernelSigma)
280 nAppended = 1
281
282 for i in range(nAppended, basisNGauss):
283 basisSigmaGauss.append(basisSigmaGauss[-1]*basisGaussBeta)
284
285 kernelSize = int(fwhmScaling * basisSigmaGauss[-1])
286 kernelSize += 0 if kernelSize%2 else 1 # Make sure it's odd
287 kernelSize = min(config.kernelSizeMax, max(kernelSize, config.kernelSizeMin))
288
289 # Now build a deconvolution set from these sigmas
290 sig0 = basisSigmaGauss[0]
291 sig1 = basisSigmaGauss[1]
292 sig2 = basisSigmaGauss[2]
293 basisSigmaGauss = []
294 for n in range(1, 3):
295 for j in range(n):
296 sigma2jn = (n - j)*sig1**2
297 sigma2jn += j * sig2**2
298 sigma2jn -= (n + 1)*sig0**2
299 sigmajn = np.sqrt(sigma2jn)
300 basisSigmaGauss.append(sigmajn)
301
302 basisSigmaGauss.sort()
303 basisNGauss = len(basisSigmaGauss)
304 basisDegGauss = [config.alardDegGaussDeconv for x in basisSigmaGauss]
305
306 if metadata is not None:
307 metadata.add("ALBasisNGauss", basisNGauss)
308 metadata.add("ALBasisDegGauss", basisDegGauss)
309 metadata.add("ALBasisSigGauss", basisSigmaGauss)
310 metadata.add("ALKernelSize", kernelSize)
311 metadata.add("ALBasisMode", basisMode)
312
313 logger.debug("basisSigmaGauss: %s basisDegGauss: %s",
314 ','.join(['{:.1f}'.format(v) for v in basisSigmaGauss]),
315 ','.join(['{:d}'.format(v) for v in basisDegGauss]))
316
317 return diffimLib.makeAlardLuptonBasisList(kernelSize//2, basisNGauss, basisSigmaGauss, basisDegGauss)
int min
int max
Class for storing generic metadata.
Definition: PropertySet.h:66
def getLogger(loggername)
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174

◆ makeKernelBasisList()

def lsst.ip.diffim.makeKernelBasisList.makeKernelBasisList (   config,
  targetFwhmPix = None,
  referenceFwhmPix = None,
  basisDegGauss = None,
  basisSigmaGauss = None,
  metadata = None 
)
Generate the delta function or Alard-Lupton kernel bases depending on the Config.
Wrapper to call either `lsst.ip.diffim.makeDeltaFunctionBasisList` or
`lsst.ip.diffim.generateAlardLuptonBasisList`.

Parameters
----------
config : `lsst.ip.diffim.PsfMatchConfigAL`
    Configuration object.
targetFwhmPix : `float`, optional
    Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
    Not used for delta function basis sets.
referenceFwhmPix : `float`, optional
    Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
    Not used for delta function basis sets.
basisDegGauss : `list` of `int`, optional
    Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
    Not used for delta function basis sets.
basisSigmaGauss : `list` of `int`, optional
    Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
    Not used for delta function basis sets.
metadata : `lsst.daf.base.PropertySet`, optional
    Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
    Not used for delta function basis sets.

Returns
-------
basisList: `list` of `lsst.afw.math.kernel.FixedKernel`
    List of basis kernels.

Notes
-----
See `lsst.ip.diffim.generateAlardLuptonBasisList` and
`lsst.ip.diffim.makeDeltaFunctionBasisList` for more information.

Raises
------
ValueError
    If ``config.kernelBasisSet`` has an invalid value (not "alard-lupton" or "delta-function").

Definition at line 33 of file makeKernelBasisList.py.

34 basisDegGauss=None, basisSigmaGauss=None, metadata=None):
35 """Generate the delta function or Alard-Lupton kernel bases depending on the Config.
36 Wrapper to call either `lsst.ip.diffim.makeDeltaFunctionBasisList` or
37 `lsst.ip.diffim.generateAlardLuptonBasisList`.
38
39 Parameters
40 ----------
42 Configuration object.
43 targetFwhmPix : `float`, optional
44 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
45 Not used for delta function basis sets.
46 referenceFwhmPix : `float`, optional
47 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
48 Not used for delta function basis sets.
49 basisDegGauss : `list` of `int`, optional
50 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
51 Not used for delta function basis sets.
52 basisSigmaGauss : `list` of `int`, optional
53 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
54 Not used for delta function basis sets.
55 metadata : `lsst.daf.base.PropertySet`, optional
56 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
57 Not used for delta function basis sets.
58
59 Returns
60 -------
61 basisList: `list` of `lsst.afw.math.kernel.FixedKernel`
62 List of basis kernels.
63
64 Notes
65 -----
66 See `lsst.ip.diffim.generateAlardLuptonBasisList` and
67 `lsst.ip.diffim.makeDeltaFunctionBasisList` for more information.
68
69 Raises
70 ------
71 ValueError
72 If ``config.kernelBasisSet`` has an invalid value (not "alard-lupton" or "delta-function").
73 """
74 if config.kernelBasisSet == "alard-lupton":
75 return generateAlardLuptonBasisList(config, targetFwhmPix=targetFwhmPix,
76 referenceFwhmPix=referenceFwhmPix,
77 basisDegGauss=basisDegGauss,
78 basisSigmaGauss=basisSigmaGauss,
79 metadata=metadata)
80 elif config.kernelBasisSet == "delta-function":
81 kernelSize = config.kernelSize
82 return diffimLib.makeDeltaFunctionBasisList(kernelSize, kernelSize)
83 else:
84 raise ValueError("Cannot generate %s basis set" % (config.kernelBasisSet))
85
86
def generateAlardLuptonBasisList(config, targetFwhmPix=None, referenceFwhmPix=None, basisDegGauss=None, basisSigmaGauss=None, metadata=None)

Variable Documentation

◆ sigma2fwhm

int lsst.ip.diffim.makeKernelBasisList.sigma2fwhm = 2. * np.sqrt(2. * np.log(2.))

Definition at line 30 of file makeKernelBasisList.py.