-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move upper air data capability into Siphon #147
Conversation
siphon/upperair.py
Outdated
------- | ||
:class:`metpy.io.cdm.Dataset` containing the data | ||
|
||
.. deprecated:: 0.6.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this warning mirrored in siphon?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, we can get rid of it.
Do we have tests in MetPy that we can move over to Siphon? |
There are some tests that will need to be re-mocked. Especially my test on server return codes. |
06e80fb
to
75e186e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few places I need to update or would like input on @dopplershift
siphon/simplewebservice/wyoming.py
Outdated
from io import BytesIO | ||
import numpy as np | ||
import pandas as pd | ||
from metpy.calc import get_wind_components |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Planning on porting get_wind_components
from metpy into an _tools
.
siphon/simplewebservice/wyoming.py
Outdated
:class:`pandas.DataFrame` containing the data | ||
|
||
""" | ||
endpoint = WyomingUpperAir('http://weather.uwyo.edu/') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the URL here, I'm feeling like the object setup isn't ideal here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put it in the constructor for the class...see below.
siphon/simplewebservice/wyoming.py
Outdated
('td', 'dewpoint')]: | ||
key_data, key_units = info[key] | ||
|
||
insert_with_units(data, name, key_data, key_units) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to add u, v, speed, direction still.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here are my thoughts. You might also look at ncss.py
to see how I did things there.
|
||
class WyomingUpperAir(HTTPEndPoint): | ||
"""Download and parse data from the University of Wyoming's upper air archive.""" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the way to go is to add a __init__
that takes no arguments and passes the url to:
super(WyomingUpperAir, self).__init__('myurlhere')
Should also include 'cgi-bin/sounding'
in that url.
siphon/simplewebservice/wyoming.py
Outdated
a file-like object from which to read the data | ||
|
||
""" | ||
path = ('cgi-bin/sounding?region={region}&TYPE=TEXT%3ALIST' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's encompass this in a Query
object for Wyoming. Might need to refactor DataQuery
to allow a query object for this to inherit useful behavior.
siphon/upperair.py
Outdated
@@ -0,0 +1,279 @@ | |||
# Copyright (c) 2013-2015 University Corporation for Atmospheric Research/Unidata. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this file is going away.
siphon/simplewebservice/wyoming.py
Outdated
'&YEAR={time:%Y}&MONTH={time:%m}&FROM={time:%d%H}&TO={time:%d%H}' | ||
'&STNM={stid}').format(region=region, time=time, stid=site_id) | ||
|
||
resp = self.get_path(path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With everything above, this becomes self.get_query(query)
.
siphon/simplewebservice/wyoming.py
Outdated
|
||
# Grab the stuff *between* the <PRE> tags -- 6 below is len('<PRE>\n') | ||
buf = resp.text[data_start + 6:data_end] | ||
return BytesIO(buf.encode(encoding='UTF-8')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can probably just move the contents of parse
here since we're not trying to have the same common structure as we did in MetPy. Might be able to leverage pandas' own parsing code to do this work too.
siphon/simplewebservice/wyoming.py
Outdated
:class:`pandas.DataFrame` containing the data | ||
|
||
""" | ||
endpoint = WyomingUpperAir('http://weather.uwyo.edu/') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put it in the constructor for the class...see below.
siphon/simplewebservice/wyoming.py
Outdated
fobj = endpoint.get_data(time, site_id) | ||
info = endpoint.parse(fobj) | ||
|
||
direction, spd, spd_units = info['wind'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think all of the pandas manipulation should be in get_data
in the WyomingUpperAir class.
siphon/simplewebservice/wyoming.py
Outdated
from metpy.calc import get_wind_components | ||
|
||
|
||
def get_upper_air_data(time, site_id): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think:
- This function should be a
staticmethod
onWyomingUpperAir
- It should just wrap the process of building a query and calling
get_data
.
Happy to discuss more...probably easier to get into details now that you have a concrete picture. |
00309ac
to
7996409
Compare
Will need to have a discussion about using query tomorrow, but I have reworked the parsing completely and it's now pretty robust as far as I can tell. |
7996409
to
a2ccda3
Compare
81f0815
to
058b6ac
Compare
Ready for re-review @dopplershift |
Also notice that some of the indexes in the test changed from MetPy - we're returning the full data frame, even if the first rows (lowest altitudes) are all NaN's. I think that's fine, but am up for disagreement. |
Is there an easy way with pandas to remove empty rows? |
Technically not an empty row as the populate height still.... I'll see if there is an easy way to cut if all other fields are NaN |
See what you think about this. If we like it, I'll fixup. Not the nicest solution, but the end result is nice. You must drop the row only when all the columns specified are NaN, then reindex so the index column starts a zero and is continuous. |
a897445
to
713f769
Compare
I'm curious why you don't think it's a nice solution? It looks like a perfectly straightforward one-liner to me. |
Seems verbose for a simple task. i.e. manually specifying the index rest and needed to give a kwarg to prevent maintaining the old index as a column. It is a one-liner, just seemed overly long for a simple task. |
Me thinks someone's standards are a tad high. 😈 Lest I remind you this is how we did this before: if any(np.invert(np.isnan(values[1:]))):
arr_data.append((level,) + values) Not exactly the bastion of simple code either. |
713f769
to
7c8e887
Compare
Don't burst my idealistic bubble 😄 - just fixed up, pending CI, we're good to go. |
I would have figured that bubble had been burst many times over the last 6 months. 😁 |
Addresses #130 and moves upper air data support into Siphon. Still a sketch given that we have some questions on where exactly this should live. I've used the in memory capability of netCDF4-python here, but without wrapping the
Variable
like we do in MetPy, units are a no go. Then again, we'd be depending on MetPy's unit registry at that point, so maybe we return a plain netCDFDataset
? I'm thinking a tool in MetPy that goes through and deals with appending units from metadata might be useful anyway.