Accessing ncSOS with OWSLib and Pyoos

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

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

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

1. Try using 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]:
#url = 'http://sdf.ndbc.noaa.gov/sos/server.php?request=GetCapabilities&service=SOS&version=1.0.0'
#ndbc = SensorObservationService(url)

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

In [4]:
usgs.contents


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

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


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

In [6]:
off.response_formats


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

In [7]:
off.observed_properties


Out[7]:
['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 [8]:
# 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 [9]:
#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 [10]:
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>1211-A1H       start time = 28 Dec 1976  16:29:59  cycles = 250
               stop  time =  8 Jan 1977  01:29:59  # days = 10
Expt. = 'USGS'  sampling interval = 60.00 minutes
Lat =  40.901112
Lon = -69.176666  File created:  22:50 JUN 29,'83
depth = 69m  Mag.var = -16.000000
#  Variable     Units        Codes Depth   Inst.   Minimum   Maximum
-- ------------ ------------ ----- ------- ------ --------- ---------
 1 TIME         SECONDS      T     
 2 EAST  COMP   CMS/SEC      R       69.00 V-0069   -44.012    49.297
 3 NORTH COMP   CMS/SEC      R       69.00 V-0069   -50.654    72.174
 4 VDIR.1       DEG          R       69.00 V-0069     1.868   359.745
 5 VSPD.1       CMS/SEC      R       69.00 V-0069     1.416    79.172
 6 INT_ROTOR    CMS/SEC      R       69.00 V-0069     5.847    79.927
---------------------------------------------------------------------
 Comments:                                                      REDUCE
 GREAT SOUTH CHANNEL; ARGO MERCHANT SITE.  BEFORE TIPPED.
 VARIABLES LISTED IN ORDER SHOWN ABOVE</gml:description>
  <gml:name>Current meter archive data - Butman et al, Oct.  1992</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

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)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-12-a9d2787dbec9> in <module>()
----> 1 data, time = parse_om_xml(response)

<ipython-input-11-488ba2edb937> in parse_om_xml(response)
      1 def parse_om_xml(response):
      2     # extract data and time from OM-XML response
----> 3     root = etree.fromstring(response)
      4     # root.findall(".//{%(om)s}Observation" % root.nsmap )
      5     values = root.find(".//{%(swe)s}values" % root.nsmap )

NameError: global name 'etree' is not defined

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

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

2. Try using PYOOS


In [ ]:
from pyoos.utils.etree import etree
from pyoos.parsers.ioos.one.timeseries import TimeSeries

In [ ]:
from pyoos.parsers.ioos.get_observation import IoosGetObservation
ob = IoosGetObservation(swe)
stations = ob.observations[0].feature
# 'stations' should be a Paegan 'StationCollection'

In [ ]: