File: sof.cpp

package info (click to toggle)
pluto-lunar 0.0~git20180825.e34c1d1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster, forky, sid, trixie
  • size: 1,584 kB
  • sloc: cpp: 18,100; makefile: 653; ansic: 368
file content (216 lines) | stat: -rw-r--r-- 6,582 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/* sof.cpp: extracts orbital elements from SOF (Standard Orbit Format)
(See https://www.projectpluto.com/orb_form.htm for an explanation)

Copyright (C) 2018, Project Pluto

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.    */

#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "watdefs.h"
#include "comets.h"
#include "date.h"

int extract_sof_data( ELEMENTS *elem, const char *buff, const char *header);

#define GAUSS_K .01720209895
#define SOLAR_GM (GAUSS_K * GAUSS_K)

#define SOF_Q_FOUND                 0x0001
#define SOF_ECC_FOUND               0x0002
#define SOF_NAME_FOUND              0x0004
#define SOF_TPERIH_FOUND            0x0008
#define SOF_TEPOCH_FOUND            0x0010
#define SOF_INCL_FOUND              0x0020
#define SOF_ASC_NODE_FOUND          0x0040
#define SOF_ARG_PERIH_FOUND         0x0080
#define SOF_ABS_MAG_FOUND           0x0100
#define SOF_SLOPE_PARAM_FOUND       0x0200

   /* If you don't have these fields,  you don't have a defined orbit. */
#define MIN_FIELDS_NEEDED (SOF_Q_FOUND | SOF_ECC_FOUND | SOF_TPERIH_FOUND \
              | SOF_INCL_FOUND | SOF_ASC_NODE_FOUND | SOF_ARG_PERIH_FOUND)

/* All dates are currently stored as YYYYMMDD[.dddd],  Gregorian. */

static double extract_jd( const char *buff)
{
   long t;
   int bytes_read;
   double rval = 0.;

   if( sscanf( buff, "%ld%n", &t, &bytes_read) == 1)
      {
      if( bytes_read == 8)    /* YYYYMMDD */
         rval = (double)dmy_to_day( t % 100, (t / 100) % 100, t / 10000,
                                    CALENDAR_GREGORIAN) - .5;
      if( buff[bytes_read] == '.')
         rval += atof( buff + bytes_read);
      }
   return( rval);
}

#define PI 3.1415926535897932384626433832795028841971693993751058209749445923

int extract_sof_data( ELEMENTS *elem, const char *buff, const char *header)
{
   int fields_found = 0, rval;

   memset( elem, 0, sizeof( ELEMENTS));
   elem->slope_param = 0.15;
   elem->gm = SOLAR_GM;
   while( *header >= ' ')
      {
      size_t i = 0;

      while( header[i] >= ' ' && header[i] != '|')
         i++;
      if( i < 2)
         return( -1);
      if( header[1] == ' ')
         {
         switch( header[0])
            {
            case 'q':
               elem->q = atof( buff);
               fields_found |= SOF_Q_FOUND;
               break;
            case 'e':
               elem->ecc = atof( buff);
               fields_found |= SOF_ECC_FOUND;
               break;
            case 'i':
               elem->incl = atof( buff) * PI / 180.;
               fields_found |= SOF_INCL_FOUND;
               break;
            case 'O':
               elem->asc_node = atof( buff) * PI / 180.;
               fields_found |= SOF_ASC_NODE_FOUND;
               break;
            case 'o':
               elem->arg_per = atof( buff) * PI / 180.;
               fields_found |= SOF_ARG_PERIH_FOUND;
               break;
            case 'H':
               elem->abs_mag = atof( buff);
               fields_found |= SOF_ABS_MAG_FOUND;
               break;
            case 'G':
               elem->slope_param = atof( buff);
               fields_found |= SOF_SLOPE_PARAM_FOUND;
               break;
            case 'C':
               elem->central_obj = atoi( buff);
               break;
            }
         }
      else if( header[2] == ' ')
         {
         switch( header[0])
            {
            case 'T':
               {
               const double jd = extract_jd( buff);

               if( header[1] == 'p')
                  {
                  elem->perih_time = jd;
                  fields_found |= SOF_TPERIH_FOUND;
                  }
               else if( header[1] == 'e')
                  {
                  elem->epoch = jd;
                  fields_found |= SOF_TEPOCH_FOUND;
                  }
               elem->q = atof( buff);
               fields_found |= SOF_Q_FOUND;
               }
               break;
            case 'O':
               elem->asc_node = atof( buff) * PI / 180.;
               fields_found |= SOF_ASC_NODE_FOUND;
               break;
            case 'o':
               elem->arg_per = atof( buff) * PI / 180.;
               fields_found |= SOF_ARG_PERIH_FOUND;
               break;
            }

         }
      if( header[i] == '|')
         i++;
      header += i;
      buff += i;
      }
   if( (fields_found & MIN_FIELDS_NEEDED) == MIN_FIELDS_NEEDED)
      {
      rval = 0;            /* success */
      derive_quantities( elem, elem->gm);
      }
   else
      {
      printf( "Got '%x'\n", (unsigned)fields_found);
      rval = -1;
      }
   return( rval);
}

#ifdef TEST_CODE

#define MAX_LEN 300

int main( const int argc, const char **argv)
{
   FILE *ifile = fopen( argv[1], "rb");
   char header_line[MAX_LEN], buff[MAX_LEN];
   char *tptr;
   size_t name_len;

   assert( ifile);
   assert( argc == 3);
   if( !fgets( header_line, sizeof( header_line), ifile))
      {
      printf( "Couldn't read header\n");
      return( -1);
      }
   tptr = strchr( header_line, '|');
   assert( tptr);
   name_len = tptr - header_line;
   while( fgets( buff, sizeof( buff), ifile))
      if( (tptr = strstr( buff, argv[2])) && tptr < buff + name_len
                  && tptr[strlen( argv[2])] == ' ')
         {
         ELEMENTS elem;
         int rval = extract_sof_data( &elem, buff, header_line);

         printf( "rval %d\n", rval);
         printf( "   Tp= %f\n", elem.perih_time);
         printf( "   q = %f\n", elem.q);
         printf( "   a = %f\n", elem.major_axis);
         printf( "   e = %f\n", elem.ecc);
         printf( "   H = %f\n", elem.abs_mag);
         printf( "   i = %f\n", elem.incl * 180. / PI);
         printf( "   Om= %f\n", elem.asc_node * 180. / PI);
         printf( "   om= %f\n", elem.arg_per * 180. / PI);
         printf( "   Epoch = %f\n", elem.epoch);
         }
   fclose( ifile);
   return( 0);
}
#endif