diff --git a/mpas_analysis/ocean/index_nino34.py b/mpas_analysis/ocean/index_nino34.py index b7a80cf66..366c2bfee 100644 --- a/mpas_analysis/ocean/index_nino34.py +++ b/mpas_analysis/ocean/index_nino34.py @@ -14,12 +14,12 @@ from ..shared.constants import constants from ..shared.io.utility import build_config_full_path -from ..shared.timekeeping.utility import get_simulation_start_time, \ - datetime_to_days, string_to_days_since_date +from ..shared.timekeeping.utility import datetime_to_days, \ + string_to_days_since_date from ..shared.io import open_mpas_dataset -from ..shared.plot.plotting import plot_xtick_format, plot_size_y_axis +from ..shared.plot.plotting import plot_xtick_format from ..shared import AnalysisTask from ..shared.html import write_image_xml @@ -63,7 +63,7 @@ def __init__(self, config, mpasTimeSeriesTask): # {{{ config=config, taskName='indexNino34', componentName='ocean', - tags=['index', 'nino']) + tags=['timeSeries', 'index', 'nino']) self.mpasTimeSeriesTask = mpasTimeSeriesTask @@ -87,8 +87,8 @@ def setup_and_check(self): # {{{ # self.calendar super(IndexNino34, self).setup_and_check() - self.startDate = self.config.get('timeSeries', 'startDate') - self.endDate = self.config.get('timeSeries', 'endDate') + self.startDate = self.config.get('index', 'startDate') + self.endDate = self.config.get('index', 'endDate') self.variableList = \ ['timeMonthly_avg_avgValueWithinOceanRegion_avgSurfaceTemperature'] @@ -165,55 +165,57 @@ def run_task(self): # {{{ self.logger.info(' Compute NINO3.4 index...') varName = self.variableList[0] regionSST = ds[varName].isel(nOceanRegions=regionIndex) - nino34 = self._compute_nino34_index(regionSST, calendar) + nino34Main = self._compute_nino34_index(regionSST, calendar) # Compute the observational index over the entire time range # nino34Obs = compute_nino34_index(dsObs.sst, calendar) self.logger.info(' Computing NINO3.4 power spectra...') - f, spectra, conf99, conf95, redNoise = \ - self._compute_nino34_spectra(nino34) + spectraMain = self._compute_nino34_spectra(nino34Main) # Compute the observational spectra over the whole record - fObs, spectraObs, conf99Obs, conf95Obs, redNoiseObs = \ - self._compute_nino34_spectra(nino34Obs) + spectraObs = self._compute_nino34_spectra(nino34Obs) # Compute the observational spectra over the last 30 years for # comparison. Only saving the spectra - time_start = datetime_to_days(datetime.datetime(1976, 1, 1), + subsetStartYear = 1976 + subsetEndYear = 2016 + time_start = datetime_to_days(datetime.datetime(subsetStartYear, 1, 1), calendar=calendar) - time_end = datetime_to_days(datetime.datetime(2016, 12, 31), + time_end = datetime_to_days(datetime.datetime(subsetEndYear, 12, 31), calendar=calendar) - nino3430 = nino34Obs.sel(Time=slice(time_start, time_end)) - f30, spectra30yrs, conf9930, conf9530, redNoise30 = \ - self._compute_nino34_spectra(nino3430) + nino34Subset = nino34Obs.sel(Time=slice(time_start, time_end)) + spectraSubset = self._compute_nino34_spectra(nino34Subset) # Convert frequencies to period in years - f = 1.0 / (constants.eps + f*constants.sec_per_year) - fObs = 1.0 / (constants.eps + fObs*constants.sec_per_year) - f30 = 1.0 / (constants.eps + f30*constants.sec_per_year) + for spectra in [spectraMain, spectraObs, spectraSubset]: + spectra['period'] = \ + 1.0 / (constants.eps + spectra['f']*constants.sec_per_year) self.logger.info(' Plot NINO3.4 index and spectra...') - figureName = '{}/NINO34_{}.png'.format(self.plotsDirectory, - mainRunName) - modelTitle = "{}".format(mainRunName) - self._nino34_timeseries_plot(config, nino34, nino34Obs, nino3430, - 'NINO 3.4 Index', modelTitle, obsTitle, - figureName, linewidths=2, - calendar=calendar) + outFileName = '{}/NINO34_{}.png'.format(self.plotsDirectory, + mainRunName) + titles = ['{} (Full Record)'.format(obsTitle), + '{} ({} - {})'.format(obsTitle, subsetStartYear, + subsetEndYear), + mainRunName] + self._nino34_timeseries_plot( + nino34s=[nino34Obs[2:-3], nino34Subset, nino34Main[2:-3]], + title='NINO 3.4 Index', + panelTitles=titles, + outFileName=outFileName) self._write_xml(filePrefix='NINO34_{}'.format(mainRunName), plotType='Time Series') - figureName = '{}/NINO34_spectra_{}.png'.format(self.plotsDirectory, - mainRunName) - self._nino34_spectra_plot(config, f, spectra, conf95, conf99, redNoise, - fObs, f30, spectraObs, conf95Obs, conf99Obs, - redNoiseObs, spectra30yrs, conf9530, - conf9930, redNoise30, - 'NINO3.4 power spectrum', modelTitle, - obsTitle, figureName, linewidths=2) + outFileName = '{}/NINO34_spectra_{}.png'.format(self.plotsDirectory, + mainRunName) + self._nino34_spectra_plot( + spectra=[spectraObs, spectraSubset, spectraMain], + title='NINO3.4 power spectrum', + panelTitles=titles, + outFileName=outFileName) self._write_xml(filePrefix='NINO34_spectra_{}'.format(mainRunName), plotType='Spectra') @@ -353,7 +355,9 @@ def _compute_nino34_spectra(self, nino34Index): # {{{ # return Spectra, 99% confidence level, 95% confidence level, # and Red-noise fit - return f, pxxSmooth, mkov*scale*xHigh, mkov*scale*xLow, mkov*scale + spectra = {'f': f, 'spectrum': pxxSmooth, 'conf99': mkov*scale*xHigh, + 'conf95': mkov*scale*xLow, 'redNoise': mkov*scale} + return spectra # }}} def _autocorr(self, x, t=1): # {{{ @@ -405,73 +409,38 @@ def _running_mean(self, inputData, wgts): # {{{ return runningMean # }}} - def _nino34_spectra_plot(self, config, f, ninoSpectra, - confidence95, confidence99, redNoiseSpectra, - fObs, f30, ninoObs, - conf95Obs, conf99Obs, redNoiseObs, - nino30yr, conf9530, conf9930, redNoise30, - title, modelTitle, obsTitle, - fileout, linewidths, xlabel='Period (years)', + def _nino34_spectra_plot(self, spectra, title, panelTitles, + outFileName, lineWidth=2, xlabel='Period (years)', ylabel=r'Power ($^o$C / cycles mo$^{-1}$)', - titleFontSize=None, figsize=(9, 21), dpi=None): + titleFontSize=None, figsize=(9, 21), dpi=None, + periodMin=1., periodMax=10.): # {{{ """ Plots the nino34 time series and power spectra in an image file Parameters ---------- - config : instance of ConfigParser - the configuration, containing a [plot] section with options that - control plotting - - f : numpy.array - periods to plot on x-axis - - ninoSpectra : xarray.dataArray object - nino34 power spectra - - confidence95 : numpy.array - 95% confidence level based on chi squared test - - confidence99 : numpy.array - 99% confidence level based on chi squared test - - redNoiseSpectra : numpy.array - red noise fit to the ninoSpectra - - fObs : numpy.array - periods to plot on x-axis for observations - - ninoObs : xarray.dataArray object - nino34 power spectra from the full observational record - - conf95Obs : numpy.array - 95% confidence level based on chi squared for observations - - conf99Obs : numpy.array - 99% confidence level based on chi squared for observations - - redNoiseObs : numpy.array - red noise fit to ninoObs - - nino30yr : xarray.dataArray object - power spectra of the last 30 years of the observational record + spectra : list of dict + a dictionary for each panel returned from + ``self._compute_nino34_spectra`` including entries + ``period`` (periods to plot on x-axis), ``spectrum`` (nino34 power + spectra), ``conf95`` (95% confidence level based on chi squared + test), ``conf99`` (99% confidence level based on chi squared test) + and ``redNoise`` (red noise fit to ``spectrum``) title : str the title of the plot - modelTitle : str - the title of model panel - - obsTitle : str - the title of the obs panel + panelTitles : list of str + title of each panel of the plot - xLabel, yLabel : str - axis labels - - fileout : str + outFileName : str the file name to be written - linewidths : control line width + lineWidth : int, optional + control line width + + xLabel, yLabel : str, optional + axis labels titleFontSize : int, optional the size of the title font @@ -483,10 +452,14 @@ def _nino34_spectra_plot(self, config, f, ninoSpectra, the number of dots per inch of the figure, taken from section ``plot`` option ``dpi`` in the config file by default + periodMin, periodMax : float, optional + the maximum and minimum periods (in years) to be plotted + Authors ------- Luke Van Roekel, Xylar Asay-Davis """ + config = self.config if dpi is None: dpi = config.getint('plot', 'dpi') @@ -502,137 +475,95 @@ def _nino34_spectra_plot(self, config, f, ninoSpectra, if title is not None: fig.suptitle(title, y=0.92, **title_font) - plt.subplot(3, 1, 1) - - plt.plot(fObs[2:-3], ninoObs[2:-3], 'k', linewidth=linewidths) - plt.plot(fObs[2:-3], redNoiseObs[2:-3], 'r', linewidth=linewidths) - plt.plot(fObs[2:-3], conf95Obs[2:-3], 'b', linewidth=linewidths) - plt.plot(fObs[2:-3], conf99Obs[2:-3], 'g', linewidth=linewidths) - plt.xlim(10, 1) - - plt.legend(['Nino34 spectra (Full Record)', 'Red noise fit', - '95% confidence threshold', '99% confidence threshold'], - loc='upper right') - maxObs = plot_size_y_axis(plt, fObs, c1=conf99Obs, c2=redNoiseObs) - max30 = plot_size_y_axis(plt, f30, c1=conf9930, c2=redNoise30) - maxModel = plot_size_y_axis(plt, f, c1=ninoSpectra.values, - c2=confidence99, c3=redNoiseSpectra) - - maxYval = max(maxObs, max30, maxModel) - plt.ylim(0, 0.9*maxYval) - - if obsTitle is not None: - plt.title(obsTitle+' (Full Record)', **title_font) - if xlabel is not None: - plt.xlabel(xlabel, **axis_font) - if ylabel is not None: - plt.ylabel(ylabel, **axis_font) - - plt.subplot(3, 1, 2) - - plt.plot(f30[2:-3], nino30yr[2:-3], 'k', linewidth=linewidths) - plt.plot(f30[2:-3], redNoise30[2:-3], 'r', linewidth=linewidths) - plt.plot(f30[2:-3], conf9530[2:-3], 'b', linewidth=linewidths) - plt.plot(f30[2:-3], conf9930[2:-3], 'g', linewidth=linewidths) - plt.xlim(10, 1) - plt.ylim(0, 0.9*maxYval) - - plt.legend(['Nino34 spectra (1976 - 2016)', 'Red noise fit', - '95% confidence threshold', '99% confidence threshold'], - loc='upper right') - - if obsTitle is not None: - plt.title(obsTitle+' (1976-2016)', **title_font) - if xlabel is not None: - plt.xlabel(xlabel, **axis_font) - if ylabel is not None: - plt.ylabel(ylabel, **axis_font) - - plt.subplot(3, 1, 3) - plt.plot(f[2:-3], ninoSpectra[2:-3], 'k', linewidth=linewidths) - plt.plot(f[2:-3], redNoiseSpectra[2:-3], 'r', linewidth=linewidths) - plt.plot(f[2:-3], confidence95[2:-3], 'b', linewidth=linewidths) - plt.plot(f[2:-3], confidence99[2:-3], 'g', linewidth=linewidths) - plt.xlim(10, 1) - plt.ylim(0, 0.9*maxYval) - - # add legend - plt.legend(['Nino34 index spectra', 'Red noise fit', - '95% confidence threshold', '99% confidence threshold'], - loc='upper right') - - if modelTitle is not None: - plt.title(modelTitle, **title_font) - if xlabel is not None: - plt.xlabel(xlabel, **axis_font) - if ylabel is not None: - plt.ylabel(ylabel, **axis_font) + spectrumNames = ['spectrum', 'redNoise', 'conf95', 'conf99'] + colors = ['k', 'r', 'g', 'b'] + legends = ['Nino34 spectrum', 'Red noise fit', + '95% confidence threshold', '99% confidence threshold'] + + maxYval = -1e20 + for plotIndex in range(3): + x = spectra[plotIndex]['period'] + ys = [spectra[plotIndex][spectrumNames[curveIndex]] for curveIndex + in range(4)] + maxYval = max(maxYval, + self._plot_size_y_axis(x=x, ys=ys, xmin=periodMin, + xmax=periodMax)) + + for plotIndex in range(3): + plt.subplot(3, 1, plotIndex+1) + + period = spectra[plotIndex]['period'] + for curveIndex in range(4): + spectrum = spectra[plotIndex][spectrumNames[curveIndex]] + plt.plot(period[2:-3], spectrum[2:-3], colors[curveIndex], + linewidth=lineWidth, label=legends[curveIndex]) + plt.xlim(10, 1) + + plt.legend(loc='upper right') + plt.ylim(0, 0.9*maxYval) + + if panelTitles[plotIndex] is not None: + plt.title(panelTitles[plotIndex], **title_font) + if xlabel is not None: + plt.xlabel(xlabel, **axis_font) + if ylabel is not None: + plt.ylabel(ylabel, **axis_font) plt.tight_layout(rect=[0, 0.03, 1, 0.90]) - if fileout is not None: - fig.savefig(fileout, dpi=dpi, bbox_inches='tight', pad_inches=0.1) + if outFileName is not None: + fig.savefig(outFileName, dpi=dpi, bbox_inches='tight', + pad_inches=0.1) if not config.getboolean('plot', 'displayToScreen'): plt.close() # }}} - def _nino34_timeseries_plot(self, config, nino34Index, nino34Obs, nino3430, - title, modelTitle, obsTitle, fileout, - linewidths, calendar, xlabel='Time (years)', - ylabel='($^\circ$C)', titleFontSize=None, - figsize=(9, 21), dpi=None, maxXTicks=20): + def _nino34_timeseries_plot(self, nino34s, title, panelTitles, outFileName, + xlabel='Time (years)', ylabel='($^\circ$C)', + titleFontSize=None, figsize=(9, 21), dpi=None, + maxXTicks=20, lineWidth=2): # {{{ """ Plots the nino34 time series and power spectra in an image file Parameters ---------- - config : instance of ConfigParser - the configuration, containing a [plot] section with options that - control plotting - - nino34Index : xarray.dataArray - nino34 timeseries to plot - - nino34Obs : xarray.dataArray - nino34 observation - - nino3430 : xarray.dataArray - subset of nino34 observations + nino34s : list of xarray.dataArray + nino34 timeseries to plot in each panel title : str the title of the plot - obsTitle : str - title of observational plot + panelTitles : list of str + title of each panel of the plot - modelTitle : str - title of model plot + outFileName : str + the file name to be written xLabel, yLabel : str axis labels - fileout : str - the file name to be written - - lineWidths : list of str - control line width - titleFontSize : int, optional the size of the title font - figsize : tuple of floa # {{{t, optional + figsize : tuple of float, optional the size of the figure in inches dpi : int, optional the number of dots per inch of the figure, taken from section ``plot`` option ``dpi`` in the config file by default + lineWidth : int, optional + control line width + Authors ------- Luke Van Roekel, Xylar Asay-Davis """ + config = self.config + calendar = self.calendar + if dpi is None: dpi = config.getint('plot', 'dpi') fig = plt.figure(figsize=figsize, dpi=dpi) @@ -647,56 +578,32 @@ def _nino34_timeseries_plot(self, config, nino34Index, nino34Obs, nino3430, if title is not None: fig.suptitle(title, y=0.92, **title_font) - # Plot Nino34 Observation Time series - plt.subplot(3, 1, 1) - index = nino34Obs[2:-3].values - time = nino34Obs.Time[2:-3].values - self._plot_nino_timeseries(index, time, xlabel, ylabel, - obsTitle+' (Full Record)', calendar, - title_font, axis_font, linewidths) - - minDays = time.min() - maxDays = time.max() + for plotIndex in range(3): + plt.subplot(3, 1, plotIndex+1) + index = nino34s[plotIndex].values + time = nino34s[plotIndex].Time.values + self._plot_nino_timeseries(index, time, xlabel, ylabel, + panelTitles[plotIndex], + title_font, axis_font, lineWidth) - plot_xtick_format(plt, calendar, minDays, maxDays, maxXTicks) + minDays = time.min() + maxDays = time.max() - # Plot subset of the observational data set - plt.subplot(3, 1, 2) - index = nino3430.values - time = nino3430.Time.values - self._plot_nino_timeseries(index, time, xlabel, ylabel, - obsTitle+' (1976 - 2016)', calendar, - title_font, axis_font, linewidths) - - minDays = time.min() - maxDays = time.max() - - plot_xtick_format(plt, calendar, minDays, maxDays, maxXTicks) - - # Plot Nino34 model time series - plt.subplot(3, 1, 3) - index = nino34Index[2:-3].values - time = nino34Index.Time[2:-3].values - self._plot_nino_timeseries(index, time, xlabel, ylabel, - modelTitle, calendar, title_font, axis_font, - linewidths) - minDays = time.min() - maxDays = time.max() - - plot_xtick_format(plt, calendar, minDays, maxDays, maxXTicks) + plot_xtick_format(plt, calendar, minDays, maxDays, maxXTicks) plt.tight_layout(rect=[0, 0.03, 1, 0.90]) - if fileout is not None: - plt.savefig(fileout, dpi=dpi, bbox_inches='tight', pad_inches=0.1) + if outFileName is not None: + plt.savefig(outFileName, dpi=dpi, bbox_inches='tight', + pad_inches=0.1) if not config.getboolean('plot', 'displayToScreen'): plt.close() # }}} def _plot_nino_timeseries(self, ninoIndex, time, xlabel, ylabel, - panelTitle, calendar, title_font, axis_font, - linewidths): # {{{ + panelTitle, title_font, axis_font, + lineWidth): # {{{ ''' Plot the nino time series on a subplot @@ -717,10 +624,7 @@ def _plot_nino_timeseries(self, ninoIndex, time, xlabel, ylabel, panelTitle : string string to label the subplot with - calendar : str - specified calendar for the plot - - lineWidths : list of str + lineWidth : list of str control line width Authors @@ -734,9 +638,9 @@ def _plot_nino_timeseries(self, ninoIndex, time, xlabel, ylabel, y2 = np.zeros(nt) plt.plot(time, 0.4*np.ones(nt), '--k', - linewidth=linewidths) + linewidth=lineWidth) plt.plot(time, -0.4*np.ones(nt), '--k', - linewidth=linewidths) + linewidth=lineWidth) plt.fill_between(time, y1, y2, where=y1 > y2, facecolor='red', interpolate=True, linewidth=0) plt.fill_between(time, y1, y2, where=y1 < y2, @@ -761,6 +665,41 @@ def _write_xml(self, filePrefix, plotType): # {{{ imageDescription=caption, imageCaption=caption) # }}} + def _plot_size_y_axis(self, x, ys, xmin, xmax): + ''' + Get the maximum y value over the given range of x values + + Parameters + ---------- + x : numpy.array + x values + + ys : list of numpy.array + a list of curves (y values) + + xmin : float + The minimum x value + + xmax : float, optional + The maximum x values + + Authors + ------- + Luke Van Roekel, Xylar Asay-Davis + ''' + mask = np.logical_and(x >= xmin, x <= xmax) + + # find maximum value of three curves plotted + maxY = -1E20 + for y in ys: + maxY = max(y[mask].max(), maxY) + # check the function interpolated to the max/min as well + # Note: flipping the axis so x is in increasing order + maxY = max(np.interp(xmin, x[::-1], y[::-1]), maxY) + maxY = max(np.interp(xmax, x[::-1], y[::-1]), maxY) + + return maxY + # }}} # vim: foldmethod=marker ai ts=4 sts=4 et sw=4 ft=python diff --git a/mpas_analysis/ocean/meridional_heat_transport.py b/mpas_analysis/ocean/meridional_heat_transport.py index 53722e859..80d7ba51a 100644 --- a/mpas_analysis/ocean/meridional_heat_transport.py +++ b/mpas_analysis/ocean/meridional_heat_transport.py @@ -6,15 +6,12 @@ import numpy as np import netCDF4 import os -import warnings from ..shared.plot.plotting import plot_vertical_section,\ setup_colormap, plot_1D from ..shared.io.utility import build_config_full_path -from ..shared.timekeeping.utility import get_simulation_start_time - from ..shared import AnalysisTask from ..shared.html import write_image_xml @@ -119,8 +116,8 @@ def setup_and_check(self): # {{{ if os.path.exists(observationsFile): self.observationsFile = observationsFile else: - warnings.warn('No MHT observations file found: skip plotting ' - 'obs') + print('Warning: No MHT observations file found: skip plotting ' + 'obs') mainRunName = self.config.get('runs', 'mainRunName') diff --git a/mpas_analysis/shared/analysis_task.py b/mpas_analysis/shared/analysis_task.py index 0e38798db..53bb262cd 100644 --- a/mpas_analysis/shared/analysis_task.py +++ b/mpas_analysis/shared/analysis_task.py @@ -10,7 +10,6 @@ from __future__ import absolute_import, division, print_function, \ unicode_literals -import warnings from multiprocessing import Process, Value import time import traceback @@ -451,13 +450,12 @@ def check_analysis_enabled(self, analysisOptionName, default=False, except ValueError: enabled = default if default: - message = 'WARNING: namelist option {} not found.\n' \ - 'This likely indicates that the simulation you ' \ - 'are analyzing was run with an\n' \ - 'older version of MPAS-O that did not support ' \ - 'this flag. Assuming enabled.'.format( - analysisOptionName) - warnings.warn(message) + print('Warning: namelist option {} not found.\n' + 'This likely indicates that the simulation you ' + 'are analyzing was run with an\n' + 'older version of MPAS-O that did not support ' + 'this flag. Assuming enabled.'.format( + analysisOptionName)) if not enabled and raiseException: raise RuntimeError('*** MPAS-Analysis relies on {} = .true.\n' diff --git a/mpas_analysis/shared/climatology/mpas_climatology_task.py b/mpas_analysis/shared/climatology/mpas_climatology_task.py index e741ba9fc..ac7020073 100644 --- a/mpas_analysis/shared/climatology/mpas_climatology_task.py +++ b/mpas_analysis/shared/climatology/mpas_climatology_task.py @@ -4,7 +4,6 @@ import xarray import os -import warnings import subprocess from distutils.spawn import find_executable @@ -288,14 +287,13 @@ def _update_climatology_bounds_from_file_names(self): # {{{ endYear = years[lastIndex] if startYear != requestedStartYear or endYear != requestedEndYear: - message = "climatology start and/or end year different from " \ - "requested\n" \ - "requestd: {:04d}-{:04d}\n" \ - "actual: {:04d}-{:04d}\n".format(requestedStartYear, - requestedEndYear, - startYear, - endYear) - warnings.warn(message) + print("Warning: climatology start and/or end year different from " + "requested\n" + "requestd: {:04d}-{:04d}\n" + "actual: {:04d}-{:04d}\n".format(requestedStartYear, + requestedEndYear, + startYear, + endYear)) config.set('climatology', 'startYear', str(startYear)) config.set('climatology', 'endYear', str(endYear)) diff --git a/mpas_analysis/shared/plot/plotting.py b/mpas_analysis/shared/plot/plotting.py index 64cb4c2ab..fd86777c8 100644 --- a/mpas_analysis/shared/plot/plotting.py +++ b/mpas_analysis/shared/plot/plotting.py @@ -1144,42 +1144,6 @@ def setup_colormap(config, configSectionName, suffix=''): return (colormap, colorbarLevels) -def plot_size_y_axis(plt, xaxisValues, **data): - ''' - Resize the y-axis limit based on the curves being plotted - - Parameters - ---------- - plt : plot handle - - xaxisValues : numpy.array - Values plotted along the x-axis - - data : dictionary entries must be numpy.array - data for curves on plot - - Authors - ------- - Luke Van Roekel - ''' - - ax = plt.gca() - xmin = ax.get_xlim()[0] - xmax = ax.get_xlim()[1] - - # find period/frequency bounds for chosen xmin/xmax - minIndex = np.abs(xaxisValues - xmin).argmin() - maxIndex = np.abs(xaxisValues - xmax).argmin() - - # find maximum value of three curves plotted - maxCurveVal = -1E20 - for key in data: - maxTemp = data[key][minIndex:maxIndex].max() - maxCurveVal = max(maxTemp, maxCurveVal) - - return maxCurveVal - - def plot_xtick_format(plt, calendar, minDays, maxDays, maxXTicks): ''' Formats tick labels and positions along the x-axis for time series diff --git a/mpas_analysis/shared/time_series/mpas_time_series_task.py b/mpas_analysis/shared/time_series/mpas_time_series_task.py index 4f165d815..f9aa170ef 100644 --- a/mpas_analysis/shared/time_series/mpas_time_series_task.py +++ b/mpas_analysis/shared/time_series/mpas_time_series_task.py @@ -3,7 +3,6 @@ unicode_literals import os -import warnings import subprocess from distutils.spawn import find_executable import xarray as xr @@ -42,7 +41,7 @@ class MpasTimeSeriesTask(AnalysisTask): # {{{ ''' def __init__(self, config, componentName, taskName=None, - subtaskName=None): # {{{ + subtaskName=None, section='timeSeries'): # {{{ ''' Construct the analysis task for extracting time series. @@ -62,19 +61,22 @@ def __init__(self, config, componentName, taskName=None, subtaskName : str, optional The name of the subtask (if any) + section : str, optional + The section of the config file from which to read the start and + end times for the time series, also added as a tag Authors ------- Xylar Asay-Davis ''' self.variableList = [] - self.seasons = [] + self.section = section + tags = [section] - tags = ['timeSeries'] - - suffix = componentName[0].upper() + componentName[1:] if taskName is None: - taskName = 'mpasTimeSeries{}'.format(suffix) + suffix = section[0].upper() + section[1:] + \ + componentName[0].upper() + componentName[1:] + taskName = 'mpas{}'.format(suffix) # call the constructor from the base class (AnalysisTask) super(MpasTimeSeriesTask, self).__init__( @@ -138,8 +140,8 @@ def setup_and_check(self): # {{{ # get a list of timeSeriesStats output files from the streams file, # reading only those that are between the start and end dates - startDate = config.get('timeSeries', 'startDate') - endDate = config.get('timeSeries', 'endDate') + startDate = config.get(self.section, 'startDate') + endDate = config.get(self.section, 'endDate') streamName = 'timeSeriesStatsMonthlyOutput' self.inputFiles = self.historyStreams.readpath( streamName, startDate=startDate, endDate=endDate, @@ -200,7 +202,7 @@ def _update_time_series_bounds_from_file_names(self): # {{{ """ config = self.config - section = 'timeSeries' + section = self.section requestedStartYear = config.getint(section, 'startYear') requestedEndYear = config.getint(section, 'endYear') @@ -222,14 +224,14 @@ def _update_time_series_bounds_from_file_names(self): # {{{ endYear = years[lastIndex] if startYear != requestedStartYear or endYear != requestedEndYear: - message = "time series start and/or end year different from " \ - "requested\n" \ - "requestd: {:04d}-{:04d}\n" \ - "actual: {:04d}-{:04d}\n".format(requestedStartYear, - requestedEndYear, - startYear, - endYear) - warnings.warn(message) + print("Warning: {} start and/or end year different from " + "requested\n" \ + "requestd: {:04d}-{:04d}\n" \ + "actual: {:04d}-{:04d}\n".format(section, + requestedStartYear, + requestedEndYear, + startYear, + endYear)) config.set(section, 'startYear', str(startYear)) config.set(section, 'endYear', str(endYear)) @@ -280,7 +282,7 @@ def _compute_time_series_with_ncrcat(self): with xr.open_dataset(self.outputFile) as ds: dates = [bytes.decode(name) for name in - ds.xtime_startMonthly.values] + ds.xtime_startMonthly.values] lastDate = dates[-1] lastYear = int(lastDate[0:4]) diff --git a/mpas_analysis/shared/time_series/time_series.py b/mpas_analysis/shared/time_series/time_series.py index c39d44b22..76df1ab20 100644 --- a/mpas_analysis/shared/time_series/time_series.py +++ b/mpas_analysis/shared/time_series/time_series.py @@ -12,7 +12,6 @@ import xarray as xr import numpy import os -import warnings from ..timekeeping.utility import days_to_datetime @@ -87,7 +86,7 @@ def cache_time_series(timesInDataSet, timeSeriesCalcFunction, cacheFileName, message = 'Deleting cache file {}, which appears to have ' \ 'been corrupted.'.format(cacheFileName) if logger is None: - warnings.warn(message) + print('Warning: {}'.format(message)) else: logger.warning(message) os.remove(cacheFileName) diff --git a/mpas_analysis/test/test_mpas_climatology_task.py b/mpas_analysis/test/test_mpas_climatology_task.py index 24c897a14..8ba50800b 100644 --- a/mpas_analysis/test/test_mpas_climatology_task.py +++ b/mpas_analysis/test/test_mpas_climatology_task.py @@ -142,8 +142,7 @@ def test_update_climatology_bounds_from_file_names(self): config.set('climatology', 'startDate', startDate) config.set('climatology', 'endDate', endDate) - with pytest.warns(UserWarning): - mpasClimatologyTask._update_climatology_bounds_from_file_names() + mpasClimatologyTask._update_climatology_bounds_from_file_names() startYear = 2 endYear = 2 diff --git a/run_mpas_analysis b/run_mpas_analysis index 168b565d7..973e0b5c7 100755 --- a/run_mpas_analysis +++ b/run_mpas_analysis @@ -70,6 +70,9 @@ def build_analysis_list(config): # {{{ componentName='ocean') oceanTimeSeriesTask = MpasTimeSeriesTask(config=config, componentName='ocean') + oceanIndexTask = MpasTimeSeriesTask(config=config, + componentName='ocean', + section='index') analyses.append(oceanClimatolgyTask) analyses.append(ocean.ClimatologyMapMLD(config, oceanClimatolgyTask)) analyses.append(ocean.ClimatologyMapSST(config, oceanClimatolgyTask)) @@ -81,7 +84,7 @@ def build_analysis_list(config): # {{{ analyses.append(ocean.TimeSeriesSST(config, oceanTimeSeriesTask)) analyses.append(ocean.MeridionalHeatTransport(config, oceanClimatolgyTask)) analyses.append(ocean.StreamfunctionMOC(config, oceanClimatolgyTask)) - analyses.append(ocean.IndexNino34(config, oceanTimeSeriesTask)) + analyses.append(ocean.IndexNino34(config, oceanIndexTask)) # Sea Ice Analyses seaIceClimatolgyTask = MpasClimatologyTask(config=config,