##// END OF EJS Templates
Move schaincli to schainpy.cli
Juan C. Espinoza -
r1113:f2689c814816
parent child
Show More
1 NO CONTENT: file renamed from schaincli/README.md to schainpy/cli/README.md
NO CONTENT: file renamed from schaincli/README.md to schainpy/cli/README.md
1 NO CONTENT: file renamed from schaincli/__init__.py to schainpy/cli/__init__.py
NO CONTENT: file renamed from schaincli/__init__.py to schainpy/cli/__init__.py
@@ -1,168 +1,168
1 import click
1 import click
2 import schainpy
2 import schainpy
3 import subprocess
3 import subprocess
4 import os
4 import os
5 import sys
5 import sys
6 import glob
6 import glob
7 save_stdout = sys.stdout
7 save_stdout = sys.stdout
8 sys.stdout = open('trash', 'w')
8 sys.stdout = open('trash', 'w')
9 from multiprocessing import cpu_count
9 from multiprocessing import cpu_count
10 from schaincli import templates
11 from schainpy.controller import Project
10 from schainpy.controller import Project
12 from schainpy.model import Operation, ProcessingUnit
11 from schainpy.model import Operation, ProcessingUnit
13 from schainpy.utils import log
12 from schainpy.utils import log
14 from importlib import import_module
13 from importlib import import_module
15 from pydoc import locate
14 from pydoc import locate
16 from fuzzywuzzy import process
15 from fuzzywuzzy import process
17 from schainpy.utils import paramsFinder
16 from schainpy.utils import paramsFinder
17 import templates
18 sys.stdout = save_stdout
18 sys.stdout = save_stdout
19
19
20
20
21 def print_version(ctx, param, value):
21 def print_version(ctx, param, value):
22 if not value or ctx.resilient_parsing:
22 if not value or ctx.resilient_parsing:
23 return
23 return
24 click.echo(schainpy.__version__)
24 click.echo(schainpy.__version__)
25 ctx.exit()
25 ctx.exit()
26
26
27
27
28 cliLogger = log.makelogger('schain cli')
28 cliLogger = log.makelogger('schain cli')
29 PREFIX = 'experiment'
29 PREFIX = 'experiment'
30
30
31
31
32 @click.command()
32 @click.command()
33 @click.option('--version', '-v', is_flag=True, callback=print_version, help='SChain version', type=str)
33 @click.option('--version', '-v', is_flag=True, callback=print_version, help='SChain version', type=str)
34 @click.argument('command', default='run', required=True)
34 @click.argument('command', default='run', required=True)
35 @click.argument('nextcommand', default=None, required=False, type=str)
35 @click.argument('nextcommand', default=None, required=False, type=str)
36 def main(command, nextcommand, version):
36 def main(command, nextcommand, version):
37 """COMMAND LINE INTERFACE FOR SIGNAL CHAIN - JICAMARCA RADIO OBSERVATORY \n
37 """COMMAND LINE INTERFACE FOR SIGNAL CHAIN - JICAMARCA RADIO OBSERVATORY \n
38 Available commands.\n
38 Available commands.\n
39 --xml: runs a schain XML generated file\n
39 --xml: runs a schain XML generated file\n
40 run: runs any python script starting 'experiment_'\n
40 run: runs any python script starting 'experiment_'\n
41 generate: generates a template schain script\n
41 generate: generates a template schain script\n
42 search: return avilable operations, procs or arguments of the give operation/proc\n"""
42 search: return avilable operations, procs or arguments of the give operation/proc\n"""
43 if command == 'xml':
43 if command == 'xml':
44 runFromXML(nextcommand)
44 runFromXML(nextcommand)
45 elif command == 'generate':
45 elif command == 'generate':
46 generate()
46 generate()
47 elif command == 'test':
47 elif command == 'test':
48 test()
48 test()
49 elif command == 'run':
49 elif command == 'run':
50 runschain(nextcommand)
50 runschain(nextcommand)
51 elif command == 'search':
51 elif command == 'search':
52 search(nextcommand)
52 search(nextcommand)
53 else:
53 else:
54 log.error('Command {} is not defined'.format(command))
54 log.error('Command {} is not defined'.format(command))
55
55
56
56
57 def check_module(possible, instance):
57 def check_module(possible, instance):
58 def check(x):
58 def check(x):
59 try:
59 try:
60 instancia = locate('schainpy.model.{}'.format(x))
60 instancia = locate('schainpy.model.{}'.format(x))
61 return isinstance(instancia(), instance)
61 return isinstance(instancia(), instance)
62 except Exception as e:
62 except Exception as e:
63 return False
63 return False
64 clean = clean_modules(possible)
64 clean = clean_modules(possible)
65 return [x for x in clean if check(x)]
65 return [x for x in clean if check(x)]
66
66
67
67
68 def clean_modules(module):
68 def clean_modules(module):
69 noEndsUnder = [x for x in module if not x.endswith('__')]
69 noEndsUnder = [x for x in module if not x.endswith('__')]
70 noStartUnder = [x for x in noEndsUnder if not x.startswith('__')]
70 noStartUnder = [x for x in noEndsUnder if not x.startswith('__')]
71 noFullUpper = [x for x in noStartUnder if not x.isupper()]
71 noFullUpper = [x for x in noStartUnder if not x.isupper()]
72 return noFullUpper
72 return noFullUpper
73
73
74
74
75 def search(nextcommand):
75 def search(nextcommand):
76 if nextcommand is None:
76 if nextcommand is None:
77 log.error('There is no Operation/ProcessingUnit to search')
77 log.error('There is no Operation/ProcessingUnit to search')
78 elif nextcommand == 'procs':
78 elif nextcommand == 'procs':
79 procs = paramsFinder.getProcs()
79 procs = paramsFinder.getProcs()
80 log.success(
80 log.success(
81 'Current ProcessingUnits are:\n\033[1m{}\033[0m'.format('\n'.join(procs)))
81 'Current ProcessingUnits are:\n\033[1m{}\033[0m'.format('\n'.join(procs)))
82
82
83 elif nextcommand == 'operations':
83 elif nextcommand == 'operations':
84 operations = paramsFinder.getOperations()
84 operations = paramsFinder.getOperations()
85 log.success('Current Operations are:\n\033[1m{}\033[0m'.format(
85 log.success('Current Operations are:\n\033[1m{}\033[0m'.format(
86 '\n'.join(operations)))
86 '\n'.join(operations)))
87 else:
87 else:
88 try:
88 try:
89 args = paramsFinder.getArgs(nextcommand)
89 args = paramsFinder.getArgs(nextcommand)
90 log.warning(
90 log.warning(
91 'Use this feature with caution. It may not return all the allowed arguments')
91 'Use this feature with caution. It may not return all the allowed arguments')
92 if len(args) == 0:
92 if len(args) == 0:
93 log.success('{} has no arguments'.format(nextcommand))
93 log.success('{} has no arguments'.format(nextcommand))
94 else:
94 else:
95 log.success('Showing {} arguments:\n\033[1m{}\033[0m'.format(
95 log.success('Showing {} arguments:\n\033[1m{}\033[0m'.format(
96 nextcommand, '\n'.join(args)))
96 nextcommand, '\n'.join(args)))
97 except Exception as e:
97 except Exception as e:
98 log.error('Module {} does not exists'.format(nextcommand))
98 log.error('Module {} does not exists'.format(nextcommand))
99 allModules = paramsFinder.getAll()
99 allModules = paramsFinder.getAll()
100 similar = process.extractOne(nextcommand, allModules)[0]
100 similar = process.extractOne(nextcommand, allModules)[0]
101 log.success('Showing {} instead'.format(similar))
101 log.success('Showing {} instead'.format(similar))
102 search(similar)
102 search(similar)
103
103
104
104
105 def runschain(nextcommand):
105 def runschain(nextcommand):
106 if nextcommand is None:
106 if nextcommand is None:
107 currentfiles = glob.glob('./{}_*.py'.format(PREFIX))
107 currentfiles = glob.glob('./{}_*.py'.format(PREFIX))
108 numberfiles = len(currentfiles)
108 numberfiles = len(currentfiles)
109 if numberfiles > 1:
109 if numberfiles > 1:
110 log.error('There is more than one file to run')
110 log.error('There is more than one file to run')
111 elif numberfiles == 1:
111 elif numberfiles == 1:
112 subprocess.call(['python ' + currentfiles[0]], shell=True)
112 subprocess.call(['python ' + currentfiles[0]], shell=True)
113 else:
113 else:
114 log.error('There is no file to run')
114 log.error('There is no file to run')
115 else:
115 else:
116 try:
116 try:
117 subprocess.call(['python ' + nextcommand], shell=True)
117 subprocess.call(['python ' + nextcommand], shell=True)
118 except Exception as e:
118 except Exception as e:
119 log.error("I cannot run the file. Does it exists?")
119 log.error("I cannot run the file. Does it exists?")
120
120
121
121
122 def basicInputs():
122 def basicInputs():
123 inputs = {}
123 inputs = {}
124 inputs['desc'] = click.prompt(
124 inputs['desc'] = click.prompt(
125 'Enter a description', default="A schain project", type=str)
125 'Enter a description', default="A schain project", type=str)
126 inputs['name'] = click.prompt(
126 inputs['name'] = click.prompt(
127 'Name of the project', default="project", type=str)
127 'Name of the project', default="project", type=str)
128 inputs['path'] = click.prompt('Data path', default=os.getcwd(
128 inputs['path'] = click.prompt('Data path', default=os.getcwd(
129 ), type=click.Path(exists=True, resolve_path=True))
129 ), type=click.Path(exists=True, resolve_path=True))
130 inputs['startDate'] = click.prompt(
130 inputs['startDate'] = click.prompt(
131 'Start date', default='1970/01/01', type=str)
131 'Start date', default='1970/01/01', type=str)
132 inputs['endDate'] = click.prompt(
132 inputs['endDate'] = click.prompt(
133 'End date', default='2017/12/31', type=str)
133 'End date', default='2017/12/31', type=str)
134 inputs['startHour'] = click.prompt(
134 inputs['startHour'] = click.prompt(
135 'Start hour', default='00:00:00', type=str)
135 'Start hour', default='00:00:00', type=str)
136 inputs['endHour'] = click.prompt('End hour', default='23:59:59', type=str)
136 inputs['endHour'] = click.prompt('End hour', default='23:59:59', type=str)
137 inputs['figpath'] = inputs['path'] + '/figs'
137 inputs['figpath'] = inputs['path'] + '/figs'
138 return inputs
138 return inputs
139
139
140
140
141 def generate():
141 def generate():
142 inputs = basicInputs()
142 inputs = basicInputs()
143 inputs['multiprocess'] = click.confirm('Is this a multiprocess script?')
143 inputs['multiprocess'] = click.confirm('Is this a multiprocess script?')
144 if inputs['multiprocess']:
144 if inputs['multiprocess']:
145 inputs['nProcess'] = click.prompt(
145 inputs['nProcess'] = click.prompt(
146 'How many process?', default=cpu_count(), type=int)
146 'How many process?', default=cpu_count(), type=int)
147 current = templates.multiprocess.format(**inputs)
147 current = templates.multiprocess.format(**inputs)
148 else:
148 else:
149 current = templates.basic.format(**inputs)
149 current = templates.basic.format(**inputs)
150 scriptname = '{}_{}.py'.format(PREFIX, inputs['name'])
150 scriptname = '{}_{}.py'.format(PREFIX, inputs['name'])
151 script = open(scriptname, 'w')
151 script = open(scriptname, 'w')
152 try:
152 try:
153 script.write(current)
153 script.write(current)
154 log.success('Script {} generated'.format(scriptname))
154 log.success('Script {} generated'.format(scriptname))
155 except Exception as e:
155 except Exception as e:
156 log.error('I cannot create the file. Do you have writing permissions?')
156 log.error('I cannot create the file. Do you have writing permissions?')
157
157
158
158
159 def test():
159 def test():
160 log.warning('testing')
160 log.warning('testing')
161
161
162
162
163 def runFromXML(filename):
163 def runFromXML(filename):
164 controller = Project()
164 controller = Project()
165 if not controller.readXml(filename):
165 if not controller.readXml(filename):
166 return
166 return
167 controller.start()
167 controller.start()
168 return
168 return
1 NO CONTENT: file renamed from schaincli/templates.py to schainpy/cli/templates.py
NO CONTENT: file renamed from schaincli/templates.py to schainpy/cli/templates.py
1 NO CONTENT: file renamed from schaincli/tests/__init__.py to schainpy/cli/tests/__init__.py
NO CONTENT: file renamed from schaincli/tests/__init__.py to schainpy/cli/tests/__init__.py
@@ -1,29 +1,29
1 import pytest
1 import pytest
2 from click.testing import CliRunner
2 from click.testing import CliRunner
3 from schaincli import cli
3 from schainpy.cli import cli
4
4
5
5
6 @pytest.fixture
6 @pytest.fixture
7 def runner():
7 def runner():
8 return CliRunner()
8 return CliRunner()
9
9
10
10
11 def test_cli(runner):
11 def test_cli(runner):
12 result = runner.invoke(cli.main)
12 result = runner.invoke(cli.main)
13 assert result.exit_code == 0
13 assert result.exit_code == 0
14 assert not result.exception
14 assert not result.exception
15 assert result.output.strip() == 'Hello, world.'
15 assert result.output.strip() == 'Hello, world.'
16
16
17
17
18 def test_cli_with_option(runner):
18 def test_cli_with_option(runner):
19 result = runner.invoke(cli.main, ['--as-cowboy'])
19 result = runner.invoke(cli.main, ['--as-cowboy'])
20 assert not result.exception
20 assert not result.exception
21 assert result.exit_code == 0
21 assert result.exit_code == 0
22 assert result.output.strip() == 'Howdy, world.'
22 assert result.output.strip() == 'Howdy, world.'
23
23
24
24
25 def test_cli_with_arg(runner):
25 def test_cli_with_arg(runner):
26 result = runner.invoke(cli.main, ['Jicamarca'])
26 result = runner.invoke(cli.main, ['Jicamarca'])
27 assert result.exit_code == 0
27 assert result.exit_code == 0
28 assert not result.exception
28 assert not result.exception
29 assert result.output.strip() == 'Hello, Jicamarca.'
29 assert result.output.strip() == 'Hello, Jicamarca.'
@@ -1,40 +1,39
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 import os
2 import os
3 import sys
3 import sys
4 from schainpy.utils import log
4 from schainpy.utils import log
5
5
6 try:
6 try:
7 from PyQt4 import QtCore, QtGui
7 from PyQt4 import QtCore, QtGui
8 from PyQt4.QtGui import QApplication
8 from PyQt4.QtGui import QApplication
9 except:
9 except:
10 log.error(
10 log.error(
11 'You should install PyQt4 module in order to run the GUI. See the README.')
11 'You should install PyQt4 module in order to run the GUI. See the README.')
12 sys.exit()
12 sys.exit()
13
13
14
15 from schainpy.gui.viewcontroller.initwindow import InitWindow
14 from schainpy.gui.viewcontroller.initwindow import InitWindow
16 from schainpy.gui.viewcontroller.basicwindow import BasicWindow
15 from schainpy.gui.viewcontroller.basicwindow import BasicWindow
17 from schainpy.gui.viewcontroller.workspace import Workspace
16 from schainpy.gui.viewcontroller.workspace import Workspace
18
17
19
18
20 def main():
19 def main():
21
20
22 app = QtGui.QApplication(sys.argv)
21 app = QtGui.QApplication(sys.argv)
23
22
24 Welcome = InitWindow()
23 Welcome = InitWindow()
25
24
26 if not Welcome.exec_():
25 if not Welcome.exec_():
27 sys.exit(-1)
26 sys.exit(-1)
28
27
29 WorkPathspace = Workspace()
28 WorkPathspace = Workspace()
30 if not WorkPathspace.exec_():
29 if not WorkPathspace.exec_():
31 sys.exit(-1)
30 sys.exit(-1)
32
31
33 MainGUI = BasicWindow()
32 MainGUI = BasicWindow()
34 MainGUI.setWorkSpaceGUI(WorkPathspace.dirComBox.currentText())
33 MainGUI.setWorkSpaceGUI(WorkPathspace.dirComBox.currentText())
35 MainGUI.show()
34 MainGUI.show()
36 sys.exit(app.exec_())
35 sys.exit(app.exec_())
37
36
38
37
39 if __name__ == "__main__":
38 if __name__ == "__main__":
40 main()
39 main()
@@ -1,635 +1,636
1 '''
1 '''
2 @author: Juan C. Espinoza
2 @author: Juan C. Espinoza
3 '''
3 '''
4
4
5 import time
5 import time
6 import json
6 import json
7 import numpy
7 import numpy
8 import paho.mqtt.client as mqtt
8 import paho.mqtt.client as mqtt
9 import zmq
9 import zmq
10 import datetime
10 import datetime
11 from zmq.utils.monitor import recv_monitor_message
11 from zmq.utils.monitor import recv_monitor_message
12 from functools import wraps
12 from functools import wraps
13 from threading import Thread
13 from threading import Thread
14 from multiprocessing import Process
14 from multiprocessing import Process
15
15
16 from schainpy.model.proc.jroproc_base import Operation, ProcessingUnit
16 from schainpy.model.proc.jroproc_base import Operation, ProcessingUnit
17 from schainpy.model.data.jrodata import JROData
17 from schainpy.model.data.jrodata import JROData
18 from schainpy.utils import log
18 from schainpy.utils import log
19
19
20 MAXNUMX = 100
20 MAXNUMX = 100
21 MAXNUMY = 100
21 MAXNUMY = 100
22
22
23 class PrettyFloat(float):
23 class PrettyFloat(float):
24 def __repr__(self):
24 def __repr__(self):
25 return '%.2f' % self
25 return '%.2f' % self
26
26
27 def roundFloats(obj):
27 def roundFloats(obj):
28 if isinstance(obj, list):
28 if isinstance(obj, list):
29 return map(roundFloats, obj)
29 return map(roundFloats, obj)
30 elif isinstance(obj, float):
30 elif isinstance(obj, float):
31 return round(obj, 2)
31 return round(obj, 2)
32
32
33 def decimate(z, MAXNUMY):
33 def decimate(z, MAXNUMY):
34 dy = int(len(z[0])/MAXNUMY) + 1
34 dy = int(len(z[0])/MAXNUMY) + 1
35
35
36 return z[::, ::dy]
36 return z[::, ::dy]
37
37
38 class throttle(object):
38 class throttle(object):
39 '''
39 '''
40 Decorator that prevents a function from being called more than once every
40 Decorator that prevents a function from being called more than once every
41 time period.
41 time period.
42 To create a function that cannot be called more than once a minute, but
42 To create a function that cannot be called more than once a minute, but
43 will sleep until it can be called:
43 will sleep until it can be called:
44 @throttle(minutes=1)
44 @throttle(minutes=1)
45 def foo():
45 def foo():
46 pass
46 pass
47
47
48 for i in range(10):
48 for i in range(10):
49 foo()
49 foo()
50 print "This function has run %s times." % i
50 print "This function has run %s times." % i
51 '''
51 '''
52
52
53 def __init__(self, seconds=0, minutes=0, hours=0):
53 def __init__(self, seconds=0, minutes=0, hours=0):
54 self.throttle_period = datetime.timedelta(
54 self.throttle_period = datetime.timedelta(
55 seconds=seconds, minutes=minutes, hours=hours
55 seconds=seconds, minutes=minutes, hours=hours
56 )
56 )
57
57
58 self.time_of_last_call = datetime.datetime.min
58 self.time_of_last_call = datetime.datetime.min
59
59
60 def __call__(self, fn):
60 def __call__(self, fn):
61 @wraps(fn)
61 @wraps(fn)
62 def wrapper(*args, **kwargs):
62 def wrapper(*args, **kwargs):
63 coerce = kwargs.pop('coerce', None)
63 coerce = kwargs.pop('coerce', None)
64 if coerce:
64 if coerce:
65 self.time_of_last_call = datetime.datetime.now()
65 self.time_of_last_call = datetime.datetime.now()
66 return fn(*args, **kwargs)
66 return fn(*args, **kwargs)
67 else:
67 else:
68 now = datetime.datetime.now()
68 now = datetime.datetime.now()
69 time_since_last_call = now - self.time_of_last_call
69 time_since_last_call = now - self.time_of_last_call
70 time_left = self.throttle_period - time_since_last_call
70 time_left = self.throttle_period - time_since_last_call
71
71
72 if time_left > datetime.timedelta(seconds=0):
72 if time_left > datetime.timedelta(seconds=0):
73 return
73 return
74
74
75 self.time_of_last_call = datetime.datetime.now()
75 self.time_of_last_call = datetime.datetime.now()
76 return fn(*args, **kwargs)
76 return fn(*args, **kwargs)
77
77
78 return wrapper
78 return wrapper
79
79
80 class Data(object):
80 class Data(object):
81 '''
81 '''
82 Object to hold data to be plotted
82 Object to hold data to be plotted
83 '''
83 '''
84
84
85 def __init__(self, plottypes, throttle_value):
85 def __init__(self, plottypes, throttle_value):
86 self.plottypes = plottypes
86 self.plottypes = plottypes
87 self.throttle = throttle_value
87 self.throttle = throttle_value
88 self.ended = False
88 self.ended = False
89 self.localtime = False
89 self.localtime = False
90 self.__times = []
90 self.__times = []
91 self.__heights = []
91 self.__heights = []
92
92
93 def __str__(self):
93 def __str__(self):
94 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
94 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
95 return 'Data[{}][{}]'.format(';'.join(dum), len(self.__times))
95 return 'Data[{}][{}]'.format(';'.join(dum), len(self.__times))
96
96
97 def __len__(self):
97 def __len__(self):
98 return len(self.__times)
98 return len(self.__times)
99
99
100 def __getitem__(self, key):
100 def __getitem__(self, key):
101 if key not in self.data:
101 if key not in self.data:
102 raise KeyError(log.error('Missing key: {}'.format(key)))
102 raise KeyError(log.error('Missing key: {}'.format(key)))
103
103
104 if 'spc' in key:
104 if 'spc' in key:
105 ret = self.data[key]
105 ret = self.data[key]
106 else:
106 else:
107 ret = numpy.array([self.data[key][x] for x in self.times])
107 ret = numpy.array([self.data[key][x] for x in self.times])
108 if ret.ndim > 1:
108 if ret.ndim > 1:
109 ret = numpy.swapaxes(ret, 0, 1)
109 ret = numpy.swapaxes(ret, 0, 1)
110 return ret
110 return ret
111
111
112 def __contains__(self, key):
112 def __contains__(self, key):
113 return key in self.data
113 return key in self.data
114
114
115 def setup(self):
115 def setup(self):
116 '''
116 '''
117 Configure object
117 Configure object
118 '''
118 '''
119
119
120 self.ended = False
120 self.ended = False
121 self.data = {}
121 self.data = {}
122 self.__times = []
122 self.__times = []
123 self.__heights = []
123 self.__heights = []
124 self.__all_heights = set()
124 self.__all_heights = set()
125 for plot in self.plottypes:
125 for plot in self.plottypes:
126 if 'snr' in plot:
126 if 'snr' in plot:
127 plot = 'snr'
127 plot = 'snr'
128 self.data[plot] = {}
128 self.data[plot] = {}
129
129
130 def shape(self, key):
130 def shape(self, key):
131 '''
131 '''
132 Get the shape of the one-element data for the given key
132 Get the shape of the one-element data for the given key
133 '''
133 '''
134
134
135 if len(self.data[key]):
135 if len(self.data[key]):
136 if 'spc' in key:
136 if 'spc' in key:
137 return self.data[key].shape
137 return self.data[key].shape
138 return self.data[key][self.__times[0]].shape
138 return self.data[key][self.__times[0]].shape
139 return (0,)
139 return (0,)
140
140
141 def update(self, dataOut, tm):
141 def update(self, dataOut, tm):
142 '''
142 '''
143 Update data object with new dataOut
143 Update data object with new dataOut
144 '''
144 '''
145
145
146 if tm in self.__times:
146 if tm in self.__times:
147 return
147 return
148
148
149 self.parameters = getattr(dataOut, 'parameters', [])
149 self.parameters = getattr(dataOut, 'parameters', [])
150 self.pairs = dataOut.pairsList
150 if hasattr(dataOut, 'pairsList'):
151 self.pairs = dataOut.pairsList
151 self.channels = dataOut.channelList
152 self.channels = dataOut.channelList
152 self.interval = dataOut.getTimeInterval()
153 self.interval = dataOut.getTimeInterval()
153 self.localtime = dataOut.useLocalTime
154 self.localtime = dataOut.useLocalTime
154 if 'spc' in self.plottypes or 'cspc' in self.plottypes:
155 if 'spc' in self.plottypes or 'cspc' in self.plottypes:
155 self.xrange = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
156 self.xrange = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
156 self.__heights.append(dataOut.heightList)
157 self.__heights.append(dataOut.heightList)
157 self.__all_heights.update(dataOut.heightList)
158 self.__all_heights.update(dataOut.heightList)
158 self.__times.append(tm)
159 self.__times.append(tm)
159
160
160 for plot in self.plottypes:
161 for plot in self.plottypes:
161 if plot == 'spc':
162 if plot == 'spc':
162 z = dataOut.data_spc/dataOut.normFactor
163 z = dataOut.data_spc/dataOut.normFactor
163 self.data[plot] = 10*numpy.log10(z)
164 self.data[plot] = 10*numpy.log10(z)
164 if plot == 'cspc':
165 if plot == 'cspc':
165 self.data[plot] = dataOut.data_cspc
166 self.data[plot] = dataOut.data_cspc
166 if plot == 'noise':
167 if plot == 'noise':
167 self.data[plot][tm] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
168 self.data[plot][tm] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
168 if plot == 'rti':
169 if plot == 'rti':
169 self.data[plot][tm] = dataOut.getPower()
170 self.data[plot][tm] = dataOut.getPower()
170 if plot == 'snr_db':
171 if plot == 'snr_db':
171 self.data['snr'][tm] = dataOut.data_SNR
172 self.data['snr'][tm] = dataOut.data_SNR
172 if plot == 'snr':
173 if plot == 'snr':
173 self.data[plot][tm] = 10*numpy.log10(dataOut.data_SNR)
174 self.data[plot][tm] = 10*numpy.log10(dataOut.data_SNR)
174 if plot == 'dop':
175 if plot == 'dop':
175 self.data[plot][tm] = 10*numpy.log10(dataOut.data_DOP)
176 self.data[plot][tm] = 10*numpy.log10(dataOut.data_DOP)
176 if plot == 'mean':
177 if plot == 'mean':
177 self.data[plot][tm] = dataOut.data_MEAN
178 self.data[plot][tm] = dataOut.data_MEAN
178 if plot == 'std':
179 if plot == 'std':
179 self.data[plot][tm] = dataOut.data_STD
180 self.data[plot][tm] = dataOut.data_STD
180 if plot == 'coh':
181 if plot == 'coh':
181 self.data[plot][tm] = dataOut.getCoherence()
182 self.data[plot][tm] = dataOut.getCoherence()
182 if plot == 'phase':
183 if plot == 'phase':
183 self.data[plot][tm] = dataOut.getCoherence(phase=True)
184 self.data[plot][tm] = dataOut.getCoherence(phase=True)
184 if plot == 'output':
185 if plot == 'output':
185 self.data[plot][tm] = dataOut.data_output
186 self.data[plot][tm] = dataOut.data_output
186 if plot == 'param':
187 if plot == 'param':
187 self.data[plot][tm] = dataOut.data_param
188 self.data[plot][tm] = dataOut.data_param
188
189
189 def normalize_heights(self):
190 def normalize_heights(self):
190 '''
191 '''
191 Ensure same-dimension of the data for different heighList
192 Ensure same-dimension of the data for different heighList
192 '''
193 '''
193
194
194 H = numpy.array(list(self.__all_heights))
195 H = numpy.array(list(self.__all_heights))
195 H.sort()
196 H.sort()
196 for key in self.data:
197 for key in self.data:
197 shape = self.shape(key)[:-1] + H.shape
198 shape = self.shape(key)[:-1] + H.shape
198 for tm, obj in self.data[key].items():
199 for tm, obj in self.data[key].items():
199 h = self.__heights[self.__times.index(tm)]
200 h = self.__heights[self.__times.index(tm)]
200 if H.size == h.size:
201 if H.size == h.size:
201 continue
202 continue
202 index = numpy.where(numpy.in1d(H, h))[0]
203 index = numpy.where(numpy.in1d(H, h))[0]
203 dummy = numpy.zeros(shape) + numpy.nan
204 dummy = numpy.zeros(shape) + numpy.nan
204 if len(shape) == 2:
205 if len(shape) == 2:
205 dummy[:, index] = obj
206 dummy[:, index] = obj
206 else:
207 else:
207 dummy[index] = obj
208 dummy[index] = obj
208 self.data[key][tm] = dummy
209 self.data[key][tm] = dummy
209
210
210 self.__heights = [H for tm in self.__times]
211 self.__heights = [H for tm in self.__times]
211
212
212 def jsonify(self, decimate=False):
213 def jsonify(self, decimate=False):
213 '''
214 '''
214 Convert data to json
215 Convert data to json
215 '''
216 '''
216
217
217 ret = {}
218 ret = {}
218 tm = self.times[-1]
219 tm = self.times[-1]
219
220
220 for key, value in self.data:
221 for key, value in self.data:
221 if key in ('spc', 'cspc'):
222 if key in ('spc', 'cspc'):
222 ret[key] = roundFloats(self.data[key].to_list())
223 ret[key] = roundFloats(self.data[key].to_list())
223 else:
224 else:
224 ret[key] = roundFloats(self.data[key][tm].to_list())
225 ret[key] = roundFloats(self.data[key][tm].to_list())
225
226
226 ret['timestamp'] = tm
227 ret['timestamp'] = tm
227 ret['interval'] = self.interval
228 ret['interval'] = self.interval
228
229
229 @property
230 @property
230 def times(self):
231 def times(self):
231 '''
232 '''
232 Return the list of times of the current data
233 Return the list of times of the current data
233 '''
234 '''
234
235
235 ret = numpy.array(self.__times)
236 ret = numpy.array(self.__times)
236 ret.sort()
237 ret.sort()
237 return ret
238 return ret
238
239
239 @property
240 @property
240 def heights(self):
241 def heights(self):
241 '''
242 '''
242 Return the list of heights of the current data
243 Return the list of heights of the current data
243 '''
244 '''
244
245
245 return numpy.array(self.__heights[-1])
246 return numpy.array(self.__heights[-1])
246
247
247 class PublishData(Operation):
248 class PublishData(Operation):
248 '''
249 '''
249 Operation to send data over zmq.
250 Operation to send data over zmq.
250 '''
251 '''
251
252
252 __attrs__ = ['host', 'port', 'delay', 'zeromq', 'mqtt', 'verbose']
253 __attrs__ = ['host', 'port', 'delay', 'zeromq', 'mqtt', 'verbose']
253
254
254 def __init__(self, **kwargs):
255 def __init__(self, **kwargs):
255 """Inicio."""
256 """Inicio."""
256 Operation.__init__(self, **kwargs)
257 Operation.__init__(self, **kwargs)
257 self.isConfig = False
258 self.isConfig = False
258 self.client = None
259 self.client = None
259 self.zeromq = None
260 self.zeromq = None
260 self.mqtt = None
261 self.mqtt = None
261
262
262 def on_disconnect(self, client, userdata, rc):
263 def on_disconnect(self, client, userdata, rc):
263 if rc != 0:
264 if rc != 0:
264 log.warning('Unexpected disconnection.')
265 log.warning('Unexpected disconnection.')
265 self.connect()
266 self.connect()
266
267
267 def connect(self):
268 def connect(self):
268 log.warning('trying to connect')
269 log.warning('trying to connect')
269 try:
270 try:
270 self.client.connect(
271 self.client.connect(
271 host=self.host,
272 host=self.host,
272 port=self.port,
273 port=self.port,
273 keepalive=60*10,
274 keepalive=60*10,
274 bind_address='')
275 bind_address='')
275 self.client.loop_start()
276 self.client.loop_start()
276 # self.client.publish(
277 # self.client.publish(
277 # self.topic + 'SETUP',
278 # self.topic + 'SETUP',
278 # json.dumps(setup),
279 # json.dumps(setup),
279 # retain=True
280 # retain=True
280 # )
281 # )
281 except:
282 except:
282 log.error('MQTT Conection error.')
283 log.error('MQTT Conection error.')
283 self.client = False
284 self.client = False
284
285
285 def setup(self, port=1883, username=None, password=None, clientId="user", zeromq=1, verbose=True, **kwargs):
286 def setup(self, port=1883, username=None, password=None, clientId="user", zeromq=1, verbose=True, **kwargs):
286 self.counter = 0
287 self.counter = 0
287 self.topic = kwargs.get('topic', 'schain')
288 self.topic = kwargs.get('topic', 'schain')
288 self.delay = kwargs.get('delay', 0)
289 self.delay = kwargs.get('delay', 0)
289 self.plottype = kwargs.get('plottype', 'spectra')
290 self.plottype = kwargs.get('plottype', 'spectra')
290 self.host = kwargs.get('host', "10.10.10.82")
291 self.host = kwargs.get('host', "10.10.10.82")
291 self.port = kwargs.get('port', 3000)
292 self.port = kwargs.get('port', 3000)
292 self.clientId = clientId
293 self.clientId = clientId
293 self.cnt = 0
294 self.cnt = 0
294 self.zeromq = zeromq
295 self.zeromq = zeromq
295 self.mqtt = kwargs.get('plottype', 0)
296 self.mqtt = kwargs.get('plottype', 0)
296 self.client = None
297 self.client = None
297 self.verbose = verbose
298 self.verbose = verbose
298 setup = []
299 setup = []
299 if mqtt is 1:
300 if mqtt is 1:
300 self.client = mqtt.Client(
301 self.client = mqtt.Client(
301 client_id=self.clientId + self.topic + 'SCHAIN',
302 client_id=self.clientId + self.topic + 'SCHAIN',
302 clean_session=True)
303 clean_session=True)
303 self.client.on_disconnect = self.on_disconnect
304 self.client.on_disconnect = self.on_disconnect
304 self.connect()
305 self.connect()
305 for plot in self.plottype:
306 for plot in self.plottype:
306 setup.append({
307 setup.append({
307 'plot': plot,
308 'plot': plot,
308 'topic': self.topic + plot,
309 'topic': self.topic + plot,
309 'title': getattr(self, plot + '_' + 'title', False),
310 'title': getattr(self, plot + '_' + 'title', False),
310 'xlabel': getattr(self, plot + '_' + 'xlabel', False),
311 'xlabel': getattr(self, plot + '_' + 'xlabel', False),
311 'ylabel': getattr(self, plot + '_' + 'ylabel', False),
312 'ylabel': getattr(self, plot + '_' + 'ylabel', False),
312 'xrange': getattr(self, plot + '_' + 'xrange', False),
313 'xrange': getattr(self, plot + '_' + 'xrange', False),
313 'yrange': getattr(self, plot + '_' + 'yrange', False),
314 'yrange': getattr(self, plot + '_' + 'yrange', False),
314 'zrange': getattr(self, plot + '_' + 'zrange', False),
315 'zrange': getattr(self, plot + '_' + 'zrange', False),
315 })
316 })
316 if zeromq is 1:
317 if zeromq is 1:
317 context = zmq.Context()
318 context = zmq.Context()
318 self.zmq_socket = context.socket(zmq.PUSH)
319 self.zmq_socket = context.socket(zmq.PUSH)
319 server = kwargs.get('server', 'zmq.pipe')
320 server = kwargs.get('server', 'zmq.pipe')
320
321
321 if 'tcp://' in server:
322 if 'tcp://' in server:
322 address = server
323 address = server
323 else:
324 else:
324 address = 'ipc:///tmp/%s' % server
325 address = 'ipc:///tmp/%s' % server
325
326
326 self.zmq_socket.connect(address)
327 self.zmq_socket.connect(address)
327 time.sleep(1)
328 time.sleep(1)
328
329
329
330
330 def publish_data(self):
331 def publish_data(self):
331 self.dataOut.finished = False
332 self.dataOut.finished = False
332 if self.mqtt is 1:
333 if self.mqtt is 1:
333 yData = self.dataOut.heightList[:2].tolist()
334 yData = self.dataOut.heightList[:2].tolist()
334 if self.plottype == 'spectra':
335 if self.plottype == 'spectra':
335 data = getattr(self.dataOut, 'data_spc')
336 data = getattr(self.dataOut, 'data_spc')
336 z = data/self.dataOut.normFactor
337 z = data/self.dataOut.normFactor
337 zdB = 10*numpy.log10(z)
338 zdB = 10*numpy.log10(z)
338 xlen, ylen = zdB[0].shape
339 xlen, ylen = zdB[0].shape
339 dx = int(xlen/MAXNUMX) + 1
340 dx = int(xlen/MAXNUMX) + 1
340 dy = int(ylen/MAXNUMY) + 1
341 dy = int(ylen/MAXNUMY) + 1
341 Z = [0 for i in self.dataOut.channelList]
342 Z = [0 for i in self.dataOut.channelList]
342 for i in self.dataOut.channelList:
343 for i in self.dataOut.channelList:
343 Z[i] = zdB[i][::dx, ::dy].tolist()
344 Z[i] = zdB[i][::dx, ::dy].tolist()
344 payload = {
345 payload = {
345 'timestamp': self.dataOut.utctime,
346 'timestamp': self.dataOut.utctime,
346 'data': roundFloats(Z),
347 'data': roundFloats(Z),
347 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
348 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
348 'interval': self.dataOut.getTimeInterval(),
349 'interval': self.dataOut.getTimeInterval(),
349 'type': self.plottype,
350 'type': self.plottype,
350 'yData': yData
351 'yData': yData
351 }
352 }
352
353
353 elif self.plottype in ('rti', 'power'):
354 elif self.plottype in ('rti', 'power'):
354 data = getattr(self.dataOut, 'data_spc')
355 data = getattr(self.dataOut, 'data_spc')
355 z = data/self.dataOut.normFactor
356 z = data/self.dataOut.normFactor
356 avg = numpy.average(z, axis=1)
357 avg = numpy.average(z, axis=1)
357 avgdB = 10*numpy.log10(avg)
358 avgdB = 10*numpy.log10(avg)
358 xlen, ylen = z[0].shape
359 xlen, ylen = z[0].shape
359 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
360 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
360 AVG = [0 for i in self.dataOut.channelList]
361 AVG = [0 for i in self.dataOut.channelList]
361 for i in self.dataOut.channelList:
362 for i in self.dataOut.channelList:
362 AVG[i] = avgdB[i][::dy].tolist()
363 AVG[i] = avgdB[i][::dy].tolist()
363 payload = {
364 payload = {
364 'timestamp': self.dataOut.utctime,
365 'timestamp': self.dataOut.utctime,
365 'data': roundFloats(AVG),
366 'data': roundFloats(AVG),
366 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
367 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
367 'interval': self.dataOut.getTimeInterval(),
368 'interval': self.dataOut.getTimeInterval(),
368 'type': self.plottype,
369 'type': self.plottype,
369 'yData': yData
370 'yData': yData
370 }
371 }
371 elif self.plottype == 'noise':
372 elif self.plottype == 'noise':
372 noise = self.dataOut.getNoise()/self.dataOut.normFactor
373 noise = self.dataOut.getNoise()/self.dataOut.normFactor
373 noisedB = 10*numpy.log10(noise)
374 noisedB = 10*numpy.log10(noise)
374 payload = {
375 payload = {
375 'timestamp': self.dataOut.utctime,
376 'timestamp': self.dataOut.utctime,
376 'data': roundFloats(noisedB.reshape(-1, 1).tolist()),
377 'data': roundFloats(noisedB.reshape(-1, 1).tolist()),
377 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
378 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
378 'interval': self.dataOut.getTimeInterval(),
379 'interval': self.dataOut.getTimeInterval(),
379 'type': self.plottype,
380 'type': self.plottype,
380 'yData': yData
381 'yData': yData
381 }
382 }
382 elif self.plottype == 'snr':
383 elif self.plottype == 'snr':
383 data = getattr(self.dataOut, 'data_SNR')
384 data = getattr(self.dataOut, 'data_SNR')
384 avgdB = 10*numpy.log10(data)
385 avgdB = 10*numpy.log10(data)
385
386
386 ylen = data[0].size
387 ylen = data[0].size
387 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
388 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
388 AVG = [0 for i in self.dataOut.channelList]
389 AVG = [0 for i in self.dataOut.channelList]
389 for i in self.dataOut.channelList:
390 for i in self.dataOut.channelList:
390 AVG[i] = avgdB[i][::dy].tolist()
391 AVG[i] = avgdB[i][::dy].tolist()
391 payload = {
392 payload = {
392 'timestamp': self.dataOut.utctime,
393 'timestamp': self.dataOut.utctime,
393 'data': roundFloats(AVG),
394 'data': roundFloats(AVG),
394 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
395 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
395 'type': self.plottype,
396 'type': self.plottype,
396 'yData': yData
397 'yData': yData
397 }
398 }
398 else:
399 else:
399 print "Tipo de grafico invalido"
400 print "Tipo de grafico invalido"
400 payload = {
401 payload = {
401 'data': 'None',
402 'data': 'None',
402 'timestamp': 'None',
403 'timestamp': 'None',
403 'type': None
404 'type': None
404 }
405 }
405
406
406 self.client.publish(self.topic + self.plottype, json.dumps(payload), qos=0)
407 self.client.publish(self.topic + self.plottype, json.dumps(payload), qos=0)
407
408
408 if self.zeromq is 1:
409 if self.zeromq is 1:
409 if self.verbose:
410 if self.verbose:
410 log.log(
411 log.log(
411 'Sending {} - {}'.format(self.dataOut.type, self.dataOut.datatime),
412 'Sending {} - {}'.format(self.dataOut.type, self.dataOut.datatime),
412 self.name
413 self.name
413 )
414 )
414 self.zmq_socket.send_pyobj(self.dataOut)
415 self.zmq_socket.send_pyobj(self.dataOut)
415
416
416 def run(self, dataOut, **kwargs):
417 def run(self, dataOut, **kwargs):
417 self.dataOut = dataOut
418 self.dataOut = dataOut
418 if not self.isConfig:
419 if not self.isConfig:
419 self.setup(**kwargs)
420 self.setup(**kwargs)
420 self.isConfig = True
421 self.isConfig = True
421
422
422 self.publish_data()
423 self.publish_data()
423 time.sleep(self.delay)
424 time.sleep(self.delay)
424
425
425 def close(self):
426 def close(self):
426 if self.zeromq is 1:
427 if self.zeromq is 1:
427 self.dataOut.finished = True
428 self.dataOut.finished = True
428 self.zmq_socket.send_pyobj(self.dataOut)
429 self.zmq_socket.send_pyobj(self.dataOut)
429 time.sleep(0.1)
430 time.sleep(0.1)
430 self.zmq_socket.close()
431 self.zmq_socket.close()
431 if self.client:
432 if self.client:
432 self.client.loop_stop()
433 self.client.loop_stop()
433 self.client.disconnect()
434 self.client.disconnect()
434
435
435
436
436 class ReceiverData(ProcessingUnit):
437 class ReceiverData(ProcessingUnit):
437
438
438 __attrs__ = ['server']
439 __attrs__ = ['server']
439
440
440 def __init__(self, **kwargs):
441 def __init__(self, **kwargs):
441
442
442 ProcessingUnit.__init__(self, **kwargs)
443 ProcessingUnit.__init__(self, **kwargs)
443
444
444 self.isConfig = False
445 self.isConfig = False
445 server = kwargs.get('server', 'zmq.pipe')
446 server = kwargs.get('server', 'zmq.pipe')
446 if 'tcp://' in server:
447 if 'tcp://' in server:
447 address = server
448 address = server
448 else:
449 else:
449 address = 'ipc:///tmp/%s' % server
450 address = 'ipc:///tmp/%s' % server
450
451
451 self.address = address
452 self.address = address
452 self.dataOut = JROData()
453 self.dataOut = JROData()
453
454
454 def setup(self):
455 def setup(self):
455
456
456 self.context = zmq.Context()
457 self.context = zmq.Context()
457 self.receiver = self.context.socket(zmq.PULL)
458 self.receiver = self.context.socket(zmq.PULL)
458 self.receiver.bind(self.address)
459 self.receiver.bind(self.address)
459 time.sleep(0.5)
460 time.sleep(0.5)
460 log.success('ReceiverData from {}'.format(self.address))
461 log.success('ReceiverData from {}'.format(self.address))
461
462
462
463
463 def run(self):
464 def run(self):
464
465
465 if not self.isConfig:
466 if not self.isConfig:
466 self.setup()
467 self.setup()
467 self.isConfig = True
468 self.isConfig = True
468
469
469 self.dataOut = self.receiver.recv_pyobj()
470 self.dataOut = self.receiver.recv_pyobj()
470 log.log('{} - {}'.format(self.dataOut.type,
471 log.log('{} - {}'.format(self.dataOut.type,
471 self.dataOut.datatime.ctime(),),
472 self.dataOut.datatime.ctime(),),
472 'Receiving')
473 'Receiving')
473
474
474
475
475 class PlotterReceiver(ProcessingUnit, Process):
476 class PlotterReceiver(ProcessingUnit, Process):
476
477
477 throttle_value = 5
478 throttle_value = 5
478 __attrs__ = ['server', 'plottypes', 'realtime', 'localtime', 'throttle']
479 __attrs__ = ['server', 'plottypes', 'realtime', 'localtime', 'throttle']
479
480
480 def __init__(self, **kwargs):
481 def __init__(self, **kwargs):
481
482
482 ProcessingUnit.__init__(self, **kwargs)
483 ProcessingUnit.__init__(self, **kwargs)
483 Process.__init__(self)
484 Process.__init__(self)
484 self.mp = False
485 self.mp = False
485 self.isConfig = False
486 self.isConfig = False
486 self.isWebConfig = False
487 self.isWebConfig = False
487 self.connections = 0
488 self.connections = 0
488 server = kwargs.get('server', 'zmq.pipe')
489 server = kwargs.get('server', 'zmq.pipe')
489 plot_server = kwargs.get('plot_server', 'zmq.web')
490 plot_server = kwargs.get('plot_server', 'zmq.web')
490 if 'tcp://' in server:
491 if 'tcp://' in server:
491 address = server
492 address = server
492 else:
493 else:
493 address = 'ipc:///tmp/%s' % server
494 address = 'ipc:///tmp/%s' % server
494
495
495 if 'tcp://' in plot_server:
496 if 'tcp://' in plot_server:
496 plot_address = plot_server
497 plot_address = plot_server
497 else:
498 else:
498 plot_address = 'ipc:///tmp/%s' % plot_server
499 plot_address = 'ipc:///tmp/%s' % plot_server
499
500
500 self.address = address
501 self.address = address
501 self.plot_address = plot_address
502 self.plot_address = plot_address
502 self.plottypes = [s.strip() for s in kwargs.get('plottypes', 'rti').split(',')]
503 self.plottypes = [s.strip() for s in kwargs.get('plottypes', '').split(',') if s]
503 self.realtime = kwargs.get('realtime', False)
504 self.realtime = kwargs.get('realtime', False)
504 self.localtime = kwargs.get('localtime', True)
505 self.localtime = kwargs.get('localtime', True)
505 self.throttle_value = kwargs.get('throttle', 5)
506 self.throttle_value = kwargs.get('throttle', 5)
506 self.sendData = self.initThrottle(self.throttle_value)
507 self.sendData = self.initThrottle(self.throttle_value)
507 self.dates = []
508 self.dates = []
508 self.setup()
509 self.setup()
509
510
510 def setup(self):
511 def setup(self):
511
512
512 self.data = Data(self.plottypes, self.throttle_value)
513 self.data = Data(self.plottypes, self.throttle_value)
513 self.isConfig = True
514 self.isConfig = True
514
515
515 def event_monitor(self, monitor):
516 def event_monitor(self, monitor):
516
517
517 events = {}
518 events = {}
518
519
519 for name in dir(zmq):
520 for name in dir(zmq):
520 if name.startswith('EVENT_'):
521 if name.startswith('EVENT_'):
521 value = getattr(zmq, name)
522 value = getattr(zmq, name)
522 events[value] = name
523 events[value] = name
523
524
524 while monitor.poll():
525 while monitor.poll():
525 evt = recv_monitor_message(monitor)
526 evt = recv_monitor_message(monitor)
526 if evt['event'] == 32:
527 if evt['event'] == 32:
527 self.connections += 1
528 self.connections += 1
528 if evt['event'] == 512:
529 if evt['event'] == 512:
529 pass
530 pass
530
531
531 evt.update({'description': events[evt['event']]})
532 evt.update({'description': events[evt['event']]})
532
533
533 if evt['event'] == zmq.EVENT_MONITOR_STOPPED:
534 if evt['event'] == zmq.EVENT_MONITOR_STOPPED:
534 break
535 break
535 monitor.close()
536 monitor.close()
536 print('event monitor thread done!')
537 print('event monitor thread done!')
537
538
538 def initThrottle(self, throttle_value):
539 def initThrottle(self, throttle_value):
539
540
540 @throttle(seconds=throttle_value)
541 @throttle(seconds=throttle_value)
541 def sendDataThrottled(fn_sender, data):
542 def sendDataThrottled(fn_sender, data):
542 fn_sender(data)
543 fn_sender(data)
543
544
544 return sendDataThrottled
545 return sendDataThrottled
545
546
546 def send(self, data):
547 def send(self, data):
547 log.success('Sending {}'.format(data), self.name)
548 log.success('Sending {}'.format(data), self.name)
548 self.sender.send_pyobj(data)
549 self.sender.send_pyobj(data)
549
550
550 def run(self):
551 def run(self):
551
552
552 log.success(
553 log.success(
553 'Starting from {}'.format(self.address),
554 'Starting from {}'.format(self.address),
554 self.name
555 self.name
555 )
556 )
556
557
557 self.context = zmq.Context()
558 self.context = zmq.Context()
558 self.receiver = self.context.socket(zmq.PULL)
559 self.receiver = self.context.socket(zmq.PULL)
559 self.receiver.bind(self.address)
560 self.receiver.bind(self.address)
560 monitor = self.receiver.get_monitor_socket()
561 monitor = self.receiver.get_monitor_socket()
561 self.sender = self.context.socket(zmq.PUB)
562 self.sender = self.context.socket(zmq.PUB)
562 if self.realtime:
563 if self.realtime:
563 self.sender_web = self.context.socket(zmq.PUB)
564 self.sender_web = self.context.socket(zmq.PUB)
564 self.sender_web.connect(self.plot_address)
565 self.sender_web.connect(self.plot_address)
565 time.sleep(1)
566 time.sleep(1)
566
567
567 if 'server' in self.kwargs:
568 if 'server' in self.kwargs:
568 self.sender.bind("ipc:///tmp/{}.plots".format(self.kwargs['server']))
569 self.sender.bind("ipc:///tmp/{}.plots".format(self.kwargs['server']))
569 else:
570 else:
570 self.sender.bind("ipc:///tmp/zmq.plots")
571 self.sender.bind("ipc:///tmp/zmq.plots")
571
572
572 time.sleep(2)
573 time.sleep(2)
573
574
574 t = Thread(target=self.event_monitor, args=(monitor,))
575 t = Thread(target=self.event_monitor, args=(monitor,))
575 t.start()
576 t.start()
576
577
577 while True:
578 while True:
578 dataOut = self.receiver.recv_pyobj()
579 dataOut = self.receiver.recv_pyobj()
579 if not dataOut.flagNoData:
580 if not dataOut.flagNoData:
580 if dataOut.type == 'Parameters':
581 if dataOut.type == 'Parameters':
581 tm = dataOut.utctimeInit
582 tm = dataOut.utctimeInit
582 else:
583 else:
583 tm = dataOut.utctime
584 tm = dataOut.utctime
584 if dataOut.useLocalTime:
585 if dataOut.useLocalTime:
585 if not self.localtime:
586 if not self.localtime:
586 tm += time.timezone
587 tm += time.timezone
587 dt = datetime.datetime.fromtimestamp(tm).date()
588 dt = datetime.datetime.fromtimestamp(tm).date()
588 else:
589 else:
589 if self.localtime:
590 if self.localtime:
590 tm -= time.timezone
591 tm -= time.timezone
591 dt = datetime.datetime.utcfromtimestamp(tm).date()
592 dt = datetime.datetime.utcfromtimestamp(tm).date()
592 coerce = False
593 coerce = False
593 if dt not in self.dates:
594 if dt not in self.dates:
594 if self.data:
595 if self.data:
595 self.data.ended = True
596 self.data.ended = True
596 self.send(self.data)
597 self.send(self.data)
597 coerce = True
598 coerce = True
598 self.data.setup()
599 self.data.setup()
599 self.dates.append(dt)
600 self.dates.append(dt)
600
601
601 self.data.update(dataOut, tm)
602 self.data.update(dataOut, tm)
602
603
603 if dataOut.finished is True:
604 if dataOut.finished is True:
604 self.connections -= 1
605 self.connections -= 1
605 if self.connections == 0 and dt in self.dates:
606 if self.connections == 0 and dt in self.dates:
606 self.data.ended = True
607 self.data.ended = True
607 self.send(self.data)
608 self.send(self.data)
608 self.data.setup()
609 self.data.setup()
609 else:
610 else:
610 if self.realtime:
611 if self.realtime:
611 self.send(self.data)
612 self.send(self.data)
612 # self.sender_web.send_string(self.data.jsonify())
613 # self.sender_web.send_string(self.data.jsonify())
613 else:
614 else:
614 self.sendData(self.send, self.data, coerce=coerce)
615 self.sendData(self.send, self.data, coerce=coerce)
615 coerce = False
616 coerce = False
616
617
617 return
618 return
618
619
619 def sendToWeb(self):
620 def sendToWeb(self):
620
621
621 if not self.isWebConfig:
622 if not self.isWebConfig:
622 context = zmq.Context()
623 context = zmq.Context()
623 sender_web_config = context.socket(zmq.PUB)
624 sender_web_config = context.socket(zmq.PUB)
624 if 'tcp://' in self.plot_address:
625 if 'tcp://' in self.plot_address:
625 dum, address, port = self.plot_address.split(':')
626 dum, address, port = self.plot_address.split(':')
626 conf_address = '{}:{}:{}'.format(dum, address, int(port)+1)
627 conf_address = '{}:{}:{}'.format(dum, address, int(port)+1)
627 else:
628 else:
628 conf_address = self.plot_address + '.config'
629 conf_address = self.plot_address + '.config'
629 sender_web_config.bind(conf_address)
630 sender_web_config.bind(conf_address)
630 time.sleep(1)
631 time.sleep(1)
631 for kwargs in self.operationKwargs.values():
632 for kwargs in self.operationKwargs.values():
632 if 'plot' in kwargs:
633 if 'plot' in kwargs:
633 log.success('[Sending] Config data to web for {}'.format(kwargs['code'].upper()))
634 log.success('[Sending] Config data to web for {}'.format(kwargs['code'].upper()))
634 sender_web_config.send_string(json.dumps(kwargs))
635 sender_web_config.send_string(json.dumps(kwargs))
635 self.isWebConfig = True
636 self.isWebConfig = True
@@ -1,69 +1,69
1 '''
1 '''
2 Created on Jul 16, 2014
2 Created on Jul 16, 2014
3
3
4 @author: Miguel Urco
4 @author: Miguel Urco
5 '''
5 '''
6
6
7 import os
7 import os
8 from setuptools import setup, Extension
8 from setuptools import setup, Extension
9 from setuptools.command.build_ext import build_ext as _build_ext
9 from setuptools.command.build_ext import build_ext as _build_ext
10 from schainpy import __version__
10 from schainpy import __version__
11
11
12 class build_ext(_build_ext):
12 class build_ext(_build_ext):
13 def finalize_options(self):
13 def finalize_options(self):
14 _build_ext.finalize_options(self)
14 _build_ext.finalize_options(self)
15 # Prevent numpy from thinking it is still in its setup process:
15 # Prevent numpy from thinking it is still in its setup process:
16 __builtins__.__NUMPY_SETUP__ = False
16 __builtins__.__NUMPY_SETUP__ = False
17 import numpy
17 import numpy
18 self.include_dirs.append(numpy.get_include())
18 self.include_dirs.append(numpy.get_include())
19
19
20 setup(name="schainpy",
20 setup(name = "schainpy",
21 version=__version__,
21 version = __version__,
22 description="Python tools to read, write and process Jicamarca data",
22 description = "Python tools to read, write and process Jicamarca data",
23 author="Miguel Urco",
23 author = "Miguel Urco",
24 author_email="miguel.urco@jro.igp.gob.pe",
24 author_email = "miguel.urco@jro.igp.gob.pe",
25 url="http://jro.igp.gob.pe",
25 url = "http://jro.igp.gob.pe",
26 packages={'schainpy',
26 packages = {'schainpy',
27 'schainpy.model',
27 'schainpy.model',
28 'schainpy.model.data',
28 'schainpy.model.data',
29 'schainpy.model.graphics',
29 'schainpy.model.graphics',
30 'schainpy.model.io',
30 'schainpy.model.io',
31 'schainpy.model.proc',
31 'schainpy.model.proc',
32 'schainpy.model.serializer',
32 'schainpy.model.serializer',
33 'schainpy.model.utils',
33 'schainpy.model.utils',
34 'schainpy.utils',
34 'schainpy.utils',
35 'schainpy.gui',
35 'schainpy.gui',
36 'schainpy.gui.figures',
36 'schainpy.gui.figures',
37 'schainpy.gui.viewcontroller',
37 'schainpy.gui.viewcontroller',
38 'schainpy.gui.viewer',
38 'schainpy.gui.viewer',
39 'schainpy.gui.viewer.windows'},
39 'schainpy.gui.viewer.windows',
40 ext_package='schainpy',
40 'schainpy.cli'},
41 py_modules=[''],
41 ext_package = 'schainpy',
42 package_data={'': ['schain.conf.template'],
42 package_data = {'': ['schain.conf.template'],
43 'schainpy.gui.figures': ['*.png', '*.jpg'],
43 'schainpy.gui.figures': ['*.png', '*.jpg'],
44 },
44 },
45 include_package_data=False,
45 include_package_data = False,
46 scripts=['schainpy/gui/schainGUI'],
46 scripts = ['schainpy/gui/schainGUI'],
47 ext_modules=[
47 ext_modules = [
48 Extension("cSchain", ["schainpy/model/proc/extensions.c"]
48 Extension("cSchain", ["schainpy/model/proc/extensions.c"])
49 )],
49 ],
50 entry_points={
50 entry_points = {
51 'console_scripts': [
51 'console_scripts': [
52 'schain = schaincli.cli:main',
52 'schain = schainpy.cli.cli:main',
53 ],
53 ],
54 },
54 },
55 cmdclass={'build_ext': build_ext},
55 cmdclass = {'build_ext': build_ext},
56 setup_requires=["numpy >= 1.11.2"],
56 setup_requires = ["numpy >= 1.11.2"],
57 install_requires=[
57 install_requires = [
58 "scipy >= 0.14.0",
58 "scipy >= 0.14.0",
59 "h5py >= 2.2.1",
59 "h5py >= 2.2.1",
60 "matplotlib >= 2.0.0",
60 "matplotlib >= 2.0.0",
61 "pyfits >= 3.4",
61 "pyfits >= 3.4",
62 "paramiko >= 2.1.2",
62 "paramiko >= 2.1.2",
63 "paho-mqtt >= 1.2",
63 "paho-mqtt >= 1.2",
64 "zmq",
64 "zmq",
65 "fuzzywuzzy",
65 "fuzzywuzzy",
66 "click",
66 "click",
67 "python-Levenshtein"
67 "python-Levenshtein"
68 ],
68 ],
69 )
69 )
General Comments 0
You need to be logged in to leave comments. Login now