Exemple #1
0
class EventListDatasetChecker(object):
    """Event list dataset checker.

    TODO: link to defining standard documents,
     especially the CTA event list spec.

    Having such a checker is useful at the moment because
    the CTA data formats are quickly evolving and there's
    various sources of event list data, e.g. exporters are
    being written for the existing IACTs and simulators
    are being written for CTA.

    Parameters
    ----------
    event_list_dataset : `~gammapy.data.EventListDataset`
        Event list dataset
    logger : `logging.Logger` or None
        Logger to use (use module-level Gammapy logger by default)
    """
    _AVAILABLE_CHECKS = OrderedDict(
        misc='check_misc',
        times='check_times',
        coordinates='check_coordinates',
    )

    accuracy = OrderedDict(
        angle=Angle('1 arcsec'),
        time=Quantity(1, 'microsecond'),
    )

    def __init__(self, event_list_dataset, logger=None):
        self.dset = event_list_dataset
        if logger:
            self.logger = logger
        else:
            self.logger = log

    def run(self, checks='all'):
        """Run checks.

        Available checks: {...}

        Parameters
        ----------
        checks : list of str or "all"
            Which checks to run

        Returns
        -------
        ok : bool
            Everything ok?
        """
        if checks == 'all':
            checks = self._AVAILABLE_CHECKS.keys()

        unknown_checks = set(checks).difference(self._AVAILABLE_CHECKS.keys())
        if unknown_checks:
            raise ValueError('Unknown checks: {}'.format(unknown_checks))

        ok = True
        for check in checks:
            check_method = getattr(self, self._AVAILABLE_CHECKS[check])
            ok &= check_method()

        return ok

    def check_misc(self):
        """Check misc basic stuff."""
        ok = True

        required_meta = ['TELESCOP', 'OBS_ID']
        missing_meta = set(required_meta) - set(self.dset.event_list.meta)
        if missing_meta:
            ok = False
            self.logger.error('Missing meta info: {}'.format(missing_meta))

        # TODO: implement more basic checks that all required info is present.

        return ok

    def _check_times_gtis(self):
        """Check GTI info"""
        # TODO:
        # Check that required info is there
        for colname in ['START', 'STOP']:
            if colname not in self.colnames:
                raise InvalidDataError(
                    'GTI missing column: {}'.format(colname))

        for key in ['TSTART', 'TSTOP', 'MJDREFI', 'MJDREFF']:
            if key not in self.meta:
                raise InvalidDataError(
                    'GTI missing header keyword: {}'.format(key))

        # TODO: Check that header keywords agree with table entries
        # TSTART, TSTOP, MJDREFI, MJDREFF

        # Check that START and STOP times are consecutive
        times = np.ravel(self['START'], self['STOP'])
        # TODO: not sure this is correct ... add test with a multi-gti table from Fermi.
        if not np.all(np.diff(times) >= 0):
            raise InvalidDataError('GTIs are not consecutive or sorted.')

    def check_times(self):
        """Check if various times are consistent.

        The headers and tables of the FITS EVENTS and GTI extension
        contain various observation and event time information.
        """
        ok = True

        # http://fermi.gsfc.nasa.gov/ssc/data/analysis/documentation/Cicerone/Cicerone_Data/Time_in_ScienceTools.html
        telescope_met_refs = OrderedDict(
            FERMI=Time('2001-01-01T00:00:00'),
            HESS=Time('2000-01-01T12:00:00.000'),
            # TODO: Once CTA has specified their MET reference add check here
        )

        telescope = self.dset.event_list.meta['TELESCOP']
        met_ref = time_ref_from_dict(self.dset.event_list.meta)

        if telescope in telescope_met_refs.keys():
            dt = (met_ref - telescope_met_refs[telescope])
            if dt > self.accuracy['time']:
                ok = False
                self.logger.error('MET reference is incorrect.')
        else:
            self.logger.debug(
                'Skipping MET reference check ... not known for this telescope.'
            )

        # TODO: check latest CTA spec to see which info is required / optional
        # EVENTS header keywords:
        # 'DATE_OBS': '2004-10-14'
        # 'TIME_OBS': '00:08:27'
        # 'DATE_END': '2004-10-14'
        # 'TIME_END': '00:34:44'
        # 'TSTART': 150984507.0
        # 'TSTOP': 150986084.0
        # 'MJDREFI': 51544
        # 'MJDREFF': 0.5
        # 'TIMEUNIT': 's'
        # 'TIMESYS': 'TT'
        # 'TIMEREF': 'local'
        # 'TASSIGN': 'Namibia'
        # 'TELAPSE': 0
        # 'ONTIME': 1577.0
        # 'LIVETIME': 1510.95910644531
        # 'DEADC': 0.964236799627542

        return ok

    def check_coordinates(self):
        """Check if various event list coordinates are consistent.

        Parameters
        ----------
        event_list_dataset : `~gammapy.data.EventListDataset`
            Event list dataset
        accuracy : `~astropy.coordinates.Angle`
            Required accuracy.

        Returns
        -------
        status : bool
            All coordinates consistent?
        """
        ok = True
        ok &= self._check_coordinates_header()
        ok &= self._check_coordinates_galactic()
        ok &= self._check_coordinates_altaz()
        ok &= self._check_coordinates_field_of_view()
        return ok

    def _check_coordinates_header(self):
        """Check TODO"""
        # TODO: implement
        return True

    def _check_coordinates_galactic(self):
        """Check if RA / DEC matches GLON / GLAT."""
        event_list = self.dset.event_list

        for colname in ['RA', 'DEC', 'GLON', 'GLAT']:
            if colname not in event_list.colnames:
                # GLON / GLAT columns are optional ...
                # so it's OK if they are not present ... just move on ...
                self.logger.info('Skipping Galactic coordinate check. '
                                 'Missing column: "{}".'.format(colname))
                return True

        radec = event_list.radec
        galactic = event_list.galactic
        separation = radec.separation(galactic).to('arcsec')
        return self._check_separation(separation, 'GLON / GLAT', 'RA / DEC')

    def _check_coordinates_altaz(self):
        """Check if ALT / AZ matches RA / DEC."""
        event_list = self.dset.event_list

        for colname in ['RA', 'DEC', 'AZ', 'ALT']:
            if colname not in event_list.colnames:
                # AZ / ALT columns are optional ...
                # so it's OK if they are not present ... just move on ...
                self.logger.info('Skipping AltAz coordinate check. '
                                 'Missing column: "{}".'.format(colname))
                return True

        radec = event_list.radec
        altaz_expected = event_list.altaz
        altaz_actual = radec.transform_to(altaz_expected)
        separation = altaz_actual.separation(altaz_expected).to('arcsec')
        return self._check_separation(separation, 'ALT / AZ', 'RA / DEC')

    def _check_coordinates_field_of_view(self):
        """Check if DETX / DETY matches ALT / AZ"""
        # TODO: implement
        return True

    def _check_separation(self, separation, tag1, tag2):
        max_separation = separation.max()

        if max_separation > self.accuracy['angle']:
            # TODO: probably we need to print run number and / or other
            # things for this to be useful in a pipeline ...
            fmt = '{0} not consistent with {1}. Max separation: {2}'
            args = [tag1, tag2, max_separation]
            self.logger.warning(fmt.format(*args))
            return False
        else:
            return True
Exemple #2
0
    def _info_map(self):
        """Print info from map analysis."""
        d = self.data
        ss = '\n*** Info from map analysis ***\n\n'

        ra_str = Angle(d['RAJ2000'], 'deg').to_string(unit='hour', precision=0)
        dec_str = Angle(d['DEJ2000'], 'deg').to_string(unit='deg', precision=0)
        ss += '{:<20s} : {:8.3f} = {}\n'.format('RA', d['RAJ2000'], ra_str)
        ss += '{:<20s} : {:8.3f} = {}\n'.format('DEC', d['DEJ2000'], dec_str)

        ss += '{:<20s} : {:8.3f} +/- {:.3f} deg\n'.format(
            'GLON', d['GLON'].value, d['GLON_Err'].value)
        ss += '{:<20s} : {:8.3f} +/- {:.3f} deg\n'.format(
            'GLAT', d['GLAT'].value, d['GLAT_Err'].value)

        ss += '{:<20s} : {:.3f}\n'.format('Position Error (68%)',
                                          d['Pos_Err_68'])
        ss += '{:<20s} : {:.3f}\n'.format('Position Error (95%)',
                                          d['Pos_Err_95'])

        ss += '{:<20s} : {:.0f}\n'.format('ROI number', d['ROI_Number'])
        ss += '{:<20s} : {}\n'.format('Spatial model', d['Spatial_Model'])
        ss += '{:<20s} : {}\n'.format('Spatial components', d['Components'])

        ss += '{:<20s} : {:.1f}\n'.format('TS', d['Sqrt_TS']**2)
        ss += '{:<20s} : {:.1f}\n'.format('sqrt(TS)', d['Sqrt_TS'])

        ss += '{:<20s} : {:.3f} +/- {:.3f} (UL: {:.3f}) deg\n'.format(
            'Size', d['Size'].value, d['Size_Err'].value, d['Size_UL'].value)

        ss += '{:<20s} : {:.3f}\n'.format('R70', d['R70'])
        ss += '{:<20s} : {:.3f}\n'.format('RSpec', d['RSpec'])

        ss += '{:<20s} : {:.1f}\n'.format('Total model excess',
                                          d['Excess_Model_Total'])
        ss += '{:<20s} : {:.1f}\n'.format('Excess in RSpec', d['Excess_RSpec'])
        ss += '{:<20s} : {:.1f}\n'.format('Model Excess in RSpec',
                                          d['Excess_RSpec_Model'])
        ss += '{:<20s} : {:.1f}\n'.format('Background in RSpec',
                                          d['Background_RSpec'])

        ss += '{:<20s} : {:.1f} hours\n'.format('Livetime',
                                                d['Livetime'].value)

        ss += '{:<20s} : {:.2f}\n'.format('Energy threshold',
                                          d['Energy_Threshold'])

        val, err = d['Flux_Map'].value, d['Flux_Map_Err'].value
        ss += '{:<20s} : ({:.3f} +/- {:.3f}) x 10^-12 cm^-2 s^-1 = ({:.2f} +/- {:.2f}) % Crab\n'.format(
            'Source flux (>1 TeV)', val / FF, err / FF, val * FLUX_TO_CRAB,
            err * FLUX_TO_CRAB)

        ss += '\nFluxes in RSpec (> 1 TeV):\n'

        ss += '{:<30s} : {:.3f} x 10^-12 cm^-2 s^-1 = {:5.2f} % Crab\n'.format(
            'Map measurement',
            d['Flux_Map_RSpec_Data'].value / FF,
            d['Flux_Map_RSpec_Data'].value * FLUX_TO_CRAB,
        )

        ss += '{:<30s} : {:.3f} x 10^-12 cm^-2 s^-1 = {:5.2f} % Crab\n'.format(
            'Source model',
            d['Flux_Map_RSpec_Source'].value / FF,
            d['Flux_Map_RSpec_Source'].value * FLUX_TO_CRAB,
        )

        ss += '{:<30s} : {:.3f} x 10^-12 cm^-2 s^-1 = {:5.2f} % Crab\n'.format(
            'Other component model',
            d['Flux_Map_RSpec_Other'].value / FF,
            d['Flux_Map_RSpec_Other'].value * FLUX_TO_CRAB,
        )

        ss += '{:<30s} : {:.3f} x 10^-12 cm^-2 s^-1 = {:5.2f} % Crab\n'.format(
            'Large scale component model',
            d['Flux_Map_RSpec_LS'].value / FF,
            d['Flux_Map_RSpec_LS'].value * FLUX_TO_CRAB,
        )

        ss += '{:<30s} : {:.3f} x 10^-12 cm^-2 s^-1 = {:5.2f} % Crab\n'.format(
            'Total model',
            d['Flux_Map_RSpec_Total'].value / FF,
            d['Flux_Map_RSpec_Total'].value * FLUX_TO_CRAB,
        )

        ss += '{:<35s} : {:5.1f} %\n'.format('Containment in RSpec',
                                             100 * d['Containment_RSpec'])
        ss += '{:<35s} : {:5.1f} %\n'.format('Contamination in RSpec',
                                             100 * d['Contamination_RSpec'])
        label, val = 'Flux correction (RSpec -> Total)', 100 * d[
            'Flux_Correction_RSpec_To_Total']
        ss += '{:<35s} : {:5.1f} %\n'.format(label, val)
        label, val = 'Flux correction (Total -> RSpec)', 100 * (
            1 / d['Flux_Correction_RSpec_To_Total'])
        ss += '{:<35s} : {:5.1f} %\n'.format(label, val)

        return ss
