home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 March / PCWorld_2002-03_cd.bin / Software / Vyzkuste / homeplanet / TOOLS / ASTRELEM.C next >
C/C++ Source or Header  |  1997-04-04  |  8KB  |  232 lines

  1. /*
  2.  
  3.     Convert asteroid elements in the 8-line format used
  4.     by the Minor Planet Center (and in the Minor Planet
  5.     Electronic Circulars) to our CSV format.
  6.     
  7.     Designed and implemented by John Walker in October of 1994.
  8.     
  9.      (4646) Kwee
  10.     Epoch 1993 Jan. 13.0 TT = JDT 2449000.5  (M-P)          Oishi
  11.     M 220.20030              (2000.0)            P               Q
  12.     n   0.26003234     Peri.  350.28914     +0.79481320     +0.60665475
  13.     a   2.4309973      Node   332.34432     -0.55450494     +0.71559595
  14.     e   0.1921938      Incl.    1.92064     -0.24656897     +0.34625491
  15.     P   3.79           H   14.0           G   0.15
  16.     From observations at 4 oppositions, 1960-1990.  Ref. MPC 17195.
  17.               1         2         3         4         5         6         7
  18.     01234567890123456789012345678901234567890123456789012345678901234567890
  19.     
  20.     Name,Magnitude H,Magnitude G,Mean anomaly,Arg. perihelion,Long. node,Inclination,Eccentricity,Semimajor axis,Epoch (MJD)
  21.     AALTJE 677,9.70,0.15,47.68385,272.29565,272.71469,8.48713,0.04530949,2.95528649,48600
  22.  
  23.     
  24. */
  25.  
  26. #include <stdio.h>
  27. #include <ctype.h>
  28. #include <string.h>
  29. #include <math.h>
  30.  
  31. #ifdef unix
  32. #define READMODE "r"
  33. #else
  34. /*  On DOS-like systems we read the input file in binary mode
  35.     so that a ^Z embedded in a Unix mail folder (they get there
  36.     when a DOS user embeds a file in a mail message) doesn't
  37.     truncate the input.  */
  38. #define READMODE "rb"
  39. #endif
  40.  
  41. static char s[8][132];                  /* Buffer to hold complete entry */
  42.  
  43. static int rs(char *s, FILE *fp)
  44. {
  45.     if (fgets(s, 132, fp) == NULL) {
  46.         return 0;
  47.     }
  48.     while (strlen(s) > 0 && s[strlen(s) - 1] < ' ') {
  49.         s[strlen(s) - 1] = 0;
  50.     }
  51.     return 1;
  52. }
  53.  
  54. static void sc(char *b, int line, int start, int end) {
  55.     char *c = s[line];
  56.     int i, n;
  57.     
  58.     for (i = 0, n = start; n <= end; n++) {
  59.         if (c[n] == 0) {
  60.             break;
  61.         }
  62.         if (!isspace(c[n])) {
  63.             b[i++] = c[n];
  64.         }
  65.     }
  66.     b[i] = 0;
  67. }
  68.  
  69. int main(int argc, char *argv[])
  70. {
  71.     int i, p, running = 1, recov, written = 0;
  72. #define IBN 4   
  73.     static char ib[IBN][132];
  74.     FILE *fi = stdin, *fo = stdout;         /* Input and output file names */
  75. #ifdef EDITMODE
  76.     FILE *fn = NULL;
  77. #endif  
  78.     static char anum[80], aname[80], epoch[80], meanan[80], semimaj[80],
  79.         eccen[80], argperi[80], longnode[80], inclin[80], magh[80], magg[80];
  80.     
  81.     if (argc > 1) {
  82.         fi = fopen(argv[1], READMODE);      /* Input file */
  83.         if (fi == NULL) {
  84.             fprintf(stderr, "Cannot open input file %s\n", argv[1]);
  85.             return 2;
  86.         }
  87.         if (argc > 2) {
  88.             fo = fopen(argv[2], "w");       /* Output file */
  89.             if (fo == NULL) {
  90.                 fprintf(stderr, "Cannot open output file %s\n", argv[2]);
  91.                 return 2;
  92.             }
  93. #ifdef EDITMODE         
  94.             if (argc > 3) {
  95.                 fn = fopen(argv[3], "w");   /* Edit mode file */
  96.                 if (fn == NULL) {
  97.                     fprintf(stderr, "Cannot open numeric format output file %s\n", argv[3]);
  98.                     return 2;
  99.                 }
  100.             }
  101. #endif          
  102.         }
  103.     }
  104.  
  105. #ifdef EDITMODE 
  106.     fprintf(fo, "Number,Name,Number Name,Name Number,Magnitude H,Magnitude G,Mean anomaly,Arg. perihelion,Long. node,Inclination,Eccentricity,Semimajor axis,Epoch (MJD)\n");
  107.     if (fn != NULL) {
  108.         fprintf(fn, "Number,Name,Magnitude H,Magnitude G,Mean anomaly,Arg. perihelion,Long. node,Inclination,Eccentricity,Semimajor axis,Epoch (MJD)\n");
  109.     }
  110. #else
  111.     fprintf(fo, "Name,Magnitude H,Magnitude G,Mean anomaly,Arg. perihelion,Long. node,Inclination,Eccentricity,Semimajor axis,Epoch (MJD)\n");
  112. #endif
  113.     
  114.     while (1) {
  115.         char *u, *v;
  116.  
  117.         p = 0;
  118.         while (1) {
  119. #define ibm(x)  ib[(p + (IBN - (x))) % IBN]
  120.             if (!rs(ib[p], fi)) {
  121.                 running = 0;
  122.                 break;
  123.             }
  124.             if (strncmp(ib[p], "Epoch ", 6) == 0 &&
  125.                 strstr(ib[p], "TT") != NULL &&
  126.                 strchr(ib[p], '=') != NULL &&
  127.                 strstr(ib[p], "JDT") != NULL) {
  128.         
  129.                 /* MPECs for recovered objects contain an "Id." line after the name
  130.                    and before the Epoch, instead of a "From" line at the end of the
  131.                    elements.  If this is the case with these elements, move the ID
  132.                    to the end of the elements and shift everything else up one line. */
  133.                    
  134.                 recov = strncmp(ibm(1), "Id", 2) == 0;
  135.  
  136.                 strcpy(s[0], ibm(recov ? 2 : 1));
  137.                 strcpy(s[1], ib[p]);
  138.                 for (i = 0; i < 5; i++) {
  139.                     if (!rs(s[i + 2], fi)) {
  140.                         running = 0;
  141.                         break;
  142.                     }
  143.                 }
  144.                 p = (p + 1) % IBN; 
  145.                 break;
  146.             }
  147.             p = (p + 1) % IBN; 
  148.         }
  149.         if (!running) {
  150.             break;
  151.         }       
  152.         
  153.         /*  Scan asteroid number, if one has been assigned. */
  154.         
  155.         if ((u = strchr(s[0], '(')) != NULL && (v = strchr(u + 1, ')')) != NULL) {
  156.             u += 1;
  157.             *v++ = 0;
  158.             strcpy(anum, u);
  159.         } else {
  160.             v = s[0];
  161.             strcpy(anum, "(Unnamed)");
  162.         }
  163.         
  164.         /*  Scan name or other designation */
  165.         
  166.         while (isspace(*v)) {
  167.             v++;
  168.         }
  169.         while (strlen(v) > 0 && isspace(v[strlen(v) - 1])) {
  170.             v[strlen(v) - 1] = 0;   
  171.         }
  172.         strcpy(aname, v);
  173.         
  174.         /* Epoch isn't always precisely aligned in MPC postings.
  175.            Allow for some slack. */
  176.            
  177.         v = strstr(s[1], "JDT");
  178.         if (v == NULL) {
  179.             strcpy(epoch, "0");         /* Zero should get somebody's attention */
  180.         } else {
  181.             sprintf(epoch, "%g", atof(v + 3) - 2400000.5);
  182.         }
  183.         
  184.         sc(meanan, 2, 2, 15);
  185.         sc(semimaj, 4, 2, 15);
  186.         sc(eccen, 5, 2, 15);
  187.         sc(argperi, 3, 26, 35);
  188.         sc(longnode, 4, 26, 35);
  189.         sc(inclin, 5, 26, 35);
  190.         sc(magg, 6, 39, 48);
  191.         sc(magh, 6, 20, 30);
  192.         
  193.         /* Mean anomaly is blank in some MPECs, meaning zero.
  194.            Home Planet correctly interprets the blank field as zero,
  195.            but it might confuse other programs.  Replace it with 0.0 if
  196.            blank. */
  197.            
  198.         if (strlen(meanan) == 0) {
  199.             strcpy(meanan, "0.0");
  200.         }
  201.         
  202.         /* Output information in CSV format */
  203.  
  204. #ifdef EDITMODE     
  205.         fprintf(fo, "%s,%s,%s %s,%s %s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
  206.                     anum, aname, anum, aname, aname, anum, magh, magg, meanan, argperi,
  207.                     longnode, inclin, eccen, semimaj, epoch);
  208.         if (fn != NULL) {
  209.             fprintf(fn, "%s,%s %s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
  210.                         anum, anum, aname, magh, magg, meanan, argperi,
  211.                         longnode, inclin, eccen, semimaj, epoch);
  212.         }
  213. #else
  214.         fprintf(fo, "%s %s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
  215.                     aname, anum, magh, magg, meanan, argperi,
  216.                     longnode, inclin, eccen, semimaj, epoch);
  217. #endif
  218.         written++;                  
  219.     }
  220.     
  221.     fclose(fi);
  222.     fclose(fo);
  223. #ifdef EDITMODE 
  224.     if (fn != NULL) {
  225.         fclose(fn);
  226.     }
  227. #endif
  228.     fprintf(stderr, "%d record%s written.\n", written, written == 1 ? "" : "s");        
  229.     
  230.     return 0;
  231. }
  232.