A modern implementation of astrological calculations in Rust, focusing on accuracy and performance.
The project uses Swiss Ephemeris for high-precision astronomical calculations. Before building, you need to set up the Swiss Ephemeris files and library:
-
Download the Swiss Ephemeris source and ephemeris files:
- Go to https://www.astro.com/swisseph/ and download:
- The Swiss Ephemeris source code (for the C library)
- The Ephemeris files package (contains files like
seas_18.se1
,semo_18.se1
,sepl_18.se1
, etc.)
- Go to https://www.astro.com/swisseph/ and download:
-
Compile the Swiss Ephemeris C library:
- Extract the source code (if not already in
external/swisseph
). - In the
external/swisseph
directory, run:make
- This will generate the static library files (e.g.,
libswe.a
).
- Extract the source code (if not already in
-
Create the required directories:
mkdir -p $HOME/.swisseph/lib mkdir -p $HOME/.swisseph/include mkdir -p $HOME/.swisseph/ephe
-
Copy the compiled library and header files:
# Copy library and header files cp external/swisseph/*.h $HOME/.swisseph/include/ cp external/swisseph/*.a $HOME/.swisseph/lib/
-
Copy the ephemeris files:
- Copy all
.se1
and other ephemeris files from the downloaded ephemeris package to:
cp /path/to/downloaded/ephemeris/files/* $HOME/.swisseph/ephe/
- Ensure that files like
seas_18.se1
,semo_18.se1
, andsepl_18.se1
are present in$HOME/.swisseph/ephe
.
- Copy all
-
Set the environment variable (if needed):
- By default, the application looks for ephemeris files in
$HOME/.swisseph/ephe
. If you want to override this or run from a different location, set the environment variable before running:
export SE_EPHE_PATH=$HOME/.swisseph/ephe
- You can add this to your shell profile (e.g.,
~/.bashrc
,~/.zshrc
) to make it permanent.
- By default, the application looks for ephemeris files in
- Accurate VSOP87-based planetary position calculations
- Support for all major planets (Sun through Pluto)
- Proper handling of retrograde motion detection
- Stationary point calculations
- Geocentric and heliocentric coordinate systems
- Ecliptic to equatorial coordinate conversion
- Proper handling of coordinate system transformations
- Support for different ayanamsas (sidereal offsets)
- Multiple house system calculations
- Accurate house cusp determination
- Support for different house system methods
- Uses VSOP87 theory for high-precision planetary positions
- Implements proper retrograde motion detection with optimized time deltas:
- Mars: 0.1 Julian centuries (3650 days) for accurate retrograde detection
- Mercury: 0.01 Julian centuries (365 days) for precise motion tracking
- Handles 0°/360° boundary crossing in speed calculations
- Provides detailed debug output for motion analysis
- Time-dependent obliquity of ecliptic
- Proper handling of coordinate transformations
- Support for different coordinate systems and reference frames
- Written in Rust for high performance and safety
- Efficient algorithms for astronomical calculations
- Optimized coordinate transformations
use astrolog_rs::calc::planets;
// Calculate planetary positions for a given Julian date
let jd = 2460314.5; // January 14, 2024
let positions = planets::calculate_planet_positions(jd)?;
// Access individual planet positions
for position in positions {
println!("Longitude: {:.2}°, Latitude: {:.2}°, Speed: {:.2}°/day, Retrograde: {}",
position.longitude,
position.latitude,
position.speed,
position.is_retrograde
);
}
The server provides a REST API for generating astrological charts. Here are some example requests:
curl -X POST http://localhost:4008/api/chart/natal \
-H "Content-Type: application/json" \
-d '{
"date": "2024-01-14T12:00:00Z",
"latitude": 40.7128,
"longitude": -74.0060,
"house_system": "placidus",
"ayanamsa": "tropical"
}'
curl -X POST http://localhost:4008/api/chart/transit \
-H "Content-Type: application/json" \
-d '{
"natal_date": "1990-01-01T12:00:00Z",
"transit_date": "2024-01-14T12:00:00Z",
"latitude": 40.7128,
"longitude": -74.0060,
"house_system": "placidus",
"ayanamsa": "tropical"
}'
curl -X POST http://localhost:4008/api/chart/synastry \
-H "Content-Type: application/json" \
-d '{
"chart1": {
"date": "1977-10-24T12:00:00Z",
"latitude": 14.6488,
"longitude": 121.0509,
"house_system": "placidus",
"ayanamsa": "tropical"
},
"chart2": {
"date": "1996-01-06T12:00:00Z",
"latitude": 36.66833,
"longitude": 116.99722,
"house_system": "placidus",
"ayanamsa": "tropical"
}
}'
Response:
{
"chart_type": "synastry",
"chart1": {
"chart_type": "natal",
"date": "1977-10-24T12:00:00Z",
"latitude": 14.6488,
"longitude": 121.0509,
"house_system": "placidus",
"ayanamsa": "tropical",
"planets": [...],
"houses": [...]
},
"chart2": {
"chart_type": "natal",
"date": "1996-01-06T12:00:00Z",
"latitude": 36.66833,
"longitude": 116.99722,
"house_system": "placidus",
"ayanamsa": "tropical",
"planets": [...],
"houses": [...]
},
"aspects": [...]
}
Generate a natal chart for a given location and birth date/time.
POST /api/chart/natal
Request body:
{
"date": "2000-01-01T12:00:00Z", // Birth date/time in ISO 8601 format
"latitude": 40.7128, // Birth location latitude
"longitude": -74.0060, // Birth location longitude
"house_system": "placidus", // House system (placidus, koch, equal, wholesign, etc.)
"ayanamsa": "tropical" // Ayanamsa system (tropical, lahiri, etc.)
}
Response:
{
"planets": [
{
"name": "Sun",
"longitude": 280.5,
"latitude": 0.0,
"speed": 1.0,
"is_retrograde": false,
"house": 10
},
// ... other planets
],
"houses": [
{
"number": 1,
"longitude": 0.0,
"latitude": 0.0
},
// ... other houses
],
"aspects": [
{
"planet1": "Sun",
"planet2": "Moon",
"aspect": "Conjunction",
"orb": 2.5
},
// ... other aspects
]
}
Generate a transit chart comparing current or future planetary positions to a natal chart.
POST /api/chart/transit
Request body:
{
"natal_date": "2000-01-01T12:00:00Z", // Birth date/time
"transit_date": "2024-01-01T12:00:00Z", // Current/future date to check
"latitude": 40.7128, // Location latitude
"longitude": -74.0060, // Location longitude
"house_system": "placidus", // House system
"ayanamsa": "tropical" // Ayanamsa system
}
Response:
{
"natal_planets": [
// Same format as natal chart planets
],
"transit_planets": [
// Same format as natal chart planets
],
"aspects": [
{
"planet1": "Sun",
"planet2": "Moon",
"aspect": "Conjunction",
"orb": 2.5
},
// ... other aspects
]
}
Generate a synastry chart comparing two natal charts.
POST /api/chart/synastry
Request body:
{
"chart1": {
"date": "2000-01-01T12:00:00Z", // Person A's birth date/time
"latitude": 40.7128, // Person A's birth location latitude
"longitude": -74.0060, // Person A's birth location longitude
"house_system": "placidus", // House system
"ayanamsa": "tropical" // Ayanamsa system
},
"chart2": {
"date": "1995-01-01T12:00:00Z", // Person B's birth date/time
"latitude": 34.0522, // Person B's birth location latitude
"longitude": -118.2437, // Person B's birth location longitude
"house_system": "placidus", // House system
"ayanamsa": "tropical" // Ayanamsa system
}
}
Response:
{
"chart1_planets": [
// Person A's planets
],
"chart2_planets": [
// Person B's planets
],
"aspects": [
{
"planet1": "Sun",
"planet2": "Moon",
"aspect": "Conjunction",
"orb": 2.5
},
// ... other aspects
]
}
All endpoints return standard HTTP status codes:
- 200: Success
- 400: Bad Request (invalid input)
- 500: Internal Server Error
Error response format:
{
"error": "Error message description"
}
- All dates should be in ISO 8601 format
- Latitude and longitude should be in decimal degrees
- Supported house systems: placidus, koch, equal, wholesign, campanus, regiomontanus
- Supported ayanamsa systems: tropical, lahiri, raman, krishnamurti, etc.
cargo build
cargo test
RUST_LOG=debug cargo test
cargo run --bin server
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
- Based on the original Astrolog software
- Uses VSOP87 theory for planetary positions
- Implements algorithms from Meeus' Astronomical Algorithms
Changes in the last version Astrolog 5.41G
-
Fixed original Astrolog bug, where Local Horizon data (and also Prime Vertical) were off by up to several arc-minutes.
-
Fixed original Astrolog bug (Windows version), where "Time / Space Midpoint" chart is correct, but it was not possible to return back to "No relationship chart" - there was still previous "midpoint" chart.
-
In "Rising and Setting" chart fixed bug, where "Print Nearest Second" worked unproperly - seconds weren't shown for risings and settings.
In this context more correct termin instead of "zenith" and "nadir" is astronomical termin "culmination" that means transit over meridian. There are two culminations: "upper culmination" when planet has highest position and "lower culmination" when planet has lowest position. So in the chart termins "zeniths" and "nadirs" are replaced by "culm.(up)" and "culm.(lo)" respectively.
-
Uncorrect object name "Nadir" has been replaced by corret "IC". Nadir has different meaning than IC, Nadir is the point on the sky opposite to Zenith.
-
Slightly improved Astrolog's behaviour in case of progressed and relationship charts. Earlyer Windows versions allowed to do progression and then do some relationship chart like Natal-Progressed. Or vice versa, when looking say Natal-Progressed chart switch also Progression "on". That all confused Astrolog and results were often unpredictable.
Now any use of relationship charts (in menu "Info") switches off "Do Progression" (in "Chart" => "Progressions"). And vice versa, switching progression on (in "Chart" => "Progression") switches off any comparison. As result Astrolog is displaying just what it has to dasplay, no confusion.
-
Fixed orignal astrolog bug (appeared only in Windows version). When natal chart was opened from file with saved planets positions (not birth data), there only first output was correct, all next charts (as aspect list, transit searches, all comparison charts etc) had wrong planets positions.
NB! Use such input files carefully! They are treated by astrolog as files "with no time and space", so a lot of chart types can't be used with them. An examples are all progression charts, because they needs birth-chart time to calculate progressions.
-
Fixed bug of changed versions, where in case of use of data with saved planet positions (just as above), data-border of graphics charts dilsplayed info "no time or space" twice.
-
Time and location have new format - with seconds, both for chart's data inputs and outputs. Only outputs with old data format are events searching outputs, because with reasonably low division value they anyway can be off by a few minutes, so seconds seems unnecessary there.
"Rising and setting" chart is only exception among searching charts that shows time with seconds. Even with default setting d: 48 times are off by only a few seconds, and it is quick enough to show precise (by seconds) times with d: 96 in reasonably short time. Note, that values of azimuth angles in rising/setting moment are extremely sensitive of time changes (very small change of time causes big change in azimuth) and can be off by a few seconds. To improve azimuth precision one has to increase division value up to hundreds.
All input files with old time/location format can be used, but all outputs are saved only in new time/location format.
-
Calculations precision improved - time-dependent obliquity of ecliptic is used instead of fixed value.
-
Added new switsh to change local horizon text output from default ENWS to NESW. One has just to add line
=YZ
to astrolog.dat file and it will be deafult setting.
-
Slightly changed Prime Vertical text chart output: Altitude and Azimuth in header have been replaced by Amplitude and Prm-Vrt. One can see this chart by choosing "Local Horizon" and setting "Horizon Chart with Polar Center / Prime Vert. (text)" in "Chart settings". Note, that this switch has different meanings for text and graphics charts: in text mode it switches between Local Horizon <=> Prime Vertical outputs, in graphics it switches between "normal wiew" and "view vith Polar Center". However, one can switch also between Polar Center and Pime Vert. also in graphics by hitting 'i' on the keyboard (switch to bonus mode).
-
Changed calculations of Solar Arc. Original Astrolog calculates there actually directions, where all planets and house cusps positions are moved forward to an amount equal in degrees to the number of years that have passed between the specified date and the chart in question. Because real (even mean or average) motion of Sun isn't 1 degree per day, resulting Solar Arc Sun position doesn't match with secondary progressed Sun position (but they must match).
To correct this situation, there has been added another calculation of Solar Arc - first secondary progressed Sun's position is determined and then all chart components are moved accordlingly.
To avoid misunderstanding, existing Solar Acr calculations remains, but have now corrected name "Degree Per Day/Month", as earlyer one can change amount of degrees per year (more strictly, amount of days for 1 degree direction. See description of -p0 and -pd switches in helpfile.540). Added calculation is named "Solar Arc Directions" and there Sun's position follows secondary progressed Sun positions, all other point in chart are moved accordlingly.
Existing switches -p0, -p0n remain as previously. For new correct "Solar Arc Directions" calculations new switches -p1 and -p1n are used. In Windows version all can be done through menus: "Chart" => "Progressions..."
-
Slightly changed chraphics charts' infoborder and text charts' headers
- secondary progressed charts are still named as "progressed", Solar Arc and "Degree per Year/Mont" are marked as "directed" with name of direction.
-
Graphics chart's infoborder has additional information: Obliquity of ecliptic, Sidereal time, Delta T (in seconds) and in case of sidereal chart Ayanamsha (sidereal offest).
Note, that Ayanamsha has negative value and dafaults to Fagan Bradley. Ayanamsha control in "Calculation Settings" has a dropdown to allow quick selection of some common systems of sidereal astrology. The values are additions to default value and they are 0.0 for Fagan Bradley, 0.883333 (or 0 degrees 53') for N.C. Lahiri, 0.983333 (or 0 degrees 59') for Krishnamurti, and 2.333333 (or 2 degrees 20') for B.V. Raman. On the screen has shown resulting value.
-
Date/time and Julian Day in the graphics charts' infoboredr has been colored:
1. First (or single) data/time is always bright white. 2. Second date/time is always yellow. 3. JD (which is actually also time/date) has color of corresponding date/time above (as yellow in case of transit comparison or direction charts). If JD doesn't correspond to neither date/time above (as in case of progressions where JD corresponds to date/time of planets' positions on the screen), color is green. Note, that in case of Synastry and Comparison charts JD will be yellow, becsuse it corresponds to second date/time above (data of second chart).
-
Windows version controls of progressed charts have been polished. They looks more clear now. As default 365.2422 (tropical) year has used.
In "Degree per Days" dropdown are also available:
365.25636 (sidereal year) 27.321582 (tropical month) 27.321661 (sidereal month) 29.530588 (synodic month)
Other more exotic (like Draconic) years/months aren't included.
-
Astrolog computes position of Lilith (Dark Moon) using external ephemeris. When ephemeris are set off, Astrolog will display the position of the South Node instead (see helpfile.540, description of -HO switch). For users, who wants to use South Node always, there has been added new switch =YN which forces Astrolog to do it. This switch can be entered through "Edit" => "Enter Command Line" (Windows version) or simply added to astrolog.dat file to make this behaviour default.
-
By default Astrolog calculates mean Lilith. For users who wants to use osculting position of Lilith, new switch -YL has been added. As above, this switch can be added to astrolog.dat file, which makes such behaviour default.
-
Dispositors glyphs on the graphics wheels can be switched on/off using switch -YD. It can be added to astrolg.dat file: =YD (on) or _YD (off), default "on".
18th. May. 2002
The server can be run as a systemd service, allowing it to start automatically on boot and be managed by systemd. The service runs as a regular user and supports configurable ports.
- Navigate to the systemd directory:
cd systemd
- Run the installation script:
./install-service.sh
The service will be installed and started automatically. By default, it runs on port 8808.
The service can be configured by editing the service file at /etc/systemd/system/astrolog-rs.service
. Key configuration options:
PORT
: The port number the server listens on (default: 8808)RUST_LOG
: Logging level (default: info)EPHE_PATH
: Path to the Swiss Ephemeris files
To apply configuration changes:
sudo systemctl daemon-reload
sudo systemctl restart astrolog-rs@username
Check service status:
systemctl status astrolog-rs@username
View service logs:
journalctl -u astrolog-rs@username
Stop the service:
sudo systemctl stop astrolog-rs@username
Start the service:
sudo systemctl start astrolog-rs@username
To remove the service:
cd systemd
./uninstall-service.sh
The server can be run as a systemd service, allowing it to start automatically on boot and be managed by systemd. The service runs as a regular user and supports configurable ports.
- Navigate to the systemd directory:
cd systemd
- Run the installation script:
./install-service.sh
The service will be installed and started automatically. By default, it runs on port 8808.
The service can be configured by editing the service file at /etc/systemd/system/astrolog-rs.service
. Key configuration options:
PORT
: The port number the server listens on (default: 8808)RUST_LOG
: Logging level (default: info)EPHE_PATH
: Path to the Swiss Ephemeris files
To apply configuration changes:
sudo systemctl daemon-reload
sudo systemctl restart astrolog-rs@username
Check service status:
systemctl status astrolog-rs@username
View service logs:
journalctl -u astrolog-rs@username
Stop the service:
sudo systemctl stop astrolog-rs@username
Start the service:
sudo systemctl start astrolog-rs@username
To remove the service:
cd systemd
./uninstall-service.sh
The server can be run as a systemd service, allowing it to start automatically on boot and be managed by systemd. The service runs as a regular user and supports configurable ports.
- Navigate to the systemd directory:
cd systemd
- Run the installation script:
./install-service.sh
The service will be installed and started automatically. By default, it runs on port 8808.
The service can be configured by editing the service file at /etc/systemd/system/astrolog-rs.service
. Key configuration options:
PORT
: The port number the server listens on (default: 8808)RUST_LOG
: Logging level (default: info)EPHE_PATH
: Path to the Swiss Ephemeris files
To apply configuration changes:
sudo systemctl daemon-reload
sudo systemctl restart astrolog-rs@username
Check service status:
systemctl status astrolog-rs@username
View service logs:
journalctl -u astrolog-rs@username
Stop the service:
sudo systemctl stop astrolog-rs@username
Start the service:
sudo systemctl start astrolog-rs@username
To remove the service:
cd systemd
./uninstall-service.sh
A high-performance astrological calculation server written in Rust.
- Natal chart calculations
- Transit chart calculations
- Synastry chart calculations
- High-performance concurrent request handling
- Swiss Ephemeris integration
- Rust (latest stable version)
- Swiss Ephemeris library and files
- For load testing:
hey
tool (install viabrew install hey
on macOS)
- Clone the repository:
git clone https://github.com/yourusername/astrolog-rs.git
cd astrolog-rs
-
Install Swiss Ephemeris:
- Download Swiss Ephemeris files
- Place them in
~/.swisseph/ephe/
- Install Swiss Ephemeris library in
~/.swisseph/lib/
-
Build the project:
cargo build --release
To start the server with default settings:
./start-server.sh
For best performance, run with sudo to apply system optimizations:
sudo ./start-server.sh
The server will start on port 4008 by default. You can configure the following environment variables:
PORT
: Server port (default: 4008)WORKERS
: Number of worker threads (default: 2x CPU cores)MAX_CONCURRENT
: Maximum concurrent calculations (default: 1000)RUST_LOG
: Log level (default: info)
The project includes load testing scripts to verify performance under high concurrency.
-
Install the
hey
load testing tool:- macOS:
brew install hey
- Linux:
go install github.com/rakyll/hey@latest
- macOS:
-
Make the test script executable:
chmod +x load_tester/loadtest.sh
Run the load tests with:
cd load_tester
./loadtest.sh
The load test script will:
- Test each endpoint (natal, transit, synastry)
- Progressively increase concurrency (100, 200, 500, 1000)
- Run each test for 60 seconds
- Wait 10 seconds between tests for connection cleanup
The load tests use the following JSON payloads:
natal_payload.json
: Natal chart calculation parameterstransit_payload.json
: Transit chart calculation parameterssynastry_payload.json
: Synastry chart calculation parameters
curl -X POST http://localhost:4008/api/chart/natal \
-H "Content-Type: application/json" \
-d @natal_payload.json
curl -X POST http://localhost:4008/api/chart/transit \
-H "Content-Type: application/json" \
-d @transit_payload.json
curl -X POST http://localhost:4008/api/chart/synastry \
-H "Content-Type: application/json" \
-d @synastry_payload.json
The server is optimized for high concurrency with:
- Multiple worker threads
- Connection pooling
- Response compression
- Optimized TCP settings
- System resource limits
For best performance:
- Run with sudo to apply system optimizations
- Adjust
WORKERS
andMAX_CONCURRENT
based on your system - Monitor system resources during load tests
[Your License]