Exemple #3
0
def calculate_airmass(textlist_files):
    """
    Calculates AIRMASS for the list of all FITS files and appends respective details in the headers.
    Args:
        textlist_files : List of all FITS files whose headers have to be edited
    Returns:
        None
    """
    list_files = text_list_to_python_list(textlist_files)

    for file_name in list_files:
        hdulist = fits.open(file_name, mode='update')
        file_header = hdulist[0].header
        date_obs = file_header[DATE_keyword]
        time_start = file_header[TIMESTART_keyword]

        if RA_keyword in file_header.keys():
            object_ra = file_header[RA_keyword]
        else:
            object_ra = OBJECT_RA

        if DEC_keyword in file_header.keys():
            object_dec = file_header[DEC_keyword]
        else:
            object_dec = OBJECT_DEC

        time_utc = str(datetime.timedelta(seconds=int(time_start)))
        datetime_utc = date_obs + ' ' + time_utc
        jd = ephem.julian_date(datetime_utc)

        telescope = ephem.Observer()
        telescope.lon = OBS_LONG
        telescope.lat = OBS_LAT
        telescope.elevation = OBS_ALT
        telescope.pressure = 0
        telescope.epoch = ephem.J2000
        telescope.date = datetime_utc

        obj_pos = ephem.FixedBody()
        obj_pos._ra = object_ra
        obj_pos._dec = object_dec
        obj_pos._epoch = ephem.J2000
        obj_pos.compute(telescope)

        time_sidereal = telescope.sidereal_time()
        object_alt = Angle(str(obj_pos.alt) + ' degrees').degree
        airmass = 1 / math.cos(math.radians(90 - object_alt))

        list_keywords = [
            'OBSERVAT', 'OBS_LAT', 'OBS_LONG', 'OBS_ALT', 'TIMEZONE',
            'DATE_OBS', 'UT', 'JD', 'ST', 'RA', 'DEC', 'ALT', 'AZ', 'AIRMASS'
        ]

        dict_header = {
            'OBSERVAT': OBS_NAME,
            'OBS_LAT': OBS_LAT,
            'OBS_LONG': OBS_LONG,
            'OBS_ALT': OBS_ALT,
            'TIMEZONE': OBS_TIMEZONE,
            'DATE_OBS': date_obs,
            'UT': time_utc,
            'JD': jd,
            'ST': time_sidereal,
            'RA': object_ra,
            'DEC': object_dec,
            'ALT': obj_pos.alt,
            'AZ': obj_pos.az,
            'AIRMASS': airmass
        }

        for keyword in list_keywords:
            if keyword in file_header.keys():
                file_header.remove(keyword, remove_all=True)
            file_header.append(card=(keyword, dict_header[keyword]))

        hdulist.flush()
        hdulist.close()
Exemple #4
0
g = ax.coords.grid(alpha=0.25, color='white')

# Zoom in by a factor of 2.5 and place on the upper left
axins = zoomed_inset_axes(ax, 2.5, loc=2)
axins.imshow(image_data, interpolation="nearest", origin="lower")
plt.yticks(visible=False)
plt.xticks(visible=False)

ax1 = fig.add_axes([0.1, 0.1, 0.85, 0.85])

# Add on the sources
for indx, entry in enumerate(data[1:]):  # data[0] is the header row
    
    # Only need to pull out the coordinates of each source 
    coords = SkyCoord(
        ra=Angle('17h45m{0}s'.format(entry[1])), dec=Angle('-29d00m{0}s'.format(entry[2])), frame='fk4')
    print(coords.ra.hms, coords.dec.deg)

    ax1.scatter(coords.ra.hour, coords.dec.deg, marker='+',
                label="{0}".format(entry[0]))
    axins.scatter(coords.ra.hour, coords.dec.deg, marker='+',
                label="{0}".format(entry[0]))

ax1.patch.set_alpha(.0)
ax1.axis('off')

x1, x2, y1, y2 = 2100, 2450, 3100, 4100  # specify the limits
axins.set_xlim(x1, x2)  # apply the x-limits
axins.set_ylim(y1, y2)  # apply the y-limits
plt.yticks(visible=False)
plt.xticks(visible=False)
Exemple #5
0
class EventListChecker(Checker):
    """Event list checker.

    Data format specification: ref:`gadf:iact-events`

    Parameters
    ----------
    event_list : `~gammapy.data.EventList`
        Event list
    """

    CHECKS = {
        "meta": "check_meta",
        "columns": "check_columns",
        "times": "check_times",
        "coordinates_galactic": "check_coordinates_galactic",
        "coordinates_altaz": "check_coordinates_altaz",
    }

    accuracy = {"angle": Angle("1 arcsec"), "time": Quantity(1, "microsecond")}

    # https://gamma-astro-data-formats.readthedocs.io/en/latest/events/events.html#mandatory-header-keywords
    meta_required = [
        "HDUCLASS",
        "HDUDOC",
        "HDUVERS",
        "HDUCLAS1",
        "OBS_ID",
        "TSTART",
        "TSTOP",
        "ONTIME",
        "LIVETIME",
        "DEADC",
        "RA_PNT",
        "DEC_PNT",
        # TODO: what to do about these?
        # They are currently listed as required in the spec,
        # but I think we should just require ICRS and those
        # are irrelevant, should not be used.
        # 'RADECSYS',
        # 'EQUINOX',
        "ORIGIN",
        "TELESCOP",
        "INSTRUME",
        "CREATOR",
        # https://gamma-astro-data-formats.readthedocs.io/en/latest/general/time.html#time-formats
        "MJDREFI",
        "MJDREFF",
        "TIMEUNIT",
        "TIMESYS",
        "TIMEREF",
        # https://gamma-astro-data-formats.readthedocs.io/en/latest/general/coordinates.html#coords-location
        "GEOLON",
        "GEOLAT",
        "ALTITUDE",
    ]

    _col = collections.namedtuple("col", ["name", "unit"])
    columns_required = [
        _col(name="EVENT_ID", unit=""),
        _col(name="TIME", unit="s"),
        _col(name="RA", unit="deg"),
        _col(name="DEC", unit="deg"),
        _col(name="ENERGY", unit="TeV"),
    ]

    def __init__(self, event_list):
        self.event_list = event_list

    def _record(self, level="info", msg=None):
        obs_id = self.event_list.table.meta["OBS_ID"]
        return {"level": level, "obs_id": obs_id, "msg": msg}

    def check_meta(self):
        meta_missing = sorted(set(self.meta_required) - set(self.event_list.table.meta))
        if meta_missing:
            yield self._record(
                level="error", msg=f"Missing meta keys: {meta_missing!r}"
            )

    def check_columns(self):
        t = self.event_list.table

        if len(t) == 0:
            yield self._record(level="error", msg="Events table has zero rows")

        for name, unit in self.columns_required:
            if name not in t.colnames:
                yield self._record(level="error", msg=f"Missing table column: {name!r}")
            else:
                if Unit(unit) != (t[name].unit or ""):
                    yield self._record(
                        level="error", msg=f"Invalid unit for column: {name!r}"
                    )

    def check_times(self):
        dt = (self.event_list.time - self.event_list.observation_time_start).sec
        if dt.min() < self.accuracy["time"].to_value("s"):
            yield self._record(level="error", msg="Event times before obs start time")

        dt = (self.event_list.time - self.event_list.observation_time_end).sec
        if dt.max() > self.accuracy["time"].to_value("s"):
            yield self._record(level="error", msg="Event times after the obs end time")

        if np.min(np.diff(dt)) <= 0:
            yield self._record(level="error", msg="Events are not time-ordered.")

    def check_coordinates_galactic(self):
        """Check if RA / DEC matches GLON / GLAT."""
        t = self.event_list.table

        if "GLON" not in t.colnames:
            return

        galactic = SkyCoord(t["GLON"], t["GLAT"], unit="deg", frame="galactic")
        separation = self.event_list.radec.separation(galactic).to("arcsec")
        if separation.max() > self.accuracy["angle"]:
            yield self._record(
                level="error", msg="GLON / GLAT not consistent with RA / DEC"
            )

    def check_coordinates_altaz(self):
        """Check if ALT / AZ matches RA / DEC."""
        t = self.event_list.table

        if "AZ" not in t.colnames:
            return

        altaz_astropy = self.event_list.altaz
        separation = angular_separation(
            altaz_astropy.data.lon,
            altaz_astropy.data.lat,
            t["AZ"].quantity,
            t["ALT"].quantity,
        )
        if separation.max() > self.accuracy["angle"]:
            yield self._record(
                level="error", msg="ALT / AZ not consistent with RA / DEC"
            )
Exemple #6
0
def plot_all(niters):
    dirty = fits_data("wsclean-dirty.fits")
    image = fits_data("wsclean-image.fits")
    sun_rad = Angle(0.25 * u.deg)
    with fits.open("wsclean-image.fits") as hdu:
        BMAJ = hdu[0].header["BMAJ"]
        BMIN = hdu[0].header["BMIN"]
        BPA = hdu[0].header["BPA"]
        head_str = fits.Header.tostring(hdu[0].header)
        str_start = head_str.find('scale')
        str_end = head_str.find('asec')
        axis_x = hdu[0].header["NAXIS1"]
        axis_y = hdu[0].header["NAXIS2"]
        scale = Angle(float(head_str[str_end - 7:str_end]) * u.arcsec)
        sun_x, sun_y = int(hdu[0].header['CRPIX1']), int(
            hdu[0].header['CRPIX2'])
        sun_x, sun_y = sun_x * scale.arcsec, sun_y * scale.arcsec
        MHz = hdu[0].header['CRVAL3'] * 1e-6
        obs_date = hdu[0].header["DATE-OBS"]

    try:
        residuals = fits_data("wsclean-residual.fits")
    except FileNotFoundError:
        print("No residuals")
    psf = fits_data("wsclean-psf.fits")
    try:
        model = fits_data("wsclean-model.fits")
    except FileNotFoundError:
        print("No model")

    fig, axarr = plt.subplots(2, 2, figsize=(8, 8))
    im0 = axarr[0, 0].imshow(
        image,
        aspect="equal",
        origin="lower",
        extent=[0, axis_x * scale.arcsec, 0, axis_y * scale.arcsec])
    b = Ellipse((1000, 1000),
                Angle(BMAJ * u.deg).arcsec,
                Angle(BMIN * u.deg).arcsec,
                angle=90 + BPA,
                fill=False,
                color='w')
    p = Circle((sun_x, sun_y), sun_rad.arcsec, fill=False, color='r')

    # b = Ellipse((250,250), BMAJ/scale.deg, BMIN/scale.deg,angle=90+BPA, fill=False, color='w')
    axarr[0, 0].set_title("Clean image " + niters + " iterations")
    axarr[0, 0].add_patch(b)
    axarr[0, 0].add_patch(p)
    fig.colorbar(im0, ax=axarr[0, 0], fraction=0.046, pad=0.04)
    im1 = axarr[0, 1].imshow(
        dirty,
        aspect="equal",
        origin="lower",
        extent=[0, axis_x * scale.arcsec, 0, axis_y * scale.arcsec])
    axarr[0, 1].set_title("Dirty image " + niters + " iterations")
    p1 = Circle((sun_x, sun_y), sun_rad.arcsec, fill=False, color='r')
    axarr[0, 1].add_patch(p1)
    fig.colorbar(im1, ax=axarr[0, 1], fraction=0.046, pad=0.04)

    if "residuals" in locals():
        im2 = axarr[1, 0].imshow(
            residuals,
            aspect="equal",
            origin="lower",
            extent=[0, axis_x * scale.arcsec, 0, axis_y * scale.arcsec])
        axarr[1, 0].set_title("Residuals " + niters + " iterations")
        p2 = Circle((sun_x, sun_y), sun_rad.arcsec, fill=False, color='r')
        axarr[1, 0].add_patch(p2)
        fig.colorbar(im2, ax=axarr[1, 0], fraction=0.046, pad=0.04)
    if "model" in locals():
        im3 = axarr[1, 1].imshow(
            model,
            aspect="equal",
            origin="lower",
            extent=[0, axis_x * scale.arcsec, 0, axis_y * scale.arcsec])
        axarr[1, 1].set_title("Model " + niters + " iterations")
        p3 = Circle((sun_x, sun_y), sun_rad.arcsec, fill=False, color='r')
        axarr[1, 1].add_patch(p3)
        fig.colorbar(im3, ax=axarr[1, 1], fraction=0.046, pad=0.04)
    plt.tight_layout()
Exemple #7
0
# %%
# Example plot
# ------------
# Here is an example plot of the model:


import numpy as np
from astropy.coordinates import Angle
from gammapy.modeling.models import (
    DiskSpatialModel,
    Models,
    PowerLawSpectralModel,
    SkyModel,
)

phi = Angle("30 deg")
model = DiskSpatialModel(
    lon_0="2 deg",
    lat_0="2 deg",
    r_0="1 deg",
    e=0.8,
    phi=phi,
    edge_width=0.1,
    frame="galactic",
)

ax = model.plot(add_cbar=True)

