示例#1
0
def _compute_loc_sunset(input_str):
    geolocator = Nominatim(user_agent='sunset_app', timeout=3)
    geoloc = geolocator.geocode(input_str)
    lat, lon = geoloc.latitude, geoloc.longitude

    loc = api.Topos('{0} N'.format(lat), '{0} E'.format(lon))

    t0 = ts.utc(2020, 7, 1)
    t1 = ts.utc(2021, 7, 1)
    t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(e, loc))

    df = pd.DataFrame({'datetime': t.utc_iso(), 'sun_down': y})
    df['datetime'] = pd.to_datetime(df['datetime'])
    tz = GeoNames(username='******').reverse_timezone(
        (geoloc.latitude, geoloc.longitude))
    try:
        df['datetime'] = df['datetime'].dt.tz_localize('utc').dt.tz_convert(
            tz.pytz_timezone)
    except TypeError:
        df['datetime'] = df['datetime'].dt.tz_convert(tz.pytz_timezone)
    df['date'] = df['datetime'].dt.date
    df['time'] = df['datetime'].dt.time
    df['hour'] = (df['time'].astype(str).str.split(
        ':', expand=True).astype(int).apply(
            lambda row: row[0] + row[1] / 60. + row[2] / 3600., axis=1))
    df['hour_24'] = 240
    df['daylight'] = np.abs(df['hour'].diff().shift(-1))
    return df, geoloc
示例#2
0
def get_sun_data(lat, lon, flight_date):
    sky_fmt = "%Y-%m-%dT%H:%M:%SZ"

    ts = api.load.timescale()
    e = api.load('de421.bsp')

    sunrise = None
    sunset = None

    bluffton = api.Topos(lat, lon)
    # first get sunrise and sunset times
    t, y = almanac.find_discrete(
        ts.utc(flight_date.date()),
        ts.utc(flight_date.date() + datetime.timedelta(days=1)),
        almanac.sunrise_sunset(e, bluffton))
    for ti, yi in zip(t, y):
        if yi:
            sunrise = ti.utc_iso()
        else:
            sunset = ti.utc_iso()

    return (datetime.datetime.strptime(
        sunrise, sky_fmt).replace(tzinfo=datetime.timezone.utc) -
            datetime.timedelta(minutes=30),
            datetime.datetime.strptime(
                sunset, sky_fmt).replace(tzinfo=datetime.timezone.utc) +
            datetime.timedelta(minutes=30))
 def _location_sunlit(self, time, location):
     """
     Returns a function that tells you if the sun is shining at a given
     time in a given location.
     """
     func = almanac.sunrise_sunset(self.ephemeris, self.target)
     return func(time)
示例#4
0
def get_sunrise_sunset(latitude, longitude, date, timezone):
    """
    :type timezone: datetime.tzinfo
    :type date: datetime.date
    :type latitude: float
    :type longitude: float
    :return Tuple of datetime (sunrise, sunset), or None instead of a datetime
            if it doesn't occur that day.
    """
    # TODO: 4 AM is used in the documentation, but does it work everywhere?
    #       https://rhodesmill.org/skyfield/almanac.html#sunrise-and-sunset
    t0 = ts.utc(date.year, date.month, date.day, 4)
    t1 = ts.utc(date.year, date.month, date.day + 1, 4)

    location = api.Topos(latitude_degrees=latitude, longitude=longitude)

    # The result t will be an array of times, and y will be True if the sun
    # rises at the corresponding time and False if it sets.
    times, are_sunrise = almanac.find_discrete(
        t0, t1, almanac.sunrise_sunset(e, location))

    sunrise = None
    sunset = None
    for time, is_sunrise in zip(times, are_sunrise):
        if is_sunrise:
            # Not expecting multiple sunrises per day.
            assert sunrise is None
            sunrise = time.astimezone(timezone)
        else:
            # Not expecting multiple sunsets per day.
            assert sunset is None
            sunset = time.astimezone(timezone)

    return sunrise, sunset
 def testSunrise(self):
     timisoaraLoc = api.Topos('45.4758 N', '21.1738 E')
     t0 = ts.utc(2018, 9, 12, 4)
     t1 = ts.utc(2018, 9, 13, 4)
     t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(eph, timisoaraLoc))
     print("****************")
     print(t.utc_iso())
     print(y)
示例#6
0
 def _compute_sun_rise_sun_set(self, start: Time, stop: Time):
     times, rise_set = find_discrete(
         start, stop, sunrise_sunset(self.planets, self.topo))
     for t in times[rise_set]:
         cur_date = t.utc_datetime().date()
         if cur_date not in self.sun_rise_cache.keys():
             self.sun_rise_cache[cur_date] = t
     return times[rise_set], times[~rise_set]
示例#7
0
    def get_sun(self, start_time, end_time) -> dict:
        times, is_risen = find_discrete(
            start_time, end_time,
            almanac.sunrise_sunset(get_skf_objects(), self.position))

        sunrise = times[0] if is_risen[0] else times[1]
        sunset = times[1] if not is_risen[1] else times[0]

        return {'rise': sunrise, 'set': sunset}
