23 from .astierCovPtcFit
import CovFit
25 __all__ = [
'CovFastFourierTransform']
29 """A class to compute (via FFT) the nearby pixels correlation function.
31 Implements appendix of Astier+19.
36 Image where to calculate the covariances (e.g., the difference image of two flats).
39 Weight image (mask): it should consist of 1's (good pixel) and 0's (bad pixels).
42 2d-tuple with the shape of the FFT
45 Maximum range for the covariances.
48 def __init__(self, diff, w, fftShape, maxRangeCov):
51 assert(fftShape[0] > diff.shape[0]+maxRangeCov+1)
52 assert(fftShape[1] > diff.shape[1]+maxRangeCov+1)
55 if fftShape[1]%2 == 1:
56 fftShape = (fftShape[0], fftShape[1]+1)
57 tIm = np.fft.rfft2(diff*w, fftShape)
58 tMask = np.fft.rfft2(w, fftShape)
60 self.
pCovpCov = np.fft.irfft2(tIm*tIm.conjugate())
62 self.
pMeanpMean = np.fft.irfft2(tIm*tMask.conjugate())
64 self.
pCountpCount = np.fft.irfft2(tMask*tMask.conjugate())
66 def cov(self, dx, dy):
67 """Covariance for dx,dy averaged with dx,-dy if both non zero.
69 Implements appendix of Astier+19.
81 0.5*(cov1+cov2): `float`
82 Covariance at (dx, dy) lag
85 Number of pixels used in covariance calculation.
88 nPix1 = int(round(self.
pCountpCount[dy, dx]))
89 cov1 = self.
pCovpCov[dy, dx]/nPix1-self.
pMeanpMean[dy, dx]*self.
pMeanpMean[-dy, -dx]/(nPix1*nPix1)
90 if (dx == 0
or dy == 0):
92 nPix2 = int(round(self.
pCountpCount[-dy, dx]))
93 cov2 = self.
pCovpCov[-dy, dx]/nPix2-self.
pMeanpMean[-dy, dx]*self.
pMeanpMean[dy, -dx]/(nPix2*nPix2)
94 return 0.5*(cov1+cov2), nPix1+nPix2
97 """Produce a list of tuples with covariances.
99 Implements appendix of Astier+19.
104 Maximum range of covariances.
109 List with covariance tuples.
113 for dy
in range(maxRange+1):
114 for dx
in range(maxRange+1):
115 cov, npix = self.
covcov(dx, dy)
116 if (dx == 0
and dy == 0):
118 tupleVec.append((dx, dy, var, cov, npix))
123 """Compute covariances of diffImage in real space.
125 For lags larger than ~25, it is slower than the FFT way.
126 Taken from https://github.com/PierreAstier/bfptc/
130 diffImage : `numpy.array`
131 Image to compute the covariance of.
133 weightImage : `numpy.array`
134 Weight image of diffImage (1's and 0's for good and bad pixels, respectively).
137 Last index of the covariance to be computed.
142 List with tuples of the form (dx, dy, var, cov, npix), where:
148 Variance at (dx, dy).
150 Covariance at (dx, dy).
152 Number of pixel pairs used to evaluate var and cov.
157 for dy
in range(maxRange + 1):
158 for dx
in range(0, maxRange + 1):
162 cov = 0.5*(cov1 + cov2)
166 if (dx == 0
and dy == 0):
168 outList.append((dx, dy, var, cov, nPix))
174 """Compute covariances of diffImage in real space at lag (dx, dy).
176 Taken from https://github.com/PierreAstier/bfptc/ (c.f., appendix of Astier+19).
180 diffImage : `numpy.array`
181 Image to compute the covariance of.
183 weightImage : `numpy.array`
184 Weight image of diffImage (1's and 0's for good and bad pixels, respectively).
195 Covariance at (dx, dy)
198 Number of pixel pairs used to evaluate var and cov.
200 (nCols, nRows) = diffImage.shape
204 (dx, dy) = (-dx, -dy)
208 im1 = diffImage[dy:, dx:]
209 w1 = weightImage[dy:, dx:]
210 im2 = diffImage[:nCols - dy, :nRows - dx]
211 w2 = weightImage[:nCols - dy, :nRows - dx]
213 im1 = diffImage[:nCols + dy, dx:]
214 w1 = weightImage[:nCols + dy, dx:]
215 im2 = diffImage[-dy:, :nRows - dx]
216 w2 = weightImage[-dy:, :nRows - dx]
222 s1 = im1TimesW.sum()/nPix
223 s2 = (im2*wAll).sum()/nPix
224 p = (im1TimesW*im2).sum()/nPix
231 """ Returns a list of CovFit objects, indexed by amp number.
235 dataset : `lsst.ip.isr.ptcDataset.PhotonTransferCurveDataset`
236 The PTC dataset containing the means, variances, and
242 Dictionary with amps as keys, and CovFit objects as values.
246 for ampName
in dataset.ampNames:
248 if ampName
in dataset.badAmps:
250 maskAtAmp = dataset.expIdMask[ampName]
251 muAtAmp = dataset.rawMeans[ampName]
252 covAtAmp = dataset.covariances[ampName]
253 covSqrtWeightsAtAmp = dataset.covariancesSqrtWeights[ampName]
255 c =
CovFit(muAtAmp, covAtAmp, covSqrtWeightsAtAmp, dataset.covMatrixSide, maskAtAmp)
258 covFitDict[ampName] = cc
264 """Fit data to model in Astier+19 (Eq. 20).
268 dataset : `lsst.ip.isr.ptcDataset.PhotonTransferCurveDataset`
269 The dataset containing the means, (co)variances, and exposure times.
274 Dictionary of CovFit objects, with amp names as keys.
276 covFitNoBDict: `dict`
277 Dictionary of CovFit objects, with amp names as keys (b=0 in Eq. 20 of Astier+19).
281 The parameters of the full model for C_ij(mu) ("C_ij" and "mu" in ADU^2 and ADU, respectively)
282 in Astier+19 (Eq. 20) are:
284 "a" coefficients (r by r matrix), units: 1/e
285 "b" coefficients (r by r matrix), units: 1/e
286 noise matrix (r by r matrix), units: e^2
289 "b" appears in Eq. 20 only through the "ab" combination, which is defined in this code as "c=ab".
294 for ext, c
in covFitDict.items():
296 covFitNoBDict[ext] = c.copy()
297 c.params[
'c'].release()
299 return covFitDict, covFitNoBDict
303 divideByMu=False, returnMasked=False):
304 """Get measured signal and covariance, cov model, weigths, and mask at covariance lag (i, j).
309 Lag for covariance matrix.
312 Lag for covariance matrix.
317 fullCov: `list` of `numpy.array`
318 Measured covariance matrices at each mean signal level in mu.
320 fullCovSqrtWeights: `list` of `numpy.array`
321 List of square root of measured covariances at each mean signal level in mu.
323 fullCovModel : `list` of `numpy.array`
324 List of modeled covariances at each mean signal level in mu.
326 gain : `float`, optional
327 Gain, in e-/ADU. If other than 1.0 (default), the returned quantities will be in
328 electrons or powers of electrons.
330 divideByMu: `bool`, optional
331 Divide returned covariance, model, and weights by the mean signal mu?
333 returnMasked : `bool`, optional
334 Use mask (based on weights) in returned arrays (mu, covariance, and model)?
339 list of signal values at (i, j).
341 covariance : `numpy.array`
342 Covariance at (i, j) at each mean signal mu value (fullCov[:, i, j]).
344 covarianceModel : `numpy.array`
345 Covariance model at (i, j).
347 weights : `numpy.array`
350 maskFromWeights : `numpy.array`, optional
351 Boolean mask of the covariance at (i,j), where the weights differ from 0.
355 This function is a method of the `CovFit` class.
358 fullCov = np.array(fullCov)
359 fullCovModel = np.array(fullCovModel)
360 fullCovSqrtWeights = np.array(fullCovSqrtWeights)
361 covariance = fullCov[:, i, j]*(gain**2)
362 covarianceModel = fullCovModel[:, i, j]*(gain**2)
363 weights = fullCovSqrtWeights[:, i, j]/(gain**2)
365 maskFromWeights = weights != 0
367 weights = weights[maskFromWeights]
368 covarianceModel = covarianceModel[maskFromWeights]
369 mu = mu[maskFromWeights]
370 covariance = covariance[maskFromWeights]
374 covarianceModel /= mu
376 return mu, covariance, covarianceModel, weights, maskFromWeights
def getFitDataFromCovariances(i, j, mu, fullCov, fullCovModel, fullCovSqrtWeights, gain=1.0, divideByMu=False, returnMasked=False)
def fitDataFullCovariance(dataset)
def computeCovDirect(diffImage, weightImage, maxRange)
def covDirectValue(diffImage, weightImage, dx, dy)