soltrack

The Python version of the SolTrack code to compute the position of and track the Sun.

https://github.com/marcvdsluys/soltrack-python

Science Score: 54.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
    Links to: arxiv.org
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (12.2%) to scientific vocabulary
Last synced: 7 months ago · JSON representation ·

Repository

The Python version of the SolTrack code to compute the position of and track the Sun.

Basic Info
  • Host: GitHub
  • Owner: MarcvdSluys
  • License: eupl-1.2
  • Language: Python
  • Default Branch: master
  • Size: 164 KB
Statistics
  • Stars: 4
  • Watchers: 2
  • Forks: 6
  • Open Issues: 0
  • Releases: 0
Created over 5 years ago · Last pushed 8 months ago
Metadata Files
Readme Citation Codemeta

README.md

SolTrack for Python

PyPI PyPI - Downloads Documentation
Status PyPI - Licence

A free, fast and simple Python package to compute the position of the Sun, as well as its rise and set times. SolTrack was originally written in C/C++ by Marc van der Sluys of the department of astrophysics of the Radboud University Nijmegen, the Netherlands and the Sustainable energy research group of the HAN University of Applied Sciences in Arnhem, the Netherlands (now at the Netherlands Institute for Nuclear and High-Energy Physics (Nikhef) in Amsterdam and the Institute for Gravitational and Subatomic Physics (GRASP) at Utrecht University in the Netherlands), and Paul van Kan of the Sustainable energy research group of the HAN University of Applied Sciences in Arnhem, the Netherlands. The code has now been translated to pure Python and can be used under the conditions of the EUPL 1.2 licence.

SolTrack can perform up to 1.5 million position calculations per second on a single 3.4 GHz core of my laptop (the C version of SolTrack is about twice as fast) with an accuracy of 0.0030 ± 0.0016°.

Installation

This package can be installed using pip install soltrack. This should automatically install the dependency packages numpy, pandas, astroconst and astrotool if they haven't been installed already (if you're not using a Python version older than 3.7, you will need to install dataclasses as well). If you are installing by hand, ensure that these packages are installed as well.

Example use

Code example for a number or range of datetimes

```python """Compute the position of the Sun and its rise and set times for a vector of instances."""

Create a Pandas DatetimeIndex range every 20 days 1 hour and 10 minutes, in my timezone:

import pandas as pd dti = pd.date_range('2022-01-01 01:00', '2022-12-31 23:00', freq='20d1h10min', tz='Europe/Amsterdam')

Set the geographic location to Arnhem, the Netherlands (we'll use degrees in SolTrack):

geolon = 5.950270 # Positive -> east of Greenwich (degrees) geolat = 51.987380 # Positive -> northern hemisphere (degrees)

Create a SolTrack instance and specify preferences:

from soltrack import SolTrack st = SolTrack(geolon, geolat, usedegrees=True) # Use default values for all but usedegrees st.setdatetime(dti) # Pass my dates and times to SolTrack st.computeposition() # Compute the Sun's position st.computerise_set() # Compute the rise and set times of the Sun

Print some selected results as arrays and create chaos:

if st.lt is not None: # If local time was used print('Local time: ', st.lt) # Asterisk () unpacks the DTI

print('UTC: ', *st.utc) print('azimuth: ', *st.azimuth) print('altitude: ', *st.altitude) print('distance: ', *st.distance) print('riseTime: ', *st.risetime) print('transTime: ', *st.transittime) print('setTime: ', *st.set_time)

Store selected results in a Pandas DataFrame and print that in a more orderly fashion:

st.createdf(utc=True, jd=True, ecl=True, rtspos=True) with pd.optioncontext('display.maxcolumns',None, 'display.width',None): # Want all columns print(st.df) ```

Code example for a single instant

Note that in most cases, you should use the vector option instead, as it is faster starting from calculations for two instances. See the section Performance for more details. The code listing below is provided for completeness only.

