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