/* Return the difference in ecliptic longitude between object & bary * (e.g., 180 degrees is opposition). * gives Sun - Target so it increases about 1 deg/day. */ double opposition_angle(OBSERVATION *obs) { double lat, lonkbo, lonbary; double xx, yy, zz, xec, yec, zec; if (obs->xe < -9.) { earth3d(obs->obstime, obs->obscode, &(obs->xe),&(obs->ye),&(obs->ze)); } /* Get barycenter ecliptic longitude */ xx = xBary - obs->xe; yy = yBary - obs->ye; zz = zBary - obs->ze; xyz_proj_to_ec(xx, yy, zz, &xec, &yec, &zec, lat0, lon0, NULL); lonbary = atan2(yec,xec); /* And the observation ecliptic longitude*/ proj_to_ec(obs->thetax, obs->thetay, &lat, &lonkbo, lat0, lon0, NULL); lonkbo = lonbary - lonkbo; while (lonkbo<0) lonkbo += 2*PI; return lonkbo; }
void print_radec(OBSERVATION *obs, FILE *fptr) { /* Print out new observation */ /* Now transform to RA/DEC, via ecliptic*/ double ra, dec, lat, lon; char rastring[20],decstring[20]; void deghms(double degr, char *outbuff); void degdms(double degr, char *outbuff); proj_to_ec(obs->thetax,obs->thetay, &lat, &lon, lat0, lon0, NULL); ec_to_eq(lat, lon, &ra, &dec, NULL); ra /= DTOR; if (ra<0.) ra+= 360.; dec /= DTOR; deghms(ra,rastring); degdms(dec,decstring); fprintf(fptr,"%.4f %s %s %5.2f %d\n", obs->obstime/DAY + jd0, rastring,decstring,obs->dthetax/ARCSEC, obs->obscode); return; }
double *predict(char *abg_file, double jdate, int obscode) { PBASIS p; OBSERVATION futobs; struct date_time dt; char inbuff[256], rastring[20], decstring[20]; char outbuff[256]; char *f_string; double **covar,**sigxy,a,b,PA,**derivs; double lat,lon,**covecl; double ra,dec, **coveq; double yr,mo,day,hr,mn,ss; double xx,yy,xy,bovasqrd,det; double distance; static double result[6]; int i,nfields; int iarg=1; sigxy = dmatrix(1,2,1,2); derivs = dmatrix(1,2,1,2); covar = dmatrix(1,6,1,6); covecl = dmatrix(1,2,1,2); coveq = dmatrix(1,2,1,2); result[0] = -1.0; result[1] = -1.0; result[2] = -1.0; result[3] = -1.0; result[4] = -1.0; result[5] = -1.0; if (read_abg(abg_file,&p,covar) ) { fprintf(stderr, "Error input alpha/beta/gamma file %s\n",abg_file); return result; } /* get observatory code */ futobs.obscode=obscode; futobs.obstime=(jdate-jd0)*DAY; futobs.xe = -999.; /* Force evaluation of earth3d */ distance = predict_posn(&p,covar,&futobs,sigxy); /* Now transform to RA/DEC, via ecliptic*/ proj_to_ec(futobs.thetax,futobs.thetay, &lat, &lon, lat0, lon0, derivs); /* map the covariance */ covar_map(sigxy, derivs, covecl, 2, 2); /* Now to ICRS: */ ec_to_eq(lat, lon, &ra, &dec, derivs); /* map the covariance */ covar_map(covecl, derivs, coveq, 2, 2); /* Compute a, b, theta of error ellipse for output */ xx = coveq[1][1]*cos(dec)*cos(dec); xy = coveq[1][2]*cos(dec); yy = coveq[2][2]; PA = 0.5 * atan2(2.*xy,(xx-yy)) * 180./PI; /*go right to degrees*/ /* Put PA N through E */ PA = 90.-PA; bovasqrd = (xx+yy-sqrt(pow(xx-yy,2.)+pow(2.*xy,2.))) / (xx+yy+sqrt(pow(xx-yy,2.)+pow(2.*xy,2.))) ; det = xx*yy-xy*xy; b = pow(det*bovasqrd,0.25); a = pow(det/bovasqrd,0.25); ra /= DTOR; if (ra<0.) ra+= 360.; dec /= DTOR; result[0] = ra; result[1] = dec; result[2] = a/ARCSEC; result[3] = b/ARCSEC; result[4] = PA; result[5] = distance; return result; }
int main(int argc, char *argv[]) { PBASIS p, pfit; ORBIT o, ofit; XVBASIS xv; OBSERVATION futobs; OBSERVATION *oo; FILE *abgfile; char inbuff[256],objname[256],fname[256]; double **covar,**sigxy; double lat,lon; int i,nfields; double x[3], v[3], range; double oppangle, epochs[MAX_EPOCHS], observe_day, period; double x0, y0; int nepochs, iphase, iexpose, iorbit; int dof,ii; double chisq, dbary, ddbary, vis_start, vis_end, jd; double **covar_abg, **covar_xyz, **derivs, **covar_aei; double launch; /*Date to start hunting for oppangle*/ if (argc<2) print_help(); oppangle = atof(argv[1]); epochs[0]=0.; for (i=2; i<argc; i++) epochs[i-1] = atof(argv[i]); nepochs = argc-1; futobs.obscode = OBSCODE_HST; /* echo the command line to output */ printf("#"); for (i=0; i<argc; i++) printf(" %s",argv[i]); { #include <time.h> time_t timettt; time(&timettt); /* note that ctime returns string with newline at end */ printf("\n#---%s",ctime(&timettt)); } printf( "# ID phi distance a e i " " posn d a e i \n" "# real fit err real fit err fit err NEW OBSERVATION:\n"); covar_abg = dmatrix(1,6,1,6); covar_xyz = dmatrix(1,6,1,6); covar_aei = dmatrix(1,6,1,6); derivs = dmatrix(1,6,1,6); sigxy = dmatrix(1,2,1,2); covar = dmatrix(1,6,1,6); /* Loop through input containing names of objects */ while ( fgets_nocomment(inbuff,255,stdin,NULL)!=NULL) { sscanf(inbuff," %s ",objname); strcpy(fname,objname); strcat(fname,SUFFIX); if (read_abg(fname,&p,covar)) { fprintf(stderr, "Error reading alpha/beta/gamma file %s\n",fname); exit(1); } /* look at several points around the orbital phase */ /* get orbital elements for this one */ pbasis_to_bary(&p, &xv, NULL); orbitElements(&xv, &o); period = pow(o.a, 1.5); launch = jd0; for (iphase=0; iphase<PHASE_STEPS; iphase++) { /* Advance the object through its orbit by moving back time * of perihelion (which is in days) */ o.T -= period/ (PHASE_STEPS*DAY); /* Set up new orbit system based on this */ elements_to_pbasis(&o, launch, futobs.obscode, &p); /* Now look for the day at which opp. angle meets spec */ observe_day = launch; seek_oppangle(oppangle, &observe_day, &p, futobs.obscode); futobs.obstime = (observe_day-jd0)*DAY; futobs.xe = -999.; /* Force evaluation of earth3d */ predict_posn(&p,NULL,&futobs,NULL); /* Now transform ecliptic*/ proj_to_ec(futobs.thetax,futobs.thetay, &lat, &lon, lat0, lon0, NULL); /* Only keep objects close to ecliptic */ if (fabs(lat) > LAT_MAX*DTOR) continue; /* Now reset the orbit and coordinate system to start here */ elements_to_pbasis(&o, observe_day, futobs.obscode, &p); nobs = 0; /* accumulate observations at all epochs */ for (i=0; i<nepochs; i++) { /* Advance time until object is NOT visible */ vis_end = observe_day+epochs[i]; do { vis_end+= VIS_TIME_STEP; futobs.obstime = (vis_end-jd0)*DAY; futobs.xe = -999.; /* Force evaluation of earth3d */ predict_posn(&p,NULL,&futobs,NULL); } while (zenith_angle(&futobs) <= ZA_LIMIT) ; for (iorbit=0; iorbit<NORBITS*NFIELDS; iorbit++) { /* Then advance to first time it IS visible. */ vis_start = vis_end; do { vis_start+= VIS_TIME_STEP; futobs.obstime = (vis_start-jd0)*DAY; futobs.xe = -999.; /* Force evaluation of earth3d */ predict_posn(&p,NULL,&futobs,NULL); } while (zenith_angle(&futobs) > ZA_LIMIT) ; /* Now find end of visibility period */ vis_end = vis_start; do { vis_end+= VIS_TIME_STEP; futobs.obstime = (vis_end-jd0)*DAY; futobs.xe = -999.; /* Force evaluation of earth3d */ predict_posn(&p,NULL,&futobs,NULL); } while (zenith_angle(&futobs) <= ZA_LIMIT) ; vis_end -= VIS_TIME_STEP; /* Only proceed if we are observing this field on this orbit*/ if (iorbit%NFIELDS !=0) continue; /* Find middle of each exposure time */ jd = vis_start + (vis_end - vis_start)/(2.*EXP_PER_ORBIT); for (iexpose=0; iexpose<EXP_PER_ORBIT; iexpose++, jd+=(vis_end - vis_start)/EXP_PER_ORBIT) { oo = &obsarray[nobs]; oo->obstime = (jd-jd0)*DAY; oo->xe = -999.; /* Force evaluation of earth3d */ oo->obscode = OBSCODE_HST; predict_posn(&p,NULL,oo,NULL); oo->dthetax = oo->dthetay = ASTROM_ERROR*sqrt(NORBITS*EXP_PER_ORBIT)*ARCSEC; nobs++; /*if (iphase==0) { double ra, dec; char rastring[40], decstring[40]; proj_to_ec(oo->thetax,oo->thetay, &lat, &lon, lat0, lon0, NULL); ec_to_eq(lat, lon, &ra, &dec, NULL); deghms(ra/DTOR,rastring); degdms(dec/DTOR,decstring); fprintf(stderr,"%f %s %s %.3f %d\n",jd, rastring, decstring, oo->dthetax/ARCSEC, OBSCODE_HST); }*/ } /*exposure loop*/ } /*orbit loop*/ } /*observation-epoch loop */ /* Now fit the observations and report results */ ii=fit_observations(obsarray, nobs, &pfit, covar, &chisq, &dof, NULL); /*fprintf(stderr,"# lat0 lon0 xBary yBary zBary JD0\n"); fprintf(stderr,"%12.7f %12.7f %10.7f %10.7f %10.7f %.6f\n", lat0/DTOR,lon0/DTOR,xBary,yBary,zBary,jd0); fprintf(stderr,"# Chi-squared of fit: %.2f DOF: %d\n",chisq,dof); fprintf(stderr,"%11.8f %11.8f %11.8f %11.8f %11.8f %11.8f\n", pfit.a,pfit.adot,pfit.b,pfit.bdot, pfit.g, pfit.gdot); print_matrix(stderr,covar,6,6); */ pbasis_to_bary(&pfit, &xv, derivs); orbitElements(&xv, &ofit); /* Note that below is distance at jd0=abg file zpoint, NOT at * first observation, which is some part of a year later. */ dbary = sqrt(xBary*xBary + yBary*yBary + pow(zBary-1/pfit.g,2.)); ddbary = dbary*dbary*sqrt(covar[5][5]); /* Get elements and covariance matrix thereof */ covar_map(covar, derivs, covar_xyz,6,6); aei_derivs(&xv, derivs); covar_map(covar_xyz, derivs, covar_aei,6,6); /*Print out some info & uncertainties */ printf("%8s %2d %5.2f +- %4.2f %1d %5.2f %5.2f +- %4.2f %5.3f %5.3f +- %5.3f" " %7.1f +- %4.1f", objname, iphase, dbary, ddbary, ii, o.a, ofit.a, sqrt(covar_aei[1][1]), o.e, ofit.e, sqrt(covar_aei[2][2]), ofit.i, sqrt(covar_aei[3][3])/DTOR); /* Now get the positional uncertainty at a future date, and * refit after two extra measurements from ground */ oo = &obsarray[nobs]; nobs++; jd = observe_day + OPP_GRND - oppangle; oo->obstime = (jd-jd0)*DAY; oo->obscode = OBSCODE_GRND; oo->xe = -999.; predict_posn(&pfit,covar,oo,sigxy); /*if (iphase==0) { fprintf(stderr,"Prediction on %.2f, posn %.2f %.2f unc %.2f %.2f\n", jd, oo->thetax/ARCSEC, oo->thetay/ARCSEC, sqrt(sigxy[1][1])/ARCSEC, sqrt(sigxy[2][2])/ARCSEC); print_matrix(stderr,covar,6,6); }*/ { /* Compute a, of error ellipse for output */ double xx, yy, xy, bovasqrd, det, a; xx = sigxy[1][1]; yy = sigxy[2][2]; xy = sigxy[1][2]; bovasqrd = (xx+yy-sqrt(pow(xx-yy,2.)+pow(2.*xy,2.))) / (xx+yy+sqrt(pow(xx-yy,2.)+pow(2.*xy,2.))) ; det = xx*yy-xy*xy; a = pow(det/bovasqrd,0.25); printf(" %5.1f", a/ARCSEC); } /* Now re-fit with two additional observations */ predict_posn(&p,NULL,oo,NULL); oo->dthetax = oo->dthetay = ERROR_GRND * ARCSEC; oo = &obsarray[nobs]; nobs++; oo->obstime = obsarray[nobs-2].obstime + DAY; oo->obscode = OBSCODE_GRND; oo->xe = -999.; predict_posn(&p,NULL,oo,NULL); oo->dthetax = oo->dthetay = ERROR_GRND * ARCSEC; ii = fit_observations(obsarray, nobs, &pfit, covar, &chisq, &dof, NULL); pbasis_to_bary(&pfit, &xv, derivs); orbitElements(&xv, &ofit); dbary = sqrt(xBary*xBary + yBary*yBary + pow(zBary-1/pfit.g,2.)); ddbary = dbary*dbary*sqrt(covar[5][5]); /* Get elements and covariance matrix thereof */ covar_map(covar, derivs, covar_xyz,6,6); aei_derivs(&xv, derivs); covar_map(covar_xyz, derivs, covar_aei,6,6); /*Print out some info & uncertainties */ printf(" %5.2f +- %4.2f %1d %5.2f +- %4.2f %5.3f +- %5.3f" " %7.1f +- %4.1f \n", dbary, ddbary, ii, ofit.a, sqrt(covar_aei[1][1]), ofit.e, sqrt(covar_aei[2][2]), ofit.i, sqrt(covar_aei[3][3])/DTOR); } /*phase loop */ } /*object loop*/ exit(0); }
int main(int argc, char *argv[]) { PBASIS p; OBSERVATION futobs; struct date_time dt; char inbuff[256],rastring[20],decstring[20]; double **covar,**sigxy,a,b,PA,**derivs; double lat,lon,**covecl; double ra,dec, **coveq; double yr,mo,day,hr,mn,ss; double xx,yy,xy,bovasqrd,det; int i,nfields; int iarg=1; if (argc>1 && *argv[1]=='^') print_help(); if (read_options(&iarg, argc, argv)) print_help(); if (iarg>=argc) print_help(); /* echo the command line to output */ printf("#"); for (i=0; i<argc; i++) printf(" %s",argv[i]); { #include <time.h> time_t timettt; time(&timettt); /* note that ctime returns string with newline at end */ printf("\n#---%s",ctime(&timettt)); } sigxy = dmatrix(1,2,1,2); derivs = dmatrix(1,2,1,2); covar = dmatrix(1,6,1,6); covecl = dmatrix(1,2,1,2); coveq = dmatrix(1,2,1,2); if (read_abg(argv[iarg],&p,covar)) { fprintf(stderr, "Error input alpha/beta/gamma file %s\n",argv[iarg]); exit(1); } /* get observatory code */ fprintf (stderr,"Enter observatory code:\n"); if (fgets_nocomment(inbuff,255,stdin,NULL)==NULL || sscanf(inbuff,"%d",&futobs.obscode)!=1) { fprintf(stderr,"Error reading observatory code\n"); exit(1); } printf("# For observations at site %d\n" "# x/RA y/DEC " "err_a err_b err_pa\n",futobs.obscode); fprintf (stderr,"Enter JD's or Y M D ... of observations, -1 to quit:\n"); while ( fgets_nocomment(inbuff,255,stdin,NULL)!=NULL) { nfields=sscanf(inbuff,"%lf %lf %lf %lf %lf %lf", &yr,&mo,&day,&hr,&mn,&ss); if (nfields==0 ) { fprintf(stderr,"Error on time spec:\n->%s\n",inbuff); exit(1); } else if (yr<0.) { /*done*/ exit(0); } else if (nfields==1 || nfields==2) { /* Got a JD. (probably...)*/ futobs.obstime = (yr-jd0)*DAY; } else { dt.y = yr; dt.mo = mo; dt.d = day; if (nfields>=4) dt.h = hr; else dt.h=0.; if (nfields>=5) dt.mn = mn; else dt.mn=0.; if (nfields>=6) dt.s = ss; else dt.s=0.; futobs.obstime = (date_to_jd(dt)-jd0)*DAY; } futobs.xe = -999.; /* Force evaluation of earth3d */ printf("At time= %s",inbuff); predict_posn(&p,covar,&futobs,sigxy); printf("# Solar Elongation = %.2f Opp angle = %.2f\n", elongation(&futobs)/DTOR,opposition_angle(&futobs)/DTOR); /* Compute a, b, theta of error ellipse for output */ xx = sigxy[1][1]; yy = sigxy[2][2]; xy = sigxy[1][2]; PA = 0.5 * atan2(2.*xy,(xx-yy)) * 180./PI; /*go right to degrees*/ /* Adjust for PA to be N through E, */ PA = PA-90; if (PA<-90.) PA += 180.; bovasqrd = (xx+yy-sqrt(pow(xx-yy,2.)+pow(2.*xy,2.))) / (xx+yy+sqrt(pow(xx-yy,2.)+pow(2.*xy,2.))) ; det = xx*yy-xy*xy; b = pow(det*bovasqrd,0.25); a = pow(det/bovasqrd,0.25); printf("Cum. ecliptic posn: %10.4f %10.4f %8.2f %8.2f %7.2f\n", futobs.thetax/ARCSEC, futobs.thetay/ARCSEC, a/ARCSEC,b/ARCSEC,PA); /* Now transform to RA/DEC, via ecliptic*/ proj_to_ec(futobs.thetax,futobs.thetay, &lat, &lon, lat0, lon0, derivs); /* map the covariance */ covar_map(sigxy, derivs, covecl, 2, 2); /* Now to ICRS: */ ec_to_eq(lat, lon, &ra, &dec, derivs); /* map the covariance */ covar_map(covecl, derivs, coveq, 2, 2); /* Compute a, b, theta of error ellipse for output */ xx = coveq[1][1]*cos(dec)*cos(dec); xy = coveq[1][2]*cos(dec); yy = coveq[2][2]; PA = 0.5 * atan2(2.*xy,(xx-yy)) * 180./PI; /*go right to degrees*/ /* Put PA N through E */ PA = 90.-PA; bovasqrd = (xx+yy-sqrt(pow(xx-yy,2.)+pow(2.*xy,2.))) / (xx+yy+sqrt(pow(xx-yy,2.)+pow(2.*xy,2.))) ; det = xx*yy-xy*xy; b = pow(det*bovasqrd,0.25); a = pow(det/bovasqrd,0.25); ra /= DTOR; if (ra<0.) ra+= 360.; dec /= DTOR; deghms(ra,rastring); degdms(dec,decstring); printf("ICRS position: %s %s %10.4f %10.4f %7.2f\n", rastring,decstring,a/ARCSEC,b/ARCSEC,PA); } exit(0); }