```python """Example Python script to compute the position of the Sun and its rise and set times for a single instant and demonstrate some other features."""

from soltrack import SolTrack import datetime as dt import pytz as tz

Set the geographic location to Arnhem, the Netherlands:

geolon = 5.950270 # Positive -> east of Greenwich (degrees) geolat = 51.987380 # Positive -> northern hemisphere (degrees)

st = SolTrack(geolon, geolat, usedegrees=True) # Same as above, using default values for all but usedegrees.

Set SolTrack date and time using separate (UTC!) year, month, day, hour, minute and second variables:

st.setdateand_time(2023, 7, 16, 6, 2, 49.217348) # Date: 2023-07-16, time: 06:02:49.217348 UTC

Alternatively, use a (localised) datetime object:

cet = tz.timezone('Europe/Amsterdam') mydate = dt.datetime(2023, 7, 16, 8, 2, 49, 217348) # Same as above, in local time for TZ=+2 (08:02:49.217348 LT) mydate = cet.localize(mydate) st.setdatetime(mydate) # Set SolTrack date and time using a Python datetime object.

Compute the Sun's position:

st.compute_position()

Compute the rise and set times of the Sun:

st.computeriseset()

Write results to standard output:

print("Location: %0.3lf E, %0.3lf N" % (st.geolongitude, st.geolatitude))

print("Date/time: %4d-%02d-%02d %02d:%02d:%09.6lf" % (st.year, st.month, st.day, st.hour, st.minute, st.second))

print("Date/time: %s" % mydate) print("JD: %0.11lf" % (st.julianday)) print()

print("Ecliptic longitude, latitude: %10.6lf° %10.6lf°" % (st.longitude, 0.0)) # Note: latitude is always 0 in this model print("Distance: %10.6lf°" % (st.distance)) print("Right ascension, declination: %10.6lf° %10.6lf°" % (st.rightascensionuncorr, st.declinationuncorr)) print("Uncorrected altitude: %10.6lf°" % (st.altitudeuncorr)) print("Corrected azimuth, altitude: %10.6lf° %10.6lf°" % (st.azimuth, st.altitude)) print("Corrected hour angle, declination: %10.6lf° %10.6lf°" % (st.hourangle, st.declination)) print()

print("Rise time: %s, azimuth: %11.5lf" % (st.risetime, st.riseazimuth)) print("Transit time: %s, altitude: %11.5lf" % (st.transittime, st.transitaltitude)) print("Set time: %s, azimuth: %11.5lf" % (st.settime, st.setazimuth)) print()

Change the location whilst keeping the same SolTrack object:

st.setlocation(geolon, -geo_lat)

Compute the current position of the Sun for the new location:

st.now() st.compute_position()

print("Location: %0.3lf E, %0.3lf N" % (st.geolongitude, st.geolatitude)) print("Date (UT): %4d-%02d-%02d" % (st.year, st.month, st.day)) print("Time (UT): %02d:%02d:%09.6lf" % (st.hour, st.minute, st.second)) print("Corrected azimuth, altitude: %10.6lf° %10.6lf°" % (st.azimuth, st.altitude)) ```

Update from v0.1.x to v0.2.0

The update from SolTrack v0.1.4 to v0.2.0 is not backwards compatible. Most public members/variables and methods/functions, as well as dummy arguments have been renamed in order to comply better with the Python standards. I have tried to put as much nuisance into a single update as possible (as opposed to in multiple updates, rather than as opposed to as little nuisance as possible), so that this will hopefully not happen again in the future. For public methods, the obsolescent old name is kept as an alias, and warnings are issued when used, instructing how to adapt your code. In many cases a variable or function name likeThis will have been replaced to one like_this, i.e. upper case replaced with an underscore and lower case. See the documentation for more details.

Code example for SolTrack v0.1.x (old)

