def retrieve_calibration_table(self, force=False):

        if self.name in self.qc1_retrievable:
            if self.calibration_table_last_updated != date.today() or force:
                down_path = os.path.join(self.data_path, "fors2_qc.tbl")
                fil = self.name
                if fil == "R_SPECIAL":
                    fil = "R_SPEC"
                save_fors2_calib(
                    output=down_path,
                    fil=fil,
                )
                self.calibration_table = table.QTable.read(down_path, format="ascii")
                self.calibration_table["zeropoint"] *= units.mag
                self.calibration_table["zeropoint_err"] *= units.mag
                self.calibration_table["colour_term"] *= units.mag
                self.calibration_table["colour_term_err"] *= units.mag
                self.calibration_table["extinction"] *= units.mag
                self.calibration_table["extinction_err"] *= units.mag
                self.write_calibration_table()
                self.calibration_table_last_updated = date.today()
            else:
                u.debug_print(1, "Filter calibrations already updated today; skipping.")

        else:
            u.debug_print(1, f"Cannot retrieve calibration table for {self.name}.")

        self.update_output_file()

        return self.calibration_table
 def from_params(cls, instrument_name: str):
     if instrument_name in active_instruments:
         return active_instruments[instrument_name]
     path = cls._build_param_path(instrument_name=instrument_name)
     u.debug_print(1, "Instrument.from_params(): instrument_name ==", instrument_name)
     u.debug_print(1, "Instrument.from_params(): path ==", path)
     return cls.from_file(param_file=path)
 def _build_param_dir(cls, instrument_name: str):
     path = os.path.join(p.param_dir, "instruments")
     u.mkdir_check(path)
     u.debug_print(2, "Instrument._build_param_dir(): instrument_name ==", instrument_name)
     path = os.path.join(path, instrument_name)
     u.mkdir_check(path)
     return path
Esempio n. 4
0
def match_catalogs(cat_1: table.Table,
                   cat_2: table.Table,
                   ra_col_1: str = "RA",
                   dec_col_1: str = "DEC",
                   ra_col_2: str = "ra",
                   dec_col_2: str = "dec",
                   tolerance: units.Quantity = 1 * units.arcsec):
    # Clean out any invalid declinations
    u.debug_print(2, "match_catalogs(): type(cat_1) ==", type(cat_1),
                  "type(cat_2) ==", type(cat_2))
    cat_1 = cat_1[cat_1[dec_col_1] <= 90 * units.deg]
    cat_1 = cat_1[cat_1[dec_col_1] >= -90 * units.deg]

    cat_2 = cat_2[cat_2[dec_col_2] <= 90 * units.deg]
    cat_2 = cat_2[cat_2[dec_col_2] >= -90 * units.deg]

    coords_1 = SkyCoord(cat_1[ra_col_1], cat_1[dec_col_1])
    coords_2 = SkyCoord(cat_2[ra_col_2], cat_2[dec_col_2])

    idx, distance, _ = coords_2.match_to_catalog_sky(coords_1)
    keep = distance < tolerance
    idx = idx[keep]
    matches_2 = cat_2[keep]
    distance = distance[keep]

    matches_1 = cat_1[idx]

    return matches_1, matches_2, distance
Esempio n. 5
0
def save_params(file: str, dictionary: dict):
    file = u.sanitise_file_ext(filename=file, ext=".yaml")

    u.debug_print(1, 'Saving parameter file to ' + str(file))
    u.debug_print(2, "params.save_params: dictionary ==", dictionary)

    with open(file, 'w') as f:
        yaml.dump(dictionary, f)
 def gather_filters(self):
     filter_dir = self.guess_filter_dir()
     for file in filter(lambda f: f.endswith(".yaml"), os.listdir(filter_dir)):
         u.debug_print(1, "Instrument.gather_filters(): file == ", file)
         fil = Filter.from_params(filter_name=file[:-5], instrument_name=self.name)
         fil.instrument = self
         self.filters[fil.name] = fil
         if fil.votable_path is None:
             fil.retrieve_from_svo()