# illustrate size parameter
region = model.to_region().to_pixel(ax.wcs)
artist = region.as_artist(facecolor="none", edgecolor="red")
Exemple #8
0
    def cone_search_async(self,
                          coo,
                          rad,
                          epoch,
                          location='500',
                          position_error=120,
                          find_planets=True,
                          find_asteroids=True,
                          find_comets=True,
                          get_query_payload=False,
                          get_raw_response=False,
                          cache=True):
        """
        This method queries the IMCCE
        `SkyBoT <http://vo.imcce.fr/webservices/skybot/?conesearch>`_
        cone search service and produces a `~astropy.table.QTable` object
        containing all Solar System bodies that might be in the cone
        defined by the cone center coordinates and epoch provided.

        Parameters
        ----------
        coo : `~astropy.coordinates.SkyCoord` object or tuple
            Center coordinates of the search cone in ICRS coordinates. If
            provided as tuple, the input is excepted as (right ascension
            in degrees, declination in degrees).
        rad : `~astropy.units.Quantity` object or float
            Radius of the search cone. If no units are provided (input as
            float), degrees are assumed. The maximum search radius is 10
            degrees; if this
            maximum radius is exceeded, it will be clipped and a warning
            will be provided to the user.
        epoch : `~astropy.time.Time` object, float, or string
            Epoch of search process in UT. If provided as float, it is
            interpreted as Julian Date, if provided as string, it is
            interpreted as date in the form ``'YYYY-MM-DD HH-MM-SS'``.
        location : int or str, optional
            Location of the observer on Earth as defined in the official
            `list of IAU codes
            <https://www.minorplanetcenter.net/iau/lists/ObsCodes.html>`_.
            Default: geocentric location (``'500'``)
        position_error : `~astropy.units.Quantity` or float, optional
            Maximum positional error for targets to be queried. If no
            unit is provided, arcseconds are assumed. Maximum positional
            error is 120 arcseconds, larger values are clipped and warning
            will be provided to the user. Default: 120 arcseconds
        find_planets : boolean, optional
            If ``True``, planets will be included in the search. Default:
            ``True``
        find_asteroids : boolean, optional
            If ``True``, asteroids will be included in the search. Default:
            ``True``
        find_comets : boolean, optional
            If ``True``, comets will be included in the search. Default:
            ``True``
        get_query_payload : boolean, optional
            Returns the query payload only and performs no query.
            Default: ``False``
        get_raw_response : boolean, optional
            Returns the raw response as provided by the IMCCE server instead
            of the parsed output. Default: ``False``
        cache : boolean, optional
            Cache this specfific query so it might be retrieved faster in
            the future. Default: ``True``

        Notes
        -----
        The following parameters are queried from the SkyBoT service:

        +------------------+-----------------------------------------------+
        | Column Name      | Definition                                    |
        +==================+===============================================+
        | ``'Number'``     | Target Number (``-1`` if none provided, int)  |
        +------------------+-----------------------------------------------+
        | ``'Name'``       | Target Name (str)                             |
        +------------------+-----------------------------------------------+
        | ``'RA'``         | Target RA (J2000, deg, float)                 |
        +------------------+-----------------------------------------------+
        | ``'DEC'``        | Target declination (J2000, deg, float)        |
        +------------------+-----------------------------------------------+
        | ``'Type'``       | Target dynamical/physical type (str)          |
        +------------------+-----------------------------------------------+
        | ``'V'``          | Target apparent brightness (V-band, mag,      |
        |                  | float)                                        |
        +------------------+-----------------------------------------------+
        | ``'posunc'``     | Positional uncertainty (arcsec, float)        |
        +------------------+-----------------------------------------------+
        | ``'centerdist'`` | Angular distance of target from cone center   |
        |                  | (arcsec, float)                               |
        +------------------+-----------------------------------------------+
        | ``'RA_rate'``    | RA rate of motion (arcsec/hr, float)          |
        +------------------+-----------------------------------------------+
        | ``'DEC_rate'``   | Declination rate of motion (arcsec/hr, float) |
        +------------------+-----------------------------------------------+
        | ``'geodist'``    | Geocentric distance of target (au, float)     |
        +------------------+-----------------------------------------------+
        | ``'heliodist'``  | Heliocentric distance of target (au, float)   |
        +------------------+-----------------------------------------------+
        | ``'alpha'``      | Solar phase angle (deg, float)                |
        +------------------+-----------------------------------------------+
        | ``'elong'``      | Solar elongation angle (deg, float)           |
        +------------------+-----------------------------------------------+
        | ``'x'``          | Target equatorial vector x (au, float)        |
        +------------------+-----------------------------------------------+
        | ``'y'``          | Target equatorial vector y (au, float)        |
        +------------------+-----------------------------------------------+
        | ``'z'``          | Target equatorial vector z (au, float)        |
        +------------------+-----------------------------------------------+
        | ``'vx'``         | Target velocity vector x (au/d, float)        |
        +------------------+-----------------------------------------------+
        | ``'vy'``         | Target velocity vector y (au/d, float)        |
        +------------------+-----------------------------------------------+
        | ``'vz'``         | Target velocity vector z (au/d, float)        |
        +------------------+-----------------------------------------------+
        | ``'epoch'``      | Ephemerides epoch (JD, float)                 |
        +------------------+-----------------------------------------------+

        Examples
        --------
        >>> from astroquery.imcce import Skybot
        >>> from astropy.coordinates import SkyCoord
        >>> from astropy.time import Time
        >>> import astropy.units as u
        >>> field = SkyCoord(1*u.deg, 1*u.deg)
        >>> epoch = Time('2019-05-29 21:42', format='iso')
        >>> Skybot.cone_search(field, 0.1*u.deg, epoch)  # doctest: +SKIP
        <QTable length=2>
        Number    Name           RA         ...      vy          vz       epoch
                                deg         ...    AU / d      AU / d       d
        int64     str9        float64       ...   float64     float64    float64
        ------ --------- ------------------ ... ----------- ----------- ---------
        180969 2005 MM39 1.0019566666666666 ...  0.00977568 0.003022634 2458630.0
        107804 2001 FV58 1.0765258333333332 ... 0.006551369 0.003846177 2458630.0
        """

        URL = conf.skybot_server
        TIMEOUT = conf.timeout

        # check for types and units
        if not isinstance(coo, SkyCoord):
            coo = SkyCoord(ra=coo[0] * u.degree,
                           dec=coo[1] * u.degree,
                           frame='icrs')
        if isinstance(rad, u.Quantity):
            rad = Angle(rad.value, unit=rad.unit)
        if not isinstance(rad, u.Quantity):
            rad = Angle(rad, unit=u.degree)
        if rad > Angle(10, unit=u.degree):
            rad = Angle(10, unit=u.degree)
            warnings.warn('search cone radius set to maximum: 10 deg',
                          UserWarning)
        if isinstance(epoch, (int, float)):
            epoch = Time(epoch, format='jd')
        elif isinstance(epoch, str):
            epoch = Time(epoch, format='iso')
        if isinstance(position_error, u.Quantity):
            position_error = Angle(position_error.value,
                                   unit=position_error.unit)
        if not isinstance(position_error, u.Quantity):
            position_error = Angle(position_error, unit=u.arcsec)
        if position_error > Angle(120, unit=u.arcsec):
            position_error = Angle(120, unit=u.arcsec)
            warnings.warn('positional error set to maximum: 120 arcsec',
                          UserWarning)

        # assemble payload
        request_payload = {
            '-ra':
            coo.ra.deg,
            '-dec':
            coo.dec.deg,
            '-rd':
            rad.deg,
            '-ep':
            str(epoch.jd),
            '-loc':
            str(location),
            '-filter':
            position_error.arcsec,
            '-objFilter':
            str(int(find_asteroids)) + str(int(find_planets)) +
            str(int(find_comets)),
            '-refsys':
            'EQJ2000',
            '-output':
            'all',
            '-mime':
            'text'
        }

        # check for diagnostic flags
        if get_query_payload:
            return request_payload

        self._get_raw_response = get_raw_response

        response = self._request(method='GET',
                                 url=URL,
                                 params=request_payload,
                                 timeout=TIMEOUT,
                                 cache=cache)

        self._uri = response.url

        return response
########################################################################################################

output_path = '/mnt/dwf/archive_NOAO_data/data_outputs/'
output_cats = '/mnt/dwf/archive_NOAO_data/data_outputs/' + year + '/' + month + '/' + field + '/vizier_cats/'

if not os.path.exists(output_cats):
    os.makedirs(output_cats)
else:
    pass

AAVOS = 'II/336'
#v = Vizier(columns = ['mag', '_RAJ2000', '_DEJ2000'], catalog = AAVOS)
#result = v.query_region(field_RA_DEC, radius=Angle(1.5, "deg"))
result = Vizier.query_region(field_RA_DEC,
                             radius=Angle(1.5, "deg"),
                             catalog=AAVOS)

AAVOS_table = Table()
AAVOS_table['RA'] = result[0]['RAJ2000']
AAVOS_table['DEC'] = result[0]['DEJ2000']
AAVOS_table['g_mag'] = result[0]['g_mag']
AAVOS_table['g_mag_err'] = result[0]['e_g_mag']
AAVOS_table['r_mag'] = result[0]['r_mag']
AAVOS_table['r_mag_err'] = result[0]['e_r_mag']
AAVOS_table['i_mag'] = result[0]['i_mag']
AAVOS_table['i_mag_err'] = result[0]['e_i_mag']

AAVOS_output = 'AAVOS.ascii'
AAVOS_table.write(output_cats + AAVOS_output, format='ascii', overwrite=True)
Exemple #10
0
def correct_rgc(coord,
                glx_ctr=SkyCoord('00h42m44.33s +41d16m07.5s', frame='icrs'),
                glx_PA=Angle('37d42m54s'),
                glx_incl=Angle('77.5d'),
                glx_dist=Distance(783, unit=u.kpc),
                deproject=True):
    """Computes deprojected galactocentric distance.

    Inspired by: http://idl-moustakas.googlecode.com/svn-history/
        r560/trunk/impro/hiiregions/im_hiiregion_deproject.pro

    Parameters
    ----------
    coord : :class:`astropy.coordinates.ICRS`
        Coordinate of points to compute galactocentric distance for.
        Can be either a single coordinate, or array of coordinates.
    glx_ctr : :class:`astropy.coordinates.ICRS`
        Galaxy center.
    glx_PA : :class:`astropy.coordinates.Angle`
        Position angle of galaxy disk.
    glx_incl : :class:`astropy.coordinates.Angle`
        Inclination angle of the galaxy disk.
    glx_dist : :class:`astropy.coordinates.Distance`
        Distance to galaxy.
    deproject: :class:`bool`
        Correct to face-on inclination?

    Returns
    -------
    obj_dist : class:`astropy.coordinates.Distance`
        Galactocentric distance(s) for coordinate point(s).
    """
    # distance from coord to glx centre
    sky_radius = glx_ctr.separation(coord)
    avg_dec = 0.5 * (glx_ctr.dec + coord.dec).radian
    x = (glx_ctr.ra - coord.ra) * np.cos(avg_dec)
    y = glx_ctr.dec - coord.dec
    # azimuthal angle from coord to glx  -- not completely happy with this
    phi = glx_PA - Angle('90d') \
            + Angle(np.arctan(y.arcsec / x.arcsec), unit=u.rad)

    # convert to coordinates in rotated frame, where y-axis is galaxy major
    # ax; have to convert to arcmin b/c can't do sqrt(x^2+y^2) when x and y
    # are angles
    xp = (sky_radius * np.cos(phi.radian)).arcmin
    yp = (sky_radius * np.sin(phi.radian)).arcmin

    # de-project if desired
    if deproject:
        ypp = yp / np.cos(glx_incl.radian)
    else:
        ypp = yp
    obj_radius = np.sqrt(xp**2 + ypp**2)  # in arcmin
    # TODO: options for units of output (might want angle rather than distance)
    obj_dist = Distance(Angle(obj_radius, unit=u.arcmin).radian * glx_dist,
                        unit=glx_dist.unit)

    # Computing PA in disk (unused)
    obj_phi = Angle(np.arctan(ypp / xp), unit=u.rad)
    # TODO Zero out very small angles, i.e.
    # if np.abs(Angle(xp, unit=u.arcmin)) < Angle(1e-5, unit=u.rad):
    #     obj_phi = Angle(0.0)

    return obj_dist
Exemple #11
0
    def _parse_result(self, response, verbose=None):
        """
        Parser for Miriade request results
        """

        response_txt = response.text

        if self._get_raw_response:
            return response_txt

        # intercept error messages
        for line in response_txt.split('\n'):
            if 'name="QUERY_STATUS" value="ERROR"' in line:
                errmsg = line[line.find('ERROR:>') +
                              9:line.find('</vot:INFO>')]
                raise RuntimeError(errmsg)

        # convert votable to table
        commons.suppress_vo_warnings()
        voraw = BytesIO(response.content)
        votable = parse(voraw)
        data = votable.get_first_table().to_table()

        # modify table columns
        data['epoch'].unit = u.d

        if 'ra' in data.columns:
            data['ra'] = Angle(data['ra'], unit=u.hourangle).deg * u.deg
            data.rename_column('ra', 'RA')

        if 'dec' in data.columns:
            data['dec'] = Angle(data['dec'], unit=u.deg).deg * u.deg
            data.rename_column('dec', 'DEC')

        if 'raJ2000' in data.columns and 'decJ2000' in data.columns:
            data['raJ2000'] = Angle(data['raJ2000'],
                                    unit=u.hourangle).deg * u.deg
            data['decJ2000'] = Angle(data['decJ2000'], unit=u.deg).deg * u.deg
            data.rename_column('raJ2000', 'RAJ2000')
            data.rename_column('decJ2000', 'DECJ2000')

        if all([p in data.columns for p in ['xp', 'yp', 'zp']]):
            data.rename_column('xp', 'vx')
            data.rename_column('yp', 'vy')
            data.rename_column('zp', 'vz')
            if all([str(data[p].unit) == 'au/day'
                    for p in ['vx', 'vy', 'vz']]):
                data['vx'].unit = u.au / u.day
                data['vy'].unit = u.au / u.day
                data['vz'].unit = u.au / u.day

        if all([p in data.columns for p in ['xh', 'yh', 'zh']]):
            data.rename_column('xh', 'x_h')
            data.rename_column('yh', 'y_h')
            data.rename_column('zh', 'z_h')

        if all([p in data.columns for p in ['xhp', 'yhp', 'zhp']]):
            data.rename_column('xhp', 'vx_h')
            data.rename_column('yhp', 'vy_h')
            data.rename_column('zhp', 'vz_h')
            if all([
                    str(data[p].unit) == 'au/day'
                    for p in ['vx_h', 'vy_h', 'vz_h']
            ]):
                data['vx_h'].unit = u.au / u.day
                data['vy_h'].unit = u.au / u.day
                data['vz_h'].unit = u.au / u.day

        if 'distance' in data.columns:
            data.rename_column('distance', 'delta')

        if 'obsdistance' in data.columns:
            data.rename_column('obsdistance', 'delta')

        if 'heliodistance' in data.columns:
            data.rename_column('heliodistance', 'heldist')

        if 'azimut' in data.columns and 'elevation' in data.columns:
            data['azimut'] = Angle(data['azimut'], unit=u.deg).deg * u.deg
            data['elevation'] = Angle(data['elevation'],
                                      unit=u.deg).deg * u.deg
            data.rename_column('azimut', 'AZ')
            data.rename_column('elevation', 'EL')

        if 'mv' in data.columns:
            data.rename_column('mv', 'V')
            data['V'].unit = u.mag

        if 'phase' in data.columns:
            data.rename_column('phase', 'alpha')

        if 'elongation' in data.columns:
            data.rename_column('elongation', 'elong')

        if 'dracosdec' in data.columns:
            data.rename_column('dracosdec', 'RAcosD_rate')

        if 'ddec' in data.columns:
            data.rename_column('ddec', 'DEC_rate')

        if 'dist_dot' in data.columns:
            data.rename_column('dist_dot', 'delta_rate')

        if 'lst' in data.columns:
            data.rename_column('lst', 'siderealtime')

        if 'hourangle' in data.columns:
            data['hourangle'] = Angle(data['hourangle'],
                                      unit=u.hourangle).deg * u.deg

        if 'aeu' in data.columns:
            data.rename_column('aeu', 'posunc')

        return data
