def main(field, destination, epoch, force_subtract_better_seeing, subtraction_type, template_instrument):
    if destination[-1] != '/':
        destination = destination + '/'

    params = p.object_params_frb(field)
    destination_path = f'{params["data_dir"]}subtraction/{destination}/'
    u.mkdir_check(destination_path)

    params = p.object_params_frb(field)
    template_epoch = params['template_epoch_' + template_instrument.lower()]

    comparison_title = f'{field}_{epoch}'
    template_title = f'{field}_{template_epoch}'

    filters = params['filters']

    for f in filters:
        f_0 = f[0]

        destination_path_filter = f'{destination_path}{f}/'
        u.mkdir_check(destination_path_filter)

        template_params = p.load_params(destination_path_filter + f'{template_title}_template_output_values.yaml')
        comparison_params = p.load_params(destination_path_filter + f'{comparison_title}_comparison_output_values.yaml')

        if f_0 + '_fwhm_arcsec' in template_params:
            fwhm_template = template_params[f_0 + '_fwhm_arcsec']
        elif f_0.lower() + '_fwhm_arcsec' in template_params:
            fwhm_template = template_params[f_0.lower() + '_fwhm_arcsec']
        else:
            raise ValueError(f_0 + '_fwhm_arcsec or ' + f_0.lower() + '_fwhm_arcsec not found for template image.')

        if f_0 + '_fwhm_arcsec' in comparison_params:
            fwhm_comparison = comparison_params[f_0 + '_fwhm_arcsec']
        elif f_0.lower() + '_fwhm_arcsec' in comparison_params:
            fwhm_comparison = comparison_params[f_0.lower() + '_fwhm_arcsec']
        else:
            raise ValueError(f_0 + '_fwhm_arcsec or ' + f_0.lower() + '_fwhm_arcsec not found for comparison image.')

        template = destination_path_filter + f'{template_title}_template_aligned.fits'
        comparison = destination_path_filter + f'{comparison_title}_comparison_aligned.fits'

        _, difference = ph.subtract(template_origin=template,
                                    comparison_origin=comparison,
                                    output=destination_path_filter,
                                    template_fwhm=fwhm_template,
                                    comparison_fwhm=fwhm_comparison,
                                    force_subtract_better_seeing=force_subtract_better_seeing,
                                    comparison_title=comparison_title,
                                    template_title=template_title,
                                    field=field, comparison_epoch=epoch, template_epoch=template_epoch)
Exemple #2
0
def update_frb_sdss_photometry(frb: str, force: bool = False):
    """
    Retrieve SDSS photometry for the field of an FRB (with a valid param file in param_dir), in a 0.2 x 0.2 degree box
    centred on the FRB coordinates, and
    (Note - the width of the box is in RA degrees, not corrected for spherical distortion)
    :param frb: FRB name, FRBXXXXXX. Must match title of param file.
    :return: Retrieved photometry table, as a pandas dataframe, if successful; if not, None.
    """
    params = p.object_params_frb(frb)
    path = params['data_dir'] + "SDSS/SDSS.csv"
    outputs = p.frb_output_params(obj=frb)
    if outputs is None or "in_sdss" not in outputs or force:
        response = save_sdss_photometry(ra=params['burst_ra'], dec=params['burst_dec'], output=path)
        params = {}
        if response is not None:
            params["in_sdss"] = True
        else:
            params["in_sdss"] = False
        p.add_output_values_frb(obj=frb, params=params)
        return response
    elif outputs["in_sdss"] is True:
        print("There is already SDSS data present for this field.")
        return True
    else:
        print("This field is not present in SDSS.")
Exemple #3
0
def update_frb_des_photometry(frb: str, force: bool = False):
    """
    Retrieve DES photometry for the field of an FRB (with a valid param file in param_dir), in a 0.2 x 0.2 degree box
    centred on the FRB coordinates, and download it to the appropriate data directory.
    (Note - the width of the box is in RA degrees, not corrected for spherical distortion)
    Updates the "in_des" value (in output_values.yaml in the FRB data_dir path) to True if the data is successfully retrieved,
    and to False if not.
    If the data already exists in the FRB data_dir directory, or if the field is outside the DES footprint
    (as ascertained by a previous query and stored in output_values.yaml), no attempt is made (unless
    force is True).
    :param force: If True, ignores both the existence of the data in the data_dir directory and whether the field is
    in the DES footprint.
    :param frb: FRB name, FRBXXXXXX. Must match title of param file.
    :return: True if successful, False if not.
    """
    params = p.object_params_frb(frb)
    path = params['data_dir'] + "DES/DES.csv"
    outputs = p.frb_output_params(obj=frb)
    if outputs is None or "in_des" not in outputs or force:
        response = save_des_photometry(ra=params['burst_ra'], dec=params['burst_dec'], output=path)
        params = {}
        if response is not None:
            params["in_des"] = True
        else:
            params["in_des"] = False
        p.add_output_values_frb(obj=frb, params=params)
        return response
    elif outputs["in_des"] is True:
        print("There is already DES data present for this field.")
        return True
    else:
        print("This field is not present in DES.")
Exemple #4
0
def update_frb_skymapper_photometry(frb: str, force: bool = False):
    """
    Retrieve DES photometry for the field of an FRB (with a valid param file in param_dir), in a 0.2 deg radius cone
    centred on the FRB coordinates, and download it to the appropriate data directory.
    (Note - the width of the box is in RA degrees, not corrected for spherical distortion)
    :param frb: FRB name, FRBXXXXXX. Must match title of param file.
    :return: True if successful, False if not.
    """
    params = p.object_params_frb(frb)
    path = params['data_dir'] + "SkyMapper/SkyMapper.csv"
    outputs = p.frb_output_params(obj=frb)
    if outputs is None or "in_skymapper" not in outputs or force:
        response = save_skymapper_photometry(ra=params['burst_ra'], dec=params['burst_dec'], output=path)
        params = {}
        if response is not None:
            params["in_skymapper"] = True
        else:
            params["in_skymapper"] = False
        p.add_output_values_frb(obj=frb, params=params)
        return response
    elif outputs["in_skymapper"] is True:
        print("There is already SkyMapper data present for this field.")
        return True
    else:
        print("This field is not present in SkyMapper.")
def main(obj: str):
    matplotlib.rcParams.update({'errorbar.capsize': 3})

    frb_params = p.object_params_frb(obj=obj)

    print("\nExecuting Python script extinction_galactic.py, with:")
    print(f"\tobj {obj}")

    lambda_eff_interp = p.instrument_filters_single_param(param="lambda_eff",
                                                          instrument='FORS2',
                                                          sort_value=True)
    filters_interp = list(lambda_eff_interp.keys())
    lambda_eff_interp = list(lambda_eff_interp.values())

    extinction_path = frb_params['data_dir'] + 'galactic_extinction.txt'
    if not isfile(extinction_path):
        print(
            "Extinction bandpass data not found. Attempting retrieval from IRSA Dust Tool..."
        )
        update_frb_irsa_extinction(frb=obj)

    tbl = Table.read(frb_params['data_dir'] + 'galactic_extinction.txt',
                     format='ascii')
    tbl.sort('LamEff')
    lambda_eff_tbl = tbl['LamEff'] * 1000
    extinctions = tbl['A_SandF']

    extinctions_interp = np.interp(lambda_eff_interp, lambda_eff_tbl,
                                   extinctions)

    plt.errorbar(lambda_eff_tbl,
                 extinctions,
                 label='Calculated by IRSA',
                 fmt='o')
    plt.errorbar(lambda_eff_interp,
                 extinctions_interp,
                 label='Numpy Interpolated',
                 fmt='o')
    plt.title('Extinction Interpolation for FRB190102')
    plt.xlabel(r'Filter $\lambda_\mathrm{eff}}$ (nm)')
    plt.ylabel(r'Extinction (magnitude)')
    plt.legend()
    plt.close()

    to_write = {}
    for i, f in enumerate(filters_interp):
        value = float(extinctions_interp[i])
        to_write[f"{f}_ext_gal"] = value
    p.add_output_values_frb(obj=obj, params=to_write)
Exemple #6
0
def update_frb_irsa_extinction(frb: str):
    """
    Retrieves the extinction per bandpass table, and other relevant parameters, for a given sky position from the
    IRSA Dust Tool (https://irsa.ipac.caltech.edu/applications/DUST/) and writes it to disk.
    :param frb: FRB name, FRBXXXXXX. Must match title of param file.
    :return: Tuple: dictionary of retrieved values, table-formatted string.
    """
    params = p.object_params_frb(obj=frb)
    outputs = p.frb_output_params(obj=frb)
    data_dir = params['data_dir']
    if 'dust_ebv' not in outputs and not os.path.isfile(data_dir + "galactic_extinction.txt"):
        values, ext_str = save_irsa_extinction(ra=params['burst_ra'], dec=params['burst_dec'],
                                               output=data_dir + "galactic_extinction.txt")
        p.add_output_values_frb(obj=frb, params=values)
        return values, ext_str
    else:
        print("IRSA Dust Tool data already retrieved.")
