libaditya 0.3.4__py2.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.
Files changed (131) hide show
  1. libaditya/__init__.py +46 -0
  2. libaditya/_version.py +29 -0
  3. libaditya/calc/__init__.py +9 -0
  4. libaditya/calc/api.py +30 -0
  5. libaditya/calc/avasthas.py +346 -0
  6. libaditya/calc/docs/jaimini-get-arch.md +95 -0
  7. libaditya/calc/hellenistic.py +37 -0
  8. libaditya/calc/jaimini.py +335 -0
  9. libaditya/calc/jaimini_get.py +240 -0
  10. libaditya/calc/kala.py +73 -0
  11. libaditya/calc/panchanga.py +422 -0
  12. libaditya/calc/rashi.py +612 -0
  13. libaditya/calc/returns.py +50 -0
  14. libaditya/calc/swe_functions.py +118 -0
  15. libaditya/calc/varga.py +287 -0
  16. libaditya/calc/vimshottari.py +431 -0
  17. libaditya/cards/__init__.py +5 -0
  18. libaditya/cards/card.py +90 -0
  19. libaditya/cards/cards_constants.py +115 -0
  20. libaditya/cards/cards_of_truth.py +323 -0
  21. libaditya/cards/cot.py +142 -0
  22. libaditya/cards/deck.py +52 -0
  23. libaditya/charts/__init__.py +6 -0
  24. libaditya/charts/api.py +36 -0
  25. libaditya/charts/bodygraph.py +80 -0
  26. libaditya/charts/chart.py +286 -0
  27. libaditya/charts/jaimini.py +83 -0
  28. libaditya/charts/tajika.py +36 -0
  29. libaditya/constants.py +1776 -0
  30. libaditya/draw/__init__.py +20 -0
  31. libaditya/draw/draw_bodygraph.py +489 -0
  32. libaditya/draw/draw_sbc.py +712 -0
  33. libaditya/draw/themes/default-theme.hd +53 -0
  34. libaditya/ephe/ast0/se00010s.se1 +0 -0
  35. libaditya/ephe/seas_00.se1 +0 -0
  36. libaditya/ephe/seas_06.se1 +0 -0
  37. libaditya/ephe/seas_12.se1 +0 -0
  38. libaditya/ephe/seas_18.se1 +0 -0
  39. libaditya/ephe/seas_24.se1 +0 -0
  40. libaditya/ephe/seas_30.se1 +0 -0
  41. libaditya/ephe/seas_36.se1 +0 -0
  42. libaditya/ephe/seas_42.se1 +0 -0
  43. libaditya/ephe/seas_48.se1 +0 -0
  44. libaditya/ephe/seasm06.se1 +0 -0
  45. libaditya/ephe/seasm12.se1 +0 -0
  46. libaditya/ephe/seasm18.se1 +0 -0
  47. libaditya/ephe/seasm24.se1 +0 -0
  48. libaditya/ephe/seasm30.se1 +0 -0
  49. libaditya/ephe/seasm36.se1 +0 -0
  50. libaditya/ephe/seasm42.se1 +0 -0
  51. libaditya/ephe/seasm48.se1 +0 -0
  52. libaditya/ephe/seasm54.se1 +0 -0
  53. libaditya/ephe/sefstars.txt +4245 -0
  54. libaditya/ephe/semo_00.se1 +0 -0
  55. libaditya/ephe/semo_06.se1 +0 -0
  56. libaditya/ephe/semo_12.se1 +0 -0
  57. libaditya/ephe/semo_18.se1 +0 -0
  58. libaditya/ephe/semo_24.se1 +0 -0
  59. libaditya/ephe/semo_30.se1 +0 -0
  60. libaditya/ephe/semo_36.se1 +0 -0
  61. libaditya/ephe/semo_42.se1 +0 -0
  62. libaditya/ephe/semo_48.se1 +0 -0
  63. libaditya/ephe/semom06.se1 +0 -0
  64. libaditya/ephe/semom12.se1 +0 -0
  65. libaditya/ephe/semom18.se1 +0 -0
  66. libaditya/ephe/semom24.se1 +0 -0
  67. libaditya/ephe/semom30.se1 +0 -0
  68. libaditya/ephe/semom36.se1 +0 -0
  69. libaditya/ephe/semom42.se1 +0 -0
  70. libaditya/ephe/semom48.se1 +0 -0
  71. libaditya/ephe/semom54.se1 +0 -0
  72. libaditya/ephe/sepl_00.se1 +0 -0
  73. libaditya/ephe/sepl_06.se1 +0 -0
  74. libaditya/ephe/sepl_12.se1 +0 -0
  75. libaditya/ephe/sepl_18.se1 +0 -0
  76. libaditya/ephe/sepl_24.se1 +0 -0
  77. libaditya/ephe/sepl_30.se1 +0 -0
  78. libaditya/ephe/sepl_36.se1 +0 -0
  79. libaditya/ephe/sepl_42.se1 +0 -0
  80. libaditya/ephe/sepl_48.se1 +0 -0
  81. libaditya/ephe/seplm06.se1 +0 -0
  82. libaditya/ephe/seplm12.se1 +0 -0
  83. libaditya/ephe/seplm18.se1 +0 -0
  84. libaditya/ephe/seplm24.se1 +0 -0
  85. libaditya/ephe/seplm30.se1 +0 -0
  86. libaditya/ephe/seplm36.se1 +0 -0
  87. libaditya/ephe/seplm42.se1 +0 -0
  88. libaditya/ephe/seplm48.se1 +0 -0
  89. libaditya/ephe/seplm54.se1 +0 -0
  90. libaditya/hd/__init__.py +8 -0
  91. libaditya/hd/calc.py +55 -0
  92. libaditya/hd/constants.py +127 -0
  93. libaditya/hd/longitude.py +271 -0
  94. libaditya/objects/__init__.py +19 -0
  95. libaditya/objects/celestial_object.py +206 -0
  96. libaditya/objects/context.py +133 -0
  97. libaditya/objects/cusps.py +259 -0
  98. libaditya/objects/julian_day.py +265 -0
  99. libaditya/objects/location.py +167 -0
  100. libaditya/objects/longitude.py +987 -0
  101. libaditya/objects/nakshatras.py +285 -0
  102. libaditya/objects/planets.py +2059 -0
  103. libaditya/objects/shadbala.py +398 -0
  104. libaditya/objects/signs.py +690 -0
  105. libaditya/objects/swe_functions.py +75 -0
  106. libaditya/print_functions.py +548 -0
  107. libaditya/read.py +665 -0
  108. libaditya/stars/__init__.py +4 -0
  109. libaditya/stars/fixed_star.py +216 -0
  110. libaditya/stars/make_swe_stars.py +407 -0
  111. libaditya/stars/star-sign-boundaries +44 -0
  112. libaditya/stars/stellarium/__init__.py +6 -0
  113. libaditya/stars/stellarium/remote_control/__init__.py +22 -0
  114. libaditya/stars/stellarium/remote_control/location.py +82 -0
  115. libaditya/stars/stellarium/remote_control/locationsearch.py +35 -0
  116. libaditya/stars/stellarium/remote_control/main.py +165 -0
  117. libaditya/stars/stellarium/remote_control/objects.py +63 -0
  118. libaditya/stars/stellarium/remote_control/scripts.py +81 -0
  119. libaditya/stars/stellarium/remote_control/simbad.py +20 -0
  120. libaditya/stars/stellarium/remote_control/stelaction.py +31 -0
  121. libaditya/stars/stellarium/remote_control/stelproperty.py +30 -0
  122. libaditya/stars/stellarium/remote_control/view.py +85 -0
  123. libaditya/stars/stellarium/stellarium.py +92 -0
  124. libaditya/stars/the_stars.py +522 -0
  125. libaditya/stars/utilities.py +539 -0
  126. libaditya/utils.py +431 -0
  127. libaditya/write.py +67 -0
  128. libaditya-0.3.4.dist-info/METADATA +588 -0
  129. libaditya-0.3.4.dist-info/RECORD +131 -0
  130. libaditya-0.3.4.dist-info/WHEEL +5 -0
  131. libaditya-0.3.4.dist-info/licenses/LICENSE +661 -0