Esempio n. 7
0
def solve_field(
        image_files: Union[str, list],
        base_filename: str = "astrometry",
        overwrite: bool = True,
        tweak: bool = True,
        search_radius: units.Quantity = 1 * units.degree,
        centre: SkyCoord = None,
        guess_scale: bool = True,
        time_limit: units.Quantity = None,
        verify: bool = True,
        odds_to_tune_up: float = 1e6,
        odds_to_solve: float = 1e9,
        *flags,
        **params):
    """
    Returns True if successful (by checking whether the corrected file is generated); False if not.
    :param image_files:
    :param base_filename:
    :param overwrite:
    :param flags:
    :param params:
    :return:
    """

    params["o"] = base_filename
    params["odds-to-tune-up"] = odds_to_tune_up
    params["odds-to-solve"] = odds_to_solve
    if time_limit is not None:
        params["l"] = check_quantity(time_limit, units.second).value
    if search_radius is not None:
        params["radius"] = search_radius.to(units.deg).value
    if centre is not None:
        params["ra"] = centre.ra.to(units.deg).value
        params["dec"] = centre.dec.to(units.deg).value
    debug_print(1, "solve_field(): tweak ==", tweak)

    flags = list(flags)
    if overwrite:
        flags.append("O")
    if guess_scale:
        flags.append("g")
    if not tweak:
        flags.append("T")
    if not verify:
        flags.append("y")


    system_command("solve-field", image_files, False, True, False, *flags, **params)
    if isinstance(image_files, list):
        image_path = image_files[0]
    else:
        image_path = image_files
    check_dir = os.path.split(image_path)[0]
    check_path = os.path.join(check_dir, f"{base_filename}.new")
    print(f"Checking for result file at {check_path}...")
    return os.path.isfile(check_path)
Esempio n. 8
0
 def check_data_path(self):
     if self.field is not None:
         u.debug_print(2, "", self.name)
         # print(self.field.data_path, self.name_filesys)
         self.data_path = os.path.join(self.field.data_path, "objects", self.name_filesys)
         u.mkdir_check(self.data_path)
         self.output_file = os.path.join(self.data_path, f"{self.name_filesys}_outputs.yaml")
         return True
     else:
         return False
 def write_calibration_table(self):
     if self.calibration_table is None:
         u.debug_print(1, "calibration_table not yet loaded.")
     else:
         if self.calibration_table_path is None:
             self.calibration_table_path = os.path.join(
                 self.data_path,
                 f"{self.instrument.name}_{self.name}_calibration_table.ecsv")
         u.debug_print(1, "Writing calibration table to", self.calibration_table_path)
         self.calibration_table.write(self.calibration_table_path, format="ascii.ecsv", overwrite=True)
Esempio n. 10
0
def plot_gal_params(
        hdu: fits.HDUList, ras: Union[list, np.ndarray, float], decs: Union[list, np.ndarray, float],
        a: Union[list, np.ndarray, float], b: Union[list, np.ndarray, float],
        theta: Union[list, np.ndarray, float], colour: str = 'white',
        show_centre: bool = False,
        label: str = None, world: bool = True, world_axes: bool = True, **kwargs):
    """

    :param hdu:
    :param ras: In degrees.
    :param decs: In degrees.
    :param a: In degrees.
    :param b: In degrees.
    :param theta: In degrees, apparently.
    :param colour:
    :param offset:
    :param show_centre:
    :return:
    """
    # TODO: Rename parameters to reflect acceptance of pixel coordinates.

    _, pix_scale = ff.get_pixel_scale(hdu)
    n_y, n_x = hdu[0].data.shape
    header = hdu[0].header
    wcs_image = wcs.WCS(header=header)
    if world:
        xs, ys = wcs_image.all_world2pix(ras, decs, 0)
    else:
        xs = np.array(ras)
        ys = np.array(decs)

    theta = np.array(theta)
    # Convert to photutils angle format
    theta = u.world_angle_se_to_pu(theta, rot_angle=ff.get_rotation_angle(header))

    a = u.dequantify(a)
    b = u.dequantify(b)

    for i, x in enumerate(xs):
        u.debug_print(2, "plotting.plot_gal_params(): x, ys[i] ==", x, ys[i])
        if a[i] != 0 and b[i] != 0:
            if world_axes:
                ellipse = photutils.EllipticalAperture((x, ys[i]), a=a[i] / pix_scale, b=b[i] / pix_scale,
                                                       theta=theta[i])
            else:
                ellipse = photutils.EllipticalAperture((x, ys[i]), a=a[i], b=b[i], theta=theta[i])
            ellipse.plot(**kwargs)
            line_label = None
        else:
            line_label = label
        if show_centre:
            plt.plot((0.0, n_x), (ys[i], ys[i]), c=colour, label=line_label)
            plt.plot((x, x), (0.0, n_y), c=colour)