def main(frb: str, new: bool):
    data_dir = p.config['top_data_dir']
    ra = dec = None
    if new:
        p.add_frb_param(obj=frb, params={"data_dir": data_dir + frb + "/"})
        print()
        print(
            f"Enter the FRB coordinates. These can be changed later by editing the file {p.param_dir}FRBs/{frb}.yaml")
        ra = input(f"Please enter the right ascension of {frb}:")
        try:
            ra = float(ra)
            ra = units.Quantity(ra, unit="deg")
        except ValueError:
            print()
        dec = input(f"Please enter the declination of {frb}:")
        try:
            dec = float(dec)
            dec = units.Quantity(dec, unit="deg")
        except ValueError:
            print()
    else:
        params = p.object_params_frb(obj=frb)

        na = [0.0, None]

        if params["burst_ra"] in na and params["burst_dec"] in na and params["burst_ra_str"] is not None and params[
            "burst_dec_str"] is not None:
            ra = params["burst_ra_str"]
            dec = params["burst_dec_str"]

    coords = SkyCoord(ra, dec)
    ra = float(coords.ra.value)
    dec = float(coords.dec.value)
    ra_str = str(coords.ra.to_string())
    dec_str = str(coords.dec.to_string())
    p.add_frb_param(obj=frb,
                    params={"burst_ra": ra, "burst_dec": dec, "burst_ra_str": ra_str, "burst_dec_str": dec_str})
Exemple #8
0
def update_frb_des_cutout(frb: str, force: bool = False):
    """

    :param frb:
    :return:
    """
    params = p.object_params_frb(obj=frb)
    outputs = p.frb_output_params(obj=frb)
    if "in_des" not in outputs:
        update_frb_des_photometry(frb=frb)
        outputs = p.frb_output_params(obj=frb)
    if force or outputs["in_des"]:
        path = params['data_dir'] + "DES/0-data/"
        files = os.listdir(path)
        condition = False
        for f in des_filters:
            if f"{f.lower()}_cutout.fits" not in files:
                condition = True
        if force or condition:
            return save_des_cutout(ra=params['burst_ra'], dec=params['burst_dec'], output=path)
        else:
            print("DES cutout already downloaded.")
    else:
        print("No DES cutout available for this position.")
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()
Exemple #10
0
def calculate_error_ellipse(frb: Union[str, dict], error: str = 'quadrature'):
    """
    Calculates the parameters of the uncertainty ellipse of an FRB, for use in plotting.
    :param frb: Either a string specifying the FRB, which must have a corresponding .yaml file in /param/FRBs, or a
        dictionary containing the same information.
    :param error: String specifying the type of error calculation to use. Available options are 'quadrature', which
        provides the quadrature sum of statistical and systematic uncertainty; 'systematic'; and 'statistical'.
    :return: (a, b, theta) as floats in a tuple, in units of degrees.
    """
    if error == 'quadrature':

        if type(frb) is str:
            frb = p.object_params_frb(frb)

        if frb['burst_err_stat_a'] == 0.0 or frb['burst_err_stat_b'] == 0.0:

            ra_frb = frb['burst_dec']
            dec_frb = frb['burst_dec']

            ra_stat = frb['burst_err_stat_ra']
            ra_sys = frb['burst_err_sys_ra']
            ra = np.sqrt(ra_stat**2 + ra_sys**2)

            a = SkyCoord(f'0h0m0s {dec_frb}d').separation(
                SkyCoord(f'0h0m{ra}s {dec_frb}d')).value

            dec_stat = frb['burst_err_stat_dec'] / 3600
            dec_sys = frb['burst_err_sys_dec'] / 3600
            dec = np.sqrt(dec_stat**2 + dec_sys**2)
            b = SkyCoord(f'{ra_frb}d {dec_frb}d').separation(
                SkyCoord(f'{ra_frb}d {dec_frb + dec}d')).value

            theta = 0.0

        else:

            a_stat = frb['burst_err_stat_a']
            a_sys = frb['burst_err_sys_a']
            a = np.sqrt(a_stat**2 + a_sys**2) / 3600

            b_stat = frb['burst_err_stat_b']
            b_sys = frb['burst_err_sys_b']
            b = np.sqrt(b_stat**2 + b_sys**2) / 3600

            theta = frb['burst_err_theta']

    elif error == 'systematic':

        if frb['burst_err_stat_a'] == 0.0 or frb['burst_err_stat_b'] == 0.0:

            ra_frb = frb['burst_dec']
            dec_frb = frb['burst_dec']

            ra_sys = frb['burst_err_sys_ra']

            a = SkyCoord(f'0h0m0s {dec_frb}d').separation(
                SkyCoord(f'0h0m{ra_sys}s {dec_frb}d')).value

            dec_sys = frb['burst_err_sys_dec'] / 3600
            b = SkyCoord(f'{ra_frb}d {dec_frb}d').separation(
                SkyCoord(f'{ra_frb}d {dec_frb + dec_sys}d')).value

            theta = 0.0

        else:
            a = frb['burst_err_sys_a'] / 3600
            b = frb['burst_err_sys_b'] / 3600
            theta = frb['burst_err_theta']

    elif error == 'statistical':

        if frb['burst_err_stat_a'] == 0.0 or frb['burst_err_stat_b'] == 0.0:

            ra_frb = frb['burst_dec']
            dec_frb = frb['burst_dec']

            ra_stat = frb['burst_err_stat_ra']

            a = SkyCoord(f'0h0m0s {dec_frb}d').separation(
                SkyCoord(f'0h0m{ra_stat}s {dec_frb}d')).value

            dec_stat = frb['burst_err_stat_dec'] / 3600
            b = SkyCoord(f'{ra_frb}d {dec_frb}d').separation(
                SkyCoord(f'{ra_frb}d {dec_frb + dec_stat}d')).value

            theta = 0.0

        else:
            a = frb['burst_err_stat_a'] / 3600
            b = frb['burst_err_stat_b'] / 3600
            theta = frb['burst_err_theta']

    else:
        raise ValueError('error type not recognised.')

    # print(a * 3600)
    # print(b * 3600)

    return a, b, theta
