Implement SkewTOptions class

Implement SkewTOptions class to allow specifying exact items to be
rendered on a Skew-T chart
This commit is contained in:
XANTRONIX 2025-03-14 17:00:58 -04:00
parent 77fe922d90
commit 5bf5f66180

View file

@ -21,7 +21,7 @@ TEMP_CENTER = 0 # degrees C
TEMP_STEP = 5 TEMP_STEP = 5
TEMP_STEP_COUNT = math.ceil(TEMP_RANGE / TEMP_STEP) TEMP_STEP_COUNT = math.ceil(TEMP_RANGE / TEMP_STEP)
SKEW = 1.0 SKEW_DEFAULT = 1.0
def clamp(value, lowest, highest): def clamp(value, lowest, highest):
if value < lowest: if value < lowest:
@ -31,13 +31,25 @@ def clamp(value, lowest, highest):
return value return value
class SkewTGraph(): class SkewTOptions():
__slots__ = 'width', 'height', 'skew', 'temp_step_width', def __init__(self):
self.skew = SKEW_DEFAULT
self.draw_dry_adiabats = True
self.draw_moist_adiabats = True
self.draw_lcl = False
self.draw_lfc = False
self.draw_el = False
self.draw_cape_mixing_ratio = False
self.draw_cape_dry_adiabat = False
self.draw_cape_moist_adiabat = False
def __init__(self, width: float, height: float, skew: float=SKEW): class SkewTGraph():
__slots__ = 'width', 'height', 'opts', 'temp_step_width',
def __init__(self, width: float, height: float, opts: SkewTOptions=SkewTOptions()):
self.width = width self.width = width
self.height = height self.height = height
self.skew = skew self.opts = opts
self.temp_step_width = min(self.width, self.height) / TEMP_STEP_COUNT self.temp_step_width = min(self.width, self.height) / TEMP_STEP_COUNT
@ -75,7 +87,7 @@ class SkewTGraph():
cr.restore() cr.restore()
def skew_t_to_graph(self, x: float, y: float): def skew_t_to_graph(self, x: float, y: float):
return (x+self.skew*y, y) return (x+self.opts.skew*y, y)
def sample_to_graph(self, temp: float, pressure: float): def sample_to_graph(self, temp: float, pressure: float):
x = (temp / TEMP_STEP) * self.temp_step_width x = (temp / TEMP_STEP) * self.temp_step_width
@ -137,11 +149,13 @@ class SkewTGraph():
y: float): y: float):
cr.save() cr.save()
if self.opts.draw_dry_adiabats:
cr.set_source_rgba(1.0, 0.2, 0, 0.2) cr.set_source_rgba(1.0, 0.2, 0, 0.2)
for temp in range(-140, 140, 10): for temp in range(-160, 160, 10):
self.draw_adiabat(cr, x, y, temp, 1000.0, lambda t, p: LAPSE_RATE_DRY) self.draw_adiabat(cr, x, y, temp, 1000.0, lambda t, p: LAPSE_RATE_DRY)
if self.opts.draw_moist_adiabats:
cr.set_source_rgba(0.3, 0.1, 0, 0.2) cr.set_source_rgba(0.3, 0.1, 0, 0.2)
for temp in range(-140, 140, 5): for temp in range(-140, 140, 5):
@ -219,6 +233,32 @@ class SkewTGraph():
self.draw_isobars(cr, x, y) self.draw_isobars(cr, x, y)
self.draw_adiabats(cr, x, y) self.draw_adiabats(cr, x, y)
params = SoundingParameters.from_sounding(sounding)
if self.opts.draw_lcl:
cr.set_source_rgb(1.0, 0.4, 0.0)
self.draw_isobar(cr, x, y, params.lcl[1])
if self.opts.draw_lfc:
cr.set_source_rgb(1.0, 0.4, 0.0)
self.draw_isobar(cr, x, y, params.lfc[1])
if self.opts.draw_el:
cr.set_source_rgb(1.0, 0.4, 0.0)
self.draw_isobar(cr, x, y, params.el[1])
if self.opts.draw_cape_dry_adiabat:
cr.set_source_rgb(1.0, 0.8, 0.2)
self.draw_series(cr, x, y, params.dry_adiabat)
if self.opts.draw_cape_moist_adiabat:
cr.set_source_rgb(0.8, 0.5, 0.8)
self.draw_series(cr, x, y, params.moist_adiabat)
if self.opts.draw_cape_mixing_ratio:
cr.set_source_rgb(0.8, 0.8, 1.0)
self.draw_series(cr, x, y, params.saturated_mr_line)
cr.set_source_rgb(1, 0, 0) cr.set_source_rgb(1, 0, 0)
self.draw_sounding(cr, x, y, sounding, lambda s: s.temp) self.draw_sounding(cr, x, y, sounding, lambda s: s.temp)
@ -242,7 +282,7 @@ class SkewTLegend():
x_rel, y_rel = skew_t.sample_to_screen(temp, PRESSURE_MAX) x_rel, y_rel = skew_t.sample_to_screen(temp, PRESSURE_MAX)
if x_rel < 0: if x_rel < 0:
y_rel = skew_t.height + x_rel / skew_t.skew y_rel = skew_t.height + x_rel / skew_t.opts.skew
x_rel = 0 x_rel = 0
if y_rel <= 0: if y_rel <= 0: