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