Esempio n. 11
0
def load_params(file: str):
    file = u.sanitise_file_ext(file, '.yaml')

    u.debug_print(2, 'Loading parameter file from ' + str(file))

    if os.path.isfile(file):
        with open(file) as f:
            p = yaml.load(f)
    else:
        p = None
        u.debug_print(1, 'No parameter file found at',
                      str(file) + ', returning None.')
    return p
Esempio n. 12
0
def sof(frames: Dict[str, list], output_path: str):
    output_lines = []
    for frame_type in frames:
        u.debug_print(0, output_lines)
        for frame in frames[frame_type]:
            output_lines.append(f"{frame} {frame_type}\n")

    u.mkdir_check_nested(output_path)
    print(f"Writing SOF file to {output_path}")
    with open(output_path, "w") as file:
        file.writelines(output_lines)

    return output_lines
Esempio n. 13
0
def update_output_file(obj):
    if obj.output_file is not None:
        param_dict = load_params(obj.output_file)
        if param_dict is None:
            param_dict = {}
        # For each of these, check if None first.
        u.debug_print(2, "params.update_output_file(): obj, type(obj) ==", obj,
                      type(obj))
        u.debug_print(2, "params.update_output_file(): obj._output_dict() ==",
                      obj._output_dict())
        param_dict.update(obj._output_dict())
        save_params(dictionary=param_dict, file=obj.output_file)
    else:
        raise ValueError(
            "Output could not be saved to file due to lack of valid output path."
        )
Esempio n. 14
0
 def select_photometry_sep(
         self,
         fil: str,
         instrument: str,
         local_output: bool = True
 ):
     fil_photom = self.photometry_tbl[self.photometry_tbl["band"] == fil]
     fil_photom = fil_photom[fil_photom["instrument"] == instrument]
     mean = {
         "mag": np.mean(fil_photom["mag_sep"]),
         "mag_err": np.std(fil_photom["mag_sep"]),
         "mag_psf": np.mean(fil_photom["mag_psf"]),
         "mag_psf_err": np.std(fil_photom["mag_psf"])
     }
     u.debug_print(2, f"Object.select_photometry_sep(): {self.name=}, {fil=}, {instrument=}")
     print(fil_photom)
     return fil_photom[np.argmax(fil_photom["snr_sep"])], mean
def check_subimage_edges(data: np.ndarray, bottom, top, left, right):
    u.debug_print(
        1, "fits_files.check_subimage_edges(): bottom, top, left, right == ",
        bottom, top, left, right)
    if (bottom < 0 and top < 0) or (bottom > data.shape[0]
                                    and top > data.shape[0]):
        raise ValueError(
            f"Both y-axis edges ({bottom}, {top}) are outside the image.")
    if (left < 0 and right < 0) or (left > data.shape[1]
                                    and right > data.shape[1]):
        raise ValueError(
            f"Both x-axis edges ({left}, {right}) are outside the image.")
    bottom = max(int(bottom), 0)
    top = min(int(top), data.shape[0])
    left = max(int(left), 0)
    right = min(int(right), data.shape[1])
    return bottom, top, left, right
def detect_edges_area(file: Union['fits.HDUList', 'str']):
    if type(file) is str:
        print("Area file:", file)
        file = fits.open(file)

    data = file[0].data

    # We round to the 13th decimal place
    keep_val = u.bucket_mode(data, 13)

    height = data.shape[0]
    mid_y = int(height / 2)
    # Take a horizontal slice right across the middle of the image.
    slice_hor = np.round(data[mid_y], 13)
    slice_hor_keep = np.nonzero(slice_hor == keep_val)[0]
    # This is here just in case mid_y finds a row that does not have maximum coverage.
    while len(slice_hor_keep) == 0:
        mid_y = int(mid_y / 2)
        if mid_y == 0:
            raise ValueError("mid_y got stuck.")
        u.debug_print(2, "detect_edges_area(): mid_y==", mid_y)
        # Take a horizontal slice right across the middle of the image.
        slice_hor = np.round(data[mid_y], 13)
        slice_hor_keep = np.nonzero(slice_hor > 0.75 * keep_val)[0]
        u.debug_print(2, "detect_edges_area(): slice_hor.max()",
                      slice_hor.max())
    left = slice_hor_keep[0]
    right = slice_hor_keep[-1]

    width = data.shape[1]
    mid_x = int(width / 2)
    slice_vert = np.round(data[:, mid_x], 13)
    slice_vert_keep = np.nonzero(slice_vert == keep_val)[0]
    while len(slice_hor_keep) == 0:
        mid_x = int(mid_x / 2)
        # Take a horizontal slice right across the middle of the image.
        slice_hor = np.round(data[mid_x], 13)
        slice_hor_keep = np.nonzero(slice_hor == keep_val)[0]
    bottom = slice_vert_keep[0]
    top = slice_vert_keep[-1]

    if type(file) is str:
        file.close()

    return left, right, bottom, top
