Skip to content
This repository has been archived by the owner on Aug 4, 2018. It is now read-only.
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: astrotools/swego
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.1.0
Choose a base ref
...
head repository: astrotools/swego
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref

Commits on Aug 7, 2016

  1. swego: add EclNut constant

    dwlnetnl committed Aug 7, 2016
    Copy the full SHA
    52c8bdb View commit details

Commits on Aug 14, 2016

  1. Copy the full SHA
    0dcbfaa View commit details

Commits on Sep 4, 2016

  1. Copy the full SHA
    f906fea View commit details
  2. Copy the full SHA
    4659ca5 View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    64a7c05 View commit details
  4. Copy the full SHA
    7a79026 View commit details

Commits on Oct 4, 2016

  1. Copy the full SHA
    d64dd32 View commit details

Commits on Oct 5, 2016

  1. Copy the full SHA
    6108731 View commit details

Commits on Oct 6, 2016

  1. Copy the full SHA
    dcbc33b View commit details

Commits on Jan 26, 2017

  1. Copy the full SHA
    918c3bd View commit details
  2. Copy the full SHA
    69e4703 View commit details
  3. swego: add Error type

    dwlnetnl committed Jan 26, 2017
    Copy the full SHA
    ee9ed31 View commit details
  4. Copy the full SHA
    a08b249 View commit details
  5. Copy the full SHA
    491ee8a View commit details

Commits on Jan 27, 2017

  1. Copy the full SHA
    4f395fc View commit details

Commits on Jan 28, 2017

  1. Copy the full SHA
    ff43629 View commit details

Commits on Feb 8, 2017

  1. Copy the full SHA
    596e4cc View commit details
  2. Copy the full SHA
    5e96e13 View commit details
  3. Copy the full SHA
    02d702d View commit details
  4. Copy the full SHA
    d93025a View commit details
  5. swego: update read me

    dwlnetnl committed Feb 8, 2017
    Copy the full SHA
    58c37ed View commit details