Exemple #11
0
def main(field, destination, epoch, instrument, template_instrument,
         comparison_type):
    if destination[-1] != '/':
        destination = destination + '/'

    # p.refresh_params_frbs()
    # types = ['multi_frb_range', 'multi_sn_models', 'multi_sn_random', 'multi_sn_random_ia', 'multi_sn_random_ib']
    # if comparison_type not in types:
    #     raise ValueError(comparison_type + ' is not a valid multi-synthetic argument; choose from ' + str(types))
    comparison_type = '_' + comparison_type
    type_suffix = comparison_type[7:]

    params = p.object_params_frb(field)
    u.mkdir_check(f'{params["data_dir"]}subtraction/')
    destination_path = f'{params["data_dir"]}subtraction/{destination}/'
    u.mkdir_check(destination_path)

    comparison_title = f'{field}_{epoch}'

    comparison_paths = p.object_output_paths(obj=comparison_title,
                                             instrument=instrument)

    comparison_origin_top = comparison_paths['subtraction_image_synth_' +
                                             type_suffix]
    comparison_tests = os.listdir(comparison_origin_top)

    comparison_params = p.object_params_instrument(obj=comparison_title,
                                                   instrument=instrument)

    params = p.object_params_frb(field)
    template_epoch = params['template_epoch_' + template_instrument.lower()]

    template_title = f'{field}_{template_epoch}'
    template_paths = p.object_output_paths(obj=template_title,
                                           instrument=template_instrument)
    template_outputs = p.object_output_params(obj=template_title,
                                              instrument=template_instrument)
    template_params = p.object_params_instrument(
        obj=template_title, instrument=template_instrument)

    filters = params['filters']

    for test in comparison_tests:

        destination_test = destination_path + test + '/'
        origin_test = comparison_origin_top + test + '/'
        u.mkdir_check(destination_test)

        test_files = os.listdir(origin_test)

        for f in filters:

            for file in filter(lambda fil: fil[:2] != f + '_',
                               os.listdir(origin_test)):
                shutil.copyfile(origin_test + file, destination_test + file)

            values = {}

            f_0 = f[0]
            destination_path_filter = f'{destination_test}{f}/'
            u.mkdir_check(destination_path_filter)

            # COMPARISON IMAGE:

            # Get path to comparison image from parameter .yaml file

            comparison_origin = origin_test + filter(
                lambda file: file[0] == f_0 and file[-5:] == '.fits',
                test_files).__next__()

            comparison_destination = f'{comparison_title}_comparison.fits'

            shutil.copyfile(comparison_origin,
                            destination_path_filter + comparison_destination)
            shutil.copyfile(
                comparison_origin.replace('.fits',
                                          '.csv'), destination_path_filter +
                comparison_destination.replace('.fits', '.csv'))

            print('Copying comparison image from:')
            print('\t', comparison_origin)

            print('To:')
            print(f'\t {destination_test}{f}/{comparison_destination}')
            shutil.copy(
                comparison_params['data_dir'] + 'output_values.yaml',
                f'{destination_test}{f}/{comparison_title}_comparison_output_values.yaml'
            )
            shutil.copy(
                comparison_params['data_dir'] + 'output_values.json',
                f'{destination_test}{f}/{comparison_title}_comparison_output_values.json'
            )
            shutil.copy(comparison_origin,
                        f'{destination_test}{f}/{comparison_destination}')
            values['comparison_file'] = comparison_origin

            if template_instrument != 'FORS2':

                # TEMPLATE IMAGE

                if template_instrument != 'XSHOOTER':
                    f_0 = f_0.lower()

                template_image_name = template_params['subtraction_image']
                if f'{f_0}_{template_image_name}' in template_paths:
                    template_origin = template_paths[
                        f'{f_0}_{template_image_name}']
                elif f'{f_0.lower()}_{template_image_name}' in template_paths:
                    template_origin = template_paths[
                        f'{f_0.lower()}_{template_image_name}']
                else:
                    raise ValueError(
                        f'{f_0.lower()}_{template_image_name} not found in {template_title} paths'
                    )
                fwhm_template = template_outputs[f_0 + '_fwhm_pix']
                template_destination = f'{template_title}_template.fits'

                print('Copying template from:')
                print('\t', template_origin)
                print('To:')
                print(f'\t {destination_test}{f}/{template_destination}')
                shutil.copy(
                    template_params['data_dir'] + 'output_values.yaml',
                    f'{destination_test}{f}/{template_title}_template_output_values.yaml'
                )
                shutil.copy(
                    template_params['data_dir'] + 'output_values.json',
                    f'{destination_test}{f}/{template_title}_template_output_values.json'
                )
                shutil.copy(template_origin,
                            f'{destination_test}{f}/{template_destination}')
                values['template_file'] = comparison_origin

                p.add_params(f'{destination_test}{f}/output_values.yaml',
                             values)
Exemple #12
0
def tweak_final(sextractor_path: str,
                destination: str,
                epoch: str,
                instrument: str,
                show: bool,
                tolerance: float = 10.,
                output_suffix: str = 'astrometry',
                input_suffix='coadded',
                stars_only: bool = False,
                path_add: str = 'subtraction_image',
                manual: bool = False,
                specific_star: bool = False):
    """
    A wrapper for tweak, to interface with the .yaml param files and provide offsets to all filters used in an
    observation.
    :param sextractor_path: Path to SExtractor-generated catalogue.
    :param destination: Directory to write tweaked image to.
    :param epoch: The epoch number of the observation to be tweaked.
    :param instrument: The instrument on which the observation was taken.
    :param show: Plot matches onscreen?
    :param tolerance: Tolerance, in pixels, within which matches will be accepted.
    :param output_suffix: String to append to filename of output file.
    :param input_suffix: Suffix appended to filenmae of input file.
    :param stars_only: Only match using stars, determined using SExtractor's 'class_star' output.
    :param path_add: Key under which to add the output path in the 'output_paths.yaml' file.
    :param manual: Use manual offset?
    :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.
    :return: None
    """
    u.mkdir_check(destination)
    properties = p.object_params_instrument(obj=epoch, instrument=instrument)
    frb_properties = p.object_params_frb(obj=epoch[:-2])
    cat_name = properties['cat_field_name']
    manual = properties['manual_astrometry'] and manual
    cat_path = frb_properties['data_dir'] + cat_name.upper(
    ) + "/" + cat_name.upper() + ".csv"

    if cat_path is not None:

        outputs = p.object_output_params(obj=epoch, instrument=instrument)
        filters = outputs['filters']

        param_dict = {}

        for filt in filters:

            print(filt)

            f = filt[0]

            if manual:

                offset_x = properties[f + '_offset_x']
                offset_y = properties[f + '_offset_y']

            else:
                offset_x = None
                offset_y = None

            if specific_star:
                burst_properties = p.object_params_frb(epoch[:-2])
                star_ra = burst_properties['alignment_ra']
                star_dec = burst_properties['alignment_dec']

            else:
                star_ra = star_dec = None

            param = tweak(
                sextractor_path=sextractor_path + f + '_psf-fit.cat',
                destination=destination + f + '_' + output_suffix + '.fits',
                image_path=destination + f + '_' + input_suffix + '.fits',
                cat_path=cat_path,
                cat_name=cat_name,
                tolerance=tolerance,
                show=show,
                stars_only=stars_only,
                manual=manual,
                offset_x=offset_x,
                offset_y=offset_y,
                specific_star=specific_star,
                star_ra=star_ra,
                star_dec=star_dec)

            for par in param:
                param_dict[f + '_' + par] = param[par]

            p.add_output_path(obj=epoch,
                              key=f + '_' + path_add,
                              path=destination + f + '_' + output_suffix +
                              '.fits',
                              instrument=instrument)

        p.add_params(properties['data_dir'] + 'output_values.yaml',
                     params=param_dict)

    else:
        print('No catalogue found for this alignment.')
Exemple #13
0
def plot_difference(fig: plt.figure, path: str, obj: str, instrument: str,
                    frame: Union[int, float], world_frame: bool = True,
                    n: int = 1, n_y: int = 1, show_title: bool = True,
                    cmap: str = 'viridis', show_cbar: bool = False, stretch: str = 'sqrt', vmin: float = None,
                    vmax: float = None, show_grid: bool = False,
                    ticks: int = None, interval: str = 'minmax',
                    show_coords=False, show_frb: bool = False,
                    font_size: int = 12
                    ):
    params = p.object_params_frb(obj=obj)
    ra = params['hg_ra']
    dec = params['hg_dec']

    titles = ['FORS2', instrument, f'FORS2 - {instrument}']

    difference_path = path + filter(lambda f: "difference.fits" in f, os.listdir(path)).__next__()

    template = list(filter(lambda f: "template_tweaked.fits" in f, os.listdir(path)))
    if not template:
        template_file = filter(lambda f: "template_aligned.fits" in f, os.listdir(path)).__next__()
        print('Using reprojected template')
    else:
        template_file = template[0]
        print('Using aligned template')

    template_path = path + template_file

    comparison = list(filter(lambda f: "comparison_tweaked.fits" in f, os.listdir(path)))
    if not comparison:
        comparison_file = filter(lambda f: "comparison_aligned.fits" in f, os.listdir(path)).__next__()
        print('Using reprojected comparison')
    else:
        comparison_file = comparison[0]
        print('Using aligned comparison')

    comparison_path = path + comparison_file

    paths = [comparison_path, template_path, difference_path]
    path_names = ['Comparison', 'Template', 'Difference']

    for i, image_path in enumerate(paths):
        print()
        print(path_names[i])
        n_x = i + 1

        print(image_path)

        hdu = fits.open(image_path)
        header = hdu[0].header

        ylabel = None

        if show_title:
            title = titles[i]
            if n_x != 3:
                title = title + ', MJD ' + str(int(np.round(header['MJD-OBS'])))
            if show_frb and n_x == 1:
                ylabel = obj.replace('FRB', 'FRB\,')
        else:
            title = None

        plot, hdu = plot_subimage(fig=fig, hdu=hdu, ra=ra, dec=dec, frame=frame, world_frame=world_frame,
                                  title=title,
                                  n=(n - 1) * 3 + n_x, n_x=3, n_y=n_y, cmap=cmap, show_cbar=show_cbar, stretch=stretch,
                                  vmin=vmin,
                                  vmax=vmax, show_grid=show_grid, ticks=ticks, interval=interval,
                                  show_coords=show_coords, ylabel=ylabel, font_size=font_size)

        hdu.close()

    return fig
