/* Function to return xyz coords of a JPL ephemeris body in * standard coordinate system. */ void body3d(double t, /* time is in years here */ int body, double *x, double *y, double *z, double *vxyz) { double xxx[3]; double xec, yec, zec; /* get observatory posn wrt barycenter */ bodycenter_ssbary(t/DAY+jd0, xxx, body, vxyz); /*fprintf(stderr,"bodycenter for %d: %f %f %f\n",body,xxx[0],xxx[1],xxx[2]);*/ /* convert to tangent-point coord system */ /* via ecliptic */ xyz_eq_to_ec(xxx[0], xxx[1], xxx[2], &xec, &yec, &zec,NULL); xyz_ec_to_proj(xec, yec, zec, x, y, z, lat0, lon0, NULL); /* Translate to our origin */ *x += xBary; *y += yBary; *z += zBary; /* Rotate velocity if it has bee requested: */ if (vxyz != NULL) { xyz_eq_to_ec(vxyz[0], vxyz[1], vxyz[2], &xec, &yec, &zec,NULL); xyz_ec_to_proj(xec, yec, zec, vxyz, vxyz+1, vxyz+2, lat0, lon0, NULL); } return; }
/* Transform from an orbital element representation to a PBASIS * description. Sets up projected coordinate system to the proper * situation for the desired epoch as well, so the global lat0, lon0, * etc. will be changed. */ void elements_to_pbasis(ORBIT *o, double jd, int obscode, PBASIS *p) { XVBASIS xv; double xec, yec, zec; elements_to_xv(o, jd, &xv); /* Set up a new coordinate system that centers on current-epoch * positions */ earth_ssbary(jd, obscode, &xBary, &yBary, &zBary); /* Get target vector in ecliptic coords, set lat0/lon0 */ xBary *= -1.; yBary *= -1.; zBary *= -1.; xyz_eq_to_ec(xBary, yBary, zBary, &xec, &yec, &zec,NULL); xv.x += xec; xv.y+=yec; xv.z+=zec; lon0 = atan2(xv.y, xv.x); lat0 = asin( xv.z / sqrt(xv.x*xv.x + xv.y*xv.y + xv.z*xv.z)); jd0 = jd; /* Rotate target and bary into the projected system */ xyz_ec_to_proj(xec, yec, zec, &xBary, &yBary, &zBary, lat0, lon0, NULL); xyz_ec_to_proj(xv.x, xv.y, xv.z, &xv.x, &xv.y, &xv.z, lat0, lon0, NULL); xyz_ec_to_proj(xv.xdot, xv.ydot, xv.zdot, &xv.xdot, &xv.ydot, &xv.zdot, lat0, lon0, NULL); p->g = 1./xv.z; p->a = xv.x * p->g; p->b = xv.y * p->g; p->adot = xv.xdot * p->g; p->bdot = xv.ydot * p->g; p->gdot = xv.zdot * p->g; return; }
/* Input file is stdin if fname==NULL */ int read_radec(OBSERVATION obsarray[], char *fname, int *nobs) { FILE *fptr; OBSERVATION *obs; int i; char inbuff[256]; double jd,ra,dec,elat,elon; if (fname==NULL) fptr = stdin; else if ( (fptr=fopen(fname,"r"))==NULL) { fprintf(stderr,"Error opening observations file %s\n",fname); exit(1); } *nobs=0; while ( fgets_nocomment(inbuff,255,fptr,NULL)!=NULL) { if ( scan_observation(inbuff, &(obsarray[*nobs]))) { fprintf(stderr,"Quitting on format error\n"); exit(1); } obs = &(obsarray[*nobs]); (*nobs)++; eq_to_ec(obs->thetax,obs->thetay,&elat,&elon,NULL); if (*nobs==1) { double xec, yec, zec; /* Use first observation to set the reference frame */ jd0 = obs->obstime; lat0 = elat; lon0 = elon; /* Find location of SSBARY wrt observatory at zero time */ earth_ssbary(jd0, obs->obscode, &xBary, &yBary, &zBary); /* Negate the vector to make it earth->SSBARY*/ /* And rotate equatorial into the tangent-point coords */ xBary *= -1.; yBary *= -1.; zBary *= -1.; xyz_eq_to_ec(xBary, yBary, zBary, &xec, &yec, &zec,NULL); xyz_ec_to_proj(xec, yec, zec, &xBary, &yBary, &zBary, lat0, lon0, NULL); } /* Set time to years after jd0, rotate to tangent plane coords */ obs->obstime = (obs->obstime-jd0)*DAY; ec_to_proj(elat,elon,&(obs->thetax),&(obs->thetay), lat0,lon0,NULL); /* Calculate the position of Earth at this time to avoid doing * it many times later: */ earth3d(obs->obstime, obs->obscode, &(obs->xe),&(obs->ye),&(obs->ze)); } if (fname!=NULL) fclose(fptr); return(0); }
/* Function to return xyz coords of observatory in the current * standard coordinate system. */ void earth3d(double t, /* time is in years here */ int obscode, double *x, double *y, double *z) { double x1,y1,z1,xTelEq,yTelEq,zTelEq; double xec, yec, zec; /* get observatory posn wrt barycenter */ earth_ssbary(t/DAY+jd0, obscode, &x1, &y1, &z1); /* convert to tangent-point coord system */ /* via ecliptic */ xyz_eq_to_ec(x1, y1, z1, &xec, &yec, &zec,NULL); xyz_ec_to_proj(xec, yec, zec, x, y, z, lat0, lon0, NULL); /* Translate to our origin */ *x += xBary; *y += yBary; *z += zBary; return; }
/* Function to return xyz coords of observatory in the current * standard coordinate system based on 2line MPC supplied values */ void mpc3d(double t, /* time is in years here */ double *x, double *y, double *z) { double xTelEq,yTelEq,zTelEq; double xec, yec, zec; double xgeo[3]; geo_to_ssbary(t/DAY+jd0, x, y, z); /* convert to tangent-point coord system */ /* via ecliptic */ xyz_eq_to_ec(*x, *y, *z, &xec, &yec, &zec,NULL); xyz_ec_to_proj(xec, yec, zec, x, y, z, lat0, lon0, NULL); /* Translate to our origin */ *x += xBary; *y += yBary; *z += zBary; return; }
/* Return the angle btwn zenith (anti-earth) direction and target*/ double zenith_angle(OBSERVATION *obs) { double xobs, yobs, zobs, r; double xec, yec, zec, cosb; /* Get the anti-Earth vector (in ICRS) for this observation */ observatory_geocenter(obs->obstime/DAY+jd0, obs->obscode, &xobs, &yobs, &zobs); r = sqrt(xobs*xobs+yobs*yobs+zobs*zobs); if (r<=0.) { fprintf(stderr,"Non-positive geocentric radius in zenith_angle()\n"); exit(1); } xobs /=r; yobs/=r; zobs/=r; /* Rotate this ICRS vector into ecliptic, then projected coords */ xyz_eq_to_ec(xobs, yobs, zobs, &xec, &yec, &zec,NULL); xyz_ec_to_proj(xec, yec, zec, &xobs, &yobs, &zobs, lat0, lon0, NULL); /* dot the observation direction into the (Earth->bary) vector*/ cosb = obs->thetax*xobs + obs->thetay*yobs + zobs; cosb /= sqrt(1+obs->thetax*obs->thetax+obs->thetay*obs->thetay); return acos(cosb); }
/* Input file is stdin if fname==NULL */ int read_radec(OBSERVATION obsarray[], char *fname, int *nobs) { FILE *fptr; OBSERVATION *obs; int scan_status_flag; int i; char inbuff[256]; double jd,ra,dec,elat,elon; if (fname==NULL) fptr = stdin; else if ( (fptr=fopen(fname,"r"))==NULL) { fprintf(stderr,"Error opening observations file %s\n",fname); exit(1); } *nobs=0; while ( fgets_nocomment(inbuff,255,fptr,NULL)!=NULL) { // obs refers to the previous observation, after the first loop. scan_status_flag = scan_observation(inbuff, &(obsarray[*nobs]), obs); // scanned line was 2nd line of two line format so don't advance nobs as all we did was reset the observer x/y if (scan_status_flag == -1) { mpc3d(obs->obstime, &(obs->xe), &(obs->ye), &(obs->ze)); continue; } // all other non-zero status values indicate an error. if ( scan_status_flag == 1) { fprintf(stderr,"Quitting on format error\n"); exit(1); } obs = &(obsarray[*nobs]); (*nobs)++; eq_to_ec(obs->thetax,obs->thetay,&elat,&elon,NULL); if (*nobs==1) { double xec, yec, zec; /* Use first observation to set the reference frame */ jd0 = obs->obstime; lat0 = elat; lon0 = elon; /* fprintf(stderr, "%f %f %f %d\n", elat, elon, obs->obstime, obs->obscode); */ /* Find location of SSBARY wrt observatory at zero time */ earth_ssbary(jd0, obs->obscode, &xBary, &yBary, &zBary); /* fprintf(stderr, "%f %f %f %d\n", elat, elon, obs->obstime, obs->obscode); */ /* Negate the vector to make it earth->SSBARY*/ /* And rotate equatorial into the tangent-point coords */ xBary *= -1.; yBary *= -1.; zBary *= -1.; xyz_eq_to_ec(xBary, yBary, zBary, &xec, &yec, &zec,NULL); xyz_ec_to_proj(xec, yec, zec, &xBary, &yBary, &zBary, lat0, lon0, NULL); } /* fprintf(stderr,"%f %f", lat0, lon0); */ /* Set time to years after jd0, rotate to tangent plane coords */ obs->obstime = (obs->obstime-jd0)*DAY; ec_to_proj(elat,elon,&(obs->thetax),&(obs->thetay), lat0,lon0,NULL); /* Calculate the position of Earth at this time to avoid doing * it many times later: */ if (scan_status_flag == -2) { mpc3d(obs->obstime, &(obs->xe), &(obs->ye), &(obs->ze)); } else { earth3d(obs->obstime, obs->obscode, &(obs->xe), &(obs->ye), &(obs->ze)); } } if (fname!=NULL) fclose(fptr); return(0); }