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

Last change on this file since 2643 was 2643, checked in by cmv, 21 years ago

update pour version 3.6.3 Xephem cmv 17/01/04

File size: 24.5 KB
Line 
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
13int get_fields (char *s, int delim, char *fields[]);
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
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[]);
44
45/* crack the given .edb database line into op.
46 * if ok
47 * return number of names in nm[], or 1 if nm == NULL
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
55 * only the first name is stored in op, all names (up to nnm) are in nm[], or
56 * ignored if nm == NULL.
57 */
58int
59db_crack_line (char s[], Obj *op, char nm[][MAXNM], int nnm, char whynot[])
60{
61 char copy[MAXDBLINE]; /* work copy; leave s untouched */
62 char *flds[MAXFLDS]; /* point to each field for easy reference */
63 int nf;
64 int i;
65
66 /* init no response */
67 if (whynot)
68 whynot[0] = '\0';
69
70 /* basic initial check */
71 if (dbline_candidate (s) < 0)
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)
86 sprintf (whynot, "Bogus: %s", s);
87 return (-1);
88 }
89
90 /* switch out on type of object - the second field */
91 switch (flds[1][0]) {
92
93 case 'f':
94 if (crack_f (op, flds, nf, whynot) < 0)
95 return (-1);
96 break;
97
98 case 'e':
99 if (crack_e (op, flds, nf, whynot) < 0)
100 return (-1);
101 break;
102
103 case 'h':
104 if (crack_h (op, flds, nf, whynot) < 0)
105 return (-1);
106 break;
107
108 case 'p':
109 if (crack_p (op, flds, nf, whynot) < 0)
110 return (-1);
111 break;
112
113 case 'B':
114 if (crack_B (op, flds, nf, whynot) < 0)
115 return (-1);
116 break;
117
118 case 'E':
119 if (crack_E (op, flds, nf, whynot) < 0)
120 return (-1);
121 break;
122
123 case 'P':
124 if (crack_P (op, flds, nf, whynot) < 0)
125 return (-1);
126 break;
127
128 default:
129 if (whynot)
130 sprintf (whynot, "%s: Unknown type %c for %s", enm(flds),
131 flds[1][0], flds[0]);
132 return (-1);
133 }
134
135 return (crack_name (op, flds, nf, nm, nnm));
136}
137
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[])
143{
144 int priorpref;
145
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);
150
151 switch (op->o_type) {
152 case FIXED:
153 write_f (op, lp);
154 break;
155
156 case BINARYSTAR:
157 write_B (op, lp);
158 break;
159
160 case ELLIPTICAL:
161 write_e (op, lp);
162 break;
163
164 case HYPERBOLIC:
165 write_h (op, lp);
166 break;
167
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);
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
198db_tle (char *name, char *l1, char *l2, Obj *op)
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);
241 op->es_decay = (float) tle_fld (l1, 34, 43);
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
261/* return 0 if op has no date range information or what it does have brackets
262 * now, else -1
263 */
264int
265dateRangeOK (Now *np, Obj *op)
266{
267 float *sp, *ep;
268
269 switch (op->o_type) {
270 case ELLIPTICAL:
271 sp = &op->e_startok;
272 ep = &op->e_endok;
273 break;
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 }
289
290 if (*sp <= mjd && (!*ep || mjd <= *ep))
291 return (0);
292 return (-1);
293}
294
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;
306
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++;
315 }
316 } while (c);
317
318 return (n);
319}
320
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];
328
329 return (c == '#' || c == '!' || isspace(c) ? -1 : 0);
330}
331
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;
338
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++;
347 }
348
349 return (*l - '0' == (sum%10) ? 0 : -1);
350}
351
352/* extract the given columns and return value.
353 * N.B. from and to are 1-based within l
354 */
355static double
356tle_fld (char *l, int from, int thru)
357{
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];
384 double tmp;
385 int nsf;
386
387 if (nf < 5 || nf > 7) {
388 if (whynot)
389 sprintf (whynot, "%s: f needs 5-7 fields, not %d",enm(flds),nf);
390 return (-1);
391 }
392
393 zero_mem ((void *)op, sizeof(ObjF));
394 op->o_type = FIXED;
395
396 nsf = get_fields(flds[1], SUBFLD, sflds);
397 if (nsf > 1) {
398 switch (sflds[1][0]) {
399 case 'A': case 'B': case 'C': case 'D': case 'F': case 'G':
400 case 'H': case 'K': case 'J': case 'L': case 'M': case 'N':
401 case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T':
402 case 'U': case 'V': case 'Y':
403 op->f_class = sflds[1][0];
404 if (op->f_class == 'B')
405 op->f_class = 'D'; /* merge B and D since BINARYSTAR */
406 break;
407 default:
408 if (whynot)
409 sprintf (whynot, "%s: Bad f class: %c", enm(flds),
410 sflds[1][0]);
411 return (-1);
412 }
413 }
414 if (nsf > 2) {
415 /* fill f_spect all the way */
416 char buf[sizeof(op->f_spect)+1];
417 memset (buf, 0, sizeof(buf));
418 sprintf (buf, "%.*s", (int)sizeof(op->f_spect), sflds[2]);
419 memcpy (op->f_spect, buf, (int)sizeof(op->f_spect));
420 }
421
422 nsf = get_fields(flds[2], SUBFLD, sflds);
423 f_scansexa (sflds[0], &tmp);
424 op->f_RA = (float) hrrad(tmp);
425 if (nsf > 1)
426 op->f_pmRA = (float) 1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
427
428 nsf = get_fields(flds[3], SUBFLD, sflds);
429 f_scansexa (sflds[0], &tmp);
430 op->f_dec = (float) degrad(tmp);
431 if (nsf > 1)
432 op->f_pmdec = (float)1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
433 if (fabs(op->f_dec) < PI/2)
434 op->f_pmRA /= cos (op->f_dec);
435
436 set_fmag (op, atod(flds[4]));
437
438 if (nf > 5 && flds[5][0]) {
439 tmp = op->f_epoch;
440 crack_year (flds[5], &tmp);
441 op->f_epoch = (float) tmp;
442 } else
443 op->f_epoch = J2000; /* default */
444
445 if (nf > 6) {
446 op->f_size = (float) atod(flds[6]);
447
448 /* optional minor axis and position angle subfields */
449 nsf = get_fields(flds[6], SUBFLD, sflds);
450 if (nsf == 3) {
451 set_ratio(op, op->s_size, atod(sflds[1]));
452 set_pa(op,degrad(atod(sflds[2])));
453 } else {
454 set_ratio(op,1,1); /* round */
455 set_pa(op,0.0);
456 }
457 }
458
459 return (0);
460}
461
462static int
463crack_e (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
464{
465 if (nf != 13 && nf != 14) {
466 if (whynot)
467 sprintf (whynot, "%s: e needs 13 or 14 fields, not %d",
468 enm(flds), nf);
469 return (-1);
470 }
471
472 zero_mem ((void *)op, sizeof(ObjE));
473 op->o_type = ELLIPTICAL;
474
475 op->e_inc = (float) atod (flds[2]);
476 op->e_Om = (float) atod (flds[3]);
477 op->e_om = (float) atod (flds[4]);
478 op->e_a = (float) atod (flds[5]);
479 /* retired op->e_n = (float) atod (flds[6]); */
480 op->e_e = atod (flds[7]);
481 op->e_M = (float) atod (flds[8]);
482 crack_year (flds[9], &op->e_cepoch);
483 crack_okdates (flds[9], &op->e_startok, &op->e_endok);
484 crack_year (flds[10], &op->e_epoch);
485
486 /* magnitude model gk or HG(default). allow prefixes in either field */
487 op->e_mag.whichm = flds[11][0] == 'g' ? MAG_gk : MAG_HG;
488 if (isdigit(flds[11][0]))
489 op->e_mag.m1 = (float) atod(&flds[11][0]);
490 else
491 op->e_mag.m1 = (float) atod(&flds[11][1]);
492 if (isdigit(flds[12][0]))
493 op->e_mag.m2 = (float) atod(&flds[12][0]);
494 else
495 op->e_mag.m2 = (float) atod(&flds[12][1]);
496
497 if (nf == 14)
498 op->e_size = (float) atod (flds[13]);
499
500 return (0);
501}
502
503static int
504crack_h (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
505{
506 if (nf != 11 && nf != 12) {
507 if (whynot)
508 sprintf (whynot, "%s: h needs 11 or 12 fields, not %d",
509 enm(flds), nf);
510 return (-1);
511 }
512
513 zero_mem ((void *)op, sizeof(ObjH));
514 op->o_type = HYPERBOLIC;
515
516 crack_year (flds[2], &op->h_ep);
517 crack_okdates (flds[2], &op->h_startok, &op->h_endok);
518 op->h_inc = (float) atod (flds[3]);
519 op->h_Om = (float) atod (flds[4]);
520 op->h_om = (float) atod (flds[5]);
521 op->h_e = (float) atod (flds[6]);
522 op->h_qp = (float) atod (flds[7]);
523 crack_year (flds[8], &op->h_epoch);
524 op->h_g = (float) atod (flds[9]);
525 op->h_k = (float) atod (flds[10]);
526
527 if (nf == 12)
528 op->h_size = (float) atod (flds[11]);
529
530 return (0);
531}
532
533static int
534crack_p (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
535{
536 if (nf != 10 && nf != 11) {
537 if (whynot)
538 sprintf (whynot, "%s: p needs 10 or 11 fields, not %d",
539 enm(flds), nf);
540 return (-1);
541 }
542
543 zero_mem ((void *)op, sizeof(ObjP));
544 op->o_type = PARABOLIC;
545
546 crack_year (flds[2], &op->p_ep);
547 crack_okdates (flds[2], &op->p_startok, &op->p_endok);
548 op->p_inc = (float) atod (flds[3]);
549 op->p_om = (float) atod (flds[4]);
550 op->p_qp = (float) atod (flds[5]);
551 op->p_Om = (float) atod (flds[6]);
552 crack_year (flds[7], &op->p_epoch);
553 op->p_g = (float) atod (flds[8]);
554 op->p_k = (float) atod (flds[9]);
555
556 if (nf == 11)
557 op->p_size = (float) atod (flds[10]);
558
559 return (0);
560}
561
562static int
563crack_E (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
564{
565 if (nf != 11 && nf != 12) {
566 if (whynot)
567 sprintf (whynot, "%s: E needs 11 or 12 fields, not %d",
568 enm(flds), nf);
569 return (-1);
570 }
571
572 zero_mem ((void *)op, sizeof(ObjES));
573 op->o_type = EARTHSAT;
574 crack_year (flds[2], &op->es_epoch);
575 crack_okdates (flds[2], &op->es_startok, &op->es_endok);
576 op->es_inc = (float) atod (flds[3]);
577 op->es_raan = (float) atod (flds[4]);
578 op->es_e = (float) atod (flds[5]);
579 op->es_ap = (float) atod (flds[6]);
580 op->es_M = (float) atod (flds[7]);
581 op->es_n = atod (flds[8]);
582 op->es_decay = (float) atod (flds[9]);
583 op->es_orbit = atoi (flds[10]);
584 if (nf == 12)
585 op->es_drag = (float) atod (flds[11]);
586
587 return (0);
588}
589
590static int
591crack_P (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
592{
593 Obj *bi;
594 int nbi;
595 int i;
596
597 nbi = getBuiltInObjs (&bi);
598
599 for (i = 0; i < nbi; i++) {
600 Obj *bop = bi + i;
601 if (is_type(bop,PLANETM) && !strcmp (flds[0], bop->o_name)) {
602 memcpy ((void *)op, bop, sizeof(ObjPl));
603 return (0);
604 }
605 }
606
607 if (whynot)
608 sprintf (whynot, "%s: Unknown planet or moon", enm(flds));
609 return (-1);
610}
611
612static int
613crack_B (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
614{
615 char *sflds[MAXFLDS];
616 double tmp;
617 int nsf;
618
619 if (nf != 7) {
620 if (whynot)
621 sprintf (whynot, "%s: B need 7 fields, not %d", enm(flds), nf);
622 return (-1);
623 }
624
625 zero_mem ((void *)op, sizeof(ObjB));
626 op->o_type = BINARYSTAR;
627
628 nsf = get_fields(flds[1], SUBFLD, sflds);
629 if (nsf > 1) {
630 switch (sflds[1][0]) {
631 case 'a': case 'c': case 'e': case 'x': case 'y': case 'o':
632 case 's': case 't': case 'u': case 'v': case 'b': case 'd':
633 case 'q': case 'r': case 'p': case 'U': case 'V': case 'Y':
634 op->f_class = sflds[1][0];
635 break;
636 default:
637 if (whynot)
638 sprintf (whynot, "%s: Bad B class: %c", enm(flds),
639 sflds[1][0]);
640 return (-1);
641 }
642 }
643 if (nsf > 2) {
644 /* fill f_spect all the way */
645 char buf[sizeof(op->f_spect)+1];
646 memset (buf, 0, sizeof(buf));
647 sprintf (buf, "%.*s", (int)sizeof(op->f_spect), sflds[2]);
648 memcpy (op->f_spect, buf, (int)sizeof(op->f_spect));
649 }
650 if (nsf > 3) {
651 /* fill b_2spect all the way */
652 char buf[sizeof(op->b_2spect)+1];
653 memset (buf, 0, sizeof(buf));
654 sprintf (buf, "%.*s", (int)sizeof(op->b_2spect), sflds[3]);
655 memcpy (op->b_2spect, buf, (int)sizeof(op->b_2spect));
656 }
657
658 nsf = get_fields(flds[2], SUBFLD, sflds);
659 f_scansexa (sflds[0], &tmp);
660 op->f_RA = (float) hrrad(tmp);
661 if (nsf > 1)
662 op->f_pmRA = (float) 1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
663
664 nsf = get_fields(flds[3], SUBFLD, sflds);
665 f_scansexa (sflds[0], &tmp);
666 op->f_dec = (float) degrad(tmp);
667 if (nsf > 1)
668 op->f_pmdec = (float)1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
669 if (fabs(op->f_dec) < PI/2)
670 op->f_pmRA /= cos (op->f_dec);
671
672 nsf = get_fields(flds[4], SUBFLD, sflds);
673 if (nsf > 0)
674 set_fmag (op, atod(sflds[0]));
675 if (nsf > 1)
676 op->b_2mag = (short)floor((atod(sflds[1]))*MAGSCALE + 0.5);
677
678 if (flds[5][0]) {
679 tmp = op->f_epoch;
680 crack_year (flds[5], &tmp);
681 op->f_epoch = (float) tmp;
682 } else
683 op->f_epoch = J2000; /* default */
684
685 nsf = get_fields(flds[6], SUBFLD, sflds);
686 if (nsf == 7) {
687 int l;
688 char c;
689
690 op->b_bo.bo_a = atod(sflds[0]);
691 op->b_bo.bo_i = atod(sflds[1]);
692 op->b_bo.bo_O = atod(sflds[2]);
693 op->b_bo.bo_e = atod(sflds[3]);
694 op->b_bo.bo_T = atod(sflds[4]);
695 op->b_bo.bo_o = atod(sflds[5]);
696 op->b_bo.bo_P = atod(sflds[6]);
697
698 /* reject some weird entries actually seen in real lists */
699 if (op->b_bo.bo_a <= 0) {
700 if (whynot)
701 sprintf (whynot, "%s: Bogus B semi major axis: %g",
702 enm(flds), op->b_bo.bo_a);
703 return (-1);
704 }
705 if (op->b_bo.bo_P <= 0) {
706 if (whynot)
707 sprintf (whynot, "%s: Bogus B period: %g", enm(flds),
708 op->b_bo.bo_P);
709 return (-1);
710 }
711
712 /* scale period */
713 l = strlen (sflds[6]);
714 c = sflds[6][l-1];
715 switch (c) {
716 case 'y': case 'Y':
717 break;
718 case 'h': case 'H':
719 op->b_bo.bo_P /= (24.0*365.25);
720 break;
721 case 'd': case 'D':
722 op->b_bo.bo_P /= 365.25;
723 break;
724 default:
725 if (c != ' ' && !isdigit(c)) {
726 if (whynot)
727 sprintf (whynot,"%s: B period suffix not Y, D or H: %c",
728 enm(flds), c);
729 return (-1);
730 }
731 }
732
733 } else if (nsf==3 || nsf==6 || nsf==9) {
734 double yr;
735 int i;
736
737 op->b_nbp = nsf/3;
738 for (i = 0; i < nsf; i += 3) {
739 tmp = 0;
740 crack_year (sflds[i+0], &tmp);
741 mjd_year (tmp, &yr);
742 op->b_bp[i/3].bp_ep = (float)yr;
743 op->b_bp[i/3].bp_sep = atod(sflds[i+1]);
744 op->b_bp[i/3].bp_pa = degrad(atod(sflds[i+2]));
745 }
746 } else {
747 if (whynot)
748 sprintf (whynot,
749 "%s: B needs 3,6 or 7 subfields in field 7, not %d",
750 enm(flds), nsf);
751 return (-1);
752 }
753
754 return (0);
755}
756
757/* put all names in nm but load only the first into o_name */
758static int
759crack_name (Obj *op, char *flds[MAXFLDS], int nf, char nm[][MAXNM], int nnm)
760{
761 char *sflds[MAXFLDS];
762 int nsf;
763 int i;
764
765 nsf = get_fields (flds[0], SUBFLD, sflds);
766 for (i = 0; nm && i < nsf && i < nnm; i++) {
767 strncpy (nm[i], sflds[i], MAXNM);
768 nm[i][MAXNM-1] = '\0';
769 }
770 strncpy (op->o_name, sflds[0], MAXNM-1);
771 return (nsf);
772}
773
774/* simple name cracker just for error messages */
775static char *
776enm (char *flds[MAXFLDS])
777{
778 char *sflds[MAXFLDS];
779 int nsf = get_fields (flds[0], SUBFLD, sflds);
780 return (nsf > 0 ? sflds[0] : "Unknown");
781}
782
783/* given either a decimal year (xxxx[.xxx]) or a calendar (x/x/x) date
784 * convert it to an mjd and store it at *p.
785 */
786static void
787crack_year (char *bp, double *p)
788{
789 int m, y;
790 double d;
791
792 mjd_cal (*p, &m, &d, &y); /* init with current */
793 f_sscandate (bp, PREF_MDY, &m, &d, &y);
794 cal_mjd (m, d, y, p);
795}
796
797/* crack the startok and endok date fields found in several Obj types.
798 * set to 0 if blank or any problems.
799 */
800static void
801crack_okdates (char *fld, float *startok, float *endok)
802{
803 char *sflds[MAXFLDS];
804 double tmp;
805 int m, y;
806 double d;
807 int nsf;
808
809 *startok = *endok = 0;
810 nsf = get_fields(fld, SUBFLD, sflds);
811 if (nsf > 1) {
812 d = m = y = 0;
813 f_sscandate (sflds[1], PREF_MDY, &m, &d, &y);
814 cal_mjd (m, d, y, &tmp);
815 *startok = (float)tmp;
816 if (nsf > 2) {
817 d = m = y = 0;
818 f_sscandate (sflds[2], PREF_MDY, &m, &d, &y);
819 cal_mjd (m, d, y, &tmp);
820 *endok = (float)tmp;
821 }
822 }
823}
824
825/* add startok and endok to string at lp if non-zero.
826 * return number of characters added.
827 */
828static int
829get_okdates (char *lp, float *sp, float *ep)
830{
831 char *lp0 = lp;
832
833 if (*sp || *ep) {
834 *lp++ = '|';
835 if (*sp)
836 lp += fs_date (lp, *sp);
837 if (*ep) {
838 *lp++ = '|';
839 lp += fs_date (lp, *ep);
840 }
841 }
842
843 return (lp - lp0);
844}
845
846static void
847write_f (Obj *op, char lp[])
848{
849 double tmp;
850
851 lp += sprintf (lp, "%s,f", op->o_name);
852 if (op->f_class)
853 lp += sprintf (lp, "|%c", op->f_class);
854 if (op->f_spect[0])
855 lp += sprintf (lp, "|%.*s", (int)sizeof(op->f_spect), op->f_spect);
856 *lp++ = ',';
857 lp += fs_sexa (lp, radhr(op->f_RA), 2, 36000);
858 if (op->f_pmRA)
859 lp += sprintf (lp, "|%.6g",cos(op->f_dec)*op->f_pmRA/1.327e-11);
860 *lp++ = ',';
861 lp += fs_sexa (lp, raddeg(op->f_dec), 3, 3600);
862 if (op->f_pmdec)
863 lp += sprintf (lp, "|%.6g", op->f_pmdec/1.327e-11);
864 lp += sprintf (lp, ",%.2f", get_mag(op));
865 mjd_year (op->f_epoch, &tmp);
866 lp += sprintf (lp, ",%.6g", tmp); /* %.7g gives 2000.001 */
867 lp += sprintf (lp, ",%.7g", op->f_size);
868 if (op->f_size && (op->f_ratio || op->f_pa))
869 lp += sprintf (lp,"|%g|%g", op->f_size*get_ratio(op),
870 raddeg(get_pa(op)));
871}
872
873static void
874write_e (Obj *op, char lp[])
875{
876 lp += sprintf (lp, "%s,e", op->o_name);
877 lp += sprintf (lp, ",%.7g", op->e_inc);
878 lp += sprintf (lp, ",%.7g", op->e_Om);
879 lp += sprintf (lp, ",%.7g", op->e_om);
880 lp += sprintf (lp, ",%.7g", op->e_a);
881 lp += sprintf (lp, ",%.7g", 0.0); /* retired op->e_n */
882 lp += sprintf (lp, ",%.7g", op->e_e);
883 lp += sprintf (lp, ",%.7g", op->e_M);
884 *lp++ = ',';
885 lp += fs_date (lp, op->e_cepoch);
886 lp += get_okdates (lp, &op->e_startok, &op->e_endok);
887 *lp++ = ',';
888 lp += fs_date (lp, op->e_epoch);
889 if (op->e_mag.whichm == MAG_gk)
890 lp += sprintf (lp, ",g%.7g", op->e_mag.m1);
891 else if (op->e_mag.whichm == MAG_HG)
892 lp += sprintf (lp, ",H%.7g", op->e_mag.m1);
893 else
894 lp += sprintf (lp, ",%.7g", op->e_mag.m1);
895 lp += sprintf (lp, ",%.7g", op->e_mag.m2);
896 lp += sprintf (lp, ",%.7g", op->e_size);
897}
898
899static void
900write_h (Obj *op, char lp[])
901{
902 lp += sprintf (lp, "%s,h", op->o_name);
903 *lp++ = ',';
904 lp += fs_date (lp, op->h_ep);
905 lp += get_okdates (lp, &op->h_startok, &op->h_endok);
906 lp += sprintf (lp, ",%.7g", op->h_inc);
907 lp += sprintf (lp, ",%.7g", op->h_Om);
908 lp += sprintf (lp, ",%.7g", op->h_om);
909 lp += sprintf (lp, ",%.7g", op->h_e);
910 lp += sprintf (lp, ",%.7g", op->h_qp);
911 *lp++ = ',';
912 lp += fs_date (lp, op->h_epoch);
913 lp += sprintf (lp, ",%.7g", op->h_g);
914 lp += sprintf (lp, ",%.7g", op->h_k);
915 lp += sprintf (lp, ",%.7g", op->h_size);
916}
917
918static void
919write_p (Obj *op, char lp[])
920{
921 lp += sprintf (lp, "%s,p", op->o_name);
922 *lp++ = ',';
923 lp += fs_date (lp, op->p_ep);
924 lp += get_okdates (lp, &op->p_startok, &op->p_endok);
925 lp += sprintf (lp, ",%.7g", op->p_inc);
926 lp += sprintf (lp, ",%.7g", op->p_om);
927 lp += sprintf (lp, ",%.7g", op->p_qp);
928 lp += sprintf (lp, ",%.7g", op->p_Om);
929 *lp++ = ',';
930 lp += fs_date (lp, op->p_epoch);
931 lp += sprintf (lp, ",%.7g", op->p_g);
932 lp += sprintf (lp, ",%.7g", op->p_k);
933 lp += sprintf (lp, ",%.7g", op->p_size);
934}
935
936static void
937write_E (Obj *op, char lp[])
938{
939 lp += sprintf (lp, "%s,E", op->o_name);
940 *lp++ = ',';
941 lp += fs_date (lp, op->es_epoch);
942 lp += get_okdates (lp, &op->es_startok, &op->es_endok);
943 lp += sprintf (lp, ",%.7g", op->es_inc);
944 lp += sprintf (lp, ",%.7g", op->es_raan);
945 lp += sprintf (lp, ",%.7g", op->es_e);
946 lp += sprintf (lp, ",%.7g", op->es_ap);
947 lp += sprintf (lp, ",%.7g", op->es_M);
948 lp += sprintf (lp, ",%.7g", op->es_n);
949 lp += sprintf (lp, ",%.7g", op->es_decay);
950 lp += sprintf (lp, ",%d", op->es_orbit);
951 lp += sprintf (lp, ",%.7g", op->es_drag);
952}
953
954static void
955write_B (Obj *op, char lp[])
956{
957 double tmp;
958
959 lp += sprintf (lp, "%s,B", op->o_name);
960 if (op->f_class)
961 lp += sprintf (lp, "|%c", op->f_class);
962 if (op->f_spect[0])
963 lp += sprintf (lp, "|%.*s", (int)sizeof(op->f_spect), op->f_spect);
964 if (op->b_2spect[0])
965 lp += sprintf (lp, "|%.*s", (int)sizeof(op->b_2spect),op->b_2spect);
966 *lp++ = ',';
967 lp += fs_sexa (lp, radhr(op->f_RA), 2, 36000);
968 if (op->f_pmRA)
969 lp += sprintf (lp, "|%.6g",cos(op->f_dec)*op->f_pmRA/1.327e-11);
970 *lp++ = ',';
971 lp += fs_sexa (lp, raddeg(op->f_dec), 3, 3600);
972 if (op->f_pmdec)
973 lp += sprintf (lp, "|%.6g", op->f_pmdec/1.327e-11);
974 lp += sprintf (lp, ",%.2f", get_mag(op));
975 lp += sprintf (lp, "|%.2f", op->b_2mag/MAGSCALE);
976 mjd_year (op->f_epoch, &tmp);
977 lp += sprintf (lp, ",%.6g", tmp); /* %.7g gives 2000.001 */
978 if (op->b_nbp == 0) {
979 lp += sprintf (lp, ",%.6g", op->b_bo.bo_a);
980 lp += sprintf (lp, "|%.6g", op->b_bo.bo_i);
981 lp += sprintf (lp, "|%.6g", op->b_bo.bo_O);
982 lp += sprintf (lp, "|%.6g", op->b_bo.bo_e);
983 lp += sprintf (lp, "|%.6g", op->b_bo.bo_T);
984 lp += sprintf (lp, "|%.6g", op->b_bo.bo_o);
985 lp += sprintf (lp, "|%.6gy", op->b_bo.bo_P);
986 } else {
987 int i;
988
989 for (i = 0; i < op->b_nbp; i++) {
990 BinPos *bp = &op->b_bp[i];
991 lp += sprintf (lp, "%c%.6g", i==0?',':'|', bp->bp_ep);
992 lp += sprintf (lp, "|%.6g", bp->bp_sep);
993 lp += sprintf (lp, "|%.6g", raddeg(bp->bp_pa));
994 }
995 }
996}
997
998static void
999write_P (Obj *op, char lp[])
1000{
1001
1002 lp += sprintf (lp, "%s,P", op->o_name);
1003}
1004
1005/* For RCS Only -- Do Not Edit */
1006static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: dbfmt.c,v $ $Date: 2005-01-17 10:13:04 $ $Revision: 1.4 $ $Name: not supported by cvs2svn $"};
Note: See TracBrowser for help on using the repository browser.