```python """Example Python script to compute the position of the Sun and its rise and set times for a single instant."""

import soltrack as st

Set preferences (all are False by default):

useDegrees = True # Input (geographic position) and output are in degrees useNorthEqualsZero = True # Azimuth: 0 = South, pi/2 (90deg) = West -> 0 = North, pi/2 (90deg) = East computeRefrEquatorial = True # Compure refraction-corrected equatorial coordinates (Hour angle, declination) computeDistance = True # Compute the distance to the Sun

Set up geographical location (in degrees, since useDegrees=True) in a SolTrack Location dataclass object:

loc = st.Location(5.950270, 51.987380) # longitude (>0: east of Greenwich), latitude (>0: northern hemisphere)

Set (UT!) date and time in a SolTrack Time dataclass object:

time = st.Time(2045, 7, 16, 6, 2, 49.217348) # Date: 2045-07-16, time: 06:02:49.217348

Compute positions - returns a st.Position object:

pos = st.computeSunPosition(loc, time, useDegrees, useNorthEqualsZero, computeRefrEquatorial, computeDistance)

Compute rise and set times - returns a st.RiseSet object:

riseSet = st.computeSunRiseSet(loc, time, 0.0, useDegrees, useNorthEqualsZero)

Write results to standard output:

print("Location: %0.3lf E, %0.3lf N" % (loc.longitude, loc.latitude)) print("Date: %4d %2d %2d" % (time.year, time.month, time.day)) print("Time: %2d %2d %9.6lf" % (time.hour, time.minute, time.second)) print("JD: %0.11lf" % (pos.julianDay)) print()

print("Ecliptic longitude, latitude: %10.6lf° %10.6lf°" % (pos.longitude, 0.0)) print("Right ascension, declination: %10.6lf° %10.6lf°" % (pos.rightAscension, pos.declination)) print("Uncorrected altitude: %10.6lf°" % (pos.altitude)) print("Corrected azimuth, altitude: %10.6lf° %10.6lf°" % (pos.azimuthRefract, pos.altitudeRefract)) print("Corrected hour angle, declination: %10.6lf° %10.6lf°" % (pos.hourAngleRefract, pos.declinationRefract)) print()

print("Rise time: %11.5lf, azimuth: %11.5lf" % (riseSet.riseTime, riseSet.riseAzimuth)) print("Transit time: %11.5lf, altitude: %11.5lf" % (riseSet.transitTime, riseSet.transitAltitude)) print("Set time: %11.5lf, azimuth: %11.5lf" % (riseSet.setTime, riseSet.setAzimuth)) print() ```

Performance

Performance of position calculations for an array/vector or range of instants

From v0.2.0 on, SolTrack uses Pandas to allow the use of arrays or vectors of datetimes (Series, DatetimeIndex, ndarrays of datetime64, ...). This causes some overhead, which is relatively more significant for small numbers. SolTrack performs fastest (per position calculation and on my laptop) for about 105-106 calculations:

| Ncalc (-) | Time (s) | Speed (/s) | Speed (millions/s) | |----------------------|----------|------------|--------------------| | 1e0 | 0.00081 | 1.23e+03 | 0.001 | | 1e1 | 0.00080 | 1.25e+04 | 0.013 | | 1e2 | 0.00105 | 9.52e+04 | 0.095 | | 1e3 | 0.00256 | 3.91e+05 | 0.39 | | 1e4 | 0.0132 | 7.58e+05 | 0.76 | | 1e5 | 0.0688 | 1.45e+06 | 1.45 | | 3e5 | 0.1960 | 1.53e+06 | 1.53 | | 1e6 | 0.6660 | 1.50e+06 | 1.50 | | 3e6 | 2.068 | 1.45e+06 | 1.45 | | 1e7 | 8.691 | 1.15e+06 | 1.15 |

These benchmarks were done on a single CPU core, capped at 3.4GHz. The cpu and core were always the same, and the minimum of 10 benchmarks is listed. Timezone-naive datetimes (representing UTC) were used; using timezone-aware datetimes slows down the code by a factor of ~4.6 compared to the numbers in the table.

Performance of calculations of rise, transit and set times

Benchmarks for rise, transit and set computations were performed in the same manner as above, but using return_datetimes=False in the st.compute_rise_set() call, which returns rise, transit and set times in decimal hours. If instead datetimes are desired, the code becomes a factor of about 3.1 times slower. The use of utc=True has little effect, and using timezone-aware datetimes instead of timezone-naive ones adds 6.1% to the computational times listed below.

| Ncalc (-) | Time (s) | Speed (/s) | |----------------------|----------|------------| | 1 | 0.0020 | 500.0 | | 10 | 0.0134 | 746.3 | | 100 | 0.1247 | 801.9 | | 1000 | 1.207 | 828.5 | | 1e4 | 12.00 | 833.3 |

