Accessing ncSOS with OWSLib


In [1]:
from owslib.sos import SensorObservationService
import pdb
from owslib.etree import etree
import pandas as pd
import datetime as dt

In [2]:
# usgs woods hole
# buoy data (single current meter)
url='http://geoport.whoi.edu/thredds/sos/usgs/data2/emontgomery/stellwagen/CF-1.6/ARGO_MERCHANT/1211-A1H.cdf'
usgs = SensorObservationService(url)
contents = usgs.contents

In [3]:
usgs.contents


Out[3]:
{'network-all': <owslib.swe.observation.sos100.SosObservationOffering at 0x7fcb79c7be10>,
 'urn_ioos_station_gov.usgs_1211-A1H': <owslib.swe.observation.sos100.SosObservationOffering at 0x7fcb79c84210>}

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


Out[4]:
'urn:ioos:station:gov.usgs:1211-A1H'

In [5]:
off.response_formats


Out[5]:
['text/xml;schema="om/1.0.0"',
 'text/xml;schema="om/1.0.0/profiles/ioos_sos/1.0"']

In [6]:
off.observed_properties


Out[6]:
['urn:ioos:sensor:gov.usgs:1211-A1H:u_1205',
 'urn:ioos:sensor:gov.usgs:1211-A1H:v_1206',
 'urn:ioos:sensor:gov.usgs:1211-A1H:CD_310',
 'urn:ioos:sensor:gov.usgs:1211-A1H:CS_300',
 'urn:ioos:sensor:gov.usgs:1211-A1H:upr_4001']

In [7]:
# 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 [8]:
#pdb.set_trace()
response = usgs.get_observation(offerings=['1211-A1H'],
                                 responseFormat='text/xml;schema="om/1.0.0"',
                                 observedProperties=['u_1205'],
                                 procedure='urn:ioos:station:gov.usgs:1211-A1H')

In [9]:
print response[0:4000]


