{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Modeling Spectral Irradiance\n\nRecreating Figure 5-1A from the SPECTRL2 NREL Technical Report.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "This example shows how to model the spectral distribution of irradiance\nbased on atmospheric conditions. The spectral distribution of irradiance is\nthe power content at each wavelength band in the solar spectrum and is\naffected by various scattering and absorption mechanisms in the atmosphere.\nThis example recreates an example figure from the SPECTRL2 NREL Technical\nReport [1]_. The figure shows modeled spectra at hourly intervals across\na single morning.\n\n## References\n.. [1] Bird, R, and Riordan, C., 1984, \"Simple solar spectral model for\n   direct and diffuse irradiance on horizontal and tilted planes at the\n   earth's surface for cloudless atmospheres\", NREL Technical Report\n   TR-215-2436 doi:10.2172/5986936.\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The SPECTRL2 model has several inputs; some can be calculated with pvlib,\nbut other must come from a weather dataset. In this case, these weather\nparameters are example assumptions taken from the technical report.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from pvlib import spectrum, solarposition, irradiance, atmosphere\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\n# assumptions from the technical report:\nlat = 37\nlon = -100\ntilt = 37\nazimuth = 180\npressure = 101300  # sea level, roughly\nwater_vapor_content = 0.5  # cm\ntau500 = 0.1\nozone = 0.31  # atm-cm\nalbedo = 0.2\n\ntimes = pd.date_range('1984-03-20 06:17', freq='h', periods=6, tz='Etc/GMT+7')\nsolpos = solarposition.get_solarposition(times, lat, lon)\naoi = irradiance.aoi(tilt, azimuth, solpos.apparent_zenith, solpos.azimuth)\n\n# The technical report uses the 'kasten1966' airmass model, but later\n# versions of SPECTRL2 use 'kastenyoung1989'.  Here we use 'kasten1966'\n# for consistency with the technical report.\nrelative_airmass = atmosphere.get_relative_airmass(solpos.apparent_zenith,\n                                                   model='kasten1966')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "With all the necessary inputs in hand we can model spectral irradiance using\n:py:func:`pvlib.spectrum.spectrl2`.  Note that because we are calculating\nthe spectra for more than one set of conditions, we will get back 2-D\narrays (one dimension for wavelength, one for time).\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "spectra = spectrum.spectrl2(\n    apparent_zenith=solpos.apparent_zenith,\n    aoi=aoi,\n    surface_tilt=tilt,\n    ground_albedo=albedo,\n    surface_pressure=pressure,\n    relative_airmass=relative_airmass,\n    precipitable_water=water_vapor_content,\n    ozone=ozone,\n    aerosol_turbidity_500nm=tau500,\n)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The ``poa_global`` array represents the total spectral irradiance on our\nhypothetical solar panel. Let's plot it against wavelength to recreate\nFigure 5-1A:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "plt.figure()\nplt.plot(spectra['wavelength'], spectra['poa_global'])\nplt.xlim(200, 2700)\nplt.ylim(0, 1.8)\nplt.title(r\"Day 80 1984, $\\tau=0.1$, Wv=0.5 cm\")\nplt.ylabel(r\"Irradiance ($W m^{-2} nm^{-1}$)\")\nplt.xlabel(r\"Wavelength ($nm$)\")\ntime_labels = times.strftime(\"%H:%M %p\")\nlabels = [\n    \"AM {:0.02f}, Z{:0.02f}, {}\".format(*vals)\n    for vals in zip(relative_airmass, solpos.apparent_zenith, time_labels)\n]\nplt.legend(labels)\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Note that the airmass and zenith values do not exactly match the values in\nthe technical report; this is because airmass is estimated from solar\nposition and the solar position calculation in the technical report does not\nexactly match the one used here.  However, the differences are minor enough\nto not materially change the spectra.\n\n"
      ]
    }
  ],
  "metadata": {
    "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.7.9"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}