kerykeion 5.0.0a4__py3-none-any.whl → 5.0.0a6__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/astrological_subject_factory.py +245 -233
- kerykeion/charts/kerykeion_chart_svg.py +94 -50
- kerykeion/charts/templates/chart.xml +3 -3
- kerykeion/charts/themes/classic.css +5 -0
- kerykeion/charts/themes/dark-high-contrast.css +5 -0
- kerykeion/charts/themes/dark.css +5 -0
- kerykeion/charts/themes/light.css +5 -0
- kerykeion/charts/themes/strawberry.css +5 -0
- kerykeion/kr_types/kr_models.py +5 -5
- kerykeion/planetary_return_factory.py +1 -0
- kerykeion/settings/kr.config.json +16 -16
- kerykeion/utilities.py +7 -10
- {kerykeion-5.0.0a4.dist-info → kerykeion-5.0.0a6.dist-info}/METADATA +1 -1
- {kerykeion-5.0.0a4.dist-info → kerykeion-5.0.0a6.dist-info}/RECORD +17 -17
- {kerykeion-5.0.0a4.dist-info → kerykeion-5.0.0a6.dist-info}/LICENSE +0 -0
- {kerykeion-5.0.0a4.dist-info → kerykeion-5.0.0a6.dist-info}/WHEEL +0 -0
- {kerykeion-5.0.0a4.dist-info → kerykeion-5.0.0a6.dist-info}/entry_points.txt +0 -0
|
@@ -186,6 +186,7 @@ class AstrologicalSubjectFactory:
|
|
|
186
186
|
is_dst: Optional[bool] = None,
|
|
187
187
|
altitude: Optional[float] = None,
|
|
188
188
|
active_points: List[AstrologicalPoint] = DEFAULT_ACTIVE_POINTS,
|
|
189
|
+
calculate_lunar_phase: bool = True,
|
|
189
190
|
*,
|
|
190
191
|
seconds: int = 0,
|
|
191
192
|
|
|
@@ -205,53 +206,16 @@ class AstrologicalSubjectFactory:
|
|
|
205
206
|
zodiac_type: Type of zodiac (Tropical or Sidereal)
|
|
206
207
|
sidereal_mode: Mode for sidereal calculations
|
|
207
208
|
houses_system_identifier: House system for calculations
|
|
208
|
-
perspective_type: Perspective
|
|
209
|
+
perspective_type: Perspective for calculations
|
|
209
210
|
cache_expire_after_days: Cache duration for geonames data
|
|
210
211
|
is_dst: Daylight saving time flag
|
|
211
212
|
altitude: Location altitude for topocentric calculations
|
|
212
213
|
active_points: Set of points to calculate (optimization)
|
|
214
|
+
calculate_lunar_phase: Whether to calculate lunar phase (requires Sun and Moon)
|
|
213
215
|
|
|
214
216
|
Returns:
|
|
215
217
|
An AstrologicalSubjectModel with calculated data
|
|
216
218
|
"""
|
|
217
|
-
logging.debug("Starting Kerykeion calculation")
|
|
218
|
-
|
|
219
|
-
if "Sun" not in active_points:
|
|
220
|
-
logging.info("Automatically adding 'Sun' to active points")
|
|
221
|
-
active_points.append("Sun")
|
|
222
|
-
|
|
223
|
-
if "Moon" not in active_points:
|
|
224
|
-
logging.info("Automatically adding 'Moon' to active points")
|
|
225
|
-
active_points.append("Moon")
|
|
226
|
-
|
|
227
|
-
if "Ascendant" not in active_points:
|
|
228
|
-
logging.info("Automatically adding 'Ascendant' to active points")
|
|
229
|
-
active_points.append("Ascendant")
|
|
230
|
-
|
|
231
|
-
if "Medium_Coeli" not in active_points:
|
|
232
|
-
logging.info("Automatically adding 'Medium_Coeli' to active points")
|
|
233
|
-
active_points.append("Medium_Coeli")
|
|
234
|
-
|
|
235
|
-
if "Mercury" not in active_points:
|
|
236
|
-
logging.info("Automatically adding 'Mercury' to active points")
|
|
237
|
-
active_points.append("Mercury")
|
|
238
|
-
|
|
239
|
-
if "Venus" not in active_points:
|
|
240
|
-
logging.info("Automatically adding 'Venus' to active points")
|
|
241
|
-
active_points.append("Venus")
|
|
242
|
-
|
|
243
|
-
if "Mars" not in active_points:
|
|
244
|
-
logging.info("Automatically adding 'Mars' to active points")
|
|
245
|
-
active_points.append("Mars")
|
|
246
|
-
|
|
247
|
-
if "Jupiter" not in active_points:
|
|
248
|
-
logging.info("Automatically adding 'Jupiter' to active points")
|
|
249
|
-
active_points.append("Jupiter")
|
|
250
|
-
|
|
251
|
-
if "Saturn" not in active_points:
|
|
252
|
-
logging.info("Automatically adding 'Saturn' to active points")
|
|
253
|
-
active_points.append("Saturn")
|
|
254
|
-
|
|
255
219
|
# Create a calculation data container
|
|
256
220
|
calc_data = {}
|
|
257
221
|
|
|
@@ -259,6 +223,11 @@ class AstrologicalSubjectFactory:
|
|
|
259
223
|
calc_data["name"] = name
|
|
260
224
|
calc_data["json_dir"] = str(Path.home())
|
|
261
225
|
|
|
226
|
+
# Create a deep copy of active points to avoid modifying the original list
|
|
227
|
+
active_points = list(active_points)
|
|
228
|
+
|
|
229
|
+
calc_data["active_points"] = active_points
|
|
230
|
+
|
|
262
231
|
# Initialize configuration
|
|
263
232
|
config = ChartConfiguration(
|
|
264
233
|
zodiac_type=zodiac_type,
|
|
@@ -290,13 +259,13 @@ class AstrologicalSubjectFactory:
|
|
|
290
259
|
)
|
|
291
260
|
|
|
292
261
|
# If offline mode is requested but required data is missing, raise error
|
|
293
|
-
if not online and (not tz_str or
|
|
262
|
+
if not online and (not tz_str or lat is None or lng is None):
|
|
294
263
|
raise KerykeionException(
|
|
295
264
|
"For offline mode, you must provide timezone (tz_str) and coordinates (lat, lng)"
|
|
296
265
|
)
|
|
297
266
|
|
|
298
267
|
# Fetch location data if needed
|
|
299
|
-
if online and (not tz_str or
|
|
268
|
+
if online and (not tz_str or lat is None or lng is None):
|
|
300
269
|
location.fetch_from_geonames(
|
|
301
270
|
username=geonames_username or DEFAULT_GEONAMES_USERNAME,
|
|
302
271
|
cache_expire_after_days=cache_expire_after_days
|
|
@@ -321,22 +290,22 @@ class AstrologicalSubjectFactory:
|
|
|
321
290
|
calc_data["minute"] = minute
|
|
322
291
|
calc_data["seconds"] = seconds
|
|
323
292
|
calc_data["is_dst"] = is_dst
|
|
324
|
-
calc_data["active_points"] = active_points
|
|
325
293
|
|
|
326
294
|
# Calculate time conversions
|
|
327
295
|
cls._calculate_time_conversions(calc_data, location)
|
|
328
296
|
|
|
329
297
|
# Initialize Swiss Ephemeris and calculate houses and planets
|
|
330
298
|
cls._setup_ephemeris(calc_data, config)
|
|
331
|
-
cls._calculate_houses(calc_data, active_points)
|
|
332
|
-
cls._calculate_planets(calc_data, active_points)
|
|
299
|
+
cls._calculate_houses(calc_data, calc_data["active_points"])
|
|
300
|
+
cls._calculate_planets(calc_data, calc_data["active_points"])
|
|
333
301
|
cls._calculate_day_of_week(calc_data)
|
|
334
302
|
|
|
335
|
-
# Calculate lunar phase
|
|
336
|
-
calc_data
|
|
337
|
-
calc_data["
|
|
338
|
-
|
|
339
|
-
|
|
303
|
+
# Calculate lunar phase (optional - only if requested and Sun and Moon are available)
|
|
304
|
+
if calculate_lunar_phase and "moon" in calc_data and "sun" in calc_data:
|
|
305
|
+
calc_data["lunar_phase"] = calculate_moon_phase(
|
|
306
|
+
calc_data["moon"].abs_pos,
|
|
307
|
+
calc_data["sun"].abs_pos
|
|
308
|
+
)
|
|
340
309
|
|
|
341
310
|
# Create and return the AstrologicalSubjectModel
|
|
342
311
|
return AstrologicalSubjectModel(**calc_data)
|
|
@@ -349,7 +318,7 @@ class AstrologicalSubjectFactory:
|
|
|
349
318
|
city: str = "Greenwich",
|
|
350
319
|
nation: str = "GB",
|
|
351
320
|
tz_str: str = "Etc/GMT",
|
|
352
|
-
online: bool =
|
|
321
|
+
online: bool = True,
|
|
353
322
|
lng: float = 0.0,
|
|
354
323
|
lat: float = 51.5074,
|
|
355
324
|
geonames_username: str = DEFAULT_GEONAMES_USERNAME,
|
|
@@ -358,7 +327,8 @@ class AstrologicalSubjectFactory:
|
|
|
358
327
|
houses_system_identifier: HousesSystemIdentifier = DEFAULT_HOUSES_SYSTEM_IDENTIFIER,
|
|
359
328
|
perspective_type: PerspectiveType = DEFAULT_PERSPECTIVE_TYPE,
|
|
360
329
|
altitude: Optional[float] = None,
|
|
361
|
-
active_points: List[AstrologicalPoint] = DEFAULT_ACTIVE_POINTS
|
|
330
|
+
active_points: List[AstrologicalPoint] = DEFAULT_ACTIVE_POINTS,
|
|
331
|
+
calculate_lunar_phase: bool = True
|
|
362
332
|
) -> AstrologicalSubjectModel:
|
|
363
333
|
"""
|
|
364
334
|
Create an astrological subject from an ISO formatted UTC time.
|
|
@@ -378,6 +348,7 @@ class AstrologicalSubjectFactory:
|
|
|
378
348
|
perspective_type: Perspective for calculations
|
|
379
349
|
altitude: Location altitude
|
|
380
350
|
active_points: Set of points to calculate
|
|
351
|
+
calculate_lunar_phase: Whether to calculate lunar phase
|
|
381
352
|
|
|
382
353
|
Returns:
|
|
383
354
|
AstrologicalSubjectModel instance
|
|
@@ -425,7 +396,8 @@ class AstrologicalSubjectFactory:
|
|
|
425
396
|
houses_system_identifier=houses_system_identifier,
|
|
426
397
|
perspective_type=perspective_type,
|
|
427
398
|
altitude=altitude,
|
|
428
|
-
active_points=active_points
|
|
399
|
+
active_points=active_points,
|
|
400
|
+
calculate_lunar_phase=calculate_lunar_phase
|
|
429
401
|
)
|
|
430
402
|
|
|
431
403
|
@classmethod
|
|
@@ -443,7 +415,8 @@ class AstrologicalSubjectFactory:
|
|
|
443
415
|
sidereal_mode: Optional[SiderealMode] = None,
|
|
444
416
|
houses_system_identifier: HousesSystemIdentifier = DEFAULT_HOUSES_SYSTEM_IDENTIFIER,
|
|
445
417
|
perspective_type: PerspectiveType = DEFAULT_PERSPECTIVE_TYPE,
|
|
446
|
-
active_points: List[AstrologicalPoint] = DEFAULT_ACTIVE_POINTS
|
|
418
|
+
active_points: List[AstrologicalPoint] = DEFAULT_ACTIVE_POINTS,
|
|
419
|
+
calculate_lunar_phase: bool = True
|
|
447
420
|
) -> AstrologicalSubjectModel:
|
|
448
421
|
"""
|
|
449
422
|
Create an astrological subject for the current time.
|
|
@@ -461,6 +434,7 @@ class AstrologicalSubjectFactory:
|
|
|
461
434
|
houses_system_identifier: House system
|
|
462
435
|
perspective_type: Perspective for calculations
|
|
463
436
|
active_points: Set of points to calculate
|
|
437
|
+
calculate_lunar_phase: Whether to calculate lunar phase
|
|
464
438
|
|
|
465
439
|
Returns:
|
|
466
440
|
AstrologicalSubjectModel for current time
|
|
@@ -486,7 +460,8 @@ class AstrologicalSubjectFactory:
|
|
|
486
460
|
sidereal_mode=sidereal_mode,
|
|
487
461
|
houses_system_identifier=houses_system_identifier,
|
|
488
462
|
perspective_type=perspective_type,
|
|
489
|
-
active_points=active_points
|
|
463
|
+
active_points=active_points,
|
|
464
|
+
calculate_lunar_phase=calculate_lunar_phase
|
|
490
465
|
)
|
|
491
466
|
|
|
492
467
|
@classmethod
|
|
@@ -627,6 +602,56 @@ class AstrologicalSubjectFactory:
|
|
|
627
602
|
data["imum_coeli"].retrograde = False
|
|
628
603
|
calculated_axial_cusps.append("Imum_Coeli")
|
|
629
604
|
|
|
605
|
+
@classmethod
|
|
606
|
+
def _calculate_single_planet(
|
|
607
|
+
cls,
|
|
608
|
+
data: Dict[str, Any],
|
|
609
|
+
planet_name: AstrologicalPoint,
|
|
610
|
+
planet_id: int,
|
|
611
|
+
julian_day: float,
|
|
612
|
+
iflag: int,
|
|
613
|
+
houses_degree_ut: List[float],
|
|
614
|
+
point_type: PointType,
|
|
615
|
+
calculated_planets: List[str],
|
|
616
|
+
active_points: List[AstrologicalPoint]
|
|
617
|
+
) -> None:
|
|
618
|
+
"""
|
|
619
|
+
Calculate a single planet's position with error handling and store it in the data dictionary.
|
|
620
|
+
|
|
621
|
+
Args:
|
|
622
|
+
data: The data dictionary to store the planet information
|
|
623
|
+
planet_name: Name of the planet
|
|
624
|
+
planet_id: Swiss Ephemeris planet ID
|
|
625
|
+
julian_day: Julian day for the calculation
|
|
626
|
+
iflag: Swiss Ephemeris calculation flags
|
|
627
|
+
houses_degree_ut: House degrees for house calculation
|
|
628
|
+
point_type: Type of point being calculated
|
|
629
|
+
calculated_planets: List to track calculated planets
|
|
630
|
+
active_points: List of active points to modify if error occurs
|
|
631
|
+
"""
|
|
632
|
+
try:
|
|
633
|
+
# Calculate planet position using Swiss Ephemeris
|
|
634
|
+
planet_calc = swe.calc_ut(julian_day, planet_id, iflag)[0]
|
|
635
|
+
|
|
636
|
+
# Create Kerykeion point from degree
|
|
637
|
+
data[planet_name.lower()] = get_kerykeion_point_from_degree(
|
|
638
|
+
planet_calc[0], planet_name, point_type=point_type
|
|
639
|
+
)
|
|
640
|
+
|
|
641
|
+
# Calculate house position
|
|
642
|
+
data[planet_name.lower()].house = get_planet_house(planet_calc[0], houses_degree_ut)
|
|
643
|
+
|
|
644
|
+
# Determine if planet is retrograde
|
|
645
|
+
data[planet_name.lower()].retrograde = planet_calc[3] < 0
|
|
646
|
+
|
|
647
|
+
# Track calculated planet
|
|
648
|
+
calculated_planets.append(planet_name)
|
|
649
|
+
|
|
650
|
+
except Exception as e:
|
|
651
|
+
logging.error(f"Error calculating {planet_name}: {e}")
|
|
652
|
+
if planet_name in active_points:
|
|
653
|
+
active_points.remove(planet_name)
|
|
654
|
+
|
|
630
655
|
@classmethod
|
|
631
656
|
def _calculate_planets(cls, data: Dict[str, Any], active_points: List[AstrologicalPoint]) -> None:
|
|
632
657
|
"""Calculate planetary positions and related information"""
|
|
@@ -647,83 +672,43 @@ class AstrologicalSubjectFactory:
|
|
|
647
672
|
|
|
648
673
|
# Calculate Sun
|
|
649
674
|
if should_calculate("Sun"):
|
|
650
|
-
|
|
651
|
-
data["sun"] = get_kerykeion_point_from_degree(sun_deg, "Sun", point_type=point_type)
|
|
652
|
-
data["sun"].house = get_planet_house(sun_deg, houses_degree_ut)
|
|
653
|
-
data["sun"].retrograde = swe.calc_ut(julian_day, 0, iflag)[0][3] < 0
|
|
654
|
-
calculated_planets.append("Sun")
|
|
675
|
+
cls._calculate_single_planet(data, "Sun", 0, julian_day, iflag, houses_degree_ut, point_type, calculated_planets, active_points)
|
|
655
676
|
|
|
656
677
|
# Calculate Moon
|
|
657
678
|
if should_calculate("Moon"):
|
|
658
|
-
|
|
659
|
-
data["moon"] = get_kerykeion_point_from_degree(moon_deg, "Moon", point_type=point_type)
|
|
660
|
-
data["moon"].house = get_planet_house(moon_deg, houses_degree_ut)
|
|
661
|
-
data["moon"].retrograde = swe.calc_ut(julian_day, 1, iflag)[0][3] < 0
|
|
662
|
-
calculated_planets.append("Moon")
|
|
679
|
+
cls._calculate_single_planet(data, "Moon", 1, julian_day, iflag, houses_degree_ut, point_type, calculated_planets, active_points)
|
|
663
680
|
|
|
664
681
|
# Calculate Mercury
|
|
665
682
|
if should_calculate("Mercury"):
|
|
666
|
-
|
|
667
|
-
data["mercury"] = get_kerykeion_point_from_degree(mercury_deg, "Mercury", point_type=point_type)
|
|
668
|
-
data["mercury"].house = get_planet_house(mercury_deg, houses_degree_ut)
|
|
669
|
-
data["mercury"].retrograde = swe.calc_ut(julian_day, 2, iflag)[0][3] < 0
|
|
670
|
-
calculated_planets.append("Mercury")
|
|
683
|
+
cls._calculate_single_planet(data, "Mercury", 2, julian_day, iflag, houses_degree_ut, point_type, calculated_planets, active_points)
|
|
671
684
|
|
|
672
685
|
# Calculate Venus
|
|
673
686
|
if should_calculate("Venus"):
|
|
674
|
-
|
|
675
|
-
data["venus"] = get_kerykeion_point_from_degree(venus_deg, "Venus", point_type=point_type)
|
|
676
|
-
data["venus"].house = get_planet_house(venus_deg, houses_degree_ut)
|
|
677
|
-
data["venus"].retrograde = swe.calc_ut(julian_day, 3, iflag)[0][3] < 0
|
|
678
|
-
calculated_planets.append("Venus")
|
|
687
|
+
cls._calculate_single_planet(data, "Venus", 3, julian_day, iflag, houses_degree_ut, point_type, calculated_planets, active_points)
|
|
679
688
|
|
|
680
689
|
# Calculate Mars
|
|
681
690
|
if should_calculate("Mars"):
|
|
682
|
-
|
|
683
|
-
data["mars"] = get_kerykeion_point_from_degree(mars_deg, "Mars", point_type=point_type)
|
|
684
|
-
data["mars"].house = get_planet_house(mars_deg, houses_degree_ut)
|
|
685
|
-
data["mars"].retrograde = swe.calc_ut(julian_day, 4, iflag)[0][3] < 0
|
|
686
|
-
calculated_planets.append("Mars")
|
|
691
|
+
cls._calculate_single_planet(data, "Mars", 4, julian_day, iflag, houses_degree_ut, point_type, calculated_planets, active_points)
|
|
687
692
|
|
|
688
693
|
# Calculate Jupiter
|
|
689
694
|
if should_calculate("Jupiter"):
|
|
690
|
-
|
|
691
|
-
data["jupiter"] = get_kerykeion_point_from_degree(jupiter_deg, "Jupiter", point_type=point_type)
|
|
692
|
-
data["jupiter"].house = get_planet_house(jupiter_deg, houses_degree_ut)
|
|
693
|
-
data["jupiter"].retrograde = swe.calc_ut(julian_day, 5, iflag)[0][3] < 0
|
|
694
|
-
calculated_planets.append("Jupiter")
|
|
695
|
+
cls._calculate_single_planet(data, "Jupiter", 5, julian_day, iflag, houses_degree_ut, point_type, calculated_planets, active_points)
|
|
695
696
|
|
|
696
697
|
# Calculate Saturn
|
|
697
698
|
if should_calculate("Saturn"):
|
|
698
|
-
|
|
699
|
-
data["saturn"] = get_kerykeion_point_from_degree(saturn_deg, "Saturn", point_type=point_type)
|
|
700
|
-
data["saturn"].house = get_planet_house(saturn_deg, houses_degree_ut)
|
|
701
|
-
data["saturn"].retrograde = swe.calc_ut(julian_day, 6, iflag)[0][3] < 0
|
|
702
|
-
calculated_planets.append("Saturn")
|
|
699
|
+
cls._calculate_single_planet(data, "Saturn", 6, julian_day, iflag, houses_degree_ut, point_type, calculated_planets, active_points)
|
|
703
700
|
|
|
704
701
|
# Calculate Uranus
|
|
705
702
|
if should_calculate("Uranus"):
|
|
706
|
-
|
|
707
|
-
data["uranus"] = get_kerykeion_point_from_degree(uranus_deg, "Uranus", point_type=point_type)
|
|
708
|
-
data["uranus"].house = get_planet_house(uranus_deg, houses_degree_ut)
|
|
709
|
-
data["uranus"].retrograde = swe.calc_ut(julian_day, 7, iflag)[0][3] < 0
|
|
710
|
-
calculated_planets.append("Uranus")
|
|
703
|
+
cls._calculate_single_planet(data, "Uranus", 7, julian_day, iflag, houses_degree_ut, point_type, calculated_planets, active_points)
|
|
711
704
|
|
|
712
705
|
# Calculate Neptune
|
|
713
706
|
if should_calculate("Neptune"):
|
|
714
|
-
|
|
715
|
-
data["neptune"] = get_kerykeion_point_from_degree(neptune_deg, "Neptune", point_type=point_type)
|
|
716
|
-
data["neptune"].house = get_planet_house(neptune_deg, houses_degree_ut)
|
|
717
|
-
data["neptune"].retrograde = swe.calc_ut(julian_day, 8, iflag)[0][3] < 0
|
|
718
|
-
calculated_planets.append("Neptune")
|
|
707
|
+
cls._calculate_single_planet(data, "Neptune", 8, julian_day, iflag, houses_degree_ut, point_type, calculated_planets, active_points)
|
|
719
708
|
|
|
720
709
|
# Calculate Pluto
|
|
721
710
|
if should_calculate("Pluto"):
|
|
722
|
-
|
|
723
|
-
data["pluto"] = get_kerykeion_point_from_degree(pluto_deg, "Pluto", point_type=point_type)
|
|
724
|
-
data["pluto"].house = get_planet_house(pluto_deg, houses_degree_ut)
|
|
725
|
-
data["pluto"].retrograde = swe.calc_ut(julian_day, 9, iflag)[0][3] < 0
|
|
726
|
-
calculated_planets.append("Pluto")
|
|
711
|
+
cls._calculate_single_planet(data, "Pluto", 9, julian_day, iflag, houses_degree_ut, point_type, calculated_planets, active_points)
|
|
727
712
|
|
|
728
713
|
# ==================
|
|
729
714
|
# LUNAR NODES
|
|
@@ -731,19 +716,11 @@ class AstrologicalSubjectFactory:
|
|
|
731
716
|
|
|
732
717
|
# Calculate Mean Lunar Node
|
|
733
718
|
if should_calculate("Mean_Node"):
|
|
734
|
-
|
|
735
|
-
data["mean_node"] = get_kerykeion_point_from_degree(mean_node_deg, "Mean_Node", point_type=point_type)
|
|
736
|
-
data["mean_node"].house = get_planet_house(mean_node_deg, houses_degree_ut)
|
|
737
|
-
data["mean_node"].retrograde = swe.calc_ut(julian_day, 10, iflag)[0][3] < 0
|
|
738
|
-
calculated_planets.append("Mean_Node")
|
|
719
|
+
cls._calculate_single_planet(data, "Mean_Node", 10, julian_day, iflag, houses_degree_ut, point_type, calculated_planets, active_points)
|
|
739
720
|
|
|
740
721
|
# Calculate True Lunar Node
|
|
741
722
|
if should_calculate("True_Node"):
|
|
742
|
-
|
|
743
|
-
data["true_node"] = get_kerykeion_point_from_degree(true_node_deg, "True_Node", point_type=point_type)
|
|
744
|
-
data["true_node"].house = get_planet_house(true_node_deg, houses_degree_ut)
|
|
745
|
-
data["true_node"].retrograde = swe.calc_ut(julian_day, 11, iflag)[0][3] < 0
|
|
746
|
-
calculated_planets.append("True_Node")
|
|
723
|
+
cls._calculate_single_planet(data, "True_Node", 11, julian_day, iflag, houses_degree_ut, point_type, calculated_planets, active_points)
|
|
747
724
|
|
|
748
725
|
# Calculate Mean South Node (opposite to Mean North Node)
|
|
749
726
|
if should_calculate("Mean_South_Node") and "mean_node" in data:
|
|
@@ -771,28 +748,17 @@ class AstrologicalSubjectFactory:
|
|
|
771
748
|
|
|
772
749
|
# Calculate Mean Lilith (Mean Black Moon)
|
|
773
750
|
if should_calculate("Mean_Lilith"):
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
data["mean_lilith"].retrograde = swe.calc_ut(julian_day, 12, iflag)[0][3] < 0
|
|
779
|
-
calculated_planets.append("Mean_Lilith")
|
|
780
|
-
except Exception as e:
|
|
781
|
-
logging.error(f"Error calculating Mean Lilith: {e}")
|
|
782
|
-
active_points.remove("Mean_Lilith")
|
|
783
|
-
|
|
751
|
+
cls._calculate_single_planet(
|
|
752
|
+
data, "Mean_Lilith", 12, julian_day, iflag, houses_degree_ut,
|
|
753
|
+
point_type, calculated_planets, active_points
|
|
754
|
+
)
|
|
784
755
|
|
|
785
756
|
# Calculate True Lilith (Osculating Black Moon)
|
|
786
757
|
if should_calculate("True_Lilith"):
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
data["true_lilith"].retrograde = swe.calc_ut(julian_day, 13, iflag)[0][3] < 0
|
|
792
|
-
calculated_planets.append("True_Lilith")
|
|
793
|
-
except Exception as e:
|
|
794
|
-
logging.error(f"Error calculating True Lilith: {e}")
|
|
795
|
-
active_points.remove("True_Lilith")
|
|
758
|
+
cls._calculate_single_planet(
|
|
759
|
+
data, "True_Lilith", 13, julian_day, iflag, houses_degree_ut,
|
|
760
|
+
point_type, calculated_planets, active_points
|
|
761
|
+
)
|
|
796
762
|
|
|
797
763
|
# ==================
|
|
798
764
|
# SPECIAL POINTS
|
|
@@ -800,39 +766,24 @@ class AstrologicalSubjectFactory:
|
|
|
800
766
|
|
|
801
767
|
# Calculate Earth - useful for heliocentric charts
|
|
802
768
|
if should_calculate("Earth"):
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
data["earth"].retrograde = swe.calc_ut(julian_day, 14, iflag)[0][3] < 0
|
|
808
|
-
calculated_planets.append("Earth")
|
|
809
|
-
except Exception as e:
|
|
810
|
-
logging.error(f"Error calculating Earth position: {e}")
|
|
811
|
-
active_points.remove("Earth")
|
|
769
|
+
cls._calculate_single_planet(
|
|
770
|
+
data, "Earth", 14, julian_day, iflag, houses_degree_ut,
|
|
771
|
+
point_type, calculated_planets, active_points
|
|
772
|
+
)
|
|
812
773
|
|
|
813
774
|
# Calculate Chiron
|
|
814
775
|
if should_calculate("Chiron"):
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
data["chiron"].retrograde = swe.calc_ut(julian_day, 15, iflag)[0][3] < 0
|
|
820
|
-
calculated_planets.append("Chiron")
|
|
821
|
-
except Exception as e:
|
|
822
|
-
logging.error(f"Error calculating Chiron position: {e}")
|
|
823
|
-
active_points.remove("Chiron")
|
|
776
|
+
cls._calculate_single_planet(
|
|
777
|
+
data, "Chiron", 15, julian_day, iflag, houses_degree_ut,
|
|
778
|
+
point_type, calculated_planets, active_points
|
|
779
|
+
)
|
|
824
780
|
|
|
825
781
|
# Calculate Pholus
|
|
826
782
|
if should_calculate("Pholus"):
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
data["pholus"].retrograde = swe.calc_ut(julian_day, 16, iflag)[0][3] < 0
|
|
832
|
-
calculated_planets.append("Pholus")
|
|
833
|
-
except Exception as e:
|
|
834
|
-
logging.error(f"Error calculating Pholus position: {e}")
|
|
835
|
-
active_points.remove("Pholus")
|
|
783
|
+
cls._calculate_single_planet(
|
|
784
|
+
data, "Pholus", 16, julian_day, iflag, houses_degree_ut,
|
|
785
|
+
point_type, calculated_planets, active_points
|
|
786
|
+
)
|
|
836
787
|
|
|
837
788
|
# ==================
|
|
838
789
|
# ASTEROIDS
|
|
@@ -840,51 +791,31 @@ class AstrologicalSubjectFactory:
|
|
|
840
791
|
|
|
841
792
|
# Calculate Ceres
|
|
842
793
|
if should_calculate("Ceres"):
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
data["ceres"].retrograde = swe.calc_ut(julian_day, 17, iflag)[0][3] < 0
|
|
848
|
-
calculated_planets.append("Ceres")
|
|
849
|
-
except Exception as e:
|
|
850
|
-
logging.error(f"Error calculating Ceres position: {e}")
|
|
851
|
-
active_points.remove("Ceres")
|
|
794
|
+
cls._calculate_single_planet(
|
|
795
|
+
data, "Ceres", 17, julian_day, iflag, houses_degree_ut,
|
|
796
|
+
point_type, calculated_planets, active_points
|
|
797
|
+
)
|
|
852
798
|
|
|
853
799
|
# Calculate Pallas
|
|
854
800
|
if should_calculate("Pallas"):
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
data["pallas"].retrograde = swe.calc_ut(julian_day, 18, iflag)[0][3] < 0
|
|
860
|
-
calculated_planets.append("Pallas")
|
|
861
|
-
except Exception as e:
|
|
862
|
-
logging.error(f"Error calculating Pallas position: {e}")
|
|
863
|
-
active_points.remove("Pallas")
|
|
801
|
+
cls._calculate_single_planet(
|
|
802
|
+
data, "Pallas", 18, julian_day, iflag, houses_degree_ut,
|
|
803
|
+
point_type, calculated_planets, active_points
|
|
804
|
+
)
|
|
864
805
|
|
|
865
806
|
# Calculate Juno
|
|
866
807
|
if should_calculate("Juno"):
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
data["juno"].retrograde = swe.calc_ut(julian_day, 19, iflag)[0][3] < 0
|
|
872
|
-
calculated_planets.append("Juno")
|
|
873
|
-
except Exception as e:
|
|
874
|
-
logging.error(f"Error calculating Juno position: {e}")
|
|
875
|
-
active_points.remove("Juno")
|
|
808
|
+
cls._calculate_single_planet(
|
|
809
|
+
data, "Juno", 19, julian_day, iflag, houses_degree_ut,
|
|
810
|
+
point_type, calculated_planets, active_points
|
|
811
|
+
)
|
|
876
812
|
|
|
877
813
|
# Calculate Vesta
|
|
878
814
|
if should_calculate("Vesta"):
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
data["vesta"].retrograde = swe.calc_ut(julian_day, 20, iflag)[0][3] < 0
|
|
884
|
-
calculated_planets.append("Vesta")
|
|
885
|
-
except Exception as e:
|
|
886
|
-
logging.error(f"Error calculating Vesta position: {e}")
|
|
887
|
-
active_points.remove("Vesta")
|
|
815
|
+
cls._calculate_single_planet(
|
|
816
|
+
data, "Vesta", 20, julian_day, iflag, houses_degree_ut,
|
|
817
|
+
point_type, calculated_planets, active_points
|
|
818
|
+
)
|
|
888
819
|
|
|
889
820
|
# ==================
|
|
890
821
|
# TRANS-NEPTUNIAN OBJECTS
|
|
@@ -893,10 +824,10 @@ class AstrologicalSubjectFactory:
|
|
|
893
824
|
# Calculate Eris
|
|
894
825
|
if should_calculate("Eris"):
|
|
895
826
|
try:
|
|
896
|
-
|
|
897
|
-
data["eris"] = get_kerykeion_point_from_degree(
|
|
898
|
-
data["eris"].house = get_planet_house(
|
|
899
|
-
data["eris"].retrograde =
|
|
827
|
+
eris_calc = swe.calc_ut(julian_day, swe.AST_OFFSET + 136199, iflag)[0]
|
|
828
|
+
data["eris"] = get_kerykeion_point_from_degree(eris_calc[0], "Eris", point_type=point_type)
|
|
829
|
+
data["eris"].house = get_planet_house(eris_calc[0], houses_degree_ut)
|
|
830
|
+
data["eris"].retrograde = eris_calc[3] < 0
|
|
900
831
|
calculated_planets.append("Eris")
|
|
901
832
|
except Exception as e:
|
|
902
833
|
logging.warning(f"Could not calculate Eris position: {e}")
|
|
@@ -905,10 +836,10 @@ class AstrologicalSubjectFactory:
|
|
|
905
836
|
# Calculate Sedna
|
|
906
837
|
if should_calculate("Sedna"):
|
|
907
838
|
try:
|
|
908
|
-
|
|
909
|
-
data["sedna"] = get_kerykeion_point_from_degree(
|
|
910
|
-
data["sedna"].house = get_planet_house(
|
|
911
|
-
data["sedna"].retrograde =
|
|
839
|
+
sedna_calc = swe.calc_ut(julian_day, swe.AST_OFFSET + 90377, iflag)[0]
|
|
840
|
+
data["sedna"] = get_kerykeion_point_from_degree(sedna_calc[0], "Sedna", point_type=point_type)
|
|
841
|
+
data["sedna"].house = get_planet_house(sedna_calc[0], houses_degree_ut)
|
|
842
|
+
data["sedna"].retrograde = sedna_calc[3] < 0
|
|
912
843
|
calculated_planets.append("Sedna")
|
|
913
844
|
except Exception as e:
|
|
914
845
|
logging.warning(f"Could not calculate Sedna position: {e}")
|
|
@@ -917,10 +848,10 @@ class AstrologicalSubjectFactory:
|
|
|
917
848
|
# Calculate Haumea
|
|
918
849
|
if should_calculate("Haumea"):
|
|
919
850
|
try:
|
|
920
|
-
|
|
921
|
-
data["haumea"] = get_kerykeion_point_from_degree(
|
|
922
|
-
data["haumea"].house = get_planet_house(
|
|
923
|
-
data["haumea"].retrograde =
|
|
851
|
+
haumea_calc = swe.calc_ut(julian_day, swe.AST_OFFSET + 136108, iflag)[0]
|
|
852
|
+
data["haumea"] = get_kerykeion_point_from_degree(haumea_calc[0], "Haumea", point_type=point_type)
|
|
853
|
+
data["haumea"].house = get_planet_house(haumea_calc[0], houses_degree_ut)
|
|
854
|
+
data["haumea"].retrograde = haumea_calc[3] < 0
|
|
924
855
|
calculated_planets.append("Haumea")
|
|
925
856
|
except Exception as e:
|
|
926
857
|
logging.warning(f"Could not calculate Haumea position: {e}")
|
|
@@ -929,10 +860,10 @@ class AstrologicalSubjectFactory:
|
|
|
929
860
|
# Calculate Makemake
|
|
930
861
|
if should_calculate("Makemake"):
|
|
931
862
|
try:
|
|
932
|
-
|
|
933
|
-
data["makemake"] = get_kerykeion_point_from_degree(
|
|
934
|
-
data["makemake"].house = get_planet_house(
|
|
935
|
-
data["makemake"].retrograde =
|
|
863
|
+
makemake_calc = swe.calc_ut(julian_day, swe.AST_OFFSET + 136472, iflag)[0]
|
|
864
|
+
data["makemake"] = get_kerykeion_point_from_degree(makemake_calc[0], "Makemake", point_type=point_type)
|
|
865
|
+
data["makemake"].house = get_planet_house(makemake_calc[0], houses_degree_ut)
|
|
866
|
+
data["makemake"].retrograde = makemake_calc[3] < 0
|
|
936
867
|
calculated_planets.append("Makemake")
|
|
937
868
|
except Exception as e:
|
|
938
869
|
logging.warning(f"Could not calculate Makemake position: {e}")
|
|
@@ -941,10 +872,10 @@ class AstrologicalSubjectFactory:
|
|
|
941
872
|
# Calculate Ixion
|
|
942
873
|
if should_calculate("Ixion"):
|
|
943
874
|
try:
|
|
944
|
-
|
|
945
|
-
data["ixion"] = get_kerykeion_point_from_degree(
|
|
946
|
-
data["ixion"].house = get_planet_house(
|
|
947
|
-
data["ixion"].retrograde =
|
|
875
|
+
ixion_calc = swe.calc_ut(julian_day, swe.AST_OFFSET + 28978, iflag)[0]
|
|
876
|
+
data["ixion"] = get_kerykeion_point_from_degree(ixion_calc[0], "Ixion", point_type=point_type)
|
|
877
|
+
data["ixion"].house = get_planet_house(ixion_calc[0], houses_degree_ut)
|
|
878
|
+
data["ixion"].retrograde = ixion_calc[3] < 0
|
|
948
879
|
calculated_planets.append("Ixion")
|
|
949
880
|
except Exception as e:
|
|
950
881
|
logging.warning(f"Could not calculate Ixion position: {e}")
|
|
@@ -953,10 +884,10 @@ class AstrologicalSubjectFactory:
|
|
|
953
884
|
# Calculate Orcus
|
|
954
885
|
if should_calculate("Orcus"):
|
|
955
886
|
try:
|
|
956
|
-
|
|
957
|
-
data["orcus"] = get_kerykeion_point_from_degree(
|
|
958
|
-
data["orcus"].house = get_planet_house(
|
|
959
|
-
data["orcus"].retrograde =
|
|
887
|
+
orcus_calc = swe.calc_ut(julian_day, swe.AST_OFFSET + 90482, iflag)[0]
|
|
888
|
+
data["orcus"] = get_kerykeion_point_from_degree(orcus_calc[0], "Orcus", point_type=point_type)
|
|
889
|
+
data["orcus"].house = get_planet_house(orcus_calc[0], houses_degree_ut)
|
|
890
|
+
data["orcus"].retrograde = orcus_calc[3] < 0
|
|
960
891
|
calculated_planets.append("Orcus")
|
|
961
892
|
except Exception as e:
|
|
962
893
|
logging.warning(f"Could not calculate Orcus position: {e}")
|
|
@@ -965,10 +896,10 @@ class AstrologicalSubjectFactory:
|
|
|
965
896
|
# Calculate Quaoar
|
|
966
897
|
if should_calculate("Quaoar"):
|
|
967
898
|
try:
|
|
968
|
-
|
|
969
|
-
data["quaoar"] = get_kerykeion_point_from_degree(
|
|
970
|
-
data["quaoar"].house = get_planet_house(
|
|
971
|
-
data["quaoar"].retrograde =
|
|
899
|
+
quaoar_calc = swe.calc_ut(julian_day, swe.AST_OFFSET + 50000, iflag)[0]
|
|
900
|
+
data["quaoar"] = get_kerykeion_point_from_degree(quaoar_calc[0], "Quaoar", point_type=point_type)
|
|
901
|
+
data["quaoar"].house = get_planet_house(quaoar_calc[0], houses_degree_ut)
|
|
902
|
+
data["quaoar"].retrograde = quaoar_calc[3] < 0
|
|
972
903
|
calculated_planets.append("Quaoar")
|
|
973
904
|
except Exception as e:
|
|
974
905
|
logging.warning(f"Could not calculate Quaoar position: {e}")
|
|
@@ -1012,12 +943,34 @@ class AstrologicalSubjectFactory:
|
|
|
1012
943
|
|
|
1013
944
|
# Calculate Pars Fortunae (Part of Fortune)
|
|
1014
945
|
if should_calculate("Pars_Fortunae"):
|
|
946
|
+
# Auto-activate required points with notification
|
|
947
|
+
required_points: List[AstrologicalPoint] = ["Ascendant", "Sun", "Moon"]
|
|
948
|
+
missing_points = [point for point in required_points if point not in active_points]
|
|
949
|
+
if missing_points:
|
|
950
|
+
logging.info(f"Automatically adding required points for Pars_Fortunae: {missing_points}")
|
|
951
|
+
active_points.extend(cast(List[AstrologicalPoint], missing_points))
|
|
952
|
+
# Recalculate the missing points
|
|
953
|
+
for point in missing_points:
|
|
954
|
+
if point == "Sun" and point not in data:
|
|
955
|
+
sun_calc = swe.calc_ut(julian_day, 0, iflag)[0]
|
|
956
|
+
data["sun"] = get_kerykeion_point_from_degree(sun_calc[0], "Sun", point_type=point_type)
|
|
957
|
+
data["sun"].house = get_planet_house(sun_calc[0], houses_degree_ut)
|
|
958
|
+
data["sun"].retrograde = sun_calc[3] < 0
|
|
959
|
+
elif point == "Moon" and point not in data:
|
|
960
|
+
moon_calc = swe.calc_ut(julian_day, 1, iflag)[0]
|
|
961
|
+
data["moon"] = get_kerykeion_point_from_degree(moon_calc[0], "Moon", point_type=point_type)
|
|
962
|
+
data["moon"].house = get_planet_house(moon_calc[0], houses_degree_ut)
|
|
963
|
+
data["moon"].retrograde = moon_calc[3] < 0
|
|
964
|
+
|
|
1015
965
|
# Check if required points are available
|
|
1016
966
|
if all(k in data for k in ["ascendant", "sun", "moon"]):
|
|
1017
967
|
# Different calculation for day and night charts
|
|
1018
968
|
# Day birth (Sun above horizon): ASC + Moon - Sun
|
|
1019
969
|
# Night birth (Sun below horizon): ASC + Sun - Moon
|
|
1020
|
-
|
|
970
|
+
if data["sun"].house:
|
|
971
|
+
is_day_chart = get_house_number(data["sun"].house) < 7 # Houses 1-6 are above horizon
|
|
972
|
+
else:
|
|
973
|
+
is_day_chart = True # Default to day chart if house is None
|
|
1021
974
|
|
|
1022
975
|
if is_day_chart:
|
|
1023
976
|
fortune_deg = math.fmod(data["ascendant"].abs_pos + data["moon"].abs_pos - data["sun"].abs_pos, 360)
|
|
@@ -1031,11 +984,33 @@ class AstrologicalSubjectFactory:
|
|
|
1031
984
|
|
|
1032
985
|
# Calculate Pars Spiritus (Part of Spirit)
|
|
1033
986
|
if should_calculate("Pars_Spiritus"):
|
|
987
|
+
# Auto-activate required points with notification
|
|
988
|
+
required_points: List[AstrologicalPoint] = ["Ascendant", "Sun", "Moon"]
|
|
989
|
+
missing_points = [point for point in required_points if point not in active_points]
|
|
990
|
+
if missing_points:
|
|
991
|
+
logging.info(f"Automatically adding required points for Pars_Spiritus: {missing_points}")
|
|
992
|
+
active_points.extend(cast(List[AstrologicalPoint], missing_points))
|
|
993
|
+
# Recalculate the missing points
|
|
994
|
+
for point in missing_points:
|
|
995
|
+
if point == "Sun" and point not in data:
|
|
996
|
+
sun_calc = swe.calc_ut(julian_day, 0, iflag)[0]
|
|
997
|
+
data["sun"] = get_kerykeion_point_from_degree(sun_calc[0], "Sun", point_type=point_type)
|
|
998
|
+
data["sun"].house = get_planet_house(sun_calc[0], houses_degree_ut)
|
|
999
|
+
data["sun"].retrograde = sun_calc[3] < 0
|
|
1000
|
+
elif point == "Moon" and point not in data:
|
|
1001
|
+
moon_calc = swe.calc_ut(julian_day, 1, iflag)[0]
|
|
1002
|
+
data["moon"] = get_kerykeion_point_from_degree(moon_calc[0], "Moon", point_type=point_type)
|
|
1003
|
+
data["moon"].house = get_planet_house(moon_calc[0], houses_degree_ut)
|
|
1004
|
+
data["moon"].retrograde = moon_calc[3] < 0
|
|
1005
|
+
|
|
1034
1006
|
# Check if required points are available
|
|
1035
1007
|
if all(k in data for k in ["ascendant", "sun", "moon"]):
|
|
1036
1008
|
# Day birth: ASC + Sun - Moon
|
|
1037
1009
|
# Night birth: ASC + Moon - Sun
|
|
1038
|
-
|
|
1010
|
+
if data["sun"].house:
|
|
1011
|
+
is_day_chart = get_house_number(data["sun"].house) < 7
|
|
1012
|
+
else:
|
|
1013
|
+
is_day_chart = True # Default to day chart if house is None
|
|
1039
1014
|
|
|
1040
1015
|
if is_day_chart:
|
|
1041
1016
|
spirit_deg = math.fmod(data["ascendant"].abs_pos + data["sun"].abs_pos - data["moon"].abs_pos, 360)
|
|
@@ -1049,19 +1024,56 @@ class AstrologicalSubjectFactory:
|
|
|
1049
1024
|
|
|
1050
1025
|
# Calculate Pars Amoris (Part of Eros/Love)
|
|
1051
1026
|
if should_calculate("Pars_Amoris"):
|
|
1027
|
+
# Auto-activate required points with notification
|
|
1028
|
+
required_points: List[AstrologicalPoint] = ["Ascendant", "Venus", "Sun"]
|
|
1029
|
+
missing_points = [point for point in required_points if point not in active_points]
|
|
1030
|
+
if missing_points:
|
|
1031
|
+
logging.info(f"Automatically adding required points for Pars_Amoris: {missing_points}")
|
|
1032
|
+
active_points.extend(cast(List[AstrologicalPoint], missing_points))
|
|
1033
|
+
# Recalculate the missing points
|
|
1034
|
+
for point in missing_points:
|
|
1035
|
+
if point == "Sun" and point not in data:
|
|
1036
|
+
sun_calc = swe.calc_ut(julian_day, 0, iflag)[0]
|
|
1037
|
+
data["sun"] = get_kerykeion_point_from_degree(sun_calc[0], "Sun", point_type=point_type)
|
|
1038
|
+
data["sun"].house = get_planet_house(sun_calc[0], houses_degree_ut)
|
|
1039
|
+
data["sun"].retrograde = sun_calc[3] < 0
|
|
1040
|
+
elif point == "Venus" and point not in data:
|
|
1041
|
+
venus_calc = swe.calc_ut(julian_day, 3, iflag)[0]
|
|
1042
|
+
data["venus"] = get_kerykeion_point_from_degree(venus_calc[0], "Venus", point_type=point_type)
|
|
1043
|
+
data["venus"].house = get_planet_house(venus_calc[0], houses_degree_ut)
|
|
1044
|
+
data["venus"].retrograde = venus_calc[3] < 0
|
|
1045
|
+
|
|
1052
1046
|
# Check if required points are available
|
|
1053
|
-
if all(k in data for k in ["ascendant", "venus"]):
|
|
1047
|
+
if all(k in data for k in ["ascendant", "venus", "sun"]):
|
|
1054
1048
|
# ASC + Venus - Sun
|
|
1055
|
-
|
|
1056
|
-
amoris_deg = math.fmod(data["ascendant"].abs_pos + data["venus"].abs_pos - data["sun"].abs_pos, 360)
|
|
1049
|
+
amoris_deg = math.fmod(data["ascendant"].abs_pos + data["venus"].abs_pos - data["sun"].abs_pos, 360)
|
|
1057
1050
|
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1051
|
+
data["pars_amoris"] = get_kerykeion_point_from_degree(amoris_deg, "Pars_Amoris", point_type=point_type)
|
|
1052
|
+
data["pars_amoris"].house = get_planet_house(amoris_deg, houses_degree_ut)
|
|
1053
|
+
data["pars_amoris"].retrograde = False
|
|
1054
|
+
calculated_planets.append("Pars_Amoris")
|
|
1062
1055
|
|
|
1063
1056
|
# Calculate Pars Fidei (Part of Faith)
|
|
1064
1057
|
if should_calculate("Pars_Fidei"):
|
|
1058
|
+
# Auto-activate required points with notification
|
|
1059
|
+
required_points: List[AstrologicalPoint] = ["Ascendant", "Jupiter", "Saturn"]
|
|
1060
|
+
missing_points = [point for point in required_points if point not in active_points]
|
|
1061
|
+
if missing_points:
|
|
1062
|
+
logging.info(f"Automatically adding required points for Pars_Fidei: {missing_points}")
|
|
1063
|
+
active_points.extend(cast(List[AstrologicalPoint], missing_points))
|
|
1064
|
+
# Recalculate the missing points
|
|
1065
|
+
for point in missing_points:
|
|
1066
|
+
if point == "Jupiter" and point not in data:
|
|
1067
|
+
jupiter_calc = swe.calc_ut(julian_day, 5, iflag)[0]
|
|
1068
|
+
data["jupiter"] = get_kerykeion_point_from_degree(jupiter_calc[0], "Jupiter", point_type=point_type)
|
|
1069
|
+
data["jupiter"].house = get_planet_house(jupiter_calc[0], houses_degree_ut)
|
|
1070
|
+
data["jupiter"].retrograde = jupiter_calc[3] < 0
|
|
1071
|
+
elif point == "Saturn" and point not in data:
|
|
1072
|
+
saturn_calc = swe.calc_ut(julian_day, 6, iflag)[0]
|
|
1073
|
+
data["saturn"] = get_kerykeion_point_from_degree(saturn_calc[0], "Saturn", point_type=point_type)
|
|
1074
|
+
data["saturn"].house = get_planet_house(saturn_calc[0], houses_degree_ut)
|
|
1075
|
+
data["saturn"].retrograde = saturn_calc[3] < 0
|
|
1076
|
+
|
|
1065
1077
|
# Check if required points are available
|
|
1066
1078
|
if all(k in data for k in ["ascendant", "jupiter", "saturn"]):
|
|
1067
1079
|
# ASC + Jupiter - Saturn
|