def main(obj, test, n, filter_dist, sn_type, instrument, limit):
    properties = p.object_params_instrument(obj, instrument=instrument)
    burst_properties = p.object_params_frb(obj=obj[:-2])
    output = p.object_output_params(obj=obj, instrument=instrument)
    paths = p.object_output_paths(obj=obj, instrument=instrument)

    z = burst_properties['z']
    mjd_burst = burst_properties['mjd_burst']
    ebv_mw = burst_properties['dust_ebv']

    mjd_obs = properties['mjd']
    synth_path = properties['data_dir'] + 'synthetic/'
    u.mkdir_check(synth_path)
    synth_path = synth_path + 'sn_random/'
    u.mkdir_check(synth_path)

    epoch = mjd_obs - mjd_burst

    f_0 = filter_dist[0]

    hg_ra = burst_properties['hg_ra']
    hg_dec = burst_properties['hg_dec']

    image_path = paths[f_0 + '_' + properties['subtraction_image']]

    image = fits.open(image_path)

    now = time.Time.now()
    now.format = 'isot'
    test += sn_type + '_'
    synth_path += test + str(now) + '/'
    u.mkdir_check(synth_path)

    filters = output['filters']

    if 'FRB190608' in obj:
        limit = 45

    psf_models = []
    for f in filters:
        sn.register_filter(f=f)
        psf_model = fits.open(paths[f[0] + '_psf_model'])
        psf_models.append(psf_model)

    for i in range(n):
        test_spec = test + str(i)
        test_path = synth_path + test_spec + '/'

        magnitudes = []
        mags_filters, model, x, y, tbl = sn.random_light_curves(
            sn_type=sn_type,
            filters=filters,
            image=image,
            hg_ra=hg_ra,
            hg_dec=hg_dec,
            z=z,
            ebv_mw=ebv_mw,
            output_path=test_path,
            output_title=test,
            limit=limit)
        days = mags_filters['days']

        for f in filters:
            magnitude = sn.magnitude_at_epoch(epoch=epoch,
                                              days=days,
                                              mags=mags_filters[f])
            print(f, 'mag:', magnitude)
            magnitudes.append(magnitude)

        ph.insert_synthetic(x=x,
                            y=y,
                            obj=properties,
                            test_path=test_path,
                            filters=filters,
                            magnitudes=magnitudes,
                            suffix='sn_random_random_' + sn_type,
                            extra_values=tbl,
                            paths=paths,
                            output_properties=output,
                            psf_models=psf_models,
                            instrument=instrument)

    p.add_output_path(obj=obj,
                      key='subtraction_image_synth_sn_random_' + sn_type,
                      path=synth_path,
                      instrument=instrument)
def plot_galaxy(fig: plt.Figure, data_title: str, instrument: str, f: str, ra: float, dec: float,
                frame: Union[int, float], world_frame: bool = False,
                n: int = 1, n_x: int = 1, n_y: int = 1,
                cmap: str = 'viridis', show_cbar: bool = False, stretch: str = 'sqrt', vmin: float = None,
                vmax: float = None,
                show_filter: bool = True, show_instrument: bool = False,
                show_grid: bool = False,
                image_name: str = 'astrometry_image',
                object_name: str = None, ticks: int = None, interval: str = 'minmax',
                show_coords=True,
                reverse_y=False,
                show_frb=False, ellipse_colour: str = 'white',
                line_width=1.):
    instrument = instrument.lower()
    instruments = {'fors2': 'FORS2', 'imacs': 'IMACS', 'xshooter': 'X-shooter', 'gmos': 'GMOS',
                   'hst': 'Hubble Space Telescope'}

    if instrument == 'imacs':
        f_0 = f
    else:
        f_0 = f[0]

    epoch_properties = p.object_params_instrument(obj=data_title, instrument=instrument)
    paths = p.object_output_paths(obj=data_title, instrument=instrument)

    if 'sdss' in image_name:
        instrument_formal = 'SDSS'
    elif 'des' in image_name:
        instrument_formal = 'DES'
    else:
        instrument_formal = instruments[instrument]

    print(f_0)
    print(image_name)
    print(f_0 + '_' + image_name)
    if f_0 + '_' + image_name in paths:
        path = paths[f_0 + '_' + image_name]
    elif f_0 + '_' + image_name in epoch_properties:
        path = epoch_properties[f_0 + '_' + image_name]
    else:
        raise ValueError(f'No path for {f_0}_{image_name} found.')

    title = object_name
    if title is None:
        title = ''
        if show_instrument:
            title += f'({instrument_formal}'
        if show_filter:
            if instrument == 'imacs':
                title += f'${f[-1]}$-band'
            else:
                title += f'${f_0}$-band'

    else:
        if show_filter:
            if instrument == 'imacs':
                title += f' (${f[-1]}$-band)'
            else:
                title += f' (${f_0}$-band)'
        if show_instrument:
            title = title.replace('(', f'({instrument_formal}, ')

    plot, hdu_cut = plot_subimage(fig=fig, hdu=path, ra=ra, dec=dec,
                                  frame=frame, world_frame=world_frame, title=title,
                                  n=n, n_x=n_x, n_y=n_y,
                                  cmap=cmap, show_cbar=show_cbar, stretch=stretch, vmin=vmin,
                                  vmax=vmax,
                                  show_grid=show_grid,
                                  ticks=ticks, interval=interval,
                                  show_coords=show_coords,
                                  reverse_y=reverse_y,
                                  )

    burst_name = data_title[:data_title.find("_")]
    name = burst_name[3:]
    burst_properties = p.object_params_frb(burst_name)
    burst_ra = burst_properties['burst_ra']
    burst_dec = burst_properties['burst_dec']

    if show_frb is True:
        show_frb = 'quadrature'

    if show_frb == 'all':
        # Statistical
        a, b, theta = am.calculate_error_ellipse(burst_properties, error='statistical')
        plot_gal_params(hdu=hdu_cut, ras=[burst_ra], decs=[burst_dec], a=[a],
                        b=[b],
                        theta=[-theta], colour=ellipse_colour, ls='-')
        # Systematic
        a, b, theta = am.calculate_error_ellipse(burst_properties, error='systematic')
        plot_gal_params(hdu=hdu_cut, ras=[burst_ra], decs=[burst_dec], a=[a],
                        b=[b],
                        theta=[-theta], colour=ellipse_colour, ls='--')
        # Quadrature
        a, b, theta = am.calculate_error_ellipse(burst_properties, error='quadrature')
        plot_gal_params(hdu=hdu_cut, ras=[burst_ra], decs=[burst_dec], a=[a],
                        b=[b],
                        theta=[-theta], colour=ellipse_colour, ls=':')

    elif show_frb is not False:
        a, b, theta = am.calculate_error_ellipse(burst_properties, error=show_frb)
        plot_gal_params(hdu=hdu_cut, ras=[burst_ra], decs=[burst_dec], a=[a],
                        b=[b],
                        theta=[-theta], colour=ellipse_colour, ls='-', lw=line_width)

    return plot, hdu_cut