def test_sunrise_sunset():
    ts = api.load.timescale()
    t0 = ts.utc(2018, 9, 12, 4)
    t1 = ts.utc(2018, 9, 13, 4)
    e = api.load('de421.bsp')
    bluffton = api.Topos('40.8939 N', '83.8917 W')
    t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(e, bluffton))
    strings = t.utc_strftime('%Y-%m-%d %H:%M')
    assert strings == ['2018-09-12 11:13', '2018-09-12 23:50']
    assert (y == (1, 0)).all()
示例#9
0
 def sunset(self, t, case):
     t = t.utc
     t0 = ts.utc(t[0], t[1], t[2], t[3], t[4], t[5])
     t1 = ts.utc(t[0], t[1], t[2] + case, t[3], t[4], t[5])
     f = almanac.sunrise_sunset(e, self.topo)
     t, y = almanac.find_discrete(t0, t1, f)
     for ti, yi in zip(t, y):
         if(yi == False):
             return ti
         else:
             pass
示例#10
0
def test_sunrise_sunset():
    ts = api.load.timescale()
    t0 = ts.utc(2018, 9, 12, 4)
    t1 = ts.utc(2018, 9, 13, 4)
    e = api.load('de421.bsp')
    bluffton = api.Topos('40.8939 N', '83.8917 W')
    t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(e, bluffton))
    t.tt += half_minute
    strings = t.utc_strftime('%Y-%m-%d %H:%M')
    assert strings == ['2018-09-12 11:13', '2018-09-12 23:50']
    assert (y == (1, 0)).all()
示例#11
0
def rise_set_event_times(start, end):
    """
    Computes sunrise and sunset times between start and end.
    Returns list of EventTime objects.
    """
    t, y = almanac.find_discrete(start, end,
                                 almanac.sunrise_sunset(ephemeris, greenwich))
    return [
        EventTime(Event(rise, 'Sunrise' if rise else 'Sunset'), time)
        for time, rise in zip(t, y)
    ]
示例#12
0
def sunset_and_rise_for_date(data: AstroData, year: int, month: int,
                             day: int) -> Tuple[Time, Time]:
    """
    For a given date find the time of sunset in Babylon
    """
    t0 = data.timescale.ut1(year, month, day, 12)
    t1 = data.timescale.tt_jd(t0.tt + 1)
    times, types = almanac.find_discrete(
        t0, t1, almanac.sunrise_sunset(data.ephemeris, data.babylon_topos))
    assert len(times) == 2
    assert types[0] == 0  # 0 = Sunset
    assert types[1] == 1  # 1 = Sunrise
    return times[0], times[1]
def sunrise_sunset():
    e = api.load('de421.bsp')
    ts = api.load.timescale()
    bluffton = api.Topos('65.02 N', '25.47 E')  # Oulu coordinates
    t0 = ts.utc(2019, 3, 1, 0)
    t1 = ts.utc(2019, 4, 1, 0)
    t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(e, bluffton))

    sunrises = np.array(
        t.utc_iso()[::2])  # gets every element which index is even
    sunsets = np.array(
        t.utc_iso()[1::2])  # gets every element which index is odd
    # sunrises_sunsets = pd.DataFrame({'sunrises':sunrises, 'sunsets':sunsets})
    return sunrises, sunsets
示例#14
0
def find_sunrise(n=1):
    """
    Search the almanac for sunrise and sunset times in the next 24 hours.
    Does not actually compute the times.
    It looks them up in the precomputed ephemeris files provided by the JPL.
    Sunrise times are 'True', Sunset times are 'False'. Times are UTC. 
    """
    ts = api.load.timescale()
    ep = api.load('de421.bsp')
    location = api.Topos('41.85 N', '87.65 W')  # Chicago, USA
    t0 = ts.now()
    t1 = ts.utc(t0.utc_datetime() + timedelta(days=n))
    t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(ep, location))

    times = list(zip(t.utc_iso(), y))
    print(times)
示例#15
0
def _risesetextremes(lat, lon, tzstr, startYear, years, verbose=False):
    ts = api.load.timescale()
    load = api.Loader('/var/data')
    e = load('de430t.bsp')
    # earth = planets['earth']

    tz = timezone(tzstr)

    bluffton = api.Topos(lat, lon)
    t0 = ts.utc(startYear, 1, 1)
    t1 = ts.utc(startYear+years, 1, 1)
    t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(e, bluffton))



    if verbose: print ('done')

    result = dict()

    prevrise = None
    for ti, yi in zip(t, y):
        dt, _ = ti.astimezone_and_leap_second(tz)
        if yi:
            x = 'rise'
        else:
            x = 'set'

        year = str(dt.year)

        if year not in result.keys():
            result[year] = {'rises': [],
                            'rise_hr': [],
                            'sets': [],
                            'set_hr': [],
                            'sunlight': []
                            }
        hrs = dt.hour + dt.minute/60.0 + dt.second/3600.0
        result[year][f"{x}s"].append(dt)
        result[year][f"{x}_hr"].append(hrs)
        if yi:
            prevrise = ti
        else:
            if prevrise is not None:
                result[year]['sunlight'].append((ti - prevrise)*24.0)

    return result
