# Path: openlego/utils/general_utils.py
# def str_to_valid_sys_name(string):
#     # type: (str) -> str
#     """Ensures a given string is a valid OpenMDAO system name."""
#     sys_name = re_sys_name_char.sub('', string)
#     while not re_sys_name_starts.match(sys_name):
#         sys_name = sys_name[1:]
#     return sys_name
# 
# def unscale_value(v, ref0, ref):
#     # TODO: add docstring
#     if isinstance(v, list):
#         v = np.array(v)
#     return v*(ref-ref0)+ref0
# 
# def scale_value(v, adder, scaler):
#     # TODO: add docstring
#     if adder is None:
#         adder = 0.
#     if scaler is None:
#         scaler = 1.
#     if isinstance(v, list):
#         v = np.array(v)
#     return (v + adder) * scaler
# 
# Path: openlego/utils/xml_utils.py
# def param_to_xpath(param):
#     # type: (str) -> str
#     """Convert an ``OpenMDAO`` parameter name to the corresponding XML XPath.
# 
#     This function is the inverse of `xpath_to_param()`.
# 
#     Parameters
#     ----------
#         param : str
#             Valid ``OpenMDAO`` parameter name.
# 
#     Returns
#     -------
#         str
#             Corresponding XML XPath.
#     """
#     xpath = param.replace(repl_emm, repl_emm_inv)
#     xpath = xpath.replace(repl_qtm, repl_qtm_inv)
#     xpath = xpath.replace(repl_str, repl_str_inv)
#     xpath = xpath.replace(repl_dot, repl_dot_inv)
#     xpath = re_ind_inv.sub(repl_ind_inv, xpath)
#     xpath = re_atr_inv.sub(repl_atr_inv, xpath)
#     return xpath


import copy
import os
import pickle
import numpy as np
import plotly
import plotly.graph_objs as go
from math import isnan as isnan
from typing import List
from openmdao.api import NonlinearBlockGS
from openmdao.core.analysis_error import AnalysisError
from openmdao.recorders.recording_iteration_stack import Recording
from openmdao.utils.general_utils import format_as_float_or_array
from openlego.utils.general_utils import str_to_valid_sys_name, unscale_value, scale_value
from openlego.utils.xml_utils import param_to_xpath
    @property
    def system_optimizer_name(self):
        # type: () -> str
        """Get the name of the system-level optimizer."""
        sys = self._system
        for sd in sys.super_drivers:
            if sys.loop_element_details[sd] == 'optimizer':
                return sd

    @property
    def system_optimizer_prob(self):
        # type: () -> LEGOProblem
        """Get the system-level optimizer object."""
        return getattr(self._system, str_to_valid_sys_name(self.system_optimizer_name)).prob

    @property
    def system_doe_names(self):
        # type: () -> set
        """Get the system-level DOEs."""
        _system_does = set()
        sys = self._system
        for sd in sys.super_drivers:
            if sys.loop_element_details[sd] == 'doe':
                _system_does.add(sd)
        return _system_does

    @property
    def system_doe_probs(self):
        # type: () -> List[LEGOProblem]
        """Get the system-level DOE LEGOProblem objects"""

# Path: openlego/utils/general_utils.py
# def str_to_valid_sys_name(string):
#     # type: (str) -> str
#     """Ensures a given string is a valid OpenMDAO system name."""
#     sys_name = re_sys_name_char.sub('', string)
#     while not re_sys_name_starts.match(sys_name):
#         sys_name = sys_name[1:]
#     return sys_name
# 
# def unscale_value(v, ref0, ref):
#     # TODO: add docstring
#     if isinstance(v, list):
#         v = np.array(v)
#     return v*(ref-ref0)+ref0
# 
# def scale_value(v, adder, scaler):
#     # TODO: add docstring
#     if adder is None:
#         adder = 0.
#     if scaler is None:
#         scaler = 1.
#     if isinstance(v, list):
#         v = np.array(v)
#     return (v + adder) * scaler
# 
# Path: openlego/utils/xml_utils.py
# def param_to_xpath(param):
#     # type: (str) -> str
#     """Convert an ``OpenMDAO`` parameter name to the corresponding XML XPath.
# 
#     This function is the inverse of `xpath_to_param()`.
# 
#     Parameters
#     ----------
#         param : str
#             Valid ``OpenMDAO`` parameter name.
# 
#     Returns
#     -------
#         str
#             Corresponding XML XPath.
#     """
#     xpath = param.replace(repl_emm, repl_emm_inv)
#     xpath = xpath.replace(repl_qtm, repl_qtm_inv)
#     xpath = xpath.replace(repl_str, repl_str_inv)
#     xpath = xpath.replace(repl_dot, repl_dot_inv)
#     xpath = re_ind_inv.sub(repl_ind_inv, xpath)
#     xpath = re_atr_inv.sub(repl_atr_inv, xpath)
#     return xpath


# Path: openlego/core/b2k_solver.py
import copy
import os
import pickle
import numpy as np
import plotly
import plotly.graph_objs as go
from math import isnan as isnan
from typing import List
from openmdao.api import NonlinearBlockGS
from openmdao.core.analysis_error import AnalysisError
from openmdao.recorders.recording_iteration_stack import Recording
from openmdao.utils.general_utils import format_as_float_or_array
from openlego.utils.general_utils import str_to_valid_sys_name, unscale_value, scale_value
from openlego.utils.xml_utils import param_to_xpath

    @property
    def system_optimizer_name(self):
        # type: () -> str
        """Get the name of the system-level optimizer."""
        sys = self._system
        for sd in sys.super_drivers:
            if sys.loop_element_details[sd] == 'optimizer':
                return sd

    @property
    def system_optimizer_prob(self):
        # type: () -> LEGOProblem
        """Get the system-level optimizer object."""
        return getattr(self._system, str_to_valid_sys_name(self.system_optimizer_name)).prob

    @property
    def system_doe_names(self):
        # type: () -> set
        """Get the system-level DOEs."""
        _system_does = set()
        sys = self._system
        for sd in sys.super_drivers:
            if sys.loop_element_details[sd] == 'doe':
                _system_does.add(sd)
        return _system_does

    @property
    def system_doe_probs(self):
        # type: () -> List[LEGOProblem]
        """Get the system-level DOE LEGOProblem objects"""

        return [getattr(self._system, str_to_valid_sys_name(x)).prob for x in self.system_doe_names]