Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OSNAP Arctic Transects transport time series #910

Merged
merged 5 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/users_guide/tasks/timeSeriesTransport.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ The following configuration options are available for this task::
# available transects.
transectsToPlot = ['Drake Passage', 'Tasmania-Ant', 'Africa-Ant', 'Antilles Inflow',
'Mona Passage', 'Windward Passage', 'Florida-Cuba', 'Florida-Bahamas',
'Indonesian Throughflow', 'Agulhas', 'Mozambique Channel', 'Bering Strait',
'Lancaster Sound', 'Fram Strait', 'Nares Strait']
'Indonesian Throughflow', 'Agulhas', 'Mozambique Channel']

# Number of months over which to compute moving average
movingAverageMonths = 1
Expand Down Expand Up @@ -54,8 +53,9 @@ defined in the ``transportTransects`` transect group. These are::
"Japan blockage", "Lancaster Sound", "Mona Passage", "Mozambique Channel",
"Nares Strait", "Nares Strait Deepen", "Persian Gulf Deepen",
"Red Sea Deepen", "Sakhalin blockage", "Strait of Gibralter Deepen 1",
"Strait of Gibralter Deepen 2", "Tasmania-Ant", "White Sea",
"Windward Passage"]
"Hudson Bay-Labrador Sea", "OSNAP section East", "OSNAP section West",
"Strait of Gibralter Deepen 2", "Tasmania-Ant", "White Sea",
"Windward Passage"]

Many of these are likely not of interest in most simulations, so a subset of
the most relevant transects has been chosen in the default configuration.
Expand Down
27 changes: 24 additions & 3 deletions mpas_analysis/default.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -1763,15 +1763,15 @@ obs = ['SOSE', 'WOA18']

[timeSeriesTransport]
## options related to plotting time series of transport through transects
transportGroups = ['Transport Transects']

[timeSeriesTransportTransects]
# list of ocean transects from geometric_features to plot or ['all'] for all
# available transects.
transectsToPlot = ['Drake Passage', 'Tasmania-Ant', 'Africa-Ant',
'Antilles Inflow', 'Mona Passage', 'Windward Passage',
'Florida-Cuba', 'Florida-Bahamas', 'Indonesian Throughflow',
'Agulhas', 'Mozambique Channel', 'Bering Strait',
'Lancaster Sound', 'Fram Strait', 'Nares Strait',
'Denmark Strait', 'Iceland-Faroe-Scotland']
'Agulhas', 'Mozambique Channel']

# Number of months over which to compute moving average
movingAveragePoints = 1
Expand All @@ -1790,6 +1790,27 @@ movingAveragePoints = 1
# Analysis may run faster for large meshes when this value is set to 2 or 3
subprocessCount = 1

[timeSeriesArcticTransportTransects]

transectsToPlot = ['all']
# Number of months over which to compute moving average
movingAveragePoints = 1

# An optional first year for the tick marks on the x axis. Leave commented out
# to start at the beginning of the time series.

# firstYearXTicks = 1

# An optional number of years between tick marks on the x axis. Leave
# commented out to determine the distance between ticks automatically.

# yearStrideXTicks = 1

# The number of parallel tasks occupied by each timeSeriesTransport task.
# Analysis may run faster for large meshes when this value is set to 2 or 3
subprocessCount = 1



[regionalTSDiagrams]
## options related to plotting T/S diagrams of ocean regions
Expand Down
145 changes: 84 additions & 61 deletions mpas_analysis/ocean/time_series_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def __init__(self, config, controlConfig=None):
# Xylar Asay-Davis

