diff --git a/src/addwcs.c b/src/addwcs.c index 629b295..f23d4ba 100644 --- a/src/addwcs.c +++ b/src/addwcs.c @@ -13,444 +13,512 @@ #define D2R M_PI/180.0 #define R2D 180.0/M_PI -struct image { - int naxis,naxis1,naxis2,nframes; - float *zavg,*zstd,*zmax,*znum; - double ra0,de0; - float x0,y0; - float a[2],b[2]; +struct image +{ + int naxis, naxis1, naxis2, nframes; + float *zavg, *zstd, *zmax, *znum; + double ra0, de0; + float x0, y0; + float a[2], b[2]; double mjd; float *dt; }; -struct transformation { +struct transformation +{ double mjd; - double ra0,de0; - float a[3],b[3]; - float x0,y0; - float xrms,yrms,rms; + double ra0, de0; + float a[3], b[3]; + float x0, y0; + float xrms, yrms, rms; }; -struct star { - double ra,de; - float pmra,pmde; +struct star +{ + double ra, de; + float pmra, pmde; float mag; }; -struct catalog { +struct catalog +{ int n; - float x[NMAX],y[NMAX],imag[NMAX],fm[NMAX],fb[NMAX],bg[NMAX]; - double ra[NMAX],de[NMAX],vmag[NMAX]; - double rx[NMAX],ry[NMAX]; - float xres[NMAX],yres[NMAX],res[NMAX]; + float x[NMAX], y[NMAX], imag[NMAX], fm[NMAX], fb[NMAX], bg[NMAX]; + double ra[NMAX], de[NMAX], vmag[NMAX]; + double rx[NMAX], ry[NMAX]; + float xres[NMAX], yres[NMAX], res[NMAX]; int usage[NMAX]; }; -struct image read_fits(char *filename); -void forward(double ra0,double de0,double ra,double de,double *x,double *y); -void reverse(double ra0,double de0,double x,double y,double *ra,double *de); -double gmst(double mjd); -double modulo(double x,double y); -int fgetline(FILE *file,char *s,int lim); -struct catalog match_catalogs(char *pixcat,char *astcat,struct transformation t,struct image img,float rmax,float mmin); -void plot_astrometric_catalog(struct transformation t,struct image img,float mmin); -void plot_pixel_catalog(char *filename); -void lfit2d(float *x,float *y,float *z,int n,float *a); -void add_fits_keywords(struct transformation t,char *filename); -void modify_fits_keywords(struct transformation t,char *filename); -void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de); +struct image read_fits (char *filename); +void forward (double ra0, double de0, double ra, double de, double *x, + double *y); +void reverse (double ra0, double de0, double x, double y, double *ra, + double *de); +double gmst (double mjd); +double modulo (double x, double y); +int fgetline (FILE * file, char *s, int lim); +struct catalog match_catalogs (char *pixcat, char *astcat, + struct transformation t, struct image img, + float rmax, float mmin); +void plot_astrometric_catalog (struct transformation t, struct image img, + float mmin); +void plot_pixel_catalog (char *filename); +void lfit2d (float *x, float *y, float *z, int n, float *a); +void add_fits_keywords (struct transformation t, char *filename); +void modify_fits_keywords (struct transformation t, char *filename); +void precess (double mjd0, double ra0, double de0, double mjd, double *ra, + double *de); -void plot_image(struct image img,struct transformation t,struct catalog c,char *filename,float mmin) +void +plot_image (struct image img, struct transformation t, struct catalog c, + char *filename, float mmin) { int i; - float tr[]={-0.5,1.0,0.0,-0.5,0.0,1.0}; - float heat_l[]={0.0,0.2,0.4,0.6,1.0}; - float heat_r[]={0.0,0.5,1.0,1.0,1.0}; - float heat_g[]={0.0,0.0,0.5,1.0,1.0}; - float heat_b[]={0.0,0.0,0.0,0.3,1.0}; - float zmin,zmax,zavg,zstd; + float tr[] = { -0.5, 1.0, 0.0, -0.5, 0.0, 1.0 }; + float heat_l[] = { 0.0, 0.2, 0.4, 0.6, 1.0 }; + float heat_r[] = { 0.0, 0.5, 1.0, 1.0, 1.0 }; + float heat_g[] = { 0.0, 0.0, 0.5, 1.0, 1.0 }; + float heat_b[] = { 0.0, 0.0, 0.0, 0.3, 1.0 }; + float zmin, zmax, zavg, zstd; - for (i=0,zavg=0.0;i: FITS file to add/fit WCS to [required]\n"); - printf("-r : FITS file with reference WCS [required]\n"); - printf("-m : Magnitude cut-off in Tycho-2 catalog [optional; default %.1f]\n",mmin); - printf("-R : Radius cut-off for matching [optional; default %.1f pix]\n",rmin); - printf("-p Plot image and selected stars [optional]\n"); - printf("-a Add WCS keywords to input file (instead of modify) [optional]\n"); - printf("-t Track on a fixed RA/Dec (correct for field rotation)\n"); - printf("-h Print this help\n"); + printf ("-f : FITS file to add/fit WCS to [required]\n"); + printf ("-r : FITS file with reference WCS [required]\n"); + printf + ("-m : Magnitude cut-off in Tycho-2 catalog [optional; default %.1f]\n", + mmin); + printf + ("-R : Radius cut-off for matching [optional; default %.1f pix]\n", + rmin); + printf ("-p Plot image and selected stars [optional]\n"); + printf + ("-a Add WCS keywords to input file (instead of modify) [optional]\n"); + printf + ("-t Track on a fixed RA/Dec (correct for field rotation)\n"); + printf ("-h Print this help\n"); return; } // Get reference transformation -struct transformation reference(char *filename) +struct transformation +reference (char *filename) { struct transformation t; - t.mjd=atof(qfits_query_hdr(filename,"MJD-OBS")); - t.ra0=atof(qfits_query_hdr(filename,"CRVAL1")); - t.de0=atof(qfits_query_hdr(filename,"CRVAL2")); - t.x0=atof(qfits_query_hdr(filename,"CRPIX1")); - t.y0=atof(qfits_query_hdr(filename,"CRPIX2")); - t.a[0]=0.0; - t.a[1]=3600.0*atof(qfits_query_hdr(filename,"CD1_1")); - t.a[2]=3600.0*atof(qfits_query_hdr(filename,"CD1_2")); - t.b[0]=0.0; - t.b[1]=3600.0*atof(qfits_query_hdr(filename,"CD2_1")); - t.b[2]=3600.0*atof(qfits_query_hdr(filename,"CD2_2")); + t.mjd = atof (qfits_query_hdr (filename, "MJD-OBS")); + t.ra0 = atof (qfits_query_hdr (filename, "CRVAL1")); + t.de0 = atof (qfits_query_hdr (filename, "CRVAL2")); + t.x0 = atof (qfits_query_hdr (filename, "CRPIX1")); + t.y0 = atof (qfits_query_hdr (filename, "CRPIX2")); + t.a[0] = 0.0; + t.a[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_1")); + t.a[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_2")); + t.b[0] = 0.0; + t.b[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_1")); + t.b[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_2")); return t; } -void rotate(float theta,float *x,float *y) +void +rotate (float theta, float *x, float *y) { - float ct,st; - float x0,y0; - - ct=cos(theta*D2R); - st=sin(theta*D2R); - x0= *x; - y0= *y; + float ct, st; + float x0, y0; - *x=ct*x0-st*y0; - *y=st*x0+ct*y0; + ct = cos (theta * D2R); + st = sin (theta * D2R); + x0 = *x; + y0 = *y; + + *x = ct * x0 - st * y0; + *y = st * x0 + ct * y0; return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int i,j,k,l,m; + int i, j, k, l, m; struct transformation t; struct image img; - char *fitsfile=NULL,*reffile=NULL,catfile[128],calfile[128]; + char *fitsfile = NULL, *reffile = NULL, catfile[128], calfile[128]; FILE *outfile; struct catalog c; - float mmin=10.0,rmin=10.0; - double mjd0=51544.5,ra0,de0,ra1,de1; - float q0,q1; + float mmin = 10.0, rmin = 10.0; + double mjd0 = 51544.5, ra0, de0, ra1, de1; + float q0, q1; float rmsmin; - float x[NMAX],y[NMAX],rx[NMAX],ry[NMAX]; - int arg=0,plot=0,add=0,track=0; - char *env,starfile[128]; + float x[NMAX], y[NMAX], rx[NMAX], ry[NMAX]; + int arg = 0, plot = 0, add = 0, track = 0; + char *env, starfile[128]; // Environment variables - env=getenv("ST_DATADIR"); - sprintf(starfile,"%s/data/tycho2.dat",env); + env = getenv ("ST_DATADIR"); + sprintf (starfile, "%s/data/tycho2.dat", env); // Decode options - if (argc>1) { - while ((arg=getopt(argc,argv,"f:r:m:R:hpnta"))!=-1) { - switch (arg) { - - case 'f': - fitsfile=optarg; - break; - - case 'r': - reffile=optarg; - break; - - case 'm': - mmin=atof(optarg); - break; + if (argc > 1) + { + while ((arg = getopt (argc, argv, "f:r:m:R:hpnta")) != -1) + { + switch (arg) + { - case 't': - track=1; - break; + case 'f': + fitsfile = optarg; + break; - case 'R': - rmin=atof(optarg); - break; - - case 'p': - plot=1; - break; + case 'r': + reffile = optarg; + break; - case 'a': - add=1; - break; - - case 'h': - usage(mmin,rmin); - return 0; - - default: - usage(mmin,rmin); - return 0; - } - } - } else { - usage(mmin,rmin); - return 0; - } + case 'm': + mmin = atof (optarg); + break; + + case 't': + track = 1; + break; + + case 'R': + rmin = atof (optarg); + break; + + case 'p': + plot = 1; + break; + + case 'a': + add = 1; + break; + + case 'h': + usage (mmin, rmin); + return 0; + + default: + usage (mmin, rmin); + return 0; + } + } + } + else + { + usage (mmin, rmin); + return 0; + } // Check if minimum input is provided - if (fitsfile==NULL || reffile==NULL) { - usage(mmin,rmin); - return 0; - } + if (fitsfile == NULL || reffile == NULL) + { + usage (mmin, rmin); + return 0; + } // Check this is indeed a FITS file - if (is_fits_file(fitsfile)!=1) { - printf("%s is not a FITS file\n",fitsfile); - return -1 ; - } - + if (is_fits_file (fitsfile) != 1) + { + printf ("%s is not a FITS file\n", fitsfile); + return -1; + } + // Check this is indeed a FITS file - if (is_fits_file(reffile)!=1) { - printf("%s is not a FITS file\n",reffile); - return -1 ; - } + if (is_fits_file (reffile) != 1) + { + printf ("%s is not a FITS file\n", reffile); + return -1; + } // Read fits file - img=read_fits(fitsfile); - sprintf(catfile,"%s.cat",fitsfile); - sprintf(calfile,"%s.cal",fitsfile); + img = read_fits (fitsfile); + sprintf (catfile, "%s.cat", fitsfile); + sprintf (calfile, "%s.cal", fitsfile); // Read reference transformation - t=reference(reffile); + t = reference (reffile); // Correct astrometry for fixed or tracked setup - if (track==0) { - precess(mjd0,t.ra0,t.de0,t.mjd,&ra1,&de1); - ra1=modulo(ra1+gmst(img.mjd)-gmst(t.mjd),360.0); - precess(img.mjd,ra1,de1,mjd0,&t.ra0,&t.de0); - } + if (track == 0) + { + precess (mjd0, t.ra0, t.de0, t.mjd, &ra1, &de1); + ra1 = modulo (ra1 + gmst (img.mjd) - gmst (t.mjd), 360.0); + precess (img.mjd, ra1, de1, mjd0, &t.ra0, &t.de0); + } // Match catalog - c=match_catalogs(catfile,starfile,t,img,rmin,mmin); + c = match_catalogs (catfile, starfile, t, img, rmin, mmin); + - // Plot - if (plot==1) - plot_image(img,t,c,catfile,mmin); + if (plot == 1) + plot_image (img, t, c, catfile, mmin); // Do fit - if (c.n>10) { - for (l=0;l<10;l++) { - for (j=0;j<5;j++) { - // Transform - for (i=0;i 10) + { + for (l = 0; l < 10; l++) + { + for (j = 0; j < 5; j++) + { + // Transform + for (i = 0; i < c.n; i++) + forward (t.ra0, t.de0, c.ra[i], c.de[i], &c.rx[i], &c.ry[i]); + + // Select + for (i = 0, k = 0; i < c.n; i++) + { + if (c.usage[i] == 1) + { + x[k] = c.x[i]; + y[k] = c.y[i]; + rx[k] = (float) c.rx[i]; + ry[k] = (float) c.ry[i]; + k++; + } + } + // Fit + lfit2d (x, y, rx, k, t.a); + lfit2d (x, y, ry, k, t.b); + + // Move reference point + reverse (t.ra0, t.de0, t.a[0], t.b[0], &ra0, &de0); + t.ra0 = ra0; + t.de0 = de0; + } + + // Compute and plot residuals + for (i = 0, t.xrms = 0.0, t.yrms = 0.0, m = 0; i < c.n; i++) + { + if (c.usage[i] == 1) + { + c.xres[i] = + c.rx[i] - (t.a[0] + t.a[1] * c.x[i] + t.a[2] * c.y[i]); + c.yres[i] = + c.ry[i] - (t.b[0] + t.b[1] * c.x[i] + t.b[2] * c.y[i]); + + c.res[i] = + sqrt (c.xres[i] * c.xres[i] + c.yres[i] * c.yres[i]); + t.xrms += c.xres[i] * c.xres[i]; + t.yrms += c.yres[i] * c.yres[i]; + t.rms += c.xres[i] * c.xres[i] + c.yres[i] * c.yres[i]; + m++; + } + } + t.xrms = sqrt (t.xrms / (float) m); + t.yrms = sqrt (t.yrms / (float) m); + t.rms = sqrt (t.rms / (float) m); + + // Deselect outliers + for (i = 0; i < c.n; i++) + { + if (c.res[i] > 2 * t.rms) + c.usage[i] = 0; + } } - // Fit - lfit2d(x,y,rx,k,t.a); - lfit2d(x,y,ry,k,t.b); - - // Move reference point - reverse(t.ra0,t.de0,t.a[0],t.b[0],&ra0,&de0); - t.ra0=ra0; - t.de0=de0; - } - - // Compute and plot residuals - for (i=0,t.xrms=0.0,t.yrms=0.0,m=0;i2*t.rms) - c.usage[i]=0; - } } - } else { - t.xrms=0.0; - t.yrms=0.0; - t.rms=0.0; - } + else + { + t.xrms = 0.0; + t.yrms = 0.0; + t.rms = 0.0; + } // Print results - outfile=fopen(calfile,"w"); - for (i=0;i 0 && (c=fgetc(file)) != EOF && c != '\n') + int c, i = 0; + + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; @@ -459,373 +527,404 @@ int fgetline(FILE *file,char *s,int lim) } // Match catalogs -struct catalog match_catalogs(char *pixcat,char *astcat,struct transformation t,struct image img,float rmax,float mmin) +struct catalog +match_catalogs (char *pixcat, char *astcat, struct transformation t, + struct image img, float rmax, float mmin) { - int i=0,imin,j,k,np; + int i = 0, imin, j, k, np; FILE *file; char line[LIM]; struct star s; - double rx,ry,d,dx,dy; + double rx, ry, d, dx, dy; int usage[NMAX]; - float xp[NMAX],yp[NMAX],mp[NMAX],x,y,fb[NMAX],fm[NMAX],bg[NMAX]; + float xp[NMAX], yp[NMAX], mp[NMAX], x, y, fb[NMAX], fm[NMAX], bg[NMAX]; struct catalog c; - float r,rmin; + float r, rmin; // Read pixel catalog - file=fopen(pixcat,"r"); - if (file==NULL) { - printf("pixel catalog not found\n"); - exit(-1); - } - while (fgetline(file,line,LIM)>0) { - if (strstr(line,"#")!=NULL) - continue; - sscanf(line,"%f %f %f %f %f %f",&xp[i],&yp[i],&mp[i],&fb[i],&fm[i],&bg[i]); - usage[i]=1; - i++; - } - fclose(file); - np=i; + file = fopen (pixcat, "r"); + if (file == NULL) + { + printf ("pixel catalog not found\n"); + exit (-1); + } + while (fgetline (file, line, LIM) > 0) + { + if (strstr (line, "#") != NULL) + continue; + sscanf (line, "%f %f %f %f %f %f", &xp[i], &yp[i], &mp[i], &fb[i], + &fm[i], &bg[i]); + usage[i] = 1; + i++; + } + fclose (file); + np = i; // Denominator - d=t.a[1]*t.b[2]-t.a[2]*t.b[1]; + d = t.a[1] * t.b[2] - t.a[2] * t.b[1]; // Read astrometric catalog - file=fopen(astcat,"rb"); - if (file==NULL) { - printf("astrometric catalog not found\n"); - exit(-1); - } - j=0; - while (!feof(file)) { - fread(&s,sizeof(struct star),1,file); - if (s.mag>mmin) - continue; - r=acos(sin(t.de0*D2R)*sin(s.de*D2R)+cos(t.de0*D2R)*cos(s.de*D2R)*cos((t.ra0-s.ra)*D2R))*R2D; - if (r>90.0) - continue; - forward(t.ra0,t.de0,s.ra,s.de,&rx,&ry); - - dx=rx-t.a[0]; - dy=ry-t.b[0]; - x=(t.b[2]*dx-t.a[2]*dy)/d+t.x0; - y=(t.a[1]*dy-t.b[1]*dx)/d+t.y0; - - // On image - if (x>0.0 && x0.0 && y mmin) + continue; + r = + acos (sin (t.de0 * D2R) * sin (s.de * D2R) + + cos (t.de0 * D2R) * cos (s.de * D2R) * cos ((t.ra0 - s.ra) * + D2R)) * R2D; + if (r > 90.0) + continue; + forward (t.ra0, t.de0, s.ra, s.de, &rx, &ry); + + dx = rx - t.a[0]; + dy = ry - t.b[0]; + x = (t.b[2] * dx - t.a[2] * dy) / d + t.x0; + y = (t.a[1] * dy - t.b[1] * dx) / d + t.y0; + + // On image + if (x > 0.0 && x < img.naxis1 && y > 0.0 && y < img.naxis2) + { + // Loop over pixel catalog + for (i = 0; i < np; i++) + { + r = sqrt (pow (xp[i] - x, 2) + pow (yp[i] - y, 2)); + if (i == 0 || r < rmin) + { + rmin = r; + imin = i; + } + } + + // Select + if (rmin < rmax && usage[imin] == 1) + { + c.x[j] = xp[imin] - t.x0; + c.y[j] = yp[imin] - t.y0; + c.imag[j] = mp[imin]; + c.fb[j] = fb[imin]; + c.fm[j] = fm[imin]; + c.bg[j] = bg[imin]; + c.ra[j] = s.ra; + c.de[j] = s.de; + c.vmag[j] = s.mag; + c.usage[j] = 1; + usage[imin] = 0; + j++; + } + } + } + fclose (file); + c.n = j; return c; } // Plot astrometric catalog -void plot_astrometric_catalog(struct transformation t,struct image img,float mmin) +void +plot_astrometric_catalog (struct transformation t, struct image img, + float mmin) { - int i=0; + int i = 0; FILE *file; struct star s; - double rx,ry,d,r; - double ra,de; - float x,y; - char *env,starfile[128]; + double rx, ry, d, r; + double ra, de; + float x, y; + char *env, starfile[128]; // Environment variables - env=getenv("ST_DATADIR"); - sprintf(starfile,"%s/data/tycho2.dat",env); + env = getenv ("ST_DATADIR"); + sprintf (starfile, "%s/data/tycho2.dat", env); - d=t.a[1]*t.b[2]-t.a[2]*t.b[1]; + d = t.a[1] * t.b[2] - t.a[2] * t.b[1]; - file=fopen(starfile,"rb"); - while (!feof(file)) { - fread(&s,sizeof(struct star),1,file); - if (s.mag>mmin) - continue; - r=acos(sin(t.de0*D2R)*sin(s.de*D2R)+cos(t.de0*D2R)*cos(s.de*D2R)*cos((t.ra0-s.ra)*D2R))*R2D; - if (r>90.0) - continue; - forward(t.ra0,t.de0,s.ra,s.de,&rx,&ry); - x=(t.b[2]*rx-t.a[2]*ry)/d+t.x0; - y=(t.a[1]*ry-t.b[1]*rx)/d+t.y0; - if (x>0.0 && x0.0 && y mmin) + continue; + r = + acos (sin (t.de0 * D2R) * sin (s.de * D2R) + + cos (t.de0 * D2R) * cos (s.de * D2R) * cos ((t.ra0 - s.ra) * + D2R)) * R2D; + if (r > 90.0) + continue; + forward (t.ra0, t.de0, s.ra, s.de, &rx, &ry); + x = (t.b[2] * rx - t.a[2] * ry) / d + t.x0; + y = (t.a[1] * ry - t.b[1] * rx) / d + t.y0; + if (x > 0.0 && x < img.naxis1 && y > 0.0 && y < img.naxis2) + cpgpt1 (x, y, 24); + } + fclose (file); return; } // Plot pixel catalog -void plot_pixel_catalog(char *filename) +void +plot_pixel_catalog (char *filename) { - int i=0; + int i = 0; FILE *file; char line[LIM]; - float x,y,mag; + float x, y, mag; // Read catalog - file=fopen(filename,"r"); - while (fgetline(file,line,LIM)>0) { - if (strstr(line,"#")!=NULL) - continue; - sscanf(line,"%f %f %f",&x,&y,&mag); + file = fopen (filename, "r"); + while (fgetline (file, line, LIM) > 0) + { + if (strstr (line, "#") != NULL) + continue; + sscanf (line, "%f %f %f", &x, &y, &mag); - cpgpt1(x,y,4); + cpgpt1 (x, y, 4); - i++; - } - fclose(file); + i++; + } + fclose (file); return; } // Linear 2D fit -void lfit2d(float *x,float *y,float *z,int n,float *a) +void +lfit2d (float *x, float *y, float *z, int n, float *a) { - int i,j,m; + int i, j, m; double chisq; - gsl_matrix *X,*cov; - gsl_vector *yy,*w,*c; + gsl_matrix *X, *cov; + gsl_vector *yy, *w, *c; - X=gsl_matrix_alloc(n,3); - yy=gsl_vector_alloc(n); - w=gsl_vector_alloc(n); + X = gsl_matrix_alloc (n, 3); + yy = gsl_vector_alloc (n); + w = gsl_vector_alloc (n); - c=gsl_vector_alloc(3); - cov=gsl_matrix_alloc(3,3); + c = gsl_vector_alloc (3); + cov = gsl_matrix_alloc (3, 3); // Fill matrices - for(i=0;i360.0) - *ra-=360.0; + *ra = (atan2 (a, b) + z) * R2D; + *de = asin (c) * R2D; + + if (*ra < 360.0) + *ra += 360.0; + if (*ra > 360.0) + *ra -= 360.0; return; } diff --git a/src/allnight.c b/src/allnight.c index da958d9..f43d53f 100644 --- a/src/allnight.c +++ b/src/allnight.c @@ -9,385 +9,441 @@ #define LIM 384 #define D2R M_PI/180.0 #define R2D 180.0/M_PI -#define XKMPAU 149597879.691 // AU in km +#define XKMPAU 149597879.691 // AU in km -struct map { +struct map +{ int site_id; double mjd; - float saltmin,alt; - char nfd[LIM],observer[32],datadir[LIM]; - double lat,lng; + float saltmin, alt; + char nfd[LIM], observer[32], datadir[LIM]; + double lat, lng; float length; } m; -void allnight(void); -void sunpos_xyz(double,xyz_t *,double *,double *); -double modulo(double,double); -void equatorial2horizontal(double,double,double,double *,double *); -void mjd2date(double mjd,char *date); -double gmst(double mjd); -void nfd_now(char *s); -double nfd2mjd(char *date); -void get_site(int site_id); -double date2mjd(int year,int month,double day); -void usage(void); +void allnight (void); +void sunpos_xyz (double, xyz_t *, double *, double *); +double modulo (double, double); +void equatorial2horizontal (double, double, double, double *, double *); +void mjd2date (double mjd, char *date); +double gmst (double mjd); +void nfd_now (char *s); +double nfd2mjd (char *date); +void get_site (int site_id); +double date2mjd (int year, int month, double day); +void usage (void); -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int arg=0; + int arg = 0; char *env; // Default settings - strcpy(m.observer,"Unknown"); - m.site_id=0; - m.mjd=-1.0; - m.saltmin=-6.0; - m.alt=0.0; - m.lat=0.0; - m.lng=0.0; - + strcpy (m.observer, "Unknown"); + m.site_id = 0; + m.mjd = -1.0; + m.saltmin = -6.0; + m.alt = 0.0; + m.lat = 0.0; + m.lng = 0.0; + // Get default site - env=getenv("ST_DATADIR"); - if (env!=NULL) { - strcpy(m.datadir,env); - } else { - printf("ST_DATADIR environment variable not found.\n"); - } - env=getenv("ST_COSPAR"); - if (env!=NULL) { - get_site(atoi(env)); - } else { - printf("ST_COSPAR environment variable not found.\n"); - } + env = getenv ("ST_DATADIR"); + if (env != NULL) + { + strcpy (m.datadir, env); + } + else + { + printf ("ST_DATADIR environment variable not found.\n"); + } + env = getenv ("ST_COSPAR"); + if (env != NULL) + { + get_site (atoi (env)); + } + else + { + printf ("ST_COSPAR environment variable not found.\n"); + } // Get current time - nfd_now(m.nfd); - m.mjd=nfd2mjd(m.nfd); - + nfd_now (m.nfd); + m.mjd = nfd2mjd (m.nfd); + // Decode options - while ((arg=getopt(argc,argv,"t:s:S:h"))!=-1) { - switch (arg) { + while ((arg = getopt (argc, argv, "t:s:S:h")) != -1) + { + switch (arg) + { - case 't': - strcpy(m.nfd,optarg); - m.mjd=nfd2mjd(m.nfd); - break; + case 't': + strcpy (m.nfd, optarg); + m.mjd = nfd2mjd (m.nfd); + break; - case 'S': - m.saltmin=atof(optarg); - break; + case 'S': + m.saltmin = atof (optarg); + break; - case 's': - get_site(atoi(optarg)); - break; + case 's': + get_site (atoi (optarg)); + break; - case 'h': - usage(); - return 0; - break; + case 'h': + usage (); + return 0; + break; - default: - usage(); - return 0; + default: + usage (); + return 0; + } } - } - + // Compute set/rise times of sun - allnight(); + allnight (); return 0; } // Usage -void usage(void) +void +usage (void) { - printf("allnight t:s:S:\n\n"); - printf("t date/time (yyyy-mm-ddThh:mm:ss.sss) [default: now]\n"); - printf("S Minimum sun altitude\n"); - printf("s site (COSPAR)\n"); + printf ("allnight t:s:S:\n\n"); + printf ("t date/time (yyyy-mm-ddThh:mm:ss.sss) [default: now]\n"); + printf ("S Minimum sun altitude\n"); + printf ("s site (COSPAR)\n"); return; } // Convert equatorial into horizontal coordinates -void equatorial2horizontal(double mjd,double ra,double de,double *azi,double *alt) +void +equatorial2horizontal (double mjd, double ra, double de, double *azi, + double *alt) { double h; - h=gmst(mjd)+m.lng-ra; - - *azi=modulo(atan2(sin(h*D2R),cos(h*D2R)*sin(m.lat*D2R)-tan(de*D2R)*cos(m.lat*D2R))*R2D,360.0); - *alt=asin(sin(m.lat*D2R)*sin(de*D2R)+cos(m.lat*D2R)*cos(de*D2R)*cos(h*D2R))*R2D; + h = gmst (mjd) + m.lng - ra; + + *azi = + modulo (atan2 + (sin (h * D2R), + cos (h * D2R) * sin (m.lat * D2R) - + tan (de * D2R) * cos (m.lat * D2R)) * R2D, 360.0); + *alt = + asin (sin (m.lat * D2R) * sin (de * D2R) + + cos (m.lat * D2R) * cos (de * D2R) * cos (h * D2R)) * R2D; return; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Solar position -void sunpos_xyz(double mjd,xyz_t *pos,double *ra,double *de) +void +sunpos_xyz (double mjd, xyz_t * pos, double *ra, double *de) { - double jd,t,l0,m,e,c,r; - double n,s,ecl; + double jd, t, l0, m, e, c, r; + double n, s, ecl; - jd=mjd+2400000.5; - t=(jd-2451545.0)/36525.0; - l0=modulo(280.46646+t*(36000.76983+t*0.0003032),360.0)*D2R; - m=modulo(357.52911+t*(35999.05029-t*0.0001537),360.0)*D2R; - e=0.016708634+t*(-0.000042037-t*0.0000001267); - c=(1.914602+t*(-0.004817-t*0.000014))*sin(m)*D2R; - c+=(0.019993-0.000101*t)*sin(2.0*m)*D2R; - c+=0.000289*sin(3.0*m)*D2R; + jd = mjd + 2400000.5; + t = (jd - 2451545.0) / 36525.0; + l0 = modulo (280.46646 + t * (36000.76983 + t * 0.0003032), 360.0) * D2R; + m = modulo (357.52911 + t * (35999.05029 - t * 0.0001537), 360.0) * D2R; + e = 0.016708634 + t * (-0.000042037 - t * 0.0000001267); + c = (1.914602 + t * (-0.004817 - t * 0.000014)) * sin (m) * D2R; + c += (0.019993 - 0.000101 * t) * sin (2.0 * m) * D2R; + c += 0.000289 * sin (3.0 * m) * D2R; - r=1.000001018*(1.0-e*e)/(1.0+e*cos(m+c)); - n=modulo(125.04-1934.136*t,360.0)*D2R; - s=l0+c+(-0.00569-0.00478*sin(n))*D2R; - ecl=(23.43929111+(-46.8150*t-0.00059*t*t+0.001813*t*t*t)/3600.0+0.00256*cos(n))*D2R; + r = 1.000001018 * (1.0 - e * e) / (1.0 + e * cos (m + c)); + n = modulo (125.04 - 1934.136 * t, 360.0) * D2R; + s = l0 + c + (-0.00569 - 0.00478 * sin (n)) * D2R; + ecl = + (23.43929111 + + (-46.8150 * t - 0.00059 * t * t + 0.001813 * t * t * t) / 3600.0 + + 0.00256 * cos (n)) * D2R; - *ra=atan2(cos(ecl)*sin(s),cos(s))*R2D; - *de=asin(sin(ecl)*sin(s))*R2D; + *ra = atan2 (cos (ecl) * sin (s), cos (s)) * R2D; + *de = asin (sin (ecl) * sin (s)) * R2D; - pos->x=r*cos(*de*D2R)*cos(*ra*D2R)*XKMPAU; - pos->y=r*cos(*de*D2R)*sin(*ra*D2R)*XKMPAU; - pos->z=r*sin(*de*D2R)*XKMPAU; + pos->x = r * cos (*de * D2R) * cos (*ra * D2R) * XKMPAU; + pos->y = r * cos (*de * D2R) * sin (*ra * D2R) * XKMPAU; + pos->z = r * sin (*de * D2R) * XKMPAU; return; } -void allnight(void) +void +allnight (void) { int flag; xyz_t sunpos; - double ra,de,azi,alt,alt0; - double mjd,mjdrise=-1.0,mjdset=-1.0; + double ra, de, azi, alt, alt0; + double mjd, mjdrise = -1.0, mjdset = -1.0; char nfd[32]; // Find solar altitude at reference time - sunpos_xyz(m.mjd,&sunpos,&ra,&de); - equatorial2horizontal(m.mjd,ra,de,&azi,&alt); + sunpos_xyz (m.mjd, &sunpos, &ra, &de); + equatorial2horizontal (m.mjd, ra, de, &azi, &alt); // Sun below limit, find rise, then set - if (altm.saltmin && alt0<=m.saltmin) - mjdrise=mjd; - } - - if (flag==0) - flag=1; - - alt0=alt; - } - for (flag=0,mjd=m.mjd-0.5;mjd=m.saltmin) - mjdset=mjd; - } - - if (flag==0) - flag=1; - - alt0=alt; - } - // Sun above limit, find set, and rise - } else { - for (flag=0,mjd=m.mjd;mjdm.saltmin && alt0<=m.saltmin) - mjdrise=mjd; - if (alt=m.saltmin) - mjdset=mjd; - } - - if (flag==0) - flag=1; - - alt0=alt; - } - } + if (alt < m.saltmin) + { + for (flag = 0, mjd = m.mjd; mjd < m.mjd + 0.5; mjd += 1.0 / 86400) + { + sunpos_xyz (mjd, &sunpos, &ra, &de); + equatorial2horizontal (mjd, ra, de, &azi, &alt); + + if (flag != 0) + { + if (alt > m.saltmin && alt0 <= m.saltmin) + mjdrise = mjd; + } + + if (flag == 0) + flag = 1; + + alt0 = alt; + } + for (flag = 0, mjd = m.mjd - 0.5; mjd < m.mjd; mjd += 1.0 / 86400) + { + sunpos_xyz (mjd, &sunpos, &ra, &de); + equatorial2horizontal (mjd, ra, de, &azi, &alt); + + if (flag != 0) + { + if (alt < m.saltmin && alt0 >= m.saltmin) + mjdset = mjd; + } + + if (flag == 0) + flag = 1; + + alt0 = alt; + } + // Sun above limit, find set, and rise + } + else + { + for (flag = 0, mjd = m.mjd; mjd < m.mjd + 1.0; mjd += 1.0 / 86400) + { + sunpos_xyz (mjd, &sunpos, &ra, &de); + equatorial2horizontal (mjd, ra, de, &azi, &alt); + + if (flag != 0) + { + if (alt > m.saltmin && alt0 <= m.saltmin) + mjdrise = mjd; + if (alt < m.saltmin && alt0 >= m.saltmin) + mjdset = mjd; + } + + if (flag == 0) + flag = 1; + + alt0 = alt; + } + } + + m.mjd = mjdset; + mjd2date (m.mjd, m.nfd); + mjd2date (mjdrise, nfd); + printf ("%s %s\n", m.nfd, nfd); - m.mjd=mjdset; - mjd2date(m.mjd,m.nfd); - mjd2date(mjdrise,nfd); - printf("%s %s\n",m.nfd,nfd); - return; } // Compute Date from Julian Day -void mjd2date(double mjd,char *date) +void +mjd2date (double mjd, char *date) { - double f,jd,dday; - int z,alpha,a,b,c,d,e; - int year,month,day,hour,min; - float sec,x; + double f, jd, dday; + int z, alpha, a, b, c, d, e; + int year, month, day, hour, min; + float sec, x; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - dday=b-d-floor(30.6001*e)+f; - if (e<14) - month=e-1; + if (z < 2299161) + a = z; else - month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (month>2) - year=c-4716; + dday = b - d - floor (30.6001 * e) + f; + if (e < 14) + month = e - 1; else - year=c-4715; + month = e - 13; - day=(int) floor(dday); - x=24.0*(dday-day); - x=3600.*fabs(x)+0.0001; - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - hour=x; - sec=floor(1000.0*sec)/1000.0; + if (month > 2) + year = c - 4716; + else + year = c - 4715; - sprintf(date,"%04d-%02d-%02dT%02d:%02d:%02.0f",year,month,day,hour,min,sec); + day = (int) floor (dday); + x = 24.0 * (dday - day); + x = 3600. * fabs (x) + 0.0001; + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + hour = x; + sec = floor (1000.0 * sec) / 1000.0; + + sprintf (date, "%04d-%02d-%02dT%02d:%02d:%02.0f", year, month, day, hour, + min, sec); return; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } // Present nfd -void nfd_now(char *s) +void +nfd_now (char *s) { time_t rawtime; struct tm *ptm; // Get UTC time - time(&rawtime); - ptm=gmtime(&rawtime); - - sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec); - + time (&rawtime); + ptm = gmtime (&rawtime); + + sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900, + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, + ptm->tm_sec); + return; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min,sec; - double mjd,dday; + int year, month, day, hour, min, sec; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; - mjd=date2mjd(year,month,dday); + mjd = date2mjd (year, month, dday); return mjd; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // Get observing site -void get_site(int site_id) +void +get_site (int site_id) { - int i=0; + int i = 0; char line[LIM]; FILE *file; int id; - double lat,lng; + double lat, lng; float alt; - char abbrev[3],observer[64],filename[LIM]; + char abbrev[3], observer[64], filename[LIM]; - sprintf(filename,"%s/data/sites.txt",m.datadir); - file=fopen(filename,"r"); - if (file==NULL) { - printf("File with site information not found!\n"); - return; - } - while (fgets(line,LIM,file)!=NULL) { - // Skip - if (strstr(line,"#")!=NULL) - continue; - - // Strip newline - line[strlen(line)-1]='\0'; - - // Read data - sscanf(line,"%4d %2s %lf %lf %f", - &id,abbrev,&lat,&lng,&alt); - strcpy(observer,line+38); - - // Change to km - alt/=1000.0; - - if (id==site_id) { - m.lat=lat; - m.lng=lng; - m.alt=alt; - m.site_id=id; - strcpy(m.observer,observer); + sprintf (filename, "%s/data/sites.txt", m.datadir); + file = fopen (filename, "r"); + if (file == NULL) + { + printf ("File with site information not found!\n"); + return; } + while (fgets (line, LIM, file) != NULL) + { + // Skip + if (strstr (line, "#") != NULL) + continue; - } - fclose(file); + // Strip newline + line[strlen (line) - 1] = '\0'; + + // Read data + sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt); + strcpy (observer, line + 38); + + // Change to km + alt /= 1000.0; + + if (id == site_id) + { + m.lat = lat; + m.lng = lng; + m.alt = alt; + m.site_id = id; + strcpy (m.observer, observer); + } + + } + fclose (file); return; } diff --git a/src/angular.c b/src/angular.c index 6dc27d2..38dd0f6 100644 --- a/src/angular.c +++ b/src/angular.c @@ -6,159 +6,181 @@ #define LIM 80 -void dec2s(double,char *,int,int); -double s2dec(char *); -void reverse(double,double,double,double,double *,double *); -void forward(double,double,double,double,double *,double *); +void dec2s (double, char *, int, int); +double s2dec (char *); +void reverse (double, double, double, double, double *, double *); +void forward (double, double, double, double, double *, double *); -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { int i; - double ra1,de1,ra2,de2; - double rx,ry; - char sra[15],sde[15]; + double ra1, de1, ra2, de2; + double rx, ry; + char sra[15], sde[15]; - if (argc==1) { - printf("Usage: %s \n",argv[0]); - printf(" Computes angular offset\n"); - printf("Usage: %s -d \n",argv[0]); - printf(" Applies angular offset\n"); - printf("Usage: %s -x \n",argv[0]); - printf(" Computes x-offset only\n"); - printf("Usage: %s -y \n",argv[0]); - printf(" Computes y-offset only\n"); - return -1; - } + if (argc == 1) + { + printf ("Usage: %s \n", argv[0]); + printf (" Computes angular offset\n"); + printf ("Usage: %s -d \n", argv[0]); + printf (" Applies angular offset\n"); + printf ("Usage: %s -x \n", argv[0]); + printf (" Computes x-offset only\n"); + printf ("Usage: %s -y \n", argv[0]); + printf (" Computes y-offset only\n"); + return -1; + } - if (strcmp(argv[1],"-d")==0) { - if (strchr(argv[2],':')!=NULL) - ra1=15.*s2dec(argv[2]); - else - ra1=atof(argv[2]); - if (strchr(argv[3],':')!=NULL) - de1=s2dec(argv[3]); - else - de1=atof(argv[3]); + if (strcmp (argv[1], "-d") == 0) + { + if (strchr (argv[2], ':') != NULL) + ra1 = 15. * s2dec (argv[2]); + else + ra1 = atof (argv[2]); + if (strchr (argv[3], ':') != NULL) + de1 = s2dec (argv[3]); + else + de1 = atof (argv[3]); - rx=(double) atof(argv[4]); - ry=(double) atof(argv[5]); + rx = (double) atof (argv[4]); + ry = (double) atof (argv[5]); - reverse(ra1,de1,rx,ry,&ra2,&de2); + reverse (ra1, de1, rx, ry, &ra2, &de2); - dec2s(ra2/15.0,sra,0,7); - dec2s(de2,sde,0,6); + dec2s (ra2 / 15.0, sra, 0, 7); + dec2s (de2, sde, 0, 6); - printf("%s %s\n",sra,sde); - } else if (strcmp(argv[1],"-x")==0) { - if (strchr(argv[2],':')!=NULL) - ra1=15.*s2dec(argv[2]); - else - ra1=atof(argv[2]); - if (strchr(argv[3],':')!=NULL) - de1=s2dec(argv[3]); - else - de1=atof(argv[3]); - if (strchr(argv[4],':')!=NULL) - ra2=15.*s2dec(argv[4]); - else - ra2=atof(argv[4]); - if (strchr(argv[5],':')!=NULL) - de2=s2dec(argv[5]); - else - de2=atof(argv[5]); - - forward(ra1,de1,ra2,de2,&rx,&ry); - - printf("%8.3f\n",rx); - } else if (strcmp(argv[1],"-y")==0) { - if (strchr(argv[2],':')!=NULL) - ra1=15.*s2dec(argv[2]); - else - ra1=atof(argv[2]); - if (strchr(argv[3],':')!=NULL) - de1=s2dec(argv[3]); - else - de1=atof(argv[3]); - if (strchr(argv[4],':')!=NULL) - ra2=15.*s2dec(argv[4]); - else - ra2=atof(argv[4]); - if (strchr(argv[5],':')!=NULL) - de2=s2dec(argv[5]); - else - de2=atof(argv[5]); - - forward(ra1,de1,ra2,de2,&rx,&ry); - - printf("%8.3f\n",ry); - } else { - if (strchr(argv[1],':')!=NULL) - ra1=15.*s2dec(argv[1]); - else - ra1=atof(argv[1]); - if (strchr(argv[2],':')!=NULL) - de1=s2dec(argv[2]); - else - de1=atof(argv[2]); - if (strchr(argv[3],':')!=NULL) - ra2=15.*s2dec(argv[3]); - else - ra2=atof(argv[3]); - if (strchr(argv[4],':')!=NULL) - de2=s2dec(argv[4]); - else - de2=atof(argv[4]); - - forward(ra1,de1,ra2,de2,&rx,&ry); - - printf("%8.3f %8.3f %8.3f\n",rx,ry,sqrt(rx*rx+ry*ry)); - } + printf ("%s %s\n", sra, sde); + } + else if (strcmp (argv[1], "-x") == 0) + { + if (strchr (argv[2], ':') != NULL) + ra1 = 15. * s2dec (argv[2]); + else + ra1 = atof (argv[2]); + if (strchr (argv[3], ':') != NULL) + de1 = s2dec (argv[3]); + else + de1 = atof (argv[3]); + if (strchr (argv[4], ':') != NULL) + ra2 = 15. * s2dec (argv[4]); + else + ra2 = atof (argv[4]); + if (strchr (argv[5], ':') != NULL) + de2 = s2dec (argv[5]); + else + de2 = atof (argv[5]); + + forward (ra1, de1, ra2, de2, &rx, &ry); + + printf ("%8.3f\n", rx); + } + else if (strcmp (argv[1], "-y") == 0) + { + if (strchr (argv[2], ':') != NULL) + ra1 = 15. * s2dec (argv[2]); + else + ra1 = atof (argv[2]); + if (strchr (argv[3], ':') != NULL) + de1 = s2dec (argv[3]); + else + de1 = atof (argv[3]); + if (strchr (argv[4], ':') != NULL) + ra2 = 15. * s2dec (argv[4]); + else + ra2 = atof (argv[4]); + if (strchr (argv[5], ':') != NULL) + de2 = s2dec (argv[5]); + else + de2 = atof (argv[5]); + + forward (ra1, de1, ra2, de2, &rx, &ry); + + printf ("%8.3f\n", ry); + } + else + { + if (strchr (argv[1], ':') != NULL) + ra1 = 15. * s2dec (argv[1]); + else + ra1 = atof (argv[1]); + if (strchr (argv[2], ':') != NULL) + de1 = s2dec (argv[2]); + else + de1 = atof (argv[2]); + if (strchr (argv[3], ':') != NULL) + ra2 = 15. * s2dec (argv[3]); + else + ra2 = atof (argv[3]); + if (strchr (argv[4], ':') != NULL) + de2 = s2dec (argv[4]); + else + de2 = atof (argv[4]); + + forward (ra1, de1, ra2, de2, &rx, &ry); + + printf ("%8.3f %8.3f %8.3f\n", rx, ry, sqrt (rx * rx + ry * ry)); + } return 0; } // Convert Decimal into Sexagesimal -void dec2s(double x,char *s,int f,int len) +void +dec2s (double x, char *s, int f, int len) { int i; - double sec,deg,min; + double sec, deg, min; char sign; - char *form[]={":: ",",, ","hms"," "}; + char *form[] = { ":: ", ",, ", "hms", " " }; - sign=(x<0 ? '-' : ' '); - x=3600.*fabs(x); + sign = (x < 0 ? '-' : ' '); + x = 3600. * fabs (x); - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; // deg=fmod(x,60.); - deg=x; + deg = x; - if (len==7) sprintf(s,"%c%02i%c%02i%c%07.4f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]); - if (len==6) sprintf(s,"%c%02i%c%02i%c%06.3f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]); - if (len==5) sprintf(s,"%c%02i%c%02i%c%05.2f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]); - if (len==4) sprintf(s,"%c%02i%c%02i%c%04.1f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]); - if (len==2) sprintf(s,"%c%02i%c%02i%c%02i%c",sign,(int) deg,form[f][0],(int) min,form[f][1],(int) floor(sec),form[f][2]); + if (len == 7) + sprintf (s, "%c%02i%c%02i%c%07.4f%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], sec, form[f][2]); + if (len == 6) + sprintf (s, "%c%02i%c%02i%c%06.3f%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], sec, form[f][2]); + if (len == 5) + sprintf (s, "%c%02i%c%02i%c%05.2f%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], sec, form[f][2]); + if (len == 4) + sprintf (s, "%c%02i%c%02i%c%04.1f%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], sec, form[f][2]); + if (len == 2) + sprintf (s, "%c%02i%c%02i%c%02i%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], (int) floor (sec), form[f][2]); return; } // Convert Sexagesimal into Decimal -double s2dec(char *s) +double +s2dec (char *s) { double x; - float deg,min,sec; + float deg, min, sec; char t[LIM]; - strcpy(t,s); + strcpy (t, s); - deg=fabs(atof(strtok(t," :"))); - min=fabs(atof(strtok(NULL," :"))); - sec=fabs(atof(strtok(NULL," :"))); + deg = fabs (atof (strtok (t, " :"))); + min = fabs (atof (strtok (NULL, " :"))); + sec = fabs (atof (strtok (NULL, " :"))); - x=(double) deg+(double) min/60.+(double) sec/3600.; - if (s[0]=='-') x= -x; + x = (double) deg + (double) min / 60. + (double) sec / 3600.; + if (s[0] == '-') + x = -x; return x; } diff --git a/src/calibrate.c b/src/calibrate.c index 86b874d..341533e 100644 --- a/src/calibrate.c +++ b/src/calibrate.c @@ -13,346 +13,385 @@ #define D2R M_PI/180.0 #define R2D 180.0/M_PI -struct star { - double ra,de; - float pmra,pmde; +struct star +{ + double ra, de; + float pmra, pmde; float mag; }; -struct image { - int naxis1,naxis2,naxis3; +struct image +{ + int naxis1, naxis2, naxis3; float *z; - float zmin,zmax; - double ra0,de0; - float x0,y0; - float a[3],b[3]; + float zmin, zmax; + double ra0, de0; + float x0, y0; + float a[3], b[3]; double mjd; } img; -struct catalog { +struct catalog +{ int n; - float x[NMAX],y[NMAX],mag[NMAX]; - double ra[NMAX],de[NMAX],rx[NMAX],ry[NMAX]; + float x[NMAX], y[NMAX], mag[NMAX]; + double ra[NMAX], de[NMAX], rx[NMAX], ry[NMAX]; int select[NMAX]; }; -struct image read_fits(char *filename,int pnum); -struct catalog read_pixel_catalog(char *filename,float,float,float); -int fgetline(FILE *file,char *s,int lim); -struct catalog read_astrometric_catalog(char *filename,float mmin,float sx,float sy,float angle); -void forward(double ra0,double de0,double ra,double de,double *x,double *y); -int select_nearest(struct catalog c,float x,float y); -void lfit2d(float *x,float *y,float *z,int n,float *a); -void fit_transformation(struct catalog cat,struct catalog ast,int nselect); -struct catalog reread_astrometric_catalog(char *filename,float mmin); -int match_catalogs(struct catalog *cat,struct catalog *ast,float rmax); -double s2dec(char *s); +struct image read_fits (char *filename, int pnum); +struct catalog read_pixel_catalog (char *filename, float, float, float); +int fgetline (FILE * file, char *s, int lim); +struct catalog read_astrometric_catalog (char *filename, float mmin, float sx, + float sy, float angle); +void forward (double ra0, double de0, double ra, double de, double *x, + double *y); +int select_nearest (struct catalog c, float x, float y); +void lfit2d (float *x, float *y, float *z, int n, float *a); +void fit_transformation (struct catalog cat, struct catalog ast, int nselect); +struct catalog reread_astrometric_catalog (char *filename, float mmin); +int match_catalogs (struct catalog *cat, struct catalog *ast, float rmax); +double s2dec (char *s); -void usage(void) +void +usage (void) { - printf("-f FITS file to calibrate\n"); - printf("-R RA of center\n"); - printf("-D Decl of center\n"); - printf("-s Pixel scale (arcseconds) [10.0]\n"); - printf("-q Parallactic angle (degrees) [0.0]\n"); - printf("-m Magnitude limit [9.0]\n"); - printf("-r Matching radius (pixels) [10]\n"); + printf ("-f FITS file to calibrate\n"); + printf ("-R RA of center\n"); + printf ("-D Decl of center\n"); + printf ("-s Pixel scale (arcseconds) [10.0]\n"); + printf ("-q Parallactic angle (degrees) [0.0]\n"); + printf ("-m Magnitude limit [9.0]\n"); + printf ("-r Matching radius (pixels) [10]\n"); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int i,j; - float xmin,xmax,ymin,ymax,zmin,zmax; - float tr[]={-0.5,1.0,0.0,-0.5,0.0,1.0}; - float heat_l[] = {0.0, 0.2, 0.4, 0.6, 1.0}; - float heat_r[] = {0.0, 0.5, 1.0, 1.0, 1.0}; - float heat_g[] = {0.0, 0.0, 0.5, 1.0, 1.0}; - float heat_b[] = {0.0, 0.0, 0.0, 0.3, 1.0}; - int redraw=1,plotcat=0,click=0,nselect=0; - float x,y,width; - char c,pixcat[LIM]; - struct catalog cat,ast; - float sx=-10.0,sy=10.0,q=0.0; - char *env,starfile[128]; - float r,srmin=1.0,srmax=10.0,smmin=2.0,smmax=8.0,mag=9.0,rmax=10.0,rmask=-1; - int arg=0; - char *fitsfile=NULL; - char sra[16],sde[16]; - double ra,de; + int i, j; + float xmin, xmax, ymin, ymax, zmin, zmax; + float tr[] = { -0.5, 1.0, 0.0, -0.5, 0.0, 1.0 }; + float heat_l[] = { 0.0, 0.2, 0.4, 0.6, 1.0 }; + float heat_r[] = { 0.0, 0.5, 1.0, 1.0, 1.0 }; + float heat_g[] = { 0.0, 0.0, 0.5, 1.0, 1.0 }; + float heat_b[] = { 0.0, 0.0, 0.0, 0.3, 1.0 }; + int redraw = 1, plotcat = 0, click = 0, nselect = 0; + float x, y, width; + char c, pixcat[LIM]; + struct catalog cat, ast; + float sx = -10.0, sy = 10.0, q = 0.0; + char *env, starfile[128]; + float r, srmin = 1.0, srmax = 10.0, smmin = 2.0, smmax = 8.0, mag = + 9.0, rmax = 10.0, rmask = -1; + int arg = 0; + char *fitsfile = NULL; + char sra[16], sde[16]; + double ra, de; FILE *file; // Environment variables - env=getenv("ST_DATADIR"); - sprintf(starfile,"%s/data/tycho2.dat",env); + env = getenv ("ST_DATADIR"); + sprintf (starfile, "%s/data/tycho2.dat", env); // Decode options - if (argc>1) { - while ((arg=getopt(argc,argv,"f:R:D:s:q:m:r:M:"))!=-1) { - switch(arg) { - - case 'f': - fitsfile=optarg; - break; - - case 'R': - strcpy(sra,optarg); - if (strchr(sra,':')!=NULL) - ra=15.0*s2dec(sra); - else - ra=atof(sra); - break; - - case 'D': - strcpy(sde,optarg); - if (strchr(sde,':')!=NULL) - de=s2dec(sde); - else - de=atof(sde); - break; - - case 's': - if (strchr(optarg,',')!=NULL) { - sscanf(optarg,"%f,%f",&sx,&sy); - } else { - sx=-atof(optarg); - sy=-sx; + if (argc > 1) + { + while ((arg = getopt (argc, argv, "f:R:D:s:q:m:r:M:")) != -1) + { + switch (arg) + { + + case 'f': + fitsfile = optarg; + break; + + case 'R': + strcpy (sra, optarg); + if (strchr (sra, ':') != NULL) + ra = 15.0 * s2dec (sra); + else + ra = atof (sra); + break; + + case 'D': + strcpy (sde, optarg); + if (strchr (sde, ':') != NULL) + de = s2dec (sde); + else + de = atof (sde); + break; + + case 's': + if (strchr (optarg, ',') != NULL) + { + sscanf (optarg, "%f,%f", &sx, &sy); + } + else + { + sx = -atof (optarg); + sy = -sx; + } + break; + + case 'q': + q = atof (optarg); + break; + + case 'm': + mag = atof (optarg); + break; + + case 'M': + rmask = atof (optarg); + break; + + case 'r': + rmax = atof (optarg); + break; + + case 'h': + usage (); + return 0; + break; + + default: + usage (); + return 0; + } } - break; - - case 'q': - q=atof(optarg); - break; - - case 'm': - mag=atof(optarg); - break; - - case 'M': - rmask=atof(optarg); - break; - - case 'r': - rmax=atof(optarg); - break; - - case 'h': - usage(); - return 0; - break; - - default: - usage(); - return 0; - } - } - } else { - usage(); - return 0; - } + } + else + { + usage (); + return 0; + } // Read image - img=read_fits(fitsfile,0); + img = read_fits (fitsfile, 0); // Set variables - img.ra0=ra; - img.de0=de; - img.x0=0.5*(float) img.naxis1; - img.y0=0.5*(float) img.naxis2; + img.ra0 = ra; + img.de0 = de; + img.x0 = 0.5 * (float) img.naxis1; + img.y0 = 0.5 * (float) img.naxis2; // Read pixel catalog - sprintf(pixcat,"%s.cat",fitsfile); - cat=read_pixel_catalog(pixcat,img.x0,img.y0,rmask); + sprintf (pixcat, "%s.cat", fitsfile); + cat = read_pixel_catalog (pixcat, img.x0, img.y0, rmask); // Read astrometric catalog - ast=read_astrometric_catalog(starfile,mag,sx,sy,q); + ast = read_astrometric_catalog (starfile, mag, sx, sy, q); // Open server - cpgopen("/xs"); + cpgopen ("/xs"); // cpgpap(0.,1.0); - cpgask(0); - cpgsch(0.8); + cpgask (0); + cpgsch (0.8); // Default limits - width=(img.naxis1>img.naxis2) ? img.naxis1 : img.naxis2; - xmin=0.5*(img.naxis1-width); - xmax=0.5*(img.naxis1+width); - ymin=0.5*(img.naxis2-width); - ymax=0.5*(img.naxis2+width); - zmin=img.zmin; - zmax=img.zmax; + width = (img.naxis1 > img.naxis2) ? img.naxis1 : img.naxis2; + xmin = 0.5 * (img.naxis1 - width); + xmax = 0.5 * (img.naxis1 + width); + ymin = 0.5 * (img.naxis2 - width); + ymax = 0.5 * (img.naxis2 + width); + zmin = img.zmin; + zmax = img.zmax; // Forever loop - for (;;) { - if (redraw==1) { - cpgeras(); - - cpgsvp(0.1,0.95,0.1,0.95); - cpgwnad(xmin,xmax,ymin,ymax); - cpglab("x (pix)","y (pix)"," "); - cpgsfs(2); - cpgctab (heat_l,heat_r,heat_g,heat_b,5,1.0,0.5); + for (;;) + { + if (redraw == 1) + { + cpgeras (); - cpgimag(img.z,img.naxis1,img.naxis2,1,img.naxis1,1,img.naxis2,zmin,zmax,tr); - cpgbox("BCTSNI",0.,0,"BCTSNI",0.,0); + cpgsvp (0.1, 0.95, 0.1, 0.95); + cpgwnad (xmin, xmax, ymin, ymax); + cpglab ("x (pix)", "y (pix)", " "); + cpgsfs (2); + cpgctab (heat_l, heat_r, heat_g, heat_b, 5, 1.0, 0.5); + + cpgimag (img.z, img.naxis1, img.naxis2, 1, img.naxis1, 1, + img.naxis2, zmin, zmax, tr); + cpgbox ("BCTSNI", 0., 0, "BCTSNI", 0., 0); + + // Plot catalog + if (plotcat == 1) + { + cpgsci (3); + for (i = 0; i < cat.n; i++) + { + if (cat.select[i] != 0) + cpgpt1 (cat.x[i], cat.y[i], 6); + else + cpgpt1 (cat.x[i], cat.y[i], 24); + } + cpgsci (1); + } + + cpgsci (4); + for (i = 0; i < ast.n; i++) + { + r = + srmax - (srmax - srmin) * (ast.mag[i] - smmin) / (smmax - + smmin); + + // Upscale for image size + r *= img.naxis1 / 752.0; + if (ast.select[i] != 0) + cpgpt1 (ast.x[i], ast.y[i], 6); + cpgcirc (ast.x[i], ast.y[i], r); + } + cpgsci (1); + redraw = 0; + } + + // Get cursor + cpgcurs (&x, &y, &c); + + // Quit + if (c == 'q') + break; + + // Help + if (c == 'h') + { + printf + ("Calibrates astrometry. Initially requires manual matching of at least three stars. Use 'a' to select star on the image, then 'b' to select star from the catalog (blue circles). If at least three stars are matched, use 'f' and 'm' to converge the calibration.\n\n"); + printf ("q Quit\n"); + printf ("a Select star on image\n"); + printf ("b Select star from catalog\n"); + printf ("c Center image on pixel\n"); + printf ("f Fit calibration\n"); + printf ("m Match stars using current calibration\n"); + printf ("z/+ Zoom in on cursor\n"); + printf ("x/- Zoom out on cursor\n"); + printf ("p Plot source-extractor catalog\n"); + printf ("r Reset zoom\n"); + + } + + // Select pixel catalog + if (c == 'a' && click == 0) + { + i = select_nearest (cat, x, y); + cat.select[i] = nselect + 1; + redraw = 1; + click = 1; + } + + // Select catalog + if (c == 'b' && click == 1) + { + i = select_nearest (ast, x, y); + ast.select[i] = nselect + 1; + redraw = 1; + click = 0; + nselect++; + } + + // Center + if (c == 'c') + { + xmin = x - 0.5 * width; + xmax = x + 0.5 * width; + ymin = y - 0.5 * width; + ymax = y + 0.5 * width; + redraw = 1; + continue; + } + + // Fit + if (c == 'f' && nselect >= 3) + { + fit_transformation (cat, ast, nselect); + ast = reread_astrometric_catalog (starfile, mag + 1); + redraw = 1; + } + + // Zoom + if (c == 'z' || c == '+' || c == '=') + { + width /= 1.25; + xmin = x - 0.5 * width; + xmax = x + 0.5 * width; + ymin = y - 0.5 * width; + ymax = y + 0.5 * width; + redraw = 1; + continue; + } + + // Match catalogs + if (c == 'm') + { + nselect = match_catalogs (&cat, &ast, rmax); + redraw = 1; + } + + // Unzoom + if (c == 'x' || c == '-') + { + width *= 1.25; + xmin = x - 0.5 * width; + xmax = x + 0.5 * width; + ymin = y - 0.5 * width; + ymax = y + 0.5 * width; + redraw = 1; + continue; + } // Plot catalog - if (plotcat==1) { - cpgsci(3); - for (i=0;i img.naxis2) ? img.naxis1 : img.naxis2; + xmin = 0.5 * (img.naxis1 - width); + xmax = 0.5 * (img.naxis1 + width); + ymin = 0.5 * (img.naxis2 - width); + ymax = 0.5 * (img.naxis2 + width); + redraw = 1; + continue; + } - // Upscale for image size - r*=img.naxis1/752.0; - if (ast.select[i]!=0) - cpgpt1(ast.x[i],ast.y[i],6); - cpgcirc(ast.x[i],ast.y[i],r); - } - cpgsci(1); - redraw=0; + // Dump + if (c == 'd') + { + file = fopen ("dump.dat", "w"); + for (i = 0; i < nselect; i++) + { + for (j = 0; j < cat.n; j++) + if (cat.select[j] == i + 1) + fprintf (file, "%lf %lf ", cat.x[j] - img.x0, + cat.y[j] - img.y0); + for (j = 0; j < ast.n; j++) + if (ast.select[j] == i + 1) + fprintf (file, "%lf %lf\n", ast.ra[j], ast.de[j]); + } + fclose (file); + } } - // Get cursor - cpgcurs(&x,&y,&c); - - // Quit - if (c=='q') - break; - - // Help - if (c=='h') { - printf("Calibrates astrometry. Initially requires manual matching of at least three stars. Use 'a' to select star on the image, then 'b' to select star from the catalog (blue circles). If at least three stars are matched, use 'f' and 'm' to converge the calibration.\n\n"); - printf("q Quit\n"); - printf("a Select star on image\n"); - printf("b Select star from catalog\n"); - printf("c Center image on pixel\n"); - printf("f Fit calibration\n"); - printf("m Match stars using current calibration\n"); - printf("z/+ Zoom in on cursor\n"); - printf("x/- Zoom out on cursor\n"); - printf("p Plot source-extractor catalog\n"); - printf("r Reset zoom\n"); - - } - - // Select pixel catalog - if (c=='a' && click==0) { - i=select_nearest(cat,x,y); - cat.select[i]=nselect+1; - redraw=1; - click=1; - } - - // Select catalog - if (c=='b' && click==1) { - i=select_nearest(ast,x,y); - ast.select[i]=nselect+1; - redraw=1; - click=0; - nselect++; - } - - // Center - if (c=='c') { - xmin=x-0.5*width; - xmax=x+0.5*width; - ymin=y-0.5*width; - ymax=y+0.5*width; - redraw=1; - continue; - } - - // Fit - if (c=='f' && nselect>=3) { - fit_transformation(cat,ast,nselect); - ast=reread_astrometric_catalog(starfile,mag+1); - redraw=1; - } - - // Zoom - if (c=='z' || c=='+' || c=='=') { - width/=1.25; - xmin=x-0.5*width; - xmax=x+0.5*width; - ymin=y-0.5*width; - ymax=y+0.5*width; - redraw=1; - continue; - } - - // Match catalogs - if (c=='m') { - nselect=match_catalogs(&cat,&ast,rmax); - redraw=1; - } - - // Unzoom - if (c=='x' || c=='-') { - width*=1.25; - xmin=x-0.5*width; - xmax=x+0.5*width; - ymin=y-0.5*width; - ymax=y+0.5*width; - redraw=1; - continue; - } - - // Plot catalog - if (c=='p') { - plotcat = (plotcat==1) ? 0 : 1; - redraw=1; - } - - // Reset - if (c=='r') { - width=(img.naxis1>img.naxis2) ? img.naxis1 : img.naxis2; - xmin=0.5*(img.naxis1-width); - xmax=0.5*(img.naxis1+width); - ymin=0.5*(img.naxis2-width); - ymax=0.5*(img.naxis2+width); - redraw=1; - continue; - } - - // Dump - if (c=='d') { - file=fopen("dump.dat","w"); - for (i=0;i0) { - if (i>=NMAX) - break; - if (strstr(line,"#")!=NULL) - continue; - sscanf(line,"%f %f %f",&c.x[i],&c.y[i],&c.mag[i]); - dx=c.x[i]-x0; - dy=c.y[i]-y0; - r=sqrt(dx*dx+dy*dy); - if (r>rmin && rmin>0.0) - continue; - c.select[i]=0; - i++; - } - fclose(file); - c.n=i; + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "%s not found!\n", filename); + exit (0); + } + while (fgetline (file, line, LIM) > 0) + { + if (i >= NMAX) + break; + if (strstr (line, "#") != NULL) + continue; + sscanf (line, "%f %f %f", &c.x[i], &c.y[i], &c.mag[i]); + dx = c.x[i] - x0; + dy = c.y[i] - y0; + r = sqrt (dx * dx + dy * dy); + if (r > rmin && rmin > 0.0) + continue; + c.select[i] = 0; + i++; + } + fclose (file); + c.n = i; return c; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; - - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + int c, i = 0; + + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; @@ -449,236 +494,269 @@ int fgetline(FILE *file,char *s,int lim) return i; } -struct catalog read_astrometric_catalog(char *filename,float mmin,float sx,float sy,float angle) +struct catalog +read_astrometric_catalog (char *filename, float mmin, float sx, float sy, + float angle) { - int i=0; + int i = 0; FILE *file; char line[LIM]; struct catalog c; - double rx,ry,x,y,ra,de; + double rx, ry, x, y, ra, de; struct star s; - double d,dx,dy; - double mjd0=51544.5; - - file=fopen(filename,"rb"); - if (file==NULL) { - fprintf(stderr,"%s not found!\n",filename); - exit(0); - } - while (!feof(file)) { - fread(&s,sizeof(struct star),1,file); - if (s.mag>mmin) - continue; - forward(img.ra0,img.de0,s.ra,s.de,&rx,&ry); - x=img.x0+1.0/sx*(cos(angle*D2R)*rx+sin(angle*D2R)*ry); - y=img.y0+1.0/sy*(-sin(angle*D2R)*rx+cos(angle*D2R)*ry); - if (x>0.0 && x<(float) img.naxis1 && y>0.0 && y<(float) img.naxis2) { - c.x[i]=x; - c.y[i]=y; - c.rx[i]=rx; - c.ry[i]=ry; - c.ra[i]=s.ra; - c.de[i]=s.de; - c.mag[i]=s.mag; - c.select[i]=0; + double d, dx, dy; + double mjd0 = 51544.5; - if (i>=NMAX) - break; - i++; + file = fopen (filename, "rb"); + if (file == NULL) + { + fprintf (stderr, "%s not found!\n", filename); + exit (0); } - } - fclose(file); - c.n=i; + while (!feof (file)) + { + fread (&s, sizeof (struct star), 1, file); + if (s.mag > mmin) + continue; + forward (img.ra0, img.de0, s.ra, s.de, &rx, &ry); + x = + img.x0 + 1.0 / sx * (cos (angle * D2R) * rx + sin (angle * D2R) * ry); + y = + img.y0 + 1.0 / sy * (-sin (angle * D2R) * rx + + cos (angle * D2R) * ry); + if (x > 0.0 && x < (float) img.naxis1 && y > 0.0 + && y < (float) img.naxis2) + { + c.x[i] = x; + c.y[i] = y; + c.rx[i] = rx; + c.ry[i] = ry; + c.ra[i] = s.ra; + c.de[i] = s.de; + c.mag[i] = s.mag; + c.select[i] = 0; + + if (i >= NMAX) + break; + i++; + } + } + fclose (file); + c.n = i; return c; } // Select nearest object -int select_nearest(struct catalog c,float x,float y) +int +select_nearest (struct catalog c, float x, float y) { - int i,imin; - float r,rmin; + int i, imin; + float r, rmin; - for (i=0;immin) - continue; - forward(img.ra0,img.de0,s.ra,s.de,&rx,&ry); - dx=rx-img.a[0]; - dy=ry-img.b[0]; - d=img.a[1]*img.b[2]-img.a[2]*img.b[1]; - x=(img.b[2]*dx-img.a[2]*dy)/d+img.x0; - y=(img.a[1]*dy-img.b[1]*dx)/d+img.y0; - if (x>0.0 && x0.0 && y mmin) + continue; + forward (img.ra0, img.de0, s.ra, s.de, &rx, &ry); + dx = rx - img.a[0]; + dy = ry - img.b[0]; + d = img.a[1] * img.b[2] - img.a[2] * img.b[1]; + x = (img.b[2] * dx - img.a[2] * dy) / d + img.x0; + y = (img.a[1] * dy - img.b[1] * dx) / d + img.y0; + if (x > 0.0 && x < img.naxis1 && y > 0.0 && y < img.naxis2) + { + c.x[i] = x; + c.y[i] = y; + c.rx[i] = rx; + c.ry[i] = ry; + c.ra[i] = s.ra; + c.de[i] = s.de; + c.mag[i] = s.mag; + c.select[i] = 0; + i++; + } } - } - fclose(file); - c.n=i; + fclose (file); + c.n = i; return c; } -int match_catalogs(struct catalog *cat,struct catalog *ast,float rmax) +int +match_catalogs (struct catalog *cat, struct catalog *ast, float rmax) { - int i,j,jmin,n,flag=0; - float r,rmin; + int i, j, jmin, n, flag = 0; + float r, rmin; FILE *file; // Reset - for (i=0;in;i++) - cat->select[i]=0; - for (i=0;in;i++) - ast->select[i]=0; - - file=fopen("out.dat","w"); - for (i=0,n=0;in;i++) { - for (j=0,flag=0;jn;j++) { - if (ast->select[j]!=0) - continue; - r=sqrt(pow(cat->x[i]-ast->x[j],2)+pow(cat->y[i]-ast->y[j],2)); - if (flag==0 || rx[i]-img.x0,cat->y[i]-img.y0,ast->ra[jmin],ast->de[jmin]); - cat->select[i]=n+1; - ast->select[jmin]=n+1; - n++; - } - } - fclose(file); + for (i = 0; i < cat->n; i++) + cat->select[i] = 0; + for (i = 0; i < ast->n; i++) + ast->select[i] = 0; - printf("%d stars matched\n",n); + file = fopen ("out.dat", "w"); + for (i = 0, n = 0; i < cat->n; i++) + { + for (j = 0, flag = 0; j < ast->n; j++) + { + if (ast->select[j] != 0) + continue; + r = + sqrt (pow (cat->x[i] - ast->x[j], 2) + + pow (cat->y[i] - ast->y[j], 2)); + if (flag == 0 || r < rmin) + { + rmin = r; + jmin = j; + flag = 1; + } + } + if (rmin < rmax) + { + fprintf (file, "%10.4f %10.4f %10.6f %10.6f\n", cat->x[i] - img.x0, + cat->y[i] - img.y0, ast->ra[jmin], ast->de[jmin]); + cat->select[i] = n + 1; + ast->select[jmin] = n + 1; + n++; + } + } + fclose (file); + + printf ("%d stars matched\n", n); return n; } // Convert Sexagesimal into Decimal -double s2dec(char *s) +double +s2dec (char *s) { double x; - float deg,min,sec; + float deg, min, sec; char t[LIM]; - strcpy(t,s); + strcpy (t, s); - deg=fabs(atof(strtok(t," :"))); - min=fabs(atof(strtok(NULL," :"))); - sec=fabs(atof(strtok(NULL," :"))); + deg = fabs (atof (strtok (t, " :"))); + min = fabs (atof (strtok (NULL, " :"))); + sec = fabs (atof (strtok (NULL, " :"))); - x=(double) deg+(double) min/60.+(double) sec/3600.; - if (s[0]=='-') x= -x; + x = (double) deg + (double) min / 60. + (double) sec / 3600.; + if (s[0] == '-') + x = -x; return x; } diff --git a/src/confirm.c b/src/confirm.c index 59de605..47d70f9 100644 --- a/src/confirm.c +++ b/src/confirm.c @@ -13,953 +13,1057 @@ #define D2R M_PI/180.0 #define R2D 180.0/M_PI -struct fourframe { +struct fourframe +{ char filename[64]; - int naxis1,naxis2,naxis3,nframes; - float *zavg,*zstd,*zmax,*znum,*ztrk,*zsig; + int naxis1, naxis2, naxis3, nframes; + float *zavg, *zstd, *zmax, *znum, *ztrk, *zsig; int *mask; - double ra0,de0; - float x0,y0; - float a[3],b[3],xrms,yrms; + double ra0, de0; + float x0, y0; + float a[3], b[3], xrms, yrms; double mjd; - float *dt,exptime; + float *dt, exptime; char nfd[32]; int cospar; }; -struct observation { - int satno,cospar; - char desig[16],conditions,behavior,catalog[32],comment[LIM]; - double mjd,ra,de; - float terr,perr,tmid; - char nfd[32],pos[32]; - int epoch,type; +struct observation +{ + int satno, cospar; + char desig[16], conditions, behavior, catalog[32], comment[LIM]; + double mjd, ra, de; + float terr, perr, tmid; + char nfd[32], pos[32]; + int epoch, type; char iod_line[80]; - float x[3],y[3],t[3],dxdt,dydt,drdt; + float x[3], y[3], t[3], dxdt, dydt, drdt; int state; }; -struct point +struct point { - float x,y,t; + float x, y, t; int flag; }; -struct fourframe read_fits(char *filename); -void forward(double ra0,double de0,double ra,double de,double *x,double *y); -void reverse(double ra0,double de0,double x,double y,double *ra,double *de); +struct fourframe read_fits (char *filename); +void forward (double ra0, double de0, double ra, double de, double *x, + double *y); +void reverse (double ra0, double de0, double x, double y, double *ra, + double *de); // Linear least squares fit -float linear_fit(float x[],float y[],float w[],int n,float a[],float sa[]) +float +linear_fit (float x[], float y[], float w[], int n, float a[], float sa[]) { int i; - float sum,sumx,sumy,sumxx,sumxy; - float d,chi2,covar,r; + float sum, sumx, sumy, sumxx, sumxy; + float d, chi2, covar, r; // Compute sums - sum=sumx=sumy=sumxx=sumxy=0.; - for (i=0;i2) - year=c-4716; + dday = b - d - floor (30.6001 * e) + f; + if (e < 14) + month = e - 1; else - year=c-4715; + month = e - 13; - day=(int) floor(dday); - x=24.0*(dday-day); - x=3600.*fabs(x); - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - hour=x; - fsec=1000.0*(sec-floor(sec)); - sprintf(date,"%04d%02d%02d%02d%02d%02.0f%03.0f",(int) year,(int) month,(int) day,(int) hour,(int) min,floor(sec),fsec); + if (month > 2) + year = c - 4716; + else + year = c - 4715; + + day = (int) floor (dday); + x = 24.0 * (dday - day); + x = 3600. * fabs (x); + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + hour = x; + fsec = 1000.0 * (sec - floor (sec)); + sprintf (date, "%04d%02d%02d%02d%02d%02.0f%03.0f", (int) year, (int) month, + (int) day, (int) hour, (int) min, floor (sec), fsec); return; } // MJD to DOY -double mjd2doy(double mjd,int *yr) +double +mjd2doy (double mjd, int *yr) { - int year,month,k=2; + int year, month, k = 2; int day; double doy; char nfd[32]; - - mjd2date(mjd,nfd); - sscanf(nfd,"%04d",&year); - sscanf(nfd+4,"%02d",&month); - sscanf(nfd+6,"%02d",&day); + mjd2date (mjd, nfd); - if (year%4==0 && year%400!=0) - k=1; + sscanf (nfd, "%04d", &year); + sscanf (nfd + 4, "%02d", &month); + sscanf (nfd + 6, "%02d", &day); - doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - *yr=year; + doy = + floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30; + + *yr = year; return doy; } // Convert Decimal into Sexagesimal -void dec2s(double x,char *s,int type) +void +dec2s (double x, char *s, int type) { int i; - double sec,deg,min,fmin; + double sec, deg, min, fmin; char sign; - sign=(x<0 ? '-' : '+'); - x=60.*fabs(x); + sign = (x < 0 ? '-' : '+'); + x = 60. * fabs (x); - min=fmod(x,60.); - x=(x-min)/60.; + min = fmod (x, 60.); + x = (x - min) / 60.; // deg=fmod(x,60.); - deg=x; - if (type==0) - fmin=1000.0*(min-floor(min)); + deg = x; + if (type == 0) + fmin = 1000.0 * (min - floor (min)); else - fmin=100.0*(min-floor(min)); + fmin = 100.0 * (min - floor (min)); - if (type==0) - sprintf(s,"%02.0f%02.0f%03.0f",deg,floor(min),fmin); + if (type == 0) + sprintf (s, "%02.0f%02.0f%03.0f", deg, floor (min), fmin); else - sprintf(s,"%c%02.0f%02.0f%02.0f",sign,deg,floor(min),fmin); + sprintf (s, "%c%02.0f%02.0f%02.0f", sign, deg, floor (min), fmin); return; } // Reduce point -void reduce_point(struct observation *obs,struct fourframe img,float tmid,float x,float y) +void +reduce_point (struct observation *obs, struct fourframe img, float tmid, + float x, float y) { - int iframe,k; - double ra,de,rx,ry; - float dx,dy,dt; + int iframe, k; + double ra, de, rx, ry; + float dx, dy, dt; double mjd; - char nfd[32],sra[15],sde[15]; + char nfd[32], sra[15], sde[15]; // Transform position - dx=x-img.x0; - dy=y-img.y0; - rx=img.a[0]+img.a[1]*dx+img.a[2]*dy; - ry=img.b[0]+img.b[1]*dx+img.b[2]*dy; - reverse(img.ra0,img.de0,rx,ry,&ra,&de); + dx = x - img.x0; + dy = y - img.y0; + rx = img.a[0] + img.a[1] * dx + img.a[2] * dy; + ry = img.b[0] + img.b[1] * dx + img.b[2] * dy; + reverse (img.ra0, img.de0, rx, ry, &ra, &de); - dec2s(ra/15.0,sra,0); - dec2s(de,sde,1); + dec2s (ra / 15.0, sra, 0); + dec2s (de, sde, 1); // Get time - k=(int) x + img.naxis1*(int) y; - iframe=(int) img.znum[k]; - if (tmid<0.0) - dt=img.dt[iframe]; + k = (int) x + img.naxis1 * (int) y; + iframe = (int) img.znum[k]; + if (tmid < 0.0) + dt = img.dt[iframe]; else - dt=tmid; - mjd=nfd2mjd(img.nfd)+(double) dt/86400.0; - mjd2date(mjd,nfd); - + dt = tmid; + mjd = nfd2mjd (img.nfd) + (double) dt / 86400.0; + mjd2date (mjd, nfd); + // Copy - strcpy(obs->nfd,nfd); - sprintf(obs->pos,"%s%s",sra,sde); + strcpy (obs->nfd, nfd); + sprintf (obs->pos, "%s%s", sra, sde); return; } -void fit(struct observation *obs,struct fourframe ff,struct point *p,int np,int flag) +void +fit (struct observation *obs, struct fourframe ff, struct point *p, int np, + int flag) { - int i,j,k,l,n,m; - float *t,*dt,*x,*y,*w; - float tmin,tmax,tmid; - float chi2x,chi2y,ax[2],sax[2],ay[2],say[2]; - float dx,dy,dr,rmsx,rmsy; + int i, j, k, l, n, m; + float *t, *dt, *x, *y, *w; + float tmin, tmax, tmid; + float chi2x, chi2y, ax[2], sax[2], ay[2], say[2]; + float dx, dy, dr, rmsx, rmsy; // Count number of points - for (i=0,n=0;itmax) tmax=t[i]; - } - } - tmid=0.5*(tmin+tmax); - - // Shift in time - for (i=0;ix[0]=ax[0]; - obs->y[0]=ay[0]; - obs->t[0]=tmid; - obs->x[1]=ax[0]+ax[1]*(tmin-tmid); - obs->y[1]=ay[0]+ay[1]*(tmin-tmid); - obs->t[1]=tmin; - obs->x[2]=ax[0]+ax[1]*(tmax-tmid); - obs->y[2]=ay[0]+ay[1]*(tmax-tmid); - obs->t[2]=tmax; - obs->state=1; - obs->dxdt=(obs->x[2]-obs->x[1])/(obs->t[2]-obs->t[1]); - obs->dydt=(obs->y[2]-obs->y[1])/(obs->t[2]-obs->t[1]); - obs->drdt=sqrt(obs->dxdt*obs->dxdt+obs->dydt*obs->dydt); + // Allocate + t = (float *) malloc (sizeof (float) * n); + dt = (float *) malloc (sizeof (float) * n); + x = (float *) malloc (sizeof (float) * n); + y = (float *) malloc (sizeof (float) * n); + w = (float *) malloc (sizeof (float) * n); + + // Fill + for (i = 0, l = 0; i < np; i++) + { + if (p[i].flag == flag) + { + x[l] = p[i].x; + y[l] = p[i].y; + w[l] = 1.0; + t[l] = p[i].t; + l++; + } + } + + // Find limits in time + for (i = 0; i < n; i++) + { + if (i == 0) + { + tmin = t[i]; + tmax = t[i]; + } + else + { + if (t[i] < tmin) + tmin = t[i]; + if (t[i] > tmax) + tmax = t[i]; + } + } + tmid = 0.5 * (tmin + tmax); + + // Shift in time + for (i = 0; i < n; i++) + dt[i] = t[i] - tmid; + + // Fit x-pixel position + chi2x = linear_fit (dt, x, w, n, ax, sax); + + // Fit x-pixel position + chi2y = linear_fit (dt, y, w, n, ay, say); + + // Compute rms + for (i = 0, rmsx = 0.0, rmsy = 0.0; i < n; i++) + { + rmsx += pow (x[i] - (ax[0] + ax[1] * dt[i]), 2); + rmsy += pow (y[i] - (ay[0] + ay[1] * dt[i]), 2); + } + rmsx = sqrt (rmsx / (float) (n - 1)); + rmsy = sqrt (rmsy / (float) (n - 1)); + + obs->x[0] = ax[0]; + obs->y[0] = ay[0]; + obs->t[0] = tmid; + obs->x[1] = ax[0] + ax[1] * (tmin - tmid); + obs->y[1] = ay[0] + ay[1] * (tmin - tmid); + obs->t[1] = tmin; + obs->x[2] = ax[0] + ax[1] * (tmax - tmid); + obs->y[2] = ay[0] + ay[1] * (tmax - tmid); + obs->t[2] = tmax; + obs->state = 1; + obs->dxdt = (obs->x[2] - obs->x[1]) / (obs->t[2] - obs->t[1]); + obs->dydt = (obs->y[2] - obs->y[1]) / (obs->t[2] - obs->t[1]); + obs->drdt = sqrt (obs->dxdt * obs->dxdt + obs->dydt * obs->dydt); // Reduce point - reduce_point(obs,ff,tmid,ax[0],ay[0]); + reduce_point (obs, ff, tmid, ax[0], ay[0]); // Free - free(t); - free(dt); - free(x); - free(y); + free (t); + free (dt); + free (x); + free (y); return; } -void format_iod_line(struct observation *obs) +void +format_iod_line (struct observation *obs) { - int mt,xt,mp,xp; + int mt, xt, mp, xp; char string[10]; - + // Time format - sprintf(string,"%7.1e",obs->terr); - mt=string[0]-'0'; - xt=atoi(string+4)+8; + sprintf (string, "%7.1e", obs->terr); + mt = string[0] - '0'; + xt = atoi (string + 4) + 8; // Position format - if (obs->type==2) { - sprintf(string,"%7.1e",obs->perr); - mp=string[0]-'0'; - xp=atoi(string+4)+8; - } else { - printf("Position format not implemented!\n"); - } + if (obs->type == 2) + { + sprintf (string, "%7.1e", obs->perr); + mp = string[0] - '0'; + xp = atoi (string + 4) + 8; + } + else + { + printf ("Position format not implemented!\n"); + } - sprintf(obs->iod_line,"%05d %c%c %-6s %04d %c %-17s %d%d %d%d %-14s %d%d %c", - obs->satno, - obs->desig[0],obs->desig[1], - obs->desig+2, - obs->cospar, - obs->conditions, - obs->nfd, - mt,xt, - obs->type,obs->epoch, - obs->pos, - mp,xp, - obs->behavior); + sprintf (obs->iod_line, + "%05d %c%c %-6s %04d %c %-17s %d%d %d%d %-14s %d%d %c", obs->satno, + obs->desig[0], obs->desig[1], obs->desig + 2, obs->cospar, + obs->conditions, obs->nfd, mt, xt, obs->type, obs->epoch, obs->pos, + mp, xp, obs->behavior); return; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; + int c, i = 0; - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\t') - c=' '; + c = ' '; if (c == '\n') s[i++] = c; s[i] = '\0'; return i; } -void find_designation(int satno0,char *desig0) +void +find_designation (int satno0, char *desig0) { FILE *file; int satno; char desig[16]; - char *env,filename[128]; + char *env, filename[128]; // Environment variables - env=getenv("ST_DATADIR"); - sprintf(filename,"%s/data/desig.txt",env); + env = getenv ("ST_DATADIR"); + sprintf (filename, "%s/data/desig.txt", env); - file=fopen(filename,"r"); - if (file==NULL) { - fprintf(stderr,"Designation file not found!\n"); - exit(0); - } - while (!feof(file)) { - fscanf(file,"%d %s",&satno,desig); - if (satno==satno0) { - strcpy(desig0,desig); - break; + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "Designation file not found!\n"); + exit (0); } - } - fclose(file); + while (!feof (file)) + { + fscanf (file, "%d %s", &satno, desig); + if (satno == satno0) + { + strcpy (desig0, desig); + break; + } + } + fclose (file); return; } -void identify_observation(struct observation *obs,char *fileroot,float drmin,float amin) +void +identify_observation (struct observation *obs, char *fileroot, float drmin, + float amin) { FILE *file; - float x0,y0,x1,y1,x,y,texp; + float x0, y0, x1, y1, x, y, texp; double mjd; - int satno,flag=0,i; - char nfd[32],filename[LIM],line[LIM],catalog[LIM]; - float dx,dy,dr,dxdt,dydt,drdt,angle,dp; + int satno, flag = 0, i; + char nfd[32], filename[LIM], line[LIM], catalog[LIM]; + float dx, dy, dr, dxdt, dydt, drdt, angle, dp; // Open ID file - sprintf(filename,"%s.id",fileroot); - file=fopen(filename,"r"); - if (file==NULL) { - fprintf(stderr,"ID file %s not found\n",filename); - return; - } - while (fgetline(file,line,LIM)>0) { - sscanf(line,"%s %f %f %f %f %f %d %s",nfd,&x0,&y0,&x1,&y1,&texp,&satno,catalog); - - // Predicted pixel rates - dxdt=(x1-x0)/texp; - dydt=(y1-y0)/texp; - drdt=sqrt(dxdt*dxdt+dydt*dydt); - x=x0+dxdt*obs->t[0]; - y=y0+dydt*obs->t[0]; - - // Compare - dx=x-obs->x[0]; - dy=y-obs->y[0]; - dr=sqrt(dx*dx+dy*dy); - dp=(dxdt*obs->dxdt+dydt*obs->dydt)/(obs->drdt*drdt); - if (dp<=1.0) - angle=acos(dp)*R2D; - else - angle=0.0; - - // Identify - if (drsatno=satno; - if (strstr(catalog,"classfd.tle")!=NULL) - strcpy(obs->catalog,"classfd"); - if (strstr(catalog,"inttles.tle")!=NULL) - strcpy(obs->catalog,"classfd"); - else if (strstr(catalog,"catalog.tle")!=NULL) - strcpy(obs->catalog,"catalog"); + sprintf (filename, "%s.id", fileroot); + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "ID file %s not found\n", filename); + return; } - } - fclose(file); + while (fgetline (file, line, LIM) > 0) + { + sscanf (line, "%s %f %f %f %f %f %d %s", nfd, &x0, &y0, &x1, &y1, &texp, + &satno, catalog); + + // Predicted pixel rates + dxdt = (x1 - x0) / texp; + dydt = (y1 - y0) / texp; + drdt = sqrt (dxdt * dxdt + dydt * dydt); + x = x0 + dxdt * obs->t[0]; + y = y0 + dydt * obs->t[0]; + + // Compare + dx = x - obs->x[0]; + dy = y - obs->y[0]; + dr = sqrt (dx * dx + dy * dy); + dp = (dxdt * obs->dxdt + dydt * obs->dydt) / (obs->drdt * drdt); + if (dp <= 1.0) + angle = acos (dp) * R2D; + else + angle = 0.0; + + // Identify + if (dr < drmin && angle < amin) + { + obs->satno = satno; + if (strstr (catalog, "classfd.tle") != NULL) + strcpy (obs->catalog, "classfd"); + if (strstr (catalog, "inttles.tle") != NULL) + strcpy (obs->catalog, "classfd"); + else if (strstr (catalog, "catalog.tle") != NULL) + strcpy (obs->catalog, "catalog"); + } + } + fclose (file); return; } -void write_observation(struct observation obs) +void +write_observation (struct observation obs) { FILE *file; char filename[LIM]; - sprintf(filename,"%s.dat",obs.catalog); + sprintf (filename, "%s.dat", obs.catalog); - file=fopen(filename,"a"); - fprintf(file,"%s\n%s\n",obs.comment,obs.iod_line); - fclose(file); + file = fopen (filename, "a"); + fprintf (file, "%s\n%s\n", obs.comment, obs.iod_line); + fclose (file); return; } -void overlay_predictions(char *fitsfile,struct fourframe ff) +void +overlay_predictions (char *fitsfile, struct fourframe ff) { - float x0,y0,x1,y1,texp; - int satno,isch; - char filename[LIM],line[LIM],nfd[32],catalog[LIM],text[8]; + float x0, y0, x1, y1, texp; + int satno, isch; + char filename[LIM], line[LIM], nfd[32], catalog[LIM], text[8]; FILE *file; - float t,x,y; + float t, x, y; - cpgqci(&isch); + cpgqci (&isch); - sprintf(filename,"%s.id",fitsfile); + sprintf (filename, "%s.id", fitsfile); // Open ID file - file=fopen(filename,"r"); - if (file==NULL) { - fprintf(stderr,"ID file %s not found\n",filename); - return; - } - while (fgetline(file,line,LIM)>0) { - sscanf(line,"%s %f %f %f %f %f %d %s",nfd,&x0,&y0,&x1,&y1,&texp,&satno,catalog); - - if (strstr(catalog,"classfd")!=NULL) - cpgsci(4); - else if (strstr(catalog,"catalog")!=NULL) - cpgsci(0); - else if (strstr(catalog,"inttles")!=NULL) - cpgsci(3); - else if (strstr(catalog,"jsc")!=NULL) - cpgsci(5); - - cpgpt1(x0,y0,17); - cpgmove(x0,y0); - cpgdraw(x1,y1); - - // plot text - cpgsch(0.65); - sprintf(text," %05d",satno); - for (t=0.0;t<1.0;t+=0.1) { - x=x0+(x1-x0)*t; - y=y0+(y1-y0)*t; - if (x>0.0 && y>0.0 && x 0) + { + sscanf (line, "%s %f %f %f %f %f %d %s", nfd, &x0, &y0, &x1, &y1, &texp, + &satno, catalog); + + if (strstr (catalog, "classfd") != NULL) + cpgsci (4); + else if (strstr (catalog, "catalog") != NULL) + cpgsci (0); + else if (strstr (catalog, "inttles") != NULL) + cpgsci (3); + else if (strstr (catalog, "jsc") != NULL) + cpgsci (5); + + cpgpt1 (x0, y0, 17); + cpgmove (x0, y0); + cpgdraw (x1, y1); + + // plot text + cpgsch (0.65); + sprintf (text, " %05d", satno); + for (t = 0.0; t < 1.0; t += 0.1) + { + x = x0 + (x1 - x0) * t; + y = y0 + (y1 - y0) * t; + if (x > 0.0 && y > 0.0 && x < ff.naxis1 && y < ff.naxis2) + { + cpgtext (x, y, text); + break; + } + } + cpgsch (1.0); + cpgsci (isch); + } + fclose (file); return; } -void accumulate(float *z,int nx,int ny,int nz,int *mask,int bx,int by,int bz,int nsel,int *zsel) +void +accumulate (float *z, int nx, int ny, int nz, int *mask, int bx, int by, + int bz, int nsel, int *zsel) { - int ix,iy,iz; - int jx,jy,jz,k; - int mx,my,mz; - int *c,npoints=0; + int ix, iy, iz; + int jx, jy, jz, k; + int mx, my, mz; + int *c, npoints = 0; // New dimensions - mx=nx/bx; - my=ny/by; - mz=nz/bz; + mx = nx / bx; + my = ny / by; + mz = nz / bz; // Allocate and zero - c=(int *) malloc(sizeof(int)*mx*my*mz); - for (ix=0;ixnsel) - zsel[ix+nx*iy]++; + for (ix = 0; ix < nx; ix++) + { + for (iy = 0; iy < ny; iy++) + { + iz = (int) z[ix + nx * iy]; + jx = ix / bx; + jy = iy / by; + jz = iz / bz; + k = jx + mx * (jy + my * jz); + if (c[k] > nsel) + zsel[ix + nx * iy]++; + } } - } - free(c); + free (c); return; } // RANSAC line finding -void ransac(struct point *p,int np,float drmin) +void +ransac (struct point *p, int np, float drmin) { - int i=0,j,k,l,m,n,mmax; + int i = 0, j, k, l, m, n, mmax; const gsl_rng_type *T; - gsl_rng * r; - int i0,i1,i0max,i1max; - float ax,bx,ay,by; - float dx,dy,dr; + gsl_rng *r; + int i0, i1, i0max, i1max; + float ax, bx, ay, by; + float dx, dy, dr; // Set up randomizer - gsl_rng_env_setup(); + gsl_rng_env_setup (); - T=gsl_rng_default; - r=gsl_rng_alloc(T); + T = gsl_rng_default; + r = gsl_rng_alloc (T); // Loop over number of lines - for (i=1;i<=4;i++) { - // Number of iterations - for (l=0,mmax=0;l<10000;l++) { - // Get random end points - for (;;) { - i0=(int) (np*gsl_rng_uniform(r)); - if (p[i0].flag==0) - break; - } - for (;;) { - i1=(int) (np*gsl_rng_uniform(r)); - if (p[i1].flag==0) - break; - } - + for (i = 1; i <= 4; i++) + { + // Number of iterations + for (l = 0, mmax = 0; l < 10000; l++) + { + // Get random end points + for (;;) + { + i0 = (int) (np * gsl_rng_uniform (r)); + if (p[i0].flag == 0) + break; + } + for (;;) + { + i1 = (int) (np * gsl_rng_uniform (r)); + if (p[i1].flag == 0) + break; + } + + // Linear model + ax = (p[i1].x - p[i0].x) / (p[i1].t - p[i0].t); + bx = p[i0].x - ax * p[i0].t; + ay = (p[i1].y - p[i0].y) / (p[i1].t - p[i0].t); + by = p[i0].y - ay * p[i0].t; + + // Find matches + for (k = 0, m = 0; k < np; k++) + { + dx = bx + ax * p[k].t - p[k].x; + dy = by + ay * p[k].t - p[k].y; + dr = sqrt (dx * dx + dy * dy); + if (dr < drmin && p[k].flag == 0) + m++; + } + + // Store + if (m > mmax) + { + mmax = m; + i0max = i0; + i1max = i1; + } + } + // Linear model - ax=(p[i1].x-p[i0].x)/(p[i1].t-p[i0].t); - bx=p[i0].x-ax*p[i0].t; - ay=(p[i1].y-p[i0].y)/(p[i1].t-p[i0].t); - by=p[i0].y-ay*p[i0].t; - + ax = (p[i1max].x - p[i0max].x) / (p[i1max].t - p[i0max].t); + bx = p[i0max].x - ax * p[i0max].t; + ay = (p[i1max].y - p[i0max].y) / (p[i1max].t - p[i0max].t); + by = p[i0max].y - ay * p[i0max].t; + // Find matches - for (k=0,m=0;kmmax) { - mmax=m; - i0max=i0; - i1max=i1; - } - } - - // Linear model - ax=(p[i1max].x-p[i0max].x)/(p[i1max].t-p[i0max].t); - bx=p[i0max].x-ax*p[i0max].t; - ay=(p[i1max].y-p[i0max].y)/(p[i1max].t-p[i0max].t); - by=p[i0max].y-ay*p[i0max].t; - - // Find matches - for (k=0;k1) { - while ((arg=getopt(argc,argv,"f:s:R:r:a:pn:"))!=-1) { - switch(arg) { - - case 'f': - fitsfile=optarg; - break; - - case 'p': - plot=1; - break; + if (argc > 1) + { + while ((arg = getopt (argc, argv, "f:s:R:r:a:pn:")) != -1) + { + switch (arg) + { - case 's': - sigma=atof(optarg); - break; + case 'f': + fitsfile = optarg; + break; - case 'R': - drmin=atof(optarg); - break; + case 'p': + plot = 1; + break; - case 'r': - rmin=atof(optarg); - break; + case 's': + sigma = atof (optarg); + break; - case 'n': - mmin=atoi(optarg); - break; - - default: - return 0; - break; - } + case 'R': + drmin = atof (optarg); + break; + + case 'r': + rmin = atof (optarg); + break; + + case 'n': + mmin = atoi (optarg); + break; + + default: + return 0; + break; + } + } + } + else + { + return 0; } - } else { - return 0; - } // Open measurements file - sprintf(filename,"%s.det",fitsfile); - file=fopen(filename,"r"); - if (file==NULL) + sprintf (filename, "%s.det", fitsfile); + file = fopen (filename, "r"); + if (file == NULL) return 0; else - fclose(file); - + fclose (file); + // Read - ff=read_fits(fitsfile); + ff = read_fits (fitsfile); // Fill mask - if (ff.naxis1==720 && ff.naxis2==576) { - for (i=0;iff.naxis1-10 || j>ff.naxis2-10) - ff.mask[k]=0; - } + if (ff.naxis1 == 720 && ff.naxis2 == 576) + { + for (i = 0; i < ff.naxis1; i++) + { + for (j = 0; j < ff.naxis2; j++) + { + k = i + ff.naxis1 * j; + if (i < 10 || i > ff.naxis1 - 10 || j > ff.naxis2 - 10) + ff.mask[k] = 0; + } + } } - } - + // Allocate accumulation array - zsel=(int *) malloc(sizeof(int)*ff.naxis1*ff.naxis2); - for (i=0;i0) { - if (i%4==1) { - sscanf(line,"# %f %f %f %f %f %f %f %f %f",&x[0],&y[0],&t[0],&x[1],&y[1],&t[1],&x[2],&y[2],&t[2]); - cpgsci(5); - cpgpt1(x[0],y[0],4); - cpgmove(x[1],y[1]); - cpgdraw(x[2],y[2]); - } - if (i%4==2) { - line[strlen(line)-1]='\0'; - sprintf(catalog,"%s.dat",line+2); - } - if (i%4==3) { - line[strlen(line)-1]=' '; - cpgstbg(0); - cpgsch(0.8); - cpgsci(1); - cpgmtxt("T",1.0,0.5,0.5,line); - cpgsch(1.0); + sprintf (filename, "%s.det", fitsfile); + file = fopen (filename, "r"); + if (file != NULL) + { + i = 0; + while (fgetline (file, line, LIM) > 0) + { + if (i % 4 == 1) + { + sscanf (line, "# %f %f %f %f %f %f %f %f %f", &x[0], &y[0], + &t[0], &x[1], &y[1], &t[1], &x[2], &y[2], &t[2]); + cpgsci (5); + cpgpt1 (x[0], y[0], 4); + cpgmove (x[1], y[1]); + cpgdraw (x[2], y[2]); + } + if (i % 4 == 2) + { + line[strlen (line) - 1] = '\0'; + sprintf (catalog, "%s.dat", line + 2); + } + if (i % 4 == 3) + { + line[strlen (line) - 1] = ' '; + cpgstbg (0); + cpgsch (0.8); + cpgsci (1); + cpgmtxt ("T", 1.0, 0.5, 0.5, line); + cpgsch (1.0); - printf("Accept observation:\n%s\nto %s\n",line,catalog); - printf("\nPress a to accept, s to skip.\n"); - cpgcurs(&x0,&y0,&c); + printf ("Accept observation:\n%s\nto %s\n", line, catalog); + printf ("\nPress a to accept, s to skip.\n"); + cpgcurs (&x0, &y0, &c); - // Accept - if (c=='a') { - outfile=fopen(catalog,"a"); - fprintf(outfile,"%s\n",line); - fclose(outfile); + // Accept + if (c == 'a') + { + outfile = fopen (catalog, "a"); + fprintf (outfile, "%s\n", line); + fclose (outfile); + } + } + + + i++; } - } - - - i++; } - } - cpgend(); + cpgend (); + - // Free - free(ff.zavg); - free(ff.zstd); - free(ff.zmax); - free(ff.znum); - free(ff.zsig); - free(ff.dt); - free(ff.mask); - free(zsel); + free (ff.zavg); + free (ff.zstd); + free (ff.zmax); + free (ff.znum); + free (ff.zsig); + free (ff.dt); + free (ff.mask); + free (zsel); return 0; } // Read fits fourframe -struct fourframe read_fits(char *filename) +struct fourframe +read_fits (char *filename) { - int i,j,k,l,m; + int i, j, k, l, m; qfitsloader ql; - char key[FITS_LINESZ+1]; - char val[FITS_LINESZ+1]; + char key[FITS_LINESZ + 1]; + char val[FITS_LINESZ + 1]; struct fourframe img; // Copy filename - strcpy(img.filename,filename); + strcpy (img.filename, filename); // Image size - img.naxis1=atoi(qfits_query_hdr(filename,"NAXIS1")); - img.naxis2=atoi(qfits_query_hdr(filename,"NAXIS2")); - img.naxis3=atoi(qfits_query_hdr(filename,"NAXIS3")); + img.naxis1 = atoi (qfits_query_hdr (filename, "NAXIS1")); + img.naxis2 = atoi (qfits_query_hdr (filename, "NAXIS2")); + img.naxis3 = atoi (qfits_query_hdr (filename, "NAXIS3")); // MJD - img.mjd=(double) atof(qfits_query_hdr(filename,"MJD-OBS")); - strcpy(img.nfd,qfits_query_hdr(filename,"DATE-OBS")); + img.mjd = (double) atof (qfits_query_hdr (filename, "MJD-OBS")); + strcpy (img.nfd, qfits_query_hdr (filename, "DATE-OBS")); // COSPAR ID - img.cospar=atoi(qfits_query_hdr(filename,"COSPAR")); + img.cospar = atoi (qfits_query_hdr (filename, "COSPAR")); // Transformation - img.mjd=atof(qfits_query_hdr(filename,"MJD-OBS")); - img.ra0=atof(qfits_query_hdr(filename,"CRVAL1")); - img.de0=atof(qfits_query_hdr(filename,"CRVAL2")); - img.x0=atof(qfits_query_hdr(filename,"CRPIX1")); - img.y0=atof(qfits_query_hdr(filename,"CRPIX2")); - img.a[0]=0.0; - img.a[1]=3600.0*atof(qfits_query_hdr(filename,"CD1_1")); - img.a[2]=3600.0*atof(qfits_query_hdr(filename,"CD1_2")); - img.b[0]=0.0; - img.b[1]=3600.0*atof(qfits_query_hdr(filename,"CD2_1")); - img.b[2]=3600.0*atof(qfits_query_hdr(filename,"CD2_2")); - img.xrms=3600.0*atof(qfits_query_hdr(filename,"CRRES1")); - img.yrms=3600.0*atof(qfits_query_hdr(filename,"CRRES2")); - img.exptime=atof(qfits_query_hdr(filename,"EXPTIME")); - img.nframes=atoi(qfits_query_hdr(filename,"NFRAMES")); + img.mjd = atof (qfits_query_hdr (filename, "MJD-OBS")); + img.ra0 = atof (qfits_query_hdr (filename, "CRVAL1")); + img.de0 = atof (qfits_query_hdr (filename, "CRVAL2")); + img.x0 = atof (qfits_query_hdr (filename, "CRPIX1")); + img.y0 = atof (qfits_query_hdr (filename, "CRPIX2")); + img.a[0] = 0.0; + img.a[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_1")); + img.a[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_2")); + img.b[0] = 0.0; + img.b[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_1")); + img.b[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_2")); + img.xrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES1")); + img.yrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES2")); + img.exptime = atof (qfits_query_hdr (filename, "EXPTIME")); + img.nframes = atoi (qfits_query_hdr (filename, "NFRAMES")); // Timestamps - img.dt=(float *) malloc(sizeof(float)*img.nframes); - for (i=0;i=2000) - sprintf(orb.desig,"%02d%3.0fA",foy-2000,doy+500); + mjd = date2mjd (foy, fom, fod); + doy = mjd2doy (mjd, &foy); + if (foy >= 2000) + sprintf (orb.desig, "%02d%3.0fA", foy - 2000, doy + 500); else - sprintf(orb.desig,"%02d%3.0fA",foy-1900,doy+500); + sprintf (orb.desig, "%02d%3.0fA", foy - 1900, doy + 500); // Find epoch - mjd=date2mjd(year,month,day+hour/24.0+min/1440.0+sec/86400.0); - orb.ep_day=mjd2doy(mjd,&orb.ep_year); - + mjd = + date2mjd (year, month, day + hour / 24.0 + min / 1440.0 + sec / 86400.0); + orb.ep_day = mjd2doy (mjd, &orb.ep_year); + // Set values - orb.satno=no; - orb.eqinc=incl*D2R; - orb.argp=argp*D2R; - orb.ascn=raan*D2R; - orb.ecc=ecc; - orb.bstar=0.0; - orb.rev=XKE*pow(sma/XKMPER,-1.5)*XMNPDA/(2.0*M_PI); + orb.satno = no; + orb.eqinc = incl * D2R; + orb.argp = argp * D2R; + orb.ascn = raan * D2R; + orb.ecc = ecc; + orb.bstar = 0.0; + orb.rev = XKE * pow (sma / XKMPER, -1.5) * XMNPDA / (2.0 * M_PI); // Mean anomaly - v=argl-argp; - e=2*atan(sqrt((1.0-ecc)/(1.0+ecc))*tan(v*D2R/2.0)); - orb.mnan=modulo((e-ecc*sin(e)),2.0*M_PI); - - // Orbit - perigee=sma*(1.0-ecc)-XKMPER; - apogee=sma*(1.0+ecc)-XKMPER; + v = argl - argp; + e = 2 * atan (sqrt ((1.0 - ecc) / (1.0 + ecc)) * tan (v * D2R / 2.0)); + orb.mnan = modulo ((e - ecc * sin (e)), 2.0 * M_PI); - sprintf(line0,"SO %6d %4.1f %7.0fkm x%7.0fkm",so,mag+dm,perigee,apogee); + // Orbit + perigee = sma * (1.0 - ecc) - XKMPER; + apogee = sma * (1.0 + ecc) - XKMPER; + + sprintf (line0, + "SO %6d %4.1f %7.0fkm x%7.0fkm", + so, mag + dm, perigee, apogee); // Format line - format_tle(orb,line1,line2); - printf("%s\n%s\n%s\n",line0,line1,line2); + format_tle (orb, line1, line2); + printf ("%s\n%s\n%s\n", line0, line1, line2); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { FILE *file; - char line[LIM],*fname; - int arg=0; + char line[LIM], *fname; + int arg = 0; // Decode options - while ((arg=getopt(argc,argv,"f:"))!=-1) { - switch(arg) { + while ((arg = getopt (argc, argv, "f:")) != -1) + { + switch (arg) + { - case 'f': - fname=optarg; - break; + case 'f': + fname = optarg; + break; - default: - break; + default: + break; + } } - } - file=fopen(fname,"r"); - while (fgetline(file,line,LIM)>0) - convert(line); - fclose(file); + file = fopen (fname, "r"); + while (fgetline (file, line, LIM) > 0) + convert (line); + fclose (file); return 0; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; + int c, i = 0; - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; @@ -118,123 +129,150 @@ int fgetline(FILE *file,char *s,int lim) } // Compute Date from Julian Day -void mjd2date(double mjd,int *year,int *month,double *day) +void +mjd2date (double mjd, int *year, int *month, double *day) { - double f,jd; - int z,alpha,a,b,c,d,e; + double f, jd; + int z, alpha, a, b, c, d, e; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - *day=b-d-floor(30.6001*e)+f; - if (e<14) - *month=e-1; + if (z < 2299161) + a = z; else - *month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (*month>2) - *year=c-4716; + *day = b - d - floor (30.6001 * e) + f; + if (e < 14) + *month = e - 1; else - *year=c-4715; + *month = e - 13; + + if (*month > 2) + *year = c - 4716; + else + *year = c - 4715; return; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // MJD to DOY -double mjd2doy(double mjd,int *yr) +double +mjd2doy (double mjd, int *yr) { - int year,month,k=2; - double day,doy; - - mjd2date(mjd,&year,&month,&day); + int year, month, k = 2; + double day, doy; - if (year%4==0 && year%400!=0) - k=1; + mjd2date (mjd, &year, &month, &day); - doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - *yr=year; + doy = + floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30; + + *yr = year; return doy; } // Format TLE -void format_tle(orbit_t orb,char *line1,char *line2) +void +format_tle (orbit_t orb, char *line1, char *line2) { - int i,csum; - char sbstar[]=" 00000-0",bstar[13]; + int i, csum; + char sbstar[] = " 00000-0", bstar[13]; // Format Bstar term - if (fabs(orb.bstar)>1e-9) { - sprintf(bstar,"%11.4e",10*orb.bstar); - sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4]; - sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0'; - } + if (fabs (orb.bstar) > 1e-9) + { + sprintf (bstar, "%11.4e", 10 * orb.bstar); + sbstar[0] = bstar[0]; + sbstar[1] = bstar[1]; + sbstar[2] = bstar[3]; + sbstar[3] = bstar[4]; + sbstar[4] = bstar[5]; + sbstar[5] = bstar[6]; + sbstar[6] = bstar[8]; + sbstar[7] = bstar[10]; + sbstar[8] = '\0'; + } // Print lines - sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar); - sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev); + sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0", + orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar); + sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0", + orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc, + DEG (orb.argp), DEG (orb.mnan), orb.rev); // Compute checksums - for (i=0,csum=0;i #include -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int h=0; - double sec,deg,min; - char c,sign,d=' '; + int h = 0; + double sec, deg, min; + char c, sign, d = ' '; double x; char s[14]; - if (argc==1) { - printf("Usage: dec2s [options] \n\nCompute sexagesimal from decimal input x.\n"); - printf("Options: -r gives hours instead of degrees\n"); - printf(" -d uses character a as delimiter\n"); - printf(" -h uses hms as delimiters\n"); - printf(" -s always prints sign\n\n"); - - return -1; - } - + if (argc == 1) + { + printf + ("Usage: dec2s [options] \n\nCompute sexagesimal from decimal input x.\n"); + printf ("Options: -r gives hours instead of degrees\n"); + printf (" -d uses character a as delimiter\n"); + printf (" -h uses hms as delimiters\n"); + printf (" -s always prints sign\n\n"); + + return -1; + } + // Get Decimal Value - x=(double) atof(argv[--argc]); - sign=(x<0 ? '-' : ' '); + x = (double) atof (argv[--argc]); + sign = (x < 0 ? '-' : ' '); // Get Options - while (--argc > 0 && (*++argv)[0] == '-') { - while (c = *++argv[0]) { - if (c == 'r') - x /= 15.; - if (c == 's') - sign=(x<0 ? '-' : '+'); - if (c == 'd') - if (strlen(argv[0])!=1) - d=(*argv)[1]; - if (c == 'h') - h++; + while (--argc > 0 && (*++argv)[0] == '-') + { + while (c = *++argv[0]) + { + if (c == 'r') + x /= 15.; + if (c == 's') + sign = (x < 0 ? '-' : '+'); + if (c == 'd') + if (strlen (argv[0]) != 1) + d = (*argv)[1]; + if (c == 'h') + h++; + } } - } - x=3600.*fabs(x); - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - deg=x; + x = 3600. * fabs (x); + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + deg = x; - if (h==0) - printf("%c%02i%c%02i%c%06.3f\n",sign,(int) deg,d,(int) min,d,(float) sec); + if (h == 0) + printf ("%c%02i%c%02i%c%06.3f\n", sign, (int) deg, d, (int) min, d, + (float) sec); else - printf("%c%02ih%02im%06.3fs\n",sign,(int) deg,(int) min,(float) sec); + printf ("%c%02ih%02im%06.3fs\n", sign, (int) deg, (int) min, (float) sec); return 0; } diff --git a/src/deep.c b/src/deep.c index 570c1ca..603052f 100644 --- a/src/deep.c +++ b/src/deep.c @@ -55,19 +55,20 @@ #include #include -static const char SCCSid[] = "@(#)deep.c 3.04 (C) 1995 psc SatLib: Deep Space effects"; +static const char SCCSid[] = + "@(#)deep.c 3.04 (C) 1995 psc SatLib: Deep Space effects"; #ifndef NO_DEEP_SPACE #include "sgdp4h.h" -extern int Set_LS_zero; /* From sgdp4.c */ +extern int Set_LS_zero; /* From sgdp4.c */ /* ======================= Function prototypes ====================== */ -static void dot_terms_calculated(void); -static void compute_LunarSolar(double tsince); -static void thetag(double ep, real *thegr, double *days50); +static void dot_terms_calculated (void); +static void compute_LunarSolar (double tsince); +static void thetag (double ep, real * thegr, double *days50); /* ===================== Strange constants, etc ===================== */ @@ -101,7 +102,7 @@ static void thetag(double ep, real *thegr, double *days50); #define ROOT54 ((real)2.1765803e-9) #define THDT ((real)4.37526908801129966e-3) -//#define THDT ((real)0.0043752691) +//#define THDT ((real)0.0043752691) #define STEP 720.0 #define MAX_INTEGRATE (STEP * 10000) @@ -109,10 +110,10 @@ static void thetag(double ep, real *thegr, double *days50); /* ======= Global variables used by dpsec(), from dpinit(). ======== */ -static real eo; /* copy of original eccentricity. */ -static real xincl; /* copy of original equatorial inclination. */ +static real eo; /* copy of original eccentricity. */ +static real xincl; /* copy of original equatorial inclination. */ -static int isynfl=0, iresfl=0; +static int isynfl = 0, iresfl = 0; static double atime, xli, xni, xnq, xfact; @@ -123,19 +124,19 @@ static real d2201, d2211, d3210, d3222, d4410, d4422; static real d5220, d5232, d5421, d5433; static real xnddt, xndot, xldot; /* Integrator terms. */ -static real xnddt0, xndot0, xldot0; /* Integrator at epoch. */ +static real xnddt0, xndot0, xldot0; /* Integrator at epoch. */ /* ======== Global Variables used by dpper(), from dpinit(). ======= */ -static int ilsd=0, ilsz=0; +static int ilsd = 0, ilsz = 0; static real zmos, se2, se3, si2, si3, sl2, sl3, sl4; static real sgh2, sgh3, sgh4, sh2, sh3; -static real zmol, ee2, e3 ,xi2, xi3, xl2, xl3, xl4; +static real zmol, ee2, e3, xi2, xi3, xl2, xl3, xl4; static real xgh2, xgh3, xgh4, xh2, xh3; static real pe, pinc, pgh, ph, pl; -static real pgh0, ph0, pe0, pinc0, pl0; /* Added terms to save the epoch values of perturbations. */ +static real pgh0, ph0, pe0, pinc0, pl0; /* Added terms to save the epoch values of perturbations. */ /* ================================================================== @@ -156,392 +157,453 @@ static real pgh0, ph0, pe0, pinc0, pl0; /* Added terms to save the epoch values ================================================================== */ -sgdp4_mode_t SGDP4_dpinit(double epoch, real omegao, real xnodeo, real xmo, - real orb_eo, real orb_xincl, real aodp, double xlldot, - real omgdot, real xnodot, double xnodp) +sgdp4_mode_t +SGDP4_dpinit (double epoch, real omegao, real xnodeo, real xmo, + real orb_eo, real orb_xincl, real aodp, double xlldot, + real omgdot, real xnodot, double xnodp) { -LOCAL_DOUBLE ds50, day, xnodce, bfact=0, gam, c; -LOCAL_REAL ctem, sinq, cosq, aqnv, xmao, stem, eqsq, xnoi, ainv2; -LOCAL_REAL zcosg, zsing, zcosi, zsini, zcosh, zsinh; -LOCAL_REAL cosomo, zcosgl, zcoshl, zcosil, sinomo; -LOCAL_REAL xpidot, zsinil, siniq2, cosiq2; -LOCAL_REAL rteqsq, zsinhl, zsingl; -LOCAL_REAL eoc, sgh, g200, bsq, xno2; -LOCAL_REAL a1, a2, a3, a4, a5, a6, a7, a8, a9, a10; -LOCAL_REAL x1, x2, x3, x4, x5, x6, x7, x8; -LOCAL_REAL z1, z2, z3, z11, z12, z13, z21, z22, z23, z31, z32, z33; -LOCAL_REAL s1, s2, s3, s4, s5, s6, s7, cc, ao, eq, se, shdq, si, sl; -LOCAL_REAL zx, zy, ze, zn; -LOCAL_REAL g201, g211, g310, g300, g322, g410, g422, g520, g533, g521, g532; -LOCAL_REAL f220, f221, f311, f321, f322, f330, f441, f442, f522, f523, f542, f543; -real siniq, cosiq; -real temp0, temp1; -int ls; -sgdp4_mode_t imode = SGDP4_NOT_INIT; -int ishq; + LOCAL_DOUBLE ds50, day, xnodce, bfact = 0, gam, c; + LOCAL_REAL ctem, sinq, cosq, aqnv, xmao, stem, eqsq, xnoi, ainv2; + LOCAL_REAL zcosg, zsing, zcosi, zsini, zcosh, zsinh; + LOCAL_REAL cosomo, zcosgl, zcoshl, zcosil, sinomo; + LOCAL_REAL xpidot, zsinil, siniq2, cosiq2; + LOCAL_REAL rteqsq, zsinhl, zsingl; + LOCAL_REAL eoc, sgh, g200, bsq, xno2; + LOCAL_REAL a1, a2, a3, a4, a5, a6, a7, a8, a9, a10; + LOCAL_REAL x1, x2, x3, x4, x5, x6, x7, x8; + LOCAL_REAL z1, z2, z3, z11, z12, z13, z21, z22, z23, z31, z32, z33; + LOCAL_REAL s1, s2, s3, s4, s5, s6, s7, cc, ao, eq, se, shdq, si, sl; + LOCAL_REAL zx, zy, ze, zn; + LOCAL_REAL g201, g211, g310, g300, g322, g410, g422, g520, g533, g521, g532; + LOCAL_REAL f220, f221, f311, f321, f322, f330, f441, f442, f522, f523, f542, + f543; + real siniq, cosiq; + real temp0, temp1; + int ls; + sgdp4_mode_t imode = SGDP4_NOT_INIT; + int ishq; - /* - Copy the supplied orbital elements to "local" (static to this file) - variables and compute common trig values. - */ - eq = eo = orb_eo; - xincl = orb_xincl; + /* + Copy the supplied orbital elements to "local" (static to this file) + variables and compute common trig values. + */ + eq = eo = orb_eo; + xincl = orb_xincl; - /* Decide on direct or Lyddane Lunar-Solar perturbations. */ - ilsd = 0; - if(xincl >= (real)0.2) ilsd = 1; + /* Decide on direct or Lyddane Lunar-Solar perturbations. */ + ilsd = 0; + if (xincl >= (real) 0.2) + ilsd = 1; - /* Drop some terms below 3 deg inclination. */ - ishq = 0; + /* Drop some terms below 3 deg inclination. */ + ishq = 0; #define SHQT 0.052359877 - if (xincl >= (real)SHQT) ishq = 1; /* As per reoprt #3. */ + if (xincl >= (real) SHQT) + ishq = 1; /* As per reoprt #3. */ - SINCOS(omegao, &sinomo, &cosomo); - SINCOS(xnodeo, &sinq, &cosq); - SINCOS(xincl, &siniq, &cosiq); + SINCOS (omegao, &sinomo, &cosomo); + SINCOS (xnodeo, &sinq, &cosq); + SINCOS (xincl, &siniq, &cosiq); - if (fabs(siniq) <= SIN_EPS) - { - siniq = SIGN(SIN_EPS, siniq); - } + if (fabs (siniq) <= SIN_EPS) + { + siniq = SIGN (SIN_EPS, siniq); + } - cosiq2 = cosiq * cosiq; - siniq2 = siniq * siniq; + cosiq2 = cosiq * cosiq; + siniq2 = siniq * siniq; - ao = aodp; - omgdt = omgdot; - eqsq = eo * eo; - bsq = (real)1.0 - eqsq; - rteqsq = SQRT(bsq); - thetag(epoch, &thgr, &ds50); + ao = aodp; + omgdt = omgdot; + eqsq = eo * eo; + bsq = (real) 1.0 - eqsq; + rteqsq = SQRT (bsq); + thetag (epoch, &thgr, &ds50); - /*printf("# epoch = %.8f ds50 = %.8f thgr = %f\n", epoch, ds50, DEG(thgr));*/ + /*printf("# epoch = %.8f ds50 = %.8f thgr = %f\n", epoch, ds50, DEG(thgr)); */ - xnq = xnodp; - aqnv = (real)1.0 / ao; - xmao = xmo; - xpidot = omgdt + xnodot; - omegaq = omegao; + xnq = xnodp; + aqnv = (real) 1.0 / ao; + xmao = xmo; + xpidot = omgdt + xnodot; + omegaq = omegao; - /* INITIALIZE LUNAR SOLAR TERMS */ + /* INITIALIZE LUNAR SOLAR TERMS */ - day = ds50 + 18261.5; + day = ds50 + 18261.5; - xnodce = 4.523602 - day * 9.2422029e-4; - temp0 = (real)fmod(xnodce, TWOPI); - SINCOS(temp0, &stem, &ctem); + xnodce = 4.523602 - day * 9.2422029e-4; + temp0 = (real) fmod (xnodce, TWOPI); + SINCOS (temp0, &stem, &ctem); - zcosil = (real)0.91375164 - ctem * (real)0.03568096; - zsinil = SQRT((real)1.0 - zcosil * zcosil); - zsinhl = stem * (real)0.089683511 / zsinil; - zcoshl = SQRT((real)1.0 - zsinhl * zsinhl); - c = day * 0.2299715 + 4.7199672; - gam = day * 0.001944368 + 5.8351514; - zmol = (real)MOD2PI(c - gam); - zx = stem * (real)0.39785416 / zsinil; - zy = zcoshl * ctem + zsinhl * (real)0.91744867 * stem; - zx = ATAN2(zx, zy); - zx = (real)fmod(gam + zx - xnodce, TWOPI); - SINCOS(zx, &zsingl, &zcosgl); - zmos = (real)MOD2PI(day * 0.017201977 + 6.2565837); + zcosil = (real) 0.91375164 - ctem * (real) 0.03568096; + zsinil = SQRT ((real) 1.0 - zcosil * zcosil); + zsinhl = stem * (real) 0.089683511 / zsinil; + zcoshl = SQRT ((real) 1.0 - zsinhl * zsinhl); + c = day * 0.2299715 + 4.7199672; + gam = day * 0.001944368 + 5.8351514; + zmol = (real) MOD2PI (c - gam); + zx = stem * (real) 0.39785416 / zsinil; + zy = zcoshl * ctem + zsinhl * (real) 0.91744867 *stem; + zx = ATAN2 (zx, zy); + zx = (real) fmod (gam + zx - xnodce, TWOPI); + SINCOS (zx, &zsingl, &zcosgl); + zmos = (real) MOD2PI (day * 0.017201977 + 6.2565837); - /* DO SOLAR TERMS */ + /* DO SOLAR TERMS */ - zcosg = ZCOSGS; - zsing = ZSINGS; - zcosi = ZCOSIS; - zsini = ZSINIS; - zcosh = cosq; - zsinh = sinq; - cc = C1SS; - zn = ZNS; - ze = ZES; - xnoi = (real)(1.0 / xnq); + zcosg = ZCOSGS; + zsing = ZSINGS; + zcosi = ZCOSIS; + zsini = ZSINIS; + zcosh = cosq; + zsinh = sinq; + cc = C1SS; + zn = ZNS; + ze = ZES; + xnoi = (real) (1.0 / xnq); - for(ls = 0; ls < 2; ls++) - { - a1 = zcosg * zcosh + zsing * zcosi * zsinh; - a3 = -zsing * zcosh + zcosg * zcosi * zsinh; - a7 = -zcosg * zsinh + zsing * zcosi * zcosh; - a8 = zsing * zsini; - a9 = zsing * zsinh + zcosg * zcosi * zcosh; - a10 = zcosg * zsini; - a2 = cosiq * a7 + siniq * a8; - a4 = cosiq * a9 + siniq * a10; - a5 = -siniq * a7 + cosiq * a8; - a6 = -siniq * a9 + cosiq * a10; + for (ls = 0; ls < 2; ls++) + { + a1 = zcosg * zcosh + zsing * zcosi * zsinh; + a3 = -zsing * zcosh + zcosg * zcosi * zsinh; + a7 = -zcosg * zsinh + zsing * zcosi * zcosh; + a8 = zsing * zsini; + a9 = zsing * zsinh + zcosg * zcosi * zcosh; + a10 = zcosg * zsini; + a2 = cosiq * a7 + siniq * a8; + a4 = cosiq * a9 + siniq * a10; + a5 = -siniq * a7 + cosiq * a8; + a6 = -siniq * a9 + cosiq * a10; - x1 = a1 * cosomo + a2 * sinomo; - x2 = a3 * cosomo + a4 * sinomo; - x3 = -a1 * sinomo + a2 * cosomo; - x4 = -a3 * sinomo + a4 * cosomo; - x5 = a5 * sinomo; - x6 = a6 * sinomo; - x7 = a5 * cosomo; - x8 = a6 * cosomo; + x1 = a1 * cosomo + a2 * sinomo; + x2 = a3 * cosomo + a4 * sinomo; + x3 = -a1 * sinomo + a2 * cosomo; + x4 = -a3 * sinomo + a4 * cosomo; + x5 = a5 * sinomo; + x6 = a6 * sinomo; + x7 = a5 * cosomo; + x8 = a6 * cosomo; - z31 = x1 * (real)12.0 * x1 - x3 * (real)3.0 * x3; - z32 = x1 * (real)24.0 * x2 - x3 * (real)6.0 * x4; - z33 = x2 * (real)12.0 * x2 - x4 * (real)3.0 * x4; - z1 = (a1 * a1 + a2 * a2) * (real)3.0 + z31 * eqsq; - z2 = (a1 * a3 + a2 * a4) * (real)6.0 + z32 * eqsq; - z3 = (a3 * a3 + a4 * a4) * (real)3.0 + z33 * eqsq; - z11 = a1 * (real)-6.0 * a5 + eqsq * (x1 * (real)-24.0 * x7 - x3 * - (real)6.0 * x5); - z12 = (a1 * a6 + a3 * a5) * (real)-6.0 + eqsq * ((x2 * x7 + - x1 * x8) * (real)-24.0 - (x3 * x6 + x4 * x5) * (real)6.0); - z13 = a3 * (real)-6.0 * a6 + eqsq * (x2 * (real)-24.0 * x8 - x4 * - (real)6.0 * x6); - z21 = a2 * (real)6.0 * a5 + eqsq * (x1 * (real)24.0 * x5 - - x3 * (real)6.0 * x7); - z22 = (a4 * a5 + a2 * a6) * (real)6.0 + eqsq * ((x2 * x5 + x1 * x6) * - (real)24.0 - (x4 * x7 + x3 * x8) * (real)6.0); - z23 = a4 * (real)6.0 * a6 + eqsq * (x2 * (real)24.0 * x6 - x4 * - (real)6.0 * x8); - z1 = z1 + z1 + bsq * z31; - z2 = z2 + z2 + bsq * z32; - z3 = z3 + z3 + bsq * z33; - s3 = cc * xnoi; - s2 = s3 * (real)-0.5 / rteqsq; - s4 = s3 * rteqsq; - s1 = eq * (real)-15.0 * s4; - s5 = x1 * x3 + x2 * x4; - s6 = x2 * x3 + x1 * x4; - s7 = x2 * x4 - x1 * x3; - se = s1 * zn * s5; - si = s2 * zn * (z11 + z13); - sl = -zn * s3 * (z1 + z3 - (real)14.0 - eqsq * (real)6.0); - sgh = s4 * zn * (z31 + z33 - (real)6.0); + z31 = x1 * (real) 12.0 *x1 - x3 * (real) 3.0 *x3; + z32 = x1 * (real) 24.0 *x2 - x3 * (real) 6.0 *x4; + z33 = x2 * (real) 12.0 *x2 - x4 * (real) 3.0 *x4; + z1 = (a1 * a1 + a2 * a2) * (real) 3.0 + z31 * eqsq; + z2 = (a1 * a3 + a2 * a4) * (real) 6.0 + z32 * eqsq; + z3 = (a3 * a3 + a4 * a4) * (real) 3.0 + z33 * eqsq; + z11 = a1 * (real) - 6.0 * a5 + eqsq * (x1 * (real) - 24.0 * x7 - x3 * + (real) 6.0 * x5); + z12 = (a1 * a6 + a3 * a5) * (real) - 6.0 + eqsq * ((x2 * x7 + + x1 * x8) * (real) - + 24.0 - (x3 * x6 + + x4 * x5) * + (real) 6.0); + z13 = + a3 * (real) - 6.0 * a6 + eqsq * (x2 * (real) - 24.0 * x8 - + x4 * (real) 6.0 * x6); + z21 = + a2 * (real) 6.0 *a5 + eqsq * (x1 * (real) 24.0 * x5 - + x3 * (real) 6.0 * x7); + z22 = + (a4 * a5 + a2 * a6) * (real) 6.0 + + eqsq * ((x2 * x5 + x1 * x6) * (real) 24.0 - + (x4 * x7 + x3 * x8) * (real) 6.0); + z23 = + a4 * (real) 6.0 *a6 + eqsq * (x2 * (real) 24.0 * x6 - + x4 * (real) 6.0 * x8); + z1 = z1 + z1 + bsq * z31; + z2 = z2 + z2 + bsq * z32; + z3 = z3 + z3 + bsq * z33; + s3 = cc * xnoi; + s2 = s3 * (real) - 0.5 / rteqsq; + s4 = s3 * rteqsq; + s1 = eq * (real) - 15.0 * s4; + s5 = x1 * x3 + x2 * x4; + s6 = x2 * x3 + x1 * x4; + s7 = x2 * x4 - x1 * x3; + se = s1 * zn * s5; + si = s2 * zn * (z11 + z13); + sl = -zn * s3 * (z1 + z3 - (real) 14.0 - eqsq * (real) 6.0); + sgh = s4 * zn * (z31 + z33 - (real) 6.0); - shdq = 0; - if(ishq) - { - real sh = -zn * s2 * (z21 + z23); - shdq = sh / siniq; - } + shdq = 0; + if (ishq) + { + real sh = -zn * s2 * (z21 + z23); + shdq = sh / siniq; + } - ee2 = s1 * (real)2.0 * s6; - e3 = s1 * (real)2.0 * s7; - xi2 = s2 * (real)2.0 * z12; - xi3 = s2 * (real)2.0 * (z13 - z11); - xl2 = s3 * (real)-2.0 * z2; - xl3 = s3 * (real)-2.0 * (z3 - z1); - xl4 = s3 * (real)-2.0 * ((real)-21.0 - eqsq * (real)9.0) * ze; - xgh2 = s4 * (real)2.0 * z32; - xgh3 = s4 * (real)2.0 * (z33 - z31); - xgh4 = s4 * (real)-18.0 * ze; - xh2 = s2 * (real)-2.0 * z22; - xh3 = s2 * (real)-2.0 * (z23 - z21); + ee2 = s1 * (real) 2.0 *s6; + e3 = s1 * (real) 2.0 *s7; + xi2 = s2 * (real) 2.0 *z12; + xi3 = s2 * (real) 2.0 *(z13 - z11); + xl2 = s3 * (real) - 2.0 * z2; + xl3 = s3 * (real) - 2.0 * (z3 - z1); + xl4 = s3 * (real) - 2.0 * ((real) - 21.0 - eqsq * (real) 9.0) * ze; + xgh2 = s4 * (real) 2.0 *z32; + xgh3 = s4 * (real) 2.0 *(z33 - z31); + xgh4 = s4 * (real) - 18.0 * ze; + xh2 = s2 * (real) - 2.0 * z22; + xh3 = s2 * (real) - 2.0 * (z23 - z21); - if (ls == 1) break; + if (ls == 1) + break; - /* DO LUNAR TERMS */ + /* DO LUNAR TERMS */ - sse = se; - ssi = si; - ssl = sl; - ssh = shdq; - ssg = sgh - cosiq * ssh; - se2 = ee2; - si2 = xi2; - sl2 = xl2; - sgh2 = xgh2; - sh2 = xh2; - se3 = e3; - si3 = xi3; - sl3 = xl3; - sgh3 = xgh3; - sh3 = xh3; - sl4 = xl4; - sgh4 = xgh4; - zcosg = zcosgl; - zsing = zsingl; - zcosi = zcosil; - zsini = zsinil; - zcosh = zcoshl * cosq + zsinhl * sinq; - zsinh = sinq * zcoshl - cosq * zsinhl; - zn = ZNL; - cc = C1L; - ze = ZEL; - } + sse = se; + ssi = si; + ssl = sl; + ssh = shdq; + ssg = sgh - cosiq * ssh; + se2 = ee2; + si2 = xi2; + sl2 = xl2; + sgh2 = xgh2; + sh2 = xh2; + se3 = e3; + si3 = xi3; + sl3 = xl3; + sgh3 = xgh3; + sh3 = xh3; + sl4 = xl4; + sgh4 = xgh4; + zcosg = zcosgl; + zsing = zsingl; + zcosi = zcosil; + zsini = zsinil; + zcosh = zcoshl * cosq + zsinhl * sinq; + zsinh = sinq * zcoshl - cosq * zsinhl; + zn = ZNL; + cc = C1L; + ze = ZEL; + } - sse += se; - ssi += si; - ssl += sl; - ssg += sgh - cosiq * shdq; - ssh += shdq; + sse += se; + ssi += si; + ssl += sl; + ssg += sgh - cosiq * shdq; + ssh += shdq; - if (xnq < 0.0052359877 && xnq > 0.0034906585) - { - /* 24h SYNCHRONOUS RESONANCE TERMS INITIALIZATION */ - iresfl = 1; - isynfl = 1; - g200 = eqsq * (eqsq * (real)0.8125 - (real)2.5) + (real)1.0; - g310 = eqsq * (real)2.0 + (real)1.0; - g300 = eqsq * (eqsq * (real)6.60937 - (real)6.0) + (real)1.0; - f220 = (cosiq + (real)1.0) * (real)0.75 * (cosiq + (real)1.0); - f311 = siniq * (real)0.9375 * siniq * (cosiq * (real)3.0 + - (real)1.0) - (cosiq + (real)1.0) * (real)0.75; - f330 = cosiq + (real)1.0; - f330 = f330 * (real)1.875 * f330 * f330; - del1 = (real)3.0 * (real)(xnq * xnq * aqnv * aqnv); - del2 = del1 * (real)2.0 * f220 * g200 * Q22; - del3 = del1 * (real)3.0 * f330 * g300 * Q33 * aqnv; - del1 = del1 * f311 * g310 * Q31 * aqnv; - fasx2 = (real)0.13130908; - fasx4 = (real)2.8843198; - fasx6 = (real)0.37448087; - xlamo = xmao + xnodeo + omegao - thgr; - bfact = xlldot + xpidot - THDT; - bfact += (double)(ssl + ssg + ssh); - } - else if (xnq >= 0.00826 && xnq <= 0.00924 && eq >= (real)0.5) - { - /* GEOPOTENTIAL RESONANCE INITIALIZATION FOR 12 HOUR ORBITS */ - iresfl = 1; - isynfl = 0; - eoc = eq * eqsq; - g201 = (real)-0.306 - (eq - (real)0.64) * (real)0.44; + if (xnq < 0.0052359877 && xnq > 0.0034906585) + { + /* 24h SYNCHRONOUS RESONANCE TERMS INITIALIZATION */ + iresfl = 1; + isynfl = 1; + g200 = eqsq * (eqsq * (real) 0.8125 - (real) 2.5) + (real) 1.0; + g310 = eqsq * (real) 2.0 + (real) 1.0; + g300 = eqsq * (eqsq * (real) 6.60937 - (real) 6.0) + (real) 1.0; + f220 = (cosiq + (real) 1.0) * (real) 0.75 *(cosiq + (real) 1.0); + f311 = siniq * (real) 0.9375 *siniq * (cosiq * (real) 3.0 + + (real) 1.0) - (cosiq + + (real) 1.0) * + (real) 0.75; + f330 = cosiq + (real) 1.0; + f330 = f330 * (real) 1.875 *f330 * f330; + del1 = (real) 3.0 *(real) (xnq * xnq * aqnv * aqnv); + del2 = del1 * (real) 2.0 *f220 * g200 * Q22; + del3 = del1 * (real) 3.0 *f330 * g300 * Q33 * aqnv; + del1 = del1 * f311 * g310 * Q31 * aqnv; + fasx2 = (real) 0.13130908; + fasx4 = (real) 2.8843198; + fasx6 = (real) 0.37448087; + xlamo = xmao + xnodeo + omegao - thgr; + bfact = xlldot + xpidot - THDT; + bfact += (double) (ssl + ssg + ssh); + } + else if (xnq >= 0.00826 && xnq <= 0.00924 && eq >= (real) 0.5) + { + /* GEOPOTENTIAL RESONANCE INITIALIZATION FOR 12 HOUR ORBITS */ + iresfl = 1; + isynfl = 0; + eoc = eq * eqsq; + g201 = (real) - 0.306 - (eq - (real) 0.64) * (real) 0.44; - if (eq <= (real)0.65) - { - g211 = (real)3.616 - eq * (real)13.247 + eqsq * (real)16.29; - g310 = eq * (real)117.39 - (real)19.302 - eqsq * (real)228.419 + eoc * (real)156.591; - g322 = eq * (real)109.7927 - (real)18.9068 - eqsq * (real)214.6334 + eoc * (real)146.5816; - g410 = eq * (real)242.694 - (real)41.122 - eqsq * (real)471.094 + eoc * (real)313.953; - g422 = eq * (real)841.88 - (real)146.407 - eqsq * (real)1629.014 + eoc * (real)1083.435; - g520 = eq * (real)3017.977 - (real)532.114 - eqsq * 5740.032 + eoc * (real)3708.276; - } - else - { - g211 = eq * (real)331.819 - (real)72.099 - eqsq * (real)508.738 + eoc * (real)266.724; - g310 = eq * (real)1582.851 - (real)346.844 - eqsq * (real)2415.925 + eoc * (real)1246.113; - g322 = eq * (real)1554.908 - (real)342.585 - eqsq * (real)2366.899 + eoc * (real)1215.972; - g410 = eq * (real)4758.686 - (real)1052.797 - eqsq * (real)7193.992 + eoc * (real)3651.957; - g422 = eq * (real)16178.11 - (real)3581.69 - eqsq * (real)24462.77 + eoc * (real)12422.52; + if (eq <= (real) 0.65) + { + g211 = (real) 3.616 - eq * (real) 13.247 + eqsq * (real) 16.29; + g310 = + eq * (real) 117.39 - (real) 19.302 - eqsq * (real) 228.419 + + eoc * (real) 156.591; + g322 = + eq * (real) 109.7927 - (real) 18.9068 - eqsq * (real) 214.6334 + + eoc * (real) 146.5816; + g410 = + eq * (real) 242.694 - (real) 41.122 - eqsq * (real) 471.094 + + eoc * (real) 313.953; + g422 = + eq * (real) 841.88 - (real) 146.407 - eqsq * (real) 1629.014 + + eoc * (real) 1083.435; + g520 = + eq * (real) 3017.977 - (real) 532.114 - eqsq * 5740.032 + + eoc * (real) 3708.276; + } + else + { + g211 = + eq * (real) 331.819 - (real) 72.099 - eqsq * (real) 508.738 + + eoc * (real) 266.724; + g310 = + eq * (real) 1582.851 - (real) 346.844 - eqsq * (real) 2415.925 + + eoc * (real) 1246.113; + g322 = + eq * (real) 1554.908 - (real) 342.585 - eqsq * (real) 2366.899 + + eoc * (real) 1215.972; + g410 = + eq * (real) 4758.686 - (real) 1052.797 - eqsq * (real) 7193.992 + + eoc * (real) 3651.957; + g422 = + eq * (real) 16178.11 - (real) 3581.69 - eqsq * (real) 24462.77 + + eoc * (real) 12422.52; - if (eq <= (real)0.715) - { - g520 = (real)1464.74 - eq * (real)4664.75 + eqsq * (real)3763.64; - } - else - { - g520 = eq * (real)29936.92 - (real)5149.66 - eqsq * (real)54087.36 + eoc * (real)31324.56; - } - } + if (eq <= (real) 0.715) + { + g520 = + (real) 1464.74 - eq * (real) 4664.75 + eqsq * (real) 3763.64; + } + else + { + g520 = + eq * (real) 29936.92 - (real) 5149.66 - + eqsq * (real) 54087.36 + eoc * (real) 31324.56; + } + } - if (eq < (real)0.7) - { - g533 = eq * (real)4988.61 - (real)919.2277 - eqsq * (real)9064.77 + eoc * (real)5542.21; - g521 = eq * (real)4568.6173 - (real)822.71072 - eqsq * (real)8491.4146 + eoc * (real)5337.524; - g532 = eq * (real)4690.25 - (real)853.666 - eqsq * (real)8624.77 + eoc * (real)5341.4; - } - else - { - g533 = eq * (real)161616.52 - (real)37995.78 - eqsq * (real)229838.2 + eoc * (real)109377.94; - g521 = eq * (real)218913.95 - (real)51752.104 - eqsq * (real)309468.16 + eoc * (real)146349.42; - g532 = eq * (real)170470.89 - (real)40023.88 - eqsq * (real)242699.48 + eoc * (real)115605.82; - } + if (eq < (real) 0.7) + { + g533 = + eq * (real) 4988.61 - (real) 919.2277 - eqsq * (real) 9064.77 + + eoc * (real) 5542.21; + g521 = + eq * (real) 4568.6173 - (real) 822.71072 - + eqsq * (real) 8491.4146 + eoc * (real) 5337.524; + g532 = + eq * (real) 4690.25 - (real) 853.666 - eqsq * (real) 8624.77 + + eoc * (real) 5341.4; + } + else + { + g533 = + eq * (real) 161616.52 - (real) 37995.78 - eqsq * (real) 229838.2 + + eoc * (real) 109377.94; + g521 = + eq * (real) 218913.95 - (real) 51752.104 - + eqsq * (real) 309468.16 + eoc * (real) 146349.42; + g532 = + eq * (real) 170470.89 - (real) 40023.88 - + eqsq * (real) 242699.48 + eoc * (real) 115605.82; + } - f220 = (cosiq * (real)2.0 + (real)1.0 + cosiq2) * (real)0.75; - f221 = siniq2 * (real)1.5; - f321 = siniq * (real)1.875 * ((real)1.0 - cosiq * (real)2.0 - cosiq2 * (real)3.0); - f322 = siniq * (real)-1.875 * (cosiq * (real)2.0 + (real)1.0 - cosiq2 * (real)3.0); - f441 = siniq2 * (real)35.0 * f220; - f442 = siniq2 * (real)39.375 * siniq2; - f522 = siniq * (real)9.84375 * (siniq2 * ((real)1.0 - cosiq * - (real)2.0 - cosiq2 * (real)5.0) + (cosiq * (real)4.0 - - (real)2.0 + cosiq2 * (real)6.0) * (real)0.33333333); - f523 = siniq * (siniq2 * (real)4.92187512 * ((real)-2.0 - cosiq * - (real)4.0 + cosiq2 * (real)10.0) + (cosiq * (real)2.0 + - (real)1.0 - cosiq2 * (real)3.0) * (real)6.56250012); - f542 = siniq * (real)29.53125 * ((real)2.0 - cosiq * (real)8.0 + - cosiq2 * (cosiq * (real)8.0 - (real)12.0 + cosiq2 * - (real)10.0)); - f543 = siniq * (real)29.53125 * ((real)-2.0 - cosiq * (real)8.0 + - cosiq2 * (cosiq * (real)8.0 + (real)12.0 - cosiq2 * - (real)10.0)); - xno2 = (real)(xnq * xnq); - ainv2 = aqnv * aqnv; - temp1 = xno2 * (real)3.0 * ainv2; - temp0 = temp1 * ROOT22; - d2201 = temp0 * f220 * g201; - d2211 = temp0 * f221 * g211; - temp1 *= aqnv; - temp0 = temp1 * ROOT32; - d3210 = temp0 * f321 * g310; - d3222 = temp0 * f322 * g322; - temp1 *= aqnv; - temp0 = temp1 * (real)2.0 * ROOT44; - d4410 = temp0 * f441 * g410; - d4422 = temp0 * f442 * g422; - temp1 *= aqnv; - temp0 = temp1 * ROOT52; - d5220 = temp0 * f522 * g520; - d5232 = temp0 * f523 * g532; - temp0 = temp1 * (real)2.0 * ROOT54; - d5421 = temp0 * f542 * g521; - d5433 = temp0 * f543 * g533; - xlamo = xmao + xnodeo + xnodeo - thgr - thgr; - bfact = xlldot + xnodot + xnodot - THDT - THDT; - bfact += (double)(ssl + ssh + ssh); - } - else - { - /* NON RESONANT ORBITS */ - iresfl = 0; - isynfl = 0; - } + f220 = (cosiq * (real) 2.0 + (real) 1.0 + cosiq2) * (real) 0.75; + f221 = siniq2 * (real) 1.5; + f321 = + siniq * (real) 1.875 *((real) 1.0 - cosiq * (real) 2.0 - + cosiq2 * (real) 3.0); + f322 = + siniq * (real) - 1.875 * (cosiq * (real) 2.0 + (real) 1.0 - + cosiq2 * (real) 3.0); + f441 = siniq2 * (real) 35.0 *f220; + f442 = siniq2 * (real) 39.375 *siniq2; + f522 = siniq * (real) 9.84375 *(siniq2 * ((real) 1.0 - cosiq * + (real) 2.0 - + cosiq2 * (real) 5.0) + + (cosiq * (real) 4.0 - (real) 2.0 + + cosiq2 * (real) 6.0) * + (real) 0.33333333); + f523 = + siniq * (siniq2 * (real) 4.92187512 * + ((real) - 2.0 - cosiq * (real) 4.0 + cosiq2 * (real) 10.0) + + (cosiq * (real) 2.0 + (real) 1.0 - + cosiq2 * (real) 3.0) * (real) 6.56250012); + f542 = + siniq * (real) 29.53125 *((real) 2.0 - cosiq * (real) 8.0 + + cosiq2 * (cosiq * (real) 8.0 - (real) 12.0 + + cosiq2 * (real) 10.0)); + f543 = + siniq * (real) 29.53125 *((real) - 2.0 - cosiq * (real) 8.0 + + cosiq2 * (cosiq * (real) 8.0 + (real) 12.0 - + cosiq2 * (real) 10.0)); + xno2 = (real) (xnq * xnq); + ainv2 = aqnv * aqnv; + temp1 = xno2 * (real) 3.0 *ainv2; + temp0 = temp1 * ROOT22; + d2201 = temp0 * f220 * g201; + d2211 = temp0 * f221 * g211; + temp1 *= aqnv; + temp0 = temp1 * ROOT32; + d3210 = temp0 * f321 * g310; + d3222 = temp0 * f322 * g322; + temp1 *= aqnv; + temp0 = temp1 * (real) 2.0 *ROOT44; + d4410 = temp0 * f441 * g410; + d4422 = temp0 * f442 * g422; + temp1 *= aqnv; + temp0 = temp1 * ROOT52; + d5220 = temp0 * f522 * g520; + d5232 = temp0 * f523 * g532; + temp0 = temp1 * (real) 2.0 *ROOT54; + d5421 = temp0 * f542 * g521; + d5433 = temp0 * f543 * g533; + xlamo = xmao + xnodeo + xnodeo - thgr - thgr; + bfact = xlldot + xnodot + xnodot - THDT - THDT; + bfact += (double) (ssl + ssh + ssh); + } + else + { + /* NON RESONANT ORBITS */ + iresfl = 0; + isynfl = 0; + } - if(iresfl == 0) - { - /* Non-resonant orbits. */ - imode = SGDP4_DEEP_NORM; - } - else - { - /* INITIALIZE INTEGRATOR */ - xfact = bfact - xnq; - xli = (double)xlamo; - xni = xnq; - atime = 0.0; + if (iresfl == 0) + { + /* Non-resonant orbits. */ + imode = SGDP4_DEEP_NORM; + } + else + { + /* INITIALIZE INTEGRATOR */ + xfact = bfact - xnq; + xli = (double) xlamo; + xni = xnq; + atime = 0.0; - dot_terms_calculated(); + dot_terms_calculated (); - /* Save the "dot" terms for integrator re-start. */ - xnddt0 = xnddt; - xndot0 = xndot; - xldot0 = xldot; + /* Save the "dot" terms for integrator re-start. */ + xnddt0 = xnddt; + xndot0 = xndot; + xldot0 = xldot; - if (isynfl) - imode = SGDP4_DEEP_SYNC; - else - imode = SGDP4_DEEP_RESN; - } + if (isynfl) + imode = SGDP4_DEEP_SYNC; + else + imode = SGDP4_DEEP_RESN; + } - /* Set up for original mode (LS terms at epoch non-zero). */ - ilsz = 0; - pgh0 = ph0 = pe0 = pinc0 = pl0 = (real)0.0; + /* Set up for original mode (LS terms at epoch non-zero). */ + ilsz = 0; + pgh0 = ph0 = pe0 = pinc0 = pl0 = (real) 0.0; - if(Set_LS_zero) - { - /* Save the epoch case Lunar-Solar terms to remove this bias for - * actual computations later on. - * Not sure if this is a good idea. - */ - compute_LunarSolar(0.0); + if (Set_LS_zero) + { + /* Save the epoch case Lunar-Solar terms to remove this bias for + * actual computations later on. + * Not sure if this is a good idea. + */ + compute_LunarSolar (0.0); - pgh0 = pgh; - ph0 = ph; - pe0 = pe; - pinc0 = pinc; - pl0 = pl; - ilsz = 1; - } + pgh0 = pgh; + ph0 = ph; + pe0 = pe; + pinc0 = pinc; + pl0 = pl; + ilsz = 1; + } -return imode; -} /* SGDP4_dpinit */ + return imode; +} /* SGDP4_dpinit */ /* ===================================================================== @@ -559,87 +621,91 @@ return imode; ===================================================================== */ -int SGDP4_dpsec(double *xll, real *omgasm, real *xnodes, real *em, - real *xinc, double *xn, double tsince) +int +SGDP4_dpsec (double *xll, real * omgasm, real * xnodes, real * em, + real * xinc, double *xn, double tsince) { -LOCAL_DOUBLE delt, ft, xl; -real temp0; + LOCAL_DOUBLE delt, ft, xl; + real temp0; - *xll += ssl * tsince; - *omgasm += ssg * tsince; - *xnodes += ssh * tsince; - *em += sse * tsince; - *xinc += ssi * tsince; + *xll += ssl * tsince; + *omgasm += ssg * tsince; + *xnodes += ssh * tsince; + *em += sse * tsince; + *xinc += ssi * tsince; - if (iresfl == 0) return 0; + if (iresfl == 0) + return 0; - /* - * A minor increase in some efficiency can be had by restarting if - * the new time is closer to epoch than to the old integrated - * time. This also forces a re-start on a change in sign (i.e. going - * through zero time) as then we have |tsince - atime| > |tsince| - * as well. Second test is for stepping back towards zero, forcing a restart - * if close enough rather than integrating to zero. - */ + /* + * A minor increase in some efficiency can be had by restarting if + * the new time is closer to epoch than to the old integrated + * time. This also forces a re-start on a change in sign (i.e. going + * through zero time) as then we have |tsince - atime| > |tsince| + * as well. Second test is for stepping back towards zero, forcing a restart + * if close enough rather than integrating to zero. + */ #define AHYST 1.0 - /* Most accurate (OK, most _consistant_) method. Restart if need to - * integrate 'backwards' significantly from current point. - */ - if(fabs(tsince) < STEP || - (atime > 0.0 && tsince < atime - AHYST) || - (atime < 0.0 && tsince > atime + AHYST)) - { - /* Epoch restart if we are at, or have crossed, tsince==0 */ - atime = 0.0; - xni = xnq; - xli = (double)xlamo; - /* Restore the old "dot" terms. */ - xnddt = xnddt0; - xndot = xndot0; - xldot = xldot0; - } + /* Most accurate (OK, most _consistant_) method. Restart if need to + * integrate 'backwards' significantly from current point. + */ + if (fabs (tsince) < STEP || + (atime > 0.0 && tsince < atime - AHYST) || + (atime < 0.0 && tsince > atime + AHYST)) + { + /* Epoch restart if we are at, or have crossed, tsince==0 */ + atime = 0.0; + xni = xnq; + xli = (double) xlamo; + /* Restore the old "dot" terms. */ + xnddt = xnddt0; + xndot = xndot0; + xldot = xldot0; + } - ft = tsince - atime; + ft = tsince - atime; - if (fabs(ft) > MAX_INTEGRATE) - { - fatal_error("SGDP4_dpsec: Integration limit reached"); - return -1; - } + if (fabs (ft) > MAX_INTEGRATE) + { + fatal_error ("SGDP4_dpsec: Integration limit reached"); + return -1; + } - if (fabs(ft) >= STEP) - { - /* - Do integration if required. Find the step direction to - make 'atime' catch up with 'tsince'. - */ - delt = (tsince >= atime ? STEP : -STEP); + if (fabs (ft) >= STEP) + { + /* + Do integration if required. Find the step direction to + make 'atime' catch up with 'tsince'. + */ + delt = (tsince >= atime ? STEP : -STEP); - do { - /* INTEGRATOR (using the last "dot" terms). */ - xli += delt * (xldot + delt * (real)0.5 * xndot); - xni += delt * (xndot + delt * (real)0.5 * xnddt); - atime += delt; + do + { + /* INTEGRATOR (using the last "dot" terms). */ + xli += delt * (xldot + delt * (real) 0.5 * xndot); + xni += delt * (xndot + delt * (real) 0.5 * xnddt); + atime += delt; - dot_terms_calculated(); + dot_terms_calculated (); - /* Are we close enough now ? */ - ft = tsince - atime; - } while (fabs(ft) >= STEP); - } + /* Are we close enough now ? */ + ft = tsince - atime; + } + while (fabs (ft) >= STEP); + } - xl = xli + ft * (xldot + ft * (real)0.5 * xndot); - *xn = xni + ft * (xndot + ft * (real)0.5 * xnddt); + xl = xli + ft * (xldot + ft * (real) 0.5 * xndot); + *xn = xni + ft * (xndot + ft * (real) 0.5 * xnddt); - temp0 = -(*xnodes) + thgr + tsince * THDT; + temp0 = -(*xnodes) + thgr + tsince * THDT; - if (isynfl == 0) - *xll = xl + temp0 + temp0; - else - *xll = xl - *omgasm + temp0; + if (isynfl == 0) + *xll = xl + temp0 + temp0; + else + *xll = xl - *omgasm + temp0; -return 0; -} /* SGDP4_dpsec */ + return 0; +} /* SGDP4_dpsec */ /* ===================================================================== @@ -649,54 +715,54 @@ return 0; ===================================================================== */ -static void dot_terms_calculated(void) +static void +dot_terms_calculated (void) { -LOCAL_DOUBLE x2li, x2omi, xomi; + LOCAL_DOUBLE x2li, x2omi, xomi; - /* DOT TERMS CALCULATED */ - if (isynfl) - { - xndot = del1 * SIN(xli - fasx2) - + del2 * SIN((xli - fasx4) * (real)2.0) - + del3 * SIN((xli - fasx6) * (real)3.0); + /* DOT TERMS CALCULATED */ + if (isynfl) + { + xndot = del1 * SIN (xli - fasx2) + + del2 * SIN ((xli - fasx4) * (real) 2.0) + + del3 * SIN ((xli - fasx6) * (real) 3.0); - xnddt = del1 * COS(xli - fasx2) - + del2 * COS((xli - fasx4) * (real)2.0) * (real)2.0 - + del3 * COS((xli - fasx6) * (real)3.0) * (real)3.0; - } - else - { - xomi = omegaq + omgdt * atime; - x2omi = xomi + xomi; - x2li = xli + xli; + xnddt = del1 * COS (xli - fasx2) + + del2 * COS ((xli - fasx4) * (real) 2.0) * (real) 2.0 + + del3 * COS ((xli - fasx6) * (real) 3.0) * (real) 3.0; + } + else + { + xomi = omegaq + omgdt * atime; + x2omi = xomi + xomi; + x2li = xli + xli; - xndot = d2201 * SIN(x2omi + xli - G22) - + d2211 * SIN(xli - G22) - + d3210 * SIN(xomi + xli - G32) - + d3222 * SIN(-xomi + xli - G32) - + d5220 * SIN(xomi + xli - G52) - + d5232 * SIN(-xomi + xli - G52) - + d4410 * SIN(x2omi + x2li - G44) - + d4422 * SIN(x2li - G44) - + d5421 * SIN(xomi + x2li - G54) - + d5433 * SIN(-xomi + x2li - G54); + xndot = d2201 * SIN (x2omi + xli - G22) + + d2211 * SIN (xli - G22) + + d3210 * SIN (xomi + xli - G32) + + d3222 * SIN (-xomi + xli - G32) + + d5220 * SIN (xomi + xli - G52) + + d5232 * SIN (-xomi + xli - G52) + + d4410 * SIN (x2omi + x2li - G44) + + d4422 * SIN (x2li - G44) + + d5421 * SIN (xomi + x2li - G54) + d5433 * SIN (-xomi + x2li - G54); - xnddt = d2201 * COS(x2omi + xli - G22) - + d2211 * COS(xli - G22) - + d3210 * COS(xomi + xli - G32) - + d3222 * COS(-xomi + xli - G32) - + d5220 * COS(xomi + xli - G52) - + d5232 * COS(-xomi + xli - G52) - + (d4410 * COS(x2omi + x2li - G44) - + d4422 * COS(x2li - G44) - + d5421 * COS(xomi + x2li - G54) - + d5433 * COS(-xomi + x2li - G54)) * (real)2.0; - } + xnddt = d2201 * COS (x2omi + xli - G22) + + d2211 * COS (xli - G22) + + d3210 * COS (xomi + xli - G32) + + d3222 * COS (-xomi + xli - G32) + + d5220 * COS (xomi + xli - G52) + + d5232 * COS (-xomi + xli - G52) + + (d4410 * COS (x2omi + x2li - G44) + + d4422 * COS (x2li - G44) + + d5421 * COS (xomi + x2li - G54) + + d5433 * COS (-xomi + x2li - G54)) * (real) 2.0; + } - xldot = (real)(xni + xfact); - xnddt *= xldot; + xldot = (real) (xni + xfact); + xnddt *= xldot; -} /* dot_terms_calculated */ +} /* dot_terms_calculated */ /* ===================================================================== @@ -711,62 +777,63 @@ LOCAL_DOUBLE x2li, x2omi, xomi; ===================================================================== */ -int SGDP4_dpper(real *em, real *xinc, real *omgasm, real *xnodes, - double *xll, double tsince) +int +SGDP4_dpper (real * em, real * xinc, real * omgasm, real * xnodes, + double *xll, double tsince) { -real sinis, cosis; + real sinis, cosis; - compute_LunarSolar(tsince); + compute_LunarSolar (tsince); - *xinc += pinc; - *em += pe; + *xinc += pinc; + *em += pe; - /* Spacetrack report #3 has sin/cos from before perturbations - * added to xinc (oldxinc), but apparently report # 6 has then - * from after they are added. - */ - SINCOS(*xinc, &sinis, &cosis); + /* Spacetrack report #3 has sin/cos from before perturbations + * added to xinc (oldxinc), but apparently report # 6 has then + * from after they are added. + */ + SINCOS (*xinc, &sinis, &cosis); - if (ilsd) - { - /* APPLY PERIODICS DIRECTLY */ - real tmp_ph; - tmp_ph = ph / sinis; + if (ilsd) + { + /* APPLY PERIODICS DIRECTLY */ + real tmp_ph; + tmp_ph = ph / sinis; - *omgasm += pgh - cosis * tmp_ph; - *xnodes += tmp_ph; - *xll += pl; - } - else - { - /* APPLY PERIODICS WITH LYDDANE MODIFICATION */ - LOCAL_REAL alfdp, betdp, dalf, dbet, xls, dls; - LOCAL_REAL sinok, cosok; - int ishift; - real oldxnode = (*xnodes); + *omgasm += pgh - cosis * tmp_ph; + *xnodes += tmp_ph; + *xll += pl; + } + else + { + /* APPLY PERIODICS WITH LYDDANE MODIFICATION */ + LOCAL_REAL alfdp, betdp, dalf, dbet, xls, dls; + LOCAL_REAL sinok, cosok; + int ishift; + real oldxnode = (*xnodes); - SINCOS(*xnodes, &sinok, &cosok); - alfdp = sinis * sinok; - betdp = sinis * cosok; - dalf = ph * cosok + pinc * cosis * sinok; - dbet = -ph * sinok + pinc * cosis * cosok; - alfdp += dalf; - betdp += dbet; - xls = (real)*xll + *omgasm + cosis * *xnodes; - dls = pl + pgh - pinc * *xnodes * sinis; - xls += dls; - *xnodes = ATAN2(alfdp, betdp); + SINCOS (*xnodes, &sinok, &cosok); + alfdp = sinis * sinok; + betdp = sinis * cosok; + dalf = ph * cosok + pinc * cosis * sinok; + dbet = -ph * sinok + pinc * cosis * cosok; + alfdp += dalf; + betdp += dbet; + xls = (real) * xll + *omgasm + cosis * *xnodes; + dls = pl + pgh - pinc * *xnodes * sinis; + xls += dls; + *xnodes = ATAN2 (alfdp, betdp); - /* Get perturbed xnodes in to same quadrant as original. */ - ishift = NINT((oldxnode - (*xnodes))/TWOPI); - *xnodes += (real)(TWOPI * ishift); + /* Get perturbed xnodes in to same quadrant as original. */ + ishift = NINT ((oldxnode - (*xnodes)) / TWOPI); + *xnodes += (real) (TWOPI * ishift); - *xll += (double)pl; - *omgasm = xls - (real)*xll - cosis * (*xnodes); - } + *xll += (double) pl; + *omgasm = xls - (real) * xll - cosis * (*xnodes); + } -return 0; -} /* SGDP4_dpper */ + return 0; +} /* SGDP4_dpper */ /* ===================================================================== Do the Lunar-Solar terms for the SGDP4_dpper() function (normally only @@ -778,55 +845,56 @@ return 0; code). ===================================================================== */ -static void compute_LunarSolar(double tsince) +static void +compute_LunarSolar (double tsince) { -LOCAL_REAL sinzf, coszf; -LOCAL_REAL f2, f3, zf, zm; -LOCAL_REAL sel, sil, ses, sll, sis, sls; -LOCAL_REAL sghs, shs, sghl, shl; + LOCAL_REAL sinzf, coszf; + LOCAL_REAL f2, f3, zf, zm; + LOCAL_REAL sel, sil, ses, sll, sis, sls; + LOCAL_REAL sghs, shs, sghl, shl; - /* Update Solar terms. */ - zm = zmos + ZNS * tsince; - zf = zm + ZES * (real)2.0 * SIN(zm); - SINCOS(zf, &sinzf, &coszf); - f2 = sinzf * (real)0.5 * sinzf - (real)0.25; - f3 = sinzf * (real)-0.5 * coszf; - ses = se2 * f2 + se3 * f3; - sis = si2 * f2 + si3 * f3; - sls = sl2 * f2 + sl3 * f3 + sl4 * sinzf; + /* Update Solar terms. */ + zm = zmos + ZNS * tsince; + zf = zm + ZES * (real) 2.0 *SIN (zm); + SINCOS (zf, &sinzf, &coszf); + f2 = sinzf * (real) 0.5 *sinzf - (real) 0.25; + f3 = sinzf * (real) - 0.5 * coszf; + ses = se2 * f2 + se3 * f3; + sis = si2 * f2 + si3 * f3; + sls = sl2 * f2 + sl3 * f3 + sl4 * sinzf; - sghs = sgh2 * f2 + sgh3 * f3 + sgh4 * sinzf; - shs = sh2 * f2 + sh3 * f3; + sghs = sgh2 * f2 + sgh3 * f3 + sgh4 * sinzf; + shs = sh2 * f2 + sh3 * f3; - /* Update Lunar terms. */ - zm = zmol + ZNL * tsince; - zf = zm + ZEL * (real)2.0 * SIN(zm); - SINCOS(zf, &sinzf, &coszf); - f2 = sinzf * (real)0.5 * sinzf - (real)0.25; - f3 = sinzf * (real)-0.5 * coszf; - sel = ee2 * f2 + e3 * f3; - sil = xi2 * f2 + xi3 * f3; - sll = xl2 * f2 + xl3 * f3 + xl4 * sinzf; + /* Update Lunar terms. */ + zm = zmol + ZNL * tsince; + zf = zm + ZEL * (real) 2.0 *SIN (zm); + SINCOS (zf, &sinzf, &coszf); + f2 = sinzf * (real) 0.5 *sinzf - (real) 0.25; + f3 = sinzf * (real) - 0.5 * coszf; + sel = ee2 * f2 + e3 * f3; + sil = xi2 * f2 + xi3 * f3; + sll = xl2 * f2 + xl3 * f3 + xl4 * sinzf; - sghl = xgh2 * f2 + xgh3 * f3 + xgh4 * sinzf; - shl = xh2 * f2 + xh3 * f3; + sghl = xgh2 * f2 + xgh3 * f3 + xgh4 * sinzf; + shl = xh2 * f2 + xh3 * f3; - /* Save computed values to calling structure. */ - pgh = sghs + sghl; - ph = shs + shl; - pe = ses + sel; - pinc = sis + sil; - pl = sls + sll; + /* Save computed values to calling structure. */ + pgh = sghs + sghl; + ph = shs + shl; + pe = ses + sel; + pinc = sis + sil; + pl = sls + sll; - if (ilsz) - { - /* Correct for previously saved epoch terms. */ - pgh -= pgh0; - ph -= ph0; - pe -= pe0; - pinc -= pinc0; - pl -= pl0; - } + if (ilsz) + { + /* Correct for previously saved epoch terms. */ + pgh -= pgh0; + ph -= ph0; + pe -= pe0; + pinc -= pinc0; + pl -= pl0; + } } @@ -856,74 +924,80 @@ LOCAL_REAL sghs, shs, sghl, shl; #define FK5R (5.07551419432269442E-15) -static void thetag(double ep, real *thegr, double *days50) +static void +thetag (double ep, real * thegr, double *days50) { -double d; -long n, jy; -double theta; + double d; + long n, jy; + double theta; - jy = (long)((ep + 2.0e-7) * 0.001); /* Extract the year. */ - d = ep - jy * 1.0e3; /* And then the day of year. */ + jy = (long) ((ep + 2.0e-7) * 0.001); /* Extract the year. */ + d = ep - jy * 1.0e3; /* And then the day of year. */ - /* Assume " 8" is 1980, or more sensibly 2008 ? */ - /* - if (jy < 10) jy += 80; - */ - if (jy < 50) jy += 100; + /* Assume " 8" is 1980, or more sensibly 2008 ? */ + /* + if (jy < 10) jy += 80; + */ + if (jy < 50) + jy += 100; - if (jy < 70) /* Fix for leap years ? */ - n = (jy - 72) / 4; - else - n = (jy - 69) / 4; + if (jy < 70) /* Fix for leap years ? */ + n = (jy - 72) / 4; + else + n = (jy - 69) / 4; - *days50 = (jy - 70) * 365.0 + 7305.0 + n + d; + *days50 = (jy - 70) * 365.0 + 7305.0 + n + d; #if THETAG == 0 - /* Original report #3 code. */ - theta = *days50 * 6.3003880987 + 1.72944494; + /* Original report #3 code. */ + theta = *days50 * 6.3003880987 + 1.72944494; #elif THETAG == 1 - /* Method from project pluto code. */ - /* Reference: The 1992 Astronomical Almanac, page B6. */ - { - const double omega_E = 1.00273790934; /* Earth rotations per sidereal day (non-constant) */ - const double jd = d + J1900 + jy * 365. + ((jy - 1) / 4); - const double UT = fmod(jd + 0.5, 1.0); - double t_cen, GMST; + /* Method from project pluto code. */ + /* Reference: The 1992 Astronomical Almanac, page B6. */ + { + const double omega_E = 1.00273790934; /* Earth rotations per sidereal day (non-constant) */ + const double jd = d + J1900 + jy * 365. + ((jy - 1) / 4); + const double UT = fmod (jd + 0.5, 1.0); + double t_cen, GMST; - t_cen = (jd - UT - 2451545.0) / 36525.0; - GMST = 24110.54841 + t_cen * (8640184.812866 + t_cen * (0.093104 - t_cen * 6.2E-6)); + t_cen = (jd - UT - 2451545.0) / 36525.0; + GMST = + 24110.54841 + t_cen * (8640184.812866 + + t_cen * (0.093104 - t_cen * 6.2E-6)); - GMST = fmod( GMST + SECDAY * omega_E * UT, SECDAY); + GMST = fmod (GMST + SECDAY * omega_E * UT, SECDAY); - if(GMST < 0.0) GMST += SECDAY; + if (GMST < 0.0) + GMST += SECDAY; - theta = TWOPI * GMST / SECDAY; - } + theta = TWOPI * GMST / SECDAY; + } #elif THETAG == 2 - { - /* Method from SGP4SUB.F code. */ - double ts70, ds70, trfac; - long ids70; + { + /* Method from SGP4SUB.F code. */ + double ts70, ds70, trfac; + long ids70; ts70 = (*days50) - 7305.0; - ids70 = (long)(ts70 + 1.0e-8); + ids70 = (long) (ts70 + 1.0e-8); ds70 = ids70; trfac = ts70 - ds70; - /* CALCULATE GREENWICH LOCATION AT EPOCH */ - theta = THGR70 + C1*ds70 + C1P2P*trfac + ts70*ts70*FK5R; - } + /* CALCULATE GREENWICH LOCATION AT EPOCH */ + theta = THGR70 + C1 * ds70 + C1P2P * trfac + ts70 * ts70 * FK5R; + } #else #error 'Unknown method for theta-G calculation' #endif - theta = fmod(theta, TWOPI); - if (theta < 0.0) theta += TWOPI; + theta = fmod (theta, TWOPI); + if (theta < 0.0) + theta += TWOPI; - *thegr = (real)theta; + *thegr = (real) theta; -} /* thetag */ +} /* thetag */ #endif /* !NO_DEEP_SPACE */ diff --git a/src/deproject.c b/src/deproject.c index 7d2b90a..32efd48 100644 --- a/src/deproject.c +++ b/src/deproject.c @@ -8,143 +8,154 @@ #include #include -struct image { - int naxis1,naxis2,naxis3; +struct image +{ + int naxis1, naxis2, naxis3; float *z; - float zmin,zmax; - double ra0,de0; - float avg,std; - float x0,y0; - float a[3],b[3],xrms,yrms; + float zmin, zmax; + double ra0, de0; + float avg, std; + float x0, y0; + float a[3], b[3], xrms, yrms; float exptime; double mjd; char nfd[32]; int cospar; }; -struct jpeg_image { - int nx,ny,nz; +struct jpeg_image +{ + int nx, ny, nz; float *z; }; -struct jpeg_image read_jpg(char *filename); -void write_jpg(char *filename,struct jpeg_image img); -struct image read_fits(char *filename,int pnum); -void forward(double ra0,double de0,double ra,double de,double *x,double *y); -void reverse(double ra0,double de0,double x,double y,double *ra,double *de); +struct jpeg_image read_jpg (char *filename); +void write_jpg (char *filename, struct jpeg_image img); +struct image read_fits (char *filename, int pnum); +void forward (double ra0, double de0, double ra, double de, double *x, + double *y); +void reverse (double ra0, double de0, double x, double y, double *ra, + double *de); -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int i,j,k,l,m; + int i, j, k, l, m; struct image img; - struct jpeg_image jpg,out; - double rx,ry,ra,de,rx0,ry0; - double x,y,d; - double drx=-10.0,dry=10.0; - double ra0=237.0,de0=12.5; - int arg=0; - char *fitsfile,*jpgfile,*outfile; + struct jpeg_image jpg, out; + double rx, ry, ra, de, rx0, ry0; + double x, y, d; + double drx = -10.0, dry = 10.0; + double ra0 = 237.0, de0 = 12.5; + int arg = 0; + char *fitsfile, *jpgfile, *outfile; - // Decode options - while ((arg=getopt(argc,argv,"j:f:o:R:D:s:"))!=-1) { - switch(arg) { + // Decode options + while ((arg = getopt (argc, argv, "j:f:o:R:D:s:")) != -1) + { + switch (arg) + { - case 'j': - jpgfile=optarg; - break; + case 'j': + jpgfile = optarg; + break; - case 'f': - fitsfile=optarg; - break; + case 'f': + fitsfile = optarg; + break; - case 'o': - outfile=optarg; - break; + case 'o': + outfile = optarg; + break; - case 'R': - ra0=atof(optarg); - break; + case 'R': + ra0 = atof (optarg); + break; - case 'D': - de0=atof(optarg); - break; + case 'D': + de0 = atof (optarg); + break; - case 's': - dry=atof(optarg); - drx=-dry; - break; + case 's': + dry = atof (optarg); + drx = -dry; + break; - default: - return 0; + default: + return 0; + } } - } // Read image - img=read_fits(fitsfile,0); - jpg=read_jpg(jpgfile); + img = read_fits (fitsfile, 0); + jpg = read_jpg (jpgfile); - out.nx=3000; - out.ny=6000; - out.nz=3; + out.nx = 3000; + out.ny = 6000; + out.nz = 3; /* - img.x0*=4.0; - img.y0*=4.0; - img.a[1]/=4.0; - img.a[2]/=4.0; - img.b[1]/=4.0; - img.b[2]/=4.0; - */ - out.z=(float *) malloc(sizeof(float)*out.nx*out.ny*out.nz); + img.x0*=4.0; + img.y0*=4.0; + img.a[1]/=4.0; + img.a[2]/=4.0; + img.b[1]/=4.0; + img.b[2]/=4.0; + */ + out.z = (float *) malloc (sizeof (float) * out.nx * out.ny * out.nz); - for (i=0;i0.0 && x0.0 && y 0.0 && x < jpg.nx && y > 0.0 && y < jpg.ny) + out.z[l] = jpg.z[m]; + else + out.z[l] = 0.0; + + } + } } - } // Dump - write_jpg(outfile,out); + write_jpg (outfile, out); // Free - free(img.z); - free(jpg.z); - free(out.z); + free (img.z); + free (jpg.z); + free (out.z); return 0; } // Read fits image -struct image read_fits(char *filename,int pnum) +struct image +read_fits (char *filename, int pnum) { - int i,j,k,l,m; + int i, j, k, l, m; qfitsloader ql; - char key[FITS_LINESZ+1] ; + char key[FITS_LINESZ + 1]; struct image img; - float s1,s2,avg,std; + float s1, s2, avg, std; // Set plane ql.xtnum = 0; @@ -154,172 +165,191 @@ struct image read_fits(char *filename,int pnum) ql.ptype = PTYPE_FLOAT; // Set filename - ql.filename=filename; + ql.filename = filename; // Image size - img.naxis1=atoi(qfits_query_hdr(filename,"NAXIS1")); - img.naxis2=atoi(qfits_query_hdr(filename,"NAXIS2")); + img.naxis1 = atoi (qfits_query_hdr (filename, "NAXIS1")); + img.naxis2 = atoi (qfits_query_hdr (filename, "NAXIS2")); // MJD - img.mjd=atof(qfits_query_hdr(filename,"MJD-OBS")); - strcpy(img.nfd,qfits_query_hdr(filename,"DATE-OBS")); - img.exptime=atof(qfits_query_hdr(filename,"EXPTIME")); + img.mjd = atof (qfits_query_hdr (filename, "MJD-OBS")); + strcpy (img.nfd, qfits_query_hdr (filename, "DATE-OBS")); + img.exptime = atof (qfits_query_hdr (filename, "EXPTIME")); // COSPAR ID - img.cospar=atoi(qfits_query_hdr(filename,"COSPAR")); + img.cospar = atoi (qfits_query_hdr (filename, "COSPAR")); // Transformation - img.mjd=atof(qfits_query_hdr(filename,"MJD-OBS")); - img.ra0=atof(qfits_query_hdr(filename,"CRVAL1")); - img.de0=atof(qfits_query_hdr(filename,"CRVAL2")); - img.x0=atof(qfits_query_hdr(filename,"CRPIX1")); - img.y0=atof(qfits_query_hdr(filename,"CRPIX2")); - img.a[0]=0.0; - img.a[1]=3600.0*atof(qfits_query_hdr(filename,"CD1_1")); - img.a[2]=3600.0*atof(qfits_query_hdr(filename,"CD1_2")); - img.b[0]=0.0; - img.b[1]=3600.0*atof(qfits_query_hdr(filename,"CD2_1")); - img.b[2]=3600.0*atof(qfits_query_hdr(filename,"CD2_2")); - img.xrms=3600.0*atof(qfits_query_hdr(filename,"CRRES1")); - img.yrms=3600.0*atof(qfits_query_hdr(filename,"CRRES2")); + img.mjd = atof (qfits_query_hdr (filename, "MJD-OBS")); + img.ra0 = atof (qfits_query_hdr (filename, "CRVAL1")); + img.de0 = atof (qfits_query_hdr (filename, "CRVAL2")); + img.x0 = atof (qfits_query_hdr (filename, "CRPIX1")); + img.y0 = atof (qfits_query_hdr (filename, "CRPIX2")); + img.a[0] = 0.0; + img.a[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_1")); + img.a[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_2")); + img.b[0] = 0.0; + img.b[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_1")); + img.b[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_2")); + img.xrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES1")); + img.yrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES2")); // Initialize load - if (qfitsloader_init(&ql) != 0) - printf("Error initializing data loading\n"); + if (qfitsloader_init (&ql) != 0) + printf ("Error initializing data loading\n"); // Test load - if (qfits_loadpix(&ql) != 0) - printf("Error loading actual data\n"); + if (qfits_loadpix (&ql) != 0) + printf ("Error loading actual data\n"); // Allocate image memory - img.z=(float *) malloc(sizeof(float) * img.naxis1*img.naxis2); + img.z = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2); // Fill z array - for (i=0,l=0,m=0;i2) - year=c-4716; + dday = b - d - floor (30.6001 * e) + f; + if (e < 14) + month = e - 1; else - year=c-4715; + month = e - 13; - day=(int) floor(dday); - x=24.0*(dday-day); - x=3600.*fabs(x); - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - hour=x; - fsec=1000.0*(sec-floor(sec)); - sprintf(date,"%04d%02d%02d%02d%02d%02.0f%03.0f",(int) year,(int) month,(int) day,(int) hour,(int) min,floor(sec),fsec); + if (month > 2) + year = c - 4716; + else + year = c - 4715; + + day = (int) floor (dday); + x = 24.0 * (dday - day); + x = 3600. * fabs (x); + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + hour = x; + fsec = 1000.0 * (sec - floor (sec)); + sprintf (date, "%04d%02d%02d%02d%02d%02.0f%03.0f", (int) year, (int) month, + (int) day, (int) hour, (int) min, floor (sec), fsec); return; } // MJD to DOY -double mjd2doy(double mjd,int *yr) +double +mjd2doy (double mjd, int *yr) { - int year,month,k=2; + int year, month, k = 2; int day; double doy; char nfd[32]; - - mjd2date(mjd,nfd); - sscanf(nfd,"%04d",&year); - sscanf(nfd+4,"%02d",&month); - sscanf(nfd+6,"%02d",&day); + mjd2date (mjd, nfd); - if (year%4==0 && year%400!=0) - k=1; + sscanf (nfd, "%04d", &year); + sscanf (nfd + 4, "%02d", &month); + sscanf (nfd + 6, "%02d", &day); - doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - *yr=year; + doy = + floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30; + + *yr = year; return doy; } // Convert Decimal into Sexagesimal -void dec2s(double x,char *s,int type) +void +dec2s (double x, char *s, int type) { int i; - double sec,deg,min,fmin; + double sec, deg, min, fmin; char sign; - sign=(x<0 ? '-' : '+'); - x=60.*fabs(x); + sign = (x < 0 ? '-' : '+'); + x = 60. * fabs (x); - min=fmod(x,60.); - x=(x-min)/60.; + min = fmod (x, 60.); + x = (x - min) / 60.; // deg=fmod(x,60.); - deg=x; - if (type==0) - fmin=1000.0*(min-floor(min)); + deg = x; + if (type == 0) + fmin = 1000.0 * (min - floor (min)); else - fmin=100.0*(min-floor(min)); + fmin = 100.0 * (min - floor (min)); - if (type==0) - sprintf(s,"%02.0f%02.0f%03.0f",deg,floor(min),fmin); + if (type == 0) + sprintf (s, "%02.0f%02.0f%03.0f", deg, floor (min), fmin); else - sprintf(s,"%c%02.0f%02.0f%02.0f",sign,deg,floor(min),fmin); + sprintf (s, "%c%02.0f%02.0f%02.0f", sign, deg, floor (min), fmin); return; } // Reduce point -void reduce_point(struct observation *obs,struct fourframe img,float tmid,float x,float y) +void +reduce_point (struct observation *obs, struct fourframe img, float tmid, + float x, float y) { - int iframe,k; - double ra,de,rx,ry; - float dx,dy,dt; + int iframe, k; + double ra, de, rx, ry; + float dx, dy, dt; double mjd; - char nfd[32],sra[15],sde[15]; + char nfd[32], sra[15], sde[15]; // Transform position - dx=x-img.x0; - dy=y-img.y0; - rx=img.a[0]+img.a[1]*dx+img.a[2]*dy; - ry=img.b[0]+img.b[1]*dx+img.b[2]*dy; - reverse(img.ra0,img.de0,rx,ry,&ra,&de); + dx = x - img.x0; + dy = y - img.y0; + rx = img.a[0] + img.a[1] * dx + img.a[2] * dy; + ry = img.b[0] + img.b[1] * dx + img.b[2] * dy; + reverse (img.ra0, img.de0, rx, ry, &ra, &de); - dec2s(ra/15.0,sra,0); - dec2s(de,sde,1); + dec2s (ra / 15.0, sra, 0); + dec2s (de, sde, 1); // Get time - k=(int) x + img.naxis1*(int) y; - iframe=(int) img.znum[k]; - if (tmid<0.0) - dt=img.dt[iframe]; + k = (int) x + img.naxis1 * (int) y; + iframe = (int) img.znum[k]; + if (tmid < 0.0) + dt = img.dt[iframe]; else - dt=tmid; - mjd=nfd2mjd(img.nfd)+(double) dt/86400.0; - mjd2date(mjd,nfd); - + dt = tmid; + mjd = nfd2mjd (img.nfd) + (double) dt / 86400.0; + mjd2date (mjd, nfd); + // Copy - strcpy(obs->nfd,nfd); - sprintf(obs->pos,"%s%s",sra,sde); + strcpy (obs->nfd, nfd); + sprintf (obs->pos, "%s%s", sra, sde); return; } -void fit(struct observation *obs,struct fourframe ff,struct point *p,int np,int flag) +void +fit (struct observation *obs, struct fourframe ff, struct point *p, int np, + int flag) { - int i,j,k,l,n,m; - float *t,*dt,*x,*y,*w; - float tmin,tmax,tmid; - float chi2x,chi2y,ax[2],sax[2],ay[2],say[2]; - float dx,dy,dr,rmsx,rmsy; + int i, j, k, l, n, m; + float *t, *dt, *x, *y, *w; + float tmin, tmax, tmid; + float chi2x, chi2y, ax[2], sax[2], ay[2], say[2]; + float dx, dy, dr, rmsx, rmsy; // Count number of points - for (i=0,n=0;itmax) tmax=t[i]; - } - } - tmid=0.5*(tmin+tmax); - - // Shift in time - for (i=0;ix[0]=ax[0]; - obs->y[0]=ay[0]; - obs->t[0]=tmid; - obs->x[1]=ax[0]+ax[1]*(tmin-tmid); - obs->y[1]=ay[0]+ay[1]*(tmin-tmid); - obs->t[1]=tmin; - obs->x[2]=ax[0]+ax[1]*(tmax-tmid); - obs->y[2]=ay[0]+ay[1]*(tmax-tmid); - obs->t[2]=tmax; - obs->state=1; - obs->dxdt=(obs->x[2]-obs->x[1])/(obs->t[2]-obs->t[1]); - obs->dydt=(obs->y[2]-obs->y[1])/(obs->t[2]-obs->t[1]); - obs->drdt=sqrt(obs->dxdt*obs->dxdt+obs->dydt*obs->dydt); + // Allocate + t = (float *) malloc (sizeof (float) * n); + dt = (float *) malloc (sizeof (float) * n); + x = (float *) malloc (sizeof (float) * n); + y = (float *) malloc (sizeof (float) * n); + w = (float *) malloc (sizeof (float) * n); + + // Fill + for (i = 0, l = 0; i < np; i++) + { + if (p[i].flag == flag) + { + x[l] = p[i].x; + y[l] = p[i].y; + w[l] = 1.0; + t[l] = p[i].t; + l++; + } + } + + // Find limits in time + for (i = 0; i < n; i++) + { + if (i == 0) + { + tmin = t[i]; + tmax = t[i]; + } + else + { + if (t[i] < tmin) + tmin = t[i]; + if (t[i] > tmax) + tmax = t[i]; + } + } + tmid = 0.5 * (tmin + tmax); + + // Shift in time + for (i = 0; i < n; i++) + dt[i] = t[i] - tmid; + + // Fit x-pixel position + chi2x = linear_fit (dt, x, w, n, ax, sax); + + // Fit x-pixel position + chi2y = linear_fit (dt, y, w, n, ay, say); + + // Compute rms + for (i = 0, rmsx = 0.0, rmsy = 0.0; i < n; i++) + { + rmsx += pow (x[i] - (ax[0] + ax[1] * dt[i]), 2); + rmsy += pow (y[i] - (ay[0] + ay[1] * dt[i]), 2); + } + rmsx = sqrt (rmsx / (float) (n - 1)); + rmsy = sqrt (rmsy / (float) (n - 1)); + + obs->x[0] = ax[0]; + obs->y[0] = ay[0]; + obs->t[0] = tmid; + obs->x[1] = ax[0] + ax[1] * (tmin - tmid); + obs->y[1] = ay[0] + ay[1] * (tmin - tmid); + obs->t[1] = tmin; + obs->x[2] = ax[0] + ax[1] * (tmax - tmid); + obs->y[2] = ay[0] + ay[1] * (tmax - tmid); + obs->t[2] = tmax; + obs->state = 1; + obs->dxdt = (obs->x[2] - obs->x[1]) / (obs->t[2] - obs->t[1]); + obs->dydt = (obs->y[2] - obs->y[1]) / (obs->t[2] - obs->t[1]); + obs->drdt = sqrt (obs->dxdt * obs->dxdt + obs->dydt * obs->dydt); // Reduce point - reduce_point(obs,ff,tmid,ax[0],ay[0]); + reduce_point (obs, ff, tmid, ax[0], ay[0]); // Free - free(t); - free(dt); - free(x); - free(y); + free (t); + free (dt); + free (x); + free (y); return; } -void format_iod_line(struct observation *obs) +void +format_iod_line (struct observation *obs) { - int mt,xt,mp,xp; + int mt, xt, mp, xp; char string[10]; - + // Time format - sprintf(string,"%7.1e",obs->terr); - mt=string[0]-'0'; - xt=atoi(string+4)+8; + sprintf (string, "%7.1e", obs->terr); + mt = string[0] - '0'; + xt = atoi (string + 4) + 8; // Position format - if (obs->type==2) { - sprintf(string,"%7.1e",obs->perr); - mp=string[0]-'0'; - xp=atoi(string+4)+8; - } else { - printf("Position format not implemented!\n"); - } + if (obs->type == 2) + { + sprintf (string, "%7.1e", obs->perr); + mp = string[0] - '0'; + xp = atoi (string + 4) + 8; + } + else + { + printf ("Position format not implemented!\n"); + } - sprintf(obs->iod_line,"%05d %c%c %-6s %04d %c %-17s %d%d %d%d %-14s %d%d %c", - obs->satno, - obs->desig[0],obs->desig[1], - obs->desig+2, - obs->cospar, - obs->conditions, - obs->nfd, - mt,xt, - obs->type,obs->epoch, - obs->pos, - mp,xp, - obs->behavior); + sprintf (obs->iod_line, + "%05d %c%c %-6s %04d %c %-17s %d%d %d%d %-14s %d%d %c", obs->satno, + obs->desig[0], obs->desig[1], obs->desig + 2, obs->cospar, + obs->conditions, obs->nfd, mt, xt, obs->type, obs->epoch, obs->pos, + mp, xp, obs->behavior); return; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; + int c, i = 0; - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\t') - c=' '; + c = ' '; if (c == '\n') s[i++] = c; s[i] = '\0'; return i; } -void find_designation(int satno0,char *desig0) +void +find_designation (int satno0, char *desig0) { FILE *file; int satno; char desig[16]; - char *env,filename[128]; + char *env, filename[128]; // Environment variables - env=getenv("ST_DATADIR"); - sprintf(filename,"%s/data/desig.txt",env); + env = getenv ("ST_DATADIR"); + sprintf (filename, "%s/data/desig.txt", env); - file=fopen(filename,"r"); - if (file==NULL) { - fprintf(stderr,"Designation file not found!\n"); - exit(0); - } - while (!feof(file)) { - fscanf(file,"%d %s",&satno,desig); - if (satno==satno0) { - strcpy(desig0,desig); - break; + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "Designation file not found!\n"); + exit (0); } - } - fclose(file); + while (!feof (file)) + { + fscanf (file, "%d %s", &satno, desig); + if (satno == satno0) + { + strcpy (desig0, desig); + break; + } + } + fclose (file); return; } -void identify_observation(struct observation *obs,char *fileroot,float drmin,float amin) +void +identify_observation (struct observation *obs, char *fileroot, float drmin, + float amin) { FILE *file; - float x0,y0,x1,y1,x,y,texp; + float x0, y0, x1, y1, x, y, texp; double mjd; - int satno,flag=0,i; - char nfd[32],filename[LIM],line[LIM],catalog[LIM]; - float dx,dy,dr,dxdt,dydt,drdt,angle,dp; + int satno, flag = 0, i; + char nfd[32], filename[LIM], line[LIM], catalog[LIM]; + float dx, dy, dr, dxdt, dydt, drdt, angle, dp; // Open ID file - sprintf(filename,"%s.id",fileroot); - file=fopen(filename,"r"); - if (file==NULL) { - fprintf(stderr,"ID file %s not found\n",filename); - return; - } - while (fgetline(file,line,LIM)>0) { - sscanf(line,"%s %f %f %f %f %f %d %s",nfd,&x0,&y0,&x1,&y1,&texp,&satno,catalog); - - // Predicted pixel rates - dxdt=(x1-x0)/texp; - dydt=(y1-y0)/texp; - drdt=sqrt(dxdt*dxdt+dydt*dydt); - x=x0+dxdt*obs->t[0]; - y=y0+dydt*obs->t[0]; - - // Compare - dx=x-obs->x[0]; - dy=y-obs->y[0]; - dr=sqrt(dx*dx+dy*dy); - dp=(dxdt*obs->dxdt+dydt*obs->dydt)/(obs->drdt*drdt); - if (dp<=1.0) - angle=acos(dp)*R2D; - else - angle=0.0; - - // Identify - if (drsatno=satno; - if (strstr(catalog,"classfd.tle")!=NULL) - strcpy(obs->catalog,"classfd"); - if (strstr(catalog,"inttles.tle")!=NULL) - strcpy(obs->catalog,"classfd"); - else if (strstr(catalog,"catalog.tle")!=NULL) - strcpy(obs->catalog,"catalog"); + sprintf (filename, "%s.id", fileroot); + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "ID file %s not found\n", filename); + return; } - } - fclose(file); + while (fgetline (file, line, LIM) > 0) + { + sscanf (line, "%s %f %f %f %f %f %d %s", nfd, &x0, &y0, &x1, &y1, &texp, + &satno, catalog); + + // Predicted pixel rates + dxdt = (x1 - x0) / texp; + dydt = (y1 - y0) / texp; + drdt = sqrt (dxdt * dxdt + dydt * dydt); + x = x0 + dxdt * obs->t[0]; + y = y0 + dydt * obs->t[0]; + + // Compare + dx = x - obs->x[0]; + dy = y - obs->y[0]; + dr = sqrt (dx * dx + dy * dy); + dp = (dxdt * obs->dxdt + dydt * obs->dydt) / (obs->drdt * drdt); + if (dp <= 1.0) + angle = acos (dp) * R2D; + else + angle = 0.0; + + // Identify + if (dr < drmin && angle < amin) + { + obs->satno = satno; + if (strstr (catalog, "classfd.tle") != NULL) + strcpy (obs->catalog, "classfd"); + if (strstr (catalog, "inttles.tle") != NULL) + strcpy (obs->catalog, "classfd"); + else if (strstr (catalog, "catalog.tle") != NULL) + strcpy (obs->catalog, "catalog"); + } + } + fclose (file); return; } -void write_observation(struct observation obs) +void +write_observation (struct observation obs) { FILE *file; char filename[LIM]; - sprintf(filename,"%s.dat",obs.catalog); + sprintf (filename, "%s.dat", obs.catalog); - file=fopen(filename,"a"); - fprintf(file,"%s\n%s\n",obs.comment,obs.iod_line); - fclose(file); + file = fopen (filename, "a"); + fprintf (file, "%s\n%s\n", obs.comment, obs.iod_line); + fclose (file); return; } -void overlay_predictions(char *fitsfile,struct fourframe ff) +void +overlay_predictions (char *fitsfile, struct fourframe ff) { - float x0,y0,x1,y1,texp; - int satno,isch; - char filename[LIM],line[LIM],nfd[32],catalog[LIM],text[8]; + float x0, y0, x1, y1, texp; + int satno, isch; + char filename[LIM], line[LIM], nfd[32], catalog[LIM], text[8]; FILE *file; - float t,x,y; + float t, x, y; - cpgqci(&isch); + cpgqci (&isch); - sprintf(filename,"%s.id",fitsfile); + sprintf (filename, "%s.id", fitsfile); // Open ID file - file=fopen(filename,"r"); - if (file==NULL) { - fprintf(stderr,"ID file %s not found\n",filename); - return; - } - while (fgetline(file,line,LIM)>0) { - sscanf(line,"%s %f %f %f %f %f %d %s",nfd,&x0,&y0,&x1,&y1,&texp,&satno,catalog); - - if (strstr(catalog,"classfd")!=NULL) - cpgsci(4); - else if (strstr(catalog,"catalog")!=NULL) - cpgsci(0); - else if (strstr(catalog,"inttles")!=NULL) - cpgsci(3); - else if (strstr(catalog,"jsc")!=NULL) - cpgsci(5); - - cpgpt1(x0,y0,17); - cpgmove(x0,y0); - cpgdraw(x1,y1); - - // plot text - cpgsch(0.65); - sprintf(text," %05d",satno); - for (t=0.0;t<1.0;t+=0.1) { - x=x0+(x1-x0)*t; - y=y0+(y1-y0)*t; - if (x>0.0 && y>0.0 && x 0) + { + sscanf (line, "%s %f %f %f %f %f %d %s", nfd, &x0, &y0, &x1, &y1, &texp, + &satno, catalog); + + if (strstr (catalog, "classfd") != NULL) + cpgsci (4); + else if (strstr (catalog, "catalog") != NULL) + cpgsci (0); + else if (strstr (catalog, "inttles") != NULL) + cpgsci (3); + else if (strstr (catalog, "jsc") != NULL) + cpgsci (5); + + cpgpt1 (x0, y0, 17); + cpgmove (x0, y0); + cpgdraw (x1, y1); + + // plot text + cpgsch (0.65); + sprintf (text, " %05d", satno); + for (t = 0.0; t < 1.0; t += 0.1) + { + x = x0 + (x1 - x0) * t; + y = y0 + (y1 - y0) * t; + if (x > 0.0 && y > 0.0 && x < ff.naxis1 && y < ff.naxis2) + { + cpgtext (x, y, text); + break; + } + } + cpgsch (1.0); + cpgsci (isch); + } + fclose (file); return; } -void accumulate(float *z,int nx,int ny,int nz,int *mask,int bx,int by,int bz,int nsel,int *zsel) +void +accumulate (float *z, int nx, int ny, int nz, int *mask, int bx, int by, + int bz, int nsel, int *zsel) { - int ix,iy,iz; - int jx,jy,jz,k; - int mx,my,mz; - int *c,npoints=0; + int ix, iy, iz; + int jx, jy, jz, k; + int mx, my, mz; + int *c, npoints = 0; // New dimensions - mx=nx/bx; - my=ny/by; - mz=nz/bz; + mx = nx / bx; + my = ny / by; + mz = nz / bz; // Allocate and zero - c=(int *) malloc(sizeof(int)*mx*my*mz); - for (ix=0;ixnsel) - zsel[ix+nx*iy]++; + for (ix = 0; ix < nx; ix++) + { + for (iy = 0; iy < ny; iy++) + { + iz = (int) z[ix + nx * iy]; + jx = ix / bx; + jy = iy / by; + jz = iz / bz; + k = jx + mx * (jy + my * jz); + if (c[k] > nsel) + zsel[ix + nx * iy]++; + } } - } - free(c); + free (c); return; } // RANSAC line finding -void ransac(struct point *p,int np,float drmin) +void +ransac (struct point *p, int np, float drmin) { - int i=0,j,k,l,m,n,mmax; + int i = 0, j, k, l, m, n, mmax; const gsl_rng_type *T; - gsl_rng * r; - int i0,i1,i0max,i1max; - float ax,bx,ay,by; - float dx,dy,dr; + gsl_rng *r; + int i0, i1, i0max, i1max; + float ax, bx, ay, by; + float dx, dy, dr; // Set up randomizer - gsl_rng_env_setup(); + gsl_rng_env_setup (); - T=gsl_rng_default; - r=gsl_rng_alloc(T); + T = gsl_rng_default; + r = gsl_rng_alloc (T); // Loop over number of lines - for (i=1;i<=4;i++) { - // Number of iterations - for (l=0,mmax=0;l<10000;l++) { - // Get random end points - for (;;) { - i0=(int) (np*gsl_rng_uniform(r)); - if (p[i0].flag==0) - break; - } - for (;;) { - i1=(int) (np*gsl_rng_uniform(r)); - if (p[i1].flag==0) - break; - } - + for (i = 1; i <= 4; i++) + { + // Number of iterations + for (l = 0, mmax = 0; l < 10000; l++) + { + // Get random end points + for (;;) + { + i0 = (int) (np * gsl_rng_uniform (r)); + if (p[i0].flag == 0) + break; + } + for (;;) + { + i1 = (int) (np * gsl_rng_uniform (r)); + if (p[i1].flag == 0) + break; + } + + // Linear model + ax = (p[i1].x - p[i0].x) / (p[i1].t - p[i0].t); + bx = p[i0].x - ax * p[i0].t; + ay = (p[i1].y - p[i0].y) / (p[i1].t - p[i0].t); + by = p[i0].y - ay * p[i0].t; + + // Find matches + for (k = 0, m = 0; k < np; k++) + { + dx = bx + ax * p[k].t - p[k].x; + dy = by + ay * p[k].t - p[k].y; + dr = sqrt (dx * dx + dy * dy); + if (dr < drmin && p[k].flag == 0) + m++; + } + + // Store + if (m > mmax) + { + mmax = m; + i0max = i0; + i1max = i1; + } + } + // Linear model - ax=(p[i1].x-p[i0].x)/(p[i1].t-p[i0].t); - bx=p[i0].x-ax*p[i0].t; - ay=(p[i1].y-p[i0].y)/(p[i1].t-p[i0].t); - by=p[i0].y-ay*p[i0].t; - + ax = (p[i1max].x - p[i0max].x) / (p[i1max].t - p[i0max].t); + bx = p[i0max].x - ax * p[i0max].t; + ay = (p[i1max].y - p[i0max].y) / (p[i1max].t - p[i0max].t); + by = p[i0max].y - ay * p[i0max].t; + // Find matches - for (k=0,m=0;kmmax) { - mmax=m; - i0max=i0; - i1max=i1; - } - } - - // Linear model - ax=(p[i1max].x-p[i0max].x)/(p[i1max].t-p[i0max].t); - bx=p[i0max].x-ax*p[i0max].t; - ay=(p[i1max].y-p[i0max].y)/(p[i1max].t-p[i0max].t); - by=p[i0max].y-ay*p[i0max].t; - - // Find matches - for (k=0;k1) { - while ((arg=getopt(argc,argv,"f:s:R:r:a:pn:"))!=-1) { - switch(arg) { - - case 'f': - fitsfile=optarg; - break; - - case 'p': - plot=1; - break; + if (argc > 1) + { + while ((arg = getopt (argc, argv, "f:s:R:r:a:pn:")) != -1) + { + switch (arg) + { - case 's': - sigma=atof(optarg); - break; + case 'f': + fitsfile = optarg; + break; - case 'R': - drmin=atof(optarg); - break; + case 'p': + plot = 1; + break; - case 'r': - rmin=atof(optarg); - break; + case 's': + sigma = atof (optarg); + break; - case 'n': - mmin=atoi(optarg); - break; - - default: - return 0; - break; - } + case 'R': + drmin = atof (optarg); + break; + + case 'r': + rmin = atof (optarg); + break; + + case 'n': + mmin = atoi (optarg); + break; + + default: + return 0; + break; + } + } + } + else + { + return 0; } - } else { - return 0; - } - printf("# Processing %s\n",fitsfile); - + printf ("# Processing %s\n", fitsfile); + // Read - ff=read_fits(fitsfile); - + ff = read_fits (fitsfile); + // Fill mask - if (ff.naxis1==720 && ff.naxis2==576) { - for (i=0;iff.naxis1-12 || j>ff.naxis2-1 || j<1) - ff.mask[k]=0; - } + if (ff.naxis1 == 720 && ff.naxis2 == 576) + { + for (i = 0; i < ff.naxis1; i++) + { + for (j = 0; j < ff.naxis2; j++) + { + k = i + ff.naxis1 * j; + if (i < 10 || i > ff.naxis1 - 12 || j > ff.naxis2 - 1 || j < 1) + ff.mask[k] = 0; + } + } } - } - + // Allocate accumulation array - zsel=(int *) malloc(sizeof(int)*ff.naxis1*ff.naxis2); - for (i=0;i0) + for (i = 0, np = 0; i < ff.naxis1 * ff.naxis2; i++) + if (zsel[i] > 0) np++; // Skip if no points - if (np==0) + if (np == 0) return 0; // Skip if too many points - if (np>0.1*ff.naxis1*ff.naxis2) + if (np > 0.1 * ff.naxis1 * ff.naxis2) return 0; - + // Allocate points - p=(struct point *) malloc(sizeof(struct point)*np); + p = (struct point *) malloc (sizeof (struct point) * np); // Fill - for (i=0,l=0;i0) { - p[l].x=(float) i; - p[l].y=(float) j; - p[l].t=ff.dt[(int) ff.znum[k]]; - p[l].flag=0; - l++; - } + for (i = 0, l = 0; i < ff.naxis1; i++) + { + for (j = 0; j < ff.naxis2; j++) + { + k = i + ff.naxis1 * j; + if (zsel[k] > 0) + { + p[l].x = (float) i; + p[l].y = (float) j; + p[l].t = ff.dt[(int) ff.znum[k]]; + p[l].flag = 0; + l++; + } + } } - } // Random Sample Consensus line finding - ransac(p,np,drmin); + ransac (p, np, drmin); // Fit lines - for (l=1;l<=4;l++) { - // Default observation - env=getenv("ST_COSPAR"); - obs.satno=99999; - strcpy(obs.catalog,"unidentified"); - strcpy(obs.desig,"99999U"); - obs.cospar=atoi(env); - obs.conditions='G'; - strcpy(obs.nfd,"YYYYMMDDHHMMSSsss"); - obs.terr=0.1; - strcpy(obs.pos,"HHMMmmm+DDMMmm"); - strcpy(obs.iod_line,""); - obs.perr=0.3; - obs.epoch=5; - obs.type=2; - obs.behavior=' '; - obs.state=0; + for (l = 1; l <= 4; l++) + { + // Default observation + env = getenv ("ST_COSPAR"); + obs.satno = 99999; + strcpy (obs.catalog, "unidentified"); + strcpy (obs.desig, "99999U"); + obs.cospar = atoi (env); + obs.conditions = 'G'; + strcpy (obs.nfd, "YYYYMMDDHHMMSSsss"); + obs.terr = 0.1; + strcpy (obs.pos, "HHMMmmm+DDMMmm"); + strcpy (obs.iod_line, ""); + obs.perr = 0.3; + obs.epoch = 5; + obs.type = 2; + obs.behavior = ' '; + obs.state = 0; - // Count points - for (i=0,m=0;iy[1]) ? (ise=1,0) : (ise=0,1); - for (i=0;i<=n;i++) { - if (y[i]<=y[ilo]) ilo=i; - if (y[i]>y[ihi]) { - ise=ihi; - ihi=i; - } else if (y[i]>y[ise] && i!=ihi) ise=i; - } - - // Compute fractional range from highest to lowest point - rtol=2.0*fabs(y[ihi]-y[ilo])/(fabs(y[ihi])+fabs(y[ilo])+TINY); - - // Return if fractional tolerance is acceptable - if (rtol=NMAX) { - printf("dsmin: NMAX exceeded!\n"); - return -1; - } - nfunk+=2; - - // Reflect simplex - ytry=dsmod(p,y,psum,n,func,ihi,-1.0); - - if (ytry<=y[ilo]) // Goes right direction, extrapolate by factor 2 - ytry=dsmod(p,y,psum,n,func,ihi,2.0); - else if (ytry>=y[ise]) { // 1D contraction - ysave=y[ihi]; - ytry=dsmod(p,y,psum,n,func,ihi,0.5); - if (ytry>=ysave) { - for (i=0;i<=n;i++) { - if (i!=ilo) { - for (j=0;j y[1]) ? (ise = 1, 0) : (ise = 0, 1); + for (i = 0; i <= n; i++) + { + if (y[i] <= y[ilo]) + ilo = i; + if (y[i] > y[ihi]) + { + ise = ihi; + ihi = i; + } + else if (y[i] > y[ise] && i != ihi) + ise = i; } - nfunk+=n; - - psum=vector_sum(p,n); - } - } else --nfunk; - } - free(psum); + + // Compute fractional range from highest to lowest point + rtol = + 2.0 * fabs (y[ihi] - y[ilo]) / (fabs (y[ihi]) + fabs (y[ilo]) + TINY); + + // Return if fractional tolerance is acceptable + if (rtol < ftol) + break; + + if (nfunk >= NMAX) + { + printf ("dsmin: NMAX exceeded!\n"); + return -1; + } + nfunk += 2; + + // Reflect simplex + ytry = dsmod (p, y, psum, n, func, ihi, -1.0); + + if (ytry <= y[ilo]) // Goes right direction, extrapolate by factor 2 + ytry = dsmod (p, y, psum, n, func, ihi, 2.0); + else if (ytry >= y[ise]) + { // 1D contraction + ysave = y[ihi]; + ytry = dsmod (p, y, psum, n, func, ihi, 0.5); + if (ytry >= ysave) + { + for (i = 0; i <= n; i++) + { + if (i != ilo) + { + for (j = 0; j < n; j++) + p[i][j] = psum[j] = 0.5 * (p[i][j] + p[ilo][j]); + y[i] = (*func) (psum); + } + } + nfunk += n; + + psum = vector_sum (p, n); + } + } + else + --nfunk; + } + free (psum); return nfunk; } // Sum vectors -double *vector_sum(double **p,int n) +double * +vector_sum (double **p, int n) { - int i,j; - double sum,*psum; + int i, j; + double sum, *psum; - psum=(double *) malloc(sizeof(double) * n); + psum = (double *) malloc (sizeof (double) * n); - for (i=0;i0) { - status=sscanf(line,"%lf",&mjd); - satpos_xyz(mjd+2400000.5,&satpos,&satvel); - strcpy(orb.desig,"14999A"); // FIX! - compute_position(mjd,satpos,s,orb.satno,orb.desig,precess_flag); - } - fclose(file); + // Initialize + imode = init_sgdp4 (&orb); + if (imode == SGDP4_ERROR) + { + fprintf (stderr, "Error initializing SGDP4\n"); + exit (0); + } + + // Compute + if (usefile == 0) + { + satpos_xyz (mjd + 2400000.5, &satpos, &satvel); + compute_position (mjd, satpos, s, orb.satno, orb.desig, + precess_flag); + } + else + { + + file = fopen (fname, "r"); + while (fgetline (file, line, LIM) > 0) + { + status = sscanf (line, "%lf", &mjd); + satpos_xyz (mjd + 2400000.5, &satpos, &satvel); + strcpy (orb.desig, "14999A"); // FIX! + compute_position (mjd, satpos, s, orb.satno, orb.desig, + precess_flag); + } + fclose (file); + } } - } else { - file=fopen(fname,"r"); - while (fgetline(file,line,LIM)>0) { - if (!isdigit(line[0])) - continue; - if (line[10]=='T') { - status=sscanf(line,"%s %lf %lf %lf",nfd,&satpos.x,&satpos.y,&satpos.z); - mjd=nfd2mjd(nfd); - } else { - status=sscanf(line,"%lf %lf %lf %lf",&mjd,&satpos.x,&satpos.y,&satpos.z); - if (gmat==1) - mjd+=29999.5; - } - compute_position(mjd,satpos,s,satno,desig,precess_flag); + else + { + file = fopen (fname, "r"); + while (fgetline (file, line, LIM) > 0) + { + if (!isdigit (line[0])) + continue; + if (line[10] == 'T') + { + status = + sscanf (line, "%s %lf %lf %lf", nfd, &satpos.x, &satpos.y, + &satpos.z); + mjd = nfd2mjd (nfd); + } + else + { + status = + sscanf (line, "%lf %lf %lf %lf", &mjd, &satpos.x, &satpos.y, + &satpos.z); + if (gmat == 1) + mjd += 29999.5; + } + compute_position (mjd, satpos, s, satno, desig, precess_flag); + } + fclose (file); } - fclose(file); - } return 0; } // Get observing site -struct site get_site(int site_id) +struct site +get_site (int site_id) { - int i=0; + int i = 0; char line[LIM]; FILE *file; int id; - double lat,lng; + double lat, lng; float alt; - char abbrev[3],observer[64]; + char abbrev[3], observer[64]; struct site s; - char *env,filename[LIM]; + char *env, filename[LIM]; - env=getenv("ST_DATADIR"); - sprintf(filename,"%s/data/sites.txt",env); - file=fopen(filename,"r"); - if (file==NULL) { - printf("File with site information not found!\n"); - return s; - } - while (fgets(line,LIM,file)!=NULL) { - // Skip - if (strstr(line,"#")!=NULL) - continue; - - // Strip newline - line[strlen(line)-1]='\0'; - - // Read data - sscanf(line,"%4d %2s %lf %lf %f", - &id,abbrev,&lat,&lng,&alt); - strcpy(observer,line+38); - - // Change to km - alt/=1000.0; - - // Copy site - if (id==site_id) { - s.lat=lat; - s.lng=lng; - s.alt=alt; - s.id=id; - strcpy(s.observer,observer); + env = getenv ("ST_DATADIR"); + sprintf (filename, "%s/data/sites.txt", env); + file = fopen (filename, "r"); + if (file == NULL) + { + printf ("File with site information not found!\n"); + return s; } + while (fgets (line, LIM, file) != NULL) + { + // Skip + if (strstr (line, "#") != NULL) + continue; - } - fclose(file); + // Strip newline + line[strlen (line) - 1] = '\0'; + + // Read data + sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt); + strcpy (observer, line + 38); + + // Change to km + alt /= 1000.0; + + // Copy site + if (id == site_id) + { + s.lat = lat; + s.lng = lng; + s.alt = alt; + s.id = id; + strcpy (s.observer, observer); + } + + } + fclose (file); return s; } + // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } // Greenwich Mean Sidereal Time -double dgmst(double mjd) +double +dgmst (double mjd) { - double t,dgmst; + double t, dgmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - dgmst=360.98564736629+t*(0.000387933-t/38710000); + dgmst = 360.98564736629 + t * (0.000387933 - t / 38710000); return dgmst; } // Observer position -void obspos_xyz(double mjd,double lng,double lat,float alt,xyz_t *pos,xyz_t *vel) +void +obspos_xyz (double mjd, double lng, double lat, float alt, xyz_t * pos, + xyz_t * vel) { - double ff,gc,gs,theta,s,dtheta; + double ff, gc, gs, theta, s, dtheta; - s=sin(lat*D2R); - ff=sqrt(1.0-FLAT*(2.0-FLAT)*s*s); - gc=1.0/ff+alt/XKMPER; - gs=(1.0-FLAT)*(1.0-FLAT)/ff+alt/XKMPER; + s = sin (lat * D2R); + ff = sqrt (1.0 - FLAT * (2.0 - FLAT) * s * s); + gc = 1.0 / ff + alt / XKMPER; + gs = (1.0 - FLAT) * (1.0 - FLAT) / ff + alt / XKMPER; - theta=gmst(mjd)+lng; - dtheta=dgmst(mjd)*D2R/86400; + theta = gmst (mjd) + lng; + dtheta = dgmst (mjd) * D2R / 86400; - pos->x=gc*cos(lat*D2R)*cos(theta*D2R)*XKMPER; - pos->y=gc*cos(lat*D2R)*sin(theta*D2R)*XKMPER; - pos->z=gs*sin(lat*D2R)*XKMPER; - vel->x=-gc*cos(lat*D2R)*sin(theta*D2R)*XKMPER*dtheta; - vel->y=gc*cos(lat*D2R)*cos(theta*D2R)*XKMPER*dtheta; - vel->z=0.0; + pos->x = gc * cos (lat * D2R) * cos (theta * D2R) * XKMPER; + pos->y = gc * cos (lat * D2R) * sin (theta * D2R) * XKMPER; + pos->z = gs * sin (lat * D2R) * XKMPER; + vel->x = -gc * cos (lat * D2R) * sin (theta * D2R) * XKMPER * dtheta; + vel->y = gc * cos (lat * D2R) * cos (theta * D2R) * XKMPER * dtheta; + vel->z = 0.0; return; } // Precess a celestial position -void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de) +void +precess (double mjd0, double ra0, double de0, double mjd, double *ra, + double *de) { - double t0,t; - double zeta,z,theta; - double a,b,c; + double t0, t; + double zeta, z, theta; + double a, b, c; // Angles in radians - ra0*=D2R; - de0*=D2R; + ra0 *= D2R; + de0 *= D2R; // Time in centuries - t0=(mjd0-51544.5)/36525.0; - t=(mjd-mjd0)/36525.0; + t0 = (mjd0 - 51544.5) / 36525.0; + t = (mjd - mjd0) / 36525.0; // Precession angles - zeta=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - zeta+=(0.30188-0.000344*t0)*t*t+0.017998*t*t*t; - zeta*=D2R/3600.0; - z=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - z+=(1.09468+0.000066*t0)*t*t+0.018203*t*t*t; - z*=D2R/3600.0; - theta=(2004.3109-0.85330*t0-0.000217*t0*t0)*t; - theta+=-(0.42665+0.000217*t0)*t*t-0.041833*t*t*t; - theta*=D2R/3600.0; - - a=cos(de0)*sin(ra0+zeta); - b=cos(theta)*cos(de0)*cos(ra0+zeta)-sin(theta)*sin(de0); - c=sin(theta)*cos(de0)*cos(ra0+zeta)+cos(theta)*sin(de0); + zeta = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + zeta += (0.30188 - 0.000344 * t0) * t * t + 0.017998 * t * t * t; + zeta *= D2R / 3600.0; + z = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + z += (1.09468 + 0.000066 * t0) * t * t + 0.018203 * t * t * t; + z *= D2R / 3600.0; + theta = (2004.3109 - 0.85330 * t0 - 0.000217 * t0 * t0) * t; + theta += -(0.42665 + 0.000217 * t0) * t * t - 0.041833 * t * t * t; + theta *= D2R / 3600.0; - *ra=(atan2(a,b)+z)*R2D; - *de=asin(c)*R2D; + a = cos (de0) * sin (ra0 + zeta); + b = cos (theta) * cos (de0) * cos (ra0 + zeta) - sin (theta) * sin (de0); + c = sin (theta) * cos (de0) * cos (ra0 + zeta) + cos (theta) * sin (de0); - if (*ra<360.0) - *ra+=360.0; - if (*ra>360.0) - *ra-=360.0; + *ra = (atan2 (a, b) + z) * R2D; + *de = asin (c) * R2D; + + if (*ra < 360.0) + *ra += 360.0; + if (*ra > 360.0) + *ra -= 360.0; return; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; + int c, i = 0; - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\t') - c=' '; + c = ' '; if (c == '\n') s[i++] = c; s[i] = '\0'; @@ -382,136 +434,152 @@ int fgetline(FILE *file,char *s,int lim) } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // Compute Date from Julian Day -void mjd2date(double mjd,char *date) +void +mjd2date (double mjd, char *date) { - double f,jd,dday; - int z,alpha,a,b,c,d,e; - int year,month,day,hour,min; - float sec,x; + double f, jd, dday; + int z, alpha, a, b, c, d, e; + int year, month, day, hour, min; + float sec, x; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - dday=b-d-floor(30.6001*e)+f; - if (e<14) - month=e-1; + if (z < 2299161) + a = z; else - month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (month>2) - year=c-4716; + dday = b - d - floor (30.6001 * e) + f; + if (e < 14) + month = e - 1; else - year=c-4715; + month = e - 13; - day=(int) floor(dday); - x=24.0*(dday-day); - x=3600.*fabs(x)+0.0001; - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - hour=x; - sec=floor(1000.0*sec)/1000.0; + if (month > 2) + year = c - 4716; + else + year = c - 4715; - sprintf(date,"%04d%02d%02d%02d%02d%05.0f",year,month,day,hour,min,sec*1000); + day = (int) floor (dday); + x = 24.0 * (dday - day); + x = 3600. * fabs (x) + 0.0001; + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + hour = x; + sec = floor (1000.0 * sec) / 1000.0; + + sprintf (date, "%04d%02d%02d%02d%02d%05.0f", year, month, day, hour, min, + sec * 1000); return; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min; + int year, month, day, hour, min; float sec; - double mjd,dday; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%f",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%f", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; - mjd=date2mjd(year,month,dday); + mjd = date2mjd (year, month, dday); return mjd; } // Convert Decimal into Sexagesimal -void dec2s(double x,char *s,int type) +void +dec2s (double x, char *s, int type) { int i; - double sec,deg,min,fmin; + double sec, deg, min, fmin; char sign; - sign=(x<0 ? '-' : '+'); - x=60.*fabs(x); + sign = (x < 0 ? '-' : '+'); + x = 60. * fabs (x); - min=fmod(x,60.); - x=(x-min)/60.; + min = fmod (x, 60.); + x = (x - min) / 60.; // deg=fmod(x,60.); - deg=x; - if (type==0) - fmin=1000.0*(min-floor(min)); + deg = x; + if (type == 0) + fmin = 1000.0 * (min - floor (min)); else - fmin=100.0*(min-floor(min)); + fmin = 100.0 * (min - floor (min)); - if (type==0) - sprintf(s,"%02.0f%02.0f%03.0f",deg,floor(min),floor(fmin)); + if (type == 0) + sprintf (s, "%02.0f%02.0f%03.0f", deg, floor (min), floor (fmin)); else - sprintf(s,"%c%02.0f%02.0f%02.0f",sign,deg,floor(min),floor(fmin)); + sprintf (s, "%c%02.0f%02.0f%02.0f", sign, deg, floor (min), floor (fmin)); return; } // DOY to MJD -double doy2mjd(int year,double doy) +double +doy2mjd (int year, double doy) { - int month,k=2; + int month, k = 2; double day; - if (year%4==0 && year%400!=0) - k=1; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - month=floor(9.0*(k+doy)/275.0+0.98); - - if (doy<32) - month=1; + month = floor (9.0 * (k + doy) / 275.0 + 0.98); - day=doy-floor(275.0*month/9.0)+k*floor((month+9.0)/12.0)+30.0; + if (doy < 32) + month = 1; - return date2mjd(year,month,day); + day = + doy - floor (275.0 * month / 9.0) + k * floor ((month + 9.0) / 12.0) + + 30.0; + + return date2mjd (year, month, day); } diff --git a/src/faketle.c b/src/faketle.c index 28ac356..a682d78 100644 --- a/src/faketle.c +++ b/src/faketle.c @@ -7,295 +7,334 @@ #include "satutl.h" #include -#define XKMPER 6378.135 /* Km per earth radii */ -#define XMNPDA 1440.0 /* Minutes per day */ -#define AE 1.0 /* Earth radius in "chosen units". */ +#define XKMPER 6378.135 /* Km per earth radii */ +#define XMNPDA 1440.0 /* Minutes per day */ +#define AE 1.0 /* Earth radius in "chosen units". */ #define XKE 0.743669161e-1 -#define CK2 5.413080e-4 /* (0.5 * XJ2 * AE * AE) */ +#define CK2 5.413080e-4 /* (0.5 * XJ2 * AE * AE) */ #define R2D 180.0/M_PI #define D2R M_PI/180.0 extern double SGDP4_jd0; -void orbit(orbit_t orb,float *aodp,float *perigee,float *apogee,float *period); -void format_tle(orbit_t orb,char *line1,char *line2); -double mjd2doy(double mjd,int *yr); -double nfd2mjd(char *date); -double date2mjd(int year,int month,double day); -void mjd2date(double mjd,int *year,int *month,double *day); -double gmst(double mjd); -double modulo(double x,double y); +void orbit (orbit_t orb, float *aodp, float *perigee, float *apogee, + float *period); +void format_tle (orbit_t orb, char *line1, char *line2); +double mjd2doy (double mjd, int *yr); +double nfd2mjd (char *date); +double date2mjd (int year, int month, double day); +void mjd2date (double mjd, int *year, int *month, double *day); +double gmst (double mjd); +double modulo (double x, double y); -void usage(void) +void +usage (void) { - printf("faketle q:Q:i:I:w:t:m:n:d:\n\n"); + printf ("faketle q:Q:i:I:w:t:m:n:d:\n\n"); - printf("-q Perigee altitude (km)\n"); - printf("-Q Apogee altitude (km)\n"); - printf("-I Orbital inclination (deg)\n"); - printf("-n RA of the ascending node (deg)\n"); - printf("-w Argument of perigee (deg)\n"); - printf("-m Mean anomaly (deg)\n"); - printf("-t Epoch (YYYY-mm-ddThh:mm:ss)\n"); - printf("-i Satellite number\n"); - printf("-d Time offset from epoch (s)\n"); + printf ("-q Perigee altitude (km)\n"); + printf ("-Q Apogee altitude (km)\n"); + printf ("-I Orbital inclination (deg)\n"); + printf ("-n RA of the ascending node (deg)\n"); + printf ("-w Argument of perigee (deg)\n"); + printf ("-m Mean anomaly (deg)\n"); + printf ("-t Epoch (YYYY-mm-ddThh:mm:ss)\n"); + printf ("-i Satellite number\n"); + printf ("-d Time offset from epoch (s)\n"); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { orbit_t orb; - float aodp,perigee,apogee,period,dt=0.0; - char line1[70],line2[70]; - int arg=0; - double mjd,dh; + float aodp, perigee, apogee, period, dt = 0.0; + char line1[70], line2[70]; + int arg = 0; + double mjd, dh; // Initialize - orb.satno=99999; - orb.eqinc=0.0; - orb.ascn=0.0; - orb.argp=0.0; - orb.mnan=0.0; - orb.bstar=0.5e-4; - orb.ep_day=1.000; - orb.ep_year=2013; + orb.satno = 99999; + orb.eqinc = 0.0; + orb.ascn = 0.0; + orb.argp = 0.0; + orb.mnan = 0.0; + orb.bstar = 0.5e-4; + orb.ep_day = 1.000; + orb.ep_year = 2013; // Decode options - while ((arg=getopt(argc,argv,"q:Q:i:I:w:t:m:n:hd:"))!=-1) { - switch(arg) { - case 'q': - perigee=atof(optarg); - break; + while ((arg = getopt (argc, argv, "q:Q:i:I:w:t:m:n:hd:")) != -1) + { + switch (arg) + { + case 'q': + perigee = atof (optarg); + break; - case 'Q': - apogee=atof(optarg); - break; + case 'Q': + apogee = atof (optarg); + break; - case 'I': - orb.eqinc=atof(optarg)*D2R; - break; + case 'I': + orb.eqinc = atof (optarg) * D2R; + break; - case 'n': - orb.ascn=atof(optarg)*D2R; - break; + case 'n': + orb.ascn = atof (optarg) * D2R; + break; - case 'i': - orb.satno=atoi(optarg); - break; + case 'i': + orb.satno = atoi (optarg); + break; - case 'w': - orb.argp=atof(optarg)*D2R; - break; + case 'w': + orb.argp = atof (optarg) * D2R; + break; - case 'm': - orb.mnan=atof(optarg)*D2R; - break; + case 'm': + orb.mnan = atof (optarg) * D2R; + break; - case 't': - mjd=nfd2mjd(optarg); - break; + case 't': + mjd = nfd2mjd (optarg); + break; - case 'd': - dt=atof(optarg); - break; + case 'd': + dt = atof (optarg); + break; - case 'h': - usage(); - return 0; + case 'h': + usage (); + return 0; - default: - usage(); - return 0; + default: + usage (); + return 0; + } } - } - orb.ep_day=mjd2doy(mjd+dt/86400.0,&orb.ep_year); + orb.ep_day = mjd2doy (mjd + dt / 86400.0, &orb.ep_year); - perigee+=XKMPER; - apogee+=XKMPER; - aodp=0.5*(perigee+apogee)/XKMPER; - orb.ecc=0.5*(apogee-perigee)/(aodp*XKMPER); - orb.rev=XKE*pow(aodp,-1.5)*XMNPDA/(2.0*M_PI); - if (orb.rev<10) - orb.bstar=0.0; - orbit(orb,&aodp,&perigee,&apogee,&period); + perigee += XKMPER; + apogee += XKMPER; + aodp = 0.5 * (perigee + apogee) / XKMPER; + orb.ecc = 0.5 * (apogee - perigee) / (aodp * XKMPER); + orb.rev = XKE * pow (aodp, -1.5) * XMNPDA / (2.0 * M_PI); + if (orb.rev < 10) + orb.bstar = 0.0; + orbit (orb, &aodp, &perigee, &apogee, &period); - format_tle(orb,line1,line2); - printf("%s\n%s\n",line1,line2); + format_tle (orb, line1, line2); + printf ("%s\n%s\n", line1, line2); return 0; } -void orbit(orbit_t orb,float *aodp,float *perigee,float *apogee,float *period) +void +orbit (orbit_t orb, float *aodp, float *perigee, float *apogee, float *period) { - float xno,eo,xincl; - float a1,betao2,betao,temp0,del1,a0,del0,xnodp; + float xno, eo, xincl; + float a1, betao2, betao, temp0, del1, a0, del0, xnodp; - xno=orb.rev*2.0*M_PI/XMNPDA; - eo=orb.ecc; - xincl=orb.eqinc; + xno = orb.rev * 2.0 * M_PI / XMNPDA; + eo = orb.ecc; + xincl = orb.eqinc; - a1 = pow(XKE / xno, 2.0/3.0); + a1 = pow (XKE / xno, 2.0 / 3.0); betao2 = 1.0 - eo * eo; - betao = sqrt(betao2); - temp0 = (1.5 * CK2) * cos(xincl)*cos(xincl) / (betao * betao2); + betao = sqrt (betao2); + temp0 = (1.5 * CK2) * cos (xincl) * cos (xincl) / (betao * betao2); del1 = temp0 / (a1 * a1); - a0 = a1 * (1.0 - del1 * (1.0/3.0 + del1 * (1.0 + del1 * 134.0/81.0))); + a0 = a1 * (1.0 - del1 * (1.0 / 3.0 + del1 * (1.0 + del1 * 134.0 / 81.0))); del0 = temp0 / (a0 * a0); xnodp = xno / (1.0 + del0); *aodp = (a0 / (1.0 - del0)); *perigee = (*aodp * (1.0 - eo) - 1) * XKMPER; *apogee = (*aodp * (1.0 + eo) - 1) * XKMPER; *period = (TWOPI * 1440.0 / XMNPDA) / xnodp; - *aodp=(*aodp-1)*XKMPER; + *aodp = (*aodp - 1) * XKMPER; return; } // Format TLE -void format_tle(orbit_t orb,char *line1,char *line2) +void +format_tle (orbit_t orb, char *line1, char *line2) { - int i,csum; - char sbstar[]=" 00000-0",bstar[13]; + int i, csum; + char sbstar[] = " 00000-0", bstar[13]; // Format Bstar term - if (fabs(orb.bstar)>1e-9) { - sprintf(bstar,"%11.4e",10*orb.bstar); - sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4]; - sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0'; - } + if (fabs (orb.bstar) > 1e-9) + { + sprintf (bstar, "%11.4e", 10 * orb.bstar); + sbstar[0] = bstar[0]; + sbstar[1] = bstar[1]; + sbstar[2] = bstar[3]; + sbstar[3] = bstar[4]; + sbstar[4] = bstar[5]; + sbstar[5] = bstar[6]; + sbstar[6] = bstar[8]; + sbstar[7] = bstar[10]; + sbstar[8] = '\0'; + } // Print lines - sprintf(line1,"1 %05dU %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.ep_year-2000,orb.ep_day,sbstar); - sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev); + sprintf (line1, + "1 %05dU %2d%012.8f .00000000 00000-0 %8s 0 0", + orb.satno, orb.ep_year - 2000, orb.ep_day, sbstar); + sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0", + orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc, + DEG (orb.argp), DEG (orb.mnan), orb.rev); // Compute checksums - for (i=0,csum=0;i2) - *year=c-4716; + *day = b - d - floor (30.6001 * e) + f; + if (e < 14) + *month = e - 1; else - *year=c-4715; + *month = e - 13; + + if (*month > 2) + *year = c - 4716; + else + *year = c - 4715; return; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } diff --git a/src/ferror.c b/src/ferror.c index feae52d..a26bbc0 100644 --- a/src/ferror.c +++ b/src/ferror.c @@ -7,23 +7,24 @@ #include -void fatal_error(const char *format, ...) +void +fatal_error (const char *format, ...) { -va_list arg_ptr; + va_list arg_ptr; - fflush(stdout); + fflush (stdout); - fprintf(stderr, "\nFatal run-time error:\n"); + fprintf (stderr, "\nFatal run-time error:\n"); - va_start(arg_ptr, format); - vfprintf(stderr, format, arg_ptr); - va_end(arg_ptr); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); - //fprintf(stderr, "\nNow terminating the program...\n"); - // fflush(stderr); + //fprintf(stderr, "\nNow terminating the program...\n"); + // fflush(stderr); - // exit(5); - return; + // exit(5); + return; } /* ===================================================================== */ diff --git a/src/fitsheader.c b/src/fitsheader.c index 789cf97..4095bf4 100644 --- a/src/fitsheader.c +++ b/src/fitsheader.c @@ -5,43 +5,48 @@ #define LIM 81 -int fgetline(FILE *,char *,int); -void rtrim(char *); +int fgetline (FILE *, char *, int); +void rtrim (char *); -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { char line[LIM]; FILE *fitsfile; // Usage - if (argc<2) { - printf("Usage: %s \n",argv[0]); - printf("\n\nOutputs the header of \n"); - return 1; - } + if (argc < 2) + { + printf ("Usage: %s \n", argv[0]); + printf ("\n\nOutputs the header of \n"); + return 1; + } // Open file - fitsfile=fopen(argv[1],"r"); + fitsfile = fopen (argv[1], "r"); // Loop over file and output - while (fgetline(fitsfile,line,LIM)>0) { - rtrim(line); - printf("%s\n",line); - if (strcmp(line,"END")==0) break; - } + while (fgetline (fitsfile, line, LIM) > 0) + { + rtrim (line); + printf ("%s\n", line); + if (strcmp (line, "END") == 0) + break; + } // Close file - fclose(fitsfile); + fclose (fitsfile); return 0; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; + int c, i = 0; - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; @@ -50,15 +55,17 @@ int fgetline(FILE *file,char *s,int lim) } // Removes trailing blanks from string s -void rtrim(char *s) +void +rtrim (char *s) { - int i,j=0,n; + int i, j = 0, n; - n=strlen(s); - for (i=n;i>=0;i--) - if (s[i]!='\0' && s[i]!='\n') - if (!isspace(s[i]) && j==0) j=i; - s[++j]='\0'; + n = strlen (s); + for (i = n; i >= 0; i--) + if (s[i] != '\0' && s[i] != '\n') + if (!isspace (s[i]) && j == 0) + j = i; + s[++j] = '\0'; return; } diff --git a/src/fitskey.c b/src/fitskey.c index 0bdb2a9..0e56f3c 100644 --- a/src/fitskey.c +++ b/src/fitskey.c @@ -4,34 +4,40 @@ #include #include "qfits.h" -int main(int argc, char * argv[]) +int +main (int argc, char *argv[]) { int i; - char keyword[FITS_LINESZ+1]; + char keyword[FITS_LINESZ + 1]; char *value; - + // Usage - if (argc<3) { - printf("Usage: %s [ext] etc.\n", argv[0]); - return 1 ; - } + if (argc < 3) + { + printf ("Usage: %s [ext] etc.\n", argv[0]); + return 1; + } // Check this is indeed a FITS file - if (is_fits_file(argv[1])!=1) { - printf("%s is not a FITS file\n", argv[1]); - return -1 ; - } - + if (is_fits_file (argv[1]) != 1) + { + printf ("%s is not a FITS file\n", argv[1]); + return -1; + } + // Extension header? - if (atoi(argv[2])==0) { - for (i=2;i // Get a x and y from a RA and Decl -void forward(double ra0,double de0,double ra,double de,double *x,double *y) +void +forward (double ra0, double de0, double ra, double de, double *x, double *y) { - int i,status; - double phi,theta; + int i, status; + double phi, theta; struct celprm cel; // Initialize Reference Angles - celini(&cel); - cel.ref[0]=ra0; - cel.ref[1]=de0; - cel.ref[2]=999.; - cel.ref[3]=999.; - cel.flag=0.; - strcpy(cel.prj.code,"STG"); + celini (&cel); + cel.ref[0] = ra0; + cel.ref[1] = de0; + cel.ref[2] = 999.; + cel.ref[3] = 999.; + cel.flag = 0.; + strcpy (cel.prj.code, "STG"); - if (celset(&cel)) { - printf("Error in Projection (celset)\n"); - return; - } - cels2x(&cel,1,0,1,1,&ra,&de,&phi,&theta,x,y,&status); + if (celset (&cel)) + { + printf ("Error in Projection (celset)\n"); + return; + } + cels2x (&cel, 1, 0, 1, 1, &ra, &de, &phi, &theta, x, y, &status); - *x *=3600.; - *y *=3600.; + *x *= 3600.; + *y *= 3600.; return; } diff --git a/src/geolon.c b/src/geolon.c index 7302ea4..a02628b 100644 --- a/src/geolon.c +++ b/src/geolon.c @@ -9,196 +9,227 @@ #define LIM 128 #define D2R M_PI/180.0 #define R2D 180.0/M_PI -#define XKMPER 6378.135 // Earth radius in km +#define XKMPER 6378.135 // Earth radius in km -long Isat=0; -long Isatsel=0; +long Isat = 0; +long Isatsel = 0; extern double SGDP4_jd0; -struct map { +struct map +{ long satno; double mjd; - char nfd[LIM],tlefile[LIM],observer[32]; - char datadir[LIM],tledir[LIM]; + char nfd[LIM], tlefile[LIM], observer[32]; + char datadir[LIM], tledir[LIM]; } m; // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min,sec; - double mjd,dday; + int year, month, day, hour, min, sec; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; - mjd=date2mjd(year,month,dday); + mjd = date2mjd (year, month, dday); return mjd; } -void usage() +void +usage () { - printf("Usage goes here.\n"); - + printf ("Usage goes here.\n"); + return; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } // Present nfd -void nfd_now(char *s) +void +nfd_now (char *s) { time_t rawtime; struct tm *ptm; // Get UTC time - time(&rawtime); - ptm=gmtime(&rawtime); - - sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec); - + time (&rawtime); + ptm = gmtime (&rawtime); + + sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900, + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, + ptm->tm_sec); + return; } // Compute longitude -void compute_longitude(char *tlefile,long satno,double mjd) +void +compute_longitude (char *tlefile, long satno, double mjd) { - FILE *fp=NULL; + FILE *fp = NULL; orbit_t orb; - xyz_t satpos,satvel; - double jd,h,l,b,r; + xyz_t satpos, satvel; + double jd, h, l, b, r; long imode; - + // Open TLE file - fp = fopen(tlefile, "rb"); - if(fp == NULL) - fatal_error("File open failed for reading \"%s\"", tlefile); - + fp = fopen (tlefile, "rb"); + if (fp == NULL) + fatal_error ("File open failed for reading \"%s\"", tlefile); + // Loop over elements - while(read_twoline(fp, satno, &orb) == 0) { - Isat = orb.satno; - imode = init_sgdp4(&orb); - if(imode == SGDP4_ERROR) continue; + while (read_twoline (fp, satno, &orb) == 0) + { + Isat = orb.satno; + imode = init_sgdp4 (&orb); + if (imode == SGDP4_ERROR) + continue; - // Skip objects with mean motions outside of 0.8 to 1.2 revs/day - if (orb.rev<0.8 || orb.rev>1.2) - continue; - - // Get Julian Date - jd=mjd+2400000.5; - - // Get positions - satpos_xyz(jd,&satpos,&satvel); + // Skip objects with mean motions outside of 0.8 to 1.2 revs/day + if (orb.rev < 0.8 || orb.rev > 1.2) + continue; - // Greenwich Mean Sidereal time - h=gmst(mjd); + // Get Julian Date + jd = mjd + 2400000.5; - // Celestial position - r=sqrt(satpos.x*satpos.x+satpos.y*satpos.y+satpos.z*satpos.z); - l=atan2(satpos.y,satpos.x)*R2D; - l=modulo(l-h,360.0); - b=asin(satpos.z/r)*R2D; - if (l>180.0) - l-=360.0; - if (l<-180.0) - l+=360.0; + // Get positions + satpos_xyz (jd, &satpos, &satvel); - printf("%05d %10s %8.3lf %8.3lf %6.0lf\n",orb.satno,orb.desig,l,b,r-XKMPER); - } - fclose(fp); + // Greenwich Mean Sidereal time + h = gmst (mjd); + + // Celestial position + r = + sqrt (satpos.x * satpos.x + satpos.y * satpos.y + + satpos.z * satpos.z); + l = atan2 (satpos.y, satpos.x) * R2D; + l = modulo (l - h, 360.0); + b = asin (satpos.z / r) * R2D; + if (l > 180.0) + l -= 360.0; + if (l < -180.0) + l += 360.0; + + printf ("%05d %10s %8.3lf %8.3lf %6.0lf\n", orb.satno, orb.desig, l, b, + r - XKMPER); + } + fclose (fp); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int arg=0; - long satno=0; + int arg = 0; + long satno = 0; double mjd; - char nfd[LIM],tlefile[LIM]; + char nfd[LIM], tlefile[LIM]; + + nfd_now (nfd); + mjd = nfd2mjd (nfd); - nfd_now(nfd); - mjd=nfd2mjd(nfd); - // Decode options - if (argc>1) { - while ((arg=getopt(argc,argv,"t:c:i:h"))!=-1) { - switch (arg) { - - case 't': - strcpy(nfd,optarg); - mjd=nfd2mjd(nfd); - break; - - case 'c': - strcpy(tlefile,optarg); - break; - - case 'i': - satno=atoi(optarg); - break; - - case 'h': - usage(); - return 0; - break; - - default: - usage(); - return 0; - } + if (argc > 1) + { + while ((arg = getopt (argc, argv, "t:c:i:h")) != -1) + { + switch (arg) + { + + case 't': + strcpy (nfd, optarg); + mjd = nfd2mjd (nfd); + break; + + case 'c': + strcpy (tlefile, optarg); + break; + + case 'i': + satno = atoi (optarg); + break; + + case 'h': + usage (); + return 0; + break; + + default: + usage (); + return 0; + } + } + } + else + { + usage (); + return 0; } - } else { - usage(); - return 0; - } // Compute longitudes of satellites - compute_longitude(tlefile,satno,mjd); + compute_longitude (tlefile, satno, mjd); return 0; } diff --git a/src/imgstat.c b/src/imgstat.c index 1d05b6d..e2dd296 100644 --- a/src/imgstat.c +++ b/src/imgstat.c @@ -8,266 +8,294 @@ #define D2R M_PI/180.0 #define R2D 180.0/M_PI -struct image { +struct image +{ char filename[64]; - int naxis1,naxis2; + int naxis1, naxis2; float *zavg; - double ra0,de0; - float x0,y0; - float a[3],b[3],xrms,yrms; + double ra0, de0; + float x0, y0; + float a[3], b[3], xrms, yrms; double mjd; float exptime; char nfd[32]; int cospar; }; -struct map { - char datadir[LIM],observer[32]; - double lng,lat; +struct map +{ + char datadir[LIM], observer[32]; + double lng, lat; float alt; int site_id; } m; -struct image read_fits(char *filename); +struct image read_fits (char *filename); // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } // Precess a celestial position -void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de) +void +precess (double mjd0, double ra0, double de0, double mjd, double *ra, + double *de) { - double t0,t; - double zeta,z,theta; - double a,b,c; + double t0, t; + double zeta, z, theta; + double a, b, c; // Angles in radians - ra0*=D2R; - de0*=D2R; + ra0 *= D2R; + de0 *= D2R; // Time in centuries - t0=(mjd0-51544.5)/36525.0; - t=(mjd-mjd0)/36525.0; + t0 = (mjd0 - 51544.5) / 36525.0; + t = (mjd - mjd0) / 36525.0; // Precession angles - zeta=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - zeta+=(0.30188-0.000344*t0)*t*t+0.017998*t*t*t; - zeta*=D2R/3600.0; - z=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - z+=(1.09468+0.000066*t0)*t*t+0.018203*t*t*t; - z*=D2R/3600.0; - theta=(2004.3109-0.85330*t0-0.000217*t0*t0)*t; - theta+=-(0.42665+0.000217*t0)*t*t-0.041833*t*t*t; - theta*=D2R/3600.0; - - a=cos(de0)*sin(ra0+zeta); - b=cos(theta)*cos(de0)*cos(ra0+zeta)-sin(theta)*sin(de0); - c=sin(theta)*cos(de0)*cos(ra0+zeta)+cos(theta)*sin(de0); + zeta = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + zeta += (0.30188 - 0.000344 * t0) * t * t + 0.017998 * t * t * t; + zeta *= D2R / 3600.0; + z = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + z += (1.09468 + 0.000066 * t0) * t * t + 0.018203 * t * t * t; + z *= D2R / 3600.0; + theta = (2004.3109 - 0.85330 * t0 - 0.000217 * t0 * t0) * t; + theta += -(0.42665 + 0.000217 * t0) * t * t - 0.041833 * t * t * t; + theta *= D2R / 3600.0; - *ra=(atan2(a,b)+z)*R2D; - *de=asin(c)*R2D; + a = cos (de0) * sin (ra0 + zeta); + b = cos (theta) * cos (de0) * cos (ra0 + zeta) - sin (theta) * sin (de0); + c = sin (theta) * cos (de0) * cos (ra0 + zeta) + cos (theta) * sin (de0); - if (*ra<360.0) - *ra+=360.0; - if (*ra>360.0) - *ra-=360.0; + *ra = (atan2 (a, b) + z) * R2D; + *de = asin (c) * R2D; + + if (*ra < 360.0) + *ra += 360.0; + if (*ra > 360.0) + *ra -= 360.0; return; } // Get observing site -void get_site(int site_id) +void +get_site (int site_id) { - int i=0; + int i = 0; char line[LIM]; FILE *file; int id; - double lat,lng; + double lat, lng; float alt; - char abbrev[3],observer[64],filename[LIM]; + char abbrev[3], observer[64], filename[LIM]; - sprintf(filename,"%s/data/sites.txt",m.datadir); - file=fopen(filename,"r"); - if (file==NULL) { - printf("File with site information not found!\n"); - return; - } - while (fgets(line,LIM,file)!=NULL) { - // Skip - if (strstr(line,"#")!=NULL) - continue; - - // Strip newline - line[strlen(line)-1]='\0'; - - // Read data - sscanf(line,"%4d %2s %lf %lf %f", - &id,abbrev,&lat,&lng,&alt); - strcpy(observer,line+38); - - // Change to km - alt/=1000.0; - - if (id==site_id) { - m.lat=lat; - m.lng=lng; - m.alt=alt; - m.site_id=id; - strcpy(m.observer,observer); + sprintf (filename, "%s/data/sites.txt", m.datadir); + file = fopen (filename, "r"); + if (file == NULL) + { + printf ("File with site information not found!\n"); + return; } + while (fgets (line, LIM, file) != NULL) + { + // Skip + if (strstr (line, "#") != NULL) + continue; - } - fclose(file); + // Strip newline + line[strlen (line) - 1] = '\0'; + + // Read data + sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt); + strcpy (observer, line + 38); + + // Change to km + alt /= 1000.0; + + if (id == site_id) + { + m.lat = lat; + m.lng = lng; + m.alt = alt; + m.site_id = id; + strcpy (m.observer, observer); + } + + } + fclose (file); return; } // Convert equatorial into horizontal coordinates -void equatorial2horizontal(double mjd,double ra,double de,double *azi,double *alt) +void +equatorial2horizontal (double mjd, double ra, double de, double *azi, + double *alt) { double h; - h=gmst(mjd)+m.lng-ra; - - *azi=modulo(atan2(sin(h*D2R),cos(h*D2R)*sin(m.lat*D2R)-tan(de*D2R)*cos(m.lat*D2R))*R2D,360.0); - *alt=asin(sin(m.lat*D2R)*sin(de*D2R)+cos(m.lat*D2R)*cos(de*D2R)*cos(h*D2R))*R2D; + h = gmst (mjd) + m.lng - ra; + + *azi = + modulo (atan2 + (sin (h * D2R), + cos (h * D2R) * sin (m.lat * D2R) - + tan (de * D2R) * cos (m.lat * D2R)) * R2D, 360.0); + *alt = + asin (sin (m.lat * D2R) * sin (de * D2R) + + cos (m.lat * D2R) * cos (de * D2R) * cos (h * D2R)) * R2D; return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { int i; struct image img; - float zavg,zstd,sx,sy,wx,wy; - double ra,de,alt,azi,mjd0=51544.5; + float zavg, zstd, sx, sy, wx, wy; + double ra, de, alt, azi, mjd0 = 51544.5; char *env; - + // Get environment variables - env=getenv("ST_DATADIR"); - if (env!=NULL) { - strcpy(m.datadir,env); - } else { - printf("ST_DATADIR environment variable not found.\n"); - } + env = getenv ("ST_DATADIR"); + if (env != NULL) + { + strcpy (m.datadir, env); + } + else + { + printf ("ST_DATADIR environment variable not found.\n"); + } // Read image - img=read_fits(argv[1]); + img = read_fits (argv[1]); // Get site - get_site(img.cospar); - + get_site (img.cospar); + // Compute statistics - for (i=0,zavg=0.0;i #include -struct image { - int nx,ny,nz; +struct image +{ + int nx, ny, nz; float *z; double mjd; - char nfd[32],observer[32]; - int cospar,tracked; + char nfd[32], observer[32]; + int cospar, tracked; float exptime; }; -struct image read_jpg(char *filename); -void write_fits(struct image img,char *filename); -double date2mjd(int year,int month,double day); -double nfd2mjd(char *date); -void mjd2nfd(double mjd,char *nfd); +struct image read_jpg (char *filename); +void write_fits (struct image img, char *filename); +double date2mjd (int year, int month, double day); +double nfd2mjd (char *date); +void mjd2nfd (double mjd, char *nfd); // Read fits image -struct image read_fits(char *filename) +struct image +read_fits (char *filename) { - int i,j,k,l,m; + int i, j, k, l, m; qfitsloader ql; - char key[FITS_LINESZ+1] ; + char key[FITS_LINESZ + 1]; struct image img; - float s1,s2,avg,std; + float s1, s2, avg, std; // Set plane ql.xtnum = 0; @@ -38,478 +40,520 @@ struct image read_fits(char *filename) ql.ptype = PTYPE_FLOAT; // Set filename - ql.filename=filename; + ql.filename = filename; // Image size - img.nx=atoi(qfits_query_hdr(filename,"NAXIS1")); - img.ny=atoi(qfits_query_hdr(filename,"NAXIS2")); - img.nz=1; + img.nx = atoi (qfits_query_hdr (filename, "NAXIS1")); + img.ny = atoi (qfits_query_hdr (filename, "NAXIS2")); + img.nz = 1; // Initialize load - if (qfitsloader_init(&ql) != 0) - printf("Error initializing data loading\n"); + if (qfitsloader_init (&ql) != 0) + printf ("Error initializing data loading\n"); // Test load - if (qfits_loadpix(&ql) != 0) - printf("Error loading actual data\n"); + if (qfits_loadpix (&ql) != 0) + printf ("Error loading actual data\n"); // Allocate image memory - img.z=(float *) malloc(sizeof(float) * img.nx*img.ny*img.nz); + img.z = (float *) malloc (sizeof (float) * img.nx * img.ny * img.nz); // Fill z array - for (i=0,l=0,m=0;i1) { - while ((arg=getopt(argc,argv,"i:t:o:d:Z:c:T:O:b:hFs"))!=-1) { - switch(arg) { + if (argc > 1) + { + while ((arg = getopt (argc, argv, "i:t:o:d:Z:c:T:O:b:hFs")) != -1) + { + switch (arg) + { - case 's': - tracked=1; - break; - - case 'i': - strcpy(infile,optarg); - break; - - case 'd': - delay=(double) atof(optarg); - break; - - case 'b': - nbin=atoi(optarg); - break; - - case 'Z': - tz=(double) atof(optarg); - break; - - case 'o': - strcpy(outfile,optarg); - flag=1; - break; - - case 'F': - readfits=1; - break; + case 's': + tracked = 1; + break; - case 't': - strcpy(nfd,optarg); - break; - - case 'c': - cospar=atoi(optarg); - break; - - case 'T': - exptime=atof(optarg); - break; - - case 'O': - strcpy(observer,optarg); - break; - - case 'h': - usage(); - break; - - default: - usage(); - return 0; - - } + case 'i': + strcpy (infile, optarg); + break; + + case 'd': + delay = (double) atof (optarg); + break; + + case 'b': + nbin = atoi (optarg); + break; + + case 'Z': + tz = (double) atof (optarg); + break; + + case 'o': + strcpy (outfile, optarg); + flag = 1; + break; + + case 'F': + readfits = 1; + break; + + case 't': + strcpy (nfd, optarg); + break; + + case 'c': + cospar = atoi (optarg); + break; + + case 'T': + exptime = atof (optarg); + break; + + case 'O': + strcpy (observer, optarg); + break; + + case 'h': + usage (); + break; + + default: + usage (); + return 0; + + } + } } - } else { - usage(); - } - - if (infile!=NULL) { - if (nbin==1) { - if (readfits==0) - img=read_jpg(infile); - else - img=read_fits(infile); - } else { - if (readfits==0) - raw=read_jpg(infile); - else - raw=read_fits(infile); - img=rebin(raw,nbin); + else + { + usage (); + } + + if (infile != NULL) + { + if (nbin == 1) + { + if (readfits == 0) + img = read_jpg (infile); + else + img = read_fits (infile); + } + else + { + if (readfits == 0) + raw = read_jpg (infile); + else + raw = read_fits (infile); + img = rebin (raw, nbin); + } } - } // Set tracked flag - if (tracked==1) - img.tracked=1; + if (tracked == 1) + img.tracked = 1; else - img.tracked=0; - - if (nfd!=NULL) { - // Compute time - mjd=nfd2mjd(nfd); - mjd+=(delay+tz)/86400.0; - mjd2nfd(mjd,nfd); + img.tracked = 0; - // Into file - strcpy(img.nfd,nfd); - img.mjd=mjd; - } + if (nfd != NULL) + { + // Compute time + mjd = nfd2mjd (nfd); + mjd += (delay + tz) / 86400.0; + mjd2nfd (mjd, nfd); - if (flag==0) - sprintf(outfile,"%s.fits",img.nfd); + // Into file + strcpy (img.nfd, nfd); + img.mjd = mjd; + } + + if (flag == 0) + sprintf (outfile, "%s.fits", img.nfd); // Set properties - img.cospar=cospar; - img.exptime=exptime; - strcpy(img.observer,observer); + img.cospar = cospar; + img.exptime = exptime; + strcpy (img.observer, observer); - if (outfile!=NULL) - write_fits(img,outfile); + if (outfile != NULL) + write_fits (img, outfile); // Free - free(img.z); - if (nbin!=1) - free(raw.z); + free (img.z); + if (nbin != 1) + free (raw.z); return 0; } -struct image read_jpg(char *filename) +struct image +read_jpg (char *filename) { - int i=0,j,k,l,m; - unsigned long location=0; + int i = 0, j, k, l, m; + unsigned long location = 0; struct image img; struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; - unsigned char *raw_image=NULL; + unsigned char *raw_image = NULL; FILE *file; ExifData *ed; ExifEntry *entry; // Open file - file=fopen(filename,"rb"); + file = fopen (filename, "rb"); if (!file) - perror("Error opening file"); + perror ("Error opening file"); // Get header info, decompress - cinfo.err=jpeg_std_error(&jerr); - jpeg_create_decompress(&cinfo); - jpeg_stdio_src(&cinfo,file); - jpeg_read_header(&cinfo,TRUE); - jpeg_start_decompress(&cinfo); + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_decompress (&cinfo); + jpeg_stdio_src (&cinfo, file); + jpeg_read_header (&cinfo, TRUE); + jpeg_start_decompress (&cinfo); // Allocate memory - raw_image=(unsigned char *) malloc(cinfo.output_width*cinfo.output_height*cinfo.num_components); + raw_image = + (unsigned char *) malloc (cinfo.output_width * cinfo.output_height * + cinfo.num_components); // Read image, one scan at a time - row_pointer[0]=(unsigned char *) malloc(cinfo.output_width*cinfo.num_components); - while(cinfo.output_scanlineifd[0],EXIF_TAG_DATE_TIME); - exif_entry_get_value(entry,img.nfd, sizeof(img.nfd)); - img.nfd[4]='-'; - img.nfd[7]='-'; - img.nfd[10]='T'; - img.nfd[20]='\0'; - img.mjd=nfd2mjd(img.nfd); - } - */ + // Get exif info + ed=exif_data_new_from_file(filename); + if (!ed) { + printf("File not readable or no EXIF data in file %s\n",filename); + } else { + entry=exif_content_get_entry(ed->ifd[0],EXIF_TAG_DATE_TIME); + exif_entry_get_value(entry,img.nfd, sizeof(img.nfd)); + img.nfd[4]='-'; + img.nfd[7]='-'; + img.nfd[10]='T'; + img.nfd[20]='\0'; + img.mjd=nfd2mjd(img.nfd); + } + */ return img; } // Write fits file -void write_fits(struct image img,char *filename) +void +write_fits (struct image img, char *filename) { - int i,j,k,l; + int i, j, k, l; int *ibuf; qfitsdumper qd; qfits_header *qh; - char key[FITS_LINESZ+1] ; - char val[FITS_LINESZ+1] ; - char com[FITS_LINESZ+1] ; - char lin[FITS_LINESZ+1] ; + char key[FITS_LINESZ + 1]; + char val[FITS_LINESZ + 1]; + char com[FITS_LINESZ + 1]; + char lin[FITS_LINESZ + 1]; FILE *file; // Create FITS header - qh=qfits_header_default(); + qh = qfits_header_default (); // Add stuff - qfits_header_add(qh,"BITPIX","16"," ",NULL); - qfits_header_add(qh,"NAXIS","2"," ",NULL); - sprintf(val,"%i",img.nx); - qfits_header_add(qh,"NAXIS1",val," ",NULL); - sprintf(val,"%i",img.ny); - qfits_header_add(qh,"NAXIS2",val," ",NULL); - qfits_header_add(qh,"BSCALE","1.0"," ",NULL); - qfits_header_add(qh,"BZERO","0.0"," ",NULL); - qfits_header_add(qh,"DATAMAX","255.0"," ",NULL); - qfits_header_add(qh,"DATAMIN","0.0"," ",NULL); + qfits_header_add (qh, "BITPIX", "16", " ", NULL); + qfits_header_add (qh, "NAXIS", "2", " ", NULL); + sprintf (val, "%i", img.nx); + qfits_header_add (qh, "NAXIS1", val, " ", NULL); + sprintf (val, "%i", img.ny); + qfits_header_add (qh, "NAXIS2", val, " ", NULL); + qfits_header_add (qh, "BSCALE", "1.0", " ", NULL); + qfits_header_add (qh, "BZERO", "0.0", " ", NULL); + qfits_header_add (qh, "DATAMAX", "255.0", " ", NULL); + qfits_header_add (qh, "DATAMIN", "0.0", " ", NULL); // Astrometry keywors - sprintf(val,"%f",img.nx/2.0); - qfits_header_add(qh,"CRPIX1",val," ",NULL); - sprintf(val,"%f",img.ny/2.0); - qfits_header_add(qh,"CRPIX2",val," ",NULL); - qfits_header_add(qh,"CRVAL1","0.0"," ",NULL); - qfits_header_add(qh,"CRVAL2","0.0"," ",NULL); - qfits_header_add(qh,"CD1_1","0.0"," ",NULL); - qfits_header_add(qh,"CD1_2","0.0"," ",NULL); - qfits_header_add(qh,"CD2_1","0.0"," ",NULL); - qfits_header_add(qh,"CD2_2","0.0"," ",NULL); - qfits_header_add(qh,"CTYPE1","'RA---TAN'"," ",NULL); - qfits_header_add(qh,"CTYPE2","'DEC--TAN'"," ",NULL); - qfits_header_add(qh,"CUNIT1","'deg'"," ",NULL); - qfits_header_add(qh,"CUNIT2","'deg'"," ",NULL); - qfits_header_add(qh,"CRRES1","0.0"," ",NULL); - qfits_header_add(qh,"CRRES2","0.0"," ",NULL); - qfits_header_add(qh,"EQUINOX","2000.0"," ",NULL); - qfits_header_add(qh,"RADECSYS","ICRS"," ",NULL); - sprintf(val,"%s",img.nfd); - qfits_header_add(qh,"DATE-OBS",val," ",NULL); - sprintf(val,"%lf",img.mjd); - qfits_header_add(qh,"MJD-OBS",val," ",NULL); - sprintf(val,"%d",img.cospar); - qfits_header_add(qh,"COSPAR",val," ",NULL); - sprintf(val,"%f",img.exptime); - qfits_header_add(qh,"EXPTIME",val," ",NULL); - sprintf(val,"%s",img.observer); - qfits_header_add(qh,"OBSERVER",val," ",NULL); - sprintf(val,"%d",img.tracked); - qfits_header_add(qh,"TRACKED",val," ",NULL); - + sprintf (val, "%f", img.nx / 2.0); + qfits_header_add (qh, "CRPIX1", val, " ", NULL); + sprintf (val, "%f", img.ny / 2.0); + qfits_header_add (qh, "CRPIX2", val, " ", NULL); + qfits_header_add (qh, "CRVAL1", "0.0", " ", NULL); + qfits_header_add (qh, "CRVAL2", "0.0", " ", NULL); + qfits_header_add (qh, "CD1_1", "0.0", " ", NULL); + qfits_header_add (qh, "CD1_2", "0.0", " ", NULL); + qfits_header_add (qh, "CD2_1", "0.0", " ", NULL); + qfits_header_add (qh, "CD2_2", "0.0", " ", NULL); + qfits_header_add (qh, "CTYPE1", "'RA---TAN'", " ", NULL); + qfits_header_add (qh, "CTYPE2", "'DEC--TAN'", " ", NULL); + qfits_header_add (qh, "CUNIT1", "'deg'", " ", NULL); + qfits_header_add (qh, "CUNIT2", "'deg'", " ", NULL); + qfits_header_add (qh, "CRRES1", "0.0", " ", NULL); + qfits_header_add (qh, "CRRES2", "0.0", " ", NULL); + qfits_header_add (qh, "EQUINOX", "2000.0", " ", NULL); + qfits_header_add (qh, "RADECSYS", "ICRS", " ", NULL); + sprintf (val, "%s", img.nfd); + qfits_header_add (qh, "DATE-OBS", val, " ", NULL); + sprintf (val, "%lf", img.mjd); + qfits_header_add (qh, "MJD-OBS", val, " ", NULL); + sprintf (val, "%d", img.cospar); + qfits_header_add (qh, "COSPAR", val, " ", NULL); + sprintf (val, "%f", img.exptime); + qfits_header_add (qh, "EXPTIME", val, " ", NULL); + sprintf (val, "%s", img.observer); + qfits_header_add (qh, "OBSERVER", val, " ", NULL); + sprintf (val, "%d", img.tracked); + qfits_header_add (qh, "TRACKED", val, " ", NULL); + // Dump fitsheader // qfits_header_dump(qh,stdout); - + // Dump to file - file=fopen(filename,"w"); - qfits_header_dump(qh,file); - fclose(file); + file = fopen (filename, "w"); + qfits_header_dump (qh, file); + fclose (file); // Fill buffer - ibuf=malloc(img.nx*img.ny*sizeof(int)); - for (i=0,l=0;i=0;j--) { - ibuf[l]=(int) img.z[l]; - - l++; + ibuf = malloc (img.nx * img.ny * sizeof (int)); + for (i = 0, l = 0; i < img.nx; i++) + { + for (j = img.ny - 1; j >= 0; j--) + { + ibuf[l] = (int) img.z[l]; + + l++; + } } - } // Set parameters - qd.filename=filename; - qd.npix=img.nx*img.ny; - qd.ptype=PTYPE_INT; - qd.ibuf=ibuf; - qd.out_ptype=BPP_16_SIGNED; + qd.filename = filename; + qd.npix = img.nx * img.ny; + qd.ptype = PTYPE_INT; + qd.ibuf = ibuf; + qd.out_ptype = BPP_16_SIGNED; // Dump - qfits_pixdump(&qd); + qfits_pixdump (&qd); - free(ibuf); + free (ibuf); return; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min; + int year, month, day, hour, min; float sec; - double mjd,dday; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%f",&year,&month,&day,&hour,&min,&sec); + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%f", &year, &month, &day, &hour, + &min, &sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; - mjd=date2mjd(year,month,dday); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; + mjd = date2mjd (year, month, dday); return mjd; } // Compute Date from Julian Day -void mjd2nfd(double mjd,char *nfd) +void +mjd2nfd (double mjd, char *nfd) { - double f,jd,dday; - int z,alpha,a,b,c,d,e; - int year,month,day,hour,min; - float sec,x; + double f, jd, dday; + int z, alpha, a, b, c, d, e; + int year, month, day, hour, min; + float sec, x; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - dday=b-d-floor(30.6001*e)+f; - if (e<14) - month=e-1; + if (z < 2299161) + a = z; else - month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (month>2) - year=c-4716; + dday = b - d - floor (30.6001 * e) + f; + if (e < 14) + month = e - 1; else - year=c-4715; + month = e - 13; - day=(int) floor(dday); - x=24.0*(dday-day); - x=3600.*fabs(x); - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - hour=x; - sec=floor(1000.0*sec)/1000.0; + if (month > 2) + year = c - 4716; + else + year = c - 4715; - sprintf(nfd,"%04d-%02d-%02dT%02d:%02d:%06.3f",year,month,day,hour,min,sec); + day = (int) floor (dday); + x = 24.0 * (dday - day); + x = 3600. * fabs (x); + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + hour = x; + sec = floor (1000.0 * sec) / 1000.0; + + sprintf (nfd, "%04d-%02d-%02dT%02d:%02d:%06.3f", year, month, day, hour, + min, sec); return; } diff --git a/src/jpgstack.c b/src/jpgstack.c index f0dbb67..0b89fa5 100644 --- a/src/jpgstack.c +++ b/src/jpgstack.c @@ -6,175 +6,198 @@ #define NMAX 1024 -struct image { - int nx,ny,nz; +struct image +{ + int nx, ny, nz; float *z; }; -struct image read_jpg(char *filename); -void write_jpg(char *filename,struct image img); +struct image read_jpg (char *filename); +void write_jpg (char *filename, struct image img); -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int i,j,flag,n; - struct image avg,max,raw; - - for (flag=0,i=1,n=0;i max.z[j]) + max.z[j] = raw.z[j]; + + // Free + free (raw.z); } - - // Add values - for (j=0;jmax.z[j]) - max.z[j]=raw.z[j]; - - // Free - free(raw.z); - } // Average; - for (j=0;j2) - *year=c-4716; + *day = b - d - floor (30.6001 * e) + f; + if (e < 14) + *month = e - 1; else - *year=c-4715; + *month = e - 13; + + if (*month > 2) + *year = c - 4716; + else + *year = c - 4715; return; } // MJD to DOY -double mjd2doy(double mjd,int *yr) +double +mjd2doy (double mjd, int *yr) { - int year,month,k=2; - double day,doy; - - mjd2date(mjd,&year,&month,&day); + int year, month, k = 2; + double day, doy; - if (year%4==0 && year%400!=0) - k=1; + mjd2date (mjd, &year, &month, &day); - doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - *yr=year; + doy = + floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30; + + *yr = year; return doy; } // Format TLE -void format_tle(orbit_t orb,char *line1,char *line2) +void +format_tle (orbit_t orb, char *line1, char *line2) { - int i,csum; - char sbstar[]=" 00000-0",bstar[13]; + int i, csum; + char sbstar[] = " 00000-0", bstar[13]; // Format Bstar term - if (fabs(orb.bstar)>1e-9) { - sprintf(bstar,"%11.4e",10*orb.bstar); - sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4]; - sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0'; - } + if (fabs (orb.bstar) > 1e-9) + { + sprintf (bstar, "%11.4e", 10 * orb.bstar); + sbstar[0] = bstar[0]; + sbstar[1] = bstar[1]; + sbstar[2] = bstar[3]; + sbstar[3] = bstar[4]; + sbstar[4] = bstar[5]; + sbstar[5] = bstar[6]; + sbstar[6] = bstar[8]; + sbstar[7] = bstar[10]; + sbstar[8] = '\0'; + } // Print lines - sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar); - sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev); + sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0", + orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar); + sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0", + orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc, + DEG (orb.argp), DEG (orb.mnan), orb.rev); // Compute checksums - for (i=0,csum=0;i0) { - sscanf(line,"%f %f",&x,&y); + cpgsci (7); + while (fgetline (file, line, LIM) > 0) + { + sscanf (line, "%f %f", &x, &y); - cpgpt1(x,y,19); + cpgpt1 (x, y, 19); + + } + fclose (file); + cpgsci (1); - } - fclose(file); - cpgsci(1); - return; } -void log_defects(float x,float y) +void +log_defects (float x, float y) { FILE *file; - char *env,filename[128]; - + char *env, filename[128]; + // Environment variables - env=getenv("ST_DATADIR"); - sprintf(filename,"%s/data/defects.txt",env); + env = getenv ("ST_DATADIR"); + sprintf (filename, "%s/data/defects.txt", env); - file=fopen(filename,"a"); - if (file==NULL) { - fprintf(stderr,"Defects file not found!\n"); - return; - } + file = fopen (filename, "a"); + if (file == NULL) + { + fprintf (stderr, "Defects file not found!\n"); + return; + } + + fprintf (file, "%4.0f %4.0f\n", x, y); + fclose (file); - fprintf(file,"%4.0f %4.0f\n",x,y); - fclose(file); - return; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } -void plot_objects(char *filename) +void +plot_objects (char *filename) { int i; FILE *file; - float x0,y0,x1,y1,texp; + float x0, y0, x1, y1, texp; int id; - char line[LIM],catalog[128],dummy[128],text[8]; + char line[LIM], catalog[128], dummy[128], text[8]; - file=fopen(filename,"r"); - if (file==NULL) + file = fopen (filename, "r"); + if (file == NULL) return; - while (fgetline(file,line,LIM)>0) { - sscanf(line,"%s %f %f %f %f %f %d %s",dummy,&x0,&y0,&x1,&y1,&texp,&id,catalog); + while (fgetline (file, line, LIM) > 0) + { + sscanf (line, "%s %f %f %f %f %f %d %s", dummy, &x0, &y0, &x1, &y1, + &texp, &id, catalog); - cpgsci(0); - if (strstr(catalog,"classfd")!=NULL) - cpgsci(4); - if (strstr(catalog,"inttles")!=NULL) - cpgsci(3); - if (strstr(catalog,"jsc")!=NULL) - cpgsci(5); + cpgsci (0); + if (strstr (catalog, "classfd") != NULL) + cpgsci (4); + if (strstr (catalog, "inttles") != NULL) + cpgsci (3); + if (strstr (catalog, "jsc") != NULL) + cpgsci (5); - cpgmove(x0,y0); - cpgdraw(x1,y1); - cpgpt1(x0,y0,4); - sprintf(text," %05d",id); - cpgtext(x0,y0,text); - } - fclose(file); - cpgsci(1); + cpgmove (x0, y0); + cpgdraw (x1, y1); + cpgpt1 (x0, y0, 4); + sprintf (text, " %05d", id); + cpgtext (x0, y0, text); + } + fclose (file); + cpgsci (1); return; } // Compute Date from Julian Day -void mjd2date(double mjd,char *date) +void +mjd2date (double mjd, char *date) { - double f,jd,dday; - int z,alpha,a,b,c,d,e; - double year,month,day,hour,min; - double sec,x,fsec; + double f, jd, dday; + int z, alpha, a, b, c, d, e; + double year, month, day, hour, min; + double sec, x, fsec; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - dday=b-d-floor(30.6001*e)+f; - if (e<14) - month=e-1; + if (z < 2299161) + a = z; else - month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (month>2) - year=c-4716; + dday = b - d - floor (30.6001 * e) + f; + if (e < 14) + month = e - 1; else - year=c-4715; + month = e - 13; - day=(int) floor(dday); - x=24.0*(dday-day); - x=3600.*fabs(x); - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - hour=x; - fsec=floor(1000.0*(sec-floor(sec))); - sprintf(date,"%04d%02d%02d%02d%02d%02.0f%03.0f",(int) year,(int) month,(int) day,(int) hour,(int) min,floor(sec),fsec); + if (month > 2) + year = c - 4716; + else + year = c - 4715; + + day = (int) floor (dday); + x = 24.0 * (dday - day); + x = 3600. * fabs (x); + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + hour = x; + fsec = floor (1000.0 * (sec - floor (sec))); + sprintf (date, "%04d%02d%02d%02d%02d%02.0f%03.0f", (int) year, (int) month, + (int) day, (int) hour, (int) min, floor (sec), fsec); return; } // Convert Decimal into Sexagesimal -void dec2s(double x,char *s,int type) +void +dec2s (double x, char *s, int type) { int i; - double sec,deg,min,fmin; + double sec, deg, min, fmin; char sign; - sign=(x<0 ? '-' : '+'); - x=60.*fabs(x); + sign = (x < 0 ? '-' : '+'); + x = 60. * fabs (x); - min=fmod(x,60.); - x=(x-min)/60.; + min = fmod (x, 60.); + x = (x - min) / 60.; // deg=fmod(x,60.); - deg=x; - if (type==0) - fmin=floor(1000.0*(min-floor(min))); + deg = x; + if (type == 0) + fmin = floor (1000.0 * (min - floor (min))); else - fmin=floor(100.0*(min-floor(min))); + fmin = floor (100.0 * (min - floor (min))); - if (type==0) - sprintf(s,"%02.0f%02.0f%03.0f",deg,floor(min),fmin); + if (type == 0) + sprintf (s, "%02.0f%02.0f%03.0f", deg, floor (min), fmin); else - sprintf(s,"%c%02.0f%02.0f%02.0f",sign,deg,floor(min),fmin); + sprintf (s, "%c%02.0f%02.0f%02.0f", sign, deg, floor (min), fmin); return; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // MJD to DOY -double mjd2doy(double mjd,int *yr) +double +mjd2doy (double mjd, int *yr) { - int year,month,k=2; + int year, month, k = 2; int day; double doy; char nfd[32]; - - mjd2date(mjd,nfd); - sscanf(nfd,"%04d",&year); - sscanf(nfd+4,"%02d",&month); - sscanf(nfd+6,"%02d",&day); + mjd2date (mjd, nfd); - if (year%4==0 && year%400!=0) - k=1; + sscanf (nfd, "%04d", &year); + sscanf (nfd + 4, "%02d", &month); + sscanf (nfd + 6, "%02d", &day); - doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - *yr=year; + doy = + floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30; + + *yr = year; return doy; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min; - double mjd,dday; + int year, month, day, hour, min; + double mjd, dday; float sec; - sscanf(date,"'%04d-%02d-%02dT%02d:%02d:%f'",&year,&month,&day,&hour,&min,&sec); + sscanf (date, "'%04d-%02d-%02dT%02d:%02d:%f'", &year, &month, &day, &hour, + &min, &sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; - mjd=date2mjd(year,month,dday); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; + mjd = date2mjd (year, month, dday); return mjd; } -void format_iod_line(struct observation *obs) +void +format_iod_line (struct observation *obs) { - int mt,xt,mp,xp; + int mt, xt, mp, xp; char string[10]; - + // Time format - sprintf(string,"%7.1e",obs->terr); - mt=string[0]-'0'; - xt=atoi(string+4)+8; + sprintf (string, "%7.1e", obs->terr); + mt = string[0] - '0'; + xt = atoi (string + 4) + 8; // Position format - if (obs->type==2) { - sprintf(string,"%7.1e",obs->perr); - mp=string[0]-'0'; - xp=atoi(string+4)+8; - } else { - printf("Position format not implemented!\n"); - } + if (obs->type == 2) + { + sprintf (string, "%7.1e", obs->perr); + mp = string[0] - '0'; + xp = atoi (string + 4) + 8; + } + else + { + printf ("Position format not implemented!\n"); + } - sprintf(obs->iod_line,"%05d %c%c %-6s %04d %c %-17s %d%d %d%d %-14s %d%d %c", - obs->satno, - obs->desig[0],obs->desig[1], - obs->desig+2, - obs->cospar, - obs->conditions, - obs->nfd, - mt,xt, - obs->type,obs->epoch, - obs->pos, - mp,xp, - obs->behavior); + sprintf (obs->iod_line, + "%05d %c%c %-6s %04d %c %-17s %d%d %d%d %-14s %d%d %c", obs->satno, + obs->desig[0], obs->desig[1], obs->desig + 2, obs->cospar, + obs->conditions, obs->nfd, mt, xt, obs->type, obs->epoch, obs->pos, + mp, xp, obs->behavior); return; } -void find_designation(int satno0,char *desig0) +void +find_designation (int satno0, char *desig0) { FILE *file; int satno; char desig[16]; - char *env,filename[128]; + char *env, filename[128]; // Environment variables - env=getenv("ST_DATADIR"); - sprintf(filename,"%s/data/desig.txt",env); + env = getenv ("ST_DATADIR"); + sprintf (filename, "%s/data/desig.txt", env); - file=fopen(filename,"r"); - if (file==NULL) { - fprintf(stderr,"Designation file not found!\n"); - exit(0); - } - while (!feof(file)) { - fscanf(file,"%d %s",&satno,desig); - if (satno==satno0) { - strcpy(desig0,desig); - break; + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "Designation file not found!\n"); + exit (0); } - } - fclose(file); + while (!feof (file)) + { + fscanf (file, "%d %s", &satno, desig); + if (satno == satno0) + { + strcpy (desig0, desig); + break; + } + } + fclose (file); return; } -void write_observation(struct observation obs) +void +write_observation (struct observation obs) { FILE *file; - file=fopen("observations.txt","a"); - fprintf(file,"%s\n",obs.iod_line); - fclose(file); + file = fopen ("observations.txt", "a"); + fprintf (file, "%s\n", obs.iod_line); + fclose (file); - printf("Observation written\n"); + printf ("Observation written\n"); return; } -void aperture_photometry(struct image img,struct aperture ap) +void +aperture_photometry (struct image img, struct aperture ap) { - int i,j,k,n1,n2; - float s1,ss1,s2,ss2; - float dx,dy,x,y,r; - float f1,f2; + int i, j, k, n1, n2; + float s1, ss1, s2, ss2; + float dx, dy, x, y, r; + float f1, f2; double mjd; - - mjd=img.mjd+0.5*(double) img.exptime/86400.0; - s1=0.0; - ss1=0.0; - s2=0.0; - ss2=0.0; - n1=0; - n2=0; - - for (i=0;i=ap.r1 && r= ap.r1 && r < ap.r2) + { + s2 += img.z[k]; + ss2 += img.z[k] * img.z[k]; + n2++; + } + } } - } - f1=s1/(float) n1; - f2=s2/(float) n2; + f1 = s1 / (float) n1; + f2 = s2 / (float) n2; - printf("%lf %8.3f %8.3f %.0f %d %.0f %d %f\n",mjd,ap.x,ap.y,s1,n1,s2,n2,f1-f2); + printf ("%lf %8.3f %8.3f %.0f %d %.0f %d %f\n", mjd, ap.x, ap.y, s1, n1, s2, + n2, f1 - f2); return; } // Reduce point -void reduce_point(struct observation *obs,struct image img,float tmid,float x,float y) +void +reduce_point (struct observation *obs, struct image img, float tmid, float x, + float y) { - int iframe,k; - double ra,de,rx,ry; - float dx,dy,dt; - double mjd,mjd1,mjd2; - char nfd[32],sra[15],sde[15]; + int iframe, k; + double ra, de, rx, ry; + float dx, dy, dt; + double mjd, mjd1, mjd2; + char nfd[32], sra[15], sde[15]; // Transform position - dx=x-img.x0; - dy=y-img.y0; - rx=img.a[0]+img.a[1]*dx+img.a[2]*dy; - ry=img.b[0]+img.b[1]*dx+img.b[2]*dy; - reverse(img.ra0,img.de0,rx,ry,&ra,&de); + dx = x - img.x0; + dy = y - img.y0; + rx = img.a[0] + img.a[1] * dx + img.a[2] * dy; + ry = img.b[0] + img.b[1] * dx + img.b[2] * dy; + reverse (img.ra0, img.de0, rx, ry, &ra, &de); // Correct for stationary camera - if (img.tracked==0) { - mjd1=img.mjd+0.5*(double) img.exptime/86400.0; - mjd2=img.mjd+(double) tmid/86400.0; - ra+=gmst(mjd2)-gmst(mjd1); - } + if (img.tracked == 0) + { + mjd1 = img.mjd + 0.5 * (double) img.exptime / 86400.0; + mjd2 = img.mjd + (double) tmid / 86400.0; + ra += gmst (mjd2) - gmst (mjd1); + } - dec2s(ra/15.0,sra,0); - dec2s(de,sde,1); + dec2s (ra / 15.0, sra, 0); + dec2s (de, sde, 1); // Get time - mjd=img.mjd+(double) tmid/86400.0; - mjd2date(mjd,nfd); - + mjd = img.mjd + (double) tmid / 86400.0; + mjd2date (mjd, nfd); + // Copy - strcpy(obs->nfd,nfd); - sprintf(obs->pos,"%s%s",sra,sde); + strcpy (obs->nfd, nfd); + sprintf (obs->pos, "%s%s", sra, sde); return; } -struct image maximum_image(struct image *raw,int n) +struct image +maximum_image (struct image *raw, int n) { - int i,j,k,l; - float max,s1,s2; + int i, j, k, l; + float max, s1, s2; struct image img; - printf("%d\n",n); - img.naxis1=raw[0].naxis1; - img.naxis2=raw[0].naxis2; - img.z=(float *) malloc(sizeof(float) * img.naxis1*img.naxis2); - for (i=0;imax) - max=raw[j].z[i]; - img.z[i]=max; - } + printf ("%d\n", n); + img.naxis1 = raw[0].naxis1; + img.naxis2 = raw[0].naxis2; + img.z = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2); + for (i = 0; i < img.naxis1 * img.naxis2; i++) + { + for (j = 0, max = 0.0; j < n; j++) + if (raw[j].z[i] > max) + max = raw[j].z[i]; + img.z[i] = max; + } // Get levels - for (i=0,s1=0.0,s2=0.0;i0) { - if (i>=NMAX) - break; - if (strstr(line,"#")!=NULL) - continue; - sscanf(line,"%f %f %f",&c.x[i],&c.y[i],&c.mag[i]); - c.select[i]=0; - i++; - } - fclose(file); - c.n=i; + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "%s not found!\n", filename); + exit (0); + } + while (fgetline (file, line, LIM) > 0) + { + if (i >= NMAX) + break; + if (strstr (line, "#") != NULL) + continue; + sscanf (line, "%f %f %f", &c.x[i], &c.y[i], &c.mag[i]); + c.select[i] = 0; + i++; + } + fclose (file); + c.n = i; return c; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int i,iimg=0,nimg; - float xmin,xmax,ymin,ymax,zmin,zmax; - float tr[]={-0.5,1.0,0.0,-0.5,0.0,1.0}; - float heat_l[] = {0.0, 0.2, 0.4, 0.6, 1.0}; - float heat_r[] = {0.0, 0.5, 1.0, 1.0, 1.0}; - float heat_g[] = {0.0, 0.0, 0.5, 1.0, 1.0}; - float heat_b[] = {0.0, 0.0, 0.0, 0.3, 1.0}; - int redraw=1,plotobj=1,click=0,nselect=0,plotcat=0; - float x,y,width; - char c,pixcat[128],text[128]; - struct catalog cat,ast; - float sx,sy,q; - char *env,idfile[128]; - float r,rmin=1.0,rmax=10.0,mmin=1.0,mmax=8.0,mag=8.0; + int i, iimg = 0, nimg; + float xmin, xmax, ymin, ymax, zmin, zmax; + float tr[] = { -0.5, 1.0, 0.0, -0.5, 0.0, 1.0 }; + float heat_l[] = { 0.0, 0.2, 0.4, 0.6, 1.0 }; + float heat_r[] = { 0.0, 0.5, 1.0, 1.0, 1.0 }; + float heat_g[] = { 0.0, 0.0, 0.5, 1.0, 1.0 }; + float heat_b[] = { 0.0, 0.0, 0.0, 0.3, 1.0 }; + int redraw = 1, plotobj = 1, click = 0, nselect = 0, plotcat = 0; + float x, y, width; + char c, pixcat[128], text[128]; + struct catalog cat, ast; + float sx, sy, q; + char *env, idfile[128]; + float r, rmin = 1.0, rmax = 10.0, mmin = 1.0, mmax = 8.0, mag = 8.0; struct observation obs; - double mjd,doy; + double mjd, doy; int year; - float frac=0.5; - float fx=0.5,fy=0.5; - int ix=0,iy=0,istar; + float frac = 0.5; + float fx = 0.5, fy = 0.5; + int ix = 0, iy = 0, istar; struct image *img; struct aperture ap; - + // Environment variables - env=getenv("ST_DATADIR"); + env = getenv ("ST_DATADIR"); // Number of images - nimg=argc; - + nimg = argc; + // Allocate - img=(struct image *) malloc(sizeof(struct image)*nimg); + img = (struct image *) malloc (sizeof (struct image) * nimg); // Read image - for (i=0;iimg[0].naxis2) ? img[0].naxis1 : img[0].naxis2; - xmin=0.0; - xmax=img[0].naxis1; - ymin=0.0; - ymax=img[0].naxis2; + width = (img[0].naxis1 > img[0].naxis2) ? img[0].naxis1 : img[0].naxis2; + xmin = 0.0; + xmax = img[0].naxis1; + ymin = 0.0; + ymax = img[0].naxis2; // Default aperture - ap.x=0.0; - ap.y=0.0; - ap.r1=5.0; - ap.r2=10.0; - + ap.x = 0.0; + ap.y = 0.0; + ap.r1 = 5.0; + ap.r2 = 10.0; + // Forever loop - for (;;) { - if (redraw!=0) { - if (redraw==1) - cpgpage(); - cpgsci(1); - - cpgsvp(0.1,0.9,0.1,0.85); - cpgwnad(xmin,xmax,ymin,ymax); - cpglab("x (pix)","y (pix)"," "); - cpgsfs(2); - cpgctab (heat_l,heat_r,heat_g,heat_b,5,1.0,0.5); + for (;;) + { + if (redraw != 0) + { + if (redraw == 1) + cpgpage (); + cpgsci (1); - sprintf(text,"File %d: %s; UT Date: %.23s COSPAR ID: %04d",iimg+1,img[iimg].filename,img[iimg].nfd+1,img[iimg].cospar); - cpgmtxt("T",6.0,0.0,0.0,text); - sprintf(text,"R.A.: %10.5f (%4.1f'') Decl.: %10.5f (%4.1f'')",img[iimg].ra0,img[iimg].xrms,img[iimg].de0,img[iimg].yrms); - cpgmtxt("T",4.8,0.0,0.0,text); - sprintf(text,"FoV: %.2f\\(2218)x%.2f\\(2218) Scale: %.2f''x%.2f'' pix\\u-1\\d Fraction: %.1f",img[iimg].naxis1*sqrt(img[iimg].a[1]*img[iimg].a[1]+img[iimg].b[1]*img[iimg].b[1])/3600.0,img[iimg].naxis2*sqrt(img[iimg].a[2]*img[iimg].a[2]+img[iimg].b[2]*img[iimg].b[2])/3600.0,sqrt(img[iimg].a[1]*img[iimg].a[1]+img[iimg].b[1]*img[iimg].b[1]),sqrt(img[iimg].a[2]*img[iimg].a[2]+img[iimg].b[2]*img[iimg].b[2]),frac); - cpgmtxt("T",3.6,0.0,0.0,text); + cpgsvp (0.1, 0.9, 0.1, 0.85); + cpgwnad (xmin, xmax, ymin, ymax); + cpglab ("x (pix)", "y (pix)", " "); + cpgsfs (2); + cpgctab (heat_l, heat_r, heat_g, heat_b, 5, 1.0, 0.5); - zmin=img[iimg].zmin; - zmax=img[iimg].zmax; + sprintf (text, "File %d: %s; UT Date: %.23s COSPAR ID: %04d", + iimg + 1, img[iimg].filename, img[iimg].nfd + 1, + img[iimg].cospar); + cpgmtxt ("T", 6.0, 0.0, 0.0, text); + sprintf (text, "R.A.: %10.5f (%4.1f'') Decl.: %10.5f (%4.1f'')", + img[iimg].ra0, img[iimg].xrms, img[iimg].de0, + img[iimg].yrms); + cpgmtxt ("T", 4.8, 0.0, 0.0, text); + sprintf (text, + "FoV: %.2f\\(2218)x%.2f\\(2218) Scale: %.2f''x%.2f'' pix\\u-1\\d Fraction: %.1f", + img[iimg].naxis1 * sqrt (img[iimg].a[1] * img[iimg].a[1] + + img[iimg].b[1] * img[iimg].b[1]) / + 3600.0, + img[iimg].naxis2 * sqrt (img[iimg].a[2] * img[iimg].a[2] + + img[iimg].b[2] * img[iimg].b[2]) / + 3600.0, + sqrt (img[iimg].a[1] * img[iimg].a[1] + + img[iimg].b[1] * img[iimg].b[1]), + sqrt (img[iimg].a[2] * img[iimg].a[2] + + img[iimg].b[2] * img[iimg].b[2]), frac); + cpgmtxt ("T", 3.6, 0.0, 0.0, text); - cpgimag(img[iimg].z,img[iimg].naxis1,img[iimg].naxis2,1,img[iimg].naxis1,1,img[iimg].naxis2,zmin,zmax,tr); - cpgbox("BCTSNI",0.,0,"BCTSNI",0.,0); + zmin = img[iimg].zmin; + zmax = img[iimg].zmax; - // Plot fit - if (obs.state==1) { - cpgsci(4); - cpgpt1(obs.x[0],obs.y[0],4); - cpgmove(obs.x[1],obs.y[1]); - cpgdraw(obs.x[2],obs.y[2]); - cpgsci(1); - } else if (obs.state==2) { - cpgsci(4); - cpgpt1(obs.x[0],obs.y[0],4); - cpgsci(1); - } + cpgimag (img[iimg].z, img[iimg].naxis1, img[iimg].naxis2, 1, + img[iimg].naxis1, 1, img[iimg].naxis2, zmin, zmax, tr); + cpgbox ("BCTSNI", 0., 0, "BCTSNI", 0., 0); - if (plotobj==1) { - if (iimg 0.0 && ap.y > 0.0) + { + cpgsci (3); + cpgcirc (ap.x, ap.y, ap.r1); + cpgcirc (ap.x, ap.y, ap.r2); + cpgsci (1); + } + + plot_defects (); + + redraw = 0; } - } - format_iod_line(&obs); - cpgmtxt("T",1.0,0.5,0.5,obs.iod_line); + // Get cursor + cpgcurs (&x, &y, &c); - // Read pixel catalog - if (plotcat==1) { - if (iimg 0.49 && frac < 0.51) + frac = 1.0; + else if (frac > 0.51) + frac = 0.0; + else if (frac < 0.49) + frac = 0.5; + printf ("Fraction: %.1f\n", frac); + redraw = 1; } - } - // Plot aperture - if (ap.x>0.0 && ap.y>0.0) { - cpgsci(3); - cpgcirc(ap.x,ap.y,ap.r1); - cpgcirc(ap.x,ap.y,ap.r2); - cpgsci(1); - } + if (c == 'p' || c == 'X') + { + if (plotobj == 1) + plotobj = 0; + else + plotobj = 1; + redraw = 1; + } - plot_defects(); + // Mark bad pixel + if (c == 't') + { + log_defects (x, y); + redraw = 1; + } - redraw=0; + // Plot catalog + if (c == 'l') + { + if (plotcat == 1) + plotcat = 0; + else + plotcat = 1; + redraw = 1; + } + + // Get designation + if (c == 'd') + { + printf ("Provide satellite number: "); + scanf ("%d", &obs.satno); + find_designation (obs.satno, obs.desig); + redraw = 1; + continue; + } + + // Center + if (c == 'c') + { + xmin = x - fx * width; + xmax = x + fx * width; + ymin = y - fy * width; + ymax = y + fy * width; + redraw = 1; + continue; + } + + if (isdigit (c)) + { + width = 1000.0 / (c - '0'); + xmin = x - fx * width; + xmax = x + fx * width; + ymin = y - fy * width; + ymax = y + fy * width; + redraw = 1; + continue; + } + + // Cycle through images + if (c == ']' || c == 's') + { + iimg++; + if (iimg >= nimg - 1) + iimg = 0; + if (c == ']') + redraw = 2; + else + redraw = 1; + continue; + } + + // Cycle through images + if (c == '[' || c == 'a') + { + iimg--; + if (iimg < 0) + iimg = nimg - 2; + if (c == '[') + redraw = 2; + else + redraw = 1; + continue; + } + + // Maximum image + if (c == 'o') + { + iimg = nimg - 1; + redraw = 1; + continue; + } + + // Cycle through image + if (c == '\t') + { + printf ("%d %d\n", ix, iy); + + // Set area + width = 750; + x = width * (ix + 0.5); + y = width * (iy + 0.5); + xmin = x - 1.5 * fx * width; + xmax = x + 1.5 * fx * width; + ymin = y - 1.5 * fy * width; + ymax = y + 1.5 * fy * width; + + // Increment + ix++; + if (width * ix > img[iimg].naxis1) + { + ix = 0; + iy++; + } + if (width * iy > img[iimg].naxis2) + { + ix = 0; + iy = 0; + } + redraw = 1; + continue; + } + + + + // Zoom + if (c == 'z' || c == '+' || c == '=') + { + width /= 1.5; + xmin = x - fx * width; + xmax = x + fx * width; + ymin = y - fy * width; + ymax = y + fy * width; + redraw = 1; + continue; + } + + // Unzoom + if (c == 'x' || c == '-') + { + width *= 1.5; + xmin = x - fx * width; + xmax = x + fx * width; + ymin = y - fy * width; + ymax = y + fy * width; + redraw = 1; + continue; + } + + // Reset + if (c == 'r') + { + width = + (img[iimg].naxis1 > + img[iimg].naxis2) ? img[iimg].naxis1 : img[iimg].naxis2; + xmin = 0.0; + xmax = img[iimg].naxis1; + ymin = 0.0; + ymax = img[iimg].naxis2; + redraw = 1; + continue; + } + + // Reset + if (c == 'R') + { + width = + (img[iimg].naxis1 > + img[iimg].naxis2) ? img[iimg].naxis1 : img[iimg].naxis2; + xmin = 0.0; + xmax = img[iimg].naxis1; + ymin = 0.0; + ymax = img[iimg].naxis2; + iimg = 0; + + obs.satno = 99999; + strcpy (obs.desig, "99999U"); + obs.cospar = atoi (env); + obs.conditions = 'G'; + strcpy (obs.nfd, "YYYYMMDDHHMMSSsss"); + obs.terr = 0.2; + strcpy (obs.pos, "HHMMmmm+DDMMmm"); + strcpy (obs.iod_line, ""); + obs.perr = 0.1; + obs.epoch = 5; + obs.type = 2; + obs.behavior = 'S'; + obs.state = 0; + obs.cospar = img[0].cospar; + + // Get fake designation + mjd = nfd2mjd (img[0].nfd); + doy = mjd2doy (mjd, &year); + sprintf (obs.desig, "%02d%03.0lfA", year - 2000, doy + 500); + redraw = 1; + continue; + } + + // Write obs + if (c == 'w') + { + write_observation (obs); + continue; + } + + // Measure + if (c == 'm' || c == 'D') + { + // istar=select_nearest(cat,x,y); + // printf("%f %f -> %f %f %f\n",x,y,cat.x[istar],cat.y[istar],cat.mag[istar]); + reduce_point (&obs, img[iimg], frac * img[iimg].exptime, x, y); + obs.x[0] = x; + obs.y[0] = y; + obs.state = 2; + redraw = 1; + continue; + } + + // Aperture photometry + if (c == 'g') + { + ap.x = x; + ap.y = y; + aperture_photometry (img[iimg], ap); + redraw = 1; + continue; + } + + // Help + if (c == 'h') + { + printf ("q Quit\n"); + printf + ("e Change of exposure (0.0 = start, 0.5 = middle, 1.0 = end)\n"); + printf ("p (right) Plot objects\n"); + printf ("l Plot star catalog\n"); + printf ("d Set object NORAD designation\n"); + printf ("c Center on cursor\n"); + printf ("0-9 Set zoom level\n"); + printf ("s/] Cycle through images forward\n"); + printf ("a/[ Cycle through images backward\n"); + printf ("o Show maximum pixels of all images\n"); + printf ("TAB Cycle through frame at current zoom level\n"); + printf ("z/+ Zoom in on cursor\n"); + printf ("x/- Zoom out on cursor\n"); + printf ("r Reset zoom\n"); + printf ("R Reset setup\n"); + printf ("w Write IOD observation\n"); + printf ("m (mid) measure position\n"); + } } - // Get cursor - cpgcurs(&x,&y,&c); - - // Quit - if (c=='q') - break; + cpgend (); - // Change fraction - if (c=='e') { - if (frac>0.49 && frac<0.51) - frac=1.0; - else if (frac>0.51) - frac=0.0; - else if (frac<0.49) - frac=0.5; - printf("Fraction: %.1f\n",frac); - redraw=1; - } - - if (c=='p' || c=='X') { - if (plotobj==1) - plotobj=0; - else - plotobj=1; - redraw=1; - } - - // Mark bad pixel - if (c=='t') { - log_defects(x,y); - redraw=1; - } - - // Plot catalog - if (c=='l') { - if (plotcat==1) - plotcat=0; - else - plotcat=1; - redraw=1; - } - - // Get designation - if (c=='d') { - printf("Provide satellite number: "); - scanf("%d",&obs.satno); - find_designation(obs.satno,obs.desig); - redraw=1; - continue; - } - - // Center - if (c=='c') { - xmin=x-fx*width; - xmax=x+fx*width; - ymin=y-fy*width; - ymax=y+fy*width; - redraw=1; - continue; - } - - if (isdigit(c)) { - width=1000.0/(c-'0'); - xmin=x-fx*width; - xmax=x+fx*width; - ymin=y-fy*width; - ymax=y+fy*width; - redraw=1; - continue; - } - - // Cycle through images - if (c==']' || c=='s') { - iimg++; - if (iimg>=nimg-1) - iimg=0; - if (c==']') - redraw=2; - else - redraw=1; - continue; - } - - // Cycle through images - if (c=='[' || c=='a') { - iimg--; - if (iimg<0) - iimg=nimg-2; - if (c=='[') - redraw=2; - else - redraw=1; - continue; - } - - // Maximum image - if (c=='o') { - iimg=nimg-1; - redraw=1; - continue; - } - - // Cycle through image - if (c=='\t') { - printf("%d %d\n",ix,iy); - - // Set area - width=750; - x=width*(ix+0.5); - y=width*(iy+0.5); - xmin=x-1.5*fx*width; - xmax=x+1.5*fx*width; - ymin=y-1.5*fy*width; - ymax=y+1.5*fy*width; - - // Increment - ix++; - if (width*ix>img[iimg].naxis1) { - ix=0; - iy++; - } - if (width*iy>img[iimg].naxis2) { - ix=0; - iy=0; - } - redraw=1; - continue; - } - - - - // Zoom - if (c=='z' || c=='+' || c=='=') { - width/=1.5; - xmin=x-fx*width; - xmax=x+fx*width; - ymin=y-fy*width; - ymax=y+fy*width; - redraw=1; - continue; - } - - // Unzoom - if (c=='x' || c=='-') { - width*=1.5; - xmin=x-fx*width; - xmax=x+fx*width; - ymin=y-fy*width; - ymax=y+fy*width; - redraw=1; - continue; - } - - // Reset - if (c=='r') { - width=(img[iimg].naxis1>img[iimg].naxis2) ? img[iimg].naxis1 : img[iimg].naxis2; - xmin=0.0; - xmax=img[iimg].naxis1; - ymin=0.0; - ymax=img[iimg].naxis2; - redraw=1; - continue; - } - - // Reset - if (c=='R') { - width=(img[iimg].naxis1>img[iimg].naxis2) ? img[iimg].naxis1 : img[iimg].naxis2; - xmin=0.0; - xmax=img[iimg].naxis1; - ymin=0.0; - ymax=img[iimg].naxis2; - iimg=0; - - obs.satno=99999; - strcpy(obs.desig,"99999U"); - obs.cospar=atoi(env); - obs.conditions='G'; - strcpy(obs.nfd,"YYYYMMDDHHMMSSsss"); - obs.terr=0.2; - strcpy(obs.pos,"HHMMmmm+DDMMmm"); - strcpy(obs.iod_line,""); - obs.perr=0.1; - obs.epoch=5; - obs.type=2; - obs.behavior='S'; - obs.state=0; - obs.cospar=img[0].cospar; - - // Get fake designation - mjd=nfd2mjd(img[0].nfd); - doy=mjd2doy(mjd,&year); - sprintf(obs.desig,"%02d%03.0lfA",year-2000,doy+500); - redraw=1; - continue; - } - - // Write obs - if (c=='w') { - write_observation(obs); - continue; - } - - // Measure - if (c=='m' || c=='D') { - // istar=select_nearest(cat,x,y); - // printf("%f %f -> %f %f %f\n",x,y,cat.x[istar],cat.y[istar],cat.mag[istar]); - reduce_point(&obs,img[iimg],frac*img[iimg].exptime,x,y); - obs.x[0]=x; - obs.y[0]=y; - obs.state=2; - redraw=1; - continue; - } - - // Aperture photometry - if (c=='g') { - ap.x=x; - ap.y=y; - aperture_photometry(img[iimg],ap); - redraw=1; - continue; - } - - // Help - if (c=='h') { - printf("q Quit\n"); - printf("e Change of exposure (0.0 = start, 0.5 = middle, 1.0 = end)\n"); - printf("p (right) Plot objects\n"); - printf("l Plot star catalog\n"); - printf("d Set object NORAD designation\n"); - printf("c Center on cursor\n"); - printf("0-9 Set zoom level\n"); - printf("s/] Cycle through images forward\n"); - printf("a/[ Cycle through images backward\n"); - printf("o Show maximum pixels of all images\n"); - printf("TAB Cycle through frame at current zoom level\n"); - printf("z/+ Zoom in on cursor\n"); - printf("x/- Zoom out on cursor\n"); - printf("r Reset zoom\n"); - printf("R Reset setup\n"); - printf("w Write IOD observation\n"); - printf("m (mid) measure position\n"); - } - } - - cpgend(); - - free(img); + free (img); return 0; } // Read fits image -struct image read_fits(char *filename,int pnum) +struct image +read_fits (char *filename, int pnum) { - int i,j,k,l,m; + int i, j, k, l, m; qfitsloader ql; - char key[FITS_LINESZ+1] ; + char key[FITS_LINESZ + 1]; struct image img; - float s1,s2,avg,std; + float s1, s2, avg, std; // Set plane ql.xtnum = 0; @@ -970,82 +1079,85 @@ struct image read_fits(char *filename,int pnum) ql.ptype = PTYPE_FLOAT; // Set filename - ql.filename=filename; + ql.filename = filename; // Set filename - strcpy(img.filename,filename); + strcpy (img.filename, filename); // Image size - img.naxis1=atoi(qfits_query_hdr(filename,"NAXIS1")); - img.naxis2=atoi(qfits_query_hdr(filename,"NAXIS2")); + img.naxis1 = atoi (qfits_query_hdr (filename, "NAXIS1")); + img.naxis2 = atoi (qfits_query_hdr (filename, "NAXIS2")); // MJD - img.mjd=(double) atof(qfits_query_hdr(filename,"MJD-OBS")); - strcpy(img.nfd,qfits_query_hdr(filename,"DATE-OBS")); - img.exptime=atof(qfits_query_hdr(filename,"EXPTIME")); + img.mjd = (double) atof (qfits_query_hdr (filename, "MJD-OBS")); + strcpy (img.nfd, qfits_query_hdr (filename, "DATE-OBS")); + img.exptime = atof (qfits_query_hdr (filename, "EXPTIME")); // COSPAR ID - img.cospar=atoi(qfits_query_hdr(filename,"COSPAR")); + img.cospar = atoi (qfits_query_hdr (filename, "COSPAR")); // Tracked - if (qfits_query_hdr(filename,"TRACKED")!=NULL) - img.tracked=atoi(qfits_query_hdr(filename,"TRACKED")); + if (qfits_query_hdr (filename, "TRACKED") != NULL) + img.tracked = atoi (qfits_query_hdr (filename, "TRACKED")); else - img.tracked=0; - + img.tracked = 0; + // Transformation - img.ra0=atof(qfits_query_hdr(filename,"CRVAL1")); - img.de0=atof(qfits_query_hdr(filename,"CRVAL2")); - img.x0=atof(qfits_query_hdr(filename,"CRPIX1")); - img.y0=atof(qfits_query_hdr(filename,"CRPIX2")); - img.a[0]=0.0; - img.a[1]=3600.0*atof(qfits_query_hdr(filename,"CD1_1")); - img.a[2]=3600.0*atof(qfits_query_hdr(filename,"CD1_2")); - img.b[0]=0.0; - img.b[1]=3600.0*atof(qfits_query_hdr(filename,"CD2_1")); - img.b[2]=3600.0*atof(qfits_query_hdr(filename,"CD2_2")); - img.xrms=3600.0*atof(qfits_query_hdr(filename,"CRRES1")); - img.yrms=3600.0*atof(qfits_query_hdr(filename,"CRRES2")); + img.ra0 = atof (qfits_query_hdr (filename, "CRVAL1")); + img.de0 = atof (qfits_query_hdr (filename, "CRVAL2")); + img.x0 = atof (qfits_query_hdr (filename, "CRPIX1")); + img.y0 = atof (qfits_query_hdr (filename, "CRPIX2")); + img.a[0] = 0.0; + img.a[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_1")); + img.a[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_2")); + img.b[0] = 0.0; + img.b[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_1")); + img.b[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_2")); + img.xrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES1")); + img.yrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES2")); // Initialize load - if (qfitsloader_init(&ql) != 0) - printf("Error initializing data loading\n"); + if (qfitsloader_init (&ql) != 0) + printf ("Error initializing data loading\n"); // Test load - if (qfits_loadpix(&ql) != 0) - printf("Error loading actual data\n"); + if (qfits_loadpix (&ql) != 0) + printf ("Error loading actual data\n"); // Allocate image memory - img.z=(float *) malloc(sizeof(float) * img.naxis1*img.naxis2); + img.z = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2); // Fill z array - for (i=0,l=0,m=0;i 0 && (c=fgetc(file)) != EOF && c != '\n') + int c, i = 0; + + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; @@ -1055,19 +1167,21 @@ int fgetline(FILE *file,char *s,int lim) // Select nearest object -int select_nearest(struct catalog c,float x,float y) +int +select_nearest (struct catalog c, float x, float y) { - int i,imin; - float r,rmin; + int i, imin; + float r, rmin; - for (i=0;i 0 && (c=fgetc(file)) != EOF && c != '\n') + int c, i = 0; + + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; // if (c == '\n') // s[i++] = c; @@ -21,117 +22,138 @@ int fgetline(FILE *file,char *s,int lim) } // Format TLE -void format_tle(orbit_t orb,char *line1,char *line2) +void +format_tle (orbit_t orb, char *line1, char *line2) { - int i,csum; - char sbstar[]=" 00000-0",bstar[13]; + int i, csum; + char sbstar[] = " 00000-0", bstar[13]; // Format Bstar term - if (fabs(orb.bstar)>1e-9) { - sprintf(bstar,"%11.4e",10*orb.bstar); - sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4]; - sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0'; - } + if (fabs (orb.bstar) > 1e-9) + { + sprintf (bstar, "%11.4e", 10 * orb.bstar); + sbstar[0] = bstar[0]; + sbstar[1] = bstar[1]; + sbstar[2] = bstar[3]; + sbstar[3] = bstar[4]; + sbstar[4] = bstar[5]; + sbstar[5] = bstar[6]; + sbstar[6] = bstar[8]; + sbstar[7] = bstar[10]; + sbstar[8] = '\0'; + } // Print lines - sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar); - sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f%5ld",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev,orb.norb); + sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0", + orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar); + sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f%5ld", + orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc, + DEG (orb.argp), DEG (orb.mnan), orb.rev, orb.norb); // Compute checksums - for (i=0,csum=0;i #define LIM 128 -#define XKE 0.07436680 // Guassian Gravitational Constant +#define XKE 0.07436680 // Guassian Gravitational Constant #define XKMPER 6378.135 #define AE 1.0 #define XMNPDA 1440.0 @@ -19,442 +19,492 @@ extern double SGDP4_jd0; // Dot product -float dot(xyz_t a,xyz_t b) +float +dot (xyz_t a, xyz_t b) { - return a.x*b.x+a.y*b.y+a.z*b.z; + return a.x * b.x + a.y * b.y + a.z * b.z; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Magnitude -double magnitude(xyz_t a) +double +magnitude (xyz_t a) { - return sqrt(dot(a,a)); + return sqrt (dot (a, a)); } // Cross product -xyz_t cross(xyz_t a,xyz_t b) +xyz_t +cross (xyz_t a, xyz_t b) { xyz_t c; - c.x=a.y*b.z-a.z*b.y; - c.y=a.z*b.x-a.x*b.z; - c.z=a.x*b.y-a.y*b.x; + c.x = a.y * b.z - a.z * b.y; + c.y = a.z * b.x - a.x * b.z; + c.z = a.x * b.y - a.y * b.x; return c; } // Compute Date from Julian Day -void mjd2date(double mjd,int *year,int *month,double *day) +void +mjd2date (double mjd, int *year, int *month, double *day) { - double f,jd; - int z,alpha,a,b,c,d,e; + double f, jd; + int z, alpha, a, b, c, d, e; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - *day=b-d-floor(30.6001*e)+f; - if (e<14) - *month=e-1; + if (z < 2299161) + a = z; else - *month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (*month>2) - *year=c-4716; + *day = b - d - floor (30.6001 * e) + f; + if (e < 14) + *month = e - 1; else - *year=c-4715; + *month = e - 13; + + if (*month > 2) + *year = c - 4716; + else + *year = c - 4715; return; } // MJD to DOY -double mjd2doy(double mjd,int *yr) +double +mjd2doy (double mjd, int *yr) { - int year,month,k=2; - double day,doy; - - mjd2date(mjd,&year,&month,&day); + int year, month, k = 2; + double day, doy; - if (year%4==0 && year%400!=0) - k=1; + mjd2date (mjd, &year, &month, &day); - doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - *yr=year; + doy = + floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30; + + *yr = year; return doy; } // Clasical elements -orbit_t classel(int ep_year,double ep_day,xyz_t r,xyz_t v) +orbit_t +classel (int ep_year, double ep_day, xyz_t r, xyz_t v) { int i; - double rm,vm,vm2,rvm,mu=1.0;; - double chi,xp,yp,sx,cx,b,ee; - double a,ecc,incl,node,peri,mm,n; - xyz_t h,e,kk,nn; + double rm, vm, vm2, rvm, mu = 1.0;; + double chi, xp, yp, sx, cx, b, ee; + double a, ecc, incl, node, peri, mm, n; + xyz_t h, e, kk, nn; orbit_t orb; - r.x/=XKMPER; - r.y/=XKMPER; - r.z/=XKMPER; - v.x/=(XKE*XKMPER/AE*XMNPDA/86400.0); - v.y/=(XKE*XKMPER/AE*XMNPDA/86400.0); - v.z/=(XKE*XKMPER/AE*XMNPDA/86400.0); + r.x /= XKMPER; + r.y /= XKMPER; + r.z /= XKMPER; + v.x /= (XKE * XKMPER / AE * XMNPDA / 86400.0); + v.y /= (XKE * XKMPER / AE * XMNPDA / 86400.0); + v.z /= (XKE * XKMPER / AE * XMNPDA / 86400.0); - rm=magnitude(r); - vm2=dot(v,v); - rvm=dot(r,v); - h=cross(r,v); - chi=dot(h,h)/mu; + rm = magnitude (r); + vm2 = dot (v, v); + rvm = dot (r, v); + h = cross (r, v); + chi = dot (h, h) / mu; - e.x=(vm2/mu-1.0/rm)*r.x-rvm/mu*v.x; - e.y=(vm2/mu-1.0/rm)*r.y-rvm/mu*v.y; - e.z=(vm2/mu-1.0/rm)*r.z-rvm/mu*v.z; + e.x = (vm2 / mu - 1.0 / rm) * r.x - rvm / mu * v.x; + e.y = (vm2 / mu - 1.0 / rm) * r.y - rvm / mu * v.y; + e.z = (vm2 / mu - 1.0 / rm) * r.z - rvm / mu * v.z; - a=pow(2.0/rm-vm2/mu,-1); - ecc=magnitude(e); - incl=acos(h.z/magnitude(h))*R2D; - - kk.x=0.0; - kk.y=0.0; - kk.z=1.0; - nn=cross(kk,h); - if (nn.x==0.0 && nn.y==0.0) - nn.x=1.0; - node=atan2(nn.y,nn.x)*R2D; - if (node<0.0) - node+=360.0; + a = pow (2.0 / rm - vm2 / mu, -1); + ecc = magnitude (e); + incl = acos (h.z / magnitude (h)) * R2D; - peri=acos(dot(nn,e)/(magnitude(nn)*ecc))*R2D; - if (e.z<0.0) - peri=360.0-peri; - if (peri<0.0) - peri+=360.0; + kk.x = 0.0; + kk.y = 0.0; + kk.z = 1.0; + nn = cross (kk, h); + if (nn.x == 0.0 && nn.y == 0.0) + nn.x = 1.0; + node = atan2 (nn.y, nn.x) * R2D; + if (node < 0.0) + node += 360.0; + + peri = acos (dot (nn, e) / (magnitude (nn) * ecc)) * R2D; + if (e.z < 0.0) + peri = 360.0 - peri; + if (peri < 0.0) + peri += 360.0; // Elliptic motion - if (ecc<1.0) { - xp=(chi-rm)/ecc; - yp=rvm/ecc*sqrt(chi/mu); - b=a*sqrt(1.0-ecc*ecc); - cx=xp/a+ecc; - sx=yp/b; - ee=atan2(sx,cx); - n=XKE*sqrt(mu/(a*a*a)); - mm=(ee-ecc*sx)*R2D; - } - if (mm<0.0) - mm+=360.0; + if (ecc < 1.0) + { + xp = (chi - rm) / ecc; + yp = rvm / ecc * sqrt (chi / mu); + b = a * sqrt (1.0 - ecc * ecc); + cx = xp / a + ecc; + sx = yp / b; + ee = atan2 (sx, cx); + n = XKE * sqrt (mu / (a * a * a)); + mm = (ee - ecc * sx) * R2D; + } + if (mm < 0.0) + mm += 360.0; // Fill - orb.satno=0; - orb.eqinc=incl*D2R; - orb.ascn=node*D2R; - orb.argp=peri*D2R; - orb.mnan=mm*D2R; - orb.ecc=ecc; - orb.rev=XKE*pow(a,-3.0/2.0)*XMNPDA/(2.0*M_PI); - orb.bstar=0.0; - orb.ep_year=ep_year; - orb.ep_day=ep_day; - orb.norb=0; + orb.satno = 0; + orb.eqinc = incl * D2R; + orb.ascn = node * D2R; + orb.argp = peri * D2R; + orb.mnan = mm * D2R; + orb.ecc = ecc; + orb.rev = XKE * pow (a, -3.0 / 2.0) * XMNPDA / (2.0 * M_PI); + orb.bstar = 0.0; + orb.ep_year = ep_year; + orb.ep_day = ep_day; + orb.norb = 0; return orb; } -orbit_t rv2el(int satno,double mjd,xyz_t r0,xyz_t v0) +orbit_t +rv2el (int satno, double mjd, xyz_t r0, xyz_t v0) { - int i,imode; - orbit_t orb[5],orb1[5]; - xyz_t r,v; + int i, imode; + orbit_t orb[5], orb1[5]; + xyz_t r, v; kep_t kep; - char line1[70],line2[70]; + char line1[70], line2[70]; int ep_year; double ep_day; // Epoch - ep_day=mjd2doy(mjd,&ep_year); + ep_day = mjd2doy (mjd, &ep_year); // Initial guess - orb[0]=classel(ep_year,ep_day,r0,v0); - orb[0].satno=satno; - - for (i=0;i<4;i++) { - // Propagate - imode=init_sgdp4(&orb[i]); - imode=satpos_xyz(mjd+2400000.5,&r,&v); + orb[0] = classel (ep_year, ep_day, r0, v0); + orb[0].satno = satno; - // Compute initial orbital elements - orb1[i]=classel(ep_year,ep_day,r,v); + for (i = 0; i < 4; i++) + { + // Propagate + imode = init_sgdp4 (&orb[i]); + imode = satpos_xyz (mjd + 2400000.5, &r, &v); - // Adjust - orb[i+1].rev=orb[i].rev+orb[0].rev-orb1[i].rev; - orb[i+1].ascn=orb[i].ascn+orb[0].ascn-orb1[i].ascn; - orb[i+1].argp=orb[i].argp+orb[0].argp-orb1[i].argp; - orb[i+1].mnan=orb[i].mnan+orb[0].mnan-orb1[i].mnan; - orb[i+1].eqinc=orb[i].eqinc+orb[0].eqinc-orb1[i].eqinc; - orb[i+1].ecc=orb[i].ecc+orb[0].ecc-orb1[i].ecc; - orb[i+1].ep_year=orb[i].ep_year; - orb[i+1].ep_day=orb[i].ep_day; - orb[i+1].satno=orb[i].satno; - orb[i+1].norb=orb[i].norb; - orb[i+1].bstar=orb[i].bstar; + // Compute initial orbital elements + orb1[i] = classel (ep_year, ep_day, r, v); - // Keep in range - if (orb[i+1].ecc<0.0) - orb[i+1].ecc=0.0; - if (orb[i+1].eqinc<0.0) - orb[i+1].eqinc=0.0; - } + // Adjust + orb[i + 1].rev = orb[i].rev + orb[0].rev - orb1[i].rev; + orb[i + 1].ascn = orb[i].ascn + orb[0].ascn - orb1[i].ascn; + orb[i + 1].argp = orb[i].argp + orb[0].argp - orb1[i].argp; + orb[i + 1].mnan = orb[i].mnan + orb[0].mnan - orb1[i].mnan; + orb[i + 1].eqinc = orb[i].eqinc + orb[0].eqinc - orb1[i].eqinc; + orb[i + 1].ecc = orb[i].ecc + orb[0].ecc - orb1[i].ecc; + orb[i + 1].ep_year = orb[i].ep_year; + orb[i + 1].ep_day = orb[i].ep_day; + orb[i + 1].satno = orb[i].satno; + orb[i + 1].norb = orb[i].norb; + orb[i + 1].bstar = orb[i].bstar; - orb[i].mnan=modulo(orb[i].mnan,2.0*M_PI); - orb[i].ascn=modulo(orb[i].ascn,2.0*M_PI); - orb[i].argp=modulo(orb[i].argp,2.0*M_PI); + // Keep in range + if (orb[i + 1].ecc < 0.0) + orb[i + 1].ecc = 0.0; + if (orb[i + 1].eqinc < 0.0) + orb[i + 1].eqinc = 0.0; + } + + orb[i].mnan = modulo (orb[i].mnan, 2.0 * M_PI); + orb[i].ascn = modulo (orb[i].ascn, 2.0 * M_PI); + orb[i].argp = modulo (orb[i].argp, 2.0 * M_PI); return orb[i]; } // Format TLE -void format_tle(orbit_t orb,char *line1,char *line2) +void +format_tle (orbit_t orb, char *line1, char *line2) { - int i,csum; - char sbstar[]=" 00000-0",bstar[13]; + int i, csum; + char sbstar[] = " 00000-0", bstar[13]; // Format Bstar term - if (fabs(orb.bstar)>1e-9) { - sprintf(bstar,"%11.4e",10*orb.bstar); - sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4]; - sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0'; - } + if (fabs (orb.bstar) > 1e-9) + { + sprintf (bstar, "%11.4e", 10 * orb.bstar); + sbstar[0] = bstar[0]; + sbstar[1] = bstar[1]; + sbstar[2] = bstar[3]; + sbstar[3] = bstar[4]; + sbstar[4] = bstar[5]; + sbstar[5] = bstar[6]; + sbstar[6] = bstar[8]; + sbstar[7] = bstar[10]; + sbstar[8] = '\0'; + } // Print lines - sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar); - sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev); + sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0", + orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar); + sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0", + orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc, + DEG (orb.argp), DEG (orb.mnan), orb.rev); // Compute checksums - for (i=0,csum=0;itm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec); - + time (&rawtime); + ptm = gmtime (&rawtime); + + sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900, + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, + ptm->tm_sec); + return; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min,sec; - double mjd,dday; + int year, month, day, hour, min, sec; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; - mjd=date2mjd(year,month,dday); + mjd = date2mjd (year, month, dday); return mjd; } -void usage(void) +void +usage (void) { - printf("propagate c:i:t:m:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n"); + printf + ("propagate c:i:t:m:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n"); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int imode,satno=0,arg,usecatalog=0,satnomin,flag=0; + int imode, satno = 0, arg, usecatalog = 0, satnomin, flag = 0; FILE *file; orbit_t orb; - xyz_t r,v,n,m,nm,r0,v0,mr,mv; - char tlefile[LIM],catalog[LIM],nfd[32]; - char line1[80],line2[80],desig[20]; - double mjd,ra,de,dr,drmin,dmr,dmv; + xyz_t r, v, n, m, nm, r0, v0, mr, mv; + char tlefile[LIM], catalog[LIM], nfd[32]; + char line1[80], line2[80], desig[20]; + double mjd, ra, de, dr, drmin, dmr, dmv; char *env; - int at_epoch=0; + int at_epoch = 0; // Get environment variable - env=getenv("ST_TLEDIR"); - sprintf(tlefile,"%s/classfd.tle",env); + env = getenv ("ST_TLEDIR"); + sprintf (tlefile, "%s/classfd.tle", env); // Set date - nfd_now(nfd); - mjd=nfd2mjd(nfd); + nfd_now (nfd); + mjd = nfd2mjd (nfd); // Decode options - while ((arg=getopt(argc,argv,"C:c:i:t:m:he"))!=-1) { - switch (arg) { + while ((arg = getopt (argc, argv, "C:c:i:t:m:he")) != -1) + { + switch (arg) + { - case 't': - strcpy(nfd,optarg); - mjd=nfd2mjd(nfd); - break; + case 't': + strcpy (nfd, optarg); + mjd = nfd2mjd (nfd); + break; - case 'm': - mjd=(double) atof(optarg); - break; - - case 'c': - strcpy(tlefile,optarg); - break; + case 'm': + mjd = (double) atof (optarg); + break; - case 'C': - strcpy(catalog,optarg); - usecatalog=1; - break; + case 'c': + strcpy (tlefile, optarg); + break; - case 'e': - at_epoch=1; - break; - - case 'i': - satno=atoi(optarg); - break; + case 'C': + strcpy (catalog, optarg); + usecatalog = 1; + break; - case 'h': - usage(); - return 0; - break; + case 'e': + at_epoch = 1; + break; - default: - usage(); - return 0; + case 'i': + satno = atoi (optarg); + break; + + case 'h': + usage (); + return 0; + break; + + default: + usage (); + return 0; + } } - } // Reloop stderr - freopen("/tmp/stderr.txt","w",stderr); + freopen ("/tmp/stderr.txt", "w", stderr); // Open file - file=fopen(tlefile,"r"); - while (read_twoline(file,satno,&orb)==0) { - format_tle(orb,line1,line2); - - // Propagate - imode=init_sgdp4(&orb); - if (at_epoch==1) - mjd=SGDP4_jd0-2400000.5; - imode=satpos_xyz(mjd+2400000.5,&r0,&v0); - - // Compute normal - n=cross(r0,v0); - ra=modulo(atan2(n.y,n.x)*R2D,360.0); - de=asin(n.z/magnitude(n))*R2D; - - if (usecatalog==0) - printf("%05d %14.8lf %10.6f %10.6f %10.2f %10.2f %10.2f %10.2f\n",orb.satno,mjd,ra,de,magnitude(n),n.x,n.y,n.z); - - } - fclose(file); - - // Match against a catalog - if (usecatalog==1) { - // Open file - file=fopen(catalog,"r"); - while (read_twoline(file,0,&orb)==0) { - format_tle(orb,line1,line2); + file = fopen (tlefile, "r"); + while (read_twoline (file, satno, &orb) == 0) + { + format_tle (orb, line1, line2); // Propagate - imode=init_sgdp4(&orb); - imode=satpos_xyz(mjd+2400000.5,&r,&v); - - + imode = init_sgdp4 (&orb); + if (at_epoch == 1) + mjd = SGDP4_jd0 - 2400000.5; + imode = satpos_xyz (mjd + 2400000.5, &r0, &v0); + // Compute normal - m=cross(r,v); + n = cross (r0, v0); + ra = modulo (atan2 (n.y, n.x) * R2D, 360.0); + de = asin (n.z / magnitude (n)) * R2D; - // Normal difference - nm.x=n.x-m.x; - nm.y=n.y-m.y; - nm.z=n.z-m.z; - dr=magnitude(nm); + if (usecatalog == 0) + printf ("%05d %14.8lf %10.6f %10.6f %10.2f %10.2f %10.2f %10.2f\n", + orb.satno, mjd, ra, de, magnitude (n), n.x, n.y, n.z); - // Position/velocity difference - mr.x=r0.x-r.x; - mr.y=r0.y-r.y; - mr.z=r0.z-r.z; - mv.x=v0.x-v.x; - mv.y=v0.y-v.y; - mv.z=v0.z-v.z; - - if (flag==0 || dr-psun && psat-pearthpsun) - strcpy(state,"sunlit"); - if (strcmp(state,"eclipsed")!=0) - sunlit=1; - else - sunlit=0; + // Distances + rsun = sqrt (dx * dx + dy * dy + dz * dz); + rearth = + sqrt (satpos.x * satpos.x + satpos.y * satpos.y + + satpos.z * satpos.z); + h = rearth - XKMPER; - // Position differences - dx=satpos.x-pt[i].obspos.x; - dy=satpos.y-pt[i].obspos.y; - dz=satpos.z-pt[i].obspos.z; - - // Celestial position - r=sqrt(dx*dx+dy*dy+dz*dz); - ra=modulo(atan2(dy,dx)*R2D,360.0); - de=asin(dz/r)*R2D; - - // Phase - phase=acos(((pt[i].obspos.x-satpos.x)*(pt[i].sunpos.x-satpos.x)+(pt[i].obspos.y-satpos.y)*(pt[i].sunpos.y-satpos.y)+(pt[i].obspos.z-satpos.z)*(pt[i].sunpos.z-satpos.z))/(rsun*r))*R2D; + // Angles + psun = asin (696.0e3 / rsun) * R2D; + pearth = asin (6378.135 / rearth) * R2D; + psat = + acos ((-dx * satpos.x - dy * satpos.y - + dz * satpos.z) / (rsun * rearth)) * R2D; - // Magnitude - if (strcmp(state,"sunlit")==0) - mag=STDMAG-15.0+5*log10(r)-2.5*log10(sin(phase*D2R)+(M_PI-phase*D2R)*cos(phase*D2R)); - else - mag=15; + // Visibility state + if (psat - pearth < -psun) + strcpy (state, "eclipsed"); + else if (psat - pearth > -psun && psat - pearth < psun) + strcpy (state, "umbra"); + else if (psat - pearth > psun) + strcpy (state, "sunlit"); + if (strcmp (state, "eclipsed") != 0) + sunlit = 1; + else + sunlit = 0; - // Horizontal position - equatorial2horizontal(pt[i].mjd,ra,de,&azi,&alt); - if (alt>0.0) - pt[i].alt=alt; - else - pt[i].alt=0.0; - pt[i].azi=modulo(azi+180.0,360.0); + // Position differences + dx = satpos.x - pt[i].obspos.x; + dy = satpos.y - pt[i].obspos.y; + dz = satpos.z - pt[i].obspos.z; - // Find all passes - if (m.all==1) { - if (i==0) { - if (alt>=m.altmin && flag==0) { - irise=i; - flag=1; - } - if (imax==-1 && flag==1) { - imax=i; - flag=2; + // Celestial position + r = sqrt (dx * dx + dy * dy + dz * dz); + ra = modulo (atan2 (dy, dx) * R2D, 360.0); + de = asin (dz / r) * R2D; + + // Phase + phase = + acos (((pt[i].obspos.x - satpos.x) * (pt[i].sunpos.x - satpos.x) + + (pt[i].obspos.y - satpos.y) * (pt[i].sunpos.y - satpos.y) + + (pt[i].obspos.z - satpos.z) * (pt[i].sunpos.z - + satpos.z)) / (rsun * r)) * R2D; + + // Magnitude + if (strcmp (state, "sunlit") == 0) + mag = + STDMAG - 15.0 + 5 * log10 (r) - 2.5 * log10 (sin (phase * D2R) + + (M_PI - + phase * D2R) * + cos (phase * D2R)); + else + mag = 15; + + // Horizontal position + equatorial2horizontal (pt[i].mjd, ra, de, &azi, &alt); + if (alt > 0.0) + pt[i].alt = alt; + else + pt[i].alt = 0.0; + pt[i].azi = modulo (azi + 180.0, 360.0); + + // Find all passes + if (m.all == 1) + { + if (i == 0) + { + if (alt >= m.altmin && flag == 0) + { + irise = i; + flag = 1; + } + if (imax == -1 && flag == 1) + { + imax = i; + flag = 2; + } + } + else if (i == m.length - 1) + { + if (alt >= m.altmin && flag == 0) + { + irise = i; + flag = 1; + } + if (imax == -1 && flag == 1) + { + imax = i; + flag = 2; + } + if (alt >= m.altmin && flag == 2) + { + iset = i; + flag = 3; + } + } + else if (i > 0) + { + if (alt1 < m.altmin && alt >= m.altmin && flag == 0) + { + irise = i; + flag = 1; + } + else if (alt1 > m.altmin && alt <= m.altmin && flag == 2) + { + iset = i; + flag = 3; + } + else if (flag == 1 && alt < alt1) + { + imax = i - 1; + flag = 2; + } + } } - } else if (i==m.length-1) { - if (alt>=m.altmin && flag==0) { - irise=i; - flag=1; - } - if (imax==-1 && flag==1) { - imax=i; - flag=2; + else + { + if (flag == 0 && alt >= m.altmin && sundown == 1 && sunlit == 1) + { + irise = i; + flag = 1; + } + else if (flag == 1 + && (alt < alt1 || !(sundown == 1 && sunlit == 1))) + { + imax = i - 1; + flag = 2; + } + else if (flag == 2 + && !(alt >= m.altmin && sundown == 1 && sunlit == 1)) + { + iset = i; + flag = 3; + } + /* + if (sundown==1 && sunlit==1) { + if (alt>=m.altmin && flag==0) { + irise=i; + flag=1; + } else if (alt<=m.altmin && flag==2) { + iset=i; + flag=3; + } else if (flag==1 && alt=m.altmin && flag==2) { - iset=i; - flag=3; + + if (flag == 3) + { + i1 = irise; + i2 = imax; + i3 = iset; + + p[ipass].satno = orb.satno; + p[ipass].mjdrise = pt[i1].mjd; + p[ipass].mjdmax = pt[i2].mjd; + p[ipass].mjdset = pt[i3].mjd; + p[ipass].length = 86400.0 * (pt[i3].mjd - pt[i1].mjd); + p[ipass].altmax = pt[i2].alt; + + sprintf (p[ipass].line, + "%05d | %s %3.0f/%2.0f | %.8s %3.0f/%2.0f | %.8s %3.0f/%2.0f | \n", + orb.satno, pt[i1].nfd, pt[i1].azi, pt[i1].alt, + pt[i2].nfd + 11, pt[i2].azi, pt[i2].alt, pt[i3].nfd + 11, + pt[i3].azi, pt[i3].alt); + sprintf (p[ipass].radio, "%05d %s %s %s %4.0f %5.1f\n", orb.satno, + pt[i1].nfd, pt[i2].nfd, pt[i3].nfd, p[ipass].length, + pt[i2].alt); + sprintf (p[ipass].skymap, "skymap -c %s -i %d -s %d -t %s -l %.0f", + m.tlefile, orb.satno, m.site_id, pt[i1].nfd, + p[ipass].length); + + flag = 0; + irise = -1; + imax = -1; + iset = -1; + ientry = -1; + iexit = -1; + ipass++; + npass++; } - } else if (i>0) { - if (alt1=m.altmin && flag==0) { - irise=i; - flag=1; - } else if (alt1>m.altmin && alt<=m.altmin && flag==2) { - iset=i; - flag=3; - } else if (flag==1 && alt=m.altmin && sundown==1 && sunlit==1) { - irise=i; - flag=1; - } else if (flag==1 && (alt=m.altmin && sundown==1 && sunlit==1)) { - iset=i; - flag=3; - } - /* - if (sundown==1 && sunlit==1) { - if (alt>=m.altmin && flag==0) { - irise=i; - flag=1; - } else if (alt<=m.altmin && flag==2) { - iset=i; - flag=3; - } else if (flag==1 && altmjdrisemjdrise) + if (pa->mjdrise < pb->mjdrise) return -1; - else if (pa->mjdrise>pb->mjdrise) + else if (pa->mjdrise > pb->mjdrise) return 1; else return 0; -} +} -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int arg=0,radio=0; + int arg = 0, radio = 0; FILE *file; orbit_t orb; - int imode,quiet=0; + int imode, quiet = 0; // Initialize setup - initialize_setup(); + initialize_setup (); // Decode options - while ((arg=getopt(argc,argv,"t:c:i:s:l:hS:A:aPqm:RM:"))!=-1) { - switch (arg) { + while ((arg = getopt (argc, argv, "t:c:i:s:l:hS:A:aPqm:RM:")) != -1) + { + switch (arg) + { - case 'R': - radio=1; - break; - - case 't': - strcpy(m.nfd,optarg); - m.mjd=nfd2mjd(m.nfd); - break; + case 'R': + radio = 1; + break; - case 'm': - m.mjd=atof(optarg); - mjd2date(m.mjd,m.nfd,0); - break; + case 't': + strcpy (m.nfd, optarg); + m.mjd = nfd2mjd (m.nfd); + break; - case 'c': - strcpy(m.tlefile,optarg); - break; + case 'm': + m.mjd = atof (optarg); + mjd2date (m.mjd, m.nfd, 0); + break; - case 's': - get_site(atoi(optarg)); - break; + case 'c': + strcpy (m.tlefile, optarg); + break; - case 'i': - m.satno=atoi(optarg); - break; + case 's': + get_site (atoi (optarg)); + break; - case 'l': - m.length=atoi(optarg); - if (strchr(optarg,'h')!=NULL) - m.length*=3600; - else if (strchr(optarg,'m')!=NULL) - m.length*=60; - else if (strchr(optarg,'d')!=NULL) - m.length*=86400; - break; + case 'i': + m.satno = atoi (optarg); + break; - case 'S': - m.saltmin=atof(optarg); - break; + case 'l': + m.length = atoi (optarg); + if (strchr (optarg, 'h') != NULL) + m.length *= 3600; + else if (strchr (optarg, 'm') != NULL) + m.length *= 60; + else if (strchr (optarg, 'd') != NULL) + m.length *= 86400; + break; - case 'A': - m.altmin=atof(optarg); - break; + case 'S': + m.saltmin = atof (optarg); + break; - case 'M': - m.altmax=atof(optarg); - break; - - case 'a': - m.all=1; - break; + case 'A': + m.altmin = atof (optarg); + break; - case 'h': - usage(); - return 0; - break; - - case 'P': - m.plot=1; - break; + case 'M': + m.altmax = atof (optarg); + break; - case 'q': - quiet=1; - break; + case 'a': + m.all = 1; + break; - default: - usage(); - return 0; + case 'h': + usage (); + return 0; + break; + + case 'P': + m.plot = 1; + break; + + case 'q': + quiet = 1; + break; + + default: + usage (); + return 0; + } } - } // Allocate - pt=(struct point *) malloc(sizeof(struct point)*m.length); + pt = (struct point *) malloc (sizeof (struct point) * m.length); // Compute observer positions - compute_observer_and_solar_positions(); + compute_observer_and_solar_positions (); // Reloop stderr - freopen("/tmp/stderr.txt","w",stderr); + freopen ("/tmp/stderr.txt", "w", stderr); // Open TLE file - file=fopen(m.tlefile,"r"); - if (file==NULL) - fatal_error("File open failed for reading %s\n",m.tlefile); + file = fopen (m.tlefile, "r"); + if (file == NULL) + fatal_error ("File open failed for reading %s\n", m.tlefile); // Loop over objects - while (read_twoline(file,m.satno,&orb)==0) { - Isat=orb.satno; - imode=init_sgdp4(&orb); + while (read_twoline (file, m.satno, &orb) == 0) + { + Isat = orb.satno; + imode = init_sgdp4 (&orb); - if (imode==SGDP4_ERROR) - continue; + if (imode == SGDP4_ERROR) + continue; + + // Skip non LEO objects + if (orb.rev >= 10.0 || m.satno != 0) + compute_track (orb); + } + npass = ipass; - // Skip non LEO objects - if (orb.rev>=10.0 || m.satno!=0) - compute_track(orb); - } - npass=ipass; - // Close - fclose(file); - fclose(stderr); + fclose (file); + fclose (stderr); // Sort passes - qsort(p,npass,sizeof(struct pass),qsort_compare_mjdrise); + qsort (p, npass, sizeof (struct pass), qsort_compare_mjdrise); // Output header - if (quiet==0) - print_header(); + if (quiet == 0) + print_header (); // Print passes - for (ipass=0;ipassm.altmax) - printf("%s",p[ipass].radio); - if (m.plot==1) - system(p[ipass].skymap); - } + for (ipass = 0; ipass < npass; ipass++) + { + if (radio == 0) + printf ("%s", p[ipass].line); + else if (radio == 1 && p[ipass].altmax > m.altmax) + printf ("%s", p[ipass].radio); + if (m.plot == 1) + system (p[ipass].skymap); + } // Free - free(pt); - + free (pt); + return 0; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min,sec; - double mjd,dday; + int year, month, day, hour, min, sec; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; - mjd=date2mjd(year,month,dday); + mjd = date2mjd (year, month, dday); return mjd; } -void usage() +void +usage () { - printf("pass t:c:i:s:l:hS:A:aPqm:R\n\n"); - printf("t date/time (yyyy-mm-ddThh:mm:ss.sss) [default: now]\n"); - printf("c TLE catalog file [default: classfd.tle]\n"); - printf("i satellite ID (NORAD) [default: all]\n"); - printf("s site (COSPAR\n"); - printf("l length [default: %d s]\n",m.length); - printf("A minimum satellite altitude [default: %.1f deg]\n",m.altmin); - printf("S maximum solar altitude [default: %.1f deg]\n",m.saltmin); - printf("a compute all passes [toggle; default: off]\n"); - printf("P plot passes [toggle; default: off]\n"); - printf("m MJD date/time\n"); - printf("q no header [toggle; default: off]\n"); - printf("R format output for radio passes [toggle; default: off]\n"); - printf("h this help\n"); - + printf ("pass t:c:i:s:l:hS:A:aPqm:R\n\n"); + printf ("t date/time (yyyy-mm-ddThh:mm:ss.sss) [default: now]\n"); + printf ("c TLE catalog file [default: classfd.tle]\n"); + printf ("i satellite ID (NORAD) [default: all]\n"); + printf ("s site (COSPAR\n"); + printf ("l length [default: %d s]\n", m.length); + printf ("A minimum satellite altitude [default: %.1f deg]\n", m.altmin); + printf ("S maximum solar altitude [default: %.1f deg]\n", m.saltmin); + printf ("a compute all passes [toggle; default: off]\n"); + printf ("P plot passes [toggle; default: off]\n"); + printf ("m MJD date/time\n"); + printf ("q no header [toggle; default: off]\n"); + printf ("R format output for radio passes [toggle; default: off]\n"); + printf ("h this help\n"); + return; } // Compute Date from Julian Day -void mjd2date(double mjd,char *date,int length) +void +mjd2date (double mjd, char *date, int length) { - double f,jd,dday; - int z,alpha,a,b,c,d,e; - int year,month,day,hour,min; - float sec,x; + double f, jd, dday; + int z, alpha, a, b, c, d, e; + int year, month, day, hour, min; + float sec, x; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - dday=b-d-floor(30.6001*e)+f; - if (e<14) - month=e-1; + if (z < 2299161) + a = z; else - month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (month>2) - year=c-4716; + dday = b - d - floor (30.6001 * e) + f; + if (e < 14) + month = e - 1; else - year=c-4715; + month = e - 13; - day=(int) floor(dday); - x=24.0*(dday-day); - x=3600.*fabs(x)+0.0001; - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - hour=x; - sec=floor(1000.0*sec)/1000.0; + if (month > 2) + year = c - 4716; + else + year = c - 4715; - if (length==3) - sprintf(date,"%04d-%02d-%02dT%02d:%02d:%06.3f",year,month,day,hour,min,sec); - else if (length==0) - sprintf(date,"%04d-%02d-%02dT%02d:%02d:%02.0f",year,month,day,hour,min,sec); + day = (int) floor (dday); + x = 24.0 * (dday - day); + x = 3600. * fabs (x) + 0.0001; + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + hour = x; + sec = floor (1000.0 * sec) / 1000.0; + + if (length == 3) + sprintf (date, "%04d-%02d-%02dT%02d:%02d:%06.3f", year, month, day, hour, + min, sec); + else if (length == 0) + sprintf (date, "%04d-%02d-%02dT%02d:%02d:%02.0f", year, month, day, hour, + min, sec); return; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // Initialize setup -void initialize_setup(void) +void +initialize_setup (void) { char *env; // Default parameters - m.satno=0; - m.timezone=0.0; - m.length=3600; - nfd_now(m.nfd); - m.mjd=nfd2mjd(m.nfd); - m.saltmin=-6.0; - m.altmin=10.0; - m.altmax=10.0; - m.all=0; - m.plot=0; + m.satno = 0; + m.timezone = 0.0; + m.length = 3600; + nfd_now (m.nfd); + m.mjd = nfd2mjd (m.nfd); + m.saltmin = -6.0; + m.altmin = 10.0; + m.altmax = 10.0; + m.all = 0; + m.plot = 0; // Default settings - strcpy(m.observer,"Unknown"); - m.site_id=0; + strcpy (m.observer, "Unknown"); + m.site_id = 0; // Get environment variables - env=getenv("ST_DATADIR"); - if (env!=NULL) { - strcpy(m.datadir,env); - } else { - printf("ST_DATADIR environment variable not found.\n"); - } - env=getenv("ST_COSPAR"); - if (env!=NULL) { - get_site(atoi(env)); - } else { - printf("ST_COSPAR environment variable not found.\n"); - } - env=getenv("ST_TLEDIR"); - if (env!=NULL) { - strcpy(m.tledir,env); - } else { - printf("ST_TLEDIR environment variable not found.\n"); - } - sprintf(m.tlefile,"%s/classfd.tle",m.tledir); + env = getenv ("ST_DATADIR"); + if (env != NULL) + { + strcpy (m.datadir, env); + } + else + { + printf ("ST_DATADIR environment variable not found.\n"); + } + env = getenv ("ST_COSPAR"); + if (env != NULL) + { + get_site (atoi (env)); + } + else + { + printf ("ST_COSPAR environment variable not found.\n"); + } + env = getenv ("ST_TLEDIR"); + if (env != NULL) + { + strcpy (m.tledir, env); + } + else + { + printf ("ST_TLEDIR environment variable not found.\n"); + } + sprintf (m.tlefile, "%s/classfd.tle", m.tledir); return; } // Get observing site -void get_site(int site_id) +void +get_site (int site_id) { - int i=0; + int i = 0; char line[LIM]; FILE *file; int id; - double lat,lng; + double lat, lng; float alt; - char abbrev[3],observer[64],filename[LIM]; + char abbrev[3], observer[64], filename[LIM]; - sprintf(filename,"%s/data/sites.txt",m.datadir); - file=fopen(filename,"r"); - if (file==NULL) { - printf("File with site information not found!\n"); - return; - } - while (fgets(line,LIM,file)!=NULL) { - // Skip - if (strstr(line,"#")!=NULL) - continue; - - // Strip newline - line[strlen(line)-1]='\0'; - - // Read data - sscanf(line,"%4d %2s %lf %lf %f", - &id,abbrev,&lat,&lng,&alt); - strcpy(observer,line+38); - - // Change to km - alt/=1000.0; - - if (id==site_id) { - m.lat=lat; - m.lng=lng; - m.alt=alt; - m.site_id=id; - strcpy(m.observer,observer); + sprintf (filename, "%s/data/sites.txt", m.datadir); + file = fopen (filename, "r"); + if (file == NULL) + { + printf ("File with site information not found!\n"); + return; } + while (fgets (line, LIM, file) != NULL) + { + // Skip + if (strstr (line, "#") != NULL) + continue; - } - fclose(file); + // Strip newline + line[strlen (line) - 1] = '\0'; + + // Read data + sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt); + strcpy (observer, line + 38); + + // Change to km + alt /= 1000.0; + + if (id == site_id) + { + m.lat = lat; + m.lng = lng; + m.alt = alt; + m.site_id = id; + strcpy (m.observer, observer); + } + + } + fclose (file); return; } // Present nfd -void nfd_now(char *s) +void +nfd_now (char *s) { time_t rawtime; struct tm *ptm; // Get UTC time - time(&rawtime); - ptm=gmtime(&rawtime); - - sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec); - + time (&rawtime); + ptm = gmtime (&rawtime); + + sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900, + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, + ptm->tm_sec); + return; } // Print header -void print_header(void) +void +print_header (void) { - printf("Observer: %s (%04d) [%+.4f, %+.4f, %.0fm]\n",m.observer,m.site_id,m.lat,m.lng,m.alt*1000.0); - printf("Elements: %s\n",m.tlefile); - printf("UT Date/Time: %s for %g h \n",m.nfd,m.length/3600.0); + printf ("Observer: %s (%04d) [%+.4f, %+.4f, %.0fm]\n", m.observer, + m.site_id, m.lat, m.lng, m.alt * 1000.0); + printf ("Elements: %s\n", m.tlefile); + printf ("UT Date/Time: %s for %g h \n", m.nfd, m.length / 3600.0); return; } // Observer position -void obspos_xyz(double mjd,xyz_t *pos,xyz_t *vel) +void +obspos_xyz (double mjd, xyz_t * pos, xyz_t * vel) { - double ff,gc,gs,theta,s,dtheta; + double ff, gc, gs, theta, s, dtheta; - s=sin(m.lat*D2R); - ff=sqrt(1.0-FLAT*(2.0-FLAT)*s*s); - gc=1.0/ff+m.alt/XKMPER; - gs=(1.0-FLAT)*(1.0-FLAT)/ff+m.alt/XKMPER; + s = sin (m.lat * D2R); + ff = sqrt (1.0 - FLAT * (2.0 - FLAT) * s * s); + gc = 1.0 / ff + m.alt / XKMPER; + gs = (1.0 - FLAT) * (1.0 - FLAT) / ff + m.alt / XKMPER; - theta=gmst(mjd)+m.lng; - dtheta=dgmst(mjd)*D2R/86400; + theta = gmst (mjd) + m.lng; + dtheta = dgmst (mjd) * D2R / 86400; - pos->x=gc*cos(m.lat*D2R)*cos(theta*D2R)*XKMPER; - pos->y=gc*cos(m.lat*D2R)*sin(theta*D2R)*XKMPER; - pos->z=gs*sin(m.lat*D2R)*XKMPER; - vel->x=-gc*cos(m.lat*D2R)*sin(theta*D2R)*XKMPER*dtheta; - vel->y=gc*cos(m.lat*D2R)*cos(theta*D2R)*XKMPER*dtheta; - vel->z=0.0; + pos->x = gc * cos (m.lat * D2R) * cos (theta * D2R) * XKMPER; + pos->y = gc * cos (m.lat * D2R) * sin (theta * D2R) * XKMPER; + pos->z = gs * sin (m.lat * D2R) * XKMPER; + vel->x = -gc * cos (m.lat * D2R) * sin (theta * D2R) * XKMPER * dtheta; + vel->y = gc * cos (m.lat * D2R) * cos (theta * D2R) * XKMPER * dtheta; + vel->z = 0.0; return; } // Solar position -void sunpos_xyz(double mjd,xyz_t *pos,double *ra,double *de) +void +sunpos_xyz (double mjd, xyz_t * pos, double *ra, double *de) { - double jd,t,l0,m,e,c,r; - double n,s,ecl; + double jd, t, l0, m, e, c, r; + double n, s, ecl; - jd=mjd+2400000.5; - t=(jd-2451545.0)/36525.0; - l0=modulo(280.46646+t*(36000.76983+t*0.0003032),360.0)*D2R; - m=modulo(357.52911+t*(35999.05029-t*0.0001537),360.0)*D2R; - e=0.016708634+t*(-0.000042037-t*0.0000001267); - c=(1.914602+t*(-0.004817-t*0.000014))*sin(m)*D2R; - c+=(0.019993-0.000101*t)*sin(2.0*m)*D2R; - c+=0.000289*sin(3.0*m)*D2R; + jd = mjd + 2400000.5; + t = (jd - 2451545.0) / 36525.0; + l0 = modulo (280.46646 + t * (36000.76983 + t * 0.0003032), 360.0) * D2R; + m = modulo (357.52911 + t * (35999.05029 - t * 0.0001537), 360.0) * D2R; + e = 0.016708634 + t * (-0.000042037 - t * 0.0000001267); + c = (1.914602 + t * (-0.004817 - t * 0.000014)) * sin (m) * D2R; + c += (0.019993 - 0.000101 * t) * sin (2.0 * m) * D2R; + c += 0.000289 * sin (3.0 * m) * D2R; - r=1.000001018*(1.0-e*e)/(1.0+e*cos(m+c)); - n=modulo(125.04-1934.136*t,360.0)*D2R; - s=l0+c+(-0.00569-0.00478*sin(n))*D2R; - ecl=(23.43929111+(-46.8150*t-0.00059*t*t+0.001813*t*t*t)/3600.0+0.00256*cos(n))*D2R; + r = 1.000001018 * (1.0 - e * e) / (1.0 + e * cos (m + c)); + n = modulo (125.04 - 1934.136 * t, 360.0) * D2R; + s = l0 + c + (-0.00569 - 0.00478 * sin (n)) * D2R; + ecl = + (23.43929111 + + (-46.8150 * t - 0.00059 * t * t + 0.001813 * t * t * t) / 3600.0 + + 0.00256 * cos (n)) * D2R; - *ra=atan2(cos(ecl)*sin(s),cos(s))*R2D; - *de=asin(sin(ecl)*sin(s))*R2D; + *ra = atan2 (cos (ecl) * sin (s), cos (s)) * R2D; + *de = asin (sin (ecl) * sin (s)) * R2D; - pos->x=r*cos(*de*D2R)*cos(*ra*D2R)*XKMPAU; - pos->y=r*cos(*de*D2R)*sin(*ra*D2R)*XKMPAU; - pos->z=r*sin(*de*D2R)*XKMPAU; + pos->x = r * cos (*de * D2R) * cos (*ra * D2R) * XKMPAU; + pos->y = r * cos (*de * D2R) * sin (*ra * D2R) * XKMPAU; + pos->z = r * sin (*de * D2R) * XKMPAU; return; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } // Greenwich Mean Sidereal Time -double dgmst(double mjd) +double +dgmst (double mjd) { - double t,dgmst; + double t, dgmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - dgmst=360.98564736629+t*(0.000387933-t/38710000); + dgmst = 360.98564736629 + t * (0.000387933 - t / 38710000); return dgmst; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Convert equatorial into horizontal coordinates -void equatorial2horizontal(double mjd,double ra,double de,double *azi,double *alt) +void +equatorial2horizontal (double mjd, double ra, double de, double *azi, + double *alt) { double h; - h=gmst(mjd)+m.lng-ra; - - *azi=modulo(atan2(sin(h*D2R),cos(h*D2R)*sin(m.lat*D2R)-tan(de*D2R)*cos(m.lat*D2R))*R2D,360.0); - *alt=asin(sin(m.lat*D2R)*sin(de*D2R)+cos(m.lat*D2R)*cos(de*D2R)*cos(h*D2R))*R2D; + h = gmst (mjd) + m.lng - ra; + + *azi = + modulo (atan2 + (sin (h * D2R), + cos (h * D2R) * sin (m.lat * D2R) - + tan (de * D2R) * cos (m.lat * D2R)) * R2D, 360.0); + *alt = + asin (sin (m.lat * D2R) * sin (de * D2R) + + cos (m.lat * D2R) * cos (de * D2R) * cos (h * D2R)) * R2D; return; } // Convert horizontal into equatorial coordinates -void horizontal2equatorial(double mjd,double azi,double alt,double *ra,double *de) +void +horizontal2equatorial (double mjd, double azi, double alt, double *ra, + double *de) { double h; - h=atan2(sin(azi*D2R),cos(azi*D2R)*sin(m.lat*D2R)+tan(alt*D2R)*cos(m.lat*D2R))*R2D; - *ra=modulo(gmst(mjd)+m.lng-h,360.0); - *de=asin(sin(m.lat*D2R)*sin(alt*D2R)-cos(m.lat*D2R)*cos(alt*D2R)*cos(azi*D2R))*R2D; - if (*ra<0.0) - *ra+=360.0; + h = + atan2 (sin (azi * D2R), + cos (azi * D2R) * sin (m.lat * D2R) + + tan (alt * D2R) * cos (m.lat * D2R)) * R2D; + *ra = modulo (gmst (mjd) + m.lng - h, 360.0); + *de = + asin (sin (m.lat * D2R) * sin (alt * D2R) - + cos (m.lat * D2R) * cos (alt * D2R) * cos (azi * D2R)) * R2D; + if (*ra < 0.0) + *ra += 360.0; return; } -void compute_observer_and_solar_positions(void) +void +compute_observer_and_solar_positions (void) { int i; xyz_t obsvel; - for (i=0;i -struct image { - int nx,ny; +struct image +{ + int nx, ny; char timestamp[64]; unsigned char *c; }; -struct fourframe { - int nx,ny,nt,nlayer; - char timestamp[64],observer[64]; - double mjd; - float *z,*dt; - int cospar,type; -}; -int fgetline(FILE *file,char *s,int lim); -void write_fits(char *filename,struct fourframe ff); -struct image read_pgm(char *filename,int *status); -double nfd2mjd(char *date); -double date2mjd(int year,int month,double day); -void write_pgm(char *filename,struct fourframe ff); -void mjd2date(double mjd,char *date); - -void usage(void) +struct fourframe { - printf("pgm2fits p:w:h:s:n:Dd:x:y:c:o:gm:t:r:I\n\n"); - printf("-p image prefix\n"); - printf("-w image width in pixels\n"); - printf("-h image height in pixels\n"); - printf("-s number of first image to process\n"); - printf("-n number of images to process\n"); - printf("-D toggle for creating dark frame\n"); - printf("-d toggle for creating dark frame\n"); - printf("-d filename of dark frame to substract\n"); - printf("-m filename of mask frame to apply\n"); - printf("-x tracking rate in x (pix/s)\n"); - printf("-y tracking rate in y (pix/s)\n"); - printf("-c COSPAR [default 4553]\n"); - printf("-o observer [default \"Cees Bassa\"]\n"); - printf("-g toggle for guiding??\n"); - printf("-t time stamp of first image [YYYY-MM-DDTHH:MM:SS.SSS]\n"); - printf("-r frame rate (frames/s)\n"); - printf("-I integer output\n"); - exit(0); + int nx, ny, nt, nlayer; + char timestamp[64], observer[64]; + double mjd; + float *z, *dt; + int cospar, type; +}; +int fgetline (FILE * file, char *s, int lim); +void write_fits (char *filename, struct fourframe ff); +struct image read_pgm (char *filename, int *status); +double nfd2mjd (char *date); +double date2mjd (int year, int month, double day); +void write_pgm (char *filename, struct fourframe ff); +void mjd2date (double mjd, char *date); + +void +usage (void) +{ + printf ("pgm2fits p:w:h:s:n:Dd:x:y:c:o:gm:t:r:I\n\n"); + printf ("-p image prefix\n"); + printf ("-w image width in pixels\n"); + printf ("-h image height in pixels\n"); + printf ("-s number of first image to process\n"); + printf ("-n number of images to process\n"); + printf ("-D toggle for creating dark frame\n"); + printf ("-d toggle for creating dark frame\n"); + printf ("-d filename of dark frame to substract\n"); + printf ("-m filename of mask frame to apply\n"); + printf ("-x tracking rate in x (pix/s)\n"); + printf ("-y tracking rate in y (pix/s)\n"); + printf ("-c COSPAR [default 4553]\n"); + printf ("-o observer [default \"Cees Bassa\"]\n"); + printf ("-g toggle for guiding??\n"); + printf ("-t time stamp of first image [YYYY-MM-DDTHH:MM:SS.SSS]\n"); + printf ("-r frame rate (frames/s)\n"); + printf ("-I integer output\n"); + exit (0); } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int i,j,k,l,m,k0=1,status,nt,darkout=0,darkin=0,track=0,maskin=0; - int n,n0,di,dj,npix; - struct image *img,drk,msk; + int i, j, k, l, m, k0 = 1, status, nt, darkout = 0, darkin = 0, track = + 0, maskin = 0; + int n, n0, di, dj, npix; + struct image *img, drk, msk; struct fourframe ff; - char filename[128],nfd[64]; - float s1,s2,z; - float avg,std,max,cnt,*trk; + char filename[128], nfd[64]; + float s1, s2, z; + float avg, std, max, cnt, *trk; int *wt; - int arg=0; - char *path,*darkfile,*maskfile; - double mjd,mjd0=0.0; - float dxdn=0.0,dydn=0.0,dx,dy; - int guide=0,timereset=0; - float framerate=25.0; + int arg = 0; + char *path, *darkfile, *maskfile; + double mjd, mjd0 = 0.0; + float dxdn = 0.0, dydn = 0.0, dx, dy; + int guide = 0, timereset = 0; + float framerate = 25.0; char *env; // Set defaults - env=getenv("ST_COSPAR"); - ff.cospar=atoi(env); - strcpy(ff.observer,"Cees Bassa"); - ff.type=0; - + env = getenv ("ST_COSPAR"); + ff.cospar = atoi (env); + strcpy (ff.observer, "Cees Bassa"); + ff.type = 0; + // Decode options - if (argc>1) { - while ((arg=getopt(argc,argv,"p:w:h:s:n:Dd:x:y:c:o:gm:t:r:I"))!=-1) { - switch(arg) { - case 'p': - path=optarg; - break; + if (argc > 1) + { + while ((arg = + getopt (argc, argv, "p:w:h:s:n:Dd:x:y:c:o:gm:t:r:I")) != -1) + { + switch (arg) + { + case 'p': + path = optarg; + break; - case 'g': - guide=1; - break; + case 'g': + guide = 1; + break; - case 'w': - ff.nx=atoi(optarg); - break; - - case 'h': - ff.ny=atoi(optarg); - break; + case 'w': + ff.nx = atoi (optarg); + break; - case 'I': - ff.type=1; - break; - - case 'c': - ff.cospar=atoi(optarg); - break; + case 'h': + ff.ny = atoi (optarg); + break; - case 'o': - strcpy(ff.observer,optarg); - break; + case 'I': + ff.type = 1; + break; - case 's': - k0=atoi(optarg); - break; - - case 'n': - nt=atoi(optarg); - break; + case 'c': + ff.cospar = atoi (optarg); + break; - case 'D': - darkout=1; - break; - - case 'd': - darkin=1; - darkfile=optarg; - break; + case 'o': + strcpy (ff.observer, optarg); + break; - case 'm': - maskin=1; - maskfile=optarg; - break; - - case 'x': - dxdn=atof(optarg); - track=1; - break; - - case 'y': - dydn=atof(optarg); - track=1; - break; + case 's': + k0 = atoi (optarg); + break; - case 't': - strcpy(nfd,optarg); - mjd0=nfd2mjd(nfd); - timereset=1; - break; + case 'n': + nt = atoi (optarg); + break; - case 'r': - framerate=atof(optarg); - timereset=1; - break; + case 'D': + darkout = 1; + break; - default: - usage(); - } + case 'd': + darkin = 1; + darkfile = optarg; + break; + + case 'm': + maskin = 1; + maskfile = optarg; + break; + + case 'x': + dxdn = atof (optarg); + track = 1; + break; + + case 'y': + dydn = atof (optarg); + track = 1; + break; + + case 't': + strcpy (nfd, optarg); + mjd0 = nfd2mjd (nfd); + timereset = 1; + break; + + case 'r': + framerate = atof (optarg); + timereset = 1; + break; + + default: + usage (); + } + } + } + else + { + usage (); } - } else { - usage(); - } // Add layer - if (track==1) - ff.nlayer=5; + if (track == 1) + ff.nlayer = 5; else - ff.nlayer=4; + ff.nlayer = 4; // Allocate - ff.z=(float *) malloc(ff.nlayer*sizeof(float)*ff.nx*ff.ny); - ff.dt=(float *) malloc(sizeof(float)*nt); - trk=(float *) malloc(sizeof(float)*ff.nx*ff.ny); - wt=(int *) malloc(sizeof(float)*ff.nx*ff.ny); - img=(struct image *) malloc(sizeof(struct image)*nt); + ff.z = (float *) malloc (ff.nlayer * sizeof (float) * ff.nx * ff.ny); + ff.dt = (float *) malloc (sizeof (float) * nt); + trk = (float *) malloc (sizeof (float) * ff.nx * ff.ny); + wt = (int *) malloc (sizeof (float) * ff.nx * ff.ny); + img = (struct image *) malloc (sizeof (struct image) * nt); // Read dark file - if (darkin==1) - drk=read_pgm(darkfile,&status); + if (darkin == 1) + drk = read_pgm (darkfile, &status); // Read mask file - if (maskin==1) - msk=read_pgm(maskfile,&status); + if (maskin == 1) + msk = read_pgm (maskfile, &status); // Loop over files - for (k=0,l=0;kmax) { - max=z; - cnt=(float) k; + // Reset time + if (timereset == 1) + { + mjd = mjd0 + (double) (k + k0) / (86400.0 * framerate); + mjd2date (mjd, img[l].timestamp); } - } - s1-=max; - s2-=max*max; - avg=s1/(float) (ff.nt-1); - std=sqrt((s2-s1*avg)/(float) (ff.nt-2)); - - // Reset masked pixels - if (maskin==1 && msk.c[n]==0.0) { - avg=0.0; - std=0.0; - max=0.0; - cnt=128.0; - } - for (m=0;m max) + { + max = z; + cnt = (float) k; + } + } + s1 -= max; + s2 -= max * max; + avg = s1 / (float) (ff.nt - 1); + std = sqrt ((s2 - s1 * avg) / (float) (ff.nt - 2)); + + // Reset masked pixels + if (maskin == 1 && msk.c[n] == 0.0) + { + avg = 0.0; + std = 0.0; + max = 0.0; + cnt = 128.0; + } + + for (m = 0; m < ff.nlayer; m++) + { + l = i + (ff.ny - j - 1) * ff.nx + m * ff.nx * ff.ny; + if (m == 0) + ff.z[l] = avg; + if (m == 1) + ff.z[l] = std; + if (m == 2) + ff.z[l] = max; + if (m == 3) + ff.z[l] = cnt; + if (m == 4) + ff.z[l] = avg; + } + } } - } // Create tracked layer - if (track==1) { - printf("Creating tracked layer\n"); + if (track == 1) + { + printf ("Creating tracked layer\n"); - // Set weights - for (i=0;i0 && i+di0 && j+dj 0 && i + di < ff.nx && j + dj > 0 + && j + dj < ff.ny) + { + wt[k] += 1; + trk[k] += (float) img[l].c[k0]; + } + } + } + } + // Save layer + for (i = 0; i < ff.nx; i++) + { + for (j = 0; j < ff.ny; j++) + { + k = i + ff.nx * j; + if (guide == 0) + l = i + (ff.ny - j - 1) * ff.nx; + else + l = i + (ff.ny - j - 1) * ff.nx + 4 * ff.nx * ff.ny; + if (wt[k] > 0) + ff.z[l] = trk[k] / (float) wt[k]; + else + ff.z[l] = trk[k]; + } } - } } - // Save layer - for (i=0;i0) - ff.z[l]=trk[k]/(float) wt[k]; - else - ff.z[l]=trk[k]; - } - } - } // Write fits - if (ff.timestamp!=NULL) - sprintf(filename,"%s.fits",ff.timestamp); + if (ff.timestamp != NULL) + sprintf (filename, "%s.fits", ff.timestamp); else - strcpy(filename,"test.fits"); - write_fits(filename,ff); + strcpy (filename, "test.fits"); + write_fits (filename, ff); // Write dark frame - if (darkout==1) - write_pgm("dark.pgm",ff); + if (darkout == 1) + write_pgm ("dark.pgm", ff); // Free - for (k=0;k0 && (c=fgetc(file))!=EOF && c!='\n') - s[i++]=c; + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') + s[i++] = c; // if (c=='\n') // s[i++]=c; - s[i]='\0'; + s[i] = '\0'; return i; } - + // Write fits file -void write_fits(char *filename,struct fourframe ff) +void +write_fits (char *filename, struct fourframe ff) { - int i,j,k,l; + int i, j, k, l; float *fbuf; int *ibuf; qfitsdumper qd; qfits_header *qh; - char key[FITS_LINESZ+1] ; - char val[FITS_LINESZ+1] ; - char com[FITS_LINESZ+1] ; - char lin[FITS_LINESZ+1] ; + char key[FITS_LINESZ + 1]; + char val[FITS_LINESZ + 1]; + char com[FITS_LINESZ + 1]; + char lin[FITS_LINESZ + 1]; FILE *file; // Create FITS header - qh=qfits_header_default(); + qh = qfits_header_default (); // Add stuff - if (ff.type==1) - qfits_header_add(qh,"BITPIX","8"," ",NULL); + if (ff.type == 1) + qfits_header_add (qh, "BITPIX", "8", " ", NULL); else - qfits_header_add(qh,"BITPIX","-32"," ",NULL); - qfits_header_add(qh,"NAXIS","3"," ",NULL); - sprintf(val,"%i",ff.nx); - qfits_header_add(qh,"NAXIS1",val," ",NULL); - sprintf(val,"%i",ff.ny); - qfits_header_add(qh,"NAXIS2",val," ",NULL); - sprintf(val,"%i",ff.nlayer); - qfits_header_add(qh,"NAXIS3",val," ",NULL); - qfits_header_add(qh,"BSCALE","1.0"," ",NULL); - qfits_header_add(qh,"BZERO","0.0"," ",NULL); - qfits_header_add(qh,"DATAMAX","255.0"," ",NULL); - qfits_header_add(qh,"DATAMIN","0.0"," ",NULL); - sprintf(val,"%s",ff.timestamp); - qfits_header_add(qh,"DATE-OBS",val," ",NULL); + qfits_header_add (qh, "BITPIX", "-32", " ", NULL); + qfits_header_add (qh, "NAXIS", "3", " ", NULL); + sprintf (val, "%i", ff.nx); + qfits_header_add (qh, "NAXIS1", val, " ", NULL); + sprintf (val, "%i", ff.ny); + qfits_header_add (qh, "NAXIS2", val, " ", NULL); + sprintf (val, "%i", ff.nlayer); + qfits_header_add (qh, "NAXIS3", val, " ", NULL); + qfits_header_add (qh, "BSCALE", "1.0", " ", NULL); + qfits_header_add (qh, "BZERO", "0.0", " ", NULL); + qfits_header_add (qh, "DATAMAX", "255.0", " ", NULL); + qfits_header_add (qh, "DATAMIN", "0.0", " ", NULL); + sprintf (val, "%s", ff.timestamp); + qfits_header_add (qh, "DATE-OBS", val, " ", NULL); // MJD-OBS - sprintf(val,"%lf",ff.mjd); - qfits_header_add(qh,"MJD-OBS",val," ",NULL); - sprintf(val,"%f",ff.dt[ff.nt-1]-ff.dt[0]); - qfits_header_add(qh,"EXPTIME",val," ",NULL); - sprintf(val,"%d",ff.nt); - qfits_header_add(qh,"NFRAMES",val," ",NULL); + sprintf (val, "%lf", ff.mjd); + qfits_header_add (qh, "MJD-OBS", val, " ", NULL); + sprintf (val, "%f", ff.dt[ff.nt - 1] - ff.dt[0]); + qfits_header_add (qh, "EXPTIME", val, " ", NULL); + sprintf (val, "%d", ff.nt); + qfits_header_add (qh, "NFRAMES", val, " ", NULL); // Astrometry keywors - sprintf(val,"%f",ff.nx/2.0); - qfits_header_add(qh,"CRPIX1",val," ",NULL); - sprintf(val,"%f",ff.ny/2.0); - qfits_header_add(qh,"CRPIX2",val," ",NULL); - qfits_header_add(qh,"CRVAL1","0.0"," ",NULL); - qfits_header_add(qh,"CRVAL2","0.0"," ",NULL); - qfits_header_add(qh,"CD1_1","0.0"," ",NULL); - qfits_header_add(qh,"CD1_2","0.0"," ",NULL); - qfits_header_add(qh,"CD2_1","0.0"," ",NULL); - qfits_header_add(qh,"CD2_2","0.0"," ",NULL); - qfits_header_add(qh,"CTYPE1","'RA---TAN'"," ",NULL); - qfits_header_add(qh,"CTYPE2","'DEC--TAN'"," ",NULL); - qfits_header_add(qh,"CUNIT1","'deg'"," ",NULL); - qfits_header_add(qh,"CUNIT2","'deg'"," ",NULL); - qfits_header_add(qh,"CRRES1","0.0"," ",NULL); - qfits_header_add(qh,"CRRES2","0.0"," ",NULL); - qfits_header_add(qh,"EQUINOX","2000.0"," ",NULL); - qfits_header_add(qh,"RADECSYS","ICRS"," ",NULL); - sprintf(val,"%d",ff.cospar); - qfits_header_add(qh,"COSPAR",val," ",NULL); - sprintf(val,"'%s'",ff.observer); - qfits_header_add(qh,"OBSERVER",val," ",NULL); + sprintf (val, "%f", ff.nx / 2.0); + qfits_header_add (qh, "CRPIX1", val, " ", NULL); + sprintf (val, "%f", ff.ny / 2.0); + qfits_header_add (qh, "CRPIX2", val, " ", NULL); + qfits_header_add (qh, "CRVAL1", "0.0", " ", NULL); + qfits_header_add (qh, "CRVAL2", "0.0", " ", NULL); + qfits_header_add (qh, "CD1_1", "0.0", " ", NULL); + qfits_header_add (qh, "CD1_2", "0.0", " ", NULL); + qfits_header_add (qh, "CD2_1", "0.0", " ", NULL); + qfits_header_add (qh, "CD2_2", "0.0", " ", NULL); + qfits_header_add (qh, "CTYPE1", "'RA---TAN'", " ", NULL); + qfits_header_add (qh, "CTYPE2", "'DEC--TAN'", " ", NULL); + qfits_header_add (qh, "CUNIT1", "'deg'", " ", NULL); + qfits_header_add (qh, "CUNIT2", "'deg'", " ", NULL); + qfits_header_add (qh, "CRRES1", "0.0", " ", NULL); + qfits_header_add (qh, "CRRES2", "0.0", " ", NULL); + qfits_header_add (qh, "EQUINOX", "2000.0", " ", NULL); + qfits_header_add (qh, "RADECSYS", "ICRS", " ", NULL); + sprintf (val, "%d", ff.cospar); + qfits_header_add (qh, "COSPAR", val, " ", NULL); + sprintf (val, "'%s'", ff.observer); + qfits_header_add (qh, "OBSERVER", val, " ", NULL); // Add timestamps - for (k=0;k=0;j--) { - for (k=0;k= 0; j--) + { + for (k = 0; k < ff.nlayer; k++) + { + fbuf[l] = ff.z[l]; + ibuf[l] = (int) ff.z[l]; + + l++; + } + } } - } // Set parameters - qd.filename=filename; - qd.npix=ff.nlayer*ff.nx*ff.ny; - if (ff.type==1) { - qd.ptype=PTYPE_INT; - qd.ibuf=ibuf; - qd.out_ptype=BPP_8_UNSIGNED; - } else { - qd.ptype=PTYPE_FLOAT; - qd.fbuf=fbuf; - qd.out_ptype=-32; - } + qd.filename = filename; + qd.npix = ff.nlayer * ff.nx * ff.ny; + if (ff.type == 1) + { + qd.ptype = PTYPE_INT; + qd.ibuf = ibuf; + qd.out_ptype = BPP_8_UNSIGNED; + } + else + { + qd.ptype = PTYPE_FLOAT; + qd.fbuf = fbuf; + qd.out_ptype = -32; + } // Dump - qfits_pixdump(&qd); + qfits_pixdump (&qd); - free(fbuf); - free(ibuf); + free (fbuf); + free (ibuf); return; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min; - double mjd,dday; + int year, month, day, hour, min; + double mjd, dday; float sec; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%f",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; - mjd=date2mjd(year,month,dday); + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%f", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; + mjd = date2mjd (year, month, dday); return mjd; } // Write pgm file -void write_pgm(char *filename,struct fourframe ff) +void +write_pgm (char *filename, struct fourframe ff) { - int i,j,k; + int i, j, k; FILE *file; - file=fopen(filename,"w"); - fprintf(file,"P5\n# 2013-01-01T00:00:00\n%d %d\n255\n",ff.nx,ff.ny); - for (j=0;j2) - year=c-4716; + dday = b - d - floor (30.6001 * e) + f; + if (e < 14) + month = e - 1; else - year=c-4715; + month = e - 13; - day=(int) floor(dday); - x=24.0*(dday-day); - x=3600.*fabs(x); - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - hour=x; + if (month > 2) + year = c - 4716; + else + year = c - 4715; + + day = (int) floor (dday); + x = 24.0 * (dday - day); + x = 3600. * fabs (x); + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + hour = x; + + sprintf (date, "%04d-%02d-%02dT%02d:%02d:%06.3f", year, month, day, hour, + min, sec); - sprintf(date,"%04d-%02d-%02dT%02d:%02d:%06.3f",year,month,day,hour,min,sec); - return; } diff --git a/src/planscan.c b/src/planscan.c index 50c08d6..d8cd9c0 100644 --- a/src/planscan.c +++ b/src/planscan.c @@ -9,649 +9,765 @@ #define LIM 128 #define D2R M_PI/180.0 #define R2D 180.0/M_PI -#define XKMPER 6378.135 // Earth radius in km -#define XKMPAU 149597879.691 // AU in km +#define XKMPER 6378.135 // Earth radius in km +#define XKMPAU 149597879.691 // AU in km #define XKE 0.743669161e-1 -#define CK2 5.413080e-4 /* (0.5 * XJ2 * AE * AE) */ -#define XMNPDA 1440.0 /* Minutes per day */ +#define CK2 5.413080e-4 /* (0.5 * XJ2 * AE * AE) */ +#define XMNPDA 1440.0 /* Minutes per day */ #define FLAT (1.0/298.257) #define STDMAG 6.0 #define MMAX 1024 -long Isat=0; -long Isatsel=0; +long Isat = 0; +long Isatsel = 0; extern double SGDP4_jd0; -struct map { - double lat,lng; +struct map +{ + double lat, lng; float alt; char observer[32]; int site_id; } m; -void get_site(int site_id); -double nfd2mjd(char *date); -double date2mjd(int year,int month,double day); -void nfd_now(char *s); -void obspos_xyz(double mjd,xyz_t *pos,xyz_t *vel); -void sunpos_xyz(double mjd,xyz_t *pos,double *ra,double *de); -double gmst(double mjd); -double dgmst(double mjd); -double modulo(double x,double y); -void equatorial2horizontal(double mjd,double ra,double de,double *azi,double *alt); -void mjd2date(double mjd,char *date); -int properties(kep_t K,xyz_t obspos,xyz_t sunpos,float radius,float t,double *ra,double *de,double *r,float *mag); -void dec2s(double x,char *s,int f,int len); +void get_site (int site_id); +double nfd2mjd (char *date); +double date2mjd (int year, int month, double day); +void nfd_now (char *s); +void obspos_xyz (double mjd, xyz_t * pos, xyz_t * vel); +void sunpos_xyz (double mjd, xyz_t * pos, double *ra, double *de); +double gmst (double mjd); +double dgmst (double mjd); +double modulo (double x, double y); +void equatorial2horizontal (double mjd, double ra, double de, double *azi, + double *alt); +void mjd2date (double mjd, char *date); +int properties (kep_t K, xyz_t obspos, xyz_t sunpos, float radius, float t, + double *ra, double *de, double *r, float *mag); +void dec2s (double x, char *s, int f, int len); -float semimajoraxis(orbit_t orb) +float +semimajoraxis (orbit_t orb) { - float xno,eo,xincl; - float a1,betao2,betao,temp0,del1,a0,del0,xnodp,aodp; + float xno, eo, xincl; + float a1, betao2, betao, temp0, del1, a0, del0, xnodp, aodp; - xno=orb.rev*2.0*M_PI/XMNPDA; - eo=orb.ecc; - xincl=orb.eqinc; + xno = orb.rev * 2.0 * M_PI / XMNPDA; + eo = orb.ecc; + xincl = orb.eqinc; - a1 = pow(XKE / xno, 2.0/3.0); + a1 = pow (XKE / xno, 2.0 / 3.0); betao2 = 1.0 - eo * eo; - betao = sqrt(betao2); - temp0 = (1.5 * CK2) * cos(xincl)*cos(xincl) / (betao * betao2); + betao = sqrt (betao2); + temp0 = (1.5 * CK2) * cos (xincl) * cos (xincl) / (betao * betao2); del1 = temp0 / (a1 * a1); - a0 = a1 * (1.0 - del1 * (1.0/3.0 + del1 * (1.0 + del1 * 134.0/81.0))); + a0 = a1 * (1.0 - del1 * (1.0 / 3.0 + del1 * (1.0 + del1 * 134.0 / 81.0))); del0 = temp0 / (a0 * a0); xnodp = xno / (1.0 + del0); aodp = (a0 / (1.0 - del0)); - aodp=(aodp-1)*XKMPER; + aodp = (aodp - 1) * XKMPER; return aodp; } -void usage(void) +void +usage (void) { - printf("planscan -t -c -s -l -i \n"); - printf(" -r -A -S \n\n"); - printf("-t UT Start date/time in yyyy-mm-ddThh:mm:ss [default: now]\n"); - printf("-c Input TLE catalog to use [default: classfd.tle]\n"); - printf("-s Site number from sites.txt [default: 4171]\n"); - printf("-l Search length from UT start in seconds [default: 86400 s]\n"); - printf("-i NORAD number of satellite to select [default: 41334]\n"); - printf("-r Satellite altitude above surface in km [default: mean orbital altitude]\n"); - printf("-A Minimum satellite elevation in degrees [default: 10 degrees]\n"); - printf("-S Maximum solar elevation in degrees [default: -6 degrees\n"); - printf("-d Time step in seconds [default: 60s]\n"); - printf("-C Select on culmination instead of maximum brightness\n"); - printf("-h Shows this help\n"); + printf + ("planscan -t -c -s -l -i \n"); + printf (" -r -A -S \n\n"); + printf + ("-t UT Start date/time in yyyy-mm-ddThh:mm:ss [default: now]\n"); + printf + ("-c Input TLE catalog to use [default: classfd.tle]\n"); + printf ("-s Site number from sites.txt [default: 4171]\n"); + printf + ("-l Search length from UT start in seconds [default: 86400 s]\n"); + printf + ("-i NORAD number of satellite to select [default: 41334]\n"); + printf + ("-r Satellite altitude above surface in km [default: mean orbital altitude]\n"); + printf + ("-A Minimum satellite elevation in degrees [default: 10 degrees]\n"); + printf + ("-S Maximum solar elevation in degrees [default: -6 degrees\n"); + printf ("-d Time step in seconds [default: 60s]\n"); + printf + ("-C Select on culmination instead of maximum brightness\n"); + printf ("-h Shows this help\n"); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int arg=0,imode,i; - int satno=-1; + int arg = 0, imode, i; + int satno = -1; orbit_t orb; FILE *fp; - char tlefile[256]="classfd.tle"; + char tlefile[256] = "classfd.tle"; char nfd[32]; - double mjd0,mjd,jd,tsince; - int rv,withvel; + double mjd0, mjd, jd, tsince; + int rv, withvel; kep_t K; - double radius=-1; - xyz_t obspos,obsvel,sunpos; - double p,pmin,p0,p1,r,ra,de,azi,alt,sazi,salt,altmin=10.0,saltmin=-6.0,altmax,dp; - float mag,mmin; - int state,pstate,nstate; - float t,length=86400.0,dt=60.0; - char sra[16],sde[16],type[32]; - int opttype=0; // 0 magnitude; 1 elevation + double radius = -1; + xyz_t obspos, obsvel, sunpos; + double p, pmin, p0, p1, r, ra, de, azi, alt, sazi, salt, altmin = + 10.0, saltmin = -6.0, altmax, dp; + float mag, mmin; + int state, pstate, nstate; + float t, length = 86400.0, dt = 60.0; + char sra[16], sde[16], type[32]; + int opttype = 0; // 0 magnitude; 1 elevation // Initialize - nfd_now(nfd); - mjd0=nfd2mjd(nfd); - get_site(4171); - + nfd_now (nfd); + mjd0 = nfd2mjd (nfd); + get_site (4171); + // Decode options - while ((arg=getopt(argc,argv,"t:c:i:s:l:hS:A:r:d:C"))!=-1) { - switch (arg) { - - case 't': - strcpy(nfd,optarg); - mjd0=nfd2mjd(nfd); - break; + while ((arg = getopt (argc, argv, "t:c:i:s:l:hS:A:r:d:C")) != -1) + { + switch (arg) + { - case 'c': - strcpy(tlefile,optarg); - break; + case 't': + strcpy (nfd, optarg); + mjd0 = nfd2mjd (nfd); + break; - case 's': - get_site(atoi(optarg)); - break; + case 'c': + strcpy (tlefile, optarg); + break; - case 'C': - opttype=1; - break; - - case 'i': - satno=atoi(optarg); - break; + case 's': + get_site (atoi (optarg)); + break; - case 'r': - radius=atof(optarg); - break; - - case 'l': - length=atoi(optarg); - if (strchr(optarg,'h')!=NULL) - length*=3600; - else if (strchr(optarg,'m')!=NULL) - length*=60; - else if (strchr(optarg,'d')!=NULL) - length*=86400; - break; + case 'C': + opttype = 1; + break; - case 'S': - saltmin=atof(optarg); - break; + case 'i': + satno = atoi (optarg); + break; - case 'A': - altmin=atof(optarg); - break; + case 'r': + radius = atof (optarg); + break; - case 'd': - dt=atof(optarg); - break; + case 'l': + length = atoi (optarg); + if (strchr (optarg, 'h') != NULL) + length *= 3600; + else if (strchr (optarg, 'm') != NULL) + length *= 60; + else if (strchr (optarg, 'd') != NULL) + length *= 86400; + break; - case 'h': - usage(); - return 0; - break; - - default: - usage(); - return 0; + case 'S': + saltmin = atof (optarg); + break; + + case 'A': + altmin = atof (optarg); + break; + + case 'd': + dt = atof (optarg); + break; + + case 'h': + usage (); + return 0; + break; + + default: + usage (); + return 0; + } } - } // Error checking - if (satno<=0) { - fprintf(stderr,"ERROR: NORAD satellite number not provided!\n"); - return -1; - } + if (satno <= 0) + { + fprintf (stderr, "ERROR: NORAD satellite number not provided!\n"); + return -1; + } // Get TLE - fp=fopen(tlefile,"rb"); - if (fp==NULL) { - fprintf(stderr,"ERROR: Failed to open file with TLEs (%s)!\n",tlefile); - return -1; - } + fp = fopen (tlefile, "rb"); + if (fp == NULL) + { + fprintf (stderr, "ERROR: Failed to open file with TLEs (%s)!\n", + tlefile); + return -1; + } // Read TLE - while (read_twoline(fp,satno,&orb)==0) { - Isat=orb.satno; - imode=init_sgdp4(&orb); + while (read_twoline (fp, satno, &orb) == 0) + { + Isat = orb.satno; + imode = init_sgdp4 (&orb); - if (imode==SGDP4_ERROR) - continue; + if (imode == SGDP4_ERROR) + continue; - } - fclose(fp); + } + fclose (fp); // Object found? - if (orb.satno!=satno) { - fprintf(stderr,"ERROR: Object %d not found in %s!\n",satno,tlefile); - return -1; - } + if (orb.satno != satno) + { + fprintf (stderr, "ERROR: Object %d not found in %s!\n", satno, tlefile); + return -1; + } // Object found? - if (orb.rev<10.0) { - fprintf(stderr,"ERROR: Object %d is not in a LEO orbit.\n",satno); - return -1; - } + if (orb.rev < 10.0) + { + fprintf (stderr, "ERROR: Object %d is not in a LEO orbit.\n", satno); + return -1; + } // Compute radius - if (radius<0.0) - radius=semimajoraxis(orb); - + if (radius < 0.0) + radius = semimajoraxis (orb); + // Print header - printf("Observer: %s (%04d) [%+.4f, %+.4f, %.0fm]\n",m.observer,m.site_id,m.lat,m.lng,m.alt*1000.0); - printf("Elements: %s\n",tlefile); - printf("Object: %d\n",satno); - printf("Radius: %g km\n",radius); - printf("Start UT Date/Time: %s for %g h \n\n",nfd,length/3600.0); - printf("UT Date/Time R.A. Decl. Azi. Alt. Range Mag Sun Alt. Type\n"); - printf(" (deg) (deg) (km) (deg)\n"); - printf("=====================================================================================\n"); - + printf ("Observer: %s (%04d) [%+.4f, %+.4f, %.0fm]\n", m.observer, + m.site_id, m.lat, m.lng, m.alt * 1000.0); + printf ("Elements: %s\n", tlefile); + printf ("Object: %d\n", satno); + printf ("Radius: %g km\n", radius); + printf ("Start UT Date/Time: %s for %g h \n\n", nfd, length / 3600.0); + printf + ("UT Date/Time R.A. Decl. Azi. Alt. Range Mag Sun Alt. Type\n"); + printf + (" (deg) (deg) (km) (deg)\n"); + printf + ("=====================================================================================\n"); - for (t=0.0;t altmax && mag < 15.0) + { + pmin = p; + altmax = alt; + } + } } - } else if (opttype==1) { - if (alt>altmax && mag<15.0) { - pmin=p; - altmax=alt; + + // Finer search + p0 = pmin - 4.0 * M_PI / (float) MMAX; + p1 = pmin + 4.0 * M_PI / (float) MMAX; + for (i = 0, pmin = 0.0, mmin = 15.0; i < MMAX; i++) + { + p = p0 + (p1 - p0) * (float) i / (float) (MMAX - 1); + state = + properties (K, obspos, sunpos, radius, p, &ra, &de, &r, &mag); + equatorial2horizontal (mjd, ra, de, &azi, &alt); + + if (opttype == 0) + { + if (mag < mmin) + { + pmin = p; + mmin = mag; + } + } + else if (opttype == 1) + { + if (alt > altmax && mag < 15.0) + { + pmin = p; + altmax = alt; + } + } } - } + + // Get properties before and after maximum + pstate = + properties (K, obspos, sunpos, radius, pmin - 0.01, &ra, &de, &r, + &mag); + nstate = + properties (K, obspos, sunpos, radius, pmin + 0.01, &ra, &de, &r, + &mag); + state = + properties (K, obspos, sunpos, radius, pmin, &ra, &de, &r, &mag); + if (pstate < state && state == nstate) + strcpy (type, "Egress"); + else if (pstate == state && state > nstate) + strcpy (type, "Ingress"); + else if (opttype == 0) + strcpy (type, "Maximum"); + else if (opttype == 1) + strcpy (type, "Culmination"); + + ra = modulo (ra, 360.0); + equatorial2horizontal (mjd, ra, de, &azi, &alt); + azi = modulo (azi + 180.0, 360.0); + mjd2date (mjd, nfd); + dec2s (ra / 15.0, sra, 0, 2); + dec2s (de, sde, 0, 2); + if (alt > altmin && salt < saltmin) + printf ("%s %s %s %6.2f %6.2f %7.1f %5.2f %6.2f %s\n", nfd, sra, + sde, azi, alt, r, mag, salt, type); } - // Finer search - p0=pmin-4.0*M_PI/(float) MMAX; - p1=pmin+4.0*M_PI/(float) MMAX; - for (i=0,pmin=0.0,mmin=15.0;ialtmax && mag<15.0) { - pmin=p; - altmax=alt; - } - } - } - - // Get properties before and after maximum - pstate=properties(K,obspos,sunpos,radius,pmin-0.01,&ra,&de,&r,&mag); - nstate=properties(K,obspos,sunpos,radius,pmin+0.01,&ra,&de,&r,&mag); - state=properties(K,obspos,sunpos,radius,pmin,&ra,&de,&r,&mag); - if (pstatenstate) - strcpy(type,"Ingress"); - else if (opttype==0) - strcpy(type,"Maximum"); - else if (opttype==1) - strcpy(type,"Culmination"); - - ra=modulo(ra,360.0); - equatorial2horizontal(mjd,ra,de,&azi,&alt); - azi=modulo(azi+180.0,360.0); - mjd2date(mjd,nfd); - dec2s(ra/15.0,sra,0,2); - dec2s(de,sde,0,2); - if (alt>altmin && salttm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec); - + time (&rawtime); + ptm = gmtime (&rawtime); + + sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900, + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, + ptm->tm_sec); + return; } // Observer position -void obspos_xyz(double mjd,xyz_t *pos,xyz_t *vel) +void +obspos_xyz (double mjd, xyz_t * pos, xyz_t * vel) { - double ff,gc,gs,theta,s,dtheta; + double ff, gc, gs, theta, s, dtheta; - s=sin(m.lat*D2R); - ff=sqrt(1.0-FLAT*(2.0-FLAT)*s*s); - gc=1.0/ff+m.alt/XKMPER; - gs=(1.0-FLAT)*(1.0-FLAT)/ff+m.alt/XKMPER; + s = sin (m.lat * D2R); + ff = sqrt (1.0 - FLAT * (2.0 - FLAT) * s * s); + gc = 1.0 / ff + m.alt / XKMPER; + gs = (1.0 - FLAT) * (1.0 - FLAT) / ff + m.alt / XKMPER; - theta=gmst(mjd)+m.lng; - dtheta=dgmst(mjd)*D2R/86400; + theta = gmst (mjd) + m.lng; + dtheta = dgmst (mjd) * D2R / 86400; - pos->x=gc*cos(m.lat*D2R)*cos(theta*D2R)*XKMPER; - pos->y=gc*cos(m.lat*D2R)*sin(theta*D2R)*XKMPER; - pos->z=gs*sin(m.lat*D2R)*XKMPER; - vel->x=-gc*cos(m.lat*D2R)*sin(theta*D2R)*XKMPER*dtheta; - vel->y=gc*cos(m.lat*D2R)*cos(theta*D2R)*XKMPER*dtheta; - vel->z=0.0; + pos->x = gc * cos (m.lat * D2R) * cos (theta * D2R) * XKMPER; + pos->y = gc * cos (m.lat * D2R) * sin (theta * D2R) * XKMPER; + pos->z = gs * sin (m.lat * D2R) * XKMPER; + vel->x = -gc * cos (m.lat * D2R) * sin (theta * D2R) * XKMPER * dtheta; + vel->y = gc * cos (m.lat * D2R) * cos (theta * D2R) * XKMPER * dtheta; + vel->z = 0.0; return; } // Solar position -void sunpos_xyz(double mjd,xyz_t *pos,double *ra,double *de) +void +sunpos_xyz (double mjd, xyz_t * pos, double *ra, double *de) { - double jd,t,l0,m,e,c,r; - double n,s,ecl; + double jd, t, l0, m, e, c, r; + double n, s, ecl; - jd=mjd+2400000.5; - t=(jd-2451545.0)/36525.0; - l0=modulo(280.46646+t*(36000.76983+t*0.0003032),360.0)*D2R; - m=modulo(357.52911+t*(35999.05029-t*0.0001537),360.0)*D2R; - e=0.016708634+t*(-0.000042037-t*0.0000001267); - c=(1.914602+t*(-0.004817-t*0.000014))*sin(m)*D2R; - c+=(0.019993-0.000101*t)*sin(2.0*m)*D2R; - c+=0.000289*sin(3.0*m)*D2R; + jd = mjd + 2400000.5; + t = (jd - 2451545.0) / 36525.0; + l0 = modulo (280.46646 + t * (36000.76983 + t * 0.0003032), 360.0) * D2R; + m = modulo (357.52911 + t * (35999.05029 - t * 0.0001537), 360.0) * D2R; + e = 0.016708634 + t * (-0.000042037 - t * 0.0000001267); + c = (1.914602 + t * (-0.004817 - t * 0.000014)) * sin (m) * D2R; + c += (0.019993 - 0.000101 * t) * sin (2.0 * m) * D2R; + c += 0.000289 * sin (3.0 * m) * D2R; - r=1.000001018*(1.0-e*e)/(1.0+e*cos(m+c)); - n=modulo(125.04-1934.136*t,360.0)*D2R; - s=l0+c+(-0.00569-0.00478*sin(n))*D2R; - ecl=(23.43929111+(-46.8150*t-0.00059*t*t+0.001813*t*t*t)/3600.0+0.00256*cos(n))*D2R; + r = 1.000001018 * (1.0 - e * e) / (1.0 + e * cos (m + c)); + n = modulo (125.04 - 1934.136 * t, 360.0) * D2R; + s = l0 + c + (-0.00569 - 0.00478 * sin (n)) * D2R; + ecl = + (23.43929111 + + (-46.8150 * t - 0.00059 * t * t + 0.001813 * t * t * t) / 3600.0 + + 0.00256 * cos (n)) * D2R; - *ra=atan2(cos(ecl)*sin(s),cos(s))*R2D; - *de=asin(sin(ecl)*sin(s))*R2D; + *ra = atan2 (cos (ecl) * sin (s), cos (s)) * R2D; + *de = asin (sin (ecl) * sin (s)) * R2D; - pos->x=r*cos(*de*D2R)*cos(*ra*D2R)*XKMPAU; - pos->y=r*cos(*de*D2R)*sin(*ra*D2R)*XKMPAU; - pos->z=r*sin(*de*D2R)*XKMPAU; + pos->x = r * cos (*de * D2R) * cos (*ra * D2R) * XKMPAU; + pos->y = r * cos (*de * D2R) * sin (*ra * D2R) * XKMPAU; + pos->z = r * sin (*de * D2R) * XKMPAU; return; } // Greenwich Mean Sidereal Time -double dgmst(double mjd) +double +dgmst (double mjd) { - double t,dgmst; + double t, dgmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - dgmst=360.98564736629+t*(0.000387933-t/38710000); + dgmst = 360.98564736629 + t * (0.000387933 - t / 38710000); return dgmst; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Convert equatorial into horizontal coordinates -void equatorial2horizontal(double mjd,double ra,double de,double *azi,double *alt) +void +equatorial2horizontal (double mjd, double ra, double de, double *azi, + double *alt) { double h; - h=gmst(mjd)+m.lng-ra; - - *azi=modulo(atan2(sin(h*D2R),cos(h*D2R)*sin(m.lat*D2R)-tan(de*D2R)*cos(m.lat*D2R))*R2D,360.0); - *alt=asin(sin(m.lat*D2R)*sin(de*D2R)+cos(m.lat*D2R)*cos(de*D2R)*cos(h*D2R))*R2D; + h = gmst (mjd) + m.lng - ra; + + *azi = + modulo (atan2 + (sin (h * D2R), + cos (h * D2R) * sin (m.lat * D2R) - + tan (de * D2R) * cos (m.lat * D2R)) * R2D, 360.0); + *alt = + asin (sin (m.lat * D2R) * sin (de * D2R) + + cos (m.lat * D2R) * cos (de * D2R) * cos (h * D2R)) * R2D; return; } // Compute Date from Julian Day -void mjd2date(double mjd,char *date) +void +mjd2date (double mjd, char *date) { - double f,jd,dday; - int z,alpha,a,b,c,d,e; - int year,month,day,hour,min; - float sec,x; + double f, jd, dday; + int z, alpha, a, b, c, d, e; + int year, month, day, hour, min; + float sec, x; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - dday=b-d-floor(30.6001*e)+f; - if (e<14) - month=e-1; + if (z < 2299161) + a = z; else - month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (month>2) - year=c-4716; + dday = b - d - floor (30.6001 * e) + f; + if (e < 14) + month = e - 1; else - year=c-4715; + month = e - 13; - day=(int) floor(dday); - x=24.0*(dday-day); - x=3600.*fabs(x)+0.0001; - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - hour=x; - sec=floor(1000.0*sec)/1000.0; + if (month > 2) + year = c - 4716; + else + year = c - 4715; - sprintf(date,"%04d-%02d-%02dT%02d:%02d:%02.0f",year,month,day,hour,min,sec); + day = (int) floor (dday); + x = 24.0 * (dday - day); + x = 3600. * fabs (x) + 0.0001; + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + hour = x; + sec = floor (1000.0 * sec) / 1000.0; + + sprintf (date, "%04d-%02d-%02dT%02d:%02d:%02.0f", year, month, day, hour, + min, sec); return; } -int properties(kep_t K,xyz_t obspos,xyz_t sunpos,float radius,float t,double *ra,double *de,double *r,float *mag) +int +properties (kep_t K, xyz_t obspos, xyz_t sunpos, float radius, float t, + double *ra, double *de, double *r, float *mag) { - double st,ct,sn,cn,si,ci; + double st, ct, sn, cn, si, ci; xyz_t satpos; - double dx,dy,dz,rsun,rearth,psun,pearth,p; + double dx, dy, dz, rsun, rearth, psun, pearth, p; float phase; int state; - + // Angles - sn=sin(K.ascn); - cn=cos(K.ascn); - si=sin(K.eqinc); - ci=cos(K.eqinc); - st=sin(K.theta+t); - ct=cos(K.theta+t); - - satpos.x=-sn*ci*st+cn*ct; - satpos.y=cn*ci*st+sn*ct; - satpos.z=si*st; - satpos.x*=(radius+XKMPER); - satpos.y*=(radius+XKMPER); - satpos.z*=(radius+XKMPER); - + sn = sin (K.ascn); + cn = cos (K.ascn); + si = sin (K.eqinc); + ci = cos (K.eqinc); + st = sin (K.theta + t); + ct = cos (K.theta + t); + + satpos.x = -sn * ci * st + cn * ct; + satpos.y = cn * ci * st + sn * ct; + satpos.z = si * st; + satpos.x *= (radius + XKMPER); + satpos.y *= (radius + XKMPER); + satpos.z *= (radius + XKMPER); + // Sun position from satellite - dx=-satpos.x+sunpos.x; - dy=-satpos.y+sunpos.y; - dz=-satpos.z+sunpos.z; - + dx = -satpos.x + sunpos.x; + dy = -satpos.y + sunpos.y; + dz = -satpos.z + sunpos.z; + // Distances - rsun=sqrt(dx*dx+dy*dy+dz*dz); - rearth=sqrt(satpos.x*satpos.x+satpos.y*satpos.y+satpos.z*satpos.z); - + rsun = sqrt (dx * dx + dy * dy + dz * dz); + rearth = + sqrt (satpos.x * satpos.x + satpos.y * satpos.y + satpos.z * satpos.z); + // Angles - psun=asin(696.0e3/rsun)*R2D; - pearth=asin(6378.135/rearth)*R2D; - - pearth=asin(6378.135/rearth)*R2D; - p=acos((-dx*satpos.x-dy*satpos.y-dz*satpos.z)/(rsun*rearth))*R2D; - p-=pearth; - + psun = asin (696.0e3 / rsun) * R2D; + pearth = asin (6378.135 / rearth) * R2D; + + pearth = asin (6378.135 / rearth) * R2D; + p = + acos ((-dx * satpos.x - dy * satpos.y - + dz * satpos.z) / (rsun * rearth)) * R2D; + p -= pearth; + // Position differences - dx=satpos.x-obspos.x; - dy=satpos.y-obspos.y; - dz=satpos.z-obspos.z; - + dx = satpos.x - obspos.x; + dy = satpos.y - obspos.y; + dz = satpos.z - obspos.z; + // Celestial position - *r=sqrt(dx*dx+dy*dy+dz*dz); - *ra=atan2(dy,dx)*R2D; - *de=asin(dz/ *r)*R2D; + *r = sqrt (dx * dx + dy * dy + dz * dz); + *ra = atan2 (dy, dx) * R2D; + *de = asin (dz / *r) * R2D; // Visibility - if (p<-psun) { - // strcpy(state,"eclipsed"); - state=0; - } else if (p>-psun && ppsun) { - // strcpy(state,"sunlit"); - state=2; - } - + if (p < -psun) + { + // strcpy(state,"eclipsed"); + state = 0; + } + else if (p > -psun && p < psun) + { + // strcpy(state,"umbra"); + state = 1; + } + else if (p > psun) + { + // strcpy(state,"sunlit"); + state = 2; + } + // Phase - phase=acos(((obspos.x-satpos.x)*(sunpos.x-satpos.x)+(obspos.y-satpos.y)*(sunpos.y-satpos.y)+(obspos.z-satpos.z)*(sunpos.z-satpos.z))/(rsun* *r))*R2D; - + phase = + acos (((obspos.x - satpos.x) * (sunpos.x - satpos.x) + + (obspos.y - satpos.y) * (sunpos.y - satpos.y) + (obspos.z - + satpos.z) * + (sunpos.z - satpos.z)) / (rsun * *r)) * R2D; + // Magnitude - if (state==2) - *mag=STDMAG-15.0+5*log10( *r)-2.5*log10(sin(phase*D2R)+(M_PI-phase*D2R)*cos(phase*D2R)); + if (state == 2) + *mag = + STDMAG - 15.0 + 5 * log10 (*r) - 2.5 * log10 (sin (phase * D2R) + + (M_PI - + phase * D2R) * + cos (phase * D2R)); else - *mag=15; + *mag = 15; return state; } // Convert Decimal into Sexagesimal -void dec2s(double x,char *s,int f,int len) +void +dec2s (double x, char *s, int f, int len) { int i; - double sec,deg,min; + double sec, deg, min; char sign; - char *form[]={"::",",,","hms"," "}; + char *form[] = { "::", ",,", "hms", " " }; - sign=(x<0 ? '-' : ' '); - x=3600.*fabs(x); + sign = (x < 0 ? '-' : ' '); + x = 3600. * fabs (x); - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; // deg=fmod(x,60.); - deg=x; + deg = x; - if (len==7) sprintf(s,"%c%02i%c%02i%c%07.4f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]); - if (len==6) sprintf(s,"%c%02i%c%02i%c%06.3f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]); - if (len==5) sprintf(s,"%c%02i%c%02i%c%05.2f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]); - if (len==4) sprintf(s,"%c%02i%c%02i%c%04.1f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]); - if (len==2) sprintf(s,"%c%02i%c%02i%c%02i%c",sign,(int) deg,form[f][0],(int) min,form[f][1],(int) floor(sec),form[f][2]); + if (len == 7) + sprintf (s, "%c%02i%c%02i%c%07.4f%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], sec, form[f][2]); + if (len == 6) + sprintf (s, "%c%02i%c%02i%c%06.3f%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], sec, form[f][2]); + if (len == 5) + sprintf (s, "%c%02i%c%02i%c%05.2f%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], sec, form[f][2]); + if (len == 4) + sprintf (s, "%c%02i%c%02i%c%04.1f%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], sec, form[f][2]); + if (len == 2) + sprintf (s, "%c%02i%c%02i%c%02i%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], (int) floor (sec), form[f][2]); return; } diff --git a/src/plotfits.c b/src/plotfits.c index e874d28..22057e0 100644 --- a/src/plotfits.c +++ b/src/plotfits.c @@ -13,440 +13,498 @@ #define R2D 180.0/M_PI #define NMAX 4096 -struct star { - double ra,de; - float pmra,pmde; +struct star +{ + double ra, de; + float pmra, pmde; float mag; }; -struct image { - int naxis1,naxis2,naxis3; +struct image +{ + int naxis1, naxis2, naxis3; float *z; - float zmin,zmax; - double ra0,de0; - float x0,y0; - float a[3],b[3]; + float zmin, zmax; + double ra0, de0; + float x0, y0; + float a[3], b[3]; double mjd; } img; -struct catalog { +struct catalog +{ int n; - float x[NMAX],y[NMAX],mag[NMAX]; - double ra[NMAX],de[NMAX],rx[NMAX],ry[NMAX]; + float x[NMAX], y[NMAX], mag[NMAX]; + double ra[NMAX], de[NMAX], rx[NMAX], ry[NMAX]; int select[NMAX]; }; -struct map { - double lat,lng; +struct map +{ + double lat, lng; float alt; int site_id; char observer[32]; } m; -struct image read_fits(char *filename,int pnum); -int fgetline(FILE *,char *,int); -void forward(double ra0,double de0,double ra,double de,double *x,double *y); -void reverse(double,double,double,double,double *,double *); -void lfit2d(float *x,float *y,float *z,int n,float *a); -struct catalog read_pixel_catalog(char *filename); -double gmst(double mjd); -double modulo(double x,double y); -void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de); -double s2dec(char *s); +struct image read_fits (char *filename, int pnum); +int fgetline (FILE *, char *, int); +void forward (double ra0, double de0, double ra, double de, double *x, + double *y); +void reverse (double, double, double, double, double *, double *); +void lfit2d (float *x, float *y, float *z, int n, float *a); +struct catalog read_pixel_catalog (char *filename); +double gmst (double mjd); +double modulo (double x, double y); +void precess (double mjd0, double ra0, double de0, double mjd, double *ra, + double *de); +double s2dec (char *s); // Read astrometric catalog -struct catalog read_astrometric_catalog(char *filename,float mmin,float sx,float sy,float angle) +struct catalog +read_astrometric_catalog (char *filename, float mmin, float sx, float sy, + float angle) { - int i=0; + int i = 0; FILE *file; char line[LIM]; struct catalog c; - double rx,ry,x,y,ra,de; + double rx, ry, x, y, ra, de; struct star s; - double d,dx,dy; - double mjd0=51544.5; + double d, dx, dy; + double mjd0 = 51544.5; - file=fopen(filename,"rb"); - if (file==NULL) { - fprintf(stderr,"%s not found!\n",filename); - exit(0); - } - while (!feof(file)) { - fread(&s,sizeof(struct star),1,file); - if (s.mag>mmin) - continue; - precess(mjd0,s.ra,s.de,img.mjd,&ra,&de); - forward(img.ra0,img.de0,ra,de,&rx,&ry); - x=img.x0+1.0/sx*(cos(angle*D2R)*rx+sin(angle*D2R)*ry); - y=img.y0+1.0/sy*(-sin(angle*D2R)*rx+cos(angle*D2R)*ry); + file = fopen (filename, "rb"); + if (file == NULL) + { + fprintf (stderr, "%s not found!\n", filename); + exit (0); + } + while (!feof (file)) + { + fread (&s, sizeof (struct star), 1, file); + if (s.mag > mmin) + continue; + precess (mjd0, s.ra, s.de, img.mjd, &ra, &de); + forward (img.ra0, img.de0, ra, de, &rx, &ry); + x = + img.x0 + 1.0 / sx * (cos (angle * D2R) * rx + sin (angle * D2R) * ry); + y = + img.y0 + 1.0 / sy * (-sin (angle * D2R) * rx + + cos (angle * D2R) * ry); /* - } else if (t.state==1) { - dx=rx-t.a[0]; - dy=ry-t.b[0]; - d=t.a[1]*t.b[2]-t.a[2]*t.b[1]; - x=(t.b[2]*dx-t.a[2]*dy)/d; - y=(t.a[1]*dy-t.b[1]*dx)/d; + } else if (t.state==1) { + dx=rx-t.a[0]; + dy=ry-t.b[0]; + d=t.a[1]*t.b[2]-t.a[2]*t.b[1]; + x=(t.b[2]*dx-t.a[2]*dy)/d; + y=(t.a[1]*dy-t.b[1]*dx)/d; + } + */ + if (x > 0.0 && x < img.naxis1 && y > 0.0 && y < img.naxis2) + { + c.x[i] = x; + c.y[i] = y; + c.rx[i] = rx; + c.ry[i] = ry; + c.ra[i] = s.ra; + c.de[i] = s.de; + c.mag[i] = s.mag; + c.select[i] = 0; + i++; + } } - */ - if (x>0.0 && x0.0 && ymmin) - continue; - precess(mjd0,s.ra,s.de,img.mjd,&ra,&de); - forward(img.ra0,img.de0,ra,de,&rx,&ry); - dx=rx-img.a[0]; - dy=ry-img.b[0]; - d=img.a[1]*img.b[2]-img.a[2]*img.b[1]; - x=(img.b[2]*dx-img.a[2]*dy)/d+img.x0; - y=(img.a[1]*dy-img.b[1]*dx)/d+img.y0; - if (x>0.0 && x0.0 && y mmin) + continue; + precess (mjd0, s.ra, s.de, img.mjd, &ra, &de); + forward (img.ra0, img.de0, ra, de, &rx, &ry); + dx = rx - img.a[0]; + dy = ry - img.b[0]; + d = img.a[1] * img.b[2] - img.a[2] * img.b[1]; + x = (img.b[2] * dx - img.a[2] * dy) / d + img.x0; + y = (img.a[1] * dy - img.b[1] * dx) / d + img.y0; + if (x > 0.0 && x < img.naxis1 && y > 0.0 && y < img.naxis2) + { + c.x[i] = x; + c.y[i] = y; + c.rx[i] = rx; + c.ry[i] = ry; + c.ra[i] = s.ra; + c.de[i] = s.de; + c.mag[i] = s.mag; + c.select[i] = 0; + i++; + } } - } - fclose(file); - c.n=i; + fclose (file); + c.n = i; return c; } -int select_nearest(struct catalog c,float x,float y) +int +select_nearest (struct catalog c, float x, float y) { - int i,imin; - float r,rmin; + int i, imin; + float r, rmin; - for (i=0;in;i++) - cat->select[i]=0; - for (i=0;in;i++) - ast->select[i]=0; - - file=fopen("out.dat","w"); - for (i=0,n=0;in;i++) { - for (j=0,flag=0;jn;j++) { - if (ast->select[j]!=0) - continue; - r=sqrt(pow(cat->x[i]-ast->x[j],2)+pow(cat->y[i]-ast->y[j],2)); - if (flag==0 || rx[i]-img.x0,cat->y[i]-img.y0,ast->ra[jmin],ast->de[jmin]); - cat->select[i]=n+1; - ast->select[jmin]=n+1; - n++; - } - } - fclose(file); + for (i = 0; i < cat->n; i++) + cat->select[i] = 0; + for (i = 0; i < ast->n; i++) + ast->select[i] = 0; - printf("%d stars matched\n",n); + file = fopen ("out.dat", "w"); + for (i = 0, n = 0; i < cat->n; i++) + { + for (j = 0, flag = 0; j < ast->n; j++) + { + if (ast->select[j] != 0) + continue; + r = + sqrt (pow (cat->x[i] - ast->x[j], 2) + + pow (cat->y[i] - ast->y[j], 2)); + if (flag == 0 || r < rmin) + { + rmin = r; + jmin = j; + flag = 1; + } + } + if (rmin < rmax) + { + fprintf (file, "%10.4f %10.4f %10.6f %10.6f\n", cat->x[i] - img.x0, + cat->y[i] - img.y0, ast->ra[jmin], ast->de[jmin]); + cat->select[i] = n + 1; + ast->select[jmin] = n + 1; + n++; + } + } + fclose (file); + + printf ("%d stars matched\n", n); return n; } // Get observing site -void get_site(int site_id) +void +get_site (int site_id) { - int i=0; + int i = 0; char line[LIM]; FILE *file; int id; - double lat,lng; + double lat, lng; float alt; - char abbrev[3],observer[64],filename[LIM],*env; + char abbrev[3], observer[64], filename[LIM], *env; - env=getenv("ST_DATADIR"); - sprintf(filename,"%s/data/sites.txt",env); - file=fopen(filename,"r"); - if (file==NULL) { - printf("File with site information not found!\n"); - return; - } - while (fgets(line,LIM,file)!=NULL) { - // Skip - if (strstr(line,"#")!=NULL) - continue; - - // Strip newline - line[strlen(line)-1]='\0'; - - // Read data - sscanf(line,"%4d %2s %lf %lf %f", - &id,abbrev,&lat,&lng,&alt); - strcpy(observer,line+38); - - // Change to km - alt/=1000.0; - - if (id==site_id) { - m.lat=lat; - m.lng=lng; - m.alt=alt; - m.site_id=id; - strcpy(m.observer,observer); + env = getenv ("ST_DATADIR"); + sprintf (filename, "%s/data/sites.txt", env); + file = fopen (filename, "r"); + if (file == NULL) + { + printf ("File with site information not found!\n"); + return; } + while (fgets (line, LIM, file) != NULL) + { + // Skip + if (strstr (line, "#") != NULL) + continue; - } - fclose(file); + // Strip newline + line[strlen (line) - 1] = '\0'; + + // Read data + sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt); + strcpy (observer, line + 38); + + // Change to km + alt /= 1000.0; + + if (id == site_id) + { + m.lat = lat; + m.lng = lng; + m.alt = alt; + m.site_id = id; + strcpy (m.observer, observer); + } + + } + fclose (file); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { int i; - float tr[]={-0.5,1.0,0.0,-0.5,0.0,1.0}; - float heat_l[] = {0.0, 0.2, 0.4, 0.6, 1.0}; - float heat_r[] = {0.0, 0.5, 1.0, 1.0, 1.0}; - float heat_g[] = {0.0, 0.0, 0.5, 1.0, 1.0}; - float heat_b[] = {0.0, 0.0, 0.0, 0.3, 1.0}; - float x,y,r,rmin=1.0,rmax=10.0,mmin=5.0,mmax=10.0; - struct catalog cat,ast; + float tr[] = { -0.5, 1.0, 0.0, -0.5, 0.0, 1.0 }; + float heat_l[] = { 0.0, 0.2, 0.4, 0.6, 1.0 }; + float heat_r[] = { 0.0, 0.5, 1.0, 1.0, 1.0 }; + float heat_g[] = { 0.0, 0.0, 0.5, 1.0, 1.0 }; + float heat_b[] = { 0.0, 0.0, 0.0, 0.3, 1.0 }; + float x, y, r, rmin = 1.0, rmax = 10.0, mmin = 5.0, mmax = 10.0; + struct catalog cat, ast; char c; - int redraw=1,click=0,nselect=0,plotstars=1; - char filename[128],sra[20],sde[20]; - float h,q,s=0.0,mag=9; + int redraw = 1, click = 0, nselect = 0, plotstars = 1; + char filename[128], sra[20], sde[20]; + float h, q, s = 0.0, mag = 9; FILE *file; - char *env,starfile[128]; + char *env, starfile[128]; // Environment variables - env=getenv("ST_DATADIR"); - sprintf(starfile,"%s/data/tycho2.dat",env); + env = getenv ("ST_DATADIR"); + sprintf (starfile, "%s/data/tycho2.dat", env); // Geographic position - env=getenv("ST_COSPAR"); - get_site(atoi(env)); + env = getenv ("ST_COSPAR"); + get_site (atoi (env)); // Read image - img=read_fits(argv[1],0); - sprintf(filename,"%s.cat",argv[1]); + img = read_fits (argv[1], 0); + sprintf (filename, "%s.cat", argv[1]); - printf("Image read\n"); + printf ("Image read\n"); // Initial transformation - if (argc==7) { - s=atof(argv[2]); - img.ra0=atof(argv[3]); - img.de0=atof(argv[4]); - q=atof(argv[5]); - mag=atof(argv[6]); - } else { - file=fopen("position.txt","r"); - if (file==NULL) { - fprintf(stderr,"No position file found\n"); - return 0; + if (argc == 7) + { + s = atof (argv[2]); + img.ra0 = atof (argv[3]); + img.de0 = atof (argv[4]); + q = atof (argv[5]); + mag = atof (argv[6]); } - fscanf(file,"%s %s",sra,sde); - fclose(file); - - // Get parameters - img.ra0=15.0*s2dec(sra); - img.de0=s2dec(sde); + else + { + file = fopen ("position.txt", "r"); + if (file == NULL) + { + fprintf (stderr, "No position file found\n"); + return 0; + } + fscanf (file, "%s %s", sra, sde); + fclose (file); - // Hour angle - h=gmst(img.mjd)+m.lng-img.ra0; - q=atan2(sin(h*D2R),(tan(m.lat*D2R)*cos(img.de0*D2R)-sin(img.de0*D2R)*cos(h*D2R)))*R2D; - printf("Hour angle: %.3f deg, parallactic angle: %.3f deg\n",h,q); - } - img.x0=0.5*(float) img.naxis1; - img.y0=0.5*(float) img.naxis2; + // Get parameters + img.ra0 = 15.0 * s2dec (sra); + img.de0 = s2dec (sde); + + // Hour angle + h = gmst (img.mjd) + m.lng - img.ra0; + q = + atan2 (sin (h * D2R), + (tan (m.lat * D2R) * cos (img.de0 * D2R) - + sin (img.de0 * D2R) * cos (h * D2R))) * R2D; + printf ("Hour angle: %.3f deg, parallactic angle: %.3f deg\n", h, q); + } + img.x0 = 0.5 * (float) img.naxis1; + img.y0 = 0.5 * (float) img.naxis2; // Read catalogs - cat=read_pixel_catalog(filename); - if (s==0.0) - ast=read_astrometric_catalog(starfile,mag,-36.15,33.22,-q); + cat = read_pixel_catalog (filename); + if (s == 0.0) + ast = read_astrometric_catalog (starfile, mag, -36.15, 33.22, -q); else - ast=read_astrometric_catalog(starfile,mag,-s,s,-q); + ast = read_astrometric_catalog (starfile, mag, -s, s, -q); // Plot image - cpgopen("/xs"); - cpgwnad(0.0,img.naxis1,0.0,img.naxis2); - cpgsfs(2); - cpgctab (heat_l,heat_r,heat_g,heat_b,5,1.0,0.5); + cpgopen ("/xs"); + cpgwnad (0.0, img.naxis1, 0.0, img.naxis2); + cpgsfs (2); + cpgctab (heat_l, heat_r, heat_g, heat_b, 5, 1.0, 0.5); // For ever loop - for (;;) { - if (redraw==1) { - cpgimag(img.z,img.naxis1,img.naxis2,1,img.naxis1,1,img.naxis2,img.zmin,img.zmax,tr); - cpgbox("BCTSNI",0.,0,"BCTSNI",0.,0); - - // Plot catalogs - if (plotstars==1) { - cpgsci(3); - for (i=0;i= 3) + { + fit_transformation (cat, ast, nselect); + ast = reread_astrometric_catalog (starfile, mag + 1); + redraw = 1; + } + + // Reread + if (c == 'r') + { + ast = reread_astrometric_catalog (starfile, mag + 1); + redraw = 1; + } + + // Select pixel catalog + if (c == 'a' && click == 0) + { + i = select_nearest (cat, x, y); + cat.select[i] = nselect + 1; + redraw = 1; + click = 1; + } + + // Select catalog + if (c == 'b' && click == 1) + { + i = select_nearest (ast, x, y); + ast.select[i] = nselect + 1; + redraw = 1; + click = 0; + nselect++; + } + + // + if (c == 'p') + { + if (plotstars == 1) + plotstars = 0; + else if (plotstars == 0) + plotstars = 1; + redraw = 1; + } + + // Match catalogs + if (c == 'm') + { + nselect = match_catalogs (&cat, &ast, 10.0); + redraw = 1; + } } - - cpgcurs(&x,&y,&c); - - // Quit - if (c=='q') - break; - - // Fit - if (c=='f' && nselect>=3) { - fit_transformation(cat,ast,nselect); - ast=reread_astrometric_catalog(starfile,mag+1); - redraw=1; - } - - // Reread - if (c=='r') { - ast=reread_astrometric_catalog(starfile,mag+1); - redraw=1; - } - - // Select pixel catalog - if (c=='a' && click==0) { - i=select_nearest(cat,x,y); - cat.select[i]=nselect+1; - redraw=1; - click=1; - } - - // Select catalog - if (c=='b' && click==1) { - i=select_nearest(ast,x,y); - ast.select[i]=nselect+1; - redraw=1; - click=0; - nselect++; - } - - // - if (c=='p') { - if (plotstars==1) - plotstars=0; - else if (plotstars==0) - plotstars=1; - redraw=1; - } - - // Match catalogs - if (c=='m') { - nselect=match_catalogs(&cat,&ast,10.0); - redraw=1; - } - } - cpgend(); + cpgend (); return 0; } // Read fits image -struct image read_fits(char *filename,int pnum) +struct image +read_fits (char *filename, int pnum) { - int i,j,k,l,m; + int i, j, k, l, m; qfitsloader ql; - char key[FITS_LINESZ+1] ; + char key[FITS_LINESZ + 1]; struct image img; - double s1,s2,avg,std; + double s1, s2, avg, std; // Set plane ql.xtnum = 0; @@ -456,52 +514,56 @@ struct image read_fits(char *filename,int pnum) ql.ptype = PTYPE_FLOAT; // Set filename - ql.filename=filename; + ql.filename = filename; // Image size - img.naxis1=atoi(qfits_query_hdr(filename,"NAXIS1")); - img.naxis2=atoi(qfits_query_hdr(filename,"NAXIS2")); - img.mjd=atof(qfits_query_hdr(filename,"MJD-OBS")); + img.naxis1 = atoi (qfits_query_hdr (filename, "NAXIS1")); + img.naxis2 = atoi (qfits_query_hdr (filename, "NAXIS2")); + img.mjd = atof (qfits_query_hdr (filename, "MJD-OBS")); // Initialize load - if (qfitsloader_init(&ql) != 0) - printf("Error initializing data loading\n"); + if (qfitsloader_init (&ql) != 0) + printf ("Error initializing data loading\n"); // Test load - if (qfits_loadpix(&ql) != 0) - printf("Error loading actual data\n"); + if (qfits_loadpix (&ql) != 0) + printf ("Error loading actual data\n"); // Allocate image memory - img.z=(float *) malloc(sizeof(float) * img.naxis1*img.naxis2); + img.z = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2); // Fill z array - for (i=0,l=0,m=0;i 0 && (c=fgetc(file)) != EOF && c != '\n') + int c, i = 0; + + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; @@ -511,152 +573,166 @@ int fgetline(FILE *file,char *s,int lim) // Linear 2D fit -void lfit2d(float *x,float *y,float *z,int n,float *a) +void +lfit2d (float *x, float *y, float *z, int n, float *a) { int i; double chisq; - gsl_matrix *X,*cov; - gsl_vector *yy,*w,*c; + gsl_matrix *X, *cov; + gsl_vector *yy, *w, *c; - X=gsl_matrix_alloc(n,3); - yy=gsl_vector_alloc(n); - w=gsl_vector_alloc(n); + X = gsl_matrix_alloc (n, 3); + yy = gsl_vector_alloc (n); + w = gsl_vector_alloc (n); - c=gsl_vector_alloc(3); - cov=gsl_matrix_alloc(3,3); + c = gsl_vector_alloc (3); + cov = gsl_matrix_alloc (3, 3); // Fill matrices - for(i=0;i0) { - if (strstr(line,"#")!=NULL) - continue; - sscanf(line,"%f %f %f",&c.x[i],&c.y[i],&c.mag[i]); - c.select[i]=0; - i++; - } - fclose(file); - c.n=i; + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "%s not found!\n", filename); + exit (0); + } + while (fgetline (file, line, LIM) > 0) + { + if (strstr (line, "#") != NULL) + continue; + sscanf (line, "%f %f %f", &c.x[i], &c.y[i], &c.mag[i]); + c.select[i] = 0; + i++; + } + fclose (file); + c.n = i; return c; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Precess a celestial position -void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de) +void +precess (double mjd0, double ra0, double de0, double mjd, double *ra, + double *de) { - double t0,t; - double zeta,z,theta; - double a,b,c; + double t0, t; + double zeta, z, theta; + double a, b, c; // Angles in radians - ra0*=D2R; - de0*=D2R; + ra0 *= D2R; + de0 *= D2R; // Time in centuries - t0=(mjd0-51544.5)/36525.0; - t=(mjd-mjd0)/36525.0; + t0 = (mjd0 - 51544.5) / 36525.0; + t = (mjd - mjd0) / 36525.0; // Precession angles - zeta=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - zeta+=(0.30188-0.000344*t0)*t*t+0.017998*t*t*t; - zeta*=D2R/3600.0; - z=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - z+=(1.09468+0.000066*t0)*t*t+0.018203*t*t*t; - z*=D2R/3600.0; - theta=(2004.3109-0.85330*t0-0.000217*t0*t0)*t; - theta+=-(0.42665+0.000217*t0)*t*t-0.041833*t*t*t; - theta*=D2R/3600.0; + zeta = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + zeta += (0.30188 - 0.000344 * t0) * t * t + 0.017998 * t * t * t; + zeta *= D2R / 3600.0; + z = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + z += (1.09468 + 0.000066 * t0) * t * t + 0.018203 * t * t * t; + z *= D2R / 3600.0; + theta = (2004.3109 - 0.85330 * t0 - 0.000217 * t0 * t0) * t; + theta += -(0.42665 + 0.000217 * t0) * t * t - 0.041833 * t * t * t; + theta *= D2R / 3600.0; - a=cos(de0)*sin(ra0+zeta); - b=cos(theta)*cos(de0)*cos(ra0+zeta)-sin(theta)*sin(de0); - c=sin(theta)*cos(de0)*cos(ra0+zeta)+cos(theta)*sin(de0); + a = cos (de0) * sin (ra0 + zeta); + b = cos (theta) * cos (de0) * cos (ra0 + zeta) - sin (theta) * sin (de0); + c = sin (theta) * cos (de0) * cos (ra0 + zeta) + cos (theta) * sin (de0); - *ra=(atan2(a,b)+z)*R2D; - *de=asin(c)*R2D; + *ra = (atan2 (a, b) + z) * R2D; + *de = asin (c) * R2D; - if (*ra<360.0) - *ra+=360.0; - if (*ra>360.0) - *ra-=360.0; + if (*ra < 360.0) + *ra += 360.0; + if (*ra > 360.0) + *ra -= 360.0; return; } // Convert Sexagesimal into Decimal -double s2dec(char *s) +double +s2dec (char *s) { double x; - float deg,min,sec; + float deg, min, sec; char t[LIM]; - strcpy(t,s); + strcpy (t, s); - deg=fabs(atof(strtok(t," :"))); - min=fabs(atof(strtok(NULL," :"))); - sec=fabs(atof(strtok(NULL," :"))); + deg = fabs (atof (strtok (t, " :"))); + min = fabs (atof (strtok (NULL, " :"))); + sec = fabs (atof (strtok (NULL, " :"))); - x=(double) deg+(double) min/60.+(double) sec/3600.; - if (s[0]=='-') x= -x; + x = (double) deg + (double) min / 60. + (double) sec / 3600.; + if (s[0] == '-') + x = -x; return x; } diff --git a/src/posmatch.c b/src/posmatch.c index 69635dc..aa3db72 100644 --- a/src/posmatch.c +++ b/src/posmatch.c @@ -9,26 +9,28 @@ #define LIM 80 // Cross product -xyz_t cross(xyz_t a,xyz_t b) +xyz_t +cross (xyz_t a, xyz_t b) { xyz_t c; - c.x=a.y*b.z-a.z*b.y; - c.y=a.z*b.x-a.x*b.z; - c.z=a.x*b.y-a.y*b.x; + c.x = a.y * b.z - a.z * b.y; + c.y = a.z * b.x - a.x * b.z; + c.z = a.x * b.y - a.y * b.x; return c; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; + int c, i = 0; - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\t') - c=' '; + c = ' '; if (c == '\n') s[i++] = c; s[i] = '\0'; @@ -36,140 +38,160 @@ int fgetline(FILE *file,char *s,int lim) } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // DOY to MJD -double doy2mjd(int year,double doy) +double +doy2mjd (int year, double doy) { - int month,k=2; + int month, k = 2; double day; - if (year%4==0 && year%400!=0) - k=1; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - month=floor(9.0*(k+doy)/275.0+0.98); - - if (doy<32) - month=1; + month = floor (9.0 * (k + doy) / 275.0 + 0.98); - day=doy-floor(275.0*month/9.0)+k*floor((month+9.0)/12.0)+30.0; + if (doy < 32) + month = 1; - return date2mjd(year,month,day); + day = + doy - floor (275.0 * month / 9.0) + k * floor ((month + 9.0) / 12.0) + + 30.0; + + return date2mjd (year, month, day); } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int i,arg=0,imode,n=100,satno,satname,satno2,imin,flag,status; - char catalog1[]="20180121_173045_catalog.txt",catalog2[]="jsc_20180122.txt"; - FILE *file1,*file2; - orbit_t orb1,orb2; - double mjd0=58140.0,mjd; - xyz_t *r,*v,r0,v0,d,n1,n2; - double dr,dv,dn,drmin,dvmin,mjdmin; - char line0[LIM],line1[LIM],line2[LIM]; + int i, arg = 0, imode, n = 100, satno, satname, satno2, imin, flag, status; + char catalog1[] = "20180121_173045_catalog.txt", catalog2[] = + "jsc_20180122.txt"; + FILE *file1, *file2; + orbit_t orb1, orb2; + double mjd0 = 58140.0, mjd; + xyz_t *r, *v, r0, v0, d, n1, n2; + double dr, dv, dn, drmin, dvmin, mjdmin; + char line0[LIM], line1[LIM], line2[LIM]; // Reroute stderr - freopen("/tmp/stderr.txt","w",stderr); + freopen ("/tmp/stderr.txt", "w", stderr); // Allocate - r=(xyz_t *) malloc(sizeof(xyz_t)*n); - v=(xyz_t *) malloc(sizeof(xyz_t)*n); + r = (xyz_t *) malloc (sizeof (xyz_t) * n); + v = (xyz_t *) malloc (sizeof (xyz_t) * n); // Open file - file1=fopen(catalog1,"r"); - file2=fopen(catalog2,"r"); + file1 = fopen (catalog1, "r"); + file2 = fopen (catalog2, "r"); // Loop over classfd catalog - while (read_twoline(file1,0,&orb1)==0) { - // Compute positions - imode=init_sgdp4(&orb1); - for (i=0;i 0) + { + fgetline (file2, line1, LIM); + fgetline (file2, line2, LIM); + sscanf (line1, "1 %d", &satno2); + if (satno == satno2) + { + sscanf (line0, "SO %d", &satname); + } + } + + // printf("%05d %05d %8.2f km %9.5f km/s %6.0lf s %8.0f km\n",orb1.satno,satno,drmin,dvmin,(mjd0+(double) imin/86400.0-mjd)*86400,dn); + printf ("%6d %05d %s | %5d %8.2f km %9.5f km/s %6.0lf s %8.0f km\n", + satname, orb1.satno, orb1.desig, satno, drmin, dvmin, + (mjd0 + (double) imin / 86400.0 - mjd) * 86400, dn); } - - // Compute normals - rewind(file2); - read_twoline(file2,satno,&orb2); - mjd=doy2mjd(orb2.ep_year,orb2.ep_day); - imode=init_sgdp4(&orb2); - satpos_xyz(mjd+2400000.5,&r0,&v0); - n1=cross(r[0],v[0]); - n2=cross(r0,v0); - d.x=n1.x-n2.x; - d.y=n1.y-n2.y; - d.z=n1.z-n2.z; - dn=sqrt(d.x*d.x+d.y*d.y+d.z*d.z); - - // Find object name - rewind(file2); - while (fgetline(file2,line0,LIM)>0) { - fgetline(file2,line1,LIM); - fgetline(file2,line2,LIM); - sscanf(line1,"1 %d",&satno2); - if (satno==satno2) { - sscanf(line0,"SO %d",&satname); - } - } - - // printf("%05d %05d %8.2f km %9.5f km/s %6.0lf s %8.0f km\n",orb1.satno,satno,drmin,dvmin,(mjd0+(double) imin/86400.0-mjd)*86400,dn); - printf("%6d %05d %s | %5d %8.2f km %9.5f km/s %6.0lf s %8.0f km\n",satname,orb1.satno,orb1.desig,satno,drmin,dvmin,(mjd0+(double) imin/86400.0-mjd)*86400,dn); - } - fclose(file1); - fclose(file2); + fclose (file1); + fclose (file2); // Free - free(r); - free(v); + free (r); + free (v); return 0; } diff --git a/src/posvel.c b/src/posvel.c index 995c5cc..f269121 100644 --- a/src/posvel.c +++ b/src/posvel.c @@ -8,7 +8,7 @@ #include #define LIM 128 -#define XKE 0.07436680 // Guassian Gravitational Constant +#define XKE 0.07436680 // Guassian Gravitational Constant #define XKMPER 6378.135 #define AE 1.0 #define XMNPDA 1440.0 @@ -19,191 +19,214 @@ extern double SGDP4_jd0; // Compute Date from Julian Day -void mjd2date(double mjd,int *year,int *month,double *day) +void +mjd2date (double mjd, int *year, int *month, double *day) { - double f,jd; - int z,alpha,a,b,c,d,e; + double f, jd; + int z, alpha, a, b, c, d, e; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - *day=b-d-floor(30.6001*e)+f; - if (e<14) - *month=e-1; + if (z < 2299161) + a = z; else - *month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (*month>2) - *year=c-4716; + *day = b - d - floor (30.6001 * e) + f; + if (e < 14) + *month = e - 1; else - *year=c-4715; + *month = e - 13; + + if (*month > 2) + *year = c - 4716; + else + *year = c - 4715; return; } // MJD to DOY -double mjd2doy(double mjd,int *yr) +double +mjd2doy (double mjd, int *yr) { - int year,month,k=2; - double day,doy; - - mjd2date(mjd,&year,&month,&day); + int year, month, k = 2; + double day, doy; - if (year%4==0 && year%400!=0) - k=1; + mjd2date (mjd, &year, &month, &day); - doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - *yr=year; + doy = + floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30; + + *yr = year; return doy; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min,sec; - double mjd,dday; + int year, month, day, hour, min, sec; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; - mjd=date2mjd(year,month,dday); + mjd = date2mjd (year, month, dday); return mjd; } // Present nfd -void nfd_now(char *s) +void +nfd_now (char *s) { time_t rawtime; struct tm *ptm; // Get UTC time - time(&rawtime); - ptm=gmtime(&rawtime); - - sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec); - + time (&rawtime); + ptm = gmtime (&rawtime); + + sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900, + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, + ptm->tm_sec); + return; } -void usage(void) +void +usage (void) { - printf("propagate c:i:t:m:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n"); + printf + ("propagate c:i:t:m:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n"); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int imode,satno=0,arg,i; + int imode, satno = 0, arg, i; FILE *file; orbit_t orb; - xyz_t r,v; - char tlefile[LIM],nfd[32]; + xyz_t r, v; + char tlefile[LIM], nfd[32]; char *env; double mjd; - int length=3600,dl=60; + int length = 3600, dl = 60; // Get environment variable - env=getenv("ST_TLEDIR"); - sprintf(tlefile,"%s/classfd.tle",env); + env = getenv ("ST_TLEDIR"); + sprintf (tlefile, "%s/classfd.tle", env); // Set date - nfd_now(nfd); - mjd=nfd2mjd(nfd); + nfd_now (nfd); + mjd = nfd2mjd (nfd); // Decode options - while ((arg=getopt(argc,argv,"c:i:t:l:d:"))!=-1) { - switch (arg) { + while ((arg = getopt (argc, argv, "c:i:t:l:d:")) != -1) + { + switch (arg) + { - case 't': - strcpy(nfd,optarg); - mjd=nfd2mjd(nfd); - break; - - case 'c': - strcpy(tlefile,optarg); - break; + case 't': + strcpy (nfd, optarg); + mjd = nfd2mjd (nfd); + break; - case 'i': - satno=atoi(optarg); - break; + case 'c': + strcpy (tlefile, optarg); + break; - case 'l': - length=atoi(optarg); - break; + case 'i': + satno = atoi (optarg); + break; - case 'd': - dl=atoi(optarg); - break; + case 'l': + length = atoi (optarg); + break; - case 'h': - usage(); - return 0; - break; + case 'd': + dl = atoi (optarg); + break; - default: - usage(); - return 0; + case 'h': + usage (); + return 0; + break; + + default: + usage (); + return 0; + } } - } // Reloop stderr - freopen("/tmp/stderr.txt","w",stderr); + freopen ("/tmp/stderr.txt", "w", stderr); // Open file - file=fopen(tlefile,"r"); - while (read_twoline(file,satno,&orb)==0) { - // Propagate - imode=init_sgdp4(&orb); + file = fopen (tlefile, "r"); + while (read_twoline (file, satno, &orb) == 0) + { + // Propagate + imode = init_sgdp4 (&orb); - for (i=0;i #define LIM 128 -#define XKE 0.07436680 // Guassian Gravitational Constant +#define XKE 0.07436680 // Guassian Gravitational Constant #define XKMPER 6378.135 #define AE 1.0 #define XMNPDA 1440.0 @@ -18,431 +18,479 @@ extern double SGDP4_jd0; // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Dot product -float dot(xyz_t a,xyz_t b) +float +dot (xyz_t a, xyz_t b) { - return a.x*b.x+a.y*b.y+a.z*b.z; + return a.x * b.x + a.y * b.y + a.z * b.z; } // Magnitude -double magnitude(xyz_t a) +double +magnitude (xyz_t a) { - return sqrt(dot(a,a)); + return sqrt (dot (a, a)); } // Cross product -xyz_t cross(xyz_t a,xyz_t b) +xyz_t +cross (xyz_t a, xyz_t b) { xyz_t c; - c.x=a.y*b.z-a.z*b.y; - c.y=a.z*b.x-a.x*b.z; - c.z=a.x*b.y-a.y*b.x; + c.x = a.y * b.z - a.z * b.y; + c.y = a.z * b.x - a.x * b.z; + c.z = a.x * b.y - a.y * b.x; return c; } // Compute Date from Julian Day -void mjd2date(double mjd,int *year,int *month,double *day) +void +mjd2date (double mjd, int *year, int *month, double *day) { - double f,jd; - int z,alpha,a,b,c,d,e; + double f, jd; + int z, alpha, a, b, c, d, e; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - *day=b-d-floor(30.6001*e)+f; - if (e<14) - *month=e-1; + if (z < 2299161) + a = z; else - *month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (*month>2) - *year=c-4716; + *day = b - d - floor (30.6001 * e) + f; + if (e < 14) + *month = e - 1; else - *year=c-4715; + *month = e - 13; + + if (*month > 2) + *year = c - 4716; + else + *year = c - 4715; return; } // MJD to DOY -double mjd2doy(double mjd,int *yr) +double +mjd2doy (double mjd, int *yr) { - int year,month,k=2; - double day,doy; - - mjd2date(mjd,&year,&month,&day); + int year, month, k = 2; + double day, doy; - if (year%4==0 && year%400!=0) - k=1; + mjd2date (mjd, &year, &month, &day); - doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - *yr=year; + doy = + floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30; + + *yr = year; return doy; } // Clasical elements -orbit_t classel(int ep_year,double ep_day,xyz_t r,xyz_t v) +orbit_t +classel (int ep_year, double ep_day, xyz_t r, xyz_t v) { int i; - double rm,vm,vm2,rvm,mu=1.0;; - double chi,xp,yp,sx,cx,b,ee; - double a,ecc,incl,node,peri,mm,n; - xyz_t h,e,kk,nn; + double rm, vm, vm2, rvm, mu = 1.0;; + double chi, xp, yp, sx, cx, b, ee; + double a, ecc, incl, node, peri, mm, n; + xyz_t h, e, kk, nn; orbit_t orb; - r.x/=XKMPER; - r.y/=XKMPER; - r.z/=XKMPER; - v.x/=(XKE*XKMPER/AE*XMNPDA/86400.0); - v.y/=(XKE*XKMPER/AE*XMNPDA/86400.0); - v.z/=(XKE*XKMPER/AE*XMNPDA/86400.0); + r.x /= XKMPER; + r.y /= XKMPER; + r.z /= XKMPER; + v.x /= (XKE * XKMPER / AE * XMNPDA / 86400.0); + v.y /= (XKE * XKMPER / AE * XMNPDA / 86400.0); + v.z /= (XKE * XKMPER / AE * XMNPDA / 86400.0); - rm=magnitude(r); - vm2=dot(v,v); - rvm=dot(r,v); - h=cross(r,v); - chi=dot(h,h)/mu; + rm = magnitude (r); + vm2 = dot (v, v); + rvm = dot (r, v); + h = cross (r, v); + chi = dot (h, h) / mu; - e.x=(vm2/mu-1.0/rm)*r.x-rvm/mu*v.x; - e.y=(vm2/mu-1.0/rm)*r.y-rvm/mu*v.y; - e.z=(vm2/mu-1.0/rm)*r.z-rvm/mu*v.z; + e.x = (vm2 / mu - 1.0 / rm) * r.x - rvm / mu * v.x; + e.y = (vm2 / mu - 1.0 / rm) * r.y - rvm / mu * v.y; + e.z = (vm2 / mu - 1.0 / rm) * r.z - rvm / mu * v.z; - a=pow(2.0/rm-vm2/mu,-1); - ecc=magnitude(e); - incl=acos(h.z/magnitude(h))*R2D; - - kk.x=0.0; - kk.y=0.0; - kk.z=1.0; - nn=cross(kk,h); - if (nn.x==0.0 && nn.y==0.0) - nn.x=1.0; - node=atan2(nn.y,nn.x)*R2D; - if (node<0.0) - node+=360.0; + a = pow (2.0 / rm - vm2 / mu, -1); + ecc = magnitude (e); + incl = acos (h.z / magnitude (h)) * R2D; - peri=acos(dot(nn,e)/(magnitude(nn)*ecc))*R2D; - if (e.z<0.0) - peri=360.0-peri; - if (peri<0.0) - peri+=360.0; + kk.x = 0.0; + kk.y = 0.0; + kk.z = 1.0; + nn = cross (kk, h); + if (nn.x == 0.0 && nn.y == 0.0) + nn.x = 1.0; + node = atan2 (nn.y, nn.x) * R2D; + if (node < 0.0) + node += 360.0; + + peri = acos (dot (nn, e) / (magnitude (nn) * ecc)) * R2D; + if (e.z < 0.0) + peri = 360.0 - peri; + if (peri < 0.0) + peri += 360.0; // Elliptic motion - if (ecc<1.0) { - xp=(chi-rm)/ecc; - yp=rvm/ecc*sqrt(chi/mu); - b=a*sqrt(1.0-ecc*ecc); - cx=xp/a+ecc; - sx=yp/b; - ee=atan2(sx,cx); - n=XKE*sqrt(mu/(a*a*a)); - mm=(ee-ecc*sx)*R2D; - } - if (mm<0.0) - mm+=360.0; + if (ecc < 1.0) + { + xp = (chi - rm) / ecc; + yp = rvm / ecc * sqrt (chi / mu); + b = a * sqrt (1.0 - ecc * ecc); + cx = xp / a + ecc; + sx = yp / b; + ee = atan2 (sx, cx); + n = XKE * sqrt (mu / (a * a * a)); + mm = (ee - ecc * sx) * R2D; + } + if (mm < 0.0) + mm += 360.0; // Fill - orb.satno=0; - orb.eqinc=incl*D2R; - orb.ascn=node*D2R; - orb.argp=peri*D2R; - orb.mnan=mm*D2R; - orb.ecc=ecc; - orb.rev=XKE*pow(a,-3.0/2.0)*XMNPDA/(2.0*M_PI); - orb.bstar=0.0; - orb.ep_year=ep_year; - orb.ep_day=ep_day; - orb.norb=0; + orb.satno = 0; + orb.eqinc = incl * D2R; + orb.ascn = node * D2R; + orb.argp = peri * D2R; + orb.mnan = mm * D2R; + orb.ecc = ecc; + orb.rev = XKE * pow (a, -3.0 / 2.0) * XMNPDA / (2.0 * M_PI); + orb.bstar = 0.0; + orb.ep_year = ep_year; + orb.ep_day = ep_day; + orb.norb = 0; return orb; } -orbit_t rv2el(int satno,double mjd,xyz_t r0,xyz_t v0) +orbit_t +rv2el (int satno, double mjd, xyz_t r0, xyz_t v0) { - int i,imode; - orbit_t orb[5],orb1[5]; - xyz_t r,v; + int i, imode; + orbit_t orb[5], orb1[5]; + xyz_t r, v; kep_t kep; - char line1[70],line2[70]; + char line1[70], line2[70]; int ep_year; double ep_day; // Epoch - ep_day=mjd2doy(mjd,&ep_year); + ep_day = mjd2doy (mjd, &ep_year); // Initial guess - orb[0]=classel(ep_year,ep_day,r0,v0); - orb[0].satno=satno; - - for (i=0;i<4;i++) { - // Propagate - imode=init_sgdp4(&orb[i]); - imode=satpos_xyz(mjd+2400000.5,&r,&v); + orb[0] = classel (ep_year, ep_day, r0, v0); + orb[0].satno = satno; - // Compute initial orbital elements - orb1[i]=classel(ep_year,ep_day,r,v); + for (i = 0; i < 4; i++) + { + // Propagate + imode = init_sgdp4 (&orb[i]); + imode = satpos_xyz (mjd + 2400000.5, &r, &v); - // Adjust - orb[i+1].rev=orb[i].rev+orb[0].rev-orb1[i].rev; - orb[i+1].ascn=orb[i].ascn+orb[0].ascn-orb1[i].ascn; - orb[i+1].argp=orb[i].argp+orb[0].argp-orb1[i].argp; - orb[i+1].mnan=orb[i].mnan+orb[0].mnan-orb1[i].mnan; - orb[i+1].eqinc=orb[i].eqinc+orb[0].eqinc-orb1[i].eqinc; - orb[i+1].ecc=orb[i].ecc+orb[0].ecc-orb1[i].ecc; - orb[i+1].ep_year=orb[i].ep_year; - orb[i+1].ep_day=orb[i].ep_day; - orb[i+1].satno=orb[i].satno; - orb[i+1].norb=orb[i].norb; - orb[i+1].bstar=orb[i].bstar; + // Compute initial orbital elements + orb1[i] = classel (ep_year, ep_day, r, v); - // Keep in range - if (orb[i+1].ecc<0.0) - orb[i+1].ecc=0.0; - if (orb[i+1].eqinc<0.0) - orb[i+1].eqinc=0.0; - } + // Adjust + orb[i + 1].rev = orb[i].rev + orb[0].rev - orb1[i].rev; + orb[i + 1].ascn = orb[i].ascn + orb[0].ascn - orb1[i].ascn; + orb[i + 1].argp = orb[i].argp + orb[0].argp - orb1[i].argp; + orb[i + 1].mnan = orb[i].mnan + orb[0].mnan - orb1[i].mnan; + orb[i + 1].eqinc = orb[i].eqinc + orb[0].eqinc - orb1[i].eqinc; + orb[i + 1].ecc = orb[i].ecc + orb[0].ecc - orb1[i].ecc; + orb[i + 1].ep_year = orb[i].ep_year; + orb[i + 1].ep_day = orb[i].ep_day; + orb[i + 1].satno = orb[i].satno; + orb[i + 1].norb = orb[i].norb; + orb[i + 1].bstar = orb[i].bstar; - orb[i].mnan=modulo(orb[i].mnan,2.0*M_PI); - orb[i].ascn=modulo(orb[i].ascn,2.0*M_PI); - orb[i].argp=modulo(orb[i].argp,2.0*M_PI); + // Keep in range + if (orb[i + 1].ecc < 0.0) + orb[i + 1].ecc = 0.0; + if (orb[i + 1].eqinc < 0.0) + orb[i + 1].eqinc = 0.0; + } + + orb[i].mnan = modulo (orb[i].mnan, 2.0 * M_PI); + orb[i].ascn = modulo (orb[i].ascn, 2.0 * M_PI); + orb[i].argp = modulo (orb[i].argp, 2.0 * M_PI); return orb[i]; } // Format TLE -void format_tle(orbit_t orb,char *line1,char *line2) +void +format_tle (orbit_t orb, char *line1, char *line2) { - int i,csum; - char sbstar[]=" 00000-0",bstar[13]; + int i, csum; + char sbstar[] = " 00000-0", bstar[13]; // Format Bstar term - if (fabs(orb.bstar)>1e-9) { - sprintf(bstar,"%11.4e",10*orb.bstar); - sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4]; - sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0'; - } + if (fabs (orb.bstar) > 1e-9) + { + sprintf (bstar, "%11.4e", 10 * orb.bstar); + sbstar[0] = bstar[0]; + sbstar[1] = bstar[1]; + sbstar[2] = bstar[3]; + sbstar[3] = bstar[4]; + sbstar[4] = bstar[5]; + sbstar[5] = bstar[6]; + sbstar[6] = bstar[8]; + sbstar[7] = bstar[10]; + sbstar[8] = '\0'; + } // Print lines - sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar); - sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev); + sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0", + orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar); + sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0", + orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc, + DEG (orb.argp), DEG (orb.mnan), orb.rev); // Compute checksums - for (i=0,csum=0;itm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec); - + time (&rawtime); + ptm = gmtime (&rawtime); + + sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900, + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, + ptm->tm_sec); + return; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // DOY to MJD -double doy2mjd(int year,double doy) +double +doy2mjd (int year, double doy) { - int month,k=2; + int month, k = 2; double day; - if (year%4==0 && year%400!=0) - k=1; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - month=floor(9.0*(k+doy)/275.0+0.98); - - if (doy<32) - month=1; + month = floor (9.0 * (k + doy) / 275.0 + 0.98); - day=doy-floor(275.0*month/9.0)+k*floor((month+9.0)/12.0)+30.0; + if (doy < 32) + month = 1; - return date2mjd(year,month,day); + day = + doy - floor (275.0 * month / 9.0) + k * floor ((month + 9.0) / 12.0) + + 30.0; + + return date2mjd (year, month, day); } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min,sec; - double mjd,dday; + int year, month, day, hour, min, sec; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; - mjd=date2mjd(year,month,dday); + mjd = date2mjd (year, month, dday); return mjd; } -void usage(void) +void +usage (void) { - printf("propagate c:i:t:m:e:d:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n-e New epoch (YYDDD.ddddddd)\n-d New COSPAR designation\n"); + printf + ("propagate c:i:t:m:e:d:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n-e New epoch (YYDDD.ddddddd)\n-d New COSPAR designation\n"); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int imode,satno=0,arg,desigflag=0; + int imode, satno = 0, arg, desigflag = 0; FILE *file; orbit_t orb; - xyz_t r,v; - char tlefile[LIM],nfd[32]; - char line1[80],line2[80],desig[20]; - double mjd,epoch,ep_day,bstar; + xyz_t r, v; + char tlefile[LIM], nfd[32]; + char line1[80], line2[80], desig[20]; + double mjd, epoch, ep_day, bstar; char *env; int ep_year; // Get environment variable - env=getenv("ST_TLEDIR"); - sprintf(tlefile,"%s/classfd.tle",env); + env = getenv ("ST_TLEDIR"); + sprintf (tlefile, "%s/classfd.tle", env); // Set date - nfd_now(nfd); - mjd=nfd2mjd(nfd); + nfd_now (nfd); + mjd = nfd2mjd (nfd); // Decode options - while ((arg=getopt(argc,argv,"c:i:t:m:he:d:"))!=-1) { - switch (arg) { + while ((arg = getopt (argc, argv, "c:i:t:m:he:d:")) != -1) + { + switch (arg) + { - case 't': - strcpy(nfd,optarg); - mjd=nfd2mjd(nfd); - break; + case 't': + strcpy (nfd, optarg); + mjd = nfd2mjd (nfd); + break; - case 'e': - epoch=(double) atof(optarg); - ep_year=(int) floor(epoch/1000.0); - ep_day=epoch-1000*ep_year; - printf("%d %f\n",ep_year,ep_day); - if (ep_year<50) - ep_year+=2000; - else - ep_year+=1900; - - mjd=doy2mjd(ep_year,ep_day); - break; + case 'e': + epoch = (double) atof (optarg); + ep_year = (int) floor (epoch / 1000.0); + ep_day = epoch - 1000 * ep_year; + printf ("%d %f\n", ep_year, ep_day); + if (ep_year < 50) + ep_year += 2000; + else + ep_year += 1900; - case 'd': - strcpy(desig,optarg); - desigflag=1; - break; - - case 'm': - mjd=(double) atof(optarg); - break; - - case 'c': - strcpy(tlefile,optarg); - break; + mjd = doy2mjd (ep_year, ep_day); + break; - case 'i': - satno=atoi(optarg); - break; + case 'd': + strcpy (desig, optarg); + desigflag = 1; + break; - case 'h': - usage(); - return 0; - break; + case 'm': + mjd = (double) atof (optarg); + break; - default: - usage(); - return 0; + case 'c': + strcpy (tlefile, optarg); + break; + + case 'i': + satno = atoi (optarg); + break; + + case 'h': + usage (); + return 0; + break; + + default: + usage (); + return 0; + } } - } // Open file - file=fopen(tlefile,"r"); - while (read_twoline(file,satno,&orb)==0) { - format_tle(orb,line1,line2); - // printf("Input:\n%s\n%s\n",line1,line2); - if (desigflag==0) - strcpy(desig,orb.desig); - bstar=orb.bstar; - - // Propagate - imode=init_sgdp4(&orb); - imode=satpos_xyz(mjd+2400000.5,&r,&v); - - // Convert - orb=rv2el(orb.satno,mjd,r,v); + file = fopen (tlefile, "r"); + while (read_twoline (file, satno, &orb) == 0) + { + format_tle (orb, line1, line2); + // printf("Input:\n%s\n%s\n",line1,line2); + if (desigflag == 0) + strcpy (desig, orb.desig); + bstar = orb.bstar; - // Copy back - strcpy(orb.desig,desig); - orb.bstar=bstar; + // Propagate + imode = init_sgdp4 (&orb); + imode = satpos_xyz (mjd + 2400000.5, &r, &v); - format_tle(orb,line1,line2); - printf("%s\n%s\n",line1,line2); - } - fclose(file); + // Convert + orb = rv2el (orb.satno, mjd, r, v); + + // Copy back + strcpy (orb.desig, desig); + orb.bstar = bstar; + + format_tle (orb, line1, line2); + printf ("%s\n%s\n", line1, line2); + } + fclose (file); return 0; } diff --git a/src/pstrack.c b/src/pstrack.c index fac43cb..301d706 100644 --- a/src/pstrack.c +++ b/src/pstrack.c @@ -11,678 +11,755 @@ #define NMAX 256 #define D2R M_PI/180.0 #define R2D 180.0/M_PI -#define XKMPER 6378.135 // Earth radius in km -#define XKMPAU 149597879.691 // AU in km +#define XKMPER 6378.135 // Earth radius in km +#define XKMPAU 149597879.691 // AU in km #define FLAT (1.0/298.257) #define STDMAG 6.0 #define MMAX 10 -long Isat=0; -long Isatsel=0; +long Isat = 0; +long Isatsel = 0; extern double SGDP4_jd0; -struct map { - double lat,lng; +struct map +{ + double lat, lng; float alt; char observer[32]; int site_id; } m; -struct image { +struct image +{ char filename[64]; - int naxis1,naxis2,naxis3,nframes; - float *zavg,*zstd,*zmax,*znum,*zd; - double ra0,de0; - float x0,y0; - float a[3],b[3],xrms,yrms; + int naxis1, naxis2, naxis3, nframes; + float *zavg, *zstd, *zmax, *znum, *zd; + double ra0, de0; + float x0, y0; + float a[3], b[3], xrms, yrms; double mjd; - float *dt,exptime; + float *dt, exptime; char nfd[32]; int cospar; }; -struct sat { +struct sat +{ long Isat; char state[10]; float mag; double jd; - double dx,dy,dz; - double x,y,z,vx,vy,vz; - double rsun,rearth; - double psun,pearth,p,phase; - double r,v,ra,de; - double azi,alt; - double rx,ry; + double dx, dy, dz; + double x, y, z, vx, vy, vz; + double rsun, rearth; + double psun, pearth, p, phase; + double r, v, ra, de; + double azi, alt; + double rx, ry; }; -struct track { - float x0,y0,x1,y1; +struct track +{ + float x0, y0, x1, y1; }; -struct image read_fits(char *filename); -struct sat apparent_position(double mjd); -double modulo(double,double); -void obspos_xyz(double,xyz_t *,xyz_t *); -void sunpos_xyz(double,xyz_t *); -double gmst(double); -double dgmst(double); -void forward(double ra0,double de0,double ra,double de,double *x,double *y); -void reverse(double ra0,double de0,double x,double y,double *ra,double *de); +struct image read_fits (char *filename); +struct sat apparent_position (double mjd); +double modulo (double, double); +void obspos_xyz (double, xyz_t *, xyz_t *); +void sunpos_xyz (double, xyz_t *); +double gmst (double); +double dgmst (double); +void forward (double ra0, double de0, double ra, double de, double *x, + double *y); +void reverse (double ra0, double de0, double x, double y, double *ra, + double *de); // Get observing site -void get_site(int site_id) +void +get_site (int site_id) { - int i=0; + int i = 0; char line[LIM]; FILE *file; int id; - double lat,lng; + double lat, lng; float alt; - char abbrev[3],observer[64],filename[LIM],*env; + char abbrev[3], observer[64], filename[LIM], *env; - env=getenv("ST_DATADIR"); - sprintf(filename,"%s/data/sites.txt",env); - file=fopen(filename,"r"); - if (file==NULL) { - printf("File with site information not found!\n"); - return; - } - while (fgets(line,LIM,file)!=NULL) { - // Skip - if (strstr(line,"#")!=NULL) - continue; - - // Strip newline - line[strlen(line)-1]='\0'; - - // Read data - sscanf(line,"%4d %2s %lf %lf %f", - &id,abbrev,&lat,&lng,&alt); - strcpy(observer,line+38); - - // Change to km - alt/=1000.0; - - if (id==site_id) { - m.lat=lat; - m.lng=lng; - m.alt=alt; - m.site_id=id; - strcpy(m.observer,observer); + env = getenv ("ST_DATADIR"); + sprintf (filename, "%s/data/sites.txt", env); + file = fopen (filename, "r"); + if (file == NULL) + { + printf ("File with site information not found!\n"); + return; } + while (fgets (line, LIM, file) != NULL) + { + // Skip + if (strstr (line, "#") != NULL) + continue; - } - fclose(file); + // Strip newline + line[strlen (line) - 1] = '\0'; + + // Read data + sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt); + strcpy (observer, line + 38); + + // Change to km + alt /= 1000.0; + + if (id == site_id) + { + m.lat = lat; + m.lng = lng; + m.alt = alt; + m.site_id = id; + strcpy (m.observer, observer); + } + + } + fclose (file); return; } // Precess a celestial position -void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de) +void +precess (double mjd0, double ra0, double de0, double mjd, double *ra, + double *de) { - double t0,t; - double zeta,z,theta; - double a,b,c; + double t0, t; + double zeta, z, theta; + double a, b, c; // Angles in radians - ra0*=D2R; - de0*=D2R; + ra0 *= D2R; + de0 *= D2R; // Time in centuries - t0=(mjd0-51544.5)/36525.0; - t=(mjd-mjd0)/36525.0; + t0 = (mjd0 - 51544.5) / 36525.0; + t = (mjd - mjd0) / 36525.0; // Precession angles - zeta=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - zeta+=(0.30188-0.000344*t0)*t*t+0.017998*t*t*t; - zeta*=D2R/3600.0; - z=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - z+=(1.09468+0.000066*t0)*t*t+0.018203*t*t*t; - z*=D2R/3600.0; - theta=(2004.3109-0.85330*t0-0.000217*t0*t0)*t; - theta+=-(0.42665+0.000217*t0)*t*t-0.041833*t*t*t; - theta*=D2R/3600.0; - - a=cos(de0)*sin(ra0+zeta); - b=cos(theta)*cos(de0)*cos(ra0+zeta)-sin(theta)*sin(de0); - c=sin(theta)*cos(de0)*cos(ra0+zeta)+cos(theta)*sin(de0); + zeta = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + zeta += (0.30188 - 0.000344 * t0) * t * t + 0.017998 * t * t * t; + zeta *= D2R / 3600.0; + z = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + z += (1.09468 + 0.000066 * t0) * t * t + 0.018203 * t * t * t; + z *= D2R / 3600.0; + theta = (2004.3109 - 0.85330 * t0 - 0.000217 * t0 * t0) * t; + theta += -(0.42665 + 0.000217 * t0) * t * t - 0.041833 * t * t * t; + theta *= D2R / 3600.0; - *ra=(atan2(a,b)+z)*R2D; - *de=asin(c)*R2D; + a = cos (de0) * sin (ra0 + zeta); + b = cos (theta) * cos (de0) * cos (ra0 + zeta) - sin (theta) * sin (de0); + c = sin (theta) * cos (de0) * cos (ra0 + zeta) + cos (theta) * sin (de0); - if (*ra<360.0) - *ra+=360.0; - if (*ra>360.0) - *ra-=360.0; + *ra = (atan2 (a, b) + z) * R2D; + *de = asin (c) * R2D; + + if (*ra < 360.0) + *ra += 360.0; + if (*ra > 360.0) + *ra -= 360.0; return; } -orbit_t find_tle(char *tlefile,struct image img,int satno) +orbit_t +find_tle (char *tlefile, struct image img, int satno) { int i; orbit_t orb; struct sat s; - int imode,flag,textflag; - FILE *fp=NULL; - xyz_t satpos,obspos,satvel,sunpos; - double mjd,jd,dx,dy,dz; - double rx,ry,ra,de,azi,alt,r,t,d; - float x[MMAX],y[MMAX],x0,y0; - char norad[7],satname[30]; + int imode, flag, textflag; + FILE *fp = NULL; + xyz_t satpos, obspos, satvel, sunpos; + double mjd, jd, dx, dy, dz; + double rx, ry, ra, de, azi, alt, r, t, d; + float x[MMAX], y[MMAX], x0, y0; + char norad[7], satname[30]; float isch; - float rsun,rearth,psun,pearth,p; + float rsun, rearth, psun, pearth, p; char filename[128]; - double mnan,mnanmin,rmin; + double mnan, mnanmin, rmin; // Open TLE file - fp=fopen(tlefile,"rb"); - if (fp==NULL) - fatal_error("File open failed for reading %s\n",tlefile); + fp = fopen (tlefile, "rb"); + if (fp == NULL) + fatal_error ("File open failed for reading %s\n", tlefile); // Read TLEs - if (satno!=0) { - read_twoline(fp,satno,&orb); - fclose(fp); - return orb; - } - - read_twoline(fp,0,&orb); - fclose(fp); - - for (i=0,mnan=0.0;mnan<360.0;mnan+=0.01,i++) { - orb.mnan=mnan*D2R; - Isat=orb.satno; - imode=init_sgdp4(&orb); - - mjd=img.mjd+0.5*img.exptime/86400.0; - - // Compute apparent position - s=apparent_position(mjd); - - r=acos(sin(img.de0*D2R)*sin(s.de*D2R)+cos(img.de0*D2R)*cos(s.de*D2R)*cos((img.ra0-s.ra)*D2R))*R2D; - if (r<10.0) { - forward(img.ra0,img.de0,s.ra,s.de,&s.rx,&s.ry); - r=sqrt(s.rx*s.rx+s.ry*s.ry)/3600.0; + if (satno != 0) + { + read_twoline (fp, satno, &orb); + fclose (fp); + return orb; } - - if (i==0 || rnframes; - dydn=(trk.y1-trk.y0)/(float) img->nframes; + dxdn = (trk.x1 - trk.x0) / (float) img->nframes; + dydn = (trk.y1 - trk.y0) / (float) img->nframes; // Allocate - z=(float *) malloc(sizeof(float)*img->naxis1*img->naxis2); - wt=(int *) malloc(sizeof(int)*img->naxis1*img->naxis2); + z = (float *) malloc (sizeof (float) * img->naxis1 * img->naxis2); + wt = (int *) malloc (sizeof (int) * img->naxis1 * img->naxis2); // Set to zero - for (i=0;inaxis1*img->naxis2;i++) { - z[i]=0.0; - wt[i]=0; - } + for (i = 0; i < img->naxis1 * img->naxis2; i++) + { + z[i] = 0.0; + wt[i] = 0; + } // Loop over frames - for (l=0;lnframes;l++) { - // Offset - dx=dxdn*(l-img->nframes/2); - dy=dydn*(l-img->nframes/2); - - // Integer offset - di=(int) floor(dx+0.5); - dj=(int) floor(dy+0.5); + for (l = 0; l < img->nframes; l++) + { + // Offset + dx = dxdn * (l - img->nframes / 2); + dy = dydn * (l - img->nframes / 2); - // Set - for (i=0;inaxis1;i++) { - for (j=0;jnaxis2;j++) { - k=i+img->naxis1*j; - k0=i+di+img->naxis1*(j+dj); - if (i+di>0 && i+dinaxis1 && j+dj>0 && j+djnaxis2) { - wt[k]+=1; - if (img->znum[k0]==l) - z[k]+=img->zmax[k0]; - // else - // z[k]+=img->zavg[k0]; + // Integer offset + di = (int) floor (dx + 0.5); + dj = (int) floor (dy + 0.5); + + // Set + for (i = 0; i < img->naxis1; i++) + { + for (j = 0; j < img->naxis2; j++) + { + k = i + img->naxis1 * j; + k0 = i + di + img->naxis1 * (j + dj); + if (i + di > 0 && i + di < img->naxis1 && j + dj > 0 + && j + dj < img->naxis2) + { + wt[k] += 1; + if (img->znum[k0] == l) + z[k] += img->zmax[k0]; + // else + // z[k]+=img->zavg[k0]; + } + } } - } } - } // Scale - for (i=0;inaxis1*img->naxis2;i++) { - if (wt[i]>0) - img->zd[i]=z[i]/(float) wt[i]; - else - img->zd[i]=z[i]; - } - img->naxis3=5; + for (i = 0; i < img->naxis1 * img->naxis2; i++) + { + if (wt[i] > 0) + img->zd[i] = z[i] / (float) wt[i]; + else + img->zd[i] = z[i]; + } + img->naxis3 = 5; - free(z); - free(wt); + free (z); + free (wt); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { int i; struct image img; - float zmin,zmax,zavg,zstd; - float tr[]={-0.5,1.0,0.0,-0.5,0.0,1.0}; - float heat_l[] = {0.0, 0.2, 0.4, 0.6, 1.0}; - float heat_r[] = {0.0, 0.5, 1.0, 1.0, 1.0}; - float heat_g[] = {0.0, 0.0, 0.5, 1.0, 1.0}; - float heat_b[] = {0.0, 0.0, 0.0, 0.3, 1.0}; + float zmin, zmax, zavg, zstd; + float tr[] = { -0.5, 1.0, 0.0, -0.5, 0.0, 1.0 }; + float heat_l[] = { 0.0, 0.2, 0.4, 0.6, 1.0 }; + float heat_r[] = { 0.0, 0.5, 1.0, 1.0, 1.0 }; + float heat_g[] = { 0.0, 0.0, 0.5, 1.0, 1.0 }; + float heat_b[] = { 0.0, 0.0, 0.0, 0.3, 1.0 }; char text[128]; orbit_t orb; - float x0,y0,x1,y1; + float x0, y0, x1, y1; struct track trk; FILE *file; char filename[128]; - int satno=0; + int satno = 0; char *env; // Read image - img=read_fits(argv[1]); + img = read_fits (argv[1]); // Set site - get_site(img.cospar); + get_site (img.cospar); - if (argc==5) - satno=atoi(argv[4]); + if (argc == 5) + satno = atoi (argv[4]); // Find closest orbit - orb=find_tle(argv[2],img,satno); + orb = find_tle (argv[2], img, satno); - trk=plot_satellite(orb,img); + trk = plot_satellite (orb, img); - track_image(&img,trk); + track_image (&img, trk); - for (i=0,zavg=0.0;i-s.psun && s.p-s.pearths.psun) - strcpy(s.state,"sunlit"); + if (s.p - s.pearth < -s.psun) + strcpy (s.state, "eclipsed"); + else if (s.p - s.pearth > -s.psun && s.p - s.pearth < s.psun) + strcpy (s.state, "umbra"); + else if (s.p - s.pearth > s.psun) + strcpy (s.state, "sunlit"); // Position differences - dx=satpos.x-obspos.x; - dy=satpos.y-obspos.y; - dz=satpos.z-obspos.z; - dvx=satvel.x-obsvel.x; - dvy=satvel.y-obsvel.y; - dvz=satvel.z-obsvel.z; - + dx = satpos.x - obspos.x; + dy = satpos.y - obspos.y; + dz = satpos.z - obspos.z; + dvx = satvel.x - obsvel.x; + dvy = satvel.y - obsvel.y; + dvz = satvel.z - obsvel.z; + // Celestial position - s.r=sqrt(dx*dx+dy*dy+dz*dz); - s.v=(dvx*dx+dvy*dy+dvz*dz)/s.r; - ra=modulo(atan2(dy,dx)*R2D,360.0); - de=asin(dz/s.r)*R2D; + s.r = sqrt (dx * dx + dy * dy + dz * dz); + s.v = (dvx * dx + dvy * dy + dvz * dz) / s.r; + ra = modulo (atan2 (dy, dx) * R2D, 360.0); + de = asin (dz / s.r) * R2D; // Precess - precess(mjd,ra,de,mjd0,&s.ra,&s.de); + precess (mjd, ra, de, mjd0, &s.ra, &s.de); // Phase - s.phase=acos(((obspos.x-satpos.x)*(sunpos.x-satpos.x)+(obspos.y-satpos.y)*(sunpos.y-satpos.y)+(obspos.z-satpos.z)*(sunpos.z-satpos.z))/(rsun*s.r))*R2D; - + s.phase = + acos (((obspos.x - satpos.x) * (sunpos.x - satpos.x) + + (obspos.y - satpos.y) * (sunpos.y - satpos.y) + (obspos.z - + satpos.z) * + (sunpos.z - satpos.z)) / (rsun * s.r)) * R2D; + // Magnitude - if (strcmp(s.state,"sunlit")==0) - s.mag=STDMAG-15.0+5*log10(s.r)-2.5*log10(sin(s.phase*D2R)+(M_PI-s.phase*D2R)*cos(s.phase*D2R)); + if (strcmp (s.state, "sunlit") == 0) + s.mag = + STDMAG - 15.0 + 5 * log10 (s.r) - 2.5 * log10 (sin (s.phase * D2R) + + (M_PI - + s.phase * D2R) * + cos (s.phase * D2R)); else - s.mag=15; + s.mag = 15; /* - // Convert and project - if (strcmp(m.orientation,"horizontal")==0) { - equatorial2horizontal(mjd,s.ra,s.de,&s.azi,&s.alt); - forward(s.azi,s.alt,&s.rx,&s.ry); - } else if (strcmp(m.orientation,"equatorial")==0) { - forward(s.ra,s.de,&s.rx,&s.ry); - } - */ + // Convert and project + if (strcmp(m.orientation,"horizontal")==0) { + equatorial2horizontal(mjd,s.ra,s.de,&s.azi,&s.alt); + forward(s.azi,s.alt,&s.rx,&s.ry); + } else if (strcmp(m.orientation,"equatorial")==0) { + forward(s.ra,s.de,&s.rx,&s.ry); + } + */ return s; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Observer position -void obspos_xyz(double mjd,xyz_t *pos,xyz_t *vel) +void +obspos_xyz (double mjd, xyz_t * pos, xyz_t * vel) { - double ff,gc,gs,theta,s,dtheta; + double ff, gc, gs, theta, s, dtheta; - s=sin(m.lat*D2R); - ff=sqrt(1.0-FLAT*(2.0-FLAT)*s*s); - gc=1.0/ff+m.alt/XKMPER; - gs=(1.0-FLAT)*(1.0-FLAT)/ff+m.alt/XKMPER; + s = sin (m.lat * D2R); + ff = sqrt (1.0 - FLAT * (2.0 - FLAT) * s * s); + gc = 1.0 / ff + m.alt / XKMPER; + gs = (1.0 - FLAT) * (1.0 - FLAT) / ff + m.alt / XKMPER; - theta=gmst(mjd)+m.lng; - dtheta=dgmst(mjd)*D2R/86400; + theta = gmst (mjd) + m.lng; + dtheta = dgmst (mjd) * D2R / 86400; - pos->x=gc*cos(m.lat*D2R)*cos(theta*D2R)*XKMPER; - pos->y=gc*cos(m.lat*D2R)*sin(theta*D2R)*XKMPER; - pos->z=gs*sin(m.lat*D2R)*XKMPER; - vel->x=-gc*cos(m.lat*D2R)*sin(theta*D2R)*XKMPER*dtheta; - vel->y=gc*cos(m.lat*D2R)*cos(theta*D2R)*XKMPER*dtheta; - vel->z=0.0; + pos->x = gc * cos (m.lat * D2R) * cos (theta * D2R) * XKMPER; + pos->y = gc * cos (m.lat * D2R) * sin (theta * D2R) * XKMPER; + pos->z = gs * sin (m.lat * D2R) * XKMPER; + vel->x = -gc * cos (m.lat * D2R) * sin (theta * D2R) * XKMPER * dtheta; + vel->y = gc * cos (m.lat * D2R) * cos (theta * D2R) * XKMPER * dtheta; + vel->z = 0.0; return; } // Solar position -void sunpos_xyz(double mjd,xyz_t *pos) +void +sunpos_xyz (double mjd, xyz_t * pos) { - double jd,t,l0,m,e,c,r; - double n,s,ecl,ra,de; + double jd, t, l0, m, e, c, r; + double n, s, ecl, ra, de; - jd=mjd+2400000.5; - t=(jd-2451545.0)/36525.0; - l0=modulo(280.46646+t*(36000.76983+t*0.0003032),360.0)*D2R; - m=modulo(357.52911+t*(35999.05029-t*0.0001537),360.0)*D2R; - e=0.016708634+t*(-0.000042037-t*0.0000001267); - c=(1.914602+t*(-0.004817-t*0.000014))*sin(m)*D2R; - c+=(0.019993-0.000101*t)*sin(2.0*m)*D2R; - c+=0.000289*sin(3.0*m)*D2R; + jd = mjd + 2400000.5; + t = (jd - 2451545.0) / 36525.0; + l0 = modulo (280.46646 + t * (36000.76983 + t * 0.0003032), 360.0) * D2R; + m = modulo (357.52911 + t * (35999.05029 - t * 0.0001537), 360.0) * D2R; + e = 0.016708634 + t * (-0.000042037 - t * 0.0000001267); + c = (1.914602 + t * (-0.004817 - t * 0.000014)) * sin (m) * D2R; + c += (0.019993 - 0.000101 * t) * sin (2.0 * m) * D2R; + c += 0.000289 * sin (3.0 * m) * D2R; - r=1.000001018*(1.0-e*e)/(1.0+e*cos(m+c)); - n=modulo(125.04-1934.136*t,360.0)*D2R; - s=l0+c+(-0.00569-0.00478*sin(n))*D2R; - ecl=(23.43929111+(-46.8150*t-0.00059*t*t+0.001813*t*t*t)/3600.0+0.00256*cos(n))*D2R; + r = 1.000001018 * (1.0 - e * e) / (1.0 + e * cos (m + c)); + n = modulo (125.04 - 1934.136 * t, 360.0) * D2R; + s = l0 + c + (-0.00569 - 0.00478 * sin (n)) * D2R; + ecl = + (23.43929111 + + (-46.8150 * t - 0.00059 * t * t + 0.001813 * t * t * t) / 3600.0 + + 0.00256 * cos (n)) * D2R; - ra=atan2(cos(ecl)*sin(s),cos(s)); - de=asin(sin(ecl)*sin(s)); + ra = atan2 (cos (ecl) * sin (s), cos (s)); + de = asin (sin (ecl) * sin (s)); - pos->x=r*cos(de)*cos(ra)*XKMPAU; - pos->y=r*cos(de)*sin(ra)*XKMPAU; - pos->z=r*sin(de)*XKMPAU; + pos->x = r * cos (de) * cos (ra) * XKMPAU; + pos->y = r * cos (de) * sin (ra) * XKMPAU; + pos->z = r * sin (de) * XKMPAU; return; } // Greenwich Mean Sidereal Time -double dgmst(double mjd) +double +dgmst (double mjd) { - double t,dgmst; + double t, dgmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - dgmst=360.98564736629+t*(0.000387933-t/38710000); + dgmst = 360.98564736629 + t * (0.000387933 - t / 38710000); return dgmst; } diff --git a/src/rde2iod.c b/src/rde2iod.c index 5fa641c..ac0e57f 100644 --- a/src/rde2iod.c +++ b/src/rde2iod.c @@ -6,147 +6,165 @@ #define LIM 128 -int fgetline(FILE *file,char *s,int lim); -int find_satno(char *desig0) +int fgetline (FILE * file, char *s, int lim); +int +find_satno (char *desig0) { FILE *file; - int satno=99999,status; + int satno = 99999, status; char desig[16]; - char *env,filename[LIM]; + char *env, filename[LIM]; - env=getenv("ST_DATADIR"); - sprintf(filename,"%s/data/desig.txt",env); - file=fopen(filename,"r"); - if (file==NULL) { - fprintf(stderr,"Designation file not found!\n"); - exit(0); - } - while (!feof(file)) { - status=fscanf(file,"%d %s",&satno,desig); - if (strcmp(desig,desig0)==0) - break; - } - fclose(file); + env = getenv ("ST_DATADIR"); + sprintf (filename, "%s/data/desig.txt", env); + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "Designation file not found!\n"); + exit (0); + } + while (!feof (file)) + { + status = fscanf (file, "%d %s", &satno, desig); + if (strcmp (desig, desig0) == 0) + break; + } + fclose (file); return satno; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { FILE *file; char line[LIM]; - int intidy,intido,piece,site,year,month,day,hour,min,sec,fsec,satno; - char desig[16],pdesig[16]; - int format,epoch,dummy,icsec; - float csec,cang; - int rah,ram,rafm,ded,dem,defm; - float tm,tx,am,ax; + int intidy, intido, piece, site, year, month, day, hour, min, sec, fsec, + satno; + char desig[16], pdesig[16]; + int format, epoch, dummy, icsec; + float csec, cang; + int rah, ram, rafm, ded, dem, defm; + float tm, tx, am, ax; char sign; - int lineno=0; + int lineno = 0; - file=fopen(argv[1],"r"); - while (fgetline(file,line,LIM)>0) { - if (strncmp(line,"2420",4)==0 && lineno==0) { - lineno++; - sscanf(line,"%04d %02d%02d",&site,&year,&month); - sscanf(line+12,"%1d%1d%1d %3d%1d",&icsec,&dummy,&format,&dummy,&epoch); + file = fopen (argv[1], "r"); + while (fgetline (file, line, LIM) > 0) + { + if (strncmp (line, "2420", 4) == 0 && lineno == 0) + { + lineno++; + sscanf (line, "%04d %02d%02d", &site, &year, &month); + sscanf (line + 12, "%1d%1d%1d %3d%1d", &icsec, &dummy, &format, + &dummy, &epoch); - csec=0.1*icsec; - cang=dummy; + csec = 0.1 * icsec; + cang = dummy; - // Year switch - if (year>50) - year+=1900; + // Year switch + if (year > 50) + year += 1900; + else + year += 2000; + + // Time accuracy + tx = floor (log10 (csec)) + 8; + tm = floor (csec / pow (10.0, tx - 8)); + + // angle accuracy + ax = floor (log10 (cang)) + 8; + am = floor (cang / pow (10.0, ax - 8)); + + if (ax > 9.0) + { + ax = 9.0; + am = 9.0; + } + + continue; + } + if (strlen (line) < 5 && lineno == 1) + { + sscanf (line, "%d", &day); + if (day == 999) + break; + continue; + } + + // Skip wrong lines + if (!isdigit (line[0])) + continue; + // Skip short lines + if (strlen (line) < 31) + continue; + + // Scan line + sscanf (line, "%02d%03d%02d", &intidy, &intido, &piece); + sscanf (line + 8, "%02d%02d%02d.%02d", &hour, &min, &sec, &fsec); + sscanf (line + 18, "%02d%02d%d", &rah, &ram, &rafm); + sscanf (line + 24, "%c%02d%02d%d", &sign, &ded, &dem, &defm); + fsec *= 10.0; + // Format designation + if (piece < 26) + { + sprintf (desig, "%02d %03d%c", intidy, intido, piece + 'A' - 1); + sprintf (pdesig, "%02d%03d%c", intidy, intido, piece + 'A' - 1); + } else - year+=2000; + { + fprintf (stderr, "Failed to understand designation!\n"); + fprintf (stderr, "%s\n", line); + continue; + } - // Time accuracy - tx=floor(log10(csec))+8; - tm=floor(csec/pow(10.0,tx-8)); + // Test data format + if (format != 1) + { + fprintf (stderr, "Angle format %d not implemented!\n", format); + fprintf (stderr, "%s\n", line); + continue; + } - // angle accuracy - ax=floor(log10(cang))+8; - am=floor(cang/pow(10.0,ax-8)); + // Fractional RA + if (rafm < 10) + rafm *= 100; + else if (rafm < 100) + rafm *= 10; - if (ax>9.0) { - ax=9.0; - am=9.0; - } + // Fractional DE + if (defm < 10) + defm *= 10; + else if (defm < 100) + defm *= 1; - continue; + // Get satellite number + satno = find_satno (pdesig); + + // Format IOD line + printf + ("%05d %s %04d G %04d%02d%02d%02d%02d%02d%03d %1.0f%1.0f %d%d ", + satno, desig, site, year, month, day, hour, min, sec, fsec, tm, tx, + format, epoch); + printf ("%02d%02d%03d%c%02d%02d%02d %1.0f%1.0f\n", rah, ram, rafm, sign, + ded, dem, defm, am, ax); } - if (strlen(line)<5 && lineno==1) { - sscanf(line,"%d",&day); - if (day==999) - break; - continue; - } - - // Skip wrong lines - if (!isdigit(line[0])) - continue; - // Skip short lines - if (strlen(line)<31) - continue; - - // Scan line - sscanf(line,"%02d%03d%02d",&intidy,&intido,&piece); - sscanf(line+8,"%02d%02d%02d.%02d",&hour,&min,&sec,&fsec); - sscanf(line+18,"%02d%02d%d",&rah,&ram,&rafm); - sscanf(line+24,"%c%02d%02d%d",&sign,&ded,&dem,&defm); - fsec*=10.0; - // Format designation - if (piece<26) { - sprintf(desig,"%02d %03d%c",intidy,intido,piece+'A'-1); - sprintf(pdesig,"%02d%03d%c",intidy,intido,piece+'A'-1); - } else { - fprintf(stderr,"Failed to understand designation!\n"); - fprintf(stderr,"%s\n",line); - continue; - } - - // Test data format - if (format!=1) { - fprintf(stderr,"Angle format %d not implemented!\n",format); - fprintf(stderr,"%s\n",line); - continue; - } - - // Fractional RA - if (rafm<10) - rafm*=100; - else if (rafm<100) - rafm*=10; - - // Fractional DE - if (defm<10) - defm*=10; - else if (defm<100) - defm*=1; - - // Get satellite number - satno=find_satno(pdesig); - - // Format IOD line - printf("%05d %s %04d G %04d%02d%02d%02d%02d%02d%03d %1.0f%1.0f %d%d ",satno,desig,site,year,month,day,hour,min,sec,fsec,tm,tx,format,epoch); - printf("%02d%02d%03d%c%02d%02d%02d %1.0f%1.0f\n",rah,ram,rafm,sign,ded,dem,defm,am,ax); - } - fclose(file); + fclose (file); return 0; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; - - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + int c, i = 0; + + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return i; } - diff --git a/src/reduce.c b/src/reduce.c index 8736b12..320adb5 100644 --- a/src/reduce.c +++ b/src/reduce.c @@ -11,1454 +11,1673 @@ #define R2D 180.0/M_PI #define LIM 256 -struct image { +struct image +{ char filename[64]; - int naxis1,naxis2,naxis3,nframes; - float *zavg,*zstd,*zmax,*znum,*zd,*zsig; + int naxis1, naxis2, naxis3, nframes; + float *zavg, *zstd, *zmax, *znum, *zd, *zsig; int *mask; char nfd[32]; - double ra0,de0; - float x0,y0; - float a[3],b[3],xrms,yrms; + double ra0, de0; + float x0, y0; + float a[3], b[3], xrms, yrms; double mjd; - float *dt,exptime; + float *dt, exptime; int cospar; }; -struct selection { - int state,fit; - float x0,y0,x1,y1; - float w,zmin,zmax; - float a,ca,sa,r; - float tmid,tmin,tmax,ax[2],sax[2],ay[2],say[2],chi2x,chi2y; +struct selection +{ + int state, fit; + float x0, y0, x1, y1; + float w, zmin, zmax; + float a, ca, sa, r; + float tmid, tmin, tmax, ax[2], sax[2], ay[2], say[2], chi2x, chi2y; }; -struct observation { - int satno,cospar; - char desig[16],conditions,behavior; - double mjd,ra,de; - float terr,perr,tmid,tmin,tmax; - char nfd[32],pos[32]; - int epoch,type; +struct observation +{ + int satno, cospar; + char desig[16], conditions, behavior; + double mjd, ra, de; + float terr, perr, tmid, tmin, tmax; + char nfd[32], pos[32]; + int epoch, type; char iod_line[80]; - float x[3],y[3]; - float ax[2],ay[2]; + float x[3], y[3]; + float ax[2], ay[2]; int state; }; -struct track { - float x0,y0,x1,y1,texp; +struct track +{ + float x0, y0, x1, y1, texp; int satno; } trk; -int iobject=0; - -struct image read_fits(char *filename); -void forward(double ra0,double de0,double ra,double de,double *x,double *y); -void reverse(double ra0,double de0,double x,double y,double *ra,double *de); -double nfd2mjd(char *date); -double date2mjd(int year,int month,double day); -void mjd2date(double mjd,char *date); -void dec2s(double x,char *s,int type); -float linear_fit(float x[],float y[],int n,float a[],float sa[]); -int fgetline(FILE *file,char *s,int lim); -double gmst(double mjd); -double modulo(double x,double y); +int iobject = 0; + +struct image read_fits (char *filename); +void forward (double ra0, double de0, double ra, double de, double *x, + double *y); +void reverse (double ra0, double de0, double x, double y, double *ra, + double *de); +double nfd2mjd (char *date); +double date2mjd (int year, int month, double day); +void mjd2date (double mjd, char *date); +void dec2s (double x, char *s, int type); +float linear_fit (float x[], float y[], int n, float a[], float sa[]); +int fgetline (FILE * file, char *s, int lim); +double gmst (double mjd); +double modulo (double x, double y); // Find peak -float find_peak(float *z,int kx,int ky,int xmin,int xmax,int ymin,int ymax,float s,int mx,int my,float *x0,float *y0) +float +find_peak (float *z, int kx, int ky, int xmin, int xmax, int ymin, int ymax, + float s, int mx, int my, float *x0, float *y0) { - int i,j,k,l,i0,j0,k0,i1,j1,k1,nx,ny; - int imid,jmid,imax,jmax,flag; - float *d,*g,*w,*h; - float sg,sgg,sgn,den,s1,s2; - float hmax,havg,hstd; - float x,y; + int i, j, k, l, i0, j0, k0, i1, j1, k1, nx, ny; + int imid, jmid, imax, jmax, flag; + float *d, *g, *w, *h; + float sg, sgg, sgn, den, s1, s2; + float hmax, havg, hstd; + float x, y; - printf("%d %d %d %d -> %d %d\n",xmin,xmax,ymin,ymax,kx,ky); + printf ("%d %d %d %d -> %d %d\n", xmin, xmax, ymin, ymax, kx, ky); // Select image - if (xmin<0.0) xmin=0.0; - if (ymin<0.0) ymin=0.0; - if (xmax>=kx) xmax=kx; - if (ymax>=ky) ymax=ky; - nx=(int) (xmax-xmin); - ny=(int) (ymax-ymin); - d=(float *) malloc(sizeof(float)*nx*ny); - for (i=xmin,i0=0;i= kx) + xmax = kx; + if (ymax >= ky) + ymax = ky; + nx = (int) (xmax - xmin); + ny = (int) (ymax - ymin); + d = (float *) malloc (sizeof (float) * nx * ny); + for (i = xmin, i0 = 0; i < xmax; i++, i0++) + { + for (j = ymin, j0 = 0; j < ymax; j++, j0++) + { + k = i + kx * j; + k0 = i0 + nx * j0; + d[k0] = z[k]; + } } - } - printf("%d %d %d %d -> %d %d\n",xmin,xmax,ymin,ymax,nx,ny); + printf ("%d %d %d %d -> %d %d\n", xmin, xmax, ymin, ymax, nx, ny); // Make kernel - g=(float *) malloc(sizeof(float)*mx*my); - for (i=0,imid=mx/2,jmid=my/2,sg=0.0,sgg=0.0;i=nx || j1<0 || j1>=ny) - continue; - k1=i1+nx*j1; - h[k]+=w[k0]*d[k1]; + h = (float *) malloc (sizeof (float) * nx * ny); + for (i = 0; i < nx; i++) + { + for (j = 0; j < ny; j++) + { + k = i + nx * j; + h[k] = 0.0; + for (i0 = 0; i0 < mx; i0++) + { + for (j0 = 0; j0 < my; j0++) + { + k0 = i0 + mx * j0; + i1 = i + i0 - imid; + j1 = j + j0 - jmid; + // Keep in range + if (i1 < 0 || i1 >= nx || j1 < 0 || j1 >= ny) + continue; + k1 = i1 + nx * j1; + h[k] += w[k0] * d[k1]; + } + } + h[k] /= (float) (mx * my); } - } - h[k]/=(float) (mx*my); } - } - + // Locate maximum - for (i=mx,flag=0;ihmax) { - imax=i; - jmax=j; - hmax=h[k]; - } + for (i = mx, flag = 0; i < nx - mx; i++) + { + for (j = my; j < ny - my; j++) + { + k = i + nx * j; + if (flag == 0) + { + imax = i; + jmax = j; + hmax = h[k]; + flag = 1; + } + if (h[k] > hmax) + { + imax = i; + jmax = j; + hmax = h[k]; + } + } } - } // Compute mean value - for (i=mx,s1=0.0,s2=0.0;iax[i]; - ay[i]=obs->ay[i]; - } - obs->ax[1]=(img.a[1]*ax[1]+img.a[2]*ay[1])/3600.0; - obs->ay[1]=(img.b[1]*ax[1]+img.b[2]*ay[1])/3600.0; - + for (i = 0; i < 2; i++) + { + ax[i] = obs->ax[i]; + ay[i] = obs->ay[i]; + } + obs->ax[1] = (img.a[1] * ax[1] + img.a[2] * ay[1]) / 3600.0; + obs->ay[1] = (img.b[1] * ax[1] + img.b[2] * ay[1]) / 3600.0; + // Get time - k=(int) x + img.naxis1*(int) y; - iframe=(int) img.znum[k]; - if (tmid<0.0) - dt=img.dt[iframe]; + k = (int) x + img.naxis1 * (int) y; + iframe = (int) img.znum[k]; + if (tmid < 0.0) + dt = img.dt[iframe]; else - dt=tmid; - mjd=nfd2mjd(img.nfd)+(double) dt/86400.0; - mjd2date(mjd,nfd); - obs->mjd=mjd; + dt = tmid; + mjd = nfd2mjd (img.nfd) + (double) dt / 86400.0; + mjd2date (mjd, nfd); + obs->mjd = mjd; // Correct for motion - mjd1=img.mjd+0.5*(double) img.exptime/86400.0; - dra=gmst(mjd)-gmst(mjd1); - ra+=dra; + mjd1 = img.mjd + 0.5 * (double) img.exptime / 86400.0; + dra = gmst (mjd) - gmst (mjd1); + ra += dra; // Get RA/Dec - dec2s(ra/15.0,sra,0); - dec2s(de,sde,1); - obs->ra=ra; - obs->de=de; - + dec2s (ra / 15.0, sra, 0); + dec2s (de, sde, 1); + obs->ra = ra; + obs->de = de; + // Copy - strcpy(obs->nfd,nfd); - sprintf(obs->pos,"%s%s",sra,sde); + strcpy (obs->nfd, nfd); + sprintf (obs->pos, "%s%s", sra, sde); return; } -void compute_cuts(float *z,int *mask,int n,float *zmin,float *zmax,float lcut,float hcut) +void +compute_cuts (float *z, int *mask, int n, float *zmin, float *zmax, + float lcut, float hcut) { - int i,m; - double s1,s2; - double avg,std; + int i, m; + double s1, s2; + double avg, std; - for (i=0,s1=0.0,s2=0.0,m=0;i1) { // cpgmove(s.x0,s.y0); // cpgdraw(s.x1,s.y1); // } - if (s.state==2) { - for (i=0;i<5;i++) { - if (i==0 || i==4) { - dx=-s.w; - dy=-s.w; - } else if (i==1) { - dx=-s.w; - dy=s.w; - } else if (i==2) { - dx=s.w; - dy=s.w; - } else if (i==3) { - dx=s.w; - dy=-s.w; - } - dx=0.0; - if (i<2 || i==4) { - x=s.ca*dx-s.sa*dy+s.x0; - y=s.sa*dx+s.ca*dy+s.y0; - } else { - x=s.ca*dx-s.sa*dy+s.x1; - y=s.sa*dx+s.ca*dy+s.y1; - } - - if (i==0) - cpgmove(x,y); - else - cpgdraw(x,y); + if (s.state == 2) + { + for (i = 0; i < 5; i++) + { + if (i == 0 || i == 4) + { + dx = -s.w; + dy = -s.w; + } + else if (i == 1) + { + dx = -s.w; + dy = s.w; + } + else if (i == 2) + { + dx = s.w; + dy = s.w; + } + else if (i == 3) + { + dx = s.w; + dy = -s.w; + } + dx = 0.0; + if (i < 2 || i == 4) + { + x = s.ca * dx - s.sa * dy + s.x0; + y = s.sa * dx + s.ca * dy + s.y0; + } + else + { + x = s.ca * dx - s.sa * dy + s.x1; + y = s.sa * dx + s.ca * dy + s.y1; + } + if (i == 0) + cpgmove (x, y); + else + cpgdraw (x, y); + + } } - } - cpgsci(1); + cpgsci (1); return; } -void apply_mask(struct image *img,struct selection s) +void +apply_mask (struct image *img, struct selection s) { - int i,j,k; - float x,y,dx,dy; + int i, j, k; + float x, y, dx, dy; - for (i=0;inaxis1;i++) { - for (j=0;jnaxis2;j++) { - k=i+img->naxis1*j; - if (img->mask[k]==0) - continue; - dx=(float) i-s.x0; - dy=(float) j-s.y0; - x=s.ca*dx+s.sa*dy; - y=-s.sa*dx+s.ca*dy; - if (x>=0.0 && x<=s.r && y>-s.w && yzmax[k]>s.zmin) { - img->mask[k]=1; - } else { - img->mask[k]=0; - } + for (i = 0; i < img->naxis1; i++) + { + for (j = 0; j < img->naxis2; j++) + { + k = i + img->naxis1 * j; + if (img->mask[k] == 0) + continue; + dx = (float) i - s.x0; + dy = (float) j - s.y0; + x = s.ca * dx + s.sa * dy; + y = -s.sa * dx + s.ca * dy; + if (x >= 0.0 && x <= s.r && y > -s.w && y < s.w + && img->zmax[k] > s.zmin) + { + img->mask[k] = 1; + } + else + { + img->mask[k] = 0; + } + } } - } - + return; } -void apply_mask_sigma(struct image *img,struct selection s) +void +apply_mask_sigma (struct image *img, struct selection s) { - int i,j,k; - float x,y,dx,dy; + int i, j, k; + float x, y, dx, dy; - for (i=0;inaxis1;i++) { - for (j=0;jnaxis2;j++) { - k=i+img->naxis1*j; - if (img->mask[k]==0) - continue; - dx=(float) i-s.x0; - dy=(float) j-s.y0; - x=s.ca*dx+s.sa*dy; - y=-s.sa*dx+s.ca*dy; - if (x>=0.0 && x<=s.r && y>-s.w && yzsig[k]>s.zmin) { - img->mask[k]=1; - } else { - img->mask[k]=0; - } + for (i = 0; i < img->naxis1; i++) + { + for (j = 0; j < img->naxis2; j++) + { + k = i + img->naxis1 * j; + if (img->mask[k] == 0) + continue; + dx = (float) i - s.x0; + dy = (float) j - s.y0; + x = s.ca * dx + s.sa * dy; + y = -s.sa * dx + s.ca * dy; + if (x >= 0.0 && x <= s.r && y > -s.w && y < s.w + && img->zsig[k] > s.zmin) + { + img->mask[k] = 1; + } + else + { + img->mask[k] = 0; + } + } } - } - + return; } -void mask_pixel(struct image *img,float x,float y) +void +mask_pixel (struct image *img, float x, float y) { - int i,j,k,kmin,i0,j0,flag; - float r,rmin; + int i, j, k, kmin, i0, j0, flag; + float r, rmin; - i0=(int) x; - j0=(int) y; + i0 = (int) x; + j0 = (int) y; // Find nearest pixel - for (i=0,flag=0;inaxis1;i++) { - for (j=0;jnaxis2;j++) { - k=i+img->naxis1*j; - r=sqrt(pow(i-i0,2)+pow(j-j0,2)); - if (img->mask[k]==0) - continue; - if (flag==0 || rnaxis1; i++) + { + for (j = 0; j < img->naxis2; j++) + { + k = i + img->naxis1 * j; + r = sqrt (pow (i - i0, 2) + pow (j - j0, 2)); + if (img->mask[k] == 0) + continue; + if (flag == 0 || r < rmin) + { + rmin = r; + kmin = k; + flag = 1; + } + } } - } // Mask pixel - img->mask[kmin]=0; + img->mask[kmin] = 0; return; } -void fit(struct observation *obs,struct image img) +void +fit (struct observation *obs, struct image img) { - int i,j,k,l,n; - float *t,*dt,*x,*y; - float tmin,tmax,tmid; - float chi2x,chi2y,ax[2],sax[2],ay[2],say[2]; + int i, j, k, l, n; + float *t, *dt, *x, *y; + float tmin, tmax, tmid; + float chi2x, chi2y, ax[2], sax[2], ay[2], say[2]; // Count number of points - for (i=0,n=0;itmax) tmax=t[i]; + for (i = 0; i < n; i++) + { + if (i == 0) + { + tmin = t[i]; + tmax = t[i]; + } + else + { + if (t[i] < tmin) + tmin = t[i]; + if (t[i] > tmax) + tmax = t[i]; + } } - } - tmid=0.5*(tmin+tmax); - printf("Using points between %.3f and %.3f\n",tmin,tmax); - + tmid = 0.5 * (tmin + tmax); + printf ("Using points between %.3f and %.3f\n", tmin, tmax); + // Shift in time - for (i=0;ix[0] = ax[0]; + obs->y[0] = ay[0]; + obs->x[1] = ax[0] + ax[1] * (tmin - tmid); + obs->y[1] = ay[0] + ay[1] * (tmin - tmid); + obs->x[2] = ax[0] + ax[1] * (tmax - tmid); + obs->y[2] = ay[0] + ay[1] * (tmax - tmid); + obs->state = 1; + obs->tmin = tmin; + obs->tmax = tmax; + for (i = 0; i < 2; i++) + { + obs->ax[i] = ax[i]; + obs->ay[i] = ay[i]; + } - obs->x[0]=ax[0]; - obs->y[0]=ay[0]; - obs->x[1]=ax[0]+ax[1]*(tmin-tmid); - obs->y[1]=ay[0]+ay[1]*(tmin-tmid); - obs->x[2]=ax[0]+ax[1]*(tmax-tmid); - obs->y[2]=ay[0]+ay[1]*(tmax-tmid); - obs->state=1; - obs->tmin=tmin; - obs->tmax=tmax; - for (i=0;i<2;i++) { - obs->ax[i]=ax[i]; - obs->ay[i]=ay[i]; - } - // Reduce point - reduce_point(obs,img,tmid,ax[0],ay[0]); + reduce_point (obs, img, tmid, ax[0], ay[0]); // Free - free(t); - free(dt); - free(x); - free(y); + free (t); + free (dt); + free (x); + free (y); return; } -void format_iod_line(struct observation *obs) +void +format_iod_line (struct observation *obs) { - int mt,xt,mp,xp; + int mt, xt, mp, xp; char string[10]; - + // Time format - sprintf(string,"%7.1e",obs->terr); - mt=string[0]-'0'; - xt=atoi(string+4)+8; + sprintf (string, "%7.1e", obs->terr); + mt = string[0] - '0'; + xt = atoi (string + 4) + 8; // Position format - if (obs->type==2) { - sprintf(string,"%7.1e",obs->perr); - mp=string[0]-'0'; - xp=atoi(string+4)+8; - } else { - printf("Position format not implemented!\n"); - } + if (obs->type == 2) + { + sprintf (string, "%7.1e", obs->perr); + mp = string[0] - '0'; + xp = atoi (string + 4) + 8; + } + else + { + printf ("Position format not implemented!\n"); + } - sprintf(obs->iod_line,"%05d %c%c %-6s %04d %c %-17s %d%d %d%d %-14s %d%d %c", - obs->satno, - obs->desig[0],obs->desig[1], - obs->desig+2, - obs->cospar, - obs->conditions, - obs->nfd, - mt,xt, - obs->type,obs->epoch, - obs->pos, - mp,xp, - obs->behavior); + sprintf (obs->iod_line, + "%05d %c%c %-6s %04d %c %-17s %d%d %d%d %-14s %d%d %c", obs->satno, + obs->desig[0], obs->desig[1], obs->desig + 2, obs->cospar, + obs->conditions, obs->nfd, mt, xt, obs->type, obs->epoch, obs->pos, + mp, xp, obs->behavior); return; } -void find_designation(int satno0,char *desig0) +void +find_designation (int satno0, char *desig0) { FILE *file; int satno; char desig[16]; - char *env,filename[128]; + char *env, filename[128]; // Environment variables - env=getenv("ST_DATADIR"); - sprintf(filename,"%s/data/desig.txt",env); + env = getenv ("ST_DATADIR"); + sprintf (filename, "%s/data/desig.txt", env); - file=fopen(filename,"r"); - if (file==NULL) { - fprintf(stderr,"Designation file not found!\n"); - exit(0); - } - while (!feof(file)) { - fscanf(file,"%d %s",&satno,desig); - if (satno==satno0) { - strcpy(desig0,desig); - break; + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "Designation file not found!\n"); + exit (0); } - } - fclose(file); + while (!feof (file)) + { + fscanf (file, "%d %s", &satno, desig); + if (satno == satno0) + { + strcpy (desig0, desig); + break; + } + } + fclose (file); return; } -void write_observation(struct observation obs) +void +write_observation (struct observation obs) { FILE *file; - float w,pa,dt; - - file=fopen("observations.txt","a"); - fprintf(file,"%s\n",obs.iod_line); - fclose(file); + float w, pa, dt; - printf("Observation written\n"); + file = fopen ("observations.txt", "a"); + fprintf (file, "%s\n", obs.iod_line); + fclose (file); + + printf ("Observation written\n"); + + dt = obs.tmax - obs.tmin; + w = sqrt (obs.ax[1] * obs.ax[1] + obs.ay[1] * obs.ay[1]) / dt; + pa = atan2 (obs.ay[1], obs.ax[1]) * R2D; - dt=obs.tmax-obs.tmin; - w=sqrt(obs.ax[1]*obs.ax[1]+obs.ay[1]*obs.ay[1])/dt; - pa=atan2(obs.ay[1],obs.ax[1])*R2D; - return; } -void track(char *fileroot,struct observation obs,struct image *img,float frac) +void +track (char *fileroot, struct observation obs, struct image *img, float frac) { FILE *file; - char line[LIM],filename[LIM]; - int flag=0,satno; - float x0,y0,x1,y1,texp; - int i,j,k,l,k0; - int di,dj; + char line[LIM], filename[LIM]; + int flag = 0, satno; + float x0, y0, x1, y1, texp; + int i, j, k, l, k0; + int di, dj; float *z; int *wt; - float dxdn,dydn,dx,dy; + float dxdn, dydn, dx, dy; - sprintf(filename,"%s.id",fileroot); + sprintf (filename, "%s.id", fileroot); // Open ID file - file=fopen(filename,"r"); - if (file==NULL) { - fprintf(stderr,"ID file %s not found\n",filename); - return; - } - while (fgetline(file,line,LIM)>0) { - sscanf(line,"%s %f %f %f %f %f %d",filename,&x0,&y0,&x1,&y1,&texp,&satno); - trk.x0=x0; - trk.y0=y0; - trk.x1=x1; - trk.y1=y1; - trk.satno=satno; - trk.texp=texp; - if (satno==obs.satno) - break; - } - fclose(file); + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "ID file %s not found\n", filename); + return; + } + while (fgetline (file, line, LIM) > 0) + { + sscanf (line, "%s %f %f %f %f %f %d", filename, &x0, &y0, &x1, &y1, + &texp, &satno); + trk.x0 = x0; + trk.y0 = y0; + trk.x1 = x1; + trk.y1 = y1; + trk.satno = satno; + trk.texp = texp; + if (satno == obs.satno) + break; + } + fclose (file); - if (satno!=obs.satno) { - fprintf(stderr,"Object %d not found\n",obs.satno); - return; - } - dxdn=(x1-x0)/(float) img->nframes; - dydn=(y1-y0)/(float) img->nframes; + if (satno != obs.satno) + { + fprintf (stderr, "Object %d not found\n", obs.satno); + return; + } + dxdn = (x1 - x0) / (float) img->nframes; + dydn = (y1 - y0) / (float) img->nframes; // Allocate - z=(float *) malloc(sizeof(float)*img->naxis1*img->naxis2); - wt=(int *) malloc(sizeof(int)*img->naxis1*img->naxis2); + z = (float *) malloc (sizeof (float) * img->naxis1 * img->naxis2); + wt = (int *) malloc (sizeof (int) * img->naxis1 * img->naxis2); // Set to zero - for (i=0;inaxis1*img->naxis2;i++) { - z[i]=0.0; - wt[i]=0; - } + for (i = 0; i < img->naxis1 * img->naxis2; i++) + { + z[i] = 0.0; + wt[i] = 0; + } // Loop over frames - for (l=0;lnframes;l++) { - // Offset - dx=dxdn*(l-frac*img->nframes); - dy=dydn*(l-frac*img->nframes); - - // Integer offset - di=(int) floor(dx+0.5); - dj=(int) floor(dy+0.5); + for (l = 0; l < img->nframes; l++) + { + // Offset + dx = dxdn * (l - frac * img->nframes); + dy = dydn * (l - frac * img->nframes); - // Set - for (i=0;inaxis1;i++) { - for (j=0;jnaxis2;j++) { - k=i+img->naxis1*j; - k0=i+di+img->naxis1*(j+dj); - if (i+di>0 && i+dinaxis1 && j+dj>0 && j+djnaxis2) { - wt[k]+=1; - if (img->znum[k0]==l) - z[k]+=img->zmax[k0]; - // else - // z[k]+=img->zavg[k0]; + // Integer offset + di = (int) floor (dx + 0.5); + dj = (int) floor (dy + 0.5); + + // Set + for (i = 0; i < img->naxis1; i++) + { + for (j = 0; j < img->naxis2; j++) + { + k = i + img->naxis1 * j; + k0 = i + di + img->naxis1 * (j + dj); + if (i + di > 0 && i + di < img->naxis1 && j + dj > 0 + && j + dj < img->naxis2) + { + wt[k] += 1; + if (img->znum[k0] == l) + z[k] += img->zmax[k0]; + // else + // z[k]+=img->zavg[k0]; + } + } } - } } - } // Scale - for (i=0;inaxis1*img->naxis2;i++) { - if (wt[i]>0) - img->zd[i]=z[i]/(float) wt[i]; - else - img->zd[i]=z[i]; - } - img->naxis3=5; + for (i = 0; i < img->naxis1 * img->naxis2; i++) + { + if (wt[i] > 0) + img->zd[i] = z[i] / (float) wt[i]; + else + img->zd[i] = z[i]; + } + img->naxis3 = 5; - free(z); - free(wt); + free (z); + free (wt); return; } -int autotrack(char *fileroot,struct observation obs,struct image *img,int cflag) +int +autotrack (char *fileroot, struct observation obs, struct image *img, + int cflag) { FILE *file; - char line[LIM],filename[LIM]; - int flag=0,satno,satno0=0,i=0,n; - float x0,y0,x1,y1,texp; - int status=0; + char line[LIM], filename[LIM]; + int flag = 0, satno, satno0 = 0, i = 0, n; + float x0, y0, x1, y1, texp; + int status = 0; - sprintf(filename,"%s.id",fileroot); + sprintf (filename, "%s.id", fileroot); // Open ID file - file=fopen(filename,"r"); - if (file==NULL) { - fprintf(stderr,"ID file %s not found\n",filename); - return -1; - } - while (fgetline(file,line,LIM)>0) { - if (cflag==1 && strstr(line,"classfd")==NULL) - continue; - sscanf(line,"%s %f %f %f %f %f %d",filename,&trk.x0,&trk.y0,&trk.x1,&trk.y1,&trk.texp,&trk.satno); - if (i==iobject) { - status=1; - break; + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "ID file %s not found\n", filename); + return -1; } + while (fgetline (file, line, LIM) > 0) + { + if (cflag == 1 && strstr (line, "classfd") == NULL) + continue; + sscanf (line, "%s %f %f %f %f %f %d", filename, &trk.x0, &trk.y0, + &trk.x1, &trk.y1, &trk.texp, &trk.satno); + if (i == iobject) + { + status = 1; + break; + } - i++; - } - fclose(file); + i++; + } + fclose (file); iobject++; return status; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int i,j,k,l; - int iconditions=0,ibehavior=0; + int i, j, k, l; + int iconditions = 0, ibehavior = 0; struct image img; - float tr[]={-0.5,1.0,0.0,-0.5,0.0,1.0}; - float heat_l[] = {0.0, 0.2, 0.4, 0.6, 1.0}; - float heat_r[] = {0.0, 0.5, 1.0, 1.0, 1.0}; - float heat_g[] = {0.0, 0.0, 0.5, 1.0, 1.0}; - float heat_b[] = {0.0, 0.0, 0.0, 0.3, 1.0}; - float x,y,frac=0.5; + float tr[] = { -0.5, 1.0, 0.0, -0.5, 0.0, 1.0 }; + float heat_l[] = { 0.0, 0.2, 0.4, 0.6, 1.0 }; + float heat_r[] = { 0.0, 0.5, 1.0, 1.0, 1.0 }; + float heat_g[] = { 0.0, 0.0, 0.5, 1.0, 1.0 }; + float heat_b[] = { 0.0, 0.0, 0.0, 0.3, 1.0 }; + float x, y, frac = 0.5; char c; - float xmin,xmax,ymin,ymax,zmin,zmax,*z; + float xmin, xmax, ymin, ymax, zmin, zmax, *z; float width; - int redraw=1,layer=2,status; - float lcut=4,hcut=6; + int redraw = 1, layer = 2, status; + float lcut = 4, hcut = 6; struct selection s; struct observation obs; - char conditions[]="EGFPBT",behavior[]="EFIRSX"; + char conditions[] = "EGFPBT", behavior[] = "EFIRSX"; char text[128]; - double doy,mjd; + double doy, mjd; int year; char *env; - float sigma,xa,ya; + float sigma, xa, ya; FILE *file; char filename[128]; - - env=getenv("ST_COSPAR"); + + env = getenv ("ST_COSPAR"); // Default observation - obs.satno=99999; - strcpy(obs.desig,"99999U"); - obs.cospar=atoi(env); - obs.conditions='G'; - strcpy(obs.nfd,"YYYYMMDDHHMMSSsss"); - obs.terr=0.1; - strcpy(obs.pos,"HHMMmmm+DDMMmm"); - strcpy(obs.iod_line,""); - obs.perr=0.3; - obs.epoch=5; - obs.type=2; - obs.behavior='S'; - obs.state=0; + obs.satno = 99999; + strcpy (obs.desig, "99999U"); + obs.cospar = atoi (env); + obs.conditions = 'G'; + strcpy (obs.nfd, "YYYYMMDDHHMMSSsss"); + obs.terr = 0.1; + strcpy (obs.pos, "HHMMmmm+DDMMmm"); + strcpy (obs.iod_line, ""); + obs.perr = 0.3; + obs.epoch = 5; + obs.type = 2; + obs.behavior = 'S'; + obs.state = 0; // Set track - trk.satno=0; + trk.satno = 0; // Read image - img=read_fits(argv[1]); + img = read_fits (argv[1]); // Allocate - z=(float *) malloc(sizeof(float)*img.naxis1*img.naxis2); + z = (float *) malloc (sizeof (float) * img.naxis1 * img.naxis2); // Get fake designation - mjd=nfd2mjd(img.nfd); - doy=mjd2doy(mjd,&year); - sprintf(obs.desig,"%02d%03.0lfA",year-2000,doy+500); + mjd = nfd2mjd (img.nfd); + doy = mjd2doy (mjd, &year); + sprintf (obs.desig, "%02d%03.0lfA", year - 2000, doy + 500); - cpgopen("/xs"); - cpgpap(0.,1.0); + cpgopen ("/xs"); + cpgpap (0., 1.0); //cpgpap(7,0.75); - cpgask(0); - cpgsch(0.8); + cpgask (0); + cpgsch (0.8); // Default limits - xmin=0.0; - xmax=(float) img.naxis1; - ymin=0.0; - ymax=(float) img.naxis2; - width=img.naxis1; + xmin = 0.0; + xmax = (float) img.naxis1; + ymin = 0.0; + ymax = (float) img.naxis2; + width = img.naxis1; // Default selection - s.state=0; - s.w=10; - s.zmin=5.0; - s.zmax=20.0; - s.fit=0; + s.state = 0; + s.w = 10; + s.zmin = 5.0; + s.zmax = 20.0; + s.fit = 0; // Set cospas - obs.cospar=img.cospar; + obs.cospar = img.cospar; - for (;;) { - if (redraw==1) { - cpgeras(); - - cpgsvp(0.1,0.95,0.1,0.95); - cpgwnad(xmin,xmax,ymin,ymax); - cpglab("x (pix)","y (pix)"," "); - cpgsfs(2); - cpgctab (heat_l,heat_r,heat_g,heat_b,5,1.0,0.5); + for (;;) + { + if (redraw == 1) + { + cpgeras (); - sprintf(text,"UT Date: %.23s COSPAR ID: %04d",img.nfd+1,img.cospar); - cpgmtxt("T",6.0,0.0,0.0,text); - sprintf(text,"R.A.: %10.5f (%4.1f'') Decl.: %10.5f (%4.1f'')",img.ra0,img.xrms,img.de0,img.yrms); - cpgmtxt("T",4.8,0.0,0.0,text); - sprintf(text,"FoV: %.2f\\(2218)x%.2f\\(2218) Scale: %.2f''x%.2f'' pix\\u-1\\d",img.naxis1*sqrt(img.a[1]*img.a[1]+img.b[1]*img.b[1])/3600.0,img.naxis2*sqrt(img.a[2]*img.a[2]+img.b[2]*img.b[2])/3600.0,sqrt(img.a[1]*img.a[1]+img.b[1]*img.b[1]),sqrt(img.a[2]*img.a[2]+img.b[2]*img.b[2])); - cpgmtxt("T",3.6,0.0,0.0,text); - - // Apply mask - for (i=0;i5.0) { - reduce_point(&obs,img,frac*img.exptime,x,y); - obs.x[0]=x; - obs.y[0]=y; - obs.state=2; + format_iod_line (&obs); + cpgmtxt ("T", 1.0, 0.5, 0.5, obs.iod_line); + redraw = 0; } - redraw=1; - layer=4; - } - continue; - } - // Find peak - if (c=='p') { - sigma=find_peak(img.zd,img.naxis1,img.naxis2,(int) xmin,(int) xmax,(int) ymin,(int) ymax,2.0,11,11,&x,&y); - printf("%f %f %f\n",x,y,sigma); - reduce_point(&obs,img,frac*img.exptime,x,y); - obs.x[0]=x; - obs.y[0]=y; - obs.state=2; - redraw=1; - continue; - } - - // Track - if (c=='t') { - printf("Provide satellite ID: "); - scanf("%d",&obs.satno); - find_designation(obs.satno,obs.desig); - track(argv[1],obs,&img,frac); - layer=4; - redraw=1; - } - - if (c=='\t') { - status=autotrack(argv[1],obs,&img,1); - if (status==1) { - obs.satno=trk.satno; - find_designation(obs.satno,obs.desig); - track(argv[1],obs,&img,frac); - redraw=1; - layer=4; - } - } - // Write obs - if (c=='w') { - write_observation(obs); - continue; - } + // Get cursor + cpgcurs (&x, &y, &c); - // Reduce - if (c=='m') { - reduce_point(&obs,img,-1.0,x,y); - obs.x[0]=x; - obs.y[0]=y; - obs.state=2; - redraw=1; - continue; - } + // Log as bad and quit + if (c == 'Q') + { + sprintf (filename, "%s.bad", argv[1]); + file = fopen (filename, "w"); + fclose (file); + break; + } - // Change fraction - if (c=='e') { - if (frac>0.49 && frac<0.51) - frac=1.0; - else if (frac>0.51) - frac=0.0; - else if (frac<0.49) - frac=0.5; - printf("Fraction: %.1f\n",frac); - iobject=0; - } + // Quit + if (c == 'q') + break; - // Change fraction - if (c=='E') { - frac+=0.1; - if (frac>1.0) - frac=0.0; - printf("Fraction: %.1f\n",frac); - iobject=0; - } - - // Reduce - if (c=='M' || c=='D') { - reduce_point(&obs,img,frac*img.exptime,x,y); - obs.x[0]=x; - obs.y[0]=y; - obs.state=2; - redraw=1; - continue; - } - - // Get designation - if (c=='d') { - printf("Provide satellite number: "); - scanf("%d",&obs.satno); - find_designation(obs.satno,obs.desig); - redraw=1; - continue; - } - - // Toggle condition - if (c=='C') { - iconditions++; - if (iconditions>strlen(conditions)-1) - iconditions=0; - obs.conditions=conditions[iconditions]; - redraw=1; - continue; - } - // Toggle behavior - if (c=='B') { - ibehavior++; - if (ibehavior>strlen(behavior)-1) - ibehavior=0; - obs.behavior=behavior[ibehavior]; - redraw=1; - continue; - } - - // Reread - if (c=='R') { - img=read_fits(argv[1]); - redraw=1; - continue; - } - - // Start - if (c=='s' && s.state==0) { - s.x0=x; - s.y0=y; - s.state=1; - redraw=1; - continue; - } - - // Fit - if (c=='F') { - fit(&obs,img); - redraw=1; - continue; - } - - // End - if (c=='f' && s.state==1) { - s.x1=x; - s.y1=y; - s.a=atan2(s.y1-s.y0,s.x1-s.x0); - s.ca=cos(s.a); - s.sa=sin(s.a); - s.r=sqrt(pow(s.x0-s.x1,2)+pow(s.y0-s.y1,2)); - s.state=2; - apply_mask_sigma(&img,s); - //s.zmin=zmin; - redraw=1; - continue; - } - - // Mask pixel - if (c=='X' && s.state!=0) { - mask_pixel(&img,x,y); - apply_mask(&img,s); - redraw=1; - continue; - } - - // Change level - if (c=='+' || c=='=') { - s.zmin*=1.01; - printf("%.4f\n",s.zmin); - apply_mask_sigma(&img,s); - redraw=1; - continue; - } - if (c=='-') { - s.zmin/=1.01; - printf("%.4f\n",s.zmin); - apply_mask_sigma(&img,s); - redraw=1; - continue; - } - - // Mean - if (isdigit(c)) { - layer=c-'0'-1; - redraw=1; - continue; - } - - // Adjust cuts - if (c=='v') { - lcut*=2; - hcut*=2; - redraw=1; - continue; - } - if (c=='b') { - lcut/=2; - hcut/=2; - if (lcut<0.5) lcut=0.5; - if (hcut<0.75) hcut=0.75; - redraw=1; - continue; - } - - // Center - if (c=='c') { - xmin=x-0.5*width; - xmax=x+0.5*width; - ymin=y-0.5*width*img.naxis2/img.naxis1; - ymax=y+0.5*width*img.naxis2/img.naxis1; - redraw=1; - continue; - } - - // Zoom - if (c=='z') { - width/=2; - xmin=x-0.5*width; - xmax=x+0.5*width; - ymin=y-0.5*width*img.naxis2/img.naxis1; - ymax=y+0.5*width*img.naxis2/img.naxis1; - redraw=1; - continue; - } - - // Unzoom - if (c=='x') { - width*=2; - xmin=x-0.5*width; - xmax=x+0.5*width; - ymin=y-0.5*width*img.naxis2/img.naxis1; - ymax=y+0.5*width*img.naxis2/img.naxis1; - redraw=1; - continue; - } - - // Reset - if (c=='r') { - xmin=0.0; - xmax=(float) img.naxis1; - ymin=0.0; - ymax=(float) img.naxis2; - width=img.naxis1; - lcut=4.0; - hcut=6.0; - s.state=0; - s.fit=0; - obs.state=0; - redraw=1; - continue; - } - - if (c=='h'){ - printf("Reduce Satellite tracks. "); - printf("q Quit\n"); - printf("TAB track and stack objects automatically (only classfd sats)\n"); - printf("w write IOD observation to observations.txt\n"); - printf("M/D measure stack and track position (also middle mouse button)\n"); - printf("e change fraction (0.0 to start, 0.5 for medium, 1.0 for the end)\n"); - printf("d provide NORAD satellite number\n"); - printf("C toggle IOD observing conditions G-Good F-Fair P-Poor B-Bad T-Terrible E-Excellent\n"); - printf("B toggle behavior of sat.: F-Flash I-Irregular R-Regular S-Steady X-Uspecified E-Extremely weak\n"); - printf("s select start of satellite track\n"); - printf("f select end of satellite track\n"); - printf("F fit satellite track\n"); - printf("+/= Increase level of masking pixels\n"); - printf("- Lower level for masking pixels (This does not seem to work)\n"); - printf("1 go to the mean pixel value FITS layer\n"); - printf("2 go to the FITS standard deviation layer\n"); - printf("3 go to the maximum pixel value FITS layer\n"); - printf("4 go to the frame number of the maximum pixel value FITS layer\n"); - printf("5 go to the stack and track layer (only after 't' or 'TAB')\n"); - printf("v lower dynamic range\n"); - printf("b increase dynamic range\n"); - printf("c center on cursor\n"); - printf("z zoom in at cursor\n"); - printf("x zoom out at cursor\n"); - printf("R/r reset to start\n"); - printf("m measure position of pixel\n"); - printf("t track & stack, give NORAD satellite number\n"); - printf("E change fraction in tenths\n"); - printf("X pixel mask (also with mouse scroll wheel)\n"); + // End + if (c == 'a') + { + status = autotrack (argv[1], obs, &img, 0); + if (status == 1) + { + obs.satno = trk.satno; + find_designation (obs.satno, obs.desig); + track (argv[1], obs, &img, frac); + x = frac * (trk.x1 - trk.x0) + trk.x0; + y = frac * (trk.y1 - trk.y0) + trk.y0; + width = 100; + xmin = x - 0.5 * width; + xmax = x + 0.5 * width; + ymin = y - 0.5 * width * img.naxis2 / img.naxis1; + ymax = y + 0.5 * width * img.naxis2 / img.naxis1; + sigma = + find_peak (img.zd, img.naxis1, img.naxis2, (int) xmin, + (int) xmax, (int) ymin, (int) ymax, 2.0, 11, 11, + &x, &y); + printf ("%f %f %f\n", x, y, sigma); + if (sigma > 5.0) + { + reduce_point (&obs, img, frac * img.exptime, x, y); + obs.x[0] = x; + obs.y[0] = y; + obs.state = 2; } - } - cpgend(); + redraw = 1; + layer = 4; + } + continue; + } - free(img.zavg); - free(img.zstd); - free(img.zmax); - free(img.znum); - free(img.zd); - free(img.zsig); + // Find peak + if (c == 'p') + { + sigma = + find_peak (img.zd, img.naxis1, img.naxis2, (int) xmin, (int) xmax, + (int) ymin, (int) ymax, 2.0, 11, 11, &x, &y); + printf ("%f %f %f\n", x, y, sigma); + reduce_point (&obs, img, frac * img.exptime, x, y); + obs.x[0] = x; + obs.y[0] = y; + obs.state = 2; + redraw = 1; + continue; + } + + // Track + if (c == 't') + { + printf ("Provide satellite ID: "); + scanf ("%d", &obs.satno); + find_designation (obs.satno, obs.desig); + track (argv[1], obs, &img, frac); + layer = 4; + redraw = 1; + } + + if (c == '\t') + { + status = autotrack (argv[1], obs, &img, 1); + if (status == 1) + { + obs.satno = trk.satno; + find_designation (obs.satno, obs.desig); + track (argv[1], obs, &img, frac); + redraw = 1; + layer = 4; + } + } + + // Write obs + if (c == 'w') + { + write_observation (obs); + continue; + } + + // Reduce + if (c == 'm') + { + reduce_point (&obs, img, -1.0, x, y); + obs.x[0] = x; + obs.y[0] = y; + obs.state = 2; + redraw = 1; + continue; + } + + // Change fraction + if (c == 'e') + { + if (frac > 0.49 && frac < 0.51) + frac = 1.0; + else if (frac > 0.51) + frac = 0.0; + else if (frac < 0.49) + frac = 0.5; + printf ("Fraction: %.1f\n", frac); + iobject = 0; + } + + // Change fraction + if (c == 'E') + { + frac += 0.1; + if (frac > 1.0) + frac = 0.0; + printf ("Fraction: %.1f\n", frac); + iobject = 0; + } + + // Reduce + if (c == 'M' || c == 'D') + { + reduce_point (&obs, img, frac * img.exptime, x, y); + obs.x[0] = x; + obs.y[0] = y; + obs.state = 2; + redraw = 1; + continue; + } + + // Get designation + if (c == 'd') + { + printf ("Provide satellite number: "); + scanf ("%d", &obs.satno); + find_designation (obs.satno, obs.desig); + redraw = 1; + continue; + } + + // Toggle condition + if (c == 'C') + { + iconditions++; + if (iconditions > strlen (conditions) - 1) + iconditions = 0; + obs.conditions = conditions[iconditions]; + redraw = 1; + continue; + } + // Toggle behavior + if (c == 'B') + { + ibehavior++; + if (ibehavior > strlen (behavior) - 1) + ibehavior = 0; + obs.behavior = behavior[ibehavior]; + redraw = 1; + continue; + } + + // Reread + if (c == 'R') + { + img = read_fits (argv[1]); + redraw = 1; + continue; + } + + // Start + if (c == 's' && s.state == 0) + { + s.x0 = x; + s.y0 = y; + s.state = 1; + redraw = 1; + continue; + } + + // Fit + if (c == 'F') + { + fit (&obs, img); + redraw = 1; + continue; + } + + // End + if (c == 'f' && s.state == 1) + { + s.x1 = x; + s.y1 = y; + s.a = atan2 (s.y1 - s.y0, s.x1 - s.x0); + s.ca = cos (s.a); + s.sa = sin (s.a); + s.r = sqrt (pow (s.x0 - s.x1, 2) + pow (s.y0 - s.y1, 2)); + s.state = 2; + apply_mask_sigma (&img, s); + //s.zmin=zmin; + redraw = 1; + continue; + } + + // Mask pixel + if (c == 'X' && s.state != 0) + { + mask_pixel (&img, x, y); + apply_mask (&img, s); + redraw = 1; + continue; + } + + // Change level + if (c == '+' || c == '=') + { + s.zmin *= 1.01; + printf ("%.4f\n", s.zmin); + apply_mask_sigma (&img, s); + redraw = 1; + continue; + } + if (c == '-') + { + s.zmin /= 1.01; + printf ("%.4f\n", s.zmin); + apply_mask_sigma (&img, s); + redraw = 1; + continue; + } + + // Mean + if (isdigit (c)) + { + layer = c - '0' - 1; + redraw = 1; + continue; + } + + // Adjust cuts + if (c == 'v') + { + lcut *= 2; + hcut *= 2; + redraw = 1; + continue; + } + if (c == 'b') + { + lcut /= 2; + hcut /= 2; + if (lcut < 0.5) + lcut = 0.5; + if (hcut < 0.75) + hcut = 0.75; + redraw = 1; + continue; + } + + // Center + if (c == 'c') + { + xmin = x - 0.5 * width; + xmax = x + 0.5 * width; + ymin = y - 0.5 * width * img.naxis2 / img.naxis1; + ymax = y + 0.5 * width * img.naxis2 / img.naxis1; + redraw = 1; + continue; + } + + // Zoom + if (c == 'z') + { + width /= 2; + xmin = x - 0.5 * width; + xmax = x + 0.5 * width; + ymin = y - 0.5 * width * img.naxis2 / img.naxis1; + ymax = y + 0.5 * width * img.naxis2 / img.naxis1; + redraw = 1; + continue; + } + + // Unzoom + if (c == 'x') + { + width *= 2; + xmin = x - 0.5 * width; + xmax = x + 0.5 * width; + ymin = y - 0.5 * width * img.naxis2 / img.naxis1; + ymax = y + 0.5 * width * img.naxis2 / img.naxis1; + redraw = 1; + continue; + } + + // Reset + if (c == 'r') + { + xmin = 0.0; + xmax = (float) img.naxis1; + ymin = 0.0; + ymax = (float) img.naxis2; + width = img.naxis1; + lcut = 4.0; + hcut = 6.0; + s.state = 0; + s.fit = 0; + obs.state = 0; + redraw = 1; + continue; + } + + if (c == 'h') + { + printf ("Reduce Satellite tracks. "); + printf ("q Quit\n"); + printf + ("TAB track and stack objects automatically (only classfd sats)\n"); + printf ("w write IOD observation to observations.txt\n"); + printf + ("M/D measure stack and track position (also middle mouse button)\n"); + printf + ("e change fraction (0.0 to start, 0.5 for medium, 1.0 for the end)\n"); + printf ("d provide NORAD satellite number\n"); + printf + ("C toggle IOD observing conditions G-Good F-Fair P-Poor B-Bad T-Terrible E-Excellent\n"); + printf + ("B toggle behavior of sat.: F-Flash I-Irregular R-Regular S-Steady X-Uspecified E-Extremely weak\n"); + printf ("s select start of satellite track\n"); + printf ("f select end of satellite track\n"); + printf ("F fit satellite track\n"); + printf ("+/= Increase level of masking pixels\n"); + printf + ("- Lower level for masking pixels (This does not seem to work)\n"); + printf ("1 go to the mean pixel value FITS layer\n"); + printf ("2 go to the FITS standard deviation layer\n"); + printf ("3 go to the maximum pixel value FITS layer\n"); + printf + ("4 go to the frame number of the maximum pixel value FITS layer\n"); + printf + ("5 go to the stack and track layer (only after 't' or 'TAB')\n"); + printf ("v lower dynamic range\n"); + printf ("b increase dynamic range\n"); + printf ("c center on cursor\n"); + printf ("z zoom in at cursor\n"); + printf ("x zoom out at cursor\n"); + printf ("R/r reset to start\n"); + printf ("m measure position of pixel\n"); + printf ("t track & stack, give NORAD satellite number\n"); + printf ("E change fraction in tenths\n"); + printf ("X pixel mask (also with mouse scroll wheel)\n"); + } + } + + cpgend (); + + free (img.zavg); + free (img.zstd); + free (img.zmax); + free (img.znum); + free (img.zd); + free (img.zsig); return 0; } // Read fits image -struct image read_fits(char *filename) +struct image +read_fits (char *filename) { - int i,j,k,l,m; + int i, j, k, l, m; qfitsloader ql; - char key[FITS_LINESZ+1]; - char val[FITS_LINESZ+1]; + char key[FITS_LINESZ + 1]; + char val[FITS_LINESZ + 1]; struct image img; // Copy filename - strcpy(img.filename,filename); + strcpy (img.filename, filename); // Image size - img.naxis1=atoi(qfits_query_hdr(filename,"NAXIS1")); - img.naxis2=atoi(qfits_query_hdr(filename,"NAXIS2")); - img.naxis3=atoi(qfits_query_hdr(filename,"NAXIS3")); - img.nframes=atoi(qfits_query_hdr(filename,"NFRAMES")); + img.naxis1 = atoi (qfits_query_hdr (filename, "NAXIS1")); + img.naxis2 = atoi (qfits_query_hdr (filename, "NAXIS2")); + img.naxis3 = atoi (qfits_query_hdr (filename, "NAXIS3")); + img.nframes = atoi (qfits_query_hdr (filename, "NFRAMES")); // MJD - img.mjd=(double) atof(qfits_query_hdr(filename,"MJD-OBS")); - strcpy(img.nfd,qfits_query_hdr(filename,"DATE-OBS")); - img.exptime=atof(qfits_query_hdr(filename,"EXPTIME")); + img.mjd = (double) atof (qfits_query_hdr (filename, "MJD-OBS")); + strcpy (img.nfd, qfits_query_hdr (filename, "DATE-OBS")); + img.exptime = atof (qfits_query_hdr (filename, "EXPTIME")); // COSPAR ID - img.cospar=atoi(qfits_query_hdr(filename,"COSPAR")); + img.cospar = atoi (qfits_query_hdr (filename, "COSPAR")); // Transformation - img.mjd=atof(qfits_query_hdr(filename,"MJD-OBS")); - img.ra0=atof(qfits_query_hdr(filename,"CRVAL1")); - img.de0=atof(qfits_query_hdr(filename,"CRVAL2")); - img.x0=atof(qfits_query_hdr(filename,"CRPIX1")); - img.y0=atof(qfits_query_hdr(filename,"CRPIX2")); - img.a[0]=0.0; - img.a[1]=3600.0*atof(qfits_query_hdr(filename,"CD1_1")); - img.a[2]=3600.0*atof(qfits_query_hdr(filename,"CD1_2")); - img.b[0]=0.0; - img.b[1]=3600.0*atof(qfits_query_hdr(filename,"CD2_1")); - img.b[2]=3600.0*atof(qfits_query_hdr(filename,"CD2_2")); - img.xrms=3600.0*atof(qfits_query_hdr(filename,"CRRES1")); - img.yrms=3600.0*atof(qfits_query_hdr(filename,"CRRES2")); + img.mjd = atof (qfits_query_hdr (filename, "MJD-OBS")); + img.ra0 = atof (qfits_query_hdr (filename, "CRVAL1")); + img.de0 = atof (qfits_query_hdr (filename, "CRVAL2")); + img.x0 = atof (qfits_query_hdr (filename, "CRPIX1")); + img.y0 = atof (qfits_query_hdr (filename, "CRPIX2")); + img.a[0] = 0.0; + img.a[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_1")); + img.a[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_2")); + img.b[0] = 0.0; + img.b[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_1")); + img.b[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_2")); + img.xrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES1")); + img.yrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES2")); // Timestamps - img.dt=(float *) malloc(sizeof(float)*img.nframes); - for (i=0;i2) - year=c-4716; + dday = b - d - floor (30.6001 * e) + f; + if (e < 14) + month = e - 1; else - year=c-4715; + month = e - 13; - day=(int) floor(dday); - x=24.0*(dday-day); - x=3600.*fabs(x); - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - hour=x; - fsec=floor(1000.0*(sec-floor(sec))); - sprintf(date,"%04d%02d%02d%02d%02d%02.0f%03.0f",(int) year,(int) month,(int) day,(int) hour,(int) min,floor(sec),fsec); + if (month > 2) + year = c - 4716; + else + year = c - 4715; + + day = (int) floor (dday); + x = 24.0 * (dday - day); + x = 3600. * fabs (x); + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + hour = x; + fsec = floor (1000.0 * (sec - floor (sec))); + sprintf (date, "%04d%02d%02d%02d%02d%02.0f%03.0f", (int) year, (int) month, + (int) day, (int) hour, (int) min, floor (sec), fsec); return; } // Convert Decimal into Sexagesimal -void dec2s(double x,char *s,int type) +void +dec2s (double x, char *s, int type) { int i; - double sec,deg,min,fmin; + double sec, deg, min, fmin; char sign; - sign=(x<0 ? '-' : '+'); - x=60.*fabs(x); + sign = (x < 0 ? '-' : '+'); + x = 60. * fabs (x); - min=fmod(x,60.); - x=(x-min)/60.; + min = fmod (x, 60.); + x = (x - min) / 60.; // deg=fmod(x,60.); - deg=x; - if (type==0) - fmin=floor(1000.0*(min-floor(min))); + deg = x; + if (type == 0) + fmin = floor (1000.0 * (min - floor (min))); else - fmin=floor(100.0*(min-floor(min))); + fmin = floor (100.0 * (min - floor (min))); - if (type==0) - sprintf(s,"%02.0f%02.0f%03.0f",deg,floor(min),fmin); + if (type == 0) + sprintf (s, "%02.0f%02.0f%03.0f", deg, floor (min), fmin); else - sprintf(s,"%c%02.0f%02.0f%02.0f",sign,deg,floor(min),fmin); + sprintf (s, "%c%02.0f%02.0f%02.0f", sign, deg, floor (min), fmin); return; } // Linear least squares fit -float linear_fit(float x[],float y[],int n,float a[],float sa[]) +float +linear_fit (float x[], float y[], int n, float a[], float sa[]) { int i; - float sum,sumx,sumy,sumxx,sumxy; - float w,d,chi2,covar,r; + float sum, sumx, sumy, sumxx, sumxy; + float w, d, chi2, covar, r; // Compute sums - sum=sumx=sumy=sumxx=sumxy=0.; - for (i=0;i 0 && (c=fgetc(file)) != EOF && c != '\n') + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\t') - c=' '; + c = ' '; if (c == '\n') s[i++] = c; s[i] = '\0'; @@ -1466,22 +1685,27 @@ int fgetline(FILE *file,char *s,int lim) } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } diff --git a/src/residuals.c b/src/residuals.c index f737012..c92b80e 100644 --- a/src/residuals.c +++ b/src/residuals.c @@ -11,582 +11,648 @@ #define NMAX 256 #define D2R M_PI/180.0 #define R2D 180.0/M_PI -#define XKMPER 6378.135 // Earth radius in km -#define XKMPAU 149597879.691 // AU in km +#define XKMPER 6378.135 // Earth radius in km +#define XKMPAU 149597879.691 // AU in km #define FLAT (1.0/298.257) -long Isat=0; -long Isatsel=0; +long Isat = 0; +long Isatsel = 0; extern double SGDP4_jd0; -struct point { - int flag,satno; - double mjd,ra,de; - float st,sr; +struct point +{ + int flag, satno; + double mjd, ra, de; + float st, sr; char iod_line[LIM]; xyz_t obspos; }; -struct site { +struct site +{ int id; - double lng,lat; + double lng, lat; float alt; char observer[64]; }; -struct data { +struct data +{ int n; struct point *p; -} ; -struct point decode_iod_observation(char *iod_line); -struct site get_site(int site_id); -int fgetline(FILE *file,char *s,int lim); -double modulo(double x,double y); -double gmst(double mjd); -double dgmst(double mjd); -double date2mjd(int year,int month,double day); -void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de); -void usage(); -void obspos_xyz(double mjd,double lng,double lat,float alt,xyz_t *pos,xyz_t *vel); -struct data read_data(char *filename); -void forward(double ra0,double de0,double ra,double de,double *x,double *y); +}; +struct point decode_iod_observation (char *iod_line); +struct site get_site (int site_id); +int fgetline (FILE * file, char *s, int lim); +double modulo (double x, double y); +double gmst (double mjd); +double dgmst (double mjd); +double date2mjd (int year, int month, double day); +void precess (double mjd0, double ra0, double de0, double mjd, double *ra, + double *de); +void usage (); +void obspos_xyz (double mjd, double lng, double lat, float alt, xyz_t * pos, + xyz_t * vel); +struct data read_data (char *filename); +void forward (double ra0, double de0, double ra, double de, double *x, + double *y); -void compute_residual(char *filename,struct point p,int satno) +void +compute_residual (char *filename, struct point p, int satno) { - int i,imode; + int i, imode; FILE *file; orbit_t orb; - xyz_t satpos,satvel; - double dx,dy,dz; - double r[2],ra,de; - double rx[2],ry[2],dr,dt,drx,dry; + xyz_t satpos, satvel; + double dx, dy, dz; + double r[2], ra, de; + double rx[2], ry[2], dr, dt, drx, dry; double jd; double age; - + // Open catalog - file=fopen(filename,"r"); - if (file==NULL) - fatal_error("Failed to open %s\n",filename); + file = fopen (filename, "r"); + if (file == NULL) + fatal_error ("Failed to open %s\n", filename); // Read TLE - if (satno==0) - read_twoline(file,p.satno,&orb); + if (satno == 0) + read_twoline (file, p.satno, &orb); else - read_twoline(file,satno,&orb); - fclose(file); + read_twoline (file, satno, &orb); + fclose (file); // Check for match - if (orb.satno!=p.satno && satno==0) { - // fprintf(stderr,"object %d not found in %s\n",p.satno,filename); - return; - } - + if (orb.satno != p.satno && satno == 0) + { + // fprintf(stderr,"object %d not found in %s\n",p.satno,filename); + return; + } + // Initialize - imode=init_sgdp4(&orb); - if (imode==SGDP4_ERROR) { - fprintf(stderr,"Error initializing SGDP4\n"); - exit(0); - } - - for (i=0;i<2;i++) { - jd=p.mjd+2400000.5+(double) i/86400; + imode = init_sgdp4 (&orb); + if (imode == SGDP4_ERROR) + { + fprintf (stderr, "Error initializing SGDP4\n"); + exit (0); + } - // Compute position - satpos_xyz(jd,&satpos,&satvel); - age=jd-SGDP4_jd0; + for (i = 0; i < 2; i++) + { + jd = p.mjd + 2400000.5 + (double) i / 86400; - // compute difference vector - dx=satpos.x-p.obspos.x; - dy=satpos.y-p.obspos.y; - dz=satpos.z-p.obspos.z; - - // Celestial position - r[i]=sqrt(dx*dx+dy*dy+dz*dz); - ra=modulo(atan2(dy,dx)*R2D,360.0); - de=asin(dz/r[i])*R2D; + // Compute position + satpos_xyz (jd, &satpos, &satvel); + age = jd - SGDP4_jd0; - // Compute offset - forward(p.ra,p.de,ra,de,&rx[i],&ry[i]); - } - drx=rx[1]-rx[0]; - dry=ry[1]-ry[0]; - dt=-(rx[0]*drx+ry[0]*dry)/(drx*drx+dry*dry); - dr=sqrt(pow(dry*rx[0]-drx*ry[0],2)/(drx*drx+dry*dry)); - if ((-rx[0]*drx-ry[0]*dry)<0.0) - dr*=-1; - printf("%s | %8.5f deg %9.4f sec %7.3f day, %.1f km\n",p.iod_line,dr,dt,age,r[0]); + // compute difference vector + dx = satpos.x - p.obspos.x; + dy = satpos.y - p.obspos.y; + dz = satpos.z - p.obspos.z; + + // Celestial position + r[i] = sqrt (dx * dx + dy * dy + dz * dz); + ra = modulo (atan2 (dy, dx) * R2D, 360.0); + de = asin (dz / r[i]) * R2D; + + // Compute offset + forward (p.ra, p.de, ra, de, &rx[i], &ry[i]); + } + drx = rx[1] - rx[0]; + dry = ry[1] - ry[0]; + dt = -(rx[0] * drx + ry[0] * dry) / (drx * drx + dry * dry); + dr = sqrt (pow (dry * rx[0] - drx * ry[0], 2) / (drx * drx + dry * dry)); + if ((-rx[0] * drx - ry[0] * dry) < 0.0) + dr *= -1; + printf ("%s | %8.5f deg %9.4f sec %7.3f day, %.1f km\n", p.iod_line, dr, dt, + age, r[0]); //printf("%12.8lf %8.3f %8.3f\n",p.mjd,3600*rx[0],3600*ry[0]); return; } -void split_file(struct data d,float dtmax) +void +split_file (struct data d, float dtmax) { - int i,j,flag=0; + int i, j, flag = 0; FILE *file; char filename[LIM]; - double mjd0,dt; + double mjd0, dt; - for (i=0,j=0;idtmax) { - if (file!=NULL) - fclose(file); - flag=0; - j++; - } - } - if (flag==0) { - mjd0=d.p[i].mjd; - flag=1; - sprintf(filename,"split%04d.dat",j+1); - file=fopen(filename,"w"); + for (i = 0, j = 0; i < d.n; i++) + { + if (flag == 1) + { + dt = 86400 * (d.p[i].mjd - mjd0); + if (dt > dtmax) + { + if (file != NULL) + fclose (file); + flag = 0; + j++; + } + } + if (flag == 0) + { + mjd0 = d.p[i].mjd; + flag = 1; + sprintf (filename, "split%04d.dat", j + 1); + file = fopen (filename, "w"); + } + fprintf (file, "%s\n", d.p[i].iod_line); } - fprintf(file,"%s\n",d.p[i].iod_line); - } - if (file!=NULL) - fclose(file); + if (file != NULL) + fclose (file); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int i,arg=0,split=0; + int i, arg = 0, split = 0; struct data d; - char *datafile,catalog[LIM]; + char *datafile, catalog[LIM]; char *env; float dt; - int verbose=0,satno=0; + int verbose = 0, satno = 0; - env=getenv("ST_TLEDIR"); - sprintf(catalog,"%s/classfd.tle",env); + env = getenv ("ST_TLEDIR"); + sprintf (catalog, "%s/classfd.tle", env); // Decode options - while ((arg=getopt(argc,argv,"d:c:hs:vi:"))!=-1) { - switch(arg) { - case 'd': - datafile=optarg; - break; + while ((arg = getopt (argc, argv, "d:c:hs:vi:")) != -1) + { + switch (arg) + { + case 'd': + datafile = optarg; + break; - case 'v': - verbose=1; - break; + case 'v': + verbose = 1; + break; - case 'i': - satno=atoi(optarg); - break; + case 'i': + satno = atoi (optarg); + break; - case 'c': - strcpy(catalog,optarg); - break; + case 'c': + strcpy (catalog, optarg); + break; - case 's': - dt=atof(optarg); - split=1; - break; + case 's': + dt = atof (optarg); + split = 1; + break; - case 'h': - usage(); - return 0; - break; + case 'h': + usage (); + return 0; + break; - default: - usage(); - return 0; + default: + usage (); + return 0; + } } - } // Read data - d=read_data(datafile); + d = read_data (datafile); - if (verbose==1) { - for (i=0;ix=gc*cos(lat*D2R)*cos(theta*D2R)*XKMPER; - pos->y=gc*cos(lat*D2R)*sin(theta*D2R)*XKMPER; - pos->z=gs*sin(lat*D2R)*XKMPER; - vel->x=-gc*cos(lat*D2R)*sin(theta*D2R)*XKMPER*dtheta; - vel->y=gc*cos(lat*D2R)*cos(theta*D2R)*XKMPER*dtheta; - vel->z=0.0; + pos->x = gc * cos (lat * D2R) * cos (theta * D2R) * XKMPER; + pos->y = gc * cos (lat * D2R) * sin (theta * D2R) * XKMPER; + pos->z = gs * sin (lat * D2R) * XKMPER; + vel->x = -gc * cos (lat * D2R) * sin (theta * D2R) * XKMPER * dtheta; + vel->y = gc * cos (lat * D2R) * cos (theta * D2R) * XKMPER * dtheta; + vel->z = 0.0; return; } // Precess a celestial position -void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de) +void +precess (double mjd0, double ra0, double de0, double mjd, double *ra, + double *de) { - double t0,t; - double zeta,z,theta; - double a,b,c; + double t0, t; + double zeta, z, theta; + double a, b, c; // Angles in radians - ra0*=D2R; - de0*=D2R; + ra0 *= D2R; + de0 *= D2R; // Time in centuries - t0=(mjd0-51544.5)/36525.0; - t=(mjd-mjd0)/36525.0; + t0 = (mjd0 - 51544.5) / 36525.0; + t = (mjd - mjd0) / 36525.0; // Precession angles - zeta=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - zeta+=(0.30188-0.000344*t0)*t*t+0.017998*t*t*t; - zeta*=D2R/3600.0; - z=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - z+=(1.09468+0.000066*t0)*t*t+0.018203*t*t*t; - z*=D2R/3600.0; - theta=(2004.3109-0.85330*t0-0.000217*t0*t0)*t; - theta+=-(0.42665+0.000217*t0)*t*t-0.041833*t*t*t; - theta*=D2R/3600.0; - - a=cos(de0)*sin(ra0+zeta); - b=cos(theta)*cos(de0)*cos(ra0+zeta)-sin(theta)*sin(de0); - c=sin(theta)*cos(de0)*cos(ra0+zeta)+cos(theta)*sin(de0); + zeta = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + zeta += (0.30188 - 0.000344 * t0) * t * t + 0.017998 * t * t * t; + zeta *= D2R / 3600.0; + z = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + z += (1.09468 + 0.000066 * t0) * t * t + 0.018203 * t * t * t; + z *= D2R / 3600.0; + theta = (2004.3109 - 0.85330 * t0 - 0.000217 * t0 * t0) * t; + theta += -(0.42665 + 0.000217 * t0) * t * t - 0.041833 * t * t * t; + theta *= D2R / 3600.0; - *ra=(atan2(a,b)+z)*R2D; - *de=asin(c)*R2D; + a = cos (de0) * sin (ra0 + zeta); + b = cos (theta) * cos (de0) * cos (ra0 + zeta) - sin (theta) * sin (de0); + c = sin (theta) * cos (de0) * cos (ra0 + zeta) + cos (theta) * sin (de0); - if (*ra<360.0) - *ra+=360.0; - if (*ra>360.0) - *ra-=360.0; + *ra = (atan2 (a, b) + z) * R2D; + *de = asin (c) * R2D; + + if (*ra < 360.0) + *ra += 360.0; + if (*ra > 360.0) + *ra -= 360.0; return; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; + int c, i = 0; - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\t') - c=' '; + c = ' '; if (c == '\n') s[i++] = c; s[i] = '\0'; return i; } -void usage() +void +usage () { - printf("bla\n"); + printf ("bla\n"); return; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // Read data -struct data read_data(char *filename) +struct data +read_data (char *filename) { - int i=0; + int i = 0; char line[LIM]; FILE *file; struct data d; // Open file - file=fopen(filename,"r"); - if (file==NULL) { - fprintf(stderr,"Failed to open %s\n",filename); - exit(1); - } + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "Failed to open %s\n", filename); + exit (1); + } // Count lines - while (fgetline(file,line,LIM)>0) + while (fgetline (file, line, LIM) > 0) i++; - d.n=i; + d.n = i; // Allocate - d.p=(struct point *) malloc(sizeof(struct point)*d.n); + d.p = (struct point *) malloc (sizeof (struct point) * d.n); // Rewind file - rewind(file); + rewind (file); // Read data - i=0; - while (fgetline(file,line,LIM)>0) { - if (isdigit(line[0])) - d.p[i++]=decode_iod_observation(line); - } + i = 0; + while (fgetline (file, line, LIM) > 0) + { + if (isdigit (line[0])) + d.p[i++] = decode_iod_observation (line); + } // Close file - fclose(file); + fclose (file); return d; } // Get a x and y from a RA and Decl -void forward(double ra0,double de0,double ra,double de,double *x,double *y) +void +forward (double ra0, double de0, double ra, double de, double *x, double *y) { - int i,status; - double phi,theta; + int i, status; + double phi, theta; struct celprm cel; // Initialize Reference Angles - celini(&cel); - cel.ref[0]=ra0; - cel.ref[1]=de0; - cel.ref[2]=999.; - cel.ref[3]=999.; - cel.flag=0.; - strcpy(cel.prj.code,"TAN"); + celini (&cel); + cel.ref[0] = ra0; + cel.ref[1] = de0; + cel.ref[2] = 999.; + cel.ref[3] = 999.; + cel.flag = 0.; + strcpy (cel.prj.code, "TAN"); - if (celset(&cel)) { - printf("Error in Projection (celset)\n"); - return; - } - cels2x(&cel,1,0,1,1,&ra,&de,&phi,&theta,x,y,&status); + if (celset (&cel)) + { + printf ("Error in Projection (celset)\n"); + return; + } + cels2x (&cel, 1, 0, 1, 1, &ra, &de, &phi, &theta, x, y, &status); return; } diff --git a/src/reverse.c b/src/reverse.c index 0b78db1..e06c6a0 100644 --- a/src/reverse.c +++ b/src/reverse.c @@ -4,29 +4,31 @@ #include // Get a RA and Decl from x and y -void reverse(double ra0,double de0,double x,double y,double *ra,double *de) +void +reverse (double ra0, double de0, double x, double y, double *ra, double *de) { - int i,status; - double phi,theta; + int i, status; + double phi, theta; struct celprm cel; - x/=3600.; - y/=3600.; + x /= 3600.; + y /= 3600.; // Initialize Reference Angles - celini(&cel); - cel.ref[0]=ra0; - cel.ref[1]=de0; - cel.ref[2]=999.; - cel.ref[3]=999.; - cel.flag=0.; - strcpy(cel.prj.code,"STG"); - - if (celset(&cel)) { - printf("Error in Projection (celset)\n"); - return; - } - celx2s(&cel,1,0,1,1,&x,&y,&phi,&theta,ra,de,&status); + celini (&cel); + cel.ref[0] = ra0; + cel.ref[1] = de0; + cel.ref[2] = 999.; + cel.ref[3] = 999.; + cel.flag = 0.; + strcpy (cel.prj.code, "STG"); + + if (celset (&cel)) + { + printf ("Error in Projection (celset)\n"); + return; + } + celx2s (&cel, 1, 0, 1, 1, &x, &y, &phi, &theta, ra, de, &status); return; } diff --git a/src/runsched.c b/src/runsched.c index ee67d54..dd19918 100644 --- a/src/runsched.c +++ b/src/runsched.c @@ -23,117 +23,142 @@ #define FINISHED 2 // Observation struct contains observation time, celestial coords and camera name -struct observation { - char stime[32],sra[32],sde[32],camname[15],startstop[10]; +struct observation +{ + char stime[32], sra[32], sde[32], camname[15], startstop[10]; time_t ptime; float dt; }; -int fgetline(FILE *file,char *s,int lim); -void send_position(char *sra,char *sde,char *datadir,char *obsdir,char *camname); -void stop_obs(char *datadir,char *obsdir,char *camname); -time_t decode_time(char *stm); +int fgetline (FILE * file, char *s, int lim); +void send_position (char *sra, char *sde, char *datadir, char *obsdir, + char *camname); +void stop_obs (char *datadir, char *obsdir, char *camname); +time_t decode_time (char *stm); -int main(int argc, char *argv[]) +int +main (int argc, char *argv[]) { - int i=0,nobs,flag=0; - time_t rawtime,aimtime; - struct tm *ptm,*rtm; - char buf[20],line[LIM],stm[20],sra[32],sde[32],pra[32],pde[32]; + int i = 0, nobs, flag = 0; + time_t rawtime, aimtime; + struct tm *ptm, *rtm; + char buf[20], line[LIM], stm[20], sra[32], sde[32], pra[32], pde[32]; FILE *file; struct observation obs[NMAX]; char *env; - char datadir[128],obsdir[128]; - int nextobs, dtnext; + char datadir[128], obsdir[128]; + int nextobs, dtnext; // Get environment variables - env=getenv("ST_DATADIR"); - if (env!=NULL) { - strcpy(datadir,env); - } else { - printf("ST_DATADIR environment variable not found.\n"); - } + env = getenv ("ST_DATADIR"); + if (env != NULL) + { + strcpy (datadir, env); + } + else + { + printf ("ST_DATADIR environment variable not found.\n"); + } // Get environment variables - env=getenv("ST_OBSDIR"); - if (env!=NULL) { - strcpy(obsdir,env); - } else { - printf("ST_OBSDIR environment variable not found.\n"); - } + env = getenv ("ST_OBSDIR"); + if (env != NULL) + { + strcpy (obsdir, env); + } + else + { + printf ("ST_OBSDIR environment variable not found.\n"); + } // For ever loop - for (;;) { - // Read file - i=0; - file=fopen("schedule.txt","r"); - while (fgetline(file,line,LIM)>0) { - sscanf(line,"%s %s %s %s %s",obs[i].stime,obs[i].sra,obs[i].sde,obs[i].camname,obs[i].startstop); - obs[i].ptime=decode_time(obs[i].stime); - - i++; - } - fclose(file); - nobs=i; + for (;;) + { + // Read file + i = 0; + file = fopen ("schedule.txt", "r"); + while (fgetline (file, line, LIM) > 0) + { + sscanf (line, "%s %s %s %s %s", obs[i].stime, obs[i].sra, + obs[i].sde, obs[i].camname, obs[i].startstop); + obs[i].ptime = decode_time (obs[i].stime); - // Get local time - time(&rawtime); - //rawtime-=3600; - - - // Print UTC time - ptm=gmtime(&rawtime); - strftime(buf,32,"%Y-%m-%dT%H:%M:%S",ptm); - - // Make raw time UTC to compare with scheduled time - rawtime=mktime(ptm); - - // Show current raw time, just to check - // printf("%s\n",ctime(&rawtime)); - - // Compute time differences - for (i=0;i0.0) { - if(obs[i].dt < dtnext){ - nextobs=i; - dtnext=obs[i].dt; + i++; } - // printf("%4.0f %s %s %s %s\n",obs[i].dt,obs[i].stime,obs[i].sra,obs[i].sde,obs[i].startstop); - // break; - } else if (obs[i].dt==0) { - if(strstr(obs[i].startstop,"tart")!=NULL){ - //printf("Slewing to %s %s\n",obs[i].sra,obs[i].sde); - send_position(obs[i].sra,obs[i].sde,datadir,obsdir,obs[i].camname); - } else if(strstr(obs[i].startstop,"top")!=NULL){ - stop_obs(datadir,obsdir,obs[i].camname); + fclose (file); + nobs = i; + + // Get local time + time (&rawtime); + //rawtime-=3600; + + + // Print UTC time + ptm = gmtime (&rawtime); + strftime (buf, 32, "%Y-%m-%dT%H:%M:%S", ptm); + + // Make raw time UTC to compare with scheduled time + rawtime = mktime (ptm); + + // Show current raw time, just to check + // printf("%s\n",ctime(&rawtime)); + + // Compute time differences + for (i = 0; i < nobs; i++) + { + obs[i].dt = difftime (obs[i].ptime, rawtime); } - } + + nextobs = -1; + dtnext = 9999999; + // Loop over observations + for (i = 0; i < nobs; i++) + { + if (obs[i].dt > 0.0) + { + if (obs[i].dt < dtnext) + { + nextobs = i; + dtnext = obs[i].dt; + } + // printf("%4.0f %s %s %s %s\n",obs[i].dt,obs[i].stime,obs[i].sra,obs[i].sde,obs[i].startstop); + // break; + } + else if (obs[i].dt == 0) + { + if (strstr (obs[i].startstop, "tart") != NULL) + { + //printf("Slewing to %s %s\n",obs[i].sra,obs[i].sde); + send_position (obs[i].sra, obs[i].sde, datadir, obsdir, + obs[i].camname); + } + else if (strstr (obs[i].startstop, "top") != NULL) + { + stop_obs (datadir, obsdir, obs[i].camname); + } + } + } + + if (nextobs >= 0) + { + // print next observation data if any found + printf ("%4.0f %s %s %s %s\n", obs[nextobs].dt, obs[nextobs].stime, + obs[nextobs].sra, obs[nextobs].sde, obs[nextobs].startstop); + } + // Sleep + sleep (1); } - - if(nextobs>=0){ - // print next observation data if any found - printf("%4.0f %s %s %s %s\n",obs[nextobs].dt,obs[nextobs].stime,obs[nextobs].sra,obs[nextobs].sde,obs[nextobs].startstop); - } - // Sleep - sleep(1); - } return 0; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; - - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + int c, i = 0; + + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; @@ -142,155 +167,176 @@ int fgetline(FILE *file,char *s,int lim) } // Read data/cameras.txt in search of specified camera name and return complete camera details line -int read_cameras(char *camname,char *datadir,char *camera) +int +read_cameras (char *camname, char *datadir, char *camera) { FILE *file; - char line[127],filename[127]; + char line[127], filename[127]; - sprintf(filename,"%s/data/cameras.txt",datadir); - file=fopen(filename,"r"); - if (file==NULL) { - printf("File with camera information not found!\n"); - return -1; - } - while (fgets(line,LIM,file)!=NULL) { - // Skip commented lines - if (strstr(line,"#")!=NULL) - continue; - if(strstr(line, camname)!=NULL){ - strcpy(camera, line); - return 0; + sprintf (filename, "%s/data/cameras.txt", datadir); + file = fopen (filename, "r"); + if (file == NULL) + { + printf ("File with camera information not found!\n"); + return -1; } - } - fclose(file); + while (fgets (line, LIM, file) != NULL) + { + // Skip commented lines + if (strstr (line, "#") != NULL) + continue; + if (strstr (line, camname) != NULL) + { + strcpy (camera, line); + return 0; + } + } + fclose (file); return -1; } // Send new position to telescope -void send_position(char *sra,char *sde,char *datadir,char *obsdir,char *camname) +void +send_position (char *sra, char *sde, char *datadir, char *obsdir, + char *camname) { int skt, port; struct hostent *he; struct sockaddr_in addr; char packet[LIM]; FILE *file; - float ra,de; - char camera[128],fname[128]; + float ra, de; + char camera[128], fname[128]; float f; char s[31]; // Check if camera is fixed // read complete line from data/cameras.txt describing the scheduled camera - read_cameras(camname,datadir,camera); // search for camera name - sscanf(camera,"%s %f %f %f %f %s", s, &f, &f, &f, &f, s); + read_cameras (camname, datadir, camera); // search for camera name + sscanf (camera, "%s %f %f %f %f %s", s, &f, &f, &f, &f, s); // Look for "fix" string to jump over slewing routines. - if(strstr(s,"ix")==NULL){ - - // Old packet style - // sprintf(packet,"%s%s",sra,sde); + if (strstr (s, "ix") == NULL) + { - // New packet style (as of 2013-08-20) - sprintf(packet,"%s%s",sra,sde); + // Old packet style + // sprintf(packet,"%s%s",sra,sde); - printf("Slewing to %s %s\n",sra,sde); + // New packet style (as of 2013-08-20) + sprintf (packet, + "%s%s", + sra, sde); - // Send TCP packet - skt=socket(AF_INET,SOCK_STREAM,0); - addr.sin_family=AF_INET; - port=PORT; - addr.sin_port=htons(port); - he=gethostbyname(IP); - bcopy(he->h_addr,(struct in_addr *) &addr.sin_addr,he->h_length); - while((connect(skt,(struct sockaddr *) &addr,sizeof(addr))<0) && (port < MAXPORT)) { - fprintf(stderr,"Connection refused by remote host on port %04d.\n",port); - port++; - // Skip port 7265... used by some other service? - if(port==7265) port++; - fprintf(stderr,"Trying port %04d.\n",port); + printf ("Slewing to %s %s\n", sra, sde); - addr.sin_port=htons(port); - he=gethostbyname(IP); - bcopy(he->h_addr,(struct in_addr *) &addr.sin_addr,he->h_length); + // Send TCP packet + skt = socket (AF_INET, SOCK_STREAM, 0); + addr.sin_family = AF_INET; + port = PORT; + addr.sin_port = htons (port); + he = gethostbyname (IP); + bcopy (he->h_addr, (struct in_addr *) &addr.sin_addr, he->h_length); + while ((connect (skt, (struct sockaddr *) &addr, sizeof (addr)) < 0) + && (port < MAXPORT)) + { + fprintf (stderr, + "Connection refused by remote host on port %04d.\n", port); + port++; + // Skip port 7265... used by some other service? + if (port == 7265) + port++; + fprintf (stderr, "Trying port %04d.\n", port); + addr.sin_port = htons (port); + he = gethostbyname (IP); + bcopy (he->h_addr, (struct in_addr *) &addr.sin_addr, he->h_length); + + } + if (port >= MAXPORT) + return; + + printf ("Connected to Indi server on port %04d.\n", port); + + write (skt, packet, strlen (packet)); + close (skt); } - if(port>=MAXPORT) return; - printf("Connected to Indi server on port %04d.\n",port); + printf ("Starting new observation\n"); - write(skt,packet,strlen(packet)); - close(skt); - } - - printf("Starting new observation\n"); - // Set restart - sprintf(fname,"%s/control/state.txt",obsdir); - file=fopen(fname,"w"); - if (file!=NULL) { - fprintf(file,"restart"); - fclose(file); - } + sprintf (fname, "%s/control/state.txt", obsdir); + file = fopen (fname, "w"); + if (file != NULL) + { + fprintf (file, "restart"); + fclose (file); + } // Set position - sprintf(fname,"%s/control/position.txt",obsdir); - file=fopen(fname,"w"); - if (file!=NULL) { - fprintf(file,"%s %s\n",sra,sde); - fclose(file); - } + sprintf (fname, "%s/control/position.txt", obsdir); + file = fopen (fname, "w"); + if (file != NULL) + { + fprintf (file, "%s %s\n", sra, sde); + fclose (file); + } // Set camera - sprintf(fname,"%s/control/camera.txt",obsdir); - file=fopen(fname,"w"); - if (file!=NULL) { - fprintf(file,"%s",camera); - fclose(file); - } + sprintf (fname, "%s/control/camera.txt", obsdir); + file = fopen (fname, "w"); + if (file != NULL) + { + fprintf (file, "%s", camera); + fclose (file); + } return; } // Send stop observation signal -void stop_obs(char *datadir,char *obsdir,char *camname) +void +stop_obs (char *datadir, char *obsdir, char *camname) { FILE *file; - char camera[128],fname[128]; + char camera[128], fname[128]; float f; char s[31]; // Retrieve Camera data // read complete line from data/cameras.txt describing the scheduled camera - read_cameras(camname,datadir,camera); // search for camera name - sscanf(camera,"%s %f %f %f %f %s", s, &f, &f, &f, &f, s); + read_cameras (camname, datadir, camera); // search for camera name + sscanf (camera, "%s %f %f %f %f %s", s, &f, &f, &f, &f, s); + + printf ("Stop observation\n"); - printf("Stop observation\n"); - // Set stop - sprintf(fname,"%s/control/state.txt",obsdir); - file=fopen(fname,"w"); - if (file!=NULL) { - fprintf(file,"stop"); - fclose(file); - } + sprintf (fname, "%s/control/state.txt", obsdir); + file = fopen (fname, "w"); + if (file != NULL) + { + fprintf (file, "stop"); + fclose (file); + } return; } // Decode time -time_t decode_time(char *stm) +time_t +decode_time (char *stm) { time_t aimtime; struct tm *rtm; int d; - rtm=gmtime(&aimtime); - sscanf(stm,"%04d-%02d-%02dT%02d:%02d:%02d",&rtm->tm_year,&rtm->tm_mon,&rtm->tm_mday,&rtm->tm_hour,&rtm->tm_min,&rtm->tm_sec); - rtm->tm_year-=1900; + rtm = gmtime (&aimtime); + sscanf (stm, "%04d-%02d-%02dT%02d:%02d:%02d", &rtm->tm_year, &rtm->tm_mon, + &rtm->tm_mday, &rtm->tm_hour, &rtm->tm_min, &rtm->tm_sec); + rtm->tm_year -= 1900; rtm->tm_mon--; - aimtime=mktime(rtm); + aimtime = mktime (rtm); return aimtime; } diff --git a/src/rv2tle.c b/src/rv2tle.c index 2811f24..b5960b5 100644 --- a/src/rv2tle.c +++ b/src/rv2tle.c @@ -8,7 +8,7 @@ #include #define LIM 1024 -#define XKE 0.07436680 // Guassian Gravitational Constant +#define XKE 0.07436680 // Guassian Gravitational Constant #define XKMPER 6378.135 #define AE 1.0 #define XMNPDA 1440.0 @@ -18,330 +18,374 @@ extern double SGDP4_jd0; // Dot product -float dot(xyz_t a,xyz_t b) +float +dot (xyz_t a, xyz_t b) { - return a.x*b.x+a.y*b.y+a.z*b.z; + return a.x * b.x + a.y * b.y + a.z * b.z; } // Magnitude -double magnitude(xyz_t a) +double +magnitude (xyz_t a) { - return sqrt(dot(a,a)); + return sqrt (dot (a, a)); } // Cross product -xyz_t cross(xyz_t a,xyz_t b) +xyz_t +cross (xyz_t a, xyz_t b) { xyz_t c; - c.x=a.y*b.z-a.z*b.y; - c.y=a.z*b.x-a.x*b.z; - c.z=a.x*b.y-a.y*b.x; + c.x = a.y * b.z - a.z * b.y; + c.y = a.z * b.x - a.x * b.z; + c.z = a.x * b.y - a.y * b.x; return c; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Compute Date from Julian Day -void mjd2date(double mjd,int *year,int *month,double *day) +void +mjd2date (double mjd, int *year, int *month, double *day) { - double f,jd; - int z,alpha,a,b,c,d,e; + double f, jd; + int z, alpha, a, b, c, d, e; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - *day=b-d-floor(30.6001*e)+f; - if (e<14) - *month=e-1; + if (z < 2299161) + a = z; else - *month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (*month>2) - *year=c-4716; + *day = b - d - floor (30.6001 * e) + f; + if (e < 14) + *month = e - 1; else - *year=c-4715; + *month = e - 13; + + if (*month > 2) + *year = c - 4716; + else + *year = c - 4715; return; } // MJD to DOY -double mjd2doy(double mjd,int *yr) +double +mjd2doy (double mjd, int *yr) { - int year,month,k=2; - double day,doy; - - mjd2date(mjd,&year,&month,&day); + int year, month, k = 2; + double day, doy; - if (year%4==0 && year%400!=0) - k=1; + mjd2date (mjd, &year, &month, &day); - doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - *yr=year; + doy = + floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30; + + *yr = year; return doy; } // Clasical elements -orbit_t classel(int ep_year,double ep_day,xyz_t r,xyz_t v) +orbit_t +classel (int ep_year, double ep_day, xyz_t r, xyz_t v) { int i; - double rm,vm,vm2,rvm,mu=1.0;; - double chi,xp,yp,sx,cx,b,ee; - double a,ecc,incl,node,peri,mm,n; - xyz_t h,e,kk,nn; + double rm, vm, vm2, rvm, mu = 1.0;; + double chi, xp, yp, sx, cx, b, ee; + double a, ecc, incl, node, peri, mm, n; + xyz_t h, e, kk, nn; orbit_t orb; - r.x/=XKMPER; - r.y/=XKMPER; - r.z/=XKMPER; - v.x/=(XKE*XKMPER/AE*XMNPDA/86400.0); - v.y/=(XKE*XKMPER/AE*XMNPDA/86400.0); - v.z/=(XKE*XKMPER/AE*XMNPDA/86400.0); + r.x /= XKMPER; + r.y /= XKMPER; + r.z /= XKMPER; + v.x /= (XKE * XKMPER / AE * XMNPDA / 86400.0); + v.y /= (XKE * XKMPER / AE * XMNPDA / 86400.0); + v.z /= (XKE * XKMPER / AE * XMNPDA / 86400.0); - rm=magnitude(r); - vm2=dot(v,v); - rvm=dot(r,v); - h=cross(r,v); - chi=dot(h,h)/mu; + rm = magnitude (r); + vm2 = dot (v, v); + rvm = dot (r, v); + h = cross (r, v); + chi = dot (h, h) / mu; - e.x=(vm2/mu-1.0/rm)*r.x-rvm/mu*v.x; - e.y=(vm2/mu-1.0/rm)*r.y-rvm/mu*v.y; - e.z=(vm2/mu-1.0/rm)*r.z-rvm/mu*v.z; + e.x = (vm2 / mu - 1.0 / rm) * r.x - rvm / mu * v.x; + e.y = (vm2 / mu - 1.0 / rm) * r.y - rvm / mu * v.y; + e.z = (vm2 / mu - 1.0 / rm) * r.z - rvm / mu * v.z; - a=pow(2.0/rm-vm2/mu,-1); - ecc=magnitude(e); - incl=acos(h.z/magnitude(h))*R2D; - - kk.x=0.0; - kk.y=0.0; - kk.z=1.0; - nn=cross(kk,h); - if (nn.x==0.0 && nn.y==0.0) - nn.x=1.0; - node=atan2(nn.y,nn.x)*R2D; - if (node<0.0) - node+=360.0; + a = pow (2.0 / rm - vm2 / mu, -1); + ecc = magnitude (e); + incl = acos (h.z / magnitude (h)) * R2D; - peri=acos(dot(nn,e)/(magnitude(nn)*ecc))*R2D; - if (e.z<0.0) - peri=360.0-peri; - if (peri<0.0) - peri+=360.0; + kk.x = 0.0; + kk.y = 0.0; + kk.z = 1.0; + nn = cross (kk, h); + if (nn.x == 0.0 && nn.y == 0.0) + nn.x = 1.0; + node = atan2 (nn.y, nn.x) * R2D; + if (node < 0.0) + node += 360.0; + + peri = acos (dot (nn, e) / (magnitude (nn) * ecc)) * R2D; + if (e.z < 0.0) + peri = 360.0 - peri; + if (peri < 0.0) + peri += 360.0; // Elliptic motion - if (ecc<1.0) { - xp=(chi-rm)/ecc; - yp=rvm/ecc*sqrt(chi/mu); - b=a*sqrt(1.0-ecc*ecc); - cx=xp/a+ecc; - sx=yp/b; - ee=atan2(sx,cx); - n=XKE*sqrt(mu/(a*a*a)); - mm=(ee-ecc*sx)*R2D; - } - if (mm<0.0) - mm+=360.0; + if (ecc < 1.0) + { + xp = (chi - rm) / ecc; + yp = rvm / ecc * sqrt (chi / mu); + b = a * sqrt (1.0 - ecc * ecc); + cx = xp / a + ecc; + sx = yp / b; + ee = atan2 (sx, cx); + n = XKE * sqrt (mu / (a * a * a)); + mm = (ee - ecc * sx) * R2D; + } + if (mm < 0.0) + mm += 360.0; // Fill - orb.satno=0; - orb.eqinc=incl*D2R; - orb.ascn=node*D2R; - orb.argp=peri*D2R; - orb.mnan=mm*D2R; - orb.ecc=ecc; - orb.rev=XKE*pow(a,-3.0/2.0)*XMNPDA/(2.0*M_PI); - orb.bstar=0.0; - orb.ep_year=ep_year; - orb.ep_day=ep_day; - orb.norb=0; + orb.satno = 0; + orb.eqinc = incl * D2R; + orb.ascn = node * D2R; + orb.argp = peri * D2R; + orb.mnan = mm * D2R; + orb.ecc = ecc; + orb.rev = XKE * pow (a, -3.0 / 2.0) * XMNPDA / (2.0 * M_PI); + orb.bstar = 0.0; + orb.ep_year = ep_year; + orb.ep_day = ep_day; + orb.norb = 0; return orb; } -orbit_t rv2el(int satno,double mjd,xyz_t r0,xyz_t v0) +orbit_t +rv2el (int satno, double mjd, xyz_t r0, xyz_t v0) { - int i,imode; - orbit_t orb[5],orb1[5]; - xyz_t r,v; + int i, imode; + orbit_t orb[5], orb1[5]; + xyz_t r, v; kep_t kep; - char line1[70],line2[70]; + char line1[70], line2[70]; int ep_year; double ep_day; // Epoch - ep_day=mjd2doy(mjd,&ep_year); + ep_day = mjd2doy (mjd, &ep_year); // Initial guess - orb[0]=classel(ep_year,ep_day,r0,v0); - orb[0].satno=satno; - - for (i=0;i<5;i++) { - // Propagate - imode=init_sgdp4(&orb[i]); - imode=satpos_xyz(mjd+2400000.5,&r,&v); + orb[0] = classel (ep_year, ep_day, r0, v0); + orb[0].satno = satno; - // Compute initial orbital elements - orb1[i]=classel(ep_year,ep_day,r,v); + for (i = 0; i < 5; i++) + { + // Propagate + imode = init_sgdp4 (&orb[i]); + imode = satpos_xyz (mjd + 2400000.5, &r, &v); - // Adjust - orb[i+1].rev=orb[i].rev+orb[0].rev-orb1[i].rev; - orb[i+1].ascn=orb[i].ascn+orb[0].ascn-orb1[i].ascn; - orb[i+1].argp=orb[i].argp+orb[0].argp-orb1[i].argp; - orb[i+1].mnan=orb[i].mnan+orb[0].mnan-orb1[i].mnan; - orb[i+1].eqinc=orb[i].eqinc+orb[0].eqinc-orb1[i].eqinc; - orb[i+1].ecc=orb[i].ecc+orb[0].ecc-orb1[i].ecc; - orb[i+1].ep_year=orb[i].ep_year; - orb[i+1].ep_day=orb[i].ep_day; - orb[i+1].satno=orb[i].satno; - orb[i+1].norb=orb[i].norb; - orb[i+1].bstar=orb[i].bstar; + // Compute initial orbital elements + orb1[i] = classel (ep_year, ep_day, r, v); - // Keep in range - if (orb[i+1].ecc<0.0) - orb[i+1].ecc=0.0; - if (orb[i+1].eqinc<0.0) - orb[i+1].eqinc=0.0; - } + // Adjust + orb[i + 1].rev = orb[i].rev + orb[0].rev - orb1[i].rev; + orb[i + 1].ascn = orb[i].ascn + orb[0].ascn - orb1[i].ascn; + orb[i + 1].argp = orb[i].argp + orb[0].argp - orb1[i].argp; + orb[i + 1].mnan = orb[i].mnan + orb[0].mnan - orb1[i].mnan; + orb[i + 1].eqinc = orb[i].eqinc + orb[0].eqinc - orb1[i].eqinc; + orb[i + 1].ecc = orb[i].ecc + orb[0].ecc - orb1[i].ecc; + orb[i + 1].ep_year = orb[i].ep_year; + orb[i + 1].ep_day = orb[i].ep_day; + orb[i + 1].satno = orb[i].satno; + orb[i + 1].norb = orb[i].norb; + orb[i + 1].bstar = orb[i].bstar; - orb[i].mnan=modulo(orb[i].mnan,2.0*M_PI); - orb[i].ascn=modulo(orb[i].ascn,2.0*M_PI); - orb[i].argp=modulo(orb[i].argp,2.0*M_PI); + // Keep in range + if (orb[i + 1].ecc < 0.0) + orb[i + 1].ecc = 0.0; + if (orb[i + 1].eqinc < 0.0) + orb[i + 1].eqinc = 0.0; + } + + orb[i].mnan = modulo (orb[i].mnan, 2.0 * M_PI); + orb[i].ascn = modulo (orb[i].ascn, 2.0 * M_PI); + orb[i].argp = modulo (orb[i].argp, 2.0 * M_PI); return orb[i]; } // Format TLE -void format_tle(orbit_t orb,char *line1,char *line2) +void +format_tle (orbit_t orb, char *line1, char *line2) { - int i,csum; - char sbstar[]=" 00000-0",bstar[13]; + int i, csum; + char sbstar[] = " 00000-0", bstar[13]; // Format Bstar term - if (fabs(orb.bstar)>1e-9) { - sprintf(bstar,"%11.4e",10*orb.bstar); - sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4]; - sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0'; - } + if (fabs (orb.bstar) > 1e-9) + { + sprintf (bstar, "%11.4e", 10 * orb.bstar); + sbstar[0] = bstar[0]; + sbstar[1] = bstar[1]; + sbstar[2] = bstar[3]; + sbstar[3] = bstar[4]; + sbstar[4] = bstar[5]; + sbstar[5] = bstar[6]; + sbstar[6] = bstar[8]; + sbstar[7] = bstar[10]; + sbstar[8] = '\0'; + } // Print lines - sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar); - sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev); + sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0", + orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar); + sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0", + orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc, + DEG (orb.argp), DEG (orb.mnan), orb.rev); // Compute checksums - for (i=0,csum=0;itm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec); - + time (&rawtime); + ptm = gmtime (&rawtime); + + sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900, + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, + ptm->tm_sec); + return; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min,sec; - double mjd,dday; + int year, month, day, hour, min, sec; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; - mjd=date2mjd(year,month,dday); + mjd = date2mjd (year, month, dday); return mjd; } -void usage(void) +void +usage (void) { - printf("Usage: rv2tle -p XYZFILE [- i NORADID] [-d COSPARID] [-g] [-h]\n\n"); - printf("Arguments:\n"); - printf("-p XYZFILE File with cartesian position and velocity vector\n"); - printf(" Format: '{mjd} {x} {y} {z} {vx} {vy} {vz}'\n"); - printf(" Units: position in km, velocity in km/s\n"); - printf("-i NORADID Satellite Catalog Number (NORAD ID), default: 99000\n"); - printf("-d COSPARID International Designator (COSPAR ID), default: 14999A\n"); - printf("-g Use non-standard / GMAT's Modified Julian Date\n"); - printf("-h This help\n"); + printf + ("Usage: rv2tle -p XYZFILE [- i NORADID] [-d COSPARID] [-g] [-h]\n\n"); + printf ("Arguments:\n"); + printf ("-p XYZFILE File with cartesian position and velocity vector\n"); + printf (" Format: '{mjd} {x} {y} {z} {vx} {vy} {vz}'\n"); + printf (" Units: position in km, velocity in km/s\n"); + printf + ("-i NORADID Satellite Catalog Number (NORAD ID), default: 99000\n"); + printf + ("-d COSPARID International Designator (COSPAR ID), default: 14999A\n"); + printf ("-g Use non-standard / GMAT's Modified Julian Date\n"); + printf ("-h This help\n"); return; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; + int c, i = 0; - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; @@ -349,70 +393,74 @@ int fgetline(FILE *file,char *s,int lim) return i; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int imode,satno=99000,arg,gmat=0; + int imode, satno = 99000, arg, gmat = 0; FILE *file; orbit_t orb; - xyz_t r,v; - char xyzfile[LIM],nfd[32],line[LIM]; - char line1[80],line2[80],desig[20]="14999A"; + xyz_t r, v; + char xyzfile[LIM], nfd[32], line[LIM]; + char line1[80], line2[80], desig[20] = "14999A"; double mjd; char *env; // Decode options - while ((arg=getopt(argc,argv,"p:i:d:gh"))!=-1) { - switch (arg) { + while ((arg = getopt (argc, argv, "p:i:d:gh")) != -1) + { + switch (arg) + { - case 'p': - strcpy(xyzfile,optarg); - break; + case 'p': + strcpy (xyzfile, optarg); + break; - case 'i': - satno=atoi(optarg); - break; + case 'i': + satno = atoi (optarg); + break; - case 'd': - strcpy(desig,optarg); - break; + case 'd': + strcpy (desig, optarg); + break; - case 'g': - gmat=1; - break; + case 'g': + gmat = 1; + break; - case 'h': - usage(); - return 0; - break; + case 'h': + usage (); + return 0; + break; - default: - usage(); - return 0; + default: + usage (); + return 0; + } } - } // Open file - file=fopen(xyzfile,"r"); - while (fgetline(file,line,LIM)>0) { - sscanf(line,"%lf %lf %lf %lf %lf %lf %lf",&mjd,&r.x,&r.y,&r.z,&v.x,&v.y,&v.z); + file = fopen (xyzfile, "r"); + while (fgetline (file, line, LIM) > 0) + { + sscanf (line, "%lf %lf %lf %lf %lf %lf %lf", &mjd, &r.x, &r.y, &r.z, + &v.x, &v.y, &v.z); - // Convert to MJD - if (gmat==1) - mjd+=29999.5; + // Convert to MJD + if (gmat == 1) + mjd += 29999.5; - // Convert - orb=rv2el(orb.satno,mjd,r,v); - orb.satno=satno; - strcpy(orb.desig,desig); + // Convert + orb = rv2el (orb.satno, mjd, r, v); + orb.satno = satno; + strcpy (orb.desig, desig); - format_tle(orb,line1,line2); - printf("%s\n%s\n",line1,line2); - satno++; - } - fclose(file); + format_tle (orb, line1, line2); + printf ("%s\n%s\n", line1, line2); + satno++; + } + fclose (file); return 0; } - diff --git a/src/s2dec.c b/src/s2dec.c index 6866392..3d8fae2 100644 --- a/src/s2dec.c +++ b/src/s2dec.c @@ -5,38 +5,44 @@ #include // Usage: s2dec [options] hh:mm:ss.ss -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { double x; - int sign=1; - float deg,min,sec; - char t[20],c; + int sign = 1; + float deg, min, sec; + char t[20], c; - if (argc==1) { - printf("Usage: s2dec -r \n -or- \nCompute sexagesimal from decimal input x.\n"); - printf("Options: -r Converts hours into degrees\n"); - - return -1; - } + if (argc == 1) + { + printf + ("Usage: s2dec -r \n -or- \nCompute sexagesimal from decimal input x.\n"); + printf ("Options: -r Converts hours into degrees\n"); + + return -1; + } // Get Sexagesimal string - strcpy(t,argv[--argc]); - if (t[0]=='-') sign=-1; + strcpy (t, argv[--argc]); + if (t[0] == '-') + sign = -1; - deg=fabs(atof(strtok(t," :,"))); - min=fabs(atof(strtok(NULL," :,"))); - sec=fabs(atof(strtok(NULL," :,"))); - - x=(double) deg+(double) min/60.+(double) sec/3600.; + deg = fabs (atof (strtok (t, " :,"))); + min = fabs (atof (strtok (NULL, " :,"))); + sec = fabs (atof (strtok (NULL, " :,"))); + + x = (double) deg + (double) min / 60. + (double) sec / 3600.; // Get Options - while (--argc > 0 && (*++argv)[0] == '-') { - while (c = *++argv[0]) { - if (c == 'r') - x *= 15.; + while (--argc > 0 && (*++argv)[0] == '-') + { + while (c = *++argv[0]) + { + if (c == 'r') + x *= 15.; + } } - } - printf("%lf\n",sign*x); + printf ("%lf\n", sign * x); return 0; } diff --git a/src/satfit.c b/src/satfit.c index d0aeb42..4f19115 100644 --- a/src/satfit.c +++ b/src/satfit.c @@ -12,333 +12,387 @@ #define NMAX 256 #define D2R M_PI/180.0 #define R2D 180.0/M_PI -#define XKMPER 6378.135 // Earth radius in km -#define XKMPAU 149597879.691 // AU in km +#define XKMPER 6378.135 // Earth radius in km +#define XKMPAU 149597879.691 // AU in km #define FLAT (1.0/298.257) -#define XKE 0.07436680 // Guassian Gravitational Constant +#define XKE 0.07436680 // Guassian Gravitational Constant #define AE 1.0 #define XMNPDA 1440.0 -long Isat=0; -long Isatsel=0; +long Isat = 0; +long Isatsel = 0; extern double SGDP4_jd0; -struct point { - int flag,satno; +struct point +{ + int flag, satno; char desig[10]; - double mjd,ra,de,rac,dec; - float st,sr; + double mjd, ra, de, rac, dec; + float st, sr; char iod_line[LIM]; - double dx,dy,dr,dt; + double dx, dy, dr, dt; xyz_t obspos; }; -struct doppler { - double mjd,freq,v; - xyz_t obspos,obsvel; +struct doppler +{ + double mjd, freq, v; + xyz_t obspos, obsvel; }; -struct data { - int n,nsel,m; +struct data +{ + int n, nsel, m; struct point *p; struct doppler *q; - double chisq,rms; + double chisq, rms; } d; -struct site { +struct site +{ int id; - double lng,lat; + double lng, lat; float alt; char observer[64]; }; orbit_t orb; -struct site get_site(int site_id); -struct point decode_iod_observation(char *iod_line); -struct doppler decode_doppler_observation(char *line); -int fgetline(FILE *file,char *s,int lim); -double modulo(double x,double y); -double gmst(double mjd); -double dgmst(double mjd); -double date2mjd(int year,int month,double day); -double mjd2doy(double mjd,int *yr); -void mjd2date(double mjd,int *year,int *month,double *day); -void obspos_xyz(double mjd,double lng,double lat,float alt,xyz_t *pos,xyz_t *vel); -void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de); -void forward(double ra0,double de0,double ra,double de,double *x,double *y); -struct data read_data(char *iodfname,char *dopfname); -void versafit(int m,int n,double *a,double *da,double (*func)(double *),double dchisq,double tol,char *opt); -double chisq(double a[]); -orbit_t read_tle(char *filename,int satno); -void format_tle(orbit_t orb,char *line1,char *line2); -void highlight(float x0,float y0,float x,float y,int flag); -void time_range(double *mjdmin,double *mjdmax,int flag); -void print_tle(orbit_t orb,char *filename); -void fit(orbit_t orb,int *ia); -void usage(); -double nfd2mjd(char *date); -double dot(xyz_t a,xyz_t b); -double magnitude(xyz_t a); -xyz_t cross(xyz_t a,xyz_t b); -orbit_t classel(int ep_year,double ep_day,xyz_t r,xyz_t v); -orbit_t rv2el(int satno,double mjd,xyz_t r0,xyz_t v0); +struct site get_site (int site_id); +struct point decode_iod_observation (char *iod_line); +struct doppler decode_doppler_observation (char *line); +int fgetline (FILE * file, char *s, int lim); +double modulo (double x, double y); +double gmst (double mjd); +double dgmst (double mjd); +double date2mjd (int year, int month, double day); +double mjd2doy (double mjd, int *yr); +void mjd2date (double mjd, int *year, int *month, double *day); +void obspos_xyz (double mjd, double lng, double lat, float alt, xyz_t * pos, + xyz_t * vel); +void precess (double mjd0, double ra0, double de0, double mjd, double *ra, + double *de); +void forward (double ra0, double de0, double ra, double de, double *x, + double *y); +struct data read_data (char *iodfname, char *dopfname); +void versafit (int m, int n, double *a, double *da, double (*func) (double *), + double dchisq, double tol, char *opt); +double chisq (double a[]); +orbit_t read_tle (char *filename, int satno); +void format_tle (orbit_t orb, char *line1, char *line2); +void highlight (float x0, float y0, float x, float y, int flag); +void time_range (double *mjdmin, double *mjdmax, int flag); +void print_tle (orbit_t orb, char *filename); +void fit (orbit_t orb, int *ia); +void usage (); +double nfd2mjd (char *date); +double dot (xyz_t a, xyz_t b); +double magnitude (xyz_t a); +xyz_t cross (xyz_t a, xyz_t b); +orbit_t classel (int ep_year, double ep_day, xyz_t r, xyz_t v); +orbit_t rv2el (int satno, double mjd, xyz_t r0, xyz_t v0); // Propagate elements -void propagate(double mjd) +void +propagate (double mjd) { int imode; - xyz_t r,v; - char desig[20],line1[80],line2[80]; + xyz_t r, v; + char desig[20], line1[80], line2[80]; // Store designation - strcpy(desig,orb.desig); + strcpy (desig, orb.desig); // Propagate - imode=init_sgdp4(&orb); - imode=satpos_xyz(mjd+2400000.5,&r,&v); - + imode = init_sgdp4 (&orb); + imode = satpos_xyz (mjd + 2400000.5, &r, &v); + // Convert - orb=rv2el(orb.satno,mjd,r,v); + orb = rv2el (orb.satno, mjd, r, v); // Copy designation - strcpy(orb.desig,desig); + strcpy (orb.desig, desig); return; } -xyz_t get_position(double r0,int i0) +xyz_t +get_position (double r0, int i0) { int i; - double rr,drr,r; + double rr, drr, r; xyz_t pos; - double x,y,z; + double x, y, z; // Initial range - rr=100.0; - do { - x=d.p[i0].obspos.x+rr*cos(d.p[i0].ra*D2R)*cos(d.p[i0].de*D2R); - y=d.p[i0].obspos.y+rr*sin(d.p[i0].ra*D2R)*cos(d.p[i0].de*D2R); - z=d.p[i0].obspos.z+rr*sin(d.p[i0].de*D2R); - r=sqrt(x*x+y*y+z*z); - drr=r-r0; - rr-=drr; - } while (fabs(drr)>0.01); - - pos.x=x; - pos.y=y; - pos.z=z; + rr = 100.0; + do + { + x = + d.p[i0].obspos.x + + rr * cos (d.p[i0].ra * D2R) * cos (d.p[i0].de * D2R); + y = + d.p[i0].obspos.y + + rr * sin (d.p[i0].ra * D2R) * cos (d.p[i0].de * D2R); + z = d.p[i0].obspos.z + rr * sin (d.p[i0].de * D2R); + r = sqrt (x * x + y * y + z * z); + drr = r - r0; + rr -= drr; + } + while (fabs (drr) > 0.01); + + pos.x = x; + pos.y = y; + pos.z = z; return pos; } -void period_search(void) +void +period_search (void) { - int i,j,i1,i2; + int i, j, i1, i2; float dt; - int nrev,nrevmin,nrevmax; - char line1[70],line2[70]; + int nrev, nrevmin, nrevmax; + char line1[70], line2[70]; int ia[7]; // Set fitting parameters - for (i=0;i<6;i++) - ia[i]=1; - ia[6]=0; + for (i = 0; i < 6; i++) + ia[i] = 1; + ia[6] = 0; // Select all points - for (i=0;i1e-5 && i<1000); - printf("%f\n",r0); + // Compute angle + ang = + acos ((pos0.x * pos1.x + pos0.y * pos1.y + + pos0.z * pos1.z) / (r0 * r0)) * R2D; + + // Angular motion (deg/sec); + w = ang / dt; + + r0 += 1000.0 * (w0 - w); + i++; + } + while (fabs (w0 - w) > 1e-5 && i < 1000); + printf ("%f\n", r0); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int i,j,nobs=0; - int redraw=1,plot_residuals=0,adjust=0,quit=0,identify=0; - int ia[]={0,0,0,0,0,0,0}; - float dx[]={0.1,0.1,0.35,0.35,0.6,0.6,0.85},dy[]={0.0,-0.25,0.0,-0.25,0.0,-0.25,0.0}; + int i, j, nobs = 0; + int redraw = 1, plot_residuals = 0, adjust = 0, quit = 0, identify = 0; + int ia[] = { 0, 0, 0, 0, 0, 0, 0 }; + float dx[] = { 0.1, 0.1, 0.35, 0.35, 0.6, 0.6, 0.85 }, dy[] = + { 0.0, -0.25, 0.0, -0.25, 0.0, -0.25, 0.0 }; char c; - int mode=0,posn=0,click=0; - float x0,y0,x,y; - float xmin=0.0,xmax=360.0,ymin=-90.0,ymax=90.0; - char string[64],bstar[10]=" 50000-4",line0[72],line1[72],line2[72],text[10]; - char filename[64],nfd[32]; - int satno=-1; - double mjdmin,mjdmax,mjd=0.0; - int length=864000; - int arg=0,elset=0,circular=0,tleout=0,noplot=0; - char *ioddatafile=NULL,*dopdatafile=NULL,*catalog,tlefile[LIM]; + int mode = 0, posn = 0, click = 0; + float x0, y0, x, y; + float xmin = 0.0, xmax = 360.0, ymin = -90.0, ymax = 90.0; + char string[64], bstar[10] = + " 50000-4", line0[72], line1[72], line2[72], text[10]; + char filename[64], nfd[32]; + int satno = -1; + double mjdmin, mjdmax, mjd = 0.0; + int length = 864000; + int arg = 0, elset = 0, circular = 0, tleout = 0, noplot = 0; + char *ioddatafile = NULL, *dopdatafile = NULL, *catalog, tlefile[LIM]; orbit_t orb0; FILE *file; // Decode options - while ((arg=getopt(argc,argv,"d:r:c:i:haCo:pIt:l:m:"))!=-1) { - switch(arg) { + while ((arg = getopt (argc, argv, "d:r:c:i:haCo:pIt:l:m:")) != -1) + { + switch (arg) + { - case 'd': - ioddatafile=optarg; - break; + case 'd': + ioddatafile = optarg; + break; - case 'r': - dopdatafile=optarg; - break; + case 'r': + dopdatafile = optarg; + break; - case 'c': - catalog=optarg; - break; + case 'c': + catalog = optarg; + break; - case 'i': - satno=atoi(optarg); - break; + case 'i': + satno = atoi (optarg); + break; - case 't': - strcpy(nfd,optarg); - mjd=nfd2mjd(nfd); - break; + case 't': + strcpy (nfd, optarg); + mjd = nfd2mjd (nfd); + break; - case 'm': - mjd=(double) atof(optarg); - break; + case 'm': + mjd = (double) atof (optarg); + break; - case 'l': - length=atoi(optarg); - if (strchr(optarg,'h')!=NULL) - length*=3600; - else if (strchr(optarg,'m')!=NULL) - length*=60; - else if (strchr(optarg,'d')!=NULL) - length*=86400; - break; + case 'l': + length = atoi (optarg); + if (strchr (optarg, 'h') != NULL) + length *= 3600; + else if (strchr (optarg, 'm') != NULL) + length *= 60; + else if (strchr (optarg, 'd') != NULL) + length *= 86400; + break; - case 'C': - circular=1; - break; + case 'C': + circular = 1; + break; - case 'p': - noplot=1; - break; + case 'p': + noplot = 1; + break; - case 'o': - tleout=1; - strcpy(tlefile,optarg); - break; + case 'o': + tleout = 1; + strcpy (tlefile, optarg); + break; - case 'h': - usage(); - return 0; - break; + case 'h': + usage (); + return 0; + break; - case 'a': - adjust=1; - break; + case 'a': + adjust = 1; + break; - case 'I': - identify=1; - break; + case 'I': + identify = 1; + break; - default: - usage(); - return 0; + default: + usage (); + return 0; + } } - } // Read data - d=read_data(ioddatafile,dopdatafile); + d = read_data (ioddatafile, dopdatafile); // Select observations based on time - if (mjd>0.0) { - mjdmin=mjd-length/86400.0; - mjdmax=mjd; - for (i=0;imjdmin && d.p[i].mjd<=mjdmax && d.p[i].flag==1) - d.p[i].flag=2; - else - d.p[i].flag=0; + if (mjd > 0.0) + { + mjdmin = mjd - length / 86400.0; + mjdmax = mjd; + for (i = 0; i < d.n; i++) + { + if (d.p[i].mjd > mjdmin && d.p[i].mjd <= mjdmax && d.p[i].flag == 1) + d.p[i].flag = 2; + else + d.p[i].flag = 0; + } } - } - time_range(&mjdmin,&mjdmax,1); + time_range (&mjdmin, &mjdmax, 1); // Read TLE - if (satno>=0) - orb=read_tle(catalog,satno); + if (satno >= 0) + orb = read_tle (catalog, satno); // Open catalog - if (identify==1) { - file=fopen(catalog,"r"); - if (file==NULL) - fatal_error("Failed to open %s\n",catalog); - } + if (identify == 1) + { + file = fopen (catalog, "r"); + if (file == NULL) + fatal_error ("Failed to open %s\n", catalog); + } // Reloop stderr - freopen("/tmp/stderr.txt","w",stderr); + freopen ("/tmp/stderr.txt", "w", stderr); // Fit circular orbit - if (circular==1) { - for (i=0;i mjdmax) + mjdmax = d.p[i].mjd; + j++; + } + } + + // Propagate orbit to time of last observation + propagate (mjdmax); + orb0 = orb; + + // Fit + adjust_fit (16); + + // Print results + // printf("%05d %8.3f %8.3f %8.3f %s %8.3f %d\n",satno,DEG(orb.mnan-orb0.mnan),DEG(orb.ascn-orb0.ascn),d.rms,ioddatafile,mjdmin-(SGDP4_jd0-2400000.5),d.nsel); + + // Dump tle + if (tleout == 1) + print_tle (orb, tlefile); + + // Set thingies + plot_residuals = 1; + redraw = 1; + quit = 1; } - // Not enough observations - if (nobs<10) - return 0; - - // Get last point - for (i=0,j=0;imjdmax) mjdmax=d.p[i].mjd; - j++; - } - } - - // Propagate orbit to time of last observation - propagate(mjdmax); - orb0=orb; - - // Fit - adjust_fit(16); - - // Print results - // printf("%05d %8.3f %8.3f %8.3f %s %8.3f %d\n",satno,DEG(orb.mnan-orb0.mnan),DEG(orb.ascn-orb0.ascn),d.rms,ioddatafile,mjdmin-(SGDP4_jd0-2400000.5),d.nsel); - - // Dump tle - if (tleout==1) - print_tle(orb,tlefile); - - // Set thingies - plot_residuals=1; - redraw=1; - quit=1; - } - // Exit before plotting - if (quit==1 && noplot==1) { - if (d.n) free(d.p); - if (d.m) free(d.q); - fclose(stderr); - return 0; - } + if (quit == 1 && noplot == 1) + { + if (d.n) + free (d.p); + if (d.m) + free (d.q); + fclose (stderr); + return 0; + } - cpgopen("/xs"); - cpgask(0); + cpgopen ("/xs"); + cpgask (0); // For ever loop - for (;;) { - if (redraw==1) { - cpgpage(); - cpgsvp(0.1,0.95,0.0,0.18); - cpgswin(0.0,1.0,-0.5,0.5); + for (;;) + { + if (redraw == 1) + { + cpgpage (); + cpgsvp (0.1, 0.95, 0.0, 0.18); + cpgswin (0.0, 1.0, -0.5, 0.5); - // Buttons - cpgtext(0.12,-0.05,"Inclination"); - cpgtext(0.372,-0.05,"Eccentricity"); - cpgtext(0.62,-0.05,"Mean Anomaly"); - cpgtext(0.87,-0.05,"B\\u*\\d"); - cpgtext(0.12,-0.3,"Ascending Node"); - cpgtext(0.37,-0.3,"Arg. of Perigee"); - cpgtext(0.62,-0.3,"Mean Motion"); + // Buttons + cpgtext (0.12, -0.05, "Inclination"); + cpgtext (0.372, -0.05, "Eccentricity"); + cpgtext (0.62, -0.05, "Mean Anomaly"); + cpgtext (0.87, -0.05, "B\\u*\\d"); + cpgtext (0.12, -0.3, "Ascending Node"); + cpgtext (0.37, -0.3, "Arg. of Perigee"); + cpgtext (0.62, -0.3, "Mean Motion"); + + // Toggles + for (i = 0; i < 7; i++) + { + cpgpt1 (dx[i], dy[i], 19); + if (ia[i] == 1) + { + cpgsci (2); + cpgpt1 (dx[i], dy[i], 16); + cpgsci (1); + } + } + + // Plot map + cpgsvp (0.1, 0.9, 0.2, 0.9); + cpgswin (xmax, xmin, ymin, ymax); + cpgbox ("BCTSN", 0., 0, "BCTSN", 0., 0); + cpglab ("Right Ascension", "Declination", " "); + + if (satno > 0) + { + // Plot tle + format_tle (orb, line1, line2); + cpgmtxt ("T", 2.0, 0.0, 0.0, line1); + cpgmtxt ("T", 1.0, 0.0, 0.0, line2); + } + + // Plot points + for (i = 0; i < d.n; i++) + { + if (d.p[i].flag >= 1) + { + cpgpt1 (d.p[i].ra, d.p[i].de, 17); + sprintf (text, " %d", i + 1); + cpgtext (d.p[i].ra, d.p[i].de, text); + if (plot_residuals == 1) + { + cpgmove (d.p[i].ra, d.p[i].de); + cpgdraw (d.p[i].rac, d.p[i].dec); + } + if (d.p[i].flag == 2) + { + cpgsci (2); + cpgpt1 (d.p[i].ra, d.p[i].de, 4); + cpgsci (1); + } + } + } + } + + // Quit + if (quit == 1) + break; + + // Get cursor + cpgband (mode, posn, x0, y0, &x, &y, &c); + + // Help + if (c == 'h' || c == '?') + { + printf + ("q Quit\nw Write TLE file\nP Search mean motion space\nf Fit orbit\ns Select observations in current window\nu Unselect observations\n1-7 Toggle parameter\nC Fit circular orbit\nS Search mean motion/eccentricity space\nc Change a parameter\nz Zoom\nr Unzoom\nt Toggle starting orbits (LEO, GTO, GEO, HEO)\n"); + } + + // Quit + if (c == 'q' || c == 'Q') + break; + + // Period search + if (c == 'P') + { + period_search (); + } + + // Fit + if (c == 'f') + { + // Count points + for (i = 0, nobs = 0; i < d.n; i++) + if (d.p[i].flag == 2) + nobs++; + if (satno < 0) + { + printf ("No elements loaded!\n"); + } + else if (nobs == 0) + { + printf ("No points selected!\n"); + } + else + { + fit (orb, ia); + printf ("%d %.5f\n", nobs, d.rms); + plot_residuals = 1; + redraw = 1; + continue; + } + } + + // Write TLE + if (c == 'w') + { + printf ("TLE filename to write: "); + scanf ("%s", filename); + print_tle (orb, filename); + printf + ("\n================================================================================\n"); + continue; + } + + // Highlight + if (c == 's') + { + highlight (xmin, ymin, xmax, ymax, 2); + time_range (&mjdmin, &mjdmax, 2); + for (i = 0, nobs = 0; i < d.n; i++) + if (d.p[i].flag == 2) + nobs++; + click = 0; + mode = 0; + redraw = 1; + continue; + } + + // Unselect + if (c == 'U') + { + for (i = 0; i < d.n; i++) + d.p[i].flag = 1; + time_range (&mjdmin, &mjdmax, 1); + redraw = 1; + continue; + } + + // Unselect + if (c == 'u') + { + for (i = 0; i < d.n; i++) + if (d.p[i].flag == 2) + d.p[i].flag = 1; + redraw = 1; + continue; + } // Toggles - for (i=0;i<7;i++) { - cpgpt1(dx[i],dy[i],19); - if (ia[i]==1) { - cpgsci(2); - cpgpt1(dx[i],dy[i],16); - cpgsci(1); + if (isdigit (c) && c - '0' >= 1 && c - '0' < 8) + { + if (ia[c - 49] == 0) + ia[c - 49] = 1; + else if (ia[c - 49] == 1) + ia[c - 49] = 0; + redraw = 1; + continue; } - } - // Plot map - cpgsvp(0.1,0.9,0.2,0.9); - cpgswin(xmax,xmin,ymin,ymax); - cpgbox("BCTSN",0.,0,"BCTSN",0.,0); - cpglab("Right Ascension","Declination"," "); - - if (satno>0) { - // Plot tle - format_tle(orb,line1,line2); - cpgmtxt("T",2.0,0.0,0.0,line1); - cpgmtxt("T",1.0,0.0,0.0,line2); - } - - // Plot points - for (i=0;i=1) { - cpgpt1(d.p[i].ra,d.p[i].de,17); - sprintf(text," %d",i+1); - cpgtext(d.p[i].ra,d.p[i].de,text); - if (plot_residuals==1) { - cpgmove(d.p[i].ra,d.p[i].de); - cpgdraw(d.p[i].rac,d.p[i].dec); - } - if (d.p[i].flag==2) { - cpgsci(2); - cpgpt1(d.p[i].ra,d.p[i].de,4); - cpgsci(1); - } + // Circular fit + if (c == 'C') + { + satno = circular_fit (); + plot_residuals = 1; + printf ("%.3f\n", d.rms); + ia[0] = ia[1] = ia[4] = ia[5] = 1; + redraw = 1; } - } - } - // Quit - if (quit==1) - break; - - // Get cursor - cpgband(mode,posn,x0,y0,&x,&y,&c); - - // Help - if (c=='h' || c=='?') { - printf("q Quit\nw Write TLE file\nP Search mean motion space\nf Fit orbit\ns Select observations in current window\nu Unselect observations\n1-7 Toggle parameter\nC Fit circular orbit\nS Search mean motion/eccentricity space\nc Change a parameter\nz Zoom\nr Unzoom\nt Toggle starting orbits (LEO, GTO, GEO, HEO)\n"); - } - - // Quit - if (c=='q' || c=='Q') - break; - - // Period search - if (c=='P') { - period_search(); - } - - // Fit - if (c=='f') { - // Count points - for (i=0,nobs=0;i=1 && c-'0'<8) { - if (ia[c-49]==0) - ia[c-49]=1; - else if (ia[c-49]==1) - ia[c-49]=0; - redraw=1; - continue; - } - - // Circular fit - if (c=='C') { - satno=circular_fit(); - plot_residuals=1; - printf("%.3f\n",d.rms); - ia[0]=ia[1]=ia[4]=ia[5]=1; - redraw=1; - } - - // Search - if (c=='S') { - satno=psearch(); - plot_residuals=1; - ia[0]=ia[1]=ia[4]=ia[5]=1; - redraw=1; - } - - // Search - if (c=='R') { - satno=revsearch(); - plot_residuals=1; - // ia[0]=ia[1]=ia[4]=ia[5]=ia[2]=1; - redraw=1; - } - - // EW search - if (c=='e') { - satno=ewsearch(); - plot_residuals=1; - redraw=1; - } - - // Change - if (c=='c') { - printf("(1) Inclination, (2) Ascending Node, (3) Eccentricity,\n(4) Arg. of Perigee, (5) Mean Anomaly, (6) Mean Motion,\n(7) B* drag, (8) Epoch, (9) Satellite ID\n(0) Sat ID\nWhich parameter to change: "); - scanf("%i",&i); - if (i>=0 && i<=9) { - printf("\nNew value: "); - fgets(string,64,stdin); - scanf("%s",string); - if (i==0) strcpy(orb.desig,string); - if (i==1) orb.eqinc=RAD(atof(string)); - if (i==2) orb.ascn=RAD(atof(string)); - if (i==3) orb.ecc=atof(string); - if (i==4) orb.argp=RAD(atof(string)); - if (i==5) orb.mnan=RAD(atof(string)); - if (i==6) orb.rev=atof(string); - if (i==7) orb.bstar=atof(string); - if (i==8) { - orb.ep_year=2000+(int) floor(atof(string)/1000.0); - orb.ep_day=atof(string)-1000*floor(atof(string)/1000.0); + // Search + if (c == 'S') + { + satno = psearch (); + plot_residuals = 1; + ia[0] = ia[1] = ia[4] = ia[5] = 1; + redraw = 1; } - if (i==9) orb.satno=atoi(string); - redraw=1; - continue; - } - printf("\n================================================================================\n"); + + // Search + if (c == 'R') + { + satno = revsearch (); + plot_residuals = 1; + // ia[0]=ia[1]=ia[4]=ia[5]=ia[2]=1; + redraw = 1; + } + + // EW search + if (c == 'e') + { + satno = ewsearch (); + plot_residuals = 1; + redraw = 1; + } + + // Change + if (c == 'c') + { + printf + ("(1) Inclination, (2) Ascending Node, (3) Eccentricity,\n(4) Arg. of Perigee, (5) Mean Anomaly, (6) Mean Motion,\n(7) B* drag, (8) Epoch, (9) Satellite ID\n(0) Sat ID\nWhich parameter to change: "); + scanf ("%i", &i); + if (i >= 0 && i <= 9) + { + printf ("\nNew value: "); + fgets (string, 64, stdin); + scanf ("%s", string); + if (i == 0) + strcpy (orb.desig, string); + if (i == 1) + orb.eqinc = RAD (atof (string)); + if (i == 2) + orb.ascn = RAD (atof (string)); + if (i == 3) + orb.ecc = atof (string); + if (i == 4) + orb.argp = RAD (atof (string)); + if (i == 5) + orb.mnan = RAD (atof (string)); + if (i == 6) + orb.rev = atof (string); + if (i == 7) + orb.bstar = atof (string); + if (i == 8) + { + orb.ep_year = 2000 + (int) floor (atof (string) / 1000.0); + orb.ep_day = + atof (string) - 1000 * floor (atof (string) / 1000.0); + } + if (i == 9) + orb.satno = atoi (string); + redraw = 1; + continue; + } + printf + ("\n================================================================================\n"); + } + + // Zoom + if (c == 'z') + { + click = 1; + mode = 2; + } + + // Execute zoom, or box delete + if (c == 'A') + { + if (click == 0) + { + click = 1; + } + else if (click == 1 && mode == 2) + { + xmin = (x0 < x) ? x0 : x; + xmax = (x0 > x) ? x0 : x; + ymin = (y0 < y) ? y0 : y; + ymax = (y0 > y) ? y0 : y; + + click = 0; + mode = 0; + redraw = 1; + continue; + } + else + { + click = 0; + mode = 0; + redraw = 1; + continue; + } + } + + // Unzoom + if (c == 'r') + { + xmin = 0.0; + xmax = 360.0; + ymin = -90.0; + ymax = 90.0; + mode = 0; + click = 0; + redraw = 1; + continue; + } + + // Default tle + if (c == 't') + { + orb.satno = d.p[0].satno; + strcpy (orb.desig, d.p[0].desig); + orb.ep_day = mjd2doy (0.5 * (mjdmin + mjdmax), &orb.ep_year); + satno = orb.satno; + if (elset == 0) + { + orb.eqinc = 0.5 * M_PI; + orb.ascn = 0.0; + orb.ecc = 0.0001; + orb.argp = 0.0; + orb.mnan = 0.0; + orb.rev = 14.0; + orb.bstar = 0.5e-4; + printf ("LEO orbit\n"); + } + else if (elset == 1) + { + orb.eqinc = 20.0 * D2R; + orb.ascn = 0.0; + orb.ecc = 0.7; + orb.argp = 0.0; + orb.mnan = 0.0; + orb.rev = 2.25; + orb.bstar = 0.0; + printf ("GTO orbit\n"); + } + else if (elset == 2) + { + orb.eqinc = 10.0 * D2R; + orb.ascn = 0.0; + orb.ecc = 0.0001; + orb.argp = 0.0; + orb.mnan = 0.0; + orb.rev = 1.0027; + orb.bstar = 0.0; + printf ("GSO orbit\n"); + } + else if (elset == 3) + { + orb.eqinc = 63.434 * D2R; + orb.ascn = 0.0; + orb.ecc = 0.71; + orb.argp = 270 * D2R; + orb.mnan = 0.0; + orb.rev = 2.006; + orb.bstar = 0.0; + printf ("HEO orbit\n"); + } + elset++; + if (elset > 3) + elset = 0; + print_orb (&orb); + printf + ("\n================================================================================\n"); + click = 0; + redraw = 1; + continue; + } + + // Save + x0 = x; + y0 = y; } - // Zoom - if (c=='z') { - click=1; - mode=2; - } + cpgend (); - // Execute zoom, or box delete - if (c=='A') { - if (click==0) { - click=1; - } else if (click==1 && mode==2) { - xmin=(x0x) ? x0 : x; - ymin=(y0y) ? y0 : y; + if (d.n) + free (d.p); + if (d.m) + free (d.q); - click=0; - mode=0; - redraw=1; - continue; - } else { - click=0; - mode=0; - redraw=1; - continue; - } - } - - // Unzoom - if (c=='r') { - xmin=0.0; - xmax=360.0; - ymin=-90.0; - ymax=90.0; - mode=0; - click=0; - redraw=1; - continue; - } - - // Default tle - if (c=='t') { - orb.satno=d.p[0].satno; - strcpy(orb.desig,d.p[0].desig); - orb.ep_day=mjd2doy(0.5*(mjdmin+mjdmax),&orb.ep_year); - satno=orb.satno; - if (elset==0) { - orb.eqinc=0.5*M_PI; - orb.ascn=0.0; - orb.ecc=0.0001; - orb.argp=0.0; - orb.mnan=0.0; - orb.rev=14.0; - orb.bstar=0.5e-4; - printf("LEO orbit\n"); - } else if (elset==1) { - orb.eqinc=20.0*D2R; - orb.ascn=0.0; - orb.ecc=0.7; - orb.argp=0.0; - orb.mnan=0.0; - orb.rev=2.25; - orb.bstar=0.0; - printf("GTO orbit\n"); - } else if (elset==2) { - orb.eqinc=10.0*D2R; - orb.ascn=0.0; - orb.ecc=0.0001; - orb.argp=0.0; - orb.mnan=0.0; - orb.rev=1.0027; - orb.bstar=0.0; - printf("GSO orbit\n"); - } else if (elset==3) { - orb.eqinc=63.434*D2R; - orb.ascn=0.0; - orb.ecc=0.71; - orb.argp=270*D2R; - orb.mnan=0.0; - orb.rev=2.006; - orb.bstar=0.0; - printf("HEO orbit\n"); - } - elset++; - if (elset>3) - elset=0; - print_orb(&orb); - printf("\n================================================================================\n"); - click=0; - redraw=1; - continue; - } - - // Save - x0=x; - y0=y; - } - - cpgend(); - - if (d.n) free(d.p); - if (d.m) free(d.q); - - fclose(stderr); + fclose (stderr); return 0; } // Get observing site -struct site get_site(int site_id) +struct site +get_site (int site_id) { - int i=0; + int i = 0; char line[LIM]; FILE *file; int id; - double lat,lng; + double lat, lng; float alt; - char abbrev[3],observer[64]; + char abbrev[3], observer[64]; struct site s; - char *env,filename[LIM]; + char *env, filename[LIM]; - env=getenv("ST_DATADIR"); - sprintf(filename,"%s/data/sites.txt",env); + env = getenv ("ST_DATADIR"); + sprintf (filename, "%s/data/sites.txt", env); - file=fopen(filename,"r"); - if (file==NULL) { - printf("File with site information not found!\n"); - return s; - } - while (fgets(line,LIM,file)!=NULL) { - // Skip - if (strstr(line,"#")!=NULL) - continue; - - // Strip newline - line[strlen(line)-1]='\0'; - - // Read data - sscanf(line,"%4d %2s %lf %lf %f", - &id,abbrev,&lat,&lng,&alt); - strcpy(observer,line+38); - - // Change to km - alt/=1000.0; - - // Copy site - if (id==site_id) { - s.lat=lat; - s.lng=lng; - s.alt=alt; - s.id=id; - strcpy(s.observer,observer); + file = fopen (filename, "r"); + if (file == NULL) + { + printf ("File with site information not found!\n"); + return s; } + while (fgets (line, LIM, file) != NULL) + { + // Skip + if (strstr (line, "#") != NULL) + continue; - } - fclose(file); + // Strip newline + line[strlen (line) - 1] = '\0'; + + // Read data + sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt); + strcpy (observer, line + 38); + + // Change to km + alt /= 1000.0; + + // Copy site + if (id == site_id) + { + s.lat = lat; + s.lng = lng; + s.alt = alt; + s.id = id; + strcpy (s.observer, observer); + } + + } + fclose (file); + + if (id != site_id) + s.id == -1; - if (id!=site_id) - s.id==-1; - return s; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } // Greenwich Mean Sidereal Time -double dgmst(double mjd) +double +dgmst (double mjd) { - double t,dgmst; + double t, dgmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - dgmst=360.98564736629+t*(0.000387933-t/38710000); + dgmst = 360.98564736629 + t * (0.000387933 - t / 38710000); return dgmst; } // Observer position -void obspos_xyz(double mjd,double lng,double lat,float alt,xyz_t *pos,xyz_t *vel) +void +obspos_xyz (double mjd, double lng, double lat, float alt, xyz_t * pos, + xyz_t * vel) { - double ff,gc,gs,theta,s,dtheta; + double ff, gc, gs, theta, s, dtheta; - s=sin(lat*D2R); - ff=sqrt(1.0-FLAT*(2.0-FLAT)*s*s); - gc=1.0/ff+alt/XKMPER; - gs=(1.0-FLAT)*(1.0-FLAT)/ff+alt/XKMPER; + s = sin (lat * D2R); + ff = sqrt (1.0 - FLAT * (2.0 - FLAT) * s * s); + gc = 1.0 / ff + alt / XKMPER; + gs = (1.0 - FLAT) * (1.0 - FLAT) / ff + alt / XKMPER; - theta=gmst(mjd)+lng; - dtheta=dgmst(mjd)*D2R/86400; + theta = gmst (mjd) + lng; + dtheta = dgmst (mjd) * D2R / 86400; - pos->x=gc*cos(lat*D2R)*cos(theta*D2R)*XKMPER; - pos->y=gc*cos(lat*D2R)*sin(theta*D2R)*XKMPER; - pos->z=gs*sin(lat*D2R)*XKMPER; - vel->x=-gc*cos(lat*D2R)*sin(theta*D2R)*XKMPER*dtheta; - vel->y=gc*cos(lat*D2R)*cos(theta*D2R)*XKMPER*dtheta; - vel->z=0.0; + pos->x = gc * cos (lat * D2R) * cos (theta * D2R) * XKMPER; + pos->y = gc * cos (lat * D2R) * sin (theta * D2R) * XKMPER; + pos->z = gs * sin (lat * D2R) * XKMPER; + vel->x = -gc * cos (lat * D2R) * sin (theta * D2R) * XKMPER * dtheta; + vel->y = gc * cos (lat * D2R) * cos (theta * D2R) * XKMPER * dtheta; + vel->z = 0.0; return; } // Precess a celestial position -void precess(double mjd0,double ra0,double de0,double mjd,double *ra,double *de) +void +precess (double mjd0, double ra0, double de0, double mjd, double *ra, + double *de) { - double t0,t; - double zeta,z,theta; - double a,b,c; + double t0, t; + double zeta, z, theta; + double a, b, c; // Angles in radians - ra0*=D2R; - de0*=D2R; + ra0 *= D2R; + de0 *= D2R; // Time in centuries - t0=(mjd0-51544.5)/36525.0; - t=(mjd-mjd0)/36525.0; + t0 = (mjd0 - 51544.5) / 36525.0; + t = (mjd - mjd0) / 36525.0; // Precession angles - zeta=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - zeta+=(0.30188-0.000344*t0)*t*t+0.017998*t*t*t; - zeta*=D2R/3600.0; - z=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - z+=(1.09468+0.000066*t0)*t*t+0.018203*t*t*t; - z*=D2R/3600.0; - theta=(2004.3109-0.85330*t0-0.000217*t0*t0)*t; - theta+=-(0.42665+0.000217*t0)*t*t-0.041833*t*t*t; - theta*=D2R/3600.0; - - a=cos(de0)*sin(ra0+zeta); - b=cos(theta)*cos(de0)*cos(ra0+zeta)-sin(theta)*sin(de0); - c=sin(theta)*cos(de0)*cos(ra0+zeta)+cos(theta)*sin(de0); + zeta = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + zeta += (0.30188 - 0.000344 * t0) * t * t + 0.017998 * t * t * t; + zeta *= D2R / 3600.0; + z = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + z += (1.09468 + 0.000066 * t0) * t * t + 0.018203 * t * t * t; + z *= D2R / 3600.0; + theta = (2004.3109 - 0.85330 * t0 - 0.000217 * t0 * t0) * t; + theta += -(0.42665 + 0.000217 * t0) * t * t - 0.041833 * t * t * t; + theta *= D2R / 3600.0; - *ra=(atan2(a,b)+z)*R2D; - *de=asin(c)*R2D; + a = cos (de0) * sin (ra0 + zeta); + b = cos (theta) * cos (de0) * cos (ra0 + zeta) - sin (theta) * sin (de0); + c = sin (theta) * cos (de0) * cos (ra0 + zeta) + cos (theta) * sin (de0); - if (*ra<360.0) - *ra+=360.0; - if (*ra>360.0) - *ra-=360.0; + *ra = (atan2 (a, b) + z) * R2D; + *de = asin (c) * R2D; + + if (*ra < 360.0) + *ra += 360.0; + if (*ra > 360.0) + *ra -= 360.0; return; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // Decode IOD Observations -struct point decode_iod_observation(char *iod_line) +struct point +decode_iod_observation (char *iod_line) { - int year,month,iday,hour,min; - int format,epoch,me,xe,sign; + int year, month, iday, hour, min; + int format, epoch, me, xe, sign; int site_id; - double sec,ra,mm,ss,de,dd,ds,day,mjd0; - char secbuf[6],sn[2],degbuf[3],buf1[3],buf2[6]; + double sec, ra, mm, ss, de, dd, ds, day, mjd0; + char secbuf[6], sn[2], degbuf[3], buf1[3], buf2[6]; struct point p; struct site s; xyz_t vel; // Strip newline - iod_line[strlen(iod_line)-1]='\0'; + iod_line[strlen (iod_line) - 1] = '\0'; // Copy full line - strcpy(p.iod_line,iod_line); + strcpy (p.iod_line, iod_line); // Set flag - p.flag=1; + p.flag = 1; // Get SSN - sscanf(iod_line,"%5d",&p.satno); + sscanf (iod_line, "%5d", &p.satno); // Get desig - sscanf(iod_line+6,"%s %s",buf1,buf2); - sprintf(p.desig,"%s%s",buf1,buf2); + sscanf (iod_line + 6, "%s %s", buf1, buf2); + sprintf (p.desig, "%s%s", buf1, buf2); // Get site - sscanf(iod_line+16,"%4d",&site_id); - s=get_site(site_id); + sscanf (iod_line + 16, "%4d", &site_id); + s = get_site (site_id); // Skip if site not found - if (s.id<0) { - fprintf(stderr,"Site %d not found!\n",site_id); - p.flag=0; - } - + if (s.id < 0) + { + fprintf (stderr, "Site %d not found!\n", site_id); + p.flag = 0; + } + // Decode date/time - sscanf(iod_line+23,"%4d%2d%2d%2d%2d%5s",&year,&month,&iday,&hour,&min,secbuf); - sec=atof(secbuf); - sec/=pow(10,strlen(secbuf)-2); - day=(double) iday+(double) hour/24.0+(double) min/1440.0+(double) sec/86400.0; - p.mjd=date2mjd(year,month,day); + sscanf (iod_line + 23, "%4d%2d%2d%2d%2d%5s", &year, &month, &iday, &hour, + &min, secbuf); + sec = atof (secbuf); + sec /= pow (10, strlen (secbuf) - 2); + day = + (double) iday + (double) hour / 24.0 + (double) min / 1440.0 + + (double) sec / 86400.0; + p.mjd = date2mjd (year, month, day); // Get uncertainty in time - sscanf(iod_line+41,"%1d%1d",&me,&xe); - p.st=(float) me*pow(10,xe-8); + sscanf (iod_line + 41, "%1d%1d", &me, &xe); + p.st = (float) me *pow (10, xe - 8); // Get observer position - obspos_xyz(p.mjd,s.lng,s.lat,s.alt,&p.obspos,&vel); + obspos_xyz (p.mjd, s.lng, s.lat, s.alt, &p.obspos, &vel); // Skip empty observations - if (strlen(iod_line)<64 || (iod_line[54]!='+' && iod_line[54]!='-')) - p.flag=0; + if (strlen (iod_line) < 64 || (iod_line[54] != '+' && iod_line[54] != '-')) + p.flag = 0; // Get format, epoch - sscanf(iod_line+44,"%1d%1d",&format,&epoch); + sscanf (iod_line + 44, "%1d%1d", &format, &epoch); // Read position - sscanf(iod_line+47,"%2lf%2lf%3lf%1s",&ra,&mm,&ss,sn); - sscanf(iod_line+55,"%2lf%2lf%2s",&de,&dd,degbuf); - ds=atof(degbuf); - if (strlen(degbuf)==1) - ds*=10; - sign=(sn[0]=='-') ? -1 : 1; - sscanf(iod_line+62,"%1d%1d",&me,&xe); - p.sr=(float) me*pow(10,xe-8); - + sscanf (iod_line + 47, "%2lf%2lf%3lf%1s", &ra, &mm, &ss, sn); + sscanf (iod_line + 55, "%2lf%2lf%2s", &de, &dd, degbuf); + ds = atof (degbuf); + if (strlen (degbuf) == 1) + ds *= 10; + sign = (sn[0] == '-') ? -1 : 1; + sscanf (iod_line + 62, "%1d%1d", &me, &xe); + p.sr = (float) me *pow (10, xe - 8); + // Decode position - switch(format) + switch (format) { // Format 1: RA/DEC = HHMMSSs+DDMMSS MX (MX in seconds of arc) - case 1 : - ra+=mm/60+ss/36000; - de=sign*(de+dd/60+ds/3600); - p.sr/=3600.0; + case 1: + ra += mm / 60 + ss / 36000; + de = sign * (de + dd / 60 + ds / 3600); + p.sr /= 3600.0; break; // Format 2: RA/DEC = HHMMmmm+DDMMmm MX (MX in minutes of arc) case 2: - ra+=mm/60+ss/60000; - de=sign*(de+dd/60+ds/6000); - p.sr/=60.0; + ra += mm / 60 + ss / 60000; + de = sign * (de + dd / 60 + ds / 6000); + p.sr /= 60.0; break; // Format 3: RA/DEC = HHMMmmm+DDdddd MX (MX in degrees of arc) - case 3 : - ra+=mm/60+ss/60000; - de=sign*(de+dd/100+ds/10000); + case 3: + ra += mm / 60 + ss / 60000; + de = sign * (de + dd / 100 + ds / 10000); break; // Format 7: RA/DEC = HHMMSSs+DDdddd MX (MX in degrees of arc) - case 7 : - ra+=mm/60+ss/36000; - de=sign*(de+dd/100+ds/10000); + case 7: + ra += mm / 60 + ss / 36000; + de = sign * (de + dd / 100 + ds / 10000); break; - default : - printf("IOD Format not implemented\n"); - p.flag=0; + default: + printf ("IOD Format not implemented\n"); + p.flag = 0; break; - } + } // Convert to degrees - ra*=15.0; + ra *= 15.0; // Get precession epoch - if (epoch==0) { - p.ra=ra; - p.de=de; - return p; - } else if (epoch==4) { - mjd0=33281.9235; - } else if (epoch==5) { - mjd0=51544.5; - } else { - printf("Observing epoch not implemented\n"); - p.flag=0; - } + if (epoch == 0) + { + p.ra = ra; + p.de = de; + return p; + } + else if (epoch == 4) + { + mjd0 = 33281.9235; + } + else if (epoch == 5) + { + mjd0 = 51544.5; + } + else + { + printf ("Observing epoch not implemented\n"); + p.flag = 0; + } // Precess position - precess(mjd0,ra,de,p.mjd,&p.ra,&p.de); + precess (mjd0, ra, de, p.mjd, &p.ra, &p.de); return p; } // Decode doppler Observations -struct doppler decode_doppler_observation(char *line) +struct doppler +decode_doppler_observation (char *line) { struct doppler q; struct site s; @@ -1326,27 +1530,28 @@ struct doppler decode_doppler_observation(char *line) int site_id; // Read line - sscanf(line,"%lf %lf %f %d",&q.mjd,&q.freq,&flux,&site_id); + sscanf (line, "%lf %lf %f %d", &q.mjd, &q.freq, &flux, &site_id); // Get site - s=get_site(site_id); + s = get_site (site_id); // Get observer position - obspos_xyz(q.mjd,s.lng,s.lat,s.alt,&q.obspos,&q.obsvel); + obspos_xyz (q.mjd, s.lng, s.lat, s.alt, &q.obspos, &q.obsvel); return q; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; + int c, i = 0; - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\t') - c=' '; + c = ' '; if (c == '\n') s[i++] = c; s[i] = '\0'; @@ -1354,86 +1559,92 @@ int fgetline(FILE *file,char *s,int lim) } // Read IOD data -struct data read_data(char *iodfname,char *dopfname) +struct data +read_data (char *iodfname, char *dopfname) { - int i=0; + int i = 0; char line[LIM]; FILE *file; struct data d; - d.n=0; - d.m=0; + d.n = 0; + d.m = 0; // Read IOD data - if (iodfname!=NULL) { - // Open file - file=fopen(iodfname,"r"); - if (file==NULL) { - fprintf(stderr,"Failed to open %s\n",iodfname); - exit(1); - } - - // Count lines - while (fgetline(file,line,LIM)>0) - i++; - d.n=i; + if (iodfname != NULL) + { + // Open file + file = fopen (iodfname, "r"); + if (file == NULL) + { + fprintf (stderr, "Failed to open %s\n", iodfname); + exit (1); + } - // Allocate - d.p=(struct point *) malloc(sizeof(struct point)*d.n); - - // Rewind file - rewind(file); - - // Read data - i=0; - while (fgetline(file,line,LIM)>0) - d.p[i++]=decode_iod_observation(line); - - // Close file - fclose(file); - } + // Count lines + while (fgetline (file, line, LIM) > 0) + i++; + d.n = i; + + // Allocate + d.p = (struct point *) malloc (sizeof (struct point) * d.n); + + // Rewind file + rewind (file); + + // Read data + i = 0; + while (fgetline (file, line, LIM) > 0) + d.p[i++] = decode_iod_observation (line); + + // Close file + fclose (file); + } // Read doppler data - if (dopfname!=NULL) { - // Open file - file=fopen(iodfname,"r"); - if (file==NULL) { - fprintf(stderr,"Failed to open %s\n",dopfname); - exit(1); + if (dopfname != NULL) + { + // Open file + file = fopen (iodfname, "r"); + if (file == NULL) + { + fprintf (stderr, "Failed to open %s\n", dopfname); + exit (1); + } + + // Count lines + i = 0; + while (fgetline (file, line, LIM) > 0) + i++; + d.m = i; + + // Allocate + d.q = (struct doppler *) malloc (sizeof (struct doppler) * d.m); + + // Rewind file + rewind (file); + + // Read data + i = 0; + while (fgetline (file, line, LIM) > 0) + d.q[i++] = decode_doppler_observation (line); + + // Close file + fclose (file); } - - // Count lines - i=0; - while (fgetline(file,line,LIM)>0) - i++; - d.m=i; - - // Allocate - d.q=(struct doppler *) malloc(sizeof(struct doppler)*d.m); - - // Rewind file - rewind(file); - - // Read data - i=0; - while (fgetline(file,line,LIM)>0) - d.q[i++]=decode_doppler_observation(line); - - // Close file - fclose(file); - } return d; } // Chi-squared -double chisq(double a[]) +double +chisq (double a[]) { - int i,imode,nsel; - double chisq,rms; - xyz_t satpos,satvel; - double dx,dy,dz; + int i, imode, nsel; + double chisq, rms; + xyz_t satpos, satvel; + double dx, dy, dz; double r; // Construct struct @@ -1444,288 +1655,330 @@ double chisq(double a[]) // a[4]: mean anomaly // a[5]: revs per day - if (a[2]<0.0) - a[2]=0.0; - if (a[0]<0.0) { - a[0]*=-1; - a[1]+=180.0; - } else if (a[0]>180.0) { - a[0]=180.0; - } - if (a[5]>20.0) - a[5]=20.0; - if (a[5]<0.05) - a[5]=0.05; - + if (a[2] < 0.0) + a[2] = 0.0; + if (a[0] < 0.0) + { + a[0] *= -1; + a[1] += 180.0; + } + else if (a[0] > 180.0) + { + a[0] = 180.0; + } + if (a[5] > 20.0) + a[5] = 20.0; + if (a[5] < 0.05) + a[5] = 0.05; + // Set parameters - orb.eqinc=RAD(a[0]); - orb.ascn=RAD(modulo(a[1],360.0)); - orb.ecc=a[2]; - orb.argp=RAD(modulo(a[3],360.0)); - orb.mnan=RAD(modulo(a[4],360.0)); - orb.rev=a[5]; - orb.bstar=a[6]; + orb.eqinc = RAD (a[0]); + orb.ascn = RAD (modulo (a[1], 360.0)); + orb.ecc = a[2]; + orb.argp = RAD (modulo (a[3], 360.0)); + orb.mnan = RAD (modulo (a[4], 360.0)); + orb.rev = a[5]; + orb.bstar = a[6]; // Initialize - imode=init_sgdp4(&orb); - if (imode==SGDP4_ERROR) - printf("Error\n"); + imode = init_sgdp4 (&orb); + if (imode == SGDP4_ERROR) + printf ("Error\n"); // Loop over points - for (i=0,nsel=0,chisq=0.0,rms=0.0;i0) - rms=sqrt(rms/(float) nsel); - - d.chisq=chisq; - d.rms=rms; - d.nsel=nsel; + if (nsel > 0) + rms = sqrt (rms / (float) nsel); + + d.chisq = chisq; + d.rms = rms; + d.nsel = nsel; return chisq; } // Read tle -orbit_t read_tle(char *filename,int satno) +orbit_t +read_tle (char *filename, int satno) { int i; FILE *file; orbit_t orb; - file=fopen(filename,"r"); - if (file==NULL) - fatal_error("Failed to open %s\n",filename); + file = fopen (filename, "r"); + if (file == NULL) + fatal_error ("Failed to open %s\n", filename); // Read TLE - read_twoline(file,satno,&orb); - fclose(file); + read_twoline (file, satno, &orb); + fclose (file); return orb; } // MJD to DOY -double mjd2doy(double mjd,int *yr) +double +mjd2doy (double mjd, int *yr) { - int year,month,k=2; - double day,doy; - - mjd2date(mjd,&year,&month,&day); + int year, month, k = 2; + double day, doy; - if (year%4==0 && year%400!=0) - k=1; + mjd2date (mjd, &year, &month, &day); - doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - *yr=year; + doy = + floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30; + + *yr = year; return doy; } // Compute Date from Julian Day -void mjd2date(double mjd,int *year,int *month,double *day) +void +mjd2date (double mjd, int *year, int *month, double *day) { - double f,jd; - int z,alpha,a,b,c,d,e; + double f, jd; + int z, alpha, a, b, c, d, e; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - *day=b-d-floor(30.6001*e)+f; - if (e<14) - *month=e-1; + if (z < 2299161) + a = z; else - *month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (*month>2) - *year=c-4716; + *day = b - d - floor (30.6001 * e) + f; + if (e < 14) + *month = e - 1; else - *year=c-4715; + *month = e - 13; + + if (*month > 2) + *year = c - 4716; + else + *year = c - 4715; return; } // Format TLE -void format_tle(orbit_t orb,char *line1,char *line2) +void +format_tle (orbit_t orb, char *line1, char *line2) { - int i,csum; - char sbstar[]=" 00000-0",bstar[13]; + int i, csum; + char sbstar[] = " 00000-0", bstar[13]; // Format Bstar term - if (fabs(orb.bstar)>1e-9) { - sprintf(bstar,"%11.4e",10*orb.bstar); - sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4]; - sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0'; - } + if (fabs (orb.bstar) > 1e-9) + { + sprintf (bstar, "%11.4e", 10 * orb.bstar); + sbstar[0] = bstar[0]; + sbstar[1] = bstar[1]; + sbstar[2] = bstar[3]; + sbstar[3] = bstar[4]; + sbstar[4] = bstar[5]; + sbstar[5] = bstar[6]; + sbstar[6] = bstar[8]; + sbstar[7] = bstar[10]; + sbstar[8] = '\0'; + } // Print lines - sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar); - sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev); + sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0", + orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar); + sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0", + orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc, + DEG (orb.argp), DEG (orb.mnan), orb.rev); // Compute checksums - for (i=0,csum=0;ix) ? x0 : x; - ymin=(y0y) ? y0 : y; - for (i=0;ixmin && d.p[i].raymin && d.p[i].de x) ? x0 : x; + ymin = (y0 < y) ? y0 : y; + ymax = (y0 > y) ? y0 : y; + for (i = 0; i < d.n; i++) + if (d.p[i].ra > xmin && d.p[i].ra < xmax && d.p[i].de > ymin + && d.p[i].de < ymax && d.p[i].flag != 0) + d.p[i].flag = flag; return; } // Select time range -void time_range(double *mjdmin,double *mjdmax,int flag) +void +time_range (double *mjdmin, double *mjdmax, int flag) { - int i,n; + int i, n; float c; - for (i=0,n=0;i *mjdmax) *mjdmax=d.p[i].mjd; - n++; + for (i = 0, n = 0; i < d.n; i++) + { + if (d.p[i].flag == flag) + { + if (n == 0) + { + *mjdmin = d.p[i].mjd; + *mjdmax = d.p[i].mjd; + } + if (d.p[i].mjd < *mjdmin) + *mjdmin = d.p[i].mjd; + if (d.p[i].mjd > *mjdmax) + *mjdmax = d.p[i].mjd; + n++; + } } - } - c=0.1*(*mjdmax- *mjdmin); - *mjdmin-=c; - *mjdmax+=c; + c = 0.1 * (*mjdmax - *mjdmin); + *mjdmin -= c; + *mjdmax += c; return; } // Print TLE -void print_tle(orbit_t orb,char *filename) +void +print_tle (orbit_t orb, char *filename) { - int i,n; + int i, n; FILE *file; - double mjdmin,mjdmax; - int year,month; + double mjdmin, mjdmax; + int year, month; double day; - char line1[70],line2[70]; + char line1[70], line2[70]; // Count number of points - for (i=0,n=0;imjdmax) mjdmax=d.p[i].mjd; - n++; + for (i = 0, n = 0; i < d.n; i++) + { + if (d.p[i].flag == 2) + { + if (n == 0) + { + mjdmin = d.p[i].mjd; + mjdmax = d.p[i].mjd; + } + if (d.p[i].mjd < mjdmin) + mjdmin = d.p[i].mjd; + if (d.p[i].mjd > mjdmax) + mjdmax = d.p[i].mjd; + n++; + } } - } // Write TLE - file=fopen(filename,"a"); - format_tle(orb,line1,line2); - fprintf(file,"OBJ\n%s\n%s\n",line1,line2); + file = fopen (filename, "a"); + format_tle (orb, line1, line2); + fprintf (file, "OBJ\n%s\n%s\n", line1, line2); - mjd2date(mjdmin,&year,&month,&day); - fprintf(file,"# %4d%02d%05.2lf-",year,month,day); - mjd2date(mjdmax,&year,&month,&day); - fprintf(file,"%4d%02d%05.2lf, %d measurements, %.3lf deg rms\n",year,month,day,n,d.rms); - fclose(file); + mjd2date (mjdmin, &year, &month, &day); + fprintf (file, "# %4d%02d%05.2lf-", year, month, day); + mjd2date (mjdmax, &year, &month, &day); + fprintf (file, "%4d%02d%05.2lf, %d measurements, %.3lf deg rms\n", year, + month, day, n, d.rms); + fclose (file); return; } // Fit -void fit(orbit_t orb,int *ia) +void +fit (orbit_t orb, int *ia) { - int i,n; - double a[7],da[7]; + int i, n; + double a[7], da[7]; // double db[7]={5.0,5.0,0.1,5.0,5.0,0.5,0.0001}; // double db[7]={1.0,1.0,0.02,1.0,1.0,0.1,0.0001}; - double db[7]={0.1,0.1,0.002,0.1,0.1,0.01,0.00001}; + double db[7] = { 0.1, 0.1, 0.002, 0.1, 0.1, 0.01, 0.00001 }; - a[0]=orb.eqinc*R2D; - da[0]=da[0]*R2D; - a[1]=orb.ascn*R2D; - da[1]=da[1]*R2D; - a[2]=orb.ecc; - a[3]=orb.argp*R2D; - da[3]=da[3]*R2D; - a[4]=orb.mnan*R2D; - da[4]=da[4]*R2D; - a[5]=orb.rev; - a[6]=orb.bstar; + a[0] = orb.eqinc * R2D; + da[0] = da[0] * R2D; + a[1] = orb.ascn * R2D; + da[1] = da[1] * R2D; + a[2] = orb.ecc; + a[3] = orb.argp * R2D; + da[3] = da[3] * R2D; + a[4] = orb.mnan * R2D; + da[4] = da[4] * R2D; + a[5] = orb.rev; + a[6] = orb.bstar; - for (i=0;i<7;i++) { - if (ia[i]==1) - da[i]=db[i]; - else - da[i]=0.0; - } + for (i = 0; i < 7; i++) + { + if (ia[i] == 1) + da[i] = db[i]; + else + da[i] = 0.0; + } // Construct struct // a[0]: inclination @@ -1737,231 +1990,242 @@ void fit(orbit_t orb,int *ia) // a[6]: bstar // Count highlighted points - for (i=0,n=0;i0) - versafit(n,7,a,da,chisq,0.0,1e-6,"n"); + if (n > 0) + versafit (n, 7, a, da, chisq, 0.0, 1e-6, "n"); // Return parameters - orb.eqinc=RAD(a[0]); - orb.ascn=RAD(modulo(a[1],360.0)); - orb.ecc=a[2]; - orb.argp=RAD(modulo(a[3],360.0)); - orb.mnan=RAD(modulo(a[4],360.0)); - orb.rev=a[5]; - orb.bstar=a[6]; + orb.eqinc = RAD (a[0]); + orb.ascn = RAD (modulo (a[1], 360.0)); + orb.ecc = a[2]; + orb.argp = RAD (modulo (a[3], 360.0)); + orb.mnan = RAD (modulo (a[4], 360.0)); + orb.rev = a[5]; + orb.bstar = a[6]; return; } -void usage() +void +usage () { - printf("satfit d:c:i:haCo:p\n\n"); - printf("d IOD observations\n"); - printf("c TLE catalog\n"); - printf("i Satellite ID (NORAD)\n"); - printf("C Fit circular orbit\n"); - printf("p No plotting\n"); - printf("o Output TLE file\n"); - printf("a Adjust MA and RAAN\n"); - printf("h This help\n"); + printf ("satfit d:c:i:haCo:p\n\n"); + printf ("d IOD observations\n"); + printf ("c TLE catalog\n"); + printf ("i Satellite ID (NORAD)\n"); + printf ("C Fit circular orbit\n"); + printf ("p No plotting\n"); + printf ("o Output TLE file\n"); + printf ("a Adjust MA and RAAN\n"); + printf ("h This help\n"); return; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min,sec; - double mjd,dday; + int year, month, day, hour, min, sec; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; - mjd=date2mjd(year,month,dday); + mjd = date2mjd (year, month, dday); return mjd; } // Dot product -double dot(xyz_t a,xyz_t b) +double +dot (xyz_t a, xyz_t b) { - return a.x*b.x+a.y*b.y+a.z*b.z; + return a.x * b.x + a.y * b.y + a.z * b.z; } // Magnitude -double magnitude(xyz_t a) +double +magnitude (xyz_t a) { - return sqrt(dot(a,a)); + return sqrt (dot (a, a)); } // Cross product -xyz_t cross(xyz_t a,xyz_t b) +xyz_t +cross (xyz_t a, xyz_t b) { xyz_t c; - c.x=a.y*b.z-a.z*b.y; - c.y=a.z*b.x-a.x*b.z; - c.z=a.x*b.y-a.y*b.x; + c.x = a.y * b.z - a.z * b.y; + c.y = a.z * b.x - a.x * b.z; + c.z = a.x * b.y - a.y * b.x; return c; } // Clasical elements -orbit_t classel(int ep_year,double ep_day,xyz_t r,xyz_t v) +orbit_t +classel (int ep_year, double ep_day, xyz_t r, xyz_t v) { int i; - double rm,vm,vm2,rvm,mu=1.0;; - double chi,xp,yp,sx,cx,b,ee; - double a,ecc,incl,node,peri,mm,n; - xyz_t h,e,kk,nn; + double rm, vm, vm2, rvm, mu = 1.0;; + double chi, xp, yp, sx, cx, b, ee; + double a, ecc, incl, node, peri, mm, n; + xyz_t h, e, kk, nn; orbit_t orb; - r.x/=XKMPER; - r.y/=XKMPER; - r.z/=XKMPER; - v.x/=(XKE*XKMPER/AE*XMNPDA/86400.0); - v.y/=(XKE*XKMPER/AE*XMNPDA/86400.0); - v.z/=(XKE*XKMPER/AE*XMNPDA/86400.0); + r.x /= XKMPER; + r.y /= XKMPER; + r.z /= XKMPER; + v.x /= (XKE * XKMPER / AE * XMNPDA / 86400.0); + v.y /= (XKE * XKMPER / AE * XMNPDA / 86400.0); + v.z /= (XKE * XKMPER / AE * XMNPDA / 86400.0); - rm=magnitude(r); - vm2=dot(v,v); - rvm=dot(r,v); - h=cross(r,v); - chi=dot(h,h)/mu; + rm = magnitude (r); + vm2 = dot (v, v); + rvm = dot (r, v); + h = cross (r, v); + chi = dot (h, h) / mu; - e.x=(vm2/mu-1.0/rm)*r.x-rvm/mu*v.x; - e.y=(vm2/mu-1.0/rm)*r.y-rvm/mu*v.y; - e.z=(vm2/mu-1.0/rm)*r.z-rvm/mu*v.z; + e.x = (vm2 / mu - 1.0 / rm) * r.x - rvm / mu * v.x; + e.y = (vm2 / mu - 1.0 / rm) * r.y - rvm / mu * v.y; + e.z = (vm2 / mu - 1.0 / rm) * r.z - rvm / mu * v.z; - a=pow(2.0/rm-vm2/mu,-1); - ecc=magnitude(e); - incl=acos(h.z/magnitude(h))*R2D; - - kk.x=0.0; - kk.y=0.0; - kk.z=1.0; - nn=cross(kk,h); - if (nn.x==0.0 && nn.y==0.0) - nn.x=1.0; - node=atan2(nn.y,nn.x)*R2D; - if (node<0.0) - node+=360.0; + a = pow (2.0 / rm - vm2 / mu, -1); + ecc = magnitude (e); + incl = acos (h.z / magnitude (h)) * R2D; - peri=acos(dot(nn,e)/(magnitude(nn)*ecc))*R2D; - if (e.z<0.0) - peri=360.0-peri; - if (peri<0.0) - peri+=360.0; + kk.x = 0.0; + kk.y = 0.0; + kk.z = 1.0; + nn = cross (kk, h); + if (nn.x == 0.0 && nn.y == 0.0) + nn.x = 1.0; + node = atan2 (nn.y, nn.x) * R2D; + if (node < 0.0) + node += 360.0; + + peri = acos (dot (nn, e) / (magnitude (nn) * ecc)) * R2D; + if (e.z < 0.0) + peri = 360.0 - peri; + if (peri < 0.0) + peri += 360.0; // Elliptic motion - if (ecc<1.0) { - xp=(chi-rm)/ecc; - yp=rvm/ecc*sqrt(chi/mu); - b=a*sqrt(1.0-ecc*ecc); - cx=xp/a+ecc; - sx=yp/b; - ee=atan2(sx,cx); - n=XKE*sqrt(mu/(a*a*a)); - mm=(ee-ecc*sx)*R2D; - } - if (mm<0.0) - mm+=360.0; + if (ecc < 1.0) + { + xp = (chi - rm) / ecc; + yp = rvm / ecc * sqrt (chi / mu); + b = a * sqrt (1.0 - ecc * ecc); + cx = xp / a + ecc; + sx = yp / b; + ee = atan2 (sx, cx); + n = XKE * sqrt (mu / (a * a * a)); + mm = (ee - ecc * sx) * R2D; + } + if (mm < 0.0) + mm += 360.0; // Fill - orb.satno=0; - orb.eqinc=incl*D2R; - orb.ascn=node*D2R; - orb.argp=peri*D2R; - orb.mnan=mm*D2R; - orb.ecc=ecc; - orb.rev=XKE*pow(a,-3.0/2.0)*XMNPDA/(2.0*M_PI); - orb.bstar=0.0; - orb.ep_year=ep_year; - orb.ep_day=ep_day; - orb.norb=0; + orb.satno = 0; + orb.eqinc = incl * D2R; + orb.ascn = node * D2R; + orb.argp = peri * D2R; + orb.mnan = mm * D2R; + orb.ecc = ecc; + orb.rev = XKE * pow (a, -3.0 / 2.0) * XMNPDA / (2.0 * M_PI); + orb.bstar = 0.0; + orb.ep_year = ep_year; + orb.ep_day = ep_day; + orb.norb = 0; return orb; } // Position and velocity to elements -orbit_t rv2el(int satno,double mjd,xyz_t r0,xyz_t v0) +orbit_t +rv2el (int satno, double mjd, xyz_t r0, xyz_t v0) { - int i,imode; - orbit_t orb[5],orb1[5]; - xyz_t r,v; + int i, imode; + orbit_t orb[5], orb1[5]; + xyz_t r, v; kep_t kep; - char line1[70],line2[70]; + char line1[70], line2[70]; int ep_year; double ep_day; // Epoch - ep_day=mjd2doy(mjd,&ep_year); + ep_day = mjd2doy (mjd, &ep_year); // Initial guess - orb[0]=classel(ep_year,ep_day,r0,v0); - orb[0].satno=satno; - - for (i=0;i<4;i++) { - // Propagate - imode=init_sgdp4(&orb[i]); - imode=satpos_xyz(mjd+2400000.5,&r,&v); + orb[0] = classel (ep_year, ep_day, r0, v0); + orb[0].satno = satno; - // Compute initial orbital elements - orb1[i]=classel(ep_year,ep_day,r,v); + for (i = 0; i < 4; i++) + { + // Propagate + imode = init_sgdp4 (&orb[i]); + imode = satpos_xyz (mjd + 2400000.5, &r, &v); - // Adjust - orb[i+1].rev=orb[i].rev+orb[0].rev-orb1[i].rev; - orb[i+1].ascn=orb[i].ascn+orb[0].ascn-orb1[i].ascn; - orb[i+1].argp=orb[i].argp+orb[0].argp-orb1[i].argp; - orb[i+1].mnan=orb[i].mnan+orb[0].mnan-orb1[i].mnan; - orb[i+1].eqinc=orb[i].eqinc+orb[0].eqinc-orb1[i].eqinc; - orb[i+1].ecc=orb[i].ecc+orb[0].ecc-orb1[i].ecc; - orb[i+1].ep_year=orb[i].ep_year; - orb[i+1].ep_day=orb[i].ep_day; - orb[i+1].satno=orb[i].satno; - orb[i+1].norb=orb[i].norb; - orb[i+1].bstar=orb[i].bstar; + // Compute initial orbital elements + orb1[i] = classel (ep_year, ep_day, r, v); - // Keep in range - if (orb[i+1].ecc<0.0) - orb[i+1].ecc=0.0; - if (orb[i+1].eqinc<0.0) - orb[i+1].eqinc=0.0; - } + // Adjust + orb[i + 1].rev = orb[i].rev + orb[0].rev - orb1[i].rev; + orb[i + 1].ascn = orb[i].ascn + orb[0].ascn - orb1[i].ascn; + orb[i + 1].argp = orb[i].argp + orb[0].argp - orb1[i].argp; + orb[i + 1].mnan = orb[i].mnan + orb[0].mnan - orb1[i].mnan; + orb[i + 1].eqinc = orb[i].eqinc + orb[0].eqinc - orb1[i].eqinc; + orb[i + 1].ecc = orb[i].ecc + orb[0].ecc - orb1[i].ecc; + orb[i + 1].ep_year = orb[i].ep_year; + orb[i + 1].ep_day = orb[i].ep_day; + orb[i + 1].satno = orb[i].satno; + orb[i + 1].norb = orb[i].norb; + orb[i + 1].bstar = orb[i].bstar; - orb[i].mnan=modulo(orb[i].mnan,2.0*M_PI); - orb[i].ascn=modulo(orb[i].ascn,2.0*M_PI); - orb[i].argp=modulo(orb[i].argp,2.0*M_PI); + // Keep in range + if (orb[i + 1].ecc < 0.0) + orb[i + 1].ecc = 0.0; + if (orb[i + 1].eqinc < 0.0) + orb[i + 1].eqinc = 0.0; + } + + orb[i].mnan = modulo (orb[i].mnan, 2.0 * M_PI); + orb[i].ascn = modulo (orb[i].ascn, 2.0 * M_PI); + orb[i].argp = modulo (orb[i].argp, 2.0 * M_PI); return orb[i]; } // Get a x and y from a RA and Decl -void forward(double ra0,double de0,double ra,double de,double *x,double *y) +void +forward (double ra0, double de0, double ra, double de, double *x, double *y) { - int i,status; - double phi,theta; + int i, status; + double phi, theta; struct celprm cel; // Initialize Reference Angles - celini(&cel); - cel.ref[0]=ra0; - cel.ref[1]=de0; - cel.ref[2]=999.; - cel.ref[3]=999.; - cel.flag=0.; - strcpy(cel.prj.code,"STG"); + celini (&cel); + cel.ref[0] = ra0; + cel.ref[1] = de0; + cel.ref[2] = 999.; + cel.ref[3] = 999.; + cel.flag = 0.; + strcpy (cel.prj.code, "STG"); - if (celset(&cel)) { - printf("Error in Projection (celset)\n"); - return; - } - cels2x(&cel,1,0,1,1,&ra,&de,&phi,&theta,x,y,&status); + if (celset (&cel)) + { + printf ("Error in Projection (celset)\n"); + return; + } + cels2x (&cel, 1, 0, 1, 1, &ra, &de, &phi, &theta, x, y, &status); return; } - diff --git a/src/satid.c b/src/satid.c index 7572eb9..80bdbf3 100644 --- a/src/satid.c +++ b/src/satid.c @@ -11,607 +11,688 @@ #define MMAX 10 #define D2R M_PI/180.0 #define R2D 180.0/M_PI -#define XKMPER 6378.135 // Earth radius in km -#define XKMPAU 149597879.691 // AU in km +#define XKMPER 6378.135 // Earth radius in km +#define XKMPAU 149597879.691 // AU in km #define FLAT (1.0/298.257) #define STDMAG 6.0 -long Isat=0; -long Isatsel=0; +long Isat = 0; +long Isatsel = 0; extern double SGDP4_jd0; -struct map { - double lat,lng; +struct map +{ + double lat, lng; float alt; char observer[32]; int site_id; } m; -struct point { +struct point +{ double mjd; - xyz_t obspos,sunpos; - double zeta,z,theta; + xyz_t obspos, sunpos; + double zeta, z, theta; } p[MMAX]; -struct image { +struct image +{ char filename[64]; - int naxis,naxis1,naxis2,nframes; - float *zavg,*zstd,*zmax,*znum; - double ra0,de0; - float x0,y0; - float a[3],b[3],xrms,yrms; + int naxis, naxis1, naxis2, nframes; + float *zavg, *zstd, *zmax, *znum; + double ra0, de0; + float x0, y0; + float a[3], b[3], xrms, yrms; double mjd; - float *dt,exptime; + float *dt, exptime; char nfd[32]; - int cospar,tracked; + int cospar, tracked; }; -struct image read_fits(char *filename); -void get_site(int site_id); -double modulo(double,double); -void obspos_xyz(double,xyz_t *,xyz_t *); -void sunpos_xyz(double,xyz_t *); -double gmst(double); -double dgmst(double); -void precession_angles(double mjd0,double mjd,double *zeta,double *z,double *theta); -void initialize(struct image img); -void forward(double ra0,double de0,double ra,double de,double *x,double *y); -void reverse(double ra0,double de0,double x,double y,double *ra,double *de); -struct sat apparent_position(double mjd); +struct image read_fits (char *filename); +void get_site (int site_id); +double modulo (double, double); +void obspos_xyz (double, xyz_t *, xyz_t *); +void sunpos_xyz (double, xyz_t *); +double gmst (double); +double dgmst (double); +void precession_angles (double mjd0, double mjd, double *zeta, double *z, + double *theta); +void initialize (struct image img); +void forward (double ra0, double de0, double ra, double de, double *x, + double *y); +void reverse (double ra0, double de0, double x, double y, double *ra, + double *de); +struct sat apparent_position (double mjd); -void plot_satellites(char *tlefile,struct image img,long satno,double mjd0,float dt,int color) +void +plot_satellites (char *tlefile, struct image img, long satno, double mjd0, + float dt, int color) { int i; orbit_t orb; - int imode,flag,textflag,sflag; - FILE *fp=NULL,*file; - xyz_t satpos,satvel; - float x,y,x0,y0; - char norad[7],satname[30],state[16]; + int imode, flag, textflag, sflag; + FILE *fp = NULL, *file; + xyz_t satpos, satvel; + float x, y, x0, y0; + char norad[7], satname[30], state[16]; float isch; char filename[128]; - double dx,dy,dz,r,ra,de,d,rsun,rearth; - double psun,pearth,ptot; - double a,b,c; - double rx,ry; + double dx, dy, dz, r, ra, de, d, rsun, rearth; + double psun, pearth, ptot; + double a, b, c; + double rx, ry; - cpgqch(&isch); + cpgqch (&isch); // Image determinant - d=img.a[1]*img.b[2]-img.a[2]*img.b[1]; + d = img.a[1] * img.b[2] - img.a[2] * img.b[1]; // Open TLE file - fp=fopen(tlefile,"rb"); - if (fp==NULL) + fp = fopen (tlefile, "rb"); + if (fp == NULL) return; - cpgsci(color); + cpgsci (color); // Open file - sprintf(filename,"%s.id",img.filename); - file=fopen(filename,"a"); + sprintf (filename, "%s.id", img.filename); + file = fopen (filename, "a"); // Read TLEs - while (read_twoline(fp,satno,&orb)==0) { - Isat=orb.satno; - imode=init_sgdp4(&orb); + while (read_twoline (fp, satno, &orb) == 0) + { + Isat = orb.satno; + imode = init_sgdp4 (&orb); - sprintf(norad," %05ld",Isat); + sprintf (norad, " %05ld", Isat); - if (imode==SGDP4_ERROR) - continue; - - // Loop over times - for (flag=0,textflag=0,sflag=0,i=0;i300000) - continue; - - // Relative to observer - dx=satpos.x-p[i].obspos.x; - dy=satpos.y-p[i].obspos.y; - dz=satpos.z-p[i].obspos.z; - - // Celestial position - r=sqrt(dx*dx+dy*dy+dz*dz); - ra=modulo(atan2(dy,dx),2.0*M_PI); - de=asin(dz/r); - - - // Correct for precession - a=cos(de)*sin(ra+p[i].zeta); - b=cos(p[i].theta)*cos(de)*cos(ra+p[i].zeta)-sin(p[i].theta)*sin(de); - c=sin(p[i].theta)*cos(de)*cos(ra+p[i].zeta)+cos(p[i].theta)*sin(de); - ra=modulo((atan2(a,b)+p[i].z)*R2D,360.0); - de=asin(c)*R2D; - - // Adjust for stationary camera - if (img.tracked==0) - ra+=gmst(img.mjd+0.5*img.exptime/86400.0)-gmst(p[i].mjd); - - // Check if nearby enough - r=acos(sin(img.de0*D2R)*sin(de*D2R)+cos(img.de0*D2R)*cos(de*D2R)*cos((img.ra0-ra)*D2R))*R2D; - if (r<90.0) - forward(img.ra0,img.de0,ra,de,&rx,&ry); - else + if (imode == SGDP4_ERROR) continue; - // Satellite position relative to the Sun - dx=-satpos.x+p[i].sunpos.x; - dy=-satpos.y+p[i].sunpos.y; - dz=-satpos.z+p[i].sunpos.z; + // Loop over times + for (flag = 0, textflag = 0, sflag = 0, i = 0; i < MMAX; i++) + { + // Satellite position + satpos_xyz (p[i].mjd + 2400000.5, &satpos, &satvel); - // Distances - rsun=sqrt(dx*dx+dy*dy+dz*dz); - rearth=sqrt(satpos.x*satpos.x+satpos.y*satpos.y+satpos.z*satpos.z); + // Check on radius + r = + sqrt (satpos.x * satpos.x + satpos.y * satpos.y + + satpos.z * satpos.z); + if (r > 300000) + continue; - // Angles - psun=asin(696.0e3/rsun)*R2D; - pearth=asin(6378.135/rearth)*R2D; - ptot=acos((-dx*satpos.x-dy*satpos.y-dz*satpos.z)/(rsun*rearth))*R2D; + // Relative to observer + dx = satpos.x - p[i].obspos.x; + dy = satpos.y - p[i].obspos.y; + dz = satpos.z - p[i].obspos.z; - // Visibility state - if (ptot-pearth<-psun) { - cpgsls(4); - strcpy(state,"eclipsed"); - } else if (ptot-pearth>-psun && ptot-pearthpsun) { - cpgsls(1); - strcpy(state,"sunlit"); - sflag=1; - } + // Celestial position + r = sqrt (dx * dx + dy * dy + dz * dz); + ra = modulo (atan2 (dy, dx), 2.0 * M_PI); + de = asin (dz / r); - // Convert image position - dx=rx-img.a[0]; - dy=ry-img.b[0]; - x=(img.b[2]*dx-img.a[2]*dy)/d+img.x0; - y=(img.a[1]*dy-img.b[1]*dx)/d+img.y0; - // Print name if in viewport - if (x>0.0 && x0.0 && y -psun && ptot - pearth < psun) + { + cpgsls (2); + strcpy (state, "umbra"); + sflag = 1; + } + else if (ptot - pearth > psun) + { + cpgsls (1); + strcpy (state, "sunlit"); + sflag = 1; + } + + // Convert image position + dx = rx - img.a[0]; + dy = ry - img.b[0]; + x = (img.b[2] * dx - img.a[2] * dy) / d + img.x0; + y = (img.a[1] * dy - img.b[1] * dx) / d + img.y0; + + // Print name if in viewport + if (x > 0.0 && x < img.naxis1 && y > 0.0 && y < img.naxis2 + && textflag == 0) + { + if (flag != 0) + cpgdraw (x, y); + cpgsch (0.65); + cpgtext (x, y, norad); + cpgsch (isch); + cpgmove (x, y); + textflag = 1; + } + if (i == 0) + { + x0 = x; + y0 = y; + } + + // Plot satellites + if (flag == 0) + { + cpgpt1 (x, y, 17); + cpgmove (x, y); + flag = 1; + } + else + { + cpgdraw (x, y); + } + } + if (textflag == 1) + { + if (sflag == 0) + fprintf (file, + "%.23s %8.3f %8.3f %8.3f %8.3f %8.5f %s %s eclipsed\n", + img.nfd + 1, x0, y0, x, y, img.exptime, norad, tlefile); + else + fprintf (file, + "%.23s %8.3f %8.3f %8.3f %8.3f %8.5f %s %s sunlit\n", + img.nfd + 1, x0, y0, x, y, img.exptime, norad, tlefile); + } } - if (textflag==1) { - if (sflag==0) - fprintf(file,"%.23s %8.3f %8.3f %8.3f %8.3f %8.5f %s %s eclipsed\n",img.nfd+1,x0,y0,x,y,img.exptime,norad,tlefile); - else - fprintf(file,"%.23s %8.3f %8.3f %8.3f %8.3f %8.5f %s %s sunlit\n",img.nfd+1,x0,y0,x,y,img.exptime,norad,tlefile); - } - } - fclose(fp); - fclose(file); - cpgsci(1); + fclose (fp); + fclose (file); + cpgsci (1); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { int i; struct image img; - float zmin,zmax,zavg,zstd; - float tr[]={-0.5,1.0,0.0,-0.5,0.0,1.0}; - float heat_l[] = {0.0, 0.2, 0.4, 0.6, 1.0}; - float heat_r[] = {0.0, 0.5, 1.0, 1.0, 1.0}; - float heat_g[] = {0.0, 0.0, 0.5, 1.0, 1.0}; - float heat_b[] = {0.0, 0.0, 0.0, 0.3, 1.0}; + float zmin, zmax, zavg, zstd; + float tr[] = { -0.5, 1.0, 0.0, -0.5, 0.0, 1.0 }; + float heat_l[] = { 0.0, 0.2, 0.4, 0.6, 1.0 }; + float heat_r[] = { 0.0, 0.5, 1.0, 1.0, 1.0 }; + float heat_g[] = { 0.0, 0.0, 0.5, 1.0, 1.0 }; + float heat_b[] = { 0.0, 0.0, 0.0, 0.3, 1.0 }; char text[128]; - char *env,filename[128]; - float sx,sy,wx,wy; - + char *env, filename[128]; + float sx, sy, wx, wy; + // Read fits file - img=read_fits(argv[1]); + img = read_fits (argv[1]); // Set site - get_site(img.cospar); + get_site (img.cospar); // Initialize - initialize(img); + initialize (img); // Fill buffer - if (img.naxis==3) { - for (i=0,zavg=0.0;i2.0 || img.yrms/sy>2.0) - cpgsci(2); + cpgsch (0.8); + sprintf (text, "UT Date: %.23s COSPAR ID: %04d", img.nfd + 1, img.cospar); + cpgmtxt ("T", 6.0, 0.0, 0.0, text); + sprintf (text, "R.A.: %10.5f (%4.1f'') Decl.: %10.5f (%4.1f'')", img.ra0, + img.xrms, img.de0, img.yrms); + if (img.xrms < 1e-3 || img.yrms < 1e-3 || img.xrms / sx > 2.0 + || img.yrms / sy > 2.0) + cpgsci (2); else - cpgsci(1); - cpgmtxt("T",4.8,0.0,0.0,text); - cpgsci(1); + cpgsci (1); + cpgmtxt ("T", 4.8, 0.0, 0.0, text); + cpgsci (1); - - sprintf(text,"FoV: %.2f\\(2218)x%.2f\\(2218) Scale: %.2f''x%.2f'' pix\\u-1\\d",wx,wy,sx,sy); - cpgmtxt("T",3.6,0.0,0.0,text); - sprintf(text,"Stat: %5.1f+-%.1f (%.1f-%.1f)",zavg,zstd,zmin,zmax); - cpgmtxt("T",2.4,0.0,0.0,text); - - cpgsch(1.0); - cpgwnad(0.0,img.naxis1,0.0,img.naxis2); - cpglab("x (pix)","y (pix)"," "); - cpgctab (heat_l,heat_r,heat_g,heat_b,5,1.0,0.5); - - if (img.naxis==3) - cpgimag(img.zmax,img.naxis1,img.naxis2,1,img.naxis1,1,img.naxis2,zmin,zmax,tr); + sprintf (text, + "FoV: %.2f\\(2218)x%.2f\\(2218) Scale: %.2f''x%.2f'' pix\\u-1\\d", + wx, wy, sx, sy); + cpgmtxt ("T", 3.6, 0.0, 0.0, text); + sprintf (text, "Stat: %5.1f+-%.1f (%.1f-%.1f)", zavg, zstd, zmin, zmax); + cpgmtxt ("T", 2.4, 0.0, 0.0, text); + + cpgsch (1.0); + cpgwnad (0.0, img.naxis1, 0.0, img.naxis2); + + cpglab ("x (pix)", "y (pix)", " "); + cpgctab (heat_l, heat_r, heat_g, heat_b, 5, 1.0, 0.5); + + if (img.naxis == 3) + cpgimag (img.zmax, img.naxis1, img.naxis2, 1, img.naxis1, 1, img.naxis2, + zmin, zmax, tr); else - cpgimag(img.zavg,img.naxis1,img.naxis2,1,img.naxis1,1,img.naxis2,zmin,zmax,tr); - cpgbox("BCTSNI",0.,0,"BCTSNI",0.,0); + cpgimag (img.zavg, img.naxis1, img.naxis2, 1, img.naxis1, 1, img.naxis2, + zmin, zmax, tr); + cpgbox ("BCTSNI", 0., 0, "BCTSNI", 0., 0); - cpgstbg(1); + cpgstbg (1); // Environment variables - env=getenv("ST_TLEDIR"); - sprintf(filename,"%s/classfd.tle",env); - plot_satellites(filename,img,0,img.mjd,img.exptime,4); - sprintf(filename,"%s/inttles.tle",env); - plot_satellites(filename,img,0,img.mjd,img.exptime,3); - sprintf(filename,"%s/catalog.tle",env); - plot_satellites(filename,img,0,img.mjd,img.exptime,0); - sprintf(filename,"%s/jsc.txt",env); - plot_satellites(filename,img,0,img.mjd,img.exptime,5); + env = getenv ("ST_TLEDIR"); + sprintf (filename, "%s/classfd.tle", env); + plot_satellites (filename, img, 0, img.mjd, img.exptime, 4); + sprintf (filename, "%s/inttles.tle", env); + plot_satellites (filename, img, 0, img.mjd, img.exptime, 3); + sprintf (filename, "%s/catalog.tle", env); + plot_satellites (filename, img, 0, img.mjd, img.exptime, 0); + sprintf (filename, "%s/jsc.txt", env); + plot_satellites (filename, img, 0, img.mjd, img.exptime, 5); + + cpgend (); - cpgend(); - return 0; } // Read fits image -struct image read_fits(char *filename) +struct image +read_fits (char *filename) { - int i,j,k,l,m; + int i, j, k, l, m; qfitsloader ql; - char key[FITS_LINESZ+1]; - char val[FITS_LINESZ+1]; + char key[FITS_LINESZ + 1]; + char val[FITS_LINESZ + 1]; struct image img; // Copy filename - strcpy(img.filename,filename); + strcpy (img.filename, filename); // Image size - img.naxis=atoi(qfits_query_hdr(filename,"NAXIS")); - img.naxis1=atoi(qfits_query_hdr(filename,"NAXIS1")); - img.naxis2=atoi(qfits_query_hdr(filename,"NAXIS2")); + img.naxis = atoi (qfits_query_hdr (filename, "NAXIS")); + img.naxis1 = atoi (qfits_query_hdr (filename, "NAXIS1")); + img.naxis2 = atoi (qfits_query_hdr (filename, "NAXIS2")); // MJD - img.mjd=(double) atof(qfits_query_hdr(filename,"MJD-OBS")); - strcpy(img.nfd,qfits_query_hdr(filename,"DATE-OBS")); - img.exptime=atof(qfits_query_hdr(filename,"EXPTIME")); + img.mjd = (double) atof (qfits_query_hdr (filename, "MJD-OBS")); + strcpy (img.nfd, qfits_query_hdr (filename, "DATE-OBS")); + img.exptime = atof (qfits_query_hdr (filename, "EXPTIME")); // COSPAR ID - img.cospar=atoi(qfits_query_hdr(filename,"COSPAR")); + img.cospar = atoi (qfits_query_hdr (filename, "COSPAR")); // Tracked - if (qfits_query_hdr(filename,"TRACKED")!=NULL) - img.tracked=atoi(qfits_query_hdr(filename,"TRACKED")); + if (qfits_query_hdr (filename, "TRACKED") != NULL) + img.tracked = atoi (qfits_query_hdr (filename, "TRACKED")); else - img.tracked=0; + img.tracked = 0; // Transformation - img.ra0=atof(qfits_query_hdr(filename,"CRVAL1")); - img.de0=atof(qfits_query_hdr(filename,"CRVAL2")); - img.x0=atof(qfits_query_hdr(filename,"CRPIX1")); - img.y0=atof(qfits_query_hdr(filename,"CRPIX2")); - img.a[0]=0.0; - img.a[1]=3600.0*atof(qfits_query_hdr(filename,"CD1_1")); - img.a[2]=3600.0*atof(qfits_query_hdr(filename,"CD1_2")); - img.b[0]=0.0; - img.b[1]=3600.0*atof(qfits_query_hdr(filename,"CD2_1")); - img.b[2]=3600.0*atof(qfits_query_hdr(filename,"CD2_2")); - img.xrms=3600.0*atof(qfits_query_hdr(filename,"CRRES1")); - img.yrms=3600.0*atof(qfits_query_hdr(filename,"CRRES2")); + img.ra0 = atof (qfits_query_hdr (filename, "CRVAL1")); + img.de0 = atof (qfits_query_hdr (filename, "CRVAL2")); + img.x0 = atof (qfits_query_hdr (filename, "CRPIX1")); + img.y0 = atof (qfits_query_hdr (filename, "CRPIX2")); + img.a[0] = 0.0; + img.a[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_1")); + img.a[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_2")); + img.b[0] = 0.0; + img.b[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_1")); + img.b[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_2")); + img.xrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES1")); + img.yrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES2")); // Set parameters - ql.xtnum=0; - ql.ptype=PTYPE_FLOAT; - ql.filename=filename; + ql.xtnum = 0; + ql.ptype = PTYPE_FLOAT; + ql.filename = filename; // Read four-frame info - if (img.naxis==3) { - // Number of frames - img.nframes=atoi(qfits_query_hdr(filename,"NFRAMES")); + if (img.naxis == 3) + { + // Number of frames + img.nframes = atoi (qfits_query_hdr (filename, "NFRAMES")); - // Timestamps - img.dt=(float *) malloc(sizeof(float)*img.nframes); - for (i=0;ix=gc*cos(m.lat*D2R)*cos(theta*D2R)*XKMPER; - pos->y=gc*cos(m.lat*D2R)*sin(theta*D2R)*XKMPER; - pos->z=gs*sin(m.lat*D2R)*XKMPER; - vel->x=-gc*cos(m.lat*D2R)*sin(theta*D2R)*XKMPER*dtheta; - vel->y=gc*cos(m.lat*D2R)*cos(theta*D2R)*XKMPER*dtheta; - vel->z=0.0; + pos->x = gc * cos (m.lat * D2R) * cos (theta * D2R) * XKMPER; + pos->y = gc * cos (m.lat * D2R) * sin (theta * D2R) * XKMPER; + pos->z = gs * sin (m.lat * D2R) * XKMPER; + vel->x = -gc * cos (m.lat * D2R) * sin (theta * D2R) * XKMPER * dtheta; + vel->y = gc * cos (m.lat * D2R) * cos (theta * D2R) * XKMPER * dtheta; + vel->z = 0.0; return; } // Solar position -void sunpos_xyz(double mjd,xyz_t *pos) +void +sunpos_xyz (double mjd, xyz_t * pos) { - double jd,t,l0,m,e,c,r; - double n,s,ecl,ra,de; + double jd, t, l0, m, e, c, r; + double n, s, ecl, ra, de; - jd=mjd+2400000.5; - t=(jd-2451545.0)/36525.0; - l0=modulo(280.46646+t*(36000.76983+t*0.0003032),360.0)*D2R; - m=modulo(357.52911+t*(35999.05029-t*0.0001537),360.0)*D2R; - e=0.016708634+t*(-0.000042037-t*0.0000001267); - c=(1.914602+t*(-0.004817-t*0.000014))*sin(m)*D2R; - c+=(0.019993-0.000101*t)*sin(2.0*m)*D2R; - c+=0.000289*sin(3.0*m)*D2R; + jd = mjd + 2400000.5; + t = (jd - 2451545.0) / 36525.0; + l0 = modulo (280.46646 + t * (36000.76983 + t * 0.0003032), 360.0) * D2R; + m = modulo (357.52911 + t * (35999.05029 - t * 0.0001537), 360.0) * D2R; + e = 0.016708634 + t * (-0.000042037 - t * 0.0000001267); + c = (1.914602 + t * (-0.004817 - t * 0.000014)) * sin (m) * D2R; + c += (0.019993 - 0.000101 * t) * sin (2.0 * m) * D2R; + c += 0.000289 * sin (3.0 * m) * D2R; - r=1.000001018*(1.0-e*e)/(1.0+e*cos(m+c)); - n=modulo(125.04-1934.136*t,360.0)*D2R; - s=l0+c+(-0.00569-0.00478*sin(n))*D2R; - ecl=(23.43929111+(-46.8150*t-0.00059*t*t+0.001813*t*t*t)/3600.0+0.00256*cos(n))*D2R; + r = 1.000001018 * (1.0 - e * e) / (1.0 + e * cos (m + c)); + n = modulo (125.04 - 1934.136 * t, 360.0) * D2R; + s = l0 + c + (-0.00569 - 0.00478 * sin (n)) * D2R; + ecl = + (23.43929111 + + (-46.8150 * t - 0.00059 * t * t + 0.001813 * t * t * t) / 3600.0 + + 0.00256 * cos (n)) * D2R; - ra=atan2(cos(ecl)*sin(s),cos(s)); - de=asin(sin(ecl)*sin(s)); + ra = atan2 (cos (ecl) * sin (s), cos (s)); + de = asin (sin (ecl) * sin (s)); - pos->x=r*cos(de)*cos(ra)*XKMPAU; - pos->y=r*cos(de)*sin(ra)*XKMPAU; - pos->z=r*sin(de)*XKMPAU; + pos->x = r * cos (de) * cos (ra) * XKMPAU; + pos->y = r * cos (de) * sin (ra) * XKMPAU; + pos->z = r * sin (de) * XKMPAU; return; } // Compute precession angles -void precession_angles(double mjd0,double mjd,double *zeta,double *z,double *theta) +void +precession_angles (double mjd0, double mjd, double *zeta, double *z, + double *theta) { - double t0,t; + double t0, t; // Time in centuries - t0=(mjd0-51544.5)/36525.0; - t=(mjd-mjd0)/36525.0; + t0 = (mjd0 - 51544.5) / 36525.0; + t = (mjd - mjd0) / 36525.0; // Precession angles - *zeta=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - *zeta+=(0.30188-0.000344*t0)*t*t+0.017998*t*t*t; - *zeta*=D2R/3600.0; - *z=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - *z+=(1.09468+0.000066*t0)*t*t+0.018203*t*t*t; - *z*=D2R/3600.0; - *theta=(2004.3109-0.85330*t0-0.000217*t0*t0)*t; - *theta+=-(0.42665+0.000217*t0)*t*t-0.041833*t*t*t; - *theta*=D2R/3600.0; - + *zeta = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + *zeta += (0.30188 - 0.000344 * t0) * t * t + 0.017998 * t * t * t; + *zeta *= D2R / 3600.0; + *z = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + *z += (1.09468 + 0.000066 * t0) * t * t + 0.018203 * t * t * t; + *z *= D2R / 3600.0; + *theta = (2004.3109 - 0.85330 * t0 - 0.000217 * t0 * t0) * t; + *theta += -(0.42665 + 0.000217 * t0) * t * t - 0.041833 * t * t * t; + *theta *= D2R / 3600.0; + return; } // Initialize observer and sun position and precession angles -void initialize(struct image img) +void +initialize (struct image img) { int i; double t; xyz_t obsvel; // Loop over points - for (i=0;i180.0) - l0-=360.0; - + l0 = modulo (sra - h, 360.0); + b0 = sde; + if (l0 > 180.0) + l0 -= 360.0; + // Loop over terminator boundaries - for (k=0;k<4;k++) { - for (i=0,j=0,flag=0;i180.0) - l[j]-=360.0; - if (l[j]<-180.0) - l[j]+=360.0; - - // Passing limit left to right - if (l[j]*l[j-1]<0.0 && fabs(l[j])>45.0 && flag==0 && k==0) { - l[j+4]=l[j]; - b[j+4]=b[j]; - b[j]=b[j-1]; - b[j+3]=b[j-1]; - if (l[j-1] 180.0) + l[j] -= 360.0; + if (l[j] < -180.0) + l[j] += 360.0; + + // Passing limit left to right + if (l[j] * l[j - 1] < 0.0 && fabs (l[j]) > 45.0 && flag == 0 + && k == 0) + { + l[j + 4] = l[j]; + b[j + 4] = b[j]; + b[j] = b[j - 1]; + b[j + 3] = b[j - 1]; + if (l[j - 1] < l[j]) + { + l[j] = -180.0; + l[j + 1] = -180.0; + l[j + 2] = 180.0; + l[j + 3] = 180.0; + } + else + { + l[j] = 180.0; + l[j + 1] = 180.0; + l[j + 2] = -180.0; + l[j + 3] = -180.0; + } + if (b0 <= 0.0) + { + b[j + 1] = 90.0; + b[j + 2] = 90.0; + } + else + { + b[j + 1] = -90.0; + b[j + 2] = -90.0; + } + j += 4; + flag = 1; + } } - if (b0<=0.0) { - b[j+1]=90.0; - b[j+2]=90.0; - } else { - b[j+1]=-90.0; - b[j+2]=-90.0; + + if (k == 0) + { + // Set night color + cpgscr (16, 0.0, 0.0, 0.2); + + // Plot night side + cpgsci (16); + cpgpoly (NMAX + 4, l, b); + + // Plot terminator + cpgsci (14); + cpgline (NMAX + 4, l, b); + cpgsci (1); + } + else + { + // Plot twilight boundaries + cpgsci (14); + for (i = 0, flag = 0; i < NMAX; i++) + { + if (i > 0 && l[i - 1] * l[i] < 0.0 + && fabs (l[i - 1] - l[i]) > 10.0) + flag = 0; + + if (flag == 0) + { + cpgmove (l[i], b[i]); + flag = 1; + } + else + { + cpgdraw (l[i], b[i]); + cpgmove (l[i], b[i]); + } + } + cpgsci (1); } - j+=4; - flag=1; - } } - - if (k==0) { - // Set night color - cpgscr(16,0.0,0.0,0.2); - - // Plot night side - cpgsci(16); - cpgpoly(NMAX+4,l,b); - - // Plot terminator - cpgsci(14); - cpgline(NMAX+4,l,b); - cpgsci(1); - } else { - // Plot twilight boundaries - cpgsci(14); - for (i=0,flag=0;i0 && l[i-1]*l[i]<0.0 && fabs(l[i-1]-l[i])>10.0) - flag=0; - - if (flag==0) { - cpgmove(l[i],b[i]); - flag=1; - } else { - cpgdraw(l[i],b[i]); - cpgmove(l[i],b[i]); - } - } - cpgsci(1); - } - } // Save sub solar position - m.l0=l0; - m.b0=b0; + m.l0 = l0; + m.b0 = b0; return; } -void init_plot(char *psfile,float width,float aspect) +void +init_plot (char *psfile, float width, float aspect) { - - cpgslw(2); + + cpgslw (2); return; } // Plot observing sites -void plot_sites(void) +void +plot_sites (void) { - int i=0; + int i = 0; char line[LIM]; FILE *file; int id; - double lat,lng; + double lat, lng; float alt; - char abbrev[3],observer[64],text[8],filename[LIM]; + char abbrev[3], observer[64], text[8], filename[LIM]; float isch; - cpgqch(&isch); + cpgqch (&isch); - sprintf(filename,"%s/data/sites.txt",m.datadir); - file=fopen(filename,"r"); - if (file==NULL) { - printf("File with site information not found!\n"); - return; - } - while (fgets(line,LIM,file)!=NULL) { - // Skip - if (strstr(line,"#")!=NULL) - continue; + sprintf (filename, "%s/data/sites.txt", m.datadir); + file = fopen (filename, "r"); + if (file == NULL) + { + printf ("File with site information not found!\n"); + return; + } + while (fgets (line, LIM, file) != NULL) + { + // Skip + if (strstr (line, "#") != NULL) + continue; - // Strip newline - line[strlen(line)-1]='\0'; + // Strip newline + line[strlen (line) - 1] = '\0'; - // Read data - sscanf(line,"%4d %2s %lf %lf %f", - &id,abbrev,&lat,&lng,&alt); - strcpy(observer,line+38); + // Read data + sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt); + strcpy (observer, line + 38); - sprintf(text," %04d",id); - cpgsci(2); - cpgsch(0.5); - cpgpt1(lng,lat,4); - cpgtext(lng,lat,text); - cpgsci(1); - } - fclose(file); - cpgsch(isch); + sprintf (text, " %04d", id); + cpgsci (2); + cpgsch (0.5); + cpgpt1 (lng, lat, 4); + cpgtext (lng, lat, text); + cpgsci (1); + } + fclose (file); + cpgsch (isch); return; } // Plot observing sites -void plot_launch_sites(void) +void +plot_launch_sites (void) { - int i=0; + int i = 0; char line[LIM]; FILE *file; - double lat,lng; - char site[64],text[8],filename[LIM]; + double lat, lng; + char site[64], text[8], filename[LIM]; float isch; - cpgqch(&isch); + cpgqch (&isch); - sprintf(filename,"%s/data/launchsites.txt",m.datadir); - file=fopen(filename,"r"); - if (file==NULL) { - printf("File with site information not found!\n"); - return; - } - while (fgets(line,LIM,file)!=NULL) { - // Skip - if (strstr(line,"#")!=NULL) - continue; + sprintf (filename, "%s/data/launchsites.txt", m.datadir); + file = fopen (filename, "r"); + if (file == NULL) + { + printf ("File with site information not found!\n"); + return; + } + while (fgets (line, LIM, file) != NULL) + { + // Skip + if (strstr (line, "#") != NULL) + continue; - // Strip newline - line[strlen(line)-1]='\0'; + // Strip newline + line[strlen (line) - 1] = '\0'; - // Read data - sscanf(line,"%lf %lf", - &lat,&lng); - strcpy(site,line+21); + // Read data + sscanf (line, "%lf %lf", &lat, &lng); + strcpy (site, line + 21); - cpgsci(2); - cpgsch(0.5); - cpgpt1(lng,lat,4); - cpgtext(lng,lat,site); - cpgsci(1); - } - fclose(file); - cpgsch(isch); + cpgsci (2); + cpgsch (0.5); + cpgpt1 (lng, lat, 4); + cpgtext (lng, lat, site); + cpgsci (1); + } + fclose (file); + cpgsch (isch); return; } // Computes apparent position -struct sat apparent_position(double mjd) +struct sat +apparent_position (double mjd) { struct sat s; - double jd,rsun,rearth; - double dx,dy,dz; - xyz_t satpos,obspos,satvel,sunpos; - double sra,sde; + double jd, rsun, rearth; + double dx, dy, dz; + xyz_t satpos, obspos, satvel, sunpos; + double sra, sde; // Sat ID - s.Isat=Isat; + s.Isat = Isat; // Get Julian Date - jd=mjd+2400000.5; + jd = mjd + 2400000.5; // Get positions - satpos_xyz(jd,&satpos,&satvel); - sunpos_xyz(mjd,&sunpos,&sra,&sde); + satpos_xyz (jd, &satpos, &satvel); + sunpos_xyz (mjd, &sunpos, &sra, &sde); // Sat positions - s.x=satpos.x; - s.y=satpos.y; - s.z=satpos.z; - s.vx=satvel.x; - s.vy=satvel.y; - s.vz=satvel.y; + s.x = satpos.x; + s.y = satpos.y; + s.z = satpos.z; + s.vx = satvel.x; + s.vy = satvel.y; + s.vz = satvel.y; // Sun position from satellite - dx=-satpos.x+sunpos.x; - dy=-satpos.y+sunpos.y; - dz=-satpos.z+sunpos.z; + dx = -satpos.x + sunpos.x; + dy = -satpos.y + sunpos.y; + dz = -satpos.z + sunpos.z; // Distances - rsun=sqrt(dx*dx+dy*dy+dz*dz); - rearth=sqrt(satpos.x*satpos.x+satpos.y*satpos.y+satpos.z*satpos.z); + rsun = sqrt (dx * dx + dy * dy + dz * dz); + rearth = + sqrt (satpos.x * satpos.x + satpos.y * satpos.y + satpos.z * satpos.z); // Angles - s.psun=asin(696.0e3/rsun)*R2D; - s.pearth=asin(6378.135/rearth)*R2D; - s.p=acos((-dx*satpos.x-dy*satpos.y-dz*satpos.z)/(rsun*rearth))*R2D; + s.psun = asin (696.0e3 / rsun) * R2D; + s.pearth = asin (6378.135 / rearth) * R2D; + s.p = + acos ((-dx * satpos.x - dy * satpos.y - + dz * satpos.z) / (rsun * rearth)) * R2D; // s.p=acos(((sunpos.x+satpos.x)*satpos.x+(sunpos.y+satpos.y)*satpos.y+(sunpos.z+satpos.z)*satpos.z)/(rsun*rearth))*R2D; - s.p-=s.pearth; + s.p -= s.pearth; // Celestial position - s.r=sqrt(satpos.x*satpos.x+satpos.y*satpos.y+satpos.z*satpos.z); - s.ra=atan2(satpos.y,satpos.x)*R2D; - s.de=asin(satpos.z/s.r)*R2D; - + s.r = + sqrt (satpos.x * satpos.x + satpos.y * satpos.y + satpos.z * satpos.z); + s.ra = atan2 (satpos.y, satpos.x) * R2D; + s.de = asin (satpos.z / s.r) * R2D; + return s; } // plot satellite track -void track_plot_track(char *tlefile,long satno,double mjd0) +void +track_plot_track (char *tlefile, long satno, double mjd0) { - int i=0,nstep=500; + int i = 0, nstep = 500; orbit_t orb; - xyz_t pos,vel; - double jd,dt,h,l,b,l0,mjd; - FILE *fp=NULL; - float x,y,z,r,v; + xyz_t pos, vel; + double jd, dt, h, l, b, l0, mjd; + FILE *fp = NULL; + float x, y, z, r, v; long imode; int isci; float isch; char norad[7]; struct sat s; - cpgqci(&isci); - cpgqch(&isch); - cpgsci(7); + cpgqci (&isci); + cpgqch (&isch); + cpgsci (7); - fp = fopen(tlefile, "rb"); - if(fp == NULL) { - fatal_error("File open failed for reading \"%s\"", tlefile); - } - - while(read_twoline(fp, satno, &orb) == 0) { - // print_orb(&orb); - - Isat = orb.satno; - imode = init_sgdp4(&orb); - - if(imode == SGDP4_ERROR) continue; - - jd=mjd0+2400000.5; - for (i=0;;i++) { - // if(satpos_xyz(jd, &pos, &vel) == SGDP4_ERROR) break; - mjd=jd-2400000.5; - s=apparent_position(mjd); - - h=gmst(mjd); - - x=s.x; - y=s.y; - z=s.z; - - // Celestial position - r=sqrt(x*x+y*y+z*z); - l=atan2(y,x)*R2D; - b=asin(z/r)*R2D; - l-=h; - l=modulo(l,360.0); - if (l>180.0) - l-=360.0; - if (l<-180.0) - l+=360.0; - - // Visibility - if (s.p<-s.psun) - cpgsci(14); - else if (s.p>-s.psun && s.ps.psun) - cpgsci(7); - - // Plot - if (i==0) { - sprintf(norad," %ld",Isat); - cpgsch(0.6); - cpgtext(l,b,norad); - cpgsch(isch); - cpgpt1(l,b,17); - l0=l; - } - if (i==0 || fabs(l-l0)>10.0) - cpgmove(l,b); - else - cpgdraw(l,b); - cpgmove(l,b); - l0=l; - - // Do timestep - r=sqrt(s.x*s.x+s.y*s.y+s.z*s.z); - v=sqrt(s.vx*s.vx+s.vy*s.vy+s.vz*s.vz); - dt=2.0*M_PI*r/(0.75*v*nstep); - jd+=dt/86400.0; - - if (i==nstep) - break; + fp = fopen (tlefile, "rb"); + if (fp == NULL) + { + fatal_error ("File open failed for reading \"%s\"", tlefile); } - } - cpgsci(isci); - cpgsch(isch); + + while (read_twoline (fp, satno, &orb) == 0) + { + // print_orb(&orb); + + Isat = orb.satno; + imode = init_sgdp4 (&orb); + + if (imode == SGDP4_ERROR) + continue; + + jd = mjd0 + 2400000.5; + for (i = 0;; i++) + { + // if(satpos_xyz(jd, &pos, &vel) == SGDP4_ERROR) break; + mjd = jd - 2400000.5; + s = apparent_position (mjd); + + h = gmst (mjd); + + x = s.x; + y = s.y; + z = s.z; + + // Celestial position + r = sqrt (x * x + y * y + z * z); + l = atan2 (y, x) * R2D; + b = asin (z / r) * R2D; + l -= h; + l = modulo (l, 360.0); + if (l > 180.0) + l -= 360.0; + if (l < -180.0) + l += 360.0; + + // Visibility + if (s.p < -s.psun) + cpgsci (14); + else if (s.p > -s.psun && s.p < s.psun) + cpgsci (15); + else if (s.p > s.psun) + cpgsci (7); + + // Plot + if (i == 0) + { + sprintf (norad, " %ld", Isat); + cpgsch (0.6); + cpgtext (l, b, norad); + cpgsch (isch); + cpgpt1 (l, b, 17); + l0 = l; + } + if (i == 0 || fabs (l - l0) > 10.0) + cpgmove (l, b); + else + cpgdraw (l, b); + cpgmove (l, b); + l0 = l; + + // Do timestep + r = sqrt (s.x * s.x + s.y * s.y + s.z * s.z); + v = sqrt (s.vx * s.vx + s.vy * s.vy + s.vz * s.vz); + dt = 2.0 * M_PI * r / (0.75 * v * nstep); + jd += dt / 86400.0; + + if (i == nstep) + break; + } + } + cpgsci (isci); + cpgsch (isch); return; } -void plot_map(void) +void +plot_map (void) { - int redraw=1; + int redraw = 1; char text[256]; - float x,y; + float x, y; char c; - for (;;) { - if (redraw>0) { - // Get present mjd - if (m.mjd<0.0) { - nfd_now(m.nfd); - m.mjd=nfd2mjd(m.nfd); - } + for (;;) + { + if (redraw > 0) + { + // Get present mjd + if (m.mjd < 0.0) + { + nfd_now (m.nfd); + m.mjd = nfd2mjd (m.nfd); + } - cpgscr(0,0.0,0.0,0.0); - cpgeras(); + cpgscr (0, 0.0, 0.0, 0.0); + cpgeras (); - // Create window - cpgsvp(0.01,0.99,0.01,0.99); - cpgwnad(-180.0,180.0,-90.0,90.0); + // Create window + cpgsvp (0.01, 0.99, 0.01, 0.99); + cpgwnad (-180.0, 180.0, -90.0, 90.0); - // Set background - cpgscr(0,0.0,0.0,0.5); - cpgsci(0); - cpgrect(-180.0,180.0,-90.0,90.0); - cpgsci(1); - cpgscr(0,0.0,0.0,0.0); - cpgbox("BC",0.,0,"BC",0.,0); - - // Top left string - cpgsch(0.8); - mjd2date(m.mjd,m.nfd,0); - sprintf(text,"%s UTC",m.nfd); - cpgmtxt("T",0.6,0.0,0.0,text); - - // Bottom string - sprintf(text,"l: %d s",m.length); - cpgmtxt("B",1.0,0.0,0.0,text); - cpgsch(1.0); + // Set background + cpgscr (0, 0.0, 0.0, 0.5); + cpgsci (0); + cpgrect (-180.0, 180.0, -90.0, 90.0); + cpgsci (1); + cpgscr (0, 0.0, 0.0, 0.0); + cpgbox ("BC", 0., 0, "BC", 0., 0); - // Plot terminator - plot_terminator(); - cpgsci(14); - cpgbox("ABCG",30.,3,"ABCG",30.,3); - cpgsci(1); + // Top left string + cpgsch (0.8); + mjd2date (m.mjd, m.nfd, 0); + sprintf (text, "%s UTC", m.nfd); + cpgmtxt ("T", 0.6, 0.0, 0.0, text); - // Plot globe - plot_globe(); - cpgsci(1); - cpgbox("BCTS",30.,3,"BCTS",30.,3); + // Bottom string + sprintf (text, "l: %d s", m.length); + cpgmtxt ("B", 1.0, 0.0, 0.0, text); + cpgsch (1.0); - // Plot sites - // plot_sites(); + // Plot terminator + plot_terminator (); + cpgsci (14); + cpgbox ("ABCG", 30., 3, "ABCG", 30., 3); + cpgsci (1); - // Plot launch sites - plot_launch_sites(); + // Plot globe + plot_globe (); + cpgsci (1); + cpgbox ("BCTS", 30., 3, "BCTS", 30., 3); - // Plot satellites - track_plot_track(m.tlefile,m.satno,m.mjd); + // Plot sites + // plot_sites(); - // Plot sub solar position - cpgsci(7); - cpgpt1(m.l0,m.b0,17); - cpgsci(1); + // Plot launch sites + plot_launch_sites (); + + // Plot satellites + track_plot_track (m.tlefile, m.satno, m.mjd); + + // Plot sub solar position + cpgsci (7); + cpgpt1 (m.l0, m.b0, 17); + cpgsci (1); + } + + // Reset redraw + redraw = 0; + + // Get cursor + cpgcurs (&x, &y, &c); + + // Help + if (c == 'h') + { + interactive_usage (); + + continue; + } + + // Redraw + if (c == 'r') + { + m.mjd = -1.0; + m.length = 60; + redraw = 1; + } + // Increase/decrease time + if (c == '.') + { + m.mjd += m.length / 86400.0; + redraw = 1; + } + if (c == ',') + { + m.mjd -= m.length / 86400.0; + redraw = 1; + } + + // Increase/decrease step + if (c == '>') + { + m.length *= 2.0; + redraw = 2; + } + if (c == '<') + { + m.length /= 2.0; + redraw = 2; + } + + // Exit + if (c == 'q' || c == 'Q') + { + cpgend (); + exit (0); + } } - - // Reset redraw - redraw=0; - - // Get cursor - cpgcurs(&x,&y,&c); - - // Help - if (c=='h') { - interactive_usage(); - - continue; - } - - // Redraw - if (c=='r') { - m.mjd=-1.0; - m.length=60; - redraw=1; - } - // Increase/decrease time - if (c=='.') { - m.mjd+=m.length/86400.0; - redraw=1; - } - if (c==',') { - m.mjd-=m.length/86400.0; - redraw=1; - } - - // Increase/decrease step - if (c=='>') { - m.length*=2.0; - redraw=2; - } - if (c=='<') { - m.length/=2.0; - redraw=2; - } - - // Exit - if (c=='q' || c=='Q') { - cpgend(); - exit(0); - } - } return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int arg=0; + int arg = 0; // Initialize setup - initialize_setup(); + initialize_setup (); // Decode options - while ((arg=getopt(argc,argv,"t:c:i:s:l:h"))!=-1) { - switch (arg) { - - case 't': - strcpy(m.nfd,optarg); - m.mjd=nfd2mjd(m.nfd); - break; + while ((arg = getopt (argc, argv, "t:c:i:s:l:h")) != -1) + { + switch (arg) + { - case 'c': - strcpy(m.tlefile,optarg); - break; + case 't': + strcpy (m.nfd, optarg); + m.mjd = nfd2mjd (m.nfd); + break; - case 's': - get_site(atoi(optarg)); - break; + case 'c': + strcpy (m.tlefile, optarg); + break; - case 'i': - m.satno=atoi(optarg); - break; + case 's': + get_site (atoi (optarg)); + break; - case 'l': - m.length=atoi(optarg); - break; + case 'i': + m.satno = atoi (optarg); + break; - case 'h': - usage(); - return 0; - break; + case 'l': + m.length = atoi (optarg); + break; - default: - usage(); - return 0; + case 'h': + usage (); + return 0; + break; + + default: + usage (); + return 0; + } } - } // Read data - read_globe(); + read_globe (); // Initialize plot - giza_open_device_size("/xs", "satmap", 1920, 1020, 3); - giza_set_colour_palette(1); - - plot_map(); + giza_open_device_size ("/xs", "satmap", 1920, 1020, 3); + giza_set_colour_palette (1); - cpgend(); + plot_map (); + + cpgend (); return 0; } -void read_globe(void) +void +read_globe (void) { - int i,status; + int i, status; FILE *file; char filename[LIM]; - sprintf(filename,"%s/data/globe.dat",m.datadir); - file=fopen(filename,"r"); + sprintf (filename, "%s/data/globe.dat", m.datadir); + file = fopen (filename, "r"); - for (i=0;itm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec); - + time (&rawtime); + ptm = gmtime (&rawtime); + + sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900, + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, + ptm->tm_sec); + return; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min,sec; - double mjd,dday; + int year, month, day, hour, min, sec; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; - mjd=date2mjd(year,month,dday); + mjd = date2mjd (year, month, dday); return mjd; } -void usage() +void +usage () { - printf("usage: satmap -c TLEFILE [-t TIMESTAMP] [-s COSPARID] [-i SATNO]\n"); - printf(" [-l LENGTH] [-h]\n"); + printf + ("usage: satmap -c TLEFILE [-t TIMESTAMP] [-s COSPARID] [-i SATNO]\n"); + printf (" [-l LENGTH] [-h]\n"); } -void interactive_usage() +void +interactive_usage () { - printf("Interactive help:"); - printf("r Redraw\n"); - printf("\n"); - printf("< Divide the integration length by a facor of 2\n"); - printf("> Multiply the integration length by a facor of 2\n"); - printf("\n"); - printf(", Increase time (+integration_length in seconds /(1 day))\n"); - printf(". Roll back the time\n"); - printf("\n"); - printf("h this interactive help\n"); - printf("q/Q Exit\n"); + printf ("Interactive help:"); + printf ("r Redraw\n"); + printf ("\n"); + printf ("< Divide the integration length by a facor of 2\n"); + printf ("> Multiply the integration length by a facor of 2\n"); + printf ("\n"); + printf (", Increase time (+integration_length in seconds /(1 day))\n"); + printf (". Roll back the time\n"); + printf ("\n"); + printf ("h this interactive help\n"); + printf ("q/Q Exit\n"); } // Compute Date from Julian Day -void mjd2date(double mjd,char *date,int length) +void +mjd2date (double mjd, char *date, int length) { - double f,jd,dday; - int z,alpha,a,b,c,d,e; - int year,month,day,hour,min; - float sec,x; + double f, jd, dday; + int z, alpha, a, b, c, d, e; + int year, month, day, hour, min; + float sec, x; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - dday=b-d-floor(30.6001*e)+f; - if (e<14) - month=e-1; + if (z < 2299161) + a = z; else - month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (month>2) - year=c-4716; + dday = b - d - floor (30.6001 * e) + f; + if (e < 14) + month = e - 1; else - year=c-4715; + month = e - 13; - day=(int) floor(dday); - x=24.0*(dday-day); - x=3600.*fabs(x); - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - hour=x; - sec=floor(1000.0*sec)/1000.0; + if (month > 2) + year = c - 4716; + else + year = c - 4715; - if (length==3) - sprintf(date,"%04d-%02d-%02dT%02d:%02d:%06.3f",year,month,day,hour,min,sec); - else if (length==0) - sprintf(date,"%04d-%02d-%02dT%02d:%02d:%02.0f",year,month,day,hour,min,sec); + day = (int) floor (dday); + x = 24.0 * (dday - day); + x = 3600. * fabs (x); + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + hour = x; + sec = floor (1000.0 * sec) / 1000.0; + + if (length == 3) + sprintf (date, "%04d-%02d-%02dT%02d:%02d:%06.3f", year, month, day, hour, + min, sec); + else if (length == 0) + sprintf (date, "%04d-%02d-%02dT%02d:%02d:%02.0f", year, month, day, hour, + min, sec); return; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // Solar position -void sunpos_xyz(double mjd,xyz_t *pos,double *ra,double *de) +void +sunpos_xyz (double mjd, xyz_t * pos, double *ra, double *de) { - double jd,t,l0,m,e,c,r; - double n,s,ecl; + double jd, t, l0, m, e, c, r; + double n, s, ecl; - jd=mjd+2400000.5; - t=(jd-2451545.0)/36525.0; - l0=modulo(280.46646+t*(36000.76983+t*0.0003032),360.0)*D2R; - m=modulo(357.52911+t*(35999.05029-t*0.0001537),360.0)*D2R; - e=0.016708634+t*(-0.000042037-t*0.0000001267); - c=(1.914602+t*(-0.004817-t*0.000014))*sin(m)*D2R; - c+=(0.019993-0.000101*t)*sin(2.0*m)*D2R; - c+=0.000289*sin(3.0*m)*D2R; + jd = mjd + 2400000.5; + t = (jd - 2451545.0) / 36525.0; + l0 = modulo (280.46646 + t * (36000.76983 + t * 0.0003032), 360.0) * D2R; + m = modulo (357.52911 + t * (35999.05029 - t * 0.0001537), 360.0) * D2R; + e = 0.016708634 + t * (-0.000042037 - t * 0.0000001267); + c = (1.914602 + t * (-0.004817 - t * 0.000014)) * sin (m) * D2R; + c += (0.019993 - 0.000101 * t) * sin (2.0 * m) * D2R; + c += 0.000289 * sin (3.0 * m) * D2R; - r=1.000001018*(1.0-e*e)/(1.0+e*cos(m+c)); - n=modulo(125.04-1934.136*t,360.0)*D2R; - s=l0+c+(-0.00569-0.00478*sin(n))*D2R; - ecl=(23.43929111+(-46.8150*t-0.00059*t*t+0.001813*t*t*t)/3600.0+0.00256*cos(n))*D2R; + r = 1.000001018 * (1.0 - e * e) / (1.0 + e * cos (m + c)); + n = modulo (125.04 - 1934.136 * t, 360.0) * D2R; + s = l0 + c + (-0.00569 - 0.00478 * sin (n)) * D2R; + ecl = + (23.43929111 + + (-46.8150 * t - 0.00059 * t * t + 0.001813 * t * t * t) / 3600.0 + + 0.00256 * cos (n)) * D2R; - *ra=atan2(cos(ecl)*sin(s),cos(s))*R2D; - *de=asin(sin(ecl)*sin(s))*R2D; + *ra = atan2 (cos (ecl) * sin (s), cos (s)) * R2D; + *de = asin (sin (ecl) * sin (s)) * R2D; - pos->x=r*cos(*de*D2R)*cos(*ra*D2R)*XKMPAU; - pos->y=r*cos(*de*D2R)*sin(*ra*D2R)*XKMPAU; - pos->z=r*sin(*de*D2R)*XKMPAU; + pos->x = r * cos (*de * D2R) * cos (*ra * D2R) * XKMPAU; + pos->y = r * cos (*de * D2R) * sin (*ra * D2R) * XKMPAU; + pos->z = r * sin (*de * D2R) * XKMPAU; return; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } // Greenwich Mean Sidereal Time -double dgmst(double mjd) +double +dgmst (double mjd) { - double t,dgmst; + double t, dgmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - dgmst=360.98564736629+t*(0.000387933-t/38710000); + dgmst = 360.98564736629 + t * (0.000387933 - t / 38710000); return dgmst; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // rotate vector -void rotate(int axis,float angle,float *x,float *y,float *z) +void +rotate (int axis, float angle, float *x, float *y, float *z) { - float xx,yy,zz; - float ca,sa; + float xx, yy, zz; + float ca, sa; - ca=cos(angle*D2R); - sa=sin(angle*D2R); - - if (axis==0) { - xx= *x; - yy= *y*ca- *z*sa; - zz= *z*ca+ *y*sa; - } - if (axis==1) { - xx= *x*ca- *z*sa; - yy= *y; - zz= *z*ca+ *x*sa; - } - if (axis==2) { - xx= *x*ca- *y*sa; - yy= *y*ca+ *x*sa; - zz= *z; - } - - *x=xx; - *y=yy; - *z=zz; + ca = cos (angle * D2R); + sa = sin (angle * D2R); + + if (axis == 0) + { + xx = *x; + yy = *y * ca - *z * sa; + zz = *z * ca + *y * sa; + } + if (axis == 1) + { + xx = *x * ca - *z * sa; + yy = *y; + zz = *z * ca + *x * sa; + } + if (axis == 2) + { + xx = *x * ca - *y * sa; + yy = *y * ca + *x * sa; + zz = *z; + } + + *x = xx; + *y = yy; + *z = zz; return; } // Get observing site -void get_site(int site_id) +void +get_site (int site_id) { - int i=0; + int i = 0; char line[LIM]; FILE *file; int id; - double lat,lng; + double lat, lng; float alt; - char abbrev[3],observer[64]; + char abbrev[3], observer[64]; char filename[LIM]; - sprintf(filename,"%s/data/sites.txt",m.datadir); - file=fopen(filename,"r"); - if (file==NULL) { - printf("File with site information not found!\n"); - return; - } - while (fgets(line,LIM,file)!=NULL) { - // Skip - if (strstr(line,"#")!=NULL) - continue; - - // Strip newline - line[strlen(line)-1]='\0'; - - // Read data - sscanf(line,"%4d %2s %lf %lf %f", - &id,abbrev,&lat,&lng,&alt); - strcpy(observer,line+38); - - // Change to km - alt/=1000.0; - - if (id==site_id) { - m.lat=lat; - m.lng=lng; - m.alt=alt; - m.site_id=id; - strcpy(m.observer,observer); + sprintf (filename, "%s/data/sites.txt", m.datadir); + file = fopen (filename, "r"); + if (file == NULL) + { + printf ("File with site information not found!\n"); + return; } + while (fgets (line, LIM, file) != NULL) + { + // Skip + if (strstr (line, "#") != NULL) + continue; - } - fclose(file); + // Strip newline + line[strlen (line) - 1] = '\0'; + + // Read data + sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt); + strcpy (observer, line + 38); + + // Change to km + alt /= 1000.0; + + if (id == site_id) + { + m.lat = lat; + m.lng = lng; + m.alt = alt; + m.site_id = id; + strcpy (m.observer, observer); + } + + } + fclose (file); return; } diff --git a/src/satorbit.c b/src/satorbit.c index d5f1997..534028f 100644 --- a/src/satorbit.c +++ b/src/satorbit.c @@ -12,1732 +12,1946 @@ #define MMAX 28368 #define D2R M_PI/180.0 #define R2D 180.0/M_PI -#define XKMPER 6378.135 // Earth radius in km +#define XKMPER 6378.135 // Earth radius in km #define FLAT (1.0/298.257) -#define XKMPAU 149597879.691 // AU in km +#define XKMPAU 149597879.691 // AU in km -long Isat=0; -long Isatsel=0; +long Isat = 0; +long Isatsel = 0; extern double SGDP4_jd0; -struct coeff_lr { - int nd,nm,nm1,nf; - double sa,ca; +struct coeff_lr +{ + int nd, nm, nm1, nf; + double sa, ca; } clr[60]; -struct coeff_b { - int nd,nm,nm1,nf; +struct coeff_b +{ + int nd, nm, nm1, nf; double sa; } cb[60]; -struct map { +struct map +{ long satno; - double l0,b0,h0; - double lat,lng; + double l0, b0, h0; + double lat, lng; double mjd; - float alt,timezone; + float alt, timezone; int length; char orientation[LIM]; - char nfd[LIM],tlefile[LIM],observer[32]; - char datadir[LIM],tledir[LIM],notamfile[LIM],xyzfile[LIM]; - int site_id,notamflag,xyzflag,moonflag,launchsitesflag; + char nfd[LIM], tlefile[LIM], observer[32]; + char datadir[LIM], tledir[LIM], notamfile[LIM], xyzfile[LIM]; + int site_id, notamflag, xyzflag, moonflag, launchsitesflag; int plotfootprint; float w; } m; -struct globe { +struct globe +{ int n; - float l[MMAX],b[MMAX],x[MMAX],y[MMAX],z[MMAX]; + float l[MMAX], b[MMAX], x[MMAX], y[MMAX], z[MMAX]; } glb; -struct sat { +struct sat +{ long Isat; double jd; - double dx,dy,dz; - double x,y,z,vx,vy,vz; - double rsun,rearth; - double psun,pearth,p; - double r,ra,de; - double azi,alt; - double rx,ry; - double lng,lat; + double dx, dy, dz; + double x, y, z, vx, vy, vz; + double rsun, rearth; + double psun, pearth, p; + double r, ra, de; + double azi, alt; + double rx, ry; + double lng, lat; }; -void read_globe(void); -void plot_globe(void); -double nfd2mjd(char *date); -double date2mjd(int year,int month,double day); -void mjd2date(double mjd,char *date,int length); -void usage(); -void interactive_usage(); -void nfd_now(char *s); -void rotate(int axis,float angle,float *x,float *y,float *z); -void sunpos_xyz(double mjd,xyz_t *pos,double *ra,double *de); -void lunpos_xyz(double mjd,xyz_t *pos,double *ra,double *de); -double gmst(double); -double dgmst(double); -double modulo(double,double); -void get_site(int site_id); -void ecliptical2equatorial(double l,double b,double *ra,double *de); -void plot_launch_sites(void); -int fgetline(FILE *file,char *s,int lim); +void read_globe (void); +void plot_globe (void); +double nfd2mjd (char *date); +double date2mjd (int year, int month, double day); +void mjd2date (double mjd, char *date, int length); +void usage (); +void interactive_usage (); +void nfd_now (char *s); +void rotate (int axis, float angle, float *x, float *y, float *z); +void sunpos_xyz (double mjd, xyz_t * pos, double *ra, double *de); +void lunpos_xyz (double mjd, xyz_t * pos, double *ra, double *de); +double gmst (double); +double dgmst (double); +double modulo (double, double); +void get_site (int site_id); +void ecliptical2equatorial (double l, double b, double *ra, double *de); +void plot_launch_sites (void); +int fgetline (FILE * file, char *s, int lim); -int giza_open_device_size_float (const char *, const char *, float, float, int); -void giza_set_colour_palette (int palette) ; +int giza_open_device_size_float (const char *, const char *, float, float, + int); +void giza_set_colour_palette (int palette); // Initialize setup -void initialize_setup(void) +void +initialize_setup (void) { int i; FILE *file; - char *env,filename[128]; + char *env, filename[128]; // Default parameters - m.satno=0; - m.timezone=0.0; - m.length=60; - strcpy(m.orientation,"terrestial"); - nfd_now(m.nfd); - m.mjd=nfd2mjd(m.nfd); - m.w=1.2; - m.h0=gmst(m.mjd); - m.notamflag=0; - m.xyzflag=0; - m.moonflag=0; - m.launchsitesflag=0; - m.plotfootprint=1; + m.satno = 0; + m.timezone = 0.0; + m.length = 60; + strcpy (m.orientation, "terrestial"); + nfd_now (m.nfd); + m.mjd = nfd2mjd (m.nfd); + m.w = 1.2; + m.h0 = gmst (m.mjd); + m.notamflag = 0; + m.xyzflag = 0; + m.moonflag = 0; + m.launchsitesflag = 0; + m.plotfootprint = 1; // Default settings - strcpy(m.observer,"Unknown"); - m.site_id=0; + strcpy (m.observer, "Unknown"); + m.site_id = 0; // Get environment variables - env=getenv("ST_DATADIR"); - if (env!=NULL) { - strcpy(m.datadir,env); - } else { - printf("ST_DATADIR environment variable not found.\n"); - } - env=getenv("ST_COSPAR"); - if (env!=NULL) { - get_site(atoi(env)); - } else { - printf("ST_COSPAR environment variable not found.\n"); - } - env=getenv("ST_TLEDIR"); - if (env!=NULL) { - strcpy(m.tledir,env); - } else { - printf("ST_TLEDIR environment variable not found.\n"); - } + env = getenv ("ST_DATADIR"); + if (env != NULL) + { + strcpy (m.datadir, env); + } + else + { + printf ("ST_DATADIR environment variable not found.\n"); + } + env = getenv ("ST_COSPAR"); + if (env != NULL) + { + get_site (atoi (env)); + } + else + { + printf ("ST_COSPAR environment variable not found.\n"); + } + env = getenv ("ST_TLEDIR"); + if (env != NULL) + { + strcpy (m.tledir, env); + } + else + { + printf ("ST_TLEDIR environment variable not found.\n"); + } // sprintf(m.tlefile,"%s/classfd.tle",m.tledir); - strcpy(m.tlefile,""); + strcpy (m.tlefile, ""); // Read LR coefficients - sprintf(filename,"%s/data/moonLR.dat",m.datadir); - file=fopen(filename,"r"); - for (i=0;i<60;i++) - fscanf(file,"%d %d %d %d %lf %lf",&clr[i].nd,&clr[i].nm,&clr[i].nm1,&clr[i].nf,&clr[i].sa,&clr[i].ca); - fclose(file); + sprintf (filename, "%s/data/moonLR.dat", m.datadir); + file = fopen (filename, "r"); + for (i = 0; i < 60; i++) + fscanf (file, "%d %d %d %d %lf %lf", &clr[i].nd, &clr[i].nm, &clr[i].nm1, + &clr[i].nf, &clr[i].sa, &clr[i].ca); + fclose (file); // Read B coefficients - sprintf(filename,"%s/data/moonB.dat",m.datadir); - file=fopen(filename,"r"); - for (i=0;i<60;i++) - fscanf(file,"%d %d %d %d %lf",&cb[i].nd,&cb[i].nm,&cb[i].nm1,&cb[i].nf,&cb[i].sa); - fclose(file); + sprintf (filename, "%s/data/moonB.dat", m.datadir); + file = fopen (filename, "r"); + for (i = 0; i < 60; i++) + fscanf (file, "%d %d %d %d %lf", &cb[i].nd, &cb[i].nm, &cb[i].nm1, + &cb[i].nf, &cb[i].sa); + fclose (file); return; } // Convert ecliptical into equatorial coordinates -void ecliptical2equatorial(double l,double b,double *ra,double *de) +void +ecliptical2equatorial (double l, double b, double *ra, double *de) { - double eps=23.4392911; + double eps = 23.4392911; - *ra=modulo(atan2(sin(l*D2R)*cos(eps*D2R)-tan(b*D2R)*sin(eps*D2R),cos(l*D2R))*R2D,360.0); - *de=asin(sin(b*D2R)*cos(eps*D2R)+cos(b*D2R)*sin(eps*D2R)*sin(l*D2R))*R2D; + *ra = + modulo (atan2 + (sin (l * D2R) * cos (eps * D2R) - + tan (b * D2R) * sin (eps * D2R), cos (l * D2R)) * R2D, 360.0); + *de = + asin (sin (b * D2R) * cos (eps * D2R) + + cos (b * D2R) * sin (eps * D2R) * sin (l * D2R)) * R2D; return; } -void plot_footprint(struct sat s) +void +plot_footprint (struct sat s) { - int i,j,flag; - float range,alpha,dist,zz,theta,rr; - float x,y,z,x0,y0,z0,r0,r; + int i, j, flag; + float range, alpha, dist, zz, theta, rr; + float x, y, z, x0, y0, z0, r0, r; // Foot print size - range=sqrt(s.x*s.x+s.y*s.y+s.z*s.z); - dist=sqrt(range*range-XKMPER*XKMPER); - alpha=acos(XKMPER/range); - zz=range-dist*sin(alpha); - rr=sqrt(XKMPER*XKMPER-zz*zz); + range = sqrt (s.x * s.x + s.y * s.y + s.z * s.z); + dist = sqrt (range * range - XKMPER * XKMPER); + alpha = acos (XKMPER / range); + zz = range - dist * sin (alpha); + rr = sqrt (XKMPER * XKMPER - zz * zz); // Sub satellite point - z=cos(s.lng*D2R)*cos(s.lat*D2R)*XKMPER; - x=sin(s.lng*D2R)*cos(s.lat*D2R)*XKMPER; - y=sin(s.lat*D2R)*XKMPER; - rotate(1,m.l0,&x,&y,&z); - rotate(0,m.b0,&x,&y,&z); - r=sqrt(x*x+y*y); - z0=cos(s.lng*D2R)*cos(s.lat*D2R)*range; - x0=sin(s.lng*D2R)*cos(s.lat*D2R)*range; - y0=sin(s.lat*D2R)*range; - rotate(1,m.l0,&x0,&y0,&z0); - rotate(0,m.b0,&x0,&y0,&z0); - r0=sqrt(x0*x0+y0*y0); + z = cos (s.lng * D2R) * cos (s.lat * D2R) * XKMPER; + x = sin (s.lng * D2R) * cos (s.lat * D2R) * XKMPER; + y = sin (s.lat * D2R) * XKMPER; + rotate (1, m.l0, &x, &y, &z); + rotate (0, m.b0, &x, &y, &z); + r = sqrt (x * x + y * y); + z0 = cos (s.lng * D2R) * cos (s.lat * D2R) * range; + x0 = sin (s.lng * D2R) * cos (s.lat * D2R) * range; + y0 = sin (s.lat * D2R) * range; + rotate (1, m.l0, &x0, &y0, &z0); + rotate (0, m.b0, &x0, &y0, &z0); + r0 = sqrt (x0 * x0 + y0 * y0); - if (rXKMPER || (r00.0)) { - cpgmove(x0,y0); - cpgdraw(x,y); - cpgmove(x,y); - } - if (z>0.0) - cpgpt1(x,y,4); - - for (i=0,j=0,flag=0;i XKMPER || (r0 < XKMPER && z0 > 0.0)) + { + cpgmove (x0, y0); + cpgdraw (x, y); + cpgmove (x, y); + } + if (z > 0.0) + cpgpt1 (x, y, 4); + + for (i = 0, j = 0, flag = 0; i < NMAX; i++, j++) + { + theta = 2.0 * M_PI * (float) i / (float) (NMAX - 1); + + x = rr * sin (theta); + y = rr * cos (theta); + z = zz; + + rotate (0, -s.lat, &x, &y, &z); + rotate (1, -s.lng, &x, &y, &z); + rotate (1, m.l0, &x, &y, &z); + rotate (0, m.b0, &x, &y, &z); + + if (flag == 0) + cpgmove (x, y); + else + { + cpgdraw (x, y); + cpgmove (x, y); + } + if (z > 0.0) + flag = 1; + else + flag = 0; } - if (z>0.0) - flag=1; - else - flag=0; - } return; } // Computes apparent position -struct sat apparent_position(double mjd) +struct sat +apparent_position (double mjd) { struct sat s; - double jd,rsun,rearth; - double dx,dy,dz; - xyz_t satpos,obspos,satvel,sunpos; - double sra,sde; + double jd, rsun, rearth; + double dx, dy, dz; + xyz_t satpos, obspos, satvel, sunpos; + double sra, sde; // Sat ID - s.Isat=Isat; + s.Isat = Isat; // Get Julian Date - jd=mjd+2400000.5; + jd = mjd + 2400000.5; // Get positions - satpos_xyz(jd,&satpos,&satvel); - sunpos_xyz(mjd,&sunpos,&sra,&sde); + satpos_xyz (jd, &satpos, &satvel); + sunpos_xyz (mjd, &sunpos, &sra, &sde); // Sat positions - s.x=satpos.x; - s.y=satpos.y; - s.z=satpos.z; - s.vx=satvel.x; - s.vy=satvel.y; - s.vz=satvel.y; + s.x = satpos.x; + s.y = satpos.y; + s.z = satpos.z; + s.vx = satvel.x; + s.vy = satvel.y; + s.vz = satvel.y; // Sun position from satellite - dx=-satpos.x+sunpos.x; - dy=-satpos.y+sunpos.y; - dz=-satpos.z+sunpos.z; + dx = -satpos.x + sunpos.x; + dy = -satpos.y + sunpos.y; + dz = -satpos.z + sunpos.z; // Distances - rsun=sqrt(dx*dx+dy*dy+dz*dz); - rearth=sqrt(satpos.x*satpos.x+satpos.y*satpos.y+satpos.z*satpos.z); + rsun = sqrt (dx * dx + dy * dy + dz * dz); + rearth = + sqrt (satpos.x * satpos.x + satpos.y * satpos.y + satpos.z * satpos.z); // Angles - s.psun=asin(696.0e3/rsun)*R2D; - s.pearth=asin(6378.135/rearth)*R2D; - s.p=acos((-dx*satpos.x-dy*satpos.y-dz*satpos.z)/(rsun*rearth))*R2D; + s.psun = asin (696.0e3 / rsun) * R2D; + s.pearth = asin (6378.135 / rearth) * R2D; + s.p = + acos ((-dx * satpos.x - dy * satpos.y - + dz * satpos.z) / (rsun * rearth)) * R2D; // s.p=acos(((sunpos.x+satpos.x)*satpos.x+(sunpos.y+satpos.y)*satpos.y+(sunpos.z+satpos.z)*satpos.z)/(rsun*rearth))*R2D; - s.p-=s.pearth; + s.p -= s.pearth; // Celestial position - s.r=sqrt(satpos.x*satpos.x+satpos.y*satpos.y+satpos.z*satpos.z); - s.ra=atan2(satpos.y,satpos.x)*R2D; - s.de=asin(satpos.z/s.r)*R2D; + s.r = + sqrt (satpos.x * satpos.x + satpos.y * satpos.y + satpos.z * satpos.z); + s.ra = atan2 (satpos.y, satpos.x) * R2D; + s.de = asin (satpos.z / s.r) * R2D; // Latitude and longitude - s.lng=s.ra-gmst(m.mjd);; - s.lat=s.de; - + s.lng = s.ra - gmst (m.mjd);; + s.lat = s.de; + return s; } // plot satellite track -void plot_track(void) +void +plot_track (void) { - int i=0,nstep=500; + int i = 0, nstep = 500; orbit_t orb; - xyz_t pos,vel; - double jd,dt,h,mjd; - FILE *fp=NULL; - float x,y,z,r,v; + xyz_t pos, vel; + double jd, dt, h, mjd; + FILE *fp = NULL; + float x, y, z, r, v; long imode; int isci; float isch; char norad[7]; struct sat s; - float rmin,rmax; - float xmin,ymin,zmin,xmax,ymax,zmax; + float rmin, rmax; + float xmin, ymin, zmin, xmax, ymax, zmax; - if (strcmp(m.tlefile,"")==0) + if (strcmp (m.tlefile, "") == 0) return; - cpgqci(&isci); - cpgqch(&isch); - cpgsci(7); + cpgqci (&isci); + cpgqch (&isch); + cpgsci (7); - fp=fopen(m.tlefile,"rb"); - if (fp==NULL) { - fatal_error("File open failed for reading \"%s\"",m.tlefile); - } - - while (read_twoline(fp,m.satno,&orb) == 0) { - // print_orb(&orb); - - Isat=orb.satno; - imode=init_sgdp4(&orb); - - if(imode == SGDP4_ERROR) continue; - - jd=m.mjd+2400000.5; - h=gmst(m.mjd); - - for (i=0,dt=0.0;;i++) { - //if(satpos_xyz(jd, &pos, &vel) == SGDP4_ERROR) break; - mjd=jd-2400000.5; - s=apparent_position(mjd); - - x=s.x; - y=s.y; - z=s.z; - - rotate(0,-90.0,&x,&y,&z); - rotate(1,90.0,&x,&y,&z); - rotate(1,m.l0+h,&x,&y,&z); - rotate(0,m.b0,&x,&y,&z); - - // Visibility - if (s.p<-s.psun) - cpgsci(14); - else if (s.p>-s.psun && s.ps.psun) - cpgsci(7); - - // Find perigee and apogee - if (i==0) { - rmin=s.r; - rmax=s.r; - } else { - if (s.rrmax) { - rmax=s.r; - xmax=x; - ymax=y; - zmax=z; - } - } - - // Plot - if (i==0) { - if (m.plotfootprint==1) - plot_footprint(s); - if (!(sqrt(x*x+y*y)XKMPER) { - if (sqrt(x*x+y*y) -s.psun && s.p < s.psun) + cpgsci (15); + else if (s.p > s.psun) + cpgsci (7); + + // Find perigee and apogee + if (i == 0) + { + rmin = s.r; + rmax = s.r; + } + else + { + if (s.r < rmin) + { + rmin = s.r; + xmin = x; + ymin = y; + zmin = z; + } + if (s.r > rmax) + { + rmax = s.r; + xmax = x; + ymax = y; + zmax = z; + } + } + + // Plot + if (i == 0) + { + if (m.plotfootprint == 1) + plot_footprint (s); + if (!(sqrt (x * x + y * y) < XKMPER && z < 0.0)) + { + sprintf (norad, " %ld", Isat); + cpgsch (0.6); + cpgtext (x, y, norad); + cpgsch (isch); + cpgpt1 (x, y, 17); + } + cpgmove (x, y); + } + else if (s.r > XKMPER) + { + if (sqrt (x * x + y * y) < XKMPER && z < 0.0) + cpgmove (x, y); + else + cpgdraw (x, y); + cpgmove (x, y); + } + + // Do timestep + r = sqrt (s.x * s.x + s.y * s.y + s.z * s.z); + v = sqrt (s.vx * s.vx + s.vy * s.vy + s.vz * s.vz); + dt = 2.0 * M_PI * r / (0.75 * v * nstep); + jd += dt / 86400.0; + + if (i == nstep) + break; + } + if (!(sqrt (xmin * xmin + ymin * ymin) < XKMPER && zmin < 0.0)) + cpgpt1 (xmin, ymin, 4); + if (!(sqrt (xmax * xmax + ymax * ymax) < XKMPER && zmax < 0.0)) + cpgpt1 (xmax, ymax, 6); + } + cpgsls (1); + cpgsci (isci); + cpgsch (isch); return; } // plot satellite track -void plot_xyz(void) +void +plot_xyz (void) { - int i=0,nstep=500,flag=0; + int i = 0, nstep = 500, flag = 0; orbit_t orb; - xyz_t pos,vel; - double jd,dt,h,mjd,mjd0; - FILE *fp=NULL; - float x,y,z,r,v; + xyz_t pos, vel; + double jd, dt, h, mjd, mjd0; + FILE *fp = NULL; + float x, y, z, r, v; long imode; int isci; float isch; - char norad[7],line[LIM],nfd[32]; + char norad[7], line[LIM], nfd[32]; struct sat s; - double rsun,rearth; - double dx,dy,dz,sra,sde; - xyz_t sunpos,satpos; + double rsun, rearth; + double dx, dy, dz, sra, sde; + xyz_t sunpos, satpos; - cpgqci(&isci); - cpgqch(&isch); - cpgsci(8); + cpgqci (&isci); + cpgqch (&isch); + cpgsci (8); - fp=fopen(m.xyzfile,"rb"); - if (fp==NULL) { - fatal_error("File open failed for reading \"%s\"",m.xyzfile); - } - h=gmst(m.mjd); - - while (fgetline(fp,line,LIM)>0) { - // Get satellite position - if (line[10]=='T') { - sscanf(line,"%s %lf %lf %lf",nfd,&satpos.x,&satpos.y,&satpos.z); - mjd=nfd2mjd(nfd); - } else { - sscanf(line,"%lf %lf %lf %lf",&mjd,&satpos.x,&satpos.y,&satpos.z); + fp = fopen (m.xyzfile, "rb"); + if (fp == NULL) + { + fatal_error ("File open failed for reading \"%s\"", m.xyzfile); } + h = gmst (m.mjd); - // Mark point to plot - if (mjd>m.mjd && mjd0<=m.mjd && flag==0 && i>0) - flag=1; - - // Get positions - sunpos_xyz(m.mjd,&sunpos,&sra,&sde); - // Sun position from satellite - dx=-satpos.x+sunpos.x; - dy=-satpos.y+sunpos.y; - dz=-satpos.z+sunpos.z; - - // Distances - rsun=sqrt(dx*dx+dy*dy+dz*dz); - rearth=sqrt(satpos.x*satpos.x+satpos.y*satpos.y+satpos.z*satpos.z); - // Angles - s.psun=asin(696.0e3/rsun)*R2D; - s.pearth=asin(6378.135/rearth)*R2D; - s.p=acos((-dx*satpos.x-dy*satpos.y-dz*satpos.z)/(rsun*rearth))*R2D; - // s.p=acos(((sunpos.x+satpos.x)*satpos.x+(sunpos.y+satpos.y)*satpos.y+(sunpos.z+satpos.z)*satpos.z)/(rsun*rearth))*R2D; - - s.p-=s.pearth; - - // Celestial position - s.r=sqrt(satpos.x*satpos.x+satpos.y*satpos.y+satpos.z*satpos.z); - s.ra=atan2(satpos.y,satpos.x)*R2D; - s.de=asin(satpos.z/s.r)*R2D; - - // Latitude and longitude - s.lng=s.ra-gmst(m.mjd);; - s.lat=s.de; - - s.x=satpos.x; - s.y=satpos.y; - s.z=satpos.z; - - x=satpos.x; - y=satpos.y; - z=satpos.z; - - rotate(0,-90.0,&x,&y,&z); - rotate(1,90.0,&x,&y,&z); - rotate(1,m.l0+h,&x,&y,&z); - rotate(0,m.b0,&x,&y,&z); - - // Visibility - if (s.p<-s.psun) - cpgsci(14); - else if (s.p>-s.psun && s.ps.psun) - cpgsci(7); - - // Plot - if (flag==1) { - flag=2; - if (m.plotfootprint==1) - plot_footprint(s); - if (!(sqrt(x*x+y*y)XKMPER) { - if (sqrt(x*x+y*y) 0) + { + // Get satellite position + if (line[10] == 'T') + { + sscanf (line, "%s %lf %lf %lf", nfd, &satpos.x, &satpos.y, + &satpos.z); + mjd = nfd2mjd (nfd); + } else - cpgdraw(x,y); - cpgmove(x,y); + { + sscanf (line, "%lf %lf %lf %lf", &mjd, &satpos.x, &satpos.y, + &satpos.z); + } + + // Mark point to plot + if (mjd > m.mjd && mjd0 <= m.mjd && flag == 0 && i > 0) + flag = 1; + + // Get positions + sunpos_xyz (m.mjd, &sunpos, &sra, &sde); + // Sun position from satellite + dx = -satpos.x + sunpos.x; + dy = -satpos.y + sunpos.y; + dz = -satpos.z + sunpos.z; + + // Distances + rsun = sqrt (dx * dx + dy * dy + dz * dz); + rearth = + sqrt (satpos.x * satpos.x + satpos.y * satpos.y + + satpos.z * satpos.z); + // Angles + s.psun = asin (696.0e3 / rsun) * R2D; + s.pearth = asin (6378.135 / rearth) * R2D; + s.p = + acos ((-dx * satpos.x - dy * satpos.y - + dz * satpos.z) / (rsun * rearth)) * R2D; + // s.p=acos(((sunpos.x+satpos.x)*satpos.x+(sunpos.y+satpos.y)*satpos.y+(sunpos.z+satpos.z)*satpos.z)/(rsun*rearth))*R2D; + + s.p -= s.pearth; + + // Celestial position + s.r = + sqrt (satpos.x * satpos.x + satpos.y * satpos.y + + satpos.z * satpos.z); + s.ra = atan2 (satpos.y, satpos.x) * R2D; + s.de = asin (satpos.z / s.r) * R2D; + + // Latitude and longitude + s.lng = s.ra - gmst (m.mjd);; + s.lat = s.de; + + s.x = satpos.x; + s.y = satpos.y; + s.z = satpos.z; + + x = satpos.x; + y = satpos.y; + z = satpos.z; + + rotate (0, -90.0, &x, &y, &z); + rotate (1, 90.0, &x, &y, &z); + rotate (1, m.l0 + h, &x, &y, &z); + rotate (0, m.b0, &x, &y, &z); + + // Visibility + if (s.p < -s.psun) + cpgsci (14); + else if (s.p > -s.psun && s.p < s.psun) + cpgsci (15); + else if (s.p > s.psun) + cpgsci (7); + + // Plot + if (flag == 1) + { + flag = 2; + if (m.plotfootprint == 1) + plot_footprint (s); + if (!(sqrt (x * x + y * y) < XKMPER && z < 0.0)) + { + sprintf (norad, " xyz"); + cpgsch (0.6); + cpgtext (x, y, norad); + cpgsch (isch); + cpgpt1 (x, y, 17); + } + } + if (i == 0) + { + cpgmove (x, y); + i++; + } + else if (s.r > XKMPER) + { + if (sqrt (x * x + y * y) < XKMPER && z < 0.0) + cpgmove (x, y); + else + cpgdraw (x, y); + cpgmove (x, y); + } + mjd0 = mjd; } - mjd0=mjd; - } - cpgsls(1); - cpgsci(isci); - cpgsch(isch); + cpgsls (1); + cpgsci (isci); + cpgsch (isch); return; } -void read_globe(void) +void +read_globe (void) { - int i,status; + int i, status; FILE *file; - float l,b; + float l, b; char filename[LIM]; - sprintf(filename,"%s/data/globe.dat",m.datadir); - file=fopen(filename,"r"); + sprintf (filename, "%s/data/globe.dat", m.datadir); + file = fopen (filename, "r"); - for (i=0;i0.0) { - if (flag==0) { - cpgmove(x,y); - flag=1; - } else { - cpgdraw(x,y); - cpgmove(x,y); - } - } else { - flag=0; + rotate (1, m.l0, &x, &y, &z); + rotate (0, m.b0, &x, &y, &z); + + if (z > 0.0) + { + if (flag == 0) + { + cpgmove (x, y); + flag = 1; + } + else + { + cpgdraw (x, y); + cpgmove (x, y); + } + } + else + { + flag = 0; + } } - } return; } // plot grid -void plot_grid(void) +void +plot_grid (void) { - int i,j,flag; - float l,b; - float x,y,z; + int i, j, flag; + float l, b; + float x, y, z; - for (l=0.0;l<=360.0;l+=30.0) { - for (b=-90.0,flag=0;b<=90.0;b+=1.0) { - z=cos(l*D2R)*cos(b*D2R)*XKMPER; - x=sin(l*D2R)*cos(b*D2R)*XKMPER; - y=sin(b*D2R)*XKMPER; - - rotate(1,m.l0,&x,&y,&z); - rotate(0,m.b0,&x,&y,&z); + for (l = 0.0; l <= 360.0; l += 30.0) + { + for (b = -90.0, flag = 0; b <= 90.0; b += 1.0) + { + z = cos (l * D2R) * cos (b * D2R) * XKMPER; + x = sin (l * D2R) * cos (b * D2R) * XKMPER; + y = sin (b * D2R) * XKMPER; - if (flag==0) - cpgmove(x,y); - else { - cpgdraw(x,y); - cpgmove(x,y); - } - if (z>0.0) - flag=1; - else - flag=0; + rotate (1, m.l0, &x, &y, &z); + rotate (0, m.b0, &x, &y, &z); + + if (flag == 0) + cpgmove (x, y); + else + { + cpgdraw (x, y); + cpgmove (x, y); + } + if (z > 0.0) + flag = 1; + else + flag = 0; + } } - } - for (b=-90.0;b<=90.0;b+=30.0) { - for (l=0.0,flag=0;l<=360.0;l+=1.0) { - z=cos(l*D2R)*cos(b*D2R)*XKMPER; - x=sin(l*D2R)*cos(b*D2R)*XKMPER; - y=sin(b*D2R)*XKMPER; - - rotate(1,m.l0,&x,&y,&z); - rotate(0,m.b0,&x,&y,&z); + for (b = -90.0; b <= 90.0; b += 30.0) + { + for (l = 0.0, flag = 0; l <= 360.0; l += 1.0) + { + z = cos (l * D2R) * cos (b * D2R) * XKMPER; + x = sin (l * D2R) * cos (b * D2R) * XKMPER; + y = sin (b * D2R) * XKMPER; - if (flag==0) - cpgmove(x,y); - else { - cpgdraw(x,y); - cpgmove(x,y); - } - if (z>0.0) - flag=1; - else - flag=0; + rotate (1, m.l0, &x, &y, &z); + rotate (0, m.b0, &x, &y, &z); + + if (flag == 0) + cpgmove (x, y); + else + { + cpgdraw (x, y); + cpgmove (x, y); + } + if (z > 0.0) + flag = 1; + else + flag = 0; + } } - } return; } // Plot terminator -void plot_moon(void) +void +plot_moon (void) { xyz_t s; - float r,h; - float l,b,l0,b0; - float x0,y0,z0,x,y,z; - double lra,lde,dmjd; + float r, h; + float l, b, l0, b0; + float x0, y0, z0, x, y, z; + double lra, lde, dmjd; int isci; char text[8]; - cpgqci(&isci); - cpgsci(3); + cpgqci (&isci); + cpgsci (3); // Get positions - lunpos_xyz(m.mjd,&s,&lra,&lde); + lunpos_xyz (m.mjd, &s, &lra, &lde); // GMST - h=gmst(m.mjd); + h = gmst (m.mjd); // Lunar subpoint - l0=modulo(lra-h,360.0); - b0=lde; - if (l0>180.0) - l0-=360.0; + l0 = modulo (lra - h, 360.0); + b0 = lde; + if (l0 > 180.0) + l0 -= 360.0; // Convert - z0=cos(l0*D2R)*cos(b0*D2R)*XKMPER; - x0=sin(l0*D2R)*cos(b0*D2R)*XKMPER; - y0=sin(b0*D2R)*XKMPER; + z0 = cos (l0 * D2R) * cos (b0 * D2R) * XKMPER; + x0 = sin (l0 * D2R) * cos (b0 * D2R) * XKMPER; + y0 = sin (b0 * D2R) * XKMPER; - rotate(1,m.l0,&x0,&y0,&z0); - rotate(0,m.b0,&x0,&y0,&z0); + rotate (1, m.l0, &x0, &y0, &z0); + rotate (0, m.b0, &x0, &y0, &z0); // Plot sub lunar point - if (z0>0.0) - cpgpt1(x0,y0,17); + if (z0 > 0.0) + cpgpt1 (x0, y0, 17); // Lunar antipode - l0=modulo(lra-h-180,360.0); - b0=-lde; - if (l0>180.0) - l0-=360.0; + l0 = modulo (lra - h - 180, 360.0); + b0 = -lde; + if (l0 > 180.0) + l0 -= 360.0; // Convert - z0=cos(l0*D2R)*cos(b0*D2R)*XKMPER; - x0=sin(l0*D2R)*cos(b0*D2R)*XKMPER; - y0=sin(b0*D2R)*XKMPER; + z0 = cos (l0 * D2R) * cos (b0 * D2R) * XKMPER; + x0 = sin (l0 * D2R) * cos (b0 * D2R) * XKMPER; + y0 = sin (b0 * D2R) * XKMPER; - rotate(1,m.l0,&x0,&y0,&z0); - rotate(0,m.b0,&x0,&y0,&z0); + rotate (1, m.l0, &x0, &y0, &z0); + rotate (0, m.b0, &x0, &y0, &z0); // Plot antipode - if (z0>0.0) - cpgpt1(x0,y0,6); + if (z0 > 0.0) + cpgpt1 (x0, y0, 6); // Plot moon - z=s.z; - x=s.x; - y=s.y; + z = s.z; + x = s.x; + y = s.y; - rotate(0,-90.0,&x,&y,&z); - rotate(1,90.0,&x,&y,&z); - rotate(1,m.l0+h,&x,&y,&z); - rotate(0,m.b0,&x,&y,&z); + rotate (0, -90.0, &x, &y, &z); + rotate (1, 90.0, &x, &y, &z); + rotate (1, m.l0 + h, &x, &y, &z); + rotate (0, m.b0, &x, &y, &z); - cpgcirc(x,y,1737.5); + cpgcirc (x, y, 1737.5); // Plot antipode travel - for (dmjd=1.0;dmjd<7.0;dmjd+=1.0) { - // Get positions - lunpos_xyz(m.mjd+dmjd,&s,&lra,&lde); + for (dmjd = 1.0; dmjd < 7.0; dmjd += 1.0) + { + // Get positions + lunpos_xyz (m.mjd + dmjd, &s, &lra, &lde); - // GMST - h=gmst(m.mjd); + // GMST + h = gmst (m.mjd); - // Lunar antipode - l0=modulo(lra-h-180,360.0); - b0=-lde; - if (l0>180.0) - l0-=360.0; + // Lunar antipode + l0 = modulo (lra - h - 180, 360.0); + b0 = -lde; + if (l0 > 180.0) + l0 -= 360.0; - // Convert - z0=cos(l0*D2R)*cos(b0*D2R)*XKMPER; - x0=sin(l0*D2R)*cos(b0*D2R)*XKMPER; - y0=sin(b0*D2R)*XKMPER; - - rotate(1,m.l0,&x0,&y0,&z0); - rotate(0,m.b0,&x0,&y0,&z0); - - // Plot antipode - if (z0>0.0) { - sprintf(text," %.0f",dmjd); - cpgpt1(x0,y0,2); - cpgtext(x0,y0,text); + // Convert + z0 = cos (l0 * D2R) * cos (b0 * D2R) * XKMPER; + x0 = sin (l0 * D2R) * cos (b0 * D2R) * XKMPER; + y0 = sin (b0 * D2R) * XKMPER; + + rotate (1, m.l0, &x0, &y0, &z0); + rotate (0, m.b0, &x0, &y0, &z0); + + // Plot antipode + if (z0 > 0.0) + { + sprintf (text, " %.0f", dmjd); + cpgpt1 (x0, y0, 2); + cpgtext (x0, y0, text); + } } - } - for (dmjd=-6.0;dmjd<0.0;dmjd+=1.0) { - // Get positions - lunpos_xyz(m.mjd+dmjd,&s,&lra,&lde); + for (dmjd = -6.0; dmjd < 0.0; dmjd += 1.0) + { + // Get positions + lunpos_xyz (m.mjd + dmjd, &s, &lra, &lde); - // GMST - h=gmst(m.mjd); + // GMST + h = gmst (m.mjd); - // Lunar antipode - l0=modulo(lra-h-180,360.0); - b0=-lde; - if (l0>180.0) - l0-=360.0; + // Lunar antipode + l0 = modulo (lra - h - 180, 360.0); + b0 = -lde; + if (l0 > 180.0) + l0 -= 360.0; - // Convert - z0=cos(l0*D2R)*cos(b0*D2R)*XKMPER; - x0=sin(l0*D2R)*cos(b0*D2R)*XKMPER; - y0=sin(b0*D2R)*XKMPER; - - rotate(1,m.l0,&x0,&y0,&z0); - rotate(0,m.b0,&x0,&y0,&z0); - - // Plot antipode - if (z0>0.0) { - sprintf(text," %.0f",dmjd); - cpgpt1(x0,y0,2); - cpgtext(x0,y0,text); + // Convert + z0 = cos (l0 * D2R) * cos (b0 * D2R) * XKMPER; + x0 = sin (l0 * D2R) * cos (b0 * D2R) * XKMPER; + y0 = sin (b0 * D2R) * XKMPER; + + rotate (1, m.l0, &x0, &y0, &z0); + rotate (0, m.b0, &x0, &y0, &z0); + + // Plot antipode + if (z0 > 0.0) + { + sprintf (text, " %.0f", dmjd); + cpgpt1 (x0, y0, 2); + cpgtext (x0, y0, text); + } } - } - cpgsci(isci); + cpgsci (isci); return; } // Plot terminator -void plot_terminator(void) +void +plot_terminator (void) { - int i,j,k,flag,j1,j2; + int i, j, k, flag, j1, j2; double jd; xyz_t s; - float r,h; - float l,b,l0,b0; - float x0,y0,z0; - float x,y,z,t0,t1,t2,t; - float xx[NMAX],yy[NMAX],zz[NMAX]; - float xt[NMAX],yt[NMAX],zt[NMAX]; + float r, h; + float l, b, l0, b0; + float x0, y0, z0; + float x, y, z, t0, t1, t2, t; + float xx[NMAX], yy[NMAX], zz[NMAX]; + float xt[NMAX], yt[NMAX], zt[NMAX]; int isci; - double sra,sde; + double sra, sde; float theta; - float ang[]={0.0,-6.0,-12.0,-18.0}; + float ang[] = { 0.0, -6.0, -12.0, -18.0 }; - cpgqci(&isci); + cpgqci (&isci); // Get positions - sunpos_xyz(m.mjd,&s,&sra,&sde); + sunpos_xyz (m.mjd, &s, &sra, &sde); // GMST - h=gmst(m.mjd); + h = gmst (m.mjd); // Solar subpoint - l0=modulo(sra-h,360.0); - b0=sde; - if (l0>180.0) - l0-=360.0; + l0 = modulo (sra - h, 360.0); + b0 = sde; + if (l0 > 180.0) + l0 -= 360.0; // Convert - z0=cos(l0*D2R)*cos(b0*D2R)*XKMPER; - x0=sin(l0*D2R)*cos(b0*D2R)*XKMPER; - y0=sin(b0*D2R)*XKMPER; + z0 = cos (l0 * D2R) * cos (b0 * D2R) * XKMPER; + x0 = sin (l0 * D2R) * cos (b0 * D2R) * XKMPER; + y0 = sin (b0 * D2R) * XKMPER; - rotate(1,m.l0,&x0,&y0,&z0); - rotate(0,m.b0,&x0,&y0,&z0); + rotate (1, m.l0, &x0, &y0, &z0); + rotate (0, m.b0, &x0, &y0, &z0); - t0=atan2(y0,x0)*R2D; + t0 = atan2 (y0, x0) * R2D; // Loop over terminator boundaries - for (i=0,j=0,flag=0;i0 && zz[i]*zz[i-1]<0.0) { - if (zz[i]>0.0 && zz[i-1]<0.0) { - t1=atan2(yy[i],xx[i])*R2D; - j1=i; - } else { - t2=atan2(yy[i],xx[i])*R2D; - j2=i; - } + for (i = 0, j = 0, flag = 0; i < NMAX; i++, j++) + { + theta = 2.0 * M_PI * (float) i / (float) (NMAX - 1); + + x = XKMPER * sin (theta); + y = XKMPER * cos (theta); + z = 0.0; + + rotate (0, -b0, &x, &y, &z); + rotate (1, -l0, &x, &y, &z); + rotate (1, m.l0, &x, &y, &z); + rotate (0, m.b0, &x, &y, &z); + xx[i] = x; + yy[i] = y; + zz[i] = z; + } + for (i = 0, j = 0; i < NMAX; i++) + { + if (i > 0 && zz[i] * zz[i - 1] < 0.0) + { + if (zz[i] > 0.0 && zz[i - 1] < 0.0) + { + t1 = atan2 (yy[i], xx[i]) * R2D; + j1 = i; + } + else + { + t2 = atan2 (yy[i], xx[i]) * R2D; + j2 = i; + } + } } - } // angles - t0=modulo(t0,360); - t1=modulo(t1,360); - t2=modulo(t2,360); - if (t1512) + t0 = modulo (t0, 360); + t1 = modulo (t1, 360); + t2 = modulo (t2, 360); + if (t1 < t2) + t1 += 360.0; + if (abs (j2 - j1) > 512) j2++; - if (abs(j2-j1)<512) + if (abs (j2 - j1) < 512) j2--; - if (j1>j2) { - for (i=0,j=0;i j2) + { + for (i = 0, j = 0; i < j2; i++, j++) + { + xt[j] = xx[i]; + yt[j] = yy[i]; + } + for (i = 0; i < NMAX - abs (j2 - j1); i++, j++) + { + t = t2 - (t2 - t1) * (float) i / (float) (NMAX - abs (j2 - j1)); + + xt[j] = XKMPER * cos (t * D2R); + yt[j] = XKMPER * sin (t * D2R); + } + for (i = j1; i < NMAX; i++, j++) + { + xt[j] = xx[i]; + yt[j] = yy[i]; + } } - for (i=0;i0.0) { - cpgsci(7); - cpgpt1(x0,y0,17); - } + if (z0 > 0.0) + { + cpgsci (7); + cpgpt1 (x0, y0, 17); + } // Loop over terminator boundaries - for (k=0;k<4;k++) { - if (k==0) - cpgsci(2); - else - cpgsci(4); - for (i=0,j=0,flag=0;i0.0) - flag=1; + for (k = 0; k < 4; k++) + { + if (k == 0) + cpgsci (2); else - flag=0; + cpgsci (4); + for (i = 0, j = 0, flag = 0; i < NMAX; i++, j++) + { + theta = 2.0 * M_PI * (float) i / (float) (NMAX - 1); + + x = XKMPER * sin (theta) * cos (ang[k] * D2R); + y = XKMPER * cos (theta) * cos (ang[k] * D2R); + z = XKMPER * sin (ang[k] * D2R); + + rotate (0, -b0, &x, &y, &z); + rotate (1, -l0, &x, &y, &z); + rotate (1, m.l0, &x, &y, &z); + rotate (0, m.b0, &x, &y, &z); + + if (flag == 0) + cpgmove (x, y); + else + { + cpgdraw (x, y); + cpgmove (x, y); + } + if (z > 0.0) + flag = 1; + else + flag = 0; + } } - } - cpgsci(isci); + cpgsci (isci); return; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; + int c, i = 0; - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\t') - c=' '; + c = ' '; if (c == '\n') s[i++] = c; s[i] = '\0'; return i; } -void plot_notam(char *filename) +void +plot_notam (char *filename) { - int i,flag=0; - float x,y,z; - float l,b,r; + int i, flag = 0; + float x, y, z; + float l, b, r; char line[LIM]; FILE *file; - file=fopen(filename,"r"); - while (fgetline(file,line,LIM)>0) { - r=0.0; - sscanf(line,"%f %f %f",&b,&l,&r); - if (strlen(line)<2) { - flag=0; - continue; - } + file = fopen (filename, "r"); + while (fgetline (file, line, LIM) > 0) + { + r = 0.0; + sscanf (line, "%f %f %f", &b, &l, &r); + if (strlen (line) < 2) + { + flag = 0; + continue; + } - z=cos(l*D2R)*cos(b*D2R)*XKMPER; - x=sin(l*D2R)*cos(b*D2R)*XKMPER; - y=sin(b*D2R)*XKMPER; + z = cos (l * D2R) * cos (b * D2R) * XKMPER; + x = sin (l * D2R) * cos (b * D2R) * XKMPER; + y = sin (b * D2R) * XKMPER; - rotate(1,m.l0,&x,&y,&z); - rotate(0,m.b0,&x,&y,&z); - - if (z>0.0) { - if (flag==0) { - cpgmove(x,y); - flag=1; - } else { - cpgdraw(x,y); - cpgmove(x,y); - } - } else { - flag=0; + rotate (1, m.l0, &x, &y, &z); + rotate (0, m.b0, &x, &y, &z); + + if (z > 0.0) + { + if (flag == 0) + { + cpgmove (x, y); + flag = 1; + } + else + { + cpgdraw (x, y); + cpgmove (x, y); + } + } + else + { + flag = 0; + } } - } return; } -void plot_map(int plotflag) +void +plot_map (int plotflag) { - int redraw=1,status; + int redraw = 1, status; char text[256]; - float x,y,z; + float x, y, z; char c; - for (;;) { - if (redraw>0) { - // Get present mjd - if (m.mjd<0.0) { - nfd_now(m.nfd); - m.mjd=nfd2mjd(m.nfd); - m.h0=gmst(m.mjd); - } + for (;;) + { + if (redraw > 0) + { + // Get present mjd + if (m.mjd < 0.0) + { + nfd_now (m.nfd); + m.mjd = nfd2mjd (m.nfd); + m.h0 = gmst (m.mjd); + } - // Update position - if (strcmp(m.orientation,"terrestial")==0) { - m.l0=m.lng; - m.b0=m.lat; - } else if (strcmp(m.orientation,"sidereal")==0) { - m.l0=m.lng-gmst(m.mjd)+m.h0; - m.b0=m.lat; - } + // Update position + if (strcmp (m.orientation, "terrestial") == 0) + { + m.l0 = m.lng; + m.b0 = m.lat; + } + else if (strcmp (m.orientation, "sidereal") == 0) + { + m.l0 = m.lng - gmst (m.mjd) + m.h0; + m.b0 = m.lat; + } - cpgscr(0,0.0,0.0,0.0); - cpgeras(); + cpgscr (0, 0.0, 0.0, 0.0); + cpgeras (); - // Create window - cpgsvp(0.05,0.95,0.05,0.95); - cpgwnad(-m.w*XKMPER,m.w*XKMPER,-m.w*XKMPER,m.w*XKMPER); + // Create window + cpgsvp (0.05, 0.95, 0.05, 0.95); + cpgwnad (-m.w * XKMPER, m.w * XKMPER, -m.w * XKMPER, m.w * XKMPER); - // Set background - cpgscr(0,0.0,0.0,0.5); - cpgsci(0); - cpgwnad(-m.w*XKMPER,m.w*XKMPER,-m.w*XKMPER,m.w*XKMPER); - cpgsci(1); - cpgscr(0,0.0,0.0,0.0); + // Set background + cpgscr (0, 0.0, 0.0, 0.5); + cpgsci (0); + cpgwnad (-m.w * XKMPER, m.w * XKMPER, -m.w * XKMPER, m.w * XKMPER); + cpgsci (1); + cpgscr (0, 0.0, 0.0, 0.0); - // Top left string - cpgsch(0.8); - mjd2date(m.mjd,m.nfd,0); - sprintf(text,"%s UTC",m.nfd); - cpgmtxt("T",0.6,0.0,0.0,text); + // Top left string + cpgsch (0.8); + mjd2date (m.mjd, m.nfd, 0); + sprintf (text, "%s UTC", m.nfd); + cpgmtxt ("T", 0.6, 0.0, 0.0, text); - // Bottom string - sprintf(text,"l: %d s",m.length); - cpgmtxt("B",1.0,0.0,0.0,text); - cpgsch(1.0); + // Bottom string + sprintf (text, "l: %d s", m.length); + cpgmtxt ("B", 1.0, 0.0, 0.0, text); + cpgsch (1.0); - // Plot terminator - plot_terminator(); + // Plot terminator + plot_terminator (); - // Plot Grid - cpgsls(2); - cpgsci(14); - plot_grid(); - cpgsls(1); - cpgsci(1); + // Plot Grid + cpgsls (2); + cpgsci (14); + plot_grid (); + cpgsls (1); + cpgsci (1); - // Plot globe - plot_globe(); - cpgsfs(2); - cpgcirc(0.0,0.0,XKMPER); - cpgpt1(0.0,0.0,2); - cpgsci(1); - cpgbox("BC",0.,0,"BC",0.,0); + // Plot globe + plot_globe (); + cpgsfs (2); + cpgcirc (0.0, 0.0, XKMPER); + cpgpt1 (0.0, 0.0, 2); + cpgsci (1); + cpgbox ("BC", 0., 0, "BC", 0., 0); - // Plot notam - if (m.notamflag==1) { - cpgsci(3); - plot_notam(m.notamfile); - cpgsci(1); - } + // Plot notam + if (m.notamflag == 1) + { + cpgsci (3); + plot_notam (m.notamfile); + cpgsci (1); + } - // Plot moon - if (m.moonflag==1) - plot_moon(); + // Plot moon + if (m.moonflag == 1) + plot_moon (); - // Plot launch sites - if (m.launchsitesflag==1) - plot_launch_sites(); + // Plot launch sites + if (m.launchsitesflag == 1) + plot_launch_sites (); - // Plot track - if (m.xyzflag==1) - plot_xyz(); - else - plot_track(); + // Plot track + if (m.xyzflag == 1) + plot_xyz (); + else + plot_track (); + } + + // Reset redraw + redraw = 0; + + if (plotflag == 1) + { + cpgend (); + exit (0); + } + + // Get cursor + cpgcurs (&x, &y, &c); + + // Help + if (c == 'h') + { + interactive_usage (); + + continue; + } + + // Redraw + if (c == 'r') + { + m.mjd = -1.0; + m.length = 60; + redraw = 1; + } + + // Footprint toggle + if (c == 'f') + { + if (m.plotfootprint == 1) + m.plotfootprint = 0; + else + m.plotfootprint = 1; + redraw = 1; + } + + // Moon toggle + if (c == 'm') + { + if (m.moonflag == 1) + m.moonflag = 0; + else + m.moonflag = 1; + redraw = 1; + } + + // Launchsites toggle + if (c == 'L') + { + if (m.launchsitesflag == 1) + m.launchsitesflag = 0; + else + m.launchsitesflag = 1; + redraw = 1; + } + + // Orientation + if (c == 'o') + { + if (strcmp (m.orientation, "terrestial") == 0) + strcpy (m.orientation, "sidereal"); + else if (strcmp (m.orientation, "sidereal") == 0) + strcpy (m.orientation, "terrestial"); + redraw = 1; + } + + // Recenter + if (sqrt (x * x + y * y) < XKMPER && c == 'c') + { + z = sqrt (XKMPER * XKMPER - x * x - y * y); + rotate (0, -m.lat, &x, &y, &z); + rotate (1, -m.l0, &x, &y, &z); + rotate (1, -90.0, &x, &y, &z); + rotate (0, 90.0, &x, &y, &z); + + m.lng = atan2 (y, x) * R2D; + m.lat = asin (z / XKMPER) * R2D; + printf ("%8.3f %8.3f\n", m.lng, m.lat); + m.l0 = m.lng; + m.b0 = m.lat; + redraw = 1; + } + + // Zoom + if (c == '-') + { + m.w *= 1.2; + redraw = 1; + } + if (c == '+' || c == '=') + { + m.w /= 1.2; + redraw = 1; + } + + // Pan + if (c == '{') + { + m.lat -= 2.0; + redraw = 1; + } + if (c == '}') + { + m.lat += 2.0; + redraw = 1; + } + if (c == '[') + { + m.lng -= 2.0; + redraw = 1; + } + if (c == ']') + { + m.lng += 2.0; + redraw = 1; + } + + if (c == '>') + { + m.length *= 2.0; + redraw = 1; + } + if (c == '<') + { + m.length /= 2.0; + redraw = 1; + } + if (c == ',') + { + m.mjd -= m.length / 86400.0; + redraw = 1; + } + if (c == '.') + { + m.mjd += m.length / 86400.0; + redraw = 1; + } + + // Integration length + if (c == 'l') + { + printf ("Enter integration length (s): "); + status = scanf ("%d", &m.length); + redraw = 1; + } + + // Exit + if (c == 'q' || c == 'Q') + { + cpgend (); + exit (0); + } } - - // Reset redraw - redraw=0; - - if (plotflag==1) { - cpgend(); - exit(0); - } - - // Get cursor - cpgcurs(&x,&y,&c); - - // Help - if (c=='h') { - interactive_usage(); - - continue; - } - - // Redraw - if (c=='r') { - m.mjd=-1.0; - m.length=60; - redraw=1; - } - - // Footprint toggle - if (c=='f') { - if (m.plotfootprint==1) - m.plotfootprint=0; - else - m.plotfootprint=1; - redraw=1; - } - - // Moon toggle - if (c=='m') { - if (m.moonflag==1) - m.moonflag=0; - else - m.moonflag=1; - redraw=1; - } - - // Launchsites toggle - if (c=='L') { - if (m.launchsitesflag==1) - m.launchsitesflag=0; - else - m.launchsitesflag=1; - redraw=1; - } - - // Orientation - if (c=='o') { - if (strcmp(m.orientation,"terrestial")==0) - strcpy(m.orientation,"sidereal"); - else if (strcmp(m.orientation,"sidereal")==0) - strcpy(m.orientation,"terrestial"); - redraw=1; - } - - // Recenter - if (sqrt(x*x+y*y)') { - m.length*=2.0; - redraw=1; - } - if (c=='<') { - m.length/=2.0; - redraw=1; - } - if (c==',') { - m.mjd-=m.length/86400.0; - redraw=1; - } - if (c=='.') { - m.mjd+=m.length/86400.0; - redraw=1; - } - - // Integration length - if (c=='l') { - printf("Enter integration length (s): "); - status=scanf("%d",&m.length); - redraw=1; - } - - // Exit - if (c=='q' || c=='Q') { - cpgend(); - exit(0); - } - } return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int arg=0,plotflag=0; - char plottype[128]="/xs"; + int arg = 0, plotflag = 0; + char plottype[128] = "/xs"; // Initialize setup - initialize_setup(); + initialize_setup (); // Decode options - while ((arg=getopt(argc,argv,"t:c:i:s:l:hN:p:mL:B:R:Sqg:"))!=-1) { - switch (arg) { + while ((arg = getopt (argc, argv, "t:c:i:s:l:hN:p:mL:B:R:Sqg:")) != -1) + { + switch (arg) + { - case 'g': - strcpy(plottype,optarg); - plotflag=1; - break; - - case 't': - strcpy(m.nfd,optarg); - m.mjd=nfd2mjd(m.nfd); - break; + case 'g': + strcpy (plottype, optarg); + plotflag = 1; + break; - case 'c': - strcpy(m.tlefile,optarg); - break; + case 't': + strcpy (m.nfd, optarg); + m.mjd = nfd2mjd (m.nfd); + break; - case 's': - get_site(atoi(optarg)); - break; + case 'c': + strcpy (m.tlefile, optarg); + break; - case 'i': - m.satno=atoi(optarg); - break; + case 's': + get_site (atoi (optarg)); + break; - case 'q': - m.launchsitesflag=1; - break; + case 'i': + m.satno = atoi (optarg); + break; - case 'l': - m.length=atoi(optarg); - break; + case 'q': + m.launchsitesflag = 1; + break; - case 'N': - strcpy(m.notamfile,optarg); - m.notamflag=1; - break; + case 'l': + m.length = atoi (optarg); + break; - case 'L': - m.lng=atof(optarg); - break; + case 'N': + strcpy (m.notamfile, optarg); + m.notamflag = 1; + break; - case 'B': - m.lat=atof(optarg); - break; + case 'L': + m.lng = atof (optarg); + break; - case 'R': - m.w=atof(optarg); - break; + case 'B': + m.lat = atof (optarg); + break; - case 'S': - strcpy(m.orientation,"sidereal"); - break; + case 'R': + m.w = atof (optarg); + break; - case 'p': - strcpy(m.xyzfile,optarg); - m.xyzflag=1; - break; + case 'S': + strcpy (m.orientation, "sidereal"); + break; - case 'm': - m.moonflag=1; - break; + case 'p': + strcpy (m.xyzfile, optarg); + m.xyzflag = 1; + break; - case 'h': - usage(); - return 0; - break; + case 'm': + m.moonflag = 1; + break; - default: - usage(); - return 0; + case 'h': + usage (); + return 0; + break; + + default: + usage (); + return 0; + } } - } - read_globe(); + read_globe (); - giza_open_device_size_float("/xs", "satorbit", 1920, 1020, 3); - giza_set_colour_palette(1); + giza_open_device_size_float ("/xs", "satorbit", 1920, 1020, 3); + giza_set_colour_palette (1); - plot_map(plotflag); + plot_map (plotflag); - cpgend(); + cpgend (); return 0; } // Present nfd -void nfd_now(char *s) +void +nfd_now (char *s) { time_t rawtime; struct tm *ptm; // Get UTC time - time(&rawtime); - ptm=gmtime(&rawtime); - - sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec); - + time (&rawtime); + ptm = gmtime (&rawtime); + + sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900, + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, + ptm->tm_sec); + return; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min,sec; - double mjd,dday; + int year, month, day, hour, min, sec; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; - mjd=date2mjd(year,month,dday); + mjd = date2mjd (year, month, dday); return mjd; } -void usage() +void +usage () { - printf("usage: satorbit -c TLEFILE [-g DEVICE] [-t TIMESTAMP] [-s COSPARID] [-i SATNO]\n"); - printf(" [-q] [-p XYZFILE] [-m] [-N NOTAMFILE] [-l LENGTH]\n"); - printf(" [-L LNG] [-B LAT] [-R ZOOMSIZE] [-S ORIENTATION] [-h]\n\n"); + printf + ("usage: satorbit -c TLEFILE [-g DEVICE] [-t TIMESTAMP] [-s COSPARID] [-i SATNO]\n"); + printf + (" [-q] [-p XYZFILE] [-m] [-N NOTAMFILE] [-l LENGTH]\n"); + printf + (" [-L LNG] [-B LAT] [-R ZOOMSIZE] [-S ORIENTATION] [-h]\n\n"); - printf("-c TLEFILE The file containing orbital elements in the form of TLEs, 3 lines per object\n"); - printf("-g DEVICE PGPlot device (default: \"/xs\" --> interactive).\n"); - printf(" If set exit the program when everything was drawn.\n"); - printf(" default: stay in interactive mode\n"); - printf("-t TIMESTAMP Timestamp of the map, formatted as YYYY-mm-ddTHH:MM:SS, default: now\n"); - printf("-s COSPARID observation site, COSPAR ID of the observation site on which the map is centered optionally\n"); - printf("-i SATNO satno of the selected satellite, default: 0 (all satellites in the TLE file)\n"); - printf("-q launchsitesflag: If value=1 plot the launch sites as well, default: 0\n"); - printf("-p XYZFILE If given, plot xyz instead of track\n"); - printf("-m moonflag: If value=1 plot the moon as well\n"); - printf("-N NOTAMFILE If given, plot the NOTAM as well\n"); - printf("-l LENGTH Integration length in seconds, default: 60\n"); - printf("-L LNG map longitude\n"); - printf("-B LAT map latitude\n"); - printf("-R ZOOMSIZE Initial window size in earth radii, default: 1.2\n"); - printf("-S ORIENTATION map orientation: sidereal, default: terrestial\n"); - printf("-h Print usage\n"); + printf + ("-c TLEFILE The file containing orbital elements in the form of TLEs, 3 lines per object\n"); + printf + ("-g DEVICE PGPlot device (default: \"/xs\" --> interactive).\n"); + printf + (" If set exit the program when everything was drawn.\n"); + printf (" default: stay in interactive mode\n"); + printf + ("-t TIMESTAMP Timestamp of the map, formatted as YYYY-mm-ddTHH:MM:SS, default: now\n"); + printf + ("-s COSPARID observation site, COSPAR ID of the observation site on which the map is centered optionally\n"); + printf + ("-i SATNO satno of the selected satellite, default: 0 (all satellites in the TLE file)\n"); + printf + ("-q launchsitesflag: If value=1 plot the launch sites as well, default: 0\n"); + printf ("-p XYZFILE If given, plot xyz instead of track\n"); + printf ("-m moonflag: If value=1 plot the moon as well\n"); + printf ("-N NOTAMFILE If given, plot the NOTAM as well\n"); + printf ("-l LENGTH Integration length in seconds, default: 60\n"); + printf ("-L LNG map longitude\n"); + printf ("-B LAT map latitude\n"); + printf + ("-R ZOOMSIZE Initial window size in earth radii, default: 1.2\n"); + printf ("-S ORIENTATION map orientation: sidereal, default: terrestial\n"); + printf ("-h Print usage\n"); } -void interactive_usage() +void +interactive_usage () { - printf("r Redraw\n"); - printf("f Toggle footprint visibility\n"); - printf("m Toggle moon visibility\n"); - printf("L Toggle launchsite visibility\n"); - printf("o Switch between terrestial and sidereal orientation\n"); - printf("c Center map on cursor position\n"); - printf("- Zoom out by a factor of 1.2\n"); - printf("+/= Zoom in\n"); - printf("{ decrease latitude -2\n"); - printf("} increase latitude +2\n"); - printf("[ decrease longitude -2\n"); - printf("] increase longitude +2\n"); - printf("< Divide the integration length by a facor of 2\n"); - printf("> Multiply the integration length by a facor of 2\n"); - printf(", Increase time (+integration_length in seconds /(1 day))\n"); - printf(". Roll back the time\n"); - printf("l Enter the integration length in seconds\n"); - printf("h this interactive help\n"); - printf("q/Q Exit\n"); + printf ("r Redraw\n"); + printf ("f Toggle footprint visibility\n"); + printf ("m Toggle moon visibility\n"); + printf ("L Toggle launchsite visibility\n"); + printf ("o Switch between terrestial and sidereal orientation\n"); + printf ("c Center map on cursor position\n"); + printf ("- Zoom out by a factor of 1.2\n"); + printf ("+/= Zoom in\n"); + printf ("{ decrease latitude -2\n"); + printf ("} increase latitude +2\n"); + printf ("[ decrease longitude -2\n"); + printf ("] increase longitude +2\n"); + printf ("< Divide the integration length by a facor of 2\n"); + printf ("> Multiply the integration length by a facor of 2\n"); + printf (", Increase time (+integration_length in seconds /(1 day))\n"); + printf (". Roll back the time\n"); + printf ("l Enter the integration length in seconds\n"); + printf ("h this interactive help\n"); + printf ("q/Q Exit\n"); } // Compute Date from Julian Day -void mjd2date(double mjd,char *date,int length) +void +mjd2date (double mjd, char *date, int length) { - double f,jd,dday; - int z,alpha,a,b,c,d,e; - int year,month,day,hour,min; - float sec,x; + double f, jd, dday; + int z, alpha, a, b, c, d, e; + int year, month, day, hour, min; + float sec, x; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - dday=b-d-floor(30.6001*e)+f; - if (e<14) - month=e-1; + if (z < 2299161) + a = z; else - month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (month>2) - year=c-4716; + dday = b - d - floor (30.6001 * e) + f; + if (e < 14) + month = e - 1; else - year=c-4715; + month = e - 13; - day=(int) floor(dday); - x=24.0*(dday-day); - x=3600.*fabs(x); - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - hour=x; - sec=floor(1000.0*sec)/1000.0; + if (month > 2) + year = c - 4716; + else + year = c - 4715; - if (length==3) - sprintf(date,"%04d-%02d-%02dT%02d:%02d:%06.3f",year,month,day,hour,min,sec); - else if (length==0) - sprintf(date,"%04d-%02d-%02dT%02d:%02d:%02.0f",year,month,day,hour,min,sec); + day = (int) floor (dday); + x = 24.0 * (dday - day); + x = 3600. * fabs (x); + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + hour = x; + sec = floor (1000.0 * sec) / 1000.0; + + if (length == 3) + sprintf (date, "%04d-%02d-%02dT%02d:%02d:%06.3f", year, month, day, hour, + min, sec); + else if (length == 0) + sprintf (date, "%04d-%02d-%02dT%02d:%02d:%02.0f", year, month, day, hour, + min, sec); return; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // rotate vector -void rotate(int axis,float angle,float *x,float *y,float *z) +void +rotate (int axis, float angle, float *x, float *y, float *z) { - float xx,yy,zz; - float ca,sa; + float xx, yy, zz; + float ca, sa; - ca=cos(angle*D2R); - sa=sin(angle*D2R); - - if (axis==0) { - xx= *x; - yy= *y*ca- *z*sa; - zz= *z*ca+ *y*sa; - } - if (axis==1) { - xx= *x*ca- *z*sa; - yy= *y; - zz= *z*ca+ *x*sa; - } - if (axis==2) { - xx= *x*ca- *y*sa; - yy= *y*ca+ *x*sa; - zz= *z; - } - - *x=xx; - *y=yy; - *z=zz; + ca = cos (angle * D2R); + sa = sin (angle * D2R); + + if (axis == 0) + { + xx = *x; + yy = *y * ca - *z * sa; + zz = *z * ca + *y * sa; + } + if (axis == 1) + { + xx = *x * ca - *z * sa; + yy = *y; + zz = *z * ca + *x * sa; + } + if (axis == 2) + { + xx = *x * ca - *y * sa; + yy = *y * ca + *x * sa; + zz = *z; + } + + *x = xx; + *y = yy; + *z = zz; return; } // Moon position -void lunpos_xyz(double mjd,xyz_t *pos,double *ra,double *de) +void +lunpos_xyz (double mjd, xyz_t * pos, double *ra, double *de) { int i; - double t,t2,t3,t4; - double l1,d,m,m1,f,a1,a2,a3,e,ef; - double suml,sumb,sumr,arglr,argb; - double l,b,r; + double t, t2, t3, t4; + double l1, d, m, m1, f, a1, a2, a3, e, ef; + double suml, sumb, sumr, arglr, argb; + double l, b, r; // Julian Centuries - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; // Powers of t - t2=t*t; - t3=t2*t; - t4=t3*t; + t2 = t * t; + t3 = t2 * t; + t4 = t3 * t; // angles - l1=modulo(218.3164477+481267.88123421*t-0.0015786*t2+t3/538841.0-t4/65194000.0,360.0)*D2R; - d=modulo(297.8501921+445267.1114034*t-0.0018819*t2+t3/545868.0-t4/113065000.0,360.0)*D2R; - m=modulo(357.5291092+35999.0502909*t-0.0001536*t2+t3/24490000.0,360.0)*D2R; - m1=modulo(134.9633964+477198.8675055*t+0.0087417*t2+t3/69699.0-t4/14712000.0,360.0)*D2R; - f=modulo(93.2720950+483202.0175233*t-0.0036539*t2-t3/3526000.0+t4/86331000.0,360.0)*D2R; - a1=modulo(119.75+131.849*t,360.0)*D2R; - a2=modulo(53.09+479264.290*t,360.0)*D2R; - a3=modulo(313.45+481266.484*t,360.0)*D2R; - e=1.0-0.002516*t-0.0000074*t2; + l1 = + modulo (218.3164477 + 481267.88123421 * t - 0.0015786 * t2 + + t3 / 538841.0 - t4 / 65194000.0, 360.0) * D2R; + d = + modulo (297.8501921 + 445267.1114034 * t - 0.0018819 * t2 + + t3 / 545868.0 - t4 / 113065000.0, 360.0) * D2R; + m = + modulo (357.5291092 + 35999.0502909 * t - 0.0001536 * t2 + + t3 / 24490000.0, 360.0) * D2R; + m1 = + modulo (134.9633964 + 477198.8675055 * t + 0.0087417 * t2 + t3 / 69699.0 - + t4 / 14712000.0, 360.0) * D2R; + f = + modulo (93.2720950 + 483202.0175233 * t - 0.0036539 * t2 - + t3 / 3526000.0 + t4 / 86331000.0, 360.0) * D2R; + a1 = modulo (119.75 + 131.849 * t, 360.0) * D2R; + a2 = modulo (53.09 + 479264.290 * t, 360.0) * D2R; + a3 = modulo (313.45 + 481266.484 * t, 360.0) * D2R; + e = 1.0 - 0.002516 * t - 0.0000074 * t2; // Compute sums - for (i=0,suml=sumb=sumr=0.0;i<60;i++) { - // Arguments - arglr=clr[i].nd*d+clr[i].nm*m+clr[i].nm1*m1+clr[i].nf*f; - argb=cb[i].nd*d+cb[i].nm*m+cb[i].nm1*m1+cb[i].nf*f; - - // E multiplication factor - if (abs(clr[i].nm)==1) - ef=e; - else if (abs(clr[i].nm)==2) - ef=e*e; - else - ef=1.0; + for (i = 0, suml = sumb = sumr = 0.0; i < 60; i++) + { + // Arguments + arglr = clr[i].nd * d + clr[i].nm * m + clr[i].nm1 * m1 + clr[i].nf * f; + argb = cb[i].nd * d + cb[i].nm * m + cb[i].nm1 * m1 + cb[i].nf * f; - // Sums - suml+=clr[i].sa*sin(arglr)*ef; - sumr+=clr[i].ca*cos(arglr)*ef; + // E multiplication factor + if (abs (clr[i].nm) == 1) + ef = e; + else if (abs (clr[i].nm) == 2) + ef = e * e; + else + ef = 1.0; - // E multiplication factor - if (abs(cb[i].nm)==1) - ef=e; - else if (abs(cb[i].nm)==2) - ef=e*e; - else - ef=1.0; + // Sums + suml += clr[i].sa * sin (arglr) * ef; + sumr += clr[i].ca * cos (arglr) * ef; - // Sums - sumb+=cb[i].sa*sin(argb)*ef; - } + // E multiplication factor + if (abs (cb[i].nm) == 1) + ef = e; + else if (abs (cb[i].nm) == 2) + ef = e * e; + else + ef = 1.0; + + // Sums + sumb += cb[i].sa * sin (argb) * ef; + } // Additives - suml+=3958*sin(a1)+1962*sin(l1-f)+318*sin(a2); - sumb+=-2235*sin(l1)+382*sin(a3)+175*sin(a1-f)+175*sin(a1+f)+127*sin(l1-m1)-115*sin(l1+m1); + suml += 3958 * sin (a1) + 1962 * sin (l1 - f) + 318 * sin (a2); + sumb += + -2235 * sin (l1) + 382 * sin (a3) + 175 * sin (a1 - f) + 175 * sin (a1 + + f) + + 127 * sin (l1 - m1) - 115 * sin (l1 + m1); // Ecliptic longitude, latitude and distance - l=modulo(l1*R2D+suml/1000000.0,360.0); - b=sumb/1000000.0; - r=385000.56+sumr/1000.0; + l = modulo (l1 * R2D + suml / 1000000.0, 360.0); + b = sumb / 1000000.0; + r = 385000.56 + sumr / 1000.0; // Equatorial - ecliptical2equatorial(l,b,ra,de); + ecliptical2equatorial (l, b, ra, de); // Position - pos->x=r*cos(*de*D2R)*cos(*ra*D2R); - pos->y=r*cos(*de*D2R)*sin(*ra*D2R); - pos->z=r*sin(*de*D2R); + pos->x = r * cos (*de * D2R) * cos (*ra * D2R); + pos->y = r * cos (*de * D2R) * sin (*ra * D2R); + pos->z = r * sin (*de * D2R); return; } // Solar position -void sunpos_xyz(double mjd,xyz_t *pos,double *ra,double *de) +void +sunpos_xyz (double mjd, xyz_t * pos, double *ra, double *de) { - double jd,t,l0,m,e,c,r; - double n,s,ecl; + double jd, t, l0, m, e, c, r; + double n, s, ecl; - jd=mjd+2400000.5; - t=(jd-2451545.0)/36525.0; - l0=modulo(280.46646+t*(36000.76983+t*0.0003032),360.0)*D2R; - m=modulo(357.52911+t*(35999.05029-t*0.0001537),360.0)*D2R; - e=0.016708634+t*(-0.000042037-t*0.0000001267); - c=(1.914602+t*(-0.004817-t*0.000014))*sin(m)*D2R; - c+=(0.019993-0.000101*t)*sin(2.0*m)*D2R; - c+=0.000289*sin(3.0*m)*D2R; + jd = mjd + 2400000.5; + t = (jd - 2451545.0) / 36525.0; + l0 = modulo (280.46646 + t * (36000.76983 + t * 0.0003032), 360.0) * D2R; + m = modulo (357.52911 + t * (35999.05029 - t * 0.0001537), 360.0) * D2R; + e = 0.016708634 + t * (-0.000042037 - t * 0.0000001267); + c = (1.914602 + t * (-0.004817 - t * 0.000014)) * sin (m) * D2R; + c += (0.019993 - 0.000101 * t) * sin (2.0 * m) * D2R; + c += 0.000289 * sin (3.0 * m) * D2R; - r=1.000001018*(1.0-e*e)/(1.0+e*cos(m+c)); - n=modulo(125.04-1934.136*t,360.0)*D2R; - s=l0+c+(-0.00569-0.00478*sin(n))*D2R; - ecl=(23.43929111+(-46.8150*t-0.00059*t*t+0.001813*t*t*t)/3600.0+0.00256*cos(n))*D2R; + r = 1.000001018 * (1.0 - e * e) / (1.0 + e * cos (m + c)); + n = modulo (125.04 - 1934.136 * t, 360.0) * D2R; + s = l0 + c + (-0.00569 - 0.00478 * sin (n)) * D2R; + ecl = + (23.43929111 + + (-46.8150 * t - 0.00059 * t * t + 0.001813 * t * t * t) / 3600.0 + + 0.00256 * cos (n)) * D2R; - *ra=atan2(cos(ecl)*sin(s),cos(s))*R2D; - *de=asin(sin(ecl)*sin(s))*R2D; + *ra = atan2 (cos (ecl) * sin (s), cos (s)) * R2D; + *de = asin (sin (ecl) * sin (s)) * R2D; - pos->x=r*cos(*de*D2R)*cos(*ra*D2R)*XKMPAU; - pos->y=r*cos(*de*D2R)*sin(*ra*D2R)*XKMPAU; - pos->z=r*sin(*de*D2R)*XKMPAU; + pos->x = r * cos (*de * D2R) * cos (*ra * D2R) * XKMPAU; + pos->y = r * cos (*de * D2R) * sin (*ra * D2R) * XKMPAU; + pos->z = r * sin (*de * D2R) * XKMPAU; return; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } // Greenwich Mean Sidereal Time -double dgmst(double mjd) +double +dgmst (double mjd) { - double t,dgmst; + double t, dgmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - dgmst=360.98564736629+t*(0.000387933-t/38710000); + dgmst = 360.98564736629 + t * (0.000387933 - t / 38710000); return dgmst; } // Get observing site -void get_site(int site_id) +void +get_site (int site_id) { - int i=0; + int i = 0; char line[LIM]; FILE *file; int id; - double lat,lng; + double lat, lng; float alt; - char abbrev[3],observer[64]; + char abbrev[3], observer[64]; char filename[LIM]; - sprintf(filename,"%s/data/sites.txt",m.datadir); - file=fopen(filename,"r"); - if (file==NULL) { - printf("File with site information not found!\n"); - return; - } - while (fgets(line,LIM,file)!=NULL) { - // Skip - if (strstr(line,"#")!=NULL) - continue; - - // Strip newline - line[strlen(line)-1]='\0'; - - // Read data - sscanf(line,"%4d %2s %lf %lf %f", - &id,abbrev,&lat,&lng,&alt); - strcpy(observer,line+38); - - // Change to km - alt/=1000.0; - - if (id==site_id) { - m.lat=lat; - m.lng=lng; - m.alt=alt; - m.site_id=id; - strcpy(m.observer,observer); + sprintf (filename, "%s/data/sites.txt", m.datadir); + file = fopen (filename, "r"); + if (file == NULL) + { + printf ("File with site information not found!\n"); + return; } + while (fgets (line, LIM, file) != NULL) + { + // Skip + if (strstr (line, "#") != NULL) + continue; + + // Strip newline + line[strlen (line) - 1] = '\0'; + + // Read data + sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt); + strcpy (observer, line + 38); + + // Change to km + alt /= 1000.0; + + if (id == site_id) + { + m.lat = lat; + m.lng = lng; + m.alt = alt; + m.site_id = id; + strcpy (m.observer, observer); + } + + } + fclose (file); - } - fclose(file); - return; } // Plot launch sites -void plot_launch_sites(void) +void +plot_launch_sites (void) { - int i=0; + int i = 0; char line[LIM]; FILE *file; - double lat,lng; - char site[64],text[8],filename[LIM]; + double lat, lng; + char site[64], text[8], filename[LIM]; float isch; - float x0,y0,z0,l0,b0; + float x0, y0, z0, l0, b0; - cpgqch(&isch); + cpgqch (&isch); - sprintf(filename,"%s/data/launchsites.txt",m.datadir); - file=fopen(filename,"r"); - if (file==NULL) { - printf("File with site information not found!\n"); - return; - } - while (fgets(line,LIM,file)!=NULL) { - // Skip - if (strstr(line,"#")!=NULL) - continue; - - // Strip newline - line[strlen(line)-1]='\0'; - - // Read data - sscanf(line,"%lf %lf", - &lat,&lng); - strcpy(site,line+21); - - l0=modulo(lng,360.0); - b0=lat; - if (l0>180.0) - l0-=360.0; - - // Convert - z0=cos(l0*D2R)*cos(b0*D2R)*XKMPER; - x0=sin(l0*D2R)*cos(b0*D2R)*XKMPER; - y0=sin(b0*D2R)*XKMPER; - - rotate(1,m.l0,&x0,&y0,&z0); - rotate(0,m.b0,&x0,&y0,&z0); - - // Plot location - if (z0>0.0) { - cpgsci(2); - cpgsch(0.5); - cpgpt1(x0,y0,4); - cpgtext(x0,y0,site); - cpgsci(1); + sprintf (filename, "%s/data/launchsites.txt", m.datadir); + file = fopen (filename, "r"); + if (file == NULL) + { + printf ("File with site information not found!\n"); + return; } - } - fclose(file); - cpgsch(isch); + while (fgets (line, LIM, file) != NULL) + { + // Skip + if (strstr (line, "#") != NULL) + continue; + + // Strip newline + line[strlen (line) - 1] = '\0'; + + // Read data + sscanf (line, "%lf %lf", &lat, &lng); + strcpy (site, line + 21); + + l0 = modulo (lng, 360.0); + b0 = lat; + if (l0 > 180.0) + l0 -= 360.0; + + // Convert + z0 = cos (l0 * D2R) * cos (b0 * D2R) * XKMPER; + x0 = sin (l0 * D2R) * cos (b0 * D2R) * XKMPER; + y0 = sin (b0 * D2R) * XKMPER; + + rotate (1, m.l0, &x0, &y0, &z0); + rotate (0, m.b0, &x0, &y0, &z0); + + // Plot location + if (z0 > 0.0) + { + cpgsci (2); + cpgsch (0.5); + cpgpt1 (x0, y0, 4); + cpgtext (x0, y0, site); + cpgsci (1); + } + } + fclose (file); + cpgsch (isch); return; } diff --git a/src/satutl.c b/src/satutl.c index aa0f02f..07f0f73 100644 --- a/src/satutl.c +++ b/src/satutl.c @@ -7,29 +7,30 @@ #include -static char *st_start(char *buf); -static long i_read(char *str, int start, int stop); -static double d_read(char *str, int start, int stop); +static char *st_start (char *buf); +static long i_read (char *str, int start, int stop); +static double d_read (char *str, int start, int stop); /* ==================================================================== - Read a string from key board, remove CR/LF etc. - ==================================================================== */ + Read a string from key board, remove CR/LF etc. + ==================================================================== */ -void read_kb(char *buf) +void +read_kb (char *buf) { -int ii; + int ii; - fgets(buf, ST_SIZE-1, stdin); + fgets (buf, ST_SIZE - 1, stdin); - /* Remove the CR/LF etc. */ - for(ii = 0; ii < ST_SIZE; ii++) - { - if(buf[ii] == '\r' || buf[ii] == '\n') - { - buf[ii] = '\0'; - break; - } - } + /* Remove the CR/LF etc. */ + for (ii = 0; ii < ST_SIZE; ii++) + { + if (buf[ii] == '\r' || buf[ii] == '\n') + { + buf[ii] = '\0'; + break; + } + } } /* ==================================================================== @@ -38,7 +39,8 @@ int ii; next elements of whatever sort. ==================================================================== */ -int read_twoline(FILE *fp, long search_satno, orbit_t *orb) +int +read_twoline (FILE * fp, long search_satno, orbit_t * orb) { static char search[ST_SIZE]; static char line1[ST_SIZE]; @@ -46,73 +48,85 @@ int read_twoline(FILE *fp, long search_satno, orbit_t *orb) char *st1, *st2; int found; double bm, bx; - + // Set defaults - strcpy(orb->desig,""); + strcpy (orb->desig, ""); st1 = line1; st2 = line2; - - do { - if(fgets(line1, ST_SIZE-1, fp) == NULL) - return -1; - st1 = st_start(line1); - } while(st1[0] != '1'); - - if(search_satno > 0) { - found = 0; - } else { - found = 1; - search_satno = atol(st1+2); - } - sprintf(search, "1 %05ld", search_satno); - - do { - st1 = st_start(line1); - if(strncmp(st1, search, 7) == 0) { - found = 1; - break; + + do + { + if (fgets (line1, ST_SIZE - 1, fp) == NULL) + return -1; + st1 = st_start (line1); } - } while(fgets(line1, ST_SIZE-1, fp) != NULL); - - sprintf(search, "2 %05ld", search_satno); - - if(found) { - fgets(line2, ST_SIZE-1, fp); - st2 = st_start(line2); - } - - if(!found || strncmp(st2, search, 7) != 0) { - return -1; - } - orb->ep_year = (int)i_read(st1, 19, 20); + while (st1[0] != '1'); - if(orb->ep_year < 57) orb->ep_year += 2000; - else orb->ep_year += 1900; - - orb->ep_day = d_read(st1, 21, 32); - - orb->ndot2 = d_read(st1, 34, 43); - bm = d_read(st1, 45, 50) * 1.0e-5; - bx = d_read(st1, 51, 52); - orb->nddot6 = bm * pow(10.0, bx); - bm = d_read(st1, 54, 59) * 1.0e-5; - bx = d_read(st1, 60, 61); - orb->bstar = bm * pow(10.0, bx); + if (search_satno > 0) + { + found = 0; + } + else + { + found = 1; + search_satno = atol (st1 + 2); + } + sprintf (search, "1 %05ld", search_satno); + + do + { + st1 = st_start (line1); + if (strncmp (st1, search, 7) == 0) + { + found = 1; + break; + } + } + while (fgets (line1, ST_SIZE - 1, fp) != NULL); + + sprintf (search, "2 %05ld", search_satno); + + if (found) + { + fgets (line2, ST_SIZE - 1, fp); + st2 = st_start (line2); + } + + if (!found || strncmp (st2, search, 7) != 0) + { + return -1; + } + orb->ep_year = (int) i_read (st1, 19, 20); + + if (orb->ep_year < 57) + orb->ep_year += 2000; + else + orb->ep_year += 1900; + + orb->ep_day = d_read (st1, 21, 32); + + orb->ndot2 = d_read (st1, 34, 43); + bm = d_read (st1, 45, 50) * 1.0e-5; + bx = d_read (st1, 51, 52); + orb->nddot6 = bm * pow (10.0, bx); + bm = d_read (st1, 54, 59) * 1.0e-5; + bx = d_read (st1, 60, 61); + orb->bstar = bm * pow (10.0, bx); + + orb->eqinc = RAD (d_read (st2, 9, 16)); + orb->ascn = RAD (d_read (st2, 18, 25)); + orb->ecc = d_read (st2, 27, 33) * 1.0e-7; + orb->argp = RAD (d_read (st2, 35, 42)); + orb->mnan = RAD (d_read (st2, 44, 51)); + orb->rev = d_read (st2, 53, 63); + orb->norb = i_read (st2, 64, 68); - orb->eqinc = RAD(d_read(st2, 9, 16)); - orb->ascn = RAD(d_read(st2, 18, 25)); - orb->ecc = d_read(st2, 27, 33) * 1.0e-7; - orb->argp = RAD(d_read(st2, 35, 42)); - orb->mnan = RAD(d_read(st2, 44, 51)); - orb->rev = d_read(st2, 53, 63); - orb->norb = i_read(st2, 64, 68); - orb->satno = search_satno; // sscanf(st1+9,"%s",orb->desig); - strncpy(orb->desig,st1+9,8); - orb->desig[8]='\0'; + strncpy (orb->desig, st1 + 9, 8); + orb->desig[8] = '\0'; return 0; } @@ -121,13 +135,16 @@ int read_twoline(FILE *fp, long search_satno, orbit_t *orb) Locate the first non-white space character, return location. ================================================================== */ -static char *st_start(char *buf) +static char * +st_start (char *buf) { - if(buf == NULL) return buf; + if (buf == NULL) + return buf; - while(*buf != '\0' && isspace(*buf)) buf++; + while (*buf != '\0' && isspace (*buf)) + buf++; -return buf; + return buf; } /* ================================================================== @@ -135,27 +152,28 @@ return buf; characters to buffer then convert. ================================================================== */ -static long i_read(char *str, int start, int stop) +static long +i_read (char *str, int start, int stop) { -long itmp=0; -char *buf, *tmp; -int ii; + long itmp = 0; + char *buf, *tmp; + int ii; - start--; /* 'C' arrays start at 0 */ - stop--; + start--; /* 'C' arrays start at 0 */ + stop--; - tmp = buf = (char *)vector(stop-start+2, sizeof(char)); + tmp = buf = (char *) vector (stop - start + 2, sizeof (char)); - for(ii = start; ii <= stop; ii++) - { - *tmp++ = str[ii]; /* Copy the characters. */ - } - *tmp = '\0'; /* NUL terminate */ + for (ii = start; ii <= stop; ii++) + { + *tmp++ = str[ii]; /* Copy the characters. */ + } + *tmp = '\0'; /* NUL terminate */ - itmp = atol(buf); /* Convert to long integer. */ - free(buf); + itmp = atol (buf); /* Convert to long integer. */ + free (buf); -return itmp; + return itmp; } /* ================================================================== @@ -163,65 +181,69 @@ return itmp; characters to buffer then convert. ================================================================== */ -static double d_read(char *str, int start, int stop) +static double +d_read (char *str, int start, int stop) { -double dtmp=0; -char *buf, *tmp; -int ii; + double dtmp = 0; + char *buf, *tmp; + int ii; - start--; - stop--; + start--; + stop--; - tmp = buf = (char *)vector(stop-start+2, sizeof(char)); + tmp = buf = (char *) vector (stop - start + 2, sizeof (char)); - for(ii = start; ii <= stop; ii++) - { - *tmp++ = str[ii]; /* Copy the characters. */ - } - *tmp = '\0'; /* NUL terminate */ + for (ii = start; ii <= stop; ii++) + { + *tmp++ = str[ii]; /* Copy the characters. */ + } + *tmp = '\0'; /* NUL terminate */ - dtmp = atof(buf); /* Convert to long integer. */ - free(buf); + dtmp = atof (buf); /* Convert to long integer. */ + free (buf); -return dtmp; + return dtmp; } /* ================================================================== Allocate and check an all-zero array of memory (storage vector). ================================================================== */ -void *vector(size_t num, size_t size) +void * +vector (size_t num, size_t size) { -void *ptr; + void *ptr; - ptr = calloc(num, size); - if(ptr == NULL) - { - fatal_error("vector: Allocation failed %u * %u", num, size); - } + ptr = calloc (num, size); + if (ptr == NULL) + { + fatal_error ("vector: Allocation failed %u * %u", num, size); + } -return ptr; + return ptr; } /* ================================================================== Print out orbital parameters. ================================================================== */ -void print_orb(orbit_t *orb) +void +print_orb (orbit_t * orb) { - printf("# Satellite ID = %ld\n", (long)orb->satno); - printf("# Satellite designation = %s\n",orb->desig); - printf("# Epoch year = %d day = %.8f\n", orb->ep_year, orb->ep_day); - printf("# Eccentricity = %.7f\n", orb->ecc); - printf("# Equatorial inclination = %.4f deg\n", DEG(orb->eqinc)); - printf("# Argument of perigee = %.4f deg\n", DEG(orb->argp)); - printf("# Mean anomaly = %.4f deg\n", DEG(orb->mnan)); - printf("# Right Ascension of Ascending Node = %.4f deg\n", DEG(orb->ascn)); - printf("# Mean Motion (number of rev/day) = %.8f\n", orb->rev); - printf("# First derivative of mean motion = %e\n",orb->ndot2); - printf("# Second derivative of mean motion = %e\n",orb->nddot6); - printf("# BSTAR drag = %.4e\n", orb->bstar); - printf("# Orbit number = %ld\n", orb->norb); + printf ("# Satellite ID = %ld\n", (long) orb->satno); + printf ("# Satellite designation = %s\n", orb->desig); + printf ("# Epoch year = %d day = %.8f\n", orb->ep_year, orb->ep_day); + printf ("# Eccentricity = %.7f\n", orb->ecc); + printf ("# Equatorial inclination = %.4f deg\n", DEG (orb->eqinc)); + printf ("# Argument of perigee = %.4f deg\n", DEG (orb->argp)); + printf ("# Mean anomaly = %.4f deg\n", DEG (orb->mnan)); + printf ("# Right Ascension of Ascending Node = %.4f deg\n", + DEG (orb->ascn)); + printf ("# Mean Motion (number of rev/day) = %.8f\n", orb->rev); + printf ("# First derivative of mean motion = %e\n", orb->ndot2); + printf ("# Second derivative of mean motion = %e\n", orb->nddot6); + printf ("# BSTAR drag = %.4e\n", orb->bstar); + printf ("# Orbit number = %ld\n", orb->norb); } /* ====================================================================== */ diff --git a/src/satutl.h b/src/satutl.h index 04e1969..5d50822 100644 --- a/src/satutl.h +++ b/src/satutl.h @@ -8,23 +8,24 @@ #define ST_SIZE 256 #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /** satutl.c **/ -void read_kb(char *buf); -int read_twoline(FILE *fp, long satno, orbit_t *orb); -void *vector(size_t num, size_t size); -void print_orb(orbit_t *orb); + void read_kb (char *buf); + int read_twoline (FILE * fp, long satno, orbit_t * orb); + void *vector (size_t num, size_t size); + void print_orb (orbit_t * orb); /** aries.c **/ -double gha_aries(double jd); + double gha_aries (double jd); /** ferror.c **/ -void fatal_error(const char *format, ...); + void fatal_error (const char *format, ...); #ifdef __cplusplus } #endif -#endif /* _SATUTL_H */ +#endif /* _SATUTL_H */ diff --git a/src/sgdp4.c b/src/sgdp4.c index 36750f3..d34494a 100644 --- a/src/sgdp4.c +++ b/src/sgdp4.c @@ -63,7 +63,8 @@ * */ -static const char SCCSid[] = "@(#)sgdp4.c 3.04 (C) 1995 psc SatLib: Orbital Model"; +static const char SCCSid[] = + "@(#)sgdp4.c 3.04 (C) 1995 psc SatLib: Orbital Model"; #include #include @@ -73,7 +74,7 @@ static const char SCCSid[] = "@(#)sgdp4.c 3.04 (C) 1995 psc SatLib: Orbita #include "sgdp4h.h" -#define ECC_ZERO ((real)0.0) /* Zero eccentricity case ? */ +#define ECC_ZERO ((real)0.0) /* Zero eccentricity case ? */ #define ECC_ALL ((real)1.0e-4) /* For all drag terms in GSFC case. */ #define ECC_EPS ((real)1.0e-6) /* Too low for computing further drops. */ #define ECC_LIMIT_LOW ((real)-1.0e-3) /* Exit point for serious decaying of orbits. */ @@ -84,9 +85,9 @@ static const char SCCSid[] = "@(#)sgdp4.c 3.04 (C) 1995 psc SatLib: Orbita #define TOTHRD (2.0/3.0) #if defined( SGDP4_SNGL ) || 0 -#define NR_EPS ((real)(1.0e-6)) /* Minimum ~1e-6 min for float. */ +#define NR_EPS ((real)(1.0e-6)) /* Minimum ~1e-6 min for float. */ #else -#define NR_EPS ((real)(1.0e-12)) /* Minimum ~1e-14 for double. */ +#define NR_EPS ((real)(1.0e-12)) /* Minimum ~1e-14 for double. */ #endif #define Q0 ((real)120.0) @@ -94,38 +95,38 @@ static const char SCCSid[] = "@(#)sgdp4.c 3.04 (C) 1995 psc SatLib: Orbita #define XJ2 ((real)1.082616e-3) #define XJ3 ((real)-2.53881e-6) #define XJ4 ((real)-1.65597e-6) -#define XKMPER (6378.135) /* Km per earth radii */ -#define XMNPDA (1440.0) /* Minutes per day */ -#define AE (1.0) /* Earth radius in "chosen units". */ +#define XKMPER (6378.135) /* Km per earth radii */ +#define XMNPDA (1440.0) /* Minutes per day */ +#define AE (1.0) /* Earth radius in "chosen units". */ #if 0 /* Original code constants. */ #define XKE (0.743669161e-1) -#define CK2 ((real)5.413080e-4) /* (0.5 * XJ2 * AE * AE) */ -#define CK4 ((real)0.62098875e-6) /* (-0.375 * XJ4 * AE * AE * AE * AE) */ -#define QOMS2T ((real)1.88027916e-9) /* (pow((Q0 - S0)*AE/XKMPER, 4.0)) */ -#define KS ((real)1.01222928) /* (AE * (1.0 + S0/XKMPER)) */ +#define CK2 ((real)5.413080e-4) /* (0.5 * XJ2 * AE * AE) */ +#define CK4 ((real)0.62098875e-6) /* (-0.375 * XJ4 * AE * AE * AE * AE) */ +#define QOMS2T ((real)1.88027916e-9) /* (pow((Q0 - S0)*AE/XKMPER, 4.0)) */ +#define KS ((real)1.01222928) /* (AE * (1.0 + S0/XKMPER)) */ #else /* GSFC improved coefficient resolution. */ #define XKE ((real)7.43669161331734132e-2) #define CK2 ((real)(0.5 * XJ2 * AE * AE)) #define CK4 ((real)(-0.375 * XJ4 * AE * AE * AE * AE)) -#define QOMS2T ((real)1.880279159015270643865e-9) /* (pow((Q0 - S0)*AE/XKMPER, 4.0)) */ +#define QOMS2T ((real)1.880279159015270643865e-9) /* (pow((Q0 - S0)*AE/XKMPER, 4.0)) */ #define KS ((real)(AE * (1.0 + S0/XKMPER))) #endif -static const real a3ovk2 = (real)(-XJ3 / CK2 * (AE * AE * AE)); +static const real a3ovk2 = (real) (-XJ3 / CK2 * (AE * AE * AE)); /* ================= Copy of the orbital elements ==================== */ -static double xno; /* Mean motion (rad/min) */ -static real xmo; /* Mean "mean anomaly" at epoch (rad). */ -static real eo; /* Eccentricity. */ -static real xincl; /* Equatorial inclination (rad). */ -static real omegao; /* Mean argument of perigee at epoch (rad). */ -static real xnodeo; /* Mean longitude of ascending node (rad, east). */ -static real bstar; /* Drag term. */ +static double xno; /* Mean motion (rad/min) */ +static real xmo; /* Mean "mean anomaly" at epoch (rad). */ +static real eo; /* Eccentricity. */ +static real xincl; /* Equatorial inclination (rad). */ +static real omegao; /* Mean argument of perigee at epoch (rad). */ +static real xnodeo; /* Mean longitude of ascending node (rad, east). */ +static real bstar; /* Drag term. */ -double SGDP4_jd0; /* Julian Day for epoch (available to outside functions. */ +double SGDP4_jd0; /* Julian Day for epoch (available to outside functions. */ /* ================== Local "global" variables for SGP4 ================= */ @@ -138,11 +139,11 @@ static real xnodcf, delmo, x7thm1, x3thm1, x1mth2; static real aodp, eta, omgdot, xnodot; static double xnodp, xmdot; -static long Isat = 0; /* 16-bit compilers need 'long' integer for higher space catalogue numbers. */ +static long Isat = 0; /* 16-bit compilers need 'long' integer for higher space catalogue numbers. */ static double perigee, period, apogee; -int Set_LS_zero = 0; /* Set to 1 to zero Lunar-Solar terms at epoch. */ +int Set_LS_zero = 0; /* Set to 1 to zero Lunar-Solar terms at epoch. */ /* ======================================================================= The init_sgdp4() function passes all of the required orbital elements to @@ -163,274 +164,313 @@ int Set_LS_zero = 0; /* Set to 1 to zero Lunar-Solar terms at epoch. */ The return value indicates the orbital model used. ======================================================================= */ -sgdp4_mode_t init_sgdp4(orbit_t *orb) +sgdp4_mode_t +init_sgdp4 (orbit_t * orb) { -LOCAL_REAL theta2, theta4, xhdot1, x1m5th; -LOCAL_REAL s4, del1, del0; -LOCAL_REAL betao, betao2, coef, coef1; -LOCAL_REAL etasq, eeta, qoms24; -LOCAL_REAL pinvsq, tsi, psisq, c1sq; -LOCAL_DOUBLE a0, a1, epoch; -real temp0, temp1, temp2, temp3; -long iday, iyear; + LOCAL_REAL theta2, theta4, xhdot1, x1m5th; + LOCAL_REAL s4, del1, del0; + LOCAL_REAL betao, betao2, coef, coef1; + LOCAL_REAL etasq, eeta, qoms24; + LOCAL_REAL pinvsq, tsi, psisq, c1sq; + LOCAL_DOUBLE a0, a1, epoch; + real temp0, temp1, temp2, temp3; + long iday, iyear; - /* Copy over elements. */ - /* Convert year to Gregorian with century as 1994 or 94 type ? */ + /* Copy over elements. */ + /* Convert year to Gregorian with century as 1994 or 94 type ? */ - iyear = (long)orb->ep_year; + iyear = (long) orb->ep_year; - if (iyear < 1960) - { - /* Assume 0 and 100 both refer to 2000AD */ - iyear += (iyear < 60 ? 2000 : 1900); - } + if (iyear < 1960) + { + /* Assume 0 and 100 both refer to 2000AD */ + iyear += (iyear < 60 ? 2000 : 1900); + } - if (iyear < 1901 || iyear > 2099) - { - fatal_error("init_sgdp4: Satellite ep_year error %ld", iyear); - imode = SGDP4_ERROR; - return imode; - } + if (iyear < 1901 || iyear > 2099) + { + fatal_error ("init_sgdp4: Satellite ep_year error %ld", iyear); + imode = SGDP4_ERROR; + return imode; + } - Isat = orb->satno; + Isat = orb->satno; - /* Compute days from 1st Jan 1900 (works 1901 to 2099 only). */ + /* Compute days from 1st Jan 1900 (works 1901 to 2099 only). */ - iday = ((iyear - 1901)*1461L)/4L + 364L + 1L; + iday = ((iyear - 1901) * 1461L) / 4L + 364L + 1L; - SGDP4_jd0 = JD1900 + iday + (orb->ep_day - 1.0); /* Julian day number. */ + SGDP4_jd0 = JD1900 + iday + (orb->ep_day - 1.0); /* Julian day number. */ - epoch = (iyear - 1900) * 1.0e3 + orb->ep_day; /* YYDDD.DDDD as from 2-line. */ + epoch = (iyear - 1900) * 1.0e3 + orb->ep_day; /* YYDDD.DDDD as from 2-line. */ #ifdef DEBUG - fprintf(stderr, "Epoch = %f SGDP4_jd0 = %f\n", epoch, SGDP4_jd0); + fprintf (stderr, "Epoch = %f SGDP4_jd0 = %f\n", epoch, SGDP4_jd0); #endif - eo = (real)orb->ecc; - xno = (double)orb->rev * TWOPI/XMNPDA; /* Radian / unit time. */ - xincl = (real)orb->eqinc; - xnodeo = (real)orb->ascn; - omegao = (real)orb->argp; - xmo = (real)orb->mnan; - bstar = (real)orb->bstar; + eo = (real) orb->ecc; + xno = (double) orb->rev * TWOPI / XMNPDA; /* Radian / unit time. */ + xincl = (real) orb->eqinc; + xnodeo = (real) orb->ascn; + omegao = (real) orb->argp; + xmo = (real) orb->mnan; + bstar = (real) orb->bstar; - /* A few simple error checks here. */ + /* A few simple error checks here. */ - if (eo < (real)0.0 || eo > ECC_LIMIT_HIGH) - { - fatal_error("init_sgdp4: Eccentricity out of range for %ld (%le)", Isat, (double)eo); - imode = SGDP4_ERROR; - return imode; - } + if (eo < (real) 0.0 || eo > ECC_LIMIT_HIGH) + { + fatal_error ("init_sgdp4: Eccentricity out of range for %ld (%le)", + Isat, (double) eo); + imode = SGDP4_ERROR; + return imode; + } - if (xno < 0.035*TWOPI/XMNPDA || xno > 18.0*TWOPI/XMNPDA) - { - fatal_error("init_sgdp4: Mean motion out of range %ld (%le)", Isat, xno); - imode = SGDP4_ERROR; - return imode; - } + if (xno < 0.035 * TWOPI / XMNPDA || xno > 18.0 * TWOPI / XMNPDA) + { + fatal_error ("init_sgdp4: Mean motion out of range %ld (%le)", Isat, + xno); + imode = SGDP4_ERROR; + return imode; + } - if (xincl < (real)0.0 || xincl > (real)PI) - { - fatal_error("init_sgdp4: Equatorial inclination out of range %ld (%le)", Isat, DEG(xincl)); - imode = SGDP4_ERROR; - return imode; - } + if (xincl < (real) 0.0 || xincl > (real) PI) + { + fatal_error + ("init_sgdp4: Equatorial inclination out of range %ld (%le)", Isat, + DEG (xincl)); + imode = SGDP4_ERROR; + return imode; + } - /* Start the initialisation. */ + /* Start the initialisation. */ - if (eo < ECC_ZERO) - imode = SGDP4_ZERO_ECC; /* Special mode for "ideal" circular orbit. */ - else - imode = SGDP4_NOT_INIT; + if (eo < ECC_ZERO) + imode = SGDP4_ZERO_ECC; /* Special mode for "ideal" circular orbit. */ + else + imode = SGDP4_NOT_INIT; - /* - Recover original mean motion (xnodp) and semimajor axis (aodp) - from input elements. - */ + /* + Recover original mean motion (xnodp) and semimajor axis (aodp) + from input elements. + */ - SINCOS(xincl, &sinIO, &cosIO); + SINCOS (xincl, &sinIO, &cosIO); - theta2 = cosIO * cosIO; - theta4 = theta2 * theta2; - x3thm1 = (real)3.0 * theta2 - (real)1.0; - x1mth2 = (real)1.0 - theta2; - x7thm1 = (real)7.0 * theta2 - (real)1.0; + theta2 = cosIO * cosIO; + theta4 = theta2 * theta2; + x3thm1 = (real) 3.0 *theta2 - (real) 1.0; + x1mth2 = (real) 1.0 - theta2; + x7thm1 = (real) 7.0 *theta2 - (real) 1.0; - a1 = pow(XKE / xno, TOTHRD); - betao2 = (real)1.0 - eo * eo; - betao = SQRT(betao2); - temp0 = (real)(1.5 * CK2) * x3thm1 / (betao * betao2); - del1 = temp0 / (a1 * a1); - a0 = a1 * (1.0 - del1 * (1.0/3.0 + del1 * (1.0 + del1 * 134.0/81.0))); - del0 = temp0 / (a0 * a0); - xnodp = xno / (1.0 + del0); - aodp = (real)(a0 / (1.0 - del0)); - perigee = (aodp * (1.0 - eo) - AE) * XKMPER; - apogee = (aodp * (1.0 + eo) - AE) * XKMPER; - period = (TWOPI * 1440.0 / XMNPDA) / xnodp; + a1 = pow (XKE / xno, TOTHRD); + betao2 = (real) 1.0 - eo * eo; + betao = SQRT (betao2); + temp0 = (real) (1.5 * CK2) * x3thm1 / (betao * betao2); + del1 = temp0 / (a1 * a1); + a0 = a1 * (1.0 - del1 * (1.0 / 3.0 + del1 * (1.0 + del1 * 134.0 / 81.0))); + del0 = temp0 / (a0 * a0); + xnodp = xno / (1.0 + del0); + aodp = (real) (a0 / (1.0 - del0)); + perigee = (aodp * (1.0 - eo) - AE) * XKMPER; + apogee = (aodp * (1.0 + eo) - AE) * XKMPER; + period = (TWOPI * 1440.0 / XMNPDA) / xnodp; - /* - printf("Perigee = %lf km period = %lf min del0 = %e\n", - perigee, period, del0); - */ - if (perigee <= 0.0) - { - fprintf(stderr, "# Satellite %ld sub-orbital (apogee = %.1f km, perigee = %.1f km)\n", Isat, apogee, perigee); - } + /* + printf("Perigee = %lf km period = %lf min del0 = %e\n", + perigee, period, del0); + */ + if (perigee <= 0.0) + { + fprintf (stderr, + "# Satellite %ld sub-orbital (apogee = %.1f km, perigee = %.1f km)\n", + Isat, apogee, perigee); + } - if (imode == SGDP4_ZERO_ECC) return imode; + if (imode == SGDP4_ZERO_ECC) + return imode; - if (period >= 225.0 && Set_LS_zero < 2) - { - imode = SGDP4_DEEP_NORM; /* Deep-Space model(s). */ - } - else if (perigee < 220.0) - { - /* - For perigee less than 220 km the imode flag is set so the - equations are truncated to linear variation in sqrt A and - quadratic variation in mean anomaly. Also the c3 term, the - delta omega term and the delta m term are dropped. - */ - imode = SGDP4_NEAR_SIMP; /* Near-space, simplified equations. */ - } - else - { - imode = SGDP4_NEAR_NORM; /* Near-space, normal equations. */ - } + if (period >= 225.0 && Set_LS_zero < 2) + { + imode = SGDP4_DEEP_NORM; /* Deep-Space model(s). */ + } + else if (perigee < 220.0) + { + /* + For perigee less than 220 km the imode flag is set so the + equations are truncated to linear variation in sqrt A and + quadratic variation in mean anomaly. Also the c3 term, the + delta omega term and the delta m term are dropped. + */ + imode = SGDP4_NEAR_SIMP; /* Near-space, simplified equations. */ + } + else + { + imode = SGDP4_NEAR_NORM; /* Near-space, normal equations. */ + } - /* For perigee below 156 km the values of S and QOMS2T are altered */ + /* For perigee below 156 km the values of S and QOMS2T are altered */ - if (perigee < 156.0) - { - s4 = (real)(perigee - 78.0); + if (perigee < 156.0) + { + s4 = (real) (perigee - 78.0); - if(s4 < (real)20.0) - { - fprintf(stderr, "# Very low s4 constant for sat %ld (perigee = %.2f)\n", Isat, perigee); - s4 = (real)20.0; - } - else - { - fprintf(stderr, "# Changing s4 constant for sat %ld (perigee = %.2f)\n", Isat, perigee); - } + if (s4 < (real) 20.0) + { + fprintf (stderr, + "# Very low s4 constant for sat %ld (perigee = %.2f)\n", + Isat, perigee); + s4 = (real) 20.0; + } + else + { + fprintf (stderr, + "# Changing s4 constant for sat %ld (perigee = %.2f)\n", + Isat, perigee); + } - qoms24 = POW4((real)((120.0 - s4) * (AE / XKMPER))); - s4 = (real)(s4 / XKMPER + AE); - } - else - { - s4 = KS; - qoms24 = QOMS2T; - } + qoms24 = POW4 ((real) ((120.0 - s4) * (AE / XKMPER))); + s4 = (real) (s4 / XKMPER + AE); + } + else + { + s4 = KS; + qoms24 = QOMS2T; + } - pinvsq = (real)1.0 / (aodp * aodp * betao2 * betao2); - tsi = (real)1.0 / (aodp - s4); - eta = aodp * eo * tsi; - etasq = eta * eta; - eeta = eo * eta; - psisq = FABS((real)1.0 - etasq); - coef = qoms24 * POW4(tsi); - coef1 = coef / POW(psisq, 3.5); + pinvsq = (real) 1.0 / (aodp * aodp * betao2 * betao2); + tsi = (real) 1.0 / (aodp - s4); + eta = aodp * eo * tsi; + etasq = eta * eta; + eeta = eo * eta; + psisq = FABS ((real) 1.0 - etasq); + coef = qoms24 * POW4 (tsi); + coef1 = coef / POW (psisq, 3.5); - c2 = coef1 * (real)xnodp * (aodp * - ((real)1.0 + (real)1.5 * etasq + eeta * ((real)4.0 + etasq)) + - (real)(0.75 * CK2) * tsi / psisq * x3thm1 * - ((real)8.0 + (real)3.0 * etasq * ((real)8.0 + etasq))); + c2 = coef1 * (real) xnodp *(aodp * + ((real) 1.0 + (real) 1.5 * etasq + + eeta * ((real) 4.0 + etasq)) + + (real) (0.75 * CK2) * tsi / psisq * x3thm1 * + ((real) 8.0 + + (real) 3.0 * etasq * ((real) 8.0 + etasq))); - c1 = bstar * c2; + c1 = bstar * c2; - c4 = (real)2.0 * (real)xnodp * coef1 * aodp * betao2 * (eta * - ((real)2.0 + (real)0.5 * etasq) + eo * ((real)0.5 + (real)2.0 * - etasq) - (real)(2.0 * CK2) * tsi / (aodp * psisq) * ((real)-3.0 * - x3thm1 * ((real)1.0 - (real)2.0 * eeta + etasq * - ((real)1.5 - (real)0.5 * eeta)) + (real)0.75 * x1mth2 * ((real)2.0 * - etasq - eeta * ((real)1.0 + etasq)) * COS((real)2.0 * omegao))); + c4 = (real) 2.0 *(real) xnodp *coef1 * aodp * betao2 * (eta * + ((real) 2.0 + + (real) 0.5 * + etasq) + + eo * ((real) 0.5 + + (real) 2.0 * + etasq) - + (real) (2.0 * CK2) * + tsi / (aodp * + psisq) * + ((real) - + 3.0 * x3thm1 * + ((real) 1.0 - + (real) 2.0 * + eeta + + etasq * + ((real) 1.5 - + (real) 0.5 * + eeta)) + + (real) 0.75 * + x1mth2 * + ((real) 2.0 * + etasq - + eeta * + ((real) 1.0 + + etasq)) * + COS ((real) 2.0 * + omegao))); - c5 = c3 = omgcof = (real)0.0; + c5 = c3 = omgcof = (real) 0.0; - if (imode == SGDP4_NEAR_NORM) - { - /* BSTAR drag terms for normal near-space 'normal' model only. */ - c5 = (real)2.0 * coef1 * aodp * betao2 * - ((real)1.0 + (real)2.75 * (etasq + eeta) + eeta * etasq); + if (imode == SGDP4_NEAR_NORM) + { + /* BSTAR drag terms for normal near-space 'normal' model only. */ + c5 = (real) 2.0 *coef1 * aodp * betao2 * + ((real) 1.0 + (real) 2.75 * (etasq + eeta) + eeta * etasq); - if(eo > ECC_ALL) - { - c3 = coef * tsi * a3ovk2 * (real)xnodp * (real)AE * sinIO / eo; - } + if (eo > ECC_ALL) + { + c3 = coef * tsi * a3ovk2 * (real) xnodp *(real) AE *sinIO / eo; + } - omgcof = bstar * c3 * COS(omegao); - } + omgcof = bstar * c3 * COS (omegao); + } - temp1 = (real)(3.0 * CK2) * pinvsq * (real)xnodp; - temp2 = temp1 * CK2 * pinvsq; - temp3 = (real)(1.25 * CK4) * pinvsq * pinvsq * (real)xnodp; + temp1 = (real) (3.0 * CK2) * pinvsq * (real) xnodp; + temp2 = temp1 * CK2 * pinvsq; + temp3 = (real) (1.25 * CK4) * pinvsq * pinvsq * (real) xnodp; - xmdot = xnodp + ((real)0.5 * temp1 * betao * x3thm1 + (real)0.0625 * - temp2 * betao * ((real)13.0 - (real)78.0 * theta2 + - (real)137.0 * theta4)); + xmdot = xnodp + ((real) 0.5 * temp1 * betao * x3thm1 + (real) 0.0625 * + temp2 * betao * ((real) 13.0 - (real) 78.0 * theta2 + + (real) 137.0 * theta4)); - x1m5th = (real)1.0 - (real)5.0 * theta2; + x1m5th = (real) 1.0 - (real) 5.0 *theta2; - omgdot = (real)-0.5 * temp1 * x1m5th + (real)0.0625 * temp2 * - ((real)7.0 - (real)114.0 * theta2 + (real)395.0 * theta4) + - temp3 * ((real)3.0 - (real)36.0 * theta2 + (real)49.0 * theta4); + omgdot = (real) - 0.5 * temp1 * x1m5th + (real) 0.0625 *temp2 * + ((real) 7.0 - (real) 114.0 * theta2 + (real) 395.0 * theta4) + + temp3 * ((real) 3.0 - (real) 36.0 * theta2 + (real) 49.0 * theta4); - xhdot1 = -temp1 * cosIO; - xnodot = xhdot1 + ((real)0.5 * temp2 * ((real)4.0 - (real)19.0 * theta2) + - (real)2.0 * temp3 * ((real)3.0 - (real)7.0 * theta2)) * cosIO; + xhdot1 = -temp1 * cosIO; + xnodot = + xhdot1 + ((real) 0.5 * temp2 * ((real) 4.0 - (real) 19.0 * theta2) + + (real) 2.0 * temp3 * ((real) 3.0 - + (real) 7.0 * theta2)) * cosIO; - xmcof = (real)0.0; - if(eo > ECC_ALL) - { - xmcof = (real)(-TOTHRD * AE) * coef * bstar / eeta; - } + xmcof = (real) 0.0; + if (eo > ECC_ALL) + { + xmcof = (real) (-TOTHRD * AE) * coef * bstar / eeta; + } - xnodcf = (real)3.5 * betao2 * xhdot1 * c1; - t2cof = (real)1.5 * c1; + xnodcf = (real) 3.5 *betao2 * xhdot1 * c1; + t2cof = (real) 1.5 *c1; - /* Check for possible divide-by-zero for X/(1+cosIO) when calculating xlcof */ - temp0 = (real)1.0 + cosIO; + /* Check for possible divide-by-zero for X/(1+cosIO) when calculating xlcof */ + temp0 = (real) 1.0 + cosIO; - if(fabs(temp0) < EPS_COSIO) temp0 = (real)SIGN(EPS_COSIO, temp0); + if (fabs (temp0) < EPS_COSIO) + temp0 = (real) SIGN (EPS_COSIO, temp0); - xlcof = (real)0.125 * a3ovk2 * sinIO * - ((real)3.0 + (real)5.0 * cosIO) / temp0; + xlcof = (real) 0.125 *a3ovk2 * sinIO * + ((real) 3.0 + (real) 5.0 * cosIO) / temp0; - aycof = (real)0.25 * a3ovk2 * sinIO; + aycof = (real) 0.25 *a3ovk2 * sinIO; - SINCOS(xmo, &sinXMO, &cosXMO); - delmo = CUBE((real)1.0 + eta * cosXMO); + SINCOS (xmo, &sinXMO, &cosXMO); + delmo = CUBE ((real) 1.0 + eta * cosXMO); - if (imode == SGDP4_NEAR_NORM) - { - c1sq = c1 * c1; - d2 = (real)4.0 * aodp * tsi * c1sq; - temp0 = d2 * tsi * c1 / (real)3.0; - d3 = ((real)17.0 * aodp + s4) * temp0; - d4 = (real)0.5 * temp0 * aodp * tsi * ((real)221.0 * aodp + - (real)31.0 * s4) * c1; - t3cof = d2 + (real)2.0 * c1sq; - t4cof = (real)0.25 * ((real)3.0 * d3 + c1 * ((real)12.0 * d2 + - (real)10.0 * c1sq)); - t5cof = (real)0.2 * ((real)3.0 * d4 + (real)12.0 * c1 * d3 + - (real)6.0 * d2 * d2 + (real)15.0 * c1sq * ((real)2.0 * - d2 + c1sq)); - } - else if (imode == SGDP4_DEEP_NORM) - { + if (imode == SGDP4_NEAR_NORM) + { + c1sq = c1 * c1; + d2 = (real) 4.0 *aodp * tsi * c1sq; + temp0 = d2 * tsi * c1 / (real) 3.0; + d3 = ((real) 17.0 * aodp + s4) * temp0; + d4 = (real) 0.5 *temp0 * aodp * tsi * ((real) 221.0 * aodp + + (real) 31.0 * s4) * c1; + t3cof = d2 + (real) 2.0 *c1sq; + t4cof = (real) 0.25 *((real) 3.0 * d3 + c1 * ((real) 12.0 * d2 + + (real) 10.0 * c1sq)); + t5cof = (real) 0.2 *((real) 3.0 * d4 + (real) 12.0 * c1 * d3 + + (real) 6.0 * d2 * d2 + + (real) 15.0 * c1sq * ((real) 2.0 * d2 + c1sq)); + } + else if (imode == SGDP4_DEEP_NORM) + { #ifdef NO_DEEP_SPACE - fprintf(stderr, "init_sgdp4: Deep space equations not supported\n"); - imode = SGDP4_NEAR_NORM; /* Force operations even if wrong model? */ + fprintf (stderr, "init_sgdp4: Deep space equations not supported\n"); + imode = SGDP4_NEAR_NORM; /* Force operations even if wrong model? */ #else - imode = SGDP4_dpinit(epoch, omegao, xnodeo, xmo, eo, xincl, - aodp, xmdot, omgdot, xnodot, xnodp); + imode = SGDP4_dpinit (epoch, omegao, xnodeo, xmo, eo, xincl, + aodp, xmdot, omgdot, xnodot, xnodp); #endif /* !NO_DEEP_SPACE */ - } + } -return imode; + return imode; } /* ======================================================================= @@ -455,288 +495,299 @@ return imode; ======================================================================= */ -sgdp4_mode_t sgdp4(double tsince, int withvel, kep_t *kep) +sgdp4_mode_t +sgdp4 (double tsince, int withvel, kep_t * kep) { -LOCAL_REAL rk, uk, xnodek, xinck, em, xinc; -LOCAL_REAL xnode, delm, axn, ayn, omega; -LOCAL_REAL capu, epw, elsq, invR, beta2, betal; -LOCAL_REAL sinu, sin2u, cosu, cos2u; -LOCAL_REAL a, e, r, u, pl; -LOCAL_REAL sinEPW, cosEPW, sinOMG, cosOMG; -LOCAL_DOUBLE xmp, xl, xlt; -const int MAXI = 10; + LOCAL_REAL rk, uk, xnodek, xinck, em, xinc; + LOCAL_REAL xnode, delm, axn, ayn, omega; + LOCAL_REAL capu, epw, elsq, invR, beta2, betal; + LOCAL_REAL sinu, sin2u, cosu, cos2u; + LOCAL_REAL a, e, r, u, pl; + LOCAL_REAL sinEPW, cosEPW, sinOMG, cosOMG; + LOCAL_DOUBLE xmp, xl, xlt; + const int MAXI = 10; #ifndef NO_DEEP_SPACE -LOCAL_DOUBLE xn, xmam; -#endif /* !NO_DEEP_SPACE */ + LOCAL_DOUBLE xn, xmam; +#endif /* !NO_DEEP_SPACE */ -real esinE, ecosE, maxnr; -real temp0, temp1, temp2, temp3; -real tempa, tempe, templ; -int ii; + real esinE, ecosE, maxnr; + real temp0, temp1, temp2, temp3; + real tempa, tempe, templ; + int ii; #ifdef SGDP4_SNGL -real ts = (real)tsince; + real ts = (real) tsince; #else #define ts tsince #endif /* ! SGDP4_SNGL */ - /* Update for secular gravity and atmospheric drag. */ + /* Update for secular gravity and atmospheric drag. */ - em = eo; - xinc = xincl; + em = eo; + xinc = xincl; - xmp = (double)xmo + xmdot * tsince; - xnode = xnodeo + ts * (xnodot + ts * xnodcf); - omega = omegao + omgdot * ts; + xmp = (double) xmo + xmdot * tsince; + xnode = xnodeo + ts * (xnodot + ts * xnodcf); + omega = omegao + omgdot * ts; - switch(imode) - { - case SGDP4_ZERO_ECC: - /* Not a "real" orbit but OK for fast computation searches. */ - kep->smjaxs = kep->radius = (double)aodp * XKMPER/AE; - kep->theta = fmod(PI + xnodp * tsince, TWOPI) - PI; - kep->eqinc = (double)xincl; - kep->ascn = xnodeo; + switch (imode) + { + case SGDP4_ZERO_ECC: + /* Not a "real" orbit but OK for fast computation searches. */ + kep->smjaxs = kep->radius = (double) aodp *XKMPER / AE; + kep->theta = fmod (PI + xnodp * tsince, TWOPI) - PI; + kep->eqinc = (double) xincl; + kep->ascn = xnodeo; - kep->argp = 0; - kep->ecc = 0; + kep->argp = 0; + kep->ecc = 0; - kep->rfdotk = 0; - if(withvel) - kep->rfdotk = aodp * xnodp * (XKMPER/AE*XMNPDA/86400.0); /* For km/sec */ - else - kep->rfdotk = 0; + kep->rfdotk = 0; + if (withvel) + kep->rfdotk = aodp * xnodp * (XKMPER / AE * XMNPDA / 86400.0); /* For km/sec */ + else + kep->rfdotk = 0; - return imode; + return imode; - case SGDP4_NEAR_SIMP: - tempa = (real)1.0 - ts * c1; - tempe = bstar * ts * c4; - templ = ts * ts * t2cof; - a = aodp * tempa * tempa; - e = em - tempe; - xl = xmp + omega + xnode + xnodp * templ; - break; + case SGDP4_NEAR_SIMP: + tempa = (real) 1.0 - ts * c1; + tempe = bstar * ts * c4; + templ = ts * ts * t2cof; + a = aodp * tempa * tempa; + e = em - tempe; + xl = xmp + omega + xnode + xnodp * templ; + break; - case SGDP4_NEAR_NORM: - delm = xmcof * (CUBE((real)1.0 + eta * COS(xmp)) - delmo); - temp0 = ts * omgcof + delm; - xmp += (double)temp0; - omega -= temp0; - tempa = (real)1.0 - (ts * (c1 + ts * (d2 + ts * (d3 + ts * d4)))); - tempe = bstar * (c4 * ts + c5 * (SIN(xmp) - sinXMO)); - templ = ts * ts * (t2cof + ts * (t3cof + ts * (t4cof + ts * t5cof))); - //xmp += (double)temp0; - a = aodp * tempa * tempa; - e = em - tempe; - xl = xmp + omega + xnode + xnodp * templ; - break; + case SGDP4_NEAR_NORM: + delm = xmcof * (CUBE ((real) 1.0 + eta * COS (xmp)) - delmo); + temp0 = ts * omgcof + delm; + xmp += (double) temp0; + omega -= temp0; + tempa = (real) 1.0 - (ts * (c1 + ts * (d2 + ts * (d3 + ts * d4)))); + tempe = bstar * (c4 * ts + c5 * (SIN (xmp) - sinXMO)); + templ = ts * ts * (t2cof + ts * (t3cof + ts * (t4cof + ts * t5cof))); + //xmp += (double)temp0; + a = aodp * tempa * tempa; + e = em - tempe; + xl = xmp + omega + xnode + xnodp * templ; + break; #ifndef NO_DEEP_SPACE - case SGDP4_DEEP_NORM: - case SGDP4_DEEP_RESN: - case SGDP4_DEEP_SYNC: - tempa = (real)1.0 - ts * c1; - tempe = bstar * ts * c4; - templ = ts * ts * t2cof; - xn = xnodp; + case SGDP4_DEEP_NORM: + case SGDP4_DEEP_RESN: + case SGDP4_DEEP_SYNC: + tempa = (real) 1.0 - ts * c1; + tempe = bstar * ts * c4; + templ = ts * ts * t2cof; + xn = xnodp; - SGDP4_dpsec(&xmp, &omega, &xnode, &em, &xinc, &xn, tsince); + SGDP4_dpsec (&xmp, &omega, &xnode, &em, &xinc, &xn, tsince); - a = POW(XKE / xn, TOTHRD) * tempa * tempa; - e = em - tempe; - xmam = xmp + xnodp * templ; + a = POW (XKE / xn, TOTHRD) * tempa * tempa; + e = em - tempe; + xmam = xmp + xnodp * templ; - SGDP4_dpper(&e, &xinc, &omega, &xnode, &xmam, tsince); + SGDP4_dpper (&e, &xinc, &omega, &xnode, &xmam, tsince); - if (xinc < (real)0.0) - { - xinc = (-xinc); - xnode += (real)PI; - omega -= (real)PI; - } + if (xinc < (real) 0.0) + { + xinc = (-xinc); + xnode += (real) PI; + omega -= (real) PI; + } - xl = xmam + omega + xnode; + xl = xmam + omega + xnode; - /* Re-compute the perturbed values. */ - SINCOS(xinc, &sinIO, &cosIO); + /* Re-compute the perturbed values. */ + SINCOS (xinc, &sinIO, &cosIO); - { - real theta2 = cosIO * cosIO; + { + real theta2 = cosIO * cosIO; - x3thm1 = (real)3.0 * theta2 - (real)1.0; - x1mth2 = (real)1.0 - theta2; - x7thm1 = (real)7.0 * theta2 - (real)1.0; + x3thm1 = (real) 3.0 *theta2 - (real) 1.0; + x1mth2 = (real) 1.0 - theta2; + x7thm1 = (real) 7.0 *theta2 - (real) 1.0; - /* Check for possible divide-by-zero for X/(1+cosIO) when calculating xlcof */ - temp0 = (real)1.0 + cosIO; + /* Check for possible divide-by-zero for X/(1+cosIO) when calculating xlcof */ + temp0 = (real) 1.0 + cosIO; - if(fabs(temp0) < EPS_COSIO) temp0 = (real)SIGN(EPS_COSIO, temp0); + if (fabs (temp0) < EPS_COSIO) + temp0 = (real) SIGN (EPS_COSIO, temp0); - xlcof = (real)0.125 * a3ovk2 * sinIO * - ((real)3.0 + (real)5.0 * cosIO) / temp0; + xlcof = (real) 0.125 *a3ovk2 * sinIO * + ((real) 3.0 + (real) 5.0 * cosIO) / temp0; - aycof = (real)0.25 * a3ovk2 * sinIO; - } + aycof = (real) 0.25 *a3ovk2 * sinIO; + } - break; + break; #endif /* ! NO_DEEP_SPACE */ - default: - fatal_error("sgdp4: Orbit not initialised"); - return SGDP4_ERROR; - } + default: + fatal_error ("sgdp4: Orbit not initialised"); + return SGDP4_ERROR; + } - if(a < (real)1.0) - { - fprintf(stderr, "sgdp4: Satellite %05ld crashed at %.3f (a = %.3f Earth radii)\n", Isat, ts, a); - return SGDP4_ERROR; - } + if (a < (real) 1.0) + { + fprintf (stderr, + "sgdp4: Satellite %05ld crashed at %.3f (a = %.3f Earth radii)\n", + Isat, ts, a); + return SGDP4_ERROR; + } - if(e < ECC_LIMIT_LOW) - { - fprintf(stderr, "sgdp4: Satellite %05ld modified eccentricity too low (ts = %.3f, e = %e < %e)\n", Isat, ts, e, ECC_LIMIT_LOW); - return SGDP4_ERROR; - } + if (e < ECC_LIMIT_LOW) + { + fprintf (stderr, + "sgdp4: Satellite %05ld modified eccentricity too low (ts = %.3f, e = %e < %e)\n", + Isat, ts, e, ECC_LIMIT_LOW); + return SGDP4_ERROR; + } - if(e < ECC_EPS) - { - /*fprintf(stderr, "# ecc %f at %.3f for for %05ld\n", e, ts, Isat);*/ - e = ECC_EPS; - } - else if(e > ECC_LIMIT_HIGH) - { - /*fprintf(stderr, "# ecc %f at %.3f for for %05ld\n", e, ts, Isat);*/ - e = ECC_LIMIT_HIGH; - } + if (e < ECC_EPS) + { + /*fprintf(stderr, "# ecc %f at %.3f for for %05ld\n", e, ts, Isat); */ + e = ECC_EPS; + } + else if (e > ECC_LIMIT_HIGH) + { + /*fprintf(stderr, "# ecc %f at %.3f for for %05ld\n", e, ts, Isat); */ + e = ECC_LIMIT_HIGH; + } - beta2 = (real)1.0 - e * e; + beta2 = (real) 1.0 - e * e; - /* Long period periodics */ - SINCOS(omega, &sinOMG, &cosOMG); + /* Long period periodics */ + SINCOS (omega, &sinOMG, &cosOMG); - temp0 = (real)1.0 / (a * beta2); - axn = e * cosOMG; - ayn = e * sinOMG + temp0 * aycof; - xlt = xl + temp0 * xlcof * axn; + temp0 = (real) 1.0 / (a * beta2); + axn = e * cosOMG; + ayn = e * sinOMG + temp0 * aycof; + xlt = xl + temp0 * xlcof * axn; - elsq = axn * axn + ayn * ayn; - if (elsq >= (real)1.0) - { - fprintf(stderr, "sgdp4: SQR(e) >= 1 (%.3f at tsince = %.3f for sat %05ld)\n", elsq, tsince, Isat); - return SGDP4_ERROR; - } + elsq = axn * axn + ayn * ayn; + if (elsq >= (real) 1.0) + { + fprintf (stderr, + "sgdp4: SQR(e) >= 1 (%.3f at tsince = %.3f for sat %05ld)\n", + elsq, tsince, Isat); + return SGDP4_ERROR; + } - /* Sensibility check for N-R correction. */ - kep->ecc = sqrt(elsq); + /* Sensibility check for N-R correction. */ + kep->ecc = sqrt (elsq); - /* - * Solve Kepler's equation using Newton-Raphson root solving. Here 'capu' is - * almost the "Mean anomaly", initialise the "Eccentric Anomaly" term 'epw'. - * The fmod() saves reduction of angle to +/-2pi in SINCOS() and prevents - * convergence problems. - * - * Later modified to support 2nd order NR method which saves roughly 1 iteration - * for only a couple of arithmetic operations. - */ + /* + * Solve Kepler's equation using Newton-Raphson root solving. Here 'capu' is + * almost the "Mean anomaly", initialise the "Eccentric Anomaly" term 'epw'. + * The fmod() saves reduction of angle to +/-2pi in SINCOS() and prevents + * convergence problems. + * + * Later modified to support 2nd order NR method which saves roughly 1 iteration + * for only a couple of arithmetic operations. + */ - epw = capu = fmod(xlt - xnode, TWOPI); + epw = capu = fmod (xlt - xnode, TWOPI); - maxnr = kep->ecc; + maxnr = kep->ecc; - for(ii = 0; ii < MAXI; ii++) - { - real nr, f, df; - SINCOS(epw, &sinEPW, &cosEPW); + for (ii = 0; ii < MAXI; ii++) + { + real nr, f, df; + SINCOS (epw, &sinEPW, &cosEPW); - ecosE = axn * cosEPW + ayn * sinEPW; - esinE = axn * sinEPW - ayn * cosEPW; + ecosE = axn * cosEPW + ayn * sinEPW; + esinE = axn * sinEPW - ayn * cosEPW; - f = capu - epw + esinE; - if (fabs(f) < NR_EPS) break; + f = capu - epw + esinE; + if (fabs (f) < NR_EPS) + break; - df = (real)1.0 - ecosE; + df = (real) 1.0 - ecosE; - /* 1st order Newton-Raphson correction. */ - nr = f / df; + /* 1st order Newton-Raphson correction. */ + nr = f / df; - /*Sanity check for high eccentricity failure case. */ - if (ii == 0 && FABS(nr) > (real)1.25 * maxnr) - nr = SIGN(maxnr, nr); + /*Sanity check for high eccentricity failure case. */ + if (ii == 0 && FABS (nr) > (real) 1.25 * maxnr) + nr = SIGN (maxnr, nr); #if 1 - /* 2nd order Newton-Raphson correction. */ - else - nr = f / (df + (real)0.5 * esinE*nr); /* f/(df - 0.5*d2f*f/df) */ + /* 2nd order Newton-Raphson correction. */ + else + nr = f / (df + (real) 0.5 * esinE * nr); /* f/(df - 0.5*d2f*f/df) */ #endif - epw += nr; /* Newton-Raphson correction of -F/DF. */ - } + epw += nr; /* Newton-Raphson correction of -F/DF. */ + } - /* Short period preliminary quantities */ - temp0 = (real)1.0 - elsq; - betal = SQRT(temp0); - pl = a * temp0; - r = a * ((real)1.0 - ecosE); - invR = (real)1.0 / r; - temp2 = a * invR; - temp3 = (real)1.0 / ((real)1.0 + betal); - cosu = temp2 * (cosEPW - axn + ayn * esinE * temp3); - sinu = temp2 * (sinEPW - ayn - axn * esinE * temp3); - u = ATAN2(sinu, cosu); - sin2u = (real)2.0 * sinu * cosu; - cos2u = (real)2.0 * cosu * cosu - (real)1.0; - temp0 = (real)1.0 / pl; - temp1 = CK2 * temp0; - temp2 = temp1 * temp0; + /* Short period preliminary quantities */ + temp0 = (real) 1.0 - elsq; + betal = SQRT (temp0); + pl = a * temp0; + r = a * ((real) 1.0 - ecosE); + invR = (real) 1.0 / r; + temp2 = a * invR; + temp3 = (real) 1.0 / ((real) 1.0 + betal); + cosu = temp2 * (cosEPW - axn + ayn * esinE * temp3); + sinu = temp2 * (sinEPW - ayn - axn * esinE * temp3); + u = ATAN2 (sinu, cosu); + sin2u = (real) 2.0 *sinu * cosu; + cos2u = (real) 2.0 *cosu * cosu - (real) 1.0; + temp0 = (real) 1.0 / pl; + temp1 = CK2 * temp0; + temp2 = temp1 * temp0; - /* Update for short term periodics to position terms. */ + /* Update for short term periodics to position terms. */ - rk = r * ((real)1.0 - (real)1.5 * temp2 * betal * x3thm1) + (real)0.5 * temp1 * x1mth2 * cos2u; - uk = u - (real)0.25 * temp2 * x7thm1 * sin2u; - xnodek = xnode + (real)1.5 * temp2 * cosIO * sin2u; - xinck = xinc + (real)1.5 * temp2 * cosIO * sinIO * cos2u; + rk = + r * ((real) 1.0 - (real) 1.5 * temp2 * betal * x3thm1) + + (real) 0.5 *temp1 * x1mth2 * cos2u; + uk = u - (real) 0.25 *temp2 * x7thm1 * sin2u; + xnodek = xnode + (real) 1.5 *temp2 * cosIO * sin2u; + xinck = xinc + (real) 1.5 *temp2 * cosIO * sinIO * cos2u; - if(rk < (real)1.0) - { + if (rk < (real) 1.0) + { #if 1 - fprintf(stderr, "sgdp4: Satellite %05ld crashed at %.3f (rk = %.3f Earth radii)\n", Isat, ts, rk); + fprintf (stderr, + "sgdp4: Satellite %05ld crashed at %.3f (rk = %.3f Earth radii)\n", + Isat, ts, rk); #endif - return SGDP4_ERROR; - } + return SGDP4_ERROR; + } - kep->radius = rk * XKMPER/AE; /* Into km */ - kep->theta = uk; - kep->eqinc = xinck; - kep->ascn = xnodek; - kep->argp = omega; - kep->smjaxs = a * XKMPER/AE; + kep->radius = rk * XKMPER / AE; /* Into km */ + kep->theta = uk; + kep->eqinc = xinck; + kep->ascn = xnodek; + kep->argp = omega; + kep->smjaxs = a * XKMPER / AE; - /* Short period velocity terms ?. */ - if (withvel) - { - /* xn = XKE / pow(a, 1.5); */ - temp0 = SQRT(a); - temp2 = (real)XKE / (a * temp0); + /* Short period velocity terms ?. */ + if (withvel) + { + /* xn = XKE / pow(a, 1.5); */ + temp0 = SQRT (a); + temp2 = (real) XKE / (a * temp0); - kep->rdotk = ((real)XKE * temp0 * esinE * invR - - temp2 * temp1 * x1mth2 * sin2u) * - (XKMPER/AE*XMNPDA/86400.0); /* Into km/sec */ + kep->rdotk = ((real) XKE * temp0 * esinE * invR - temp2 * temp1 * x1mth2 * sin2u) * (XKMPER / AE * XMNPDA / 86400.0); /* Into km/sec */ - kep->rfdotk = ((real)XKE * SQRT(pl) * invR + temp2 * temp1 * - (x1mth2 * cos2u + (real)1.5 * x3thm1)) * - (XKMPER/AE*XMNPDA/86400.0); - } - else - { - kep->rdotk = kep->rfdotk = 0; - } + kep->rfdotk = ((real) XKE * SQRT (pl) * invR + temp2 * temp1 * + (x1mth2 * cos2u + (real) 1.5 * x3thm1)) * + (XKMPER / AE * XMNPDA / 86400.0); + } + else + { + kep->rdotk = kep->rfdotk = 0; + } #ifndef SGDP4_SNGL #undef ts #endif -return imode; + return imode; } /* ==================================================================== @@ -752,44 +803,45 @@ return imode; ==================================================================== */ -void kep2xyz(kep_t *K, xyz_t *pos, xyz_t *vel) +void +kep2xyz (kep_t * K, xyz_t * pos, xyz_t * vel) { -real xmx, xmy; -real ux, uy, uz, vx, vy, vz; -real sinT, cosT, sinI, cosI, sinS, cosS; + real xmx, xmy; + real ux, uy, uz, vx, vy, vz; + real sinT, cosT, sinI, cosI, sinS, cosS; - /* Orientation vectors for X-Y-Z format. */ + /* Orientation vectors for X-Y-Z format. */ - SINCOS((real)K->theta, &sinT, &cosT); - SINCOS((real)K->eqinc, &sinI, &cosI); - SINCOS((real)K->ascn, &sinS, &cosS); + SINCOS ((real) K->theta, &sinT, &cosT); + SINCOS ((real) K->eqinc, &sinI, &cosI); + SINCOS ((real) K->ascn, &sinS, &cosS); - xmx = -sinS * cosI; - xmy = cosS * cosI; + xmx = -sinS * cosI; + xmy = cosS * cosI; - ux = xmx * sinT + cosS * cosT; - uy = xmy * sinT + sinS * cosT; - uz = sinI * sinT; + ux = xmx * sinT + cosS * cosT; + uy = xmy * sinT + sinS * cosT; + uz = sinI * sinT; - /* Position and velocity */ + /* Position and velocity */ - if(pos != NULL) - { - pos->x = K->radius * ux; - pos->y = K->radius * uy; - pos->z = K->radius * uz; - } + if (pos != NULL) + { + pos->x = K->radius * ux; + pos->y = K->radius * uy; + pos->z = K->radius * uz; + } - if(vel != NULL) - { - vx = xmx * cosT - cosS * sinT; - vy = xmy * cosT - sinS * sinT; - vz = sinI * cosT; + if (vel != NULL) + { + vx = xmx * cosT - cosS * sinT; + vy = xmy * cosT - sinS * sinT; + vz = sinI * cosT; - vel->x = K->rdotk * ux + K->rfdotk * vx; - vel->y = K->rdotk * uy + K->rfdotk * vy; - vel->z = K->rdotk * uz + K->rfdotk * vz; - } + vel->x = K->rdotk * ux + K->rfdotk * vx; + vel->y = K->rdotk * uy + K->rfdotk * vy; + vel->z = K->rdotk * uz + K->rfdotk * vz; + } } @@ -806,29 +858,30 @@ real sinT, cosT, sinI, cosI, sinS, cosS; ====================================================================== */ -sgdp4_mode_t satpos_xyz(double jd, xyz_t *pos, xyz_t *vel) +sgdp4_mode_t +satpos_xyz (double jd, xyz_t * pos, xyz_t * vel) { -kep_t K; -int withvel; -sgdp4_mode_t rv; -double tsince; + kep_t K; + int withvel; + sgdp4_mode_t rv; + double tsince; - tsince = (jd - SGDP4_jd0) * XMNPDA; + tsince = (jd - SGDP4_jd0) * XMNPDA; #if defined( DEBUG ) && 0 - fprintf(stderr, "Tsince = %f\n", tsince); + fprintf (stderr, "Tsince = %f\n", tsince); #endif - if(vel != NULL) - withvel = 1; - else - withvel = 0; + if (vel != NULL) + withvel = 1; + else + withvel = 0; - rv = sgdp4(tsince, withvel, &K); + rv = sgdp4 (tsince, withvel, &K); - kep2xyz(&K, pos, vel); + kep2xyz (&K, pos, vel); -return rv; + return rv; } /* ==================== End of file sgdp4.c ========================== */ diff --git a/src/sgdp4h.h b/src/sgdp4h.h index f5cdc76..288ee3d 100644 --- a/src/sgdp4h.h +++ b/src/sgdp4h.h @@ -27,14 +27,14 @@ */ #if defined( unix ) -# define UNIX -# if defined( linux ) && !defined( LINUX ) -# define LINUX -# endif +#define UNIX +#if defined( linux ) && !defined( LINUX ) +#define LINUX +#endif #elif defined( __riscos ) && !defined( RISCOS ) -# define RISCOS +#define RISCOS #elif !defined( MSDOS ) && !defined( WIN32 ) && !defined( __CYGWIN__ ) -# define MSDOS +#define MSDOS #endif /* @@ -56,13 +56,13 @@ #endif #ifdef sun -#include /* solaris 7 has struct timeval in here */ -#include /* for sincos() which is in libsunmath */ +#include /* solaris 7 has struct timeval in here */ +#include /* for sincos() which is in libsunmath */ #endif #ifdef linux #include -void sincos(double x, double *s, double *c); /* declared where? */ +void sincos (double x, double *s, double *c); /* declared where? */ #endif /* @@ -96,18 +96,18 @@ void sincos(double x, double *s, double *c); /* declared where? */ #define PI M_PI #endif -#define TWOPI (2.0*PI) /* Optimising compiler will deal with this! */ +#define TWOPI (2.0*PI) /* Optimising compiler will deal with this! */ #define PB2 (0.5*PI) #define PI180 (PI/180.0) -#define SOLAR_DAY (1440.0) /* Minutes per 24 hours */ -#define SIDERIAL_DAY (23.0*60.0 + 56.0 + 4.09054/60.0) /* Against stars */ +#define SOLAR_DAY (1440.0) /* Minutes per 24 hours */ +#define SIDERIAL_DAY (23.0*60.0 + 56.0 + 4.09054/60.0) /* Against stars */ -#define EQRAD (6378.137) /* Earth radius at equator, km */ -#define LATCON (1.0/298.257) /* Latitude radius constant */ +#define EQRAD (6378.137) /* Earth radius at equator, km */ +#define LATCON (1.0/298.257) /* Latitude radius constant */ #define ECON ((1.0-LATCON)*(1.0-LATCON)) -#define JD1900 2415020.5 /* Julian day number for Jan 1st, 00:00 hours 1900 */ +#define JD1900 2415020.5 /* Julian day number for Jan 1st, 00:00 hours 1900 */ /* @@ -126,38 +126,149 @@ void sincos(double x, double *s, double *c); /* declared where? */ /* Coordinate conversion macros */ #define DEG(x) ((x)/PI180) #define RAD(x) ((x)*PI180) -#define GEOC(x) (atan(ECON*tan(x))) /* Geographic to geocentric. */ +#define GEOC(x) (atan(ECON*tan(x))) /* Geographic to geocentric. */ #define GEOG(x) (atan(tan(x)/ECON)) /* * All other compilers can have static inline functions. * (SQR is used badly here: do_cal.c, glat2lat.c, satpos.c, vmath.h). */ -static INLINE int NINT(double a) { return (int)(a > 0 ? a+0.5 : a-0.5); } -static INLINE long NLONG(double a) { return (long)(a > 0 ? a+0.5 : a-0.5); } +static INLINE int +NINT (double a) +{ + return (int) (a > 0 ? a + 0.5 : a - 0.5); +} -static INLINE double DSQR(double a) { return(a*a); } -static INLINE float FSQR(float a) { return(a*a); } -static INLINE int ISQR(int a) { return(a*a); } +static INLINE long +NLONG (double a) +{ + return (long) (a > 0 ? a + 0.5 : a - 0.5); +} -static INLINE double DCUBE(double a) { return(a*a*a); } -static INLINE float FCUBE(float a) { return(a*a*a); } -static INLINE int ICUBE(int a) { return(a*a*a); } +static INLINE double +DSQR (double a) +{ + return (a * a); +} -static INLINE double DPOW4(double a) { a*=a; return(a*a); } -static INLINE float FPOW4(float a) { a*=a; return(a*a); } -static INLINE int IPOW4(int a) { a*=a; return(a*a); } +static INLINE float +FSQR (float a) +{ + return (a * a); +} -static INLINE double DMAX(double a,double b) { if (a>b) return a; else return b; } -static INLINE float FMAX(float a, float b) { if (a>b) return a; else return b; } -static INLINE int IMAX(int a, int b) { if (a>b) return a; else return b; } +static INLINE int +ISQR (int a) +{ + return (a * a); +} -static INLINE double DMIN(double a,double b) { if (a b) + return a; + else + return b; +} + +static INLINE float +FMAX (float a, float b) +{ + if (a > b) + return a; + else + return b; +} + +static INLINE int +IMAX (int a, int b) +{ + if (a > b) + return a; + else + return b; +} + +static INLINE double +DMIN (double a, double b) +{ + if (a < b) + return a; + else + return b; +} + +static INLINE float +FMIN (float a, float b) +{ + if (a < b) + return a; + else + return b; +} + +static INLINE int +IMIN (int a, int b) +{ + if (a < b) + return a; + else + return b; +} + +static INLINE double +MOD2PI (double a) +{ + a = fmod (a, TWOPI); + return a < 0.0 ? a + TWOPI : a; +} + +static INLINE double +MOD360 (double a) +{ + a = fmod (a, 360.0); + return a < 0.0 ? a + 360.0 : a; +} /* * Unless you have higher than default optimisation the Sun compiler @@ -173,49 +284,49 @@ static INLINE double MOD360(double a) { a=fmod(a, 360.0); return a < 0.0 ? a+ typedef struct orbit_s { - /* Add the epoch time if required. */ + /* Add the epoch time if required. */ - int ep_year;/* Year of epoch, e.g. 94 for 1994, 100 for 2000AD */ - double ep_day; /* Day of epoch from 00:00 Jan 1st ( = 1.0 ) */ - double rev; /* Mean motion, revolutions per day */ - double bstar; /* Drag term .*/ - double eqinc; /* Equatorial inclination, radians */ - double ecc; /* Eccentricity */ - double mnan; /* Mean anomaly at epoch from elements, radians */ - double argp; /* Argument of perigee, radians */ - double ascn; /* Right ascension (ascending node), radians */ - double smjaxs; /* Semi-major axis, km */ - double ndot2,nddot6; /* Mean motion derivatives */ - char desig[10]; /* International designation */ - long norb; /* Orbit number, for elements */ - int satno; /* Satellite number. */ + int ep_year; /* Year of epoch, e.g. 94 for 1994, 100 for 2000AD */ + double ep_day; /* Day of epoch from 00:00 Jan 1st ( = 1.0 ) */ + double rev; /* Mean motion, revolutions per day */ + double bstar; /* Drag term . */ + double eqinc; /* Equatorial inclination, radians */ + double ecc; /* Eccentricity */ + double mnan; /* Mean anomaly at epoch from elements, radians */ + double argp; /* Argument of perigee, radians */ + double ascn; /* Right ascension (ascending node), radians */ + double smjaxs; /* Semi-major axis, km */ + double ndot2, nddot6; /* Mean motion derivatives */ + char desig[10]; /* International designation */ + long norb; /* Orbit number, for elements */ + int satno; /* Satellite number. */ } orbit_t; typedef struct xyz_s { - double x; - double y; - double z; + double x; + double y; + double z; } xyz_t; typedef struct kep_s { - double theta; /* Angle "theta" from equatorial plane (rad) = U. */ - double ascn; /* Right ascension (rad). */ - double eqinc; /* Equatorial inclination (rad). */ - double radius; /* Radius (km). */ - double rdotk; - double rfdotk; + double theta; /* Angle "theta" from equatorial plane (rad) = U. */ + double ascn; /* Right ascension (rad). */ + double eqinc; /* Equatorial inclination (rad). */ + double radius; /* Radius (km). */ + double rdotk; + double rfdotk; - /* - * Following are without short-term perturbations but used to - * speed searches. - */ + /* + * Following are without short-term perturbations but used to + * speed searches. + */ - double argp; /* Argument of perigee at 'tsince' (rad). */ - double smjaxs; /* Semi-major axis at 'tsince' (km). */ - double ecc; /* Eccentricity at 'tsince'. */ + double argp; /* Argument of perigee at 'tsince' (rad). */ + double smjaxs; /* Semi-major axis at 'tsince' (km). */ + double ecc; /* Eccentricity at 'tsince'. */ } kep_t; @@ -237,7 +348,7 @@ typedef double real; #define SGDP4_DBLE #endif -#endif /* Single or double choice. */ +#endif /* Single or double choice. */ /* Something silly ? */ #if defined( SGDP4_SNGL ) && defined( SGDP4_DBLE ) @@ -276,8 +387,8 @@ version of these functions. #define SINCOS sincos #endif /* ! SGDP4_SNGL */ -void sincos(double, double *, double *); -void sincosf(float, float *, float *); +void sincos (double, double *, double *); +void sincosf (float, float *, float *); #else /* Sun 'C' compiler. */ @@ -307,23 +418,23 @@ void sincosf(float, float *, float *); /* ======== Macro fixes for float/double in math.h type functions. ===== */ #if defined( SGDP4_SNGL ) - #define SIN(x) sinf(x) - #define COS(x) cosf(x) - #define SQRT(x) sqrtf(x) - #define FABS(x) fabsf(x) - #define POW(x,y) powf(x, y) - #define FMOD(x,y) fmodf(x, y) - #define ATAN2(x,y) atan2f(x, y) +#define SIN(x) sinf(x) +#define COS(x) cosf(x) +#define SQRT(x) sqrtf(x) +#define FABS(x) fabsf(x) +#define POW(x,y) powf(x, y) +#define FMOD(x,y) fmodf(x, y) +#define ATAN2(x,y) atan2f(x, y) #elif defined( SGDP4_DBLE ) - #define SIN(x) sin(x) - #define COS(x) cos(x) - #define SQRT(x) sqrt(x) - #define FABS(x) fabs(x) - #define POW(x,y) pow(x, y) - #define FMOD(x,y) fmod(x, y) - #define ATAN2(x,y) atan2(x, y) +#define SIN(x) sin(x) +#define COS(x) cos(x) +#define SQRT(x) sqrt(x) +#define FABS(x) fabs(x) +#define POW(x,y) pow(x, y) +#define FMOD(x,y) fmod(x, y) +#define ATAN2(x,y) atan2(x, y) #else - #error "Incompatible choices for SGDP4_SNGL / SGDP4_DBLE" +#error "Incompatible choices for SGDP4_SNGL / SGDP4_DBLE" #endif #ifdef SGDP4_SNGL @@ -336,15 +447,16 @@ void sincosf(float, float *, float *); /* SGDP4 function return values. */ -typedef enum { - SGDP4_ERROR = (-1), - SGDP4_NOT_INIT = 0, - SGDP4_ZERO_ECC = 1, - SGDP4_NEAR_SIMP = 2, - SGDP4_NEAR_NORM = 3, - SGDP4_DEEP_NORM = 4, - SGDP4_DEEP_RESN = 5, - SGDP4_DEEP_SYNC = 6 +typedef enum +{ + SGDP4_ERROR = (-1), + SGDP4_NOT_INIT = 0, + SGDP4_ZERO_ECC = 1, + SGDP4_NEAR_SIMP = 2, + SGDP4_NEAR_NORM = 3, + SGDP4_DEEP_NORM = 4, + SGDP4_DEEP_RESN = 5, + SGDP4_DEEP_SYNC = 6 } sgdp4_mode_t; #include "satutl.h" @@ -352,30 +464,32 @@ typedef enum { /* ======================= Function prototypes ====================== */ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /** deep.c **/ -sgdp4_mode_t SGDP4_dpinit(double epoch, real omegao, real xnodeo, real xmo, - real orb_eo, real orb_xincl, real aodp, double xlldot, - real omgdot, real xnodot, double xnodp); + sgdp4_mode_t SGDP4_dpinit (double epoch, real omegao, real xnodeo, real xmo, + real orb_eo, real orb_xincl, real aodp, + double xlldot, real omgdot, real xnodot, + double xnodp); -int SGDP4_dpsec(double *xll, real *omgasm, real *xnodes, real *em, - real *xinc, double *xn, double tsince); + int SGDP4_dpsec (double *xll, real * omgasm, real * xnodes, real * em, + real * xinc, double *xn, double tsince); -int SGDP4_dpper(real *em, real *xinc, real *omgasm, real *xnodes, - double *xll, double tsince); + int SGDP4_dpper (real * em, real * xinc, real * omgasm, real * xnodes, + double *xll, double tsince); /** sgdp4.c **/ -sgdp4_mode_t init_sgdp4(orbit_t *orb); -sgdp4_mode_t sgdp4(double tsince, int withvel, kep_t *kep); -void kep2xyz(kep_t *K, xyz_t *pos, xyz_t *vel); -sgdp4_mode_t satpos_xyz(double jd, xyz_t *pos, xyz_t *vel); + sgdp4_mode_t init_sgdp4 (orbit_t * orb); + sgdp4_mode_t sgdp4 (double tsince, int withvel, kep_t * kep); + void kep2xyz (kep_t * K, xyz_t * pos, xyz_t * vel); + sgdp4_mode_t satpos_xyz (double jd, xyz_t * pos, xyz_t * vel); #ifdef __cplusplus } #endif -#endif /* !_SGDP4H_H */ +#endif /* !_SGDP4H_H */ diff --git a/src/simplex.c b/src/simplex.c index 68ac169..52aa3ad 100644 --- a/src/simplex.c +++ b/src/simplex.c @@ -2,27 +2,32 @@ #include #include -double **simplex(int n,double *a,double *da) +double ** +simplex (int n, double *a, double *da) { - int i,j; + int i, j; double **p; // Allocate pointers to rows - p=(double **) malloc(sizeof(double *) * (n+1)); + p = (double **) malloc (sizeof (double *) * (n + 1)); // Allocate rows and set pointers - for (i=0;i<=n;i++) - p[i]=(double *) malloc(sizeof(double) * (n+1)*n); + for (i = 0; i <= n; i++) + p[i] = (double *) malloc (sizeof (double) * (n + 1) * n); // Fill simplex - for (i=0;i<=n;i++) { - for (j=0;jj) p[i][j]=a[j]-da[j]; + for (i = 0; i <= n; i++) + { + for (j = 0; j < n; j++) + { + if (i < j) + p[i][j] = a[j]; + if (i == j) + p[i][j] = a[j] + da[j]; + if (i > j) + p[i][j] = a[j] - da[j]; + } } - } return p; } - diff --git a/src/slewto.c b/src/slewto.c index 666899d..45a7ca7 100644 --- a/src/slewto.c +++ b/src/slewto.c @@ -20,103 +20,112 @@ #define PORT 7624 #define IP "127.0.0.1" -struct map { - double alpha0,delta0,ra0,de0,azi0,alt0,q; +struct map +{ + double alpha0, delta0, ra0, de0, azi0, alt0, q; char orientation[LIM]; char nfd[LIM]; - char datadir[LIM],observer[32]; - double lat,lng; + char datadir[LIM], observer[32]; + double lat, lng; double mjd; - float alt,timezone; + float alt, timezone; int site_id; } m; -void usage(void) +void +usage (void) { return; } // Compute Date from Julian Day -void mjd2nfd(double mjd,char *nfd) +void +mjd2nfd (double mjd, char *nfd) { - double f,jd,dday; - int z,alpha,a,b,c,d,e; - int year,month,day,hour,min; - float sec,x; + double f, jd, dday; + int z, alpha, a, b, c, d, e; + int year, month, day, hour, min; + float sec, x; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - dday=b-d-floor(30.6001*e)+f; - if (e<14) - month=e-1; + if (z < 2299161) + a = z; else - month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (month>2) - year=c-4716; + dday = b - d - floor (30.6001 * e) + f; + if (e < 14) + month = e - 1; else - year=c-4715; + month = e - 13; - day=(int) floor(dday); - x=24.0*(dday-day); - x=3600.*fabs(x); - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - hour=x; - sec=floor(1000.0*sec)/1000.0; + if (month > 2) + year = c - 4716; + else + year = c - 4715; - sprintf(nfd,"%04d-%02d-%02dT%02d:%02d:%06.3f",year,month,day,hour,min,sec); + day = (int) floor (dday); + x = 24.0 * (dday - day); + x = 3600. * fabs (x); + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + hour = x; + sec = floor (1000.0 * sec) / 1000.0; + + sprintf (nfd, "%04d-%02d-%02dT%02d:%02d:%06.3f", year, month, day, hour, + min, sec); return; } // Send new position to telescope -void send_position(char *sra,char *sde) +void +send_position (char *sra, char *sde) { int skt; struct hostent *he; struct sockaddr_in addr; char packet[2048]; FILE *file; - float ra,de; + float ra, de; // Old packet style // sprintf(packet,"%s%s",sra,sde); // New packet style (as of 2013-08-20) - sprintf(packet,"%s%s",sra,sde); + sprintf (packet, + "%s%s", + sra, sde); // Send TCP packet - skt=socket(AF_INET,SOCK_STREAM,0); - addr.sin_family=AF_INET; - addr.sin_port=htons(PORT); - he=gethostbyname(IP); - bcopy(he->h_addr,(struct in_addr *) &addr.sin_addr,he->h_length); - if(connect(skt,(struct sockaddr *) &addr,sizeof(addr))<0) { - fprintf(stderr,"Connection refused by remote host.\n"); - return; - } - write(skt,packet,strlen(packet)); - close(skt); - + skt = socket (AF_INET, SOCK_STREAM, 0); + addr.sin_family = AF_INET; + addr.sin_port = htons (PORT); + he = gethostbyname (IP); + bcopy (he->h_addr, (struct in_addr *) &addr.sin_addr, he->h_length); + if (connect (skt, (struct sockaddr *) &addr, sizeof (addr)) < 0) + { + fprintf (stderr, "Connection refused by remote host.\n"); + return; + } + write (skt, packet, strlen (packet)); + close (skt); + // Set restart // file=fopen("/media/video/satobs/control/state.txt","w"); // if (file!=NULL) { @@ -135,347 +144,414 @@ void send_position(char *sra,char *sde) } // Get observing site -void get_site(int site_id) +void +get_site (int site_id) { - int i=0; + int i = 0; char line[LIM]; FILE *file; int id; - double lat,lng; + double lat, lng; float alt; - char abbrev[3],observer[64],filename[LIM]; + char abbrev[3], observer[64], filename[LIM]; - sprintf(filename,"%s/data/sites.txt",m.datadir); - file=fopen(filename,"r"); - if (file==NULL) { - printf("File with site information not found!\n"); - return; - } - while (fgets(line,LIM,file)!=NULL) { - // Skip - if (strstr(line,"#")!=NULL) - continue; - - // Strip newline - line[strlen(line)-1]='\0'; - - // Read data - sscanf(line,"%4d %2s %lf %lf %f", - &id,abbrev,&lat,&lng,&alt); - strcpy(observer,line+38); - - // Change to km - alt/=1000.0; - - if (id==site_id) { - m.lat=lat; - m.lng=lng; - m.alt=alt; - m.site_id=id; - strcpy(m.observer,observer); + sprintf (filename, "%s/data/sites.txt", m.datadir); + file = fopen (filename, "r"); + if (file == NULL) + { + printf ("File with site information not found!\n"); + return; } + while (fgets (line, LIM, file) != NULL) + { + // Skip + if (strstr (line, "#") != NULL) + continue; - } - fclose(file); + // Strip newline + line[strlen (line) - 1] = '\0'; + + // Read data + sscanf (line, "%4d %2s %lf %lf %f", &id, abbrev, &lat, &lng, &alt); + strcpy (observer, line + 38); + + // Change to km + alt /= 1000.0; + + if (id == site_id) + { + m.lat = lat; + m.lng = lng; + m.alt = alt; + m.site_id = id; + strcpy (m.observer, observer); + } + + } + fclose (file); return; } -void initialize(void) +void +initialize (void) { int i; char *env; // Default Map parameters - m.azi0=0; - m.alt0=90.0; + m.azi0 = 0; + m.alt0 = 90.0; - m.lat=0.0; - m.lng=0.0; - m.alt=0.0; + m.lat = 0.0; + m.lng = 0.0; + m.alt = 0.0; // Default settings - m.site_id=0; + m.site_id = 0; // Get environment variables - env=getenv("ST_DATADIR"); - if (env!=NULL) { - strcpy(m.datadir,env); - } else { - printf("ST_DATADIR environment variable not found.\n"); - } - env=getenv("ST_COSPAR"); - if (env!=NULL) { - get_site(atoi(env)); - } else { - printf("ST_COSPAR environment variable not found.\n"); - } + env = getenv ("ST_DATADIR"); + if (env != NULL) + { + strcpy (m.datadir, env); + } + else + { + printf ("ST_DATADIR environment variable not found.\n"); + } + env = getenv ("ST_COSPAR"); + if (env != NULL) + { + get_site (atoi (env)); + } + else + { + printf ("ST_COSPAR environment variable not found.\n"); + } return; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Greenwich Mean Sidereal Time -double gmst(double mjd) +double +gmst (double mjd) { - double t,gmst; + double t, gmst; - t=(mjd-51544.5)/36525.0; + t = (mjd - 51544.5) / 36525.0; - gmst=modulo(280.46061837+360.98564736629*(mjd-51544.5)+t*t*(0.000387933-t/38710000),360.0); + gmst = + modulo (280.46061837 + 360.98564736629 * (mjd - 51544.5) + + t * t * (0.000387933 - t / 38710000), 360.0); return gmst; } // Convert Sexagesimal into Decimal -double s2dec(char *s) +double +s2dec (char *s) { double x; - float deg,min,sec; + float deg, min, sec; char t[LIM]; - strcpy(t,s); + strcpy (t, s); - deg=fabs(atof(strtok(t," :"))); - min=fabs(atof(strtok(NULL," :"))); - sec=fabs(atof(strtok(NULL," :"))); + deg = fabs (atof (strtok (t, " :"))); + min = fabs (atof (strtok (NULL, " :"))); + sec = fabs (atof (strtok (NULL, " :"))); - x=(double) deg+(double) min/60.+(double) sec/3600.; - if (s[0]=='-') x= -x; + x = (double) deg + (double) min / 60. + (double) sec / 3600.; + if (s[0] == '-') + x = -x; return x; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // Present nfd -void nfd_now(char *s) +void +nfd_now (char *s) { time_t rawtime; struct tm *ptm; // Get UTC time - time(&rawtime); - ptm=gmtime(&rawtime); - - sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec); - + time (&rawtime); + ptm = gmtime (&rawtime); + + sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900, + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, + ptm->tm_sec); + return; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min,sec; - double mjd,dday; + int year, month, day, hour, min, sec; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; - mjd=date2mjd(year,month,dday); + mjd = date2mjd (year, month, dday); return mjd; } // Convert horizontal into equatorial coordinates -void horizontal2equatorial(double mjd,double azi,double alt,double *ra,double *de) +void +horizontal2equatorial (double mjd, double azi, double alt, double *ra, + double *de) { double h; - h=atan2(sin(azi*D2R),cos(azi*D2R)*sin(m.lat*D2R)+tan(alt*D2R)*cos(m.lat*D2R))*R2D; - *ra=modulo(gmst(mjd)+m.lng-h,360.0); - *de=asin(sin(m.lat*D2R)*sin(alt*D2R)-cos(m.lat*D2R)*cos(alt*D2R)*cos(azi*D2R))*R2D; - if (*ra<0.0) - *ra+=360.0; + h = + atan2 (sin (azi * D2R), + cos (azi * D2R) * sin (m.lat * D2R) + + tan (alt * D2R) * cos (m.lat * D2R)) * R2D; + *ra = modulo (gmst (mjd) + m.lng - h, 360.0); + *de = + asin (sin (m.lat * D2R) * sin (alt * D2R) - + cos (m.lat * D2R) * cos (alt * D2R) * cos (azi * D2R)) * R2D; + if (*ra < 0.0) + *ra += 360.0; return; } // Convert equatorial into horizontal coordinates -void equatorial2horizontal(double mjd,double ra,double de,double *azi,double *alt) +void +equatorial2horizontal (double mjd, double ra, double de, double *azi, + double *alt) { double h; - h=gmst(mjd)+m.lng-ra; - - *azi=modulo(atan2(sin(h*D2R),cos(h*D2R)*sin(m.lat*D2R)-tan(de*D2R)*cos(m.lat*D2R))*R2D,360.0); - *alt=asin(sin(m.lat*D2R)*sin(de*D2R)+cos(m.lat*D2R)*cos(de*D2R)*cos(h*D2R))*R2D; + h = gmst (mjd) + m.lng - ra; + + *azi = + modulo (atan2 + (sin (h * D2R), + cos (h * D2R) * sin (m.lat * D2R) - + tan (de * D2R) * cos (m.lat * D2R)) * R2D, 360.0); + *alt = + asin (sin (m.lat * D2R) * sin (de * D2R) + + cos (m.lat * D2R) * cos (de * D2R) * cos (h * D2R)) * R2D; return; } -double parallactic_angle(double mjd,double ra,double de) +double +parallactic_angle (double mjd, double ra, double de) { - double h,q; + double h, q; - h=gmst(mjd)+m.lng-ra; + h = gmst (mjd) + m.lng - ra; - q=atan2(sin(h*D2R),(tan(m.lat*D2R)*cos(de*D2R)-sin(de*D2R)*cos(h*D2R)))*R2D; + q = + atan2 (sin (h * D2R), + (tan (m.lat * D2R) * cos (de * D2R) - + sin (de * D2R) * cos (h * D2R))) * R2D; return q; } // Convert Decimal into Sexagesimal -void dec2s(double x,char *s,int f,int len) +void +dec2s (double x, char *s, int f, int len) { int i; - double sec,deg,min; + double sec, deg, min; char sign; - char *form[]={"::",",,","hms"," "}; + char *form[] = { "::", ",,", "hms", " " }; - sign=(x<0 ? '-' : ' '); - x=3600.*fabs(x); + sign = (x < 0 ? '-' : ' '); + x = 3600. * fabs (x); - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; // deg=fmod(x,60.); - deg=x; + deg = x; - if (len==7) sprintf(s,"%c%02i%c%02i%c%07.4f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]); - if (len==6) sprintf(s,"%c%02i%c%02i%c%06.3f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]); - if (len==5) sprintf(s,"%c%02i%c%02i%c%05.2f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]); - if (len==4) sprintf(s,"%c%02i%c%02i%c%04.1f%c",sign,(int) deg,form[f][0],(int) min,form[f][1],sec,form[f][2]); - if (len==2) sprintf(s,"%c%02i%c%02i%c%02i%c",sign,(int) deg,form[f][0],(int) min,form[f][1],(int) floor(sec),form[f][2]); + if (len == 7) + sprintf (s, "%c%02i%c%02i%c%07.4f%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], sec, form[f][2]); + if (len == 6) + sprintf (s, "%c%02i%c%02i%c%06.3f%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], sec, form[f][2]); + if (len == 5) + sprintf (s, "%c%02i%c%02i%c%05.2f%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], sec, form[f][2]); + if (len == 4) + sprintf (s, "%c%02i%c%02i%c%04.1f%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], sec, form[f][2]); + if (len == 2) + sprintf (s, "%c%02i%c%02i%c%02i%c", sign, (int) deg, form[f][0], + (int) min, form[f][1], (int) floor (sec), form[f][2]); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int arg=0,haflag=0,dry=0; - char sra[16],sde[16]; + int arg = 0, haflag = 0, dry = 0; + char sra[16], sde[16]; double ha; FILE *file; // Initialize - initialize(); + initialize (); // Get time - nfd_now(m.nfd); - m.mjd=nfd2mjd(m.nfd); + nfd_now (m.nfd); + m.mjd = nfd2mjd (m.nfd); - // Decode options - while ((arg=getopt(argc,argv,"m:t:H:R:D:A:E:hn"))!=-1) { - switch(arg) { + // Decode options + while ((arg = getopt (argc, argv, "m:t:H:R:D:A:E:hn")) != -1) + { + switch (arg) + { - case 'n': - dry=1; - break; + case 'n': + dry = 1; + break; - case 't': - strcpy(m.nfd,optarg); - m.mjd=nfd2mjd(m.nfd); - break; + case 't': + strcpy (m.nfd, optarg); + m.mjd = nfd2mjd (m.nfd); + break; - case 'm': - m.mjd=atof(optarg); - mjd2nfd(m.mjd,m.nfd); - break; + case 'm': + m.mjd = atof (optarg); + mjd2nfd (m.mjd, m.nfd); + break; - case 'H': - ha=atof(optarg); - haflag=1; - strcpy(m.orientation,"equatorial"); - break; + case 'H': + ha = atof (optarg); + haflag = 1; + strcpy (m.orientation, "equatorial"); + break; - case 'R': - m.ra0=15.0*s2dec(optarg); - strcpy(m.orientation,"equatorial"); - break; + case 'R': + m.ra0 = 15.0 * s2dec (optarg); + strcpy (m.orientation, "equatorial"); + break; - case 'D': - m.de0=s2dec(optarg); - strcpy(m.orientation,"equatorial"); - break; + case 'D': + m.de0 = s2dec (optarg); + strcpy (m.orientation, "equatorial"); + break; - case 'A': - m.azi0=modulo(atof(optarg)+180.0,360.0); - strcpy(m.orientation,"horizontal"); - break; + case 'A': + m.azi0 = modulo (atof (optarg) + 180.0, 360.0); + strcpy (m.orientation, "horizontal"); + break; - case 'E': - m.alt0=atof(optarg); - strcpy(m.orientation,"horizontal"); - break; + case 'E': + m.alt0 = atof (optarg); + strcpy (m.orientation, "horizontal"); + break; - case 'h': - usage(); - return 0; - break; + case 'h': + usage (); + return 0; + break; - default: - usage(); - return 0; + default: + usage (); + return 0; + } } - } // Compute RA from HA - if (haflag==1) { - m.ra0=modulo(gmst(m.mjd)+m.lng-ha,360.0); - } else { - ha=modulo(gmst(m.mjd)+m.lng-m.ra0,360.0); - if (ha>180.0) - ha-=360.0; - } + if (haflag == 1) + { + m.ra0 = modulo (gmst (m.mjd) + m.lng - ha, 360.0); + } + else + { + ha = modulo (gmst (m.mjd) + m.lng - m.ra0, 360.0); + if (ha > 180.0) + ha -= 360.0; + } // Compute RA and Dec - if (strcmp(m.orientation,"horizontal")==0) - horizontal2equatorial(m.mjd,m.azi0,m.alt0,&m.ra0,&m.de0); - else if (strcmp(m.orientation,"equatorial")==0) - equatorial2horizontal(m.mjd,m.ra0,m.de0,&m.azi0,&m.alt0); + if (strcmp (m.orientation, "horizontal") == 0) + horizontal2equatorial (m.mjd, m.azi0, m.alt0, &m.ra0, &m.de0); + else if (strcmp (m.orientation, "equatorial") == 0) + equatorial2horizontal (m.mjd, m.ra0, m.de0, &m.azi0, &m.alt0); // Parallactic angle - m.q=parallactic_angle(m.mjd,m.ra0,m.de0); + m.q = parallactic_angle (m.mjd, m.ra0, m.de0); // Get sexagesimal - dec2s(m.ra0/15.0,sra,0,5); - dec2s(m.de0,sde,0,4); + dec2s (m.ra0 / 15.0, sra, 0, 5); + dec2s (m.de0, sde, 0, 4); // Print to screen - printf("%s R:%s D: %s H: %7.3f A: %6.3f E: %6.3f q: %5.2f\n",m.nfd,sra,sde,ha,modulo(m.azi0-180.0,360.0),m.alt0,m.q); + printf ("%s R:%s D: %s H: %7.3f A: %6.3f E: %6.3f q: %5.2f\n", m.nfd, sra, + sde, ha, modulo (m.azi0 - 180.0, 360.0), m.alt0, m.q); - if (dry==0) { - // Send position - send_position(sra,sde); - - // Log - file=fopen("position.txt","a"); - fprintf(file,"%s %lf %lf %f\n",m.nfd,m.ra0,m.de0,m.q); - fclose(file); - } + if (dry == 0) + { + // Send position + send_position (sra, sde); + + // Log + file = fopen ("position.txt", "a"); + fprintf (file, "%s %lf %lf %f\n", m.nfd, m.ra0, m.de0, m.q); + fclose (file); + } return 0; } diff --git a/src/stviewer.c b/src/stviewer.c index 7df2eb0..8cd4f42 100644 --- a/src/stviewer.c +++ b/src/stviewer.c @@ -10,246 +10,282 @@ #define D2R M_PI/180.0 #define R2D 180.0/M_PI -struct image { +struct image +{ char filename[64]; - int naxis1,naxis2,naxis3,nframes; - float *zavg,*zstd,*zmax,*znum,*ztrk; - double ra0,de0; - float x0,y0; - float a[3],b[3],xrms,yrms; + int naxis1, naxis2, naxis3, nframes; + float *zavg, *zstd, *zmax, *znum, *ztrk; + double ra0, de0; + float x0, y0; + float a[3], b[3], xrms, yrms; double mjd; - float *dt,exptime; + float *dt, exptime; char nfd[32]; int cospar; }; -struct image read_fits(char *filename); -void write_composite_pgm(char *filename,struct image img); -void write_pgm(char *filename,struct image img); +struct image read_fits (char *filename); +void write_composite_pgm (char *filename, struct image img); +void write_pgm (char *filename, struct image img); -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { int i; struct image img; - img=read_fits(argv[1]); + img = read_fits (argv[1]); - write_composite_pgm("avg.pgm",img); - write_pgm("f1.pgm",img); + write_composite_pgm ("avg.pgm", img); + write_pgm ("f1.pgm", img); return 0; } // Read fits image -struct image read_fits(char *filename) +struct image +read_fits (char *filename) { - int i,j,k,l,m; + int i, j, k, l, m; qfitsloader ql; - char key[FITS_LINESZ+1]; - char val[FITS_LINESZ+1]; + char key[FITS_LINESZ + 1]; + char val[FITS_LINESZ + 1]; struct image img; // Copy filename - strcpy(img.filename,filename); + strcpy (img.filename, filename); // Image size - img.naxis1=atoi(qfits_query_hdr(filename,"NAXIS1")); - img.naxis2=atoi(qfits_query_hdr(filename,"NAXIS2")); - img.naxis3=atoi(qfits_query_hdr(filename,"NAXIS3")); + img.naxis1 = atoi (qfits_query_hdr (filename, "NAXIS1")); + img.naxis2 = atoi (qfits_query_hdr (filename, "NAXIS2")); + img.naxis3 = atoi (qfits_query_hdr (filename, "NAXIS3")); // MJD - img.mjd=(double) atof(qfits_query_hdr(filename,"MJD-OBS")); - strcpy(img.nfd,qfits_query_hdr(filename,"DATE-OBS")); + img.mjd = (double) atof (qfits_query_hdr (filename, "MJD-OBS")); + strcpy (img.nfd, qfits_query_hdr (filename, "DATE-OBS")); // COSPAR ID - img.cospar=atoi(qfits_query_hdr(filename,"COSPAR")); + img.cospar = atoi (qfits_query_hdr (filename, "COSPAR")); // Transformation - img.mjd=atof(qfits_query_hdr(filename,"MJD-OBS")); - img.ra0=atof(qfits_query_hdr(filename,"CRVAL1")); - img.de0=atof(qfits_query_hdr(filename,"CRVAL2")); - img.x0=atof(qfits_query_hdr(filename,"CRPIX1")); - img.y0=atof(qfits_query_hdr(filename,"CRPIX2")); - img.a[0]=0.0; - img.a[1]=3600.0*atof(qfits_query_hdr(filename,"CD1_1")); - img.a[2]=3600.0*atof(qfits_query_hdr(filename,"CD1_2")); - img.b[0]=0.0; - img.b[1]=3600.0*atof(qfits_query_hdr(filename,"CD2_1")); - img.b[2]=3600.0*atof(qfits_query_hdr(filename,"CD2_2")); - img.xrms=3600.0*atof(qfits_query_hdr(filename,"CRRES1")); - img.yrms=3600.0*atof(qfits_query_hdr(filename,"CRRES2")); - img.exptime=atof(qfits_query_hdr(filename,"EXPTIME")); - img.nframes=atoi(qfits_query_hdr(filename,"NFRAMES")); + img.mjd = atof (qfits_query_hdr (filename, "MJD-OBS")); + img.ra0 = atof (qfits_query_hdr (filename, "CRVAL1")); + img.de0 = atof (qfits_query_hdr (filename, "CRVAL2")); + img.x0 = atof (qfits_query_hdr (filename, "CRPIX1")); + img.y0 = atof (qfits_query_hdr (filename, "CRPIX2")); + img.a[0] = 0.0; + img.a[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_1")); + img.a[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD1_2")); + img.b[0] = 0.0; + img.b[1] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_1")); + img.b[2] = 3600.0 * atof (qfits_query_hdr (filename, "CD2_2")); + img.xrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES1")); + img.yrms = 3600.0 * atof (qfits_query_hdr (filename, "CRRES2")); + img.exptime = atof (qfits_query_hdr (filename, "EXPTIME")); + img.nframes = atoi (qfits_query_hdr (filename, "NFRAMES")); // Timestamps - img.dt=(float *) malloc(sizeof(float)*img.nframes); - for (i=0;i=255.0) - z=255.0; - if (z<0.0) - z=0.0; - buffer[l++]=(unsigned char) z; + for (j = 0, l = 0; j < img.naxis2; j++) + { + for (i = 0; i < img.naxis1; i++) + { + k = i + (img.naxis2 - j - 1) * img.naxis1; + z = 255.0 * (img.zavg[k] - zavgmin) / (zavgmax - zavgmin); + if (z >= 255.0) + z = 255.0; + if (z < 0.0) + z = 0.0; + buffer[l++] = (unsigned char) z; + } + for (i = 0; i < img.naxis1; i++) + { + k = i + (img.naxis2 - j - 1) * img.naxis1; + z = 255.0 * (img.zstd[k] - zstdmin) / (zstdmax - zstdmin); + if (z >= 255.0) + z = 255.0; + if (z < 0.0) + z = 0.0; + buffer[l++] = (unsigned char) z; + } } - for (i=0;i=255.0) - z=255.0; - if (z<0.0) - z=0.0; - buffer[l++]=(unsigned char) z; + for (j = 0; j < img.naxis2; j++) + { + for (i = 0; i < img.naxis1; i++) + { + k = i + (img.naxis2 - j - 1) * img.naxis1; + z = 255 * (img.zmax[k] - zmaxmin) / (zmaxmax - zmaxmin); + if (z >= 255.0) + z = 255.0; + if (z < 0.0) + z = 0.0; + buffer[l++] = (unsigned char) z; + } + for (i = 0; i < img.naxis1; i++) + { + k = i + (img.naxis2 - j - 1) * img.naxis1; + z = img.znum[k]; + if (z >= 255.0) + z = 255.0; + if (z < 0.0) + z = 0.0; + buffer[l++] = (unsigned char) z; + } } - } - for (j=0;j=255.0) - z=255.0; - if (z<0.0) - z=0.0; - buffer[l++]=(unsigned char) z; - } - for (i=0;i=255.0) - z=255.0; - if (z<0.0) - z=0.0; - buffer[l++]=(unsigned char) z; - } - } - file=fopen(filename,"wb"); - fprintf(file,"P5\n%d %d\n255\n",2*img.naxis1,2*img.naxis2); - fwrite(buffer,4*n,sizeof(unsigned char),file); - fclose(file); + file = fopen (filename, "wb"); + fprintf (file, "P5\n%d %d\n255\n", 2 * img.naxis1, 2 * img.naxis2); + fwrite (buffer, 4 * n, sizeof (unsigned char), file); + fclose (file); return; } // Write pgm file -void write_pgm(char *filename,struct image img) +void +write_pgm (char *filename, struct image img) { - int i,j,k,n; + int i, j, k, n; FILE *file; - float s1,s2,z,avg,std,zavgmin,zavgmax; + float s1, s2, z, avg, std, zavgmin, zavgmax; - n=img.naxis1*img.naxis2; - for (i=0,s1=0.0,s2=0.0;i255.0) - z=255.0; - if (z<0.0) - z=0.0; - fprintf(file,"%c",(unsigned char) z); + n = img.naxis1 * img.naxis2; + for (i = 0, s1 = 0.0, s2 = 0.0; i < n; i++) + { + z = img.zavg[i]; + s1 += z; + s2 += z * z; } - } - fclose(file); + avg = s1 / (float) n; + std = sqrt (s2 / (float) n - avg * avg); + zavgmin = avg - 2 * std; + zavgmax = avg + 3 * std; + + file = fopen (filename, "w"); + fprintf (file, "P5\n# %.23s\n%d %d\n255\n", img.nfd + 1, img.naxis1, + img.naxis2); + for (j = 0; j < img.naxis2; j++) + { + for (i = 0; i < img.naxis1; i++) + { + k = i + (img.naxis2 - j - 1) * img.naxis1; + z = 255.0 * (img.zavg[k] - zavgmin) / (zavgmax - zavgmin); + if (z > 255.0) + z = 255.0; + if (z < 0.0) + z = 0.0; + fprintf (file, "%c", (unsigned char) z); + } + } + fclose (file); return; } diff --git a/src/tle2ole.c b/src/tle2ole.c index fce7534..a59ebbc 100644 --- a/src/tle2ole.c +++ b/src/tle2ole.c @@ -6,11 +6,12 @@ #define LIM 256 // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; + int c, i = 0; - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; // if (c == '\n') // s[i++] = c; @@ -18,54 +19,65 @@ int fgetline(FILE *file,char *s,int lim) return i; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int reverse=0; - char line[LIM],pline[LIM],tlefile[LIM]; - char line0[70],line1[70],line2[70]; + int reverse = 0; + char line[LIM], pline[LIM], tlefile[LIM]; + char line0[70], line1[70], line2[70]; FILE *file; - int arg=0; + int arg = 0; // Decode options - while ((arg=getopt(argc,argv,"c:rh"))!=-1) { - switch(arg) { + while ((arg = getopt (argc, argv, "c:rh")) != -1) + { + switch (arg) + { - case 'c': - strcpy(tlefile,optarg); - break; + case 'c': + strcpy (tlefile, optarg); + break; - case 'r': - reverse=1; - break; + case 'r': + reverse = 1; + break; - case 'h': - default: - printf("-c \n-r reverse\n"); - return 0; + case 'h': + default: + printf ("-c \n-r reverse\n"); + return 0; + } } - } - if (reverse==0) { - file=fopen(tlefile,"r"); - while (fgetline(file,line,LIM)>0) { - if (line[0]=='1') { - strcpy(line0,pline); - strcpy(line1,line); - fgetline(file,line,LIM); - strcpy(line2,line); - printf("%s | %s | %s\n",line1,line2,line0); - } else { - strcpy(pline,line); - } + if (reverse == 0) + { + file = fopen (tlefile, "r"); + while (fgetline (file, line, LIM) > 0) + { + if (line[0] == '1') + { + strcpy (line0, pline); + strcpy (line1, line); + fgetline (file, line, LIM); + strcpy (line2, line); + printf ("%s | %s | %s\n", line1, line2, line0); + } + else + { + strcpy (pline, line); + } + } + fclose (file); } - fclose(file); - } else { - file=fopen(tlefile,"r"); - while (fgetline(file,line,LIM)>0) { - printf("%.70s\n%.70s\n%.70s\n",line+144,line,line+72); + else + { + file = fopen (tlefile, "r"); + while (fgetline (file, line, LIM) > 0) + { + printf ("%.70s\n%.70s\n%.70s\n", line + 144, line, line + 72); + } + fclose (file); } - fclose(file); - } return 0; } diff --git a/src/tle2rv.c b/src/tle2rv.c index 21a81c1..a361ae3 100644 --- a/src/tle2rv.c +++ b/src/tle2rv.c @@ -8,7 +8,7 @@ #define LIM 128 -#define XKE 0.07436680 // Guassian Gravitational Constant +#define XKE 0.07436680 // Guassian Gravitational Constant #define XKMPER 6378.135 #define AE 1.0 #define XMNPDA 1440.0 @@ -18,573 +18,629 @@ extern double SGDP4_jd0; // Nutation series -static const struct { - int nm1,nm,nf,nd,nn; - double s,st; - double c,ct; -} nut[]={ - { 0, 0, 0, 0, 1, -171996.0, -174.2, 92025.0, 8.9 }, - { 0, 0, 0, 0, 2, 2062.0, 0.2, -895.0, 0.5 }, - { -2, 0, 2, 0, 1, 46.0, 0.0, -24.0, 0.0 }, - { 2, 0, -2, 0, 0, 11.0, 0.0, 0.0, 0.0 }, - { -2, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0 }, - { 1, -1, 0, -1, 0, -3.0, 0.0, 0.0, 0.0 }, - { 0, -2, 2, -2, 1, -2.0, 0.0, 1.0, 0.0 }, - { 2, 0, -2, 0, 1, 1.0, 0.0, 0.0, 0.0 }, - { 0, 0, 2, -2, 2, -13187.0, -1.6, 5736.0, -3.1 }, - { 0, 1, 0, 0, 0, 1426.0, -3.4, 54.0, -0.1 }, - { 0, 1, 2, -2, 2, -517.0, 1.2, 224.0, -0.6 }, - { 0, -1, 2, -2, 2, 217.0, -0.5, -95.0, 0.3 }, - { 0, 0, 2, -2, 1, 129.0, 0.1, -70.0, 0.0 }, - { 2, 0, 0, -2, 0, 48.0, 0.0, 1.0, 0.0 }, - { 0, 0, 2, -2, 0, -22.0, 0.0, 0.0, 0.0 }, - { 0, 2, 0, 0, 0, 17.0, -0.1, 0.0, 0.0 }, - { 0, 1, 0, 0, 1, -15.0, 0.0, 9.0, 0.0 }, - { 0, 2, 2, -2, 2, -16.0, 0.1, 7.0, 0.0 }, - { 0, -1, 0, 0, 1, -12.0, 0.0, 6.0, 0.0 }, - { -2, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0 }, - { 0, -1, 2, -2, 1, -5.0, 0.0, 3.0, 0.0 }, - { 2, 0, 0, -2, 1, 4.0, 0.0, -2.0, 0.0 }, - { 0, 1, 2, -2, 1, 4.0, 0.0, -2.0, 0.0 }, - { 1, 0, 0, -1, 0, -4.0, 0.0, 0.0, 0.0 }, - { 2, 1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0 }, - { 0, 0, -2, 2, 1, 1.0, 0.0, 0.0, 0.0 }, - { 0, 1, -2, 2, 0, -1.0, 0.0, 0.0, 0.0 }, - { 0, 1, 0, 0, 2, 1.0, 0.0, 0.0, 0.0 }, - { -1, 0, 0, 1, 1, 1.0, 0.0, 0.0, 0.0 }, - { 0, 1, 2, -2, 0, -1.0, 0.0, 0.0, 0.0 }, - { 0, 0, 2, 0, 2, -2274.0, -0.2, 977.0, -0.5 }, - { 1, 0, 0, 0, 0, 712.0, 0.1, -7.0, 0.0 }, - { 0, 0, 2, 0, 1, -386.0, -0.4, 200.0, 0.0 }, - { 1, 0, 2, 0, 2, -301.0, 0.0, 129.0, -0.1 }, - { 1, 0, 0, -2, 0, -158.0, 0.0, -1.0, 0.0 }, - { -1, 0, 2, 0, 2, 123.0, 0.0, -53.0, 0.0 }, - { 0, 0, 0, 2, 0, 63.0, 0.0, -2.0, 0.0 }, - { 1, 0, 0, 0, 1, 63.0, 0.1, -33.0, 0.0 }, - { -1, 0, 0, 0, 1, -58.0, -0.1, 32.0, 0.0 }, - { -1, 0, 2, 2, 2, -59.0, 0.0, 26.0, 0.0 }, - { 1, 0, 2, 0, 1, -51.0, 0.0, 27.0, 0.0 }, - { 0, 0, 2, 2, 2, -38.0, 0.0, 16.0, 0.0 }, - { 2, 0, 0, 0, 0, 29.0, 0.0, -1.0, 0.0 }, - { 1, 0, 2, -2, 2, 29.0, 0.0, -12.0, 0.0 }, - { 2, 0, 2, 0, 2, -31.0, 0.0, 13.0, 0.0 }, - { 0, 0, 2, 0, 0, 26.0, 0.0, -1.0, 0.0 }, - { -1, 0, 2, 0, 1, 21.0, 0.0, -10.0, 0.0 }, - { -1, 0, 0, 2, 1, 16.0, 0.0, -8.0, 0.0 }, - { 1, 0, 0, -2, 1, -13.0, 0.0, 7.0, 0.0 }, - { -1, 0, 2, 2, 1, -10.0, 0.0, 5.0, 0.0 }, - { 1, 1, 0, -2, 0, -7.0, 0.0, 0.0, 0.0 }, - { 0, 1, 2, 0, 2, 7.0, 0.0, -3.0, 0.0 }, - { 0, -1, 2, 0, 2, -7.0, 0.0, 3.0, 0.0 }, - { 1, 0, 2, 2, 2, -8.0, 0.0, 3.0, 0.0 }, - { 1, 0, 0, 2, 0, 6.0, 0.0, 0.0, 0.0 }, - { 2, 0, 2, -2, 2, 6.0, 0.0, -3.0, 0.0 }, - { 0, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0 }, - { 0, 0, 2, 2, 1, -7.0, 0.0, 3.0, 0.0 }, - { 1, 0, 2, -2, 1, 6.0, 0.0, -3.0, 0.0 }, - { 0, 0, 0, -2, 1, -5.0, 0.0, 3.0, 0.0 }, - { 1, -1, 0, 0, 0, 5.0, 0.0, 0.0, 0.0 }, - { 2, 0, 2, 0, 1, -5.0, 0.0, 3.0, 0.0 }, - { 0, 1, 0, -2, 0, -4.0, 0.0, 0.0, 0.0 }, - { 1, 0, -2, 0, 0, 4.0, 0.0, 0.0, 0.0 }, - { 0, 0, 0, 1, 0, -4.0, 0.0, 0.0, 0.0 }, - { 1, 1, 0, 0, 0, -3.0, 0.0, 0.0, 0.0 }, - { 1, 0, 2, 0, 0, 3.0, 0.0, 0.0, 0.0 }, - { 1, -1, 2, 0, 2, -3.0, 0.0, 1.0, 0.0 }, - { -1, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0 }, - { -2, 0, 0, 0, 1, -2.0, 0.0, 1.0, 0.0 }, - { 3, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0 }, - { 0, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0 }, - { 1, 1, 2, 0, 2, 2.0, 0.0, -1.0, 0.0 }, - { -1, 0, 2, -2, 1, -2.0, 0.0, 1.0, 0.0 }, - { 2, 0, 0, 0, 1, 2.0, 0.0, -1.0, 0.0 }, - { 1, 0, 0, 0, 2, -2.0, 0.0, 1.0, 0.0 }, - { 3, 0, 0, 0, 0, 2.0, 0.0, 0.0, 0.0 }, - { 0, 0, 2, 1, 2, 2.0, 0.0, -1.0, 0.0 }, - { -1, 0, 0, 0, 2, 1.0, 0.0, -1.0, 0.0 }, - { 1, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0 }, - { -2, 0, 2, 2, 2, 1.0, 0.0, -1.0, 0.0 }, - { -1, 0, 2, 4, 2, -2.0, 0.0, 1.0, 0.0 }, - { 2, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0 }, - { 1, 1, 2, -2, 2, 1.0, 0.0, -1.0, 0.0 }, - { 1, 0, 2, 2, 1, -1.0, 0.0, 1.0, 0.0 }, - { -2, 0, 2, 4, 2, -1.0, 0.0, 1.0, 0.0 }, - { -1, 0, 4, 0, 2, 1.0, 0.0, 0.0, 0.0 }, - { 1, -1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0 }, - { 2, 0, 2, -2, 1, 1.0, 0.0, -1.0, 0.0 }, - { 2, 0, 2, 2, 2, -1.0, 0.0, 0.0, 0.0 }, - { 1, 0, 0, 2, 1, -1.0, 0.0, 0.0, 0.0 }, - { 0, 0, 4, -2, 2, 1.0, 0.0, 0.0, 0.0 }, - { 3, 0, 2, -2, 2, 1.0, 0.0, 0.0, 0.0 }, - { 1, 0, 2, -2, 0, -1.0, 0.0, 0.0, 0.0 }, - { 0, 1, 2, 0, 1, 1.0, 0.0, 0.0, 0.0 }, - { -1, -1, 0, 2, 1, 1.0, 0.0, 0.0, 0.0 }, - { 0, 0, -2, 0, 1, -1.0, 0.0, 0.0, 0.0 }, - { 0, 0, 2, -1, 2, -1.0, 0.0, 0.0, 0.0 }, - { 0, 1, 0, 2, 0, -1.0, 0.0, 0.0, 0.0 }, - { 1, 0, -2, -2, 0, -1.0, 0.0, 0.0, 0.0 }, - { 0, -1, 2, 0, 1, -1.0, 0.0, 0.0, 0.0 }, - { 1, 1, 0, -2, 1, -1.0, 0.0, 0.0, 0.0 }, - { 1, 0, -2, 2, 0, -1.0, 0.0, 0.0, 0.0 }, - { 2, 0, 0, 2, 0, 1.0, 0.0, 0.0, 0.0 }, - { 0, 0, 2, 4, 2, -1.0, 0.0, 0.0, 0.0 }, - { 0, 1, 0, 1, 0, 1.0, 0.0, 0.0, 0.0 } +static const struct +{ + int nm1, nm, nf, nd, nn; + double s, st; + double c, ct; +} nut[] = { + {0, 0, 0, 0, 1, -171996.0, -174.2, 92025.0, 8.9}, + {0, 0, 0, 0, 2, 2062.0, 0.2, -895.0, 0.5}, + {-2, 0, 2, 0, 1, 46.0, 0.0, -24.0, 0.0}, + {2, 0, -2, 0, 0, 11.0, 0.0, 0.0, 0.0}, + {-2, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0}, + {1, -1, 0, -1, 0, -3.0, 0.0, 0.0, 0.0}, + {0, -2, 2, -2, 1, -2.0, 0.0, 1.0, 0.0}, + {2, 0, -2, 0, 1, 1.0, 0.0, 0.0, 0.0}, + {0, 0, 2, -2, 2, -13187.0, -1.6, 5736.0, -3.1}, + {0, 1, 0, 0, 0, 1426.0, -3.4, 54.0, -0.1}, + {0, 1, 2, -2, 2, -517.0, 1.2, 224.0, -0.6}, + {0, -1, 2, -2, 2, 217.0, -0.5, -95.0, 0.3}, + {0, 0, 2, -2, 1, 129.0, 0.1, -70.0, 0.0}, + {2, 0, 0, -2, 0, 48.0, 0.0, 1.0, 0.0}, + {0, 0, 2, -2, 0, -22.0, 0.0, 0.0, 0.0}, + {0, 2, 0, 0, 0, 17.0, -0.1, 0.0, 0.0}, + {0, 1, 0, 0, 1, -15.0, 0.0, 9.0, 0.0}, + {0, 2, 2, -2, 2, -16.0, 0.1, 7.0, 0.0}, + {0, -1, 0, 0, 1, -12.0, 0.0, 6.0, 0.0}, + {-2, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0}, + {0, -1, 2, -2, 1, -5.0, 0.0, 3.0, 0.0}, + {2, 0, 0, -2, 1, 4.0, 0.0, -2.0, 0.0}, + {0, 1, 2, -2, 1, 4.0, 0.0, -2.0, 0.0}, + {1, 0, 0, -1, 0, -4.0, 0.0, 0.0, 0.0}, + {2, 1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0}, + {0, 0, -2, 2, 1, 1.0, 0.0, 0.0, 0.0}, + {0, 1, -2, 2, 0, -1.0, 0.0, 0.0, 0.0}, + {0, 1, 0, 0, 2, 1.0, 0.0, 0.0, 0.0}, + {-1, 0, 0, 1, 1, 1.0, 0.0, 0.0, 0.0}, + {0, 1, 2, -2, 0, -1.0, 0.0, 0.0, 0.0}, + {0, 0, 2, 0, 2, -2274.0, -0.2, 977.0, -0.5}, + {1, 0, 0, 0, 0, 712.0, 0.1, -7.0, 0.0}, + {0, 0, 2, 0, 1, -386.0, -0.4, 200.0, 0.0}, + {1, 0, 2, 0, 2, -301.0, 0.0, 129.0, -0.1}, + {1, 0, 0, -2, 0, -158.0, 0.0, -1.0, 0.0}, + {-1, 0, 2, 0, 2, 123.0, 0.0, -53.0, 0.0}, + {0, 0, 0, 2, 0, 63.0, 0.0, -2.0, 0.0}, + {1, 0, 0, 0, 1, 63.0, 0.1, -33.0, 0.0}, + {-1, 0, 0, 0, 1, -58.0, -0.1, 32.0, 0.0}, + {-1, 0, 2, 2, 2, -59.0, 0.0, 26.0, 0.0}, + {1, 0, 2, 0, 1, -51.0, 0.0, 27.0, 0.0}, + {0, 0, 2, 2, 2, -38.0, 0.0, 16.0, 0.0}, + {2, 0, 0, 0, 0, 29.0, 0.0, -1.0, 0.0}, + {1, 0, 2, -2, 2, 29.0, 0.0, -12.0, 0.0}, + {2, 0, 2, 0, 2, -31.0, 0.0, 13.0, 0.0}, + {0, 0, 2, 0, 0, 26.0, 0.0, -1.0, 0.0}, + {-1, 0, 2, 0, 1, 21.0, 0.0, -10.0, 0.0}, + {-1, 0, 0, 2, 1, 16.0, 0.0, -8.0, 0.0}, + {1, 0, 0, -2, 1, -13.0, 0.0, 7.0, 0.0}, + {-1, 0, 2, 2, 1, -10.0, 0.0, 5.0, 0.0}, + {1, 1, 0, -2, 0, -7.0, 0.0, 0.0, 0.0}, + {0, 1, 2, 0, 2, 7.0, 0.0, -3.0, 0.0}, + {0, -1, 2, 0, 2, -7.0, 0.0, 3.0, 0.0}, + {1, 0, 2, 2, 2, -8.0, 0.0, 3.0, 0.0}, + {1, 0, 0, 2, 0, 6.0, 0.0, 0.0, 0.0}, + {2, 0, 2, -2, 2, 6.0, 0.0, -3.0, 0.0}, + {0, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0}, + {0, 0, 2, 2, 1, -7.0, 0.0, 3.0, 0.0}, + {1, 0, 2, -2, 1, 6.0, 0.0, -3.0, 0.0}, + {0, 0, 0, -2, 1, -5.0, 0.0, 3.0, 0.0}, + {1, -1, 0, 0, 0, 5.0, 0.0, 0.0, 0.0}, + {2, 0, 2, 0, 1, -5.0, 0.0, 3.0, 0.0}, + {0, 1, 0, -2, 0, -4.0, 0.0, 0.0, 0.0}, + {1, 0, -2, 0, 0, 4.0, 0.0, 0.0, 0.0}, + {0, 0, 0, 1, 0, -4.0, 0.0, 0.0, 0.0}, + {1, 1, 0, 0, 0, -3.0, 0.0, 0.0, 0.0}, + {1, 0, 2, 0, 0, 3.0, 0.0, 0.0, 0.0}, + {1, -1, 2, 0, 2, -3.0, 0.0, 1.0, 0.0}, + {-1, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0}, + {-2, 0, 0, 0, 1, -2.0, 0.0, 1.0, 0.0}, + {3, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0}, + {0, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0}, + {1, 1, 2, 0, 2, 2.0, 0.0, -1.0, 0.0}, + {-1, 0, 2, -2, 1, -2.0, 0.0, 1.0, 0.0}, + {2, 0, 0, 0, 1, 2.0, 0.0, -1.0, 0.0}, + {1, 0, 0, 0, 2, -2.0, 0.0, 1.0, 0.0}, + {3, 0, 0, 0, 0, 2.0, 0.0, 0.0, 0.0}, + {0, 0, 2, 1, 2, 2.0, 0.0, -1.0, 0.0}, + {-1, 0, 0, 0, 2, 1.0, 0.0, -1.0, 0.0}, + {1, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0}, + {-2, 0, 2, 2, 2, 1.0, 0.0, -1.0, 0.0}, + {-1, 0, 2, 4, 2, -2.0, 0.0, 1.0, 0.0}, + {2, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0}, + {1, 1, 2, -2, 2, 1.0, 0.0, -1.0, 0.0}, + {1, 0, 2, 2, 1, -1.0, 0.0, 1.0, 0.0}, + {-2, 0, 2, 4, 2, -1.0, 0.0, 1.0, 0.0}, + {-1, 0, 4, 0, 2, 1.0, 0.0, 0.0, 0.0}, + {1, -1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0}, + {2, 0, 2, -2, 1, 1.0, 0.0, -1.0, 0.0}, + {2, 0, 2, 2, 2, -1.0, 0.0, 0.0, 0.0}, + {1, 0, 0, 2, 1, -1.0, 0.0, 0.0, 0.0}, + {0, 0, 4, -2, 2, 1.0, 0.0, 0.0, 0.0}, + {3, 0, 2, -2, 2, 1.0, 0.0, 0.0, 0.0}, + {1, 0, 2, -2, 0, -1.0, 0.0, 0.0, 0.0}, + {0, 1, 2, 0, 1, 1.0, 0.0, 0.0, 0.0}, + {-1, -1, 0, 2, 1, 1.0, 0.0, 0.0, 0.0}, + {0, 0, -2, 0, 1, -1.0, 0.0, 0.0, 0.0}, + {0, 0, 2, -1, 2, -1.0, 0.0, 0.0, 0.0}, + {0, 1, 0, 2, 0, -1.0, 0.0, 0.0, 0.0}, + {1, 0, -2, -2, 0, -1.0, 0.0, 0.0, 0.0}, + {0, -1, 2, 0, 1, -1.0, 0.0, 0.0, 0.0}, + {1, 1, 0, -2, 1, -1.0, 0.0, 0.0, 0.0}, + {1, 0, -2, 2, 0, -1.0, 0.0, 0.0, 0.0}, + {2, 0, 0, 2, 0, 1.0, 0.0, 0.0, 0.0}, + {0, 0, 2, 4, 2, -1.0, 0.0, 0.0, 0.0}, + {0, 1, 0, 1, 0, 1.0, 0.0, 0.0, 0.0} }; // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Present nfd -void nfd_now(char *s) +void +nfd_now (char *s) { time_t rawtime; struct tm *ptm; // Get UTC time - time(&rawtime); - ptm=gmtime(&rawtime); - - sprintf(s,"%04d-%02d-%02dT%02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec); - + time (&rawtime); + ptm = gmtime (&rawtime); + + sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900, + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, + ptm->tm_sec); + return; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min,sec; - double mjd,dday; + int year, month, day, hour, min, sec; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; - mjd=date2mjd(year,month,dday); + mjd = date2mjd (year, month, dday); return mjd; } // Nutation -void nutation(double mjd,double *dpsi,double *deps,double *eps) +void +nutation (double mjd, double *dpsi, double *deps, double *eps) { int i; - double t,t2,t3; - double d,m,m1,f,n; + double t, t2, t3; + double d, m, m1, f, n; double arg; // Julian centuries - t=(mjd-51544.5)/36525.0; - t2=t*t; - t3=t2*t; + t = (mjd - 51544.5) / 36525.0; + t2 = t * t; + t3 = t2 * t; // Angles - d=modulo(297.85036+445267.111480*t-0.0019142*t2+t3/189474.0,360.0)*D2R; - m=modulo(357.52772+35999.050340*t-0.0001603*t2-t3/300000.0,360.0)*D2R; - m1=modulo(134.96298+477198.867398*t+0.0086972*t2+t3/56250.0,360.0)*D2R; - f=modulo(93.27191+483202.017538*t-0.0036825*t2+t3/327270.0,360.0)*D2R; - n=modulo(125.04452-1934.136261*t+0.0020708*t2+t3/450000.0,360.0)*D2R; - + d = + modulo (297.85036 + 445267.111480 * t - 0.0019142 * t2 + t3 / 189474.0, + 360.0) * D2R; + m = + modulo (357.52772 + 35999.050340 * t - 0.0001603 * t2 - t3 / 300000.0, + 360.0) * D2R; + m1 = + modulo (134.96298 + 477198.867398 * t + 0.0086972 * t2 + t3 / 56250.0, + 360.0) * D2R; + f = + modulo (93.27191 + 483202.017538 * t - 0.0036825 * t2 + t3 / 327270.0, + 360.0) * D2R; + n = + modulo (125.04452 - 1934.136261 * t + 0.0020708 * t2 + t3 / 450000.0, + 360.0) * D2R; + // Compute sums - *dpsi=0.0; - *deps=0.0; - for (i=0;i<106;i++) { - arg=nut[i].nd*d+nut[i].nm*m+nut[i].nm1*m1+nut[i].nf*f+nut[i].nn*n; - *dpsi+=(nut[i].s+nut[i].st*t)*sin(arg); - *deps+=(nut[i].c+nut[i].ct*t)*cos(arg); - } - *dpsi*=0.0001/3600*D2R; - *deps*=0.0001/3600*D2R; - *eps=-46.8150*t-0.00059*t2+0.001813*t3; - *eps=(23.4392911+ *eps/3600.0)*D2R; + *dpsi = 0.0; + *deps = 0.0; + for (i = 0; i < 106; i++) + { + arg = + nut[i].nd * d + nut[i].nm * m + nut[i].nm1 * m1 + nut[i].nf * f + + nut[i].nn * n; + *dpsi += (nut[i].s + nut[i].st * t) * sin (arg); + *deps += (nut[i].c + nut[i].ct * t) * cos (arg); + } + *dpsi *= 0.0001 / 3600 * D2R; + *deps *= 0.0001 / 3600 * D2R; + *eps = -46.8150 * t - 0.00059 * t2 + 0.001813 * t3; + *eps = (23.4392911 + *eps / 3600.0) * D2R; return; } // Precession -void precess(double mjd0,double mjd,double *zeta,double *z,double *theta) +void +precess (double mjd0, double mjd, double *zeta, double *z, double *theta) { - double t0,t; + double t0, t; // Time in centuries - t0=(mjd0-51544.5)/36525.0; - t=(mjd-mjd0)/36525.0; + t0 = (mjd0 - 51544.5) / 36525.0; + t = (mjd - mjd0) / 36525.0; // Precession angles - *zeta=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - *zeta+=(0.30188-0.000344*t0)*t*t+0.017998*t*t*t; - *zeta*=D2R/3600.0; - *z=(2306.2181+1.39656*t0-0.000139*t0*t0)*t; - *z+=(1.09468+0.000066*t0)*t*t+0.018203*t*t*t; - *z*=D2R/3600.0; - *theta=(2004.3109-0.85330*t0-0.000217*t0*t0)*t; - *theta+=-(0.42665+0.000217*t0)*t*t-0.041833*t*t*t; - *theta*=D2R/3600.0; - + *zeta = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + *zeta += (0.30188 - 0.000344 * t0) * t * t + 0.017998 * t * t * t; + *zeta *= D2R / 3600.0; + *z = (2306.2181 + 1.39656 * t0 - 0.000139 * t0 * t0) * t; + *z += (1.09468 + 0.000066 * t0) * t * t + 0.018203 * t * t * t; + *z *= D2R / 3600.0; + *theta = (2004.3109 - 0.85330 * t0 - 0.000217 * t0 * t0) * t; + *theta += -(0.42665 + 0.000217 * t0) * t * t - 0.041833 * t * t * t; + *theta *= D2R / 3600.0; + return; } // Set identity matrix -void identity_matrix(double a[3][3]) +void +identity_matrix (double a[3][3]) { - int i,j; + int i, j; - for (i=0;i<3;i++) { - for (j=0;j<3;j++) { - if (i==j) - a[i][j]=1.0; - else - a[i][j]=0.0; + for (i = 0; i < 3; i++) + { + for (j = 0; j < 3; j++) + { + if (i == j) + a[i][j] = 1.0; + else + a[i][j] = 0.0; + } } - } return; } // Rotate around x-axis -void rotate_x(double phi, double a[3][3]) +void +rotate_x (double phi, double a[3][3]) { - double s,c,a10,a11,a12,a20,a21,a22; + double s, c, a10, a11, a12, a20, a21, a22; - s=sin(phi); - c=cos(phi); + s = sin (phi); + c = cos (phi); + + a10 = c * a[1][0] + s * a[2][0]; + a11 = c * a[1][1] + s * a[2][1]; + a12 = c * a[1][2] + s * a[2][2]; + a20 = -s * a[1][0] + c * a[2][0]; + a21 = -s * a[1][1] + c * a[2][1]; + a22 = -s * a[1][2] + c * a[2][2]; + + a[1][0] = a10; + a[1][1] = a11; + a[1][2] = a12; + a[2][0] = a20; + a[2][1] = a21; + a[2][2] = a22; - a10=c*a[1][0]+s*a[2][0]; - a11=c*a[1][1]+s*a[2][1]; - a12=c*a[1][2]+s*a[2][2]; - a20=-s*a[1][0]+c*a[2][0]; - a21=-s*a[1][1]+c*a[2][1]; - a22=-s*a[1][2]+c*a[2][2]; - - a[1][0]=a10; - a[1][1]=a11; - a[1][2]=a12; - a[2][0]=a20; - a[2][1]=a21; - a[2][2]=a22; - return; } // Rotate around y-axis -void rotate_y(double phi, double a[3][3]) +void +rotate_y (double phi, double a[3][3]) { - double s,c,a00,a01,a02,a20,a21,a22; + double s, c, a00, a01, a02, a20, a21, a22; - s=sin(phi); - c=cos(phi); + s = sin (phi); + c = cos (phi); + + a00 = c * a[0][0] - s * a[2][0]; + a01 = c * a[0][1] - s * a[2][1]; + a02 = c * a[0][2] - s * a[2][2]; + a20 = s * a[0][0] + c * a[2][0]; + a21 = s * a[0][1] + c * a[2][1]; + a22 = s * a[0][2] + c * a[2][2]; + + a[0][0] = a00; + a[0][1] = a01; + a[0][2] = a02; + a[2][0] = a20; + a[2][1] = a21; + a[2][2] = a22; - a00=c*a[0][0]-s*a[2][0]; - a01=c*a[0][1]-s*a[2][1]; - a02=c*a[0][2]-s*a[2][2]; - a20=s*a[0][0]+c*a[2][0]; - a21=s*a[0][1]+c*a[2][1]; - a22=s*a[0][2]+c*a[2][2]; - - a[0][0]=a00; - a[0][1]=a01; - a[0][2]=a02; - a[2][0]=a20; - a[2][1]=a21; - a[2][2]=a22; - return; } // Rotate around z-axis -void rotate_z(double phi, double a[3][3]) +void +rotate_z (double phi, double a[3][3]) { - double s,c,a00,a01,a02,a10,a11,a12; + double s, c, a00, a01, a02, a10, a11, a12; - s=sin(phi); - c=cos(phi); + s = sin (phi); + c = cos (phi); - a00=c*a[0][0]+s*a[1][0]; - a01=c*a[0][1]+s*a[1][1]; - a02=c*a[0][2]+s*a[1][2]; - a10=-s*a[0][0]+c*a[1][0]; - a11=-s*a[0][1]+c*a[1][1]; - a12=-s*a[0][2]+c*a[1][2]; + a00 = c * a[0][0] + s * a[1][0]; + a01 = c * a[0][1] + s * a[1][1]; + a02 = c * a[0][2] + s * a[1][2]; + a10 = -s * a[0][0] + c * a[1][0]; + a11 = -s * a[0][1] + c * a[1][1]; + a12 = -s * a[0][2] + c * a[1][2]; - a[0][0]=a00; - a[0][1]=a01; - a[0][2]=a02; - a[1][0]=a10; - a[1][1]=a11; - a[1][2]=a12; + a[0][0] = a00; + a[0][1] = a01; + a[0][2] = a02; + a[1][0] = a10; + a[1][1] = a11; + a[1][2] = a12; return; } // Matrix multiply -void matrix_multiply(double a[3][3],double b[3][3],double c[3][3]) +void +matrix_multiply (double a[3][3], double b[3][3], double c[3][3]) { - int i,j,k; + int i, j, k; - for (i=0;i<3;i++) { - for (j=0;j<3;j++) { - c[i][j]=0.0; - for (k=0;k<3;k++) - c[i][j]+=a[i][k]*b[k][j]; + for (i = 0; i < 3; i++) + { + for (j = 0; j < 3; j++) + { + c[i][j] = 0.0; + for (k = 0; k < 3; k++) + c[i][j] += a[i][k] * b[k][j]; + } } - } return; } // Vector multiply -void vector_multiply_in_place(double a[3][3],double b[3]) +void +vector_multiply_in_place (double a[3][3], double b[3]) { - int i,j,k; + int i, j, k; double c[3]; - for (i=0;i<3;i++) { - c[i]=0.0; - for (j=0;j<3;j++) - c[i]+=a[i][j]*b[j]; - } - for (i=0;i<3;i++) - b[i]=c[i]; + for (i = 0; i < 3; i++) + { + c[i] = 0.0; + for (j = 0; j < 3; j++) + c[i] += a[i][j] * b[j]; + } + for (i = 0; i < 3; i++) + b[i] = c[i]; return; } // Vector multiply -void vector_multiply(double a[3][3],double b[3],double c[3]) +void +vector_multiply (double a[3][3], double b[3], double c[3]) { - int i,j,k; + int i, j, k; - for (i=0;i<3;i++) { - c[i]=0.0; - for (j=0;j<3;j++) - c[i]+=a[i][j]*b[j]; - } + for (i = 0; i < 3; i++) + { + c[i] = 0.0; + for (j = 0; j < 3; j++) + c[i] += a[i][j] * b[j]; + } return; } // Transpose -void matrix_transpose(double a[3][3],double b[3][3]) +void +matrix_transpose (double a[3][3], double b[3][3]) { - int i,j; + int i, j; - for (i=0;i<3;i++) - for (j=0;j<3;j++) - b[i][j]=a[j][i]; + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + b[i][j] = a[j][i]; return; } // Dot product -double dot_product(double a[3],double b[3]) +double +dot_product (double a[3], double b[3]) { - return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]; -} + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; +} // Magnitude -double magnitude(double a[3]) +double +magnitude (double a[3]) { - return sqrt(dot_product(a,a)); + return sqrt (dot_product (a, a)); } // Cross product -void cross_product(double a[3],double b[3],double c[3]) +void +cross_product (double a[3], double b[3], double c[3]) { - c[0]=a[1]*b[2]-a[2]*b[1]; - c[1]=a[2]*b[0]-a[0]*b[2]; - c[2]=a[0]*b[1]-a[1]*b[0]; + c[0] = a[1] * b[2] - a[2] * b[1]; + c[1] = a[2] * b[0] - a[0] * b[2]; + c[2] = a[0] * b[1] - a[1] * b[0]; return; } // ICRS to TEME conversion -void icrs_to_teme(double mjd,double a[3][3]) +void +icrs_to_teme (double mjd, double a[3][3]) { - int i,j; - double dpsi,deps,eps,z,theta,zeta,h; - double p[3][3],n[3][3],q[3][3],b[3][3]; + int i, j; + double dpsi, deps, eps, z, theta, zeta, h; + double p[3][3], n[3][3], q[3][3], b[3][3]; // Precession - precess(51544.5,mjd,&zeta,&z,&theta); - identity_matrix(p); - rotate_z(-zeta,p); - rotate_y(theta,p); - rotate_z(-z,p); + precess (51544.5, mjd, &zeta, &z, &theta); + identity_matrix (p); + rotate_z (-zeta, p); + rotate_y (theta, p); + rotate_z (-z, p); // Nutation - nutation(mjd,&dpsi,&deps,&eps); - identity_matrix(n); - rotate_x(eps,n); - rotate_z(-dpsi,n); - rotate_x(-eps-deps,n); + nutation (mjd, &dpsi, &deps, &eps); + identity_matrix (n); + rotate_x (eps, n); + rotate_z (-dpsi, n); + rotate_x (-eps - deps, n); // Equation of equinoxes - identity_matrix(q); - rotate_z(dpsi*cos(eps+deps),q); + identity_matrix (q); + rotate_z (dpsi * cos (eps + deps), q); // Multiply matrices (left to right) - matrix_multiply(q,n,b); - matrix_multiply(b,p,a); + matrix_multiply (q, n, b); + matrix_multiply (b, p, a); return; } -void usage(void) +void +usage (void) { - printf("tle2rv c:i:t:m:efh\n\n"); - printf("-c Catalog to load [classfd.tle]\n"); - printf("-i Object to convert [all]\n"); - printf("-t Epoch (YYYY-mm-ddThh:mm:ss)\n"); - printf("-m Epoch (MJD)\n"); - printf("-e Use TLE epoch\n"); - printf("-j J2000 output\n"); - printf("-g GMAT output (J2000)\n"); - printf("-h This help\n"); + printf ("tle2rv c:i:t:m:efh\n\n"); + printf ("-c Catalog to load [classfd.tle]\n"); + printf ("-i Object to convert [all]\n"); + printf ("-t Epoch (YYYY-mm-ddThh:mm:ss)\n"); + printf ("-m Epoch (MJD)\n"); + printf ("-e Use TLE epoch\n"); + printf ("-j J2000 output\n"); + printf ("-g GMAT output (J2000)\n"); + printf ("-h This help\n"); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int imode,arg,satno=0,useepoch=0,format=0,gmat=0; + int imode, arg, satno = 0, useepoch = 0, format = 0, gmat = 0; FILE *file; char *env; - char tlefile[LIM],nfd[32]; + char tlefile[LIM], nfd[32]; double mjd; - xyz_t r,v; + xyz_t r, v; orbit_t orb; - double rr[3],vv[3],e[3][3],et[3][3]; + double rr[3], vv[3], e[3][3], et[3][3]; // Get environment variable - env=getenv("ST_TLEDIR"); - sprintf(tlefile,"%s/classfd.tle",env); + env = getenv ("ST_TLEDIR"); + sprintf (tlefile, "%s/classfd.tle", env); // Set date - nfd_now(nfd); - mjd=nfd2mjd(nfd); + nfd_now (nfd); + mjd = nfd2mjd (nfd); // Decode options - while ((arg=getopt(argc,argv,"c:i:t:m:hejg"))!=-1) { - switch (arg) { + while ((arg = getopt (argc, argv, "c:i:t:m:hejg")) != -1) + { + switch (arg) + { - case 't': - strcpy(nfd,optarg); - mjd=nfd2mjd(nfd); - break; - - case 'm': - mjd=atof(optarg); - break; + case 't': + strcpy (nfd, optarg); + mjd = nfd2mjd (nfd); + break; - case 'e': - useepoch=1; - break; + case 'm': + mjd = atof (optarg); + break; - case 'j': - format=1; - break; + case 'e': + useepoch = 1; + break; - case 'g': - gmat=1; - break; + case 'j': + format = 1; + break; - case 'c': - strcpy(tlefile,optarg); - break; + case 'g': + gmat = 1; + break; - case 'i': - satno=atoi(optarg); - break; + case 'c': + strcpy (tlefile, optarg); + break; - case 'h': - usage(); - return 0; - break; + case 'i': + satno = atoi (optarg); + break; - default: - usage(); - return 0; + case 'h': + usage (); + return 0; + break; + + default: + usage (); + return 0; + } } - } // Open file - file=fopen(tlefile,"r"); - while (read_twoline(file,satno,&orb)==0) { - // Propagate - imode=init_sgdp4(&orb); + file = fopen (tlefile, "r"); + while (read_twoline (file, satno, &orb) == 0) + { + // Propagate + imode = init_sgdp4 (&orb); - // Use epoch instead of user supplied date - if (useepoch==1) - mjd=SGDP4_jd0-2400000.5; + // Use epoch instead of user supplied date + if (useepoch == 1) + mjd = SGDP4_jd0 - 2400000.5; - // Compute position and velocity - imode=satpos_xyz(mjd+2400000.5,&r,&v); + // Compute position and velocity + imode = satpos_xyz (mjd + 2400000.5, &r, &v); - // Output - if (format==0 && gmat==0) - printf("%05d %14.8lf %f %f %f %f %f %f TEME\n",orb.satno,mjd,r.x,r.y,r.z,v.x,v.y,v.z); + // Output + if (format == 0 && gmat == 0) + printf ("%05d %14.8lf %f %f %f %f %f %f TEME\n", orb.satno, mjd, r.x, + r.y, r.z, v.x, v.y, v.z); - // To vectors - rr[0]=r.x; - rr[1]=r.y; - rr[2]=r.z; - vv[0]=v.x; - vv[1]=v.y; - vv[2]=v.z; + // To vectors + rr[0] = r.x; + rr[1] = r.y; + rr[2] = r.z; + vv[0] = v.x; + vv[1] = v.y; + vv[2] = v.z; - // Matrices - icrs_to_teme(mjd,e); - matrix_transpose(e,et); + // Matrices + icrs_to_teme (mjd, e); + matrix_transpose (e, et); - // Transform - vector_multiply_in_place(et,rr); - vector_multiply_in_place(et,vv); - - // Output J2000 - if (format==1 && gmat==0) - printf("%05d %14.8lf %f %f %f %f %f %f J2000\n",orb.satno,mjd,rr[0],rr[1],rr[2],vv[0],vv[1],vv[2]); + // Transform + vector_multiply_in_place (et, rr); + vector_multiply_in_place (et, vv); - // GMAT output - if (gmat==1) { - printf("UTCModJulian = %14.8lf\n",mjd-29999.5); - printf("CoordinateSystem = EarthMJ2000Eq\n"); - printf("X = %lf\n",rr[0]); - printf("Y = %lf\n",rr[1]); - printf("Z = %lf\n",rr[2]); - printf("VX = %lf\n",vv[0]); - printf("VY = %lf\n",vv[1]); - printf("VZ = %lf\n",vv[2]); + // Output J2000 + if (format == 1 && gmat == 0) + printf ("%05d %14.8lf %f %f %f %f %f %f J2000\n", orb.satno, mjd, + rr[0], rr[1], rr[2], vv[0], vv[1], vv[2]); + + // GMAT output + if (gmat == 1) + { + printf ("UTCModJulian = %14.8lf\n", mjd - 29999.5); + printf ("CoordinateSystem = EarthMJ2000Eq\n"); + printf ("X = %lf\n", rr[0]); + printf ("Y = %lf\n", rr[1]); + printf ("Z = %lf\n", rr[2]); + printf ("VX = %lf\n", vv[0]); + printf ("VY = %lf\n", vv[1]); + printf ("VZ = %lf\n", vv[2]); + } } - } - fclose(file); + fclose (file); return 0; } diff --git a/src/tleinfo.c b/src/tleinfo.c index 52da859..267562d 100644 --- a/src/tleinfo.c +++ b/src/tleinfo.c @@ -7,96 +7,115 @@ #include "satutl.h" #define LIM 128 -#define XKMPER 6378.135 /* Km per earth radii */ -#define XMNPDA 1440.0 /* Minutes per day */ -#define AE 1.0 /* Earth radius in "chosen units". */ +#define XKMPER 6378.135 /* Km per earth radii */ +#define XMNPDA 1440.0 /* Minutes per day */ +#define AE 1.0 /* Earth radius in "chosen units". */ #define XKE 0.743669161e-1 -#define CK2 5.413080e-4 /* (0.5 * XJ2 * AE * AE) */ +#define CK2 5.413080e-4 /* (0.5 * XJ2 * AE * AE) */ #define D2R M_PI/180.0 #define R2D 180.0/M_PI extern double SGDP4_jd0; -void usage(void) +void +usage (void) { - printf("usage: tleinfo [-c TLEFILE] [-u] [|-1|-f] [ |-n|-d] [-i SATNO] [-I INTLDESG ] [ |-a|-b] [-H] [-h]\n\n"); + printf + ("usage: tleinfo [-c TLEFILE] [-u] [|-1|-f] [ |-n|-d] [-i SATNO] [-I INTLDESG ] [ |-a|-b] [-H] [-h]\n\n"); - printf("-c TLEFILE The file containing orbital elements in the form of TLEs, 3 lines per object\n"); - printf(" default: ./bulk.tle\n"); - printf("-i SATNO Filter only elements for objects with this NORAD catalog identifier\n"); - printf("-I INTLDESG Filter only elements for objects with this international designator\n"); - printf("-u Show only one object (MODE0 only)\n"); + printf + ("-c TLEFILE The file containing orbital elements in the form of TLEs, 3 lines per object\n"); + printf (" default: ./bulk.tle\n"); + printf + ("-i SATNO Filter only elements for objects with this NORAD catalog identifier\n"); + printf + ("-I INTLDESG Filter only elements for objects with this international designator\n"); + printf ("-u Show only one object (MODE0 only)\n"); - printf("\nSelect MODE:\n"); - printf(" MODE0: Show TLEs, object names or COSPAR designations\n"); - printf("-1 MODE1: Show list of elements (one line per object)\n"); - printf("-f MODE2: Show human-readable parameters\n\n"); + printf ("\nSelect MODE:\n"); + printf + (" MODE0: Show TLEs, object names or COSPAR designations\n"); + printf ("-1 MODE1: Show list of elements (one line per object)\n"); + printf ("-f MODE2: Show human-readable parameters\n\n"); - printf("Select INFOTYPE\n"); - printf("MODE0:\n"); - printf(" default Show the TLEs itself\n"); - printf(" -n Show only the name of the objects\n"); - printf(" -d Show only the COSPAR designation of the objects\n\n"); - printf("MODE1:\n"); - printf(" default SATNO, YEAR, DOY, INCL, ASCN, ARGP, MA, ECC, MM, BSTAR\n"); - printf(" -a SATNO, SEMI, PERIGEE, APOGEE, INCL, PERIOD, ECC\n"); - printf(" -b SATNO, YEAR, DOY, INCL, ASCN, ARGP, MA, ECC, MM, floor(MJD), LNG_AT_MIDNIGHT\n\n"); + printf ("Select INFOTYPE\n"); + printf ("MODE0:\n"); + printf (" default Show the TLEs itself\n"); + printf (" -n Show only the name of the objects\n"); + printf (" -d Show only the COSPAR designation of the objects\n\n"); + printf ("MODE1:\n"); + printf + (" default SATNO, YEAR, DOY, INCL, ASCN, ARGP, MA, ECC, MM, BSTAR\n"); + printf (" -a SATNO, SEMI, PERIGEE, APOGEE, INCL, PERIOD, ECC\n"); + printf + (" -b SATNO, YEAR, DOY, INCL, ASCN, ARGP, MA, ECC, MM, floor(MJD), LNG_AT_MIDNIGHT\n\n"); - printf("-H Show header (MODE1 only), default: disabled\n"); - printf("-h Print usage\n"); + printf ("-H Show header (MODE1 only), default: disabled\n"); + printf ("-h Print usage\n"); } -double modulo(double x,double y); +double modulo (double x, double y); // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // DOY to MJD -double doy2mjd(int year,double doy) +double +doy2mjd (int year, double doy) { - int month,k=2; + int month, k = 2; double day; - if (year%4==0 && year%400!=0) - k=1; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - month=floor(9.0*(k+doy)/275.0+0.98); - - if (doy<32) - month=1; + month = floor (9.0 * (k + doy) / 275.0 + 0.98); - day=doy-floor(275.0*month/9.0)+k*floor((month+9.0)/12.0)+30.0; + if (doy < 32) + month = 1; - return date2mjd(year,month,day); + day = + doy - floor (275.0 * month / 9.0) + k * floor ((month + 9.0) / 12.0) + + 30.0; + + return date2mjd (year, month, day); } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; - - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + int c, i = 0; + + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; // if (c == '\n') // s[i++] = c; @@ -104,282 +123,321 @@ int fgetline(FILE *file,char *s,int lim) return i; } -void orbit(orbit_t orb,float *aodp,float *perigee,float *apogee,float *period) +void +orbit (orbit_t orb, float *aodp, float *perigee, float *apogee, float *period) { - float xno,eo,xincl; - float a1,betao2,betao,temp0,del1,a0,del0,xnodp; + float xno, eo, xincl; + float a1, betao2, betao, temp0, del1, a0, del0, xnodp; - xno=orb.rev*2.0*M_PI/XMNPDA; - eo=orb.ecc; - xincl=orb.eqinc; + xno = orb.rev * 2.0 * M_PI / XMNPDA; + eo = orb.ecc; + xincl = orb.eqinc; - a1 = pow(XKE / xno, 2.0/3.0); + a1 = pow (XKE / xno, 2.0 / 3.0); betao2 = 1.0 - eo * eo; - betao = sqrt(betao2); - temp0 = (1.5 * CK2) * cos(xincl)*cos(xincl) / (betao * betao2); + betao = sqrt (betao2); + temp0 = (1.5 * CK2) * cos (xincl) * cos (xincl) / (betao * betao2); del1 = temp0 / (a1 * a1); - a0 = a1 * (1.0 - del1 * (1.0/3.0 + del1 * (1.0 + del1 * 134.0/81.0))); + a0 = a1 * (1.0 - del1 * (1.0 / 3.0 + del1 * (1.0 + del1 * 134.0 / 81.0))); del0 = temp0 / (a0 * a0); xnodp = xno / (1.0 + del0); *aodp = (a0 / (1.0 - del0)); *perigee = (*aodp * (1.0 - eo) - 1) * XKMPER; *apogee = (*aodp * (1.0 + eo) - 1) * XKMPER; *period = (TWOPI * 1440.0 / XMNPDA) / xnodp; - *aodp=(*aodp-1)*XKMPER; + *aodp = (*aodp - 1) * XKMPER; return; } // Compute Date from Julian Day -void mjd2nfd(double mjd,char *nfd) +void +mjd2nfd (double mjd, char *nfd) { - double f,jd,dday; - int z,alpha,a,b,c,d,e; - int year,month,day,hour,min; - float sec,x; + double f, jd, dday; + int z, alpha, a, b, c, d, e; + int year, month, day, hour, min; + float sec, x; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - dday=b-d-floor(30.6001*e)+f; - if (e<14) - month=e-1; + if (z < 2299161) + a = z; else - month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (month>2) - year=c-4716; + dday = b - d - floor (30.6001 * e) + f; + if (e < 14) + month = e - 1; else - year=c-4715; + month = e - 13; - day=(int) floor(dday); - x=24.0*(dday-day); - x=3600.*fabs(x); - sec=fmod(x,60.); - x=(x-sec)/60.; - min=fmod(x,60.); - x=(x-min)/60.; - hour=x; - sec=floor(1000.0*sec)/1000.0; + if (month > 2) + year = c - 4716; + else + year = c - 4715; - sprintf(nfd,"%04d-%02d-%02dT%02d:%02d:%06.3f",year,month,day,hour,min,sec); + day = (int) floor (dday); + x = 24.0 * (dday - day); + x = 3600. * fabs (x); + sec = fmod (x, 60.); + x = (x - sec) / 60.; + min = fmod (x, 60.); + x = (x - min) / 60.; + hour = x; + sec = floor (1000.0 * sec) / 1000.0; + + sprintf (nfd, "%04d-%02d-%02dT%02d:%02d:%06.3f", year, month, day, hour, + min, sec); return; } -float orbital_longitude_at_midnight(orbit_t orb,double mjd0) +float +orbital_longitude_at_midnight (orbit_t orb, double mjd0) { - int rv,imode; - double jd,tsince,mjd; + int rv, imode; + double jd, tsince, mjd; kep_t K; - imode=init_sgdp4(&orb); + imode = init_sgdp4 (&orb); - mjd=floor(mjd0); - - jd=mjd+2400000.5; - tsince=1440.0*(jd-SGDP4_jd0); - rv=sgdp4(tsince,1,&K); + mjd = floor (mjd0); - return modulo(K.theta*R2D,360.0); + jd = mjd + 2400000.5; + tsince = 1440.0 * (jd - SGDP4_jd0); + rv = sgdp4 (tsince, 1, &K); + + return modulo (K.theta * R2D, 360.0); } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int arg=0,satno=0,header=0,oneline=0,no,name=0,desig=0,has_intldesg=0; + int arg = 0, satno = 0, header = 0, oneline = 0, no, name = 0, desig = + 0, has_intldesg = 0; char tlefile[LIM]; - char line0[LIM],line1[LIM],line2[LIM],nfd[32],intldesg[16]="",desg[16]=""; + char line0[LIM], line1[LIM], line2[LIM], nfd[32], intldesg[16] = + "", desg[16] = ""; FILE *file; orbit_t orb; - float aodp,perigee,apogee,period,lng; - int info=0,unique=0; + float aodp, perigee, apogee, period, lng; + int info = 0, unique = 0; double mjd; char *env; - env=getenv("ST_TLEDIR"); - sprintf(tlefile,"%s/bulk.tle",env); + env = getenv ("ST_TLEDIR"); + sprintf (tlefile, "%s/bulk.tle", env); // Decode options - while ((arg=getopt(argc,argv,"c:i:I:aH1ftndbu"))!=-1) { - switch (arg) { - - case 'c': - strcpy(tlefile,optarg); - break; + while ((arg = getopt (argc, argv, "c:i:I:aH1ftndbu")) != -1) + { + switch (arg) + { - case 'u': - unique=1; - break; + case 'c': + strcpy (tlefile, optarg); + break; - case '1': - oneline=1; - break; + case 'u': + unique = 1; + break; - case 'f': - oneline=2; - break; + case '1': + oneline = 1; + break; - case 'n': - name=1; - break; + case 'f': + oneline = 2; + break; - case 'd': - desig=1; - break; + case 'n': + name = 1; + break; - case 'i': - satno=atoi(optarg); - break; + case 'd': + desig = 1; + break; - case 'I': - strcpy(intldesg,optarg); - has_intldesg=1; - break; - - case 'a': - info=1; - break; + case 'i': + satno = atoi (optarg); + break; - case 'b': - info=2; - break; + case 'I': + strcpy (intldesg, optarg); + has_intldesg = 1; + break; - case 'H': - header=1; - break; + case 'a': + info = 1; + break; - case 'h': - usage(); - return 0; - break; + case 'b': + info = 2; + break; - default: - usage(); - return 0; - } - } + case 'H': + header = 1; + break; - if (oneline==0) { - // Open file - file=fopen(tlefile,"rb"); - if (file==NULL) - fatal_error("File open failed for reading \"%s\"",tlefile); + case 'h': + usage (); + return 0; + break; - while (fgetline(file,line1,LIM)>0) { - // Find TLE line - if (line1[0]=='1') { - fgetline(file,line2,LIM); - sscanf(line1+2,"%d",&no); - sscanf(line1+9,"%s",&desg); - - if ((satno==0 || satno==no) && (has_intldesg==0)) { - if (name==1 && desig==0) - printf("%s\n",line0); - else if (name==0 && desig==1) - printf("%.8s\n",line1+9); - else - printf("%s\n%s\n%s\n",line0,line1,line2); - if (unique==1) - break; - } else if (has_intldesg==1) { - if (strcmp(desg,intldesg)==0) { - printf("%s\n%s\n%s\n",line0,line1,line2); - } + default: + usage (); + return 0; } - } - strcpy(line0,line1); } - /* - // Loop over file - while (fgetline(file,line0,LIM)>0) { - // Read data lines - if (line0[0]!='1' || line0[0]!='2') { - fgetline(file,line1,LIM); - fgetline(file,line2,LIM); - sscanf(line1+2,"%d",&no); + if (oneline == 0) + { + // Open file + file = fopen (tlefile, "rb"); + if (file == NULL) + fatal_error ("File open failed for reading \"%s\"", tlefile); - if (satno==0 || satno==no) { - if (name==1 && desig==0) - printf("%s\n",line0); - else if (name==0 && desig==1) - printf("%.8s\n",line1+9); - else - printf("%s\n%s\n%s\n",line0,line1,line2); + while (fgetline (file, line1, LIM) > 0) + { + // Find TLE line + if (line1[0] == '1') + { + fgetline (file, line2, LIM); + sscanf (line1 + 2, "%d", &no); + sscanf (line1 + 9, "%s", &desg); + + if ((satno == 0 || satno == no) && (has_intldesg == 0)) + { + if (name == 1 && desig == 0) + printf ("%s\n", line0); + else if (name == 0 && desig == 1) + printf ("%.8s\n", line1 + 9); + else + printf ("%s\n%s\n%s\n", line0, line1, line2); + if (unique == 1) + break; + } + else if (has_intldesg == 1) + { + if (strcmp (desg, intldesg) == 0) + { + printf ("%s\n%s\n%s\n", line0, line1, line2); + } + } + } + strcpy (line0, line1); } - } else if (line0[0]=='1') { - fgetline(file,line2,LIM); - sscanf(line1+2,"%d",&no); - if (satno==0 || satno==no) - printf("%s\n%s\n",line0,line2); - } + /* + // Loop over file + while (fgetline(file,line0,LIM)>0) { + // Read data lines + if (line0[0]!='1' || line0[0]!='2') { + fgetline(file,line1,LIM); + fgetline(file,line2,LIM); + sscanf(line1+2,"%d",&no); + + if (satno==0 || satno==no) { + if (name==1 && desig==0) + printf("%s\n",line0); + else if (name==0 && desig==1) + printf("%.8s\n",line1+9); + else + printf("%s\n%s\n%s\n",line0,line1,line2); + } + } else if (line0[0]=='1') { + fgetline(file,line2,LIM); + sscanf(line1+2,"%d",&no); + + if (satno==0 || satno==no) + printf("%s\n%s\n",line0,line2); + } + } + */ + fclose (file); } - */ - fclose(file); - } else if (oneline==1) { - // Open file - file=fopen(tlefile,"rb"); - if (file==NULL) - fatal_error("File open failed for reading \"%s\"",tlefile); + else if (oneline == 1) + { + // Open file + file = fopen (tlefile, "rb"); + if (file == NULL) + fatal_error ("File open failed for reading \"%s\"", tlefile); - if (header==1) { - if (info==0) - printf("SATNO YEAR DOY INCL ASCN ARGP MA ECC MM BSTAR\n"); - else if (info==1) - printf("SATNO SEMI PERIGEE APOGEE PERIOD ECC\n"); - else if (info==2) - printf("SATNO YEAR DOY INCL ASCN ARGP MA ECC MM floor(MJD) LNG_AT_MIDNIGHT\n"); + if (header == 1) + { + if (info == 0) + printf + ("SATNO YEAR DOY INCL ASCN ARGP MA ECC MM BSTAR\n"); + else if (info == 1) + printf ("SATNO SEMI PERIGEE APOGEE PERIOD ECC\n"); + else if (info == 2) + printf + ("SATNO YEAR DOY INCL ASCN ARGP MA ECC MM floor(MJD) LNG_AT_MIDNIGHT\n"); + } + + // Loop over file + while (read_twoline (file, satno, &orb) == 0) + { + orbit (orb, &aodp, &perigee, &apogee, &period); + mjd = doy2mjd (orb.ep_year, orb.ep_day); + mjd2nfd (mjd, nfd); + if (info == 0) + printf ("%05d %10.4lf %8.4f %8.4f %8.4f %8.4f %8.6f %8.5f %e\n", + orb.satno, mjd, DEG (orb.eqinc), DEG (orb.ascn), + DEG (orb.argp), DEG (orb.mnan), orb.ecc, orb.rev, + orb.bstar); + if (info == 1) + printf ("%05d %6.0f x %6.0f x %6.2f %8.2f %8.6f %14.8lf\n", + orb.satno, perigee, apogee, DEG (orb.eqinc), period, + orb.ecc, mjd); + if (info == 2) + { + lng = orbital_longitude_at_midnight (orb, mjd); + printf + ("%05d %10.4lf %8.4f %8.4f %8.4f %8.4f %8.6f %8.5f %10.4lf %8.4f\n", + orb.satno, mjd, DEG (orb.eqinc), DEG (orb.ascn), + DEG (orb.argp), DEG (orb.mnan), orb.ecc, orb.rev, + floor (mjd), lng); + } + } + fclose (file); } + else if (oneline == 2) + { + // Open file + file = fopen (tlefile, "rb"); + if (file == NULL) + fatal_error ("File open failed for reading \"%s\"", tlefile); - // Loop over file - while (read_twoline(file,satno,&orb)==0) { - orbit(orb,&aodp,&perigee,&apogee,&period); - mjd=doy2mjd(orb.ep_year,orb.ep_day); - mjd2nfd(mjd,nfd); - if (info==0) printf("%05d %10.4lf %8.4f %8.4f %8.4f %8.4f %8.6f %8.5f %e\n",orb.satno,mjd,DEG(orb.eqinc),DEG(orb.ascn),DEG(orb.argp),DEG(orb.mnan),orb.ecc,orb.rev,orb.bstar); - if (info==1) printf("%05d %6.0f x %6.0f x %6.2f %8.2f %8.6f %14.8lf\n",orb.satno,perigee,apogee,DEG(orb.eqinc),period,orb.ecc,mjd); - if (info==2) { - lng=orbital_longitude_at_midnight(orb,mjd); - printf("%05d %10.4lf %8.4f %8.4f %8.4f %8.4f %8.6f %8.5f %10.4lf %8.4f\n",orb.satno,mjd,DEG(orb.eqinc),DEG(orb.ascn),DEG(orb.argp),DEG(orb.mnan),orb.ecc,orb.rev,floor(mjd),lng); - } + // Loop over file + while (read_twoline (file, satno, &orb) == 0) + print_orb (&orb); + + fclose (file); } - fclose(file); - } else if (oneline==2) { - // Open file - file=fopen(tlefile,"rb"); - if (file==NULL) - fatal_error("File open failed for reading \"%s\"",tlefile); - - // Loop over file - while (read_twoline(file,satno,&orb)==0) - print_orb(&orb); - - fclose(file); - } return 0; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } diff --git a/src/uk2iod.c b/src/uk2iod.c index 10d9409..b3355bf 100644 --- a/src/uk2iod.c +++ b/src/uk2iod.c @@ -6,159 +6,171 @@ #define LIM 128 -int fgetline(FILE *file,char *s,int lim); -int find_satno(char *desig0) +int fgetline (FILE * file, char *s, int lim); +int +find_satno (char *desig0) { FILE *file; - int satno=99999,status; + int satno = 99999, status; char desig[16]; - char *env,filename[LIM]; + char *env, filename[LIM]; - env=getenv("ST_DATADIR"); - sprintf(filename,"%s/data/desig.txt",env); - file=fopen(filename,"r"); - if (file==NULL) { - fprintf(stderr,"Designation file not found!\n"); - exit(0); - } - while (!feof(file)) { - status=fscanf(file,"%d %s",&satno,desig); - if (strcmp(desig,desig0)==0) - break; - } - fclose(file); + env = getenv ("ST_DATADIR"); + sprintf (filename, "%s/data/desig.txt", env); + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "Designation file not found!\n"); + exit (0); + } + while (!feof (file)) + { + status = fscanf (file, "%d %s", &satno, desig); + if (strcmp (desig, desig0) == 0) + break; + } + fclose (file); return satno; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { FILE *file; char line[LIM]; - int intidy,intido,piece,site,year,month,day,hour,min,sec,fsec,satno; - char desig[16],pdesig[16]; - int format,epoch; - float csec,cang,x; - int rah,ram,rafm,ded,dem,defm; - float tm,tx,am,ax; + int intidy, intido, piece, site, year, month, day, hour, min, sec, fsec, + satno; + char desig[16], pdesig[16]; + int format, epoch; + float csec, cang, x; + int rah, ram, rafm, ded, dem, defm; + float tm, tx, am, ax; char sign; - file=fopen(argv[1],"r"); - while (fgetline(file,line,LIM)>0) { - // Skip wrong lines - if (!isdigit(line[0])) - continue; - // Skip short lines - if (strlen(line)<55) - continue; + file = fopen (argv[1], "r"); + while (fgetline (file, line, LIM) > 0) + { + // Skip wrong lines + if (!isdigit (line[0])) + continue; + // Skip short lines + if (strlen (line) < 55) + continue; - // Scan line - sscanf(line,"%02d%03d%02d%04d%02d%02d%02d%02d%02d%02d%03d",&intidy,&intido, - &piece, - &site, - &year, - &month, - &day, - &hour, - &min, - &sec, - &fsec); - sscanf(line+27,"%f",&csec); - sscanf(line+33,"%1d",&format); - if (format==2) { - sscanf(line+34,"%02d%02d%d",&rah,&ram,&rafm); - sscanf(line+42,"%c%02d%02d%d",&sign,&ded,&dem,&defm); - } else if (format==3) { - sscanf(line+34,"%02d%02d%d",&rah,&ram,&rafm); - sscanf(line+42,"%c%02d%02d",&sign,&ded,&dem); + // Scan line + sscanf (line, "%02d%03d%02d%04d%02d%02d%02d%02d%02d%02d%03d", &intidy, + &intido, &piece, &site, &year, &month, &day, &hour, &min, &sec, + &fsec); + sscanf (line + 27, "%f", &csec); + sscanf (line + 33, "%1d", &format); + if (format == 2) + { + sscanf (line + 34, "%02d%02d%d", &rah, &ram, &rafm); + sscanf (line + 42, "%c%02d%02d%d", &sign, &ded, &dem, &defm); + } + else if (format == 3) + { + sscanf (line + 34, "%02d%02d%d", &rah, &ram, &rafm); + sscanf (line + 42, "%c%02d%02d", &sign, &ded, &dem); + } + sscanf (line + 50, "%f", &cang); + sscanf (line + 54, "%d", &epoch); + + // Year switch + if (year > 50) + year += 1900; + else + year += 2000; + + // Format designation + if (piece < 26) + { + sprintf (desig, "%02d %03d%c", intidy, intido, piece + 'A' - 1); + sprintf (pdesig, "%02d%03d%c", intidy, intido, piece + 'A' - 1); + } + else + { + fprintf (stderr, "Failed to understand designation!\n"); + fprintf (stderr, "%s\n", line); + continue; + } + + // Test data format + if (format == 3) + { + x = dem * 0.6; + dem = (int) floor (x); + defm = (int) (100.0 * (x - dem)); + } + else if (format != 2) + { + fprintf (stderr, "Angle format not implemented!\n"); + fprintf (stderr, "%s\n", line); + continue; + } + + // Fractional seconds + if (fsec < 10) + fsec *= 100; + else if (fsec < 100) + fsec *= 10; + + // Time accuracy + if (csec < 10) + csec *= 0.1; + else if (csec < 100) + csec *= 0.01; + tx = floor (log10 (csec)) + 8; + tm = floor (csec / pow (10.0, tx - 8)); + + // angle accuracy + if (cang < 10) + cang *= 1; + else if (cang < 100) + cang *= 0.1; + ax = floor (log10 (cang)) + 8; + am = floor (cang / pow (10.0, ax - 8)); + + // Fractional RA + if (rafm < 10) + rafm *= 100; + else if (rafm < 100) + rafm *= 10; + + // Fractional DE + if (defm < 10) + defm *= 10; + else if (defm < 100) + defm *= 1; + + // Get satellite number + satno = find_satno (pdesig); + + // Format IOD line + printf + ("%05d %s %04d G %04d%02d%02d%02d%02d%02d%03d %1.0f%1.0f %d%d ", + satno, desig, site, year, month, day, hour, min, sec, fsec, tm, tx, + format, epoch); + printf ("%02d%02d%03d%c%02d%02d%02d %1.0f%1.0f\n", rah, ram, rafm, sign, + ded, dem, defm, am, ax); } - sscanf(line+50,"%f",&cang); - sscanf(line+54,"%d",&epoch); - - // Year switch - if (year>50) - year+=1900; - else - year+=2000; - - // Format designation - if (piece<26) { - sprintf(desig,"%02d %03d%c",intidy,intido,piece+'A'-1); - sprintf(pdesig,"%02d%03d%c",intidy,intido,piece+'A'-1); - } else { - fprintf(stderr,"Failed to understand designation!\n"); - fprintf(stderr,"%s\n",line); - continue; - } - - // Test data format - if (format==3) { - x=dem*0.6; - dem=(int) floor(x); - defm=(int) (100.0*(x-dem)); - } else if (format!=2) { - fprintf(stderr,"Angle format not implemented!\n"); - fprintf(stderr,"%s\n",line); - continue; - } - - // Fractional seconds - if (fsec<10) - fsec*=100; - else if (fsec<100) - fsec*=10; - - // Time accuracy - if (csec<10) - csec*=0.1; - else if (csec<100) - csec*=0.01; - tx=floor(log10(csec))+8; - tm=floor(csec/pow(10.0,tx-8)); - - // angle accuracy - if (cang<10) - cang*=1; - else if (cang<100) - cang*=0.1; - ax=floor(log10(cang))+8; - am=floor(cang/pow(10.0,ax-8)); - - // Fractional RA - if (rafm<10) - rafm*=100; - else if (rafm<100) - rafm*=10; - - // Fractional DE - if (defm<10) - defm*=10; - else if (defm<100) - defm*=1; - - // Get satellite number - satno=find_satno(pdesig); - - // Format IOD line - printf("%05d %s %04d G %04d%02d%02d%02d%02d%02d%03d %1.0f%1.0f %d%d ",satno,desig,site,year,month,day,hour,min,sec,fsec,tm,tx,format,epoch); - printf("%02d%02d%03d%c%02d%02d%02d %1.0f%1.0f\n",rah,ram,rafm,sign,ded,dem,defm,am,ax); - } - fclose(file); + fclose (file); return 0; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; - - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + int c, i = 0; + + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return i; } - diff --git a/src/vadd.c b/src/vadd.c index 64bd3d9..9bcd323 100644 --- a/src/vadd.c +++ b/src/vadd.c @@ -8,7 +8,7 @@ #include #define LIM 128 -#define XKE 0.07436680 // Guassian Gravitational Constant +#define XKE 0.07436680 // Guassian Gravitational Constant #define XKMPER 6378.135 #define AE 1.0 #define XMNPDA 1440.0 @@ -18,435 +18,491 @@ extern double SGDP4_jd0; // Dot product -float dot(xyz_t a,xyz_t b) +float +dot (xyz_t a, xyz_t b) { - return a.x*b.x+a.y*b.y+a.z*b.z; + return a.x * b.x + a.y * b.y + a.z * b.z; } // Return x modulo y [0,y) -double modulo(double x,double y) +double +modulo (double x, double y) { - x=fmod(x,y); - if (x<0.0) x+=y; + x = fmod (x, y); + if (x < 0.0) + x += y; return x; } // Magnitude -double magnitude(xyz_t a) +double +magnitude (xyz_t a) { - return sqrt(dot(a,a)); + return sqrt (dot (a, a)); } // Cross product -xyz_t cross(xyz_t a,xyz_t b) +xyz_t +cross (xyz_t a, xyz_t b) { xyz_t c; - c.x=a.y*b.z-a.z*b.y; - c.y=a.z*b.x-a.x*b.z; - c.z=a.x*b.y-a.y*b.x; + c.x = a.y * b.z - a.z * b.y; + c.y = a.z * b.x - a.x * b.z; + c.z = a.x * b.y - a.y * b.x; return c; } // Compute Date from Julian Day -void mjd2date(double mjd,int *year,int *month,double *day) +void +mjd2date (double mjd, int *year, int *month, double *day) { - double f,jd; - int z,alpha,a,b,c,d,e; + double f, jd; + int z, alpha, a, b, c, d, e; - jd=mjd+2400000.5; - jd+=0.5; + jd = mjd + 2400000.5; + jd += 0.5; - z=floor(jd); - f=fmod(jd,1.); + z = floor (jd); + f = fmod (jd, 1.); - if (z<2299161) - a=z; - else { - alpha=floor((z-1867216.25)/36524.25); - a=z+1+alpha-floor(alpha/4.); - } - b=a+1524; - c=floor((b-122.1)/365.25); - d=floor(365.25*c); - e=floor((b-d)/30.6001); - - *day=b-d-floor(30.6001*e)+f; - if (e<14) - *month=e-1; + if (z < 2299161) + a = z; else - *month=e-13; + { + alpha = floor ((z - 1867216.25) / 36524.25); + a = z + 1 + alpha - floor (alpha / 4.); + } + b = a + 1524; + c = floor ((b - 122.1) / 365.25); + d = floor (365.25 * c); + e = floor ((b - d) / 30.6001); - if (*month>2) - *year=c-4716; + *day = b - d - floor (30.6001 * e) + f; + if (e < 14) + *month = e - 1; else - *year=c-4715; + *month = e - 13; + + if (*month > 2) + *year = c - 4716; + else + *year = c - 4715; return; } // MJD to DOY -double mjd2doy(double mjd,int *yr) +double +mjd2doy (double mjd, int *yr) { - int year,month,k=2; - double day,doy; - - mjd2date(mjd,&year,&month,&day); + int year, month, k = 2; + double day, doy; - if (year%4==0 && year%400!=0) - k=1; + mjd2date (mjd, &year, &month, &day); - doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - *yr=year; + doy = + floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30; + + *yr = year; return doy; } // Clasical elements -orbit_t classel(int ep_year,double ep_day,xyz_t r,xyz_t v) +orbit_t +classel (int ep_year, double ep_day, xyz_t r, xyz_t v) { int i; - double rm,vm,vm2,rvm,mu=1.0;; - double chi,xp,yp,sx,cx,b,ee; - double a,ecc,incl,node,peri,mm,n; - xyz_t h,e,kk,nn; + double rm, vm, vm2, rvm, mu = 1.0;; + double chi, xp, yp, sx, cx, b, ee; + double a, ecc, incl, node, peri, mm, n; + xyz_t h, e, kk, nn; orbit_t orb; - r.x/=XKMPER; - r.y/=XKMPER; - r.z/=XKMPER; - v.x/=(XKE*XKMPER/AE*XMNPDA/86400.0); - v.y/=(XKE*XKMPER/AE*XMNPDA/86400.0); - v.z/=(XKE*XKMPER/AE*XMNPDA/86400.0); + r.x /= XKMPER; + r.y /= XKMPER; + r.z /= XKMPER; + v.x /= (XKE * XKMPER / AE * XMNPDA / 86400.0); + v.y /= (XKE * XKMPER / AE * XMNPDA / 86400.0); + v.z /= (XKE * XKMPER / AE * XMNPDA / 86400.0); - rm=magnitude(r); - vm2=dot(v,v); - rvm=dot(r,v); - h=cross(r,v); - chi=dot(h,h)/mu; + rm = magnitude (r); + vm2 = dot (v, v); + rvm = dot (r, v); + h = cross (r, v); + chi = dot (h, h) / mu; - e.x=(vm2/mu-1.0/rm)*r.x-rvm/mu*v.x; - e.y=(vm2/mu-1.0/rm)*r.y-rvm/mu*v.y; - e.z=(vm2/mu-1.0/rm)*r.z-rvm/mu*v.z; + e.x = (vm2 / mu - 1.0 / rm) * r.x - rvm / mu * v.x; + e.y = (vm2 / mu - 1.0 / rm) * r.y - rvm / mu * v.y; + e.z = (vm2 / mu - 1.0 / rm) * r.z - rvm / mu * v.z; - a=pow(2.0/rm-vm2/mu,-1); - ecc=magnitude(e); - incl=acos(h.z/magnitude(h))*R2D; - - kk.x=0.0; - kk.y=0.0; - kk.z=1.0; - nn=cross(kk,h); - if (nn.x==0.0 && nn.y==0.0) - nn.x=1.0; - node=atan2(nn.y,nn.x)*R2D; - if (node<0.0) - node+=360.0; + a = pow (2.0 / rm - vm2 / mu, -1); + ecc = magnitude (e); + incl = acos (h.z / magnitude (h)) * R2D; - peri=acos(dot(nn,e)/(magnitude(nn)*ecc))*R2D; - if (e.z<0.0) - peri=360.0-peri; - if (peri<0.0) - peri+=360.0; + kk.x = 0.0; + kk.y = 0.0; + kk.z = 1.0; + nn = cross (kk, h); + if (nn.x == 0.0 && nn.y == 0.0) + nn.x = 1.0; + node = atan2 (nn.y, nn.x) * R2D; + if (node < 0.0) + node += 360.0; + + peri = acos (dot (nn, e) / (magnitude (nn) * ecc)) * R2D; + if (e.z < 0.0) + peri = 360.0 - peri; + if (peri < 0.0) + peri += 360.0; // Elliptic motion - if (ecc<1.0) { - xp=(chi-rm)/ecc; - yp=rvm/ecc*sqrt(chi/mu); - b=a*sqrt(1.0-ecc*ecc); - cx=xp/a+ecc; - sx=yp/b; - ee=atan2(sx,cx); - n=XKE*sqrt(mu/(a*a*a)); - mm=(ee-ecc*sx)*R2D; - } - if (mm<0.0) - mm+=360.0; + if (ecc < 1.0) + { + xp = (chi - rm) / ecc; + yp = rvm / ecc * sqrt (chi / mu); + b = a * sqrt (1.0 - ecc * ecc); + cx = xp / a + ecc; + sx = yp / b; + ee = atan2 (sx, cx); + n = XKE * sqrt (mu / (a * a * a)); + mm = (ee - ecc * sx) * R2D; + } + if (mm < 0.0) + mm += 360.0; // Fill - orb.satno=0; - orb.eqinc=incl*D2R; - orb.ascn=node*D2R; - orb.argp=peri*D2R; - orb.mnan=mm*D2R; - orb.ecc=ecc; - orb.rev=XKE*pow(a,-3.0/2.0)*XMNPDA/(2.0*M_PI); - orb.bstar=0.0; - orb.ep_year=ep_year; - orb.ep_day=ep_day; - orb.norb=0; + orb.satno = 0; + orb.eqinc = incl * D2R; + orb.ascn = node * D2R; + orb.argp = peri * D2R; + orb.mnan = mm * D2R; + orb.ecc = ecc; + orb.rev = XKE * pow (a, -3.0 / 2.0) * XMNPDA / (2.0 * M_PI); + orb.bstar = 0.0; + orb.ep_year = ep_year; + orb.ep_day = ep_day; + orb.norb = 0; return orb; } -orbit_t rv2el(int satno,double mjd,xyz_t r0,xyz_t v0) +orbit_t +rv2el (int satno, double mjd, xyz_t r0, xyz_t v0) { - int i,imode; - orbit_t orb[5],orb1[5]; - xyz_t r,v; + int i, imode; + orbit_t orb[5], orb1[5]; + xyz_t r, v; kep_t kep; - char line1[70],line2[70]; + char line1[70], line2[70]; int ep_year; double ep_day; // Epoch - ep_day=mjd2doy(mjd,&ep_year); + ep_day = mjd2doy (mjd, &ep_year); // Initial guess - orb[0]=classel(ep_year,ep_day,r0,v0); - orb[0].satno=satno; - - for (i=0;i<4;i++) { - // Propagate - imode=init_sgdp4(&orb[i]); - imode=satpos_xyz(mjd+2400000.5,&r,&v); + orb[0] = classel (ep_year, ep_day, r0, v0); + orb[0].satno = satno; - // Compute initial orbital elements - orb1[i]=classel(ep_year,ep_day,r,v); + for (i = 0; i < 4; i++) + { + // Propagate + imode = init_sgdp4 (&orb[i]); + imode = satpos_xyz (mjd + 2400000.5, &r, &v); - // Adjust - orb[i+1].rev=orb[i].rev+orb[0].rev-orb1[i].rev; - orb[i+1].ascn=orb[i].ascn+orb[0].ascn-orb1[i].ascn; - orb[i+1].argp=orb[i].argp+orb[0].argp-orb1[i].argp; - orb[i+1].mnan=orb[i].mnan+orb[0].mnan-orb1[i].mnan; - orb[i+1].eqinc=orb[i].eqinc+orb[0].eqinc-orb1[i].eqinc; - orb[i+1].ecc=orb[i].ecc+orb[0].ecc-orb1[i].ecc; - orb[i+1].ep_year=orb[i].ep_year; - orb[i+1].ep_day=orb[i].ep_day; - orb[i+1].satno=orb[i].satno; - orb[i+1].norb=orb[i].norb; - orb[i+1].bstar=orb[i].bstar; + // Compute initial orbital elements + orb1[i] = classel (ep_year, ep_day, r, v); - // Keep in range - if (orb[i+1].ecc<0.0) - orb[i+1].ecc=0.0; - if (orb[i+1].eqinc<0.0) - orb[i+1].eqinc=0.0; - } + // Adjust + orb[i + 1].rev = orb[i].rev + orb[0].rev - orb1[i].rev; + orb[i + 1].ascn = orb[i].ascn + orb[0].ascn - orb1[i].ascn; + orb[i + 1].argp = orb[i].argp + orb[0].argp - orb1[i].argp; + orb[i + 1].mnan = orb[i].mnan + orb[0].mnan - orb1[i].mnan; + orb[i + 1].eqinc = orb[i].eqinc + orb[0].eqinc - orb1[i].eqinc; + orb[i + 1].ecc = orb[i].ecc + orb[0].ecc - orb1[i].ecc; + orb[i + 1].ep_year = orb[i].ep_year; + orb[i + 1].ep_day = orb[i].ep_day; + orb[i + 1].satno = orb[i].satno; + orb[i + 1].norb = orb[i].norb; + orb[i + 1].bstar = orb[i].bstar; - orb[i].mnan=modulo(orb[i].mnan,2.0*M_PI); - orb[i].ascn=modulo(orb[i].ascn,2.0*M_PI); - orb[i].argp=modulo(orb[i].argp,2.0*M_PI); + // Keep in range + if (orb[i + 1].ecc < 0.0) + orb[i + 1].ecc = 0.0; + if (orb[i + 1].eqinc < 0.0) + orb[i + 1].eqinc = 0.0; + } + + orb[i].mnan = modulo (orb[i].mnan, 2.0 * M_PI); + orb[i].ascn = modulo (orb[i].ascn, 2.0 * M_PI); + orb[i].argp = modulo (orb[i].argp, 2.0 * M_PI); return orb[i]; } // Format TLE -void format_tle(orbit_t orb,char *line1,char *line2) +void +format_tle (orbit_t orb, char *line1, char *line2) { - int i,csum; - char sbstar[]=" 00000-0",bstar[13]; + int i, csum; + char sbstar[] = " 00000-0", bstar[13]; // Format Bstar term - if (fabs(orb.bstar)>1e-9) { - sprintf(bstar,"%11.4e",10*orb.bstar); - sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4]; - sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0'; - } + if (fabs (orb.bstar) > 1e-9) + { + sprintf (bstar, "%11.4e", 10 * orb.bstar); + sbstar[0] = bstar[0]; + sbstar[1] = bstar[1]; + sbstar[2] = bstar[3]; + sbstar[3] = bstar[4]; + sbstar[4] = bstar[5]; + sbstar[5] = bstar[6]; + sbstar[6] = bstar[8]; + sbstar[7] = bstar[10]; + sbstar[8] = '\0'; + } // Print lines - sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar); - sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev); + sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0", + orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar); + sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0", + orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc, + DEG (orb.argp), DEG (orb.mnan), orb.rev); // Compute checksums - for (i=0,csum=0;itm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec); - + time (&rawtime); + ptm = gmtime (&rawtime); + + sprintf (s, "%04d-%02d-%02dT%02d:%02d:%02d", ptm->tm_year + 1900, + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, + ptm->tm_sec); + return; } // Compute Julian Day from Date -double date2mjd(int year,int month,double day) +double +date2mjd (int year, int month, double day) { - int a,b; + int a, b; double jd; - if (month<3) { - year--; - month+=12; - } + if (month < 3) + { + year--; + month += 12; + } - a=floor(year/100.); - b=2.-a+floor(a/4.); + a = floor (year / 100.); + b = 2. - a + floor (a / 4.); - if (year<1582) b=0; - if (year==1582 && month<10) b=0; - if (year==1582 && month==10 && day<=4) b=0; + if (year < 1582) + b = 0; + if (year == 1582 && month < 10) + b = 0; + if (year == 1582 && month == 10 && day <= 4) + b = 0; - jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; + jd = + floor (365.25 * (year + 4716)) + floor (30.6001 * (month + 1)) + day + b - + 1524.5; - return jd-2400000.5; + return jd - 2400000.5; } // nfd2mjd -double nfd2mjd(char *date) +double +nfd2mjd (char *date) { - int year,month,day,hour,min,sec; - double mjd,dday; + int year, month, day, hour, min, sec; + double mjd, dday; - sscanf(date,"%04d-%02d-%02dT%02d:%02d:%02d",&year,&month,&day,&hour,&min,&sec); - dday=day+hour/24.0+min/1440.0+sec/86400.0; + sscanf (date, "%04d-%02d-%02dT%02d:%02d:%02d", &year, &month, &day, &hour, + &min, &sec); + dday = day + hour / 24.0 + min / 1440.0 + sec / 86400.0; - mjd=date2mjd(year,month,dday); + mjd = date2mjd (year, month, dday); return mjd; } -void usage(void) +void +usage (void) { - printf("propagate c:i:t:m:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n"); + printf + ("propagate c:i:t:m:\n\nPropagates orbital elements to a new epoch using the SGP4/SDP4 model.\nDefault operation propagates classfd.tle to now,\n\n-c input catalog\n-i Satellite number\n-t New epoch (YYYY-MM-DDTHH:MM:SS)\n-m New epoch (MJD)\n"); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int imode,satno=0,arg,satnomin,flag=0,satnonew=-1; + int imode, satno = 0, arg, satnomin, flag = 0, satnonew = -1; FILE *file; orbit_t orb; - xyz_t r,v,n,dv; - char tlefile[LIM],nfd[32]; - char line1[80],line2[80],desig[20]; - double mjd,ra,de,dr,drmin; - float vadd=0.0; - char direction[16]="radial"; + xyz_t r, v, n, dv; + char tlefile[LIM], nfd[32]; + char line1[80], line2[80], desig[20]; + double mjd, ra, de, dr, drmin; + float vadd = 0.0; + char direction[16] = "radial"; char *env; // Get environment variable - env=getenv("ST_TLEDIR"); - sprintf(tlefile,"%s/classfd.tle",env); + env = getenv ("ST_TLEDIR"); + sprintf (tlefile, "%s/classfd.tle", env); // Set date - nfd_now(nfd); - mjd=nfd2mjd(nfd); + nfd_now (nfd); + mjd = nfd2mjd (nfd); // Decode options - while ((arg=getopt(argc,argv,"c:i:t:m:hv:d:I:"))!=-1) { - switch (arg) { + while ((arg = getopt (argc, argv, "c:i:t:m:hv:d:I:")) != -1) + { + switch (arg) + { - case 't': - strcpy(nfd,optarg); - mjd=nfd2mjd(nfd); - break; + case 't': + strcpy (nfd, optarg); + mjd = nfd2mjd (nfd); + break; - case 'm': - mjd=(double) atof(optarg); - break; - - case 'c': - strcpy(tlefile,optarg); - break; + case 'm': + mjd = (double) atof (optarg); + break; - case 'i': - satno=atoi(optarg); - break; + case 'c': + strcpy (tlefile, optarg); + break; - case 'h': - usage(); - return 0; - break; + case 'i': + satno = atoi (optarg); + break; - case 'v': - vadd=atof(optarg); - break; + case 'h': + usage (); + return 0; + break; - case 'd': - strcpy(direction,optarg); - break; + case 'v': + vadd = atof (optarg); + break; - case 'I': - satnonew=atoi(optarg); - break; + case 'd': + strcpy (direction, optarg); + break; - default: - usage(); - return 0; + case 'I': + satnonew = atoi (optarg); + break; + + default: + usage (); + return 0; + } } - } // Reloop stderr - freopen("/tmp/stderr.txt","w",stderr); + freopen ("/tmp/stderr.txt", "w", stderr); // Open file - file=fopen(tlefile,"r"); - while (read_twoline(file,satno,&orb)==0) { - format_tle(orb,line1,line2); - strcpy(desig,orb.desig); + file = fopen (tlefile, "r"); + while (read_twoline (file, satno, &orb) == 0) + { + format_tle (orb, line1, line2); + strcpy (desig, orb.desig); - // Propagate - imode=init_sgdp4(&orb); - imode=satpos_xyz(mjd+2400000.5,&r,&v); - - // Compute normal - n=cross(r,v); + // Propagate + imode = init_sgdp4 (&orb); + imode = satpos_xyz (mjd + 2400000.5, &r, &v); - // Add velocity - if (strcmp(direction,"prograde")==0) { - dv.x=vadd*v.x/magnitude(v); - dv.y=vadd*v.y/magnitude(v); - dv.z=vadd*v.z/magnitude(v); - } else if (strcmp(direction,"radial")==0) { - dv.x=vadd*r.x/magnitude(r); - dv.y=vadd*r.y/magnitude(r); - dv.z=vadd*r.z/magnitude(r); - } else if (strcmp(direction,"normal")==0) { - dv.x=vadd*n.x/magnitude(n); - dv.y=vadd*n.y/magnitude(n); - dv.z=vadd*n.z/magnitude(n); - } else { - dv.x=0.0; - dv.y=0.0; - dv.z=0.0; + // Compute normal + n = cross (r, v); + + // Add velocity + if (strcmp (direction, "prograde") == 0) + { + dv.x = vadd * v.x / magnitude (v); + dv.y = vadd * v.y / magnitude (v); + dv.z = vadd * v.z / magnitude (v); + } + else if (strcmp (direction, "radial") == 0) + { + dv.x = vadd * r.x / magnitude (r); + dv.y = vadd * r.y / magnitude (r); + dv.z = vadd * r.z / magnitude (r); + } + else if (strcmp (direction, "normal") == 0) + { + dv.x = vadd * n.x / magnitude (n); + dv.y = vadd * n.y / magnitude (n); + dv.z = vadd * n.z / magnitude (n); + } + else + { + dv.x = 0.0; + dv.y = 0.0; + dv.z = 0.0; + } + v.x += dv.x / 1000.0; + v.y += dv.y / 1000.0; + v.z += dv.z / 1000.0; + + // Convert + orb = rv2el (orb.satno, mjd, r, v); + + if (satnonew == -1) + { + strcpy (orb.desig, desig); + } + else + { + strcpy (orb.desig, "15999A"); + orb.satno = satnonew; + } + + // Print tle + format_tle (orb, line1, line2); + printf ("%s\n%s\n# %05d + %g m/s %s\n", line1, line2, satno, vadd, + direction); } - v.x+=dv.x/1000.0; - v.y+=dv.y/1000.0; - v.z+=dv.z/1000.0; - - // Convert - orb=rv2el(orb.satno,mjd,r,v); - - if (satnonew==-1) { - strcpy(orb.desig,desig); - } else { - strcpy(orb.desig,"15999A"); - orb.satno=satnonew; - } - - // Print tle - format_tle(orb,line1,line2); - printf("%s\n%s\n# %05d + %g m/s %s\n",line1,line2,satno,vadd,direction); - } - fclose(file); + fclose (file); return 0; diff --git a/src/versafit.c b/src/versafit.c index 8b49a44..df492fe 100644 --- a/src/versafit.c +++ b/src/versafit.c @@ -4,12 +4,12 @@ #include #include -int OUTPUT=1; // Print output on screen (1 = yes; 0 = no) -int ERRCOMP=0; // Set reduced Chi-Squared to unity (1 = yes; 0 = no) +int OUTPUT = 1; // Print output on screen (1 = yes; 0 = no) +int ERRCOMP = 0; // Set reduced Chi-Squared to unity (1 = yes; 0 = no) -int dsmin(double **,double *,int,double,double (*func)(double *)); -double **simplex(int,double *,double *); -double parabolic_root(double,double,double,double); +int dsmin (double **, double *, int, double, double (*func) (double *)); +double **simplex (int, double *, double *); +double parabolic_root (double, double, double, double); // Versafit fitting routine // @@ -23,126 +23,148 @@ double parabolic_root(double,double,double,double); // tol: tolerance // opt: options // - n: no output -void versafit(int m,int n,double *a,double *da,double (*func)(double *),double dchisq,double tol,char *opt) +void +versafit (int m, int n, double *a, double *da, double (*func) (double *), + double dchisq, double tol, char *opt) { - int i,j,k,l,nfunk,kmax=50; + int i, j, k, l, nfunk, kmax = 50; double chisqmin; - double *b,*db; - double **p,*y; - double d[2],errcomp; + double *b, *db; + double **p, *y; + double d[2], errcomp; // Decode options - if (strchr(opt,'n')!=NULL) OUTPUT=0; - if (strchr(opt,'e')!=NULL) ERRCOMP=1; + if (strchr (opt, 'n') != NULL) + OUTPUT = 0; + if (strchr (opt, 'e') != NULL) + ERRCOMP = 1; // Intialize y - y=(double *) malloc(sizeof(double) * (n+1)); + y = (double *) malloc (sizeof (double) * (n + 1)); - if (dchisq>=0.) { - // Compute simplex and minimize function - p=simplex(n,a,da); - nfunk=dsmin(p,y,n,tol,func); + if (dchisq >= 0.) + { + // Compute simplex and minimize function + p = simplex (n, a, da); + nfunk = dsmin (p, y, n, tol, func); - // Average parameters - for (i=0;i #include -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { struct timeval tv; - for (;;) { - gettimeofday(&tv,0); - if (tv.tv_usec>999000) - break; - } + for (;;) + { + gettimeofday (&tv, 0); + if (tv.tv_usec > 999000) + break; + } return 0; } diff --git a/src/wcsfit.c b/src/wcsfit.c index 3dde5ed..888813f 100644 --- a/src/wcsfit.c +++ b/src/wcsfit.c @@ -12,174 +12,195 @@ #define R2D 180.0/M_PI #define NMAX 4096 -struct catalog { +struct catalog +{ int n; - float x[NMAX],y[NMAX]; - double ra[NMAX],de[NMAX]; - double rx[NMAX],ry[NMAX]; - float xres[NMAX],yres[NMAX],res[NMAX]; - float xrms,yrms,rms; + float x[NMAX], y[NMAX]; + double ra[NMAX], de[NMAX]; + double rx[NMAX], ry[NMAX]; + float xres[NMAX], yres[NMAX], res[NMAX]; + float xrms, yrms, rms; int usage[NMAX]; }; -struct image { - int naxis1,naxis2,nframes; - float *zavg,*zstd,*zmax,*znum; - double ra0,de0; - float x0,y0; - float a[2],b[2]; +struct image +{ + int naxis1, naxis2, nframes; + float *zavg, *zstd, *zmax, *znum; + double ra0, de0; + float x0, y0; + float a[2], b[2]; double mjd; float *dt; }; -struct transformation { - double ra0,de0; - float a[3],b[3]; - float x0,y0; +struct transformation +{ + double ra0, de0; + float a[3], b[3]; + float x0, y0; }; -int fgetline(FILE *file,char *s,int lim); -void forward(double ra0,double de0,double ra,double de,double *x,double *y); -void reverse(double ra0,double de0,double x,double y,double *ra,double *de); -struct catalog read_catalog(char *filename); -void lfit2d(float *x,float *y,float *z,int n,float *a); -void add_fits_keywords(struct transformation t,char *filename); -struct image read_fits(char *filename); +int fgetline (FILE * file, char *s, int lim); +void forward (double ra0, double de0, double ra, double de, double *x, + double *y); +void reverse (double ra0, double de0, double x, double y, double *ra, + double *de); +struct catalog read_catalog (char *filename); +void lfit2d (float *x, float *y, float *z, int n, float *a); +void add_fits_keywords (struct transformation t, char *filename); +struct image read_fits (char *filename); // Modify FITS keywords -void modify_fits_keywords(struct transformation t,char *filename) +void +modify_fits_keywords (struct transformation t, char *filename) { - char card[FITS_LINESZ+1]; - char key[FITS_LINESZ+1]; - char val[FITS_LINESZ+1]; - char com[FITS_LINESZ+1]; + char card[FITS_LINESZ + 1]; + char key[FITS_LINESZ + 1]; + char val[FITS_LINESZ + 1]; + char com[FITS_LINESZ + 1]; - sprintf(val,"%f",t.x0); - keytuple2str(card,"CRPIX1",val,""); - qfits_replace_card(filename,"CRPIX1",card); + sprintf (val, "%f", t.x0); + keytuple2str (card, "CRPIX1", val, ""); + qfits_replace_card (filename, "CRPIX1", card); - sprintf(val,"%f",t.y0); - keytuple2str(card,"CRPIX2",val,""); - qfits_replace_card(filename,"CRPIX2",card); + sprintf (val, "%f", t.y0); + keytuple2str (card, "CRPIX2", val, ""); + qfits_replace_card (filename, "CRPIX2", card); - sprintf(val,"%f",t.ra0); - keytuple2str(card,"CRVAL1",val,""); - qfits_replace_card(filename,"CRVAL1",card); + sprintf (val, "%f", t.ra0); + keytuple2str (card, "CRVAL1", val, ""); + qfits_replace_card (filename, "CRVAL1", card); - sprintf(val,"%f",t.de0); - keytuple2str(card,"CRVAL2",val,""); - qfits_replace_card(filename,"CRVAL2",card); + sprintf (val, "%f", t.de0); + keytuple2str (card, "CRVAL2", val, ""); + qfits_replace_card (filename, "CRVAL2", card); - sprintf(val,"%e",t.a[1]/3600.0); - keytuple2str(card,"CD1_1",val,""); - qfits_replace_card(filename,"CD1_1",card); + sprintf (val, "%e", t.a[1] / 3600.0); + keytuple2str (card, "CD1_1", val, ""); + qfits_replace_card (filename, "CD1_1", card); - sprintf(val,"%e",t.a[2]/3600.0); - keytuple2str(card,"CD1_2",val,""); - qfits_replace_card(filename,"CD1_2",card); + sprintf (val, "%e", t.a[2] / 3600.0); + keytuple2str (card, "CD1_2", val, ""); + qfits_replace_card (filename, "CD1_2", card); - sprintf(val,"%e",t.b[1]/3600.0); - keytuple2str(card,"CD2_1",val,""); - qfits_replace_card(filename,"CD2_1",card); + sprintf (val, "%e", t.b[1] / 3600.0); + keytuple2str (card, "CD2_1", val, ""); + qfits_replace_card (filename, "CD2_1", card); - sprintf(val,"%e",t.b[2]/3600.0); - keytuple2str(card,"CD2_2",val,""); - qfits_replace_card(filename,"CD2_2",card); + sprintf (val, "%e", t.b[2] / 3600.0); + keytuple2str (card, "CD2_2", val, ""); + qfits_replace_card (filename, "CD2_2", card); return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int i,j,k,l,m; + int i, j, k, l, m; struct catalog c; struct transformation t; - double ra0,de0; + double ra0, de0; float rmsmin; - float x[NMAX],y[NMAX],rx[NMAX],ry[NMAX]; + float x[NMAX], y[NMAX], rx[NMAX], ry[NMAX]; struct image img; char filename[128]; - - if (argc==1) - strcpy(filename,"test.fits"); - else if (argc==2) - strcpy(filename,argv[1]); - img=read_fits(filename); - printf("files read\n"); - c=read_catalog("out.dat"); - printf("files read\n"); + if (argc == 1) + strcpy (filename, "test.fits"); + else if (argc == 2) + strcpy (filename, argv[1]); + + img = read_fits (filename); + printf ("files read\n"); + c = read_catalog ("out.dat"); + printf ("files read\n"); // Initial fit - t.ra0=c.ra[0]; - t.de0=c.de[0]; - t.x0=(float) img.naxis1/2.0; - t.y0=(float) img.naxis2/2.0; + t.ra0 = c.ra[0]; + t.de0 = c.de[0]; + t.x0 = (float) img.naxis1 / 2.0; + t.y0 = (float) img.naxis2 / 2.0; - for (l=0;l<10;l++) { - for (j=0;j<5;j++) { - // Transform - for (i=0;i 2 * c.rms) + c.usage[i] = 0; + } } - c.xrms=sqrt(c.xrms/(float) m); - c.yrms=sqrt(c.yrms/(float) m); - c.rms=sqrt(c.rms/(float) m); - - // Deselect outliers - for (i=0;i2*c.rms) - c.usage[i]=0; - } - } - printf("%12.8lf %10.6lf %10.6lf %8.4f %8.4f %8.4f %8.4f\n",img.mjd,t.ra0,t.de0,t.a[1],t.a[2],t.b[1],t.b[2]); - printf("%d/%d %f %f %f\n",m,c.n,c.xrms,c.yrms,c.rms); + printf ("%12.8lf %10.6lf %10.6lf %8.4f %8.4f %8.4f %8.4f\n", img.mjd, t.ra0, + t.de0, t.a[1], t.a[2], t.b[1], t.b[2]); + printf ("%d/%d %f %f %f\n", m, c.n, c.xrms, c.yrms, c.rms); // add_fits_keywords(t,"test.fits"); - modify_fits_keywords(t,filename); + modify_fits_keywords (t, filename); return 0; } // Read a line of maximum length int lim from file FILE into string s -int fgetline(FILE *file,char *s,int lim) +int +fgetline (FILE * file, char *s, int lim) { - int c,i=0; - - while (--lim > 0 && (c=fgetc(file)) != EOF && c != '\n') + int c, i = 0; + + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; @@ -188,170 +209,179 @@ int fgetline(FILE *file,char *s,int lim) } // Read catalog -struct catalog read_catalog(char *filename) +struct catalog +read_catalog (char *filename) { - int i=0; + int i = 0; char line[LIM]; FILE *file; struct catalog c; - file=fopen(filename,"r"); - while (fgetline(file,line,LIM)>0) { - sscanf(line,"%f %f %lf %lf",&c.x[i],&c.y[i],&c.ra[i],&c.de[i]); - c.usage[i]=1; - - i++; - } - fclose(file); - c.n=i; + file = fopen (filename, "r"); + while (fgetline (file, line, LIM) > 0) + { + sscanf (line, "%f %f %lf %lf", &c.x[i], &c.y[i], &c.ra[i], &c.de[i]); + c.usage[i] = 1; + + i++; + } + fclose (file); + c.n = i; return c; } // Linear 2D fit -void lfit2d(float *x,float *y,float *z,int n,float *a) +void +lfit2d (float *x, float *y, float *z, int n, float *a) { - int i,j,m; + int i, j, m; double chisq; - gsl_matrix *X,*cov; - gsl_vector *yy,*w,*c; + gsl_matrix *X, *cov; + gsl_vector *yy, *w, *c; - X=gsl_matrix_alloc(n,3); - yy=gsl_vector_alloc(n); - w=gsl_vector_alloc(n); + X = gsl_matrix_alloc (n, 3); + yy = gsl_vector_alloc (n); + w = gsl_vector_alloc (n); - c=gsl_vector_alloc(3); - cov=gsl_matrix_alloc(3,3); + c = gsl_vector_alloc (3); + cov = gsl_matrix_alloc (3, 3); // Fill matrices - for(i=0;i 0 && (c=fgetc(file)) != EOF && c != '\n') + while (--lim > 0 && (c = fgetc (file)) != EOF && c != '\n') s[i++] = c; if (c == '\t') - c=' '; + c = ' '; if (c == '\n') s[i++] = c; s[i] = '\0'; @@ -102,162 +118,183 @@ int fgetline(FILE *file,char *s,int lim) } // Format TLE -void format_tle(orbit_t orb,char *line1,char *line2) +void +format_tle (orbit_t orb, char *line1, char *line2) { - int i,csum; - char sbstar[]=" 00000-0",bstar[13]; + int i, csum; + char sbstar[] = " 00000-0", bstar[13]; // Format Bstar term - if (fabs(orb.bstar)>1e-9) { - sprintf(bstar,"%11.4e",10*orb.bstar); - sbstar[0] = bstar[0]; sbstar[1] = bstar[1]; sbstar[2] = bstar[3]; sbstar[3] = bstar[4]; - sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0'; - } + if (fabs (orb.bstar) > 1e-9) + { + sprintf (bstar, "%11.4e", 10 * orb.bstar); + sbstar[0] = bstar[0]; + sbstar[1] = bstar[1]; + sbstar[2] = bstar[3]; + sbstar[3] = bstar[4]; + sbstar[4] = bstar[5]; + sbstar[5] = bstar[6]; + sbstar[6] = bstar[8]; + sbstar[7] = bstar[10]; + sbstar[8] = '\0'; + } // Print lines - sprintf(line1,"1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.desig,orb.ep_year-2000,orb.ep_day,sbstar); - sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f%5ld",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev,orb.norb); + sprintf (line1, "1 %05dU %-8s %2d%012.8f .00000000 00000-0 %8s 0 0", + orb.satno, orb.desig, orb.ep_year - 2000, orb.ep_day, sbstar); + sprintf (line2, "2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f%5ld", + orb.satno, DEG (orb.eqinc), DEG (orb.ascn), 1E7 * orb.ecc, + DEG (orb.argp), DEG (orb.mnan), orb.rev, orb.norb); // Compute checksums - for (i=0,csum=0;i360.0) - *ra-=360.0; + *ra = (atan2 (a, b) + z) * R2D; + *de = asin (c) * R2D; + + if (*ra < 360.0) + *ra += 360.0; + if (*ra > 360.0) + *ra -= 360.0; return; } // Read data file -struct data read_data(char *filename,double mjd0) +struct data +read_data (char *filename, double mjd0) { - int i=0,status; + int i = 0, status; char line[LIM]; FILE *file; struct data d; int min; - double ra,de,ra0,de0,r; - double x,y,z; + double ra, de, ra0, de0, r; + double x, y, z; // Open file - file=fopen(filename,"r"); - if (file==NULL) { - fprintf(stderr,"Failed to open %s\n",filename); - exit(1); - } + file = fopen (filename, "r"); + if (file == NULL) + { + fprintf (stderr, "Failed to open %s\n", filename); + exit (1); + } // Count lines - while (fgetline(file,line,LIM)>0) + while (fgetline (file, line, LIM) > 0) i++; - d.n=i; + d.n = i; // Allocate - d.p=(struct point *) malloc(sizeof(struct point)*d.n); + d.p = (struct point *) malloc (sizeof (struct point) * d.n); // Rewind file - rewind(file); + rewind (file); // Read data - i=0; - while (fgetline(file,line,LIM)>0) { - status=sscanf(line,"%d,%lf,%lf,%lf",&min,&x,&y,&z); - if (d.n==1008) - min*=10; - d.p[i].mjd=mjd0+(double) min/1440.0; + i = 0; + while (fgetline (file, line, LIM) > 0) + { + status = sscanf (line, "%d,%lf,%lf,%lf", &min, &x, &y, &z); + if (d.n == 1008) + min *= 10; + d.p[i].mjd = mjd0 + (double) min / 1440.0; - // Precess position - r=sqrt(x*x+y*y+z*z); - ra0=atan2(y,x)*R2D; - de0=asin(z/r)*R2D; + // Precess position + r = sqrt (x * x + y * y + z * z); + ra0 = atan2 (y, x) * R2D; + de0 = asin (z / r) * R2D; - precess(51544.5,ra0,de0,d.p[i].mjd,&ra,&de); - d.p[i].r.x=r*cos(de*D2R)*cos(ra*D2R); - d.p[i].r.y=r*cos(de*D2R)*sin(ra*D2R); - d.p[i].r.z=r*sin(de*D2R); + precess (51544.5, ra0, de0, d.p[i].mjd, &ra, &de); + d.p[i].r.x = r * cos (de * D2R) * cos (ra * D2R); + d.p[i].r.y = r * cos (de * D2R) * sin (ra * D2R); + d.p[i].r.z = r * sin (de * D2R); - d.p[i].flag=0; - i++; - } + d.p[i].flag = 0; + i++; + } // Close file - fclose(file); + fclose (file); return d; } // Read tle -orbit_t read_tle(char *filename,int satno) +orbit_t +read_tle (char *filename, int satno) { int i; FILE *file; orbit_t orb; - file=fopen(filename,"r"); - if (file==NULL) - fatal_error("Failed to open %s\n",filename); + file = fopen (filename, "r"); + if (file == NULL) + fatal_error ("Failed to open %s\n", filename); // Read TLE - read_twoline(file,satno,&orb); - fclose(file); + read_twoline (file, satno, &orb); + fclose (file); return orb; } // Chi-squared -double chisq(double *a) +double +chisq (double *a) { - int i,imode,n; + int i, imode, n; double chisq; - xyz_t satpos,satvel,dr; + xyz_t satpos, satvel, dr; // Construct struct // a[0]: inclination @@ -268,282 +305,301 @@ double chisq(double *a) // a[5]: revs per day // a[6]: bstar drag - if (a[2]<0.0) - a[2]=0.0; - if (a[0]<0.0) { - a[0]*=-1; - a[1]+=180.0; - } else if (a[0]>180.0) { - a[0]=180.0; - } - if (a[5]>20.0) - a[5]=20.0; - if (a[5]<0.1) - a[5]=0.1; + if (a[2] < 0.0) + a[2] = 0.0; + if (a[0] < 0.0) + { + a[0] *= -1; + a[1] += 180.0; + } + else if (a[0] > 180.0) + { + a[0] = 180.0; + } + if (a[5] > 20.0) + a[5] = 20.0; + if (a[5] < 0.1) + a[5] = 0.1; // Set parameters - orb.eqinc=RAD(a[0]); - orb.ascn=RAD(modulo(a[1],360.0)); - orb.ecc=a[2]; - orb.argp=RAD(modulo(a[3],360.0)); - orb.mnan=RAD(modulo(a[4],360.0)); - orb.rev=a[5]; - orb.bstar=a[6]; + orb.eqinc = RAD (a[0]); + orb.ascn = RAD (modulo (a[1], 360.0)); + orb.ecc = a[2]; + orb.argp = RAD (modulo (a[3], 360.0)); + orb.mnan = RAD (modulo (a[4], 360.0)); + orb.rev = a[5]; + orb.bstar = a[6]; // Initialize - imode=init_sgdp4(&orb); - if (imode==SGDP4_ERROR) - printf("Error\n"); + imode = init_sgdp4 (&orb); + if (imode == SGDP4_ERROR) + printf ("Error\n"); // Loop over points - for (i=0,chisq=0.0,n=0;i2) - *year=c-4716; + *day = b - d - floor (30.6001 * e) + f; + if (e < 14) + *month = e - 1; else - *year=c-4715; + *month = e - 13; + + if (*month > 2) + *year = c - 4716; + else + *year = c - 4715; return; } // MJD to DOY -double mjd2doy(double mjd,int *yr) +double +mjd2doy (double mjd, int *yr) { - int year,month,k=2; - double day,doy; - - mjd2date(mjd,&year,&month,&day); + int year, month, k = 2; + double day, doy; - if (year%4==0 && year%400!=0) - k=1; + mjd2date (mjd, &year, &month, &day); - doy=floor(275.0*month/9.0)-k*floor((month+9.0)/12.0)+day-30; + if (year % 4 == 0 && year % 400 != 0) + k = 1; - *yr=year; + doy = + floor (275.0 * month / 9.0) - k * floor ((month + 9.0) / 12.0) + day - 30; + + *yr = year; return doy; } // Clasical elements -orbit_t classel(int ep_year,double ep_day,xyz_t r,xyz_t v) +orbit_t +classel (int ep_year, double ep_day, xyz_t r, xyz_t v) { int i; - double rm,vm,vm2,rvm,mu=1.0;; - double chi,xp,yp,sx,cx,b,ee; - double a,ecc,incl,node,peri,mm,n; - xyz_t h,e,kk,nn; + double rm, vm, vm2, rvm, mu = 1.0;; + double chi, xp, yp, sx, cx, b, ee; + double a, ecc, incl, node, peri, mm, n; + xyz_t h, e, kk, nn; orbit_t orb; - r.x/=XKMPER; - r.y/=XKMPER; - r.z/=XKMPER; - v.x/=(XKE*XKMPER/AE*XMNPDA/86400.0); - v.y/=(XKE*XKMPER/AE*XMNPDA/86400.0); - v.z/=(XKE*XKMPER/AE*XMNPDA/86400.0); + r.x /= XKMPER; + r.y /= XKMPER; + r.z /= XKMPER; + v.x /= (XKE * XKMPER / AE * XMNPDA / 86400.0); + v.y /= (XKE * XKMPER / AE * XMNPDA / 86400.0); + v.z /= (XKE * XKMPER / AE * XMNPDA / 86400.0); - rm=magnitude(r); - vm2=dot(v,v); - rvm=dot(r,v); - h=cross(r,v); - chi=dot(h,h)/mu; + rm = magnitude (r); + vm2 = dot (v, v); + rvm = dot (r, v); + h = cross (r, v); + chi = dot (h, h) / mu; - e.x=(vm2/mu-1.0/rm)*r.x-rvm/mu*v.x; - e.y=(vm2/mu-1.0/rm)*r.y-rvm/mu*v.y; - e.z=(vm2/mu-1.0/rm)*r.z-rvm/mu*v.z; + e.x = (vm2 / mu - 1.0 / rm) * r.x - rvm / mu * v.x; + e.y = (vm2 / mu - 1.0 / rm) * r.y - rvm / mu * v.y; + e.z = (vm2 / mu - 1.0 / rm) * r.z - rvm / mu * v.z; - a=pow(2.0/rm-vm2/mu,-1); - ecc=magnitude(e); - incl=acos(h.z/magnitude(h))*R2D; - - kk.x=0.0; - kk.y=0.0; - kk.z=1.0; - nn=cross(kk,h); - if (nn.x==0.0 && nn.y==0.0) - nn.x=1.0; - node=atan2(nn.y,nn.x)*R2D; - if (node<0.0) - node+=360.0; + a = pow (2.0 / rm - vm2 / mu, -1); + ecc = magnitude (e); + incl = acos (h.z / magnitude (h)) * R2D; - peri=acos(dot(nn,e)/(magnitude(nn)*ecc))*R2D; - if (e.z<0.0) - peri=360.0-peri; - if (peri<0.0) - peri+=360.0; + kk.x = 0.0; + kk.y = 0.0; + kk.z = 1.0; + nn = cross (kk, h); + if (nn.x == 0.0 && nn.y == 0.0) + nn.x = 1.0; + node = atan2 (nn.y, nn.x) * R2D; + if (node < 0.0) + node += 360.0; + + peri = acos (dot (nn, e) / (magnitude (nn) * ecc)) * R2D; + if (e.z < 0.0) + peri = 360.0 - peri; + if (peri < 0.0) + peri += 360.0; // Elliptic motion - if (ecc<1.0) { - xp=(chi-rm)/ecc; - yp=rvm/ecc*sqrt(chi/mu); - b=a*sqrt(1.0-ecc*ecc); - cx=xp/a+ecc; - sx=yp/b; - ee=atan2(sx,cx); - n=XKE*sqrt(mu/(a*a*a)); - mm=(ee-ecc*sx)*R2D; - } - if (mm<0.0) - mm+=360.0; + if (ecc < 1.0) + { + xp = (chi - rm) / ecc; + yp = rvm / ecc * sqrt (chi / mu); + b = a * sqrt (1.0 - ecc * ecc); + cx = xp / a + ecc; + sx = yp / b; + ee = atan2 (sx, cx); + n = XKE * sqrt (mu / (a * a * a)); + mm = (ee - ecc * sx) * R2D; + } + if (mm < 0.0) + mm += 360.0; // Fill - orb.satno=0; - orb.eqinc=incl*D2R; - orb.ascn=node*D2R; - orb.argp=peri*D2R; - orb.mnan=mm*D2R; - orb.ecc=ecc; - orb.rev=XKE*pow(a,-3.0/2.0)*XMNPDA/(2.0*M_PI); - orb.bstar=0.0; - orb.ep_year=ep_year; - orb.ep_day=ep_day; - orb.norb=0; + orb.satno = 0; + orb.eqinc = incl * D2R; + orb.ascn = node * D2R; + orb.argp = peri * D2R; + orb.mnan = mm * D2R; + orb.ecc = ecc; + orb.rev = XKE * pow (a, -3.0 / 2.0) * XMNPDA / (2.0 * M_PI); + orb.bstar = 0.0; + orb.ep_year = ep_year; + orb.ep_day = ep_day; + orb.norb = 0; return orb; } // State vector to SGP4 elements -orbit_t rv2el(int satno,double mjd,xyz_t r0,xyz_t v0) +orbit_t +rv2el (int satno, double mjd, xyz_t r0, xyz_t v0) { - int i,imode; - orbit_t orb[5],orb1[5]; - xyz_t r,v; + int i, imode; + orbit_t orb[5], orb1[5]; + xyz_t r, v; kep_t kep; - char line1[70],line2[70]; + char line1[70], line2[70]; int ep_year; double ep_day; // Epoch - ep_day=mjd2doy(mjd,&ep_year); + ep_day = mjd2doy (mjd, &ep_year); // Initial guess - orb[0]=classel(ep_year,ep_day,r0,v0); - orb[0].satno=satno; - - for (i=0;i<4;i++) { - // Propagate - imode=init_sgdp4(&orb[i]); - imode=satpos_xyz(mjd+2400000.5,&r,&v); + orb[0] = classel (ep_year, ep_day, r0, v0); + orb[0].satno = satno; - // Compute initial orbital elements - orb1[i]=classel(ep_year,ep_day,r,v); + for (i = 0; i < 4; i++) + { + // Propagate + imode = init_sgdp4 (&orb[i]); + imode = satpos_xyz (mjd + 2400000.5, &r, &v); - // Adjust - orb[i+1].rev=orb[i].rev+orb[0].rev-orb1[i].rev; - orb[i+1].ascn=orb[i].ascn+orb[0].ascn-orb1[i].ascn; - orb[i+1].argp=orb[i].argp+orb[0].argp-orb1[i].argp; - orb[i+1].mnan=orb[i].mnan+orb[0].mnan-orb1[i].mnan; - orb[i+1].eqinc=orb[i].eqinc+orb[0].eqinc-orb1[i].eqinc; - orb[i+1].ecc=orb[i].ecc+orb[0].ecc-orb1[i].ecc; - orb[i+1].ep_year=orb[i].ep_year; - orb[i+1].ep_day=orb[i].ep_day; - orb[i+1].satno=orb[i].satno; - orb[i+1].norb=orb[i].norb; - orb[i+1].bstar=orb[i].bstar; + // Compute initial orbital elements + orb1[i] = classel (ep_year, ep_day, r, v); - // Keep in range - if (orb[i+1].ecc<0.0) - orb[i+1].ecc=0.0; - if (orb[i+1].eqinc<0.0) - orb[i+1].eqinc=0.0; - } + // Adjust + orb[i + 1].rev = orb[i].rev + orb[0].rev - orb1[i].rev; + orb[i + 1].ascn = orb[i].ascn + orb[0].ascn - orb1[i].ascn; + orb[i + 1].argp = orb[i].argp + orb[0].argp - orb1[i].argp; + orb[i + 1].mnan = orb[i].mnan + orb[0].mnan - orb1[i].mnan; + orb[i + 1].eqinc = orb[i].eqinc + orb[0].eqinc - orb1[i].eqinc; + orb[i + 1].ecc = orb[i].ecc + orb[0].ecc - orb1[i].ecc; + orb[i + 1].ep_year = orb[i].ep_year; + orb[i + 1].ep_day = orb[i].ep_day; + orb[i + 1].satno = orb[i].satno; + orb[i + 1].norb = orb[i].norb; + orb[i + 1].bstar = orb[i].bstar; - orb[i].mnan=modulo(orb[i].mnan,2.0*M_PI); - orb[i].ascn=modulo(orb[i].ascn,2.0*M_PI); - orb[i].argp=modulo(orb[i].argp,2.0*M_PI); + // Keep in range + if (orb[i + 1].ecc < 0.0) + orb[i + 1].ecc = 0.0; + if (orb[i + 1].eqinc < 0.0) + orb[i + 1].eqinc = 0.0; + } + + orb[i].mnan = modulo (orb[i].mnan, 2.0 * M_PI); + orb[i].ascn = modulo (orb[i].ascn, 2.0 * M_PI); + orb[i].argp = modulo (orb[i].argp, 2.0 * M_PI); return orb[i]; } // Fit -void fit(orbit_t orb,int *ia) +void +fit (orbit_t orb, int *ia) { - int i,n; - double a[7],da[7]; - double db[7]={0.1,0.1,0.002,0.1,0.1,0.01,0.0001}; + int i, n; + double a[7], da[7]; + double db[7] = { 0.1, 0.1, 0.002, 0.1, 0.1, 0.01, 0.0001 }; // Copy parameters - a[0]=orb.eqinc*R2D; - da[0]=da[0]*R2D; - a[1]=orb.ascn*R2D; - da[1]=da[1]*R2D; - a[2]=orb.ecc; - a[3]=orb.argp*R2D; - da[3]=da[3]*R2D; - a[4]=orb.mnan*R2D; - da[4]=da[4]*R2D; - a[5]=orb.rev; - a[6]=orb.bstar; + a[0] = orb.eqinc * R2D; + da[0] = da[0] * R2D; + a[1] = orb.ascn * R2D; + da[1] = da[1] * R2D; + a[2] = orb.ecc; + a[3] = orb.argp * R2D; + da[3] = da[3] * R2D; + a[4] = orb.mnan * R2D; + da[4] = da[4] * R2D; + a[5] = orb.rev; + a[6] = orb.bstar; - for (i=0;i<7;i++) { - if (ia[i]==1) - da[i]=db[i]; - else - da[i]=0.0; - } + for (i = 0; i < 7; i++) + { + if (ia[i] == 1) + da[i] = db[i]; + else + da[i] = 0.0; + } // Construct struct // a[0]: inclination @@ -555,154 +611,173 @@ void fit(orbit_t orb,int *ia) // a[6]: bstar // Count highlighted points - for (i=0,n=0;i0) - versafit(n,7,a,da,chisq,0.0,1e-7,"n"); + if (n > 0) + versafit (n, 7, a, da, chisq, 0.0, 1e-7, "n"); // Return parameters - orb.eqinc=RAD(a[0]); - orb.ascn=RAD(modulo(a[1],360.0)); - orb.ecc=a[2]; - orb.argp=RAD(modulo(a[3],360.0)); - orb.mnan=RAD(modulo(a[4],360.0)); - orb.rev=a[5]; - orb.bstar=a[6]; + orb.eqinc = RAD (a[0]); + orb.ascn = RAD (modulo (a[1], 360.0)); + orb.ecc = a[2]; + orb.argp = RAD (modulo (a[3], 360.0)); + orb.mnan = RAD (modulo (a[4], 360.0)); + orb.rev = a[5]; + orb.bstar = a[6]; return; } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - int i,j,k,arg=0,satno=0,satname=0,usecatalog=0,imode,m=10; + int i, j, k, arg = 0, satno = 0, satname = 0, usecatalog = 0, imode, m = 10; long norb; - char *datafile,*catalog,filename[32]; - int ia[7]={0,0,0,0,0,0,0}; - char line1[70],line2[70],desig[10]; - double mjd,sma,perigee,apogee,xno; - float mag=0.0,dm; - xyz_t r,v; + char *datafile, *catalog, filename[32]; + int ia[7] = { 0, 0, 0, 0, 0, 0, 0 }; + char line1[70], line2[70], desig[10]; + double mjd, sma, perigee, apogee, xno; + float mag = 0.0, dm; + xyz_t r, v; FILE *file; // Decode options - while ((arg=getopt(argc,argv,"d:c:i:n:m:"))!=-1) { - switch(arg) { + while ((arg = getopt (argc, argv, "d:c:i:n:m:")) != -1) + { + switch (arg) + { - case 'd': - datafile=optarg; - break; + case 'd': + datafile = optarg; + break; - case 'c': - catalog=optarg; - usecatalog=1; - break; + case 'c': + catalog = optarg; + usecatalog = 1; + break; - case 'i': - satno=atoi(optarg); - break; + case 'i': + satno = atoi (optarg); + break; - case 'n': - norb=atoi(optarg); - if (norb<0) - norb=0; - break; + case 'n': + norb = atoi (optarg); + if (norb < 0) + norb = 0; + break; - case 'm': - mag=atof(optarg); - break; + case 'm': + mag = atof (optarg); + break; - default: - return 0; + default: + return 0; + } } - } // Magnitude offset - dm=5.0*log10(1000.0/40000.0); + dm = 5.0 * log10 (1000.0 / 40000.0); // Reloop stderr - freopen("/tmp/stderr.txt","w",stderr); + freopen ("/tmp/stderr.txt", "w", stderr); // Decode filename - mjd=decode_filename(datafile,&satname); + mjd = decode_filename (datafile, &satname); // Read data - d=read_data(datafile,mjd); + d = read_data (datafile, mjd); // Write data - sprintf(filename,"%06d.xyz",satname); - file=fopen(filename,"w"); - for (i=0;i