def render_patches(self, psf_model, patch_side, flux_range, bkg_range, index, noise_parms, bad_frac): """ Make fake patches using a psf model, include noise, backgrounds, and a range of flux values. """ # center locations, dont allow less than full patches for now buff = (patch_side - 1) / 2 ind = ((self.pixel_rows >= buff) & (self.pixel_rows < self.flat_field.shape[0] - buff) & (self.pixel_cols >= buff) & (self.pixel_cols < self.flat_field.shape[1] - buff)) self.row_centers = self.pixel_rows[ind] self.col_centers = self.pixel_cols[ind] self.N = self.row_centers.size # flux and background defs self.fluxes = self.draw_fluxes(flux_range, index) self.bkgs = np.random.rand(self.N) * (bkg_range[1] - bkg_range[0]) self.bkgs += bkg_range[0] # define subpixel shifts and render psfs self.shifts = np.random.rand(self.N, 2) - 0.5 self.psfs = psf_model.render(self.shifts) # flat map pls = (self.row_centers, self.col_centers) flatmap = FlatMapper(self.flat_field, patch_side, pls) # create data self.data = self.psfs * self.fluxes[:, None] + self.bkgs[:, None] self.true_flats = flatmap.get_1D_flat_patches() self.data *= self.true_flats # does this go here?? self.vars = noise_parms[0] + self.data * noise_parms[1] self.data += (np.random.randn(self.N, patch_side ** 2) * np.sqrt(self.vars)) # make a set of masks to indicate 'bad data' size = self.flat_field.size bf = np.zeros(size, np.bool) Nbad = np.int(np.round(size * bad_frac)) ind = np.random.permutation(size)[:Nbad] bf[ind] = True self.bad_field = bf.reshape(self.flat_field.shape) badmap = FlatMapper(self.bad_field, patch_side, pls) self.masks = badmap.get_1D_flat_patches()
def neg_log_likelihood(self, flat, flxs, bkgs, return_grads=True): """ Return the neg log likelihood of the data. `parms` is an array with the flat, flux, and background parameters appended. """ if self.model_noise: floor, gain = parms[-2:] else: floor, gain = self.floor, self.gain mapper = FlatMapper(flat, self.patch_D, self.patch_locs) flat_patches = mapper.get_1D_flat_patches() # model for the flux, pre-flat incident_model = flxs[:, None] * self.psfs + bkgs[:, None] models = flat_patches * incident_model if self.est_noise: x = self.data else: x = models C = floor + gain * x dmm = self.data - models dmm2 = dmm**2. nll = 0.5 * self.sum(dmm2 / C + np.log(C)) if return_grads: m_grad = self.grad_model(models, dmm, dmm2, 1. / C, gain) flat_grad = self.grad_flat_nll(incident_model, m_grad, mapper.rowinds, mapper.colinds) flux_grad = self.grad_fluxes(flat_patches, self.psfs, m_grad) bkg_grad = self.grad_bkgs(flat_patches, m_grad) return nll, flat_grad, flux_grad, bkg_grad else: return nll, None, None, None
def neg_log_likelihood(self, flat, flxs, bkgs, return_grads=True): """ Return the neg log likelihood of the data. `parms` is an array with the flat, flux, and background parameters appended. """ if self.model_noise: floor, gain = parms[-2:] else: floor, gain = self.floor, self.gain mapper = FlatMapper(flat, self.patch_D, self.patch_locs) flat_patches = mapper.get_1D_flat_patches() # model for the flux, pre-flat incident_model = flxs[:, None] * self.psfs + bkgs[:, None] models = flat_patches * incident_model if self.est_noise: x = self.data else: x = models C = floor + gain * x dmm = self.data - models dmm2 = dmm ** 2. nll = 0.5 * self.sum(dmm2 / C + np.log(C)) if return_grads: m_grad = self.grad_model(models, dmm, dmm2, 1. / C, gain) flat_grad = self.grad_flat_nll(incident_model, m_grad, mapper.rowinds, mapper.colinds) flux_grad = self.grad_fluxes(flat_patches, self.psfs, m_grad) bkg_grad = self.grad_bkgs(flat_patches, m_grad) return nll, flat_grad, flux_grad, bkg_grad else: return nll, None, None, None