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