Exemple #16
0
def plot_hg(data_title: str, instrument: str, f: str, frame: int,
            fig: plt.figure, n: int = 1, n_x: int = 1, n_y: int = 1,
            show_frb: Union[bool, str] = False, ellipse_colour: str = 'white',
            cmap: str = 'viridis', show_cbar: bool = False, stretch: str = 'sqrt', vmin: float = None,
            vmax: float = None,
            bar_colour: str = 'white',
            show_filter: bool = True,
            show_hg: bool = False, show_grid: bool = False, show_z: bool = True, z_colour: str = 'white',
            image_name: str = 'astrometry_image',
            show_instrument: bool = False,
            ticks: int = None,
            show_distance: bool = True, bar_position: str = 'left',
            show_coords: bool = True,
            show_name: bool = True,
            reverse_y=False):
    instrument = instrument.lower()
    instruments = {'fors2': 'FORS2', 'imacs': 'IMACS', 'xshooter': 'X-shooter', 'gmos': 'GMOS'}
    if instrument not in instruments:
        raise ValueError('Instrument not recognised.')

    burst_name = data_title[:-2]
    name = burst_name[3:]
    burst_properties = p.object_params_frb(burst_name)

    hg_ra = burst_properties['hg_ra']
    hg_dec = burst_properties['hg_dec']

    burst_ra = burst_properties['burst_ra']
    burst_dec = burst_properties['burst_dec']

    ang_size_distance = burst_properties['ang_size_distance']

    if show_name:
        object_name = f'HG\,{name}'
    else:
        object_name = ''

    plot, hdu_cut = plot_galaxy(data_title=data_title, instrument=instrument, f=f, ra=hg_ra, dec=hg_dec, frame=frame,
                                fig=fig,
                                n=n, n_x=n_x, n_y=n_y, cmap=cmap, show_cbar=show_cbar, stretch=stretch, vmin=vmin,
                                vmax=vmax,
                                show_grid=show_grid,
                                show_filter=show_filter, image_name=image_name, show_instrument=show_instrument,
                                object_name=object_name, ticks=ticks, show_coords=show_coords, reverse_y=reverse_y)

    if show_z:
        if reverse_y:
            plt.text(frame / 15, frame / 5, f'z = {burst_properties["z"]}', color=z_colour)
        else:
            plt.text(frame / 15, frame * 2 - frame / 5, f'z = {burst_properties["z"]}', color=z_colour)

    # cbar.set_label('ADU/s', rotation=270)

    if show_distance:
        if bar_position == 'left':

            distance_bar(hdu=hdu_cut, ang_size_distance=ang_size_distance, angle_length=1.0, x=frame / 15,
                         y=frame / 4.5,
                         colour=bar_colour, spread=frame / 10, reverse_y=reverse_y, frame=frame)
        elif bar_position == 'right':
            distance_bar(hdu=hdu_cut, ang_size_distance=ang_size_distance, angle_length=1.0, x=frame * 2 - frame / 1.8,
                         y=frame / 4.5,
                         colour=bar_colour, spread=frame / 10, reverse_y=reverse_y, frame=frame)
        else:
            raise ValueError('Bar position not recognised.')

    if show_frb is True:
        show_frb = 'quadrature'

    if show_frb == 'all':
        # Statistical
        a, b, theta = am.calculate_error_ellipse(burst_properties, error='statistical')
        plot_gal_params(hdu=hdu_cut, ras=[burst_ra], decs=[burst_dec], a=[a],
                        b=[b],
                        theta=[-theta], colour=ellipse_colour, line_style='-')
        # Systematic
        a, b, theta = am.calculate_error_ellipse(burst_properties, error='systematic')
        plot_gal_params(hdu=hdu_cut, ras=[burst_ra], decs=[burst_dec], a=[a],
                        b=[b],
                        theta=[-theta], colour=ellipse_colour, line_style='--')
        # Quadrature
        a, b, theta = am.calculate_error_ellipse(burst_properties, error='quadrature')
        plot_gal_params(hdu=hdu_cut, ras=[burst_ra], decs=[burst_dec], a=[a],
                        b=[b],
                        theta=[-theta], colour=ellipse_colour, line_style=':')

    elif show_frb is not False:
        a, b, theta = am.calculate_error_ellipse(burst_properties, error=show_frb)
        plot_gal_params(hdu=hdu_cut, ras=[burst_ra], decs=[burst_dec], a=[a],
                        b=[b],
                        theta=[-theta], colour=ellipse_colour, line_style='-')

        # burst_x, burst_y = wcs_cut.all_world2pix(burst_ra, burst_dec, 0)
        # plt.scatter(burst_x, burst_y)
    if show_hg:
        wcs_cut = wcs.WCS(header=hdu_cut[0].header)
        hg_x, hg_y = wcs_cut.all_world2pix(hg_ra, hg_dec, 0)
        plt.scatter(hg_x, hg_y, marker='x', c='r')

    return fig, hdu_cut
Exemple #17
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)
Exemple #18
0
def main(
    field_name: str,
    epoch_name: str,
    imaging: bool,
    spectroscopy: bool,
    instrument: str,
    furby_path: str,
    do: str,
    do_not_reuse_masters: bool,
    overwrite_download: bool,
    distance_tolerance: float,
    snr_min: float,
    class_star_tolerance: float,
    debug_level: int,
):
    u.debug_level = debug_level

    new_field = False

    directory = fld.load_epoch_directory()
    if epoch_name is not None:
        print(f"Looking for {epoch_name} in directory...")
        if epoch_name in directory:
            epoch_dict = directory[epoch_name]
            field_name = epoch_dict["field_name"]
            instrument = epoch_dict["instrument"]
            mode = epoch_dict["mode"]
            if mode == "imaging":
                imaging = True
            elif mode == "spectroscopy":
                spectroscopy = True
        else:
            print(f"{epoch_name} not found.")

    # Do automated FURBY process.
    if furby_path is not None:

        new_field = True
        furby = True

        imaging = True

        healpix_path = furby_path.replace(".json", "_hp.fits")
        if not os.path.isfile(healpix_path):
            healpix_path = None

        params = fld.FRBField.param_from_furby_json(
            json_path=furby_path,
            healpix_path=healpix_path,
        )
        field_name = params["name"]
        field = fld.Field.from_params(name=field_name)

        instrument = "vlt-fors2"

        epoch_name = f"{field_name}_FORS2_1"
        fld.FORS2ImagingEpoch.new_yaml(
            name=epoch_name,
            path=fld.FORS2ImagingEpoch.build_param_path(
                instrument_name=instrument,
                field_name=field_name,
                epoch_name=epoch_name),
            field=field.name,
            instrument=instrument,
            data_path=os.path.join(field_name, "imaging", instrument,
                                   epoch_name, ""))
        # epoch = fld.FORS2ImagingEpoch.from_params(
        #     name=epoch_name,
        #     instrument=instrument,
        #     field=field,
        #     old_format=False,
        # )

    else:
        if field_name is None:
            fields = ["New field"]
            fields += fld.list_fields()
            old_fields = fld.list_fields_old()
            for old_field in old_fields:
                if old_field not in fields and f"FRB20{old_field[3:]}" not in fields:
                    fields.append(old_field)
            opt, field_name = u.select_option(
                "No field specified. Please select one:",
                options=fields,
                sort=False)
            if opt == 0:
                new_field = True
                field_name = input("Please enter the name of the new field:\n")
        # Check for field param file
        if not new_field:
            field = fld.Field.from_params(name=field_name)
        else:
            field = None
        # If this field has no parameter file, ask to create one.
        if field is None:
            param_path = os.path.join(p.param_dir, "fields", "")
            # Check for old format param file, and ask to convert if found.
            old_field_name = f"FRB{field_name[-8:]}"
            old_params = p.object_params_frb(obj=old_field_name)
            print()
            field_param_path = os.path.join(param_path, field_name)
            u.mkdir_check(field_param_path)
            field_param_path_yaml = os.path.join(field_param_path,
                                                 f"{field_name}.yaml")
            if old_params is None:
                if not new_field:
                    print(f"{field_name} not found in the param directory.")
                if u.select_yn(
                        f"Create a new param file at '{field_param_path_yaml}'?"
                ):
                    fld.Field.new_params_from_input(
                        field_name=field_name,
                        field_param_path=field_param_path)
                else:
                    print("Exiting.")
                    exit(0)
            else:
                print("Old format param file detected.")
                if u.select_yn("Convert to new format?"):
                    fld.FRBField.convert_old_param(frb=old_field_name)
                else:
                    print("Exiting...")
                    exit(0)
            field = fld.Field.from_params(name=field_name)

    if spectroscopy:
        mode = "Spectroscopy"
    elif imaging:
        mode = "Imaging"
    else:
        _, mode = u.select_option(message="Please select a mode.",
                                  options=["Imaging", "Spectroscopy"])

    if mode == "Spectroscopy":
        if epoch_name is None:
            # Build a list of imaging epochs from that field.
            field.gather_epochs_spectroscopy()
            # Let the user select an epoch.
            epoch = field.select_epoch_spectroscopy()
        else:
            if instrument is None:
                instrument = fld.select_instrument(mode="spectroscopy")
            epoch = fld.SpectroscopyEpoch.from_params(epoch_name,
                                                      instrument=instrument,
                                                      field=field)

    else:  # if mode == "Imaging"
        if epoch_name is None:
            # Build a list of imaging epochs from that field.
            if type(field) is fld.FRBField:
                field.gather_epochs_old()
            field.gather_epochs_imaging()
            # Let the user select an epoch.
            epoch = field.select_epoch_imaging()
        else:
            if instrument is None:
                instrument = fld.select_instrument(mode="imaging")
            epoch = fld.ImagingEpoch.from_params(epoch_name,
                                                 instrument=instrument,
                                                 field=field)
            epoch.field = field

    u.debug_print(2, "pipeline.py: type(epoch) ==", type(epoch))
    epoch.do = do
    epoch.pipeline(do_not_reuse_masters=do_not_reuse_masters,
                   overwrite_download=overwrite_download,
                   distance_tolerance=distance_tolerance,
                   snr_min=snr_min,
                   class_star_tolerance=class_star_tolerance)
