Commit c3eee192 authored by Yori Fournier's avatar Yori Fournier
Browse files

Merge branch '49-make-myaxes-client' of gitlab.aip.de:yfournier/myplotlib into...

Merge branch '49-make-myaxes-client' of gitlab.aip.de:yfournier/myplotlib into 49-make-myaxes-client

Conflicts:
	server.py
parents 26ee0ed1 d3f06a03
......@@ -63,11 +63,14 @@ if D_HIERARCHY in ('CLIENT', 'client', 'LOCAL', 'local'):
from matplotlib.figure import Figure
from matplotlib import is_interactive
from matplotlib import use
from .config import D_HOST, D_PORT
from socket import socket, AF_INET, SOCK_STREAM
elif D_HIERARCHY in ('SERVER', 'server'):
print(INFO+'Import myplotlib as a server.')
from .config import D_HOST, D_PORT
from socket import socket, AF_INET, SOCK_STREAM
from socket import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
else:
print(SEVR+'the value of D_HIERARCHY has to be SERVER or CLIENT')
......@@ -90,11 +93,39 @@ if D_HIERARCHY in ('CLIENT', 'client', 'LOCAL', 'local'):
# BACKEND: u'TKAgg', u'GTKAgg', u'WXAgg', u'Qt4Agg', u'MacOSX'
rcParams['backend'] = u'GTKAgg'
if D_HIERARCHY in ('CLIENT', 'client'):
# MyAxes: Overlay on matplotlib.Axes class
from .myAxes import MyAxes_client as MyAxes
# MyFig: Overlay on matplotlib.Figure class
from .myFig import MyFig_client as MyFig
elif(D_HIERARCHY in ('SERVER', 'server')):
# MyAxes: Overlay on matplotlib.Axes class
from .myAxes_server import MyAxes_server as MyAxes
# MyFig: Overlay on matplotlib.Figure class
from .myFig_server import MyFig_server as MyFig
elif D_HIERARCHY in ('LOCAL', 'local'):
# MyAxes: Overlay on matplotlib.Axes class
from .myAxes import MyAxes
# MyFig: Overlay on matplotlib.Figure class
from .myFig import MyFig
else:
print(SEVR+'the value of D_HIERARCHY has to be SERVER, CLIENT or LOCAL')
raise ImportError
if D_HIERARCHY in ('CLIENT', 'client', 'LOCAL', 'local'):
_G_WINDOWS = []
......@@ -112,20 +143,6 @@ if D_HIERARCHY in ('CLIENT', 'client', 'LOCAL', 'local'):
else:
print(SEVR + "The backend you choosed is not supported interactive mode not available")
elif(D_HIERARCHY in ('SERVER', 'server')):
# MyAxes: Overlay on matplotlib.Axes class
from .myAxes_server import MyAxes_server as MyAxes
# MyFig: Overlay on matplotlib.Figure class
from .myFig_server import MyFig_server as MyFig
else:
print(SEVR+'the value of D_HIERARCHY has to be SERVER, CLIENT or LOCAL')
raise ImportError
# myTool.*: interface functions to use myplotlib interactively
#from .mytool import print2file # need to make tools for server ?? or just put them in client/local
#from .mytool import FigOneAxes
......@@ -143,3 +160,6 @@ if D_HIERARCHY in ('CLIENT', 'client', 'LOCAL', 'local'):
from .test import myTest
from .test import testList
# for testing purpose
from .test import readStupidData
......@@ -149,6 +149,7 @@ elif run4Plot:
elif run4server:
from .server import Server
from .test import readStupidData
server = Server()
server.init()
......
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ================= FILE HEADER ========================================
#
# myplotlib v3.0.1,
#
# @file myAxes.py
# @author Yori 'AGy' Fournier
# @licence CC-BY-SA
#
# MyAxes class: Overlay of matplotlib Axes class
# It is done such that the user can concentrate on
# the important aspect of the figure and not the
# technical part. It consists of a constructor,
# that requires a Figure, the ratio of the xaxis over
# the yaxis, and the frame in which the figure
# should be plotted.
#
# @Class MyAxes
#
# @Constructor(self, fig, ratio, frame, +user defined kw):
#
# @section Functions
#
# - plotting: this is the overwritten function
# from Axes. It is called by it's
# parent-figure's function .plot()
#
# - formatRawData: it computes out of the rawData
# given as argument some quantities that
# are returned as a dictionary and
# become accessable for plotting.
#
# @section History
#
# v 0.0.0 - MyAxes class for the myplotlib module, consists
# of a constructor, a pltting function and
# formatRawData.
#
# v 2.2.3 - Add testRawData function
#
# ======================================================================
#
#
# IMPORT ---------------------------------------------------------------
from . import SEVR, DBUG
from . import Axes
from . import rcParams
# Class MyAxes Overwriting Matplotlib.figure.Axes
class MyAxes(Axes):
# CONSTRUCTOR --------------------------------------------------------
def __init__(self, fig, ratio, frameRect, *args, **kwargs):
self.fig = fig
self.declareKeywords()
rect = self.computeRect(ratio, frameRect, *args, **kwargs)
kwargs.pop('forceRatioOnWidth', None)
kwargs.pop('forceRatioOnHeight', None)
# parent constructor
Axes.__init__(self, fig, rect, **kwargs)
# set a default name. Should be individualized by instance
self.name = 'default'
# COMPUTE RECT -------------------------------------------------------
def computeRect(self, ratio, frameRect, *args, **kwargs):
# Get the optional keyword
forceRatioOnWidth = kwargs.pop('forceRatioOnWidth', None)
forceRatioOnHeight = kwargs.pop('forceRatioOnHeight', None)
# get the frame allowed
framePosX, framePosY, frameWidth, frameHeight = frameRect
# get the size of the figure
figWidth = self.fig.get_figwidth()
figHeight = self.fig.get_figheight()
if(forceRatioOnWidth):
frameWidth = ratio * figWidth / (frameHeight * figHeight)
elif(forceRatioOnHeight):
frameHeight = ratio * (frameWidth * figWidth) / figHeight
rect = [framePosX, framePosY, frameWidth, frameHeight]
return(rect)
# DECLARE KEYWORDS -------------------------------------------------
def declareKeywords(self):
self.keywords = {}
# PLOTTING -----------------------------------------------------------
def plotting(self):
return(True)
# UPDATE -------------------------------------------------------------
def update(self, *args, **kwargs):
# Because matplotlib.axes.update expect kwargs and not **kwargs ... (stupid!!)
if args: # catch matplotlib kwargs
kwargs = args[0]
# kw_for_axes = {key: value for (key, value) in args[0].items() if key not in self.keywords} # Not compatible with python2.6
kw_for_axes = {}
for (key, value) in args[0].items():
if key not in self.keywords:
kw_for_axes.update({key: value})
Axes.update(self, kw_for_axes) # update matplotlib.Axes
# myplotlib update
# self.keywords.update({key: value for (key, value) in kwargs.items() if key in self.keywords}) # Not compatible with python2.6
for (key, value) in kwargs.items():
if key in self.keywords:
self.keywords.update({key: value})
from . import socket, AF_INET, SOCK_STREAM
from . import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
from . import D_HOST
from . import D_PORT
from . import INFO, DBUG, WARN, SEVR, SPCE
from . import readStupidData
G_RAWDATA = {}
class Server():
def __init__(self):
self.soc = socket(AF_INET, SOCK_STREAM)
# self.soc.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) # requires some extra import
self.soc.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) # requires some extra import
self.host = D_HOST
self.port = D_PORT
# self.answer = False
def init(self):
self.soc.bind((self.host, self.port))
......@@ -22,27 +24,75 @@ class Server():
def run(self):
answer = False
signal = False
while True:
if not answer:
if not signal:
conn, addr = self.soc.accept()
print(INFO + 'Connected by ' + str(addr))
answer = conn.recv(1024)
signal = conn.recv(1024)
if answer in ('KILL', 'kill', 'Kill'):
if signal in ('KILL', 'kill', 'Kill'):
print(INFO+"Recieved 'Kill' signal.")
conn.close()
break
elif signal != '':
answer = self.treatAnswer(signal)
conn.sendall(str(answer))
else:
self.treatAnswer(answer)
pass
def treatAnswer(self, answer):
def treatAnswer(self, signal):
answer = None
try:
exec(str(answer))
(header, content) = eval(str(signal))
except:
print(INFO+"I could not execute the command")
print(INFO+'Received: '+str(answer))
print(WARN+"I could not execute the command")
print(SPCE+'Received: '+str(signal))
print(SPCE+"I expect '(header, content)'")
answer = ('readData', None, 'answer not correct format')
return(answer)
if header in ('readData', 'READDATA', 'readdata'):
try:
(dataName, functionName, args, kwargs) = eval(str(content))
except:
print(WARN+"The content of readData could not be extracted")
print(SPCE+'Received: '+str(content))
print(SPCE+"I expect '(dataName, functionName, args, kwargs)'")
answer = ('readData', None, 'could not extract content')
return(answer)
try:
print(str(functionName)+'('+str(args)+', '+str(kwargs)+')')
if args is not None:
if kwargs is not None:
G_RAWDATA[dataName] = eval(str(functionName)+'('+str(args)+', '+str(kwargs)+')')
else:
G_RAWDATA[dataName] = eval(str(functionName)+'('+str(args)+')')
else:
if kwargs is not None:
G_RAWDATA[dataName] = eval(str(functionName)+'('+str(kwargs)+')')
else:
G_RAWDATA[dataName] = eval(str(functionName)+'()')
print(G_RAWDATA[dataName].data)
answer = ('readData', dataName, 'no error')
except:
print(WARN+"The read function could not be executed")
answer = ('readData', None, 'function could not be executed')
return(answer)
else:
print(WARN+"I don't know ths signal, sorry")
answer = ('readData', None, 'signal unknown')
return(answer)
return(answer)
from socket import socket, AF_INET, SOCK_STREAM
class ServerInterface(object):
def __init__(self, ip, port):
self.ip = ip
self.port = port
# just a list of names
self.currentRemoteData = []
def readData(self, ioFunction, dataName, *args, **kwargs):
content = '['+str(dataName)+', '+ioFunction.__name__+', '+str(args)+', '+str(kwargs)+']'
signal = "("+'readData'+', '+str(content)+')'
# create signal
sock = self.sendSignal(signal)
(answer, errmsg) = self.waitForAnswer(sock)
dataName = answer
# add data in the currentSyncData interface
if dataName is None:
print(SEVR+errmsg)
status=False
else:
self.currentSyncData.append(dataName)
status=True
return(True)
def newSyncFigure(self, figClass, symbolicRawdata, **kwargs):
syncFigure = figClass(symbolicRawdata, **kwargs)
# create a socket
# connect to ip:port
# send signal with parameters
# wait for answer:
# response is [ID, errormsg]
# ID = -1 no figure were created
# maybe error msg?
ID = 1
# if ok then create syncFigure.
# add the identifier of the server-side figure
syncFigure.syncID = ID
# return the syncFigure
return(syncFigure)
def sendSignal(self, signal):
sock = socket(AF_INET, SOCK_STREAM)
sock.connect((self.ip, self.port))
sock.sendall(str(signal))
return(sock)
def waitForAnswer(self, sock):
answer = sock.recv(1024)
return(answer)
from .. import D_HIERARCHY
from .myIOs import readStupidData, readStupidData2
if D_HIERARCHY in ('CLIENT', 'client', 'local', 'LOCAL'):
if D_HIERARCHY in ('CLIENT', 'client'):
from .axTestClient import AxTestClient
# from .figTestClient import FigTestClient
# from .tests_client import myTest
# from .tests_client import test100
# testList = [test100,
# ]
elif D_HIERARCHY in ('SERVER', 'server'):
pass
# from .axTestServer import AxTestServer
# from .figTestServer import FigTestServer
# from .tests_server import myTest
# from .tests_server import test100
# testList = [test100,
# ]
elif D_HIERARCHY in ('local', 'LOCAL'):
from .axTest1 import AxTest1
from .axTest1 import AxTestPlot2D, AxTestPlots2D
......@@ -38,10 +58,4 @@ if D_HIERARCHY in ('CLIENT', 'client', 'local', 'LOCAL'):
else:
from .axTestServer import AxTestServer
from .figTestServer import FigTestServer
from .tests_server import myTest
from .tests_server import test100
testList = [test100,
]
raise ImportError
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ================= FILE HEADER ========================================
#
# myplotlib v3.0.1,
#
# @file myAxes.py
# @author Yori 'AGy' Fournier
# @licence CC-BY-SA
#
# MyAxes class: Overlay of matplotlib Axes class
# It is done such that the user can concentrate on
# the important aspect of the figure and not the
# technical part. It consists of a constructor,
# that requires a Figure, the ratio of the xaxis over
# the yaxis, and the frame in which the figure
# should be plotted.
#
# @Class MyAxes
#
# @Constructor(self, fig, ratio, frame, +user defined kw):
#
# @section Functions
#
# - plotting: this is the overwritten function
# from Axes. It is called by it's
# parent-figure's function .plot()
#
# - formatRawData: it computes out of the rawData
# given as argument some quantities that
# are returned as a dictionary and
# become accessable for plotting.
#
# @section History
#
# v 0.0.0 - MyAxes class for the myplotlib module, consists
# of a constructor, a pltting function and
# formatRawData.
#
# ======================================================================
#
#
# IMPORT ---------------------------------------------------------------
from .. import SEVR, DBUG, INFO
from .. import MyAxes
D_XRANGE = None
D_YRANGE = None
D_LOGY = False
D_LOGX = False
# Class MyAxes Overwriting Matplotlib.figure.Axes
class AxTestClient(MyAxes):
def declareKeywords(self):
self.keywords = {'xRange': D_XRANGE,
'yRange': D_YRANGE}
return(True)
# PLOTTING -----------------------------------------------------------
# the plotting function (need to be overwrite from child
def plotting(self):
xRange = self.keywords.get('xRange')
yRange = self.keywords.get('yRange')
try:
self.plot(self.data['xdata'], self.data['ydata'])
except KeyError:
print(SEVR + 'The formatting of the data was apparently wrong. --> EXIT')
return(False)
if (xRange): self.set_xlim(xRange)
if (yRange): self.set_ylim(yRange)
return(True)
from .. import os
from .. import D_OFORMAT, D_OPATH
from .. import MyData
from .. import SEVR, WARN, DBUG, SPCE
# TESTER
def myTest(function, expected, failed, debug):
if debug:
status = function(debug)
if status is not expected:
failed.append(str(function.__name__))
return(False)
else:
return(True)
else:
try:
status = function(debug)
if status is not expected:
failed.append(str(function.__name__))
return(False)
else:
return(True)
except:
print(WARN + str(function.__name__) + " caught exception.")
failed.append(str(function.__name__))
return(False)
return(True)
# TEST 1.* for testing MyFig_server
# TEST 2.* for testing MyAxes_server
# TEST 1.00: Test server.requestServerInterface
def test100(debug):
status = True
wrongIP = 15.12.12.12.42
wrongPort = 22
correctIP = 127.0.0.1
correctPort = 50824
server = requestServerInterface(wrongIP, correctPORT)
if (server is None) or (not isinstance(server, ServerInterface)):
status = True
else:
status = False
server = requestServerInterface(correctIP, wrongPORT)
if (server is None) or (not isinstance(server, ServerInterface)):
status = status and True
else:
status = False
server = requestServerInterface(correctIP, correctPORT)
if (server is None) or (not isinstance(server, ServerInterface)):
status = False
else:
status = status and True
return(status)
# Test readData
def test101(debug):
status = True
IP = 127.0.0.1
Port = 50824
server = requestServerInterface(IP, PORT)
status = server.readData(readStupidData, 'data-name', 42, option=True)
return(status)
# Test listCurrentData
def test102(debug):
status = True
IP = 127.0.0.1
Port = 50824
server = requestServerInterface(IP, PORT)
server.readData(readStupidData, 'data-name', 42, option=True)
listOfData = server.listCurrentData()
if listOfData != ['data-name',]:
status = False
return(status)
# test newFigure
def test103(debug):
status = True
IP = 127.0.0.1
Port = 50824
server = requestServerInterface(IP, PORT)
server.readData(readStupidData, 'data-name', 42, option=True)
listOfData = server.listCurrentData()
myTestFig = server.newFigure(FigTestRemote, ('data-name', ), xRange = [2.,3.])
return(status)