Esempio n. 17
0
def correct_gaia_to_epoch(gaia_cat: Union[str, table.QTable],
                          new_epoch: time.Time):
    gaia_cat = load_catalogue(cat_name="gaia", cat=gaia_cat)
    epochs = list(map(lambda y: f"J{y}", gaia_cat['ref_epoch']))
    gaia_coords = SkyCoord(ra=gaia_cat["ra"],
                           dec=gaia_cat["dec"],
                           pm_ra_cosdec=gaia_cat["pmra"],
                           pm_dec=gaia_cat["pmdec"],
                           obstime=epochs)
    u.debug_print(2, "astrometry.correct_gaia_to_epoch(): new_epoch ==",
                  new_epoch)
    gaia_coords_corrected = gaia_coords.apply_space_motion(
        new_obstime=new_epoch)
    gaia_cat_corrected = copy.deepcopy(gaia_cat)
    gaia_cat_corrected["ra"] = gaia_coords_corrected.ra
    gaia_cat_corrected["dec"] = gaia_coords_corrected.dec
    new_epoch.format = "jyear"
    gaia_cat_corrected["ref_epoch"] = new_epoch.value
    return gaia_cat_corrected
Esempio n. 18
0
def yaml_to_json(yaml_file: str, output: str = None):
    yaml_file = u.sanitise_file_ext(yaml_file, '.yaml')
    if output is not None:
        output = u.sanitise_file_ext(output, '.json')
    elif output is None:
        output = yaml_file.replace('.yaml', '.json')

    p = load_params(file=yaml_file)

    u.debug_print(1, 'Saving parameter file to ' + output)

    for param in p:
        if type(p[param]) is date:
            p[param] = str(p[param])

    with open(output, 'w') as fj:
        json.dump(p, fj)

    return p
 def from_file(cls, param_file: Union[str, dict]):
     u.debug_print(1, "Instrument.from_file(): param_file ==", param_file)
     name, param_file, param_dict = p.params_init(param_file)
     u.debug_print(1, "Instrument.from_file(): name ==", name)
     u.debug_print(1, "Instrument.from_file(): param_dict ==", param_dict)
     if param_dict is None:
         raise FileNotFoundError("Param file missing!")
     return cls(**param_dict)
Esempio n. 20
0
 def from_params(cls, survey_name: str):
     path = cls._build_param_path(survey_name=survey_name)
     u.debug_print(1, "Survey.from_params(): path ==", path)
     return cls.from_file(param_file=path)
