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