import numpy as np
from qtpy import QtGui, QtCore, QtWidgets
import sharppy.sharptab as tab
from sharppy.sharptab.constants import *
import platform
## routine written by Kelton Halbert
## keltonhalbert@ou.edu
__all__ = ['backgroundWinter', 'plotWinter']
[docs]class backgroundWinter(QtWidgets.QFrame):
'''
Handles drawing the background frame.
'''
def __init__(self):
super(backgroundWinter, self).__init__()
self.initUI()
[docs] def initUI(self):
## initialize fram variables such as size,
## padding, etc.
self.setStyleSheet("QFrame {"
" background-color: rgb(0, 0, 0);"
" border-width: 1px;"
" border-style: solid;"
" border-color: #3399CC;}")
self.lpad = 5; self.rpad = 5
self.tpad = 3; self.bpad = 3
self.os_mod = 0
self.barby = 0
self.wid = self.size().width()
self.hgt = self.size().height()
self.tlx = self.rpad; self.tly = self.tpad
self.brx = self.wid; self.bry = self.hgt
if self.physicalDpiX() > 75:
fsize = 8
else:
fsize = 10
self.font_ratio = 0.0512
self.label_font = QtGui.QFont('Helvetica', round(self.hgt * self.font_ratio))
self.label_metrics = QtGui.QFontMetrics( self.label_font )
if platform.system() == "Windows":
self.os_mod = self.label_metrics.descent()
self.label_height = self.label_metrics.xHeight() + self.tpad
self.ylast = self.label_height
self.plotBitMap = QtGui.QPixmap(self.width()-2, self.height()-2)
self.plotBitMap.fill(self.bg_color)
self.plotBackground()
[docs] def draw_frame(self, qp):
'''
Draws the background frame and the text headers for indices.
'''
## initialize a white pen with thickness 1 and a solid line
pen = QtGui.QPen(self.dgz_color, 1, QtCore.Qt.SolidLine)
qp.setPen(pen)
qp.setFont(self.label_font)
## make the initial x value relative to the width of the frame
x1 = self.brx / 10
y1 = self.ylast + self.tpad
## draw the header
rect1 = QtCore.QRect(0, self.tpad, self.wid, self.label_height)
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter, '*** DENDRITIC GROWTH ZONE (-12 TO -17 C) ***')
self.oprh_y1 = 2*self.label_height+self.tpad
pen = QtGui.QPen(self.fg_color, 1, QtCore.Qt.SolidLine)
qp.setPen(pen)
sep = 5
y1 = 3 * self.label_height + self.tpad + sep + self.os_mod
self.layers_y1 = y1
label = ['', '', '']
for i in label:
rect1 = QtCore.QRect(self.lpad, y1, self.wid/10, self.label_height)
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignLeft, i)
y1 += self.label_height + sep + self.os_mod
y1 = 3 * (self.label_height + self.os_mod) + self.tpad + sep + self.label_height + sep + self.os_mod
begin = y1
label = ['', '']
for i in label:
rect1 = QtCore.QRect(self.brx/2 + 2, y1, self.wid/10, self.label_height)
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignLeft, i)
y1 += self.label_height + sep + self.os_mod
qp.drawLine( 0, y1, self.brx, y1 )
qp.drawLine( self.brx* .48, y1, self.brx*.48, begin )
y1 = y1+3
self.init_phase_y1 = y1
label = ['']
for i in label:
rect1 = QtCore.QRect(self.lpad, y1, self.wid/10, self.label_height)
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignLeft, i)
y1 += self.label_height + sep + self.os_mod
qp.drawLine( 0, y1, self.brx, y1 )
y1 = y1+3
backup = y1
label = ['','', '', '']
for i in label:
rect1 = QtCore.QRect(self.lpad, y1, self.wid/10, self.label_height)
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignLeft, i)
y1 += self.label_height + sep + self.os_mod
y1 = backup
label = ['','', '', '']
for i in label:
rect1 = QtCore.QRect(self.brx/2 + 2, y1, self.wid/10, self.label_height)
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignLeft, i)
y1 += self.label_height + sep + self.os_mod
self.energy_y1 = backup
qp.drawLine( 0, y1 + 0, self.brx, y1 + 0)
qp.drawLine( self.brx* .48, y1 + 0, self.brx*.48, backup )
y1 += 4
rect1 = QtCore.QRect(0, y1, self.wid, self.label_height)
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter, '*** BEST GUESS PRECIP TYPE ***')
self.precip_type_y1 = y1 + self.label_height + 3 + 2 * self.os_mod
self.ptype_tmpf_y1 = self.precip_type_y1 + self.label_height + 8 + 2 * self.os_mod
[docs] def resizeEvent(self, e):
'''
Handles when the window gets resized.
'''
self.initUI()
[docs] def plotBackground(self):
'''
Handles drawing the text background.
'''
## initialize a QPainter objext
qp = QtGui.QPainter()
qp.begin(self.plotBitMap)
## draw the frame
self.draw_frame(qp)
qp.end()
[docs]class plotWinter(backgroundWinter):
'''
Handles plotting the indices in the frame.
'''
def __init__(self):
## get the surfce based, most unstable, and mixed layer
## parcels to use for indices, as well as the sounding
## profile itself.
self.bg_color = QtGui.QColor('#000000')
self.fg_color = QtGui.QColor('#ffffff')
self.dgz_color = QtGui.QColor('#ffff00')
super(plotWinter, self).__init__()
self.prof = None
[docs] def setProf(self, prof):
self.prof = prof;
# DGZ data
self.dgz_pbot = prof.dgz_pbot
self.dgz_ptop = prof.dgz_ptop
self.dgz_zbot = tab.utils.M2FT(tab.interp.hght(prof, self.dgz_pbot))
self.dgz_ztop = tab.utils.M2FT(tab.interp.hght(prof, self.dgz_ptop))
self.dgz_depth = self.dgz_ztop - self.dgz_zbot
self.oprh = prof.oprh
self.dgz_meanrh = prof.dgz_meanrh
self.dgz_pw = prof.dgz_pw
self.dgz_meanq = prof.dgz_meanq
self.dgz_meanomeg = prof.dgz_meanomeg
# Inital Phase Types
self.plevel = prof.plevel
self.init_phase = prof.phase
self.init_tmp = prof.tmp
self.init_st = prof.st
# TEMP Energy
self.tpos = prof.tpos
self.tneg = prof.tneg
self.ttop = prof.ttop
self.tbot = prof.tbot
# WETBULB Energy
self.wpos = prof.wpos
self.wneg = prof.wneg
self.wtop = prof.wtop
self.wbot = prof.wbot
# PRECIP TYPE
self.precip_type = prof.precip_type
# PRECIP TYPE SFC TEMPERATURE
self.ptype_tmpf = tab.thermo.ctof(prof.tmpc[prof.get_sfc()])
self.ptype_tmpf_string = "Based on SFC Temperature of %.2f F" % self.ptype_tmpf
self.clearData()
self.plotBackground()
self.plotData()
self.update()
[docs] def setPreferences(self, update_gui=True, **prefs):
self.bg_color = QtGui.QColor(prefs['bg_color'])
self.fg_color = QtGui.QColor(prefs['fg_color'])
self.dgz_color = QtGui.QColor(prefs['winter_dgz_color'])
if update_gui:
self.clearData()
self.plotBackground()
self.plotData()
self.update()
[docs] def resizeEvent(self, e):
'''
Handles when the window is resized.
'''
super(plotWinter, self).resizeEvent(e)
self.plotData()
[docs] def paintEvent(self, e):
super(plotWinter, self).paintEvent(e)
qp = QtGui.QPainter()
qp.begin(self)
qp.drawPixmap(1, 1, self.plotBitMap)
qp.end()
[docs] def clearData(self):
'''
Handles the clearing of the pixmap
in the frame.
'''
self.plotBitMap = QtGui.QPixmap(self.width(), self.height())
self.plotBitMap.fill(self.bg_color)
[docs] def plotData(self):
'''
Handles the drawing of the text on the frame.
'''
if self.prof is None:
return
x1 = self.brx / 10
y1 = self.bry / 19
origin_x = x1*8.5
origin_y = y1*15
## initialize a QPainter object
qp = QtGui.QPainter()
qp.begin(self.plotBitMap)
qp.setRenderHint(qp.Antialiasing)
qp.setRenderHint(qp.TextAntialiasing)
## draw the indices
self.drawPrecipType(qp)
self.drawPrecipTypeTemp(qp)
self.drawOPRH(qp)
self.drawInitial(qp)
self.drawDGZLayer(qp)
self.drawWCLayer(qp)
qp.end()
[docs] def drawOPRH(self, qp):
if self.oprh < -.1 and tab.utils.QC(self.oprh) and self.dgz_meanomeg != -99990.0:
pen = QtGui.QPen(QtCore.Qt.red, 1, QtCore.Qt.SolidLine)
else:
pen = QtGui.QPen(self.fg_color, 1, QtCore.Qt.SolidLine)
qp.setPen(pen)
qp.setFont(self.label_font)
rect1 = QtCore.QRect(0, self.oprh_y1, self.wid, self.label_height)
if self.dgz_meanomeg == -99990.0:
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter, 'OPRH (Omega*PW*RH): N/A')
else:
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter, 'OPRH (Omega*PW*RH): ' + tab.utils.FLOAT2STR(self.oprh,2))
[docs] def drawPrecipType(self, qp):
big = QtGui.QFont('Helvetica', round(self.hgt * self.font_ratio) + 5, bold=True)
big_metrics = QtGui.QFontMetrics( big )
height = big_metrics.xHeight() + self.tpad
pen = QtGui.QPen(self.fg_color, 2, QtCore.Qt.SolidLine)
qp.setPen(pen)
qp.setFont(big)
rect1 = QtCore.QRect(0, self.precip_type_y1, self.wid, height)
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter, self.precip_type)
[docs] def drawPrecipTypeTemp(self, qp):
small = QtGui.QFont('Helvetica', round(self.hgt * self.font_ratio) -1 , bold=False)
small_metrics = QtGui.QFontMetrics( small )
height = small_metrics.xHeight() + self.tpad
pen = QtGui.QPen(self.fg_color, 2, QtCore.Qt.SolidLine)
qp.setPen(pen)
qp.setFont(small)
rect1 = QtCore.QRect(0, self.ptype_tmpf_y1, self.wid, height)
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignCenter, self.ptype_tmpf_string)
[docs] def drawWCLayer(self, qp):
sep = 5
# Temperature Profile Stuff
y1 = self.energy_y1
x = self.lpad
if self.tpos > 0 and self.tneg < 0:
string = 'P/N: ' + str(round(self.tpos,0)) + ' / ' + str(round(self.tneg,0)) + ' J/kg'
label = ['TEMPERATURE PROFILE', \
string, \
'Melt Lyr: ' + str(int(self.ttop)) + '-' + str(int(self.tbot)) + ' mb', \
'Frz Lyr: ' + str(int(self.tbot)) + '-' + str(int(self.prof.pres[self.prof.sfc])) + ' mb']
else:
label = ['TEMPERATURE PROFILE', '', 'Warm/Cold layers not found.', '']
for i in label:
rect1 = QtCore.QRect(x, y1, self.wid/10, self.label_height)
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignLeft, i)
y1 += self.label_height + sep + self.os_mod
# Wetbulb Profile stuff
y1 = self.energy_y1
x = self.brx/2 + 2
if self.wpos > 0 and self.wneg < 0:
string = 'P/N: ' + str(round(self.wpos,0)) + ' / ' + str(round(self.wneg,0)) + ' J/kg'
label = ['WETBULB PROFILE', \
string, \
'Melt Lyr: ' + str(int(self.wtop)) + '-' + str(int(self.wbot)) + ' mb', \
'Frz Lyr: ' + str(int(self.wbot)) + '-' + str(int(self.prof.pres[self.prof.sfc])) + ' mb']
else:
label = ['WETBULB PROFILE', '', 'Warm/Cold layers not found.', '']
for i in label:
rect1 = QtCore.QRect(x, y1, self.wid/10, self.label_height)
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignLeft, i)
y1 += self.label_height + sep + self.os_mod
[docs] def drawDGZLayer(self, qp):
pen = QtGui.QPen(self.fg_color, 1, QtCore.Qt.SolidLine)
qp.setPen(pen)
qp.setFont(self.label_font)
sep = 5
y1 = self.layers_y1
label = ['Layer Depth: ' + tab.utils.INT2STR(self.dgz_depth) + " ft (" + tab.utils.INT2STR(self.dgz_zbot) + '-' +\
tab.utils.INT2STR(self.dgz_ztop) + ' ft msl)',\
'Mean Layer RH: ' + tab.utils.FLOAT2STR(self.dgz_meanrh,0) + ' %',\
'Mean Layer PW: ' + tab.utils.FLOAT2STR(self.dgz_pw,1) + ' in']
for i in label:
rect1 = QtCore.QRect(self.lpad, y1, self.wid/10, self.label_height)
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignLeft, i)
y1 += self.label_height + sep + self.os_mod
y1 = self.layers_y1 + self.label_height + sep + self.os_mod
if self.dgz_meanomeg == 10*self.prof.missing:
omeg = 'N/A'
else:
omeg = tab.utils.FLOAT2STR(self.dgz_meanomeg,1) + ' ub/s'
label = ['Mean Layer MixRat: ' + tab.utils.FLOAT2STR(self.dgz_meanq,1) + ' g/kg', \
'Mean Layer Omega: ' + omeg]
for i in label:
rect1 = QtCore.QRect(self.brx/2 + 2, y1, self.wid/10, self.label_height)
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignLeft, i)
y1 += self.label_height + sep + self.os_mod
[docs] def drawInitial(self, qp):
'''
This handles the severe indices, such as STP, sig hail, etc.
---------
qp: QtGui.QPainter object
'''
pen = QtGui.QPen(self.fg_color, 1, QtCore.Qt.SolidLine)
qp.setPen(pen)
qp.setFont(self.label_font)
rect1 = QtCore.QRect(self.lpad, self.init_phase_y1, self.wid/10, self.label_height)
if self.plevel > 100:
hght = tab.utils.M2FT(tab.interp.hght(self.prof, self.plevel))
string = "Inital Phase: " + self.init_st + ' from: ' + tab.utils.INT2STR(self.plevel) + ' mb (' + tab.utils.INT2STR(hght) + ' ft msl; ' + tab.utils.FLOAT2STR(self.init_tmp,1) + ' C)'
else:
string = "Initial Phase: No Precipitation layers found."
qp.drawText(rect1, QtCore.Qt.TextDontClip | QtCore.Qt.AlignLeft, string)
if __name__ == '__main__':
app_frame = QtGui.QApplication([])
tester = plotWinter()
tester.show()
app_frame.exec_()