Exemple #12
0
    def select_observations(self, selection=None):
        """Select subset of observations.

        Returns a new observation table representing the subset.

        There are 3 main kinds of selection criteria, according to the
        value of the **type** keyword in the **selection** dictionary:

        - sky regions (boxes or circles)

        - time intervals (min, max)

        - intervals (min, max) on any other parameter present in the
          observation table, that can be casted into an
          `~astropy.units.Quantity` object

        Allowed selection criteria are interpreted using the following
        keywords in the **selection** dictionary under the **type** key.

        - ``sky_box`` and ``sky_circle`` are 2D selection criteria acting
          on sky coordinates

            - ``sky_box`` is a squared region delimited by the **lon** and
              **lat** keywords: both tuples of format (min, max); uses
              `~gammapy.catalog.select_sky_box`

            - ``sky_circle`` is a circular region centered in the coordinate
              marked by the **lon** and **lat** keywords, and radius **radius**;
              uses `~gammapy.catalog.select_sky_circle`

          in each case, the coordinate system can be specified by the **frame**
          keyword (built-in Astropy coordinate frames are supported, e.g.
          ``icrs`` or ``galactic``); an aditional border can be defined using
          the **border** keyword

        - ``time_box`` is a 1D selection criterion acting on the observation
          start time (**TSTART**); the interval is set via the
          **time_range** keyword; uses
          `~gammapy.data.ObservationTable.select_time_range`

        - ``par_box`` is a 1D selection criterion acting on any
          parameter defined in the observation table that can be casted
          into an `~astropy.units.Quantity` object; the parameter name
          and interval can be specified using the keywords **variable** and
          **value_range** respectively; min = max selects exact
          values of the parameter; uses
          `~gammapy.data.ObservationTable.select_range`

        In all cases, the selection can be inverted by activating the
        **inverted** flag, in which case, the selection is applied to keep all
        elements outside the selected range.

        A few examples of selection criteria are given below.

        Parameters
        ----------
        selection : dict
            Dictionary with a few keywords for applying selection cuts.

        Returns
        -------
        obs_table : `~gammapy.data.ObservationTable`
            Observation table after selection.

        Examples
        --------
        >>> selection = dict(type='sky_box', frame='icrs',
        ...                  lon=Angle([150, 300], 'deg'),
        ...                  lat=Angle([-50, 0], 'deg'),
        ...                  border=Angle(2, 'deg'))
        >>> selected_obs_table = obs_table.select_observations(selection)

        >>> selection = dict(type='sky_circle', frame='galactic',
        ...                  lon=Angle(0, 'deg'),
        ...                  lat=Angle(0, 'deg'),
        ...                  radius=Angle(5, 'deg'),
        ...                  border=Angle(2, 'deg'))
        >>> selected_obs_table = obs_table.select_observations(selection)

        >>> selection = dict(type='time_box',
        ...                  time_range=Time(['2012-01-01T01:00:00', '2012-01-01T02:00:00']))
        >>> selected_obs_table = obs_table.select_observations(selection)

        >>> selection = dict(type='par_box', variable='ALT',
        ...                  value_range=Angle([60., 70.], 'deg'))
        >>> selected_obs_table = obs_table.select_observations(selection)

        >>> selection = dict(type='par_box', variable='OBS_ID',
        ...                  value_range=[2, 5])
        >>> selected_obs_table = obs_table.select_observations(selection)

        >>> selection = dict(type='par_box', variable='N_TELS',
        ...                  value_range=[4, 4])
        >>> selected_obs_table = obs_table.select_observations(selection)
        """
        from ..catalog import select_sky_box, select_sky_circle

        if "inverted" not in selection.keys():
            selection["inverted"] = False

        if selection["type"] == "sky_circle":
            lon = selection["lon"]
            lat = selection["lat"]
            radius = selection["radius"] + selection["border"]
            return select_sky_circle(
                self,
                lon_cen=lon,
                lat_cen=lat,
                radius=radius,
                frame=selection["frame"],
                inverted=selection["inverted"],
            )

        elif selection["type"] == "sky_box":
            lon = selection["lon"]
            lat = selection["lat"]
            border = selection["border"]
            lon = Angle([lon[0] - border, lon[1] + border])
            lat = Angle([lat[0] - border, lat[1] + border])
            return select_sky_box(
                self,
                lon_lim=lon,
                lat_lim=lat,
                frame=selection["frame"],
                inverted=selection["inverted"],
            )

        elif selection["type"] == "time_box":
            return self.select_time_range(
                "TSTART", selection["time_range"], selection["inverted"]
            )

        elif selection["type"] == "par_box":
            return self.select_range(
                selection["variable"], selection["value_range"], selection["inverted"]
            )

        else:
            raise ValueError("Invalid selection type: {}".format(selection["type"]))
