House Systems
House systems divide the celestial sphere into twelve segments, called houses, starting from the Ascendant (the eastern horizon at the moment of birth). Each system uses a different mathematical projection to do this division, which is why the same chart can look markedly different depending on which system you choose. Ketu ships six systems and lets you register additional ones.
Supported Systems
The six built-in systems are exposed in the SYSTEMS dict:
Key |
Name |
Description |
|---|---|---|
|
Placidus |
Time-based; most common in modern western practice |
|
Koch |
Birthplace system; similar to Placidus at mid-latitudes |
|
Porphyry |
Divides quadrants into thirds; works at high latitudes |
|
Whole Sign |
Each house = one full sign; oldest recorded system |
|
Equal |
Houses of 30° each, starting from the Ascendant |
|
Regiomontanus |
Space-based; common in horary astrology |
from ketu.houses import SYSTEMS
print(list(SYSTEMS.keys()))
# ['placidus', 'koch', 'porphyry', 'whole_sign', 'equal', 'regiomontanus']
calculate_houses
calculate_houses(jd, lat, lon, system="placidus", polar_fallback="raise")
Computes the twelve house cusps and the angles (Ascendant, Midheaven, ARMC, Vertex) for a given moment and location. Returns a NumPy structured array of HOUSES_DTYPE.
Parameters
jd— Julian Day (float, UTC)lat— geographic latitude in degrees (+N / -S)lon— geographic longitude in degrees (+E / -W)system— one of the six keys above (default"placidus")polar_fallback— behaviour above the Arctic/Antarctic circles (see below)
Example — Paris chart at J2000
from ketu.houses import calculate_houses, house_of, SYSTEMS, HOUSES_DTYPE, HighLatitudeError
jd = 2451545.0 # J2000: 2000-01-01 12:00 UTC
lat = 48.8566 # Paris latitude
lon = 2.3522 # Paris longitude
h = calculate_houses(jd, lat, lon, system="placidus")
print(h["asc"]) # Ascendant longitude (degrees)
print(h["mc"]) # Midheaven longitude (degrees)
print(h["cusps"]) # Array of 12 cusp longitudes
Switching systems
for system in SYSTEMS:
h = calculate_houses(jd, lat, lon, system=system)
print(f"{system:16s} ASC={h['asc']:.2f} MC={h['mc']:.2f}")
house_of
house_of(planet_lon, cusps)
Places one or more planet longitudes into a house number (1–12), vectorised over an array of longitudes.
from ketu.houses import calculate_houses, house_of
jd = 2451545.0
h = calculate_houses(jd, 48.8566, 2.3522)
cusps = h["cusps"]
# Single planet
sun_lon = 280.5
print(house_of(sun_lon, cusps)) # e.g. 10
# Multiple planets at once
import numpy as np
planet_lons = np.array([280.5, 45.3, 123.7, 198.2])
houses = house_of(planet_lons, cusps)
print(houses) # array of house numbers 1–12
HOUSES_DTYPE
The structured array returned by calculate_houses has the following fields:
Field |
Type |
Description |
|---|---|---|
|
float64 |
Julian Day of the calculation |
|
float64 |
Geographic latitude |
|
float64 |
Geographic longitude |
|
U20 |
House system name |
|
float64[12] |
Twelve house cusp longitudes (degrees) |
|
float64 |
Ascendant longitude (degrees) |
|
float64 |
Midheaven longitude (degrees) |
|
float64 |
ARMC (sidereal time angle) |
|
float64 |
Vertex longitude (degrees) |
High-Latitude Handling
Projection-based systems (Placidus, Koch) break down at extreme latitudes (roughly above 66° N or below 66° S) because the ecliptic can fail to intersect the prime vertical.
polar_fallback="raise" (default) — raises HighLatitudeError when the calculation is geometrically impossible.
Alternative fallback — pass the name of another system to use as a fallback:
from ketu.houses import calculate_houses, HighLatitudeError
# Attempt Placidus; fall back to Porphyry at high latitudes
try:
h = calculate_houses(jd, 70.0, 25.0, system="placidus", polar_fallback="porphyry")
except HighLatitudeError:
# polar_fallback="raise" and the location is beyond the polar circle
pass
Whole Sign and Equal never raise HighLatitudeError — they work everywhere.
Registering Custom Systems
from ketu.houses import register
@register("my_system")
def my_system_calculator(jd, lat, lon):
# Returns (cusps_array[12], asc, mc, armc, vertex)
...
After registration, "my_system" is available as a system= argument to calculate_houses.
Next Steps
Relational charts — synastry and composite charts using house cusps
API reference — full
ketu.housessignature list