");
37 | avoid_runaway_process( 300);
38 | rval = initialize_cgi_reading( );
39 | if( rval <= 0)
40 | {
41 | printf( " CGI data reading failed : error %d ", rval);
42 | printf( "This isn't supposed to happen. Please report this.
\n");
43 | return( 0);
44 | }
45 | while( !get_cgi_data( field, buff, NULL, sizeof( buff)))
46 | {
47 | if( !strcmp( field, "packed") && strlen( buff) > 3)
48 | {
49 | rval = unpack_unaligned_mpc_desig( tbuff, buff);
50 | printf( "'%s' unpacks to '%s'\n", buff, tbuff);
51 | if( rval == -1)
52 | printf( "(This does not appear to be a valid packed designation)\n");
53 | }
54 | if( !strcmp( field, "unpacked") && strlen( buff) > 3)
55 | {
56 | rval = create_mpc_packed_desig( tbuff, buff);
57 | printf( "'%s' packs to '%s'\n", buff, tbuff);
58 | if( rval == -1)
59 | printf( "(This was not successfully packed.)\n");
60 | }
61 | }
62 | return( 0);
63 | }
64 |
--------------------------------------------------------------------------------
/pollute.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #define CSI "\x1b\x5b"
5 |
6 | /* Code to extract chunks of the light pollution map at
7 |
8 | https://www.nasa.gov/feature/goddard/2017/new-night-lights-maps-open-up-possible-real-time-applications/
9 |
10 | and output a roughly 120x120-km (40x40) pixel area as an image
11 | on an xterm, using color control codes.
12 |
13 | The 8 MByte JPG is 13500 x 6750 pixels, roughly three km to the pixel :
14 |
15 | https://www.nasa.gov/specials/blackmarble/2016/globalmaps/BlackMarble_2016_3km.jpg
16 |
17 | Run 'convert BlackMarble_2016_3km.jpg /tmp/night.pgm', and you have
18 | something this program can use. I doubt that anyone else is apt to use
19 | this code, but it's helped me to visualize the map. */
20 |
21 | int main( const int argc, const char **argv)
22 | {
23 | const int xsize = 13500, ysize = xsize / 2;
24 | FILE *ifile = fopen( "/tmp/night.pgm", "rb");
25 | int x0, y0;
26 | int x, y, size = (argc > 3 ? atoi( argv[3]) : 20);
27 | long header_size = 18;
28 | unsigned char buff[200];
29 |
30 | if( !ifile)
31 | printf( "This program gets data from /tmp/night.pgm, and cannot\n"
32 | "open that file. See 'pollute.c' for details.\n");
33 | if( argc < 3)
34 | printf( "Usage : ./pollute longitude latitude\n");
35 | if( !ifile || argc < 3)
36 | return( -1);
37 | x0 = (int)( ( 180. + atof( argv[1])) * (double)xsize / 360.);
38 | y0 = (int)( ( 90. - atof( argv[2])) * (double)ysize / 180.);
39 | x0 %= xsize;
40 | for( y = y0 - size; y < y0 + size; y++)
41 | {
42 | long loc = header_size + (long)y * (long)xsize + (long)( x0 - size);
43 |
44 | fseek( ifile, loc, SEEK_SET);
45 | if( fread( (char *)buff, size * 2, 1, ifile))
46 | {
47 | for( x = 0; x < size * 2; x++)
48 | if( x == size && y == y0)
49 | printf( CSI "48;2;255;128;0m ");
50 | else
51 | printf( CSI "48;2;%d;%d;%dm ", buff[x], buff[x], buff[x]);
52 | printf( CSI "49m\n"); /* reset default bkgrnd */
53 | }
54 | }
55 | return( -1);
56 | }
57 |
--------------------------------------------------------------------------------
/stringex.h:
--------------------------------------------------------------------------------
1 | #ifndef STRINGEX_H_INCLUDED
2 | #define STRINGEX_H_INCLUDED
3 |
4 | /* Some extensions to the usual string/snprintf functions. These
5 | silently truncate buffer overruns, or abort so you know you
6 | have such overruns.
7 |
8 | First, the OpenBSD strlcxx functions. See comments in 'stringex.cpp'. */
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif /* #ifdef __cplusplus */
13 |
14 |
15 | #if !defined( __APPLE__) && !defined( __OpenBSD__)
16 | size_t strlcpy( char *dst, const char *src, const size_t dsize);
17 | size_t strlcat( char *dst, const char *src, const size_t dsize);
18 | #endif
19 |
20 | /* The above truncate silently. On occasion, one wants that. Most of
21 | the time, such truncation indicates a bug, and the program should
22 | abort (at least in debug builds and, arguably, always). The
23 | '_err()' variants will do so. */
24 |
25 | size_t strlcpy_err( char *dst, const char *src, const size_t dsize);
26 | size_t strlcat_err( char *dst, const char *src, const size_t dsize);
27 |
28 | /* Frequently, 'dsize' is simply sizeof( dst). The following macros
29 | can result in slightly easier to read code in such cases. */
30 |
31 | #define strlcat_error( a, b) strlcat_err( a, b, sizeof( a))
32 | #define strlcpy_error( a, b) strlcpy_err( a, b, sizeof( a))
33 |
34 | /* Older MSVC/C++ lacks snprintf(). See 'stringex.cpp' for details. */
35 |
36 | #if defined(_MSC_VER) && _MSC_VER < 1900
37 | #define NO_BUILT_IN_SNPRINTF
38 | #endif
39 |
40 | #ifdef NO_BUILT_IN_SNPRINTF
41 | int snprintf( char *string, const size_t max_len, const char *format, ...);
42 | #endif
43 |
44 | int snprintf_append( char *string, const size_t max_len,
45 | const char *format, ...)
46 | #ifdef __GNUC__
47 | __attribute__ (( format( printf, 3, 4)))
48 | #endif
49 | ;
50 |
51 | int snprintf_err( char *string, const size_t max_len,
52 | const char *format, ...)
53 | #ifdef __GNUC__
54 | __attribute__ (( format( printf, 3, 4)))
55 | #endif
56 | ;
57 |
58 | #ifdef __cplusplus
59 | }
60 | #endif /* #ifdef __cplusplus */
61 | #endif /* #ifndef STRINGEX_H_INCLUDED */
62 |
--------------------------------------------------------------------------------
/mini_dll.cpp:
--------------------------------------------------------------------------------
1 | /* mini_dll.cpp: probably obsolete code for a 16-bit DLL!
2 | I don't think use has been made of this in a decade or so.
3 |
4 | Copyright (C) 2010, Project Pluto
5 |
6 | This program is free software; you can redistribute it and/or
7 | modify it under the terms of the GNU General Public License
8 | as published by the Free Software Foundation; either version 2
9 | of the License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program; if not, write to the Free Software
18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 | 02110-1301, USA. */
20 |
21 | // libentry.cpp : Defines the entry point for the DLL application.
22 | //
23 | /* Usually, the following lines come from a separate file, STDAFX.H.
24 | However, for the 'mini-DLL', STDAFX is used only in this file,
25 | and maintaining a separate include file seems superfluous. */
26 |
27 | /* ------ STDAFX.H BEGINS HERE ------ */
28 | // stdafx.h : include file for standard system include files,
29 | // or project specific include files that are used frequently, but
30 | // are changed infrequently
31 | //
32 |
33 | #if !defined(AFX_STDAFX_H__298970FE_2CDF_11D5_A298_000102CA0D3E__INCLUDED_)
34 | #define AFX_STDAFX_H__298970FE_2CDF_11D5_A298_000102CA0D3E__INCLUDED_
35 |
36 | #if _MSC_VER > 1000
37 | #pragma once
38 | #endif // _MSC_VER > 1000
39 |
40 |
41 | // Insert your headers here
42 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
43 |
44 | #include
45 |
46 | // TODO: reference additional headers your program requires here
47 |
48 | //{{AFX_INSERT_LOCATION}}
49 | // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
50 |
51 | #endif // !defined(AFX_STDAFX_H__298970FE_2CDF_11D5_A298_000102CA0D3E__INCLUDED_)
52 | /* ------ STDAFX.H ENDS HERE ------ */
53 |
54 | BOOL APIENTRY DllMain( HANDLE hModule,
55 | DWORD ul_reason_for_call,
56 | LPVOID lpReserved
57 | )
58 | {
59 | return TRUE;
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/lun_test.cpp:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2018, Project Pluto
2 |
3 | This program is free software; you can redistribute it and/or
4 | modify it under the terms of the GNU General Public License
5 | as published by the Free Software Foundation; either version 2
6 | of the License, or (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 | 02110-1301, USA. */
17 |
18 | #include
19 | #include
20 | #include "lun_tran.h"
21 |
22 | int main( const int argc, const char **argv)
23 | {
24 | double lon, lat;
25 | int day, zip_code, year, month;
26 | int time_zone, use_dst;
27 | char place_name[100];
28 |
29 | if( argc != 4)
30 | {
31 | printf( "'lun_test' requires, as command-line arguments, a year,\n");
32 | printf( "month, and US five-digit postal code. For example,\n\n");
33 | printf( "./luntest 2015 2 04008\n\n");
34 | printf( "would produce a list of lunar transit times for 2015 February\n");
35 | printf( "for the town of Bowdoinham, Maine, which has ZIP code 04008.\n\n");
36 | return( -2);
37 | }
38 | year = atoi( argv[1]);
39 | month = atoi( argv[2]);
40 | zip_code = atoi( argv[3]);
41 | if( get_zip_code_data( zip_code, &lat, &lon, &time_zone,
42 | &use_dst, place_name))
43 | {
44 | printf( "Couldn't get data for ZIP code %05d\n", zip_code);
45 | return( -1);
46 | }
47 |
48 | printf( "Lat %f Lon %f Time zone %d DST=%d %s\n",
49 | lat, lon, time_zone, use_dst, place_name);
50 | for( day = 1; day <= 31; day++)
51 | {
52 | const double transit_time =
53 | get_lunar_transit_time( year, month, day,
54 | lat, lon, time_zone, use_dst, 1);
55 | const double antitransit_time =
56 | get_lunar_transit_time( year, month, day,
57 | lat, lon, time_zone, use_dst, 0);
58 | char transit_buff[6], antitransit_buff[6];
59 |
60 | format_hh_mm( transit_buff, transit_time);
61 | format_hh_mm( antitransit_buff, antitransit_time);
62 |
63 | printf( "%2d: %s %s\n", day,
64 | transit_buff, antitransit_buff);
65 | }
66 | return( 0);
67 | }
68 |
--------------------------------------------------------------------------------
/mpc_hdr.htm:
--------------------------------------------------------------------------------
1 | # Header for HTML versions of the MPC observatory code list. See
2 | # 'mpc_code.cpp' for explanation. This file is read in, and any
3 | # line not starting with '#' is output. Then the actual observatory
4 | # data is written.
5 |
6 |
7 |
8 | MPC station sites
9 |
10 |
11 |
12 |
13 | MPC observatory codes
14 |
15 | Created %.24s UTC
16 |
17 |
18 | Click here for a G__gle Map showing all observatory codes
19 |
20 | Click here for
21 | information about this page.
22 |
23 |
The first half of each line (MPC code, lon, lat) links to a G__gle™
24 | map for that observatory; the rest of the line links to a Bing® map.
25 |
26 | # 'rovers' off (i.e., don't show these lines for that file)
27 |
28 |
29 | 000
30 | 100
31 | 200
32 | 300
33 | 400
34 | 500
35 | 600
36 | 700
37 | 800
38 |
39 |
40 | 900
41 | A00
42 | B00
43 | C00
44 | D00
45 | E00
46 | F00
47 | G00
48 | H00
49 |
50 |
51 |
52 | I00
53 | J00
54 | K00
55 | L00
56 | M00
57 | N00
58 | O00
59 | P00
60 | Q00
61 |
62 |
63 |
64 | R00
65 | S00
66 | T00
67 | U00
68 | V00
69 | W00
70 | X00
71 | Y00
72 | Z00
73 |
74 |
75 | # 'rovers' on (i.e., always show these lines)
76 |
77 |
--------------------------------------------------------------------------------
/get_test.cpp:
--------------------------------------------------------------------------------
1 | /* get_test.cpp: tests/exercises the get_time_from_string( ) function
2 |
3 | Copyright (C) 2010, Project Pluto
4 |
5 | This program is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU General Public License
7 | as published by the Free Software Foundation; either version 2
8 | of the License, or (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 | 02110-1301, USA. */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include "watdefs.h"
26 | #include "date.h"
27 |
28 | /* Test routine for get_time_from_string(). This function is supposed
29 | to puzzle out a huge range of bizarre inputs, such as "March 4" (fourth
30 | day of March) vs. "4 Mar" and so on. 'get_test.txt' contains some example
31 | inputs; 'get_test' reads those inputs, prints out the resulting times,
32 | and you can then check to make sure that the approved output resulted
33 | by comparing it to 'get_out.txt'. Exactly one line -- the one corresponding
34 | to 'now-4d' -- should differ. */
35 |
36 | int main( int argc, char **argv)
37 | {
38 | FILE *ifile = fopen( argc == 1 ? "get_test.txt" : argv[1], "rb");
39 |
40 | if( ifile)
41 | {
42 | char buff[80];
43 | double jd = 0;
44 | int i;
45 | unsigned time_format = 0;
46 |
47 | setvbuf( stdout, NULL, _IONBF, 0);
48 | while( fgets( buff, sizeof( buff), ifile))
49 | {
50 | for( i = 0; buff[i] >= ' '; i++)
51 | ;
52 | buff[i] = '\0';
53 | if( !memcmp( buff, "format", 6))
54 | {
55 | sscanf( buff + 6, "%x", &time_format);
56 | printf( "%s\n", buff);
57 | }
58 | else if( *buff != ';')
59 | {
60 | char obuff[80];
61 | int is_ut;
62 |
63 | jd = get_time_from_string( jd, buff, (int)time_format, &is_ut);
64 | full_ctime( obuff, jd, FULL_CTIME_MILLISECS | CALENDAR_JULIAN_GREGORIAN);
65 | printf( "%s %d %s\n", obuff, is_ut, buff);
66 | }
67 | else
68 | printf( "%s\n", buff);
69 | }
70 | fclose( ifile);
71 | }
72 | return( ifile ? 0 : -1);
73 | }
74 |
--------------------------------------------------------------------------------
/prectes2.cpp:
--------------------------------------------------------------------------------
1 | /* prectes2.cpp: compares Earth precession done in ecliptic and equatorial
2 | systems. See 'precess.cpp' for details as to why both methods matter
3 | and when they ought to be used.
4 |
5 | Copyright (C) 2017, Project Pluto
6 |
7 | This program is free software; you can redistribute it and/or
8 | modify it under the terms of the GNU General Public License
9 | as published by the Free Software Foundation; either version 2
10 | of the License, or (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program; if not, write to the Free Software
19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 | 02110-1301, USA. */
21 |
22 | #include
23 | #include
24 | #include
25 | #include "watdefs.h"
26 | #include "afuncs.h"
27 | #include "date.h"
28 | #include "lunar.h" /* for obliquity( ) prototype */
29 |
30 | #define PI 3.1415926535897932384626433832795028841971693993751058209749445923
31 |
32 | int DLL_FUNC setup_equatorial_precession_from_j2000( double DLLPTR *matrix,
33 | const double year);
34 |
35 | #include
36 | #include
37 |
38 | int main( const int argc, const char **argv)
39 | {
40 | double t1, matrix[9];
41 | int i, pass;
42 | const double J2000 = 2451545.;
43 |
44 | t1 = get_time_from_string( 0., (argc == 1 ? "now" : argv[1]),
45 | FULL_CTIME_YMD, NULL);
46 | printf( "JD %f =", t1);
47 | t1 = (t1 - J2000) / 365.25 + 2000.;
48 | printf( " year %f\n", t1);
49 | printf( "Last digits represent about 0.64 mm on earth's surface\n");
50 | for( pass = 0; pass < 3; pass++)
51 | {
52 | if( !pass)
53 | {
54 | printf( "New, ecliptic-based precession :\n");
55 | setup_precession( matrix, 2000., t1);
56 | }
57 | else if( pass == 1)
58 | {
59 | printf( "Original, rougher precession :\n");
60 | setup_equatorial_precession_from_j2000( matrix, t1);
61 | }
62 | else
63 | {
64 | double mat2[9];
65 |
66 | printf( "Differences are (old - new) :\n");
67 | setup_equatorial_precession_from_j2000( matrix, t1);
68 | setup_precession( mat2, 2000., t1);
69 | for( i = 0; i < 9; i++)
70 | matrix[i] -= mat2[i];
71 | }
72 | for( i = 0; i < 9; i++)
73 | printf( "%14.10f%s", matrix[i], (i % 3 == 2) ? "\n" : " ");
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/vislimit.h:
--------------------------------------------------------------------------------
1 | /* vislimith: header file for visibility/sky brightness computations
2 | Copyright (C) 2010, Project Pluto
3 |
4 | This program is free software; you can redistribute it and/or
5 | modify it under the terms of the GNU General Public License
6 | as published by the Free Software Foundation; either version 2
7 | of the License, or (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 | 02110-1301, USA. */
18 |
19 | /* Visibility is computed in five bands : U, B, V, R, I.
20 | Thus, the k[0], k[1], ... k[4] values give the total extinction
21 | coefficients for U, B, V, R, I respectively. */
22 |
23 | #define BRIGHTNESS_DATA struct brightness_data
24 |
25 | #pragma pack(4)
26 | BRIGHTNESS_DATA
27 | {
28 | /* constants for a given time: */
29 | double zenith_ang_moon, zenith_ang_sun, moon_elongation;
30 | double ht_above_sea_in_meters, latitude;
31 | double temperature_in_c, relative_humidity;
32 | double year, month;
33 | /* values varying across the sky: */
34 | double zenith_angle;
35 | double dist_moon, dist_sun; /* angular, not real linear */
36 | int mask; /* indicates which of the 5 photometric bands we want */
37 | /* Items computed in set_brightness_params: */
38 | double air_mass_sun, air_mass_moon, lunar_mag;
39 | double k[5], c3[5], c4[5];
40 | double ka[5]; /* Aerosol extinction coeffs in UBVRI */
41 | double kr[5]; /* Rayleigh extinction coeffs */
42 | double ko[5]; /* Ozone extinction */
43 | double kw[5]; /* Water extinction */
44 | double year_term; /* variation due to 11-year solar cycle */
45 | /* Items computed in compute_limiting_mag: */
46 | double air_mass_gas, air_mass_aerosol, air_mass_ozone;
47 | double extinction[5];
48 | /* Internal parameters from compute_sky_brightness: */
49 | double air_mass;
50 | double brightness[5];
51 | };
52 | #pragma pack( )
53 |
54 | #ifdef _WIN32
55 | #define DLL_FUNC __stdcall
56 | #else
57 | #define DLL_FUNC
58 | #endif
59 |
60 | #ifdef __cplusplus
61 | extern "C" {
62 | #endif
63 |
64 | int DLL_FUNC set_brightness_params( BRIGHTNESS_DATA *b);
65 | int DLL_FUNC compute_sky_brightness( BRIGHTNESS_DATA *b);
66 | double DLL_FUNC compute_limiting_mag( BRIGHTNESS_DATA *b);
67 | int DLL_FUNC compute_extinction( BRIGHTNESS_DATA *b);
68 |
69 | #ifdef __cplusplus
70 | }
71 | #endif
72 |
--------------------------------------------------------------------------------
/ll_test.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include "watdefs.h"
6 | #include "mpc_func.h"
7 |
8 | /* Run as, e.g., './ll_test "n23 45 12.3, w31.4159, 200ft"' to test out
9 | the lat/lon parsing code in 'mpc_code.cpp.' Compile with
10 |
11 | gcc -Wall -Wextra -pedantic -o ll_test ll_test.c liblunar.a -lm */
12 |
13 | #define PI 3.1415926535897932384626433832795028841971693993751058209749445923
14 |
15 | static void run_tests( void)
16 | {
17 | FILE *ifile = fopen( "ll_test.txt", "rb");
18 | char buff[200];
19 | int n_tests = 0;
20 |
21 | assert( ifile);
22 | while( fgets( buff, sizeof( buff), ifile))
23 | if( *buff != '#')
24 | {
25 | double lat, lon, alt;
26 | int expected_rval, rval;
27 | mpc_code_t cinfo;
28 |
29 | if( !memcmp( buff + 32, "COM Long.", 9))
30 | rval = get_xxx_location_info( &cinfo, buff + 32);
31 | else
32 | rval = get_lat_lon_info( &cinfo, buff + 32);
33 | assert( 4 == sscanf( buff, "%d %lf %lf %lf", &expected_rval, &lon, &lat, &alt));
34 | if( rval != expected_rval)
35 | fprintf( stderr, "Error with string '%s'; got %d\n", buff + 32, rval);
36 | else if( !rval) /* should have succeeded */
37 | {
38 | const double lat1 = cinfo.lat * 180. / PI;
39 | const double lon1 = cinfo.lon * 180. / PI;
40 | const double rounding_tolerance = 1e-8;
41 |
42 | if( alt - cinfo.alt < -rounding_tolerance
43 | || alt - cinfo.alt > rounding_tolerance
44 | || lat - lat1 < -rounding_tolerance
45 | || lat - lat1 > rounding_tolerance
46 | || lon - lon1 < -rounding_tolerance
47 | || lon - lon1 > rounding_tolerance)
48 | fprintf( stderr, "Error with string '%s'; got %.8lf %.8lf %.8lf\n",
49 | buff + 32,
50 | cinfo.lat * 180. / PI, cinfo.lon * 180. / PI, cinfo.alt);
51 | }
52 | n_tests++;
53 | }
54 | printf( "%d tests run\n", n_tests);
55 | fclose( ifile);
56 | }
57 |
58 | int main( const int argc, const char **argv)
59 | {
60 | if( argc > 1)
61 | {
62 | mpc_code_t cinfo;
63 | int rval;
64 |
65 | if( !memcmp( argv[1], "COM Long.", 9))
66 | rval = get_xxx_location_info( &cinfo, argv[1]);
67 | else
68 | rval = get_lat_lon_info( &cinfo, argv[1]);
69 |
70 | if( rval)
71 | printf( "Failed %d\n", rval);
72 | else
73 | {
74 | printf( "Lat %lf\nLon %lf\n", cinfo.lat * 180. / PI, cinfo.lon * 180. / PI);
75 | printf( "Alt %lf metres\n", cinfo.alt);
76 | }
77 | }
78 | else
79 | run_tests( );
80 | return( 0);
81 | }
82 |
--------------------------------------------------------------------------------
/utc_test.cpp:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2018, Project Pluto
2 |
3 | This program is free software; you can redistribute it and/or
4 | modify it under the terms of the GNU General Public License
5 | as published by the Free Software Foundation; either version 2
6 | of the License, or (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 | 02110-1301, USA. */
17 |
18 | #include
19 | #include
20 | #include "watdefs.h"
21 | #include "afuncs.h"
22 | #include "mjd_defs.h"
23 |
24 | int main( const int argc, const char **argv)
25 | {
26 | int year = 1970, end_year = 2040, i;
27 | unsigned count = 0;
28 |
29 | for( i = 1; i < argc; i++)
30 | if( argv[i][0] == '-')
31 | switch( argv[i][1])
32 | {
33 | case 'p':
34 | mjd_end_of_predictive_leap_seconds = atoi( argv[i] + 2);
35 | printf( "No predicted leap seconds after MJD %d\n",
36 | mjd_end_of_predictive_leap_seconds);
37 | break;
38 | default:
39 | printf( "Option '%s' ignored\n", argv[i]);
40 | break;
41 | }
42 | else
43 | sscanf( argv[i], "%d,%d", &year, &end_year);
44 | printf( "Leap seconds for years %d to %d\n", year, end_year);
45 | printf( "(See the 'official' list at https://hpiers.obspm.fr/iers/bul/bulc/UTC-TAI.history)\n");
46 | printf( "Future leap seconds are predicted using the method described\n");
47 | printf( "in 'delta_t.cpp', and come without warranty of any kind.\n");
48 | for( ; year <= end_year; year++)
49 | if( year >= 1972)
50 | for( unsigned pass = 0; pass < 2; pass++)
51 | {
52 | const double tai_minus_tdt = -32.184; /* by definition */
53 | const double jd = 2400000.5 + (pass ? JUL_1( year) : JAN_1( year));
54 | const double tai_minus_utc_before =
55 | tai_minus_tdt + td_minus_utc( jd - .0001);
56 | const double tai_minus_utc_after =
57 | tai_minus_tdt + td_minus_utc( jd + .0001);
58 |
59 | if( tai_minus_utc_before != tai_minus_utc_after)
60 | {
61 | printf( "%d %s : %.3f%s", year, (pass ? "Jul" : "Jan"),
62 | tai_minus_utc_after,
63 | (count % 3 == 2 ? "\n" : " "));
64 | count++;
65 | }
66 | }
67 | printf( "\n");
68 | return( 0);
69 | }
70 |
--------------------------------------------------------------------------------
/obliquit.cpp:
--------------------------------------------------------------------------------
1 | /* obliquit.cpp: function to compute earth's obliquity
2 |
3 | Copyright (C) 2010, Project Pluto
4 |
5 | This program is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU General Public License
7 | as published by the Free Software Foundation; either version 2
8 | of the License, or (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 | 02110-1301, USA. */
19 |
20 | /* 21 Sep 2011: improved caching of previous values. Also, the
21 | formula diverges badly outside +/- 10 millenia, so I "capped"
22 | results at that point. The test code now compares to the IAU
23 | obliquity formula, and shows values linearly interpolated from
24 | integrated values from a file due to Laskar. */
25 |
26 | #include "watdefs.h"
27 | #include "lunar.h"
28 |
29 | #define PI 3.1415926535897932384626433832795028841971693993751058209749445923
30 | #define CVT (PI / 180.)
31 | #define ARCSECONDS_TO_RADIANS (CVT / 3600.)
32 |
33 | /* obliquity formula comes from p 135, Meeus, Astro Algor */
34 | /* input is time in julian centuries from 2000. */
35 | /* rval is mean obliq. (epsilon sub 0) in radians */
36 | /* Valid range is the years -8000 to +12000 (t = -100 to 100) */
37 |
38 | double DLL_FUNC mean_obliquity( const double t_cen)
39 | {
40 | double u, u0;
41 | unsigned i;
42 | const double obliquit_minus_100_cen = 24.232841111 * PI / 180.;
43 | const double obliquit_plus_100_cen = 22.611485556 * PI / 180.;
44 | static double j2000_obliquit = 23. * 3600. + 26. * 60. + 21.448;
45 | static double t0 = 30000., rval;
46 | static long coeffs[10] = { -468093L, -155L, 199925L, -5138L,
47 | -24967L, -3905L, 712L, 2787L, 579L, 245L };
48 |
49 | if( t_cen == 0.) /* common J2000 case; don't do any math */
50 | return( j2000_obliquit * ARCSECONDS_TO_RADIANS);
51 | #ifndef CLIP_OBLIQUITY
52 | else if( t_cen > 100.) /* Diverges outside +/- 10 millennia, */
53 | return( obliquit_plus_100_cen);
54 | else if( t_cen < -100.) /* so we might as well clip to that */
55 | return( obliquit_minus_100_cen);
56 | #endif
57 |
58 | if( t0 == t_cen) /* return previous answer */
59 | return( rval);
60 |
61 | rval = j2000_obliquit;
62 | t0 = t_cen;
63 | u = u0 = t_cen / 100.; /* u is in julian 10000's of years */
64 | for( i = 0; i < 10; i++, u *= u0)
65 | rval += u * (double)coeffs[i] / 100.;
66 |
67 | rval *= ARCSECONDS_TO_RADIANS;
68 | return( rval);
69 | }
70 |
--------------------------------------------------------------------------------
/ssattest.cpp:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2018, Project Pluto
2 |
3 | This program is free software; you can redistribute it and/or
4 | modify it under the terms of the GNU General Public License
5 | as published by the Free Software Foundation; either version 2
6 | of the License, or (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 | 02110-1301, USA. */
17 |
18 | #include
19 | #include
20 | #include
21 | #include "watdefs.h"
22 | #include "lunar.h"
23 | #include "date.h"
24 | #include "afuncs.h"
25 |
26 | #define JUPITER_R (71492. / AU_IN_KM)
27 | #define J2000 2451545.
28 |
29 | int main( const int argc, const char **argv)
30 | {
31 | int i;
32 | double loc[12], jd, precess_matrix[9], t_years, obliquity;
33 | char buff[80];
34 |
35 | if( argc != 2)
36 | {
37 | printf( "'ssattest' takes a JD on the command line, and outputs\n"
38 | "J2000 ecliptic Cartesian coordinates for the eight main\n"
39 | "satellites of Saturn and the four Galileans.\n");
40 | return( -1);
41 | }
42 | jd = get_time_from_string( 0., argv[1], 0, NULL);
43 | full_ctime( buff, jd, FULL_CTIME_YMD);
44 | t_years = (jd - J2000) / 365.25;
45 | obliquity = mean_obliquity( t_years / 100.);
46 | printf( "Coordinates are in AU, ecliptic J2000\n");
47 | printf( "Date: %.5f = %s\n", jd, buff);
48 | for( i = 0; i < 8; i++)
49 | {
50 | const char *names[8] = { "Mimas", "Enceladus", "Tethys",
51 | "Dione", "Rhea", "Titan", "Hyperion", "Iapetus" };
52 |
53 | calc_ssat_loc( jd, loc, i, 0L);
54 | printf( "%d: %10.7f %10.7f %10.7f %s\n", i, loc[0], loc[1], loc[2],
55 | names[i]);
56 | }
57 | printf( "\n");
58 | setup_precession( precess_matrix, 2000. + t_years, 2000.);
59 | calc_jsat_loc( jd, loc, 15, 0L);
60 | for( i = 0; i < 4; i++)
61 | {
62 | const char *names[4] = { "Io", "Europa", "Ganymede", "Callisto" };
63 | double tloc[3];
64 |
65 | /* turn ecliptic of date to equatorial: */
66 | rotate_vector( loc + i * 3, obliquity, 0);
67 | /* then to equatorial J2000: */
68 | precess_vector( precess_matrix, loc + i * 3, tloc);
69 | /* then to ecliptic J2000: */
70 | equatorial_to_ecliptic( tloc);
71 | printf( "%d: %10.7f %10.7f %10.7f %s\n", i, tloc[0] * JUPITER_R,
72 | tloc[1] * JUPITER_R, tloc[2] * JUPITER_R, names[i]);
73 | }
74 | return( 0);
75 | }
76 |
--------------------------------------------------------------------------------
/oblitest.cpp:
--------------------------------------------------------------------------------
1 | /* oblitest.cpp: tests various obliquity formulae
2 |
3 | Copyright (C) 2011, Project Pluto
4 |
5 | This program is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU General Public License
7 | as published by the Free Software Foundation; either version 2
8 | of the License, or (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 | 02110-1301, USA. */
19 |
20 | #include
21 | #include
22 | #include "watdefs.h"
23 | #include "lunar.h"
24 |
25 | #define PI 3.1415926535897932384626433832795028841971693993751058209749445923
26 |
27 | /* By default, this program shows the obliquity from years 0 to 4000 at
28 | 200-year steps, using a variety of obliquity formulae. Command-line
29 | arguments can change the range/step. */
30 |
31 | double iau_obliquity( const double t_cen);
32 | double file_obliquity( const double t_cen);
33 | double spline_obliquity( const double t_cen);
34 |
35 | int main( const int argc, const char **argv)
36 | {
37 | double t0 = (argc > 1 ? atof( argv[1]) : 0.);
38 | const double dt = (argc > 2 ? atof( argv[2]) : 200.);
39 | unsigned n_steps = (argc > 3 ? (unsigned)atoi( argv[3]) : 21);
40 | const char *header_trailer =
41 | " year : Laskar cubic file spline dSpline dCubic\n";
42 |
43 | printf( "%s", header_trailer);
44 | while( n_steps--)
45 | {
46 | const double t_cen = (t0 - 2000.) / 100.;
47 | const double laskar_obliquity = mean_obliquity( t_cen);
48 | const double iau_value = iau_obliquity( t_cen);
49 | const double file_value = file_obliquity( t_cen);
50 | const double spline_value = spline_obliquity( t_cen);
51 |
52 | printf( "%10.2f: %.8f %.8f %.8f %.8f %.3f %.3f\n", t0,
53 | laskar_obliquity * 180. / PI,
54 | iau_value * 180. / PI,
55 | file_value * 180. / PI,
56 | spline_value * 180. / PI,
57 | (laskar_obliquity - spline_value) * 3600. * 180. / PI,
58 | (laskar_obliquity - iau_value) * 3600. * 180. / PI);
59 | t0 += dt;
60 | }
61 | printf( "%s", header_trailer);
62 | if( file_obliquity( 1.) == 0.)
63 | {
64 | printf( "'File' obliquity is interpolated from values found in files at\n\n");
65 | printf( "http://cdsarc.u-strasbg.fr/viz-bin/Cat?VI/63\n\n");
66 | printf( "Get those files, and the 'file' obliquities will be computed and shown.\n");
67 | }
68 | return( 0);
69 | }
70 |
--------------------------------------------------------------------------------
/cosptest.cpp:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2018, Project Pluto
2 |
3 | This program is free software; you can redistribute it and/or
4 | modify it under the terms of the GNU General Public License
5 | as published by the Free Software Foundation; either version 2
6 | of the License, or (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 | 02110-1301, USA. */
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include "watdefs.h"
24 | #include "afuncs.h"
25 | #include "lunar.h"
26 |
27 | /* Unit test code for COSPAR functions. I've used this */
28 | /* after making changes to 'cospar.txt' or 'cospar.cpp' */
29 | /* just to verify that only the things that were _supposed_ */
30 | /* to change, actually changed. */
31 |
32 | int main( const int argc, const char **argv)
33 | {
34 | double matrix[9], prev_matrix[9];
35 | int i, j, system_number, rval;
36 | clock_t t0 = clock( );
37 |
38 | if( argc == 2) /* you can specify the COSPAR file name from */
39 | load_cospar_file( argv[1]); /* the command line */
40 | setvbuf( stdout, NULL, _IONBF, 0);
41 | for( i = 0; i < 14; i++)
42 | {
43 | const double rate = planet_rotation_rate( i, 0);
44 |
45 | printf( "%d: %f deg/day; rotation period %f days\n", i, rate, 360. / rate);
46 | }
47 | for( i = 0; i < 9; i++)
48 | prev_matrix[i] = 0.;
49 | for( i = -5; i < 2000; i++)
50 | {
51 | for( system_number = 0; system_number < 4; system_number++)
52 | {
53 | rval = calc_planet_orientation( i, system_number,
54 | 2451000. + (double)i * 1000., matrix);
55 | if( rval && rval != -1)
56 | printf( "rval %d\n", rval);
57 | else if( !rval)
58 | if( memcmp( matrix, prev_matrix, 9 * sizeof( double)))
59 | {
60 | double radii[3];
61 |
62 | printf( "Planet %d, system %d\n", i, system_number);
63 | planet_radii( i, radii);
64 | printf( " Radii %.2f %.2f %.2f km\n",
65 | radii[0], radii[1], radii[2]);
66 | for( j = 0; j < 9; j += 3)
67 | printf( "%11.8f %11.8f %11.8f\n",
68 | matrix[j], matrix[j + 1], matrix[j + 2]);
69 | for( j = 0; j < 9; j++)
70 | prev_matrix[j] = matrix[j];
71 | }
72 | }
73 | }
74 | printf( "Total time: %f\n",
75 | (double)( clock() - t0) / (double)CLOCKS_PER_SEC);
76 | return( 0);
77 | }
78 |
--------------------------------------------------------------------------------
/them_cat.c:
--------------------------------------------------------------------------------
1 | /* See 'themis.cpp'. The ephems for the Themis satellites cover about 18
2 | days each. My plan is to set up a cron job to run once a week or so,
3 | downloading THEMIS ephems, running through 'themis' to get those ephems
4 | in the form used by 'eph2tle', then using 'eph2tle' to generate 18 TLEs.
5 |
6 | Then we run this little program to enable TLEs to accumulate, for
7 | historical purposes. Run as
8 |
9 | ./them_cat old_file.tle new_file.tle
10 |
11 | it will generate a new "temporary" TLE that contains data from 'old_file'
12 | right up to the point where 'new_file' starts. Then we finish off with the
13 | 'new_file' data. If this all runs correctly, we move the "temporary" file
14 | over to replace the old file. */
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 | #ifndef _WIN32
21 | #include
22 | #endif
23 | #include
24 | #include
25 | #include "stringex.h"
26 |
27 | static FILE *err_fopen( const char *filename, const char *permits)
28 | {
29 | FILE *rval = fopen( filename, permits);
30 |
31 | if( !rval)
32 | {
33 | fprintf( stderr, "'%s' not opened ", filename);
34 | perror( NULL);
35 | exit( -1);
36 | }
37 | return( rval);
38 | }
39 |
40 | int main( const int argc, const char **argv)
41 | {
42 | FILE *old_file = err_fopen( argv[1], "rb");
43 | FILE *new_file = err_fopen( argv[2], "rb");
44 | FILE *temp_file = err_fopen( "ickywax.ugh", "wb");
45 | double jd0_new, end_jd_new;
46 | char buff[200], new_end[200];
47 | const time_t t0 = time( NULL);
48 | int i;
49 | bool found_end = false;
50 |
51 | assert( argc >= 3);
52 | while( fgets( buff, sizeof( buff), new_file)
53 | && memcmp( buff, "# Ephem range:", 14))
54 | ;
55 | sscanf( buff + 15, "%lf %lf", &jd0_new, &end_jd_new);
56 | for( i = 0; i < 3; i++) /* skip lines */
57 | if( !fgets( buff, sizeof( buff), new_file))
58 | perror( "Error reading 'new' file");
59 | strlcpy_error( new_end, buff);
60 |
61 | while( !found_end && fgets( buff, sizeof( buff), old_file))
62 | {
63 | if( !memcmp( buff, "# Ephem range:", 14))
64 | snprintf_err( buff + 28, sizeof( buff) - 28, "%f %f\n", end_jd_new, 1.);
65 | if( !memcmp( buff, "# Ephemeris end:", 16))
66 | strlcpy_error( buff, new_end);
67 | if( !memcmp( buff, "# Last updated with", 19))
68 | strlcpy_err( buff + 42, asctime( gmtime( &t0)), sizeof( buff) - 42);
69 |
70 | fputs( buff, temp_file);
71 | if( !memcmp( buff, "# MJD ", 6) && atof( buff + 6) == jd0_new - 1.)
72 | found_end = true;
73 | }
74 | assert( found_end);
75 | for( i = 0; i < 3 && fgets( buff, sizeof( buff), old_file); i++)
76 | fputs( buff, temp_file);
77 | fclose( old_file);
78 | while( fgets( buff, sizeof( buff), new_file))
79 | fputs( buff, temp_file);
80 | fclose( temp_file);
81 | fclose( new_file);
82 | #ifdef _WIN32
83 | _unlink( argv[1]);
84 | #else
85 | unlink( argv[1]);
86 | #endif
87 | rename( "ickywax.ugh", argv[1]);
88 | return( 0);
89 | }
90 |
--------------------------------------------------------------------------------
/comets.h:
--------------------------------------------------------------------------------
1 | /* comets.h: header file for comet/asteroid functions
2 | Copyright (C) 2010, Project Pluto
3 |
4 | This program is free software; you can redistribute it and/or
5 | modify it under the terms of the GNU General Public License
6 | as published by the Free Software Foundation; either version 2
7 | of the License, or (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 | 02110-1301, USA. */
18 |
19 | #define ELEMENTS struct elements
20 |
21 | #pragma pack(4)
22 | ELEMENTS
23 | {
24 | double perih_time, q, ecc, incl, arg_per, asc_node;
25 | double epoch, mean_anomaly;
26 | /* derived quantities: */
27 | double lon_per, minor_to_major;
28 | double perih_vec[3], sideways[3];
29 | double angular_momentum, major_axis, t0, w0;
30 | double abs_mag, slope_param, gm;
31 | int is_asteroid, central_obj;
32 | };
33 | #pragma pack( )
34 |
35 | /* Note that in the above structure, t0 = 1/n = time to move */
36 | /* one radian in mean anomaly = orbital period / (2*pi). */
37 |
38 | #ifdef __cplusplus
39 | extern "C" {
40 | #endif
41 |
42 | #include
43 |
44 | // void calc_vectors( ELEMENTS *elem, const double sqrt_gm);
45 | int DLL_FUNC calc_classical_elements( ELEMENTS *elem, const double *r,
46 | const double t, const int ref);
47 | int DLL_FUNC comet_posn_and_vel( ELEMENTS DLLPTR *elem, double t,
48 | double DLLPTR *loc, double DLLPTR *vel);
49 | int DLL_FUNC comet_posn( ELEMENTS DLLPTR *elem, double t, double DLLPTR *loc); /* astfuncs.c */
50 | void DLL_FUNC derive_quantities( ELEMENTS DLLPTR *e, const double gm);
51 | int DLL_FUNC setup_elems_from_ast_file( ELEMENTS DLLPTR *class_elem,
52 | const uint32_t DLLPTR *elem, const double t_epoch);
53 | double DLL_FUNC phase_angle_correction_to_magnitude( const double phase_angle,
54 | const double slope_param);
55 | int setup_planet_elem( ELEMENTS *elem, const int planet_idx,
56 | const double t_cen);
57 | int extract_sof_data( ELEMENTS *elem, const char *buff, const char *header);
58 | int extract_sof_data_ex( ELEMENTS *elem, const char *buff, const char *header,
59 | double *extra_info); /* sof.cpp */
60 | double extract_yyyymmdd_to_jd( const char *buff); /* sof.cpp */
61 |
62 | typedef struct
63 | {
64 | double obj1_true_anom, jd1; /* these are set in find_moid_full */
65 | double obj2_true_anom, jd2; /* NOT SET YET */
66 | double barbee_speed; /* in AU/day */
67 | } moid_data_t;
68 |
69 | double DLL_FUNC find_moid_full( const ELEMENTS *elem1, const ELEMENTS *elem2, moid_data_t *mdata);
70 |
71 | #ifdef __cplusplus
72 | }
73 | #endif
74 |
--------------------------------------------------------------------------------
/triton.cpp:
--------------------------------------------------------------------------------
1 | /* triton.cpp: low-precision ephems for Triton
2 |
3 | Copyright (C) 2010, Project Pluto
4 |
5 | This program is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU General Public License
7 | as published by the Free Software Foundation; either version 2
8 | of the License, or (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 | 02110-1301, USA. */
19 |
20 | #include
21 | #include "watdefs.h"
22 | #include "lunar.h"
23 | #include "afuncs.h"
24 |
25 | #define J2000 2451545.
26 | #define PI 3.1415926535897932384626433832795028841971693993751058209749445923
27 |
28 | /* For the following, see p 373 of the _Explanatory Supplement_ */
29 | /* Note that 'rocks.cpp' also has code for computing the position of Triton.
30 | The following is, therefore, essentially obsolete. */
31 |
32 | void DLL_FUNC calc_triton_loc( const double jd, double *vect)
33 | {
34 | const double t_cent = (jd - J2000) / 36525.;
35 | const double n = (359.28 + 54.308 * t_cent) * (PI / 180.);
36 | const double t0 = 2433282.5;
37 | const double theta = (151.401 + .57806 * (jd - t0) / 365.25) * (PI / 180.);
38 | /* Semimajor axis is 488.49 arcseconds at one AU: */
39 | const double semimajor = 488.49 * (PI / 180.) / 3600.;
40 | const double longitude =
41 | (200.913 + 61.2588532 * (jd - t0)) * (PI / 180.);
42 | const double gamma = 158.996 * (PI / 180.);
43 |
44 | /* Calculate longitude and latitude on invariable plane: */
45 | const double lon_on_ip = theta + atan2( sin( longitude) * cos( gamma),
46 | cos( longitude));
47 | const double lat_on_ip = asin( sin( longitude) * sin( gamma));
48 | /* Vectors defining invariable plane, expressed in B1950: */
49 | double x_axis[3], y_axis[3], z_axis[3];
50 | /* Vector defining Triton position in invariable plane space: */
51 | double triton[3];
52 | /* RA/dec of the pole: */
53 | double ra_dec_p[2];
54 | double matrix[9];
55 | double vect_1950[3];
56 | int i;
57 |
58 | polar3_to_cartesian( triton, lon_on_ip, lat_on_ip);
59 |
60 | ra_dec_p[0] = (298.72 * PI / 180.) + (2.58 * PI / 180.) * sin( n)
61 | - (0.04 * PI / 180.) * sin( n + n);
62 | ra_dec_p[1] = (42.63 * PI / 180.) - (1.90 * PI / 180.) * cos( n)
63 | + (0.01 * PI / 180.) * cos( n + n);
64 | setup_precession( matrix, 1950., 2000.);
65 | precess_ra_dec( matrix, ra_dec_p, ra_dec_p, 1);
66 | polar3_to_cartesian( x_axis, ra_dec_p[0] + PI / 2., 0.);
67 | polar3_to_cartesian( y_axis, ra_dec_p[0] + PI, PI / 2. - ra_dec_p[1]);
68 | polar3_to_cartesian( z_axis, ra_dec_p[0], ra_dec_p[1]);
69 |
70 | for( i = 0; i < 3; i++)
71 | vect_1950[i] = semimajor * (x_axis[i] * triton[0] +
72 | y_axis[i] * triton[1] + z_axis[i] * triton[2]);
73 | precess_vector( matrix, vect_1950, vect);
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/moidtest.txt:
--------------------------------------------------------------------------------
1 | Name |C |Tp . |Te |q |i . |Om . |om . |e |n_u |n_o |rms. |Tfirst |Tlast |H . |G |Twritten. ^
2 | CJ95O010 19970330.3688675 20130813 0.91971424 89.573293 282.053191 130.681474 0.99493312 3616 3616 1.6 19930427.77 20130813.32 2.8 10.0 20181022.1095
3 | hale1 19970330.3688675 20130813 0.91971424 89.573293 282.053191 130.681474 0.99993312 3616 3616 1.6 19930427.77 20130813.32 2.8 10.0 20181022.1095
4 | K16V01B 20170225.4865665 20161105 0.51790827 2.404097 43.038361 173.857333 0.31567127 44 44 0.7 20161105.45 20161108.11 28.6 0.15 20181019.7512
5 | K14S00E 20141006.8011685 20140921 1.02927157 20.051616 351.119492 22.439099 0.17226306 22 22 0.6 20140916.16 20140921.87 25.3 0.15 20181020.0300
6 | K05Q11O 20130710.0934002 20140225 1.20160773 45.190269 163.091520 231.376682 0.50943671 181 181 0.5 20050828.15 20140225.04 19.1 0.15 20181020.0317
7 | 00588 20230503.2487172 20181010 4.44669508 10.318794 316.535808 133.418685 0.14640725 1376 1503 0.6 19720904.84 20181010.29 8.4 0.15 20181022.1083
8 | J99A10N 20180823.3237952 20190427 0.63865361 39.931199 314.386280 268.327414 0.56216577 172 173 0.6 19550126.40 20130304.77 18.3 0.15 20181024.0492
9 | K18U00L 20180920.9054030 20181020 0.96695902 0.768560 201.447506 151.726056 0.28271825 39 40 0.5 20181018.21 20181019.30 29.1 0.15 20181024.9187
10 | K11C01Q 20110326.6909216 20110202 0.90886394 1.080878 135.382944 58.713560 0.19555169 35 35 0.9 20110204.23 20110204.75 32.0 0.15 20181024.9327
11 | A10c9Hw 20190126.5179220 20190218 0.96433842 5.806607 141.193420 340.490896 0.52262560 37 37 0.3 20190215.53 20190218.43 26.1 0.15 20190220.6992
12 | AK17U010 20170909.4958011 20171123 0.25558762 122.710325 24.598185 241.747571 1.20016896 175 192 0.3 20171018.47 20171123.37 22.0 0.15 20181019.7520
13 | hale2 19970330.3688675 20130813 0.91971424 89.573293 282.053191 130.681474 1.00010312 3616 3616 1.6 19930427.77 20130813.32 2.8 10.0 20181022.1095
14 | CK19Q040 20191207.9436140 20190910 2.03235968 43.822756 308.371745 208.531655 3.46244900 128 128 0.7 20190830.04 20190910.63 12.5 0.15 20190919.6215
15 |
16 | MOID AK17U010 `Oumuamua : 0.0958212
17 | /* (433) Eros : MOID = 0.149341 */
18 | /* (4179) Toutatis : MOID = 0.00609937 */
19 | /* (163693) Atira : MOID = 0.206823 */
20 | MOID K16V01B 2016 VB1 : 0.0012415773444360
21 | MOID K14S00E : 0.0342838294450511
22 | MOID K05Q11O 0.3352818313812920
23 | MOID 00588 3.47306
24 | MOID CJ95O010 0.116025
25 | MOID J99A10N 0.000128404
26 | MOID CK19Q040 1.11575 (wrt jupiter : 2.37345)
27 |
28 | A10ccKO 20181219.0435365 20190227 0.80541305 10.359704 336.456356 90.965887 0.24925404 8 8 0.1 20190226.44 20190226.87 25.0 0.15 20190226.9165
29 | C09JH82 20190409.3478258 20190302 1.75132141 28.792401 105.232279 71.255700 0.30153792 14 14 0.2 20190301.32 20190301.89 17.3 0.15 20190302.0706
30 | K18J02D 20130910.3301017 20131001 0.21342780 50.894109 54.698961 313.135832 0.88293807 115 115 0.4 20130429.53 20180701.17 18.9 0.15 20190318.7890
31 |
32 |
--------------------------------------------------------------------------------
/cgicheck.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | On-line asteroid identification
5 |
6 |
7 |
8 |
9 |
10 | On-line asteroid identification
11 |
12 |
13 | Source code for this can be found on GitHub.
14 |
15 | This is an on-line version of the astcheck
16 | program used for identifying observations with known objects.
17 | Use the form below to find asteroids that might match the position/motion
18 | of objects you've observed.
19 |
20 | Suggested quick start: Don't panic! Copy/paste observations
21 | for one or more objects in the large text window below, or
22 | click on "Browse" to pick a file containing the astrometry. Then click
23 | the "find matching asteroids" button. That will probably be all you
24 | need.
25 |
26 | The output will show each object, and its motion in arcseconds/hour.
27 | After that, you'll see possible matching objects, and their offsets in
28 | arcseconds and their motions in arcseconds/hour. You can set a limit for
29 | the search radius, and can tell the program whether to use the Minor
30 | Planet Center's
31 | MPCORB or the Lowell Observatory
32 | ASTORB orbit catalog. The latter offers "current ephemeris uncertainty"
33 | data. This is not perhaps as rock-solid as it ought to be, but can tell
34 | you if the predicted position from the orbital elements is very, very good,
35 | or complete rubbish.
36 |
37 | You can also show only possible matches with unnumbered objects, useful
38 | to those who are already pretty confident that the object isn't easily identified.
39 |
40 | If you're still not getting things to work, contact me at
41 | pôç.ötulpťcéjôřp@otúlm
42 | (modified to baffle spammers).
43 |
44 |
45 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/jpl_xref.h:
--------------------------------------------------------------------------------
1 | /* The following table is going to need occasional fixes, mostly
2 | as new spacecraft are launched. Cas = Cassini, SoO = Solar Orbiter,
3 | etc. are _not_ official MPC codes; if they ever get them, that
4 | will also cause updates to be made. The list does not reflect
5 | every spacecraft listed on Horizons; it lists those that have
6 | either gotten astrometry or for which I compute TLEs. */
7 |
8 | typedef struct
9 | {
10 | const char mpc_code[4];
11 | int jpl_desig, norad_number;
12 | const char *intl_desig, *name;
13 | } jpl_xref_t;
14 |
15 | /* MPC code JPL# NORAD# Intl desig Common name */
16 | static const jpl_xref_t jpl_xrefs[] = {
17 | { "Cap", -1176, 52914, "2022-070A", "CAPSTONE" },
18 | { "Cas", -82, 25008, "1997-061A", "Cassini" },
19 | { "Cha", -151, 25867, "1999-040B", "Chandra X-ray Observatory" },
20 | { "Cdr", -158, 57320, "2023-098A", "Chandrayaan-3" },
21 | { "Equ", -101, 79970, "2022-156ZZZ", "EQUULEUS" },
22 | { "EsB", -9, 66451, "2025-260A", "EscaPADE Blue" },
23 | { "EsG", -10, 66452, "2025-260B", "EscaPADE Gold" },
24 | { "273", -680, 57209, "2023-092A", "Euclid" },
25 | { "EuC", -159, 61507, "2024-182A", "Europa Clipper" },
26 | { "339", -143, 41388, "2016-017A", "ExoMars Trace Gas Orbiter" },
27 | { "258", -139479, 39479, "2013-074A", "Gaia" },
28 | { "Goe", -160133, 60133, "2024-119A", "GOES-19" },
29 | { "Ha2", -37, 40319, "2014-076A", "Hayabusa 2" },
30 | { "Her", -91, 61449, "2024-180A", "Hera", },
31 | { "250", -48, 20580, "1990-037B", "Hubble Space Telescope" },
32 | { "IM1", -229, 58963, "2024-030A", "IM-1 (Odysseus)" },
33 | { "274", -170, 50463, "2021-130A", "James Webb Space Telescope" },
34 | { "Jui", -28, 56176, "2023-053A", "JUICE" },
35 | { "C55", -227, 34380, "2009-011A", "Kepler" },
36 | { "C56", -141043, 41043, "2015-070A", "LISA Pathfinder" },
37 | { "Luc", -49, 49328, "2021-093A", "Lucy" },
38 | { "LFL", -164, 54697, "2022-168B", "Lunar Flashlight" },
39 | { "MRO", -74, 28788, "2005-029A", "Mars Reconnaissance Orbiter" },
40 | { "289", -211, 99999, "2026-000ZZZ", "Nancy Grace Roman Space Telescope" },
41 | { "C53", -139089, 39089, "2013-009D", "NEOSSat" },
42 | { "C58", -33, 99999, "2027-000ZZZ", "NEO Surveyor" },
43 | { "C54", -98, 28928, "2006-001A", "New Horizons" },
44 | { "OsR", -64, 41757, "2016-055A", "OSIRIS-REx" },
45 | { "PSP", -96, 43592, "2018-065A", "Parker Solar Probe" },
46 | { "Prg", -244, 58751, "2024-006A", "Peregrine" },
47 | { "338", -255, 58049, "2023-157A", "Psyche" },
48 | { "Sli", -240, 57803, "2023-137D", "SLIM" },
49 | { "249", -21, 23726, "1995-065A", "SOHO" },
50 | { "SoO", -144, 45167, "2020-010A", "Solar Orbiter" },
51 | { "288", -163183, 63183, "2025-047E", "SPHEREx" },
52 | { "245", -79, 27871, "2003-038A", "Spitzer Space Telescope" },
53 | { "C49", -234, 29510, "2006-047A", "STEREO-A" },
54 | { "C50", -235, 29511, "2006-047B", "STEREO-B" },
55 | { "C52", -128485, 28485, "2004-047A", "Swift" },
56 | { "C57", -95, 43435, "2018-038A", "TESS" },
57 | { "Tia", -9901491, 45935, "2020-049A", "Tianwen-1" },
58 | { "C51", -163, 36119, "2009-071A", "WISE" },
59 | { "C59", -148840, 48841, "2021-050B", "Yangwang 1" } };
60 | /* MPC code JPL# NORAD# Intl desig Common name */
61 |
--------------------------------------------------------------------------------
/jpl_url.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include "watdefs.h"
6 | #include "date.h"
7 | #include "jpl_xref.h"
8 |
9 | /* You can access vector (and other) ephemerides from JPL Horizons
10 | with a URL. This program generates the URL required for a particular
11 | object covering a particular year at 0.1 day intervals; the resulting
12 | ephemerides can be fed through 'jpl2mpc', then 'eph2tle' to generate
13 | TLEs for that year. The URL looks like (broken into multiple lines
14 | for clarity/explanations; this is for Gaia in 2020):
15 |
16 | https://ssd.jpl.nasa.gov/api/horizons_api?format=text
17 | &COMMAND=%27-139479%27 object -139479 = JPL ID for Gaia
18 | &OBJ_DATA=%27YES%27 give us the header/boilerplate info
19 | &TABLE_TYPE=%27V%27 V = vector ephems
20 | &START_TIME=%272020-01-01%27 starts 2020 Jan 1
21 | &START_TIME=%27JD2458849.5%27 (alternative start format)
22 | &STOP_TIME=%272021-01-01%27 ends the following year
23 | &STOP_TIME=%27JD2459215.5%27 (similarly alternative end format)
24 | &STEP_SIZE=%273660%27 3660 steps (2020 was a leap year)
25 | &VEC_TABLE=%272%27 table type 2 = positions & velocities
26 | &VEC_LABELS=%27NO%27 skip the XYZ VXVYVZ labelling
27 |
28 | Compiles with gcc -Wall -Wextra -pedantic -o jpl_url jpl_url.c liblunar.a -lm */
29 |
30 | static void error_exit( void)
31 | {
32 | const size_t n_xrefs = sizeof( jpl_xrefs) / sizeof( jpl_xrefs[0]);
33 | size_t i;
34 |
35 | fputs( "usage : jpl_url obj_desig start_date end_date\n"
36 | " obj_desig = MPC code or YYYY-NNNA (COSPAR) designation\n"
37 | "See comments in 'jpl_url.c' for details.\n"
38 | "Supported objects:\n\n"
39 | "MPC COSPAR_desig name\n", stderr);
40 | for( i = 0; i < n_xrefs; i++)
41 | fprintf( stderr, "%s %-11s %s\n", jpl_xrefs[i].mpc_code,
42 | jpl_xrefs[i].intl_desig,
43 | jpl_xrefs[i].name);
44 | exit( -1);
45 | }
46 |
47 | int main( const int argc, const char **argv)
48 | {
49 | size_t i = 0;
50 | const size_t n_xrefs = sizeof( jpl_xrefs) / sizeof( jpl_xrefs[0]);
51 | double jd1, jd2;
52 | const double min_jd = 2447892.5; /* 1990 Jan 1 */
53 |
54 | if( argc < 4)
55 | error_exit( );
56 | while( i < n_xrefs && strcmp( argv[1], jpl_xrefs[i].mpc_code)
57 | && strcmp( argv[1], jpl_xrefs[i].intl_desig)
58 | && atoi( argv[1]) != jpl_xrefs[i].jpl_desig)
59 | i++;
60 | if( i == n_xrefs)
61 | {
62 | fprintf( stderr, "'%s' is not a spacecraft MPC code, YYYY-NNNA"
63 | " designation, or Horizons object number\n", argv[1]);
64 | fprintf( stderr, "Valid designations are :\n");
65 | error_exit( );
66 | }
67 | jd1 = get_time_from_string( 0., argv[2], 0, NULL);
68 | jd2 = get_time_from_string( jd1, argv[3], 0, NULL);
69 | if( jd1 < min_jd || jd2 < min_jd)
70 | {
71 | fprintf( stderr, "Can't go before JD %f\n", min_jd);
72 | error_exit( );
73 | }
74 | printf( "https://ssd.jpl.nasa.gov/api/horizons.api?format=text");
75 | printf( "&COMMAND='%d'", jpl_xrefs[i].jpl_desig);
76 | printf( "&OBJ_DATA='YES'&TABLE_TYPE='V'");
77 | printf( "&START_TIME='JD%f'", jd1);
78 | printf( "&STOP_TIME='JD%f'", jd2);
79 | printf( "&STEP_SIZE='%d'", (int)( (jd2 - jd1) * 10. + 0.5));
80 | printf( "&VEC_TABLE='2'&VEC_LABELS='NO'\n");
81 | return( 0);
82 | }
83 |
--------------------------------------------------------------------------------
/disttest.cpp:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2018, Project Pluto
2 |
3 | This program is free software; you can redistribute it and/or
4 | modify it under the terms of the GNU General Public License
5 | as published by the Free Software Foundation; either version 2
6 | of the License, or (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 | 02110-1301, USA. */
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include "watdefs.h"
23 | #include "afuncs.h"
24 |
25 | /* Test routine for position angle/distance code.
26 |
27 | I'm not using the library rand( ) function, because I want to be
28 | confident that the results will be the same when compiled on different
29 | systems. Following is the MMIX linear congruential pseudo-random number
30 | generator, copied from Donald Knuth. It's not a great PRNG, but it's
31 | fine for the current humble purpose. */
32 |
33 | uint64_t pseudo_random( const uint64_t prev_value)
34 | {
35 | uint64_t a = UINT64_C( 6364136223846793005);
36 | uint64_t c = UINT64_C( 1442695040888963407);
37 |
38 | return( a * prev_value + c);
39 | }
40 |
41 | static double get_pseudorandom_double( void)
42 | {
43 | static uint64_t rval = 1;
44 | const double two_to_the_53rd_power = 9007199254740992.0;
45 |
46 | rval = pseudo_random( rval);
47 | return (int64_t)(rval >> 11) * (1.0 / two_to_the_53rd_power);
48 | }
49 |
50 | /* Should provide RA/dec values uniformly distributed over the */
51 | /* celestial sphere. */
52 |
53 | static void get_random_ra_dec( double *ra, double *dec)
54 | {
55 | double x, y, z, dist;
56 |
57 | do
58 | {
59 | x = get_pseudorandom_double( ) - .5;
60 | y = get_pseudorandom_double( ) - .5;
61 | z = get_pseudorandom_double( ) - .5;
62 | }
63 | while( (dist = x * x + y * y + z * z) > .125);
64 | *ra = atan2( y, x);
65 | *dec = asin( z / sqrt( dist));
66 | }
67 |
68 | static double calc_dist_with_acos( double *p1, double *p2)
69 | {
70 | double d_ra = p1[0] - p2[0];
71 | double cos_dist = sin( p1[1]) * sin( p2[1]) + cos( p1[1]) * cos( p2[1]) * cos( d_ra);
72 |
73 | return( acos( cos_dist));
74 | }
75 |
76 | int main( const int argc, const char **argv)
77 | {
78 | int i;
79 |
80 | for( i = 0; i < 10000; i++)
81 | {
82 | double p1[2], p2[2], dist1, dist2;
83 | const double pi = 3.1415926535897932384626433832795028841971693993751058209749445923;
84 |
85 | get_random_ra_dec( p1, p1 + 1);
86 | get_random_ra_dec( p2, p2 + 1);
87 | if( !i && argc == 5)
88 | {
89 | p1[0] = atof( argv[1]) * pi / 180.;
90 | p1[1] = atof( argv[2]) * pi / 180.;
91 | p2[0] = atof( argv[3]) * pi / 180.;
92 | p2[1] = atof( argv[4]) * pi / 180.;
93 | }
94 | calc_dist_and_posn_ang( p1, p2, &dist1, NULL);
95 | dist2 = calc_dist_with_acos( p1, p2);
96 | printf( "%12.8lf %12.8lf %lg\n",
97 | dist1 * 180. / pi,
98 | dist2 * 180. / pi,
99 | (dist1 - dist2) * 180. / pi);
100 | }
101 | return( 0);
102 | }
103 |
--------------------------------------------------------------------------------
/gust_ref.cpp:
--------------------------------------------------------------------------------
1 | /* gust_ref.cpp: function to compute Uranian satellite matrix
2 |
3 | Copyright (C) 2010, Project Pluto
4 |
5 | This program is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU General Public License
7 | as published by the Free Software Foundation; either version 2
8 | of the License, or (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 | 02110-1301, USA. */
19 |
20 | #include
21 |
22 | /* The original GUST86 code transformed Uranicentric coords to B1950.
23 | Rather than do that, then precess to J2000, I wrote the snippet below
24 | to compute the full Uranicentric-to-J2000 matrix. Also, the original
25 | code did quite a bit of math to convert alf and del -- the RA and dec
26 | of the Uranian pole in B1950 -- into a rotation matrix. If you just
27 | store the matrix as nine precomputed doubles, you save yourself
28 | some code and time and math.
29 |
30 | Spoiler alert: the resulting output is
31 |
32 | { 0.9753206898, -0.2207422915, 0.0047321138},
33 | { 0.0619432123, 0.2529905682, -0.9654837185},
34 | { 0.2119259083, 0.9419493686, 0.2604204221},
35 |
36 | If you look at the gust86_posn() in gust86.c, you will see this matrix.
37 | So there is not really any reason to build this code.
38 | */
39 |
40 | int main( const int unused_argc, const char **unused_argv)
41 | {
42 | // const double alf = 76.60666666666667 * DEGREES_TO_RADIANS;
43 | // const double del = 15.03222222222222 * DEGREES_TO_RADIANS;
44 | // The GUST86 method originally used the above 'alf' and 'del'
45 | // values to specify the rotation from the plane of Uranus'
46 | // equator to the B1950 equator. The 3x3 matrix was computed
47 | // within this code. To simplify life a little, I've set the
48 | // matrix to be a batch of 'const' values.
49 | // alf and delta aren't used here, but their sines and cosines are...
50 | const double sin_alf = .9728028367170815;
51 | const double cos_alf = .2316347143137209;
52 | const double sin_del = .2593622252488415;
53 | const double cos_del = .9657801178912150;
54 | // ...to build the following 3x3 matrix to convert from Uranicentric
55 | // coords to B1950:
56 | const double trans[3][3] = {
57 | { sin_alf, -cos_alf, 0. },
58 | { cos_alf * sin_del, sin_alf * sin_del, -cos_del },
59 | { cos_alf * cos_del, sin_alf * cos_del, sin_del } };
60 |
61 | // Rotation matrix for converting from B1950.0 FK4 positions
62 | // to J2000.0 FK5 positions.
63 |
64 | double P[3][3] =
65 | {
66 | { 0.9999256782, -0.0111820611, -0.0048579477 },
67 | { 0.0111820610, 0.9999374784, -0.0000271765 },
68 | { 0.0048579479, -0.0000271474, 0.9999881997 }
69 | };
70 | int i, j, k;
71 |
72 | /* Multiply trans by P and show the resulting matrix: */
73 | for( i = 0; i < 3; i++)
74 | for( j = 0; j < 3; j++)
75 | {
76 | double elem = 0;
77 |
78 | for( k = 0; k < 3; k++)
79 | elem += trans[i][k] * P[j][k];
80 | if( !j)
81 | printf( " { ");
82 | printf( "%13.10lf%s", elem, (j == 2) ? "},\n" : ", ");
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/test_des.txt:
--------------------------------------------------------------------------------
1 | # Test input for 'test_des'. See 'test_des.cpp'.
2 | # 'Test 1' = test packing; 'Test 2' = test unpacking; 'Test 3' = test both
3 | # At present, we have one pack-only test. 'Neptune 210' packs to N210S;
4 | # but on unpacking, it becomes 'Neptune CCX'.
5 | # Test 2
6 | N210S 5 Neptune 210
7 | # And we have some unpacking-only tests. The following should
8 | # be unpacked correctly, but you lose the redundant provisional desig
9 | # data in the process. So it can't be packed to get the original input.
10 | # Test 1
11 | 0001IK17U010 3 1I
12 | 0001PI35P010 3 1P
13 | 67282J99A38M 1 (67282) = 1999 AM38
14 | # All the other tests are bidirectional :
15 | # Test 3
16 | # Packed Typ Fullname
17 | J95X00A 0 1995 XA
18 | K07Tf8A 0 2007 TA418
19 | SK03J020 4 S/2003 J 2
20 | SJ45Ux90 4 S/1945 U 599
21 | 0041P 3 41P
22 | 3141P e 3 3141P-E
23 | 3141P az 3 3141P-AZ
24 | DJ65Az9c 2 D/1965 A619-C
25 | XJ65K810 2 X/1965 K81
26 | PLS2040 0 2040 P-L
27 | T3S3141 0 3141 T-3
28 | 00433 1 (433)
29 | G4060 1 (164060)
30 | n1415 1 (491415)
31 | ~0000 1 (620000)
32 | ~000a 1 (620036)
33 | ~00A0 1 (620620)
34 | ~AZaz 1 (3140113)
35 | ~zzzz 1 (15396335)
36 | U024S 5 Uranus XXIV
37 | N924S 5 Neptune CMXXIV
38 | N089S 5 Neptune LXXXIX
39 | U410S 5 Uranus CDX
40 | 1992-044A 6 1992-044A
41 | 1963-731KHG 6 1963-731KHG
42 | WT1190F -1 WT1190F
43 | ZTF0Ep4 -1 ZTF0Ep4
44 | C12J001 -1 C12J001
45 | 9496058 -1 9496058
46 | G4060e -1 G4060e
47 | 1762B11 -1 1762B11
48 | _QC0000 0 2026 CA620
49 | _QC0aEM 0 2026 CZ6190
50 | _QCzzzz 0 2026 CL591673
51 | _AH9fZ7 0 2010 HJ92809
52 | C_3MDZ3v 2 C/2003 MX129941
53 | P_WY0Mpc 2 P/2032 YT4130
54 | # MPC optimistically states (see
55 | # https://minorplanetcenter.net/media/newsletters/MPC_Newsletter_Oct2023.pdf
56 | # ) that the extension allowing packed provisional designations past cycle 620
57 | # = 15500th object in a half-month will not be used after the end of 2035,
58 | # and that therefore the year will be designated by an uppercase letter. I am
59 | # less sanguine and am allowing lowercase letters (hence base-62) to allow the
60 | # scheme to work to the end of 2061. With any luck, I'll be dead by then.
61 | _cRAZaz 0 2038 RO101424
62 | _xMDZ3v 0 2059 MX129941
63 | # MPC provides a few examples at
64 | # https://minorplanetcenter.net/mpcops/documentation/provisional-designation-definition/#extended_packed_provid
65 | # so let's test 'em out :
66 | K23B00A 0 2023 BA
67 | K24C03Z 0 2024 CZ3
68 | K25Dz9Z 0 2025 DZ619
69 | _PD0000 0 2025 DA620
70 | _QD000N 0 2026 DY620
71 | _RD0aEM 0 2027 DZ6190
72 | _SEZZZZ 0 2028 EA339749
73 | _TFzzzz 0 2029 FL591673
74 | # ...and, sometime between my writing the above and 2025 Apr 15, MPC added
75 | # 'explicit examples of cometified [sic] object designations'. Let's test
76 | # them, too. (Note that they're actually the same examples, except with a
77 | # letter-slash prepended.)
78 | PK23B00A 2 P/2023 BA
79 | CK24C03Z 2 C/2024 CZ3
80 | AK25Dz9Z 0 A/2025 DZ619
81 | P_PD0000 2 P/2025 DA620
82 | C_QD000N 2 C/2026 DY620
83 | A_RD0aEM 0 A/2027 DZ6190
84 | C_SEZZZZ 2 C/2028 EA339749
85 | P_TFzzzz 2 P/2029 FL591673
86 | # I had cases (now fixed) of eight-character designations starting with P, C,
87 | # D, X, A, etc. which were erroneously treated as comet or satellite desigs.
88 | # These can't be re-packed (and are not really valid packed designations to
89 | # begin with), so only unpacking is tested.
90 | # Test 1
91 | Censored -1 Censored
92 | P317abo# -1 P317abo#
93 | STress17 -1 STress17
94 |
--------------------------------------------------------------------------------
/get_bin.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2018, Project Pluto
2 |
3 | This program is free software; you can redistribute it and/or
4 | modify it under the terms of the GNU General Public License
5 | as published by the Free Software Foundation; either version 2
6 | of the License, or (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 | 02110-1301, USA. */
17 |
18 | /* Code to read integers of various sizes and 64-bit double-precision
19 | floats from binary data buffers. See uses in 'vsopson.cpp' and 'lunar2.cpp'
20 | where data is extracted from binary files.
21 |
22 | It's assumed that the input data is in Intel (little-Endian) order.
23 |
24 | On Intel machines, you can extract such data by type-punning,
25 | even if the data isn't aligned on a word boundary. On some other
26 | machines, the data must be aligned on a word boundary and/or you
27 | may have reverse the byte order.
28 |
29 | OpenWATCOM, Microsoft C, Borland, TurboC, and Digital Mars are all
30 | Intel-only. If we're using one of those compilers, we can type-pun.
31 | gcc and clang #define __x86_64__ or __i386__ for Intel hardware.
32 |
33 | There are probably other cases where we could type-pun. But the
34 | non-punning code will work in all cases; all we lose by not punning
35 | is a very small amount of speed. If I learn of other cases where
36 | punning is possible, the conditions under which USE_TYPE_PUNNING
37 | is defined can be modified. */
38 |
39 | #if defined(__x86_64__) || defined(__i386__) || defined(__WATCOMC__) \
40 | || defined(_MSC_VER) || defined (__BORLANDC__) \
41 | || defined (__TURBOC__) || defined( __DMC__)
42 | #define USE_TYPE_PUNNING
43 | #endif
44 |
45 | #if defined( __WORD_ORDER__) && (__WORD_ORDER__ == __ORDER_BIG_ENDIAN__)
46 | #define USING_BIG_ENDIAN
47 | #endif
48 |
49 | #undef USE_TYPE_PUNNING
50 |
51 | #ifdef USE_TYPE_PUNNING
52 | #define get16bits(d) (*((const uint16_t *) (d)))
53 | #define get32bits(d) (*((const uint32_t *) (d)))
54 | #define get64bits(d) (*((const uint64_t *) (d)))
55 |
56 | /* Signed integer extraction : */
57 | #define get16sbits(d) (*((const int16_t *) (d)))
58 | #define get32sbits(d) (*((const int32_t *) (d)))
59 | #define get64sbits(d) (*((const int64_t *) (d)))
60 | #define get_double(d) (*((const double *) (d)))
61 | #else /* Can't directly read binary data */
62 | #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
63 | +(uint32_t)(((const uint8_t *)(d))[0]) )
64 | #define get32bits(d) ((((uint32_t)(((const uint8_t *)(d))[3])) << 24)\
65 | +(((uint32_t)(((const uint8_t *)(d))[2])) << 16)\
66 | +(((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
67 | +(uint32_t)(((const uint8_t *)(d))[0]) )
68 |
69 | #define get16sbits(d) ((int16_t)( get16bits( d)))
70 | #define get32sbits(d) ((int32_t)( get32bits( d)))
71 | #define get64sbits(d) ((int64_t)( get64bits( d)))
72 |
73 | static inline double get_double( const void *iptr)
74 | {
75 | const char *idata = (const char *)iptr;
76 | int i;
77 | double rval;
78 | char *buff = (char *)&rval;
79 |
80 | #if defined( USING_BIG_ENDIAN)
81 | for( i = 7; i >= 0; i--)
82 | #else
83 | for( i = 0; i < 8; i++)
84 | #endif
85 | buff[i] = *idata++;
86 | return( rval);
87 | }
88 | #endif /* End of code to indirectly read binary data */
89 |
--------------------------------------------------------------------------------
/getplane.cpp:
--------------------------------------------------------------------------------
1 | /* getplane.cpp: functions for computing planetary ephems
2 |
3 | Copyright (C) 2010, Project Pluto
4 |
5 | This program is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU General Public License
7 | as published by the Free Software Foundation; either version 2
8 | of the License, or (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 | 02110-1301, USA. */
19 |
20 | #include
21 | #include
22 | #include "watdefs.h"
23 | #include "lunar.h"
24 | #include "afuncs.h"
25 |
26 | #define PI 3.1415926535897932384626433832795028841971693993751058209749445923
27 |
28 | /* The compute_planet( ) function is supposed to provide a "standardized"
29 | way to get positions for planets and the moon, in any of four systems.
30 | You give it a pointer to the VSOP data, a planet number (0=sun,
31 | 1=mercury, ... 9 = Pluto, 10 = the Moon), and a time in centuries
32 | from J2000. The returned array of fifteen doubles gives you the object
33 | position in five different systems:
34 |
35 | ovals[0, 1, 2] = lon, lat, r, heliocentric ecliptic of date;
36 | ovals[3, 4, 5] = x, y, z, heliocentric ecliptic of date;
37 | ovals[6, 7, 8] = x, y, z, heliocentric equatorial of date;
38 | ovals[9, 10, 11] = x, y, z, heliocentric equatorial, J2000.0
39 | ovals[12, 13, 14] = x, y, z, heliocentric ecliptical, J2000.0
40 |
41 | I intended to rig this up so you could keep on going to 11=Io, 12=Europa,
42 | etc. This would make all sorts of sense. But I've not done it yet. */
43 |
44 | int DLL_FUNC compute_planet( const char FAR *vsop_data, const int planet_no,
45 | const double t_c, double DLLPTR *ovals)
46 | {
47 | double lat, lon, r;
48 | const double obliquit = mean_obliquity( t_c);
49 | double matrix[9];
50 | const double obliq_2000 = 23.4392911 * PI / 180.;
51 |
52 | /* first, compute polar heliocentric in eclip of date */
53 | if( planet_no != 10)
54 | {
55 | lon = calc_vsop_loc( vsop_data, planet_no, 0, t_c, 0.);
56 | lat = calc_vsop_loc( vsop_data, planet_no, 1, t_c, 0.);
57 | r = calc_vsop_loc( vsop_data, planet_no, 2, t_c, 0.);
58 | }
59 | else
60 | {
61 | double fund[N_FUND];
62 |
63 | lunar_fundamentals( vsop_data, t_c, fund);
64 | lat = lunar_lat( vsop_data, fund, 0L);
65 | lunar_lon_and_dist( vsop_data, fund, &lon, &r, 0L);
66 | lon *= PI / 180.;
67 | lat *= PI / 180.;
68 | r /= AU_IN_KM; /* from km to AU */
69 | }
70 | ovals[0] = lon;
71 | ovals[1] = lat;
72 | ovals[2] = r;
73 | /* next, compute polar cartesian in eclip of date */
74 | ovals[3] = cos( lon) * cos( lat) * r;
75 | ovals[4] = sin( lon) * cos( lat) * r;
76 | ovals[5] = sin( lat) * r;
77 | /* next, compute polar cartesian in eclip of date, */
78 | /* but in equatorial coords */
79 | FMEMCPY( ovals + 6, ovals + 3, 3 * sizeof( double));
80 | rotate_vector( ovals + 6, obliquit, 0);
81 | /* next, precess to get J2000.0 equatorial values */
82 | setup_precession( matrix, 2000. + t_c * 100., 2000.);
83 | precess_vector( matrix, ovals + 6, ovals + 9);
84 | /* Finally, rotate equatorial J2000.0 into ecliptical J2000 */
85 | FMEMCPY( ovals + 12, ovals + 9, 3 * sizeof( double));
86 | rotate_vector( ovals + 12, -obliq_2000, 0);
87 | return( 0);
88 | }
89 |
--------------------------------------------------------------------------------
/adestags.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | /* See 'ades2mpc.cpp'. This takes a list of ADES tags, in the order
5 | specified in the documentation, and produces arrays suitable for use
6 | in 'ades2mpc.cpp'. It also sorts the tags; this will allow for a
7 | binary search, gaining 0.001% (probably) in speed.
8 |
9 | 2022 Aug 02 : added shapeOcc, obsSubID, trkMPC elements. */
10 |
11 | #define INTENTIONALLY_UNUSED_PARAMETER( param) (void)(param)
12 |
13 | int main( const int intentionally_unused_argc,
14 | const char **intentionally_unused_argv)
15 | {
16 | static const char *tags[] = {
17 | "permID", "provID", "artSat", "trkSub", "obsID", "obsSubID", "trkID",
18 | "trkMPC",
19 | "mode", "stn", "trx", "rcv", "sys", "ctr", "pos1", "pos2", "pos3",
20 | "posCov11", "posCov12", "posCov13",
21 | "posCov22", "posCov23", "posCov33",
22 | "prog", "obsTime", "ra", "dec", "raStar", "decStar", "obsCenter",
23 | "deltaRA", "deltaDec", "dist", "pa", "rmsRA", "rmsDec", "rmsDist",
24 | "rmsPA", "rmsCorr", "delay", "rmsDelay", "doppler", "rmsDoppler",
25 | "astCat", "mag", "rmsMag", "band",
26 | "fltr", /* added 2024 Dec 16 */
27 | "photCat", "photAp",
28 | "nucMag", "logSNR", "shapeOcc", "seeing", "exp",
29 | /* end p6, start p7 */
30 | "rmsFit", "nStars", "com",
31 | "frq", "ref", "disc", "subFmt", "subFrm",
32 | /* end p7/start p8 */
33 | "precTime", "precRA", "precDec", "uncTime", "notes", "remarks",
34 | "deprecated", "localUse", "orbProd", "orbID", "resRA", "resDec",
35 | "selAst", "sigRA", "sigDec", "sigCorr", "sigTime", "biasRA",
36 | "biasDec", "biasTime", "photProd", "resMag", "selPhot",
37 | /* end p9/start p10 */
38 | "sigMag", "biasMag", "photMod", "resDelay", "selDelay", "sigDelay",
39 | "resDoppler", "selDoppler", "sigDoppler", "observatory", "submitter",
40 | "observers", "measurers", "telescope", "software", "coinvestigators",
41 | "collaborators", "fundingSource",
42 | /* end p10/start p11 */
43 | "comment", "optical", "offset", "occultation", "radar", "obsContext",
44 | "obsData", "obsBlock", "opticalResidual", "radarResidual", "ades",
45 | /* start "Table of Restricted Simple Types" */
46 | "MPCID", "OpticalID", "RadarID", "RadarValue", "Precision", "Location",
47 | "Photometry", "OffsetVal", "OpticalRes", "OpticalResMag",
48 | "OpticalResiduals", "RadarResiduals",
49 | /* start p 25 */
50 | "mpcCode", "institution", "design", "aperture", "detector", "fRatio",
51 | "filter", "arrayScale", "pixelScale", "astrometry", "fitOrder",
52 | "photometry", "objectDetection", "line",
53 | "name",
54 | /* added Sep 2018 */
55 | "rmsTime",
56 | /* added April 2024 */
57 | "vel1", "vel2", "vel3",
58 | NULL };
59 | size_t i, j;
60 |
61 | INTENTIONALLY_UNUSED_PARAMETER( intentionally_unused_argv);
62 | INTENTIONALLY_UNUSED_PARAMETER( intentionally_unused_argc);
63 |
64 | for( i = 0; tags[i]; i++)
65 | for( j = i + 1; tags[j]; j++)
66 | if( strcmp( tags[i], tags[j]) > 0)
67 | {
68 | const char *tptr = tags[j];
69 |
70 | tags[j] = tags[i];
71 | tags[i] = tptr;
72 | }
73 |
74 | j = 60;
75 | printf( " static const char *tags[] = {");
76 | for( i = 0; tags[i]; i++)
77 | {
78 | int len = strlen( tags[i]) + 4;
79 |
80 | if( j + len > 60)
81 | {
82 | printf( "\n ");
83 | j = 0;
84 | }
85 | printf( "\"%s\", ", tags[i]);
86 | j += len;
87 | }
88 |
89 | printf( "\n NULL };\n\n");
90 | for( i = 0; tags[i]; i++)
91 | printf( "#define ADES_%-27s%4d\n", tags[i], (int)i + 1);
92 | return( 0);
93 | }
94 |
--------------------------------------------------------------------------------
/watdefs.h:
--------------------------------------------------------------------------------
1 | /* watdefs.h: header file for inter-compiler compatibility
2 | Copyright (C) 2010, Project Pluto
3 |
4 | This program is free software; you can redistribute it and/or
5 | modify it under the terms of the GNU General Public License
6 | as published by the Free Software Foundation; either version 2
7 | of the License, or (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 | 02110-1301, USA. */
18 |
19 | #ifdef __WATCOMC__
20 | #ifndef bool
21 | #define bool int
22 | #endif
23 | #ifndef true
24 | #define true 1
25 | #endif
26 | #ifndef false
27 | #define false 0
28 | #endif
29 | #ifdef __386__
30 | #define BITS_32
31 | #endif
32 | #endif
33 |
34 | #ifdef __GNUC__
35 | #define BITS_32
36 | #endif
37 |
38 | #ifdef _WIN32
39 | #define BITS_32
40 | #endif
41 |
42 | #ifdef BITS_32
43 |
44 | #ifndef FAR
45 | #define FAR
46 | #endif
47 |
48 | #ifndef _HUGE
49 | #define _HUGE
50 | #endif
51 |
52 | #ifndef NEAR
53 | #define NEAR
54 | #endif
55 |
56 | #ifndef PASCAL
57 | #define PASCAL
58 | #endif
59 |
60 | #define FMEMCPY memcpy
61 | #define FMEMCMP memcmp
62 | #define FMEMICMP memicmp
63 | #define FMEMMOVE memmove
64 | #define FMEMSET memset
65 | #define FSTRCPY strcpy
66 | #define FSTRSTR strstr
67 | #define FSTRCAT strcat
68 | #define FSTRNCPY strncpy
69 | #define FSTRICMP stricmp
70 | #define FSTRCMP strcmp
71 | #define FSTRLEN strlen
72 | #define FMALLOC malloc
73 | #define FCALLOC calloc
74 | #define FFREE free
75 | #define FREALLOC realloc
76 | #define STRUPR strupr
77 |
78 | #ifdef __WATCOMC__
79 | #define _ftime ftime
80 | #define _timeb timeb
81 | #define _videoconfig videoconfig
82 | #define _timezone timezone
83 | #define _tzset tzset
84 | #define _swab swab
85 | #define _unlink unlink
86 | /* int _stricmp( char *s1, char *s2); */
87 | /* int _memicmp( char *s1, char *s2, int n); */
88 | #endif
89 | #endif
90 |
91 | #ifndef BITS_32
92 |
93 | #define _FAR __far
94 | #define _HUGE huge
95 |
96 | #ifndef FAR
97 | #define FAR far
98 | #endif
99 |
100 | #ifndef NEAR
101 | #define NEAR near
102 | #endif
103 |
104 | #ifndef PASCAL
105 | #define PASCAL pascal
106 | #endif
107 |
108 | #define FMEMCPY _fmemcpy
109 | #define FMEMCMP _fmemcmp
110 | #define FMEMICMP _fmemicmp
111 | #define FMEMMOVE _fmemmove
112 | #define FMEMSET _fmemset
113 | #define FSTRCPY _fstrcpy
114 | #define FSTRSTR _fstrstr
115 | #define FSTRCAT _fstrcat
116 | #define FSTRNCPY _fstrncpy
117 | #define FSTRLEN _fstrlen
118 | #define FSTRICMP _fstricmp
119 | #define FSTRCMP _fstrcmp
120 | #define FMALLOC _fmalloc
121 | #define FCALLOC _fcalloc
122 | #define FFREE _ffree
123 | #define FREALLOC _frealloc
124 | #define STRUPR _strupr
125 | #endif
126 |
127 | #ifdef _WIN32
128 | #define DLL_FUNC __stdcall
129 | #else
130 | #define DLL_FUNC
131 | #endif
132 |
133 | #define DLLPTR
134 |
135 | /* __restrict is defined in MinGW and Digital Mars, no matter what; and
136 | in Watcom for C, but not C++. It's not in Visual C++ at all. */
137 |
138 | #if defined( __WATCOMC__) && defined( __cplusplus)
139 | #define __restrict
140 | #elif defined( _MSC_VER)
141 | #define __restrict
142 | #endif
143 |
144 | /* A useful trick to suppress 'unused parameter' warnings, modified from
145 |
146 | https://stackoverflow.com/questions/1486904/how-do-i-best-silence-a-warning-about-unused-variables
147 | */
148 |
149 | #define INTENTIONALLY_UNUSED_PARAMETER( param) (void)(param)
150 |
--------------------------------------------------------------------------------
/rckin.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | /* rckin.cpp: processes/reformats JPL 'rckin' files
4 |
5 | Copyright (C) 2010, Project Pluto
6 |
7 | This program is free software; you can redistribute it and/or
8 | modify it under the terms of the GNU General Public License
9 | as published by the Free Software Foundation; either version 2
10 | of the License, or (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program; if not, write to the Free Software
19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 | 02110-1301, USA. */
21 |
22 | #include
23 | #include
24 |
25 | /* Code to convert files such as 'rckin.ura091.txt', etc. from
26 | ftp://ssd.jpl.nasa.gov/pub/eph/satellites/rckin
27 | into the form used in 'rocks.cpp'.
28 |
29 | Of late, JPL hasn't been updating these files. I gather this is
30 | because they are using integrated ephemerides for almost all "rocks".
31 | So this may prove to be of historical interest only. (Although when
32 | I asked, Bob Jacobson kindly provided updates to some of the files.)
33 | */
34 |
35 | int main( const int argc, const char **argv)
36 | {
37 | FILE *ifile = fopen( argv[1], "rb");
38 | char buff[200];
39 | char rock_name[80];
40 |
41 | if( !ifile)
42 | {
43 | printf( "%s not opened\n", argv[1]);
44 | return( -1);
45 | }
46 |
47 | while( fgets( buff, sizeof( buff), ifile))
48 | {
49 | char *tptr = strchr( buff + 19, '\'');
50 |
51 | if( tptr)
52 | *tptr = '\0';
53 | tptr = strchr( buff + 19, ',');
54 | if( tptr)
55 | *tptr = '\0';
56 | tptr = buff + 19;
57 | if( !memcmp( buff, " RCKNAM", 8))
58 | {
59 | int i;
60 |
61 | strcpy( rock_name, tptr);
62 | for( i = 1; rock_name[i]; i++)
63 | rock_name[i] = tolower( rock_name[i]);
64 | }
65 | if( !memcmp( buff, " RCKNUM", 8))
66 | printf( "\n { %d, /* %s %s*/\n", atoi( buff + 17),
67 | rock_name, (argc < 3 ? " " : argv[2]));
68 | if( !memcmp( buff, " RCKEP", 7))
69 | {
70 | strcat( tptr, ",");
71 | printf( " %-38s/* element epoch Julian date */\n", tptr);
72 | }
73 | if( !memcmp( buff, " RCKELT", 8))
74 | {
75 | const int field_no = atoi( buff + 9);
76 | const char *comment[10] = { NULL,
77 | "a = semi-major axis (km) ",
78 | "h = e sin(periapsis longitude)",
79 | "k = e cos(periapsis longitude)",
80 | "l = mean longitude (deg) ",
81 | "p = tan(i/2) sin(node) ",
82 | "q = tan(i/2) cos(node) ",
83 | "apsis rate (deg/sec) ",
84 | "mean motion (deg/sec) ",
85 | "node rate (deg/sec) " };
86 |
87 | if( field_no == 4 || field_no == 7 || field_no == 8 || field_no == 9)
88 | strcat( tptr, " * PI / 180.");
89 | strcat( tptr, ",");
90 | printf( " %-38s/* %s*/\n", tptr,
91 | comment[atoi( buff + 9)]);
92 | }
93 | if( !memcmp( buff, " CTRRA", 7))
94 | {
95 | strcat( tptr, " * PI / 180.,");
96 | printf( " %-38s/* Laplacian plane pole ra (deg) */\n", tptr);
97 | }
98 | if( !memcmp( buff, " CTRDEC", 8))
99 | {
100 | strcat( tptr, " * PI / 180. },");
101 | printf( " %-38s/* Laplacian plane pole dec (deg)*/\n", tptr);
102 | }
103 | }
104 | fclose( ifile);
105 | return( 0);
106 | }
107 |
--------------------------------------------------------------------------------
/vsopson.cpp:
--------------------------------------------------------------------------------
1 | /* vsopson.cpp: functions for medium-precision planetary coordinates
2 |
3 | Copyright (C) 2010, Project Pluto
4 |
5 | This program is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU General Public License
7 | as published by the Free Software Foundation; either version 2
8 | of the License, or (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 | 02110-1301, USA. */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include "watdefs.h"
25 | #include "lunar.h"
26 | #include "get_bin.h"
27 |
28 | #define PI 3.1415926535897932384626433832795028841971693993751058209749445923
29 | #define TWO_PI (PI + PI)
30 |
31 | /* This function, given a pointer to a buffer containing the data from
32 | VSOP.BIN, can compute planetary positions in heliocentric ecliptic
33 | coordinates. 'planet' can run from 0=sun, 1=mercury, ... 8=neptune.
34 | (VSOP doesn't handle the moon or Pluto.) 'value' can be either
35 | 0=ecliptic longitude, 1=ecliptic latitude, 2=distance from sun.
36 | (These are ecliptic coordinates _of date_, by the way!)
37 |
38 | t = (JD - 2451545.) / 36525. = difference from J2000, in Julian
39 | centuries. 'prec' ('precision') can be used to tell the code to ignore
40 | small terms in the VSOP expansion. Once upon a time, when math
41 | coprocessors were rare, I occasionally made use of this fact. Nowadays,
42 | almost all my code sets prec=0 (i.e., include all terms.)
43 |
44 | This function relies on direct reading of binary data. See
45 | 'get_bin.h' for details on this. */
46 |
47 | double DLL_FUNC calc_vsop_loc( const void FAR *data, const int planet,
48 | const int value, double t, double prec)
49 | {
50 | int16_t FAR *loc;
51 | int i, j;
52 | double sum, rval = 0., power = 1.;
53 | double FAR *tptr;
54 |
55 | if( !planet)
56 | return( 0.); /* the sun */
57 |
58 | assert( planet > 0 && planet < 9);
59 | assert( value >= 0 && value <= 2);
60 | assert( data); /* now check VSOP data is correct */
61 | assert( ((char *)data)[2] == '&'); /* verify a few bytes at random */
62 | assert( ((char *)data)[20] == 'x');
63 | assert( ((char *)data)[0xea0a] == 'q');
64 | assert( get16bits( (char *)data + 0x10c) == 0x93e);
65 | t /= 10.; /* convert to julian millennia */
66 | loc = (int16_t FAR *)data + (planet - 1) * 18 + value * 6;
67 | for( i = 6; i; i--, loc++)
68 | {
69 | const int16_t loc0 = get16bits( loc);
70 | const int16_t loc1 = get16bits( loc + 1);
71 |
72 | assert( loc0 >= 0);
73 | assert( loc1 >= loc0);
74 | assert( loc1 <= 0x97e);
75 | sum = 0.;
76 | if( prec < 0.)
77 | prec = -prec;
78 | tptr = (double FAR *)((int16_t FAR *)data + 8 * 18 + 1) + loc0 * 3U;
79 |
80 | for( j = loc1 - loc0; j; j--, tptr += 3)
81 | {
82 | const double amplitude = get_double( tptr);
83 |
84 | if( amplitude > prec || amplitude < -prec)
85 | {
86 | const double argument =
87 | get_double( tptr + 1) + get_double( tptr + 2) * t;
88 |
89 | sum += amplitude * cos( argument);
90 | }
91 | }
92 | rval += sum * power;
93 | power *= t;
94 | if( t != 0.)
95 | prec /= t;
96 | }
97 |
98 | if( ((char FAR *)data)[2] == 38)
99 | rval *= 1.e-8;
100 | if( value == 0) /* ensure 0 < lon < 2 * pi */
101 | {
102 | rval = fmod( rval, TWO_PI);
103 | if( rval < 0.)
104 | rval += TWO_PI;
105 | }
106 | return( rval);
107 | }
108 |
109 |
--------------------------------------------------------------------------------
/get_out.txt:
--------------------------------------------------------------------------------
1 | ; Test cases for 'get_time':
2 | format 6 (day/month/year: 0009-aug-07)
3 | 1 Sep 2009 0:00:00.000 0 se 2009
4 | 7 Oct 2009 0:00:00.000 0 7 oct
5 | 29 Dec 2009 0:00:00.000 0 12 29
6 | 28 Nov 2009 0:00:00.000 0 28 11
7 | 28 Oct 1912 0:00:00.000 0 oct 1912
8 | 7 Dec 1941 3:14:00.000 0 7 dec 1941 3:14
9 | 22 Nov 1963 18:19:22.000 0 22 1963 nov18:19:22
10 | 25 Dec 2008 18:19:22.000 0 081225 :
11 | 4 Jul 1776 12:00:00.000 0 17760704 12:00
12 | 1 Jan 2000 12:00:00.000 1 2451545
13 | 1 Nov 2008 0:00:00.000 0 2008 n
14 | 11 Sep 2001 0:00:00.000 0 se 11 2001
15 | 10 Sep 2001 21:00:00.000 0 -3h
16 | 15 Sep 2001 21:00:00.000 0 +5d
17 | 15 Sep 2001 17:00:00.000 0 17:
18 | 15 Sep 2001 17:07:00.000 0 :7
19 | 19 Feb 2008 6:00:00.000 0 2008/50.25
20 | 19 Dec 2008 6:00:00.000 0 d :
21 | 19 Dec 2008 3:14:15.926 0 3:14:15.92653
22 | 2 Dec -443 0:00:00.000 0 -443 2 12
23 | 6 May 1997 12:30:23.334 0 1997.06.05 12:30:23.3348
24 | 9 Oct -414 10:33:00.000 0 BC 415o9 12:33 -2h
25 | 3 Feb 2100 3:14:00.000 0 21000203 03:14
26 | 25 Feb 1965 16:00:00.000 0 650225 16:00
27 | 25 Feb 1965 3:14:15.900 0 3:14:15.9
28 | 11 Feb 1965 3:14:15.900 0 11/2 :
29 | 12 Mar 1965 0:00:00.000 0 12 3
30 | 11 Feb 1965 6:00:00.000 0 11.25-2
31 | 13 Mar 1965 9:36:00.000 0 3-13.4
32 | 1 Jan 2000 12:00:00.000 1 j2451545
33 | 1 Apr 2000 12:00:00.000 0 Ap :
34 | 18 Jun 2004 0:00:00.000 0 6/18/2004
35 | 18 Jun 2004 0:17:12.300 0 :17:12.3
36 | 1 Jan 2000 12:00:00.000 1 JD 2451545.
37 | 14 Mar 2008 15:26:53.500 0 2008-03-14T15:26:53.5
38 | 6 Jul 1998 0:00:00.000 1 mjd 51000
39 | 19 Feb 2008 3:14:09.540 0 50 2008 3:14.159
40 | 4 May 1952 4:26:24.000 0 y1952.34
41 | 19 Feb 2008 18:00:00.000 0 50.75 2008
42 | 4 May 1952 4:26:24.000 0 1952.34
43 | 4 May 1952 4:08:24.000 0 :8.4
44 | 13 May 1952 10:08:24.000 0 +9.25
45 | format 806 (year/day/month: following should be 0003-may-4, jun-7)
46 | 4 May 3 0:00:00.000 0 3 4 5
47 | 7 Jun 3 0:00:00.000 0 7 6
48 | format 1806 (year/month/day: following should be 0001-feb-6, sep-11)
49 | 6 Feb 1 0:00:00.000 0 1.2.6
50 | 11 Sep 1 0:00:00.000 0 9 11
51 | format 6 (day/month/year: 0009-aug-07)
52 | 7 Aug 9 0:00:00.000 0 7 8 9
53 | format 1006 (month/day/year: 0012-oct-11)
54 | 11 Oct 12 0:00:00.000 0 10 11 12
55 | 15 Feb 2008 0:00:00.000 0 15 2 2008
56 | 16 Mar 2009 0:00:00.000 0 3 16 2009
57 | 4 Jul -10 0:00:00.000 0 7 4 bc11
58 | 15 Feb 2008 4:00:00.000 0 2008.15.2 4:
59 | 16 Jul 2009 0:00:00.000 0 2009 7 16
60 | ; If a field has a decimal point in it, it should be recognized as a day:
61 | 3 Apr 1941 4:48:00.000 0 1941 4 3.2
62 | 5 Oct 2009 12:00:00.000 0 5.5 10 2009
63 | 6 Aug 2002 6:00:00.000 0 2002-6.25-8
64 | 1 Apr 1997 7:12:00.000 0 1.3 1997 4
65 | ; Next line _should_ change between runs...
66 | 26 Feb 2024 19:37:49.000 0 now-4d
67 | ; ...but nothing else should!
68 | 5 Oct 2015 9:36:00.000 0 10/5.4/2015
69 | 7 Mar 1917 18:00:00.000 0 3 1917 7.75
70 | 9 May 1917 3:00:00.000 0 9.125 5
71 | 7 Feb 1917 6:00:00.000 0 2 7.25
72 | ; find time three days before new moon...
73 | 18 Feb 1917 18:08:14.187 1 nm-3d
74 | 3 Oct -1456 12:34:00.000 0 1457 oct 3 BC 12:34
75 | ; Start from 2011 dec 13, back up four weeks, find the time of the
76 | ; nearest Third Quarter phase, then add two days:
77 | 20 Nov 2011 15:09:17.518 1 2011 dec 13 -4w 3Q +2d
78 | ; Similar efforts:
79 | 24 Dec 1842 23:59:39.702 1 15o1843-300d1q+16d-22.43h
80 | 1 Mar 1843 6:00:07.258 1 +60d nm
81 | 1 Mar 1843 3:00:00.000 0 1q 3:00
82 | 1 Mar 1843 16:56:07.000 0 4:56:07 p.m.
83 | 4 May 37 16:10:00.000 0 5 4 37 6:10 pm -2h
84 | 3 Aug 37 3:01:00.000 0 8/3 3:01 A.M.
85 | 14 Sep 37 12:17:00.000 0 14/9 12:17 pm
86 | 11 Sep 37 0:51:00.000 0 s11 12:51am
87 | 1 Oct 2009 21:41:23.800 0 2009-10-01T21:41:23.8
88 | format 6 (day/month/year: 0009-aug-07)
89 | 4 Mar 1997 3:14:16.000 0 1997-03-04T03:14:16
90 | ; Added 2019 Jul 21 :
91 | 21 Jul 2069 0:37:33.000 0 unix3141592653
92 | 24 Jul 2019 13:14:12.000 0 gps20633+13h+14.2m
93 | ; Added 2024 Mar 01 : the following should cause errores to be returned
94 | 28 Jan 2019 0:00:00.000 -4 z28
95 | 3 Jan 2021 17:00:00.000 -5 3Ock2021 17:00
96 | 21 Jan 2022 0:00:00.000 -5 2022 Maz 21
97 | 15 Jan 2022 3:17:00.000 -6 Jan 15 z 3:17
98 |
--------------------------------------------------------------------------------
/lunar.h:
--------------------------------------------------------------------------------
1 | /* lunar.h: header file for basic astrometric functions
2 | Copyright (C) 2010, Project Pluto
3 |
4 | This program is free software; you can redistribute it and/or
5 | modify it under the terms of the GNU General Public License
6 | as published by the Free Software Foundation; either version 2
7 | of the License, or (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 | 02110-1301, USA. */
18 |
19 | #ifndef LUNAR_H_INCLUDED
20 | #define LUNAR_H_INCLUDED
21 |
22 | #define N_FUND 9
23 |
24 | #ifdef __cplusplus
25 | extern "C" {
26 | #endif
27 |
28 | #ifndef AU_IN_KM
29 | #define AU_IN_KM 1.495978707e+8
30 | #endif
31 |
32 | #ifndef AU_IN_METERS
33 | #define AU_IN_METERS (AU_IN_KM * 1000.)
34 | #endif
35 |
36 | #ifndef SPEED_OF_LIGHT
37 | #define SPEED_OF_LIGHT 299792.458
38 | #endif
39 |
40 | #ifndef AU_PER_DAY
41 | #define AU_PER_DAY (86400. * SPEED_OF_LIGHT / AU_IN_KM)
42 | #endif
43 |
44 | double DLL_FUNC lunar_lat( const void FAR *data, const double DLLPTR *fund,
45 | const long precision);
46 | int DLL_FUNC lunar_lon_and_dist( const void FAR *data, const double DLLPTR *fund,
47 | double DLLPTR *lon, double DLLPTR *r, const long precision);
48 |
49 | int DLL_FUNC unload_ps1996_series( void *p);
50 | int DLL_FUNC get_ps1996_position( const double jd, const void *iptr,
51 | double *state_vect, const int compute_velocity);
52 | #ifdef SEEK_CUR
53 | void * DLL_FUNC load_ps1996_series( FILE *ifile, double jd, int planet_no);
54 | int DLL_FUNC compute_elp_xyz( FILE *ifile, const double t_cen, const double prec,
55 | double *ecliptic_xyz_2000);
56 | int DLL_FUNC calc_big_vsop_loc( FILE *ifile, const int planet,
57 | double *ovals, double t, const double prec0);
58 | #endif
59 |
60 | int DLL_FUNC lunar_fundamentals( const void FAR *data, const double t,
61 | double DLLPTR *fund);
62 | long double DLL_FUNC find_nearest_lunar_phase_time(
63 | const int phase_idx, const long double t2k);
64 | double DLL_FUNC mean_obliquity( const double t_cen);
65 | int DLL_FUNC calc_pluto_loc( const void FAR *data, double DLLPTR *loc,
66 | const double t, const long precision);
67 | int DLL_FUNC calc_jsat_loc( const double jd, double DLLPTR *jsats,
68 | const int sats_wanted, const long precision);
69 | int DLL_FUNC calc_ssat_loc( const double t, double DLLPTR *ssat,
70 | const int sat_wanted, const long precision);
71 | void DLL_FUNC calc_triton_loc( const double jd, double *vect);
72 | double DLL_FUNC calc_vsop_loc( const void FAR *data, const int planet,
73 | const int value, double t, double prec);
74 | int DLL_FUNC nutation( const double t, double DLLPTR *d_lon,
75 | double DLLPTR *d_obliq);
76 | int DLL_FUNC compute_planet( const char FAR *vsop_data, const int planet_no,
77 | const double t_c, double DLLPTR *ovals);
78 | int DLL_FUNC calc_planet_orientation( const int planet_no, const int system_no,
79 | const double jd, double *matrix);
80 | int DLL_FUNC planet_radii( const int planet_no, double *radii_in_km);
81 | double DLL_FUNC planet_rotation_rate( const int planet_no, const int system_no);
82 | int DLL_FUNC load_cospar_file( const char *filename);
83 | int DLL_FUNC evaluate_rock( const double jd, const int jpl_id,
84 | double *output_vect);
85 | double planet_radius_in_meters( const int planet_idx); /* mpc_code.cpp */
86 | double planet_axis_ratio( const int planet_idx); /* mpc_code.cpp */
87 |
88 | #ifdef __cplusplus
89 | }
90 | #endif
91 |
92 | #endif /* #ifndef LUNAR_H_INCLUDED */
93 |
--------------------------------------------------------------------------------
/mpcorb2.cpp:
--------------------------------------------------------------------------------
1 | /* mpcorb2.cpp: functions to get basic data on 'mpcorb.dat' files
2 | (Not really very relevant to anything, as it's turned out!)
3 |
4 | Copyright (C) 2010, Project Pluto
5 |
6 | This program is free software; you can redistribute it and/or
7 | modify it under the terms of the GNU General Public License
8 | as published by the Free Software Foundation; either version 2
9 | of the License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program; if not, write to the Free Software
18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 | 02110-1301, USA. */
20 |
21 | #include
22 | #include
23 |
24 | /* 'mpcorb.dat' files have some oddities that complicate automated
25 | handling. Each file has a dozen or so lines of "header" data.
26 | Following are a few hundred thousand lines of numbered objects,
27 | with each line being 203 bytes long (202 bytes of actual data
28 | plus a line-feed terminator).
29 |
30 | Then an additional line-feed is inserted, followed by more lines
31 | for unnumbered multi-opposition objects, plus another line-feed and
32 | more lines for single-opposition objects (all unnumbered). Hence,
33 | you can't just seek to (header_size + 203 * record_number) and
34 | read 202 bytes. Well, you can do that for numbered objects...
35 | but for unnumbered multi-opp ones, you need to go an additional
36 | byte, to account for that !*#% line feed; and for single-opp
37 | data, you need to go yet another byte. So knowing ahead of time
38 | the header length and how many objects there are of each type
39 | could be useful.
40 |
41 | As it turned out, I never actually needed the following (I worked
42 | away around the need). So it's not as thoroughly tested as it might be.
43 | User beware.
44 |
45 | data[0] = header length, in bytes;
46 | data[1] = number of numbered asteroids / start of multi-opps;
47 | data[2] = start of single-opp objects;
48 | data[3] = total number of objects */
49 |
50 | #define MPCORB_RECLEN 203
51 |
52 | int get_mpcorb_info( FILE *ifile, long *data)
53 | {
54 | char buff[210];
55 | int lines_read = 0, i;
56 |
57 | fseek( ifile, 0L, SEEK_SET);
58 | data[0] = 0; /* assume no header */
59 | data[1] = data[2] = data[3] = 0;
60 | while( lines_read < 50 && fgets( buff, sizeof( buff), ifile))
61 | {
62 | lines_read++;
63 | if( *buff == '-') /* we've read the entire header */
64 | {
65 | lines_read = 1000;
66 | data[0] = ftell( ifile);
67 | }
68 | }
69 | fseek( ifile, 0L, SEEK_END);
70 | data[3] = (ftell( ifile) - data[0]) / MPCORB_RECLEN;
71 | for( i = 1; i <= 3; i++)
72 | {
73 | long step, loc1;
74 |
75 | for( step = 0x800000; step; step >>= 1)
76 | {
77 | loc1 = data[i] + step;
78 | if( !fseek( ifile, data[0] + loc1 * MPCORB_RECLEN, SEEK_SET))
79 | if( fread( buff, 10, 1, ifile))
80 | {
81 | if( buff[0] == 10 && loc1 > data[2])
82 | data[2] = loc1;
83 | else if( buff[0] != 10 && buff[1] != 10 && loc1 > data[1])
84 | data[1] = loc1;
85 | }
86 | }
87 | }
88 | data[1]++;
89 | return( 0);
90 | }
91 |
92 | int main( const int argc, const char **argv)
93 | {
94 | FILE *ifile = fopen( "mpcorb.dat", "rb");
95 | long data[4];
96 | char tbuff[80];
97 |
98 | if( ifile)
99 | {
100 | get_mpcorb_info( ifile, data);
101 | printf( "%ld %ld %ld %ld\n", data[0], data[1], data[2], data[3]);
102 | }
103 | else
104 | printf( "mpcorb.dat not opened\n");
105 | if( argc > 1)
106 | {
107 | long rec_num = atol( argv[1]);
108 | long offset = data[0] + rec_num * MPCORB_RECLEN;
109 |
110 | if( rec_num >= data[2])
111 | offset += 2;
112 | else if( rec_num >= data[1])
113 | offset++;
114 | fseek( ifile, offset, SEEK_SET);
115 | fread( tbuff, 80, 1, ifile);
116 | tbuff[79] = '\0';
117 | printf( "%s", tbuff);
118 | }
119 | return( 0);
120 | }
121 |
--------------------------------------------------------------------------------
/superga2.cpp:
--------------------------------------------------------------------------------
1 | /* superga2.cpp: code to compute a supergalactic-to-J2000 matrix
2 |
3 | Copyright (C) 2010, Project Pluto
4 |
5 | This program is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU General Public License
7 | as published by the Free Software Foundation; either version 2
8 | of the License, or (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 | 02110-1301, USA. */
19 | #include
20 | #include
21 |
22 | /* Running the following code produces a J2000 to supergalactic
23 | coordinate matrix, which looks as follows:
24 |
25 | 0.37501548 0.34135896 0.86188018
26 | -0.89832046 -0.09572714 0.42878511
27 | 0.22887497 -0.93504565 0.27075058
28 |
29 | Written in reply to an inquiry from Christopher Watson; see
30 |
31 | https://groups.io/g/amastro/message/13921
32 |
33 | The code in 'supergal.cpp' gets a similar result, using equatorial values
34 | for the position of the supergalactic plane. However, the RA/dec values
35 | given are not exact (given to one-second precision, or 15-arcsec precision,
36 | in RA.) This method ought to be "exact".
37 |
38 | At the end, it gives the coordinates for the SG north pole and zero
39 | point in J2000 to full precision, in decimal and base-60, as
40 |
41 | 2.82067484 02h 49m 14.4294s (RA of zero point, SGL = SGB = 0)
42 | 59.52834978 +59 31' 42.0592" (dec of zero point, SGL = SGB = 0)
43 | 18.91693936 18h 55m 0.9817s (RA of SG north pole, SGB = 90)
44 | 15.70893553 +15 42' 32.1679" (dec of SG north pole)
45 | */
46 |
47 | #define PI 3.1415926535897932384626433832795028841971693993751058209749445923
48 | #define NORTH_POLE_LAT (6.32 * PI / 180.)
49 | #define NORTH_POLE_LON (47.37 * PI / 180.)
50 | #define ZERO_POINT_LON (137.37 * PI / 180.)
51 |
52 | /* The following matrix comes from _The Hipparcos & Tycho */
53 | /* Catalogues: Introduction & Guide to the Data_, p 92: */
54 | static const double galactic_to_j2000[9] = {
55 | -.0548755604, -.8734370902, -.4838350155,
56 | .4941094279, -.4448296300, .7469822445,
57 | -.8676661490, -.1980763734, .4559837762 };
58 |
59 | int main( const int unused_argc, const char **unused_argv)
60 | {
61 | double matrix[9], rotation[9];
62 | int i, j;
63 |
64 | /* vector pointing toward (supergalactic) lat=lon=0: */
65 | rotation[0] = cos( ZERO_POINT_LON);
66 | rotation[1] = sin( ZERO_POINT_LON);
67 | rotation[2] = 0.;
68 |
69 | /* vector pointing toward the north supergalactic pole: */
70 | rotation[6] = cos( NORTH_POLE_LON) * cos( NORTH_POLE_LAT);
71 | rotation[7] = sin( NORTH_POLE_LON) * cos( NORTH_POLE_LAT);
72 | rotation[8] = sin( NORTH_POLE_LAT);
73 |
74 | rotation[3] = -cos( NORTH_POLE_LON) * sin( NORTH_POLE_LAT);
75 | rotation[4] = -sin( NORTH_POLE_LON) * sin( NORTH_POLE_LAT);
76 | rotation[5] = cos( NORTH_POLE_LAT);
77 |
78 | for( i = 0; i < 3; i++)
79 | for( j = 0; j < 3; j++)
80 | matrix[j + i * 3] =
81 | rotation[i * 3] * galactic_to_j2000[j]
82 | + rotation[i * 3 + 1] * galactic_to_j2000[j + 3]
83 | + rotation[i * 3 + 2] * galactic_to_j2000[j + 6];
84 |
85 | printf( "%11.8lf %11.8lf %11.8lf\n", matrix[0], matrix[1], matrix[2]);
86 | printf( "%11.8lf %11.8lf %11.8lf\n", matrix[3], matrix[4], matrix[5]);
87 | printf( "%11.8lf %11.8lf %11.8lf\n", matrix[6], matrix[7], matrix[8]);
88 | printf( "\n");
89 |
90 | for( i = 0; i < 4; i++)
91 | {
92 | double oval, tval, sec;
93 | int deg, min;
94 |
95 | j = (i / 2) * 6;
96 | if( i % 2 == 0)
97 | oval = atan2( -matrix[j + 1], -matrix[j]) * 12. / PI + 12.;
98 | else
99 | oval = asin( matrix[j + 2]) * 180. / PI;
100 | deg = (int)oval;
101 | tval = (oval - (double)deg) * 60.;
102 | min = (int)tval;
103 | sec = (tval - (double)min) * 60.;
104 | printf( "%12.8lf %02d %02d %7.4lf\n", oval, deg, min, sec);
105 | }
106 | return( 0);
107 | }
108 |
--------------------------------------------------------------------------------
/big_vsop.txt:
--------------------------------------------------------------------------------
1 | Hi Mark,
2 |
3 | Following is "documentation", of a sort, for 'big_vsop.bin'
4 | and 'big_vsop.cpp'. I'll incorporate it into the latter at some
5 | point. The opening paragraphs are probably old news to you,
6 | but... here goes:
7 |
8 | BE WARNED that for many purposes, rather than using VSOP (in
9 | either its short or long forms), it's well to use either the
10 | PS-1996 series or DE ephemerides. Source code for both is
11 | available from my site.
12 |
13 | VSOP is based on the now-obsolete DE-200 ephemeris, doesn't
14 | include the moon or Pluto, and requires summing up a staggering
15 | number of terms to get full accuracy. Use of DE ephemerides or
16 | PS-1996 is much faster and more accurate.
17 |
18 | On the plus side, VSOP covers millennia into the past and
19 | future (PS-1996 only covers about a century or so into the past
20 | and future, depending on the planet in question), and can be
21 | packed into a small file size (the full DE ephemerides can
22 | consume up to 200 MBytes). You can sum up just a few VSOP terms
23 | and get results good to an arcminute or so, ample for
24 | low-precision uses.
25 |
26 | In both 'big_vsop.bin' and 'vsop.bin', for each of the eight
27 | planets (Mercury through Neptune), data is provided in the
28 | "usual" VSOP form, as a Poisson series (a mix of a Fourier-like
29 | series of trig terms and a Taylor-like power series.) Thus, for
30 | example, the ecliptic latitude of a planet would be computed as
31 |
32 | latitude = (sum of trig terms0)
33 | + (sum of trig terms1) * t
34 | + (sum of trig terms2) * t^2
35 | + (sum of trig terms3) * t^3
36 | + (sum of trig terms4) * t^4
37 | + (sum of trig terms5) * t^5
38 |
39 | ...with similar series given for ecliptic longitude and heliocentric
40 | radius.
41 |
42 | 't' = (jd - 2541545.0) / 365250, the difference in millennia
43 | between the time in question and 1.5 January 2000. The 'trig terms'
44 | are all of the form amplitude * cos( angle + rate * t). Almost all of
45 | 'big_vsop.bin' consists of the values for 'amplitude', 'angle' and
46 | 'rate', with a small header describing just where the 'amplitude',
47 | 'angle' and 'rate' data for a given series begins and ends.
48 |
49 | As you can see, each value requires summing up six series, then
50 | multiplying by some integer power of t. We've got six series per
51 | value, three values per planet, and eight planets... therefore,
52 | 6 * 3 * 8 = 144 series. Any given planet requires 18 series.
53 |
54 | The 'big_vsop' header could, in theory, give you the starting
55 | and ending location of each series, as short integer values. You'd
56 | then have 144 * 2, or 288, values in the header. In reality, all
57 | I did was store the beginning of each series; you figure out where
58 | it ends by looking at the beginning of the next series. That brings
59 | us down to 145 values in the header (the last value giving you where
60 | the final series actually ends.)
61 |
62 | Since each header entry is a short int, we're looking at 290 bytes.
63 |
64 | In a possibly misguided effort to save space (well, it _did_ make
65 | lots of sense back in 1993!), I store the header data needed for
66 | one particular planet in RAM at a given time. If someone asks for
67 | a "new planet" (in big_vsop.cpp, 'if( curr_planet != planet)'),
68 | then we dig through 'big_vsop.bin' for the required header data
69 | and store it in a static array. That requirement is for nineteen
70 | short (16-bit) integers: there are three values to be computed
71 | (lat/lon/r) and six series for each of them (1, t, t^2, ...t^5),
72 | and we need to know where the last of them ends. So the static
73 | array 'cache' is dimensioned for 19 shorts.
74 |
75 | We then use that data stored in 'cache' to go forth and grab
76 | VSOP data. For longitude, the coefficients for the (1, t, ...t^5)
77 | series are stored at offsets indicated by cache[0], cache[1], ...
78 | cache[5], with the latter ending at cache[6] (that is, the t^5
79 | series would have cache[6]-cache[5] terms.) For latitude,
80 | the coefficients would be at offsets indicated by cache[6...11],
81 | and for heliocentric radius, cache[12...17], with the last
82 | t^5 term having cache[18]-cache[17] terms.
83 |
84 | The actual file offset, in bytes, is going to be 24 bytes
85 | per term (each term consumes three double-precision floats) plus
86 | the 290 bytes for the header. That's why the actual 'fseek' call
87 | in 'big_vsop.cpp' reads as
88 |
89 | fseek( ifile, 290L + (long)loc[0] * 24L, SEEK_SET);
90 |
91 | -- Bill
92 |
--------------------------------------------------------------------------------
/nanosecs.cpp:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2018, Project Pluto
2 |
3 | This program is free software; you can redistribute it and/or
4 | modify it under the terms of the GNU General Public License
5 | as published by the Free Software Foundation; either version 2
6 | of the License, or (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 | 02110-1301, USA. */
17 |
18 | /* 'nanoseconds_since_1970( )' returns something close to the result of
19 | ctime( ), except a billion times larger and with added precision.
20 | Naturally, DOS/Windows, OS/X, and POSIX systems each use different
21 | methods.
22 |
23 | As currently coded, the actual precision provided is 10^-7 second
24 | in Windows; a millisecond with the WATCOM compiler; and 10^-6 second
25 | in everything else. But note that "true" nanosecond precision is
26 | possible, if actually desired (see the NOT_CURRENTLY_IN_USE code).
27 |
28 | The range of a 64-bit signed integer is large enough to enable
29 | this function to work until Friday, 2262 Apr 11 23:47:16.854775808.
30 | We can get an addition 292 years by using unsigned integers, but
31 | it may be wiser to switch to 128-bit integers.
32 |
33 | Note that the usual limitations apply: no leap seconds, and if
34 | the computer's time is adjusted by NTP or the user, the result may
35 | actually go backward. If you want to know what time it is, don't
36 | ask a computer. */
37 |
38 | #ifdef _WIN32
39 | #include
40 | #endif
41 |
42 | #ifdef __WATCOMC__
43 | #include
44 | #endif
45 |
46 | #include
47 | #include "watdefs.h"
48 | #include "afuncs.h"
49 |
50 | int64_t DLL_FUNC nanoseconds_since_1970( void); /* afuncs.c */
51 |
52 | #ifdef _WIN32
53 |
54 | int64_t DLL_FUNC nanoseconds_since_1970( void)
55 | {
56 | FILETIME ft;
57 | const uint64_t jd_1601 = 2305813; /* actually 2305813.5 */
58 | const uint64_t jd_1970 = 2440587; /* actually 2440587.5 */
59 | const uint64_t ten_million = 10000000;
60 | const uint64_t diff = (jd_1970 - jd_1601) * ten_million * (uint64_t)seconds_per_day;
61 | uint64_t decimicroseconds_since_1970; /* i.e., time in units of 1e-7 seconds */
62 |
63 | GetSystemTimeAsFileTime( &ft);
64 | decimicroseconds_since_1970 = ((uint64_t)ft.dwLowDateTime |
65 | ((uint64_t)ft.dwHighDateTime << 32)) - diff;
66 | return( decimicroseconds_since_1970 * (int64_t)100);
67 | }
68 | #else
69 | #ifdef __WATCOMC__
70 | int64_t DLL_FUNC nanoseconds_since_1970( void)
71 | {
72 | struct timeb t;
73 | const int64_t one_million = 1000000;
74 | int64_t millisec;
75 |
76 | ftime( &t);
77 | millisec = (int64_t)t.millitm + (int64_t)1000 * (int64_t)t.time;
78 | return( millisec * (int64_t)one_million);
79 | }
80 | #else /* OS/X, BSD, and Linux */
81 | #include
82 | #include
83 |
84 | int64_t DLL_FUNC nanoseconds_since_1970( void)
85 | {
86 | struct timeval now;
87 | const int rv = gettimeofday( &now, NULL);
88 | int64_t rval;
89 | const int64_t one_billion = (int64_t)1000000000;
90 |
91 | if( !rv)
92 | rval = (int64_t)now.tv_sec * one_billion
93 | + (int64_t)now.tv_usec * (int64_t)1000;
94 | else
95 | rval = 0;
96 | return( rval);
97 | }
98 | #endif
99 | #endif
100 |
101 | /* At one time, I was using the following in Linux. It gives a
102 | "real" precision of nanoseconds, instead of getting microseconds
103 | and multiplying by 1000 (or decimicroseconds and multiplying by 100).
104 | However, it does require the realtime library to be linked in...
105 | I leave it here in case we someday need nanosecond precision. */
106 |
107 | #ifdef NOT_CURRENTLY_IN_USE
108 | int64_t DLL_FUNC nanoseconds_since_1970( void)
109 | {
110 | struct timespec t;
111 |
112 | clock_gettime( CLOCK_REALTIME, &t);
113 | return( t.tv_sec * (int64_t)1000000000 + t.tv_nsec);
114 | }
115 | #endif /* NOT_CURRENTLY_IN_USE */
116 |
117 | double DLL_FUNC current_jd( void)
118 | {
119 | static const double jan_1970 = 2440587.5;
120 | const double jd = jan_1970 +
121 | (double)nanoseconds_since_1970( ) * 1e-9 / seconds_per_day;
122 |
123 | return( jd);
124 | }
125 |
--------------------------------------------------------------------------------
/jsattest.cpp:
--------------------------------------------------------------------------------
1 | /* jsats.cpp: functions for Galilean satellite posns
2 |
3 | Copyright (C) 2010, Project Pluto
4 |
5 | This program is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU General Public License
7 | as published by the Free Software Foundation; either version 2
8 | of the License, or (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 | 02110-1301, USA. */
19 |
20 | /* NOTE that 'ssattest' now provides testing of Galilean satellite
21 | ephems, as well as Saturnian satellite ephems. The following
22 | program is not entirely obsolete, but it's close to it.
23 |
24 | A little test program I wrote to test out my implementation of Lieske's E5
25 | theory of the Galilean satellites, as written in 'jsats.cpp'. It works by
26 | reading in an ASCII ephemeris of Jovicentric vectors for a given satellite,
27 | computing the position for that satellite at that time using E5, and showing
28 | the difference, both as an absolute XYZ in J2000 ecliptic coordinates and
29 | in terms of "along-track" and "radial" components. The latter allowed me to
30 | see a long-term quadratic drift for Ganymede and Callisto. (They were in
31 | opposite directions, so I'm confident that it's not a situation where I've
32 | got the whole system rotating somehow. My guess is that the mean longitudes
33 | for those satellites should include a small quadratic term, instead of
34 | being just linear functions of time.) */
35 |
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include "watdefs.h"
42 | #include "lunar.h"
43 | #include "afuncs.h"
44 |
45 | #define JRADIUS_IN_KM 71418.0
46 | // #define JRADIUS_IN_KM 71406.0
47 |
48 | int main( const int argc, const char **argv)
49 | {
50 | char buff[100];
51 | FILE *ifile;
52 | time_t t0 = time( NULL);
53 | const int sat_number = (argc == 2 ? atoi( argv[1]) : 0);
54 |
55 | if( sat_number < 1 || sat_number > 4)
56 | {
57 | printf( "'jsattest' needs a command-line argument from 1 to 4,\n");
58 | printf( "corresponding to the number of the Galilean satellite\n");
59 | printf( "that is being tested.\n");
60 | return( -1);
61 | }
62 | snprintf( buff, 7, "j%s.txt", argv[1]);
63 | ifile = fopen( buff, "rb");
64 | if( !ifile)
65 | {
66 | printf( "%s not opened\n", buff);
67 | return( -1);
68 | }
69 | printf( "All data in kilometers, in J2000 ecliptic coords\n");
70 | printf( "Compiled %s %s; run %.24s\n", __DATE__, __TIME__, asctime( gmtime( &t0)));
71 | printf( " JDE dx dy dz ");
72 | printf( "x y z radial along\n");
73 | while( fgets( buff, sizeof( buff), ifile))
74 | if( strlen( buff) > 56 && !memcmp( buff + 37, "00:00:00.0000 (CT)", 18))
75 | {
76 | const double jd = atof( buff );
77 | double loc[15], *tptr = loc + (sat_number - 1) * 3;
78 | double precess_matrix[9];
79 | double j2000_loc[3], x, y, z, r;
80 |
81 | if( !fgets( buff, sizeof( buff), ifile))
82 | {
83 | printf( "Read error");
84 | return( -2);
85 | }
86 | x = atof( buff);
87 | y = atof( buff + 24);
88 | z = atof( buff + 47);
89 | setup_ecliptic_precession( precess_matrix, 2000. + (jd - 2451545.) / 365., 2000.);
90 | calc_jsat_loc( jd, loc, 15, 0L);
91 | precess_vector( precess_matrix, tptr, j2000_loc);
92 | j2000_loc[0] *= JRADIUS_IN_KM;
93 | j2000_loc[1] *= JRADIUS_IN_KM;
94 | j2000_loc[2] *= JRADIUS_IN_KM;
95 | j2000_loc[0] -= x;
96 | j2000_loc[1] -= y;
97 | j2000_loc[2] -= z;
98 | r = sqrt( x * x + y * y);
99 | printf( "%10.2f %10.3f%10.3f%10.3f %11.2f%11.2f%11.2f %10.2f %10.2f\n", jd,
100 | j2000_loc[0],
101 | j2000_loc[1],
102 | j2000_loc[2], x, y, z,
103 | (j2000_loc[0] * x + j2000_loc[1] * y) / r,
104 | (j2000_loc[1] * x - j2000_loc[0] * y) / r);
105 | }
106 | fclose( ifile);
107 | return( 0);
108 | }
109 |
--------------------------------------------------------------------------------
/watmake:
--------------------------------------------------------------------------------
1 | # Basic astronomical functions library. Use
2 | # wmake -f watmake
3 | # to build a version that is either 32 or 64 bit;
4 | # and which either builds the library as a DLL or statically
5 |
6 | EXES= astcheck.exe astephem.exe calendar.exe cosptest.exe dist.exe &
7 | easter.exe get_test.exe htc20b.exe jd.exe jevent.exe &
8 | jpl2b32.exe jsattest.exe lun_test.exe marstime.exe oblitest.exe &
9 | persian.exe phases.exe prectest.exe ps_1996.exe &
10 | relativi.exe ssattest.exe tables.exe &
11 | testprec.exe test_ref.exe uranus1.exe utc_test.exe
12 |
13 | all: $(EXES)
14 |
15 | LIB_OBJS= ades2mpc.obj alt_az.obj astfuncs.obj big_vsop.obj &
16 | brentmin.obj cgi_func.obj classel.obj com_file.obj &
17 | conbound.obj &
18 | cospar.obj date.obj de_plan.obj delta_t.obj dist_pa.obj &
19 | eart2000.obj elp82dat.obj eop_prec.obj &
20 | getplane.obj get_time.obj jsats.obj lunar2.obj &
21 | miscell.obj moid.obj mpc_code.obj mpc_fmt.obj &
22 | mpc_fmt2.obj nanosecs.obj &
23 | nutation.obj obliquit.obj pluto.obj precess.obj &
24 | refract.obj refract4.obj rocks.obj showelem.obj sof.obj &
25 | snprintf.obj spline.obj ssats.obj triton.obj &
26 | unpack.obj vislimit.obj vsopson.obj
27 |
28 | LINK=wcl386 -zq -k10000
29 |
30 | BASE_FLAGS=-w4 -oxt -4r -s -j -zq
31 | LIBNAME=wafuncs
32 | RM=-rm
33 |
34 | !ifdef DLL
35 | COMMON_FLAGS = $(BASE_FLAGS) -EHsc -LD -DNDEBUG
36 | !else
37 | COMMON_FLAGS = $(BASE_FLAGS)
38 | !endif
39 |
40 | $(EXES) : $(LIBNAME).lib
41 |
42 | %.exe : %.obj
43 | $(LINK) $< $(LIBNAME).lib
44 |
45 | .cpp.obj:
46 | wcc386 $(COMMON_FLAGS) -za99 $<
47 |
48 | .c.obj:
49 | wcc386 $(COMMON_FLAGS) -za99 $<
50 |
51 | $(LIBNAME).lib : $(LIB_OBJS)
52 | %write wlunar.lrf $(LIB_OBJS)
53 | wlib -q -n -t $@ @wlunar.lrf
54 | $(RM) wlunar.lrf
55 |
56 | clean:
57 | $(RM) *.obj
58 | $(RM) *.exe
59 | $(RM) *.err
60 | $(RM) *.map
61 | $(RM) *.exp
62 | $(RM) $(LIBNAME).lib
63 | $(RM) $(LIBNAME).dll
64 |
65 | astcheck.exe: astcheck.obj eart2000.obj mpcorb.obj $(LIBNAME).lib
66 | $(LINK) astcheck.obj eart2000.obj mpcorb.obj $(LIBNAME).lib
67 |
68 | astephem.exe: astephem.obj eart2000.obj mpcorb.obj $(LIBNAME).lib
69 | $(LINK) astephem.obj eart2000.obj mpcorb.obj $(LIBNAME).lib
70 |
71 | calendar.exe: calendar.obj $(LIBNAME).lib
72 | $(LINK) calendar.obj $(LIBNAME).lib
73 |
74 | cosptest.exe: cosptest.obj $(LIBNAME).lib
75 | $(LINK) cosptest.obj $(LIBNAME).lib
76 |
77 | dist.exe: dist.obj
78 | $(LINK) dist.obj
79 |
80 | easter.exe: easter.cpp
81 | $(LINK) -DTEST_CODE $(BASE_FLAGS) easter.cpp
82 |
83 | get_test.exe: get_test.obj $(LIBNAME).lib
84 | $(LINK) get_test.obj $(LIBNAME).lib
85 |
86 | htc20b.exe: htc20b.cpp
87 | $(LINK) -DTEST_MAIN $(BASE_FLAGS) htc20b.cpp
88 |
89 | jevent.exe: jevent.obj $(LIBNAME).lib
90 | $(LINK) jevent.obj $(LIBNAME).lib
91 |
92 | jd.exe: jd.obj $(LIBNAME).lib
93 | $(LINK) jd.obj $(LIBNAME).lib
94 |
95 | jpl2b32.exe: jpl2b32.obj
96 | $(LINK) jpl2b32.obj
97 |
98 | jsattest.exe: jsattest.obj $(LIBNAME).lib
99 | $(LINK) jsattest.obj $(LIBNAME).lib
100 |
101 | lun_test.exe: lun_test.obj lun_tran.obj riseset3.obj $(LIBNAME).lib
102 | $(LINK) lun_test.obj lun_tran.obj riseset3.obj $(LIBNAME).lib
103 |
104 | marstime.exe: marstime.cpp
105 | $(LINK) -DTEST_PROGRAM $(BASE_FLAGS) marstime.cpp snprintf.obj
106 |
107 | oblitest.exe: oblitest.obj obliqui2.obj spline.obj $(LIBNAME).lib
108 | $(LINK) oblitest.obj obliqui2.obj spline.obj $(LIBNAME).lib
109 |
110 | persian.exe: persian.obj solseqn.obj $(LIBNAME).lib
111 | $(LINK) persian.obj solseqn.obj $(LIBNAME).lib
112 |
113 | phases.exe: phases.obj $(LIBNAME).lib
114 | $(LINK) phases.obj $(LIBNAME).lib
115 |
116 | prectest.exe: prectest.obj $(LIBNAME).lib
117 | $(LINK) prectest.obj $(LIBNAME).lib
118 |
119 | ps_1996.exe: ps_1996.obj $(LIBNAME).lib
120 | $(LINK) ps_1996.obj $(LIBNAME).lib
121 |
122 | relativi.exe: relativi.obj $(LIBNAME).lib
123 | $(LINK) relativi.obj $(LIBNAME).lib
124 |
125 | relativi.obj:
126 | wcc386 $(BASE_FLAGS) -DTEST_CODE relativi.cpp
127 |
128 | ssattest.exe: ssattest.obj $(LIBNAME).lib
129 | $(LINK) ssattest.obj $(LIBNAME).lib
130 |
131 | tables.exe: tables.obj riseset3.obj $(LIBNAME).lib
132 | $(LINK) tables.obj riseset3.obj $(LIBNAME).lib
133 |
134 | testprec.exe: testprec.obj $(LIBNAME).lib
135 | $(LINK) testprec.obj $(LIBNAME).lib
136 |
137 | test_ref.exe: test_ref.obj refract.obj refract4.obj
138 | $(LINK) test_ref.obj refract.obj refract4.obj
139 |
140 | uranus1.exe: uranus1.obj gust86.obj
141 | $(LINK) uranus1.obj gust86.obj
142 |
143 | utc_test.exe: utc_test.obj $(LIBNAME).lib
144 | $(LINK) utc_test.obj $(LIBNAME).lib
145 |
--------------------------------------------------------------------------------
/mpc_time.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include "watdefs.h"
8 | #include "mpc_func.h"
9 | #include "date.h"
10 | #include "afuncs.h"
11 |
12 | /*
13 | The obsID field in ADES starts with eight mutant-hex (base 62)
14 | digits that give the time the observation was received at MPC.
15 | Mike Rudenko pointed me to
16 |
17 | https://minorplanetcenter.net/decode_obsid.py
18 |
19 | from which I learned that :
20 |
21 | The first three digits, when decoded, give the year, month,
22 | and day of submission, packed as
23 |
24 | value(0,1,2) = (year - 1800) * 12 * 31 + (month - 1) * 31 + (day-1)
25 |
26 | The next three digits, when decoded, give
27 |
28 | value(3,5) = seconds since 00:00 UT
29 |
30 | and therefore ranges from 0 to 86399 (MTX in base 62). And
31 | finally, the last two digits give
32 |
33 | value(6,7) = milliseconds
34 |
35 | and is therefore from 0 to 999 (G7 in base 62). Valid times can
36 | run from
37 |
38 | 00000000 = 1800-Jan-01 00:00:00.000
39 | zzzMTXG7 = 2440-Aug-31 23:59:59.999
40 |
41 | unless that day has a leap second (it _is_ at the end of a
42 | month, and we'll be having leap seconds monthly by then, so
43 | that will probably happen.) In that case, the scheme can be
44 | extended by one second :
45 |
46 | zzzMTYG7 = 2440-Aug-31 24:00:00.999
47 |
48 | The need to handle leap second madness may be why MPC went with
49 | this scheme, instead of the straightforward 'milliseconds since
50 | an epoch' one I'd expected.
51 |
52 | Some test cases :
53 |
54 | < Date >sb
55 | K6yCeR0100005WG401000000A 2007-10-30T13:30:35.001_00005WG4_01
56 | LP6CWP340000E5ZY010000QZe 2021-03-07T13:22:17.190_0000E5ZY_01
57 | LQBB0Q8k0000EAnd0100006Ne 2021-05-12T11:45:10.542_0000EAnd_01
58 |
59 | David Bell provided some additional info :
60 |
61 | 1-8 - ISO date to millisecond in base-62
62 |
63 | 9-16 - base62 counter that increases for each submission
64 |
65 | 17-18 - base62 sub-batch number within the main batch, usually “01”
66 | unless a single submission included multiple header blocks (different
67 | telescopes, different observers for each subbatch, etc.)
68 |
69 | 19-25 - base62 counter for the observation number within the sub-batch */
70 |
71 | static int show_usage( void)
72 | {
73 | printf( "usage : ./mpc_time (obsID)\n"
74 | "Can be full obsID or, if you just want the submission time,\n"
75 | "supply the first eight characters of the obsID.\n");
76 | return( -1);
77 | }
78 |
79 | int main( const int argc, const char **argv)
80 | {
81 | const char *id = (argc == 2 ? argv[1] : " ");
82 | const int ymd = get_mutant_hex_value( id, 3);
83 | const int hms = get_mutant_hex_value( id + 3, 3);
84 | const int millisec = get_mutant_hex_value( id + 6, 2);
85 | const int year = ymd / (31 * 12) + 1800;
86 | const int month = (ymd / 31) % 12 + 1;
87 | const int day = ymd % 31 + 1;
88 | const int n_days = days_in_month( month, year, CALENDAR_GREGORIAN);
89 | char buff[80];
90 |
91 | if( argc != 2)
92 | return( show_usage( ));
93 | snprintf( buff, sizeof( buff), "%04d-%02d-%02d %02d:%02d:%02d.%03d",
94 | year, month, day,
95 | hms / 3600, (hms / 60) % 60, hms % 60,
96 | millisec);
97 | printf( "%s = JD %f\n", buff,
98 | get_time_from_string( 0., buff, FULL_CTIME_YMD, NULL));
99 | if( strlen( id) >= 16)
100 | printf( "Submission counter: %.8s (mutant hex)\n", id + 8);
101 | if( strlen( id) >= 18)
102 | printf( "Sub-batch number within main batch counter: %.2s (mutant hex)\n", id + 16);
103 | if( strlen( id) >= 25)
104 | printf( "Observation number within the sub-batch: %.7s (mutant hex)\n", id + 18);
105 | if( day > n_days)
106 | printf( "WARNING: There are only %d days in that month\n", n_days);
107 | if( millisec >= 1000)
108 | printf( "WARNING: milliseconds should be 999 or less\n");
109 | if( hms > 86400) /* allow for one possible leap second */
110 | printf( "WARNING: time of day is out of range\n");
111 | if( hms == 86400)
112 | {
113 | if( (month % 6) || day != n_days)
114 | printf( "WARNING: This is an invalid leap second. It's not on the\n"
115 | "last day of June or December.\n");
116 | else
117 | printf( "WARNING: This is a leap second. Theoretically, it's allowed,\n"
118 | "but my code and MPC's will probably break if this submission\n"
119 | "time is used.\n");
120 | }
121 | /* Further checking could be done. Times in the future or
122 | before the time of the actual observation should be flagged. */
123 | return( 0);
124 | }
125 |
--------------------------------------------------------------------------------
/adestest.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include "mpc_func.h"
6 | #include "watdefs.h"
7 | #include "date.h"
8 |
9 | static void error_exit( )
10 | {
11 | fprintf( stderr,
12 | "\n"
13 | "Given the name of a file containing XML or PSV ADES data as a command\n"
14 | "line argument, 'adestest' will read it and output 80-column MPC-like\n"
15 | "astrometry. This can be used to make XML ADES slightly more readable\n"
16 | "(and PSV ADES data slightly _less_ readable), but its main purpose\n"
17 | "was to let me test my code for parsing ADES data. It also serves\n"
18 | "as an example of how to use the 'ades2mpc.cpp' ADES-parsing functions.\n"
19 | "\n"
20 | "Note that the 80-column output contains various extensions to the MPC\n"
21 | "format. RA/decs are stored in decimal degrees, both to match what\n"
22 | "we get from ADES and to allow greater precision. Uncertainties (which\n"
23 | "the 80-column format knows nothing about) are stored in COM (comment)\n"
24 | "lines. Dates/times are stored in a compacted form to allow millisecond\n"
25 | "precision (the usual MPC format allows only 10^-6 day = 86.4 ms\n"
26 | "precision). The resulting '80-column data' will work with all of my\n"
27 | "tools, but probably not with anyone else's.\n"
28 | "\n"
29 | " Add a '-m' command line switch to get 'real' 80-column data, with\n"
30 | "times in decimal days and RA/decs in base-60 form.\n");
31 | exit( -1);
32 | }
33 |
34 | void ades_artsat_desigs( void *ades_context, const bool ignore_artsat_desigs);
35 |
36 | int main( const int argc, const char **argv)
37 | {
38 | FILE *ifile;
39 | char buff[400];
40 | void *ades_context = init_ades2mpc( );
41 | int i, rval, show_data = 0;
42 | bool make_mpc80 = false, comments = true;
43 |
44 | if( argc < 2)
45 | {
46 | fprintf( stderr, "No file of ADES astrometry supplied on command line\n");
47 | error_exit( );
48 | }
49 | ifile = fopen( argv[1], "rb");
50 | if( !ifile)
51 | {
52 | fprintf( stderr, "Couldn't open '%s' : ", argv[1]);
53 | perror( NULL);
54 | error_exit( );
55 | }
56 | assert( ades_context);
57 | for( i = 2; i < argc; i++)
58 | if( argv[i][0] == '-')
59 | switch( argv[i][1])
60 | {
61 | case 'd':
62 | show_data = 1;
63 | break;
64 | case 'm':
65 | make_mpc80 = true;
66 | break;
67 | case 'c':
68 | comments = false;
69 | break;
70 | case 'a':
71 | ades_artsat_desigs( ades_context, true);
72 | break;
73 | default:
74 | fprintf( stderr, "'%s' not recognized\n", argv[i]);
75 | error_exit( );
76 | break;
77 | }
78 | while( fgets_with_ades_xlation( buff, sizeof( buff), ades_context, ifile))
79 | {
80 | if( show_data || make_mpc80)
81 | {
82 | unsigned time_format;
83 | const double jd = extract_date_from_mpc_report( buff, &time_format);
84 | double ra, dec;
85 |
86 | if( jd)
87 | {
88 | int ra_format, dec_format;
89 | double ra_prec, dec_prec;
90 | const double PI = 3.1415926535897932384626433832795028841971693993751058209749445923;
91 |
92 | get_ra_dec_from_mpc_report( buff, &ra_format, &ra, &ra_prec,
93 | &dec_format, &dec, &dec_prec);
94 |
95 | if( show_data)
96 | printf( "MJD %f RA %f dec %f\n", jd - 2400000.5, ra, dec);
97 | if( make_mpc80)
98 | { /* switch date, RA, dec to MPC80 format */
99 | char tbuff[40];
100 | int format = FULL_CTIME_YMD | FULL_CTIME_LEADING_ZEROES
101 | | FULL_CTIME_MONTHS_AS_DIGITS | FULL_CTIME_FORMAT_DAY;
102 |
103 | format |= FULL_CTIME_6_PLACES;
104 | full_ctime( tbuff, jd, format);
105 | memcpy( buff + 15, tbuff, 17);
106 | if( buff[14] != 'v')
107 | {
108 | output_angle_to_buff( tbuff, ra * 12. / PI, 3);
109 | memcpy( buff + 32, tbuff, 12);
110 | output_signed_angle_to_buff( tbuff, dec * 180. / PI, 2);
111 | memcpy( buff + 44, tbuff, 12);
112 | }
113 | }
114 | }
115 | }
116 | if( comments || memcmp( buff, "COM ", 4))
117 | printf( "%s\n", buff);
118 | }
119 | rval = free_ades2mpc_context( ades_context);
120 | fclose( ifile);
121 | printf( "rval = %d\n", rval);
122 | return( 0);
123 | }
124 |
--------------------------------------------------------------------------------
/brentmin.h:
--------------------------------------------------------------------------------
1 | #ifndef BRENTMIN_H_INCLUDED
2 | #define BRENTMIN_H_INCLUDED
3 |
4 | /* brentmin.h: header file for Brent minimization without derivatives
5 |
6 | Copyright (C) 2018, Project Pluto
7 |
8 | This program is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU General Public License
10 | as published by the Free Software Foundation; either version 2
11 | of the License, or (at your option) any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with this program; if not, write to the Free Software
20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 | 02110-1301, USA. */
22 |
23 | #ifdef __cplusplus
24 | extern "C" {
25 | #endif /* #ifdef __cplusplus */
26 |
27 | typedef struct
28 | {
29 | double x[5], y[5]; /* lowest values thus far */
30 | double xmin, xmax; /* bracketing values */
31 | double next_x;
32 | double gold_ratio; /* variable; see brentmin.cpp */
33 | double tolerance, ytolerance;
34 | double prev_range, prev_range2;
35 | int step_type, n_iterations;
36 | } brent_min_t;
37 |
38 | void brent_min_init( brent_min_t *b, const double x1, const double y1,
39 | const double x2, const double y2,
40 | const double x3, const double y3);
41 | double brent_min_next( brent_min_t *b);
42 | int brent_min_add( brent_min_t *b, const double next_y);
43 | double fit_parabola( const double *x, const double *y, double *b, double *c);
44 |
45 | /* This is a somewhat modified version of Brent's algorithm for finding the
46 | minimum of a single-variable function. brent_min_init( ) takes three points
47 | with distinct x values, such that the middle x value has the lowest y value;
48 | i.e., it's a bracketed minimum. (The points need not be passed in any
49 | particular order).
50 |
51 | One then enters a loop wherein one calls brent_min_next( ) to get the
52 | next suggested point to check; you evaluate the function there and call
53 | brent_min_add( ) to update the algorithm. Repeat until xmax-xmin is below
54 | a desired threshhold.
55 |
56 | Brent's method combines "golden search" (a not very fast method, but
57 | with guaranteed linear convergence) and parabolic interpolation : find
58 | the quadratic fitting through the three lowest points seen thus far, and
59 | look at the point that is the minimum of that quadratic. The latter
60 | method is much faster, _if_ the function really resembles a parabola
61 | within the bracket. Some bookkeeping is required to detect cases where
62 | convergence is slow; if that happens, we switch back to the reliable
63 | golden section method for a step or two. Thus, even in worst-case
64 | scenarios, the algorithm _will_ still converge linearly.
65 |
66 | I've made the following modifications :
67 |
68 | -- This code keeps track of the _four_ lowest points and fits a _cubic_
69 | polynomial to them, and determines a minimum from that.
70 |
71 | -- Convergence to the minimum tends to be extremely fast for sufficiently
72 | "well-behaved" functions. But even with those, you can have problems because
73 | you've reduced the (say) left-hand side of the bracket a thousandfold, but the
74 | right-hand side is as large as ever. In such cases, we're probably very close
75 | to the minimum, and don't have to go far into the larger side to find a point
76 | that is, most likely, past the maximum. This "shrink" step can easily reduce
77 | xmax-xmin a hundredfold, and more than that in the final steps where the
78 | function is effectively a parabola or cubic.
79 |
80 | At present, if the large side of the bracket is more than ten times
81 | the size of the small side of the bracket, we take a look at a point that
82 | is at xmin - (xsmall - xmin) * 3, where xmin is our minimum point and
83 | xsmall is the point at the small end of the bracket. In other words,
84 | we take the small end's size, triple it, and look that far into the
85 | larger bracket.
86 |
87 | If we're lucky (as we usually are), this drastically reduces the size
88 | of the larger side of the bracket. If not, the smaller side is tripled
89 | in size (and the larger size shrinks accordingly).
90 |
91 | This is the result of some empirical testing, and should be examined
92 | more carefully. I'd like to have something on a more solid theoretical
93 | ground. One possibility is to compute both the cubic and parabolic minima;
94 | the difference between them could be a gauge of the error to which we've
95 | determined the minimum. Or perhaps the magnitude of the leading coefficient
96 | of the cubic polynomial gives us a clue as to how far the function departs
97 | from being a parabola.
98 | */
99 |
100 | #ifdef __cplusplus
101 | }
102 | #endif /* #ifdef __cplusplus */
103 | #endif /* #ifndef BRENTMIN_H_INCLUDED */
104 |
--------------------------------------------------------------------------------
/text_ca2.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include "watdefs.h"
6 | #include "date.h"
7 | #include "lunar.h"
8 |
9 | /* Small program-let to generate the ASCII calendar with lunar phases
10 | shown in interactive Find_Orb when you hit 'c'. (See the file
11 | 'calendar.txt' in the Find_Orb repository.) Compile with
12 |
13 | gcc -Wextra -Wall -O3 -pedantic text_ca2.c -o text_ca2 liblunar.a -lm
14 |
15 | See 'boxize.c' in the 'junk' repo for code to turn the output from
16 | + - | dividers into Unicode box characters.
17 |
18 | make_base_line( ) will produce one of the following four lines,
19 | for line = 0, 1, 2, 3, except with the width depending on the value
20 | of 'cols'.
21 |
22 | 0: (all spaces)
23 | 1: +---------+---------+---------+---------+---------+---------+---------+
24 | 2: | Sunday | Monday | Tuesday |Wednesday| Thursday| Friday | Saturday|
25 | 3: | | | | | | | |
26 | */
27 |
28 | static void make_base_line( char *txt, const int cols, const int line)
29 | {
30 | int i;
31 |
32 | memset( txt, (line != 1 ? ' ' : '-'), cols * 7);
33 | txt[cols * 7 + 1] = '\0';
34 | if( !line)
35 | return;
36 | for( i = 0; i < 8; i++)
37 | txt[i * cols] = (line != 1 ? '|' : '+');
38 | if( line == 2)
39 | for( i = 0; i < 7; i++)
40 | {
41 | const char *days[7] = { "Sunday", "Monday", "Tuesday", "Wednesday",
42 | "Thursday", "Friday", "Saturday" };
43 | int len = (int)strlen( days[i]);
44 |
45 | if( len > cols - 1)
46 | len = cols - 1;
47 | memcpy( txt + i * cols + (cols - len + 1) / 2, days[i], len);
48 | }
49 | }
50 |
51 | static int lines_per_week = 4;
52 |
53 | static void show_calendar( const long year, const int month, const int cols)
54 | {
55 | int i, day, n_output_lines = 4 + 5 * lines_per_week;
56 | const long jd0 = dmy_to_day( 0, month, year, CALENDAR_GREGORIAN);
57 | const int loc0 = (int)( (jd0 + 2) % 7) - 1;
58 | char **text;
59 | const char *month_names[12] = { "January", "February", "March",
60 | "April", "May", "June", "July", "August", "September",
61 | "October", "November", "December" };
62 |
63 | text = (char **)calloc( n_output_lines, sizeof( char *));
64 | text[0] = (char *)malloc( n_output_lines * (7 * cols + 2));
65 | for( i = 1; i < n_output_lines; i++)
66 | text[i] = text[i - 1] + 7 * cols + 2;
67 | for( i = 0; i < 3; i++)
68 | make_base_line( text[i], cols, i);
69 | for( i = 0; i <= 5 * lines_per_week; i++)
70 | make_base_line( text[i + 3], cols, (i % lines_per_week ? 3 : 1));
71 | for( day = days_in_month( month, year, CALENDAR_GREGORIAN); day; day--)
72 | {
73 | const unsigned col = cols * ((unsigned)(day + loc0) % 7u) + 2u;
74 | unsigned line = (unsigned)((day + loc0) / 7u) % 5u;
75 | const long t2k = (double)jd0 + (double)day - 2451545.;
76 | int phase;
77 |
78 | line = line * (unsigned)lines_per_week + 4u;
79 | if( day >= 10)
80 | text[line][col] = '0' + day / 10u;
81 | text[line][col + 1] = '0' + day % 10u;
82 | for( phase = 0; phase < 4; phase++)
83 | if( (long)( find_nearest_lunar_phase_time( phase, (long double)t2k) + .5) == t2k)
84 | {
85 | const char *phases[4] = { "New Moon", "1st Qtr", "Full Moon", "3rd Qtr" };
86 |
87 | memcpy( text[line + 1] + col - 1, phases[phase], strlen( phases[phase]));
88 | }
89 | }
90 | sprintf( text[0] + (cols * 7 - strlen( month_names[month - 1])) / 2 - 2,
91 | "%s %ld", month_names[month - 1], year);
92 | for( i = 0; i < 4 + 5 * lines_per_week; i++)
93 | printf( "%s\n", text[i]);
94 | free( text[0]);
95 | free( text);
96 | printf( "\n");
97 | }
98 |
99 | static void usage_exit( void)
100 | {
101 | fputs( "usage: text_ca2 year n_years [-c cols] [-l lines]\n", stderr);
102 | exit( -1);
103 | }
104 |
105 | int main( const int argc, const char **argv)
106 | {
107 | long year = (argc > 1 ? atoi( argv[1]) : 0);
108 | long n_years = (argc > 2 ? atoi( argv[2]) : 0);
109 | int cols = 11;
110 |
111 | if( !n_years || !year)
112 | usage_exit( );
113 | for( int i = 3; i < argc - 1; i++)
114 | if( argv[i][0] == '-')
115 | {
116 | switch( argv[i][1])
117 | {
118 | case 'l' :
119 | lines_per_week = atoi( argv[i + 1]);
120 | break;
121 | case 'c' :
122 | cols = atoi( argv[i + 1]);
123 | break;
124 | default:
125 | fprintf( stderr, "Unrecognized argument '%s'\n", argv[i]);
126 | usage_exit( );
127 | break;
128 | }
129 | i++;
130 | }
131 | else
132 | usage_exit( );
133 | while( n_years--)
134 | {
135 | int month;
136 |
137 | for( month = 1; month <= 12; month++)
138 | show_calendar( year, month, cols);
139 | year++;
140 | }
141 | return( 0);
142 | }
143 |
--------------------------------------------------------------------------------
/lunar64.def:
--------------------------------------------------------------------------------
1 | LIBRARY lunar64
2 | EXPORTS
3 | acose @1
4 | asine @2
5 | calc_big_vsop_loc @3
6 | calc_classical_elements @4
7 | calc_dist_and_posn_ang @5
8 | calc_jsat_loc @6
9 | calc_planet_orientation @8
10 | calc_pluto_loc @9
11 | calc_ssat_loc @10
12 | calc_vsop_loc @11
13 | comet_posn @12
14 | comet_posn_and_vel @13
15 | compute_elp_xyz @14
16 | compute_extinction @15
17 | compute_limiting_mag @16
18 | compute_planet @17
19 | compute_sky_brightness @18
20 | day_to_dmy @19
21 | decipher_var_desig @20
22 | deprecess_vector @21
23 | derive_quantities @22
24 | dmy_to_day @23
25 | evaluate_rock @24
26 | extract_periodic_name @25
27 | full_alt_az_to_ra_dec @26
28 | full_ctime @27
29 | full_ra_dec_to_alt_az @28
30 | galactic_to_ra_dec @29
31 | get_chinese_intercalary_month @30
32 | ; get_comet_file @31
33 | get_ps1996_position @32
34 | green_sidereal_time @33
35 | invert_orthonormal_matrix @34
36 | j2000_to_galactic_matrix @35
37 | load_ps1996_series @36
38 | lunar_fundamentals @37
39 | lunar_lat @38
40 | lunar_lon_and_dist @39
41 | make_var_desig @40
42 | mean_obliquity @41
43 | nutation @42
44 | polar3_to_cartesian @43
45 | precess_pt @44
46 | precess_ra_dec @45
47 | precess_vector @46
48 | pre_spin_matrix @47
49 | ra_dec_to_galactic @48
50 | refraction @49
51 | reset_td_minus_dt_string @50
52 | reverse_refraction @51
53 | reverse_saasta_refraction @52
54 | rotate_vector @53
55 | saasta_refraction @54
56 | setup_ecliptic_precession @55
57 | setup_elems_from_ast_file @56
58 | setup_precession @57
59 | set_brightness_params @58
60 | set_chinese_calendar_data @59
61 | set_identity_matrix @60
62 | set_month_name @61
63 | spin_matrix @62
64 | td_minus_ut @63
65 | unload_ps1996_series @64
66 | elements_in_mpc_format @65
67 | decimal_day_to_dmy @66
68 | td_minus_utc @67
69 | j2000_to_supergalactic_matrix @68
70 | supergalactic_to_ra_dec @69
71 | ra_dec_to_supergalactic @70
72 | integrated_refraction @71
73 | reverse_integrated_refraction @72
74 | reverse_dist_and_posn_ang @73
75 | split_time @74
76 | get_time_from_string @75
77 | equatorial_to_ecliptic @76
78 | ecliptic_to_equatorial @77
79 | vector3_length @78
80 | calc_triton_loc @79
81 | vector_cross_product @80
82 | full_ctimel @81
83 | get_time_from_stringl @82
84 | setup_precession_with_nutation @83
85 | setup_precession_with_nutation_eops @84
86 | get_earth_orientation_params @85
87 | load_earth_orientation_params @86
88 | load_cospar_file @87
89 | tdb_minus_tdt @88
90 | split_timel @89
91 | set_day_of_week_name @90
92 | extract_date_from_mpc_report @91
93 | extract_sof_data @92
94 | get_mpc_code_info @93
95 | get_ra_dec_from_mpc_report @94
96 | lat_alt_to_parallax @95
97 | planet_axis_ratio @96
98 | point_to_ellipse @97
99 | is_valid_mpc_code @98
100 | byte_code_to_net_name @99
101 | net_name_to_byte_code @100
102 | create_mpc_packed_desig @101
103 | init_ades2mpc @102
104 | free_ades2mpc_context @103
105 | xlate_ades2mpc @104
106 | xlate_ades2mpc_in_place @105
107 | fgets_with_ades_xlation @106
108 | find_moid_full @107
109 |
--------------------------------------------------------------------------------
/mpc_func.h:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2018, Project Pluto
2 |
3 | This program is free software; you can redistribute it and/or
4 | modify it under the terms of the GNU General Public License
5 | as published by the Free Software Foundation; either version 2
6 | of the License, or (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 | 02110-1301, USA. */
17 |
18 | #ifndef MPC_FUNC_H_INCLUDED
19 | #define MPC_FUNC_H_INCLUDED
20 |
21 | #ifndef DLL_FUNC
22 | #include "watdefs.h"
23 | #endif
24 |
25 | #ifdef __cplusplus
26 | extern "C" {
27 | #endif
28 |
29 | bool is_valid_mpc_code( const char *mpc_code); /* mpc_fmt.cpp */
30 | double extract_date_from_mpc_report( const char *buff, unsigned *format);
31 | int get_ra_dec_from_mpc_report( const char *ibuff, /* mpc_fmt.cpp */
32 | int *ra_format, double *ra, double *ra_precision,
33 | int *dec_format, double *dec, double *dec_precision);
34 |
35 | char net_name_to_byte_code( const char *net_name);
36 | const char *byte_code_to_net_name( const char byte_code);
37 | int extract_region_data_for_lat_lon( FILE *ifile, char *buff,
38 | const double lat_in_degrees, const double lon_in_degrees);
39 |
40 | typedef struct
41 | {
42 | double lat, lon; /* in radians */
43 | double alt; /* in metres */
44 | double rho_cos_phi, rho_sin_phi; /* in planet radii */
45 | int planet, prec1, prec2, format;
46 | const char *name;
47 | char code[5];
48 | } mpc_code_t;
49 |
50 | #define MPC_CODE_PARALLAXES 1
51 | #define MPC_CODE_LAT_LON_ALT 2
52 | #define MPC_CODE_SATELLITE 3
53 |
54 | int DLL_FUNC text_search_and_replace( char *str, const char *oldstr,
55 | const char *newstr);
56 | int get_mpc_code_info( mpc_code_t *cinfo, const char *buff);
57 | int get_xxx_location_info( mpc_code_t *cinfo, const char *buff);
58 | int get_lat_lon_info( mpc_code_t *cinfo, const char *buff);
59 | double get_ra_from_string( const char *buff, int *bytes_read);
60 | double get_dec_from_string( const char *buff, int *bytes_read);
61 | void output_angle_to_buff( char *obuff, double angle, int precision);
62 | void output_signed_angle_to_buff( char *obuff, const double angle,
63 | const int precision);
64 |
65 | double point_to_ellipse( const double a, const double b,
66 | const double x, const double y, double *dist);
67 | int lat_alt_to_parallax( const double lat, const double ht_in_meters,
68 | double *rho_cos_phi, double *rho_sin_phi,
69 | const double major_axis_in_meters,
70 | const double minor_axis_in_meters); /* mpc_code.cpp */
71 | int create_mpc_packed_desig( char *packed_desig, const char *obj_name);
72 |
73 | void *init_ades2mpc( void);
74 | int xlate_ades2mpc( void *context, char *obuff, const char *buff);
75 | int xlate_ades2mpc_in_place( void *context, char *buff);
76 | int free_ades2mpc_context( void *context);
77 | int fgets_with_ades_xlation( char *buff, const size_t len,
78 | void *ades_context, FILE *ifile);
79 | int mutant_hex_char_to_int( const char c);
80 | char int_to_mutant_hex_char( const int ival);
81 | int get_mutant_hex_value( const char *buff, size_t n_digits);
82 | int encode_value_in_mutant_hex( char *buff, size_t n_digits, int value);
83 | int unpack_mpc_desig( char *obuff, const char *packed);
84 | int unpack_unaligned_mpc_desig( char *obuff, const char *packed);
85 |
86 | #define OBJ_DESIG_ASTEROID_PROVISIONAL 0
87 | #define OBJ_DESIG_ASTEROID_NUMBERED 1
88 | #define OBJ_DESIG_COMET_PROVISIONAL 2
89 | #define OBJ_DESIG_COMET_NUMBERED 3
90 | #define OBJ_DESIG_NATSAT_PROVISIONAL 4
91 | #define OBJ_DESIG_NATSAT_NUMBERED 5
92 | #define OBJ_DESIG_ARTSAT 6
93 | #define OBJ_DESIG_OTHER -1
94 |
95 | /* The offset between a satellite observation and the earth or sun
96 | is stored in a second line, as described at
97 |
98 | https://www.minorplanetcenter.net/iau/info/SatelliteObs.html
99 |
100 | These are sometimes -- nay, frequently -- mangled (decimal points
101 | in odd places, etc.) get_satellite_offset() will do its best to
102 | recover from such things, but may fail. */
103 |
104 | #define SATELL_COORD_ERR_NO_ERROR 0
105 | #define SATELL_COORD_ERR_BAD_SIGN -1
106 | #define SATELL_COORD_ERR_BAD_NUMBER -2
107 | #define SATELL_COORD_ERR_NO_DECIMAL -3
108 | #define SATELL_COORD_ERR_DECIMAL_MISPLACED -4
109 | #define SATELL_COORD_ERR_UNKNOWN_OFFSET -5
110 | #define SATELL_COORD_ERR_EXACTLY_ZERO -6
111 | #define SATELL_COORD_ERR_INSIDE_EARTH -7
112 |
113 | #define N_SATELL_COORD_ERRORS 8
114 |
115 | int DLL_FUNC get_satellite_offset( const char *iline, double xyz[3]);
116 |
117 | #ifdef __cplusplus
118 | }
119 | #endif
120 |
121 | #endif
122 |
--------------------------------------------------------------------------------
/cgicheck.cpp:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2018, Project Pluto
2 |
3 | This program is free software; you can redistribute it and/or
4 | modify it under the terms of the GNU General Public License
5 | as published by the Free Software Foundation; either version 2
6 | of the License, or (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 | 02110-1301, USA. */
17 |
18 | #include
19 | #include
20 | #include
21 | #include "cgi_func.h"
22 | #include "watdefs.h"
23 | #include "stringex.h"
24 |
25 | /* Code to invoke the 'astcheck' routine from an HTML form.
26 | You'll see a _lot_ of overlap between this and 'sat_id2.cpp',
27 | the code to do satellite checking from an HTML form, and the
28 | 'fo_serve.cpp' code to run Find_Orb from an HTML form...
29 | there's a lot of recycling going on.
30 |
31 | In setting up cgicheck on your server, you'll need to make
32 | sure that 'cgicheck.htm' is present, of course, along with a copy
33 | of ObsCodes.html for parallax data. You should have either mpcorb.dat
34 | or the Lowell astorb.dat files, or both, present (note that the code
35 | expects the lowercase filenames). The results are similar with either
36 | database of orbital elements, except that 'astorb' gives you current
37 | ephemeris uncertainties.
38 | */
39 |
40 | int astcheck_main( const int argc, const char **argv); /* astcheck.c */
41 |
42 | int main( const int unused_argc, const char **unused_argv)
43 | {
44 | const char *argv[20];
45 | const size_t max_buff_size = 40000; /* room for 500 obs */
46 | char *buff;
47 | char boundary[100], field[30];
48 | const char *temp_obs_filename = "temp_obs.txt";
49 | int argc = 2;
50 | FILE *lock_file = fopen( "lock.txt", "w");
51 | size_t bytes_written = 0;
52 | #ifndef _WIN32
53 | extern char **environ;
54 | #endif
55 | extern int verbose;
56 | double search_radius = 2.; /* default to looking two degrees */
57 |
58 | INTENTIONALLY_UNUSED_PARAMETER( unused_argv);
59 | INTENTIONALLY_UNUSED_PARAMETER( unused_argc);
60 | #ifndef _WIN32 /* If things take more than 60 seconds, */
61 | avoid_runaway_process( 60); /* assume failure and give an error msg */
62 | #endif /* _WIN32 to that effect */
63 | printf( "Content-type: text/html\n\n");
64 | printf( " \n");
65 | if( !lock_file)
66 | {
67 | printf( "Server is busy. (At least as currently written, we can only run\n");
68 | printf( "a single batch of observations at a time. However, a given batch of\n");
69 | printf( "observations usually doesn't take all that long... come back in\n");
70 | printf( "a minute or two and try again.)\n");
71 | printf( " ");
72 | return( 0);
73 | }
74 | fprintf( lock_file, "We're in\n");
75 | #ifndef _WIN32
76 | for( size_t i = 0; environ[i]; i++)
77 | fprintf( lock_file, "%s\n", environ[i]);
78 | #endif
79 | if( !fgets( boundary, sizeof( boundary), stdin))
80 | {
81 | printf( " No info read from stdin");
82 | printf( "This isn't supposed to happen.\n");
83 | return( 0);
84 | }
85 | buff = (char *)malloc( max_buff_size + 100);
86 | while( get_multipart_form_data( boundary, field, buff, NULL, max_buff_size) >= 0)
87 | {
88 | if( !strcmp( field, "TextArea") || !strcmp( field, "upfile"))
89 | {
90 | if( strlen( buff) > 70)
91 | {
92 | FILE *ofile = fopen( temp_obs_filename,
93 | (bytes_written ? "ab" : "wb"));
94 |
95 | bytes_written += fwrite( buff, 1, strlen( buff), ofile);
96 | fclose( ofile);
97 | }
98 | }
99 | else if( !strcmp( field, "radius"))
100 | {
101 | const char *verbosity = strchr( buff, 'v');
102 |
103 | search_radius = atof( buff);
104 | if( verbosity)
105 | verbose = atoi( verbosity + 1) + 1;
106 | }
107 | else if( !strcmp( field, "catalog"))
108 | {
109 | if( buff[0] == '1') /* use MPCORB */
110 | argv[argc++] = "-M";
111 | }
112 | else if( !strcmp( field, "uncertainties"))
113 | argv[argc++] = "-e";
114 | else if( !strcmp( field, "unn_only"))
115 | argv[argc++] = "-u";
116 | }
117 | free( buff);
118 | if( verbose)
119 | printf( "Searching to %f degrees; %u bytes read from input\n",
120 | search_radius, (unsigned)bytes_written);
121 | argv[0] = "cgicheck";
122 | argv[1] = temp_obs_filename;
123 | snprintf_err( field, sizeof( field), "-r%.2f", search_radius * 3600.); /* cvt degrees to arcsec */
124 | argv[argc++] = field;
125 | argv[argc] = NULL;
126 | astcheck_main( argc, argv);
127 | printf( "
");
128 | return( 0);
129 | }
130 |
--------------------------------------------------------------------------------
/utc_algo.cpp:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2018, Project Pluto
2 |
3 | This program is free software; you can redistribute it and/or
4 | modify it under the terms of the GNU General Public License
5 | as published by the Free Software Foundation; either version 2
6 | of the License, or (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 | 02110-1301, USA. */
17 |
18 | #include
19 | #include
20 | #include
21 | #include "watdefs.h"
22 | #include "date.h"
23 |
24 | /* Code to test a (relatively) simple, quick way to determine in which half
25 | year a given MJD falls. This is of use in 'delta_t.cpp' in figuring out
26 | guesstimates of when future leap seconds should be inserted. See the
27 | 'td_minus_utc()' function.
28 |
29 | Having been written and used to test the handling of future leap seconds,
30 | this code is really of only historical use. I'm leaving it around in order
31 | to document how this rather strange algorithm works.
32 |
33 | The basic idea is this. 400 Gregorian years will contain 400*365 "regular"
34 | days, plus 397 leap days, for a total of 146097 days. Therefore, given a
35 | number of days past "year zero", the year will be approximately
36 |
37 | year = day * 400 / 146097
38 |
39 | Note that, in what follows, the above math is promoted to 64-bit ints
40 | to avoid overflow. 1 Jan 0 (first day of the year zero) is JD 1721057.5.
41 | Round this up, and one finds that day = mjd + 2400000 - 1721058. Using
42 | this, the above formula can sometimes yield a year that is one too high
43 | for dates in late December; hence the computation of 'low' as the MJD of
44 | the corresponding year and the test to see "if( mjd < low)".
45 |
46 | So now we know what year corresponds to the given MJD. Next problem is,
47 | are we before or after 1 July of that year? To find this out, we compute
48 | the MJD for 1 January of the following year, then compute the MJD of the
49 | preceding 1 July. There can't be leap days over that span, so all we
50 | need do is to subtract 31 + 31 + 30 + 31 + 30 + 31 = 183 days to back up
51 | from 1 Jan to 1 July.
52 |
53 | We then know in which half-year we are. In the actual Delta-T code,
54 | we can then average the MJDs of the ends of that time span to get the MJD
55 | for the _middle_ of the time span, compute Delta-T at that point, and come
56 | up with a UTC offset that'll keep |UTC-UT| < .5 second; i.e., keep UTC
57 | and UT as close together as possible.
58 |
59 | This is admittedly something of a kludge. But anything done to estimate
60 | future leap seconds has to be a kludge; there's no "good" way to do it.
61 |
62 | See 'delta_t.cpp' for an explanation of the following macro. */
63 |
64 | #define BASE_YEAR 19999999999L
65 | #define JAN_1( YEAR) (((YEAR) * 365L + ((YEAR) + BASE_YEAR) / 4L - ((YEAR) + BASE_YEAR) / 100L \
66 | + ((YEAR) + BASE_YEAR) / 400L) - 678940L \
67 | - ((BASE_YEAR + 1L) / 400L) * 97L)
68 |
69 | // unsigned day = mjd + 1931367u + 2400000u;
70 | // int year = (int)( day * 400u / 146097u) - 10000;
71 |
72 | int main( const int argc, const char **argv)
73 | {
74 | int mjd = atoi( argv[1]);
75 |
76 | if( argc == 2)
77 | {
78 | int day = mjd + 2400000 - 1721058;
79 | int year = (int)( (int64_t)day * (int64_t)400 / (int64_t)146097);
80 | int low, high, july_1;
81 |
82 | printf( "Year = %d\n", year);
83 | low = JAN_1( year);
84 | printf( "MJD 1 Jan %d = %ld\n", year, JAN_1( year));
85 | if( mjd < low)
86 | {
87 | year--;
88 | low = JAN_1( year);
89 | printf( "MJD 1 Jan %d = %ld\n", year, JAN_1( year));
90 | }
91 | high = JAN_1( year + 1);
92 | printf( "MJD 1 Jan %d = %d\n", year + 1, high);
93 | /* jul aug sep oct nov dec */
94 | july_1 = high - (31 + 31 + 30 + 31 + 30 + 31);
95 | printf( "MJD 1 Jul %d = %d\n", year, july_1);
96 | if( mjd < july_1)
97 | printf( "In first half of %d\n", year);
98 | else
99 | printf( "In second half of %d\n", year);
100 | }
101 | else /* Test to see: over a given range of */
102 | { /* MJDs, how often does the above year */
103 | int n_less = 0, n_more = 0; /* determination land "spot on"? How */
104 | /* often must we go to the next year? */
105 | while( mjd < atoi( argv[2]))
106 | {
107 | int day = mjd + 2400000 - 1721058;
108 | int year = (int)( (int64_t)day * (int64_t)400 / (int64_t)146097);
109 |
110 | if( JAN_1( year) > mjd)
111 | n_more++;
112 | if( JAN_1( year + 1) <= mjd)
113 | n_less++;
114 | mjd++;
115 | }
116 | printf( "%d cases went over; %d went under\n", n_more, n_less);
117 | }
118 | return( 0);
119 | }
120 |
--------------------------------------------------------------------------------
/mms.cpp:
--------------------------------------------------------------------------------
1 | /* Code to read in files of the form
2 |
3 | https://lasp.colorado.edu/mms/sdc/public/data/ancillary/mms1/predeph/MMS1_PREDEPH_2019155_2019171.V00
4 |
5 | and spit out ephemeris files of the sort readable by 'eph2tle' (q.v.,
6 | in the Find_Orb repository). The files give times in days since
7 | 1958 Jan 1 = JD 2436204.5 TAI. TAI differs from TDT (the ephemeris
8 | time scale we actually want) by a solidly fixed 32.184 seconds.
9 |
10 | This is somewhat analogous to 'themis.cpp' (q.v.), written to
11 | produce accurate TLEs for an object where Space-Track is not entirely
12 | effectual. However, while the TLEs generated in this manner are
13 | really good and would enable us to determine which of the four MMS
14 | satellites we're looking at, the Space-Track TLEs appear to be good
15 | enough for the general problem of at least being able to say : "you
16 | got one of the four MMS sats; how much do we really care which one
17 | you got?"
18 |
19 | If we decide that _really_ matters, I'll set this up to generate
20 | TLEs for all four MMS sats, as 'themis' currently does for
21 | THEMIS-A, D, and E. But that's not a priority at present. */
22 |
23 | #define TDT_MINUS_TAI 32.184
24 | #define JAN_1_1958 (2436204.5 + TDT_MINUS_TAI / 86400.)
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include "watdefs.h"
31 | #include "date.h"
32 |
33 | static void error_exit( const char *message)
34 | {
35 | if( message)
36 | fprintf( stderr, "%s\n", message);
37 | fprintf( stderr, "'mms' requires the name of an MMS ephemeris file as\n"
38 | "a command-line argument. Output defaults to 'mms.eph'.\n");
39 | exit( -1);
40 | }
41 |
42 | /* I really should use getopt() or a portable variant. However, this has
43 | been sufficiently effective thus far... */
44 |
45 | static const char *get_arg( const int argc, const char **argv, const int idx)
46 | {
47 | if( argv[idx][2] || idx == argc - 1)
48 | return( argv[idx] + 2);
49 | else
50 | return( argv[idx + 1]);
51 | }
52 |
53 | static double mms_ephem_jd( const char *buff)
54 | {
55 | if( strlen( buff) > 150 && buff[4] == '-' && buff[8] == '/'
56 | && buff[11] == ':')
57 | return( atof( buff + 23) + JAN_1_1958);
58 | else
59 | return( 0.);
60 | }
61 |
62 | int main( const int argc, const char **argv)
63 | {
64 | double jd_start = 0.;
65 | char buff[300];
66 | FILE *ifile, *ofile = stdout;
67 | int n_lines = 0, out_freq = 72, i;
68 | int mms_number = 0;
69 |
70 | if( argc < 2)
71 | error_exit( NULL);
72 | ifile = fopen( argv[1], "rb");
73 | if( !ifile)
74 | {
75 | fprintf( stderr, "Couldn't open '%s' ", argv[1]);
76 | perror( NULL);
77 | error_exit( NULL);
78 | }
79 | if( argc > 2 && argv[2][0] != '-')
80 | {
81 | ofile = fopen( argv[2], "wb");
82 | if( !ifile)
83 | {
84 | fprintf( stderr, "Couldn't open '%s' ", argv[2]);
85 | perror( NULL);
86 | error_exit( NULL);
87 | }
88 | }
89 | for( i = 2; i < argc; i++)
90 | if( argv[i][0] == '-')
91 | {
92 | const char *arg = get_arg( argc, argv, i);
93 |
94 | assert( arg);
95 | switch( argv[i][1])
96 | {
97 | case 'f':
98 | out_freq = atoi( arg);
99 | if( !out_freq || (720 % out_freq))
100 | error_exit( "The output frequency must be a factor of 720.\n");
101 | break;
102 | default:
103 | fprintf( stderr, "Unrecognized parameter '%s ", argv[i]);
104 | error_exit( NULL);
105 | }
106 | }
107 | while( fgets( buff, sizeof( buff), ifile))
108 | {
109 | const double jd = mms_ephem_jd( buff);
110 |
111 | if( jd)
112 | {
113 | n_lines++;
114 | if( !jd_start)
115 | jd_start = jd;
116 | }
117 | if( !memcmp( buff, "Spacecraft = MMS", 16))
118 | mms_number = buff[16];
119 | }
120 | assert( mms_number >= '1' && mms_number <= '4');
121 | fseek( ifile, 0L, SEEK_SET);
122 | /* '0,149597870.7,86400' = coords are J2000 equatorial,
123 | in km and km/s. */
124 | fprintf( ofile, "%.6f %.6f %d 0,149597870.7,86400 (500) Geocentric: MMS%c = 2015-011%c\n",
125 | jd_start, (double)out_freq / 720., n_lines / out_freq,
126 | mms_number, mms_number + 'A' - '1');
127 |
128 | n_lines = 0;
129 | while( fgets( buff, sizeof( buff), ifile))
130 | {
131 | const double jd = mms_ephem_jd( buff);
132 |
133 | if( jd)
134 | {
135 | buff[184] = '\0';
136 | if( n_lines % out_freq == 0)
137 | fprintf( ofile, "%.6f %s\n", jd, buff + 44);
138 | n_lines++;
139 | }
140 | }
141 | fclose( ifile);
142 | fprintf( ofile, "\nCreated from 'mms.cpp' (q.v.)\n");
143 | full_ctime( buff, jd_start, CALENDAR_JULIAN_GREGORIAN);
144 | fprintf( ofile, "Ephemeris start: %s\n", buff);
145 |
146 | full_ctime( buff, jd_start + (n_lines / out_freq) * out_freq / 720., CALENDAR_JULIAN_GREGORIAN);
147 | fprintf( ofile, "Ephemeris end: %s\n", buff);
148 | if( ofile != stdout)
149 | fclose( ofile);
150 | return( 0);
151 | }
152 |
--------------------------------------------------------------------------------
/lunar.def:
--------------------------------------------------------------------------------
1 | LIBRARY lunar
2 | EXPORTS
3 | acose @1
4 | asine @2
5 | calc_big_vsop_loc @3
6 | calc_classical_elements @4
7 | calc_dist_and_posn_ang @5
8 | calc_jsat_loc @6
9 | calc_planet_orientation @8
10 | calc_pluto_loc @9
11 | calc_ssat_loc @10
12 | calc_vsop_loc @11
13 | comet_posn @12
14 | comet_posn_and_vel @13
15 | compute_elp_xyz @14
16 | compute_extinction @15
17 | compute_limiting_mag @16
18 | compute_planet @17
19 | compute_sky_brightness @18
20 | day_to_dmy @19
21 | decipher_var_desig @20
22 | deprecess_vector @21
23 | derive_quantities @22
24 | dmy_to_day @23
25 | evaluate_rock @24
26 | extract_periodic_name @25
27 | full_alt_az_to_ra_dec @26
28 | full_ctime @27
29 | full_ra_dec_to_alt_az @28
30 | galactic_to_ra_dec @29
31 | get_chinese_intercalary_month @30
32 | ; get_comet_file @31
33 | get_ps1996_position @32
34 | green_sidereal_time @33
35 | invert_orthonormal_matrix @34
36 | j2000_to_galactic_matrix @35
37 | load_ps1996_series @36
38 | lunar_fundamentals @37
39 | lunar_lat @38
40 | lunar_lon_and_dist @39
41 | make_var_desig @40
42 | mean_obliquity @41
43 | nutation @42
44 | polar3_to_cartesian @43
45 | precess_pt @44
46 | precess_ra_dec @45
47 | precess_vector @46
48 | pre_spin_matrix @47
49 | ra_dec_to_galactic @48
50 | refraction @49
51 | reset_td_minus_dt_string @50
52 | reverse_refraction @51
53 | reverse_saasta_refraction @52
54 | rotate_vector @53
55 | saasta_refraction @54
56 | setup_ecliptic_precession @55
57 | setup_elems_from_ast_file @56
58 | setup_precession @57
59 | set_brightness_params @58
60 | set_chinese_calendar_data @59
61 | set_identity_matrix @60
62 | set_month_name @61
63 | spin_matrix @62
64 | td_minus_ut @63
65 | unload_ps1996_series @64
66 | elements_in_mpc_format @65
67 | decimal_day_to_dmy @66
68 | td_minus_utc @67
69 | j2000_to_supergalactic_matrix @68
70 | supergalactic_to_ra_dec @69
71 | ra_dec_to_supergalactic @70
72 | integrated_refraction @71
73 | reverse_integrated_refraction @72
74 | reverse_dist_and_posn_ang @73
75 | split_time @74
76 | get_time_from_string @75
77 | equatorial_to_ecliptic @76
78 | ecliptic_to_equatorial @77
79 | vector3_length @78
80 | calc_triton_loc @79
81 | vector_cross_product @80
82 | full_ctimel @81
83 | get_time_from_stringl @82
84 | setup_precession_with_nutation @83
85 | setup_precession_with_nutation_eops @84
86 | get_earth_orientation_params @85
87 | load_earth_orientation_params @86
88 | load_cospar_file @87
89 | tdb_minus_tdt @88
90 | split_timel @89
91 | set_day_of_week_name @90
92 | extract_date_from_mpc_report @91
93 | extract_sof_data @92
94 | get_mpc_code_info @93
95 | get_ra_dec_from_mpc_report @94
96 | lat_alt_to_parallax @95
97 | planet_axis_ratio @96
98 | point_to_ellipse @97
99 | is_valid_mpc_code @98
100 | byte_code_to_net_name @99
101 | net_name_to_byte_code @100
102 | create_mpc_packed_desig @101
103 | init_ades2mpc @102
104 | free_ades2mpc_context @103
105 | xlate_ades2mpc @104
106 | xlate_ades2mpc_in_place @105
107 | fgets_with_ades_xlation @106
108 | find_moid_full @107
109 | mutant_hex_char_to_int @108
110 | int_to_mutant_hex_char @109
111 | unpack_mpc_desig @110
112 |
--------------------------------------------------------------------------------
/themis.cpp:
--------------------------------------------------------------------------------
1 | /* Code to convert THEMIS ephemerides such as those at
2 |
3 | http://soleil.ssl.berkeley.edu/ground_systems/products/THEMIS/THEMIS_D/2019_041/THEMIS_D.2019_041.OEM_CARA
4 |
5 | into the sort of state vectors that Find_Orb would emit, in preparation
6 | for making TLEs using eph2tle (see my Find_Orb repo on GitHub).
7 |
8 | The conversion is fairly straightforward. The input files give an 'object
9 | ID' equal to the NORAD catalogue number, from which we can get the international
10 | (YYYY-NNNA) designation. We get a start and stop time in Gregorian calendar form.
11 | Positions are given at one-minute intervals; we take every 'out_freq' line and
12 | output it.
13 |
14 | The resulting TLEs tend to cover about 18 days; 'them_cat' can then be
15 | used to concatenate Themis TLE sets. */
16 |
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include "watdefs.h"
22 | #include "date.h"
23 |
24 | static void error_exit( const char *message)
25 | {
26 | if( message)
27 | fprintf( stderr, "%s\n", message);
28 | fprintf( stderr, "'themis' requires the name of a THEMIS-A, D, or E ephemeris file as\n"
29 | "a command-line argument. Output defaults to stdout.\n");
30 | exit( -1);
31 | }
32 |
33 | /* I really should use getopt() or a portable variant. However, this has
34 | been sufficiently effective thus far... */
35 |
36 | static const char *get_arg( const int argc, const char **argv, const int idx)
37 | {
38 | if( argv[idx][2] || idx == argc - 1)
39 | return( argv[idx] + 2);
40 | else
41 | return( argv[idx + 1]);
42 | }
43 |
44 | /* JD 2454101.5 = 2007 Jan 1. The THEMIS satellites were launched */
45 | /* early that year. We shouldn't see ephems before this date. */
46 | #define MIN_JD 2454101.5
47 |
48 | int main( const int argc, const char **argv)
49 | {
50 | double jd_start = 0., jd_end = 0.;
51 | char buff[200];
52 | FILE *ifile, *ofile = stdout;
53 | int output_line = 0, norad_id = 0, out_freq = 144, i;
54 |
55 | if( argc < 2)
56 | error_exit( NULL);
57 | ifile = fopen( argv[1], "rb");
58 | if( !ifile)
59 | {
60 | fprintf( stderr, "Couldn't open '%s' ", argv[1]);
61 | perror( NULL);
62 | error_exit( NULL);
63 | }
64 | for( i = 2; i < argc; i++)
65 | if( argv[i][0] == '-')
66 | {
67 | const char *arg = get_arg( argc, argv, i);
68 |
69 | assert( arg);
70 | switch( argv[i][1])
71 | {
72 | case 'f':
73 | out_freq = atoi( arg);
74 | if( !out_freq || (1440 % out_freq))
75 | error_exit( "The output frequency must be a factor of 1440.\n");
76 | break;
77 | case 'o':
78 | ofile = fopen( arg, "wb");
79 | if( !ofile)
80 | {
81 | fprintf( stderr, "Couldn't open '%s ", arg);
82 | perror( NULL);
83 | error_exit( NULL);
84 | }
85 | break;
86 | default:
87 | fprintf( stderr, "Unrecognized parameter '%s ", argv[i]);
88 | error_exit( NULL);
89 | }
90 | }
91 | while( fgets( buff, sizeof( buff), ifile))
92 | {
93 | if( !memcmp( buff, "OBJECT_ID", 9))
94 | norad_id = atoi( buff + 23);
95 | if( !memcmp( buff, "START_TIM", 9))
96 | jd_start = get_time_from_string( 0., buff + 23, FULL_CTIME_YMD, NULL);
97 | if( !memcmp( buff, "STOP_TIME", 9))
98 | jd_end = get_time_from_string( 0., buff + 23, FULL_CTIME_YMD, NULL);
99 | if( buff[4] == '-' && buff[7] == '-' && buff[10] == 'T' && buff[13] == ':')
100 | {
101 | if( !output_line)
102 | {
103 | int intl_letter = 0;
104 |
105 | assert( jd_start > MIN_JD);
106 | assert( jd_end > MIN_JD);
107 | assert( norad_id);
108 | if( norad_id >= 30580 && norad_id <= 30582)
109 | intl_letter = 'A' + norad_id - 30580;
110 | if( norad_id == 30797 || norad_id == 30798)
111 | intl_letter = 'D' + norad_id - 30797;
112 | assert( intl_letter);
113 | /* '-1,149597870.7,86400' = coords are mean
114 | equatorial of date, in km and km/s. */
115 |
116 | fprintf( ofile, "%f %f %d -1,149597870.7,86400 (500) Geocentric: ",
117 | jd_start, (double)out_freq / 1440.,
118 | (int)( jd_end - jd_start) * 1440 / out_freq);
119 | fprintf( ofile, "NORAD %d = 2007-004%c = THEMIS %c\n",
120 | norad_id, intl_letter, intl_letter);
121 | }
122 | if( !(output_line % out_freq))
123 | fprintf( ofile, "%f %s", jd_start + (double)output_line / 1440., buff + 24);
124 | output_line++;
125 | }
126 | }
127 | fclose( ifile);
128 | assert( jd_start > MIN_JD);
129 | assert( jd_end > MIN_JD);
130 | fprintf( ofile, "\nCreated from 'themis.cpp' (q.v.)\n");
131 | full_ctime( buff, jd_start, CALENDAR_JULIAN_GREGORIAN);
132 | fprintf( ofile, "Ephemeris start: %s\n", buff);
133 |
134 | full_ctime( buff, jd_end, CALENDAR_JULIAN_GREGORIAN);
135 | fprintf( ofile, "Ephemeris end: %s\n", buff);
136 | if( ofile != stdout)
137 | fclose( ofile);
138 | return( 0);
139 | }
140 |
--------------------------------------------------------------------------------
/pluto.cpp:
--------------------------------------------------------------------------------
1 | /* pluto.cpp: functions for Pluto coordinates from Meeus theory
2 |
3 | Copyright (C) 2010, Project Pluto
4 |
5 | This program is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU General Public License
7 | as published by the Free Software Foundation; either version 2
8 | of the License, or (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, write to the Free Software
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 | 02110-1301, USA. */
19 |
20 | #include
21 | #include
22 | #include
23 | #include "watdefs.h"
24 | #include "lunar.h"
25 |
26 | #define PI 3.1415926535897932384626433832795028841971693993751058209749445923
27 | #define N_COEFFS 36
28 | #define COEFFS struct coeffs
29 |
30 | #pragma pack( 1)
31 | COEFFS
32 | {
33 | signed char j, s, p, dummy_to_maintain_alignment;
34 | int16_t lon_a, lon_b, lat_a, lat_b, rad_a, rad_b;
35 | };
36 | #pragma pack( )
37 |
38 | /*
39 | Lifted from p 247, Meeus, Astro Algorithms. Note that this provides
40 | excellent accuracy for years 1885-2099, but is not really intended
41 | for use outside that range. NOTE that this will fail on big-Endian
42 | machines, and on some little-Endians that require byte alignment.
43 | Let me know if you have such a machine. The fix is simple, but I'm
44 | reluctant to try it without a means of verifying that it works. */
45 |
46 | int DLL_FUNC calc_pluto_loc( const void FAR *data, double DLLPTR *loc,
47 | const double t, const long precision)
48 | {
49 | double lat, lon, r, j, s, p, cosine, sine, arg;
50 | int i, prec = (int)precision;
51 | COEFFS FAR *tptr;
52 | int32_t FAR *long_coeffs = (int32_t FAR *)((char FAR *)data + 58610U);
53 | COEFFS FAR *coeffs = (COEFFS FAR *)(long_coeffs + 42);
54 |
55 | /* assume t in julian centuries from J2000.0 */
56 | j = 34.35 + 3034.9057 * t; /* jupiter's mean longitude */
57 | s = 50.08 + 1222.1138 * t; /* saturn's mean longitude */
58 | p = 238.96 + 144.9600 * t; /* pluto's mean longitude */
59 | j *= PI / 180.;
60 | s *= PI / 180.;
61 | p *= PI / 180.;
62 | lon = 238.956785 + 144.96 * t;
63 | lat = -3.908202;
64 | r = 407.247248; /* temporarily in tenths of AUs; fixed at the end */
65 | for( i = 0; i < 7; i++)
66 | {
67 | int32_t FAR *ltptr;
68 |
69 | if( i == 6)
70 | arg = j - p;
71 | else
72 | arg = (double)(i + 1) * p;
73 | cosine = cos( arg) * 1.e-6;
74 | sine = sin( arg) * 1.e-6;
75 | ltptr = long_coeffs + (i * 6);
76 | lon += (double)ltptr[0] * sine + (double)ltptr[1] * cosine;
77 | lat += (double)ltptr[2] * sine + (double)ltptr[3] * cosine;
78 | r += (double)ltptr[4] * sine + (double)ltptr[5] * cosine;
79 | }
80 | tptr = coeffs;
81 | for( i = 0; i < N_COEFFS; i++, tptr++)
82 | if( abs( tptr->lon_a) > prec || abs( tptr->lon_b) > prec ||
83 | abs( tptr->lat_a) > prec || abs( tptr->lat_b) > prec ||
84 | abs( tptr->rad_a) > prec || abs( tptr->rad_b) > prec)
85 | {
86 | if( !tptr->j)
87 | arg = 0.;
88 | else
89 | arg = ((tptr->j == 1) ? j : j * (double)tptr->j);
90 | if( tptr->s < 0)
91 | arg -= (tptr->s == -1) ? s : s + s;
92 | if( tptr->s > 0)
93 | arg += (tptr->s == 1) ? s : s + s;
94 | if( tptr->p)
95 | arg += p * (double)tptr->p;
96 | cosine = cos( arg) * 1.e-6;
97 | sine = sin( arg) * 1.e-6;
98 | lon += sine * (double)tptr->lon_a + cosine * (double)tptr->lon_b;
99 | lat += sine * (double)tptr->lat_a + cosine * (double)tptr->lat_b;
100 | r += sine * (double)tptr->rad_a + cosine * (double)tptr->rad_b;
101 | }
102 | *loc++ = lon * PI / 180.; /* cvt to radians */
103 | *loc++ = lat * PI / 180.;
104 | *loc++ = r / 10.; /* convert back to units of AUs */
105 | return( 0);
106 | }
107 |
108 | #ifdef TEST_PROGRAM
109 |
110 | /* Compile as, e.g.,
111 |
112 | g++ -Wall -Wextra -pedantic -DTEST_PROGRAM -o pluto pluto.cpp */
113 |
114 | #include
115 | #include
116 | #include
117 |
118 | int main( const int argc, const char **argv)
119 | {
120 | const size_t vsop_size = 60874;
121 | FILE *ifile = fopen( "vsop.bin", "rb");
122 | char *buff = (char *)malloc( vsop_size);
123 |
124 | INTENTIONALLY_UNUSED_PARAMETER( argv);
125 | INTENTIONALLY_UNUSED_PARAMETER( argc);
126 | assert( ifile);
127 | assert( buff);
128 | if( fread( buff, 1, vsop_size, ifile) != vsop_size)
129 | fprintf( stderr, "Wrong vsop.bin file size\n");
130 | else
131 | {
132 | double loc[3];
133 | double t_cen = -0.0721834360; /* 1992 Oct 13.0 TD */
134 |
135 | calc_pluto_loc( buff, loc, t_cen, 0);
136 | printf( "Computed : %10.6f %10.6f %10.7f\n", loc[0] * 180. / PI,
137 | loc[1] * 180. / PI, loc[2]);
138 | printf( "From Meeus: 232.74009 14.58789 29.711383\n");
139 | }
140 | free( buff);
141 | fclose( ifile);
142 | return( 0);
143 | }
144 | #endif /* #ifdef TEST_PROGRAM */
145 |
--------------------------------------------------------------------------------
/uranus1.cpp:
--------------------------------------------------------------------------------
1 | /* uranus1.cpp: test code for Uranian satellite coordinate functions,
2 | linked "normally" (compare to uranus2.cpp)
3 |
4 | Copyright (C) 2010, Project Pluto
5 |
6 | This program is free software; you can redistribute it and/or
7 | modify it under the terms of the GNU General Public License
8 | as published by the Free Software Foundation; either version 2
9 | of the License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program; if not, write to the Free Software
18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 | 02110-1301, USA. */
20 |
21 | /*
22 | ** Uranus.cpp
23 | ** Functions relating to Uranus and its satellites. Written by Chris
24 | ** Marriott for SkyMap, with some modifications by me (Bill J. Gray).
25 | **
26 | ** Created: 17-JUL-98
27 | **
28 | ** $History: Uranus.cpp $
29 | **
30 | ** ***************** Version 1 *****************
31 | ** User: Chris Date: 2/10/98 Time: 6:55
32 | ** Created in $/SkyMap 4.0
33 | ** Moved from solar system DLL into main project.
34 | **
35 | ** ***************** Version 2 *****************
36 | ** User: Chris Date: 18/07/98 Time: 4:49p
37 | ** Updated in $/SkyMap 4.0/SolarSys
38 | ** New file to compute data relating to Uranus and its satellites.
39 | */
40 |
41 | #include "gust86.h"
42 |
43 | #include
44 | #include
45 | #include
46 |
47 |
48 | // UranusSatellite
49 | // Compute the positions of Uranus's satellites.
50 |
51 | #define AU_IN_KM 1.495978707e+8
52 |
53 | static void subtract_test_data( double *ivals, const int satellite,
54 | const int is_velocity)
55 | {
56 | /* Following are state vectors for all five satellites */
57 | /* for JDE 2451539.5 = 27 Dec 1999, as given by Horizons. */
58 |
59 | #ifdef COMPARE_TO_HORIZONS
60 | static const double test_data[60] = {
61 | /* X Y Z vx vy vz */
62 | 130609.219205, -63609.804468, 123914.883497,
63 | 332755.476940, 19395.593811, -339740.309375,
64 | 169031.741269, -89894.366595, 186084.712454,
65 | 299664.428730, 7278.709236, -267485.829018,
66 | -270571.386731, -33418.471015, 341847.941085,
67 | 237817.716674, -102816.931847, 177706.820567,
68 | 528174.319532, -51132.708805,-242110.833416,
69 | -100437.670099, 87763.820120, -237466.213432,
70 | -128420.756530, 15056.079281, 12341.354683,
71 | 33339.723882, -163288.106059, 552424.102310 };
72 | #else
73 | /* ...and as given by this program. If you run */
74 | /* 'uranus1 2451539.5', you should get the following. Run */
75 | /* 'uranus1 2451539.5 z', and the following will be subtracted */
76 | /* from the output, and you should get all zeroes. */
77 | static const double test_data[60] = {
78 | 130608.740570, -63609.454817, 123914.157536,
79 | 332753.924857, 19395.739133, -339739.097154,
80 | 169031.139042, -89894.351535, 186085.561827,
81 | 299665.211058, 7278.266868, -267484.726136,
82 | -270565.130051, -33419.941877, 341847.964177,
83 | 237818.078944, -102815.738968, 177702.440261,
84 | 528175.409357, -51133.015840, -242110.654650,
85 | -100437.576682, 87763.875080, -237466.804419,
86 | -128422.243906, 15056.226282, 12341.164393,
87 | 33339.740820, -163282.893418, 552432.372423 };
88 | #endif
89 | int i;
90 |
91 | for( i = 0; i < 3; i++)
92 | {
93 | double test_value = test_data[satellite * 6 + is_velocity * 3 + i];
94 |
95 | test_value /= AU_IN_KM; /* cvt km to AU... */
96 | if( is_velocity)
97 | test_value /= 86400.; /* and days to seconds */
98 | ivals[i] -= test_value;
99 | }
100 | }
101 |
102 | int main( int argc, char **argv)
103 | {
104 | const int test_differences = (argc == 1 || argc == 3);
105 | const double jde = (argc == 1 ? 2451539.5 : atof( argv[1]));
106 | int nSat; // loop counter
107 | const char *sat_names[5] = {
108 | "Ariel", "Umbriel", "Titania", "Oberon", "Miranda" };
109 |
110 | // Process each satellite in turn.
111 |
112 | for (nSat=0; nSat<5; nSat++)
113 | {
114 | double dRect[6]; // satellite coordinates
115 |
116 | // Retrieve the coordinates of the satellite relative to the
117 | // centre of Saturn. These are equatorial coordinates for the
118 | // mean ecliptic and epoch of J2000.0. Positions in AU,
119 | // velocities in AU/second. Printed out in km and km/s.
120 |
121 | gust86_posn( jde, nSat, dRect );
122 | if( test_differences)
123 | subtract_test_data( dRect, nSat, 0);
124 | printf( "%d %-8s: %14.6f %14.6f %14.6f\n", nSat, sat_names[nSat],
125 | dRect[0] * AU_IN_KM,
126 | dRect[1] * AU_IN_KM,
127 | dRect[2] * AU_IN_KM);
128 | if( test_differences)
129 | subtract_test_data( dRect + 3, nSat, 1);
130 | printf( " %14.6f %14.6f %14.6f\n",
131 | dRect[3] * AU_IN_KM,
132 | dRect[4] * AU_IN_KM,
133 | dRect[5] * AU_IN_KM);
134 | }
135 | return( 0);
136 | }
137 |
--------------------------------------------------------------------------------