def __init__(self, camera_catalog, FoV, inside_FoV, eta, delta, epsilon_max): ''' This class generates the measured catalog object. Sources within in the imagers field-of-view are identified and then "measurements" are performed using the *true* instrument response model Input ----- camera_catalog : object The camera catalog FoV : float array The imagers field-of-view (dalpha, dbeta) inside_FoV : boolean array Array identifying sources within the instruments field of view eta, delta, epsilon_max : all floats The parameters describing the noise model according to: sigma ** 2 = (1 + epsilon) * delta ** 2 + eta ** 2 * count_rate ** 2 ''' self.size = len(inside_FoV[0]) self.k = camera_catalog.k[inside_FoV] self.alpha = camera_catalog.alpha[inside_FoV] self.beta = camera_catalog.beta[inside_FoV] self.is_in_analysis_region = camera_catalog.is_in_analysis_region[ inside_FoV] self.x = camera_catalog.x[inside_FoV] self.y = camera_catalog.y[inside_FoV] flat = true_functions.flat_field(self.x, self.y, FoV) true_counts = camera_catalog.flux[inside_FoV] * flat self.true_invvar = self.true_invvar_func(true_counts, eta, delta, epsilon_max) self.invvar = self.reported_invvar(true_counts, eta, delta) self.counts = true_counts + np.random.normal(size=self.size) \ / np.sqrt(self.true_invvar)
def __init__(self, camera_catalog, FoV, inside_FoV, eta, delta, epsilon_max): ''' This class generates the measured catalog object. Sources within in the imagers field-of-view are identified and then "measurements" are performed using the *true* instrument response model Input ----- camera_catalog : object The camera catalog FoV : float array The imagers field-of-view (dalpha, dbeta) inside_FoV : boolean array Array identifying sources within the instruments field of view eta, delta, epsilon_max : all floats The parameters describing the noise model according to: sigma ** 2 = (1 + epsilon) * delta ** 2 + eta ** 2 * count_rate ** 2 ''' self.size = len(inside_FoV[0]) self.k = camera_catalog.k[inside_FoV] self.alpha = camera_catalog.alpha[inside_FoV] self.beta = camera_catalog.beta[inside_FoV] self.is_in_analysis_region = camera_catalog.is_in_analysis_region[inside_FoV] self.x = camera_catalog.x[inside_FoV] self.y = camera_catalog.y[inside_FoV] flat = true_functions.flat_field(self.x, self.y, FoV) true_counts = camera_catalog.flux[inside_FoV] * flat self.true_invvar = self.true_invvar_func(true_counts, eta, delta, epsilon_max) self.invvar = self.reported_invvar(true_counts, eta, delta) self.counts = true_counts + np.random.normal(size=self.size) \ / np.sqrt(self.true_invvar)
def best_fit_ff(FoV, ff_samples, order, stop_condition, max_iterations, verbose=False): ''' Calculates the best fit possible to true flat-field with the basis used to model it during the self-calibration procedure. Parameters ---------- FoV : Float Array The simulate imager's field-of-view in degrees [alpha, beta] ff_samples : Integer Array The number of sample points on the focal plane for the best-in-basis fitting and all of the badness measures order : Integer The order of the polynomial flat-field used to fit the instrument response in the self-calibration procedure stop_condition : Float The stop condition for the self-calibration procedure and the best-in-basis fitting (stop when difference is less than 2 times this) max_iterations : Integer The maximum number of iterations in the self-calibration procedure and the best-in-basis fitting verbose : Boolean Set to true to run the simulations in verbose mode Returns ------- out : numpy array the fitted parameter ''' if verbose: print("Fitting the true flat-field with basis...") x = np.linspace(- FoV[0] / 2, FoV[0] / 2, ff_samples[0]) y = np.linspace(- FoV[1] / 2, FoV[1] / 2, ff_samples[1]) X, Y = np.meshgrid(x, y) g = self_cal.evaluate_flat_field_functions(X.flatten(), Y.flatten(), order) true_ff = true_functions.flat_field(X.flatten(), Y.flatten(), FoV) a = np.zeros((order + 1) * (order + 2) / 2) fitted_parameters = opt.leastsq(compare_flats, a, args=(true_ff, g))[0] fitted_parameters = self_cal.normalize_flat_field(fitted_parameters, FoV, ff_samples) if verbose: print("...done!") print("Fitted Parameters: ", fitted_parameters) return fitted_parameters
def badness(q, FoV, ff_samples, verbose=False): ''' Calculates the 'badness' of the instrument response fit. The 'badness' is defined as the root-mean-square difference between the true instrument response and the fitted instrument response measured on a regular grid of sample points across the focal plane. Parameters ---------- q : numpy array The fitted instrument response parameters FoV : float array The imagers field-of-view in degrees (dalpha, dbeta) ff_samples : float array The number of focal plane sample points (alpha-axis, beta-axis) Returns ------- out : float the calculated badness ''' if verbose: print("Calculating best-in-basis badness of fitted flat-field...") x = np.linspace(-FoV[0] / 2, FoV[0] / 2, ff_samples[0]) y = np.linspace(-FoV[1] / 2, FoV[1] / 2, ff_samples[1]) X, Y = np.meshgrid(x, y) our_ff = self_cal.evaluate_flat_field(x.flatten(), y.flatten(), q) true_ff = true_functions.flat_field(x.flatten(), y.flatten(), FoV) badness = 100. * np.sqrt(np.mean(((our_ff - true_ff) / true_ff) ** 2)) if verbose: print("...done!") return badness
def flat_fields(filename, FoV, ff_samples, best_fit_params, output_path=False, fig_width=8.3, suffix='.png', verbose=False): ''' This function plots the fitted flat-field against the *true* (top) and the best-in-basis (bottom) flat-fields. Left: contour plots to compare flat-fields, Right: residuals between two flat-fields. Input ----- filename : string The path to the survey files FoV : float array The size of the imagers field-of-view in degrees (dalpha, dbeta) ff_samples : float array The number of points at which the instrument responses are sampled in the (x-direction, y-direction) The imager's field-of-view in degrees (dalpha, dbeta) best_fit_params : numpy array Array of the best-in-basis parameters output_path : string The path to save the figure to. If no value is given, figure is saved in same directory as source pickle figure_width : float The width of the figure in inches, default it 8.3 suffix : string The format of the saved figure, either '.pdf', '.eps' or '.png'. Default is '.png' verbose : Boolean Set to true to run function in verbose mode ''' if verbose: print("Plotting flat-field from {0}...".format(filename)) scale = 0.88 dic = pickle.load(open(filename)) fig = plt.figure(figsize=(fig_width, scale * fig_width)) fig.clf() ax_cb = fig.add_axes([0.85, 0.075 / scale, 0.05, 0.75 / scale]) ax1 = fig.add_axes([0.075, 0.075 / scale, 0.375, 0.375 / scale]) ax2 = fig.add_axes([0.075, 0.45 / scale, 0.375, 0.375 / scale]) ax3 = fig.add_axes([0.45, 0.075 / scale, 0.375, 0.375 / scale]) ax4 = fig.add_axes([0.45, 0.45 / scale, 0.375, 0.375 / scale]) ax1.text(0.95, 0.96, '(c)', va='center', ha='center', bbox=dict(facecolor='w', edgecolor='w', alpha=0.7), zorder=2000, transform=ax1.transAxes) ax2.text(0.95, 0.04, '(a)', va='center', ha='center', bbox=dict(facecolor='w', edgecolor='w', alpha=0.7), zorder=2000, transform=ax2.transAxes) ax3.text(0.05, 0.96, '(d)', va='center', ha='center', zorder=2000, transform=ax3.transAxes) ax4.text(0.05, 0.04, '(b)', va='center', ha='center', zorder=2000, transform=ax4.transAxes) ax2.set_xticklabels([]) ax4.set_xticklabels([]) ax4.set_yticklabels([]) ax3.set_yticklabels([]) ax_cb.set_xticks([]) fig.text(0.45, 0.025 / scale, r'Focal Plane Position $x$ (deg)', va='center', ha='center') fig.text(0.015, 0.45 / scale, r'Focal Plane Position $y$ (deg)', va='center', ha='center', rotation='vertical') true_ff = true_functions.flat_field(dic['x'], dic['y'], FoV) best_ff = self_calibration.evaluate_flat_field( dic['x'].flatten(), dic['y'].flatten(), best_fit_params).reshape(ff_samples) levels = np.linspace(np.min(true_ff), np.max(true_ff), 25) labels = levels[::2] cs = ax2.contour(dic['x'], dic['y'], true_ff, colors='0.75', levels=levels) cs = ax1.contour(dic['x'], dic['y'], best_ff, colors='0.75', levels=levels) cs = ax1.contour(dic['x'], dic['y'], dic['fitted_ff'], colors='k', levels=levels) cs.clabel(labels, fontsize=8) cs = ax2.contour(dic['x'], dic['y'], dic['fitted_ff'], colors='k', levels=levels) cs.clabel(labels, fontsize=8) true_residual = 100 * (dic['fitted_ff'] - true_ff) / true_ff best_residual = 100 * (dic['fitted_ff'] - best_ff) / best_ff fp = (-FoV[0] / 2, FoV[0] / 2, -FoV[1] / 2, FoV[1] / 2) a = ax4.imshow(true_residual, extent=fp, vmin=-2., vmax=2., cmap='gray', aspect='auto') ax3.imshow(best_residual, extent=fp, vmin=-2., vmax=2., cmap='gray', aspect='auto') cbar = fig.colorbar(a, ax_cb, orientation='vertical') cbar.set_label(r'Residuals (percent)') if output_path: filename = output_path + suffix else: filename = string.replace(filename, '.p', suffix) fig.savefig(filename) fig.clf() if verbose: print('...done!')
def camera_image(filename, sky_limits, density, output_path=False, fig_width=8.3, suffix='.png', verbose=False): ''' This function plots the footprint of the imagers field-of-view on the sky (left) and a camera image with the *true* instrument response (right) Input ----- filename : string The path to the survey files sky_limits : numpy array The area of sky to generate sources in [alpha_min, alpha_max, beta_min, beta_max] density : int The maximum number of sources (all magnitude) per unit area to generate for the self-calibration simulations output_path : string The path to save the figure to. If no value is given, figure is saved in same directory as source pickle figure_width : float The width of the figure in inches, default it 8.3 suffix : string The format of the saved figure, either '.pdf', '.eps' or '.png'. Default is '.png' verbose : Boolean Set to true to run function in verbose mode ''' if verbose: print("Plotting Camera Image from {0}...".format(filename)) dic = pickle.load(open(filename)) fig = plt.figure(figsize=(fig_width, 0.5 * fig_width)) fig.clf() x = dic['sources_x'] y = dic['sources_y'] alpha = dic['sky_catalog'].alpha beta = dic['sky_catalog'].beta pointing = dic['pointing'] orientation = dic['orientation'] fp_x = dic['fp_x'] fp_y = dic['fp_y'] fp_alpha = dic['fp_alpha'] fp_beta = dic['fp_beta'] ax1 = fig.add_axes([0.075, 0.15, 0.4, 0.8]) ax1.plot(alpha, beta, 'k.', alpha=(10 / density)) ax1.plot(fp_alpha, fp_beta, 'k', linewidth=2) ax1.set_xlabel(r'Sky Position $\alpha$ (deg)') ax1.set_ylabel(r'Sky Position $\beta$ (deg)') ax1.set_xlim(sky_limits[0], sky_limits[1]) ax1.set_ylim(sky_limits[2], sky_limits[3]) ax2 = fig.add_axes([0.575, 0.15, 0.4, 0.8]) ax2.plot(x, y, 'k.', markersize=6) ax2.plot(fp_x, fp_y, 'k', linewidth=3) ax2.set_xlabel(r'Focal Plane Position $x$ (deg)') ax2.set_ylabel(r'Focal Plane Position $y$ (deg)') ax2.set_xlim(1.3 * np.min(fp_x), 1.3 * np.max(fp_x)) ax2.set_ylim(1.3 * np.min(fp_y), 1.3 * np.max(fp_y)) x = np.linspace(np.min(fp_x), np.max(fp_x), 100) y = np.linspace(np.min(fp_y), np.max(fp_y), 100) X, Y = np.meshgrid(x, y) FoV = [np.max(fp_x) - np.min(fp_x), np.max(fp_y) - np.min(fp_y)] true_ff = true_functions.flat_field(X, Y, FoV) levels = np.linspace(np.min(true_ff), np.max(true_ff), 25) labels = levels[::3] cs = ax2.contour(X, Y, true_ff, colors='0.75', levels=levels) cs.clabel(labels, fontsize=8) if output_path: filename = output_path + suffix else: filename = string.replace(filename, '.p', suffix) fig.savefig(filename) fig.clf() if verbose: print('...done!')
def flat_fields(filename, FoV, ff_samples, best_fit_params, output_path=False, fig_width=8.3, suffix='.png', verbose=False): ''' This function plots the fitted flat-field against the *true* (top) and the best-in-basis (bottom) flat-fields. Left: contour plots to compare flat-fields, Right: residuals between two flat-fields. Input ----- filename : string The path to the survey files FoV : float array The size of the imagers field-of-view in degrees (dalpha, dbeta) ff_samples : float array The number of points at which the instrument responses are sampled in the (x-direction, y-direction) The imager's field-of-view in degrees (dalpha, dbeta) best_fit_params : numpy array Array of the best-in-basis parameters output_path : string The path to save the figure to. If no value is given, figure is saved in same directory as source pickle figure_width : float The width of the figure in inches, default it 8.3 suffix : string The format of the saved figure, either '.pdf', '.eps' or '.png'. Default is '.png' verbose : Boolean Set to true to run function in verbose mode ''' if verbose: print("Plotting flat-field from {0}...".format(filename)) scale = 0.88 dic = pickle.load(open(filename)) fig = plt.figure(figsize=(fig_width, scale * fig_width)) fig.clf() ax_cb = fig.add_axes([0.85, 0.075 / scale, 0.05, 0.75 / scale]) ax1 = fig.add_axes([0.075, 0.075 / scale, 0.375, 0.375 / scale]) ax2 = fig.add_axes([0.075, 0.45 / scale, 0.375, 0.375 / scale]) ax3 = fig.add_axes([0.45, 0.075 / scale, 0.375, 0.375 / scale]) ax4 = fig.add_axes([0.45, 0.45 / scale, 0.375, 0.375 / scale]) ax1.text(0.95, 0.96, '(c)', va='center', ha='center', bbox=dict(facecolor='w', edgecolor='w', alpha=0.7), zorder=2000, transform=ax1.transAxes) ax2.text(0.95, 0.04, '(a)', va='center', ha='center', bbox=dict(facecolor='w', edgecolor='w', alpha=0.7), zorder=2000, transform=ax2.transAxes) ax3.text(0.05, 0.96, '(d)', va='center', ha='center', zorder=2000, transform=ax3.transAxes) ax4.text(0.05, 0.04, '(b)', va='center', ha='center', zorder=2000, transform=ax4.transAxes) ax2.set_xticklabels([]) ax4.set_xticklabels([]) ax4.set_yticklabels([]) ax3.set_yticklabels([]) ax_cb.set_xticks([]) fig.text(0.45, 0.025 / scale, r'Focal Plane Position $x$ (deg)', va='center', ha='center') fig.text(0.015, 0.45 / scale, r'Focal Plane Position $y$ (deg)', va='center', ha='center', rotation='vertical') true_ff = true_functions.flat_field(dic['x'], dic['y'], FoV) best_ff = self_calibration.evaluate_flat_field(dic['x'].flatten(), dic['y'].flatten(), best_fit_params).reshape(ff_samples) levels = np.linspace(np.min(true_ff), np.max(true_ff), 25) labels = levels[::2] cs = ax2.contour(dic['x'], dic['y'], true_ff, colors='0.75', levels=levels) cs = ax1.contour(dic['x'], dic['y'], best_ff, colors='0.75', levels=levels) cs = ax1.contour(dic['x'], dic['y'], dic['fitted_ff'], colors='k', levels=levels) cs.clabel(labels, fontsize=8) cs = ax2.contour(dic['x'], dic['y'], dic['fitted_ff'], colors='k', levels=levels) cs.clabel(labels, fontsize=8) true_residual = 100 * (dic['fitted_ff'] - true_ff) / true_ff best_residual = 100 * (dic['fitted_ff'] - best_ff) / best_ff fp = (-FoV[0] / 2, FoV[0] / 2, -FoV[1] / 2, FoV[1] / 2) a = ax4.imshow(true_residual, extent=fp, vmin=-2., vmax=2., cmap='gray', aspect='auto') ax3.imshow(best_residual, extent=fp, vmin=-2., vmax=2., cmap='gray', aspect='auto') cbar = fig.colorbar(a, ax_cb, orientation='vertical') cbar.set_label(r'Residuals (percent)') if output_path: filename = output_path + suffix else: filename = string.replace(filename, '.p', suffix) fig.savefig(filename) fig.clf() if verbose: print('...done!')