Astral 3.3

repository·master·Indexed 43 days ago

https://github.com/sffjunkie/astral

A Python library for astronomical calculations, including solar and lunar positions, timings (sunrise, sunset, moonrise, moonset), lunar phases, and Julian Day conversions. It features a geocoder for location lookups and tools for calculating solar elevation, azimuth, and Rahukaalam.

Tokens
10.2K
Snippets
41
Records
51
Agent score
54%

What's inside Astral

  1. Overview of Astral capabilities

    master

    Astral is a Python module designed for astronomical calculations. It provides tools to calculate:

    • Solar positions and times: dawn, sunrise, solar noon, sunset, dusk, solar elevation, solar azimuth, and rahukaalam.
    • Lunar positions and times: moon rise, moon set, azimuth, and zenith.
    • Lunar phases: the current phase of the moon.
  2. Overview of the astral package modules

    master

    The astral package provides tools for astronomical calculations and location-based data. The package is organized into several specialized modules:

    • astral.sun: Functions and classes for calculating solar positions, sunrise, sunset, and solar noon.
    • astral.moon: Functions and classes for calculating lunar positions, moonrise, moonset, and moon phases.
    • astral.geocoder: Tools for resolving geographic information into coordinates.
    • astral.location: Core abstractions for representing geographic locations and timezones.
  3. Atmospheric refraction in sun calculations

    master

    Astral accounts for atmospheric refraction when calculating solar positions, which makes the sun appear higher in the sky than its actual position.

    Specifically, the astral.sun.sunrise and astral.sun.sunset functions use a refraction angle of 32 arcminutes (applied when the sun is half of its apparent diameter below the horizon).

    Note: The refraction calculation does not account for temperature and pressure, which can influence the actual angle of refraction.

  4. Adjust for observer elevation

    master

    Observer elevation affects the calculated times of the sun. Astral handles this via the Observer object.

    1. Horizon Obscuration: If the view is obscured by the horizon and you are at an elevation above ground level, pass a single float representing the elevation to the Observer. This accounts for the extra angle visible due to elevation.
    2. Feature Obscuration: If the view is obscured by a geographical feature (like a mountain), pass a tuple of two floats to the Observer: (vertical_distance_to_top, horizontal_distance_to_feature).
  5. Python version compatibility for Astral

    master

    Astral's support for Python versions has changed over time:

    • Current (v3.2+): Python 3.6 support has been dropped. It is recommended to use a supported version of Python.
    • v2.0 to v3.1: Requires Python 3.6 or greater (due to dataclasses).
    • Legacy: Older versions supported Python 2, but these are no longer maintained.
  6. Migrate to Astral v2.0 or later

    master

    Astral v2.0 introduced significant breaking changes and a code refactor. If you are upgrading from a version prior to 2.0, you must adapt your code to the following changes:

    • Removed Classes: Astral, AstralGeocoder, and GoogleGeocoder classes have been removed.
    • New Data Classes:
      • Use astral.Observer to store latitude, longitude, and elevation.
      • Use astral.LocationInfo to store location name, region, timezone, latitude, and longitude.
    • Geocoder Changes: Geocoder functions now return an astral.LocationInfo instance instead of a astral.location.Location object.
    • Refraction: All calculations now automatically adjust for refraction. To get the true angle, set the with_refraction parameter to False.
    • Renamed Functions:
      • solar_noon is now astral.sun.noon.
      • solar_midnight is now astral.sun.midnight.
    • Python Compatibility: Requires Python 3.6 or greater due to the use of data classes.
  7. How the geocoder database is structured

    master

    The geocoder uses a hierarchical dictionary structure to organize locations by their timezone groups.

    • LocationDatabase: A dictionary where keys are GroupName (sanitized timezone groups like europe or america) and values are GroupInfo objects.
    • GroupInfo: A dictionary mapping LocationName to a list of LocationInfo objects. Using a list allows multiple locations to share the same name but exist in different regions.
    • LocationInfo: The leaf object containing name, region, timezone, latitude, and longitude.

    When performing lookups, the system sanitizes keys by converting them to lowercase and replacing spaces with underscores.

  8. Calculate Sun times with `astral.sun.sun`

    master

    Use astral.sun.sun to calculate various solar events for a specific date and location. The function returns a dictionary containing keys for events like dawn, sunrise, noon, sunset, and dusk.

    By default, results are returned in UTC. To get results in a specific timezone, pass a tzinfo object (such as a zoneinfo.ZoneInfo instance or a timezone string from a LocationInfo object) to the tzinfo parameter.

    import datetime
    from astral import LocationInfo
    from astral.sun import sun
    
    # Define location: name, region, timezone, latitude, longitude
    city = LocationInfo("London", "England", "Europe/London", 51.5, -0.116)
    
    # Calculate sun times for a specific date
    s = sun(city.observer, date=datetime.date(2009, 4, 22))
    print(s['sunrise'])
    
    # To return times in a specific timezone:
    # Option 1: Using LocationInfo's timezone
    s_local = sun(city.observer, date=datetime.date(2009, 4, 22), tzinfo=city.tzinfo)
    
    # Option 2: Using zoneinfo
    import zoneinfo
    tz = zoneinfo.ZoneInfo("Europe/London")
    s_local = sun(city.observer, date=datetime.date(2009, 4, 22), tzinfo=tz)
  9. Lookup and manage locations with the Geocoder

    master

    The astral.geocoder module allows you to look up predefined locations or manage a local database of locations.

    • Lookup: Use lookup(name, database()) to find a LocationInfo object for a city name.
    • Groups: Use group(name, database()) to retrieve a collection of locations belonging to a specific group (e.g., "europe").
    • Adding Locations: Use add_locations(data, database()) to extend the database. data can be a single string (one location per line) or a list containing strings, lists, or tuples (tuples/lists are passed to the LocationInfo constructor).
    from astral.geocoder import lookup, database, add_locations, group
    
    db = database()
    
    # Lookup a city
    location = lookup("London", db)
    
    # Get a group of cities
    europe = group("europe", db)
    
    # Add a new location
    add_locations("Somewhere,Secret Location,UTC,24°28'N,39°36'E", db)
  10. Calculate Moonrise, Moonset, and Moon Phase

    master

    Astral provides tools to calculate lunar events.

    • Moonrise/Moonset: Use astral.moon.moonrise (or similar functions) passing the observer and a date. These return UTC times by default. You can pass a tzinfo to get local times.
    • Moon Phase: Use astral.moon.phase(date) which returns a float between 0 and 27.99.

    Moon Phase Mapping:

    • 0 .. 6.99: New moon
    • 7 .. 13.99: First quarter
    • 14 .. 20.99: Full moon
    • 21 .. 27.99: Last quarter
    import datetime
    from astral import LocationInfo
    from astral.moon import moonrise, phase
    
    city = LocationInfo("London", "England", "Europe/London", 51.5, -0.116)
    dt = datetime.date(2021, 10, 28)
    
    # Moonrise (UTC)
    rise = moonrise(city.observer, dt)
    
    # Moonrise (Local)
    rise_local = moonrise(city.observer, dt, city.tzinfo)
    
    # Moon Phase
    phase_val = phase(datetime.date(2018, 1, 1))
  11. Create custom LocationInfo objects

    master

    If a location is not in the geocoder database, you can manually create a LocationInfo object. You can provide all details during initialization or set them as attributes later.

    Attributes:

    • name: String name of the location.
    • region: String region/state.
    • timezone: Timezone name (e.g., 'US/Central').
    • latitude: Float.
    • longitude: Float.
    from astral import LocationInfo
    
    # Initialization method
    l = LocationInfo('name', 'region', 'timezone/name', 0.1, 1.2)
    
    # Attribute assignment method
    l = LocationInfo()
    l.name = 'name'
    l.region = 'region'
    l.timezone = 'US/Central'
    l.latitude = 0.1
    l.longitude = 1.2