##// END OF EJS Templates
Testeado con datos de Imagenes (Espectros)...
Miguel Valdez -
r201:86bbb8030d3e
parent child
Show More
@@ -1,634 +1,643
1 1 '''
2 2 Created on September , 2012
3 3 @author:
4 4 '''
5 5 from xml.etree.ElementTree import Element, SubElement, ElementTree
6 6 from xml.etree import ElementTree as ET
7 7 from xml.dom import minidom
8 8
9 9 import sys
10 10 import datetime
11 11 from model.jrodataIO import *
12 12 from model.jroprocessing import *
13 13 from model.jroplot import *
14 14
15 15 def prettify(elem):
16 16 """Return a pretty-printed XML string for the Element.
17 17 """
18 18 rough_string = ET.tostring(elem, 'utf-8')
19 19 reparsed = minidom.parseString(rough_string)
20 20 return reparsed.toprettyxml(indent=" ")
21 21
22 22 class ParameterConf():
23 23
24 24 id = None
25 25 name = None
26 26 value = None
27 27 format = None
28 28
29 29 ELEMENTNAME = 'Parameter'
30 30
31 31 def __init__(self):
32 32
33 33 self.format = 'str'
34 34
35 35 def getElementName(self):
36 36
37 37 return self.ELEMENTNAME
38 38
39 39 def getValue(self):
40 40
41 41 if self.format == 'list':
42 42 strList = self.value.split(',')
43 43 return strList
44 44
45 45 if self.format == 'intlist':
46 46 strList = self.value.split(',')
47 47 intList = [int(x) for x in strList]
48 48 return intList
49 49
50 50 if self.format == 'floatlist':
51 51 strList = self.value.split(',')
52 52 floatList = [float(x) for x in strList]
53 53 return floatList
54 54
55 55 if self.format == 'date':
56 56 strList = self.value.split('/')
57 57 intList = [int(x) for x in strList]
58 58 date = datetime.date(intList[0], intList[1], intList[2])
59 59 return date
60 60
61 61 if self.format == 'time':
62 62 strList = self.value.split(':')
63 63 intList = [int(x) for x in strList]
64 64 time = datetime.time(intList[0], intList[1], intList[2])
65 65 return time
66 66
67 67 func = eval(self.format)
68 68
69 69 return func(self.value)
70 70
71 71 def setup(self, id, name, value, format='str'):
72 72
73 73 self.id = id
74 74 self.name = name
75 75 self.value = str(value)
76 76 self.format = format
77 77
78 78 def makeXml(self, opElement):
79 79
80 80 parmElement = SubElement(opElement, self.ELEMENTNAME)
81 81 parmElement.set('id', str(self.id))
82 82 parmElement.set('name', self.name)
83 83 parmElement.set('value', self.value)
84 84 parmElement.set('format', self.format)
85 85
86 86 def readXml(self, parmElement):
87 87
88 88 self.id = parmElement.get('id')
89 89 self.name = parmElement.get('name')
90 90 self.value = parmElement.get('value')
91 91 self.format = parmElement.get('format')
92 92
93 93 def printattr(self):
94 94
95 95 print "Parameter[%s]: name = %s, value = %s, format = %s" %(self.id, self.name, self.value, self.format)
96 96
97 97 class OperationConf():
98 98
99 99 id = None
100 100 name = None
101 101 priority = None
102 102 type = None
103 103
104 104 parmConfObjList = []
105 105
106 106 ELEMENTNAME = 'Operation'
107 107
108 108 def __init__(self):
109 109
110 110 id = 0
111 111 name = None
112 112 priority = None
113 113 type = 'self'
114 114
115 115
116 116 def __getNewId(self):
117 117
118 118 return int(self.id)*10 + len(self.parmConfObjList) + 1
119 119
120 120 def getElementName(self):
121 121
122 122 return self.ELEMENTNAME
123 123
124 124 def getParameterObjList(self):
125 125
126 126 return self.parmConfObjList
127 127
128 128 def setup(self, id, name, priority, type):
129 129
130 130 self.id = id
131 131 self.name = name
132 132 self.type = type
133 133 self.priority = priority
134 134
135 135 self.parmConfObjList = []
136 136
137 137 def addParameter(self, name, value, format='str'):
138 138
139 139 id = self.__getNewId()
140 140
141 141 parmConfObj = ParameterConf()
142 142 parmConfObj.setup(id, name, value, format)
143 143
144 144 self.parmConfObjList.append(parmConfObj)
145 145
146 146 return parmConfObj
147 147
148 148 def makeXml(self, upElement):
149 149
150 150 opElement = SubElement(upElement, self.ELEMENTNAME)
151 151 opElement.set('id', str(self.id))
152 152 opElement.set('name', self.name)
153 153 opElement.set('type', self.type)
154 154 opElement.set('priority', str(self.priority))
155 155
156 156 for parmConfObj in self.parmConfObjList:
157 157 parmConfObj.makeXml(opElement)
158 158
159 159 def readXml(self, opElement):
160 160
161 161 self.id = opElement.get('id')
162 162 self.name = opElement.get('name')
163 163 self.type = opElement.get('type')
164 164 self.priority = opElement.get('priority')
165 165
166 166 self.parmConfObjList = []
167 167
168 168 parmElementList = opElement.getiterator(ParameterConf().getElementName())
169 169
170 170 for parmElement in parmElementList:
171 171 parmConfObj = ParameterConf()
172 172 parmConfObj.readXml(parmElement)
173 173 self.parmConfObjList.append(parmConfObj)
174 174
175 175 def printattr(self):
176 176
177 177 print "%s[%s]: name = %s, type = %s, priority = %s" %(self.ELEMENTNAME,
178 178 self.id,
179 179 self.name,
180 180 self.type,
181 181 self.priority)
182 182
183 183 for parmConfObj in self.parmConfObjList:
184 184 parmConfObj.printattr()
185 185
186 186 def createObject(self):
187 187
188 188 if self.type == 'self':
189 189 raise ValueError, "This operation type cannot be created"
190 190
191 191 if self.type == 'other':
192 192 className = eval(self.name)
193 193 opObj = className()
194 194
195 195 return opObj
196 196
197 197 class ProcUnitConf():
198 198
199 199 id = None
200 200 name = None
201 201 datatype = None
202 202 inputId = None
203 203
204 204 opConfObjList = []
205 205
206 206 procUnitObj = None
207 207 opObjList = []
208 208
209 209 ELEMENTNAME = 'ProcUnit'
210 210
211 211 def __init__(self):
212 212
213 213 self.id = None
214 214 self.datatype = None
215 215 self.name = None
216 216 self.inputId = None
217 217
218 218 self.opConfObjList = []
219 219
220 220 self.procUnitObj = None
221 221 self.opObjDict = {}
222 222
223 223 def __getPriority(self):
224 224
225 225 return len(self.opConfObjList)+1
226 226
227 227 def __getNewId(self):
228 228
229 229 return int(self.id)*10 + len(self.opConfObjList) + 1
230 230
231 231 def getElementName(self):
232 232
233 233 return self.ELEMENTNAME
234 234
235 235 def getId(self):
236 236
237 237 return str(self.id)
238 238
239 239 def getInputId(self):
240 240
241 241 return str(self.inputId)
242 242
243 243 def getOperationObjList(self):
244 244
245 245 return self.opConfObjList
246 246
247 247 def getProcUnitObj(self):
248 248
249 249 return self.procUnitObj
250 250
251 251 def setup(self, id, name, datatype, inputId):
252 252
253 253 self.id = id
254 254 self.name = name
255 255 self.datatype = datatype
256 256 self.inputId = inputId
257 257
258 258 self.opConfObjList = []
259 259
260 260 self.addOperation(name='init', optype='self')
261 261
262 262 def addOperation(self, name, optype='self'):
263 263
264 264 id = self.__getNewId()
265 265 priority = self.__getPriority()
266 266
267 267 opConfObj = OperationConf()
268 268 opConfObj.setup(id, name=name, priority=priority, type=optype)
269 269
270 270 self.opConfObjList.append(opConfObj)
271 271
272 272 return opConfObj
273 273
274 274 def makeXml(self, procUnitElement):
275 275
276 276 upElement = SubElement(procUnitElement, self.ELEMENTNAME)
277 277 upElement.set('id', str(self.id))
278 278 upElement.set('name', self.name)
279 279 upElement.set('datatype', self.datatype)
280 280 upElement.set('inputId', str(self.inputId))
281 281
282 282 for opConfObj in self.opConfObjList:
283 283 opConfObj.makeXml(upElement)
284 284
285 285 def readXml(self, upElement):
286 286
287 287 self.id = upElement.get('id')
288 288 self.name = upElement.get('name')
289 289 self.datatype = upElement.get('datatype')
290 290 self.inputId = upElement.get('inputId')
291 291
292 292 self.opConfObjList = []
293 293
294 294 opElementList = upElement.getiterator(OperationConf().getElementName())
295 295
296 296 for opElement in opElementList:
297 297 opConfObj = OperationConf()
298 298 opConfObj.readXml(opElement)
299 299 self.opConfObjList.append(opConfObj)
300 300
301 301 def printattr(self):
302 302
303 303 print "%s[%s]: name = %s, datatype = %s, inputId = %s" %(self.ELEMENTNAME,
304 304 self.id,
305 305 self.name,
306 306 self.datatype,
307 307 self.inputId)
308 308
309 309 for opConfObj in self.opConfObjList:
310 310 opConfObj.printattr()
311 311
312 312 def createObjects(self):
313 313
314 314 className = eval(self.name)
315 315 procUnitObj = className()
316 316
317 317 for opConfObj in self.opConfObjList:
318 318
319 319 if opConfObj.type == 'self':
320 320 continue
321 321
322 322 opObj = opConfObj.createObject()
323 323
324 324 self.opObjDict[opConfObj.id] = opObj
325 325 procUnitObj.addOperation(opObj, opConfObj.id)
326 326
327 327 self.procUnitObj = procUnitObj
328 328
329 329 return procUnitObj
330 330
331 331 def run(self):
332 332
333 333 finalSts = False
334 334
335 335 for opConfObj in self.opConfObjList:
336 336
337 337 kwargs = {}
338 338 for parmConfObj in opConfObj.getParameterObjList():
339 339 kwargs[parmConfObj.name] = parmConfObj.getValue()
340 340
341 341 #print "\tRunning the '%s' operation with %s" %(opConfObj.name, opConfObj.id)
342 342 sts = self.procUnitObj.call(opConfObj, **kwargs)
343 343 finalSts = finalSts or sts
344 344
345 345 return finalSts
346 346
347 347 class ReadUnitConf(ProcUnitConf):
348 348
349 349 path = None
350 350 startDate = None
351 351 endDate = None
352 352 startTime = None
353 353 endTime = None
354 354 online = None
355 355 expLabel = None
356 356 delay = None
357 357
358 358 ELEMENTNAME = 'ReadUnit'
359 359
360 360 def __init__(self):
361 361
362 362 self.id = None
363 363 self.datatype = None
364 364 self.name = None
365 365 self.inputId = 0
366 366
367 367 self.opConfObjList = []
368 368 self.opObjList = []
369 369
370 370 def getElementName(self):
371 371
372 372 return self.ELEMENTNAME
373 373
374 374 def setup(self, id, name, datatype, path, startDate, endDate, startTime, endTime, online=0, expLabel='', delay=60):
375 375
376 376 self.id = id
377 377 self.name = name
378 378 self.datatype = datatype
379 379
380 380 self.path = path
381 381 self.startDate = startDate
382 382 self.endDate = endDate
383 383 self.startTime = startTime
384 384 self.endTime = endTime
385 385 self.online = online
386 386 self.expLabel = expLabel
387 387 self.delay = delay
388 388
389 389 self.addRunOperation()
390 390
391 391 def addRunOperation(self):
392 392
393 393 opObj = self.addOperation(name = 'run', optype = 'self')
394 394
395 395 opObj.addParameter(name='path' , value=self.path, format='str')
396 396 opObj.addParameter(name='startDate' , value=self.startDate, format='date')
397 397 opObj.addParameter(name='endDate' , value=self.endDate, format='date')
398 398 opObj.addParameter(name='startTime' , value=self.startTime, format='time')
399 399 opObj.addParameter(name='endTime' , value=self.endTime, format='time')
400 400 opObj.addParameter(name='expLabel' , value=self.expLabel, format='str')
401 401 opObj.addParameter(name='online' , value=self.online, format='int')
402 402 opObj.addParameter(name='delay' , value=self.delay, format='float')
403 403
404 404 return opObj
405 405
406 406
407 407 class Controller():
408 408
409 409 id = None
410 410 name = None
411 411 description = None
412 412 # readUnitConfObjList = None
413 413 procUnitConfObjDict = None
414 414
415 415 ELEMENTNAME = 'Controller'
416 416
417 417 def __init__(self):
418 418
419 419 self.id = None
420 420 self.name = None
421 421 self.description = None
422 422
423 423 # self.readUnitConfObjList = []
424 424 self.procUnitConfObjDict = {}
425 425
426 426 def __getNewId(self):
427 427
428 428 id = int(self.id)*10 + len(self.procUnitConfObjDict) + 1
429 429
430 430 return str(id)
431 431
432 432 def getElementName(self):
433 433
434 434 return self.ELEMENTNAME
435 435
436 436 def setup(self, id, name, description):
437 437
438 438 self.id = id
439 439 self.name = name
440 440 self.description = description
441 441
442 442 def addReadUnit(self, datatype, path, startDate='', endDate='', startTime='', endTime='', online=0, expLabel='', delay=60):
443 443
444 444 id = self.__getNewId()
445 445 name = '%sReader' %(datatype)
446 446
447 447 readUnitConfObj = ReadUnitConf()
448 448 readUnitConfObj.setup(id, name, datatype, path, startDate, endDate, startTime, endTime, online, expLabel, delay)
449 449
450 450 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
451 451
452 452 return readUnitConfObj
453 453
454 454 def addProcUnit(self, datatype, inputId):
455 455
456 456 id = self.__getNewId()
457 457 name = '%sProc' %(datatype)
458 458
459 459 procUnitConfObj = ProcUnitConf()
460 460 procUnitConfObj.setup(id, name, datatype, inputId)
461 461
462 462 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
463 463
464 464 return procUnitConfObj
465 465
466 466 def makeXml(self):
467 467
468 468 projectElement = Element('Controller')
469 469 projectElement.set('id', str(self.id))
470 470 projectElement.set('name', self.name)
471 471 projectElement.set('description', self.description)
472 472
473 473 # for readUnitConfObj in self.readUnitConfObjList:
474 474 # readUnitConfObj.makeXml(projectElement)
475 475
476 476 for procUnitConfObj in self.procUnitConfObjDict.values():
477 477 procUnitConfObj.makeXml(projectElement)
478 478
479 479 self.projectElement = projectElement
480 480
481 481 def writeXml(self, filename):
482 482
483 483 self.makeXml()
484 484
485 485 print prettify(self.projectElement)
486 486
487 487 ElementTree(self.projectElement).write(filename, method='xml')
488 488
489 489 def readXml(self, filename):
490 490
491 491 #tree = ET.parse(filename)
492 492 self.projectElement = None
493 493 # self.readUnitConfObjList = []
494 494 self.procUnitConfObjDict = {}
495 495
496 496 self.projectElement = ElementTree().parse(filename)
497 497
498 498 self.project = self.projectElement.tag
499 499
500 500 self.id = self.projectElement.get('id')
501 501 self.name = self.projectElement.get('name')
502 502 self.description = self.projectElement.get('description')
503 503
504 504 readUnitElementList = self.projectElement.getiterator(ReadUnitConf().getElementName())
505 505
506 506 for readUnitElement in readUnitElementList:
507 507 readUnitConfObj = ReadUnitConf()
508 508 readUnitConfObj.readXml(readUnitElement)
509 509
510 510 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
511 511
512 512 procUnitElementList = self.projectElement.getiterator(ProcUnitConf().getElementName())
513 513
514 514 for procUnitElement in procUnitElementList:
515 515 procUnitConfObj = ProcUnitConf()
516 516 procUnitConfObj.readXml(procUnitElement)
517 517
518 518 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
519 519
520 520 def printattr(self):
521 521
522 522 print "Controller[%s]: name = %s, description = %s" %(self.id,
523 523 self.name,
524 524 self.description)
525 525
526 526 # for readUnitConfObj in self.readUnitConfObjList:
527 527 # readUnitConfObj.printattr()
528 528
529 529 for procUnitConfObj in self.procUnitConfObjDict.values():
530 530 procUnitConfObj.printattr()
531 531
532 532 def createObjects(self):
533 533
534 534 # for readUnitConfObj in self.readUnitConfObjList:
535 535 # readUnitConfObj.createObjects()
536 536
537 537 for procUnitConfObj in self.procUnitConfObjDict.values():
538 538 procUnitConfObj.createObjects()
539 539
540 540 def __connect(self, objIN, obj):
541 541
542 542 obj.setInput(objIN.getOutput())
543 543
544 544 def connectObjects(self):
545 545
546 546 for puConfObj in self.procUnitConfObjDict.values():
547 547
548 548 inputId = puConfObj.getInputId()
549 549
550 550 if int(inputId) == 0:
551 551 continue
552 552
553 553 puConfINObj = self.procUnitConfObjDict[inputId]
554 554
555 555 puObj = puConfObj.getProcUnitObj()
556 556 puINObj = puConfINObj.getProcUnitObj()
557 557
558 558 self.__connect(puINObj, puObj)
559 559
560 560 def run(self):
561 561
562 562 # for readUnitConfObj in self.readUnitConfObjList:
563 563 # readUnitConfObj.run()
564 564
565 565 while(True):
566 566
567 567 finalSts = False
568 568
569 569 for procUnitConfObj in self.procUnitConfObjDict.values():
570 570 #print "Running the '%s' process with %s" %(procUnitConfObj.name, procUnitConfObj.id)
571 571 sts = procUnitConfObj.run()
572 572 finalSts = finalSts or sts
573 573
574 574 #If every process unit finished so end process
575 575 if not(finalSts):
576 576 print "Every process units have finished"
577 577 break
578 578
579 579 if __name__ == '__main__':
580 580
581 581 desc = "Segundo Test"
582 582 filename = "schain.xml"
583 583
584 584 controllerObj = Controller()
585 585
586 586 controllerObj.setup(id = '191', name='test01', description=desc)
587 587
588 588 readUnitConfObj = controllerObj.addReadUnit(datatype='Spectra',
589 589 path='D:\Data\IMAGING',
590 590 startDate='2011/01/01',
591 591 endDate='2012/12/31',
592 592 startTime='00:00:00',
593 593 endTime='23:59:59',
594 594 online=0)
595 595
596 596 opObj00 = readUnitConfObj.addOperation(name='printTotalBlocks')
597 597
598 598 procUnitConfObj1 = controllerObj.addProcUnit(datatype='Spectra', inputId=readUnitConfObj.getId())
599 599
600 600 opObj10 = procUnitConfObj1.addOperation(name='selectChannels')
601 opObj10.addParameter(name='channelList', value='0,1,3', format='intlist')
601 opObj10.addParameter(name='channelList', value='0,1', format='intlist')
602 602
603 603 opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other')
604 604 opObj11.addParameter(name='idfigure', value='1', format='int')
605 605 opObj11.addParameter(name='wintitle', value='SpectraPlot', format='str')
606 opObj11.addParameter(name='zmin', value='60', format='int')
607 opObj11.addParameter(name='zmax', value='100', format='int')
606 # opObj11.addParameter(name='zmin', value='60', format='int')
607 # opObj11.addParameter(name='zmax', value='100', format='int')
608
609 opObj12 = procUnitConfObj1.addOperation(name='IncohInt', optype='other')
610 opObj12.addParameter(name='n', value='30', format='int')
611
612 opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other')
613 opObj11.addParameter(name='idfigure', value='2', format='int')
614 opObj11.addParameter(name='wintitle', value='SpectraPlot10', format='str')
615 # opObj11.addParameter(name='zmin', value='60', format='int')
616 # opObj11.addParameter(name='zmax', value='100', format='int')
608 617
609 618 # opObj12 = procUnitConfObj1.addOperation(name='decoder')
610 619 # opObj12.addParameter(name='ncode', value='2', format='int')
611 620 # opObj12.addParameter(name='nbauds', value='8', format='int')
612 621 # opObj12.addParameter(name='code0', value='001110011', format='int')
613 622 # opObj12.addParameter(name='code1', value='001110011', format='int')
614 623
615 624 # procUnitConfObj2 = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObj1.getId())
616 625
617 626
618 627 # opObj21 = procUnitConfObj2.addOperation(name='IncohInt', optype='other')
619 628 # opObj21.addParameter(name='nCohInt', value='10', format='int')
620 629
621 630
622 631 print "Escribiendo el archivo XML"
623 632
624 633 controllerObj.writeXml(filename)
625 634
626 635 print "Leyendo el archivo XML"
627 636 controllerObj.readXml(filename)
628 637 #controllerObj.printattr()
629 638
630 639 controllerObj.createObjects()
631 640 controllerObj.connectObjects()
632 641 controllerObj.run()
633 642
634 643 No newline at end of file
@@ -1,84 +1,231
1 import numpy
1 2 import mpldriver
2 3
4
3 5 class Figure:
4 axesList = None
6
7 __driver = mpldriver
8
9 idfigure = None
10 wintitle = None
5 11 width = None
6 12 height = None
7 def __init__(self):
8 pass
13 nplots = None
14
15 axesObjList = []
16
17 WIDTH = None
18 HEIGHT = None
19
20 def __init__(self):
21
22 raise ValueError, "This method is not implemented"
23
24 def getAxesObjList(self):
25
26 return self.axesObjList
27
28 def getSubplots(self):
29
30 raise ValueError, "Abstract method: This method should be defined"
31
32 def getScreenDim(self):
33
34 nrow, ncol = self.getSubplots()
35
36 width = self.WIDTH*ncol
37 height = self.HEIGHT*nrow
38
39 return width, height
40
41 def init(self, idfigure, nplots, wintitle):
42
43 """
44 Inicializa la figura de acuerdo al driver seleccionado
45 Input:
46 *args : Los parametros necesarios son
47 idfigure, wintitle, width, height
48 """
9 49
10 def init(self, idfigure, wintitle, width, height, nplots):
11 50 self.idfigure = idfigure
12 self.wintitle = wintitle
13 self.width = width
14 self.height = height
51
15 52 self.nplots = nplots
16 self.fig = mpldriver.init(idfigure, wintitle, width, height)
17 53
18 self.axesList = []
54 self.wintitle = wintitle
55
56 self.width, self.height = self.getScreenDim()
57
58 self.fig = self.__driver.createFigure(self.idfigure,
59 self.wintitle,
60 self.width,
61 self.height)
62
63 self.axesObjList = []
19 64
65 def setDriver(self, driver=mpldriver):
66
67 self.__driver = driver
68
20 69 def setTitle(self, title):
21 mpldriver.setTitle(self.idfigure, title)
70
71 self.__driver.setTitle(self.fig, title)
22 72
23 def setWinTitle(self,title):
24 mpldriver.setWinTitle(fig=self.fig, title=title)
73 def setWinTitle(self, title):
74
75 self.__driver.setWinTitle(self.fig, title=title)
25 76
26 def setTextFromAxes(self, title):
27 mpldriver.setTextFromAxes(self.idfigure, self.axesList[0].ax, title)
77 def setTextFromAxes(self, text):
78
79 raise ValueError, "Este metodo ha sido reemplazaado con el metodo setText de la clase Axes"
28 80
29 81 def makeAxes(self, nrow, ncol, xpos, ypos, colspan, rowspan):
30 ax = mpldriver.makeAxes(self.idfigure, nrow, ncol, xpos, ypos, colspan, rowspan)
31 axesObj = Axes(ax)
32 self.axesList.append(axesObj)
82
83 raise ValueError, "Este metodo ha sido reemplazaado con el metodo addAxes"
84
85 def addAxes(self, *args):
86 """
87
88 Input:
89 *args : Los parametros necesarios son
90 nrow, ncol, xpos, ypos, colspan, rowspan
91 """
92
93 axesObj = Axes(self.fig, *args)
94 self.axesObjList.append(axesObj)
33 95
34 96 def draw(self):
35 mpldriver.draw(self.idfigure)
97
98 self.__driver.draw(self.fig)
36 99
37 100 def run(self):
38 pass
101
102 raise ValueError, "This method is not implemented"
103
104 axesList = property(getAxesObjList)
39 105
40 106
41 107 class Axes:
42 firsttime = None
108
109 __driver = mpldriver
110 fig = None
43 111 ax = None
44 mesh = None
112 plot = None
45 113
46 def __init__(self, ax):
47 self.firsttime = True
114 firsttime = None
115
116 def __init__(self, *args):
117
118 """
119
120 Input:
121 *args : Los parametros necesarios son
122 fig, nrow, ncol, xpos, ypos, colspan, rowspan
123 """
124
125 ax = self.__driver.createAxes(*args)
126 self.fig = args[0]
48 127 self.ax = ax
49 self.mesh = None
50
51 def pline(self, x, y, xmin, xmax, ymin, ymax, xlabel, ylabel, title):
52
53 mpldriver.pline(ax=self.ax,
54 x=x,
55 y=y,
56 xmin=xmin,
57 xmax=xmax,
58 ymin=ymin,
59 ymax=ymax,
60 xlabel=xlabel,
61 ylabel=ylabel,
62 title=title,
63 firsttime=self.firsttime)
64
65 self.firsttime = False
66
67 def pcolor(self, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax, xlabel, ylabel, title):
68 meshfromaxes=mpldriver.pcolor(ax=self.ax,
69 x=x,
70 y=y,
71 z=z,
72 xmin=xmin,
73 xmax=xmax,
74 ymin=ymin,
75 ymax=ymax,
76 zmin=zmin,
77 zmax=zmax,
78 xlabel=xlabel,
79 ylabel=ylabel,
80 title=title,
81 firsttime=self.firsttime,
82 mesh=self.mesh)
83 self.mesh = meshfromaxes
84 self.firsttime = False
128 self.plot = None
129
130 self.firsttime = True
131
132 def setText(self, text):
133
134 self.__driver.setAxesText(self.ax, text)
135
136 def pline(self, x, y,
137 xmin=None, xmax=None,
138 ymin=None, ymax=None,
139 xlabel='', ylabel='',
140 title='',
141 **kwargs):
142
143 """
144
145 Input:
146 x :
147 y :
148 xmin :
149 xmax :
150 ymin :
151 ymax :
152 xlabel :
153 ylabel :
154 title :
155 **kwargs : Los parametros aceptados son
156
157 ticksize
158 """
159
160 if self.firsttime:
161
162 if xmin == None: xmin = numpy.nanmin(x)
163 if xmax == None: xmax = numpy.nanmax(x)
164 if ymin == None: ymin = numpy.nanmin(y)
165 if ymax == None: ymax = numpy.nanmax(y)
166
167 self.plot = self.__driver.createPline(self.ax, x, y,
168 xmin, xmax,
169 ymin, ymax,
170 xlabel=xlabel,
171 ylabel=ylabel,
172 title=title,
173 **kwargs)
174 self.firsttime = False
175 return
176
177 self.__driver.pline(self.plot, x, y, xlabel=xlabel,
178 ylabel=ylabel,
179 title=title)
180
181
182 def pcolor(self, x, y, z,
183 xmin=None, xmax=None,
184 ymin=None, ymax=None,
185 zmin=None, zmax=None,
186 xlabel='', ylabel='',
187 title='',
188 **kwargs):
189
190 """
191 Input:
192 x :
193 y :
194 x :
195 xmin :
196 xmax :
197 ymin :
198 ymax :
199 zmin :
200 zmax :
201 xlabel :
202 ylabel :
203 title :
204 **kwargs : Los parametros aceptados son
205 ticksize=9,
206 cblabel=''
207 """
208
209 if self.firsttime:
210
211 if xmin == None: xmin = numpy.nanmin(x)
212 if xmax == None: xmax = numpy.nanmax(x)
213 if ymin == None: ymin = numpy.nanmin(y)
214 if ymax == None: ymax = numpy.nanmax(y)
215 if zmin == None: zmin = numpy.nanmin(z)
216 if zmax == None: zmax = numpy.nanmax(z)
217
218 self.plot = self.__driver.createPcolor(self.ax, x, y, z,
219 xmin, xmax,
220 ymin, ymax,
221 zmin, zmax,
222 xlabel=xlabel,
223 ylabel=ylabel,
224 title=title,
225 **kwargs)
226 self.firsttime = False
227 return
228
229 mesh = self.__driver.pcolor(self.plot, z, xlabel=xlabel,
230 ylabel=ylabel,
231 title=title)
@@ -1,86 +1,215
1 import numpy
1 2 import matplotlib
2 3 matplotlib.use("TKAgg")
3 4 import matplotlib.pyplot
4 5 #import scitools.numpyutils
5 6 from mpl_toolkits.axes_grid1 import make_axes_locatable
6 7
7 def init(idfigure, wintitle, width, height):
8 def init(idfigure, wintitle, width, height, facecolor="w"):
9
8 10 matplotlib.pyplot.ioff()
9 fig = matplotlib.pyplot.matplotlib.pyplot.figure(num=idfigure, facecolor="w")
11 fig = matplotlib.pyplot.matplotlib.pyplot.figure(num=idfigure, facecolor=facecolor)
10 12 fig.canvas.manager.set_window_title(wintitle)
11 fig.canvas.manager.resize(width,height)
13 fig.canvas.manager.resize(width, height)
12 14 matplotlib.pyplot.ion()
15
13 16 return fig
14 17
15 18 def setWinTitle(fig, title):
19
16 20 fig.canvas.manager.set_window_title(title)
17 21
18 def setTextFromAxes(idfigure, ax, title):
19 fig = matplotlib.pyplot.figure(idfigure)
20 ax.annotate(title, xy=(.1, .99),
21 xycoords='figure fraction',
22 horizontalalignment='left', verticalalignment='top',
23 fontsize=10)
24
25 22 def setTitle(idfigure, title):
26 23 fig = matplotlib.pyplot.figure(idfigure)
27 24 fig.suptitle(title)
28 25
29 26 def makeAxes(idfigure, nrow, ncol, xpos, ypos, colspan, rowspan):
30 27 fig = matplotlib.pyplot.figure(idfigure)
31 28 ax = matplotlib.pyplot.subplot2grid((nrow, ncol), (xpos, ypos), colspan=colspan, rowspan=rowspan)
32 29 return ax
33 30
31 def setTextFromAxes(idfigure, ax, title):
32 fig = matplotlib.pyplot.figure(idfigure)
33 ax.annotate(title, xy=(.1, .99),
34 xycoords='figure fraction',
35 horizontalalignment='left', verticalalignment='top',
36 fontsize=10)
37
34 38 def pline(ax, x, y, xmin, xmax, ymin, ymax, xlabel, ylabel, title, firsttime):
39
35 40 if firsttime:
36 41 ax.plot(x, y)
37 42 ax.set_xlim([xmin,xmax])
38 43 ax.set_ylim([ymin,ymax])
39 44 ax.set_xlabel(xlabel, size=8)
40 45 ax.set_ylabel(ylabel, size=8)
41 46 ax.set_title(title, size=10)
42 47 matplotlib.pyplot.tight_layout()
43 48 else:
44 49 ax.lines[0].set_data(x,y)
45 50
46 51 def draw(idfigure):
52
47 53 fig = matplotlib.pyplot.figure(idfigure)
48 54 fig.canvas.draw()
49 55
50 56 def pcolor(ax, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax, xlabel, ylabel, title, firsttime, mesh):
57
51 58 if firsttime:
52 59 divider = make_axes_locatable(ax)
53 ax_cb = divider.new_horizontal(size="5%", pad=0.05)
60 ax_cb = divider.new_horizontal(size="4%", pad=0.05)
54 61 fig1 = ax.get_figure()
55 62 fig1.add_axes(ax_cb)
56 63
57 64 ax.set_xlim([xmin,xmax])
58 65 ax.set_ylim([ymin,ymax])
59 66 ax.set_xlabel(xlabel)
60 67 ax.set_ylabel(ylabel)
61 68 ax.set_title(title)
62
69 print x
63 70 imesh=ax.pcolormesh(x,y,z.T,vmin=zmin,vmax=zmax)
64 71 matplotlib.pyplot.colorbar(imesh, cax=ax_cb)
65 72 ax_cb.yaxis.tick_right()
66 73 for tl in ax_cb.get_yticklabels():
67 74 tl.set_visible(True)
68 75 ax_cb.yaxis.tick_right()
69 76 matplotlib.pyplot.tight_layout()
70 77 return imesh
71 78 else:
72 ax.set_xlim([xmin,xmax])
73 ax.set_ylim([ymin,ymax])
79 # ax.set_xlim([xmin,xmax])
80 # ax.set_ylim([ymin,ymax])
74 81 ax.set_xlabel(xlabel)
75 82 ax.set_ylabel(ylabel)
76 83 ax.set_title(title)
77 84
78 85 z = z.T
79 z = z[0:-1,0:-1]
86 # z = z[0:-1,0:-1]
80 87 mesh.set_array(z.ravel())
81 88
82 89 return mesh
83 90
91 ###########################################
92 #Actualizacion de las funciones del driver
93 ###########################################
94
95 def createFigure(idfigure, wintitle, width, height, facecolor="w"):
96
97 matplotlib.pyplot.ioff()
98 fig = matplotlib.pyplot.matplotlib.pyplot.figure(num=idfigure, facecolor=facecolor)
99 fig.canvas.manager.set_window_title(wintitle)
100 fig.canvas.manager.resize(width, height)
101 matplotlib.pyplot.ion()
102
103 return fig
104
105 def setWinTitle(fig, title):
106
107 fig.canvas.manager.set_window_title(title)
108
109 def setTitle(fig, title):
110
111 fig.suptitle(title)
112
113 def createAxes(fig, nrow, ncol, xpos, ypos, colspan, rowspan):
114
115 matplotlib.pyplot.figure(fig.number)
116 axes = matplotlib.pyplot.subplot2grid((nrow, ncol),
117 (xpos, ypos),
118 colspan=colspan,
119 rowspan=rowspan)
120 return axes
121
122 def setAxesText(ax, text):
123
124 ax.annotate(text,
125 xy = (.1, .99),
126 xycoords = 'figure fraction',
127 horizontalalignment = 'left',
128 verticalalignment = 'top',
129 fontsize = 10)
130
131 def printLabels(ax, xlabel, ylabel, title):
132
133 ax.set_xlabel(xlabel, size=11)
134 ax.set_ylabel(ylabel, size=11)
135 ax.set_title(title, size=12)
136
137 def createPline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', ticksize = 9):
138
139 ax.plot(x, y)
140 ax.set_xlim([xmin,xmax])
141 ax.set_ylim([ymin,ymax])
142
143 printLabels(ax, xlabel, ylabel, title)
144
145 for tick in ax.yaxis.get_major_ticks():
146 tick.label.set_fontsize(ticksize)
147
148 for tick in ax.xaxis.get_major_ticks():
149 tick.label.set_fontsize(ticksize)
150
151 matplotlib.pyplot.tight_layout()
152
153 iplot = ax.lines[-1]
154
155 return iplot
156
157 def pline(iplot, x, y, xlabel='', ylabel='', title=''):
158
159 ax = iplot.get_axes()
160
161 printLabels(ax, xlabel, ylabel, title)
162
163 iplot.set_data(x, y)
164
165 def createPcolor(ax, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax, xlabel='', ylabel='', title='', ticksize = 9, cblabel=''):
166
167 divider = make_axes_locatable(ax)
168 ax_cb = divider.new_horizontal(size="4%", pad=0.05)
169 fig = ax.get_figure()
170 fig.add_axes(ax_cb)
171
172 ax.set_xlim([xmin,xmax])
173 ax.set_ylim([ymin,ymax])
174
175 printLabels(ax, xlabel, ylabel, title)
176
177 imesh = ax.pcolormesh(x,y,z.T,vmin=zmin,vmax=zmax)
178 cb = matplotlib.pyplot.colorbar(imesh, cax=ax_cb)
179 cb.set_label(cblabel)
180
181 ax_cb.yaxis.tick_right()
182
183 for tl in ax_cb.get_yticklabels():
184 tl.set_visible(True)
185
186 for tick in ax.yaxis.get_major_ticks():
187 tick.label.set_fontsize(ticksize)
188
189 for tick in ax.xaxis.get_major_ticks():
190 tick.label.set_fontsize(ticksize)
191
192 for tick in cb.ax.get_yticklabels():
193 tick.set_fontsize(ticksize)
194
195 ax_cb.yaxis.tick_right()
196 matplotlib.pyplot.tight_layout()
197
198 return imesh
84 199
200 def pcolor(imesh, z, xlabel='', ylabel='', title=''):
201
202 z = z.T
203
204 ax = imesh.get_axes()
205
206 printLabels(ax, xlabel, ylabel, title)
207
208 imesh.set_array(z.ravel())
85 209
86 No newline at end of file
210 def draw(fig):
211
212 if type(fig) == 'int':
213 raise ValueError, "This parameter should be of tpye matplotlib figure"
214
215 fig.canvas.draw() No newline at end of file
@@ -1,430 +1,462
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 os, sys
8 8 import copy
9 9 import numpy
10 10
11 11 from jroheaderIO import SystemHeader, RadarControllerHeader
12 12
13 13 def hildebrand_sekhon(data, navg):
14 14 """
15 15 This method is for the objective determination of de noise level in Doppler spectra. This
16 16 implementation technique is based on the fact that the standard deviation of the spectral
17 17 densities is equal to the mean spectral density for white Gaussian noise
18 18
19 19 Inputs:
20 20 Data : heights
21 21 navg : numbers of averages
22 22
23 23 Return:
24 24 -1 : any error
25 25 anoise : noise's level
26 26 """
27 27
28 dataflat = data.reshape(-1)
28 dataflat = data.copy().reshape(-1)
29 29 dataflat.sort()
30 30 npts = dataflat.size #numbers of points of the data
31 31
32 32 if npts < 32:
33 33 print "error in noise - requires at least 32 points"
34 34 return -1.0
35 35
36 36 dataflat2 = numpy.power(dataflat,2)
37 37
38 38 cs = numpy.cumsum(dataflat)
39 39 cs2 = numpy.cumsum(dataflat2)
40 40
41 41 # data sorted in ascending order
42 42 nmin = int((npts + 7.)/8)
43 43
44 44 for i in range(nmin, npts):
45 45 s = cs[i]
46 46 s2 = cs2[i]
47 47 p = s / float(i);
48 48 p2 = p**2;
49 49 q = s2 / float(i) - p2;
50 50 leftc = p2;
51 51 rightc = q * float(navg);
52 52 R2 = leftc/rightc
53 53
54 54 # Signal detect: R2 < 1 (R2 = leftc/rightc)
55 55 if R2 < 1:
56 56 npts_noise = i
57 57 break
58 58
59 59
60 60 anoise = numpy.average(dataflat[0:npts_noise])
61 61
62 62 return anoise;
63 63
64 def sorting_bruce(Data, navg):
65 sortdata = numpy.sort(Data)
66 lenOfData = len(Data)
64 def sorting_bruce(data, navg):
65
66 data = data.copy()
67
68 sortdata = numpy.sort(data)
69 lenOfData = len(data)
67 70 nums_min = lenOfData/10
68 71
69 72 if (lenOfData/10) > 0:
70 73 nums_min = lenOfData/10
71 74 else:
72 75 nums_min = 0
73 76
74 77 rtest = 1.0 + 1.0/navg
75 78
76 79 sum = 0.
77 80
78 81 sumq = 0.
79 82
80 83 j = 0
81 84
82 85 cont = 1
83 86
84 87 while((cont==1)and(j<lenOfData)):
85 88
86 89 sum += sortdata[j]
87 90
88 91 sumq += sortdata[j]**2
89 92
90 93 j += 1
91 94
92 95 if j > nums_min:
93 96 if ((sumq*j) <= (rtest*sum**2)):
94 97 lnoise = sum / j
95 98 else:
96 99 j = j - 1
97 100 sum = sum - sordata[j]
98 101 sumq = sumq - sordata[j]**2
99 102 cont = 0
100 103
101 104 if j == nums_min:
102 105 lnoise = sum /j
103 106
104 107 return lnoise
105 108
106 109 class JROData:
107 110
108 111 # m_BasicHeader = BasicHeader()
109 112 # m_ProcessingHeader = ProcessingHeader()
110 113
111 114 systemHeaderObj = SystemHeader()
112 115
113 116 radarControllerHeaderObj = RadarControllerHeader()
114 117
115 118 # data = None
116 119
117 120 type = None
118 121
119 122 dtype = None
120 123
121 124 # nChannels = None
122 125
123 126 nHeights = None
124 127
125 128 nProfiles = None
126 129
127 130 heightList = None
128 131
129 132 channelList = None
130 133
131 134 flagNoData = True
132 135
133 136 flagTimeBlock = False
134 137
135 138 utctime = None
136 139
137 140 blocksize = None
138 141
139 142 nCode = None
140 143
141 144 nBaud = None
142 145
143 146 code = None
144 147
145 148 flagDecodeData = True #asumo q la data esta decodificada
146 149
147 150 flagDeflipData = True #asumo q la data esta sin flip
148 151
149 152 flagShiftFFT = False
150 153
151 154 ippSeconds = None
152 155
153 156 timeInterval = None
154 157
155 158 nCohInt = None
156 159
157 160 noise = None
161
162 #Speed of ligth
163 C = 3e8
164
165 frequency = 49.92e6
158 166
159 167 def __init__(self):
160 168
161 169 raise ValueError, "This class has not been implemented"
162 170
163 171 def copy(self, inputObj=None):
164 172
165 173 if inputObj == None:
166 174 return copy.deepcopy(self)
167 175
168 176 for key in inputObj.__dict__.keys():
169 177 self.__dict__[key] = inputObj.__dict__[key]
170 178
171 179 def deepcopy(self):
172 180
173 181 return copy.deepcopy(self)
174 182
175 183 def isEmpty(self):
176 184
177 185 return self.flagNoData
178 186
179 187 def getNChannels(self):
180 188
181 189 return len(self.channelList)
182 190
183 191 def getChannelIndexList(self):
184 192
185 193 return range(self.nChannels)
186 194
187 195 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
188 196 channelIndexList = property(getChannelIndexList, "I'm the 'channelIndexList' property.")
189 197
190 198 class Voltage(JROData):
191 199
192 200 #data es un numpy array de 2 dmensiones (canales, alturas)
193 201 data = None
194 202
195 203 def __init__(self):
196 204 '''
197 205 Constructor
198 206 '''
199 207
200 208 self.radarControllerHeaderObj = RadarControllerHeader()
201 209
202 210 self.systemHeaderObj = SystemHeader()
203 211
204 212 self.type = "Voltage"
205 213
206 214 self.data = None
207 215
208 216 self.dtype = None
209 217
210 218 # self.nChannels = 0
211 219
212 220 self.nHeights = 0
213 221
214 222 self.nProfiles = None
215 223
216 224 self.heightList = None
217 225
218 226 self.channelList = None
219 227
220 228 # self.channelIndexList = None
221 229
222 230 self.flagNoData = True
223 231
224 232 self.flagTimeBlock = False
225 233
226 234 self.utctime = None
227 235
228 236 self.nCohInt = None
229 237
230 238 self.blocksize = None
231 239
232 240 def getNoisebyHildebrand(self):
233 241 """
234 242 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
235 243
236 244 Return:
237 245 noiselevel
238 246 """
239 247
240 248 for channel in range(self.nChannels):
241 249 daux = self.data_spc[channel,:,:]
242 250 self.noise[channel] = hildebrand_sekhon(daux, self.nCohInt)
243 251
244 252 return self.noise
245 253
246 254 def getNoise(self, type = 1):
247 255
248 256 self.noise = numpy.zeros(self.nChannels)
249 257
250 258 if type == 1:
251 259 noise = self.getNoisebyHildebrand()
252 260
253 261 return 10*numpy.log10(noise)
254 262
255 263 class Spectra(JROData):
256 264
257 265 #data es un numpy array de 2 dmensiones (canales, perfiles, alturas)
258 266 data_spc = None
259 267
260 268 #data es un numpy array de 2 dmensiones (canales, pares, alturas)
261 269 data_cspc = None
262 270
263 271 #data es un numpy array de 2 dmensiones (canales, alturas)
264 272 data_dc = None
265 273
266 274 nFFTPoints = None
267 275
268 276 nPairs = None
269 277
270 278 pairsList = None
271 279
272 280 nIncohInt = None
273 281
274 282 wavelength = None #Necesario para cacular el rango de velocidad desde la frecuencia
275 283
276 284 nCohInt = None #se requiere para determinar el valor de timeInterval
277 285
278 286 def __init__(self):
279 287 '''
280 288 Constructor
281 289 '''
282 290
283 291 self.radarControllerHeaderObj = RadarControllerHeader()
284 292
285 293 self.systemHeaderObj = SystemHeader()
286 294
287 295 self.type = "Spectra"
288 296
289 297 # self.data = None
290 298
291 299 self.dtype = None
292 300
293 301 # self.nChannels = 0
294 302
295 303 self.nHeights = 0
296 304
297 305 self.nProfiles = None
298 306
299 307 self.heightList = None
300 308
301 309 self.channelList = None
302 310
303 311 # self.channelIndexList = None
304 312
305 313 self.flagNoData = True
306 314
307 315 self.flagTimeBlock = False
308 316
309 317 self.utctime = None
310 318
311 319 self.nCohInt = None
312 320
313 321 self.nIncohInt = None
314 322
315 323 self.blocksize = None
316 324
317 325 self.nFFTPoints = None
318 326
319 327 self.wavelength = None
320 328
321 def getFrequencies(self):
329 def getFmax(self):
330
331 PRF = 1./(self.ippSeconds * self.nCohInt)
332
333 fmax = PRF/2.
334
335 return fmax
336
337 def getVmax(self):
338
339 _lambda = self.C/self.frequency
340
341 vmax = self.getFmax() * _lambda / 2.
342
343 return vmax
344
345 def getFreqRange(self, extrapoints=0):
346
347 delfreq = 2 * self.getFmax() / self.nFFTPoints
348 freqrange = deltafreqs*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2
349
350 return freqrange
351
352 def getVelRange(self, extrapoints=0):
353
354 deltav = 2 * self.getVmax() / self.nFFTPoints
355 velrange = deltav*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltav/2
322 356
323 xrange = numpy.arange(self.nFFTPoints)
324 xrange = xrange
325 return None
357 return velrange
326 358
327 359 def getNoisebyHildebrand(self):
328 360 """
329 361 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
330 362
331 363 Return:
332 364 noiselevel
333 365 """
334 366
335 367 for channel in range(self.nChannels):
336 368 daux = self.data_spc[channel,:,:]
337 369 self.noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
338 370
339 371 return self.noise
340 372
341 373 def getNoisebyWindow(self, heiIndexMin=0, heiIndexMax=-1, freqIndexMin=0, freqIndexMax=-1):
342 374 """
343 375 Determina el ruido del canal utilizando la ventana indicada con las coordenadas:
344 376 (heiIndexMIn, freqIndexMin) hasta (heiIndexMax, freqIndexMAx)
345 377
346 378 Inputs:
347 379 heiIndexMin: Limite inferior del eje de alturas
348 380 heiIndexMax: Limite superior del eje de alturas
349 381 freqIndexMin: Limite inferior del eje de frecuencia
350 382 freqIndexMax: Limite supoerior del eje de frecuencia
351 383 """
352 384
353 385 data = self.data_spc[:, heiIndexMin:heiIndexMax, freqIndexMin:freqIndexMax]
354 386
355 387 for channel in range(self.nChannels):
356 388 daux = data[channel,:,:]
357 389 self.noise[channel] = numpy.average(daux)
358 390
359 391 return self.noise
360 392
361 393 def getNoisebySort(self):
362 394
363 395 for channel in range(self.nChannels):
364 396 daux = self.data_spc[channel,:,:]
365 397 self.noise[channel] = sorting_bruce(daux, self.nIncohInt)
366 398
367 399 return self.noise
368 400
369 401 def getNoise(self, type = 1):
370 402
371 403 self.noise = numpy.zeros(self.nChannels)
372 404
373 405 if type == 1:
374 406 noise = self.getNoisebyHildebrand()
375 407
376 408 if type == 2:
377 409 noise = self.getNoisebySort()
378 410
379 411 if type == 3:
380 412 noise = self.getNoisebyWindow()
381 413
382 414 return 10*numpy.log10(noise)
383 415
384 416 class SpectraHeis(JROData):
385 417
386 418 data_spc = None
387 419
388 420 data_cspc = None
389 421
390 422 data_dc = None
391 423
392 424 nFFTPoints = None
393 425
394 426 nPairs = None
395 427
396 428 pairsList = None
397 429
398 430 nIncohInt = None
399 431
400 432 def __init__(self):
401 433
402 434 self.radarControllerHeaderObj = RadarControllerHeader()
403 435
404 436 self.systemHeaderObj = SystemHeader()
405 437
406 438 self.type = "SpectraHeis"
407 439
408 440 self.dtype = None
409 441
410 442 # self.nChannels = 0
411 443
412 444 self.nHeights = 0
413 445
414 446 self.nProfiles = None
415 447
416 448 self.heightList = None
417 449
418 450 self.channelList = None
419 451
420 452 # self.channelIndexList = None
421 453
422 454 self.flagNoData = True
423 455
424 456 self.flagTimeBlock = False
425 457
426 458 self.nPairs = 0
427 459
428 460 self.utctime = None
429 461
430 462 self.blocksize = None
@@ -1,2478 +1,2479
1 1 '''
2 2
3 3 $Author: murco $
4 4 $Id: JRODataIO.py 169 2012-11-19 21:57:03Z murco $
5 5 '''
6 6
7 7 import os, sys
8 8 import glob
9 9 import time
10 10 import numpy
11 11 import fnmatch
12 12 import time, datetime
13 13
14 14 from jrodata import *
15 15 from jroheaderIO import *
16 16 from jroprocessing import *
17 17
18 18 def isNumber(str):
19 19 """
20 20 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
21 21
22 22 Excepciones:
23 23 Si un determinado string no puede ser convertido a numero
24 24 Input:
25 25 str, string al cual se le analiza para determinar si convertible a un numero o no
26 26
27 27 Return:
28 28 True : si el string es uno numerico
29 29 False : no es un string numerico
30 30 """
31 31 try:
32 32 float( str )
33 33 return True
34 34 except:
35 35 return False
36 36
37 37 def isThisFileinRange(filename, startUTSeconds, endUTSeconds):
38 38 """
39 39 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
40 40
41 41 Inputs:
42 42 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
43 43
44 44 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
45 45 segundos contados desde 01/01/1970.
46 46 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
47 47 segundos contados desde 01/01/1970.
48 48
49 49 Return:
50 50 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
51 51 fecha especificado, de lo contrario retorna False.
52 52
53 53 Excepciones:
54 54 Si el archivo no existe o no puede ser abierto
55 55 Si la cabecera no puede ser leida.
56 56
57 57 """
58 58 basicHeaderObj = BasicHeader()
59 59
60 60 try:
61 61 fp = open(filename,'rb')
62 62 except:
63 63 raise IOError, "The file %s can't be opened" %(filename)
64 64
65 65 sts = basicHeaderObj.read(fp)
66 66 fp.close()
67 67
68 68 if not(sts):
69 69 print "Skipping the file %s because it has not a valid header" %(filename)
70 70 return 0
71 71
72 72 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
73 73 return 0
74 74
75 75 return 1
76 76
77 77 def getlastFileFromPath(path, ext):
78 78 """
79 79 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
80 80 al final de la depuracion devuelve el ultimo file de la lista que quedo.
81 81
82 82 Input:
83 83 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
84 84 ext : extension de los files contenidos en una carpeta
85 85
86 86 Return:
87 87 El ultimo file de una determinada carpeta, no se considera el path.
88 88 """
89 89 validFilelist = []
90 90 fileList = os.listdir(path)
91 91
92 92 # 0 1234 567 89A BCDE
93 93 # H YYYY DDD SSS .ext
94 94
95 95 for file in fileList:
96 96 try:
97 97 year = int(file[1:5])
98 98 doy = int(file[5:8])
99 99
100 100 if (os.path.splitext(file)[-1].upper() != ext.upper()) : continue
101 101 except:
102 102 continue
103 103
104 104 validFilelist.append(file)
105 105
106 106 if validFilelist:
107 107 validFilelist = sorted( validFilelist, key=str.lower )
108 108 return validFilelist[-1]
109 109
110 110 return None
111 111
112 112 def checkForRealPath(path, year, doy, set, ext):
113 113 """
114 114 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
115 115 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
116 116 el path exacto de un determinado file.
117 117
118 118 Example :
119 119 nombre correcto del file es .../.../D2009307/P2009307367.ext
120 120
121 121 Entonces la funcion prueba con las siguientes combinaciones
122 122 .../.../x2009307/y2009307367.ext
123 123 .../.../x2009307/Y2009307367.ext
124 124 .../.../X2009307/y2009307367.ext
125 125 .../.../X2009307/Y2009307367.ext
126 126 siendo para este caso, la ultima combinacion de letras, identica al file buscado
127 127
128 128 Return:
129 129 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
130 130 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
131 131 para el filename
132 132 """
133 133 filepath = None
134 134 find_flag = False
135 135 filename = None
136 136
137 137 if ext.lower() == ".r": #voltage
138 138 header1 = "dD"
139 139 header2 = "dD"
140 140 elif ext.lower() == ".pdata": #spectra
141 141 header1 = "dD"
142 142 header2 = "pP"
143 143 else:
144 144 return None, filename
145 145
146 146 for dir in header1: #barrido por las dos combinaciones posibles de "D"
147 147 for fil in header2: #barrido por las dos combinaciones posibles de "D"
148 148 doypath = "%s%04d%03d" % ( dir, year, doy ) #formo el nombre del directorio xYYYYDDD (x=d o x=D)
149 149 filename = "%s%04d%03d%03d%s" % ( fil, year, doy, set, ext ) #formo el nombre del file xYYYYDDDSSS.ext
150 150 filepath = os.path.join( path, doypath, filename ) #formo el path completo
151 151 if os.path.exists( filepath ): #verifico que exista
152 152 find_flag = True
153 153 break
154 154 if find_flag:
155 155 break
156 156
157 157 if not(find_flag):
158 158 return None, filename
159 159
160 160 return filepath, filename
161 161
162 162 class JRODataIO:
163 163
164 164 c = 3E8
165 165
166 166 isConfig = False
167 167
168 168 basicHeaderObj = BasicHeader()
169 169
170 170 systemHeaderObj = SystemHeader()
171 171
172 172 radarControllerHeaderObj = RadarControllerHeader()
173 173
174 174 processingHeaderObj = ProcessingHeader()
175 175
176 176 online = 0
177 177
178 178 dtype = None
179 179
180 180 pathList = []
181 181
182 182 filenameList = []
183 183
184 184 filename = None
185 185
186 186 ext = None
187 187
188 188 flagIsNewFile = 1
189 189
190 190 flagTimeBlock = 0
191 191
192 192 flagIsNewBlock = 0
193 193
194 194 fp = None
195 195
196 196 firstHeaderSize = 0
197 197
198 198 basicHeaderSize = 24
199 199
200 200 versionFile = 1103
201 201
202 202 fileSize = None
203 203
204 204 ippSeconds = None
205 205
206 206 fileSizeByHeader = None
207 207
208 208 fileIndex = None
209 209
210 210 profileIndex = None
211 211
212 212 blockIndex = None
213 213
214 214 nTotalBlocks = None
215 215
216 216 maxTimeStep = 30
217 217
218 218 lastUTTime = None
219 219
220 220 datablock = None
221 221
222 222 dataOut = None
223 223
224 224 blocksize = None
225 225
226 226 def __init__(self):
227 227
228 228 raise ValueError, "Not implemented"
229 229
230 230 def run(self):
231 231
232 232 raise ValueError, "Not implemented"
233 233
234 234 def getOutput(self):
235 235
236 236 return self.dataOut
237 237
238 238 class JRODataReader(JRODataIO, ProcessingUnit):
239 239
240 240 nReadBlocks = 0
241 241
242 242 delay = 60 #number of seconds waiting a new file
243 243
244 244 nTries = 3 #quantity tries
245 245
246 246 nFiles = 3 #number of files for searching
247 247
248 248 flagNoMoreFiles = 0
249 249
250 250 def __init__(self):
251 251
252 252 """
253 253
254 254 """
255 255
256 256 raise ValueError, "This method has not been implemented"
257 257
258 258
259 259 def createObjByDefault(self):
260 260 """
261 261
262 262 """
263 263 raise ValueError, "This method has not been implemented"
264 264
265 265 def getBlockDimension(self):
266 266
267 267 raise ValueError, "No implemented"
268 268
269 269 def __searchFilesOffLine(self,
270 270 path,
271 271 startDate,
272 272 endDate,
273 273 startTime=datetime.time(0,0,0),
274 274 endTime=datetime.time(23,59,59),
275 275 set=None,
276 276 expLabel="",
277 277 ext=".r"):
278 278 dirList = []
279 279 for thisPath in os.listdir(path):
280 280 if os.path.isdir(os.path.join(path,thisPath)):
281 281 dirList.append(thisPath)
282 282
283 283 if not(dirList):
284 284 return None, None
285 285
286 286 pathList = []
287 287 dateList = []
288 288
289 289 thisDate = startDate
290 290
291 291 while(thisDate <= endDate):
292 292 year = thisDate.timetuple().tm_year
293 293 doy = thisDate.timetuple().tm_yday
294 294
295 295 match = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy))
296 296 if len(match) == 0:
297 297 thisDate += datetime.timedelta(1)
298 298 continue
299 299
300 300 pathList.append(os.path.join(path,match[0],expLabel))
301 301 dateList.append(thisDate)
302 302 thisDate += datetime.timedelta(1)
303 303
304 304 filenameList = []
305 305 for index in range(len(pathList)):
306 306
307 307 thisPath = pathList[index]
308 308 fileList = glob.glob1(thisPath, "*%s" %ext)
309 309 fileList.sort()
310 310
311 311 #Busqueda de datos en el rango de horas indicados
312 312 thisDate = dateList[index]
313 313 startDT = datetime.datetime.combine(thisDate, startTime)
314 314 endDT = datetime.datetime.combine(thisDate, endTime)
315 315
316 316 startUtSeconds = time.mktime(startDT.timetuple())
317 317 endUtSeconds = time.mktime(endDT.timetuple())
318 318
319 319 for file in fileList:
320 320
321 321 filename = os.path.join(thisPath,file)
322 322
323 323 if isThisFileinRange(filename, startUtSeconds, endUtSeconds):
324 324 filenameList.append(filename)
325 325
326 326 if not(filenameList):
327 327 return None, None
328 328
329 329 self.filenameList = filenameList
330 330
331 331 return pathList, filenameList
332 332
333 333 def __searchFilesOnLine(self, path, startDate=None, endDate=None, startTime=None, endTime=None, expLabel = "", ext = None):
334 334
335 335 """
336 336 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
337 337 devuelve el archivo encontrado ademas de otros datos.
338 338
339 339 Input:
340 340 path : carpeta donde estan contenidos los files que contiene data
341 341
342 342 startDate : Fecha inicial. Rechaza todos los directorios donde
343 343 file end time < startDate (obejto datetime.date)
344 344
345 345 endDate : Fecha final. Rechaza todos los directorios donde
346 346 file start time > endDate (obejto datetime.date)
347 347
348 348 startTime : Tiempo inicial. Rechaza todos los archivos donde
349 349 file end time < startTime (obejto datetime.time)
350 350
351 351 endTime : Tiempo final. Rechaza todos los archivos donde
352 352 file start time > endTime (obejto datetime.time)
353 353
354 354 expLabel : Nombre del subexperimento (subfolder)
355 355
356 356 ext : extension de los files
357 357
358 358 Return:
359 359 directory : eL directorio donde esta el file encontrado
360 360 filename : el ultimo file de una determinada carpeta
361 361 year : el anho
362 362 doy : el numero de dia del anho
363 363 set : el set del archivo
364 364
365 365
366 366 """
367 367 dirList = []
368 368 pathList = []
369 369 directory = None
370 370
371 371 #Filtra solo los directorios
372 372 for thisPath in os.listdir(path):
373 373 if os.path.isdir(os.path.join(path, thisPath)):
374 374 dirList.append(thisPath)
375 375
376 376 if not(dirList):
377 377 return None, None, None, None, None
378 378
379 379 dirList = sorted( dirList, key=str.lower )
380 380
381 381 if startDate:
382 382 startDateTime = datetime.datetime.combine(startDate, startTime)
383 383 thisDateTime = startDateTime
384 384 if endDate == None: endDateTime = startDateTime
385 385 else: endDateTime = datetime.datetime.combine(endDate, endTime)
386 386
387 387 while(thisDateTime <= endDateTime):
388 388 year = thisDateTime.timetuple().tm_year
389 389 doy = thisDateTime.timetuple().tm_yday
390 390
391 391 match = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy))
392 392 if len(match) == 0:
393 393 thisDateTime += datetime.timedelta(1)
394 394 continue
395 395
396 396 pathList.append(os.path.join(path,match[0], expLabel))
397 397 thisDateTime += datetime.timedelta(1)
398 398
399 399 if not(pathList):
400 400 print "\tNo files in range: %s - %s" %(startDateTime.ctime(), endDateTime.ctime())
401 401 return None, None, None, None, None
402 402
403 403 directory = pathList[0]
404 404
405 405 else:
406 406 directory = dirList[-1]
407 407 directory = os.path.join(path,directory)
408 408
409 409 filename = getlastFileFromPath(directory, ext)
410 410
411 411 if not(filename):
412 412 return None, None, None, None, None
413 413
414 414 if not(self.__verifyFile(os.path.join(directory, filename))):
415 415 return None, None, None, None, None
416 416
417 417 year = int( filename[1:5] )
418 418 doy = int( filename[5:8] )
419 419 set = int( filename[8:11] )
420 420
421 421 return directory, filename, year, doy, set
422 422
423 423
424 424
425 425 def __setNextFileOffline(self):
426 426
427 427 idFile = self.fileIndex
428 428
429 429 while (True):
430 430 idFile += 1
431 431 if not(idFile < len(self.filenameList)):
432 432 self.flagNoMoreFiles = 1
433 433 print "No more Files"
434 434 return 0
435 435
436 436 filename = self.filenameList[idFile]
437 437
438 438 if not(self.__verifyFile(filename)):
439 439 continue
440 440
441 441 fileSize = os.path.getsize(filename)
442 442 fp = open(filename,'rb')
443 443 break
444 444
445 445 self.flagIsNewFile = 1
446 446 self.fileIndex = idFile
447 447 self.filename = filename
448 448 self.fileSize = fileSize
449 449 self.fp = fp
450 450
451 451 print "Setting the file: %s"%self.filename
452 452
453 453 return 1
454 454
455 455 def __setNextFileOnline(self):
456 456 """
457 457 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
458 458 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
459 459 siguientes.
460 460
461 461 Affected:
462 462 self.flagIsNewFile
463 463 self.filename
464 464 self.fileSize
465 465 self.fp
466 466 self.set
467 467 self.flagNoMoreFiles
468 468
469 469 Return:
470 470 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
471 471 1 : si el file fue abierto con exito y esta listo a ser leido
472 472
473 473 Excepciones:
474 474 Si un determinado file no puede ser abierto
475 475 """
476 476 nFiles = 0
477 477 fileOk_flag = False
478 478 firstTime_flag = True
479 479
480 480 self.set += 1
481 481
482 482 #busca el 1er file disponible
483 483 file, filename = checkForRealPath( self.path, self.year, self.doy, self.set, self.ext )
484 484 if file:
485 485 if self.__verifyFile(file, False):
486 486 fileOk_flag = True
487 487
488 488 #si no encuentra un file entonces espera y vuelve a buscar
489 489 if not(fileOk_flag):
490 490 for nFiles in range(self.nFiles+1): #busco en los siguientes self.nFiles+1 files posibles
491 491
492 492 if firstTime_flag: #si es la 1era vez entonces hace el for self.nTries veces
493 493 tries = self.nTries
494 494 else:
495 495 tries = 1 #si no es la 1era vez entonces solo lo hace una vez
496 496
497 497 for nTries in range( tries ):
498 498 if firstTime_flag:
499 499 print "\tWaiting %0.2f sec for the file \"%s\" , try %03d ..." % ( self.delay, filename, nTries+1 )
500 500 time.sleep( self.delay )
501 501 else:
502 502 print "\tSearching next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext)
503 503
504 504 file, filename = checkForRealPath( self.path, self.year, self.doy, self.set, self.ext )
505 505 if file:
506 506 if self.__verifyFile(file):
507 507 fileOk_flag = True
508 508 break
509 509
510 510 if fileOk_flag:
511 511 break
512 512
513 513 firstTime_flag = False
514 514
515 515 print "\tSkipping the file \"%s\" due to this file doesn't exist" % filename
516 516 self.set += 1
517 517
518 518 if nFiles == (self.nFiles-1): #si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
519 519 self.set = 0
520 520 self.doy += 1
521 521
522 522 if fileOk_flag:
523 523 self.fileSize = os.path.getsize( file )
524 524 self.filename = file
525 525 self.flagIsNewFile = 1
526 526 if self.fp != None: self.fp.close()
527 527 self.fp = open(file)
528 528 self.flagNoMoreFiles = 0
529 529 print 'Setting the file: %s' % file
530 530 else:
531 531 self.fileSize = 0
532 532 self.filename = None
533 533 self.flagIsNewFile = 0
534 534 self.fp = None
535 535 self.flagNoMoreFiles = 1
536 536 print 'No more Files'
537 537
538 538 return fileOk_flag
539 539
540 540
541 541 def setNextFile(self):
542 542 if self.fp != None:
543 543 self.fp.close()
544 544
545 545 if self.online:
546 546 newFile = self.__setNextFileOnline()
547 547 else:
548 548 newFile = self.__setNextFileOffline()
549 549
550 550 if not(newFile):
551 551 return 0
552 552
553 553 self.__readFirstHeader()
554 554 self.nReadBlocks = 0
555 555 return 1
556 556
557 557 def __setNewBlock(self):
558 558 if self.fp == None:
559 559 return 0
560 560
561 561 if self.flagIsNewFile:
562 562 return 1
563 563
564 564 self.lastUTTime = self.basicHeaderObj.utc
565 565 currentSize = self.fileSize - self.fp.tell()
566 566 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
567 567
568 568 if (currentSize >= neededSize):
569 569 self.__rdBasicHeader()
570 570 return 1
571 571
572 572 if not(self.setNextFile()):
573 573 return 0
574 574
575 575 deltaTime = self.basicHeaderObj.utc - self.lastUTTime #
576 576
577 577 self.flagTimeBlock = 0
578 578
579 579 if deltaTime > self.maxTimeStep:
580 580 self.flagTimeBlock = 1
581 581
582 582 return 1
583 583
584 584
585 585 def readNextBlock(self):
586 586 if not(self.__setNewBlock()):
587 587 return 0
588 588
589 589 if not(self.readBlock()):
590 590 return 0
591 591
592 592 return 1
593 593
594 594 def __rdProcessingHeader(self, fp=None):
595 595 if fp == None:
596 596 fp = self.fp
597 597
598 598 self.processingHeaderObj.read(fp)
599 599
600 600 def __rdRadarControllerHeader(self, fp=None):
601 601 if fp == None:
602 602 fp = self.fp
603 603
604 604 self.radarControllerHeaderObj.read(fp)
605 605
606 606 def __rdSystemHeader(self, fp=None):
607 607 if fp == None:
608 608 fp = self.fp
609 609
610 610 self.systemHeaderObj.read(fp)
611 611
612 612 def __rdBasicHeader(self, fp=None):
613 613 if fp == None:
614 614 fp = self.fp
615 615
616 616 self.basicHeaderObj.read(fp)
617 617
618 618
619 619 def __readFirstHeader(self):
620 620 self.__rdBasicHeader()
621 621 self.__rdSystemHeader()
622 622 self.__rdRadarControllerHeader()
623 623 self.__rdProcessingHeader()
624 624
625 625 self.firstHeaderSize = self.basicHeaderObj.size
626 626
627 627 datatype = int(numpy.log2((self.processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
628 628 if datatype == 0:
629 629 datatype_str = numpy.dtype([('real','<i1'),('imag','<i1')])
630 630 elif datatype == 1:
631 631 datatype_str = numpy.dtype([('real','<i2'),('imag','<i2')])
632 632 elif datatype == 2:
633 633 datatype_str = numpy.dtype([('real','<i4'),('imag','<i4')])
634 634 elif datatype == 3:
635 635 datatype_str = numpy.dtype([('real','<i8'),('imag','<i8')])
636 636 elif datatype == 4:
637 637 datatype_str = numpy.dtype([('real','<f4'),('imag','<f4')])
638 638 elif datatype == 5:
639 639 datatype_str = numpy.dtype([('real','<f8'),('imag','<f8')])
640 640 else:
641 641 raise ValueError, 'Data type was not defined'
642 642
643 643 self.dtype = datatype_str
644 644 self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
645 645 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + self.firstHeaderSize + self.basicHeaderSize*(self.processingHeaderObj.dataBlocksPerFile - 1)
646 646 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
647 647 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
648 648 self.getBlockDimension()
649 649
650 650
651 651 def __verifyFile(self, filename, msgFlag=True):
652 652 msg = None
653 653 try:
654 654 fp = open(filename, 'rb')
655 655 currentPosition = fp.tell()
656 656 except:
657 657 if msgFlag:
658 658 print "The file %s can't be opened" % (filename)
659 659 return False
660 660
661 661 neededSize = self.processingHeaderObj.blockSize + self.firstHeaderSize
662 662
663 663 if neededSize == 0:
664 664 basicHeaderObj = BasicHeader()
665 665 systemHeaderObj = SystemHeader()
666 666 radarControllerHeaderObj = RadarControllerHeader()
667 667 processingHeaderObj = ProcessingHeader()
668 668
669 669 try:
670 670 if not( basicHeaderObj.read(fp) ): raise ValueError
671 671 if not( systemHeaderObj.read(fp) ): raise ValueError
672 672 if not( radarControllerHeaderObj.read(fp) ): raise ValueError
673 673 if not( processingHeaderObj.read(fp) ): raise ValueError
674 674 data_type = int(numpy.log2((processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
675 675
676 676 neededSize = processingHeaderObj.blockSize + basicHeaderObj.size
677 677
678 678 except:
679 679 if msgFlag:
680 680 print "\tThe file %s is empty or it hasn't enough data" % filename
681 681
682 682 fp.close()
683 683 return False
684 684 else:
685 685 msg = "\tSkipping the file %s due to it hasn't enough data" %filename
686 686
687 687 fp.close()
688 688 fileSize = os.path.getsize(filename)
689 689 currentSize = fileSize - currentPosition
690 690 if currentSize < neededSize:
691 691 if msgFlag and (msg != None):
692 692 print msg #print"\tSkipping the file %s due to it hasn't enough data" %filename
693 693 return False
694 694
695 695 return True
696 696
697 697 def setup(self,
698 698 path=None,
699 699 startDate=None,
700 700 endDate=None,
701 701 startTime=datetime.time(0,0,0),
702 702 endTime=datetime.time(23,59,59),
703 703 set=0,
704 704 expLabel = "",
705 705 ext = None,
706 706 online = False,
707 707 delay = 60):
708 708
709 709 if path == None:
710 710 raise ValueError, "The path is not valid"
711 711
712 712 if ext == None:
713 713 ext = self.ext
714 714
715 715 if online:
716 716 print "Searching files in online mode..."
717 717 doypath, file, year, doy, set = self.__searchFilesOnLine(path=path, expLabel=expLabel, ext=ext)
718 718
719 719 if not(doypath):
720 720 for nTries in range( self.nTries ):
721 721 print '\tWaiting %0.2f sec for an valid file in %s: try %02d ...' % (self.delay, path, nTries+1)
722 722 time.sleep( self.delay )
723 723 doypath, file, year, doy, set = self.__searchFilesOnLine(path=path, expLabel=expLabel, ext=ext)
724 724 if doypath:
725 725 break
726 726
727 727 if not(doypath):
728 728 print "There 'isn't valied files in %s" % path
729 729 return None
730 730
731 731 self.year = year
732 732 self.doy = doy
733 733 self.set = set - 1
734 734 self.path = path
735 735
736 736 else:
737 737 print "Searching files in offline mode ..."
738 738 pathList, filenameList = self.__searchFilesOffLine(path, startDate, endDate, startTime, endTime, set, expLabel, ext)
739 739
740 740 if not(pathList):
741 741 print "No *%s files into the folder %s \nfor the range: %s - %s"%(ext, path,
742 742 datetime.datetime.combine(startDate,startTime).ctime(),
743 743 datetime.datetime.combine(endDate,endTime).ctime())
744 744
745 745 sys.exit(-1)
746 746
747 747
748 748 self.fileIndex = -1
749 749 self.pathList = pathList
750 750 self.filenameList = filenameList
751 751
752 752 self.online = online
753 753 self.delay = delay
754 754 ext = ext.lower()
755 755 self.ext = ext
756 756
757 757 if not(self.setNextFile()):
758 758 if (startDate!=None) and (endDate!=None):
759 759 print "No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
760 760 elif startDate != None:
761 761 print "No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime())
762 762 else:
763 763 print "No files"
764 764
765 765 sys.exit(-1)
766 766
767 767 # self.updateDataHeader()
768 768
769 769 return self.dataOut
770 770
771 771 def getData():
772 772
773 773 raise ValueError, "This method has not been implemented"
774 774
775 775 def hasNotDataInBuffer():
776 776
777 777 raise ValueError, "This method has not been implemented"
778 778
779 779 def readBlock():
780 780
781 781 raise ValueError, "This method has not been implemented"
782 782
783 783 def isEndProcess(self):
784 784
785 785 return self.flagNoMoreFiles
786 786
787 787 def printReadBlocks(self):
788 788
789 789 print "Number of read blocks per file %04d" %self.nReadBlocks
790 790
791 791 def printTotalBlocks(self):
792 792
793 793 print "Number of read blocks %04d" %self.nTotalBlocks
794 794
795 795 def run(self, **kwargs):
796 796
797 797 if not(self.isConfig):
798 798
799 799 # self.dataOut = dataOut
800 800 self.setup(**kwargs)
801 801 self.isConfig = True
802 802
803 803 self.getData()
804 804
805 805 class JRODataWriter(JRODataIO, Operation):
806 806
807 807 """
808 808 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
809 809 de los datos siempre se realiza por bloques.
810 810 """
811 811
812 812 blockIndex = 0
813 813
814 814 path = None
815 815
816 816 setFile = None
817 817
818 818 profilesPerBlock = None
819 819
820 820 blocksPerFile = None
821 821
822 822 nWriteBlocks = 0
823 823
824 824 def __init__(self, dataOut=None):
825 825 raise ValueError, "Not implemented"
826 826
827 827
828 828 def hasAllDataInBuffer(self):
829 829 raise ValueError, "Not implemented"
830 830
831 831
832 832 def setBlockDimension(self):
833 833 raise ValueError, "Not implemented"
834 834
835 835
836 836 def writeBlock(self):
837 837 raise ValueError, "No implemented"
838 838
839 839
840 840 def putData(self):
841 841 raise ValueError, "No implemented"
842 842
843 843 def getDataHeader(self):
844 844 """
845 845 Obtiene una copia del First Header
846 846
847 847 Affected:
848 848
849 849 self.basicHeaderObj
850 850 self.systemHeaderObj
851 851 self.radarControllerHeaderObj
852 852 self.processingHeaderObj self.
853 853
854 854 Return:
855 855 None
856 856 """
857 857
858 858 raise ValueError, "No implemented"
859 859
860 860 def getBasicHeader(self):
861 861
862 862 self.basicHeaderObj.size = self.basicHeaderSize #bytes
863 863 self.basicHeaderObj.version = self.versionFile
864 864 self.basicHeaderObj.dataBlock = self.nTotalBlocks
865 865
866 866 utc = numpy.floor(self.dataOut.utctime)
867 867 milisecond = (self.dataOut.utctime - utc)* 1000.0
868 868
869 869 self.basicHeaderObj.utc = utc
870 870 self.basicHeaderObj.miliSecond = milisecond
871 871 self.basicHeaderObj.timeZone = 0
872 872 self.basicHeaderObj.dstFlag = 0
873 873 self.basicHeaderObj.errorCount = 0
874 874
875 875 def __writeFirstHeader(self):
876 876 """
877 877 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
878 878
879 879 Affected:
880 880 __dataType
881 881
882 882 Return:
883 883 None
884 884 """
885 885
886 886 # CALCULAR PARAMETROS
887 887
888 888 sizeLongHeader = self.systemHeaderObj.size + self.radarControllerHeaderObj.size + self.processingHeaderObj.size
889 889 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
890 890
891 891 self.basicHeaderObj.write(self.fp)
892 892 self.systemHeaderObj.write(self.fp)
893 893 self.radarControllerHeaderObj.write(self.fp)
894 894 self.processingHeaderObj.write(self.fp)
895 895
896 896 self.dtype = self.dataOut.dtype
897 897
898 898 def __setNewBlock(self):
899 899 """
900 900 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
901 901
902 902 Return:
903 903 0 : si no pudo escribir nada
904 904 1 : Si escribio el Basic el First Header
905 905 """
906 906 if self.fp == None:
907 907 self.setNextFile()
908 908
909 909 if self.flagIsNewFile:
910 910 return 1
911 911
912 912 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
913 913 self.basicHeaderObj.write(self.fp)
914 914 return 1
915 915
916 916 if not( self.setNextFile() ):
917 917 return 0
918 918
919 919 return 1
920 920
921 921
922 922 def writeNextBlock(self):
923 923 """
924 924 Selecciona el bloque siguiente de datos y los escribe en un file
925 925
926 926 Return:
927 927 0 : Si no hizo pudo escribir el bloque de datos
928 928 1 : Si no pudo escribir el bloque de datos
929 929 """
930 930 if not( self.__setNewBlock() ):
931 931 return 0
932 932
933 933 self.writeBlock()
934 934
935 935 return 1
936 936
937 937 def setNextFile(self):
938 938 """
939 939 Determina el siguiente file que sera escrito
940 940
941 941 Affected:
942 942 self.filename
943 943 self.subfolder
944 944 self.fp
945 945 self.setFile
946 946 self.flagIsNewFile
947 947
948 948 Return:
949 949 0 : Si el archivo no puede ser escrito
950 950 1 : Si el archivo esta listo para ser escrito
951 951 """
952 952 ext = self.ext
953 953 path = self.path
954 954
955 955 if self.fp != None:
956 956 self.fp.close()
957 957
958 958 timeTuple = time.localtime( self.dataOut.dataUtcTime)
959 959 subfolder = 'D%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
960 960
961 961 doypath = os.path.join( path, subfolder )
962 962 if not( os.path.exists(doypath) ):
963 963 os.mkdir(doypath)
964 964 self.setFile = -1 #inicializo mi contador de seteo
965 965 else:
966 966 filesList = os.listdir( doypath )
967 967 if len( filesList ) > 0:
968 968 filesList = sorted( filesList, key=str.lower )
969 969 filen = filesList[-1]
970 970 # el filename debera tener el siguiente formato
971 971 # 0 1234 567 89A BCDE (hex)
972 972 # x YYYY DDD SSS .ext
973 973 if isNumber( filen[8:11] ):
974 974 self.setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
975 975 else:
976 976 self.setFile = -1
977 977 else:
978 978 self.setFile = -1 #inicializo mi contador de seteo
979 979
980 980 setFile = self.setFile
981 981 setFile += 1
982 982
983 983 file = '%s%4.4d%3.3d%3.3d%s' % (self.optchar,
984 984 timeTuple.tm_year,
985 985 timeTuple.tm_yday,
986 986 setFile,
987 987 ext )
988 988
989 989 filename = os.path.join( path, subfolder, file )
990 990
991 991 fp = open( filename,'wb' )
992 992
993 993 self.blockIndex = 0
994 994
995 995 #guardando atributos
996 996 self.filename = filename
997 997 self.subfolder = subfolder
998 998 self.fp = fp
999 999 self.setFile = setFile
1000 1000 self.flagIsNewFile = 1
1001 1001
1002 1002 self.getDataHeader()
1003 1003
1004 1004 print 'Writing the file: %s'%self.filename
1005 1005
1006 1006 self.__writeFirstHeader()
1007 1007
1008 1008 return 1
1009 1009
1010 1010 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=None, set=0, ext=None):
1011 1011 """
1012 1012 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1013 1013
1014 1014 Inputs:
1015 1015 path : el path destino en el cual se escribiran los files a crear
1016 1016 format : formato en el cual sera salvado un file
1017 1017 set : el setebo del file
1018 1018
1019 1019 Return:
1020 1020 0 : Si no realizo un buen seteo
1021 1021 1 : Si realizo un buen seteo
1022 1022 """
1023 1023
1024 1024 if ext == None:
1025 1025 ext = self.ext
1026 1026
1027 1027 ext = ext.lower()
1028 1028
1029 1029 self.ext = ext
1030 1030
1031 1031 self.path = path
1032 1032
1033 1033 self.setFile = set - 1
1034 1034
1035 1035 self.blocksPerFile = blocksPerFile
1036 1036
1037 1037 self.profilesPerBlock = profilesPerBlock
1038 1038
1039 1039 self.dataOut = dataOut
1040 1040
1041 1041 if not(self.setNextFile()):
1042 1042 print "There isn't a next file"
1043 1043 return 0
1044 1044
1045 1045 self.setBlockDimension()
1046 1046
1047 1047 return 1
1048 1048
1049 1049 def run(self, dataOut, **kwargs):
1050 1050
1051 1051 if not(self.isConfig):
1052 1052
1053 1053 self.setup(dataOut, **kwargs)
1054 1054 self.isConfig = True
1055 1055
1056 1056 self.putData()
1057 1057
1058 1058 class VoltageReader(JRODataReader):
1059 1059 """
1060 1060 Esta clase permite leer datos de voltage desde archivos en formato rawdata (.r). La lectura
1061 1061 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones:
1062 1062 perfiles*alturas*canales) son almacenados en la variable "buffer".
1063 1063
1064 1064 perfiles * alturas * canales
1065 1065
1066 1066 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
1067 1067 RadarControllerHeader y Voltage. Los tres primeros se usan para almacenar informacion de la
1068 1068 cabecera de datos (metadata), y el cuarto (Voltage) para obtener y almacenar un perfil de
1069 1069 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
1070 1070
1071 1071 Example:
1072 1072
1073 1073 dpath = "/home/myuser/data"
1074 1074
1075 1075 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
1076 1076
1077 1077 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
1078 1078
1079 1079 readerObj = VoltageReader()
1080 1080
1081 1081 readerObj.setup(dpath, startTime, endTime)
1082 1082
1083 1083 while(True):
1084 1084
1085 1085 #to get one profile
1086 1086 profile = readerObj.getData()
1087 1087
1088 1088 #print the profile
1089 1089 print profile
1090 1090
1091 1091 #If you want to see all datablock
1092 1092 print readerObj.datablock
1093 1093
1094 1094 if readerObj.flagNoMoreFiles:
1095 1095 break
1096 1096
1097 1097 """
1098 1098
1099 1099 ext = ".r"
1100 1100
1101 1101 optchar = "D"
1102 1102 dataOut = None
1103 1103
1104 1104
1105 1105 def __init__(self):
1106 1106 """
1107 1107 Inicializador de la clase VoltageReader para la lectura de datos de voltage.
1108 1108
1109 1109 Input:
1110 1110 dataOut : Objeto de la clase Voltage. Este objeto sera utilizado para
1111 1111 almacenar un perfil de datos cada vez que se haga un requerimiento
1112 1112 (getData). El perfil sera obtenido a partir del buffer de datos,
1113 1113 si el buffer esta vacio se hara un nuevo proceso de lectura de un
1114 1114 bloque de datos.
1115 1115 Si este parametro no es pasado se creara uno internamente.
1116 1116
1117 1117 Variables afectadas:
1118 1118 self.dataOut
1119 1119
1120 1120 Return:
1121 1121 None
1122 1122 """
1123 1123
1124 1124 self.isConfig = False
1125 1125
1126 1126 self.datablock = None
1127 1127
1128 1128 self.utc = 0
1129 1129
1130 1130 self.ext = ".r"
1131 1131
1132 1132 self.optchar = "D"
1133 1133
1134 1134 self.basicHeaderObj = BasicHeader()
1135 1135
1136 1136 self.systemHeaderObj = SystemHeader()
1137 1137
1138 1138 self.radarControllerHeaderObj = RadarControllerHeader()
1139 1139
1140 1140 self.processingHeaderObj = ProcessingHeader()
1141 1141
1142 1142 self.online = 0
1143 1143
1144 1144 self.fp = None
1145 1145
1146 1146 self.idFile = None
1147 1147
1148 1148 self.dtype = None
1149 1149
1150 1150 self.fileSizeByHeader = None
1151 1151
1152 1152 self.filenameList = []
1153 1153
1154 1154 self.filename = None
1155 1155
1156 1156 self.fileSize = None
1157 1157
1158 1158 self.firstHeaderSize = 0
1159 1159
1160 1160 self.basicHeaderSize = 24
1161 1161
1162 1162 self.pathList = []
1163 1163
1164 1164 self.filenameList = []
1165 1165
1166 1166 self.lastUTTime = 0
1167 1167
1168 1168 self.maxTimeStep = 30
1169 1169
1170 1170 self.flagNoMoreFiles = 0
1171 1171
1172 1172 self.set = 0
1173 1173
1174 1174 self.path = None
1175 1175
1176 1176 self.profileIndex = 9999
1177 1177
1178 1178 self.delay = 3 #seconds
1179 1179
1180 1180 self.nTries = 3 #quantity tries
1181 1181
1182 1182 self.nFiles = 3 #number of files for searching
1183 1183
1184 1184 self.nReadBlocks = 0
1185 1185
1186 1186 self.flagIsNewFile = 1
1187 1187
1188 1188 self.ippSeconds = 0
1189 1189
1190 1190 self.flagTimeBlock = 0
1191 1191
1192 1192 self.flagIsNewBlock = 0
1193 1193
1194 1194 self.nTotalBlocks = 0
1195 1195
1196 1196 self.blocksize = 0
1197 1197
1198 1198 self.dataOut = self.createObjByDefault()
1199 1199
1200 1200 def createObjByDefault(self):
1201 1201
1202 1202 dataObj = Voltage()
1203 1203
1204 1204 return dataObj
1205 1205
1206 1206 def __hasNotDataInBuffer(self):
1207 1207 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock:
1208 1208 return 1
1209 1209 return 0
1210 1210
1211 1211
1212 1212 def getBlockDimension(self):
1213 1213 """
1214 1214 Obtiene la cantidad de puntos a leer por cada bloque de datos
1215 1215
1216 1216 Affected:
1217 1217 self.blocksize
1218 1218
1219 1219 Return:
1220 1220 None
1221 1221 """
1222 1222 pts2read = self.processingHeaderObj.profilesPerBlock * self.processingHeaderObj.nHeights * self.systemHeaderObj.nChannels
1223 1223 self.blocksize = pts2read
1224 1224
1225 1225
1226 1226 def readBlock(self):
1227 1227 """
1228 1228 readBlock lee el bloque de datos desde la posicion actual del puntero del archivo
1229 1229 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
1230 1230 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
1231 1231 es seteado a 0
1232 1232
1233 1233 Inputs:
1234 1234 None
1235 1235
1236 1236 Return:
1237 1237 None
1238 1238
1239 1239 Affected:
1240 1240 self.profileIndex
1241 1241 self.datablock
1242 1242 self.flagIsNewFile
1243 1243 self.flagIsNewBlock
1244 1244 self.nTotalBlocks
1245 1245
1246 1246 Exceptions:
1247 1247 Si un bloque leido no es un bloque valido
1248 1248 """
1249 1249
1250 1250 junk = numpy.fromfile( self.fp, self.dtype, self.blocksize )
1251 1251
1252 1252 try:
1253 1253 junk = junk.reshape( (self.processingHeaderObj.profilesPerBlock, self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels) )
1254 1254 except:
1255 1255 print "The read block (%3d) has not enough data" %self.nReadBlocks
1256 1256 return 0
1257 1257
1258 1258 junk = numpy.transpose(junk, (2,0,1))
1259 1259 self.datablock = junk['real'] + junk['imag']*1j
1260 1260
1261 1261 self.profileIndex = 0
1262 1262
1263 1263 self.flagIsNewFile = 0
1264 1264 self.flagIsNewBlock = 1
1265 1265
1266 1266 self.nTotalBlocks += 1
1267 1267 self.nReadBlocks += 1
1268 1268
1269 1269 return 1
1270 1270
1271 1271
1272 1272 def getData(self):
1273 1273 """
1274 1274 getData obtiene una unidad de datos del buffer de lectura y la copia a la clase "Voltage"
1275 1275 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
1276 1276 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
1277 1277
1278 1278 Ademas incrementa el contador del buffer en 1.
1279 1279
1280 1280 Return:
1281 1281 data : retorna un perfil de voltages (alturas * canales) copiados desde el
1282 1282 buffer. Si no hay mas archivos a leer retorna None.
1283 1283
1284 1284 Variables afectadas:
1285 1285 self.dataOut
1286 1286 self.profileIndex
1287 1287
1288 1288 Affected:
1289 1289 self.dataOut
1290 1290 self.profileIndex
1291 1291 self.flagTimeBlock
1292 1292 self.flagIsNewBlock
1293 1293 """
1294 1294
1295 1295 if self.flagNoMoreFiles:
1296 1296 self.dataOut.flagNoData = True
1297 1297 print 'Process finished'
1298 1298 return 0
1299 1299
1300 1300 self.flagTimeBlock = 0
1301 1301 self.flagIsNewBlock = 0
1302 1302
1303 1303 if self.__hasNotDataInBuffer():
1304 1304
1305 1305 if not( self.readNextBlock() ):
1306 1306 return 0
1307 1307
1308 1308 # self.updateDataHeader()
1309 1309
1310 1310 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
1311 1311
1312 1312 if self.datablock == None:
1313 1313 self.dataOut.flagNoData = True
1314 1314 return 0
1315 1315
1316 1316 self.dataOut.data = self.datablock[:,self.profileIndex,:]
1317 1317
1318 1318 self.dataOut.dtype = self.dtype
1319 1319
1320 1320 # self.dataOut.nChannels = self.systemHeaderObj.nChannels
1321 1321
1322 1322 self.dataOut.nHeights = self.processingHeaderObj.nHeights
1323 1323
1324 1324 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
1325 1325
1326 1326 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
1327 1327
1328 1328 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
1329 1329
1330 1330 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
1331 1331
1332 1332 # self.dataOut.channelIndexList = range(self.systemHeaderObj.nChannels)
1333 1333
1334 1334 self.dataOut.flagTimeBlock = self.flagTimeBlock
1335 1335
1336 1336 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond/1000. + self.profileIndex * self.ippSeconds
1337 1337
1338 1338 self.dataOut.ippSeconds = self.ippSeconds
1339 1339
1340 1340 self.dataOut.timeInterval = self.ippSeconds * self.processingHeaderObj.nCohInt
1341 1341
1342 1342 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
1343 1343
1344 1344 self.dataOut.flagShiftFFT = False
1345 1345
1346 1346 if self.processingHeaderObj.code != None:
1347 1347 self.dataOut.nCode = self.processingHeaderObj.nCode
1348 1348
1349 1349 self.dataOut.nBaud = self.processingHeaderObj.nBaud
1350 1350
1351 1351 self.dataOut.code = self.processingHeaderObj.code
1352 1352
1353 1353 self.profileIndex += 1
1354 1354
1355 1355 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
1356 1356
1357 1357 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
1358 1358
1359 1359 self.dataOut.flagNoData = False
1360 1360
1361 1361 # print self.profileIndex, self.dataOut.utctime
1362 1362 # if self.profileIndex == 800:
1363 1363 # a=1
1364 1364
1365 1365 return self.dataOut.data
1366 1366
1367 1367
1368 1368 class VoltageWriter(JRODataWriter):
1369 1369 """
1370 1370 Esta clase permite escribir datos de voltajes a archivos procesados (.r). La escritura
1371 1371 de los datos siempre se realiza por bloques.
1372 1372 """
1373 1373
1374 1374 ext = ".r"
1375 1375
1376 1376 optchar = "D"
1377 1377
1378 1378 shapeBuffer = None
1379 1379
1380 1380
1381 1381 def __init__(self):
1382 1382 """
1383 1383 Inicializador de la clase VoltageWriter para la escritura de datos de espectros.
1384 1384
1385 1385 Affected:
1386 1386 self.dataOut
1387 1387
1388 1388 Return: None
1389 1389 """
1390 1390
1391 1391 self.nTotalBlocks = 0
1392 1392
1393 1393 self.profileIndex = 0
1394 1394
1395 1395 self.isConfig = False
1396 1396
1397 1397 self.fp = None
1398 1398
1399 1399 self.flagIsNewFile = 1
1400 1400
1401 1401 self.nTotalBlocks = 0
1402 1402
1403 1403 self.flagIsNewBlock = 0
1404 1404
1405 1405 self.setFile = None
1406 1406
1407 1407 self.dtype = None
1408 1408
1409 1409 self.path = None
1410 1410
1411 1411 self.filename = None
1412 1412
1413 1413 self.basicHeaderObj = BasicHeader()
1414 1414
1415 1415 self.systemHeaderObj = SystemHeader()
1416 1416
1417 1417 self.radarControllerHeaderObj = RadarControllerHeader()
1418 1418
1419 1419 self.processingHeaderObj = ProcessingHeader()
1420 1420
1421 1421 def hasAllDataInBuffer(self):
1422 1422 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock:
1423 1423 return 1
1424 1424 return 0
1425 1425
1426 1426
1427 1427 def setBlockDimension(self):
1428 1428 """
1429 1429 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
1430 1430
1431 1431 Affected:
1432 1432 self.shape_spc_Buffer
1433 1433 self.shape_cspc_Buffer
1434 1434 self.shape_dc_Buffer
1435 1435
1436 1436 Return: None
1437 1437 """
1438 1438 self.shapeBuffer = (self.processingHeaderObj.profilesPerBlock,
1439 1439 self.processingHeaderObj.nHeights,
1440 1440 self.systemHeaderObj.nChannels)
1441 1441
1442 1442 self.datablock = numpy.zeros((self.systemHeaderObj.nChannels,
1443 1443 self.processingHeaderObj.profilesPerBlock,
1444 1444 self.processingHeaderObj.nHeights),
1445 1445 dtype=numpy.dtype('complex'))
1446 1446
1447 1447
1448 1448 def writeBlock(self):
1449 1449 """
1450 1450 Escribe el buffer en el file designado
1451 1451
1452 1452 Affected:
1453 1453 self.profileIndex
1454 1454 self.flagIsNewFile
1455 1455 self.flagIsNewBlock
1456 1456 self.nTotalBlocks
1457 1457 self.blockIndex
1458 1458
1459 1459 Return: None
1460 1460 """
1461 1461 data = numpy.zeros( self.shapeBuffer, self.dtype )
1462 1462
1463 1463 junk = numpy.transpose(self.datablock, (1,2,0))
1464 1464
1465 1465 data['real'] = junk.real
1466 1466 data['imag'] = junk.imag
1467 1467
1468 1468 data = data.reshape( (-1) )
1469 1469
1470 1470 data.tofile( self.fp )
1471 1471
1472 1472 self.datablock.fill(0)
1473 1473
1474 1474 self.profileIndex = 0
1475 1475 self.flagIsNewFile = 0
1476 1476 self.flagIsNewBlock = 1
1477 1477
1478 1478 self.blockIndex += 1
1479 1479 self.nTotalBlocks += 1
1480 1480
1481 1481 def putData(self):
1482 1482 """
1483 1483 Setea un bloque de datos y luego los escribe en un file
1484 1484
1485 1485 Affected:
1486 1486 self.flagIsNewBlock
1487 1487 self.profileIndex
1488 1488
1489 1489 Return:
1490 1490 0 : Si no hay data o no hay mas files que puedan escribirse
1491 1491 1 : Si se escribio la data de un bloque en un file
1492 1492 """
1493 1493 if self.dataOut.flagNoData:
1494 1494 return 0
1495 1495
1496 1496 self.flagIsNewBlock = 0
1497 1497
1498 1498 if self.dataOut.flagTimeBlock:
1499 1499
1500 1500 self.datablock.fill(0)
1501 1501 self.profileIndex = 0
1502 1502 self.setNextFile()
1503 1503
1504 1504 if self.profileIndex == 0:
1505 1505 self.getBasicHeader()
1506 1506
1507 1507 self.datablock[:,self.profileIndex,:] = self.dataOut.data
1508 1508
1509 1509 self.profileIndex += 1
1510 1510
1511 1511 if self.hasAllDataInBuffer():
1512 1512 #if self.flagIsNewFile:
1513 1513 self.writeNextBlock()
1514 1514 # self.getDataHeader()
1515 1515
1516 1516 return 1
1517 1517
1518 1518 def __getProcessFlags(self):
1519 1519
1520 1520 processFlags = 0
1521 1521
1522 1522 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
1523 1523 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
1524 1524 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
1525 1525 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
1526 1526 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
1527 1527 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
1528 1528
1529 1529 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
1530 1530
1531 1531
1532 1532
1533 1533 datatypeValueList = [PROCFLAG.DATATYPE_CHAR,
1534 1534 PROCFLAG.DATATYPE_SHORT,
1535 1535 PROCFLAG.DATATYPE_LONG,
1536 1536 PROCFLAG.DATATYPE_INT64,
1537 1537 PROCFLAG.DATATYPE_FLOAT,
1538 1538 PROCFLAG.DATATYPE_DOUBLE]
1539 1539
1540 1540
1541 1541 for index in range(len(dtypeList)):
1542 1542 if self.dataOut.dtype == dtypeList[index]:
1543 1543 dtypeValue = datatypeValueList[index]
1544 1544 break
1545 1545
1546 1546 processFlags += dtypeValue
1547 1547
1548 1548 if self.dataOut.flagDecodeData:
1549 1549 processFlags += PROCFLAG.DECODE_DATA
1550 1550
1551 1551 if self.dataOut.flagDeflipData:
1552 1552 processFlags += PROCFLAG.DEFLIP_DATA
1553 1553
1554 1554 if self.dataOut.code != None:
1555 1555 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1556 1556
1557 1557 if self.dataOut.nCohInt > 1:
1558 1558 processFlags += PROCFLAG.COHERENT_INTEGRATION
1559 1559
1560 1560 return processFlags
1561 1561
1562 1562
1563 1563 def __getBlockSize(self):
1564 1564 '''
1565 1565 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Voltage
1566 1566 '''
1567 1567
1568 1568 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
1569 1569 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
1570 1570 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
1571 1571 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
1572 1572 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
1573 1573 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
1574 1574
1575 1575 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
1576 1576 datatypeValueList = [1,2,4,8,4,8]
1577 1577 for index in range(len(dtypeList)):
1578 1578 if self.dataOut.dtype == dtypeList[index]:
1579 1579 datatypeValue = datatypeValueList[index]
1580 1580 break
1581 1581
1582 1582 blocksize = int(self.dataOut.nHeights * self.dataOut.nChannels * self.dataOut.nProfiles * datatypeValue * 2)
1583 1583
1584 1584 return blocksize
1585 1585
1586 1586 def getDataHeader(self):
1587 1587
1588 1588 """
1589 1589 Obtiene una copia del First Header
1590 1590
1591 1591 Affected:
1592 1592 self.systemHeaderObj
1593 1593 self.radarControllerHeaderObj
1594 1594 self.dtype
1595 1595
1596 1596 Return:
1597 1597 None
1598 1598 """
1599 1599
1600 1600 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
1601 1601 self.systemHeaderObj.nChannels = self.dataOut.nChannels
1602 1602 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
1603 1603
1604 1604 self.getBasicHeader()
1605 1605
1606 1606 processingHeaderSize = 40 # bytes
1607 1607 self.processingHeaderObj.dtype = 0 # Voltage
1608 1608 self.processingHeaderObj.blockSize = self.__getBlockSize()
1609 1609 self.processingHeaderObj.profilesPerBlock = self.profilesPerBlock
1610 1610 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
1611 1611 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
1612 1612 self.processingHeaderObj.processFlags = self.__getProcessFlags()
1613 1613 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt
1614 1614 self.processingHeaderObj.nIncohInt = 1 # Cuando la data de origen es de tipo Voltage
1615 1615 self.processingHeaderObj.totalSpectra = 0 # Cuando la data de origen es de tipo Voltage
1616 1616
1617 1617 if self.dataOut.code != None:
1618 1618 self.processingHeaderObj.code = self.dataOut.code
1619 1619 self.processingHeaderObj.nCode = self.dataOut.nCode
1620 1620 self.processingHeaderObj.nBaud = self.dataOut.nBaud
1621 1621 codesize = int(8 + 4 * self.dataOut.nCode * self.dataOut.nBaud)
1622 1622 processingHeaderSize += codesize
1623 1623
1624 1624 if self.processingHeaderObj.nWindows != 0:
1625 1625 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
1626 1626 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
1627 1627 self.processingHeaderObj.nHeights = self.dataOut.nHeights
1628 1628 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
1629 1629 processingHeaderSize += 12
1630 1630
1631 1631 self.processingHeaderObj.size = processingHeaderSize
1632 1632
1633 1633 class SpectraReader(JRODataReader):
1634 1634 """
1635 1635 Esta clase permite leer datos de espectros desde archivos procesados (.pdata). La lectura
1636 1636 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones)
1637 1637 son almacenados en tres buffer's para el Self Spectra, el Cross Spectra y el DC Channel.
1638 1638
1639 1639 paresCanalesIguales * alturas * perfiles (Self Spectra)
1640 1640 paresCanalesDiferentes * alturas * perfiles (Cross Spectra)
1641 1641 canales * alturas (DC Channels)
1642 1642
1643 1643 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
1644 1644 RadarControllerHeader y Spectra. Los tres primeros se usan para almacenar informacion de la
1645 1645 cabecera de datos (metadata), y el cuarto (Spectra) para obtener y almacenar un bloque de
1646 1646 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
1647 1647
1648 1648 Example:
1649 1649 dpath = "/home/myuser/data"
1650 1650
1651 1651 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
1652 1652
1653 1653 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
1654 1654
1655 1655 readerObj = SpectraReader()
1656 1656
1657 1657 readerObj.setup(dpath, startTime, endTime)
1658 1658
1659 1659 while(True):
1660 1660
1661 1661 readerObj.getData()
1662 1662
1663 1663 print readerObj.data_spc
1664 1664
1665 1665 print readerObj.data_cspc
1666 1666
1667 1667 print readerObj.data_dc
1668 1668
1669 1669 if readerObj.flagNoMoreFiles:
1670 1670 break
1671 1671
1672 1672 """
1673 1673
1674 1674 pts2read_SelfSpectra = 0
1675 1675
1676 1676 pts2read_CrossSpectra = 0
1677 1677
1678 1678 pts2read_DCchannels = 0
1679 1679
1680 1680 ext = ".pdata"
1681 1681
1682 1682 optchar = "P"
1683 1683
1684 1684 dataOut = None
1685 1685
1686 1686 nRdChannels = None
1687 1687
1688 1688 nRdPairs = None
1689 1689
1690 1690 rdPairList = []
1691 1691
1692 1692
1693 1693 def __init__(self):
1694 1694 """
1695 1695 Inicializador de la clase SpectraReader para la lectura de datos de espectros.
1696 1696
1697 1697 Inputs:
1698 1698 dataOut : Objeto de la clase Spectra. Este objeto sera utilizado para
1699 1699 almacenar un perfil de datos cada vez que se haga un requerimiento
1700 1700 (getData). El perfil sera obtenido a partir del buffer de datos,
1701 1701 si el buffer esta vacio se hara un nuevo proceso de lectura de un
1702 1702 bloque de datos.
1703 1703 Si este parametro no es pasado se creara uno internamente.
1704 1704
1705 1705 Affected:
1706 1706 self.dataOut
1707 1707
1708 1708 Return : None
1709 1709 """
1710 1710
1711 1711 self.isConfig = False
1712 1712
1713 1713 self.pts2read_SelfSpectra = 0
1714 1714
1715 1715 self.pts2read_CrossSpectra = 0
1716 1716
1717 1717 self.pts2read_DCchannels = 0
1718 1718
1719 1719 self.datablock = None
1720 1720
1721 1721 self.utc = None
1722 1722
1723 1723 self.ext = ".pdata"
1724 1724
1725 1725 self.optchar = "P"
1726 1726
1727 1727 self.basicHeaderObj = BasicHeader()
1728 1728
1729 1729 self.systemHeaderObj = SystemHeader()
1730 1730
1731 1731 self.radarControllerHeaderObj = RadarControllerHeader()
1732 1732
1733 1733 self.processingHeaderObj = ProcessingHeader()
1734 1734
1735 1735 self.online = 0
1736 1736
1737 1737 self.fp = None
1738 1738
1739 1739 self.idFile = None
1740 1740
1741 1741 self.dtype = None
1742 1742
1743 1743 self.fileSizeByHeader = None
1744 1744
1745 1745 self.filenameList = []
1746 1746
1747 1747 self.filename = None
1748 1748
1749 1749 self.fileSize = None
1750 1750
1751 1751 self.firstHeaderSize = 0
1752 1752
1753 1753 self.basicHeaderSize = 24
1754 1754
1755 1755 self.pathList = []
1756 1756
1757 1757 self.lastUTTime = 0
1758 1758
1759 1759 self.maxTimeStep = 30
1760 1760
1761 1761 self.flagNoMoreFiles = 0
1762 1762
1763 1763 self.set = 0
1764 1764
1765 1765 self.path = None
1766 1766
1767 1767 self.delay = 3 #seconds
1768 1768
1769 1769 self.nTries = 3 #quantity tries
1770 1770
1771 1771 self.nFiles = 3 #number of files for searching
1772 1772
1773 1773 self.nReadBlocks = 0
1774 1774
1775 1775 self.flagIsNewFile = 1
1776 1776
1777 1777 self.ippSeconds = 0
1778 1778
1779 1779 self.flagTimeBlock = 0
1780 1780
1781 1781 self.flagIsNewBlock = 0
1782 1782
1783 1783 self.nTotalBlocks = 0
1784 1784
1785 1785 self.blocksize = 0
1786 1786
1787 1787 self.dataOut = self.createObjByDefault()
1788 1788
1789 1789
1790 1790 def createObjByDefault(self):
1791 1791
1792 1792 dataObj = Spectra()
1793 1793
1794 1794 return dataObj
1795 1795
1796 1796 def __hasNotDataInBuffer(self):
1797 1797 return 1
1798 1798
1799 1799
1800 1800 def getBlockDimension(self):
1801 1801 """
1802 1802 Obtiene la cantidad de puntos a leer por cada bloque de datos
1803 1803
1804 1804 Affected:
1805 1805 self.nRdChannels
1806 1806 self.nRdPairs
1807 1807 self.pts2read_SelfSpectra
1808 1808 self.pts2read_CrossSpectra
1809 1809 self.pts2read_DCchannels
1810 1810 self.blocksize
1811 1811 self.dataOut.nChannels
1812 1812 self.dataOut.nPairs
1813 1813
1814 1814 Return:
1815 1815 None
1816 1816 """
1817 1817 self.nRdChannels = 0
1818 1818 self.nRdPairs = 0
1819 1819 self.rdPairList = []
1820 1820
1821 1821 for i in range(0, self.processingHeaderObj.totalSpectra*2, 2):
1822 1822 if self.processingHeaderObj.spectraComb[i] == self.processingHeaderObj.spectraComb[i+1]:
1823 1823 self.nRdChannels = self.nRdChannels + 1 #par de canales iguales
1824 1824 else:
1825 1825 self.nRdPairs = self.nRdPairs + 1 #par de canales diferentes
1826 1826 self.rdPairList.append((self.processingHeaderObj.spectraComb[i], self.processingHeaderObj.spectraComb[i+1]))
1827 1827
1828 1828 pts2read = self.processingHeaderObj.nHeights * self.processingHeaderObj.profilesPerBlock
1829 1829
1830 1830 self.pts2read_SelfSpectra = int(self.nRdChannels * pts2read)
1831 1831 self.blocksize = self.pts2read_SelfSpectra
1832 1832
1833 1833 if self.processingHeaderObj.flag_cspc:
1834 1834 self.pts2read_CrossSpectra = int(self.nRdPairs * pts2read)
1835 1835 self.blocksize += self.pts2read_CrossSpectra
1836 1836
1837 1837 if self.processingHeaderObj.flag_dc:
1838 1838 self.pts2read_DCchannels = int(self.systemHeaderObj.nChannels * self.processingHeaderObj.nHeights)
1839 1839 self.blocksize += self.pts2read_DCchannels
1840 1840
1841 1841 # self.blocksize = self.pts2read_SelfSpectra + self.pts2read_CrossSpectra + self.pts2read_DCchannels
1842 1842
1843 1843
1844 1844 def readBlock(self):
1845 1845 """
1846 1846 Lee el bloque de datos desde la posicion actual del puntero del archivo
1847 1847 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
1848 1848 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
1849 1849 es seteado a 0
1850 1850
1851 1851 Return: None
1852 1852
1853 1853 Variables afectadas:
1854 1854
1855 1855 self.flagIsNewFile
1856 1856 self.flagIsNewBlock
1857 1857 self.nTotalBlocks
1858 1858 self.data_spc
1859 1859 self.data_cspc
1860 1860 self.data_dc
1861 1861
1862 1862 Exceptions:
1863 1863 Si un bloque leido no es un bloque valido
1864 1864 """
1865 1865 blockOk_flag = False
1866 1866 fpointer = self.fp.tell()
1867 1867
1868 1868 spc = numpy.fromfile( self.fp, self.dtype[0], self.pts2read_SelfSpectra )
1869 1869 spc = spc.reshape( (self.nRdChannels, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
1870 1870
1871 1871 if self.processingHeaderObj.flag_cspc:
1872 1872 cspc = numpy.fromfile( self.fp, self.dtype, self.pts2read_CrossSpectra )
1873 1873 cspc = cspc.reshape( (self.nRdPairs, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
1874 1874
1875 1875 if self.processingHeaderObj.flag_dc:
1876 1876 dc = numpy.fromfile( self.fp, self.dtype, self.pts2read_DCchannels ) #int(self.processingHeaderObj.nHeights*self.systemHeaderObj.nChannels) )
1877 1877 dc = dc.reshape( (self.systemHeaderObj.nChannels, self.processingHeaderObj.nHeights) ) #transforma a un arreglo 2D
1878 1878
1879 1879
1880 1880 if not(self.processingHeaderObj.shif_fft):
1881 1881 #desplaza a la derecha en el eje 2 determinadas posiciones
1882 1882 shift = int(self.processingHeaderObj.profilesPerBlock/2)
1883 1883 spc = numpy.roll( spc, shift , axis=2 )
1884 1884
1885 1885 if self.processingHeaderObj.flag_cspc:
1886 1886 #desplaza a la derecha en el eje 2 determinadas posiciones
1887 1887 cspc = numpy.roll( cspc, shift, axis=2 )
1888 1888
1889 1889
1890 1890 spc = numpy.transpose( spc, (0,2,1) )
1891 1891 self.data_spc = spc
1892 1892
1893 1893 if self.processingHeaderObj.flag_cspc:
1894 1894 cspc = numpy.transpose( cspc, (0,2,1) )
1895 1895 self.data_cspc = cspc['real'] + cspc['imag']*1j
1896 1896 else:
1897 1897 self.data_cspc = None
1898 1898
1899 1899 if self.processingHeaderObj.flag_dc:
1900 1900 self.data_dc = dc['real'] + dc['imag']*1j
1901 1901 else:
1902 1902 self.data_dc = None
1903 1903
1904 1904 self.flagIsNewFile = 0
1905 1905 self.flagIsNewBlock = 1
1906 1906
1907 1907 self.nTotalBlocks += 1
1908 1908 self.nReadBlocks += 1
1909 1909
1910 1910 return 1
1911 1911
1912 1912
1913 1913 def getData(self):
1914 1914 """
1915 1915 Copia el buffer de lectura a la clase "Spectra",
1916 1916 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
1917 1917 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
1918 1918
1919 1919 Return:
1920 1920 0 : Si no hay mas archivos disponibles
1921 1921 1 : Si hizo una buena copia del buffer
1922 1922
1923 1923 Affected:
1924 1924 self.dataOut
1925 1925
1926 1926 self.flagTimeBlock
1927 1927 self.flagIsNewBlock
1928 1928 """
1929 1929
1930 1930 if self.flagNoMoreFiles:
1931 1931 self.dataOut.flagNoData = True
1932 1932 print 'Process finished'
1933 1933 return 0
1934 1934
1935 1935 self.flagTimeBlock = 0
1936 1936 self.flagIsNewBlock = 0
1937 1937
1938 1938 if self.__hasNotDataInBuffer():
1939 1939
1940 1940 if not( self.readNextBlock() ):
1941 1941 self.dataOut.flagNoData = True
1942 1942 return 0
1943 1943
1944 1944 # self.updateDataHeader()
1945 1945
1946 1946 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
1947 1947
1948 1948 if self.data_dc == None:
1949 1949 self.dataOut.flagNoData = True
1950 1950 return 0
1951 1951
1952 1952 self.dataOut.data_spc = self.data_spc
1953 1953
1954 1954 self.dataOut.data_cspc = self.data_cspc
1955 1955
1956 1956 self.dataOut.data_dc = self.data_dc
1957 1957
1958 1958 self.dataOut.flagTimeBlock = self.flagTimeBlock
1959 1959
1960 1960 self.dataOut.flagNoData = False
1961 1961
1962 1962 self.dataOut.dtype = self.dtype
1963 1963
1964 1964 # self.dataOut.nChannels = self.nRdChannels
1965 1965
1966 1966 self.dataOut.nPairs = self.nRdPairs
1967 1967
1968 1968 self.dataOut.pairsList = self.rdPairList
1969 1969
1970 1970 self.dataOut.nHeights = self.processingHeaderObj.nHeights
1971 1971
1972 1972 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
1973 1973
1974 1974 self.dataOut.nFFTPoints = self.processingHeaderObj.profilesPerBlock
1975 1975
1976 self.dataOut.nIncohInt = self.processingHeaderObj.nIncohInt
1976 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
1977 1977
1978 self.dataOut.nIncohInt = self.processingHeaderObj.nIncohInt
1978 1979
1979 1980 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
1980 1981
1981 1982 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
1982 1983
1983 1984 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
1984 1985
1985 1986 # self.dataOut.channelIndexList = range(self.systemHeaderObj.nChannels)
1986 1987
1987 1988 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond/1000.#+ self.profileIndex * self.ippSeconds
1988 1989
1989 1990 self.dataOut.ippSeconds = self.ippSeconds
1990 1991
1991 1992 self.dataOut.timeInterval = self.ippSeconds * self.processingHeaderObj.nCohInt * self.processingHeaderObj.nIncohInt * self.dataOut.nFFTPoints
1992 1993
1993 1994 self.dataOut.flagShiftFFT = self.processingHeaderObj.shif_fft
1994 1995
1995 1996 # self.profileIndex += 1
1996 1997
1997 1998 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
1998 1999
1999 2000 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
2000 2001
2001 2002 return self.dataOut.data_spc
2002 2003
2003 2004
2004 2005 class SpectraWriter(JRODataWriter):
2005 2006
2006 2007 """
2007 2008 Esta clase permite escribir datos de espectros a archivos procesados (.pdata). La escritura
2008 2009 de los datos siempre se realiza por bloques.
2009 2010 """
2010 2011
2011 2012 ext = ".pdata"
2012 2013
2013 2014 optchar = "P"
2014 2015
2015 2016 shape_spc_Buffer = None
2016 2017
2017 2018 shape_cspc_Buffer = None
2018 2019
2019 2020 shape_dc_Buffer = None
2020 2021
2021 2022 data_spc = None
2022 2023
2023 2024 data_cspc = None
2024 2025
2025 2026 data_dc = None
2026 2027
2027 2028 # dataOut = None
2028 2029
2029 2030 def __init__(self):
2030 2031 """
2031 2032 Inicializador de la clase SpectraWriter para la escritura de datos de espectros.
2032 2033
2033 2034 Affected:
2034 2035 self.dataOut
2035 2036 self.basicHeaderObj
2036 2037 self.systemHeaderObj
2037 2038 self.radarControllerHeaderObj
2038 2039 self.processingHeaderObj
2039 2040
2040 2041 Return: None
2041 2042 """
2042 2043
2043 2044 self.isConfig = False
2044 2045
2045 2046 self.nTotalBlocks = 0
2046 2047
2047 2048 self.data_spc = None
2048 2049
2049 2050 self.data_cspc = None
2050 2051
2051 2052 self.data_dc = None
2052 2053
2053 2054 self.fp = None
2054 2055
2055 2056 self.flagIsNewFile = 1
2056 2057
2057 2058 self.nTotalBlocks = 0
2058 2059
2059 2060 self.flagIsNewBlock = 0
2060 2061
2061 2062 self.setFile = None
2062 2063
2063 2064 self.dtype = None
2064 2065
2065 2066 self.path = None
2066 2067
2067 2068 self.noMoreFiles = 0
2068 2069
2069 2070 self.filename = None
2070 2071
2071 2072 self.basicHeaderObj = BasicHeader()
2072 2073
2073 2074 self.systemHeaderObj = SystemHeader()
2074 2075
2075 2076 self.radarControllerHeaderObj = RadarControllerHeader()
2076 2077
2077 2078 self.processingHeaderObj = ProcessingHeader()
2078 2079
2079 2080
2080 2081 def hasAllDataInBuffer(self):
2081 2082 return 1
2082 2083
2083 2084
2084 2085 def setBlockDimension(self):
2085 2086 """
2086 2087 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
2087 2088
2088 2089 Affected:
2089 2090 self.shape_spc_Buffer
2090 2091 self.shape_cspc_Buffer
2091 2092 self.shape_dc_Buffer
2092 2093
2093 2094 Return: None
2094 2095 """
2095 2096 self.shape_spc_Buffer = (self.dataOut.nChannels,
2096 2097 self.processingHeaderObj.nHeights,
2097 2098 self.processingHeaderObj.profilesPerBlock)
2098 2099
2099 2100 self.shape_cspc_Buffer = (self.dataOut.nPairs,
2100 2101 self.processingHeaderObj.nHeights,
2101 2102 self.processingHeaderObj.profilesPerBlock)
2102 2103
2103 2104 self.shape_dc_Buffer = (self.dataOut.nChannels,
2104 2105 self.processingHeaderObj.nHeights)
2105 2106
2106 2107
2107 2108 def writeBlock(self):
2108 2109 """
2109 2110 Escribe el buffer en el file designado
2110 2111
2111 2112 Affected:
2112 2113 self.data_spc
2113 2114 self.data_cspc
2114 2115 self.data_dc
2115 2116 self.flagIsNewFile
2116 2117 self.flagIsNewBlock
2117 2118 self.nTotalBlocks
2118 2119 self.nWriteBlocks
2119 2120
2120 2121 Return: None
2121 2122 """
2122 2123
2123 2124 spc = numpy.transpose( self.data_spc, (0,2,1) )
2124 2125 if not( self.processingHeaderObj.shif_fft ):
2125 2126 spc = numpy.roll( spc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
2126 2127 data = spc.reshape((-1))
2127 2128 data.tofile(self.fp)
2128 2129
2129 2130 if self.data_cspc != None:
2130 2131 data = numpy.zeros( self.shape_cspc_Buffer, self.dtype )
2131 2132 cspc = numpy.transpose( self.data_cspc, (0,2,1) )
2132 2133 if not( self.processingHeaderObj.shif_fft ):
2133 2134 cspc = numpy.roll( cspc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
2134 2135 data['real'] = cspc.real
2135 2136 data['imag'] = cspc.imag
2136 2137 data = data.reshape((-1))
2137 2138 data.tofile(self.fp)
2138 2139
2139 2140 if self.data_dc != None:
2140 2141 data = numpy.zeros( self.shape_dc_Buffer, self.dtype )
2141 2142 dc = self.data_dc
2142 2143 data['real'] = dc.real
2143 2144 data['imag'] = dc.imag
2144 2145 data = data.reshape((-1))
2145 2146 data.tofile(self.fp)
2146 2147
2147 2148 self.data_spc.fill(0)
2148 2149 self.data_dc.fill(0)
2149 2150 if self.data_cspc != None:
2150 2151 self.data_cspc.fill(0)
2151 2152
2152 2153 self.flagIsNewFile = 0
2153 2154 self.flagIsNewBlock = 1
2154 2155 self.nTotalBlocks += 1
2155 2156 self.nWriteBlocks += 1
2156 2157 self.blockIndex += 1
2157 2158
2158 2159
2159 2160 def putData(self):
2160 2161 """
2161 2162 Setea un bloque de datos y luego los escribe en un file
2162 2163
2163 2164 Affected:
2164 2165 self.data_spc
2165 2166 self.data_cspc
2166 2167 self.data_dc
2167 2168
2168 2169 Return:
2169 2170 0 : Si no hay data o no hay mas files que puedan escribirse
2170 2171 1 : Si se escribio la data de un bloque en un file
2171 2172 """
2172 2173
2173 2174 if self.dataOut.flagNoData:
2174 2175 return 0
2175 2176
2176 2177 self.flagIsNewBlock = 0
2177 2178
2178 2179 if self.dataOut.flagTimeBlock:
2179 2180 self.data_spc.fill(0)
2180 2181 self.data_cspc.fill(0)
2181 2182 self.data_dc.fill(0)
2182 2183 self.setNextFile()
2183 2184
2184 2185 if self.flagIsNewFile == 0:
2185 2186 self.getBasicHeader()
2186 2187
2187 2188 self.data_spc = self.dataOut.data_spc
2188 2189 self.data_cspc = self.dataOut.data_cspc
2189 2190 self.data_dc = self.dataOut.data_dc
2190 2191
2191 2192 # #self.processingHeaderObj.dataBlocksPerFile)
2192 2193 if self.hasAllDataInBuffer():
2193 2194 # self.getDataHeader()
2194 2195 self.writeNextBlock()
2195 2196
2196 2197 return 1
2197 2198
2198 2199
2199 2200 def __getProcessFlags(self):
2200 2201
2201 2202 processFlags = 0
2202 2203
2203 2204 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
2204 2205 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
2205 2206 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
2206 2207 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
2207 2208 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
2208 2209 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
2209 2210
2210 2211 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
2211 2212
2212 2213
2213 2214
2214 2215 datatypeValueList = [PROCFLAG.DATATYPE_CHAR,
2215 2216 PROCFLAG.DATATYPE_SHORT,
2216 2217 PROCFLAG.DATATYPE_LONG,
2217 2218 PROCFLAG.DATATYPE_INT64,
2218 2219 PROCFLAG.DATATYPE_FLOAT,
2219 2220 PROCFLAG.DATATYPE_DOUBLE]
2220 2221
2221 2222
2222 2223 for index in range(len(dtypeList)):
2223 2224 if self.dataOut.dtype == dtypeList[index]:
2224 2225 dtypeValue = datatypeValueList[index]
2225 2226 break
2226 2227
2227 2228 processFlags += dtypeValue
2228 2229
2229 2230 if self.dataOut.flagDecodeData:
2230 2231 processFlags += PROCFLAG.DECODE_DATA
2231 2232
2232 2233 if self.dataOut.flagDeflipData:
2233 2234 processFlags += PROCFLAG.DEFLIP_DATA
2234 2235
2235 2236 if self.dataOut.code != None:
2236 2237 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
2237 2238
2238 2239 if self.dataOut.nIncohInt > 1:
2239 2240 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
2240 2241
2241 2242 if self.dataOut.data_dc != None:
2242 2243 processFlags += PROCFLAG.SAVE_CHANNELS_DC
2243 2244
2244 2245 return processFlags
2245 2246
2246 2247
2247 2248 def __getBlockSize(self):
2248 2249 '''
2249 2250 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Spectra
2250 2251 '''
2251 2252
2252 2253 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
2253 2254 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
2254 2255 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
2255 2256 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
2256 2257 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
2257 2258 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
2258 2259
2259 2260 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
2260 2261 datatypeValueList = [1,2,4,8,4,8]
2261 2262 for index in range(len(dtypeList)):
2262 2263 if self.dataOut.dtype == dtypeList[index]:
2263 2264 datatypeValue = datatypeValueList[index]
2264 2265 break
2265 2266
2266 2267
2267 2268 pts2write = self.dataOut.nHeights * self.dataOut.nFFTPoints
2268 2269
2269 2270 pts2write_SelfSpectra = int(self.dataOut.nChannels * pts2write)
2270 2271 blocksize = (pts2write_SelfSpectra*datatypeValue)
2271 2272
2272 2273 if self.dataOut.data_cspc != None:
2273 2274 pts2write_CrossSpectra = int(self.dataOut.nPairs * pts2write)
2274 2275 blocksize += (pts2write_CrossSpectra*datatypeValue*2)
2275 2276
2276 2277 if self.dataOut.data_dc != None:
2277 2278 pts2write_DCchannels = int(self.dataOut.nChannels * self.dataOut.nHeights)
2278 2279 blocksize += (pts2write_DCchannels*datatypeValue*2)
2279 2280
2280 2281 blocksize = blocksize #* datatypeValue * 2 #CORREGIR ESTO
2281 2282
2282 2283 return blocksize
2283 2284
2284 2285 def getDataHeader(self):
2285 2286
2286 2287 """
2287 2288 Obtiene una copia del First Header
2288 2289
2289 2290 Affected:
2290 2291 self.systemHeaderObj
2291 2292 self.radarControllerHeaderObj
2292 2293 self.dtype
2293 2294
2294 2295 Return:
2295 2296 None
2296 2297 """
2297 2298
2298 2299 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
2299 2300 self.systemHeaderObj.nChannels = self.dataOut.nChannels
2300 2301 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
2301 2302
2302 2303 self.getBasicHeader()
2303 2304
2304 2305 processingHeaderSize = 40 # bytes
2305 2306 self.processingHeaderObj.dtype = 0 # Voltage
2306 2307 self.processingHeaderObj.blockSize = self.__getBlockSize()
2307 2308 self.processingHeaderObj.profilesPerBlock = self.dataOut.nFFTPoints
2308 2309 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
2309 2310 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
2310 2311 self.processingHeaderObj.processFlags = self.__getProcessFlags()
2311 2312 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt# Se requiere para determinar el valor de timeInterval
2312 2313 self.processingHeaderObj.nIncohInt = self.dataOut.nIncohInt
2313 2314 self.processingHeaderObj.totalSpectra = self.dataOut.nPairs + self.dataOut.nChannels
2314 2315
2315 2316 if self.processingHeaderObj.totalSpectra > 0:
2316 2317 channelList = []
2317 2318 for channel in range(self.dataOut.nChannels):
2318 2319 channelList.append(channel)
2319 2320 channelList.append(channel)
2320 2321
2321 2322 pairsList = []
2322 2323 for pair in self.dataOut.pairsList:
2323 2324 pairsList.append(pair[0])
2324 2325 pairsList.append(pair[1])
2325 2326 spectraComb = channelList + pairsList
2326 2327 spectraComb = numpy.array(spectraComb,dtype="u1")
2327 2328 self.processingHeaderObj.spectraComb = spectraComb
2328 2329 sizeOfSpcComb = len(spectraComb)
2329 2330 processingHeaderSize += sizeOfSpcComb
2330 2331
2331 2332 if self.dataOut.code != None:
2332 2333 self.processingHeaderObj.code = self.dataOut.code
2333 2334 self.processingHeaderObj.nCode = self.dataOut.nCode
2334 2335 self.processingHeaderObj.nBaud = self.dataOut.nBaud
2335 2336 nCodeSize = 4 # bytes
2336 2337 nBaudSize = 4 # bytes
2337 2338 codeSize = 4 # bytes
2338 2339 sizeOfCode = int(nCodeSize + nBaudSize + codeSize * self.dataOut.nCode * self.dataOut.nBaud)
2339 2340 processingHeaderSize += sizeOfCode
2340 2341
2341 2342 if self.processingHeaderObj.nWindows != 0:
2342 2343 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
2343 2344 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
2344 2345 self.processingHeaderObj.nHeights = self.dataOut.nHeights
2345 2346 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
2346 2347 sizeOfFirstHeight = 4
2347 2348 sizeOfdeltaHeight = 4
2348 2349 sizeOfnHeights = 4
2349 2350 sizeOfWindows = (sizeOfFirstHeight + sizeOfdeltaHeight + sizeOfnHeights)*self.processingHeaderObj.nWindows
2350 2351 processingHeaderSize += sizeOfWindows
2351 2352
2352 2353 self.processingHeaderObj.size = processingHeaderSize
2353 2354
2354 2355 class SpectraHeisWriter():
2355 2356
2356 2357 i=0
2357 2358
2358 2359 def __init__(self, dataOut):
2359 2360
2360 2361 self.wrObj = FITS()
2361 2362 self.dataOut = dataOut
2362 2363
2363 2364 def isNumber(str):
2364 2365 """
2365 2366 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
2366 2367
2367 2368 Excepciones:
2368 2369 Si un determinado string no puede ser convertido a numero
2369 2370 Input:
2370 2371 str, string al cual se le analiza para determinar si convertible a un numero o no
2371 2372
2372 2373 Return:
2373 2374 True : si el string es uno numerico
2374 2375 False : no es un string numerico
2375 2376 """
2376 2377 try:
2377 2378 float( str )
2378 2379 return True
2379 2380 except:
2380 2381 return False
2381 2382
2382 2383 def setup(self, wrpath,):
2383 2384
2384 2385 if not(os.path.exists(wrpath)):
2385 2386 os.mkdir(wrpath)
2386 2387
2387 2388 self.wrpath = wrpath
2388 2389 self.setFile = 0
2389 2390
2390 2391 def putData(self):
2391 2392 # self.wrObj.writeHeader(nChannels=self.dataOut.nChannels, nFFTPoints=self.dataOut.nFFTPoints)
2392 2393 #name = self.dataOut.utctime
2393 2394 name= time.localtime( self.dataOut.utctime)
2394 2395 ext=".fits"
2395 2396 #folder='D%4.4d%3.3d'%(name.tm_year,name.tm_yday)
2396 2397 subfolder = 'D%4.4d%3.3d' % (name.tm_year,name.tm_yday)
2397 2398
2398 2399 doypath = os.path.join( self.wrpath, subfolder )
2399 2400 if not( os.path.exists(doypath) ):
2400 2401 os.mkdir(doypath)
2401 2402 self.setFile += 1
2402 2403 file = 'D%4.4d%3.3d%3.3d%s' % (name.tm_year,name.tm_yday,self.setFile,ext)
2403 2404
2404 2405 filename = os.path.join(self.wrpath,subfolder, file)
2405 2406
2406 2407 # print self.dataOut.ippSeconds
2407 2408 freq=numpy.arange(-1*self.dataOut.nHeights/2.,self.dataOut.nHeights/2.)/(2*self.dataOut.ippSeconds)
2408 2409
2409 2410 col1=self.wrObj.setColF(name="freq", format=str(self.dataOut.nFFTPoints)+'E', array=freq)
2410 2411 col2=self.wrObj.writeData(name="P_Ch1",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[0,:]))
2411 2412 col3=self.wrObj.writeData(name="P_Ch2",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[1,:]))
2412 2413 col4=self.wrObj.writeData(name="P_Ch3",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[2,:]))
2413 2414 col5=self.wrObj.writeData(name="P_Ch4",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[3,:]))
2414 2415 col6=self.wrObj.writeData(name="P_Ch5",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[4,:]))
2415 2416 col7=self.wrObj.writeData(name="P_Ch6",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[5,:]))
2416 2417 col8=self.wrObj.writeData(name="P_Ch7",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[6,:]))
2417 2418 col9=self.wrObj.writeData(name="P_Ch8",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[7,:]))
2418 2419 #n=numpy.arange((100))
2419 2420 n=self.dataOut.data_spc[6,:]
2420 2421 a=self.wrObj.cFImage(n)
2421 2422 b=self.wrObj.Ctable(col1,col2,col3,col4,col5,col6,col7,col8,col9)
2422 2423 self.wrObj.CFile(a,b)
2423 2424 self.wrObj.wFile(filename)
2424 2425 return 1
2425 2426
2426 2427 class FITS:
2427 2428
2428 2429 name=None
2429 2430 format=None
2430 2431 array =None
2431 2432 data =None
2432 2433 thdulist=None
2433 2434
2434 2435 def __init__(self):
2435 2436
2436 2437 pass
2437 2438
2438 2439 def setColF(self,name,format,array):
2439 2440 self.name=name
2440 2441 self.format=format
2441 2442 self.array=array
2442 2443 a1=numpy.array([self.array],dtype=numpy.float32)
2443 2444 self.col1 = pyfits.Column(name=self.name, format=self.format, array=a1)
2444 2445 return self.col1
2445 2446
2446 2447 # def setColP(self,name,format,data):
2447 2448 # self.name=name
2448 2449 # self.format=format
2449 2450 # self.data=data
2450 2451 # a2=numpy.array([self.data],dtype=numpy.float32)
2451 2452 # self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2)
2452 2453 # return self.col2
2453 2454
2454 2455 def writeHeader(self,):
2455 2456 pass
2456 2457
2457 2458 def writeData(self,name,format,data):
2458 2459 self.name=name
2459 2460 self.format=format
2460 2461 self.data=data
2461 2462 a2=numpy.array([self.data],dtype=numpy.float32)
2462 2463 self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2)
2463 2464 return self.col2
2464 2465
2465 2466 def cFImage(self,n):
2466 2467 self.hdu= pyfits.PrimaryHDU(n)
2467 2468 return self.hdu
2468 2469
2469 2470 def Ctable(self,col1,col2,col3,col4,col5,col6,col7,col8,col9):
2470 2471 self.cols=pyfits.ColDefs( [col1,col2,col3,col4,col5,col6,col7,col8,col9])
2471 2472 self.tbhdu = pyfits.new_table(self.cols)
2472 2473 return self.tbhdu
2473 2474
2474 2475 def CFile(self,hdu,tbhdu):
2475 2476 self.thdulist=pyfits.HDUList([hdu,tbhdu])
2476 2477
2477 2478 def wFile(self,filename):
2478 2479 self.thdulist.writeto(filename) No newline at end of file
@@ -1,193 +1,209
1 1 import numpy
2 2 import datetime
3 3 from graphics.figure import *
4 4
5 5 class SpectraPlot(Figure):
6 6
7 7 __isConfig = None
8 8
9 9 def __init__(self):
10 10
11 11 self.__isConfig = False
12 self.width = 850
13 self.height = 800
14
12 self.WIDTH = 300
13 self.HEIGHT = 400
14
15 15 def getSubplots(self):
16 16
17 17 ncol = int(numpy.sqrt(self.nplots)+0.9)
18 18 nrow = int(self.nplots*1./ncol + 0.9)
19 19 return nrow, ncol
20
20
21 21 def setAxesWithOutProfiles(self, nrow, ncol):
22 22
23 23 colspan = 1
24 24 rowspan = 1
25 25 counter = 0
26 26
27 27 for y in range(nrow):
28 28 for x in range(ncol):
29 29 if counter < self.nplots:
30 self.makeAxes(nrow, ncol, y, x, colspan, rowspan)
30 self.addAxes(nrow, ncol, y, x, colspan, rowspan)
31 31 counter += 1
32 32
33 33 def setAxesWithProfiles(self, nrow, ncol):
34 34
35 35 colspan = 1
36 36 rowspan = 1
37 37 factor = 2
38 38 ncol = ncol*factor
39 39 counter = 0
40 40
41 41 for y in range(nrow):
42 42 for x in range(ncol):
43 43 if counter < self.nplots*factor:
44 44 # plt.subplot2grid((nrow, ncol), (y, x), colspan=colspan, rowspan=rowspan)
45 self.makeAxes(nrow, ncol, y, x, colspan, rowspan)
45 self.addAxes(nrow, ncol, y, x, colspan, rowspan)
46 46 counter += 1
47 47
48 def setup(self, idfigure, wintitle, width, height, nplots, profile):
48 def setup(self, idfigure, nplots, wintitle, showprofile=True):
49 49
50 self.init(idfigure, wintitle, width, height, nplots)
50 self.init(idfigure, nplots, wintitle)
51 51
52 nrow,ncol = self.getSubplots()
52 nrow, ncol = self.getSubplots()
53 53
54 if profile:
54 if showprofile:
55 55 self.setAxesWithProfiles(nrow, ncol)
56 56 else:
57 57 self.setAxesWithOutProfiles(nrow, ncol)
58 58
59 def run(self, dataOut, idfigure, wintitle="", channelList=None, xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, profile=False):
59 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile=False,
60 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None):
61
62 """
63
64 Input:
65 dataOut :
66 idfigure :
67 wintitle :
68 channelList :
69 showProfile :
70 xmin : None,
71 xmax : None,
72 ymin : None,
73 ymax : None,
74 zmin : None,
75 zmax : None
76 """
60 77
61 78 if channelList == None:
62 79 channelList = dataOut.channelList
63
64 nplots = len(channelList)
65
66 z = 10.*numpy.log10(dataOut.data_spc[channelList,:,:])
67 80
81 x = dataOut.getVelRange(1)
68 82 y = dataOut.heightList
69
70 x = numpy.arange(dataOut.nFFTPoints)
83 z = 10.*numpy.log10(dataOut.data_spc[channelList,:,:])
71 84
72 85 noise = dataOut.getNoise()
73 86
74 87 if not self.__isConfig:
75 self.setup(idfigure=idfigure,
76 wintitle=wintitle,
77 width=self.width,
78 height=self.height,
79 nplots=nplots,
80 profile=profile)
81 88
82 if xmin == None: xmin = numpy.min(x)
83 if xmax == None: xmax = numpy.max(x)
84 if ymin == None: ymin = numpy.min(y)
85 if ymax == None: ymax = numpy.max(y)
86 if zmin == None: zmin = numpy.min(z)
87 if zmax == None: zmax = numpy.max(z)
89 nplots = len(channelList)
88 90
89 self.xmin = xmin
90 self.xmax = xmax
91 self.ymin = ymin
92 self.ymax = ymax
93 self.zmin = zmin
94 self.zmax = zmax
91 self.setup(idfigure=idfigure,
92 nplots=nplots,
93 wintitle=wintitle,
94 showprofile=showprofile)
95
96 if xmin == None: xmin = numpy.nanmin(x)
97 if xmax == None: xmax = numpy.nanmax(x)
98 if ymin == None: ymin = numpy.nanmin(y)
99 if ymax == None: ymax = numpy.nanmax(y)
100 if zmin == None: zmin = numpy.nanmin(z)*0.9
101 if zmax == None: zmax = numpy.nanmax(z)*0.9
95 102
96 103 self.__isConfig = True
97
104
98 105 thisDatetime = datetime.datetime.fromtimestamp(dataOut.utctime)
99 dateTime = "%s"%(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
100 date = "%s"%(thisDatetime.strftime("%d-%b-%Y"))
101 title = "Spectra: " + dateTime
106 title = "Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
107 xlabel = "Velocity (m/s)"
108 ylabel = "Range (Km)"
102 109
103 110 self.setWinTitle(title)
104 111
105 ylabel = "Range[Km]"
106
107 xlabel = "m/s"
108
109 for i in range(len(self.axesList)):
112 for i in range(self.nplots):
110 113 title = "Channel %d: %4.2fdB" %(channelList[i], noise[i])
114 zchannel = z[i,:,:]
115
111 116 axes = self.axesList[i]
112 z2 = z[i,:,:]
113 axes.pcolor(x, y, z2, self.xmin, self.xmax, self.ymin, self.ymax, self.zmin, self.zmax, xlabel, ylabel, title)
117 axes.pcolor(x, y, zchannel,
118 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
119 xlabel=xlabel, ylabel=ylabel, title=title,
120 ticksize=9, cblabel='dB')
114 121
115 122 self.draw()
116 123
117 124 class Scope(Figure):
125
118 126 __isConfig = None
119 127
120 128 def __init__(self):
129
121 130 self.__isConfig = False
122 self.width = 850
123 self.height = 800
131 self.WIDTH = 600
132 self.HEIGHT = 200
124 133
125 134 def getSubplots(self):
135
126 136 nrow = self.nplots
127 137 ncol = 3
128 138 return nrow, ncol
129 139
130 def setup(self, idfigure, wintitle, width, height, nplots):
131 self.init(idfigure, wintitle, width, height, nplots)
140 def setup(self, idfigure, nplots, wintitle):
141
142 self.init(idfigure, nplots, wintitle)
132 143
133 144 nrow,ncol = self.getSubplots()
134 145 colspan = 3
135 146 rowspan = 1
136 147
137 148 for i in range(nplots):
138 self.makeAxes(nrow, ncol, i, 0, colspan, rowspan)
139
140
149 self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
141 150
142 def run(self, dataOut, idfigure, wintitle="", channelList=None, xmin=None, xmax=None, ymin=None, ymax=None):
143
144 if dataOut.isEmpty():
145 return None
151 def run(self, dataOut, idfigure, wintitle="", channelList=None,
152 xmin=None, xmax=None, ymin=None, ymax=None):
153
154 """
155
156 Input:
157 dataOut :
158 idfigure :
159 wintitle :
160 channelList :
161 xmin : None,
162 xmax : None,
163 ymin : None,
164 ymax : None,
165 """
146 166
147 167 if channelList == None:
148 channelList = dataOut.channelList
149
150 nplots = len(channelList)
168 channelList = dataOut.channelList
151 169
170 x = dataOut.heightList
152 171 y = dataOut.data[channelList,:] * numpy.conjugate(dataOut.data[channelList,:])
153 172 y = y.real
154 173
155 x = dataOut.heightList
174 noise = dataOut.getNoise()
156 175
157 176 if not self.__isConfig:
158 self.setup(idfigure=idfigure,
159 wintitle=wintitle,
160 width=self.width,
161 height=self.height,
162 nplots=nplots)
177 nplots = len(channelList)
178
179 self.setup(idfigure=idfigure,
180 nplots=nplots,
181 wintitle=wintitle)
163 182
164 if xmin == None: self.xmin = numpy.min(x)
165 if xmax == None: self.xmax = numpy.max(x)
166 if ymin == None: self.ymin = numpy.min(y)
167 if ymax == None: self.ymax = numpy.max(y)
183 if xmin == None: xmin = numpy.nanmin(x)
184 if xmax == None: xmax = numpy.nanmax(x)
185 if ymin == None: ymin = numpy.nanmin(y)
186 if ymax == None: ymax = numpy.nanmax(y)
168 187
169 188 self.__isConfig = True
170 189
171 190
172
173 191 thisDatetime = datetime.datetime.fromtimestamp(dataOut.utctime)
174 dateTime = "%s"%(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
175 date = "%s"%(thisDatetime.strftime("%d-%b-%Y"))
176 title = "Scope: " + dateTime
177
178 self.setWinTitle(title)
179
192 title = "Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
193 xlabel = "Range (Km)"
180 194 ylabel = "Intensity"
181 195
182 xlabel = "Range[Km]"
196 self.setWinTitle(title)
183 197
184 198 for i in range(len(self.axesList)):
185 199 title = "Channel %d: %4.2fdB" %(i, noise[i])
186 200 axes = self.axesList[i]
187 y2 = y[i,:]
188 axes.pline(x, y2, self.xmin, self.xmax, self.ymin, self.ymax, xlabel, ylabel, title)
201 ychannel = y[i,:]
202 axes.pline(x, ychannel,
203 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
204 xlabel=xlabel, ylabel=ylabel, title=title)
189 205
190 206 self.draw()
191 207
192 208
193 209 No newline at end of file
@@ -1,648 +1,836
1 1 '''
2 2
3 3 $Author: dsuarez $
4 4 $Id: Processor.py 1 2012-11-12 18:56:07Z dsuarez $
5 5 '''
6 6 import os
7 7 import numpy
8 8 import datetime
9 9 import time
10 10
11 11 from jrodata import *
12 12 from jrodataIO import *
13 13 from jroplot import *
14 14
15 15 class ProcessingUnit:
16 16
17 17 """
18 18 Esta es la clase base para el procesamiento de datos.
19 19
20 20 Contiene el metodo "call" para llamar operaciones. Las operaciones pueden ser:
21 21 - Metodos internos (callMethod)
22 22 - Objetos del tipo Operation (callObject). Antes de ser llamados, estos objetos
23 23 tienen que ser agreagados con el metodo "add".
24 24
25 25 """
26 26 # objeto de datos de entrada (Voltage, Spectra o Correlation)
27 27 dataIn = None
28 28
29 29 # objeto de datos de entrada (Voltage, Spectra o Correlation)
30 30 dataOut = None
31 31
32 32
33 33 objectDict = None
34 34
35 35 def __init__(self):
36 36
37 37 self.objectDict = {}
38 38
39 39 def init(self):
40 40
41 41 raise ValueError, "Not implemented"
42 42
43 43 def addOperation(self, object, objId):
44 44
45 45 """
46 46 Agrega el objeto "object" a la lista de objetos "self.objectList" y retorna el
47 47 identificador asociado a este objeto.
48 48
49 49 Input:
50 50
51 51 object : objeto de la clase "Operation"
52 52
53 53 Return:
54 54
55 55 objId : identificador del objeto, necesario para ejecutar la operacion
56 56 """
57 57
58 58 self.objectDict[objId] = object
59 59
60 60 return objId
61 61
62 62 def operation(self, **kwargs):
63 63
64 64 """
65 65 Operacion directa sobre la data (dataout.data). Es necesario actualizar los valores de los
66 66 atributos del objeto dataOut
67 67
68 68 Input:
69 69
70 70 **kwargs : Diccionario de argumentos de la funcion a ejecutar
71 71 """
72 72
73 73 raise ValueError, "ImplementedError"
74 74
75 75 def callMethod(self, name, **kwargs):
76 76
77 77 """
78 78 Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
79 79
80 80 Input:
81 81 name : nombre del metodo a ejecutar
82 82
83 83 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
84 84
85 85 """
86 86 if name != 'run':
87 87
88 88 if name == 'init' and self.dataIn.isEmpty():
89 89 self.dataOut.flagNoData = True
90 90 return False
91 91
92 92 if name != 'init' and self.dataOut.isEmpty():
93 93 return False
94 94
95 95 methodToCall = getattr(self, name)
96 96
97 97 methodToCall(**kwargs)
98 98
99 99 if name != 'run':
100 100 return True
101 101
102 102 if self.dataOut.isEmpty():
103 103 return False
104 104
105 105 return True
106 106
107 107 def callObject(self, objId, **kwargs):
108 108
109 109 """
110 110 Ejecuta la operacion asociada al identificador del objeto "objId"
111 111
112 112 Input:
113 113
114 114 objId : identificador del objeto a ejecutar
115 115
116 116 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
117 117
118 118 Return:
119 119
120 120 None
121 121 """
122 122
123 123 if self.dataOut.isEmpty():
124 124 return False
125 125
126 126 object = self.objectDict[objId]
127 127
128 128 object.run(self.dataOut, **kwargs)
129 129
130 130 return True
131 131
132 132 def call(self, operationConf, **kwargs):
133 133
134 134 """
135 135 Return True si ejecuta la operacion "operationConf.name" con los
136 136 argumentos "**kwargs". False si la operacion no se ha ejecutado.
137 137 La operacion puede ser de dos tipos:
138 138
139 139 1. Un metodo propio de esta clase:
140 140
141 141 operation.type = "self"
142 142
143 143 2. El metodo "run" de un objeto del tipo Operation o de un derivado de ella:
144 144 operation.type = "other".
145 145
146 146 Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
147 147 "addOperation" e identificado con el operation.id
148 148
149 149
150 150 con el id de la operacion.
151 151
152 152 Input:
153 153
154 154 Operation : Objeto del tipo operacion con los atributos: name, type y id.
155 155
156 156 """
157 157
158 158 if operationConf.type == 'self':
159 159 sts = self.callMethod(operationConf.name, **kwargs)
160 160
161 161 if operationConf.type == 'other':
162 162 sts = self.callObject(operationConf.id, **kwargs)
163 163
164 164 return sts
165 165
166 166 def setInput(self, dataIn):
167 167
168 168 self.dataIn = dataIn
169 169
170 170 def getOutput(self):
171 171
172 172 return self.dataOut
173 173
174 174 class Operation():
175 175
176 176 """
177 177 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
178 178 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
179 179 acumulacion dentro de esta clase
180 180
181 181 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
182 182
183 183 """
184 184
185 185 __buffer = None
186 186 __isConfig = False
187 187
188 188 def __init__(self):
189 189
190 190 pass
191 191
192 192 def run(self, dataIn, **kwargs):
193 193
194 194 """
195 195 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los atributos del objeto dataIn.
196 196
197 197 Input:
198 198
199 199 dataIn : objeto del tipo JROData
200 200
201 201 Return:
202 202
203 203 None
204 204
205 205 Affected:
206 206 __buffer : buffer de recepcion de datos.
207 207
208 208 """
209 209
210 210 raise ValueError, "ImplementedError"
211 211
212 212 class VoltageProc(ProcessingUnit):
213 213
214 214
215 215 def __init__(self):
216 216
217 217 self.objectDict = {}
218 218 self.dataOut = Voltage()
219 219
220 220 def init(self):
221 221
222 222 self.dataOut.copy(self.dataIn)
223 223 # No necesita copiar en cada init() los atributos de dataIn
224 224 # la copia deberia hacerse por cada nuevo bloque de datos
225 225
226 226 def selectChannels(self, channelList):
227 227
228 228 channelIndexList = []
229 229
230 230 for channel in channelList:
231 231 index = self.dataOut.channelList.index(channel)
232 232 channelIndexList.append(index)
233 233
234 234 self.selectChannelsByIndex(channelIndexList)
235 235
236 236 def selectChannelsByIndex(self, channelIndexList):
237 237 """
238 238 Selecciona un bloque de datos en base a canales segun el channelIndexList
239 239
240 240 Input:
241 241 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
242 242
243 243 Affected:
244 244 self.dataOut.data
245 245 self.dataOut.channelIndexList
246 246 self.dataOut.nChannels
247 247 self.dataOut.m_ProcessingHeader.totalSpectra
248 248 self.dataOut.systemHeaderObj.numChannels
249 249 self.dataOut.m_ProcessingHeader.blockSize
250 250
251 251 Return:
252 252 None
253 253 """
254 254
255 255 for channelIndex in channelIndexList:
256 256 if channelIndex not in self.dataOut.channelIndexList:
257 257 print channelIndexList
258 258 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
259 259
260 260 nChannels = len(channelIndexList)
261 261
262 262 data = self.dataOut.data[channelIndexList,:]
263 263
264 264 self.dataOut.data = data
265 265 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
266 266 # self.dataOut.nChannels = nChannels
267 267
268 268 return 1
269 269
270 270 class CohInt(Operation):
271 271
272 272 __profIndex = 0
273 273 __withOverapping = False
274 274
275 275 __byTime = False
276 276 __initime = None
277 277 __lastdatatime = None
278 278 __integrationtime = None
279 279
280 280 __buffer = None
281 281
282 282 __dataReady = False
283 283
284 nCohInt = None
284 n = None
285 285
286 286
287 287 def __init__(self):
288 288
289 289 self.__isConfig = False
290 290
291 def setup(self, nCohInt=None, timeInterval=None, overlapping=False):
291 def setup(self, n=None, timeInterval=None, overlapping=False):
292 292 """
293 293 Set the parameters of the integration class.
294 294
295 295 Inputs:
296 296
297 nCohInt : Number of coherent integrations
298 timeInterval : Time of integration. If the parameter "nCohInt" is selected this one does not work
297 n : Number of coherent integrations
298 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
299 299 overlapping :
300 300
301 301 """
302 302
303 303 self.__initime = None
304 304 self.__lastdatatime = 0
305 305 self.__buffer = None
306 306 self.__dataReady = False
307 307
308 308
309 if nCohInt == None and timeInterval == None:
310 raise ValueError, "nCohInt or timeInterval should be specified ..."
309 if n == None and timeInterval == None:
310 raise ValueError, "n or timeInterval should be specified ..."
311 311
312 if nCohInt != None:
313 self.nCohInt = nCohInt
312 if n != None:
313 self.n = n
314 314 self.__byTime = False
315 315 else:
316 316 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
317 self.nCohInt = 9999
317 self.n = 9999
318 318 self.__byTime = True
319 319
320 320 if overlapping:
321 321 self.__withOverapping = True
322 322 self.__buffer = None
323 323 else:
324 324 self.__withOverapping = False
325 325 self.__buffer = 0
326 326
327 327 self.__profIndex = 0
328 328
329 329 def putData(self, data):
330 330
331 331 """
332 332 Add a profile to the __buffer and increase in one the __profileIndex
333 333
334 334 """
335 335
336 336 if not self.__withOverapping:
337 self.__buffer += data
337 self.__buffer += data.copy()
338 338 self.__profIndex += 1
339 339 return
340 340
341 341 #Overlapping data
342 342 nChannels, nHeis = data.shape
343 343 data = numpy.reshape(data, (1, nChannels, nHeis))
344 344
345 345 #If the buffer is empty then it takes the data value
346 346 if self.__buffer == None:
347 347 self.__buffer = data
348 348 self.__profIndex += 1
349 349 return
350 350
351 #If the buffer length is lower than nCohInt then stakcing the data value
352 if self.__profIndex < self.nCohInt:
351 #If the buffer length is lower than n then stakcing the data value
352 if self.__profIndex < self.n:
353 353 self.__buffer = numpy.vstack((self.__buffer, data))
354 354 self.__profIndex += 1
355 355 return
356 356
357 #If the buffer length is equal to nCohInt then replacing the last buffer value with the data value
357 #If the buffer length is equal to n then replacing the last buffer value with the data value
358 358 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
359 self.__buffer[self.nCohInt-1] = data
360 self.__profIndex = self.nCohInt
359 self.__buffer[self.n-1] = data
360 self.__profIndex = self.n
361 361 return
362 362
363 363
364 364 def pushData(self):
365 365 """
366 366 Return the sum of the last profiles and the profiles used in the sum.
367 367
368 368 Affected:
369 369
370 370 self.__profileIndex
371 371
372 372 """
373 373
374 374 if not self.__withOverapping:
375 375 data = self.__buffer
376 nCohInt = self.__profIndex
376 n = self.__profIndex
377 377
378 378 self.__buffer = 0
379 379 self.__profIndex = 0
380 380
381 return data, nCohInt
381 return data, n
382 382
383 383 #Integration with Overlapping
384 384 data = numpy.sum(self.__buffer, axis=0)
385 nCohInt = self.__profIndex
385 n = self.__profIndex
386 386
387 return data, nCohInt
387 return data, n
388 388
389 389 def byProfiles(self, data):
390 390
391 391 self.__dataReady = False
392 392 avgdata = None
393 nCohInt = None
393 n = None
394 394
395 395 self.putData(data)
396 396
397 if self.__profIndex == self.nCohInt:
397 if self.__profIndex == self.n:
398 398
399 avgdata, nCohInt = self.pushData()
399 avgdata, n = self.pushData()
400 400 self.__dataReady = True
401 401
402 402 return avgdata
403 403
404 404 def byTime(self, data, datatime):
405 405
406 406 self.__dataReady = False
407 407 avgdata = None
408 nCohInt = None
408 n = None
409 409
410 410 self.putData(data)
411 411
412 412 if (datatime - self.__initime) >= self.__integrationtime:
413 avgdata, nCohInt = self.pushData()
414 self.nCohInt = nCohInt
413 avgdata, n = self.pushData()
414 self.n = n
415 415 self.__dataReady = True
416 416
417 417 return avgdata
418 418
419 419 def integrate(self, data, datatime=None):
420 420
421 421 if self.__initime == None:
422 422 self.__initime = datatime
423 423
424 424 if self.__byTime:
425 425 avgdata = self.byTime(data, datatime)
426 426 else:
427 427 avgdata = self.byProfiles(data)
428 428
429 429
430 430 self.__lastdatatime = datatime
431 431
432 432 if avgdata == None:
433 433 return None, None
434 434
435 435 avgdatatime = self.__initime
436 436
437 437 deltatime = datatime -self.__lastdatatime
438 438
439 439 if not self.__withOverapping:
440 440 self.__initime = datatime
441 441 else:
442 442 self.__initime += deltatime
443 443
444 444 return avgdata, avgdatatime
445 445
446 def run(self, dataOut, nCohInt=None, timeInterval=None, overlapping=False):
446 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
447 447
448 448 if not self.__isConfig:
449 self.setup(nCohInt, timeInterval, overlapping)
449 self.setup(n, timeInterval, overlapping)
450 450 self.__isConfig = True
451 451
452 452 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
453 453
454 # dataOut.timeInterval *= nCohInt
454 # dataOut.timeInterval *= n
455 455 dataOut.flagNoData = True
456 456
457 457 if self.__dataReady:
458 458 dataOut.data = avgdata
459 dataOut.timeInterval *= self.nCohInt
460 dataOut.nCohInt *= self.nCohInt
459 dataOut.nCohInt *= self.n
461 460 dataOut.utctime = avgdatatime
461 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
462 462 dataOut.flagNoData = False
463 463
464 464
465 465 class SpectraProc(ProcessingUnit):
466 466
467 467 def __init__(self):
468 468
469 469 self.objectDict = {}
470 470 self.buffer = None
471 471 self.firstdatatime = None
472 472 self.profIndex = 0
473 473 self.dataOut = Spectra()
474 474
475 475 def __updateObjFromInput(self):
476 476
477 477 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
478 478 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
479 479 self.dataOut.channelList = self.dataIn.channelList
480 480 self.dataOut.heightList = self.dataIn.heightList
481 481 self.dataOut.dtype = self.dataIn.dtype
482 482 self.dataOut.nHeights = self.dataIn.nHeights
483 483 # self.dataOut.nChannels = self.dataIn.nChannels
484 484 self.dataOut.nBaud = self.dataIn.nBaud
485 485 self.dataOut.nCode = self.dataIn.nCode
486 486 self.dataOut.code = self.dataIn.code
487 487 self.dataOut.nProfiles = self.dataOut.nFFTPoints
488 488 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
489 489 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
490 490 self.dataOut.utctime = self.firstdatatime
491 491 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
492 492 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
493 493 self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
494 494 self.dataOut.nCohInt = self.dataIn.nCohInt
495 495 self.dataOut.nIncohInt = 1
496 496 self.dataOut.ippSeconds = self.dataIn.ippSeconds
497 497 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nFFTPoints
498 498
499 499 def __getFft(self):
500 500 """
501 501 Convierte valores de Voltaje a Spectra
502 502
503 503 Affected:
504 504 self.dataOut.data_spc
505 505 self.dataOut.data_cspc
506 506 self.dataOut.data_dc
507 507 self.dataOut.heightList
508 508 self.dataOut.m_BasicHeader
509 509 self.dataOut.m_ProcessingHeader
510 510 self.dataOut.radarControllerHeaderObj
511 511 self.dataOut.systemHeaderObj
512 512 self.profIndex
513 513 self.buffer
514 514 self.dataOut.flagNoData
515 515 self.dataOut.dtype
516 516 self.dataOut.nPairs
517 517 self.dataOut.nChannels
518 518 self.dataOut.nProfiles
519 519 self.dataOut.systemHeaderObj.numChannels
520 520 self.dataOut.m_ProcessingHeader.totalSpectra
521 521 self.dataOut.m_ProcessingHeader.profilesPerBlock
522 522 self.dataOut.m_ProcessingHeader.numHeights
523 523 self.dataOut.m_ProcessingHeader.spectraComb
524 524 self.dataOut.m_ProcessingHeader.shif_fft
525 525 """
526 526 fft_volt = numpy.fft.fft(self.buffer,axis=1)
527 527 dc = fft_volt[:,0,:]
528 528
529 529 #calculo de self-spectra
530 530 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
531 531 spc = fft_volt * numpy.conjugate(fft_volt)
532 532 spc = spc.real
533 533
534 534 blocksize = 0
535 535 blocksize += dc.size
536 536 blocksize += spc.size
537 537
538 538 cspc = None
539 539 pairIndex = 0
540 540 if self.dataOut.pairsList != None:
541 541 #calculo de cross-spectra
542 542 cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
543 543 for pair in self.dataOut.pairsList:
544 544 cspc[pairIndex,:,:] = numpy.abs(fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:]))
545 545 pairIndex += 1
546 546 blocksize += cspc.size
547 547
548 548 self.dataOut.data_spc = spc
549 549 self.dataOut.data_cspc = cspc
550 550 self.dataOut.data_dc = dc
551 551 self.dataOut.blockSize = blocksize
552 552
553 553 def init(self, nFFTPoints=None, pairsList=None):
554 554
555 555 if self.dataIn.type == "Spectra":
556 556 self.dataOut.copy(self.dataIn)
557 557 return
558 558
559 559 if self.dataIn.type == "Voltage":
560 560
561 561 if nFFTPoints == None:
562 562 raise ValueError, "This SpectraProc.setup() need nFFTPoints input variable"
563 563
564 564 if pairsList == None:
565 565 nPairs = 0
566 566 else:
567 567 nPairs = len(pairsList)
568 568
569 569 self.dataOut.nFFTPoints = nFFTPoints
570 570 self.dataOut.pairsList = pairsList
571 571 self.dataOut.nPairs = nPairs
572 572
573 573 if self.buffer == None:
574 574 self.buffer = numpy.zeros((self.dataIn.nChannels,
575 575 self.dataOut.nFFTPoints,
576 576 self.dataIn.nHeights),
577 577 dtype='complex')
578 578
579 579
580 580 self.buffer[:,self.profIndex,:] = self.dataIn.data
581 581 self.profIndex += 1
582 582
583 583 if self.firstdatatime == None:
584 584 self.firstdatatime = self.dataIn.utctime
585 585
586 586 if self.profIndex == self.dataOut.nFFTPoints:
587 587 self.__updateObjFromInput()
588 588 self.__getFft()
589 589
590 590 self.dataOut.flagNoData = False
591 591
592 592 self.buffer = None
593 593 self.firstdatatime = None
594 594 self.profIndex = 0
595 595
596 596 return
597 597
598 598 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
599 599
600 600 def selectChannels(self, channelList):
601 601
602 602 channelIndexList = []
603 603
604 604 for channel in channelList:
605 605 index = self.dataOut.channelList.index(channel)
606 606 channelIndexList.append(index)
607 607
608 608 self.selectChannelsByIndex(channelIndexList)
609 609
610 610 def selectChannelsByIndex(self, channelIndexList):
611 611 """
612 612 Selecciona un bloque de datos en base a canales segun el channelIndexList
613 613
614 614 Input:
615 615 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
616 616
617 617 Affected:
618 self.dataOut.data
618 self.dataOut.data_spc
619 619 self.dataOut.channelIndexList
620 620 self.dataOut.nChannels
621 self.dataOut.m_ProcessingHeader.totalSpectra
622 self.dataOut.systemHeaderObj.numChannels
623 self.dataOut.m_ProcessingHeader.blockSize
624 621
625 622 Return:
626 623 None
627 624 """
628 625
629 626 for channelIndex in channelIndexList:
630 627 if channelIndex not in self.dataOut.channelIndexList:
631 628 print channelIndexList
632 629 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
633 630
634 631 nChannels = len(channelIndexList)
635 632
636 data = self.dataOut.data_spc[channelIndexList,:]
633 data_spc = self.dataOut.data_spc[channelIndexList,:]
637 634
638 self.dataOut.data = data
635 self.dataOut.data_spc = data_spc
639 636 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
640 637 # self.dataOut.nChannels = nChannels
641 638
642 639 return 1
643 640
644 641
645 642 class IncohInt(Operation):
646 643
647 def __init__(self):
648 pass No newline at end of file
644
645 __profIndex = 0
646 __withOverapping = False
647
648 __byTime = False
649 __initime = None
650 __lastdatatime = None
651 __integrationtime = None
652
653 __buffer = None
654
655 __dataReady = False
656
657 n = None
658
659
660 def __init__(self):
661
662 self.__isConfig = False
663
664 def setup(self, n=None, timeInterval=None, overlapping=False):
665 """
666 Set the parameters of the integration class.
667
668 Inputs:
669
670 n : Number of coherent integrations
671 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
672 overlapping :
673
674 """
675
676 self.__initime = None
677 self.__lastdatatime = 0
678 self.__buffer = None
679 self.__dataReady = False
680
681
682 if n == None and timeInterval == None:
683 raise ValueError, "n or timeInterval should be specified ..."
684
685 if n != None:
686 self.n = n
687 self.__byTime = False
688 else:
689 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
690 self.n = 9999
691 self.__byTime = True
692
693 if overlapping:
694 self.__withOverapping = True
695 self.__buffer = None
696 else:
697 self.__withOverapping = False
698 self.__buffer = 0
699
700 self.__profIndex = 0
701
702 def putData(self, data):
703
704 """
705 Add a profile to the __buffer and increase in one the __profileIndex
706
707 """
708
709 if not self.__withOverapping:
710 self.__buffer += data.copy()
711 self.__profIndex += 1
712 return
713
714 #Overlapping data
715 nChannels, nFFTPoints, nHeis = data.shape
716 data = numpy.reshape(data, (1, nChannels, nFFTPoints, nHeis))
717
718 #If the buffer is empty then it takes the data value
719 if self.__buffer == None:
720 self.__buffer = data
721 self.__profIndex += 1
722 return
723
724 #If the buffer length is lower than n then stakcing the data value
725 if self.__profIndex < self.n:
726 self.__buffer = numpy.vstack((self.__buffer, data))
727 self.__profIndex += 1
728 return
729
730 #If the buffer length is equal to n then replacing the last buffer value with the data value
731 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
732 self.__buffer[self.n-1] = data
733 self.__profIndex = self.n
734 return
735
736
737 def pushData(self):
738 """
739 Return the sum of the last profiles and the profiles used in the sum.
740
741 Affected:
742
743 self.__profileIndex
744
745 """
746
747 if not self.__withOverapping:
748 data = self.__buffer
749 n = self.__profIndex
750
751 self.__buffer = 0
752 self.__profIndex = 0
753
754 return data, n
755
756 #Integration with Overlapping
757 data = numpy.sum(self.__buffer, axis=0)
758 n = self.__profIndex
759
760 return data, n
761
762 def byProfiles(self, data):
763
764 self.__dataReady = False
765 avgdata = None
766 n = None
767
768 self.putData(data)
769
770 if self.__profIndex == self.n:
771
772 avgdata, n = self.pushData()
773 self.__dataReady = True
774
775 return avgdata
776
777 def byTime(self, data, datatime):
778
779 self.__dataReady = False
780 avgdata = None
781 n = None
782
783 self.putData(data)
784
785 if (datatime - self.__initime) >= self.__integrationtime:
786 avgdata, n = self.pushData()
787 self.n = n
788 self.__dataReady = True
789
790 return avgdata
791
792 def integrate(self, data, datatime=None):
793
794 if self.__initime == None:
795 self.__initime = datatime
796
797 if self.__byTime:
798 avgdata = self.byTime(data, datatime)
799 else:
800 avgdata = self.byProfiles(data)
801
802
803 self.__lastdatatime = datatime
804
805 if avgdata == None:
806 return None, None
807
808 avgdatatime = self.__initime
809
810 deltatime = datatime -self.__lastdatatime
811
812 if not self.__withOverapping:
813 self.__initime = datatime
814 else:
815 self.__initime += deltatime
816
817 return avgdata, avgdatatime
818
819 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
820
821 if not self.__isConfig:
822 self.setup(n, timeInterval, overlapping)
823 self.__isConfig = True
824
825 avgdata, avgdatatime = self.integrate(dataOut.data_spc, dataOut.utctime)
826
827 # dataOut.timeInterval *= n
828 dataOut.flagNoData = True
829
830 if self.__dataReady:
831 dataOut.data_spc = avgdata
832 dataOut.nIncohInt *= self.n
833 dataOut.utctime = avgdatatime
834 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt * dataOut.nIncohInt
835 dataOut.flagNoData = False
836 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now