@@ -0,0 +1,285 @@
1
+ # This file is part of libaditya.
2
+ #
3
+ # Copyright (c) 2025 Josh Harper <humanhaven@substack.com>
4
+ #
5
+ # libaditya is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Affero General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # libaditya is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Affero General Public License
16
+ # along with libaditya. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ import swisseph as swe
19
+ from prettytable import PrettyTable
20
+
21
+ from libaditya import constants as const
22
+
23
+ class Nakshatra:
24
+ def __init__(self, occupant):
25
+ self._occupant = occupant
26
+ self.context = occupant.context
27
+ self.timeJD = occupant.timeJD
28
+ self.base_long = self._occupant.ecliptic_longitude()
29
+ self.ayanamsa = self.context.ayanamsa
30
+ self._naksize = 360/28 if self.ayanamsa == 101 else 13+(1/3)
31
+ # ashlong means the number of degrees from ashvini; in most cases, the sidereal longitude
32
+ self.ash_long = self.init_ash_long()
33
+
34
+ def __str__(self):
35
+ nak = f"Nakshatra of {self.occupant()}\n"
36
+ base_long = f"base longitude: {self.base_longitude()}\n"
37
+ ash_long = f"Degrees from beginning of ashvini: {self.ashvini_longitude()}\n"
38
+ ayana = f"Using {self.ayanamsa_name()} ayanamsa\n"
39
+ nakshatra = f"{self.nakshatra()}\n"
40
+ return nak + base_long + ash_long + ayana + nakshatra
41
+
42
+ def __repr__(self):
43
+ """
44
+ return neutral string representation for database
45
+ returns the English name of this nakshatra, in hopes that everyone can type that on any keyboard
46
+ ...my terminal emunlator cannot properly disply devangari
47
+ """
48
+ return f"{self.identity()}"
49
+ # nak = f"Nakshatra of {self.occupant()}\n"
50
+ # base_long = f"base longitude: {self.base_longitude()}\n"
51
+ # ash_long = f"Degrees from beginning of ashvini: {self.ashvini_longitude()}\n"
52
+ # ayana = f"Using {self.ayanamsa_name()} ayanamsa\n"
53
+ # nakshatra = f"{self.nakshatra()}\n"
54
+ # return nak + base_long + ash_long + ayana + nakshatra
55
+
56
+ def occupant(self):
57
+ return self._occupant.name()
58
+
59
+ def naksize(self):
60
+ return self._naksize
61
+
62
+ def base_longitude(self):
63
+ return self.base_long
64
+
65
+ def ashvini_longitude(self):
66
+ return self.ash_long
67
+
68
+ def index(self):
69
+ if self.ayanamsa == 101:
70
+ return int(self.ashvini_longitude()/self.naksize())%28
71
+ return int(self.ashvini_longitude()/self.naksize())%27
72
+
73
+ def identity(self):
74
+ """
75
+ return the English name to use as an all purpose nakshatras dictionary index
76
+ ['Ashvini', 'Bharani', 'Krittika', 'Rohini', 'Mrigashira', 'Ardra', 'Punarvasu', 'Pushya', 'Ashlesha', 'Magha', 'P. Phalguni', 'U. Phalguni', 'Hasta', 'Chitra', 'Svati', 'Vishakha', 'Anuradha', 'Jyeshtha', 'Mula', 'P. Ashadha', 'U. Ashadha', 'Shravana', 'Danishtha', 'Shatabhisha', 'P. Bhadrapada', 'U. Bhadrapada', 'Revati'
77
+ """
78
+ nak_key = "nakshatras_28eq" if self.ayanamsa == 101 else "nakshatras"
79
+ return const.names["eng"][nak_key][self.index()]
80
+
81
+ def nakshatra(self):
82
+ nak_key = "nakshatras_28eq" if self.ayanamsa == 101 else "nakshatras"
83
+ return const.names[self.context.names_type][nak_key][self.index()]
84
+
85
+ def degrees_elapsed(self):
86
+ if self.context.toround[0] == True:
87
+ return round(self.ashvini_longitude()-(self.index()*self.naksize()),2)
88
+ else:
89
+ return self.ashvini_longitude()-(self.index()*self.naksize())
90
+
91
+ def degrees_remaining(self):
92
+ if self.context.toround[0] == True:
93
+ return round(self.naksize()-self.degrees_elapsed(),2)
94
+ else:
95
+ return self.naksize()-self.degrees_elapsed()
96
+
97
+ def percent_elapsed(self):
98
+ if self.context.toround[0] == True:
99
+ return round((self.degrees_elapsed()/self.naksize())*100,2)
100
+ else:
101
+ return (self.degrees_elapsed()/self.naksize())*100
102
+
103
+ return False
104
+ def elapsed(self):
105
+ return f"{self.degrees_elapsed()} ({self.percent_elapsed()} %)"
106
+
107
+ def print_in_longitude(self):
108
+ print(f"Elapsed: {self.degrees_elapsed()} deg ({round((self.degrees_elapsed() / self.naksize()) * 100, 3)} %)")
109
+ degremain = self.degrees_remaining()
110
+ print(
111
+ f"Remaining: {degremain} deg ({round((degremain / self.naksize()) * 100, 3)} %)"
112
+ )
113
+
114
+ def init_ash_long(self):
115
+ from .planets import Planet
116
+ from .cusps import Cusp
117
+ # otherwise, find the number of degrees from ashvini
118
+ # insert custom ayanamsa codes and methods here
119
+ if self.ayanamsa == -1:
120
+ return self.base_longitude()
121
+ if self.ayanamsa == 101:
122
+ return self.base_longitude()
123
+ if self.ayanamsa == 98:
124
+ return self.dhruva_gc_equatorial()
125
+ if self.ayanamsa == 99:
126
+ return self.vedanga_jyotisha_ecliptic()
127
+ if self.ayanamsa == 100:
128
+ return self.vedanga_jyotisha_equatorial()
129
+ if isinstance(self._occupant, Planet):
130
+ return self.init_ash_long_Planet()
131
+ if isinstance(self._occupant, Cusp):
132
+ return self.init_ash_long_Cusp()
133
+ else:
134
+ print(f"instance of type {type(self._occupant)} cannot be in a nakshatra")
135
+
136
+ def init_ash_long_Planet(self):
137
+ swe.set_sid_mode(self.ayanamsa)
138
+ long = swe.calc_ut(self.timeJD.jd_number(), self._occupant.pnumber, swe.FLG_SIDEREAL)[0][0]
139
+ long = self.ketuize(long)
140
+ return long
141
+
142
+ def init_ash_long_Cusp(self):
143
+ swe.set_sid_mode(self.ayanamsa)
144
+ cusps, _, _, _ = swe.houses_ex2(
145
+ self._occupant.timeJD.jd_number(),
146
+ self._occupant.location.lat,
147
+ self._occupant.location.long,
148
+ self._occupant.hsys,
149
+ swe.FLG_SIDEREAL,
150
+ )
151
+ return cusps[self._occupant.cusp_index()]
152
+
153
+ def ayanamsa_name(self):
154
+ return const.ayanamsa_name(self.ayanamsa)
155
+
156
+ def ketuize(self,long):
157
+ from .planets import Ketu
158
+ if isinstance(self._occupant,Ketu):
159
+ long = (long-180)%360
160
+ return long
161
+
162
+ def dhruva_gc_equatorial(self):
163
+ from .planets import Planet
164
+ from .cusps import Cusp
165
+ gcequ=swe.fixstar(",SgrA*",self.timeJD.jd, swe.FLG_EQUATORIAL)[0][0]
166
+ mula=gcequ-(self.naksize()/2)
167
+ ashvini=mula-(18*self.naksize())
168
+ if isinstance(self._occupant,Planet):
169
+ equlong = swe.calc_ut(self.timeJD.jd, self._occupant.pnumber, swe.FLG_EQUATORIAL)[0][0]
170
+ equlong = self.ketuize(equlong)
171
+ if isinstance(self._occupant,Cusp):
172
+ equlong = swe.cotrans((self.base_longitude(),0,1),self.timeJD.ecliptic_obliquity())[0]
173
+ if equlong < ashvini:
174
+ equlong+=360
175
+ return equlong-ashvini
176
+
177
+ def vedanga_jyotisha_ecliptic(self):
178
+ """
179
+ dhanishta begins at the winter solstice, i.e., 270 degrees ecliptic longitude
180
+ this puts ashivini to start at 336+2/3 ecliptic longitude
181
+ so our "ayanamsa" is 23+1/3, in order to line up with our nakshatra list
182
+ but we have to add this, so that ashvini+ayanamsa=0
183
+ """
184
+ # aval = 23+1/3
185
+ # this is how it is calculated
186
+ # find where ashvini starts; it is five nakshatras after dhanishta
187
+ ashvini = 360 - (270+5*self.naksize())
188
+ return (self.base_longitude()+ashvini)%360
189
+
190
+ def vedanga_jyotisha_equatorial(self):
191
+ """
192
+ dhanishta at the winter solstice, but equatorial nakshatras
193
+ so find the equatorial longitude of the solstice, then
194
+ determine nakshatras from there with equatorial planet longitudes
195
+ the projection of the winter solstice onto the equator is always at 270 equatorial longitude
196
+ but im calculating it just for the form of it, on principle
197
+ """
198
+ from .planets import Planet
199
+ from .cusps import Cusp
200
+ # equatorial longitude of the winter solstice
201
+ # the swe.calc call is for the ecliptic_obliquity, which is required for coordinate transformations
202
+ # according to the documentation, '-' is used to go from ecliptic to equatorial, which we are doing here
203
+ solequ = swe.cotrans((270,0,1),-swe.calc(self.timeJD.jd,swe.ECL_NUT)[0][0])[0]
204
+ # find where equatorial ashvini starts; it is five nakshatras after dhanishta
205
+ ashvini = 360 - (solequ+5*self.naksize())
206
+ # equatorial longitude of this planet
207
+ if isinstance(self._occupant,Planet):
208
+ equlong = swe.calc_ut(self.timeJD.jd, self._occupant.pnumber, swe.FLG_EQUATORIAL)[0][0]
209
+ equlong = self.ketuize(equlong)
210
+ if isinstance(self._occupant,Cusp):
211
+ equlong = swe.cotrans((self.base_longitude(),0,1),self.timeJD.ecliptic_obliquity())[0]
212
+ return (equlong+ashvini)%360
213
+
214
+ class Ashvini(Nakshatra):
215
+ pass
216
+
217
+ class Nakshatras:
218
+
219
+ def __init__(self, occupants, context):
220
+ self._occupants = occupants
221
+ self.context = context
222
+ self.nakshatras = self.init_Nakshatras()
223
+
224
+ def __iter__(self):
225
+ return iter(self.nakshatras)
226
+
227
+ def __getitem__(self,n):
228
+ return self.nakshatras[n]
229
+
230
+ def __str__(self):
231
+ output = PrettyTable()
232
+ output.field_names = [f"{self.occupant_type()}", "Nakshatra", "Percent Elapsed"]
233
+ output.align[f"{self.occupant_type()}"] = "l"
234
+ output.align["Nakshatra"] = "l"
235
+ output.align["Percent Elapsed"] = "r"
236
+
237
+ for occupant in self.nakshatras:
238
+ output.add_row([occupant.occupant(),occupant.nakshatra(),f"{occupant.degrees_elapsed()} ({occupant.percent_elapsed()} %)"])
239
+
240
+ ret = output.get_string(fields=[f"{self.occupant_type()}","Nakshatra","Percent Elapsed"])
241
+
242
+ return self.mkheader() + ret
243
+
244
+ def __repr__(self):
245
+ return self.mkheader()
246
+
247
+ def occupant_type(self) -> str:
248
+ from .planets import Planets
249
+ from .cusps import Cusps
250
+ if isinstance(self._occupants,Planets):
251
+ return "Planet"
252
+ elif isinstance(self._occupants,Cusps):
253
+ return "Cusp"
254
+ else:
255
+ raise TypeError("cannot make Nakshatras from this type")
256
+
257
+ def init_Nakshatras(self):
258
+ ret = []
259
+ for occupant in self._occupants:
260
+ ret.append(occupant.nakshatra())
261
+ return ret
262
+
263
+ def mkheader(self):
264
+ from .planets import Planets
265
+ from .cusps import Cusps
266
+ if isinstance(self._occupants,Planets):
267
+ return self.mkheader_Planets()
268
+ elif isinstance(self._occupants,Cusps):
269
+ return self.mkheader_Cusps()
270
+ else:
271
+ raise TypeError("cannot make Nakshatras from this type")
272
+
273
+ def mkheader_Planets(self):
274
+ header = "Nakshatras of the planets:\n"
275
+ header += f"{self.context.timeJD}\n"
276
+ header += f"using {const.ayanamsa_name(self.context.ayanamsa)} ayanamsa\n"
277
+ return header
278
+
279
+ def mkheader_Cusps(self):
280
+ header = "Nakshatras of the cusps:\n"
281
+ header += f"{self.context.timeJD}\n"
282
+ header += f"{self.context.location}\n"
283
+ header += f"using {const.ayanamsa_name(self.context.ayanamsa)} ayanamsa\n"
284
+ header += f"using house system {self._occupants[0].house_system()}\n"
285
+ return header