Esempio n. 21
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)
Esempio n. 22
0
def standard_script(
        input_directory: str,
        output_directory: str,
        output_file_name: str = None,
        ignore_differences: bool = False,
        coadd_types: Union[List[str], str] = 'median',
        # unit="electron / second",
        do_inject_header: bool = True,
        **kwargs):
    """
    Does a standard median coaddition of fits files in input_directory.
    Adapted from an example bash script found at http://montage.ipac.caltech.edu/docs/first_mosaic_tutorial.html
    :param input_directory: path to directory containing input images.
    :param output_directory: path to directory to write data products to; will be created if it doesn't exist.
    :param output_file_name: Name of final coadded image file.
    :param ignore_differences: If False, checks if input images have compatible exposure times, filter, etc. and raises ValueError if not.
    :return:
    """
    u.mkdir_check(output_directory)
    old_dir = os.getcwd()

    proj_dir = os.path.join(output_directory, "projdir")
    diff_dir = os.path.join(output_directory, "diffdir")
    corr_dir = os.path.join(output_directory, "corrdir")
    u.mkdir_check(proj_dir, diff_dir, corr_dir)

    os.chdir(output_directory)
    print("Creating directories to hold processed images.")

    proj_dir = "projdir"
    diff_dir = "diffdir"
    corr_dir = "corrdir"

    if not ignore_differences:
        print("Checking input images...")
        check_input_images(input_directory=input_directory, **kwargs)

    print("Creating metadata tables of the input images.")
    table_path = "images.tbl"
    image_table(input_directory=input_directory, output_path=table_path)

    print("Creating FITS headers describing the footprint of the mosaic.")
    header_path = "template.hdr"
    make_header(table_path=table_path, output_path=header_path)

    print("Reprojecting input images.")
    stats_table_path = "stats.tbl"
    project_execute(input_directory=input_directory,
                    table_path=table_path,
                    header_path=header_path,
                    proj_dir=proj_dir,
                    stats_table_path=stats_table_path)

    print("Creating metadata table of the reprojected images.")
    reprojected_table_path = "proj.tbl"
    image_table(input_directory=proj_dir, output_path=reprojected_table_path)

    print("Analyzing the overlaps between images.")
    difference_table_path = "diffs.tbl"
    fit_table_path = "fits.tbl"
    overlaps(table_path=reprojected_table_path,
             difference_table_path=difference_table_path)
    difference_execute(input_directory=proj_dir,
                       difference_table_path=difference_table_path,
                       header_path=header_path,
                       diff_dir=diff_dir)
    fit_execute(difference_table_path=difference_table_path,
                fit_table_path=fit_table_path,
                diff_dir=diff_dir)

    print(
        "Performing background modeling and compute corrections for each image."
    )
    corrections_table_path = "corrections.tbl"
    background_model(table_path=reprojected_table_path,
                     fit_table_path=fit_table_path,
                     correction_table_path=corrections_table_path)

    print("Applying corrections to each image")
    background_execute(input_directory=proj_dir,
                       table_path=reprojected_table_path,
                       correction_table_path=corrections_table_path,
                       corr_dir=corr_dir)

    if isinstance(coadd_types, str):
        coadd_types = [coadd_types]

    file_paths = []

    for i, coadd_type in enumerate(coadd_types):
        print(f"Coadding the images with {coadd_type}.")
        if output_file_name is None:
            output_file_name = "coadded.fits"
        output_file_name_coadd = output_file_name.replace(
            ".fits", f"_{coadd_type}.fits")

        add(input_directory=corr_dir,
            coadd_type=coadd_type,
            table_path=reprojected_table_path,
            header_path=header_path,
            output_path=output_file_name_coadd)

        if do_inject_header:
            inject_header(file_path=output_file_name_coadd,
                          input_directory=input_directory,
                          coadd_type=coadd_type)

        file_paths.append(
            os.path.join(output_directory, output_file_name_coadd))

    os.chdir(old_dir)

    u.debug_print(1, "montage.standard_script():", file_paths)

    return file_paths
Esempio n. 23
0
 def load_extinction_table(self, force: bool = False):
     if force or self.irsa_extinction is None:
         if self.irsa_extinction_path is not None:
             u.debug_print(1, "Loading irsa_extinction from", self.irsa_extinction_path)
             self.irsa_extinction = table.QTable.read(self.irsa_extinction_path, format="ascii.ecsv")
