Skip to main content

Compute the sun's observed position based on Reda & Adreas's 2004 paper "Solar position algorithm for solar radiation applications"

Project description

sunposition

Description

sunposition is a python module for computing the sun's position based on the algorithms from "Solar position algorithm for solar radiation applications" by Ibrahim Reda and Afshin Anreas, Solar Energy (2004). The algorithm calculates "the solar zenith and azimuth angles in the period from the year −2000 to 6000, with uncertainties of ±0.0003°". See http://dx.doi.org/10.1016/j.solener.2003.12.003 for more information.

In this code, the latitude and longitude are positive for North and East, respectively. The azimuth angle is 0 at North and positive towards the east. The zenith angle is 0 at vertical and positive towards the horizon.

The code is hosted at https://github.com/s-bear/sun-position

The module is a single python file sunposition.py and may be used as a command-line utility or imported into a script. The module depends only on NumPy but can optionally use Numba and SciPy for performance improvements.

Installation

sunposition is hosted at https://pypi.org/project/sunposition/ and may be installed using pip:

$ pip install sunposition

Example usage on the command line

$ sunposition --help
usage: sunposition [-h] [--version] [--citation] [-t TIME] [-lat LATITUDE] [-lon LONGITUDE] [-e ELEVATION] [-T TEMPERATURE] [-p PRESSURE] [-a ATMOS_REFRACT] [-dt DT] [-r] [--csv] [--jit]

Compute sun position parameters given the time and location

options:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  --citation            Print citation information
  -t TIME, --time TIME  "now" or date and time in ISO8601 format or a (UTC) POSIX timestamp
  -lat LATITUDE, --latitude LATITUDE
                        observer latitude, in decimal degrees, positive for north
  -lon LONGITUDE, --longitude LONGITUDE
                        observer longitude, in decimal degrees, positive for east
  -e ELEVATION, --elevation ELEVATION
                        observer elevation, in meters
  -T TEMPERATURE, --temperature TEMPERATURE
                        temperature, in degrees celcius
  -p PRESSURE, --pressure PRESSURE
                        atmospheric pressure, in millibar
  -a ATMOS_REFRACT, --atmos_refract ATMOS_REFRACT
                        Atmospheric refraction at sunrise and sunset, in degrees. Omit to compute automatically, spa.c uses 0.5667
  -dt DT                difference between earth's rotation time (TT) and universal time (UT1)
  -r, --radians         Output in radians instead of degrees
  --csv                 Comma separated values (time,dt,lat,lon,elev,temp,pressure,az,zen,RA,dec,H)
  --jit                 Enable Numba acceleration (likely to cause slowdown for a single computation!)

$ sunposition
Computing sun position at T = 2025-02-03T05:13:53.608472Z + 0.0 s
Lat, Lon, Elev = 51.48 deg, 0.0 deg, 0 m
T, P = 14.6 C, 1013.0 mbar
Results:
Azimuth, zenith = 88.915691 deg, 112.077238 deg
RA, dec, H = 317.087980 deg, -16.448005 deg, -104.973487 deg

$ sunposition -t "1953-05-29 05:45:00" -lat 27.9881 -lon 86.9253 -e 8848
Computing sun position at T = 1953-05-29T05:45:00Z + 0.0 s
Lat, Lon, Elev = 27.9881 deg, 86.9253 deg, 8848.0 m
T, P = 14.6 C, 1013.0 mbar
Results:
Azimuth, zenith = 137.735174 deg, 8.480987 deg
RA, dec, H = 65.760501 deg, 21.576785 deg, 353.875172 deg

An example test file is provided at https://raw.githubusercontent.com/s-bear/sun-position/master/sunposition_test.txt

Example usage in a script

import numpy as np
import matplotlib.pyplot as plt
# When imported as a module, sunposition will use numba.jit if available
# This may negatively impact performance if few positions are being computed
# For a rough guideline, on the author's machine:
#    jit:    5.5 seconds + 35 microseconds per computation
#    no-jit  1.4 milliseconds per computation
#    break-even: ~4000 computations
# There are several methods to disable jit:
#    1. If numba.config.DISABLE_JIT or the environment variable NUMBA_DISABLE_JIT
#       are set *before* sunposition is imported, jit will be disabled by default.
#    2. After sunposition is imported, use
#          sunposition.disable_jit()
#       or
#          sunposition.enable_jit(False)
#    3. Pass `jit=False` as a keyword argument to the function
import sunposition

