##// END OF EJS Templates
Se agrega a JROData el flag realtime, para este caso se da prioridad al procesamiento de datos. Los graficos se generan solo cuando el tiempo de procesamiento es cercano al tiempo de adquisición.
Daniel Valdez -
r360:31a78476b797
parent child
Show More
@@ -1,624 +1,626
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 import datetime
11 11
12 12 from jroheaderIO import SystemHeader, RadarControllerHeader
13 13
14 14 def hildebrand_sekhon(data, navg):
15 15 """
16 16 This method is for the objective determination of de noise level in Doppler spectra. This
17 17 implementation technique is based on the fact that the standard deviation of the spectral
18 18 densities is equal to the mean spectral density for white Gaussian noise
19 19
20 20 Inputs:
21 21 Data : heights
22 22 navg : numbers of averages
23 23
24 24 Return:
25 25 -1 : any error
26 26 anoise : noise's level
27 27 """
28 28
29 29 dataflat = data.copy().reshape(-1)
30 30 dataflat.sort()
31 31 npts = dataflat.size #numbers of points of the data
32 32 npts_noise = 0.2*npts
33 33
34 34 if npts < 32:
35 35 print "error in noise - requires at least 32 points"
36 36 return -1.0
37 37
38 38 dataflat2 = numpy.power(dataflat,2)
39 39
40 40 cs = numpy.cumsum(dataflat)
41 41 cs2 = numpy.cumsum(dataflat2)
42 42
43 43 # data sorted in ascending order
44 44 nmin = int((npts + 7.)/8)
45 45
46 46 for i in range(nmin, npts):
47 47 s = cs[i]
48 48 s2 = cs2[i]
49 49 p = s / float(i);
50 50 p2 = p**2;
51 51 q = s2 / float(i) - p2;
52 52 leftc = p2;
53 53 rightc = q * float(navg);
54 54 R2 = leftc/rightc
55 55
56 56 # Signal detect: R2 < 1 (R2 = leftc/rightc)
57 57 if R2 < 1:
58 58 npts_noise = i
59 59 break
60 60
61 61
62 62 anoise = numpy.average(dataflat[0:npts_noise])
63 63
64 64 return anoise;
65 65
66 66 def sorting_bruce(data, navg):
67 67
68 68 data = data.copy()
69 69
70 70 sortdata = numpy.sort(data)
71 71 lenOfData = len(data)
72 72 nums_min = lenOfData/10
73 73
74 74 if (lenOfData/10) > 0:
75 75 nums_min = lenOfData/10
76 76 else:
77 77 nums_min = 0
78 78
79 79 rtest = 1.0 + 1.0/navg
80 80
81 81 sum = 0.
82 82
83 83 sumq = 0.
84 84
85 85 j = 0
86 86
87 87 cont = 1
88 88
89 89 while((cont==1)and(j<lenOfData)):
90 90
91 91 sum += sortdata[j]
92 92
93 93 sumq += sortdata[j]**2
94 94
95 95 j += 1
96 96
97 97 if j > nums_min:
98 98 if ((sumq*j) <= (rtest*sum**2)):
99 99 lnoise = sum / j
100 100 else:
101 101 j = j - 1
102 102 sum = sum - sordata[j]
103 103 sumq = sumq - sordata[j]**2
104 104 cont = 0
105 105
106 106 if j == nums_min:
107 107 lnoise = sum /j
108 108
109 109 return lnoise
110 110
111 111 class JROData:
112 112
113 113 # m_BasicHeader = BasicHeader()
114 114 # m_ProcessingHeader = ProcessingHeader()
115 115
116 116 systemHeaderObj = SystemHeader()
117 117
118 118 radarControllerHeaderObj = RadarControllerHeader()
119 119
120 120 # data = None
121 121
122 122 type = None
123 123
124 124 dtype = None
125 125
126 126 # nChannels = None
127 127
128 128 # nHeights = None
129 129
130 130 nProfiles = None
131 131
132 132 heightList = None
133 133
134 134 channelList = None
135 135
136 136 flagNoData = True
137 137
138 138 flagTimeBlock = False
139 139
140 140 useLocalTime = False
141 141
142 142 utctime = None
143 143
144 144 timeZone = None
145 145
146 146 dstFlag = None
147 147
148 148 errorCount = None
149 149
150 150 blocksize = None
151 151
152 152 nCode = None
153 153
154 154 nBaud = None
155 155
156 156 code = None
157 157
158 158 flagDecodeData = False #asumo q la data no esta decodificada
159 159
160 160 flagDeflipData = False #asumo q la data no esta sin flip
161 161
162 162 flagShiftFFT = False
163 163
164 164 ippSeconds = None
165 165
166 166 timeInterval = None
167 167
168 168 nCohInt = None
169 169
170 170 noise = None
171 171
172 172 windowOfFilter = 1
173 173
174 174 #Speed of ligth
175 175 C = 3e8
176 176
177 177 frequency = 49.92e6
178 178
179 realtime = False
180
179 181 def __init__(self):
180 182
181 183 raise ValueError, "This class has not been implemented"
182 184
183 185 def copy(self, inputObj=None):
184 186
185 187 if inputObj == None:
186 188 return copy.deepcopy(self)
187 189
188 190 for key in inputObj.__dict__.keys():
189 191 self.__dict__[key] = inputObj.__dict__[key]
190 192
191 193 def deepcopy(self):
192 194
193 195 return copy.deepcopy(self)
194 196
195 197 def isEmpty(self):
196 198
197 199 return self.flagNoData
198 200
199 201 def getNoise(self):
200 202
201 203 raise ValueError, "Not implemented"
202 204
203 205 def getNChannels(self):
204 206
205 207 return len(self.channelList)
206 208
207 209 def getChannelIndexList(self):
208 210
209 211 return range(self.nChannels)
210 212
211 213 def getNHeights(self):
212 214
213 215 return len(self.heightList)
214 216
215 217 def getHeiRange(self, extrapoints=0):
216 218
217 219 heis = self.heightList
218 220 # deltah = self.heightList[1] - self.heightList[0]
219 221 #
220 222 # heis.append(self.heightList[-1])
221 223
222 224 return heis
223 225
224 226 def getltctime(self):
225 227
226 228 if self.useLocalTime:
227 229 return self.utctime - self.timeZone*60
228 230
229 231 return self.utctime
230 232
231 233 def getDatatime(self):
232 234
233 235 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
234 236 return datatime
235 237
236 238 def getTimeRange(self):
237 239
238 240 datatime = []
239 241
240 242 datatime.append(self.ltctime)
241 243 datatime.append(self.ltctime + self.timeInterval)
242 244
243 245 datatime = numpy.array(datatime)
244 246
245 247 return datatime
246 248
247 249 def getFmax(self):
248 250
249 251 PRF = 1./(self.ippSeconds * self.nCohInt)
250 252
251 253 fmax = PRF/2.
252 254
253 255 return fmax
254 256
255 257 def getVmax(self):
256 258
257 259 _lambda = self.C/self.frequency
258 260
259 261 vmax = self.getFmax() * _lambda
260 262
261 263 return vmax
262 264
263 265 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
264 266 channelIndexList = property(getChannelIndexList, "I'm the 'channelIndexList' property.")
265 267 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
266 268 noise = property(getNoise, "I'm the 'nHeights' property.")
267 269 datatime = property(getDatatime, "I'm the 'datatime' property")
268 270 ltctime = property(getltctime, "I'm the 'ltctime' property")
269 271
270 272 class Voltage(JROData):
271 273
272 274 #data es un numpy array de 2 dmensiones (canales, alturas)
273 275 data = None
274 276
275 277 def __init__(self):
276 278 '''
277 279 Constructor
278 280 '''
279 281
280 282 self.radarControllerHeaderObj = RadarControllerHeader()
281 283
282 284 self.systemHeaderObj = SystemHeader()
283 285
284 286 self.type = "Voltage"
285 287
286 288 self.data = None
287 289
288 290 self.dtype = None
289 291
290 292 # self.nChannels = 0
291 293
292 294 # self.nHeights = 0
293 295
294 296 self.nProfiles = None
295 297
296 298 self.heightList = None
297 299
298 300 self.channelList = None
299 301
300 302 # self.channelIndexList = None
301 303
302 304 self.flagNoData = True
303 305
304 306 self.flagTimeBlock = False
305 307
306 308 self.utctime = None
307 309
308 310 self.timeZone = None
309 311
310 312 self.dstFlag = None
311 313
312 314 self.errorCount = None
313 315
314 316 self.nCohInt = None
315 317
316 318 self.blocksize = None
317 319
318 320 self.flagDecodeData = False #asumo q la data no esta decodificada
319 321
320 322 self.flagDeflipData = False #asumo q la data no esta sin flip
321 323
322 324 self.flagShiftFFT = False
323 325
324 326
325 327 def getNoisebyHildebrand(self):
326 328 """
327 329 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
328 330
329 331 Return:
330 332 noiselevel
331 333 """
332 334
333 335 for channel in range(self.nChannels):
334 336 daux = self.data_spc[channel,:,:]
335 337 self.noise[channel] = hildebrand_sekhon(daux, self.nCohInt)
336 338
337 339 return self.noise
338 340
339 341 def getNoise(self, type = 1):
340 342
341 343 self.noise = numpy.zeros(self.nChannels)
342 344
343 345 if type == 1:
344 346 noise = self.getNoisebyHildebrand()
345 347
346 348 return 10*numpy.log10(noise)
347 349
348 350 class Spectra(JROData):
349 351
350 352 #data es un numpy array de 2 dmensiones (canales, perfiles, alturas)
351 353 data_spc = None
352 354
353 355 #data es un numpy array de 2 dmensiones (canales, pares, alturas)
354 356 data_cspc = None
355 357
356 358 #data es un numpy array de 2 dmensiones (canales, alturas)
357 359 data_dc = None
358 360
359 361 nFFTPoints = None
360 362
361 363 nPairs = None
362 364
363 365 pairsList = None
364 366
365 367 nIncohInt = None
366 368
367 369 wavelength = None #Necesario para cacular el rango de velocidad desde la frecuencia
368 370
369 371 nCohInt = None #se requiere para determinar el valor de timeInterval
370 372
371 373 def __init__(self):
372 374 '''
373 375 Constructor
374 376 '''
375 377
376 378 self.radarControllerHeaderObj = RadarControllerHeader()
377 379
378 380 self.systemHeaderObj = SystemHeader()
379 381
380 382 self.type = "Spectra"
381 383
382 384 # self.data = None
383 385
384 386 self.dtype = None
385 387
386 388 # self.nChannels = 0
387 389
388 390 # self.nHeights = 0
389 391
390 392 self.nProfiles = None
391 393
392 394 self.heightList = None
393 395
394 396 self.channelList = None
395 397
396 398 # self.channelIndexList = None
397 399
398 400 self.flagNoData = True
399 401
400 402 self.flagTimeBlock = False
401 403
402 404 self.utctime = None
403 405
404 406 self.nCohInt = None
405 407
406 408 self.nIncohInt = None
407 409
408 410 self.blocksize = None
409 411
410 412 self.nFFTPoints = None
411 413
412 414 self.wavelength = None
413 415
414 416 self.flagDecodeData = False #asumo q la data no esta decodificada
415 417
416 418 self.flagDeflipData = False #asumo q la data no esta sin flip
417 419
418 420 self.flagShiftFFT = False
419 421
420 422 def getNoisebyHildebrand(self):
421 423 """
422 424 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
423 425
424 426 Return:
425 427 noiselevel
426 428 """
427 429
428 430 for channel in range(self.nChannels):
429 431 daux = self.data_spc[channel,:,:]
430 432 self.noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
431 433
432 434 return self.noise
433 435
434 436 def getNoisebyWindow(self, heiIndexMin=0, heiIndexMax=-1, freqIndexMin=0, freqIndexMax=-1):
435 437 """
436 438 Determina el ruido del canal utilizando la ventana indicada con las coordenadas:
437 439 (heiIndexMIn, freqIndexMin) hasta (heiIndexMax, freqIndexMAx)
438 440
439 441 Inputs:
440 442 heiIndexMin: Limite inferior del eje de alturas
441 443 heiIndexMax: Limite superior del eje de alturas
442 444 freqIndexMin: Limite inferior del eje de frecuencia
443 445 freqIndexMax: Limite supoerior del eje de frecuencia
444 446 """
445 447
446 448 data = self.data_spc[:, heiIndexMin:heiIndexMax, freqIndexMin:freqIndexMax]
447 449
448 450 for channel in range(self.nChannels):
449 451 daux = data[channel,:,:]
450 452 self.noise[channel] = numpy.average(daux)
451 453
452 454 return self.noise
453 455
454 456 def getNoisebySort(self):
455 457
456 458 for channel in range(self.nChannels):
457 459 daux = self.data_spc[channel,:,:]
458 460 self.noise[channel] = sorting_bruce(daux, self.nIncohInt)
459 461
460 462 return self.noise
461 463
462 464 def getNoise(self, type = 1):
463 465
464 466 self.noise = numpy.zeros(self.nChannels)
465 467
466 468 if type == 1:
467 469 noise = self.getNoisebyHildebrand()
468 470
469 471 if type == 2:
470 472 noise = self.getNoisebySort()
471 473
472 474 if type == 3:
473 475 noise = self.getNoisebyWindow()
474 476
475 477 return noise
476 478
477 479
478 480 def getFreqRange(self, extrapoints=0):
479 481
480 482 deltafreq = self.getFmax() / self.nFFTPoints
481 483 freqrange = deltafreq*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2
482 484
483 485 return freqrange
484 486
485 487 def getVelRange(self, extrapoints=0):
486 488
487 489 deltav = self.getVmax() / self.nFFTPoints
488 490 velrange = deltav*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltav/2
489 491
490 492 return velrange
491 493
492 494 def getNPairs(self):
493 495
494 496 return len(self.pairsList)
495 497
496 498 def getPairsIndexList(self):
497 499
498 500 return range(self.nPairs)
499 501
500 502 def getNormFactor(self):
501 503 pwcode = 1
502 504 if self.flagDecodeData:
503 505 pwcode = numpy.sum(self.code[0]**2)
504 506 normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode
505 507
506 508 return normFactor
507 509
508 510 def getFlagCspc(self):
509 511
510 512 if self.data_cspc == None:
511 513 return True
512 514
513 515 return False
514 516
515 517 def getFlagDc(self):
516 518
517 519 if self.data_dc == None:
518 520 return True
519 521
520 522 return False
521 523
522 524 nPairs = property(getNPairs, "I'm the 'nPairs' property.")
523 525 pairsIndexList = property(getPairsIndexList, "I'm the 'pairsIndexList' property.")
524 526 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
525 527 flag_cspc = property(getFlagCspc)
526 528 flag_dc = property(getFlagDc)
527 529
528 530 class SpectraHeis(JROData):
529 531
530 532 data_spc = None
531 533
532 534 data_cspc = None
533 535
534 536 data_dc = None
535 537
536 538 nFFTPoints = None
537 539
538 540 nPairs = None
539 541
540 542 pairsList = None
541 543
542 544 nIncohInt = None
543 545
544 546 def __init__(self):
545 547
546 548 self.radarControllerHeaderObj = RadarControllerHeader()
547 549
548 550 self.systemHeaderObj = SystemHeader()
549 551
550 552 self.type = "SpectraHeis"
551 553
552 554 self.dtype = None
553 555
554 556 # self.nChannels = 0
555 557
556 558 # self.nHeights = 0
557 559
558 560 self.nProfiles = None
559 561
560 562 self.heightList = None
561 563
562 564 self.channelList = None
563 565
564 566 # self.channelIndexList = None
565 567
566 568 self.flagNoData = True
567 569
568 570 self.flagTimeBlock = False
569 571
570 572 self.nPairs = 0
571 573
572 574 self.utctime = None
573 575
574 576 self.blocksize = None
575 577
576 578 class Fits:
577 579
578 580 def __init__(self):
579 581 self.useLocalTime = False
580 582 self.utctime = None
581 583 self.timeZone = None
582 584 self.ltctime = None
583 585 self.timeInterval = None
584 586 self.header = None
585 587 self.data_header = None
586 588 self.data = None
587 589 self.datatime = None
588 590 self.flagNoData = False
589 591 self.expName = ''
590 592 self.nChannels = None
591 593 self.nSamples = None
592 594 self.dataBlocksPerFile = None
593 595 self.comments = ''
594 596
595 597
596 598 def getltctime(self):
597 599
598 600 if self.useLocalTime:
599 601 return self.utctime - self.timeZone*60
600 602
601 603 return self.utctime
602 604
603 605 def getDatatime(self):
604 606
605 607 datatime = datetime.datetime.utcfromtimestamp(self.ltctime)
606 608 return datatime
607 609
608 610 def getTimeRange(self):
609 611
610 612 datatime = []
611 613
612 614 datatime.append(self.ltctime)
613 615 datatime.append(self.ltctime + self.timeInterval)
614 616
615 617 datatime = numpy.array(datatime)
616 618
617 619 return datatime
618 620
619 621 def isEmpty(self):
620 622
621 623 return self.flagNoData
622 624
623 625 datatime = property(getDatatime, "I'm the 'datatime' property")
624 626 ltctime = property(getltctime, "I'm the 'ltctime' property") No newline at end of file
@@ -1,3313 +1,3317
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 from xml.etree.ElementTree import Element, SubElement, ElementTree
14 14 try:
15 15 import pyfits
16 16 except:
17 17 print "pyfits module has not been imported, it should be installed to save files in fits format"
18 18
19 19 from jrodata import *
20 20 from jroheaderIO import *
21 21 from jroprocessing import *
22 22
23 23 LOCALTIME = True #-18000
24 24
25 25 def isNumber(str):
26 26 """
27 27 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
28 28
29 29 Excepciones:
30 30 Si un determinado string no puede ser convertido a numero
31 31 Input:
32 32 str, string al cual se le analiza para determinar si convertible a un numero o no
33 33
34 34 Return:
35 35 True : si el string es uno numerico
36 36 False : no es un string numerico
37 37 """
38 38 try:
39 39 float( str )
40 40 return True
41 41 except:
42 42 return False
43 43
44 44 def isThisFileinRange(filename, startUTSeconds, endUTSeconds):
45 45 """
46 46 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
47 47
48 48 Inputs:
49 49 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
50 50
51 51 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
52 52 segundos contados desde 01/01/1970.
53 53 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
54 54 segundos contados desde 01/01/1970.
55 55
56 56 Return:
57 57 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
58 58 fecha especificado, de lo contrario retorna False.
59 59
60 60 Excepciones:
61 61 Si el archivo no existe o no puede ser abierto
62 62 Si la cabecera no puede ser leida.
63 63
64 64 """
65 65 basicHeaderObj = BasicHeader(LOCALTIME)
66 66
67 67 try:
68 68 fp = open(filename,'rb')
69 69 except:
70 70 raise IOError, "The file %s can't be opened" %(filename)
71 71
72 72 sts = basicHeaderObj.read(fp)
73 73 fp.close()
74 74
75 75 if not(sts):
76 76 print "Skipping the file %s because it has not a valid header" %(filename)
77 77 return 0
78 78
79 79 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
80 80 return 0
81 81
82 82 return 1
83 83
84 84 def isFileinThisTime(filename, startTime, endTime):
85 85 """
86 86 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
87 87
88 88 Inputs:
89 89 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
90 90
91 91 startTime : tiempo inicial del rango seleccionado en formato datetime.time
92 92
93 93 endTime : tiempo final del rango seleccionado en formato datetime.time
94 94
95 95 Return:
96 96 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
97 97 fecha especificado, de lo contrario retorna False.
98 98
99 99 Excepciones:
100 100 Si el archivo no existe o no puede ser abierto
101 101 Si la cabecera no puede ser leida.
102 102
103 103 """
104 104
105 105
106 106 try:
107 107 fp = open(filename,'rb')
108 108 except:
109 109 raise IOError, "The file %s can't be opened" %(filename)
110 110
111 111 basicHeaderObj = BasicHeader(LOCALTIME)
112 112 sts = basicHeaderObj.read(fp)
113 113 fp.close()
114 114
115 115 thisDatetime = basicHeaderObj.datatime
116 116 thisTime = basicHeaderObj.datatime.time()
117 117
118 118 if not(sts):
119 119 print "Skipping the file %s because it has not a valid header" %(filename)
120 120 return None
121 121
122 122 if not ((startTime <= thisTime) and (endTime > thisTime)):
123 123 return None
124 124
125 125 return thisDatetime
126 126
127 127 def getlastFileFromPath(path, ext):
128 128 """
129 129 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
130 130 al final de la depuracion devuelve el ultimo file de la lista que quedo.
131 131
132 132 Input:
133 133 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
134 134 ext : extension de los files contenidos en una carpeta
135 135
136 136 Return:
137 137 El ultimo file de una determinada carpeta, no se considera el path.
138 138 """
139 139 validFilelist = []
140 140 fileList = os.listdir(path)
141 141
142 142 # 0 1234 567 89A BCDE
143 143 # H YYYY DDD SSS .ext
144 144
145 145 for file in fileList:
146 146 try:
147 147 year = int(file[1:5])
148 148 doy = int(file[5:8])
149 149
150 150
151 151 except:
152 152 continue
153 153
154 154 if (os.path.splitext(file)[-1].lower() != ext.lower()):
155 155 continue
156 156
157 157 validFilelist.append(file)
158 158
159 159 if validFilelist:
160 160 validFilelist = sorted( validFilelist, key=str.lower )
161 161 return validFilelist[-1]
162 162
163 163 return None
164 164
165 165 def checkForRealPath(path, foldercounter, year, doy, set, ext):
166 166 """
167 167 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
168 168 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
169 169 el path exacto de un determinado file.
170 170
171 171 Example :
172 172 nombre correcto del file es .../.../D2009307/P2009307367.ext
173 173
174 174 Entonces la funcion prueba con las siguientes combinaciones
175 175 .../.../y2009307367.ext
176 176 .../.../Y2009307367.ext
177 177 .../.../x2009307/y2009307367.ext
178 178 .../.../x2009307/Y2009307367.ext
179 179 .../.../X2009307/y2009307367.ext
180 180 .../.../X2009307/Y2009307367.ext
181 181 siendo para este caso, la ultima combinacion de letras, identica al file buscado
182 182
183 183 Return:
184 184 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
185 185 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
186 186 para el filename
187 187 """
188 188 fullfilename = None
189 189 find_flag = False
190 190 filename = None
191 191
192 192 prefixDirList = [None,'d','D']
193 193 if ext.lower() == ".r": #voltage
194 194 prefixFileList = ['d','D']
195 195 elif ext.lower() == ".pdata": #spectra
196 196 prefixFileList = ['p','P']
197 197 else:
198 198 return None, filename
199 199
200 200 #barrido por las combinaciones posibles
201 201 for prefixDir in prefixDirList:
202 202 thispath = path
203 203 if prefixDir != None:
204 204 #formo el nombre del directorio xYYYYDDD (x=d o x=D)
205 205 if foldercounter == 0:
206 206 thispath = os.path.join(path, "%s%04d%03d" % ( prefixDir, year, doy ))
207 207 else:
208 208 thispath = os.path.join(path, "%s%04d%03d_%02d" % ( prefixDir, year, doy , foldercounter))
209 209 for prefixFile in prefixFileList: #barrido por las dos combinaciones posibles de "D"
210 210 filename = "%s%04d%03d%03d%s" % ( prefixFile, year, doy, set, ext ) #formo el nombre del file xYYYYDDDSSS.ext
211 211 fullfilename = os.path.join( thispath, filename ) #formo el path completo
212 212
213 213 if os.path.exists( fullfilename ): #verifico que exista
214 214 find_flag = True
215 215 break
216 216 if find_flag:
217 217 break
218 218
219 219 if not(find_flag):
220 220 return None, filename
221 221
222 222 return fullfilename, filename
223 223
224 224 def isDoyFolder(folder):
225 225 try:
226 226 year = int(folder[1:5])
227 227 except:
228 228 return 0
229 229
230 230 try:
231 231 doy = int(folder[5:8])
232 232 except:
233 233 return 0
234 234
235 235 return 1
236 236
237 237 class JRODataIO:
238 238
239 239 c = 3E8
240 240
241 241 isConfig = False
242 242
243 243 basicHeaderObj = BasicHeader(LOCALTIME)
244 244
245 245 systemHeaderObj = SystemHeader()
246 246
247 247 radarControllerHeaderObj = RadarControllerHeader()
248 248
249 249 processingHeaderObj = ProcessingHeader()
250 250
251 251 online = 0
252 252
253 253 dtype = None
254 254
255 255 pathList = []
256 256
257 257 filenameList = []
258 258
259 259 filename = None
260 260
261 261 ext = None
262 262
263 263 flagIsNewFile = 1
264 264
265 265 flagTimeBlock = 0
266 266
267 267 flagIsNewBlock = 0
268 268
269 269 fp = None
270 270
271 271 firstHeaderSize = 0
272 272
273 273 basicHeaderSize = 24
274 274
275 275 versionFile = 1103
276 276
277 277 fileSize = None
278 278
279 279 ippSeconds = None
280 280
281 281 fileSizeByHeader = None
282 282
283 283 fileIndex = None
284 284
285 285 profileIndex = None
286 286
287 287 blockIndex = None
288 288
289 289 nTotalBlocks = None
290 290
291 291 maxTimeStep = 30
292 292
293 293 lastUTTime = None
294 294
295 295 datablock = None
296 296
297 297 dataOut = None
298 298
299 299 blocksize = None
300 300
301 301 def __init__(self):
302 302
303 303 raise ValueError, "Not implemented"
304 304
305 305 def run(self):
306 306
307 307 raise ValueError, "Not implemented"
308 308
309 309 def getOutput(self):
310 310
311 311 return self.dataOut
312 312
313 313 class JRODataReader(JRODataIO, ProcessingUnit):
314 314
315 315 nReadBlocks = 0
316 316
317 317 delay = 10 #number of seconds waiting a new file
318 318
319 319 nTries = 3 #quantity tries
320 320
321 321 nFiles = 3 #number of files for searching
322 322
323 323 path = None
324 324
325 325 foldercounter = 0
326 326
327 327 flagNoMoreFiles = 0
328 328
329 329 datetimeList = []
330 330
331 331 __isFirstTimeOnline = 1
332 332
333 333 __printInfo = True
334 334
335 335 profileIndex = None
336 336
337 337 def __init__(self):
338 338
339 339 """
340 340
341 341 """
342 342
343 343 raise ValueError, "This method has not been implemented"
344 344
345 345
346 346 def createObjByDefault(self):
347 347 """
348 348
349 349 """
350 350 raise ValueError, "This method has not been implemented"
351 351
352 352 def getBlockDimension(self):
353 353
354 354 raise ValueError, "No implemented"
355 355
356 356 def __searchFilesOffLine(self,
357 357 path,
358 358 startDate,
359 359 endDate,
360 360 startTime=datetime.time(0,0,0),
361 361 endTime=datetime.time(23,59,59),
362 362 set=None,
363 363 expLabel='',
364 364 ext='.r',
365 365 walk=True):
366 366
367 367 pathList = []
368 368
369 369 if not walk:
370 370 pathList.append(path)
371 371
372 372 else:
373 373 dirList = []
374 374 for thisPath in os.listdir(path):
375 375 if not os.path.isdir(os.path.join(path,thisPath)):
376 376 continue
377 377 if not isDoyFolder(thisPath):
378 378 continue
379 379
380 380 dirList.append(thisPath)
381 381
382 382 if not(dirList):
383 383 return None, None
384 384
385 385 thisDate = startDate
386 386
387 387 while(thisDate <= endDate):
388 388 year = thisDate.timetuple().tm_year
389 389 doy = thisDate.timetuple().tm_yday
390 390
391 391 matchlist = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy) + '*')
392 392 if len(matchlist) == 0:
393 393 thisDate += datetime.timedelta(1)
394 394 continue
395 395 for match in matchlist:
396 396 pathList.append(os.path.join(path,match,expLabel))
397 397
398 398 thisDate += datetime.timedelta(1)
399 399
400 400 if pathList == []:
401 401 print "Any folder was found for the date range: %s-%s" %(startDate, endDate)
402 402 return None, None
403 403
404 404 print "%d folder(s) was(were) found for the date range: %s - %s" %(len(pathList), startDate, endDate)
405 405
406 406 filenameList = []
407 407 datetimeList = []
408 408
409 409 for i in range(len(pathList)):
410 410
411 411 thisPath = pathList[i]
412 412
413 413 fileList = glob.glob1(thisPath, "*%s" %ext)
414 414 fileList.sort()
415 415
416 416 for file in fileList:
417 417
418 418 filename = os.path.join(thisPath,file)
419 419 thisDatetime = isFileinThisTime(filename, startTime, endTime)
420 420
421 421 if not(thisDatetime):
422 422 continue
423 423
424 424 filenameList.append(filename)
425 425 datetimeList.append(thisDatetime)
426 426
427 427 if not(filenameList):
428 428 print "Any file was found for the time range %s - %s" %(startTime, endTime)
429 429 return None, None
430 430
431 431 print "%d file(s) was(were) found for the time range: %s - %s" %(len(filenameList), startTime, endTime)
432 432 print
433 433
434 434 for i in range(len(filenameList)):
435 435 print "%s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
436 436
437 437 self.filenameList = filenameList
438 438 self.datetimeList = datetimeList
439 439
440 440 return pathList, filenameList
441 441
442 442 def __searchFilesOnLine(self, path, expLabel = "", ext = None, walk=True):
443 443
444 444 """
445 445 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
446 446 devuelve el archivo encontrado ademas de otros datos.
447 447
448 448 Input:
449 449 path : carpeta donde estan contenidos los files que contiene data
450 450
451 451 expLabel : Nombre del subexperimento (subfolder)
452 452
453 453 ext : extension de los files
454 454
455 455 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
456 456
457 457 Return:
458 458 directory : eL directorio donde esta el file encontrado
459 459 filename : el ultimo file de una determinada carpeta
460 460 year : el anho
461 461 doy : el numero de dia del anho
462 462 set : el set del archivo
463 463
464 464
465 465 """
466 466 dirList = []
467 467
468 468 if not walk:
469 469 fullpath = path
470
470 foldercounter = ''
471 471 else:
472 472 #Filtra solo los directorios
473 473 for thisPath in os.listdir(path):
474 474 if not os.path.isdir(os.path.join(path,thisPath)):
475 475 continue
476 476 if not isDoyFolder(thisPath):
477 477 continue
478 478
479 479 dirList.append(thisPath)
480 480
481 481 if not(dirList):
482 return None, None, None, None, None
482 return None, None, None, None, None, None
483 483
484 484 dirList = sorted( dirList, key=str.lower )
485 485
486 486 doypath = dirList[-1]
487 487 foldercounter = int(doypath.split('_')[1]) if len(doypath.split('_'))>1 else 0
488 488 fullpath = os.path.join(path, doypath, expLabel)
489 489
490 490
491 491 print "%s folder was found: " %(fullpath )
492 492
493 493 filename = getlastFileFromPath(fullpath, ext)
494 494
495 495 if not(filename):
496 496 return None, None, None, None, None
497 497
498 498 print "%s file was found" %(filename)
499 499
500 500 if not(self.__verifyFile(os.path.join(fullpath, filename))):
501 501 return None, None, None, None, None
502 502
503 503 year = int( filename[1:5] )
504 504 doy = int( filename[5:8] )
505 505 set = int( filename[8:11] )
506 506
507 507 return fullpath, foldercounter, filename, year, doy, set
508 508
509 509 def __setNextFileOffline(self):
510 510
511 511 idFile = self.fileIndex
512 512
513 513 while (True):
514 514 idFile += 1
515 515 if not(idFile < len(self.filenameList)):
516 516 self.flagNoMoreFiles = 1
517 517 print "No more Files"
518 518 return 0
519 519
520 520 filename = self.filenameList[idFile]
521 521
522 522 if not(self.__verifyFile(filename)):
523 523 continue
524 524
525 525 fileSize = os.path.getsize(filename)
526 526 fp = open(filename,'rb')
527 527 break
528 528
529 529 self.flagIsNewFile = 1
530 530 self.fileIndex = idFile
531 531 self.filename = filename
532 532 self.fileSize = fileSize
533 533 self.fp = fp
534 534
535 535 print "Setting the file: %s"%self.filename
536 536
537 537 return 1
538 538
539 539 def __setNextFileOnline(self):
540 540 """
541 541 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
542 542 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
543 543 siguientes.
544 544
545 545 Affected:
546 546 self.flagIsNewFile
547 547 self.filename
548 548 self.fileSize
549 549 self.fp
550 550 self.set
551 551 self.flagNoMoreFiles
552 552
553 553 Return:
554 554 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
555 555 1 : si el file fue abierto con exito y esta listo a ser leido
556 556
557 557 Excepciones:
558 558 Si un determinado file no puede ser abierto
559 559 """
560 560 nFiles = 0
561 561 fileOk_flag = False
562 562 firstTime_flag = True
563 563
564 564 self.set += 1
565 565
566 566 if self.set > 999:
567 567 self.set = 0
568 568 self.foldercounter += 1
569 569
570 570 #busca el 1er file disponible
571 571 fullfilename, filename = checkForRealPath( self.path, self.foldercounter, self.year, self.doy, self.set, self.ext )
572 572 if fullfilename:
573 573 if self.__verifyFile(fullfilename, False):
574 574 fileOk_flag = True
575 575
576 576 #si no encuentra un file entonces espera y vuelve a buscar
577 577 if not(fileOk_flag):
578 578 for nFiles in range(self.nFiles+1): #busco en los siguientes self.nFiles+1 files posibles
579 579
580 580 if firstTime_flag: #si es la 1era vez entonces hace el for self.nTries veces
581 581 tries = self.nTries
582 582 else:
583 583 tries = 1 #si no es la 1era vez entonces solo lo hace una vez
584 584
585 585 for nTries in range( tries ):
586 586 if firstTime_flag:
587 587 print "\tWaiting %0.2f sec for the file \"%s\" , try %03d ..." % ( self.delay, filename, nTries+1 )
588 588 time.sleep( self.delay )
589 589 else:
590 590 print "\tSearching next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext)
591 591
592 592 fullfilename, filename = checkForRealPath( self.path, self.foldercounter, self.year, self.doy, self.set, self.ext )
593 593 if fullfilename:
594 594 if self.__verifyFile(fullfilename):
595 595 fileOk_flag = True
596 596 break
597 597
598 598 if fileOk_flag:
599 599 break
600 600
601 601 firstTime_flag = False
602 602
603 603 print "\tSkipping the file \"%s\" due to this file doesn't exist" % filename
604 604 self.set += 1
605 605
606 606 if nFiles == (self.nFiles-1): #si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
607 607 self.set = 0
608 608 self.doy += 1
609 609 self.foldercounter = 0
610 610
611 611 if fileOk_flag:
612 612 self.fileSize = os.path.getsize( fullfilename )
613 613 self.filename = fullfilename
614 614 self.flagIsNewFile = 1
615 615 if self.fp != None: self.fp.close()
616 616 self.fp = open(fullfilename, 'rb')
617 617 self.flagNoMoreFiles = 0
618 618 print 'Setting the file: %s' % fullfilename
619 619 else:
620 620 self.fileSize = 0
621 621 self.filename = None
622 622 self.flagIsNewFile = 0
623 623 self.fp = None
624 624 self.flagNoMoreFiles = 1
625 625 print 'No more Files'
626 626
627 627 return fileOk_flag
628 628
629 629
630 630 def setNextFile(self):
631 631 if self.fp != None:
632 632 self.fp.close()
633 633
634 634 if self.online:
635 635 newFile = self.__setNextFileOnline()
636 636 else:
637 637 newFile = self.__setNextFileOffline()
638 638
639 639 if not(newFile):
640 640 return 0
641 641
642 642 self.__readFirstHeader()
643 643 self.nReadBlocks = 0
644 644 return 1
645 645
646 646 def __waitNewBlock(self):
647 647 """
648 648 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
649 649
650 650 Si el modo de lectura es OffLine siempre retorn 0
651 651 """
652 652 if not self.online:
653 653 return 0
654 654
655 655 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
656 656 return 0
657 657
658 658 currentPointer = self.fp.tell()
659 659
660 660 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
661 661
662 662 for nTries in range( self.nTries ):
663 663
664 664 self.fp.close()
665 665 self.fp = open( self.filename, 'rb' )
666 666 self.fp.seek( currentPointer )
667 667
668 668 self.fileSize = os.path.getsize( self.filename )
669 669 currentSize = self.fileSize - currentPointer
670 670
671 671 if ( currentSize >= neededSize ):
672 672 self.__rdBasicHeader()
673 673 return 1
674 674
675 675 print "\tWaiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1)
676 676 time.sleep( self.delay )
677 677
678 678
679 679 return 0
680 680
681 681 def __jumpToLastBlock(self):
682 682
683 683 if not(self.__isFirstTimeOnline):
684 684 return
685 685
686 686 csize = self.fileSize - self.fp.tell()
687 687
688 688 #sata el primer bloque de datos
689 689 if csize > self.processingHeaderObj.blockSize:
690 690 self.fp.seek(self.fp.tell() + self.processingHeaderObj.blockSize)
691 691 else:
692 692 return
693 693
694 694 csize = self.fileSize - self.fp.tell()
695 695 neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
696 696 factor = int(csize/neededsize)
697 697 if factor > 0:
698 698 self.fp.seek(self.fp.tell() + factor*neededsize)
699 699
700 700 self.flagIsNewFile = 0
701 701 self.__isFirstTimeOnline = 0
702 702
703 703
704 704 def __setNewBlock(self):
705 705
706 706 if self.fp == None:
707 707 return 0
708 708
709 709 if self.online:
710 710 self.__jumpToLastBlock()
711 711
712 712 if self.flagIsNewFile:
713 713 return 1
714 714
715 715 self.lastUTTime = self.basicHeaderObj.utc
716 716 currentSize = self.fileSize - self.fp.tell()
717 717 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
718 718
719 719 if (currentSize >= neededSize):
720 720 self.__rdBasicHeader()
721 721 return 1
722 722
723 723 if self.__waitNewBlock():
724 724 return 1
725 725
726 726 if not(self.setNextFile()):
727 727 return 0
728 728
729 729 deltaTime = self.basicHeaderObj.utc - self.lastUTTime #
730 730
731 731 self.flagTimeBlock = 0
732 732
733 733 if deltaTime > self.maxTimeStep:
734 734 self.flagTimeBlock = 1
735 735
736 736 return 1
737 737
738 738
739 739 def readNextBlock(self):
740 740 if not(self.__setNewBlock()):
741 741 return 0
742 742
743 743 if not(self.readBlock()):
744 744 return 0
745 745
746 746 return 1
747 747
748 748 def __rdProcessingHeader(self, fp=None):
749 749 if fp == None:
750 750 fp = self.fp
751 751
752 752 self.processingHeaderObj.read(fp)
753 753
754 754 def __rdRadarControllerHeader(self, fp=None):
755 755 if fp == None:
756 756 fp = self.fp
757 757
758 758 self.radarControllerHeaderObj.read(fp)
759 759
760 760 def __rdSystemHeader(self, fp=None):
761 761 if fp == None:
762 762 fp = self.fp
763 763
764 764 self.systemHeaderObj.read(fp)
765 765
766 766 def __rdBasicHeader(self, fp=None):
767 767 if fp == None:
768 768 fp = self.fp
769 769
770 770 self.basicHeaderObj.read(fp)
771 771
772 772
773 773 def __readFirstHeader(self):
774 774 self.__rdBasicHeader()
775 775 self.__rdSystemHeader()
776 776 self.__rdRadarControllerHeader()
777 777 self.__rdProcessingHeader()
778 778
779 779 self.firstHeaderSize = self.basicHeaderObj.size
780 780
781 781 datatype = int(numpy.log2((self.processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
782 782 if datatype == 0:
783 783 datatype_str = numpy.dtype([('real','<i1'),('imag','<i1')])
784 784 elif datatype == 1:
785 785 datatype_str = numpy.dtype([('real','<i2'),('imag','<i2')])
786 786 elif datatype == 2:
787 787 datatype_str = numpy.dtype([('real','<i4'),('imag','<i4')])
788 788 elif datatype == 3:
789 789 datatype_str = numpy.dtype([('real','<i8'),('imag','<i8')])
790 790 elif datatype == 4:
791 791 datatype_str = numpy.dtype([('real','<f4'),('imag','<f4')])
792 792 elif datatype == 5:
793 793 datatype_str = numpy.dtype([('real','<f8'),('imag','<f8')])
794 794 else:
795 795 raise ValueError, 'Data type was not defined'
796 796
797 797 self.dtype = datatype_str
798 798 self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
799 799 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + self.firstHeaderSize + self.basicHeaderSize*(self.processingHeaderObj.dataBlocksPerFile - 1)
800 800 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
801 801 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
802 802 self.getBlockDimension()
803 803
804 804
805 805 def __verifyFile(self, filename, msgFlag=True):
806 806 msg = None
807 807 try:
808 808 fp = open(filename, 'rb')
809 809 currentPosition = fp.tell()
810 810 except:
811 811 if msgFlag:
812 812 print "The file %s can't be opened" % (filename)
813 813 return False
814 814
815 815 neededSize = self.processingHeaderObj.blockSize + self.firstHeaderSize
816 816
817 817 if neededSize == 0:
818 818 basicHeaderObj = BasicHeader(LOCALTIME)
819 819 systemHeaderObj = SystemHeader()
820 820 radarControllerHeaderObj = RadarControllerHeader()
821 821 processingHeaderObj = ProcessingHeader()
822 822
823 823 try:
824 824 if not( basicHeaderObj.read(fp) ): raise IOError
825 825 if not( systemHeaderObj.read(fp) ): raise IOError
826 826 if not( radarControllerHeaderObj.read(fp) ): raise IOError
827 827 if not( processingHeaderObj.read(fp) ): raise IOError
828 828 data_type = int(numpy.log2((processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
829 829
830 830 neededSize = processingHeaderObj.blockSize + basicHeaderObj.size
831 831
832 832 except:
833 833 if msgFlag:
834 834 print "\tThe file %s is empty or it hasn't enough data" % filename
835 835
836 836 fp.close()
837 837 return False
838 838 else:
839 839 msg = "\tSkipping the file %s due to it hasn't enough data" %filename
840 840
841 841 fp.close()
842 842 fileSize = os.path.getsize(filename)
843 843 currentSize = fileSize - currentPosition
844 844 if currentSize < neededSize:
845 845 if msgFlag and (msg != None):
846 846 print msg #print"\tSkipping the file %s due to it hasn't enough data" %filename
847 847 return False
848 848
849 849 return True
850 850
851 851 def setup(self,
852 852 path=None,
853 853 startDate=None,
854 854 endDate=None,
855 855 startTime=datetime.time(0,0,0),
856 856 endTime=datetime.time(23,59,59),
857 857 set=0,
858 858 expLabel = "",
859 859 ext = None,
860 860 online = False,
861 861 delay = 60,
862 862 walk = True):
863 863
864 864 if path == None:
865 865 raise ValueError, "The path is not valid"
866 866
867 867 if ext == None:
868 868 ext = self.ext
869 869
870 870 if online:
871 871 print "Searching files in online mode..."
872 872
873 873 for nTries in range( self.nTries ):
874 874 fullpath, foldercounter, file, year, doy, set = self.__searchFilesOnLine(path=path, expLabel=expLabel, ext=ext, walk=walk)
875 875
876 876 if fullpath:
877 877 break
878 878
879 879 print '\tWaiting %0.2f sec for an valid file in %s: try %02d ...' % (self.delay, path, nTries+1)
880 880 time.sleep( self.delay )
881 881
882 882 if not(fullpath):
883 883 print "There 'isn't valied files in %s" % path
884 884 return None
885 885
886 886 self.year = year
887 887 self.doy = doy
888 888 self.set = set - 1
889 889 self.path = path
890 890 self.foldercounter = foldercounter
891 891
892 892 else:
893 893 print "Searching files in offline mode ..."
894 894 pathList, filenameList = self.__searchFilesOffLine(path, startDate=startDate, endDate=endDate,
895 895 startTime=startTime, endTime=endTime,
896 896 set=set, expLabel=expLabel, ext=ext,
897 897 walk=walk)
898 898
899 899 if not(pathList):
900 900 print "No *%s files into the folder %s \nfor the range: %s - %s"%(ext, path,
901 901 datetime.datetime.combine(startDate,startTime).ctime(),
902 902 datetime.datetime.combine(endDate,endTime).ctime())
903 903
904 904 sys.exit(-1)
905 905
906 906
907 907 self.fileIndex = -1
908 908 self.pathList = pathList
909 909 self.filenameList = filenameList
910 910
911 911 self.online = online
912 912 self.delay = delay
913 913 ext = ext.lower()
914 914 self.ext = ext
915 915
916 916 if not(self.setNextFile()):
917 917 if (startDate!=None) and (endDate!=None):
918 918 print "No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
919 919 elif startDate != None:
920 920 print "No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime())
921 921 else:
922 922 print "No files"
923 923
924 924 sys.exit(-1)
925 925
926 926 # self.updateDataHeader()
927 927
928 928 return self.dataOut
929 929
930 930 def getBasicHeader(self):
931 931
932 932 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond/1000. + self.profileIndex * self.ippSeconds
933 933
934 934 self.dataOut.flagTimeBlock = self.flagTimeBlock
935 935
936 936 self.dataOut.timeZone = self.basicHeaderObj.timeZone
937 937
938 938 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
939 939
940 940 self.dataOut.errorCount = self.basicHeaderObj.errorCount
941 941
942 942 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
943 943
944 944 def getFirstHeader(self):
945 945
946 946 raise ValueError, "This method has not been implemented"
947 947
948 948 def getData():
949 949
950 950 raise ValueError, "This method has not been implemented"
951 951
952 952 def hasNotDataInBuffer():
953 953
954 954 raise ValueError, "This method has not been implemented"
955 955
956 956 def readBlock():
957 957
958 958 raise ValueError, "This method has not been implemented"
959 959
960 960 def isEndProcess(self):
961 961
962 962 return self.flagNoMoreFiles
963 963
964 964 def printReadBlocks(self):
965 965
966 966 print "Number of read blocks per file %04d" %self.nReadBlocks
967 967
968 968 def printTotalBlocks(self):
969 969
970 970 print "Number of read blocks %04d" %self.nTotalBlocks
971 971
972 972 def printNumberOfBlock(self):
973 973
974 974 if self.flagIsNewBlock:
975 975 print "Block No. %04d, Total blocks %04d -> %s" %(self.basicHeaderObj.dataBlock, self.nTotalBlocks, self.dataOut.datatime.ctime())
976 976
977 977 def printInfo(self):
978 978
979 979 if self.__printInfo == False:
980 980 return
981 981
982 982 self.basicHeaderObj.printInfo()
983 983 self.systemHeaderObj.printInfo()
984 984 self.radarControllerHeaderObj.printInfo()
985 985 self.processingHeaderObj.printInfo()
986 986
987 987 self.__printInfo = False
988 988
989 989
990 990 def run(self, **kwargs):
991 991
992 992 if not(self.isConfig):
993 993
994 994 # self.dataOut = dataOut
995 995 self.setup(**kwargs)
996 996 self.isConfig = True
997 997
998 998 self.getData()
999 999
1000 1000 class JRODataWriter(JRODataIO, Operation):
1001 1001
1002 1002 """
1003 1003 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1004 1004 de los datos siempre se realiza por bloques.
1005 1005 """
1006 1006
1007 1007 blockIndex = 0
1008 1008
1009 1009 path = None
1010 1010
1011 1011 setFile = None
1012 1012
1013 1013 profilesPerBlock = None
1014 1014
1015 1015 blocksPerFile = None
1016 1016
1017 1017 nWriteBlocks = 0
1018 1018
1019 1019 def __init__(self, dataOut=None):
1020 1020 raise ValueError, "Not implemented"
1021 1021
1022 1022
1023 1023 def hasAllDataInBuffer(self):
1024 1024 raise ValueError, "Not implemented"
1025 1025
1026 1026
1027 1027 def setBlockDimension(self):
1028 1028 raise ValueError, "Not implemented"
1029 1029
1030 1030
1031 1031 def writeBlock(self):
1032 1032 raise ValueError, "No implemented"
1033 1033
1034 1034
1035 1035 def putData(self):
1036 1036 raise ValueError, "No implemented"
1037 1037
1038 1038
1039 1039 def setBasicHeader(self):
1040 1040
1041 1041 self.basicHeaderObj.size = self.basicHeaderSize #bytes
1042 1042 self.basicHeaderObj.version = self.versionFile
1043 1043 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1044 1044
1045 1045 utc = numpy.floor(self.dataOut.utctime)
1046 1046 milisecond = (self.dataOut.utctime - utc)* 1000.0
1047 1047
1048 1048 self.basicHeaderObj.utc = utc
1049 1049 self.basicHeaderObj.miliSecond = milisecond
1050 1050 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1051 1051 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1052 1052 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1053 1053
1054 1054 def setFirstHeader(self):
1055 1055 """
1056 1056 Obtiene una copia del First Header
1057 1057
1058 1058 Affected:
1059 1059
1060 1060 self.basicHeaderObj
1061 1061 self.systemHeaderObj
1062 1062 self.radarControllerHeaderObj
1063 1063 self.processingHeaderObj self.
1064 1064
1065 1065 Return:
1066 1066 None
1067 1067 """
1068 1068
1069 1069 raise ValueError, "No implemented"
1070 1070
1071 1071 def __writeFirstHeader(self):
1072 1072 """
1073 1073 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1074 1074
1075 1075 Affected:
1076 1076 __dataType
1077 1077
1078 1078 Return:
1079 1079 None
1080 1080 """
1081 1081
1082 1082 # CALCULAR PARAMETROS
1083 1083
1084 1084 sizeLongHeader = self.systemHeaderObj.size + self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1085 1085 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1086 1086
1087 1087 self.basicHeaderObj.write(self.fp)
1088 1088 self.systemHeaderObj.write(self.fp)
1089 1089 self.radarControllerHeaderObj.write(self.fp)
1090 1090 self.processingHeaderObj.write(self.fp)
1091 1091
1092 1092 self.dtype = self.dataOut.dtype
1093 1093
1094 1094 def __setNewBlock(self):
1095 1095 """
1096 1096 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1097 1097
1098 1098 Return:
1099 1099 0 : si no pudo escribir nada
1100 1100 1 : Si escribio el Basic el First Header
1101 1101 """
1102 1102 if self.fp == None:
1103 1103 self.setNextFile()
1104 1104
1105 1105 if self.flagIsNewFile:
1106 1106 return 1
1107 1107
1108 1108 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1109 1109 self.basicHeaderObj.write(self.fp)
1110 1110 return 1
1111 1111
1112 1112 if not( self.setNextFile() ):
1113 1113 return 0
1114 1114
1115 1115 return 1
1116 1116
1117 1117
1118 1118 def writeNextBlock(self):
1119 1119 """
1120 1120 Selecciona el bloque siguiente de datos y los escribe en un file
1121 1121
1122 1122 Return:
1123 1123 0 : Si no hizo pudo escribir el bloque de datos
1124 1124 1 : Si no pudo escribir el bloque de datos
1125 1125 """
1126 1126 if not( self.__setNewBlock() ):
1127 1127 return 0
1128 1128
1129 1129 self.writeBlock()
1130 1130
1131 1131 return 1
1132 1132
1133 1133 def setNextFile(self):
1134 1134 """
1135 1135 Determina el siguiente file que sera escrito
1136 1136
1137 1137 Affected:
1138 1138 self.filename
1139 1139 self.subfolder
1140 1140 self.fp
1141 1141 self.setFile
1142 1142 self.flagIsNewFile
1143 1143
1144 1144 Return:
1145 1145 0 : Si el archivo no puede ser escrito
1146 1146 1 : Si el archivo esta listo para ser escrito
1147 1147 """
1148 1148 ext = self.ext
1149 1149 path = self.path
1150 1150
1151 1151 if self.fp != None:
1152 1152 self.fp.close()
1153 1153
1154 1154 timeTuple = time.localtime( self.dataOut.utctime)
1155 1155 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
1156 1156
1157 1157 fullpath = os.path.join( path, subfolder )
1158 1158 if not( os.path.exists(fullpath) ):
1159 1159 os.mkdir(fullpath)
1160 1160 self.setFile = -1 #inicializo mi contador de seteo
1161 1161 else:
1162 1162 filesList = os.listdir( fullpath )
1163 1163 if len( filesList ) > 0:
1164 1164 filesList = sorted( filesList, key=str.lower )
1165 1165 filen = filesList[-1]
1166 1166 # el filename debera tener el siguiente formato
1167 1167 # 0 1234 567 89A BCDE (hex)
1168 1168 # x YYYY DDD SSS .ext
1169 1169 if isNumber( filen[8:11] ):
1170 1170 self.setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
1171 1171 else:
1172 1172 self.setFile = -1
1173 1173 else:
1174 1174 self.setFile = -1 #inicializo mi contador de seteo
1175 1175
1176 1176 setFile = self.setFile
1177 1177 setFile += 1
1178 1178
1179 1179 file = '%s%4.4d%3.3d%3.3d%s' % (self.optchar,
1180 1180 timeTuple.tm_year,
1181 1181 timeTuple.tm_yday,
1182 1182 setFile,
1183 1183 ext )
1184 1184
1185 1185 filename = os.path.join( path, subfolder, file )
1186 1186
1187 1187 fp = open( filename,'wb' )
1188 1188
1189 1189 self.blockIndex = 0
1190 1190
1191 1191 #guardando atributos
1192 1192 self.filename = filename
1193 1193 self.subfolder = subfolder
1194 1194 self.fp = fp
1195 1195 self.setFile = setFile
1196 1196 self.flagIsNewFile = 1
1197 1197
1198 1198 self.setFirstHeader()
1199 1199
1200 1200 print 'Writing the file: %s'%self.filename
1201 1201
1202 1202 self.__writeFirstHeader()
1203 1203
1204 1204 return 1
1205 1205
1206 1206 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=None, set=0, ext=None):
1207 1207 """
1208 1208 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1209 1209
1210 1210 Inputs:
1211 1211 path : el path destino en el cual se escribiran los files a crear
1212 1212 format : formato en el cual sera salvado un file
1213 1213 set : el setebo del file
1214 1214
1215 1215 Return:
1216 1216 0 : Si no realizo un buen seteo
1217 1217 1 : Si realizo un buen seteo
1218 1218 """
1219 1219
1220 1220 if ext == None:
1221 1221 ext = self.ext
1222 1222
1223 1223 ext = ext.lower()
1224 1224
1225 1225 self.ext = ext
1226 1226
1227 1227 self.path = path
1228 1228
1229 1229 self.setFile = set - 1
1230 1230
1231 1231 self.blocksPerFile = blocksPerFile
1232 1232
1233 1233 self.profilesPerBlock = profilesPerBlock
1234 1234
1235 1235 self.dataOut = dataOut
1236 1236
1237 1237 if not(self.setNextFile()):
1238 1238 print "There isn't a next file"
1239 1239 return 0
1240 1240
1241 1241 self.setBlockDimension()
1242 1242
1243 1243 return 1
1244 1244
1245 1245 def run(self, dataOut, **kwargs):
1246 1246
1247 1247 if not(self.isConfig):
1248 1248
1249 1249 self.setup(dataOut, **kwargs)
1250 1250 self.isConfig = True
1251 1251
1252 1252 self.putData()
1253 1253
1254 1254 class VoltageReader(JRODataReader):
1255 1255 """
1256 1256 Esta clase permite leer datos de voltage desde archivos en formato rawdata (.r). La lectura
1257 1257 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones:
1258 1258 perfiles*alturas*canales) son almacenados en la variable "buffer".
1259 1259
1260 1260 perfiles * alturas * canales
1261 1261
1262 1262 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
1263 1263 RadarControllerHeader y Voltage. Los tres primeros se usan para almacenar informacion de la
1264 1264 cabecera de datos (metadata), y el cuarto (Voltage) para obtener y almacenar un perfil de
1265 1265 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
1266 1266
1267 1267 Example:
1268 1268
1269 1269 dpath = "/home/myuser/data"
1270 1270
1271 1271 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
1272 1272
1273 1273 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
1274 1274
1275 1275 readerObj = VoltageReader()
1276 1276
1277 1277 readerObj.setup(dpath, startTime, endTime)
1278 1278
1279 1279 while(True):
1280 1280
1281 1281 #to get one profile
1282 1282 profile = readerObj.getData()
1283 1283
1284 1284 #print the profile
1285 1285 print profile
1286 1286
1287 1287 #If you want to see all datablock
1288 1288 print readerObj.datablock
1289 1289
1290 1290 if readerObj.flagNoMoreFiles:
1291 1291 break
1292 1292
1293 1293 """
1294 1294
1295 1295 ext = ".r"
1296 1296
1297 1297 optchar = "D"
1298 1298 dataOut = None
1299 1299
1300 1300
1301 1301 def __init__(self):
1302 1302 """
1303 1303 Inicializador de la clase VoltageReader para la lectura de datos de voltage.
1304 1304
1305 1305 Input:
1306 1306 dataOut : Objeto de la clase Voltage. Este objeto sera utilizado para
1307 1307 almacenar un perfil de datos cada vez que se haga un requerimiento
1308 1308 (getData). El perfil sera obtenido a partir del buffer de datos,
1309 1309 si el buffer esta vacio se hara un nuevo proceso de lectura de un
1310 1310 bloque de datos.
1311 1311 Si este parametro no es pasado se creara uno internamente.
1312 1312
1313 1313 Variables afectadas:
1314 1314 self.dataOut
1315 1315
1316 1316 Return:
1317 1317 None
1318 1318 """
1319 1319
1320 1320 self.isConfig = False
1321 1321
1322 1322 self.datablock = None
1323 1323
1324 1324 self.utc = 0
1325 1325
1326 1326 self.ext = ".r"
1327 1327
1328 1328 self.optchar = "D"
1329 1329
1330 1330 self.basicHeaderObj = BasicHeader(LOCALTIME)
1331 1331
1332 1332 self.systemHeaderObj = SystemHeader()
1333 1333
1334 1334 self.radarControllerHeaderObj = RadarControllerHeader()
1335 1335
1336 1336 self.processingHeaderObj = ProcessingHeader()
1337 1337
1338 1338 self.online = 0
1339 1339
1340 1340 self.fp = None
1341 1341
1342 1342 self.idFile = None
1343 1343
1344 1344 self.dtype = None
1345 1345
1346 1346 self.fileSizeByHeader = None
1347 1347
1348 1348 self.filenameList = []
1349 1349
1350 1350 self.filename = None
1351 1351
1352 1352 self.fileSize = None
1353 1353
1354 1354 self.firstHeaderSize = 0
1355 1355
1356 1356 self.basicHeaderSize = 24
1357 1357
1358 1358 self.pathList = []
1359 1359
1360 1360 self.filenameList = []
1361 1361
1362 1362 self.lastUTTime = 0
1363 1363
1364 1364 self.maxTimeStep = 30
1365 1365
1366 1366 self.flagNoMoreFiles = 0
1367 1367
1368 1368 self.set = 0
1369 1369
1370 1370 self.path = None
1371 1371
1372 1372 self.profileIndex = 2**32-1
1373 1373
1374 1374 self.delay = 3 #seconds
1375 1375
1376 1376 self.nTries = 3 #quantity tries
1377 1377
1378 1378 self.nFiles = 3 #number of files for searching
1379 1379
1380 1380 self.nReadBlocks = 0
1381 1381
1382 1382 self.flagIsNewFile = 1
1383 1383
1384 1384 self.__isFirstTimeOnline = 1
1385 1385
1386 1386 self.ippSeconds = 0
1387 1387
1388 1388 self.flagTimeBlock = 0
1389 1389
1390 1390 self.flagIsNewBlock = 0
1391 1391
1392 1392 self.nTotalBlocks = 0
1393 1393
1394 1394 self.blocksize = 0
1395 1395
1396 1396 self.dataOut = self.createObjByDefault()
1397 1397
1398 1398 def createObjByDefault(self):
1399 1399
1400 1400 dataObj = Voltage()
1401 1401
1402 1402 return dataObj
1403 1403
1404 1404 def __hasNotDataInBuffer(self):
1405 1405 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock:
1406 1406 return 1
1407 1407 return 0
1408 1408
1409 1409
1410 1410 def getBlockDimension(self):
1411 1411 """
1412 1412 Obtiene la cantidad de puntos a leer por cada bloque de datos
1413 1413
1414 1414 Affected:
1415 1415 self.blocksize
1416 1416
1417 1417 Return:
1418 1418 None
1419 1419 """
1420 1420 pts2read = self.processingHeaderObj.profilesPerBlock * self.processingHeaderObj.nHeights * self.systemHeaderObj.nChannels
1421 1421 self.blocksize = pts2read
1422 1422
1423 1423
1424 1424 def readBlock(self):
1425 1425 """
1426 1426 readBlock lee el bloque de datos desde la posicion actual del puntero del archivo
1427 1427 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
1428 1428 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
1429 1429 es seteado a 0
1430 1430
1431 1431 Inputs:
1432 1432 None
1433 1433
1434 1434 Return:
1435 1435 None
1436 1436
1437 1437 Affected:
1438 1438 self.profileIndex
1439 1439 self.datablock
1440 1440 self.flagIsNewFile
1441 1441 self.flagIsNewBlock
1442 1442 self.nTotalBlocks
1443 1443
1444 1444 Exceptions:
1445 1445 Si un bloque leido no es un bloque valido
1446 1446 """
1447 1447
1448 1448 junk = numpy.fromfile( self.fp, self.dtype, self.blocksize )
1449 1449
1450 1450 try:
1451 1451 junk = junk.reshape( (self.processingHeaderObj.profilesPerBlock, self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels) )
1452 1452 except:
1453 1453 print "The read block (%3d) has not enough data" %self.nReadBlocks
1454 1454 return 0
1455 1455
1456 1456 junk = numpy.transpose(junk, (2,0,1))
1457 1457 self.datablock = junk['real'] + junk['imag']*1j
1458 1458
1459 1459 self.profileIndex = 0
1460 1460
1461 1461 self.flagIsNewFile = 0
1462 1462 self.flagIsNewBlock = 1
1463 1463
1464 1464 self.nTotalBlocks += 1
1465 1465 self.nReadBlocks += 1
1466 1466
1467 1467 return 1
1468 1468
1469 1469 def getFirstHeader(self):
1470 1470
1471 1471 self.dataOut.dtype = self.dtype
1472 1472
1473 1473 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
1474 1474
1475 1475 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
1476 1476
1477 1477 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
1478 1478
1479 1479 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
1480 1480
1481 1481 self.dataOut.ippSeconds = self.ippSeconds
1482 1482
1483 1483 self.dataOut.timeInterval = self.ippSeconds * self.processingHeaderObj.nCohInt
1484 1484
1485 1485 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
1486 1486
1487 1487 self.dataOut.flagShiftFFT = False
1488 1488
1489 1489 if self.radarControllerHeaderObj.code != None:
1490 1490
1491 1491 self.dataOut.nCode = self.radarControllerHeaderObj.nCode
1492 1492
1493 1493 self.dataOut.nBaud = self.radarControllerHeaderObj.nBaud
1494 1494
1495 1495 self.dataOut.code = self.radarControllerHeaderObj.code
1496 1496
1497 1497 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
1498 1498
1499 1499 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
1500 1500
1501 1501 self.dataOut.flagDecodeData = False #asumo q la data no esta decodificada
1502 1502
1503 1503 self.dataOut.flagDeflipData = False #asumo q la data no esta sin flip
1504 1504
1505 1505 self.dataOut.flagShiftFFT = False
1506 1506
1507 1507 def getData(self):
1508 1508 """
1509 1509 getData obtiene una unidad de datos del buffer de lectura y la copia a la clase "Voltage"
1510 1510 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
1511 1511 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
1512 1512
1513 1513 Ademas incrementa el contador del buffer en 1.
1514 1514
1515 1515 Return:
1516 1516 data : retorna un perfil de voltages (alturas * canales) copiados desde el
1517 1517 buffer. Si no hay mas archivos a leer retorna None.
1518 1518
1519 1519 Variables afectadas:
1520 1520 self.dataOut
1521 1521 self.profileIndex
1522 1522
1523 1523 Affected:
1524 1524 self.dataOut
1525 1525 self.profileIndex
1526 1526 self.flagTimeBlock
1527 1527 self.flagIsNewBlock
1528 1528 """
1529 1529
1530 1530 if self.flagNoMoreFiles:
1531 1531 self.dataOut.flagNoData = True
1532 1532 print 'Process finished'
1533 1533 return 0
1534 1534
1535 1535 self.flagTimeBlock = 0
1536 1536 self.flagIsNewBlock = 0
1537 1537
1538 1538 if self.__hasNotDataInBuffer():
1539 1539
1540 1540 if not( self.readNextBlock() ):
1541 1541 return 0
1542 1542
1543 1543 self.getFirstHeader()
1544 1544
1545 1545 if self.datablock == None:
1546 1546 self.dataOut.flagNoData = True
1547 1547 return 0
1548 1548
1549 1549 self.dataOut.data = self.datablock[:,self.profileIndex,:]
1550 1550
1551 1551 self.dataOut.flagNoData = False
1552 1552
1553 1553 self.getBasicHeader()
1554 1554
1555 1555 self.profileIndex += 1
1556 1556
1557 self.dataOut.realtime = self.online
1558
1557 1559 return self.dataOut.data
1558 1560
1559 1561
1560 1562 class VoltageWriter(JRODataWriter):
1561 1563 """
1562 1564 Esta clase permite escribir datos de voltajes a archivos procesados (.r). La escritura
1563 1565 de los datos siempre se realiza por bloques.
1564 1566 """
1565 1567
1566 1568 ext = ".r"
1567 1569
1568 1570 optchar = "D"
1569 1571
1570 1572 shapeBuffer = None
1571 1573
1572 1574
1573 1575 def __init__(self):
1574 1576 """
1575 1577 Inicializador de la clase VoltageWriter para la escritura de datos de espectros.
1576 1578
1577 1579 Affected:
1578 1580 self.dataOut
1579 1581
1580 1582 Return: None
1581 1583 """
1582 1584
1583 1585 self.nTotalBlocks = 0
1584 1586
1585 1587 self.profileIndex = 0
1586 1588
1587 1589 self.isConfig = False
1588 1590
1589 1591 self.fp = None
1590 1592
1591 1593 self.flagIsNewFile = 1
1592 1594
1593 1595 self.nTotalBlocks = 0
1594 1596
1595 1597 self.flagIsNewBlock = 0
1596 1598
1597 1599 self.setFile = None
1598 1600
1599 1601 self.dtype = None
1600 1602
1601 1603 self.path = None
1602 1604
1603 1605 self.filename = None
1604 1606
1605 1607 self.basicHeaderObj = BasicHeader(LOCALTIME)
1606 1608
1607 1609 self.systemHeaderObj = SystemHeader()
1608 1610
1609 1611 self.radarControllerHeaderObj = RadarControllerHeader()
1610 1612
1611 1613 self.processingHeaderObj = ProcessingHeader()
1612 1614
1613 1615 def hasAllDataInBuffer(self):
1614 1616 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock:
1615 1617 return 1
1616 1618 return 0
1617 1619
1618 1620
1619 1621 def setBlockDimension(self):
1620 1622 """
1621 1623 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
1622 1624
1623 1625 Affected:
1624 1626 self.shape_spc_Buffer
1625 1627 self.shape_cspc_Buffer
1626 1628 self.shape_dc_Buffer
1627 1629
1628 1630 Return: None
1629 1631 """
1630 1632 self.shapeBuffer = (self.processingHeaderObj.profilesPerBlock,
1631 1633 self.processingHeaderObj.nHeights,
1632 1634 self.systemHeaderObj.nChannels)
1633 1635
1634 1636 self.datablock = numpy.zeros((self.systemHeaderObj.nChannels,
1635 1637 self.processingHeaderObj.profilesPerBlock,
1636 1638 self.processingHeaderObj.nHeights),
1637 1639 dtype=numpy.dtype('complex64'))
1638 1640
1639 1641
1640 1642 def writeBlock(self):
1641 1643 """
1642 1644 Escribe el buffer en el file designado
1643 1645
1644 1646 Affected:
1645 1647 self.profileIndex
1646 1648 self.flagIsNewFile
1647 1649 self.flagIsNewBlock
1648 1650 self.nTotalBlocks
1649 1651 self.blockIndex
1650 1652
1651 1653 Return: None
1652 1654 """
1653 1655 data = numpy.zeros( self.shapeBuffer, self.dtype )
1654 1656
1655 1657 junk = numpy.transpose(self.datablock, (1,2,0))
1656 1658
1657 1659 data['real'] = junk.real
1658 1660 data['imag'] = junk.imag
1659 1661
1660 1662 data = data.reshape( (-1) )
1661 1663
1662 1664 data.tofile( self.fp )
1663 1665
1664 1666 self.datablock.fill(0)
1665 1667
1666 1668 self.profileIndex = 0
1667 1669 self.flagIsNewFile = 0
1668 1670 self.flagIsNewBlock = 1
1669 1671
1670 1672 self.blockIndex += 1
1671 1673 self.nTotalBlocks += 1
1672 1674
1673 1675 def putData(self):
1674 1676 """
1675 1677 Setea un bloque de datos y luego los escribe en un file
1676 1678
1677 1679 Affected:
1678 1680 self.flagIsNewBlock
1679 1681 self.profileIndex
1680 1682
1681 1683 Return:
1682 1684 0 : Si no hay data o no hay mas files que puedan escribirse
1683 1685 1 : Si se escribio la data de un bloque en un file
1684 1686 """
1685 1687 if self.dataOut.flagNoData:
1686 1688 return 0
1687 1689
1688 1690 self.flagIsNewBlock = 0
1689 1691
1690 1692 if self.dataOut.flagTimeBlock:
1691 1693
1692 1694 self.datablock.fill(0)
1693 1695 self.profileIndex = 0
1694 1696 self.setNextFile()
1695 1697
1696 1698 if self.profileIndex == 0:
1697 1699 self.setBasicHeader()
1698 1700
1699 1701 self.datablock[:,self.profileIndex,:] = self.dataOut.data
1700 1702
1701 1703 self.profileIndex += 1
1702 1704
1703 1705 if self.hasAllDataInBuffer():
1704 1706 #if self.flagIsNewFile:
1705 1707 self.writeNextBlock()
1706 1708 # self.setFirstHeader()
1707 1709
1708 1710 return 1
1709 1711
1710 1712 def __getProcessFlags(self):
1711 1713
1712 1714 processFlags = 0
1713 1715
1714 1716 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
1715 1717 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
1716 1718 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
1717 1719 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
1718 1720 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
1719 1721 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
1720 1722
1721 1723 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
1722 1724
1723 1725
1724 1726
1725 1727 datatypeValueList = [PROCFLAG.DATATYPE_CHAR,
1726 1728 PROCFLAG.DATATYPE_SHORT,
1727 1729 PROCFLAG.DATATYPE_LONG,
1728 1730 PROCFLAG.DATATYPE_INT64,
1729 1731 PROCFLAG.DATATYPE_FLOAT,
1730 1732 PROCFLAG.DATATYPE_DOUBLE]
1731 1733
1732 1734
1733 1735 for index in range(len(dtypeList)):
1734 1736 if self.dataOut.dtype == dtypeList[index]:
1735 1737 dtypeValue = datatypeValueList[index]
1736 1738 break
1737 1739
1738 1740 processFlags += dtypeValue
1739 1741
1740 1742 if self.dataOut.flagDecodeData:
1741 1743 processFlags += PROCFLAG.DECODE_DATA
1742 1744
1743 1745 if self.dataOut.flagDeflipData:
1744 1746 processFlags += PROCFLAG.DEFLIP_DATA
1745 1747
1746 1748 if self.dataOut.code != None:
1747 1749 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1748 1750
1749 1751 if self.dataOut.nCohInt > 1:
1750 1752 processFlags += PROCFLAG.COHERENT_INTEGRATION
1751 1753
1752 1754 return processFlags
1753 1755
1754 1756
1755 1757 def __getBlockSize(self):
1756 1758 '''
1757 1759 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Voltage
1758 1760 '''
1759 1761
1760 1762 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
1761 1763 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
1762 1764 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
1763 1765 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
1764 1766 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
1765 1767 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
1766 1768
1767 1769 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
1768 1770 datatypeValueList = [1,2,4,8,4,8]
1769 1771 for index in range(len(dtypeList)):
1770 1772 if self.dataOut.dtype == dtypeList[index]:
1771 1773 datatypeValue = datatypeValueList[index]
1772 1774 break
1773 1775
1774 1776 blocksize = int(self.dataOut.nHeights * self.dataOut.nChannels * self.dataOut.nProfiles * datatypeValue * 2)
1775 1777
1776 1778 return blocksize
1777 1779
1778 1780 def setFirstHeader(self):
1779 1781
1780 1782 """
1781 1783 Obtiene una copia del First Header
1782 1784
1783 1785 Affected:
1784 1786 self.systemHeaderObj
1785 1787 self.radarControllerHeaderObj
1786 1788 self.dtype
1787 1789
1788 1790 Return:
1789 1791 None
1790 1792 """
1791 1793
1792 1794 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
1793 1795 self.systemHeaderObj.nChannels = self.dataOut.nChannels
1794 1796 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
1795 1797
1796 1798 self.setBasicHeader()
1797 1799
1798 1800 processingHeaderSize = 40 # bytes
1799 1801 self.processingHeaderObj.dtype = 0 # Voltage
1800 1802 self.processingHeaderObj.blockSize = self.__getBlockSize()
1801 1803 self.processingHeaderObj.profilesPerBlock = self.profilesPerBlock
1802 1804 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
1803 1805 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
1804 1806 self.processingHeaderObj.processFlags = self.__getProcessFlags()
1805 1807 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt
1806 1808 self.processingHeaderObj.nIncohInt = 1 # Cuando la data de origen es de tipo Voltage
1807 1809 self.processingHeaderObj.totalSpectra = 0 # Cuando la data de origen es de tipo Voltage
1808 1810
1809 1811 if self.dataOut.code != None:
1810 1812 self.processingHeaderObj.code = self.dataOut.code
1811 1813 self.processingHeaderObj.nCode = self.dataOut.nCode
1812 1814 self.processingHeaderObj.nBaud = self.dataOut.nBaud
1813 1815 codesize = int(8 + 4 * self.dataOut.nCode * self.dataOut.nBaud)
1814 1816 processingHeaderSize += codesize
1815 1817
1816 1818 if self.processingHeaderObj.nWindows != 0:
1817 1819 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
1818 1820 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
1819 1821 self.processingHeaderObj.nHeights = self.dataOut.nHeights
1820 1822 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
1821 1823 processingHeaderSize += 12
1822 1824
1823 1825 self.processingHeaderObj.size = processingHeaderSize
1824 1826
1825 1827 class SpectraReader(JRODataReader):
1826 1828 """
1827 1829 Esta clase permite leer datos de espectros desde archivos procesados (.pdata). La lectura
1828 1830 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones)
1829 1831 son almacenados en tres buffer's para el Self Spectra, el Cross Spectra y el DC Channel.
1830 1832
1831 1833 paresCanalesIguales * alturas * perfiles (Self Spectra)
1832 1834 paresCanalesDiferentes * alturas * perfiles (Cross Spectra)
1833 1835 canales * alturas (DC Channels)
1834 1836
1835 1837 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
1836 1838 RadarControllerHeader y Spectra. Los tres primeros se usan para almacenar informacion de la
1837 1839 cabecera de datos (metadata), y el cuarto (Spectra) para obtener y almacenar un bloque de
1838 1840 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
1839 1841
1840 1842 Example:
1841 1843 dpath = "/home/myuser/data"
1842 1844
1843 1845 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
1844 1846
1845 1847 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
1846 1848
1847 1849 readerObj = SpectraReader()
1848 1850
1849 1851 readerObj.setup(dpath, startTime, endTime)
1850 1852
1851 1853 while(True):
1852 1854
1853 1855 readerObj.getData()
1854 1856
1855 1857 print readerObj.data_spc
1856 1858
1857 1859 print readerObj.data_cspc
1858 1860
1859 1861 print readerObj.data_dc
1860 1862
1861 1863 if readerObj.flagNoMoreFiles:
1862 1864 break
1863 1865
1864 1866 """
1865 1867
1866 1868 pts2read_SelfSpectra = 0
1867 1869
1868 1870 pts2read_CrossSpectra = 0
1869 1871
1870 1872 pts2read_DCchannels = 0
1871 1873
1872 1874 ext = ".pdata"
1873 1875
1874 1876 optchar = "P"
1875 1877
1876 1878 dataOut = None
1877 1879
1878 1880 nRdChannels = None
1879 1881
1880 1882 nRdPairs = None
1881 1883
1882 1884 rdPairList = []
1883 1885
1884 1886 def __init__(self):
1885 1887 """
1886 1888 Inicializador de la clase SpectraReader para la lectura de datos de espectros.
1887 1889
1888 1890 Inputs:
1889 1891 dataOut : Objeto de la clase Spectra. Este objeto sera utilizado para
1890 1892 almacenar un perfil de datos cada vez que se haga un requerimiento
1891 1893 (getData). El perfil sera obtenido a partir del buffer de datos,
1892 1894 si el buffer esta vacio se hara un nuevo proceso de lectura de un
1893 1895 bloque de datos.
1894 1896 Si este parametro no es pasado se creara uno internamente.
1895 1897
1896 1898 Affected:
1897 1899 self.dataOut
1898 1900
1899 1901 Return : None
1900 1902 """
1901 1903
1902 1904 self.isConfig = False
1903 1905
1904 1906 self.pts2read_SelfSpectra = 0
1905 1907
1906 1908 self.pts2read_CrossSpectra = 0
1907 1909
1908 1910 self.pts2read_DCchannels = 0
1909 1911
1910 1912 self.datablock = None
1911 1913
1912 1914 self.utc = None
1913 1915
1914 1916 self.ext = ".pdata"
1915 1917
1916 1918 self.optchar = "P"
1917 1919
1918 1920 self.basicHeaderObj = BasicHeader(LOCALTIME)
1919 1921
1920 1922 self.systemHeaderObj = SystemHeader()
1921 1923
1922 1924 self.radarControllerHeaderObj = RadarControllerHeader()
1923 1925
1924 1926 self.processingHeaderObj = ProcessingHeader()
1925 1927
1926 1928 self.online = 0
1927 1929
1928 1930 self.fp = None
1929 1931
1930 1932 self.idFile = None
1931 1933
1932 1934 self.dtype = None
1933 1935
1934 1936 self.fileSizeByHeader = None
1935 1937
1936 1938 self.filenameList = []
1937 1939
1938 1940 self.filename = None
1939 1941
1940 1942 self.fileSize = None
1941 1943
1942 1944 self.firstHeaderSize = 0
1943 1945
1944 1946 self.basicHeaderSize = 24
1945 1947
1946 1948 self.pathList = []
1947 1949
1948 1950 self.lastUTTime = 0
1949 1951
1950 1952 self.maxTimeStep = 30
1951 1953
1952 1954 self.flagNoMoreFiles = 0
1953 1955
1954 1956 self.set = 0
1955 1957
1956 1958 self.path = None
1957 1959
1958 1960 self.delay = 60 #seconds
1959 1961
1960 1962 self.nTries = 3 #quantity tries
1961 1963
1962 1964 self.nFiles = 3 #number of files for searching
1963 1965
1964 1966 self.nReadBlocks = 0
1965 1967
1966 1968 self.flagIsNewFile = 1
1967 1969
1968 1970 self.__isFirstTimeOnline = 1
1969 1971
1970 1972 self.ippSeconds = 0
1971 1973
1972 1974 self.flagTimeBlock = 0
1973 1975
1974 1976 self.flagIsNewBlock = 0
1975 1977
1976 1978 self.nTotalBlocks = 0
1977 1979
1978 1980 self.blocksize = 0
1979 1981
1980 1982 self.dataOut = self.createObjByDefault()
1981 1983
1982 1984 self.profileIndex = 1 #Always
1983 1985
1984 1986
1985 1987 def createObjByDefault(self):
1986 1988
1987 1989 dataObj = Spectra()
1988 1990
1989 1991 return dataObj
1990 1992
1991 1993 def __hasNotDataInBuffer(self):
1992 1994 return 1
1993 1995
1994 1996
1995 1997 def getBlockDimension(self):
1996 1998 """
1997 1999 Obtiene la cantidad de puntos a leer por cada bloque de datos
1998 2000
1999 2001 Affected:
2000 2002 self.nRdChannels
2001 2003 self.nRdPairs
2002 2004 self.pts2read_SelfSpectra
2003 2005 self.pts2read_CrossSpectra
2004 2006 self.pts2read_DCchannels
2005 2007 self.blocksize
2006 2008 self.dataOut.nChannels
2007 2009 self.dataOut.nPairs
2008 2010
2009 2011 Return:
2010 2012 None
2011 2013 """
2012 2014 self.nRdChannels = 0
2013 2015 self.nRdPairs = 0
2014 2016 self.rdPairList = []
2015 2017
2016 2018 for i in range(0, self.processingHeaderObj.totalSpectra*2, 2):
2017 2019 if self.processingHeaderObj.spectraComb[i] == self.processingHeaderObj.spectraComb[i+1]:
2018 2020 self.nRdChannels = self.nRdChannels + 1 #par de canales iguales
2019 2021 else:
2020 2022 self.nRdPairs = self.nRdPairs + 1 #par de canales diferentes
2021 2023 self.rdPairList.append((self.processingHeaderObj.spectraComb[i], self.processingHeaderObj.spectraComb[i+1]))
2022 2024
2023 2025 pts2read = self.processingHeaderObj.nHeights * self.processingHeaderObj.profilesPerBlock
2024 2026
2025 2027 self.pts2read_SelfSpectra = int(self.nRdChannels * pts2read)
2026 2028 self.blocksize = self.pts2read_SelfSpectra
2027 2029
2028 2030 if self.processingHeaderObj.flag_cspc:
2029 2031 self.pts2read_CrossSpectra = int(self.nRdPairs * pts2read)
2030 2032 self.blocksize += self.pts2read_CrossSpectra
2031 2033
2032 2034 if self.processingHeaderObj.flag_dc:
2033 2035 self.pts2read_DCchannels = int(self.systemHeaderObj.nChannels * self.processingHeaderObj.nHeights)
2034 2036 self.blocksize += self.pts2read_DCchannels
2035 2037
2036 2038 # self.blocksize = self.pts2read_SelfSpectra + self.pts2read_CrossSpectra + self.pts2read_DCchannels
2037 2039
2038 2040
2039 2041 def readBlock(self):
2040 2042 """
2041 2043 Lee el bloque de datos desde la posicion actual del puntero del archivo
2042 2044 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
2043 2045 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
2044 2046 es seteado a 0
2045 2047
2046 2048 Return: None
2047 2049
2048 2050 Variables afectadas:
2049 2051
2050 2052 self.flagIsNewFile
2051 2053 self.flagIsNewBlock
2052 2054 self.nTotalBlocks
2053 2055 self.data_spc
2054 2056 self.data_cspc
2055 2057 self.data_dc
2056 2058
2057 2059 Exceptions:
2058 2060 Si un bloque leido no es un bloque valido
2059 2061 """
2060 2062 blockOk_flag = False
2061 2063 fpointer = self.fp.tell()
2062 2064
2063 2065 spc = numpy.fromfile( self.fp, self.dtype[0], self.pts2read_SelfSpectra )
2064 2066 spc = spc.reshape( (self.nRdChannels, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
2065 2067
2066 2068 if self.processingHeaderObj.flag_cspc:
2067 2069 cspc = numpy.fromfile( self.fp, self.dtype, self.pts2read_CrossSpectra )
2068 2070 cspc = cspc.reshape( (self.nRdPairs, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
2069 2071
2070 2072 if self.processingHeaderObj.flag_dc:
2071 2073 dc = numpy.fromfile( self.fp, self.dtype, self.pts2read_DCchannels ) #int(self.processingHeaderObj.nHeights*self.systemHeaderObj.nChannels) )
2072 2074 dc = dc.reshape( (self.systemHeaderObj.nChannels, self.processingHeaderObj.nHeights) ) #transforma a un arreglo 2D
2073 2075
2074 2076
2075 2077 if not(self.processingHeaderObj.shif_fft):
2076 2078 #desplaza a la derecha en el eje 2 determinadas posiciones
2077 2079 shift = int(self.processingHeaderObj.profilesPerBlock/2)
2078 2080 spc = numpy.roll( spc, shift , axis=2 )
2079 2081
2080 2082 if self.processingHeaderObj.flag_cspc:
2081 2083 #desplaza a la derecha en el eje 2 determinadas posiciones
2082 2084 cspc = numpy.roll( cspc, shift, axis=2 )
2083 2085
2084 2086 # self.processingHeaderObj.shif_fft = True
2085 2087
2086 2088 spc = numpy.transpose( spc, (0,2,1) )
2087 2089 self.data_spc = spc
2088 2090
2089 2091 if self.processingHeaderObj.flag_cspc:
2090 2092 cspc = numpy.transpose( cspc, (0,2,1) )
2091 2093 self.data_cspc = cspc['real'] + cspc['imag']*1j
2092 2094 else:
2093 2095 self.data_cspc = None
2094 2096
2095 2097 if self.processingHeaderObj.flag_dc:
2096 2098 self.data_dc = dc['real'] + dc['imag']*1j
2097 2099 else:
2098 2100 self.data_dc = None
2099 2101
2100 2102 self.flagIsNewFile = 0
2101 2103 self.flagIsNewBlock = 1
2102 2104
2103 2105 self.nTotalBlocks += 1
2104 2106 self.nReadBlocks += 1
2105 2107
2106 2108 return 1
2107 2109
2108 2110 def getFirstHeader(self):
2109 2111
2110 2112 self.dataOut.dtype = self.dtype
2111 2113
2112 2114 self.dataOut.nPairs = self.nRdPairs
2113 2115
2114 2116 self.dataOut.pairsList = self.rdPairList
2115 2117
2116 2118 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
2117 2119
2118 2120 self.dataOut.nFFTPoints = self.processingHeaderObj.profilesPerBlock
2119 2121
2120 2122 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
2121 2123
2122 2124 self.dataOut.nIncohInt = self.processingHeaderObj.nIncohInt
2123 2125
2124 2126 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
2125 2127
2126 2128 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
2127 2129
2128 2130 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
2129 2131
2130 2132 self.dataOut.ippSeconds = self.ippSeconds
2131 2133
2132 2134 self.dataOut.timeInterval = self.ippSeconds * self.processingHeaderObj.nCohInt * self.processingHeaderObj.nIncohInt * self.dataOut.nFFTPoints
2133 2135
2134 2136 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
2135 2137
2136 2138 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
2137 2139
2138 2140 self.dataOut.flagShiftFFT = self.processingHeaderObj.shif_fft
2139 2141
2140 2142 self.dataOut.flagDecodeData = False #asumo q la data no esta decodificada
2141 2143
2142 2144 self.dataOut.flagDeflipData = True #asumo q la data no esta sin flip
2143 2145
2144 2146 if self.processingHeaderObj.code != None:
2145 2147
2146 2148 self.dataOut.nCode = self.processingHeaderObj.nCode
2147 2149
2148 2150 self.dataOut.nBaud = self.processingHeaderObj.nBaud
2149 2151
2150 2152 self.dataOut.code = self.processingHeaderObj.code
2151 2153
2152 2154 self.dataOut.flagDecodeData = True
2153 2155
2154 2156 def getData(self):
2155 2157 """
2156 2158 Copia el buffer de lectura a la clase "Spectra",
2157 2159 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
2158 2160 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
2159 2161
2160 2162 Return:
2161 2163 0 : Si no hay mas archivos disponibles
2162 2164 1 : Si hizo una buena copia del buffer
2163 2165
2164 2166 Affected:
2165 2167 self.dataOut
2166 2168
2167 2169 self.flagTimeBlock
2168 2170 self.flagIsNewBlock
2169 2171 """
2170 2172
2171 2173 if self.flagNoMoreFiles:
2172 2174 self.dataOut.flagNoData = True
2173 2175 print 'Process finished'
2174 2176 return 0
2175 2177
2176 2178 self.flagTimeBlock = 0
2177 2179 self.flagIsNewBlock = 0
2178 2180
2179 2181 if self.__hasNotDataInBuffer():
2180 2182
2181 2183 if not( self.readNextBlock() ):
2182 2184 self.dataOut.flagNoData = True
2183 2185 return 0
2184 2186
2185 2187 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
2186 2188
2187 2189 if self.data_dc == None:
2188 2190 self.dataOut.flagNoData = True
2189 2191 return 0
2190 2192
2191 2193 self.getBasicHeader()
2192 2194
2193 2195 self.getFirstHeader()
2194 2196
2195 2197 self.dataOut.data_spc = self.data_spc
2196 2198
2197 2199 self.dataOut.data_cspc = self.data_cspc
2198 2200
2199 2201 self.dataOut.data_dc = self.data_dc
2200 2202
2201 2203 self.dataOut.flagNoData = False
2202 2204
2205 self.dataOut.realtime = self.online
2206
2203 2207 return self.dataOut.data_spc
2204 2208
2205 2209
2206 2210 class SpectraWriter(JRODataWriter):
2207 2211
2208 2212 """
2209 2213 Esta clase permite escribir datos de espectros a archivos procesados (.pdata). La escritura
2210 2214 de los datos siempre se realiza por bloques.
2211 2215 """
2212 2216
2213 2217 ext = ".pdata"
2214 2218
2215 2219 optchar = "P"
2216 2220
2217 2221 shape_spc_Buffer = None
2218 2222
2219 2223 shape_cspc_Buffer = None
2220 2224
2221 2225 shape_dc_Buffer = None
2222 2226
2223 2227 data_spc = None
2224 2228
2225 2229 data_cspc = None
2226 2230
2227 2231 data_dc = None
2228 2232
2229 2233 # dataOut = None
2230 2234
2231 2235 def __init__(self):
2232 2236 """
2233 2237 Inicializador de la clase SpectraWriter para la escritura de datos de espectros.
2234 2238
2235 2239 Affected:
2236 2240 self.dataOut
2237 2241 self.basicHeaderObj
2238 2242 self.systemHeaderObj
2239 2243 self.radarControllerHeaderObj
2240 2244 self.processingHeaderObj
2241 2245
2242 2246 Return: None
2243 2247 """
2244 2248
2245 2249 self.isConfig = False
2246 2250
2247 2251 self.nTotalBlocks = 0
2248 2252
2249 2253 self.data_spc = None
2250 2254
2251 2255 self.data_cspc = None
2252 2256
2253 2257 self.data_dc = None
2254 2258
2255 2259 self.fp = None
2256 2260
2257 2261 self.flagIsNewFile = 1
2258 2262
2259 2263 self.nTotalBlocks = 0
2260 2264
2261 2265 self.flagIsNewBlock = 0
2262 2266
2263 2267 self.setFile = None
2264 2268
2265 2269 self.dtype = None
2266 2270
2267 2271 self.path = None
2268 2272
2269 2273 self.noMoreFiles = 0
2270 2274
2271 2275 self.filename = None
2272 2276
2273 2277 self.basicHeaderObj = BasicHeader(LOCALTIME)
2274 2278
2275 2279 self.systemHeaderObj = SystemHeader()
2276 2280
2277 2281 self.radarControllerHeaderObj = RadarControllerHeader()
2278 2282
2279 2283 self.processingHeaderObj = ProcessingHeader()
2280 2284
2281 2285
2282 2286 def hasAllDataInBuffer(self):
2283 2287 return 1
2284 2288
2285 2289
2286 2290 def setBlockDimension(self):
2287 2291 """
2288 2292 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
2289 2293
2290 2294 Affected:
2291 2295 self.shape_spc_Buffer
2292 2296 self.shape_cspc_Buffer
2293 2297 self.shape_dc_Buffer
2294 2298
2295 2299 Return: None
2296 2300 """
2297 2301 self.shape_spc_Buffer = (self.dataOut.nChannels,
2298 2302 self.processingHeaderObj.nHeights,
2299 2303 self.processingHeaderObj.profilesPerBlock)
2300 2304
2301 2305 self.shape_cspc_Buffer = (self.dataOut.nPairs,
2302 2306 self.processingHeaderObj.nHeights,
2303 2307 self.processingHeaderObj.profilesPerBlock)
2304 2308
2305 2309 self.shape_dc_Buffer = (self.dataOut.nChannels,
2306 2310 self.processingHeaderObj.nHeights)
2307 2311
2308 2312
2309 2313 def writeBlock(self):
2310 2314 """
2311 2315 Escribe el buffer en el file designado
2312 2316
2313 2317 Affected:
2314 2318 self.data_spc
2315 2319 self.data_cspc
2316 2320 self.data_dc
2317 2321 self.flagIsNewFile
2318 2322 self.flagIsNewBlock
2319 2323 self.nTotalBlocks
2320 2324 self.nWriteBlocks
2321 2325
2322 2326 Return: None
2323 2327 """
2324 2328
2325 2329 spc = numpy.transpose( self.data_spc, (0,2,1) )
2326 2330 if not( self.processingHeaderObj.shif_fft ):
2327 2331 spc = numpy.roll( spc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
2328 2332 data = spc.reshape((-1))
2329 2333 data = data.astype(self.dtype[0])
2330 2334 data.tofile(self.fp)
2331 2335
2332 2336 if self.data_cspc != None:
2333 2337 data = numpy.zeros( self.shape_cspc_Buffer, self.dtype )
2334 2338 cspc = numpy.transpose( self.data_cspc, (0,2,1) )
2335 2339 if not( self.processingHeaderObj.shif_fft ):
2336 2340 cspc = numpy.roll( cspc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
2337 2341 data['real'] = cspc.real
2338 2342 data['imag'] = cspc.imag
2339 2343 data = data.reshape((-1))
2340 2344 data.tofile(self.fp)
2341 2345
2342 2346 if self.data_dc != None:
2343 2347 data = numpy.zeros( self.shape_dc_Buffer, self.dtype )
2344 2348 dc = self.data_dc
2345 2349 data['real'] = dc.real
2346 2350 data['imag'] = dc.imag
2347 2351 data = data.reshape((-1))
2348 2352 data.tofile(self.fp)
2349 2353
2350 2354 self.data_spc.fill(0)
2351 2355 self.data_dc.fill(0)
2352 2356 if self.data_cspc != None:
2353 2357 self.data_cspc.fill(0)
2354 2358
2355 2359 self.flagIsNewFile = 0
2356 2360 self.flagIsNewBlock = 1
2357 2361 self.nTotalBlocks += 1
2358 2362 self.nWriteBlocks += 1
2359 2363 self.blockIndex += 1
2360 2364
2361 2365
2362 2366 def putData(self):
2363 2367 """
2364 2368 Setea un bloque de datos y luego los escribe en un file
2365 2369
2366 2370 Affected:
2367 2371 self.data_spc
2368 2372 self.data_cspc
2369 2373 self.data_dc
2370 2374
2371 2375 Return:
2372 2376 0 : Si no hay data o no hay mas files que puedan escribirse
2373 2377 1 : Si se escribio la data de un bloque en un file
2374 2378 """
2375 2379
2376 2380 if self.dataOut.flagNoData:
2377 2381 return 0
2378 2382
2379 2383 self.flagIsNewBlock = 0
2380 2384
2381 2385 if self.dataOut.flagTimeBlock:
2382 2386 self.data_spc.fill(0)
2383 2387 self.data_cspc.fill(0)
2384 2388 self.data_dc.fill(0)
2385 2389 self.setNextFile()
2386 2390
2387 2391 if self.flagIsNewFile == 0:
2388 2392 self.setBasicHeader()
2389 2393
2390 2394 self.data_spc = self.dataOut.data_spc.copy()
2391 2395 self.data_cspc = self.dataOut.data_cspc.copy()
2392 2396 self.data_dc = self.dataOut.data_dc.copy()
2393 2397
2394 2398 # #self.processingHeaderObj.dataBlocksPerFile)
2395 2399 if self.hasAllDataInBuffer():
2396 2400 # self.setFirstHeader()
2397 2401 self.writeNextBlock()
2398 2402
2399 2403 return 1
2400 2404
2401 2405
2402 2406 def __getProcessFlags(self):
2403 2407
2404 2408 processFlags = 0
2405 2409
2406 2410 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
2407 2411 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
2408 2412 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
2409 2413 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
2410 2414 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
2411 2415 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
2412 2416
2413 2417 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
2414 2418
2415 2419
2416 2420
2417 2421 datatypeValueList = [PROCFLAG.DATATYPE_CHAR,
2418 2422 PROCFLAG.DATATYPE_SHORT,
2419 2423 PROCFLAG.DATATYPE_LONG,
2420 2424 PROCFLAG.DATATYPE_INT64,
2421 2425 PROCFLAG.DATATYPE_FLOAT,
2422 2426 PROCFLAG.DATATYPE_DOUBLE]
2423 2427
2424 2428
2425 2429 for index in range(len(dtypeList)):
2426 2430 if self.dataOut.dtype == dtypeList[index]:
2427 2431 dtypeValue = datatypeValueList[index]
2428 2432 break
2429 2433
2430 2434 processFlags += dtypeValue
2431 2435
2432 2436 if self.dataOut.flagDecodeData:
2433 2437 processFlags += PROCFLAG.DECODE_DATA
2434 2438
2435 2439 if self.dataOut.flagDeflipData:
2436 2440 processFlags += PROCFLAG.DEFLIP_DATA
2437 2441
2438 2442 if self.dataOut.code != None:
2439 2443 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
2440 2444
2441 2445 if self.dataOut.nIncohInt > 1:
2442 2446 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
2443 2447
2444 2448 if self.dataOut.data_dc != None:
2445 2449 processFlags += PROCFLAG.SAVE_CHANNELS_DC
2446 2450
2447 2451 return processFlags
2448 2452
2449 2453
2450 2454 def __getBlockSize(self):
2451 2455 '''
2452 2456 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Spectra
2453 2457 '''
2454 2458
2455 2459 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
2456 2460 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
2457 2461 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
2458 2462 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
2459 2463 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
2460 2464 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
2461 2465
2462 2466 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
2463 2467 datatypeValueList = [1,2,4,8,4,8]
2464 2468 for index in range(len(dtypeList)):
2465 2469 if self.dataOut.dtype == dtypeList[index]:
2466 2470 datatypeValue = datatypeValueList[index]
2467 2471 break
2468 2472
2469 2473
2470 2474 pts2write = self.dataOut.nHeights * self.dataOut.nFFTPoints
2471 2475
2472 2476 pts2write_SelfSpectra = int(self.dataOut.nChannels * pts2write)
2473 2477 blocksize = (pts2write_SelfSpectra*datatypeValue)
2474 2478
2475 2479 if self.dataOut.data_cspc != None:
2476 2480 pts2write_CrossSpectra = int(self.dataOut.nPairs * pts2write)
2477 2481 blocksize += (pts2write_CrossSpectra*datatypeValue*2)
2478 2482
2479 2483 if self.dataOut.data_dc != None:
2480 2484 pts2write_DCchannels = int(self.dataOut.nChannels * self.dataOut.nHeights)
2481 2485 blocksize += (pts2write_DCchannels*datatypeValue*2)
2482 2486
2483 2487 blocksize = blocksize #* datatypeValue * 2 #CORREGIR ESTO
2484 2488
2485 2489 return blocksize
2486 2490
2487 2491 def setFirstHeader(self):
2488 2492
2489 2493 """
2490 2494 Obtiene una copia del First Header
2491 2495
2492 2496 Affected:
2493 2497 self.systemHeaderObj
2494 2498 self.radarControllerHeaderObj
2495 2499 self.dtype
2496 2500
2497 2501 Return:
2498 2502 None
2499 2503 """
2500 2504
2501 2505 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
2502 2506 self.systemHeaderObj.nChannels = self.dataOut.nChannels
2503 2507 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
2504 2508
2505 2509 self.setBasicHeader()
2506 2510
2507 2511 processingHeaderSize = 40 # bytes
2508 2512 self.processingHeaderObj.dtype = 1 # Spectra
2509 2513 self.processingHeaderObj.blockSize = self.__getBlockSize()
2510 2514 self.processingHeaderObj.profilesPerBlock = self.dataOut.nFFTPoints
2511 2515 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
2512 2516 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
2513 2517 self.processingHeaderObj.processFlags = self.__getProcessFlags()
2514 2518 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt# Se requiere para determinar el valor de timeInterval
2515 2519 self.processingHeaderObj.nIncohInt = self.dataOut.nIncohInt
2516 2520 self.processingHeaderObj.totalSpectra = self.dataOut.nPairs + self.dataOut.nChannels
2517 2521 self.processingHeaderObj.shif_fft = self.dataOut.flagShiftFFT
2518 2522
2519 2523 if self.processingHeaderObj.totalSpectra > 0:
2520 2524 channelList = []
2521 2525 for channel in range(self.dataOut.nChannels):
2522 2526 channelList.append(channel)
2523 2527 channelList.append(channel)
2524 2528
2525 2529 pairsList = []
2526 2530 for pair in self.dataOut.pairsList:
2527 2531 pairsList.append(pair[0])
2528 2532 pairsList.append(pair[1])
2529 2533 spectraComb = channelList + pairsList
2530 2534 spectraComb = numpy.array(spectraComb,dtype="u1")
2531 2535 self.processingHeaderObj.spectraComb = spectraComb
2532 2536 sizeOfSpcComb = len(spectraComb)
2533 2537 processingHeaderSize += sizeOfSpcComb
2534 2538
2535 2539 # The processing header should not have information about code
2536 2540 # if self.dataOut.code != None:
2537 2541 # self.processingHeaderObj.code = self.dataOut.code
2538 2542 # self.processingHeaderObj.nCode = self.dataOut.nCode
2539 2543 # self.processingHeaderObj.nBaud = self.dataOut.nBaud
2540 2544 # nCodeSize = 4 # bytes
2541 2545 # nBaudSize = 4 # bytes
2542 2546 # codeSize = 4 # bytes
2543 2547 # sizeOfCode = int(nCodeSize + nBaudSize + codeSize * self.dataOut.nCode * self.dataOut.nBaud)
2544 2548 # processingHeaderSize += sizeOfCode
2545 2549
2546 2550 if self.processingHeaderObj.nWindows != 0:
2547 2551 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
2548 2552 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
2549 2553 self.processingHeaderObj.nHeights = self.dataOut.nHeights
2550 2554 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
2551 2555 sizeOfFirstHeight = 4
2552 2556 sizeOfdeltaHeight = 4
2553 2557 sizeOfnHeights = 4
2554 2558 sizeOfWindows = (sizeOfFirstHeight + sizeOfdeltaHeight + sizeOfnHeights)*self.processingHeaderObj.nWindows
2555 2559 processingHeaderSize += sizeOfWindows
2556 2560
2557 2561 self.processingHeaderObj.size = processingHeaderSize
2558 2562
2559 2563 class SpectraHeisWriter(Operation):
2560 2564 # set = None
2561 2565 setFile = None
2562 2566 idblock = None
2563 2567 doypath = None
2564 2568 subfolder = None
2565 2569
2566 2570 def __init__(self):
2567 2571 self.wrObj = FITS()
2568 2572 # self.dataOut = dataOut
2569 2573 self.nTotalBlocks=0
2570 2574 # self.set = None
2571 2575 self.setFile = None
2572 2576 self.idblock = 0
2573 2577 self.wrpath = None
2574 2578 self.doypath = None
2575 2579 self.subfolder = None
2576 2580 self.isConfig = False
2577 2581
2578 2582 def isNumber(str):
2579 2583 """
2580 2584 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
2581 2585
2582 2586 Excepciones:
2583 2587 Si un determinado string no puede ser convertido a numero
2584 2588 Input:
2585 2589 str, string al cual se le analiza para determinar si convertible a un numero o no
2586 2590
2587 2591 Return:
2588 2592 True : si el string es uno numerico
2589 2593 False : no es un string numerico
2590 2594 """
2591 2595 try:
2592 2596 float( str )
2593 2597 return True
2594 2598 except:
2595 2599 return False
2596 2600
2597 2601 def setup(self, dataOut, wrpath):
2598 2602
2599 2603 if not(os.path.exists(wrpath)):
2600 2604 os.mkdir(wrpath)
2601 2605
2602 2606 self.wrpath = wrpath
2603 2607 # self.setFile = 0
2604 2608 self.dataOut = dataOut
2605 2609
2606 2610 def putData(self):
2607 2611 name= time.localtime( self.dataOut.utctime)
2608 2612 ext=".fits"
2609 2613
2610 2614 if self.doypath == None:
2611 2615 self.subfolder = 'F%4.4d%3.3d_%d' % (name.tm_year,name.tm_yday,time.mktime(datetime.datetime.now().timetuple()))
2612 2616 self.doypath = os.path.join( self.wrpath, self.subfolder )
2613 2617 os.mkdir(self.doypath)
2614 2618
2615 2619 if self.setFile == None:
2616 2620 # self.set = self.dataOut.set
2617 2621 self.setFile = 0
2618 2622 # if self.set != self.dataOut.set:
2619 2623 ## self.set = self.dataOut.set
2620 2624 # self.setFile = 0
2621 2625
2622 2626 #make the filename
2623 2627 file = 'D%4.4d%3.3d_%3.3d%s' % (name.tm_year,name.tm_yday,self.setFile,ext)
2624 2628
2625 2629 filename = os.path.join(self.wrpath,self.subfolder, file)
2626 2630
2627 2631 idblock = numpy.array([self.idblock],dtype="int64")
2628 2632 header=self.wrObj.cFImage(idblock=idblock,
2629 2633 year=time.gmtime(self.dataOut.utctime).tm_year,
2630 2634 month=time.gmtime(self.dataOut.utctime).tm_mon,
2631 2635 day=time.gmtime(self.dataOut.utctime).tm_mday,
2632 2636 hour=time.gmtime(self.dataOut.utctime).tm_hour,
2633 2637 minute=time.gmtime(self.dataOut.utctime).tm_min,
2634 2638 second=time.gmtime(self.dataOut.utctime).tm_sec)
2635 2639
2636 2640 c=3E8
2637 2641 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
2638 2642 freq=numpy.arange(-1*self.dataOut.nHeights/2.,self.dataOut.nHeights/2.)*(c/(2*deltaHeight*1000))
2639 2643
2640 2644 colList = []
2641 2645
2642 2646 colFreq=self.wrObj.setColF(name="freq", format=str(self.dataOut.nFFTPoints)+'E', array=freq)
2643 2647
2644 2648 colList.append(colFreq)
2645 2649
2646 2650 nchannel=self.dataOut.nChannels
2647 2651
2648 2652 for i in range(nchannel):
2649 2653 col = self.wrObj.writeData(name="PCh"+str(i+1),
2650 2654 format=str(self.dataOut.nFFTPoints)+'E',
2651 2655 data=10*numpy.log10(self.dataOut.data_spc[i,:]))
2652 2656
2653 2657 colList.append(col)
2654 2658
2655 2659 data=self.wrObj.Ctable(colList=colList)
2656 2660
2657 2661 self.wrObj.CFile(header,data)
2658 2662
2659 2663 self.wrObj.wFile(filename)
2660 2664
2661 2665 #update the setFile
2662 2666 self.setFile += 1
2663 2667 self.idblock += 1
2664 2668
2665 2669 return 1
2666 2670
2667 2671 def run(self, dataOut, **kwargs):
2668 2672
2669 2673 if not(self.isConfig):
2670 2674
2671 2675 self.setup(dataOut, **kwargs)
2672 2676 self.isConfig = True
2673 2677
2674 2678 self.putData()
2675 2679
2676 2680
2677 2681 class FITS:
2678 2682 name=None
2679 2683 format=None
2680 2684 array =None
2681 2685 data =None
2682 2686 thdulist=None
2683 2687 prihdr=None
2684 2688 hdu=None
2685 2689
2686 2690 def __init__(self):
2687 2691
2688 2692 pass
2689 2693
2690 2694 def setColF(self,name,format,array):
2691 2695 self.name=name
2692 2696 self.format=format
2693 2697 self.array=array
2694 2698 a1=numpy.array([self.array],dtype=numpy.float32)
2695 2699 self.col1 = pyfits.Column(name=self.name, format=self.format, array=a1)
2696 2700 return self.col1
2697 2701
2698 2702 # def setColP(self,name,format,data):
2699 2703 # self.name=name
2700 2704 # self.format=format
2701 2705 # self.data=data
2702 2706 # a2=numpy.array([self.data],dtype=numpy.float32)
2703 2707 # self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2)
2704 2708 # return self.col2
2705 2709
2706 2710
2707 2711 def writeData(self,name,format,data):
2708 2712 self.name=name
2709 2713 self.format=format
2710 2714 self.data=data
2711 2715 a2=numpy.array([self.data],dtype=numpy.float32)
2712 2716 self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2)
2713 2717 return self.col2
2714 2718
2715 2719 def cFImage(self,idblock,year,month,day,hour,minute,second):
2716 2720 self.hdu= pyfits.PrimaryHDU(idblock)
2717 2721 self.hdu.header.set("Year",year)
2718 2722 self.hdu.header.set("Month",month)
2719 2723 self.hdu.header.set("Day",day)
2720 2724 self.hdu.header.set("Hour",hour)
2721 2725 self.hdu.header.set("Minute",minute)
2722 2726 self.hdu.header.set("Second",second)
2723 2727 return self.hdu
2724 2728
2725 2729
2726 2730 def Ctable(self,colList):
2727 2731 self.cols=pyfits.ColDefs(colList)
2728 2732 self.tbhdu = pyfits.new_table(self.cols)
2729 2733 return self.tbhdu
2730 2734
2731 2735
2732 2736 def CFile(self,hdu,tbhdu):
2733 2737 self.thdulist=pyfits.HDUList([hdu,tbhdu])
2734 2738
2735 2739 def wFile(self,filename):
2736 2740 if os.path.isfile(filename):
2737 2741 os.remove(filename)
2738 2742 self.thdulist.writeto(filename)
2739 2743
2740 2744
2741 2745 class ParameterConf:
2742 2746 ELEMENTNAME = 'Parameter'
2743 2747 def __init__(self):
2744 2748 self.name = ''
2745 2749 self.value = ''
2746 2750
2747 2751 def readXml(self, parmElement):
2748 2752 self.name = parmElement.get('name')
2749 2753 self.value = parmElement.get('value')
2750 2754
2751 2755 def getElementName(self):
2752 2756 return self.ELEMENTNAME
2753 2757
2754 2758 class Metadata:
2755 2759
2756 2760 def __init__(self, filename):
2757 2761 self.parmConfObjList = []
2758 2762 self.readXml(filename)
2759 2763
2760 2764 def readXml(self, filename):
2761 2765 self.projectElement = None
2762 2766 self.procUnitConfObjDict = {}
2763 2767 self.projectElement = ElementTree().parse(filename)
2764 2768 self.project = self.projectElement.tag
2765 2769
2766 2770 parmElementList = self.projectElement.getiterator(ParameterConf().getElementName())
2767 2771
2768 2772 for parmElement in parmElementList:
2769 2773 parmConfObj = ParameterConf()
2770 2774 parmConfObj.readXml(parmElement)
2771 2775 self.parmConfObjList.append(parmConfObj)
2772 2776
2773 2777 class FitsWriter(Operation):
2774 2778
2775 2779 def __init__(self):
2776 2780 self.isConfig = False
2777 2781 self.dataBlocksPerFile = None
2778 2782 self.blockIndex = 0
2779 2783 self.flagIsNewFile = 1
2780 2784 self.fitsObj = None
2781 2785 self.optchar = 'P'
2782 2786 self.ext = '.fits'
2783 2787 self.setFile = 0
2784 2788
2785 2789 def setFitsHeader(self, dataOut, metadatafile):
2786 2790
2787 2791 header_data = pyfits.PrimaryHDU()
2788 2792
2789 2793 metadata4fits = Metadata(metadatafile)
2790 2794 for parameter in metadata4fits.parmConfObjList:
2791 2795 parm_name = parameter.name
2792 2796 parm_value = parameter.value
2793 2797
2794 2798 if parm_value == 'fromdatadatetime':
2795 2799 value = time.strftime("%b %d %Y %H:%M:%S", dataOut.datatime.timetuple())
2796 2800 elif parm_value == 'fromdataheights':
2797 2801 value = dataOut.nHeights
2798 2802 elif parm_value == 'fromdatachannel':
2799 2803 value = dataOut.nChannels
2800 2804 elif parm_value == 'fromdatasamples':
2801 2805 value = dataOut.nFFTPoints
2802 2806 else:
2803 2807 value = parm_value
2804 2808
2805 2809 header_data.header[parm_name] = value
2806 2810
2807 2811 header_data.header['NBLOCK'] = self.blockIndex
2808 2812
2809 2813 header_data.writeto(self.filename)
2810 2814
2811 2815
2812 2816 def setup(self, dataOut, path, dataBlocksPerFile, metadatafile):
2813 2817
2814 2818 self.path = path
2815 2819 self.dataOut = dataOut
2816 2820 self.metadatafile = metadatafile
2817 2821 self.dataBlocksPerFile = dataBlocksPerFile
2818 2822
2819 2823 def open(self):
2820 2824 self.fitsObj = pyfits.open(self.filename, mode='update')
2821 2825
2822 2826
2823 2827 def addData(self, data):
2824 2828 self.open()
2825 2829 extension = pyfits.ImageHDU(data=data, name=self.fitsObj[0].header['DATA'])
2826 2830 extension.header['UTCTIME'] = self.dataOut.utctime
2827 2831 self.fitsObj.append(extension)
2828 2832 self.blockIndex += 1
2829 2833 self.fitsObj[0].header['NBLOCK'] = self.blockIndex
2830 2834
2831 2835 self.write()
2832 2836
2833 2837 def write(self):
2834 2838
2835 2839 self.fitsObj.flush(verbose=True)
2836 2840 self.fitsObj.close()
2837 2841
2838 2842
2839 2843 def setNextFile(self):
2840 2844
2841 2845 ext = self.ext
2842 2846 path = self.path
2843 2847
2844 2848 timeTuple = time.localtime( self.dataOut.utctime)
2845 2849 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
2846 2850
2847 2851 fullpath = os.path.join( path, subfolder )
2848 2852 if not( os.path.exists(fullpath) ):
2849 2853 os.mkdir(fullpath)
2850 2854 self.setFile = -1 #inicializo mi contador de seteo
2851 2855 else:
2852 2856 filesList = os.listdir( fullpath )
2853 2857 if len( filesList ) > 0:
2854 2858 filesList = sorted( filesList, key=str.lower )
2855 2859 filen = filesList[-1]
2856 2860
2857 2861 if isNumber( filen[8:11] ):
2858 2862 self.setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
2859 2863 else:
2860 2864 self.setFile = -1
2861 2865 else:
2862 2866 self.setFile = -1 #inicializo mi contador de seteo
2863 2867
2864 2868 setFile = self.setFile
2865 2869 setFile += 1
2866 2870
2867 2871 file = '%s%4.4d%3.3d%3.3d%s' % (self.optchar,
2868 2872 timeTuple.tm_year,
2869 2873 timeTuple.tm_yday,
2870 2874 setFile,
2871 2875 ext )
2872 2876
2873 2877 filename = os.path.join( path, subfolder, file )
2874 2878
2875 2879 self.blockIndex = 0
2876 2880 self.filename = filename
2877 2881 self.setFile = setFile
2878 2882 self.flagIsNewFile = 1
2879 2883
2880 2884 print 'Writing the file: %s'%self.filename
2881 2885
2882 2886 self.setFitsHeader(self.dataOut, self.metadatafile)
2883 2887
2884 2888 return 1
2885 2889
2886 2890 def writeBlock(self):
2887 2891 self.addData(self.dataOut.data_spc)
2888 2892 self.flagIsNewFile = 0
2889 2893
2890 2894
2891 2895 def __setNewBlock(self):
2892 2896
2893 2897 if self.flagIsNewFile:
2894 2898 return 1
2895 2899
2896 2900 if self.blockIndex < self.dataBlocksPerFile:
2897 2901 return 1
2898 2902
2899 2903 if not( self.setNextFile() ):
2900 2904 return 0
2901 2905
2902 2906 return 1
2903 2907
2904 2908 def writeNextBlock(self):
2905 2909 if not( self.__setNewBlock() ):
2906 2910 return 0
2907 2911 self.writeBlock()
2908 2912 return 1
2909 2913
2910 2914 def putData(self):
2911 2915 if self.flagIsNewFile:
2912 2916 self.setNextFile()
2913 2917 self.writeNextBlock()
2914 2918
2915 2919 def run(self, dataOut, **kwargs):
2916 2920 if not(self.isConfig):
2917 2921 self.setup(dataOut, **kwargs)
2918 2922 self.isConfig = True
2919 2923 self.putData()
2920 2924
2921 2925
2922 2926 class FitsReader(ProcessingUnit):
2923 2927
2924 2928 __TIMEZONE = time.timezone
2925 2929
2926 2930 expName = None
2927 2931 datetimestr = None
2928 2932 utc = None
2929 2933 nChannels = None
2930 2934 nSamples = None
2931 2935 dataBlocksPerFile = None
2932 2936 comments = None
2933 2937 lastUTTime = None
2934 2938 header_dict = None
2935 2939 data = None
2936 2940 data_header_dict = None
2937 2941
2938 2942 def __init__(self):
2939 2943 self.isConfig = False
2940 2944 self.ext = '.fits'
2941 2945 self.setFile = 0
2942 2946 self.flagNoMoreFiles = 0
2943 2947 self.flagIsNewFile = 1
2944 2948 self.flagTimeBlock = None
2945 2949 self.fileIndex = None
2946 2950 self.filename = None
2947 2951 self.fileSize = None
2948 2952 self.fitsObj = None
2949 2953 self.nReadBlocks = 0
2950 2954 self.nTotalBlocks = 0
2951 2955 self.dataOut = self.createObjByDefault()
2952 2956 self.maxTimeStep = 10# deberia ser definido por el usuario usando el metodo setup()
2953 2957 self.blockIndex = 1
2954 2958
2955 2959 def createObjByDefault(self):
2956 2960
2957 2961 dataObj = Fits()
2958 2962
2959 2963 return dataObj
2960 2964
2961 2965 def isFileinThisTime(self, filename, startTime, endTime, useLocalTime=False):
2962 2966 try:
2963 2967 fitsObj = pyfits.open(filename,'readonly')
2964 2968 except:
2965 2969 raise IOError, "The file %s can't be opened" %(filename)
2966 2970
2967 2971 header = fitsObj[0].header
2968 2972 struct_time = time.strptime(header['DATETIME'], "%b %d %Y %H:%M:%S")
2969 2973 utc = time.mktime(struct_time) - time.timezone #TIMEZONE debe ser un parametro del header FITS
2970 2974
2971 2975 ltc = utc
2972 2976 if useLocalTime:
2973 2977 ltc -= time.timezone
2974 2978 thisDatetime = datetime.datetime.utcfromtimestamp(ltc)
2975 2979 thisTime = thisDatetime.time()
2976 2980
2977 2981 if not ((startTime <= thisTime) and (endTime > thisTime)):
2978 2982 return None
2979 2983
2980 2984 return thisDatetime
2981 2985
2982 2986 def __setNextFileOnline(self):
2983 2987 raise ValueError, "No implemented"
2984 2988
2985 2989 def __setNextFileOffline(self):
2986 2990 idFile = self.fileIndex
2987 2991
2988 2992 while (True):
2989 2993 idFile += 1
2990 2994 if not(idFile < len(self.filenameList)):
2991 2995 self.flagNoMoreFiles = 1
2992 2996 print "No more Files"
2993 2997 return 0
2994 2998
2995 2999 filename = self.filenameList[idFile]
2996 3000
2997 3001 # if not(self.__verifyFile(filename)):
2998 3002 # continue
2999 3003
3000 3004 fileSize = os.path.getsize(filename)
3001 3005 fitsObj = pyfits.open(filename,'readonly')
3002 3006 break
3003 3007
3004 3008 self.flagIsNewFile = 1
3005 3009 self.fileIndex = idFile
3006 3010 self.filename = filename
3007 3011 self.fileSize = fileSize
3008 3012 self.fitsObj = fitsObj
3009 3013
3010 3014 print "Setting the file: %s"%self.filename
3011 3015
3012 3016 return 1
3013 3017
3014 3018 def readHeader(self):
3015 3019 headerObj = self.fitsObj[0]
3016 3020
3017 3021 self.header_dict = headerObj.header
3018 3022 self.expName = headerObj.header['EXPNAME']
3019 3023 self.datetimestr = headerObj.header['DATETIME']
3020 3024 struct_time = time.strptime(headerObj.header['DATETIME'], "%b %d %Y %H:%M:%S")
3021 3025 # self.utc = time.mktime(struct_time) - self.__TIMEZONE
3022 3026 self.nChannels = headerObj.header['NCHANNEL']
3023 3027 self.nSamples = headerObj.header['NSAMPLE']
3024 3028 self.dataBlocksPerFile = headerObj.header['NBLOCK']
3025 3029 self.comments = headerObj.header['COMMENT']
3026 3030
3027 3031
3028 3032 def setNextFile(self):
3029 3033
3030 3034 if self.online:
3031 3035 newFile = self.__setNextFileOnline()
3032 3036 else:
3033 3037 newFile = self.__setNextFileOffline()
3034 3038
3035 3039 if not(newFile):
3036 3040 return 0
3037 3041
3038 3042 self.readHeader()
3039 3043
3040 3044 self.nReadBlocks = 0
3041 3045 self.blockIndex = 1
3042 3046 return 1
3043 3047
3044 3048 def __searchFilesOffLine(self,
3045 3049 path,
3046 3050 startDate,
3047 3051 endDate,
3048 3052 startTime=datetime.time(0,0,0),
3049 3053 endTime=datetime.time(23,59,59),
3050 3054 set=None,
3051 3055 expLabel='',
3052 3056 ext='.fits',
3053 3057 walk=True):
3054 3058
3055 3059 pathList = []
3056 3060
3057 3061 if not walk:
3058 3062 pathList.append(path)
3059 3063
3060 3064 else:
3061 3065 dirList = []
3062 3066 for thisPath in os.listdir(path):
3063 3067 if not os.path.isdir(os.path.join(path,thisPath)):
3064 3068 continue
3065 3069 if not isDoyFolder(thisPath):
3066 3070 continue
3067 3071
3068 3072 dirList.append(thisPath)
3069 3073
3070 3074 if not(dirList):
3071 3075 return None, None
3072 3076
3073 3077 thisDate = startDate
3074 3078
3075 3079 while(thisDate <= endDate):
3076 3080 year = thisDate.timetuple().tm_year
3077 3081 doy = thisDate.timetuple().tm_yday
3078 3082
3079 3083 matchlist = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy) + '*')
3080 3084 if len(matchlist) == 0:
3081 3085 thisDate += datetime.timedelta(1)
3082 3086 continue
3083 3087 for match in matchlist:
3084 3088 pathList.append(os.path.join(path,match,expLabel))
3085 3089
3086 3090 thisDate += datetime.timedelta(1)
3087 3091
3088 3092 if pathList == []:
3089 3093 print "Any folder was found for the date range: %s-%s" %(startDate, endDate)
3090 3094 return None, None
3091 3095
3092 3096 print "%d folder(s) was(were) found for the date range: %s - %s" %(len(pathList), startDate, endDate)
3093 3097
3094 3098 filenameList = []
3095 3099 datetimeList = []
3096 3100
3097 3101 for i in range(len(pathList)):
3098 3102
3099 3103 thisPath = pathList[i]
3100 3104
3101 3105 fileList = glob.glob1(thisPath, "*%s" %ext)
3102 3106 fileList.sort()
3103 3107
3104 3108 for file in fileList:
3105 3109
3106 3110 filename = os.path.join(thisPath,file)
3107 3111 thisDatetime = self.isFileinThisTime(filename, startTime, endTime, useLocalTime=True)
3108 3112
3109 3113 if not(thisDatetime):
3110 3114 continue
3111 3115
3112 3116 filenameList.append(filename)
3113 3117 datetimeList.append(thisDatetime)
3114 3118
3115 3119 if not(filenameList):
3116 3120 print "Any file was found for the time range %s - %s" %(startTime, endTime)
3117 3121 return None, None
3118 3122
3119 3123 print "%d file(s) was(were) found for the time range: %s - %s" %(len(filenameList), startTime, endTime)
3120 3124 print
3121 3125
3122 3126 for i in range(len(filenameList)):
3123 3127 print "%s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
3124 3128
3125 3129 self.filenameList = filenameList
3126 3130 self.datetimeList = datetimeList
3127 3131
3128 3132 return pathList, filenameList
3129 3133
3130 3134 def setup(self, path=None,
3131 3135 startDate=None,
3132 3136 endDate=None,
3133 3137 startTime=datetime.time(0,0,0),
3134 3138 endTime=datetime.time(23,59,59),
3135 3139 set=0,
3136 3140 expLabel = "",
3137 3141 ext = None,
3138 3142 online = False,
3139 3143 delay = 60,
3140 3144 walk = True):
3141 3145
3142 3146 if path == None:
3143 3147 raise ValueError, "The path is not valid"
3144 3148
3145 3149 if ext == None:
3146 3150 ext = self.ext
3147 3151
3148 3152 if not(online):
3149 3153 print "Searching files in offline mode ..."
3150 3154 pathList, filenameList = self.__searchFilesOffLine(path, startDate=startDate, endDate=endDate,
3151 3155 startTime=startTime, endTime=endTime,
3152 3156 set=set, expLabel=expLabel, ext=ext,
3153 3157 walk=walk)
3154 3158
3155 3159 if not(pathList):
3156 3160 print "No *%s files into the folder %s \nfor the range: %s - %s"%(ext, path,
3157 3161 datetime.datetime.combine(startDate,startTime).ctime(),
3158 3162 datetime.datetime.combine(endDate,endTime).ctime())
3159 3163
3160 3164 sys.exit(-1)
3161 3165
3162 3166 self.fileIndex = -1
3163 3167 self.pathList = pathList
3164 3168 self.filenameList = filenameList
3165 3169
3166 3170 self.online = online
3167 3171 self.delay = delay
3168 3172 ext = ext.lower()
3169 3173 self.ext = ext
3170 3174
3171 3175 if not(self.setNextFile()):
3172 3176 if (startDate!=None) and (endDate!=None):
3173 3177 print "No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
3174 3178 elif startDate != None:
3175 3179 print "No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime())
3176 3180 else:
3177 3181 print "No files"
3178 3182
3179 3183 sys.exit(-1)
3180 3184
3181 3185
3182 3186
3183 3187 def readBlock(self):
3184 3188 dataObj = self.fitsObj[self.blockIndex]
3185 3189
3186 3190 self.data = dataObj.data
3187 3191 self.data_header_dict = dataObj.header
3188 3192 self.utc = self.data_header_dict['UTCTIME']
3189 3193
3190 3194 self.flagIsNewFile = 0
3191 3195 self.blockIndex += 1
3192 3196 self.nTotalBlocks += 1
3193 3197 self.nReadBlocks += 1
3194 3198
3195 3199 return 1
3196 3200
3197 3201 def __jumpToLastBlock(self):
3198 3202 raise ValueError, "No implemented"
3199 3203
3200 3204 def __waitNewBlock(self):
3201 3205 """
3202 3206 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
3203 3207
3204 3208 Si el modo de lectura es OffLine siempre retorn 0
3205 3209 """
3206 3210 if not self.online:
3207 3211 return 0
3208 3212
3209 3213 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
3210 3214 return 0
3211 3215
3212 3216 currentPointer = self.fp.tell()
3213 3217
3214 3218 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
3215 3219
3216 3220 for nTries in range( self.nTries ):
3217 3221
3218 3222 self.fp.close()
3219 3223 self.fp = open( self.filename, 'rb' )
3220 3224 self.fp.seek( currentPointer )
3221 3225
3222 3226 self.fileSize = os.path.getsize( self.filename )
3223 3227 currentSize = self.fileSize - currentPointer
3224 3228
3225 3229 if ( currentSize >= neededSize ):
3226 3230 self.__rdBasicHeader()
3227 3231 return 1
3228 3232
3229 3233 print "\tWaiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1)
3230 3234 time.sleep( self.delay )
3231 3235
3232 3236
3233 3237 return 0
3234 3238
3235 3239 def __setNewBlock(self):
3236 3240
3237 3241 if self.online:
3238 3242 self.__jumpToLastBlock()
3239 3243
3240 3244 if self.flagIsNewFile:
3241 3245 return 1
3242 3246
3243 3247 self.lastUTTime = self.utc
3244 3248
3245 3249 if self.online:
3246 3250 if self.__waitNewBlock():
3247 3251 return 1
3248 3252
3249 3253 if self.nReadBlocks < self.dataBlocksPerFile:
3250 3254 return 1
3251 3255
3252 3256 if not(self.setNextFile()):
3253 3257 return 0
3254 3258
3255 3259 deltaTime = self.utc - self.lastUTTime
3256 3260
3257 3261 self.flagTimeBlock = 0
3258 3262
3259 3263 if deltaTime > self.maxTimeStep:
3260 3264 self.flagTimeBlock = 1
3261 3265
3262 3266 return 1
3263 3267
3264 3268
3265 3269 def readNextBlock(self):
3266 3270 if not(self.__setNewBlock()):
3267 3271 return 0
3268 3272
3269 3273 if not(self.readBlock()):
3270 3274 return 0
3271 3275
3272 3276 return 1
3273 3277
3274 3278
3275 3279 def getData(self):
3276 3280
3277 3281 if self.flagNoMoreFiles:
3278 3282 self.dataOut.flagNoData = True
3279 3283 print 'Process finished'
3280 3284 return 0
3281 3285
3282 3286 self.flagTimeBlock = 0
3283 3287 self.flagIsNewBlock = 0
3284 3288
3285 3289 if not(self.readNextBlock()):
3286 3290 return 0
3287 3291
3288 3292 if self.data == None:
3289 3293 self.dataOut.flagNoData = True
3290 3294 return 0
3291 3295
3292 3296 self.dataOut.data = self.data
3293 3297 self.dataOut.data_header = self.data_header_dict
3294 3298 self.dataOut.utctime = self.utc
3295 3299
3296 3300 self.dataOut.header = self.header_dict
3297 3301 self.dataOut.expName = self.expName
3298 3302 self.dataOut.nChannels = self.nChannels
3299 3303 self.dataOut.nSamples = self.nSamples
3300 3304 self.dataOut.dataBlocksPerFile = self.dataBlocksPerFile
3301 3305 self.dataOut.comments = self.comments
3302 3306
3303 3307 self.dataOut.flagNoData = False
3304 3308
3305 3309 return self.dataOut.data
3306 3310
3307 3311 def run(self, **kwargs):
3308 3312
3309 3313 if not(self.isConfig):
3310 3314 self.setup(**kwargs)
3311 3315 self.isConfig = True
3312 3316
3313 3317 self.getData() No newline at end of file
@@ -1,1343 +1,1354
1 1 import numpy
2 2 import time, datetime, os
3 3 from graphics.figure import *
4 def isRealtime(utcdatatime):
5 utcnow = time.mktime(datetime.datetime.utcnow().timetuple())
6 delta = utcnow - utcdatatime # abs
7 if delta >= 5*60.:
8 return False
9 return True
4 10
5 11 class CrossSpectraPlot(Figure):
6 12
7 13 __isConfig = None
8 14 __nsubplots = None
9 15
10 16 WIDTH = None
11 17 HEIGHT = None
12 18 WIDTHPROF = None
13 19 HEIGHTPROF = None
14 20 PREFIX = 'cspc'
15 21
16 22 def __init__(self):
17 23
18 24 self.__isConfig = False
19 25 self.__nsubplots = 4
20 26
21 27 self.WIDTH = 250
22 28 self.HEIGHT = 250
23 29 self.WIDTHPROF = 0
24 30 self.HEIGHTPROF = 0
25 31
26 32 def getSubplots(self):
27 33
28 34 ncol = 4
29 35 nrow = self.nplots
30 36
31 37 return nrow, ncol
32 38
33 39 def setup(self, idfigure, nplots, wintitle, showprofile=True, show=True):
34 40
35 41 self.__showprofile = showprofile
36 42 self.nplots = nplots
37 43
38 44 ncolspan = 1
39 45 colspan = 1
40 46
41 47 self.createFigure(idfigure = idfigure,
42 48 wintitle = wintitle,
43 49 widthplot = self.WIDTH + self.WIDTHPROF,
44 50 heightplot = self.HEIGHT + self.HEIGHTPROF,
45 51 show=True)
46 52
47 53 nrow, ncol = self.getSubplots()
48 54
49 55 counter = 0
50 56 for y in range(nrow):
51 57 for x in range(ncol):
52 58 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
53 59
54 60 counter += 1
55 61
56 62 def run(self, dataOut, idfigure, wintitle="", pairsList=None, showprofile='True',
57 63 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
58 64 save=False, figpath='./', figfile=None,
59 65 power_cmap='jet', coherence_cmap='jet', phase_cmap='RdBu_r', show=True):
60 66
61 67 """
62 68
63 69 Input:
64 70 dataOut :
65 71 idfigure :
66 72 wintitle :
67 73 channelList :
68 74 showProfile :
69 75 xmin : None,
70 76 xmax : None,
71 77 ymin : None,
72 78 ymax : None,
73 79 zmin : None,
74 80 zmax : None
75 81 """
76 82
77 83 if pairsList == None:
78 84 pairsIndexList = dataOut.pairsIndexList
79 85 else:
80 86 pairsIndexList = []
81 87 for pair in pairsList:
82 88 if pair not in dataOut.pairsList:
83 89 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
84 90 pairsIndexList.append(dataOut.pairsList.index(pair))
85 91
86 92 if pairsIndexList == []:
87 93 return
88 94
89 95 if len(pairsIndexList) > 4:
90 96 pairsIndexList = pairsIndexList[0:4]
91 97 factor = dataOut.normFactor
92 98 x = dataOut.getVelRange(1)
93 99 y = dataOut.getHeiRange()
94 100 z = dataOut.data_spc[:,:,:]/factor
95 101 # z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
96 102 avg = numpy.abs(numpy.average(z, axis=1))
97 103 noise = dataOut.getNoise()/factor
98 104
99 105 zdB = 10*numpy.log10(z)
100 106 avgdB = 10*numpy.log10(avg)
101 107 noisedB = 10*numpy.log10(noise)
102 108
103 109
104 110 thisDatetime = dataOut.datatime
105 111 title = "Cross-Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
106 112 xlabel = "Velocity (m/s)"
107 113 ylabel = "Range (Km)"
108 114
109 115 if not self.__isConfig:
110 116
111 117 nplots = len(pairsIndexList)
112 118
113 119 self.setup(idfigure=idfigure,
114 120 nplots=nplots,
115 121 wintitle=wintitle,
116 122 showprofile=showprofile,
117 123 show=show)
118 124
119 125 if xmin == None: xmin = numpy.nanmin(x)
120 126 if xmax == None: xmax = numpy.nanmax(x)
121 127 if ymin == None: ymin = numpy.nanmin(y)
122 128 if ymax == None: ymax = numpy.nanmax(y)
123 129 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
124 130 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
125 131
126 132 self.__isConfig = True
127 133
128 134 self.setWinTitle(title)
129 135
130 136 for i in range(self.nplots):
131 137 pair = dataOut.pairsList[pairsIndexList[i]]
132 138
133 139 title = "Channel %d: %4.2fdB" %(pair[0], noisedB[pair[0]])
134 140 zdB = 10.*numpy.log10(dataOut.data_spc[pair[0],:,:]/factor)
135 141 axes0 = self.axesList[i*self.__nsubplots]
136 142 axes0.pcolor(x, y, zdB,
137 143 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
138 144 xlabel=xlabel, ylabel=ylabel, title=title,
139 145 ticksize=9, colormap=power_cmap, cblabel='')
140 146
141 147 title = "Channel %d: %4.2fdB" %(pair[1], noisedB[pair[1]])
142 148 zdB = 10.*numpy.log10(dataOut.data_spc[pair[1],:,:]/factor)
143 149 axes0 = self.axesList[i*self.__nsubplots+1]
144 150 axes0.pcolor(x, y, zdB,
145 151 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
146 152 xlabel=xlabel, ylabel=ylabel, title=title,
147 153 ticksize=9, colormap=power_cmap, cblabel='')
148 154
149 155 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[pair[0],:,:]*dataOut.data_spc[pair[1],:,:])
150 156 coherence = numpy.abs(coherenceComplex)
151 157 # phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
152 158 phase = numpy.arctan2(coherenceComplex.imag, coherenceComplex.real)*180/numpy.pi
153 159
154 160 title = "Coherence %d%d" %(pair[0], pair[1])
155 161 axes0 = self.axesList[i*self.__nsubplots+2]
156 162 axes0.pcolor(x, y, coherence,
157 163 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=0, zmax=1,
158 164 xlabel=xlabel, ylabel=ylabel, title=title,
159 165 ticksize=9, colormap=coherence_cmap, cblabel='')
160 166
161 167 title = "Phase %d%d" %(pair[0], pair[1])
162 168 axes0 = self.axesList[i*self.__nsubplots+3]
163 169 axes0.pcolor(x, y, phase,
164 170 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=-180, zmax=180,
165 171 xlabel=xlabel, ylabel=ylabel, title=title,
166 172 ticksize=9, colormap=phase_cmap, cblabel='')
167 173
168 174
169 175
170 176 self.draw()
171 177
172 178 if save:
173 179 date = thisDatetime.strftime("%Y%m%d_%H%M%S")
174 180 if figfile == None:
175 181 figfile = self.getFilename(name = date)
176 182
177 183 self.saveFigure(figpath, figfile)
178 184
179 185
180 186 class RTIPlot(Figure):
181 187
182 188 __isConfig = None
183 189 __nsubplots = None
184 190
185 191 WIDTHPROF = None
186 192 HEIGHTPROF = None
187 193 PREFIX = 'rti'
188 194
189 195 def __init__(self):
190 196
191 197 self.timerange = 2*60*60
192 198 self.__isConfig = False
193 199 self.__nsubplots = 1
194 200
195 201 self.WIDTH = 800
196 202 self.HEIGHT = 150
197 203 self.WIDTHPROF = 120
198 204 self.HEIGHTPROF = 0
199 205 self.counterftp = 0
200 206
201 207 def getSubplots(self):
202 208
203 209 ncol = 1
204 210 nrow = self.nplots
205 211
206 212 return nrow, ncol
207 213
208 214 def setup(self, idfigure, nplots, wintitle, showprofile=True, show=True):
209 215
210 216 self.__showprofile = showprofile
211 217 self.nplots = nplots
212 218
213 219 ncolspan = 1
214 220 colspan = 1
215 221 if showprofile:
216 222 ncolspan = 7
217 223 colspan = 6
218 224 self.__nsubplots = 2
219 225
220 226 self.createFigure(idfigure = idfigure,
221 227 wintitle = wintitle,
222 228 widthplot = self.WIDTH + self.WIDTHPROF,
223 229 heightplot = self.HEIGHT + self.HEIGHTPROF,
224 230 show=show)
225 231
226 232 nrow, ncol = self.getSubplots()
227 233
228 234 counter = 0
229 235 for y in range(nrow):
230 236 for x in range(ncol):
231 237
232 238 if counter >= self.nplots:
233 239 break
234 240
235 241 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
236 242
237 243 if showprofile:
238 244 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
239 245
240 246 counter += 1
241 247
242 248 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
243 249 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
244 250 timerange=None,
245 251 save=False, figpath='./', figfile=None, ftp=False, ftpratio=1, show=True):
246 252
247 253 """
248 254
249 255 Input:
250 256 dataOut :
251 257 idfigure :
252 258 wintitle :
253 259 channelList :
254 260 showProfile :
255 261 xmin : None,
256 262 xmax : None,
257 263 ymin : None,
258 264 ymax : None,
259 265 zmin : None,
260 266 zmax : None
261 267 """
262 268
263 269 if channelList == None:
264 270 channelIndexList = dataOut.channelIndexList
265 271 else:
266 272 channelIndexList = []
267 273 for channel in channelList:
268 274 if channel not in dataOut.channelList:
269 275 raise ValueError, "Channel %d is not in dataOut.channelList"
270 276 channelIndexList.append(dataOut.channelList.index(channel))
271 277
272 278 if timerange != None:
273 279 self.timerange = timerange
274 280
275 281 tmin = None
276 282 tmax = None
277 283 factor = dataOut.normFactor
278 284 x = dataOut.getTimeRange()
279 285 y = dataOut.getHeiRange()
280 286
281 287 z = dataOut.data_spc[channelIndexList,:,:]/factor
282 288 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
283 289 avg = numpy.average(z, axis=1)
284 290
285 291 avgdB = 10.*numpy.log10(avg)
286 292
287 293
288 294 thisDatetime = dataOut.datatime
289 295 title = "RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
290 296 xlabel = ""
291 297 ylabel = "Range (Km)"
292 298
293 299 if not self.__isConfig:
294 300
295 301 nplots = len(channelIndexList)
296 302
297 303 self.setup(idfigure=idfigure,
298 304 nplots=nplots,
299 305 wintitle=wintitle,
300 306 showprofile=showprofile,
301 307 show=show)
302 308
303 309 tmin, tmax = self.getTimeLim(x, xmin, xmax)
304 310 if ymin == None: ymin = numpy.nanmin(y)
305 311 if ymax == None: ymax = numpy.nanmax(y)
306 312 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
307 313 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
308 314
309 315 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
310 316 self.__isConfig = True
311 317
312 318
313 319 self.setWinTitle(title)
314 320
315 321 for i in range(self.nplots):
316 322 title = "Channel %d: %s" %(dataOut.channelList[i], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
317 323 axes = self.axesList[i*self.__nsubplots]
318 324 zdB = avgdB[i].reshape((1,-1))
319 325 axes.pcolorbuffer(x, y, zdB,
320 326 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
321 327 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
322 328 ticksize=9, cblabel='', cbsize="1%")
323 329
324 330 if self.__showprofile:
325 331 axes = self.axesList[i*self.__nsubplots +1]
326 332 axes.pline(avgdB[i], y,
327 333 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
328 334 xlabel='dB', ylabel='', title='',
329 335 ytick_visible=False,
330 336 grid='x')
331 337
332 338 self.draw()
333 339
334 340 if save:
335 341
336 342 if figfile == None:
337 343 figfile = self.getFilename(name = self.name)
338 344
339 345 self.saveFigure(figpath, figfile)
340 346
341 347 self.counterftp += 1
342 348 if (ftp and (self.counterftp==ftpratio)):
343 349 figfilename = os.path.join(figpath,figfile)
344 350 self.sendByFTP(figfilename)
345 351 self.counterftp = 0
346 352
347 353 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
348 354 self.__isConfig = False
349 355
350 356 class SpectraPlot(Figure):
351 357
352 358 __isConfig = None
353 359 __nsubplots = None
354 360
355 361 WIDTHPROF = None
356 362 HEIGHTPROF = None
357 363 PREFIX = 'spc'
358 364
359 365 def __init__(self):
360 366
361 367 self.__isConfig = False
362 368 self.__nsubplots = 1
363 369
364 370 self.WIDTH = 230
365 371 self.HEIGHT = 250
366 372 self.WIDTHPROF = 120
367 373 self.HEIGHTPROF = 0
368 374
369 375 def getSubplots(self):
370 376
371 377 ncol = int(numpy.sqrt(self.nplots)+0.9)
372 378 nrow = int(self.nplots*1./ncol + 0.9)
373 379
374 380 return nrow, ncol
375 381
376 382 def setup(self, idfigure, nplots, wintitle, showprofile=True, show=True):
377 383
378 384 self.__showprofile = showprofile
379 385 self.nplots = nplots
380 386
381 387 ncolspan = 1
382 388 colspan = 1
383 389 if showprofile:
384 390 ncolspan = 3
385 391 colspan = 2
386 392 self.__nsubplots = 2
387 393
388 394 self.createFigure(idfigure = idfigure,
389 395 wintitle = wintitle,
390 396 widthplot = self.WIDTH + self.WIDTHPROF,
391 397 heightplot = self.HEIGHT + self.HEIGHTPROF,
392 398 show=show)
393 399
394 400 nrow, ncol = self.getSubplots()
395 401
396 402 counter = 0
397 403 for y in range(nrow):
398 404 for x in range(ncol):
399 405
400 406 if counter >= self.nplots:
401 407 break
402 408
403 409 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
404 410
405 411 if showprofile:
406 412 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
407 413
408 414 counter += 1
409 415
410 416 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
411 417 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
412 418 save=False, figpath='./', figfile=None, show=True):
413 419
414 420 """
415 421
416 422 Input:
417 423 dataOut :
418 424 idfigure :
419 425 wintitle :
420 426 channelList :
421 427 showProfile :
422 428 xmin : None,
423 429 xmax : None,
424 430 ymin : None,
425 431 ymax : None,
426 432 zmin : None,
427 433 zmax : None
428 434 """
429 435
430 436 if channelList == None:
431 437 channelIndexList = dataOut.channelIndexList
432 438 else:
433 439 channelIndexList = []
434 440 for channel in channelList:
435 441 if channel not in dataOut.channelList:
436 442 raise ValueError, "Channel %d is not in dataOut.channelList"
437 443 channelIndexList.append(dataOut.channelList.index(channel))
438 444 factor = dataOut.normFactor
439 445 x = dataOut.getVelRange(1)
440 446 y = dataOut.getHeiRange()
441 447
442 448 z = dataOut.data_spc[channelIndexList,:,:]/factor
443 449 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
444 450 avg = numpy.average(z, axis=1)
445 451 noise = dataOut.getNoise()/factor
446 452
447 453 zdB = 10*numpy.log10(z)
448 454 avgdB = 10*numpy.log10(avg)
449 455 noisedB = 10*numpy.log10(noise)
450 456
451 457 thisDatetime = dataOut.datatime
452 458 title = "Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
453 459 xlabel = "Velocity (m/s)"
454 460 ylabel = "Range (Km)"
455 461
456 462 if not self.__isConfig:
457 463
458 464 nplots = len(channelIndexList)
459 465
460 466 self.setup(idfigure=idfigure,
461 467 nplots=nplots,
462 468 wintitle=wintitle,
463 469 showprofile=showprofile,
464 470 show=show)
465 471
466 472 if xmin == None: xmin = numpy.nanmin(x)
467 473 if xmax == None: xmax = numpy.nanmax(x)
468 474 if ymin == None: ymin = numpy.nanmin(y)
469 475 if ymax == None: ymax = numpy.nanmax(y)
470 476 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
471 477 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
472 478
473 479 self.__isConfig = True
474 480
475 481 self.setWinTitle(title)
476 482
477 483 for i in range(self.nplots):
478 484 title = "Channel %d: %4.2fdB" %(dataOut.channelList[i], noisedB[i])
479 485 axes = self.axesList[i*self.__nsubplots]
480 486 axes.pcolor(x, y, zdB[i,:,:],
481 487 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
482 488 xlabel=xlabel, ylabel=ylabel, title=title,
483 489 ticksize=9, cblabel='')
484 490
485 491 if self.__showprofile:
486 492 axes = self.axesList[i*self.__nsubplots +1]
487 493 axes.pline(avgdB[i], y,
488 494 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
489 495 xlabel='dB', ylabel='', title='',
490 496 ytick_visible=False,
491 497 grid='x')
492 498
493 499 noiseline = numpy.repeat(noisedB[i], len(y))
494 500 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
495 501
496 502 self.draw()
497 503
498 504 if save:
499 505 date = thisDatetime.strftime("%Y%m%d_%H%M%S")
500 506 if figfile == None:
501 507 figfile = self.getFilename(name = date)
502 508
503 509 self.saveFigure(figpath, figfile)
504 510
505 511 class Scope(Figure):
506 512
507 513 __isConfig = None
508 514
509 515 def __init__(self):
510 516
511 517 self.__isConfig = False
512 518 self.WIDTH = 600
513 519 self.HEIGHT = 200
514 520
515 521 def getSubplots(self):
516 522
517 523 nrow = self.nplots
518 524 ncol = 3
519 525 return nrow, ncol
520 526
521 527 def setup(self, idfigure, nplots, wintitle, show):
522 528
523 529 self.nplots = nplots
524 530
525 531 self.createFigure(idfigure=idfigure,
526 532 wintitle=wintitle,
527 533 show=show)
528 534
529 535 nrow,ncol = self.getSubplots()
530 536 colspan = 3
531 537 rowspan = 1
532 538
533 539 for i in range(nplots):
534 540 self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
535 541
536 542
537 543
538 544 def run(self, dataOut, idfigure, wintitle="", channelList=None,
539 545 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
540 546 figpath='./', figfile=None, show=True):
541 547
542 548 """
543 549
544 550 Input:
545 551 dataOut :
546 552 idfigure :
547 553 wintitle :
548 554 channelList :
549 555 xmin : None,
550 556 xmax : None,
551 557 ymin : None,
552 558 ymax : None,
553 559 """
554 560
555 561 if channelList == None:
556 562 channelIndexList = dataOut.channelIndexList
557 563 else:
558 564 channelIndexList = []
559 565 for channel in channelList:
560 566 if channel not in dataOut.channelList:
561 567 raise ValueError, "Channel %d is not in dataOut.channelList"
562 568 channelIndexList.append(dataOut.channelList.index(channel))
563 569
564 570 x = dataOut.heightList
565 571 y = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
566 572 y = y.real
567 573
568 574 thisDatetime = dataOut.datatime
569 575 title = "Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
570 576 xlabel = "Range (Km)"
571 577 ylabel = "Intensity"
572 578
573 579 if not self.__isConfig:
574 580 nplots = len(channelIndexList)
575 581
576 582 self.setup(idfigure=idfigure,
577 583 nplots=nplots,
578 584 wintitle=wintitle,
579 585 show=show)
580 586
581 587 if xmin == None: xmin = numpy.nanmin(x)
582 588 if xmax == None: xmax = numpy.nanmax(x)
583 589 if ymin == None: ymin = numpy.nanmin(y)
584 590 if ymax == None: ymax = numpy.nanmax(y)
585 591
586 592 self.__isConfig = True
587 593
588 594 self.setWinTitle(title)
589 595
590 596 for i in range(len(self.axesList)):
591 597 title = "Channel %d" %(i)
592 598 axes = self.axesList[i]
593 599 ychannel = y[i,:]
594 600 axes.pline(x, ychannel,
595 601 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
596 602 xlabel=xlabel, ylabel=ylabel, title=title)
597 603
598 604 self.draw()
599 605
600 606 if save:
601 607 date = thisDatetime.strftime("%Y%m%d_%H%M%S")
602 608 if figfile == None:
603 609 figfile = self.getFilename(name = date)
604 610
605 611 self.saveFigure(figpath, figfile)
606 612
607 613 class ProfilePlot(Figure):
608 614 __isConfig = None
609 615 __nsubplots = None
610 616
611 617 WIDTHPROF = None
612 618 HEIGHTPROF = None
613 619 PREFIX = 'spcprofile'
614 620
615 621 def __init__(self):
616 622 self.__isConfig = False
617 623 self.__nsubplots = 1
618 624
619 625 self.WIDTH = 300
620 626 self.HEIGHT = 500
621 627
622 628 def getSubplots(self):
623 629 ncol = 1
624 630 nrow = 1
625 631
626 632 return nrow, ncol
627 633
628 634 def setup(self, idfigure, nplots, wintitle, show):
629 635
630 636 self.nplots = nplots
631 637
632 638 ncolspan = 1
633 639 colspan = 1
634 640
635 641 self.createFigure(idfigure = idfigure,
636 642 wintitle = wintitle,
637 643 widthplot = self.WIDTH,
638 644 heightplot = self.HEIGHT,
639 645 show=show)
640 646
641 647 nrow, ncol = self.getSubplots()
642 648
643 649 counter = 0
644 650 for y in range(nrow):
645 651 for x in range(ncol):
646 652 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
647 653
648 654 def run(self, dataOut, idfigure, wintitle="", channelList=None,
649 655 xmin=None, xmax=None, ymin=None, ymax=None,
650 656 save=False, figpath='./', figfile=None, show=True):
651 657
652 658 if channelList == None:
653 659 channelIndexList = dataOut.channelIndexList
654 660 channelList = dataOut.channelList
655 661 else:
656 662 channelIndexList = []
657 663 for channel in channelList:
658 664 if channel not in dataOut.channelList:
659 665 raise ValueError, "Channel %d is not in dataOut.channelList"
660 666 channelIndexList.append(dataOut.channelList.index(channel))
661 667
662 668 factor = dataOut.normFactor
663 669 y = dataOut.getHeiRange()
664 670 x = dataOut.data_spc[channelIndexList,:,:]/factor
665 671 x = numpy.where(numpy.isfinite(x), x, numpy.NAN)
666 672 avg = numpy.average(x, axis=1)
667 673
668 674 avgdB = 10*numpy.log10(avg)
669 675
670 676 thisDatetime = dataOut.datatime
671 677 title = "Power Profile"
672 678 xlabel = "dB"
673 679 ylabel = "Range (Km)"
674 680
675 681 if not self.__isConfig:
676 682
677 683 nplots = 1
678 684
679 685 self.setup(idfigure=idfigure,
680 686 nplots=nplots,
681 687 wintitle=wintitle,
682 688 show=show)
683 689
684 690 if ymin == None: ymin = numpy.nanmin(y)
685 691 if ymax == None: ymax = numpy.nanmax(y)
686 692 if xmin == None: xmin = numpy.nanmin(avgdB)*0.9
687 693 if xmax == None: xmax = numpy.nanmax(avgdB)*0.9
688 694
689 695 self.__isConfig = True
690 696
691 697 self.setWinTitle(title)
692 698
693 699
694 700 title = "Power Profile: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
695 701 axes = self.axesList[0]
696 702
697 703 legendlabels = ["channel %d"%x for x in channelList]
698 704 axes.pmultiline(avgdB, y,
699 705 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
700 706 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
701 707 ytick_visible=True, nxticks=5,
702 708 grid='x')
703 709
704 710 self.draw()
705 711
706 712 if save:
707 713 date = thisDatetime.strftime("%Y%m%d")
708 714 if figfile == None:
709 715 figfile = self.getFilename(name = date)
710 716
711 717 self.saveFigure(figpath, figfile)
712 718
713 719 class CoherenceMap(Figure):
714 720 __isConfig = None
715 721 __nsubplots = None
716 722
717 723 WIDTHPROF = None
718 724 HEIGHTPROF = None
719 725 PREFIX = 'cmap'
720 726
721 727 def __init__(self):
722 728 self.timerange = 2*60*60
723 729 self.__isConfig = False
724 730 self.__nsubplots = 1
725 731
726 732 self.WIDTH = 800
727 733 self.HEIGHT = 150
728 734 self.WIDTHPROF = 120
729 735 self.HEIGHTPROF = 0
730 736 self.counterftp = 0
731 737
732 738 def getSubplots(self):
733 739 ncol = 1
734 740 nrow = self.nplots*2
735 741
736 742 return nrow, ncol
737 743
738 744 def setup(self, idfigure, nplots, wintitle, showprofile=True, show=True):
739 745 self.__showprofile = showprofile
740 746 self.nplots = nplots
741 747
742 748 ncolspan = 1
743 749 colspan = 1
744 750 if showprofile:
745 751 ncolspan = 7
746 752 colspan = 6
747 753 self.__nsubplots = 2
748 754
749 755 self.createFigure(idfigure = idfigure,
750 756 wintitle = wintitle,
751 757 widthplot = self.WIDTH + self.WIDTHPROF,
752 758 heightplot = self.HEIGHT + self.HEIGHTPROF,
753 759 show=True)
754 760
755 761 nrow, ncol = self.getSubplots()
756 762
757 763 for y in range(nrow):
758 764 for x in range(ncol):
759 765
760 766 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
761 767
762 768 if showprofile:
763 769 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
764 770
765 771 def run(self, dataOut, idfigure, wintitle="", pairsList=None, showprofile='True',
766 772 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
767 773 timerange=None,
768 774 save=False, figpath='./', figfile=None, ftp=False, ftpratio=1,
769 775 coherence_cmap='jet', phase_cmap='RdBu_r', show=True):
770 776
771 777 if pairsList == None:
772 778 pairsIndexList = dataOut.pairsIndexList
773 779 else:
774 780 pairsIndexList = []
775 781 for pair in pairsList:
776 782 if pair not in dataOut.pairsList:
777 783 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
778 784 pairsIndexList.append(dataOut.pairsList.index(pair))
779 785
780 786 if timerange != None:
781 787 self.timerange = timerange
782 788
783 789 if pairsIndexList == []:
784 790 return
785 791
786 792 if len(pairsIndexList) > 4:
787 793 pairsIndexList = pairsIndexList[0:4]
788 794
789 795 tmin = None
790 796 tmax = None
791 797 x = dataOut.getTimeRange()
792 798 y = dataOut.getHeiRange()
793 799
794 800 thisDatetime = dataOut.datatime
795 801 title = "CoherenceMap: %s" %(thisDatetime.strftime("%d-%b-%Y"))
796 802 xlabel = ""
797 803 ylabel = "Range (Km)"
798 804
799 805 if not self.__isConfig:
800 806 nplots = len(pairsIndexList)
801 807 self.setup(idfigure=idfigure,
802 808 nplots=nplots,
803 809 wintitle=wintitle,
804 810 showprofile=showprofile,
805 811 show=show)
806 812
807 813 tmin, tmax = self.getTimeLim(x, xmin, xmax)
808 814 if ymin == None: ymin = numpy.nanmin(y)
809 815 if ymax == None: ymax = numpy.nanmax(y)
810 816
811 817 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
812 818
813 819 self.__isConfig = True
814 820
815 821 self.setWinTitle(title)
816 822
817 823 for i in range(self.nplots):
818 824
819 825 pair = dataOut.pairsList[pairsIndexList[i]]
820 826 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[pair[0],:,:]*dataOut.data_spc[pair[1],:,:])
821 827 avgcoherenceComplex = numpy.average(coherenceComplex, axis=0)
822 828 coherence = numpy.abs(avgcoherenceComplex)
823 829 # coherence = numpy.abs(coherenceComplex)
824 830 # avg = numpy.average(coherence, axis=0)
825 831
826 832 z = coherence.reshape((1,-1))
827 833
828 834 counter = 0
829 835
830 836 title = "Coherence %d%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
831 837 axes = self.axesList[i*self.__nsubplots*2]
832 838 axes.pcolorbuffer(x, y, z,
833 839 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=0, zmax=1,
834 840 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
835 841 ticksize=9, cblabel='', colormap=coherence_cmap, cbsize="1%")
836 842
837 843 if self.__showprofile:
838 844 counter += 1
839 845 axes = self.axesList[i*self.__nsubplots*2 + counter]
840 846 axes.pline(coherence, y,
841 847 xmin=0, xmax=1, ymin=ymin, ymax=ymax,
842 848 xlabel='', ylabel='', title='', ticksize=7,
843 849 ytick_visible=False, nxticks=5,
844 850 grid='x')
845 851
846 852 counter += 1
847 853 # phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
848 854 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
849 855 # avg = numpy.average(phase, axis=0)
850 856 z = phase.reshape((1,-1))
851 857
852 858 title = "Phase %d%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
853 859 axes = self.axesList[i*self.__nsubplots*2 + counter]
854 860 axes.pcolorbuffer(x, y, z,
855 861 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=-180, zmax=180,
856 862 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
857 863 ticksize=9, cblabel='', colormap=phase_cmap, cbsize="1%")
858 864
859 865 if self.__showprofile:
860 866 counter += 1
861 867 axes = self.axesList[i*self.__nsubplots*2 + counter]
862 868 axes.pline(phase, y,
863 869 xmin=-180, xmax=180, ymin=ymin, ymax=ymax,
864 870 xlabel='', ylabel='', title='', ticksize=7,
865 871 ytick_visible=False, nxticks=4,
866 872 grid='x')
867 873
868 874 self.draw()
869 875
870 876 if save:
871 877
872 878 if figfile == None:
873 879 figfile = self.getFilename(name = self.name)
874 880
875 881 self.saveFigure(figpath, figfile)
876 882
877 883 self.counterftp += 1
878 884 if (ftp and (self.counterftp==ftpratio)):
879 885 figfilename = os.path.join(figpath,figfile)
880 886 self.sendByFTP(figfilename)
881 887 self.counterftp = 0
882 888
883 889 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
884 890 self.__isConfig = False
885 891
886 892 class RTIfromNoise(Figure):
887 893
888 894 __isConfig = None
889 895 __nsubplots = None
890 896
891 897 PREFIX = 'rtinoise'
892 898
893 899 def __init__(self):
894 900
895 901 self.timerange = 24*60*60
896 902 self.__isConfig = False
897 903 self.__nsubplots = 1
898 904
899 905 self.WIDTH = 820
900 906 self.HEIGHT = 200
901 907 self.WIDTHPROF = 120
902 908 self.HEIGHTPROF = 0
903 909 self.xdata = None
904 910 self.ydata = None
905 911
906 912 def getSubplots(self):
907 913
908 914 ncol = 1
909 915 nrow = 1
910 916
911 917 return nrow, ncol
912 918
913 919 def setup(self, idfigure, nplots, wintitle, showprofile=True, show=True):
914 920
915 921 self.__showprofile = showprofile
916 922 self.nplots = nplots
917 923
918 924 ncolspan = 7
919 925 colspan = 6
920 926 self.__nsubplots = 2
921 927
922 928 self.createFigure(idfigure = idfigure,
923 929 wintitle = wintitle,
924 930 widthplot = self.WIDTH+self.WIDTHPROF,
925 931 heightplot = self.HEIGHT+self.HEIGHTPROF,
926 932 show=show)
927 933
928 934 nrow, ncol = self.getSubplots()
929 935
930 936 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
931 937
932 938
933 939 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
934 940 xmin=None, xmax=None, ymin=None, ymax=None,
935 941 timerange=None,
936 942 save=False, figpath='./', figfile=None, show=True):
937 943
938 944 if channelList == None:
939 945 channelIndexList = dataOut.channelIndexList
940 946 channelList = dataOut.channelList
941 947 else:
942 948 channelIndexList = []
943 949 for channel in channelList:
944 950 if channel not in dataOut.channelList:
945 951 raise ValueError, "Channel %d is not in dataOut.channelList"
946 952 channelIndexList.append(dataOut.channelList.index(channel))
947 953
948 954 if timerange != None:
949 955 self.timerange = timerange
950 956
951 957 tmin = None
952 958 tmax = None
953 959 x = dataOut.getTimeRange()
954 960 y = dataOut.getHeiRange()
955 961 factor = dataOut.normFactor
956 962 noise = dataOut.getNoise()/factor
957 963 noisedB = 10*numpy.log10(noise)
958 964
959 965 thisDatetime = dataOut.datatime
960 966 title = "RTI Noise: %s" %(thisDatetime.strftime("%d-%b-%Y"))
961 967 xlabel = ""
962 968 ylabel = "Range (Km)"
963 969
964 970 if not self.__isConfig:
965 971
966 972 nplots = 1
967 973
968 974 self.setup(idfigure=idfigure,
969 975 nplots=nplots,
970 976 wintitle=wintitle,
971 977 showprofile=showprofile,
972 978 show=show)
973 979
974 980 tmin, tmax = self.getTimeLim(x, xmin, xmax)
975 981 if ymin == None: ymin = numpy.nanmin(noisedB)
976 982 if ymax == None: ymax = numpy.nanmax(noisedB)
977 983
978 984 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
979 985 self.__isConfig = True
980 986
981 987 self.xdata = numpy.array([])
982 988 self.ydata = numpy.array([])
983 989
984 990 self.setWinTitle(title)
985 991
986 992
987 993 title = "RTI Noise %s" %(thisDatetime.strftime("%d-%b-%Y"))
988 994
989 995 legendlabels = ["channel %d"%idchannel for idchannel in channelList]
990 996 axes = self.axesList[0]
991 997
992 998 self.xdata = numpy.hstack((self.xdata, x[0:1]))
993 999
994 1000 if len(self.ydata)==0:
995 1001 self.ydata = noisedB[channelIndexList].reshape(-1,1)
996 1002 else:
997 1003 self.ydata = numpy.hstack((self.ydata, noisedB[channelIndexList].reshape(-1,1)))
998 1004
999 1005
1000 1006 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1001 1007 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax,
1002 1008 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1003 1009 XAxisAsTime=True
1004 1010 )
1005 1011
1006 1012 self.draw()
1007 1013
1008 1014 if save:
1009 1015
1010 1016 if figfile == None:
1011 1017 figfile = self.getFilename(name = self.name)
1012 1018
1013 1019 self.saveFigure(figpath, figfile)
1014 1020
1015 1021 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
1016 1022 self.__isConfig = False
1017 1023 del self.xdata
1018 1024 del self.ydata
1019 1025
1020 1026
1021 1027 class SpectraHeisScope(Figure):
1022 1028
1023 1029
1024 1030 __isConfig = None
1025 1031 __nsubplots = None
1026 1032
1027 1033 WIDTHPROF = None
1028 1034 HEIGHTPROF = None
1029 1035 PREFIX = 'spc'
1030 1036
1031 1037 def __init__(self):
1032 1038
1033 1039 self.__isConfig = False
1034 1040 self.__nsubplots = 1
1035 1041
1036 1042 self.WIDTH = 230
1037 1043 self.HEIGHT = 250
1038 1044 self.WIDTHPROF = 120
1039 1045 self.HEIGHTPROF = 0
1040 1046 self.counterftp = 0
1041 1047
1042 1048 def getSubplots(self):
1043 1049
1044 1050 ncol = int(numpy.sqrt(self.nplots)+0.9)
1045 1051 nrow = int(self.nplots*1./ncol + 0.9)
1046 1052
1047 1053 return nrow, ncol
1048 1054
1049 1055 def setup(self, idfigure, nplots, wintitle, show):
1050 1056
1051 1057 showprofile = False
1052 1058 self.__showprofile = showprofile
1053 1059 self.nplots = nplots
1054 1060
1055 1061 ncolspan = 1
1056 1062 colspan = 1
1057 1063 if showprofile:
1058 1064 ncolspan = 3
1059 1065 colspan = 2
1060 1066 self.__nsubplots = 2
1061 1067
1062 1068 self.createFigure(idfigure = idfigure,
1063 1069 wintitle = wintitle,
1064 1070 widthplot = self.WIDTH + self.WIDTHPROF,
1065 1071 heightplot = self.HEIGHT + self.HEIGHTPROF,
1066 1072 show = show)
1067 1073
1068 1074 nrow, ncol = self.getSubplots()
1069 1075
1070 1076 counter = 0
1071 1077 for y in range(nrow):
1072 1078 for x in range(ncol):
1073 1079
1074 1080 if counter >= self.nplots:
1075 1081 break
1076 1082
1077 1083 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1078 1084
1079 1085 if showprofile:
1080 1086 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1081 1087
1082 1088 counter += 1
1083 1089
1084 1090 # __isConfig = None
1085 1091 # def __init__(self):
1086 1092 #
1087 1093 # self.__isConfig = False
1088 1094 # self.WIDTH = 600
1089 1095 # self.HEIGHT = 200
1090 1096 #
1091 1097 # def getSubplots(self):
1092 1098 #
1093 1099 # nrow = self.nplots
1094 1100 # ncol = 3
1095 1101 # return nrow, ncol
1096 1102 #
1097 1103 # def setup(self, idfigure, nplots, wintitle):
1098 1104 #
1099 1105 # self.nplots = nplots
1100 1106 #
1101 1107 # self.createFigure(idfigure, wintitle)
1102 1108 #
1103 1109 # nrow,ncol = self.getSubplots()
1104 1110 # colspan = 3
1105 1111 # rowspan = 1
1106 1112 #
1107 1113 # for i in range(nplots):
1108 1114 # self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
1109 1115
1110 1116 def run(self, dataOut, idfigure, wintitle="", channelList=None,
1111 1117 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
1112 1118 figpath='./', figfile=None, ftp=False, ftpratio=1, show=True):
1113 1119
1114 1120 """
1115 1121
1116 1122 Input:
1117 1123 dataOut :
1118 1124 idfigure :
1119 1125 wintitle :
1120 1126 channelList :
1121 1127 xmin : None,
1122 1128 xmax : None,
1123 1129 ymin : None,
1124 1130 ymax : None,
1125 1131 """
1126 1132
1133 if dataOut.realtime:
1134 if not(isRealtime(utcdatatime = dataOut.utctime)):
1135 print 'Skipping this plot function'
1136 return
1137
1127 1138 if channelList == None:
1128 1139 channelIndexList = dataOut.channelIndexList
1129 1140 else:
1130 1141 channelIndexList = []
1131 1142 for channel in channelList:
1132 1143 if channel not in dataOut.channelList:
1133 1144 raise ValueError, "Channel %d is not in dataOut.channelList"
1134 1145 channelIndexList.append(dataOut.channelList.index(channel))
1135 1146
1136 1147 # x = dataOut.heightList
1137 1148 c = 3E8
1138 1149 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1139 1150 #deberia cambiar para el caso de 1Mhz y 100KHz
1140 1151 x = numpy.arange(-1*dataOut.nHeights/2.,dataOut.nHeights/2.)*(c/(2*deltaHeight*dataOut.nHeights*1000))
1141 1152 x= x/(10000.0)
1142 1153 # y = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
1143 1154 # y = y.real
1144 1155 datadB = 10.*numpy.log10(dataOut.data_spc)
1145 1156 y = datadB
1146 1157
1147 1158 thisDatetime = dataOut.datatime
1148 1159 title = "Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1149 1160 xlabel = "Frequency x 10000"
1150 1161 ylabel = "Intensity (dB)"
1151 1162
1152 1163 if not self.__isConfig:
1153 1164 nplots = len(channelIndexList)
1154 1165
1155 1166 self.setup(idfigure=idfigure,
1156 1167 nplots=nplots,
1157 1168 wintitle=wintitle,
1158 1169 show=show)
1159 1170
1160 1171 if xmin == None: xmin = numpy.nanmin(x)
1161 1172 if xmax == None: xmax = numpy.nanmax(x)
1162 1173 if ymin == None: ymin = numpy.nanmin(y)
1163 1174 if ymax == None: ymax = numpy.nanmax(y)
1164 1175
1165 1176 self.__isConfig = True
1166 1177
1167 1178 self.setWinTitle(title)
1168 1179
1169 1180 for i in range(len(self.axesList)):
1170 1181 ychannel = y[i,:]
1171 1182 title = "Channel %d - peak:%.2f" %(i,numpy.max(ychannel))
1172 1183 axes = self.axesList[i]
1173 1184 axes.pline(x, ychannel,
1174 1185 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1175 1186 xlabel=xlabel, ylabel=ylabel, title=title, grid='both')
1176 1187
1177 1188
1178 1189 self.draw()
1179 1190
1180 1191 if save:
1181 1192 date = thisDatetime.strftime("%Y%m%d_%H%M%S")
1182 1193 if figfile == None:
1183 1194 figfile = self.getFilename(name = date)
1184 1195
1185 1196 self.saveFigure(figpath, figfile)
1186 1197
1187 1198 self.counterftp += 1
1188 1199 if (ftp and (self.counterftp==ftpratio)):
1189 1200 figfilename = os.path.join(figpath,figfile)
1190 1201 self.sendByFTP(figfilename)
1191 1202 self.counterftp = 0
1192 1203
1193 1204
1194 1205 class RTIfromSpectraHeis(Figure):
1195 1206
1196 1207 __isConfig = None
1197 1208 __nsubplots = None
1198 1209
1199 1210 PREFIX = 'rtinoise'
1200 1211
1201 1212 def __init__(self):
1202 1213
1203 1214 self.timerange = 24*60*60
1204 1215 self.__isConfig = False
1205 1216 self.__nsubplots = 1
1206 1217
1207 1218 self.WIDTH = 820
1208 1219 self.HEIGHT = 200
1209 1220 self.WIDTHPROF = 120
1210 1221 self.HEIGHTPROF = 0
1211 1222 self.counterftp = 0
1212 1223 self.xdata = None
1213 1224 self.ydata = None
1214 1225
1215 1226 def getSubplots(self):
1216 1227
1217 1228 ncol = 1
1218 1229 nrow = 1
1219 1230
1220 1231 return nrow, ncol
1221 1232
1222 1233 def setup(self, idfigure, nplots, wintitle, showprofile=True, show=True):
1223 1234
1224 1235 self.__showprofile = showprofile
1225 1236 self.nplots = nplots
1226 1237
1227 1238 ncolspan = 7
1228 1239 colspan = 6
1229 1240 self.__nsubplots = 2
1230 1241
1231 1242 self.createFigure(idfigure = idfigure,
1232 1243 wintitle = wintitle,
1233 1244 widthplot = self.WIDTH+self.WIDTHPROF,
1234 1245 heightplot = self.HEIGHT+self.HEIGHTPROF,
1235 1246 show = show)
1236 1247
1237 1248 nrow, ncol = self.getSubplots()
1238 1249
1239 1250 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1240 1251
1241 1252
1242 1253 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
1243 1254 xmin=None, xmax=None, ymin=None, ymax=None,
1244 1255 timerange=None,
1245 1256 save=False, figpath='./', figfile=None, ftp=False, ftpratio=1, show=True):
1246 1257
1247 1258 if channelList == None:
1248 1259 channelIndexList = dataOut.channelIndexList
1249 1260 channelList = dataOut.channelList
1250 1261 else:
1251 1262 channelIndexList = []
1252 1263 for channel in channelList:
1253 1264 if channel not in dataOut.channelList:
1254 1265 raise ValueError, "Channel %d is not in dataOut.channelList"
1255 1266 channelIndexList.append(dataOut.channelList.index(channel))
1256 1267
1257 1268 if timerange != None:
1258 1269 self.timerange = timerange
1259 1270
1260 1271 tmin = None
1261 1272 tmax = None
1262 1273 x = dataOut.getTimeRange()
1263 1274 y = dataOut.getHeiRange()
1264 1275
1265 1276 factor = 1
1266 1277 data = dataOut.data_spc/factor
1267 1278 data = numpy.average(data,axis=1)
1268 1279 datadB = 10*numpy.log10(data)
1269 1280
1270 1281 # factor = dataOut.normFactor
1271 1282 # noise = dataOut.getNoise()/factor
1272 1283 # noisedB = 10*numpy.log10(noise)
1273 1284
1274 1285 thisDatetime = dataOut.datatime
1275 1286 title = "RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
1276 1287 xlabel = "Local Time"
1277 1288 ylabel = "Intensity (dB)"
1278 1289
1279 1290 if not self.__isConfig:
1280 1291
1281 1292 nplots = 1
1282 1293
1283 1294 self.setup(idfigure=idfigure,
1284 1295 nplots=nplots,
1285 1296 wintitle=wintitle,
1286 1297 showprofile=showprofile,
1287 1298 show=show)
1288 1299
1289 1300 tmin, tmax = self.getTimeLim(x, xmin, xmax)
1290 1301 if ymin == None: ymin = numpy.nanmin(datadB)
1291 1302 if ymax == None: ymax = numpy.nanmax(datadB)
1292 1303
1293 1304 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1294 1305 self.__isConfig = True
1295 1306
1296 1307 self.xdata = numpy.array([])
1297 1308 self.ydata = numpy.array([])
1298 1309
1299 1310 self.setWinTitle(title)
1300 1311
1301 1312
1302 1313 # title = "RTI %s" %(thisDatetime.strftime("%d-%b-%Y"))
1303 1314 title = "RTI-Noise - %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1304 1315
1305 1316 legendlabels = ["channel %d"%idchannel for idchannel in channelList]
1306 1317 axes = self.axesList[0]
1307 1318
1308 1319 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1309 1320
1310 1321 if len(self.ydata)==0:
1311 1322 self.ydata = datadB[channelIndexList].reshape(-1,1)
1312 1323 else:
1313 1324 self.ydata = numpy.hstack((self.ydata, datadB[channelIndexList].reshape(-1,1)))
1314 1325
1315 1326
1316 1327 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1317 1328 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax,
1318 1329 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='.', markersize=8, linestyle="solid", grid='both',
1319 1330 XAxisAsTime=True
1320 1331 )
1321 1332
1322 1333 self.draw()
1323 1334
1324 1335 if save:
1325 1336
1326 1337 if figfile == None:
1327 1338 figfile = self.getFilename(name = self.name)
1328 1339
1329 1340 self.saveFigure(figpath, figfile)
1330 1341
1331 1342 self.counterftp += 1
1332 1343 if (ftp and (self.counterftp==ftpratio)):
1333 1344 figfilename = os.path.join(figpath,figfile)
1334 1345 self.sendByFTP(figfilename)
1335 1346 self.counterftp = 0
1336 1347
1337 1348 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
1338 1349 self.__isConfig = False
1339 1350 del self.xdata
1340 1351 del self.ydata
1341 1352
1342 1353
1343 1354 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now