Skip to content

Commit

Permalink
Fixed odd behavior when selecting models that haven't run yet on the …
Browse files Browse the repository at this point in the history
…current day (say shortly after 00Z)
  • Loading branch information
tsupinie committed Jan 4, 2019
1 parent d8491a2 commit 68eb9e3
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 42 deletions.
39 changes: 20 additions & 19 deletions datasources/available.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def _download_goes():

return goes_text

def _available_goes(dt):
def _available_goes(dt=None):
'''
_available_sharp()
Expand Down Expand Up @@ -95,7 +95,7 @@ def _download_sharp_archive(dt):
sharp_time = now
return sharp_archive_text, dt

def _available_sharp(dt):
def _available_sharp(dt=None):
'''
_available_sharp()
Expand Down Expand Up @@ -155,7 +155,7 @@ def _download_spc():

return spc_text

def _available_spc(dt):
def _available_spc(dt=None):
'''
_available_spc()
Expand Down Expand Up @@ -223,7 +223,7 @@ def _download_psu():

return psu_text

def _availableat_psu(model, dt=None):
def _availableat_psu(model, dt):
'''
_availableat_psu
Expand Down Expand Up @@ -264,17 +264,15 @@ def _available_psu(model, dt=None):
off : boolean (default: false)
Specifies whether or not this is an off-hour run
'''
#nam=(m in [ 'nam', '4km nam' ])

if dt < datetime.utcnow() - timedelta(3600*29): # We know PSU is only a 24 hr service
if dt is not None and dt < datetime.utcnow() - timedelta(3600*29): # We know PSU is only a 24 hr service
return []

if model == '4km nam': model = 'nam4km'

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")

return [ dt ]

### IEM CODE
Expand Down Expand Up @@ -303,7 +301,7 @@ def _download_iem():

return iem_text

def _availableat_iem(model, dt=None):
def _availableat_iem(model, dt):
'''
_availableat_iem
Expand Down Expand Up @@ -346,10 +344,13 @@ def _available_iem(model, dt=None):
Specifies whether or not this is an off-hour run
'''
#nam=(m in [ 'nam', '4km nam' ])
try:
a = int(dt.year)
except:
dt = datetime(dt.year(), dt.month(), dt.day())
if dt is None:
dt = datetime.utcnow()
else:
try:
a = int(dt.year)
except:
dt = datetime(dt.year(), dt.month(), dt.day())

if model == '4km nam': model = 'nam4km'

Expand Down Expand Up @@ -387,7 +388,7 @@ def _availableat_oupecan(dt):
## NCAR ENSEMBLE CODE
ncarens_base_url = 'http://sharp.weather.ou.edu/soundings/ncarens/'

def _available_ncarens(dt):
def _available_ncarens(dt=None):
text = urlopen(ncarens_base_url).read().decode('utf-8')

matches = sorted(list(set(re.findall("([\d]{8}_[\d]{2})", text))))
Expand All @@ -411,10 +412,10 @@ def _available_nssl(ens=False):
available = {
'psu':{},
'iem':{},
'spc':{'observed': lambda dt: _available_spc(dt)},
'ou_pecan': {'pecan ensemble': lambda dt: _available_oupecan(dt) },
'ncar_ens': {'ncar ensemble': lambda dt: _available_ncarens(dt) },
'sharp': {'ncar ensemble': lambda dt: _available_ncarens(dt), 'observed': lambda dt: _available_sharp(dt), 'goes': lambda dt: _available_goes(dt) },
'spc':{'observed': lambda dt=None: _available_spc(dt=dt)},
'ou_pecan': {'pecan ensemble': lambda dt=None: _available_oupecan(dt=dt) },
'ncar_ens': {'ncar ensemble': lambda dt=None: _available_ncarens(dt=dt) },
'sharp': {'ncar ensemble': lambda dt=None: _available_ncarens(dt=dt), 'observed': lambda dt=None: _available_sharp(dt=dt), 'goes': lambda dt=None: _available_goes(dt=dt) },
'local': {'local wrf-arw': lambda filename: _available_local(filename)},
}

Expand All @@ -430,12 +431,12 @@ def _available_nssl(ens=False):

# Set the available and available-at-time functions for the PSU data.
for model in [ 'gfs', 'nam', 'rap', 'hrrr', '4km nam', 'sref' ]:
available['psu'][model] = (lambda m: lambda dt: _available_psu(m, dt))(model)
available['psu'][model] = (lambda m: lambda dt=None: _available_psu(m, dt=dt))(model)
availableat['psu'][model] = (lambda m: lambda dt: _availableat_psu(m, dt))(model)

# Set the available and available-at-time functions for the IEM data.
for model in [ 'gfs', 'nam', 'rap', 'ruc', '4km nam' ]:
available['iem'][model] = (lambda m: lambda dt: _available_iem(m, dt))(model)
available['iem'][model] = (lambda m: lambda dt=None: _available_iem(m, dt=dt))(model)
availableat['iem'][model] = (lambda m: lambda dt: _availableat_iem(m, dt))(model)


Expand Down
51 changes: 28 additions & 23 deletions runsharp/full_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,20 +131,23 @@ def __init__(self, *args, **kwargs):
super(Calendar, self).__init__(*args, **kwargs)

min_date = QDate(1946, 1, 1)
qdate_avail = QDate(dt_avail.year, dt_avail.month, dt_avail.day)

self.setGridVisible(True)
self.setVerticalHeaderFormat(QCalendarWidget.NoVerticalHeader)
self.setHorizontalHeaderFormat(QCalendarWidget.SingleLetterDayNames)
self.setMinimumDate(min_date)
self.setMaximumDate(qdate_avail)
self.setSelectedDate(qdate_avail)
self.setLatestAvailable(dt_avail)

for day in [Qt.Sunday, Qt.Saturday]:
txt_fmt = self.weekdayTextFormat(day)
txt_fmt.setForeground(QBrush(Qt.black))
self.setWeekdayTextFormat(day, txt_fmt)

def setLatestAvailable(self, dt_avail):
qdate_avail = QDate(dt_avail.year, dt_avail.month, dt_avail.day)
self.setMaximumDate(qdate_avail)
self.setSelectedDate(qdate_avail)


class Picker(QWidget):
date_format = "%Y-%m-%d %HZ"
Expand Down Expand Up @@ -328,19 +331,16 @@ def dropdown_menu(self, item_list):

return dropdown

def update_from_cal(self):
def update_from_cal(self, dt, updated_model=False):
"""
Update the dropdown list and the forecast times list if a new date
is selected in the calendar app.
"""

models = sorted(self.data_sources.keys())
self.get_model(models.index(self.model))
self.update_run_dropdown(updated_model=updated_model)

# self.update_run_dropdown()
# self.update_list()
#print(self.run, self.model)
#self.view.setDataSource(self.data_sources[self.model], self.run)
self.update_list()
self.view.setDataSource(self.data_sources[self.model], self.run)

def update_list(self):
"""
Expand Down Expand Up @@ -403,28 +403,37 @@ def update_datasource_dropdown(self, selected="Observed"):
self.model_dropdown.setCurrentIndex(models.index(selected))
self.get_model(models.index(selected))

def update_run_dropdown(self):
def update_run_dropdown(self, updated_model=False):
"""
Updates the dropdown menu that contains the model run
information.
:return:
"""
logging.debug("Calling full_gui.update_run_dropdown")

self.cal_date = self.cal.selectedDate()
if self.model.startswith("Local"):
url = self.data_sources[self.model].getURLList(
outlet="Local")[0].replace("file://", "")

def getTimes(): return self.data_sources[self.model].getAvailableTimes(
url)
def getTimes():
return self.data_sources[self.model].getAvailableTimes(url)
else:
def getTimes(): return self.data_sources[self.model].getAvailableTimes(
dt=self.cal_date)
if updated_model:
def getTimes():
return self.data_sources[self.model].getAvailableTimes()
else:
self.cal_date = self.cal.selectedDate()
def getTimes():
return self.data_sources[self.model].getAvailableTimes(dt=self.cal_date)

# Function to update the times.
def update(times):
times = times[0]

if updated_model:
self.cal.setLatestAvailable(max(times))
self.cal_date = self.cal.selectedDate()

self.run_dropdown.clear() # Clear all of the items from the dropdown

# Filter out only times for the specified date.
Expand All @@ -449,14 +458,14 @@ def update(times):
self.run = times[-1]
else:
self.run = date.datetime(1700, 1, 1, 0, 0, 0)
self.view.setCurrentTime(self.run)
self.run_dropdown.update()
if len(filtered_times) > 0:
self.run_dropdown.setCurrentIndex(times.index(self.run))

# Post the getTimes to update. This will re-write the list of times in the dropdown box that
# match the date selected in the calendar.
self.async_id = self.async_obj.post(getTimes, update)
async_id = self.async_obj.post(getTimes, update)
self.async_obj.join(async_id)

def map_link(self, point):
"""
Expand Down Expand Up @@ -534,11 +543,7 @@ def get_model(self, index):
logging.debug("Calling full_gui.get_model")
self.model = self.model_dropdown.currentText()

self.update_run_dropdown()
self.async_obj.join(self.async_id)

self.update_list()
self.view.setDataSource(self.data_sources[self.model], self.run)
self.update_from_cal(None, updated_model=True)

def get_run(self, index):
"""
Expand Down

0 comments on commit 68eb9e3

Please sign in to comment.