示例#1
0
文件: core.py 项目: gyenney/Tools
    def evaluate(self,
                 cmds,
                 verbose=True,
                 log=True,
                 logger=None,
                 timeout=None,
                 pre_call='',
                 post_call=''):
        """Perform the low-level interaction with an Scilab Session
        """

        self.logger = logger

        if not timeout is None:
            self.set_timeout(timeout)

        if not self.proc:
            raise Scilab2PyError('Session Closed, try a restart()')

        if self._first:
            self.write("""
                try
                  getd(".");
                catch
                end
                """)

        if os.path.exists(self.outfile):
            try:
                os.remove(self.outfile)
            except OSError as e:
                self.logger.debug(e)

        outfile = self.outfile

        # use ascii code 2 for start of text, 3 for end of text, and
        # 24 to signal an error
        expr = '\n'.join(cmds)

        # scilab cannot handle "#" commented lines
        # try and remove them
        expr = re.sub(r'[\A\n]\s*#', '//', expr)

        # use ascii code 2 for start of text, 3 for end of text, and
        # 24 to signal an error
        output = """
        %(pre_call)s

        clear("ans");
        clear("a__");
        clear("_ans");

        try
            disp(char(2));
            %(expr)s
            if exists("ans") == 1 then
               _ans = ans;
            end
        catch
            disp(lasterror());
            disp(char(24));
        end


        if exists("_ans") == 1
            if type(_ans) == 4 then
                   _ans = double(_ans)
            end
            if or(type(_ans) == [1,2,3,5,6,7,8,10]) then
                    if exists("a__") == 0 then
                        try
                            savematfile -v6 %(outfile)s _ans;
                        catch
                            disp(_ans)
                        end
                    end
                elseif type(_ans)
                    disp(_ans);
                end
        end

        %(post_call)s

        disp(char(3))
        """ % locals()

        if len(cmds) == 5:
            main_line = cmds[2].strip()
        else:
            main_line = '\n'.join(cmds)

        self.logger.debug(output)

        self.write(output + '\n')

        if self._first:
            self.expect(chr(2))
        else:
            self.expect(chr(2), timeout=1)
        self._first = False

        debug_prompt = ("Type 'resume' or 'abort' to return to "
                        "standard level prompt.")

        resp = []
        while 1:
            line = self.readline()

            if chr(3) in line:
                break

            elif chr(24) in line:
                msg = ('Scilab2Py tried to run:\n"""\n{0}\n"""\n'
                       'Scilab returned:\n{1}'.format(main_line,
                                                      '\n'.join(resp)))
                raise Scilab2PyError(msg)

            elif line.strip() == debug_prompt:
                self.interact('-1->')

            if verbose and logger:
                logger.info(line)

            elif log and logger:
                logger.debug(line)

            if resp or line.strip():
                resp.append(line)

        return '\n'.join(resp).rstrip()
示例#2
0
文件: core.py 项目: rowhit/scilab2py
    def eval(self,
             cmds,
             verbose=True,
             timeout=None,
             log=True,
             plot_dir=None,
             plot_name='plot',
             plot_format='png',
             plot_width=620,
             plot_height=590,
             return_both=False):
        """
        Perform Scilab command or commands.

        Parameters
        ----------
        cmd : str or list
            Commands(s) to pass directly to Scilab.
        verbose : bool, optional
             Log Scilab output at info level.
        timeout : float
            Time to wait for response from Scilab (per character).
                plot_dir: str, optional
            If specificed, save the session's plot figures to the plot
            directory instead of displaying the plot window.
        plot_name : str, optional
            Saved plots will start with `plot_name` and
            end with "_%%.xxx' where %% is the plot number and
            xxx is the `plot_format`.
        plot_format: str, optional
            The format in which to save the plot (PNG by default).
        plot_width: int, optional
            The plot with in pixels.
        plot_height: int, optional
            The plot height in pixels.
        return_both : bool, optional
            If True, return an (printed output, value) tuple. If "ans =" is in the printed output,
            the printed output will have that portion removed.

        Returns
        -------
        out : str
            Results printed by Scilab.

        Raises
        ------
        Scilab2PyError
            If the command(s) fail.

        """
        if not self._session:
            raise Scilab2PyError('No Scilab Session')

        if isinstance(cmds, (str, unicode)):
            cmds = [cmds]

        if verbose and log:
            [self.logger.info(line) for line in cmds]

        elif log:
            [self.logger.debug(line) for line in cmds]

        if timeout is None:
            timeout = self.timeout

        pre_call = ''
        post_call = ''

        pre_call += '''
        h = gdf();
         h.figure_position = [0, 0];
         h.figure_size = [%(plot_width)s,%(plot_height)s];
         h.axes_size = [%(plot_width)s * 0.98, %(plot_height)s * 0.8];
        ''' % locals()

        if not plot_dir is None:
            plot_dir = plot_dir.replace("\\", "/")

            spec = '%(plot_dir)s/%(plot_name)s*.%(plot_format)s' % locals()
            existing = glob.glob(spec)
            plot_offset = len(existing)

            pre_call += '''
                close all;
                function handle_all_fig()
                   ids_array=winsid();
                   for i=1:length(ids_array)
                      id=ids_array(i);
                      outfile = sprintf('%(plot_dir)s/__ipy_sci_fig_%%03d', i + %(plot_offset)s);
                      if '%(plot_format)s' == 'jpg' then
                        xs2jpg(id, outfile + '.jpg');
                      elseif '%(plot_format)s' == 'jpeg' then
                        xs2jpg(id, outfile + '.jpeg');
                      elseif '%(plot_format)s' == 'png' then
                        xs2png(id, outfile);
                      else
                        xs2svg(id, outfile);
                      end
                      close(get_figure_handle(id));
                   end
                endfunction
                ''' % locals()

            post_call += 'handle_all_fig();'

        try:
            resp = self._session.evaluate(cmds,
                                          verbose,
                                          log,
                                          self.logger,
                                          timeout=timeout,
                                          pre_call=pre_call,
                                          post_call=post_call)
        except KeyboardInterrupt:
            self.restart()
            raise Scilab2PyError('Session Interrupted, Restarting')

        outfile = self._reader.out_file

        data = None
        if os.path.exists(outfile) and os.stat(outfile).st_size:
            try:
                data = self._reader.extract_file()
            except (TypeError, IOError) as e:
                self.logger.debug(e)

        resp = resp.strip()

        if resp:
            if verbose:
                print(resp)
            self.logger.info(resp)

        if return_both:
            return resp, data
        else:
            return data
