# 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.climatology import RemapMpasClimatologySubtask
from mpas_analysis.shared.plot import PlotClimatologyMapSubtask
[docs]
class ClimatologyMapMLDMinMax(AnalysisTask):
    """
    An analysis task for comparison of mixed layer depth (mld) against
    observations
    """
    # Authors
    # -------
    # Luke Van Roekel, Xylar Asay-Davis, Milena Veneziani
[docs]
    def __init__(self, config, mpasClimatologyTasks, controlConfig=None):
        """
        Construct the analysis task.
        Parameters
        ----------
        config : tranche.Tranche
            Configuration options
        mpasClimatologyTasks : dict of ``MpasClimatologyTask``
            The tasks that produced the climatology of monthly min and max to
            be remapped and plotted
        controlconfig : tranche.Tranche, optional
            Configuration options for a control run (if any)
        """
        # Authors
        # -------
        # Xylar Asay-Davis
        fieldName = 'mld'
        # call the constructor from the base class (AnalysisTask)
        super(ClimatologyMapMLDMinMax, self).__init__(
            config=config, taskName='climatologyMapMLDMinMax',
            componentName='ocean',
            tags=['climatology', 'horizontalMap', fieldName, 'publicObs',
                  'min', 'max'])
        self._add_tasks(config, mpasClimatologyTasks, controlConfig,
                        title='Density MLD',
                        mpasVariableSuffix='dThreshMLD',
                        filePrefix='d_mld',
                        sectionPrefix='climatologyMapDensityMLD')
        self._add_tasks(config, mpasClimatologyTasks, controlConfig,
                        title='Temperature MLD',
                        mpasVariableSuffix='tThreshMLD',
                        filePrefix='t_mld',
                        sectionPrefix='climatologyMapTemperatureMLD')
        self._add_tasks(config, mpasClimatologyTasks, controlConfig,
                        title='Boundary-Layer Depth',
                        mpasVariableSuffix='boundaryLayerDepth',
                        filePrefix='bld',
                        sectionPrefix='climatologyMapBLD') 
    def setup_and_check(self):
        """
        Check if MLD capability was turned on in the run.
        """
        # Authors
        # -------
        # Xylar Asay-Davis
        # first, call setup_and_check from the base class (AnalysisTask),
        # which will perform some common setup, including storing:
        #     self.runDirectory , self.historyDirectory, self.plotsDirectory,
        #     self.namelist, self.runStreams, self.historyStreams,
        #     self.calendar
        super(ClimatologyMapMLDMinMax, self).setup_and_check()
        self.check_analysis_enabled(
            analysisOptionName='config_am_mixedlayerdepths_enable',
            raiseException=True)
        self.check_analysis_enabled(
            analysisOptionName='config_AM_timeSeriesStatsMonthlyMin_enable',
            raiseException=True)
        self.check_analysis_enabled(
            analysisOptionName='config_AM_timeSeriesStatsMonthlyMax_enable',
            raiseException=True)
    def _add_tasks(self, config, mpasClimatologyTasks, controlConfig,
                   title, mpasVariableSuffix, filePrefix, sectionPrefix):
        """
        Add tasks for a given variable
        """
        iselValues = None
        # read in what seasons we want to plot
        seasons = config.getexpression(self.taskName, 'seasons')
        if len(seasons) == 0:
            raise ValueError('config section {} does not contain valid list '
                             'of seasons'.format(self.taskName))
        comparisonGridNames = config.getexpression(self.taskName,
                                                   'comparisonGrids')
        if len(comparisonGridNames) == 0:
            raise ValueError('config section {} does not contain valid list '
                             'of comparison grids'.format(self.taskName))
        remapClimatologySubtasks = {}
        mpasFieldNames = {}
        for op in ['min', 'max']:
            upperOp = op[0].upper() + op[1:]
            mpasFieldNames[op] = 'timeMonthly{}_{}_{}'.format(
                upperOp, op, mpasVariableSuffix)
            # the variable 'timeMonthly_avg_dThreshMLD' will be added to
            # mpasClimatologyTask along with the seasons.
            remapClimatologySubtasks[op] = RemapMpasClimatologySubtask(
                mpasClimatologyTask=mpasClimatologyTasks[op],
                parentTask=self,
                climatologyName=filePrefix,
                variableList=[mpasFieldNames[op]],
                comparisonGridNames=comparisonGridNames,
                seasons=seasons,
                iselValues=iselValues,
                subtaskName='remap{}_{}'.format(upperOp, filePrefix))
        if controlConfig is None:
            fieldNameInTitle = 'Max {}'.format(title)
            refTitleLabel = 'Min {}'.format(title)
            diffTitleLabel = 'Max - Min {}'.format(title)
            galleryName = title
            outFileLabel = '{}_min_max'.format(filePrefix)
            sectionName = '{}MinMax'.format(sectionPrefix)
            for comparisonGridName in comparisonGridNames:
                for season in seasons:
                    subtaskName = 'plot_{}_{}_{}'.format(filePrefix,
                                                         season,
                                                         comparisonGridName)
                    # make a new subtask for this season and comparison grid
                    firstTask = remapClimatologySubtasks['max']
                    secondTask = remapClimatologySubtasks['min']
                    subtask = PlotClimatologyMapSubtask(
                        self, season, comparisonGridName,
                        remapMpasClimatologySubtask=firstTask,
                        secondRemapMpasClimatologySubtask=secondTask,
                        controlConfig=controlConfig,
                        subtaskName=subtaskName)
                    subtask.set_plot_info(
                        outFileLabel=outFileLabel,
                        fieldNameInTitle=fieldNameInTitle,
                        mpasFieldName=mpasFieldNames['max'],
                        refFieldName=mpasFieldNames['min'],
                        refTitleLabel=refTitleLabel,
                        diffTitleLabel=diffTitleLabel,
                        unitsLabel=r'm',
                        imageCaption='Min/Max Mixed-Layer Depth',
                        galleryGroup='Min/Max Mixed-Layer Depth',
                        groupSubtitle=None,
                        groupLink='mld_min_max',
                        galleryName=galleryName,
                        configSectionName=sectionName)
                    self.add_subtask(subtask)
        else:
            controlRunName = controlConfig.get('runs', 'mainRunName')
            galleryName = title
            refTitleLabel = 'Control: {}'.format(controlRunName)
            diffTitleLabel = 'Main - Control'
            for comparisonGridName in comparisonGridNames:
                for season in seasons:
                    for op in ['min', 'max']:
                        upperOp = op[0].upper() + op[1:]
                        subtaskName = 'plot{}_{}_{}_{}'.format(
                            upperOp, filePrefix, season, comparisonGridName)
                        fieldNameInTitle = '{} {}'.format(upperOp, title)
                        outFileLabel = '{}_{}'.format(filePrefix, op)
                        sectionName = '{}{}'.format(sectionPrefix, upperOp)
                        # make a new subtask for this season and comparison
                        # grid
                        subtask = PlotClimatologyMapSubtask(
                            self, season, comparisonGridName,
                            remapClimatologySubtasks[op],
                            controlConfig=controlConfig,
                            subtaskName=subtaskName)
                        subtask.set_plot_info(
                            outFileLabel=outFileLabel,
                            fieldNameInTitle=fieldNameInTitle,
                            mpasFieldName=mpasFieldNames[op],
                            refFieldName=mpasFieldNames[op],
                            refTitleLabel=refTitleLabel,
                            diffTitleLabel=diffTitleLabel,
                            unitsLabel=r'm',
                            imageCaption=fieldNameInTitle,
                            galleryGroup='Min/Max Mixed-Layer Depth',
                            groupSubtitle=None,
                            groupLink='mld_{}'.format(op),
                            galleryName=galleryName,
                            configSectionName=sectionName)
                        self.add_subtask(subtask)