Astrolith

A Ruby port of the immanuel-python astrology library, functioning as a decoupled data calculation engine with structured JSON output.

Tests Ruby

Features

  • Multiple Chart Types: Natal, Solar Return, Progressed, Composite, Transit
  • Comprehensive Data: Planets, houses, aspects, dignities, decans, moon phase, chart shape
  • Swiss Ephemeris: High-precision astronomical calculations using built-in Moshier ephemeris
  • No External Files Required: Uses analytical ephemeris (precision: ~0.1 arc seconds for planets, ~3" for Moon)
  • JSON Output: Structured data output for easy integration
  • Flexible Input: Multiple formats for coordinates, datetime, and timezone
  • 7 House Systems: Placidus, Koch, Whole Sign, Equal, Porphyrius, Regiomontanus, Campanus

Installation

Add this line to your application's Gemfile:

gem 'astrolith'

And then execute:

bundle install

Or install it yourself as:

gem install astrolith

Quick Start

require 'ruby_chart_engine'

# Create a natal chart
chart = RubyChartEngine::Charts::Natal.new(
  datetime: '1990-05-15T14:30:00',
  latitude: 40.7128,
  longitude: -74.0060,
  timezone: 'America/New_York',
  house_system: :placidus
)

# Access chart data
puts chart.planets[:sun][:sign][:name]  # => "Taurus"
puts chart.planets[:sun][:house]        # => 10
puts chart.moon_phase                   # => "Waxing Gibbous"
puts chart.chart_shape                  # => "bowl"

# Export to JSON
json = chart.to_json
puts json

Usage Examples

Natal Chart

chart = RubyChartEngine::Charts::Natal.new(
  datetime: '1990-05-15T14:30:00',
  latitude: 40.7128,
  longitude: -74.0060,
  timezone: 'America/New_York'
)

# Access planetary data
sun = chart.planets[:sun]
# => {
#   longitude: 54.123,
#   sign_longitude: 24.123,
#   sign: { name: "Taurus", element: "Earth", modality: "Fixed" },
#   house: 10,
#   decan: 3,
#   movement: "direct",
#   dignities: { domicile: false, exaltation: false, ... }
# }

# Check aspects
chart.aspects.each do |aspect|
  puts "#{aspect[:planet1]} #{aspect[:type]} #{aspect[:planet2]} (orb: #{aspect[:orb]}�)"
end

Solar Return

solar_return = RubyChartEngine::Charts::SolarReturn.new(
  natal_datetime: '1990-05-15T14:30:00',
  return_year: 2024,
  latitude: 40.7128,
  longitude: -74.0060,
  timezone: 'America/New_York'
)

Progressed Chart

progressed = RubyChartEngine::Charts::Progressed.new(
  natal_datetime: '1990-05-15T14:30:00',
  progression_date: '2024-03-15',
  latitude: 40.7128,
  longitude: -74.0060,
  timezone: 'America/New_York'
)

Composite Chart

composite = RubyChartEngine::Charts::Composite.new(
  chart1_params: {
    datetime: '1990-05-15T14:30:00',
    latitude: 40.7128,
    longitude: -74.0060,
    timezone: 'America/New_York'
  },
  chart2_params: {
    datetime: '1992-08-20T10:00:00',
    latitude: 34.0522,
    longitude: -118.2437,
    timezone: 'America/Los_Angeles'
  }
)

Transit Chart

natal = RubyChartEngine::Charts::Natal.new(
  datetime: '1990-05-15T14:30:00',
  latitude: 40.7128,
  longitude: -74.0060,
  timezone: 'America/New_York'
)

transit = RubyChartEngine::Charts::Transit.new(
  natal_chart_params: natal,
  transit_datetime: Time.now.iso8601
)

# View transit aspects
transit.transit_aspects.each do |aspect|
  puts "#{aspect[:planet1]} #{aspect[:type]} #{aspect[:planet2]}"
end

Input Formats

Coordinates

# Decimal degrees
latitude: 40.7128, longitude: -74.0060

# Text format (degrees and minutes)
latitude: '40n43', longitude: '74w00'

# Mixed formats work too
latitude: 40.7128, longitude: '74w00'

DateTime

# ISO 8601 string
datetime: '1990-05-15T14:30:00'

# Hash
datetime: { year: 1990, month: 5, day: 15, hour: 14, minute: 30 }

# Ruby DateTime object
datetime: DateTime.new(1990, 5, 15, 14, 30, 0)

House Systems

# Available systems:
house_system: :placidus       # Default
house_system: :koch
house_system: :whole_sign
house_system: :equal
house_system: :porphyrius
house_system: :regiomontanus
house_system: :campanus

Output Structure

{
  "metadata": {
    "datetime": "1990-05-15T14:30:00+00:00",
    "julian_day": 2448025.1041666665,
    "latitude": 40.7128,
    "longitude": -74.006,
    "timezone": "America/New_York",
    "house_system": "placidus"
  },
  "planets": {
    "sun": {
      "longitude": 54.123,
      "sign_longitude": 24.123,
      "sign": { "name": "Taurus", "element": "Earth", "modality": "Fixed" },
      "house": 10,
      "decan": 3,
      "movement": "direct",
      "dignities": { "domicile": false, "exaltation": false, ... }
    }
  },
  "houses": { "cusps": [...] },
  "angles": { "ascendant": {...}, "midheaven": {...}, ... },
  "aspects": [...],
  "moon_phase": "Waxing Gibbous",
  "chart_shape": "bowl"
}

Celestial Objects

Planets: Sun, Moon, Mercury, Venus, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto

Points: North Node, South Node (Note: Chiron is not available when using the built-in Moshier ephemeris)

Angles: Ascendant, Midheaven, Descendant, Imum Coeli

Aspects

Supported aspects with configurable orbs:

  • Conjunction (0�)
  • Opposition (180�)
  • Trine (120�)
  • Square (90�)
  • Sextile (60�)
  • Quincunx (150�)
  • Semi-Sextile (30�)
  • Semi-Square (45�)
  • Sesquiquadrate (135�)

Testing

Run the test suite:

bundle exec rspec

# With documentation format
bundle exec rspec --format documentation

# Run specific test file
bundle exec rspec spec/charts/natal_spec.rb

Dependencies

  • swe4r: Swiss Ephemeris C extension for astronomical calculations
  • ephemeris: Higher-level astrological logic built on swe4r
  • daru: Data Analysis in Ruby for data structuring
  • tzinfo: Timezone handling

Optional Visualization

  • apexcharts: For analytical charts
  • prawn: For PDF and geometric drawing (chart wheels)

Documentation

Development

After checking out the repo:

# Install dependencies
bundle install

# Run tests
bundle exec rspec

# Run console for experimentation
bundle console

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

License

MIT License

Acknowledgments

This library is a Ruby port of immanuel-python, maintaining compatibility with its JSON output structure while leveraging Ruby's ecosystem.

Notes

  • This implementation uses the built-in Moshier ephemeris (analytical calculations) which provides excellent precision without requiring external ephemeris files
  • Chiron is not available with the Moshier ephemeris (would require external .se1 files)
  • For production use with extended date ranges or maximum precision, consider using the full Swiss Ephemeris with external data files