def produce_postage_stamps_new(row_dict, askap_data, askap_wcs, mos_data, mos_wcs, askap_extractions, cat_extractions, askap_pre_convolve_catalog, radius=13./60., contrast=0.2,
                            convolve=False, askap_nonconv_data=None, askap_nonconv_wcs=None, basecat="sumss"):
    #For now support one ASKAP image at a time so can just take this from the first entry.

    #First initialise the figure and set up the askap panel with the image.
    radius = Angle(radius * u.arcmin)
    if convolve:
        total_panels = 3
    else:
        total_panels = 2
    panels={}
    other={"sumss":"nvss", "nvss":"sumss"}
    fig = plt.figure(figsize=(18, 8))
    thissurvey = row_dict["survey_used"].upper()

    target = SkyCoord(row_dict["master_ra"]*u.degree, row_dict["master_dec"]*u.degree)
    askap_cutout = Cutout2D(askap_data, position=target, size=radius, wcs=askap_wcs, mode='partial')
    mos_cutout = Cutout2D(mos_data, position=target, size=radius, wcs=mos_wcs, mode='partial')
    if convolve:
        askap_nonconv_cutout = Cutout2D(askap_nonconv_data, position=target, size=radius, wcs=askap_nonconv_wcs, mode='partial')

    askap_norm = ImageNormalize(askap_cutout.data, interval=ZScaleInterval(contrast=contrast))
    mos_norm = ImageNormalize(mos_cutout.data, interval=ZScaleInterval(contrast=contrast))
    if convolve:
        askap_nonconv_norm = ImageNormalize(askap_nonconv_cutout.data, interval=ZScaleInterval(contrast=contrast))

    panels[1] = fig.add_subplot(1,total_panels,1, projection=mos_cutout.wcs)
    panels[2] = fig.add_subplot(1,total_panels,2, projection=askap_cutout.wcs)
    if convolve:
        panels[3] = fig.add_subplot(1,total_panels,3, projection=askap_nonconv_cutout.wcs)

    panels[1].imshow(mos_cutout.data,norm=mos_norm,cmap='gray_r')
    panels[2].imshow(askap_cutout.data,norm=askap_norm,cmap='gray_r')
    if convolve:
        panels[3].imshow(askap_nonconv_cutout.data,norm=askap_nonconv_norm,cmap='gray_r')

    asp = np.diff(panels[1].get_xlim())[0] / np.diff(panels[1].get_ylim())[0]

    asp /= np.abs(np.diff(panels[2].get_xlim())[0] / np.diff(panels[2].get_ylim())[0])

    panels[1].set_aspect(asp)

    # if convolve:
        # panels[3].set_aspect(asp)

    for i in panels:
        panels[i].set_autoscale_on(False)

    askap_collection = create_ellipses(askap_extractions, askap_cutout.wcs, "#1f77b4")

    if convolve:
        askap_nonconv_collection = create_ellipses(askap_pre_convolve_catalog, askap_cutout.wcs, "#11BA1C")
        askap_nonconv_collection_2 = create_ellipses(askap_pre_convolve_catalog, askap_cutout.wcs, "#11BA1C")
        askap_collection_2 = create_ellipses(askap_extractions, askap_cutout.wcs, "#1f77b4")
    else:
        askap_nonconv_collection = None
        askap_nonconv_collection_2 = None
        askap_collection_2 = None

    askap_catalog_collection = create_ellipses(cat_extractions, askap_cutout.wcs, "#d62728")

    catalog_askap_collection = create_ellipses(askap_extractions, mos_cutout.wcs, "#1f77b4")

    if convolve:
        catalog_askap_nonconv_collection = create_ellipses(askap_pre_convolve_catalog, mos_cutout.wcs, "#11BA1C")
        askap_catalog_collection_2 = create_ellipses(cat_extractions, askap_cutout.wcs, "#d62728")
    else:
        catalog_askap_nonconv_collection = None
        catalog_askap_nonconv_collection_2 = None
        askap_catalog_collection_2 = None

    catalog_collection = create_ellipses(cat_extractions, mos_cutout.wcs, "#d62728")

    #Ellipes loading
    panels[1].add_collection(catalog_collection, autolim=False)
    panels[1].add_collection(catalog_askap_collection, autolim=False)

    panels[2].add_collection(askap_collection, autolim=False)
    panels[2].add_collection(askap_catalog_collection, autolim=False)

    if convolve:
        panels[1].add_collection(catalog_askap_nonconv_collection, autolim=False)
        panels[2].add_collection(askap_nonconv_collection, autolim=False)
        panels[3].add_collection(askap_catalog_collection_2, autolim=False)
        panels[3].add_collection(askap_collection_2, autolim=False)
        panels[3].add_collection(askap_nonconv_collection_2, autolim=False)


    bbox_dict=dict(boxstyle="round", ec="white", fc="white", alpha=0.8)

    # if not pd.isna(filtered_cross_matches.iloc[0]["master_catalog_Mosaic_rms"]):
    #     image_rms = filtered_cross_matches.iloc[0]["master_catalog_Mosaic_rms"]
    # else:
    #     image_rms = filtered_cross_matches.iloc[0]["catalog_Mosaic_rms"]

    #Now begin the main loop per source
    # debug_num=0
    if row_dict["type"] == "match":
        askap_title = "RACS "+row_dict["askap_name"]
        if np.isnan(row_dict["aegean_convolved_int_flux"]) and convolve:
            askap_title_2 = "RACS "+row_dict["askap_non_conv_name"]
        else:
            askap_title_2 = "RACS" + row_dict["askap_name"]
        sumss_title = "{} {}".format(thissurvey, row_dict["master_name"])
        recentre_ra=row_dict["master_ra"]
        recentre_dec=row_dict["master_dec"]

    elif row_dict["type"] == "noaskapmatch":
        askap_title = "RACS (Convolved)"
        askap_title_2 = "RACS (Non-Convolved)"
        sumss_title = "{} {}".format(thissurvey, row_dict["master_name"])
        recentre_ra=row_dict["master_ra"]
        recentre_dec=row_dict["master_dec"]
    elif row_dict["type"] == "nocatalogmatch":
        askap_title = "RACS "+row_dict["askap_name"]
        if convolve:
            askap_title_2 = "RACS "+row_dict["askap_non_conv_name"]
        sumss_title = "{} ({})".format(thissurvey, row_dict["master_catalog_mosaic"])
        recentre_ra=row_dict["askap_ra"]
        recentre_dec=row_dict["askap_dec"]

    panels[1].set_title(sumss_title)
    panels[2].set_title(askap_title)
    if convolve:
        panels[3].set_title(askap_title_2)

    #Centre each image on the ASKAP coordinates for clarity
    if convolve:
        pos_x_1 = 0.41
        pos_y_1 = 0.68
        pos_x_2 = 0.14
        pos_y_2 = 0.27
        pos_x_3 = 0.07
        pos_y_3 = 0.12
        pos_x_4 = 0.65
        pos_x_5 = 0.68
        pos_y_5 = 0.27
        size=15
        boxsize = 10
    else:
        pos_x_1 = 0.57
        pos_y_1 = 0.75
        pos_x_2 = 0.14
        pos_y_2 = 0.14
        pos_x_3 = 0.02
        pos_y_3 = 0.02
        pos_x_4 = 0.8
        size = 18
        boxsize = 14


    for i in panels:
        lon = panels[i].coords[0]
        lat = panels[i].coords[1]
        if i==1:
            lon.set_axislabel('RA', size=size)
            lat.set_axislabel('Dec.', size=size)
            lon.set_ticklabel(size=12)
            lat.set_ticklabel(size=12)
        else:
            lon.set_ticklabel_visible(False)
            lat.set_ticklabel_visible(False)
            lon.set_axislabel('')
            lat.set_axislabel('')

    image_rms = row_dict["master_catalog_Mosaic_rms"]
    snr_col = "{0}_{0}_snr".format(thissurvey.lower())

    if row_dict["type"] == "match":
        for p in panels:
            r = SphericalCircle((target.ra, target.dec), 1. * u.arcmin, edgecolor='C9', facecolor='none', transform=panels[p].get_transform('fk5'), linewidth=3)
            panels[p].add_patch(r)
            askap_target = SkyCoord(row_dict["askap_ra"]*u.degree, row_dict["askap_dec"]*u.degree)
            r = SphericalCircle((askap_target.ra, askap_target.dec), 1. * u.arcmin, edgecolor='C1', facecolor='none', transform=panels[p].get_transform('fk5'), linewidth=3)
            panels[p].add_patch(r)
            if p==2:
                sep_text=plt.text(pos_x_3, pos_y_3, "Distance Separation = {:.2f} arcsec".format(row_dict["d2d"]), transform=fig.transFigure, size=size)
                ratio_text=plt.text(pos_x_4, pos_y_3, "Scaled Int. Flux Ratio = {:.2f} +/- {:.2f}".format(row_dict["master_ratio"], row_dict["master_ratio_err"]), transform=fig.transFigure, size=size)
                askap_snr_text=plt.text(pos_x_1, pos_y_2, "ASKAP Int. Flux = {:.2f} +/- {:.2f} mJy\nASKAP Image RMS ~ {:.2f} mJy\nASKAP Local RMS ~ {:.2f} mJy".format(row_dict["askap_flux_to_use"]*1.e3,
                    row_dict["askap_flux_to_use_err"]*1.e3, row_dict["askap_rms"]*1.e3, row_dict["measured_askap_local_rms"]*1.e3), transform=fig.transFigure, bbox=bbox_dict, size=boxsize)
                sumss_snr_text=plt.text(pos_x_2, pos_y_2, "{0} Int. Flux = {1:.2f} +/- {2:.2f} mJy\n{0} RMS ~ {3:.2f} mJy\n{0} SNR = {4:.2f}".format(thissurvey,
                    row_dict["catalog_flux_to_use"]*1.e3,row_dict["catalog_flux_to_use_err"]*1.e3,image_rms*1.e3, row_dict[snr_col]), transform=fig.transFigure, bbox=bbox_dict, size=boxsize)
                if convolve:
                    askap_snr_text_preconv=plt.text(pos_x_5, pos_y_2, "ASKAP Int. Flux = {:.2f} +/- {:.2f} mJy\nASKAP Image RMS ~ {:.2f} mJy\nASKAP Local RMS ~ {:.2f} mJy".format(row_dict["askap_flux_to_use_2"]*1.e3,
                        row_dict["askap_flux_to_use_2_err"]*1.e3, row_dict["askap_rms_preconv"]*1.e3, row_dict["measured_preconv_askap_local_rms"]*1.e3), transform=fig.transFigure, bbox=bbox_dict, size=boxsize)
                    custom_lines = [Line2D([0], [0], color="w", marker="o", fillstyle="none", lw=2, markeredgecolor='#1f77b4', linestyle="none"),
                                    Line2D([0], [0], color="w", marker="o", fillstyle="none", lw=2, markeredgecolor='#d62728', linestyle="none"),
                                    Line2D([0], [0], color="w", markeredgecolor='#11BA1C', marker="o", fillstyle="none", lw=2, linestyle="none"),
                                    Line2D([0], [0], color="w", markeredgecolor='C9', marker="o", fillstyle="none", lw=2, linestyle="none"),
                                    Line2D([0], [0], color='C1'),
                                    Line2D([0], [0], color='C9')
                                ]
                    labels = ["ASKAP Sources", "{} Sources".format(basecat.upper()), "Non-conv ASKAP sources", "Extracted Flux", "ASKAP Source Position", thissurvey+" Source Position"]
                else:
                    custom_lines = [Line2D([0], [0], color="w", marker="o", fillstyle="none", lw=2, markeredgecolor='#1f77b4', linestyle="none"),
                                    Line2D([0], [0], color="w", marker="o", fillstyle="none", lw=2, markeredgecolor='#d62728', linestyle="none"),
                                    Line2D([0], [0], color="w", markeredgecolor='C9', marker="o", fillstyle="none", lw=2, linestyle="none"),
                                    Line2D([0], [0], color='C1'),
                                    Line2D([0], [0], color='C9')
                                ]
                    labels = ["ASKAP Sources", "{} Sources".format(basecat.upper()), "Extracted Flux", "ASKAP Source Position", thissurvey+" Source Position"]

    elif row_dict["type"] == "noaskapmatch":
        for p in panels:
            r = SphericalCircle((target.ra, target.dec), 1. * u.arcmin, edgecolor='C9', facecolor='none', transform=panels[p].get_transform('fk5'), linewidth=3)
            panels[p].add_patch(r)
            if p==1:
                ratio_text=plt.text(pos_x_4, pos_y_3, "Scaled Int. Flux Ratio = {:.2f} +/- {:.2f}".format(row_dict["master_ratio"], row_dict["master_ratio_err"]), transform=fig.transFigure, size=size)
            if convolve:
                if p==2:
                    r = SphericalCircle((target.ra, target.dec), 22.5 * u.arcsec, edgecolor='C1', facecolor='none', transform=panels[p].get_transform('fk5'), linewidth=1)
                    panels[p].add_patch(r)
                if p==3:
                    r = SphericalCircle((target.ra, target.dec), 7. * u.arcsec, edgecolor='C1', facecolor='none', transform=panels[p].get_transform('fk5'), linewidth=1)
                    panels[p].add_patch(r)
                if p==1:
                    askap_snr_text=plt.text(pos_x_1, pos_y_2, "ASKAP Measured Int. Flux = {:.2f} mJy +/- {:.2f} \nASKAP Image RMS ~ {:.2f} mJy\nASKAP Local RMS ~ {:.2f} mJy".format(row_dict["askap_flux_to_use"]*1.e3,
                        row_dict["askap_flux_to_use_err"]*1.e3, row_dict["askap_rms"]*1.e3, row_dict["measured_askap_local_rms"]*1.e3), transform=fig.transFigure, bbox=bbox_dict, size=boxsize)
                    askap_snr_text_preconv=plt.text(pos_x_5, pos_y_2, "ASKAP Measured Int. Flux = {:.2f} +/- {:.2f} mJy\nASKAP Image RMS ~ {:.2f} mJy\nASKAP Local RMS ~ {:.2f} mJy".format(row_dict["askap_flux_to_use_2"]*1.e3,
                        row_dict["askap_flux_to_use_2_err"]*1.e3, row_dict["askap_rms_preconv"]*1.e3, row_dict["measured_preconv_askap_local_rms"]*1.e3), transform=fig.transFigure, bbox=bbox_dict, size=boxsize)
                    custom_lines = [Line2D([0], [0], color="w", marker="o", fillstyle="none", lw=2, markeredgecolor='#1f77b4'),
                                    Line2D([0], [0], color="w", marker="o", fillstyle="none", lw=2, markeredgecolor='#d62728'),
                                    Line2D([0], [0], color="w", markeredgecolor='#11BA1C', marker="o", fillstyle="none", lw=2),
                                    Line2D([0], [0], color="w", markeredgecolor='C9', marker="o", fillstyle="none", lw=2),
                                    Line2D([0], [0], color='C1')
                                ]
                    labels = ["ASKAP Sources", "{} Sources".format(thissurvey), "Non-conv ASKAP sources", "Extracted Flux", thissurvey+" Source Position"]
            else:
                if p==2:
                    r = SphericalCircle((target.ra, target.dec), 7. * u.arcsec, edgecolor='C1', facecolor='none', transform=panels[p].get_transform('fk5'), linewidth=1)
                    panels[p].add_patch(r)
                if p==1:
                    askap_snr_text=plt.text(pos_x_1, pos_y_2, "ASKAP Measured Int. Flux = {:.2f} +/- {:.2f} mJy\nASKAP Image RMS ~ {:.2f} mJy\nASKAP Local RMS ~ {:.2f} mJy".format(row_dict["askap_flux_to_use"]*1.e3,
                        row_dict["askap_flux_to_use_err"]*1.e3, row_dict["askap_rms"]*1.e3, row_dict["measured_askap_local_rms"]*1.e3), transform=fig.transFigure, bbox=bbox_dict, size=boxsize)
                    custom_lines = [Line2D([0], [0], color="w", marker="o", fillstyle="none", lw=2, markeredgecolor='#1f77b4'),
                                    Line2D([0], [0], color="w", marker="o", fillstyle="none", lw=2, markeredgecolor='#d62728'),
                                    Line2D([0], [0], color="w", markeredgecolor='C9', marker="o", fillstyle="none", lw=2),
                                    Line2D([0], [0], color='C1')
                                ]
                    labels = ["ASKAP Sources", "{} Sources".format(thissurvey), "Extracted Flux", thissurvey+" Source Position"]
            if p==1:
                sumss_snr_text=plt.text(pos_x_2, pos_y_2, "{0} Int. Flux = {1:.2f} +/- {2:.2f} mJy\n{0} RMS ~ {3:.2f} mJy\n{0} SNR = {4:.2f}".format(thissurvey,
                    row_dict["catalog_flux_to_use"]*1.e3, row_dict["catalog_flux_to_use_err"]*1.e3,image_rms*1.e3, row_dict[snr_col]), transform=fig.transFigure, bbox=bbox_dict, size=boxsize)
        #Rectangle on extracted flux on ASKAP images
        # x_size,y_size=_get_extracted_rectangle_size(panels[1], recentre_ra, recentre_dec, 10)
        # panels[1].show_rectangles([recentre_ra], [recentre_dec], x_size, y_size, color='C1', linewidth=1, label="Extracted Flux", layer="Extracted Flux")
        # if convolve:
        #     x_size,y_size=_get_extracted_rectangle_size(panels[2], recentre_ra, recentre_dec, 10)
        #     panels[2].show_rectangles([recentre_ra], [recentre_dec], x_size, y_size, color='C1', linewidth=1, label="Extracted Flux", layer="Extracted Flux")

    elif row_dict["type"] == "nocatalogmatch":
        for p in panels:
            r = SphericalCircle((target.ra, target.dec), 1. * u.arcmin, edgecolor='C1', facecolor='none', transform=panels[p].get_transform('fk5'), linewidth=3)
            panels[p].add_patch(r)
            if p==1:
                ratio_text=plt.text(pos_x_4, pos_y_3, "Scaled Int. Flux Ratio = {:.2f} +/- {:.2f}".format(row_dict["master_ratio"], row_dict["master_ratio_err"]), transform=fig.transFigure, size=size)
                #Put a rectangle to show extracted peak flux measurement
                # x_size,y_size=_get_extracted_rectangle_size(panels[0], recentre_ra, recentre_dec, 5)
                r = SphericalCircle((target.ra, target.dec), 22.5 * u.arcsec, edgecolor='C9', facecolor='none', transform=panels[p].get_transform('fk5'), linewidth=1)
                panels[p].add_patch(r)
                askap_snr_text=plt.text(pos_x_1, pos_y_2, "ASKAP Int. Flux = {:.2f} +/- {:.2f} mJy\nASKAP Image RMS ~ {:.2f} mJy\nASKAP Local RMS ~ {:.2f} mJy".format(row_dict["askap_flux_to_use"]*1.e3,
                    row_dict["askap_flux_to_use_err"]*1.e3,row_dict["askap_rms"]*1.e3, row_dict["measured_askap_local_rms"]*1.e3), transform=fig.transFigure, bbox=bbox_dict, size=boxsize)
                if convolve:
                    askap_snr_text_preconv=plt.text(pos_x_5, pos_y_2, "ASKAP Int. Flux = {:.2f} +/- {:.2f} mJy\nASKAP Image RMS ~ {:.2f} mJy\nASKAP Local RMS ~ {:.2f} mJy".format(row_dict["askap_flux_to_use_2"]*1.e3,
                        row_dict["askap_flux_to_use_2_err"]*1.e3,row_dict["askap_rms_preconv"]*1.e3, row_dict["measured_preconv_askap_local_rms"]*1.e3), transform=fig.transFigure, bbox=bbox_dict, size=boxsize)
                    custom_lines = [Line2D([0], [0], color="w", marker="o", fillstyle="none", lw=2, markeredgecolor='#1f77b4'),
                                    Line2D([0], [0], color="w", marker="o", fillstyle="none", lw=2, markeredgecolor='#d62728'),
                                    Line2D([0], [0], color="w", markeredgecolor='#11BA1C', marker="o", fillstyle="none", lw=2),
                                    Line2D([0], [0], color="w", markeredgecolor='C9', marker="o", fillstyle="none", lw=2),
                                    Line2D([0], [0], color='C9')
                                ]
                    labels = ["ASKAP Sources", "{} Sources".format(basecat.upper()), "Non-conv ASKAP sources", "Extracted Flux", "ASKAP Source Position"]
                else:
                    custom_lines = [Line2D([0], [0], color="w", marker="o", fillstyle="none", lw=2, markeredgecolor='#1f77b4'),
                                    Line2D([0], [0], color="w", marker="o", fillstyle="none", lw=2, markeredgecolor='#d62728'),
                                    Line2D([0], [0], color="w", markeredgecolor='C9', marker="o", fillstyle="none", lw=2),
                                    Line2D([0], [0], color='C9')
                                ]
                    labels = ["ASKAP Sources", "{} Sources".format(basecat.upper()), "Extracted Flux", "ASKAP Source Position"]
                sumss_snr_text=plt.text(pos_x_2, pos_y_2, "Measured {0} Int. Flux = {1:.2f} +/- {2:.2f} mJy\n{0} RMS ~ {3:.2f} mJy\n{0} SNR = {4:.2f}".format(thissurvey,
                    row_dict["catalog_flux_to_use"]*1.e3,row_dict["catalog_flux_to_use_err"]*1.e3,image_rms*1.e3, row_dict["catalog_flux_to_use"]/image_rms), transform=fig.transFigure, bbox=bbox_dict, size=boxsize)
            # panels[0].show_rectangles([recentre_ra], [recentre_dec], x_size, y_size, color='C1', linewidth=1, label="Extracted Flux", layer="Extracted Flux")
    #         #
    #         # if skip:
    #         #     continue
            #
    figname = "source_{}_postagestamps.jpg".format(row_dict["master_name"])

    if convolve:
        panels[3].legend(custom_lines,  labels, fontsize=10, loc=1)
    else:
        panels[2].legend(custom_lines, labels, fontsize=14, loc=1)



    plt.savefig(figname, bbox_inches="tight")
    fig.clf()
    #plt.show()
    plt.close(fig)
    return