示例#16
0
def sun_time(which_one="sunrise"):
    from skyfield import api, almanac
    import dateutil.tz
    load = api.Loader("~/.skyfield", verbose=False)
    location = config["location"]
    ts = load.timescale()
    e = load('de421.bsp')
    here = api.Topos(location["latitude"], location["longitude"])
    now = datetime.datetime.now()
    today = now.date()
    local = dateutil.tz.gettz()
    midnight = datetime.datetime.combine(today, datetime.time(), local)
    next_midnight = midnight + datetime.timedelta(1)
    begin = ts.utc(midnight)
    end = ts.utc(next_midnight)
    t, _ = almanac.find_discrete(begin, end, almanac.sunrise_sunset(e, here))
    idx = 0 if which_one == "sunrise" else 1
    return t[idx].astimezone(local)
示例#17
0
    def next_set_rise(self, day):
        # By adding 2 days, we can be sure to find today's sunset and the following (tomorrow
        # morning's) sunrise.
        #
        # TODO(MP): Like all other times, the UTC situation here is a bit crappy.  We should really
        # just start searching at noon local time.
        begin = self.ts.utc(day)
        end = self.ts.utc(day + timedelta(days=2))
        times, ups = almanac.find_discrete(
            begin, end, almanac.sunrise_sunset(self.ephemeris, self.topos))
        times = [t.astimezone(self.timezone) for t in times]

        # Find the first sunset
        sunset = next(horizon for horizon in zip(times, ups)
                      if not horizon[1])[0]
        # Find the first sunrise after the first sunset
        sunrise = next(horizon for horizon in zip(times, ups)
                       if horizon[1] and horizon[0] > sunset)[0]
        return (sunset, sunrise)
示例#18
0
def sunrise_sunset(lat, lon):
    place = api.Topos(lat, lon)
    one_day = timedelta(days=1)
    start = datetime.today().astimezone().replace(hour=0,
                                                  minute=0,
                                                  second=0,
                                                  microsecond=0)
    end = start + one_day

    start = ts.utc(start)
    end = ts.utc(end)
    srss, sross = almanac.find_discrete(start, end,
                                        almanac.sunrise_sunset(ephem, place))

    tz = datetime.now().astimezone().tzinfo
    (sr, ss) = srss.astimezone(tz)

    t0_time = sr.strftime('%H%M')
    t0_srss = "SR" if sross[0] else "SS"
    t1_time = ss.strftime('%H%M')
    t1_srss = "SR" if sross[1] else "SS"
    return f"{t0_srss}{t0_time} {t1_srss}{t1_time}"
示例#19
0
文件: tasks.py 项目: nchls/pi-coop
def get_sunrise_sunset_times():
    pownal = api.Topos('43.921554 N', '70.147969 W')
    ts = api.load.timescale(builtin=True)
    eph = api.load_file(settings.SKYFIELD_DATA_PATH)
    now = datetime.now().astimezone()
    today_start = datetime(now.year, now.month, now.day).astimezone()
    today_end = today_start + timedelta(days=1)
    today_start_ts = ts.utc(today_start)
    today_end_ts = ts.utc(today_end)
    traversals, is_sunrise = almanac.find_discrete(
        today_start_ts, today_end_ts, almanac.sunrise_sunset(eph, pownal))
    # If there are multiple sunrises in a day then we have bigger problems than opening the coop door at the right time
    sunrise_iso = traversals[0].utc_iso(
    ) if is_sunrise[0] else traversals[1].utc_iso()
    sunset_iso = traversals[1].utc_iso(
    ) if not is_sunrise[1] else traversals[0].utc_iso()
    sunrise_dtm = datetime.strptime(
        sunrise_iso,
        '%Y-%m-%dT%H:%M:%SZ').replace(tzinfo=timezone.utc).astimezone()
    sunset_dtm = datetime.strptime(
        sunset_iso,
        '%Y-%m-%dT%H:%M:%SZ').replace(tzinfo=timezone.utc).astimezone()
    return (sunrise_dtm, sunset_dtm)
示例#20
0
def is_light():
    """is_light returns True if the sun is up and False otherwise"""
    # load in data directory to avoid redownloading
    loader = Loader('~/skyfield_data')
    ts = loader.timescale()
    e = loader('de421.bsp')

    # set current location (melbourne does not appear in the default list)
    melbourne = api.Topos('37.951910 S', '145.152080 E')
    # get current time in UTC format
    now = datetime.datetime.utcnow()
    now = now.replace(tzinfo=utc)
    # set the interval for now and 24 hours from now
    t0 = ts.utc(now)
    t1 = ts.utc(now + timedelta(hours=24))

    # find the times and types of event (sunrise/sunset)
    t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(e, melbourne))

    #y[0] = True for sunrise (which means it is currently dark)

    light = not y[0]

    return light
示例#21
0
from skyfield.api import load
from skyfield import almanac
# ['New Moon', 'First Quarter', 'Full Moon', 'Last Quarter']
#print('Load bsp file ...')
eph = load('de421.bsp')

ts = load.timescale()
#Sunrise and Sunset
RISE_SET = ['Sunset', 'Sunrise']

from skyfield.api import N, W, wgs84
lat, lon = (48.8796966, 2.5415929)
#print('Bluffton using wgs84 :',lat,lon)
bluffton = wgs84.latlon(lat, lon)
body = 'Sun'

