Bias correction process

This example shows how to call the bias-correction service based on the Kernel Density Distribution Mapping. We first connect to the WPS server and get some information on the service, identified by id kddm_bc.

from owslib.wps import WebProcessingService

url = "https://pavics.ouranos.ca/twitcher/ows/proxy/flyingpigeon/wps"
wps = WebProcessingService(url=url)
proc = wps.describeprocess("kddm_bc")
print(proc.abstract)
---------------------------------------------------------------------------
ServiceException                          Traceback (most recent call last)
Cell In[1], line 4
      1 from owslib.wps import WebProcessingService
      3 url = "https://pavics.ouranos.ca/twitcher/ows/proxy/flyingpigeon/wps"
----> 4 wps = WebProcessingService(url=url)
      5 proc = wps.describeprocess("kddm_bc")
      6 print(proc.abstract)

File ~/checkouts/readthedocs.org/user_builds/pavics-sdi/conda/latest/lib/python3.10/site-packages/owslib/wps.py:259, in WebProcessingService.__init__(self, url, version, username, password, skip_caps, headers, verify, cert, timeout, auth, language)
    256 self.languages = None
    258 if not skip_caps:
--> 259     self.getcapabilities()

File ~/checkouts/readthedocs.org/user_builds/pavics-sdi/conda/latest/lib/python3.10/site-packages/owslib/wps.py:278, in WebProcessingService.getcapabilities(self, xml)
    276     self._capabilities = reader.readFromString(xml)
    277 else:
--> 278     self._capabilities = reader.readFromUrl(
    279         self.url, headers=self.headers)
    281 LOGGER.debug(element_to_string(self._capabilities))
    283 # populate the capabilities metadata obects from the XML tree

File ~/checkouts/readthedocs.org/user_builds/pavics-sdi/conda/latest/lib/python3.10/site-packages/owslib/wps.py:547, in WPSCapabilitiesReader.readFromUrl(self, url, username, password, headers, verify, cert)
    540 def readFromUrl(self, url, username=None, password=None,
    541                 headers=None, verify=None, cert=None):
    542     """
    543     Method to get and parse a WPS capabilities document, returning an elementtree instance.
    544 
    545     :param str url: WPS service base url, to which is appended the HTTP parameters: service, version, and request.
    546     """
--> 547     return self._readFromUrl(url,
    548                              {'service': 'WPS', 'request':
    549                                  'GetCapabilities', 'version': self.version},
    550                              self.timeout,
    551                              username=username, password=password,
    552                              headers=headers, verify=verify, cert=cert)

File ~/checkouts/readthedocs.org/user_builds/pavics-sdi/conda/latest/lib/python3.10/site-packages/owslib/wps.py:504, in WPSReader._readFromUrl(self, url, data, timeout, method, username, password, headers, verify, cert)
    502     # split URL into base url and query string to use utility function
    503     spliturl = request_url.split('?')
--> 504     u = openURL(spliturl[0], spliturl[
    505                 1], method='Get', username=self.auth.username, password=self.auth.password,
    506                 headers=headers, verify=self.auth.verify, cert=self.auth.cert, timeout=self.timeout)
    507     return etree.fromstring(u.read())
    509 elif method == 'Post':

File ~/checkouts/readthedocs.org/user_builds/pavics-sdi/conda/latest/lib/python3.10/site-packages/owslib/util.py:210, in openURL(url_base, data, method, cookies, username, password, timeout, headers, verify, cert, auth)
    207 req = requests.request(method.upper(), url_base, headers=headers, **rkwargs)
    209 if req.status_code in [400, 401]:
--> 210     raise ServiceException(req.text)
    212 if req.status_code in [404, 500, 502, 503, 504]:    # add more if needed
    213     req.raise_for_status()

ServiceException: <?xml version="1.0" encoding="utf-8"?>
<ExceptionReport version="1.0.0"
    xmlns="http://www.opengis.net/ows/1.1"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd">
    <Exception exceptionCode="NoApplicableCode" locator="NotAcceptable">
        <ExceptionText>Request failed: HTTPConnectionPool(host=&#x27;flyingpigeon&#x27;, port=8093): Max retries exceeded with url: /wps/wps?service=WPS&amp;request=GetCapabilities&amp;version=1.0.0 (Caused by NewConnectionError(&#x27;&lt;urllib3.connection.HTTPConnection object at 0x7f7c27f0ab10&gt;: Failed to establish a new connection: [Errno -3] Try again&#x27;))</ExceptionText>
    </Exception>
</ExceptionReport>

For the next step, we’ll create small synthetic files and run the process.

import numpy as np
import pandas as pd
import xarray as xr

obs_time_index = pd.date_range(start="2000-01-01", end="2000-12-31", freq="D")
obs = xr.DataArray(
    np.arange(len(obs_time_index)), coords={"time": obs_time_index}, dims="time"
)
ref = obs + 1

fut_time_index = pd.date_range(start="2050-01-01", end="2050-12-31", freq="D")
fut = xr.DataArray(
    np.arange(len(fut_time_index)) + 10, coords={"time": fut_time_index}, dims="time"
)

fn = {"obs": "/tmp/obs.nc", "ref": "/tmp/ref.nc", "fut": "/tmp/fut.nc"}

obs.to_netcdf(fn["obs"])
ref.to_netcdf(fn["ref"])
fut.to_netcdf(fn["fut"])

resp = wps.execute(
    "kddm_bc", inputs=[("obs", fn["obs"]), ("ref", fn["ref"]), ("fut", fn["fut"])]
)
print(resp.status)
ProcessAccepted