示例#1
0
def main(field, subtraction_path, epoch, instrument, instrument_template, show):
    comparison_name = f'{field}_{epoch}'

    params = p.object_params_frb(field)
    burst_ra = params['burst_ra']
    burst_dec = params['burst_dec']
    burst_err_a, burst_err_b, theta = am.calculate_error_ellipse(frb=params, error='systematic')
    hg_ra = params['hg_ra']
    hg_dec = params['hg_dec']

    burst_err_theta = 0.0  # params['burst_err_theta']
    # comparison_params = p.object_params_instrument(comparison_name, instrument)
    # comparison_outputs = p.object_output_params(comparison_name, instrument)

    subtraction_path = f'{params["data_dir"]}subtraction/{subtraction_path}'

    filters = params['filters']

    folders = list(filter(lambda file: os.path.isdir(subtraction_path + file), os.listdir(subtraction_path)))
    folders.sort()

    output_table = table.Table(names=['name'], dtype=[f'S{len(folders[-1])}'])

    first = True

    sextractor_names = p.sextractor_names()

    print(subtraction_path)

    for i, folder in enumerate(folders):
        print()
        print(folder)
        subtraction_path_spec = subtraction_path + folder + '/'
        output_table.add_row()
        output_table['name'][i] = folder

        for f in filters:
            print()
            print(f)

            f_0 = f[0]
            destination_path_filter = f'{subtraction_path_spec}{f}/'

            template_epoch = params['template_epoch_' + instrument_template.lower()]
            template_name = f'{field}_{template_epoch}'

            print(destination_path_filter)
            print('Finding files...')

            cats = list(filter(lambda file: file[-15:] == '_comparison.csv',
                               os.listdir(f'{destination_path_filter}')))
            comparisons = list(filter(lambda file: file[-24:] == '_comparison_aligned.fits',
                                      os.listdir(f'{destination_path_filter}')))
            differences = list(filter(lambda file: file[-16:] == '_difference.fits',
                                      os.listdir(f'{destination_path_filter}')))

            if cats:  # If the generated catalogue was successfully copied.
                print('Loading generated table...')
                cat_generated_file = cats[0]
                cat_generated_path = f'{destination_path_filter}{cat_generated_file}'
                cat_generated = table.Table.read(cat_generated_path, format='ascii.csv')

                if comparisons and differences:  # If the subtraction was successful.

                    comparison_image_file = comparisons[0]
                    difference_image_file = differences[0]

                    print('Loading SExtractor table...')
                    cat_sextractor_path = f'{destination_path_filter}difference.cat'
                    comparison_image_path = f'{destination_path_filter}{comparison_image_file}'
                    difference_image_path = f'{destination_path_filter}{difference_image_file}'

                    cat_sextractor = table.Table(np.genfromtxt(cat_sextractor_path, names=sextractor_names))
                    if len(cat_sextractor) > 0:
                        difference_image = fits.open(difference_image_path)
                        comparison_image = fits.open(comparison_image_path)

                        comparison_header = comparison_image[0].header

                        exp_time = comparison_header['EXPTIME']

                        print('Selecting zeropoint...')

                        comparison_zeropoint, _, airmass, _, comparison_extinction, _ = ph.select_zeropoint(
                            comparison_name,
                            f,
                            instrument=instrument)

                        print('Matching coordinates...')

                        match_ids_generated, match_ids_sextractor, match_distances = u.match_cat(
                            x_cat=cat_sextractor['ra'],
                            y_cat=cat_sextractor[
                                'dec'],
                            x_match=cat_generated[
                                'ra'],
                            y_match=cat_generated[
                                'dec'],
                            tolerance=2 / 3600,
                            world=True,
                            return_dist=True)

                        matches_sextractor = cat_sextractor[match_ids_sextractor]
                        matches_generated = cat_generated[match_ids_generated]

                        w = wcs.WCS(header=difference_image[0].header)
                        hg_x, hg_y = w.all_world2pix(hg_ra, hg_dec, 0)

                        # norm = plotting.nice_norm(difference_image[0].data)
                        # print('Generating full-image plot...')
                        # plt.figure(figsize=(30, 20))
                        # plt.imshow(difference_image[0].data, norm=norm, origin='lower')
                        # plotting.plot_all_params(image=difference_image, cat=cat_sextractor, show=False)
                        # # plt.legend()
                        # plt.savefig(f'{destination_path_filter}recovered_all.png')
                        # if show:
                        #     plt.show()
                        # plt.close()

                        plt.figure(figsize=(6, 8))

                        print('Generating cutout plot...')
                        cutout = ff.trim(difference_image, int(hg_x) - 20, int(hg_x) + 20, int(hg_y) - 20,
                                         int(hg_y) + 20)
                        plotting.plot_all_params(image=difference_image, cat=matches_sextractor, show=False)
                        plotting.plot_gal_params(hdu=difference_image, ras=[burst_ra], decs=[burst_dec],
                                                 a=[burst_err_a],
                                                 b=[burst_err_b], theta=[burst_err_theta], colour='blue',
                                                 show_centre=True,
                                                 label='Burst')

                        norm = plotting.nice_norm(cutout[0].data)
                        plt.imshow(cutout[0].data, norm=norm, origin='lower')
                        plt.scatter(hg_x - (int(hg_x) - 20), hg_y - (int(hg_y) - 20), c='orange',
                                    label='Galaxy centroid')
                        for obj in matches_generated:
                            plt.scatter(obj['x_0'] - (int(hg_x) - 20), obj['y_0'] - (int(hg_y) - 20), c='white',
                                        label='Generated')
                        plt.legend()
                        plt.savefig(f'{destination_path_filter}recovered.png')
                        if show:
                            plt.show()
                        plt.close()

                        matches_sextractor['mag_sextractor'], _, _ = ph.magnitude_complete(
                            flux=matches_sextractor['flux_auto'],
                            exp_time=exp_time, airmass=airmass,
                            zeropoint=comparison_zeropoint,
                            ext=comparison_extinction)

                        matches = table.hstack([matches_generated, matches_sextractor],
                                               table_names=['generated', 'sextracted'])

                        matches['delta_mag'] = matches['mag_sextractor'] - matches['mag']

                        delta_mag = np.median(matches['delta_mag'])

                        matches.write(
                            f'{destination_path_filter}{field}_{epoch}-{template_epoch}_difference_matched_sources.csv',
                            format='ascii.csv', overwrite=True)

                        print(f'{len(matches)} matches / {len(cat_generated)} generated = '
                              f'{100 * len(matches) / len(cat_generated)} % ')

                        # TODO: Will need to rewrite this if you want to insert more than one synthetic.

                        output_table = table_setup(f, first, output_table, cat_generated)

                        output_table[f + '_subtraction_successful'][i] = True
                        if len(matches) > 0:
                            print(f'Faintest recovered: {max(matches["mag"])} generated; '
                                  f'{max(matches_sextractor["mag_sextractor"])} sextracted')

                            print('Median delta mag:', delta_mag)

                            if show:
                                plt.scatter(matches['mag'], matches['delta_mag'])
                                plt.show()

                            arg_faintest = np.argmax(matches["mag"])
                            output_table[f + '_mag_generated'][i] = cat_generated["mag"][arg_faintest]
                            output_table[f + '_mag_recovered'][i] = matches['mag_sextractor'][arg_faintest]
                            output_table[f + '_difference'][i] = delta_mag
                            output_table[f + '_matching_distance_arcsec'][i] = match_distances[arg_faintest] * 3600
                            output_table[f + '_nuclear_offset_pix_x'][i] = matches['x'][arg_faintest] - hg_x
                            output_table[f + '_nuclear_offset_pix_y'][i] = matches['y'][arg_faintest] - hg_y
                            for col in cat_generated.colnames:
                                output_table[f + '_' + col][i] = cat_generated[col][arg_faintest]

                        else:  # If there were no matches
                            output_table[f + '_mag_generated'][i] = cat_generated["mag"][0]
                            output_table[f + '_mag_recovered'][i] = np.nan
                            output_table[f + '_difference'][i] = np.nan
                            output_table[f + '_matching_distance_arcsec'][i] = np.nan
                            output_table[f + '_nuclear_offset_pix_x'][i] = np.nan
                            output_table[f + '_nuclear_offset_pix_y'][i] = np.nan
                            for col in cat_generated.colnames:
                                output_table[f + '_' + col][i] = cat_generated[col][0]
                    else:  # If SExtractor was not successful, probably because of a blank difference image

                        output_table = table_setup(f, first, output_table, cat_generated)
                        output_table[f + '_mag_generated'][i] = cat_generated["mag"][0]
                        output_table[f + '_subtraction_successful'][i] = False
                        output_table[f + '_mag_recovered'][i] = np.nan
                        output_table[f + '_difference'][i] = np.nan
                        output_table[f + '_matching_distance_arcsec'][i] = np.nan
                        output_table[f + '_nuclear_offset_pix_x'][i] = np.nan
                        output_table[f + '_nuclear_offset_pix_y'][i] = np.nan
                        for col in cat_generated.colnames:
                            output_table[f + '_' + col][i] = cat_generated[col][0]

                else:  # If the subtraction was not successful.

                    output_table = table_setup(f, first, output_table, cat_generated)
                    output_table[f + '_mag_generated'][i] = cat_generated["mag"][0]
                    output_table[f + '_subtraction_successful'][i] = False
                    output_table[f + '_mag_recovered'][i] = np.nan
                    output_table[f + '_difference'][i] = np.nan
                    output_table[f + '_matching_distance_arcsec'][i] = np.nan
                    output_table[f + '_nuclear_offset_pix_x'][i] = np.nan
                    output_table[f + '_nuclear_offset_pix_y'][i] = np.nan
                    for col in cat_generated.colnames:
                        output_table[f + '_' + col][i] = cat_generated[col][0]

            else:  # If the generated catalogue was not successfully copied.
                output_table[f + '_mag_generated'][i] = np.nan
                output_table[f + '_subtraction_successful'][i] = True
                output_table[f + '_mag_recovered'][i] = np.nan
                output_table[f + '_mag_generated'][i] = np.nan
                output_table[f + '_difference'][i] = np.nan
                output_table[f + '_matching_distance_arcsec'][i] = np.nan
                output_table[f + '_nuclear_offset_pix_x'][i] = np.nan
                output_table[f + '_nuclear_offset_pix_y'][i] = np.nan

        first = False
        

    plt.close()
    for f in filters:
        plt.scatter(output_table[f + '_mag_generated'], output_table[f + '_mag_recovered'],
                    label=f)
        plt.plot([min(output_table[f + '_mag_generated']), max(output_table[f + '_mag_generated'])],
                 [min(output_table[f + '_mag_generated']), max(output_table[f + '_mag_generated'])], c='red',
                 linestyle=':')
        plt.ylim(20, 30)
        plt.savefig(subtraction_path + 'genvrecovered_' + f + '.png')
        plt.close()

        plt.scatter(output_table[f + '_mag_generated'],
                    output_table[f + '_mag_recovered'] - output_table[f + '_mag_generated'],
                    label=f)
        plt.plot([min(output_table[f + '_mag_generated']), max(output_table[f + '_mag_generated'])],
                 [0, 0], c='red',
                 linestyle=':')
        plt.xlim(20, 30)
        plt.savefig(subtraction_path + 'residuals_' + f + '.png')
        plt.close()

    for f in filters:
        plt.scatter(output_table[f + '_mag_generated'],
                    output_table[f + '_mag_recovered'] - output_table[f + '_mag_generated'],
                    label=f)

        plt.plot([min(output_table[f + '_mag_generated']), max(output_table[f + '_mag_generated'])],
                 [0, 0], c='red',
                 linestyle=':')
    plt.xlim(20, 30)
    plt.ylabel('Recovered magnitudes')
    plt.legend()
    plt.savefig(subtraction_path + 'residuals.png')
    if show:
        plt.show()
    plt.close()

    for f in filters:
        plt.scatter(output_table[f + '_mag_generated'], output_table[f + '_mag_recovered'],
                    label=f)
        plt.plot([min(output_table[f + '_mag_generated']), max(output_table[f + '_mag_generated'])],
                 [min(output_table[f + '_mag_generated']), max(output_table[f + '_mag_generated'])], c='red',
                 linestyle=':')
    plt.xlim(20, 30)
    plt.ylim(20, 30)
    plt.xlabel('Generated magnitudes')
    plt.ylabel('Recovered magnitudes')
    plt.legend()
    plt.savefig(subtraction_path + 'genvrecovered.png')
    if show:
        plt.show()
    plt.close()

    output_table.write(subtraction_path + 'recovery_table.csv', format='ascii.csv', overwrite=True)
