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

Last change on this file since 3879 was 3654, checked in by cmv, 16 years ago

mise a niveau Xephem 3.7.4, cmv 16/07/2009

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