{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Clear Sky Examples\n", "\n", "## Overview of Functionality\n", "\n", "The captest clear sky functionality is based entirely on wrapping and integrating the clear sky modeling capabilities of the [pvlib-python package](https://pvlib-python.readthedocs.io/en/latest/index.html). The primary intent of this functionality is to provide the option to easily calculate and plot modeled clear sky data as part of the workflow of loading, visualizing, and validating data from pyranometers.\n", "\n", "When setting clear_sky to True when calling the CapData load_data method, the csky function will be called when loading data and the modeled clear sky POA and GHI data will be added to the dataframe. The plot method will detect these columns and plot them as dashed lines with the measured irradiance data.\n", "\n", "Below is a basic example of this functionality using data from the NREL Solar Radiation Research Library.\n", "\n", "Andreas, A.; Stoffel, T.; (1981). NREL Solar Radiation Research Laboratory (SRRL): Baseline\n", "Measurement System (BMS); Golden, Colorado (Data); NREL Report No. DA-5500-56488.\n", "http://dx.doi.org/10.5439/1052221 " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import warnings\n", "warnings.filterwarnings('ignore')\n", "import pandas as pd\n", "import captest as ct\n", "from captest import capdata as pvc\n", "\n", "from bokeh.io import output_notebook\n", "output_notebook()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "site = {\n", " 'loc': {'latitude': 39.742, 'longitude': -105.18, 'altitude': 1828.8, 'tz': 'Etc/GMT+7'},\n", " 'sys': {'surface_tilt': 40, 'surface_azimuth': 180, 'albedo': 0.2},\n", "}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "meas_nrel = ct.load_data('./data/nrel_data.csv', site=site)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "meas_nrel.plot(default_groups=['irr_comb'], combine={'irr_comb':'poa|ghi'}, width=900)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Viewing a few rows of the dataframe within the CapData object shows that the modeled clear sky POA and GHI irradiance have been added as columns when loading the data." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "meas_nrel.data['3/10/2019 12:00':'3/10/2019 12:03']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Explanation of csky Functions\n", "\n", "The clear sky functionality is based around 4 top-level functions:\n", "- pvlib_location\n", "- pvlib_system\n", "- get_tz_index\n", "- csky\n", "\n", "### Location and System wrappers: `pvlib_location` and `pvlib_system`\n", "\n", "The first two, pvlib_location and pvlib_system, are simply wrappers that generate pvlib location and system objects from a dictionary. The intent of providing these wrapper functions is to allow the captest user to be able to simply specify a dictionary for each without needing to import the entire pvlib package or know where the `Location` and system objects are within pvlib. \n", "\n", "The location dictionary defined in the example can be used with the `pvlib_location` function to create a pvlib location object." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "site['loc']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bms_location = pvc.pvlib_location(site['loc'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "type(bms_location)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bms_location" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly, the `pvlib_system` function can be used to generate a pvlib system object.\n", "\n", "Creating a pvlib ModelChain object requires providing a system object with module and inverter parameters defined. The captest pvlib_system function provides arbitrary module and inverter parameters, so the captest user does not need to find and specify these. The module and inverter parameters are not used when calculating the clear sky data.\n", "\n", "The `pvlib_system` function also determines from the keywords of the passed dictionary whether the `PVSystem` pvlib object should have a `FixedMount` or a `SingleAxisTrackerMount`. There is a tracking system example below." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "site['sys']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bms_system = pvc.pvlib_system(site['sys'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "type(bms_system)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bms_system" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bms_system.arrays[0].module_parameters.head()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bms_system.inverter_parameters.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Get Timezone Index `get_tz_index`\n", "\n", "The pvlib methods used to calculate clear sky irradiance require a time-zone aware datetime index as an argument. The get_tz_index function returns a time-zone aware datetime index given a datetime index or a dataframe. If the passed argument is already timezone aware, the index will be used as is; otherwise, the timezone will be set using the timezone in the location dictionary.\n", "\n", "**Be sure the timezone matches the timezone of the measured data.**\n", "\n", "For example, the time stamps of the example data from NREL are in MST and do not adjust for daylight savings, so specifying a timezone that does follow daylight savings, like 'America/Denver' will cause an error. Please refer to the pvlib documentaiton, which has a helpful [section on timezones](https://pvlib-python.readthedocs.io/en/latest/timetimezones.html), for more information.\n", "\n", "The example usage of `get_tz_index` below matches the usage within the csky function in the example above. The function returns a time-zone aware datetime index." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(meas_nrel.data.index.tz)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pvc.get_tz_index(meas_nrel.data, site['loc'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Passing the datetime index rather than the dataframe will return the same time-zone aware index." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pvc.get_tz_index(meas_nrel.data.index, site['loc'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The below example shows the behavior if the time_source, dataframe or datetime index, already has a timezone when passed to `get_tz_index`. The timezone of the time_source is used and a warning is raised to alert the user that the timezone of the time_source and the passed location dictionary do not match." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df = meas_nrel.data.copy()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df.index = df.index.tz_localize('America/Caracas')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "site['loc']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pvc.get_tz_index(df, site['loc'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Clear Sky Function `csky`\n", "\n", "The clear sky function calls `pvlib_location`, `pvlib_system`, and `get_tz_index` and genarates pvlib objects to calculate modeled clear sky GHI and POA. The essential functionality is shown in the example where the clear sky POA and GHI are added to the imported data. `csky` can also return any componenet of the modeled csky data directly as shown below." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "poa_ghi = pvc.csky(meas_nrel.data, loc=site['loc'], sys=site['sys'], concat=False, output='both')\n", "poa_ghi['3/10/2019 12:00':'3/10/2019 12:05']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "all_irrad_comp = pvc.csky(meas_nrel.data, loc=site['loc'], sys=site['sys'], concat=False, output='all')\n", "all_irrad_comp['3/10/2019 12:00':'3/10/2019 12:05']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tracking System Example\n", "\n", "It is possible to calculate the POA irradiance for a single-axis tracking system by defining location dictionary with tracker specific values." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "meas_nrel_trck = pvc.CapData('meas_nrel_track')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "site_tracker = {\n", " 'loc': {'latitude': 39.742, 'longitude': -105.18, 'altitude': 1828.8, 'tz': 'Etc/GMT+7'},\n", " 'sys': {'axis_tilt': 0, 'axis_azimuth': 0, 'max_angle': 52, 'backtrack': True, 'gcr': 0.2, 'albedo': 0.2},\n", "}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "meas_nrel_trck = ct.load_data('./data/nrel_data.csv', site=site_tracker)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "meas_nrel_trck.plot(default_groups=['irr_comb'], combine={'irr_comb':'poa|ghi'}, width=900)" ] } ], "metadata": { "hide_input": false, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 4 }