def main(destination, show, field, epoch, skip_reproject, offsets_yaml,
         copy_other_vals, f, manual, instrument_template):
    print('manual:', manual)
    properties = p.object_params_frb(field)
    alignment_ra = properties['alignment_ra']
    alignment_dec = properties['alignment_dec']
    skip_reproject = properties['skip_reproject'] or skip_reproject

    specific_star = False
    if alignment_dec != 0.0 and alignment_ra != 0.0 and offsets_yaml is not None:
        specific_star = True

    if destination[-1] != '/':
        destination = destination + '/'
    comparison = f'{field}_{epoch}_comparison.fits'

    if skip_reproject:
        comparison_tweaked = comparison.replace('comparison.fits',
                                                'comparison_aligned.fits')
    else:
        comparison_tweaked = comparison.replace('comparison.fits',
                                                'comparison_tweaked.fits')

    if offsets_yaml is not None:

        offsets = p.load_params(offsets_yaml)
        offset_ra = offsets['offset_ra']
        offset_dec = offsets['offset_dec']
        values = {'offset_ra': offset_ra, 'offset_dec': offset_dec}
        ast.offset_astrometry(hdu=destination + comparison,
                              offset_ra=offset_ra,
                              offset_dec=offset_dec,
                              output=destination + comparison_tweaked)

    else:
        if not manual:
            print('Doing specific star offset...')
            values = ast.tweak(sextractor_path=destination +
                               '/sextractor/alignment/comparison.cat',
                               destination=destination + comparison_tweaked,
                               image_path=destination + comparison,
                               cat_path=destination +
                               '/sextractor/alignment/template.cat',
                               cat_name='SExtractor',
                               tolerance=10.,
                               show=show,
                               stars_only=True,
                               psf=True,
                               specific_star=specific_star,
                               star_dec=alignment_dec,
                               star_ra=alignment_ra)
        else:
            print('Doing manual offset...')
            instrument_template = instrument_template.lower()
            manual_x = properties['offset_' + instrument_template + '_' +
                                  f[0] + '_x']
            manual_y = properties['offset_' + instrument_template + '_' +
                                  f[0] + '_y']
            values = ast.tweak(sextractor_path=destination +
                               '/sextractor/alignment/comparison.cat',
                               destination=destination + comparison_tweaked,
                               image_path=destination + comparison,
                               cat_path=destination +
                               '/sextractor/alignment/template.cat',
                               cat_name='SExtractor',
                               tolerance=10.,
                               show=show,
                               stars_only=True,
                               psf=True,
                               specific_star=specific_star,
                               star_dec=alignment_dec,
                               star_ra=alignment_ra,
                               manual=True,
                               offset_x=manual_x,
                               offset_y=manual_y)

    if instrument_template == 'FORS2':
        force = 2
    else:
        force = None

    if not skip_reproject:
        template = filter(lambda f: "template.fits" in f,
                          os.listdir(destination)).__next__()
        n = ff.reproject(
            image_1=destination + comparison_tweaked,
            image_2=destination + template,
            image_1_output=destination +
            comparison.replace('comparison.fits', 'comparison_aligned.fits'),
            image_2_output=destination +
            template.replace('template.fits', 'template_aligned.fits'),
            force=force)

        if n == 1:
            values['reprojected'] = 'comparison'
        else:
            values['reprojected'] = 'template'

    p.add_params(destination + 'output_values.yaml', values)
Exemple #20
0
# Code by Lachlan Marnoch, 2019
from astropy.coordinates import SkyCoord
import os
import numpy as np

from craftutils import params as p
from craftutils import astrometry as am

bursts = list(
    filter(lambda f: f[-5:] == '.yaml' and 'template' not in f,
           os.listdir('param/FRBs/')))
bursts.sort()

for burst in bursts:
    burst = burst[:-5]
    burst_params = p.object_params_frb(burst)

    hg_ra = burst_params['hg_ra']
    hg_dec = burst_params['hg_dec']
    hg_x_err = burst_params['hg_err_x']
    hg_y_err = burst_params['hg_err_y']

    hg_x_err = 2 * np.sqrt(hg_x_err)
    hg_y_err = 2 * np.sqrt(hg_y_err)

    a, b, theta = am.calculate_error_ellipse(burst_params, 'quadrature')

    burst_err = np.sqrt(a**2 + b**2)

    hg_err = np.sqrt(hg_x_err**2 + hg_y_err**2)
Exemple #21
0
def main(obj, test, n, mag_lower, mag_upper, colour_upper, colour_lower):
    properties = p.object_params_fors2(obj)
    output = p.object_output_params(obj=obj, instrument='FORS2')
    paths = p.object_output_paths(obj)
    burst_properties = p.object_params_frb(obj[:-2])

    synth_path = properties['data_dir'] + 'synthetic/'

    u.mkdir_check(synth_path)
    synth_path = synth_path + 'random/'
    u.mkdir_check(synth_path)
    now = time.Time.now()
    now.format = 'isot'
    test = str(now) + '_' + test
    test_path = synth_path + test + '/'
    u.mkdir_check(test_path)

    filters = {}
    bluest = None
    bluest_lambda = np.inf
    for f in output['filters']:
        filter_properties = p.filter_params(f=f, instrument='FORS2')
        filters[f] = filter_properties
        lambda_eff = filter_properties['lambda_eff']
        if lambda_eff < bluest_lambda:
            bluest_lambda = lambda_eff
            bluest = f

    # Insert random sources in the bluest filter.

    f_0 = bluest[0]
    output_properties = p.object_output_params(obj)
    fwhm = output_properties[f_0 + '_fwhm_pix']
    zeropoint, _, airmass, _ = ph.select_zeropoint(obj,
                                                   bluest,
                                                   instrument='fors2')

    base_path = paths[f_0 + '_subtraction_image']

    output_path = test_path + f_0 + '_random_sources.fits'
    _, sources = ph.insert_random_point_sources_to_file(file=base_path,
                                                        fwhm=fwhm,
                                                        output=output_path,
                                                        n=n,
                                                        airmass=airmass,
                                                        zeropoint=zeropoint)

    p.add_output_path(obj=obj,
                      key=f_0 + '_subtraction_image_synth_random',
                      path=output_path)

    # Now insert sources at the same positions in other filters, but with magnitudes randomised.
    for f in filters:
        if f != bluest:
            f_0 = f[0]
            output_properties = p.object_output_params(obj)
            fwhm = output_properties[f_0 + '_fwhm_pix']
            zeropoint, _, airmass, _ = ph.select_zeropoint(obj,
                                                           f,
                                                           instrument='fors2')

            base_path = paths[f_0 + '_subtraction_image']

            mag = np.random.uniform(mag_lower, mag_upper, size=n)

            output_path = test_path + f_0 + '_random_sources.fits'
            ph.insert_point_sources_to_file(file=base_path,
                                            fwhm=fwhm,
                                            output=output_path,
                                            x=sources['x_0'],
                                            y=sources['y_0'],
                                            mag=mag,
                                            airmass=airmass,
                                            zeropoint=zeropoint)

            p.add_output_path(obj=obj,
                              key=f_0 + '_subtraction_image_synth_random',
                              path=output_path)
