def loadModel(self, model_file): if not path.exists(model_file): logger.warn('Initial model file not found (%s), guessing one. ' % model_file) x0 = (self.flux.shape[1] / 2.0) + 1.0 y0 = (self.flux.shape[0] / 2.0) + 1.0 pa, ell = ellipse_params(self.flux, x0, y0) r = distance(self.flux.shape, x0, y0, pa, ell) r = np.ma.array(r, mask=self.flux.mask) hlr = r50(self.flux, r) I_e = self.flux.max() * 0.1 r_e = 0.5 * hlr n = 2.0 I_0 = self.flux.max() * 0.1 h = 1.0 * hlr model = BDModel() model.wl = 5635.0 model.x0.setValue(x0) model.x0.setLimitsRel(10, 10) model.y0.setValue(y0) model.y0.setLimitsRel(10, 10) model.disk.I_0.setValue(I_0) model.disk.I_0.setLimits(0.0, 10.0 * I_0) model.disk.h.setValue(h) model.disk.h.setLimits(0.0, 5.0 * hlr) model.disk.PA.setValue(pa) model.disk.PA.setLimits(0.0, 180.0) model.disk.ell.setValue(ell) model.disk.ell.setLimits(0.0, 1.0) model.bulge.I_e.setValue(I_e) model.bulge.I_e.setLimits(1e-33, 3.0 * I_e) model.bulge.r_e.setValue(r_e) model.bulge.r_e.setLimits(1e-33, 2.5 * r_e) model.bulge.n.setValue(n, vmin=1.0, vmax=5.0) model.bulge.PA.setValue(pa) model.bulge.PA.setLimits(0.0, 180.0) model.bulge.ell.setValue(ell) model.bulge.ell.setLimits(0.0, 1.0) return model else: return BDModel.load(model_file)
print 'Fitting %s profiles' % func cubes = glob('../images.calibration/*.g.fits') fitradius = 30 sigma2fwhm = 2.0 * np.sqrt(2.0 * np.log(2.0)) debug = True flux = [] for cube in cubes: f = pyfits.open(cube) shape = f[0].data.shape _mask = f[0].data <= 0 _flux = np.ma.array(f[0].data, mask=_mask) y0, x0 = np.where(_flux == _flux.max()) r = distance(shape, x0, y0) _flux[r > fitradius] = np.ma.masked y0 = shape[0] / 2 _flux /= _flux.max() flux.append(_flux) f.close() psf_func = function_description(func, name='psf') psf_func.PA.setValue(60, vmin=-190, vmax=190) psf_func.ell.setValue(0.2, vmin=-1.0, vmax=1.0) psf_func.I_0.setValue(1.0, vmin=1e-20, vmax=10.0) if func == 'Gaussian': psf_func.sigma.setValue(1.0, vmin=0.1, vmax=20.0) else: psf_func.fwhm.setValue(2.5, vmin=0.1, vmax=20.0) if func == 'Moffat':
pa = (90.0 + initial_model.disk.PA.value) * np.pi / 180.0 ba = 1.0 - initial_model.disk.ell.value disk_error = fitted_disk_ifs * flux_unit / disk_ifs disk_error_mean = np.mean(disk_error) disk_error_std = np.std(disk_error) print 'Disk error: %.4f +- %.4f' % (disk_error_mean, disk_error_std) disk_error_r = radialProfile(disk_error, bins, norm_x0, norm_y0, pa, ba, rad_scale=1.0) disk_error_min, disk_error_max = np.percentile(disk_error_r, (5, 95)) disk_error_mean = np.mean(disk_error_r) disk_error_std = np.std(disk_error_r) pa = (90.0 + initial_model.bulge.PA.value) * np.pi / 180.0 ba = 1.0 - initial_model.bulge.ell.value bulge_bins = np.arange(0.0, initial_model.bulge.r_e.value * 2.5 + 1.0) bulge_error = fitted_bulge_ifs * flux_unit / bulge_ifs good_bulge = distance(total_im.shape, norm_x0, norm_y0, pa, ba) < (initial_model.bulge.r_e.value * 2.5) print bulge_error.shape bulge_error_mean = np.mean(bulge_error[:, good_bulge]) bulge_error_std = np.std(bulge_error[:, good_bulge]) print 'bulge error: %.4f +- %.4f' % (bulge_error_mean, bulge_error_std) bulge_error_r = radialProfile(bulge_error, bulge_bins, norm_x0, norm_y0, pa, ba, rad_scale=1.0) bulge_error_min, bulge_error_max = np.percentile(bulge_error_r, (5, 95)) bulge_error_mean = np.mean(bulge_error_r) bulge_error_std = np.std(bulge_error_r) error_range = np.abs(1.0 - np.array([bulge_error_min, bulge_error_max, disk_error_min, disk_error_max])).max() vmin = 1.0 - error_range vmax = 1.0 + error_range ax = plt.subplot(gs[2, 0]) im = ax.pcolormesh(bulge_bins, wl, bulge_error_r, vmin=vmin, vmax=vmax, cmap='RdBu')
########## ########## Morphology model setup ########## ################################################################################ logger.info('Creating original B-D models.') norm_model = get_model(args.trueModel, with_default=True) model_deriv = np.array(get_model(args.trueModelDeriv).getParams(), dtype=norm_model.dtype) original_models = linear_model(norm_model, model_deriv, l_ssp) logger.info('Original model at normalization window:\n%s\n' % str(norm_model)) imshape = (72,77) ifsshape = (len(l_ssp),) + imshape norm_y0 = norm_model.y0.value norm_x0 = norm_model.x0.value flagged = distance(imshape, norm_x0, norm_y0) > 32.0 noise = 0.05 flux_unit = 1e-16 logger.info('Creating original PSF (FWHM = %.2f ")' % args.truePsfFWHM) original_PSF = gaussian_psf(args.truePsfFWHM, size=15) logger.info('Creating model images.') bulge_image = np.ma.empty(ifsshape) disk_image = np.ma.empty(ifsshape) for i, model in enumerate(original_models): bulge_image[i], disk_image[i] = create_model_images(model, imshape, original_PSF) bulge_image[:,flagged] = np.ma.masked disk_image[:,flagged] = np.ma.masked model_image = bulge_image + disk_image #model_noise = model_image * noise
def get_bulge_distance(shape, model): return distance(shape, model.x0.value, model.x0.value, model.bulge.PA.value, model.bulge.ell.value)
bulge_ifs_pad[:, i, j] = bulge_spec * (args.fluxUnit * bulge_image_pad[np.newaxis, i, j]) logger.info("Creating disk spectra.") disk_sfh = SyntheticSFH(base.ageBase) disk_sfh.addSquare(0.0, 14e9, 1.0) disk_spec = (f_ssp * disk_sfh.massVector()[:, np.newaxis]).sum(axis=1).sum(axis=0) disk_spec /= np.median(disk_spec[wl_norm_window]) logger.info("Creating IFS.") disk_ifs_pad = disk_spec[..., np.newaxis, np.newaxis] * (args.fluxUnit * disk_image_pad) full_ifs_pad = bulge_ifs_pad + disk_ifs_pad logger.info("Convolving IFS with PSF.") imshape = (args.Ny, args.Nx) ifsshape = (len(l_ssp),) + imshape flagged = distance(imshape, norm_x0, norm_y0) > args.flagRadius bulge_ifs = np.empty(ifsshape) disk_ifs = np.empty(ifsshape) for l in xrange(len(l_ssp)): bulge_ifs[l] = convolve_image(bulge_ifs_pad[l], PSF)[Ny_psf:-Ny_psf, Nx_psf:-Nx_psf] disk_ifs[l] = convolve_image(disk_ifs_pad[l], PSF)[Ny_psf:-Ny_psf, Nx_psf:-Nx_psf] # Convolution is linear. full_ifs = bulge_ifs + disk_ifs # We removed the PSF padding, fix the center of the model again. norm_y0 = norm_model.y0.value - Ny_psf norm_x0 = norm_model.x0.value - Nx_psf norm_model.y0.setValue(norm_y0) norm_model.x0.setValue(norm_x0)
pa = (90.0 + initial_model.disk.PA.value) * np.pi / 180.0 ba = 1.0 - initial_model.disk.ell.value disk_error = fitted_disk_ifs * flux_unit / disk_ifs disk_error_mean = np.mean(disk_error) disk_error_std = np.std(disk_error) print 'Disk error: %.4f +- %.4f' % (disk_error_mean, disk_error_std) disk_error_r = radialProfile(disk_error, bins, norm_x0, norm_y0, pa, ba, rad_scale=1.0) disk_error_min, disk_error_max = np.percentile(disk_error_r, (5, 95)) disk_error_mean = np.mean(disk_error_r) disk_error_std = np.std(disk_error_r) pa = (90.0 + initial_model.bulge.PA.value) * np.pi / 180.0 ba = 1.0 - initial_model.bulge.ell.value bulge_bins = np.arange(0.0, initial_model.bulge.r_e.value * 2.5 + 1.0) bulge_error = fitted_bulge_ifs * flux_unit / bulge_ifs good_bulge = distance(fitted_bulge_ifs.shape[1:], norm_x0, norm_y0, pa, ba) < (initial_model.bulge.r_e.value * 2.5) print bulge_error.shape bulge_error_mean = np.mean(bulge_error[:, good_bulge]) bulge_error_std = np.std(bulge_error[:, good_bulge]) print 'bulge error: %.4f +- %.4f' % (bulge_error_mean, bulge_error_std) bulge_error_r = radialProfile(bulge_error, bulge_bins, norm_x0, norm_y0, pa, ba, rad_scale=1.0) bulge_error_min, bulge_error_max = np.percentile(bulge_error_r, (5, 95)) bulge_error_mean = np.mean(bulge_error_r) bulge_error_std = np.std(bulge_error_r) error_range = np.abs(1.0 - np.array([bulge_error_min, bulge_error_max, disk_error_min, disk_error_max])).max() vmin = 1.0 - error_range vmax = 1.0 + error_range ax = plt.subplot(gs[0]) im = ax.pcolormesh(wl, bulge_bins, bulge_error_r.T, vmin=vmin, vmax=vmax, cmap='RdBu')
print 'Fitting %s profiles' % func f = pyfits.open(cube) h = f[0].header lambda0 = h['CRVAL3'] dlambda = h['CDELT3'] _mask = f[3].data _flux = np.ma.array(f[0].data, mask=_mask) _err = np.ma.array(f[1].data, mask=_mask) wl = np.arange(lambda0, lambda0 + (_flux.shape[0]) * dlambda, dlambda) image = _flux.sum(axis=0) y0, x0 = np.where(image == np.nanmax(image)) r = distance(image.shape, x0, y0) r_mask = r > 30 max_valid_pix = (~r_mask).sum() _flux[:, r_mask] = np.ma.masked _err[:, r_mask] = np.ma.masked print 'Estimated star center: ', y0, x0 f.close() psfLstep_ix = int(np.ceil(psfLstep / dlambda)) wl_ix = np.arange(0, len(wl), psfLstep_ix) psf_wl = wl[wl_ix] flux = np.ma.empty((len(wl_ix), _flux.shape[1], _flux.shape[2]))