Skip to content

Combustion API Reference

combustion

Provides functions to determine if a planet is in combustion.

CombustFunction

Callable combustion function for Skyfield's find_discrete.

Source code in ndastro_engine/combustion.py
class CombustFunction:
    """Callable combustion function for Skyfield's find_discrete."""

    step_days = 1.0  # Step size in days for Skyfield's find_discrete

    def __init__(self, planet_name: str, latitude: float, longitude: float, orb: float) -> None:
        """Initialize a new instance of the combustion function.

        Args:
            planet_name: The name of the planet to check (Skyfield code).
            latitude: The latitude of the observation location.
            longitude: The longitude of the observation location.
            orb: Combustion orb in degrees.

        """
        self.planet_name = planet_name
        self.latitude = latitude
        self.longitude = longitude
        self.orb = orb

    def __call__(self, t: Time) -> bool:
        """Return True if the planet is combust at the given time."""
        observer = (earth + Topos(latitude=self.latitude, longitude=self.longitude)).at(t)

        astrometric_planet = cast("Barycentric", observer).observe(eph[self.planet_name]).apparent()
        astrometric_sun = cast("Barycentric", observer).observe(eph[Planets.SUN.astronomical_code]).apparent()

        separation = astrometric_planet.separation_from(astrometric_sun).degrees
        # Return the comparison result directly (handles both scalar and array cases)
        return cast("float", separation) <= self.orb

__call__(t)

Return True if the planet is combust at the given time.

Source code in ndastro_engine/combustion.py
def __call__(self, t: Time) -> bool:
    """Return True if the planet is combust at the given time."""
    observer = (earth + Topos(latitude=self.latitude, longitude=self.longitude)).at(t)

    astrometric_planet = cast("Barycentric", observer).observe(eph[self.planet_name]).apparent()
    astrometric_sun = cast("Barycentric", observer).observe(eph[Planets.SUN.astronomical_code]).apparent()

    separation = astrometric_planet.separation_from(astrometric_sun).degrees
    # Return the comparison result directly (handles both scalar and array cases)
    return cast("float", separation) <= self.orb

__init__(planet_name, latitude, longitude, orb)

Initialize a new instance of the combustion function.

Parameters:

Name Type Description Default
planet_name str

The name of the planet to check (Skyfield code).

required
latitude float

The latitude of the observation location.

required
longitude float

The longitude of the observation location.

required
orb float

Combustion orb in degrees.

required
Source code in ndastro_engine/combustion.py
def __init__(self, planet_name: str, latitude: float, longitude: float, orb: float) -> None:
    """Initialize a new instance of the combustion function.

    Args:
        planet_name: The name of the planet to check (Skyfield code).
        latitude: The latitude of the observation location.
        longitude: The longitude of the observation location.
        orb: Combustion orb in degrees.

    """
    self.planet_name = planet_name
    self.latitude = latitude
    self.longitude = longitude
    self.orb = orb

find_combust_periods(start_date, end_date, planet_name, latitude, longitude)

Calculate combustion periods for a planet within a specified date range.

Parameters:

Name Type Description Default
start_date datetime

The start date of the period to check.

required
end_date datetime

The end date of the period to check.

required
planet_name str

The name of the planet to check (Skyfield code).

required
latitude float

The latitude of the observation location.

required
longitude float

The longitude of the observation location.

required

Returns:

Type Description
list[tuple[datetime, datetime]]

List of (start, end) datetimes representing combustion periods.

Source code in ndastro_engine/combustion.py
def find_combust_periods(
    start_date: datetime,
    end_date: datetime,
    planet_name: str,
    latitude: float,
    longitude: float,
) -> list[tuple[datetime, datetime]]:
    """Calculate combustion periods for a planet within a specified date range.

    Args:
        start_date: The start date of the period to check.
        end_date: The end date of the period to check.
        planet_name: The name of the planet to check (Skyfield code).
        latitude: The latitude of the observation location.
        longitude: The longitude of the observation location.

    Returns:
        List of (start, end) datetimes representing combustion periods.

    """
    if planet_name in [
        Planets.SUN.astronomical_code,
        Planets.ASCENDANT.astronomical_code,
        Planets.EMPTY.astronomical_code,
        Planets.RAHU.astronomical_code,
        Planets.KETHU.astronomical_code,
    ]:
        return []

    orb = ORB_BY_PLANET.get(planet_name)
    if orb is None:
        return []

    t0 = ts.utc(start_date)
    t1 = ts.utc(end_date)

    times, values = find_discrete(
        t0,
        t1,
        _get_combust_function(planet_name, latitude, longitude, orb),
    )

    combust_periods: list[tuple[datetime, datetime]] = []
    in_combust = False
    combust_start = None

    for t, combust in zip(times, values, strict=False):
        if combust:
            if not in_combust:
                combust_start = cast("Time", t).utc_datetime()
                in_combust = True
        elif in_combust:
            combust_periods.append((cast("datetime", combust_start), t.utc_datetime()))
            in_combust = False

    if in_combust and combust_start is not None:
        combust_periods.append((cast("datetime", combust_start), cast("datetime", t1.utc_datetime())))

    return combust_periods

is_planet_in_combust(check_date, planet_name, latitude, longitude)

Check if a planet is combust on a specific date.

Parameters:

Name Type Description Default
check_date datetime

The date to check for combustion.

required
planet_name str

The name of the planet to check (Skyfield code).

required
latitude float

The latitude of the observation location.

required
longitude float

The longitude of the observation location.

required

Returns:

Type Description
bool

A tuple containing a boolean indicating if the planet is combust,

datetime | None

the start datetime of the combustion period, and the end datetime of the combustion period.

datetime | None

If the planet is not combust, the start and end datetimes will be None.

Source code in ndastro_engine/combustion.py
def is_planet_in_combust(
    check_date: datetime,
    planet_name: str,
    latitude: float,
    longitude: float,
) -> tuple[bool, datetime | None, datetime | None]:
    """Check if a planet is combust on a specific date.

    Args:
        check_date: The date to check for combustion.
        planet_name: The name of the planet to check (Skyfield code).
        latitude: The latitude of the observation location.
        longitude: The longitude of the observation location.

    Returns:
        A tuple containing a boolean indicating if the planet is combust,
        the start datetime of the combustion period, and the end datetime of the combustion period.
        If the planet is not combust, the start and end datetimes will be None.

    """
    if planet_name in [
        Planets.SUN.astronomical_code,
        Planets.ASCENDANT.astronomical_code,
        Planets.EMPTY.astronomical_code,
        Planets.RAHU.astronomical_code,
        Planets.KETHU.astronomical_code,
    ]:
        return (False, None, None)

    start_date = check_date - timedelta(days=DAYS_IN_YEAR)
    end_date = check_date + timedelta(days=DAYS_IN_YEAR)
    combust_periods = find_combust_periods(
        start_date,
        end_date,
        planet_name,
        latitude,
        longitude,
    )

    for period_start, period_end in combust_periods:
        if period_start <= check_date <= period_end:
            return (True, period_start, period_end)

    return (False, None, None)