Enhance Jyotish validation and Jaimini modules
- add external validation reports and open-source comparison references - integrate Jaimini arudha/graha pada, enhanced argala, and additional synastry kutas - update skill docs and capability matrices - add smoke tests for open-source integrations
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
import math
|
||||
from .constants import TITHI_NAMES, VARA_NAMES, VARA_LORDS, PANCHANG_YOGA_NAMES, KARANA_NAMES
|
||||
from .nakshatra import get_nakshatra
|
||||
|
||||
|
||||
def calculate_panchang(jd, sun_lon, moon_lon, lat=None, lon=None):
|
||||
"""
|
||||
Calculate the five Panchang elements for a given moment.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
jd : float
|
||||
Julian Day number
|
||||
sun_lon : float
|
||||
Sidereal longitude of the Sun (0-360)
|
||||
moon_lon : float
|
||||
Sidereal longitude of the Moon (0-360)
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict with tithi, vara, nakshatra, yoga, karana
|
||||
"""
|
||||
# --- Tithi ---
|
||||
diff = (moon_lon - sun_lon) % 360.0
|
||||
tithi_num = int(diff / 12.0) # 0-29
|
||||
paksha = "Shukla" if tithi_num < 15 else "Krishna"
|
||||
tithi_name = TITHI_NAMES[tithi_num]
|
||||
|
||||
# --- Vara (weekday) ---
|
||||
# Julian Day 0 = Monday in many conventions; swe.julday for J2000 epoch
|
||||
# JD 2451545.0 (2000-01-01 12:00 UT) was a Saturday
|
||||
# weekday = (JD + 1.5) % 7 => 0=Mon, 1=Tue, ... 6=Sun (Julian convention)
|
||||
day_idx = int(math.floor(jd + 0.5)) % 7
|
||||
|
||||
# Correct for local sunrise if lat/lon provided
|
||||
if lat is not None and lon is not None:
|
||||
try:
|
||||
import swisseph as swe
|
||||
swe.set_topo(lon, lat, 0)
|
||||
# Find the sunrise for the current civil day UT
|
||||
jd_midnight = math.floor(jd - 0.5) + 0.5
|
||||
res, tret = swe.rise_trans(jd_midnight, swe.SUN, "", swe.CALC_RISE, (lon, lat, 0.0))
|
||||
sunrise_jd = tret[0]
|
||||
# If born before today's sunrise, the Vedic day is yesterday
|
||||
if jd < sunrise_jd:
|
||||
day_idx = (day_idx - 1) % 7
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# JD 0 = Monday (Julian proleptic). Map: 0=Mon,1=Tue,...6=Sun
|
||||
vara = VARA_NAMES[day_idx]
|
||||
vara_lord = VARA_LORDS[day_idx]
|
||||
|
||||
# --- Nakshatra (Moon's) ---
|
||||
nak = get_nakshatra(moon_lon)
|
||||
|
||||
# --- Yoga (Panchang Yoga) ---
|
||||
yoga_val = (sun_lon + moon_lon) % 360.0
|
||||
yoga_idx = int(yoga_val / (360.0 / 27.0))
|
||||
if yoga_idx >= 27:
|
||||
yoga_idx = 26
|
||||
yoga_name = PANCHANG_YOGA_NAMES[yoga_idx]
|
||||
|
||||
# --- Karana ---
|
||||
# Each tithi has 2 karanas (half-tithi = 6 degrees of Sun-Moon distance)
|
||||
karana_num = int(diff / 6.0) # 0-59
|
||||
if karana_num == 0:
|
||||
karana_name = KARANA_NAMES[10] # Kimstughna (first half of Shukla Pratipada)
|
||||
elif karana_num >= 57:
|
||||
# Last 3 are fixed karanas: Shakuni(57), Chatushpada(58), Nagava(59)
|
||||
fixed_idx = karana_num - 57 + 7 # maps to indices 7,8,9
|
||||
karana_name = KARANA_NAMES[fixed_idx]
|
||||
else:
|
||||
# Repeating cycle of first 7 karanas (Bava through Vishti)
|
||||
karana_name = KARANA_NAMES[(karana_num - 1) % 7]
|
||||
|
||||
return {
|
||||
"tithi": {
|
||||
"number": tithi_num + 1,
|
||||
"name": tithi_name,
|
||||
"paksha": paksha,
|
||||
},
|
||||
"vara": {
|
||||
"name": vara,
|
||||
"lord": vara_lord,
|
||||
},
|
||||
"nakshatra": {
|
||||
"name": nak["name"],
|
||||
"pada": nak["pada"],
|
||||
"lord": nak["lord"],
|
||||
},
|
||||
"yoga": {
|
||||
"index": yoga_idx,
|
||||
"name": yoga_name,
|
||||
},
|
||||
"karana": karana_name,
|
||||
}
|
||||
Reference in New Issue
Block a user