Source code for mpas_analysis.ocean.time_series_sst

# This software is open source software available under the BSD-3 license.
#
# Copyright (c) 2022 Triad National Security, LLC. All rights reserved.
# Copyright (c) 2022 Lawrence Livermore National Security, LLC. All rights
# reserved.
# Copyright (c) 2022 UT-Battelle, LLC. All rights reserved.
#
# Additional copyright and license information can be found in the LICENSE file
# distributed with this code, or at
# https://raw.githubusercontent.com/MPAS-Dev/MPAS-Analysis/main/LICENSE

from mpas_analysis.shared import AnalysisTask

from mpas_analysis.shared.plot import timeseries_analysis_plot, savefig

from mpas_analysis.shared.time_series import combine_time_series_with_ncrcat
from mpas_analysis.shared.io import open_mpas_dataset

from mpas_analysis.shared.timekeeping.utility import date_to_days, \
    days_to_datetime

from mpas_analysis.shared.io.utility import build_config_full_path, \
    make_directories, check_path_exists
from mpas_analysis.shared.html import write_image_xml


[docs] class TimeSeriesSST(AnalysisTask): """ Performs analysis of the time-series output of sea-surface temperature (SST). Attributes ---------- mpasTimeSeriesTask : ``MpasTimeSeriesTask`` The task that extracts the time series from MPAS monthly output controlconfig : mpas_tools.config.MpasConfigParser Configuration options for a control run (if any) """ # Authors # ------- # Xylar Asay-Davis, Milena Veneziani
[docs] def __init__(self, config, mpasTimeSeriesTask, controlConfig=None): """ Construct the analysis task. Parameters ---------- config : mpas_tools.config.MpasConfigParser Configuration options mpasTimeSeriesTask : ``MpasTimeSeriesTask`` The task that extracts the time series from MPAS monthly output controlconfig : mpas_tools.config.MpasConfigParser, optional Configuration options for a control run (if any) """ # Authors # ------- # Xylar Asay-Davis # first, call the constructor from the base class (AnalysisTask) super(TimeSeriesSST, self).__init__( config=config, taskName='timeSeriesSST', componentName='ocean', tags=['timeSeries', 'sst', 'publicObs']) self.mpasTimeSeriesTask = mpasTimeSeriesTask self.controlConfig = controlConfig self.run_after(mpasTimeSeriesTask)
def setup_and_check(self): """ Perform steps to set up the analysis and check for errors in the setup. Raises ------ OSError If files are not present """ # Authors # ------- # Xylar Asay-Davis # first, call setup_and_check from the base class (AnalysisTask), # which will perform some common setup, including storing: # self.inDirectory, self.plotsDirectory, self.namelist, self.streams # self.calendar super(TimeSeriesSST, self).setup_and_check() config = self.config self.startDate = self.config.get('timeSeries', 'startDate') self.endDate = self.config.get('timeSeries', 'endDate') self.variableList = \ ['timeMonthly_avg_avgValueWithinOceanRegion_avgSurfaceTemperature'] self.mpasTimeSeriesTask.add_variables(variableList=self.variableList) if config.get('runs', 'preprocessedReferenceRunName') != 'None': check_path_exists(config.get('oceanPreprocessedReference', 'baseDirectory')) self.inputFile = self.mpasTimeSeriesTask.outputFile mainRunName = config.get('runs', 'mainRunName') regions = config.getexpression('timeSeriesSST', 'regions') self.xmlFileNames = [] self.filePrefixes = {} for region in regions: filePrefix = 'sst_{}_{}'.format(region, mainRunName) self.xmlFileNames.append('{}/{}.xml'.format(self.plotsDirectory, filePrefix)) self.filePrefixes[region] = filePrefix return def run_task(self): """ Performs analysis of the time-series output of sea-surface temperature (SST). """ # Authors # ------- # Xylar Asay-Davis, Milena Veneziani self.logger.info("\nPlotting SST time series...") self.logger.info(' Load SST data...') config = self.config calendar = self.calendar mainRunName = config.get('runs', 'mainRunName') preprocessedReferenceRunName = \ config.get('runs', 'preprocessedReferenceRunName') preprocessedInputDirectory = config.get('oceanPreprocessedReference', 'baseDirectory') movingAveragePoints = config.getint('timeSeriesSST', 'movingAveragePoints') regions = config.getexpression('regions', 'regions') plotTitles = config.getexpression('regions', 'plotTitles') regionsToPlot = config.getexpression('timeSeriesSST', 'regions') regionIndicesToPlot = [regions.index(region) for region in regionsToPlot] outputDirectory = build_config_full_path(config, 'output', 'timeseriesSubdirectory') make_directories(outputDirectory) dsSST = open_mpas_dataset(fileName=self.inputFile, calendar=calendar, variableList=self.variableList, startDate=self.startDate, endDate=self.endDate) yearStart = days_to_datetime(dsSST.Time.min(), calendar=calendar).year yearEnd = days_to_datetime(dsSST.Time.max(), calendar=calendar).year timeStart = date_to_days(year=yearStart, month=1, day=1, calendar=calendar) timeEnd = date_to_days(year=yearEnd, month=12, day=31, calendar=calendar) if self.controlConfig is not None: baseDirectory = build_config_full_path( self.controlConfig, 'output', 'timeSeriesSubdirectory') controlFileName = '{}/{}.nc'.format( baseDirectory, self.mpasTimeSeriesTask.fullTaskName) controlStartYear = self.controlConfig.getint( 'timeSeries', 'startYear') controlEndYear = self.controlConfig.getint('timeSeries', 'endYear') controlStartDate = '{:04d}-01-01_00:00:00'.format(controlStartYear) controlEndDate = '{:04d}-12-31_23:59:59'.format(controlEndYear) dsRefSST = open_mpas_dataset( fileName=controlFileName, calendar=calendar, variableList=self.variableList, startDate=controlStartDate, endDate=controlEndDate) else: dsRefSST = None if preprocessedReferenceRunName != 'None': self.logger.info(' Load in SST for a preprocesses reference ' 'run...') inFilesPreprocessed = '{}/SST.{}.year*.nc'.format( preprocessedInputDirectory, preprocessedReferenceRunName) outFolder = '{}/preprocessed'.format(outputDirectory) make_directories(outFolder) outFileName = '{}/sst.nc'.format(outFolder) combine_time_series_with_ncrcat(inFilesPreprocessed, outFileName, logger=self.logger) dsPreprocessed = open_mpas_dataset(fileName=outFileName, calendar=calendar, timeVariableNames='xtime') yearEndPreprocessed = days_to_datetime(dsPreprocessed.Time.max(), calendar=calendar).year if yearStart <= yearEndPreprocessed: dsPreprocessedTimeSlice = \ dsPreprocessed.sel(Time=slice(timeStart, timeEnd)) else: self.logger.warning('Preprocessed time series ends before the ' 'timeSeries startYear and will not be ' 'plotted.') preprocessedReferenceRunName = 'None' self.logger.info(' Make plots...') for regionIndex in regionIndicesToPlot: region = regions[regionIndex] title = '{} SST'.format(plotTitles[regionIndex]) xLabel = 'Time [years]' yLabel = r'[$\degree$C]' varName = self.variableList[0] SST = dsSST[varName].isel(nOceanRegions=regionIndex) filePrefix = self.filePrefixes[region] outFileName = '{}/{}.png'.format(self.plotsDirectory, filePrefix) lineColors = [config.get('timeSeries', 'mainColor')] lineWidths = [3] fields = [SST] legendText = [mainRunName] if dsRefSST is not None: refSST = dsRefSST[varName].isel(nOceanRegions=regionIndex) fields.append(refSST) lineColors.append(config.get('timeSeries', 'controlColor')) lineWidths.append(1.5) controlRunName = self.controlConfig.get('runs', 'mainRunName') legendText.append(controlRunName) if preprocessedReferenceRunName != 'None': SST_v0 = dsPreprocessedTimeSlice.SST fields.append(SST_v0) lineColors.append('purple') lineWidths.append(1.5) legendText.append(preprocessedReferenceRunName) if config.has_option(self.taskName, 'firstYearXTicks'): firstYearXTicks = config.getint(self.taskName, 'firstYearXTicks') else: firstYearXTicks = None if config.has_option(self.taskName, 'yearStrideXTicks'): yearStrideXTicks = config.getint(self.taskName, 'yearStrideXTicks') else: yearStrideXTicks = None timeseries_analysis_plot(config, fields, calendar=calendar, title=title, xlabel=xLabel, ylabel=yLabel, movingAveragePoints=movingAveragePoints, lineColors=lineColors, lineWidths=lineWidths, legendText=legendText, firstYearXTicks=firstYearXTicks, yearStrideXTicks=yearStrideXTicks) savefig(outFileName, config) caption = 'Running Mean of {} Sea Surface Temperature'.format( region) write_image_xml( config=config, filePrefix=filePrefix, componentName='Ocean', componentSubdirectory='ocean', galleryGroup='Time Series', groupLink='timeseries', thumbnailDescription='{} SST'.format(region), imageDescription=caption, imageCaption=caption)
# }}}