示例#2
0
def stack(files: list,
          output: str = None,
          directory: str = '',
          stack_type: str = 'median',
          inherit: bool = True,
          show: bool = False,
          normalise: bool = False):
    accepted_stack_types = ['mean', 'median', 'add']
    if stack_type not in accepted_stack_types:
        raise ValueError('stack_type must be in ' + str(accepted_stack_types))
    if directory != '' and directory[-1] != '/':
        directory = directory + '/'

    data = []
    template = None

    print('Stacking:')

    for f in files:
        # Extract image data and append to list.
        if type(f) is str:
            f = u.sanitise_file_ext(f, 'fits')
            print(' ' + f)
            f = fits.open(directory + f)

        if type(f) is fits.hdu.hdulist.HDUList:
            data_append = f[0].data
            if template is None and inherit:
                # Get a template file to use for output.
                # TODO: Refine this - keep a record of which files went in in the header.
                template = f.copy()
        elif type(f) is CCDData:
            data_append = f.data

        else:
            raise TypeError(
                'files must contain only strings, HDUList or CCDData objects.')

        if normalise:
            data_append = data_append / np.nanmedian(
                data_append[np.isfinite(data_append)])
        if show:
            norm = pl.nice_norm(data_append)
            plt.imshow(data_append, origin='lower', norm=norm)
            plt.show()

        data.append(data_append)

    data = np.array(data)
    if stack_type == 'mean':
        stacked = np.mean(data, axis=0)
    elif stack_type == 'median':
        stacked = np.median(data, axis=0)
    else:
        stacked = np.sum(data, axis=0)

    if show:
        norm = pl.nice_norm(stacked)
        plt.imshow(stacked, origin='lower', norm=norm)
        plt.show()

    if inherit:
        template[0].data = stacked
    else:
        template = fits.PrimaryHDU(stacked)
        template = fits.HDUList([template])
    add_log(template, f'Stacked.')
    if output is not None:
        print('Writing stacked image to', output)
        template[0].header['BZERO'] = 0
        template.writeto(output, overwrite=True, output_verify='warn')

    return template
