def test_regression_5085(): """ PR #5085 was put in place to fix the following issue. Issue: https://github.com/astropy/astropy/issues/5069 At root was the transformation of Ecliptic coordinates with non-scalar times. """ times = Time(["2015-08-28 03:30", "2015-09-05 10:30", "2015-09-15 18:35"]) latitudes = Latitude([3.9807075, -5.00733806, 1.69539491] * u.deg) longitudes = Longitude([311.79678613, 72.86626741, 199.58698226] * u.deg) distances = u.Quantity([0.00243266, 0.0025424, 0.00271296] * u.au) coo = GeocentricTrueEcliptic(lat=latitudes, lon=longitudes, distance=distances, equinox=times) # expected result ras = Longitude([310.50095400, 314.67109920, 319.56507428] * u.deg) decs = Latitude([-18.25190443, -17.1556676, -15.71616522] * u.deg) distances = u.Quantity([1.78309901, 1.710874, 1.61326649] * u.au) expected_result = GCRS(ra=ras, dec=decs, distance=distances, obstime="J2000").cartesian.xyz actual_result = coo.transform_to(GCRS(obstime="J2000")).cartesian.xyz assert_quantity_allclose(expected_result, actual_result)
def termtime(daytime,daytime2,code,unit='hour'): if unit=='hour': times=daytime+np.linspace(0.,1.,25)*(daytime2-daytime) elif unit=='minute': times=daytime+np.linspace(0.,1.,61)*(daytime2-daytime) else: times=daytime+np.linspace(0.,1.,61)*(daytime2-daytime) gmttimes=times-eighthours if type=='jieqi': diflongitudes=get_body('sun', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg else: sunlongitudes=get_body('sun', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg moonlongitudes=get_body('moon', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg diflongitudes=(moonlongitudes-sunlongitudes)%360 difcode=diflongitudes // sec difcode=[int(difcode[i]) for i in range(len(difcode))] for i in range(len(difcode)-1): if difcode[i+1]!=code: if unit=='hour': return termtime(times[i],times[i+1],code,"minute") else: if unit=='minute': return termtime(times[i],times[i+1],code,"second") else: return ((code+1) % (360//sec),(times[i]+0.5*(times[i+1]-times[i])).value) return (-1,"")
def CCTerm(start,end,type): eighthours=TimeDelta(8*3600,format='sec') def termtime(daytime,daytime2,code,unit='hour'): if unit=='hour': times=daytime+np.linspace(0.,1.,25)*(daytime2-daytime) elif unit=='minute': times=daytime+np.linspace(0.,1.,61)*(daytime2-daytime) else: times=daytime+np.linspace(0.,1.,61)*(daytime2-daytime) gmttimes=times-eighthours if type=='jieqi': diflongitudes=get_body('sun', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg else: sunlongitudes=get_body('sun', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg moonlongitudes=get_body('moon', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg diflongitudes=(moonlongitudes-sunlongitudes)%360 difcode=diflongitudes // sec difcode=[int(difcode[i]) for i in range(len(difcode))] for i in range(len(difcode)-1): if difcode[i+1]!=code: if unit=='hour': return termtime(times[i],times[i+1],code,"minute") else: if unit=='minute': return termtime(times[i],times[i+1],code,"second") else: return ((code+1) % (360//sec),(times[i]+0.5*(times[i+1]-times[i])).value) return (-1,"") start=Time(Time(start,out_subfmt='date').iso) end=Time(Time(end,out_subfmt='date').iso) daycount=int(round((Time(end)-Time(start)).value)) # print(start,end,daycount) # print(daycount) times=Time(start)+np.linspace(0.,1.,daycount+1)*(end-start+TimeDelta(3,format='sec')) # 考量潤秒,故加上3秒 times=Time(Time(times,out_subfmt='date').iso) gmttimes=times-TimeDelta(8*3600,format='sec') if type=='jieqi': diflongitudes= get_body('sun', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg sec=15 else: sunlongitudes=get_body('sun', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg moonlongitudes=get_body('moon', gmttimes, ephemeris='jpl').\ transform_to(GeocentricTrueEcliptic(equinox=gmttimes)).lon.deg diflongitudes=(moonlongitudes-sunlongitudes)%360 sec=90 res=[] difcode=diflongitudes // sec difcode=[int(difcode[i]) for i in range(len(difcode))] for i in range(len(difcode)-1): if difcode[i]!=difcode[i+1]: res.append(termtime(times[i],times[i+1],difcode[i],'hour')) return res
def relative_brightness(self, position, time): """ Calculate the Zodiacal Light surface brightness relative to that at the ecliptic poles for a given sky position and observing time. Args: position: sky position(s) in the form of either an astropy.coordinates.SkyCoord object or a string that can be converted into one. time: time of observation in the form of either an astropy.time.Time or a string that can be converted into one. Returns: rel_SB: relative sky brightness of the Zodiacal light """ # Convert position(s) to SkyCoord if not already one if not isinstance(position, SkyCoord): position = SkyCoord(position) if len(position.shape) == 2: shape = position.shape else: shape = False # Convert time to a Time if not already one if not isinstance(time, Time): time = Time(time) # Convert to ecliptic coordinates at current epoch position = position.transform_to(GeocentricTrueEcliptic(equinox=time)) # Get position of the Sun sun = get_sun(time).transform_to(GeocentricTrueEcliptic(equinox=time)) # Ecliptic latitude, remapped to range 0 to 180 degrees, in radians beta = (Angle(90 * u.degree) - position.lat).radian # Ecliptic longitude minus Sun's ecliptic longitude, remapped to # range 0 to 360 degrees, in radians llsun = (position.lon - sun.lon).wrap_at(360 * u.degree).radian rl = self._spatial(beta, llsun, grid=False) if shape: rl = rl.reshape((shape[1], shape[0])) rl = rl.T return rl
def get_zodiacal_light_scale(coord, time): """Get the scale factor for zodiacal light compared to "high" conditions. Estimate the ratio between the zodiacal light at a specific sky position and time, and its "high" value, by interpolating Table 6.2 of the STIS Instrument Manual. Parameters ---------- coord : astropy.coordinates.SkyCoord The coordinates of the object under observation. If the coordinates do not specify a distance, then the object is assumed to be a fixed star at infinite distance for the purpose of calculating its helioecliptic position. time : astropy.time.Time The time of the observation. Returns ------- float The zodiacal light scale factor. References ---------- https://hst-docs.stsci.edu/stisihb/chapter-6-exposure-time-calculations/6-5-detector-and-sky-backgrounds """ obj = SkyCoord(coord).transform_to(GeocentricTrueEcliptic(equinox=time)) sun = get_sun(time).transform_to(GeocentricTrueEcliptic(equinox=time)) # Wrap angles and look up in table lat = np.abs(obj.lat.deg) lon = np.abs((obj.lon - sun.lon).wrap_at(180 * u.deg).deg) result = _zodi_angular_dependence(np.stack((lon, lat), axis=-1)) # When interp2d encounters infinities, it returns nan. Fix that up here. result = np.where(np.isnan(result), -np.inf, result) # Fix up shape if obj.isscalar: result = result.item() result -= _zodi_angular_dependence([180, 0]).item() return u.mag(1).to_physical(result)
def test_regression_5085(): """ PR #5085 was put in place to fix the following issue. Issue: https://github.com/astropy/astropy/issues/5069 At root was the transformation of Ecliptic coordinates with non-scalar times. """ times = Time(["2015-08-28 03:30", "2015-09-05 10:30", "2015-09-15 18:35"]) latitudes = Latitude([3.9807075, -5.00733806, 1.69539491]*u.deg) longitudes = Longitude([311.79678613, 72.86626741, 199.58698226]*u.deg) distances = u.Quantity([0.00243266, 0.0025424, 0.00271296]*u.au) coo = GeocentricTrueEcliptic(lat=latitudes, lon=longitudes, distance=distances, equinox=times) # expected result ras = Longitude([310.50095400, 314.67109920, 319.56507428]*u.deg) decs = Latitude([-18.25190443, -17.1556676, -15.71616522]*u.deg) distances = u.Quantity([1.78309901, 1.710874, 1.61326649]*u.au) expected_result = GCRS(ra=ras, dec=decs, distance=distances, obstime="J2000").cartesian.xyz actual_result = coo.transform_to(GCRS(obstime="J2000")).cartesian.xyz assert_quantity_allclose(expected_result, actual_result)
def apparent_latitude(t='now'): """ Returns the Sun's apparent latitude, referred to the true equinox of date. Corrections for nutation and aberration (for Earth motion) are included. Parameters ---------- t : {parse_time_types} Time to use in a parse-time-compatible format """ time = parse_time(t) sun = SkyCoord(0*u.deg, 0*u.deg, 0*u.AU, frame='hcrs', obstime=time) coord = sun.transform_to(GeocentricTrueEcliptic(equinox=time)) # Astropy's GeocentricTrueEcliptic includes both aberration and nutation lat = coord.lat return Latitude(lat)
def apparent_longitude(t='now'): """ Returns the Sun's apparent longitude, referred to the true equinox of date. Corrections for nutation and aberration (for Earth motion) are included. Parameters ---------- t : {parse_time_types} Time to use in a parse-time-compatible format Notes ----- The nutation model is IAU 2000A nutation with adjustments to match IAU 2006 precession. """ time = parse_time(t) sun = SkyCoord(0*u.deg, 0*u.deg, 0*u.AU, frame='hcrs', obstime=time) coord = sun.transform_to(GeocentricTrueEcliptic(equinox=time)) # Astropy's GeocentricTrueEcliptic includes both aberration and nutation lon = coord.lon return Longitude(lon)
def accumoon(time, obs) : # ,geolat,lst) : # More accurate (but more elaborate and slower) lunar # ephemeris, from Jean Meeus' *Astronomical Formulae For Calculators*, # pub. Willman-Bell. Includes all the terms given there. */ # a run of comparisons every 3 days through 2018 shows that this # agrees with the more accurate astropy positions with an RMS of # 0.007 degrees. time_tt = time.tt # important to use correct time argument for this!! T = (time_tt.jd - 2415020.) / 36525. # this based around 1900 ... */ Tsq = T * T; Tcb = Tsq * T; Lpr = 270.434164 + 481267.8831 * T - 0.001133 * Tsq + 0.0000019 * Tcb M = 358.475833 + 35999.0498*T - 0.000150*Tsq - 0.0000033*Tcb Mpr = 296.104608 + 477198.8491*T + 0.009192*Tsq + 0.0000144*Tcb D = 350.737486 + 445267.1142*T - 0.001436 * Tsq + 0.0000019*Tcb F = 11.250889 + 483202.0251*T -0.003211 * Tsq - 0.0000003*Tcb Om = 259.183275 - 1934.1420*T + 0.002078*Tsq + 0.0000022*Tcb Lpr = Lpr % 360. Mpr = Mpr % 360. M = M % 360. D = D % 360. F = F % 360. Om = Om % 360. sinx = np.sin(np.deg2rad(51.2 + 20.2 * T)) Lpr = Lpr + 0.000233 * sinx M = M - 0.001778 * sinx Mpr = Mpr + 0.000817 * sinx D = D + 0.002011 * sinx sinx = 0.003964 * np.sin(np.deg2rad(346.560+132.870*T -0.0091731*Tsq)) Lpr = Lpr + sinx; Mpr = Mpr + sinx; D = D + sinx; F = F + sinx; sinx = np.sin(np.deg2rad(Om)) Lpr = Lpr + 0.001964 * sinx Mpr = Mpr + 0.002541 * sinx D = D + 0.001964 * sinx F = F - 0.024691 * sinx F = F - 0.004328 * np.sin(np.deg2rad(Om + 275.05 -2.30*T)) e = 1 - 0.002495 * T - 0.00000752 * Tsq; M = np.deg2rad(M) # these will all be arguments ... */ Mpr = np.deg2rad(Mpr) D = np.deg2rad(D) F = np.deg2rad(F) lambd = Lpr + 6.288750 * np.sin(Mpr) \ + 1.274018 * np.sin(2*D - Mpr) \ + 0.658309 * np.sin(2*D) \ + 0.213616 * np.sin(2*Mpr) \ - e * 0.185596 * np.sin(M) \ - 0.114336 * np.sin(2*F) \ + 0.058793 * np.sin(2*D - 2*Mpr) \ + e * 0.057212 * np.sin(2*D - M - Mpr) \ + 0.053320 * np.sin(2*D + Mpr) \ + e * 0.045874 * np.sin(2*D - M) \ + e * 0.041024 * np.sin(Mpr - M) \ - 0.034718 * np.sin(D) \ - e * 0.030465 * np.sin(M+Mpr) \ + 0.015326 * np.sin(2*D - 2*F) \ - 0.012528 * np.sin(2*F + Mpr) \ - 0.010980 * np.sin(2*F - Mpr) \ + 0.010674 * np.sin(4*D - Mpr) \ + 0.010034 * np.sin(3*Mpr) \ + 0.008548 * np.sin(4*D - 2*Mpr) \ - e * 0.007910 * np.sin(M - Mpr + 2*D) \ - e * 0.006783 * np.sin(2*D + M) \ + 0.005162 * np.sin(Mpr - D) # /* And furthermore.....*/ lambd = lambd + e * 0.005000 * np.sin(M + D) \ + e * 0.004049 * np.sin(Mpr - M + 2*D) \ + 0.003996 * np.sin(2*Mpr + 2*D) \ + 0.003862 * np.sin(4*D) \ + 0.003665 * np.sin(2*D - 3*Mpr) \ + e * 0.002695 * np.sin(2*Mpr - M) \ + 0.002602 * np.sin(Mpr - 2*F - 2*D) \ + e * 0.002396 * np.sin(2*D - M - 2*Mpr) \ - 0.002349 * np.sin(Mpr + D) \ + e * e * 0.002249 * np.sin(2*D - 2*M) \ - e * 0.002125 * np.sin(2*Mpr + M) \ - e * e * 0.002079 * np.sin(2*M) \ + e * e * 0.002059 * np.sin(2*D - Mpr - 2*M) \ - 0.001773 * np.sin(Mpr + 2*D - 2*F) \ - 0.001595 * np.sin(2*F + 2*D) \ + e * 0.001220 * np.sin(4*D - M - Mpr) \ - 0.001110 * np.sin(2*Mpr + 2*F) \ + 0.000892 * np.sin(Mpr - 3*D) \ - e * 0.000811 * np.sin(M + Mpr + 2*D) \ + e * 0.000761 * np.sin(4*D - M - 2*Mpr) \ + e * e * 0.000717 * np.sin(Mpr - 2*M) \ + e * e * 0.000704 * np.sin(Mpr - 2 * M - 2*D) \ + e * 0.000693 * np.sin(M - 2*Mpr + 2*D) \ + e * 0.000598 * np.sin(2*D - M - 2*F) \ + 0.000550 * np.sin(Mpr + 4*D) \ + 0.000538 * np.sin(4*Mpr) \ + e * 0.000521 * np.sin(4*D - M) \ + 0.000486 * np.sin(2*Mpr - D) B = 5.128189 * np.sin(F) \ + 0.280606 * np.sin(Mpr + F) \ + 0.277693 * np.sin(Mpr - F) \ + 0.173238 * np.sin(2*D - F) \ + 0.055413 * np.sin(2*D + F - Mpr) \ + 0.046272 * np.sin(2*D - F - Mpr) \ + 0.032573 * np.sin(2*D + F) \ + 0.017198 * np.sin(2*Mpr + F) \ + 0.009267 * np.sin(2*D + Mpr - F) \ + 0.008823 * np.sin(2*Mpr - F) \ + e * 0.008247 * np.sin(2*D - M - F) \ + 0.004323 * np.sin(2*D - F - 2*Mpr) \ + 0.004200 * np.sin(2*D + F + Mpr) \ + e * 0.003372 * np.sin(F - M - 2*D) \ + 0.002472 * np.sin(2*D + F - M - Mpr) \ + e * 0.002222 * np.sin(2*D + F - M) \ + e * 0.002072 * np.sin(2*D - F - M - Mpr) \ + e * 0.001877 * np.sin(F - M + Mpr) \ + 0.001828 * np.sin(4*D - F - Mpr) \ - e * 0.001803 * np.sin(F + M) \ - 0.001750 * np.sin(3*F) \ + e * 0.001570 * np.sin(Mpr - M - F) \ - 0.001487 * np.sin(F + D) \ - e * 0.001481 * np.sin(F + M + Mpr) \ + e * 0.001417 * np.sin(F - M - Mpr) \ + e * 0.001350 * np.sin(F - M) \ + 0.001330 * np.sin(F - D) \ + 0.001106 * np.sin(F + 3*Mpr) \ + 0.001020 * np.sin(4*D - F) \ + 0.000833 * np.sin(F + 4*D - Mpr) # /* not only that, but */ B = B + 0.000781 * np.sin(Mpr - 3*F) \ + 0.000670 * np.sin(F + 4*D - 2*Mpr) \ + 0.000606 * np.sin(2*D - 3*F) \ + 0.000597 * np.sin(2*D + 2*Mpr - F) \ + e * 0.000492 * np.sin(2*D + Mpr - M - F) \ + 0.000450 * np.sin(2*Mpr - F - 2*D) \ + 0.000439 * np.sin(3*Mpr - F) \ + 0.000423 * np.sin(F + 2*D + 2*Mpr) \ + 0.000422 * np.sin(2*D - F - 3*Mpr) \ - e * 0.000367 * np.sin(M + F + 2*D - Mpr) \ - e * 0.000353 * np.sin(M + F + 2*D) \ + 0.000331 * np.sin(F + 4*D) \ + e * 0.000317 * np.sin(2*D + F - M + Mpr) \ + e * e * 0.000306 * np.sin(2*D - 2*M - F) \ - 0.000283 * np.sin(Mpr + 3*F) om1 = 0.0004664 * np.cos(np.deg2rad(Om)) om2 = 0.0000754 * np.cos(np.deg2rad(Om + 275.05 - 2.30*T)) beta = B * (1. - om1 - om2); pie = 0.950724 + 0.051818 * np.cos(Mpr) \ + 0.009531 * np.cos(2*D - Mpr) \ + 0.007843 * np.cos(2*D) \ + 0.002824 * np.cos(2*Mpr) \ + 0.000857 * np.cos(2*D + Mpr) \ + e * 0.000533 * np.cos(2*D - M) \ + e * 0.000401 * np.cos(2*D - M - Mpr) \ + e * 0.000320 * np.cos(Mpr - M) \ - 0.000271 * np.cos(D) \ - e * 0.000264 * np.cos(M + Mpr) \ - 0.000198 * np.cos(2*F - Mpr) \ + 0.000173 * np.cos(3*Mpr) \ + 0.000167 * np.cos(4*D - Mpr) \ - e * 0.000111 * np.cos(M) \ + 0.000103 * np.cos(4*D - 2*Mpr) \ - 0.000084 * np.cos(2*Mpr - 2*D) \ - e * 0.000083 * np.cos(2*D + M) \ + 0.000079 * np.cos(2*D + 2*Mpr) \ + 0.000072 * np.cos(4*D) \ + e * 0.000064 * np.cos(2*D - M + Mpr) \ - e * 0.000063 * np.cos(2*D + M - Mpr) \ + e * 0.000041 * np.cos(M + D) \ + e * 0.000035 * np.cos(2*Mpr - M) \ - 0.000033 * np.cos(3*Mpr - 2*D) \ - 0.000030 * np.cos(Mpr + D) \ - 0.000029 * np.cos(2*F - 2*D) \ - e * 0.000029 * np.cos(2*Mpr + M) \ + e * e * 0.000026 * np.cos(2*D - 2*M) \ - 0.000023 * np.cos(2*F - 2*D + Mpr) \ + e * 0.000019 * np.cos(4*D - M - Mpr); beta = Angle(np.deg2rad(beta), unit = u.rad) lambd = Angle(np.deg2rad(lambd), unit = u.rad) dist = Distance(1./np.sin(np.deg2rad(pie)) * thorconsts.EQUAT_RAD) # place these in a skycoord in ecliptic coords of date. Handle distance # separately since it does not transform properly for some reason. eq = 'J%7.2f' % (2000. + (time.jd - thorconsts.J2000) / 365.25) fr = GeocentricTrueEcliptic(equinox = eq) inecl = SkyCoord(lon = Angle(lambd, unit=u.rad), lat = Angle(beta,unit=u.rad), frame=fr) # Transform into geocentric equatorial. geocen = inecl.transform_to(currentgeocentframe(time)) # Do the topo correction yourself. First form xyz coords in equatorial syst of date x = dist * np.cos(geocen.ra) * np.cos(geocen.dec) y = dist * np.sin(geocen.ra) * np.cos(geocen.dec) z = dist * np.sin(geocen.dec) # Now compute geocentric location of the observatory in a frame aligned with the # equatorial system of date, which one can do simply by replacing the west longitude # with the sidereal time (xobs, yobs, zobs) = geocent(lpsidereal(time,obs),obs.lat,2000. * u.m) # don't have obs.height yet # recenter moon's cartesian coordinates on position of obs x = x - xobs y = y - yobs z = z - zobs # form the toposcentric ra and dec and bundle them into a skycoord of epoch of date. topodist = np.sqrt(x**2 + y**2 + z**2) raout = np.arctan2(y,x) decout = np.arcsin(z / topodist) topocen = SkyCoord(raout, decout, unit = u.rad, frame = currentgeocentframe(time)) return topocen,topodist
def test_astroby_skyfield_horizons(): """ ### Astropy 與 Skyfield 取得太陽座標對照表 * 基本上,Astropy 的 get_obj 會得到從地心看太陽的 GCRS 赤道座標,對應於 Skyfield 的 earth.at(t).observe(sun).apparent()。 * Astropy 用 gcrscoord.transform_to(GeocentricTrueEcliptic(equinox = t)) 將 GCRS 赤道座標轉成真時黃道座標(true ecliptic), 對應於 Skyfield 的 gcrscoord.frame_latlon(ecliptic_frame)。 """ timestr = "2021-4-20 9:37" t_astropy = Time(timestr, scale='utc') solar_system_ephemeris.set('de430.bsp') sun_astropy_apparent = get_body('sun', t_astropy) t_skyfield = ts.utc(2021, 4, 20, 9, 37) sun_skyfield_astrometric = earth.at(t_skyfield).observe(sun).radec() sun_skyfield_apparent = earth.at(t_skyfield).observe(sun).apparent() # print(sun_skyfield_astrometric) print("\n比較 GCRS astrometric") print("sun_skyfield_astrometric", sun_skyfield_astrometric[0]._degrees, sun_skyfield_astrometric[1]._degrees, sun_skyfield_astrometric[2].km) # 比較 GCRS print("\n比較 GCRS apparent") print(sun_astropy_apparent) print('sun_astropy_apparent in (deg,deg,km) :', sun_astropy_apparent.ra.deg, sun_astropy_apparent.dec.deg, sun_astropy_apparent.distance.km) radec_skyfield = sun_skyfield_apparent.radec() print('sun_skyfield_apparent in (deg,deg,km) :', radec_skyfield[0]._degrees, radec_skyfield[1]._degrees, radec_skyfield[2].km) # 比較 GeocentricTrueEcliptic print('\n比較 GeocentricTrueEcliptic') sun_ecliptic_astropy = sun_astropy_apparent.transform_to( GeocentricTrueEcliptic(equinox=t_astropy)) sun_ecliptic_skyfield = sun_skyfield_apparent.frame_latlon(ecliptic_frame) print(sun_ecliptic_astropy) print(sun_ecliptic_skyfield[1]._degrees, sun_ecliptic_skyfield[0]._degrees, sun_ecliptic_skyfield[2].km) # 比較 TETE print('\n比較 TreeEclipticTrueEquator(TETE)') sun_tete_astropy = sun_astropy_apparent.transform_to( TETE(obstime=t_astropy)) sun_tete_skyfield = sun_skyfield_apparent.radec(epoch='date') print(sun_tete_astropy) print(sun_tete_skyfield[0]._degrees, sun_tete_skyfield[1]._degrees, sun_tete_skyfield[2].km) sun_by_earth = Horizons(id='10', id_type='majorbody', location='500', epochs={ 'start': "2021-4-20 9:37", 'stop': "2021-4-20 9:38", 'step': '1' }) sun_by_earth_ephem = sun_by_earth.ephemerides(quantities='1,2,4,20,31') print("jpl 資料") print(sun_by_earth_ephem['RA', 'DEC', 'RA_app', 'DEC_app', 'delta', 'ObsEclLon', 'ObsEclLat']) # 比較 AltAz print("\n比較 AltAz") location_astropy = EarthLocation(lon=121 * u.deg, lat=25 * u.deg, height=0 * u.m) moon_taipei_astropy = get_body('moon', t_astropy, location_astropy) # print(moon_taipei_astropy) _altaz_astropy = AltAz(obstime=t_astropy, location=location_astropy) moon_taipei_altaz_astropy = moon_taipei_astropy.transform_to( _altaz_astropy) print("moon_taipei_altaz_astropy: ", moon_taipei_altaz_astropy) taipei = earth + wgs84.latlon(25 * N, 121 * E, elevation_m=0) moon_taipei_skyfield = taipei.at(t_skyfield).observe(moon).apparent() alt, az, distance = moon_taipei_skyfield.altaz() print("moon_taipei_altaz_skyfield: ", az._degrees, alt._degrees, distance.km) moon_by_taipei = Horizons(id='301', id_type='majorbody', location={ 'lon': 121, 'lat': 25, 'elevation': 0 }, epochs={ 'start': "2021-4-20 9:37", 'stop': "2021-4-20 9:38", 'step': '1' }) moon_by_taipei_ephem = moon_by_taipei.ephemerides(quantities='1,2,4,20,31') print("moon_taipei_jpl (AZ EL)", moon_by_taipei_ephem['AZ', 'EL'])
def squiggle_plot(RA, RAerr, Dec, Decerr, pmRA, pmRAerr, pmDec, pmDecerr, parallax, parallaxerr, ref_date, \ obsdate, obs_RAs, obs_RAs_err, obs_Decs, obs_Decs_err, labels, \ ref_RA_offset = 0, ref_Dec_offset = 0, time_interval = [12,12], n_times = 5000, plt_xlim=[-200,200], plt_ylim=[-200,200], marker = ['^','o'], marker_size = [100,100], figsize = (8,8) ): ''' Test for common proper motion of a candidate companion by plotting the track the cc would have been observed on if it were a background object and not graviationally bound. Inputs: RA/Dec + errors [deg] (flt): RA/Dec of host star pmRA, pmDec + errors [mas/yr] (flt): - proper motion of host star. Use the negative of reported values because we treat the star as unmoving and will observe the apparent motion of the cc parallax + erro [mas] (flt): parallax ref_date [decimal year] (astropy Time object): reference date obsdate [decimal year] (array): array of dates of observations obs_RAs, obs_Decs + errors [mas] (array): array of observed RA/Dec offsets of companion to host star labels (str array): strings to label plot points ref_RA_offset, ref_Dec_offset [mas] (flt): 'zero point' reference RA/Dec offset for for companion to host time_interval [yrs] (array): Number of years [below,above] reference date to compute plot n_times (int): number of time points to compute values for plot plt_xlim, plt_ylim [mas] (array): axis limits [min,max] marker (array): markers to use for prediction points [0] and observed points [1] marker_size (array): size of markers for predicition points [0] and observed points [1] Returns: fig (matplotlib figure): plot of proper motion track pred_dRA_total, pred_dDec_total (flt): predicted RA/Dec offsets if cc were a background object ''' deg_to_mas = 3600000. mas_to_deg = 1. / 3600000. ############### Compute track: ################### # Define a time span around reference date: delta_time = np.linspace(-time_interval[0], time_interval[1], n_times) * u.yr times = ref_date + delta_time # Compute change in RA/Dec during time interval due to proper motion only: dRA, dDec = (pmRA) * (delta_time.value), (pmDec) * (delta_time.value) # Compute motion in the ecliptic coords due to parallactic motion: # Make a sky coord object in RA/Dec: obj = SkyCoord(ra=RA, dec=Dec, frame='icrs', unit='deg', obstime=time) # Convert to ecliptic lon/lat: gteframe = GeocentricTrueEcliptic() obj_ecl = obj.transform_to(gteframe) # Angle array during a year: theta = (delta_time.value % 1) * 2 * np.pi #Parallel to ecliptic: x = parallax * np.sin(theta) #Perp to ecliptic y = parallax * np.sin(obj_ecl.lat.rad) * np.cos(theta) # Compute ecliptic motion to equatorial motion: print 'Plotting... this part may take a minute.' new_RA, new_Dec = ecliptic_to_equatorial(obj_ecl.lon.deg+x*mas_to_deg, \ obj_ecl.lat.deg+y*mas_to_deg) # Compute change in RA/Dec for each time point in mas: delta_RA, delta_Dec = (new_RA - RA) * deg_to_mas, (new_Dec - Dec) * deg_to_mas #Put it together: dRA_total = delta_RA + dRA + ref_RA_offset dDec_total = delta_Dec + dDec + ref_Dec_offset ############# Compute prediction: ############# ### Where the object would have been observed were it a background object # Compute how far into each year the observation occured: pred_time_delta = (obsdate - np.floor(obsdate)) pred_theta = (pred_time_delta) * 2 * np.pi # Compute ecliptic motion: pred_x = parallax * np.sin(pred_theta) #Parallel to ecliptic pred_y = parallax * np.sin(obj_ecl.lat.rad) * np.cos( pred_theta) #Perp to ecliptic # Convert to RA/Dec: pred_new_RA, pred_new_Dec = ecliptic_to_equatorial(obj_ecl.lon.deg+pred_x*mas_to_deg, \ obj_ecl.lat.deg+pred_y*mas_to_deg) pred_delta_RA, pred_delta_Dec = (pred_new_RA - RA) * deg_to_mas, ( pred_new_Dec - Dec) * deg_to_mas # Compute location due to proper motion: pred_dRA, pred_dDec = (pmRA) * (obsdate - ref_date.value), (pmDec) * ( obsdate - ref_date.value) # Put it together: pred_dRA_total = -pred_delta_RA + pred_dRA + ref_RA_offset pred_dDec_total = -pred_delta_Dec + pred_dDec + ref_Dec_offset #################### Draw plot: ################# plt.rcParams['ytick.labelsize'] = tick_labelsize plt.rcParams['xtick.labelsize'] = tick_labelsize fig = plt.figure(figsize=figsize) plt.plot(dRA_total, dDec_total, lw=3, color='lightgrey', alpha=0.5, zorder=0) plt.plot(dRA_total, dDec_total, zorder=1) for i in range(len(pred_dRA)): plt.scatter(pred_dRA_total[i], pred_dDec_total[i], marker=marker[0], s=marker_size[0], zorder=2, edgecolors='black') plt.annotate(labels[i], xy=(pred_dRA_total[i], pred_dDec_total[i]), xytext=(-10, 10), textcoords='offset points', ha='right', va='bottom', fontsize=labelsize) for i in range(len(obs_RAs)): plt.scatter(obs_RAs[i], obs_Decs[i], edgecolors="black", marker=marker[1], s=marker_size[1], zorder=10) plt.errorbar(obs_RAs[i], obs_Decs[i], xerr=obs_RAs_err[i], yerr=obs_Decs_err[i], ls='none', elinewidth=1, capsize=0, ecolor='black', zorder=10) plt.ylim(plt_ylim[0], plt_ylim[1]) plt.xlim(plt_xlim[0], plt_xlim[1]) plt.xlabel(r'$\Delta$ RA [mas]', fontsize=fontsize) plt.ylabel(r'$\Delta$ Dec [mas]', fontsize=fontsize) plt.grid(ls=':') plt.tight_layout() return fig, pred_dRA_total, pred_dDec_total
def lonofobj(objname, t): # t = Time({'year':year, 'month': month, 'day': day, 'hour': hour, 'minute': minute, 'second': second}) with solar_system_ephemeris.set('jpl'): obj = get_body(objname, t) obj_ecliptic = obj.transform_to(GeocentricTrueEcliptic(equinox=t)) return obj_ecliptic.lon.value
try: coord = SkyCoord.from_name(coord) except NameResolveError: try: coord = SkyCoord(coord) except ValueError: st.sidebar.error('Did not understand coordinate format') st.stop() st.sidebar.success(f'Resolved to ' + coord.to_string('hmsdms', format='latex') + ' (' + coord.to_string('decimal') + ')') else: lat = {'Low': 90, 'Medium': 30, 'High': 0}[zodi] time = Time('2025-03-01') sun = get_sun(time).transform_to(GeocentricTrueEcliptic(equinox=time)) coord = SkyCoord(sun.lon + 180 * u.deg, lat * u.deg, frame=GeocentricTrueEcliptic(equinox=time)) st.markdown('## Source') spectrum = st.radio('Spectrum', ('Thermal', 'Flat in frequency (AB mag = const)', 'Flat in wavelength (ST mag = const)')) if spectrum == 'Thermal': temperature = st.number_input('Temperature (K)', 0, 20000, 10000, 1000) source = synphot.SourceSpectrum(synphot.BlackBodyNorm1D, temperature=temperature * u.K) elif spectrum == 'Flat in frequency (AB mag = const)':
from astropy import units as u from astropy.coordinates import SkyCoord, Galactic, GeocentricTrueEcliptic print('> Testing transformation from Galactic to Ecliptic coordinate frame') c_gal = SkyCoord(l=180 * u.degree, b=0 * u.degree, frame='galactic') c_epl_g = c_gal.geocentrictrueecliptic c_epl_b = c_gal.barycentrictrueecliptic print(c_gal) print(c_epl_g.lon.deg, c_epl_g.lat.deg) print(c_epl_b.lon.deg, c_epl_b.lat.deg) print('> Testing inverse transformation, from Eclptic to Galactic') lon, lat = c_epl_g.lon.deg, c_epl_g.lat.deg c_epl_g = GeocentricTrueEcliptic(lon=lon * u.degree, lat=lat * u.degree) c_gal = SkyCoord(c_epl_g).galactic # this is fine # c_gal = Galactic(c_epl_g) # this does not work! print(c_epl_g.lon.deg, c_epl_g.lat.deg) print(c_gal)