diff --git a/docs/source/_autosummary/pvdeg.degradation.deg.rst b/docs/source/_autosummary/pvdeg.degradation.deg.rst new file mode 100644 index 00000000..406abe21 --- /dev/null +++ b/docs/source/_autosummary/pvdeg.degradation.deg.rst @@ -0,0 +1,6 @@ +pvdeg.degradation.deg +===================== + +.. currentmodule:: pvdeg.degradation + +.. autofunction:: deg \ No newline at end of file diff --git a/docs/source/_autosummary/pvdeg.degradation.rst b/docs/source/_autosummary/pvdeg.degradation.rst index 9e2e6ca6..26847b1f 100644 --- a/docs/source/_autosummary/pvdeg.degradation.rst +++ b/docs/source/_autosummary/pvdeg.degradation.rst @@ -22,6 +22,7 @@ pvdeg.degradation pvdeg.degradation.IwaArrhenius pvdeg.degradation.IwaVantHoff pvdeg.degradation.arrhenius_deg + pvdeg.degradation.deg pvdeg.degradation.degradation pvdeg.degradation.vantHoff_deg pvdeg.degradation.vecArrhenius @@ -61,6 +62,13 @@ pvdeg.degradation .. minigallery:: pvdeg.degradation.arrhenius_deg :add-heading: + .. autofunction:: deg + + .. _sphx_glr_backref_pvdeg.degradation.deg: + + .. minigallery:: pvdeg.degradation.deg + :add-heading: + .. autofunction:: degradation .. _sphx_glr_backref_pvdeg.degradation.degradation: diff --git a/docs/source/_autosummary/pvdeg.diffusion.esdiffusion.rst b/docs/source/_autosummary/pvdeg.diffusion.esdiffusion.rst new file mode 100644 index 00000000..3a3b7bce --- /dev/null +++ b/docs/source/_autosummary/pvdeg.diffusion.esdiffusion.rst @@ -0,0 +1,6 @@ +pvdeg.diffusion.esdiffusion +=========================== + +.. currentmodule:: pvdeg.diffusion + +.. autofunction:: esdiffusion \ No newline at end of file diff --git a/docs/source/_autosummary/pvdeg.geospatial.can_auto_template.rst b/docs/source/_autosummary/pvdeg.geospatial.can_auto_template.rst new file mode 100644 index 00000000..dfce6002 --- /dev/null +++ b/docs/source/_autosummary/pvdeg.geospatial.can_auto_template.rst @@ -0,0 +1,6 @@ +pvdeg.geospatial.can\_auto\_template +==================================== + +.. currentmodule:: pvdeg.geospatial + +.. autofunction:: can_auto_template \ No newline at end of file diff --git a/docs/source/_autosummary/pvdeg.geospatial.rst b/docs/source/_autosummary/pvdeg.geospatial.rst index 159523fc..7c5970fc 100644 --- a/docs/source/_autosummary/pvdeg.geospatial.rst +++ b/docs/source/_autosummary/pvdeg.geospatial.rst @@ -24,6 +24,7 @@ pvdeg.geospatial pvdeg.geospatial.auto_template pvdeg.geospatial.calc_block pvdeg.geospatial.calc_gid + pvdeg.geospatial.can_auto_template pvdeg.geospatial.elevation_stochastic_downselect pvdeg.geospatial.feature_downselect pvdeg.geospatial.identify_mountains_radii @@ -88,6 +89,13 @@ pvdeg.geospatial .. minigallery:: pvdeg.geospatial.calc_gid :add-heading: + .. autofunction:: can_auto_template + + .. _sphx_glr_backref_pvdeg.geospatial.can_auto_template: + + .. minigallery:: pvdeg.geospatial.can_auto_template + :add-heading: + .. autofunction:: elevation_stochastic_downselect .. _sphx_glr_backref_pvdeg.geospatial.elevation_stochastic_downselect: diff --git a/docs/source/_autosummary/pvdeg.spectral.calc_full_from_irradiance_340.rst b/docs/source/_autosummary/pvdeg.spectral.calc_full_from_irradiance_340.rst new file mode 100644 index 00000000..bd06f360 --- /dev/null +++ b/docs/source/_autosummary/pvdeg.spectral.calc_full_from_irradiance_340.rst @@ -0,0 +1,6 @@ +pvdeg.spectral.calc\_full\_from\_irradiance\_340 +================================================ + +.. currentmodule:: pvdeg.spectral + +.. autofunction:: calc_full_from_irradiance_340 \ No newline at end of file diff --git a/docs/source/_autosummary/pvdeg.temperature.fdm_temperature_irradiance.rst b/docs/source/_autosummary/pvdeg.temperature.fdm_temperature_irradiance.rst new file mode 100644 index 00000000..e4157f4c --- /dev/null +++ b/docs/source/_autosummary/pvdeg.temperature.fdm_temperature_irradiance.rst @@ -0,0 +1,6 @@ +pvdeg.temperature.fdm\_temperature\_irradiance +============================================== + +.. currentmodule:: pvdeg.temperature + +.. autofunction:: fdm_temperature_irradiance \ No newline at end of file diff --git a/docs/source/_static/PVDeg-Flow.svg b/docs/source/_static/PVDeg-Flow.svg new file mode 100644 index 00000000..935de386 --- /dev/null +++ b/docs/source/_static/PVDeg-Flow.svg @@ -0,0 +1,10 @@ + + + + + + + + NSRDBPVGISResultsSatellite Data \ No newline at end of file diff --git a/docs/source/_static/logo-vectors/PVdeg-Logo-Black.svg b/docs/source/_static/logo-vectors/PVdeg-Logo-Black.svg new file mode 100644 index 00000000..60087393 --- /dev/null +++ b/docs/source/_static/logo-vectors/PVdeg-Logo-Black.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/source/_static/logo-vectors/PVdeg-Logo-Color.svg b/docs/source/_static/logo-vectors/PVdeg-Logo-Color.svg new file mode 100644 index 00000000..d082f0c3 --- /dev/null +++ b/docs/source/_static/logo-vectors/PVdeg-Logo-Color.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/source/_static/logo-vectors/PVdeg-Logo-Horiz-Color.svg b/docs/source/_static/logo-vectors/PVdeg-Logo-Horiz-Color.svg new file mode 100644 index 00000000..cb6121a9 --- /dev/null +++ b/docs/source/_static/logo-vectors/PVdeg-Logo-Horiz-Color.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/source/_static/logo-vectors/PVdeg-Logo-Horiz-black.svg b/docs/source/_static/logo-vectors/PVdeg-Logo-Horiz-black.svg new file mode 100644 index 00000000..ab3b6480 --- /dev/null +++ b/docs/source/_static/logo-vectors/PVdeg-Logo-Horiz-black.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/source/_static/logo-vectors/PVdeg-Logo-Horiz-white.svg b/docs/source/_static/logo-vectors/PVdeg-Logo-Horiz-white.svg new file mode 100644 index 00000000..22d61d60 --- /dev/null +++ b/docs/source/_static/logo-vectors/PVdeg-Logo-Horiz-white.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/source/_static/logo-vectors/PVdeg-Logo-White.svg b/docs/source/_static/logo-vectors/PVdeg-Logo-White.svg new file mode 100644 index 00000000..cc795b30 --- /dev/null +++ b/docs/source/_static/logo-vectors/PVdeg-Logo-White.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/source/_static/pvdeg.ico b/docs/source/_static/pvdeg.ico new file mode 100644 index 00000000..f36d3275 Binary files /dev/null and b/docs/source/_static/pvdeg.ico differ diff --git a/docs/source/conf.py b/docs/source/conf.py index 680216c2..f07206d5 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -147,12 +147,12 @@ # The name of an image file (relative to this directory) to place at the top # of the sidebar. -html_logo = "../../tutorials_and_tools/pvdeg_logo.png" # logo should work at this path +html_logo = "./_static/logo-vectors/PVdeg-Logo-Horiz-Color.svg" # logo should work at this path # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -# html_favicon = None +html_favicon = "./_static/pvdeg.ico" html_static_path = ["_static"] diff --git a/docs/source/index.rst b/docs/source/index.rst index f9786b8d..5eef84de 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,9 +3,10 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -.. image:: ../../tutorials_and_tools/pvdeg_logo.png - :width: 500 +.. .. image:: ../../tutorials_and_tools/pvdeg_logo.png +.. :width: 500 +.. image:: ./_static/logo-vectors/PVdeg-Logo-Horiz-Color.svg Welcome to pvdeg! @@ -25,35 +26,44 @@ relative humidity in the outside, front and back encapsulant and backsheet, spectral degradation, and solder fatigue. More functions for standards and other degradation profiles are in the works. -The source code for pvdeg is hosted on `github -`_. +The source code for pvdeg is hosted on `github `_. Please see the :ref:`installation` page for installation help. See :ref:`tutorials` to learn how to use and experiment with various functionalities -Please see the :ref:`installation` page for installation help. + +.. image:: ./_static/PVDeg-Flow.svg + :alt: PVDeg-Flow diagram. + How the Model Works =================== Coupled with pvlib for module performan and weather/irradiance calculations, -the PVDegradation Tool estimates degradations, and accelerated factors on +PVDegradation Tool estimates degradations, and accelerated factors on user-defined parameters. The `Data Library` is under development as part of the PVDegradationTool project, compiling literature parameters and functions. The PVDegradationTool simulatineously reads tens of terabytes of time-series solar data from state-of-art resource data set National Solar Radiation Database -(NSRDB), publicly avialable no the cloud, enabling the execution of pvdeg +(NSRDB), publicly available on the cloud, enabling the execution of pvdeg beyond the confines of NREL's high-performance computing capabilities. - Citing PVDegradation Tools ========================== If you use this calculator in a published work, please cite: +.. code-block:: + + Holsapple, Derek, Ayala Pelaez, Silvana, Kempe, Michael. "PV Degradation Tools", NREL Github 2020, Software Record SWR-20-71. + Please also cite the DOI corresponding to the specific version that you used. -DOIs are listed at Zenodo.org +DOIs are listed at Zenodo.org. `linked here `_ + +.. code-block:: + + Martin Springer, Tobin Ford, Matt, MDKempe, Silvana Ovaitt, AidanWesley, joe karas, Mark Campanelli, Derek M Holsapple, and Kevin Anderson. “NREL/PVDegradationTools: 0.4.2.” Zenodo, 2024. doi:10.5281/zenodo.13760911. .. toctree:: diff --git a/docs/source/user_guide/geospatial-details/ds_res-gid-shape.svg b/docs/source/user_guide/geospatial-details/ds_res-gid-shape.svg new file mode 100644 index 00000000..61bf52fe --- /dev/null +++ b/docs/source/user_guide/geospatial-details/ds_res-gid-shape.svg @@ -0,0 +1,10 @@ + + + + + + + + LatitudeLongitudeds_res \ No newline at end of file diff --git a/docs/source/user_guide/geospatial-details/ds_res-gid-time-shape.svg b/docs/source/user_guide/geospatial-details/ds_res-gid-time-shape.svg new file mode 100644 index 00000000..a6e6f75a --- /dev/null +++ b/docs/source/user_guide/geospatial-details/ds_res-gid-time-shape.svg @@ -0,0 +1,10 @@ + + + + + + + + LatitudeLongitudeTimeds_res \ No newline at end of file diff --git a/docs/source/user_guide/geospatial-details/geospatial-analysis-horizontal.svg b/docs/source/user_guide/geospatial-details/geospatial-analysis-horizontal.svg new file mode 100644 index 00000000..5ad8e5c5 --- /dev/null +++ b/docs/source/user_guide/geospatial-details/geospatial-analysis-horizontal.svg @@ -0,0 +1,10 @@ + + + + + + + + LatitudeLongitudeTimeTimeLocation IDgeospatial.analysisweather_dsLocation IDmeta_dfds_res \ No newline at end of file diff --git a/docs/source/user_guide/geospatial-details/geospatial-analysis-vertical.svg b/docs/source/user_guide/geospatial-details/geospatial-analysis-vertical.svg new file mode 100644 index 00000000..8f7f82df --- /dev/null +++ b/docs/source/user_guide/geospatial-details/geospatial-analysis-vertical.svg @@ -0,0 +1,10 @@ + + + + + + + + LatitudeLongitudeTimeTimeLocation IDgeospatial.analysisweather_dsLocation IDmeta_df \ No newline at end of file diff --git a/docs/source/user_guide/geospatial-details/geospatial-analysis.svg b/docs/source/user_guide/geospatial-details/geospatial-analysis.svg new file mode 100644 index 00000000..c46a4f80 --- /dev/null +++ b/docs/source/user_guide/geospatial-details/geospatial-analysis.svg @@ -0,0 +1,10 @@ + + + + + + + + LatitudeLongitudeTimeTimeLocation IDgeospatial.analysis \ No newline at end of file diff --git a/docs/source/user_guide/geospatial-details/meta_df.svg b/docs/source/user_guide/geospatial-details/meta_df.svg new file mode 100644 index 00000000..3616b0f6 --- /dev/null +++ b/docs/source/user_guide/geospatial-details/meta_df.svg @@ -0,0 +1,10 @@ + + + + + + + + Location IDmeta_dfsingle location meta_dict \ No newline at end of file diff --git a/docs/source/user_guide/geospatial-details/multi-dimensional-outputs.svg b/docs/source/user_guide/geospatial-details/multi-dimensional-outputs.svg new file mode 100644 index 00000000..a03a2138 --- /dev/null +++ b/docs/source/user_guide/geospatial-details/multi-dimensional-outputs.svg @@ -0,0 +1,10 @@ + + + + + + + + LatitudeLongitudeTimeds_resLatitudeLongitudeds_resTimeLocation IDweather_dsLocation IDmeta_dfgeospatial.analysisoutput is template/function dependent \ No newline at end of file diff --git a/docs/source/user_guide/geospatial-details/weatherCube.svg b/docs/source/user_guide/geospatial-details/weatherCube.svg new file mode 100644 index 00000000..31954545 --- /dev/null +++ b/docs/source/user_guide/geospatial-details/weatherCube.svg @@ -0,0 +1,10 @@ + + + + + + + + LatitudeLongitudeTime \ No newline at end of file diff --git a/docs/source/user_guide/geospatial-details/weatherSheet.svg b/docs/source/user_guide/geospatial-details/weatherSheet.svg new file mode 100644 index 00000000..a494e827 --- /dev/null +++ b/docs/source/user_guide/geospatial-details/weatherSheet.svg @@ -0,0 +1,10 @@ + + + + + + + + Location IDTime \ No newline at end of file diff --git a/docs/source/user_guide/geospatial-details/weather_ds.svg b/docs/source/user_guide/geospatial-details/weather_ds.svg new file mode 100644 index 00000000..952b465f --- /dev/null +++ b/docs/source/user_guide/geospatial-details/weather_ds.svg @@ -0,0 +1,10 @@ + + + + + + + + TimeLocation IDweather_dssingle location weather_df \ No newline at end of file diff --git a/docs/source/user_guide/geospatial-templates.rst b/docs/source/user_guide/geospatial-templates.rst deleted file mode 100644 index c19dead2..00000000 --- a/docs/source/user_guide/geospatial-templates.rst +++ /dev/null @@ -1,40 +0,0 @@ -.. _geospatial-templates: - -Geospatial Templates -=================== -Using 3 dimensional labeled arrays (`Xarray`) we are able to run calculations using meteorological data across many points at once. This process has been parallelized using `dask` and `xarray`. Both of these packages can be run locally or on cloud HPC environments. - -This presents a new issue, our models produce outputs in many different shapes and sizes. We can have single numerical results, multiple numeric results or a timeseries of numeric results at each location. To parallelize this process, we cannot wait until runtime to know what shape to store the outputs in. This is where the need for `templates` arises. - -Previously, ``pvdeg.geospatial`` provided minimal templates and forced users to create their own for each function they wanted to use in a geospatial calculation. - -Auto-templating: allows users to skip creating templates for most functions within pvdeg by using ``pvdeg.geospatial.autotemplate`` to generate templates on the spot, instead of figuring out the output shape. For any given function within the source code decorated with `geospatial_result_type`, we can use `pvdeg.geospatial.autotemplate` - - -Example --------- - -Here we are providing a function to autotemplate along with an ``Xarray.Dataset`` of weather data. Combining these two will give us enough information to produce an output template. - -Autotemplate approach to creating a template - -.. code-block:: Python - - edge_seal_template = pvdeg.geospatial.auto_template( - func=pvdeg.design.edge_seal_width, - ds_gids=geo_weather - ) - -Manual Approach to Creating the Sample Template - -.. code-block:: Python - - shapes = { - "width" : ("gid",) # one return value at each datapoint, only dependent on datapoint, not time - } - - template = pvdeg.geospatial.output_template( - ds_gids=geo_weather, # xarray dataset - shapes=shapes, # output shapes - ) - diff --git a/docs/source/user_guide/geospatial.rst b/docs/source/user_guide/geospatial.rst new file mode 100644 index 00000000..43f86846 --- /dev/null +++ b/docs/source/user_guide/geospatial.rst @@ -0,0 +1,305 @@ +.. _geospatial: + +Geospatial +========== + +Geospatial data is time based data that maps to a location on Earth. PVDeg supports single site and geospatial analyses using meteorological and solar radiation data, +such as Typical meteorological year (TMY) data. This can be used to extrapolate the perfomance of PV systems over many years beacause it is statistically representative of +weather conditions given a typical year. PVDeg collects an arbitrary amount of location specific meteorological and solar radiation data to run geospatial analyses. + +These datasets are multidimensional, with time and location as coordinates. These data come from :ref:`NSRDB` and :ref:`PVGIS` and can commonly be expressed in two ways. + +- three dimensions as a cube with coordinates ``time``, ``latitude``, and ``longitude``. +- two dimensions as a sheet with coordinates ``time``, and ``location id`` (often represented as gid). Gid is a geospatial id, these are problematic and largely meaningless, see :ref:`GIDS`. + +.. image:: geospatial-details/weatherCube.svg + :width: 65% + :alt: multidimensional Meterological Solar Radiation data represented with dimensions time, latitude and longitude. + +.. image:: geospatial-details/weatherSheet.svg + :width: 50% + :alt: multidimensional Meterological Solar Radiation data represented with dimensions time, location id + +*The orange 3d shape and 2d band represent a single location's data, in the corresponding representation. This can be weather and solar radiation or other calculated results.* + + +Geospatial Analysis +------------------- + +To develop some intuition about what ``geospatial.analysis`` is doing lets examine the docstring. It says "applies a function to each gid of a weather dataset". +This is a very simple message but it is not clear how this works at a cursory look. This is a powerful paradigm. + +The most consequential part of the function is the mapping from the inputs to the output. The input and outputs are multi-dimensional and have a different number of dimensions. + +*The specific function applied is not relevant at this point, it does change the data-variable results in the multi-dimensional output but this is a different aspect of the analysis function.* +This is explained in `Geospatial Templates`_ + +.. autofunction:: pvdeg.geospatial.analysis + +Multi-dimensional inputs +^^^^^^^^^^^^^^^^^^^^^^^^ +- ``weather_ds`` is an ``xarray.Dataset`` with coordinates/dimensions of ``time`` and ``gid``. +- ``meta_df`` is a ``pandas.DataFrame`` consisting of a row of data, extracting a single row yeilds a dictionary with metadata attributes for the specific location. + +Looking at ``weather_ds``, we generally want to get one of the tall rectangles shown in the figure. To do this we only need to index by ``gid``. +This will get a "slice" that contains all of the weather data for that location for the length of the dataset (usually 1 year). +This slice is roughly equivalent to the weather ``pandas.DataFrame`` taken by ``pvdeg`` functions called ``weather_df``. + +.. image:: geospatial-details/weather_ds.svg + :width: 50% + :alt: + +Looking at ``meta_df``, we want one of the wide rectangles shown in the figure. The dataframe is indexed by ``gid`` so we only need to index by a single ``gid``. +This will get a "row" that contains the gid's meta data, such as latitude, longitude, time zone, and elevation/altitude. +This can be unpacked to the standard python dictionary (``dict``) taken by ``pvdeg`` functions called ``meta_dict``. + +.. image:: geospatial-details/meta_df.svg + :width: 50% + :alt: + +In this context, gids serve purely as indexes, gid a in ``weather_ds`` coresponds to index a in ``meta_df``. No other information can be reliabily derived from gids. + +Multi-dimensional output +^^^^^^^^^^^^^^^^^^^^^^^^ + +- ``ds_res`` is a ``xarray.Dataset`` with coordinates/dimensions of ``time``, ``latitude``, and ``longitude`` or simply ``latitude`` and ``longitude`` as shown below. + +Notice, ``ds_res`` is a multi-dimensional result similar to the inputs but it's shape can vary. The two standard appearances of ``ds_res`` are shown stacked on the right side of the figure below. + +The shape ``ds_res`` takes is determined by the provided function and template, ``func`` and ``template`` respectively. Oftentimes, ``template`` is not required because ``pvdeg`` +can automatically generate simple templates for commonly used builtin functions. + +When a function returns a timeseries result then the result will look like the cube version of ``ds_res`` with a time axis shown below. +If the function returns single numeric results such as averages of a timeseries value then there is no need for a ``time`` axis. So the result will look like the plane version of ``ds_res`` shown below. +For more on this see `Geospatial Templates`_. + + +.. image:: geospatial-details/multi-dimensional-outputs.svg + :width: 100% + :alt: + + +.. _GeospatialTemplates: +Geospatial Templates +--------------------- +Using multi-dimensional labeled arrays (``Xarray``) we are able to run calculations using meteorological data across many points at once. This process has been parallelized using `dask` and `xarray`. Both of these packages can be run locally or on cloud HPC environments. + +This presents a new issue, our models produce outputs in many different shapes and sizes. We can have single numerical results, multiple numeric results or a timeseries of numeric results at each location. To parallelize this process, we cannot wait until runtime to know what shape to store the outputs in. This is where the need for `templates` arises. + +Previously, ``pvdeg.geospatial`` provided minimal templates and forced users to create their own for each function they wanted to use in a geospatial calculation. This is still an option via ``geospatial.output_template``. +But many pvdeg functions do not require a template for geospatial analysis. + +Auto-templating: allows users to skip creating templates for most ``pvdeg`` functions. +It is integrated into ``geospatial.analysis``. If a function is defined with the ``@geospatial_quick_shape`` decorator in the source code, we can call ``geospatial.analysis`` without providing a template. +The function responsible for this is called ``geospatial.auto_template`` and is exposed publicly to create templates outside of ``geospatial.analysis``. + +If a function cannot be auto-templated, both ``geospatial.analysis`` and ``geospatial.auto_template`` will raise the following error. + +.. code-block:: Python + + " cannot be autotemplated. create a template manually" + +Auto-templating Example +----------------------- + +The code below shows how to use auto-templating on a function implicitly. We simply call ``geospatial.analysis`` on a function that can be auto-templated and ``geospatial.analysis`` does the work for us. +Note: *we do not need to provide a template to "analysis" if the function can be auto-templated* + +.. code-block:: Python + + geo_res = pvdeg.geospatial.analysis( + weather_ds = geo_weather, + meta_df = geo_meta, + func = pvdeg.design.edge_seal_width, + ) + +The code below shows the auto-templating process as the section above but this time we will explicitly call ``geospatial.auto_template`` and pass the generated template to ``geospatial.analysis``. +The approach above is more direct and thus preferable. + +.. code-block:: Python + + edge_seal_template = pvdeg.geospatial.auto_template( + func=pvdeg.design.edge_seal_width, + ds_gids=geo_weather + ) + + geo_res = pvdeg.geospatial.analysis( + weather_ds = geo_weather, + meta_df = geo_meta, + func = pvdeg.design.edge_seal_width, + template = edge_seal_template, + ) + + + +Manual Templating Example I +--------------------- + +Creating manual templates is one of the most complicated parts of ``pvdeg``. We will use ``geospatial.output_template`` to tell ``pvdeg`` how to go from the multi-dimensional inputs to a multi-dimensional output. +We have do to this because the dimensions are chaning. Refer to the sketch in `Multi-dimensional output`_. + +Lets examine some functions, comprehensive examples are the best way to illustrate this process. + +We will start by creating templates for functions that support auto-templating. If you run the code below or use the auto-templating approches shown above, the result will be identical. + +A simple function that has auto-templating is ``pvdeg.standards.standoff``. The docstring is shown below. + +.. autofunction:: pvdeg.standards.standoff + +We can see that this will return single numeric outputs for various aspects of standoff height calculation for each location. We want the output to rely only on the input location. +This is identified with an index, ``gid``. Since we have single numeric outputs, we do not want a time dimension. Borrowing from above, a simple sketch of the analysis output should look like the following. + +.. image:: geospatial-details/ds_res-gid-shape.svg + :width: 100% + :alt: + +The crux of this process is defining the shapes dictionary. As presented above, we only care about the ``gid`` axis on the input so the process for creating a template and running the analysis with it will be as follows. +The keys in the dictionary are named after the return values of the desired function. See the docstring for evidence of this. The values is a tuple of the dimensions that we map to in the output. + +.. code-block:: Python + + shapes = { + "x": ("gid",), + "T98_inf": ("gid",), + "T98_0": ("gid",), + } + +*Note: the tuples appear with a comma after the string, such that ("gid",) NOT ("gid"). This is because python will interpret the string as an group of characters to unpack if we do not +enforce the tuple requirement. Adding a comma forces python to interpret the parenthesis as a tuple* + +Next, we will create a template using this shapes dictionary and the ``weather_ds``. The parameters may be misleadly named as ``ds_gids`` but this is the same as ``weather_ds`` in ``geospatial.analysis``. + +``geo_weather`` and ``geo_meta`` are placeholders for the geospatial weather and metadata that we would generally have in this scenario. It is not possible to generate an output template without providing the +geospatial weather data beacause the function needs to know how many entries it needs to make along the ``gid`` axis in this case. + +.. code-block:: Python + + standoff_template = pvdeg.geospatial.output_template( + ds_gids=geo_weather, # geospatial xarray dataset + shapes=shapes, # output shapes defined above + ) + + geo_res = pvdeg.geospatial.analysis( + weather_ds = geo_weather, # geospatial xarray dataset + meta_df = geo_meta, # geospatial metadata dataframe + func = pvdeg.standards.standoff, + template = standoff_template # template created in this example + ) + + +Manual Templating Example II +----------------------------- +Another function we can look at that supports auto-templating is ``pvdeg.humidity.module``. This calculates module humidity parameters over a timeseries. This is where we diverge from the previous example. +Inspect the docstring below and look at the return types, notice this will be a timeseries result. + +.. autofunction:: pvdeg.humidity.module + +Now we will define the shapes dictionary, the output will be a mapping from the input dimensions of ``gid`` and ``time`` so both of these will appear in our ``shapes`` value tuples. +Thus our output will have a time axis and show look like the ``ds_res`` as a cube with the time axis as shown below. + +.. image:: geospatial-details/ds_res-gid-time-shape.svg + :width: 100% + :alt: + +This is an oversimplification but each column in the cube represets a ``pandas.DataFrame`` result with columns represeting each return value and a ``pd.DatetimeIndex``. The columns will be named as follows. + +- "RH_surface_outside" +- "RH_front_encap" +- "RH_back_encap" +- "RH_backsheet" + +The docstring does not give us that much useful information about the results so we can run it on a single location and get the column names or dict keys then these will become our shape names. +This is not ideal but simply running at a single site before a geospatial calculation can yield useful context. ``geospatial.analysis`` error messages are oftentimes clear. +This is a result of dask, lazy-computing and confusing higher dimensional datasets. + +.. code-block:: Python + + shapes = { + "RH_surface_outside": ("gid", "time"), + "RH_front_encap": ("gid", "time"), + "RH_back_encap": ("gid", "time"), + "RH_backsheet": ("gid", "time"), + } + +This shapes dictionary is valid, so we can pass it to ``geospatial.output_template`` as in the above example and run the analysis. + +.. code-block:: Python + + module_humidity_template = pvdeg.geospatial.output_template( + ds_gids=geo_weather, # geospatial xarray dataset + shapes=shapes, # output shapes defined above + ) + + geo_res = pvdeg.geospatial.analysis( + weather_ds = geo_weather, # geospatial xarray dataset + meta_df = geo_meta, # geospatial metadata dataframe + func = pvdeg.module.humidity, + template = module_humidity_template # template created in this example + ) + + +Manual Templating Example III +----------------------------- +Last, lets look at another example. This one will be abridged as it covers the same topic as `Manual Templating Example II`_. + +This time consider ``pvdeg.letid.calc_letid_outdoors``. Lets inspect the docstring to see what the return values look like. + +.. autofunction:: pvdeg.letid.calc_letid_outdoors + +Once again we can see that the output shapes are obscured. It just says we are returning a ``pandas.DataFrame`` called timesteps. This is not helpful. +We will have to run the function at a single location to see what the column names are. + +Assuming we ran ``pvdeg.letid.calc_letid_outdoors`` at a single site we would see that the DataFrame columns are named as follows. + +- "Temperature" +- "Injection" +- "NA" +- "NB" +- "NC" +- "tau" +- "Jsc" +- "Voc" +- "Isc" +- "FF" +- "Pmp" +- "Pmp_norm" + +.. image:: geospatial-details/ds_res-gid-time-shape.svg + :width: 100% + :alt: + +Because we know the function returns a ``pandas.DataFrame`` with a time index, all of the columns will have entries at each timestep. This means that we need to include, the ``time`` dimension in our output. +The shapes dictionary will look like the following. For visual assistance, refer to the cube shaped ``ds_res`` sketch. + +.. code-block:: Python + + shapes = { + "Temperature": ("gid", "time"), + "Injection": ("gid", "time"), + "NA": ("gid", "time"), + "NB": ("gid", "time"), + "NC": ("gid", "time"), + "tau": ("gid", "time"), + "Jsc": ("gid", "time"), + "Voc": ("gid", "time"), + "Isc": ("gid", "time"), + "FF": ("gid", "time"), + "Pmp": ("gid", "time"), + "Pmp_norm": ("gid", "time"), + } + +Now we have defined shapes, as above we can simply pass it to ``geospatial.output_template`` and use the generated template in our analysis. + +.. code-block:: Python + + letid_template = pvdeg.geospatial.output_template( + ds_gids=geo_weather, # geospatial xarray dataset + shapes=shapes, # output shapes defined above + ) + + geo_res = pvdeg.geospatial.analysis( + weather_ds = geo_weather, # geospatial xarray dataset + meta_df = geo_meta, # geospatial metadata dataframe + func = pvdeg.letid.calc_letid_outdoors + template = letid_template # template created in this example + ) \ No newline at end of file diff --git a/docs/source/user_guide/index.rst b/docs/source/user_guide/index.rst index 9a09bb48..d4cf0d18 100644 --- a/docs/source/user_guide/index.rst +++ b/docs/source/user_guide/index.rst @@ -8,9 +8,11 @@ User Guide installation package_overview + meteorological-data NSRDB_API_Key montecarlo - geospatial-templates + geospatial + materials pv-variables-terms chamber_setpoints contributing diff --git a/docs/source/user_guide/materials.rst b/docs/source/user_guide/materials.rst new file mode 100644 index 00000000..c81fa0e8 --- /dev/null +++ b/docs/source/user_guide/materials.rst @@ -0,0 +1,107 @@ +.. materials:: + +Materials Storage and Access +============================ + +PVDeg contains a library of material parameters suitable for estimating the durability of materials and components. + + +These material parameters and other relevant information sit in a directiory at ``PVDegradationTools/pvdeg/data``. + +This location can be quickly accessed through a special variable as shown below. + +.. code-block:: Python + + import pvdeg + + file_path = os.path.join(pvdeg.DATA_DIR, ) + +.. code-block:: Python + + from pvdeg import DATA_DIR + + file_path = os.path.join(DATA_DIR, ) + +File Organization +------------------------------------ +There are many files in this directory. We will generally be interested in one of the following files. + + +- `AApermeation.json `_ (acetic acid permeation parameters) +- `H2Opermeation.json `_ (water permeation parameters) +- `O2permeation.json `_ (oxygen permeation parameters) +- kinetic_parameters.json (letid/bolid parameters) +- DegradationDatabase.json (degredation models) + +Material Parameters +------------------------------------ +Each of the material permeation parameters files above is a json indexed by arbitrary names. +These are not a mapping of material names or aliases and are not consistent across the three files below. + +- `AApermeation.json `_ (acetic acid permeation parameters) +- `H2Opermeation.json `_ (water permeation parameters) +- `O2permeation.json `_ (oxygen permeation parameters) + +Accessing Material Parameters +----------------------------- + +PVDeg provides convenience methods/functions to access material parameters. ``pvdeg.utilities.read_material`` is the simplest way to access material parameters. We will also show a sample use. + +.. autofunction:: pvdeg.utilities.read_material + +.. code-block:: Python + + material_dict = pvdeg.utilities.read_material( + pvdeg_file = "AApermeation", + key = "AA001", + ) + +.. code-block:: Python + + material_dict = pvdeg.utilities.read_material( + pvdeg_file = "H2Opermeation", + key = "W003", + ) + + +The result of both of these functions will be a dictionary that looks like the following. The keys may vary depending on the structure of the json but this is the general idea. + +.. code-block:: Python + + { + "name": string, + "alias": string, + "contributor": string, + "source": string, + "Fickian": bool, + "Ead": numeric, + "Do": numeric, + "Eas": numeric, + "So": numeric, + "Eap": numeric, + "Po": numeric + } + +There are also convenience functions to view and search jsons in jupyter notebooks called ``pvdeg.utilities.display_json`` and ``pvdeg.utilities.search_json``. + + +.. _AApermeation: + +AApermeation +~~~~~~~~~~~~ +.. literalinclude:: ../../../pvdeg/data/AApermeation.json + :language: json + +.. _H2Opermeation: + +H2Opermeation +~~~~~~~~~~~~ +.. literalinclude:: ../../../pvdeg/data/H2Opermeation.json + :language: json + +.. _O2permeation: + +O2permeation +~~~~~~~~~~~~ +.. literalinclude:: ../../../pvdeg/data/O2permeation.json + :language: json \ No newline at end of file diff --git a/docs/source/user_guide/meteorological-data-details/data_flow_chart.png b/docs/source/user_guide/meteorological-data-details/data_flow_chart.png new file mode 100644 index 00000000..7b19bd4e Binary files /dev/null and b/docs/source/user_guide/meteorological-data-details/data_flow_chart.png differ diff --git a/docs/source/user_guide/meteorological-data-details/nsrdb_global_coverage.jpg b/docs/source/user_guide/meteorological-data-details/nsrdb_global_coverage.jpg new file mode 100644 index 00000000..dee1cc68 Binary files /dev/null and b/docs/source/user_guide/meteorological-data-details/nsrdb_global_coverage.jpg differ diff --git a/docs/source/user_guide/meteorological-data.rst b/docs/source/user_guide/meteorological-data.rst new file mode 100644 index 00000000..6132a119 --- /dev/null +++ b/docs/source/user_guide/meteorological-data.rst @@ -0,0 +1,80 @@ +.. _meteorological-data: + +Meterological Data +================== + +PVDeg seeks to automate the tedious parts of degradation analysis by providing simple tools to work with weather data. +``pvdeg.weather.get`` seeks to unify this functionality into a simple function. + +The PVDeg tutorials and examples use two datasets, `NSRDB`_ and `PVGIS`_. These are serially complete data including meteorological data and solar radiation (irradiance) measurements. +The methodology for these datasets varies but both are gridded geospatial datasets with similar attributes. + +.. _NSRDB: +NSRDB +------ +The NSRDB is produced by NREL and combines multiple datasets but we are most concerned with `Physical Solar Model 3 (PSM3) `_. This data was generated using satellite data from multiple channels to derive cloud +and aerosol properties, then fed into a radiative transfer model. Learn more about the NSRDB `here `_. + +The NSRDB is free to use but requires an api-key and email. See :ref:`NSRDB_API_Key` for more information. +For our purposes, the api is limited to 1000 requests per day, although you can request a batch download via email with a singificantly higher rate limit (not recommended for PVDeg). + +Flowchart showing the dataflow from satellite to solar radiation measurement. + +.. image:: meteorological-data-details/data_flow_chart.png + :alt: dataflow from satellite to solar radiation measurement, image missing + +``_ + +NSRDB data are seperated by satellite/model source. Each dataset is shown below, much of the PVDeg project uses the *Americas* data. + +.. image:: meteorological-data-details/nsrdb_global_coverage.jpg + :alt: NSRDB data sources, image missing + +``_ + + +.. _PVGIS: +PVGIS +------ +`PVGIS`_ is the European counterpart of the `NSRDB`_. The data was sourced similarly. With PVGIS we are most concerned with a `typical meteorological year `_. +PVDeg uses utilities built in `pvlib `_ to access the data. + +PVGIS is free to use and does NOT require an api-key. It has a rate limit of 30 requests per second and covers a much larger range of longitudes and latitudes. + +The PVDeg tutorials and examples use two datasets, `NSRDB`_ and `PVGIS`_. These are serially complete data including meteorological data and solar radiation (irradiance) measurements. +The methodology for these datasets varies but both are gridded geospatial datasets with similar attributes. + +PVGIS data are seperated by satellite/model source. Visit the links below for more information about the datasets. + +- `PVGIS 5.2 `_ +- `PVGIS 5.3 `_ + +.. _GIDS: +Issues with Gids +---------------- + +"Gids", plural or "gid" singular refer to a geospatial id. This is where the simplicity ends because gids are largely meaningless. + +When using ``pvdeg.weather.get`` to grab PVGIS data as follows. We will get a gid back but it will always be the same because PVGIS gids are meaningless. The gids created during this process only serve as indexes. + +.. code-block:: Python + + weather_df, meta_df = pvdeg.weather.get( + database="PVGIS", + id = (, ), + ) + + +When using the NSRDB PSM3 dataset, gids are unique only to their satellite. Because of this, gids can only be treated as unique if we can guarantee only one satellite source is being utilized. +This is possible but causes headaches. + +.. code-block:: Python + + weather_df, meta_df = pvdeg.weather.get( + database="PSM3", + id = (, ), + email = , + api_key = , + ) + +Takeaway: gids are not unique or necessarily meaningful, be careful when using them. Duplicate gids can exist in geospatial data and will be loaded using Xarray without raising an error. \ No newline at end of file diff --git a/docs/source/whatsnew/index.rst b/docs/source/whatsnew/index.rst index d5b2f041..84ec153a 100644 --- a/docs/source/whatsnew/index.rst +++ b/docs/source/whatsnew/index.rst @@ -4,6 +4,7 @@ What's New ========== PVDegradationTools (pvdeg) change log: +.. include:: releases/v0.4.5.rst .. include:: releases/v0.4.4.rst .. include:: releases/v0.4.3.rst .. include:: releases/v0.4.2.rst diff --git a/docs/source/whatsnew/releases/v0.4.2.rst b/docs/source/whatsnew/releases/v0.4.2.rst index d165d419..3b3fa6cb 100644 --- a/docs/source/whatsnew/releases/v0.4.2.rst +++ b/docs/source/whatsnew/releases/v0.4.2.rst @@ -4,11 +4,11 @@ v0.4.2 (2024-09-13) Bug Fixes --------- -* Remove duplicate gid's from `pvdeg.geospatial.elevation_stochastic_downselection` +* Remove duplicate gid's from ``pvdeg.geospatial.elevation_stochastic_downselection`` Tests ----- -* Added a test for Xmin in `test_standards.py` and removed dependency on pvgis. +* Added a test for Xmin in ``test_standards.py`` and removed dependency on pvgis. Contributors ~~~~~~~~~~~~ diff --git a/docs/source/whatsnew/releases/v0.4.3.rst b/docs/source/whatsnew/releases/v0.4.3.rst index 2b2691d1..aa789221 100644 --- a/docs/source/whatsnew/releases/v0.4.3.rst +++ b/docs/source/whatsnew/releases/v0.4.3.rst @@ -1,8 +1,10 @@ -v0.4.3 (2024-10-10) -=================== +v0.4.3 (2024-11-1) +======================= Enhancements ------------- +------------- +``pvdeg.geospatial.analysis`` implements autotemplating. No need to specify a template for common ``pvdeg`` functions during analysis. Manually creating and providing templates is still an option. Docstrings updated with examples. + Suite of utility functions to facilitate accessing material parameter json files. * ``pvdeg.utilities.read_material`` creates a public api to replace the private ``pvdeg.untility._read_material`` function (to be deprecated soon) diff --git a/docs/source/whatsnew/releases/v0.4.4.rst b/docs/source/whatsnew/releases/v0.4.4.rst index 2dddcb0e..6a12a891 100644 --- a/docs/source/whatsnew/releases/v0.4.4.rst +++ b/docs/source/whatsnew/releases/v0.4.4.rst @@ -1,5 +1,10 @@ -v0.4.0 (2024-08-02) -======================= + +Contributors +~~~~~~~~~~~~ +* Tobin Ford(:ghuser:`tobin-ford`) +======= +v0.4.4 (2024-11-19) +=================== Enhancements ------------ @@ -7,11 +12,14 @@ Enhancements * ``chamber`` provides a class ``Chamber`` to provide for streamlined stress test chamber conditions and test sample conditions. * ``diffusion`` provides a function ``diffusion.module_front`` to calculate solute diffusion into a host material. * Tutorial notebook: ``"Chamber Stressor.ipynb"`` +* Documenation overhaul. Significant ``User Guide`` improvements. Added geospatial information with visual aids, added meteorological data page and materials access page. +Suite of utility functions to facilitate accessing material parameter json files. +* New Logo! Documentation ------------- * Created page :ref:`chamber-setpoints` Contributors -~~~~~~~~~~~~ -* Tobin Ford(:ghuser:`tobin-ford`) \ No newline at end of file +----------- +* Tobin Ford (:ghuser:`tobin-ford`) diff --git a/docs/source/whatsnew/releases/v0.4.5.rst b/docs/source/whatsnew/releases/v0.4.5.rst new file mode 100644 index 00000000..43f32d47 --- /dev/null +++ b/docs/source/whatsnew/releases/v0.4.5.rst @@ -0,0 +1,45 @@ + +v0.4.5 (2024-12-11) +=================== + +Breaking Change +------------ +* Changed function signature of ``pvdeg.degradation.degradation``. + - New function takes ``spectra_df`` instead of ``spectra`` and ``wavelengths`` disparate arguments. + Also takes ``conditions_df`` instead of disparate ``rh_module`` and ``temp_module`` pandas series. + + spectra_df : pd.DataFrame + front or rear irradiance data in dataframe format + + - `data`: Spectral irradiance values for each wavelength [W/m^2/nm]. + - `index`: pd.DateTimeIndex + - `columns`: Wavelengths as floats (e.g., 280, 300, etc.) [nm]. + + Example:: + + timestamp 280 300 320 340 360 380 400 + 2021-03-09 10:00:00 0.6892 0.4022 0.6726 0.0268 0.3398 0.9432 0.7411 + 2021-03-09 11:00:00 0.1558 0.5464 0.6896 0.7828 0.5050 0.9336 0.4652 + 2021-03-09 12:00:00 0.2278 0.9057 0.2639 0.0572 0.9906 0.9370 0.1800 + 2021-03-09 13:00:00 0.3742 0.0358 0.4052 0.9578 0.1044 0.8917 0.4876 + + conditions_df : pd.DataFrame, optional + Environmental conditions including temperature and relative humidity. + + - `index`: pd.DateTimeIndex + - `columns`: (required) + - "temperature" [°C or K] + - "relative_humidity" [%] + + Example:: + + timestamp temperature relative_humidity + 2021-03-09 10:00:00 298.0 45.0 + 2021-03-09 11:00:00 303.0 50.0 + 2021-03-09 12:00:00 310.0 55.0 + 2021-03-09 13:00:00 315.0 60.0 + + +Contributors +----------- +* Tobin Ford (:ghuser:`tobin-ford`) \ No newline at end of file diff --git a/pvdeg/degradation.py b/pvdeg/degradation.py index 239e3517..cd8f0a4a 100644 --- a/pvdeg/degradation.py +++ b/pvdeg/degradation.py @@ -863,33 +863,70 @@ def _gJtoMJ(gJ): return MJ +# new version of degradation def degradation( - spectra: pd.Series, - rh_module: pd.Series, - temp_module: pd.Series, - wavelengths: Union[int, np.ndarray[float]], + spectra_df: pd.DataFrame, + conditions_df: pd.DataFrame = None, + temp_module: pd.Series = None, + rh_module: pd.Series = None, Ea: float = 40.0, n: float = 1.0, p: float = 0.5, C2: float = 0.07, C: float = 1.0, -) -> float: +)-> float: """ Compute degredation as double integral of Arrhenius (Activation Energy, RH, Temperature) and spectral (wavelength, irradiance) functions over wavelength and time. + .. math:: + + D = C \\int_{0}^{t} RH(t)^n \\cdot e^{\\frac{-E_a}{RT(t)}} \\int_{\\lambda} [e^{-C_2 \\lambda} \\cdot G(\\lambda, t)]^p d\\lambda dt + Parameters ---------- - spectra : pd.Series type=Float - front or rear irradiance at each wavelength in "wavelengths" [W/m^2 nm] - rh_module : pd.Series type=Float - module RH, time indexed [%] - temp_module : pd.Series type=Float - module temperature, time indexed [C] - wavelengths : int-array - integer array (or list) of wavelengths tested w/ uniform delta - in nanometers [nm] + spectra_df : pd.DataFrame + front or rear irradiance data in dataframe format + + - `data`: Spectral irradiance values for each wavelength [W/m^2 nm]. + - `index`: pd.DateTimeIndex + - `columns`: Wavelengths as floats (e.g., 280, 300, etc.) [nm]. + + Example:: + + timestamp 280 300 320 340 360 380 400 + 2021-03-09 10:00:00 0.6892 0.4022 0.6726 0.0268 0.3398 0.9432 0.7411 + 2021-03-09 11:00:00 0.1558 0.5464 0.6896 0.7828 0.5050 0.9336 0.4652 + 2021-03-09 12:00:00 0.2278 0.9057 0.2639 0.0572 0.9906 0.9370 0.1800 + 2021-03-09 13:00:00 0.3742 0.0358 0.4052 0.9578 0.1044 0.8917 0.4876 + + conditions_df : pd.DataFrame, optional + Environmental conditions including temperature and relative humidity. + + - `index`: pd.DateTimeIndex + - `columns`: (required) + - "temperature" [°K] + - "relative_humidity" [%] + + Example:: + + timestamp temperature relative_humidity + 2021-03-09 10:00:00 298.0 45.0 + 2021-03-09 11:00:00 301.0 50.0 + 2021-03-09 12:00:00 315.0 55.0 + 2021-03-09 13:00:00 150.0 60.0 + + temp_module : pd.Series, optional + Module temperatures [°K]. Required if `conditions_df` is not provided. Time indexed same as spectra_df + + rh_module : pd.Series, optional + Relative humidity values [%]. Required if `conditions_df` is not provided. Time indexed same as spectra_df + + Example:: + + 30 = 30% + Ea : float Arrhenius activation energy. The default is 40. [kJ/mol] n : float @@ -908,47 +945,66 @@ def degradation( ------- degradation : float Total degredation factor over time and wavelength. - """ - # --- TO DO --- - # unpack input-dataframe - # spectra = df['spectra'] - # temp_module = df['temp_module'] - # rh_module = df['rh_module'] - # Constants - R = 0.0083145 # Gas Constant in [kJ/mol*K] - wav_bin = list(np.diff(wavelengths)) - wav_bin.append(wav_bin[-1]) # Adding a bin for the last wavelength + if conditions_df is not None and (temp_module is not None or rh_module is not None): + raise ValueError("Provide either conditions_df or temp_module and rh_module") - # Integral over Wavelength - try: - irr = pd.DataFrame(spectra.tolist(), index=spectra.index) - irr.columns = wavelengths - except: - # TODO: Fix this except it works on some cases, veto it by cases - print("Removing brackets from spectral irradiance data") - # irr = data['spectra'].str.strip('[]').str.split(',', expand=True).astype(float) - irr = spectra.str.strip("[]").str.split(",", expand=True).astype(float) - irr.columns = wavelengths + if conditions_df is not None: + rh = conditions_df["relative_humidity"].values + temps = conditions_df["temperature"].values + else: + rh = rh_module.values + temps = temp_module.values + + wavelengths = spectra_df.columns.values.astype(float) + irr = spectra_df.values # irradiance as array + + # call numba compiled function + return deg( + wavelengths=wavelengths, + irr=irr, + rh=rh, + temps=temps, + Ea=Ea, + C2=C2, + p=p, + n=n, + C=C + ) - sensitivitywavelengths = np.exp(-C2 * wavelengths) - irr = irr * sensitivitywavelengths - irr *= np.array(wav_bin) - irr = irr**p - data = pd.DataFrame(index=spectra.index) - data["G_integral"] = irr.sum(axis=1) +@njit +def deg( + wavelengths: np.ndarray, + irr: np.ndarray, + rh: np.ndarray, + temps: np.ndarray, + Ea: float, + C2: float, + p: float, + n: float, + C: float +) -> float: - EApR = -Ea / R - C4 = np.exp(EApR / temp_module) + R = 0.0083145 # Gas Constant in [kJ/mol*K] - RHn = rh_module**n - data["Arr_integrand"] = C4 * RHn + wav_bin = np.diff(wavelengths) + wav_bin = np.append(wav_bin, wav_bin[-1]) # Extend last bin + + # inner integral + # wavelength d lambda + irr_weighted = irr * np.exp(-C2 * wavelengths) # weight irradiances + irr_weighted *= wav_bin + irr_pow = irr_weighted ** p + wavelength_integral = np.sum(irr_pow, axis=1) # sum over wavelengths - data["dD"] = data["G_integral"] * data["Arr_integrand"] + # outer integral + # arrhenius integral dt + time_integrand = (rh ** n) * np.exp(-Ea / (R * temps)) - degradation = C * data["dD"].sum(axis=0) + dD = wavelength_integral * time_integrand + degradation = C * np.sum(dD) return degradation @@ -959,7 +1015,11 @@ def vecArrhenius( poa_global: np.ndarray, module_temp: np.ndarray, ea: float, x: float, lnr0: float ) -> float: """ - Calculates degradation using :math:`R_D = R_0 * I^X * e^{\\frac{-Ea}{kT}}` + Calculate arrhenius degradation using vectorized operations. To eliminate the irradiance term set the irradiance sensitivity to 0. + + .. math:: + + R_D = R_0 \\cdot I^X \\cdot e^{\\frac{-E_a}{kT}} Parameters ---------- diff --git a/pvdeg/geospatial.py b/pvdeg/geospatial.py index c9cb0d2c..9dd82e54 100644 --- a/pvdeg/geospatial.py +++ b/pvdeg/geospatial.py @@ -7,6 +7,7 @@ humidity, letid, utilities, + decorators, ) import xarray as xr @@ -190,7 +191,12 @@ def calc_block(weather_ds_block, future_meta_df, func, func_kwargs): def analysis(weather_ds, meta_df, func, template=None, **func_kwargs): """ - Applies a function to each gid of a weather dataset. + Applies a function to each gid of a weather dataset. `analysis` will attempt to create a template using `geospatial.auto_template`. + If this process fails you will have to provide a geospatial template to the template argument. + + ValueError: cannot be autotemplated. create a template manually with `geospatial.output_template` + + Parameters ---------- @@ -212,8 +218,10 @@ def analysis(weather_ds, meta_df, func, template=None, **func_kwargs): """ if template is None: - param = template_parameters(func) - template = output_template(weather_ds, **param) + template = auto_template( + func=func, + ds_gids=weather_ds + ) # future_meta_df = client.scatter(meta_df) kwargs = {"func": func, "future_meta_df": meta_df, "func_kwargs": func_kwargs} @@ -241,7 +249,11 @@ def analysis(weather_ds, meta_df, func, template=None, **func_kwargs): def output_template( - ds_gids, shapes, attrs=dict(), global_attrs=dict(), add_dims=dict() + ds_gids: xr.Dataset, + shapes: dict, + attrs=dict(), + global_attrs=dict(), + add_dims=dict() ): """ Generates a xarray template for output data. Output variables and @@ -249,6 +261,31 @@ def output_template( The dimension length are derived from the input data. Additonal output dimensions can be defined with the add_dims argument. + Examples + -------- + Providing the shapes dictionary can be confusing. Here is what the `shapes` dictionary should look like for `pvdeg.standards.standoff`. + Refer to the docstring, the function will have one result per location so the only dimension for each return value is "gid", a geospatial ID number. + + .. code-block:: python + shapes = { + "x": ("gid",), + "T98_inf": ("gid",), + "T98_0": ("gid",), + } + + **Note: The dimensions are stored in a tuple, this this why all of the parenthesis have commas after the single string, otherwise python will interpret the value as a string.** + + This is what the shapes dictinoary should look like for `pvdeg.humidity.module`. Refering to the docstring, + we can see that the function will return a timeseries result for each location. This means we need dimensions of "gid" and "time". + + .. code-block:: python + shapes = { + "RH_surface_outside": ("gid", "time"), + "RH_front_encap": ("gid", "time"), + "RH_back_encap": ("gid", "time"), + "RH_backsheet": ("gid", "time"), + } + Parameters ---------- ds_gids : xarray.Dataset @@ -290,9 +327,9 @@ def output_template( return output_template -# we should be able to get rid of this with the new autotemplating function and decorator -# this is helpful for users so we should move it to a section in the documenation, -# discuss with group +# This has been replaced with pvdeg.geospatial.auto_templates inside of pvdeg.geospatial.analysis. +# it is here for completeness. it can be removed. +@decorators.deprecated(reason="use geospatial.auto_template or create a template with geospatial.output_template") def template_parameters(func): """ Output parameters for xarray template. @@ -410,6 +447,28 @@ def zero_template( return res +def can_auto_template(func) -> None: + """ + Check if we can use `geospatial.auto_template on a given function. + + Raise an error if the function was not declared with the `@geospatial_quick_shape` decorator. + No error raised if we can run `geospatial.auto_template` on provided function, `func`. + + Parameters + ---------- + func: callable + function to create template from. + + Returns + ------- + None + """ + if not (hasattr(func, "numeric_or_timeseries") and hasattr(func, "shape_names")): + raise ValueError( + f"{func.__name__} cannot be autotemplated. create a template manually" + ) + + def auto_template(func: Callable, ds_gids: xr.Dataset) -> xr.Dataset: """ @@ -417,11 +476,10 @@ def auto_template(func: Callable, ds_gids: xr.Dataset) -> xr.Dataset: Only works on functions that have the `numeric_or_timeseries` and `shape_names` attributes. These attributes are assigned at function definition with the `@geospatial_quick_shape` decorator. - Otherwise you will have to create your own template. - Don't worry, this is easy. See the Geospatial Templates Notebook - for more information. + Otherwise you will have to create your own template using `geospatial.output_template`. + See the Geospatial Templates Notebook for more information. - examples: + Examples --------- the function returns a numeric value @@ -430,17 +488,31 @@ def auto_template(func: Callable, ds_gids: xr.Dataset) -> xr.Dataset: the function returns a timeseries result >>> pvdeg.module.humidity - counter example: + Counter example: ---------------- the function could either return a single numeric or a series based on changed in the input. Because it does not have a known result shape we cannot determine the attributes required for autotemplating ahead of time. + + Parameters + ---------- + func: callable + function to create template from. This will raise an error if the function was not declared with the `@geospatial_quick_shape` decorator. + ds_gids : xarray.Dataset + Dataset containing the gids and their associated dimensions. (geospatial weather dataset) + Dataset should already be chunked. + + Returns + ------- + output_template : xarray.Dataset + Template for output data. """ - if not (hasattr(func, "numeric_or_timeseries") and hasattr(func, "shape_names")): - raise ValueError( - f"{func.__name__} cannot be autotemplated. create a template manually" - ) + can_auto_template(func=func) + # if not (hasattr(func, "numeric_or_timeseries") and hasattr(func, "shape_names")): + # raise ValueError( + # f"{func.__name__} cannot be autotemplated. create a template manually" + # ) if func.numeric_or_timeseries == 0: shapes = {datavar: ("gid",) for datavar in func.shape_names} diff --git a/pvdeg/humidity.py b/pvdeg/humidity.py index b8bcfe9f..ca2b1fc2 100644 --- a/pvdeg/humidity.py +++ b/pvdeg/humidity.py @@ -59,6 +59,31 @@ def _ambient(weather_df): return weather_df +# should this take the weather_df as everything else does +def precipitable_water(dew_point, pressure): + """ + calculate precipitable water vapor (PWV) in cm. + + Parameters + =========== + - dew_point: numeric + Dew point temperature in °C (array or single value) + - pressure: numeric + Atmospheric pressure in hPa (array or single value) + + Returns + =========== + - PWV: numeric + PWV in cm + """ + # Calculate saturation vapor pressure (e_s) at dew point + e_s = 6.1094 * np.exp((17.625 * dew_point) / (dew_point + 243.04)) + + # Calculate precipitable water vapor (PWV) + PWV = (0.1 * e_s) / pressure + return PWV + + # TODO: When is dew_yield used? @njit def dew_yield(elevation, dew_point, dry_bulb, wind_speed, n): diff --git a/pvdeg/scenario.py b/pvdeg/scenario.py index aab8afae..a46555c8 100644 --- a/pvdeg/scenario.py +++ b/pvdeg/scenario.py @@ -1092,6 +1092,8 @@ def __init__( geospatial=False, weather_data: xr.Dataset = None, meta_data: pd.DataFrame = None, + func: Callable = None, + template: xr.Dataset = None, ): super().__init__( name=name, @@ -1106,6 +1108,8 @@ def __init__( ) self.geospatial = geospatial self.hpc = hpc + self.func = func + self.template = template def __eq__(self, other): raise NotImplementedError(""" @@ -1593,50 +1597,50 @@ def set_geospatial_data(self, weather_ds: xr.Dataset, meta_df: pd.DataFrame ) -> """ self.weather_data, self.meta_data = weather_ds, meta_df - def addJob( self, - func: Callable = None, + func: Callable, + template: xr.Dataset = None, func_params: dict = {}, - see_added: bool = False, - ): + see_added: bool = False + ) -> None: """ - Add a pvdeg function to the scenario pipeline + Add a pvdeg geospatial function to the scenario pipeline. If no template is provided, `addJob` attempts to use `geospatial.auto_template` this will raise an Parameters: ----------- func : function - pvdeg function to use for geospatial analysis. - *Note: geospatial analysis is only available with a limited subset of pvdeg - functions* - Current supported functions for geospatial analysis: ``pvdeg.standards.standoff``, - ``pvdeg.humidity.module``, ``pvdeg.letid.calc_letid_outdoors`` + pvdeg function to use for geospatial analysis. + template : xarray.Dataset + Template for output data. Only required if a function is not supported by `geospatial.auto_template`. func_params : dict job specific keyword argument dictionary to provide to the function see_added : bool set flag to get a userWarning notifying the user of the job added - to the pipeline in method call. ``default = False`` + to the pipeline in method call. ``default = False`` """ - try: - pvdeg.geospatial.template_parameters(func) - except ValueError: - return ValueError( - f"{func.__name__} does does not have a valid geospatial results template or does not exist" - ) - geo_job_dict = {"geospatial_job": {"job": func, "params": func_params}} + if template is None: + + # take the weather datapoints specified by metadata and create a template based on them. + self.weather_data = self.weather_data.sel(gid=self.meta_data.index) + template = pvdeg.geospatial.auto_template(func=func, ds_gids=self.weather_data) - self.pipeline = geo_job_dict + self.template = template + self.func = func + self.func_params = func_params if see_added: - message = f"{func.__name__} added to pipeline as \n {geo_job_dict}" + message = f"{func.__name__} added to scenario with arguments {func_params} using template: {template}" warnings.warn(message, UserWarning) + + def run(self, hpc_worker_conf: Optional[dict] = None) -> None: """ - Run the function in the geospatial pipeline. - GeospatialScenario only supports one geospatial pipeline job at a time - unlike Scenario which supports unlimited conventional pipeline jobs. + Run the geospatial scenario stored in the geospatial scenario object. + + Only supports one function at a time. Unlike `Scenario` which supports unlimited conventional pipeline jobs. Results are stored in the `GeospatialScenario.results` attribute. Creates a dask cluster or client using the hpc_worker_conf parameter. @@ -1675,20 +1679,14 @@ def run(self, hpc_worker_conf: Optional[dict] = None) -> None: """ client = pvdeg.geospatial.start_dask(hpc=hpc_worker_conf) - geo_weather_sub = self.weather_data.sel(gid=self.meta_data.index) - - func = self.pipeline["geospatial_job"]["job"] - - if func == pvdeg.standards.standoff or func == pvdeg.humidity.module: - geo = { - "func": func, - "weather_ds": geo_weather_sub, - "meta_df": self.meta_data, - } - - analysis_result = pvdeg.geospatial.analysis(**geo) + analysis_result = pvdeg.geospatial.analysis( + weather_ds=self.weather_data, + meta_df=self.meta_data, + func=self.func, + template=self.template, # provided or generated via autotemplate in GeospatialScenario.addJob + ) - self.results = analysis_result + self.results = analysis_result client.shutdown() @@ -2021,32 +2019,32 @@ def _check_set(self, iterable, to_check: set): raise ValueError(f"All of iterable: {iterable} does not exist in {to_check}") - - def format_pipeline(self): - pipeline_html = "
" - if "geospatial_job" in self.pipeline: - step_name = "geospatial_job" - step = self.pipeline[step_name] - params_html = f"
{json.dumps(step['params'], indent=2)}
" - - step_content = f""" -
-

