lsst.ip.diffim  17.0.1-6-ga5f3de7+12
makeKernelBasisList.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008-2016 LSST Corporation.
4 #
5 # This product includes software developed by the
6 # LSST Project (http://www.lsst.org/).
7 #
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the LSST License Statement and
19 # the GNU General Public License along with this program. If not,
20 # see <http://www.lsstcorp.org/LegalNotices/>.
21 #
22 
23 __all__ = ["makeKernelBasisList", "generateAlardLuptonBasisList"]
24 
25 from . import diffimLib
26 from lsst.log import Log
27 import numpy as np
28 
29 sigma2fwhm = 2. * np.sqrt(2. * np.log(2.))
30 
31 
32 def makeKernelBasisList(config, targetFwhmPix=None, referenceFwhmPix=None,
33  basisDegGauss=None, metadata=None):
34  """Generate the appropriate Kernel basis based on the Config
35 
36  Parameters
37  ----------
38  config : TODO: DM-17458
39  TODO: DM-17458
40  targetFwhmPix : TODO: DM-17458, optional
41  TODO: DM-17458
42  referenceFwhmPix : TODO: DM-17458, optional
43  TODO: DM-17458
44  basisDegGauss : TODO: DM-17458, optional
45  TODO: DM-17458
46  metadata : TODO: DM-17458, optional
47  TODO: DM-17458
48 
49  Returns
50  -------
51  TODO: DM-17458
52  TODO: DM-17458
53 
54  Raises
55  ------
56  ValueError
57  TODO: DM-17458
58  """
59  if config.kernelBasisSet == "alard-lupton":
60  return generateAlardLuptonBasisList(config, targetFwhmPix=targetFwhmPix,
61  referenceFwhmPix=referenceFwhmPix,
62  basisDegGauss=basisDegGauss,
63  metadata=metadata)
64  elif config.kernelBasisSet == "delta-function":
65  kernelSize = config.kernelSize
66  return diffimLib.makeDeltaFunctionBasisList(kernelSize, kernelSize)
67  else:
68  raise ValueError("Cannot generate %s basis set" % (config.kernelBasisSet))
69 
70 
71 def generateAlardLuptonBasisList(config, targetFwhmPix=None, referenceFwhmPix=None,
72  basisDegGauss=None, metadata=None):
73  """Generate an Alard-Lupton kernel basis based upon the Config and
74  the input FWHM of the science and template images
75 
76  Parameters
77  ----------
78  config : TODO: DM-17458
79  TODO: DM-17458
80  targetFwhmPix : `float`, optional
81  TODO: DM-17458
82  referenceFwhmPix : `float`, optional
83  TODO: DM-17458
84  basisDegGauss : TODO: DM-17458, optional
85  TODO: DM-17458
86  metadata : TODO: DM-17458, optional
87  TODO: DM-17458
88 
89  Returns
90  -------
91  TYPE
92  TODO: DM-17458
93 
94  Raises
95  ------
96  RuntimeError
97  TODO: DM-17458
98  ValueError
99  TODO: DM-17458
100  """
101 
102  if config.kernelBasisSet != "alard-lupton":
103  raise RuntimeError("Cannot generate %s basis within generateAlardLuptonBasisList" %
104  config.kernelBasisSet)
105 
106  kernelSize = config.kernelSize
107  fwhmScaling = config.kernelSizeFwhmScaling
108  basisNGauss = config.alardNGauss
109  basisSigmaGauss = config.alardSigGauss
110  basisGaussBeta = config.alardGaussBeta
111  basisMinSigma = config.alardMinSig
112  if basisDegGauss is None:
113  basisDegGauss = config.alardDegGauss
114 
115  if len(basisDegGauss) != basisNGauss:
116  raise ValueError("len(basisDegGauss) != basisNGauss : %d vs %d" % (len(basisDegGauss), basisNGauss))
117  if len(basisSigmaGauss) != basisNGauss:
118  raise ValueError("len(basisSigmaGauss) != basisNGauss : %d vs %d" %
119  (len(basisSigmaGauss), basisNGauss))
120  if (kernelSize % 2) != 1:
121  raise ValueError("Only odd-sized Alard-Lupton bases allowed")
122 
123  if (targetFwhmPix is None) or (referenceFwhmPix is None) or (not config.scaleByFwhm):
124  if metadata is not None:
125  metadata.add("ALBasisNGauss", basisNGauss)
126  metadata.add("ALBasisDegGauss", basisDegGauss)
127  metadata.add("ALBasisSigGauss", basisSigmaGauss)
128  metadata.add("ALKernelSize", kernelSize)
129 
130  return diffimLib.makeAlardLuptonBasisList(kernelSize//2, basisNGauss, basisSigmaGauss, basisDegGauss)
131 
132  targetSigma = targetFwhmPix / sigma2fwhm
133  referenceSigma = referenceFwhmPix / sigma2fwhm
134  logger = Log.getLogger("lsst.ip.diffim.generateAlardLuptonBasisList")
135  logger.debug("Generating matching bases for sigma %.2f pix -> %.2f pix", targetSigma, referenceSigma)
136 
137  # Modify the size of Alard Lupton kernels based upon the images FWHM
138  #
139  # Note the operation is : template.x.kernel = science
140  #
141  # Assuming the template and science image Psfs are Gaussians with
142  # the Fwhm above, Fwhm_T **2 + Fwhm_K **2 = Fwhm_S **2
143  #
144  if targetSigma == referenceSigma:
145  # Leave defaults as-is
146  pass
147  elif referenceSigma > targetSigma:
148  # Normal convolution
149 
150  # First Gaussian has the sigma that comes from the convolution
151  # of two Gaussians : Sig_S**2 = Sig_T**2 + Sig_K**2
152  #
153  # If it's larger than basisMinSigma * basisGaussBeta, make it the
154  # second kernel. Else make it the smallest kernel. Unless
155  # only 1 kernel is asked for.
156  kernelSigma = np.sqrt(referenceSigma**2 - targetSigma**2)
157  if kernelSigma < basisMinSigma:
158  kernelSigma = basisMinSigma
159 
160  basisSigmaGauss = []
161  if basisNGauss == 1:
162  basisSigmaGauss.append(kernelSigma)
163  nAppended = 1
164  else:
165  if (kernelSigma/basisGaussBeta) > basisMinSigma:
166  basisSigmaGauss.append(kernelSigma/basisGaussBeta)
167  basisSigmaGauss.append(kernelSigma)
168  nAppended = 2
169  else:
170  basisSigmaGauss.append(kernelSigma)
171  nAppended = 1
172 
173  # Any other Gaussians above basisNGauss=1 come from a scaling
174  # relationship: Sig_i+1 / Sig_i = basisGaussBeta
175  for i in range(nAppended, basisNGauss):
176  basisSigmaGauss.append(basisSigmaGauss[-1]*basisGaussBeta)
177 
178  kernelSize = int(fwhmScaling * basisSigmaGauss[-1])
179  kernelSize += 0 if kernelSize%2 else 1 # Make sure it's odd
180  kernelSize = min(config.kernelSizeMax, max(kernelSize, config.kernelSizeMin))
181 
182  else:
183  # Deconvolution; Define the progression of Gaussians using a
184  # method to derive a deconvolution sum-of-Gaussians from it's
185  # convolution counterpart. Only use 3 since the algorithm
186  # assumes 3 components.
187  #
188  # http://iopscience.iop.org/0266-5611/26/8/085002 Equation 40
189 
190  # Use specializations for deconvolution
191  basisNGauss = config.alardNGaussDeconv
192  basisMinSigma = config.alardMinSigDeconv
193 
194  kernelSigma = np.sqrt(targetSigma**2 - referenceSigma**2)
195  if kernelSigma < basisMinSigma:
196  kernelSigma = basisMinSigma
197 
198  basisSigmaGauss = []
199  if (kernelSigma/basisGaussBeta) > basisMinSigma:
200  basisSigmaGauss.append(kernelSigma/basisGaussBeta)
201  basisSigmaGauss.append(kernelSigma)
202  nAppended = 2
203  else:
204  basisSigmaGauss.append(kernelSigma)
205  nAppended = 1
206 
207  for i in range(nAppended, basisNGauss):
208  basisSigmaGauss.append(basisSigmaGauss[-1]*basisGaussBeta)
209 
210  kernelSize = int(fwhmScaling * basisSigmaGauss[-1])
211  kernelSize += 0 if kernelSize%2 else 1 # Make sure it's odd
212  kernelSize = min(config.kernelSizeMax, max(kernelSize, config.kernelSizeMin))
213 
214  # Now build a deconvolution set from these sigmas
215  sig0 = basisSigmaGauss[0]
216  sig1 = basisSigmaGauss[1]
217  sig2 = basisSigmaGauss[2]
218  basisSigmaGauss = []
219  for n in range(1, 3):
220  for j in range(n):
221  sigma2jn = (n - j)*sig1**2
222  sigma2jn += j * sig2**2
223  sigma2jn -= (n + 1)*sig0**2
224  sigmajn = np.sqrt(sigma2jn)
225  basisSigmaGauss.append(sigmajn)
226 
227  basisSigmaGauss.sort()
228  basisNGauss = len(basisSigmaGauss)
229  basisDegGauss = [config.alardDegGaussDeconv for x in basisSigmaGauss]
230 
231  if metadata is not None:
232  metadata.add("ALBasisNGauss", basisNGauss)
233  metadata.add("ALBasisDegGauss", basisDegGauss)
234  metadata.add("ALBasisSigGauss", basisSigmaGauss)
235  metadata.add("ALKernelSize", kernelSize)
236 
237  return diffimLib.makeAlardLuptonBasisList(kernelSize//2, basisNGauss, basisSigmaGauss, basisDegGauss)
def makeKernelBasisList(config, targetFwhmPix=None, referenceFwhmPix=None, basisDegGauss=None, metadata=None)
def generateAlardLuptonBasisList(config, targetFwhmPix=None, referenceFwhmPix=None, basisDegGauss=None, metadata=None)