Esempio n. 24
0
def plot_subimage(
        fig: plt.Figure, hdu: Union[str, fits.HDUList], ra: float, dec: float,
        frame: Union[int, float], world_frame: bool = False, title: str = None,
        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_grid: bool = False,
        ticks: int = None, interval: str = 'minmax',
        show_coords: bool = True, ylabel: str = None,
        font_size: int = 12,
        reverse_y=False,
        **kwargs):
    """

    :param fig:
    :param hdu:
    :param ra:
    :param dec:
    :param frame: in pixels, or in degrees (?) if world_frame is True.
    :param world_frame:
    :param title:
    :param n:
    :param n_x:
    :param n_y:
    :param cmap:
    :param show_cbar:
    :param stretch:
    :param vmin:
    :param vmax:
    :param show_grid:
    :param ticks:
    :param interval:
    :param show_coords:
    :param ylabel:
    :param font_size:
    :param reverse_y:
    :return:
    """
    u.debug_print(1, "plotting.plot_subimage(): hdu ==", hdu)
    hdu, path = ff.path_or_hdu(hdu=hdu)
    u.debug_print(1, "plotting.plot_subimage(): hdu[0].data.shape ==", hdu[0].data.shape)

    hdu_cut = ff.trim_frame_point(hdu=hdu, ra=ra, dec=dec, frame=frame, world_frame=world_frame)
    wcs_cut = wcs.WCS(header=hdu_cut[0].header)

    u.debug_print(1, "plotting.plot_subimage(): n_y, n_x, n ==", n_y, n_x, n)
    if show_coords:
        plot = fig.add_subplot(n_y, n_x, n, projection=wcs_cut)
        if ticks is not None:
            lat = plot.coords[0]
            lat.set_ticks(number=ticks)
    else:
        plot = fig.add_subplot(n_y, n_x, n)
        frame1 = plt.gca()
        frame1.axes.get_xaxis().set_visible(False)
        frame1.axes.set_yticks([])
        frame1.axes.invert_yaxis()
        # frame1.axes.get_yaxis().set_visible(False)

    if show_grid:
        plt.grid(color='black', ls='dashed')

    if type(vmin) is str:
        if vmin == 'median_full':
            vmin = np.nanmedian(hdu[0].data)
        elif vmin == 'median_cut':
            vmin = np.nanmedian(hdu_cut[0].data)
        else:
            raise ValueError('Unrecognised vmin string argument.')

    if interval == 'minmax':
        interval = MinMaxInterval()
    elif interval == 'zscale':
        interval = ZScaleInterval()
    else:
        raise ValueError('Interval not recognised.')

    u.debug_print(1, "plotting.plot_subimage(): hdu_cut[0].data.shape ==", hdu_cut[0].data.shape)
    if stretch == 'log':
        norm = ImageNormalize(hdu_cut[0].data, interval=interval, stretch=LogStretch(), vmin=vmin, vmax=vmax)
    elif stretch == 'sqrt':
        norm = ImageNormalize(hdu_cut[0].data, interval=interval, stretch=SqrtStretch(), vmin=vmin, vmax=vmax)
    else:
        raise ValueError('Stretch not recognised.')

    plot.title.set_text(title)
    plot.title.set_size(font_size)
    u.debug_print(1, "plotting.plot_subimage(): ylabel ==", ylabel)
    if ylabel is not None:
        plot.set_ylabel(ylabel, size=12)

    im = plt.imshow(hdu_cut[0].data, norm=norm, cmap=cmap, **kwargs, origin='lower')
    if reverse_y:
        plot.invert_yaxis()
    c_ticks = np.linspace(norm.vmin, norm.vmax, 5, endpoint=True)
    if show_cbar:
        cbar = plt.colorbar(im)  # ticks=c_ticks)

    return plot, hdu_cut