<?xml version="1.0" encoding="UTF-8"?>
<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">
  <gml:description>A moored array deployed after the ARGO MERCHANT ran aground onNantucket Shoals designed to help understand the fate of the spilled oil.</gml:description>
  <gml:name>USGS/ARGO_MERCHANT/ARGO_MERCHANT/1211-A1H</gml:name>
  <gml:boundedBy>
    <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
      <!-- overwrite these with your actual offering ROI -->
      <gml:lowerCorner>40.9011116027832 -69.17666625976562</gml:lowerCorner>
      <gml:upperCorner>40.9011116027832 -69.17666625976562</gml:upperCorner>
    </gml:Envelope>
  </gml:boundedBy>
  <om:member>
    <om:Observation>
      <gml:description />
      <gml:name />
      <gml:boundedBy>
        <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
          <gml:lowerCorner>40.9011116027832 -69.17666625976562</gml:lowerCorner>
          <gml:upperCorner>40.9011116027832 -69.17666625976562</gml:upperCorner>
        </gml:Envelope>
      </gml:boundedBy>
      <om:samplingTime>
        <gml:TimePeriod gml:id="DATA_TIME">
          <gml:beginPosition>1976-12-28T21:29:59Z</gml:beginPosition>
          <gml:endPosition>1977-01-08T06:29:59Z</gml:endPosition>
        </gml:TimePeriod>
      </om:samplingTime>
      <om:procedure xlink:href="urn:ioos:station:gov.usgs:1211-A1H" />
      <om:observedProperty xlink:href="u_1205" />
      <om:featureOfInterest xlink:href="urn:ioos:station:gov.usgs:1211-A1H" />
      <om:result>
        <om:DataArray>
          <swe:elementCount>
            <swe:Count>
              <swe:value>1</swe:value>
            </swe:Count>
          </swe:elementCount>
          <swe:elementType name="SimpleDataArray">
            <swe:DataRecord>
              <swe:field name="time">
                <swe:Time definition="http://www.opengis.net/def/property/OGC/0/SamplingTime">
                  <swe:uom xlink:href="http://www.opengis.net/def/uom/ISO-8601/0/Gregorian" />
                </swe:Time>
              </swe:field>
              <swe:field name="u_1205">
                <swe:Quantity definition="http://mmisw.org/ont/cf/parameter/u_1205">
                  <swe:uom code="cm/s" />
                </swe:Quantity>
              </swe:field>
            </swe:DataRecord>
          </swe:elementType>
          <swe:encoding>
            <swe:TextBlock blockSeparator=" " decimalSeparator="." tokenSeparator="," />
          </swe:encoding>
          <swe:values>1976-12-28T21:29:59Z,-7.53701 1976-12-28T22:29:59Z,-2.06346 1976-12-28T23:29:59Z,5.02748 1976-12-29T00:29:59Z,9.32351 1976-12-29T01:29:59Z,16.191 1976-12-29T02:29:59Z,18.452 1976-12-29T03:29:59Z,19.452 1976-12-29T04:29:59Z,21.233 1976-12-29T05:29:59Z,8.01951 1976-12-29T06:29:59Z,0.41648 1976-12-29T07:29:59Z,-8.81638 1976-12-29T08:29:59Z,-17.9287 1976-12-29T09:29:59Z,-20.3512 1976-12-29T10:29:59Z,-17.8112 1976-12-29T11:29:59Z,-11.8939 1976-12-29T12:29:59Z,-5.42472 1976-12-29T13:29:59Z,5.48562 1976-12-29T14:29:59Z,12.7434 1976-12-29T15:29:59Z,18.8387 1976-12-29T16:29:59Z,21.7982 1976-12-29T17:29:59Z,17.6214 1976-12-29T18:29:59Z,12.2534 1976-12-29T19:29:59Z,6.98027 1976-12-29T20:29:59Z,2.10325 1976-12-29T21:29:59Z,-3.69112 1976-12-29T22:29:59Z,-1.30559 1976-12-29T23:29:59Z,0.95416 1976-12-30T00:29:59Z,7.74421 1976-12-30T01:29:59Z,14.4868 1976-12-30T02:29:59Z,20.8482 1976-12-30T03:29:59Z,28.165 1976-12-30T04:29:59Z,23.9134 1976-12-30T05:29:59Z,19.8682 1976-12-30T06:29:59Z,9.54208 1976-12-30T07:29:59Z,-1.40473 1976-12-30T08:29:59Z,-7.42687 1976-12-30T09:29:59Z,-17.5523 1976-12-30T10:29:59Z,-17.7453 1976-12-30T11:29:59Z,-15

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

In [11]:
def parse_om_xml(response):
    # extract data and time from OM-XML response
    root = etree.fromstring(response)
    # root.findall(".//{%(om)s}Observation" % root.nsmap )
    values = root.find(".//{%(swe)s}values" % root.nsmap )
    date_value = 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()]] )
    time = date_value[:,0]
    data = date_value[:,1]
    return data,time

In [12]:
data, time = parse_om_xml(response)

In [13]:
ts = pd.Series(data,index=time)

In [14]:
ts.plot(figsize(12,4));



In [15]:
''' this doesn't work
# Try adding a time range to the getobs request:

start = '1976-12-302T00:00:00Z'
stop = '1977-01-07T00:00:00Z'

response = usgs.get_observation(offerings=['1211-A1H'],
                                 responseFormat='text/xml;subtype="om/1.0.0"',
                                 observedProperties=['u_1205'],
                                 procedure='urn:ioos:station:gov.usgs:1211-A1H',
                                 eventTime='%s/%s' % (start,stop)
''';

Try adding a subset on time:


In [16]:
start = '1977-01-01T00:00:00Z'
stop = '1977-01-04T00:00:00Z'
response = usgs.get_observation(offerings=['1211-A1H'],
                                 responseFormat='text/xml;schema="om/1.0.0"',
                                 observedProperties=['u_1205'],
                                 procedure='urn:ioos:station:gov.usgs:1211-A1H',
                                 eventTime='%s/%s' % (start,stop))

In [17]:
data, time = parse_om_xml(response)
ts = pd.Series(data,index=time)
ts.plot(figsize(12,4));