Source code for qmt.utils.transplant

# SPDX-FileCopyrightText: 2021 Daniel Laidig <laidig@control.tu-berlin.de>
#
# SPDX-License-Identifier: MIT

import os

from qmt.utils.struct import Struct

try:
    import transplant
except ImportError:
    class transplant:
        class MatlabStruct:
            pass

        class Matlab:
            def __init__(self, **kwargs):
                raise RuntimeError('Transplant is not installed.')


def _getMatlabPath():
    return os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'matlab'))


class Matlab(transplant.Matlab):
    """
    Transplant's Matlab class that encodes qmt.Struct instances as Matlab structs.
    """
    def _encode_values(self, data):
        # on exit, Struct can be None
        if Struct is not None and isinstance(data, Struct):
            return super()._encode_values(transplant.MatlabStruct(data))
        else:
            return super()._encode_values(data)


[docs]class MatlabWrapper: """ Provides access to the qmt Matlab functions. A Matlab instance is automatically started in background on the first access. If there is no ``matlab`` executable in your path, call :meth:`~qmt.utils.transplant.MatlabWrapper.init` manually. See :ref:`tutorial_py_matlab_interface` for more details. """ def __init__(self): self._transplant = None @property def running(self): return self._transplant is not None
[docs] def init(self, **kwargs): """ Starts Matlab and sets up the path for the qmt functions. If there is no ``matlab`` executable in your path, call this function manually and provide the full path to Matlab:: qmt.matlab.init(executable='/usr/local/MATLAB/R2017b/bin/matlab') :param kwargs: Parameters passed to transplant. :return: None """ assert self._transplant is None, 'Matlab is already started, call exit() first' self._transplant = Matlab(**kwargs) self._transplant.addpath(_getMatlabPath())
@property def instance(self): """ Gives access to the `Transplant <https://github.com/bastibe/transplant>`_ Matlab class that can be used to call other Matlab functions and execute arbitrary Matlab code. :: m = qmt.matlab.instance m.version() m.eval('1234*(0.1+0.1+0.1-0.3)^(1/10)') """ if self._transplant is None: print('Starting Matlab...') self.init() return self._transplant
[docs] def exit(self): """ Quits Matlab. """ t = self._transplant if t is None: return self._transplant = None t.exit()
def __getattr__(self, name): return getattr(self.instance.qmt, name)
matlab = MatlabWrapper()