##// 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 25 pass
No newline at end of file
28
29
30 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
@@ -1,536 +1,541
1 1 '''
2 2 File: SpectraIO.py
3 3 Created on 20/02/2012
4 4
5 5 @author $Author$
6 6 @version $Id$
7 7 '''
8 8
9 9 import os, sys
10 10 import numpy
11 11 import glob
12 12 import fnmatch
13 13 import time, datetime
14 14
15 15 path = os.path.split(os.getcwd())[0]
16 16 sys.path.append(path)
17 17
18 18 from Model.JROHeader import *
19 19 from Model.Spectra import Spectra
20 20
21 21 from JRODataIO import JRODataReader
22 22 from JRODataIO import JRODataWriter
23 23 from JRODataIO import isNumber
24 24
25 25
26 26 class SpectraReader( JRODataReader ):
27 27 """
28 28 Esta clase permite leer datos de espectros desde archivos procesados (.pdata). La lectura
29 29 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones)
30 30 son almacenados en tres buffer's para el Self Spectra, el Cross Spectra y el DC Channel.
31 31
32 32 paresCanalesIguales * alturas * perfiles (Self Spectra)
33 33 paresCanalesDiferentes * alturas * perfiles (Cross Spectra)
34 34 canales * alturas (DC Channels)
35 35
36 36 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
37 37 RadarControllerHeader y Spectra. Los tres primeros se usan para almacenar informacion de la
38 38 cabecera de datos (metadata), y el cuarto (Spectra) para obtener y almacenar un bloque de
39 39 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
40 40
41 41 Example:
42 42 dpath = "/home/myuser/data"
43 43
44 44 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
45 45
46 46 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
47 47
48 48 readerObj = SpectraReader()
49 49
50 50 readerObj.setup(dpath, startTime, endTime)
51 51
52 52 while(True):
53 53
54 54 readerObj.getData()
55 55
56 56 print readerObj.m_Spectra.data
57 57
58 58 if readerObj.flagNoMoreFiles:
59 59 break
60 60
61 61 """
62 62 m_DataObj = None
63 63
64 64 data_spc = None
65 65 data_cspc = None
66 66 data_dc = None
67 67
68 68 pts2read_SelfSpectra = 0
69 69 pts2read_CrossSpectra = 0
70 70 pts2read_DCchannels = 0
71 71
72 72 nChannels = 0
73 73
74 74 nPairs = 0
75 75
76 76 #pairList = None
77 77
78 78 channelList = None
79 79
80 80 def __init__(self, m_Spectra=None):
81 81 """
82 82 Inicializador de la clase SpectraReader para la lectura de datos de espectros.
83 83
84 84 Inputs:
85 85 m_Spectra : Objeto de la clase Spectra. Este objeto sera utilizado para
86 86 almacenar un perfil de datos cada vez que se haga un requerimiento
87 87 (getData). El perfil sera obtenido a partir del buffer de datos,
88 88 si el buffer esta vacio se hara un nuevo proceso de lectura de un
89 89 bloque de datos.
90 90 Si este parametro no es pasado se creara uno internamente.
91 91
92 92 Affected:
93 93 self.m_DataObj
94 94
95 95 Return : None
96 96 """
97 97 if m_Spectra == None:
98 98 m_Spectra = Spectra()
99 99
100 100 if not( isinstance(m_Spectra, Spectra) ):
101 101 raise ValueError, "in SpectraReader, m_Spectra must be an Spectra class object"
102 102
103 103 self.m_DataObj = m_Spectra
104 104
105 105 self.data_spc = None
106 106 self.data_cspc = None
107 107 self.data_dc = None
108 108
109 109 self.pts2read_SelfSpectra = 0
110 110 self.pts2read_CrossSpectra = 0
111 111 self.pts2read_DCs = 0
112 112
113 113 self.nChannels = 0
114 114
115 115 self.nPairs = 0
116 116
117 117 self.ext = ".pdata"
118 118
119 119 self.optchar = "P"
120 120
121 121 ######################
122 122
123 123 self.m_BasicHeader = BasicHeader()
124 124
125 125 self.m_SystemHeader = SystemHeader()
126 126
127 127 self.m_RadarControllerHeader = RadarControllerHeader()
128 128
129 129 self.m_ProcessingHeader = ProcessingHeader()
130 130
131 131 self.online = 0
132 132
133 133 self.fp = None
134 134
135 135 self.fileSizeByHeader = None
136 136
137 137 self.filenameList = []
138 138
139 139 self.filename = None
140 140
141 141 self.fileSize = None
142 142
143 143 self.firstHeaderSize = 0
144 144
145 145 self.basicHeaderSize = 24
146 146
147 147 self.dataType = None
148 148
149 149 self.maxTimeStep = 30
150 150
151 151 self.flagNoMoreFiles = 0
152 152
153 153 self.set = 0
154 154
155 155 self.path = None
156 156
157 157 self.delay = 3 #seconds
158 158
159 159 self.nTries = 3 #quantity tries
160 160
161 161 self.nFiles = 3 #number of files for searching
162 162
163 163 self.nReadBlocks = 0
164 164
165 165 self.flagIsNewFile = 1
166 166
167 167 self.ippSeconds = 0
168 168
169 169 self.flagResetProcessing = 0
170 170
171 171 self.flagIsNewBlock = 0
172 172
173 173 self.nTotalBlocks = 0
174 174
175 175 self.blocksize = 0
176 176
177 177 #pairList = None
178 178
179 179 channelList = None
180 180
181 181
182 182 def __hasNotDataInBuffer(self):
183 183 return 1
184 184
185 185
186 186 def getBlockDimension(self):
187 187 """
188 188 Obtiene la cantidad de puntos a leer por cada bloque de datos
189 189
190 190 Affected:
191 191 self.nChannels
192 192 self.nPairs
193 193 self.pts2read_SelfSpectra
194 194 self.pts2read_CrossSpectra
195 195 self.pts2read_DCchannels
196 196 self.blocksize
197 197 self.m_DataObj.nChannels
198 198 self.m_DataObj.nPairs
199 199
200 200 Return:
201 201 None
202 202 """
203 203 self.nChannels = 0
204 204 self.nPairs = 0
205 205 self.pairList = []
206 206
207 207 for i in range( 0, self.m_ProcessingHeader.totalSpectra*2, 2 ):
208 208 if self.m_ProcessingHeader.spectraComb[i] == self.m_ProcessingHeader.spectraComb[i+1]:
209 209 self.nChannels = self.nChannels + 1 #par de canales iguales
210 210 else:
211 211 self.nPairs = self.nPairs + 1 #par de canales diferentes
212 212 self.pairList.append( (self.m_ProcessingHeader.spectraComb[i], self.m_ProcessingHeader.spectraComb[i+1]) )
213 213
214 214 pts2read = self.m_ProcessingHeader.numHeights * self.m_ProcessingHeader.profilesPerBlock
215 215
216 216 self.pts2read_SelfSpectra = int( self.nChannels * pts2read )
217 217 self.pts2read_CrossSpectra = int( self.nPairs * pts2read )
218 218 self.pts2read_DCchannels = int( self.m_SystemHeader.numChannels * self.m_ProcessingHeader.numHeights )
219 219
220 220 self.blocksize = self.pts2read_SelfSpectra + self.pts2read_CrossSpectra + self.pts2read_DCchannels
221 221
222 222 self.channelList = numpy.arange( self.nChannels )
223 223
224 224
225 225 def readBlock(self):
226 226 """
227 227 Lee el bloque de datos desde la posicion actual del puntero del archivo
228 228 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
229 229 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
230 230 es seteado a 0
231 231
232 232 Return: None
233 233
234 234 Variables afectadas:
235 235 self.datablockIndex
236 236 self.flagIsNewFile
237 237 self.flagIsNewBlock
238 238 self.nTotalBlocks
239 239 self.data_spc
240 240 self.data_cspc
241 241 self.data_dc
242 242
243 243 Exceptions:
244 244 Si un bloque leido no es un bloque valido
245 245 """
246 246 blockOk_flag = False
247 247 fpointer = self.fp.tell()
248 248
249 249 spc = numpy.fromfile( self.fp, self.dataType[0], self.pts2read_SelfSpectra )
250 250 cspc = numpy.fromfile( self.fp, self.dataType, self.pts2read_CrossSpectra )
251 251 dc = numpy.fromfile( self.fp, self.dataType, self.pts2read_DCchannels ) #int(self.m_ProcessingHeader.numHeights*self.m_SystemHeader.numChannels) )
252 252
253 253 try:
254 254 spc = spc.reshape( (self.nChannels, self.m_ProcessingHeader.numHeights, self.m_ProcessingHeader.profilesPerBlock) ) #transforma a un arreglo 3D
255 255 if self.nPairs != 0:
256 256 cspc = cspc.reshape( (self.nPairs, self.m_ProcessingHeader.numHeights, self.m_ProcessingHeader.profilesPerBlock) ) #transforma a un arreglo 3D
257 257 else:
258 258 cspc = None
259 259 dc = dc.reshape( (self.m_SystemHeader.numChannels, self.m_ProcessingHeader.numHeights) ) #transforma a un arreglo 2D
260 260 except:
261 261 print "Data file %s is invalid" % self.filename
262 262 return 0
263 263
264 264 if not( self.m_ProcessingHeader.shif_fft ):
265 265 spc = numpy.roll( spc, self.m_ProcessingHeader.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
266
266 267 if cspc != None:
267 268 cspc = numpy.roll( cspc, self.m_ProcessingHeader.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
268 269
269 270 spc = numpy.transpose( spc, (0,2,1) )
270 if cspc != None: cspc = numpy.transpose( cspc, (0,2,1) )
271 271
272 self.data_spc = spc
272 if cspc != None:
273 cspc = numpy.transpose( cspc, (0,2,1) )
274
275
273 276 if cspc != None:
274 277 self.data_cspc = cspc['real'] + cspc['imag']*1j
275 278 else:
276 279 self.data_cspc = None
280
281 self.data_spc = spc
277 282 self.data_dc = dc['real'] + dc['imag']*1j
278 283
279 284 self.datablockIndex = 0
280 285 self.flagIsNewFile = 0
281 286 self.flagIsNewBlock = 1
282 287
283 288 self.nTotalBlocks += 1
284 289 self.nReadBlocks += 1
285 290
286 291 return 1
287 292
288 293
289 294 def getData(self):
290 295 """
291 296 Copia el buffer de lectura a la clase "Spectra",
292 297 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
293 298 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
294 299
295 300 Return:
296 301 0 : Si no hay mas archivos disponibles
297 302 1 : Si hizo una buena copia del buffer
298 303
299 304 Affected:
300 305 self.m_DataObj
301 306 self.datablockIndex
302 307 self.flagResetProcessing
303 308 self.flagIsNewBlock
304 309 """
305 310
306 311 if self.flagNoMoreFiles: return 0
307 312
308 313 self.flagResetProcessing = 0
309 314 self.flagIsNewBlock = 0
310 315
311 316 if self.__hasNotDataInBuffer():
312 317
313 318 if not( self.readNextBlock() ):
314 319 return 0
315 320
316 321 self.updateDataHeader()
317 322
318 323 if self.flagNoMoreFiles == 1:
319 324 print 'Process finished'
320 325 return 0
321 326
322 327 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
323 328
324 329 if self.data_dc == None:
325 330 self.m_DataObj.flagNoData = True
326 331 return 0
327 332
328 333 self.m_DataObj.flagNoData = False
329 334 self.m_DataObj.flagResetProcessing = self.flagResetProcessing
330 335
331 336 self.m_DataObj.data_spc = self.data_spc
332 337 self.m_DataObj.data_cspc = self.data_cspc
333 338 self.m_DataObj.data_dc = self.data_dc
334 339
335 340 return 1
336 341
337 342
338 343 class SpectraWriter(JRODataWriter):
339 344
340 345 """
341 346 Esta clase permite escribir datos de espectros a archivos procesados (.pdata). La escritura
342 347 de los datos siempre se realiza por bloques.
343 348 """
344 349
345 350 m_DataObj = None
346 351
347 352 shape_spc_Buffer = None
348 353 shape_cspc_Buffer = None
349 354 shape_dc_Buffer = None
350 355
351 356 data_spc = None
352 357 data_cspc = None
353 358 data_dc = None
354 359
355 360
356 361 def __init__(self, m_Spectra=None):
357 362 """
358 363 Inicializador de la clase SpectraWriter para la escritura de datos de espectros.
359 364
360 365 Affected:
361 366 self.m_DataObj
362 367 self.m_BasicHeader
363 368 self.m_SystemHeader
364 369 self.m_RadarControllerHeader
365 370 self.m_ProcessingHeader
366 371
367 372 Return: None
368 373 """
369 374 if m_Spectra == None:
370 375 m_Spectra = Spectra()
371 376
372 377 if not( isinstance(m_Spectra, Spectra) ):
373 378 raise ValueError, "in SpectraReader, m_Spectra must be an Spectra class object"
374 379
375 380 self.m_DataObj = m_Spectra
376 381
377 382 self.ext = ".pdata"
378 383
379 384 self.optchar = "P"
380 385
381 386 self.shape_spc_Buffer = None
382 387 self.shape_cspc_Buffer = None
383 388 self.shape_dc_Buffer = None
384 389
385 390 self.data_spc = None
386 391 self.data_cspc = None
387 392 self.data_dc = None
388 393
389 394 ####################################
390 395
391 396 self.fp = None
392 397
393 398 self.nWriteBlocks = 0
394 399
395 400 self.flagIsNewFile = 1
396 401
397 402 self.nTotalBlocks = 0
398 403
399 404 self.flagIsNewBlock = 0
400 405
401 406 self.flagNoMoreFiles = 0
402 407
403 408 self.setFile = None
404 409
405 410 self.dataType = None
406 411
407 412 self.path = None
408 413
409 414 self.noMoreFiles = 0
410 415
411 416 self.filename = None
412 417
413 418 self.m_BasicHeader= BasicHeader()
414 419
415 420 self.m_SystemHeader = SystemHeader()
416 421
417 422 self.m_RadarControllerHeader = RadarControllerHeader()
418 423
419 424 self.m_ProcessingHeader = ProcessingHeader()
420 425
421 426
422 427 def hasAllDataInBuffer(self):
423 428 return 1
424 429
425 430
426 431 def setBlockDimension(self):
427 432 """
428 433 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
429 434
430 435 Affected:
431 436 self.shape_spc_Buffer
432 437 self.shape_cspc_Buffer
433 438 self.shape_dc_Buffer
434 439
435 440 Return: None
436 441 """
437 442 self.shape_spc_Buffer = (self.m_DataObj.nChannels,
438 443 self.m_ProcessingHeader.numHeights,
439 444 self.m_ProcessingHeader.profilesPerBlock)
440 445
441 446 self.shape_cspc_Buffer = (self.m_DataObj.nPairs,
442 447 self.m_ProcessingHeader.numHeights,
443 448 self.m_ProcessingHeader.profilesPerBlock)
444 449
445 450 self.shape_dc_Buffer = (self.m_SystemHeader.numChannels,
446 451 self.m_ProcessingHeader.numHeights)
447 452
448 453
449 454 def writeBlock(self):
450 455 """
451 456 Escribe el buffer en el file designado
452 457
453 458 Affected:
454 459 self.data_spc
455 460 self.data_cspc
456 461 self.data_dc
457 462 self.flagIsNewFile
458 463 self.flagIsNewBlock
459 464 self.nTotalBlocks
460 465 self.nWriteBlocks
461 466
462 467 Return: None
463 468 """
464 469
465 470 spc = numpy.transpose( self.data_spc, (0,2,1) )
466 471 if not( self.m_ProcessingHeader.shif_fft ):
467 472 spc = numpy.roll( spc, self.m_ProcessingHeader.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
468 473 data = spc.reshape((-1))
469 474 data.tofile(self.fp)
470 475
471 476 if self.data_cspc != None:
472 477 data = numpy.zeros( self.shape_cspc_Buffer, self.dataType )
473 478 cspc = numpy.transpose( self.data_cspc, (0,2,1) )
474 479 if not( self.m_ProcessingHeader.shif_fft ):
475 480 cspc = numpy.roll( cspc, self.m_ProcessingHeader.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
476 481 data['real'] = cspc.real
477 482 data['imag'] = cspc.imag
478 483 data = data.reshape((-1))
479 484 data.tofile(self.fp)
480 485
481 486 data = numpy.zeros( self.shape_dc_Buffer, self.dataType )
482 487 dc = self.data_dc
483 488 data['real'] = dc.real
484 489 data['imag'] = dc.imag
485 490 data = data.reshape((-1))
486 491 data.tofile(self.fp)
487 492
488 493 self.data_spc.fill(0)
489 494 self.data_dc.fill(0)
490 495 if self.data_cspc != None:
491 496 self.data_cspc.fill(0)
492 497
493 498 self.flagIsNewFile = 0
494 499 self.flagIsNewBlock = 1
495 500 self.nTotalBlocks += 1
496 501 self.nWriteBlocks += 1
497 502
498 503
499 504 def putData(self):
500 505 """
501 506 Setea un bloque de datos y luego los escribe en un file
502 507
503 508 Affected:
504 509 self.data_spc
505 510 self.data_cspc
506 511 self.data_dc
507 512
508 513 Return:
509 514 0 : Si no hay data o no hay mas files que puedan escribirse
510 515 1 : Si se escribio la data de un bloque en un file
511 516 """
512 517 self.flagIsNewBlock = 0
513 518
514 519 if self.m_DataObj.flagNoData:
515 520 return 0
516 521
517 522 if self.m_DataObj.flagResetProcessing:
518 523 self.data_spc.fill(0)
519 524 self.data_cspc.fill(0)
520 525 self.data_dc.fill(0)
521 526 self.setNextFile()
522 527
523 528 self.data_spc = self.m_DataObj.data_spc
524 529 self.data_cspc = self.m_DataObj.data_cspc
525 530 self.data_dc = self.m_DataObj.data_dc
526 531
527 532 # #self.m_ProcessingHeader.dataBlocksPerFile)
528 533 if self.hasAllDataInBuffer():
529 534 self.getDataHeader()
530 535 self.writeNextBlock()
531 536
532 537 if self.flagNoMoreFiles:
533 538 #print 'Process finished'
534 539 return 0
535 540
536 541 return 1 No newline at end of file
@@ -1,57 +1,57
1 1 '''
2 2 Created on 23/01/2012
3 3
4 4 @author $Author$
5 5 @version $Id$
6 6 '''
7 7 import os
8 8 import sys
9 9 import datetime
10 10 import time
11 11
12 class TestIO():
12 class TestIO:
13 13
14 14 def __init__(self):
15 15 self.setValues()
16 16 self.createVoltageObjects()
17 17 self.testReadVoltage()
18 18 pass
19 19
20 20 def setValues(self):
21 21
22 22
23 23 self.path = '/Users/danielangelsuarezmunoz/Documents/Projects/testWR'
24 24 self.startDateTime = datetime.datetime(2007,5,1,17,49,0)
25 25 self.endDateTime = datetime.datetime(2007,5,1,18,15,0)
26 26
27 27 def createVoltageObjects(self):
28 28 path = os.path.split(os.getcwd())[0]
29 29 sys.path.append(path)
30 30
31 31 from IO.VoltageIO import VoltageReader
32 32 from IO.VoltageIO import VoltageWriter
33 33 from Model.Voltage import Voltage
34 34
35 35 self.voltageModelObj = Voltage()
36 36 self.voltageReaderObj = VoltageReader(self.voltageModelObj)
37 37 self.voltageReaderObj.setup(self.path, self.startDateTime, self.endDateTime)
38 38
39 39 # self.voltageWriterObj = VoltageWriter(self.voltageModelObj)
40 40 # self.voltageWriterObj.setup('/Users/danielangelsuarezmunoz/Documents/Projects/testWR')
41 41
42 42
43 43 def testReadVoltage(self):
44 44 while(not(self.voltageReaderObj.noMoreFiles)):
45 45
46 46 self.voltageReaderObj.getData()
47 47 if self.voltageReaderObj.flagResetProcessing:
48 48 print 'jump'
49 49
50 50 if self.voltageReaderObj.flagIsNewBlock:
51 51 print 'Block No %04d, Time: %s'%(self.voltageReaderObj.nTotalBlocks,
52 52 datetime.datetime.fromtimestamp(self.voltageReaderObj.m_BasicHeader.utc))
53 53
54 54 # self.voltageWriterObj.putData()
55 55
56 56 if __name__ == '__main__':
57 57 TestIO() No newline at end of file
1 NO CONTENT: modified file
General Comments 0
You need to be logged in to leave comments. Login now