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