Exemple #22
0
def main(data_dir, data_title, origin, destination, all_synths):
    print("\nExecuting Python script pipeline_fors2/5-background_subtract.py, with:")
    print(f"\tepoch {data_title}")
    print(f"\torigin directory {origin}")
    print(f"\tdestination directory {destination}")
    print()

    methods = ["ESO backgrounds only", "SExtractor backgrounds only", "polynomial fit", "Gaussian fit", "median value"]

    if all_synths:
        frame = 56
        method = "polynomial fit"
        degree = 5
        do_mask = True
        local = True
        global_sub = False
        trim_image = False
        recorrect_subbed = True
        eso_back = False

    else:
        frame = 200
        # frame_arcsec = 30 * units.arcsec
        # frame_deg = frame_arcsec.to(units.deg)

        eso_back = False

        _, method = u.select_option(message="Please select the background subtraction method.", options=methods,
                                 default="polynomial fit")
        degree = None
        if method == "polynomial fit":
            degree = u.user_input(message=f"Please enter the degree of {method} to use:", typ=int, default=3)
        elif method == "ESO backgrounds only":
            eso_back = True
        do_mask = False
        if method not in ["ESO backgrounds only", "SExtractor backgrounds only", "median value"]:
            do_mask = u.select_yn(message="Mask sources using SExtractor catalogue?", default=True)
        if method in ["polynomial fit", "Gaussian fit"]:
            local = u.select_yn(message="Use a local fit?", default=True)
        else:
            local = False
        global_sub = False
        trim_image = False
        recorrect_subbed = False
        if local:
            global_sub = u.select_yn(message="Subtract local fit from entire image?", default="n")
            if not global_sub:
                trim_image = u.select_yn(message="Trim images to subtracted region?", default="y")
                recorrect_subbed = u.select_yn(message="Re-normalise background of subtracted region?", default="y")

        # if not eso_back and method != "SExtractor backgrounds only":
        #     eso_back = u.select_yn(message="Subtract ESO Reflex fitted backgrounds first?", default=False)

    outputs = p.object_output_params(data_title, instrument='FORS2')

    data_dir = u.check_trailing_slash(data_dir)

    destination = u.check_trailing_slash(destination)
    destination = data_dir + destination
    u.mkdir_check_nested(destination)

    origin = u.check_trailing_slash(origin)
    science_origin = data_dir + origin + "science/"
    print(science_origin)

    filters = outputs['filters']
    frb_params = p.object_params_frb(obj=data_title[:-2])
    epoch_params = p.object_params_fors2(obj=data_title)

    background_origin_eso = ""
    if eso_back:
        background_origin_eso = data_dir + "/" + origin + "/backgrounds/"

    if method == "SExtractor backgrounds only":
        background_origin = f"{data_dir}{origin}backgrounds_sextractor/"
    elif method == "polynomial fit":
        background_origin = f"{destination}backgrounds/"  # f"{destination}backgrounds_{method.replace(' ', '')}_degree_{degree}_local_{local}_globalsub_{global_sub}/"
    else:
        background_origin = f"{destination}backgrounds/"  # f"{destination}backgrounds_{method.replace(' ', '')}_local_{local}_globalsub_{global_sub}/"

    trimmed_path = ""
    if trim_image:
        trimmed_path = f"{data_dir}{origin}trimmed_to_background/"
        u.mkdir_check_nested(trimmed_path)

    ra = frb_params["burst_ra"]
    dec = frb_params["burst_dec"]

    if all_synths:
        ras = epoch_params["test_synths"]["ra"]
        decs = epoch_params["test_synths"]["dec"]
    else:
        ras = [ra]
        decs = [dec]

    for fil in filters:
        trimmed_path_fil = ""
        if trim_image:
            trimmed_path_fil = f"{trimmed_path}{fil}/"
            u.mkdir_check(trimmed_path_fil)
        background_fil_dir = f"{background_origin}{fil}/"
        u.mkdir_check_nested(background_fil_dir)
        science_destination_fil = f"{destination}science/{fil}/"
        u.mkdir_check_nested(science_destination_fil)
        files = os.listdir(science_origin + fil + "/")
        for file_name in files:
            if file_name.endswith('.fits'):
                new_file = file_name.replace("norm", "bg_sub")
                new_path = f"{science_destination_fil}/{new_file}"
                print("NEW_PATH:", new_path)
                science = science_origin + fil + "/" + file_name
                # First subtract ESO Reflex background images
                # frame = (frame_deg / f.get_pixel_scale(file=science, astropy_units=True)[1]).to(f.pix).value
                if eso_back:
                    background_eso = background_origin_eso + fil + "/" + file_name.replace("SCIENCE_REDUCED",
                                                                                           "PHOT_BACKGROUND_SCI")

                    ff.subtract_file(file=science, sub_file=background_eso, output=new_path)
                    science_image = new_path

                if method != "ESO backgrounds only":

                    print(ra, dec)

                    print("Science image:", science)
                    science_image = fits.open(science)
                    print("Science file:", science_image)
                    wcs_this = WCS(header=science_image[0].header)

                    if method == "SExtractor backgrounds only":
                        background = background_origin + fil + "/" + file_name + "_back.fits"
                        print("Background image:", background)
                    else:
                        if method == "median value":
                            print(science_image[0].data.shape)
                            _, background_value, _ = sigma_clipped_stats(science_image[0].data)
                            background = deepcopy(science_image)

                            background[0].data = np.full(shape=science_image[0].data.shape, fill_value=background_value)
                            background_path = background_origin + fil + "/" + file_name.replace("SCIENCE_REDUCED",
                                                                                                "PHOT_BACKGROUND_MEDIAN")

                            # Next do background fitting.
                        else:

                            background = deepcopy(science_image)
                            background[0].data = np.zeros(background[0].data.shape)
                            background_path = background_origin + fil + "/" + file_name.replace("SCIENCE_REDUCED",
                                                                                                "PHOT_BACKGROUND_FITTED")

                            for i, ra in enumerate(ras):
                                dec = decs[i]
                                x, y = wcs_this.all_world2pix(ra, dec, 0)
                                print(x, y)

                                bottom, top, left, right = ff.subimage_edges(data=science_image[0].data, x=x, y=y,
                                                                             frame=frame)

                                if do_mask:
                                    # Produce a pixel mask that roughly masks out the true sources in the image so that
                                    # they don't get fitted.
                                    mask_max = 10
                                    _, pixel_scale = ff.get_pixel_scale(science_image)
                                    sextractor = Table.read(
                                        f"{data_dir}analysis/sextractor/4-divided_by_exp_time/{fil}/{file_name.replace('.fits', '_psf-fit.cat')}",
                                        format='ascii.sextractor')
                                    weights = np.ones(shape=science_image[0].data.shape)

                                    for obj in filter(
                                            lambda o: left < o["X_IMAGE"] < right and bottom < o["Y_IMAGE"] < top,
                                            sextractor):
                                        mask_rad = min(int(obj["A_WORLD"] * obj["KRON_RADIUS"] / pixel_scale), mask_max)
                                        x_prime = int(np.round(obj["X_IMAGE"]))
                                        y_prime = int(np.round(obj["Y_IMAGE"]))
                                        weights[y_prime - mask_rad:y_prime + mask_rad,
                                        x_prime - mask_rad:x_prime + mask_rad] = 0.0

                                    plt.imshow(weights, origin="lower")
                                    plt.savefig(
                                        background_origin + fil + "/" + file_name.replace("norm.fits", "mask.png"))
                                else:
                                    weights = None

                                background_this = fit_background_fits(image=science_image,
                                                                      model_type=method[:method.find(" ")],
                                                                      deg=degree, local=local,
                                                                      global_sub=global_sub,
                                                                      centre_x=x, centre_y=y, frame=frame,
                                                                      weights=weights)
                                background[0].data += background_this[0].data

                                if recorrect_subbed:
                                    offset = get_median_background(image=science,
                                                                   ra=epoch_params["renormalise_centre_ra"],
                                                                   dec=epoch_params["renormalise_centre_dec"], frame=50,
                                                                   show=False,
                                                                   output=new_path[
                                                                          :new_path.find("bg_sub")] + "renorm_patch_")
                                    print("RECORRECT_SUBBED:", recorrect_subbed)
                                    print("SUBTRACTING FROM BACKGROUND:", offset)
                                    print(bottom, top, left, right)
                                    print(background[0].data[bottom:top, left:right].shape)
                                    print(np.median(background[0].data[bottom:top, left:right]))
                                    background[0].data[bottom:top, left:right] -= offset
                                    print(np.median(background[0].data[bottom:top, left:right]))

                                if trim_image:
                                    print("TRIMMED_PATH_FIL:", trimmed_path_fil)

                                    science_image = ff.trim_file(path=science_image, left=left, right=right, top=top,
                                                                 bottom=bottom,
                                                                 new_path=trimmed_path_fil + file_name.replace(
                                                                     "norm.fits",
                                                                     "trimmed_to_back.fits"))
                                    print("Science after trim:", science_image)

                                    background = ff.trim_file(path=background, left=left, right=right, top=top,
                                                              bottom=bottom,
                                                              new_path=background_path)

                            print("Writing background to:")
                            print(background_path)
                            background.writeto(background_path, overwrite=True)

                    print("SCIENCE:", science_image)
                    print("BACKGROUND:", background)

                    subbed = ff.subtract_file(file=science_image, sub_file=background, output=new_path)

                    # # TODO: check if regions overlap
                    #
                    # plt.hist(subbed[0].data[int(y - frame + 1):int(y + frame - 1),
                    #          int(x - frame + 1):int(x + frame - 1)].flatten(),
                    #          bins=10)
                    # plt.savefig(new_path[:new_path.find("bg_sub")] + "histplot.png")
                    # plt.close()

    copyfile(data_dir + "/" + origin + "/" + data_title + ".log", destination + data_title + ".log")
    u.write_log(path=destination + data_title + ".log",
                action=f'Backgrounds subtracted using 4-background_subtract.py with method {method}\n')
