Use the same approach to access time series data from an ncSOS end point and a 52North IOOS SOS end point (the Axiom stable demo). ncSOS can only return one station in the response, while 52North SOS can return multiple stations when a network-offering request is made.
Emilio Mayorga, 2/12/2014
(2/20/2014: Updated bundled Wakari environment to pyoos 0.6)
In [1]:
from datetime import datetime, timedelta
import pandas as pd
from pyoos.collectors.ioos.swe_sos import IoosSweSos
In [2]:
# convenience function to build record style time series representation
def flatten_element(p):
rd = {'time':p.time}
for m in p.members:
rd[m['standard']] = m['value']
return rd
In [3]:
url52n = 'http://ioossos.axiomalaska.com/52n-sos-ioos-stable/sos/kvp'
collector52n = IoosSweSos(url52n)
offerings52n = collector52n.server.offerings
In [4]:
# Examine the first offering
of0 = offerings52n[0]
of0.id, of0.name, of0.begin_position, of0.end_position, of0.observed_properties, of0.procedures
Out[4]:
In [5]:
# Examine the second offering
of1 = offerings52n[1]
of1.id, of1.name, of1.begin_position, of1.end_position, of1.observed_properties, of1.procedures
Out[5]:
In [6]:
vars(of1)
Out[6]:
In [7]:
# Use the network:test:all offering to query across all stations
# Set and apply filters, then "collect"
collector52n.start_time = of0.begin_position
collector52n.end_time = of0.end_position
#collector52n.variables=of0.observed_properties # 2 obsprops, each of a different feature type
# For now, query only the variable that returns timeSeries; pyoos can't handle timeSeriesProfile yet
collector52n.variables=['http://mmisw.org/ont/cf/parameter/air_temperature']
offeringname = ['urn:ioos:network:test:all']
respfrmt = 'text/xml; subtype="om/1.0.0/profiles/ioos_sos/1.0"'
In [8]:
obs52n=collector52n.collect(offerings=offeringname, responseFormat=respfrmt)
obs52n
Out[8]:
In [9]:
# 'stations' should be a Paegan 'StationCollection' with list of Paegan 'Station' elements
stations=obs52n[0].feature
print 'Station Object:', type(stations)
print 'Feature Type:', obs52n[0].feature_type
print 'Number of station in StationCollection:', len(stations.elements)
# stations returned in the network offering response
stations.elements
Out[9]:
In [10]:
# Examine one station; list its unique observed properties (variables)
station52n_0 = stations.elements['urn:ioos:station:test:0']
station52n_0.get_unique_members()
Out[10]:
In [11]:
# List and show one data value element
station52n_0.elements[0].time, station52n_0.elements[0].members
Out[11]:
In [12]:
# Extract and parse units string
unitsraw = station52n_0.elements[0].members[0]['units']
units = unitsraw.split(':')[-1]
print unitsraw, ' | ', units
In [13]:
# First station
flattened52n_0 = map(flatten_element, station52n_0.elements)
n52n_0df=pd.DataFrame.from_records(flattened52n_0, index=['time'])
n52n_0df.head()
Out[13]:
In [14]:
# A second station
station52n_5 = stations.elements['urn:ioos:station:test:5']
flattened52n_5 = map(flatten_element, station52n_5.elements)
n52n_5df=pd.DataFrame.from_records(flattened52n_5, index=['time'])
In [15]:
# Plot data from first station using plot method on DataFrame
# Note the datetime x-axis labels are much nicer here (pandas)
# than on the next plot (bare matplotlib)
n52n_0df.plot(figsize(12,5))
ylabel(units);
In [16]:
# Joint plot of time series from two stations in the network response, using matplotlib
op = n52n_0df.columns[0]
plot(n52n_0df.index, n52n_0df[op], '-b',
n52n_5df.index, n52n_5df[op], '-r')
ylabel(units)
legend([station52n_0.uid, station52n_5.uid]);