From a4630afbfc100ea63a1048faa5196b1739f6c871 Mon Sep 17 00:00:00 2001 From: Ford Date: Fri, 1 Nov 2024 17:06:55 -0600 Subject: [PATCH 1/5] geospatial analysis use auto_template --- ...g.geospatial.plot_sparse_analysis_land.rst | 6 ++ docs/source/_autosummary/pvdeg.geospatial.rst | 8 +++ .../pvdeg.utilities.linear_normalize.rst | 6 ++ .../pvdeg.utilities.merge_sparse.rst | 6 ++ docs/source/_autosummary/pvdeg.utilities.rst | 16 +++++ docs/source/whatsnew/index.rst | 2 + docs/source/whatsnew/releases/v0.4.2.rst | 4 +- docs/source/whatsnew/releases/v0.4.3.rst | 10 +++ pvdeg/geospatial.py | 71 +++++++++++++++---- 9 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 docs/source/_autosummary/pvdeg.geospatial.plot_sparse_analysis_land.rst create mode 100644 docs/source/_autosummary/pvdeg.utilities.linear_normalize.rst create mode 100644 docs/source/_autosummary/pvdeg.utilities.merge_sparse.rst create mode 100644 docs/source/whatsnew/releases/v0.4.3.rst diff --git a/docs/source/_autosummary/pvdeg.geospatial.plot_sparse_analysis_land.rst b/docs/source/_autosummary/pvdeg.geospatial.plot_sparse_analysis_land.rst new file mode 100644 index 0000000..16e8a98 --- /dev/null +++ b/docs/source/_autosummary/pvdeg.geospatial.plot_sparse_analysis_land.rst @@ -0,0 +1,6 @@ +pvdeg.geospatial.plot\_sparse\_analysis\_land +============================================= + +.. currentmodule:: pvdeg.geospatial + +.. autofunction:: plot_sparse_analysis_land \ No newline at end of file diff --git a/docs/source/_autosummary/pvdeg.geospatial.rst b/docs/source/_autosummary/pvdeg.geospatial.rst index 4524da2..159523f 100644 --- a/docs/source/_autosummary/pvdeg.geospatial.rst +++ b/docs/source/_autosummary/pvdeg.geospatial.rst @@ -34,6 +34,7 @@ pvdeg.geospatial pvdeg.geospatial.plot_Europe pvdeg.geospatial.plot_USA pvdeg.geospatial.plot_sparse_analysis + pvdeg.geospatial.plot_sparse_analysis_land pvdeg.geospatial.start_dask pvdeg.geospatial.template_parameters pvdeg.geospatial.zero_template @@ -157,6 +158,13 @@ pvdeg.geospatial .. minigallery:: pvdeg.geospatial.plot_sparse_analysis :add-heading: + .. autofunction:: plot_sparse_analysis_land + + .. _sphx_glr_backref_pvdeg.geospatial.plot_sparse_analysis_land: + + .. minigallery:: pvdeg.geospatial.plot_sparse_analysis_land + :add-heading: + .. autofunction:: start_dask .. _sphx_glr_backref_pvdeg.geospatial.start_dask: diff --git a/docs/source/_autosummary/pvdeg.utilities.linear_normalize.rst b/docs/source/_autosummary/pvdeg.utilities.linear_normalize.rst new file mode 100644 index 0000000..8fae071 --- /dev/null +++ b/docs/source/_autosummary/pvdeg.utilities.linear_normalize.rst @@ -0,0 +1,6 @@ +pvdeg.utilities.linear\_normalize +================================= + +.. currentmodule:: pvdeg.utilities + +.. autofunction:: linear_normalize \ No newline at end of file diff --git a/docs/source/_autosummary/pvdeg.utilities.merge_sparse.rst b/docs/source/_autosummary/pvdeg.utilities.merge_sparse.rst new file mode 100644 index 0000000..9da49b5 --- /dev/null +++ b/docs/source/_autosummary/pvdeg.utilities.merge_sparse.rst @@ -0,0 +1,6 @@ +pvdeg.utilities.merge\_sparse +============================= + +.. currentmodule:: pvdeg.utilities + +.. autofunction:: merge_sparse \ No newline at end of file diff --git a/docs/source/_autosummary/pvdeg.utilities.rst b/docs/source/_autosummary/pvdeg.utilities.rst index fe0b340..d769d53 100644 --- a/docs/source/_autosummary/pvdeg.utilities.rst +++ b/docs/source/_autosummary/pvdeg.utilities.rst @@ -26,6 +26,8 @@ pvdeg.utilities pvdeg.utilities.get_kinetics pvdeg.utilities.get_state_bbox pvdeg.utilities.gid_downsampling + pvdeg.utilities.linear_normalize + pvdeg.utilities.merge_sparse pvdeg.utilities.meta_as_dict pvdeg.utilities.new_id pvdeg.utilities.nrel_kestrel_check @@ -100,6 +102,20 @@ pvdeg.utilities .. minigallery:: pvdeg.utilities.gid_downsampling :add-heading: + .. autofunction:: linear_normalize + + .. _sphx_glr_backref_pvdeg.utilities.linear_normalize: + + .. minigallery:: pvdeg.utilities.linear_normalize + :add-heading: + + .. autofunction:: merge_sparse + + .. _sphx_glr_backref_pvdeg.utilities.merge_sparse: + + .. minigallery:: pvdeg.utilities.merge_sparse + :add-heading: + .. autofunction:: meta_as_dict .. _sphx_glr_backref_pvdeg.utilities.meta_as_dict: diff --git a/docs/source/whatsnew/index.rst b/docs/source/whatsnew/index.rst index 78b3536..b1070d6 100644 --- a/docs/source/whatsnew/index.rst +++ b/docs/source/whatsnew/index.rst @@ -5,6 +5,8 @@ What's New PVDegradationTools (pvdeg) change log: +.. include:: releases/v0.4.3.rst +.. include:: releases/v0.4.2.rst .. include:: releases/v0.4.1.rst .. include:: releases/v0.4.0.rst .. include:: releases/v0.3.3.rst diff --git a/docs/source/whatsnew/releases/v0.4.2.rst b/docs/source/whatsnew/releases/v0.4.2.rst index 597e551..1c7c30b 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 new file mode 100644 index 0000000..0ae9f13 --- /dev/null +++ b/docs/source/whatsnew/releases/v0.4.3.rst @@ -0,0 +1,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. + +Contributors +~~~~~~~~~~~~ +* Tobin Ford (:ghuser:`tobin-ford`) diff --git a/pvdeg/geospatial.py b/pvdeg/geospatial.py index c9cb0d2..1e015fc 100644 --- a/pvdeg/geospatial.py +++ b/pvdeg/geospatial.py @@ -190,7 +190,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 +217,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 +248,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 +260,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 +326,8 @@ 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. def template_parameters(func): """ Output parameters for xarray template. @@ -417,11 +452,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,11 +464,24 @@ 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")): From 1e58f5770b7e53c0f0b3e1667a244e41da3465ea Mon Sep 17 00:00:00 2001 From: Ford Date: Fri, 8 Nov 2024 13:26:05 -0700 Subject: [PATCH 2/5] auto_templating in GeospatialScenario --- pvdeg/decorators.py | 79 +++++++++++++++++++++++++++++++++ pvdeg/geospatial.py | 33 ++++++++++++-- pvdeg/scenario.py | 103 +++++++++++++++++++++++++++++--------------- 3 files changed, 176 insertions(+), 39 deletions(-) diff --git a/pvdeg/decorators.py b/pvdeg/decorators.py index b592739..585c9e6 100644 --- a/pvdeg/decorators.py +++ b/pvdeg/decorators.py @@ -3,6 +3,9 @@ Private API, should only be used in PVDeg implemenation files. """ +import functools +import inspect +import warnings def geospatial_quick_shape(numeric_or_timeseries: bool, shape_names: list[str]) -> None: """ @@ -57,3 +60,79 @@ def decorator(func): return func return decorator + +# Taken from: https://stackoverflow.com/questions/2536307/decorators-in-the-python-standard-lib-deprecated-specifically +# A future Python version (after 3.13) will include the warnings.deprecated decorator +def deprecated(reason): + """ + This is a decorator which can be used to mark functions + as deprecated. It will result in a warning being emitted + when the function is used. + """ + + string_types = (type(b''), type(u'')) + + if isinstance(reason, string_types): + + # The @deprecated is used with a 'reason'. + # + # .. code-block:: python + # + # @deprecated("please, use another function") + # def old_function(x, y): + # pass + + def decorator(func1): + + if inspect.isclass(func1): + fmt1 = "Call to deprecated class {name} ({reason})." + else: + fmt1 = "Call to deprecated function {name} ({reason})." + + @functools.wraps(func1) + def new_func1(*args, **kwargs): + warnings.simplefilter('always', DeprecationWarning) + warnings.warn( + fmt1.format(name=func1.__name__, reason=reason), + category=DeprecationWarning, + stacklevel=2 + ) + warnings.simplefilter('default', DeprecationWarning) + return func1(*args, **kwargs) + + return new_func1 + + return decorator + + elif inspect.isclass(reason) or inspect.isfunction(reason): + + # The @deprecated is used without any 'reason'. + # + # .. code-block:: python + # + # @deprecated + # def old_function(x, y): + # pass + + func2 = reason + + if inspect.isclass(func2): + fmt2 = "Call to deprecated class {name}." + else: + fmt2 = "Call to deprecated function {name}." + + @functools.wraps(func2) + def new_func2(*args, **kwargs): + warnings.simplefilter('always', DeprecationWarning) + warnings.warn( + fmt2.format(name=func2.__name__), + category=DeprecationWarning, + stacklevel=2 + ) + warnings.simplefilter('default', DeprecationWarning) + return func2(*args, **kwargs) + + return new_func2 + + else: + raise TypeError(repr(type(reason))) \ No newline at end of file diff --git a/pvdeg/geospatial.py b/pvdeg/geospatial.py index 1e015fc..9dd82e5 100644 --- a/pvdeg/geospatial.py +++ b/pvdeg/geospatial.py @@ -7,6 +7,7 @@ humidity, letid, utilities, + decorators, ) import xarray as xr @@ -328,6 +329,7 @@ def output_template( # 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. @@ -445,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: """ @@ -484,10 +508,11 @@ def auto_template(func: Callable, ds_gids: xr.Dataset) -> xr.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/scenario.py b/pvdeg/scenario.py index aab8afa..0a480d6 100644 --- a/pvdeg/scenario.py +++ b/pvdeg/scenario.py @@ -1594,49 +1594,88 @@ 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_params: dict = {}, + # see_added: bool = False, + # ): + # """ + # Add a pvdeg function to the scenario pipeline + + # 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`` + # 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`` + # """ + # 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}} + + # self.pipeline = geo_job_dict + + # if see_added: + # message = f"{func.__name__} added to pipeline as \n {geo_job_dict}" + # warnings.warn(message, UserWarning) + 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. + geo_weather_sub = 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 +1714,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() From 9a087a89bf5b297c64e434f4f85666a7772a399b Mon Sep 17 00:00:00 2001 From: tobin-ford Date: Fri, 8 Nov 2024 15:30:50 -0700 Subject: [PATCH 3/5] Fixed GeospatialScenario running geospatial jobs with auto_templating --- pvdeg/scenario.py | 8 +- .../Geospatial Templates.ipynb | 4022 +---------------- .../Scenario - Geospatial.ipynb | 1168 ++--- 3 files changed, 848 insertions(+), 4350 deletions(-) diff --git a/pvdeg/scenario.py b/pvdeg/scenario.py index 0a480d6..916fabb 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(""" @@ -1658,7 +1662,7 @@ def addJob( if template is None: # take the weather datapoints specified by metadata and create a template based on them. - geo_weather_sub = self.weather_data.sel(gid=self.meta_data.index) + 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.template = template @@ -2184,4 +2188,4 @@ def format_geo_weather(self): """ - return weather_data_html \ No newline at end of file + return weather_data_html diff --git a/tutorials_and_tools/tutorials_and_tools/Geospatial Templates.ipynb b/tutorials_and_tools/tutorials_and_tools/Geospatial Templates.ipynb index b9b47c0..0ada795 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 805dcdc..479442b 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:1674: 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" ] } @@ -97,102 +104,40 @@ "cell_type": "code", "execution_count": 5, "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" - ] - } - ], - "source": [ - "geospatial_standoff_scenario.viewScenario()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Run the job in the pipeline\n", - "\n", - "Currently ``scenario`` only supports one geospatial analysis at a time. We cannot have two geospatial jobs at the same time." - ] - }, - { - "cell_type": "code", - "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", - "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", - "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" - ] - } - ], - "source": [ - "geospatial_standoff_scenario.run()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Directly Access Results Attribute\n", - "\n", - "We can either view the results of the scenario pipeline using ``.viewScenario`` as shown above. The results will be displayed only if the pipeline has been run. Alternatively, we can directly view the ``results`` atribute of the scenario." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
    \n", + "\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", + "

    Pipeline

    \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", @@ -555,288 +500,551 @@ " stroke: currentColor;\n", " fill: currentColor;\n", "}\n", - "
    <xarray.Dataset> Size: 164B\n",
    -       "Dimensions:    (latitude: 2, longitude: 3)\n",
    +       "
    <xarray.Dataset> Size: 3MB\n",
    +       "Dimensions:            (time: 17520, gid: 3)\n",
            "Coordinates:\n",
    -       "  * latitude   (latitude) float32 8B 39.61 39.85\n",
    -       "  * longitude  (longitude) float32 12B -106.4 -106.2 -105.9\n",
    +       "  * gid                (gid) int64 24B 449212 454915 460611\n",
    +       "  * time               (time) datetime64[ns] 140kB 2022-01-01 ... 2022-12-31T...\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",
    +       "    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",
    -       "    long_name:  Standoff dataset
    " + " 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": [ - " Size: 164B\n", - "Dimensions: (latitude: 2, longitude: 3)\n", - "Coordinates:\n", - " * 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" + "" ] }, - "execution_count": 7, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ - "geospatial_standoff_scenario.results" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Cleanup\n", - "\n", - "The scenario object will store its attributes in a file the python script's current working directory. If we want to delete this file when we are done with the scenario instance we can use the ``.clean()`` method as shown below." + "geospatial_standoff_scenario" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + " pandas.core.frame.DataFrame>" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "geospatial_standoff_scenario.clean()" + "geospatial_standoff_scenario.func" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Example Geospatial Functionality\n", - "Many functions are supported for geospatial analysis, here are a few.\n", - "- ``pvdeg.standards.standoff`` \n", - "- ``pvdeg.humidity.module`` \n", - "- ``pvdeg.letid.calc_letid_outdoors``\n", + "## Run the job in the pipeline\n", "\n", - "See the Geospatial Templates tutorial for an example on this." + "Currently ``scenario`` only supports one geospatial analysis at a time. We cannot have two geospatial jobs at the same time." ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 7, "metadata": {}, "outputs": [ { - "name": "stderr", + "name": "stdout", "output_type": "stream", "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", - " 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", - " 476437 476438 476439 476440 476441 476442 476443 476444 476445 476446\n", - " 476447 476448 476449 476450 476451 476452 476453 477451 477452 477453\n", - " 477454 477455 477456 477457 477458 477459 477460 477461 477462 477463\n", - " 477464 477465 477466 477467 478470 478471 478472 478473 478474 478475\n", - " 478476 478477 478478 478479 478480 478481 478482 478483 478484 478485\n", - " 479490 479491 479492 479493 479494 479495 479496 479497 479498 479499\n", - " 479500 479501 479502 479503 480513 480514 480515 480516 480517 480518\n", - " 480519 480520 480521 480522 480523 481534 481535 481536 481537 481538\n", - " 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", - " warnings.warn(message, UserWarning)\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.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", + "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n" ] } ], "source": [ - "geospatial_humidity_scenario = pvdeg.GeospatialScenario(\n", - " name = 'humidity scenario',\n", - " geospatial = True\n", - ")\n", - "\n", - "geospatial_humidity_scenario.addLocation(\n", - " state = 'Colorado',\n", - " county = 'Jefferson',\n", - " see_added = True\n", - ")\n", - "\n", - "geospatial_humidity_scenario.addJob(\n", - " func=pvdeg.humidity.module,\n", - " see_added = True\n", - ")" + "geospatial_standoff_scenario.run()" ] }, { - "cell_type": "code", - "execution_count": 11, + "cell_type": "markdown", "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", - "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.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.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.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.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.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.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.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.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.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.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" - ] - } - ], "source": [ - "geospatial_humidity_scenario.run()" + "## Directly Access Results Attribute\n", + "\n", + "We can either view the results of the scenario pipeline using ``.viewScenario`` as shown above. The results will be displayed only if the pipeline has been run. Alternatively, we can directly view the ``results`` atribute of the scenario." ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -1205,224 +1413,108 @@ " stroke: currentColor;\n", " fill: currentColor;\n", "}\n", - "
    <xarray.Dataset> Size: 96MB\n",
    -       "Dimensions:             (latitude: 19, longitude: 9, time: 17520)\n",
    +       "
    <xarray.Dataset> Size: 164B\n",
    +       "Dimensions:    (latitude: 2, longitude: 3)\n",
            "Coordinates:\n",
    -       "  * latitude            (latitude) float32 76B 39.17 39.21 39.25 ... 39.85 39.89\n",
    -       "  * 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",
    +       "  * latitude   (latitude) float32 8B 39.61 39.85\n",
    +       "  * longitude  (longitude) float32 12B -106.4 -106.2 -105.9\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
    " + " 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" ], "text/plain": [ - " Size: 96MB\n", - "Dimensions: (latitude: 19, longitude: 9, time: 17520)\n", + " Size: 164B\n", + "Dimensions: (latitude: 2, longitude: 3)\n", "Coordinates:\n", - " * latitude (latitude) float32 76B 39.17 39.21 39.25 ... 39.85 39.89\n", - " * 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", + " * latitude (latitude) float32 8B 39.61 39.85\n", + " * longitude (longitude) float32 12B -106.4 -106.2 -105.9\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" + " 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" ] }, - "execution_count": 12, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], + "source": [ + "geospatial_standoff_scenario.results" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Cleanup\n", + "\n", + "The scenario object will store its attributes in a file the python script's current working directory. If we want to delete this file when we are done with the scenario instance we can use the ``.clean()`` method as shown below." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "geospatial_standoff_scenario.clean()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example Geospatial Functionality\n", + "Many functions are supported for geospatial analysis, here are a few.\n", + "- ``pvdeg.standards.standoff`` \n", + "- ``pvdeg.humidity.module`` \n", + "- ``pvdeg.letid.calc_letid_outdoors``\n", + "\n", + "See the Geospatial Templates tutorial for an example on this." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "geospatial_humidity_scenario = pvdeg.GeospatialScenario(\n", + " name = 'humidity scenario',\n", + " geospatial = True\n", + ")\n", + "\n", + "geospatial_humidity_scenario.addLocation(\n", + " state = 'Colorado',\n", + " county = 'Jefferson',\n", + " see_added = True\n", + ")\n", + "\n", + "geospatial_humidity_scenario.addJob(\n", + " func=pvdeg.humidity.module,\n", + " see_added = True\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "geospatial_humidity_scenario.run()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "geospatial_humidity_scenario.results" ] From ab6e2228fc7c29869a136933ad6fa6f69617cdcd Mon Sep 17 00:00:00 2001 From: Ford Date: Fri, 8 Nov 2024 15:38:07 -0700 Subject: [PATCH 4/5] update GeospatialScenario.display --- pvdeg/scenario.py | 115 +++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 67 deletions(-) diff --git a/pvdeg/scenario.py b/pvdeg/scenario.py index 916fabb..f1ee272 100644 --- a/pvdeg/scenario.py +++ b/pvdeg/scenario.py @@ -1597,45 +1597,6 @@ 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_params: dict = {}, - # see_added: bool = False, - # ): - # """ - # Add a pvdeg function to the scenario pipeline - - # 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`` - # 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`` - # """ - # 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}} - - # self.pipeline = geo_job_dict - - # if see_added: - # message = f"{func.__name__} added to pipeline as \n {geo_job_dict}" - # warnings.warn(message, UserWarning) - def addJob( self, func: Callable, @@ -2058,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, '/')}" @@ -2098,8 +2059,9 @@ def _ipython_display_(self): {self.format_results() if self.results else None}
    -

    Pipeline

    - {self.format_pipeline()} +

    Geospatial Job

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

    Modules

    @@ -2170,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 = "" From c1883fbc6ad2963aab1b999b5f5d4414657bae9e Mon Sep 17 00:00:00 2001 From: tobin-ford Date: Fri, 8 Nov 2024 15:42:38 -0700 Subject: [PATCH 5/5] Update GeospatialScenario.display function name --- pvdeg/scenario.py | 2 +- .../Scenario - Geospatial.ipynb | 2219 +++++++++++++---- 2 files changed, 1760 insertions(+), 461 deletions(-) diff --git a/pvdeg/scenario.py b/pvdeg/scenario.py index f1ee272..a46555c 100644 --- a/pvdeg/scenario.py +++ b/pvdeg/scenario.py @@ -2060,7 +2060,7 @@ def _ipython_display_(self):

    Geospatial Job

    - Function : {self.func} + Function : {self.func.__name__} {self.format_template()}
    diff --git a/tutorials_and_tools/tutorials_and_tools/Scenario - Geospatial.ipynb b/tutorials_and_tools/tutorials_and_tools/Scenario - Geospatial.ipynb index 479442b..322aa30 100644 --- a/tutorials_and_tools/tutorials_and_tools/Scenario - Geospatial.ipynb +++ b/tutorials_and_tools/tutorials_and_tools/Scenario - Geospatial.ipynb @@ -81,7 +81,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/tford/dev/PVDegradationTools/pvdeg/scenario.py:1674: UserWarning: standoff added to scenario with arguments {} using template: Size: 96B\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", @@ -119,24 +119,16 @@ " None\n", "
    \n", "
    \n", - "

    Pipeline

    \n", - "
    \n", - "
    \n", - "
    \n", - "

    Modules

    \n", - "
    \n", - "
    \n", - "
    \n", - "

    Weather Dataset

    \n", + "

    Geospatial Job

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

    \n", - " â–º\n", - " Weather Data\n", + " â–º\n", + " Template\n", "

    \n", "
    \n", - "
    \n", - "
    \n", + "
    \n", "
    \n", "\n", "\n", @@ -500,25 +492,14 @@ " stroke: currentColor;\n", " fill: currentColor;\n", "}\n", - "
    <xarray.Dataset> Size: 3MB\n",
    -       "Dimensions:            (time: 17520, gid: 3)\n",
    +       "
    <xarray.Dataset> Size: 96B\n",
    +       "Dimensions:  (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",
    +       "  * gid      (gid) int64 24B 449212 454915 460611\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", + "

    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" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run the job in the pipeline\n", + "\n", + "Currently ``scenario`` only supports one geospatial analysis at a time. We cannot have two geospatial jobs at the same time." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "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.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", + "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" + ] + } + ], + "source": [ + "geospatial_standoff_scenario.run()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Directly Access Results Attribute\n", + "\n", + "We can either view the results of the scenario pipeline using ``.viewScenario`` as shown above. The results will be displayed only if the pipeline has been run. Alternatively, we can directly view the ``results`` atribute of the scenario." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "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", - "
    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", - " " + ".xr-var-item > div,\n", + ".xr-var-item label,\n", + ".xr-var-item > .xr-var-name span {\n", + " background-color: var(--xr-background-color-row-even);\n", + " margin-bottom: 0;\n", + "}\n", + "\n", + ".xr-var-item > .xr-var-name:hover span {\n", + " padding-right: 5px;\n", + "}\n", + "\n", + ".xr-var-list > li:nth-child(odd) > div,\n", + ".xr-var-list > li:nth-child(odd) > label,\n", + ".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n", + " background-color: var(--xr-background-color-row-odd);\n", + "}\n", + "\n", + ".xr-var-name {\n", + " grid-column: 1;\n", + "}\n", + "\n", + ".xr-var-dims {\n", + " grid-column: 2;\n", + "}\n", + "\n", + ".xr-var-dtype {\n", + " grid-column: 3;\n", + " text-align: right;\n", + " color: var(--xr-font-color2);\n", + "}\n", + "\n", + ".xr-var-preview {\n", + " grid-column: 4;\n", + "}\n", + "\n", + ".xr-index-preview {\n", + " grid-column: 2 / 5;\n", + " color: var(--xr-font-color2);\n", + "}\n", + "\n", + ".xr-var-name,\n", + ".xr-var-dims,\n", + ".xr-var-dtype,\n", + ".xr-preview,\n", + ".xr-attrs dt {\n", + " white-space: nowrap;\n", + " overflow: hidden;\n", + " text-overflow: ellipsis;\n", + " padding-right: 10px;\n", + "}\n", + "\n", + ".xr-var-name:hover,\n", + ".xr-var-dims:hover,\n", + ".xr-var-dtype:hover,\n", + ".xr-attrs dt:hover {\n", + " overflow: visible;\n", + " width: auto;\n", + " z-index: 1;\n", + "}\n", + "\n", + ".xr-var-attrs,\n", + ".xr-var-data,\n", + ".xr-index-data {\n", + " display: none;\n", + " background-color: var(--xr-background-color) !important;\n", + " padding-bottom: 5px !important;\n", + "}\n", + "\n", + ".xr-var-attrs-in:checked ~ .xr-var-attrs,\n", + ".xr-var-data-in:checked ~ .xr-var-data,\n", + ".xr-index-data-in:checked ~ .xr-index-data {\n", + " display: block;\n", + "}\n", + "\n", + ".xr-var-data > table {\n", + " float: right;\n", + "}\n", + "\n", + ".xr-var-name span,\n", + ".xr-var-data,\n", + ".xr-index-name div,\n", + ".xr-index-data,\n", + ".xr-attrs {\n", + " padding-left: 25px !important;\n", + "}\n", + "\n", + ".xr-attrs,\n", + ".xr-var-attrs,\n", + ".xr-var-data,\n", + ".xr-index-data {\n", + " grid-column: 1 / -1;\n", + "}\n", + "\n", + "dl.xr-attrs {\n", + " padding: 0;\n", + " margin: 0;\n", + " display: grid;\n", + " grid-template-columns: 125px auto;\n", + "}\n", + "\n", + ".xr-attrs dt,\n", + ".xr-attrs dd {\n", + " padding: 0;\n", + " margin: 0;\n", + " float: left;\n", + " padding-right: 10px;\n", + " width: auto;\n", + "}\n", + "\n", + ".xr-attrs dt {\n", + " font-weight: normal;\n", + " grid-column: 1;\n", + "}\n", + "\n", + ".xr-attrs dt:hover span {\n", + " display: inline-block;\n", + " background: var(--xr-background-color);\n", + " padding-right: 10px;\n", + "}\n", + "\n", + ".xr-attrs dd {\n", + " grid-column: 2;\n", + " white-space: pre-wrap;\n", + " word-break: break-all;\n", + "}\n", + "\n", + ".xr-icon-database,\n", + ".xr-icon-file-text2,\n", + ".xr-no-icon {\n", + " display: inline-block;\n", + " vertical-align: middle;\n", + " width: 1em;\n", + " height: 1.5em !important;\n", + " stroke-width: 0;\n", + " stroke: currentColor;\n", + " fill: currentColor;\n", + "}\n", + "
    <xarray.Dataset> Size: 164B\n",
    +       "Dimensions:    (latitude: 2, longitude: 3)\n",
    +       "Coordinates:\n",
    +       "  * latitude   (latitude) float32 8B 39.61 39.85\n",
    +       "  * longitude  (longitude) float32 12B -106.4 -106.2 -105.9\n",
    +       "Data variables:\n",
    +       "    T98_0      (latitude, longitude) float64 48B nan nan 72.15 75.22 75.25 nan\n",
    +       "    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", + "Dimensions: (latitude: 2, longitude: 3)\n", + "Coordinates:\n", + " * latitude (latitude) float32 8B 39.61 39.85\n", + " * longitude (longitude) float32 12B -106.4 -106.2 -105.9\n", + "Data variables:\n", + " T98_0 (latitude, longitude) float64 48B nan nan 72.15 75.22 75.25 nan\n", + " 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, "metadata": {}, - "output_type": "display_data" + "output_type": "execute_result" } ], "source": [ - "geospatial_standoff_scenario" + "geospatial_standoff_scenario.results" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Cleanup\n", + "\n", + "The scenario object will store its attributes in a file the python script's current working directory. If we want to delete this file when we are done with the scenario instance we can use the ``.clean()`` method as shown below." ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - " pandas.core.frame.DataFrame>" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "geospatial_standoff_scenario.func" + "geospatial_standoff_scenario.clean()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Run the job in the pipeline\n", + "## Example Geospatial Functionality\n", + "Many functions are supported for geospatial analysis, here are a few.\n", + "- ``pvdeg.standards.standoff`` \n", + "- ``pvdeg.humidity.module`` \n", + "- ``pvdeg.letid.calc_letid_outdoors``\n", "\n", - "Currently ``scenario`` only supports one geospatial analysis at a time. We cannot have two geospatial jobs at the same time." + "See the Geospatial Templates tutorial for an example on this." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "metadata": {}, "outputs": [ { - "name": "stdout", + "name": "stderr", "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.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.6 was used.\n", - "The array azimuth was not provided, therefore an azimuth of 180.0 was used.\n" + "/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: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", + " 476437 476438 476439 476440 476441 476442 476443 476444 476445 476446\n", + " 476447 476448 476449 476450 476451 476452 476453 477451 477452 477453\n", + " 477454 477455 477456 477457 477458 477459 477460 477461 477462 477463\n", + " 477464 477465 477466 477467 478470 478471 478472 478473 478474 478475\n", + " 478476 478477 478478 478479 478480 478481 478482 478483 478484 478485\n", + " 479490 479491 479492 479493 479494 479495 479496 479497 479498 479499\n", + " 479500 479501 479502 479503 480513 480514 480515 480516 480517 480518\n", + " 480519 480520 480521 480522 480523 481534 481535 481536 481537 481538\n", + " 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: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" ] } ], "source": [ - "geospatial_standoff_scenario.run()" + "geospatial_humidity_scenario = pvdeg.GeospatialScenario(\n", + " name = 'humidity scenario',\n", + " geospatial = True\n", + ")\n", + "\n", + "geospatial_humidity_scenario.addLocation(\n", + " state = 'Colorado',\n", + " county = 'Jefferson',\n", + " see_added = True\n", + ")\n", + "\n", + "geospatial_humidity_scenario.addJob(\n", + " func=pvdeg.humidity.module,\n", + " see_added = True\n", + ")" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": 10, "metadata": {}, + "outputs": [ + { + "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.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.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.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.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.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.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.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.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" + ] + } + ], "source": [ - "## Directly Access Results Attribute\n", - "\n", - "We can either view the results of the scenario pipeline using ``.viewScenario`` as shown above. The results will be displayed only if the pipeline has been run. Alternatively, we can directly view the ``results`` atribute of the scenario." + "geospatial_humidity_scenario.run()" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -1413,101 +2589,226 @@ " stroke: currentColor;\n", " fill: currentColor;\n", "}\n", - "
    <xarray.Dataset> Size: 164B\n",
    -       "Dimensions:    (latitude: 2, longitude: 3)\n",
    +       "
    <xarray.Dataset> Size: 96MB\n",
    +       "Dimensions:             (latitude: 19, longitude: 9, time: 17520)\n",
            "Coordinates:\n",
    -       "  * latitude   (latitude) float32 8B 39.61 39.85\n",
    -       "  * longitude  (longitude) float32 12B -106.4 -106.2 -105.9\n",
    +       "  * latitude            (latitude) float32 76B 39.17 39.21 39.25 ... 39.85 39.89\n",
    +       "  * 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",
    -       "    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
    " + " RH_backsheet (time, latitude, longitude) float64 24MB 76.96 ... 51.74\n", + " 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
    " ], "text/plain": [ - " Size: 164B\n", - "Dimensions: (latitude: 2, longitude: 3)\n", + " Size: 96MB\n", + "Dimensions: (latitude: 19, longitude: 9, time: 17520)\n", "Coordinates:\n", - " * latitude (latitude) float32 8B 39.61 39.85\n", - " * longitude (longitude) float32 12B -106.4 -106.2 -105.9\n", + " * latitude (latitude) float32 76B 39.17 39.21 39.25 ... 39.85 39.89\n", + " * 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", - " 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" + " RH_backsheet (time, latitude, longitude) float64 24MB 76.96 ... 51.74\n", + " 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": 8, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "geospatial_standoff_scenario.results" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Cleanup\n", - "\n", - "The scenario object will store its attributes in a file the python script's current working directory. If we want to delete this file when we are done with the scenario instance we can use the ``.clean()`` method as shown below." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "geospatial_standoff_scenario.clean()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Example Geospatial Functionality\n", - "Many functions are supported for geospatial analysis, here are a few.\n", - "- ``pvdeg.standards.standoff`` \n", - "- ``pvdeg.humidity.module`` \n", - "- ``pvdeg.letid.calc_letid_outdoors``\n", - "\n", - "See the Geospatial Templates tutorial for an example on this." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "geospatial_humidity_scenario = pvdeg.GeospatialScenario(\n", - " name = 'humidity scenario',\n", - " geospatial = True\n", - ")\n", - "\n", - "geospatial_humidity_scenario.addLocation(\n", - " state = 'Colorado',\n", - " county = 'Jefferson',\n", - " see_added = True\n", - ")\n", - "\n", - "geospatial_humidity_scenario.addJob(\n", - " func=pvdeg.humidity.module,\n", - " see_added = True\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "geospatial_humidity_scenario.run()" + "geospatial_humidity_scenario.results" ] }, { @@ -1515,9 +2816,7 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "geospatial_humidity_scenario.results" - ] + "source": [] } ], "metadata": {