Skip to content
Snippets Groups Projects
Commit 8b25b7e9 authored by Bruce Flynn's avatar Bruce Flynn
Browse files

Fix some issues with solar position

Bump version.
parent b0f8042b
No related branches found
No related tags found
No related merge requests found
......@@ -27,14 +27,14 @@ Simple usage is as follows::
solarDec: 4.81517855635
eqTime: -3.71773858624
solarConstant: 1369.49188965>
The 'SolarPosition' object is a list like structure that allows you to
access the data in a list like manner::
>>> for val in s:
print val
...:
...:
45
-90
0.999456181732
......@@ -45,18 +45,18 @@ access the data in a list like manner::
4.81517855635
-3.71773858624
1369.49188965
>>> s[1]
45
>>> s[sp.SP_COS_ZEN]
0.73358139287238222
Additionally, there are property attributes for each value::
>>> s.solarDec
4.8151785563547014
>>> s.earthSunDistance
0.99945618173240092
......@@ -71,8 +71,7 @@ __docformat__ = 'restructuredtext en'
__version__ = '$Revision: 1.6 $'
# $Source: /cvsroot/TOOLS/dev/metobs/python/data/metobs/data/solar_position.py,v $
from metobs import mytime
from metobs.data import NaN, approx_eq
from metobs.data import NaN, util
import math
_days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]
......@@ -97,9 +96,9 @@ def calcDayOfWeek(juld):
return _days[int(A)]
def calcJD(year, month, day):
"""Get the interval of time in days and fractions of a day, since January 1,
"""Get the interval of time in days and fractions of a day, since January 1,
4713 BC Greenwich noon, Julian proleptic calendar.
>>> calcJD(1970,1,1)
2440587.5
"""
......@@ -109,7 +108,7 @@ def calcJD(year, month, day):
A = math.floor(year/100)
B = 2 - A + math.floor(A/4)
return (math.floor(365.25 * (year + 4716))
+ math.floor(30.6001 * (month + 1))
+ math.floor(30.6001 * (month + 1))
+ day + B - 1524.5)
def calcDateFromJD(jd):
......@@ -125,16 +124,16 @@ def calcDateFromJD(jd):
else:
alpha = math.floor((z - 1867216.25)/36524.25)
A = z + 1 + alpha - math.floor(alpha / 4)
B = A + 1524
C = math.floor((B - 122.1) / 365.25)
D = math.floor(365.25 * C)
E = math.floor((B - D) / 30.6001)
day = int(B - D - math.floor(30.6001 * E) + f)
month = int((E < 14) and E - 1 or E - 13)
year = int((month > 2) and C - 4716 or C - 4715)
return "%d-%s-%d" % (day, _months[month-1], year)
def calcDayFromJD(jd):
......@@ -193,9 +192,9 @@ def calcSunEqOfCenter(t):
sinm = math.sin(mrad)
sin2m = math.sin(mrad * 2)
sin3m = math.sin(mrad * 3)
return (sinm * (1.914602 - t * (0.004817 + 0.000014 * t))
+ sin2m * (0.019993 - 0.000101 * t)
return (sinm * (1.914602 - t * (0.004817 + 0.000014 * t))
+ sin2m * (0.019993 - 0.000101 * t)
+ sin3m * 0.000289)
def calcSunTrueLong(t):
......@@ -286,7 +285,7 @@ def calcEquationOfTime(t):
Etime = (y * sin2l0 - 2.0 * e * sinm + 4.0 * e * y * sinm * cos2l0
- 0.5 * y * y * sin4l0 - 1.25 * e * e * sin2m)
return math.degrees(Etime) * 4.0
return math.degrees(Etime) * 4.0
SP_DATE = 0
SP_LAT = 1
......@@ -305,7 +304,7 @@ class SolarPosition(object):
VAL_CNT = 12
def __init__(self, lat, lon, earthRadVec, azimuth, solarZen, coszen,
def __init__(self, lat, lon, earthRadVec, azimuth, solarZen, coszen,
elevation, solarDec, eqtime, date):
self._lat = lat
self._lon = lon
......@@ -317,14 +316,14 @@ class SolarPosition(object):
self._solarDec = solarDec
self._eqTime = eqtime
self._date = date
self._cur_idx = 0
@property
def latitude(self):
def latitude(self):
return self._lat
@property
def longitude(self):
def longitude(self):
return self._lon
@property
def earthSunDistance(self):
......@@ -349,7 +348,7 @@ class SolarPosition(object):
return self._eqTime
@property
def timenow(self):
return mytime.datetime_to_epoch(self._date) / 3600
return util.to_unix_timestamp(self._date) / 3600
@property
def date(self):
return self._date
......@@ -388,7 +387,7 @@ class SolarPosition(object):
val = self[self._cur_idx]
self._cur_idx += 1
return val
def __str__(self):
return """<SolarPosition
date: %s
......@@ -411,10 +410,10 @@ def solar_position(date, latitude, longitude):
it assumed to be in localtime.
- `latitude`: Station latitude
- `longitude`: Station longitude
Test values were results of running the SolarPosition Java code in cvs at
https://cvs.ssec.wisc.edu/cgi-bin/cvsweb.cgi/java/tower/SolarPosition.java
>>> from datetime import datetime
>>> date = datetime(1970,1,1,12,0,0)
>>> s = solar_position(date, 45, -90)
......@@ -424,19 +423,19 @@ def solar_position(date, latitude, longitude):
>>> assert approx_eq(s.elevation, 22.038213553352705, _ACCEPTABLE_DELTA)
>>> assert approx_eq(s.cosZen, 0.3752248974802099, _ACCEPTABLE_DELTA)
"""
if not date.tzinfo:
date = mytime.set_tz(date, tz=mytime.LocalTimezone)
year, month, day, hh, mm, ss = date.timetuple()[:6]
tzoffset = date.tzinfo.utcoffset(date)
if tzoffset.days < 0:
GMToffset = -(24 - tzoffset.seconds/3600)
else:
GMToffset = tzoffset.seconds/3600
GMToffset = 0
if date.tzinfo:
tzoffset = date.tzinfo.utcoffset(date)
if tzoffset.days < 0:
GMToffset = -(24 - tzoffset.seconds/3600)
else:
GMToffset = tzoffset.seconds/3600
timenow = hh + mm/60 + ss/3600 - GMToffset
JD = calcJD(year, month, day)
T = calcTimeJulianCent(JD + timenow/24.0)
T = calcTimeJulianCent(JD + timenow/24.0)
solarDec = calcSunDeclination(T)
eqTime = calcEquationOfTime(T)
earthRadVec = calcSunRadVector(T)
......@@ -453,9 +452,9 @@ def solar_position(date, latitude, longitude):
haRad = math.radians(hourAngle)
csz = (math.sin(math.radians(latitude)) *
math.sin(math.radians(solarDec)) +
math.cos(math.radians(latitude)) *
csz = (math.sin(math.radians(latitude)) *
math.sin(math.radians(solarDec)) +
math.cos(math.radians(latitude)) *
math.cos(math.radians(solarDec)) * math.cos(haRad))
if csz > 1.0:
......@@ -468,8 +467,8 @@ def solar_position(date, latitude, longitude):
math.sin(math.radians(zenith)) )
if abs(azDenom) > 0.001:
azRad = ((( math.sin(math.radians(latitude)) *
math.cos(math.radians(zenith)) ) -
azRad = ((( math.sin(math.radians(latitude)) *
math.cos(math.radians(zenith)) ) -
math.sin(math.radians(solarDec))) / azDenom)
if abs(azRad) > 1.0:
......@@ -501,12 +500,12 @@ def solar_position(date, latitude, longitude):
else:
te = math.tan (math.radians(exoatmElevation))
if (exoatmElevation > 5.0):
refractionCorrection = (58.1 / te - 0.07 / (te*te*te)
refractionCorrection = (58.1 / te - 0.07 / (te*te*te)
+ 0.000086 / (te*te*te*te*te))
elif exoatmElevation > -0.575:
refractionCorrection = (1735.0 + exoatmElevation *
(-518.2 + exoatmElevation * (103.4 +
exoatmElevation * (-12.79 +
exoatmElevation * (-12.79 +
exoatmElevation * 0.711) ) ))
else:
refractionCorrection = -20.774 / te
......@@ -526,8 +525,8 @@ def solar_position(date, latitude, longitude):
azumuth = NaN
elevation = NaN
coszen = NaN
return SolarPosition(latitude, longitude, earthRadVec, azimuth, solarZen, coszen,
return SolarPosition(latitude, longitude, earthRadVec, azimuth, solarZen, coszen,
elevation, solarDec, eqTime, date)
if __name__ == '__main__':
......
......@@ -3,7 +3,7 @@ from setuptools import setup, find_packages
setup(
name='metobs.data',
version='0.5dev',
version='0.5',
packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
namespace_packages=['metobs'],
include_package_data=True,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment