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,216 @@
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
+
20
+ from libaditya import constants as const
21
+ from libaditya import utils
22
+
23
+ from libaditya.objects import Longitude, CelestialObject, EphContext
24
+
25
+ from libaditya.stars.stellarium import Stellarium
26
+
27
+ def correct_nomen_name(swe_id):
28
+ # take care of cases like ,And14
29
+ # the proper nomen name is ,14And
30
+ # these is only for names that have numbers in them
31
+ if "," in swe_id:
32
+ # remove initial comma if there
33
+ swe_id = swe_id[1:]
34
+ # the next lines transform a Flamsteed designation of Namennn to nnnName, where there are 1-3 n's in [0,9]
35
+ # if swe_id[-3:].isnumeric():
36
+ # return ","+swe_id[-3:]+swe_id[:-3]
37
+ # if swe_id[-2:].isnumeric():
38
+ # if swe_id[-2:] == "00":
39
+ # # for GCRS00
40
+ # return ","+swe_id
41
+ # return ","+swe_id[-2:]+swe_id[:-2]
42
+ # if swe_id[-1:].isnumeric():
43
+ # return ","+swe_id[-1:]+swe_id[:-1]
44
+ # make sure there is a comma for swe
45
+ return ","+swe_id
46
+
47
+
48
+ # if you want a Stellarium star
49
+ # include "st:" at the beginning of swe_id
50
+ # and pass "rc", a stars.stellarium.stellarium.Stellarium instance, which is the connection to Stellarium
51
+
52
+ class FixedStar(CelestialObject,Longitude):
53
+ """
54
+ initialize a FixedStar through the Swiss Ephemeris
55
+ all available stars are listed in libaditya/ephe/sefstars.txt
56
+ swe_id must be the "nomenclature" name
57
+ each star has a one-line entry in sefstars.txt
58
+ the nomenclature name is the second entry, e.g.,:
59
+ Alpha Canis Majoris,alfCMa,ICRS,06,45,08.91728,-16,42,58.0171,-546.01,-1223.07,-5.50,379.21,-1.46
60
+
61
+ alfCMa is the "nomenclature" name that you should use to initialize FixedStar
62
+
63
+ in the original sefstars.txt, the first field is a "traditional" name, in this case Sirius
64
+ the swe fixed star function can "search" this field. So if it doesn't find a star based on the nomenclature name, then it
65
+ will find the first star the matches what was input
66
+
67
+ you can call FixedStar this way
68
+ right now, all the "traditional" names have been change to long form forms of the nomenclature names
69
+
70
+ most of the nomenclature names are the Bayer designation, which consists of a greek letter and a Latin gentitive for the constellation
71
+ some other designations are used as the swe_id/nomenclature name, and these expand to long form names as well, e.g., "HIP" into "Hipparcos Catalogue"
72
+
73
+ in sefstars.txt, there is now a line above each star entry that contains other names of this star
74
+ so a complete entry looks like this:
75
+
76
+ #0# alfCMa, Alpha Canis Major, Sirius, HIP 32349
77
+ Alpha Canis Majoris,alfCMa,ICRS,06,45,08.91728,-16,42,58.0171,-546.01,-1223.07,-5.50,379.21,-1.46
78
+
79
+ soon, FixedStar will parse the names of the info line that begins with #0# and add those names to itself,
80
+ which will be retrievable through FixedStar().other_names()
81
+ and maybe there will be a way to initialize FixedStar through the use of those names, but not right now
82
+
83
+ stars can be added by using the script libaditya/ephe/make_swe_star.py
84
+ """
85
+
86
+ def __init__(self, swe_id: str, context: EphContext = EphContext(), rc: Stellarium = None, swe_string=""):
87
+ self.context = context
88
+ self.system = self.context.sysflg
89
+ self.sysflg = self.system | swe.FLG_SPEED
90
+ self._other_names = ""
91
+ self._swe_string = swe_string
92
+ # swe_id is the nomenclature name of the star
93
+ # can pass it with or without comma
94
+ self._stellarium = False
95
+ if "st:" in swe_id:
96
+ # swe_id = "st:Omi Tau"
97
+ # or "st: HIP 19500"
98
+ # indicates this is a stellarium star
99
+ self._swe_id = swe_id.split(":")[1].strip()
100
+ self._stellarium = True
101
+ # called "rc", but is not a stellarium.remote_control.RemoteControl object
102
+ # it is a Stellarium object initialized by someone else to get this information
103
+ # initialized by the TheStars()
104
+ self.rc = rc
105
+ # now initialize all of the information
106
+ self.init_Stellarium()
107
+ super().__init__(self.long,1,context)
108
+ # done with this __init__
109
+ return
110
+ self._swe_id = correct_nomen_name(swe_id)
111
+ try:
112
+ # if it works, the swe_id is valid
113
+ swe.fixstar2_ut(self._swe_id,self.context.timeJD.jd_number())
114
+ except:
115
+ # if not, assume it is a search
116
+ # so remove "," from beginning, add "%" to end for wildcard
117
+ self._swe_id = self._swe_id[1:]+"%"
118
+ # self._coords is a 6-tuple
119
+ # will be unpacked into FixedStar.longitude(), etc., for each value in the tuple
120
+ (self.long, self.lat, self.dist, self.long_speed, self.lat_speed, self.dist_speed), self._name, self._retflags = self.init_coords()
121
+ self.dist_ly = 0 # convert self.dist in AUs to LYs
122
+ self._name, self.returned_swe_id = self._name.split(",")
123
+ (self._right_ascension, self._declination, self._equatorial_distance,_,_,_) = swe.fixstar2_ut(self.swe_id(),self.context.timeJD.jd_number(),swe.FLG_EQUATORIAL)[0]
124
+ if "%" in self._swe_id:
125
+ self._swe_id = self.returned_swe_id
126
+ self.attributes = {"constellation": "n/a"}
127
+ # now that we know which star this is, make sure it has the right swe_id()
128
+ # super() means Longitude. CelestialObject is a Mixin and has no __init__ method of its own
129
+ # it is basically just a holder for shared code between Planet and FixedStar
130
+ # ...things that apply to both of them as CelestialObjects
131
+ super().__init__(self.long,1,context)
132
+
133
+
134
+ def init_coords(self):
135
+ loc = self.context.location.swe_location()
136
+ # the if statements are returnless statements that initialize swe
137
+ # sysflg is definited in __init__; it is self.system + swe.FLG_SPEED
138
+ # so that we always get the speed
139
+ if self.system == const.SID:
140
+ # will need to add custom ayanamsas here
141
+ if self.ayanamsa() == 98:
142
+ self._ayanamsa = 36
143
+ if self.ayanamsa() == 97:
144
+ utils.set_swe_true_sidereal_ayanamsa()
145
+ if self.system == const.TOPO:
146
+ swe.set_topo(loc[0], loc[1], loc[2])
147
+ if self.system == (const.SID | const.TOPO):
148
+ swe.set_sid_mode(self.ayanamsa())
149
+ swe.set_topo(loc[0], loc[1], loc[2])
150
+ return swe.fixstar2_ut(self.swe_id(), self.context.timeJD.jd_number(), self.sysflg if self.sysflg >= 0 else 0)
151
+
152
+ def __eq__(self, fs2):
153
+ """
154
+ are these the same kind of object?
155
+ they could both be Aldebaran but 4000 years apart; they would still be == with this function
156
+ """
157
+ return self.swe_id() == fs2.swe_id()
158
+
159
+ def other_names(self):
160
+ return self._other_names
161
+
162
+ def retflags(self):
163
+ self._retflags
164
+
165
+ # longitude is taken care of by inheritor, Longitude
166
+
167
+ def name(self):
168
+ return self._name
169
+
170
+ def stellarium(self):
171
+ return self._stellarium
172
+
173
+ def swe_id(self):
174
+ return self._swe_id
175
+
176
+ def identity(self):
177
+ return self.swe_id()
178
+
179
+ def magnitude(self):
180
+ return swe.fixstar2_mag(self.swe_id())[0]
181
+
182
+ def init_Stellarium(self):
183
+ """
184
+ self.swe_id() should be a valid stellarium object, probably HIP
185
+
186
+ need to deal with sidereal in here, so we only get the ecliptic longitude
187
+ """
188
+ try:
189
+ self.rc.change_context(self.context)
190
+ info = self.rc.info(self.swe_id())
191
+ except:
192
+ print("Stellarium not available...")
193
+ return
194
+ self.long = info["elong"]
195
+ self.lat = info["elat"]
196
+ try:
197
+ self.dist = info["distance-ly"]
198
+ except:
199
+ self.dist = 0
200
+ self.dist_ly = self.dist
201
+ self.long_speed = self.lat_speed = self.dist_speed = 0
202
+ self._name = info["name"]
203
+ self._right_ascension = info["ra"]
204
+ self._declination = info["dec"]
205
+ self._equatorial_distance = self.dist
206
+ self._altitude = info["altitude"]
207
+ self._azimuth = info["azimuth"]
208
+ # these will be in local time, so think about time switching?
209
+ # make FixedStar.rise() which will catch Stellarium stars, if not, send them to CelestialObject.rise()
210
+ self._rise = info["rise"]
211
+ self._set = info["set"]
212
+ self._info = info
213
+ return
214
+
215
+ def info(self):
216
+ return self._info
@@ -0,0 +1,407 @@
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 argparse
19
+
20
+ # constants that need to be defined first
21
+
22
+ # if swe_id is lllUll then it is a Bayer designation
23
+ # where lll is a greek letter and Ull is a constellation abbreviation (for the Latin genitive)
24
+ # U(ll) is for other things, e.g., VC for Virgo Cluster, HIP for Hipparcos Catalogue number, etc.
25
+ # nnUll is a Flamsteed designation and will end up as ConstNN in Python
26
+ # e.g., ,48Lib becomes Librae48()
27
+ star_names_short_to_long = {
28
+ "greek": {
29
+ # note: simbad returns two-letter names with an additional "."
30
+ # e.g., "mu.Sgr"
31
+ # not all the letters of the greek alphabet
32
+ # just those used in Bayer designations
33
+ "alf": "Alpha",
34
+ "bet": "Beta",
35
+ "gam": "Gamma",
36
+ # for one star that had some weird stuff happen to it
37
+ "g": "Gamma",
38
+ "del": "Delta",
39
+ # for dOph -> d Ophiuci? just because?
40
+ "d": "Delta",
41
+ "eps": "Epsilon",
42
+ "zet": "Zeta",
43
+ "eta": "Eta", # but no stars with that letter
44
+ "tet": "Theta",
45
+ "iot": "Iota",
46
+ "kap": "Kappa",
47
+ "lam": "Lambda",
48
+ "mu.": "Mu",
49
+ "nu.": "Nu",
50
+ "ksi": "Xi",
51
+ "omi": "Omicron",
52
+ # it seems simbad may use "pi." to have three letters?
53
+ "pi.": "Pi",
54
+ "rho": "Rho",
55
+ "sig": "Sigma",
56
+ "tau": "Tau",
57
+ "ups": "Upsilon",
58
+ "phi": "Phi",
59
+ "chi": "Chi",
60
+ "psi": "Psi",
61
+ "ome": "Omega",
62
+ },
63
+ "constellations": {
64
+ "Ari": "Arietis",
65
+ "Tau": "Tauri",
66
+ "Gem": "Geminorum",
67
+ "Cnc": "Cancri",
68
+ "Leo": "Leonis",
69
+ "Vir": "Virginis",
70
+ "Lib": "Librae",
71
+ "Sco": "Scorpii",
72
+ "Oph": "Ophiuci",
73
+ "Sgr": "Sagittarii",
74
+ "Cap": "Capricorni",
75
+ "Aqr": "Aquarii",
76
+ "And": "Andromedae",
77
+ "Ant": "Antilae",
78
+ "Aps": "Apodis", # Apus constellation
79
+ "Ara": "Arae",
80
+ "Psc": "Piscium",
81
+ "Eri": "Eridani",
82
+ "Cae": "Caeli",
83
+ "Cam": "Camelopardalis",
84
+ "Cas": "Cassiopeiae",
85
+ "Cen": "Centauri",
86
+ "Cep": "Cephei",
87
+ "UMa": "Ursae Majoris",
88
+ "UMi": "Ursae Minoris",
89
+ "Aql": "Aquilae",
90
+ "Hyd": "Hydrae",
91
+ "Sct": "Scuti",
92
+ "Sex": "Sextantis",
93
+ "Sge": "Sagittae",
94
+ "Boo": "Bootis",
95
+ "Dra": "Draconis",
96
+ "Del": "Delphini",
97
+ "Dor": "Doradus",
98
+ "Equ": "Equulei",
99
+ "For": "Fornacis", # Fornax constellation
100
+ "Cyg": "Cygni",
101
+ "Gru": "Gruis",
102
+ "Ori": "Orionis",
103
+ "Cet": "Ceti",
104
+ "Cha": "Chamaeleontis", # Chamaeleon constellation
105
+ "Cir": "Circini", # Circinus constellation
106
+ "Col": "Columbae",
107
+ "Com": "Comae Berenices",
108
+ "CrB": "Coronae Borealis",
109
+ "CrA": "Coronae Australis",
110
+ "TCrB": "TCoronae Borealis",
111
+ "Crt": "Crateris",
112
+ "Cru": "Crucis",
113
+ "Crv": "Corvi",
114
+ "CVn": "Canum Venaticorum",
115
+ "CMa": "Canis Majoris",
116
+ "CMi": "Canis Minors",
117
+ "Aur": "Aurigae",
118
+ "Car": "Carinae",
119
+ "Lyr": "Lyrae",
120
+ "Lep": "Leporis",
121
+ "Men": "Mensae",
122
+ "Mic": "Microscopii",
123
+ "Mon": "Monocerotis",
124
+ "Mus": "Muscae",
125
+ "Nor": "Normae",
126
+ "Oct": "Octantis",
127
+ "Ind": "Indi",
128
+ "Pav": "Pavonis",
129
+ "Peg": "Pegasi",
130
+ "Phe": "Phoenicis",
131
+ "LMi": "Leonis Minoris",
132
+ "Lup": "Lupi",
133
+ "Lyn": "Lyncis",
134
+ "Ser": "Serpentis",
135
+ "Tel": "Telescopium",
136
+ "TrA": "Trianguli Australis",
137
+ "Tri": "Trianguli",
138
+ "Tuc": "Tucanae",
139
+ "Her": "Herculis",
140
+ "Hor": "Horologii",
141
+ "Hya": "Hydrae",
142
+ "Hyi": "Hydri",
143
+ "Lac": "Lacertae",
144
+ "Per": "Persei",
145
+ "Pic": "Pictoris",
146
+ "PsA": "Piscis Austrini",
147
+ "Pup": "Puppis",
148
+ "Pyx": "Pyxis",
149
+ "Ret": "Reticulum",
150
+ "Scl": "Sculptoris",
151
+ "Vel": "Velorum", # Vela, contains Vela supercluster
152
+ "Vol": "Volantis",
153
+ "Vul": "Vulpeculae",
154
+ "VC": "Virgo Cluster",
155
+ "M": "Messier Object",
156
+ "NGC": "New General Catalogue",
157
+ "HIP": "Hipparcos Catalogue",
158
+ "HR": "Bright Star Catalogue",
159
+ "HD": "Henry Draper Catalogue",
160
+ }
161
+ }
162
+
163
+ def main():
164
+ args, argparser = get_args()
165
+
166
+ # if they dont pass any stars, print help message
167
+ if not args.stars:
168
+ argparser.print_help()
169
+ exit()
170
+
171
+ stars = []
172
+
173
+ for star in args.stars:
174
+ # only want the star lines; swe_make_star also returns the simbad ascii response
175
+ swe_star = swe_make_star(star)[0]
176
+ info_line = swe_star[0]
177
+ star_line_long_form_nomen = swe_star[1]
178
+ long_form_nomen = star_line_long_form_nomen.split(",")[0]
179
+ # now append the correct lines into outlines
180
+ star_line_split = star_line_long_form_nomen.split(",")[1:]
181
+ nomen = star_line_split[0]
182
+ # append nomen line first, then long_form, the eac name on the info line in order
183
+ info_line = info_line.split(",")
184
+ info_line.insert(2, " "+long_form_nomen)
185
+ info_line = ",".join(info_line)
186
+ stars.append(info_line)
187
+ stars.append(",".join([nomen]+star_line_split))
188
+ stars.append(star_line_long_form_nomen)
189
+ info_line = info_line.split(",")[1:]
190
+ for name in info_line:
191
+ # sometimes there are no more names, which appears as either empty string or a string of spaces, which .strip() converts to empty string, essentially
192
+ if name.strip() == "":
193
+ continue
194
+ if name.strip() == "no hip id":
195
+ continue
196
+ stars.append(",".join([name.strip()]+star_line_split))
197
+
198
+ if args.output_file:
199
+ with open(args.output_file,"a") as outfd:
200
+ outfd.writelines(stars)
201
+ exit()
202
+
203
+ print("".join(stars))
204
+
205
+
206
+ def swe_make_star(names=[""]) -> [str]:
207
+ """
208
+ make an entry for ephe/sefstars.txt to add star "name" to that file, and thus to swe
209
+ returns a list [sefstars.txt_entry,simbad_response_str]
210
+ """
211
+ import urllib.request
212
+ from string import Template
213
+ simbad_query = Template("https://simbad.cds.unistra.fr/simbad/sim-id?Ident=$swe_id&NbIdent=1&Radius=2&Radius.unit=arcmin&submit=submit%20id&output.format=ASCII")
214
+ swe_star_entry = Template("$trad_name,$nomen_name,ICRS,$ra_hour,$ra_minute,$ra_sec,$dec_degree,$dec_minute,$dec_sec,$pmra,$pmde,$rad_vel,$parallax,$magnitude_V")
215
+ if not isinstance(names,list):
216
+ names=[names]
217
+ ret = []
218
+ for name in names:
219
+ name = name.replace(" ","+")
220
+ the_bytes = urllib.request.urlopen(simbad_query.substitute(swe_id=name))
221
+ ascii = the_bytes.read().decode()
222
+ # lines=the_bytes.read().decode().split("\n")
223
+ # for n,line in enumerate(lines):
224
+ # print(n,line)
225
+ # now parse bytes into all the variables needs for swe_star_entry
226
+ response = parse_simbad_ascii_response(ascii)
227
+ try:
228
+ ids,trad_name,nomen_name,ra_hour,ra_minute,ra_sec,dec_degree,dec_minute,dec_sec,pmra,pmde,rad_vel,parallax,magV = response
229
+ except:
230
+ print("Error: \n")
231
+ print(response)
232
+ return
233
+ id_line = f"#0# {nomen_name.replace(",","")}, "
234
+ id_line += str(ids[1]+", "+ids[0]+"\n")
235
+ ret.append(id_line)
236
+ ret.append(f"{nomen_to_long_form(nomen_name)}{nomen_name},ICRS,{ra_hour},{ra_minute},{ra_sec},{dec_degree},{dec_minute},{dec_sec},{pmra},{pmde},{rad_vel},{parallax},{magV}\n")
237
+ return ret, ascii
238
+
239
+
240
+ def swe_write_stars(names=[""],outfile=""):
241
+ """
242
+ take a list of objects ids, names
243
+ write out to a file their entries for ephe/sefstars.txt
244
+ """
245
+ lines=[]
246
+ for name in names:
247
+ returns, ascii=swe_make_star(name)
248
+ # print(f"sws: {returns[0]=} {returns[1]=}")
249
+ lines.append(returns[0])
250
+ lines.append(returns[1])
251
+ # print(f"{lines=}")
252
+ with open(outfile,"a") as fd:
253
+ fd.writelines(lines)
254
+ return
255
+
256
+ def parse_simbad_ascii_response(response: str):
257
+ """
258
+ response is the http_response itself
259
+ """
260
+ lines = response.split("\n")
261
+ #import pdb; pdb.set_trace()
262
+ magV = None
263
+ parallax = None
264
+ hipid = "no hip id"
265
+ name = ""
266
+ nomen_name = ",noMen"
267
+ for n,line in enumerate(lines):
268
+ if n > 28:
269
+ # find HIP id so we can return it first as well
270
+ for n in range(28,50):
271
+ if n >= len(lines):
272
+ break
273
+ if "HIP" in lines[n]:
274
+ line = lines[n].split()
275
+ for i,element in enumerate(line):
276
+ if element == "HIP":
277
+ hipid = element+" "+line[i+1]
278
+ if "NAME" in lines[n]:
279
+ line = lines[n].split()
280
+ for i,element in enumerate(line):
281
+ if element == "NAME":
282
+ name = line[i+1]
283
+ break
284
+ match n:
285
+ case 2:
286
+ trad_name = str(line)
287
+ case 5:
288
+ names = line.split(" ")
289
+ # try to guess the ,noMen name
290
+ nomen_name = ","+names[2]+names[3]
291
+ case 7:
292
+ # icrs coordinates
293
+ icrs = line.split(" ")
294
+ ra_hour = icrs[1]
295
+ ra_minute = icrs[2]
296
+ ra_sec = icrs[3]
297
+ dec_degree = icrs[5]
298
+ dec_minute = icrs[6]
299
+ dec_sec = icrs[7]
300
+ case 11:
301
+ pm = line.split(" ")
302
+ pmra = pm[2]
303
+ pmde = pm[3]
304
+ case 13:
305
+ rad_vel = line.split(" ")
306
+ rad_vel = rad_vel[2]
307
+ case 12:
308
+ para = line.split(" ")
309
+ parallax = para[1]
310
+ if "Flux V" in line:
311
+ flux = line.split(" ")
312
+ magV = flux[3]
313
+ if not magV:
314
+ magV = 0
315
+ try:
316
+ return [hipid,name],trad_name,nomen_name,ra_hour,ra_minute,ra_sec,dec_degree,dec_minute,dec_sec,pmra,pmde,rad_vel,parallax,magV
317
+ except:
318
+ return response
319
+
320
+ def nomen_to_long_form(nomen: str):
321
+ """
322
+ turn a nomenclature name into a long form version of itself
323
+ nomenclature names, any of these designations:
324
+ Bayer, Falmsteed, HIP, NGC, HD, HR, M (Messer Object)
325
+ greek is lowercase greek letter, will use upper case in English
326
+ Latin is genitive of Latin constellation name
327
+ e.g., alfTau, Alpha Tauri, α Tauri
328
+ """
329
+ if nomen[0] == ",":
330
+ nomen = nomen[1:]
331
+ if nomen[0].isnumeric():
332
+ # this means it is Flamsteed
333
+ # easiest to do this first
334
+ number=""
335
+ n=0
336
+ while nomen[n].isnumeric():
337
+ number+=nomen[n]
338
+ n+=1
339
+ constellation=""
340
+ while n < len(nomen):
341
+ constellation+=nomen[n]
342
+ n+=1
343
+ return star_names_short_to_long["constellations"][constellation]+number
344
+ # check if this is a "special constellation"
345
+ # not really constellations, but fill the same place in the nomen name, so are treated the same for this purpose
346
+ special_constellations = ["VC","HD","HR","HIP","NGC"]
347
+ # doesnt include "M" because that throws off other checks
348
+ special = None
349
+ for constellation in special_constellations:
350
+ number=""
351
+ if constellation in nomen.upper() or (nomen.upper().startswith("M") and "mu." not in nomen):
352
+ # if one of these special tags is here, special will show us that it is
353
+ if nomen.upper().startswith("M"):
354
+ special = "M"
355
+ number = nomen[1:]
356
+ else:
357
+ special = constellation
358
+ # the rest of the string except the "constellation" names
359
+ number = nomen[(len(special)):]
360
+ break
361
+ if number != "":
362
+ return star_names_short_to_long["constellations"][special]+f" {number.strip()}"
363
+ if number == "":
364
+ if special == "VC":
365
+ return star_names_short_to_long["constellations"][special]
366
+ # now assume it is a Bayer designation
367
+ # some in the original sefstars.txt have a hyphen "-" in the name
368
+ # replace that with 0
369
+ # first three letters are the greek
370
+ greek = nomen[:3]
371
+ # last three are the Latin constellation
372
+ latin = nomen[3:]
373
+ # sometimes there are two stars with the same name basically, one is, e.g., gam01Sgr, the other, gam02Sgr
374
+ # this will be Gamma Sagittarii 1 and Gamma Sagittarii 2
375
+ number = ""
376
+ if latin[:2].isnumeric():
377
+ number = latin[:2]
378
+ latin = latin[2:]
379
+ if not greek.islower():
380
+ return nomen
381
+ if number:
382
+ return star_names_short_to_long["greek"][greek]+" "+star_names_short_to_long["constellations"][latin]+f" {number}"
383
+ return star_names_short_to_long["greek"][greek]+" "+star_names_short_to_long["constellations"][latin]
384
+
385
+ def get_args():
386
+ parser = argparse.ArgumentParser(
387
+ prog="make_swe_stars.py",
388
+ usage="%(prog)s [stars]: [stars] is a space-separated list. For star names with spaces, use quotation marks: \"Alpha Ursae Minoris\"",
389
+ description="make sefstars.txt entry for specified stars",
390
+ )
391
+ parser.add_argument(
392
+ "-o",
393
+ "--output-file",
394
+ help="write entries to output-file. otherwise, writes to stdout",
395
+ )
396
+ # parser.add_argument(
397
+ # "-Z",
398
+ # "--zodiac",
399
+ # action="store_true",
400
+ # help="toggle use of zodiac signs; can set default variable 'signs' in defaults.py",
401
+ # )
402
+ parser.add_argument("stars", nargs='*', help="stars to make entries for. you can enter multiple as a space separated list. if the name itself has a space in it, surround whole name with double-quotes: e.g., $ python make_swe_stars.py Sirius \"HIP 34567\" M87 \"Zeta Ursae Minoris\"")
403
+ args = parser.parse_args()
404
+ return args, parser
405
+
406
+ if __name__ == "__main__":
407
+ main()
@@ -0,0 +1,44 @@
1
+ https://masteringthezodiac.com/midpoint-method
2
+ all longitudes J2000
3
+ when using swe, set sid mode to 18, J2000
4
+ and call swe.fixstar with swe.FLG_SIDEREAL
5
+
6
+ Aries
7
+ Mesarthim ,gaAri
8
+ Botein ,deAri
9
+ Taurus
10
+ Omicron Tauri ,omiTau 51.1675 HIP 15900
11
+ Tianguan ,zeTau
12
+ Gemini
13
+ 1 Geminorum 90.9519 HIP 28734
14
+ Kappa Geminorum 113.6714
15
+ Cancer
16
+ Chi Cancri 120.9783
17
+ Acubens ,alCnc
18
+ Leo
19
+ Al Minlear - Kappa Leonis 135.3008
20
+ Denebola ,beLeo
21
+ Virgo
22
+ Nu Virginis 174.1608
23
+ Rijl al Awwa ,muVir
24
+ Libra
25
+ Zubenelgenubi ,al-2Lib
26
+ 48 Librae 240.3950
27
+ Scorpio
28
+ Dschubba ,deSco
29
+ Paikauhale 240.3950
30
+ Ophiucus
31
+ Sabik ,etOph
32
+ 45 Ophiuci 262.8753
33
+ Sagittarius
34
+ Alnasl ,ga-2Sgr
35
+ Terebellium ,omeSgr
36
+ Capricorn
37
+ Dabih ,beCap
38
+ Deneb Algedi ,deCap
39
+ Aquarius
40
+ Iota Aquarii 328.7161
41
+ Phi Aquarii 347.1364
42
+ Pisces
43
+ Gamma Piscium 351.4514
44
+ Alrescha ,alPsc
@@ -0,0 +1,6 @@
1
+ from .stellarium import Stellarium
2
+ # RemoteControl is the package StellariumRC
3
+ # i changed the class Stellarium to RemoteControl, that is the only difference
4
+ # i copied and pasted the one directory of code into remote_control
5
+ # the license is mit, even though known of the file have the license in them
6
+ from .remote_control import RemoteControl