Rich Signell's Notebook Blog

Blogging with IPython Notebooks

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 0x4040d50>,
 'urn_ioos_station_gov.usgs_1211-A1H': <owslib.swe.observation.sos100.SosObservationOffering at 0x404e510>}
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:100]
<?xml version="1.0" encoding="UTF-8"?>
<om:ObservationCollection xmlns:om="http://www.opengis.net/o

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 [15]:
data, time = parse_om_xml(response)
In [16]:
ts = pd.Series(data,index=time)
In [17]:
ts.plot(figsize(12,4));

2. Try using PYOOS

In [90]:
from pyoos.collectors.ioos.swe_sos import IoosSweSos
In [92]:
# new hotness
url='http://geoport-dev.whoi.edu/thredds/sos/usgs/data2/notebook/1211-A1H.cdf'
collector = IoosSweSos(url)
collector.filter(variables=['u_1205'])     # you can chain these
Out[92]:
<pyoos.collectors.ioos.swe_sos.IoosSweSos at 0x4ba6750>
In [93]:
# newer pyoos version will auto pick responseFormat for you
obs=collector.collect(offerings=['1211-A1H'], responseFormat='text/xml;schema="om/1.0.0/profiles/ioos_sos/1.0"')
In [94]:
# 'station' should be a Paegan 'Station' with list of Points as elements
station=obs[0].feature
In [95]:
p=station.elements[0]
In [96]:
p.members
Out[96]:
[{'name': 'u_1205',
  'standard': 'http://mmisw.org/ont/cf/parameter/eastward_sea_water_velocity',
  'units': 'cm/s',
  'value': -7.53701}]
In [98]:
# list of all unique observedProperties noticed (name/standard)
station.get_unique_members()
Out[98]:
[{'name': 'u_1205',
  'standard': 'http://mmisw.org/ont/cf/parameter/eastward_sea_water_velocity'}]
In [99]:
# build record style representation
def flatten_element(p):
    rd = {'time':p.time}
    for m in p.members:
        rd[m['standard']] = m['value']
    return rd
    
flattened = map(flatten_element, station.elements)
In [86]:
ndf=pd.DataFrame.from_records(flattened, index=['time'])
In [87]:
ndf.head()
Out[87]:
http://mmisw.org/ont/cf/parameter/eastward_sea_water_velocity
time
1976-12-28 21:29:59+00:00 -7.53701
1976-12-28 22:29:59+00:00 -2.06346
1976-12-28 23:29:59+00:00 5.02748
1976-12-29 00:29:59+00:00 9.32351
1976-12-29 01:29:59+00:00 16.19100
In [88]:
ndf.plot()
Out[88]:
<matplotlib.axes.AxesSubplot at 0x41acc50>
In []:
HTML(html)

Comments