Beispiel #1
0
    def test_convert(self):

        v = WorkspaceVariable.convert("Index", 1.2)
        assert (v == 1)

        v = WorkspaceVariable.convert("String", "string")
        assert (v == "string")

        v = WorkspaceVariable.convert("Numeric", 1)
        assert (type(v) == np.float64)

        v = WorkspaceVariable.convert("Vector", 1.0)
        assert (v.shape == (1, ))

        v = WorkspaceVariable.convert("Matrix", 1.0)
        assert (v.shape == (1, 1))

        v = WorkspaceVariable.convert("Tensor3", 1.0)
        assert (v.shape == (1, 1, 1))

        v = WorkspaceVariable.convert("Tensor6", 1.0)
        assert (v.shape == (1, 1, 1, 1, 1, 1))

        v = WorkspaceVariable.convert("ArrayOfArrayOfIndex", 1.0)
        assert (type(v) == list)
        assert (type(v[0]) == list)
        assert (type(v[0][0]) == int)

        v = WorkspaceVariable.convert("ArrayOfArrayOfIndex", 1)
        return v
Beispiel #2
0
    def add_method(*args, **kwargs):
        """
        Add a workspace method call to the agenda.

        Parameters:

            ws(typhon.arts.workspace.Workspace): A (dummy) workspace object.

            m(typhon.arts.workspace.WorkspaceMethod): The method to add to the
            agenda

            *args:  Positional arguments of the WSM call to add to the agenda.

            **kwargs: Key-word arguments of the WSM call to add to the agenda.
        """
        from typhon.arts.workspace.variables import group_names

        if len(args) < 3:
            raise Exception("Need at least self, a workspace and the method to"
                            " add as arguments.")
        self = args[0]
        ws   = args[1]
        m    = args[2]
        m_id, args_out, args_in, temps = m._parse_output_input_lists(ws,
                                                                     args[3:],
                                                                     kwargs)
        arg_out_ptr = c.cast((c.c_long * len(args_out))(*args_out),
                             c.POINTER(c.c_long))
        arg_in_ptr = c.cast((c.c_long * len(args_in))(*args_in),
                            c.POINTER(c.c_long))
        if not m.name[-3:] == "Set" or not m.name[:-3] in group_names:

            for t in temps:
                arts_api.agenda_insert_set(ws.ptr, self.ptr, t.ws_id, t.group_id)

            arts_api.agenda_add_method(c.c_void_p(self.ptr), m_id,
                                       len(args_out), arg_out_ptr,
                                       len(args_in), arg_in_ptr)
        else:
            from typhon.arts.workspace.variables import WorkspaceVariable

            name_out = WorkspaceVariable.get_variable_name(args_out[0])
            name_in = WorkspaceVariable.get_variable_name(args_in[0])
            wsv_out = getattr(ws, name_out)
            wsv_in  = getattr(ws, name_in)

            ws.Copy(wsv_out, wsv_in)

            group_id = arts_api.get_variable(args_out[0]).group
            arts_api.agenda_insert_set(ws.ptr, self.ptr, args_out[0], group_id)
Beispiel #3
0
    def add_variable(self, var):
        """
        This will try to copy a given python variable to the ARTS workspace and
        return a WorkspaceVariable object representing this newly created
        variable.

        Types are natively supported by the C API are int, str, [str], [int], and
        numpy.ndarrays. These will be copied directly into the newly created WSV.

        In addition to that all typhon ARTS types the can be stored to XML can
        be set to a WSV, but in this case the communication will happen through
        the file systs (cf. WorkspaceVariable.from_typhon).

        The user should not have to call this method explicitly, but instead it
        is used by the WorkspaceMethod call function to transfer python
        variable arguments to the ARTS workspace.

        Args:
            var: Python variable of type int, str, [str], [int] or np.ndarray
            which should be copied to the workspace.
        """
        if type(var) == WorkspaceVariable:
            return var

        # Create WSV in ARTS Workspace
        group_id = WorkspaceVariable.get_group_id(var)
        ws_id = arts_api.add_variable(self.ptr, group_id, None)
        wsv = WorkspaceVariable(ws_id, str(id(var)), group_names[group_id],
                                "User defined variable.", self)
        # Set WSV value using the ARTS C API
        s = VariableValueStruct(var)
        if s.ptr:
            e = arts_api.set_variable_value(self.ptr, ws_id, group_id, s)
            if e:
                arts_api.erase_variable(self.ptr, ws_id, group_id)
                raise Exception("Setting of workspace variable through C API "
                                " failed with  the " + "following error:\n" +
                                e.decode("utf8"))
        # If the type is not supported by the C API try to write the type to XML
        # and read into ARTS workspace.
        else:
            try:
                wsv.from_typhon(var)
            except:
                raise Exception("Could not add variable since + " +
                                str(type(var)) + " is neither supported by " +
                                "the C API nor typhon XML IO.")
        return wsv