Showing with 57,689 additions and 43,969 deletions.
  1. +5 −74 README.md
  2. +2 −0 cmd/swerker/.gitignore
  3. +18 −0 cmd/swerker/Makefile
  4. +161 −0 cmd/swerker/README.md
  5. +3 −0 cmd/swerker/doc.go
  6. +477 −0 cmd/swerker/handlers.c
  7. +19 −0 cmd/swerker/handlers.h
  8. +34 −0 cmd/swerker/msgpuck.c
  9. +3,005 −0 cmd/swerker/msgpuck.h
  10. +160 −0 cmd/swerker/swerker.c
  11. +1 −0 cmd/swerker/sweversion.h
  12. +1 −0 cmd/swerker/swex.c
  13. +1 −0 cmd/swerker/swex.h
  14. +174 −0 cmd/swerker/tr-stdio.c
  15. +12 −0 cmd/swerker/tr.h
  16. +10 −12 consts.go → const.go
  17. +43 −25 swecgo/examples_test.go
  18. +85 −246 swecgo/swecgo.go
  19. +460 −506 swecgo/swecgo_test.go
  20. +33 −71 swecgo/swecgolib.go
  21. +278 −0 swecgo/swecgowrap.go
  22. +0 −6,066 swecgo/swecl.c
  23. +1 −0 swecgo/swecl.c
  24. +0 −592 swecgo/swedate.c
  25. +1 −0 swecgo/swedate.c
  26. +0 −82 swecgo/swedate.h
  27. +1 −0 swecgo/swedate.h
  28. +0 −3,478 swecgo/swehel.c
  29. +1 −0 swecgo/swehel.c
  30. +0 −2,527 swecgo/swehouse.c
  31. +1 −0 swecgo/swehouse.c
  32. +0 −87 swecgo/swehouse.h
  33. +1 −0 swecgo/swehouse.h
  34. +0 −929 swecgo/swejpl.c
  35. +1 −0 swecgo/swejpl.c
  36. +0 −104 swecgo/swejpl.h
  37. +1 −0 swecgo/swejpl.h
  38. +0 −1,931 swecgo/swemmoon.c
  39. +1 −0 swecgo/swemmoon.c
  40. +0 −968 swecgo/swemplan.c
  41. +1 −0 swecgo/swemplan.c
  42. +0 −10,641 swecgo/swemptab.h
  43. +1 −0 swecgo/swemptab.h
  44. +0 −2,820 swecgo/swenut2000a.h
  45. +1 −0 swecgo/swenut2000a.h
  46. +0 −342 swecgo/sweodef.h
  47. +1 −0 swecgo/sweodef.h
  48. +0 −7,094 swecgo/sweph.c
  49. +1 −0 swecgo/sweph.c
  50. +0 −634 swecgo/sweph.h
  51. +1 −0 swecgo/sweph.h
  52. +0 −941 swecgo/swephexp.h
  53. +1 −0 swecgo/swephexp.h
  54. +0 −3,503 swecgo/swephlib.c
  55. +1 −0 swecgo/swephlib.c
  56. +0 −224 swecgo/swephlib.h
  57. +1 −0 swecgo/swephlib.h
  58. BIN swecgo/swephprg.pdf
  59. +1 −0 swecgo/sweversion.h
  60. +1 −0 swecgo/swex.c
  61. +1 −0 swecgo/swex.h
  62. BIN swecgo/swisseph.pdf
  63. +123 −72 swego.go
  64. +59 −0 swego_test.go
  65. +147 −0 swerker/stdio/internal/lichdata/lichdata.go
  66. +104 −0 swerker/stdio/internal/lichdata/lichdata_test.go
  67. +36 −0 swerker/stdio/internal/worker/funcs.go
  68. +86 −0 swerker/stdio/internal/worker/funcs_gen.go
  69. +125 −0 swerker/stdio/internal/worker/funcs_gen_test.go
  70. +60 −0 swerker/stdio/internal/worker/funcs_test.go
  71. +178 −0 swerker/stdio/internal/worker/mock_test.go
  72. +108 −0 swerker/stdio/internal/worker/output.go
  73. +114 −0 swerker/stdio/internal/worker/output_gen.go
  74. +125 −0 swerker/stdio/internal/worker/output_gen_test.go
  75. +93 −0 swerker/stdio/internal/worker/output_test.go
  76. +184 −0 swerker/stdio/internal/worker/worker.go
  77. +317 −0 swerker/stdio/internal/worker/worker_test.go
  78. +315 −0 swerker/stdio/stdio.go
  79. +296 −0 swerker/stdio/stdio_test.go
  80. +37 −0 swerker/swerker.go
  81. +301 −0 swerker/swerker_gen.go
  82. +238 −0 swerker/swerker_gen_test.go
  83. +82 −0 swex/genversion.go
  84. +10 −0 swex/sweversion.h
  85. +49 −0 swex/swex.c
  86. +8 −0 swex/swex.h
  87. 0 {swecgo → swisseph}/LICENSE
  88. +60 −0 swisseph/Makefile
  89. +6,106 −0 swisseph/swecl.c
  90. +593 −0 swisseph/swedate.c
  91. +82 −0 swisseph/swedate.h
  92. +541 −0 swisseph/swedll.h
  93. +3,502 −0 swisseph/swehel.c
  94. +2,691 −0 swisseph/swehouse.c
  95. +87 −0 swisseph/swehouse.h
  96. +929 −0 swisseph/swejpl.c
  97. +104 −0 swisseph/swejpl.h
  98. +1,931 −0 swisseph/swemmoon.c
  99. +968 −0 swisseph/swemplan.c
  100. +10,641 −0 swisseph/swemptab.h
  101. +2,820 −0 swisseph/swenut2000a.h
  102. +342 −0 swisseph/sweodef.h
  103. +758 −0 swisseph/swepcalc.c
  104. +486 −0 swisseph/swepcalc.h
  105. +242 −0 swisseph/swepdate.c
  106. +7,109 −0 swisseph/sweph.c
  107. +644 −0 swisseph/sweph.h
  108. +967 −0 swisseph/swephexp.h
  109. +4,201 −0 swisseph/swephlib.c
  110. +224 −0 swisseph/swephlib.h
  111. BIN swisseph/swephprg.pdf
  112. +3,463 −0 swisseph/swetest.c
  113. BIN swisseph/swisseph.pdf
