def predict_pos(self, date, obscode=807): """ Computes ra, dec, and error ellipse at the date(s) and observatory specified. Date is an ephem.date object. Returns a corresponding dictionary with keywords 'ra' -- ra in ICRS coords, returned as an ephem.Angle object 'dec' -- dec in ICRS coords, ditto 'err' -- error ellipse (see below) 'elong' -- solar elongation in degrees 'opp' -- opposition angle in degrees where the error ellipse, indexed by 'err', is itself a dictionary with keywords: 'a' -- semimajor axis in arcsec 'b' -- semiminor axis in arcsec 'PA' -- position angle in degrees, north through east """ p_in = self.orbit_abg jd0 = orbfit.cvar.jd0 # zeropoint of time scale # Create space for various useful matrices sigxy = orbfit.dmatrix(1, 2, 1, 2) derivs = orbfit.dmatrix(1, 2, 1, 2) covecl = orbfit.dmatrix(1, 2, 1, 2) coveq = orbfit.dmatrix(1, 2, 1, 2) # Fill the OBSERVATION structure futobs = orbfit.OBSERVATION() futobs.obscode = obscode futobs.obstime = (ephem.julian_date(date) - jd0) * orbfit.DAY futobs.xe = -999 # force evaluation of earth3D dx = orbfit.dvector(1, 6) dy = orbfit.dvector(1, 6) # Sometimes hangs in next line... why? thetax, thetay = orbfit.kbo2d(p_in, futobs, dx, dy) # Predicted position, in abg basis: orbfit.predict_posn(p_in, self.cov_abg, futobs, sigxy) solar_elongation = orbfit.elongation( futobs) / orbfit.DTOR # solar elongation in degrees opposition_angle = orbfit.opposition_angle( futobs) / orbfit.DTOR # opposition angle in degrees lat_ec, lon_ec = orbfit.proj_to_ec( futobs.thetax, futobs.thetay, orbfit.cvar.lat0, orbfit.cvar.lon0, derivs) # project to ecliptic coords orbfit.covar_map(sigxy, derivs, covecl, 2, 2) # map the covariance ra_eq, dec_eq = orbfit.ec_to_eq( lat_ec, lon_ec, derivs) # transform to ICRS to compute ra, dec if ra_eq < 0: ra_eq += 2 * np.pi # convert angle to (0,2pi) range orbfit.covar_map(covecl, derivs, coveq, 2, 2) # map the covariance # Compute ICRS error ellipse c = orbfit.doubleArray(4) # stoopid workaround for double pointers... orbfit.flatten_cov(coveq, 2, c) covar_eq = np.array([c[i] for i in range(4)]).reshape(2, 2) xx = covar_eq[0][0] * np.cos(dec_eq)**2 xy = covar_eq[0][1] * np.cos(dec_eq) yy = covar_eq[1][1] pos_angle = 0.5 * np.arctan2(2. * xy, (xx - yy)) * 180. / np.pi pos_angle = 90 - pos_angle # convert to astronomy convention of measuring position angle North through East bovasqrd = (xx + yy - np.sqrt((xx - yy)**2 + (2 * xy)**2)) / (xx + yy + np.sqrt((xx - yy)**2 + (2 * xy)**2)) det = xx * yy - xy * xy a = (det / bovasqrd)**( 1 / 4 ) / orbfit.ARCSEC # semimajor, minor axes of error ellipse, in arcsec b = (det * bovasqrd)**(1 / 4) / orbfit.ARCSEC err_ellipse = dict(a=a, b=b, PA=pos_angle) # store as a dictionary pos = dict(ra=ephem.hours(ra_eq), dec=ephem.degrees(dec_eq), err=err_ellipse, elong=solar_elongation, opp=opposition_angle) return pos
def predict_pos(self, date, obscode=807): """ Computes ra, dec, and error ellipse at the date(s) and observatory specified. Date is an ephem.date object. Returns a corresponding dictionary with keywords 'ra' -- ra in ICRS coords, returned as an ephem.Angle object 'dec' -- dec in ICRS coords, ditto 'err' -- error ellipse (see below) 'elong' -- solar elongation in degrees 'opp' -- opposition angle in degrees where the error ellipse, indexed by 'err', is itself a dictionary with keywords: 'a' -- semimajor axis in arcsec 'b' -- semiminor axis in arcsec 'PA' -- position angle in degrees, north through east """ p_in = self.orbit_abg jd0 = orbfit.cvar.jd0 # zeropoint of time scale # Create space for various useful matrices sigxy = orbfit.dmatrix(1, 2, 1, 2) derivs = orbfit.dmatrix(1, 2, 1, 2) covecl = orbfit.dmatrix(1, 2, 1, 2) coveq = orbfit.dmatrix(1, 2, 1, 2) # Fill the OBSERVATION structure futobs = orbfit.OBSERVATION() futobs.obscode = obscode futobs.obstime = (ephem.julian_date(date) - jd0) * orbfit.DAY futobs.xe = -999 # force evaluation of earth3D dx = orbfit.dvector(1, 6) dy = orbfit.dvector(1, 6) thetax, thetay = orbfit.kbo2d(p_in, futobs, dx, dy) # Predicted position, in abg basis: orbfit.predict_posn(p_in, self.cov_abg, futobs, sigxy) solar_elongation = orbfit.elongation(futobs) / orbfit.DTOR # solar elongation in degrees opposition_angle = orbfit.opposition_angle(futobs) / orbfit.DTOR # opposition angle in degrees lat_ec, lon_ec = orbfit.proj_to_ec( futobs.thetax, futobs.thetay, orbfit.cvar.lat0, orbfit.cvar.lon0, derivs ) # project to ecliptic coords orbfit.covar_map(sigxy, derivs, covecl, 2, 2) # map the covariance ra_eq, dec_eq = orbfit.ec_to_eq(lat_ec, lon_ec, derivs) # transform to ICRS to compute ra, dec if ra_eq < 0: ra_eq += 2 * np.pi # convert angle to (0,2pi) range orbfit.covar_map(covecl, derivs, coveq, 2, 2) # map the covariance # Compute ICRS error ellipse c = orbfit.doubleArray(4) # stoopid workaround for double pointers... orbfit.flatten_cov(coveq, 2, c) covar_eq = np.array([c[i] for i in range(4)]).reshape(2, 2) xx = covar_eq[0][0] * np.cos(dec_eq) ** 2 xy = covar_eq[0][1] * np.cos(dec_eq) yy = covar_eq[1][1] pos_angle = 0.5 * np.arctan2(2.0 * xy, (xx - yy)) * 180.0 / np.pi pos_angle = 90 - pos_angle # convert to astronomy convention of measuring position angle North through East bovasqrd = (xx + yy - np.sqrt((xx - yy) ** 2 + (2 * xy) ** 2)) / ( xx + yy + np.sqrt((xx - yy) ** 2 + (2 * xy) ** 2) ) det = xx * yy - xy * xy a = (det / bovasqrd) ** (1 / 4) / orbfit.ARCSEC # semimajor, minor axes of error ellipse, in arcsec b = (det * bovasqrd) ** (1 / 4) / orbfit.ARCSEC err_ellipse = dict(a=a, b=b, PA=pos_angle) # store as a dictionary pos = dict( ra=ephem.hours(ra_eq), dec=ephem.degrees(dec_eq), err=err_ellipse, elong=solar_elongation, opp=opposition_angle, ) return pos
def predict_from_abg(abginfo, date, obscode=807): p_in = abginfo['pbasis'] cov_abg = abginfo['cov_abg'] orbfit.cvar.jd0 = abginfo['jd0'] orbfit.cvar.xBary = abginfo['xBary'] orbfit.cvar.yBary = abginfo['yBary'] orbfit.cvar.zBary = abginfo['zBary'] orbfit.cvar.lon0 = abginfo['lon0'] * np.pi / 180 orbfit.cvar.lat0 = abginfo['lat0'] * np.pi / 180 sigxy = orbfit.dmatrix(1, 2, 1, 2) derivs = orbfit.dmatrix(1, 2, 1, 2) covecl = orbfit.dmatrix(1, 2, 1, 2) coveq = orbfit.dmatrix(1, 2, 1, 2) # Fill the OBSERVATION structure futobs = orbfit.OBSERVATION() futobs.obscode = obscode futobs.obstime = (ephem.julian_date(date) - orbfit.cvar.jd0) * orbfit.DAY futobs.xe = -999 # force evaluation of earth3D dx = orbfit.dvector(1, 6) dy = orbfit.dvector(1, 6) thetax, thetay = orbfit.kbo2d(p_in, futobs, dx, dy) # Predicted position, in abg basis: orbfit.predict_posn(p_in, cov_abg, futobs, sigxy) solar_elongation = orbfit.elongation( futobs) / orbfit.DTOR # solar elongation in degrees opposition_angle = orbfit.opposition_angle( futobs) / orbfit.DTOR # opposition angle in degrees lat_ec, lon_ec = orbfit.proj_to_ec(futobs.thetax, futobs.thetay, orbfit.cvar.lat0, orbfit.cvar.lon0, derivs) # project to ecliptic coords orbfit.covar_map(sigxy, derivs, covecl, 2, 2) # map the covariance ra_eq, dec_eq = orbfit.ec_to_eq( lat_ec, lon_ec, derivs) # transform to ICRS to compute ra, dec eq = ephem.Equatorial(ephem.Ecliptic(lat_ec, lon_ec)) ra_eq2 = eq.ra * 180 / np.pi dec_eq2 = eq.dec * 180 / np.pi if ra_eq < 0: ra_eq += 2 * np.pi # convert angle to (0,2pi) range # print ra_eq*180/np.pi, dec_eq*180/np.pi, ra_eq2, dec_eq2, ra_eq*180/np.pi-ra_eq2, dec_eq*180/np.pi-dec_eq2 orbfit.covar_map(covecl, derivs, coveq, 2, 2) # map the covariance # print ephem.hours(ra_eq), ephem.degrees(dec_eq) # Compute ICRS error ellipse c2d = orbfit.doubleArray(4) # stoopid workaround for double pointers... orbfit.flatten_cov(coveq, 2, c2d) covar_eq = np.array([c2d[i] for i in range(4)]).reshape(2, 2) xx = covar_eq[0][0] * np.cos(dec_eq)**2 xy = covar_eq[0][1] * np.cos(dec_eq) yy = covar_eq[1][1] pos_angle = 0.5 * np.arctan2(2. * xy, (xx - yy)) * 180. / np.pi pos_angle = 90 - pos_angle # convert to astronomy convention of measuring position angle North through East bovasqrd = (xx + yy - np.sqrt((xx - yy)**2 + (2 * xy)**2)) / (xx + yy + np.sqrt((xx - yy)**2 + (2 * xy)**2)) det = xx * yy - xy * xy a = (det / bovasqrd)**( 1 / 4) / orbfit.ARCSEC # semimajor, minor axes of error ellipse, in arcsec b = (det * bovasqrd)**(1 / 4) / orbfit.ARCSEC err_ellipse = dict(a=a, b=b, PA=pos_angle) # store as a dictionary pos = dict(ra=ephem.hours(ra_eq), dec=ephem.degrees(dec_eq), err=err_ellipse, elong=solar_elongation, opp=opposition_angle) return pos
def predict_from_abg(abginfo, date, obscode=807): p_in = abginfo["pbasis"] cov_abg = abginfo["cov_abg"] orbfit.cvar.jd0 = abginfo["jd0"] orbfit.cvar.xBary = abginfo["xBary"] orbfit.cvar.yBary = abginfo["yBary"] orbfit.cvar.zBary = abginfo["zBary"] orbfit.cvar.lon0 = abginfo["lon0"] * np.pi / 180 orbfit.cvar.lat0 = abginfo["lat0"] * np.pi / 180 sigxy = orbfit.dmatrix(1, 2, 1, 2) derivs = orbfit.dmatrix(1, 2, 1, 2) covecl = orbfit.dmatrix(1, 2, 1, 2) coveq = orbfit.dmatrix(1, 2, 1, 2) # Fill the OBSERVATION structure futobs = orbfit.OBSERVATION() futobs.obscode = obscode futobs.obstime = (ephem.julian_date(date) - orbfit.cvar.jd0) * orbfit.DAY futobs.xe = -999 # force evaluation of earth3D dx = orbfit.dvector(1, 6) dy = orbfit.dvector(1, 6) thetax, thetay = orbfit.kbo2d(p_in, futobs, dx, dy) # Predicted position, in abg basis: orbfit.predict_posn(p_in, cov_abg, futobs, sigxy) solar_elongation = orbfit.elongation(futobs) / orbfit.DTOR # solar elongation in degrees opposition_angle = orbfit.opposition_angle(futobs) / orbfit.DTOR # opposition angle in degrees lat_ec, lon_ec = orbfit.proj_to_ec( futobs.thetax, futobs.thetay, orbfit.cvar.lat0, orbfit.cvar.lon0, derivs ) # project to ecliptic coords orbfit.covar_map(sigxy, derivs, covecl, 2, 2) # map the covariance ra_eq, dec_eq = orbfit.ec_to_eq(lat_ec, lon_ec, derivs) # transform to ICRS to compute ra, dec eq = ephem.Equatorial(ephem.Ecliptic(lat_ec, lon_ec)) ra_eq2 = eq.ra * 180 / np.pi dec_eq2 = eq.dec * 180 / np.pi if ra_eq < 0: ra_eq += 2 * np.pi # convert angle to (0,2pi) range # print ra_eq*180/np.pi, dec_eq*180/np.pi, ra_eq2, dec_eq2, ra_eq*180/np.pi-ra_eq2, dec_eq*180/np.pi-dec_eq2 orbfit.covar_map(covecl, derivs, coveq, 2, 2) # map the covariance # print ephem.hours(ra_eq), ephem.degrees(dec_eq) # Compute ICRS error ellipse c2d = orbfit.doubleArray(4) # stoopid workaround for double pointers... orbfit.flatten_cov(coveq, 2, c2d) covar_eq = np.array([c2d[i] for i in range(4)]).reshape(2, 2) xx = covar_eq[0][0] * np.cos(dec_eq) ** 2 xy = covar_eq[0][1] * np.cos(dec_eq) yy = covar_eq[1][1] pos_angle = 0.5 * np.arctan2(2.0 * xy, (xx - yy)) * 180.0 / np.pi pos_angle = 90 - pos_angle # convert to astronomy convention of measuring position angle North through East bovasqrd = (xx + yy - np.sqrt((xx - yy) ** 2 + (2 * xy) ** 2)) / (xx + yy + np.sqrt((xx - yy) ** 2 + (2 * xy) ** 2)) det = xx * yy - xy * xy a = (det / bovasqrd) ** (1 / 4) / orbfit.ARCSEC # semimajor, minor axes of error ellipse, in arcsec b = (det * bovasqrd) ** (1 / 4) / orbfit.ARCSEC err_ellipse = dict(a=a, b=b, PA=pos_angle) # store as a dictionary pos = dict( ra=ephem.hours(ra_eq), dec=ephem.degrees(dec_eq), err=err_ellipse, elong=solar_elongation, opp=opposition_angle ) return pos