Open Dong-L8 opened 2 years ago
Hi, The calc_ut() returns the longitude of an object based on the Julian date number supplied. jd = 2460110.5, it gives the longitude, latitude, distance... of the object at 15-June-2023 @ 00:00 UT. when you convert for New York it is the position at 14-June-2023 20:00 hours EST (00:00 UT) as New York is -4 GMT.
If you want the position for 15-June-2023 @ 00:00 EST, you have to convert it in terms of UT which is 15-June-2023 04:00 UT, the corresponding Julian date is 2460110.66667. So if you give this value for calc_ut(), you the the position for midnight at New York.
This is the part where the programmer has to do his own calculation. Swiss ephemeris library doesn't do this. Please refer the documentation of Swiss ephemeris :: Programming interface to the Swiss Ephemeris Swiss Ephemeris Computer ephemeris for developers of astrological software
Such general doubts can be discussed in swiss ephemeris group , group dedicated to questions regarding Swiss ephemeris.
As this is not a issue with the code, I think you can close this.
from geocentric position (as is commonly used in all branches of astrology), positions of planets at particular moment in time are the same for all planets, no matter where the observer is located on earth, because geocentric means 'as viewed from center of the earth', opposed to topocentric, where the position of the observer does matter topocentric positions are generally not used in astrology, and they differ just slightly from geocentric positions, except for the fastest planet - the moon, it differs few degrees
for the ascendant and houses, however, the location of event / birth does matter so also for planetary hours and similar specific calculations
mnsarma's answer above is generally correct all be kindly warned, datetime is a programming chapter for itself, and it is not a simple matter
as per my understanding, here is my simplified example of the py code :
import sys
import platform
import subprocess
import datetime
try:
import swisseph as swe
# from swisseph import contrib as swh
print("swisseph imported (swe & swh); version " + swe.version)
except Exception as e:
print(f"swisseph not imported; error:\n{str(e)}")
# swisseph.contrib also has function to get timezone, latitude & longitude from
# city name, but at this moment i am getting errors using it
# pytz for converting local into utc time etc
# as of python 3.9+, there are built-in functions for datetime conversions,
# but we will use time-tested pytz module
try:
import pytz
print("pytz imported; version " + pytz.VERSION)
except Exception as e:
print(f"pytz not imported; error:\n{str(e)}")
# if sidereal calculations are needed
swe.set_sid_mode(swe.SIDM_LAHIRI)
# we need latitude & longitude of city / location; we can get it
# 1) manually from ie osm (open street map) or google maps, or
# 2) we can use python modules (ie pycities, or swisseph.contrib.atlas_search())
# to get lat, lon & tz (timezone) from city & country name
# we will use helsinki finland nep tv studio (where eurojackpot is drawn ;) )
# as our example; get either decimal coordinates (as on google maps; make sure to
# check which number is latitude and which is longitude !), or
# degree-minute-second format (astrology favorite)
props.lat_degree_1 = 60 # all integers
props.lat_minute_1 = 12
props.lat_second_1 = 15
props.lat_direction_1 = "n" # for north lat
# ... repeat for props.lon
# convert to decimal, swe favorite format
lat_1 = (
props.lat_degree_1 * 3600 + props.lat_minute_1 * 60 + props.lat_second_1
) / 3600
# lat direction can only be n(orth) or s(outh)
lat_string = "sn"
if props.lat_direction_1 not in lat_string:
print("latitude 1 direction error ! use 'n' for north or 's' for south")
# latitude : north is positive (+ve), south is negative (-ve)
if props.lat_direction_1 == "s":
lat_1 *= -1
# repeat calculations for
lon_1 = (
props.lon_degree_1 * 3600 + props.lon_minute_1 * 60 + props.lon_second_1
) / 3600
lon_string = "ew"
if props.lon_direction_1 not in lon_string:
print("longitude 1 direction error ! use 'e' for east or 'w' for west")
# longitude : e(ast) is positive (+ve), w(est) is negative (-ve)
if props.lon_direction_1 == "w":
lon_1 *= -1
# print(f"lat 1 {lat_1} ; lon 1 {lon_1}")
# TODO use swh.atlas... to get lat & lon & timezone, should work on all os-es
# those who want to get lat lon tz from city & country name, check pycities
# (https://github.com/onstabb/pycities/issues/1) or use swh.atlas functions
# another option is to use ($ pip install) timezonefinder to get tz from
# lat & lon; i am using this code from blender 3d app, therefore -> subprocess
# will call terminal, query timezonefinder, and return tz string
if platform.system() == "Linux":
timezone_name_1 = subprocess.run(
["timezonefinder", str(lon_1), str(lat_1)],
stdout=subprocess.PIPE,
).stdout
# subprocess returns bytes string -> decode / convert to normal string
timezone_name_1 = timezone_name_1.decode()
# remove trailing \n newline
timezone_name_1 = timezone_name_1.rstrip()
# huston, we have a timezone ! and we are not afraid to use it !
# print(f"timezone_name : {timezone_name}")
# now we calculate proper time offset, including dst (daylight saving time)
# that is, we will convert local (wall clock / wrist watch) time into utc time
# main reason being - i do not know for sure which time does swe.calc() expects -
# local time including dst, or just local time with utc offset (aka timezone)
# but i do know that swe.calc_ut() expects utc time :o
local_1 = pytz.timezone(timezone_name_1)
# following are event local time components, aka birth time
naive_1 = datetime.datetime( # naive is datetime which is not aware of tz
props.year_1, # ie 2024
props.month_1, # ie 13 - not ! lol
props.day_1, # ie 27
props.hour_1, # ie 15
props.minute_1, # ie 19
props.second_1,
)
local_dt_1 = local_1.localize(naive_1, is_dst=None)
utc_dt_1 = local_dt_1.astimezone(pytz.utc)
# we now have proper utc time, converted from local (clock) time - all hail python !
# it is in year-month-day-hour-minute-second format, but we need decimal hour
utc_time_1 = (
utc_dt_1.hour * 3600 + utc_dt_1.minute * 60 + utc_dt_1.second
) / 3600
# --- here the answer for this thread ends ---
# now we use swe functions; it is highly recommended (by swiss ephemeris authors)
# to initialize swisseph library with set_ephe_path() function; we need minimum
# semo_18.se1 & sepl_18.se1 (range ad 1800-2400), or complete ephe folder from:
# https://github.com/aloistr/swisseph/tree/master/ephe
props.ephe_path = "your/path/to/ephe/folder/"
if props.ephe_path != "None":
swe.set_ephe_path(props.ephe_path)
# if props.print_info:
# print(f"ephe path set to {props.ephe_path}")
else:
swe.set_ephe_path(None)
# if props.print_info:
# print("ephe path set to " + str(props.ephe_path))
# next, convert gregorian to julian day (jd); default time = 12:00 mid-day
jd_ut_1 = swe.julday(utc_dt_1.year, utc_dt_1.month, utc_dt_1.day, utc_time_1)
# print(f"jd_ut 1 : {jd_ut_1}")
# set swe flags from main settings (sidereal zodiac, ayanamsa, houses) &
# from miscellaneous settings (nutation, true positions) etc
flags = swe.FLG_SPEED # calculate speed of planets
# sidereal or tropical zodiac
if props.sidereal_zodiac:
flags |= swe.FLG_SIDEREAL
if not props.nutation:
flags |= swe.FLG_NONUT
if props.heliocentric:
flags |= swe.FLG_HELCTR
if props.true_positions:
flags |= swe.FLG_TRUEPOS
if props.topocentric:
flags |= swe.FLG_TOPOCTR
if props.equatorial:
flags |= swe.FLG_EQUATORIAL
if props.radians:
flags |= swe.FLG_RADIANS
if props.cartesian:
flags |= swe.FLG_XYZ
# print(f"flags : {flags}")
# if we want to use sidereal (jyotisa) zodiac ;)
swe.set_sid_mode(int(props.ayanamsa_enum)) # ie swe.SIDM_LAHIRI = 1
ayan = swe.get_ayanamsa_name(int(props.ayanamsa_enum))
# calculate positions for main planets / objects
for i in range(0, 12):
xx, retflags = swe.calc_ut(jd_ut_1, i, flags)
name = swe.get_planet_name(i)
# xx[i] is decimal number (float), if we need standard deg-min-sec-sign format:
deg, min, sec, secfr, sign = swe.split_deg(
xx[0],
swe.SPLIT_DEG_ROUND_SEC
| swe.SPLIT_DEG_ZODIACAL
| swe.SPLIT_DEG_KEEP_SIGN
| swe.SPLIT_DEG_KEEP_DEG,
)
# aries returns as 0, but is actually 1st sign
sign += 1
if name == "Sun":
pass # beam me up, scotty ! aka your code here
print(f"planet : {name}\nlon : {xx[0]}\nlat : {xx[1]}\ndist : {xx[2]}\n")
# calculate houses & asc / mc
house = props.house_enum # ie 'P' for placidus house system
# convert string to byte string, as expected by swe.house function
house_byte = bytes(house, "utf-8")
house_system = swe.house_name(house_byte)
# houses flags : 0 or FLG_SIDEREAL or FLG_RADIANS or FLG_NONUT
# houses_ex returns : cusps (12) & ascmc (8) : 0 asc | 1 mc | 2 armc |
# 3 vertex | 4 equatorial asc | 5 co-asc (koch) | 6 co-asc (munkasey) |
# 7 polar asc (munkasey)
# vertex = point on ecliptic, located in precise western direction
houses, ascmc = swe.houses_ex(jd_ut_1, lat_1, lon_1, house_byte, flags)
# print(f"houses : {houses}")
# print(f"ascmc : {ascmc}")
house_1 = houses[0] # asc & dsc - as sign-deg-min-sec
house_10 = houses[9] # mc & ic - as sign-deg-min-sec
house_8 = houses[7] # house 2 & 8 - as degree decimal
house_9 = houses[8] # house 3 & 9 - as degree decimal
house_11 = houses[10] # house 5 & 11 - as degree decimal
house_12 = houses[11] # house 6 & 12 - as degree decimal
# ascendant & midheaven are drawn separately from the rest of houses
# ascendant
deg_asc, min_asc, sec_asc, secfr_asc, sign_asc = swe.split_deg(
house_1,
swe.SPLIT_DEG_ROUND_SEC
| swe.SPLIT_DEG_ZODIACAL
| swe.SPLIT_DEG_KEEP_SIGN
| swe.SPLIT_DEG_KEEP_DEG,
)
sign_asc += 1
# your code here, ie i'll be back
# close swe after computations, to free memory
if props.print_info:
print(f"closing swe")
swe.close()
# swiss ephemeris end
have fun
aum
For different position(like in London or in NewYork) it should get different result when using "calc_ut()", so anyone knows how to change the specific position? I don't see any parameters in the function to change position.