##// END OF EJS Templates
Set default alarms to none
Juan C. Espinoza -
r1163:897c7e98cc47
parent child
Show More
@@ -1,1337 +1,1342
1 '''
1 '''
2 Created on September , 2012
2 Created on September , 2012
3 @author:
3 @author:
4 '''
4 '''
5
5
6 import sys
6 import sys
7 import ast
7 import ast
8 import datetime
8 import datetime
9 import traceback
9 import traceback
10 import math
10 import math
11 import time
11 import time
12 from multiprocessing import Process, cpu_count
12 from multiprocessing import Process, cpu_count
13
13
14 from xml.etree.ElementTree import ElementTree, Element, SubElement, tostring
14 from xml.etree.ElementTree import ElementTree, Element, SubElement, tostring
15 from xml.dom import minidom
15 from xml.dom import minidom
16
16
17 import schainpy
17 import schainpy
18 from schainpy.admin import Alarm, SchainWarning
18 from schainpy.admin import Alarm, SchainWarning
19 from schainpy.model import *
19 from schainpy.model import *
20 from schainpy.utils import log
20 from schainpy.utils import log
21
21
22 DTYPES = {
22 DTYPES = {
23 'Voltage': '.r',
23 'Voltage': '.r',
24 'Spectra': '.pdata'
24 'Spectra': '.pdata'
25 }
25 }
26
26
27
27
28 def MPProject(project, n=cpu_count()):
28 def MPProject(project, n=cpu_count()):
29 '''
29 '''
30 Project wrapper to run schain in n processes
30 Project wrapper to run schain in n processes
31 '''
31 '''
32
32
33 rconf = project.getReadUnitObj()
33 rconf = project.getReadUnitObj()
34 op = rconf.getOperationObj('run')
34 op = rconf.getOperationObj('run')
35 dt1 = op.getParameterValue('startDate')
35 dt1 = op.getParameterValue('startDate')
36 dt2 = op.getParameterValue('endDate')
36 dt2 = op.getParameterValue('endDate')
37 tm1 = op.getParameterValue('startTime')
37 tm1 = op.getParameterValue('startTime')
38 tm2 = op.getParameterValue('endTime')
38 tm2 = op.getParameterValue('endTime')
39 days = (dt2 - dt1).days
39 days = (dt2 - dt1).days
40
40
41 for day in range(days + 1):
41 for day in range(days + 1):
42 skip = 0
42 skip = 0
43 cursor = 0
43 cursor = 0
44 processes = []
44 processes = []
45 dt = dt1 + datetime.timedelta(day)
45 dt = dt1 + datetime.timedelta(day)
46 dt_str = dt.strftime('%Y/%m/%d')
46 dt_str = dt.strftime('%Y/%m/%d')
47 reader = JRODataReader()
47 reader = JRODataReader()
48 paths, files = reader.searchFilesOffLine(path=rconf.path,
48 paths, files = reader.searchFilesOffLine(path=rconf.path,
49 startDate=dt,
49 startDate=dt,
50 endDate=dt,
50 endDate=dt,
51 startTime=tm1,
51 startTime=tm1,
52 endTime=tm2,
52 endTime=tm2,
53 ext=DTYPES[rconf.datatype])
53 ext=DTYPES[rconf.datatype])
54 nFiles = len(files)
54 nFiles = len(files)
55 if nFiles == 0:
55 if nFiles == 0:
56 continue
56 continue
57 skip = int(math.ceil(nFiles / n))
57 skip = int(math.ceil(nFiles / n))
58 while nFiles > cursor * skip:
58 while nFiles > cursor * skip:
59 rconf.update(startDate=dt_str, endDate=dt_str, cursor=cursor,
59 rconf.update(startDate=dt_str, endDate=dt_str, cursor=cursor,
60 skip=skip)
60 skip=skip)
61 p = project.clone()
61 p = project.clone()
62 p.start()
62 p.start()
63 processes.append(p)
63 processes.append(p)
64 cursor += 1
64 cursor += 1
65
65
66 def beforeExit(exctype, value, trace):
66 def beforeExit(exctype, value, trace):
67 for process in processes:
67 for process in processes:
68 process.terminate()
68 process.terminate()
69 process.join()
69 process.join()
70 print traceback.print_tb(trace)
70 print traceback.print_tb(trace)
71
71
72 sys.excepthook = beforeExit
72 sys.excepthook = beforeExit
73
73
74 for process in processes:
74 for process in processes:
75 process.join()
75 process.join()
76 process.terminate()
76 process.terminate()
77
77
78 time.sleep(3)
78 time.sleep(3)
79
79
80
80
81 class ParameterConf():
81 class ParameterConf():
82
82
83 id = None
83 id = None
84 name = None
84 name = None
85 value = None
85 value = None
86 format = None
86 format = None
87
87
88 __formated_value = None
88 __formated_value = None
89
89
90 ELEMENTNAME = 'Parameter'
90 ELEMENTNAME = 'Parameter'
91
91
92 def __init__(self):
92 def __init__(self):
93
93
94 self.format = 'str'
94 self.format = 'str'
95
95
96 def getElementName(self):
96 def getElementName(self):
97
97
98 return self.ELEMENTNAME
98 return self.ELEMENTNAME
99
99
100 def getValue(self):
100 def getValue(self):
101
101
102 value = self.value
102 value = self.value
103 format = self.format
103 format = self.format
104
104
105 if self.__formated_value != None:
105 if self.__formated_value != None:
106
106
107 return self.__formated_value
107 return self.__formated_value
108
108
109 if format == 'obj':
109 if format == 'obj':
110 return value
110 return value
111
111
112 if format == 'str':
112 if format == 'str':
113 self.__formated_value = str(value)
113 self.__formated_value = str(value)
114 return self.__formated_value
114 return self.__formated_value
115
115
116 if value == '':
116 if value == '':
117 raise ValueError, '%s: This parameter value is empty' % self.name
117 raise ValueError, '%s: This parameter value is empty' % self.name
118
118
119 if format == 'list':
119 if format == 'list':
120 strList = value.split(',')
120 strList = value.split(',')
121
121
122 self.__formated_value = strList
122 self.__formated_value = strList
123
123
124 return self.__formated_value
124 return self.__formated_value
125
125
126 if format == 'intlist':
126 if format == 'intlist':
127 '''
127 '''
128 Example:
128 Example:
129 value = (0,1,2)
129 value = (0,1,2)
130 '''
130 '''
131
131
132 new_value = ast.literal_eval(value)
132 new_value = ast.literal_eval(value)
133
133
134 if type(new_value) not in (tuple, list):
134 if type(new_value) not in (tuple, list):
135 new_value = [int(new_value)]
135 new_value = [int(new_value)]
136
136
137 self.__formated_value = new_value
137 self.__formated_value = new_value
138
138
139 return self.__formated_value
139 return self.__formated_value
140
140
141 if format == 'floatlist':
141 if format == 'floatlist':
142 '''
142 '''
143 Example:
143 Example:
144 value = (0.5, 1.4, 2.7)
144 value = (0.5, 1.4, 2.7)
145 '''
145 '''
146
146
147 new_value = ast.literal_eval(value)
147 new_value = ast.literal_eval(value)
148
148
149 if type(new_value) not in (tuple, list):
149 if type(new_value) not in (tuple, list):
150 new_value = [float(new_value)]
150 new_value = [float(new_value)]
151
151
152 self.__formated_value = new_value
152 self.__formated_value = new_value
153
153
154 return self.__formated_value
154 return self.__formated_value
155
155
156 if format == 'date':
156 if format == 'date':
157 strList = value.split('/')
157 strList = value.split('/')
158 intList = [int(x) for x in strList]
158 intList = [int(x) for x in strList]
159 date = datetime.date(intList[0], intList[1], intList[2])
159 date = datetime.date(intList[0], intList[1], intList[2])
160
160
161 self.__formated_value = date
161 self.__formated_value = date
162
162
163 return self.__formated_value
163 return self.__formated_value
164
164
165 if format == 'time':
165 if format == 'time':
166 strList = value.split(':')
166 strList = value.split(':')
167 intList = [int(x) for x in strList]
167 intList = [int(x) for x in strList]
168 time = datetime.time(intList[0], intList[1], intList[2])
168 time = datetime.time(intList[0], intList[1], intList[2])
169
169
170 self.__formated_value = time
170 self.__formated_value = time
171
171
172 return self.__formated_value
172 return self.__formated_value
173
173
174 if format == 'pairslist':
174 if format == 'pairslist':
175 '''
175 '''
176 Example:
176 Example:
177 value = (0,1),(1,2)
177 value = (0,1),(1,2)
178 '''
178 '''
179
179
180 new_value = ast.literal_eval(value)
180 new_value = ast.literal_eval(value)
181
181
182 if type(new_value) not in (tuple, list):
182 if type(new_value) not in (tuple, list):
183 raise ValueError, '%s has to be a tuple or list of pairs' % value
183 raise ValueError, '%s has to be a tuple or list of pairs' % value
184
184
185 if type(new_value[0]) not in (tuple, list):
185 if type(new_value[0]) not in (tuple, list):
186 if len(new_value) != 2:
186 if len(new_value) != 2:
187 raise ValueError, '%s has to be a tuple or list of pairs' % value
187 raise ValueError, '%s has to be a tuple or list of pairs' % value
188 new_value = [new_value]
188 new_value = [new_value]
189
189
190 for thisPair in new_value:
190 for thisPair in new_value:
191 if len(thisPair) != 2:
191 if len(thisPair) != 2:
192 raise ValueError, '%s has to be a tuple or list of pairs' % value
192 raise ValueError, '%s has to be a tuple or list of pairs' % value
193
193
194 self.__formated_value = new_value
194 self.__formated_value = new_value
195
195
196 return self.__formated_value
196 return self.__formated_value
197
197
198 if format == 'multilist':
198 if format == 'multilist':
199 '''
199 '''
200 Example:
200 Example:
201 value = (0,1,2),(3,4,5)
201 value = (0,1,2),(3,4,5)
202 '''
202 '''
203 multiList = ast.literal_eval(value)
203 multiList = ast.literal_eval(value)
204
204
205 if type(multiList[0]) == int:
205 if type(multiList[0]) == int:
206 multiList = ast.literal_eval('(' + value + ')')
206 multiList = ast.literal_eval('(' + value + ')')
207
207
208 self.__formated_value = multiList
208 self.__formated_value = multiList
209
209
210 return self.__formated_value
210 return self.__formated_value
211
211
212 if format == 'bool':
212 if format == 'bool':
213 value = int(value)
213 value = int(value)
214
214
215 if format == 'int':
215 if format == 'int':
216 value = float(value)
216 value = float(value)
217
217
218 format_func = eval(format)
218 format_func = eval(format)
219
219
220 self.__formated_value = format_func(value)
220 self.__formated_value = format_func(value)
221
221
222 return self.__formated_value
222 return self.__formated_value
223
223
224 def updateId(self, new_id):
224 def updateId(self, new_id):
225
225
226 self.id = str(new_id)
226 self.id = str(new_id)
227
227
228 def setup(self, id, name, value, format='str'):
228 def setup(self, id, name, value, format='str'):
229 self.id = str(id)
229 self.id = str(id)
230 self.name = name
230 self.name = name
231 if format == 'obj':
231 if format == 'obj':
232 self.value = value
232 self.value = value
233 else:
233 else:
234 self.value = str(value)
234 self.value = str(value)
235 self.format = str.lower(format)
235 self.format = str.lower(format)
236
236
237 self.getValue()
237 self.getValue()
238
238
239 return 1
239 return 1
240
240
241 def update(self, name, value, format='str'):
241 def update(self, name, value, format='str'):
242
242
243 self.name = name
243 self.name = name
244 self.value = str(value)
244 self.value = str(value)
245 self.format = format
245 self.format = format
246
246
247 def makeXml(self, opElement):
247 def makeXml(self, opElement):
248 if self.name not in ('queue',):
248 if self.name not in ('queue',):
249 parmElement = SubElement(opElement, self.ELEMENTNAME)
249 parmElement = SubElement(opElement, self.ELEMENTNAME)
250 parmElement.set('id', str(self.id))
250 parmElement.set('id', str(self.id))
251 parmElement.set('name', self.name)
251 parmElement.set('name', self.name)
252 parmElement.set('value', self.value)
252 parmElement.set('value', self.value)
253 parmElement.set('format', self.format)
253 parmElement.set('format', self.format)
254
254
255 def readXml(self, parmElement):
255 def readXml(self, parmElement):
256
256
257 self.id = parmElement.get('id')
257 self.id = parmElement.get('id')
258 self.name = parmElement.get('name')
258 self.name = parmElement.get('name')
259 self.value = parmElement.get('value')
259 self.value = parmElement.get('value')
260 self.format = str.lower(parmElement.get('format'))
260 self.format = str.lower(parmElement.get('format'))
261
261
262 # Compatible with old signal chain version
262 # Compatible with old signal chain version
263 if self.format == 'int' and self.name == 'idfigure':
263 if self.format == 'int' and self.name == 'idfigure':
264 self.name = 'id'
264 self.name = 'id'
265
265
266 def printattr(self):
266 def printattr(self):
267
267
268 print 'Parameter[%s]: name = %s, value = %s, format = %s' % (self.id, self.name, self.value, self.format)
268 print 'Parameter[%s]: name = %s, value = %s, format = %s' % (self.id, self.name, self.value, self.format)
269
269
270
270
271 class OperationConf():
271 class OperationConf():
272
272
273 id = None
273 id = None
274 name = None
274 name = None
275 priority = None
275 priority = None
276 type = None
276 type = None
277
277
278 parmConfObjList = []
278 parmConfObjList = []
279
279
280 ELEMENTNAME = 'Operation'
280 ELEMENTNAME = 'Operation'
281
281
282 def __init__(self):
282 def __init__(self):
283
283
284 self.id = '0'
284 self.id = '0'
285 self.name = None
285 self.name = None
286 self.priority = None
286 self.priority = None
287 self.type = 'self'
287 self.type = 'self'
288
288
289 def __getNewId(self):
289 def __getNewId(self):
290
290
291 return int(self.id) * 10 + len(self.parmConfObjList) + 1
291 return int(self.id) * 10 + len(self.parmConfObjList) + 1
292
292
293 def updateId(self, new_id):
293 def updateId(self, new_id):
294
294
295 self.id = str(new_id)
295 self.id = str(new_id)
296
296
297 n = 1
297 n = 1
298 for parmObj in self.parmConfObjList:
298 for parmObj in self.parmConfObjList:
299
299
300 idParm = str(int(new_id) * 10 + n)
300 idParm = str(int(new_id) * 10 + n)
301 parmObj.updateId(idParm)
301 parmObj.updateId(idParm)
302
302
303 n += 1
303 n += 1
304
304
305 def getElementName(self):
305 def getElementName(self):
306
306
307 return self.ELEMENTNAME
307 return self.ELEMENTNAME
308
308
309 def getParameterObjList(self):
309 def getParameterObjList(self):
310
310
311 return self.parmConfObjList
311 return self.parmConfObjList
312
312
313 def getParameterObj(self, parameterName):
313 def getParameterObj(self, parameterName):
314
314
315 for parmConfObj in self.parmConfObjList:
315 for parmConfObj in self.parmConfObjList:
316
316
317 if parmConfObj.name != parameterName:
317 if parmConfObj.name != parameterName:
318 continue
318 continue
319
319
320 return parmConfObj
320 return parmConfObj
321
321
322 return None
322 return None
323
323
324 def getParameterObjfromValue(self, parameterValue):
324 def getParameterObjfromValue(self, parameterValue):
325
325
326 for parmConfObj in self.parmConfObjList:
326 for parmConfObj in self.parmConfObjList:
327
327
328 if parmConfObj.getValue() != parameterValue:
328 if parmConfObj.getValue() != parameterValue:
329 continue
329 continue
330
330
331 return parmConfObj.getValue()
331 return parmConfObj.getValue()
332
332
333 return None
333 return None
334
334
335 def getParameterValue(self, parameterName):
335 def getParameterValue(self, parameterName):
336
336
337 parameterObj = self.getParameterObj(parameterName)
337 parameterObj = self.getParameterObj(parameterName)
338
338
339 # if not parameterObj:
339 # if not parameterObj:
340 # return None
340 # return None
341
341
342 value = parameterObj.getValue()
342 value = parameterObj.getValue()
343
343
344 return value
344 return value
345
345
346 def getKwargs(self):
346 def getKwargs(self):
347
347
348 kwargs = {}
348 kwargs = {}
349
349
350 for parmConfObj in self.parmConfObjList:
350 for parmConfObj in self.parmConfObjList:
351 if self.name == 'run' and parmConfObj.name == 'datatype':
351 if self.name == 'run' and parmConfObj.name == 'datatype':
352 continue
352 continue
353
353
354 kwargs[parmConfObj.name] = parmConfObj.getValue()
354 kwargs[parmConfObj.name] = parmConfObj.getValue()
355
355
356 return kwargs
356 return kwargs
357
357
358 def setup(self, id, name, priority, type):
358 def setup(self, id, name, priority, type):
359
359
360 self.id = str(id)
360 self.id = str(id)
361 self.name = name
361 self.name = name
362 self.type = type
362 self.type = type
363 self.priority = priority
363 self.priority = priority
364
364
365 self.parmConfObjList = []
365 self.parmConfObjList = []
366
366
367 def removeParameters(self):
367 def removeParameters(self):
368
368
369 for obj in self.parmConfObjList:
369 for obj in self.parmConfObjList:
370 del obj
370 del obj
371
371
372 self.parmConfObjList = []
372 self.parmConfObjList = []
373
373
374 def addParameter(self, name, value, format='str'):
374 def addParameter(self, name, value, format='str'):
375
375
376 if value is None:
376 if value is None:
377 return None
377 return None
378 id = self.__getNewId()
378 id = self.__getNewId()
379
379
380 parmConfObj = ParameterConf()
380 parmConfObj = ParameterConf()
381 if not parmConfObj.setup(id, name, value, format):
381 if not parmConfObj.setup(id, name, value, format):
382 return None
382 return None
383
383
384 self.parmConfObjList.append(parmConfObj)
384 self.parmConfObjList.append(parmConfObj)
385
385
386 return parmConfObj
386 return parmConfObj
387
387
388 def changeParameter(self, name, value, format='str'):
388 def changeParameter(self, name, value, format='str'):
389
389
390 parmConfObj = self.getParameterObj(name)
390 parmConfObj = self.getParameterObj(name)
391 parmConfObj.update(name, value, format)
391 parmConfObj.update(name, value, format)
392
392
393 return parmConfObj
393 return parmConfObj
394
394
395 def makeXml(self, procUnitElement):
395 def makeXml(self, procUnitElement):
396
396
397 opElement = SubElement(procUnitElement, self.ELEMENTNAME)
397 opElement = SubElement(procUnitElement, self.ELEMENTNAME)
398 opElement.set('id', str(self.id))
398 opElement.set('id', str(self.id))
399 opElement.set('name', self.name)
399 opElement.set('name', self.name)
400 opElement.set('type', self.type)
400 opElement.set('type', self.type)
401 opElement.set('priority', str(self.priority))
401 opElement.set('priority', str(self.priority))
402
402
403 for parmConfObj in self.parmConfObjList:
403 for parmConfObj in self.parmConfObjList:
404 parmConfObj.makeXml(opElement)
404 parmConfObj.makeXml(opElement)
405
405
406 def readXml(self, opElement):
406 def readXml(self, opElement):
407
407
408 self.id = opElement.get('id')
408 self.id = opElement.get('id')
409 self.name = opElement.get('name')
409 self.name = opElement.get('name')
410 self.type = opElement.get('type')
410 self.type = opElement.get('type')
411 self.priority = opElement.get('priority')
411 self.priority = opElement.get('priority')
412
412
413 # Compatible with old signal chain version
413 # Compatible with old signal chain version
414 # Use of 'run' method instead 'init'
414 # Use of 'run' method instead 'init'
415 if self.type == 'self' and self.name == 'init':
415 if self.type == 'self' and self.name == 'init':
416 self.name = 'run'
416 self.name = 'run'
417
417
418 self.parmConfObjList = []
418 self.parmConfObjList = []
419
419
420 parmElementList = opElement.iter(ParameterConf().getElementName())
420 parmElementList = opElement.iter(ParameterConf().getElementName())
421
421
422 for parmElement in parmElementList:
422 for parmElement in parmElementList:
423 parmConfObj = ParameterConf()
423 parmConfObj = ParameterConf()
424 parmConfObj.readXml(parmElement)
424 parmConfObj.readXml(parmElement)
425
425
426 # Compatible with old signal chain version
426 # Compatible with old signal chain version
427 # If an 'plot' OPERATION is found, changes name operation by the value of its type PARAMETER
427 # If an 'plot' OPERATION is found, changes name operation by the value of its type PARAMETER
428 if self.type != 'self' and self.name == 'Plot':
428 if self.type != 'self' and self.name == 'Plot':
429 if parmConfObj.format == 'str' and parmConfObj.name == 'type':
429 if parmConfObj.format == 'str' and parmConfObj.name == 'type':
430 self.name = parmConfObj.value
430 self.name = parmConfObj.value
431 continue
431 continue
432
432
433 self.parmConfObjList.append(parmConfObj)
433 self.parmConfObjList.append(parmConfObj)
434
434
435 def printattr(self):
435 def printattr(self):
436
436
437 print '%s[%s]: name = %s, type = %s, priority = %s' % (self.ELEMENTNAME,
437 print '%s[%s]: name = %s, type = %s, priority = %s' % (self.ELEMENTNAME,
438 self.id,
438 self.id,
439 self.name,
439 self.name,
440 self.type,
440 self.type,
441 self.priority)
441 self.priority)
442
442
443 for parmConfObj in self.parmConfObjList:
443 for parmConfObj in self.parmConfObjList:
444 parmConfObj.printattr()
444 parmConfObj.printattr()
445
445
446 def createObject(self, plotter_queue=None):
446 def createObject(self, plotter_queue=None):
447
447
448 if self.type == 'self':
448 if self.type == 'self':
449 raise ValueError, 'This operation type cannot be created'
449 raise ValueError, 'This operation type cannot be created'
450
450
451 if self.type == 'plotter':
451 if self.type == 'plotter':
452 if not plotter_queue:
452 if not plotter_queue:
453 raise ValueError, 'plotter_queue is not defined. Use:\nmyProject = Project()\nmyProject.setPlotterQueue(plotter_queue)'
453 raise ValueError, 'plotter_queue is not defined. Use:\nmyProject = Project()\nmyProject.setPlotterQueue(plotter_queue)'
454
454
455 opObj = Plotter(self.name, plotter_queue)
455 opObj = Plotter(self.name, plotter_queue)
456
456
457 if self.type == 'external' or self.type == 'other':
457 if self.type == 'external' or self.type == 'other':
458
458
459 className = eval(self.name)
459 className = eval(self.name)
460 kwargs = self.getKwargs()
460 kwargs = self.getKwargs()
461
461
462 opObj = className(**kwargs)
462 opObj = className(**kwargs)
463
463
464 return opObj
464 return opObj
465
465
466
466
467 class ProcUnitConf():
467 class ProcUnitConf():
468
468
469 id = None
469 id = None
470 name = None
470 name = None
471 datatype = None
471 datatype = None
472 inputId = None
472 inputId = None
473 parentId = None
473 parentId = None
474
474
475 opConfObjList = []
475 opConfObjList = []
476
476
477 procUnitObj = None
477 procUnitObj = None
478 opObjList = []
478 opObjList = []
479
479
480 ELEMENTNAME = 'ProcUnit'
480 ELEMENTNAME = 'ProcUnit'
481
481
482 def __init__(self):
482 def __init__(self):
483
483
484 self.id = None
484 self.id = None
485 self.datatype = None
485 self.datatype = None
486 self.name = None
486 self.name = None
487 self.inputId = None
487 self.inputId = None
488
488
489 self.opConfObjList = []
489 self.opConfObjList = []
490
490
491 self.procUnitObj = None
491 self.procUnitObj = None
492 self.opObjDict = {}
492 self.opObjDict = {}
493
493
494 def __getPriority(self):
494 def __getPriority(self):
495
495
496 return len(self.opConfObjList) + 1
496 return len(self.opConfObjList) + 1
497
497
498 def __getNewId(self):
498 def __getNewId(self):
499
499
500 return int(self.id) * 10 + len(self.opConfObjList) + 1
500 return int(self.id) * 10 + len(self.opConfObjList) + 1
501
501
502 def getElementName(self):
502 def getElementName(self):
503
503
504 return self.ELEMENTNAME
504 return self.ELEMENTNAME
505
505
506 def getId(self):
506 def getId(self):
507
507
508 return self.id
508 return self.id
509
509
510 def updateId(self, new_id, parentId=parentId):
510 def updateId(self, new_id, parentId=parentId):
511
511
512 new_id = int(parentId) * 10 + (int(self.id) % 10)
512 new_id = int(parentId) * 10 + (int(self.id) % 10)
513 new_inputId = int(parentId) * 10 + (int(self.inputId) % 10)
513 new_inputId = int(parentId) * 10 + (int(self.inputId) % 10)
514
514
515 # If this proc unit has not inputs
515 # If this proc unit has not inputs
516 if self.inputId == '0':
516 if self.inputId == '0':
517 new_inputId = 0
517 new_inputId = 0
518
518
519 n = 1
519 n = 1
520 for opConfObj in self.opConfObjList:
520 for opConfObj in self.opConfObjList:
521
521
522 idOp = str(int(new_id) * 10 + n)
522 idOp = str(int(new_id) * 10 + n)
523 opConfObj.updateId(idOp)
523 opConfObj.updateId(idOp)
524
524
525 n += 1
525 n += 1
526
526
527 self.parentId = str(parentId)
527 self.parentId = str(parentId)
528 self.id = str(new_id)
528 self.id = str(new_id)
529 self.inputId = str(new_inputId)
529 self.inputId = str(new_inputId)
530
530
531 def getInputId(self):
531 def getInputId(self):
532
532
533 return self.inputId
533 return self.inputId
534
534
535 def getOperationObjList(self):
535 def getOperationObjList(self):
536
536
537 return self.opConfObjList
537 return self.opConfObjList
538
538
539 def getOperationObj(self, name=None):
539 def getOperationObj(self, name=None):
540
540
541 for opConfObj in self.opConfObjList:
541 for opConfObj in self.opConfObjList:
542
542
543 if opConfObj.name != name:
543 if opConfObj.name != name:
544 continue
544 continue
545
545
546 return opConfObj
546 return opConfObj
547
547
548 return None
548 return None
549
549
550 def getOpObjfromParamValue(self, value=None):
550 def getOpObjfromParamValue(self, value=None):
551
551
552 for opConfObj in self.opConfObjList:
552 for opConfObj in self.opConfObjList:
553 if opConfObj.getParameterObjfromValue(parameterValue=value) != value:
553 if opConfObj.getParameterObjfromValue(parameterValue=value) != value:
554 continue
554 continue
555 return opConfObj
555 return opConfObj
556 return None
556 return None
557
557
558 def getProcUnitObj(self):
558 def getProcUnitObj(self):
559
559
560 return self.procUnitObj
560 return self.procUnitObj
561
561
562 def setup(self, id, name, datatype, inputId, parentId=None):
562 def setup(self, id, name, datatype, inputId, parentId=None):
563
563
564 # Compatible with old signal chain version
564 # Compatible with old signal chain version
565 if datatype == None and name == None:
565 if datatype == None and name == None:
566 raise ValueError, 'datatype or name should be defined'
566 raise ValueError, 'datatype or name should be defined'
567
567
568 if name == None:
568 if name == None:
569 if 'Proc' in datatype:
569 if 'Proc' in datatype:
570 name = datatype
570 name = datatype
571 else:
571 else:
572 name = '%sProc' % (datatype)
572 name = '%sProc' % (datatype)
573
573
574 if datatype == None:
574 if datatype == None:
575 datatype = name.replace('Proc', '')
575 datatype = name.replace('Proc', '')
576
576
577 self.id = str(id)
577 self.id = str(id)
578 self.name = name
578 self.name = name
579 self.datatype = datatype
579 self.datatype = datatype
580 self.inputId = inputId
580 self.inputId = inputId
581 self.parentId = parentId
581 self.parentId = parentId
582
582
583 self.opConfObjList = []
583 self.opConfObjList = []
584
584
585 self.addOperation(name='run', optype='self')
585 self.addOperation(name='run', optype='self')
586
586
587 def removeOperations(self):
587 def removeOperations(self):
588
588
589 for obj in self.opConfObjList:
589 for obj in self.opConfObjList:
590 del obj
590 del obj
591
591
592 self.opConfObjList = []
592 self.opConfObjList = []
593 self.addOperation(name='run')
593 self.addOperation(name='run')
594
594
595 def addParameter(self, **kwargs):
595 def addParameter(self, **kwargs):
596 '''
596 '''
597 Add parameters to 'run' operation
597 Add parameters to 'run' operation
598 '''
598 '''
599 opObj = self.opConfObjList[0]
599 opObj = self.opConfObjList[0]
600
600
601 opObj.addParameter(**kwargs)
601 opObj.addParameter(**kwargs)
602
602
603 return opObj
603 return opObj
604
604
605 def addOperation(self, name, optype='self'):
605 def addOperation(self, name, optype='self'):
606
606
607 id = self.__getNewId()
607 id = self.__getNewId()
608 priority = self.__getPriority()
608 priority = self.__getPriority()
609
609
610 opConfObj = OperationConf()
610 opConfObj = OperationConf()
611 opConfObj.setup(id, name=name, priority=priority, type=optype)
611 opConfObj.setup(id, name=name, priority=priority, type=optype)
612
612
613 self.opConfObjList.append(opConfObj)
613 self.opConfObjList.append(opConfObj)
614
614
615 return opConfObj
615 return opConfObj
616
616
617 def makeXml(self, projectElement):
617 def makeXml(self, projectElement):
618
618
619 procUnitElement = SubElement(projectElement, self.ELEMENTNAME)
619 procUnitElement = SubElement(projectElement, self.ELEMENTNAME)
620 procUnitElement.set('id', str(self.id))
620 procUnitElement.set('id', str(self.id))
621 procUnitElement.set('name', self.name)
621 procUnitElement.set('name', self.name)
622 procUnitElement.set('datatype', self.datatype)
622 procUnitElement.set('datatype', self.datatype)
623 procUnitElement.set('inputId', str(self.inputId))
623 procUnitElement.set('inputId', str(self.inputId))
624
624
625 for opConfObj in self.opConfObjList:
625 for opConfObj in self.opConfObjList:
626 opConfObj.makeXml(procUnitElement)
626 opConfObj.makeXml(procUnitElement)
627
627
628 def readXml(self, upElement):
628 def readXml(self, upElement):
629
629
630 self.id = upElement.get('id')
630 self.id = upElement.get('id')
631 self.name = upElement.get('name')
631 self.name = upElement.get('name')
632 self.datatype = upElement.get('datatype')
632 self.datatype = upElement.get('datatype')
633 self.inputId = upElement.get('inputId')
633 self.inputId = upElement.get('inputId')
634
634
635 if self.ELEMENTNAME == 'ReadUnit':
635 if self.ELEMENTNAME == 'ReadUnit':
636 self.datatype = self.datatype.replace('Reader', '')
636 self.datatype = self.datatype.replace('Reader', '')
637
637
638 if self.ELEMENTNAME == 'ProcUnit':
638 if self.ELEMENTNAME == 'ProcUnit':
639 self.datatype = self.datatype.replace('Proc', '')
639 self.datatype = self.datatype.replace('Proc', '')
640
640
641 if self.inputId == 'None':
641 if self.inputId == 'None':
642 self.inputId = '0'
642 self.inputId = '0'
643
643
644 self.opConfObjList = []
644 self.opConfObjList = []
645
645
646 opElementList = upElement.iter(OperationConf().getElementName())
646 opElementList = upElement.iter(OperationConf().getElementName())
647
647
648 for opElement in opElementList:
648 for opElement in opElementList:
649 opConfObj = OperationConf()
649 opConfObj = OperationConf()
650 opConfObj.readXml(opElement)
650 opConfObj.readXml(opElement)
651 self.opConfObjList.append(opConfObj)
651 self.opConfObjList.append(opConfObj)
652
652
653 def printattr(self):
653 def printattr(self):
654
654
655 print '%s[%s]: name = %s, datatype = %s, inputId = %s' % (self.ELEMENTNAME,
655 print '%s[%s]: name = %s, datatype = %s, inputId = %s' % (self.ELEMENTNAME,
656 self.id,
656 self.id,
657 self.name,
657 self.name,
658 self.datatype,
658 self.datatype,
659 self.inputId)
659 self.inputId)
660
660
661 for opConfObj in self.opConfObjList:
661 for opConfObj in self.opConfObjList:
662 opConfObj.printattr()
662 opConfObj.printattr()
663
663
664 def getKwargs(self):
664 def getKwargs(self):
665
665
666 opObj = self.opConfObjList[0]
666 opObj = self.opConfObjList[0]
667 kwargs = opObj.getKwargs()
667 kwargs = opObj.getKwargs()
668
668
669 return kwargs
669 return kwargs
670
670
671 def createObjects(self, plotter_queue=None):
671 def createObjects(self, plotter_queue=None):
672
672
673 className = eval(self.name)
673 className = eval(self.name)
674 kwargs = self.getKwargs()
674 kwargs = self.getKwargs()
675 procUnitObj = className(**kwargs)
675 procUnitObj = className(**kwargs)
676
676
677 for opConfObj in self.opConfObjList:
677 for opConfObj in self.opConfObjList:
678
678
679 if opConfObj.type == 'self' and self.name == 'run':
679 if opConfObj.type == 'self' and self.name == 'run':
680 continue
680 continue
681 elif opConfObj.type == 'self':
681 elif opConfObj.type == 'self':
682 procUnitObj.addOperationKwargs(
682 procUnitObj.addOperationKwargs(
683 opConfObj.id, **opConfObj.getKwargs())
683 opConfObj.id, **opConfObj.getKwargs())
684 continue
684 continue
685
685
686 opObj = opConfObj.createObject(plotter_queue)
686 opObj = opConfObj.createObject(plotter_queue)
687
687
688 self.opObjDict[opConfObj.id] = opObj
688 self.opObjDict[opConfObj.id] = opObj
689
689
690 procUnitObj.addOperation(opObj, opConfObj.id)
690 procUnitObj.addOperation(opObj, opConfObj.id)
691
691
692 self.procUnitObj = procUnitObj
692 self.procUnitObj = procUnitObj
693
693
694 return procUnitObj
694 return procUnitObj
695
695
696 def run(self):
696 def run(self):
697
697
698 is_ok = False
698 is_ok = False
699
699
700 for opConfObj in self.opConfObjList:
700 for opConfObj in self.opConfObjList:
701
701
702 kwargs = {}
702 kwargs = {}
703 for parmConfObj in opConfObj.getParameterObjList():
703 for parmConfObj in opConfObj.getParameterObjList():
704 if opConfObj.name == 'run' and parmConfObj.name == 'datatype':
704 if opConfObj.name == 'run' and parmConfObj.name == 'datatype':
705 continue
705 continue
706
706
707 kwargs[parmConfObj.name] = parmConfObj.getValue()
707 kwargs[parmConfObj.name] = parmConfObj.getValue()
708
708
709 sts = self.procUnitObj.call(opType=opConfObj.type,
709 sts = self.procUnitObj.call(opType=opConfObj.type,
710 opName=opConfObj.name,
710 opName=opConfObj.name,
711 opId=opConfObj.id)
711 opId=opConfObj.id)
712
712
713 is_ok = is_ok or sts
713 is_ok = is_ok or sts
714
714
715 return is_ok
715 return is_ok
716
716
717 def close(self):
717 def close(self):
718
718
719 for opConfObj in self.opConfObjList:
719 for opConfObj in self.opConfObjList:
720 if opConfObj.type == 'self':
720 if opConfObj.type == 'self':
721 continue
721 continue
722
722
723 opObj = self.procUnitObj.getOperationObj(opConfObj.id)
723 opObj = self.procUnitObj.getOperationObj(opConfObj.id)
724 opObj.close()
724 opObj.close()
725
725
726 self.procUnitObj.close()
726 self.procUnitObj.close()
727
727
728 return
728 return
729
729
730
730
731 class ReadUnitConf(ProcUnitConf):
731 class ReadUnitConf(ProcUnitConf):
732
732
733 path = None
733 path = None
734 startDate = None
734 startDate = None
735 endDate = None
735 endDate = None
736 startTime = None
736 startTime = None
737 endTime = None
737 endTime = None
738
738
739 ELEMENTNAME = 'ReadUnit'
739 ELEMENTNAME = 'ReadUnit'
740
740
741 def __init__(self):
741 def __init__(self):
742
742
743 self.id = None
743 self.id = None
744 self.datatype = None
744 self.datatype = None
745 self.name = None
745 self.name = None
746 self.inputId = None
746 self.inputId = None
747
747
748 self.parentId = None
748 self.parentId = None
749
749
750 self.opConfObjList = []
750 self.opConfObjList = []
751 self.opObjList = []
751 self.opObjList = []
752
752
753 def getElementName(self):
753 def getElementName(self):
754
754
755 return self.ELEMENTNAME
755 return self.ELEMENTNAME
756
756
757 def setup(self, id, name, datatype, path='', startDate='', endDate='',
757 def setup(self, id, name, datatype, path='', startDate='', endDate='',
758 startTime='', endTime='', parentId=None, server=None, **kwargs):
758 startTime='', endTime='', parentId=None, server=None, **kwargs):
759
759
760 # Compatible with old signal chain version
760 # Compatible with old signal chain version
761 if datatype == None and name == None:
761 if datatype == None and name == None:
762 raise ValueError, 'datatype or name should be defined'
762 raise ValueError, 'datatype or name should be defined'
763 if name == None:
763 if name == None:
764 if 'Reader' in datatype:
764 if 'Reader' in datatype:
765 name = datatype
765 name = datatype
766 datatype = name.replace('Reader','')
766 datatype = name.replace('Reader','')
767 else:
767 else:
768 name = '{}Reader'.format(datatype)
768 name = '{}Reader'.format(datatype)
769 if datatype == None:
769 if datatype == None:
770 if 'Reader' in name:
770 if 'Reader' in name:
771 datatype = name.replace('Reader','')
771 datatype = name.replace('Reader','')
772 else:
772 else:
773 datatype = name
773 datatype = name
774 name = '{}Reader'.format(name)
774 name = '{}Reader'.format(name)
775
775
776 self.id = id
776 self.id = id
777 self.name = name
777 self.name = name
778 self.datatype = datatype
778 self.datatype = datatype
779 if path != '':
779 if path != '':
780 self.path = os.path.abspath(path)
780 self.path = os.path.abspath(path)
781 self.startDate = startDate
781 self.startDate = startDate
782 self.endDate = endDate
782 self.endDate = endDate
783 self.startTime = startTime
783 self.startTime = startTime
784 self.endTime = endTime
784 self.endTime = endTime
785 self.inputId = '0'
785 self.inputId = '0'
786 self.parentId = parentId
786 self.parentId = parentId
787 self.server = server
787 self.server = server
788 self.addRunOperation(**kwargs)
788 self.addRunOperation(**kwargs)
789
789
790 def update(self, **kwargs):
790 def update(self, **kwargs):
791
791
792 if 'datatype' in kwargs:
792 if 'datatype' in kwargs:
793 datatype = kwargs.pop('datatype')
793 datatype = kwargs.pop('datatype')
794 if 'Reader' in datatype:
794 if 'Reader' in datatype:
795 self.name = datatype
795 self.name = datatype
796 else:
796 else:
797 self.name = '%sReader' % (datatype)
797 self.name = '%sReader' % (datatype)
798 self.datatype = self.name.replace('Reader', '')
798 self.datatype = self.name.replace('Reader', '')
799
799
800 attrs = ('path', 'startDate', 'endDate',
800 attrs = ('path', 'startDate', 'endDate',
801 'startTime', 'endTime', 'parentId')
801 'startTime', 'endTime', 'parentId')
802
802
803 for attr in attrs:
803 for attr in attrs:
804 if attr in kwargs:
804 if attr in kwargs:
805 setattr(self, attr, kwargs.pop(attr))
805 setattr(self, attr, kwargs.pop(attr))
806
806
807 self.inputId = '0'
807 self.inputId = '0'
808 self.updateRunOperation(**kwargs)
808 self.updateRunOperation(**kwargs)
809
809
810 def removeOperations(self):
810 def removeOperations(self):
811
811
812 for obj in self.opConfObjList:
812 for obj in self.opConfObjList:
813 del obj
813 del obj
814
814
815 self.opConfObjList = []
815 self.opConfObjList = []
816
816
817 def addRunOperation(self, **kwargs):
817 def addRunOperation(self, **kwargs):
818
818
819 opObj = self.addOperation(name='run', optype='self')
819 opObj = self.addOperation(name='run', optype='self')
820
820
821 if self.server is None:
821 if self.server is None:
822 opObj.addParameter(
822 opObj.addParameter(
823 name='datatype', value=self.datatype, format='str')
823 name='datatype', value=self.datatype, format='str')
824 opObj.addParameter(name='path', value=self.path, format='str')
824 opObj.addParameter(name='path', value=self.path, format='str')
825 opObj.addParameter(
825 opObj.addParameter(
826 name='startDate', value=self.startDate, format='date')
826 name='startDate', value=self.startDate, format='date')
827 opObj.addParameter(
827 opObj.addParameter(
828 name='endDate', value=self.endDate, format='date')
828 name='endDate', value=self.endDate, format='date')
829 opObj.addParameter(
829 opObj.addParameter(
830 name='startTime', value=self.startTime, format='time')
830 name='startTime', value=self.startTime, format='time')
831 opObj.addParameter(
831 opObj.addParameter(
832 name='endTime', value=self.endTime, format='time')
832 name='endTime', value=self.endTime, format='time')
833
833
834 for key, value in kwargs.items():
834 for key, value in kwargs.items():
835 opObj.addParameter(name=key, value=value,
835 opObj.addParameter(name=key, value=value,
836 format=type(value).__name__)
836 format=type(value).__name__)
837 else:
837 else:
838 opObj.addParameter(name='server', value=self.server, format='str')
838 opObj.addParameter(name='server', value=self.server, format='str')
839
839
840 return opObj
840 return opObj
841
841
842 def updateRunOperation(self, **kwargs):
842 def updateRunOperation(self, **kwargs):
843
843
844 opObj = self.getOperationObj(name='run')
844 opObj = self.getOperationObj(name='run')
845 opObj.removeParameters()
845 opObj.removeParameters()
846
846
847 opObj.addParameter(name='datatype', value=self.datatype, format='str')
847 opObj.addParameter(name='datatype', value=self.datatype, format='str')
848 opObj.addParameter(name='path', value=self.path, format='str')
848 opObj.addParameter(name='path', value=self.path, format='str')
849 opObj.addParameter(
849 opObj.addParameter(
850 name='startDate', value=self.startDate, format='date')
850 name='startDate', value=self.startDate, format='date')
851 opObj.addParameter(name='endDate', value=self.endDate, format='date')
851 opObj.addParameter(name='endDate', value=self.endDate, format='date')
852 opObj.addParameter(
852 opObj.addParameter(
853 name='startTime', value=self.startTime, format='time')
853 name='startTime', value=self.startTime, format='time')
854 opObj.addParameter(name='endTime', value=self.endTime, format='time')
854 opObj.addParameter(name='endTime', value=self.endTime, format='time')
855
855
856 for key, value in kwargs.items():
856 for key, value in kwargs.items():
857 opObj.addParameter(name=key, value=value,
857 opObj.addParameter(name=key, value=value,
858 format=type(value).__name__)
858 format=type(value).__name__)
859
859
860 return opObj
860 return opObj
861
861
862 def readXml(self, upElement):
862 def readXml(self, upElement):
863
863
864 self.id = upElement.get('id')
864 self.id = upElement.get('id')
865 self.name = upElement.get('name')
865 self.name = upElement.get('name')
866 self.datatype = upElement.get('datatype')
866 self.datatype = upElement.get('datatype')
867 self.inputId = upElement.get('inputId')
867 self.inputId = upElement.get('inputId')
868
868
869 if self.ELEMENTNAME == 'ReadUnit':
869 if self.ELEMENTNAME == 'ReadUnit':
870 self.datatype = self.datatype.replace('Reader', '')
870 self.datatype = self.datatype.replace('Reader', '')
871
871
872 if self.inputId == 'None':
872 if self.inputId == 'None':
873 self.inputId = '0'
873 self.inputId = '0'
874
874
875 self.opConfObjList = []
875 self.opConfObjList = []
876
876
877 opElementList = upElement.iter(OperationConf().getElementName())
877 opElementList = upElement.iter(OperationConf().getElementName())
878
878
879 for opElement in opElementList:
879 for opElement in opElementList:
880 opConfObj = OperationConf()
880 opConfObj = OperationConf()
881 opConfObj.readXml(opElement)
881 opConfObj.readXml(opElement)
882 self.opConfObjList.append(opConfObj)
882 self.opConfObjList.append(opConfObj)
883
883
884 if opConfObj.name == 'run':
884 if opConfObj.name == 'run':
885 self.path = opConfObj.getParameterValue('path')
885 self.path = opConfObj.getParameterValue('path')
886 self.startDate = opConfObj.getParameterValue('startDate')
886 self.startDate = opConfObj.getParameterValue('startDate')
887 self.endDate = opConfObj.getParameterValue('endDate')
887 self.endDate = opConfObj.getParameterValue('endDate')
888 self.startTime = opConfObj.getParameterValue('startTime')
888 self.startTime = opConfObj.getParameterValue('startTime')
889 self.endTime = opConfObj.getParameterValue('endTime')
889 self.endTime = opConfObj.getParameterValue('endTime')
890
890
891
891
892 class Project(Process):
892 class Project(Process):
893
893
894 id = None
894 id = None
895 # name = None
895 # name = None
896 description = None
896 description = None
897 filename = None
897 filename = None
898
898
899 procUnitConfObjDict = None
899 procUnitConfObjDict = None
900
900
901 ELEMENTNAME = 'Project'
901 ELEMENTNAME = 'Project'
902
902
903 plotterQueue = None
903 plotterQueue = None
904
904
905 def __init__(self, plotter_queue=None):
905 def __init__(self, plotter_queue=None):
906
906
907 Process.__init__(self)
907 Process.__init__(self)
908 self.id = None
908 self.id = None
909 self.description = None
909 self.description = None
910 self.email = None
910 self.email = None
911 self.alarm = None
911 self.alarm = None
912 self.plotterQueue = plotter_queue
912 self.plotterQueue = plotter_queue
913 self.procUnitConfObjDict = {}
913 self.procUnitConfObjDict = {}
914
914
915 def __getNewId(self):
915 def __getNewId(self):
916
916
917 idList = self.procUnitConfObjDict.keys()
917 idList = self.procUnitConfObjDict.keys()
918
918
919 id = int(self.id) * 10
919 id = int(self.id) * 10
920
920
921 while True:
921 while True:
922 id += 1
922 id += 1
923
923
924 if str(id) in idList:
924 if str(id) in idList:
925 continue
925 continue
926
926
927 break
927 break
928
928
929 return str(id)
929 return str(id)
930
930
931 def getElementName(self):
931 def getElementName(self):
932
932
933 return self.ELEMENTNAME
933 return self.ELEMENTNAME
934
934
935 def getId(self):
935 def getId(self):
936
936
937 return self.id
937 return self.id
938
938
939 def updateId(self, new_id):
939 def updateId(self, new_id):
940
940
941 self.id = str(new_id)
941 self.id = str(new_id)
942
942
943 keyList = self.procUnitConfObjDict.keys()
943 keyList = self.procUnitConfObjDict.keys()
944 keyList.sort()
944 keyList.sort()
945
945
946 n = 1
946 n = 1
947 newProcUnitConfObjDict = {}
947 newProcUnitConfObjDict = {}
948
948
949 for procKey in keyList:
949 for procKey in keyList:
950
950
951 procUnitConfObj = self.procUnitConfObjDict[procKey]
951 procUnitConfObj = self.procUnitConfObjDict[procKey]
952 idProcUnit = str(int(self.id) * 10 + n)
952 idProcUnit = str(int(self.id) * 10 + n)
953 procUnitConfObj.updateId(idProcUnit, parentId=self.id)
953 procUnitConfObj.updateId(idProcUnit, parentId=self.id)
954 newProcUnitConfObjDict[idProcUnit] = procUnitConfObj
954 newProcUnitConfObjDict[idProcUnit] = procUnitConfObj
955 n += 1
955 n += 1
956
956
957 self.procUnitConfObjDict = newProcUnitConfObjDict
957 self.procUnitConfObjDict = newProcUnitConfObjDict
958
958
959 def setup(self, id, name='', description='', email=None, alarm=[3]):
959 def setup(self, id, name='', description='', email=None, alarm=[]):
960
960
961 print
961 print
962 print '*' * 60
962 print '*' * 60
963 print ' Starting SIGNAL CHAIN PROCESSING v%s ' % schainpy.__version__
963 print ' Starting SIGNAL CHAIN PROCESSING v%s ' % schainpy.__version__
964 print '*' * 60
964 print '*' * 60
965 print
965 print
966 self.id = str(id)
966 self.id = str(id)
967 self.description = description
967 self.description = description
968 self.email = email
968 self.email = email
969 self.alarm = alarm
969 self.alarm = alarm
970
970
971 def update(self, **kwargs):
971 def update(self, **kwargs):
972
972
973 for key, value in kwargs.items():
973 for key, value in kwargs.items():
974 setattr(self, key, value)
974 setattr(self, key, value)
975
975
976 def clone(self):
976 def clone(self):
977
977
978 p = Project()
978 p = Project()
979 p.procUnitConfObjDict = self.procUnitConfObjDict
979 p.procUnitConfObjDict = self.procUnitConfObjDict
980 return p
980 return p
981
981
982 def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
982 def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
983
983
984 if id is None:
984 if id is None:
985 idReadUnit = self.__getNewId()
985 idReadUnit = self.__getNewId()
986 else:
986 else:
987 idReadUnit = str(id)
987 idReadUnit = str(id)
988
988
989 readUnitConfObj = ReadUnitConf()
989 readUnitConfObj = ReadUnitConf()
990 readUnitConfObj.setup(idReadUnit, name, datatype,
990 readUnitConfObj.setup(idReadUnit, name, datatype,
991 parentId=self.id, **kwargs)
991 parentId=self.id, **kwargs)
992
992
993 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
993 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
994
994
995 return readUnitConfObj
995 return readUnitConfObj
996
996
997 def addProcUnit(self, inputId='0', datatype=None, name=None):
997 def addProcUnit(self, inputId='0', datatype=None, name=None):
998
998
999 idProcUnit = self.__getNewId()
999 idProcUnit = self.__getNewId()
1000
1000
1001 procUnitConfObj = ProcUnitConf()
1001 procUnitConfObj = ProcUnitConf()
1002 procUnitConfObj.setup(idProcUnit, name, datatype,
1002 procUnitConfObj.setup(idProcUnit, name, datatype,
1003 inputId, parentId=self.id)
1003 inputId, parentId=self.id)
1004
1004
1005 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
1005 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
1006
1006
1007 return procUnitConfObj
1007 return procUnitConfObj
1008
1008
1009 def removeProcUnit(self, id):
1009 def removeProcUnit(self, id):
1010
1010
1011 if id in self.procUnitConfObjDict.keys():
1011 if id in self.procUnitConfObjDict.keys():
1012 self.procUnitConfObjDict.pop(id)
1012 self.procUnitConfObjDict.pop(id)
1013
1013
1014 def getReadUnitId(self):
1014 def getReadUnitId(self):
1015
1015
1016 readUnitConfObj = self.getReadUnitObj()
1016 readUnitConfObj = self.getReadUnitObj()
1017
1017
1018 return readUnitConfObj.id
1018 return readUnitConfObj.id
1019
1019
1020 def getReadUnitObj(self):
1020 def getReadUnitObj(self):
1021
1021
1022 for obj in self.procUnitConfObjDict.values():
1022 for obj in self.procUnitConfObjDict.values():
1023 if obj.getElementName() == 'ReadUnit':
1023 if obj.getElementName() == 'ReadUnit':
1024 return obj
1024 return obj
1025
1025
1026 return None
1026 return None
1027
1027
1028 def getProcUnitObj(self, id=None, name=None):
1028 def getProcUnitObj(self, id=None, name=None):
1029
1029
1030 if id != None:
1030 if id != None:
1031 return self.procUnitConfObjDict[id]
1031 return self.procUnitConfObjDict[id]
1032
1032
1033 if name != None:
1033 if name != None:
1034 return self.getProcUnitObjByName(name)
1034 return self.getProcUnitObjByName(name)
1035
1035
1036 return None
1036 return None
1037
1037
1038 def getProcUnitObjByName(self, name):
1038 def getProcUnitObjByName(self, name):
1039
1039
1040 for obj in self.procUnitConfObjDict.values():
1040 for obj in self.procUnitConfObjDict.values():
1041 if obj.name == name:
1041 if obj.name == name:
1042 return obj
1042 return obj
1043
1043
1044 return None
1044 return None
1045
1045
1046 def procUnitItems(self):
1046 def procUnitItems(self):
1047
1047
1048 return self.procUnitConfObjDict.items()
1048 return self.procUnitConfObjDict.items()
1049
1049
1050 def makeXml(self):
1050 def makeXml(self):
1051
1051
1052 projectElement = Element('Project')
1052 projectElement = Element('Project')
1053 projectElement.set('id', str(self.id))
1053 projectElement.set('id', str(self.id))
1054 projectElement.set('name', self.name)
1054 projectElement.set('name', self.name)
1055 projectElement.set('description', self.description)
1055 projectElement.set('description', self.description)
1056
1056
1057 for procUnitConfObj in self.procUnitConfObjDict.values():
1057 for procUnitConfObj in self.procUnitConfObjDict.values():
1058 procUnitConfObj.makeXml(projectElement)
1058 procUnitConfObj.makeXml(projectElement)
1059
1059
1060 self.projectElement = projectElement
1060 self.projectElement = projectElement
1061
1061
1062 def writeXml(self, filename=None):
1062 def writeXml(self, filename=None):
1063
1063
1064 if filename == None:
1064 if filename == None:
1065 if self.filename:
1065 if self.filename:
1066 filename = self.filename
1066 filename = self.filename
1067 else:
1067 else:
1068 filename = 'schain.xml'
1068 filename = 'schain.xml'
1069
1069
1070 if not filename:
1070 if not filename:
1071 print 'filename has not been defined. Use setFilename(filename) for do it.'
1071 print 'filename has not been defined. Use setFilename(filename) for do it.'
1072 return 0
1072 return 0
1073
1073
1074 abs_file = os.path.abspath(filename)
1074 abs_file = os.path.abspath(filename)
1075
1075
1076 if not os.access(os.path.dirname(abs_file), os.W_OK):
1076 if not os.access(os.path.dirname(abs_file), os.W_OK):
1077 print 'No write permission on %s' % os.path.dirname(abs_file)
1077 print 'No write permission on %s' % os.path.dirname(abs_file)
1078 return 0
1078 return 0
1079
1079
1080 if os.path.isfile(abs_file) and not(os.access(abs_file, os.W_OK)):
1080 if os.path.isfile(abs_file) and not(os.access(abs_file, os.W_OK)):
1081 print 'File %s already exists and it could not be overwriten' % abs_file
1081 print 'File %s already exists and it could not be overwriten' % abs_file
1082 return 0
1082 return 0
1083
1083
1084 self.makeXml()
1084 self.makeXml()
1085
1085
1086 ElementTree(self.projectElement).write(abs_file, method='xml')
1086 ElementTree(self.projectElement).write(abs_file, method='xml')
1087
1087
1088 self.filename = abs_file
1088 self.filename = abs_file
1089
1089
1090 return 1
1090 return 1
1091
1091
1092 def readXml(self, filename=None):
1092 def readXml(self, filename=None):
1093
1093
1094 if not filename:
1094 if not filename:
1095 print 'filename is not defined'
1095 print 'filename is not defined'
1096 return 0
1096 return 0
1097
1097
1098 abs_file = os.path.abspath(filename)
1098 abs_file = os.path.abspath(filename)
1099
1099
1100 if not os.path.isfile(abs_file):
1100 if not os.path.isfile(abs_file):
1101 print '%s file does not exist' % abs_file
1101 print '%s file does not exist' % abs_file
1102 return 0
1102 return 0
1103
1103
1104 self.projectElement = None
1104 self.projectElement = None
1105 self.procUnitConfObjDict = {}
1105 self.procUnitConfObjDict = {}
1106
1106
1107 try:
1107 try:
1108 self.projectElement = ElementTree().parse(abs_file)
1108 self.projectElement = ElementTree().parse(abs_file)
1109 except:
1109 except:
1110 print 'Error reading %s, verify file format' % filename
1110 print 'Error reading %s, verify file format' % filename
1111 return 0
1111 return 0
1112
1112
1113 self.project = self.projectElement.tag
1113 self.project = self.projectElement.tag
1114
1114
1115 self.id = self.projectElement.get('id')
1115 self.id = self.projectElement.get('id')
1116 self.name = self.projectElement.get('name')
1116 self.name = self.projectElement.get('name')
1117 self.description = self.projectElement.get('description')
1117 self.description = self.projectElement.get('description')
1118
1118
1119 readUnitElementList = self.projectElement.iter(
1119 readUnitElementList = self.projectElement.iter(
1120 ReadUnitConf().getElementName())
1120 ReadUnitConf().getElementName())
1121
1121
1122 for readUnitElement in readUnitElementList:
1122 for readUnitElement in readUnitElementList:
1123 readUnitConfObj = ReadUnitConf()
1123 readUnitConfObj = ReadUnitConf()
1124 readUnitConfObj.readXml(readUnitElement)
1124 readUnitConfObj.readXml(readUnitElement)
1125
1125
1126 if readUnitConfObj.parentId == None:
1126 if readUnitConfObj.parentId == None:
1127 readUnitConfObj.parentId = self.id
1127 readUnitConfObj.parentId = self.id
1128
1128
1129 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
1129 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
1130
1130
1131 procUnitElementList = self.projectElement.iter(
1131 procUnitElementList = self.projectElement.iter(
1132 ProcUnitConf().getElementName())
1132 ProcUnitConf().getElementName())
1133
1133
1134 for procUnitElement in procUnitElementList:
1134 for procUnitElement in procUnitElementList:
1135 procUnitConfObj = ProcUnitConf()
1135 procUnitConfObj = ProcUnitConf()
1136 procUnitConfObj.readXml(procUnitElement)
1136 procUnitConfObj.readXml(procUnitElement)
1137
1137
1138 if procUnitConfObj.parentId == None:
1138 if procUnitConfObj.parentId == None:
1139 procUnitConfObj.parentId = self.id
1139 procUnitConfObj.parentId = self.id
1140
1140
1141 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
1141 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
1142
1142
1143 self.filename = abs_file
1143 self.filename = abs_file
1144
1144
1145 return 1
1145 return 1
1146
1146
1147 def printattr(self):
1147 def printattr(self):
1148
1148
1149 print 'Project[%s]: name = %s, description = %s' % (self.id,
1149 print 'Project[%s]: name = %s, description = %s' % (self.id,
1150 self.name,
1150 self.name,
1151 self.description)
1151 self.description)
1152
1152
1153 for procUnitConfObj in self.procUnitConfObjDict.values():
1153 for procUnitConfObj in self.procUnitConfObjDict.values():
1154 procUnitConfObj.printattr()
1154 procUnitConfObj.printattr()
1155
1155
1156 def createObjects(self):
1156 def createObjects(self):
1157
1157
1158 for procUnitConfObj in self.procUnitConfObjDict.values():
1158 for procUnitConfObj in self.procUnitConfObjDict.values():
1159 procUnitConfObj.createObjects(self.plotterQueue)
1159 procUnitConfObj.createObjects(self.plotterQueue)
1160
1160
1161 def __connect(self, objIN, thisObj):
1161 def __connect(self, objIN, thisObj):
1162
1162
1163 thisObj.setInput(objIN.getOutputObj())
1163 thisObj.setInput(objIN.getOutputObj())
1164
1164
1165 def connectObjects(self):
1165 def connectObjects(self):
1166
1166
1167 for thisPUConfObj in self.procUnitConfObjDict.values():
1167 for thisPUConfObj in self.procUnitConfObjDict.values():
1168
1168
1169 inputId = thisPUConfObj.getInputId()
1169 inputId = thisPUConfObj.getInputId()
1170
1170
1171 if int(inputId) == 0:
1171 if int(inputId) == 0:
1172 continue
1172 continue
1173
1173
1174 # Get input object
1174 # Get input object
1175 puConfINObj = self.procUnitConfObjDict[inputId]
1175 puConfINObj = self.procUnitConfObjDict[inputId]
1176 puObjIN = puConfINObj.getProcUnitObj()
1176 puObjIN = puConfINObj.getProcUnitObj()
1177
1177
1178 # Get current object
1178 # Get current object
1179 thisPUObj = thisPUConfObj.getProcUnitObj()
1179 thisPUObj = thisPUConfObj.getProcUnitObj()
1180
1180
1181 self.__connect(puObjIN, thisPUObj)
1181 self.__connect(puObjIN, thisPUObj)
1182
1182
1183 def __handleError(self, procUnitConfObj, modes=None, stdout=True):
1183 def __handleError(self, procUnitConfObj, modes=None, stdout=True):
1184
1184
1185 import socket
1185 import socket
1186
1186
1187 if modes is None:
1187 if modes is None:
1188 modes = self.alarm
1188 modes = self.alarm
1189
1189
1190 if not self.alarm:
1191 modes = []
1192
1190 err = traceback.format_exception(sys.exc_info()[0],
1193 err = traceback.format_exception(sys.exc_info()[0],
1191 sys.exc_info()[1],
1194 sys.exc_info()[1],
1192 sys.exc_info()[2])
1195 sys.exc_info()[2])
1193
1196
1194 log.error('{}'.format(err[-1]), procUnitConfObj.name)
1197 log.error('{}'.format(err[-1]), procUnitConfObj.name)
1195
1198
1196 message = ''.join(err)
1199 message = ''.join(err)
1197
1200
1198 if stdout:
1201 if stdout:
1199 sys.stderr.write(message)
1202 sys.stderr.write(message)
1200
1203
1201 subject = 'SChain v%s: Error running %s\n' % (
1204 subject = 'SChain v%s: Error running %s\n' % (
1202 schainpy.__version__, procUnitConfObj.name)
1205 schainpy.__version__, procUnitConfObj.name)
1203
1206
1204 subtitle = '%s: %s\n' % (
1207 subtitle = '%s: %s\n' % (
1205 procUnitConfObj.getElementName(), procUnitConfObj.name)
1208 procUnitConfObj.getElementName(), procUnitConfObj.name)
1206 subtitle += 'Hostname: %s\n' % socket.gethostbyname(
1209 subtitle += 'Hostname: %s\n' % socket.gethostbyname(
1207 socket.gethostname())
1210 socket.gethostname())
1208 subtitle += 'Working directory: %s\n' % os.path.abspath('./')
1211 subtitle += 'Working directory: %s\n' % os.path.abspath('./')
1209 subtitle += 'Configuration file: %s\n' % self.filename
1212 subtitle += 'Configuration file: %s\n' % self.filename
1210 subtitle += 'Time: %s\n' % str(datetime.datetime.now())
1213 subtitle += 'Time: %s\n' % str(datetime.datetime.now())
1211
1214
1212 readUnitConfObj = self.getReadUnitObj()
1215 readUnitConfObj = self.getReadUnitObj()
1213 if readUnitConfObj:
1216 if readUnitConfObj:
1214 subtitle += '\nInput parameters:\n'
1217 subtitle += '\nInput parameters:\n'
1215 subtitle += '[Data path = %s]\n' % readUnitConfObj.path
1218 subtitle += '[Data path = %s]\n' % readUnitConfObj.path
1216 subtitle += '[Data type = %s]\n' % readUnitConfObj.datatype
1219 subtitle += '[Data type = %s]\n' % readUnitConfObj.datatype
1217 subtitle += '[Start date = %s]\n' % readUnitConfObj.startDate
1220 subtitle += '[Start date = %s]\n' % readUnitConfObj.startDate
1218 subtitle += '[End date = %s]\n' % readUnitConfObj.endDate
1221 subtitle += '[End date = %s]\n' % readUnitConfObj.endDate
1219 subtitle += '[Start time = %s]\n' % readUnitConfObj.startTime
1222 subtitle += '[Start time = %s]\n' % readUnitConfObj.startTime
1220 subtitle += '[End time = %s]\n' % readUnitConfObj.endTime
1223 subtitle += '[End time = %s]\n' % readUnitConfObj.endTime
1221
1224
1222 a = Alarm(
1225 a = Alarm(
1223 modes=modes,
1226 modes=modes,
1224 email=self.email,
1227 email=self.email,
1225 message=message,
1228 message=message,
1226 subject=subject,
1229 subject=subject,
1227 subtitle=subtitle,
1230 subtitle=subtitle,
1228 filename=self.filename
1231 filename=self.filename
1229 )
1232 )
1230
1233
1231 return a
1234 return a
1232
1235
1233 def isPaused(self):
1236 def isPaused(self):
1234 return 0
1237 return 0
1235
1238
1236 def isStopped(self):
1239 def isStopped(self):
1237 return 0
1240 return 0
1238
1241
1239 def runController(self):
1242 def runController(self):
1240 '''
1243 '''
1241 returns 0 when this process has been stopped, 1 otherwise
1244 returns 0 when this process has been stopped, 1 otherwise
1242 '''
1245 '''
1243
1246
1244 if self.isPaused():
1247 if self.isPaused():
1245 print 'Process suspended'
1248 print 'Process suspended'
1246
1249
1247 while True:
1250 while True:
1248 time.sleep(0.1)
1251 time.sleep(0.1)
1249
1252
1250 if not self.isPaused():
1253 if not self.isPaused():
1251 break
1254 break
1252
1255
1253 if self.isStopped():
1256 if self.isStopped():
1254 break
1257 break
1255
1258
1256 print 'Process reinitialized'
1259 print 'Process reinitialized'
1257
1260
1258 if self.isStopped():
1261 if self.isStopped():
1259 print 'Process stopped'
1262 print 'Process stopped'
1260 return 0
1263 return 0
1261
1264
1262 return 1
1265 return 1
1263
1266
1264 def setFilename(self, filename):
1267 def setFilename(self, filename):
1265
1268
1266 self.filename = filename
1269 self.filename = filename
1267
1270
1268 def setPlotterQueue(self, plotter_queue):
1271 def setPlotterQueue(self, plotter_queue):
1269
1272
1270 raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class'
1273 raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class'
1271
1274
1272 def getPlotterQueue(self):
1275 def getPlotterQueue(self):
1273
1276
1274 raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class'
1277 raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class'
1275
1278
1276 def useExternalPlotter(self):
1279 def useExternalPlotter(self):
1277
1280
1278 raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class'
1281 raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class'
1279
1282
1280 def run(self):
1283 def run(self):
1281
1284
1282 log.success('Starting {}'.format(self.name))
1285 log.success('Starting {}'.format(self.name))
1283 self.start_time = time.time()
1286 self.start_time = time.time()
1284 self.createObjects()
1287 self.createObjects()
1285 self.connectObjects()
1288 self.connectObjects()
1286
1289
1287 keyList = self.procUnitConfObjDict.keys()
1290 keyList = self.procUnitConfObjDict.keys()
1288 keyList.sort()
1291 keyList.sort()
1289
1292
1290 err = None
1293 err = None
1291
1294
1292 while(True):
1295 while(True):
1293
1296
1294 is_ok = False
1297 is_ok = False
1295
1298
1296 for procKey in keyList:
1299 for procKey in keyList:
1297
1300
1298 procUnitConfObj = self.procUnitConfObjDict[procKey]
1301 procUnitConfObj = self.procUnitConfObjDict[procKey]
1299
1302
1300 try:
1303 try:
1301 sts = procUnitConfObj.run()
1304 sts = procUnitConfObj.run()
1302 is_ok = is_ok or sts
1305 is_ok = is_ok or sts
1303 except SchainWarning:
1306 except SchainWarning:
1304 err = self.__handleError(procUnitConfObj, modes=[2, 3], stdout=False)
1307 err = self.__handleError(procUnitConfObj, modes=[2, 3], stdout=False)
1308 is_ok = False
1309 break
1305 except KeyboardInterrupt:
1310 except KeyboardInterrupt:
1306 is_ok = False
1311 is_ok = False
1307 break
1312 break
1308 except ValueError, e:
1313 except ValueError, e:
1309 time.sleep(0.5)
1314 time.sleep(0.5)
1310 err = self.__handleError(procUnitConfObj)
1315 err = self.__handleError(procUnitConfObj)
1311 is_ok = False
1316 is_ok = False
1312 break
1317 break
1313 except:
1318 except:
1314 time.sleep(0.5)
1319 time.sleep(0.5)
1315 err = self.__handleError(procUnitConfObj)
1320 err = self.__handleError(procUnitConfObj)
1316 is_ok = False
1321 is_ok = False
1317 break
1322 break
1318
1323
1319 # If every process unit finished so end process
1324 # If every process unit finished so end process
1320 if not(is_ok):
1325 if not(is_ok):
1321 break
1326 break
1322
1327
1323 if not self.runController():
1328 if not self.runController():
1324 break
1329 break
1325
1330
1326 # Closing every process
1331 # Closing every process
1327 for procKey in keyList:
1332 for procKey in keyList:
1328 procUnitConfObj = self.procUnitConfObjDict[procKey]
1333 procUnitConfObj = self.procUnitConfObjDict[procKey]
1329 procUnitConfObj.close()
1334 procUnitConfObj.close()
1330
1335
1331 if err is not None:
1336 if err is not None:
1332 err.start()
1337 err.start()
1333 # err.join()
1338 # err.join()
1334
1339
1335 log.success('{} finished (time: {}s)'.format(
1340 log.success('{} finished (time: {}s)'.format(
1336 self.name,
1341 self.name,
1337 time.time()-self.start_time))
1342 time.time()-self.start_time))
@@ -1,978 +1,980
1
1
2 import os
2 import os
3 import time
3 import time
4 import glob
4 import glob
5 import datetime
5 import datetime
6 from multiprocessing import Process
6 from multiprocessing import Process
7
7
8 import zmq
8 import zmq
9 import numpy
9 import numpy
10 import matplotlib
10 import matplotlib
11 import matplotlib.pyplot as plt
11 import matplotlib.pyplot as plt
12 from mpl_toolkits.axes_grid1 import make_axes_locatable
12 from mpl_toolkits.axes_grid1 import make_axes_locatable
13 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
13 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
14
14
15 from schainpy.model.proc.jroproc_base import Operation
15 from schainpy.model.proc.jroproc_base import Operation
16 from schainpy.utils import log
16 from schainpy.utils import log
17
17
18 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
18 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
19 blu_values = matplotlib.pyplot.get_cmap(
19 blu_values = matplotlib.pyplot.get_cmap(
20 'seismic_r', 20)(numpy.arange(20))[10:15]
20 'seismic_r', 20)(numpy.arange(20))[10:15]
21 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
21 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
22 'jro', numpy.vstack((blu_values, jet_values)))
22 'jro', numpy.vstack((blu_values, jet_values)))
23 matplotlib.pyplot.register_cmap(cmap=ncmap)
23 matplotlib.pyplot.register_cmap(cmap=ncmap)
24
24
25 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis', 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
25 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis', 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
26
26
27
27
28 def figpause(interval):
28 def figpause(interval):
29 backend = plt.rcParams['backend']
29 backend = plt.rcParams['backend']
30 if backend in matplotlib.rcsetup.interactive_bk:
30 if backend in matplotlib.rcsetup.interactive_bk:
31 figManager = matplotlib._pylab_helpers.Gcf.get_active()
31 figManager = matplotlib._pylab_helpers.Gcf.get_active()
32 if figManager is not None:
32 if figManager is not None:
33 canvas = figManager.canvas
33 canvas = figManager.canvas
34 if canvas.figure.stale:
34 if canvas.figure.stale:
35 canvas.draw()
35 canvas.draw()
36 try:
36 try:
37 canvas.start_event_loop(interval)
37 canvas.start_event_loop(interval)
38 except:
38 except:
39 pass
39 pass
40 return
40 return
41
41
42 def popup(message):
42 def popup(message):
43 '''
43 '''
44 '''
44 '''
45
45
46 fig = plt.figure(figsize=(12, 8), facecolor='r')
46 fig = plt.figure(figsize=(12, 8), facecolor='r')
47 text = '\n'.join([s.strip() for s in message.split(':')])
47 text = '\n'.join([s.strip() for s in message.split(':')])
48 fig.text(0.01, 0.5, text, ha='left', va='center', size='20', weight='heavy', color='w')
48 fig.text(0.01, 0.5, text, ha='left', va='center', size='20', weight='heavy', color='w')
49 fig.show()
49 fig.show()
50 figpause(1000)
50 figpause(1000)
51
51
52
52
53 class PlotData(Operation, Process):
53 class PlotData(Operation, Process):
54 '''
54 '''
55 Base class for Schain plotting operations
55 Base class for Schain plotting operations
56 '''
56 '''
57
57
58 CODE = 'Figure'
58 CODE = 'Figure'
59 colormap = 'jro'
59 colormap = 'jro'
60 bgcolor = 'white'
60 bgcolor = 'white'
61 CONFLATE = False
61 CONFLATE = False
62 __missing = 1E30
62 __missing = 1E30
63
63
64 __attrs__ = ['show', 'save', 'xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax',
64 __attrs__ = ['show', 'save', 'xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax',
65 'zlimits', 'xlabel', 'ylabel', 'xaxis','cb_label', 'title',
65 'zlimits', 'xlabel', 'ylabel', 'xaxis','cb_label', 'title',
66 'colorbar', 'bgcolor', 'width', 'height', 'localtime', 'oneFigure',
66 'colorbar', 'bgcolor', 'width', 'height', 'localtime', 'oneFigure',
67 'showprofile', 'decimation']
67 'showprofile', 'decimation']
68
68
69 def __init__(self, **kwargs):
69 def __init__(self, **kwargs):
70
70
71 Operation.__init__(self, plot=True, **kwargs)
71 Operation.__init__(self, plot=True, **kwargs)
72 Process.__init__(self)
72 Process.__init__(self)
73
73
74 self.kwargs['code'] = self.CODE
74 self.kwargs['code'] = self.CODE
75 self.mp = False
75 self.mp = False
76 self.data = None
76 self.data = None
77 self.isConfig = False
77 self.isConfig = False
78 self.figures = []
78 self.figures = []
79 self.axes = []
79 self.axes = []
80 self.cb_axes = []
80 self.cb_axes = []
81 self.localtime = kwargs.pop('localtime', True)
81 self.localtime = kwargs.pop('localtime', True)
82 self.show = kwargs.get('show', True)
82 self.show = kwargs.get('show', True)
83 self.save = kwargs.get('save', False)
83 self.save = kwargs.get('save', False)
84 self.colormap = kwargs.get('colormap', self.colormap)
84 self.colormap = kwargs.get('colormap', self.colormap)
85 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
85 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
86 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
86 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
87 self.colormaps = kwargs.get('colormaps', None)
87 self.colormaps = kwargs.get('colormaps', None)
88 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
88 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
89 self.showprofile = kwargs.get('showprofile', False)
89 self.showprofile = kwargs.get('showprofile', False)
90 self.title = kwargs.get('wintitle', self.CODE.upper())
90 self.title = kwargs.get('wintitle', self.CODE.upper())
91 self.cb_label = kwargs.get('cb_label', None)
91 self.cb_label = kwargs.get('cb_label', None)
92 self.cb_labels = kwargs.get('cb_labels', None)
92 self.cb_labels = kwargs.get('cb_labels', None)
93 self.xaxis = kwargs.get('xaxis', 'frequency')
93 self.xaxis = kwargs.get('xaxis', 'frequency')
94 self.zmin = kwargs.get('zmin', None)
94 self.zmin = kwargs.get('zmin', None)
95 self.zmax = kwargs.get('zmax', None)
95 self.zmax = kwargs.get('zmax', None)
96 self.zlimits = kwargs.get('zlimits', None)
96 self.zlimits = kwargs.get('zlimits', None)
97 self.xmin = kwargs.get('xmin', None)
97 self.xmin = kwargs.get('xmin', None)
98 self.xmax = kwargs.get('xmax', None)
98 self.xmax = kwargs.get('xmax', None)
99 self.xrange = kwargs.get('xrange', 24)
99 self.xrange = kwargs.get('xrange', 24)
100 self.ymin = kwargs.get('ymin', None)
100 self.ymin = kwargs.get('ymin', None)
101 self.ymax = kwargs.get('ymax', None)
101 self.ymax = kwargs.get('ymax', None)
102 self.xlabel = kwargs.get('xlabel', None)
102 self.xlabel = kwargs.get('xlabel', None)
103 self.decimation = kwargs.get('decimation', None)
103 self.decimation = kwargs.get('decimation', None)
104 self.showSNR = kwargs.get('showSNR', False)
104 self.showSNR = kwargs.get('showSNR', False)
105 self.oneFigure = kwargs.get('oneFigure', True)
105 self.oneFigure = kwargs.get('oneFigure', True)
106 self.width = kwargs.get('width', None)
106 self.width = kwargs.get('width', None)
107 self.height = kwargs.get('height', None)
107 self.height = kwargs.get('height', None)
108 self.colorbar = kwargs.get('colorbar', True)
108 self.colorbar = kwargs.get('colorbar', True)
109 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
109 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
110 self.titles = kwargs.get('titles', [])
110 self.titles = kwargs.get('titles', [])
111 self.polar = False
111 self.polar = False
112
112
113 def __fmtTime(self, x, pos):
113 def __fmtTime(self, x, pos):
114 '''
114 '''
115 '''
115 '''
116
116
117 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
117 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
118
118
119 def __setup(self):
119 def __setup(self):
120 '''
120 '''
121 Common setup for all figures, here figures and axes are created
121 Common setup for all figures, here figures and axes are created
122 '''
122 '''
123
123
124 if self.CODE not in self.data:
124 if self.CODE not in self.data:
125 raise ValueError(log.error('Missing data for {}'.format(self.CODE),
125 raise ValueError(log.error('Missing data for {}'.format(self.CODE),
126 self.name))
126 self.name))
127
127
128 self.setup()
128 self.setup()
129
129
130 self.time_label = 'LT' if self.localtime else 'UTC'
130 self.time_label = 'LT' if self.localtime else 'UTC'
131 if self.data.localtime:
131 if self.data.localtime:
132 self.getDateTime = datetime.datetime.fromtimestamp
132 self.getDateTime = datetime.datetime.fromtimestamp
133 else:
133 else:
134 self.getDateTime = datetime.datetime.utcfromtimestamp
134 self.getDateTime = datetime.datetime.utcfromtimestamp
135
135
136 if self.width is None:
136 if self.width is None:
137 self.width = 8
137 self.width = 8
138
138
139 self.figures = []
139 self.figures = []
140 self.axes = []
140 self.axes = []
141 self.cb_axes = []
141 self.cb_axes = []
142 self.pf_axes = []
142 self.pf_axes = []
143 self.cmaps = []
143 self.cmaps = []
144
144
145 size = '15%' if self.ncols == 1 else '30%'
145 size = '15%' if self.ncols == 1 else '30%'
146 pad = '4%' if self.ncols == 1 else '8%'
146 pad = '4%' if self.ncols == 1 else '8%'
147
147
148 if self.oneFigure:
148 if self.oneFigure:
149 if self.height is None:
149 if self.height is None:
150 self.height = 1.4 * self.nrows + 1
150 self.height = 1.4 * self.nrows + 1
151 fig = plt.figure(figsize=(self.width, self.height),
151 fig = plt.figure(figsize=(self.width, self.height),
152 edgecolor='k',
152 edgecolor='k',
153 facecolor='w')
153 facecolor='w')
154 self.figures.append(fig)
154 self.figures.append(fig)
155 for n in range(self.nplots):
155 for n in range(self.nplots):
156 ax = fig.add_subplot(self.nrows, self.ncols,
156 ax = fig.add_subplot(self.nrows, self.ncols,
157 n + 1, polar=self.polar)
157 n + 1, polar=self.polar)
158 ax.tick_params(labelsize=8)
158 ax.tick_params(labelsize=8)
159 ax.firsttime = True
159 ax.firsttime = True
160 ax.index = 0
160 ax.index = 0
161 ax.press = None
161 ax.press = None
162 self.axes.append(ax)
162 self.axes.append(ax)
163 if self.showprofile:
163 if self.showprofile:
164 cax = self.__add_axes(ax, size=size, pad=pad)
164 cax = self.__add_axes(ax, size=size, pad=pad)
165 cax.tick_params(labelsize=8)
165 cax.tick_params(labelsize=8)
166 self.pf_axes.append(cax)
166 self.pf_axes.append(cax)
167 else:
167 else:
168 if self.height is None:
168 if self.height is None:
169 self.height = 3
169 self.height = 3
170 for n in range(self.nplots):
170 for n in range(self.nplots):
171 fig = plt.figure(figsize=(self.width, self.height),
171 fig = plt.figure(figsize=(self.width, self.height),
172 edgecolor='k',
172 edgecolor='k',
173 facecolor='w')
173 facecolor='w')
174 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
174 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
175 ax.tick_params(labelsize=8)
175 ax.tick_params(labelsize=8)
176 ax.firsttime = True
176 ax.firsttime = True
177 ax.index = 0
177 ax.index = 0
178 ax.press = None
178 ax.press = None
179 self.figures.append(fig)
179 self.figures.append(fig)
180 self.axes.append(ax)
180 self.axes.append(ax)
181 if self.showprofile:
181 if self.showprofile:
182 cax = self.__add_axes(ax, size=size, pad=pad)
182 cax = self.__add_axes(ax, size=size, pad=pad)
183 cax.tick_params(labelsize=8)
183 cax.tick_params(labelsize=8)
184 self.pf_axes.append(cax)
184 self.pf_axes.append(cax)
185
185
186 for n in range(self.nrows):
186 for n in range(self.nrows):
187 if self.colormaps is not None:
187 if self.colormaps is not None:
188 cmap = plt.get_cmap(self.colormaps[n])
188 cmap = plt.get_cmap(self.colormaps[n])
189 else:
189 else:
190 cmap = plt.get_cmap(self.colormap)
190 cmap = plt.get_cmap(self.colormap)
191 cmap.set_bad(self.bgcolor, 1.)
191 cmap.set_bad(self.bgcolor, 1.)
192 self.cmaps.append(cmap)
192 self.cmaps.append(cmap)
193
193
194 for fig in self.figures:
194 for fig in self.figures:
195 fig.canvas.mpl_connect('key_press_event', self.OnKeyPress)
195 fig.canvas.mpl_connect('key_press_event', self.OnKeyPress)
196 fig.canvas.mpl_connect('scroll_event', self.OnBtnScroll)
196 fig.canvas.mpl_connect('scroll_event', self.OnBtnScroll)
197 fig.canvas.mpl_connect('button_press_event', self.onBtnPress)
197 fig.canvas.mpl_connect('button_press_event', self.onBtnPress)
198 fig.canvas.mpl_connect('motion_notify_event', self.onMotion)
198 fig.canvas.mpl_connect('motion_notify_event', self.onMotion)
199 fig.canvas.mpl_connect('button_release_event', self.onBtnRelease)
199 fig.canvas.mpl_connect('button_release_event', self.onBtnRelease)
200 if self.show:
200 if self.show:
201 fig.show()
201 fig.show()
202
202
203 def OnKeyPress(self, event):
203 def OnKeyPress(self, event):
204 '''
204 '''
205 Event for pressing keys (up, down) change colormap
205 Event for pressing keys (up, down) change colormap
206 '''
206 '''
207 ax = event.inaxes
207 ax = event.inaxes
208 if ax in self.axes:
208 if ax in self.axes:
209 if event.key == 'down':
209 if event.key == 'down':
210 ax.index += 1
210 ax.index += 1
211 elif event.key == 'up':
211 elif event.key == 'up':
212 ax.index -= 1
212 ax.index -= 1
213 if ax.index < 0:
213 if ax.index < 0:
214 ax.index = len(CMAPS) - 1
214 ax.index = len(CMAPS) - 1
215 elif ax.index == len(CMAPS):
215 elif ax.index == len(CMAPS):
216 ax.index = 0
216 ax.index = 0
217 cmap = CMAPS[ax.index]
217 cmap = CMAPS[ax.index]
218 ax.cbar.set_cmap(cmap)
218 ax.cbar.set_cmap(cmap)
219 ax.cbar.draw_all()
219 ax.cbar.draw_all()
220 ax.plt.set_cmap(cmap)
220 ax.plt.set_cmap(cmap)
221 ax.cbar.patch.figure.canvas.draw()
221 ax.cbar.patch.figure.canvas.draw()
222 self.colormap = cmap.name
222 self.colormap = cmap.name
223
223
224 def OnBtnScroll(self, event):
224 def OnBtnScroll(self, event):
225 '''
225 '''
226 Event for scrolling, scale figure
226 Event for scrolling, scale figure
227 '''
227 '''
228 cb_ax = event.inaxes
228 cb_ax = event.inaxes
229 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
229 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
230 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
230 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
231 pt = ax.cbar.ax.bbox.get_points()[:, 1]
231 pt = ax.cbar.ax.bbox.get_points()[:, 1]
232 nrm = ax.cbar.norm
232 nrm = ax.cbar.norm
233 vmin, vmax, p0, p1, pS = (
233 vmin, vmax, p0, p1, pS = (
234 nrm.vmin, nrm.vmax, pt[0], pt[1], event.y)
234 nrm.vmin, nrm.vmax, pt[0], pt[1], event.y)
235 scale = 2 if event.step == 1 else 0.5
235 scale = 2 if event.step == 1 else 0.5
236 point = vmin + (vmax - vmin) / (p1 - p0) * (pS - p0)
236 point = vmin + (vmax - vmin) / (p1 - p0) * (pS - p0)
237 ax.cbar.norm.vmin = point - scale * (point - vmin)
237 ax.cbar.norm.vmin = point - scale * (point - vmin)
238 ax.cbar.norm.vmax = point - scale * (point - vmax)
238 ax.cbar.norm.vmax = point - scale * (point - vmax)
239 ax.plt.set_norm(ax.cbar.norm)
239 ax.plt.set_norm(ax.cbar.norm)
240 ax.cbar.draw_all()
240 ax.cbar.draw_all()
241 ax.cbar.patch.figure.canvas.draw()
241 ax.cbar.patch.figure.canvas.draw()
242
242
243 def onBtnPress(self, event):
243 def onBtnPress(self, event):
244 '''
244 '''
245 Event for mouse button press
245 Event for mouse button press
246 '''
246 '''
247 cb_ax = event.inaxes
247 cb_ax = event.inaxes
248 if cb_ax is None:
248 if cb_ax is None:
249 return
249 return
250
250
251 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
251 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
252 cb_ax.press = event.x, event.y
252 cb_ax.press = event.x, event.y
253 else:
253 else:
254 cb_ax.press = None
254 cb_ax.press = None
255
255
256 def onMotion(self, event):
256 def onMotion(self, event):
257 '''
257 '''
258 Event for move inside colorbar
258 Event for move inside colorbar
259 '''
259 '''
260 cb_ax = event.inaxes
260 cb_ax = event.inaxes
261 if cb_ax is None:
261 if cb_ax is None:
262 return
262 return
263 if cb_ax not in [ax.cbar.ax for ax in self.axes if ax.cbar]:
263 if cb_ax not in [ax.cbar.ax for ax in self.axes if ax.cbar]:
264 return
264 return
265 if cb_ax.press is None:
265 if cb_ax.press is None:
266 return
266 return
267
267
268 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
268 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
269 xprev, yprev = cb_ax.press
269 xprev, yprev = cb_ax.press
270 dx = event.x - xprev
270 dx = event.x - xprev
271 dy = event.y - yprev
271 dy = event.y - yprev
272 cb_ax.press = event.x, event.y
272 cb_ax.press = event.x, event.y
273 scale = ax.cbar.norm.vmax - ax.cbar.norm.vmin
273 scale = ax.cbar.norm.vmax - ax.cbar.norm.vmin
274 perc = 0.03
274 perc = 0.03
275
275
276 if event.button == 1:
276 if event.button == 1:
277 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
277 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
278 ax.cbar.norm.vmax -= (perc * scale) * numpy.sign(dy)
278 ax.cbar.norm.vmax -= (perc * scale) * numpy.sign(dy)
279 elif event.button == 3:
279 elif event.button == 3:
280 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
280 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
281 ax.cbar.norm.vmax += (perc * scale) * numpy.sign(dy)
281 ax.cbar.norm.vmax += (perc * scale) * numpy.sign(dy)
282
282
283 ax.cbar.draw_all()
283 ax.cbar.draw_all()
284 ax.plt.set_norm(ax.cbar.norm)
284 ax.plt.set_norm(ax.cbar.norm)
285 ax.cbar.patch.figure.canvas.draw()
285 ax.cbar.patch.figure.canvas.draw()
286
286
287 def onBtnRelease(self, event):
287 def onBtnRelease(self, event):
288 '''
288 '''
289 Event for mouse button release
289 Event for mouse button release
290 '''
290 '''
291 cb_ax = event.inaxes
291 cb_ax = event.inaxes
292 if cb_ax is not None:
292 if cb_ax is not None:
293 cb_ax.press = None
293 cb_ax.press = None
294
294
295 def __add_axes(self, ax, size='30%', pad='8%'):
295 def __add_axes(self, ax, size='30%', pad='8%'):
296 '''
296 '''
297 Add new axes to the given figure
297 Add new axes to the given figure
298 '''
298 '''
299 divider = make_axes_locatable(ax)
299 divider = make_axes_locatable(ax)
300 nax = divider.new_horizontal(size=size, pad=pad)
300 nax = divider.new_horizontal(size=size, pad=pad)
301 ax.figure.add_axes(nax)
301 ax.figure.add_axes(nax)
302 return nax
302 return nax
303
303
304 self.setup()
304 self.setup()
305
305
306 def setup(self):
306 def setup(self):
307 '''
307 '''
308 This method should be implemented in the child class, the following
308 This method should be implemented in the child class, the following
309 attributes should be set:
309 attributes should be set:
310
310
311 self.nrows: number of rows
311 self.nrows: number of rows
312 self.ncols: number of cols
312 self.ncols: number of cols
313 self.nplots: number of plots (channels or pairs)
313 self.nplots: number of plots (channels or pairs)
314 self.ylabel: label for Y axes
314 self.ylabel: label for Y axes
315 self.titles: list of axes title
315 self.titles: list of axes title
316
316
317 '''
317 '''
318 raise(NotImplementedError, 'Implement this method in child class')
318 raise(NotImplementedError, 'Implement this method in child class')
319
319
320 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
320 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
321 '''
321 '''
322 Create a masked array for missing data
322 Create a masked array for missing data
323 '''
323 '''
324 if x_buffer.shape[0] < 2:
324 if x_buffer.shape[0] < 2:
325 return x_buffer, y_buffer, z_buffer
325 return x_buffer, y_buffer, z_buffer
326
326
327 deltas = x_buffer[1:] - x_buffer[0:-1]
327 deltas = x_buffer[1:] - x_buffer[0:-1]
328 x_median = numpy.median(deltas)
328 x_median = numpy.median(deltas)
329
329
330 index = numpy.where(deltas > 5 * x_median)
330 index = numpy.where(deltas > 5 * x_median)
331
331
332 if len(index[0]) != 0:
332 if len(index[0]) != 0:
333 z_buffer[::, index[0], ::] = self.__missing
333 z_buffer[::, index[0], ::] = self.__missing
334 z_buffer = numpy.ma.masked_inside(z_buffer,
334 z_buffer = numpy.ma.masked_inside(z_buffer,
335 0.99 * self.__missing,
335 0.99 * self.__missing,
336 1.01 * self.__missing)
336 1.01 * self.__missing)
337
337
338 return x_buffer, y_buffer, z_buffer
338 return x_buffer, y_buffer, z_buffer
339
339
340 def decimate(self):
340 def decimate(self):
341
341
342 # dx = int(len(self.x)/self.__MAXNUMX) + 1
342 # dx = int(len(self.x)/self.__MAXNUMX) + 1
343 dy = int(len(self.y) / self.decimation) + 1
343 dy = int(len(self.y) / self.decimation) + 1
344
344
345 # x = self.x[::dx]
345 # x = self.x[::dx]
346 x = self.x
346 x = self.x
347 y = self.y[::dy]
347 y = self.y[::dy]
348 z = self.z[::, ::, ::dy]
348 z = self.z[::, ::, ::dy]
349
349
350 return x, y, z
350 return x, y, z
351
351
352 def format(self):
352 def format(self):
353 '''
353 '''
354 Set min and max values, labels, ticks and titles
354 Set min and max values, labels, ticks and titles
355 '''
355 '''
356
356
357 if self.xmin is None:
357 if self.xmin is None:
358 xmin = self.min_time
358 xmin = self.min_time
359 else:
359 else:
360 if self.xaxis is 'time':
360 if self.xaxis is 'time':
361 dt = self.getDateTime(self.min_time)
361 dt = self.getDateTime(self.min_time)
362 xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) -
362 xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) -
363 datetime.datetime(1970, 1, 1)).total_seconds()
363 datetime.datetime(1970, 1, 1)).total_seconds()
364 if self.data.localtime:
364 if self.data.localtime:
365 xmin += time.timezone
365 xmin += time.timezone
366 else:
366 else:
367 xmin = self.xmin
367 xmin = self.xmin
368
368
369 if self.xmax is None:
369 if self.xmax is None:
370 xmax = xmin + self.xrange * 60 * 60
370 xmax = xmin + self.xrange * 60 * 60
371 else:
371 else:
372 if self.xaxis is 'time':
372 if self.xaxis is 'time':
373 dt = self.getDateTime(self.max_time)
373 dt = self.getDateTime(self.max_time)
374 xmax = (dt.replace(hour=int(self.xmax), minute=59, second=59) -
374 xmax = (dt.replace(hour=int(self.xmax), minute=59, second=59) -
375 datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds()
375 datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds()
376 if self.data.localtime:
376 if self.data.localtime:
377 xmax += time.timezone
377 xmax += time.timezone
378 else:
378 else:
379 xmax = self.xmax
379 xmax = self.xmax
380
380
381 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
381 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
382 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
382 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
383
383
384 Y = numpy.array([5, 10, 20, 50, 100, 200, 500, 1000, 2000])
384 Y = numpy.array([5, 10, 20, 50, 100, 200, 500, 1000, 2000])
385 i = 1 if numpy.where(ymax-ymin < Y)[0][0] < 0 else numpy.where(ymax-ymin < Y)[0][0]
385 i = 1 if numpy.where(ymax-ymin < Y)[0][0] < 0 else numpy.where(ymax-ymin < Y)[0][0]
386 ystep = Y[i] / 5
386 ystep = Y[i] / 5
387
387
388 for n, ax in enumerate(self.axes):
388 for n, ax in enumerate(self.axes):
389 if ax.firsttime:
389 if ax.firsttime:
390 ax.set_facecolor(self.bgcolor)
390 ax.set_facecolor(self.bgcolor)
391 ax.yaxis.set_major_locator(MultipleLocator(ystep))
391 ax.yaxis.set_major_locator(MultipleLocator(ystep))
392 if self.xaxis is 'time':
392 if self.xaxis is 'time':
393 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
393 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
394 ax.xaxis.set_major_locator(LinearLocator(9))
394 ax.xaxis.set_major_locator(LinearLocator(9))
395 if self.xlabel is not None:
395 if self.xlabel is not None:
396 ax.set_xlabel(self.xlabel)
396 ax.set_xlabel(self.xlabel)
397 ax.set_ylabel(self.ylabel)
397 ax.set_ylabel(self.ylabel)
398 ax.firsttime = False
398 ax.firsttime = False
399 if self.showprofile:
399 if self.showprofile:
400 self.pf_axes[n].set_ylim(ymin, ymax)
400 self.pf_axes[n].set_ylim(ymin, ymax)
401 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
401 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
402 self.pf_axes[n].set_xlabel('dB')
402 self.pf_axes[n].set_xlabel('dB')
403 self.pf_axes[n].grid(b=True, axis='x')
403 self.pf_axes[n].grid(b=True, axis='x')
404 [tick.set_visible(False)
404 [tick.set_visible(False)
405 for tick in self.pf_axes[n].get_yticklabels()]
405 for tick in self.pf_axes[n].get_yticklabels()]
406 if self.colorbar:
406 if self.colorbar:
407 ax.cbar = plt.colorbar(
407 ax.cbar = plt.colorbar(
408 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
408 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
409 ax.cbar.ax.tick_params(labelsize=8)
409 ax.cbar.ax.tick_params(labelsize=8)
410 ax.cbar.ax.press = None
410 ax.cbar.ax.press = None
411 if self.cb_label:
411 if self.cb_label:
412 ax.cbar.set_label(self.cb_label, size=8)
412 ax.cbar.set_label(self.cb_label, size=8)
413 elif self.cb_labels:
413 elif self.cb_labels:
414 ax.cbar.set_label(self.cb_labels[n], size=8)
414 ax.cbar.set_label(self.cb_labels[n], size=8)
415 else:
415 else:
416 ax.cbar = None
416 ax.cbar = None
417
417
418 if not self.polar:
418 if not self.polar:
419 ax.set_xlim(xmin, xmax)
419 ax.set_xlim(xmin, xmax)
420 ax.set_ylim(ymin, ymax)
420 ax.set_ylim(ymin, ymax)
421 ax.set_title('{} - {} {}'.format(
421 ax.set_title('{} - {} {}'.format(
422 self.titles[n],
422 self.titles[n],
423 self.getDateTime(self.max_time).strftime('%H:%M:%S'),
423 self.getDateTime(self.max_time).strftime('%H:%M:%S'),
424 self.time_label),
424 self.time_label),
425 size=8)
425 size=8)
426 else:
426 else:
427 ax.set_title('{}'.format(self.titles[n]), size=8)
427 ax.set_title('{}'.format(self.titles[n]), size=8)
428 ax.set_ylim(0, 90)
428 ax.set_ylim(0, 90)
429 ax.set_yticks(numpy.arange(0, 90, 20))
429 ax.set_yticks(numpy.arange(0, 90, 20))
430 ax.yaxis.labelpad = 40
430 ax.yaxis.labelpad = 40
431
431
432 def __plot(self):
432 def __plot(self):
433 '''
433 '''
434 '''
434 '''
435 log.success('Plotting', self.name)
435 log.success('Plotting', self.name)
436
436
437 try:
437 try:
438 self.plot()
438 self.plot()
439 self.format()
439 self.format()
440 except:
440 except:
441 log.warning('{} Plot could not be updated... check data'.format(self.CODE), self.name)
441 log.warning('{} Plot could not be updated... check data'.format(self.CODE), self.name)
442
442
443 for n, fig in enumerate(self.figures):
443 for n, fig in enumerate(self.figures):
444 if self.nrows == 0 or self.nplots == 0:
444 if self.nrows == 0 or self.nplots == 0:
445 log.warning('No data', self.name)
445 log.warning('No data', self.name)
446 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
446 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
447 fig.canvas.manager.set_window_title(self.CODE)
447 fig.canvas.manager.set_window_title(self.CODE)
448 continue
448 continue
449
449
450 fig.tight_layout()
450 fig.tight_layout()
451 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
451 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
452 self.getDateTime(self.max_time).strftime('%Y/%m/%d')))
452 self.getDateTime(self.max_time).strftime('%Y/%m/%d')))
453 fig.canvas.draw()
453 fig.canvas.draw()
454
454
455 if self.save and self.data.ended:
455 if self.save and self.data.ended:
456 channels = range(self.nrows)
456 channels = range(self.nrows)
457 if self.oneFigure:
457 if self.oneFigure:
458 label = ''
458 label = ''
459 else:
459 else:
460 label = '_{}'.format(channels[n])
460 label = '_{}'.format(channels[n])
461 figname = os.path.join(
461 figname = os.path.join(
462 self.save,
462 self.save,
463 '{}{}_{}.png'.format(
463 '{}{}_{}.png'.format(
464 self.CODE,
464 self.CODE,
465 label,
465 label,
466 self.getDateTime(self.saveTime).strftime(
466 self.getDateTime(self.saveTime).strftime(
467 '%Y%m%d_%H%M%S'),
467 '%Y%m%d_%H%M%S'),
468 )
468 )
469 )
469 )
470 log.log('Saving figure: {}'.format(figname), self.name)
470 log.log('Saving figure: {}'.format(figname), self.name)
471 fig.savefig(figname)
471 fig.savefig(figname)
472
472
473 def plot(self):
473 def plot(self):
474 '''
474 '''
475 '''
475 '''
476 raise(NotImplementedError, 'Implement this method in child class')
476 raise(NotImplementedError, 'Implement this method in child class')
477
477
478 def run(self):
478 def run(self):
479
479
480 log.success('Starting', self.name)
480 log.success('Starting', self.name)
481
481
482 context = zmq.Context()
482 context = zmq.Context()
483 receiver = context.socket(zmq.SUB)
483 receiver = context.socket(zmq.SUB)
484 receiver.setsockopt(zmq.SUBSCRIBE, '')
484 receiver.setsockopt(zmq.SUBSCRIBE, '')
485 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
485 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
486
486
487 if 'server' in self.kwargs['parent']:
487 if 'server' in self.kwargs['parent']:
488 receiver.connect(
488 receiver.connect(
489 'ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
489 'ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
490 else:
490 else:
491 receiver.connect("ipc:///tmp/zmq.plots")
491 receiver.connect("ipc:///tmp/zmq.plots")
492
492
493 while True:
493 while True:
494 try:
494 try:
495 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
495 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
496 if self.data.localtime and self.localtime:
496 if self.data.localtime and self.localtime:
497 self.times = self.data.times
497 self.times = self.data.times
498 elif self.data.localtime and not self.localtime:
498 elif self.data.localtime and not self.localtime:
499 self.times = self.data.times + time.timezone
499 self.times = self.data.times + time.timezone
500 elif not self.data.localtime and self.localtime:
500 elif not self.data.localtime and self.localtime:
501 self.times = self.data.times - time.timezone
501 self.times = self.data.times - time.timezone
502 else:
502 else:
503 self.times = self.data.times
503 self.times = self.data.times
504
504
505 self.min_time = self.times[0]
505 self.min_time = self.times[0]
506 self.max_time = self.times[-1]
506 self.max_time = self.times[-1]
507
507
508 if self.isConfig is False:
508 if self.isConfig is False:
509 self.__setup()
509 self.__setup()
510 self.isConfig = True
510 self.isConfig = True
511
511
512 self.__plot()
512 self.__plot()
513
513
514 except zmq.Again as e:
514 except zmq.Again as e:
515 if self.data and self.data.ended:
516 break
515 log.log('Waiting for data...')
517 log.log('Waiting for data...')
516 if self.data:
518 if self.data:
517 figpause(self.data.throttle)
519 figpause(self.data.throttle)
518 else:
520 else:
519 time.sleep(2)
521 time.sleep(2)
520
522
521 def close(self):
523 def close(self):
522 if self.data:
524 if self.data:
523 self.__plot()
525 self.__plot()
524
526
525
527
526 class PlotSpectraData(PlotData):
528 class PlotSpectraData(PlotData):
527 '''
529 '''
528 Plot for Spectra data
530 Plot for Spectra data
529 '''
531 '''
530
532
531 CODE = 'spc'
533 CODE = 'spc'
532 colormap = 'jro'
534 colormap = 'jro'
533
535
534 def setup(self):
536 def setup(self):
535 self.nplots = len(self.data.channels)
537 self.nplots = len(self.data.channels)
536 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
538 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
537 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
539 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
538 self.width = 3.4 * self.ncols
540 self.width = 3.4 * self.ncols
539 self.height = 3 * self.nrows
541 self.height = 3 * self.nrows
540 self.cb_label = 'dB'
542 self.cb_label = 'dB'
541 if self.showprofile:
543 if self.showprofile:
542 self.width += 0.8 * self.ncols
544 self.width += 0.8 * self.ncols
543
545
544 self.ylabel = 'Range [km]'
546 self.ylabel = 'Range [km]'
545
547
546 def plot(self):
548 def plot(self):
547 if self.xaxis == "frequency":
549 if self.xaxis == "frequency":
548 x = self.data.xrange[0]
550 x = self.data.xrange[0]
549 self.xlabel = "Frequency (kHz)"
551 self.xlabel = "Frequency (kHz)"
550 elif self.xaxis == "time":
552 elif self.xaxis == "time":
551 x = self.data.xrange[1]
553 x = self.data.xrange[1]
552 self.xlabel = "Time (ms)"
554 self.xlabel = "Time (ms)"
553 else:
555 else:
554 x = self.data.xrange[2]
556 x = self.data.xrange[2]
555 self.xlabel = "Velocity (m/s)"
557 self.xlabel = "Velocity (m/s)"
556
558
557 if self.CODE == 'spc_mean':
559 if self.CODE == 'spc_mean':
558 x = self.data.xrange[2]
560 x = self.data.xrange[2]
559 self.xlabel = "Velocity (m/s)"
561 self.xlabel = "Velocity (m/s)"
560
562
561 self.titles = []
563 self.titles = []
562
564
563 y = self.data.heights
565 y = self.data.heights
564 self.y = y
566 self.y = y
565 z = self.data['spc']
567 z = self.data['spc']
566
568
567 for n, ax in enumerate(self.axes):
569 for n, ax in enumerate(self.axes):
568 noise = self.data['noise'][n][-1]
570 noise = self.data['noise'][n][-1]
569 if self.CODE == 'spc_mean':
571 if self.CODE == 'spc_mean':
570 mean = self.data['mean'][n][-1]
572 mean = self.data['mean'][n][-1]
571 if ax.firsttime:
573 if ax.firsttime:
572 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
574 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
573 self.xmin = self.xmin if self.xmin else -self.xmax
575 self.xmin = self.xmin if self.xmin else -self.xmax
574 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
576 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
575 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
577 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
576 ax.plt = ax.pcolormesh(x, y, z[n].T,
578 ax.plt = ax.pcolormesh(x, y, z[n].T,
577 vmin=self.zmin,
579 vmin=self.zmin,
578 vmax=self.zmax,
580 vmax=self.zmax,
579 cmap=plt.get_cmap(self.colormap)
581 cmap=plt.get_cmap(self.colormap)
580 )
582 )
581
583
582 if self.showprofile:
584 if self.showprofile:
583 ax.plt_profile = self.pf_axes[n].plot(
585 ax.plt_profile = self.pf_axes[n].plot(
584 self.data['rti'][n][-1], y)[0]
586 self.data['rti'][n][-1], y)[0]
585 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
587 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
586 color="k", linestyle="dashed", lw=1)[0]
588 color="k", linestyle="dashed", lw=1)[0]
587 if self.CODE == 'spc_mean':
589 if self.CODE == 'spc_mean':
588 ax.plt_mean = ax.plot(mean, y, color='k')[0]
590 ax.plt_mean = ax.plot(mean, y, color='k')[0]
589 else:
591 else:
590 ax.plt.set_array(z[n].T.ravel())
592 ax.plt.set_array(z[n].T.ravel())
591 if self.showprofile:
593 if self.showprofile:
592 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
594 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
593 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
595 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
594 if self.CODE == 'spc_mean':
596 if self.CODE == 'spc_mean':
595 ax.plt_mean.set_data(mean, y)
597 ax.plt_mean.set_data(mean, y)
596
598
597 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
599 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
598 self.saveTime = self.max_time
600 self.saveTime = self.max_time
599
601
600
602
601 class PlotCrossSpectraData(PlotData):
603 class PlotCrossSpectraData(PlotData):
602
604
603 CODE = 'cspc'
605 CODE = 'cspc'
604 zmin_coh = None
606 zmin_coh = None
605 zmax_coh = None
607 zmax_coh = None
606 zmin_phase = None
608 zmin_phase = None
607 zmax_phase = None
609 zmax_phase = None
608
610
609 def setup(self):
611 def setup(self):
610
612
611 self.ncols = 4
613 self.ncols = 4
612 self.nrows = len(self.data.pairs)
614 self.nrows = len(self.data.pairs)
613 self.nplots = self.nrows * 4
615 self.nplots = self.nrows * 4
614 self.width = 3.4 * self.ncols
616 self.width = 3.4 * self.ncols
615 self.height = 3 * self.nrows
617 self.height = 3 * self.nrows
616 self.ylabel = 'Range [km]'
618 self.ylabel = 'Range [km]'
617 self.showprofile = False
619 self.showprofile = False
618
620
619 def plot(self):
621 def plot(self):
620
622
621 if self.xaxis == "frequency":
623 if self.xaxis == "frequency":
622 x = self.data.xrange[0]
624 x = self.data.xrange[0]
623 self.xlabel = "Frequency (kHz)"
625 self.xlabel = "Frequency (kHz)"
624 elif self.xaxis == "time":
626 elif self.xaxis == "time":
625 x = self.data.xrange[1]
627 x = self.data.xrange[1]
626 self.xlabel = "Time (ms)"
628 self.xlabel = "Time (ms)"
627 else:
629 else:
628 x = self.data.xrange[2]
630 x = self.data.xrange[2]
629 self.xlabel = "Velocity (m/s)"
631 self.xlabel = "Velocity (m/s)"
630
632
631 self.titles = []
633 self.titles = []
632
634
633 y = self.data.heights
635 y = self.data.heights
634 self.y = y
636 self.y = y
635 spc = self.data['spc']
637 spc = self.data['spc']
636 cspc = self.data['cspc']
638 cspc = self.data['cspc']
637
639
638 for n in range(self.nrows):
640 for n in range(self.nrows):
639 noise = self.data['noise'][n][-1]
641 noise = self.data['noise'][n][-1]
640 pair = self.data.pairs[n]
642 pair = self.data.pairs[n]
641 ax = self.axes[4 * n]
643 ax = self.axes[4 * n]
642 ax3 = self.axes[4 * n + 3]
644 ax3 = self.axes[4 * n + 3]
643 if ax.firsttime:
645 if ax.firsttime:
644 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
646 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
645 self.xmin = self.xmin if self.xmin else -self.xmax
647 self.xmin = self.xmin if self.xmin else -self.xmax
646 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
648 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
647 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
649 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
648 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
650 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
649 vmin=self.zmin,
651 vmin=self.zmin,
650 vmax=self.zmax,
652 vmax=self.zmax,
651 cmap=plt.get_cmap(self.colormap)
653 cmap=plt.get_cmap(self.colormap)
652 )
654 )
653 else:
655 else:
654 ax.plt.set_array(spc[pair[0]].T.ravel())
656 ax.plt.set_array(spc[pair[0]].T.ravel())
655 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
657 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
656
658
657 ax = self.axes[4 * n + 1]
659 ax = self.axes[4 * n + 1]
658 if ax.firsttime:
660 if ax.firsttime:
659 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
661 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
660 vmin=self.zmin,
662 vmin=self.zmin,
661 vmax=self.zmax,
663 vmax=self.zmax,
662 cmap=plt.get_cmap(self.colormap)
664 cmap=plt.get_cmap(self.colormap)
663 )
665 )
664 else:
666 else:
665 ax.plt.set_array(spc[pair[1]].T.ravel())
667 ax.plt.set_array(spc[pair[1]].T.ravel())
666 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
668 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
667
669
668 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
670 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
669 coh = numpy.abs(out)
671 coh = numpy.abs(out)
670 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
672 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
671
673
672 ax = self.axes[4 * n + 2]
674 ax = self.axes[4 * n + 2]
673 if ax.firsttime:
675 if ax.firsttime:
674 ax.plt = ax.pcolormesh(x, y, coh.T,
676 ax.plt = ax.pcolormesh(x, y, coh.T,
675 vmin=0,
677 vmin=0,
676 vmax=1,
678 vmax=1,
677 cmap=plt.get_cmap(self.colormap_coh)
679 cmap=plt.get_cmap(self.colormap_coh)
678 )
680 )
679 else:
681 else:
680 ax.plt.set_array(coh.T.ravel())
682 ax.plt.set_array(coh.T.ravel())
681 self.titles.append(
683 self.titles.append(
682 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
684 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
683
685
684 ax = self.axes[4 * n + 3]
686 ax = self.axes[4 * n + 3]
685 if ax.firsttime:
687 if ax.firsttime:
686 ax.plt = ax.pcolormesh(x, y, phase.T,
688 ax.plt = ax.pcolormesh(x, y, phase.T,
687 vmin=-180,
689 vmin=-180,
688 vmax=180,
690 vmax=180,
689 cmap=plt.get_cmap(self.colormap_phase)
691 cmap=plt.get_cmap(self.colormap_phase)
690 )
692 )
691 else:
693 else:
692 ax.plt.set_array(phase.T.ravel())
694 ax.plt.set_array(phase.T.ravel())
693 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
695 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
694
696
695 self.saveTime = self.max_time
697 self.saveTime = self.max_time
696
698
697
699
698 class PlotSpectraMeanData(PlotSpectraData):
700 class PlotSpectraMeanData(PlotSpectraData):
699 '''
701 '''
700 Plot for Spectra and Mean
702 Plot for Spectra and Mean
701 '''
703 '''
702 CODE = 'spc_mean'
704 CODE = 'spc_mean'
703 colormap = 'jro'
705 colormap = 'jro'
704
706
705
707
706 class PlotRTIData(PlotData):
708 class PlotRTIData(PlotData):
707 '''
709 '''
708 Plot for RTI data
710 Plot for RTI data
709 '''
711 '''
710
712
711 CODE = 'rti'
713 CODE = 'rti'
712 colormap = 'jro'
714 colormap = 'jro'
713
715
714 def setup(self):
716 def setup(self):
715 self.xaxis = 'time'
717 self.xaxis = 'time'
716 self.ncols = 1
718 self.ncols = 1
717 self.nrows = len(self.data.channels)
719 self.nrows = len(self.data.channels)
718 self.nplots = len(self.data.channels)
720 self.nplots = len(self.data.channels)
719 self.ylabel = 'Range [km]'
721 self.ylabel = 'Range [km]'
720 self.cb_label = 'dB'
722 self.cb_label = 'dB'
721 self.titles = ['{} Channel {}'.format(
723 self.titles = ['{} Channel {}'.format(
722 self.CODE.upper(), x) for x in range(self.nrows)]
724 self.CODE.upper(), x) for x in range(self.nrows)]
723
725
724 def plot(self):
726 def plot(self):
725 self.x = self.times
727 self.x = self.times
726 self.y = self.data.heights
728 self.y = self.data.heights
727 self.z = self.data[self.CODE]
729 self.z = self.data[self.CODE]
728 self.z = numpy.ma.masked_invalid(self.z)
730 self.z = numpy.ma.masked_invalid(self.z)
729
731
730 if self.decimation is None:
732 if self.decimation is None:
731 x, y, z = self.fill_gaps(self.x, self.y, self.z)
733 x, y, z = self.fill_gaps(self.x, self.y, self.z)
732 else:
734 else:
733 x, y, z = self.fill_gaps(*self.decimate())
735 x, y, z = self.fill_gaps(*self.decimate())
734
736
735 for n, ax in enumerate(self.axes):
737 for n, ax in enumerate(self.axes):
736 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
738 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
737 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
739 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
738 if ax.firsttime:
740 if ax.firsttime:
739 ax.plt = ax.pcolormesh(x, y, z[n].T,
741 ax.plt = ax.pcolormesh(x, y, z[n].T,
740 vmin=self.zmin,
742 vmin=self.zmin,
741 vmax=self.zmax,
743 vmax=self.zmax,
742 cmap=plt.get_cmap(self.colormap)
744 cmap=plt.get_cmap(self.colormap)
743 )
745 )
744 if self.showprofile:
746 if self.showprofile:
745 ax.plot_profile = self.pf_axes[n].plot(
747 ax.plot_profile = self.pf_axes[n].plot(
746 self.data['rti'][n][-1], self.y)[0]
748 self.data['rti'][n][-1], self.y)[0]
747 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
749 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
748 color="k", linestyle="dashed", lw=1)[0]
750 color="k", linestyle="dashed", lw=1)[0]
749 else:
751 else:
750 ax.collections.remove(ax.collections[0])
752 ax.collections.remove(ax.collections[0])
751 ax.plt = ax.pcolormesh(x, y, z[n].T,
753 ax.plt = ax.pcolormesh(x, y, z[n].T,
752 vmin=self.zmin,
754 vmin=self.zmin,
753 vmax=self.zmax,
755 vmax=self.zmax,
754 cmap=plt.get_cmap(self.colormap)
756 cmap=plt.get_cmap(self.colormap)
755 )
757 )
756 if self.showprofile:
758 if self.showprofile:
757 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
759 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
758 ax.plot_noise.set_data(numpy.repeat(
760 ax.plot_noise.set_data(numpy.repeat(
759 self.data['noise'][n][-1], len(self.y)), self.y)
761 self.data['noise'][n][-1], len(self.y)), self.y)
760
762
761 self.saveTime = self.min_time
763 self.saveTime = self.min_time
762
764
763
765
764 class PlotCOHData(PlotRTIData):
766 class PlotCOHData(PlotRTIData):
765 '''
767 '''
766 Plot for Coherence data
768 Plot for Coherence data
767 '''
769 '''
768
770
769 CODE = 'coh'
771 CODE = 'coh'
770
772
771 def setup(self):
773 def setup(self):
772 self.xaxis = 'time'
774 self.xaxis = 'time'
773 self.ncols = 1
775 self.ncols = 1
774 self.nrows = len(self.data.pairs)
776 self.nrows = len(self.data.pairs)
775 self.nplots = len(self.data.pairs)
777 self.nplots = len(self.data.pairs)
776 self.ylabel = 'Range [km]'
778 self.ylabel = 'Range [km]'
777 if self.CODE == 'coh':
779 if self.CODE == 'coh':
778 self.cb_label = ''
780 self.cb_label = ''
779 self.titles = [
781 self.titles = [
780 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
782 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
781 else:
783 else:
782 self.cb_label = 'Degrees'
784 self.cb_label = 'Degrees'
783 self.titles = [
785 self.titles = [
784 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
786 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
785
787
786
788
787 class PlotPHASEData(PlotCOHData):
789 class PlotPHASEData(PlotCOHData):
788 '''
790 '''
789 Plot for Phase map data
791 Plot for Phase map data
790 '''
792 '''
791
793
792 CODE = 'phase'
794 CODE = 'phase'
793 colormap = 'seismic'
795 colormap = 'seismic'
794
796
795
797
796 class PlotNoiseData(PlotData):
798 class PlotNoiseData(PlotData):
797 '''
799 '''
798 Plot for noise
800 Plot for noise
799 '''
801 '''
800
802
801 CODE = 'noise'
803 CODE = 'noise'
802
804
803 def setup(self):
805 def setup(self):
804 self.xaxis = 'time'
806 self.xaxis = 'time'
805 self.ncols = 1
807 self.ncols = 1
806 self.nrows = 1
808 self.nrows = 1
807 self.nplots = 1
809 self.nplots = 1
808 self.ylabel = 'Intensity [dB]'
810 self.ylabel = 'Intensity [dB]'
809 self.titles = ['Noise']
811 self.titles = ['Noise']
810 self.colorbar = False
812 self.colorbar = False
811
813
812 def plot(self):
814 def plot(self):
813
815
814 x = self.times
816 x = self.times
815 xmin = self.min_time
817 xmin = self.min_time
816 xmax = xmin + self.xrange * 60 * 60
818 xmax = xmin + self.xrange * 60 * 60
817 Y = self.data[self.CODE]
819 Y = self.data[self.CODE]
818
820
819 if self.axes[0].firsttime:
821 if self.axes[0].firsttime:
820 for ch in self.data.channels:
822 for ch in self.data.channels:
821 y = Y[ch]
823 y = Y[ch]
822 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
824 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
823 plt.legend()
825 plt.legend()
824 else:
826 else:
825 for ch in self.data.channels:
827 for ch in self.data.channels:
826 y = Y[ch]
828 y = Y[ch]
827 self.axes[0].lines[ch].set_data(x, y)
829 self.axes[0].lines[ch].set_data(x, y)
828
830
829 self.ymin = numpy.nanmin(Y) - 5
831 self.ymin = numpy.nanmin(Y) - 5
830 self.ymax = numpy.nanmax(Y) + 5
832 self.ymax = numpy.nanmax(Y) + 5
831 self.saveTime = self.min_time
833 self.saveTime = self.min_time
832
834
833
835
834 class PlotSNRData(PlotRTIData):
836 class PlotSNRData(PlotRTIData):
835 '''
837 '''
836 Plot for SNR Data
838 Plot for SNR Data
837 '''
839 '''
838
840
839 CODE = 'snr'
841 CODE = 'snr'
840 colormap = 'jet'
842 colormap = 'jet'
841
843
842
844
843 class PlotDOPData(PlotRTIData):
845 class PlotDOPData(PlotRTIData):
844 '''
846 '''
845 Plot for DOPPLER Data
847 Plot for DOPPLER Data
846 '''
848 '''
847
849
848 CODE = 'dop'
850 CODE = 'dop'
849 colormap = 'jet'
851 colormap = 'jet'
850
852
851
853
852 class PlotSkyMapData(PlotData):
854 class PlotSkyMapData(PlotData):
853 '''
855 '''
854 Plot for meteors detection data
856 Plot for meteors detection data
855 '''
857 '''
856
858
857 CODE = 'param'
859 CODE = 'param'
858
860
859 def setup(self):
861 def setup(self):
860
862
861 self.ncols = 1
863 self.ncols = 1
862 self.nrows = 1
864 self.nrows = 1
863 self.width = 7.2
865 self.width = 7.2
864 self.height = 7.2
866 self.height = 7.2
865 self.nplots = 1
867 self.nplots = 1
866 self.xlabel = 'Zonal Zenith Angle (deg)'
868 self.xlabel = 'Zonal Zenith Angle (deg)'
867 self.ylabel = 'Meridional Zenith Angle (deg)'
869 self.ylabel = 'Meridional Zenith Angle (deg)'
868 self.polar = True
870 self.polar = True
869 self.ymin = -180
871 self.ymin = -180
870 self.ymax = 180
872 self.ymax = 180
871 self.colorbar = False
873 self.colorbar = False
872
874
873 def plot(self):
875 def plot(self):
874
876
875 arrayParameters = numpy.concatenate(self.data['param'])
877 arrayParameters = numpy.concatenate(self.data['param'])
876 error = arrayParameters[:, -1]
878 error = arrayParameters[:, -1]
877 indValid = numpy.where(error == 0)[0]
879 indValid = numpy.where(error == 0)[0]
878 finalMeteor = arrayParameters[indValid, :]
880 finalMeteor = arrayParameters[indValid, :]
879 finalAzimuth = finalMeteor[:, 3]
881 finalAzimuth = finalMeteor[:, 3]
880 finalZenith = finalMeteor[:, 4]
882 finalZenith = finalMeteor[:, 4]
881
883
882 x = finalAzimuth * numpy.pi / 180
884 x = finalAzimuth * numpy.pi / 180
883 y = finalZenith
885 y = finalZenith
884
886
885 ax = self.axes[0]
887 ax = self.axes[0]
886
888
887 if ax.firsttime:
889 if ax.firsttime:
888 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
890 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
889 else:
891 else:
890 ax.plot.set_data(x, y)
892 ax.plot.set_data(x, y)
891
893
892 dt1 = self.getDateTime(self.min_time).strftime('%y/%m/%d %H:%M:%S')
894 dt1 = self.getDateTime(self.min_time).strftime('%y/%m/%d %H:%M:%S')
893 dt2 = self.getDateTime(self.max_time).strftime('%y/%m/%d %H:%M:%S')
895 dt2 = self.getDateTime(self.max_time).strftime('%y/%m/%d %H:%M:%S')
894 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
896 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
895 dt2,
897 dt2,
896 len(x))
898 len(x))
897 self.titles[0] = title
899 self.titles[0] = title
898 self.saveTime = self.max_time
900 self.saveTime = self.max_time
899
901
900
902
901 class PlotParamData(PlotRTIData):
903 class PlotParamData(PlotRTIData):
902 '''
904 '''
903 Plot for data_param object
905 Plot for data_param object
904 '''
906 '''
905
907
906 CODE = 'param'
908 CODE = 'param'
907 colormap = 'seismic'
909 colormap = 'seismic'
908
910
909 def setup(self):
911 def setup(self):
910 self.xaxis = 'time'
912 self.xaxis = 'time'
911 self.ncols = 1
913 self.ncols = 1
912 self.nrows = self.data.shape(self.CODE)[0]
914 self.nrows = self.data.shape(self.CODE)[0]
913 self.nplots = self.nrows
915 self.nplots = self.nrows
914 if self.showSNR:
916 if self.showSNR:
915 self.nrows += 1
917 self.nrows += 1
916 self.nplots += 1
918 self.nplots += 1
917
919
918 self.ylabel = 'Height [km]'
920 self.ylabel = 'Height [km]'
919 if not self.titles:
921 if not self.titles:
920 self.titles = self.data.parameters \
922 self.titles = self.data.parameters \
921 if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)]
923 if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)]
922 if self.showSNR:
924 if self.showSNR:
923 self.titles.append('SNR')
925 self.titles.append('SNR')
924
926
925 def plot(self):
927 def plot(self):
926 self.data.normalize_heights()
928 self.data.normalize_heights()
927 self.x = self.times
929 self.x = self.times
928 self.y = self.data.heights
930 self.y = self.data.heights
929 if self.showSNR:
931 if self.showSNR:
930 self.z = numpy.concatenate(
932 self.z = numpy.concatenate(
931 (self.data[self.CODE], self.data['snr'])
933 (self.data[self.CODE], self.data['snr'])
932 )
934 )
933 else:
935 else:
934 self.z = self.data[self.CODE]
936 self.z = self.data[self.CODE]
935
937
936 self.z = numpy.ma.masked_invalid(self.z)
938 self.z = numpy.ma.masked_invalid(self.z)
937
939
938 if self.decimation is None:
940 if self.decimation is None:
939 x, y, z = self.fill_gaps(self.x, self.y, self.z)
941 x, y, z = self.fill_gaps(self.x, self.y, self.z)
940 else:
942 else:
941 x, y, z = self.fill_gaps(*self.decimate())
943 x, y, z = self.fill_gaps(*self.decimate())
942
944
943 for n, ax in enumerate(self.axes):
945 for n, ax in enumerate(self.axes):
944
946
945 self.zmax = self.zmax if self.zmax is not None else numpy.max(
947 self.zmax = self.zmax if self.zmax is not None else numpy.max(
946 self.z[n])
948 self.z[n])
947 self.zmin = self.zmin if self.zmin is not None else numpy.min(
949 self.zmin = self.zmin if self.zmin is not None else numpy.min(
948 self.z[n])
950 self.z[n])
949
951
950 if ax.firsttime:
952 if ax.firsttime:
951 if self.zlimits is not None:
953 if self.zlimits is not None:
952 self.zmin, self.zmax = self.zlimits[n]
954 self.zmin, self.zmax = self.zlimits[n]
953
955
954 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
956 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
955 vmin=self.zmin,
957 vmin=self.zmin,
956 vmax=self.zmax,
958 vmax=self.zmax,
957 cmap=self.cmaps[n]
959 cmap=self.cmaps[n]
958 )
960 )
959 else:
961 else:
960 if self.zlimits is not None:
962 if self.zlimits is not None:
961 self.zmin, self.zmax = self.zlimits[n]
963 self.zmin, self.zmax = self.zlimits[n]
962 ax.collections.remove(ax.collections[0])
964 ax.collections.remove(ax.collections[0])
963 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
965 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
964 vmin=self.zmin,
966 vmin=self.zmin,
965 vmax=self.zmax,
967 vmax=self.zmax,
966 cmap=self.cmaps[n]
968 cmap=self.cmaps[n]
967 )
969 )
968
970
969 self.saveTime = self.min_time
971 self.saveTime = self.min_time
970
972
971
973
972 class PlotOutputData(PlotParamData):
974 class PlotOutputData(PlotParamData):
973 '''
975 '''
974 Plot data_output object
976 Plot data_output object
975 '''
977 '''
976
978
977 CODE = 'output'
979 CODE = 'output'
978 colormap = 'seismic'
980 colormap = 'seismic'
General Comments 0
You need to be logged in to leave comments. Login now