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)
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.")
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.")
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)
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})
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()
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
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)
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.')
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
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
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)
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)
# 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)
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)
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')
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)
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)
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()