diff options
-rw-r--r-- | metchart/aggregator/__init__.py (renamed from aggregator/__init__.py) | 0 | ||||
-rwxr-xr-x | metchart/aggregator/dwd_icon.py (renamed from aggregator/dwd_icon.py) | 2 | ||||
-rw-r--r-- | metchart/aggregator/misc.py (renamed from misc.py) | 0 | ||||
-rwxr-xr-x | metchart/aggregator/wyoming_sounding.py (renamed from aggregator/wyoming_sounding.py) | 2 | ||||
-rw-r--r-- | metchart/misc.py | 23 | ||||
-rw-r--r-- | metchart/modifier/__init__.py (renamed from modifier/__init__.py) | 0 | ||||
-rw-r--r-- | metchart/modifier/merge.py (renamed from modifier/merge.py) | 2 | ||||
-rw-r--r-- | metchart/plotter/__init__.py (renamed from plotter/__init__.py) | 0 | ||||
-rw-r--r-- | metchart/plotter/debug_data.py (renamed from plotter/debug_data.py) | 0 | ||||
-rwxr-xr-x | metchart/plotter/horizontal.py (renamed from plotter/horizontal.py) | 2 | ||||
-rwxr-xr-x | metchart/plotter/meteogram.py (renamed from plotter/meteogram.py) | 4 | ||||
-rwxr-xr-x | metchart/plotter/vertical_from_grib.py (renamed from plotter/vertical_from_grib.py) | 2 | ||||
-rwxr-xr-x | metchart/run.py | 110 | ||||
-rw-r--r-- | metchart/skewt.py (renamed from skewt.py) | 0 | ||||
-rw-r--r-- | pyproject.toml | 24 | ||||
-rwxr-xr-x | run.py | 106 |
16 files changed, 164 insertions, 113 deletions
diff --git a/aggregator/__init__.py b/metchart/aggregator/__init__.py index e69de29..e69de29 100644 --- a/aggregator/__init__.py +++ b/metchart/aggregator/__init__.py diff --git a/aggregator/dwd_icon.py b/metchart/aggregator/dwd_icon.py index 6df905c..ed5c149 100755 --- a/aggregator/dwd_icon.py +++ b/metchart/aggregator/dwd_icon.py @@ -13,7 +13,7 @@ import subprocess import xarray as xr -import misc +from . import misc BASE='https://opendata.dwd.de/weather/nwp' diff --git a/misc.py b/metchart/aggregator/misc.py index 6594d0f..6594d0f 100644 --- a/misc.py +++ b/metchart/aggregator/misc.py diff --git a/aggregator/wyoming_sounding.py b/metchart/aggregator/wyoming_sounding.py index 111e219..617d462 100755 --- a/aggregator/wyoming_sounding.py +++ b/metchart/aggregator/wyoming_sounding.py @@ -12,7 +12,7 @@ import numpy as np from metpy.units import units import metpy.calc as mpcalc -import misc +from .. import misc def get_current_run(): date=(datetime.date.today() - datetime.timedelta(days = 1)).strftime('%Y-%m-%d') diff --git a/metchart/misc.py b/metchart/misc.py new file mode 100644 index 0000000..6594d0f --- /dev/null +++ b/metchart/misc.py @@ -0,0 +1,23 @@ +import os +import numpy as np +import datetime + +def np_time_convert(dt64, func=datetime.datetime.utcfromtimestamp): + unix_epoch = np.datetime64(0, 's') + one_second = np.timedelta64(1, 's') + seconds_since_epoch = (dt64 - unix_epoch) / one_second + + return func(seconds_since_epoch) + +def np_time_convert_offset(init, step): + return np_time_convert(init) + np_time_convert(step, func=lambda x: datetime.timedelta(seconds=x)) + +def np_time_list_convert_offset(init, steps): + return list(map(lambda x: np_time_convert_offset(init, x), steps)) + +def create_output_dir(path, clear=False): + if not os.path.exists(path): + os.makedirs(path) + elif clear: + raise Exception('clear not implemented') + diff --git a/modifier/__init__.py b/metchart/modifier/__init__.py index e69de29..e69de29 100644 --- a/modifier/__init__.py +++ b/metchart/modifier/__init__.py diff --git a/modifier/merge.py b/metchart/modifier/merge.py index 692287d..1fb7fda 100644 --- a/modifier/merge.py +++ b/metchart/modifier/merge.py @@ -1,4 +1,4 @@ -import xarray as xr +import xarray as xr def run(data): return xr.merge(data) diff --git a/plotter/__init__.py b/metchart/plotter/__init__.py index e69de29..e69de29 100644 --- a/plotter/__init__.py +++ b/metchart/plotter/__init__.py diff --git a/plotter/debug_data.py b/metchart/plotter/debug_data.py index 560d13c..560d13c 100644 --- a/plotter/debug_data.py +++ b/metchart/plotter/debug_data.py diff --git a/plotter/horizontal.py b/metchart/plotter/horizontal.py index 218fd33..89945c3 100755 --- a/plotter/horizontal.py +++ b/metchart/plotter/horizontal.py @@ -8,7 +8,7 @@ import numpy as np import matplotlib.pyplot as plt from metpy.plots import MapPanel, PanelContainer, RasterPlot, ContourPlot -import misc +from . import misc config = { 'source': 'dwd_icon-eu/combined.grib2', diff --git a/plotter/meteogram.py b/metchart/plotter/meteogram.py index 724e9b2..8335247 100755 --- a/plotter/meteogram.py +++ b/metchart/plotter/meteogram.py @@ -8,7 +8,7 @@ import matplotlib.pyplot as plt import metpy.calc as mpcalc -import misc +from .. import misc HEIGHT = 13 @@ -68,7 +68,7 @@ def _add_convective_clouds(ax, data): ax.set_ylabel('Convective Clouds Height [km]') ax.bar(data.valid_time, alpha=0.5, bottom=data.HBAS_CON.metpy.convert_units('km').transpose(), - height=(data.hcct.metpy.convert_units('km')-data.HBAS_CON.metpy.convert_units('km')).transpose(), + height=(data.HTOP_CON.metpy.convert_units('km')-data.HBAS_CON.metpy.convert_units('km')).transpose(), align='edge', width=np.timedelta64(3, 'h')) def _add_precip(ax, data): diff --git a/plotter/vertical_from_grib.py b/metchart/plotter/vertical_from_grib.py index 8e4fd60..c632b0b 100755 --- a/plotter/vertical_from_grib.py +++ b/metchart/plotter/vertical_from_grib.py @@ -13,7 +13,7 @@ import numpy as np import skewt -import misc +from . import misc config = { 'source':'dwd_icon-eu/combined.grib2', diff --git a/metchart/run.py b/metchart/run.py new file mode 100755 index 0000000..17a0a97 --- /dev/null +++ b/metchart/run.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 + +import sys +import yaml +import json +import matplotlib.pyplot as plt +import matplotlib as mpl +from matplotlib.colors import LinearSegmentedColormap + +from metpy.units import units + +def create_aggregators(cfg): + ret = {} + for aggregator in cfg: + aggconf = cfg[aggregator] + classname = aggconf['module'] + del aggconf['module'] + + module = __import__(classname, fromlist=[None]) + + ret[aggregator] = module.load_data(name=aggregator, **aggconf) + + return ret + +def create_modifiers(aggregators, cfg): + # naming is scuffed + ret = {} + for modifier in cfg: + mod = cfg[modifier] + modname = mod['module'] + del mod['module'] + + if 'aggregator' in mod: + if type(mod['aggregator']) == list: + mod['data'] = [] + for ag in mod['aggregator']: + mod['data'].append(aggregators[ag]) + + del mod['aggregator'] + else: + mod['data'] = aggregators[mod['aggregator']] + del mod['aggregator'] + + pymod = __import__(modname, fromlist=[None]) + ret[modifier] = pymod.run(**mod) + + return ret + +def main(): + mpl.use('agg') + + # Define custom gpm and gpdm units. The default gpm in metpy is aliased to meter. + # We need the correct definition + units.define('_gpm = 9.80665 * J/kg') + units.define('_gpdm = 10 * _gpm') + + # Define custom colormap + clcov_cmap = { + 'red': ( + (0.0, 0.0, 0.0), + (0.1, 0.9, 0.9), + (1.0, 0.3, 0.3), + ), + 'green': ( + (0.0, 0.5, 0.5), + (0.1, 0.9, 0.9), + (1.0, 0.3, 0.3), + ), + 'blue': ( + (0.0, 0.9, 0.9), + (0.1, 0.9, 0.9), + (1.0, 0.3, 0.3), + ), + } + + mpl.colormaps.register(LinearSegmentedColormap('clcov', clcov_cmap)) + + FILE = 'config.yaml' + if len(sys.argv) > 1: + FILE = sys.argv[1] + + conf = None + with open(FILE, 'r') as f: + conf = yaml.safe_load(f) + + aggregators = create_aggregators(conf['aggregator']) + + if 'modifier' in conf: + aggregators.update(create_modifiers(aggregators, conf['modifier'])) + + index = [] + + for plotter in conf['plotter']: + modname = plotter['module'] + del plotter['module'] + + if 'aggregator' in plotter: + plotter['data'] = aggregators[plotter['aggregator']] + del plotter['aggregator'] + + mod = __import__(modname, fromlist=[None]) + index.extend(mod.run(**plotter)) + + plt.close('all') + + with open(conf['index'], 'w') as f: + f.write(json.dumps(index, indent=4)) + +if __name__ == '__main__': + main() diff --git a/skewt.py b/metchart/skewt.py index e674d09..e674d09 100644 --- a/skewt.py +++ b/metchart/skewt.py diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..53cd3e7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,24 @@ +[project] +name = "metchart" +version = "0.0.1" +dependencies = [ + "metpy", + "xarray", + "cfgrib", + "pyyaml", + "cartopy" +] +description = "declarative weather chart plotter" +readme = "Readme.md" + +[project.scripts] +metchart = "metchart.run:main" + +[tool.setuptools.packages.find] +include = [ + "metchart" +] + +[build-system] +requires = ['setuptools >= 61.0'] +build-backend = "setuptools.build_meta" @@ -1,106 +0,0 @@ -#!/usr/bin/env python3 - -import sys -import yaml -import json -import matplotlib.pyplot as plt -import matplotlib as mpl -from matplotlib.colors import LinearSegmentedColormap - -from metpy.units import units - -def create_aggregators(cfg): - ret = {} - for aggregator in cfg: - aggconf = cfg[aggregator] - classname = aggconf['module'] - del aggconf['module'] - - module = __import__(classname, fromlist=[None]) - - ret[aggregator] = module.load_data(name=aggregator, **aggconf) - - return ret - -def create_modifiers(aggregators, cfg): - # naming is scuffed - ret = {} - for modifier in cfg: - mod = cfg[modifier] - modname = mod['module'] - del mod['module'] - - if 'aggregator' in mod: - if type(mod['aggregator']) == list: - mod['data'] = [] - for ag in mod['aggregator']: - mod['data'].append(aggregators[ag]) - - del mod['aggregator'] - else: - mod['data'] = aggregators[mod['aggregator']] - del mod['aggregator'] - - pymod = __import__(modname, fromlist=[None]) - ret[modifier] = pymod.run(**mod) - - return ret - -mpl.use('agg') - -# Define custom gpm and gpdm units. The default gpm in metpy is aliased to meter. -# We need the correct definition -units.define('_gpm = 9.80665 * J/kg') -units.define('_gpdm = 10 * _gpm') - -# Define custom colormap -clcov_cmap = { - 'red': ( - (0.0, 0.0, 0.0), - (0.1, 0.9, 0.9), - (1.0, 0.3, 0.3), - ), - 'green': ( - (0.0, 0.5, 0.5), - (0.1, 0.9, 0.9), - (1.0, 0.3, 0.3), - ), - 'blue': ( - (0.0, 0.9, 0.9), - (0.1, 0.9, 0.9), - (1.0, 0.3, 0.3), - ), -} - -mpl.colormaps.register(LinearSegmentedColormap('clcov', clcov_cmap)) - -FILE = 'config.yaml' -if len(sys.argv) > 1: - FILE = sys.argv[1] - -conf = None -with open(FILE, 'r') as f: - conf = yaml.safe_load(f) - -aggregators = create_aggregators(conf['aggregator']) - -if 'modifier' in conf: - aggregators.update(create_modifiers(aggregators, conf['modifier'])) - -index = [] - -for plotter in conf['plotter']: - modname = plotter['module'] - del plotter['module'] - - if 'aggregator' in plotter: - plotter['data'] = aggregators[plotter['aggregator']] - del plotter['aggregator'] - - mod = __import__(modname, fromlist=[None]) - index.extend(mod.run(**plotter)) - - plt.close('all') - -with open(conf['index'], 'w') as f: - f.write(json.dumps(index, indent=4)) |