示例#3
0
def main(data_title: str, show: bool = False):
    properties = p.object_params_xshooter(data_title)
    path = properties['data_dir']

    master_path = path + '/1-master_calibs/'
    reduced_path = path + '/2-reduced/'
    defringed_path = path + '/3-defringed/'

    u.mkdir_check(defringed_path)

    # Define fringe measurement points.

    # high_xs = [267, 267, 267, 267, 267, 267, 267, 267]
    # high_ys = [279, 279, 279, 279, 279, 279, 279, 279]
    # low_xs = [266, 266, 266, 267, 267, 270, 274, 273]
    # low_ys = [293, 295, 298, 301, 303, 305, 303, 292]

    high_xs = [219, 380, 426, 515, 156, 495, 310]
    high_ys = [166, 369, 185, 33, 59, 195, 70]
    low_xs = [219, 380, 424, 474, 160, 500, 315]
    low_ys = [120, 342, 213, 39, 34, 160, 35]

    # n_random = 1000
    #
    # high_xs = np.random.random(n_random)
    # high_xs *= 507
    # high_xs += 29
    # high_xs = np.round(high_xs)
    # high_xs = high_xs.astype(int)
    #
    # high_ys = np.random.random(n_random)
    # high_ys *= 200
    # high_ys += 20
    # high_ys = np.round(high_ys)
    # high_ys = high_ys.astype(int)
    #
    # low_xs = np.random.random(n_random)
    # low_xs *= 507
    # low_xs += 29
    # low_xs = np.round(low_xs)
    # low_xs = low_xs.astype(int)
    #
    # low_ys = np.random.random(n_random)
    # low_ys *= 200
    # low_ys += 20
    # low_ys = np.round(low_ys)
    # low_ys = low_ys.astype(int)

    filters = filter(lambda f: os.path.isdir(reduced_path + f),
                     os.listdir(reduced_path))
    for f in filters:
        print('Constructing fringe map for', f)
        filter_path = reduced_path + f + '/'
        defringed_filter_path = defringed_path + f + '/'
        master_filter_path = master_path + f + '/'
        u.mkdir_check(defringed_filter_path)

        files = list(
            filter(lambda file: file[-5:] == '.fits', os.listdir(filter_path)))
        # Construct fringe map by median-combining science images.
        fringe_map = ff.stack(files,
                              directory=filter_path,
                              output=master_filter_path + 'fringe_map.fits',
                              stack_type='median',
                              inherit=False,
                              show=show,
                              normalise=True)
        fringe_map = fringe_map[0].data
        map_differences = []

        for i in range(len(high_xs)):
            # Take
            high_y = high_ys[i]
            high_x = high_xs[i]
            high_cut = fringe_map[high_y - 1:high_y + 1, high_x - 1:high_x + 1]
            high = np.nanmedian(high_cut)

            low_y = low_ys[i]
            low_x = low_xs[i]
            low_cut = fringe_map[low_y - 1:low_y + 1, low_x - 1:low_x + 1]
            low = np.nanmedian(low_cut)

            map_differences.append(high - low)

        for file in os.listdir(filter_path):
            print(file)
            hdu = fits.open(filter_path + file)
            data = hdu[0].data
            image_differences = []
            factors = []
            for i in range(len(high_xs)):
                high_y = high_ys[i]
                high_x = high_xs[i]
                high_cut = data[high_y - 2:high_y + 2, high_x - 2:high_x + 2]
                high = np.nanmedian(high_cut)

                low_y = low_ys[i]
                low_x = low_xs[i]
                low_cut = data[low_y - 2:low_y + 2, low_x - 2:low_x + 2]
                low = np.nanmedian(low_cut)

                difference = high - low
                image_differences.append(difference)
                factor = difference / map_differences[i]
                factors.append(factor)
            used_factor = np.nanmedian(factors)
            adjusted_map = fringe_map * used_factor
            data = data - adjusted_map
            hdu[0].data = data

            norm = pl.nice_norm(data)
            if show:
                plt.imshow(data, norm=norm, origin='lower')
                plt.show()

            hdu.writeto(defringed_filter_path + file, overwrite=True)

        if show:
            norm = pl.nice_norm(fringe_map)
            plt.imshow(fringe_map, norm=norm, origin='lower')
            plt.scatter(high_xs, high_ys)
            plt.scatter(low_xs, low_ys)
            plt.show()

        copyfile(reduced_path + data_title + ".log",
                 defringed_path + data_title + ".log")
        u.write_log(path=defringed_path + data_title + ".log",
                    action='Edges trimmed using 4-trim.py\n')