79 changes: 5 additions & 74 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,78 +1,9 @@
# Swiss Ephemeris library for Go [![GoDoc](https://godoc.org/github.com/dwlnetnl/swego?status.svg)](https://godoc.org/github.com/dwlnetnl/swego)
Package swego allows access to the Swiss Ephemeris from Go.
# Swiss Ephemeris library for Go [![GoDoc](https://godoc.org/github.com/astrotools/swego?status.svg)](https://godoc.org/github.com/astrotools/swego)

## Implemented C functions
Currently the following subset of the C API is implemented:
- [`swe_version`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200807)
- [`swe_close`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200805)
- [`swe_get_library_path`](http://www.astro.com/swisseph/swephprg.htm#_Toc452449218)
- [`swe_set_ephe_path`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200804)
- [`swe_set_jpl_file`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200806) (via arguments passed to method)
- [`swe_calc`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200740)
- [`swe_calc_ut`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200740)
- [`swe_nod_aps`](http://www.astro.com/swisseph/swephprg.htm#_Toc452449232)
- [`swe_nod_aps_ut`](http://www.astro.com/swisseph/swephprg.htm#_Toc452449231)
- [`swe_get_planet_name`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200762)
- [`swe_set_topo`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200753) (via arguments passed to method)
- [`swe_set_sid_mode`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200801) (via arguments passed to method)
- [`swe_get_ayanamsa`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200802) (_you should use `swe_get_ayanamsa_ex`_)
- [`swe_get_ayanamsa_ut`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200802) (_you should use `swe_get_ayanamsa_ex_ut`_)
- [`swe_get_ayanamsa_ex`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200802)
- [`swe_get_ayanamsa_ex_ut`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200802)
- `swe_get_ayanamsa_name`
- [`swe_julday`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200790)
- [`swe_revjul`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200790)
- [`swe_utc_to_jd`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200791)
- [`swe_jdet_to_utc`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200791)
- [`swe_jdut1_to_utc`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200791)
- [`swe_houses`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200809)
- [`swe_houses_ex`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200811)
- [`swe_houses_armc`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200810)
- [`swe_house_pos`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200814)
- [`swe_house_name`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200812)
- [`swe_deltat`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200796) (_you should use `swe_deltat_ex`_)
- [`swe_deltat_ex`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200795)
- [`swe_set_delta_t_userdef`](http://www.astro.com/swisseph/swephprg.htm#_Toc452449264)
- [`swe_time_equ`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200793)
- [`swe_lmt_to_lat`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200793)
- [`swe_lat_to_lmt`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200793)
- [`swe_sidtime0`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200816)
- [`swe_sidtime`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200816)
- [`swe_set_tid_acc`](http://www.astro.com/swisseph/swephprg.htm#_Toc433200797) (handled internally by the C library)

### What is the deal with that _via arguments passed to method_?
The reason is to eliminate the number of calls a user has to make. This is in contrast with the C API that requires you to call `swe_set_topo` before `swe_calc` when you for example are calculating the topocentric position of Venus. Only calling a single C function is important in the context of Go because you like to minimize the number of calls to C.

Currently the implementation calls always `swe_set_topo` before a `swe_calc`, however this could be combined into a single C function call without changing the public API.
This repository contains multiple ways to interface with the Swiss Ephemeris.
- `swecgo` interfaces with the C library via cgo.
- `swerker` interfaces with the C library via a separate worker or workers.
- `swerker-stdio` is a worker that runs as a subprocess.

## Pronunciation
The name of this package is pronounced _swie-go_, like cgo: cee-go.

# Example
```go
package main

import (
"log"

"github.com/dwlnetnl/swego"
"github.com/dwlnetnl/swego/swecgo"
)

func main() {
swecgo.Call(nil, func(swe swego.Interface) {
xx, cfl, err := swe.CalcUT(2451544.5, swego.Sun, swego.CalcFlags{}) // flags = 0
if err != nil {
log.Fatal(err)
}

log.Println("xx[0]", xx[0]) // xx[0] 279.8592144230897
log.Println("xx[1]", xx[1]) // xx[1] 0.0002296532779708713
log.Println("xx[2]", xx[2]) // xx[2] 0.9833318568951199
log.Println("xx[3]", xx[3]) // xx[3] 0
log.Println("xx[4]", xx[4]) // xx[4] 0
log.Println("xx[5]", xx[5]) // xx[5] 0
log.Println("cfl", cfl) // cfl 2
})
}
```
2 changes: 2 additions & 0 deletions cmd/swerker/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
swerker-stdio
*.lich
18 changes: 18 additions & 0 deletions cmd/swerker/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Compile first the Swiss Ephemeris as static library!
# see ../../swisseph/Makefile

CC = cc
CFLAGS += -std=c99 -g -Wall -fPIC
LDFLAGS += -Wl -dead_strip

.o:
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $? -L../../swisseph -lswe -lm
.c.o:
$(CC) $(CFLAGS) -c -I../../swisseph $<

swerker-stdio: swerker.o msgpuck.o handlers.o tr-stdio.o swex.o
$(CC) $(CFLAGS) $(LDFLAGS) -L../../swisseph -lswe -lm \
-o swerker-stdio swerker.o msgpuck.o handlers.o tr-stdio.o swex.o

clean:
rm -f *.o swerker-stdio
161 changes: 161 additions & 0 deletions cmd/swerker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# Swiss Ephemeris worker
The Swiss Ephemeris is not safe for use from multiple threads. To use multiple
processor cores, the Swiss Ephemeris is linked into a simple worker that can be
parallelized by running multiple copies simultaneously. The worker act as a RPC
server that can handle a single request at a time.

## Implemented library functions
Most of the Swiss Ephemeris functions are implemented and exposed as functions
that can be called as RPC.

The following functions that are unsupported via RPC:
- `swe_get_library_path`
- `swe_set_astro_models`
- `swe_get_astro_models`
- `swe_set_interpolate_nut`
- `swe_csnorm`
- `swe_difcsn`
- `swe_difcs2n`
- `swe_cs2timestr`
- `swe_cs2lonlatstr`
- `swe_cs2degstr`

Some Swiss Ephemeris functions depend on global state within the library. This
state is modified via functions like `swe_set_jpl_file`. These functions are
exposed as RPC functions and could be called as a _context call_. Each RPC call
has a context with zero or more context calls. These context calls are executed
before the actual library function is called. Clients may call these functions
directly, however they are discouraged to do so as they may unable to
predictably target a specific worker or a set of workers that will handle the
call.

The following functions modify the internal state of the library:
- `swe_close`
- `swe_set_ephe_path`
- `swe_set_jpl_file`
- `swe_set_topo`
- `swe_set_sid_mode`
- `swe_set_lapse_rate`
- `swe_set_tid_acc`
- `swe_set_delta_t_userdef`

## Wire format
Requests and responses are serialized in the [MessagePack][msgpack] format.

[msgpack]: https://msgpack.org/

## Stateful functions in Swiss Ephemeris
Some Swiss Ephemeris functions depend on global state within the library. This
state is modified via functions like `swe_set_jpl_file`. These library
functions are exposed as RPC functions. To bridge the gap between the Swiss
Ephemeris and world of RPCs each RPC call has a context that allows to do
_context calls_ that will modify the internal state. All context calls will be
executed before the requested function that is called via RPC is executed.

## Worker implementation
The RPC function handlers are internally defined as an array for quick
dispatch. This means RPC functions are identified by the index in this array of
handlers. The order of the handlers follows `swephexp.h` except for the
heliacal functions, as they are defined after `swe_split_deg` followed by
`swe_difdegn`. This means the index identifying a function is depended on the
version of the library and is unstable.

That said, there is an exception: the first entry in the handlers array (index
0). The first entry must always a RPC function called `rpc_funcs`. It returns
an array that contains the name of each function in the internal array of
handlers. This allows to create a mapping between function name and index in
the handler array.

## RPC protocol
### Request
A request is an array that contains three values:
- Context: an `array` of zero or more context calls, may be `nil`.
- Function: the function index encoded as an `uint8_t`.
- Arguments: an `array` that matches the types of the library function, may be
`nil` if there are no arguments.

A context call is the same as request array except the `array` contains only a
function and arguments, no context.

A request that calls `swe_calc` with a couple of context calls looks like this:
```
00000000 36 30 3c 93 93 92 0d 93 cb 40 14 77 77 8d d6 16 |60<......@.ww...|
00000010 f8 cb 40 4a 0a aa a7 de d6 bb 00 92 0e 93 01 00 |..@J............|
00000020 00 92 0b 91 a9 64 65 34 33 31 2e 65 70 68 04 93 |.....de431.eph..|
00000030 cb 41 42 72 8e d4 80 f1 2c 00 ce 00 01 81 01 3e |.ABr....,......>|
```

It corresponds to the following JSON:
```json
[
[
[13, [5.116667, 52.083333, 0]],
[14, [1, 0, 0]],
[11, ["de431.eph"]]
],
4,
[2417949.660185, 0, 98561]
]
```

And corresponds to the following C code:
```c
swe_set_topo(5.116667, 52.083333, 0);
swe_set_sid_mode(SE_SIDM_LAHIRI, 0, 0);
swe_set_jpl_file("de431.eph");

int fl = SEFLG_JPLEPH | SEFLG_SPEED | SEFLG_TOPOCTR | SEFLG_SIDEREAL;
double xx[6];
char err[AS_MAXCH];
int rc = swe_calc(2417949.660185, SE_SUN, fl, xx, err);
```
### Response
A response can either be an array with return values or an error string.
The response for the example request looks like this:
```
00000000 36 32 3c 93 ce 00 01 81 41 96 cb 40 70 8e e8 b7 |62<.....A..@p...|
00000010 e1 56 05 cb bf 5e 72 64 be 9d 1b 96 cb 3f ef 77 |.V...^rd.....?.w|
00000020 c2 d6 24 d2 ed cb 3f f0 61 6f 8d 18 b0 00 cb bf |..$...?.ao......|
00000030 6e d9 f9 96 82 f0 cc cb bf 1c bc 80 24 1e 00 00 |n...........$...|
00000040 a0 3e |.>|
```
It corresponds to the following JSON:
```json
[
98625,
[
264.931816,
-0.001858,
0.983369,
1.023788,
-0.003766,
-0.000110
],
""
]
```

And corresponds to the following values in C:
```c
rc = SEFLG_JPLEPH | SEFLG_NONUT | SEFLG_SPEED | SEFLG_TOPOCTR | SEFLG_SIDEREAL;
xx = [264.931816, -0.001858, 0.983369, 1.023788, -0.003766, -0.000110];
err = "";
```

## Implementation specifics
### swerker-stdio
This program is designed to run as subprocess of the client. It will read
requests from stdin and write responses to stdout. The process will exit when a
newline (`\n`) is read from stdin. Each request and response is framed in a
[Lich][lich] data element so the logic in the worker is fairly simple. Framing
enables reading the input into a buffer and parse the request incrementally.

The client is able to call functions that change the Swiss Ephemeris library
state. With this ability comes the responsibility for the client to initialize
the worker properly by calling `swe_set_ephe_path` on start up and `swe_close`
before quitting the process.

[lich]: https://github.com/rentzsch/lich
3 changes: 3 additions & 0 deletions cmd/swerker/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Command swerker is a C program that is exposes the Swiss Ephemeris via a RPC
// system.
package main
Loading