Exemple #14
0
    def __init__(self, telemetry_file=None, save_file=None):
        if telemetry_file is not None:
            self.filename = telemetry_file

            self.systime = []
            self.v_x = []
            self.v_y = []
            self.v_sum = []

            self.elevation_ae = []
            self.elevation_ie = []
            self.solar_elevation = []

            count = 0

            print("Parsing {0}".format(telemetry_file))
            with open(telemetry_file, 'rb') as f:
                pg = parser_generator(f,
                                      filter_systemid=0x03,
                                      filter_tmtype=0x03,
                                      verbose=True)
                for p in pg:
                    count += 1
                    self.systime.append(p['systime'])
                    self.v_x.append(p['v_x'])
                    self.v_y.append(p['v_y'])
                    self.v_sum.append(p['v_sum'])

                    self.elevation_ae.append(p['elevation_ae'])
                    self.elevation_ie.append(p['elevation_ie'])
                    self.solar_elevation.append(p['solar_elevation'])

            if count > 0:
                self.systime = np.hstack(self.systime)
                self.v_x = np.hstack(self.v_x)
                self.v_y = np.hstack(self.v_y)
                self.v_sum = np.hstack(self.v_sum)

                self.elevation_ae = Angle(self.elevation_ae, 'deg')
                self.elevation_ie = Angle(self.elevation_ie, 'deg')
                self.solar_elevation = Angle(self.solar_elevation, 'deg')

                print("Total packets: {0}".format(count))
            else:
                print("No packets found")

        elif save_file is not None:
            print("Restoring {0}".format(save_file))
            with gzip.open(save_file, 'rb') as f:
                try:
                    saved = pickle.load(f, encoding='latin1')
                except TypeError:
                    saved = pickle.load(f)
                self.filename = saved['filename']
                self.systime = saved['systime']
                self.v_x = saved['v_x']
                self.v_y = saved['v_y']
                self.v_sum = saved['v_sum']
                self.elevation_ae = saved['elevation_ae']
                self.elevation_ie = saved['elevation_ie']
                self.solar_elevation = saved['solar_elevation']
        else:
            raise RuntimeError(
                "Either a telemetry file or a save file must be specified")
Exemple #15
0
def radec_to_altaz(radec: SkyCoord,
                   time: Time,
                   observer: EarthLocation = nenufar_position,
                   fast_compute: bool = True) -> SkyCoord:
    r""" Converts a celestial object equatorial coordinates
        to horizontal coordinates.

        If ``fast_compute=True`` is selected, the computation is
        accelerated using Local Sidereal Time approximation
        (see :func:`~nenupy.astro.astro_tools.local_sidereal_time`).
        The altitude :math:`\theta` and azimuth :math:`\varphi` are computed
        as follows:

        .. math::
            \cases{
                \sin(\theta) = \sin(\delta) \sin(l) + \cos(\delta) \cos(l) \cos(h)\\
                \cos(\varphi) = \frac{\sin(\delta) - \sin(l) \sin(\theta)}{\cos(l)\cos(\varphi)}
            }

        with :math:`\delta` the object's declination, :math:`l`
        the ``observer``'s latitude and :math:`h` the Local Hour Angle
        (see :func:`~nenupy.astro.astro_tools.hour_angle`).
        If :math:`\sin(h) \geq 0`, then :math:`\varphi = 2 \pi - \varphi`.
        Otherwise, :meth:`~astropy.coordinates.SkyCoord.transform_to`
        is used.

        :param radec:
            Celestial object equatorial coordinates.
        :type radec:
            :class:`~astropy.coordinates.SkyCoord`
        :param time:
            Coordinated universal time.
        :type time:
            :class:`~astropy.time.Time`
        :param observer:
            Earth location where the observer is at.
            Default is NenuFAR's position.
        :type observer:
            :class:`~astropy.coordinates.EarthLocation`
        :param fast_compute:
            If set to ``True``, it enables faster computation time for the
            conversion, mainly relying on an approximation of the
            local sidereal time. All other values would lead to
            accurate coordinates computation. Differences in
            coordinates values are of the order of :math:`10^{-2}`
            degrees or less.
        :type fast_compute:
            `bool`

        :returns:
            Celestial object's horizontal coordinates.
            If either ``radec`` or ``time`` are 1D arrays, the
            resulting object will be of shape ``(time, positions)``.
        :rtype:
            :class:`~astropy.coordinates.SkyCoord`

        :Example:
            .. code-block:: python

                from nenupy.astro import radec_to_altaz
                from astropy.time import Time
                from astropy.coordinates import SkyCoord

                altaz = radec_to_altaz(
                    radec=SkyCoord([300, 200], [45, 45], unit="deg"),
                    time=Time("2022-01-01T12:00:00"),
                    fast_compute=True
                )

    """
    if not time.isscalar:
        time = time.reshape((time.size, 1))
        radec = radec.reshape((1, radec.size))

    if fast_compute:
        radec = radec.transform_to(FK5(equinox=time))

        ha = hour_angle(radec=radec,
                        time=time,
                        observer=observer,
                        fast_compute=fast_compute)

        two_pi = Angle(360.0, unit='deg')

        ha = hour_angle(radec=radec,
                        time=time,
                        observer=observer,
                        fast_compute=fast_compute)

        sin_dec = np.sin(radec.dec.rad)
        cos_dec = np.cos(radec.dec.rad)
        sin_lat = np.sin(observer.lat.rad)
        cos_lat = np.cos(observer.lat.rad)

        # Compute elevation
        sin_elevation = sin_dec * sin_lat + cos_dec * cos_lat * np.cos(ha.rad)
        elevation = Latitude(np.arcsin(sin_elevation), unit="rad")

        # Compute azimuth
        cos_azimuth = (sin_dec - np.sin(elevation.rad)*sin_lat)/\
            (np.cos(elevation.rad)*cos_lat)
        azimuth = Longitude(np.arccos(cos_azimuth), unit="rad")

        if azimuth.isscalar:
            if np.sin(ha.rad) > 0:
                azimuth *= -1
                azimuth += two_pi
        else:
            posMask = np.sin(ha.rad) > 0
            azimuth[posMask] *= -1
            azimuth[posMask] += two_pi

        return SkyCoord(azimuth,
                        elevation,
                        frame=AltAz(obstime=time, location=observer))
    else:
        return radec.transform_to(AltAz(obstime=time, location=observer))
Exemple #16
0
def main(argv):

    from optparse import OptionParser

    parser = OptionParser()

    parser.add_option('-f',
                      '--filename',
                      help='Input file with output from donut (.npy).',
                      type='string')
    parser.add_option(
        '--niter',
        help=
        'Number of iterations on the linear fitting procedure (default = 1).',
        type='int',
        default=1)
    parser.add_option('--maxreject',
                      help='Maximum number of rejected points (default=3).',
                      type='int',
                      default=3)
    parser.add_option('-o',
                      '--output',
                      help='Output file name.',
                      type='string')

    opt, args = parser.parse_args(argv)

    log.info('Reading input catalog: %s' % opt.filename)
    cat = np.load(opt.filename).T

    pix2mm = 0.1  # pixel size in um
    id_seeing = 2
    id_focus = 5
    id_astigx = 6
    id_astigy = 7
    id_commax = 9
    id_commay = 8
    id_spherical = 12

    ####################################################################################################################

    def fit():

        mask = np.zeros_like(x) == 0
        nreject = 0

        for iter in range(niter):
            x1, y1 = x[mask], y[mask]

            z = np.polyfit(x1, y1, 1)

            fit = np.poly1d(z)

            yres = y - fit(x)  # residue
            avg = np.mean(yres)
            std = np.std(yres)
            mask = np.sqrt(yres**2.) < std
            new_nreject = len(mask) - len(mask[mask])

            log.debug('Iter[%i/%i]: Avg = %f Std = %f Reject. %i' %
                      (iter, niter, avg, std, nreject))

            if new_nreject > opt.maxreject:
                log.debug('Maximum reject reached. Breaking.')
                break
            elif new_nreject == nreject:
                log.debug('Rejected 0 data points. Breaking')
                break
            nreject = new_nreject

        print z

        return z, mask

    ####################################################################################################################

    def plot():

        py.plot(x[mask], y[mask], 'bo')
        ylim = py.ylim()
        xlim = py.xlim()
        print xlim
        py.plot(x[np.bitwise_not(mask)],
                y[np.bitwise_not(mask)],
                'o',
                markerfacecolor='w')

        py.plot(xx, newFit(xx), 'r-')

        # ylim = py.ylim()

        if xlim[0] < root < xlim[1]:
            py.plot([root, root], ylim, 'r--')
        py.ylim(ylim)
        py.xlim(xlim)

        mean = np.mean(y[mask])
        py.plot(xlim, [mean, mean], 'b--')

        py.grid()

        return

    ####################################################################################################################

    center = [4357.01, 4808.43]  #[9216/2,9232/2]
    xx = (cat[0] - center[0])
    yy = (cat[1] - center[1])
    pre_mask = xx == xx  #np.bitwise_and(np.abs(xx) > 100, np.abs(yy)> 100)

    xx = (cat[0][pre_mask] - center[0])
    yy = (cat[1][pre_mask] - center[1])

    x = np.sqrt(xx**2. + yy**2.) * pix2mm  #* yy/np.abs(yy)
    y = np.sqrt(cat[id_astigx][pre_mask]**2. + cat[id_astigy][pre_mask]**2.)

    niter = opt.niter if opt.niter > 0 else 1

    z, mask = fit()
    root = -z[1] / z[0]
    V_angle = Angle(z[0] * u.rad)

    newFit = np.poly1d(z)
    mean = np.mean(y[mask])
    log.debug('Rejected %i of %i' % (len(mask) - len(mask[mask]), len(mask)))
    # log.info('Primary mirror astigmatism in V = %f'%(mean/10.))
    log.info('Angle V = %s degrees' %
             (V_angle.to_string(unit=u.degree, sep=(':', ':', ':'))))
    log.info('Center X = %.4f mm / %.2f pixels' % (root * 1e-3, root / pix2mm))

    xx = np.linspace(x.min() - 200 * pix2mm, x.max() + 200 * pix2mm)

    py.subplot(231)

    plot()

    # py.show()
    # return
    ####################################################################################################################

    # x = np.sqrt(cat[0]**2. + cat[1]**2.)*pix2mm
    y = y - newFit(x)
    x = np.arctan2(cat[0], cat[1])

    # y = cat[id_astigy][pre_mask]

    z, mask = fit()
    root = -z[1] / z[0]

    U_angle = Angle(z[0] * u.rad * 1e-3)
    newFit = np.poly1d(z)
    log.debug('Rejected %i of %i' % (len(mask) - len(mask[mask]), len(mask)))
    mean = np.mean(y[mask])
    # log.info('Primary mirror astigmatism in  U = %f'%(mean/10.))
    log.info('Angle U = %s degrees' %
             (U_angle.to_string(unit=u.degree, sep=(':', ':', ':'))))
    log.info('Center Y = %.4f mm / %.2f pixels' % (root * 1e-3, root / pix2mm))

    xx = np.linspace(x.min() - 200 * pix2mm, x.max() + 200 * pix2mm)

    py.subplot(232)

    plot()

    # py.show()
    # return
    ####################################################################################################################

    py.subplot(233)

    xx = (cat[0] - center[0])
    yy = (cat[1] - center[1])

    x = np.sqrt(xx**2. + yy**2.) * pix2mm  #* yy/np.abs(yy)
    y = cat[id_seeing][pre_mask]

    z, mask = fit()
    root = -z[1] / z[0]
    newFit = np.poly1d(z)
    log.debug('Rejected %i of %i' % (len(mask) - len(mask[mask]), len(mask)))
    Seeing = z[1]
    log.info('Seeing = %.4f arcsec' % (z[1]))
    # log.info('Spherical = %.4f '%(z[1]))
    #log.info('Center Y = %.4f mm / %.2f pixels'%(root, root/pix2mm))

    xx = np.linspace(x.min() - 200 * pix2mm, x.max() + 200 * pix2mm)

    plot()

    ####################################################################################################################

    py.subplot(234)

    x = cat[0]  #np.sqrt(cat[0]**2. + cat[1]**2.)*pix2mm
    y = cat[id_commax][pre_mask]

    z, mask = fit()
    root = -z[1] / z[0]
    newFit = np.poly1d(z)
    log.debug('Rejected %i of %i' % (len(mask) - len(mask[mask]), len(mask)))
    ShiftX = z[1]
    log.info('ShiftX = %.4f mm' % (z[1]))
    #log.info('Center Y = %.4f mm / %.2f pixels'%(root, root/pix2mm))

    xx = np.linspace(x.min() - 200 * pix2mm, x.max() + 200 * pix2mm)

    plot()

    ####################################################################################################################

    py.subplot(235)

    x = cat[1]  # np.sqrt(cat[0]**2. + cat[1]**2.)*pix2mm
    y = cat[id_commay][pre_mask]

    z, mask = fit()
    root = -z[1] / z[0]
    newFit = np.poly1d(z)
    log.debug('Rejected %i of %i' % (len(mask) - len(mask[mask]), len(mask)))
    ShiftY = z[1]
    log.info('ShiftY = %.4f mm' % (z[1]))
    #log.info('Center Y = %.4f mm / %.2f pixels'%(root, root/pix2mm))

    xx = np.linspace(x.min() - 200 * pix2mm, x.max() + 200 * pix2mm)

    plot()

    ####################################################################################################################

    py.subplot(236)

    # x = np.sqrt(cat[0]**2. + cat[1]**2.)*pix2mm
    y = cat[id_focus][pre_mask]

    z, mask = fit()
    root = -z[1] / z[0]
    newFit = np.poly1d([z[0], 0])
    log.debug('Rejected %i of %i' % (len(mask) - len(mask[mask]), len(mask)))
    yfoc = y - newFit(x)
    ShiftZ = np.mean(yfoc[mask])
    log.info('ShiftZ = %.4f mm' % (ShiftZ))
    #log.info('Center Y = %.4f mm / %.2f pixels'%(root, root/pix2mm))

    xx = np.linspace(x.min() - 200 * pix2mm, x.max() + 200 * pix2mm)

    py.plot(x, yfoc, 'o', markerfacecolor='w')
    py.plot(x[mask], yfoc[mask], 'bo')

    py.plot(xx, np.zeros_like(xx) + np.mean(yfoc[mask]), 'r-')

    # ylim = py.ylim()
    #
    # py.plot([root,root],ylim,'r--')
    # py.ylim(ylim)

    py.grid()

    ####################################################################################################################

    # Z4 + h [2 - cos(alpha_x) - cos(alpha_y)]
    CFP = 291.36  # Comma Free Point in mm
    zhexapod = ShiftZ  #- CFP * (2. - np.cos(V_angle.rad) - np.cos(U_angle.rad))
    xhexapod = ShiftX  #+ CFP * np.sin(V_angle.rad)
    yhexapod = ShiftY  #+ CFP * np.sin(U_angle.rad)

    zcfp = -CFP * (2. - np.cos(V_angle.rad) - np.cos(U_angle.rad))
    xcfp = CFP * np.sin(V_angle.rad)
    ycfp = CFP * np.sin(U_angle.rad)

    print(
        '''Hexapod offset:
    X = %+8.4f %+8.4f um
    Y = %+8.4f %+8.4f um
    Z = %+8.4f %+8.4f um
    U = %s degrees
    V = %s degrees
    ''' % (xhexapod / 10, xcfp / 10, yhexapod / 10, ycfp / 10, zhexapod / 10,
           zcfp / 10, U_angle.to_string(unit=u.degree, sep=(':', ':', ':')),
           V_angle.to_string(unit=u.degree, sep=(':', ':', ':'))))
    py.show()