Esempio n. 25
0
    def push_to_table(self, select: bool = False, local_output: bool = True):

        if select:
            tbl = obs.load_master_objects_table()
        else:
            tbl = obs.load_master_all_objects_table()

        jname = self.jname()

        for instrument in self.photometry:
            for fil in self.photometry[instrument]:
                band_str = f"{instrument}_{fil.replace('_', '-')}"
                obs.add_columns_to_master_objects(band_str)

        if select:
            row, index = obs.get_row(tbl=obs.master_objects_table, colname="object_name", colval=self.name)
        else:
            row, index = obs.get_row(tbl=obs.master_objects_all_table, colname="object_name", colval=self.name)

        print()

        if row is None:
            row = {}

        self.estimate_galactic_extinction()
        if select:
            self.get_good_photometry()
            self.photometry_to_table()
            deepest = self.select_deepest_sep(local_output=local_output)
        else:
            deepest = self.select_deepest(local_output=local_output)

        # best_position = self.select_best_position(local_output=local_output)
        best_psf = self.select_psf_photometry(local_output=local_output)

        row["jname"] = jname
        row["field_name"] = self.field.name
        row["object_name"] = self.name
        row["ra"] = deepest["ra"]
        row["ra_err"] = deepest["ra_err"]
        row["dec"] = deepest["dec"]
        row["dec_err"] = deepest["dec_err"]
        row["epoch_position"] = deepest["epoch_name"]
        row["epoch_position_date"] = deepest["epoch_date"]
        row["a"] = deepest["a"]
        row["a_err"] = deepest["a_err"]
        row["b"] = deepest["b"]
        row["b_err"] = deepest["b_err"]
        row["theta"] = deepest["theta"]
        row["kron_radius"] = deepest["kron_radius"]
        row["epoch_ellipse"] = deepest["epoch_name"]
        row["epoch_ellipse_date"] = deepest["epoch_date"]
        row["theta_err"] = deepest["theta_err"]
        row[f"e_b-v"] = self.ebv_sandf
        row[f"class_star"] = best_psf["class_star"]

        for instrument in self.photometry:
            for fil in self.photometry[instrument]:

                band_str = f"{instrument}_{fil.replace('_', '-')}"
                obs.add_columns_to_master_objects(band_str)

                if select:
                    best_photom, mean_photom = self.select_photometry_sep(fil, instrument, local_output=local_output)
                    row[f"mag_best_{band_str}"] = best_photom["mag_sep"]
                    row[f"mag_best_{band_str}_err"] = best_photom["mag_sep_err"]
                    row[f"snr_best_{band_str}"] = best_photom["snr_sep"]

                else:
                    best_photom, mean_photom = self.select_photometry(fil, instrument, local_output=local_output)
                    row[f"mag_best_{band_str}"] = best_photom["mag"]
                    row[f"mag_best_{band_str}_err"] = best_photom["mag_err"]
                    row[f"snr_best_{band_str}"] = best_photom["snr"]

                row[f"mag_mean_{band_str}"] = mean_photom["mag"]
                row[f"mag_mean_{band_str}_err"] = mean_photom["mag_err"]
                row[f"ext_gal_{band_str}"] = best_photom["ext_gal"]
                # else:
                #     row[f"ext_gal_{band_str}"] = best_photom["ext_gal_sandf"]
                row[f"epoch_best_{band_str}"] = best_photom[f"epoch_name"]
                row[f"epoch_best_date_{band_str}"] = best_photom[f"epoch_date"]
                row[f"mag_psf_best_{band_str}"] = best_photom[f"mag_psf"]
                row[f"mag_psf_best_{band_str}_err"] = best_photom[f"mag_psf_err"]
                row[f"snr_psf_best_{band_str}"] = best_photom["snr_psf"]
                row[f"mag_psf_mean_{band_str}"] = mean_photom[f"mag_psf"]
                row[f"mag_psf_mean_{band_str}_err"] = mean_photom[f"mag_psf_err"]

        for colname in tbl.colnames:
            if colname not in row:
                if "epoch" in colname:
                    row[colname] = "N/A"
                else:
                    row[colname] = tbl[0][colname]

        u.debug_print(2, "Object.push_to_table(): select ==", select)
        print(f"INDEX: {index}")
        if select:
            if index is None:
                obs.master_objects_table.add_row(row)
            else:
                obs.master_objects_table[index] = row
            obs.write_master_objects_table()
        else:
            if index is None:
                obs.master_objects_all_table.add_row(row)
            else:
                obs.master_objects_all_table[index] = row
            obs.write_master_all_objects_table()