# first, call the constructor from the base class (AnalysisTask)
super(TimeSeriesTransport, self).__init__(
super().__init__(
config=config,
taskName='timeSeriesTransport',
componentName='ocean',
Expand All @@ -69,41 +69,45 @@ def __init__(self, config, controlConfig=None):
startYear = config.getint('timeSeries', 'startYear')
endYear = config.getint('timeSeries', 'endYear')

years = [year for year in range(startYear, endYear + 1)]

transectsToPlot = config.getexpression('timeSeriesTransport',
'transectsToPlot')
if len(transectsToPlot) == 0:
return

masksSubtask = ComputeTransectMasksSubtask(
parentTask=self, transectGroup='Transport Transects')

transectsToPlot = masksSubtask.expand_transect_names(transectsToPlot)
transportTransectFileName = masksSubtask.geojsonFileName
transportGroups = config.getexpression('timeSeriesTransport', 'transportGroups')

self.add_subtask(masksSubtask)

# in the end, we'll combine all the time series into one, but we
# create this task first so it's easier to tell it to run after all
# the compute tasks
combineSubtask = CombineTransportSubtask(
self, startYears=years, endYears=years)

# run one subtask per year
for year in years:
computeSubtask = ComputeTransportSubtask(
self, startYear=year, endYear=year, masksSubtask=masksSubtask,
transectsToPlot=transectsToPlot)
self.add_subtask(computeSubtask)
computeSubtask.run_after(masksSubtask)
combineSubtask.run_after(computeSubtask)

for index, transect in enumerate(transectsToPlot):
plotTransportSubtask = PlotTransportSubtask(
self, transect, index, controlConfig, transportTransectFileName)
plotTransportSubtask.run_after(combineSubtask)
self.add_subtask(plotTransportSubtask)
years = [year for year in range(startYear, endYear + 1)]
for transportGroup in transportGroups:
groupSuffix = transportGroup.replace(' ', '')
transectsToPlot = config.getexpression(f'timeSeries{groupSuffix}',
'transectsToPlot')
if len(transectsToPlot) == 0:
return

masksSubtask = ComputeTransectMasksSubtask(
parentTask=self, transectGroup=transportGroup)

transectsToPlot = masksSubtask.expand_transect_names(transectsToPlot)
transportTransectFileName = masksSubtask.geojsonFileName

self.add_subtask(masksSubtask)

# in the end, we'll combine all the time series into one, but we
# create this task first so it's easier to tell it to run after all
# the compute tasks
combineSubtask = CombineTransportSubtask(
self, startYears=years, endYears=years, groupSuffix=groupSuffix)

# run one subtask per year
for year in years:
computeSubtask = ComputeTransportSubtask(
self, startYear=year, endYear=year, masksSubtask=masksSubtask,
transectsToPlot=transectsToPlot, groupSuffix=groupSuffix)
self.add_subtask(computeSubtask)
computeSubtask.run_after(masksSubtask)
combineSubtask.run_after(computeSubtask)

for index, transect in enumerate(transectsToPlot):
plotTransportSubtask = PlotTransportSubtask(
self, transect, index, controlConfig, transportTransectFileName,
transportGroup)
plotTransportSubtask.run_after(combineSubtask)
self.add_subtask(plotTransportSubtask)


class ComputeTransportSubtask(AnalysisTask):
Expand All @@ -120,14 +124,17 @@ class ComputeTransportSubtask(AnalysisTask):

transectsToPlot : list of str
A list of transects to plot

groupSuffix : str
standard transects vs Arctic transects
"""

# Authors
# -------
# Xylar Asay-Davis, Stephen Price

def __init__(self, parentTask, startYear, endYear,
masksSubtask, transectsToPlot):
masksSubtask, transectsToPlot, groupSuffix):
"""
Construct the analysis task.

Expand All @@ -145,21 +152,23 @@ def __init__(self, parentTask, startYear, endYear,

transectsToPlot : list of str
A list of transects to plot

groupSuffix : str
standard transects vs Arctic transects
"""
# Authors
# -------
# Xylar Asay-Davis

subtaskName = f'compute{groupSuffix}_{startYear:04d}-{endYear:04d}'
# first, call the constructor from the base class (AnalysisTask)
super(ComputeTransportSubtask, self).__init__(
super().__init__(
config=parentTask.config,
taskName=parentTask.taskName,
componentName=parentTask.componentName,
tags=parentTask.tags,
subtaskName='computeTransport_{:04d}-{:04d}'.format(startYear,
endYear))

self.subprocessCount = self.config.getint('timeSeriesTransport',
subtaskName=subtaskName)

self.subprocessCount = self.config.getint(f'timeSeries{groupSuffix}',
'subprocessCount')
self.startYear = startYear
self.endYear = endYear
Expand All @@ -169,6 +178,7 @@ def __init__(self, parentTask, startYear, endYear,

self.transectsToPlot = transectsToPlot
self.restartFileName = None
self.groupSuffix = groupSuffix

def setup_and_check(self):
"""
Expand Down Expand Up @@ -227,8 +237,7 @@ def run_task(self):
except OSError:
pass

outFileName = '{}/transport_{:04d}-{:04d}.nc'.format(
outputDirectory, self.startYear, self.endYear)
outFileName = f'{outputDirectory}/{self.groupSuffix}_{self.startYear:04d}-{self.endYear:04d}.nc'

inputFiles = sorted(self.historyStreams.readpath(
'timeSeriesStatsMonthlyOutput', startDate=startDate,
Expand Down Expand Up @@ -389,7 +398,7 @@ class CombineTransportSubtask(AnalysisTask):
# -------
# Xylar Asay-Davis

def __init__(self, parentTask, startYears, endYears):
def __init__(self, parentTask, startYears, endYears, groupSuffix):
"""
Construct the analysis task.

Expand All @@ -401,21 +410,25 @@ def __init__(self, parentTask, startYears, endYears):
startYears, endYears : list of int
The beginning and end of each time series to combine

groupSuffix : str
standard transects vs Arctic transects

"""
# Authors
# -------
# Xylar Asay-Davis

# first, call the constructor from the base class (AnalysisTask)
super(CombineTransportSubtask, self).__init__(
config=parentTask.config,
taskName=parentTask.taskName,
componentName=parentTask.componentName,
tags=parentTask.tags,
subtaskName='combineTimeSeries')

subtaskName=f'combine{groupSuffix}TimeSeries')
#print(self.taskName, self.subtaskName)
self.startYears = startYears
self.endYears = endYears
self.groupSuffix = groupSuffix

def run_task(self):
"""
Expand All @@ -424,19 +437,17 @@ def run_task(self):
# Authors
# -------
# Xylar Asay-Davis

groupSuffix = self.groupSuffix
outputDirectory = '{}/transport/'.format(
build_config_full_path(self.config, 'output',
'timeseriesSubdirectory'))
outFileName = f'{outputDirectory}/{groupSuffix}_{self.startYears[0]:04d}-{self.endYears[-1]:04d}.nc'

outFileName = '{}/transport_{:04d}-{:04d}.nc'.format(
outputDirectory, self.startYears[0], self.endYears[-1])

if not os.path.exists(outFileName):
inFileNames = []
for startYear, endYear in zip(self.startYears, self.endYears):
inFileName = '{}/transport_{:04d}-{:04d}.nc'.format(
outputDirectory, startYear, endYear)
inFileName = f'{outputDirectory}/{groupSuffix}_{startYear:04d}-{endYear:04d}.nc'
inFileNames.append(inFileName)

ds = xarray.open_mfdataset(inFileNames, combine='nested',
Expand All @@ -460,14 +471,18 @@ class PlotTransportSubtask(AnalysisTask):
controlConfig : mpas_tools.config.MpasConfigParser
The configuration options for the control run (if any)

transportGroup : str (with spaces)
standard transects (``Transport Transects``)
vs Arctic transects (``Arctic Transport Transects``)

"""

# Authors
# -------
# Xylar Asay-Davis, Stephen Price

def __init__(self, parentTask, transect, transectIndex, controlConfig,
transportTransectFileName):
transportTransectFileName, transportGroup):

"""
Construct the analysis task.
Expand All @@ -486,23 +501,29 @@ def __init__(self, parentTask, transect, transectIndex, controlConfig,

controlconfig : mpas_tools.config.MpasConfigParser, optional
Configuration options for a control run (if any)

transportGroup : str (with spaces)
standard transects (``Transport Transects``)
vs Arctic transects (``Arctic Transport Transects``)
"""
# Authors
# -------
# Xylar Asay-Davis

# first, call the constructor from the base class (AnalysisTask)
transectKey = transect.replace(' ', '_')
super(PlotTransportSubtask, self).__init__(
config=parentTask.config,
taskName=parentTask.taskName,
componentName=parentTask.componentName,
tags=parentTask.tags,
subtaskName='plotTransport_{}'.format(transect.replace(' ', '_')))
subtaskName=f'plotTransport_{transectKey}')

self.transportTransectFileName = transportTransectFileName
self.transect = transect
self.transectIndex = transectIndex
self.controlConfig = controlConfig
self.transportGroup = transportGroup

def setup_and_check(self):
"""
Expand Down Expand Up @@ -556,6 +577,8 @@ def run_task(self):
'Davis Strait': [-1.6, -3.6],
'Barents Sea Opening': [1.4, 2.6],
'Nares Strait': [-1.8, 0.2],
'OSNAP section East': [15.6 - 0.8, 15.6 + 0.8],
'OSNAP section West': [2.1 - 0.3, 2.1 + 0.3],
'Denmark Strait': None,
'Iceland-Faroe-Scotland': None}

Expand All @@ -580,7 +603,8 @@ def run_task(self):
plotControl = self.controlConfig is not None

mainRunName = config.get('runs', 'mainRunName')
movingAveragePoints = config.getint('timeSeriesTransport',
groupSuffix = self.transportGroup.replace(' ','')
movingAveragePoints = config.getint(f'timeSeries{groupSuffix}',
'movingAveragePoints')

self.logger.info(' Plotting...')
Expand Down Expand Up @@ -661,7 +685,8 @@ def run_task(self):
groupLink='transporttime',
thumbnailDescription=thumbnailDescription,
imageDescription=caption,
imageCaption=caption)
imageCaption=caption,
gallery=self.transportGroup)

def _load_transport(self, config):
"""
Expand All @@ -670,15 +695,13 @@ def _load_transport(self, config):
# Authors
# -------
# Xylar Asay-Davis

groupSuffix = self.transportGroup.replace(' ', '')
baseDirectory = build_config_full_path(
config, 'output', 'timeSeriesSubdirectory')

startYear = config.getint('timeSeries', 'startYear')
endYear = config.getint('timeSeries', 'endYear')

inFileName = '{}/transport/transport_{:04d}-{:04d}.nc'.format(
baseDirectory, startYear, endYear)
inFileName = f'{baseDirectory}/transport/{groupSuffix}_{startYear:04d}-{endYear:04d}.nc'

dsIn = xarray.open_dataset(inFileName)
transport = dsIn.transport.isel(nTransects=self.transectIndex)
Expand Down
3 changes: 3 additions & 0 deletions mpas_analysis/polar_regions.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,9 @@ makeTables = True
# ['all'] for all 106 ice shelves and regions.
iceShelvesInTable = ['all']

[timeSeriesTransport]
## options related to plotting time series of transport through transects
transportGroups = ['Transport Transects', 'Arctic Transport Transects']

[timeSeriesConservation]
## options related to producing time series plots from the conservation
Expand Down