示例#3
0
文件: core.py 项目: gyenney/Tools
    def _call(self, func, *inputs, **kwargs):
        """
        Scilab2Py Parameters
        ----------
        inputs : array_like
            Variables to pass to the function.
        nout : int, optional
            Number of output arguments.
            This is set automatically based on the number of
            return values requested.
            You can override this behavior by passing a
            different value.
        verbose : bool, optional
             Log Scilab output at info level.
                plot_dir: str, optional
            If specificed, save the session's plot figures to the plot
            directory instead of displaying the plot window.
        plot_name : str, optional
            Saved plots will start with `plot_name` and
            end with "_%%.xxx' where %% is the plot number and
            xxx is the `plot_format`.
        plot_format: str, optional
            The format in which to save the plot (PNG by default).
        kwargs : dictionary, optional
            Key - value pairs to be passed as prop - value inputs to the
            function.  The values must be strings or numbers.

        Returns
        -------
        out : value
            Value returned by the function.

        Raises
        ------
        Scilab2PyError
            If the function call is unsucessful.

        Notes
        -----
        Integer type arguments will be converted to floating point
        unless `convert_to_float=False`.
        """
        nout = kwargs.pop('nout', get_nout())

        argout_list = ['ans']
        if '=' in func:
            nout = 0

        # these three lines will form the commands sent to Scilab
        # load("-v6", "infile", "invar1", ...)
        # [a, b, c] = foo(A, B, C)
        # save("-v6", "outfile", "outvar1", ...)
        load_line = call_line = save_line = ''

        prop_vals = []
        eval_kwargs = {}
        for (key, value) in kwargs.items():
            if key in ['verbose', 'timeout'] or key.startswith('plot_'):
                eval_kwargs[key] = value
                continue
            if isinstance(value, (str, unicode, int, float)):
                prop_vals.append('"%s", %s' % (key, repr(value)))
            else:
                msg = 'Keyword arguments must be a string or number: '
                msg += '%s = %s' % (key, value)
                raise Scilab2PyError(msg)
        prop_vals = ', '.join(prop_vals)

        if nout:
            # create a dummy list of var names ("a", "b", "c", ...)
            # use ascii char codes so we can increment
            argout_list, save_line = self._reader.setup(nout)
            call_line = '[{0}] = '.format(', '.join(argout_list))

        call_line += func + '('

        if inputs:
            argin_list, load_line = self._writer.create_file(inputs)
            call_line += ', '.join(argin_list)

        if prop_vals:
            if inputs:
                call_line += ', '
            call_line += prop_vals

        call_line += ');'

        # create the command and execute in octave
        cmd = [load_line, call_line, save_line]
        data = self.eval(cmd, **eval_kwargs)

        if isinstance(data, dict) and not isinstance(data, Struct):
            data = [data.get(v, None) for v in argout_list]
            if len(data) == 1 and data[0] is None:
                data = None

        return data