Accessing ncSOS with OWSLib

We have an ncSOS server with a get observation example that works:

http://geoport-dev.whoi.edu/thredds/sos/usgs/data2/notebook/1211-AA.cdf?service=SOS&version=1.0.0&request=GetObservation&responseFormat=text%2Fxml%3Bsubtype%3D%22om%2F1.0.0%22&offering=1211-AA&observedProperty=http://mmisw.org/ont/cf/parameter/eastward_sea_water_velocity&procedure=urn:ioos:station:gov.usgs.cmgp:1211-AA

But can we formulate, request and process this same query (and others like it) using OWSlib?


In [64]:
%matplotlib inline 
from owslib.sos import SensorObservationService
import pdb
from owslib.etree import etree
import pandas as pd
import datetime as dt
import numpy as np

In [46]:
url = 'http://sdf.ndbc.noaa.gov/sos/server.php?request=GetCapabilities&service=SOS&version=1.0.0'
ndbc = SensorObservationService(url)

In [47]:
# usgs woods hole
# buoy data (single current meter)
url='http://geoport-dev.whoi.edu/thredds/sos/usgs/data2/notebook/1211-AA.cdf'
usgs = SensorObservationService(url)
contents = usgs.contents

In [48]:
usgs.contents


Out[48]:
{'network-all': <SosObservationOffering 'urn:ioos:network:gov.usgs.cmgp:all'>,
 'urn_ioos_station_gov.usgs.cmgp_1211-AA': <SosObservationOffering 'urn:ioos:station:gov.usgs.cmgp:1211-AA'>}

In [49]:
off = usgs.offerings[1]
off.name


Out[49]:
'urn:ioos:station:gov.usgs.cmgp:1211-AA'

In [50]:
off.response_formats


Out[50]:
['text/xml;subtype="om/1.0.0"',
 'text/csv',
 'text/json',
 'text/xml;subtype="om/1.0.0/profiles/ioos_sos/1.0"']

In [51]:
off.observed_properties


Out[51]:
['http://mmisw.org/ont/cf/parameter/sea_water_speed',
 'http://mmisw.org/ont/cf/parameter/eastward_sea_water_velocity',
 'http://mmisw.org/ont/cf/parameter/direction_of_sea_water_velocity',
 'http://mmisw.org/ont/fake/parameter/V00_1900',
 'http://mmisw.org/ont/fake/parameter/upr_4001',
 'http://mmisw.org/ont/cf/parameter/northward_sea_water_velocity',
 'http://mmisw.org/ont/fake/parameter/V01_1901']

In [52]:
off.procedures


Out[52]:
['urn:ioos:station:gov.usgs.cmgp:1211-AA']

In [53]:
# the get observation request below works.  How can we recreate this using OWSLib?
# http://geoport-dev.whoi.edu/thredds/sos/usgs/data2/notebook/1211-A1H.cdf?service=SOS&version=1.0.0&request=GetObservation&responseFormat=text%2Fxml%3Bsubtype%3D%22om%2F1.0.0%22&offering=1211-A1H&observedProperty=u_1205&procedure=urn:ioos:station:gov.usgs:1211-A1H

In [54]:
#pdb.set_trace()
response = usgs.get_observation(offerings=['1211-AA'],
                                 responseFormat='text/xml;subtype="om/1.0.0"',
                                 observedProperties=['http://mmisw.org/ont/cf/parameter/eastward_sea_water_velocity'],
                                 procedure='urn:ioos:station:gov.usgs:1211-AA')

In [55]:
print(response[0:4000])


