コード例 #1
0
def _convert_radec_to_altaz(ra, dec, lon, lat, height, time):
    """Convert a single position.

    This is done for easy code sharing with other tools.
    Skyfield does support arrays of positions.
    """
    load = Loader('.')
    # Skyfield uses FTP URLs, but FTP doesn't work on Github Actions so
    # we use alternative HTTP URLs.
    load.urls['finals2000A.all'] = 'https://datacenter.iers.org/data/9/'
    load.urls['.bsp'] = [
        ('*.bsp',
         'https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/')
    ]

    radec = Star(ra=Angle(degrees=ra), dec=Angle(degrees=dec))

    earth = load(EPHEMERIS)['earth']
    location = earth + wgs84.latlon(longitude_degrees=lon,
                                    latitude_degrees=lat,
                                    elevation_m=height * 1000.0)

    ts = load.timescale(builtin=False)
    with load.open('finals2000A.all') as f:
        finals_data = iers.parse_x_y_dut1_from_finals_all(f)
    iers.install_polar_motion_table(ts, finals_data)
    obstime = ts.from_astropy(Time(time, scale='utc'))

    alt, az, _ = location.at(obstime).observe(radec).apparent().altaz(
        pressure_mbar=0)

    return dict(az=az.degrees, alt=alt.degrees)
コード例 #2
0
def init_sf(spad):
    global ts, eph, earth, moon, sun, venus, mars, jupiter, saturn, df
    load = Loader(spad)  # spad = folder to store the downloaded files
    EOPdf = "finals2000A.all"  # Earth Orientation Parameters data file
    dfIERS = spad + EOPdf

    if config.useIERS:
        if compareVersion(VERSION, "1.31") >= 0:
            if path.isfile(dfIERS):
                if load.days_old(EOPdf) > float(config.ageIERS):
                    load.download(EOPdf)
                ts = load.timescale(builtin=False)  # timescale object
            else:
                load.download(EOPdf)
                ts = load.timescale(builtin=False)  # timescale object
        else:
            ts = load.timescale()  # timescale object with built-in UT1-tables
    else:
        ts = load.timescale()  # timescale object with built-in UT1-tables

    if config.ephndx in set([0, 1, 2, 3, 4]):

        eph = load(config.ephemeris[config.ephndx][0])  # load chosen ephemeris
        earth = eph['earth']
        moon = eph['moon']
        sun = eph['sun']
        venus = eph['venus']
        jupiter = eph['jupiter barycenter']
        saturn = eph['saturn barycenter']
        if config.ephndx >= 3:
            mars = eph['mars barycenter']
        else:
            mars = eph['mars']

    # load the Hipparcos catalog as a 118,218 row Pandas dataframe.
    with load.open(hipparcos.URL) as f:
        #hipparcos_epoch = ts.tt(1991.25)
        df = hipparcos.load_dataframe(f)

    return ts