Esempio n. 26
0
    def __init__(
            self,
            uncertainty: Union[float, units.Quantity, dict, tuple] = None,
            position: SkyCoord = None,
            ra_err_sys: Union[float, units.Quantity] = None,
            ra_err_stat: Union[float, units.Quantity] = None,
            dec_err_sys: Union[float, units.Quantity] = None,
            dec_err_stat: Union[float, units.Quantity] = None,
            a_stat: Union[float, units.Quantity] = None,
            a_sys: Union[float, units.Quantity] = None,
            b_stat: Union[float, units.Quantity] = None,
            b_sys: Union[float, units.Quantity] = None,
            theta: Union[float, units.Quantity] = None,
            sigma: float = None
    ):
        """
        If a single value is provided for uncertainty, the uncertainty ellipse will be assumed to be circular.
        Values in dictionary, if provided, override values given as arguments.
        Position values provided without units are assumed to be in degrees.
        On the other hand, uncertainty values provided without units are assumed to be in arcseconds;
        except for uncertainties in RA, which are assumed in RA seconds.
        :param uncertainty:
        :param position:
        :param ra_err_sys:
        :param ra_err_stat:
        :param dec_err_sys:
        :param dec_err_stat:
        :param a_stat:
        :param a_sys:
        :param b_stat:
        :param b_sys:
        :param theta:
        :param sigma: The confidence interval (expressed in multiples of sigma) of the uncertainty ellipse.
        """
        self.sigma = sigma
        # Assign values from dictionary, if provided.
        if type(uncertainty) is dict:
            if "ra" in uncertainty and uncertainty["ra"] is not None:
                if "sys" in uncertainty["ra"] and uncertainty["ra"]["sys"] is not None:
                    ra_err_sys = uncertainty["ra"]["sys"]
                if "stat" in uncertainty["ra"] and uncertainty["ra"]["stat"] is not None:
                    ra_err_stat = uncertainty["ra"]["stat"]
            if "dec" in uncertainty and uncertainty["dec"] is not None:
                if "sys" in uncertainty["dec"] and uncertainty["dec"]["sys"] is not None:
                    dec_err_sys = uncertainty["dec"]["sys"]
                if "stat" in uncertainty["dec"] and uncertainty["dec"]["stat"] is not None:
                    dec_err_stat = uncertainty["dec"]["stat"]
            if "a" in uncertainty and uncertainty["a"] is not None:
                if "sys" in uncertainty["a"] and uncertainty["a"]["sys"] is not None:
                    a_sys = uncertainty["a"]["sys"]
                if "stat" in uncertainty["a"] and uncertainty["a"]["stat"] is not None:
                    a_stat = uncertainty["a"]["stat"]
            if "b" in uncertainty and uncertainty["b"] is not None:
                if "sys" in uncertainty["b"] and uncertainty["b"]["sys"] is not None:
                    b_sys = uncertainty["b"]["sys"]
                if "stat" in uncertainty["b"] and uncertainty["a"]["stat"] is not None:
                    b_stat = uncertainty["b"]["stat"]
            if "theta" in uncertainty and uncertainty["theta"] is not None:
                theta = uncertainty["theta"]

        # If uncertainty is a single value, assume a circular uncertainty region without distinction between systematic
        # and statistical.
        elif uncertainty is not None:
            a_stat = uncertainty
            a_sys = 0.0
            b_stat = uncertainty
            b_sys = 0.0
            theta = 0.0

        # Check whether we're specifying uncertainty using equatorial coordinates or ellipse parameters.
        u.debug_print(2, "PositionUncertainty.__init__(): a_stat, a_sys, b_stat, b_sys, theta, position ==", a_stat,
                      a_sys, b_stat, b_sys, theta, position)
        u.debug_print(2, "PositionUncertainty.__init__(): ra_err_sys, ra_err_stat, dec_err_sys, dec_err_stat ==",
                      ra_err_sys, ra_err_stat, dec_err_sys, dec_err_stat)
        if a_stat is not None and a_sys is not None and b_stat is not None and b_sys is not None and theta is not None and position is not None:
            ellipse = True
        elif ra_err_sys is not None and ra_err_stat is not None and dec_err_sys is not None and dec_err_stat is not None:
            ellipse = False
        else:
            raise ValueError(
                "Either all ellipse values (a, b, theta) or all equatorial values (ra, dec, position) must be provided.")

        ra_err_sys = u.check_quantity(number=ra_err_sys, unit=units.hourangle / 3600)
        ra_err_stat = u.check_quantity(number=ra_err_stat, unit=units.hourangle / 3600)
        dec_err_sys = u.check_quantity(number=dec_err_sys, unit=units.arcsec)
        dec_err_stat = u.check_quantity(number=dec_err_stat, unit=units.arcsec)
        # Convert equatorial uncertainty to ellipse with theta=0
        if not ellipse:
            ra = position.ra
            dec = position.dec
            a_sys = SkyCoord(0.0 * units.degree, dec).separation(SkyCoord(ra_err_sys, dec))
            a_stat = SkyCoord(0.0 * units.degree, dec).separation(SkyCoord(ra_err_stat, dec))
            b_sys = SkyCoord(ra, dec).separation(SkyCoord(ra, dec + dec_err_sys))
            b_stat = SkyCoord(ra, dec).separation(SkyCoord(ra, dec + dec_err_stat))
            a_sys, b_sys = max(a_sys, b_sys), min(a_sys, b_sys)
            a_stat, b_stat = max(a_stat, b_stat), min(a_stat, b_stat)
            theta = 0.0 * units.degree
        # Or use ellipse parameters as given.
        else:
            a_sys = u.check_quantity(number=a_sys, unit=units.arcsec)
            a_stat = u.check_quantity(number=a_stat, unit=units.arcsec)
            b_sys = u.check_quantity(number=b_sys, unit=units.arcsec)
            b_stat = u.check_quantity(number=b_stat, unit=units.arcsec)
            theta = u.check_quantity(number=theta, unit=units.arcsec)

        self.a_sys = a_sys
        self.a_stat = a_stat
        self.b_sys = b_sys
        self.b_stat = b_stat
        self.theta = theta

        self.ra_sys = ra_err_sys
        self.dec_sys = dec_err_sys
        self.ra_stat = ra_err_stat
        self.dec_stat = dec_err_stat