##// END OF EJS Templates
ReceiverData Operation, test PlotData
jespinoza -
r889:7897144eeb22
parent child
Show More
@@ -0,0 +1,98
1 # Byte-compiled / optimized / DLL files
2 __pycache__/
3 *.py[cod]
4 *$py.class
5
6 # C extensions
7 *.so
8
9 # Distribution / packaging
10 .Python
11 env/
12 build/
13 develop-eggs/
14 dist/
15 downloads/
16 eggs/
17 .eggs/
18 lib/
19 lib64/
20 parts/
21 sdist/
22 var/
23 wheels/
24 *.egg-info/
25 .installed.cfg
26 *.egg
27
28 # PyInstaller
29 # Usually these files are written by a python script from a template
30 # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 *.manifest
32 *.spec
33
34 # Installer logs
35 pip-log.txt
36 pip-delete-this-directory.txt
37
38 # Unit test / coverage reports
39 htmlcov/
40 .tox/
41 .coverage
42 .coverage.*
43 .cache
44 nosetests.xml
45 coverage.xml
46 *,cover
47 .hypothesis/
48
49 # Translations
50 *.mo
51 *.pot
52
53 # Django stuff:
54 *.log
55 local_settings.py
56
57 # Flask stuff:
58 instance/
59 .webassets-cache
60
61 # Scrapy stuff:
62 .scrapy
63
64 # Sphinx documentation
65 docs/_build/
66
67 # PyBuilder
68 target/
69
70 # Jupyter Notebook
71 .ipynb_checkpoints
72
73 # pyenv
74 .python-version
75
76 # celery beat schedule file
77 celerybeat-schedule
78
79 # SageMath parsed files
80 *.sage.py
81
82 # dotenv
83 .env
84
85 # virtualenv
86 .venv
87 venv/
88 ENV/
89
90 # Spyder project settings
91 .spyderproject
92 .spyproject
93
94 # Rope project settings
95 .ropeproject
96
97 # mkdocs documentation
98 /site
@@ -0,0 +1,42
1 #!/usr/bin/env python
2 '''
3 Created on Jul 7, 2014
4
5 @author: roj-idl71
6 '''
7 import os, sys
8
9 from schainpy.controller import Project
10
11 if __name__ == '__main__':
12 desc = "Segundo Test"
13
14 controllerObj = Project()
15 controllerObj.setup(id = '191', name='test01', description=desc)
16
17 proc1 = controllerObj.addProcUnit(name='ReceiverData')
18 # proc1.addParameter(name='server', value='tcp://10.10.10.87:3000', format='str')
19 proc1.addParameter(name='realtime', value='1', format='bool')
20 proc1.addParameter(name='plottypes', value='rti,spc', format='str')
21
22 op1 = proc1.addOperation(name='PlotRTIData', optype='other')
23 op1.addParameter(name='wintitle', value='Julia 150Km', format='str')
24
25 op2 = proc1.addOperation(name='PlotSpectraData', optype='other')
26 op2.addParameter(name='wintitle', value='Julia 150Km', format='str')
27 op2.addParameter(name='xaxis', value='velocity', format='str')
28 op2.addParameter(name='showprofile', value='1', format='bool')
29 #op2.addParameter(name='xmin', value='-0.1', format='float')
30 #op2.addParameter(name='xmax', value='0.1', format='float')
31
32 # op1 = proc1.addOperation(name='PlotPHASEData', optype='other')
33 # op1.addParameter(name='wintitle', value='Julia 150Km', format='str')
34
35
36 # proc1 = controllerObj.addProcUnit(name='ReceiverData')
37 # proc1.addParameter(name='server', value='pipe2', format='str')
38 # proc1.addParameter(name='mode', value='buffer', format='str')
39 # proc1.addParameter(name='plottypes', value='snr', format='str')
40
41
42 controllerObj.start()
@@ -1,1294 +1,1261
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 schainpy
11 11 import schainpy.admin
12 12
13 13 from xml.etree.ElementTree import ElementTree, Element, SubElement, tostring
14 14 from xml.dom import minidom
15 15
16 16 from schainpy.model import *
17 17 from time import sleep
18 18
19 19 def prettify(elem):
20 20 """Return a pretty-printed XML string for the Element.
21 21 """
22 22 rough_string = tostring(elem, 'utf-8')
23 23 reparsed = minidom.parseString(rough_string)
24 24 return reparsed.toprettyxml(indent=" ")
25 25
26 26 class ParameterConf():
27 27
28 28 id = None
29 29 name = None
30 30 value = None
31 31 format = None
32 32
33 33 __formated_value = None
34 34
35 35 ELEMENTNAME = 'Parameter'
36 36
37 37 def __init__(self):
38 38
39 39 self.format = 'str'
40 40
41 41 def getElementName(self):
42 42
43 43 return self.ELEMENTNAME
44 44
45 45 def getValue(self):
46 46
47 47 value = self.value
48 48 format = self.format
49 49
50 50 if self.__formated_value != None:
51 51
52 52 return self.__formated_value
53 53
54 54 if format == 'str':
55 55 self.__formated_value = str(value)
56 56 return self.__formated_value
57 57
58 58 if value == '':
59 59 raise ValueError, "%s: This parameter value is empty" %self.name
60 60
61 61 if format == 'list':
62 62 strList = value.split(',')
63 63
64 64 self.__formated_value = strList
65 65
66 66 return self.__formated_value
67 67
68 68 if format == 'intlist':
69 69 """
70 70 Example:
71 71 value = (0,1,2)
72 72 """
73 73
74 74 new_value = ast.literal_eval(value)
75 75
76 76 if type(new_value) not in (tuple, list):
77 77 new_value = [int(new_value)]
78 78
79 79 self.__formated_value = new_value
80 80
81 81 return self.__formated_value
82 82
83 83 if format == 'floatlist':
84 84 """
85 85 Example:
86 86 value = (0.5, 1.4, 2.7)
87 87 """
88 88
89 89 new_value = ast.literal_eval(value)
90 90
91 91 if type(new_value) not in (tuple, list):
92 92 new_value = [float(new_value)]
93 93
94 94 self.__formated_value = new_value
95 95
96 96 return self.__formated_value
97 97
98 98 if format == 'date':
99 99 strList = value.split('/')
100 100 intList = [int(x) for x in strList]
101 101 date = datetime.date(intList[0], intList[1], intList[2])
102 102
103 103 self.__formated_value = date
104 104
105 105 return self.__formated_value
106 106
107 107 if format == 'time':
108 108 strList = value.split(':')
109 109 intList = [int(x) for x in strList]
110 110 time = datetime.time(intList[0], intList[1], intList[2])
111 111
112 112 self.__formated_value = time
113 113
114 114 return self.__formated_value
115 115
116 116 if format == 'pairslist':
117 117 """
118 118 Example:
119 119 value = (0,1),(1,2)
120 120 """
121 121
122 122 new_value = ast.literal_eval(value)
123 123
124 124 if type(new_value) not in (tuple, list):
125 125 raise ValueError, "%s has to be a tuple or list of pairs" %value
126 126
127 127 if type(new_value[0]) not in (tuple, list):
128 128 if len(new_value) != 2:
129 129 raise ValueError, "%s has to be a tuple or list of pairs" %value
130 130 new_value = [new_value]
131 131
132 132 for thisPair in new_value:
133 133 if len(thisPair) != 2:
134 134 raise ValueError, "%s has to be a tuple or list of pairs" %value
135 135
136 136 self.__formated_value = new_value
137 137
138 138 return self.__formated_value
139 139
140 140 if format == 'multilist':
141 141 """
142 142 Example:
143 143 value = (0,1,2),(3,4,5)
144 144 """
145 145 multiList = ast.literal_eval(value)
146 146
147 147 if type(multiList[0]) == int:
148 148 multiList = ast.literal_eval("(" + value + ")")
149 149
150 150 self.__formated_value = multiList
151 151
152 152 return self.__formated_value
153 153
154 154 if format == 'bool':
155 155 value = int(value)
156 156
157 157 if format == 'int':
158 158 value = float(value)
159 159
160 160 format_func = eval(format)
161 161
162 162 self.__formated_value = format_func(value)
163 163
164 164 return self.__formated_value
165 165
166 166 def updateId(self, new_id):
167 167
168 168 self.id = str(new_id)
169 169
170 170 def setup(self, id, name, value, format='str'):
171 171
172 172 self.id = str(id)
173 173 self.name = name
174 174 self.value = str(value)
175 175 self.format = str.lower(format)
176 176
177 177 self.getValue()
178 178
179 179 return 1
180 180
181 181 def update(self, name, value, format='str'):
182 182
183 183 self.name = name
184 184 self.value = str(value)
185 185 self.format = format
186 186
187 187 def makeXml(self, opElement):
188 188
189 189 parmElement = SubElement(opElement, self.ELEMENTNAME)
190 190 parmElement.set('id', str(self.id))
191 191 parmElement.set('name', self.name)
192 192 parmElement.set('value', self.value)
193 193 parmElement.set('format', self.format)
194 194
195 195 def readXml(self, parmElement):
196 196
197 197 self.id = parmElement.get('id')
198 198 self.name = parmElement.get('name')
199 199 self.value = parmElement.get('value')
200 200 self.format = str.lower(parmElement.get('format'))
201 201
202 202 #Compatible with old signal chain version
203 203 if self.format == 'int' and self.name == 'idfigure':
204 204 self.name = 'id'
205 205
206 206 def printattr(self):
207 207
208 208 print "Parameter[%s]: name = %s, value = %s, format = %s" %(self.id, self.name, self.value, self.format)
209 209
210 210 class OperationConf():
211 211
212 212 id = None
213 213 name = None
214 214 priority = None
215 215 type = None
216 216
217 217 parmConfObjList = []
218 218
219 219 ELEMENTNAME = 'Operation'
220 220
221 221 def __init__(self):
222 222
223 223 self.id = '0'
224 224 self.name = None
225 225 self.priority = None
226 226 self.type = 'self'
227 227
228 228
229 229 def __getNewId(self):
230 230
231 231 return int(self.id)*10 + len(self.parmConfObjList) + 1
232 232
233 233 def updateId(self, new_id):
234 234
235 235 self.id = str(new_id)
236 236
237 237 n = 1
238 238 for parmObj in self.parmConfObjList:
239 239
240 240 idParm = str(int(new_id)*10 + n)
241 241 parmObj.updateId(idParm)
242 242
243 243 n += 1
244 244
245 245 def getElementName(self):
246 246
247 247 return self.ELEMENTNAME
248 248
249 249 def getParameterObjList(self):
250 250
251 251 return self.parmConfObjList
252 252
253 253 def getParameterObj(self, parameterName):
254 254
255 255 for parmConfObj in self.parmConfObjList:
256 256
257 257 if parmConfObj.name != parameterName:
258 258 continue
259 259
260 260 return parmConfObj
261 261
262 262 return None
263 263
264 264 def getParameterObjfromValue(self, parameterValue):
265 265
266 266 for parmConfObj in self.parmConfObjList:
267 267
268 268 if parmConfObj.getValue() != parameterValue:
269 269 continue
270 270
271 271 return parmConfObj.getValue()
272 272
273 273 return None
274 274
275 275 def getParameterValue(self, parameterName):
276 276
277 277 parameterObj = self.getParameterObj(parameterName)
278 278
279 279 # if not parameterObj:
280 280 # return None
281 281
282 282 value = parameterObj.getValue()
283 283
284 284 return value
285 285
286
287 def getKwargs(self):
288
289 kwargs = {}
290
291 for parmConfObj in self.parmConfObjList:
292 if self.name == 'run' and parmConfObj.name == 'datatype':
293 continue
294
295 kwargs[parmConfObj.name] = parmConfObj.getValue()
296
297 return kwargs
298
286 299 def setup(self, id, name, priority, type):
287 300
288 301 self.id = str(id)
289 302 self.name = name
290 303 self.type = type
291 304 self.priority = priority
292 305
293 306 self.parmConfObjList = []
294 307
295 308 def removeParameters(self):
296 309
297 310 for obj in self.parmConfObjList:
298 311 del obj
299 312
300 313 self.parmConfObjList = []
301 314
302 315 def addParameter(self, name, value, format='str'):
303 316
304 317 id = self.__getNewId()
305 318
306 319 parmConfObj = ParameterConf()
307 320 if not parmConfObj.setup(id, name, value, format):
308 321 return None
309 322
310 323 self.parmConfObjList.append(parmConfObj)
311 324
312 325 return parmConfObj
313 326
314 327 def changeParameter(self, name, value, format='str'):
315 328
316 329 parmConfObj = self.getParameterObj(name)
317 330 parmConfObj.update(name, value, format)
318 331
319 332 return parmConfObj
320 333
321 334 def makeXml(self, procUnitElement):
322 335
323 336 opElement = SubElement(procUnitElement, self.ELEMENTNAME)
324 337 opElement.set('id', str(self.id))
325 338 opElement.set('name', self.name)
326 339 opElement.set('type', self.type)
327 340 opElement.set('priority', str(self.priority))
328 341
329 342 for parmConfObj in self.parmConfObjList:
330 343 parmConfObj.makeXml(opElement)
331 344
332 345 def readXml(self, opElement):
333 346
334 347 self.id = opElement.get('id')
335 348 self.name = opElement.get('name')
336 349 self.type = opElement.get('type')
337 350 self.priority = opElement.get('priority')
338 351
339 352 #Compatible with old signal chain version
340 353 #Use of 'run' method instead 'init'
341 354 if self.type == 'self' and self.name == 'init':
342 355 self.name = 'run'
343 356
344 357 self.parmConfObjList = []
345 358
346 359 parmElementList = opElement.iter(ParameterConf().getElementName())
347 360
348 361 for parmElement in parmElementList:
349 362 parmConfObj = ParameterConf()
350 363 parmConfObj.readXml(parmElement)
351 364
352 365 #Compatible with old signal chain version
353 366 #If an 'plot' OPERATION is found, changes name operation by the value of its type PARAMETER
354 367 if self.type != 'self' and self.name == 'Plot':
355 368 if parmConfObj.format == 'str' and parmConfObj.name == 'type':
356 369 self.name = parmConfObj.value
357 370 continue
358 371
359 372 self.parmConfObjList.append(parmConfObj)
360 373
361 374 def printattr(self):
362 375
363 376 print "%s[%s]: name = %s, type = %s, priority = %s" %(self.ELEMENTNAME,
364 377 self.id,
365 378 self.name,
366 379 self.type,
367 380 self.priority)
368 381
369 382 for parmConfObj in self.parmConfObjList:
370 383 parmConfObj.printattr()
371 384
372 385 def createObject(self, plotter_queue=None):
373 386
374 387 if self.type == 'self':
375 388 raise ValueError, "This operation type cannot be created"
376 389
377 390 if self.type == 'plotter':
378 391 #Plotter(plotter_name)
379 392 if not plotter_queue:
380 393 raise ValueError, "plotter_queue is not defined. Use:\nmyProject = Project()\nmyProject.setPlotterQueue(plotter_queue)"
381 394
382 395 opObj = Plotter(self.name, plotter_queue)
383 396
384 397 if self.type == 'external' or self.type == 'other':
385 398 className = eval(self.name)
386 opObj = className()
399 kwargs = self.getKwargs()
400 opObj = className(**kwargs)
387 401
388 402 return opObj
389 403
404
390 405 class ProcUnitConf():
391 406
392 407 id = None
393 408 name = None
394 409 datatype = None
395 410 inputId = None
396 411 parentId = None
397 412
398 413 opConfObjList = []
399 414
400 415 procUnitObj = None
401 416 opObjList = []
402 417
403 418 ELEMENTNAME = 'ProcUnit'
404 419
405 420 def __init__(self):
406 421
407 422 self.id = None
408 423 self.datatype = None
409 424 self.name = None
410 425 self.inputId = None
411 426
412 427 self.opConfObjList = []
413 428
414 429 self.procUnitObj = None
415 430 self.opObjDict = {}
416 431
417 432 def __getPriority(self):
418 433
419 434 return len(self.opConfObjList)+1
420 435
421 436 def __getNewId(self):
422 437
423 438 return int(self.id)*10 + len(self.opConfObjList) + 1
424 439
425 440 def getElementName(self):
426 441
427 442 return self.ELEMENTNAME
428 443
429 444 def getId(self):
430 445
431 446 return self.id
432 447
433 448 def updateId(self, new_id, parentId=parentId):
434 449
435 450
436 451 new_id = int(parentId)*10 + (int(self.id) % 10)
437 452 new_inputId = int(parentId)*10 + (int(self.inputId) % 10)
438 453
439 454 #If this proc unit has not inputs
440 455 if self.inputId == '0':
441 456 new_inputId = 0
442 457
443 458 n = 1
444 459 for opConfObj in self.opConfObjList:
445 460
446 461 idOp = str(int(new_id)*10 + n)
447 462 opConfObj.updateId(idOp)
448 463
449 464 n += 1
450 465
451 466 self.parentId = str(parentId)
452 467 self.id = str(new_id)
453 468 self.inputId = str(new_inputId)
454 469
455 470
456 471 def getInputId(self):
457 472
458 473 return self.inputId
459 474
460 475 def getOperationObjList(self):
461 476
462 477 return self.opConfObjList
463 478
464 479 def getOperationObj(self, name=None):
465 480
466 481 for opConfObj in self.opConfObjList:
467 482
468 483 if opConfObj.name != name:
469 484 continue
470 485
471 486 return opConfObj
472 487
473 488 return None
474 489
475 490 def getOpObjfromParamValue(self, value=None):
476 491
477 492 for opConfObj in self.opConfObjList:
478 493 if opConfObj.getParameterObjfromValue(parameterValue=value) != value:
479 494 continue
480 495 return opConfObj
481 496 return None
482 497
483 498 def getProcUnitObj(self):
484 499
485 500 return self.procUnitObj
486 501
487 502 def setup(self, id, name, datatype, inputId, parentId=None):
488 503
489 504 #Compatible with old signal chain version
490 505 if datatype==None and name==None:
491 506 raise ValueError, "datatype or name should be defined"
492 507
493 508 if name==None:
494 509 if 'Proc' in datatype:
495 510 name = datatype
496 511 else:
497 512 name = '%sProc' %(datatype)
498 513
499 514 if datatype==None:
500 515 datatype = name.replace('Proc','')
501 516
502 517 self.id = str(id)
503 518 self.name = name
504 519 self.datatype = datatype
505 520 self.inputId = inputId
506 521 self.parentId = parentId
507 522
508 523 self.opConfObjList = []
509 524
510 525 self.addOperation(name='run', optype='self')
511 526
512 527 def removeOperations(self):
513 528
514 529 for obj in self.opConfObjList:
515 530 del obj
516 531
517 532 self.opConfObjList = []
518 533 self.addOperation(name='run')
519 534
520 535 def addParameter(self, **kwargs):
521 536 '''
522 537 Add parameters to "run" operation
523 538 '''
524 539 opObj = self.opConfObjList[0]
525 540
526 541 opObj.addParameter(**kwargs)
527 542
528 543 return opObj
529 544
530 545 def addOperation(self, name, optype='self'):
531 546
532 547 id = self.__getNewId()
533 548 priority = self.__getPriority()
534 549
535 550 opConfObj = OperationConf()
536 551 opConfObj.setup(id, name=name, priority=priority, type=optype)
537 552
538 553 self.opConfObjList.append(opConfObj)
539 554
540 555 return opConfObj
541 556
542 557 def makeXml(self, projectElement):
543 558
544 559 procUnitElement = SubElement(projectElement, self.ELEMENTNAME)
545 560 procUnitElement.set('id', str(self.id))
546 561 procUnitElement.set('name', self.name)
547 562 procUnitElement.set('datatype', self.datatype)
548 563 procUnitElement.set('inputId', str(self.inputId))
549 564
550 565 for opConfObj in self.opConfObjList:
551 566 opConfObj.makeXml(procUnitElement)
552 567
553 568 def readXml(self, upElement):
554 569
555 570 self.id = upElement.get('id')
556 571 self.name = upElement.get('name')
557 572 self.datatype = upElement.get('datatype')
558 573 self.inputId = upElement.get('inputId')
559 574
560 575 if self.ELEMENTNAME == "ReadUnit":
561 576 self.datatype = self.datatype.replace("Reader", "")
562 577
563 578 if self.ELEMENTNAME == "ProcUnit":
564 579 self.datatype = self.datatype.replace("Proc", "")
565 580
566 581 if self.inputId == 'None':
567 582 self.inputId = '0'
568 583
569 584 self.opConfObjList = []
570 585
571 586 opElementList = upElement.iter(OperationConf().getElementName())
572 587
573 588 for opElement in opElementList:
574 589 opConfObj = OperationConf()
575 590 opConfObj.readXml(opElement)
576 591 self.opConfObjList.append(opConfObj)
577 592
578 593 def printattr(self):
579 594
580 595 print "%s[%s]: name = %s, datatype = %s, inputId = %s" %(self.ELEMENTNAME,
581 596 self.id,
582 597 self.name,
583 598 self.datatype,
584 599 self.inputId)
585 600
586 601 for opConfObj in self.opConfObjList:
587 602 opConfObj.printattr()
588 603
604
605 def getKwargs(self):
606
607 opObj = self.opConfObjList[0]
608 kwargs = opObj.getKwargs()
609
610 return kwargs
611
589 612 def createObjects(self, plotter_queue=None):
590 613
591 614 className = eval(self.name)
592 procUnitObj = className()
615 kwargs = self.getKwargs()
616 procUnitObj = className(**kwargs)
593 617
594 618 for opConfObj in self.opConfObjList:
595 619
596 620 if opConfObj.type == 'self':
597 621 continue
598 622
599 623 opObj = opConfObj.createObject(plotter_queue)
600 624
601 625 self.opObjDict[opConfObj.id] = opObj
602 626 procUnitObj.addOperation(opObj, opConfObj.id)
603 627
604 628 self.procUnitObj = procUnitObj
605 629
606 630 return procUnitObj
607 631
608 632 def run(self):
609 633
610 634 is_ok = False
611 635
612 636 for opConfObj in self.opConfObjList:
613 637
614 638 kwargs = {}
615 639 for parmConfObj in opConfObj.getParameterObjList():
616 640 if opConfObj.name == 'run' and parmConfObj.name == 'datatype':
617 641 continue
618 642
619 643 kwargs[parmConfObj.name] = parmConfObj.getValue()
620 644
621 645 #ini = time.time()
622 646
623 647 #print "\tRunning the '%s' operation with %s" %(opConfObj.name, opConfObj.id)
624 648 sts = self.procUnitObj.call(opType = opConfObj.type,
625 649 opName = opConfObj.name,
626 650 opId = opConfObj.id,
627 **kwargs)
651 )
628 652
629 653 # total_time = time.time() - ini
630 654 #
631 655 # if total_time > 0.002:
632 656 # print "%s::%s took %f seconds" %(self.name, opConfObj.name, total_time)
633 657
634 658 is_ok = is_ok or sts
635 659
636 660 return is_ok
637 661
638 662 def close(self):
639 663
640 664 for opConfObj in self.opConfObjList:
641 665 if opConfObj.type == 'self':
642 666 continue
643 667
644 668 opObj = self.procUnitObj.getOperationObj(opConfObj.id)
645 669 opObj.close()
646 670
647 671 self.procUnitObj.close()
648 672
649 673 return
650 674
651 675 class ReadUnitConf(ProcUnitConf):
652 676
653 677 path = None
654 678 startDate = None
655 679 endDate = None
656 680 startTime = None
657 681 endTime = None
658 682
659 683 ELEMENTNAME = 'ReadUnit'
660 684
661 685 def __init__(self):
662 686
663 687 self.id = None
664 688 self.datatype = None
665 689 self.name = None
666 690 self.inputId = None
667 691
668 692 self.parentId = None
669 693
670 694 self.opConfObjList = []
671 695 self.opObjList = []
672 696
673 697 def getElementName(self):
674 698
675 699 return self.ELEMENTNAME
676 700
677 701 def setup(self, id, name, datatype, path, startDate="", endDate="", startTime="", endTime="", parentId=None, **kwargs):
678 702
679 703 #Compatible with old signal chain version
680 704 if datatype==None and name==None:
681 705 raise ValueError, "datatype or name should be defined"
682 706
683 707 if name==None:
684 708 if 'Reader' in datatype:
685 709 name = datatype
686 710 else:
687 711 name = '%sReader' %(datatype)
688 712
689 713 if datatype==None:
690 714 datatype = name.replace('Reader','')
691 715
692 716 self.id = id
693 717 self.name = name
694 718 self.datatype = datatype
695 719
696 720 self.path = os.path.abspath(path)
697 721 self.startDate = startDate
698 722 self.endDate = endDate
699 723 self.startTime = startTime
700 724 self.endTime = endTime
701 725
702 726 self.inputId = '0'
703 727 self.parentId = parentId
704 728
705 729 self.addRunOperation(**kwargs)
706 730
707 731 def update(self, datatype, path, startDate, endDate, startTime, endTime, parentId=None, name=None, **kwargs):
708 732
709 733 #Compatible with old signal chain version
710 734 if datatype==None and name==None:
711 735 raise ValueError, "datatype or name should be defined"
712 736
713 737 if name==None:
714 738 if 'Reader' in datatype:
715 739 name = datatype
716 740 else:
717 741 name = '%sReader' %(datatype)
718 742
719 743 if datatype==None:
720 744 datatype = name.replace('Reader','')
721 745
722 746 self.datatype = datatype
723 747 self.name = name
724 748 self.path = path
725 749 self.startDate = startDate
726 750 self.endDate = endDate
727 751 self.startTime = startTime
728 752 self.endTime = endTime
729 753
730 754 self.inputId = '0'
731 755 self.parentId = parentId
732 756
733 757 self.updateRunOperation(**kwargs)
734 758
735 759 def removeOperations(self):
736 760
737 761 for obj in self.opConfObjList:
738 762 del obj
739 763
740 764 self.opConfObjList = []
741 765
742 766 def addRunOperation(self, **kwargs):
743 767
744 768 opObj = self.addOperation(name = 'run', optype = 'self')
745 769
746 770 opObj.addParameter(name='datatype' , value=self.datatype, format='str')
747 771 opObj.addParameter(name='path' , value=self.path, format='str')
748 772 opObj.addParameter(name='startDate' , value=self.startDate, format='date')
749 773 opObj.addParameter(name='endDate' , value=self.endDate, format='date')
750 774 opObj.addParameter(name='startTime' , value=self.startTime, format='time')
751 775 opObj.addParameter(name='endTime' , value=self.endTime, format='time')
752 776
753 777 for key, value in kwargs.items():
754 778 opObj.addParameter(name=key, value=value, format=type(value).__name__)
755 779
756 780 return opObj
757 781
758 782 def updateRunOperation(self, **kwargs):
759 783
760 784 opObj = self.getOperationObj(name = 'run')
761 785 opObj.removeParameters()
762 786
763 787 opObj.addParameter(name='datatype' , value=self.datatype, format='str')
764 788 opObj.addParameter(name='path' , value=self.path, format='str')
765 789 opObj.addParameter(name='startDate' , value=self.startDate, format='date')
766 790 opObj.addParameter(name='endDate' , value=self.endDate, format='date')
767 791 opObj.addParameter(name='startTime' , value=self.startTime, format='time')
768 792 opObj.addParameter(name='endTime' , value=self.endTime, format='time')
769 793
770 794 for key, value in kwargs.items():
771 795 opObj.addParameter(name=key, value=value, format=type(value).__name__)
772 796
773 797 return opObj
774 798
775 799 # def makeXml(self, projectElement):
776 800 #
777 801 # procUnitElement = SubElement(projectElement, self.ELEMENTNAME)
778 802 # procUnitElement.set('id', str(self.id))
779 803 # procUnitElement.set('name', self.name)
780 804 # procUnitElement.set('datatype', self.datatype)
781 805 # procUnitElement.set('inputId', str(self.inputId))
782 806 #
783 807 # for opConfObj in self.opConfObjList:
784 808 # opConfObj.makeXml(procUnitElement)
785 809
786 810 def readXml(self, upElement):
787 811
788 812 self.id = upElement.get('id')
789 813 self.name = upElement.get('name')
790 814 self.datatype = upElement.get('datatype')
791 815 self.inputId = upElement.get('inputId')
792 816
793 817 if self.ELEMENTNAME == "ReadUnit":
794 818 self.datatype = self.datatype.replace("Reader", "")
795 819
796 820 if self.inputId == 'None':
797 821 self.inputId = '0'
798 822
799 823 self.opConfObjList = []
800 824
801 825 opElementList = upElement.iter(OperationConf().getElementName())
802 826
803 827 for opElement in opElementList:
804 828 opConfObj = OperationConf()
805 829 opConfObj.readXml(opElement)
806 830 self.opConfObjList.append(opConfObj)
807 831
808 832 if opConfObj.name == 'run':
809 833 self.path = opConfObj.getParameterValue('path')
810 834 self.startDate = opConfObj.getParameterValue('startDate')
811 835 self.endDate = opConfObj.getParameterValue('endDate')
812 836 self.startTime = opConfObj.getParameterValue('startTime')
813 837 self.endTime = opConfObj.getParameterValue('endTime')
814 838
815 839 class Project():
816 840
817 841 id = None
818 842 name = None
819 843 description = None
820 844 filename = None
821 845
822 846 procUnitConfObjDict = None
823 847
824 848 ELEMENTNAME = 'Project'
825 849
826 850 plotterQueue = None
827 851
828 852 def __init__(self, plotter_queue=None):
829 853
830 854 self.id = None
831 855 self.name = None
832 856 self.description = None
833 857
834 858 self.plotterQueue = plotter_queue
835 859
836 860 self.procUnitConfObjDict = {}
837 861
838 862 def __getNewId(self):
839 863
840 864 idList = self.procUnitConfObjDict.keys()
841 865
842 866 id = int(self.id)*10
843 867
844 868 while True:
845 869 id += 1
846 870
847 871 if str(id) in idList:
848 872 continue
849 873
850 874 break
851 875
852 876 return str(id)
853 877
854 878 def getElementName(self):
855 879
856 880 return self.ELEMENTNAME
857 881
858 882 def getId(self):
859 883
860 884 return self.id
861 885
862 886 def updateId(self, new_id):
863 887
864 888 self.id = str(new_id)
865 889
866 890 keyList = self.procUnitConfObjDict.keys()
867 891 keyList.sort()
868 892
869 893 n = 1
870 894 newProcUnitConfObjDict = {}
871 895
872 896 for procKey in keyList:
873 897
874 898 procUnitConfObj = self.procUnitConfObjDict[procKey]
875 899 idProcUnit = str(int(self.id)*10 + n)
876 900 procUnitConfObj.updateId(idProcUnit, parentId = self.id)
877 901
878 902 newProcUnitConfObjDict[idProcUnit] = procUnitConfObj
879 903 n += 1
880 904
881 905 self.procUnitConfObjDict = newProcUnitConfObjDict
882 906
883 907 def setup(self, id, name, description):
884 908
885 909 self.id = str(id)
886 910 self.name = name
887 911 self.description = description
888 912
889 913 def update(self, name, description):
890 914
891 915 self.name = name
892 916 self.description = description
893 917
894 918 def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
895 919
896 920 if id is None:
897 921 idReadUnit = self.__getNewId()
898 922 else:
899 923 idReadUnit = str(id)
900 924
901 925 readUnitConfObj = ReadUnitConf()
902 926 readUnitConfObj.setup(idReadUnit, name, datatype, parentId=self.id, **kwargs)
903 927
904 928 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
905 929
906 930 return readUnitConfObj
907 931
908 932 def addProcUnit(self, inputId='0', datatype=None, name=None):
909 933
910 934 idProcUnit = self.__getNewId()
911 935
912 936 procUnitConfObj = ProcUnitConf()
913 937 procUnitConfObj.setup(idProcUnit, name, datatype, inputId, parentId=self.id)
914 938
915 939 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
916 940
917 941 return procUnitConfObj
918 942
919 943 def removeProcUnit(self, id):
920 944
921 945 if id in self.procUnitConfObjDict.keys():
922 946 self.procUnitConfObjDict.pop(id)
923 947
924 948 def getReadUnitId(self):
925 949
926 950 readUnitConfObj = self.getReadUnitObj()
927 951
928 952 return readUnitConfObj.id
929 953
930 954 def getReadUnitObj(self):
931 955
932 956 for obj in self.procUnitConfObjDict.values():
933 957 if obj.getElementName() == "ReadUnit":
934 958 return obj
935 959
936 960 return None
937 961
938 962 def getProcUnitObj(self, id=None, name=None):
939 963
940 964 if id != None:
941 965 return self.procUnitConfObjDict[id]
942 966
943 967 if name != None:
944 968 return self.getProcUnitObjByName(name)
945 969
946 970 return None
947 971
948 972 def getProcUnitObjByName(self, name):
949 973
950 974 for obj in self.procUnitConfObjDict.values():
951 975 if obj.name == name:
952 976 return obj
953 977
954 978 return None
955 979
956 980 def procUnitItems(self):
957 981
958 982 return self.procUnitConfObjDict.items()
959 983
960 984 def makeXml(self):
961 985
962 986 projectElement = Element('Project')
963 987 projectElement.set('id', str(self.id))
964 988 projectElement.set('name', self.name)
965 989 projectElement.set('description', self.description)
966 990
967 991 for procUnitConfObj in self.procUnitConfObjDict.values():
968 992 procUnitConfObj.makeXml(projectElement)
969 993
970 994 self.projectElement = projectElement
971 995
972 996 def writeXml(self, filename=None):
973 997
974 998 if filename == None:
975 999 if self.filename:
976 1000 filename = self.filename
977 1001 else:
978 1002 filename = "schain.xml"
979 1003
980 1004 if not filename:
981 1005 print "filename has not been defined. Use setFilename(filename) for do it."
982 1006 return 0
983 1007
984 1008 abs_file = os.path.abspath(filename)
985 1009
986 1010 if not os.access(os.path.dirname(abs_file), os.W_OK):
987 1011 print "No write permission on %s" %os.path.dirname(abs_file)
988 1012 return 0
989 1013
990 1014 if os.path.isfile(abs_file) and not(os.access(abs_file, os.W_OK)):
991 1015 print "File %s already exists and it could not be overwriten" %abs_file
992 1016 return 0
993 1017
994 1018 self.makeXml()
995 1019
996 1020 ElementTree(self.projectElement).write(abs_file, method='xml')
997 1021
998 1022 self.filename = abs_file
999 1023
1000 1024 return 1
1001 1025
1002 1026 def readXml(self, filename = None):
1003 1027
1004 1028 if not filename:
1005 1029 print "filename is not defined"
1006 1030 return 0
1007 1031
1008 1032 abs_file = os.path.abspath(filename)
1009 1033
1010 1034 if not os.path.isfile(abs_file):
1011 1035 print "%s file does not exist" %abs_file
1012 1036 return 0
1013 1037
1014 1038 self.projectElement = None
1015 1039 self.procUnitConfObjDict = {}
1016 1040
1017 1041 try:
1018 1042 self.projectElement = ElementTree().parse(abs_file)
1019 1043 except:
1020 1044 print "Error reading %s, verify file format" %filename
1021 1045 return 0
1022 1046
1023 1047 self.project = self.projectElement.tag
1024 1048
1025 1049 self.id = self.projectElement.get('id')
1026 1050 self.name = self.projectElement.get('name')
1027 1051 self.description = self.projectElement.get('description')
1028 1052
1029 1053 readUnitElementList = self.projectElement.iter(ReadUnitConf().getElementName())
1030 1054
1031 1055 for readUnitElement in readUnitElementList:
1032 1056 readUnitConfObj = ReadUnitConf()
1033 1057 readUnitConfObj.readXml(readUnitElement)
1034 1058
1035 1059 if readUnitConfObj.parentId == None:
1036 1060 readUnitConfObj.parentId = self.id
1037 1061
1038 1062 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
1039 1063
1040 1064 procUnitElementList = self.projectElement.iter(ProcUnitConf().getElementName())
1041 1065
1042 1066 for procUnitElement in procUnitElementList:
1043 1067 procUnitConfObj = ProcUnitConf()
1044 1068 procUnitConfObj.readXml(procUnitElement)
1045 1069
1046 1070 if procUnitConfObj.parentId == None:
1047 1071 procUnitConfObj.parentId = self.id
1048 1072
1049 1073 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
1050 1074
1051 1075 self.filename = abs_file
1052 1076
1053 1077 return 1
1054 1078
1055 1079 def printattr(self):
1056 1080
1057 1081 print "Project[%s]: name = %s, description = %s" %(self.id,
1058 1082 self.name,
1059 1083 self.description)
1060 1084
1061 1085 for procUnitConfObj in self.procUnitConfObjDict.values():
1062 1086 procUnitConfObj.printattr()
1063 1087
1064 1088 def createObjects(self):
1065 1089
1066 1090 for procUnitConfObj in self.procUnitConfObjDict.values():
1067 1091 procUnitConfObj.createObjects(self.plotterQueue)
1068 1092
1069 1093 def __connect(self, objIN, thisObj):
1070 1094
1071 1095 thisObj.setInput(objIN.getOutputObj())
1072 1096
1073 1097 def connectObjects(self):
1074 1098
1075 1099 for thisPUConfObj in self.procUnitConfObjDict.values():
1076 1100
1077 1101 inputId = thisPUConfObj.getInputId()
1078 1102
1079 1103 if int(inputId) == 0:
1080 1104 continue
1081 1105
1082 1106 #Get input object
1083 1107 puConfINObj = self.procUnitConfObjDict[inputId]
1084 1108 puObjIN = puConfINObj.getProcUnitObj()
1085 1109
1086 1110 #Get current object
1087 1111 thisPUObj = thisPUConfObj.getProcUnitObj()
1088 1112
1089 1113 self.__connect(puObjIN, thisPUObj)
1090 1114
1091 1115 def __handleError(self, procUnitConfObj, send_email=True):
1092 1116
1093 1117 import socket
1094 1118
1095 1119 err = traceback.format_exception(sys.exc_info()[0],
1096 1120 sys.exc_info()[1],
1097 1121 sys.exc_info()[2])
1098 1122
1099 1123 print "***** Error occurred in %s *****" %(procUnitConfObj.name)
1100 1124 print "***** %s" %err[-1]
1101 1125
1102 1126 message = "".join(err)
1103 1127
1104 1128 sys.stderr.write(message)
1105 1129
1106 1130 if not send_email:
1107 1131 return
1108 1132
1109 1133 subject = "SChain v%s: Error running %s\n" %(schainpy.__version__, procUnitConfObj.name)
1110 1134
1111 1135 subtitle = "%s: %s\n" %(procUnitConfObj.getElementName() ,procUnitConfObj.name)
1112 1136 subtitle += "Hostname: %s\n" %socket.gethostbyname(socket.gethostname())
1113 1137 subtitle += "Working directory: %s\n" %os.path.abspath("./")
1114 1138 subtitle += "Configuration file: %s\n" %self.filename
1115 1139 subtitle += "Time: %s\n" %str(datetime.datetime.now())
1116 1140
1117 1141 readUnitConfObj = self.getReadUnitObj()
1118 1142 if readUnitConfObj:
1119 1143 subtitle += "\nInput parameters:\n"
1120 1144 subtitle += "[Data path = %s]\n" %readUnitConfObj.path
1121 1145 subtitle += "[Data type = %s]\n" %readUnitConfObj.datatype
1122 1146 subtitle += "[Start date = %s]\n" %readUnitConfObj.startDate
1123 1147 subtitle += "[End date = %s]\n" %readUnitConfObj.endDate
1124 1148 subtitle += "[Start time = %s]\n" %readUnitConfObj.startTime
1125 1149 subtitle += "[End time = %s]\n" %readUnitConfObj.endTime
1126 1150
1127 1151 adminObj = schainpy.admin.SchainNotify()
1128 1152 adminObj.sendAlert(message=message,
1129 1153 subject=subject,
1130 1154 subtitle=subtitle,
1131 1155 filename=self.filename)
1132 1156
1133 1157 def isPaused(self):
1134 1158 return 0
1135 1159
1136 1160 def isStopped(self):
1137 1161 return 0
1138 1162
1139 1163 def runController(self):
1140 1164 """
1141 1165 returns 0 when this process has been stopped, 1 otherwise
1142 1166 """
1143 1167
1144 1168 if self.isPaused():
1145 1169 print "Process suspended"
1146 1170
1147 1171 while True:
1148 1172 sleep(0.1)
1149 1173
1150 1174 if not self.isPaused():
1151 1175 break
1152 1176
1153 1177 if self.isStopped():
1154 1178 break
1155 1179
1156 1180 print "Process reinitialized"
1157 1181
1158 1182 if self.isStopped():
1159 1183 print "Process stopped"
1160 1184 return 0
1161 1185
1162 1186 return 1
1163 1187
1164 1188 def setFilename(self, filename):
1165 1189
1166 1190 self.filename = filename
1167 1191
1168 1192 def setPlotterQueue(self, plotter_queue):
1169 1193
1170 1194 raise NotImplementedError, "Use schainpy.controller_api.ControllerThread instead Project class"
1171 1195
1172 1196 def getPlotterQueue(self):
1173 1197
1174 1198 raise NotImplementedError, "Use schainpy.controller_api.ControllerThread instead Project class"
1175 1199
1176 1200 def useExternalPlotter(self):
1177 1201
1178 1202 raise NotImplementedError, "Use schainpy.controller_api.ControllerThread instead Project class"
1179 1203
1180 1204 def run(self):
1181 1205
1182 1206 print
1183 1207 print "*"*60
1184 1208 print " Starting SIGNAL CHAIN PROCESSING v%s " %schainpy.__version__
1185 1209 print "*"*60
1186 1210 print
1187 1211
1188 1212 keyList = self.procUnitConfObjDict.keys()
1189 1213 keyList.sort()
1190 1214
1191 1215 while(True):
1192 1216
1193 1217 is_ok = False
1194 1218
1195 1219 for procKey in keyList:
1196 1220 # print "Running the '%s' process with %s" %(procUnitConfObj.name, procUnitConfObj.id)
1197 1221
1198 1222 procUnitConfObj = self.procUnitConfObjDict[procKey]
1199 1223
1200 1224 try:
1201 1225 sts = procUnitConfObj.run()
1202 1226 is_ok = is_ok or sts
1203 1227 except KeyboardInterrupt:
1204 1228 is_ok = False
1205 1229 break
1206 1230 except ValueError, e:
1207 1231 sleep(0.5)
1208 1232 self.__handleError(procUnitConfObj, send_email=True)
1209 1233 is_ok = False
1210 1234 break
1211 1235 except:
1212 1236 sleep(0.5)
1213 1237 self.__handleError(procUnitConfObj)
1214 1238 is_ok = False
1215 1239 break
1216 1240
1217 1241 #If every process unit finished so end process
1218 1242 if not(is_ok):
1219 1243 # print "Every process unit have finished"
1220 1244 break
1221 1245
1222 1246 if not self.runController():
1223 1247 break
1224 1248
1225 1249 #Closing every process
1226 1250 for procKey in keyList:
1227 1251 procUnitConfObj = self.procUnitConfObjDict[procKey]
1228 1252 procUnitConfObj.close()
1229 1253
1230 1254 print "Process finished"
1231 1255
1232 1256 def start(self):
1233 1257
1234 1258 self.writeXml()
1235
1236 1259 self.createObjects()
1237 1260 self.connectObjects()
1238 1261 self.run()
1239
1240 if __name__ == '__main__':
1241
1242 desc = "Segundo Test"
1243 filename = "schain.xml"
1244
1245 controllerObj = Project()
1246
1247 controllerObj.setup(id = '191', name='test01', description=desc)
1248
1249 readUnitConfObj = controllerObj.addReadUnit(datatype='Voltage',
1250 path='data/rawdata/',
1251 startDate='2011/01/01',
1252 endDate='2012/12/31',
1253 startTime='00:00:00',
1254 endTime='23:59:59',
1255 online=1,
1256 walk=1)
1257
1258 procUnitConfObj0 = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId())
1259
1260 opObj10 = procUnitConfObj0.addOperation(name='selectChannels')
1261 opObj10.addParameter(name='channelList', value='3,4,5', format='intlist')
1262
1263 opObj10 = procUnitConfObj0.addOperation(name='selectHeights')
1264 opObj10.addParameter(name='minHei', value='90', format='float')
1265 opObj10.addParameter(name='maxHei', value='180', format='float')
1266
1267 opObj12 = procUnitConfObj0.addOperation(name='CohInt', optype='external')
1268 opObj12.addParameter(name='n', value='10', format='int')
1269
1270 procUnitConfObj1 = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObj0.getId())
1271 procUnitConfObj1.addParameter(name='nFFTPoints', value='32', format='int')
1272 # procUnitConfObj1.addParameter(name='pairList', value='(0,1),(0,2),(1,2)', format='')
1273
1274
1275 opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='external')
1276 opObj11.addParameter(name='idfigure', value='1', format='int')
1277 opObj11.addParameter(name='wintitle', value='SpectraPlot0', format='str')
1278 opObj11.addParameter(name='zmin', value='40', format='int')
1279 opObj11.addParameter(name='zmax', value='90', format='int')
1280 opObj11.addParameter(name='showprofile', value='1', format='int')
1281
1282 print "Escribiendo el archivo XML"
1283
1284 controllerObj.writeXml(filename)
1285
1286 print "Leyendo el archivo XML"
1287 controllerObj.readXml(filename)
1288 #controllerObj.printattr()
1289
1290 controllerObj.createObjects()
1291 controllerObj.connectObjects()
1292 controllerObj.run()
1293
1294 No newline at end of file
@@ -1,1189 +1,1216
1 1 '''
2 2
3 3 $Author: murco $
4 4 $Id: JROData.py 173 2012-11-20 15:06:21Z murco $
5 5 '''
6 6
7 7 import copy
8 8 import numpy
9 9 import datetime
10 10
11 11 from jroheaderIO import SystemHeader, RadarControllerHeader
12 12 from schainpy import cSchain
13 13
14 14
15 15 def getNumpyDtype(dataTypeCode):
16 16
17 17 if dataTypeCode == 0:
18 18 numpyDtype = numpy.dtype([('real','<i1'),('imag','<i1')])
19 19 elif dataTypeCode == 1:
20 20 numpyDtype = numpy.dtype([('real','<i2'),('imag','<i2')])
21 21 elif dataTypeCode == 2:
22 22 numpyDtype = numpy.dtype([('real','<i4'),('imag','<i4')])
23 23 elif dataTypeCode == 3:
24 24 numpyDtype = numpy.dtype([('real','<i8'),('imag','<i8')])
25 25 elif dataTypeCode == 4:
26 26 numpyDtype = numpy.dtype([('real','<f4'),('imag','<f4')])
27 27 elif dataTypeCode == 5:
28 28 numpyDtype = numpy.dtype([('real','<f8'),('imag','<f8')])
29 29 else:
30 30 raise ValueError, 'dataTypeCode was not defined'
31 31
32 32 return numpyDtype
33 33
34 34 def getDataTypeCode(numpyDtype):
35 35
36 36 if numpyDtype == numpy.dtype([('real','<i1'),('imag','<i1')]):
37 37 datatype = 0
38 38 elif numpyDtype == numpy.dtype([('real','<i2'),('imag','<i2')]):
39 39 datatype = 1
40 40 elif numpyDtype == numpy.dtype([('real','<i4'),('imag','<i4')]):
41 41 datatype = 2
42 42 elif numpyDtype == numpy.dtype([('real','<i8'),('imag','<i8')]):
43 43 datatype = 3
44 44 elif numpyDtype == numpy.dtype([('real','<f4'),('imag','<f4')]):
45 45 datatype = 4
46 46 elif numpyDtype == numpy.dtype([('real','<f8'),('imag','<f8')]):
47 47 datatype = 5
48 48 else:
49 49 datatype = None
50 50
51 51 return datatype
52 52
53 53 def hildebrand_sekhon(data, navg):
54 54 """
55 55 This method is for the objective determination of the noise level in Doppler spectra. This
56 56 implementation technique is based on the fact that the standard deviation of the spectral
57 57 densities is equal to the mean spectral density for white Gaussian noise
58 58
59 59 Inputs:
60 60 Data : heights
61 61 navg : numbers of averages
62 62
63 63 Return:
64 64 -1 : any error
65 65 anoise : noise's level
66 66 """
67 67
68 68 sortdata = numpy.sort(data,axis=None)
69 69 # lenOfData = len(sortdata)
70 70 # nums_min = lenOfData*0.2
71 71 #
72 72 # if nums_min <= 5:
73 73 # nums_min = 5
74 74 #
75 75 # sump = 0.
76 76 #
77 77 # sumq = 0.
78 78 #
79 79 # j = 0
80 80 #
81 81 # cont = 1
82 82 #
83 83 # while((cont==1)and(j<lenOfData)):
84 84 #
85 85 # sump += sortdata[j]
86 86 #
87 87 # sumq += sortdata[j]**2
88 88 #
89 89 # if j > nums_min:
90 90 # rtest = float(j)/(j-1) + 1.0/navg
91 91 # if ((sumq*j) > (rtest*sump**2)):
92 92 # j = j - 1
93 93 # sump = sump - sortdata[j]
94 94 # sumq = sumq - sortdata[j]**2
95 95 # cont = 0
96 96 #
97 97 # j += 1
98 98 #
99 99 # lnoise = sump /j
100 100 #
101 101 # return lnoise
102 102
103 103 return cSchain.hildebrand_sekhon(sortdata, navg)
104 104
105 105
106 106 class Beam:
107 107
108 108 def __init__(self):
109 109 self.codeList = []
110 110 self.azimuthList = []
111 111 self.zenithList = []
112 112
113 113 class GenericData(object):
114 114
115 115 flagNoData = True
116 116
117 117 def __init__(self):
118 118
119 119 raise NotImplementedError
120 120
121 121 def copy(self, inputObj=None):
122 122
123 123 if inputObj == None:
124 124 return copy.deepcopy(self)
125 125
126 126 for key in inputObj.__dict__.keys():
127 127
128 128 attribute = inputObj.__dict__[key]
129 129
130 130 #If this attribute is a tuple or list
131 131 if type(inputObj.__dict__[key]) in (tuple, list):
132 132 self.__dict__[key] = attribute[:]
133 133 continue
134 134
135 135 #If this attribute is another object or instance
136 136 if hasattr(attribute, '__dict__'):
137 137 self.__dict__[key] = attribute.copy()
138 138 continue
139 139
140 140 self.__dict__[key] = inputObj.__dict__[key]
141 141
142 142 def deepcopy(self):
143 143
144 144 return copy.deepcopy(self)
145 145
146 146 def isEmpty(self):
147 147
148 148 return self.flagNoData
149 149
150 150 class JROData(GenericData):
151 151
152 152 # m_BasicHeader = BasicHeader()
153 153 # m_ProcessingHeader = ProcessingHeader()
154 154
155 155 systemHeaderObj = SystemHeader()
156 156
157 157 radarControllerHeaderObj = RadarControllerHeader()
158 158
159 159 # data = None
160 160
161 161 type = None
162 162
163 163 datatype = None #dtype but in string
164 164
165 165 # dtype = None
166 166
167 167 # nChannels = None
168 168
169 169 # nHeights = None
170 170
171 171 nProfiles = None
172 172
173 173 heightList = None
174 174
175 175 channelList = None
176 176
177 177 flagDiscontinuousBlock = False
178 178
179 179 useLocalTime = False
180 180
181 181 utctime = None
182 182
183 183 timeZone = None
184 184
185 185 dstFlag = None
186 186
187 187 errorCount = None
188 188
189 189 blocksize = None
190 190
191 191 # nCode = None
192 192 #
193 193 # nBaud = None
194 194 #
195 195 # code = None
196 196
197 197 flagDecodeData = False #asumo q la data no esta decodificada
198 198
199 199 flagDeflipData = False #asumo q la data no esta sin flip
200 200
201 201 flagShiftFFT = False
202 202
203 203 # ippSeconds = None
204 204
205 205 # timeInterval = None
206 206
207 207 nCohInt = None
208 208
209 209 # noise = None
210 210
211 211 windowOfFilter = 1
212 212
213 213 #Speed of ligth
214 214 C = 3e8
215 215
216 216 frequency = 49.92e6
217 217
218 218 realtime = False
219 219
220 220 beacon_heiIndexList = None
221 221
222 222 last_block = None
223 223
224 224 blocknow = None
225 225
226 226 azimuth = None
227 227
228 228 zenith = None
229 229
230 230 beam = Beam()
231 231
232 232 profileIndex = None
233 233
234 234 def __init__(self):
235 235
236 236 raise NotImplementedError
237 237
238 238 def getNoise(self):
239 239
240 240 raise NotImplementedError
241 241
242 242 def getNChannels(self):
243 243
244 244 return len(self.channelList)
245 245
246 246 def getChannelIndexList(self):
247 247
248 248 return range(self.nChannels)
249 249
250 250 def getNHeights(self):
251 251
252 252 return len(self.heightList)
253 253
254 254 def getHeiRange(self, extrapoints=0):
255 255
256 256 heis = self.heightList
257 257 # deltah = self.heightList[1] - self.heightList[0]
258 258 #
259 259 # heis.append(self.heightList[-1])
260 260
261 261 return heis
262 262
263 263 def getDeltaH(self):
264 264
265 265 delta = self.heightList[1] - self.heightList[0]
266 266
267 267 return delta
268 268
269 269 def getltctime(self):
270 270
271 271 if self.useLocalTime:
272 272 return self.utctime - self.timeZone*60
273 273
274 274 return self.utctime
275 275
276 276 def getDatatime(self):
277 277
278 278 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
279 279 return datatimeValue
280 280
281 281 def getTimeRange(self):
282 282
283 283 datatime = []
284 284
285 285 datatime.append(self.ltctime)
286 286 datatime.append(self.ltctime + self.timeInterval+1)
287 287
288 288 datatime = numpy.array(datatime)
289 289
290 290 return datatime
291 291
292 292 def getFmaxTimeResponse(self):
293 293
294 294 period = (10**-6)*self.getDeltaH()/(0.15)
295 295
296 296 PRF = 1./(period * self.nCohInt)
297 297
298 298 fmax = PRF
299 299
300 300 return fmax
301 301
302 302 def getFmax(self):
303 303
304 304 PRF = 1./(self.ippSeconds * self.nCohInt)
305 305
306 306 fmax = PRF
307 307
308 308 return fmax
309 309
310 310 def getVmax(self):
311 311
312 312 _lambda = self.C/self.frequency
313 313
314 314 vmax = self.getFmax() * _lambda/2
315 315
316 316 return vmax
317 317
318 318 def get_ippSeconds(self):
319 319 '''
320 320 '''
321 321 return self.radarControllerHeaderObj.ippSeconds
322 322
323 323 def set_ippSeconds(self, ippSeconds):
324 324 '''
325 325 '''
326 326
327 327 self.radarControllerHeaderObj.ippSeconds = ippSeconds
328 328
329 329 return
330 330
331 331 def get_dtype(self):
332 332 '''
333 333 '''
334 334 return getNumpyDtype(self.datatype)
335 335
336 336 def set_dtype(self, numpyDtype):
337 337 '''
338 338 '''
339 339
340 340 self.datatype = getDataTypeCode(numpyDtype)
341 341
342 342 def get_code(self):
343 343 '''
344 344 '''
345 345 return self.radarControllerHeaderObj.code
346 346
347 347 def set_code(self, code):
348 348 '''
349 349 '''
350 350 self.radarControllerHeaderObj.code = code
351 351
352 352 return
353 353
354 354 def get_ncode(self):
355 355 '''
356 356 '''
357 357 return self.radarControllerHeaderObj.nCode
358 358
359 359 def set_ncode(self, nCode):
360 360 '''
361 361 '''
362 362 self.radarControllerHeaderObj.nCode = nCode
363 363
364 364 return
365 365
366 366 def get_nbaud(self):
367 367 '''
368 368 '''
369 369 return self.radarControllerHeaderObj.nBaud
370 370
371 371 def set_nbaud(self, nBaud):
372 372 '''
373 373 '''
374 374 self.radarControllerHeaderObj.nBaud = nBaud
375 375
376 376 return
377 377
378 378 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
379 379 channelIndexList = property(getChannelIndexList, "I'm the 'channelIndexList' property.")
380 380 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
381 381 #noise = property(getNoise, "I'm the 'nHeights' property.")
382 382 datatime = property(getDatatime, "I'm the 'datatime' property")
383 383 ltctime = property(getltctime, "I'm the 'ltctime' property")
384 384 ippSeconds = property(get_ippSeconds, set_ippSeconds)
385 385 dtype = property(get_dtype, set_dtype)
386 386 # timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
387 387 code = property(get_code, set_code)
388 388 nCode = property(get_ncode, set_ncode)
389 389 nBaud = property(get_nbaud, set_nbaud)
390 390
391 391 class Voltage(JROData):
392 392
393 393 #data es un numpy array de 2 dmensiones (canales, alturas)
394 394 data = None
395 395
396 396 def __init__(self):
397 397 '''
398 398 Constructor
399 399 '''
400 400
401 401 self.useLocalTime = True
402 402
403 403 self.radarControllerHeaderObj = RadarControllerHeader()
404 404
405 405 self.systemHeaderObj = SystemHeader()
406 406
407 407 self.type = "Voltage"
408 408
409 409 self.data = None
410 410
411 411 # self.dtype = None
412 412
413 413 # self.nChannels = 0
414 414
415 415 # self.nHeights = 0
416 416
417 417 self.nProfiles = None
418 418
419 419 self.heightList = None
420 420
421 421 self.channelList = None
422 422
423 423 # self.channelIndexList = None
424 424
425 425 self.flagNoData = True
426 426
427 427 self.flagDiscontinuousBlock = False
428 428
429 429 self.utctime = None
430 430
431 431 self.timeZone = None
432 432
433 433 self.dstFlag = None
434 434
435 435 self.errorCount = None
436 436
437 437 self.nCohInt = None
438 438
439 439 self.blocksize = None
440 440
441 441 self.flagDecodeData = False #asumo q la data no esta decodificada
442 442
443 443 self.flagDeflipData = False #asumo q la data no esta sin flip
444 444
445 445 self.flagShiftFFT = False
446 446
447 447 self.flagDataAsBlock = False #Asumo que la data es leida perfil a perfil
448 448
449 449 self.profileIndex = 0
450 450
451 451 def getNoisebyHildebrand(self, channel = None):
452 452 """
453 453 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
454 454
455 455 Return:
456 456 noiselevel
457 457 """
458 458
459 459 if channel != None:
460 460 data = self.data[channel]
461 461 nChannels = 1
462 462 else:
463 463 data = self.data
464 464 nChannels = self.nChannels
465 465
466 466 noise = numpy.zeros(nChannels)
467 467 power = data * numpy.conjugate(data)
468 468
469 469 for thisChannel in range(nChannels):
470 470 if nChannels == 1:
471 471 daux = power[:].real
472 472 else:
473 473 daux = power[thisChannel,:].real
474 474 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
475 475
476 476 return noise
477 477
478 478 def getNoise(self, type = 1, channel = None):
479 479
480 480 if type == 1:
481 481 noise = self.getNoisebyHildebrand(channel)
482 482
483 483 return noise
484 484
485 485 def getPower(self, channel = None):
486 486
487 487 if channel != None:
488 488 data = self.data[channel]
489 489 else:
490 490 data = self.data
491 491
492 492 power = data * numpy.conjugate(data)
493 493 powerdB = 10*numpy.log10(power.real)
494 494 powerdB = numpy.squeeze(powerdB)
495 495
496 496 return powerdB
497 497
498 498 def getTimeInterval(self):
499 499
500 500 timeInterval = self.ippSeconds * self.nCohInt
501 501
502 502 return timeInterval
503 503
504 504 noise = property(getNoise, "I'm the 'nHeights' property.")
505 505 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
506 506
507 507 class Spectra(JROData):
508 508
509 509 #data spc es un numpy array de 2 dmensiones (canales, perfiles, alturas)
510 510 data_spc = None
511 511
512 512 #data cspc es un numpy array de 2 dmensiones (canales, pares, alturas)
513 513 data_cspc = None
514 514
515 515 #data dc es un numpy array de 2 dmensiones (canales, alturas)
516 516 data_dc = None
517 517
518 518 #data power
519 519 data_pwr = None
520 520
521 521 nFFTPoints = None
522 522
523 523 # nPairs = None
524 524
525 525 pairsList = None
526 526
527 527 nIncohInt = None
528 528
529 529 wavelength = None #Necesario para cacular el rango de velocidad desde la frecuencia
530 530
531 531 nCohInt = None #se requiere para determinar el valor de timeInterval
532 532
533 533 ippFactor = None
534 534
535 535 profileIndex = 0
536 536
537 537 plotting = "spectra"
538 538
539 539 def __init__(self):
540 540 '''
541 541 Constructor
542 542 '''
543 543
544 544 self.useLocalTime = True
545 545
546 546 self.radarControllerHeaderObj = RadarControllerHeader()
547 547
548 548 self.systemHeaderObj = SystemHeader()
549 549
550 550 self.type = "Spectra"
551 551
552 552 # self.data = None
553 553
554 554 # self.dtype = None
555 555
556 556 # self.nChannels = 0
557 557
558 558 # self.nHeights = 0
559 559
560 560 self.nProfiles = None
561 561
562 562 self.heightList = None
563 563
564 564 self.channelList = None
565 565
566 566 # self.channelIndexList = None
567 567
568 568 self.pairsList = None
569 569
570 570 self.flagNoData = True
571 571
572 572 self.flagDiscontinuousBlock = False
573 573
574 574 self.utctime = None
575 575
576 576 self.nCohInt = None
577 577
578 578 self.nIncohInt = None
579 579
580 580 self.blocksize = None
581 581
582 582 self.nFFTPoints = None
583 583
584 584 self.wavelength = None
585 585
586 586 self.flagDecodeData = False #asumo q la data no esta decodificada
587 587
588 588 self.flagDeflipData = False #asumo q la data no esta sin flip
589 589
590 590 self.flagShiftFFT = False
591 591
592 592 self.ippFactor = 1
593 593
594 594 #self.noise = None
595 595
596 596 self.beacon_heiIndexList = []
597 597
598 598 self.noise_estimation = None
599 599
600 600
601 601 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
602 602 """
603 603 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
604 604
605 605 Return:
606 606 noiselevel
607 607 """
608 608
609 609 noise = numpy.zeros(self.nChannels)
610 610
611 611 for channel in range(self.nChannels):
612 612 daux = self.data_spc[channel,xmin_index:xmax_index,ymin_index:ymax_index]
613 613 noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
614 614
615 615 return noise
616 616
617 617 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
618 618
619 619 if self.noise_estimation is not None:
620 620 return self.noise_estimation #this was estimated by getNoise Operation defined in jroproc_spectra.py
621 621 else:
622 622 noise = self.getNoisebyHildebrand(xmin_index, xmax_index, ymin_index, ymax_index)
623 623 return noise
624 624
625 625 def getFreqRangeTimeResponse(self, extrapoints=0):
626 626
627 627 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints*self.ippFactor)
628 628 freqrange = deltafreq*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2
629 629
630 630 return freqrange
631 631
632 632 def getAcfRange(self, extrapoints=0):
633 633
634 634 deltafreq = 10./(self.getFmax() / (self.nFFTPoints*self.ippFactor))
635 635 freqrange = deltafreq*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2
636 636
637 637 return freqrange
638 638
639 639 def getFreqRange(self, extrapoints=0):
640 640
641 641 deltafreq = self.getFmax() / (self.nFFTPoints*self.ippFactor)
642 642 freqrange = deltafreq*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2
643 643
644 644 return freqrange
645 645
646 646 def getVelRange(self, extrapoints=0):
647 647
648 648 deltav = self.getVmax() / (self.nFFTPoints*self.ippFactor)
649 649 velrange = deltav*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) #- deltav/2
650 650
651 651 return velrange
652 652
653 653 def getNPairs(self):
654 654
655 655 return len(self.pairsList)
656 656
657 657 def getPairsIndexList(self):
658 658
659 659 return range(self.nPairs)
660 660
661 661 def getNormFactor(self):
662 662
663 663 pwcode = 1
664 664
665 665 if self.flagDecodeData:
666 666 pwcode = numpy.sum(self.code[0]**2)
667 667 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
668 668 normFactor = self.nProfiles*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
669 669
670 670 return normFactor
671 671
672 672 def getFlagCspc(self):
673 673
674 674 if self.data_cspc is None:
675 675 return True
676 676
677 677 return False
678 678
679 679 def getFlagDc(self):
680 680
681 681 if self.data_dc is None:
682 682 return True
683 683
684 684 return False
685 685
686 686 def getTimeInterval(self):
687 687
688 688 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles
689 689
690 690 return timeInterval
691 691
692 692 def getPower(self):
693 693
694 694 factor = self.normFactor
695 695 z = self.data_spc/factor
696 696 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
697 697 avg = numpy.average(z, axis=1)
698 698
699 699 return 10*numpy.log10(avg)
700 700
701 def getCoherence(self, pairsList=None, phase=False):
702
703 z = []
704 if pairsList is None:
705 pairsIndexList = self.pairsIndexList
706 else:
707 pairsIndexList = []
708 for pair in pairsList:
709 if pair not in self.pairsList:
710 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
711 pairsIndexList.append(self.pairsList.index(pair))
712 for i in range(len(pairsIndexList)):
713 pair = self.pairsList[pairsIndexList[i]]
714 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
715 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
716 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
717 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
718 if phase:
719 data = numpy.arctan2(avgcoherenceComplex.imag,
720 avgcoherenceComplex.real)*180/numpy.pi
721 else:
722 data = numpy.abs(avgcoherenceComplex)
723
724 z.append(data)
725
726 return numpy.array(z)
727
701 728 def setValue(self, value):
702 729
703 730 print "This property should not be initialized"
704 731
705 732 return
706 733
707 734 nPairs = property(getNPairs, setValue, "I'm the 'nPairs' property.")
708 735 pairsIndexList = property(getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.")
709 736 normFactor = property(getNormFactor, setValue, "I'm the 'getNormFactor' property.")
710 737 flag_cspc = property(getFlagCspc, setValue)
711 738 flag_dc = property(getFlagDc, setValue)
712 739 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
713 740 timeInterval = property(getTimeInterval, setValue, "I'm the 'timeInterval' property")
714 741
715 742 class SpectraHeis(Spectra):
716 743
717 744 data_spc = None
718 745
719 746 data_cspc = None
720 747
721 748 data_dc = None
722 749
723 750 nFFTPoints = None
724 751
725 752 # nPairs = None
726 753
727 754 pairsList = None
728 755
729 756 nCohInt = None
730 757
731 758 nIncohInt = None
732 759
733 760 def __init__(self):
734 761
735 762 self.radarControllerHeaderObj = RadarControllerHeader()
736 763
737 764 self.systemHeaderObj = SystemHeader()
738 765
739 766 self.type = "SpectraHeis"
740 767
741 768 # self.dtype = None
742 769
743 770 # self.nChannels = 0
744 771
745 772 # self.nHeights = 0
746 773
747 774 self.nProfiles = None
748 775
749 776 self.heightList = None
750 777
751 778 self.channelList = None
752 779
753 780 # self.channelIndexList = None
754 781
755 782 self.flagNoData = True
756 783
757 784 self.flagDiscontinuousBlock = False
758 785
759 786 # self.nPairs = 0
760 787
761 788 self.utctime = None
762 789
763 790 self.blocksize = None
764 791
765 792 self.profileIndex = 0
766 793
767 794 self.nCohInt = 1
768 795
769 796 self.nIncohInt = 1
770 797
771 798 def getNormFactor(self):
772 799 pwcode = 1
773 800 if self.flagDecodeData:
774 801 pwcode = numpy.sum(self.code[0]**2)
775 802
776 803 normFactor = self.nIncohInt*self.nCohInt*pwcode
777 804
778 805 return normFactor
779 806
780 807 def getTimeInterval(self):
781 808
782 809 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
783 810
784 811 return timeInterval
785 812
786 813 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
787 814 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
788 815
789 816 class Fits(JROData):
790 817
791 818 heightList = None
792 819
793 820 channelList = None
794 821
795 822 flagNoData = True
796 823
797 824 flagDiscontinuousBlock = False
798 825
799 826 useLocalTime = False
800 827
801 828 utctime = None
802 829
803 830 timeZone = None
804 831
805 832 # ippSeconds = None
806 833
807 834 # timeInterval = None
808 835
809 836 nCohInt = None
810 837
811 838 nIncohInt = None
812 839
813 840 noise = None
814 841
815 842 windowOfFilter = 1
816 843
817 844 #Speed of ligth
818 845 C = 3e8
819 846
820 847 frequency = 49.92e6
821 848
822 849 realtime = False
823 850
824 851
825 852 def __init__(self):
826 853
827 854 self.type = "Fits"
828 855
829 856 self.nProfiles = None
830 857
831 858 self.heightList = None
832 859
833 860 self.channelList = None
834 861
835 862 # self.channelIndexList = None
836 863
837 864 self.flagNoData = True
838 865
839 866 self.utctime = None
840 867
841 868 self.nCohInt = 1
842 869
843 870 self.nIncohInt = 1
844 871
845 872 self.useLocalTime = True
846 873
847 874 self.profileIndex = 0
848 875
849 876 # self.utctime = None
850 877 # self.timeZone = None
851 878 # self.ltctime = None
852 879 # self.timeInterval = None
853 880 # self.header = None
854 881 # self.data_header = None
855 882 # self.data = None
856 883 # self.datatime = None
857 884 # self.flagNoData = False
858 885 # self.expName = ''
859 886 # self.nChannels = None
860 887 # self.nSamples = None
861 888 # self.dataBlocksPerFile = None
862 889 # self.comments = ''
863 890 #
864 891
865 892
866 893 def getltctime(self):
867 894
868 895 if self.useLocalTime:
869 896 return self.utctime - self.timeZone*60
870 897
871 898 return self.utctime
872 899
873 900 def getDatatime(self):
874 901
875 902 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
876 903 return datatime
877 904
878 905 def getTimeRange(self):
879 906
880 907 datatime = []
881 908
882 909 datatime.append(self.ltctime)
883 910 datatime.append(self.ltctime + self.timeInterval)
884 911
885 912 datatime = numpy.array(datatime)
886 913
887 914 return datatime
888 915
889 916 def getHeiRange(self):
890 917
891 918 heis = self.heightList
892 919
893 920 return heis
894 921
895 922 def getNHeights(self):
896 923
897 924 return len(self.heightList)
898 925
899 926 def getNChannels(self):
900 927
901 928 return len(self.channelList)
902 929
903 930 def getChannelIndexList(self):
904 931
905 932 return range(self.nChannels)
906 933
907 934 def getNoise(self, type = 1):
908 935
909 936 #noise = numpy.zeros(self.nChannels)
910 937
911 938 if type == 1:
912 939 noise = self.getNoisebyHildebrand()
913 940
914 941 if type == 2:
915 942 noise = self.getNoisebySort()
916 943
917 944 if type == 3:
918 945 noise = self.getNoisebyWindow()
919 946
920 947 return noise
921 948
922 949 def getTimeInterval(self):
923 950
924 951 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
925 952
926 953 return timeInterval
927 954
928 955 datatime = property(getDatatime, "I'm the 'datatime' property")
929 956 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
930 957 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
931 958 channelIndexList = property(getChannelIndexList, "I'm the 'channelIndexList' property.")
932 959 noise = property(getNoise, "I'm the 'nHeights' property.")
933 960
934 961 ltctime = property(getltctime, "I'm the 'ltctime' property")
935 962 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
936 963
937 964
938 965 class Correlation(JROData):
939 966
940 967 noise = None
941 968
942 969 SNR = None
943 970
944 971 #--------------------------------------------------
945 972
946 973 mode = None
947 974
948 975 split = False
949 976
950 977 data_cf = None
951 978
952 979 lags = None
953 980
954 981 lagRange = None
955 982
956 983 pairsList = None
957 984
958 985 normFactor = None
959 986
960 987 #--------------------------------------------------
961 988
962 989 # calculateVelocity = None
963 990
964 991 nLags = None
965 992
966 993 nPairs = None
967 994
968 995 nAvg = None
969 996
970 997
971 998 def __init__(self):
972 999 '''
973 1000 Constructor
974 1001 '''
975 1002 self.radarControllerHeaderObj = RadarControllerHeader()
976 1003
977 1004 self.systemHeaderObj = SystemHeader()
978 1005
979 1006 self.type = "Correlation"
980 1007
981 1008 self.data = None
982 1009
983 1010 self.dtype = None
984 1011
985 1012 self.nProfiles = None
986 1013
987 1014 self.heightList = None
988 1015
989 1016 self.channelList = None
990 1017
991 1018 self.flagNoData = True
992 1019
993 1020 self.flagDiscontinuousBlock = False
994 1021
995 1022 self.utctime = None
996 1023
997 1024 self.timeZone = None
998 1025
999 1026 self.dstFlag = None
1000 1027
1001 1028 self.errorCount = None
1002 1029
1003 1030 self.blocksize = None
1004 1031
1005 1032 self.flagDecodeData = False #asumo q la data no esta decodificada
1006 1033
1007 1034 self.flagDeflipData = False #asumo q la data no esta sin flip
1008 1035
1009 1036 self.pairsList = None
1010 1037
1011 1038 self.nPoints = None
1012 1039
1013 1040 def getPairsList(self):
1014 1041
1015 1042 return self.pairsList
1016 1043
1017 1044 def getNoise(self, mode = 2):
1018 1045
1019 1046 indR = numpy.where(self.lagR == 0)[0][0]
1020 1047 indT = numpy.where(self.lagT == 0)[0][0]
1021 1048
1022 1049 jspectra0 = self.data_corr[:,:,indR,:]
1023 1050 jspectra = copy.copy(jspectra0)
1024 1051
1025 1052 num_chan = jspectra.shape[0]
1026 1053 num_hei = jspectra.shape[2]
1027 1054
1028 1055 freq_dc = jspectra.shape[1]/2
1029 1056 ind_vel = numpy.array([-2,-1,1,2]) + freq_dc
1030 1057
1031 1058 if ind_vel[0]<0:
1032 1059 ind_vel[range(0,1)] = ind_vel[range(0,1)] + self.num_prof
1033 1060
1034 1061 if mode == 1:
1035 1062 jspectra[:,freq_dc,:] = (jspectra[:,ind_vel[1],:] + jspectra[:,ind_vel[2],:])/2 #CORRECCION
1036 1063
1037 1064 if mode == 2:
1038 1065
1039 1066 vel = numpy.array([-2,-1,1,2])
1040 1067 xx = numpy.zeros([4,4])
1041 1068
1042 1069 for fil in range(4):
1043 1070 xx[fil,:] = vel[fil]**numpy.asarray(range(4))
1044 1071
1045 1072 xx_inv = numpy.linalg.inv(xx)
1046 1073 xx_aux = xx_inv[0,:]
1047 1074
1048 1075 for ich in range(num_chan):
1049 1076 yy = jspectra[ich,ind_vel,:]
1050 1077 jspectra[ich,freq_dc,:] = numpy.dot(xx_aux,yy)
1051 1078
1052 1079 junkid = jspectra[ich,freq_dc,:]<=0
1053 1080 cjunkid = sum(junkid)
1054 1081
1055 1082 if cjunkid.any():
1056 1083 jspectra[ich,freq_dc,junkid.nonzero()] = (jspectra[ich,ind_vel[1],junkid] + jspectra[ich,ind_vel[2],junkid])/2
1057 1084
1058 1085 noise = jspectra0[:,freq_dc,:] - jspectra[:,freq_dc,:]
1059 1086
1060 1087 return noise
1061 1088
1062 1089 def getTimeInterval(self):
1063 1090
1064 1091 timeInterval = self.ippSeconds * self.nCohInt * self.nProfiles
1065 1092
1066 1093 return timeInterval
1067 1094
1068 1095 def splitFunctions(self):
1069 1096
1070 1097 pairsList = self.pairsList
1071 1098 ccf_pairs = []
1072 1099 acf_pairs = []
1073 1100 ccf_ind = []
1074 1101 acf_ind = []
1075 1102 for l in range(len(pairsList)):
1076 1103 chan0 = pairsList[l][0]
1077 1104 chan1 = pairsList[l][1]
1078 1105
1079 1106 #Obteniendo pares de Autocorrelacion
1080 1107 if chan0 == chan1:
1081 1108 acf_pairs.append(chan0)
1082 1109 acf_ind.append(l)
1083 1110 else:
1084 1111 ccf_pairs.append(pairsList[l])
1085 1112 ccf_ind.append(l)
1086 1113
1087 1114 data_acf = self.data_cf[acf_ind]
1088 1115 data_ccf = self.data_cf[ccf_ind]
1089 1116
1090 1117 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
1091 1118
1092 1119 def getNormFactor(self):
1093 1120 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
1094 1121 acf_pairs = numpy.array(acf_pairs)
1095 1122 normFactor = numpy.zeros((self.nPairs,self.nHeights))
1096 1123
1097 1124 for p in range(self.nPairs):
1098 1125 pair = self.pairsList[p]
1099 1126
1100 1127 ch0 = pair[0]
1101 1128 ch1 = pair[1]
1102 1129
1103 1130 ch0_max = numpy.max(data_acf[acf_pairs==ch0,:,:], axis=1)
1104 1131 ch1_max = numpy.max(data_acf[acf_pairs==ch1,:,:], axis=1)
1105 1132 normFactor[p,:] = numpy.sqrt(ch0_max*ch1_max)
1106 1133
1107 1134 return normFactor
1108 1135
1109 1136 timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property")
1110 1137 normFactor = property(getNormFactor, "I'm the 'normFactor property'")
1111 1138
1112 1139 class Parameters(JROData):
1113 1140
1114 1141 experimentInfo = None #Information about the experiment
1115 1142
1116 1143 #Information from previous data
1117 1144
1118 1145 inputUnit = None #Type of data to be processed
1119 1146
1120 1147 operation = None #Type of operation to parametrize
1121 1148
1122 1149 normFactor = None #Normalization Factor
1123 1150
1124 1151 groupList = None #List of Pairs, Groups, etc
1125 1152
1126 1153 #Parameters
1127 1154
1128 1155 data_param = None #Parameters obtained
1129 1156
1130 1157 data_pre = None #Data Pre Parametrization
1131 1158
1132 1159 data_SNR = None #Signal to Noise Ratio
1133 1160
1134 1161 # heightRange = None #Heights
1135 1162
1136 1163 abscissaList = None #Abscissa, can be velocities, lags or time
1137 1164
1138 1165 noise = None #Noise Potency
1139 1166
1140 1167 utctimeInit = None #Initial UTC time
1141 1168
1142 1169 paramInterval = None #Time interval to calculate Parameters in seconds
1143 1170
1144 1171 useLocalTime = True
1145 1172
1146 1173 #Fitting
1147 1174
1148 1175 data_error = None #Error of the estimation
1149 1176
1150 1177 constants = None
1151 1178
1152 1179 library = None
1153 1180
1154 1181 #Output signal
1155 1182
1156 1183 outputInterval = None #Time interval to calculate output signal in seconds
1157 1184
1158 1185 data_output = None #Out signal
1159 1186
1160 1187 nAvg = None
1161 1188
1162 1189
1163 1190 def __init__(self):
1164 1191 '''
1165 1192 Constructor
1166 1193 '''
1167 1194 self.radarControllerHeaderObj = RadarControllerHeader()
1168 1195
1169 1196 self.systemHeaderObj = SystemHeader()
1170 1197
1171 1198 self.type = "Parameters"
1172 1199
1173 1200 def getTimeRange1(self, interval):
1174 1201
1175 1202 datatime = []
1176 1203
1177 1204 if self.useLocalTime:
1178 1205 time1 = self.utctimeInit - self.timeZone*60
1179 1206 else:
1180 1207 time1 = self.utctimeInit
1181 1208
1182 1209 # datatime.append(self.utctimeInit)
1183 1210 # datatime.append(self.utctimeInit + self.outputInterval)
1184 1211 datatime.append(time1)
1185 1212 datatime.append(time1 + interval)
1186 1213
1187 1214 datatime = numpy.array(datatime)
1188 1215
1189 1216 return datatime
@@ -1,259 +1,376
1 1
2 2 import os
3 import zmq
3 4 import time
4 5 import numpy
5 6 import datetime
6 7 import numpy as np
7 8 import matplotlib.pyplot as plt
8 9 from mpl_toolkits.axes_grid1 import make_axes_locatable
9 10 from matplotlib.ticker import FuncFormatter, LinearLocator
11 from multiprocessing import Process
10 12
11 13 from schainpy.model.proc.jroproc_base import Operation
12 14
15 #plt.ion()
16
13 17 func = lambda x, pos: ('%s') %(datetime.datetime.utcfromtimestamp(x).strftime('%H:%M'))
14 18
15 19 d1970 = datetime.datetime(1970,1,1)
16 20
21 class PlotData(Operation, Process):
17 22
18 class PlotData(Operation):
19
20 __code = 'Figure'
23 CODE = 'Figure'
24 colormap = 'jet'
21 25 __MAXNUMX = 80
22 26 __MAXNUMY = 80
23 27 __missing = 1E30
24 28
25 def __init__(self):
29 def __init__(self, **kwargs):
26 30
27 31 Operation.__init__(self)
28 self.xmin = None
29 self.xmax = None
30 self.newdataOut = None
32 Process.__init__(self)
33 self.mp = False
31 34 self.dataOut = None
32 35 self.isConfig = False
33 36 self.figure = None
34 self.width = 6
35 self.height = 4
36
37 def setup(self, dataOut, **kwargs):
38
39 self.first = True
40 self.localtime = kwargs.pop('localtime', True)
41 self.show = kwargs.pop('show', True)
42 self.save = kwargs.pop('save', False)
43 self.pause = kwargs.pop('pause', False)
44 self.time = []
45 self.nblock = 0
46 self.z = []
47 self.data = [{} for __ in dataOut.channelList]
48 37 self.axes = []
49 self.colormap = kwargs.get('colormap', 'jet')
38 self.localtime = kwargs.pop('localtime', True)
39 self.show = kwargs.get('show', True)
40 self.save = kwargs.get('save', False)
41 self.colormap = kwargs.get('colormap', self.colormap)
42 self.showprofile = kwargs.get('showprofile', False)
50 43 self.title = kwargs.get('wintitle', '')
51 self.xaxis = kwargs.get('xaxis', None)
44 self.xaxis = kwargs.get('xaxis', 'time')
52 45 self.zmin = kwargs.get('zmin', None)
53 46 self.zmax = kwargs.get('zmax', None)
54
55 xmin = kwargs.get('xmin', 0)
56 xmax = kwargs.get('xmax', xmin+4)
57
58 dt = dataOut.datatime.date()
59 dtmin = datetime.datetime.combine(dt, datetime.time(xmin, 0, 0))
60 dtmax = datetime.datetime.combine(dt, datetime.time(xmax, 59, 59))
61
62 self.xmin = (dtmin-d1970).total_seconds()
63 self.xmax = (dtmax-d1970).total_seconds()
64
47 self.xmin = kwargs.get('xmin', None)
48 self.xmax = kwargs.get('xmax', None)
49 self.xrange = kwargs.get('xrange', 24)
65 50 self.ymin = kwargs.get('ymin', None)
66 51 self.ymax = kwargs.get('ymax', None)
67 52
68 if self.figure is None:
69 self.figure = plt.figure()
70 else:
71 self.figure.clf()
72
73 self.setup_fig()
74
75 for n in range(dataOut.nChannels):
76 ax = self.figure.add_subplot(self.nrows, self.ncols, n+1)
77 ax.firsttime = True
78 self.axes.append(ax)
79
80 self.setup_fig()
81
82 self.figure.set_size_inches (self.width, self.height)
83
84 53 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
85 54
86 55 if x_buffer.shape[0] < 2:
87 56 return x_buffer, y_buffer, z_buffer
88 57
89 58 deltas = x_buffer[1:] - x_buffer[0:-1]
90 59 x_median = np.median(deltas)
91 60
92 61 index = np.where(deltas > 5*x_median)
93 62
94 63 if len(index[0]) != 0:
95 64 z_buffer[::,index[0],::] = self.__missing
96 65 z_buffer = np.ma.masked_inside(z_buffer,
97 66 0.99*self.__missing,
98 67 1.01*self.__missing)
99 68
100 69 return x_buffer, y_buffer, z_buffer
101 70
102 71 def decimate(self):
103 72
104 73 dx = int(len(self.x)/self.__MAXNUMX) + 1
105 74 dy = int(len(self.y)/self.__MAXNUMY) + 1
106 75
107 76 x = self.x[::dx]
108 77 y = self.y[::dy]
109 78 z = self.z[::, ::dx, ::dy]
110 79
111 80 return x, y, z
112 81
113 def _plot(self):
82 def __plot(self):
114 83
115 self.plot()
84 print 'plotting...{}'.format(self.CODE)
116 85
117 self.figure.suptitle(self.title+self.__code)
86 self.plot()
87 self.figure.suptitle('{} {}'.format(self.title, self.CODE.upper()))
118 88
119 89 if self.save:
120 figname = os.path.join(self.save, '{}_{}.png'.format(self.__code,
121 self.plot_dt.strftime('%y%m%d_%H%M%S')))
90 figname = os.path.join(self.save, '{}_{}.png'.format(self.CODE,
91 datetime.datetime.utcfromtimestamp(self.times[-1]).strftime('%y%m%d_%H%M%S')))
122 92 print 'Saving figure: {}'.format(figname)
123 93 self.figure.savefig(figname)
124 94
125 95 self.figure.canvas.draw()
126 if self.show:
127 self.figure.show()
128 if self.pause:
129 raw_input('Press <ENTER> to continue')
130
131 96
132 def update(self):
133
134 pass
135
136 def run(self, dataOut, **kwargs):
137
138 self.dataOut = dataOut
97 def plot(self):
139 98
140 if not self.isConfig:
141 self.setup(dataOut, **kwargs)
99 print 'plotting...{}'.format(self.CODE.upper())
100 return
101
102 def run(self):
103
104 print '[Starting] {}'.format(self.name)
105 context = zmq.Context()
106 receiver = context.socket(zmq.SUB)
107 receiver.setsockopt(zmq.SUBSCRIBE, '')
108 receiver.setsockopt(zmq.CONFLATE, True)
109 receiver.connect("ipc:///tmp/zmq.plots")
110
111 while True:
112 try:
113 #if True:
114 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
115 self.dataOut = self.data['dataOut']
116 self.times = self.data['times']
117 self.times.sort()
118 self.min_time = self.times[0]
119 self.max_time = self.times[-1]
120
121 if self.isConfig is False:
122 self.setup()
142 123 self.isConfig = True
143 124
144 self.nblock += 1
145 self.update()
125 self.__plot()
146 126
147 if dataOut.ltctime>=self.xmax:
148 self._plot()
149 self.isConfig = False
127 if 'ENDED' in self.data:
128 #self.setup()
129 #self.__plot()
130 pass
131
132 except zmq.Again as e:
133 print 'Waiting for data...'
134 plt.pause(5)
135 #time.sleep(3)
150 136
151 137 def close(self):
152 138 if self.dataOut:
153 139 self._plot()
154 140
155 141
156 142 class PlotSpectraData(PlotData):
157 143
158 __code = 'Spectra'
144 CODE = 'spc'
145 colormap = 'jro'
159 146
160 def setup_fig(self):
161 pass
147 def setup(self):
148
149 ncolspan = 1
150 colspan = 1
151 self.ncols = int(numpy.sqrt(self.dataOut.nChannels)+0.9)
152 self.nrows = int(self.dataOut.nChannels*1./self.ncols + 0.9)
153 self.width = 3.6*self.ncols
154 self.height = 3.2*self.nrows
155 if self.showprofile:
156 ncolspan = 3
157 colspan = 2
158 self.width += 1.2*self.ncols
159
160 self.ylabel = 'Range [Km]'
161 self.titles = ['Channel {}'.format(x) for x in self.dataOut.channelList]
162 162
163 def update(self):
163 if self.figure is None:
164 self.figure = plt.figure(figsize=(self.width, self.height),
165 edgecolor='k',
166 facecolor='w')
167 else:
168 self.figure.clf()
169
170 n = 0
171 for y in range(self.nrows):
172 for x in range(self.ncols):
173 if n>=self.dataOut.nChannels:
174 break
175 ax = plt.subplot2grid((self.nrows, self.ncols*ncolspan), (y, x*ncolspan), 1, colspan)
176 if self.showprofile:
177 ax.ax_profile = plt.subplot2grid((self.nrows, self.ncols*ncolspan), (y, x*ncolspan+colspan), 1, 1)
164 178
165 for ch in self.dataOut.channelList:
166 self.data[ch] = self.dataOut.data_spc[ch]
179 ax.firsttime = True
180 self.axes.append(ax)
181 n += 1
182
183 self.figure.subplots_adjust(wspace=0.9, hspace=0.5)
184 self.figure.show()
167 185
168 186 def plot(self):
169 pass
187
188 if self.xaxis == "frequency":
189 x = self.dataOut.getFreqRange(1)/1000.
190 xlabel = "Frequency (kHz)"
191 elif self.xaxis == "time":
192 x = self.dataOut.getAcfRange(1)
193 xlabel = "Time (ms)"
194 else:
195 x = self.dataOut.getVelRange(1)
196 xlabel = "Velocity (m/s)"
197
198 y = self.dataOut.getHeiRange()
199 z = self.data[self.CODE]
200
201 for n, ax in enumerate(self.axes):
202
203 if ax.firsttime:
204 self.xmax = self.xmax if self.xmax else np.nanmax(x)
205 self.xmin = self.xmin if self.xmin else -self.xmax
206 self.ymin = self.ymin if self.ymin else np.nanmin(y)
207 self.ymax = self.ymax if self.ymax else np.nanmax(y)
208 self.zmin = self.zmin if self.zmin else np.nanmin(z)
209 self.zmax = self.zmax if self.zmax else np.nanmax(z)
210 ax.plot = ax.pcolormesh(x, y, z[n].T,
211 vmin=self.zmin,
212 vmax=self.zmax,
213 cmap=plt.get_cmap(self.colormap)
214 )
215 divider = make_axes_locatable(ax)
216 cax = divider.new_horizontal(size='3%', pad=0.05)
217 self.figure.add_axes(cax)
218 plt.colorbar(ax.plot, cax)
219
220 ax.set_xlim(self.xmin, self.xmax)
221 ax.set_ylim(self.ymin, self.ymax)
222
223 ax.xaxis.set_major_locator(LinearLocator(5))
224 #ax.yaxis.set_major_locator(LinearLocator(4))
225
226 ax.set_ylabel(self.ylabel)
227 ax.set_xlabel(xlabel)
228
229 ax.firsttime = False
230
231 if self.showprofile:
232 ax.plot_profile= ax.ax_profile.plot(self.data['rti'][self.max_time][n], y)[0]
233 ax.ax_profile.set_xlim(self.zmin, self.zmax)
234 ax.ax_profile.set_ylim(self.ymin, self.ymax)
235 ax.ax_profile.set_xlabel('dB')
236 ax.ax_profile.grid(b=True, axis='x')
237 [tick.set_visible(False) for tick in ax.ax_profile.get_yticklabels()]
238 noise = 10*numpy.log10(self.data['rti'][self.max_time][n]/self.dataOut.normFactor)
239 ax.ax_profile.vlines(noise, self.ymin, self.ymax, colors="k", linestyle="dashed", lw=2)
240 else:
241 ax.plot.set_array(z[n].T.ravel())
242 ax.set_title('{} {}'.format(self.titles[n],
243 datetime.datetime.utcfromtimestamp(self.max_time).strftime('%y/%m/%d %H:%M:%S')),
244 size=8)
245 if self.showprofile:
246 ax.plot_profile.set_data(self.data['rti'][self.max_time][n], y)
170 247
171 248
172 249 class PlotRTIData(PlotData):
173 250
174 __code = 'RTI'
251 CODE = 'rti'
252 colormap = 'jro'
175 253
176 def setup_fig(self):
254 def setup(self):
177 255
178 256 self.ncols = 1
179 257 self.nrows = self.dataOut.nChannels
180 self.width = 8
258 self.width = 10
181 259 self.height = 2.2*self.nrows
182 260 self.ylabel = 'Range [Km]'
261 self.titles = ['Channel {}'.format(x) for x in self.dataOut.channelList]
183 262
184 def update(self):
263 if self.figure is None:
264 self.figure = plt.figure(figsize=(self.width, self.height),
265 edgecolor='k',
266 facecolor='w')
267 else:
268 self.figure.clf()
185 269
186 self.time.append(self.dataOut.ltctime)
270 for n in range(self.nrows):
271 ax = self.figure.add_subplot(self.nrows, self.ncols, n+1)
272 ax.firsttime = True
273 self.axes.append(ax)
187 274
188 for ch in self.dataOut.channelList:
189 self.data[ch][self.dataOut.ltctime] = self.dataOut.getPower()[ch]
275 self.figure.subplots_adjust(hspace=0.5)
276 self.figure.show()
190 277
191 278 def plot(self):
192 279
193 self.plot_dt = datetime.datetime.utcfromtimestamp(self.time[-2])
194
195 self.time.sort()
196 self.x = self.time
280 self.x = np.array(self.times)
197 281 self.y = self.dataOut.getHeiRange()
198 282 self.z = []
199 283
200 for ch in self.dataOut.channelList:
201 self.z.append([self.data[ch][t] for t in self.time])
284 for ch in range(self.nrows):
285 self.z.append([self.data[self.CODE][t][ch] for t in self.times])
202 286
203 self.x = np.array(self.x)
204 287 self.z = np.array(self.z)
205 288
206 289 for n, ax in enumerate(self.axes):
207 290
291 x, y, z = self.fill_gaps(*self.decimate())
292
293 if ax.firsttime:
294 self.ymin = self.ymin if self.ymin else np.nanmin(self.y)
295 self.ymax = self.ymax if self.ymax else np.nanmax(self.y)
296 self.zmin = self.zmin if self.zmin else np.nanmin(self.z)
297 zmax = self.zmax if self.zmax else np.nanmax(self.z)
298 plot = ax.pcolormesh(x, y, z[n].T,
299 vmin=self.zmin,
300 vmax=self.zmax,
301 cmap=plt.get_cmap(self.colormap)
302 )
303 divider = make_axes_locatable(ax)
304 cax = divider.new_horizontal(size='2%', pad=0.05)
305 self.figure.add_axes(cax)
306 plt.colorbar(plot, cax)
307 ax.set_ylim(self.ymin, self.ymax)
208 308 if self.xaxis=='time':
209 309 ax.xaxis.set_major_formatter(FuncFormatter(func))
210 310 ax.xaxis.set_major_locator(LinearLocator(6))
211 311
212 312 ax.yaxis.set_major_locator(LinearLocator(4))
213 313
214 314 ax.set_ylabel(self.ylabel)
215 315
216 ax.set_xlim(self.xmin, self.xmax)
217
218 ax.set_title('Channel {} {}'.format(self.dataOut.channelList[n],
219 self.plot_dt.strftime('%y/%m/%d %H:%M:%S')),
220 size=8)
221
222 self.decimate()
316 if self.xmin is None:
317 print 'is none'
318 xmin = self.min_time
319 else:
223 320
224 for n, ax in enumerate(self.axes):
321 xmin = (datetime.datetime.combine(self.dataOut.datatime.date(),
322 datetime.time(self.xmin, 0, 0))-d1970).total_seconds()
225 323
226 x, y, z = self.fill_gaps(*self.decimate())
324 xmax = xmin+self.xrange*60*60
227 325
228 if ax.firsttime:
229 ymin = self.ymin if self.ymin else np.nanmin(self.y)
230 ymax = self.ymax if self.ymax else np.nanmax(self.y)
231 zmin = self.zmin if self.zmin else np.nanmin(self.z)
232 zmax = self.zmax if self.zmax else np.nanmax(self.z)
326 ax.set_xlim(xmin, xmax)
327 ax.firsttime = False
328 else:
329 ax.collections.remove(ax.collections[0])
233 330 plot = ax.pcolormesh(x, y, z[n].T,
234 vmin=zmin,
235 vmax=zmax,
331 vmin=self.zmin,
332 vmax=self.zmax,
236 333 cmap=plt.get_cmap(self.colormap)
237 334 )
238 divider = make_axes_locatable(ax)
239 cax = divider.new_horizontal(size='3%', pad=0.05)
240 self.figure.add_axes(cax)
241 plt.colorbar(plot, cax)
242 ax.set_ylim(self.ymin, self.ymax)
243 ax.firsttime = False
335 ax.set_title('{} {}'.format(self.titles[n],
336 datetime.datetime.utcfromtimestamp(self.max_time).strftime('%y/%m/%d %H:%M:%S')),
337 size=8)
338
339
340 class PlotCOHData(PlotRTIData):
341
342 CODE = 'coh'
343
344 def setup(self):
345
346 self.ncols = 1
347 self.nrows = self.dataOut.nPairs
348 self.width = 10
349 self.height = 2.2*self.nrows
350 self.ylabel = 'Range [Km]'
351 self.titles = ['Channels {}'.format(x) for x in self.dataOut.pairsList]
352
353 if self.figure is None:
354 self.figure = plt.figure(figsize=(self.width, self.height),
355 edgecolor='k',
356 facecolor='w')
244 357 else:
245 plot = ax.pcolormesh(x, y, z[n].T)
358 self.figure.clf()
246 359
247 self.figure.subplots_adjust(wspace=None, hspace=0.5)
360 for n in range(self.nrows):
361 ax = self.figure.add_subplot(self.nrows, self.ncols, n+1)
362 ax.firsttime = True
363 self.axes.append(ax)
248 364
365 self.figure.subplots_adjust(hspace=0.5)
366 self.figure.show()
249 367
250 368 class PlotSNRData(PlotRTIData):
251 369
252 __code = 'SNR'
370 CODE = 'coh'
253 371
254 def update(self):
255 372
256 self.time.append(self.dataOut.ltctime)
373 class PlotPHASEData(PlotCOHData):
257 374
258 for ch in self.dataOut.channelList:
259 self.data[ch][self.dataOut.ltctime] = 10*np.log10(self.dataOut.data_SNR[ch]) No newline at end of file
375 CODE = 'phase'
376 colormap = 'seismic'
@@ -1,679 +1,679
1 1 '''
2 2 Created on Jul 2, 2014
3 3
4 4 @author: roj-idl71
5 5 '''
6 6 import numpy
7 7
8 8 from jroIO_base import LOCALTIME, JRODataReader, JRODataWriter
9 9 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation
10 10 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
11 11 from schainpy.model.data.jrodata import Spectra
12 12
13 13 class SpectraReader(JRODataReader, ProcessingUnit):
14 14 """
15 15 Esta clase permite leer datos de espectros desde archivos procesados (.pdata). La lectura
16 16 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones)
17 17 son almacenados en tres buffer's para el Self Spectra, el Cross Spectra y el DC Channel.
18 18
19 19 paresCanalesIguales * alturas * perfiles (Self Spectra)
20 20 paresCanalesDiferentes * alturas * perfiles (Cross Spectra)
21 21 canales * alturas (DC Channels)
22 22
23 23 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
24 24 RadarControllerHeader y Spectra. Los tres primeros se usan para almacenar informacion de la
25 25 cabecera de datos (metadata), y el cuarto (Spectra) para obtener y almacenar un bloque de
26 26 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
27 27
28 28 Example:
29 29 dpath = "/home/myuser/data"
30 30
31 31 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
32 32
33 33 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
34 34
35 35 readerObj = SpectraReader()
36 36
37 37 readerObj.setup(dpath, startTime, endTime)
38 38
39 39 while(True):
40 40
41 41 readerObj.getData()
42 42
43 43 print readerObj.data_spc
44 44
45 45 print readerObj.data_cspc
46 46
47 47 print readerObj.data_dc
48 48
49 49 if readerObj.flagNoMoreFiles:
50 50 break
51 51
52 52 """
53 53
54 54 pts2read_SelfSpectra = 0
55 55
56 56 pts2read_CrossSpectra = 0
57 57
58 58 pts2read_DCchannels = 0
59 59
60 60 ext = ".pdata"
61 61
62 62 optchar = "P"
63 63
64 64 dataOut = None
65 65
66 66 nRdChannels = None
67 67
68 68 nRdPairs = None
69 69
70 70 rdPairList = []
71 71
72 def __init__(self):
72 def __init__(self, **kwargs):
73 73 """
74 74 Inicializador de la clase SpectraReader para la lectura de datos de espectros.
75 75
76 76 Inputs:
77 77 dataOut : Objeto de la clase Spectra. Este objeto sera utilizado para
78 78 almacenar un perfil de datos cada vez que se haga un requerimiento
79 79 (getData). El perfil sera obtenido a partir del buffer de datos,
80 80 si el buffer esta vacio se hara un nuevo proceso de lectura de un
81 81 bloque de datos.
82 82 Si este parametro no es pasado se creara uno internamente.
83 83
84 84 Affected:
85 85 self.dataOut
86 86
87 87 Return : None
88 88 """
89 89
90 90 #Eliminar de la base la herencia
91 ProcessingUnit.__init__(self)
91 ProcessingUnit.__init__(self, **kwargs)
92 92
93 93 # self.isConfig = False
94 94
95 95 self.pts2read_SelfSpectra = 0
96 96
97 97 self.pts2read_CrossSpectra = 0
98 98
99 99 self.pts2read_DCchannels = 0
100 100
101 101 self.datablock = None
102 102
103 103 self.utc = None
104 104
105 105 self.ext = ".pdata"
106 106
107 107 self.optchar = "P"
108 108
109 109 self.basicHeaderObj = BasicHeader(LOCALTIME)
110 110
111 111 self.systemHeaderObj = SystemHeader()
112 112
113 113 self.radarControllerHeaderObj = RadarControllerHeader()
114 114
115 115 self.processingHeaderObj = ProcessingHeader()
116 116
117 117 self.online = 0
118 118
119 119 self.fp = None
120 120
121 121 self.idFile = None
122 122
123 123 self.dtype = None
124 124
125 125 self.fileSizeByHeader = None
126 126
127 127 self.filenameList = []
128 128
129 129 self.filename = None
130 130
131 131 self.fileSize = None
132 132
133 133 self.firstHeaderSize = 0
134 134
135 135 self.basicHeaderSize = 24
136 136
137 137 self.pathList = []
138 138
139 139 self.lastUTTime = 0
140 140
141 141 self.maxTimeStep = 30
142 142
143 143 self.flagNoMoreFiles = 0
144 144
145 145 self.set = 0
146 146
147 147 self.path = None
148 148
149 149 self.delay = 60 #seconds
150 150
151 151 self.nTries = 3 #quantity tries
152 152
153 153 self.nFiles = 3 #number of files for searching
154 154
155 155 self.nReadBlocks = 0
156 156
157 157 self.flagIsNewFile = 1
158 158
159 159 self.__isFirstTimeOnline = 1
160 160
161 161 # self.ippSeconds = 0
162 162
163 163 self.flagDiscontinuousBlock = 0
164 164
165 165 self.flagIsNewBlock = 0
166 166
167 167 self.nTotalBlocks = 0
168 168
169 169 self.blocksize = 0
170 170
171 171 self.dataOut = self.createObjByDefault()
172 172
173 173 self.profileIndex = 1 #Always
174 174
175 175
176 176 def createObjByDefault(self):
177 177
178 178 dataObj = Spectra()
179 179
180 180 return dataObj
181 181
182 182 def __hasNotDataInBuffer(self):
183 183 return 1
184 184
185 185
186 186 def getBlockDimension(self):
187 187 """
188 188 Obtiene la cantidad de puntos a leer por cada bloque de datos
189 189
190 190 Affected:
191 191 self.nRdChannels
192 192 self.nRdPairs
193 193 self.pts2read_SelfSpectra
194 194 self.pts2read_CrossSpectra
195 195 self.pts2read_DCchannels
196 196 self.blocksize
197 197 self.dataOut.nChannels
198 198 self.dataOut.nPairs
199 199
200 200 Return:
201 201 None
202 202 """
203 203 self.nRdChannels = 0
204 204 self.nRdPairs = 0
205 205 self.rdPairList = []
206 206
207 207 for i in range(0, self.processingHeaderObj.totalSpectra*2, 2):
208 208 if self.processingHeaderObj.spectraComb[i] == self.processingHeaderObj.spectraComb[i+1]:
209 209 self.nRdChannels = self.nRdChannels + 1 #par de canales iguales
210 210 else:
211 211 self.nRdPairs = self.nRdPairs + 1 #par de canales diferentes
212 212 self.rdPairList.append((self.processingHeaderObj.spectraComb[i], self.processingHeaderObj.spectraComb[i+1]))
213 213
214 214 pts2read = self.processingHeaderObj.nHeights * self.processingHeaderObj.profilesPerBlock
215 215
216 216 self.pts2read_SelfSpectra = int(self.nRdChannels * pts2read)
217 217 self.blocksize = self.pts2read_SelfSpectra
218 218
219 219 if self.processingHeaderObj.flag_cspc:
220 220 self.pts2read_CrossSpectra = int(self.nRdPairs * pts2read)
221 221 self.blocksize += self.pts2read_CrossSpectra
222 222
223 223 if self.processingHeaderObj.flag_dc:
224 224 self.pts2read_DCchannels = int(self.systemHeaderObj.nChannels * self.processingHeaderObj.nHeights)
225 225 self.blocksize += self.pts2read_DCchannels
226 226
227 227 # self.blocksize = self.pts2read_SelfSpectra + self.pts2read_CrossSpectra + self.pts2read_DCchannels
228 228
229 229
230 230 def readBlock(self):
231 231 """
232 232 Lee el bloque de datos desde la posicion actual del puntero del archivo
233 233 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
234 234 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
235 235 es seteado a 0
236 236
237 237 Return: None
238 238
239 239 Variables afectadas:
240 240
241 241 self.flagIsNewFile
242 242 self.flagIsNewBlock
243 243 self.nTotalBlocks
244 244 self.data_spc
245 245 self.data_cspc
246 246 self.data_dc
247 247
248 248 Exceptions:
249 249 Si un bloque leido no es un bloque valido
250 250 """
251 251 blockOk_flag = False
252 252 fpointer = self.fp.tell()
253 253
254 254 spc = numpy.fromfile( self.fp, self.dtype[0], self.pts2read_SelfSpectra )
255 255 spc = spc.reshape( (self.nRdChannels, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
256 256
257 257 if self.processingHeaderObj.flag_cspc:
258 258 cspc = numpy.fromfile( self.fp, self.dtype, self.pts2read_CrossSpectra )
259 259 cspc = cspc.reshape( (self.nRdPairs, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
260 260
261 261 if self.processingHeaderObj.flag_dc:
262 262 dc = numpy.fromfile( self.fp, self.dtype, self.pts2read_DCchannels ) #int(self.processingHeaderObj.nHeights*self.systemHeaderObj.nChannels) )
263 263 dc = dc.reshape( (self.systemHeaderObj.nChannels, self.processingHeaderObj.nHeights) ) #transforma a un arreglo 2D
264 264
265 265
266 266 if not(self.processingHeaderObj.shif_fft):
267 267 #desplaza a la derecha en el eje 2 determinadas posiciones
268 268 shift = int(self.processingHeaderObj.profilesPerBlock/2)
269 269 spc = numpy.roll( spc, shift , axis=2 )
270 270
271 271 if self.processingHeaderObj.flag_cspc:
272 272 #desplaza a la derecha en el eje 2 determinadas posiciones
273 273 cspc = numpy.roll( cspc, shift, axis=2 )
274 274
275 275 #Dimensions : nChannels, nProfiles, nSamples
276 276 spc = numpy.transpose( spc, (0,2,1) )
277 277 self.data_spc = spc
278 278
279 279 if self.processingHeaderObj.flag_cspc:
280 280 cspc = numpy.transpose( cspc, (0,2,1) )
281 281 self.data_cspc = cspc['real'] + cspc['imag']*1j
282 282 else:
283 283 self.data_cspc = None
284 284
285 285 if self.processingHeaderObj.flag_dc:
286 286 self.data_dc = dc['real'] + dc['imag']*1j
287 287 else:
288 288 self.data_dc = None
289 289
290 290 self.flagIsNewFile = 0
291 291 self.flagIsNewBlock = 1
292 292
293 293 self.nTotalBlocks += 1
294 294 self.nReadBlocks += 1
295 295
296 296 return 1
297 297
298 298 def getFirstHeader(self):
299 299
300 300 self.getBasicHeader()
301 301
302 302 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
303 303
304 304 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
305 305
306 306 # self.dataOut.ippSeconds = self.ippSeconds
307 307
308 308 # self.dataOut.timeInterval = self.radarControllerHeaderObj.ippSeconds * self.processingHeaderObj.nCohInt * self.processingHeaderObj.nIncohInt * self.processingHeaderObj.profilesPerBlock
309 309
310 310 self.dataOut.dtype = self.dtype
311 311
312 312 # self.dataOut.nPairs = self.nPairs
313 313
314 314 self.dataOut.pairsList = self.rdPairList
315 315
316 316 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
317 317
318 318 self.dataOut.nFFTPoints = self.processingHeaderObj.profilesPerBlock
319 319
320 320 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
321 321
322 322 self.dataOut.nIncohInt = self.processingHeaderObj.nIncohInt
323 323
324 324 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
325 325
326 326 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
327 327
328 328 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
329 329
330 330 self.dataOut.flagShiftFFT = True #Data is always shifted
331 331
332 332 self.dataOut.flagDecodeData = self.processingHeaderObj.flag_decode #asumo q la data no esta decodificada
333 333
334 334 self.dataOut.flagDeflipData = self.processingHeaderObj.flag_deflip #asumo q la data esta sin flip
335 335
336 336 def getData(self):
337 337 """
338 338 First method to execute before "RUN" is called.
339 339
340 340 Copia el buffer de lectura a la clase "Spectra",
341 341 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
342 342 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
343 343
344 344 Return:
345 345 0 : Si no hay mas archivos disponibles
346 346 1 : Si hizo una buena copia del buffer
347 347
348 348 Affected:
349 349 self.dataOut
350 350
351 351 self.flagDiscontinuousBlock
352 352 self.flagIsNewBlock
353 353 """
354 354
355 355 if self.flagNoMoreFiles:
356 356 self.dataOut.flagNoData = True
357 357 print 'Process finished'
358 358 return 0
359 359
360 360 self.flagDiscontinuousBlock = 0
361 361 self.flagIsNewBlock = 0
362 362
363 363 if self.__hasNotDataInBuffer():
364 364
365 365 if not( self.readNextBlock() ):
366 366 self.dataOut.flagNoData = True
367 367 return 0
368 368
369 369 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
370 370
371 371 if self.data_spc is None:
372 372 self.dataOut.flagNoData = True
373 373 return 0
374 374
375 375 self.getBasicHeader()
376 376
377 377 self.getFirstHeader()
378 378
379 379 self.dataOut.data_spc = self.data_spc
380 380
381 381 self.dataOut.data_cspc = self.data_cspc
382 382
383 383 self.dataOut.data_dc = self.data_dc
384 384
385 385 self.dataOut.flagNoData = False
386 386
387 387 self.dataOut.realtime = self.online
388 388
389 389 return self.dataOut.data_spc
390 390
391 391 class SpectraWriter(JRODataWriter, Operation):
392 392
393 393 """
394 394 Esta clase permite escribir datos de espectros a archivos procesados (.pdata). La escritura
395 395 de los datos siempre se realiza por bloques.
396 396 """
397 397
398 398 ext = ".pdata"
399 399
400 400 optchar = "P"
401 401
402 402 shape_spc_Buffer = None
403 403
404 404 shape_cspc_Buffer = None
405 405
406 406 shape_dc_Buffer = None
407 407
408 408 data_spc = None
409 409
410 410 data_cspc = None
411 411
412 412 data_dc = None
413 413
414 414 # dataOut = None
415 415
416 416 def __init__(self):
417 417 """
418 418 Inicializador de la clase SpectraWriter para la escritura de datos de espectros.
419 419
420 420 Affected:
421 421 self.dataOut
422 422 self.basicHeaderObj
423 423 self.systemHeaderObj
424 424 self.radarControllerHeaderObj
425 425 self.processingHeaderObj
426 426
427 427 Return: None
428 428 """
429 429
430 430 Operation.__init__(self)
431 431
432 432 self.isConfig = False
433 433
434 434 self.nTotalBlocks = 0
435 435
436 436 self.data_spc = None
437 437
438 438 self.data_cspc = None
439 439
440 440 self.data_dc = None
441 441
442 442 self.fp = None
443 443
444 444 self.flagIsNewFile = 1
445 445
446 446 self.nTotalBlocks = 0
447 447
448 448 self.flagIsNewBlock = 0
449 449
450 450 self.setFile = None
451 451
452 452 self.dtype = None
453 453
454 454 self.path = None
455 455
456 456 self.noMoreFiles = 0
457 457
458 458 self.filename = None
459 459
460 460 self.basicHeaderObj = BasicHeader(LOCALTIME)
461 461
462 462 self.systemHeaderObj = SystemHeader()
463 463
464 464 self.radarControllerHeaderObj = RadarControllerHeader()
465 465
466 466 self.processingHeaderObj = ProcessingHeader()
467 467
468 468
469 469 def hasAllDataInBuffer(self):
470 470 return 1
471 471
472 472
473 473 def setBlockDimension(self):
474 474 """
475 475 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
476 476
477 477 Affected:
478 478 self.shape_spc_Buffer
479 479 self.shape_cspc_Buffer
480 480 self.shape_dc_Buffer
481 481
482 482 Return: None
483 483 """
484 484 self.shape_spc_Buffer = (self.dataOut.nChannels,
485 485 self.processingHeaderObj.nHeights,
486 486 self.processingHeaderObj.profilesPerBlock)
487 487
488 488 self.shape_cspc_Buffer = (self.dataOut.nPairs,
489 489 self.processingHeaderObj.nHeights,
490 490 self.processingHeaderObj.profilesPerBlock)
491 491
492 492 self.shape_dc_Buffer = (self.dataOut.nChannels,
493 493 self.processingHeaderObj.nHeights)
494 494
495 495
496 496 def writeBlock(self):
497 497 """
498 498 Escribe el buffer en el file designado
499 499
500 500 Affected:
501 501 self.data_spc
502 502 self.data_cspc
503 503 self.data_dc
504 504 self.flagIsNewFile
505 505 self.flagIsNewBlock
506 506 self.nTotalBlocks
507 507 self.nWriteBlocks
508 508
509 509 Return: None
510 510 """
511 511
512 512 spc = numpy.transpose( self.data_spc, (0,2,1) )
513 513 if not( self.processingHeaderObj.shif_fft ):
514 514 spc = numpy.roll( spc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
515 515 data = spc.reshape((-1))
516 516 data = data.astype(self.dtype[0])
517 517 data.tofile(self.fp)
518 518
519 519 if self.data_cspc is not None:
520 520 data = numpy.zeros( self.shape_cspc_Buffer, self.dtype )
521 521 cspc = numpy.transpose( self.data_cspc, (0,2,1) )
522 522 if not( self.processingHeaderObj.shif_fft ):
523 523 cspc = numpy.roll( cspc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
524 524 data['real'] = cspc.real
525 525 data['imag'] = cspc.imag
526 526 data = data.reshape((-1))
527 527 data.tofile(self.fp)
528 528
529 529 if self.data_dc is not None:
530 530 data = numpy.zeros( self.shape_dc_Buffer, self.dtype )
531 531 dc = self.data_dc
532 532 data['real'] = dc.real
533 533 data['imag'] = dc.imag
534 534 data = data.reshape((-1))
535 535 data.tofile(self.fp)
536 536
537 537 # self.data_spc.fill(0)
538 538 #
539 539 # if self.data_dc is not None:
540 540 # self.data_dc.fill(0)
541 541 #
542 542 # if self.data_cspc is not None:
543 543 # self.data_cspc.fill(0)
544 544
545 545 self.flagIsNewFile = 0
546 546 self.flagIsNewBlock = 1
547 547 self.nTotalBlocks += 1
548 548 self.nWriteBlocks += 1
549 549 self.blockIndex += 1
550 550
551 551 # print "[Writing] Block = %d04" %self.blockIndex
552 552
553 553 def putData(self):
554 554 """
555 555 Setea un bloque de datos y luego los escribe en un file
556 556
557 557 Affected:
558 558 self.data_spc
559 559 self.data_cspc
560 560 self.data_dc
561 561
562 562 Return:
563 563 0 : Si no hay data o no hay mas files que puedan escribirse
564 564 1 : Si se escribio la data de un bloque en un file
565 565 """
566 566
567 567 if self.dataOut.flagNoData:
568 568 return 0
569 569
570 570 self.flagIsNewBlock = 0
571 571
572 572 if self.dataOut.flagDiscontinuousBlock:
573 573 self.data_spc.fill(0)
574 574 if self.dataOut.data_cspc is not None:
575 575 self.data_cspc.fill(0)
576 576 if self.dataOut.data_dc is not None:
577 577 self.data_dc.fill(0)
578 578 self.setNextFile()
579 579
580 580 if self.flagIsNewFile == 0:
581 581 self.setBasicHeader()
582 582
583 583 self.data_spc = self.dataOut.data_spc.copy()
584 584
585 585 if self.dataOut.data_cspc is not None:
586 586 self.data_cspc = self.dataOut.data_cspc.copy()
587 587
588 588 if self.dataOut.data_dc is not None:
589 589 self.data_dc = self.dataOut.data_dc.copy()
590 590
591 591 # #self.processingHeaderObj.dataBlocksPerFile)
592 592 if self.hasAllDataInBuffer():
593 593 # self.setFirstHeader()
594 594 self.writeNextBlock()
595 595
596 596 return 1
597 597
598 598 def __getBlockSize(self):
599 599 '''
600 600 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Spectra
601 601 '''
602 602
603 603 dtype_width = self.getDtypeWidth()
604 604
605 605 pts2write = self.dataOut.nHeights * self.dataOut.nFFTPoints
606 606
607 607 pts2write_SelfSpectra = int(self.dataOut.nChannels * pts2write)
608 608 blocksize = (pts2write_SelfSpectra*dtype_width)
609 609
610 610 if self.dataOut.data_cspc is not None:
611 611 pts2write_CrossSpectra = int(self.dataOut.nPairs * pts2write)
612 612 blocksize += (pts2write_CrossSpectra*dtype_width*2)
613 613
614 614 if self.dataOut.data_dc is not None:
615 615 pts2write_DCchannels = int(self.dataOut.nChannels * self.dataOut.nHeights)
616 616 blocksize += (pts2write_DCchannels*dtype_width*2)
617 617
618 618 # blocksize = blocksize #* datatypeValue * 2 #CORREGIR ESTO
619 619
620 620 return blocksize
621 621
622 622 def setFirstHeader(self):
623 623
624 624 """
625 625 Obtiene una copia del First Header
626 626
627 627 Affected:
628 628 self.systemHeaderObj
629 629 self.radarControllerHeaderObj
630 630 self.dtype
631 631
632 632 Return:
633 633 None
634 634 """
635 635
636 636 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
637 637 self.systemHeaderObj.nChannels = self.dataOut.nChannels
638 638 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
639 639
640 640 self.processingHeaderObj.dtype = 1 # Spectra
641 641 self.processingHeaderObj.blockSize = self.__getBlockSize()
642 642 self.processingHeaderObj.profilesPerBlock = self.dataOut.nFFTPoints
643 643 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
644 644 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
645 645 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt# Se requiere para determinar el valor de timeInterval
646 646 self.processingHeaderObj.nIncohInt = self.dataOut.nIncohInt
647 647 self.processingHeaderObj.totalSpectra = self.dataOut.nPairs + self.dataOut.nChannels
648 648 self.processingHeaderObj.shif_fft = self.dataOut.flagShiftFFT
649 649
650 650 if self.processingHeaderObj.totalSpectra > 0:
651 651 channelList = []
652 652 for channel in range(self.dataOut.nChannels):
653 653 channelList.append(channel)
654 654 channelList.append(channel)
655 655
656 656 pairsList = []
657 657 if self.dataOut.nPairs > 0:
658 658 for pair in self.dataOut.pairsList:
659 659 pairsList.append(pair[0])
660 660 pairsList.append(pair[1])
661 661
662 662 spectraComb = channelList + pairsList
663 663 spectraComb = numpy.array(spectraComb, dtype="u1")
664 664 self.processingHeaderObj.spectraComb = spectraComb
665 665
666 666 if self.dataOut.code is not None:
667 667 self.processingHeaderObj.code = self.dataOut.code
668 668 self.processingHeaderObj.nCode = self.dataOut.nCode
669 669 self.processingHeaderObj.nBaud = self.dataOut.nBaud
670 670
671 671 if self.processingHeaderObj.nWindows != 0:
672 672 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
673 673 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
674 674 self.processingHeaderObj.nHeights = self.dataOut.nHeights
675 675 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
676 676
677 677 self.processingHeaderObj.processFlags = self.getProcessFlags()
678 678
679 679 self.setBasicHeader()
@@ -1,294 +1,299
1 1 '''
2 2
3 3 $Author: murco $
4 4 $Id: jroproc_base.py 1 2012-11-12 18:56:07Z murco $
5 5 '''
6 6
7 7 class ProcessingUnit(object):
8 8
9 9 """
10 10 Esta es la clase base para el procesamiento de datos.
11 11
12 12 Contiene el metodo "call" para llamar operaciones. Las operaciones pueden ser:
13 13 - Metodos internos (callMethod)
14 14 - Objetos del tipo Operation (callObject). Antes de ser llamados, estos objetos
15 15 tienen que ser agreagados con el metodo "add".
16 16
17 17 """
18 18 # objeto de datos de entrada (Voltage, Spectra o Correlation)
19 19 dataIn = None
20 20 dataInList = []
21 21
22 22 # objeto de datos de entrada (Voltage, Spectra o Correlation)
23 23 dataOut = None
24 24
25 25 operations2RunDict = None
26 26
27 27 isConfig = False
28 28
29 29
30 def __init__(self):
30 def __init__(self, *args, **kwargs):
31 31
32 32 self.dataIn = None
33 33 self.dataInList = []
34 34
35 35 self.dataOut = None
36 36
37 37 self.operations2RunDict = {}
38 38
39 39 self.isConfig = False
40 40
41 self.args = args
42 self.kwargs = kwargs
43
41 44 def addOperation(self, opObj, objId):
42 45
43 46 """
44 47 Agrega un objeto del tipo "Operation" (opObj) a la lista de objetos "self.objectList" y retorna el
45 48 identificador asociado a este objeto.
46 49
47 50 Input:
48 51
49 52 object : objeto de la clase "Operation"
50 53
51 54 Return:
52 55
53 56 objId : identificador del objeto, necesario para ejecutar la operacion
54 57 """
55 58
56 59 self.operations2RunDict[objId] = opObj
57 60
58 61 return objId
59 62
60 63 def getOperationObj(self, objId):
61 64
62 65 if objId not in self.operations2RunDict.keys():
63 66 return None
64 67
65 68 return self.operations2RunDict[objId]
66 69
67 70 def operation(self, **kwargs):
68 71
69 72 """
70 73 Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los
71 74 atributos del objeto dataOut
72 75
73 76 Input:
74 77
75 78 **kwargs : Diccionario de argumentos de la funcion a ejecutar
76 79 """
77 80
78 81 raise NotImplementedError
79 82
80 83 def callMethod(self, name, **kwargs):
81 84
82 85 """
83 86 Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
84 87
85 88 Input:
86 89 name : nombre del metodo a ejecutar
87 90
88 91 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
89 92
90 93 """
91 94
92 95 #Checking the inputs
93 96 if name == 'run':
94 97
95 98 if not self.checkInputs():
96 99 self.dataOut.flagNoData = True
97 100 return False
98 101 else:
99 102 #Si no es un metodo RUN la entrada es la misma dataOut (interna)
100 103 if self.dataOut.isEmpty():
101 104 return False
102 105
103 106 #Getting the pointer to method
104 107 methodToCall = getattr(self, name)
105 108
106 109 #Executing the self method
107 methodToCall(**kwargs)
108 110
109 #Checkin the outputs
110
111 # if name == 'run':
112 # pass
113 # else:
114 # pass
115 #
116 # if name != 'run':
117 # return True
111 if hasattr(self, 'mp'):
112 if self.mp is False:
113 self.mp = True
114 self.start()
115 else:
116 methodToCall(**kwargs)
118 117
119 118 if self.dataOut is None:
120 119 return False
121 120
122 121 if self.dataOut.isEmpty():
123 122 return False
124 123
125 124 return True
126 125
127 def callObject(self, objId, **kwargs):
126 def callObject(self, objId):
128 127
129 128 """
130 129 Ejecuta la operacion asociada al identificador del objeto "objId"
131 130
132 131 Input:
133 132
134 133 objId : identificador del objeto a ejecutar
135 134
136 135 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
137 136
138 137 Return:
139 138
140 139 None
141 140 """
142 141
143 if self.dataOut.isEmpty():
142 if self.dataOut is not None and self.dataOut.isEmpty():
144 143 return False
145 144
146 145 externalProcObj = self.operations2RunDict[objId]
147 146
148 externalProcObj.run(self.dataOut, **kwargs)
147 if hasattr(externalProcObj, 'mp'):
148 if externalProcObj.mp is False:
149 externalProcObj.mp = True
150 externalProcObj.start()
151 else:
152 externalProcObj.run(self.dataOut, **externalProcObj.kwargs)
149 153
150 154 return True
151 155
152 def call(self, opType, opName=None, opId=None, **kwargs):
156 def call(self, opType, opName=None, opId=None):
153 157
154 158 """
155 159 Return True si ejecuta la operacion interna nombrada "opName" o la operacion externa
156 160 identificada con el id "opId"; con los argumentos "**kwargs".
157 161
158 162 False si la operacion no se ha ejecutado.
159 163
160 164 Input:
161 165
162 166 opType : Puede ser "self" o "external"
163 167
164 168 Depende del tipo de operacion para llamar a:callMethod or callObject:
165 169
166 170 1. If opType = "self": Llama a un metodo propio de esta clase:
167 171
168 172 name_method = getattr(self, name)
169 173 name_method(**kwargs)
170 174
171 175
172 176 2. If opType = "other" o"external": Llama al metodo "run()" de una instancia de la
173 177 clase "Operation" o de un derivado de ella:
174 178
175 179 instanceName = self.operationList[opId]
176 180 instanceName.run(**kwargs)
177 181
178 182 opName : Si la operacion es interna (opType = 'self'), entonces el "opName" sera
179 183 usada para llamar a un metodo interno de la clase Processing
180 184
181 185 opId : Si la operacion es externa (opType = 'other' o 'external), entonces el
182 186 "opId" sera usada para llamar al metodo "run" de la clase Operation
183 187 registrada anteriormente con ese Id
184 188
185 189 Exception:
186 190 Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
187 191 "addOperation" e identificado con el valor "opId" = el id de la operacion.
188 192 De lo contrario retornara un error del tipo ValueError
189 193
190 194 """
191 195
192 196 if opType == 'self':
193 197
194 198 if not opName:
195 199 raise ValueError, "opName parameter should be defined"
196 200
197 sts = self.callMethod(opName, **kwargs)
201 sts = self.callMethod(opName, **self.kwargs)
198 202
199 203 elif opType == 'other' or opType == 'external' or opType == 'plotter':
200 204
201 205 if not opId:
202 206 raise ValueError, "opId parameter should be defined"
203 207
204 208 if opId not in self.operations2RunDict.keys():
205 209 raise ValueError, "Any operation with id=%s has been added" %str(opId)
206 210
207 sts = self.callObject(opId, **kwargs)
211 sts = self.callObject(opId)
208 212
209 213 else:
210 214 raise ValueError, "opType should be 'self', 'external' or 'plotter'; and not '%s'" %opType
211 215
212 216 return sts
213 217
214 218 def setInput(self, dataIn):
215 219
216 220 self.dataIn = dataIn
217 221 self.dataInList.append(dataIn)
218 222
219 223 def getOutputObj(self):
220 224
221 225 return self.dataOut
222 226
223 227 def checkInputs(self):
224 228
225 229 for thisDataIn in self.dataInList:
226 230
227 231 if thisDataIn.isEmpty():
228 232 return False
229 233
230 234 return True
231 235
232 236 def setup(self):
233 237
234 238 raise NotImplementedError
235 239
236 240 def run(self):
237 241
238 242 raise NotImplementedError
239 243
240 244 def close(self):
241 245 #Close every thread, queue or any other object here is it is neccesary.
242 246 return
243 247
244 248 class Operation(object):
245 249
246 250 """
247 251 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
248 252 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
249 253 acumulacion dentro de esta clase
250 254
251 255 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
252 256
253 257 """
254 258
255 259 __buffer = None
256 260 isConfig = False
257 261
258 def __init__(self):
262 def __init__(self, **kwargs):
259 263
260 264 self.__buffer = None
261 265 self.isConfig = False
266 self.kwargs = kwargs
262 267
263 268 def setup(self):
264 269
265 270 self.isConfig = True
266 271
267 272 raise NotImplementedError
268 273
269 274 def run(self, dataIn, **kwargs):
270 275
271 276 """
272 277 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
273 278 atributos del objeto dataIn.
274 279
275 280 Input:
276 281
277 282 dataIn : objeto del tipo JROData
278 283
279 284 Return:
280 285
281 286 None
282 287
283 288 Affected:
284 289 __buffer : buffer de recepcion de datos.
285 290
286 291 """
287 292 if not self.isConfig:
288 293 self.setup(**kwargs)
289 294
290 295 raise NotImplementedError
291 296
292 297 def close(self):
293 298
294 299 pass
@@ -1,259 +1,378
1 1 '''
2 2 @author: Juan C. Espinoza
3 3 '''
4 4
5 5 import time
6 6 import json
7 7 import numpy
8 8 import paho.mqtt.client as mqtt
9 9 import zmq
10 10 import cPickle as pickle
11 11 import datetime
12 12 from zmq.utils.monitor import recv_monitor_message
13 13 from functools import wraps
14 14 from threading import Thread
15 15 from multiprocessing import Process
16 16
17 17 from schainpy.model.proc.jroproc_base import Operation, ProcessingUnit
18 18
19 MAXNUMX = 100
20 MAXNUMY = 100
19 21 throttle_value = 5
20 22
21 23 class PrettyFloat(float):
22 24 def __repr__(self):
23 25 return '%.2f' % self
24 26
25 27 def roundFloats(obj):
26 28 if isinstance(obj, list):
27 29 return map(roundFloats, obj)
28 30 elif isinstance(obj, float):
29 31 return round(obj, 2)
30 32
31 def pretty_floats(obj):
32 if isinstance(obj, float):
33 return PrettyFloat(obj)
34 elif isinstance(obj, dict):
35 return dict((k, pretty_floats(v)) for k, v in obj.items())
36 elif isinstance(obj, (list, tuple)):
37 return map(pretty_floats, obj)
38 return obj
39 33
40 34 class throttle(object):
41 35 """Decorator that prevents a function from being called more than once every
42 36 time period.
43 37 To create a function that cannot be called more than once a minute, but
44 38 will sleep until it can be called:
45 39 @throttle(minutes=1)
46 40 def foo():
47 41 pass
48 42
49 43 for i in range(10):
50 44 foo()
51 45 print "This function has run %s times." % i
52 46 """
53 47
54 48 def __init__(self, seconds=0, minutes=0, hours=0):
55 49 self.throttle_period = datetime.timedelta(
56 50 seconds=seconds, minutes=minutes, hours=hours
57 51 )
58 52 self.time_of_last_call = datetime.datetime.min
59 53
60 54 def __call__(self, fn):
61 55 @wraps(fn)
62 56 def wrapper(*args, **kwargs):
63 57 now = datetime.datetime.now()
64 58 time_since_last_call = now - self.time_of_last_call
65 59 time_left = self.throttle_period - time_since_last_call
66 60
67 61 if time_left > datetime.timedelta(seconds=0):
68 62 return
69 63
70 64 self.time_of_last_call = datetime.datetime.now()
71 65 return fn(*args, **kwargs)
72 66
73 67 return wrapper
74 68
75 69
76 70 class PublishData(Operation):
77 71 """Clase publish."""
78 72
79 __MAXNUMX = 100
80 __MAXNUMY = 100
81
82 73 def __init__(self, **kwargs):
83 74 """Inicio."""
84 75 Operation.__init__(self, **kwargs)
85 76 self.isConfig = False
86 77 self.client = None
87 78 self.zeromq = None
88 79 self.mqtt = None
89 80
90 81 def on_disconnect(self, client, userdata, rc):
91 82 if rc != 0:
92 83 print("Unexpected disconnection.")
93 84 self.connect()
94 85
95 86 def connect(self):
96 87 print 'trying to connect'
97 88 try:
98 89 self.client.connect(
99 90 host=self.host,
100 91 port=self.port,
101 92 keepalive=60*10,
102 93 bind_address='')
103 94 print "connected"
104 95 self.client.loop_start()
105 96 # self.client.publish(
106 97 # self.topic + 'SETUP',
107 98 # json.dumps(setup),
108 99 # retain=True
109 100 # )
110 101 except:
111 102 print "MQTT Conection error."
112 103 self.client = False
113 104
114 105 def setup(self, port=1883, username=None, password=None, clientId="user", zeromq=1, **kwargs):
115 106 self.counter = 0
116 107 self.topic = kwargs.get('topic', 'schain')
117 108 self.delay = kwargs.get('delay', 0)
118 109 self.plottype = kwargs.get('plottype', 'spectra')
119 110 self.host = kwargs.get('host', "10.10.10.82")
120 111 self.port = kwargs.get('port', 3000)
121 112 self.clientId = clientId
122 113 self.cnt = 0
123 114 self.zeromq = zeromq
124 115 self.mqtt = kwargs.get('plottype', 0)
125 116 self.client = None
126 117 setup = []
127 118 if mqtt is 1:
128 119 print 'mqqt es 1'
129 120 self.client = mqtt.Client(
130 121 client_id=self.clientId + self.topic + 'SCHAIN',
131 122 clean_session=True)
132 123 self.client.on_disconnect = self.on_disconnect
133 124 self.connect()
134 125 for plot in self.plottype:
135 126 setup.append({
136 127 'plot': plot,
137 128 'topic': self.topic + plot,
138 129 'title': getattr(self, plot + '_' + 'title', False),
139 130 'xlabel': getattr(self, plot + '_' + 'xlabel', False),
140 131 'ylabel': getattr(self, plot + '_' + 'ylabel', False),
141 132 'xrange': getattr(self, plot + '_' + 'xrange', False),
142 133 'yrange': getattr(self, plot + '_' + 'yrange', False),
143 134 'zrange': getattr(self, plot + '_' + 'zrange', False),
144 135 })
145 136 if zeromq is 1:
146 137 context = zmq.Context()
147 138 self.zmq_socket = context.socket(zmq.PUSH)
148 139 server = kwargs.get('server', 'zmq.pipe')
149 140
150 141 if 'tcp://' in server:
151 142 address = server
152 143 else:
153 144 address = 'ipc:///tmp/%s' % server
154 145
155 146 self.zmq_socket.connect(address)
156 147 time.sleep(1)
157 148 print 'zeromq configured'
158 149
159 150
160 151 def publish_data(self):
161 152 self.dataOut.finished = False
162 153 if self.mqtt is 1:
163 154 yData = self.dataOut.heightList[:2].tolist()
164 155 if self.plottype == 'spectra':
165 156 data = getattr(self.dataOut, 'data_spc')
166 157 z = data/self.dataOut.normFactor
167 158 zdB = 10*numpy.log10(z)
168 159 xlen, ylen = zdB[0].shape
169 dx = numpy.floor(xlen/self.__MAXNUMX) + 1
170 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
160 dx = int(xlen/MAXNUMX) + 1
161 dy = int(ylen/MAXNUMY) + 1
171 162 Z = [0 for i in self.dataOut.channelList]
172 163 for i in self.dataOut.channelList:
173 164 Z[i] = zdB[i][::dx, ::dy].tolist()
174 165 payload = {
175 166 'timestamp': self.dataOut.utctime,
176 167 'data': roundFloats(Z),
177 168 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
178 169 'interval': self.dataOut.getTimeInterval(),
179 170 'type': self.plottype,
180 171 'yData': yData
181 172 }
182 173 # print payload
183 174
184 175 elif self.plottype in ('rti', 'power'):
185 176 data = getattr(self.dataOut, 'data_spc')
186 177 z = data/self.dataOut.normFactor
187 178 avg = numpy.average(z, axis=1)
188 179 avgdB = 10*numpy.log10(avg)
189 180 xlen, ylen = z[0].shape
190 181 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
191 182 AVG = [0 for i in self.dataOut.channelList]
192 183 for i in self.dataOut.channelList:
193 184 AVG[i] = avgdB[i][::dy].tolist()
194 185 payload = {
195 186 'timestamp': self.dataOut.utctime,
196 187 'data': roundFloats(AVG),
197 188 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
198 189 'interval': self.dataOut.getTimeInterval(),
199 190 'type': self.plottype,
200 191 'yData': yData
201 192 }
202 193 elif self.plottype == 'noise':
203 194 noise = self.dataOut.getNoise()/self.dataOut.normFactor
204 195 noisedB = 10*numpy.log10(noise)
205 196 payload = {
206 197 'timestamp': self.dataOut.utctime,
207 198 'data': roundFloats(noisedB.reshape(-1, 1).tolist()),
208 199 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
209 200 'interval': self.dataOut.getTimeInterval(),
210 201 'type': self.plottype,
211 202 'yData': yData
212 203 }
213 204 elif self.plottype == 'snr':
214 205 data = getattr(self.dataOut, 'data_SNR')
215 206 avgdB = 10*numpy.log10(data)
216 207
217 208 ylen = data[0].size
218 209 dy = numpy.floor(ylen/self.__MAXNUMY) + 1
219 210 AVG = [0 for i in self.dataOut.channelList]
220 211 for i in self.dataOut.channelList:
221 212 AVG[i] = avgdB[i][::dy].tolist()
222 213 payload = {
223 214 'timestamp': self.dataOut.utctime,
224 215 'data': roundFloats(AVG),
225 216 'channels': ['Ch %s' % ch for ch in self.dataOut.channelList],
226 217 'type': self.plottype,
227 218 'yData': yData
228 219 }
229 220 else:
230 221 print "Tipo de grafico invalido"
231 222 payload = {
232 223 'data': 'None',
233 224 'timestamp': 'None',
234 225 'type': None
235 226 }
236 227 # print 'Publishing data to {}'.format(self.host)
237 228 self.client.publish(self.topic + self.plottype, json.dumps(payload), qos=0)
238 229
239 230 if self.zeromq is 1:
240 231 print '[Sending] {} - {}'.format(self.dataOut.type, self.dataOut.datatime)
241 232 self.zmq_socket.send_pyobj(self.dataOut)
242 233
243 234 def run(self, dataOut, **kwargs):
244 235 self.dataOut = dataOut
245 236 if not self.isConfig:
246 237 self.setup(**kwargs)
247 238 self.isConfig = True
248 239
249 240 self.publish_data()
250 241 time.sleep(self.delay)
251 242
252 243 def close(self):
253 244 if self.zeromq is 1:
254 245 self.dataOut.finished = True
255 246 self.zmq_socket.send_pyobj(self.dataOut)
256 247
257 248 if self.client:
258 249 self.client.loop_stop()
259 250 self.client.disconnect()
251
252
253 class ReceiverData(ProcessingUnit, Process):
254
255 def __init__(self, **kwargs):
256
257 ProcessingUnit.__init__(self, **kwargs)
258 Process.__init__(self)
259 self.mp = False
260 self.isConfig = False
261 self.plottypes =[]
262 self.connections = 0
263 server = kwargs.get('server', 'zmq.pipe')
264 if 'tcp://' in server:
265 address = server
266 else:
267 address = 'ipc:///tmp/%s' % server
268
269 self.address = address
270 self.plottypes = [s.strip() for s in kwargs.get('plottypes', 'rti').split(',')]
271 self.realtime = kwargs.get('realtime', False)
272 global throttle_value
273 throttle_value = kwargs.get('throttle', 10)
274 self.setup()
275
276 def setup(self):
277
278 self.data = {}
279 self.data['times'] = []
280 for plottype in self.plottypes:
281 self.data[plottype] = {}
282
283 self.isConfig = True
284
285 def event_monitor(self, monitor):
286
287 events = {}
288
289 for name in dir(zmq):
290 if name.startswith('EVENT_'):
291 value = getattr(zmq, name)
292 events[value] = name
293
294 while monitor.poll():
295 evt = recv_monitor_message(monitor)
296 if evt['event'] == 32:
297 self.connections += 1
298 if evt['event'] == 512:
299 pass
300 if self.connections == 0 and self.started is True:
301 self.ended = True
302 # send('ENDED')
303 evt.update({'description': events[evt['event']]})
304
305 if evt['event'] == zmq.EVENT_MONITOR_STOPPED:
306 break
307 monitor.close()
308 print("event monitor thread done!")
309
310 @throttle(seconds=throttle_value)
311 def sendData(self, data):
312 self.send(data)
313
314 def send(self, data):
315 print '[sending] data=%s size=%s' % (data.keys(), len(data['times']))
316 self.sender.send_pyobj(data)
317
318 def update(self):
319
320 t = self.dataOut.ltctime
321 self.data['times'].append(t)
322 self.data['dataOut'] = self.dataOut
323
324 for plottype in self.plottypes:
325
326 if plottype == 'spc':
327 z = self.dataOut.data_spc/self.dataOut.normFactor
328 zdB = 10*numpy.log10(z)
329 self.data[plottype] = zdB
330 if plottype == 'rti':
331 self.data[plottype][t] = self.dataOut.getPower()
332 if plottype == 'snr':
333 self.data[plottype][t] = 10*numpy.log10(self.dataOut.data_SNR)
334 if plottype == 'dop':
335 self.data[plottype][t] = 10*numpy.log10(self.dataOut.data_DOP)
336 if plottype == 'coh':
337 self.data[plottype][t] = self.dataOut.getCoherence()
338 if plottype == 'phase':
339 self.data[plottype][t] = self.dataOut.getCoherence(phase=True)
340
341 def run(self):
342
343 print '[Starting] {} from {}'.format(self.name, self.address)
344
345 self.context = zmq.Context()
346 self.receiver = self.context.socket(zmq.PULL)
347 self.receiver.bind(self.address)
348 monitor = self.receiver.get_monitor_socket()
349 self.sender = self.context.socket(zmq.PUB)
350
351 self.sender.bind("ipc:///tmp/zmq.plots")
352
353 t = Thread(target=self.event_monitor, args=(monitor,))
354 t.start()
355
356 while True:
357 self.dataOut = self.receiver.recv_pyobj()
358 print '[Receiving] {} - {}'.format(self.dataOut.type,
359 self.dataOut.datatime.ctime())
360
361 self.update()
362
363 if self.dataOut.finished is True:
364 self.send(self.data)
365 self.connections -= 1
366 if self.connections==0 and self.started:
367 self.ended = True
368 self.data['ENDED'] = True
369 self.send(self.data)
370 self.setup()
371 else:
372 if self.realtime:
373 self.send(self.data)
374 else:
375 self.sendData(self.data)
376 self.started = True
377
378 return
General Comments 0
You need to be logged in to leave comments. Login now