コード例 #3
0
ファイル: data.py プロジェクト: yonatanzunger/orrery
class Data(object):
    """This class is the central holder for astronomical data; it acts as a wrapper around all of
    the datasets we get from JPL, the Minor Planets Center, etc., and exposes them via nice,
    Skyfield-friendly APIs.
    """
    def __init__(self,
                 dirname: str = "data",
                 ephemerides: str = "de441") -> None:
        self.load = Loader(dirname)
        self._ephName = ephemerides
        if not self._ephName.endswith(".bsp"):
            self._ephName += ".bsp"

    # CelestialObjects representing the most common things we might want to use.

    @cached_property
    def sun(self) -> CelestialObject:
        return makeObject(
            ObjectType.STAR,
            "The Sun",
            self._ephemerides["sun"],
            symbol="\u2609",
        )

    @cached_property
    def moon(self) -> CelestialObject:
        return makeObject(ObjectType.MOON,
                          "The Moon",
                          self._ephemerides["moon"],
                          symbol="\u263D")

    @cached_property
    def mercury(self) -> CelestialObject:
        return makeObject(ObjectType.PLANET,
                          "Mercury",
                          self._ephemerides["mercury"],
                          symbol="\u263f")

    @cached_property
    def venus(self) -> CelestialObject:
        return makeObject(ObjectType.PLANET,
                          "Venus",
                          self._ephemerides["venus"],
                          symbol="\u2640")

    @cached_property
    def earth(self) -> CelestialObject:
        return makeObject(ObjectType.PLANET,
                          "Earth",
                          self._ephemerides["earth"],
                          symbol="\u2641")

    @cached_property
    def mars(self) -> CelestialObject:
        return makeObject(
            ObjectType.PLANET,
            "Mars",
            self._ephemerides["mars barycenter"],
            symbol="\u2642",
        )

    @cached_property
    def jupiter(self) -> CelestialObject:
        return makeObject(
            ObjectType.PLANET,
            "Jupiter",
            self._ephemerides["jupiter barycenter"],
            symbol="\u2643",
        )

    @cached_property
    def saturn(self) -> CelestialObject:
        return makeObject(
            ObjectType.PLANET,
            "Saturn",
            self._ephemerides["saturn barycenter"],
            symbol="\u2644",
        )

    @cached_property
    def uranus(self) -> CelestialObject:
        return makeObject(
            ObjectType.PLANET,
            "Uranus",
            self._ephemerides["uranus barycenter"],
            symbol="\u2645",
        )

    @cached_property
    def neptune(self) -> CelestialObject:
        return makeObject(
            ObjectType.PLANET,
            "Neptune",
            self._ephemerides["neptune barycenter"],
            symbol="\u2646",
        )

    # Our favorite dwarf planets

    @cached_property
    def pluto(self) -> CelestialObject:
        # Still in the JPL planet ephemerides!
        return makeObject(
            ObjectType.MINOR_PLANET,
            "Pluto",
            self._ephemerides["pluto barycenter"],
            symbol="\u2647",
        )

    @cached_property
    def ceres(self) -> CelestialObject:
        return self.minorPlanet("(1) Ceres", symbol="\u26b3")

    @cached_property
    def chiron(self) -> CelestialObject:
        return self.minorPlanet("(2060) Chiron", symbol="\u26b7")

    @cached_property
    def eris(self) -> CelestialObject:
        return self.minorPlanet("(136199) Eris", symbol="\u2bf0")

    @cached_property
    def makemake(self) -> CelestialObject:
        # Not yet in Unicode!
        return self.minorPlanet("(136472) Makemake")

    @cached_property
    def haumea(self) -> CelestialObject:
        # Not yet in Unicode!
        return self.minorPlanet("(136108) Haumea")

    @cached_property
    def sedna(self) -> CelestialObject:
        return self.minorPlanet("(90377) Sedna", symbol="\u2bf2")

    # Orcus, Quaoar,Pallas, Juno, Vesta, Astraea, Hebe, Iris, Flora, Metis, Hygiea, Parthenope,
    # Victoria, Egeria, Irene, Eunomia, Psyche, Thetis, Melpomene, Fortuna, Proserpina, Bellona,
    # Amphitrite, Leukothea, Fides?

    # How about some stars?
    @cached_property
    def sirius(self) -> CelestialObject:
        return self.star("Sirius", "western")

    @cached_property
    def arcturus(self) -> CelestialObject:
        return self.star("Arcturus", "western")

    # Observation points

    # Helpers for getting positions
    def observer(
        self,
        lat: float,
        lon: float,
        elevationMeters: Optional[float] = None,
    ) -> VectorFunction:
        """Return a VectorFunction representing a terrestrial observer."""
        return self.earth.position + wgs84.latlon(
            lat, lon, elevation_m=elevationMeters or 0)

    @cached_property
    def berkeley(self) -> VectorFunction:
        return self.observer(37.8645 * N, 122.3015 * W, 52.1)

    def asTime(self, when: datetime) -> Time:
        return self.timescale.from_datetime(when)

    def observe(
        self,
        observer: VectorFunction,
        target: CelestialObject,
        when: Optional[datetime] = None,
    ) -> Observation:
        """Give the astrometric (relative) position of target relative to observer at time.

        If the time is not given, assume "now."
        """
        time = self.timescale.from_datetime(
            when) if when else self.timescale.now()
        position = observer.at(time).observe(target.position)
        return Observation(
            target=target,
            position=position,
            magnitude=target.magnitude(position),
            subpoint=self.subpoint(target, time),
        )

    # More general accessors to load up other celestial bodies in our databases.

    def comet(self, designation: str) -> CelestialObject:
        """Look up a comet by its designation, e.g. 1P/Halley"""
        # NB: mpc.comet_orbit returns an orbit centered on the Sun, so we need to offset it!
        row = self._comets.loc[designation]
        return makeObject(
            type=ObjectType.COMET,
            name=designation[designation.find("/") + 1:],
            position=self.sun.position +
            mpc.comet_orbit(row, self.timescale, GM_SUN),
            dataFrame=row,
        )

    def minorPlanet(self,
                    designation: str,
                    symbol: Optional[str] = None) -> CelestialObject:
        """Look up a minor planet by its designation, e.g. (2060) Chiron"""
        data = self._minorPlanets.loc[designation]
        shortName = designation[designation.find(") ") + 2:]
        return makeObject(
            type=ObjectType.MINOR_PLANET,
            name=shortName,
            position=self.sun.position +
            mpc.mpcorb_orbit(data, self.timescale, GM_SUN),
            dataFrame=data,
            symbol=symbol,
        )

    def star(self,
             ref: Union[str, int],
             culture: Optional[str] = None) -> CelestialObject:
        """Fetch a star by its name or Hipparcos catalogue number.

        Args:
            ref: Either the string common name, or the int catalogue number, e.g. 87937 for
                Barnard's Star.
            culture: If given, use as a hint to understand the common name.
        """
        number = ref if isinstance(ref, int) else self.starNumber(ref)
        data = self._stars.loc[number]
        names = self._starNames.allNames(number)
        primaryName = (ref if isinstance(ref, str) else names["western"]
                       if "western" in names else names["hip"])
        star = Star.from_dataframe(data)
        return makeObject(
            type=ObjectType.STAR,
            name=primaryName,
            position=star,
            dataFrame=data,
            names=names,
        )

    def cultures(self) -> Tuple[str, ...]:
        return self._starNames.cultures()

    def starNumber(self, name: str, culture: Optional[str] = None) -> int:
        return self._starNames.find(name, culture=culture)

    @property
    def timescale(self) -> Timescale:
        return self.load.timescale()

    def subpoint(self, target: CelestialObject,
                 time: Time) -> GeographicPosition:
        return wgs84.subpoint(
            self.earth.position.at(time).observe(target.position))

    #########################################################################################
    # Much more internal accessors

    @cached_property
    def _comets(self) -> DataFrame:
        with self.load.open(mpc.COMET_URL) as f:
            return (
                mpc.load_comets_dataframe(f).sort_values("reference").groupby(
                    "designation",
                    as_index=False).last().set_index("designation",
                                                     drop=False))

    @cached_property
    def _ephemerides(self) -> SpiceKernel:
        return self.load(self._ephName)

    @cached_property
    def _minorPlanets(self) -> DataFrame:
        with self.load.open(self._minorPlanetsPath()) as f:
            logging.info("Loading minor planets dataset")
            mp = mpc.load_mpcorb_dataframe(f)
            # Drop items without orbits
            badOrbits = mp.semimajor_axis_au.isnull()
            mp = mp[~badOrbits].set_index("designation", drop=False)
            return mp

    @cached_property
    def _stars(self) -> DataFrame:
        logging.info("Loading Hipparcos data")
        with self.load.open(hipparcos.URL) as f:
            df = hipparcos.load_dataframe(f)
            # Filter out the ones with no reliable position
            df = df[df["ra_degrees"].notnull()]
            return df

    @cached_property
    def _starNames(self) -> StarNames:
        return StarNames(self.load)

    # Logic for downloading data

    _MPC_ORB = "minor_planets.dat"
    _MPC_URL = "https://www.minorplanetcenter.net/iau/MPCORB/MPCORB.DAT.gz"

    def _minorPlanetsPath(self,
                          ensure: bool = True,
                          refresh: bool = False) -> str:
        """Return a path to the file containing minor planets data.

        If ensure is True, ensures that the file exists.
        If refresh is True, force a re-download.
        """
        filename = self.load.path_to(self._MPC_ORB)
        if not ensure or (not refresh and os.path.exists(filename)):
            return self._MPC_ORB

        # Do we need to refetch the compressed data?
        compressed = self._MPC_ORB + ".gz"
        if not os.path.exists(compressed):
            logging.info(f"Downloading minor planet data from {self._MPC_URL}")
            compressed = self.load.download(self._MPC_URL,
                                            filename=self._MPC_ORB + ".gz")

        # Regenerate the "clean" data. Why do they stick an unformatted header in this file?
        # I really don't know.
        logging.info("Cleaning and parsing minor planets data")
        with gzip.open(compressed, mode="rt",
                       encoding="ascii") as input, open(filename,
                                                        "w") as output:
            sawHeader = False
            count = 0
            for line in input:
                if not line:
                    continue
                if not sawHeader:
                    sawHeader = line.startswith("-----")
                else:
                    count += 1
                    output.write(line)

        logging.info(f"Loaded {count} minor planets")

        # Now nuke the compressed file.
        os.remove(compressed)

        return self._MPC_ORB
コード例 #4
0
ファイル: neowise_visibilty.py プロジェクト: rtphokie/neowise
from skyfield.constants import GM_SUN_Pitjeva_2005_km3_s2 as GM_SUN
import pandas as pd
import os
import numpy as np
from pytz import timezone
import datetime
import simple_cache
import time
import redis
import pickle

load = Loader('/var/data')
eph = load('de421.bsp')
ts = load.timescale(builtin=True)
sun, earth = eph['sun'], eph['earth']
with load.open(mpc.COMET_URL) as f:
    comets = mpc.load_comets_dataframe(f)
comets = comets.set_index('designation', drop=False)
UTC = timezone('UTC')
# LONGTTL=86400*30
# SHORTTTL=86400
LONGTTL = 86400 / 2
SHORTTTL = 86400 / 12
rconn = redis.StrictRedis(host='134.209.169.157',
                          password="******")


def degrees_to_cardinal(d):
    dirs = [
        'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW',
        'WSW', 'W', 'WNW', 'NW', 'NNW'