Beispiel #4
0
    def __getattr__(self, name):
        """ Lookup the given variable in the local variables and the ARTS workspace.

        Args:
            name(str): Name of the attribute (variable)

        Raises:
            ValueError: If the variable is not found.
        """

        group_id = None
        if name in self._vars:
            var = self._vars[name]
            var.update()
            return var
        else:
            i = arts_api.lookup_workspace_variable(name.encode())
            if i < 0:
                raise AttributeError("No workspace variable " + str(name) + " found.")
            vs = arts_api.get_variable(i)
            group_id    = vs.group
            description = vs.description.decode("utf8")

        # Get its symbolic representation
        wsv = WorkspaceVariable(i, name, group_names[group_id], description, self)
        return wsv
Beispiel #5
0
    def create_variable(self, group, name):
        """
        Create a workspace variable.

        Args:

            group: The group name of the variable to create.

            name: The name of the variable to create. If None, the
            ARTS API will assign a unique name.

        """
        if not name is None:
            name = name.encode()

        group_id = group_ids[group]
        ws_id    = arts_api.add_variable(self.ptr, group_id, name)
        v        = arts_api.get_variable(ws_id)
        wsv      = WorkspaceVariable(ws_id,
                                     v.name.decode(),
                                     group_names[group_id],
                                     "User defined variable.",
                                     self)
        self._vars[wsv.name] = wsv
        return wsv
Beispiel #6
0
    def get_default_input_dict(m_id, g_in):
        """Get dict mapping names of generic input arguments to default values.

        Is None if no default value for a given generic input is given.

        Args:
            m_id(int):   Index of the method.
            g_in([str]): Names of the generic input arguments.
        Return:
            dict: The mapping.
        """
        res = dict()
        for i, t in enumerate(g_in):
            k = arts_api.get_method_g_in(m_id, i).decode("utf8")
            d = arts_api.get_method_g_in_default(m_id, i).decode("utf8")
            if d == "":
                pass
            elif d[0] == "@":
                d = None
            elif d == "Inf":
                res[k] = np.float64("inf")
            else:
                try:
                    d = WorkspaceVariable.convert(group_names[t],
                                                  ast.literal_eval(d))
                    res[k] = d
                except:
                    res[k] = d
        return res
Beispiel #7
0
    def add_variable(self, var):
        """
        This will try to copy a given python variable to the ARTS workspace and return
        a WorkspaceVariable object representing this newly created variable. Currently
        supported types are int, str, [str], [int], and numpy.ndarrays, which will
        automatically converted to the corresponding values ARTS groups.

        The user should not have to call this method explicitly, but instead it is used by
        the WorkspaceMethod call function to transfer python variable arguments to the
        ARTS workspace.

        Args:
            var: Python variable of type int, str, [str], [int] or np.ndarray which should
                 be copied to the workspace.
        """
        if type(var) == WorkspaceVariable:
            return var
        group_id = WorkspaceVariable.get_group_id(var)
        s = VariableValueStruct(var)
        ws_id = arts_api.add_variable(self.ptr, group_id, None)
        arts_api.set_variable_value(self.ptr, ws_id, group_id, s)
        return WorkspaceVariable(ws_id, str(id(var)), group_names[group_id],
                                 "User defined variable.", self)
Beispiel #8
0
    def create(self, ws, name=None):
        """
        Call to <Group>Create WSMs are handled differently. This method simply
        determines the group type from the function name and then add a variable of
        this type to the workspace ws. A handle of this variable is then added to
        as attribute to the typhon.arts.workspace.variables module.

        Args:
            ws(Workspace): Workspace object to add the variable to
            name(str):     Name of the variable to add to the workspace
        """
        group = WorkspaceMethod.create_regexp.match(self.name).group(1)
        group_id = group_ids[group]

        if not name:
            name = "__anonymous_" + str(len(ws._vars))
            ws_id = arts_api.add_variable(ws.ptr, group_id, name.encode())
        else:
            # Is there a WSM with that name?
            if name in workspace_methods.keys():
                raise Exception("A WSM with the name " + name +
                                " already exists.")

            # Is there a WSV with that name?
            ws_id = arts_api.lookup_workspace_variable(name.encode())
            # Is yes, check that it is of the same group?
            if not ws_id == -1:
                v = arts_api.get_variable(ws_id)
                if not v.group == group_id:
                    raise Exception("A WSV with the name " + name +
                                    " but of goup " + group_names[v.group] +
                                    " already exists.")
            # Otherwise we add the variable.
            else:
                ws_id = arts_api.add_variable(ws.ptr, group_id, name.encode())

        wsv = WorkspaceVariable(ws_id, name, group, "User defined variable.",
                                ws)
        setattr(variables, name, wsv)
        ws._vars[name] = wsv
        return wsv