- - {step['job'].__name__}, #{step_name} -

-
- - """ - pipeline_html += step_content - pipeline_html += "
" - return pipeline_html + # GeospatialScenario no longer uses pipeline, instead job attributes are stored in attrbutes "func", "template" + # def format_pipeline(self): + # pipeline_html = "
" + # if "geospatial_job" in self.pipeline: + # step_name = "geospatial_job" + # step = self.pipeline[step_name] + # params_html = f"
{json.dumps(step['params'], indent=2)}
" + + # step_content = f""" + #
+ #

+ # + # {step['job'].__name__}, #{step_name} + #

+ #
+ # + # """ + # pipeline_html += step_content + # pipeline_html += "
" + # return pipeline_html def _ipython_display_(self): file_url = f"file:///{os.path.abspath(self.path).replace(os.sep, '/')}" @@ -2061,8 +2059,9 @@ def _ipython_display_(self): {self.format_results() if self.results else None}
-

Pipeline

- {self.format_pipeline()} +

Geospatial Job

+ Function : {self.func.__name__} + {self.format_template()}

Modules

@@ -2133,6 +2132,25 @@ def format_geo_meta(self): return meta_data_html + def format_template(self): + template_html = "" + + if self.meta_data is not None: + + template_html = f""" +
+

+ + Template +

+
+ + """ + + return template_html + def format_geo_weather(self): weather_data_html = "" @@ -2151,4 +2169,4 @@ def format_geo_weather(self):
""" - return weather_data_html \ No newline at end of file + return weather_data_html diff --git a/testing-setpoints/standards_testing.ipynb b/testing-setpoints/standards_testing.ipynb index 2b25c021..d9757157 100644 --- a/testing-setpoints/standards_testing.ipynb +++ b/testing-setpoints/standards_testing.ipynb @@ -8,6 +8,7 @@ "source": [ "import matplotlib.pyplot as plt\n", "import pvdeg\n", + "from pvlib import spectrum, solarposition, irradiance, atmosphere\n", "import pandas as pd\n", "import os" ] @@ -293,9 +294,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAJOCAYAAABm7rQwAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAB4G0lEQVR4nO3deZyNdf/H8ffsM8yGmLHv2UVEY4mktFPuSqmQlNIirSq7KCq0oEWj+hHV3XpXyi11J6IkpSmhkSWGhDGYGWau3x9X58wcs50zc8255jrzej4e5zFzLee6vuec75lc7z7f7xVkGIYhAAAAAAAAwI+C7W4AAAAAAAAAKh9CKQAAAAAAAPgdoRQAAAAAAAD8jlAKAAAAAAAAfkcoBQAAAAAAAL8jlAIAAAAAAIDfEUoBAAAAAADA7wilAAAAAAAA4HeEUgAAAAAAAPA7QikAQKUSFBSkO+64w+5muG3fvl1BQUF68skn7W6KY33xxRcKCgrSF198YXdTgDLp3bu3evfubXczAADwG0IpAEBA2LZtm2699VY1adJEkZGRio2NVffu3TVnzhwdP37c7uZVePv379fdd9+tli1bKioqSrVq1VKXLl304IMPKiMjw+fjrV69WhMnTtShQ4esb6yF/vzzT02cOFE//PBDuZ1j4sSJCgoKKvFRmcOIlJQUTZw4Udu3b7e7KY7QqFEjj75TtWpVdenSRa+99lqBfV2h7dtvv13osYYOHaro6OjybjIAAIUKtbsBAACU1UcffaSrrrpKERERuvHGG9W2bVtlZ2dr1apVuv/++/Xzzz/rxRdftLuZFdbff/+tzp07Kz09XTfddJNatmypAwcO6Mcff9S8efN02223+XzRunr1ak2aNElDhw5VfHx8+TT8H+ecc46OHz+u8PBwn5/7559/atKkSWrUqJE6dOhgfeMkXXnllWrWrJl7OSMjQ7fddpuuuOIKXXnlle71CQkJ5XJ+J0hJSdGkSZPUu3dvNWrUyO7mOEKHDh107733SpL27Nmjl19+WUOGDFFWVpZGjBhhc+sAAPAOoRQAwNFSU1M1aNAgNWzYUJ9//rlq167t3jZq1Cht3bpVH330kY0trBiOHj2qqlWrFrptwYIF2rFjh77++mt169bNY1t6enqpwh5/Cg4OVmRkpN3NKFL79u3Vvn179/Jff/2l2267Te3bt9f1119vY8vKT3H9rTK2ozzUrVvXo/8MHTpUTZo00axZswilAACOwfA9AICjzZgxQxkZGVqwYIFHIOXSrFkz3X333QXWv/fee2rbtq0iIiLUpk0bLVu2zGP7H3/8odtvv10tWrRQVFSUatSooauuuqrA8KKFCxcqKChIq1at0l133aWaNWsqPj5et956q7Kzs3Xo0CHdeOONqlatmqpVq6YHHnhAhmEU+lpmzZqlhg0bKioqSr169dKmTZsK7PPrr7/qX//6l6pXr67IyEh17txZH3zwQaFt+vLLL3X77berVq1aqlevXpHv4bZt2xQSEqKzzz67wLbY2NgCgc/atWt14YUXKi4uTlWqVFGvXr309ddfu7dPnDhR999/vySpcePG7iFGrvfONa/XokWL1KJFC0VGRqpTp0763//+V+D8GzZs0EUXXaTY2FhFR0frvPPO0zfffOOxT2FzSvXu3Vtt27ZVSkqKzj33XFWpUkV169bVjBkzPJ531llnSZKGDRvmbufChQslSVu2bNHAgQOVmJioyMhI1atXT4MGDdLhw4fdx/jrr7/066+/6tixY0W+v97y5bMtbX/LP4eZP/qbN9+jhQsX6qqrrpIknXvuue7PwfV5BgUFaeLEiQXa1qhRIw0dOtSrdkjSJ598op49e6pq1aqKiYnRJZdcop9//rnEz+Xvv//Wfffdp3bt2ik6OlqxsbG66KKLtHHjRo/9XP3wzTff1GOPPaZ69eopMjJS5513nrZu3VrguC+++KKaNm2qqKgodenSRV999VWJbSlOzZo11bJlS23btq1MxwEAwJ+olAIAONqHH36oJk2aFKjwKc6qVav0zjvv6Pbbb1dMTIyeeeYZDRw4UDt27FCNGjUkSd9++61Wr16tQYMGqV69etq+fbvmzZun3r17KyUlRVWqVPE45p133qnExERNmjRJ33zzjV588UXFx8dr9erVatCggaZNm6aPP/5YM2fOVNu2bXXjjTd6PP+1117TkSNHNGrUKGVmZmrOnDnq06ePfvrpJ/ewrp9//lndu3dX3bp19dBDD6lq1ap68803NWDAAP373//WFVdc4XHM22+/XTVr1tT48eN19OjRIt+Phg0bKicnR6+//rqGDBlS7Hv3+eef66KLLlKnTp00YcIEBQcHKzk5WX369NFXX32lLl266Morr9Rvv/2mN954Q7NmzdJpp50mybxodvnyyy+1dOlS3XXXXYqIiNDcuXN14YUXat26dWrbtq379fbs2VOxsbF64IEHFBYWphdeeEG9e/fWl19+qa5duxbb1oMHD+rCCy/UlVdeqauvvlpvv/22HnzwQbVr104XXXSRWrVqpcmTJ2v8+PG65ZZb1LNnT0lSt27dlJ2drX79+ikrK8v92e7evVv/+c9/dOjQIcXFxUmSnnvuOU2aNEkrV64s05xQvn62Tulv3nyPzjnnHN1111165pln9PDDD6tVq1aS5P7pq8La4erb/fr10xNPPKFjx45p3rx56tGjhzZs2FDskMHff/9d7733nq666io1btxYaWlpeuGFF9SrVy+lpKSoTp06Hvs//vjjCg4O1n333afDhw9rxowZGjx4sNauXeveZ8GCBbr11lvVrVs3jR49Wr///rsuv/xyVa9eXfXr1y/V6z558qR27dqlatWqFbr9yJEj+uuvvwqsz8rKKtX5AACwhAEAgEMdPnzYkGT079/f6+dIMsLDw42tW7e6123cuNGQZDz77LPudceOHSvw3DVr1hiSjNdee829Ljk52ZBk9OvXz8jNzXWvT0pKMoKCgoyRI0e61508edKoV6+e0atXL/e61NRUQ5IRFRVl7Nq1y71+7dq1hiTjnnvuca8777zzjHbt2hmZmZnudbm5uUa3bt2M5s2bF2hTjx49jJMnT5b4nuzdu9eoWbOmIclo2bKlMXLkSGPx4sXGoUOHPPbLzc01mjdvXuC1Hjt2zGjcuLFx/vnnu9fNnDnTkGSkpqYWOJ8kQ5Lx3Xffudf98ccfRmRkpHHFFVe41w0YMMAIDw83tm3b5l73559/GjExMcY555zjXrdy5UpDkrFy5Ur3ul69ehX4rLKysozExERj4MCB7nXffvutIclITk72aOOGDRsMScZbb71VzDtnGBMmTChw7pLs37/fkGRMmDDBvc7Xz9Yp/c3b79Fbb71V5Pt46nvl0rBhQ2PIkCEltuPIkSNGfHy8MWLECI/n792714iLiyuw/lSZmZlGTk6Ox7rU1FQjIiLCmDx5snudqx+2atXKyMrKcq+fM2eOIcn46aefDMMwjOzsbKNWrVpGhw4dPPZ78cUXDUken1dRGjZsaFxwwQXG/v37jf379xs//fSTccMNNxiSjFGjRnns62pXcY+qVauWeE4AAMoDw/cA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migtLU1r1qzRrl27tHHjxlKd+/XXX9eiRYt0xRVXqFOnTgoPD9cvv/yiV155RZGRkXr44YclScHBwXr55Zd10UUXqU2bNho2bJjq1q2r3bt3a+XKlYqNjdWHH34oSe5JzB955BENGjRIYWFhuuyyy9zhQ9u2bdWvXz/dddddioiI0Ny5cyVJkyZNcrdr6tSpWr58uXr06KHbb79doaGheuGFF5SVlaUZM2aU6rWeqmnTpoqPj9f8+fMVExOjqlWrqmvXrtq4caPuuOMOXXXVVTr99NN18uRJvf766woJCdHAgQPdz3/uuec0adIkrVy5skyTnZfXZ1sUf/U3b79HHTp0UEhIiJ544gkdPnxYERER6tOnj2rVqqWbb75ZI0eO1MCBA3X++edr48aN+vTTT72uUoqNjdW8efN0ww036Mwzz9SgQYNUs2ZN7dixQx999JG6d++u5557rtjXMHnyZA0bNkzdunXTTz/9pEWLFvk0/1N+YWFhmjp1qm699Vb16dNH11xzjVJTU5WcnFzqY7pcdNFFatu2rZ5++mmNGjVKYWFhZToeAADljVAKAOB4l19+uX788UfNnDlT77//vubNm6eIiAi1b99eTz31lEaMGOHzMefMmaOQkBAtWrRImZmZ6t69u/773/8WOb9OWd14440KDg7W7NmztW/fPnXp0kXPPfecateu7d6ndevW+u677zRp0iQtXLhQBw4cUK1atdSxY0eNHz++1Oe+9dZbVaVKFa1YsULvv/++0tPTVbNmTV1wwQUaO3asOnbs6N63d+/eWrNmjaZMmaLnnntOGRkZSkxMVNeuXXXrrbe69zvrrLM0ZcoUzZ8/X8uWLVNubq5SU1PdoVSvXr2UlJSkSZMmaceOHWrdurUWLlyo9u3bu4/Rpk0bffXVVxo7dqymT5+u3Nxcde3aVf/3f/+nrl27lvr15hcWFqZXX31VY8eO1ciRI3Xy5EklJyerV69e6tevnz788EPt3r1bVapU0RlnnKFPPvlEZ599tiXnzq+8Ptui+Ku/efs9SkxM1Pz58zV9+nQNHz5cOTk5WrlypWrVqqURI0YoNTVVCxYs0LJly9SzZ08tX75c5513ntev97rrrlOdOnX0+OOPa+bMmcrKylLdunXVs2dPDRs2rNjnPvzwwzp69KgWL16spUuX6swzz9RHH32khx56yOvzn+qWW25RTk6OZs6cqfvvv1/t2rXTBx98UOSk8r647777NHToUC1atKhUgTwAAP4UZFg96yIAAEAxgoKCNGrUqGKrU1A+tm/frsaNG2vmzJm677777G4OAACo5JhTCgAAAAAAAH5HKAUAAAAAAAC/I5QCAAAAAACA3zGnFAAAAAAAAPyOSikAAAAAAAD4HaEUAAAAAAAA/C7U7gY4wcmTJ7VhwwYlJCQoOJgcDwAAAAAAlK/c3FylpaWpY8eOCg0NzPgmMF+VxTZs2KAuXbrY3QwAAAAAAFDJrFu3TmeddZbdzSgXhFJeSEhIkGR2hNq1a9vcGgAAAAAAEOj27NmjLl26uDOJQEQo5QXXkL3atWurXr16NrcGAAAAAABUFoE8jVDgvjIAAAAAAABUWIRSAAAAAAAA8DtCKQAAAAAAAPgdc0pZJDc3V9nZ2XY3AxVQWFiYQkJC7G4GAAAAUGlwfQYn4FqRUMoS2dnZSk1NVW5urt1NQQUVHx+vxMREBQUF2d0UAAAAIKBxfQYnqezXioRSZWQYhvbs2aOQkBDVr18/oGfFh+8Mw9CxY8e0b98+SeYdHAEAAACUD67P4BRcK5oIpcro5MmTOnbsmOrUqaMqVarY3RxUQFFRUZKkffv2qVatWpW+PBMAAAAoL1yfwUm4VmSi8zLLycmRJIWHh9vcElRkrv8gnjhxwuaWAAAAAIGL6zM4TWW/ViSUskhlHf8J79A/AAAAAP/h399wisreVwmlAAAAAAAA4HeEUgAAAAAAONwXX3yhoKAgHTp0qEIcp6IbOnSoBgwYUOw+vXv31ujRo93LjRo10uzZs8u1XZUNoVQlFBQUVOxj4sSJdjfRcvzxAAAAAFBRDR061H09FhYWpsaNG+uBBx5QZmZmuZ731NBFkrp166Y9e/YoLi6u3M67fft2BQUF6YcffvCqTeVhzpw5WrhwoU/P+fbbb3XLLbe4l4OCgvTee+9Z27BKhrvvVUJ79uxx/7506VKNHz9emzdvdq+Ljo62o1k+MwxDOTk5Cg31XzfOzs5m0kQAAAAAlrvwwguVnJysEydOaP369RoyZIiCgoL0xBNP+LUd4eHhSkxM9Os57VCa0K1mzZrl0JLKjUqpSigxMdH9iIuLU1BQkMe6JUuWqFWrVoqMjFTLli01d+5c93Ndifabb76pnj17KioqSmeddZZ+++03ffvtt+rcubOio6N10UUXaf/+/e7nuUojJ02apJo1ayo2NlYjR45Udna2e5/c3FxNnz5djRs3VlRUlM444wy9/fbb7u2uMtJPPvlEnTp1UkREhFatWqVt27apf//+SkhIUHR0tM466yz997//dT+vd+/e+uOPP3TPPfe4/++DJE2cOFEdOnTweG9mz56tRo0aFWj3Y489pjp16qhFixaSpJ07d+rqq69WfHy8qlevrv79+2v79u1WfDwAAAAAKqGIiAglJiaqfv36GjBggPr27avly5e7t5d0vXSqAwcO6Nprr1XdunVVpUoVtWvXTm+88YZ7+9ChQ/Xll19qzpw57uuk7du3ewzfS09PV1RUlD755BOPY7/77ruKiYnRsWPHJJXv9VFh1Ujx8fHuKqeyXqO6HD16VDfeeKOio6NVu3ZtPfXUUwXakn8Ejuu68YorrlBQUJAaNWqk7du3Kzg4WN99953H82bPnq2GDRsqNze3zO9HoCGUsphhSEeP2vMwjLK3f9GiRRo/frwee+wx/fLLL5o2bZrGjRunV1991WO/CRMm6NFHH9X333+v0NBQXXfddXrggQc0Z84cffXVV9q6davGjx/v8ZwVK1bol19+0RdffKE33nhD77zzjiZNmuTePn36dL322muaP3++fv75Z91zzz26/vrr9eWXX3oc56GHHtLjjz+uX375Re3bt1dGRoYuvvhirVixQhs2bNCFF16oyy67TDt27JAkvfPOO6pXr54mT56sPXv2eFSKeWPFihXavHmzli9frv/85z86ceKE+vXrp5iYGH311Vf6+uuvFR0drQsvvNAjZAMAAABgM4deoG3atEmrV6/2GKXh7fWSS2Zmpjp16qSPPvpImzZt0i233KIbbrhB69atk2QOX0tKStKIESPc10n169f3OEZsbKwuvfRSLV682GP9okWLNGDAAFWpUqXCXB+V5ho1v/vvv19ffvml3n//fX322Wf64osv9P333xe5/7fffitJSk5O1p49e/Ttt9+qUaNG6tu3r5KTkz32TU5O1tChQxUcTARTgIES7dy505Bk7Ny5s8C248ePGykpKcbx48cNwzCMjAzDMP/6+P+RkeH7a0tOTjbi4uLcy02bNjUWL17ssc+UKVOMpKQkwzAMIzU11ZBkvPzyy+7tb7zxhiHJWLFihXvd9OnTjRYtWriXhwwZYlSvXt04evSoe928efOM6OhoIycnx8jMzDSqVKlirF692uPcw4cPN6699lrDMAxj5cqVhiTjvffeK/F1tWnTxnj22Wfdyw0bNjRmzZrlsc+ECROMM844w2PdrFmzjIYNG3q0OyEhwcjKynKve/31140WLVoYubm57nVZWVlGVFSU8emnnxbanlP7CQAAAADrFfh3t0Mu0IYMGWKEhIQYVatWNSIiIgxJRnBwsPH2228bhmH4dL108ODBIs9zySWXGPfee697uVevXsbdd9/tsc+px3n33XeN6Oho97Xc4cOHjcjISOOTTz4xDKN010eu68qoqCijatWqHo/g4GCPNkky3n33XY/nx8XFGcnJyR7HKs01av/+/Q3DMIwjR44Y4eHhxptvvunefuDAASMqKsqjLadeVxbWtqVLlxrVqlUzMjMzDcMwjPXr1xtBQUFGampqoe9FcdeKxWURgYI5peB29OhRbdu2TcOHD9eIESPc60+ePFlgvG379u3dvyckJEiS2rVr57Fu3759Hs8544wzVKVKFfdyUlKSMjIytHPnTmVkZOjYsWM6//zzPZ6TnZ2tjh07eqzr3Lmzx3JGRoYmTpyojz76SHv27NHJkyd1/Phxd6VUWbVr187j/1Bs3LhRW7duVUxMjMd+mZmZ2rZtmyXnBAAAAFC5nHvuuZo3b56OHj2qWbNmKTQ0VAMHDpQkbd261evrJZecnBxNmzZNb775pnbv3q3s7GxlZWV5XJN54+KLL1ZYWJg++OADDRo0SP/+978VGxurvn37Sirb9dHSpUvVqlUrj3WDBw/2qX0upblGddm2bZuys7PVtWtX97rq1au7p2/xxYABAzRq1Ci9++67GjRokBYuXKhzzz3XY5oY5CGUsliVKlJGhn3nLouMfxr+0ksveXwZJSkkJMRjOSwszP27a46mU9f5Ml7Wde6PPvpIdevW9dgWERHhsVy1alWP5fvuu0/Lly/Xk08+qWbNmikqKkr/+te/SiwVDQ4OlnFKSe2JEycK7Hfq+TIyMtSpUyctWrSowL5MfAcAAABUIA66QKtataqaNWsmSXrllVd0xhlnaMGCBRo+fLhP10suM2fO1Jw5czR79my1a9dOVatW1ejRo30eUhceHq5//etfWrx4sQYNGqTFixfrmmuucd9wqizXR/Xr13e/ZpeoqCiP5aCgIK+u26y+Ri2t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L/82pA9Y197y+nfhggULNGjQIFWtWtXStuRHP7CuvVb1g27dumn9+vXu4Xi///67Pv74Y1188cVev0ZfrxNLw6dQ6q+//lJOTo4SEhI81ickJGjv3r3au3evwsPDFR8fX+h2l6ZNm+q0005zL+/du7fIY7q2u9YVd9wGDRqodu3aJR43PT1dx48fL/H1FMWK9u7du1e1atXy2B4aGqrq1at77FPYMfKfw19tcaEPWNdeq/pASbx5jd5+bt4ek35gfz948MEHVadOHfd/QPhbUDn6wOHDhxUdHa3w8HBdcsklevbZZ3X++edb2hYX+oB17bWqD6xatUoLFizQSy+9VGRbrWhLfvQD69prVT9o0aKFXnnlFb3//vv6v//7P+Xm5qpbt27atWuXpW1xoQ9Y116r+sDvv/+ut99+Wzk5Ofr44481btw4PfXUU5o6daok6/9tSB+wrr3l8e/CdevWadOmTbr55ps92mpFW/KjH1jXXqv6wXXXXafJkyerR48eCgsLU9OmTdW7d289/PDDksrnOrE0Qi05io9WrFhRLsd97bXXyuW4sB59ABL9oLw8/vjjWrJkib744osCk9tWNPQBa8XExOiHH35QRkaGVqxYoTFjxqhJkybq3bu33U0rEn3AGkeOHNENN9ygl156yeMf805BP7BOUlKSkpKS3MvdunVTq1at9MILL2jKlCk2tqx49AHr5ObmqlatWnrxxRcVEhKiTp06affu3Zo5c6YmTJhgd/OKRB8oHwsWLFC7du3UpUsXu5viFfqBdb744gtNmzZNc+fOVdeuXbV161bdfffdmjJlisaNG2d389x8qpQ67bTTFBISUmCm9bS0NCUmJioxMVHZ2dk6dOhQoduLkpiYWOQxXdtd66w4bmxsrKKiokp8PeXZ3sTERO3bt89j+8mTJ/X333977FPYMfKfw19tcaEPWNdeq/pASbx5jb5+bvQD69prdT948skn9fjjj+uzzz5T+/btPdpqRVtc6APWtdfKPhAcHKxmzZqpQ4cOuvfee/Wvf/1L06dPt7QtLvQB69prRR/Ytm2btm/frssuu0yhoaEKDQ3Va6+9pg8++EChoaHatm2b5X1Aoh9Y2d7y+ndBWFiYOnbsqK1bt1raFhf6gHXttaoP1K5dW6effrpCQkLc+7Rq1Up79+5Vdna25f82pA9Y116r/w4cPXpU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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "fig, ax1 = plt.subplots(figsize=(12, 6))\n", "\n", @@ -329,7 +341,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -344,9 +356,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAJaCAYAAAD+qfS9AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAABjq0lEQVR4nO3deVxUZf//8feA7AhoIrig4JIr7mmYJpmJZqZli2YlZqZllnmrZeVCZqaWy1dTW7FMS1u9uy3N3HLLJZdSzIVwzT1RcQGF8/tjfkyOoALOOQP5ej4e84hzzjXX9Tkzl9zM+z7nGpthGIYAAAAAAAAAC3m4uwAAAAAAAADceAilAAAAAAAAYDlCKQAAAAAAAFiOUAoAAAAAAACWI5QCAAAAAACA5QilAAAAAAAAYDlCKQAAAAAAAFiOUAoAAAAAAACWI5QCAAAAAACA5QilAAD/ejabTc8++6y7y3DYvXu3bDab3nrrLXeXUmQtXbpUNptNS5cudXcpwHWJjY1VbGysu8sAAMAtCKUAAEVWcnKyevXqpUqVKsnX11dBQUG67bbbNHHiRJ07d87d5RV6R48e1fPPP6/q1avLz89PpUuXVuPGjfXiiy8qLS0t3/2tWrVKw4cPV2pqquuLdaG//vpLw4cP16ZNm0wbY/jw4bLZbNd83MhhRFJSkoYPH67du3e7u5QiITIy0mnuBAQEqHHjxvrkk09ytM0Obb/88stc+4qPj1dgYKDZJQMAcE3F3F0AAAAFMW/ePD344IPy8fHR448/rtq1aysjI0MrVqzQwIEDtXXrVr333nvuLrPQ+vvvv9WoUSOdOnVKTzzxhKpXr67jx4/rt99+09SpU/X000/n+0PrqlWrlJCQoPj4eIWEhJhT+P93++2369y5c/L29s73c//66y8lJCQoMjJS9erVc31xku6//35VqVLFsZ2Wlqann35a9913n+6//37H/rCwMFPGLwqSkpKUkJCg2NhYRUZGurucIqFevXr6z3/+I0k6ePCgPvjgA3Xr1k3p6enq2bOnm6sDACD/CKUAAEVOSkqKOnfurIoVK2rx4sUqU6aM41ifPn20a9cuzZs3z40VFg5nzpxRQEBArsc+/PBD7d27VytXrlTTpk2djp06dapAYY+VPDw85Ovr6+4yrqhOnTqqU6eOY/vYsWN6+umnVadOHT366KNurMw8V5tvN2IdZihXrpzT/ImPj1elSpU0fvx4QikAQJHE7XsAgCJnzJgxSktL04cffugUSGWrUqWKnn/++Rz7v/32W9WuXVs+Pj6qVauW5s+f73R8z549euaZZ1StWjX5+fnppptu0oMPPpjj9qLp06fLZrNpxYoVeu655xQaGqqQkBD16tVLGRkZSk1N1eOPP64SJUqoRIkSGjRokAzDyPVcxo8fr4oVK8rPz08tWrTQli1bcrT5448/9MADD6hkyZLy9fVVo0aN9N///jfXmpYtW6ZnnnlGpUuXVvny5a/4GiYnJ8vT01O33nprjmNBQUE5Ap81a9aoTZs2Cg4Olr+/v1q0aKGVK1c6jg8fPlwDBw6UJEVFRTluMcp+7bLX9Zo5c6aqVasmX19fNWzYUD///HOO8Tdu3Ki2bdsqKChIgYGBuvPOO/XLL784tcltTanY2FjVrl1bSUlJuuOOO+Tv769y5cppzJgxTs+75ZZbJEndu3d31Dl9+nRJ0s6dO9WpUyeFh4fL19dX5cuXV+fOnXXy5ElHH8eOHdMff/yhs2fPXvH1zav8vLcFnW+XrmFmxXzLy7+j6dOn68EHH5Qk3XHHHY73Ifv9tNlsGj58eI7aIiMjFR8fn6c6JOmHH35Q8+bNFRAQoOLFi6tdu3baunXrNd+Xv//+WwMGDFB0dLQCAwMVFBSktm3bavPmzU7tsufhnDlzNHLkSJUvX16+vr668847tWvXrhz9vvfee6pcubL8/PzUuHFjLV++/Jq1XE1oaKiqV6+u5OTk6+oHAAB34UopAECR891336lSpUo5rvC5mhUrVujrr7/WM888o+LFi+v//u//1KlTJ+3du1c33XSTJGndunVatWqVOnfurPLly2v37t2aOnWqYmNjlZSUJH9/f6c++/btq/DwcCUkJOiXX37Re++9p5CQEK1atUoVKlTQG2+8oe+//15jx45V7dq19fjjjzs9/5NPPtHp06fVp08fnT9/XhMnTlTLli31+++/O27r2rp1q2677TaVK1dOL730kgICAjRnzhx17NhRX331le677z6nPp955hmFhoZq6NChOnPmzBVfj4oVKyozM1MzZsxQt27drvraLV68WG3btlXDhg01bNgweXh4KDExUS1bttTy5cvVuHFj3X///dqxY4c+++wzjR8/XqVKlZJk/9CcbdmyZZo9e7ae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atiwoby9vbVt2zZ99NFH8vX11csvvyxJ8vDw0AcffKC2bduqVq1a6t69u8qVK6cDBw5oyZIlCgoK0nfffSdJjkXMX3nlFXXu3FleXl5q3769I3yoXbu24uLi9Nxzz8nHx0dTpkyRJCUkJDjqev3117Vw4UI1a9ZMzzzzjIoVK6Z3331X6enpGjNmTIHO9XKVK1dWSEiIpk2bpuLFiysgIEBNmjTR5s2b9eyzz+rBBx/UzTffrIsXL2rGjBny9PRUp06dHM+fPHmyEhIStGTJkuta7Nys9/ZKrJpvef13VK9ePXl6emr06NE6efKkfHx81LJlS5UuXVpPPvmkevfurU6dOumuu+7S5s2btWDBgjxfpRQUFKSpU6fqscceU4MGDdS5c2eFhoZq7969mjdvnm677TZNnjz5qufw2muvqXv37mratKl+//13zZw5M1/rP13Ky8tLr7/+unr16qWWLVvq4YcfVkpKihITEwvcZ7a2bduqdu3aGjdunPr06SMvL6/r6g8AACsRSgEAiqR7771Xv/32m8aOHau5c+dq6tSp8vHxUZ06dfT222+rZ8+e+e5z4sSJ8vT01MyZM3X+/Hnddttt+umnn664vs71evzxx+Xh4aEJEyboyJEjaty4sSZPnqwyZco42tSsWVPr169XQkKCpk+fruPHj6t06dKqX7++hg4dWuCxe/XqJX9/fy1atEhz587VqVOnFBoaqtatW2vw4MGqX7++o21sbKxWr16tESNGaPLkyUpLS1N4eLiaNGmiXr16OdrdcsstGjFihKZNm6b58+crKytLKSkpjlCqRYsWiomJUUJCgvbu3auaNWtq+vTpqlOnjqOPWrVqafny5Ro8eLBGjRqlrKwsNWnSRJ9++qmaNGlS4PO9lJeXlz7++GMNHjxYvXv31sWLF5WYmKgWLVooLi5O3333nQ4cOCB/f3/VrVtXP/zwg2699VaXjH0ps97bK7FqvuX131F4eLimTZumUaNGqUePHsrMzNSSJUtUunRp9ezZUykpKfrwww81f/58NW/eXAsXLtSdd96Z5/N95JFHVLZsWb355psaO3as0tPTVa5cOTVv3lzdu3e/6nNffvllnTlzRrNmzdLs2bPVoEEDzZs3Ty+99FKex7/cU089pczMTI0dO1YDBw5UdHS0/vvf/15xUfn8GDBggOLj4zVz5swCBfIA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81JERITjnLP5+fk5bdtstjx9jnP1Z9aC8vb21uOPP67ExETdf//9mjVrliZOnGj6uEUVodR1stmkyzKMIiMsLExly5bVn3/+WeA0+mo2b96sc+fOOX6p/PLLLwoMDFRERIRKliwpHx8f7d27Vy1atMhXvytXrlR8fLzuu+8+SfZfgpcvouft7a3MzEynfaGhoTp06JAMw3D8ksrtK0gv16BBA82ePVulS5dWUFBQvmoFAAAA4EZF9AObh4eHXn75ZfXv31+PPPKIatasme/PTytXrlSHDh306KOPSrIvlL5jxw7VrFnT0Sa3z0256dq1q+666y5t3bpVixcv1uuvv+44ZvbnpdDQUKd1gnfu3OlYYN1VKleuLC8vL61Zs0YVKlSQJJ04cUI7duy46uvt5eWV6+v35JNPqnbt2poyZYouXryo+++/36X1/puwytYNLiEhQaNGjdL//d//aceOHfr999+VmJiocePGXXffGRkZ6tGjh5KSkvT9999r2LBhevbZZ+Xh4aHixYtrwIABeuGFF/Txxx8rOTlZGzZs0KRJk3Issn65qlWr6uuvv9amTZu0efNmPfLIIzkS78jISP388886cOCAjh07Jsn+rXxHjx7VmDFjlJycrHfeeSfHt0jkpmvXripVqpQ6dOig5cuXKyUlRUuXLtVzzz2n/fv3F/wFAgAAAIArePDBB+Xp6al33nmnQJ+fqlatqoULF2rVqlXatm2bevXqpcOHDzu1iYyM1Jo1a7R7924dO3bsilcS3X777QoPD1fXrl0VFRXldKeN2Z+XWrZsqcmTJ2vjxo1av369evfu7XQFlCsEBgaqR48eGjhwoBYvXqwtW7bkaWHyyMhILVq0SIcOHdKJEycc+2vUqKFbb71VL774orp06ZLj6i/8g1DqBvfkk0/qgw8+UGJioqKjo9WiRQtNnz5dUVFR1933nXfeqapVq+r222/Xww8/rHvvvVfDhw93HB8xYoSGDBmiUaNGqUaNGmrTpo3mzZt3zbHHjRunEiVKqGnTpmrfvr3i4uLUoEEDpzavvfaadu/ercqVKzsuGa1Ro4amTJmid955R3Xr1tXatWs1YMCAa56Hv7+/fv75Z1WoUEH333+/atSooR49euj8+fNcOQUAAADAFMWKFdOzzz6rMWPG6MyZM/n+/PTqq6+qQYMGiouLU2xsrMLDw9Wx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AAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAAAADAcoRSAAAAAAAAsByhFAAAAAAAACxHKAUAAAAAAADLEUoBAAAA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fft27d271ymlu1xMTEyOVHThwoWO50RFRSk8PNypzalTp7RmzZrr6vda52NmvTExMUpNTdWvv/7qaLN48WJlZWWpSZMmjjY///yz01c7Lly4UNWqVVOJEiVcVou7MJ9cV6+r5tPlMjMz9fvvvzsudy2s84m55Lp68zKX8sKsc7QC88l19bpqPuVm06ZNjt9NzCc75pPd0qVL1a5dO40ePVpPPfWUKbW4C/PJdfW6aj5djr+dmEtS3v63LisrSxcuXFBWVpbLanEX5pPr6nXVfLpcof7dlN+V0T///HPDx8fHmD59upGUlGQ89dRTRkhIiOPrBXv37m1UqFDBWLx4sbF+/XojJibGiImJceqjZcuWxqRJkxzbK1euNIoVK2a89dZbxrZt24xhw4bl+tWJISEhxty5c43ffvvN6NChQ46vK3zssceMl156ybGd/VWPAwcONLZt22a88847uX7V49XOJ7d+XVVvmzZtjPr16xtr1qwxVqxYYVStWtXpqx5TU1ONsLAw47HHHjO2bNlifP7554a/v7/x7rvvurwWd2E+Fa75lJCQYCxYsMBITk42fv31V6Nz586Gr6+vsXXr1nzV4g7MJevmkmEYxtatW42NGzca7du3N2JjY42NGzcaGzdudPk5ugvzqXDNp/HjxxvffvutsXPnTuP33383nn/+ecPDw8P46aef8nWO7sJ8sm4+LV682PD39zcGDx7s9DXYx48fd3kt7sJ8Klzzib+dmEuGce259OmnnxqzZ882kpKSjOTkZGP27NlG2bJlja5du7q8FndhPhWu+VSUfjflO5QyDMOYNGmSUaFCBcPb29to3Lix8csvvziOnTt3znjmmWeMEiVKGP7+/sZ9991nHDx40On5FStWNIYNG+a0b86cOcbNN99seHt7G7Vq1TLmzZvndDwrK8sYMmSIERYWZvj4+Bh33nmnsX37dqc2LVq0MLp16+a0b8mSJUa9evUMb29vo1KlSkZiYmK+zudK/bqi3uPHjxtdunQxAgMDjaCgIKN79+7G6dOnndps3rzZaNasmeHj42OUK1fOePPNN3PU74pa3In5VHjmU79+/Ry1h4WFGXfffbexYcOGfNfiLswl6+ZSxYoVDUk5Hq4+R3diPhWe+TR69GijcuXKhq+vr1GyZEkjNjbWWLx4cb7P0Z2YT9bMp27duuU6l1q0aOHyWtyJ+VR45hN/OzGXDOPac+nzzz83GjRoYAQGBhoBAQFGzZo1jTfeeCPHh39+NzGfDMM186ko/W6yGYZhWHttFgAAAAAAAG50+VpTCgAAAAAAAHAFQikAAAAAAABYjlAKAAAAAAAAliOUAgAAAAAAgOUIpQAAAAAAAGA5QikAAAAAAABYjlAKAAAAAAAAliOUAgAAAAAAgOUIpQAAAAogPj5eHTt2dHcZAAAARVYxdxcAAABQ2NhstqseHzZsmCZOnCjDMCyqCAAA4N+HUAoAAOAyBw8edPw8e/ZsDR06VNu3b3fsCwwMVGBgoDtKAwAA+Nfg9j0AAIDLhIeHOx7BwcGy2WxO+wIDA3PcvhcbG6u+ffuqX79+KlGihMLCwvT+++/rzJkz6t69u4oXL64qVarohx9+cBpry5Ytatu2rQIDAxUWFqbHHntMx44ds/iMAQAArEcoBQAA4CIff/yxSpUqpbVr16pv3756+umn9eCDD6pp06basGGDWrdurccee0xnz56VJKWmpqply5aqX7++1q9fr/nz5+vw4cN66KGH3HwmAAAA5iOUAgAAcJG6devq1VdfVdWqVTV48GD5+vqqVKlS6tmzp6pWraqhQ4fq+PHj+u233yRJkydPVv369fXGG2+oevXqql+/vj766CMtWbJEO3bscPPZAAAAmIs1pQAAAFykTp06jp89PT110003KTo62rEvLCxMknTkyBFJ0ubNm7VkyZJc16dKTk7WzTffbHLFAAAA7kMoBQAA4CJeXl5O2zabzWlf9rf6ZWVlSZLS0tLUvn17jR49OkdfZcqUMbFSAAAA9yOUAgAAcJMGDRroq6++UmRkpIoV488yAABwY2FNKQAAADfp06eP/v77b3Xp0kXr1q1TcnKyFixYoO7duyszM9Pd5QEAAJiKUAoAAMBNypYtq5UrVyozM1OtW7dWdHS0+vXrp5CQEHl48GcaAAD4d7MZhmG4uwgAAAAAAADcWPi/4AAAAPLg0KFDuuuuuxQQEKCQkBB3l2OapUuXymazKTU11d2lAACAfzlCKQAA4HKZmZkaMmSIoqKi5Ofnp8qVK2vEiBG69ALt+Ph42Ww2p0ebNm3yPdaCBQt06623qnjx4goNDVWnTp20e/dux/HskOXyx6FDh/I1zvjx43Xw4EFt2rRJO3bsyHedV3P+/HnFx8crOjpaxYoVU8eOHXNtt3TpUjVo0EA+Pj6qUqWKpk+fnqPNO++8o8jISPn6+qpJkyZau3ZtjrH69Omjm266SYGBgerUqZMOHz7s0vMBAADIC0IpAADgcqNHj9bUqVM1efJkbdu2TaNHj9aYMWM0adIkp3Zt2rTRwYMHHY/PPvssX+OkpKSoQ4cOatmypTZt2qQFCxbo2LFjuv/++3O03b59u9NYpUuXztdYycnJatiwoapWrZrv52bLyMjIdX9mZqb8/Pz03HPPqVWrVrm2SUlJUbt27XTHHXdo06ZN6tevn5588kktWLDA0Wb27Nnq37+/hg0bpg0bNqhu3bqKi4vTkSNHHG1eeOEFfffdd/riiy+0bNky/fXXX7m+XgAAAGYjlAIAAC63atUqdejQQe3atVNkZKQeeOABtW7dOsdVOz4+PgoPD3c8SpQoka9xfv31V2VmZur1119X5cqV1aBBAw0YMECbNm3ShQsXnNqWLl3aaaz8LCQeGRmpr776Sp988olsNpvi4+MlSXv37lWHDh0UGBiooKAgPfTQQ05XHQ0fPlz16tXTBx98oKioKPn6+ubaf0BAgKZOnaqePXsqPDw81zbTpk1TVFSU3n77bdWoUUPPPvusHnjgAY0fP97RZty4cerZs6e6d++umjVratq0afL399dHH30kSTp58qQ+/PBDjRs3Ti1btlTDhg2VmJioVatW6Zdffsnx2jZq1Ej+/v5q2rSptm/fnufXCwAAIC8IpQAAgMs1bdpUixYtctzmtnnzZq1YsUJt27Z1ard06VKVLl1a1apV09NPP63jx4/na5yGDRvKw8NDiYmJyszM1MmTJzVjxgy1atVKXl5eTm3r1aunMmXK6K677tLKlSvzNc66devUpk0bPfTQQzp48KAmTpyorKwsdejQQX///beWLVumhQsX6s8//9TDDz/s9Nxdu3bpq6++0tdff61Nmzbla9xLrV69OsdVVHFxcVq9erUk+1VYv/76q1MbDw8PtWrVytHm119/1YULF5zaVK9eXRUqVHC0yfbKK6/o7bff1vr161WsWDE98cQTBa4dAAAgN8XcXQAAAPj3eemll3Tq1ClVr15dnp6eyszM1MiRI9W1a1dHmzZt2uj+++9XVFSUkpOT9fLLL6tt27ZavXq1PD098zROVFSUfvzxRz300EPq1auXMjMzFRMTo++//97RpkyZMpo2bZoaNWqk9PR0ffDBB4qNjdWaNWvUoEGDPI0TGhoqHx8f+fn5Oa5kWrhwoX7//XelpKQoIiJCkvTJJ5+oVq1aWrdunW655RZJ9rDok08+UWhoaJ7GupJDhw4pLCzMaV9YWJhOnTqlc+fO6cSJE8rMzMy1zR9//OHow9vbO8dC7WFhYTnW2Bo5cqRatGghyf5+tmvXTufPn7/i1V4AAAD5RSgFAABcbs6cOZo5c6ZmzZqlWrVqOdZAKlu2rLp16yZJ6ty5s6N9dHS06tSpo8qVK2vp0qW688478zTOoUOH1LNnT3Xr1k1dunTR6dOnNXToUD3wwANauHChbDabqlWrpmrVqjme07RpUyUnJ2v8+PGaMWNGgc9x27ZtioiIcARSklSzZk2FhIRo27ZtjlCqYsWK1x1IuUOdOnUcP5cpU0aSdOTIEVWoUMFdJQEAgH8ZQikAAOByAwcO1EsvveQInqKjo7Vnzx6NGjXKEUpdrlKlSipVqpR27dqV51DqnXfeUXBwsMaMGePY9+mnnyoiIkJr1qzRrbfemuvzGjdurBUrVuTzrAomICDAJf2Eh4fn+Ja8w4cPKygoSH5+fvL09JSnp2eubbKv7goPD1dGRoZSU1Odrpa6tE22S29/tNlskqSsrCyXnAsAAIDEmlIAAMAEZ8+ezbGQuKen51VDjf379+v48eOOq3KuZxzp6gHKpk2b8jVObmrUqKF9+/Zp3759jn1JSUlKTU1VzZo1r6vv3MTExGjRokVO+xYuXKiYmBhJkre3txo2bOjUJisrS4sWLXK0adiwoby8vJzabN++XXv37nW0AQAAsApXSgEAAJdr3769Ro4cqQoVKqhWrVrauHGjxo0b51gsOy0tTQkJCerUqZPCw8OVnJysQYMGqUqVKoqLi8vzOO3atdP48eP12muvOW7fe/nll1WxYkXVr19fkjRhwgRFRUWpVq1aOn/+vD744AMtXrxYP/7443WdY6tWrRQdHa2uXbtqwoQJunjxop555hm1aNFCjRo1ynd/SUlJysjI0N9//63Tp087FkWvV6+eJKl3796aPHmyBg0apCeeeEKLFy/WnDlzNG/ePEcf/fv3V7du3dSoUSM1btxYEyZM0JkzZ9S9e3dJUnBwsHr06KH+/furZMmSCgoKUt++fRUTE3PFq8oAAADMQigFAABcbtKkSRoyZIieeeYZHTlyRGXLllWvXr00dOhQSfarmX777Td9/PHHSk1NVdmyZdW6dWuNGDFCPj4+jn5iY2MVGRmp6dOn5zpOy5YtNWvWLI0ZM0ZjxoyRv7+/YmJiNH/+fPn5+UmyLzT+n//8RwcOHJC/v7/q1Kmjn376SXfccYejn+nTp6t79+4yDCPP52iz2TR37lz17dtXt99+uzw8PNSmTRtNmjSpAK+YdPfdd2vPnj2O7exQLbumqKgozZs3Ty+88IImTpyo8uXL64MPPnAK8R5++GEdPXpUQ4cO1aFDh1SvXj3Nnz/fafHz8ePHy8PDQ506dVJ6erri4uI0ZcqUAtUMAABwPWxGfv76AgAAsFDFihWVkJCg+Ph4U8cZNmyYli1bpqVLl5o6DgAAAP7BlVIAAKBQ2rp1q4KDg/X444+bPtYPP/ygyZMnmz4OAAAA/sGVUgAAAAAAALAc374HAAAAAAAAyxFKAQAAAAAAwHKEUgAAAAAAALAcoRQAAAAAAAAsRygFAAAAAAAAyxFKAQAAAAAAwHKEUgAAAAAAALAcoRQAAAAAAAAsRygFAAAAAAAAyxFKAQAAAAAAwHL/D+gyzfzFHZLCAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "fig, ax1 = plt.subplots(figsize=(12, 6))\n", "\n", @@ -384,7 +407,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -427,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -445,7 +468,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -587,16 +610,16 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 5, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" }, @@ -644,7 +667,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -662,7 +685,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -684,14 +707,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Standard test sequence\n", + "IEC 63556 - Standard test sequence\n", "\n", "![63556](63556.png)" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -822,7 +845,7 @@ "[72420 rows x 3 columns]" ] }, - "execution_count": 8, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -844,7 +867,7 @@ "\n", "\n", "### CALCULATION DOES NOT WORK IF RH IS 0, gives NaN dew point\n", - "### realisititally, RH will neverbe 0, should we approximate with a very low RH, ex. 0.1\n", + "### realistically, RH will neverbe 0, should we approximate with a very low RH, ex. 0.1\n", "### or should we use a normal indoor rh like 30 or 40\n", "### the test sequences never specify 0 RH, only that there is no active RH control\n", "### does this mean we can use a default in these cases\n", @@ -855,7 +878,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -864,7 +887,7 @@ "" ] }, - "execution_count": 9, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" }, @@ -886,7 +909,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -895,7 +918,7 @@ "" ] }, - "execution_count": 10, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" }, @@ -913,14 +936,15 @@ "source": [ "# must fix the nans so they do not propigate through our simulation\n", "# lets use a placeholder value of rh = 30 %\n", - "iec_63556[\"setpoint_relative_humidity\"] = iec_63556[\"setpoint_relative_humidity\"].apply(lambda x: 30 if pd.isna(x) else x) \n", + "# iec_63556[\"setpoint_relative_humidity\"] = iec_63556[\"setpoint_relative_humidity\"].apply(lambda x: 30 if pd.isna(x) else x) \n", + "iec_63556[\"setpoint_relative_humidity\"] = iec_63556[\"setpoint_relative_humidity\"].map(lambda x: 30 if pd.isna(x) else x) # map is faster and only works on pd.Series\n", "\n", "iec_63556[\"setpoint_relative_humidity\"].plot(title=\"rh setpoints : nans fixed\")" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -938,7 +962,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -958,7 +982,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -972,7 +996,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -992,7 +1016,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -1172,7 +1196,7 @@ "[72420 rows x 6 columns]" ] }, - "execution_count": 15, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -1186,7 +1210,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -1198,33 +1222,181 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 26, "metadata": {}, "outputs": [ { "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Sample TemperatureSample Relative HumidityEquilibrium Encapsulant WaterBack Encapsulant MoistureRelative Humidity Internal Cells Backside
0 days 00:00:0085.00000085.0000000.0056010.00560185.000000
0 days 00:01:0086.04533381.6605370.0054700.00552682.493425
0 days 00:02:0087.02325078.6740680.0053500.00542279.730607
0 days 00:03:0087.93809875.9947860.0052420.00531477.033270
0 days 00:04:0088.79394473.5840300.0051430.00520974.522821
..................
50 days 06:55:00-27.22345226.1134430.0001330.00018436.336043
50 days 06:56:00-27.16578532.6575920.0001660.00018436.261838
50 days 06:57:00-25.90500036.9052420.0001960.00018434.783481
50 days 06:58:00-24.54844142.0888190.0002330.00018533.286602
50 days 06:59:00-23.08771148.2666440.0002810.00018531.778878
\n", + "

72420 rows × 5 columns

\n", + "
" + ], "text/plain": [ - "0 days 00:00:00 85.000000\n", - "0 days 00:01:00 82.493425\n", - "0 days 00:02:00 79.730607\n", - "0 days 00:03:00 77.033270\n", - "0 days 00:04:00 74.522821\n", - " ... \n", - "50 days 06:55:00 36.336043\n", - "50 days 06:56:00 36.261838\n", - "50 days 06:57:00 34.783481\n", - "50 days 06:58:00 33.286602\n", - "50 days 06:59:00 31.778878\n", - "Freq: min, Name: Relative Humidity Internal Cells Backside, Length: 72420, dtype: float64" + " Sample Temperature Sample Relative Humidity \\\n", + "0 days 00:00:00 85.000000 85.000000 \n", + "0 days 00:01:00 86.045333 81.660537 \n", + "0 days 00:02:00 87.023250 78.674068 \n", + "0 days 00:03:00 87.938098 75.994786 \n", + "0 days 00:04:00 88.793944 73.584030 \n", + "... ... ... \n", + "50 days 06:55:00 -27.223452 26.113443 \n", + "50 days 06:56:00 -27.165785 32.657592 \n", + "50 days 06:57:00 -25.905000 36.905242 \n", + "50 days 06:58:00 -24.548441 42.088819 \n", + "50 days 06:59:00 -23.087711 48.266644 \n", + "\n", + " Equilibrium Encapsulant Water Back Encapsulant Moisture \\\n", + "0 days 00:00:00 0.005601 0.005601 \n", + "0 days 00:01:00 0.005470 0.005526 \n", + "0 days 00:02:00 0.005350 0.005422 \n", + "0 days 00:03:00 0.005242 0.005314 \n", + "0 days 00:04:00 0.005143 0.005209 \n", + "... ... ... \n", + "50 days 06:55:00 0.000133 0.000184 \n", + "50 days 06:56:00 0.000166 0.000184 \n", + "50 days 06:57:00 0.000196 0.000184 \n", + "50 days 06:58:00 0.000233 0.000185 \n", + "50 days 06:59:00 0.000281 0.000185 \n", + "\n", + " Relative Humidity Internal Cells Backside \n", + "0 days 00:00:00 85.000000 \n", + "0 days 00:01:00 82.493425 \n", + "0 days 00:02:00 79.730607 \n", + "0 days 00:03:00 77.033270 \n", + "0 days 00:04:00 74.522821 \n", + "... ... \n", + "50 days 06:55:00 36.336043 \n", + "50 days 06:56:00 36.261838 \n", + "50 days 06:57:00 34.783481 \n", + "50 days 06:58:00 33.286602 \n", + "50 days 06:59:00 31.778878 \n", + "\n", + "[72420 rows x 5 columns]" ] }, - "execution_count": 20, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "res[\"Relative Humidity Internal Cells Backside\"]" + "res" ] }, { @@ -1238,7 +1410,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 27, "metadata": {}, "outputs": [ { @@ -1267,118 +1439,487 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "wavelengths = scaled_spectrum.index.values\n", - "spectra = scaled_spectrum.values\n" + "spectra = scaled_spectrum.values" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is an approximation of incoming spectrum near mid latitudes using a reference spectrum provided by pvlib and scaled to a total irradiance of 1600 w/m^2. Ideally we look at just UV but this is a very rough approximation of the full spectrum. " + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "# intitialize zeros\n", + "zeros = np.zeros((iec_63556.shape[0], wavelengths.size))\n", + "\n", + "# determine where input has irradiance inputs and populate values\n", + "mask = iec_63556.setpoint_irradiance_full == 1600 # we should consider scaling, not just 1600 but this is fine for now, irradiance is either on or off\n", + "zeros[mask, :] = scaled_spectrum\n", + "\n", + "# construct dataframe, with timedelta index and wavelength column names\n", + "irr = pd.DataFrame(data=zeros, index=iec_63556.index, columns=wavelengths)\n", + "\n", + "# convert index to datetime using an arbitrary year (should not be a leap year)\n", + "datetime_index = pd.Timestamp(\"01-01-2001 00:00:00\") + res.index\n", + "irr.index = datetime_index\n", + "\n", + "# uncomment to view\n", + "# irr" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We must provide sample temperatures and relative humidities for the sample. We will use RH internal cells backside as it is representative of the internal conditions that directly contribute to degradation inside of a module. \n", + "\n", + "*the dataframe we provide to the function must have the appropriate column names, \"temperature\" and \"relative_humidity\"* \n", + "*the arrhenius equation uses R in units of [kJ / mol K] so temperature must be provided in Kelvin, **we must convert to K*** " ] }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 30, "metadata": {}, "outputs": [ { "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
temperaturerelative_humidity
0 days 00:00:00358.15000085.000000
0 days 00:01:00359.19533382.493425
0 days 00:02:00360.17325079.730607
0 days 00:03:00361.08809877.033270
0 days 00:04:00361.94394474.522821
.........
50 days 06:55:00245.92654836.336043
50 days 06:56:00245.98421536.261838
50 days 06:57:00247.24500034.783481
50 days 06:58:00248.60155933.286602
50 days 06:59:00250.06228931.778878
\n", + "

72420 rows × 2 columns

\n", + "
" + ], "text/plain": [ - "array([[7.54775226e-23, 1.96347813e-21, 9.07711778e-21, ...,\n", - " 1.17618834e-02, 1.15029474e-02, 1.13343119e-02]])" + " temperature relative_humidity\n", + "0 days 00:00:00 358.150000 85.000000\n", + "0 days 00:01:00 359.195333 82.493425\n", + "0 days 00:02:00 360.173250 79.730607\n", + "0 days 00:03:00 361.088098 77.033270\n", + "0 days 00:04:00 361.943944 74.522821\n", + "... ... ...\n", + "50 days 06:55:00 245.926548 36.336043\n", + "50 days 06:56:00 245.984215 36.261838\n", + "50 days 06:57:00 247.245000 34.783481\n", + "50 days 06:58:00 248.601559 33.286602\n", + "50 days 06:59:00 250.062289 31.778878\n", + "\n", + "[72420 rows x 2 columns]" ] }, - "execution_count": 46, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "pd.DataFrame(data=[spectra],columns=wavelengths).values" + "# combine the pandas series into a single dataframe\n", + "conditions_df = pd.concat([res[\"Sample Temperature\"], res[\"Relative Humidity Internal Cells Backside\"]], axis=1)\n", + "\n", + "# rename columns to match requiured names in dataframe input to pvdeg.degradation.degradation\n", + "conditions_df.columns = [\"temperature\", \"relative_humidity\"]\n", + "\n", + "# convert to kelvin\n", + "conditions_df[\"temperature\"] += 273.15\n", + "\n", + "# uncomment to view dataframe\n", + "conditions_df" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "metadata": {}, "outputs": [ { - "ename": "ValueError", - "evalue": "Length mismatch: Expected axis has 1 elements, new values have 2002 elements", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[45], line 5\u001b[0m\n\u001b[0;32m 1\u001b[0m spectra \u001b[38;5;241m=\u001b[39m pd\u001b[38;5;241m.\u001b[39mSeries(data\u001b[38;5;241m=\u001b[39mspectra, index\u001b[38;5;241m=\u001b[39mwavelengths)\n\u001b[0;32m 4\u001b[0m irr \u001b[38;5;241m=\u001b[39m pd\u001b[38;5;241m.\u001b[39mDataFrame(spectra\u001b[38;5;241m.\u001b[39mtolist(), index\u001b[38;5;241m=\u001b[39mspectra\u001b[38;5;241m.\u001b[39mindex)\n\u001b[1;32m----> 5\u001b[0m irr\u001b[38;5;241m.\u001b[39mcolumns \u001b[38;5;241m=\u001b[39m wavelengths\n\u001b[0;32m 7\u001b[0m irr\n", - "File \u001b[1;32mc:\\Users\\tford\\AppData\\Local\\miniconda3\\envs\\deg\\lib\\site-packages\\pandas\\core\\generic.py:6313\u001b[0m, in \u001b[0;36mNDFrame.__setattr__\u001b[1;34m(self, name, value)\u001b[0m\n\u001b[0;32m 6311\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 6312\u001b[0m \u001b[38;5;28mobject\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__getattribute__\u001b[39m(\u001b[38;5;28mself\u001b[39m, name)\n\u001b[1;32m-> 6313\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mobject\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;21;43m__setattr__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvalue\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 6314\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mAttributeError\u001b[39;00m:\n\u001b[0;32m 6315\u001b[0m \u001b[38;5;28;01mpass\u001b[39;00m\n", - "File \u001b[1;32mproperties.pyx:69\u001b[0m, in \u001b[0;36mpandas._libs.properties.AxisProperty.__set__\u001b[1;34m()\u001b[0m\n", - "File \u001b[1;32mc:\\Users\\tford\\AppData\\Local\\miniconda3\\envs\\deg\\lib\\site-packages\\pandas\\core\\generic.py:814\u001b[0m, in \u001b[0;36mNDFrame._set_axis\u001b[1;34m(self, axis, labels)\u001b[0m\n\u001b[0;32m 809\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 810\u001b[0m \u001b[38;5;124;03mThis is called from the cython code when we set the `index` attribute\u001b[39;00m\n\u001b[0;32m 811\u001b[0m \u001b[38;5;124;03mdirectly, e.g. `series.index = [1, 2, 3]`.\u001b[39;00m\n\u001b[0;32m 812\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 813\u001b[0m labels \u001b[38;5;241m=\u001b[39m ensure_index(labels)\n\u001b[1;32m--> 814\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_mgr\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mset_axis\u001b[49m\u001b[43m(\u001b[49m\u001b[43maxis\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlabels\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 815\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_clear_item_cache()\n", - "File \u001b[1;32mc:\\Users\\tford\\AppData\\Local\\miniconda3\\envs\\deg\\lib\\site-packages\\pandas\\core\\internals\\managers.py:238\u001b[0m, in \u001b[0;36mBaseBlockManager.set_axis\u001b[1;34m(self, axis, new_labels)\u001b[0m\n\u001b[0;32m 236\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mset_axis\u001b[39m(\u001b[38;5;28mself\u001b[39m, axis: AxisInt, new_labels: Index) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 237\u001b[0m \u001b[38;5;66;03m# Caller is responsible for ensuring we have an Index object.\u001b[39;00m\n\u001b[1;32m--> 238\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_validate_set_axis\u001b[49m\u001b[43m(\u001b[49m\u001b[43maxis\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnew_labels\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 239\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39maxes[axis] \u001b[38;5;241m=\u001b[39m new_labels\n", - "File \u001b[1;32mc:\\Users\\tford\\AppData\\Local\\miniconda3\\envs\\deg\\lib\\site-packages\\pandas\\core\\internals\\base.py:98\u001b[0m, in \u001b[0;36mDataManager._validate_set_axis\u001b[1;34m(self, axis, new_labels)\u001b[0m\n\u001b[0;32m 95\u001b[0m \u001b[38;5;28;01mpass\u001b[39;00m\n\u001b[0;32m 97\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m new_len \u001b[38;5;241m!=\u001b[39m old_len:\n\u001b[1;32m---> 98\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[0;32m 99\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mLength mismatch: Expected axis has \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mold_len\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m elements, new \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 100\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mvalues have \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mnew_len\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m elements\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 101\u001b[0m )\n", - "\u001b[1;31mValueError\u001b[0m: Length mismatch: Expected axis has 1 elements, new values have 2002 elements" - ] + "data": { + "text/plain": [ + "0.00013780131919471138" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "spectra = pd.Series(data=spectra, index=wavelengths)\n", + "# this may not calculate correctly with respect to timesteps\n", + "chamber_res = pvdeg.degradation.degradation(\n", + " spectra_df=irr, \n", + " conditions_df=conditions_df, # sourced from sample_temp and internal rh backside cells\n", "\n", + " # mike provided these constants\n", + " Ea=38,\n", + " p=0.5, # default\n", + " C2=0.07, # default\n", + " C=1,\n", + " n=0, # no dependence on RH\n", + ")\n", "\n", - "irr = pd.DataFrame(data=spectra.tolist(), index=spectra.index)\n", - "irr.columns = wavelengths\n", + "chamber_res" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Simple Calculation Compared to Miami\n", "\n", - "irr" + "How can we calculate degradation in the chamber, and degradation in miami\n" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Removing brackets from spectral irradiance data\n" + " \r" + ] + } + ], + "source": [ + "weather_db = 'PSM3'\n", + "weather_id = (25.783388, -80.189029) # Miami\n", + "weather_arg = {'api_key': 'DEMO_KEY',\n", + " 'email': 'user@mail.com',\n", + " 'names': 'tmy',\n", + " 'attributes': [],\n", + " 'map_variables': True}\n", + "\n", + "weather_df, meta = pvdeg.weather.get(weather_db, weather_id, **weather_arg)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We need to calculate some parameters to be used for inputs for the degradation model, our chamber simulation above, provided these for our setpoints so we got to circumvent these manual steps but we will calculate the following for our weather data from the NSRDB, PSM3 dataset. \n", + "\n", + "- module temperature\n", + "- module internal rh\n", + "- timeseries spectra" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The array tilt angle was not provided, therefore the latitude tilt of 25.8 was used.\n", + "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n" ] }, { - "ename": "AttributeError", - "evalue": "'numpy.ndarray' object has no attribute 'str'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", - "File \u001b[1;32m~\\dev\\PVDegradationTools\\pvdeg\\degradation.py:929\u001b[0m, in \u001b[0;36mdegradation\u001b[1;34m(spectra, rh_module, temp_module, wavelengths, Ea, n, p, C2, C)\u001b[0m\n\u001b[0;32m 928\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 929\u001b[0m irr \u001b[38;5;241m=\u001b[39m pd\u001b[38;5;241m.\u001b[39mDataFrame(spectra\u001b[38;5;241m.\u001b[39mtolist(), index\u001b[38;5;241m=\u001b[39m\u001b[43mspectra\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mindex\u001b[49m)\n\u001b[0;32m 930\u001b[0m irr\u001b[38;5;241m.\u001b[39mcolumns \u001b[38;5;241m=\u001b[39m wavelengths\n", - "\u001b[1;31mAttributeError\u001b[0m: 'numpy.ndarray' object has no attribute 'index'", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[27], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[43mpvdeg\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdegradation\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdegradation\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 2\u001b[0m \u001b[43m \u001b[49m\u001b[43mspectra\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mspectra\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 3\u001b[0m \u001b[43m \u001b[49m\u001b[43mwavelengths\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mwavelengths\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 4\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# should we use sample rh instead\u001b[39;49;00m\n\u001b[0;32m 5\u001b[0m \u001b[43m \u001b[49m\u001b[43mrh_module\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mchamber_63556\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrelative_humidity_internal_on_back_of_cells\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# this does not matter because we are using n = 0, look at equation\u001b[39;49;00m\n\u001b[0;32m 6\u001b[0m \u001b[43m \u001b[49m\u001b[43mtemp_module\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mchamber_63556\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msample_temperature\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 7\u001b[0m \n\u001b[0;32m 8\u001b[0m \u001b[43m \u001b[49m\u001b[43mp\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m0.5\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# default\u001b[39;49;00m\n\u001b[0;32m 9\u001b[0m \u001b[43m \u001b[49m\u001b[43mEa\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m38\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 10\u001b[0m \u001b[43m \u001b[49m\u001b[43mC2\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m0.07\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# default\u001b[39;49;00m\n\u001b[0;32m 11\u001b[0m \u001b[43m \u001b[49m\u001b[43mn\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# ignore RH for nowe\u001b[39;49;00m\n\u001b[0;32m 12\u001b[0m \u001b[43m)\u001b[49m\n", - "File \u001b[1;32m~\\dev\\PVDegradationTools\\pvdeg\\degradation.py:935\u001b[0m, in \u001b[0;36mdegradation\u001b[1;34m(spectra, rh_module, temp_module, wavelengths, Ea, n, p, C2, C)\u001b[0m\n\u001b[0;32m 933\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mRemoving brackets from spectral irradiance data\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 934\u001b[0m \u001b[38;5;66;03m# irr = data['spectra'].str.strip('[]').str.split(',', expand=True).astype(float)\u001b[39;00m\n\u001b[1;32m--> 935\u001b[0m irr \u001b[38;5;241m=\u001b[39m \u001b[43mspectra\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstr\u001b[49m\u001b[38;5;241m.\u001b[39mstrip(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m[]\u001b[39m\u001b[38;5;124m\"\u001b[39m)\u001b[38;5;241m.\u001b[39mstr\u001b[38;5;241m.\u001b[39msplit(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m,\u001b[39m\u001b[38;5;124m\"\u001b[39m, expand\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\u001b[38;5;241m.\u001b[39mastype(\u001b[38;5;28mfloat\u001b[39m)\n\u001b[0;32m 936\u001b[0m irr\u001b[38;5;241m.\u001b[39mcolumns \u001b[38;5;241m=\u001b[39m wavelengths\n\u001b[0;32m 938\u001b[0m sensitivitywavelengths \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mexp(\u001b[38;5;241m-\u001b[39mC2 \u001b[38;5;241m*\u001b[39m wavelengths)\n", - "\u001b[1;31mAttributeError\u001b[0m: 'numpy.ndarray' object has no attribute 'str'" + "data": { + "text/plain": [ + "2001-01-01 00:30:00 22.0\n", + "2001-01-01 01:30:00 21.0\n", + "2001-01-01 02:30:00 21.0\n", + "2001-01-01 03:30:00 21.0\n", + "2001-01-01 04:30:00 21.0\n", + " ... \n", + "2001-12-31 19:30:00 22.0\n", + "2001-12-31 20:30:00 22.0\n", + "2001-12-31 21:30:00 22.0\n", + "2001-12-31 22:30:00 22.0\n", + "2001-12-31 23:30:00 22.0\n", + "Freq: h, Length: 8760, dtype: float64" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# calculate module temperature\n", + "temp_module = pvdeg.temperature.temperature(\n", + " weather_df=weather_df,\n", + " meta=meta,\n", + " cell_or_mod=\"module\"\n", + ")\n", + "\n", + "# fix index, tmy data has non-uniform timeseries data as a part of the way it is sampled, we want a consistently increasing index\n", + "uniform_index = pd.Timestamp(\"2001-01-01 00:30:00\") + pd.timedelta_range(start=\"0 days\", periods=len(temp_module), freq=\"1h\")\n", + "temp_module.index = uniform_index\n", + "\n", + "temp_module" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The array tilt angle was not provided, therefore the latitude tilt of 25.8 was used.\n" ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
RH_surface_outsideRH_front_encapRH_back_encapRH_backsheet
2001-01-01 00:30:0073.28896565.35873073.28896573.288965
2001-01-01 01:30:0077.91515866.89112375.17585876.545508
2001-01-01 02:30:0077.91515866.89112375.33465576.624907
2001-01-01 03:30:0077.91515866.89112375.48424776.699703
2001-01-01 04:30:0073.11466066.89112375.34688274.230771
...............
2001-12-31 19:30:0078.06286465.35873050.26606464.164464
2001-12-31 20:30:0078.06286465.35873051.96524665.014055
2001-12-31 21:30:0078.06286465.35873053.56055865.811711
2001-12-31 22:30:0078.06286465.35873055.05835266.560608
2001-12-31 23:30:0073.28896565.35873056.17276564.730865
\n", + "

8760 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " RH_surface_outside RH_front_encap RH_back_encap \\\n", + "2001-01-01 00:30:00 73.288965 65.358730 73.288965 \n", + "2001-01-01 01:30:00 77.915158 66.891123 75.175858 \n", + "2001-01-01 02:30:00 77.915158 66.891123 75.334655 \n", + "2001-01-01 03:30:00 77.915158 66.891123 75.484247 \n", + "2001-01-01 04:30:00 73.114660 66.891123 75.346882 \n", + "... ... ... ... \n", + "2001-12-31 19:30:00 78.062864 65.358730 50.266064 \n", + "2001-12-31 20:30:00 78.062864 65.358730 51.965246 \n", + "2001-12-31 21:30:00 78.062864 65.358730 53.560558 \n", + "2001-12-31 22:30:00 78.062864 65.358730 55.058352 \n", + "2001-12-31 23:30:00 73.288965 65.358730 56.172765 \n", + "\n", + " RH_backsheet \n", + "2001-01-01 00:30:00 73.288965 \n", + "2001-01-01 01:30:00 76.545508 \n", + "2001-01-01 02:30:00 76.624907 \n", + "2001-01-01 03:30:00 76.699703 \n", + "2001-01-01 04:30:00 74.230771 \n", + "... ... \n", + "2001-12-31 19:30:00 64.164464 \n", + "2001-12-31 20:30:00 65.014055 \n", + "2001-12-31 21:30:00 65.811711 \n", + "2001-12-31 22:30:00 66.560608 \n", + "2001-12-31 23:30:00 64.730865 \n", + "\n", + "[8760 rows x 4 columns]" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "pvdeg.degradation.degradation(\n", - " spectra=spectra,\n", - " wavelengths=wavelengths,\n", - " # should we use sample rh instead\n", - " rh_module=chamber_63556.relative_humidity_internal_on_back_of_cells, # this does not matter because we are using n = 0, look at equation\n", - " temp_module=chamber_63556.sample_temperature,\n", + "rh_module = pvdeg.humidity.module(weather_df=weather_df, meta=meta)\n", "\n", - " p=0.5, # default\n", - " Ea=38,\n", - " C2=0.07, # default\n", - " n=0, # ignore RH for nowe\n", - ")\n" + "# fix index using same index as above\n", + "rh_module.index = pd.Timestamp(\"2001-01-01 00:30:00\") + pd.timedelta_range(start=\"0 days\", periods=len(rh_module), freq=\"1h\")\n", + "\n", + "rh_module" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Simple Calculation Compared to Miami\n", + "Spectrum Information: https://pvlib-python.readthedocs.io/en/stable/gallery/spectrum/plot_spectrl2_fig51A.html \n", "\n", - "How can we calculate degradation in the chamber, and degradation in miami\n" + "We will calculate the timeseries results for the spectra irradiance in w/m^2/nm from 300nm - 4000nm using pvlib. This will produce many results including the following \n", + "\n", + "``spectra.keys() = ['wavelength', 'dni_extra', 'dhi', 'dni', 'poa_sky_diffuse', 'poa_ground_diffuse', 'poa_direct', 'poa_global']``\n", + "\n", + "We will utilize the \"poa_global\" output later as it represents total plane of array irradiance (direct, diffuse and reflexted) so it will give us the best picture of how irradiance reaches the module in the outdoor environment. " ] }, { @@ -1387,71 +1928,517 @@ "metadata": {}, "outputs": [], "source": [ - "weather_db = 'PSM3'\n", - "weather_id = (25.783388, -80.189029)\n", - "weather_arg = {'api_key': 'DEMO_KEY',\n", - " 'email': 'user@mail.com',\n", - " 'names': 'tmy',\n", - " 'attributes': [],\n", - " 'map_variables': True}\n", + "# the metadata contains information that tells us we are in UTC-5, this corresponds to GMT+5\n", + "times = pd.date_range(\"2001-01-01 00:30:00\", freq='1h', periods=len(weather_df), tz=\"America/New_York\") # east coast time for miami, can replace with tz=\"Etc/GMT+5\"\n", + "solpos = solarposition.get_solarposition(times, latitude=meta[\"latitude\"], longitude=meta[\"longitude\"])\n", "\n", - "weather_df, meta = pvdeg.weather.get(weather_db, weather_id, **weather_arg)" + "tilt = 25.8\n", + "azimuth = 180\n", + "\n", + "# from nrel technical report used in the pvlib tutorial \n", + "# these could be gathered from other satellite sources\n", + "ozone = 0.31 # atm-cm, \n", + "tau500 = 0.1 \n", + "\n", + "aoi = irradiance.aoi(tilt, azimuth, solpos[\"apparent_zenith\"], solpos[\"azimuth\"])\n", + "\n", + "relative_airmass = atmosphere.get_relative_airmass(\n", + " solpos.apparent_zenith,\n", + " model='kasten1966'\n", + ")\n", + "\n", + "pwv = pvdeg.humidity.precipitable_water(\n", + " dew_point=weather_df[\"dew_point\"],\n", + " pressure=weather_df[\"pressure\"]\n", + ")\n", + "\n", + "spectra = spectrum.spectrl2(\n", + " # timeseries inputs\n", + " apparent_zenith=solpos[\"apparent_zenith\"],\n", + " relative_airmass=relative_airmass,\n", + " surface_pressure=weather_df[\"pressure\"] * 100, # pressure should be in pascals, nsrdb is in hPa\n", + " aoi=aoi,\n", + "\n", + " # scalars\n", + " surface_tilt=tilt,\n", + " ground_albedo=0.1, # mike said albedo of 10%\n", + " precipitable_water=pwv,\n", + " ozone=ozone,\n", + " aerosol_turbidity_500nm=tau500,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "``spectra`` is a 2d dictionary so we will unpack it into the correct output form for the ``spectra_df`` input of ``pvdeg.degradation.degradation``." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 57, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 300. , 305. , 310. , 315. , 320. , 325. , 330. , 335. ,\n", + " 340. , 345. , 350. , 360. , 370. , 380. , 390. , 400. ,\n", + " 410. , 420. , 430. , 440. , 450. , 460. , 470. , 480. ,\n", + " 490. , 500. , 510. , 520. , 530. , 540. , 550. , 570. ,\n", + " 593. , 610. , 630. , 656. , 667.6, 690. , 710. , 718. ,\n", + " 724.4, 740. , 752.5, 757.5, 762.5, 767.5, 780. , 800. ,\n", + " 816. , 823.7, 831.5, 840. , 860. , 880. , 905. , 915. ,\n", + " 925. , 930. , 937. , 948. , 965. , 980. , 993.5, 1040. ,\n", + " 1070. , 1100. , 1120. , 1130. , 1145. , 1161. , 1170. , 1200. ,\n", + " 1240. , 1270. , 1290. , 1320. , 1350. , 1395. , 1442.5, 1462.5,\n", + " 1477. , 1497. , 1520. , 1539. , 1558. , 1578. , 1592. , 1610. ,\n", + " 1630. , 1646. , 1678. , 1740. , 1800. , 1860. , 1920. , 1960. ,\n", + " 1985. , 2005. , 2035. , 2065. , 2100. , 2148. , 2198. , 2270. ,\n", + " 2360. , 2450. , 2500. , 2600. , 2700. , 2800. , 2900. , 3000. ,\n", + " 3100. , 3200. , 3300. , 3400. , 3500. , 3600. , 3700. , 3800. ,\n", + " 3900. , 4000. ])" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "def calculate_vapor_pressure(temp):\n", - " \"\"\"Calculate the saturation vapor pressure using air temperature.\"\"\"\n", - " return 6.11 * 10 ** (7.5 * temp / (237.3 + temp))\n", - "\n", - "def calculate_relative_humidity(dew_point, air_temp):\n", - " \"\"\"Calculate relative humidity.\"\"\"\n", - " avp = calculate_vapor_pressure(dew_point) # Actual Vapor Pressure\n", - " svp = calculate_vapor_pressure(air_temp) # Saturation Vapor Pressure\n", - " rh = (avp / svp) * 100 # Relative Humidity\n", - " return rh\n", + "# spectra.keys()\n", "\n", - "actual_rh = calculate_relative_humidity(chamber_63556.dew_point, chamber_63556.air_temperature)\n", - "\n", - "actual_rh" + "spectra[\"wavelength\"]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 67, "metadata": {}, - "outputs": [], - "source": [] + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
300.0305.0310.0315.0320.0325.0330.0335.0340.0345.0...3100.03200.03300.03400.03500.03600.03700.03800.03900.04000.0
2005-01-01 00:30:00-05:000.000000e+000.000000e+000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000...0.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000
2005-01-01 01:30:00-05:000.000000e+000.000000e+000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000...0.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000
2005-01-01 02:30:00-05:000.000000e+000.000000e+000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000...0.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000
2005-01-01 03:30:00-05:000.000000e+000.000000e+000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000...0.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000
2005-01-01 04:30:00-05:000.000000e+000.000000e+000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000...0.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000
2005-01-01 05:30:00-05:000.000000e+000.000000e+000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000...0.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000
2005-01-01 06:30:00-05:000.000000e+000.000000e+000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000...0.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000
2005-01-01 07:30:00-05:003.163809e-151.172403e-080.0000060.0003290.0016930.0067460.0149240.0187240.0202670.022052...0.0045750.0023910.0014740.0017050.0029320.0029640.0027870.0025070.0016860.001977
2005-01-01 08:30:00-05:006.790895e-072.517919e-040.0030430.0158450.0311390.0598680.0913060.1004120.1042280.111661...0.0098880.0067000.0049480.0050500.0062990.0060120.0055450.0049960.0038980.004022
2005-01-01 09:30:00-05:008.093579e-053.463083e-030.0177140.0535780.0853270.1401940.1980100.2127010.2196730.235010...0.0141850.0102380.0079040.0078270.0090330.0085060.0078080.0070410.0056960.005700
\n", + "

10 rows × 122 columns

\n", + "
" + ], + "text/plain": [ + " 300.0 305.0 310.0 315.0 \\\n", + "2005-01-01 00:30:00-05:00 0.000000e+00 0.000000e+00 0.000000 0.000000 \n", + "2005-01-01 01:30:00-05:00 0.000000e+00 0.000000e+00 0.000000 0.000000 \n", + "2005-01-01 02:30:00-05:00 0.000000e+00 0.000000e+00 0.000000 0.000000 \n", + "2005-01-01 03:30:00-05:00 0.000000e+00 0.000000e+00 0.000000 0.000000 \n", + "2005-01-01 04:30:00-05:00 0.000000e+00 0.000000e+00 0.000000 0.000000 \n", + "2005-01-01 05:30:00-05:00 0.000000e+00 0.000000e+00 0.000000 0.000000 \n", + "2005-01-01 06:30:00-05:00 0.000000e+00 0.000000e+00 0.000000 0.000000 \n", + "2005-01-01 07:30:00-05:00 3.163809e-15 1.172403e-08 0.000006 0.000329 \n", + "2005-01-01 08:30:00-05:00 6.790895e-07 2.517919e-04 0.003043 0.015845 \n", + "2005-01-01 09:30:00-05:00 8.093579e-05 3.463083e-03 0.017714 0.053578 \n", + "\n", + " 320.0 325.0 330.0 335.0 340.0 \\\n", + "2005-01-01 00:30:00-05:00 0.000000 0.000000 0.000000 0.000000 0.000000 \n", + "2005-01-01 01:30:00-05:00 0.000000 0.000000 0.000000 0.000000 0.000000 \n", + "2005-01-01 02:30:00-05:00 0.000000 0.000000 0.000000 0.000000 0.000000 \n", + "2005-01-01 03:30:00-05:00 0.000000 0.000000 0.000000 0.000000 0.000000 \n", + "2005-01-01 04:30:00-05:00 0.000000 0.000000 0.000000 0.000000 0.000000 \n", + "2005-01-01 05:30:00-05:00 0.000000 0.000000 0.000000 0.000000 0.000000 \n", + "2005-01-01 06:30:00-05:00 0.000000 0.000000 0.000000 0.000000 0.000000 \n", + "2005-01-01 07:30:00-05:00 0.001693 0.006746 0.014924 0.018724 0.020267 \n", + "2005-01-01 08:30:00-05:00 0.031139 0.059868 0.091306 0.100412 0.104228 \n", + "2005-01-01 09:30:00-05:00 0.085327 0.140194 0.198010 0.212701 0.219673 \n", + "\n", + " 345.0 ... 3100.0 3200.0 3300.0 \\\n", + "2005-01-01 00:30:00-05:00 0.000000 ... 0.000000 0.000000 0.000000 \n", + "2005-01-01 01:30:00-05:00 0.000000 ... 0.000000 0.000000 0.000000 \n", + "2005-01-01 02:30:00-05:00 0.000000 ... 0.000000 0.000000 0.000000 \n", + "2005-01-01 03:30:00-05:00 0.000000 ... 0.000000 0.000000 0.000000 \n", + "2005-01-01 04:30:00-05:00 0.000000 ... 0.000000 0.000000 0.000000 \n", + "2005-01-01 05:30:00-05:00 0.000000 ... 0.000000 0.000000 0.000000 \n", + "2005-01-01 06:30:00-05:00 0.000000 ... 0.000000 0.000000 0.000000 \n", + "2005-01-01 07:30:00-05:00 0.022052 ... 0.004575 0.002391 0.001474 \n", + "2005-01-01 08:30:00-05:00 0.111661 ... 0.009888 0.006700 0.004948 \n", + "2005-01-01 09:30:00-05:00 0.235010 ... 0.014185 0.010238 0.007904 \n", + "\n", + " 3400.0 3500.0 3600.0 3700.0 3800.0 \\\n", + "2005-01-01 00:30:00-05:00 0.000000 0.000000 0.000000 0.000000 0.000000 \n", + "2005-01-01 01:30:00-05:00 0.000000 0.000000 0.000000 0.000000 0.000000 \n", + "2005-01-01 02:30:00-05:00 0.000000 0.000000 0.000000 0.000000 0.000000 \n", + "2005-01-01 03:30:00-05:00 0.000000 0.000000 0.000000 0.000000 0.000000 \n", + "2005-01-01 04:30:00-05:00 0.000000 0.000000 0.000000 0.000000 0.000000 \n", + "2005-01-01 05:30:00-05:00 0.000000 0.000000 0.000000 0.000000 0.000000 \n", + "2005-01-01 06:30:00-05:00 0.000000 0.000000 0.000000 0.000000 0.000000 \n", + "2005-01-01 07:30:00-05:00 0.001705 0.002932 0.002964 0.002787 0.002507 \n", + "2005-01-01 08:30:00-05:00 0.005050 0.006299 0.006012 0.005545 0.004996 \n", + "2005-01-01 09:30:00-05:00 0.007827 0.009033 0.008506 0.007808 0.007041 \n", + "\n", + " 3900.0 4000.0 \n", + "2005-01-01 00:30:00-05:00 0.000000 0.000000 \n", + "2005-01-01 01:30:00-05:00 0.000000 0.000000 \n", + "2005-01-01 02:30:00-05:00 0.000000 0.000000 \n", + "2005-01-01 03:30:00-05:00 0.000000 0.000000 \n", + "2005-01-01 04:30:00-05:00 0.000000 0.000000 \n", + "2005-01-01 05:30:00-05:00 0.000000 0.000000 \n", + "2005-01-01 06:30:00-05:00 0.000000 0.000000 \n", + "2005-01-01 07:30:00-05:00 0.001686 0.001977 \n", + "2005-01-01 08:30:00-05:00 0.003898 0.004022 \n", + "2005-01-01 09:30:00-05:00 0.005696 0.005700 \n", + "\n", + "[10 rows x 122 columns]" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "miami_irr = pd.DataFrame(\n", + " data = np.asanyarray(spectra[\"poa_global\"]).T,\n", + " columns=spectra[\"wavelength\"],\n", + " index=weather_df.index,\n", + ")\n", + "\n", + "# the original produces rows with nan when there is no irradiance, set these to zero to avoid errors later\n", + "miami_irr = miami_irr.fillna(0)\n", + "\n", + "miami_irr.head(10)" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 68, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "2.002574069617825e-40" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "pvdeg.degradation.arrhenius_deg(\n", - " weather_df=weather_df,\n", - " meta=meta,\n", - " # calc rh outdoor?\n", - " \n", - " temp_chamber=chamber_63556.air_temperature, # must call calc_temps before this\n", - " I_chamber=chamber_63556.setpoints[\"setpoint_irradiance_full\"],\n", - " rh_chamber=actual_rh,\n", + "# once again we need to approximate the irradiance for each timestep\n", + "miami_res = pvdeg.degradation.degradation(\n", + " spectra_df=miami_irr,\n", + " # we calculated these above the irradiance calculation and they are representative of the conditions on the module\n", + " temp_module=temp_module,\n", + " rh_module=rh_module[\"RH_back_encap\"]\n", + ")\n", "\n", - " Ea=80, # sample arrhenius activation energy for a polymer\n", - ")" + "miami_res" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 70, "metadata": {}, - "outputs": [], - "source": [] + "outputs": [ + { + "data": { + "text/plain": [ + "6.881209603448508e+35" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "af = chamber_res / miami_res\n", + "\n", + "# this is extremely large\n", + "af" + ] } ], "metadata": { diff --git a/tutorials_and_tools/tutorials_and_tools/Geospatial Templates.ipynb b/tutorials_and_tools/tutorials_and_tools/Geospatial Templates.ipynb index b9b47c09..0ada7952 100644 --- a/tutorials_and_tools/tutorials_and_tools/Geospatial Templates.ipynb +++ b/tutorials_and_tools/tutorials_and_tools/Geospatial Templates.ipynb @@ -429,49 +429,49 @@ "Attributes:\n", " full_version_record: {"rex": "0.2.80", "pandas": "2.0.0", "numpy": "1.23...\n", " package: rex\n", - " version: 4.0.0
  • full_version_record :
    {"rex": "0.2.80", "pandas": "2.0.0", "numpy": "1.23.5", "python": "3.9.16 (main, Mar 8 2023, 14:00:05) \\n[GCC 11.2.0]", "click": "8.1.3", "h5py": "3.7.0", "h5pyd": "0.14.0", "scipy": "1.10.1"}
    package :
    rex
    version :
    4.0.0
  • " ], "text/plain": [ " Size: 9MB\n", @@ -689,7 +689,7 @@ { "data": { "text/plain": [ - "[]" + "[]" ] }, "execution_count": 7, @@ -698,7 +698,7 @@ }, { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
    " ] @@ -747,7 +747,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Geospatial Cell Temperature Calculation" + "## Geospatial Cell Temperature Calculation\n", + "As shown below, we have two options, we can choose to provide a template that is generated by a function which supports autotemplating. Or we can provide the function to `geospatial.analysis` and let it generate a template internally.\n", + "\n", + "### Providing a Template with `Geospatial.auto_template`" ] }, { @@ -1156,11 +1159,11 @@ " * longitude (longitude) float64 80B -106.4 -106.3 -106.3 ... -105.9 -105.9\n", " * time (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31T23:30:00\n", "Data variables:\n", - " cell (time, latitude, longitude) float64 11MB nan nan nan ... nan nan
  • " ], "text/plain": [ " Size: 11MB\n", @@ -1251,7 +1254,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Geospatial Module Temperature Calculation" + "### Analysis Without Providing a Template\n", + "\n", + "If a function is supported by `geospatial.auto_template` we do not need to create a template outside of the function as shown in the cell above. We can simply pass the function to `geospatial.analysis` and it will create a template for us." ] }, { @@ -1660,11 +1665,11 @@ " * longitude (longitude) float64 80B -106.4 -106.3 -106.3 ... -105.9 -105.9\n", " * time (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31T23:30:00\n", "Data variables:\n", - " module (time, latitude, longitude) float64 11MB nan nan nan ... nan nan
  • " ], "text/plain": [ " Size: 11MB\n", @@ -1727,7 +1732,7 @@ " * longitude (longitude) float64 80B -106.4 -106.3 -106.3 ... -105.9 -105.9\n", " * time (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31T23:30:00\n", "Data variables:\n", - " module (time, latitude, longitude) float64 11MB nan nan nan ... nan nan" + " cell (time, latitude, longitude) float64 11MB nan nan nan ... nan nan" ] }, "execution_count": 9, @@ -1735,6 +1740,26 @@ "output_type": "execute_result" } ], + "source": [ + "pvdeg.geospatial.analysis(\n", + " weather_ds=geo_weather,\n", + " meta_df=geo_meta,\n", + " func=pvdeg.temperature.cell,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Geospatial Module Temperature Calculation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "module_temp_template = pvdeg.geospatial.auto_template(\n", " func=pvdeg.temperature.module,\n", @@ -1758,3781 +1783,158 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
    \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
    <xarray.Dataset> Size: 67MB\n",
    -       "Dimensions:             (latitude: 8, longitude: 10, time: 17520)\n",
    -       "Coordinates:\n",
    -       "  * latitude            (latitude) float64 64B 39.41 39.45 39.53 ... 39.81 39.89\n",
    -       "  * longitude           (longitude) float64 80B -106.4 -106.3 ... -105.9 -105.9\n",
    -       "  * time                (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31...\n",
    -       "Data variables:\n",
    -       "    apparent_zenith     (time, latitude, longitude) float64 11MB nan nan ... nan\n",
    -       "    zenith              (time, latitude, longitude) float64 11MB nan nan ... nan\n",
    -       "    apparent_elevation  (time, latitude, longitude) float64 11MB nan nan ... nan\n",
    -       "    elevation           (time, latitude, longitude) float64 11MB nan nan ... nan\n",
    -       "    azimuth             (time, latitude, longitude) float64 11MB nan nan ... nan\n",
    -       "    equation_of_time    (time, latitude, longitude) float64 11MB nan nan ... nan
    " - ], - "text/plain": [ - " Size: 67MB\n", - "Dimensions: (latitude: 8, longitude: 10, time: 17520)\n", - "Coordinates:\n", - " * latitude (latitude) float64 64B 39.41 39.45 39.53 ... 39.81 39.89\n", - " * longitude (longitude) float64 80B -106.4 -106.3 ... -105.9 -105.9\n", - " * time (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31...\n", - "Data variables:\n", - " apparent_zenith (time, latitude, longitude) float64 11MB nan nan ... nan\n", - " zenith (time, latitude, longitude) float64 11MB nan nan ... nan\n", - " apparent_elevation (time, latitude, longitude) float64 11MB nan nan ... nan\n", - " elevation (time, latitude, longitude) float64 11MB nan nan ... nan\n", - " azimuth (time, latitude, longitude) float64 11MB nan nan ... nan\n", - " equation_of_time (time, latitude, longitude) float64 11MB nan nan ... nan" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "solar_position_template = pvdeg.geospatial.auto_template(\n", - " func=pvdeg.spectral.solar_position,\n", - " ds_gids=geo_weather\n", - ")\n", - "\n", - "pvdeg.geospatial.analysis(\n", - " weather_ds=geo_weather,\n", - " meta_df=geo_meta,\n", - " func=pvdeg.spectral.solar_position,\n", - " template=solar_position_template\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Geospatial POA Irradiance Calculation" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n" - ] - }, - { - "data": { - "text/html": [ - "
    \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
    <xarray.Dataset> Size: 56MB\n",
    -       "Dimensions:             (latitude: 8, longitude: 10, time: 17520)\n",
    -       "Coordinates:\n",
    -       "  * latitude            (latitude) float64 64B 39.41 39.45 39.53 ... 39.81 39.89\n",
    -       "  * longitude           (longitude) float64 80B -106.4 -106.3 ... -105.9 -105.9\n",
    -       "  * time                (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31...\n",
    -       "Data variables:\n",
    -       "    poa_global          (time, latitude, longitude) float64 11MB nan nan ... nan\n",
    -       "    poa_direct          (time, latitude, longitude) float64 11MB nan nan ... nan\n",
    -       "    poa_diffuse         (time, latitude, longitude) float64 11MB nan nan ... nan\n",
    -       "    poa_sky_diffuse     (time, latitude, longitude) float64 11MB nan nan ... nan\n",
    -       "    poa_ground_diffuse  (time, latitude, longitude) float64 11MB nan nan ... nan
    " - ], - "text/plain": [ - " Size: 56MB\n", - "Dimensions: (latitude: 8, longitude: 10, time: 17520)\n", - "Coordinates:\n", - " * latitude (latitude) float64 64B 39.41 39.45 39.53 ... 39.81 39.89\n", - " * longitude (longitude) float64 80B -106.4 -106.3 ... -105.9 -105.9\n", - " * time (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31...\n", - "Data variables:\n", - " poa_global (time, latitude, longitude) float64 11MB nan nan ... nan\n", - " poa_direct (time, latitude, longitude) float64 11MB nan nan ... nan\n", - " poa_diffuse (time, latitude, longitude) float64 11MB nan nan ... nan\n", - " poa_sky_diffuse (time, latitude, longitude) float64 11MB nan nan ... nan\n", - " poa_ground_diffuse (time, latitude, longitude) float64 11MB nan nan ... nan" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "poa_irradiance_template = pvdeg.geospatial.auto_template(\n", - " func=pvdeg.spectral.poa_irradiance,\n", - " ds_gids=geo_weather\n", - ")\n", - "\n", - "pvdeg.geospatial.analysis(\n", - " weather_ds=geo_weather,\n", - " meta_df=geo_meta,\n", - " func=pvdeg.spectral.poa_irradiance,\n", - " template=poa_irradiance_template\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Geospatial 98th Percentile Operating Temperature Calculation" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n" - ] - }, - { - "data": { - "text/html": [ - "
    \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
    <xarray.Dataset> Size: 784B\n",
    -       "Dimensions:       (latitude: 8, longitude: 10)\n",
    -       "Coordinates:\n",
    -       "  * latitude      (latitude) float64 64B 39.41 39.45 39.53 ... 39.69 39.81 39.89\n",
    -       "  * longitude     (longitude) float64 80B -106.4 -106.3 -106.3 ... -105.9 -105.9\n",
    -       "Data variables:\n",
    -       "    T98_estimate  (latitude, longitude) float64 640B nan nan nan ... nan nan nan
    " - ], - "text/plain": [ - " Size: 784B\n", - "Dimensions: (latitude: 8, longitude: 10)\n", - "Coordinates:\n", - " * latitude (latitude) float64 64B 39.41 39.45 39.53 ... 39.69 39.81 39.89\n", - " * longitude (longitude) float64 80B -106.4 -106.3 -106.3 ... -105.9 -105.9\n", - "Data variables:\n", - " T98_estimate (latitude, longitude) float64 640B nan nan nan ... nan nan nan" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "standoff_template = pvdeg.geospatial.auto_template(\n", - " func=pvdeg.standards.T98_estimate, \n", - " ds_gids=geo_weather\n", - " )\n", - "\n", - "pvdeg.geospatial.analysis(\n", - " weather_ds=geo_weather,\n", - " meta_df=geo_meta,\n", - " func=pvdeg.standards.T98_estimate,\n", - " template=standoff_template\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Geospatial Module Humidity Calculation" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n" - ] - }, - { - "data": { - "text/html": [ - "
    \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
    <xarray.Dataset> Size: 45MB\n",
    -       "Dimensions:             (latitude: 8, longitude: 10, time: 17520)\n",
    -       "Coordinates:\n",
    -       "  * latitude            (latitude) float64 64B 39.41 39.45 39.53 ... 39.81 39.89\n",
    -       "  * longitude           (longitude) float64 80B -106.4 -106.3 ... -105.9 -105.9\n",
    -       "  * time                (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31...\n",
    -       "Data variables:\n",
    -       "    RH_surface_outside  (time, latitude, longitude) float64 11MB nan nan ... nan\n",
    -       "    RH_front_encap      (time, latitude, longitude) float64 11MB nan nan ... nan\n",
    -       "    RH_back_encap       (time, latitude, longitude) float64 11MB nan nan ... nan\n",
    -       "    RH_backsheet        (time, latitude, longitude) float64 11MB nan nan ... nan
    " - ], - "text/plain": [ - " Size: 45MB\n", - "Dimensions: (latitude: 8, longitude: 10, time: 17520)\n", - "Coordinates:\n", - " * latitude (latitude) float64 64B 39.41 39.45 39.53 ... 39.81 39.89\n", - " * longitude (longitude) float64 80B -106.4 -106.3 ... -105.9 -105.9\n", - " * time (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31...\n", - "Data variables:\n", - " RH_surface_outside (time, latitude, longitude) float64 11MB nan nan ... nan\n", - " RH_front_encap (time, latitude, longitude) float64 11MB nan nan ... nan\n", - " RH_back_encap (time, latitude, longitude) float64 11MB nan nan ... nan\n", - " RH_backsheet (time, latitude, longitude) float64 11MB nan nan ... nan" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "humidity_template = pvdeg.geospatial.auto_template(\n", - " func=pvdeg.humidity.module,\n", - " ds_gids=geo_weather\n", - ")\n", - "\n", - "pvdeg.geospatial.analysis(\n", - " weather_ds=geo_weather,\n", - " meta_df=geo_meta,\n", - " func=pvdeg.humidity.module,\n", - " template=humidity_template\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Geospatial IwaVantHoff Environment Characterization Calculation" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n" - ] - }, - { - "data": { - "text/html": [ - "
    \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
    <xarray.Dataset> Size: 784B\n",
    -       "Dimensions:      (latitude: 8, longitude: 10)\n",
    -       "Coordinates:\n",
    -       "  * latitude     (latitude) float64 64B 39.41 39.45 39.53 ... 39.69 39.81 39.89\n",
    -       "  * longitude    (longitude) float64 80B -106.4 -106.3 -106.3 ... -105.9 -105.9\n",
    -       "Data variables:\n",
    -       "    IwaVantHoff  (latitude, longitude) float64 640B nan nan nan ... nan nan nan
    " - ], - "text/plain": [ - " Size: 784B\n", - "Dimensions: (latitude: 8, longitude: 10)\n", - "Coordinates:\n", - " * latitude (latitude) float64 64B 39.41 39.45 39.53 ... 39.69 39.81 39.89\n", - " * longitude (longitude) float64 80B -106.4 -106.3 -106.3 ... -105.9 -105.9\n", - "Data variables:\n", - " IwaVantHoff (latitude, longitude) float64 640B nan nan nan ... nan nan nan" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "iwa_vant_hoff_template = pvdeg.geospatial.auto_template(\n", - " func=pvdeg.degradation.IwaVantHoff,\n", - " ds_gids=geo_weather\n", - ")\n", - "\n", - "pvdeg.geospatial.analysis(\n", - " weather_ds=geo_weather,\n", - " meta_df=geo_meta,\n", - " func=pvdeg.degradation.IwaVantHoff,\n", - " template=iwa_vant_hoff_template\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Geospatial Edge Seal Width Calculation" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
    \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
    <xarray.Dataset> Size: 784B\n",
    -       "Dimensions:          (latitude: 8, longitude: 10)\n",
    -       "Coordinates:\n",
    -       "  * latitude         (latitude) float64 64B 39.41 39.45 39.53 ... 39.81 39.89\n",
    -       "  * longitude        (longitude) float64 80B -106.4 -106.3 ... -105.9 -105.9\n",
    -       "Data variables:\n",
    -       "    edge_seal_width  (latitude, longitude) float64 640B nan nan nan ... nan nan
    " - ], - "text/plain": [ - " Size: 784B\n", - "Dimensions: (latitude: 8, longitude: 10)\n", - "Coordinates:\n", - " * latitude (latitude) float64 64B 39.41 39.45 39.53 ... 39.81 39.89\n", - " * longitude (longitude) float64 80B -106.4 -106.3 ... -105.9 -105.9\n", - "Data variables:\n", - " edge_seal_width (latitude, longitude) float64 640B nan nan nan ... nan nan" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "edge_seal_template = pvdeg.geospatial.auto_template(\n", - " func=pvdeg.design.edge_seal_width,\n", - " ds_gids=geo_weather\n", - ")\n", - "\n", - "pvdeg.geospatial.analysis(\n", - " weather_ds=geo_weather,\n", - " meta_df=geo_meta,\n", - " func=pvdeg.design.edge_seal_width,\n", - " template=edge_seal_template\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
    \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
    <xarray.Dataset> Size: 176B\n",
    -       "Dimensions:  (gid: 11)\n",
    -       "Coordinates:\n",
    -       "  * gid      (gid) int64 88B 449211 452064 453020 ... 459670 460613 462498\n",
    -       "Data variables:\n",
    -       "    width    (gid) float64 88B dask.array<chunksize=(11,), meta=np.ndarray>
    " - ], - "text/plain": [ - " Size: 176B\n", - "Dimensions: (gid: 11)\n", - "Coordinates:\n", - " * gid (gid) int64 88B 449211 452064 453020 ... 459670 460613 462498\n", - "Data variables:\n", - " width (gid) float64 88B dask.array" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], + "source": [ + "solar_position_template = pvdeg.geospatial.auto_template(\n", + " func=pvdeg.spectral.solar_position,\n", + " ds_gids=geo_weather\n", + ")\n", + "\n", + "pvdeg.geospatial.analysis(\n", + " weather_ds=geo_weather,\n", + " meta_df=geo_meta,\n", + " func=pvdeg.spectral.solar_position,\n", + " template=solar_position_template\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Geospatial POA Irradiance Calculation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "poa_irradiance_template = pvdeg.geospatial.auto_template(\n", + " func=pvdeg.spectral.poa_irradiance,\n", + " ds_gids=geo_weather\n", + ")\n", + "\n", + "pvdeg.geospatial.analysis(\n", + " weather_ds=geo_weather,\n", + " meta_df=geo_meta,\n", + " func=pvdeg.spectral.poa_irradiance,\n", + " template=poa_irradiance_template\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Geospatial 98th Percentile Operating Temperature Calculation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "standoff_template = pvdeg.geospatial.auto_template(\n", + " func=pvdeg.standards.T98_estimate, \n", + " ds_gids=geo_weather\n", + " )\n", + "\n", + "pvdeg.geospatial.analysis(\n", + " weather_ds=geo_weather,\n", + " meta_df=geo_meta,\n", + " func=pvdeg.standards.T98_estimate,\n", + " template=standoff_template\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Geospatial Module Humidity Calculation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "humidity_template = pvdeg.geospatial.auto_template(\n", + " func=pvdeg.humidity.module,\n", + " ds_gids=geo_weather\n", + ")\n", + "\n", + "pvdeg.geospatial.analysis(\n", + " weather_ds=geo_weather,\n", + " meta_df=geo_meta,\n", + " func=pvdeg.humidity.module,\n", + " template=humidity_template\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Geospatial IwaVantHoff Environment Characterization Calculation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "iwa_vant_hoff_template = pvdeg.geospatial.auto_template(\n", + " func=pvdeg.degradation.IwaVantHoff,\n", + " ds_gids=geo_weather\n", + ")\n", + "\n", + "pvdeg.geospatial.analysis(\n", + " weather_ds=geo_weather,\n", + " meta_df=geo_meta,\n", + " func=pvdeg.degradation.IwaVantHoff,\n", + " template=iwa_vant_hoff_template\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Geospatial Edge Seal Width Calculation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "edge_seal_template = pvdeg.geospatial.auto_template(\n", + " func=pvdeg.design.edge_seal_width,\n", + " ds_gids=geo_weather\n", + ")\n", + "\n", + "pvdeg.geospatial.analysis(\n", + " weather_ds=geo_weather,\n", + " meta_df=geo_meta,\n", + " func=pvdeg.design.edge_seal_width,\n", + " template=edge_seal_template\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "edge_seal_template" ] @@ -5547,9 +1949,9 @@ ], "metadata": { "kernelspec": { - "display_name": "fem_diff", + "display_name": "rpp", "language": "python", - "name": "python3" + "name": "rpp" }, "language_info": { "codemirror_mode": { @@ -5565,5 +1967,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/tutorials_and_tools/tutorials_and_tools/Scenario - Geospatial.ipynb b/tutorials_and_tools/tutorials_and_tools/Scenario - Geospatial.ipynb index 805dcdce..322aa306 100644 --- a/tutorials_and_tools/tutorials_and_tools/Scenario - Geospatial.ipynb +++ b/tutorials_and_tools/tutorials_and_tools/Scenario - Geospatial.ipynb @@ -48,7 +48,7 @@ "text": [ "/home/tford/.conda-envs/rpp/lib/python3.10/site-packages/xarray/core/dataset.py:274: UserWarning: The specified chunks separate the stored chunks along dimension \"phony_dim_1\" starting at index 500. This could degrade performance. Instead, consider rechunking after loading.\n", " warnings.warn(\n", - "/home/tford/dev/PVDegradationTools/pvdeg/scenario.py:1237: UserWarning: Gids Added - [449212 454915 460611]\n", + "/home/tford/dev/PVDegradationTools/pvdeg/scenario.py:1248: UserWarning: Gids Added - [449212 454915 460611]\n", " warnings.warn(message, UserWarning)\n" ] } @@ -57,7 +57,8 @@ "geospatial_standoff_scenario.addLocation(\n", " state='Colorado',\n", " county='Summit',\n", - " see_added=True\n", + " see_added=True,\n", + " downsample_factor=3\n", ")" ] }, @@ -80,8 +81,14 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/tford/dev/PVDegradationTools/pvdeg/scenario.py:1626: UserWarning: standoff added to pipeline as \n", - " {'geospatial_job': {'job': , 'params': {}}}\n", + "/home/tford/dev/PVDegradationTools/pvdeg/scenario.py:1635: UserWarning: standoff added to scenario with arguments {} using template: Size: 96B\n", + "Dimensions: (gid: 3)\n", + "Coordinates:\n", + " * gid (gid) int64 24B 449212 454915 460611\n", + "Data variables:\n", + " x (gid) float64 24B dask.array\n", + " T98_0 (gid) float64 24B dask.array\n", + " T98_inf (gid) float64 24B dask.array\n", " warnings.warn(message, UserWarning)\n" ] } @@ -99,38 +106,1431 @@ "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Name : standoff geospatial\n", - "Pipeline : \n", - " geospatial_job.job\n", - "0 \n", - "Results : Pipeline results : \n", - "Pipeline has not been run\n", - "'gids : [449212 454915 460611]'\n", - "'test modules :'\n", - "scenario weather : Size: 2TB\n", - "Dimensions: (time: 17520, gid: 2018267)\n", - "Coordinates:\n", - " * gid (gid) int64 16MB 0 1 2 3 ... 2018264 2018265 2018266\n", - " * time (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31T...\n", - "Data variables:\n", - " temp_air (time, gid) float64 283GB dask.array\n", - " wind_speed (time, gid) float64 283GB dask.array\n", - " dhi (time, gid) float64 283GB dask.array\n", - " ghi (time, gid) float64 283GB dask.array\n", - " dni (time, gid) float64 283GB dask.array\n", - " relative_humidity (time, gid) float64 283GB dask.array\n", - "Attributes:\n", - " full_version_record: {\"rex\": \"0.2.80\", \"pandas\": \"2.0.0\", \"numpy\": \"1.23...\n", - " package: rex\n", - " version: 4.0.0\n" - ] + "data": { + "text/html": [ + "\n", + "
    \n", + "

    standoff geospatial: Scenario Analysis

    \n", + "

    Path: /home/tford/dev/PVDegradationTools/tutorials_and_tools/tutorials_and_tools/pvd_job_standoff geospatial

    \n", + "

    HPC Configuration: False

    \n", + "

    GIDs: [449212 454915 460611]

    \n", + "
    \n", + "

    Results

    \n", + " None\n", + "
    \n", + "
    \n", + "

    Geospatial Job

    \n", + " Function : standoff\n", + " \n", + "
    \n", + "

    \n", + " \n", + " Template\n", + "

    \n", + "
    \n", + "
    \n", + "
    \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
    <xarray.Dataset> Size: 96B\n",
    +       "Dimensions:  (gid: 3)\n",
    +       "Coordinates:\n",
    +       "  * gid      (gid) int64 24B 449212 454915 460611\n",
    +       "Data variables:\n",
    +       "    x        (gid) float64 24B dask.array<chunksize=(1,), meta=np.ndarray>\n",
    +       "    T98_0    (gid) float64 24B dask.array<chunksize=(1,), meta=np.ndarray>\n",
    +       "    T98_inf  (gid) float64 24B dask.array<chunksize=(1,), meta=np.ndarray>
    \n", + "
    \n", + " \n", + "
    \n", + "
    \n", + "

    Modules

    \n", + "
    \n", + "
    \n", + "
    \n", + "

    Weather Dataset

    \n", + " \n", + "
    \n", + "

    \n", + " \n", + " Weather Data\n", + "

    \n", + "
    \n", + "
    \n", + "
    \n", + "
    \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
    <xarray.Dataset> Size: 3MB\n",
    +       "Dimensions:            (time: 17520, gid: 3)\n",
    +       "Coordinates:\n",
    +       "  * gid                (gid) int64 24B 449212 454915 460611\n",
    +       "  * time               (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31T...\n",
    +       "Data variables:\n",
    +       "    temp_air           (time, gid) float64 420kB dask.array<chunksize=(17520, 1), meta=np.ndarray>\n",
    +       "    wind_speed         (time, gid) float64 420kB dask.array<chunksize=(17520, 1), meta=np.ndarray>\n",
    +       "    dhi                (time, gid) float64 420kB dask.array<chunksize=(17520, 1), meta=np.ndarray>\n",
    +       "    ghi                (time, gid) float64 420kB dask.array<chunksize=(17520, 1), meta=np.ndarray>\n",
    +       "    dni                (time, gid) float64 420kB dask.array<chunksize=(17520, 1), meta=np.ndarray>\n",
    +       "    relative_humidity  (time, gid) float64 420kB dask.array<chunksize=(17520, 1), meta=np.ndarray>\n",
    +       "Attributes:\n",
    +       "    full_version_record:  {"rex": "0.2.80", "pandas": "2.0.0", "numpy": "1.23...\n",
    +       "    package:              rex\n",
    +       "    version:              4.0.0
    \n", + "
    \n", + " \n", + "
    \n", + "
    \n", + "

    Meta Dataframe

    \n", + " \n", + "
    \n", + "

    \n", + " \n", + " Meta Data\n", + "

    \n", + "
    \n", + "
    \n", + "
    \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    latitudelongitudealtitudetzcountrystatecountywind_height
    44921239.849998-106.4199983208-7United StatesColoradoSummit2
    45491539.849998-106.1800003156-7United StatesColoradoSummit2
    46061139.610001-105.9400023030-7United StatesColoradoSummit2
    \n", + "
    \n", + "
    \n", + " \n", + "
    \n", + "
    \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ - "geospatial_standoff_scenario.viewScenario()" + "geospatial_standoff_scenario" ] }, { @@ -147,21 +1547,11 @@ "execution_count": 6, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/tford/.conda-envs/rpp/lib/python3.10/site-packages/distributed/node.py:182: UserWarning: Port 8787 is already in use.\n", - "Perhaps you already have a cluster running?\n", - "Hosting the HTTP server on port 37481 instead\n", - " warnings.warn(\n" - ] - }, { "name": "stdout", "output_type": "stream", "text": [ - "Dashboard: http://127.0.0.1:37481/status\n", + "Dashboard: http://127.0.0.1:8787/status\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", @@ -561,14 +1951,12 @@ " * latitude (latitude) float32 8B 39.61 39.85\n", " * longitude (longitude) float32 12B -106.4 -106.2 -105.9\n", "Data variables:\n", - " x (latitude, longitude) float64 48B nan nan 0.5751 1.432 1.421 nan\n", " T98_0 (latitude, longitude) float64 48B nan nan 72.15 75.22 75.25 nan\n", - " T98_inf (latitude, longitude) float64 48B nan nan 46.77 48.81 48.51 nan\n", - "Attributes:\n", - " long_name: Standoff dataset
    " + " x (latitude, longitude) float64 48B nan nan 0.5751 1.432 1.421 nan\n", + " T98_inf (latitude, longitude) float64 48B nan nan 46.77 48.81 48.51 nan" ], "text/plain": [ " Size: 164B\n", @@ -577,11 +1965,9 @@ " * latitude (latitude) float32 8B 39.61 39.85\n", " * longitude (longitude) float32 12B -106.4 -106.2 -105.9\n", "Data variables:\n", - " x (latitude, longitude) float64 48B nan nan 0.5751 1.432 1.421 nan\n", " T98_0 (latitude, longitude) float64 48B nan nan 72.15 75.22 75.25 nan\n", - " T98_inf (latitude, longitude) float64 48B nan nan 46.77 48.81 48.51 nan\n", - "Attributes:\n", - " long_name: Standoff dataset" + " x (latitude, longitude) float64 48B nan nan 0.5751 1.432 1.421 nan\n", + " T98_inf (latitude, longitude) float64 48B nan nan 46.77 48.81 48.51 nan" ] }, "execution_count": 7, @@ -626,7 +2012,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -635,7 +2021,7 @@ "text": [ "/home/tford/.conda-envs/rpp/lib/python3.10/site-packages/xarray/core/dataset.py:274: UserWarning: The specified chunks separate the stored chunks along dimension \"phony_dim_1\" starting at index 500. This could degrade performance. Instead, consider rechunking after loading.\n", " warnings.warn(\n", - "/home/tford/dev/PVDegradationTools/pvdeg/scenario.py:1237: UserWarning: Gids Added - [474405 474406 474407 474408 474409 474410 474411 474412 474413 474414\n", + "/home/tford/dev/PVDegradationTools/pvdeg/scenario.py:1248: UserWarning: Gids Added - [474405 474406 474407 474408 474409 474410 474411 474412 474413 474414\n", " 474415 474416 474417 474418 474419 474420 474421 474422 474423 475420\n", " 475421 475422 475423 475424 475425 475426 475427 475428 475429 475430\n", " 475431 475432 475433 475434 475435 475436 475437 475438 476435 476436\n", @@ -650,8 +2036,16 @@ " 481539 481540 481542 481543 481544 482557 482558 482559 482560 482561\n", " 482562 482564 482565]\n", " warnings.warn(message, UserWarning)\n", - "/home/tford/dev/PVDegradationTools/pvdeg/scenario.py:1626: UserWarning: module added to pipeline as \n", - " {'geospatial_job': {'job': , 'params': {}}}\n", + "/home/tford/dev/PVDegradationTools/pvdeg/scenario.py:1635: UserWarning: module added to scenario with arguments {} using template: Size: 75MB\n", + "Dimensions: (gid: 133, time: 17520)\n", + "Coordinates:\n", + " * time (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31...\n", + " * gid (gid) int64 1kB 474405 474406 474407 ... 482564 482565\n", + "Data variables:\n", + " RH_surface_outside (gid, time) float64 19MB dask.array\n", + " RH_front_encap (gid, time) float64 19MB dask.array\n", + " RH_back_encap (gid, time) float64 19MB dask.array\n", + " RH_backsheet (gid, time) float64 19MB dask.array\n", " warnings.warn(message, UserWarning)\n" ] } @@ -676,157 +2070,147 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "metadata": {}, "outputs": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/tford/.conda-envs/rpp/lib/python3.10/site-packages/distributed/node.py:182: UserWarning: Port 8787 is already in use.\n", - "Perhaps you already have a cluster running?\n", - "Hosting the HTTP server on port 40703 instead\n", - " warnings.warn(\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Dashboard: http://127.0.0.1:40703/status\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "name": "stdout", + "output_type": "stream", + "text": [ + "Dashboard: http://127.0.0.1:8787/status\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.2 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.4 was used.\n", "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", - "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n" + "The array tilt angle was not provided, therefore the latitude tilt of 39.3 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.9 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.8 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.7 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.6 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n", + "The array tilt angle was not provided, therefore the latitude tilt of 39.5 was used.\n" ] } ], @@ -836,7 +2220,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -1212,16 +2596,16 @@ " * longitude (longitude) float32 36B -105.4 -105.3 ... -105.1 -105.1\n", " * time (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31...\n", "Data variables:\n", - " RH_surface_outside (time, latitude, longitude) float64 24MB 76.96 ... 58.81\n", - " RH_back_encap (time, latitude, longitude) float64 24MB 76.96 ... 44.67\n", " RH_backsheet (time, latitude, longitude) float64 24MB 76.96 ... 51.74\n", - " RH_front_encap (time, latitude, longitude) float64 24MB 42.21 ... 31.69
  • " ], "text/plain": [ " Size: 96MB\n", @@ -1412,13 +2796,13 @@ " * longitude (longitude) float32 36B -105.4 -105.3 ... -105.1 -105.1\n", " * time (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31...\n", "Data variables:\n", - " RH_surface_outside (time, latitude, longitude) float64 24MB 76.96 ... 58.81\n", - " RH_back_encap (time, latitude, longitude) float64 24MB 76.96 ... 44.67\n", " RH_backsheet (time, latitude, longitude) float64 24MB 76.96 ... 51.74\n", - " RH_front_encap (time, latitude, longitude) float64 24MB 42.21 ... 31.69" + " RH_back_encap (time, latitude, longitude) float64 24MB 76.96 ... 44.67\n", + " RH_front_encap (time, latitude, longitude) float64 24MB 42.21 ... 31.69\n", + " RH_surface_outside (time, latitude, longitude) float64 24MB 76.96 ... 58.81" ] }, - "execution_count": 12, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -1426,6 +2810,13 @@ "source": [ "geospatial_humidity_scenario.results" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/tutorials_and_tools/tutorials_and_tools/Tools - Module Standoff for IEC TS 63126.ipynb b/tutorials_and_tools/tutorials_and_tools/Tools - Module Standoff for IEC TS 63126.ipynb index a88a81a7..9f8e068a 100644 --- a/tutorials_and_tools/tutorials_and_tools/Tools - Module Standoff for IEC TS 63126.ipynb +++ b/tutorials_and_tools/tutorials_and_tools/Tools - Module Standoff for IEC TS 63126.ipynb @@ -577,7 +577,7 @@ "metadata": {}, "outputs": [], "source": [ - "geospatial_standoff_scenario = pvdeg.scenario.Geospatial_Scenario(\n", + "geospatial_standoff_scenario = pvdeg.Geospatial_Scenario(\n", " name='standoff geospatial',\n", " geospatial = True,\n", ") "