source: Sophya/trunk/SophyaExt/XephemAstroLib/dbfmt.c@ 2932

Last change on this file since 2932 was 2818, checked in by cmv, 20 years ago

Update de Xephem 3.7 cmv 21/08/2005

File size: 24.6 KB
RevLine 
[1457]1/* code to convert between .edb format and an Obj */
2
3#include <stdio.h>
4#include <ctype.h>
5#include <math.h>
6#include <stdlib.h>
7#include <string.h>
8
9#include "astro.h"
10#include "preferences.h"
11
12
[2551]13int get_fields (char *s, int delim, char *fields[]);
[1457]14
15#define MAXDBLINE 256 /* longest allowed db line */
16
17#define FLDSEP ',' /* major field separator */
18#define SUBFLD '|' /* subfield separator */
19#define MAXFLDS 20 /* must be more than on any expected line */
20
[2551]21static char *enm (char *flds[MAXFLDS]);
22static int crack_f (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
23static int crack_e (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
24static int crack_h (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
25static int crack_p (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
26static int crack_E (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
27static int crack_P (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
28static int crack_B (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
29static int crack_name (Obj *op, char *flds[MAXFLDS], int nf,
30 char nm[][MAXNM], int nnm);
31static void crack_year (char *bp, double *p);
32static void crack_okdates (char *fld, float *startok, float *endok);
33static int get_okdates (char *lp, float *sp, float *ep);
34static int tle_sum (char *l);
35static double tle_fld (char *l, int from, int thru);
36static double tle_expfld (char *l, int start);
37static void write_f (Obj *op, char lp[]);
38static void write_e (Obj *op, char lp[]);
39static void write_h (Obj *op, char lp[]);
40static void write_p (Obj *op, char lp[]);
41static void write_E (Obj *op, char lp[]);
42static void write_P (Obj *op, char lp[]);
43static void write_B (Obj *op, char lp[]);
[1457]44
45/* crack the given .edb database line into op.
46 * if ok
[2551]47 * return number of names in nm[], or 1 if nm == NULL
[1457]48 * else
49 * if whynot
50 * if not even a candidate
51 * set whynot[0] = '\0'
52 * else
53 * fill whynot with reason message.
54 * return -1
[2551]55 * only the first name is stored in op, all names (up to nnm) are in nm[], or
56 * ignored if nm == NULL.
[1457]57 */
58int
[2551]59db_crack_line (char s[], Obj *op, char nm[][MAXNM], int nnm, char whynot[])
[1457]60{
[2551]61 char copy[MAXDBLINE]; /* work copy; leave s untouched */
[1457]62 char *flds[MAXFLDS]; /* point to each field for easy reference */
[2551]63 int nf;
[1457]64 int i;
65
[2551]66 /* init no response */
67 if (whynot)
68 whynot[0] = '\0';
69
[1457]70 /* basic initial check */
[2551]71 if (dbline_candidate (s) < 0)
[1457]72 return (-1);
73
74 /* do all the parsing on a copy */
75 (void) strcpy (copy, s);
76 i = strlen(copy);
77 if (copy[i-1] == '\n')
78 copy[i-1] = '\0';
79
80 /* parse into main fields */
81 nf = get_fields (copy, FLDSEP, flds);
82
83 /* need at least 2: name and type */
84 if (nf < 2) {
85 if (whynot)
[2551]86 sprintf (whynot, "Bogus: %s", s);
[1457]87 return (-1);
88 }
89
90 /* switch out on type of object - the second field */
91 switch (flds[1][0]) {
[2551]92
93 case 'f':
94 if (crack_f (op, flds, nf, whynot) < 0)
[1457]95 return (-1);
[2551]96 break;
97
98 case 'e':
99 if (crack_e (op, flds, nf, whynot) < 0)
[1457]100 return (-1);
101 break;
102
[2551]103 case 'h':
104 if (crack_h (op, flds, nf, whynot) < 0)
[1457]105 return (-1);
106 break;
107
[2551]108 case 'p':
109 if (crack_p (op, flds, nf, whynot) < 0)
[1457]110 return (-1);
111 break;
112
[2551]113 case 'B':
114 if (crack_B (op, flds, nf, whynot) < 0)
[1457]115 return (-1);
116 break;
117
[2551]118 case 'E':
119 if (crack_E (op, flds, nf, whynot) < 0)
[1457]120 return (-1);
121 break;
122
123 case 'P':
[2551]124 if (crack_P (op, flds, nf, whynot) < 0)
125 return (-1);
126 break;
[1457]127
128 default:
129 if (whynot)
[2551]130 sprintf (whynot, "%s: Unknown type %c for %s", enm(flds),
131 flds[1][0], flds[0]);
[1457]132 return (-1);
133 }
134
[2551]135 return (crack_name (op, flds, nf, nm, nnm));
[1457]136}
137
[2551]138/* write the given Obj in .edb format to lp[].
139 * we do _not_ include a trailing '\n'.
140 */
141void
142db_write_line (Obj *op, char lp[])
[1457]143{
[2551]144 int priorpref;
[1457]145
[2551]146 /* .edb format always uses MDY.
147 * N.B. must restore old value before returning from here!
148 */
149 priorpref = pref_set (PREF_DATE_FORMAT, PREF_MDY);
[1457]150
[2551]151 switch (op->o_type) {
152 case FIXED:
153 write_f (op, lp);
154 break;
[1457]155
[2551]156 case BINARYSTAR:
157 write_B (op, lp);
158 break;
[1457]159
[2551]160 case ELLIPTICAL:
161 write_e (op, lp);
162 break;
[1457]163
[2551]164 case HYPERBOLIC:
165 write_h (op, lp);
166 break;
[1457]167
[2551]168 case PARABOLIC:
169 write_p (op, lp);
170 break;
171
172 case EARTHSAT:
173 write_E (op, lp);
174 break;
175
176 case PLANET:
177 write_P (op, lp);
178 break;
179
180 default:
181 printf ("Unknown type for %s: %d\n", op->o_name, op->o_type);
182 abort();
183 }
184
185 /* restore date format preference */
186 (void) pref_set (PREF_DATE_FORMAT, priorpref);
[1457]187}
188
189/* given 3 lines, first of which is name and next 2 are TLE, fill op.
190 * we skip leading whitespace on all lines.
191 * we do /not/ assume the 2 TLE lines are 0 terminated, but we do reach out into
192 * each as far as 69 chars.
193 * we detect nonconformance as efficiently as possible.
194 * name ends at first '\0', '\r' or '\n'.
195 * if ok return 0 else return -1
196 */
197int
[2551]198db_tle (char *name, char *l1, char *l2, Obj *op)
[1457]199{
200 double ep;
201 int i;
202
203 /* check for correct line numbers, macthing satellite numbers and
204 * correct checksums.
205 */
206 while (isspace(*l1))
207 l1++;
208 if (*l1 != '1')
209 return (-1);
210 while (isspace(*l2))
211 l2++;
212 if (*l2 != '2')
213 return (-1);
214 if (strncmp (l1+2, l2+2, 5))
215 return (-1);
216 if (tle_sum (l1) < 0)
217 return (-1);
218 if (tle_sum (l2) < 0)
219 return (-1);
220
221 /* assume it's ok from here out */
222
223 /* fresh */
224 zero_mem ((void *)op, sizeof(ObjES));
225 op->o_type = EARTHSAT;
226
227 /* name, sans leading and trailing whitespace */
228 while (isspace(*name))
229 name++;
230 i = strcspn (name, "\r\n");
231 while (i > 0 && name[i-1] == ' ')
232 --i;
233 if (i == 0)
234 return (-1);
235 if (i > MAXNM-1)
236 i = MAXNM-1;
237 sprintf (op->o_name, "%.*s", i, name);
238
239 /* goodies from "line 1" */
240 op->es_drag = (float) tle_expfld (l1, 54);
[2551]241 op->es_decay = (float) tle_fld (l1, 34, 43);
[1457]242 i = (int) tle_fld (l1, 19, 20);
243 if (i < 57)
244 i += 100;
245 cal_mjd (1, tle_fld(l1, 21, 32), i+1900, &ep);
246 op->es_epoch = ep;
247
248 /* goodies from "line 2" */
249 op->es_n = tle_fld (l2, 53, 63);
250 op->es_inc = (float)tle_fld (l2, 9, 16);
251 op->es_raan = (float)tle_fld (l2, 18, 25);
252 op->es_e = (float)(tle_fld (l2, 27, 33) * 1e-7);
253 op->es_ap = (float)tle_fld (l2, 35, 42);
254 op->es_M = (float)tle_fld (l2, 44, 51);
255 op->es_orbit = (int)tle_fld (l2, 64, 68);
256
257 /* yes! */
258 return (0);
259}
260
[2551]261/* return 0 if op has no date range information or what it does have brackets
262 * now, else -1
[1457]263 */
[2551]264int
265dateRangeOK (Now *np, Obj *op)
[1457]266{
[2551]267 float *sp, *ep;
[1457]268
269 switch (op->o_type) {
[2551]270 case ELLIPTICAL:
271 sp = &op->e_startok;
272 ep = &op->e_endok;
[1457]273 break;
[2551]274 case HYPERBOLIC:
275 sp = &op->h_startok;
276 ep = &op->h_endok;
277 break;
278 case PARABOLIC:
279 sp = &op->p_startok;
280 ep = &op->p_endok;
281 break;
282 case EARTHSAT:
283 sp = &op->es_startok;
284 ep = &op->es_endok;
285 break;
286 default:
287 return (0);
288 }
[1457]289
[2551]290 if (*sp <= mjd && (!*ep || mjd <= *ep))
291 return (0);
292 return (-1);
293}
[1457]294
[2551]295/* given a null-terminated string, fill in fields[] with the starting addresses
296 * of each field delimited by delim or '\0'.
297 * N.B. each character matching delim is REPLACED BY '\0' IN PLACE.
298 * N.B. 0-length fields count, so even if *s=='\0' we return 1.
299 * return the number of fields.
300 */
301int
302get_fields (char *s, int delim, char *fields[])
303{
304 int n;
305 char c;
[1457]306
[2551]307 *fields = s;
308 n = 0;
309 do {
310 c = *s++;
311 if (c == delim || c == '\0') {
312 s[-1] = '\0';
313 *++fields = s;
314 n++;
[1457]315 }
[2551]316 } while (c);
[1457]317
[2551]318 return (n);
319}
[1457]320
[2551]321/* return 0 if buf qualifies as a database line worthy of a cracking
322 * attempt, else -1.
323 */
324int
325dbline_candidate (char *buf)
326{
327 char c = buf[0];
[1457]328
[2551]329 return (c == '#' || c == '!' || isspace(c) ? -1 : 0);
330}
[1457]331
[2551]332/* return 0 if TLE checksum is ok, else -1 */
333static int
334tle_sum (char *l)
335{
336 char *lastl = l + 68;
337 int sum;
[1457]338
[2551]339 for (sum = 0; l < lastl; ) {
340 char c = *l++;
341 if (c == '\0')
342 return (-1);
343 if (isdigit(c))
344 sum += c - '0';
345 else if (c == '-')
346 sum++;
[1457]347 }
348
[2551]349 return (*l - '0' == (sum%10) ? 0 : -1);
[1457]350}
351
[2551]352/* extract the given columns and return value.
353 * N.B. from and to are 1-based within l
[1457]354 */
[2551]355static double
356tle_fld (char *l, int from, int thru)
[1457]357{
[2551]358 char buf[32];
359
360 sprintf (buf, "%.*s", thru-from+1, l+from-1);
361 return (atod (buf));
362}
363
364/* extract the exponential value starting at the given column.
365 * N.B. start is 1-based within l
366 */
367static double
368tle_expfld (char *l, int start)
369{
370 char buf[32];
371 double v;
372
373 sprintf (buf, ".%.*s", 5, l+start);
374 v = atod (buf) * pow (10.0, tle_fld(l, start+6, start+7));
375 if (l[start-1] == '-')
376 v = -v;
377 return (v);
378}
379
380static int
381crack_f (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
382{
383 char *sflds[MAXFLDS];
[1457]384 double tmp;
[2551]385 int nsf;
[1457]386
[2551]387 if (nf < 5 || nf > 7) {
388 if (whynot)
[2653]389 sprintf (whynot, "%s: type f needs 5-7 fields, not %d",
390 enm(flds),nf);
[2551]391 return (-1);
392 }
[1457]393
[2551]394 zero_mem ((void *)op, sizeof(ObjF));
395 op->o_type = FIXED;
396
397 nsf = get_fields(flds[1], SUBFLD, sflds);
398 if (nsf > 1) {
399 switch (sflds[1][0]) {
[1457]400 case 'A': case 'B': case 'C': case 'D': case 'F': case 'G':
401 case 'H': case 'K': case 'J': case 'L': case 'M': case 'N':
402 case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T':
[2551]403 case 'U': case 'V': case 'Y':
404 op->f_class = sflds[1][0];
405 if (op->f_class == 'B')
406 op->f_class = 'D'; /* merge B and D since BINARYSTAR */
[1457]407 break;
408 default:
[2551]409 if (whynot)
410 sprintf (whynot, "%s: Bad f class: %c", enm(flds),
411 sflds[1][0]);
[1457]412 return (-1);
413 }
[2653]414 } else
415 op->f_class = 'T'; /* default to star-like */
[2551]416 if (nsf > 2) {
[1457]417 /* fill f_spect all the way */
[2551]418 char buf[sizeof(op->f_spect)+1];
419 memset (buf, 0, sizeof(buf));
420 sprintf (buf, "%.*s", (int)sizeof(op->f_spect), sflds[2]);
421 memcpy (op->f_spect, buf, (int)sizeof(op->f_spect));
[1457]422 }
423
[2551]424 nsf = get_fields(flds[2], SUBFLD, sflds);
425 f_scansexa (sflds[0], &tmp);
426 op->f_RA = (float) hrrad(tmp);
427 if (nsf > 1)
428 op->f_pmRA = (float) 1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
429
430 nsf = get_fields(flds[3], SUBFLD, sflds);
431 f_scansexa (sflds[0], &tmp);
432 op->f_dec = (float) degrad(tmp);
433 if (nsf > 1)
434 op->f_pmdec = (float)1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
435 if (fabs(op->f_dec) < PI/2)
436 op->f_pmRA /= cos (op->f_dec);
437
438 set_fmag (op, atod(flds[4]));
439
440 if (nf > 5 && flds[5][0]) {
441 tmp = op->f_epoch;
442 crack_year (flds[5], &tmp);
443 op->f_epoch = (float) tmp;
444 } else
445 op->f_epoch = J2000; /* default */
446
447 if (nf > 6) {
448 op->f_size = (float) atod(flds[6]);
449
450 /* optional minor axis and position angle subfields */
451 nsf = get_fields(flds[6], SUBFLD, sflds);
452 if (nsf == 3) {
453 set_ratio(op, op->s_size, atod(sflds[1]));
454 set_pa(op,degrad(atod(sflds[2])));
455 } else {
456 set_ratio(op,1,1); /* round */
457 set_pa(op,0.0);
[1457]458 }
[2551]459 }
[1457]460
[2551]461 return (0);
462}
[1457]463
[2551]464static int
465crack_e (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
466{
467 if (nf != 13 && nf != 14) {
468 if (whynot)
[2653]469 sprintf (whynot, "%s: type e needs 13 or 14 fields, not %d",
[2551]470 enm(flds), nf);
471 return (-1);
472 }
[1457]473
[2551]474 zero_mem ((void *)op, sizeof(ObjE));
475 op->o_type = ELLIPTICAL;
[1457]476
[2551]477 op->e_inc = (float) atod (flds[2]);
478 op->e_Om = (float) atod (flds[3]);
479 op->e_om = (float) atod (flds[4]);
480 op->e_a = (float) atod (flds[5]);
481 /* retired op->e_n = (float) atod (flds[6]); */
482 op->e_e = atod (flds[7]);
483 op->e_M = (float) atod (flds[8]);
484 crack_year (flds[9], &op->e_cepoch);
485 crack_okdates (flds[9], &op->e_startok, &op->e_endok);
486 crack_year (flds[10], &op->e_epoch);
487
488 /* magnitude model gk or HG(default). allow prefixes in either field */
489 op->e_mag.whichm = flds[11][0] == 'g' ? MAG_gk : MAG_HG;
490 if (isdigit(flds[11][0]))
491 op->e_mag.m1 = (float) atod(&flds[11][0]);
492 else
493 op->e_mag.m1 = (float) atod(&flds[11][1]);
494 if (isdigit(flds[12][0]))
495 op->e_mag.m2 = (float) atod(&flds[12][0]);
496 else
497 op->e_mag.m2 = (float) atod(&flds[12][1]);
498
499 if (nf == 14)
500 op->e_size = (float) atod (flds[13]);
501
502 return (0);
503}
504
505static int
506crack_h (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
507{
508 if (nf != 11 && nf != 12) {
509 if (whynot)
[2653]510 sprintf (whynot, "%s: type h needs 11 or 12 fields, not %d",
[2551]511 enm(flds), nf);
512 return (-1);
[1457]513 }
514
[2551]515 zero_mem ((void *)op, sizeof(ObjH));
516 op->o_type = HYPERBOLIC;
517
518 crack_year (flds[2], &op->h_ep);
519 crack_okdates (flds[2], &op->h_startok, &op->h_endok);
520 op->h_inc = (float) atod (flds[3]);
521 op->h_Om = (float) atod (flds[4]);
522 op->h_om = (float) atod (flds[5]);
523 op->h_e = (float) atod (flds[6]);
524 op->h_qp = (float) atod (flds[7]);
525 crack_year (flds[8], &op->h_epoch);
526 op->h_g = (float) atod (flds[9]);
527 op->h_k = (float) atod (flds[10]);
528
529 if (nf == 12)
530 op->h_size = (float) atod (flds[11]);
531
[1457]532 return (0);
533}
534
[2551]535static int
536crack_p (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
[1457]537{
[2551]538 if (nf != 10 && nf != 11) {
539 if (whynot)
[2653]540 sprintf (whynot, "%s: type p needs 10 or 11 fields, not %d",
[2551]541 enm(flds), nf);
542 return (-1);
543 }
[1457]544
[2551]545 zero_mem ((void *)op, sizeof(ObjP));
546 op->o_type = PARABOLIC;
[1457]547
[2551]548 crack_year (flds[2], &op->p_ep);
549 crack_okdates (flds[2], &op->p_startok, &op->p_endok);
550 op->p_inc = (float) atod (flds[3]);
551 op->p_om = (float) atod (flds[4]);
552 op->p_qp = (float) atod (flds[5]);
553 op->p_Om = (float) atod (flds[6]);
554 crack_year (flds[7], &op->p_epoch);
555 op->p_g = (float) atod (flds[8]);
556 op->p_k = (float) atod (flds[9]);
557
558 if (nf == 11)
559 op->p_size = (float) atod (flds[10]);
560
561 return (0);
[1457]562}
563
[2551]564static int
565crack_E (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
[1457]566{
[2551]567 if (nf != 11 && nf != 12) {
568 if (whynot)
[2653]569 sprintf (whynot, "%s: type E needs 11 or 12 fields, not %d",
[2551]570 enm(flds), nf);
571 return (-1);
572 }
573
574 zero_mem ((void *)op, sizeof(ObjES));
575 op->o_type = EARTHSAT;
576 crack_year (flds[2], &op->es_epoch);
577 crack_okdates (flds[2], &op->es_startok, &op->es_endok);
578 op->es_inc = (float) atod (flds[3]);
579 op->es_raan = (float) atod (flds[4]);
580 op->es_e = (float) atod (flds[5]);
581 op->es_ap = (float) atod (flds[6]);
582 op->es_M = (float) atod (flds[7]);
583 op->es_n = atod (flds[8]);
584 op->es_decay = (float) atod (flds[9]);
585 op->es_orbit = atoi (flds[10]);
586 if (nf == 12)
587 op->es_drag = (float) atod (flds[11]);
588
589 return (0);
590}
591
592static int
593crack_P (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
594{
595 Obj *bi;
596 int nbi;
[1457]597 int i;
598
[2551]599 nbi = getBuiltInObjs (&bi);
[1457]600
[2551]601 for (i = 0; i < nbi; i++) {
602 Obj *bop = bi + i;
603 if (is_type(bop,PLANETM) && !strcmp (flds[0], bop->o_name)) {
604 memcpy ((void *)op, bop, sizeof(ObjPl));
[1457]605 return (0);
606 }
607 }
608
[2551]609 if (whynot)
610 sprintf (whynot, "%s: Unknown planet or moon", enm(flds));
[1457]611 return (-1);
612}
613
614static int
[2551]615crack_B (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
[1457]616{
[2551]617 char *sflds[MAXFLDS];
618 double tmp;
619 int nsf;
[1457]620
[2551]621 if (nf != 7) {
622 if (whynot)
623 sprintf (whynot, "%s: B need 7 fields, not %d", enm(flds), nf);
624 return (-1);
625 }
626
627 zero_mem ((void *)op, sizeof(ObjB));
628 op->o_type = BINARYSTAR;
629
630 nsf = get_fields(flds[1], SUBFLD, sflds);
631 if (nsf > 1) {
632 switch (sflds[1][0]) {
633 case 'a': case 'c': case 'e': case 'x': case 'y': case 'o':
634 case 's': case 't': case 'u': case 'v': case 'b': case 'd':
635 case 'q': case 'r': case 'p': case 'U': case 'V': case 'Y':
636 op->f_class = sflds[1][0];
637 break;
638 default:
639 if (whynot)
640 sprintf (whynot, "%s: Bad B class: %c", enm(flds),
641 sflds[1][0]);
642 return (-1);
643 }
644 }
645 if (nsf > 2) {
646 /* fill f_spect all the way */
647 char buf[sizeof(op->f_spect)+1];
648 memset (buf, 0, sizeof(buf));
649 sprintf (buf, "%.*s", (int)sizeof(op->f_spect), sflds[2]);
650 memcpy (op->f_spect, buf, (int)sizeof(op->f_spect));
651 }
652 if (nsf > 3) {
653 /* fill b_2spect all the way */
654 char buf[sizeof(op->b_2spect)+1];
655 memset (buf, 0, sizeof(buf));
656 sprintf (buf, "%.*s", (int)sizeof(op->b_2spect), sflds[3]);
657 memcpy (op->b_2spect, buf, (int)sizeof(op->b_2spect));
658 }
659
660 nsf = get_fields(flds[2], SUBFLD, sflds);
661 f_scansexa (sflds[0], &tmp);
662 op->f_RA = (float) hrrad(tmp);
663 if (nsf > 1)
664 op->f_pmRA = (float) 1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
665
666 nsf = get_fields(flds[3], SUBFLD, sflds);
667 f_scansexa (sflds[0], &tmp);
668 op->f_dec = (float) degrad(tmp);
669 if (nsf > 1)
670 op->f_pmdec = (float)1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
671 if (fabs(op->f_dec) < PI/2)
672 op->f_pmRA /= cos (op->f_dec);
673
674 nsf = get_fields(flds[4], SUBFLD, sflds);
675 if (nsf > 0)
676 set_fmag (op, atod(sflds[0]));
677 if (nsf > 1)
678 op->b_2mag = (short)floor((atod(sflds[1]))*MAGSCALE + 0.5);
679
680 if (flds[5][0]) {
681 tmp = op->f_epoch;
682 crack_year (flds[5], &tmp);
683 op->f_epoch = (float) tmp;
684 } else
685 op->f_epoch = J2000; /* default */
686
687 nsf = get_fields(flds[6], SUBFLD, sflds);
688 if (nsf == 7) {
689 int l;
690 char c;
691
692 op->b_bo.bo_a = atod(sflds[0]);
693 op->b_bo.bo_i = atod(sflds[1]);
694 op->b_bo.bo_O = atod(sflds[2]);
695 op->b_bo.bo_e = atod(sflds[3]);
696 op->b_bo.bo_T = atod(sflds[4]);
697 op->b_bo.bo_o = atod(sflds[5]);
698 op->b_bo.bo_P = atod(sflds[6]);
699
700 /* reject some weird entries actually seen in real lists */
701 if (op->b_bo.bo_a <= 0) {
702 if (whynot)
703 sprintf (whynot, "%s: Bogus B semi major axis: %g",
704 enm(flds), op->b_bo.bo_a);
705 return (-1);
706 }
707 if (op->b_bo.bo_P <= 0) {
708 if (whynot)
709 sprintf (whynot, "%s: Bogus B period: %g", enm(flds),
710 op->b_bo.bo_P);
711 return (-1);
712 }
713
714 /* scale period */
715 l = strlen (sflds[6]);
716 c = sflds[6][l-1];
717 switch (c) {
718 case 'y': case 'Y':
719 break;
720 case 'h': case 'H':
721 op->b_bo.bo_P /= (24.0*365.25);
722 break;
723 case 'd': case 'D':
724 op->b_bo.bo_P /= 365.25;
725 break;
726 default:
727 if (c != ' ' && !isdigit(c)) {
728 if (whynot)
729 sprintf (whynot,"%s: B period suffix not Y, D or H: %c",
730 enm(flds), c);
731 return (-1);
732 }
733 }
734
735 } else if (nsf==3 || nsf==6 || nsf==9) {
736 double yr;
737 int i;
738
739 op->b_nbp = nsf/3;
740 for (i = 0; i < nsf; i += 3) {
741 tmp = 0;
742 crack_year (sflds[i+0], &tmp);
743 mjd_year (tmp, &yr);
744 op->b_bp[i/3].bp_ep = (float)yr;
745 op->b_bp[i/3].bp_sep = atod(sflds[i+1]);
746 op->b_bp[i/3].bp_pa = degrad(atod(sflds[i+2]));
747 }
748 } else {
749 if (whynot)
750 sprintf (whynot,
[2653]751 "%s: type B needs 3,6 or 7 subfields in field 7, not %d",
[2551]752 enm(flds), nsf);
753 return (-1);
754 }
755
756 return (0);
[1457]757}
758
[2551]759/* put all names in nm but load only the first into o_name */
760static int
761crack_name (Obj *op, char *flds[MAXFLDS], int nf, char nm[][MAXNM], int nnm)
762{
763 char *sflds[MAXFLDS];
764 int nsf;
765 int i;
766
767 nsf = get_fields (flds[0], SUBFLD, sflds);
768 for (i = 0; nm && i < nsf && i < nnm; i++) {
769 strncpy (nm[i], sflds[i], MAXNM);
770 nm[i][MAXNM-1] = '\0';
771 }
772 strncpy (op->o_name, sflds[0], MAXNM-1);
773 return (nsf);
774}
775
776/* simple name cracker just for error messages */
777static char *
778enm (char *flds[MAXFLDS])
779{
780 char *sflds[MAXFLDS];
781 int nsf = get_fields (flds[0], SUBFLD, sflds);
782 return (nsf > 0 ? sflds[0] : "Unknown");
783}
784
785/* given either a decimal year (xxxx[.xxx]) or a calendar (x/x/x) date
786 * convert it to an mjd and store it at *p.
[1457]787 */
788static void
[2551]789crack_year (char *bp, double *p)
[1457]790{
791 int m, y;
792 double d;
793
794 mjd_cal (*p, &m, &d, &y); /* init with current */
[2551]795 f_sscandate (bp, PREF_MDY, &m, &d, &y);
[1457]796 cal_mjd (m, d, y, p);
797}
798
[2551]799/* crack the startok and endok date fields found in several Obj types.
800 * set to 0 if blank or any problems.
[1457]801 */
[2551]802static void
803crack_okdates (char *fld, float *startok, float *endok)
[1457]804{
[2551]805 char *sflds[MAXFLDS];
[1457]806 double tmp;
[2551]807 int m, y;
808 double d;
809 int nsf;
[1457]810
[2551]811 *startok = *endok = 0;
812 nsf = get_fields(fld, SUBFLD, sflds);
813 if (nsf > 1) {
814 d = m = y = 0;
815 f_sscandate (sflds[1], PREF_MDY, &m, &d, &y);
816 cal_mjd (m, d, y, &tmp);
817 *startok = (float)tmp;
818 if (nsf > 2) {
819 d = m = y = 0;
820 f_sscandate (sflds[2], PREF_MDY, &m, &d, &y);
821 cal_mjd (m, d, y, &tmp);
822 *endok = (float)tmp;
[1457]823 }
[2551]824 }
825}
[1457]826
[2551]827/* add startok and endok to string at lp if non-zero.
828 * return number of characters added.
829 */
830static int
831get_okdates (char *lp, float *sp, float *ep)
832{
833 char *lp0 = lp;
834
835 if (*sp || *ep) {
836 *lp++ = '|';
837 if (*sp)
838 lp += fs_date (lp, *sp);
839 if (*ep) {
840 *lp++ = '|';
841 lp += fs_date (lp, *ep);
[1457]842 }
[2551]843 }
[1457]844
[2551]845 return (lp - lp0);
846}
[1457]847
[2551]848static void
849write_f (Obj *op, char lp[])
850{
851 double tmp;
[1457]852
[2551]853 lp += sprintf (lp, "%s,f", op->o_name);
854 if (op->f_class)
855 lp += sprintf (lp, "|%c", op->f_class);
856 if (op->f_spect[0])
857 lp += sprintf (lp, "|%.*s", (int)sizeof(op->f_spect), op->f_spect);
858 *lp++ = ',';
859 lp += fs_sexa (lp, radhr(op->f_RA), 2, 36000);
860 if (op->f_pmRA)
861 lp += sprintf (lp, "|%.6g",cos(op->f_dec)*op->f_pmRA/1.327e-11);
862 *lp++ = ',';
863 lp += fs_sexa (lp, raddeg(op->f_dec), 3, 3600);
864 if (op->f_pmdec)
865 lp += sprintf (lp, "|%.6g", op->f_pmdec/1.327e-11);
866 lp += sprintf (lp, ",%.2f", get_mag(op));
867 mjd_year (op->f_epoch, &tmp);
868 lp += sprintf (lp, ",%.6g", tmp); /* %.7g gives 2000.001 */
869 lp += sprintf (lp, ",%.7g", op->f_size);
870 if (op->f_size && (op->f_ratio || op->f_pa))
871 lp += sprintf (lp,"|%g|%g", op->f_size*get_ratio(op),
872 raddeg(get_pa(op)));
873}
[1457]874
[2551]875static void
876write_e (Obj *op, char lp[])
877{
878 lp += sprintf (lp, "%s,e", op->o_name);
879 lp += sprintf (lp, ",%.7g", op->e_inc);
880 lp += sprintf (lp, ",%.7g", op->e_Om);
881 lp += sprintf (lp, ",%.7g", op->e_om);
882 lp += sprintf (lp, ",%.7g", op->e_a);
883 lp += sprintf (lp, ",%.7g", 0.0); /* retired op->e_n */
884 lp += sprintf (lp, ",%.7g", op->e_e);
885 lp += sprintf (lp, ",%.7g", op->e_M);
886 *lp++ = ',';
887 lp += fs_date (lp, op->e_cepoch);
888 lp += get_okdates (lp, &op->e_startok, &op->e_endok);
889 *lp++ = ',';
890 lp += fs_date (lp, op->e_epoch);
891 if (op->e_mag.whichm == MAG_gk)
892 lp += sprintf (lp, ",g%.7g", op->e_mag.m1);
893 else if (op->e_mag.whichm == MAG_HG)
894 lp += sprintf (lp, ",H%.7g", op->e_mag.m1);
895 else
896 lp += sprintf (lp, ",%.7g", op->e_mag.m1);
897 lp += sprintf (lp, ",%.7g", op->e_mag.m2);
898 lp += sprintf (lp, ",%.7g", op->e_size);
899}
900
901static void
902write_h (Obj *op, char lp[])
903{
904 lp += sprintf (lp, "%s,h", op->o_name);
905 *lp++ = ',';
906 lp += fs_date (lp, op->h_ep);
907 lp += get_okdates (lp, &op->h_startok, &op->h_endok);
908 lp += sprintf (lp, ",%.7g", op->h_inc);
909 lp += sprintf (lp, ",%.7g", op->h_Om);
910 lp += sprintf (lp, ",%.7g", op->h_om);
911 lp += sprintf (lp, ",%.7g", op->h_e);
912 lp += sprintf (lp, ",%.7g", op->h_qp);
913 *lp++ = ',';
914 lp += fs_date (lp, op->h_epoch);
915 lp += sprintf (lp, ",%.7g", op->h_g);
916 lp += sprintf (lp, ",%.7g", op->h_k);
917 lp += sprintf (lp, ",%.7g", op->h_size);
918}
919
920static void
921write_p (Obj *op, char lp[])
922{
923 lp += sprintf (lp, "%s,p", op->o_name);
924 *lp++ = ',';
925 lp += fs_date (lp, op->p_ep);
926 lp += get_okdates (lp, &op->p_startok, &op->p_endok);
927 lp += sprintf (lp, ",%.7g", op->p_inc);
928 lp += sprintf (lp, ",%.7g", op->p_om);
929 lp += sprintf (lp, ",%.7g", op->p_qp);
930 lp += sprintf (lp, ",%.7g", op->p_Om);
931 *lp++ = ',';
932 lp += fs_date (lp, op->p_epoch);
933 lp += sprintf (lp, ",%.7g", op->p_g);
934 lp += sprintf (lp, ",%.7g", op->p_k);
935 lp += sprintf (lp, ",%.7g", op->p_size);
936}
937
938static void
939write_E (Obj *op, char lp[])
940{
941 lp += sprintf (lp, "%s,E", op->o_name);
942 *lp++ = ',';
943 lp += fs_date (lp, op->es_epoch);
944 lp += get_okdates (lp, &op->es_startok, &op->es_endok);
945 lp += sprintf (lp, ",%.7g", op->es_inc);
946 lp += sprintf (lp, ",%.7g", op->es_raan);
947 lp += sprintf (lp, ",%.7g", op->es_e);
948 lp += sprintf (lp, ",%.7g", op->es_ap);
949 lp += sprintf (lp, ",%.7g", op->es_M);
950 lp += sprintf (lp, ",%.7g", op->es_n);
951 lp += sprintf (lp, ",%.7g", op->es_decay);
952 lp += sprintf (lp, ",%d", op->es_orbit);
953 lp += sprintf (lp, ",%.7g", op->es_drag);
954}
955
956static void
957write_B (Obj *op, char lp[])
958{
959 double tmp;
960
961 lp += sprintf (lp, "%s,B", op->o_name);
962 if (op->f_class)
963 lp += sprintf (lp, "|%c", op->f_class);
964 if (op->f_spect[0])
965 lp += sprintf (lp, "|%.*s", (int)sizeof(op->f_spect), op->f_spect);
966 if (op->b_2spect[0])
967 lp += sprintf (lp, "|%.*s", (int)sizeof(op->b_2spect),op->b_2spect);
968 *lp++ = ',';
969 lp += fs_sexa (lp, radhr(op->f_RA), 2, 36000);
970 if (op->f_pmRA)
971 lp += sprintf (lp, "|%.6g",cos(op->f_dec)*op->f_pmRA/1.327e-11);
972 *lp++ = ',';
973 lp += fs_sexa (lp, raddeg(op->f_dec), 3, 3600);
974 if (op->f_pmdec)
975 lp += sprintf (lp, "|%.6g", op->f_pmdec/1.327e-11);
976 lp += sprintf (lp, ",%.2f", get_mag(op));
977 lp += sprintf (lp, "|%.2f", op->b_2mag/MAGSCALE);
978 mjd_year (op->f_epoch, &tmp);
979 lp += sprintf (lp, ",%.6g", tmp); /* %.7g gives 2000.001 */
980 if (op->b_nbp == 0) {
981 lp += sprintf (lp, ",%.6g", op->b_bo.bo_a);
982 lp += sprintf (lp, "|%.6g", op->b_bo.bo_i);
983 lp += sprintf (lp, "|%.6g", op->b_bo.bo_O);
984 lp += sprintf (lp, "|%.6g", op->b_bo.bo_e);
985 lp += sprintf (lp, "|%.6g", op->b_bo.bo_T);
986 lp += sprintf (lp, "|%.6g", op->b_bo.bo_o);
987 lp += sprintf (lp, "|%.6gy", op->b_bo.bo_P);
988 } else {
989 int i;
990
991 for (i = 0; i < op->b_nbp; i++) {
992 BinPos *bp = &op->b_bp[i];
993 lp += sprintf (lp, "%c%.6g", i==0?',':'|', bp->bp_ep);
994 lp += sprintf (lp, "|%.6g", bp->bp_sep);
995 lp += sprintf (lp, "|%.6g", raddeg(bp->bp_pa));
996 }
[1457]997 }
[2551]998}
[1457]999
[2551]1000static void
1001write_P (Obj *op, char lp[])
1002{
1003
1004 lp += sprintf (lp, "%s,P", op->o_name);
[1457]1005}
1006
1007/* For RCS Only -- Do Not Edit */
[2818]1008static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: dbfmt.c,v $ $Date: 2005-08-21 10:02:37 $ $Revision: 1.6 $ $Name: not supported by cvs2svn $"};
Note: See TracBrowser for help on using the repository browser.