##// END OF EJS Templates
SpectraIO. Clase para escribir y leer espectros...
Victor Sarmiento -
r33:e2723460f854
parent child
Show More
@@ -1,1642 +1,1666
1 1 '''
2 2 File: SpectraIO.py
3 3 Created on 20/02/2012
4 4
5 5 @author $Author$
6 6 @version $Id$
7 7 '''
8 8
9 9 import os, sys
10 10 import numpy
11 11 import glob
12 12 import fnmatch
13 13 import time, datetime
14 14
15 15 path = os.path.split(os.getcwd())[0]
16 16 sys.path.append(path)
17 17
18 18 from HeaderIO import *
19 19 from DataIO import DataReader
20 20 from DataIO import DataWriter
21 21
22 22 from Model.Spectra import Spectra
23 23
24 24 def isNumber( str ):
25 25 """
26 26 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
27 27
28 28 Excepciones:
29 29 Si un determinado string no puede ser convertido a numero
30 30 Input:
31 31 str, string al cual se le analiza para determinar si convertible a un numero o no
32 32
33 33 Return:
34 34 True : si el string es uno numerico
35 35 False : no es un string numerico
36 36 """
37 37 try:
38 38 float( str )
39 39 return True
40 40 except:
41 41 return False
42 42
43 43
44 44
45 45 def isThisFileinRange( filename, startUTSeconds, endUTSeconds ):
46 46 """
47 47 Esta funcion determina si un archivo de datos en formato Jicamarca(.r) se encuentra
48 48 o no dentro del rango de fecha especificado.
49 49
50 50 Inputs:
51 51 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
52 52
53 53 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
54 54 segundos contados desde 01/01/1970.
55 55
56 56 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
57 57 segundos contados desde 01/01/1970.
58 58
59 59 Return:
60 60 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
61 61 fecha especificado, de lo contrario retorna False.
62 62
63 63 Excepciones:
64 64 Si el archivo no existe o no puede ser abierto
65 65 Si la cabecera no puede ser leida.
66 66 """
67 67 m_BasicHeader = BasicHeader()
68 68
69 69 try:
70 70 fp = open( filename,'rb' ) #lectura binaria
71 71 except:
72 72 raise IOError, "The file %s can't be opened" %(filename)
73 73
74 74 if not(m_BasicHeader.read(fp)):
75 75 raise IOError, "The file %s has not a valid header" %(filename)
76 76
77 77 fp.close()
78 78
79 79 if not ((startUTSeconds <= m_BasicHeader.utc) and (endUTSeconds >= m_BasicHeader.utc)):
80 80 return 0
81 81
82 82 return 1
83 83
84 84
85 85 class SpectraReader( DataReader ):
86 86 """
87 87 Esta clase permite leer datos de espectros desde archivos procesados (.pdata). La lectura
88 88 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones)
89 89 son almacenados en tres buffer's para el Self Spectra, el Cross Spectra y el DC Channel.
90 90
91 91 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
92 92 RadarControllerHeader y Spectra. Los tres primeros se usan para almacenar informacion de la
93 93 cabecera de datos (metadata), y el cuarto (Spectra) para obtener y almacenar un bloque de
94 94 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
95 95
96 96 Example:
97 97 dpath = "/home/myuser/data"
98 98
99 99 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
100 100
101 101 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
102 102
103 103 readerObj = SpectraReader()
104 104
105 105 readerObj.setup(dpath, startTime, endTime)
106 106
107 107 while(True):
108 108
109 109 readerObj.getData()
110 110
111 111 print readerObj.m_Spectra.data
112 112
113 113 if readerObj.noMoreFiles:
114 114 break
115 115
116 116 """
117 117
118 118 #speed of light
119 119 __c = 3E8
120 120
121 121
122 122 def __init__( self, m_Spectra = None ):
123 123 """
124 124 Inicializador de la clase SpectraReader para la lectura de datos de espectros.
125 125
126 126 Inputs:
127 127 m_Spectra : Objeto de la clase Spectra. Este objeto sera utilizado para
128 128 almacenar un perfil de datos cada vez que se haga un requerimiento
129 129 (getData). El perfil sera obtenido a partir del buffer de datos,
130 130 si el buffer esta vacio se hara un nuevo proceso de lectura de un
131 131 bloque de datos.
132 132 Si este parametro no es pasado se creara uno internamente.
133 133
134 134 Affected:
135 135 self.m_Spectra
136 136 self.m_BasicHeader
137 137 self.m_SystemHeader
138 138 self.m_RadarControllerHeader
139 139 self.m_ProcessingHeader
140 140
141 141 Return : None
142 142 """
143 143 if m_Spectra == None:
144 144 m_Spectra = Spectra()
145 145
146 146 if not( isinstance(m_Spectra, Spectra) ):
147 147 raise ValueError, "in SpectraReader, m_Spectra must be an Spectra class object"
148 148
149 149 self.m_Spectra = m_Spectra
150 150
151 151 self.m_BasicHeader = BasicHeader()
152 152
153 153 self.m_SystemHeader = SystemHeader()
154 154
155 155 self.m_RadarControllerHeader = RadarControllerHeader()
156 156
157 157 self.m_ProcessingHeader = ProcessingHeader()
158 158
159 159 self.__fp = None
160 160
161 161 self.__idFile = None
162 162
163 163 self.__startDateTime = None
164 164
165 165 self.__endDateTime = None
166 166
167 167 self.__dataType = None
168 168
169 169 self.__fileSizeByHeader = 0
170 170
171 171 self.__pathList = []
172 172
173 173 self.filenameList = []
174 174
175 175 self.__lastUTTime = 0
176 176
177 177 self.__maxTimeStep = 30
178 178
179 179 self.__flagIsNewFile = 0
180 180
181 181 self.flagResetProcessing = 0
182 182
183 183 self.flagIsNewBlock = 0
184 184
185 185 self.noMoreFiles = 0
186 186
187 187 self.nReadBlocks = 0
188 188
189 189 self.online = 0
190 190
191 191 self.firstHeaderSize = 0
192 192
193 193 self.basicHeaderSize = 24
194 194
195 195 self.filename = None
196 196
197 197 self.fileSize = None
198 198
199 199 self.__data_spc = None
200 200 self.__data_cspc = None
201 201 self.__data_dc = None
202 202
203 203 self.nChannels = 0
204 204 self.nPairs = 0
205 205
206 206 self.__pts2read_SelfSpectra = 0
207 207 self.__pts2read_CrossSpectra = 0
208 208 self.__pts2read_DCchannels = 0
209 209 self.__blocksize = 0
210 210
211 211 self.__datablockIndex = 0
212 212
213 213 self.__ippSeconds = 0
214 214
215 215 self.nSelfChannels = 0
216 216
217 217 self.nCrossPairs = 0
218 218
219 219 self.__delay = 7 #seconds
220 220 self.__nTries = 3 #quantity tries
221 221 self.__nFiles = 3 #number of files for searching
222 222 self.__year = 0
223 223 self.__doy = 0
224 224 self.__set = 0
225 225 self.__ext = None
226 226 self.__path = None
227 227 self.datablock_id = 9999
228 228
229 229
230 230 def __rdSystemHeader( self, fp=None ):
231 231 """
232 232 Lectura del System Header
233 233
234 234 Inputs:
235 235 fp : file pointer
236 236
237 237 Affected:
238 238 self.m_SystemHeader
239 239
240 240 Return: None
241 241 """
242 242 if fp == None:
243 243 fp = self.__fp
244 244
245 245 self.m_SystemHeader.read( fp )
246 246
247 247
248 248
249 249 def __rdRadarControllerHeader( self, fp=None ):
250 250 """
251 251 Lectura del Radar Controller Header
252 252
253 253 Inputs:
254 254 fp : file pointer
255 255
256 256 Affected:
257 257 self.m_RadarControllerHeader
258 258
259 259 Return: None
260 260 """
261 261 if fp == None:
262 262 fp = self.__fp
263 263
264 264 self.m_RadarControllerHeader.read(fp)
265 265
266 266
267 267 def __rdProcessingHeader( self,fp=None ):
268 268 """
269 269 Lectura del Processing Header
270 270
271 271 Inputs:
272 272 fp : file pointer
273 273
274 274 Affected:
275 275 self.m_ProcessingHeader
276 276
277 277 Return: None
278 278 """
279 279 if fp == None:
280 280 fp = self.__fp
281 281
282 282 self.m_ProcessingHeader.read(fp)
283 283
284 284
285 285 def __rdBasicHeader( self, fp=None ):
286 286 """
287 287 Lectura del Basic Header
288 288
289 289 Inputs:
290 290 fp : file pointer
291 291
292 292 Affected:
293 293 self.m_BasicHeader
294 294
295 295 Return: None
296 296 """
297 297 if fp == None:
298 298 fp = self.__fp
299 299
300 300 self.m_BasicHeader.read(fp)
301 301
302 302
303 303 def __readFirstHeader( self ):
304 304 """
305 305 Lectura del First Header, es decir el Basic Header y el Long Header
306 306
307 307 Affected:
308 308 self.m_BasicHeader
309 309 self.m_SystemHeader
310 310 self.m_RadarControllerHeader
311 311 self.m_ProcessingHeader
312 312 self.firstHeaderSize
313 313 self.__heights
314 314 self.__dataType
315 315 self.__fileSizeByHeader
316 316 self.__ippSeconds
317 317 self.nChannels
318 318 self.nPairs
319 319 self.__pts2read_SelfSpectra
320 320 self.__pts2read_CrossSpectra
321 321
322 322 Return: None
323 323 """
324 324 self.__rdBasicHeader()
325 325 self.__rdSystemHeader()
326 326 self.__rdRadarControllerHeader()
327 327 self.__rdProcessingHeader()
328 328 self.firstHeaderSize = self.m_BasicHeader.size
329 329
330 330 data_type = int( numpy.log2((self.m_ProcessingHeader.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR) )
331 331 if data_type == 0:
332 332 tmp = numpy.dtype([('real','<i1'),('imag','<i1')])
333 333
334 334 elif data_type == 1:
335 335 tmp = numpy.dtype([('real','<i2'),('imag','<i2')])
336 336
337 337 elif data_type == 2:
338 338 tmp = numpy.dtype([('real','<i4'),('imag','<i4')])
339 339
340 340 elif data_type == 3:
341 341 tmp = numpy.dtype([('real','<i8'),('imag','<i8')])
342 342
343 343 elif data_type == 4:
344 344 tmp = numpy.dtype([('real','<f4'),('imag','<f4')])
345 345
346 346 elif data_type == 5:
347 347 tmp = numpy.dtype([('real','<f8'),('imag','<f8')])
348 348
349 349 else:
350 350 raise ValueError, 'Data type was not defined'
351 351
352 352 xi = self.m_ProcessingHeader.firstHeight
353 353 step = self.m_ProcessingHeader.deltaHeight
354 354 xf = xi + self.m_ProcessingHeader.numHeights*step
355 355
356 356 self.__heights = numpy.arange(xi, xf, step)
357 357
358 358 self.__dataType = tmp
359 359 self.__fileSizeByHeader = self.m_ProcessingHeader.dataBlocksPerFile * self.m_ProcessingHeader.blockSize + self.firstHeaderSize + self.basicHeaderSize*(self.m_ProcessingHeader.dataBlocksPerFile - 1)
360 360 self.__ippSeconds = 2 * 1000 * self.m_RadarControllerHeader.ipp / self.__c
361 361
362 362 self.nChannels = 0
363 363 self.nPairs = 0
364 364
365 365 for i in range( 0, self.m_ProcessingHeader.totalSpectra*2, 2 ):
366 366 if self.m_ProcessingHeader.spectraComb[i] == self.m_ProcessingHeader.spectraComb[i+1]:
367 367 self.nChannels = self.nChannels + 1
368 368 else:
369 369 self.nPairs = self.nPairs + 1
370 370
371 371 pts2read = self.m_ProcessingHeader.profilesPerBlock * self.m_ProcessingHeader.numHeights
372 372 self.__pts2read_SelfSpectra = int( pts2read * self.nChannels )
373 373 self.__pts2read_CrossSpectra = int( pts2read * self.nPairs )
374 374 self.__pts2read_DCchannels = int( self.m_ProcessingHeader.numHeights * self.m_SystemHeader.numChannels )
375 375
376 376 self.__blocksize = self.__pts2read_SelfSpectra + self.__pts2read_CrossSpectra + self.__pts2read_DCchannels
377 377
378 378 self.m_Spectra.nChannels = self.nChannels
379 379 self.m_Spectra.nPairs = self.nPairs
380 380
381 381
382 382 def __checkForRealPath( self ):
383 383 """
384 384 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
385 385 el path exacto de un determinado file.
386 386
387 387 Example :
388 388 nombre correcto del file es ../RAWDATA/D2009307/P2009307367
389 389
390 390 Entonces la funcion prueba con las siguientes combinaciones
391 391 ../RAWDATA/d2009307/p2009307367
392 392 ../RAWDATA/d2009307/P2009307367
393 393 ../RAWDATA/D2009307/p2009307367
394 394 ../RAWDATA/D2009307/P2009307367
395 395 siendo para este caso, la ultima combinacion de letras, identica al file buscado
396 396
397 397 Return:
398 398 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
399 399 caso contrario devuelve None
400 400 """
401 401 filepath = None
402 402 find_flag = False
403 403 filename = None
404 404
405 405 for dir in "dD": #barrido por las dos combinaciones posibles de "D"
406 406 for fil in "pP": #barrido por las dos combinaciones posibles de "D"
407 407 doypath = "%s%04d%03d" % ( dir, self.__year, self.__doy ) #formo el nombre del directorio xYYYYDDD (x=d o x=D)
408 408 filename = "%s%04d%03d%03d%s" % ( fil, self.__year, self.__doy, self.__set, self.__ext ) #formo el nombre del file xYYYYDDDSSS.ext (p=d o p=D)
409 409 filepath = os.path.join( self.__path, doypath, filename ) #formo el path completo
410 410 if os.path.exists( filepath ): #verifico que exista
411 411 find_flag = True
412 412 break
413 413 if find_flag:
414 414 break
415 415
416 416 if not(find_flag):
417 417 return None, filename
418 418
419 419 return filepath, filename
420 420
421 421
422 422 def __setNextFileOnline( self ):
423 423 """
424 424 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
425 425 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
426 426 siguientes.
427 427
428 428 Affected:
429 429 self.__flagIsNewFile
430 430 self.filename
431 431 self.fileSize
432 432 self.__fp
433 433 self.__set
434 434 self.noMoreFiles
435 435
436 436 Return:
437 437 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
438 438 1 : si el file fue abierto con exito y esta listo a ser leido
439 439
440 440 Excepciones:
441 441 Si un determinado file no puede ser abierto
442 442 """
443 443 countFiles = 0
444 444 countTries = 0
445 445
446 446 fileStatus = 0
447 447 notFirstTime_flag = False
448 448 bChangeDir = False
449 449
450 450 fileSize = 0
451 451 fp = None
452 452
453 453 self.__flagIsNewFile = 0
454 454
455 455 while(True): #este loop permite llevar la cuenta de intentos, de files y carpetas,
456 456 #si no encuentra alguno sale del bucle
457 457
458 458 countFiles += 1
459 459
460 460 if countFiles > (self.__nFiles + 1):
461 461 break
462 462
463 463 self.__set += 1
464 464
465 465 if countFiles > self.__nFiles: #si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
466 466 self.__set = 0
467 467 self.__doy += 1
468 468 bChangeDir = True
469 469
470 470 file = None
471 471 filename = None
472 472
473 473 countTries = 0
474 474
475 475 #espero hasta encontrar el 1er file disponible
476 476 while( True ):
477 477
478 478 countTries += 1
479 479 if( countTries >= self.__nTries ): #checkeo que no haya ido mas alla de la cantidad de intentos
480 480 break
481 481
482 482 file, filename = self.__checkForRealPath()
483 483 if file != None:
484 484 break
485 485
486 486 if notFirstTime_flag: #este flag me sirve solo para esperar por el 1er file, en lo siguientes no espera solo checkea si existe o no
487 487 countTries = self.__nTries
488 488 print "\tsearching next \"%s\" file ..." % filename
489 489 break
490 490
491 491 print "\twaiting new \"%s\" file ..." % filename
492 492 time.sleep( self.__delay )
493 493
494 494 if countTries >= self.__nTries: #se realizaron n intentos y no hubo un file nuevo
495 495 notFirstTime_flag = True
496 496 continue #vuelvo al inico del while principal
497 497
498 498 countTries = 0
499 499
500 500 #una vez que se obtuvo el 1er file valido se procede a checkear su contenido, y se espera una cierta cantidad
501 501 #de tiempo por una cierta cantidad de veces hasta que el contenido del file sea un contenido valido
502 502 while( True ):
503 503 countTries += 1
504 504 if countTries > self.__nTries:
505 505 break
506 506
507 507 try:
508 508 fp = open(file)
509 509 except:
510 510 print "The file \"%s\" can't be opened" % file
511 511 break
512 512
513 513 fileSize = os.path.getsize( file )
514 514 currentSize = fileSize - fp.tell()
515 515 neededSize = self.m_ProcessingHeader.blockSize + self.firstHeaderSize
516 516
517 517 if currentSize > neededSize:
518 518 fileStatus = 1
519 519 break
520 520
521 521 fp.close()
522 522
523 523 if bChangeDir: #si al buscar un file cambie de directorio ya no espero y salgo del bucle while
524 524 print "\tsearching next \"%s\" file ..." % filename
525 525 break
526 526
527 527 print "\twaiting for block of \"%s\" file ..." % filename
528 528 time.sleep( self.__delay )
529 529
530 530 if fileStatus == 1:
531 531 break
532 532
533 533 print "Skipping the file \"%s\" due to this files is empty" % filename
534 534 countFiles = 0
535 535
536 536
537 537 if fileStatus == 1:
538 538 self.fileSize = fileSize
539 539 self.filename = file#name
540 540 self.__flagIsNewFile = 1
541 541 self.__fp = fp
542 542 self.noMoreFiles = 0
543 543 print 'Setting the file: %s' % file #name
544 544 else:
545 545 self.fileSize = 0
546 546 self.filename = None
547 547 self.__fp = None
548 548 self.noMoreFiles = 1
549 549 print 'No more Files'
550 550
551 551 return fileStatus
552 552
553 553
554 554 def __setNextFileOffline( self ):
555 555 """
556 556 Busca el siguiente file dentro de un folder que tenga suficiente data para ser leida
557 557
558 558 Affected:
559 559 self.__flagIsNewFile
560 560 self.__idFile
561 561 self.filename
562 562 self.fileSize
563 563 self.__fp
564 564
565 565 Return:
566 566 0 : si un determinado file no puede ser abierto
567 567 1 : si el file fue abierto con exito
568 568
569 569 Excepciones:
570 570 Si un determinado file no puede ser abierto
571 571 """
572 572 idFile = self.__idFile
573 573 self.__flagIsNewFile = 0
574 574
575 575 while(True):
576 576 idFile += 1
577 577
578 578 if not( idFile < len(self.filenameList) ):
579 579 self.noMoreFiles = 1
580 580 return 0
581 581
582 582 filename = self.filenameList[idFile]
583 583 fileSize = os.path.getsize(filename)
584 584
585 585 try:
586 586 fp = open( filename, 'rb' )
587 587 except:
588 588 raise IOError, "The file %s can't be opened" %filename
589 589
590 590 currentSize = fileSize - fp.tell()
591 591 neededSize = self.m_ProcessingHeader.blockSize + self.firstHeaderSize
592 592
593 593 if (currentSize < neededSize):
594 594 print "Skipping the file %s due to it hasn't enough data" %filename
595 595 fp.close()
596 596 continue
597 597
598 598 break
599 599 self.__flagIsNewFile = 1
600 600 self.__idFile = idFile
601 601 self.filename = filename
602 602 self.fileSize = fileSize
603 603 self.__fp = fp
604 604
605 605 print 'Setting the file: %s'%self.filename
606 606
607 607 return 1
608 608
609 609
610 610 def __setNextFile( self ):
611 611 """
612 612 Determina el siguiente file a leer y si hay uno disponible lee el First Header
613 613
614 614 Affected:
615 615 self.m_BasicHeader
616 616 self.m_SystemHeader
617 617 self.m_RadarControllerHeader
618 618 self.m_ProcessingHeader
619 619 self.firstHeaderSize
620 620
621 621 Return:
622 622 0 : Si no hay files disponibles
623 623 1 : Si hay mas files disponibles
624 624 """
625 625 if self.__fp != None:
626 626 self.__fp.close()
627 627
628 628 if self.online:
629 629 newFile = self.__setNextFileOnline()
630 630 else:
631 631 newFile = self.__setNextFileOffline()
632 632
633 633 if not(newFile):
634 634 return 0
635 635
636 636 self.__readFirstHeader()
637 637
638 638 return 1
639 639
640 640
641 641 def __setNewBlock( self ):
642 642 """
643 643 Lee el Basic Header y posiciona le file pointer en la posicion inicial del bloque a leer
644 644
645 645 Affected:
646 646 self.m_BasicHeader
647 647 self.flagResetProcessing
648 648 self.ns
649 649
650 650 Return:
651 651 0 : Si el file no tiene un Basic Header que pueda ser leido
652 652 1 : Si se pudo leer el Basic Header
653 653 """
654 654 if self.__fp == None:
655 655 return 0
656 656
657 657 if self.__flagIsNewFile:
658 658 return 1
659 659
660 660 currentSize = self.fileSize - self.__fp.tell()
661 661 neededSize = self.m_ProcessingHeader.blockSize + self.basicHeaderSize
662 662
663 663 #If there is enough data setting new data block
664 664 if ( currentSize >= neededSize ):
665 665 self.__rdBasicHeader()
666 666 return 1
667 elif self.online:
668 nTries = 0
669 while( nTries < self.__nTries ):
670 nTries += 1
671 print "Waiting for the next block, try %03d ..." % nTries
672 time.sleep( self.__delay )
673
674 fileSize = os.path.getsize(self.filename)
675 currentSize = fileSize - self.__fp.tell()
676 neededSize = self.m_ProcessingHeader.blockSize + self.basicHeaderSize
677
678 if ( currentSize >= neededSize ):
679 self.__rdBasicHeader()
680 return 1
667 681
668 682 #Setting new file
669 683 if not( self.__setNextFile() ):
670 684 return 0
671 685
672 686 deltaTime = self.m_BasicHeader.utc - self.__lastUTTime # check this
673 687
674 688 self.flagResetProcessing = 0
675 689
676 690 if deltaTime > self.__maxTimeStep:
677 691 self.flagResetProcessing = 1
678 692 self.ns = 0
679 693
680 694 return 1
681 695
682 696
683 697 def __readBlock(self):
684 698 """
685 699 Lee el bloque de datos desde la posicion actual del puntero del archivo
686 700 (self.__fp) y actualiza todos los parametros relacionados al bloque de datos
687 701 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
688 702 es seteado a 0
689 703
690 704 Return: None
691 705
692 706 Variables afectadas:
693 707 self.__datablockIndex
694 708 self.__flagIsNewFile
695 709 self.flagIsNewBlock
696 710 self.nReadBlocks
697 711 self.__data_spc
698 712 self.__data_cspc
699 713 self.__data_dc
700 714 """
701 715 self.datablock_id = 0
702 716 self.__flagIsNewFile = 0
703 717 self.flagIsNewBlock = 1
704 718
719 fpointer = self.__fp.tell()
720
705 721 spc = numpy.fromfile( self.__fp, self.__dataType[0], self.__pts2read_SelfSpectra )
706 722 cspc = numpy.fromfile( self.__fp, self.__dataType, self.__pts2read_CrossSpectra )
707 723 dc = numpy.fromfile( self.__fp, self.__dataType, self.__pts2read_DCchannels ) #int(self.m_ProcessingHeader.numHeights*self.m_SystemHeader.numChannels) )
708
724
725 if (spc.size + cspc.size + dc.size) != self.__blocksize:
726 nTries = 0
727 while( nTries < self.__nTries ):
728 nTries += 1
729 print "Waiting for the next block, try %03d ..." % nTries
730 time.sleep( self.__delay )
731 self.__fp.seek( fpointer )
732 fpointer = self.__fp.tell()
733 spc = numpy.fromfile( self.__fp, self.__dataType[0], self.__pts2read_SelfSpectra )
734 cspc = numpy.fromfile( self.__fp, self.__dataType, self.__pts2read_CrossSpectra )
735 dc = numpy.fromfile( self.__fp, self.__dataType, self.__pts2read_DCchannels ) #int(self.m_ProcessingHeader.numHeights*self.m_SystemHeader.numChannels) )
736 if (spc.size + cspc.size + dc.size) == self.__blocksize:
737 nTries = 0
738 break
739 if nTries > 0:
740 return
741
709 742 spc = spc.reshape( (self.nChannels, self.m_ProcessingHeader.numHeights, self.m_ProcessingHeader.profilesPerBlock) ) #transforma a un arreglo 3D
710 743
711 744 cspc = cspc.reshape( (self.nPairs, self.m_ProcessingHeader.numHeights, self.m_ProcessingHeader.profilesPerBlock) ) #transforma a un arreglo 3D
712 745 dc = dc.reshape( (self.m_SystemHeader.numChannels, self.m_ProcessingHeader.numHeights) ) #transforma a un arreglo 2D
713 746
714 747 if not( self.m_ProcessingHeader.shif_fft ):
715 748 spc = numpy.roll( spc, self.m_ProcessingHeader.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
716 749 cspc = numpy.roll( cspc, self.m_ProcessingHeader.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
717 750
718 751 spc = numpy.transpose( spc, (0,2,1) )
719 752 cspc = numpy.transpose( cspc, (0,2,1) )
720 753 #dc = numpy.transpose(dc, (0,2,1))
721 754
722 755 self.__data_spc = spc
723 756 self.__data_cspc = cspc['real'] + cspc['imag']*1j
724 757 self.__data_dc = dc['real'] + dc['imag']*1j
725 758
726 759 self.__flagIsNewFile = 0
727 760
728 761 self.flagIsNewBlock = 1
729 762
730 763 self.nReadBlocks += 1
731 764 self.datablock_id = 0
732 765
733 766
734 767
735 768 def __hasNotDataInBuffer( self ):
736 769 #if self.datablock_id >= self.m_ProcessingHeader.profilesPerBlock:
737 770 return 1
738 771
739 772
740 773 def __getlastFileFromPath( self, pathList, ext ):
741 774 """
742 775 Depura el pathList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
743 776 al final de la depuracion devuelve el ultimo file de la lista que quedo.
744 777
745 778 Input:
746 779 pathList : lista conteniendo todos los filename completos que componen una determinada carpeta
747 780 ext : extension de los files contenidos en una carpeta
748 781
749 782 Return:
750 783 El ultimo file de una determinada carpeta
751 784 """
752 785
753 786 filesList = []
754 787 filename = None
755 788
756 789 # 0123456789ABCDE
757 790 # PYYYYDDDSSS.ext
758 791
759 792 for filename in pathList:
760 793 year = filename[1:5]
761 794 doy = filename[5:8]
762 795 leng = len( ext )
763 796
764 797 if ( filename[-leng:].upper() != ext.upper() ) : continue
765 798 if not( isNumber( year ) ) : continue
766 799 if not( isNumber( doy ) ) : continue
767 800
768 801 filesList.append(filename)
769 802
770 803 if len( filesList ) > 0:
771 804 #filesList.sort()
772 805 filesList = sorted( filesList, key=str.lower )
773 806 filename = filesList[-1]
774 807
775 808 return filename
776 809
777 810
778 811 def __searchFilesOnLine( self, path, startDateTime=None, ext = ".pdata" ):
779 812 """
780 813 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
781 814 devuelve el archivo encontrado ademas de otros datos.
782 815
783 816 Input:
784 817 path : carpeta donde estan contenidos los files que contiene data
785 818 startDateTime : punto especifico en el tiempo del cual se requiere la data
786 819 ext : extension de los files
787 820
788 821 Return:
789 822 year : el anho
790 823 doy : el numero de dia del anho
791 824 set : el set del archivo
792 825 filename : el ultimo file de una determinada carpeta
793 826 directory : eL directorio donde esta el file encontrado
794 827 """
795 828
796 829 print "Searching files ..."
797 830
798 831 dirList = []
799 832 directory = None
800 833
801 834 if startDateTime == None:
802 835 for thisPath in os.listdir(path):
803 836 if os.path.isdir( os.path.join(path,thisPath) ):
804 837 dirList.append( thisPath )
805 838
806 839 dirList = sorted( dirList, key=str.lower ) #para que quede ordenado al margen de si el nombre esta en mayusculas o minusculas, utilizo la funcion sorted
807 840 if len(dirList) > 0 :
808 841 directory = dirList[-1]
809 842 else:
810 843 year = startDateTime.timetuple().tm_year
811 844 doy = startDateTime.timetuple().tm_yday
812 845
813 846 doyPath = "D%04d%03d" % (year,doy) #caso del nombre en mayusculas
814 847 if os.path.isdir( os.path.join(path,doyPath) ):
815 848 directory = doyPath
816 849
817 850 doyPath = doyPath.lower() #caso del nombre en minusculas
818 851 if os.path.isdir( os.path.join(path,doyPath) ):
819 852 directory = doyPath
820 853
821 854 if directory == None:
822 855 return 0, 0, 0, None, None
823 856
824 857 filename = self.__getlastFileFromPath( os.listdir( os.path.join(path,directory) ), ext )
825 858
826 859 if filename == None:
827 860 return 0, 0, 0, None, None
828 861
829 862 year = int( directory[-7:-3] )
830 863 doy = int( directory[-3:] )
831 864 ln = len( ext )
832 865 set = int( filename[-ln-3:-ln] )
833 866
834 867 return year, doy, set, filename, directory
835 868
836 869
837 870 def __searchFilesOffLine( self, path, startDateTime, endDateTime, set=None, expLabel = "", ext = ".pdata" ):
838 871 """
839 872 Realiza una busqueda de los archivos que coincidan con los parametros
840 873 especificados y se encuentren ubicados en el path indicado. Para realizar una busqueda
841 874 correcta la estructura de directorios debe ser la siguiente:
842 875
843 876 ...path/D[yyyy][ddd]/expLabel/D[yyyy][ddd][sss].ext
844 877
845 878 [yyyy]: anio
846 879 [ddd] : dia del anio
847 880 [sss] : set del archivo
848 881
849 882 Inputs:
850 883 path : Directorio de datos donde se realizara la busqueda. Todos los
851 884 ficheros que concidan con el criterio de busqueda seran
852 885 almacenados en una lista y luego retornados.
853 886 startDateTime : Fecha inicial. Rechaza todos los archivos donde
854 887 file end time < startDateTime (objeto datetime.datetime)
855 888
856 889 endDateTime : Fecha final. Rechaza todos los archivos donde
857 890 file start time > endDateTime (obejto datetime.datetime)
858 891
859 892 set : Set del primer archivo a leer. Por defecto None
860 893
861 894 expLabel : Nombre del subdirectorio de datos. Por defecto ""
862 895
863 896 ext : Extension de los archivos a leer. Por defecto .r
864 897
865 898 Return:
866 899
867 900 (pathList, filenameList)
868 901
869 902 pathList : Lista de directorios donde se encontraron archivos dentro
870 903 de los parametros especificados
871 904 filenameList : Lista de archivos (ruta completa) que coincidieron con los
872 905 parametros especificados.
873 906
874 907 Variables afectadas:
875 908
876 909 self.filenameList: Lista de archivos (ruta completa) que la clase utiliza
877 910 como fuente para leer los bloque de datos, si se termina
878 911 de leer todos los bloques de datos de un determinado
879 912 archivo se pasa al siguiente archivo de la lista.
880 913 """
881 914
882 915 print "Searching files ..."
883 916
884 917 dirList = []
885 918 for thisPath in os.listdir(path):
886 919 if os.path.isdir(os.path.join(path,thisPath)):
887 920 dirList.append(thisPath)
888 921
889 922 pathList = []
890 923
891 924 thisDateTime = startDateTime
892 925
893 926 while(thisDateTime <= endDateTime):
894 927 year = thisDateTime.timetuple().tm_year
895 928 doy = thisDateTime.timetuple().tm_yday
896 929
897 930 match = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy))
898 931 if len(match) == 0:
899 932 thisDateTime += datetime.timedelta(1)
900 933 continue
901 934
902 935 pathList.append(os.path.join(path,match[0],expLabel))
903 936 thisDateTime += datetime.timedelta(1)
904 937
905 938 startUtSeconds = time.mktime(startDateTime.timetuple())
906 939 endUtSeconds = time.mktime(endDateTime.timetuple())
907 940
908 941 filenameList = []
909 942 for thisPath in pathList:
910 943 fileList = glob.glob1(thisPath, "*%s" %ext)
911 944 fileList.sort()
912 945 for file in fileList:
913 946 filename = os.path.join(thisPath,file)
914 947 if isThisFileinRange(filename, startUtSeconds, endUtSeconds):
915 948 filenameList.append(filename)
916 949
917 950 self.filenameList = filenameList
918 951
919 952 return pathList, filenameList
920 953
921 954
922 955 def __initFilesOnline( self, path, dirfilename, filename ):
923 956 """
924 957 Verifica que el primer file tenga una data valida, para ello leo el 1er bloque
925 958 del file, si no es un file valido espera una cierta cantidad de tiempo a que
926 959 lo sea, si transcurrido el tiempo no logra validar el file entonces el metodo
927 960 devuelve 0 caso contrario devuelve 1
928 961
929 962 Affected:
930 963 m_BasicHeader
931 964
932 965 Return:
933 966 0 : file no valido para ser leido
934 967 1 : file valido para ser leido
935 968 """
936 969 m_BasicHeader = BasicHeader()
937 970
938 971 file = os.path.join( path, dirfilename, filename )
939 972
940 973 nTries = 0
941 974 while(True):
942 975
943 976 nTries += 1
944 977 if nTries > self.__nTries:
945 978 break
946 979
947 980 try:
948 981 fp = open( file,'rb' ) #lectura binaria
949 982 except:
950 983 raise IOError, "The file %s can't be opened" %(file)
951 984
952 985 try:
953 986 m_BasicHeader.read(fp)
954 987 except:
955 988 print "The file %s is empty" % filename
956 989
957 990 fp.close()
958 991
959 992 if m_BasicHeader.size > 24:
960 993 break
961 994
962 995 print 'waiting for new block: try %02d' % ( nTries )
963 996 time.sleep( self.__delay)
964 997
965 998 if m_BasicHeader.size <= 24:
966 999 return 0
967 1000
968 1001 return 1
969 1002
970 1003
971 1004 def setup( self, path, startDateTime=None, endDateTime=None, set=None, expLabel = "", ext = ".pdata", online = 0 ):
972 1005 """
973 1006 setup configura los parametros de lectura de la clase SpectraReader.
974 1007
975 1008 Si el modo de lectura es offline, primero se realiza una busqueda de todos los archivos
976 1009 que coincidan con los parametros especificados; esta lista de archivos son almacenados en
977 1010 self.filenameList.
978 1011
979 1012 Input:
980 1013 path : Directorios donde se ubican los datos a leer. Dentro de este
981 1014 directorio deberia de estar subdirectorios de la forma:
982 1015
983 1016 path/D[yyyy][ddd]/expLabel/P[yyyy][ddd][sss][ext]
984 1017
985 1018 startDateTime : Fecha inicial. Rechaza todos los archivos donde
986 1019 file end time < startDatetime (objeto datetime.datetime)
987 1020
988 1021 endDateTime : Fecha final. Si no es None, rechaza todos los archivos donde
989 1022 file end time < startDatetime (objeto datetime.datetime)
990 1023
991 1024 set : Set del primer archivo a leer. Por defecto None
992 1025
993 1026 expLabel : Nombre del subdirectorio de datos. Por defecto ""
994 1027
995 1028 ext : Extension de los archivos a leer. Por defecto .pdata
996 1029
997 1030 online : Si es == a 0 entonces busca files que cumplan con las condiciones dadas
998 1031
999 1032 Return:
1000 1033 0 : Si no encuentra files que cumplan con las condiciones dadas
1001 1034 1 : Si encuentra files que cumplan con las condiciones dadas
1002 1035
1003 1036 Affected:
1004 1037 self.startUTCSeconds
1005 1038 self.endUTCSeconds
1006 1039 self.startYear
1007 1040 self.endYear
1008 1041 self.startDoy
1009 1042 self.endDoy
1010 1043 self.__pathList
1011 1044 self.filenameList
1012 1045 self.online
1013 1046 """
1014 1047
1015 1048 if online:
1016 1049 nTries = 0
1017 1050 while( nTries < self.__nTries ):
1018 1051 nTries += 1
1019 1052 subfolder = "D%04d%03d" % ( startDateTime.timetuple().tm_year,startDateTime.timetuple().tm_yday )
1020 1053 file = os.path.join( path, subfolder )
1021 1054 print "Searching first file in \"%s\", try %03d ..." % ( file, nTries )
1022 1055 year, doy, set, filename, dirfilename = self.__searchFilesOnLine( path, startDateTime, ext )
1023 1056 if filename == None:
1024 1057 time.sleep( self.__delay )
1025 1058 else:
1026 1059 break
1027 1060
1028 1061 if filename == None:
1029 1062 print "No files On Line"
1030 1063 return 0
1031 1064
1032 1065 if self.__initFilesOnline( path, dirfilename, filename ) == 0:
1033 1066 print "The file %s hasn't enough data"
1034 1067 return 0
1035 1068
1036 1069 self.__year = year
1037 1070 self.__doy = doy
1038 1071 self.__set = set - 1
1039 1072 self.__path = path
1040 1073
1041 1074 else:
1042 1075 pathList, filenameList = self.__searchFilesOffLine( path, startDateTime, endDateTime, set, expLabel, ext )
1043 1076 self.__idFile = -1
1044 1077 self.__pathList = pathList
1045 1078 self.filenameList = filenameList
1046 1079
1047 1080 self.online = online
1048 1081 self.__ext = ext
1049 1082
1050 1083 if not(self.__setNextFile()):
1051 1084 if (startDateTime != None) and (endDateTime != None):
1052 1085 print "No files in range: %s - %s" %(startDateTime.ctime(), endDateTime.ctime())
1053 1086 elif startDateTime != None:
1054 1087 print "No files in : %s" % startDateTime.ctime()
1055 1088 else:
1056 1089 print "No files"
1057 1090 return 0
1058 1091
1059 1092 if startDateTime != None:
1060 1093 self.startUTCSeconds = time.mktime(startDateTime.timetuple())
1061 1094 self.startYear = startDateTime.timetuple().tm_year
1062 1095 self.startDoy = startDateTime.timetuple().tm_yday
1063 1096
1064 1097 if endDateTime != None:
1065 1098 self.endUTCSeconds = time.mktime(endDateTime.timetuple())
1066 1099 self.endYear = endDateTime.timetuple().tm_year
1067 1100 self.endDoy = endDateTime.timetuple().tm_yday
1068 1101 #call fillHeaderValues() - to Data Object
1069 1102
1070 1103 self.m_Spectra.m_BasicHeader = self.m_BasicHeader.copy()
1071 1104 self.m_Spectra.m_ProcessingHeader = self.m_ProcessingHeader.copy()
1072 1105 self.m_Spectra.m_RadarControllerHeader = self.m_RadarControllerHeader.copy()
1073 1106 self.m_Spectra.m_SystemHeader = self.m_SystemHeader.copy()
1074 1107 self.m_Spectra.dataType = self.__dataType
1075 1108
1076 1109 return 1
1077 1110
1078 1111
1079 1112 def readNextBlock(self):
1080 1113 """
1081 1114 Establece un nuevo bloque de datos a leer y los lee, si es que no existiese
1082 1115 mas bloques disponibles en el archivo actual salta al siguiente.
1083 1116
1084 1117 Affected:
1085 1118 self.__lastUTTime
1086 1119
1087 1120 Return: None
1088 1121 """
1089 1122
1090 1123 if not( self.__setNewBlock() ):
1091 1124 return 0
1092
1093 if self.online:
1094 nTries = 0
1095 while( nTries < self.__nTries ):
1096 nTries += 1
1097 if self.__readBlock() == 0:
1098 print "Waiting for the next block ..."
1099 time.sleep( self.__delay )
1100 else:
1101 break
1102 else:
1103 self.__readBlock()
1125
1126 self.__readBlock()
1104 1127
1105 1128 self.__lastUTTime = self.m_BasicHeader.utc
1106 1129
1107 1130 return 1
1108 1131
1109 1132
1110 1133 def getData(self):
1111 1134 """
1112 1135 Copia el buffer de lectura a la clase "Spectra",
1113 1136 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
1114 1137 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
1115 1138
1116 1139 Return:
1117 1140 0 : Si no hay mas archivos disponibles
1118 1141 1 : Si hizo una buena copia del buffer
1119 1142
1120 1143 Variables afectadas:
1121 1144 self.m_Spectra
1122 1145 self.__datablockIndex
1123 1146 self.flagResetProcessing
1124 1147 self.flagIsNewBlock
1125 1148 """
1126 1149
1127 1150 self.flagResetProcessing = 0
1128 1151 self.flagIsNewBlock = 0
1129 1152
1130 1153 if self.__hasNotDataInBuffer():
1154
1131 1155 self.readNextBlock()
1132 1156
1133 1157 self.m_Spectra.m_BasicHeader = self.m_BasicHeader.copy()
1134 1158 self.m_Spectra.m_ProcessingHeader = self.m_ProcessingHeader.copy()
1135 1159 self.m_Spectra.m_RadarControllerHeader = self.m_RadarControllerHeader.copy()
1136 1160 self.m_Spectra.m_SystemHeader = self.m_SystemHeader.copy()
1137 1161 self.m_Spectra.heights = self.__heights
1138 1162 self.m_Spectra.dataType = self.__dataType
1139 1163
1140 1164 if self.noMoreFiles == 1:
1141 1165 print 'Process finished'
1142 1166 return 0
1143 1167
1144 1168 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
1145 1169
1146 1170 self.m_Spectra.flagNoData = False
1147 1171 self.m_Spectra.flagResetProcessing = self.flagResetProcessing
1148 1172
1149 1173 self.m_Spectra.data_spc = self.__data_spc
1150 1174 self.m_Spectra.data_cspc = self.__data_cspc
1151 1175 self.m_Spectra.data_dc = self.__data_dc
1152 1176
1153 1177 #call setData - to Data Object
1154 1178 #self.datablock_id += 1
1155 1179 #self.idProfile += 1
1156 1180
1157 1181 return 1
1158 1182
1159 1183
1160 1184 class SpectraWriter( DataWriter ):
1161 1185 """
1162 1186 Esta clase permite escribir datos de espectros a archivos procesados (.pdata). La escritura
1163 1187 de los datos siempre se realiza por bloques.
1164 1188 """
1165 1189
1166 1190 def __init__( self, m_Spectra = None ):
1167 1191 """
1168 1192 Inicializador de la clase SpectraWriter para la escritura de datos de espectros.
1169 1193
1170 1194 Affected:
1171 1195 self.m_Spectra
1172 1196 self.m_BasicHeader
1173 1197 self.m_SystemHeader
1174 1198 self.m_RadarControllerHeader
1175 1199 self.m_ProcessingHeader
1176 1200
1177 1201 Return: None
1178 1202 """
1179 1203
1180 1204 if m_Spectra == None:
1181 1205 m_Spectra = Spectra()
1182 1206
1183 1207 self.m_Spectra = m_Spectra
1184 1208
1185 1209 self.__path = None
1186 1210
1187 1211 self.__fp = None
1188 1212
1189 1213 self.__format = None
1190 1214
1191 1215 self.__blocksCounter = 0
1192 1216
1193 1217 self.__setFile = None
1194 1218
1195 1219 self.__flagIsNewFile = 1
1196 1220
1197 1221 self.__dataType = None
1198 1222
1199 1223 self.__ext = None
1200 1224
1201 1225 self.__shape_spc_Buffer = None
1202 1226 self.__shape_cspc_Buffer = None
1203 1227 self.__shape_dc_Buffer = None
1204 1228
1205 1229 self.nWriteBlocks = 0
1206 1230
1207 1231 self.flagIsNewBlock = 0
1208 1232
1209 1233 self.noMoreFiles = 0
1210 1234
1211 1235 self.filename = None
1212 1236
1213 1237 self.m_BasicHeader= BasicHeader()
1214 1238
1215 1239 self.m_SystemHeader = SystemHeader()
1216 1240
1217 1241 self.m_RadarControllerHeader = RadarControllerHeader()
1218 1242
1219 1243 self.m_ProcessingHeader = ProcessingHeader()
1220 1244
1221 1245 self.__data_spc = None
1222 1246 self.__data_cspc = None
1223 1247 self.__data_dc = None
1224 1248
1225 1249 def __writeFirstHeader( self ):
1226 1250 """
1227 1251 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1228 1252
1229 1253 Affected:
1230 1254 __dataType
1231 1255
1232 1256 Return:
1233 1257 None
1234 1258 """
1235 1259 self.__writeBasicHeader()
1236 1260 self.__wrSystemHeader()
1237 1261 self.__wrRadarControllerHeader()
1238 1262 self.__wrProcessingHeader()
1239 1263 self.__dataType = self.m_Spectra.dataType
1240 1264
1241 1265 def __writeBasicHeader( self, fp=None ):
1242 1266 """
1243 1267 Escribe solo el Basic header en el file creado
1244 1268
1245 1269 Return:
1246 1270 None
1247 1271 """
1248 1272 if fp == None:
1249 1273 fp = self.__fp
1250 1274
1251 1275 self.m_BasicHeader.write(fp)
1252 1276
1253 1277 def __wrSystemHeader( self, fp=None ):
1254 1278 """
1255 1279 Escribe solo el System header en el file creado
1256 1280
1257 1281 Return:
1258 1282 None
1259 1283 """
1260 1284 if fp == None:
1261 1285 fp = self.__fp
1262 1286
1263 1287 self.m_SystemHeader.write(fp)
1264 1288
1265 1289 def __wrRadarControllerHeader( self, fp=None ):
1266 1290 """
1267 1291 Escribe solo el RadarController header en el file creado
1268 1292
1269 1293 Return:
1270 1294 None
1271 1295 """
1272 1296 if fp == None:
1273 1297 fp = self.__fp
1274 1298
1275 1299 self.m_RadarControllerHeader.write(fp)
1276 1300
1277 1301 def __wrProcessingHeader( self, fp=None ):
1278 1302 """
1279 1303 Escribe solo el Processing header en el file creado
1280 1304
1281 1305 Return:
1282 1306 None
1283 1307 """
1284 1308 if fp == None:
1285 1309 fp = self.__fp
1286 1310
1287 1311 self.m_ProcessingHeader.write(fp)
1288 1312
1289 1313 def __setNextFile( self ):
1290 1314 """
1291 1315 Determina el siguiente file que sera escrito
1292 1316
1293 1317 Affected:
1294 1318 self.filename
1295 1319 self.__subfolder
1296 1320 self.__fp
1297 1321 self.__setFile
1298 1322 self.__flagIsNewFile
1299 1323
1300 1324 Return:
1301 1325 0 : Si el archivo no puede ser escrito
1302 1326 1 : Si el archivo esta listo para ser escrito
1303 1327 """
1304 1328 ext = self.__ext
1305 1329 path = self.__path
1306 1330
1307 1331 if self.__fp != None:
1308 1332 self.__fp.close()
1309 1333
1310 1334 if self.m_BasicHeader.size <= 24: return 0 #no existe la suficiente data para ser escrita
1311 1335
1312 1336 timeTuple = time.localtime(self.m_Spectra.m_BasicHeader.utc) # utc from m_Spectra
1313 1337 subfolder = 'D%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
1314 1338
1315 1339 tmp = os.path.join( path, subfolder )
1316 1340 if not( os.path.exists(tmp) ):
1317 1341 os.mkdir(tmp)
1318 1342 self.__setFile = -1 #inicializo mi contador de seteo
1319 1343 else:
1320 1344 filesList = os.listdir( tmp )
1321 1345 if len( filesList ) > 0:
1322 1346 filesList = sorted( filesList, key=str.lower )
1323 1347 filen = filesList[-1]
1324 1348 # el filename debera tener el siguiente formato
1325 1349 # 0 1234 567 89A BCDE (hex)
1326 1350 # P YYYY DDD SSS .ext
1327 1351 if isNumber( filen[8:11] ):
1328 1352 self.__setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
1329 1353 else:
1330 1354 self.__setFile = -1
1331 1355 else:
1332 1356 self.__setFile = -1 #inicializo mi contador de seteo
1333 1357
1334 1358 setFile = self.__setFile
1335 1359 setFile += 1
1336 1360 file = 'P%4.4d%3.3d%3.3d%s' % ( timeTuple.tm_year, timeTuple.tm_yday, setFile, ext )
1337 1361
1338 1362 filename = os.path.join( path, subfolder, file )
1339 1363
1340 1364 fp = open(filename,'wb')
1341 1365
1342 1366 self.__blocksCounter = 0
1343 1367
1344 1368 #guardando atributos
1345 1369 self.filename = filename
1346 1370 self.__subfolder = subfolder
1347 1371 self.__fp = fp
1348 1372 self.__setFile = setFile
1349 1373 self.__flagIsNewFile = 1
1350 1374
1351 1375 print 'Writing the file: %s'%self.filename
1352 1376
1353 1377 self.__writeFirstHeader()
1354 1378
1355 1379 return 1
1356 1380
1357 1381 def __setNewBlock( self ):
1358 1382 """
1359 1383 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1360 1384
1361 1385 Return:
1362 1386 0 : si no pudo escribir nada
1363 1387 1 : Si escribio el Basic el First Header
1364 1388 """
1365 1389 if self.__fp == None:
1366 1390 self.__setNextFile()
1367 1391
1368 1392 if self.__flagIsNewFile:
1369 1393 return 1
1370 1394
1371 1395 if self.__blocksCounter < self.m_ProcessingHeader.dataBlocksPerFile:
1372 1396 self.__writeBasicHeader()
1373 1397 return 1
1374 1398
1375 1399 if not(self.__setNextFile()):
1376 1400 return 0
1377 1401
1378 1402 return 1
1379 1403
1380 1404 def __writeBlock( self ):
1381 1405 """
1382 1406 Escribe el buffer en el file designado
1383 1407
1384 1408 Affected:
1385 1409 self.__data_spc
1386 1410 self.__data_cspc
1387 1411 self.__data_dc
1388 1412 self.__flagIsNewFile
1389 1413 self.flagIsNewBlock
1390 1414 self.nWriteBlocks
1391 1415 self.__blocksCounter
1392 1416
1393 1417 Return: None
1394 1418 """
1395 1419 spc = numpy.transpose( self.__data_spc, (0,2,1) )
1396 1420 if not( self.m_ProcessingHeader.shif_fft ):
1397 1421 spc = numpy.roll( spc, self.m_ProcessingHeader.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
1398 1422 data = spc.reshape((-1))
1399 1423 data.tofile(self.__fp)
1400 1424
1401 1425 data = numpy.zeros( self.__shape_cspc_Buffer, self.__dataType )
1402 1426 cspc = numpy.transpose( self.__data_cspc, (0,2,1) )
1403 1427 if not( self.m_ProcessingHeader.shif_fft ):
1404 1428 cspc = numpy.roll( cspc, self.m_ProcessingHeader.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
1405 1429 data['real'] = cspc.real
1406 1430 data['imag'] = cspc.imag
1407 1431 data = data.reshape((-1))
1408 1432 data.tofile(self.__fp)
1409 1433
1410 1434 data = numpy.zeros( self.__shape_dc_Buffer, self.__dataType )
1411 1435 dc = self.__data_dc
1412 1436 data['real'] = dc.real
1413 1437 data['imag'] = dc.imag
1414 1438 data = data.reshape((-1))
1415 1439 data.tofile(self.__fp)
1416 1440
1417 1441 self.__data_spc.fill(0)
1418 1442 self.__data_cspc.fill(0)
1419 1443 self.__data_dc.fill(0)
1420 1444
1421 1445 self.__flagIsNewFile = 0
1422 1446
1423 1447 self.flagIsNewBlock = 1
1424 1448
1425 1449 self.nWriteBlocks += 1
1426 1450
1427 1451 self.__blocksCounter += 1
1428 1452
1429 1453
1430 1454 def writeNextBlock( self ):
1431 1455 """
1432 1456 Selecciona el bloque siguiente de datos y los escribe en un file
1433 1457
1434 1458 Return:
1435 1459 0 : Si no hizo pudo escribir el bloque de datos
1436 1460 1 : Si no pudo escribir el bloque de datos
1437 1461 """
1438 1462 if not( self.__setNewBlock() ):
1439 1463 return 0
1440 1464
1441 1465 self.__writeBlock()
1442 1466
1443 1467 return 1
1444 1468
1445 1469
1446 1470 def __hasAllDataInBuffer( self ):
1447 1471 return 1
1448 1472
1449 1473
1450 1474 def putData( self ):
1451 1475 """
1452 1476 Setea un bloque de datos y luego los escribe en un file
1453 1477
1454 1478 Affected:
1455 1479 self.__data_spc
1456 1480 self.__data_cspc
1457 1481 self.__data_dc
1458 1482
1459 1483 Return:
1460 1484 0 : Si no hay data o no hay mas files que puedan escribirse
1461 1485 1 : Si se escribio la data de un bloque en un file
1462 1486 """
1463 1487 self.flagIsNewBlock = 0
1464 1488
1465 1489 if self.m_Spectra.flagNoData:
1466 1490 return 0
1467 1491
1468 1492 if self.m_Spectra.flagResetProcessing:
1469 1493 self.__data_spc.fill(0)
1470 1494 self.__data_cspc.fill(0)
1471 1495 self.__data_dc.fill(0)
1472 1496 self.__setNextFile()
1473 1497
1474 1498 self.__data_spc = self.m_Spectra.data_spc
1475 1499 self.__data_cspc = self.m_Spectra.data_cspc
1476 1500 self.__data_dc = self.m_Spectra.data_dc
1477 1501
1478 1502 if True:
1479 1503 time.sleep( 3 )
1480 1504 self.__getHeader()
1481 1505 self.writeNextBlock()
1482 1506
1483 1507 if self.noMoreFiles:
1484 1508 #print 'Process finished'
1485 1509 return 0
1486 1510
1487 1511 return 1
1488 1512
1489 1513 def __getHeader( self ):
1490 1514 """
1491 1515 Obtiene una copia del First Header
1492 1516
1493 1517 Affected:
1494 1518 self.m_BasicHeader
1495 1519 self.m_SystemHeader
1496 1520 self.m_RadarControllerHeader
1497 1521 self.m_ProcessingHeader
1498 1522 self.__dataType
1499 1523
1500 1524 Return:
1501 1525 None
1502 1526 """
1503 1527 self.m_BasicHeader = self.m_Spectra.m_BasicHeader.copy()
1504 1528 self.m_SystemHeader = self.m_Spectra.m_SystemHeader.copy()
1505 1529 self.m_RadarControllerHeader = self.m_Spectra.m_RadarControllerHeader.copy()
1506 1530 self.m_ProcessingHeader = self.m_Spectra.m_ProcessingHeader.copy()
1507 1531 self.__dataType = self.m_Spectra.dataType
1508 1532
1509 1533 def __setHeaderByFile(self):
1510 1534
1511 1535 format = self.__format
1512 1536 header = ['Basic','System','RadarController','Processing']
1513 1537
1514 1538 fmtFromFile = None
1515 1539 headerFromFile = None
1516 1540
1517 1541
1518 1542 fileTable = self.__configHeaderFile
1519 1543
1520 1544 if os.access(fileTable, os.R_OK):
1521 1545 import re, string
1522 1546
1523 1547 f = open(fileTable,'r')
1524 1548 lines = f.read()
1525 1549 f.close()
1526 1550
1527 1551 #Delete comments into expConfig
1528 1552 while 1:
1529 1553
1530 1554 startComment = string.find(lines.lower(),'#')
1531 1555 if startComment == -1:
1532 1556 break
1533 1557 endComment = string.find(lines.lower(),'\n',startComment)
1534 1558 lines = string.replace(lines,lines[startComment:endComment+1],'', 1)
1535 1559
1536 1560 while expFromFile == None:
1537 1561
1538 1562 currFmt = string.find(lines.lower(),'format="%s"' %(expName))
1539 1563 nextFmt = string.find(lines.lower(),'format',currFmt+10)
1540 1564
1541 1565 if currFmt == -1:
1542 1566 break
1543 1567 if nextFmt == -1:
1544 1568 nextFmt = len(lines)-1
1545 1569
1546 1570 fmtTable = lines[currFmt:nextFmt]
1547 1571 lines = lines[nextFmt:]
1548 1572
1549 1573 fmtRead = self.__getValueFromArg(fmtTable,'format')
1550 1574 if fmtRead != format:
1551 1575 continue
1552 1576 fmtFromFile = fmtRead
1553 1577
1554 1578 lines2 = fmtTable
1555 1579
1556 1580 while headerFromFile == None:
1557 1581
1558 1582 currHeader = string.find(lines2.lower(),'header="%s"' %(header))
1559 1583 nextHeader = string.find(lines2.lower(),'header',currHeader+10)
1560 1584
1561 1585 if currHeader == -1:
1562 1586 break
1563 1587 if nextHeader == -1:
1564 1588 nextHeader = len(lines2)-1
1565 1589
1566 1590 headerTable = lines2[currHeader:nextHeader]
1567 1591 lines2 = lines2[nextHeader:]
1568 1592
1569 1593 headerRead = self.__getValueFromArg(headerTable,'site')
1570 1594 if not(headerRead in header):
1571 1595 continue
1572 1596 headerFromFile = headerRead
1573 1597
1574 1598 if headerRead == 'Basic':
1575 1599 self.m_BasicHeader.size = self.__getValueFromArg(headerTable,'size',lower=False)
1576 1600 self.m_BasicHeader.version = self.__getValueFromArg(headerTable,'version',lower=False)
1577 1601 self.m_BasicHeader.dataBlock = self.__getValueFromArg(headerTable,'dataBlock',lower=False)
1578 1602 self.m_BasicHeader.utc = self.__getValueFromArg(headerTable,'utc',lower=False)
1579 1603 self.m_BasicHeader.miliSecond = self.__getValueFromArg(headerTable,'miliSecond',lower=False)
1580 1604 self.m_BasicHeader.timeZone = self.__getValueFromArg(headerTable,'timeZone',lower=False)
1581 1605 self.m_BasicHeader.dstFlag = self.__getValueFromArg(headerTable,'dstFlag',lower=False)
1582 1606 self.m_BasicHeader.errorCount = self.__getValueFromArg(headerTable,'errorCount',lower=False)
1583 1607
1584 1608 else:
1585 1609 print "file access denied:%s"%fileTable
1586 1610 sys.exit(0)
1587 1611
1588 1612 def setup( self, path, format='pdata' ):
1589 1613 """
1590 1614 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1591 1615
1592 1616 Inputs:
1593 1617 path : el path destino en el cual se escribiran los files a crear
1594 1618 format : formato en el cual sera salvado un file
1595 1619
1596 1620 Return:
1597 1621 0 : Si no realizo un buen seteo
1598 1622 1 : Si realizo un buen seteo
1599 1623 """
1600 1624 if format == 'hdf5':
1601 1625 ext = '.hdf5'
1602 1626 format = 'hdf5'
1603 1627 print 'call hdf5 library'
1604 1628 return 0
1605 1629
1606 1630 if format == 'rawdata':
1607 1631 ext = '.r'
1608 1632 format = 'Jicamarca'
1609 1633
1610 1634 if format == 'pdata':
1611 1635 ext = '.pdata'
1612 1636 format = 'pdata'
1613 1637
1614 1638 #call to config_headers
1615 1639 #self.__setHeaderByFile()
1616 1640
1617 1641 self.__path = path
1618 1642 self.__setFile = -1
1619 1643 self.__ext = ext
1620 1644 self.__format = format
1621 1645
1622 1646 self.__getHeader()
1623 1647
1624 1648 self.__shape_spc_Buffer = ( self.m_Spectra.nChannels,
1625 1649 self.m_ProcessingHeader.numHeights,
1626 1650 self.m_ProcessingHeader.profilesPerBlock
1627 1651 )
1628 1652
1629 1653 self.__shape_cspc_Buffer = ( self.m_Spectra.nPairs,
1630 1654 self.m_ProcessingHeader.numHeights,
1631 1655 self.m_ProcessingHeader.profilesPerBlock
1632 1656 )
1633 1657
1634 1658 self.__shape_dc_Buffer = ( self.m_SystemHeader.numChannels,
1635 1659 self.m_ProcessingHeader.numHeights
1636 1660 )
1637 1661
1638 1662 if not( self.__setNextFile() ):
1639 1663 print "There isn't a next file" #"zzzzzzzzzzzz"
1640 1664 return 0
1641 1665
1642 1666 return 1 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now