#Sunrise and Sunset
RISE_SET = ['Sunset', 'Sunrise']
day = 26
month = 1
year = 2021
print('\nSunrise and sunset on', day, 'at', lat, lon)

t0 = ts.utc(year, month, day)
t1 = ts.utc(year, month, day + 1)
t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(eph, bluffton))

for ti, yi in zip(t, y):
    print(ti.utc_iso(), RISE_SET[yi])
示例#22
0
 hours = mdates.HourLocator(byhour=range(0, 24, 6), tz=tz_UTC)
 axes_arr[0].xaxis.set_major_locator(days)
 axes_arr[0].xaxis.set_major_formatter(days_fmt)
 axes_arr[0].xaxis.set_minor_locator(hours)
 xmin = time_plottime[0]
 xmax = time_plottime[0] + 2. + args.hours / 24.
 #
 # Compute sunrise, sunset times across x axis with Skyfield.
 # tsun is a sequence of times, corresponding values of rise
 # are True for rising, False for setting.
 #
 tmin = ts.utc(time_datetime[0])
 tmax = ts.utc(time_datetime[0] +
               datetime.timedelta(hours=(48. + args.hours)))
 tsun, rise = almanac.find_discrete(tmin, tmax,
                                    almanac.sunrise_sunset(e, site))
 tsun_datetime = tsun.utc_datetime()
 tsun_plottime = mdates.date2num(tsun_datetime)
 #
 # Plot vspan rectangles from sunset to sunrise, handling axis
 # limits.
 #
 for axes in axes_arr:
     if (rise[0] == True):
         axes.axvspan(xmin,
                      tsun_plottime[0],
                      facecolor=nightcolor,
                      alpha=nightalpha)
         i = 1
     else:
         i = 0
        #     if (y_sun == False):
        #         sunset = t_sun

        conj.append(ti)
        # print(ti.astimezone(jkt))
        # print(ti.astimezone(jkt))
        # print('sunset: ', sunset.astimezone(jkt))
    else:
        pass

for i in conj:
    i_utc = i.utc
    t0 = ts.utc(i_utc[0], i_utc[1], i_utc[2], i_utc[3], i_utc[4], i_utc[5])
    t1 = ts.utc(i_utc[0], i_utc[1], i_utc[2] + 1, i_utc[3], i_utc[4], i_utc[5])
    t_rs, y_rs = almanac.find_discrete(t0, t1,
                                       almanac.sunrise_sunset(e, obsUAD))
    for t_sun, y_sun in zip(t_rs, y_rs):
        if (y_sun == False):
            sunset.append(t_sun)
            # sunset = t_sun
        else:
            pass

for s in sunset:
    s_utc = s.utc
    astro_moon = loc.at(
        ts.utc(s_utc[0], s_utc[1], s_utc[2], s_utc[3], s_utc[4],
               s_utc[5])).observe(moon)
    astro_sun = loc.at(
        ts.utc(s_utc[0], s_utc[1], s_utc[2], s_utc[3], s_utc[4],
               s_utc[5])).observe(e['sun'])
示例#24
0
from skyfield.api import load, Topos
from skyfield import almanac
from datetime import datetime, timedelta
from pytz import timezone

jkt = timezone('Asia/Jakarta')
ts = load.timescale(builtin=True)
e = load('de421.bsp')

lat = 7 + (49 / 60) + (59 / 3600)
long = 110 + (22 / 60) + (49 / 3600)

lat = str(lat) + ' S'
long = str(long) + ' E'

topos = Topos(lat, long)

t0 = ts.utc(2021, 1, 15, -7)
t1 = ts.utc(2021, 1, 20, -7)
f = almanac.sunrise_sunset(e, topos)
t, y = almanac.find_discrete(t0, t1, f)
for ti, yi in zip(t, y):
    print(ti.astimezone(jkt), yi)
示例#25
0
文件: geo_utils.py 项目: cgodine/ACT
def is_sun_visible(latitude=None, longitude=None, date_time=None, dawn_dusk=False):
    """
    Determine if sun is above horizon at for a list of times.

    Parameters
    ----------
    latitude : int, float
        Latitude in degrees north positive. Must be a scalar.
    longitude : int, float
        Longitude in degrees east positive. Must be a scalar.
    date_time : datetime.datetime, numpy.array.datetime64, list of datetime.datetime
        Datetime with timezone, datetime with no timezone in UTC, or numpy.datetime64
        format in UTC. Can be a single datetime object or list of datetime objects.
    dawn_dusk : boolean
        If set to True, will use skyfields dark_twilight_day function to calculate sun up
        Returns a list of int's instead of boolean.
        0 - Dark of Night
        1 - Astronomical Twilight
        2 - Nautical Twilight
        3 - Civil Twilight
        4 - Sun Is Up

    Returns
    -------
    result : list
        List matching size of date_time containing True/False if sun is above horizon.
    """

    sf_dates = None

    # Check if datetime object is scalar and if has no timezone.
    if isinstance(date_time, datetime):
        if date_time.tzinfo is None:
            sf_dates = [date_time.replace(tzinfo=pytz.UTC)]
        else:
            sf_dates = [date_time]

    # Check if datetime objects in list have timezone. If not add.
    if isinstance(date_time, (list, tuple)) and isinstance(date_time[0], datetime):
        if isinstance(date_time[0], datetime) and date_time[0].tzinfo is not None:
            sf_dates = date_time
        else:
            sf_dates = [ii.replace(tzinfo=pytz.UTC) for ii in date_time]

    # Convert datetime64 to datetime with timezone.
    if type(date_time).__module__ == np.__name__ and np.issubdtype(date_time.dtype, np.datetime64):
        sf_dates = datetime64_to_datetime(date_time)
        sf_dates = [ii.replace(tzinfo=pytz.UTC) for ii in sf_dates]

    if sf_dates is None:
        raise ValueError('The date_time values entered into is_sun_visible() '
                         'do not match input types.')

    ts = load.timescale()
    eph = load_file(skyfield_bsp_file)

    t0 = ts.from_datetimes(sf_dates)
    location = wgs84.latlon(latitude, longitude)
    if dawn_dusk:
        f = almanac.dark_twilight_day(eph, location)
    else:
        f = almanac.sunrise_sunset(eph, location)

    sun_up = f(t0)

    eph.close()

    return sun_up
