##// END OF EJS Templates
Se corrige un bug de la version anterior en el metodo JRODataReader.setup, se modificaron los mensajes a imprimir cuando no hay datos para el rango de Dates y Times
Daniel Valdez -
r118:84dce9e8f4f8
parent child
Show More
@@ -1,1266 +1,1267
1 1 '''
2 2 Created on 23/01/2012
3 3
4 4 @author $Author$
5 5 @version $Id$
6 6 @version $Id$
7 7 '''
8 8
9 9 import os, sys
10 10 import glob
11 11 import time
12 12 import numpy
13 13 import fnmatch
14 14 import time, datetime
15 15
16 16 path = os.path.split(os.getcwd())[0]
17 17 sys.path.append(path)
18 18
19 19 from Model.JROHeader import *
20 20 from Model.JROData import JROData
21 21
22 22 def checkForRealPath(path, year, doy, set, ext):
23 23 """
24 24 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
25 25 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
26 26 el path exacto de un determinado file.
27 27
28 28 Example :
29 29 nombre correcto del file es .../.../D2009307/P2009307367.ext
30 30
31 31 Entonces la funcion prueba con las siguientes combinaciones
32 32 .../.../x2009307/y2009307367.ext
33 33 .../.../x2009307/Y2009307367.ext
34 34 .../.../X2009307/y2009307367.ext
35 35 .../.../X2009307/Y2009307367.ext
36 36 siendo para este caso, la ultima combinacion de letras, identica al file buscado
37 37
38 38 Return:
39 39 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
40 40 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
41 41 para el filename
42 42 """
43 43 filepath = None
44 44 find_flag = False
45 45 filename = None
46 46
47 47 if ext.lower() == ".r": #voltage
48 48 header1 = "dD"
49 49 header2 = "dD"
50 50 elif ext.lower() == ".pdata": #spectra
51 51 header1 = "dD"
52 52 header2 = "pP"
53 53 else:
54 54 return None, filename
55 55
56 56 for dir in header1: #barrido por las dos combinaciones posibles de "D"
57 57 for fil in header2: #barrido por las dos combinaciones posibles de "D"
58 58 doypath = "%s%04d%03d" % ( dir, year, doy ) #formo el nombre del directorio xYYYYDDD (x=d o x=D)
59 59 filename = "%s%04d%03d%03d%s" % ( fil, year, doy, set, ext ) #formo el nombre del file xYYYYDDDSSS.ext
60 60 filepath = os.path.join( path, doypath, filename ) #formo el path completo
61 61 if os.path.exists( filepath ): #verifico que exista
62 62 find_flag = True
63 63 break
64 64 if find_flag:
65 65 break
66 66
67 67 if not(find_flag):
68 68 return None, filename
69 69
70 70 return filepath, filename
71 71
72 72
73 73 def isNumber(str):
74 74 """
75 75 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
76 76
77 77 Excepciones:
78 78 Si un determinado string no puede ser convertido a numero
79 79 Input:
80 80 str, string al cual se le analiza para determinar si convertible a un numero o no
81 81
82 82 Return:
83 83 True : si el string es uno numerico
84 84 False : no es un string numerico
85 85 """
86 86 try:
87 87 float( str )
88 88 return True
89 89 except:
90 90 return False
91 91
92 92
93 93 def isThisFileinRange(filename, startUTSeconds, endUTSeconds):
94 94 """
95 95 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
96 96
97 97 Inputs:
98 98 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
99 99
100 100 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
101 101 segundos contados desde 01/01/1970.
102 102 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
103 103 segundos contados desde 01/01/1970.
104 104
105 105 Return:
106 106 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
107 107 fecha especificado, de lo contrario retorna False.
108 108
109 109 Excepciones:
110 110 Si el archivo no existe o no puede ser abierto
111 111 Si la cabecera no puede ser leida.
112 112
113 113 """
114 114 m_BasicHeader = BasicHeader()
115 115
116 116 try:
117 117 fp = open(filename,'rb')
118 118 except:
119 119 raise IOError, "The file %s can't be opened" %(filename)
120 120
121 121 sts = m_BasicHeader.read(fp)
122 122 fp.close()
123 123
124 124 if not(sts):
125 125 print "Skipping the file %s because it has not a valid header" %(filename)
126 126 return 0
127 127
128 128 if not ((startUTSeconds <= m_BasicHeader.utc) and (endUTSeconds > m_BasicHeader.utc)):
129 129 return 0
130 130
131 131 return 1
132 132
133 133
134 134 def getlastFileFromPath(path, ext):
135 135 """
136 136 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
137 137 al final de la depuracion devuelve el ultimo file de la lista que quedo.
138 138
139 139 Input:
140 140 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
141 141 ext : extension de los files contenidos en una carpeta
142 142
143 143 Return:
144 144 El ultimo file de una determinada carpeta, no se considera el path.
145 145 """
146 146 validFilelist = []
147 147 fileList = os.listdir(path)
148 148
149 149 # 0 1234 567 89A BCDE
150 150 # H YYYY DDD SSS .ext
151 151
152 152 for file in fileList:
153 153 try:
154 154 year = int(file[1:5])
155 155 doy = int(file[5:8])
156 156
157 157 if (os.path.splitext(file)[-1].upper() != ext.upper()) : continue
158 158 except:
159 159 continue
160 160
161 161 validFilelist.append(file)
162 162
163 163 if validFilelist:
164 164 validFilelist = sorted( validFilelist, key=str.lower )
165 165 return validFilelist[-1]
166 166
167 167 return None
168 168
169 169 class JRODataIO:
170 170
171 171 #speed of light
172 172 c = 3E8
173 173
174 174 m_BasicHeader = BasicHeader()
175 175
176 176 m_SystemHeader = SystemHeader()
177 177
178 178 m_RadarControllerHeader = RadarControllerHeader()
179 179
180 180 m_ProcessingHeader = ProcessingHeader()
181 181
182 182 dataOutObj = None
183 183
184 184 online = 0
185 185
186 186 fp = None
187 187
188 188 dataType = None
189 189
190 190 fileSizeByHeader = None
191 191
192 192 filenameList = []
193 193
194 194 filename = None
195 195
196 196 fileSize = None
197 197
198 198 firstHeaderSize = 0
199 199
200 200 basicHeaderSize = 24
201 201
202 202 nTotalBlocks = 0
203 203
204 204 ippSeconds = 0
205 205
206 206 blocksize = 0
207 207
208 208 set = 0
209 209
210 210 ext = None
211 211
212 212 path = None
213 213
214 214 maxTimeStep = 30
215 215
216 216
217 217 delay = 3 #seconds
218 218
219 219 nTries = 3 #quantity tries
220 220
221 221 nFiles = 3 #number of files for searching
222 222
223 223
224 224 flagNoMoreFiles = 0
225 225
226 226 flagIsNewFile = 1
227 227
228 228 flagResetProcessing = 0
229 229
230 230 flagIsNewBlock = 0
231 231
232 232 def __init__(self):
233 233 pass
234 234
235 235 class JRODataReader(JRODataIO):
236 236
237 237 """
238 238 Esta clase es usada como la clase padre de las clases VoltageReader y SpectraReader.
239 239 Contiene todos lo metodos necesarios para leer datos desde archivos en formato
240 240 jicamarca o pdata (.r o .pdata). La lectura de los datos siempre se realiza por bloques. Los datos
241 241 leidos son array de 3 dimensiones:
242 242
243 243 Para Voltajes - perfiles * alturas * canales
244 244
245 245 Para Spectra - paresCanalesIguales * alturas * perfiles (Self Spectra)
246 246 paresCanalesDiferentes * alturas * perfiles (Cross Spectra)
247 247 canales * alturas (DC Channels)
248 248
249 249 y son almacenados en su buffer respectivo.
250 250
251 251 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
252 252 RadarControllerHeader y DataObj. Los tres primeros se usan para almacenar informacion de la
253 253 cabecera de datos (metadata), y el cuarto (DataObj) para obtener y almacenar los datos desde
254 254 el buffer de datos cada vez que se ejecute el metodo "getData".
255 255 """
256 256
257 257 nReadBlocks = 0
258 258
259 259 def __init__(self, dataOutObj=None):
260 260
261 261 raise ValueError, "This class can't be instanced"
262 262
263 263
264 264 def hasNotDataInBuffer(self):
265 265
266 266 raise ValueError, "Not implemented"
267 267
268 268 def getBlockDimension(self):
269 269
270 270 raise ValueError, "No implemented"
271 271
272 272 def readBlock(self):
273 273
274 274 self.nTotalBlocks += 1
275 275 self.nReadBlocks += 1
276 276
277 277 raise ValueError, "This method has not been implemented"
278 278
279 279 def getData( self ):
280 280
281 281 raise ValueError, "This method has not been implemented"
282 282
283 283 def createObjByDefault(self):
284 284 """
285 285 Los objetos creados por defecto por cada clase (Voltaje o Espectro) difieren en el tipo
286 286 raise ValueError, "This method has not been implemented
287 287 """
288 288 raise ValueError, "This method has not been implemented"
289 289
290 290 # def setup(self, dataOutObj=None, path=None, startDateTime=None, endDateTime=None, set=0, expLabel = "", ext = None, online = 0):
291 291
292 292 def __searchFilesOnLine(self, path, expLabel = "", ext = None, startDate=None, endDate=None, startTime=None, endTime=None):
293 293 """
294 294 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
295 295 devuelve el archivo encontrado ademas de otros datos.
296 296
297 297 Input:
298 298 path : carpeta donde estan contenidos los files que contiene data
299 299
300 300 startDate : Fecha inicial. Rechaza todos los directorios donde
301 301 file end time < startDate (obejto datetime.date)
302 302
303 303 endDate : Fecha final. Rechaza todos los directorios donde
304 304 file start time > endDate (obejto datetime.date)
305 305
306 306 startTime : Tiempo inicial. Rechaza todos los archivos donde
307 307 file end time < startTime (obejto datetime.time)
308 308
309 309 endTime : Tiempo final. Rechaza todos los archivos donde
310 310 file start time > endTime (obejto datetime.time)
311 311
312 312 ext : extension de los files
313 313
314 314 Return:
315 315 directory : eL directorio donde esta el file encontrado
316 316 filename : el ultimo file de una determinada carpeta
317 317 year : el anho
318 318 doy : el numero de dia del anho
319 319 set : el set del archivo
320 320
321 321
322 322 """
323 323 dirList = []
324 324 pathList = []
325 325 directory = None
326 326
327 327 #Filtra solo los directorios
328 328 for thisPath in os.listdir(path):
329 329 if os.path.isdir(os.path.join(path, thisPath)):
330 330 dirList.append(thisPath)
331 331
332 332 if not(dirList):
333 333 return None, None, None, None, None
334 334
335 335 dirList = sorted( dirList, key=str.lower )
336 336
337 337 if startDate:
338 338 startDateTime = datetime.datetime.combine(startDate, startTime)
339 339 thisDateTime = startDateTime
340 340 if endDate == None: endDateTime = startDateTime
341 341 else: endDateTime = datetime.datetime.combine(endDate, endTime)
342 342
343 343 while(thisDateTime <= endDateTime):
344 344 year = thisDateTime.timetuple().tm_year
345 345 doy = thisDateTime.timetuple().tm_yday
346 346
347 347 match = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy))
348 348 if len(match) == 0:
349 349 thisDateTime += datetime.timedelta(1)
350 350 continue
351 351
352 352 pathList.append(os.path.join(path,match[0], expLabel))
353 353 thisDateTime += datetime.timedelta(1)
354 354
355 355 if not(pathList):
356 356 print "\tNo files in range: %s - %s" %(startDateTime.ctime(), endDateTime.ctime())
357 357 return None, None, None, None, None
358 358
359 359 directory = pathList[0]
360 360
361 361 else:
362 362 directory = dirList[-1]
363 363 directory = os.path.join(path,directory)
364 364
365 365 filename = getlastFileFromPath(directory, ext)
366 366
367 367 if not(filename):
368 368 return None, None, None, None, None
369 369
370 370 if not(self.__verifyFile(os.path.join(directory, filename))):
371 371 return None, None, None, None, None
372 372
373 373 year = int( filename[1:5] )
374 374 doy = int( filename[5:8] )
375 375 set = int( filename[8:11] )
376 376
377 377 return directory, filename, year, doy, set
378 378
379 379
380 380 def __searchFilesOffLine(self, path, startDate, endDate, startTime=datetime.time(0,0,0), endTime=datetime.time(23,59,59),set=None, expLabel = "", ext = ".r"):
381 381 """
382 382 Realiza una busqueda de los archivos que coincidan con los parametros
383 383 especificados y se encuentren ubicados en el path indicado. Para realizar una busqueda
384 384 correcta la estructura de directorios debe ser la siguiente:
385 385
386 386 ...path/D[yyyy][ddd]/expLabel/D[yyyy][ddd][sss].ext
387 387
388 388 [yyyy]: anio
389 389 [ddd] : dia del anio
390 390 [sss] : set del archivo
391 391
392 392 Inputs:
393 393 path : Directorio de datos donde se realizara la busqueda. Todos los
394 394 ficheros que concidan con el criterio de busqueda seran
395 395 almacenados en una lista y luego retornados.
396 396 startDate : Fecha inicial. Rechaza todos los directorios donde
397 397 file end time < startDate (obejto datetime.date)
398 398
399 399 endDate : Fecha final. Rechaza todos los directorios donde
400 400 file start time > endDate (obejto datetime.date)
401 401
402 402 startTime : Tiempo inicial. Rechaza todos los archivos donde
403 403 file end time < startTime (obejto datetime.time)
404 404
405 405 endTime : Tiempo final. Rechaza todos los archivos donde
406 406 file start time > endTime (obejto datetime.time)
407 407
408 408 set : Set del primer archivo a leer. Por defecto None
409 409
410 410 expLabel : Nombre del subdirectorio de datos. Por defecto ""
411 411
412 412 ext : Extension de los archivos a leer. Por defecto .r
413 413
414 414 Return:
415 415
416 416 (pathList, filenameList)
417 417
418 418 pathList : Lista de directorios donde se encontraron archivos dentro
419 419 de los parametros especificados
420 420 filenameList : Lista de archivos (ruta completa) que coincidieron con los
421 421 parametros especificados.
422 422
423 423 Variables afectadas:
424 424
425 425 self.filenameList: Lista de archivos (ruta completa) que la clase utiliza
426 426 como fuente para leer los bloque de datos, si se termina
427 427 de leer todos los bloques de datos de un determinado
428 428 archivo se pasa al siguiente archivo de la lista.
429 429
430 430 Excepciones:
431 431
432 432 """
433 433
434 434 dirList = []
435 435 for thisPath in os.listdir(path):
436 436 if os.path.isdir(os.path.join(path,thisPath)):
437 437 dirList.append(thisPath)
438 438
439 439 if not(dirList):
440 440 return None, None
441 441
442 442 pathList = []
443 443 dateList = []
444 444
445 445 thisDate = startDate
446 446
447 447 while(thisDate <= endDate):
448 448 year = thisDate.timetuple().tm_year
449 449 doy = thisDate.timetuple().tm_yday
450 450
451 451 match = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy))
452 452 if len(match) == 0:
453 453 thisDate += datetime.timedelta(1)
454 454 continue
455 455
456 456 pathList.append(os.path.join(path,match[0],expLabel))
457 457 dateList.append(thisDate)
458 458 thisDate += datetime.timedelta(1)
459 459
460 460 filenameList = []
461 461 for index in range(len(pathList)):
462 462
463 463 thisPath = pathList[index]
464 464 fileList = glob.glob1(thisPath, "*%s" %ext)
465 465 fileList.sort()
466 466
467 467 #Busqueda de datos en el rango de horas indicados
468 468 thisDate = dateList[index]
469 469 startDT = datetime.datetime.combine(thisDate, startTime)
470 470 endDT = datetime.datetime.combine(thisDate, endTime)
471 471
472 472 startUtSeconds = time.mktime(startDT.timetuple())
473 473 endUtSeconds = time.mktime(endDT.timetuple())
474 474
475 475 for file in fileList:
476 476
477 477 filename = os.path.join(thisPath,file)
478 478
479 479 if isThisFileinRange(filename, startUtSeconds, endUtSeconds):
480 480 filenameList.append(filename)
481 481
482 482 if not(filenameList):
483 483 return None, None
484 484
485 485 self.filenameList = filenameList
486 486
487 487 return pathList, filenameList
488 488
489 489 def setup(self, dataOutObj=None, path=None, startDate=None, endDate=None, startTime=datetime.time(0,0,0), endTime=datetime.time(23,59,59), set=0, expLabel = "", ext = None, online = 0):
490 490 """
491 491 setup configura los parametros de lectura de la clase DataReader.
492 492
493 493 Si el modo de lectura es offline, primero se realiza una busqueda de todos los archivos
494 494 que coincidan con los parametros especificados; esta lista de archivos son almacenados en
495 495 self.filenameList.
496 496
497 497 Input:
498 498 path : Directorios donde se ubican los datos a leer. Dentro de este
499 499 directorio deberia de estar subdirectorios de la forma:
500 500
501 501 path/D[yyyy][ddd]/expLabel/P[yyyy][ddd][sss][ext]
502 502
503 503 startDate : Fecha inicial. Rechaza todos los directorios donde
504 504 file end time < startDate (obejto datetime.date)
505 505
506 506 endDate : Fecha final. Rechaza todos los directorios donde
507 507 file start time > endDate (obejto datetime.date)
508 508
509 509 startTime : Tiempo inicial. Rechaza todos los archivos donde
510 510 file end time < startTime (obejto datetime.time)
511 511
512 512 endTime : Tiempo final. Rechaza todos los archivos donde
513 513 file start time > endTime (obejto datetime.time)
514 514
515 515 set : Set del primer archivo a leer. Por defecto None
516 516
517 517 expLabel : Nombre del subdirectorio de datos. Por defecto ""
518 518
519 519 ext : Extension de los archivos a leer. Por defecto .r
520 520
521 521 online : Si es == a 0 entonces busca files que cumplan con las condiciones dadas
522 522
523 523 Return:
524 524 0 : Si no encuentra files que cumplan con las condiciones dadas
525 525 1 : Si encuentra files que cumplan con las condiciones dadas
526 526
527 527 Affected:
528 528 self.startYear
529 529 self.endYear
530 530 self.startDoy
531 531 self.endDoy
532 532 self.pathList
533 533 self.filenameList
534 534 self.online
535 535 """
536 536 if path == None:
537 537 raise ValueError, "The path is not valid"
538 538
539 539 if ext == None:
540 540 ext = self.ext
541 541
542 542 if dataOutObj == None:
543 543 dataOutObj = self.createObjByDefault()
544 544
545 545 self.dataOutObj = dataOutObj
546 546
547 547 if online:
548 548 print "Searching files in online mode..."
549 549 doypath, file, year, doy, set = self.__searchFilesOnLine(path=path, expLabel=expLabel, ext=exp)
550 550
551 551 if not(doypath):
552 552 for nTries in range( self.nTries ):
553 553 print '\tWaiting %0.2f sec for valid file in %s: try %02d ...' % (self.delay, path, nTries+1)
554 554 time.sleep( self.delay )
555 555 doypath, file, year, doy, set = self.__searchFilesOnLine(path=path, expLabel=expLabel, ext=exp)
556 556 if doypath:
557 557 break
558 558
559 559 if not(doypath):
560 560 print "There 'isn't valied files in %s" % path
561 561 return None
562 562
563 563 self.year = year
564 564 self.doy = doy
565 565 self.set = set - 1
566 566 self.path = path
567 567
568 568 else: # offline
569 569 print "Searching files in offline mode..."
570 570 pathList, filenameList = self.__searchFilesOffLine(path, startDate, endDate, startTime, endTime, set, expLabel, ext)
571 571 if not(pathList):
572 print "No files in range: %s - %s" %(startDateTime.ctime(), endDateTime.ctime())
572 print "No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
573 573 return None
574 574
575 575 self.fileIndex = -1
576 576 self.pathList = pathList
577 577 self.filenameList = filenameList
578 578
579 579 self.online = online
580 580 self.ext = ext
581 581
582 582 ext = ext.lower()
583 583
584 584 if not( self.setNextFile() ):
585 585 if (startDate != None) and (endDate != None):
586 print "No files in range: %s - %s" %(startDate.ctime(), endDate.ctime())
586 print "No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
587
587 588 elif startDate != None:
588 print "No files in : %s" % startDate.ctime()
589 print "No files in : %s" % datetime.datetime.combine(startDate,startTime).ctime()
589 590 else:
590 591 print "No files"
591 592 return None
592 593
593 594 #call fillHeaderValues() - to Data Object
594 595
595 596 self.updateDataHeader()
596 597
597 598 return self.dataOutObj
598 599
599 600 def __rdSystemHeader(self, fp=None):
600 601
601 602 if fp == None:
602 603 fp = self.fp
603 604
604 605 self.m_SystemHeader.read(fp)
605 606
606 607
607 608 def __rdRadarControllerHeader(self, fp=None):
608 609 if fp == None:
609 610 fp = self.fp
610 611
611 612 self.m_RadarControllerHeader.read(fp)
612 613
613 614
614 615 def __rdProcessingHeader(self, fp=None):
615 616 if fp == None:
616 617 fp = self.fp
617 618
618 619 self.m_ProcessingHeader.read(fp)
619 620
620 621
621 622 def __rdBasicHeader(self, fp=None):
622 623
623 624 if fp == None:
624 625 fp = self.fp
625 626
626 627 self.m_BasicHeader.read(fp)
627 628
628 629 def __readFirstHeader(self):
629 630 """
630 631 Lectura del First Header, es decir el Basic Header y el Long Header
631 632
632 633 Affected:
633 634 self.m_BasicHeader
634 635 self.m_SystemHeader
635 636 self.m_RadarControllerHeader
636 637 self.m_ProcessingHeader
637 638 self.firstHeaderSize
638 639 self.dataType
639 640 self.fileSizeByHeader
640 641 self.ippSeconds
641 642
642 643 Return:
643 644 None
644 645 """
645 646 self.__rdBasicHeader()
646 647 self.__rdSystemHeader()
647 648 self.__rdRadarControllerHeader()
648 649 self.__rdProcessingHeader()
649 650 self.firstHeaderSize = self.m_BasicHeader.size
650 651
651 652 datatype = int(numpy.log2((self.m_ProcessingHeader.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
652 653 if datatype == 0:
653 654 datatype_str = numpy.dtype([('real','<i1'),('imag','<i1')])
654 655
655 656 elif datatype == 1:
656 657 datatype_str = numpy.dtype([('real','<i2'),('imag','<i2')])
657 658
658 659 elif datatype == 2:
659 660 datatype_str = numpy.dtype([('real','<i4'),('imag','<i4')])
660 661
661 662 elif datatype == 3:
662 663 datatype_str = numpy.dtype([('real','<i8'),('imag','<i8')])
663 664
664 665 elif datatype == 4:
665 666 datatype_str = numpy.dtype([('real','<f4'),('imag','<f4')])
666 667
667 668 elif datatype == 5:
668 669 datatype_str = numpy.dtype([('real','<f8'),('imag','<f8')])
669 670
670 671 else:
671 672 raise ValueError, 'Data type was not defined'
672 673
673 674 self.dataType = datatype_str
674 675 self.ippSeconds = 2 * 1000 * self.m_RadarControllerHeader.ipp / self.c
675 676
676 677 self.fileSizeByHeader = self.m_ProcessingHeader.dataBlocksPerFile * self.m_ProcessingHeader.blockSize + self.firstHeaderSize + self.basicHeaderSize*(self.m_ProcessingHeader.dataBlocksPerFile - 1)
677 678 self.dataOutObj.channelList = numpy.arange(self.m_SystemHeader.numChannels)
678 679 self.dataOutObj.channelIndexList = numpy.arange(self.m_SystemHeader.numChannels)
679 680
680 681 self.getBlockDimension()
681 682
682 683
683 684 def __setNewBlock(self):
684 685 """
685 686 Lee el Basic Header y posiciona le file pointer en la posicion inicial del bloque a leer
686 687
687 688 Affected:
688 689 self.m_BasicHeader
689 690 self.flagNoContinuousBlock
690 691 self.ns
691 692
692 693 Return:
693 694 0 : Si el file no tiene un Basic Header que pueda ser leido
694 695 1 : Si se pudo leer el Basic Header
695 696 """
696 697 if self.fp == None:
697 698 return 0
698 699
699 700 if self.flagIsNewFile:
700 701 return 1
701 702
702 703 self.lastUTTime = self.m_BasicHeader.utc
703 704
704 705 currentSize = self.fileSize - self.fp.tell()
705 706 neededSize = self.m_ProcessingHeader.blockSize + self.basicHeaderSize
706 707
707 708 #If there is enough data setting new data block
708 709 if ( currentSize >= neededSize ):
709 710 self.__rdBasicHeader()
710 711 return 1
711 712
712 713 #si es OnLine y ademas aun no se han leido un bloque completo entonces se espera por uno valido
713 714 if self.online and (self.nReadBlocks < self.m_ProcessingHeader.dataBlocksPerFile):
714 715
715 716 fpointer = self.fp.tell()
716 717
717 718 for nTries in range( self.nTries ):
718 719 #self.fp.close()
719 720
720 721 print "\tWaiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1)
721 722 time.sleep( self.delay )
722 723
723 724 #self.fp = open( self.filename, 'rb' )
724 725 #self.fp.seek( fpointer )
725 726
726 727 self.fileSize = os.path.getsize( self.filename )
727 728 currentSize = self.fileSize - fpointer
728 729
729 730 if ( currentSize >= neededSize ):
730 731 self.__rdBasicHeader()
731 732 return 1
732 733
733 734 #Setting new file
734 735 if not( self.setNextFile() ):
735 736 return 0
736 737
737 738 deltaTime = self.m_BasicHeader.utc - self.lastUTTime # check this
738 739
739 740 self.flagResetProcessing = 0
740 741
741 742 if deltaTime > self.maxTimeStep:
742 743 self.flagResetProcessing = 1
743 744
744 745 return 1
745 746
746 747 def readNextBlock(self):
747 748 """
748 749 Establece un nuevo bloque de datos a leer y los lee, si es que no existiese
749 750 mas bloques disponibles en el archivo actual salta al siguiente.
750 751
751 752 Affected:
752 753 self.lastUTTime
753 754
754 755 Return: None
755 756 """
756 757
757 758 if not(self.__setNewBlock()):
758 759 return 0
759 760
760 761 if not(self.readBlock()):
761 762 return 0
762 763
763 764 return 1
764 765
765 766 def __setNextFileOnline(self):
766 767 """
767 768 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
768 769 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
769 770 siguientes.
770 771
771 772 Affected:
772 773 self.flagIsNewFile
773 774 self.filename
774 775 self.fileSize
775 776 self.fp
776 777 self.set
777 778 self.flagNoMoreFiles
778 779
779 780 Return:
780 781 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
781 782 1 : si el file fue abierto con exito y esta listo a ser leido
782 783
783 784 Excepciones:
784 785 Si un determinado file no puede ser abierto
785 786 """
786 787 nFiles = 0
787 788 fileOk_flag = False
788 789 firstTime_flag = True
789 790
790 791 self.set += 1
791 792
792 793 #busca el 1er file disponible
793 794 file, filename = checkForRealPath( self.path, self.year, self.doy, self.set, self.ext )
794 795 if file:
795 796 if self.__verifyFile(file, False):
796 797 fileOk_flag = True
797 798
798 799 #si no encuentra un file entonces espera y vuelve a buscar
799 800 if not(fileOk_flag):
800 801 for nFiles in range(self.nFiles+1): #busco en los siguientes self.nFiles+1 files posibles
801 802
802 803 if firstTime_flag: #si es la 1era vez entonces hace el for self.nTries veces
803 804 tries = self.nTries
804 805 else:
805 806 tries = 1 #si no es la 1era vez entonces solo lo hace una vez
806 807
807 808 for nTries in range( tries ):
808 809 if firstTime_flag:
809 810 print "\tWaiting %0.2f sec for new \"%s\" file, try %03d ..." % ( self.delay, filename, nTries+1 )
810 811 time.sleep( self.delay )
811 812 else:
812 813 print "\tSearching next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext)
813 814
814 815 file, filename = checkForRealPath( self.path, self.year, self.doy, self.set, self.ext )
815 816 if file:
816 817 if self.__verifyFile(file):
817 818 fileOk_flag = True
818 819 break
819 820
820 821 if fileOk_flag:
821 822 break
822 823
823 824 firstTime_flag = False
824 825
825 826 print "\tSkipping the file \"%s\" due to this file doesn't exist yet" % filename
826 827 self.set += 1
827 828
828 829 if nFiles == (self.nFiles-1): #si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
829 830 self.set = 0
830 831 self.doy += 1
831 832
832 833 if fileOk_flag:
833 834 self.fileSize = os.path.getsize( file )
834 835 self.filename = file
835 836 self.flagIsNewFile = 1
836 837 if self.fp != None: self.fp.close()
837 838 self.fp = open(file)
838 839 self.flagNoMoreFiles = 0
839 840 print 'Setting the file: %s' % file
840 841 else:
841 842 self.fileSize = 0
842 843 self.filename = None
843 844 self.flagIsNewFile = 0
844 845 self.fp = None
845 846 self.flagNoMoreFiles = 1
846 847 print 'No more Files'
847 848
848 849 return fileOk_flag
849 850
850 851
851 852 def __setNextFileOffline(self):
852 853 """
853 854 Busca el siguiente file dentro de un folder que tenga suficiente data para ser leida
854 855
855 856 Affected:
856 857 self.flagIsNewFile
857 858 self.fileIndex
858 859 self.filename
859 860 self.fileSize
860 861 self.fp
861 862
862 863 Return:
863 864 0 : si un determinado file no puede ser abierto
864 865 1 : si el file fue abierto con exito
865 866
866 867 Excepciones:
867 868 Si un determinado file no puede ser abierto
868 869 """
869 870 idFile = self.fileIndex
870 871
871 872 while(True):
872 873
873 874 idFile += 1
874 875
875 876 if not(idFile < len(self.filenameList)):
876 877 self.flagNoMoreFiles = 1
877 878 print 'No more Files'
878 879 return 0
879 880
880 881 filename = self.filenameList[idFile]
881 882
882 883 if not(self.__verifyFile(filename)):
883 884 continue
884 885
885 886 fileSize = os.path.getsize(filename)
886 887 fp = open(filename,'rb')
887 888 break
888 889
889 890 self.flagIsNewFile = 1
890 891 self.fileIndex = idFile
891 892 self.filename = filename
892 893 self.fileSize = fileSize
893 894 self.fp = fp
894 895
895 896 print 'Setting the file: %s'%self.filename
896 897
897 898 return 1
898 899
899 900
900 901 def setNextFile(self):
901 902 """
902 903 Determina el siguiente file a leer y si hay uno disponible lee el First Header
903 904
904 905 Affected:
905 906 self.m_BasicHeader
906 907 self.m_SystemHeader
907 908 self.m_RadarControllerHeader
908 909 self.m_ProcessingHeader
909 910 self.firstHeaderSize
910 911
911 912 Return:
912 913 0 : Si no hay files disponibles
913 914 1 : Si hay mas files disponibles
914 915 """
915 916 if self.fp != None:
916 917 self.fp.close()
917 918
918 919 if self.online:
919 920 newFile = self.__setNextFileOnline()
920 921 else:
921 922 newFile = self.__setNextFileOffline()
922 923
923 924 if not(newFile):
924 925 return 0
925 926
926 927 self.__readFirstHeader()
927 928 self.nReadBlocks = 0
928 929 return 1
929 930
930 931 def __verifyFile(self, filename, msgFlag=True):
931 932 """
932 933 Verifica que el filename tenga data valida, para ello leo el FirstHeader del file
933 934
934 935 Return:
935 936 0 : file no valido para ser leido
936 937 1 : file valido para ser leido
937 938 """
938 939 msg = None
939 940
940 941 try:
941 942 fp = open( filename,'rb' ) #lectura binaria
942 943 currentPosition = fp.tell()
943 944 except:
944 945 if msgFlag:
945 946 print "The file %s can't be opened" % (filename)
946 947 return False
947 948
948 949 neededSize = self.m_ProcessingHeader.blockSize + self.firstHeaderSize
949 950
950 951 if neededSize == 0:
951 952
952 953 m_BasicHeader = BasicHeader()
953 954 m_SystemHeader = SystemHeader()
954 955 m_RadarControllerHeader = RadarControllerHeader()
955 956 m_ProcessingHeader = ProcessingHeader()
956 957
957 958 try:
958 959 if not( m_BasicHeader.read(fp) ): raise ValueError
959 960 if not( m_SystemHeader.read(fp) ): raise ValueError
960 961 if not( m_RadarControllerHeader.read(fp) ): raise ValueError
961 962 if not( m_ProcessingHeader.read(fp) ): raise ValueError
962 963 data_type = int(numpy.log2((m_ProcessingHeader.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
963 964
964 965 neededSize = m_ProcessingHeader.blockSize + m_BasicHeader.size
965 966
966 967 except:
967 968 if msgFlag:
968 969 print "\tThe file %s is empty or it hasn't enough data" % filename
969 970
970 971 fp.close()
971 972 return False
972 973
973 974 else:
974 975 msg = "\tSkipping the file %s due to it hasn't enough data" %filename
975 976
976 977 fp.close()
977 978 fileSize = os.path.getsize(filename)
978 979 currentSize = fileSize - currentPosition
979 980
980 981 if currentSize < neededSize:
981 982 if msgFlag and (msg != None):
982 983 print msg #print"\tSkipping the file %s due to it hasn't enough data" %filename
983 984 return False
984 985
985 986 return True
986 987
987 988 def updateDataHeader(self):
988 989
989 990 self.dataOutObj.m_BasicHeader = self.m_BasicHeader.copy()
990 991 self.dataOutObj.m_ProcessingHeader = self.m_ProcessingHeader.copy()
991 992 self.dataOutObj.m_RadarControllerHeader = self.m_RadarControllerHeader.copy()
992 993 self.dataOutObj.m_SystemHeader = self.m_SystemHeader.copy()
993 994
994 995 self.dataOutObj.dataType = self.dataType
995 996 self.dataOutObj.updateObjFromHeader()
996 997
997 998
998 999 class JRODataWriter(JRODataIO):
999 1000
1000 1001 """
1001 1002 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1002 1003 de los datos siempre se realiza por bloques.
1003 1004 """
1004 1005
1005 1006 nWriteBlocks = 0
1006 1007
1007 1008 setFile = None
1008 1009
1009 1010
1010 1011 def __init__(self, dataOutObj=None):
1011 1012 raise ValueError, "Not implemented"
1012 1013
1013 1014
1014 1015 def hasAllDataInBuffer(self):
1015 1016 raise ValueError, "Not implemented"
1016 1017
1017 1018
1018 1019 def setBlockDimension(self):
1019 1020 raise ValueError, "Not implemented"
1020 1021
1021 1022
1022 1023 def writeBlock(self):
1023 1024 raise ValueError, "No implemented"
1024 1025
1025 1026
1026 1027 def putData(self):
1027 1028 raise ValueError, "No implemented"
1028 1029
1029 1030
1030 1031 def __writeFirstHeader(self):
1031 1032 """
1032 1033 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1033 1034
1034 1035 Affected:
1035 1036 __dataType
1036 1037
1037 1038 Return:
1038 1039 None
1039 1040 """
1040 1041 self.__writeBasicHeader()
1041 1042 self.__wrSystemHeader()
1042 1043 self.__wrRadarControllerHeader()
1043 1044 self.__wrProcessingHeader()
1044 1045 self.dataType = self.dataOutObj.dataType
1045 1046
1046 1047
1047 1048 def __writeBasicHeader(self, fp=None):
1048 1049 """
1049 1050 Escribe solo el Basic header en el file creado
1050 1051
1051 1052 Return:
1052 1053 None
1053 1054 """
1054 1055 if fp == None:
1055 1056 fp = self.fp
1056 1057
1057 1058 self.dataOutObj.m_BasicHeader.write(fp)
1058 1059
1059 1060
1060 1061 def __wrSystemHeader(self, fp=None):
1061 1062 """
1062 1063 Escribe solo el System header en el file creado
1063 1064
1064 1065 Return:
1065 1066 None
1066 1067 """
1067 1068 if fp == None:
1068 1069 fp = self.fp
1069 1070
1070 1071 self.dataOutObj.m_SystemHeader.write(fp)
1071 1072
1072 1073
1073 1074 def __wrRadarControllerHeader(self, fp=None):
1074 1075 """
1075 1076 Escribe solo el RadarController header en el file creado
1076 1077
1077 1078 Return:
1078 1079 None
1079 1080 """
1080 1081 if fp == None:
1081 1082 fp = self.fp
1082 1083
1083 1084 self.dataOutObj.m_RadarControllerHeader.write(fp)
1084 1085
1085 1086
1086 1087 def __wrProcessingHeader(self, fp=None):
1087 1088 """
1088 1089 Escribe solo el Processing header en el file creado
1089 1090
1090 1091 Return:
1091 1092 None
1092 1093 """
1093 1094 if fp == None:
1094 1095 fp = self.fp
1095 1096
1096 1097 self.dataOutObj.m_ProcessingHeader.write(fp)
1097 1098
1098 1099
1099 1100 def setNextFile(self):
1100 1101 """
1101 1102 Determina el siguiente file que sera escrito
1102 1103
1103 1104 Affected:
1104 1105 self.filename
1105 1106 self.subfolder
1106 1107 self.fp
1107 1108 self.setFile
1108 1109 self.flagIsNewFile
1109 1110
1110 1111 Return:
1111 1112 0 : Si el archivo no puede ser escrito
1112 1113 1 : Si el archivo esta listo para ser escrito
1113 1114 """
1114 1115 ext = self.ext
1115 1116 path = self.path
1116 1117
1117 1118 if self.fp != None:
1118 1119 self.fp.close()
1119 1120
1120 1121 timeTuple = time.localtime( self.dataOutObj.m_BasicHeader.utc )
1121 1122 subfolder = 'D%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
1122 1123
1123 1124 doypath = os.path.join( path, subfolder )
1124 1125 if not( os.path.exists(doypath) ):
1125 1126 os.mkdir(doypath)
1126 1127 self.setFile = -1 #inicializo mi contador de seteo
1127 1128 else:
1128 1129 filesList = os.listdir( doypath )
1129 1130 if len( filesList ) > 0:
1130 1131 filesList = sorted( filesList, key=str.lower )
1131 1132 filen = filesList[-1]
1132 1133 # el filename debera tener el siguiente formato
1133 1134 # 0 1234 567 89A BCDE (hex)
1134 1135 # x YYYY DDD SSS .ext
1135 1136 if isNumber( filen[8:11] ):
1136 1137 self.setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
1137 1138 else:
1138 1139 self.setFile = -1
1139 1140 else:
1140 1141 self.setFile = -1 #inicializo mi contador de seteo
1141 1142
1142 1143 setFile = self.setFile
1143 1144 setFile += 1
1144 1145
1145 1146 file = '%s%4.4d%3.3d%3.3d%s' % (self.optchar,
1146 1147 timeTuple.tm_year,
1147 1148 timeTuple.tm_yday,
1148 1149 setFile,
1149 1150 ext )
1150 1151
1151 1152 filename = os.path.join( path, subfolder, file )
1152 1153
1153 1154 fp = open( filename,'wb' )
1154 1155
1155 1156 self.nWriteBlocks = 0
1156 1157
1157 1158 #guardando atributos
1158 1159 self.filename = filename
1159 1160 self.subfolder = subfolder
1160 1161 self.fp = fp
1161 1162 self.setFile = setFile
1162 1163 self.flagIsNewFile = 1
1163 1164
1164 1165 print 'Writing the file: %s'%self.filename
1165 1166
1166 1167 self.__writeFirstHeader()
1167 1168
1168 1169 return 1
1169 1170
1170 1171
1171 1172 def __setNewBlock(self):
1172 1173 """
1173 1174 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1174 1175
1175 1176 Return:
1176 1177 0 : si no pudo escribir nada
1177 1178 1 : Si escribio el Basic el First Header
1178 1179 """
1179 1180 if self.fp == None:
1180 1181 self.setNextFile()
1181 1182
1182 1183 if self.flagIsNewFile:
1183 1184 return 1
1184 1185
1185 1186 if self.nWriteBlocks < self.m_ProcessingHeader.dataBlocksPerFile:
1186 1187 self.__writeBasicHeader()
1187 1188 return 1
1188 1189
1189 1190 if not( self.setNextFile() ):
1190 1191 return 0
1191 1192
1192 1193 return 1
1193 1194
1194 1195
1195 1196 def writeNextBlock(self):
1196 1197 """
1197 1198 Selecciona el bloque siguiente de datos y los escribe en un file
1198 1199
1199 1200 Return:
1200 1201 0 : Si no hizo pudo escribir el bloque de datos
1201 1202 1 : Si no pudo escribir el bloque de datos
1202 1203 """
1203 1204 if not( self.__setNewBlock() ):
1204 1205 return 0
1205 1206
1206 1207 self.writeBlock()
1207 1208
1208 1209 return 1
1209 1210
1210 1211
1211 1212 def getDataHeader(self):
1212 1213 """
1213 1214 Obtiene una copia del First Header
1214 1215
1215 1216 Affected:
1216 1217 self.m_BasicHeader
1217 1218 self.m_SystemHeader
1218 1219 self.m_RadarControllerHeader
1219 1220 self.m_ProcessingHeader
1220 1221 self.dataType
1221 1222
1222 1223 Return:
1223 1224 None
1224 1225 """
1225 1226 self.dataOutObj.updateHeaderFromObj()
1226 1227
1227 1228 self.m_BasicHeader = self.dataOutObj.m_BasicHeader.copy()
1228 1229 self.m_SystemHeader = self.dataOutObj.m_SystemHeader.copy()
1229 1230 self.m_RadarControllerHeader = self.dataOutObj.m_RadarControllerHeader.copy()
1230 1231 self.m_ProcessingHeader = self.dataOutObj.m_ProcessingHeader.copy()
1231 1232
1232 1233 self.dataType = self.dataOutObj.dataType
1233 1234
1234 1235
1235 1236 def setup(self, path, set=0, ext=None):
1236 1237 """
1237 1238 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1238 1239
1239 1240 Inputs:
1240 1241 path : el path destino en el cual se escribiran los files a crear
1241 1242 format : formato en el cual sera salvado un file
1242 1243 set : el setebo del file
1243 1244
1244 1245 Return:
1245 1246 0 : Si no realizo un buen seteo
1246 1247 1 : Si realizo un buen seteo
1247 1248 """
1248 1249
1249 1250 if ext == None:
1250 1251 ext = self.ext
1251 1252
1252 1253 ext = ext.lower()
1253 1254
1254 1255 self.path = path
1255 1256 self.setFile = set - 1
1256 1257 self.ext = ext
1257 1258 #self.format = format
1258 1259 self.getDataHeader()
1259 1260
1260 1261 self.setBlockDimension()
1261 1262
1262 1263 if not( self.setNextFile() ):
1263 1264 print "There isn't a next file"
1264 1265 return 0
1265 1266
1266 1267 return 1
General Comments 0
You need to be logged in to leave comments. Login now