Beispiel #9
0
    def create(self, ws, name=None):
        """
        Call to <Group>Create WSMs are handled differently. This method simply
        determines the group type from the function name and then add a variable of
        this type to the workspace ws. A handle of this variable is then added to
        as attribute to the typhon.arts.workspace.variables module.

        Args:
            ws(Workspace): Workspace object to add the variable to
            name(str):     Name of the variable to add to the workspace
        """
        if not name:
            name = "__anonymous_" + str(len(ws.vars))
        group = WorkspaceMethod.create_regexp.match(self.name).group(1)
        group_id = group_ids[group]
        ws_id = arts_api.add_variable(ws.ptr, group_id)
        wsv = WorkspaceVariable(ws_id, name, group, "User defined variable.",
                                ws)
        setattr(variables, name, wsv)
        ws.vars[name] = wsv
        return wsv
Beispiel #10
0
    def _parse_output_input_lists(self, ws, args, kwargs):
        n_args = self.n_g_out + self.n_g_in

        ins = self.ins
        temps = []

        # Add positional arguments to kwargs
        if (len(args)) and (len(args)) < self.n_g_out + self.n_in:
            raise Exception("Only " + str(len(args)) +
                            "positional arguments provided " + "but WSM " +
                            self.name + "requires at least " +
                            str(self.n_g_out + self.n_in))
        for j in range(len(args)):
            if j < self.n_g_out:
                name = self.g_out[j]
                try:
                    kwargs[name] = args[j]
                except:
                    raise Exception("Generic parameter " + str(name) +
                                    " set twice.")
            elif j < self.n_g_out + self.n_in:
                if type(args[j]) == WorkspaceVariable:
                    ins[j - self.n_g_out] = args[j].ws_id
                else:
                    temps.append(ws.add_variable(args[j]))
                    ins[j - self.n_g_out] = temps[-1].ws_id
            elif j < self.n_g_out + self.n_in + self.n_g_in:
                name = self.g_in[j - self.n_g_out - self.n_in]
                try:
                    kwargs[name] = args[j]
                except:
                    raise Exception("Generic parameter " + str(name) +
                                    " set twice.")
            else:
                raise Exception(
                    str(j) +
                    " positional arguments given, but this WSM expects " +
                    str(j - 1) + ".")

        # Check output argument names
        g_output_args = dict()
        for k in self.g_out:
            if not k in kwargs:
                raise Exception("WSM " + self.name + " needs generic output " +
                                k)
            else:
                g_output_args[k] = kwargs[k]

        # Check input argument names
        g_input_args = dict()
        for k in self.g_in:
            if not k in kwargs:
                if k in self.g_in_default:
                    g_input_args[k] = self.g_in_default[k]
                else:
                    raise Exception("WSM " + self.name +
                                    " needs generic input " + k)
            else:
                g_input_args[k] = kwargs[k]

        # Resolve overload (if necessary).
        g_out_types = dict([(k,
                             WorkspaceVariable.get_group_id(g_output_args[k]))
                            for k in self.g_out])
        g_in_types = dict([(k, WorkspaceVariable.get_group_id(g_input_args[k]))
                           for k in self.g_in])
        m_id = self.m_ids[0]
        sg_index = 0

        if (len(self.m_ids) > 1):
            out_indices = [
                i for i, ts in enumerate(self.g_out_types) if ts == g_out_types
            ]
            in_indices = [
                i for i, ts in enumerate(self.g_in_types) if ts == g_in_types
            ]
            sg_indices = set(out_indices) & set(in_indices)

            if len(sg_indices) > 1:
                raise Exception(
                    "Could not uniquely resolve super-generic overload.")

            sg_index = sg_indices.pop()
            m_id = self.m_ids[sg_index]

        # Combine input and output arguments into lists.
        arts_args_out = []
        for out in self.outs:
            arts_args_out.append(out)

        for name in self.g_out:
            arg = g_output_args[name]
            if not type(arg) == WorkspaceVariable:
                raise ValueError("Generic Output " + name +
                                 " must be an ARTS WSV.")
            group_id = arg.group_id
            expected = self.g_out_types[sg_index][name]
            if not group_id == expected:
                raise Exception("Generic output " + name +
                                " expected to be of type " +
                                group_names[expected])
            arts_args_out.append(arg.ws_id)

        arts_args_in = []
        for i in ins:
            if not i in self.outs:
                arts_args_in.append(i)

        for name in self.g_in:
            arg = g_input_args[name]
            if type(arg) == WorkspaceVariable:
                arts_args_in.append(arg.ws_id)
            else:
                group_id = WorkspaceVariable.get_group_id(arg)
                expected = self.g_in_types[sg_index][name]
                if not group_id == expected:
                    raise Exception("Generic input " + name +
                                    " expected to be of type " +
                                    group_names[expected])
                temps.append(ws.add_variable(arg))
                arts_args_in.append(temps[-1].ws_id)
        return (m_id, arts_args_out, arts_args_in, temps)