Skip to content

Commit

Permalink
Merge pull request #59 from sharppy/map-selector
Browse files Browse the repository at this point in the history
Map selector
  • Loading branch information
keltonhalbert committed Apr 19, 2015
2 parents a68bbc8 + 1b6a7f7 commit c034132
Show file tree
Hide file tree
Showing 2,211 changed files with 259,111 additions and 1,857 deletions.
51 changes: 36 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@

SHARPpy is a collection of open source sounding and hodograph analysis routines, a sounding plotting package, and an interactive application for analyzing real-time soundings all written in Python. It was developed to provide the atmospheric science community a free and consistent source of sounding analysis routines. SHARPpy is constantly updated and vetted by professional meteorologists and climatologists within the scientific community to help maintain a standard source of sounding routines.

Many people have put an immeasurable amount of time into developing this software package.
=======================================================================
#####Developer Requests:

1.) Many people have put an immeasurable amount of time into developing this software package.
If SHARPpy is used to develop a weather product or contributes to research that leads to a
scientific publication, please acknowledge the SHARPpy project by citing the code. You can use
this ready-made citation entry or provide a link back to this website:
Expand All @@ -18,9 +21,15 @@ http://sharppy.github.io/SHARPpy/index.html

https://github.com/sharppy/SHARPpy

Also, please send an email letting us know where SHARPpy is being used or
Additionally, Jeff Whitaker created the Basemap package, from which we have borrowed data and code to develop the SHARPpy data selector GUI.

2.) Also, please send an email letting us know where SHARPpy is being used or
has helped your work at this address so we may track the success of the project: [email protected].

3.) All bug reports and feature requests should be submitted through the Github issues page in order to assist the developers in tracking the issues noted by the users. Before you open a new issue, please check to see if your issue (or a similar one) has already been opened. If your issue already exists, please add a comment to the issue comment thread explaining your bug report or feature request with as much detail as possible. More detail will help the developers fix the issue (in the case of a bug report). The issues page for the SHARPpy project can be found here:

https://github.com/sharppy/SHARPpy/issues

=======================================================================
### Installing SHARPpy

Expand Down Expand Up @@ -51,6 +60,8 @@ Once the package has been downloaded to your computer, use your command line to

After installing the package, you can run the SHARPpy GUI and interact with the SHARPpy libraries through Python scripts.

A video tutorial for installing on Windows: https://dl.dropboxusercontent.com/u/6375163/SHARPpy.mp4

=======================================================================
### Running the SHARPpy GUI

Expand All @@ -71,8 +82,7 @@ http://nbviewer.ipython.org/github/sharppy/SHARPpy/blob/master/tutorials/SHARPpy

### Using the GUI

To open a sounding, select a sounding type, a model run time (if the type is an NWP model), and then select a time(s).
Afterwards, click on your desired location on the point and click map. Once all of these are selected, click "Generate Profiles".
To open a sounding, select a sounding source (observed, GFS, HRRR, etc.), a cycle time, and then select profile time(s) to view in the GUI. Next, click on your desired location on the point and click map. Once all of these are selected, click "Generate Profiles".

After all profiles have been generated, a window should show up with your desired data. Below are things you can do:

Expand All @@ -81,6 +91,10 @@ After all profiles have been generated, a window should show up with your desire
3. Modify the right 2 insets by right clicking on either one. Different insets are available to help the user interrogate the data.
4. Zoom in/out the Skew-T or hodograph by using the scroll wheel function on your mouse or trackpad.
5. Graphically modify the Skew-T and hodograph by clicking and dragging the points of the temperature/dewpoint/hodograph lines. Recalculations of all indices will take place when this is done. (Added 2/19/2015 by Tim Supinie.)
6. View different parcels that can be lifted and lift custom parcels.
7. Compare the profiles and hodograph from severe weather sounding analogs retrieved by SARS by clicking on any of the analogs displayed.
8. Save an image of the sounding you are viewing (Control+S; Windows/Linux, Command+S; OS X)
9. Open up a text file that contains observed sounding data you wish to view. While in the sounding picker, use the keys Control+O for Windows/Linux, Command+O for OS X. Text files must be in a tabular format. See the OAX file in the tutorials folder for an example.

#### Available Insets

Expand Down Expand Up @@ -129,14 +143,21 @@ Clicking on any of the 4 parcels in the inset will change the a) the parcel trac

### Known GUI Issues

Known Windows Issues:
- Inset text is not properly sized or placed in their windows.
- When incrementing/decrementing profiles, the entire screen goes blank and redraws (FIXED AS OF 2/11/2015)
- The program’s menu bar does not display
- The sounding window may not properly size at first. A fix is to manually resize it and manipulate it.

