cryogenic22 commited on
Commit
4f2b7a8
·
verified ·
1 Parent(s): fab8679

Create astro_core.py

Browse files
Files changed (1) hide show
  1. astro_core.py +162 -0
astro_core.py ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # astro_core.py
2
+ """
3
+ Unified astrology calculation module supporting both Western and Vedic systems.
4
+ """
5
+
6
+ from datetime import datetime
7
+ from typing import Dict, Any, Literal
8
+ import pytz
9
+ from dataclasses import dataclass
10
+
11
+ # Western astrology imports
12
+ import flatlib
13
+ from flatlib.datetime import Datetime
14
+ from flatlib.geopos import GeoPos
15
+ from flatlib.chart import Chart
16
+
17
+ # Vedic astrology imports
18
+ import jyotish
19
+ from jyotish.core import Chart as VedicChart
20
+
21
+ @dataclass
22
+ class BirthInfo:
23
+ """Birth information container"""
24
+ datetime: datetime
25
+ latitude: float
26
+ longitude: float
27
+ timezone: str
28
+ system: Literal['western', 'vedic'] = 'western'
29
+
30
+ class ChartCalculator:
31
+ """Unified chart calculator for Western and Vedic astrology"""
32
+
33
+ def __init__(self):
34
+ self.western_planets = [
35
+ 'Sun', 'Moon', 'Mercury', 'Venus', 'Mars',
36
+ 'Jupiter', 'Saturn', 'Uranus', 'Neptune', 'Pluto'
37
+ ]
38
+ self.vedic_planets = [
39
+ 'Sun', 'Moon', 'Mercury', 'Venus', 'Mars',
40
+ 'Jupiter', 'Saturn', 'Rahu', 'Ketu'
41
+ ]
42
+
43
+ def calculate_chart(self, birth_info: BirthInfo) -> Dict[str, Any]:
44
+ """Calculate birth chart based on specified system"""
45
+ if birth_info.system == 'western':
46
+ return self._calculate_western_chart(birth_info)
47
+ else:
48
+ return self._calculate_vedic_chart(birth_info)
49
+
50
+ def _calculate_western_chart(self, birth_info: BirthInfo) -> Dict[str, Any]:
51
+ """Calculate Western birth chart"""
52
+ date = Datetime(birth_info.datetime, birth_info.timezone)
53
+ pos = GeoPos(birth_info.latitude, birth_info.longitude)
54
+
55
+ chart = Chart(date, pos)
56
+
57
+ positions = {}
58
+ for planet in self.western_planets:
59
+ obj = chart.get(planet)
60
+ positions[planet] = {
61
+ 'sign': obj.sign,
62
+ 'degrees': obj.lon,
63
+ 'house': obj.house,
64
+ 'retrograde': obj.speed < 0
65
+ }
66
+
67
+ houses = {}
68
+ for i in range(1, 13):
69
+ house = chart.houses.get(i)
70
+ houses[f'House_{i}'] = {
71
+ 'sign': house.sign,
72
+ 'degrees': house.lon
73
+ }
74
+
75
+ return {
76
+ 'system': 'western',
77
+ 'planets': positions,
78
+ 'houses': houses,
79
+ 'aspects': self._calculate_western_aspects(chart)
80
+ }
81
+
82
+ def _calculate_vedic_chart(self, birth_info: BirthInfo) -> Dict[str, Any]:
83
+ """Calculate Vedic birth chart"""
84
+ # Create Vedic chart using jyotish
85
+ chart = VedicChart(
86
+ datetime=birth_info.datetime,
87
+ latitude=birth_info.latitude,
88
+ longitude=birth_info.longitude,
89
+ timezone=birth_info.timezone
90
+ )
91
+
92
+ positions = {}
93
+ for planet in self.vedic_planets:
94
+ graha = chart.get_graha(planet)
95
+ positions[planet] = {
96
+ 'rashi': graha.rashi, # Vedic sign
97
+ 'degrees': graha.longitude,
98
+ 'nakshatra': graha.nakshatra,
99
+ 'pada': graha.pada,
100
+ 'house': graha.house
101
+ }
102
+
103
+ houses = {}
104
+ for i in range(1, 13):
105
+ bhava = chart.get_bhava(i)
106
+ houses[f'House_{i}'] = {
107
+ 'rashi': bhava.rashi,
108
+ 'degrees': bhava.longitude
109
+ }
110
+
111
+ # Calculate Vedic specific details
112
+ dasha = chart.get_dasha() # Current dasha period
113
+
114
+ return {
115
+ 'system': 'vedic',
116
+ 'planets': positions,
117
+ 'houses': houses,
118
+ 'dasha': dasha,
119
+ 'nakshatras': self._calculate_nakshatras(chart)
120
+ }
121
+
122
+ def _calculate_western_aspects(self, chart: Chart) -> Dict[str, list]:
123
+ """Calculate major aspects between planets in Western astrology"""
124
+ aspects = {}
125
+ major_aspects = {
126
+ 0: 'Conjunction',
127
+ 60: 'Sextile',
128
+ 90: 'Square',
129
+ 120: 'Trine',
130
+ 180: 'Opposition'
131
+ }
132
+
133
+ for p1 in self.western_planets:
134
+ aspects[p1] = []
135
+ planet1 = chart.get(p1)
136
+
137
+ for p2 in self.western_planets:
138
+ if p1 != p2:
139
+ planet2 = chart.get(p2)
140
+ angle = abs(planet1.lon - planet2.lon) % 360
141
+
142
+ for degrees, aspect_type in major_aspects.items():
143
+ if abs(angle - degrees) <= 8: # 8 degree orb
144
+ aspects[p1].append({
145
+ 'planet': p2,
146
+ 'type': aspect_type,
147
+ 'orb': abs(angle - degrees)
148
+ })
149
+
150
+ return aspects
151
+
152
+ def _calculate_nakshatras(self, chart: VedicChart) -> Dict[str, Any]:
153
+ """Calculate Nakshatra positions for Vedic chart"""
154
+ nakshatra_data = {}
155
+ for planet in self.vedic_planets:
156
+ graha = chart.get_graha(planet)
157
+ nakshatra_data[planet] = {
158
+ 'nakshatra': graha.nakshatra,
159
+ 'pada': graha.pada,
160
+ 'lord': graha.nakshatra_lord
161
+ }
162
+ return nakshatra_data