kerykeion 5.0.0a10__py3-none-any.whl → 5.0.0a11__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 +2 -6
- kerykeion/aspects/natal_aspects_factory.py +3 -4
- kerykeion/aspects/synastry_aspects_factory.py +69 -28
- kerykeion/astrological_subject_factory.py +683 -77
- kerykeion/charts/draw_planets.py +584 -343
- kerykeion/charts/kerykeion_chart_svg.py +2 -7
- kerykeion/charts/templates/wheel_only.xml +1 -1
- kerykeion/composite_subject_factory.py +228 -9
- kerykeion/ephemeris_data_factory.py +431 -0
- kerykeion/fetch_geonames.py +27 -8
- kerykeion/kr_types/kerykeion_exception.py +6 -0
- kerykeion/kr_types/kr_models.py +55 -2
- kerykeion/planetary_return_factory.py +532 -32
- kerykeion/relationship_score_factory.py +96 -42
- kerykeion/report.py +7 -0
- kerykeion/transits_time_range_factory.py +293 -0
- kerykeion/utilities.py +129 -67
- {kerykeion-5.0.0a10.dist-info → kerykeion-5.0.0a11.dist-info}/METADATA +1 -1
- {kerykeion-5.0.0a10.dist-info → kerykeion-5.0.0a11.dist-info}/RECORD +21 -24
- kerykeion/charts/draw_planets_v2.py +0 -648
- kerykeion/charts/draw_planets_v3.py +0 -679
- kerykeion/enums.py +0 -57
- kerykeion/ephemeris_data.py +0 -238
- kerykeion/transits_time_range.py +0 -128
- {kerykeion-5.0.0a10.dist-info → kerykeion-5.0.0a11.dist-info}/WHEEL +0 -0
- {kerykeion-5.0.0a10.dist-info → kerykeion-5.0.0a11.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,44 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""
|
|
3
|
-
|
|
3
|
+
Relationship Score Factory Module
|
|
4
|
+
|
|
5
|
+
This module calculates relationship scores between two astrological subjects using the
|
|
6
|
+
Ciro Discepolo method. It analyzes synastry aspects to generate numerical compatibility
|
|
7
|
+
scores with descriptive categories.
|
|
8
|
+
|
|
9
|
+
Key Features:
|
|
10
|
+
- Point-based scoring system using synastry aspects
|
|
11
|
+
- Configurable major/minor aspect filtering
|
|
12
|
+
- Orbital precision weighting
|
|
13
|
+
- Categorical score descriptions
|
|
14
|
+
|
|
15
|
+
Score Categories:
|
|
16
|
+
- 0-5: Minimal relationship
|
|
17
|
+
- 5-10: Medium relationship
|
|
18
|
+
- 10-15: Important relationship
|
|
19
|
+
- 15-20: Very important relationship
|
|
20
|
+
- 20-30: Exceptional relationship
|
|
21
|
+
- 30+: Rare exceptional relationship
|
|
22
|
+
|
|
23
|
+
Classes:
|
|
24
|
+
RelationshipScoreFactory: Main factory for calculating relationship scores
|
|
25
|
+
|
|
26
|
+
Example:
|
|
27
|
+
>>> from kerykeion import AstrologicalSubjectFactory
|
|
28
|
+
>>> from kerykeion.relationship_score_factory import RelationshipScoreFactory
|
|
29
|
+
>>>
|
|
30
|
+
>>> person1 = AstrologicalSubjectFactory.from_birth_data("John", 1990, 5, 15, 12, 0, "New York", "US")
|
|
31
|
+
>>> person2 = AstrologicalSubjectFactory.from_birth_data("Jane", 1988, 8, 22, 14, 30, "London", "GB")
|
|
32
|
+
>>> factory = RelationshipScoreFactory(person1, person2)
|
|
33
|
+
>>> score = factory.get_relationship_score()
|
|
34
|
+
>>> print(f"Score: {score.score_value} ({score.score_description})")
|
|
35
|
+
|
|
36
|
+
Reference:
|
|
37
|
+
Ciro Discepolo Method: http://www.cirodiscepolo.it/Articoli/Discepoloele.htm
|
|
38
|
+
|
|
39
|
+
Author: Giacomo Battaglia
|
|
40
|
+
Copyright: (C) 2025 Kerykeion Project
|
|
41
|
+
License: AGPL-3.0
|
|
4
42
|
"""
|
|
5
43
|
|
|
6
44
|
from kerykeion import AstrologicalSubjectFactory
|
|
@@ -22,21 +60,26 @@ VENUS_MARS_ASPECT_POINTS = 4
|
|
|
22
60
|
|
|
23
61
|
class RelationshipScoreFactory:
|
|
24
62
|
"""
|
|
25
|
-
Calculates
|
|
63
|
+
Calculates relationship scores between two subjects using the Ciro Discepolo method.
|
|
26
64
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- 5 to 10: Medium relationship
|
|
30
|
-
- 10 to 15: Important relationship
|
|
31
|
-
- 15 to 20: Very important relationship
|
|
32
|
-
- 20 to 35: Exceptional relationship
|
|
33
|
-
- 30 and above: Rare Exceptional relationship
|
|
65
|
+
The scoring system evaluates synastry aspects between planetary positions to generate
|
|
66
|
+
numerical compatibility scores with categorical descriptions.
|
|
34
67
|
|
|
35
|
-
|
|
68
|
+
Score Ranges:
|
|
69
|
+
- 0-5: Minimal relationship
|
|
70
|
+
- 5-10: Medium relationship
|
|
71
|
+
- 10-15: Important relationship
|
|
72
|
+
- 15-20: Very important relationship
|
|
73
|
+
- 20-30: Exceptional relationship
|
|
74
|
+
- 30+: Rare exceptional relationship
|
|
36
75
|
|
|
37
76
|
Args:
|
|
38
|
-
first_subject (AstrologicalSubjectModel): First subject
|
|
39
|
-
second_subject (AstrologicalSubjectModel): Second subject
|
|
77
|
+
first_subject (AstrologicalSubjectModel): First astrological subject
|
|
78
|
+
second_subject (AstrologicalSubjectModel): Second astrological subject
|
|
79
|
+
use_only_major_aspects (bool, optional): Filter to major aspects only. Defaults to True.
|
|
80
|
+
|
|
81
|
+
Reference:
|
|
82
|
+
http://www.cirodiscepolo.it/Articoli/Discepoloele.htm
|
|
40
83
|
"""
|
|
41
84
|
|
|
42
85
|
SCORE_MAPPING = [
|
|
@@ -68,7 +111,10 @@ class RelationshipScoreFactory:
|
|
|
68
111
|
|
|
69
112
|
def _evaluate_destiny_sign(self):
|
|
70
113
|
"""
|
|
71
|
-
|
|
114
|
+
Checks if subjects share the same sun sign quality and adds points.
|
|
115
|
+
|
|
116
|
+
Adds 5 points if both subjects have sun signs with matching quality
|
|
117
|
+
(cardinal, fixed, or mutable).
|
|
72
118
|
"""
|
|
73
119
|
if self.first_subject.sun["quality"] == self.second_subject.sun["quality"]: # type: ignore
|
|
74
120
|
self.is_destiny_sign = True
|
|
@@ -77,11 +123,11 @@ class RelationshipScoreFactory:
|
|
|
77
123
|
|
|
78
124
|
def _evaluate_aspect(self, aspect, points):
|
|
79
125
|
"""
|
|
80
|
-
|
|
126
|
+
Processes an aspect and adds points to the total score.
|
|
81
127
|
|
|
82
128
|
Args:
|
|
83
|
-
aspect (dict): Aspect
|
|
84
|
-
points (int): Points to add
|
|
129
|
+
aspect (dict): Aspect data containing planetary positions and geometry
|
|
130
|
+
points (int): Points to add to the total score
|
|
85
131
|
"""
|
|
86
132
|
if self.use_only_major_aspects and aspect["aspect"] not in self.MAJOR_ASPECTS:
|
|
87
133
|
return
|
|
@@ -99,12 +145,12 @@ class RelationshipScoreFactory:
|
|
|
99
145
|
|
|
100
146
|
def _evaluate_sun_sun_main_aspect(self, aspect):
|
|
101
147
|
"""
|
|
102
|
-
Evaluates Sun-Sun
|
|
103
|
-
|
|
104
|
-
|
|
148
|
+
Evaluates Sun-Sun conjunction, opposition, or square aspects.
|
|
149
|
+
|
|
150
|
+
Adds 8 points for standard orbs, 11 points for tight orbs (≤2°).
|
|
105
151
|
|
|
106
152
|
Args:
|
|
107
|
-
aspect (dict): Aspect
|
|
153
|
+
aspect (dict): Aspect data
|
|
108
154
|
"""
|
|
109
155
|
if aspect["p1_name"] == "Sun" and aspect["p2_name"] == "Sun" and aspect["aspect"] in {"conjunction", "opposition", "square"}:
|
|
110
156
|
points = MAJOR_ASPECT_POINTS_HIGH_PRECISION if aspect["orbit"] <= HIGH_PRECISION_ORBIT_THRESHOLD else MAJOR_ASPECT_POINTS_STANDARD
|
|
@@ -112,12 +158,12 @@ class RelationshipScoreFactory:
|
|
|
112
158
|
|
|
113
159
|
def _evaluate_sun_moon_conjunction(self, aspect):
|
|
114
160
|
"""
|
|
115
|
-
Evaluates Sun-Moon
|
|
116
|
-
|
|
117
|
-
|
|
161
|
+
Evaluates Sun-Moon conjunction aspects.
|
|
162
|
+
|
|
163
|
+
Adds 8 points for standard orbs, 11 points for tight orbs (≤2°).
|
|
118
164
|
|
|
119
165
|
Args:
|
|
120
|
-
aspect (dict): Aspect
|
|
166
|
+
aspect (dict): Aspect data
|
|
121
167
|
"""
|
|
122
168
|
if {aspect["p1_name"], aspect["p2_name"]} == {"Moon", "Sun"} and aspect["aspect"] == "conjunction":
|
|
123
169
|
points = MAJOR_ASPECT_POINTS_HIGH_PRECISION if aspect["orbit"] <= HIGH_PRECISION_ORBIT_THRESHOLD else MAJOR_ASPECT_POINTS_STANDARD
|
|
@@ -125,11 +171,12 @@ class RelationshipScoreFactory:
|
|
|
125
171
|
|
|
126
172
|
def _evaluate_sun_sun_other_aspects(self, aspect):
|
|
127
173
|
"""
|
|
128
|
-
Evaluates Sun-Sun aspects
|
|
129
|
-
|
|
174
|
+
Evaluates Sun-Sun aspects other than conjunction, opposition, or square.
|
|
175
|
+
|
|
176
|
+
Adds 4 points for any qualifying aspect.
|
|
130
177
|
|
|
131
178
|
Args:
|
|
132
|
-
aspect (dict): Aspect
|
|
179
|
+
aspect (dict): Aspect data
|
|
133
180
|
"""
|
|
134
181
|
if aspect["p1_name"] == "Sun" and aspect["p2_name"] == "Sun" and aspect["aspect"] not in {"conjunction", "opposition", "square"}:
|
|
135
182
|
points = MINOR_ASPECT_POINTS
|
|
@@ -137,11 +184,12 @@ class RelationshipScoreFactory:
|
|
|
137
184
|
|
|
138
185
|
def _evaluate_sun_moon_other_aspects(self, aspect):
|
|
139
186
|
"""
|
|
140
|
-
Evaluates Sun-Moon aspects
|
|
141
|
-
|
|
187
|
+
Evaluates Sun-Moon aspects other than conjunctions.
|
|
188
|
+
|
|
189
|
+
Adds 4 points for any qualifying aspect.
|
|
142
190
|
|
|
143
191
|
Args:
|
|
144
|
-
aspect (dict): Aspect
|
|
192
|
+
aspect (dict): Aspect data
|
|
145
193
|
"""
|
|
146
194
|
if {aspect["p1_name"], aspect["p2_name"]} == {"Moon", "Sun"} and aspect["aspect"] != "conjunction":
|
|
147
195
|
points = MINOR_ASPECT_POINTS
|
|
@@ -149,11 +197,12 @@ class RelationshipScoreFactory:
|
|
|
149
197
|
|
|
150
198
|
def _evaluate_sun_ascendant_aspect(self, aspect):
|
|
151
199
|
"""
|
|
152
|
-
Evaluates Sun-Ascendant aspects
|
|
153
|
-
|
|
200
|
+
Evaluates Sun-Ascendant aspects.
|
|
201
|
+
|
|
202
|
+
Adds 4 points for any aspect between Sun and Ascendant.
|
|
154
203
|
|
|
155
204
|
Args:
|
|
156
|
-
aspect (dict): Aspect
|
|
205
|
+
aspect (dict): Aspect data
|
|
157
206
|
"""
|
|
158
207
|
if {aspect["p1_name"], aspect["p2_name"]} == {"Sun", "Ascendant"}:
|
|
159
208
|
points = SUN_ASCENDANT_ASPECT_POINTS
|
|
@@ -161,11 +210,12 @@ class RelationshipScoreFactory:
|
|
|
161
210
|
|
|
162
211
|
def _evaluate_moon_ascendant_aspect(self, aspect):
|
|
163
212
|
"""
|
|
164
|
-
Evaluates Moon-Ascendant aspects
|
|
165
|
-
|
|
213
|
+
Evaluates Moon-Ascendant aspects.
|
|
214
|
+
|
|
215
|
+
Adds 4 points for any aspect between Moon and Ascendant.
|
|
166
216
|
|
|
167
217
|
Args:
|
|
168
|
-
aspect (dict): Aspect
|
|
218
|
+
aspect (dict): Aspect data
|
|
169
219
|
"""
|
|
170
220
|
if {aspect["p1_name"], aspect["p2_name"]} == {"Moon", "Ascendant"}:
|
|
171
221
|
points = MOON_ASCENDANT_ASPECT_POINTS
|
|
@@ -173,11 +223,12 @@ class RelationshipScoreFactory:
|
|
|
173
223
|
|
|
174
224
|
def _evaluate_venus_mars_aspect(self, aspect):
|
|
175
225
|
"""
|
|
176
|
-
Evaluates Venus-Mars aspects
|
|
177
|
-
|
|
226
|
+
Evaluates Venus-Mars aspects.
|
|
227
|
+
|
|
228
|
+
Adds 4 points for any aspect between Venus and Mars.
|
|
178
229
|
|
|
179
230
|
Args:
|
|
180
|
-
aspect (dict): Aspect
|
|
231
|
+
aspect (dict): Aspect data
|
|
181
232
|
"""
|
|
182
233
|
if {aspect["p1_name"], aspect["p2_name"]} == {"Venus", "Mars"}:
|
|
183
234
|
points = VENUS_MARS_ASPECT_POINTS
|
|
@@ -185,7 +236,9 @@ class RelationshipScoreFactory:
|
|
|
185
236
|
|
|
186
237
|
def _evaluate_relationship_score_description(self):
|
|
187
238
|
"""
|
|
188
|
-
|
|
239
|
+
Determines the categorical description based on the numerical score.
|
|
240
|
+
|
|
241
|
+
Maps the total score to predefined description ranges.
|
|
189
242
|
"""
|
|
190
243
|
for description, threshold in self.SCORE_MAPPING:
|
|
191
244
|
if self.score_value < threshold:
|
|
@@ -194,10 +247,11 @@ class RelationshipScoreFactory:
|
|
|
194
247
|
|
|
195
248
|
def get_relationship_score(self):
|
|
196
249
|
"""
|
|
197
|
-
Calculates the relationship score
|
|
250
|
+
Calculates the complete relationship score using all evaluation methods.
|
|
198
251
|
|
|
199
252
|
Returns:
|
|
200
|
-
RelationshipScoreModel:
|
|
253
|
+
RelationshipScoreModel: Score object containing numerical value, description,
|
|
254
|
+
destiny sign status, contributing aspects, and subject data.
|
|
201
255
|
"""
|
|
202
256
|
self._evaluate_destiny_sign()
|
|
203
257
|
|
kerykeion/report.py
CHANGED
|
@@ -14,6 +14,12 @@ class Report:
|
|
|
14
14
|
houses_table: str
|
|
15
15
|
|
|
16
16
|
def __init__(self, instance: AstrologicalSubjectModel):
|
|
17
|
+
"""
|
|
18
|
+
Initialize a new Report instance.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
instance: The astrological subject model to create a report for.
|
|
22
|
+
"""
|
|
17
23
|
self.instance = instance
|
|
18
24
|
|
|
19
25
|
self.get_report_title()
|
|
@@ -22,6 +28,7 @@ class Report:
|
|
|
22
28
|
self.get_houses_table()
|
|
23
29
|
|
|
24
30
|
def get_report_title(self) -> None:
|
|
31
|
+
"""Generate the report title based on the subject's name."""
|
|
25
32
|
self.report_title = f"\n+- Kerykeion report for {self.instance.name} -+"
|
|
26
33
|
|
|
27
34
|
def get_data_table(self) -> None:
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Transits Time Range Factory Module
|
|
3
|
+
|
|
4
|
+
This module provides the TransitsTimeRangeFactory class for calculating astrological
|
|
5
|
+
transits over specified time periods. It compares ephemeris data points (planetary
|
|
6
|
+
positions at different times) with a natal chart to identify when celestial bodies
|
|
7
|
+
form specific angular relationships (aspects).
|
|
8
|
+
|
|
9
|
+
Key Features:
|
|
10
|
+
- Time-series transit calculations
|
|
11
|
+
- Configurable celestial points and aspect types
|
|
12
|
+
- Structured output models for data analysis
|
|
13
|
+
- Integration with ephemeris data generation
|
|
14
|
+
- Batch processing of multiple time points
|
|
15
|
+
|
|
16
|
+
The module generates comprehensive transit data by analyzing the angular relationships
|
|
17
|
+
between transiting celestial bodies and natal chart positions, creating timestamped
|
|
18
|
+
records of when specific geometric configurations occur.
|
|
19
|
+
|
|
20
|
+
Classes:
|
|
21
|
+
TransitsTimeRangeFactory: Main factory class for generating transit data
|
|
22
|
+
|
|
23
|
+
Dependencies:
|
|
24
|
+
- kerykeion.AstrologicalSubjectFactory: For creating astrological subjects
|
|
25
|
+
- kerykeion.aspects.SynastryAspectsFactory: For calculating angular relationships
|
|
26
|
+
- kerykeion.ephemeris_data_factory: For generating time-series planetary positions
|
|
27
|
+
- kerykeion.kr_types: For type definitions and model structures
|
|
28
|
+
- datetime: For date/time handling
|
|
29
|
+
|
|
30
|
+
Example:
|
|
31
|
+
Basic usage for calculating 30-day transits:
|
|
32
|
+
|
|
33
|
+
>>> from datetime import datetime, timedelta
|
|
34
|
+
>>> from kerykeion import AstrologicalSubjectFactory
|
|
35
|
+
>>> from kerykeion.ephemeris_data_factory import EphemerisDataFactory
|
|
36
|
+
>>> from kerykeion.transits_time_range_factory import TransitsTimeRangeFactory
|
|
37
|
+
>>>
|
|
38
|
+
>>> # Create natal chart
|
|
39
|
+
>>> person = AstrologicalSubjectFactory.from_birth_data(
|
|
40
|
+
... "Subject", 1990, 1, 1, 12, 0, "New York", "US"
|
|
41
|
+
... )
|
|
42
|
+
>>>
|
|
43
|
+
>>> # Generate ephemeris data
|
|
44
|
+
>>> start = datetime.now()
|
|
45
|
+
>>> end = start + timedelta(days=30)
|
|
46
|
+
>>> ephemeris_factory = EphemerisDataFactory(start, end)
|
|
47
|
+
>>> ephemeris_data = ephemeris_factory.get_ephemeris_data_as_astrological_subjects()
|
|
48
|
+
>>>
|
|
49
|
+
>>> # Calculate transits
|
|
50
|
+
>>> transit_factory = TransitsTimeRangeFactory(person, ephemeris_data)
|
|
51
|
+
>>> results = transit_factory.get_transit_moments()
|
|
52
|
+
|
|
53
|
+
Author: Giacomo Battaglia
|
|
54
|
+
Copyright: (C) 2025 Kerykeion Project
|
|
55
|
+
License: AGPL-3.0
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
from typing import Union, List
|
|
59
|
+
from datetime import datetime, timedelta
|
|
60
|
+
from kerykeion.kr_types.kr_models import AstrologicalSubjectModel
|
|
61
|
+
from kerykeion.astrological_subject_factory import AstrologicalSubjectFactory
|
|
62
|
+
from kerykeion.aspects import SynastryAspectsFactory
|
|
63
|
+
from kerykeion.ephemeris_data_factory import EphemerisDataFactory
|
|
64
|
+
from kerykeion.kr_types.kr_literals import AstrologicalPoint
|
|
65
|
+
from kerykeion.kr_types.kr_models import ActiveAspect, TransitMomentModel, TransitsTimeRangeModel
|
|
66
|
+
from kerykeion.kr_types.settings_models import KerykeionSettingsModel
|
|
67
|
+
from kerykeion.settings.config_constants import DEFAULT_ACTIVE_POINTS, DEFAULT_ACTIVE_ASPECTS
|
|
68
|
+
from pathlib import Path
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class TransitsTimeRangeFactory:
|
|
72
|
+
"""
|
|
73
|
+
Factory class for calculating astrological transits over time periods.
|
|
74
|
+
|
|
75
|
+
This class analyzes the angular relationships (aspects) between transiting
|
|
76
|
+
celestial bodies and natal chart positions across multiple time points,
|
|
77
|
+
generating structured transit data for astrological analysis.
|
|
78
|
+
|
|
79
|
+
The factory compares ephemeris data points (representing planetary positions
|
|
80
|
+
at different moments) with a natal chart to identify when specific geometric
|
|
81
|
+
configurations occur between transiting and natal celestial bodies.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
natal_chart (AstrologicalSubjectModel): The natal chart used as the reference
|
|
85
|
+
point for transit calculations. All transiting positions are compared
|
|
86
|
+
against this chart's planetary positions.
|
|
87
|
+
ephemeris_data_points (List[AstrologicalSubjectModel]): A list of astrological
|
|
88
|
+
subject models representing different moments in time, typically generated
|
|
89
|
+
by EphemerisDataFactory. Each point contains planetary positions for
|
|
90
|
+
a specific date/time.
|
|
91
|
+
active_points (List[AstrologicalPoint], optional): List of celestial bodies
|
|
92
|
+
to include in aspect calculations (e.g., Sun, Moon, planets, asteroids).
|
|
93
|
+
Defaults to DEFAULT_ACTIVE_POINTS.
|
|
94
|
+
active_aspects (List[ActiveAspect], optional): List of aspect types to
|
|
95
|
+
calculate (e.g., conjunction, opposition, trine, square, sextile).
|
|
96
|
+
Defaults to DEFAULT_ACTIVE_ASPECTS.
|
|
97
|
+
settings_file (Union[Path, KerykeionSettingsModel, dict, None], optional):
|
|
98
|
+
Configuration settings for calculations. Can be a file path, settings
|
|
99
|
+
model, dictionary, or None for defaults. Defaults to None.
|
|
100
|
+
|
|
101
|
+
Attributes:
|
|
102
|
+
natal_chart: The reference natal chart for transit calculations.
|
|
103
|
+
ephemeris_data_points: Time-series planetary position data.
|
|
104
|
+
active_points: Celestial bodies included in calculations.
|
|
105
|
+
active_aspects: Aspect types considered for analysis.
|
|
106
|
+
settings_file: Configuration settings for the calculations.
|
|
107
|
+
|
|
108
|
+
Examples:
|
|
109
|
+
Basic transit calculation:
|
|
110
|
+
|
|
111
|
+
>>> natal_chart = AstrologicalSubjectFactory.from_birth_data(...)
|
|
112
|
+
>>> ephemeris_data = ephemeris_factory.get_ephemeris_data_as_astrological_subjects()
|
|
113
|
+
>>> factory = TransitsTimeRangeFactory(natal_chart, ephemeris_data)
|
|
114
|
+
>>> transits = factory.get_transit_moments()
|
|
115
|
+
|
|
116
|
+
Custom configuration:
|
|
117
|
+
|
|
118
|
+
>>> from kerykeion.kr_types import AstrologicalPoint, ActiveAspect
|
|
119
|
+
>>> custom_points = [AstrologicalPoint.SUN, AstrologicalPoint.MOON]
|
|
120
|
+
>>> custom_aspects = [ActiveAspect.CONJUNCTION, ActiveAspect.OPPOSITION]
|
|
121
|
+
>>> factory = TransitsTimeRangeFactory(
|
|
122
|
+
... natal_chart, ephemeris_data,
|
|
123
|
+
... active_points=custom_points,
|
|
124
|
+
... active_aspects=custom_aspects
|
|
125
|
+
... )
|
|
126
|
+
|
|
127
|
+
Note:
|
|
128
|
+
- Calculation time scales with the number of ephemeris data points
|
|
129
|
+
- More active points and aspects increase computational requirements
|
|
130
|
+
- The natal chart's coordinate system should match the ephemeris data
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
def __init__(
|
|
134
|
+
self,
|
|
135
|
+
natal_chart: AstrologicalSubjectModel,
|
|
136
|
+
ephemeris_data_points: List[AstrologicalSubjectModel],
|
|
137
|
+
active_points: List[AstrologicalPoint] = DEFAULT_ACTIVE_POINTS,
|
|
138
|
+
active_aspects: List[ActiveAspect] = DEFAULT_ACTIVE_ASPECTS,
|
|
139
|
+
settings_file: Union[Path, KerykeionSettingsModel, dict, None] = None,
|
|
140
|
+
):
|
|
141
|
+
"""
|
|
142
|
+
Initialize the TransitsTimeRangeFactory with calculation parameters.
|
|
143
|
+
|
|
144
|
+
Sets up the factory with all necessary data and configuration for calculating
|
|
145
|
+
transits across the specified time period. The natal chart serves as the
|
|
146
|
+
reference point, while ephemeris data points provide the transiting positions
|
|
147
|
+
for comparison.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
natal_chart (AstrologicalSubjectModel): Reference natal chart containing
|
|
151
|
+
the baseline planetary positions for transit calculations.
|
|
152
|
+
ephemeris_data_points (List[AstrologicalSubjectModel]): Time-ordered list
|
|
153
|
+
of planetary positions representing different moments in time.
|
|
154
|
+
Typically generated by EphemerisDataFactory.
|
|
155
|
+
active_points (List[AstrologicalPoint], optional): Celestial bodies to
|
|
156
|
+
include in aspect calculations. Determines which planets/points are
|
|
157
|
+
analyzed for aspects. Defaults to DEFAULT_ACTIVE_POINTS.
|
|
158
|
+
active_aspects (List[ActiveAspect], optional): Types of angular relationships
|
|
159
|
+
to calculate between natal and transiting positions. Defaults to
|
|
160
|
+
DEFAULT_ACTIVE_ASPECTS.
|
|
161
|
+
settings_file (Union[Path, KerykeionSettingsModel, dict, None], optional):
|
|
162
|
+
Configuration settings for orb tolerances, calculation methods, and
|
|
163
|
+
other parameters. Defaults to None (uses system defaults).
|
|
164
|
+
|
|
165
|
+
Note:
|
|
166
|
+
- All ephemeris data points should use the same coordinate system as the natal chart
|
|
167
|
+
- The order of ephemeris_data_points determines the chronological sequence
|
|
168
|
+
- Settings affect orb tolerances and calculation precision
|
|
169
|
+
"""
|
|
170
|
+
self.natal_chart = natal_chart
|
|
171
|
+
self.ephemeris_data_points = ephemeris_data_points
|
|
172
|
+
self.active_points = active_points
|
|
173
|
+
self.active_aspects = active_aspects
|
|
174
|
+
self.settings_file = settings_file
|
|
175
|
+
|
|
176
|
+
def get_transit_moments(self) -> TransitsTimeRangeModel:
|
|
177
|
+
"""
|
|
178
|
+
Calculate and generate transit data for all configured time points.
|
|
179
|
+
|
|
180
|
+
This method processes each ephemeris data point to identify angular relationships
|
|
181
|
+
(aspects) between transiting celestial bodies and natal chart positions. It
|
|
182
|
+
creates a comprehensive model containing all transit moments with their
|
|
183
|
+
corresponding aspects and timestamps.
|
|
184
|
+
|
|
185
|
+
The calculation process:
|
|
186
|
+
1. Iterates through each ephemeris data point chronologically
|
|
187
|
+
2. Compares transiting planetary positions with natal chart positions
|
|
188
|
+
3. Identifies aspects that fall within the configured orb tolerances
|
|
189
|
+
4. Creates timestamped transit moment records
|
|
190
|
+
5. Compiles all data into a structured model for analysis
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
TransitsTimeRangeModel: A comprehensive model containing:
|
|
194
|
+
- dates (List[str]): ISO-formatted datetime strings for all data points
|
|
195
|
+
- subject (AstrologicalSubjectModel): The natal chart used as reference
|
|
196
|
+
- transits (List[TransitMomentModel]): Chronological list of transit moments,
|
|
197
|
+
each containing:
|
|
198
|
+
* date (str): ISO-formatted timestamp for the transit moment
|
|
199
|
+
* aspects (List[RelevantAspect]): All aspects formed at this moment
|
|
200
|
+
between transiting and natal positions
|
|
201
|
+
|
|
202
|
+
Examples:
|
|
203
|
+
Basic usage:
|
|
204
|
+
|
|
205
|
+
>>> factory = TransitsTimeRangeFactory(natal_chart, ephemeris_data)
|
|
206
|
+
>>> results = factory.get_transit_moments()
|
|
207
|
+
>>>
|
|
208
|
+
>>> # Access specific data
|
|
209
|
+
>>> all_dates = results.dates
|
|
210
|
+
>>> first_transit = results.transits[0]
|
|
211
|
+
>>> aspects_at_first_moment = first_transit.aspects
|
|
212
|
+
|
|
213
|
+
Processing results:
|
|
214
|
+
|
|
215
|
+
>>> results = factory.get_transit_moments()
|
|
216
|
+
>>> for transit_moment in results.transits:
|
|
217
|
+
... print(f"Date: {transit_moment.date}")
|
|
218
|
+
... for aspect in transit_moment.aspects:
|
|
219
|
+
... print(f" {aspect.p1_name} {aspect.aspect} {aspect.p2_name}")
|
|
220
|
+
|
|
221
|
+
Performance Notes:
|
|
222
|
+
- Calculation time is proportional to: number of time points × active points × active aspects
|
|
223
|
+
- Large datasets may require significant processing time
|
|
224
|
+
- Memory usage scales with the number of aspects found
|
|
225
|
+
- Consider filtering active_points and active_aspects for better performance
|
|
226
|
+
|
|
227
|
+
See Also:
|
|
228
|
+
TransitMomentModel: Individual transit moment structure
|
|
229
|
+
TransitsTimeRangeModel: Complete transit dataset structure
|
|
230
|
+
SynastryAspectsFactory: Underlying aspect calculation engine
|
|
231
|
+
"""
|
|
232
|
+
transit_moments = []
|
|
233
|
+
|
|
234
|
+
for ephemeris_point in self.ephemeris_data_points:
|
|
235
|
+
# Calculate aspects between transit positions and natal chart
|
|
236
|
+
aspects = SynastryAspectsFactory.from_subjects(
|
|
237
|
+
ephemeris_point,
|
|
238
|
+
self.natal_chart,
|
|
239
|
+
active_points=self.active_points,
|
|
240
|
+
active_aspects=self.active_aspects,
|
|
241
|
+
).relevant_aspects
|
|
242
|
+
|
|
243
|
+
# Create a transit moment for this point in time
|
|
244
|
+
transit_moments.append(
|
|
245
|
+
TransitMomentModel(
|
|
246
|
+
date=ephemeris_point.iso_formatted_utc_datetime,
|
|
247
|
+
aspects=aspects,
|
|
248
|
+
)
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
# Create and return the complete transits model
|
|
252
|
+
return TransitsTimeRangeModel(
|
|
253
|
+
dates=[point.iso_formatted_utc_datetime for point in self.ephemeris_data_points],
|
|
254
|
+
subject=self.natal_chart,
|
|
255
|
+
transits=transit_moments
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
if __name__ == "__main__":
|
|
260
|
+
# Create a natal chart for the subject
|
|
261
|
+
person = AstrologicalSubjectFactory.from_birth_data(
|
|
262
|
+
"Johnny Depp", 1963, 6, 9, 20, 15, "Owensboro", "US"
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
# Define the time period for transit calculation
|
|
266
|
+
start_date = datetime.now()
|
|
267
|
+
end_date = datetime.now() + timedelta(days=30)
|
|
268
|
+
|
|
269
|
+
# Create ephemeris data for the specified time period
|
|
270
|
+
ephemeris_factory = EphemerisDataFactory(
|
|
271
|
+
start_datetime=start_date,
|
|
272
|
+
end_datetime=end_date,
|
|
273
|
+
step_type="days",
|
|
274
|
+
step=1,
|
|
275
|
+
lat=person.lat,
|
|
276
|
+
lng=person.lng,
|
|
277
|
+
tz_str=person.tz_str,
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
ephemeris_data_points = ephemeris_factory.get_ephemeris_data_as_astrological_subjects()
|
|
281
|
+
|
|
282
|
+
# Calculate transits for the subject
|
|
283
|
+
transit_factory = TransitsTimeRangeFactory(
|
|
284
|
+
natal_chart=person,
|
|
285
|
+
ephemeris_data_points=ephemeris_data_points,
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
transit_results = transit_factory.get_transit_moments()
|
|
289
|
+
|
|
290
|
+
# Print example data
|
|
291
|
+
print(transit_results.model_dump()["dates"][2])
|
|
292
|
+
print(transit_results.model_dump()["transits"][2]['date'])
|
|
293
|
+
print(transit_results.model_dump()["transits"][2]['aspects'][0])
|