示例#26
0
文件: astro.py 项目: laf518/astronomy
response = requests.get(request_url)
parsed_response = json.loads(response.text)
raw_offset = parsed_response["rawOffset"] / 3600
dst_offset = parsed_response["dstOffset"] / 3600
tot_offset = raw_offset + dst_offset

ts = api.load.timescale(builtin=True)
eph = api.load('de421.bsp')
earth = eph['earth']
obs_city = api.Topos(
    str(abs(lat)) + " " + lat_card,
    str(abs(lon)) + " " + lon_card)

t0 = ts.utc(y, m, day, 12 - tot_offset)  #>UTC Time
t1 = ts.utc(y, m, day + 1, 12 - tot_offset)  #>UTC Time
t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(eph, obs_city))

adjust = (tot_offset * 60) / 24 / 60
sunset_sunrise = ts.tt_jd(t.tt + adjust)
sunset_sunrise = sunset_sunrise.utc_iso()
sunset_raw = sunset_sunrise[0]
sunrise_raw = sunset_sunrise[1]

sunset_hour = int(sunset_raw[11:13] + "00")
sunrise_hour = int(sunrise_raw[11:13] + "00")

## IMPORT INITIAL DATA FILE AND CONVERT TO Multi-Indexed DATAFRAME
# CREDIT: https://stackoverflow.com/questions/53286882/how-to-reindex-a-multiindex-dataframe

df = pd.read_csv("./data/sample_program.csv")
df = df.set_index('Object')
示例#27
0
from datetime import datetime, timedelta

ts = api.load.timescale()

ephemeris = api.load('de421.bsp')

my_position = api.Topos('34.606 S', '58.419 W')

# Only naked-eye visible planets:
planets = 'Mercury Venus Mars Jupiter Saturn'.split()

# Collect all boolean functions in one list:
ras = [
    almanac.risings_and_settings(ephemeris, ephemeris[p + '_barycenter'],
                                 my_position) for p in planets
]

# Append one for checking that the Sun is down:
is_sun_down = lambda t: not almanac.sunrise_sunset(ephemeris, my_position)(t)
ras.append(is_sun_down)

delta = timedelta(hours=1)  # days=0.5)
t = datetime.now(api.utc)

while not all(f(ts.utc(t)) for f in ras):
    t += delta
print(t)