#evaluate on a 2 degree grid
lon  = np.linspace(-180,180,181)
lat = np.linspace(-90,90,91)
LON, LAT = np.meshgrid(lon,lat)
# to_timestamp(s) converts a string to a POSIX-style timestamp (seconds since epoch)
# s may be 'now', which returns the current time using time.time()
#   or an ISO-8601 formatted date & time, e.g. '2024-04-08T11:09:34-07:00' 
now = sunposition.to_timestamp('now')
az,zen = sunposition.sunpos(now,LAT,LON,0)[:2] #discard RA, dec, H
#convert zenith to elevation
elev = 90 - zen
#convert azimuth to vectors
u, v = np.cos((90-az)*np.pi/180), np.sin((90-az)*np.pi/180)
#plot
fig, ax = plt.subplots(figsize=(6,3),layout='constrained')
img = ax.imshow(elev,cmap=plt.cm.CMRmap,origin='lower',vmin=-90,vmax=90,extent=(-181,181,-91,91))
s = slice(5,-1,5) # equivalent to 5:-1:5
ax.quiver(lon[s],lat[s],u[s,s],v[s,s],pivot='mid',scale_units='xy')
ax.contour(lon,lat,elev,[0])
ax.set_aspect('equal')
ax.set_xticks(np.arange(-180,181,45))
ax.set_yticks(np.arange(-90,91,45))
ax.set_xlabel('Longitude (deg)')
ax.set_ylabel('Latitude (deg)')
cb = plt.colorbar(img,ax=ax,shrink=0.8,pad=0.03)
cb.set_label('Sun Elevation (deg)')
#display plot
plt.show() #unnecessary in interactive sessions

Citations

Ibrahim Reda and Afshin Andreas, "Solar position algorithm for solar radiation applications," Solar Energy, Volume 76, Issue 5, 2004, Pages 577-589, ISSN 0038-092X, [https://dx.doi.org/10.1016/j.solener.2003.12.003](doi: 10.1016/j.solener.2003.12.003). Keywords: Global solar irradiance; Solar zenith angle; Solar azimuth angle; VSOP87 theory; Universal time; ΔUT1

Ibrahim Reda and Afshin Andreas, “Corrigendum to ‘Solar position algorithm for solar radiation applications’ [Solar Energy 76 (2004) 577–589],” Solar Energy, vol. 81, no. 6, p. 838, Jun. 2007, [https://dx.doi.org/10.1016/j.solener.2007.01.003](doi: 10.1016/j.solener.2007.01.003).

Cassio Neri and Lorenz Schneider, “Euclidean affine functions and their application to calendar algorithms,” Software: Practice and Experience, vol. 53, no. 4, pp. 937–970, Apr. 2023, [https://dx.doi.org/10.1002/spe.3172](doi: 10.1002/spe.3172).

LICENSE

Copyright (c) 2025 Samuel Bear Powell, samuel.powell@uq.edu.au

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sunposition-1.2.0.tar.gz (22.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sunposition-1.2.0-py3-none-any.whl (23.2 kB view details)

Uploaded Python 3

File details

Details for the file sunposition-1.2.0.tar.gz.

File metadata

  • Download URL: sunposition-1.2.0.tar.gz
  • Upload date:
  • Size: 22.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.28.1

File hashes

Hashes for sunposition-1.2.0.tar.gz
Algorithm Hash digest
SHA256 6014d076834dba3cfc69c77f5c4fa74d6b595c119a3c269a4882fa10274d8ece
MD5 050e29c07b1424e12fcbfa75dbb72dd5
BLAKE2b-256 61d29b0390f3eb7facb6c9d79544ad5b89c3fba46820ef77df1428502cc05ec3

See more details on using hashes here.

File details

Details for the file sunposition-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: sunposition-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 23.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.28.1

File hashes

Hashes for sunposition-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 60ca568bfb510750ddfba0eb973847d325db1222c21f0fdcf136f74da30518ec
MD5 259f6e49853f3664e6e6dd9f4fcb1369
BLAKE2b-256 338792ed1ea2675a02526b4a49bb2f4189eba89b20cc67f281c598a579a8fbe4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page