def _normalized (self, value) : if isinstance (value, (list, tuple)) : result = Angle_D.normalized (* value) elif not isinstance (value, (Angle_D, Angle_R)) : result = Angle_D.normalized (value) else : result = value return result
def mean_obliquity_ecliptic (self) : """Mean obliquity of the ecliptic (in degrees).""" ### see J. Meeus, p. 147, Eq. (22.2) return \ ( Angle_D (23, 26, 21.448) - Angle_D (seconds = 46.815000) * self.t - Angle_D (seconds = 0.000590) * self.t2 + Angle_D (seconds = 0.001813) * self.t3 )
def __init__(self, ephs, loc, h0=Angle_D(-0.8333)): self.__super.__init__(ephs, loc, h0) vars = self.vars vars["h0"] = Angle_D(-6.0) self.civil_twilight_start = self._Event_(self.m1, **vars) self.civil_twilight_finis = self._Event_(self.m2, **vars) vars["h0"] = Angle_D(-12.0) self.nautic_twilight_start = self._Event_(self.m1, **vars) self.nautic_twilight_finis = self._Event_(self.m2, **vars) vars["h0"] = Angle_D(-18.0) self.astro_twilight_start = self._Event_(self.m1, **vars) self.astro_twilight_finis = self._Event_(self.m2, **vars)
def nutation_obliquity (self) : """Nutation in obliquity (delta-epsilon).""" ### see J. Meeus, pp. 143–4 omega = self.longitude_ascending_node_moon om_2 = omega * 2 ls_2 = self.geometric_mean_longitude_sun * 2 lm_2 = self.geometric_mean_longitude_moon * 2 result = \ ( Angle_D (seconds = 9.20) * omega.cos + Angle_D (seconds = 0.57) * ls_2.cos + Angle_D (seconds = 0.10) * lm_2.cos - Angle_D (seconds = 0.09) * om_2.cos ) return result
def nutation_longitude (self) : """Nutation in longitude (delta-phi).""" ### see J. Meeus, pp. 143–4 omega = self.longitude_ascending_node_moon om_2 = omega * 2 ls_2 = self.geometric_mean_longitude_sun * 2 lm_2 = self.geometric_mean_longitude_moon * 2 result = \ ( Angle_D (seconds = -17.20) * omega.sin - Angle_D (seconds = - 1.32) * ls_2.sin - Angle_D (seconds = 0.23) * lm_2.sin + Angle_D (seconds = 0.21) * om_2.sin ) return result
def local_hour_angle (self, h0, lat, delta) : """Local hour angle corresponding to the time of rise or set of a celestial body. """ ### J. Meeus, eq. (15.1), p. 102 cos_H0 = (h0.sin - lat.sin * delta.sin) / (lat.cos * delta.cos) if abs (cos_H0) <= 1 : return Angle_D.acos (cos_H0)
def local_hour_angle(self, h0, lat, delta): """Local hour angle corresponding to the time of rise or set of a celestial body. """ ### J. Meeus, eq. (15.1), p. 102 cos_H0 = (h0.sin - lat.sin * delta.sin) / (lat.cos * delta.cos) if abs(cos_H0) <= 1: return Angle_D.acos(cos_H0)
def sidereal_deg (self) : """Apparent sidereal time at `self.date` and `self.time` in degrees.""" ### see J. Meeus, p. 95 result = \ ( Angle_D.normalized (self.mean_sidereal_deg) + (self.nutation_longitude / 15) * self.obliquity_corrected.cos ) return result
def azimuth (decl, ha, lat) : """Azimuth of a celestial body with declination `decl` and hour angle `ha` for latitude `lat`. Azimuth is measured eastward from the North. """ ### J. Meeus, p. 93, Eq. (13.5) tan_A = \ ( ha.sin / (ha.cos * lat.sin - decl.tan * lat.cos) ) result = Angle_D.normalized (Angle_R.atan (tan_A).degrees) corr = 0 if ha < 0 and result > 180 : corr = Angle_D (-180) ### ha < 0 --> E of meridian elif ha > 0 and result < 180 : corr = Angle_D (+180) ### ha > 0 --> W of meridian result += corr return Angle_D.normalized (result.degrees)
def azimuth (decl, ha, loc) : """Azimuth of a celestial body with declination `decl` and hour angle `ha` for location `loc`. Azimuth is measured eastward from the North. """ ### J. Meeus, p. 93, Eq. (13.5) lat = loc.latitude tan_A = \ ( ha.sin / (ha.cos * lat.sin - decl.tan * lat.cos) ) result = Angle_D.normalized (Angle_R.atan (tan_A).degrees) corr = 0 if ha < 0 and result > 180 : corr = Angle_D (-180) ### ha < 0 --> E of meridian elif ha > 0 and result < 180 : corr = Angle_D (+180) ### ha > 0 --> W of meridian result += corr return Angle_D.normalized (result.degrees)
def __init__(self, ephs, loc, h0=Angle_D(-0.5667)): """Arguments: * ephs : triple of positions for UT=0:0 for (day-1, day, day+1) * loc : SKY.Location instance * h0 : "standard" altitude, i.e., the geometric altitude of the center of the body at the time of apparent rising or setting + 0.5667 degrees for stars and planets + 0.8333 degrees for the sun """ rts = self self.ephs = ephs self.loc = loc self.lat = lat = loc.latitude self.lon = lon = loc.longitude_meuss self.h0 = h0 = Angle(h0) self.day = day = ephs[1].day self.alpha = alpha = ephs[1].ra self.delta = delta = ephs[1].decl self.time = time = ephs[1].time self.sid = sid = Angle_D.normalized(time.sidereal_deg) ### H0: local hour angle corresponding to the time of rise or set of a ### celestial body. J. Meeus, eq. (15.1), p. 102 self.H0 = H0 = self.local_hour_angle(h0, lat, delta) self.vars = vars = locals() ### m0, m1, m2 ### transit, rise, set times, on `day`, expressed as fractions of a day ### J. Meeus, eq. (15.2), p. 102 self.m0 = m0 = ((alpha + lon - sid).degrees / 360.) % 1.0 if H0 is not None: self.m1 = m1 = (m0 - H0.degrees / 360.) % 1.0 self.m2 = m2 = (m0 + H0.degrees / 360.) % 1.0 self.rise = self._Rise_(m1, **vars) self.set = self._Set_(m2, **vars) self.transit = self._Transit_(m0, **vars)
def hour_angle (sid_UT, loc, ra) : """Hour angle for sidereal_time `sid_UT`, location `loc`, and right ascension `ra`. `sid_UT` and `ra` must be Angle_D/Angle_R instances. """ ### J. Meeus, p. 92 lon = loc.longitude_meuss ha = (sid_UT - lon - ra).degrees if abs (ha) >= 360.0 : ha = ha % 360.0 if ha > 180.0 : ha -= 360.0 elif ha < -180.0 : ha += 360.0 return Angle_D (ha)
def __init__ (self, ephs, lat, lon, h0 = Angle_D (-0.5667)) : """Arguments: * ephs : triple of positions for UT=0:0 for (day-1, day, day+1) * lat : latitude in degrees + positive in northern hemisphere + negative in southern hemisphere * lon : longitude in degrees + positive W of Greenwich + negative E of Greenwich * h0 : "standard" altitude, i.e., the geometric altitude of the center of the body at the time of apparent rising or setting + 0.5667 degrees for stars and planets + 0.8333 degrees for the sun """ rts = self self.ephs = ephs self.lat = lat = Angle_D (getattr (lat, "degrees", lat)) self.lon = lon = Angle_D (getattr (lon, "degrees", lon)) self.h0 = h0 = Angle_D (getattr (h0, "degrees", h0)) self.day = day = ephs [1].day self.alpha = alpha = ephs [1].ra self.delta = delta = ephs [1].decl self.time = time = ephs [1].time self.sid = sid = Angle_D.normalized (time.sidereal_deg) ### H0: local hour angle corresponding to the time of rise or set of a ### celestial body. J. Meeus, eq. (15.1), p. 102 self.H0 = H0 = self.local_hour_angle (h0, lat, delta) self.vars = vars = locals () ### m0, m1, m2 ### transit, rise, set times, on `day`, expressed as fractions of a day ### J. Meeus, eq. (15.2), p. 102 self.m0 = m0 = ((alpha + lon - sid).degrees / 360.) % 1.0 if H0 is not None : self.m1 = m1 = (m0 - H0.degrees / 360.) % 1.0 self.m2 = m2 = (m0 + H0.degrees / 360.) % 1.0 self.rise = self._Rise_ (m1, ** vars) self.set = self._Set_ (m2, ** vars) self.transit = self._Transit_ (m0, ** vars)
def air_mass (altitude) : """Air mass coefficient due to atmospheric extinction for `altitude`. >>> for alt in (90, 30, 20, 15, 10, 5, 2, 0) : ... print ("z = %2d° --> AM = %4.1f" % (90-alt, air_mass (alt))) z = 0° --> AM = 1.0 z = 60° --> AM = 2.0 z = 70° --> AM = 2.9 z = 75° --> AM = 3.8 z = 80° --> AM = 5.6 z = 85° --> AM = 10.3 z = 88° --> AM = 19.4 z = 90° --> AM = 37.9 https://en.wikipedia.org/wiki/Air_mass_(solar_energy), formula A.2 """ z = Angle_D (90) - altitude result = 1.0 / (z.cos + 0.50572 * ((96.07995 - z.degrees) ** -1.6364)) return result
lon -= 360.0 result = "%s %s, %s %s" % \ ( abs (lon), "W" if lon.degrees < 0.0 else "E" , abs (lat), "S" if lat.degrees < 0.0 else "N" ) if self.height : result = "%s, %2.0fm above sea level" % (result, self.height) if self.name : result = "%s [%s]" % (self.ui_name, result) return result # end def __str__ # end class Location Location \ ( Angle_D (48, 14) , Angle_D (16, 22) , "Vienna" , 180 , tz_name = "Europe/Vienna" ) Location \ ( Angle_D (37, 51, 7) , - Angle_D ( 8, 47, 31) , "Porto Covo" , 25 , tz_name = "Europe/Lisbon" ) class _Location_Arg_ (TFL.CAO.Str) :
def decl (self) : """Apparent declination of the sun (in degrees).""" ### Eq. (25.7), for apparent position o = self.time.obliquity_corrected l = self.apparent_longitude return Angle_D.asin (o.sin * l.sin)
def decl(self): """Apparent declination of the sun (in degrees).""" ### Eq. (25.7), for apparent position o = self.time.obliquity_corrected l = self.apparent_longitude return Angle_D.asin(o.sin * l.sin)
def _scaled_phi(self, rhs): result = self._phi if rhs < 0: result += Angle_D(180.0) return result
def On_Day(cls, date, location, h0=Angle_D(-0.8333)): s = Sun(date) return cls((s - 1, s, s + 1), location, h0)
def __neg__(self): return self.__class__(self._r, self._phi + Angle_D(180.0))