# TODO: allow a minimum elevation
# TODO: take into account Mercury distance from the Sun, to avoid being dazzled by it.
示例#28
0
def sunset_sunrise(time, lat, lon):
    """
    Calculates the local sunrise/sunset of the glider location.

    The function uses the Skyfield package to calculate the sunrise and sunset
    times using the date, latitude and longitude. The times are returned
    rather than day or night indices, as it is more flexible for the quenching
    correction.


    Parameters
    ----------
    time: numpy.ndarray or pandas.Series
        The date & time array in a numpy.datetime64 format.
    lat: numpy.ndarray or pandas.Series
        The latitude of the glider position.
    lon: numpy.ndarray or pandas.Series
        The longitude of the glider position.

    Returns
    -------
    sunrise: numpy.ndarray
        An array of the sunrise times.
    sunset: numpy.ndarray
        An array of the sunset times.

    """

    from pandas import DataFrame
    import datetime
    import numpy as np
    import pandas as pd

    from skyfield import api

    ts = api.load.timescale()
    eph = api.load("de421.bsp")
    from skyfield import almanac

    df = DataFrame.from_dict(dict([("time", time), ("lat", lat),
                                   ("lon", lon)]))

    # set days as index
    df = df.set_index(df.time.values.astype("datetime64[D]"))

    # groupby days and find sunrise for unique days
    # groupby days and find sunrise/sunset for unique days
    grp_avg = df.groupby(df.index).mean()
    date = grp_avg.index.to_pydatetime()
    date = grp_avg.index

    time_utc = ts.utc(date.year, date.month, date.day, date.hour)
    time_utc_offset = ts.utc(
        date.year, date.month, date.day + 1, date.hour
    )  # add one day for each unique day to compute sunrise and sunset pairs

    bluffton = []
    for i in range(len(grp_avg.lat)):
        bluffton.append(api.wgs84.latlon(grp_avg.lat[i], grp_avg.lon[i]))
    bluffton = np.array(bluffton)

    sunrise = []
    sunset = []
    for n in range(len(bluffton)):

        f = almanac.sunrise_sunset(eph, bluffton[n])
        t, y = almanac.find_discrete(time_utc[n], time_utc_offset[n], f)

        if not t:
            if f(time_utc[n]):  # polar day
                sunrise.append(
                    pd.Timestamp(date[n].year, date[n].month, date[n].day, 0,
                                 1).to_datetime64())
                sunset.append(
                    pd.Timestamp(date[n].year, date[n].month, date[n].day, 23,
                                 59).to_datetime64())
            else:  # polar night
                sunrise.append(
                    pd.Timestamp(date[n].year, date[n].month, date[n].day, 11,
                                 59).to_datetime64())
                sunset.append(
                    pd.Timestamp(date[n].year, date[n].month, date[n].day, 12,
                                 1).to_datetime64())

        else:
            sr = t[y == 1]  # y=1 sunrise
            sn = t[y == 0]  # y=0 sunset

            sunup = pd.to_datetime(sr.utc_iso()).tz_localize(None)
            sundown = pd.to_datetime(sn.utc_iso()).tz_localize(None)

            # this doesnt look very efficient at the moment, but I was having issues with getting the datetime64
            # to be compatible with the above code to handle polar day and polar night

            su = pd.Timestamp(
                sunup.year[0],
                sunup.month[0],
                sunup.day[0],
                sunup.hour[0],
                sunup.minute[0],
            ).to_datetime64()

            sd = pd.Timestamp(
                sundown.year[0],
                sundown.month[0],
                sundown.day[0],
                sundown.hour[0],
                sundown.minute[0],
            ).to_datetime64()

            sunrise.append(su)
            sunset.append(sd)

    sunrise = np.array(sunrise).squeeze()
    sunset = np.array(sunset).squeeze()

    grp_avg["sunrise"] = sunrise
    grp_avg["sunset"] = sunset

    # reindex days to original dataframe as night
    df_reidx = grp_avg.reindex(df.index)
    sunrise, sunset = df_reidx[["sunrise", "sunset"]].values.T

    return sunrise, sunset