def main(field, subtraction_path, epoch, instrument):
    comparison_name = f'{field}_{epoch}'

    params = p.object_params_frb(field)
    # comparison_params = p.object_params_instrument(comparison_name, instrument)

    subtraction_path = f'{params["data_dir"]}subtraction/{subtraction_path}'

    filters = params['filters']

    burst_ra = params['burst_ra']
    burst_dec = params['burst_dec']
    hg_ra = params['hg_ra']
    hg_dec = params['hg_dec']
    burst_err_a = params['burst_err_stat_a'] / 3600
    burst_err_b = params['burst_err_stat_b'] / 3600
    burst_err_theta = params['burst_err_theta']

    for f in filters:
        print()
        print(f)
        f_0 = f[0]
        destination_path_filter = f'{subtraction_path}{f}/'

        # This relies on there only being one file with these suffixes in each directory, which, if previous scripts
        # ran correctly, should be true.

        comparison_image_file = filter(
            lambda file: file[-24:] == '_comparison_aligned.fits',
            os.listdir(f'{destination_path_filter}')).__next__()
        difference_image_file = filter(
            lambda file: file[-16:] == '_difference.fits',
            os.listdir(f'{destination_path_filter}')).__next__()

        cat_sextractor_path = f'{destination_path_filter}difference.cat'
        comparison_image_path = f'{destination_path_filter}{comparison_image_file}'
        difference_image_path = f'{destination_path_filter}{difference_image_file}'

        cat_sextractor = table.Table(
            np.genfromtxt(cat_sextractor_path, names=p.sextractor_names()))

        difference_image = fits.open(difference_image_path)
        comparison_image = fits.open(comparison_image_path)

        comparison_header = comparison_image[0].header

        exp_time = comparison_header['EXPTIME']

        comparison_zeropoint, _, airmass, _, comparison_extinction, _ = ph.select_zeropoint(
            comparison_name, f, instrument=instrument)

        cat_sextractor['mag'], _, _ = ph.magnitude_complete(
            flux=cat_sextractor['flux_aper'],
            exp_time=exp_time,
            airmass=airmass,
            zeropoint=comparison_zeropoint,
            ext=comparison_extinction)

        cat_sextractor['mag_auto'], _, _ = ph.magnitude_complete(
            flux=cat_sextractor['flux_auto'],
            exp_time=exp_time,
            airmass=airmass,
            zeropoint=comparison_zeropoint,
            ext=comparison_extinction)

        wcs_info = wcs.WCS(comparison_header)
        hg_x, hg_y = wcs_info.all_world2pix(hg_ra, hg_dec, 0)

        # norm = plotting.nice_norm(difference_image[0].data)
        # print('Generating full-image plot...')
        # plt.figure(figsize=(30, 20))
        # plt.imshow(difference_image[0].data, norm=norm, origin='lower')
        # plotting.plot_all_params(image=difference_image, cat=cat_sextractor, show=False)
        # # plt.legend()
        # plt.savefig(f'{destination_path_filter}recovered_all.pdf')
        # plt.close()

        closest_index, distance = u.find_object(burst_ra, burst_dec,
                                                cat_sextractor['ra'],
                                                cat_sextractor['dec'])

        closest = cat_sextractor[closest_index]
        x = closest['x']
        y = closest['y']

        print(closest)
        print('Magnitude:', closest['mag'])
        print('Threshold:', closest['threshold'])
        print('Flux max:', closest['flux_max'])
        print('RA:', closest['ra'], '; DEC:', closest['dec'])
        print('X:', x, '; Y:', y)
        print('Offset from HG (pixels):',
              np.sqrt((x - hg_x)**2 + (y - hg_y)**2))

        x = int(x)
        y = int(y)

        norm = plotting.nice_norm(difference_image[0].data)
        print('Generating full-image plot...')
        plt.figure(figsize=(30, 20))
        plt.imshow(difference_image[0].data, norm=norm, origin='lower')
        print(min(cat_sextractor['ra']), min(cat_sextractor['dec']))
        plotting.plot_all_params(image=difference_image,
                                 cat=cat_sextractor,
                                 show=False)
        # plt.legend()
        plt.savefig(f'{destination_path_filter}recovered_all.png')
        plt.close()

        print('Generating cutout plots...')

        plt.imshow(difference_image[0].data, norm=norm, origin='lower')
        # plt.legend()
        plotting.plot_gal_params(hdu=difference_image,
                                 ras=[burst_ra],
                                 decs=[burst_dec],
                                 a=[burst_err_a],
                                 b=[burst_err_b],
                                 theta=[burst_err_theta],
                                 colour='blue',
                                 show_centre=True,
                                 label='Burst')
        plt.scatter(hg_x, hg_y, c='orange', label='Galaxy centroid')
        plotting.plot_all_params(image=difference_image,
                                 cat=cat_sextractor,
                                 show=False)
        plt.xlim(hg_x - 50, hg_x + 50)
        plt.ylim(hg_y - 50, hg_y + 50)
        plt.legend()
        plt.savefig(f'{destination_path_filter}recovered_hg_cutout.png')
        plt.close()

        cutout_source = difference_image[0].data[y - 50:y + 50, x - 50:x + 50]

        plt.imshow(cutout_source, origin='lower')
        plt.savefig(f'{destination_path_filter}nearest_source_cutout.png')
        plt.show()
        plt.close()

        cutout_hg = ff.trim(difference_image,
                            int(hg_x) - 20,
                            int(hg_x) + 20,
                            int(hg_y) - 20,
                            int(hg_y) + 20)
        cutout_hg_data = cutout_hg[0].data

        midpoint = int(cutout_hg_data.shape[0] / 2)
        xx = np.arange(-midpoint, midpoint)
        data_slice = cutout_hg_data[midpoint, :]
        plt.plot(xx, data_slice)
        plt.savefig(f'{destination_path_filter}hg_x_slice.png')
        plt.show()
        plt.close()
        print()
        x_misalignment = np.argmax(data_slice) - np.argmin(data_slice)
        print('x peak - trough:', x_misalignment)

        midpoint = int(cutout_hg_data.shape[0] / 2)
        yy = np.arange(-midpoint, midpoint)
        data_slice = cutout_hg_data[:, midpoint]
        plt.plot(yy, data_slice)
        plt.savefig(f'{destination_path_filter}hg_y_slice.png')
        plt.show()
        plt.close()
        y_misalignment = np.argmax(data_slice) - np.argmin(data_slice)
        print('y peak - trough:', y_misalignment)
        print()

        print('Mean false positive mag:', np.nanmean(cat_sextractor['mag']))
        print('Median false positive mag:',
              np.nanmedian(cat_sextractor['mag']))

        plt.figure(figsize=(6, 8))

        sextractor_cutout = cat_sextractor[
            (cat_sextractor['x'] > int(hg_x) - 20)
            & (cat_sextractor['x'] < int(hg_x) + 20) &
            (cat_sextractor['y'] > int(hg_y) - 20) &
            (cat_sextractor['y'] < int(hg_y) + 20)]
        plotting.plot_all_params(image=difference_image,
                                 cat=sextractor_cutout,
                                 show=False)
        plotting.plot_gal_params(hdu=difference_image,
                                 ras=[burst_ra],
                                 decs=[burst_dec],
                                 a=[burst_err_a],
                                 b=[burst_err_b],
                                 theta=[burst_err_theta],
                                 colour='blue',
                                 show_centre=True,
                                 label='Burst')

        norm = plotting.nice_norm(cutout_hg[0].data)
        plt.imshow(cutout_hg[0].data, norm=norm, origin='lower')
        plt.scatter(hg_x - (int(hg_x) - 20),
                    hg_y - (int(hg_y) - 20),
                    c='orange',
                    label='Galaxy centroid')
        plt.legend()
        plt.savefig(f'{destination_path_filter}residuals_hg.png')
        plt.show()
        plt.close()
