/* * find the chart number of Millennium Star Atlas and return pointer to static * string describing location. * 0 <= ra < 24; -90 <= dec <= 90 */ char * msa_atlas(double ra, double dec) { static char buf[512]; int zone, band; int i, p; ra = radhr(ra); dec = raddeg(dec); buf[0] = 0; if (ra < 0.0 || 24.0 <= ra || dec < -90.0 || 90.0 < dec) return (buf); zone = (int)(ra/8.0); band = -((int)(dec+((dec>=0)?3:-3))/6 - 15); for (p=0, i=0; i <= band; i++) p += msa_charts[i]; i = (int)((ra - 8.0*zone) / (8.0/msa_charts[band])); sprintf(buf, "V%d - P%3d", zone+1, p-i+zone*516); return (buf); }
void unrefract (double pr, double tr, double aa, double *ta) { #define LTLIM 14.5 #define GELIM 15.5 double aadeg = raddeg(aa); if (aadeg < LTLIM) unrefractLT15 (pr, tr, aa, ta); else if (aadeg >= GELIM) unrefractGE15 (pr, tr, aa, ta); else { /* smooth blend -- important for inverse */ double taLT, taGE, p; unrefractLT15 (pr, tr, aa, &taLT); unrefractGE15 (pr, tr, aa, &taGE); p = (aadeg - LTLIM)/(GELIM - LTLIM); *ta = taLT + (taGE - taLT)*p; } }
/* given a modified Julian date, mj, and a planet, p, find: * lpd0: heliocentric longitude, * psi0: heliocentric latitude, * rp0: distance from the sun to the planet, * rho0: distance from the Earth to the planet, * none corrected for light time, ie, they are the true values for the * given instant. * lam: geocentric ecliptic longitude, * bet: geocentric ecliptic latitude, * each corrected for light time, ie, they are the apparent values as * seen from the center of the Earth for the given instant. * dia: angular diameter in arcsec at 1 AU, * mag: visual magnitude * * all angles are in radians, all distances in AU. * * corrections for nutation and abberation must be made by the caller. The RA * and DEC calculated from the fully-corrected ecliptic coordinates are then * the apparent geocentric coordinates. Further corrections can be made, if * required, for atmospheric refraction and geocentric parallax. */ void plans (double mj, PLCode p, double *lpd0, double *psi0, double *rp0, double *rho0, double *lam, double *bet, double *dia, double *mag) { static double lastmj = -10000; static double lsn, bsn, rsn; /* geocentric coords of sun */ static double xsn, ysn, zsn; /* cartesian " */ double lp, bp, rp; /* heliocentric coords of planet */ double xp, yp, zp, rho; /* rect. coords and geocentric dist. */ double dt; /* light time */ double *vp; /* vis_elements[p] */ double ci, i; /* sun/earth angle: cos, degrees */ int pass; /* get sun cartesian; needed only once at mj */ if (mj != lastmj) { sunpos (mj, &lsn, &rsn, &bsn); sphcart (lsn, bsn, rsn, &xsn, &ysn, &zsn); lastmj = mj; } /* first find the true position of the planet at mj. * then repeat a second time for a slightly different time based * on the position found in the first pass to account for light-travel * time. */ dt = 0.0; for (pass = 0; pass < 2; pass++) { double ret[6]; /* get spherical coordinates of planet from precision routines, * retarded for light time in second pass; * alternative option: vsop allows calculating rates. */ planpos(mj - dt, p, 0.0, ret); lp = ret[0]; bp = ret[1]; rp = ret[2]; sphcart (lp, bp, rp, &xp, &yp, &zp); cartsph (xp + xsn, yp + ysn, zp + zsn, lam, bet, &rho); if (pass == 0) { /* save heliocentric coordinates at first pass since, being * true, they are NOT to be corrected for light-travel time. */ *lpd0 = lp; range (lpd0, 2.*PI); *psi0 = bp; *rp0 = rp; *rho0 = rho; } /* when we view a planet we see it in the position it occupied * dt days ago, where rho is the distance between it and earth, * in AU. use this as the new time for the next pass. */ dt = rho * 5.7755183e-3; } vp = vis_elements[p]; *dia = vp[0]; /* solve plane triangle, assume sun/earth dist == 1 */ ci = (rp*rp + rho*rho - 1)/(2*rp*rho); /* expl supp equation for mag */ if (ci < -1) ci = -1; if (ci > 1) ci = 1; i = raddeg(acos(ci))/100.; *mag = vp[1] + 5*log10(rho*rp) + i*(vp[2] + i*(vp[3] + i*vp[4])); /* rings contribution if SATURN */ if (p == SATURN) { double et, st, set; satrings (bp, lp, rp, lsn+PI, rsn, mj+MJD0, &et, &st); set = sin(fabs(et)); *mag += (-2.60 + 1.25*set)*set; } }
int main(int argc, char *argv[]) { Now *np; Now now; ObjF *op = NULL; char msg[256]; char *wfsroot, *filename, ra_hms[50], dec_dms[50]; double ra, dec, fov, mag, dra, ddec, dist, fo_ra, fo_dec; int nop = 0; int i; now.n_mjd = 0.0; now.n_lat = degrad(31.689); now.n_lng = degrad(-110.885); now.n_tz = 7.0; now.n_temp = 20.0; now.n_pressure = 700.0; now.n_elev = 2580.0/ERAD; now.n_dip = 0.0; now.n_epoch = EOD; sprintf(now.n_tznm, "UTC-7"); np = &now; time_fromsys(np); ra = hrrad(atof(argv[1])); dec = degrad(atof(argv[2])); fov = degrad(atof(argv[3])); mag = atof(argv[4]); /* precess(mjd, J2000, &ra, &dec); */ if (getenv("WFSROOT")) { wfsroot = getenv("WFSROOT"); filename = (char *) malloc(strlen(wfsroot) + 20); strcpy(filename, wfsroot); strcat(filename, "/wfscat/tycho.xe2"); } else { filename = "/mmt/shwfs/wfscat/tycho.xe2"; } nop = xe2fetch(filename, np, ra, dec, fov, mag, &op, msg); for (i=0; i<nop; i++) { dist = raddeg( acos( sin(op[i].fo_dec)*sin(dec) + cos(op[i].fo_dec)*cos(dec)*cos(ra-op[i].fo_ra) ) ); dist *= 60.0; fo_ra = radhr(op[i].fo_ra); fo_dec = raddeg(op[i].fo_dec); sprintf(ra_hms, "%02d:%02d:%05.2f", (int) fo_ra, (int) ((fo_ra - (int)fo_ra)*60.0), ( (fo_ra - (int)fo_ra)*60.0 - (int) ((fo_ra - (int)fo_ra)*60.0) )*60.0); if (fo_dec < 0.0 && (int)fo_dec >= 0) { sprintf(dec_dms, "-%02d:%02d:%06.3f", (int)fo_dec, abs( (int) ((fo_dec - (int)fo_dec)*60.0) ), fabs( ( (fo_dec - (int)fo_dec)*60.0 - (int) ((fo_dec - (int)fo_dec)*60.0) )*60.0) ); } else { sprintf(dec_dms, "%+03d:%02d:%06.3f", (int)fo_dec, abs( (int) ((fo_dec - (int)fo_dec)*60.0) ), fabs( ( (fo_dec - (int)fo_dec)*60.0 - (int) ((fo_dec - (int)fo_dec)*60.0) )*60.0) ); } printf("%15s %4.1f mag %2s %c %s %s %+07.3f %+07.2f %9.2f\n", op[i].co_name, op[i].co_mag/MAGSCALE, op[i].fo_spect, op[i].fo_class, ra_hms, dec_dms, 0.1*op[i].fo_pma/cos(op[i].fo_dec), 0.1*op[i].fo_pmd, dist); } return(0); }
/* estimate size in arc seconds @ 1AU from absolute magnitude, H, and assuming * an albedo of 0.1. With this assumption an object with diameter of 1500m * has an absolute mag of 18. */ static double h_albsize (double H) { return (3600*raddeg(.707*1500*pow(2.51,(18-H)/2)/MAU)); }
static int obj_fixed (Now *np, Obj *op) { double lsn, rsn; /* true geoc lng of sun, dist from sn to earth*/ double lam, bet; /* geocentric ecliptic long and lat */ double ha; /* local hour angle */ double el; /* elongation */ double alt, az; /* current alt, az */ double ra, dec; /* ra and dec at equinox of date */ double rpm, dpm; /* astrometric ra and dec with PM to now */ double lst; /* on the assumption that the user will stick with their chosen display * epoch for a while, we move the defining values to match and avoid * precession for every call until it is changed again. * N.B. only compare and store jd's to lowest precission (f_epoch). * N.B. maintaining J2k ref (which is arbitrary) helps avoid accum err */ if (0 /* disabled in PyEphem */ && epoch != EOD && epoch != op->f_epoch) { double pr = op->f_RA, pd = op->f_dec, fe = epoch; /* first bring back to 2k */ precess (op->f_epoch, J2000, &pr, &pd); pr += op->f_pmRA*(J2000-op->f_epoch); pd += op->f_pmdec*(J2000-op->f_epoch); /* then to epoch */ pr += op->f_pmRA*(fe-J2000); pd += op->f_pmdec*(fe-J2000); precess (J2000, fe, &pr, &pd); op->f_RA = pr; op->f_dec = pd; op->f_epoch = fe; } /* apply proper motion .. assume pm epoch reference equals equinox */ rpm = op->f_RA + op->f_pmRA*(mjd-op->f_epoch); dpm = op->f_dec + op->f_pmdec*(mjd-op->f_epoch); /* set ra/dec to astrometric @ equinox of date */ ra = rpm; dec = dpm; if (op->f_epoch != mjed) precess (op->f_epoch, mjed, &ra, &dec); /* compute astrometric @ requested equinox */ op->s_astrora = rpm; op->s_astrodec = dpm; if (op->f_epoch != epoch) precess (op->f_epoch, epoch, &op->s_astrora, &op->s_astrodec); /* convert equatoreal ra/dec to mean geocentric ecliptic lat/long */ eq_ecl (mjed, ra, dec, &bet, &lam); /* find solar ecliptical long.(mean equinox) and distance from earth */ sunpos (mjed, &lsn, &rsn, NULL); /* allow for relativistic light bending near the sun */ deflect (mjed, lam, bet, lsn, rsn, 1e10, &ra, &dec); /* TODO: correction for annual parallax would go here */ /* correct EOD equatoreal for nutation/aberation to form apparent * geocentric */ nut_eq(mjed, &ra, &dec); ab_eq(mjed, lsn, &ra, &dec); op->s_gaera = ra; op->s_gaedec = dec; /* set s_ra/dec -- apparent */ op->s_ra = ra; op->s_dec = dec; /* compute elongation from ecliptic long/lat and sun geocentric long */ elongation (lam, bet, lsn, &el); el = raddeg(el); op->s_elong = (float)el; /* these are really the same fields ... op->s_mag = op->f_mag; op->s_size = op->f_size; */ /* alt, az: correct for refraction; use eod ra/dec. */ now_lst (np, &lst); ha = hrrad(lst) - ra; hadec_aa (lat, ha, dec, &alt, &az); refract (pressure, temp, alt, &alt); op->s_alt = alt; op->s_az = az; return (0); }
/* compute location of GRS and Galilean moons. * if md == NULL, just to cml. * from "Astronomical Formulae for Calculators", 2nd ed, by Jean Meeus, * Willmann-Bell, Richmond, Va., U.S.A. (c) 1982, chapters 35 and 36. */ void meeus_jupiter( double d, double *cmlI, double *cmlII, /* central meridian longitude, rads */ MoonData md[J_NMOONS]) /* fill in md[1..NM-1].x/y/z for each moon. * N.B. md[0].ra/dec must already be set */ { #define dsin(x) sin(degrad(x)) #define dcos(x) cos(degrad(x)) double A, B, Del, J, K, M, N, R, V; double cor_u1, cor_u2, cor_u3, cor_u4; double solc, tmp, G, H, psi, r, r1, r2, r3, r4; double u1, u2, u3, u4; double lam, Ds; double z1, z2, z3, z4; double De, dsinDe; double theta, phi; double tvc, pvc; double salpha, calpha; int i; V = 134.63 + 0.00111587 * d; M = (358.47583 + 0.98560003*d); N = (225.32833 + 0.0830853*d) + 0.33 * dsin (V); J = 221.647 + 0.9025179*d - 0.33 * dsin(V); A = 1.916*dsin(M) + 0.02*dsin(2*M); B = 5.552*dsin(N) + 0.167*dsin(2*N); K = (J+A-B); R = 1.00014 - 0.01672 * dcos(M) - 0.00014 * dcos(2*M); r = 5.20867 - 0.25192 * dcos(N) - 0.00610 * dcos(2*N); Del = sqrt (R*R + r*r - 2*R*r*dcos(K)); psi = raddeg (asin (R/Del*dsin(K))); *cmlI = degrad(268.28 + 877.8169088*(d - Del/173) + psi - B); range (cmlI, 2*PI); *cmlII = degrad(290.28 + 870.1869088*(d - Del/173) + psi - B); range (cmlII, 2*PI); /* that's it if don't want moon info too */ if (!md) return; solc = (d - Del/173.); /* speed of light correction */ tmp = psi - B; u1 = 84.5506 + 203.4058630 * solc + tmp; u2 = 41.5015 + 101.2916323 * solc + tmp; u3 = 109.9770 + 50.2345169 * solc + tmp; u4 = 176.3586 + 21.4879802 * solc + tmp; G = 187.3 + 50.310674 * solc; H = 311.1 + 21.569229 * solc; cor_u1 = 0.472 * dsin (2*(u1-u2)); cor_u2 = 1.073 * dsin (2*(u2-u3)); cor_u3 = 0.174 * dsin (G); cor_u4 = 0.845 * dsin (H); r1 = 5.9061 - 0.0244 * dcos (2*(u1-u2)); r2 = 9.3972 - 0.0889 * dcos (2*(u2-u3)); r3 = 14.9894 - 0.0227 * dcos (G); r4 = 26.3649 - 0.1944 * dcos (H); md[1].x = -r1 * dsin (u1+cor_u1); md[2].x = -r2 * dsin (u2+cor_u2); md[3].x = -r3 * dsin (u3+cor_u3); md[4].x = -r4 * dsin (u4+cor_u4); lam = 238.05 + 0.083091*d + 0.33*dsin(V) + B; Ds = 3.07*dsin(lam + 44.5); De = Ds - 2.15*dsin(psi)*dcos(lam+24.) - 1.31*(r-Del)/Del*dsin(lam-99.4); dsinDe = dsin(De); z1 = r1 * dcos(u1+cor_u1); z2 = r2 * dcos(u2+cor_u2); z3 = r3 * dcos(u3+cor_u3); z4 = r4 * dcos(u4+cor_u4); md[1].y = z1*dsinDe; md[2].y = z2*dsinDe; md[3].y = z3*dsinDe; md[4].y = z4*dsinDe; /* compute sky transformation angle as triple vector product */ tvc = PI/2.0 - md[0].dec; pvc = md[0].ra; theta = PI/2.0 - POLE_DEC; phi = POLE_RA; salpha = -sin(tvc)*sin(theta)*(cos(pvc)*sin(phi) - sin(pvc)*cos(phi)); calpha = sqrt (1.0 - salpha*salpha); for (i = 0; i < J_NMOONS; i++) { double tx = md[i].x*calpha + md[i].y*salpha; double ty = -md[i].x*salpha + md[i].y*calpha; md[i].x = tx; md[i].y = ty; } md[1].z = z1; md[2].z = z2; md[3].z = z3; md[4].z = z4; }