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