示例#5
0
def main(image, cat_path_1, cat_path_2, cat_name_1, cat_name_2, offset_x,
         offset_y, psf):
    if cat_name_1 == 'DES':
        ra_name_1 = 'RA'
        dec_name_1 = 'DEC'
    else:
        ra_name_1 = 'ra'
        dec_name_1 = 'dec'

    if cat_name_2 == 'DES':
        ra_name_2 = 'RA'
        dec_name_2 = 'DEC'
    else:
        ra_name_2 = 'ra'
        dec_name_2 = 'dec'

    if psf:
        names = p.sextractor_names_psf()
    else:
        names = p.sextractor_names()

    if cat_name_1 == 'SExtractor':
        cat_1 = table.Table(np.genfromtxt(cat_path_1, names=names))
    else:
        cat_1 = table.Table()
        cat_1 = cat_1.read(cat_path_1, format='ascii.csv')

    if cat_name_2 == 'SExtractor':
        cat_2 = table.Table(np.genfromtxt(cat_path_2, names=names))
    else:
        cat_2 = table.Table()
        cat_2 = cat_2.read(cat_path_2, format='ascii.csv')

    param_dict = {}

    image = fits.open(image)
    header = image[0].header
    data = image[0].data
    wcs_info = wcs.WCS(header=header)

    cat_1['x'], cat_1['y'] = wcs_info.all_world2pix(cat_1[ra_name_1],
                                                    cat_1[dec_name_1], 0)
    cat_2['x'], cat_2['y'] = wcs_info.all_world2pix(cat_2[ra_name_2],
                                                    cat_2[dec_name_2], 0)

    norm = pl.nice_norm(data)
    plt.subplot(projection=wcs_info)
    plt.imshow(data, norm=norm, origin='lower', cmap='viridis')
    plt.scatter(cat_1['x'], cat_1['y'], label=cat_name_1, c='violet')
    plt.scatter(cat_2['x'], cat_2['y'], label=cat_name_2, c='red')
    plt.legend()
    plt.show()

    scale_ra, scale_dec = ff.get_pixel_scale(image)

    ra_corrected = cat_2[ra_name_2] + offset_x * scale_ra
    dec_corrected = cat_2[dec_name_2] + offset_y * scale_ra

    x, y = wcs_info.all_world2pix(ra_corrected, dec_corrected, 0)

    norm = pl.nice_norm(data)
    plt.subplot(projection=wcs_info)
    plt.imshow(data, norm=norm, origin='lower', cmap='viridis')
    plt.scatter(cat_1['x'], cat_1['y'], label=cat_name_1, c='violet')
    plt.scatter(x, y, label=cat_name_2, c='red')
    plt.legend()
    plt.show()
    image.close()
