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