23 from .astierCovPtcFit
import CovFit
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.
pCov = np.fft.irfft2(tIm*tIm.conjugate())
62 self.
pMean = np.fft.irfft2(tIm*tMask.conjugate())
64 self.
pCount = 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.
pCount[dy, dx]))
89 cov1 = self.
pCov[dy, dx]/nPix1-self.
pMean[dy, dx]*self.
pMean[-dy, -dx]/(nPix1*nPix1)
90 if (dx == 0
or dy == 0):
92 nPix2 = int(round(self.
pCount[-dy, dx]))
93 cov2 = self.
pCov[-dy, dx]/nPix2-self.
pMean[-dy, dx]*self.
pMean[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.
cov(dx, dy)
116 if (dx == 0
and dy == 0):
118 tupleVec.append((dx, dy, var, cov, npix))
123 """Calculate the size fof one dimension for the FFT"""
124 x = int(np.log(s)/np.log(2.))
129 """Compute covariances of diffImage in real space.
131 For lags larger than ~25, it is slower than the FFT way.
132 Taken from https://github.com/PierreAstier/bfptc/
136 diffImage : `numpy.array`
137 Image to compute the covariance of.
139 weightImage : `numpy.array`
140 Weight image of diffImage (1's and 0's for good and bad pixels, respectively).
143 Last index of the covariance to be computed.
148 List with tuples of the form (dx, dy, var, cov, npix), where:
154 Variance at (dx, dy).
156 Covariance at (dx, dy).
158 Number of pixel pairs used to evaluate var and cov.
163 for dy
in range(maxRange + 1):
164 for dx
in range(0, maxRange + 1):
168 cov = 0.5*(cov1 + cov2)
172 if (dx == 0
and dy == 0):
174 outList.append((dx, dy, var, cov, nPix))
180 """Compute covariances of diffImage in real space at lag (dx, dy).
182 Taken from https://github.com/PierreAstier/bfptc/ (c.f., appendix of Astier+19).
186 diffImage : `numpy.array`
187 Image to compute the covariance of.
189 weightImage : `numpy.array`
190 Weight image of diffImage (1's and 0's for good and bad pixels, respectively).
201 Covariance at (dx, dy)
204 Number of pixel pairs used to evaluate var and cov.
206 (nCols, nRows) = diffImage.shape
210 (dx, dy) = (-dx, -dy)
214 im1 = diffImage[dy:, dx:]
215 w1 = weightImage[dy:, dx:]
216 im2 = diffImage[:nCols - dy, :nRows - dx]
217 w2 = weightImage[:nCols - dy, :nRows - dx]
219 im1 = diffImage[:nCols + dy, dx:]
220 w1 = weightImage[:nCols + dy, dx:]
221 im2 = diffImage[-dy:, :nRows - dx]
222 w2 = weightImage[-dy:, :nRows - dx]
228 s1 = im1TimesW.sum()/nPix
229 s2 = (im2*wAll).sum()/nPix
230 p = (im1TimesW*im2).sum()/nPix
238 A class to prepare covariances for the PTC fit.
243 Maximum lag considered (e.g., to eliminate data beyond a separation "r": ignored in the fit).
245 subtractDistantValue: `bool`, optional
246 Subtract a background to the measured covariances (mandatory for HSC flat pairs)?
248 start: `int`, optional
249 Distance beyond which the subtractDistant model is fitted.
252 Polynomial degree for the subtraction model.
256 params = LoadParams(). "params" drives what happens in he fit. LoadParams provides default values.
266 """ Returns a list of CovFit objects, indexed by amp number.
270 tupleName: `numpy.recarray`
271 Recarray with rows with at least ( mu1, mu2, cov ,var, i, j, npix), where:
272 mu1: mean value of flat1
273 mu2: mean value of flat2
274 cov: covariance value at lag (i, j)
275 var: variance (covariance value at lag (0, 0))
278 npix: number of pixels used for covariance calculation.
280 params: `covAstierptcUtil.LoadParams`
281 Object with values to drive the bahaviour of fits.
283 expIdMask : `dict`, [`str`, `list`]
284 Dictionary keyed by amp names containing the masked exposure pairs.
289 Dictionary with amps as keys, and CovFit objects as values.
292 exts = np.array(np.unique(tupleName[
'ampName']), dtype=str)
295 ntext = tupleName[tupleName[
'ampName'] == ext]
296 maskExt = expIdMask[ext]
297 if params.subtractDistantValue:
298 c =
CovFit(ntext, params.r, maskExt)
299 c.subtractDistantOffset(params.r, params.start, params.offsetDegree)
301 c =
CovFit(ntext, params.r, maskExt)
311 """Fit data to models in Astier+19.
315 tupleName: `numpy.recarray`
316 Recarray with rows with at least ( mu1, mu2, cov ,var, i, j, npix), where:
317 mu1: mean value of flat1
318 mu2: mean value of flat2
319 cov: covariance value at lag (i, j)
320 var: variance (covariance value at lag (0, 0))
323 npix: number of pixels used for covariance calculation.
325 expIdMask : `dict`, [`str`, `list`]
326 Dictionary keyed by amp names containing the masked exposure pairs.
329 Maximum lag considered (e.g., to eliminate data beyond a separation "r": ignored in the fit).
334 Dictionary of CovFit objects, with amp names as keys.
336 covFitNoBList: `dict`
337 Dictionary of CovFit objects, with amp names as keys (b=0 in Eq. 20 of Astier+19).
341 The parameters of the full model for C_ij(mu) ("C_ij" and "mu" in ADU^2 and ADU, respectively)
342 in Astier+19 (Eq. 20) are:
344 "a" coefficients (r by r matrix), units: 1/e
345 "b" coefficients (r by r matrix), units: 1/e
346 noise matrix (r by r matrix), units: e^2
349 "b" appears in Eq. 20 only through the "ab" combination, which is defined in this code as "c=ab".
353 lparams.subtractDistantValue =
False
355 covFitList =
loadData(tupleName, lparams, expIdMask=expIdMask)
357 for ext, c
in covFitList.items():
359 covFitNoBList[ext] = c.copy()
360 c.params[
'c'].release()
362 return covFitList, covFitNoBList
366 divideByMu=False, returnMasked=False):
367 """Get measured signal and covariance, cov model, weigths, and mask at covariance lag (i, j).
372 Lag for covariance matrix.
375 Lag for covariance matrix.
380 fullCov: `list` of `numpy.array`
381 Measured covariance matrices at each mean signal level in mu.
383 fullCovSqrtWeights: `list` of `numpy.array`
384 List of square root of measured covariances at each mean signal level in mu.
386 fullCovModel : `list` of `numpy.array`
387 List of modeled covariances at each mean signal level in mu.
389 gain : `float`, optional
390 Gain, in e-/ADU. If other than 1.0 (default), the returned quantities will be in
391 electrons or powers of electrons.
393 divideByMu: `bool`, optional
394 Divide returned covariance, model, and weights by the mean signal mu?
396 returnMasked : `bool`, optional
397 Use mask (based on weights) in returned arrays (mu, covariance, and model)?
402 list of signal values at (i, j).
404 covariance : `numpy.array`
405 Covariance at (i, j) at each mean signal mu value (fullCov[:, i, j]).
407 covarianceModel : `numpy.array`
408 Covariance model at (i, j).
410 weights : `numpy.array`
413 maskFromWeights : `numpy.array`, optional
414 Boolean mask of the covariance at (i,j), where the weights differ from 0.
418 This function is a method of the `CovFit` class.
421 fullCov = np.array(fullCov)
422 fullCovModel = np.array(fullCovModel)
423 fullCovSqrtWeights = np.array(fullCovSqrtWeights)
424 covariance = fullCov[:, i, j]*(gain**2)
425 covarianceModel = fullCovModel[:, i, j]*(gain**2)
426 weights = fullCovSqrtWeights[:, i, j]/(gain**2)
428 maskFromWeights = weights != 0
430 weights = weights[maskFromWeights]
431 covarianceModel = covarianceModel[maskFromWeights]
432 mu = mu[maskFromWeights]
433 covariance = covariance[maskFromWeights]
437 covarianceModel /= mu
439 return mu, covariance, covarianceModel, weights, maskFromWeights