diff --git a/.readthedocs.yml b/.readthedocs.yml index 832445d4..aa9372bc 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -13,9 +13,9 @@ sphinx: fail_on_warning: true build: - os: ubuntu-22.04 + os: ubuntu-lts-latest tools: - python: "mambaforge-22.9" + python: "mambaforge-23.11" jobs: pre_build: - env SPHINX_APIDOC_OPTIONS="members,undoc-members,show-inheritance,noindex" sphinx-apidoc -o docs/apidoc --private --module-first src/ravenpy diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ea60731b..7185b163 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,6 +9,11 @@ v0.17.0 (unreleased) * Updated `ts_fit_graph` logic for `matplotlib` >= 3.10.0 compatibility. (PR #434) * Temporarily pinned `pygments` below v2.19 due to a breaking change affecting `sphinx-codeautolink`. (PR #434) * Adopted a new RavenPy logo for the documentation. (PR #428) +* Documentation Updates: (PR #436) + * Cleaner imports, removed some unneeded library imports. + * Typo and grammar fixes. + * Updated the Python, Anaconda, and Ubuntu versions used to generate the documentation. +* Small import fixes and minor code cleanup (`ravenpy.extractors`). (PR #436) v0.16.1 (2024-12-05) -------------------- diff --git a/README.rst b/README.rst index 68d6569e..a68f7751 100644 --- a/README.rst +++ b/README.rst @@ -79,7 +79,7 @@ This package was created with Cookiecutter_ and the `Ouranosinc/cookiecutter-pyp :target: https://github.com/CSHS-CWRA/RavenPy/blob/master/LICENSE :alt: License -.. |logo| image:: https://raw.githubusercontent.com/CSHS-CWRA/RavenPy/main/docs/_static/_images/ravenpy-logo-small.png +.. |logo| image:: https://raw.githubusercontent.com/CSHS-CWRA/RavenPy/master/docs/_static/_images/logos/ravenpy-logo-small.png :target: https://github.com/CSHS-CWRA/RavenPy :alt: RavenPy Logo diff --git a/docs/notebooks/04_Emulating_hydrological_models.ipynb b/docs/notebooks/04_Emulating_hydrological_models.ipynb index 0b15a5af..53b296cc 100644 --- a/docs/notebooks/04_Emulating_hydrological_models.ipynb +++ b/docs/notebooks/04_Emulating_hydrological_models.ipynb @@ -26,17 +26,8 @@ "metadata": {}, "outputs": [], "source": [ - "# Import the list of possible model templates.\n", - "from ravenpy.config.emulators import (\n", - " GR4JCN,\n", - " HBVEC,\n", - " HMETS,\n", - " HYPR,\n", - " SACSMA,\n", - " Blended,\n", - " CanadianShield,\n", - " Mohyse,\n", - ")" + "# Import the emulators from the ravenpy package\n", + "from ravenpy.config import emulators" ] }, { @@ -196,7 +187,7 @@ "# preferences, and then we will write the Raven configuration files to disk such that Raven can read them and\n", "# execute a simulation. In this case, we are building a GR4JCN model, but you could change this to any of the\n", "# eight models that are preconfigured for direct emulation in Ravenpy.\n", - "m = GR4JCN(\n", + "m = emulators.GR4JCN(\n", " # Raven requires parameters for the GR4JCN model. For now, we provide default values, but in a later notebook\n", " # we will show how to calibrate and find new parameters for our model.\n", " params=[0.529, -3.396, 407.29, 1.072, 16.9, 0.947],\n", @@ -296,7 +287,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The outputs are as follow:\n", + "The outputs are as follows:\n", "\n", "- hydrograph: The actual simulated hydrograph (q_sim), in netcdf format. It also contains the observed discharge (q_obs) if observed streamflow was provided as a forcing file.\n", "- storage: The state variables of the simulation duration, in netcdf format\n", @@ -399,7 +390,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "As you can see, PAVICS-Hydro makes it easy to build a hydrological model, run it with forcing data, and then interact with the results! In the next notebooks, we will see how to adjust configuration files (the .rvX files) to setup and run a model, and also how to calibrate its parameters.\n", + "As you can see, PAVICS-Hydro makes it easy to build a hydrological model, run it with forcing data, and then interact with the results! In the next notebooks, we will see how to adjust configuration files (the .rvX files) to set up and run a model, and also how to calibrate its parameters.\n", "\n", "\n", "\n", @@ -420,7 +411,7 @@ "* MOHYSE = 10 parameters\n", "* HBVEC = 21 parameters\n", "\n", - "These parameters are found through calibration by tuning their values until the simulated streamflow matches the observations as much as possible. PAVICS-Hydro provides an integrated calibration toolbox that will be explored in the the 6th step of this tutorial. For now, we simply provided a set of parameters but it is not yet fully calibrated. This explains the poor quality of the simulated hydrograph." + "These parameters are found through calibration by tuning their values until the simulated streamflow matches the observations as much as possible. PAVICS-Hydro provides an integrated calibration toolbox that will be explored in the 6th step of this tutorial. For now, we simply provided a set of parameters, but it is not yet fully calibrated. This explains the poor quality of the simulated hydrograph." ] }, { @@ -441,7 +432,7 @@ "metadata": {}, "outputs": [], "source": [ - "m = HMETS(\n", + "m = emulators.HMETS(\n", " params=(\n", " 9.5019,\n", " 0.2774,\n", @@ -482,7 +473,7 @@ "metadata": {}, "outputs": [], "source": [ - "m = Mohyse(\n", + "m = emulators.Mohyse(\n", " params=(1.0, 0.0468, 4.2952, 2.658, 0.4038, 0.0621, 0.0273, 0.0453, 0.9039, 5.6167),\n", " **default_emulator_config,\n", ")" @@ -501,7 +492,7 @@ "metadata": {}, "outputs": [], "source": [ - "m = HBVEC(\n", + "m = emulators.HBVEC(\n", " params=(\n", " 0.059845,\n", " 4.07223,\n", @@ -542,10 +533,10 @@ "metadata": {}, "outputs": [], "source": [ - "# The CanadianShield model needs atleast 2 HRUs. We have to modify the default config before executing it.\n", + "# The CanadianShield model needs at least two (2) HRUs. We have to modify the default config before executing it.\n", "default_emulator_config[\"HRUs\"] = [hru, hru]\n", "\n", - "m = CanadianShield(\n", + "m = emulators.CanadianShield(\n", " params=(\n", " 4.72304300e-01,\n", " 8.16392200e-01,\n", @@ -599,7 +590,7 @@ "metadata": {}, "outputs": [], "source": [ - "m = HYPR(\n", + "m = emulators.HYPR(\n", " params=(\n", " -1.856410e-01,\n", " 2.92301100e00,\n", @@ -640,7 +631,7 @@ "metadata": {}, "outputs": [], "source": [ - "m = SACSMA(\n", + "m = emulators.SACSMA(\n", " params=(\n", " 0.0100000,\n", " 0.0500000,\n", @@ -681,7 +672,7 @@ "metadata": {}, "outputs": [], "source": [ - "m = Blended(\n", + "m = emulators.Blended(\n", " params=(\n", " 2.930702e-02,\n", " 2.211166e00,\n", diff --git a/docs/notebooks/07_Making_and_using_hotstart_files.ipynb b/docs/notebooks/07_Making_and_using_hotstart_files.ipynb index 8c205e40..53570186 100644 --- a/docs/notebooks/07_Making_and_using_hotstart_files.ipynb +++ b/docs/notebooks/07_Making_and_using_hotstart_files.ipynb @@ -37,10 +37,10 @@ "from matplotlib import pyplot as plt\n", "\n", "from ravenpy import Emulator, RavenWarning\n", - "from ravenpy.config import commands as rc\n", "\n", "# Import the GR4JCN model\n", - "from ravenpy.config.emulators import GR4JCN\n", + "from ravenpy.config import commands as rc\n", + "from ravenpy.config import emulators\n", "from ravenpy.utilities.testdata import get_file" ] }, @@ -85,7 +85,7 @@ "}\n", "\n", "# Model configuration\n", - "config = GR4JCN(\n", + "config = emulators.GR4JCN(\n", " params=[0.529, -3.396, 407.29, 1.072, 16.9, 0.947],\n", " Gauge=[\n", " rc.Gauge.from_nc(\n", diff --git a/docs/notebooks/09_Hydrological_impacts_of_climate_change.ipynb b/docs/notebooks/09_Hydrological_impacts_of_climate_change.ipynb index e1f97580..884c6c40 100644 --- a/docs/notebooks/09_Hydrological_impacts_of_climate_change.ipynb +++ b/docs/notebooks/09_Hydrological_impacts_of_climate_change.ipynb @@ -24,9 +24,7 @@ "metadata": {}, "outputs": [], "source": [ - "\"\"\"\n", - "Import the required packages\n", - "\"\"\"\n", + "# Import the required packages\n", "import datetime as dt\n", "import warnings\n", "\n", @@ -34,7 +32,7 @@ "\n", "from ravenpy import Emulator\n", "from ravenpy.config import commands as rc\n", - "from ravenpy.config.emulators import GR4JCN\n", + "from ravenpy.config import emulators\n", "from ravenpy.utilities.testdata import get_file\n", "\n", "warnings.filterwarnings(\"ignore\")" @@ -91,7 +89,7 @@ " }\n", "}\n", "# Start a model instance, in this case a GR4JCN model emulator.\n", - "m = GR4JCN(\n", + "m = emulators.GR4JCN(\n", " params=[0.529, -3.396, 407.29, 1.072, 16.9, 0.947],\n", " Gauge=[\n", " rc.Gauge.from_nc(\n", @@ -139,7 +137,7 @@ "future_ds = get_file(\"notebook_inputs/future_dataset.nc\")\n", "\n", "# Start a new model instance, again in this case a GR4JCN model emulator.\n", - "m = GR4JCN(\n", + "m = emulators.GR4JCN(\n", " params=[0.529, -3.396, 407.29, 1.072, 16.9, 0.947],\n", " Gauge=[\n", " rc.Gauge.from_nc(\n", diff --git a/docs/notebooks/10_Data_assimilation.ipynb b/docs/notebooks/10_Data_assimilation.ipynb index 1728f9d9..9c110e21 100644 --- a/docs/notebooks/10_Data_assimilation.ipynb +++ b/docs/notebooks/10_Data_assimilation.ipynb @@ -47,8 +47,8 @@ "\n", "from ravenpy import Emulator, EnsembleReader\n", "from ravenpy.config import commands as rc\n", + "from ravenpy.config import emulators\n", "from ravenpy.config import options as o\n", - "from ravenpy.config.emulators import GR4JCN\n", "from ravenpy.utilities.testdata import get_file\n", "\n", "# Import hydrometeorological data\n", @@ -122,7 +122,7 @@ "\n", "# Prepare the configuration for the spinup. Since we have added information about Ensemble Kalman Filter data\n", "# assimilation, a \".rve\" file will also be written to disk and Raven will use this to perform the assimilation.\n", - "conf_spinup = GR4JCN(\n", + "conf_spinup = emulators.GR4JCN(\n", " # Model parameters\n", " params=[0.14, -0.005, 576, 7.0, 1.1, 0.92],\n", " # Meteorological gauge data from the Salmon river\n", @@ -301,7 +301,7 @@ "total_hydrograph = ens_loop.hydrograph\n", "\n", "# Here is where the assimilation loop is performed. We will apply the assimilation 30 successive times, advancing\n", - "# in time by 3 days each iteration.\n", + "# in time by three (3) days each iteration.\n", "for i in range(0, 30):\n", " # Set the new start_date and end_dates\n", " start_date = end_date\n", @@ -356,12 +356,12 @@ "metadata": {}, "outputs": [], "source": [ - "# Reset the start and end-dates to cover the entire period (spinup + 30 3-day steps)\n", + "# Reset the start and end-dates to cover the entire period (spinup + 30 * 3-day steps)\n", "start_date = dt.datetime(1996, 9, 1)\n", "end_date = dt.datetime(1997, 8, 31) + dt.timedelta(days=30 * 3)\n", "\n", "# Setup a standard GR4JCN model\n", - "conf_openloop = GR4JCN(\n", + "conf_openloop = emulators.GR4JCN(\n", " params=[0.14, -0.005, 576, 7.0, 1.1, 0.92],\n", " Gauge=gauge,\n", " ObservationData=[rc.ObservationData.from_nc(salmon_meteo, alt_names=\"qobs\")],\n", @@ -396,7 +396,7 @@ "source": [ "We can see that the data assimilation as vastly improved most of the hydrograph. Making the assimilation more frequent, changing other state variables, or adjusting the error model hyperparameters could also lead to better simulations.\n", "\n", - "Once we are satisfied with the initial states, our model would now be ready for forecasting, using the ensemble initial states as initial conditions for generating the forecasts. This can be done using the EnKF forecating method:" + "Once we are satisfied with the initial states, our model would now be ready for forecasting, using the ensemble initial states as initial conditions for generating the forecasts. This can be done using the EnKF forecasting method:" ] }, { @@ -415,7 +415,7 @@ " UniformInitialConditions=None,\n", " # Set the start date equal to the end date of the last assimilation run.\n", " StartDate=end_date,\n", - " # Here we will do a 30-day forecast using the observed meteorological data as forecast data. However it is\n", + " # Here we will do a 30-day forecast using the observed meteorological data as forecast data. However, it is\n", " # possible to replace the Gauge forcing data with that of a forecast, as we have done before.\n", " EndDate=end_date + dt.timedelta(days=30),\n", ")\n", diff --git a/docs/notebooks/11_Climatological_ESP_forecasting.ipynb b/docs/notebooks/11_Climatological_ESP_forecasting.ipynb index 3b60de81..b62965bd 100644 --- a/docs/notebooks/11_Climatological_ESP_forecasting.ipynb +++ b/docs/notebooks/11_Climatological_ESP_forecasting.ipynb @@ -29,7 +29,7 @@ "from matplotlib import pyplot as plt\n", "\n", "from ravenpy.config import commands as rc\n", - "from ravenpy.config.emulators import GR4JCN\n", + "from ravenpy.config import emulators\n", "from ravenpy.utilities import forecasting\n", "from ravenpy.utilities.testdata import get_file" ] @@ -62,7 +62,6 @@ "forecast_duration = 100\n", "\n", "# Define HRU to build the hydrological model\n", - "hru = {}\n", "hru = dict(\n", " area=4250.6,\n", " elevation=843.0,\n", @@ -89,7 +88,7 @@ " }\n", "}\n", "# Model configuration\n", - "model_config = GR4JCN(\n", + "model_config = emulators.GR4JCN(\n", " params=[0.529, -3.396, 407.29, 1.072, 16.9, 0.947],\n", " Gauge=[\n", " rc.Gauge.from_nc(\n", @@ -189,7 +188,7 @@ "metadata": {}, "source": [ "## Performing a climatology ESP hindcast\n", - "In this section, we make the hindcasts for each initialization date that we desire. Here we will extract ESP forecasts for a given calendar date for the years in \"hindcast_years\" as hindcast dates. Each ESP hindcast uses all available data in the `ts` dataset, so in this case we will have 56/57 members for each hindcast initialization depending on the date that we start on, UNLESS we specify a list of years manually. The \"hindcasts\" dataset generated contains all of the flow data from the ESP hindcasts for the initialization dates. The `q_obs` dataset contains all q_obs in the timeseries: Climpred will sort it all out during its processing. Note that the format of these datasets is tailor-made to be used in climpred, and thus has specific dimension names.\n", + "In this section, we make the hindcasts for each initialization date that we desire. Here we will extract ESP forecasts for a given calendar date for the years in \"hindcast_years\" as hindcast dates. Each ESP hindcast uses all available data in the `ts` dataset, so in this case we will have 56/57 members for each hindcast initialization depending on the date that we start on, UNLESS we specify a list of years manually. The \"hindcasts\" dataset generated contains all the flow data from the ESP hindcasts for the initialization dates. The `q_obs` dataset contains all q_obs in the timeseries: Climpred will sort it all out during its processing. Note that the format of these datasets is tailor-made to be used in climpred, and thus has specific dimension names.\n", "\n", "This is a slimmed down example of how we would run an ESP forecast over multiple years to assess the skill of such a forecast." ] diff --git a/docs/notebooks/12_Performing_hindcasting_experiments.ipynb b/docs/notebooks/12_Performing_hindcasting_experiments.ipynb index 1d328026..9ea83cb9 100644 --- a/docs/notebooks/12_Performing_hindcasting_experiments.ipynb +++ b/docs/notebooks/12_Performing_hindcasting_experiments.ipynb @@ -69,7 +69,7 @@ " )\n", "ts_subset = ts_subset.resample(time=\"6H\").nearest(\n", " tolerance=\"1H\"\n", - ") # To make the timesteps identical accross the entire duration" + ") # To make the timesteps identical across the entire duration" ] }, { @@ -86,7 +86,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now that we have the correct weather forecasts, we can setup the hydrological model for a warm-up run:" + "Now that we have the correct weather forecasts, we can set up the hydrological model for a warm-up run:" ] }, { diff --git a/docs/notebooks/Assess_probabilistic_flood_risk.ipynb b/docs/notebooks/Assess_probabilistic_flood_risk.ipynb index a8cb349e..1e327c25 100644 --- a/docs/notebooks/Assess_probabilistic_flood_risk.ipynb +++ b/docs/notebooks/Assess_probabilistic_flood_risk.ipynb @@ -116,7 +116,7 @@ "outputs": [], "source": [ "from ravenpy.config import commands as rc\n", - "from ravenpy.config.emulators import GR4JCN\n", + "from ravenpy.config import emulators\n", "from ravenpy.utilities.forecasting import climatology_esp, compute_forecast_flood_risk\n", "\n", "# Choose the forecast date. Each forecast will start with the same day and month.\n", @@ -153,7 +153,7 @@ " }\n", "}\n", "# Model configuration\n", - "model_config = GR4JCN(\n", + "model_config = emulators.GR4JCN(\n", " params=[0.529, -3.396, 407.29, 1.072, 16.9, 0.947],\n", " Gauge=[\n", " rc.Gauge.from_nc(\n", diff --git a/docs/notebooks/Comparing_hindcasts_and_ESP_forecasts.ipynb b/docs/notebooks/Comparing_hindcasts_and_ESP_forecasts.ipynb index 56ad612d..c3284133 100644 --- a/docs/notebooks/Comparing_hindcasts_and_ESP_forecasts.ipynb +++ b/docs/notebooks/Comparing_hindcasts_and_ESP_forecasts.ipynb @@ -61,7 +61,6 @@ "\n", "# Define some of the catchment properties. Could also be replaced by a call to the properties WPS as in\n", "# the Tutorial Notebook 02.\n", - "hru = {}\n", "hru = dict(\n", " area=4250.6,\n", " elevation=843.0,\n", @@ -144,7 +143,7 @@ "\n", "# Build a new model config:\n", "# Model configuration\n", - "model_config_ESP = GR4JCN(\n", + "model_config_ESP = emulators.GR4JCN(\n", " params=[0.529, -3.396, 407.29, 1.072, 16.9, 0.947],\n", " Gauge=[\n", " rc.Gauge.from_nc(\n", @@ -258,7 +257,7 @@ "}\n", "\n", "# Model configuration for forecasting, including correct start date and forecast duration\n", - "model_config_fcst = GR4JCN(\n", + "model_config_fcst = emulators.GR4JCN(\n", " params=[0.529, -3.396, 407.29, 1.072, 16.9, 0.947],\n", " Gauge=[\n", " rc.Gauge.from_nc(\n", diff --git a/docs/notebooks/Distributed_hydrological_modelling.ipynb b/docs/notebooks/Distributed_hydrological_modelling.ipynb index 77daee98..2517f2ab 100644 --- a/docs/notebooks/Distributed_hydrological_modelling.ipynb +++ b/docs/notebooks/Distributed_hydrological_modelling.ipynb @@ -11,25 +11,6 @@ "In this notebook, we will demonstrate how to build a distributed hydrological model using Raven as well as \"Routing product\" (Generated by BasinMaker), a database of subbasins and how they link to one another in a river network. Currently, Routing product is only available for North American catchments. However, if in time it becomes available on a larger scale, it would be trivial to change the setup apply it to other supported regions." ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Import the list of possible model templates for distributed hydrological modelling\n", - "from ravenpy.config.emulators import (\n", - " GR4JCN,\n", - " HBVEC,\n", - " HMETS,\n", - " HYPR,\n", - " SACSMA,\n", - " Blended,\n", - " CanadianShield,\n", - " Mohyse,\n", - ")" - ] - }, { "cell_type": "code", "execution_count": null, @@ -41,14 +22,12 @@ "from pathlib import Path\n", "\n", "import matplotlib.pyplot as plt\n", - "import xarray as xr\n", "\n", "from ravenpy import Emulator\n", "from ravenpy.config import commands as rc\n", - "from ravenpy.config.emulators import GR4JCN\n", + "from ravenpy.config import emulators\n", "from ravenpy.extractors.routing_product import (\n", " BasinMakerExtractor,\n", - " GridWeightExtractor,\n", " open_shapefile,\n", " upstream_from_coords,\n", ")\n", @@ -108,7 +87,7 @@ "# Streamflow observations file\n", "qobs_fn = get_file(\"matapedia/Qobs_Matapedia_01BD009.nc\")\n", "\n", - "# Make an obervation gauge from the observed streamflow\n", + "# Make an observation gauge from the observed streamflow\n", "qobs = rc.ObservationData.from_nc(qobs_fn, alt_names=(\"discharge\",))" ] }, @@ -161,7 +140,7 @@ "outputs": [], "source": [ "# Prepare the model configuration\n", - "model_config = GR4JCN(\n", + "model_config = emulators.GR4JCN(\n", " params=[0.529, -3.396, 407.29, 1.072, 16.9, 0.947],\n", " StartDate=dt.datetime(1998, 1, 1),\n", " EndDate=dt.datetime(2020, 12, 31),\n", diff --git a/docs/notebooks/Hydrological_realtime_forecasting.ipynb b/docs/notebooks/Hydrological_realtime_forecasting.ipynb index c316b16e..d9d9a647 100644 --- a/docs/notebooks/Hydrological_realtime_forecasting.ipynb +++ b/docs/notebooks/Hydrological_realtime_forecasting.ipynb @@ -23,12 +23,10 @@ "\n", "import fiona\n", "import matplotlib.pyplot as plt\n", - "import xarray as xr\n", - "from clisops.core import average, subset\n", "\n", "from ravenpy import Emulator\n", "from ravenpy.config import commands as rc\n", - "from ravenpy.config.emulators import GR4JCN\n", + "from ravenpy.config import emulators\n", "from ravenpy.extractors.forecasts import get_recent_ECCC_forecast\n", "from ravenpy.utilities import forecasting\n", "from ravenpy.utilities.testdata import get_file, open_dataset" @@ -98,7 +96,7 @@ "}\n", "\n", "# Model configuration\n", - "model_config_warmup = GR4JCN(\n", + "model_config_warmup = emulators.GR4JCN(\n", " params=[0.529, -3.396, 407.29, 1.072, 16.9, 0.947],\n", " Gauge=[\n", " rc.Gauge.from_nc(\n", @@ -166,7 +164,7 @@ "start_date = fcst_tmp.time.data[0] + dt.timedelta(days=1)\n", "\n", "# Model configuration for forecasting, including correct start date and forecast duration and initial state\n", - "model_config_fcst = GR4JCN(\n", + "model_config_fcst = emulators.GR4JCN(\n", " params=[0.529, -3.396, 407.29, 1.072, 16.9, 0.947],\n", " Gauge=[\n", " rc.Gauge.from_nc(\n", diff --git a/docs/notebooks/Perform_Regionalization.ipynb b/docs/notebooks/Perform_Regionalization.ipynb index 796074b8..9690c730 100644 --- a/docs/notebooks/Perform_Regionalization.ipynb +++ b/docs/notebooks/Perform_Regionalization.ipynb @@ -20,7 +20,7 @@ "from matplotlib import pyplot as plt\n", "\n", "from ravenpy.config import commands as rc\n", - "from ravenpy.config.emulators import GR4JCN\n", + "from ravenpy.config import emulators\n", "from ravenpy.utilities.regionalization import (\n", " read_gauged_params,\n", " read_gauged_properties,\n", @@ -76,7 +76,7 @@ "# Also note that, for now, only the GR4JCN, HMETS and MOHYSE models are supported, as they are the only ones\n", "# for which we have a pre-computed database of parameters to use to estimate relationships between descriptors\n", "# and model parameters.\n", - "model_config = GR4JCN(\n", + "model_config = emulators.GR4JCN(\n", " Gauge=[\n", " rc.Gauge.from_nc(\n", " ts, data_type=data_type, alt_names=alt_names, data_kwds=data_kwds\n", diff --git a/docs/notebooks/Running_HMETS_with_CANOPEX_dataset.ipynb b/docs/notebooks/Running_HMETS_with_CANOPEX_dataset.ipynb index e235fdc6..a0fe45e6 100644 --- a/docs/notebooks/Running_HMETS_with_CANOPEX_dataset.ipynb +++ b/docs/notebooks/Running_HMETS_with_CANOPEX_dataset.ipynb @@ -39,7 +39,7 @@ "import xarray as xr\n", "\n", "from ravenpy.config import commands as rc\n", - "from ravenpy.config.emulators import HMETS\n", + "from ravenpy.config import emulators\n", "from ravenpy.utilities.calibration import SpotSetup\n", "from ravenpy.utilities.testdata import get_file\n", "\n", @@ -155,7 +155,7 @@ "# Set the evaluation metrics to be calculated by Raven\n", "eval_metrics = (\"NASH_SUTCLIFFE\",)\n", "\n", - "model_config = HMETS(\n", + "model_config = emulators.HMETS(\n", " ObservationData=[\n", " rc.ObservationData.from_nc(fname, alt_names=\"discharge\", station_idx=1)\n", " ],\n", @@ -258,7 +258,7 @@ " 50 # This is to keep computing time fast for the demo, increase as necessary\n", ")\n", "\n", - "# Setup the spotpy sampler with the method, the setup configuration, a run name and other options. Please refer to\n", + "# Set up the spotpy sampler with the method, the setup configuration, a run name and other options. Please refer to\n", "# the spotpy documentation for more options. We recommend sticking to this format for efficiency of most applications.\n", "sampler = spotpy.algorithms.dds(\n", " spot_setup,\n", diff --git a/docs/notebooks/Sensitivity_analysis.ipynb b/docs/notebooks/Sensitivity_analysis.ipynb index a7cda60f..5fc1e0a0 100644 --- a/docs/notebooks/Sensitivity_analysis.ipynb +++ b/docs/notebooks/Sensitivity_analysis.ipynb @@ -6,7 +6,7 @@ "source": [ "# Performing a sensitivity analysis\n", "\n", - "In this notebook, we perform a sensitivity analysis on GR4JCN to determine the importance of each parameter using the Sobol' sensitivity analysis method. The example shown herein is done using very few parameter samples, and as such, results will be poor and should not be interpreted as-is. However, it is possible to use this code locally using RavenPy to run a much larger sampling on a local computer. " + "In this notebook, we perform a sensitivity analysis on GR4JCN to determine the importance of each parameter using the Sobol' sensitivity analysis method. The example shown herein is done using very few parameter samples, and as such, results will be poor and should not be interpreted as-is. However, it is possible to use this code locally using RavenPy to run a much larger sampling on a local computer." ] }, { @@ -15,9 +15,9 @@ "source": [ "## Prepare data for GR4JCN\n", "\n", - "We will use GR4JCN for this analysis. Since the sensitivity analysis acts on a model response to different inputs, we must find a metric that can be used to measure the impacts of parameters on the model response. In this case, we will use the Nash-Sutcliffe and Absolute Error metrics as responses. It could be any scalar value: mean flow, peak flow, lowest flow, flow volume, etc. But for this exercice we suppose that we want to know the impact of a parameter set on an objective function value. We therefore use a dataset that contains observed streamflow to compute the evaluation metrics.\n", + "We will use GR4JCN for this analysis. Since the sensitivity analysis acts on a model response to different inputs, we must find a metric that can be used to measure the impacts of parameters on the model response. In this case, we will use the Nash-Sutcliffe and Absolute Error metrics as responses. It could be any scalar value: mean flow, peak flow, lowest flow, flow volume, etc. But for this exercise we suppose that we want to know the impact of a parameter set on an objective function value. We therefore use a dataset that contains observed streamflow to compute the evaluation metrics.\n", "\n", - "Let's now import the required packages, get the correct data and setup the model HRU for physiographic information." + "Let's now import the required packages, get the correct data and set up the HRU model for physiographic information." ] }, { @@ -38,10 +38,9 @@ "from SALib.sample import sobol as sobol_sampler\n", "from tqdm.notebook import tqdm\n", "\n", - "from ravenpy import OutputReader\n", + "from ravenpy import OutputReader, run\n", "from ravenpy.config import commands as rc\n", - "from ravenpy.config.emulators import GR4JCN\n", - "from ravenpy.ravenpy import run\n", + "from ravenpy.config import emulators\n", "from ravenpy.utilities.testdata import get_file\n", "\n", "# We get the netCDF from a server. You can replace the `get_file` function by a string containing the path to your own netCDF.\n", @@ -141,7 +140,7 @@ "\n", "In this stage, we have our sampled parameter sets according to the Sobol / Saltelli sampling methods. We now need to run the GR4JCN model for each of these parameter sets and compute the objective function (model response) that we want. Here we ask the model to pre-compute two objective functions (NSE and MAE), so we will be able to perform the sensitivity analysis on both metrics while only running the model once for each parameter set.\n", "\n", - "We use a simple loop to run the model here, but advanced users could parallelize this as it is an \"embarassingly parallelizable\" problem. " + "We use a simple loop to run the model here, but advanced users could parallelize this as it is an \"embarrassingly parallelizable\" problem." ] }, { @@ -178,8 +177,8 @@ "# Now we have a loop that runs the model iteratively, once per parameter set:\n", "for i, X in enumerate(tqdm(param_values)):\n", " # We need to create the desired model with its parameters the same way as in the Notebook 04_Emulating_hydrological_models.\n", - " m = GR4JCN(\n", - " params=X.tolist(), # Here is where we pass the paramter sets to the model, from the loop enumerator X.\n", + " m = emulators.GR4JCN(\n", + " params=X.tolist(), # Here is where we pass the parameter sets to the model, from the loop enumerator X.\n", " **config,\n", " )\n", "\n", @@ -242,7 +241,7 @@ "source": [ "## Result analysis\n", "\n", - "We can see that parameters x2 and x3 are more sensitive than the other with total (ST) and 1st order (S1) sensitivities higher than the other parameters. This is true for both objective functions, but could also be different for other metrics, so it is important to keep this in mind when using a sensitivity analysis to determine parameter importance! A common example is a parameter related to snowmelt. This parameter will have no impact if there is no snow during the period used in the model, but would become critical if there were to be snow in following years.\n", + "We can see that parameters x2 and x3 are more sensitive than the other with total (ST) and 1st order (S1) sensitivities higher than the other parameters. This is true for both objective functions, but could also be different for other metrics, so it is important to keep this in mind when using a sensitivity analysis to determine parameter importance! A common example is a parameter related to snow melt. This parameter will have no impact if there is no snow during the period used in the model, but would become critical if there were to be snow in following years.\n", "\n", "Note that the tables above present the sobol sensitivity in the left column and the confidence interval (95%) in the right column. Values are strange because we are using way too few parameter sets to adequately sample the parameter space here, but increasing the value of \"N\" to 1024 or 2048 would allow for a much better estimation for a 6-parameter model." ] diff --git a/docs/outputs.md b/docs/outputs.md index 1c589ee6..74a42951 100644 --- a/docs/outputs.md +++ b/docs/outputs.md @@ -31,11 +31,11 @@ Note that `Emulator.run` returns an `OutputReader` instance, so a typical ravenp ```{code-cell} ipython3 :tags: [skip-execution] -from ravenpy.config.emulators import HMETS +from ravenpy.config import emulators from ravenpy import Emulator # Configure model simulation -conf = HMETS(**kwds) +conf = emulators.HMETS(**kwds) # Run the model out = Emulator(conf).run() diff --git a/docs/usage.md b/docs/usage.md index f4f2f186..ddd730cc 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -57,11 +57,10 @@ For more info, see {ref}`ensemble_reader`. Ravenpy comes packaged with pre-configured emulators, that is, Raven model configurations that can be modified on the fly. These emulators are made out of symbolic expressions, connecting model parameters to properties and coefficients. For example, the code below creates a model configuration for emulated model GR4JCN using the parameters given, as well as a `Gauge` configuration inferred by inspecting the `meteo.nc` file. ```python -from ravenpy.config.emulators import GR4JCN -from ravenpy.config.commands import Gauge +from ravenpy.config import emulators, commands -gr4jcn = GR4JCN( - params=[0.5, -3.0, 400, 1.0, 17, 0.9], Gauge=[Gauge.from_nc("meteo.nc")] +gr4jcn = emulators.GR4JCN( + params=[0.5, -3.0, 400, 1.0, 17, 0.9], Gauge=[commands.Gauge.from_nc("meteo.nc")] ) ``` diff --git a/environment-docs.yml b/environment-docs.yml index fc9f7d5f..49f48010 100644 --- a/environment-docs.yml +++ b/environment-docs.yml @@ -3,9 +3,9 @@ channels: - conda-forge - defaults dependencies: - - python >=3.10,<3.11 # fixed to reduce solver time + - python >=3.12,<3.13 - raven-hydro >=0.3.1,<1.0 - - autodoc-pydantic +# - autodoc-pydantic # disabled - cairosvg >=2.6.0 - click >=8.0.0 # - clisops # mocked @@ -28,7 +28,7 @@ dependencies: - pygments <2.19 # FIXME: Newest pygments breaks sphinx-codeautolink. See: https://github.com/felix-hilden/sphinx-codeautolink/issues/153 - salib - seaborn - - sphinx >=7.0.0 + - sphinx >=7.1.0 - sphinx-autoapi - sphinx-click - sphinx-codeautolink >=0.15.2,!=0.16.0 # FIXME: temporary fix for sphinx-codeautolink diff --git a/src/ravenpy/extractors/__init__.py b/src/ravenpy/extractors/__init__.py index a93c4cee..10e57178 100644 --- a/src/ravenpy/extractors/__init__.py +++ b/src/ravenpy/extractors/__init__.py @@ -1 +1,2 @@ -from .routing_product import * +from ravenpy.extractors import forecasts +from ravenpy.extractors.routing_product import * diff --git a/src/ravenpy/extractors/forecasts.py b/src/ravenpy/extractors/forecasts.py index af3be35b..76d71bd2 100644 --- a/src/ravenpy/extractors/forecasts.py +++ b/src/ravenpy/extractors/forecasts.py @@ -12,7 +12,7 @@ from pandas import DatetimeIndex, Series, Timestamp from xarray import Dataset -from . import gis_import_error_message +from ravenpy.utilities import gis_import_error_message try: import fiona @@ -29,6 +29,14 @@ if not THREDDS_URL.endswith("/"): THREDDS_URL = f"{THREDDS_URL}/" +__all__ = [ + "get_CASPAR_dataset", + "get_ECCC_dataset", + "get_hindcast_day", + "get_recent_ECCC_forecast", + "get_subsetted_forecast", +] + def get_hindcast_day(region_coll: fiona.Collection, date, climate_model="GEPS"): """Generate a forecast dataset that can be used to run raven.