Exemple #17
0
import numpy as np
from astropy.coordinates import (SkyCoord, FK5, Latitude, Angle, ICRS,
                                 concatenate, UnitSphericalRepresentation,
                                 CartesianRepresentation,
                                 match_coordinates_sky)
from astropy import units as u
from astropy.time import Time


def time_latitude():
    Latitude(3.2, u.degree)


ANGLES = Angle(np.ones(10000), u.deg)
J2010 = Time('J2010')
fk5_J2010 = FK5(equinox=J2010)
rnd = np.random.RandomState(seed=42)


def time_angle_array_repr():
    # Prior to Astropy 3.0, this was very inefficient
    repr(ANGLES)


def time_angle_array_str():
    # Prior to Astropy 3.0, this was very inefficient
    str(ANGLES)


def time_angle_array_repr_latex():
    # Prior to Astropy 3.0, this was very inefficient
Exemple #18
0
    def _info_map(self):
        """Print info from map analysis."""
        d = self.data
        ss = "\n*** Info from map analysis ***\n\n"

        ra_str = Angle(d["RAJ2000"], "deg").to_string(unit="hour", precision=0)
        dec_str = Angle(d["DEJ2000"], "deg").to_string(unit="deg", precision=0)
        ss += "{:<20s} : {:8.3f} = {}\n".format("RA", d["RAJ2000"], ra_str)
        ss += "{:<20s} : {:8.3f} = {}\n".format("DEC", d["DEJ2000"], dec_str)

        ss += "{:<20s} : {:8.3f} +/- {:.3f} deg\n".format(
            "GLON", d["GLON"].value, d["GLON_Err"].value)
        ss += "{:<20s} : {:8.3f} +/- {:.3f} deg\n".format(
            "GLAT", d["GLAT"].value, d["GLAT_Err"].value)

        ss += "{:<20s} : {:.3f}\n".format("Position Error (68%)",
                                          d["Pos_Err_68"])
        ss += "{:<20s} : {:.3f}\n".format("Position Error (95%)",
                                          d["Pos_Err_95"])

        ss += "{:<20s} : {:.0f}\n".format("ROI number", d["ROI_Number"])
        ss += "{:<20s} : {}\n".format("Spatial model", d["Spatial_Model"])
        ss += "{:<20s} : {}\n".format("Spatial components", d["Components"])

        ss += "{:<20s} : {:.1f}\n".format("TS", d["Sqrt_TS"]**2)
        ss += "{:<20s} : {:.1f}\n".format("sqrt(TS)", d["Sqrt_TS"])

        ss += "{:<20s} : {:.3f} +/- {:.3f} (UL: {:.3f}) deg\n".format(
            "Size", d["Size"].value, d["Size_Err"].value, d["Size_UL"].value)

        ss += "{:<20s} : {:.3f}\n".format("R70", d["R70"])
        ss += "{:<20s} : {:.3f}\n".format("RSpec", d["RSpec"])

        ss += "{:<20s} : {:.1f}\n".format("Total model excess",
                                          d["Excess_Model_Total"])
        ss += "{:<20s} : {:.1f}\n".format("Excess in RSpec", d["Excess_RSpec"])
        ss += "{:<20s} : {:.1f}\n".format("Model Excess in RSpec",
                                          d["Excess_RSpec_Model"])
        ss += "{:<20s} : {:.1f}\n".format("Background in RSpec",
                                          d["Background_RSpec"])

        ss += "{:<20s} : {:.1f} hours\n".format("Livetime",
                                                d["Livetime"].value)

        ss += "{:<20s} : {:.2f}\n".format("Energy threshold",
                                          d["Energy_Threshold"])

        val, err = d["Flux_Map"].value, d["Flux_Map_Err"].value
        ss += "{:<20s} : ({:.3f} +/- {:.3f}) x 10^-12 cm^-2 s^-1 = ({:.2f} +/- {:.2f}) % Crab\n".format(
            "Source flux (>1 TeV)",
            val / FF,
            err / FF,
            val * FLUX_TO_CRAB,
            err * FLUX_TO_CRAB,
        )

        ss += "\nFluxes in RSpec (> 1 TeV):\n"

        ss += "{:<30s} : {:.3f} x 10^-12 cm^-2 s^-1 = {:5.2f} % Crab\n".format(
            "Map measurement",
            d["Flux_Map_RSpec_Data"].value / FF,
            d["Flux_Map_RSpec_Data"].value * FLUX_TO_CRAB,
        )

        ss += "{:<30s} : {:.3f} x 10^-12 cm^-2 s^-1 = {:5.2f} % Crab\n".format(
            "Source model",
            d["Flux_Map_RSpec_Source"].value / FF,
            d["Flux_Map_RSpec_Source"].value * FLUX_TO_CRAB,
        )

        ss += "{:<30s} : {:.3f} x 10^-12 cm^-2 s^-1 = {:5.2f} % Crab\n".format(
            "Other component model",
            d["Flux_Map_RSpec_Other"].value / FF,
            d["Flux_Map_RSpec_Other"].value * FLUX_TO_CRAB,
        )

        ss += "{:<30s} : {:.3f} x 10^-12 cm^-2 s^-1 = {:5.2f} % Crab\n".format(
            "Large scale component model",
            d["Flux_Map_RSpec_LS"].value / FF,
            d["Flux_Map_RSpec_LS"].value * FLUX_TO_CRAB,
        )

        ss += "{:<30s} : {:.3f} x 10^-12 cm^-2 s^-1 = {:5.2f} % Crab\n".format(
            "Total model",
            d["Flux_Map_RSpec_Total"].value / FF,
            d["Flux_Map_RSpec_Total"].value * FLUX_TO_CRAB,
        )

        ss += "{:<35s} : {:5.1f} %\n".format("Containment in RSpec",
                                             100 * d["Containment_RSpec"])
        ss += "{:<35s} : {:5.1f} %\n".format("Contamination in RSpec",
                                             100 * d["Contamination_RSpec"])
        label, val = (
            "Flux correction (RSpec -> Total)",
            100 * d["Flux_Correction_RSpec_To_Total"],
        )
        ss += "{:<35s} : {:5.1f} %\n".format(label, val)
        label, val = (
            "Flux correction (Total -> RSpec)",
            100 * (1 / d["Flux_Correction_RSpec_To_Total"]),
        )
        ss += "{:<35s} : {:5.1f} %\n".format(label, val)

        return ss
Exemple #19
0
    def __init__(self,
                 name,
                 ra,
                 dec,
                 exposure_time,
                 exposure_rep,
                 ra_unit='deg',
                 dec_unit='deg'):
        """Create Sources instance.

        Parameters
        -----
        name : list of str
            Source names.
        ra : np.ndarray
            Array of right ascension values.
        dec : np.ndarray
            Array of declination values.
        exposure_time : np.ndarray
            Exposure times for each source in seconds.
        exposure_rep : np.ndarray
            Number of exposure repetitions for each source.
        ra_unit : str, default='deg'
            Unit right ascensions are provided in.
        ra_unit : str, default='deg'
            Unit declinations are provided in.

        Returns
        -----
        None

        Notes
        -----
        Currently only degrees i.e. 'deg' is provided as option. Further
        options may be implemented later.
        """

        if np.unique(name).size < len(name):
            print('WARNING: name dublicates!')
            return False

        self.id = np.arange(len(name))
        self.name = np.asarray(name, dtype='<U30')

        # store right ascension:
        if ra_unit == 'deg':
            ra = Angle(ra * u.deg)
        else:
            raise ValueError("ra_unit needs to be 'deg'.")

        # store declination:
        if dec_unit == 'deg':
            dec = Angle(dec * u.deg)
        else:
            raise ValueError("dec_unit needs to be 'deg'.")

        self.coord = SkyCoord(ra, dec)
        self.exposure_time = exposure_time * u.s
        self.exposure_rep = exposure_rep
        self.active = np.ones(self.coord.size, dtype=bool)
        self.scheduled = np.zeros(self.coord.size, dtype=bool)
        self.observable_now = None
        self.observable_general = None
        self.remaining_time = None
        self.obs_start = None
        self.obs_stop = None
        self.obs_windows = None
        self.size = len(self.name)

        print('{0:s}: Source list created with {1:d} sources.'.format(
            self.class_name, self.size))
Exemple #20
0
def make_theta_squared_table(observations,
                             theta_squared_axis,
                             position,
                             position_off=None):
    """Make theta squared distribution in the same FoV for a list of `Observation`
    objects.

    The ON theta2 profile is computed from a given distribution, on_position.
    By default, the OFF theta2 profile is extracted from a mirror position
    radially symmetric in the FOV to pos_on.

    The ON and OFF regions are assumed to be of the same size, so the normalisation
    factor between both region alpha = 1.

    Parameters
    ----------
    observations: `~gammapy.data.Observations`
        List of observations
    theta_squared_axis : `~gammapy.maps.geom.MapAxis`
        Axis of edges of the theta2 bin used to compute the distribution
    position : `~astropy.coordinates.SkyCoord`
        Position from which the on theta^2 distribution is computed
    position_off : `astropy.coordinates.SkyCoord`
        Position from which the OFF theta^2 distribution is computed.
        Default: reflected position w.r.t. to the pointing position

    Returns
    -------
    table : `~astropy.table.Table`
        Table containing the on counts, the off counts, acceptance, off acceptance and alpha
        for each theta squared bin.
    """
    if not theta_squared_axis.edges.unit.is_equivalent("deg2"):
        raise ValueError("The theta2 axis should be equivalent to deg2")

    table = Table()

    table["theta2_min"] = theta_squared_axis.edges[:-1]
    table["theta2_max"] = theta_squared_axis.edges[1:]
    table["counts"] = 0
    table["counts_off"] = 0
    table["acceptance"] = 0.0
    table["acceptance_off"] = 0.0

    alpha_tot = np.zeros(len(table))
    livetime_tot = 0

    create_off = position_off is None
    for observation in observations:
        separation = position.separation(observation.events.radec)
        counts, _ = np.histogram(separation**2, theta_squared_axis.edges)
        table["counts"] += counts

        if create_off:
            # Estimate the position of the mirror position
            pos_angle = observation.pointing_radec.position_angle(position)
            sep_angle = observation.pointing_radec.separation(position)
            position_off = observation.pointing_radec.directional_offset_by(
                pos_angle + Angle(np.pi, "rad"), sep_angle)

        # Angular distance of the events from the mirror position
        separation_off = position_off.separation(observation.events.radec)

        # Extract the ON and OFF theta2 distribution from the two positions.
        counts_off, _ = np.histogram(separation_off**2,
                                     theta_squared_axis.edges)
        table["counts_off"] += counts_off

        # Normalisation between ON and OFF is one
        acceptance = np.ones(theta_squared_axis.nbin)
        acceptance_off = np.ones(theta_squared_axis.nbin)

        table["acceptance"] += acceptance
        table["acceptance_off"] += acceptance_off
        alpha = acceptance / acceptance_off
        alpha_tot += alpha * observation.observation_live_time_duration.to_value(
            "s")
        livetime_tot += observation.observation_live_time_duration.to_value(
            "s")

    alpha_tot /= livetime_tot
    table["alpha"] = alpha_tot

    stat = WStatCountsStatistic(table["counts"], table["counts_off"],
                                table["alpha"])
    table["excess"] = stat.n_sig
    table["sqrt_ts"] = stat.sqrt_ts
    table["excess_errn"] = stat.compute_errn()
    table["excess_errp"] = stat.compute_errp()

    table.meta["ON_RA"] = position.icrs.ra
    table.meta["ON_DEC"] = position.icrs.dec
    return table
