From 8c22ae7ce498a2bdd014c5a328693533c280a5d8 Mon Sep 17 00:00:00 2001 From: Mark Robertson Date: Tue, 31 Mar 2020 15:29:22 -0600 Subject: [PATCH] Add header information to daily SWE and SWI csv files, fixes #11 --- snowav/framework/figures.py | 23 +++++--- snowav/plotting/write_properties.py | 86 ++++++++++++++++++++--------- 2 files changed, 73 insertions(+), 36 deletions(-) diff --git a/snowav/framework/figures.py b/snowav/framework/figures.py index 6de6fd0..c3321c8 100755 --- a/snowav/framework/figures.py +++ b/snowav/framework/figures.py @@ -1,8 +1,9 @@ -import os -import numpy as np -import pandas as pd import copy from datetime import datetime, timedelta +import numpy as np +import os +import pandas as pd + from tablizer.tablizer import get_existing_records from snowav.plotting.swi import swi from snowav.plotting.basin_total import basin_total @@ -18,7 +19,6 @@ from snowav.plotting.inputs import inputs from snowav.inflow.inflow import inflow from snowav.plotting.diagnostics import diagnostics -from snowav.plotting.plotlims import plotlims from snowav.plotting.point_values import point_values from snowav.database.database import collect from snowav.plotting.plotlims import plotlims as plotlims @@ -311,6 +311,10 @@ def figures(cfg, process): if not flag: cfg.stn_validate_flag = False + else: + # assign fig name to cfg for use in report.py + cfg.assign_vars({'stn_validate_fig_name': ''}) + if cfg.point_values_flag and cfg.point_values: # check that cfg.point_values_date falls within options @@ -440,11 +444,12 @@ def figures(cfg, process): inflow(args, cfg._logger) - # if cfg.write_properties is not None: - # args['connector'] = cfg.connector - # args['wy_start'] = datetime(cfg.wy - 1, 10, 1) - - write_properties(args, cfg.write_properties, cfg._logger) + if cfg.write_properties is not None: + write_properties(args['end_date'], cfg.connector, args['plotorder'], + args['basins'], datetime(cfg.wy-1, 10, 1), + args['run_name'], args['figs_path'], + cfg.write_properties, vollbl=args['vollbl'], + logger=cfg._logger) if cfg.inputs_fig_flag: diff --git a/snowav/plotting/write_properties.py b/snowav/plotting/write_properties.py index 4e37453..fdf9be1 100755 --- a/snowav/plotting/write_properties.py +++ b/snowav/plotting/write_properties.py @@ -1,43 +1,75 @@ +from datetime import datetime +import os from snowav.database.database import collect -import pandas as pd -from datetime import timedelta -def write_properties(args, values, logger): - ''' - Write daily total snowpack properties to csv. + +def write_properties(end_date, cnx, plotorder, basins, wy_start, run_name, + figs_path, values, vollbl='TAF', logger=None): + """ Write daily total snowpack properties to csv. Args ------ - args : dict - dictionary with required inputs, see swi() figure for more information. - values : str - snowav database value to query and write to csv - - ''' + end_date {str}: end_date + cnx {str}: database connector + plotorder {list}: basins list + basins {dict}: basins dict + wy_start {str}: YYYY1001 + run_name {str}: snowav run_name + figs_path {str}: path to save files + values {list}: list of snowav values + vollbl {str}: volume label + depthlbl {str}: depth label + logger {class}: logger + """ - datestr = args['end_date'] + timedelta(hours=24) - datestr = datestr.strftime("%Y%m%d") + datestr = end_date.strftime("%Y%m%d") + now_str = datetime.now().date().strftime("%Y-%m-%d") + date_col = 'Date generated: {}'.format(now_str) + unit = vollbl for value in values: - out = collect(args['connector'], args['plotorder'], args['basins'], - args['wy_start'], args['end_date'], value, args['run_name'], - 'total','daily') + out = collect(cnx, plotorder, basins, wy_start, end_date, value, + run_name, 'total', 'daily') + + out.index = out.index.date + + # setting index to date strips the index name + out.index.name = 'date' - if 'vol' in value or 'avail' in value: - unit = args['vollbl'] + if value.lower() == 'swe_vol': + value_line = ('Snow Water Equivalent (SWE) volume in thousands ' + + 'of acre-feet (TAF)') + elif value.lower() == 'swi_vol': + value_line = ('Surface Water Input (SWI) volume in thousands ' + + 'of acre-feet (TAF)') + else: + if logger is not None: + logger.warning(" Value types other than swe, swi, and " + "their derivates are not supported") + return - if 'z' in value or value == 'depth': - unit = args['depthlbl'] + headers = ['USDA Agicultural Research Service Snowpack Summary Data', + value_line, + 'Data provided are daily model results from the iSnobal model', + 'First column is the date of model result', + 'Second column is the total basin volume', + 'Additional columns are the subbasins in the watershed', + date_col, + 'Valid until next reports are generated', + 'Contact: Scott Havens ' + '\n'] - if value == 'density': - unit = 'kg_m3' + filename = '{}_timeseries_{}_{}.csv'.format(value, datestr, unit.lower()) + path = os.path.join(os.path.abspath(figs_path), filename) - if value == 'coldcont': - unit = 'MJ' + if os.path.isfile(path): + os.remove(path) - path = '{}{}_timeseries_{}_{}.csv'.format(args['figs_path'], value, datestr, unit.lower()) + with open(path, mode='w', encoding='utf-8') as f: + f.write('\n'.join(headers)) - logger.info(' saving {}'.format(path)) + out.to_csv(path, encoding='utf-8', mode='a') - out.to_csv(path) + if logger is not None: + logger.info(' Saved: {}'.format(path))