예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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!')
예제 #6
0
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!')
예제 #7
0
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!')
예제 #8
0
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!')