def psf_builder(data, masks, shifts, fit_parms, fit_vars, parms): """ Build a psf model by scaling data and using a kernel basis. """ xs = parms.patch_grid[0].ravel()[None, :] + shifts[:, 0, None] ys = parms.patch_grid[1].ravel()[None, :] + shifts[:, 1, None] bkgs = make_background(data, fit_parms, parms.background) scaled = np.abs(data - bkgs) / fit_parms[:, 0][:, None] assert parms.background == 'constant', 'need to generalize for diff bkgs' scaled_vars = (scaled / fit_parms[:, 0][:, None]) ** 2. * \ fit_vars[:, 0, None] scaled_vars += (1. / fit_parms[:, 0][:, None]) ** 2. * fit_vars[:, -1, None] ivars = np.zeros(masks[masks == True].size) values = np.zeros(masks[masks == True].size) masked_xs = np.zeros(masks[masks == True].size) masked_ys = np.zeros(masks[masks == True].size) ind = 0 for i in range(data.shape[0]): chunk = masks[i][masks[i] == 1].size values[ind: ind + chunk] = scaled[i][masks[i]] ivars[ind: ind + chunk] = 1. / scaled_vars[i][masks[i]] masked_xs[ind: ind + chunk] = xs[i][masks[i]] masked_ys[ind: ind + chunk] = ys[i][masks[i]] ind += chunk return binned_model(masked_xs, masked_ys, values, ivars, parms.patch_shape, parms.psf_model_shape)
def one_datum_nll_diff((datum, shift, psf_model, old_nll, fitparms, mask, steps, parms)): """ Calculate the derivative for a single datum using forward differencing. """ # if not enough good pixels, discard patch min_pixels = np.ceil(parms.min_frac * datum.size) if datum[mask].size < min_pixels: return np.zeros_like(psf_model) # background model if parms.background == 'linear': N = np.sqrt(psf_model.size).astype(np.int) x, y = np.meshgrid(range(N), range(N)) A = np.vstack((np.ones_like(psf), np.ones_like(psf), x.ravel(), y.ravel())).T bkg = make_background(datum, A, fitparms, parms.background) elif parms.background == None: bkg = 0.0 else: bkg = fitparms[-1] # calculate the difference in nll, tweaking each psf parm. steps = parms.h * psf_model deriv = np.zeros_like(psf_model) for i in range(parms.psf_model_shape[0]): for j in range(parms.psf_model_shape[1]): temp_psf = psf_model.copy() temp_psf[i, j] += steps[i, j] psf = render_psfs(temp_psf, shift, parms.patch_shape, parms.psf_grid)[0] model = fitparms[0] * psf + bkg diff = eval_nll(datum[mask], model[mask], parms) - old_nll[mask] deriv[i, j] = np.sum(diff) / steps[i, j] return deriv