Performance of position calculation for a single instant

Because of the overhead of Pandas and datetime-like objects, SolTrack has actually slowed down by a factor of ~10.4 between versions 0.1.4 and 0.2.0 when doing single calculations. I don't consider that a big issue, since a single position calculation still takes less than a millisecond, so that the effect is not noticable for humans. It does become noticable for large numbers, but then arrays can be used, which make the code ~1000x faster. In fact, the array version is faster starting from two iterations, so there is usually very little reason to use the single-datetime option.

Single calculations can be made about 19% faster by providing datetimes in UTC and specifying utc=True in the st.set_date_time() method. The use of timezone-naive versus timezone-aware datetimes has little influence on the performance for single calculations, and calculation times scale linearly when doing multiple calls (since the must then be done in a Python loop).

For single datetimes, 1000 calculations take about 0.68 seconds on the single CPU core of my laptop capped at 3.4 GHz, and about 0.55 seconds with utc=True.

SolTrack pages

Author and licence

  • Author: Marc van der Sluys
  • Contact: http://marc.vandersluys.nl
  • Licence: EUPL 1.2

See also

  • AstroConst: a Python package that provides astronomical constants.
  • AstroTool: a Python package for astronomical calculations in Python or on the command line.
  • elp-mpp02: accurate Moon positions using the lunar solution ELP/MPP02 in Python.
  • libTheSky: a Fortran library to compute the positions of celestial bodies (Sun, Moon, planets, stars, asteroids, comets) and events (e.g. lunar phases) with great accuracy.
  • SolarEnergy: A Python module to do simple modelling in the field of solar energy.

References

Copyright (c) 2019-2025 Marc van der Sluys

Citation (CITATION.cff)

cff-version: 1.1.0
message: "Please cite the following works when using this software: https://ui.adsabs.harvard.edu/abs/2022ascl.soft09019V"
authors:
- family-names: van der Sluys
  given-names: Marc
- family-names: van Kan
  given-names: Paul
- family-names: Reintjes
  given-names: Jurgen
title: "SolTrack: Compute the position of the Sun in topocentric coordinates"
version: 0.2.2
date-released: 2022-09-22
identifiers:
 - type: "ascl-id"
   value: "2209.019"
 - type: "bibcode"
   value: "2022ascl.soft09019V"
abstract: "SolTrack computes the position of the Sun, the rise and set times and azimuths, and transit times and altitudes. It includes corrections for aberration and parallax, and has a simple routine to correct for atmospheric refraction, taking into account local atmospheric conditions. SolTrack is derived from the Fortran library libTheSky (ascl:2209.018) and has versions in C(++), Arduino Scratch and Python. The package can be used to track the Sun on a low-specs machine, such as a microcontroller or PLC, and can be used for (highly) concentrated (photovoltaic) solar power or accurate solar-energy modeling."

GitHub Events

Total
  • Push event: 2
  • Create event: 3
Last Year
  • Push event: 2
  • Create event: 3

Committers

Last synced: about 2 years ago

All Time
  • Total Commits: 116
  • Total Committers: 1
  • Avg Commits per committer: 116.0
  • Development Distribution Score (DDS): 0.0
Past Year
  • Commits: 12
  • Committers: 1
  • Avg Commits per committer: 12.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
MvdS g****t@v****l 116
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 8 months ago

All Time
  • Total issues: 0
  • Total pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Total issue authors: 0
  • Total pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
Pull Request Authors
Top Labels
Issue Labels
Pull Request Labels

Packages

  • Total packages: 1
  • Total downloads:
    • pypi 162 last-month
  • Total dependent packages: 1
  • Total dependent repositories: 1
  • Total versions: 15
  • Total maintainers: 1
pypi.org: soltrack

A free, fast and accurate Python package to compute the position of the Sun

  • Versions: 15
  • Dependent Packages: 1
  • Dependent Repositories: 1
  • Downloads: 162 Last month
Rankings
Dependent packages count: 4.8%
Average: 13.4%
Downloads: 13.7%
Dependent repos count: 21.6%
Maintainers (1)
Last synced: 8 months ago