Astronomy with libnova
libnova is a Celestial Mechanics, Astrometry and Astrodynamics Library written in C. Just yesterday, I uploaded an inital, thin XS wrapper to CPAN as Astro::Nova, so we can use it from Perl.
Here's a simple example that calculates the current moon rise, transit and set times at my home in Karlsruhe using Astro::Nova. It's quite similar to the equivalent example of the C version.
use strict;
use warnings;
use Astro::Nova qw/:all/;
my $observer = Astro::Nova::LnLatPosn->new();
# observer location: Karlsruhe, for rst
$observer->set_lat( Astro::Nova::DMS->from_string("49°00' N")->to_degrees );
$observer->set_lng( Astro::Nova::DMS->from_string("8°23' E")->to_degrees );
my $now = get_julian_from_sys(); # current julian date
print "Current Julian Day: $now\n";
my $moon_from_earth = get_lunar_geo_posn($now, 0);
my ($moonx, $moony, $moonz) = ($moon_from_earth->get_X, $moon_from_earth->get_Y, $moon_from_earth->get_Z);
printf("Moon is at (%.02fkm, %.02fkm, %.02fkm)\n", $moonx, $moony, $moonz);
printf("Moon distance: %.02fkm\n", get_lunar_earth_dist($now));
my $moon_lnglat = get_lunar_ecl_coords($now, 0);
print "Moon at:\n", $moon_lnglat->as_ascii();
my $moon_equatorial = get_lunar_equ_coords($now);
my $moon_fraction = get_lunar_disk($now);
print "Current moon fraction: $moon_fraction\n";
print "Moon phase " . get_lunar_phase($now) . "\n";
my ($status, $moon_rst) = get_lunar_rst($now, $observer);
if ($status == 1) {
print "Moon is circumpolar\n";
}
else {
print "Rise time:\n", get_local_date( $moon_rst->get_rise() )->as_ascii(), "\n";
print "Transit time:\n", get_local_date( $moon_rst->get_transit() )->as_ascii(), "\n";
print "Set time:\n", get_local_date( $moon_rst->get_set() )->as_ascii(), "\n";
}
The interface is mostly still very C-ish and that's unlikely to change entirely, but the various containers will probably gain a few more convenience and conversion methods.
Next piece of the puzzle: a module for reading a star catalog. Astronomy is fun.
Seems very nice. I see you've also included the library itself with the module. That's the first I've ever seen.
I want to start using XS to write an interface for some C libraries but I have no idea where to start.
Any advice?
Including the library with the module has both advantages and disadvantages. Pro is that you can't have conflicting versions with whatever is on the system. Contra is that a) I managed to screw up the build, so it's rebuilt in every make invocation, and b) downstream packagers really don't like this. This module could hardly be packaged by debian, for example.
As for XS... It's not *that* hard by itself. But if you don't know C, it's nigh on impossible to learn C, XS, and the perl API at the same time.
I would suggest you start reading perlxstut and some of perlxs. Keep a perlapi nearby. You'll need it a lot because the perlapi is really the hard part. Start by using either "h2xs -An Foo::Bar" or a simple XS module as an example. (An *old* version of Class::XSAccessor, for example. But that module isn't about interfacing to a C library.)
h2xs, as the name implies, can generate super-simple XS wrappers of C functions for you. In some cases, that's enough to expose them to Perl. But the interface will be very C-ish like passing output parameters.
I heard "Extending and Embedding Perl" is a good read despite its age. I've never had a copy, though.
That's all I can think of right now.
PS: I'm not aware of good and complete introductory documentation for XS and the perlapi. perlxstut is somewhat spotty but okay. Reading some of the Inline::C docs is useful, too. Maybe you could consider taking notes as you learn it?
PPS: Check out CookbookA and CookbookB in Dean Roehrich's CPAN directory (DMR). Those are gems as examples!
Thanks for the extensive reply!
I already know C, but probably not as good as I need to know if I'll be playing with the Perl API. I think I'll check out "Extending and Embedding Perl", see if it got some stuff. I also think Yuval Kogman wrote a few pieces on the Perl API.
I'll check h2xs and some code and definitely the other stuff you recommended.
Thanks again! :)