LSSTApplications  8.0.0.0+107,8.0.0.1+13,9.1+18,9.2,master-g084aeec0a4,master-g0aced2eed8+6,master-g15627eb03c,master-g28afc54ef9,master-g3391ba5ea0,master-g3d0fb8ae5f,master-g4432ae2e89+36,master-g5c3c32f3ec+17,master-g60f1e072bb+1,master-g6a3ac32d1b,master-g76a88a4307+1,master-g7bce1f4e06+57,master-g8ff4092549+31,master-g98e65bf68e,master-ga6b77976b1+53,master-gae20e2b580+3,master-gb584cd3397+53,master-gc5448b162b+1,master-gc54cf9771d,master-gc69578ece6+1,master-gcbf758c456+22,master-gcec1da163f+63,master-gcf15f11bcc,master-gd167108223,master-gf44c96c709
LSSTDataManagementBasePackage
makeKernelBasisList.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008, 2009, 2010 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 import diffimLib
23 import lsst.pex.config as pexConfig
24 import lsst.pex.logging as pexLog
25 import numpy as np
26 sigma2fwhm = 2. * np.sqrt(2. * np.log(2.))
27 
28 def makeKernelBasisList(config, targetFwhmPix=None, referenceFwhmPix=None,
29  basisDegGauss=None, metadata=None):
30  """Generate the appropriate Kernel basis based on the Config"""
31  if config.kernelBasisSet == "alard-lupton":
32  return generateAlardLuptonBasisList(config, targetFwhmPix=targetFwhmPix,
33  referenceFwhmPix=referenceFwhmPix,
34  basisDegGauss=basisDegGauss,
35  metadata=metadata)
36  elif config.kernelBasisSet == "delta-function":
37  kernelSize = config.kernelSize
38  return diffimLib.makeDeltaFunctionBasisList(kernelSize, kernelSize)
39  else:
40  raise ValueError("Cannot generate %s basis set" % (config.kernelBasisSet))
41 
42 def generateAlardLuptonBasisList(config, targetFwhmPix=None, referenceFwhmPix=None,
43  basisDegGauss=None, metadata=None):
44  """Generate an Alard-Lupton kernel basis based upon the Config and
45  the input FWHM of the science and template images"""
46 
47  if config.kernelBasisSet != "alard-lupton":
48  raise RuntimeError("Cannot generate %s basis within generateAlardLuptonBasisList" % config.kernelBasisSet)
49 
50  kernelSize = config.kernelSize
51  fwhmScaling = config.kernelSizeFwhmScaling
52  basisNGauss = config.alardNGauss
53  basisSigmaGauss = config.alardSigGauss
54  basisGaussBeta = config.alardGaussBeta
55  basisMinSigma = config.alardMinSig
56  if basisDegGauss is None:
57  basisDegGauss = config.alardDegGauss
58 
59  if len(basisDegGauss) != basisNGauss:
60  raise ValueError("len(basisDegGauss) != basisNGauss : %d vs %d" % (len(basisDegGauss), basisNGauss))
61  if len(basisSigmaGauss) != basisNGauss:
62  raise ValueError("len(basisSigmaGauss) != basisNGauss : %d vs %d" % (len(basisSigmaGauss), basisNGauss))
63  if (kernelSize % 2) != 1:
64  raise ValueError("Only odd-sized Alard-Lupton bases allowed")
65 
66  if (targetFwhmPix is None) or (referenceFwhmPix is None) or (not config.scaleByFwhm):
67  if metadata is not None:
68  metadata.add("ALBasisNGauss", basisNGauss)
69  metadata.add("ALBasisDegGauss", basisDegGauss)
70  metadata.add("ALBasisSigGauss", basisSigmaGauss)
71  metadata.add("ALKernelSize", kernelSize)
72 
73  return diffimLib.makeAlardLuptonBasisList(kernelSize//2, basisNGauss, basisSigmaGauss, basisDegGauss)
74 
75  targetSigma = targetFwhmPix / sigma2fwhm
76  referenceSigma = referenceFwhmPix / sigma2fwhm
77  pexLog.Trace("lsst.ip.diffim.generateAlardLuptonBasisList", 2,
78  "Generating matching bases for sigma %.2f pix -> %.2f pix" % (targetSigma, referenceSigma))
79 
80  # Modify the size of Alard Lupton kernels based upon the images FWHM
81  #
82  # Note the operation is : template.x.kernel = science
83  #
84  # Assuming the template and science image Psfs are Gaussians with
85  # the Fwhm above, Fwhm_T **2 + Fwhm_K **2 = Fwhm_S **2
86  #
87  if targetSigma == referenceSigma:
88  # Leave defaults as-is
89  pass
90  elif referenceSigma > targetSigma:
91  # Normal convolution
92 
93  # First Gaussian has the sigma that comes from the convolution
94  # of two Gaussians : Sig_S**2 = Sig_T**2 + Sig_K**2
95  #
96  # If it's larger than basisMinSigma * basisGaussBeta, make it the
97  # second kernel. Else make it the smallest kernel. Unless
98  # only 1 kernel is asked for.
99  kernelSigma = np.sqrt(referenceSigma**2 - targetSigma**2)
100  if kernelSigma < basisMinSigma:
101  kernelSigma = basisMinSigma
102 
103  basisSigmaGauss = []
104  if basisNGauss == 1:
105  basisSigmaGauss.append(kernelSigma)
106  nAppended = 1
107  else:
108  if (kernelSigma/basisGaussBeta) > basisMinSigma:
109  basisSigmaGauss.append(kernelSigma/basisGaussBeta)
110  basisSigmaGauss.append(kernelSigma)
111  nAppended = 2
112  else:
113  basisSigmaGauss.append(kernelSigma)
114  nAppended = 1
115 
116  # Any other Gaussians above basisNGauss=1 come from a scaling
117  # relationship: Sig_i+1 / Sig_i = basisGaussBeta
118  for i in range(nAppended,basisNGauss):
119  basisSigmaGauss.append(basisSigmaGauss[-1]*basisGaussBeta)
120 
121  kernelSize = int(fwhmScaling * basisSigmaGauss[-1])
122  kernelSize += 0 if kernelSize%2 else 1 # Make sure it's odd
123  kernelSize = min(config.kernelSizeMax, max(kernelSize, config.kernelSizeMin))
124 
125  else:
126  # Deconvolution; Define the progression of Gaussians using a
127  # method to derive a deconvolution sum-of-Gaussians from it's
128  # convolution counterpart. Only use 3 since the algorithm
129  # assumes 3 components.
130  #
131  # http://iopscience.iop.org/0266-5611/26/8/085002 Equation 40
132 
133  # Use specializations for deconvolution
134  basisNGauss = config.alardNGaussDeconv
135  basisMinSigma = config.alardMinSigDeconv
136 
137  kernelSigma = np.sqrt(targetSigma**2 - referenceSigma**2)
138  if kernelSigma < basisMinSigma:
139  kernelSigma = basisMinSigma
140 
141  basisSigmaGauss = []
142  if (kernelSigma/basisGaussBeta) > basisMinSigma:
143  basisSigmaGauss.append(kernelSigma/basisGaussBeta)
144  basisSigmaGauss.append(kernelSigma)
145  nAppended = 2
146  else:
147  basisSigmaGauss.append(kernelSigma)
148  nAppended = 1
149 
150  for i in range(nAppended,basisNGauss):
151  basisSigmaGauss.append(basisSigmaGauss[-1]*basisGaussBeta)
152 
153  kernelSize = int(fwhmScaling * basisSigmaGauss[-1])
154  kernelSize += 0 if kernelSize%2 else 1 # Make sure it's odd
155  kernelSize = min(config.kernelSizeMax, max(kernelSize, config.kernelSizeMin))
156 
157  # Now build a deconvolution set from these sigmas
158  sig0 = basisSigmaGauss[0]
159  sig1 = basisSigmaGauss[1]
160  sig2 = basisSigmaGauss[2]
161  basisSigmaGauss = []
162  for n in range(1, 3):
163  for j in range(n):
164  sigma2jn = (n - j) * sig1**2
165  sigma2jn += j * sig2**2
166  sigma2jn -= (n + 1) * sig0**2
167  sigmajn = np.sqrt(sigma2jn)
168  basisSigmaGauss.append(sigmajn)
169 
170  basisSigmaGauss.sort()
171  basisNGauss = len(basisSigmaGauss)
172  basisDegGauss = [config.alardDegGaussDeconv for x in basisSigmaGauss]
173 
174  if metadata is not None:
175  metadata.add("ALBasisNGauss", basisNGauss)
176  metadata.add("ALBasisDegGauss", basisDegGauss)
177  metadata.add("ALBasisSigGauss", basisSigmaGauss)
178  metadata.add("ALKernelSize", kernelSize)
179 
180  return diffimLib.makeAlardLuptonBasisList(kernelSize//2, basisNGauss, basisSigmaGauss, basisDegGauss)
181 
limited backward compatibility to the DC2 run-time trace facilities
Definition: Trace.h:93
double min
Definition: attributes.cc:216
double max
Definition: attributes.cc:218