示例#29
0
文件: geo_utils.py 项目: cgodine/ACT
def get_sunrise_sunset_noon(latitude=None, longitude=None, date=None, library='skyfield',
                            timezone=False):
    """
    Calculate sunrise, sunset and local solar noon times.

    Parameters
    ----------
    latitude : int, float
        Latitude in degrees north positive. Must be a scalar.
    longitude : int, float
        Longitude in degrees east positive. Must be a scalar.
    date : (datetime.datetime, numpy.datetime64, list of datetime.datetime,
            numpy.array of numpy.datetime64, string, list of string)
        Date(s) to return sunrise, sunset and noon times spaning the first date to last
        date if more than one provided. May be a scalar or vector. If entered as a string must follow
        YYYYMMDD format.
    library : str
        Library to use for making calculations. Options include ['skyfield']
    timezone : boolean
        Have timezone with datetime.

    Returns
    -------
    result : tuple of three numpy.array
        Tuple of three values sunrise, sunset, noon. Values will be a list.
        If no values can be calculated will return empty list. If the date is within
        polar night will return empty lists. If spans the transition to polar day
        will return previous sunrise or next sunset outside of date range provided.
    """

    sunrise, sunset, noon = np.array([]), np.array([]), np.array([])

    if library == 'skyfield':
        ts = load.timescale()
        eph = load_file(skyfield_bsp_file)
        sf_dates = []

        # Parse datetime object
        if isinstance(date, datetime):
            if date.tzinfo is None:
                sf_dates = [date.replace(tzinfo=pytz.UTC)]
            else:
                sf_dates = [date]

        if isinstance(date, (list, tuple)) and isinstance(date[0], datetime):
            if date[0].tzinfo is not None:
                sf_dates = date
            else:
                sf_dates = [ii.replace(tzinfo=pytz.UTC) for ii in date]

        # Parse string date
        if isinstance(date, str):
            sf_dates = [datetime.strptime(date, '%Y%m%d').replace(tzinfo=pytz.UTC)]

        # Parse list of string dates
        if isinstance(date, (list, tuple)) and isinstance(date[0], str):
            sf_dates = [datetime.strptime(dt, '%Y%m%d').replace(tzinfo=pytz.UTC) for dt in date]

        # Convert datetime64 to datetime
        if type(date).__module__ == np.__name__ and np.issubdtype(date.dtype, np.datetime64):
            sf_dates = datetime64_to_datetime(date)
            sf_dates = [ii.replace(tzinfo=pytz.UTC) for ii in sf_dates]

        # Function for calculating solar noon
        # Convert location into skyfield location object
        location = wgs84.latlon(latitude, longitude)
        # Set up function to indicate calculating locatin of Sun from Earth
        f = almanac.meridian_transits(eph, eph['Sun'], location)
        # Set up dates to be start of day and end of day so have a range
        t0 = sf_dates[0]
        t0 = t0.replace(hour=0, minute=0, second=0)
        t1 = sf_dates[-1]
        t1 = t1.replace(hour=23, minute=59, second=59)
        # Convert times from datetime to skyfild times
        t0 = ts.from_datetime(t0)
        t1 = ts.from_datetime(t1)
        # Calculate Meridian Transits. n contains times and x contains 1 and 0's
        # indicating when transit time is above or below location.
        n, x = almanac.find_discrete(t0, t1, f)

        # Determine if time is during daylight
        f = almanac.sunrise_sunset(eph, location)
        sun_up = f(n)

        # Filter out times when sun is below location or in polar night
        n = n[(x == 1) & sun_up]
        noon = n.utc_datetime()
        if noon.size == 0:
            return sunrise, sunset, noon

        # Calcuate sunrise and sunset times. Calcuate over range 12 less than minimum
        # noon time and 12 hours greater than maximum noon time.
        t0 = min(noon) - timedelta(hours=12)
        t1 = max(noon) + timedelta(hours=12)
        t0 = ts.from_datetime(t0)
        t1 = ts.from_datetime(t1)
        f = almanac.sunrise_sunset(eph, location)
        t, y = almanac.find_discrete(t0, t1, f)
        times = t.utc_datetime()
        sunrise = times[y == 1]
        sunset = times[y == 0]

        # Fill in sunrise and sunset if asked to during polar day
        if len(noon) > 0 and (y.size == 0 or len(sunrise) != len(sunset)):
            t0 = min(noon) - timedelta(days=90)
            t1 = max(noon) + timedelta(days=90)
            t0 = ts.from_datetime(t0)
            t1 = ts.from_datetime(t1)
            t, yy = almanac.find_discrete(t0, t1, f)
            times = t.utc_datetime()
            # If first time is sunset and/or last time is sunrise filter
            # from times
            if yy[0] == 0:
                yy = yy[1:]
                times = times[1:]
            if yy[-1] == 1:
                yy = yy[:-1]
                times = times[:-1]

            # Extract sunrise times
            temp_sunrise = times[yy == 1]
            # Extract sunset times
            temp_sunset = times[yy == 0]
            # Look for index closest to first noon time to get the time of last sunrise
            # since we are in polar day.
            diff = temp_sunrise - min(noon)
            sunrise_index = np.max(np.where(diff < timedelta(seconds=1)))
            # Look for index closest to last noon time to get the time of first sunset
            # since we are in polar day.
            diff = max(noon) - temp_sunset
            sunset_index = np.min(np.where(diff < timedelta(seconds=1))) + 1
            sunrise = temp_sunrise[sunrise_index: sunset_index]
            sunset = temp_sunset[sunrise_index: sunset_index]

        eph.close()

    if timezone is False:
        for ii in range(0, sunset.size):
            sunrise[ii] = sunrise[ii].replace(tzinfo=None)
            sunset[ii] = sunset[ii].replace(tzinfo=None)
        for ii in range(0, noon.size):
            noon[ii] = noon[ii].replace(tzinfo=None)

    return sunrise, sunset, noon
def _sunsuperlatives(lat, lng, timezone_name, year):
    eph = load('de430t.bsp')
    if year is None:
        year=utcnow.year
    result = {}
    observer = api.Topos(lat,lng)
    localtz = timezone(timezone_name)

    t0 = ts.utc(year) # midnight Jan 1
    t1 = ts.utc(year+1)  # midnight Jan 1 following year
    try:
        t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(eph, observer))
    except Exception as e:
        pprint(observer)
        raise ValueError(f"error calculating sunrise_sunset for {observer}: {e}")

    # build list of 365 rises, sets and day length
    days=[]
    risedt=None
    for ti, yi in zip(t, y):
        dt = ti.utc_datetime()
        ldt = dt.astimezone(localtz)
        key = ldt.strftime("%H:%M:%S")
        if yi:
            risedt=dt
        else:
            if risedt is not None:
            #store the datetime of sunrise, sunset, time the Sun is above the horizon, and how close that is to 12 hours
            #avoid pandas conversion datetime64 and its timezone complexities with iso format
                days.append({'risedt': risedt.isoformat(), 'riset': risedt.astimezone(localtz).time(),
                             'setdt': dt.isoformat(), 'sett': dt.astimezone(localtz).time(),
                             'deltadt': dt.isoformat(), 'deltat': dt-risedt, # time the Sun is above the horizon
                             'deltafrom12hrsdt': dt.isoformat(), 'deltafrom12hrst': abs(pd.Timedelta('12 hours')-(dt-risedt))})

    df = pd.DataFrame(days)
    for k in ['rise', 'set', 'delta']:
        # convert ISO8601 datetime string to datetime in specified timezone
        mintimeiso = df[df[f'{k}t'] == df[f'{k}t'].min()][f'{k}dt'].values[0]
        maxtimeiso = df[df[f'{k}t'] == df[f'{k}t'].max()][f'{k}dt'].values[0]
        result[k] = {'min': isodate.parse_datetime(mintimeiso).astimezone(localtz),
                     'max': isodate.parse_datetime(maxtimeiso).astimezone(localtz)}
        if k in ['delta']:
            # convert pandas.timedelta back to datetime.timedelta retaining microsecond resolution
            mindelta = df[df[f'{k}t'] == df[f'{k}t'].min()][f'{k}t'].values[0] / np.timedelta64(1, 's')
            maxdelta = df[df[f'{k}t'] == df[f'{k}t'].max()][f'{k}t'].values[0] / np.timedelta64(1, 's')
            result[k]['value'] = {'min': datetime.timedelta(seconds=float(mindelta)),
                                  'max': datetime.timedelta(seconds=float(maxdelta))}
    result['equilux'] = {}
    # There are 2 days with close to 12 hours of daylight, around the equinoxes
    for i, equaluxdata in df.nsmallest(2, 'deltafrom12hrst').reset_index().iterrows():
        daylightlength=equaluxdata['deltat'] / np.timedelta64(1, 's')
        record = {'dt': isodate.parse_datetime(equaluxdata['deltafrom12hrsdt']).astimezone(localtz),
                  'value': datetime.timedelta(seconds=float(daylightlength))}
        if record['dt'].strftime('%m')=='03':
            result['equilux']['Vernal'] = record
        elif record['dt'].strftime('%m') == '09':
            result['equilux']['Autumnal'] = record
        else:
            raise ValueError(f'calculated equalux {record["dt"]} outside of March or September')

    eph.close()
    return result