Exemple #21
0
def test_3rd_body_Curtis(test_params):
    # Based on example 12.11 from Howard Curtis
    body = test_params["body"]
    j_date = 2454283.0 * u.day
    tof = (test_params["tof"]).to(u.s).value
    body_r = build_ephem_interpolant(
        body,
        test_params["period"],
        (j_date, j_date + test_params["tof"]),
        rtol=1e-2,
    )

    epoch = Time(j_date, format="jd", scale="tdb")
    initial = Orbit.from_classical(Earth, *test_params["orbit"], epoch=epoch)

    def f(t0, u_, k):
        du_kep = func_twobody(t0, u_, k)
        ax, ay, az = third_body(
            t0,
            u_,
            k,
            k_third=body.k.to(u.km**3 / u.s**2).value,
            perturbation_body=body_r,
        )
        du_ad = np.array([0, 0, 0, ax, ay, az])
        return du_kep + du_ad

    rr, vv = cowell(
        Earth.k,
        initial.r,
        initial.v,
        np.linspace(0, tof, 400) * u.s,
        rtol=1e-10,
        f=f,
    )

    incs, raans, argps = [], [], []
    for ri, vi in zip(rr.to(u.km).value, vv.to(u.km / u.s).value):
        angles = Angle(
            rv2coe(Earth.k.to(u.km**3 / u.s**2).value, ri, vi)[2:5] *
            u.rad)  # inc, raan, argp
        angles = angles.wrap_at(180 * u.deg)
        incs.append(angles[0].value)
        raans.append(angles[1].value)
        argps.append(angles[2].value)

    # Averaging over 5 last values in the way Curtis does
    inc_f, raan_f, argp_f = (
        np.mean(incs[-5:]),
        np.mean(raans[-5:]),
        np.mean(argps[-5:]),
    )

    assert_quantity_allclose(
        [
            (raan_f * u.rad).to(u.deg) - test_params["orbit"][3],
            (inc_f * u.rad).to(u.deg) - test_params["orbit"][2],
            (argp_f * u.rad).to(u.deg) - test_params["orbit"][4],
        ],
        [test_params["raan"], test_params["inc"], test_params["argp"]],
        rtol=1e-1,
    )
Exemple #22
0
def plot_interactive(
    catalog_name="CantatGaudin2020",
    min_parallax=1.5,
    thin=10,
    width=800,
    height=400,
):
    """show altair plots of TOI and clusters

    Parameters
    ----------
    plx_cut : float
        parallax cut in mas; default=2 mas < 100pc
    thin : integer
        thinning factor to use ony every nth cluster member
    """
    try:
        import altair as alt
    except ModuleNotFoundError:
        print("pip install altair")

    if sys.argv[-1].endswith("json"):
        print("import altair; altair.renderers.enable('notebook')")

    cc = ClusterCatalog(verbose=False)
    df0 = cc.query_catalog(catalog_name=catalog_name, return_members=False)
    df2 = cc.query_catalog(catalog_name=catalog_name, return_members=True)
    # add members count from df2 in df0
    # counts = df2.groupby('Cluster').size()
    # counts.name = 'Nstars'
    # counts = counts.reset_index()
    # df0 = pd.merge(df0, counts, how='outer')
    idx = df0.parallax >= min_parallax
    df0 = df0.loc[idx]
    df0["distance"] = Distance(parallax=df0["parallax"].values * u.mas).pc
    # plot catalog
    chart0 = (alt.Chart(df0).mark_point(color="red").encode(
        x=alt.X(
            "ra:Q",
            axis=alt.Axis(title="RA"),
            scale=alt.Scale(domain=[0, 360]),
        ),
        y=alt.Y(
            "dec:Q",
            axis=alt.Axis(title="Dec"),
            scale=alt.Scale(domain=[-90, 90]),
        ),
        tooltip=[
            "Cluster:N",
            "distance:Q",
            "parallax:Q",
            "pmra:Q",
            "pmdec:Q",
            "Nstars:Q",
        ],
    ))

    # get TOI list
    toi = get_tois(verbose=False, clobber=False)
    toi["TIC_ID"] = toi["TIC ID"]
    toi["RA"] = Angle(toi["RA"].values, unit="hourangle").deg
    toi["Dec"] = Angle(toi["Dec"].values, unit="deg").deg
    # plot TOI
    chart1 = (
        alt.Chart(toi, title="TOI").transform_calculate(
            # FIXME: url below doesn't work in pop-up chart
            url="https://exofop.ipac.caltech.edu/tess/target.php?id=" +
            alt.datum.TIC_ID).mark_point(color="black").encode(
                x=alt.X(
                    "RA:Q",
                    axis=alt.Axis(title="RA"),
                    scale=alt.Scale(domain=[0, 360]),
                ),
                y=alt.Y(
                    "Dec:Q",
                    axis=alt.Axis(title="Dec"),
                    scale=alt.Scale(domain=[-90, 90]),
                ),
                tooltip=[
                    "TOI:Q",
                    "TIC ID:Q",
                    "url:N",
                    "Stellar Distance (pc):Q",
                    "PM RA (mas/yr):Q",
                    "PM Dec (mas/yr):Q",
                ],
            ).properties(width=width, height=height).interactive())

    # plot cluster members
    idx = df2.parallax >= min_parallax
    df2 = df2.loc[idx]
    # skip other members
    df2 = df2.iloc[::thin, :]
    chart2 = (alt.Chart(df2).mark_circle().encode(
        x="ra:Q",
        y="dec:Q",
        color="Cluster:N",
        tooltip=[
            "source_id:O",
            "parallax:Q",
            "pmra:Q",
            "pmdec:Q",
            "phot_g_mean_mag:Q",
        ],
    ))

    return chart2 + chart1 + chart0
Exemple #23
0
 def offset(self):
     """Event offset from the array pointing position (`~astropy.coordinates.Angle`)."""
     position = self.radec
     center = self.pointing_radec
     offset = center.separation(position)
     return Angle(offset, unit="deg")
Exemple #24
0
    'scalebar_frame', 'scalebar_linestyle', 'scalebar_linewidth',
    'scalebar_color', 'scalebar_fontsize', 'beam_kwargs', 'ticks_color',
    'frame_color', 'tick_label_fontsize', 'axis_label_fontsize', 'tick_length',
    'grid_label_pos', 'grid_label_color', 'grid_label_fontsize',
    'grid_label_format', 'grid_label_all', 'grid_label_bbox', 'margins',
    'props'
]

###################################################################################################

# settings that are dataset dependend, i.e. need to be changed for a new dataset
# these are just some defaults
tick_label_xformat = 'hh:mm:ss.s'
tick_label_yformat = 'dd:mm:ss'
tick_labelpad = 0
ticks_xspacing = Angle('0 1 0', unit='hourangle')
ticks_yspacing = 10.0 * u.arcsec
ticks_minor_frequency = 5

# fixed settings, i.e. settings that should be the same for each and every plot
# these can still be changed if necessary
colorbar_label_fontsize = 10  # unit: point
colorbar_width = 0.10  # relative to panel height
colorbar_labelpad = 0
scalebar_frame = False
scalebar_linestyle = 'solid'  # or any other plt.plot linestyle
scalebar_linewidth = 2  # unit: point
scalebar_color = 'red'  # any named color or mpl.color instance
scalebar_fontsize = 10.0
beam_kwargs = {
    'loc': 'lower left',
Exemple #25
0
def _angular_radius(sol_radius, distance):
    solar_semidiameter_rad = np.arcsin(sol_radius / distance)
    return Angle(solar_semidiameter_rad.to(u.arcsec))
    def __init__(self):
        super().__init__()

        try:
            urlopen('http://maia.usno.navy.mil/ser7/finals2000A.all')
        except HTTPError as e:
            print("Main IERS link not working, using mirror")
            iers.conf.iers_auto_url = 'http://toshi.nofs.navy.mil/ser7/finals2000A.all'
        except URLError as e:
            print("Main IERS link not working, using mirror")
            iers.conf.iers_auto_url = 'http://toshi.nofs.navy.mil/ser7/finals2000A.all'

        #download_IERS_A()

        plt.style.use(astropy_mpl_style)

        irbeneLocation = EarthLocation(lat=57.5535171694 * u.deg, lon=21.8545525000 * u.deg, height=87.30 * u.m)
        self.irbene = Observer(location=irbeneLocation, name="Irbene", timezone="Europe/Riga")

        observe_time = Time(['2019-02-05 15:30:00'])

        self.targets = []
        self.targetsDict = {}
        with open("config/config.csv", "r") as csvfile:
            next(csvfile)
            reader = csv.reader(csvfile, delimiter=",", quotechar="|")
            for row in reader:
                sourceName = row[0]

                raText = row[1]
                raText = insert(raText, 'h', 2)     #Nolasa targets no faila un ievieto targetsDict un targets
                raText = insert(raText, 'm', 5)
                raText = insert(raText, 's', len(raText))

                decText = row[2]
                if (decText[0] != "-"):
                    decText = insert(decText, 'd', 2)
                    decText = insert(decText, 'm', 5)
                    decText = insert(decText, 's', len(decText))
                else:
                    decText = insert(decText, 'd', 3)
                    decText = insert(decText, 'm', 6)
                    decText = insert(decText, 's', len(decText))

                ra = Angle(raText)
                dec = Angle(decText)

                targetCoord = SkyCoord(frame='icrs', ra=ra, dec=dec, obstime="J2000")
                target = FixedTarget(coord=targetCoord, name=sourceName)
                plannedObs = PlannedObs(target, int(row[4]), int(row[3]), int(row[5]))
                self.targets.append(plannedObs)  # target / obs per_week / priority / scans per obs
                coords = {"ra": ra, "dec": dec}
                self.targetsDict[sourceName] = coords

        self.targets = sorted(self.targets, key=lambda x: x.priority)  # sort targets by priority
        self.calibrators = []
        self.calibratorsDict = {}
        with open("config/calibrators.csv", "r") as csvfile:
            next(csvfile)
            reader = csv.reader(csvfile, delimiter=";", quotechar="|")
            for row in reader:
                sourceName = row[0]

                raText = str(row[1]).replace(" ", "")
                raText = insert(raText, 'h', 2)
                raText = insert(raText, 'm', 5)
                raText = insert(raText, 's', len(raText))

                decText = str(row[2]).replace(" ", "")
                if (decText[0] != "-"):
                    decText = insert(decText, 'd', 3)
                    decText = insert(decText, 'm', 6)
                    decText = insert(decText, 's', len(decText))
                else:
                    decText = insert(decText, 'd', 3)
                    decText = insert(decText, 'm', 6)
                    decText = insert(decText, 's', len(decText))            #Nolasa no faila calibratorus un ievieto calibratorsDict un calibrators

                ra = Angle(raText)
                dec = Angle(decText)

                coords = {"ra": ra, "dec": dec}
                self.calibratorsDict[sourceName] = coords
                calibratorCoord = SkyCoord(frame='icrs', ra=ra, dec=dec, obstime="J2000")
                calibrator = FixedTarget(coord=calibratorCoord, name=sourceName)
                self.calibrators.append(calibrator)

        startArray, endArray, summaryArray = get_all_events()       #No google calendar sanem noverosanas datumus un laikus
        self.dateList = QListWidget()

        tempCheck = True
        for i in range(len(startArray)):
            dayStart = parse(startArray[i])
            dayEnd = parse(endArray[i])
            daySummary = summaryArray[i]
            daySummary = daySummary + " " + str(dayStart.date()) + " " + str(dayStart.time()) + "-" + str(dayEnd.time())
            item = QListWidgetItem(daySummary, self.dateList)
            item.setData(Qt.UserRole, [dayStart, dayEnd])               #Izveido listwidget item no datuma un laika un to ievieto listwidget
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            item.setCheckState(Qt.Unchecked)
            if tempCheck and "maser" in daySummary:
                item.setCheckState(Qt.Checked)
                tempCheck = False
            self.dateList.addItem(item)

        config = configparser.ConfigParser()
        config.read('config/config.ini')
        self.config = config._sections['Default']
        self.config['calibration'] = config['Default'].getboolean('calibration')  #Nolasa config failu


        self.layout = QGridLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0,0,0,0)
        self.setLayout(self.layout)
        self.resize(1000, 600)



        self.dateBoxList = []
        self.targetTimesCount = 0
        self.load_ui()
Exemple #27
0
def exclusion_mask(geom):
    """Example mask for testing."""
    pos = SkyCoord(83.633, 22.014, unit="deg", frame="icrs")
    region = CircleSkyRegion(pos, Angle(0.3, "deg"))
    return geom.region_mask([region], inside=False)
Exemple #28
0
    scc,
    'scd':
    SkyCoord([1, 2], [3, 4], [5, 6],
             unit='deg,deg,m',
             frame='fk4',
             obstime=['J1990.5', 'J1991.5']),
    'x': [1, 2] * u.m,
    'qdb': [10, 20] * u.dB(u.mW),
    'qdex': [4.5, 5.5] * u.dex(u.cm / u.s**2),
    'qmag': [21, 22] * u.ABmag,
    'lat':
    Latitude([1, 2] * u.deg),
    'lon':
    Longitude([1, 2] * u.deg, wrap_angle=180. * u.deg),
    'ang':
    Angle([1, 2] * u.deg),
    'el2':
    el2,
    'sr':
    sr,
    'cr':
    cr,
    'sd':
    sd,
    'srd':
    srd,
}

time_attrs = ['value', 'shape', 'format', 'scale', 'location']
compare_attrs = {
    'c1': ['data'],
Exemple #29
0
def test_apparent_rightascension_J2000(t1):
    # Regression-only test
    assert_quantity_allclose(sun.apparent_rightascension(
        t1, equinox_of_date=False),
                             Angle('13h13m52.37s'),
                             atol=Angle('0h0m0.005s'))
Exemple #30
0
 def offset(self):
     """Event offset (`~astropy.coordinates.Angle`)"""
     position = self.radec
     center = self.pointing_radec
     offset = center.separation(position)
     return Angle(offset, unit='deg')