示例#6
0
def tweak(sextractor_path: str, destination: str, image_path: str, cat_path: str, cat_name: str, tolerance: float = 10.,
          show: bool = False,
          stars_only: bool = False,
          manual: bool = False, offset_x: float = None, offset_y: float = None, offsets_world: bool = False,
          psf: bool = True,
          specific_star: bool = False, star_ra: float = None, star_dec: float = None
          ):
    """
    For tweaking the astrometric solution of a fits image using a catalogue; either matches as many stars as possible
    and uses the median offset, uses a single star at a specified position (specific_star=True) or a manual offset.
    :param sextractor_path: Path to SExtractor-generated catalogue.
    :param destination: Directory to write tweaked image to.
    :param image_path: Path to image FITS file
    :param cat_path: Path to file containing catalogue.
    :param cat_name: Name of catalogue used.
    :param tolerance: Tolerance, in pixels, within which matches will be accepted.
    :param show: Plot matches onscreen?
    :param stars_only: Only match using stars, determined using SExtractor's 'class_star' output.
    :param manual: Use manual offset?
    :param offset_x: Offset in x to use; only if 'manual' is set to True.
    :param offset_y: Offset in y to use; only if 'manual' is set to True.
    :param offsets_world: If True, interprets the offsets as being given in World Coordinates (RA and DEC)
    :param psf: Use the PSF-fitting position?
    :param specific_star: Use a specific star to tweak? This means, instead of finding the closest matches for many
        stars, alignment is attempted with a single star nearest the given position.
    :param star_ra: Right Ascension of star for single-star alignment.
    :param star_dec: Declination of star for single-star alignment.
    :return: None
    """
    param_dict = {}

    print(image_path)
    image = fits.open(image_path)
    header = image[0].header
    data = image[0].data

    wcs_info = wcs.WCS(header=header)
    # Set the appropriate column names depending on the format of the catalogue to use.
    if cat_name == 'DES':
        ra_name = 'RA'
        dec_name = 'DEC'
    elif cat_name == 'Gaia' or cat_name == 'SDSS':
        ra_name = 'ra'
        dec_name = 'dec'
    else:
        if psf:
            ra_name = 'ra_psf'
            dec_name = 'dec_psf'
        else:
            ra_name = 'ra'
            dec_name = 'dec'

    if psf:
        names = p.sextractor_names_psf()
        sextractor_ra_name = 'ra_psf'
        sextractor_dec_name = 'dec_psf'

    else:
        names = p.sextractor_names()
        sextractor_ra_name = 'ra'
        sextractor_dec_name = 'dec'

    if show or not manual:
        if cat_name == 'SExtractor':
            cat = table.Table(np.genfromtxt(cat_path, names=names))
        else:
            cat = table.Table()
            cat = cat.read(cat_path, format='ascii.csv')

        sextracted = table.Table(np.genfromtxt(sextractor_path, names=names))
        if stars_only:
            sextracted = sextracted[sextracted['class_star'] > 0.9]

        cat['x'], cat['y'] = wcs_info.all_world2pix(cat[ra_name], cat[dec_name], 0)
        x, y = wcs_info.all_world2pix(sextracted[sextractor_ra_name], sextracted[sextractor_dec_name], 0)

    norm = pl.nice_norm(data)
    if show:
        # plt.subplot(projection=wcs_info)
        plt.imshow(data, norm=norm, origin='lower', cmap='viridis')
        plt.scatter(x, y, label='SExtractor', c='violet')
        plt.scatter(cat['x'], cat['y'], label=cat_name, c='red')
        plt.legend()
        plt.title('Pre-Correction')
        plt.show()

    if manual:

        if offset_x is not None and offset_y is not None:

            if not offsets_world:

                scale_ra, scale_dec = ff.get_pixel_scale(image)

                offset_ra = -offset_x * abs(scale_ra)
                offset_dec = -offset_y * abs(scale_dec)

                print(offset_x, offset_y)

            else:

                offset_ra = offset_x
                offset_dec = offset_y

        else:

            print('Set offsets in epoch .yaml file')

            offset_ra = offset_dec = None

    elif specific_star:

        if star_ra is not None and star_dec is not None:
            print(star_ra, star_dec)
            star_cat, d = u.find_object(x=star_ra, y=star_dec, x_search=cat[ra_name], y_search=cat[dec_name])
            print('MD:', d)
            star_cat = cat[star_cat]
            star_sex, d = u.find_object(x=star_ra, y=star_dec, x_search=sextracted[sextractor_ra_name],
                                        y_search=sextracted[sextractor_dec_name])
            print('MD:', d)
            star_sex = sextracted[star_sex]
            offset_ra = (star_sex[sextractor_ra_name] - star_cat[ra_name])
            offset_dec = (star_sex[sextractor_dec_name] - star_cat[dec_name])
        else:
            raise ValueError('If doing specific_star, must specify star_ra and star_dec')

    else:

        match_ids, match_ids_cat = u.match_cat(x_match=sextracted['x'], y_match=sextracted['y'],
                                               x_cat=cat['x'],
                                               y_cat=cat['y'], tolerance=tolerance)

        sextracted = sextracted[match_ids]
        cat = cat[match_ids_cat]

        offsets_ra = sextracted[sextractor_ra_name] - cat[ra_name]
        offsets_dec = sextracted[sextractor_dec_name] - cat[dec_name]

        offset_ra = np.nanmedian(offsets_ra)
        offset_dec = np.nanmedian(offsets_dec)

    # TODO: This is quick and dirty and will only work if the image is approximately oriented along x=RA
    #  and y=DEC (CROTA ~ 0)

    if offset_ra is not None and offset_dec is not None:

        param_dict['offset_ra'] = float(offset_ra)
        param_dict['offset_dec'] = float(offset_dec)

        image = offset_astrometry(hdu=image, offset_ra=offset_ra, offset_dec=offset_dec, output=destination)

        if show and not manual:
            wcs_info = wcs.WCS(header=header)
            cat['x'], cat['y'] = wcs_info.all_world2pix(cat[ra_name], cat[dec_name], 0)
            x, y = wcs_info.all_world2pix(sextracted[sextractor_ra_name] - offset_ra,
                                          sextracted[sextractor_dec_name] - offset_dec, 0)

        if show:
            plt.subplot(projection=wcs_info)
            plt.imshow(data, norm=norm, origin='lower', cmap='viridis')
            plt.scatter(x, y, label='SExtractor', c='violet')
            plt.scatter(cat['x'], cat['y'], label=cat_name, c='red')
            plt.legend()
            plt.title('Post-Correction')
            plt.show()

    image.close()
    return param_dict