Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to change different position #57

Open
Dong-L8 opened this issue Oct 9, 2022 · 2 comments
Open

How to change different position #57

Dong-L8 opened this issue Oct 9, 2022 · 2 comments

Comments

@Dong-L8
Copy link

Dong-L8 commented Oct 9, 2022

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.

@mnsarma
Copy link

mnsarma commented Jun 15, 2023

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.

@aum7
Copy link

aum7 commented May 29, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants