Source code for gemseo.post.opt_post_processor

# -*- coding: utf-8 -*-
# Copyright 2021 IRT Saint Exupéry, https://www.irt-saintexupery.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License version 3 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

# Contributors:
#    INITIAL AUTHORS - API and implementation and/or documentation
#        :author: Francois Gallard
#    OTHER AUTHORS   - MACROSCOPIC CHANGES
"""
Base class for all optimization post processings
************************************************
"""
from __future__ import absolute_import, division, unicode_literals

import inspect
from os.path import abspath, dirname, exists, join, splitext

import matplotlib
import pylab
from future import standard_library

from gemseo.core.grammar import InvalidDataException
from gemseo.core.json_grammar import JSONGrammar
from gemseo.utils.source_parsing import SourceParsing

standard_library.install_aliases()


[docs]class OptPostProcessor(object): """Abstract class for optimization post processing methods""" def __init__(self, opt_problem): """ Constructor :param opt_problem: the optimization problem to run """ self.opt_problem = opt_problem self.database = opt_problem.database cls_name = self.__class__.__name__ name = cls_name + "_options" f_class = inspect.getfile(self.__class__) comp_dir = abspath(dirname(f_class)) schema_file = join(comp_dir, name + ".json") if not exists(schema_file): schema_file = join(comp_dir, "options", name + ".json") if not exists(schema_file): raise ValueError( "Options grammar for optimization " + " post processor does not exists" + ", expected: " + str(schema_file) + "or: " + str(join(comp_dir, name + ".json")) ) self.opt_grammar = JSONGrammar(name, schema_file=schema_file) if hasattr(self.__class__, "_plot"): descr_opts = SourceParsing.get_options_doc( self.__class__._plot ) # pylint: disable=E1101 self.opt_grammar.add_description(descr_opts) if hasattr(self.__class__, "_run"): descr_opts = SourceParsing.get_options_doc(self.__class__._run) self.opt_grammar.add_description(descr_opts) # the data dict to eventually rebuild the plot in another framework self.out_data_dict = {} # Store output files generated by the post processing self.output_files = []
[docs] def execute(self, **options): """ Executes the post processing :param options: options dict, see associated JSON file """ self.check_options(**options) if not self.opt_problem.database: raise ValueError( "Optimization problem was not solved," + " cannot run post processing " + str(self.__class__.__name__) ) self._run(**options)
[docs] def check_options(self, **options): """ Checks the options of the post processor :param options: options dict, see associated JSON file """ try: self.opt_grammar.load_data(options) except InvalidDataException: name = self.__class__.__name__ raise InvalidDataException( "Invalid options for post processing " + name + " got : " + str(options) )
def _run(self, **options): """Visualizes the optimization history :param options: options of the plot, see associated JSON file """ self._plot(**options) def _plot(self, **options): """Visualizers :param options: options dict, see associated JSON file """ raise NotImplementedError() def _save_and_show(self, fig, file_path, save=True, show=False, extension="pdf"): """ Saves figures and or shows it depending on options :param fig: matplotlib figure :param file_path: file path to save the plot. If it does not end with the specified extension, the extension is replaced :param save: save the figure (default: True) :param show: show the figure (default: False) :param extension: file extension (default: 'pdf') """ matplotlib.rcParams.update({"font.size": 10}) if save: if not file_path.endswith(extension): basen = splitext(file_path)[0] file_path = basen + "." + extension fig.savefig(file_path, bbox_inches="tight") self.output_files.append(file_path) if show: try: pylab.plt.show(fig) except TypeError: pylab.plt.show()