Exemple #23
0
def main(field, destination, epoch, instrument, template_instrument,
         comparison_type):
    if destination[-1] != '/':
        destination = destination + '/'

    p.refresh_params_frbs()
    types = ['normal', 'synth_random', 'synth_frb']
    if comparison_type not in types:
        raise ValueError(comparison_type +
                         ' is not a valid synthetic argument; choose from ' +
                         str(types))
    if comparison_type == 'normal':
        comparison_type = ''
    else:
        comparison_type = '_' + comparison_type

    params = p.object_params_frb(field)
    u.mkdir_check(f'{params["data_dir"]}subtraction/')
    destination_path = f'{params["data_dir"]}subtraction/{destination}/'
    u.mkdir_check(destination_path)

    comparison_title = f'{field}_{epoch}'

    comparison_paths = p.object_output_paths(obj=comparison_title,
                                             instrument=instrument)
    comparison_params = p.object_params_instrument(obj=comparison_title,
                                                   instrument=instrument)

    params = p.object_params_frb(field)
    template_epoch = params['template_epoch_' + template_instrument.lower()]

    template_title = f'{field}_{template_epoch}'
    template_paths = p.object_output_paths(obj=template_title,
                                           instrument=template_instrument)
    template_outputs = p.object_output_params(obj=template_title,
                                              instrument=template_instrument)
    template_params = p.object_params_instrument(
        obj=template_title, instrument=template_instrument)

    filters = params['filters']
    for f in filters:

        values = {}

        f_0 = f[0]
        destination_path_filter = f'{destination_path}{f}/'
        u.mkdir_check(destination_path_filter)

        # COMPARISON IMAGE:

        comparison_image_name = comparison_params[
            'subtraction_image'] + comparison_type

        # Get path to comparison image from parameter .yaml file
        if f'{f_0}_{comparison_image_name}' in comparison_paths:
            comparison_origin = comparison_paths[
                f'{f_0}_{comparison_image_name}']
        elif f'{f_0.lower()}_{comparison_image_name}' in comparison_paths:
            comparison_origin = comparison_paths[
                f'{f_0.lower()}_{comparison_image_name}']
        else:
            raise ValueError(
                f'{f_0.lower()}_{comparison_image_name} not found in {comparison_title} paths'
            )

        comparison_destination = f'{comparison_title}_comparison.fits'

        if comparison_type != '':
            shutil.copyfile(
                comparison_origin.replace('.fits',
                                          '.csv'), destination_path_filter +
                comparison_destination.replace('.fits', '.csv'))

        print('Copying comparison image')
        print('From:')
        print('\t', comparison_origin)

        print('To:')
        print(f'\t {destination_path}{f}/{comparison_destination}')
        shutil.copy(
            comparison_params['data_dir'] + 'output_values.yaml',
            f'{destination_path}{f}/{comparison_title}_comparison_output_values.yaml'
        )
        shutil.copy(
            comparison_params['data_dir'] + 'output_values.json',
            f'{destination_path}{f}/{comparison_title}_comparison_output_values.json'
        )
        shutil.copy(comparison_origin,
                    f'{destination_path}{f}/{comparison_destination}')
        values['comparison_file'] = comparison_origin

        # TEMPLATE IMAGE

        if template_instrument != 'FORS2' and template_instrument != 'XSHOOTER':
            f_0 = f_0.lower()

        template_image_name = template_params[
            'subtraction_image'] + comparison_type
        if f'{f_0}_{template_image_name}' in template_paths:
            template_origin = template_paths[f'{f_0}_{template_image_name}']
        elif f'{f_0.lower()}_{template_image_name}' in template_paths:
            template_origin = template_paths[
                f'{f_0.lower()}_{template_image_name}']
        else:
            raise ValueError(
                f'{f_0.lower()}_{template_image_name} not found in {template_title} paths'
            )
        fwhm_template = template_outputs[f_0 + '_fwhm_pix']
        template_destination = f'{template_title}_template.fits'

        print('Copying template')
        print('From:')
        print('\t', template_origin)
        print('To:')
        print(f'\t {destination_path}{f}/{template_destination}')
        shutil.copy(
            template_params['data_dir'] + 'output_values.yaml',
            f'{destination_path}{f}/{template_title}_template_output_values.yaml'
        )
        shutil.copy(
            template_params['data_dir'] + 'output_values.json',
            f'{destination_path}{f}/{template_title}_template_output_values.json'
        )
        shutil.copy(template_origin,
                    f'{destination_path}{f}/{template_destination}')
        values['template_file'] = comparison_origin

        p.add_params(f'{destination_path}{f}/output_values.yaml', values)
Exemple #24
0
def main(obj, test, n, filter_dist, instrument, limit):
    properties = p.object_params_instrument(obj, instrument=instrument)
    burst_properties = p.object_params_frb(obj=obj[:-2])
    output = p.object_output_params(obj=obj, instrument=instrument)
    paths = p.object_output_paths(obj=obj, instrument=instrument)

    z = burst_properties['z']
    mjd_burst = burst_properties['mjd_burst']
    ebv_mw = burst_properties['dust_ebv']

    mjd_obs = properties['mjd']
    synth_path = properties['data_dir'] + 'synthetic/'
    u.mkdir_check(synth_path)
    synth_path = synth_path + 'sn_random/'
    u.mkdir_check(synth_path)

    epoch = mjd_obs - mjd_burst

    f_0 = filter_dist[0]

    hg_ra = burst_properties['hg_ra']
    hg_dec = burst_properties['hg_dec']

    burst_ra = burst_properties['burst_ra']
    burst_dec = burst_properties['burst_dec']

    image_path = paths[f_0 + '_' + properties['subtraction_image']]

    image = fits.open(image_path)

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

    burst_x, burst_y = wcs_info.all_world2pix(burst_ra, burst_dec, 0)

    now = time.Time.now()
    now.format = 'isot'
    synth_path += test + '_' + str(now) + '/'
    u.mkdir_check(synth_path)

    filters = output['filters']

    psf_models = []
    for i, f in enumerate(filters):
        sn.register_filter(f=f, instrument=instrument)
        psf_model = fits.open(paths[f[0] + '_psf_model'])
        psf_models.append(psf_model)

    for i in range(n):
        test_spec = test + '_' + str(i)
        test_path = synth_path + test_spec + '/'

        magnitudes = []
        mags_filters, model, x, y, tbl = sn.random_light_curves_type_ia(
            filters=filters,
            image=image,
            hg_ra=hg_ra,
            hg_dec=hg_dec,
            z=z,
            ebv_mw=ebv_mw,
            output_path=test_path,
            output_title=test,
            limit=limit,
            x=burst_x,
            y=burst_y,
            ra=burst_ra,
            dec=burst_dec)
        days = mags_filters['days']

        for f in filters:
            magnitude = sn.magnitude_at_epoch(epoch=epoch,
                                              days=days,
                                              mags=mags_filters[f])
            print(f, 'mag:', magnitude)
            magnitudes.append(magnitude)

        ph.insert_synthetic(x=float(x),
                            y=float(y),
                            obj=properties,
                            test_path=test_path,
                            filters=filters,
                            magnitudes=magnitudes,
                            suffix='sn_random_random_ia',
                            extra_values=tbl,
                            paths=paths,
                            output_properties=output,
                            psf_models=psf_models,
                            instrument=instrument)

    p.add_output_path(obj=obj,
                      key='subtraction_image_synth_sn_random_ia',
                      path=synth_path,
                      instrument=instrument)
Exemple #25
0
def main(field, subtraction_path, epoch, instrument):
    comparison_name = f'{field}_{epoch}'

    params = p.object_params_frb(field)
    ra_burst = params['burst_ra']
    dec_burst = params['burst_dec']
    burst_err_a = params['burst_err_a']
    burst_err_b = params['burst_err_b']
    burst_err_theta = params['burst_err_theta']
    comparison_params = p.object_params_instrument(comparison_name, instrument)

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

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

        template_epoch = params['template_epoch']

        comparison_extinction = comparison_params[f_0 + '_ext_up']

        cat_generated_file = filter(lambda file: file[-15:] == '_comparison.csv',
                                    os.listdir(f'{destination_path_filter}')).__next__()
        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_generated_path = f'{destination_path_filter}{cat_generated_file}'
        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_generated = table.Table.read(cat_generated_path, format='ascii.csv')
        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, _ = ph.select_zeropoint(comparison_name, f, instrument=instrument)

        plotting.plot_all_params(image=difference_image, cat=cat_sextractor, show=False)
        for obj in cat_generated:
            plt.scatter(obj['x_0'], obj['y_0'], c='white')
        plt.show()

        _, pix_scale = ff.get_pixel_scale(comparison_image)

        match_ids_sextractor, match_ids_generated = u.match_cat(x_match=cat_sextractor['ra'],
                                                                y_match=cat_sextractor['dec'],
                                                                x_cat=cat_generated['ra'],
                                                                y_cat=cat_generated['dec'],
                                                                tolerance=3 * pix_scale)

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

        plotting.plot_all_params(image=difference_image, cat=matches_sextractor, show=False)
        # plt.scatter(x_burst, y_burst, c='white')
        plotting.plot_gal_params(hdu=difference_image, ras=[ra_burst], decs=[dec_burst], a=[burst_err_a],
                                 b=[burst_err_b], theta=[burst_err_theta], colour='blue', show_centre=True)
        for obj in matches_generated:
            plt.scatter(obj['x_0'], obj['y_0'], c='white')
        plt.show()

        matches_sextractor['mag_sextractor'], _, _ = ph.magnitude_complete(flux=matches_sextractor['flux_aper'],
                                                                           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)} % ')

        print(f'Faintest recovered: {max(matches["mag"])} generated; '
              f'{max(matches_sextractor["mag_sextractor"])} sextracted')

        print('Median delta mag:', delta_mag)

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

        difference_image.close()