Other Issues:
- Multi-select does not work for Observed soundings
- Some forecast sounding (HRRR, NAM, etc.) point-click locations do not exist on the data server. This will cause the program to crash. (FIXED AS OF 2/28/2015 - program no longer crashes.)
- Wind barbs for very fast winds sometimes have barbs misplaced with respect to the stick of the wind diagram. (FIXED AS OF 2/20/2015)
- "Select Model Run" list of availiable model runs for SREF has invalid SREF run times (FIXED AS OF 2/20/2015)
Known Issues:
- Text can sometimes overlap. (Windows)
- The program’s menu bar does not display (minimal issue since there are very few menu bar functions) (Windows)
- SHARPpy will not work with QT 4.8.6.0 on Linux. There is a bug in the QT package affects the ability of the GUI to render. See this issue for a fix: https://github.com/sharppy/SHARPpy/issues/51 (Linux)
- Some observed soundings will be unable to be loaded into the program due to data quality issues. This is a preventative measure taken by the program that checks the sounding data for a.) incorrect ordering of the data such as in the height or pressure arrays or b.) unrealistic data values. (All OSes)

=======================================================================

### SHARPpy Development Team

SHARPpy is currently managed by the following co-developers (in no particular order):
- Patrick Marsh (SPC)
- Kelton Halbert (OU School of Meteorology)
- Greg Blumberg (OU/CIMMS)
- Tim Supinie (OU School of Meteorology)

Questions and concerns not related to bug reports or feature requests should be may be directed to the team through this email: [email protected]

1 change: 1 addition & 0 deletions datasources/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
all = [ 'data_source.py' ]
74 changes: 74 additions & 0 deletions datasources/available.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@

import urllib2
import re
from datetime import datetime, timedelta

spc_base_url = "http://www.spc.noaa.gov/exper/soundings/"

def _available_spc():
text = urllib2.urlopen(spc_base_url).read()
matches = sorted(list(set(re.findall("([\d]{8})_OBS", text))))
return [ datetime.strptime(m, '%y%m%d%H') for m in matches ]

def _availableat_spc(dt):
recent_url = "%s%s/" % (spc_base_url, dt.strftime('%y%m%d%H_OBS'))
text = urllib2.urlopen(recent_url).read()
matches = re.findall("alt=\"([\w]{3}|[\d]{5})\"", text)
return matches

psu_base_url = "ftp://ftp.meteo.psu.edu/pub/bufkit/"
psu_text = ""
psu_time = None

def _download_psu():
global psu_time, psu_text
now = datetime.utcnow()
if psu_time is None or psu_time < now - timedelta(minutes=5):
psu_time = now

url_obj = urllib2.urlopen(psu_base_url)
psu_text = url_obj.read()
return psu_text

def _availableat_psu(model, dt):
_repl = {'gfs':'gfs3', 'nam':'namm?', 'rap':'rap', 'nam4km':'nam4km', 'hrrr':'hrrr', 'sref':'sref'}

cycle = dt.hour
url = "%s%s/%02d/" % (psu_base_url, model.upper(), cycle)
url_obj = urllib2.urlopen(url)
text = url_obj.read()
stns = re.findall("%s_(.+)\.buf" % _repl[model], text)
return stns

def _available_psu(model, nam=False, off=False):
psu_text = _download_psu()
latest = re.search("%s\.([\d]{12})\.done" % model, psu_text).groups(0)[0]
dt = datetime.strptime(latest, "%Y%m%d%H%M")

if nam and off and dt.hour in [ 0, 12 ]:
dt -= timedelta(hours=6)
if nam and not off and dt.hour in [ 6, 18 ]:
dt -= timedelta(hours=6)
return [ dt ]

available = {
'psu':{},
'psu_off':{'nam':lambda: _available_psu('nam', nam=True, off=True)},
'spc':{'observed':_available_spc},
}

availableat = {
'psu':{},
'psu_off':{'nam':lambda dt: _availableat_psu('nam', dt)},
'spc':{'observed':_availableat_spc},
}

for model in [ 'gfs', 'nam', 'rap', 'hrrr', 'nam4km', 'sref' ]:
available['psu'][model] = (lambda m: lambda: _available_psu(m, nam=(m == 'nam'), off=False))(model)
availableat['psu'][model] = (lambda m: lambda dt: _availableat_psu(m, dt))(model)

if __name__ == "__main__":
# dt = available['psu']['gfs']()
# stns = availableat['psu']['gfs'](dt)
dt = available['spc']['observed']()
stns = availableat['spc']['observed'](dt[-1])
Loading

0 comments on commit c034132

Please sign in to comment.