示例#31
0
def get_dday_sunset_sunrise(sunrise_degree_def=-0.8333):
    t0 = ts.utc(1944, 6, 5, 12)  # start looking for sunset at noon Jun 5
    t1 = ts.utc(1944, 6, 6, 12)  # stop looking for sunrise at noon Jun 6
    t, y = almanac.find_discrete(t0, t1, almanac.sunrise_sunset(e, normandy))
    # t, y = almanac.find_discrete(t0, t1, sunrise_sunset(e, normandy, sunrise_degree_def=sunrise_degree_def))
    return t[:2]
def is_it_night(data, subset, ts, e):
    #determines whether it is nighttime at a particular location and time

    #format latitude and longitude
    night_time = []
    day_time = []

    for n in range(0, len(data['LATITUDE'][subset])):
        if n % 1000 == 0:
            print('File #', n)
    #format latitude and longitude
        if data['LATITUDE'][subset][n] < 0:
            lat = '%1.2f S' % data['LATITUDE'][subset][n]
        else:
            lat = '%1.2f N' % data['LATITUDE'][subset][n]

        if data['LONGITUDE'][subset][n] < 0:
            lon = '%1.2f W' % data['LONGITUDE'][subset][n]
        else:
            lon = '%1.2f E' % data['LONGITUDE'][subset][n]

        location = api.Topos(lat, lon)

        #format time
        year = pd.to_datetime(data['JULD'].values[subset])[n].year
        month = pd.to_datetime(data['JULD'].values[subset])[n].month
        day = pd.to_datetime(data['JULD'].values[subset])[n].day
        hour = pd.to_datetime(data['JULD'].values[subset])[n].hour
        minute = pd.to_datetime(data['JULD'].values[subset])[n].minute

        #define window for searching for either a sunset or sunrise
        t0, t1 = ts.utc(year, month, day, [hour - 12, hour + 12])
        #define UTC time of profile
        t2 = ts.utc(year, month, day, hour, minute)

        #t=array of times; y = 0 for sun set, 1 for sun rise: look for a sunset
        #or sunrise within the window provided
        t, y = almanac.find_discrete(t0, t1,
                                     almanac.sunrise_sunset(e, location))
        #print(t.utc_iso())
        # print(y)

        count_polar_night = 0
        count_polar_day = 0
        #first figure out if sunrise/sunset is irrelevant (i.e. poles at certain
        #times of year, then determine day/night)
        if len(t) <= 1:
            f = almanac.sunrise_sunset(e, location)
            t, y = almanac.find_discrete(t0, t1, f)
            if f(t2) == True:
                day_time.append(n)
                count_polar_day += 1
            else:
                night_time.append(n)
                count_polar_night += 1

        #if sunrise/sunset exists, figure out whether the profile occurred
        #before or sunset (sunrise). This depends on whether the t array is
        #ordered [0,1] or [1,0] and whether t2 (the actual profile time) is
        #before or after a 0 or 1.
        else:
            if t.utc_iso()[0] < t2.utc_iso() < t.utc_iso()[1] and y[0] == 1:
                day_time.append(n)
            elif t.utc_iso()[0] < t2.utc_iso() < t.utc_iso()[1] and y[0] == 0:
                night_time.append(n)
            elif t2.utc_iso() > t.utc_iso()[1] and y[0] == 0:
                day_time.append(n)
            elif t2.utc_iso() > t.utc_iso()[1] and y[0] == 1:
                night_time.append(n)
            elif t2.utc_iso() < t.utc_iso()[0] and y[0] == 1:
                night_time.append(n)
            else:
                day_time.append(n)

    #can ask the program to provide how many profiles occurred during polar
    #day or night
# print(count_polar_day,count_polar_night)
#returns lists of indices corresponding to night time and day time for the
#original array
    return night_time, day_time