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

Last change on this file since 3188 was 3111, checked in by cmv, 19 years ago

mise en conformite xephem 3.7.2 cmv 22/11/2006

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