b'<?xml version="1.0" encoding="UTF-8"?>\r\n<om:ObservationCollection xmlns:om="http://www.opengis.net/om/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml" xmlns:swe="http://www.opengis.net/swe/1.0" xsi:schemaLocation="http://www.opengis.net/om/1.0 http://schemas.opengis.net/om/1.0.0/observation.xsd">\r\n  <gml:description>USGS-CMG time-series data from the Argo Merchant Experiment project, mooring 121 and package 1211-AA. A moored array deployed after the ARGO MERCHANT ran aground on Nantucket Shoals designed to help understand the fate of the spilled oil.</gml:description>\r\n  <gml:name>USGS-CMG time-series data: ARGO_MERCHANT - 121 - 1211-AA</gml:name>\r\n  <gml:boundedBy>\r\n    <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">\r\n      <!-- overwrite these with your actual offering ROI -->\r\n      <gml:lowerCorner>40.9011116027832 -69.17666625976562</gml:lowerCorner>\r\n      <gml:upperCorner>40.9011116027832 -69.17666625976562</gml:upperCorner>\r\n    </gml:Envelope>\r\n  </gml:boundedBy>\r\n  <om:member>\r\n    <om:Observation>\r\n      <gml:description />\r\n      <gml:name />\r\n      <gml:boundedBy>\r\n        <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">\r\n          <gml:lowerCorner>40.9011116027832 -69.17666625976562</gml:lowerCorner>\r\n          <gml:upperCorner>40.9011116027832 -69.17666625976562</gml:upperCorner>\r\n        </gml:Envelope>\r\n      </gml:boundedBy>\r\n      <om:samplingTime>\r\n        <gml:TimePeriod gml:id="DATA_TIME">\r\n          <gml:beginPosition>1976-12-28T21:03:44Z</gml:beginPosition>\r\n          <gml:endPosition>1977-01-08T07:56:14Z</gml:endPosition>\r\n        </gml:TimePeriod>\r\n      </om:samplingTime>\r\n      <om:procedure xlink:href="urn:ioos:station:gov.usgs.cmgp:1211-AA" />\r\n      <om:observedProperty xlink:href="u_1205" />\r\n      <om:featureOfInterest xlink:href="urn:ioos:station:gov.usgs.cmgp:1211-AA" />\r\n      <om:result>\r\n        <om:DataArray>\r\n          <swe:elementCount>\r\n            <swe:Count>\r\n              <swe:value>1</swe:value>\r\n            </swe:Count>\r\n          </swe:elementCount>\r\n          <swe:elementType name="SimpleDataArray">\r\n            <swe:DataRecord>\r\n              <swe:field name="time">\r\n                <swe:Time definition="http://www.opengis.net/def/property/OGC/0/SamplingTime">\r\n                  <swe:uom xlink:href="http://www.opengis.net/def/uom/ISO-8601/0/Gregorian" />\r\n                </swe:Time>\r\n              </swe:field>\r\n              <swe:field name="u_1205">\r\n                <swe:Quantity definition="http://mmisw.org/ont/cf/parameter/eastward_sea_water_velocity">\r\n                  <swe:nilValues>\r\n                    <swe:nilValue reason="http://www.opengis.net/def/nil/OGC/0/missing">-9999.9</swe:nilValue>\r\n                  </swe:nilValues>\r\n                  <swe:uom code="m/s" />\r\n                </swe:Quantity>\r\n              </swe:field>\r\n            </swe:DataRecord>\r\n          </swe:elementType>\r\n          <swe:encoding>\r\n            <swe:TextBlock blockSeparator=" " decimalSeparator="." tokenSeparator="," />\r\n          </swe:encoding>\r\n          <swe:values>1976-12-28T21:03:44Z,-0.0765499 1976-12-28T21:11:14Z,-0.083910905 1976-12-28T21:18:44Z,-0.103838995 1976-12-28T21:26:14Z,-0.0832357 1976-12-28T21:33:44Z,-0.0641191 1976-12-28T21:41:14Z,-0.0702551 1976-12-28T21:48:44Z,-0.0536729 1976-12-28T21:56:14Z,-0.0673787 1976-12-28T22:03:44Z,-0.045741502 1976-12-28T22:11:14Z,-0.0703067 1976-12-28T22:18:44Z,-0.043266803 1976-12-28T22:26:14Z,-0.0138678 1976-12-28T22:33:44Z,-0.0181043 1976-12-28T22:41:14Z,-0.0163442 1976-12-28T22:48:44Z,0.0130732 1976-12-28T22:56:14Z,0.0294814 1976-12-28T23:03:44Z,0.0219251 1976-12-28T23:11:14Z,0.0363234 1976-12-28T23:18:44Z,0.025220301 1976-12-28T23:26:14Z,0.048024904 1976-12-28T23:33:44Z,0.0798901 1976-12-28T23:41:14Z,0.0578931 1976-12-28T23:48:44Z,0.0662642 1976-12-28T23:56:14Z,0.0666576 1976-12-29T00:03:44Z,0.0816142 1976-'

In [56]:
# usgs woods hole ADCP data
# url='http://geoport-dev.whoi.edu/thredds/sos/usgs/data2/notebook/9111aqd-a.nc'
# adcp = SensorObservationService(url)

In [57]:
root = etree.fromstring(response)

In [58]:
print(root)


<Element {http://www.opengis.net/om/1.0}ObservationCollection at 0x94e2188>

In [59]:
# root.findall(".//{%(om)s}Observation" % root.nsmap )
values = root.find(".//{%(swe)s}values" % root.nsmap )

In [60]:
date_value = np.array( [ (dt.datetime.strptime(d,"%Y-%m-%dT%H:%M:%SZ"),float(v))
                      for d,v in [l.split(',') for l in values.text.split()]] )

In [61]:
ts = pd.Series(date_value[:,1],index=date_value[:,0])

In [72]:
ts.plot(figsize=(12,4), grid='on');


Now try setting time range via eventTime.


In [70]:
start = '1977-01-03T00:00:00Z'
stop = '1977-01-07T00:00:00Z'
response = usgs.get_observation(offerings=['1211-AA'],
                                 responseFormat='text/xml;subtype="om/1.0.0"',
                                 observedProperties=['http://mmisw.org/ont/cf/parameter/eastward_sea_water_velocity'],
                                 procedure='urn:ioos:station:gov.usgs:1211-AA',
                                 eventTime='{}/{}'.format(start,stop))

In [73]:
root = etree.fromstring(response)
date_value = np.array( [ (dt.datetime.strptime(d,"%Y-%m-%dT%H:%M:%SZ"),float(v))
                      for d,v in [l.split(',') for l in values.text.split()]] )
ts = pd.Series(date_value[:,1],index=date_value[:,0])
ts.plot(figsize=(12,4), grid='on');


...hmmm, didn't seem to do anything


In [ ]: