diff options
author | tiagocoutinho <tiagocoutinho@users.sourceforge.net> | 2012-07-10 15:58:39 +0000 |
---|---|---|
committer | tiagocoutinho <tiagocoutinho@users.sourceforge.net> | 2012-07-10 15:58:39 +0000 |
commit | e30711b4835c56b5ed361828507610c76374c3c5 (patch) | |
tree | c663190e9ad47004a85825ce7a567a5d55f619a8 | |
parent | 367bb413328f082eec2079b6c56b559ce068e4ae (diff) |
fix plotting feature
git-svn-id: file:///home/cpascual/src/sdnongit/svnbck/sardana/share/Sardana/trunk@20879 c480fdf4-a248-4bb0-8e4a-34cd1ef68f4f
-rw-r--r-- | src/sardana/macroserver/macro.py | 25 | ||||
-rw-r--r-- | src/sardana/macroserver/macros/examples/plotting.py | 24 | ||||
-rw-r--r-- | src/sardana/macroserver/msdoor.py | 37 | ||||
-rw-r--r-- | src/sardana/spock/ipython_00_10/genutils.py | 11 | ||||
-rw-r--r-- | src/sardana/spock/ipython_00_11/genutils.py | 20 | ||||
-rw-r--r-- | src/sardana/spock/spockms.py | 32 | ||||
-rw-r--r-- | src/sardana/tango/macroserver/Door.py | 79 |
7 files changed, 186 insertions, 42 deletions
diff --git a/src/sardana/macroserver/macro.py b/src/sardana/macroserver/macro.py index c330fed2..75a8be7b 100644 --- a/src/sardana/macroserver/macro.py +++ b/src/sardana/macroserver/macro.py @@ -696,12 +696,31 @@ class Macro(Logger): def plot(self, *args, **kwargs): """**Macro API**. Sends the plot command to the client using the 'RecordData' DevEncoded - attribute. The data is encoded using the JSON -> BZ2 codec. + attribute. The data is encoded using the pickle -> BZ2 codec. :param args: the plotting args :param kwargs: the plotting keyword args""" - data = dict(args=args, kwargs=kwargs) - self.sendRecordData(data, codec='bz2_json_plot') + self.pyplot.plot(*args, **kwargs) +# data = dict(args=args, kwargs=kwargs) +# self.sendRecordData(data, codec='bz2_pickle_plot') + + @property + @mAPI + def pylab(self): + try: + pylab = self._pylab + except AttributeError: + self._pylab = pylab = self.door.pylab + return pylab + + @property + @mAPI + def pyplot(self): + try: + pyplot = self._pyplot + except AttributeError: + self._pyplot = pyplot = self.door.pyplot + return pyplot @property def data(self): diff --git a/src/sardana/macroserver/macros/examples/plotting.py b/src/sardana/macroserver/macros/examples/plotting.py new file mode 100644 index 00000000..e32237bf --- /dev/null +++ b/src/sardana/macroserver/macros/examples/plotting.py @@ -0,0 +1,24 @@ +import math +from numpy import linspace +from scipy.integrate import quad +from scipy.special import j0 + +from sardana.macroserver.macro import macro + +def j0i(x): + """Integral form of J_0(x)""" + def integrand(phi): + return math.cos(x * math.sin(phi)) + return (1.0/math.pi) * quad(integrand, 0, math.pi)[0] + +@macro() +def J0_plot(self): + x = linspace(0, 20, 200) + y = j0(x) + x1 = x[::10] + y1 = map(j0i, x1) + self.pyplot.plot(x, y, label=r'$J_0(x)$') # + self.pyplot.plot(x1, y1, 'ro', label=r'$J_0^{integ}(x)$') + self.pyplot.title(r'Verify $J_0(x)=\frac{1}{\{pi}\int_0^{\pi}\cos(x \sin\phi)\,d\phi$') + self.pyplot.xlabel('$x$') + self.pyplot.legend() diff --git a/src/sardana/macroserver/msdoor.py b/src/sardana/macroserver/msdoor.py index 694462ad..03333cd6 100644 --- a/src/sardana/macroserver/msdoor.py +++ b/src/sardana/macroserver/msdoor.py @@ -114,6 +114,7 @@ class MSDoor(MSObject): self._record_data = None self._macro_proxy_cache = None self._input_handler = BaseInputHandler() + self._pylab_handler = None MSObject.__init__(self, **kwargs) def get_type(self): @@ -129,6 +130,40 @@ class MSDoor(MSObject): running_macro = property(get_running_macro) + def set_pylab_handler(self, ph): + self._pylab_handler = ph + + def get_pylab_handler(self): + return self._pylab_handler + + pylab_handler = property(get_pylab_handler, set_pylab_handler) + + def get_pylab(self): + ph = self.pylab_handler + if ph is None: + import matplotlib.pylab + ph = matplotlib.pylab + return ph + + pylab = property(get_pylab) + + def set_pyplot_handler(self, ph): + self._pyplot_handler = ph + + def get_pyplot_handler(self): + return self._pyplot_handler + + pyplot_handler = property(get_pyplot_handler, set_pyplot_handler) + + def get_pyplot(self): + ph = self.pyplot_handler + if ph is None: + import matplotlib.pyplot + ph = matplotlib.pyplot + return ph + + pyplot = property(get_pyplot) + def set_input_handler(self, ih): self._input_handler = ih @@ -164,7 +199,7 @@ class MSDoor(MSObject): if macro is None: macro = self - input_data = dict(prompt=msg) + input_data = dict(prompt=msg, type='input') input_data.update(kwargs) data_type = kwargs['data_type'] is_seq = not isinstance(data_type, (str, unicode)) and \ diff --git a/src/sardana/spock/ipython_00_10/genutils.py b/src/sardana/spock/ipython_00_10/genutils.py index 7fbc5514..9db26845 100644 --- a/src/sardana/spock/ipython_00_10/genutils.py +++ b/src/sardana/spock/ipython_00_10/genutils.py @@ -897,11 +897,6 @@ def init_magic(ip): ip.set_hook('pre_prompt_hook', magic.spock_pre_prompt_hook) def init_pre_spock(ip, macro_server, door): - - # initialize input handler as soon as possible - import sardana.spock.inputhandler - input_handler = sardana.spock.inputhandler.InputHandler() - so = IPython.ipstruct.Struct() full_door_tg_name, door_tg_name, door_tg_alias = from_name_to_tango(door) #macro_server = get_ms_for_door(door_tg_name) @@ -960,7 +955,7 @@ def init_spock(ip, macro_server, door): def start(user_ns=None): - #if '-pylab' not in sys.argv: sys.argv.insert(1, '-pylab') + if '-pylab' not in sys.argv: sys.argv.insert(1, '-pylab') if '-q4thread' not in sys.argv: sys.argv.insert(1, '-q4thread') # Make sure the log level is changed to warning @@ -998,6 +993,10 @@ def mainloop(shell=None, user_ns=None): shell.mainloop() def run(user_ns=None): + # initialize input handler as soon as possible + import sardana.spock.inputhandler + input_handler = sardana.spock.inputhandler.InputHandler() + try: mainloop(user_ns=user_ns) finally: diff --git a/src/sardana/spock/ipython_00_11/genutils.py b/src/sardana/spock/ipython_00_11/genutils.py index 31aad4fb..3388a375 100644 --- a/src/sardana/spock/ipython_00_11/genutils.py +++ b/src/sardana/spock/ipython_00_11/genutils.py @@ -815,11 +815,6 @@ def unload_ipython_extension(ipython): pass def load_config(config): - - # initialize input handler as soon as possible - import sardana.spock.inputhandler - input_handler = sardana.spock.inputhandler.InputHandler() - spockver = release.version pyver = get_python_version() ipyver = get_ipython_version() @@ -931,6 +926,7 @@ object? -> Details about 'object'. ?object also works, ?? prints more. term_app = config.TerminalIPythonApp term_app.display_banner = True term_app.gui = gui_mode + term_app.pylab='qt' #term_app.nosep = False #term_app.classic = True @@ -954,6 +950,11 @@ object? -> Details about 'object'. ?object also works, ?? prints more. ipython_widget.pylab = 'inline' # ------------------------------------ + # ConsoleWidget + # ------------------------------------ + console_widget = config.ConsoleWidget + + # ------------------------------------ # FrontendWidget # ------------------------------------ frontend_widget = config.FrontendWidget @@ -1033,6 +1034,12 @@ def mainloop(app=None, user_ns=None): app = start(user_ns) app.start() +def prepare_input_handler(): + # initialize input handler as soon as possible + import sardana.spock.inputhandler + input_handler = sardana.spock.inputhandler.InputHandler() + + def prepare_cmdline(argv=None): if argv is None: argv = sys.argv @@ -1080,7 +1087,8 @@ def run(): sys.exit(-1) except exception.SpockMissingRecommended, recommended: print str(recommended) - + + prepare_input_handler() prepare_cmdline() launch_new_instance() diff --git a/src/sardana/spock/spockms.py b/src/sardana/spock/spockms.py index 42eb04d8..2d8dcb62 100644 --- a/src/sardana/spock/spockms.py +++ b/src/sardana/spock/spockms.py @@ -438,23 +438,23 @@ class SpockBaseDoor(BaseDoor): def processRecordData(self, data): if data is None: return data = data[1] - if data['type'] == 'plot': - func_name = data['type'] - data = data['data'] - args, kwargs = data['args'], data['kwargs'] - # json converts strings to unicode strings but in a function call - # python demands that the kwargs keys be strings so we need to convert - # in python 3k this will change since all strings will be unicode - new_kwargs = {} - for k,v in kwargs.iteritems(): - if type(k) is unicode: k = str(k) - new_kwargs[k] = v + if data['type'] == 'function': + func_name = data['func_name'] + args = data['args'] + kwargs = data['kwargs'] + + members = func_name.split(".") + mod_list, fname = members[:-1], members[-1] + mod_name = ".".join(mod_list) + if mod_name: + mod = __import__(mod_name, fromlist=mod_list) + func = getattr(mod, fname) + else: + func = __builtins__[fname] try: - import pylab - f = getattr(pylab, func_name) - f(*args, **new_kwargs) - except Exception,e: - self.logReceived(self.Warning, ['Unable to plot:', str(e)]) + func(*args, **kwargs) + except Exception as e: + self.logReceived(self.Warning, ['Unable to execute %s: ' % func_name, str(e)]) _RECORD_DATA_THRESOLD = 4*1024*1024 # 4Mb diff --git a/src/sardana/tango/macroserver/Door.py b/src/sardana/tango/macroserver/Door.py index fd9910b0..0b07a0fd 100644 --- a/src/sardana/tango/macroserver/Door.py +++ b/src/sardana/tango/macroserver/Door.py @@ -83,19 +83,68 @@ class TangoInputHandler(BaseInputHandler): self._input_event.set() def input_wait(self, timeout=None): - if timeout is not None: - start_time = time.time() - wait = self._input_event.wait(timeout) - - if timeout is not None: - dt = time.time() - start_time - if self._value is None and dt > timeout: - if 'default_value' in self.input_data: - self._value = dict(input=self.input_data['default_value']) + # if there was a timeout: + # - set the value to the default value (if one exists) + # - inform clients that timeout occured and they should not wait for + # user input anymore + if not self._input_event.is_set(): + if 'default_value' in self.input_data: + self._value = dict(input=self.input_data['default_value']) + self.send_input_timeout() self._input_event.clear() return self._value + def send_input_timeout(self): + idata = self.input_data + input_data = dict(type="timeout", macro_id=idata['macro_id']) + if 'default_value' in idata: + input_data['default_value'] = idata['default_value'] + input_data = json.dumps(input_data) + door = self._door + door.set_attribute(self._attr, value=input_data) + + +class TangoPylabHandler(object): + + def __init__(self, door, attr, format="bz2_pickle"): + self.door = door + self.attr = attr + self.format = format + self.func_call + + def handle(self, func_name, *args, **kwargs): + codec = CodecFactory().getCodec(self.format) + data = dict(type='function', func_name=func_name, args=args, kwargs=kwargs) + event_value = codec.encode(('', data)) + self.door.set_attribute(self.attr, value=event_value) + + def __getattr__(self, name): + def f(*args, **kwargs): + full_name = "pylab." + name + return self.handle(full_name, *args, **kwargs) + f.__name__ = name + return f + +class TangoPyplotHandler(object): + + def __init__(self, door, attr, format="bz2_pickle"): + self.door = door + self.attr = attr + self.format = format + + def handle(self, func_name, *args, **kwargs): + codec = CodecFactory().getCodec(self.format) + data = dict(type='function', func_name=func_name, args=args, kwargs=kwargs) + event_value = codec.encode(('', data)) + self.door.set_attribute(self.attr, value=event_value) + + def __getattr__(self, name): + def f(*args, **kwargs): + full_name = "matplotlib.pyplot." + name + return self.handle(full_name, *args, **kwargs) + f.__name__ = name + return f class Door(SardanaDevice): @@ -175,11 +224,21 @@ class Door(SardanaDevice): self.door = door = \ macro_server.create_element(type="Door", name=name, full_name=full_name, id=self.Id) - input_attr = self.get_device_attr().get_attr_by_name('Input') self._setupLogHandlers(levels) + multi_attr = self.get_device_attr() + + input_attr = multi_attr.get_attr_by_name('Input') self._input_handler = ih = TangoInputHandler(self, input_attr) door.set_input_handler(ih) + + recorddata_attr = multi_attr.get_attr_by_name('RecordData') + self._pylab_handler = pylabh = TangoPylabHandler(self, recorddata_attr) + door.set_pylab_handler(pylabh) + + self._pyplot_handler = pyploth = TangoPyplotHandler(self, recorddata_attr) + door.set_pyplot_handler(pyploth) + door.add_listener(self.on_door_changed) def _setupLogHandlers(self, levels): |