### Install solposx via pip Source: https://solposx.readthedocs.io/en/stable/installation.html Standard installation command to install the package from PyPI. ```bash pip install solposx ``` -------------------------------- ### Install solposx with optional dependencies Source: https://solposx.readthedocs.io/en/stable/installation.html Command to install the package along with optional dependencies like skyfield and sg2. ```bash pip install solposx[optional] ``` -------------------------------- ### nasa_horizons(latitude, longitude, start, end, elevation=0.0, *, time_step='1h', refraction_correction=False, url='https://ssd.jpl.nasa.gov/api/horizons.api') Source: https://solposx.readthedocs.io/en/stable/generated/solposx.solarposition.nasa_horizons.html Retrieves solar positions from NASA's Horizons web service. The function requires a start time, end time, and frequency, and returns a DataFrame with solar position angles. ```APIDOC ## nasa_horizons(latitude, longitude, start, end, elevation=0.0, *, time_step='1h', refraction_correction=False, url='https://ssd.jpl.nasa.gov/api/horizons.api') ### Description Retrieve solar positions from NASA's Horizons web service. The function requires specifying a time period with start, end, and frequency, and returns a pandas DataFrame with solar position angles. ### Method Function call ### Endpoint Not applicable (SDK function) ### Parameters - **latitude** (float) - Required - Latitude in decimal degrees. Positive north of equator, negative to south. [degrees] - **longitude** (float) - Required - Longitude in decimal degrees. Positive east of prime meridian, negative to west. [degrees] - **start** (datetime-like) - Required - Start of the requested time period. - **end** (datetime-like) - Required - End of the requested time period. - **elevation** (float, optional) - Optional - Elevation of the point of interest [m]. The default is 0 m. - **time_step** (str, optional) - Optional - Time step size of the requested time series. '1m' for minutes, '1h' for hours, '1d' for days, '1mo' for months, and '1y' for years. The default is '1h'. - **refraction_correction** (bool, optional) - Optional - Whether to return apparent solar position angles corrected for atmospheric refraction. The default is False. - **url** (str, optional) - Optional - API endpoint. The default is 'https://ssd.jpl.nasa.gov/api/horizons.api'. ### Returns pandas.DataFrame with the following columns in degrees (note that all columns except azimuth are prefixed with 'apparent_' if refraction_correction=True): - right_ascension - declination - azimuth - elevation ### Notes The refraction correction algorithm is the same as solposx.refraction.spa(). See [3] for more information. ``` -------------------------------- ### Compute solar positions and RMSD comparison Source: https://solposx.readthedocs.io/en/stable/solarposition_introduction.html Creates hourly timestamps for the year 2025, computes solar positions using the Michalsky and Skyfield algorithms, and calculates the RMSD between them using solposx.tools.calc_error. ```python times = pd.date_range('2025-01-01 00:00:00', '2025-12-31 23:59:00', freq='h', tz='UTC') michalsky = solposx.solarposition.michalsky(times, site.latitude, site.longitude) skyfield = solposx.solarposition.skyfield(times, site.latitude, site.longitude) comparison = solposx.tools.calc_error(michalsky['elevation'], michalsky['azimuth'], skyfield['elevation'], skyfield['azimuth']) ``` -------------------------------- ### solposx.solarposition.walraven Source: https://solposx.readthedocs.io/en/stable/generated/solposx.solarposition.walraven.html Documentation for the walraven function in the solposx.solarposition module. ```APIDOC ## Function: solposx.solarposition.walraven ### Description Calculate solar position using the Walraven algorithm. Walraven's algorithm has a stated accuracy of 0.01 degrees. The implementation accounts for the 1979 Erratum and the correct azimuth quadrant selection. ### Signature `solposx.solarposition.walraven(times, latitude, longitude)` ### Parameters - **times** (pandas.DatetimeIndex) - Required - Timestamps - must be localized. Prior to 1970 and far in the future UTC and UT1 may deviate significantly. For such use cases, UT1 times should be provided. - **latitude** (float) - Required - Latitude in decimal degrees. Positive north of equator, negative to south. [degrees] - **longitude** (float) - Required - Longitude in decimal degrees. Positive east of prime meridian, negative to west. [degrees] ### Returns - **pandas.DataFrame** - DataFrame with the following columns (all values in degrees): - elevation: actual sun elevation (not accounting for refraction). - zenith: actual sun zenith (not accounting for refraction). - azimuth: sun azimuth, east of north. ### References - Walraven's algorithm [1] - 1979 Erratum [2] - Correct azimuth quadrant selection [3] ``` -------------------------------- ### Skyfield de440.bsp download progress Source: https://solposx.readthedocs.io/en/stable/solarposition_introduction.html Shows the progress output from downloading the de440.bsp ephemeris file, which is required by the Skyfield algorithm. ```text [ ] 0% de440.bsp ``` ```text [#### ] 13% de440.bsp ``` ```text [############ ] 36% de440.bsp ``` ```text [################## ] 55% de440.bsp ``` ```text [####################### ] 71% de440.bsp ``` ```text [############################# ] 88% de440.bsp ``` ```text [#################################] 100% de440.bsp ``` -------------------------------- ### solarposition.walraven(times, latitude, ...) Source: https://solposx.readthedocs.io/en/stable/solarposition.html Calculates the solar position using the Walraven algorithm. ```APIDOC ## solarposition.walraven(times, latitude, ...) ### Description Calculate solar position using the Walraven algorithm. ### Parameters - **times** - The time(s) for which to calculate the solar position. - **latitude** - The latitude of the location. ### Returns - Solar zenith, elevation, and azimuth angles. ``` -------------------------------- ### michalsky() Source: https://solposx.readthedocs.io/en/stable/generated/solposx.solarposition.michalsky.html Documentation for the michalsky() function, which calculates solar position using the Michalsky algorithm. ```APIDOC ## michalsky() ### Description Calculates solar position using the Michalsky algorithm with a stated accuracy of 0.01 degrees from 1950 to 2050. The function returns a DataFrame with solar elevation, zenith, and azimuth angles. ### Method Function call ### Endpoint `solposx.solarposition.michalsky(times, latitude, longitude, spencer_correction=True, julian_date='original')` ### Parameters - **times** (pandas.DatetimeIndex) - Required - Timestamps, must be localized. Prior to 1970 and far in the future UTC and UT1 may deviate significantly; for such use cases, UT1 times should be provided. - **latitude** (float) - Required - Latitude in decimal degrees. Positive north of equator, negative to south. [degrees] - **longitude** (float) - Required - Longitude in decimal degrees. Positive east of prime meridian, negative to west. [degrees] - **spencer_correction** (bool, default True) - Optional - Applies the correction suggested by Spencer so the algorithm works for all latitudes. - **julian_date** (string, default 'original') - Optional - Julian date calculation. Can be one of the following: - `'original'`: calculation based on Michalsky's paper. - `'pandas'`: calculation using a pandas built-in function. ### Returns pandas.DataFrame with the following columns (all values in degrees): - elevation: actual sun elevation (not accounting for refraction). - apparent_elevation: sun elevation, accounting for atmospheric refraction. - zenith: actual sun zenith (not accounting for refraction). - apparent_zenith: sun zenith, accounting for atmospheric refraction. - azimuth: sun azimuth, east of north. ### Raises - **ValueError** - An error is raised if the julian_date calculation is not 'original' or 'pandas'. ### Notes The Michalsky algorithm is based on equations in the Astronomical Almanac. The original algorithm did not work for the southern hemisphere; this implementation includes by default the Spencer correction to work for all latitudes. Minor clarifications to the original paper have been published as errata. The Julian date calculation in the original paper ensures the stated accuracy only for 1950-2050; outside this period, the 'pandas' option can be used. ``` -------------------------------- ### solarposition.spa(time, latitude, longitude) Source: https://solposx.readthedocs.io/en/stable/solarposition.html Calculates the solar position using a python implementation of the NREL SPA algorithm. ```APIDOC ## solarposition.spa(time, latitude, longitude) ### Description Calculate the solar position using a python implementation of the NREL SPA algorithm. ### Parameters - **time** - The time for which to calculate the solar position. - **latitude** - The latitude of the location. - **longitude** - The longitude of the location. ### Returns - Solar zenith, elevation, and azimuth angles. ``` -------------------------------- ### Calculate solar position with solposx.michalsky and plot elevation/azimuth Source: https://solposx.readthedocs.io/en/stable/solarposition_introduction.html Calculates solar elevation and azimuth angles at the Technical University of Denmark on 2025/06/21 using the Michalsky algorithm from solposx. It creates a Location object with pvlib, generates an hourly time range, and plots the resulting elevation and azimuth angles over time. ```python import pandas as pd import matplotlib.pyplot as plt import solposx from pvlib.location import Location import matplotlib.dates as mdates # Definition of Location object site = Location(55.79, 12.52, 'UTC', 50, 'DTU, Denmark') # latitude, longitude, time_zone, altitude, name # Definition of a time range of simulation times = pd.date_range('2025-06-21 00:00:00', '2025-06-22 00:00:00', freq='h', tz=site.tz) # Calculate solar position solpos = solposx.solarposition.michalsky(times, site.latitude, site.longitude) # Plots for solar zenith and solar azimuth angles fig, axes = plt.subplots(1, 2, figsize=(8, 4)) fig.suptitle('Solar Position Estimation at the Technical University of Denmark on 2025/06/21') # plot for solar elevation angle axes[0].plot(solpos.elevation) axes[0].set_ylabel('Solar elevation angle [°]') # plot for solar azimuth angle axes[1].plot(solpos.azimuth) axes[1].set_ylabel('Solar azimuth angle [°]') # format plot for ax in axes: ax.set_xlabel('Time (UTC)') ax.xaxis.set_major_formatter(mdates.DateFormatter('%H')) ax.set_xlim(pd.Timestamp('2025-06-21 00:00:00'), pd.Timestamp('2025-06-21 23:59:00')) plt.tight_layout() plt.show() ``` -------------------------------- ### solposx.solarposition.sg2_c Source: https://solposx.readthedocs.io/en/stable/generated/solposx.solarposition.sg2_c.html Documentation for the sg2_c() function, which calculates solar position using the SG2 Python package. ```APIDOC ## solposx.solarposition.sg2_c ### Description Calculates solar position using the SG2 Python package, which wraps the official C-code. The SG2 algorithm has a stated accuracy of 0.003 degrees from years 1980 to 2030. ### Method Function call ### Signature `solposx.solarposition.sg2_c(times, latitude, longitude, elevation=0, *, pressure=101325, temperature=12)` ### Parameters - **times** (pandas.DatetimeIndex) - Required - Must be localized. - **latitude** (float) - Required - Latitude in decimal degrees. Positive north of equator, negative to south. [degrees] - **longitude** (float) - Required - Longitude in decimal degrees. Positive east of prime meridian, negative to west. [degrees] - **elevation** (float, default: 0) - Optional - Altitude of the location of interest. [m] - **pressure** (float, default: 101325) - Optional - Annual average air pressure. [Pa] - **temperature** (float, default: 12) - Optional - Annual average air temperature. [°C] ### Returns pandas.DataFrame with the following columns (all values in degrees): - elevation: actual sun elevation (not accounting for refraction). - apparent_elevation: sun elevation, accounting for atmospheric refraction. - zenith: actual sun zenith (not accounting for refraction). - apparent_zenith: sun zenith, accounting for atmospheric refraction. - azimuth: sun azimuth, east of north. ### Return Type pandas.DataFrame ### See Also - `solposx.solarposition.sg2` ### References - [1] SG2 Python package - [2] SG2 algorithm ``` -------------------------------- ### solarposition.michalsky(times, latitude, ...) Source: https://solposx.readthedocs.io/en/stable/solarposition.html Calculates the solar position using the Michalsky algorithm. ```APIDOC ## solarposition.michalsky(times, latitude, ...) ### Description Calculate solar position using the Michalsky algorithm. ### Parameters - **times** - The time(s) for which to calculate the solar position. - **latitude** - The latitude of the location. ### Returns - Solar zenith, elevation, and azimuth angles. ``` -------------------------------- ### usno(times, latitude, longitude, *, delta_t=67.0, gmst_option=1) Source: https://solposx.readthedocs.io/en/stable/generated/solposx.solarposition.usno.html Calculates solar position using the USNO algorithm. Returns a DataFrame with elevation, zenith, and azimuth angles in degrees. ```APIDOC ## usno(times, latitude, longitude, *, delta_t=67.0, gmst_option=1) ### Description Calculates solar position using the USNO algorithm. Returns a DataFrame with elevation, zenith, and azimuth angles in degrees. ### Method Function call ### Signature `usno(times, latitude, longitude, *, delta_t=67.0, gmst_option=1)` ### Parameters - **times** (pandas.DatetimeIndex) - Required - Timestamps - must be localized. Prior to 1970 and far in the future UTC and UT1 may deviate significantly. For such use cases, UT1 times should be provided. - **latitude** (float) - Required - Latitude in decimal degrees. Positive north of equator, negative to south. [degrees] - **longitude** (float) - Required - Longitude in decimal degrees. Positive east of prime meridian, negative to west. [degrees] - **delta_t** (numeric, default: 67.0) - Optional - Difference between terrestrial time and UT1. If `delta_t` is None, uses `pvlib.spa.calculate_deltat()` using `times.year` and `times.month` from pandas.DatetimeIndex. For most simulations the default `delta_t` is sufficient. The USNO has historical and forecasted `delta_t`. [seconds] - **gmst_option** (int, default: 1) - Optional - Different ways of calculating the Greenwich mean sidereal time. gmst_option needs to be either 1 or 2. ### Returns pandas.DataFrame with the following columns (all values in degrees): - **elevation** : actual sun elevation (not accounting for refraction). - **zenith** : actual sun zenith (not accounting for refraction). - **azimuth** : sun azimuth, east of north. ### Return Type pandas.DataFrame ### References [1] U.S. Naval Observatory algorithm reference. ``` -------------------------------- ### solposx.solarposition.sg2 Source: https://solposx.readthedocs.io/en/stable/generated/solposx.solarposition.sg2.html Documentation for the sg2() function, which calculates solar position using the SG2 algorithm. ```APIDOC ## solposx.solarposition.sg2 ### Description Calculate solar position using the SG2 algorithm. The SG2 algorithm has a stated accuracy of 0.003 degrees from years 1980 to 2030. ### Method Function call ### Signature ```python solposx.solarposition.sg2(times, latitude, longitude, elevation=0, *, pressure=101325, temperature=12) ``` ### Parameters - **times** (pandas.DatetimeIndex) - Required - Timestamps - must be localized. Prior to 1970 and far in the future UTC and UT1 may deviate significantly. For such use cases, UT1 times should be provided. - **latitude** (float) - Required - Latitude in decimal degrees. Positive north of equator, negative to south. [degrees] - **longitude** (float) - Required - Longitude in decimal degrees. Positive east of prime meridian, negative to west. [degrees] - **elevation** (float, default: 0) - Optional - Altitude of the location of interest. [m] - **pressure** (float, default: 101325) - Optional - Annual average air pressure. [Pa] - **temperature** (float, default: 12) - Optional - Annual average air temperature. [°C] ### Returns pandas.DataFrame with the following columns (all values in degrees): - **elevation** : actual sun elevation (not accounting for refraction). - **apparent_elevation** : sun elevation, accounting for atmospheric refraction. - **zenith** : actual sun zenith (not accounting for refraction). - **apparent_zenith** : sun zenith, accounting for atmospheric refraction. - **azimuth** : sun azimuth, east of north. ### Notes The SG2 equations as described in [1] had a number of typos and errors. These errors have been corrected in the present implementation. ### See Also - `solposx.solarposition.sg2_c` ``` -------------------------------- ### solarposition.usno(times, latitude, longitude, *) Source: https://solposx.readthedocs.io/en/stable/solarposition.html Calculates the solar position using the USNO algorithm. ```APIDOC ## solarposition.usno(times, latitude, longitude, *) ### Description Calculate solar position using the USNO algorithm. ### Parameters - **times** - The time(s) for which to calculate the solar position. - **latitude** - The latitude of the location. - **longitude** - The longitude of the location. ### Returns - Solar zenith, elevation, and azimuth angles. ``` -------------------------------- ### spa() Source: https://solposx.readthedocs.io/en/stable/generated/solposx.solarposition.spa.html Calculate the solar position using a python implementation of the NREL SPA algorithm. The function accepts a pandas.DatetimeIndex, latitude, longitude, and optional parameters for elevation, air pressure, temperature, delta_t, and atmospheric refraction. It returns a pandas DataFrame with solar position values. ```APIDOC ## spa() ### Description Calculate the solar position using a python implementation of the NREL SPA algorithm. The details of the NREL SPA algorithm are described in [1], [2]. If numba is installed, the functions can be compiled to machine code and the function can be multithreaded. Without numba, the function evaluates via numpy with a slight performance hit. ### Method Function call ### Signature `solposx.solarposition.spa(time, latitude, longitude, elevation=0.0, *, air_pressure=101325.0, temperature=12.0, delta_t=67.0, atmos_refract=None, **kwargs)` ### Parameters - **time** (pandas.DatetimeIndex) - Required - Timestamps - must be localized. Prior to 1970 and far in the future UTC and UT1 may deviate significantly. For such use cases, UT1 times should be provided. - **latitude** (float) - Required - Latitude in decimal degrees. Positive north of equator, negative to south. [degrees] - **longitude** (float) - Required - Longitude in decimal degrees. Positive east of prime meridian, negative to west. [degrees] - **elevation** (float, default: 0) - Optional - Altitude of the location of interest. [m] - **air_pressure** (float, default: 101325) - Optional - Annual average air pressure. [Pa] - **temperature** (float, default: 12) - Optional - Annual average air temperature. [°C] negative to west. [degrees] - **delta_t** (numeric, default: 67.0) - Optional - Difference between terrestrial time and UT1. If `delta_t` is None, uses `pvlib.spa.calculate_deltat()` using `times.year` and `times.month` from pandas.DatetimeIndex. For most simulations the default `delta_t` is sufficient. The USNO has historical and forecasted `delta_t` [3]. [seconds] - **atmos_refract** (float, optional) - Optional - The approximate atmospheric refraction (in degrees) at sunrise and sunset. - **how** (str, optional, default 'numpy') - Optional - Options are 'numpy' or 'numba'. If numba >= 0.17.0 is installed, how='numba' will compile the spa functions to machine code and run them multithreaded. - **numthreads** (int, optional, default 4) - Optional - Number of threads to use if how == 'numba'. ### Returns pandas.DataFrame with the following columns (all values in degrees): - **elevation** : actual sun elevation (not accounting for refraction). [°] - **apparent_elevation** : sun elevation, accounting for atmospheric refraction. [°] - **zenith** : actual sun zenith (not accounting for refraction). [°] - **apparent_zenith** : sun zenith, accounting for atmospheric refraction. [°] - **azimuth** : sun azimuth, east of north. [°] - **equation_of_time** : [minutes] ### Return Type pandas.DataFrame ### References [1] NREL SPA algorithm details [2] NREL SPA algorithm details [3] USNO historical and forecasted delta_t ``` -------------------------------- ### Plot elevation and azimuth differences Source: https://solposx.readthedocs.io/en/stable/solarposition_introduction.html Creates two side-by-side plots showing the difference in solar elevation and azimuth angles between the Michalsky and Skyfield models over the year. ```python fig, axes = plt.subplots(1, 2, figsize=(10, 4.5), facecolor='w', edgecolor='k') axes[0].plot(michalsky['elevation']-skyfield['elevation']) axes[1].plot(michalsky['azimuth']-skyfield['azimuth']) axes[0].set_ylabel('Difference in solar elevation angle [°]') axes[0].set_ylim(-0.011, 0.011) axes[1].set_ylabel('Difference in solar azimuth angle [°]') axes[1].set_ylim(-0.015, 0.015) for ax in axes: ax.set_xlabel('Month') ax.xaxis.set_major_formatter(mdates.DateFormatter('%b')) ax.grid(alpha=0.5, zorder=-2) plt.tight_layout() plt.show() ``` -------------------------------- ### solarposition.nasa_horizons(latitude, ...) Source: https://solposx.readthedocs.io/en/stable/solarposition.html Retrieves solar positions from NASA's Horizons web service. ```APIDOC ## solarposition.nasa_horizons(latitude, ...) ### Description Retrieve solar positions from NASA's Horizons web service. ### Parameters - **latitude** - The latitude of the location. ### Returns - Solar zenith, elevation, and azimuth angles. ``` -------------------------------- ### solarposition.sg2(times, latitude, longitude) Source: https://solposx.readthedocs.io/en/stable/solarposition.html Calculates the solar position using the SG2 algorithm. ```APIDOC ## solarposition.sg2(times, latitude, longitude) ### Description Calculate solar position using the SG2 algorithm. ### Parameters - **times** - The time(s) for which to calculate the solar position. - **latitude** - The latitude of the location. - **longitude** - The longitude of the location. ### Returns - Solar zenith, elevation, and azimuth angles. ``` -------------------------------- ### solarposition.psa(times, latitude, longitude, *) Source: https://solposx.readthedocs.io/en/stable/solarposition.html Calculates the solar position using the PSA algorithm. ```APIDOC ## solarposition.psa(times, latitude, longitude, *) ### Description Calculate solar position using the PSA algorithm. ### Parameters - **times** - The time(s) for which to calculate the solar position. - **latitude** - The latitude of the location. - **longitude** - The longitude of the location. ### Returns - Solar zenith, elevation, and azimuth angles. ``` -------------------------------- ### iqbal(times, latitude, longitude) Source: https://solposx.readthedocs.io/en/stable/generated/solposx.solarposition.iqbal.html Calculates solar position using the Iqbal algorithm. Returns a DataFrame with elevation, zenith, and azimuth angles in degrees. ```APIDOC ## iqbal(times, latitude, longitude) ### Description Calculates solar position using the Iqbal algorithm. The Iqbal algorithm is based on equations in [2]. ### Method Function call ### Signature `solposx.solarposition.iqbal(times, latitude, longitude)` ### Parameters - **times** (pandas.DatetimeIndex) - Required - Timestamps - must be localized. Prior to 1970 and far in the future UTC and UT1 may deviate significantly. For such use cases, UT1 times should be provided. - **latitude** (float) - Required - Latitude in decimal degrees. Positive north of equator, negative to south. [degrees] - **longitude** (float) - Required - Longitude in decimal degrees. Positive east of prime meridian, negative to west. [degrees] ### Returns DataFrame with the following columns (all values in degrees): - **elevation** : actual sun elevation (not accounting for refraction). - **zenith** : actual sun zenith (not accounting for refraction). - **azimuth** : sun azimuth, east of north. ### Return Type pandas.DataFrame ### References [1] Iqbal algorithm reference. [2] Equations reference. ``` -------------------------------- ### Calculate refraction for six models with solposx Source: https://solposx.readthedocs.io/en/stable/refraction_introduction.html Calculates refraction angles for six models (Archer, Bennett, Hughes, Michalsky, SG2, SPA) over solar elevation angles from -5 to 90 degrees in 0.1-degree steps. The resulting DataFrame is used for the comparison plots. ```python import numpy as np import pandas as pd import solposx functions = { 'Archer': solposx.refraction.archer, 'Bennett': solposx.refraction.bennett, 'Hughes': solposx.refraction.hughes, 'Michalsky': solposx.refraction.michalsky, 'SG2': solposx.refraction.sg2, 'SPA': solposx.refraction.spa, } elevation = np.arange(-5, 90, 0.1) refraction = pd.DataFrame( data={name: function(elevation) for name, function in functions.items()}, index=elevation) ``` -------------------------------- ### solarposition.skyfield(times, latitude, ...) Source: https://solposx.readthedocs.io/en/stable/solarposition.html Calculates the solar position using the Skyfield Python package. ```APIDOC ## solarposition.skyfield(times, latitude, ...) ### Description Calculate solar position using the Skyfield Python package. ### Parameters - **times** - The time(s) for which to calculate the solar position. - **latitude** - The latitude of the location. ### Returns - Solar zenith, elevation, and azimuth angles. ``` -------------------------------- ### solarposition.noaa(times, latitude, longitude, *) Source: https://solposx.readthedocs.io/en/stable/solarposition.html Calculates the solar position using the NOAA algorithm. ```APIDOC ## solarposition.noaa(times, latitude, longitude, *) ### Description Calculate solar position using the NOAA algorithm. ### Parameters - **times** - The time(s) for which to calculate the solar position. - **latitude** - The latitude of the location. - **longitude** - The longitude of the location. ### Returns - Solar zenith, elevation, and azimuth angles. ``` -------------------------------- ### psa() Source: https://solposx.readthedocs.io/en/stable/generated/solposx.solarposition.psa.html Calculate solar position using the PSA algorithm. The algorithm was developed at Plataforma Solar de Almería (PSA) and can use two sets of coefficients: 2001 (tuned to 1999-2015) and 2020 (tuned to 2020-2050). ```APIDOC ## psa() ### Description Calculate solar position using the PSA algorithm. The algorithm was developed at Plataforma Solar de Almería (PSA) and can use two sets of coefficients: 2001 (tuned to 1999-2015) and 2020 (tuned to 2020-2050). ### Method Function call ### Signature `solposx.solarposition.psa(times, latitude, longitude, *, coefficients=2020)` ### Parameters - **times** (pandas.DatetimeIndex) - Required - Timestamps - must be localized. Prior to 1970 and far in the future UTC and UT1 may deviate significantly. For such use cases, UT1 times should be provided. - **latitude** (float) - Required - Latitude in decimal degrees. Positive north of equator, negative to south. [degrees] - **longitude** (float) - Required - Longitude in decimal degrees. Positive east of prime meridian, negative to west. [degrees] - **coefficients** (int or list, default 2020) - Optional - Coefficients for the solar position algorithm. Available options include 2001 or 2020. Alternatively a list of custom coefficients can be specified. ### Raises - **ValueError** - Raises an error if `coefficients` is not in [2001, 2020] or a list of the 15 coefficients. ### Returns DataFrame with the following columns (all values in degrees): - **elevation** - actual sun elevation (not accounting for refraction). - **azimuth** - sun azimuth, east of north. - **zenith** - actual sun zenith (not accounting for refraction). Return type: pandas.DataFrame ``` -------------------------------- ### skyfield(times, latitude, longitude, *, de='de440.bsp') Source: https://solposx.readthedocs.io/en/stable/generated/solposx.solarposition.skyfield.html Calculates solar position using the Skyfield Python package. Returns a DataFrame with elevation, zenith, and azimuth in degrees. ```APIDOC ## skyfield(times, latitude, longitude, *, de='de440.bsp') ### Description Calculate solar position using the Skyfield Python package. Skyfield is a Python package that can calculate high precision position of stars, planets, and satellites in orbit around the Earth based on ephemerides. Calculated positions should agree with the Astronomical Almanac to within 0.0005 arcseconds. ### Method Function call ### Signature ```python skyfield(times, latitude, longitude, *, de='de440.bsp') ``` ### Parameters - **times** (pandas.DatetimeIndex) - Required - Timestamps - must be localized. Prior to 1970 and far in the future UTC and UT1 may deviate significantly. For such use cases, UT1 times should be provided. - **latitude** (float) - Required - Latitude in decimal degrees. Positive north of equator, negative to south. [degrees] - **longitude** (float) - Required - Longitude in decimal degrees. Positive east of prime meridian, negative to west. [degrees] - **de** (str or Skyfield SpiceKernel, optional, default: 'de440.bsp') - Ephemeris of choice. ### Returns pandas.DataFrame with the following columns (all values in degrees): - **elevation** : actual sun elevation (not accounting for refraction). - **zenith** : actual sun zenith (not accounting for refraction). - **azimuth** : sun azimuth, east of north. ### Return Type pandas.DataFrame ### References - [1] Skyfield documentation - [2] Skyfield package ``` -------------------------------- ### hughes(elevation, pressure=101325.0, temperature=12.0) Source: https://solposx.readthedocs.io/en/stable/generated/solposx.refraction.hughes.html Computes the atmospheric refraction correction based on the Hughes algorithm. Takes the true solar elevation angle and optional pressure and temperature values, returning the refraction angle in degrees. ```APIDOC ## Function: hughes(elevation, pressure=101325.0, temperature=12.0) ### Description Computes the atmospheric refraction correction based on the Hughes algorithm. This function is used to calculate the refraction correction in the NOAA solar position algorithm. ### Parameters - **elevation** (array-like) - Required - True solar elevation angle (not accounting for refraction). [degrees] - **pressure** (numeric, default 101325) - Optional - Annual average atmospheric pressure. [Pascal] - **temperature** (numeric, default 12) - Optional - Annual average temperature. The default in this code deviates from [1], which used 10 C. [C] ### Returns - **refraction_angle** (np.array or pd.Series) - Atmospheric refraction angle. [degrees] ### Notes The equation to calculate the refraction correction is given by: 5° -0.01 rad, the formula is: \(\frac{P}{1010} \cdot \frac{283}{273+T} \cdot \frac{2.96706 \times 10^{-4}}{\tan(el + 0.0031376 \cdot (el + 0.089186)^{-1})}\) For elevation < -0.01 rad, the formula is: \(\frac{P}{1010} \cdot \frac{283}{273+T} \cdot \frac{1.005516 \times 10^{-4}}{\tan(el)}\) where \(el\) is the true solar elevation angle, \(P\) is the local air pressure, and \(T\) is the local air temperature. ### References - [1] Ph. Blanc and L. Wald, "The SG2 algorithm for a fast and accurate computation of the position of the Sun for multi-decadal time period", Solar Energy, 2012. ``` -------------------------------- ### michalsky(elevation) Source: https://solposx.readthedocs.io/en/stable/generated/solposx.refraction.michalsky.html Calculates the atmospheric refraction correction for a given true solar elevation angle using the Michalsky algorithm. Returns the refraction angle in degrees. ```APIDOC ## michalsky(elevation) ### Description Calculates the atmospheric refraction correction for a given true solar elevation angle using the Michalsky algorithm. ### Method Function call ### Endpoint `solposx.refraction.michalsky(elevation)` ### Parameters - **elevation** (array-like) - Required - True solar elevation angle (not accounting for refraction). [degrees] ### Returns - **np.array or pd.Series** - Atmospheric refraction angle. [degrees] ### Notes The equation to calculate the refraction correction is given by: ref = 3.51561 * (0.1594 + 0.0196 * el + 0.00002 * el^2) / (1 + 0.505 * el + 0.0845 * el^2) where el is the true (uncorrected) solar elevation angle. ### References - Michalsky [1] ``` -------------------------------- ### RMSD output Source: https://solposx.readthedocs.io/en/stable/solarposition_introduction.html Shows the printed RMSD values for the comparison. ```text The RMSD of the Michalsky model to Skyfield for elevation angle is: 0.0043 degrees The RMSD of the Michalsky model to Skyfield for azimuth angle is: 0.0048 degrees The RMSD of the Michalsky model to Skyfield for combined vector angle is: 0.0049 degrees ``` -------------------------------- ### solposx.refraction.spa(elevation, pressure=101325.0, temperature=12.0, *, refraction_limit=-0.5667) Source: https://solposx.readthedocs.io/en/stable/generated/solposx.refraction.spa.html Calculates the atmospheric refraction correction of the solar elevation angle using the SPA algorithm. This function takes the true solar elevation angle and optional atmospheric parameters, returning the refraction angle in degrees. ```APIDOC ## solposx.refraction.spa(elevation, pressure=101325.0, temperature=12.0, *, refraction_limit=-0.5667) ### Description Calculates the atmospheric refraction correction of the solar elevation angle using the method described in Reda and Andreas's Solar Position Algorithm (SPA). ### Parameters - **elevation** (array-like) - Required - True solar elevation angle (not accounting for refraction). [degrees] - **pressure** (numeric, default 101325) - Optional - Annual average local pressure. [Pa] - **temperature** (numeric, default 12) - Optional - Annual average local air temperature. [C] - **refraction_limit** (float, default -0.5667) - Optional - Solar elevation angle below which refraction is not applied, as the sun is assumed to be below horizon. Note that the sun diameter is added to this. [degrees] ### Returns Atmospheric refraction angle. [degrees] ### Return Type np.array or pd.Series ### Notes The equation to calculate the refraction correction is given by: ref = P / 101000 * 283 / (273 + T) * 1.0260 / tan(el + 10.3 / (el + 5.11)) where el is the true solar elevation angle, P is the annual average local air pressure, and T is the annual average local air temperature. ### References Reda, I., Andreas, A. (2004). Solar Position Algorithm for Solar Radiation Applications. NREL/TP-560-34302. ``` -------------------------------- ### solposx.solarposition.noaa(times, latitude, longitude, *, delta_t=67.0) Source: https://solposx.readthedocs.io/en/stable/generated/solposx.solarposition.noaa.html Calculates solar position using the NOAA algorithm. The algorithm has stated accuracy of 0.0167 degrees for years -2000 to +3000 and latitudes within +/-72 degrees. Returns a DataFrame containing elevation, apparent elevation, zenith, apparent zenith, and azimuth angles. ```APIDOC ## solposx.solarposition.noaa ### Description Calculates solar position using the NOAA algorithm. The algorithm has a stated accuracy of 0.0167 degrees from years -2000 to +3000 for latitudes within +/- 72 degrees. For latitudes outside this range the accuracy is 0.167 degrees. Returns a pandas DataFrame with solar elevation, zenith, and azimuth angles. ### Method Function call ### Endpoint solposx.solarposition.noaa(times, latitude, longitude, *, delta_t=67.0) ### Parameters - **times** (pandas.DatetimeIndex) - Required - Timestamps, must be localized. Prior to 1970 and far in the future UTC and UT1 may deviate significantly; for such use cases, UT1 times should be provided. - **latitude** (float) - Required - Latitude in decimal degrees. Positive north of equator, negative to south. [degrees] - **longitude** (float) - Required - Longitude in decimal degrees. Positive east of prime meridian, negative to west. [degrees] - **delta_t** (numeric, default 67.0) - Optional - Difference between terrestrial time and UT1. If `delta_t` is None, uses `pvlib.spa.calculate_deltat()` using `times.year` and `times.month` from pandas.DatetimeIndex. For most simulations the default `delta_t` is sufficient. The USNO has historical and forecasted `delta_t`. [seconds] ### Returns Returns a pandas DataFrame with the following columns (all values in degrees): - elevation: actual sun elevation (not accounting for refraction). - apparent_elevation: sun elevation, accounting for atmospheric refraction. - zenith: actual sun zenith (not accounting for refraction). - apparent_zenith: sun zenith, accounting for atmospheric refraction. - azimuth: sun azimuth, east of north. Return type: pandas.DataFrame ### Notes The algorithm is from Astronomical Algorithms by Jean Meeus. ``` -------------------------------- ### bennett(elevation, pressure=101325.0, temperature=12.0) Source: https://solposx.readthedocs.io/en/stable/generated/solposx.refraction.bennett.html Calculates the atmospheric refraction correction for a given solar elevation angle using the Bennett algorithm. The function takes the true solar elevation angle, atmospheric pressure, and temperature as inputs, and returns the refraction angle in degrees. ```APIDOC ## bennett(elevation, pressure=101325.0, temperature=12.0) ### Description Calculates the atmospheric refraction correction for a given solar elevation angle using the Bennett algorithm. The function takes the true solar elevation angle, atmospheric pressure, and temperature as inputs, and returns the refraction angle in degrees. ### Method Function Call ### Endpoint bennett(elevation, pressure=101325.0, temperature=12.0) ### Parameters #### Input Parameters - **elevation** (array-like) - Required - True solar elevation angle (not accounting for refraction). [degrees] - **pressure** (numeric, default 101325) - Optional - Annual average atmospheric pressure. [Pascal] - **temperature** (numeric, default 12) - Optional - Annual average air temperature. [C] ### Returns - **refraction_angle** (np.array or pd.Series) - Atmospheric refraction angle. [degrees] ### Notes The equation to calculate the refraction correction is given by: ref = 0.28 * (P / (T + 273)) * (0.016667 / tan(el + 7.31 / (el + 4.4))) where P is the local air pressure, T is the local air temperature, and el is the true (uncorrected) solar elevation angle. ### References - Bennett, G. G. (1982). The calculation of astronomical refraction in marine navigation. Journal of Navigation, 35(2), 255-259. ``` -------------------------------- ### Plot refraction comparison with matplotlib Source: https://solposx.readthedocs.io/en/stable/refraction_introduction.html Plots the refraction DataFrame in two subplots: left shows refraction near sunrise/sunset (elevation -1.5 to 4 degrees) with linear y-axis, right shows the full range with log y-axis. Uses the previously computed 'refraction' DataFrame. ```python import matplotlib.pyplot as plt fig, axes = plt.subplots(1, 2, figsize=(8, 4)) refraction.plot(ax=axes[0]) axes[0].set_ylim(0, 1.0) axes[0].set_xlim(-1.5, 4) axes[0].set_ylabel('Refraction correction [degrees]') axes[0].set_xlabel('True elevation [degrees]') refraction.plot(ax=axes[1]) axes[1].set_yscale('log') axes[1].set_ylim(1e-3, 1.0) axes[1].set_xlim(-1.5, 90) axes[1].set_ylabel('Refraction correction [degrees]') axes[1].set_xlabel('True solar elevation [degrees]') fig.tight_layout() axes[0].legend(loc='upper center', bbox_to_anchor=[1.05, 1.25], title='Refraction model', labelspacing=1.5, ncol=6, frameon=False) axes[1].legend([], frameon=False) plt.show() ```