kerykeion 4.12.3__py3-none-any.whl → 4.18.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of kerykeion might be problematic. Click here for more details.
- kerykeion/__init__.py +3 -1
- kerykeion/aspects/aspects_utils.py +40 -123
- kerykeion/aspects/natal_aspects.py +34 -25
- kerykeion/aspects/synastry_aspects.py +34 -28
- kerykeion/astrological_subject.py +199 -196
- kerykeion/charts/charts_utils.py +701 -62
- kerykeion/charts/draw_planets.py +407 -0
- kerykeion/charts/kerykeion_chart_svg.py +534 -1140
- kerykeion/charts/templates/aspect_grid_only.xml +452 -0
- kerykeion/charts/templates/chart.xml +88 -70
- kerykeion/charts/templates/wheel_only.xml +499 -0
- kerykeion/charts/themes/classic.css +82 -0
- kerykeion/charts/themes/dark-high-contrast.css +121 -0
- kerykeion/charts/themes/dark.css +121 -0
- kerykeion/charts/themes/light.css +117 -0
- kerykeion/enums.py +1 -0
- kerykeion/ephemeris_data.py +178 -0
- kerykeion/fetch_geonames.py +2 -3
- kerykeion/kr_types/chart_types.py +6 -16
- kerykeion/kr_types/kr_literals.py +12 -3
- kerykeion/kr_types/kr_models.py +77 -32
- kerykeion/kr_types/settings_models.py +4 -10
- kerykeion/relationship_score/__init__.py +2 -0
- kerykeion/relationship_score/relationship_score.py +175 -0
- kerykeion/relationship_score/relationship_score_factory.py +275 -0
- kerykeion/report.py +6 -3
- kerykeion/settings/kerykeion_settings.py +6 -1
- kerykeion/settings/kr.config.json +256 -102
- kerykeion/utilities.py +122 -217
- {kerykeion-4.12.3.dist-info → kerykeion-4.18.0.dist-info}/METADATA +40 -10
- kerykeion-4.18.0.dist-info/RECORD +42 -0
- kerykeion/relationship_score.py +0 -205
- kerykeion-4.12.3.dist-info/RECORD +0 -32
- {kerykeion-4.12.3.dist-info → kerykeion-4.18.0.dist-info}/LICENSE +0 -0
- {kerykeion-4.12.3.dist-info → kerykeion-4.18.0.dist-info}/WHEEL +0 -0
- {kerykeion-4.12.3.dist-info → kerykeion-4.18.0.dist-info}/entry_points.txt +0 -0
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import pytz
|
|
7
7
|
import swisseph as swe
|
|
8
8
|
import logging
|
|
9
|
+
import warnings
|
|
9
10
|
|
|
10
11
|
from datetime import datetime
|
|
11
12
|
from functools import cached_property
|
|
@@ -19,11 +20,13 @@ from kerykeion.kr_types import (
|
|
|
19
20
|
PointType,
|
|
20
21
|
SiderealMode,
|
|
21
22
|
HousesSystemIdentifier,
|
|
22
|
-
PerspectiveType
|
|
23
|
+
PerspectiveType,
|
|
24
|
+
Planet,
|
|
25
|
+
Houses
|
|
23
26
|
)
|
|
24
27
|
from kerykeion.utilities import (
|
|
25
28
|
get_number_from_name,
|
|
26
|
-
|
|
29
|
+
get_kerykeion_point_from_degree,
|
|
27
30
|
get_planet_house,
|
|
28
31
|
get_moon_emoji_from_phase_int,
|
|
29
32
|
get_moon_phase_name_from_phase_int,
|
|
@@ -33,10 +36,10 @@ from pathlib import Path
|
|
|
33
36
|
from typing import Union, get_args
|
|
34
37
|
|
|
35
38
|
DEFAULT_GEONAMES_USERNAME = "century.boy"
|
|
36
|
-
DEFAULT_SIDEREAL_MODE = "FAGAN_BRADLEY"
|
|
37
|
-
DEFAULT_HOUSES_SYSTEM_IDENTIFIER = "P"
|
|
38
|
-
DEFAULT_ZODIAC_TYPE = "Tropic"
|
|
39
|
-
DEFAULT_PERSPECTIVE_TYPE = "Apparent Geocentric"
|
|
39
|
+
DEFAULT_SIDEREAL_MODE: SiderealMode = "FAGAN_BRADLEY"
|
|
40
|
+
DEFAULT_HOUSES_SYSTEM_IDENTIFIER: HousesSystemIdentifier = "P"
|
|
41
|
+
DEFAULT_ZODIAC_TYPE: ZodiacType = "Tropic"
|
|
42
|
+
DEFAULT_PERSPECTIVE_TYPE: PerspectiveType = "Apparent Geocentric"
|
|
40
43
|
GEONAMES_DEFAULT_USERNAME_WARNING = (
|
|
41
44
|
"\n********\n"
|
|
42
45
|
"NO GEONAMES USERNAME SET!\n"
|
|
@@ -75,8 +78,7 @@ class AstrologicalSubject:
|
|
|
75
78
|
You can get one for free here: https://www.geonames.org/login
|
|
76
79
|
- online (bool, optional): Sets if you want to use the online mode, which fetches the timezone and coordinates from geonames.
|
|
77
80
|
If you already have the coordinates and timezone, set this to False. Defaults to True.
|
|
78
|
-
- disable_chiron
|
|
79
|
-
Chiron calculation can create some issues with the Swiss Ephemeris when the date is too far in the past.
|
|
81
|
+
- disable_chiron: Deprecated, use disable_chiron_and_lilith instead.
|
|
80
82
|
- sidereal_mode (SiderealMode, optional): Also known as Ayanamsa.
|
|
81
83
|
The mode to use for the sidereal zodiac, according to the Swiss Ephemeris.
|
|
82
84
|
Defaults to "FAGAN_BRADLEY".
|
|
@@ -87,6 +89,11 @@ class AstrologicalSubject:
|
|
|
87
89
|
- perspective_type (PerspectiveType, optional): The perspective to use for the calculation of the chart.
|
|
88
90
|
Defaults to "Apparent Geocentric".
|
|
89
91
|
Available perspectives are visible in the PerspectiveType Literal.
|
|
92
|
+
- is_dst (Union[None, bool], optional): Specify if the time is in DST. Defaults to None.
|
|
93
|
+
By default (None), the library will try to guess if the time is in DST or not and raise an AmbiguousTimeError
|
|
94
|
+
if it can't guess. If you know the time is in DST, set this to True, if you know it's not, set it to False.
|
|
95
|
+
- disable_chiron_and_lilith (bool, optional): boolean representing if Chiron and Lilith should be disabled. Default is False.
|
|
96
|
+
Chiron calculation can create some issues with the Swiss Ephemeris when the date is too far in the past.
|
|
90
97
|
"""
|
|
91
98
|
|
|
92
99
|
# Defined by the user
|
|
@@ -104,10 +111,11 @@ class AstrologicalSubject:
|
|
|
104
111
|
geonames_username: str
|
|
105
112
|
online: bool
|
|
106
113
|
zodiac_type: ZodiacType
|
|
107
|
-
sidereal_mode: SiderealMode
|
|
114
|
+
sidereal_mode: Union[SiderealMode, None]
|
|
108
115
|
houses_system_identifier: HousesSystemIdentifier
|
|
109
116
|
houses_system_name: str
|
|
110
117
|
perspective_type: PerspectiveType
|
|
118
|
+
is_dst: Union[None, bool]
|
|
111
119
|
|
|
112
120
|
# Generated internally
|
|
113
121
|
city_data: dict[str, str]
|
|
@@ -130,6 +138,7 @@ class AstrologicalSubject:
|
|
|
130
138
|
true_node: KerykeionPointModel
|
|
131
139
|
mean_node: KerykeionPointModel
|
|
132
140
|
chiron: Union[KerykeionPointModel, None]
|
|
141
|
+
mean_lilith: Union[KerykeionPointModel, None]
|
|
133
142
|
|
|
134
143
|
# Houses
|
|
135
144
|
first_house: KerykeionPointModel
|
|
@@ -146,10 +155,15 @@ class AstrologicalSubject:
|
|
|
146
155
|
twelfth_house: KerykeionPointModel
|
|
147
156
|
|
|
148
157
|
# Lists
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
158
|
+
_houses_list: list[KerykeionPointModel]
|
|
159
|
+
_houses_degree_ut: list[float]
|
|
160
|
+
|
|
161
|
+
# Enable or disable features
|
|
162
|
+
disable_chiron: Union[None, bool]
|
|
163
|
+
disable_chiron_and_lilith: bool
|
|
164
|
+
|
|
165
|
+
planets_names_list: list[Planet]
|
|
166
|
+
houses_names_list: list[Houses]
|
|
153
167
|
|
|
154
168
|
def __init__(
|
|
155
169
|
self,
|
|
@@ -167,63 +181,89 @@ class AstrologicalSubject:
|
|
|
167
181
|
geonames_username: Union[str, None] = None,
|
|
168
182
|
zodiac_type: ZodiacType = DEFAULT_ZODIAC_TYPE,
|
|
169
183
|
online: bool = True,
|
|
170
|
-
disable_chiron: bool =
|
|
184
|
+
disable_chiron: Union[None, bool] = None, # Deprecated
|
|
171
185
|
sidereal_mode: Union[SiderealMode, None] = None,
|
|
172
186
|
houses_system_identifier: HousesSystemIdentifier = DEFAULT_HOUSES_SYSTEM_IDENTIFIER,
|
|
173
|
-
perspective_type: PerspectiveType = DEFAULT_PERSPECTIVE_TYPE
|
|
187
|
+
perspective_type: PerspectiveType = DEFAULT_PERSPECTIVE_TYPE,
|
|
188
|
+
is_dst: Union[None, bool] = None,
|
|
189
|
+
disable_chiron_and_lilith: bool = False
|
|
174
190
|
) -> None:
|
|
175
191
|
logging.debug("Starting Kerykeion")
|
|
176
192
|
|
|
193
|
+
# Deprecation warnings --->
|
|
194
|
+
if disable_chiron is not None:
|
|
195
|
+
warnings.warn(
|
|
196
|
+
"The 'disable_chiron' argument is deprecated and will be removed in a future version. "
|
|
197
|
+
"Please use 'disable_chiron' instead.",
|
|
198
|
+
DeprecationWarning
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
if disable_chiron_and_lilith:
|
|
202
|
+
raise ValueError("Cannot specify both 'disable_chiron' and 'disable_chiron_and_lilith'. Use 'disable_chiron_and_lilith' only.")
|
|
203
|
+
|
|
204
|
+
self.disable_chiron_and_lilith = disable_chiron
|
|
205
|
+
# <--- Deprecation warnings
|
|
206
|
+
|
|
177
207
|
self.name = name
|
|
178
208
|
self.year = year
|
|
179
209
|
self.month = month
|
|
180
210
|
self.day = day
|
|
181
211
|
self.hour = hour
|
|
182
212
|
self.minute = minute
|
|
183
|
-
self.city = city
|
|
184
|
-
self.nation = nation
|
|
185
|
-
self.lng = lng
|
|
186
|
-
self.lat = lat
|
|
187
|
-
self.tz_str = tz_str
|
|
188
213
|
self.zodiac_type = zodiac_type
|
|
189
214
|
self.online = online
|
|
190
215
|
self.json_dir = Path.home()
|
|
191
|
-
self.geonames_username = geonames_username
|
|
192
216
|
self.disable_chiron = disable_chiron
|
|
193
217
|
self.sidereal_mode = sidereal_mode
|
|
194
218
|
self.houses_system_identifier = houses_system_identifier
|
|
195
219
|
self.perspective_type = perspective_type
|
|
220
|
+
self.is_dst = is_dst
|
|
221
|
+
self.disable_chiron_and_lilith = disable_chiron_and_lilith
|
|
196
222
|
|
|
197
223
|
#---------------#
|
|
198
224
|
# General setup #
|
|
199
225
|
#---------------#
|
|
200
226
|
|
|
201
|
-
#
|
|
227
|
+
# Geonames username
|
|
202
228
|
if geonames_username is None and online:
|
|
203
|
-
logging.warning(
|
|
204
|
-
|
|
205
|
-
)
|
|
206
|
-
|
|
229
|
+
logging.warning(GEONAMES_DEFAULT_USERNAME_WARNING)
|
|
207
230
|
self.geonames_username = DEFAULT_GEONAMES_USERNAME
|
|
231
|
+
else:
|
|
232
|
+
self.geonames_username = geonames_username # type: ignore
|
|
208
233
|
|
|
209
|
-
|
|
234
|
+
# City
|
|
235
|
+
if not city:
|
|
210
236
|
self.city = "London"
|
|
211
237
|
logging.info("No city specified, using London as default")
|
|
238
|
+
else:
|
|
239
|
+
self.city = city
|
|
212
240
|
|
|
213
|
-
|
|
241
|
+
# Nation
|
|
242
|
+
if not nation:
|
|
214
243
|
self.nation = "GB"
|
|
215
244
|
logging.info("No nation specified, using GB as default")
|
|
245
|
+
else:
|
|
246
|
+
self.nation = nation
|
|
216
247
|
|
|
217
|
-
|
|
248
|
+
# Latitude
|
|
249
|
+
if not lat and not self.online:
|
|
218
250
|
self.lat = 51.5074
|
|
219
251
|
logging.info("No latitude specified, using London as default")
|
|
220
|
-
|
|
221
|
-
|
|
252
|
+
else:
|
|
253
|
+
self.lat = lat # type: ignore
|
|
254
|
+
|
|
255
|
+
# Longitude
|
|
256
|
+
if not lng and not self.online:
|
|
222
257
|
self.lng = 0
|
|
223
258
|
logging.info("No longitude specified, using London as default")
|
|
259
|
+
else:
|
|
260
|
+
self.lng = lng # type: ignore
|
|
224
261
|
|
|
262
|
+
# Timezone
|
|
225
263
|
if (not self.online) and (not tz_str):
|
|
226
264
|
raise KerykeionException("You need to set the coordinates and timezone if you want to use the offline mode!")
|
|
265
|
+
else:
|
|
266
|
+
self.tz_str = tz_str # type: ignore
|
|
227
267
|
|
|
228
268
|
#-----------------------#
|
|
229
269
|
# Swiss Ephemeris setup #
|
|
@@ -246,6 +286,8 @@ class AstrologicalSubject:
|
|
|
246
286
|
elif self.perspective_type == "Topocentric":
|
|
247
287
|
self._iflag += swe.FLG_TOPOCTR
|
|
248
288
|
# geopos_is_set, for topocentric
|
|
289
|
+
if (self.online) and (not self.tz_str) and (not self.lat) and (not self.lng):
|
|
290
|
+
self._fetch_and_set_tz_and_coordinates_from_geonames()
|
|
249
291
|
swe.set_topo(self.lng, self.lat, 0)
|
|
250
292
|
# <--- Chart Perspective check and setup
|
|
251
293
|
|
|
@@ -269,7 +311,8 @@ class AstrologicalSubject:
|
|
|
269
311
|
|
|
270
312
|
if self.zodiac_type == "Sidereal":
|
|
271
313
|
# Check if the sidereal mode is valid
|
|
272
|
-
|
|
314
|
+
|
|
315
|
+
if not self.sidereal_mode or not self.sidereal_mode in get_args(SiderealMode):
|
|
273
316
|
raise KerykeionException(f"\n* ERROR: '{self.sidereal_mode}' is NOT a valid sidereal mode! Available modes are: *" + "\n" + str(get_args(SiderealMode)))
|
|
274
317
|
|
|
275
318
|
self._iflag += swe.FLG_SIDEREAL
|
|
@@ -281,17 +324,22 @@ class AstrologicalSubject:
|
|
|
281
324
|
#------------------------#
|
|
282
325
|
# Start the calculations #
|
|
283
326
|
#------------------------#
|
|
284
|
-
|
|
285
|
-
check_and_adjust_polar_latitude(self.lat, self.lng)
|
|
286
327
|
|
|
287
328
|
# UTC, julian day and local time setup --->
|
|
288
|
-
if (self.online) and (not self.tz_str):
|
|
289
|
-
self.
|
|
329
|
+
if (self.online) and (not self.tz_str) and (not self.lat) and (not self.lng):
|
|
330
|
+
self._fetch_and_set_tz_and_coordinates_from_geonames()
|
|
331
|
+
|
|
332
|
+
self.lat = check_and_adjust_polar_latitude(self.lat)
|
|
290
333
|
|
|
291
334
|
# Local time to UTC
|
|
292
335
|
local_time = pytz.timezone(self.tz_str)
|
|
293
336
|
naive_datetime = datetime(self.year, self.month, self.day, self.hour, self.minute, 0)
|
|
294
|
-
|
|
337
|
+
|
|
338
|
+
try:
|
|
339
|
+
local_datetime = local_time.localize(naive_datetime, is_dst=self.is_dst)
|
|
340
|
+
except pytz.exceptions.AmbiguousTimeError:
|
|
341
|
+
raise KerykeionException("Ambiguous time! Please specify if the time is in DST or not with the is_dst argument.")
|
|
342
|
+
|
|
295
343
|
utc_object = local_datetime.astimezone(pytz.utc)
|
|
296
344
|
self.iso_formatted_utc_datetime = utc_object.isoformat()
|
|
297
345
|
|
|
@@ -303,11 +351,9 @@ class AstrologicalSubject:
|
|
|
303
351
|
self.julian_day = float(swe.julday(utc_object.year, utc_object.month, utc_object.day, utc_float_hour_with_minutes))
|
|
304
352
|
# <--- UTC, julian day and local time setup
|
|
305
353
|
|
|
306
|
-
self.
|
|
307
|
-
self.
|
|
308
|
-
self.
|
|
309
|
-
self._planets_in_houses()
|
|
310
|
-
self._lunar_phase_calc()
|
|
354
|
+
self._initialize_houses()
|
|
355
|
+
self._initialize_planets()
|
|
356
|
+
self._initialize_moon_phase()
|
|
311
357
|
|
|
312
358
|
# Deprecated properties
|
|
313
359
|
self.utc_time
|
|
@@ -325,7 +371,7 @@ class AstrologicalSubject:
|
|
|
325
371
|
def get(self, item, default=None):
|
|
326
372
|
return getattr(self, item, default)
|
|
327
373
|
|
|
328
|
-
def
|
|
374
|
+
def _fetch_and_set_tz_and_coordinates_from_geonames(self) -> None:
|
|
329
375
|
"""Gets the nearest time zone for the calculation"""
|
|
330
376
|
logging.info("Fetching timezone/coordinates from geonames")
|
|
331
377
|
|
|
@@ -349,9 +395,7 @@ class AstrologicalSubject:
|
|
|
349
395
|
self.lat = float(self.city_data["lat"])
|
|
350
396
|
self.tz_str = self.city_data["timezonestr"]
|
|
351
397
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
def _houses(self) -> None:
|
|
398
|
+
def _initialize_houses(self) -> None:
|
|
355
399
|
"""
|
|
356
400
|
Calculate positions and store them in dictionaries
|
|
357
401
|
|
|
@@ -386,7 +430,7 @@ class AstrologicalSubject:
|
|
|
386
430
|
"""
|
|
387
431
|
|
|
388
432
|
if self.zodiac_type == "Sidereal":
|
|
389
|
-
self.
|
|
433
|
+
self._houses_degree_ut = swe.houses_ex(
|
|
390
434
|
tjdut=self.julian_day,
|
|
391
435
|
lat=self.lat, lon=self.lng,
|
|
392
436
|
hsys=str.encode(self.houses_system_identifier),
|
|
@@ -394,7 +438,7 @@ class AstrologicalSubject:
|
|
|
394
438
|
)[0]
|
|
395
439
|
|
|
396
440
|
elif self.zodiac_type == "Tropic":
|
|
397
|
-
self.
|
|
441
|
+
self._houses_degree_ut = swe.houses(
|
|
398
442
|
tjdut=self.julian_day, lat=self.lat,
|
|
399
443
|
lon=self.lng,
|
|
400
444
|
hsys=str.encode(self.houses_system_identifier)
|
|
@@ -403,20 +447,23 @@ class AstrologicalSubject:
|
|
|
403
447
|
point_type: PointType = "House"
|
|
404
448
|
|
|
405
449
|
# stores the house in singular dictionaries.
|
|
406
|
-
self.first_house =
|
|
407
|
-
self.second_house =
|
|
408
|
-
self.third_house =
|
|
409
|
-
self.fourth_house =
|
|
410
|
-
self.fifth_house =
|
|
411
|
-
self.sixth_house =
|
|
412
|
-
self.seventh_house =
|
|
413
|
-
self.eighth_house =
|
|
414
|
-
self.ninth_house =
|
|
415
|
-
self.tenth_house =
|
|
416
|
-
self.eleventh_house =
|
|
417
|
-
self.twelfth_house =
|
|
418
|
-
|
|
419
|
-
self.
|
|
450
|
+
self.first_house = get_kerykeion_point_from_degree(self._houses_degree_ut[0], "First_House", point_type=point_type)
|
|
451
|
+
self.second_house = get_kerykeion_point_from_degree(self._houses_degree_ut[1], "Second_House", point_type=point_type)
|
|
452
|
+
self.third_house = get_kerykeion_point_from_degree(self._houses_degree_ut[2], "Third_House", point_type=point_type)
|
|
453
|
+
self.fourth_house = get_kerykeion_point_from_degree(self._houses_degree_ut[3], "Fourth_House", point_type=point_type)
|
|
454
|
+
self.fifth_house = get_kerykeion_point_from_degree(self._houses_degree_ut[4], "Fifth_House", point_type=point_type)
|
|
455
|
+
self.sixth_house = get_kerykeion_point_from_degree(self._houses_degree_ut[5], "Sixth_House", point_type=point_type)
|
|
456
|
+
self.seventh_house = get_kerykeion_point_from_degree(self._houses_degree_ut[6], "Seventh_House", point_type=point_type)
|
|
457
|
+
self.eighth_house = get_kerykeion_point_from_degree(self._houses_degree_ut[7], "Eighth_House", point_type=point_type)
|
|
458
|
+
self.ninth_house = get_kerykeion_point_from_degree(self._houses_degree_ut[8], "Ninth_House", point_type=point_type)
|
|
459
|
+
self.tenth_house = get_kerykeion_point_from_degree(self._houses_degree_ut[9], "Tenth_House", point_type=point_type)
|
|
460
|
+
self.eleventh_house = get_kerykeion_point_from_degree(self._houses_degree_ut[10], "Eleventh_House", point_type=point_type)
|
|
461
|
+
self.twelfth_house = get_kerykeion_point_from_degree(self._houses_degree_ut[11], "Twelfth_House", point_type=point_type)
|
|
462
|
+
|
|
463
|
+
self.houses_names_list = list(get_args(Houses))
|
|
464
|
+
|
|
465
|
+
# Deprecated
|
|
466
|
+
self._houses_list = [
|
|
420
467
|
self.first_house,
|
|
421
468
|
self.second_house,
|
|
422
469
|
self.third_house,
|
|
@@ -431,10 +478,12 @@ class AstrologicalSubject:
|
|
|
431
478
|
self.twelfth_house,
|
|
432
479
|
]
|
|
433
480
|
|
|
434
|
-
def
|
|
435
|
-
"""
|
|
481
|
+
def _initialize_planets(self) -> None:
|
|
482
|
+
"""Defines body positon in signs and information and
|
|
483
|
+
stores them in dictionaries"""
|
|
484
|
+
|
|
485
|
+
point_type: PointType = "Planet"
|
|
436
486
|
|
|
437
|
-
# Calculates the position of the planets and stores it in a list.
|
|
438
487
|
sun_deg = swe.calc(self.julian_day, 0, self._iflag)[0][0]
|
|
439
488
|
moon_deg = swe.calc(self.julian_day, 1, self._iflag)[0][0]
|
|
440
489
|
mercury_deg = swe.calc(self.julian_day, 2, self._iflag)[0][0]
|
|
@@ -447,77 +496,35 @@ class AstrologicalSubject:
|
|
|
447
496
|
pluto_deg = swe.calc(self.julian_day, 9, self._iflag)[0][0]
|
|
448
497
|
mean_node_deg = swe.calc(self.julian_day, 10, self._iflag)[0][0]
|
|
449
498
|
true_node_deg = swe.calc(self.julian_day, 11, self._iflag)[0][0]
|
|
450
|
-
|
|
451
|
-
if not self.disable_chiron:
|
|
452
|
-
chiron_deg = swe.calc(self.julian_day, 15, self._iflag)[0][0]
|
|
453
|
-
else:
|
|
454
|
-
chiron_deg = 0
|
|
455
|
-
|
|
456
|
-
self.planets_degrees_ut = [
|
|
457
|
-
sun_deg,
|
|
458
|
-
moon_deg,
|
|
459
|
-
mercury_deg,
|
|
460
|
-
venus_deg,
|
|
461
|
-
mars_deg,
|
|
462
|
-
jupiter_deg,
|
|
463
|
-
saturn_deg,
|
|
464
|
-
uranus_deg,
|
|
465
|
-
neptune_deg,
|
|
466
|
-
pluto_deg,
|
|
467
|
-
mean_node_deg,
|
|
468
|
-
true_node_deg,
|
|
469
|
-
]
|
|
470
|
-
|
|
471
|
-
if not self.disable_chiron:
|
|
472
|
-
self.planets_degrees_ut.append(chiron_deg)
|
|
473
499
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
self.
|
|
481
|
-
self.
|
|
482
|
-
self.
|
|
483
|
-
self.
|
|
484
|
-
self.
|
|
485
|
-
self.
|
|
486
|
-
|
|
487
|
-
self.
|
|
488
|
-
self.
|
|
489
|
-
self.
|
|
490
|
-
self.
|
|
491
|
-
self.
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
self.sun.house = get_planet_house(self.planets_degrees_ut[0], self.houses_degree_ut)
|
|
503
|
-
self.moon.house = get_planet_house(self.planets_degrees_ut[1], self.houses_degree_ut)
|
|
504
|
-
self.mercury.house = get_planet_house(self.planets_degrees_ut[2], self.houses_degree_ut)
|
|
505
|
-
self.venus.house = get_planet_house(self.planets_degrees_ut[3], self.houses_degree_ut)
|
|
506
|
-
self.mars.house = get_planet_house(self.planets_degrees_ut[4], self.houses_degree_ut)
|
|
507
|
-
self.jupiter.house = get_planet_house(self.planets_degrees_ut[5], self.houses_degree_ut)
|
|
508
|
-
self.saturn.house = get_planet_house(self.planets_degrees_ut[6], self.houses_degree_ut)
|
|
509
|
-
self.uranus.house = get_planet_house(self.planets_degrees_ut[7], self.houses_degree_ut)
|
|
510
|
-
self.neptune.house = get_planet_house(self.planets_degrees_ut[8], self.houses_degree_ut)
|
|
511
|
-
self.pluto.house = get_planet_house(self.planets_degrees_ut[9], self.houses_degree_ut)
|
|
512
|
-
self.mean_node.house = get_planet_house(self.planets_degrees_ut[10], self.houses_degree_ut)
|
|
513
|
-
self.true_node.house = get_planet_house(self.planets_degrees_ut[11], self.houses_degree_ut)
|
|
514
|
-
|
|
515
|
-
if not self.disable_chiron:
|
|
516
|
-
self.chiron.house = get_planet_house(self.planets_degrees_ut[12], self.houses_degree_ut)
|
|
517
|
-
else:
|
|
518
|
-
self.chiron = None
|
|
519
|
-
|
|
520
|
-
self.planets_list = [
|
|
500
|
+
self.sun = get_kerykeion_point_from_degree(sun_deg, "Sun", point_type=point_type)
|
|
501
|
+
self.moon = get_kerykeion_point_from_degree(moon_deg, "Moon", point_type=point_type)
|
|
502
|
+
self.mercury = get_kerykeion_point_from_degree(mercury_deg, "Mercury", point_type=point_type)
|
|
503
|
+
self.venus = get_kerykeion_point_from_degree(venus_deg, "Venus", point_type=point_type)
|
|
504
|
+
self.mars = get_kerykeion_point_from_degree(mars_deg, "Mars", point_type=point_type)
|
|
505
|
+
self.jupiter = get_kerykeion_point_from_degree(jupiter_deg, "Jupiter", point_type=point_type)
|
|
506
|
+
self.saturn = get_kerykeion_point_from_degree(saturn_deg, "Saturn", point_type=point_type)
|
|
507
|
+
self.uranus = get_kerykeion_point_from_degree(uranus_deg, "Uranus", point_type=point_type)
|
|
508
|
+
self.neptune = get_kerykeion_point_from_degree(neptune_deg, "Neptune", point_type=point_type)
|
|
509
|
+
self.pluto = get_kerykeion_point_from_degree(pluto_deg, "Pluto", point_type=point_type)
|
|
510
|
+
self.mean_node = get_kerykeion_point_from_degree(mean_node_deg, "Mean_Node", point_type=point_type)
|
|
511
|
+
self.true_node = get_kerykeion_point_from_degree(true_node_deg, "True_Node", point_type=point_type)
|
|
512
|
+
|
|
513
|
+
self.sun.house = get_planet_house(sun_deg, self._houses_degree_ut)
|
|
514
|
+
self.moon.house = get_planet_house(moon_deg, self._houses_degree_ut)
|
|
515
|
+
self.mercury.house = get_planet_house(mercury_deg, self._houses_degree_ut)
|
|
516
|
+
self.venus.house = get_planet_house(venus_deg, self._houses_degree_ut)
|
|
517
|
+
self.mars.house = get_planet_house(mars_deg, self._houses_degree_ut)
|
|
518
|
+
self.jupiter.house = get_planet_house(jupiter_deg, self._houses_degree_ut)
|
|
519
|
+
self.saturn.house = get_planet_house(saturn_deg, self._houses_degree_ut)
|
|
520
|
+
self.uranus.house = get_planet_house(uranus_deg, self._houses_degree_ut)
|
|
521
|
+
self.neptune.house = get_planet_house(neptune_deg, self._houses_degree_ut)
|
|
522
|
+
self.pluto.house = get_planet_house(pluto_deg, self._houses_degree_ut)
|
|
523
|
+
self.mean_node.house = get_planet_house(mean_node_deg, self._houses_degree_ut)
|
|
524
|
+
self.true_node.house = get_planet_house(true_node_deg, self._houses_degree_ut)
|
|
525
|
+
|
|
526
|
+
# Deprecated
|
|
527
|
+
planets_list = [
|
|
521
528
|
self.sun,
|
|
522
529
|
self.moon,
|
|
523
530
|
self.mercury,
|
|
@@ -531,83 +538,70 @@ class AstrologicalSubject:
|
|
|
531
538
|
self.mean_node,
|
|
532
539
|
self.true_node,
|
|
533
540
|
]
|
|
534
|
-
|
|
535
|
-
if not self.
|
|
536
|
-
|
|
541
|
+
|
|
542
|
+
if not self.disable_chiron_and_lilith:
|
|
543
|
+
chiron_deg = swe.calc(self.julian_day, 15, self._iflag)[0][0]
|
|
544
|
+
mean_lilith_deg = swe.calc(self.julian_day, 12, self._iflag)[0][0]
|
|
545
|
+
|
|
546
|
+
self.chiron = get_kerykeion_point_from_degree(chiron_deg, "Chiron", point_type=point_type)
|
|
547
|
+
self.mean_lilith = get_kerykeion_point_from_degree(mean_lilith_deg, "Mean_Lilith", point_type=point_type)
|
|
548
|
+
|
|
549
|
+
self.chiron.house = get_planet_house(chiron_deg, self._houses_degree_ut)
|
|
550
|
+
self.mean_lilith.house = get_planet_house(mean_lilith_deg, self._houses_degree_ut)
|
|
551
|
+
|
|
552
|
+
# Deprecated
|
|
553
|
+
planets_list.append(self.chiron)
|
|
554
|
+
planets_list.append(self.mean_lilith)
|
|
555
|
+
|
|
556
|
+
else:
|
|
557
|
+
self.chiron = None
|
|
558
|
+
self.mean_lilith = None
|
|
559
|
+
|
|
560
|
+
# FIXME: Update after removing planets_list
|
|
561
|
+
self.planets_names_list = [planet["name"] for planet in planets_list]
|
|
537
562
|
|
|
538
563
|
# Check in retrograde or not:
|
|
539
|
-
|
|
540
|
-
for planet in self.planets_list:
|
|
564
|
+
for planet in planets_list:
|
|
541
565
|
planet_number = get_number_from_name(planet["name"])
|
|
542
566
|
if swe.calc(self.julian_day, planet_number, self._iflag)[0][3] < 0:
|
|
543
567
|
planet["retrograde"] = True
|
|
544
568
|
else:
|
|
545
569
|
planet["retrograde"] = False
|
|
546
|
-
planets_ret.append(planet)
|
|
547
570
|
|
|
548
|
-
def _lunar_phase_calc(self) -> None:
|
|
549
|
-
"""Function to calculate the lunar phase"""
|
|
550
571
|
|
|
551
|
-
|
|
552
|
-
|
|
572
|
+
def _initialize_moon_phase(self) -> None:
|
|
573
|
+
"""
|
|
574
|
+
Calculate and initialize the lunar phase based on the positions of the moon and sun.
|
|
553
575
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
576
|
+
This function calculates the degrees between the moon and the sun, determines the moon phase
|
|
577
|
+
and sun phase, and initializes the lunar phase model with the calculated values.
|
|
578
|
+
"""
|
|
579
|
+
# Initialize moon_phase and sun_phase to None in case of an error
|
|
580
|
+
moon_phase, sun_phase = None, None
|
|
557
581
|
|
|
558
|
-
|
|
559
|
-
|
|
582
|
+
# Calculate the anti-clockwise degrees between the sun and moon
|
|
583
|
+
moon, sun = self.moon.abs_pos, self.sun.abs_pos
|
|
584
|
+
degrees_between = (moon - sun) % 360
|
|
560
585
|
|
|
586
|
+
# Calculate the moon phase (1-28) based on the degrees between the sun and moon
|
|
561
587
|
step = 360.0 / 28.0
|
|
588
|
+
moon_phase = int(degrees_between // step) + 1
|
|
562
589
|
|
|
563
|
-
|
|
564
|
-
low = x * step
|
|
565
|
-
high = (x + 1) * step
|
|
566
|
-
|
|
567
|
-
if degrees_between >= low and degrees_between < high:
|
|
568
|
-
moon_phase = x + 1
|
|
569
|
-
|
|
590
|
+
# Define the sun phase steps
|
|
570
591
|
sunstep = [
|
|
571
|
-
0,
|
|
572
|
-
|
|
573
|
-
40,
|
|
574
|
-
50,
|
|
575
|
-
60,
|
|
576
|
-
70,
|
|
577
|
-
80,
|
|
578
|
-
90,
|
|
579
|
-
120,
|
|
580
|
-
130,
|
|
581
|
-
140,
|
|
582
|
-
150,
|
|
583
|
-
160,
|
|
584
|
-
170,
|
|
585
|
-
180,
|
|
586
|
-
210,
|
|
587
|
-
220,
|
|
588
|
-
230,
|
|
589
|
-
240,
|
|
590
|
-
250,
|
|
591
|
-
260,
|
|
592
|
-
270,
|
|
593
|
-
300,
|
|
594
|
-
310,
|
|
595
|
-
320,
|
|
596
|
-
330,
|
|
597
|
-
340,
|
|
598
|
-
350,
|
|
592
|
+
0, 30, 40, 50, 60, 70, 80, 90, 120, 130, 140, 150, 160, 170, 180,
|
|
593
|
+
210, 220, 230, 240, 250, 260, 270, 300, 310, 320, 330, 340, 350
|
|
599
594
|
]
|
|
600
595
|
|
|
596
|
+
# Calculate the sun phase (1-28) based on the degrees between the sun and moon
|
|
601
597
|
for x in range(len(sunstep)):
|
|
602
598
|
low = sunstep[x]
|
|
603
|
-
|
|
604
|
-
if
|
|
605
|
-
high = 360
|
|
606
|
-
else:
|
|
607
|
-
high = sunstep[x + 1]
|
|
608
|
-
if degrees_between >= low and degrees_between < high:
|
|
599
|
+
high = sunstep[x + 1] if x < len(sunstep) - 1 else 360
|
|
600
|
+
if low <= degrees_between < high:
|
|
609
601
|
sun_phase = x + 1
|
|
602
|
+
break
|
|
610
603
|
|
|
604
|
+
# Create a dictionary with the lunar phase information
|
|
611
605
|
lunar_phase_dictionary = {
|
|
612
606
|
"degrees_between_s_m": degrees_between,
|
|
613
607
|
"moon_phase": moon_phase,
|
|
@@ -616,6 +610,7 @@ class AstrologicalSubject:
|
|
|
616
610
|
"moon_phase_name": get_moon_phase_name_from_phase_int(moon_phase)
|
|
617
611
|
}
|
|
618
612
|
|
|
613
|
+
# Initialize the lunar phase model with the calculated values
|
|
619
614
|
self.lunar_phase = LunarPhaseModel(**lunar_phase_dictionary)
|
|
620
615
|
|
|
621
616
|
def json(self, dump=False, destination_folder: Union[str, None] = None, indent: Union[int, None] = None) -> str:
|
|
@@ -698,7 +693,7 @@ class AstrologicalSubject:
|
|
|
698
693
|
lat: Union[int, float] = 51.5074,
|
|
699
694
|
geonames_username: str = DEFAULT_GEONAMES_USERNAME,
|
|
700
695
|
zodiac_type: ZodiacType = DEFAULT_ZODIAC_TYPE,
|
|
701
|
-
|
|
696
|
+
disable_chiron_and_lilith: bool = False,
|
|
702
697
|
sidereal_mode: Union[SiderealMode, None] = None,
|
|
703
698
|
houses_system_identifier: HousesSystemIdentifier = DEFAULT_HOUSES_SYSTEM_IDENTIFIER,
|
|
704
699
|
perspective_type: PerspectiveType = DEFAULT_PERSPECTIVE_TYPE
|
|
@@ -721,7 +716,7 @@ class AstrologicalSubject:
|
|
|
721
716
|
- geonames_username (str, optional): The username for the geonames API. Note: Change this to your own username to avoid rate limits!
|
|
722
717
|
You can get one for free here: https://www.geonames.org/login
|
|
723
718
|
- zodiac_type (ZodiacType, optional): The zodiac type to use. Defaults to "Tropic".
|
|
724
|
-
-
|
|
719
|
+
- disable_chiron_and_lilith: boolean representing if Chiron and Lilith should be disabled. Default is False.
|
|
725
720
|
Chiron calculation can create some issues with the Swiss Ephemeris when the date is too far in the past.
|
|
726
721
|
- sidereal_mode (SiderealMode, optional): Also known as Ayanamsa.
|
|
727
722
|
The mode to use for the sidereal zodiac, according to the Swiss Ephemeris.
|
|
@@ -767,10 +762,10 @@ class AstrologicalSubject:
|
|
|
767
762
|
online=False,
|
|
768
763
|
geonames_username=geonames_username,
|
|
769
764
|
zodiac_type=zodiac_type,
|
|
770
|
-
disable_chiron=disable_chiron,
|
|
771
765
|
sidereal_mode=sidereal_mode,
|
|
772
766
|
houses_system_identifier=houses_system_identifier,
|
|
773
|
-
perspective_type=perspective_type
|
|
767
|
+
perspective_type=perspective_type,
|
|
768
|
+
disable_chiron_and_lilith=disable_chiron_and_lilith
|
|
774
769
|
)
|
|
775
770
|
|
|
776
771
|
return subject
|
|
@@ -812,4 +807,12 @@ if __name__ == "__main__":
|
|
|
812
807
|
print(johnny.json(dump=True, indent=2))
|
|
813
808
|
|
|
814
809
|
# With Topocentric Perspective
|
|
815
|
-
johnny = AstrologicalSubject("Johnny Depp", 1963, 6, 9, 0, 0, "Owensboro", "US", perspective_type="Topocentric")
|
|
810
|
+
johnny = AstrologicalSubject("Johnny Depp", 1963, 6, 9, 0, 0, "Owensboro", "US", perspective_type="Topocentric")
|
|
811
|
+
|
|
812
|
+
# Test Mean Lilith
|
|
813
|
+
johnny = AstrologicalSubject("Johnny Depp", 1963, 6, 9, 0, 0, "Owensboro", "US", disable_chiron_and_lilith=True)
|
|
814
|
+
print(johnny.mean_lilith)
|
|
815
|
+
|
|
816
|
+
# Offline mode
|
|
817
|
+
johnny = AstrologicalSubject("Johnny Depp", 1963, 6, 9, 0, 0, "Owensboro", "US", online=False, tz_str="America/New_York", lng=-87.1111, lat=37.7711)
|
|
818
|
+
print(johnny.json(dump=True, indent=2))
|