##// END OF EJS Templates
Miguel Valdez -
r231:3ad829c7efcb
parent child
Show More
@@ -1,351 +1,353
1 1 import os
2 2 import numpy
3 import time, datetime
3 4 import mpldriver
4 5
5 6
6 7 class Figure:
7 8
8 9 __driver = mpldriver
9 10 fig = None
10 11
11 12 idfigure = None
12 13 wintitle = None
13 14 width = None
14 15 height = None
15 16 nplots = None
17 timerange = None
16 18
17 19 axesObjList = []
18 20
19 21 WIDTH = None
20 22 HEIGHT = None
21 23 PREFIX = 'fig'
22 24
23 25 def __init__(self):
24 26
25 27 raise ValueError, "This method is not implemented"
26 28
27 29 def __del__(self):
28 30
29 31 self.__driver.closeFigure()
30 32
31 33 def getFilename(self, name, ext='.png'):
32 34
33 35 filename = '%s_%s%s' %(self.PREFIX, name, ext)
34 36
35 37 return filename
36 38
37 39 def getAxesObjList(self):
38 40
39 41 return self.axesObjList
40 42
41 43 def getSubplots(self):
42 44
43 45 raise ValueError, "Abstract method: This method should be defined"
44 46
45 47 def getScreenDim(self, widthplot, heightplot):
46 48
47 49 nrow, ncol = self.getSubplots()
48 50
49 51 widthscreen = widthplot*ncol
50 52 heightscreen = heightplot*nrow
51 53
52 54 return widthscreen, heightscreen
53 55
54 56 def getTimeLim(self, x, xmin, xmax):
55 57
56 58 thisdatetime = datetime.datetime.fromtimestamp(numpy.min(x))
57 59 thisdate = datetime.datetime.combine(thisdatetime.date(), datetime.time(0,0,0))
58 60
59 61 ####################################################
60 62 #If the x is out of xrange
61 63 if xmax < (thisdatetime - thisdate).seconds/(60*60.):
62 64 xmin = None
63 65 xmax = None
64 66
65 67 if xmin == None:
66 68 td = thisdatetime - thisdate
67 69 xmin = td.seconds/(60*60.)
68 70
69 71 if xmax == None:
70 xmax = xmin + self.__timerange/(60*60.)
72 xmax = xmin + self.timerange/(60*60.)
71 73
72 74 mindt = thisdate + datetime.timedelta(0,0,0,0,0, xmin)
73 75 tmin = time.mktime(mindt.timetuple())
74 76
75 77 maxdt = thisdate + datetime.timedelta(0,0,0,0,0, xmax)
76 78 tmax = time.mktime(maxdt.timetuple())
77 79
78 self.__timerange = tmax - tmin
80 self.timerange = tmax - tmin
79 81
80 82 return tmin, tmax
81 83
82 84 def init(self, idfigure, nplots, wintitle):
83 85
84 86 raise ValueError, "This method has been replaced with createFigure"
85 87
86 88 def createFigure(self, idfigure, wintitle, widthplot=None, heightplot=None):
87 89
88 90 """
89 91 Crea la figura de acuerdo al driver y parametros seleccionados seleccionados.
90 92 Las dimensiones de la pantalla es calculada a partir de los atributos self.WIDTH
91 93 y self.HEIGHT y el numero de subplots (nrow, ncol)
92 94
93 95 Input:
94 96 idfigure : Los parametros necesarios son
95 97 wintitle :
96 98
97 99 """
98 100
99 101 if widthplot == None:
100 102 widthplot = self.WIDTH
101 103
102 104 if heightplot == None:
103 105 heightplot = self.HEIGHT
104 106
105 107 self.idfigure = idfigure
106 108
107 109 self.wintitle = wintitle
108 110
109 111 self.widthscreen, self.heightscreen = self.getScreenDim(widthplot, heightplot)
110 112
111 113 self.fig = self.__driver.createFigure(self.idfigure,
112 114 self.wintitle,
113 115 self.widthscreen,
114 116 self.heightscreen)
115 117
116 118 self.axesObjList = []
117 119
118 120 def setDriver(self, driver=mpldriver):
119 121
120 122 self.__driver = driver
121 123
122 124 def setTitle(self, title):
123 125
124 126 self.__driver.setTitle(self.fig, title)
125 127
126 128 def setWinTitle(self, title):
127 129
128 130 self.__driver.setWinTitle(self.fig, title=title)
129 131
130 132 def setTextFromAxes(self, text):
131 133
132 134 raise ValueError, "Este metodo ha sido reemplazaado con el metodo setText de la clase Axes"
133 135
134 136 def makeAxes(self, nrow, ncol, xpos, ypos, colspan, rowspan):
135 137
136 138 raise ValueError, "Este metodo ha sido reemplazaado con el metodo addAxes"
137 139
138 140 def addAxes(self, *args):
139 141 """
140 142
141 143 Input:
142 144 *args : Los parametros necesarios son
143 145 nrow, ncol, xpos, ypos, colspan, rowspan
144 146 """
145 147
146 148 axesObj = Axes(self.fig, *args)
147 149 self.axesObjList.append(axesObj)
148 150
149 151 def saveFigure(self, figpath, figfile, *args):
150 152
151 153 filename = os.path.join(figpath, figfile)
152 154 self.__driver.saveFigure(self.fig, filename, *args)
153 155
154 156 def draw(self):
155 157
156 158 self.__driver.draw(self.fig)
157 159
158 160 def run(self):
159 161
160 162 raise ValueError, "This method is not implemented"
161 163
162 164 axesList = property(getAxesObjList)
163 165
164 166
165 167 class Axes:
166 168
167 169 __driver = mpldriver
168 170 fig = None
169 171 ax = None
170 172 plot = None
171 173
172 174 __firsttime = None
173 175
174 176 __showprofile = False
175 177
176 178 xmin = None
177 179 xmax = None
178 180 ymin = None
179 181 ymax = None
180 182 zmin = None
181 183 zmax = None
182 184
183 185 def __init__(self, *args):
184 186
185 187 """
186 188
187 189 Input:
188 190 *args : Los parametros necesarios son
189 191 fig, nrow, ncol, xpos, ypos, colspan, rowspan
190 192 """
191 193
192 194 ax = self.__driver.createAxes(*args)
193 195 self.fig = args[0]
194 196 self.ax = ax
195 197 self.plot = None
196 198
197 199 self.__firsttime = True
198 200
199 201 def setText(self, text):
200 202
201 203 self.__driver.setAxesText(self.ax, text)
202 204
203 205 def setXAxisAsTime(self):
204 206 pass
205 207
206 208 def pline(self, x, y,
207 209 xmin=None, xmax=None,
208 210 ymin=None, ymax=None,
209 211 xlabel='', ylabel='',
210 212 title='',
211 213 **kwargs):
212 214
213 215 """
214 216
215 217 Input:
216 218 x :
217 219 y :
218 220 xmin :
219 221 xmax :
220 222 ymin :
221 223 ymax :
222 224 xlabel :
223 225 ylabel :
224 226 title :
225 227 **kwargs : Los parametros aceptados son
226 228
227 229 ticksize
228 230 ytick_visible
229 231 """
230 232
231 233 if self.__firsttime:
232 234
233 235 if xmin == None: xmin = numpy.nanmin(x)
234 236 if xmax == None: xmax = numpy.nanmax(x)
235 237 if ymin == None: ymin = numpy.nanmin(y)
236 238 if ymax == None: ymax = numpy.nanmax(y)
237 239
238 240 self.plot = self.__driver.createPline(self.ax, x, y,
239 241 xmin, xmax,
240 242 ymin, ymax,
241 243 xlabel=xlabel,
242 244 ylabel=ylabel,
243 245 title=title,
244 246 **kwargs)
245 247 self.__firsttime = False
246 248 return
247 249
248 250 self.__driver.pline(self.plot, x, y, xlabel=xlabel,
249 251 ylabel=ylabel,
250 252 title=title)
251 253
252 254 def pmultiline(self, x, y,
253 255 xmin=None, xmax=None,
254 256 ymin=None, ymax=None,
255 257 xlabel='', ylabel='',
256 258 title='',
257 259 **kwargs):
258 260
259 261 if self.__firsttime:
260 262
261 263 if xmin == None: xmin = numpy.nanmin(x)
262 264 if xmax == None: xmax = numpy.nanmax(x)
263 265 if ymin == None: ymin = numpy.nanmin(y)
264 266 if ymax == None: ymax = numpy.nanmax(y)
265 267
266 268 self.plot = self.__driver.createPmultiline(self.ax, x, y,
267 269 xmin, xmax,
268 270 ymin, ymax,
269 271 xlabel=xlabel,
270 272 ylabel=ylabel,
271 273 title=title,
272 274 **kwargs)
273 275 self.__firsttime = False
274 276 return
275 277
276 278 self.__driver.pmultiline(self.plot, x, y, xlabel=xlabel,
277 279 ylabel=ylabel,
278 280 title=title)
279 281
280 282 def pcolor(self, x, y, z,
281 283 xmin=None, xmax=None,
282 284 ymin=None, ymax=None,
283 285 zmin=None, zmax=None,
284 286 xlabel='', ylabel='',
285 287 title='', rti = False, colormap='jet',
286 288 **kwargs):
287 289
288 290 """
289 291 Input:
290 292 x :
291 293 y :
292 294 x :
293 295 xmin :
294 296 xmax :
295 297 ymin :
296 298 ymax :
297 299 zmin :
298 300 zmax :
299 301 xlabel :
300 302 ylabel :
301 303 title :
302 304 **kwargs : Los parametros aceptados son
303 305 ticksize=9,
304 306 cblabel=''
305 307 rti = True or False
306 308 """
307 309
308 310 if self.__firsttime:
309 311
310 312 if xmin == None: xmin = numpy.nanmin(x)
311 313 if xmax == None: xmax = numpy.nanmax(x)
312 314 if ymin == None: ymin = numpy.nanmin(y)
313 315 if ymax == None: ymax = numpy.nanmax(y)
314 316 if zmin == None: zmin = numpy.nanmin(z)
315 317 if zmax == None: zmax = numpy.nanmax(z)
316 318
317 319
318 320 self.plot = self.__driver.createPcolor(self.ax, x, y, z,
319 321 xmin, xmax,
320 322 ymin, ymax,
321 323 zmin, zmax,
322 324 xlabel=xlabel,
323 325 ylabel=ylabel,
324 326 title=title,
325 327 colormap=colormap,
326 328 **kwargs)
327 329
328 330 if self.xmin == None: self.xmin = xmin
329 331 if self.xmax == None: self.xmax = xmax
330 332 if self.ymin == None: self.ymin = ymin
331 333 if self.ymax == None: self.ymax = ymax
332 334 if self.zmin == None: self.zmin = zmin
333 335 if self.zmax == None: self.zmax = zmax
334 336
335 337 self.__firsttime = False
336 338 return
337 339
338 340 if rti:
339 341 self.__driver.addpcolor(self.ax, x, y, z, self.zmin, self.zmax,
340 342 xlabel=xlabel,
341 343 ylabel=ylabel,
342 344 title=title,
343 345 colormap=colormap)
344 346 return
345 347
346 348 self.__driver.pcolor(self.plot, z,
347 349 xlabel=xlabel,
348 350 ylabel=ylabel,
349 351 title=title)
350 352
351 353 No newline at end of file
@@ -1,2541 +1,2547
1 1 '''
2 2
3 3 $Author: murco $
4 4 $Id: JRODataIO.py 169 2012-11-19 21:57:03Z murco $
5 5 '''
6 6
7 7 import os, sys
8 8 import glob
9 9 import time
10 10 import numpy
11 11 import fnmatch
12 12 import time, datetime
13 13
14 14 from jrodata import *
15 15 from jroheaderIO import *
16 16 from jroprocessing import *
17 17
18 18 def isNumber(str):
19 19 """
20 20 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
21 21
22 22 Excepciones:
23 23 Si un determinado string no puede ser convertido a numero
24 24 Input:
25 25 str, string al cual se le analiza para determinar si convertible a un numero o no
26 26
27 27 Return:
28 28 True : si el string es uno numerico
29 29 False : no es un string numerico
30 30 """
31 31 try:
32 32 float( str )
33 33 return True
34 34 except:
35 35 return False
36 36
37 37 def isThisFileinRange(filename, startUTSeconds, endUTSeconds):
38 38 """
39 39 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
40 40
41 41 Inputs:
42 42 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
43 43
44 44 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
45 45 segundos contados desde 01/01/1970.
46 46 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
47 47 segundos contados desde 01/01/1970.
48 48
49 49 Return:
50 50 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
51 51 fecha especificado, de lo contrario retorna False.
52 52
53 53 Excepciones:
54 54 Si el archivo no existe o no puede ser abierto
55 55 Si la cabecera no puede ser leida.
56 56
57 57 """
58 58 basicHeaderObj = BasicHeader()
59 59
60 60 try:
61 61 fp = open(filename,'rb')
62 62 except:
63 63 raise IOError, "The file %s can't be opened" %(filename)
64 64
65 65 sts = basicHeaderObj.read(fp)
66 66 fp.close()
67 67
68 68 if not(sts):
69 69 print "Skipping the file %s because it has not a valid header" %(filename)
70 70 return 0
71 71
72 72 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
73 73 return 0
74 74
75 75 return 1
76 76
77 77 def isFileinThisTime(filename, startTime, endTime):
78 78 """
79 79 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
80 80
81 81 Inputs:
82 82 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
83 83
84 84 startTime : tiempo inicial del rango seleccionado en formato datetime.time
85 85
86 86 endTime : tiempo final del rango seleccionado en formato datetime.time
87 87
88 88 Return:
89 89 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
90 90 fecha especificado, de lo contrario retorna False.
91 91
92 92 Excepciones:
93 93 Si el archivo no existe o no puede ser abierto
94 94 Si la cabecera no puede ser leida.
95 95
96 96 """
97 97
98 98
99 99 try:
100 100 fp = open(filename,'rb')
101 101 except:
102 102 raise IOError, "The file %s can't be opened" %(filename)
103 103
104 104 basicHeaderObj = BasicHeader()
105 105 sts = basicHeaderObj.read(fp)
106 106 fp.close()
107 107
108 108 thisTime = basicHeaderObj.datatime.time()
109 109
110 110 if not(sts):
111 111 print "Skipping the file %s because it has not a valid header" %(filename)
112 112 return 0
113 113
114 114 if not ((startTime <= thisTime) and (endTime > thisTime)):
115 115 return 0
116 116
117 117 return 1
118 118
119 119 def getlastFileFromPath(path, ext):
120 120 """
121 121 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
122 122 al final de la depuracion devuelve el ultimo file de la lista que quedo.
123 123
124 124 Input:
125 125 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
126 126 ext : extension de los files contenidos en una carpeta
127 127
128 128 Return:
129 129 El ultimo file de una determinada carpeta, no se considera el path.
130 130 """
131 131 validFilelist = []
132 132 fileList = os.listdir(path)
133 133
134 134 # 0 1234 567 89A BCDE
135 135 # H YYYY DDD SSS .ext
136 136
137 137 for file in fileList:
138 138 try:
139 139 year = int(file[1:5])
140 140 doy = int(file[5:8])
141 141
142 142
143 143 except:
144 144 continue
145 145
146 146 if (os.path.splitext(file)[-1].lower() != ext.lower()):
147 147 continue
148 148
149 149 validFilelist.append(file)
150 150
151 151 if validFilelist:
152 152 validFilelist = sorted( validFilelist, key=str.lower )
153 153 return validFilelist[-1]
154 154
155 155 return None
156 156
157 157 def checkForRealPath(path, year, doy, set, ext):
158 158 """
159 159 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
160 160 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
161 161 el path exacto de un determinado file.
162 162
163 163 Example :
164 164 nombre correcto del file es .../.../D2009307/P2009307367.ext
165 165
166 166 Entonces la funcion prueba con las siguientes combinaciones
167 167 .../.../y2009307367.ext
168 168 .../.../Y2009307367.ext
169 169 .../.../x2009307/y2009307367.ext
170 170 .../.../x2009307/Y2009307367.ext
171 171 .../.../X2009307/y2009307367.ext
172 172 .../.../X2009307/Y2009307367.ext
173 173 siendo para este caso, la ultima combinacion de letras, identica al file buscado
174 174
175 175 Return:
176 176 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
177 177 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
178 178 para el filename
179 179 """
180 180 fullfilename = None
181 181 find_flag = False
182 182 filename = None
183 183
184 184 prefixDirList = [None,'d','D']
185 185 if ext.lower() == ".r": #voltage
186 186 prefixFileList = ['d','D']
187 187 elif ext.lower() == ".pdata": #spectra
188 188 prefixFileList = ['p','P']
189 189 else:
190 190 return None, filename
191 191
192 192 #barrido por las combinaciones posibles
193 193 for prefixDir in prefixDirList:
194 194 thispath = path
195 195 if prefixDir != None:
196 196 #formo el nombre del directorio xYYYYDDD (x=d o x=D)
197 197 thispath = os.path.join(path, "%s%04d%03d" % ( prefixDir, year, doy ))
198 198
199 199 for prefixFile in prefixFileList: #barrido por las dos combinaciones posibles de "D"
200 200 filename = "%s%04d%03d%03d%s" % ( prefixFile, year, doy, set, ext ) #formo el nombre del file xYYYYDDDSSS.ext
201 201 fullfilename = os.path.join( thispath, filename ) #formo el path completo
202 202
203 203 if os.path.exists( fullfilename ): #verifico que exista
204 204 find_flag = True
205 205 break
206 206 if find_flag:
207 207 break
208 208
209 209 if not(find_flag):
210 210 return None, filename
211 211
212 212 return fullfilename, filename
213 213
214 214 class JRODataIO:
215 215
216 216 c = 3E8
217 217
218 218 isConfig = False
219 219
220 220 basicHeaderObj = BasicHeader()
221 221
222 222 systemHeaderObj = SystemHeader()
223 223
224 224 radarControllerHeaderObj = RadarControllerHeader()
225 225
226 226 processingHeaderObj = ProcessingHeader()
227 227
228 228 online = 0
229 229
230 230 dtype = None
231 231
232 232 pathList = []
233 233
234 234 filenameList = []
235 235
236 236 filename = None
237 237
238 238 ext = None
239 239
240 240 flagIsNewFile = 1
241 241
242 242 flagTimeBlock = 0
243 243
244 244 flagIsNewBlock = 0
245 245
246 246 fp = None
247 247
248 248 firstHeaderSize = 0
249 249
250 250 basicHeaderSize = 24
251 251
252 252 versionFile = 1103
253 253
254 254 fileSize = None
255 255
256 256 ippSeconds = None
257 257
258 258 fileSizeByHeader = None
259 259
260 260 fileIndex = None
261 261
262 262 profileIndex = None
263 263
264 264 blockIndex = None
265 265
266 266 nTotalBlocks = None
267 267
268 268 maxTimeStep = 30
269 269
270 270 lastUTTime = None
271 271
272 272 datablock = None
273 273
274 274 dataOut = None
275 275
276 276 blocksize = None
277 277
278 278 def __init__(self):
279 279
280 280 raise ValueError, "Not implemented"
281 281
282 282 def run(self):
283 283
284 284 raise ValueError, "Not implemented"
285 285
286 286 def getOutput(self):
287 287
288 288 return self.dataOut
289 289
290 290 class JRODataReader(JRODataIO, ProcessingUnit):
291 291
292 292 nReadBlocks = 0
293 293
294 294 delay = 10 #number of seconds waiting a new file
295 295
296 296 nTries = 3 #quantity tries
297 297
298 298 nFiles = 3 #number of files for searching
299 299
300 300 flagNoMoreFiles = 0
301 301
302 302 def __init__(self):
303 303
304 304 """
305 305
306 306 """
307 307
308 308 raise ValueError, "This method has not been implemented"
309 309
310 310
311 311 def createObjByDefault(self):
312 312 """
313 313
314 314 """
315 315 raise ValueError, "This method has not been implemented"
316 316
317 317 def getBlockDimension(self):
318 318
319 319 raise ValueError, "No implemented"
320 320
321 321 def __searchFilesOffLine(self,
322 322 path,
323 323 startDate,
324 324 endDate,
325 325 startTime=datetime.time(0,0,0),
326 326 endTime=datetime.time(23,59,59),
327 327 set=None,
328 328 expLabel='',
329 329 ext='.r',
330 330 walk=True):
331 331
332 332 pathList = []
333 333
334 334 if not walk:
335 335 pathList.append(path)
336 336
337 337 else:
338 338 dirList = []
339 339 for thisPath in os.listdir(path):
340 340 if os.path.isdir(os.path.join(path,thisPath)):
341 341 dirList.append(thisPath)
342 342
343 343 if not(dirList):
344 344 return None, None
345 345
346 346 thisDate = startDate
347 347
348 348 while(thisDate <= endDate):
349 349 year = thisDate.timetuple().tm_year
350 350 doy = thisDate.timetuple().tm_yday
351 351
352 352 match = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy))
353 353 if len(match) == 0:
354 354 thisDate += datetime.timedelta(1)
355 355 continue
356 356
357 357 pathList.append(os.path.join(path,match[0],expLabel))
358 358 thisDate += datetime.timedelta(1)
359 359
360 if pathList == []:
361 print "Any folder found into date range %s-%s" %(startDate, endDate)
362 return None, None
363
364 print "%d folder(s) found [%s, ...]" %(len(pathList), pathList[0])
360 365
361 366 filenameList = []
362 367 for thisPath in pathList:
363 368
364 369 fileList = glob.glob1(thisPath, "*%s" %ext)
365 370 fileList.sort()
366 371
367 372 for file in fileList:
368 373
369 374 filename = os.path.join(thisPath,file)
370 375
371 376 if isFileinThisTime(filename, startTime, endTime):
372 377 filenameList.append(filename)
373 378
374 379 if not(filenameList):
380 print "Any file found into time range %s-%s" %(startTime, endTime)
375 381 return None, None
376 382
377 383 self.filenameList = filenameList
378 384
379 385 return pathList, filenameList
380 386
381 387 def __searchFilesOnLine(self, path, expLabel = "", ext = None, walk=True):
382 388
383 389 """
384 390 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
385 391 devuelve el archivo encontrado ademas de otros datos.
386 392
387 393 Input:
388 394 path : carpeta donde estan contenidos los files que contiene data
389 395
390 396 expLabel : Nombre del subexperimento (subfolder)
391 397
392 398 ext : extension de los files
393 399
394 400 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
395 401
396 402 Return:
397 403 directory : eL directorio donde esta el file encontrado
398 404 filename : el ultimo file de una determinada carpeta
399 405 year : el anho
400 406 doy : el numero de dia del anho
401 407 set : el set del archivo
402 408
403 409
404 410 """
405 411 dirList = []
406 412
407 413 if walk:
408 414
409 415 #Filtra solo los directorios
410 416 for thisPath in os.listdir(path):
411 417 if os.path.isdir(os.path.join(path, thisPath)):
412 418 dirList.append(thisPath)
413 419
414 420 if not(dirList):
415 421 return None, None, None, None, None
416 422
417 423 dirList = sorted( dirList, key=str.lower )
418 424
419 425 doypath = dirList[-1]
420 426 fullpath = os.path.join(path, doypath, expLabel)
421 427
422 428 else:
423 429 fullpath = path
424 430
425 431 filename = getlastFileFromPath(fullpath, ext)
426 432
427 433 if not(filename):
428 434 return None, None, None, None, None
429 435
430 436 if not(self.__verifyFile(os.path.join(fullpath, filename))):
431 437 return None, None, None, None, None
432 438
433 439 year = int( filename[1:5] )
434 440 doy = int( filename[5:8] )
435 441 set = int( filename[8:11] )
436 442
437 443 return fullpath, filename, year, doy, set
438 444
439 445
440 446
441 447 def __setNextFileOffline(self):
442 448
443 449 idFile = self.fileIndex
444 450
445 451 while (True):
446 452 idFile += 1
447 453 if not(idFile < len(self.filenameList)):
448 454 self.flagNoMoreFiles = 1
449 455 print "No more Files"
450 456 return 0
451 457
452 458 filename = self.filenameList[idFile]
453 459
454 460 if not(self.__verifyFile(filename)):
455 461 continue
456 462
457 463 fileSize = os.path.getsize(filename)
458 464 fp = open(filename,'rb')
459 465 break
460 466
461 467 self.flagIsNewFile = 1
462 468 self.fileIndex = idFile
463 469 self.filename = filename
464 470 self.fileSize = fileSize
465 471 self.fp = fp
466 472
467 473 print "Setting the file: %s"%self.filename
468 474
469 475 return 1
470 476
471 477 def __setNextFileOnline(self):
472 478 """
473 479 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
474 480 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
475 481 siguientes.
476 482
477 483 Affected:
478 484 self.flagIsNewFile
479 485 self.filename
480 486 self.fileSize
481 487 self.fp
482 488 self.set
483 489 self.flagNoMoreFiles
484 490
485 491 Return:
486 492 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
487 493 1 : si el file fue abierto con exito y esta listo a ser leido
488 494
489 495 Excepciones:
490 496 Si un determinado file no puede ser abierto
491 497 """
492 498 nFiles = 0
493 499 fileOk_flag = False
494 500 firstTime_flag = True
495 501
496 502 self.set += 1
497 503
498 504 #busca el 1er file disponible
499 505 fullfilename, filename = checkForRealPath( self.path, self.year, self.doy, self.set, self.ext )
500 506 if fullfilename:
501 507 if self.__verifyFile(fullfilename, False):
502 508 fileOk_flag = True
503 509
504 510 #si no encuentra un file entonces espera y vuelve a buscar
505 511 if not(fileOk_flag):
506 512 for nFiles in range(self.nFiles+1): #busco en los siguientes self.nFiles+1 files posibles
507 513
508 514 if firstTime_flag: #si es la 1era vez entonces hace el for self.nTries veces
509 515 tries = self.nTries
510 516 else:
511 517 tries = 1 #si no es la 1era vez entonces solo lo hace una vez
512 518
513 519 for nTries in range( tries ):
514 520 if firstTime_flag:
515 521 print "\tWaiting %0.2f sec for the file \"%s\" , try %03d ..." % ( self.delay, filename, nTries+1 )
516 522 time.sleep( self.delay )
517 523 else:
518 524 print "\tSearching next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext)
519 525
520 526 fullfilename, filename = checkForRealPath( self.path, self.year, self.doy, self.set, self.ext )
521 527 if fullfilename:
522 528 if self.__verifyFile(fullfilename):
523 529 fileOk_flag = True
524 530 break
525 531
526 532 if fileOk_flag:
527 533 break
528 534
529 535 firstTime_flag = False
530 536
531 537 print "\tSkipping the file \"%s\" due to this file doesn't exist" % filename
532 538 self.set += 1
533 539
534 540 if nFiles == (self.nFiles-1): #si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
535 541 self.set = 0
536 542 self.doy += 1
537 543
538 544 if fileOk_flag:
539 545 self.fileSize = os.path.getsize( fullfilename )
540 546 self.filename = fullfilename
541 547 self.flagIsNewFile = 1
542 548 if self.fp != None: self.fp.close()
543 549 self.fp = open(fullfilename, 'rb')
544 550 self.flagNoMoreFiles = 0
545 551 print 'Setting the file: %s' % fullfilename
546 552 else:
547 553 self.fileSize = 0
548 554 self.filename = None
549 555 self.flagIsNewFile = 0
550 556 self.fp = None
551 557 self.flagNoMoreFiles = 1
552 558 print 'No more Files'
553 559
554 560 return fileOk_flag
555 561
556 562
557 563 def setNextFile(self):
558 564 if self.fp != None:
559 565 self.fp.close()
560 566
561 567 if self.online:
562 568 newFile = self.__setNextFileOnline()
563 569 else:
564 570 newFile = self.__setNextFileOffline()
565 571
566 572 if not(newFile):
567 573 return 0
568 574
569 575 self.__readFirstHeader()
570 576 self.nReadBlocks = 0
571 577 return 1
572 578
573 579 def __waitNewBlock(self):
574 580 """
575 581 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
576 582
577 583 Si el modo de lectura es OffLine siempre retorn 0
578 584 """
579 585 if not self.online:
580 586 return 0
581 587
582 588 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
583 589 return 0
584 590
585 591 currentPointer = self.fp.tell()
586 592
587 593 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
588 594
589 595 for nTries in range( self.nTries ):
590 596
591 597 self.fp.close()
592 598 self.fp = open( self.filename, 'rb' )
593 599 self.fp.seek( currentPointer )
594 600
595 601 self.fileSize = os.path.getsize( self.filename )
596 602 currentSize = self.fileSize - currentPointer
597 603
598 604 if ( currentSize >= neededSize ):
599 605 self.__rdBasicHeader()
600 606 return 1
601 607
602 608 print "\tWaiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1)
603 609 time.sleep( self.delay )
604 610
605 611
606 612 return 0
607 613
608 614 def __setNewBlock(self):
609 615
610 616 if self.fp == None:
611 617 return 0
612 618
613 619 if self.flagIsNewFile:
614 620 return 1
615 621
616 622 self.lastUTTime = self.basicHeaderObj.utc
617 623 currentSize = self.fileSize - self.fp.tell()
618 624 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
619 625
620 626 if (currentSize >= neededSize):
621 627 self.__rdBasicHeader()
622 628 return 1
623 629
624 630 if self.__waitNewBlock():
625 631 return 1
626 632
627 633 if not(self.setNextFile()):
628 634 return 0
629 635
630 636 deltaTime = self.basicHeaderObj.utc - self.lastUTTime #
631 637
632 638 self.flagTimeBlock = 0
633 639
634 640 if deltaTime > self.maxTimeStep:
635 641 self.flagTimeBlock = 1
636 642
637 643 return 1
638 644
639 645
640 646 def readNextBlock(self):
641 647 if not(self.__setNewBlock()):
642 648 return 0
643 649
644 650 if not(self.readBlock()):
645 651 return 0
646 652
647 653 return 1
648 654
649 655 def __rdProcessingHeader(self, fp=None):
650 656 if fp == None:
651 657 fp = self.fp
652 658
653 659 self.processingHeaderObj.read(fp)
654 660
655 661 def __rdRadarControllerHeader(self, fp=None):
656 662 if fp == None:
657 663 fp = self.fp
658 664
659 665 self.radarControllerHeaderObj.read(fp)
660 666
661 667 def __rdSystemHeader(self, fp=None):
662 668 if fp == None:
663 669 fp = self.fp
664 670
665 671 self.systemHeaderObj.read(fp)
666 672
667 673 def __rdBasicHeader(self, fp=None):
668 674 if fp == None:
669 675 fp = self.fp
670 676
671 677 self.basicHeaderObj.read(fp)
672 678
673 679
674 680 def __readFirstHeader(self):
675 681 self.__rdBasicHeader()
676 682 self.__rdSystemHeader()
677 683 self.__rdRadarControllerHeader()
678 684 self.__rdProcessingHeader()
679 685
680 686 self.firstHeaderSize = self.basicHeaderObj.size
681 687
682 688 datatype = int(numpy.log2((self.processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
683 689 if datatype == 0:
684 690 datatype_str = numpy.dtype([('real','<i1'),('imag','<i1')])
685 691 elif datatype == 1:
686 692 datatype_str = numpy.dtype([('real','<i2'),('imag','<i2')])
687 693 elif datatype == 2:
688 694 datatype_str = numpy.dtype([('real','<i4'),('imag','<i4')])
689 695 elif datatype == 3:
690 696 datatype_str = numpy.dtype([('real','<i8'),('imag','<i8')])
691 697 elif datatype == 4:
692 698 datatype_str = numpy.dtype([('real','<f4'),('imag','<f4')])
693 699 elif datatype == 5:
694 700 datatype_str = numpy.dtype([('real','<f8'),('imag','<f8')])
695 701 else:
696 702 raise ValueError, 'Data type was not defined'
697 703
698 704 self.dtype = datatype_str
699 705 self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
700 706 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + self.firstHeaderSize + self.basicHeaderSize*(self.processingHeaderObj.dataBlocksPerFile - 1)
701 707 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
702 708 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
703 709 self.getBlockDimension()
704 710
705 711
706 712 def __verifyFile(self, filename, msgFlag=True):
707 713 msg = None
708 714 try:
709 715 fp = open(filename, 'rb')
710 716 currentPosition = fp.tell()
711 717 except:
712 718 if msgFlag:
713 719 print "The file %s can't be opened" % (filename)
714 720 return False
715 721
716 722 neededSize = self.processingHeaderObj.blockSize + self.firstHeaderSize
717 723
718 724 if neededSize == 0:
719 725 basicHeaderObj = BasicHeader()
720 726 systemHeaderObj = SystemHeader()
721 727 radarControllerHeaderObj = RadarControllerHeader()
722 728 processingHeaderObj = ProcessingHeader()
723 729
724 730 try:
725 731 if not( basicHeaderObj.read(fp) ): raise IOError
726 732 if not( systemHeaderObj.read(fp) ): raise IOError
727 733 if not( radarControllerHeaderObj.read(fp) ): raise IOError
728 734 if not( processingHeaderObj.read(fp) ): raise IOError
729 735 data_type = int(numpy.log2((processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
730 736
731 737 neededSize = processingHeaderObj.blockSize + basicHeaderObj.size
732 738
733 739 except:
734 740 if msgFlag:
735 741 print "\tThe file %s is empty or it hasn't enough data" % filename
736 742
737 743 fp.close()
738 744 return False
739 745 else:
740 746 msg = "\tSkipping the file %s due to it hasn't enough data" %filename
741 747
742 748 fp.close()
743 749 fileSize = os.path.getsize(filename)
744 750 currentSize = fileSize - currentPosition
745 751 if currentSize < neededSize:
746 752 if msgFlag and (msg != None):
747 753 print msg #print"\tSkipping the file %s due to it hasn't enough data" %filename
748 754 return False
749 755
750 756 return True
751 757
752 758 def setup(self,
753 759 path=None,
754 760 startDate=None,
755 761 endDate=None,
756 762 startTime=datetime.time(0,0,0),
757 763 endTime=datetime.time(23,59,59),
758 764 set=0,
759 765 expLabel = "",
760 766 ext = None,
761 767 online = False,
762 768 delay = 60,
763 769 walk = True):
764 770
765 771 if path == None:
766 772 raise ValueError, "The path is not valid"
767 773
768 774 if ext == None:
769 775 ext = self.ext
770 776
771 777 if online:
772 778 print "Searching files in online mode..."
773 779
774 780 for nTries in range( self.nTries ):
775 781 fullpath, file, year, doy, set = self.__searchFilesOnLine(path=path, expLabel=expLabel, ext=ext, walk=walk)
776 782
777 783 if fullpath:
778 784 break
779 785
780 786 print '\tWaiting %0.2f sec for an valid file in %s: try %02d ...' % (self.delay, path, nTries+1)
781 787 time.sleep( self.delay )
782 788
783 789 if not(fullpath):
784 790 print "There 'isn't valied files in %s" % path
785 791 return None
786 792
787 793 self.year = year
788 794 self.doy = doy
789 795 self.set = set - 1
790 796 self.path = path
791 797
792 798 else:
793 799 print "Searching files in offline mode ..."
794 800 pathList, filenameList = self.__searchFilesOffLine(path, startDate=startDate, endDate=endDate,
795 801 startTime=startTime, endTime=endTime,
796 802 set=set, expLabel=expLabel, ext=ext,
797 803 walk=walk)
798 804
799 805 if not(pathList):
800 806 print "No *%s files into the folder %s \nfor the range: %s - %s"%(ext, path,
801 807 datetime.datetime.combine(startDate,startTime).ctime(),
802 808 datetime.datetime.combine(endDate,endTime).ctime())
803 809
804 810 sys.exit(-1)
805 811
806 812
807 813 self.fileIndex = -1
808 814 self.pathList = pathList
809 815 self.filenameList = filenameList
810 816
811 817 self.online = online
812 818 self.delay = delay
813 819 ext = ext.lower()
814 820 self.ext = ext
815 821
816 822 if not(self.setNextFile()):
817 823 if (startDate!=None) and (endDate!=None):
818 824 print "No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
819 825 elif startDate != None:
820 826 print "No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime())
821 827 else:
822 828 print "No files"
823 829
824 830 sys.exit(-1)
825 831
826 832 # self.updateDataHeader()
827 833
828 834 return self.dataOut
829 835
830 836 def getData():
831 837
832 838 raise ValueError, "This method has not been implemented"
833 839
834 840 def hasNotDataInBuffer():
835 841
836 842 raise ValueError, "This method has not been implemented"
837 843
838 844 def readBlock():
839 845
840 846 raise ValueError, "This method has not been implemented"
841 847
842 848 def isEndProcess(self):
843 849
844 850 return self.flagNoMoreFiles
845 851
846 852 def printReadBlocks(self):
847 853
848 854 print "Number of read blocks per file %04d" %self.nReadBlocks
849 855
850 856 def printTotalBlocks(self):
851 857
852 858 print "Number of read blocks %04d" %self.nTotalBlocks
853 859
854 860 def printInfo(self):
855 861
856 862 print self.basicHeaderObj.printInfo()
857 863 print self.systemHeaderObj.printInfo()
858 864 print self.radarControllerHeaderObj.printInfo()
859 865 print self.processingHeaderObj.printInfo()
860 866
861 867
862 868 def run(self, **kwargs):
863 869
864 870 if not(self.isConfig):
865 871
866 872 # self.dataOut = dataOut
867 873 self.setup(**kwargs)
868 874 self.isConfig = True
869 875
870 876 self.getData()
871 877
872 878 class JRODataWriter(JRODataIO, Operation):
873 879
874 880 """
875 881 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
876 882 de los datos siempre se realiza por bloques.
877 883 """
878 884
879 885 blockIndex = 0
880 886
881 887 path = None
882 888
883 889 setFile = None
884 890
885 891 profilesPerBlock = None
886 892
887 893 blocksPerFile = None
888 894
889 895 nWriteBlocks = 0
890 896
891 897 def __init__(self, dataOut=None):
892 898 raise ValueError, "Not implemented"
893 899
894 900
895 901 def hasAllDataInBuffer(self):
896 902 raise ValueError, "Not implemented"
897 903
898 904
899 905 def setBlockDimension(self):
900 906 raise ValueError, "Not implemented"
901 907
902 908
903 909 def writeBlock(self):
904 910 raise ValueError, "No implemented"
905 911
906 912
907 913 def putData(self):
908 914 raise ValueError, "No implemented"
909 915
910 916 def getDataHeader(self):
911 917 """
912 918 Obtiene una copia del First Header
913 919
914 920 Affected:
915 921
916 922 self.basicHeaderObj
917 923 self.systemHeaderObj
918 924 self.radarControllerHeaderObj
919 925 self.processingHeaderObj self.
920 926
921 927 Return:
922 928 None
923 929 """
924 930
925 931 raise ValueError, "No implemented"
926 932
927 933 def getBasicHeader(self):
928 934
929 935 self.basicHeaderObj.size = self.basicHeaderSize #bytes
930 936 self.basicHeaderObj.version = self.versionFile
931 937 self.basicHeaderObj.dataBlock = self.nTotalBlocks
932 938
933 939 utc = numpy.floor(self.dataOut.utctime)
934 940 milisecond = (self.dataOut.utctime - utc)* 1000.0
935 941
936 942 self.basicHeaderObj.utc = utc
937 943 self.basicHeaderObj.miliSecond = milisecond
938 944 self.basicHeaderObj.timeZone = 0
939 945 self.basicHeaderObj.dstFlag = 0
940 946 self.basicHeaderObj.errorCount = 0
941 947
942 948 def __writeFirstHeader(self):
943 949 """
944 950 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
945 951
946 952 Affected:
947 953 __dataType
948 954
949 955 Return:
950 956 None
951 957 """
952 958
953 959 # CALCULAR PARAMETROS
954 960
955 961 sizeLongHeader = self.systemHeaderObj.size + self.radarControllerHeaderObj.size + self.processingHeaderObj.size
956 962 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
957 963
958 964 self.basicHeaderObj.write(self.fp)
959 965 self.systemHeaderObj.write(self.fp)
960 966 self.radarControllerHeaderObj.write(self.fp)
961 967 self.processingHeaderObj.write(self.fp)
962 968
963 969 self.dtype = self.dataOut.dtype
964 970
965 971 def __setNewBlock(self):
966 972 """
967 973 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
968 974
969 975 Return:
970 976 0 : si no pudo escribir nada
971 977 1 : Si escribio el Basic el First Header
972 978 """
973 979 if self.fp == None:
974 980 self.setNextFile()
975 981
976 982 if self.flagIsNewFile:
977 983 return 1
978 984
979 985 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
980 986 self.basicHeaderObj.write(self.fp)
981 987 return 1
982 988
983 989 if not( self.setNextFile() ):
984 990 return 0
985 991
986 992 return 1
987 993
988 994
989 995 def writeNextBlock(self):
990 996 """
991 997 Selecciona el bloque siguiente de datos y los escribe en un file
992 998
993 999 Return:
994 1000 0 : Si no hizo pudo escribir el bloque de datos
995 1001 1 : Si no pudo escribir el bloque de datos
996 1002 """
997 1003 if not( self.__setNewBlock() ):
998 1004 return 0
999 1005
1000 1006 self.writeBlock()
1001 1007
1002 1008 return 1
1003 1009
1004 1010 def setNextFile(self):
1005 1011 """
1006 1012 Determina el siguiente file que sera escrito
1007 1013
1008 1014 Affected:
1009 1015 self.filename
1010 1016 self.subfolder
1011 1017 self.fp
1012 1018 self.setFile
1013 1019 self.flagIsNewFile
1014 1020
1015 1021 Return:
1016 1022 0 : Si el archivo no puede ser escrito
1017 1023 1 : Si el archivo esta listo para ser escrito
1018 1024 """
1019 1025 ext = self.ext
1020 1026 path = self.path
1021 1027
1022 1028 if self.fp != None:
1023 1029 self.fp.close()
1024 1030
1025 1031 timeTuple = time.localtime( self.dataOut.dataUtcTime)
1026 1032 subfolder = 'D%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
1027 1033
1028 1034 fullpath = os.path.join( path, subfolder )
1029 1035 if not( os.path.exists(fullpath) ):
1030 1036 os.mkdir(fullpath)
1031 1037 self.setFile = -1 #inicializo mi contador de seteo
1032 1038 else:
1033 1039 filesList = os.listdir( fullpath )
1034 1040 if len( filesList ) > 0:
1035 1041 filesList = sorted( filesList, key=str.lower )
1036 1042 filen = filesList[-1]
1037 1043 # el filename debera tener el siguiente formato
1038 1044 # 0 1234 567 89A BCDE (hex)
1039 1045 # x YYYY DDD SSS .ext
1040 1046 if isNumber( filen[8:11] ):
1041 1047 self.setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
1042 1048 else:
1043 1049 self.setFile = -1
1044 1050 else:
1045 1051 self.setFile = -1 #inicializo mi contador de seteo
1046 1052
1047 1053 setFile = self.setFile
1048 1054 setFile += 1
1049 1055
1050 1056 file = '%s%4.4d%3.3d%3.3d%s' % (self.optchar,
1051 1057 timeTuple.tm_year,
1052 1058 timeTuple.tm_yday,
1053 1059 setFile,
1054 1060 ext )
1055 1061
1056 1062 filename = os.path.join( path, subfolder, file )
1057 1063
1058 1064 fp = open( filename,'wb' )
1059 1065
1060 1066 self.blockIndex = 0
1061 1067
1062 1068 #guardando atributos
1063 1069 self.filename = filename
1064 1070 self.subfolder = subfolder
1065 1071 self.fp = fp
1066 1072 self.setFile = setFile
1067 1073 self.flagIsNewFile = 1
1068 1074
1069 1075 self.getDataHeader()
1070 1076
1071 1077 print 'Writing the file: %s'%self.filename
1072 1078
1073 1079 self.__writeFirstHeader()
1074 1080
1075 1081 return 1
1076 1082
1077 1083 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=None, set=0, ext=None):
1078 1084 """
1079 1085 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1080 1086
1081 1087 Inputs:
1082 1088 path : el path destino en el cual se escribiran los files a crear
1083 1089 format : formato en el cual sera salvado un file
1084 1090 set : el setebo del file
1085 1091
1086 1092 Return:
1087 1093 0 : Si no realizo un buen seteo
1088 1094 1 : Si realizo un buen seteo
1089 1095 """
1090 1096
1091 1097 if ext == None:
1092 1098 ext = self.ext
1093 1099
1094 1100 ext = ext.lower()
1095 1101
1096 1102 self.ext = ext
1097 1103
1098 1104 self.path = path
1099 1105
1100 1106 self.setFile = set - 1
1101 1107
1102 1108 self.blocksPerFile = blocksPerFile
1103 1109
1104 1110 self.profilesPerBlock = profilesPerBlock
1105 1111
1106 1112 self.dataOut = dataOut
1107 1113
1108 1114 if not(self.setNextFile()):
1109 1115 print "There isn't a next file"
1110 1116 return 0
1111 1117
1112 1118 self.setBlockDimension()
1113 1119
1114 1120 return 1
1115 1121
1116 1122 def run(self, dataOut, **kwargs):
1117 1123
1118 1124 if not(self.isConfig):
1119 1125
1120 1126 self.setup(dataOut, **kwargs)
1121 1127 self.isConfig = True
1122 1128
1123 1129 self.putData()
1124 1130
1125 1131 class VoltageReader(JRODataReader):
1126 1132 """
1127 1133 Esta clase permite leer datos de voltage desde archivos en formato rawdata (.r). La lectura
1128 1134 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones:
1129 1135 perfiles*alturas*canales) son almacenados en la variable "buffer".
1130 1136
1131 1137 perfiles * alturas * canales
1132 1138
1133 1139 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
1134 1140 RadarControllerHeader y Voltage. Los tres primeros se usan para almacenar informacion de la
1135 1141 cabecera de datos (metadata), y el cuarto (Voltage) para obtener y almacenar un perfil de
1136 1142 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
1137 1143
1138 1144 Example:
1139 1145
1140 1146 dpath = "/home/myuser/data"
1141 1147
1142 1148 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
1143 1149
1144 1150 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
1145 1151
1146 1152 readerObj = VoltageReader()
1147 1153
1148 1154 readerObj.setup(dpath, startTime, endTime)
1149 1155
1150 1156 while(True):
1151 1157
1152 1158 #to get one profile
1153 1159 profile = readerObj.getData()
1154 1160
1155 1161 #print the profile
1156 1162 print profile
1157 1163
1158 1164 #If you want to see all datablock
1159 1165 print readerObj.datablock
1160 1166
1161 1167 if readerObj.flagNoMoreFiles:
1162 1168 break
1163 1169
1164 1170 """
1165 1171
1166 1172 ext = ".r"
1167 1173
1168 1174 optchar = "D"
1169 1175 dataOut = None
1170 1176
1171 1177
1172 1178 def __init__(self):
1173 1179 """
1174 1180 Inicializador de la clase VoltageReader para la lectura de datos de voltage.
1175 1181
1176 1182 Input:
1177 1183 dataOut : Objeto de la clase Voltage. Este objeto sera utilizado para
1178 1184 almacenar un perfil de datos cada vez que se haga un requerimiento
1179 1185 (getData). El perfil sera obtenido a partir del buffer de datos,
1180 1186 si el buffer esta vacio se hara un nuevo proceso de lectura de un
1181 1187 bloque de datos.
1182 1188 Si este parametro no es pasado se creara uno internamente.
1183 1189
1184 1190 Variables afectadas:
1185 1191 self.dataOut
1186 1192
1187 1193 Return:
1188 1194 None
1189 1195 """
1190 1196
1191 1197 self.isConfig = False
1192 1198
1193 1199 self.datablock = None
1194 1200
1195 1201 self.utc = 0
1196 1202
1197 1203 self.ext = ".r"
1198 1204
1199 1205 self.optchar = "D"
1200 1206
1201 1207 self.basicHeaderObj = BasicHeader()
1202 1208
1203 1209 self.systemHeaderObj = SystemHeader()
1204 1210
1205 1211 self.radarControllerHeaderObj = RadarControllerHeader()
1206 1212
1207 1213 self.processingHeaderObj = ProcessingHeader()
1208 1214
1209 1215 self.online = 0
1210 1216
1211 1217 self.fp = None
1212 1218
1213 1219 self.idFile = None
1214 1220
1215 1221 self.dtype = None
1216 1222
1217 1223 self.fileSizeByHeader = None
1218 1224
1219 1225 self.filenameList = []
1220 1226
1221 1227 self.filename = None
1222 1228
1223 1229 self.fileSize = None
1224 1230
1225 1231 self.firstHeaderSize = 0
1226 1232
1227 1233 self.basicHeaderSize = 24
1228 1234
1229 1235 self.pathList = []
1230 1236
1231 1237 self.filenameList = []
1232 1238
1233 1239 self.lastUTTime = 0
1234 1240
1235 1241 self.maxTimeStep = 30
1236 1242
1237 1243 self.flagNoMoreFiles = 0
1238 1244
1239 1245 self.set = 0
1240 1246
1241 1247 self.path = None
1242 1248
1243 1249 self.profileIndex = 9999
1244 1250
1245 1251 self.delay = 3 #seconds
1246 1252
1247 1253 self.nTries = 3 #quantity tries
1248 1254
1249 1255 self.nFiles = 3 #number of files for searching
1250 1256
1251 1257 self.nReadBlocks = 0
1252 1258
1253 1259 self.flagIsNewFile = 1
1254 1260
1255 1261 self.ippSeconds = 0
1256 1262
1257 1263 self.flagTimeBlock = 0
1258 1264
1259 1265 self.flagIsNewBlock = 0
1260 1266
1261 1267 self.nTotalBlocks = 0
1262 1268
1263 1269 self.blocksize = 0
1264 1270
1265 1271 self.dataOut = self.createObjByDefault()
1266 1272
1267 1273 def createObjByDefault(self):
1268 1274
1269 1275 dataObj = Voltage()
1270 1276
1271 1277 return dataObj
1272 1278
1273 1279 def __hasNotDataInBuffer(self):
1274 1280 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock:
1275 1281 return 1
1276 1282 return 0
1277 1283
1278 1284
1279 1285 def getBlockDimension(self):
1280 1286 """
1281 1287 Obtiene la cantidad de puntos a leer por cada bloque de datos
1282 1288
1283 1289 Affected:
1284 1290 self.blocksize
1285 1291
1286 1292 Return:
1287 1293 None
1288 1294 """
1289 1295 pts2read = self.processingHeaderObj.profilesPerBlock * self.processingHeaderObj.nHeights * self.systemHeaderObj.nChannels
1290 1296 self.blocksize = pts2read
1291 1297
1292 1298
1293 1299 def readBlock(self):
1294 1300 """
1295 1301 readBlock lee el bloque de datos desde la posicion actual del puntero del archivo
1296 1302 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
1297 1303 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
1298 1304 es seteado a 0
1299 1305
1300 1306 Inputs:
1301 1307 None
1302 1308
1303 1309 Return:
1304 1310 None
1305 1311
1306 1312 Affected:
1307 1313 self.profileIndex
1308 1314 self.datablock
1309 1315 self.flagIsNewFile
1310 1316 self.flagIsNewBlock
1311 1317 self.nTotalBlocks
1312 1318
1313 1319 Exceptions:
1314 1320 Si un bloque leido no es un bloque valido
1315 1321 """
1316 1322
1317 1323 junk = numpy.fromfile( self.fp, self.dtype, self.blocksize )
1318 1324
1319 1325 try:
1320 1326 junk = junk.reshape( (self.processingHeaderObj.profilesPerBlock, self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels) )
1321 1327 except:
1322 1328 print "The read block (%3d) has not enough data" %self.nReadBlocks
1323 1329 return 0
1324 1330
1325 1331 junk = numpy.transpose(junk, (2,0,1))
1326 1332 self.datablock = junk['real'] + junk['imag']*1j
1327 1333
1328 1334 self.profileIndex = 0
1329 1335
1330 1336 self.flagIsNewFile = 0
1331 1337 self.flagIsNewBlock = 1
1332 1338
1333 1339 self.nTotalBlocks += 1
1334 1340 self.nReadBlocks += 1
1335 1341
1336 1342 return 1
1337 1343
1338 1344
1339 1345 def getData(self):
1340 1346 """
1341 1347 getData obtiene una unidad de datos del buffer de lectura y la copia a la clase "Voltage"
1342 1348 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
1343 1349 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
1344 1350
1345 1351 Ademas incrementa el contador del buffer en 1.
1346 1352
1347 1353 Return:
1348 1354 data : retorna un perfil de voltages (alturas * canales) copiados desde el
1349 1355 buffer. Si no hay mas archivos a leer retorna None.
1350 1356
1351 1357 Variables afectadas:
1352 1358 self.dataOut
1353 1359 self.profileIndex
1354 1360
1355 1361 Affected:
1356 1362 self.dataOut
1357 1363 self.profileIndex
1358 1364 self.flagTimeBlock
1359 1365 self.flagIsNewBlock
1360 1366 """
1361 1367
1362 1368 if self.flagNoMoreFiles:
1363 1369 self.dataOut.flagNoData = True
1364 1370 print 'Process finished'
1365 1371 return 0
1366 1372
1367 1373 self.flagTimeBlock = 0
1368 1374 self.flagIsNewBlock = 0
1369 1375
1370 1376 if self.__hasNotDataInBuffer():
1371 1377
1372 1378 if not( self.readNextBlock() ):
1373 1379 return 0
1374 1380
1375 1381 self.dataOut.dtype = self.dtype
1376 1382
1377 1383 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
1378 1384
1379 1385 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
1380 1386
1381 1387 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
1382 1388
1383 1389 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
1384 1390
1385 1391 self.dataOut.flagTimeBlock = self.flagTimeBlock
1386 1392
1387 1393 self.dataOut.ippSeconds = self.ippSeconds
1388 1394
1389 1395 self.dataOut.timeInterval = self.ippSeconds * self.processingHeaderObj.nCohInt
1390 1396
1391 1397 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
1392 1398
1393 1399 self.dataOut.flagShiftFFT = False
1394 1400
1395 1401 if self.processingHeaderObj.code != None:
1396 1402 self.dataOut.nCode = self.processingHeaderObj.nCode
1397 1403
1398 1404 self.dataOut.nBaud = self.processingHeaderObj.nBaud
1399 1405
1400 1406 self.dataOut.code = self.processingHeaderObj.code
1401 1407
1402 1408 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
1403 1409
1404 1410 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
1405 1411
1406 1412 # self.updateDataHeader()
1407 1413
1408 1414 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
1409 1415
1410 1416 if self.datablock == None:
1411 1417 self.dataOut.flagNoData = True
1412 1418 return 0
1413 1419
1414 1420 self.dataOut.data = self.datablock[:,self.profileIndex,:]
1415 1421
1416 1422 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond/1000. + self.profileIndex * self.ippSeconds
1417 1423
1418 1424 self.profileIndex += 1
1419 1425
1420 1426 self.dataOut.flagNoData = False
1421 1427
1422 1428 # print self.profileIndex, self.dataOut.utctime
1423 1429 # if self.profileIndex == 800:
1424 1430 # a=1
1425 1431
1426 1432
1427 1433 return self.dataOut.data
1428 1434
1429 1435
1430 1436 class VoltageWriter(JRODataWriter):
1431 1437 """
1432 1438 Esta clase permite escribir datos de voltajes a archivos procesados (.r). La escritura
1433 1439 de los datos siempre se realiza por bloques.
1434 1440 """
1435 1441
1436 1442 ext = ".r"
1437 1443
1438 1444 optchar = "D"
1439 1445
1440 1446 shapeBuffer = None
1441 1447
1442 1448
1443 1449 def __init__(self):
1444 1450 """
1445 1451 Inicializador de la clase VoltageWriter para la escritura de datos de espectros.
1446 1452
1447 1453 Affected:
1448 1454 self.dataOut
1449 1455
1450 1456 Return: None
1451 1457 """
1452 1458
1453 1459 self.nTotalBlocks = 0
1454 1460
1455 1461 self.profileIndex = 0
1456 1462
1457 1463 self.isConfig = False
1458 1464
1459 1465 self.fp = None
1460 1466
1461 1467 self.flagIsNewFile = 1
1462 1468
1463 1469 self.nTotalBlocks = 0
1464 1470
1465 1471 self.flagIsNewBlock = 0
1466 1472
1467 1473 self.setFile = None
1468 1474
1469 1475 self.dtype = None
1470 1476
1471 1477 self.path = None
1472 1478
1473 1479 self.filename = None
1474 1480
1475 1481 self.basicHeaderObj = BasicHeader()
1476 1482
1477 1483 self.systemHeaderObj = SystemHeader()
1478 1484
1479 1485 self.radarControllerHeaderObj = RadarControllerHeader()
1480 1486
1481 1487 self.processingHeaderObj = ProcessingHeader()
1482 1488
1483 1489 def hasAllDataInBuffer(self):
1484 1490 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock:
1485 1491 return 1
1486 1492 return 0
1487 1493
1488 1494
1489 1495 def setBlockDimension(self):
1490 1496 """
1491 1497 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
1492 1498
1493 1499 Affected:
1494 1500 self.shape_spc_Buffer
1495 1501 self.shape_cspc_Buffer
1496 1502 self.shape_dc_Buffer
1497 1503
1498 1504 Return: None
1499 1505 """
1500 1506 self.shapeBuffer = (self.processingHeaderObj.profilesPerBlock,
1501 1507 self.processingHeaderObj.nHeights,
1502 1508 self.systemHeaderObj.nChannels)
1503 1509
1504 1510 self.datablock = numpy.zeros((self.systemHeaderObj.nChannels,
1505 1511 self.processingHeaderObj.profilesPerBlock,
1506 1512 self.processingHeaderObj.nHeights),
1507 1513 dtype=numpy.dtype('complex'))
1508 1514
1509 1515
1510 1516 def writeBlock(self):
1511 1517 """
1512 1518 Escribe el buffer en el file designado
1513 1519
1514 1520 Affected:
1515 1521 self.profileIndex
1516 1522 self.flagIsNewFile
1517 1523 self.flagIsNewBlock
1518 1524 self.nTotalBlocks
1519 1525 self.blockIndex
1520 1526
1521 1527 Return: None
1522 1528 """
1523 1529 data = numpy.zeros( self.shapeBuffer, self.dtype )
1524 1530
1525 1531 junk = numpy.transpose(self.datablock, (1,2,0))
1526 1532
1527 1533 data['real'] = junk.real
1528 1534 data['imag'] = junk.imag
1529 1535
1530 1536 data = data.reshape( (-1) )
1531 1537
1532 1538 data.tofile( self.fp )
1533 1539
1534 1540 self.datablock.fill(0)
1535 1541
1536 1542 self.profileIndex = 0
1537 1543 self.flagIsNewFile = 0
1538 1544 self.flagIsNewBlock = 1
1539 1545
1540 1546 self.blockIndex += 1
1541 1547 self.nTotalBlocks += 1
1542 1548
1543 1549 def putData(self):
1544 1550 """
1545 1551 Setea un bloque de datos y luego los escribe en un file
1546 1552
1547 1553 Affected:
1548 1554 self.flagIsNewBlock
1549 1555 self.profileIndex
1550 1556
1551 1557 Return:
1552 1558 0 : Si no hay data o no hay mas files que puedan escribirse
1553 1559 1 : Si se escribio la data de un bloque en un file
1554 1560 """
1555 1561 if self.dataOut.flagNoData:
1556 1562 return 0
1557 1563
1558 1564 self.flagIsNewBlock = 0
1559 1565
1560 1566 if self.dataOut.flagTimeBlock:
1561 1567
1562 1568 self.datablock.fill(0)
1563 1569 self.profileIndex = 0
1564 1570 self.setNextFile()
1565 1571
1566 1572 if self.profileIndex == 0:
1567 1573 self.getBasicHeader()
1568 1574
1569 1575 self.datablock[:,self.profileIndex,:] = self.dataOut.data
1570 1576
1571 1577 self.profileIndex += 1
1572 1578
1573 1579 if self.hasAllDataInBuffer():
1574 1580 #if self.flagIsNewFile:
1575 1581 self.writeNextBlock()
1576 1582 # self.getDataHeader()
1577 1583
1578 1584 return 1
1579 1585
1580 1586 def __getProcessFlags(self):
1581 1587
1582 1588 processFlags = 0
1583 1589
1584 1590 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
1585 1591 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
1586 1592 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
1587 1593 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
1588 1594 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
1589 1595 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
1590 1596
1591 1597 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
1592 1598
1593 1599
1594 1600
1595 1601 datatypeValueList = [PROCFLAG.DATATYPE_CHAR,
1596 1602 PROCFLAG.DATATYPE_SHORT,
1597 1603 PROCFLAG.DATATYPE_LONG,
1598 1604 PROCFLAG.DATATYPE_INT64,
1599 1605 PROCFLAG.DATATYPE_FLOAT,
1600 1606 PROCFLAG.DATATYPE_DOUBLE]
1601 1607
1602 1608
1603 1609 for index in range(len(dtypeList)):
1604 1610 if self.dataOut.dtype == dtypeList[index]:
1605 1611 dtypeValue = datatypeValueList[index]
1606 1612 break
1607 1613
1608 1614 processFlags += dtypeValue
1609 1615
1610 1616 if self.dataOut.flagDecodeData:
1611 1617 processFlags += PROCFLAG.DECODE_DATA
1612 1618
1613 1619 if self.dataOut.flagDeflipData:
1614 1620 processFlags += PROCFLAG.DEFLIP_DATA
1615 1621
1616 1622 if self.dataOut.code != None:
1617 1623 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1618 1624
1619 1625 if self.dataOut.nCohInt > 1:
1620 1626 processFlags += PROCFLAG.COHERENT_INTEGRATION
1621 1627
1622 1628 return processFlags
1623 1629
1624 1630
1625 1631 def __getBlockSize(self):
1626 1632 '''
1627 1633 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Voltage
1628 1634 '''
1629 1635
1630 1636 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
1631 1637 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
1632 1638 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
1633 1639 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
1634 1640 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
1635 1641 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
1636 1642
1637 1643 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
1638 1644 datatypeValueList = [1,2,4,8,4,8]
1639 1645 for index in range(len(dtypeList)):
1640 1646 if self.dataOut.dtype == dtypeList[index]:
1641 1647 datatypeValue = datatypeValueList[index]
1642 1648 break
1643 1649
1644 1650 blocksize = int(self.dataOut.nHeights * self.dataOut.nChannels * self.dataOut.nProfiles * datatypeValue * 2)
1645 1651
1646 1652 return blocksize
1647 1653
1648 1654 def getDataHeader(self):
1649 1655
1650 1656 """
1651 1657 Obtiene una copia del First Header
1652 1658
1653 1659 Affected:
1654 1660 self.systemHeaderObj
1655 1661 self.radarControllerHeaderObj
1656 1662 self.dtype
1657 1663
1658 1664 Return:
1659 1665 None
1660 1666 """
1661 1667
1662 1668 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
1663 1669 self.systemHeaderObj.nChannels = self.dataOut.nChannels
1664 1670 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
1665 1671
1666 1672 self.getBasicHeader()
1667 1673
1668 1674 processingHeaderSize = 40 # bytes
1669 1675 self.processingHeaderObj.dtype = 0 # Voltage
1670 1676 self.processingHeaderObj.blockSize = self.__getBlockSize()
1671 1677 self.processingHeaderObj.profilesPerBlock = self.profilesPerBlock
1672 1678 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
1673 1679 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
1674 1680 self.processingHeaderObj.processFlags = self.__getProcessFlags()
1675 1681 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt
1676 1682 self.processingHeaderObj.nIncohInt = 1 # Cuando la data de origen es de tipo Voltage
1677 1683 self.processingHeaderObj.totalSpectra = 0 # Cuando la data de origen es de tipo Voltage
1678 1684
1679 1685 if self.dataOut.code != None:
1680 1686 self.processingHeaderObj.code = self.dataOut.code
1681 1687 self.processingHeaderObj.nCode = self.dataOut.nCode
1682 1688 self.processingHeaderObj.nBaud = self.dataOut.nBaud
1683 1689 codesize = int(8 + 4 * self.dataOut.nCode * self.dataOut.nBaud)
1684 1690 processingHeaderSize += codesize
1685 1691
1686 1692 if self.processingHeaderObj.nWindows != 0:
1687 1693 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
1688 1694 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
1689 1695 self.processingHeaderObj.nHeights = self.dataOut.nHeights
1690 1696 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
1691 1697 processingHeaderSize += 12
1692 1698
1693 1699 self.processingHeaderObj.size = processingHeaderSize
1694 1700
1695 1701 class SpectraReader(JRODataReader):
1696 1702 """
1697 1703 Esta clase permite leer datos de espectros desde archivos procesados (.pdata). La lectura
1698 1704 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones)
1699 1705 son almacenados en tres buffer's para el Self Spectra, el Cross Spectra y el DC Channel.
1700 1706
1701 1707 paresCanalesIguales * alturas * perfiles (Self Spectra)
1702 1708 paresCanalesDiferentes * alturas * perfiles (Cross Spectra)
1703 1709 canales * alturas (DC Channels)
1704 1710
1705 1711 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
1706 1712 RadarControllerHeader y Spectra. Los tres primeros se usan para almacenar informacion de la
1707 1713 cabecera de datos (metadata), y el cuarto (Spectra) para obtener y almacenar un bloque de
1708 1714 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
1709 1715
1710 1716 Example:
1711 1717 dpath = "/home/myuser/data"
1712 1718
1713 1719 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
1714 1720
1715 1721 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
1716 1722
1717 1723 readerObj = SpectraReader()
1718 1724
1719 1725 readerObj.setup(dpath, startTime, endTime)
1720 1726
1721 1727 while(True):
1722 1728
1723 1729 readerObj.getData()
1724 1730
1725 1731 print readerObj.data_spc
1726 1732
1727 1733 print readerObj.data_cspc
1728 1734
1729 1735 print readerObj.data_dc
1730 1736
1731 1737 if readerObj.flagNoMoreFiles:
1732 1738 break
1733 1739
1734 1740 """
1735 1741
1736 1742 pts2read_SelfSpectra = 0
1737 1743
1738 1744 pts2read_CrossSpectra = 0
1739 1745
1740 1746 pts2read_DCchannels = 0
1741 1747
1742 1748 ext = ".pdata"
1743 1749
1744 1750 optchar = "P"
1745 1751
1746 1752 dataOut = None
1747 1753
1748 1754 nRdChannels = None
1749 1755
1750 1756 nRdPairs = None
1751 1757
1752 1758 rdPairList = []
1753 1759
1754 1760
1755 1761 def __init__(self):
1756 1762 """
1757 1763 Inicializador de la clase SpectraReader para la lectura de datos de espectros.
1758 1764
1759 1765 Inputs:
1760 1766 dataOut : Objeto de la clase Spectra. Este objeto sera utilizado para
1761 1767 almacenar un perfil de datos cada vez que se haga un requerimiento
1762 1768 (getData). El perfil sera obtenido a partir del buffer de datos,
1763 1769 si el buffer esta vacio se hara un nuevo proceso de lectura de un
1764 1770 bloque de datos.
1765 1771 Si este parametro no es pasado se creara uno internamente.
1766 1772
1767 1773 Affected:
1768 1774 self.dataOut
1769 1775
1770 1776 Return : None
1771 1777 """
1772 1778
1773 1779 self.isConfig = False
1774 1780
1775 1781 self.pts2read_SelfSpectra = 0
1776 1782
1777 1783 self.pts2read_CrossSpectra = 0
1778 1784
1779 1785 self.pts2read_DCchannels = 0
1780 1786
1781 1787 self.datablock = None
1782 1788
1783 1789 self.utc = None
1784 1790
1785 1791 self.ext = ".pdata"
1786 1792
1787 1793 self.optchar = "P"
1788 1794
1789 1795 self.basicHeaderObj = BasicHeader()
1790 1796
1791 1797 self.systemHeaderObj = SystemHeader()
1792 1798
1793 1799 self.radarControllerHeaderObj = RadarControllerHeader()
1794 1800
1795 1801 self.processingHeaderObj = ProcessingHeader()
1796 1802
1797 1803 self.online = 0
1798 1804
1799 1805 self.fp = None
1800 1806
1801 1807 self.idFile = None
1802 1808
1803 1809 self.dtype = None
1804 1810
1805 1811 self.fileSizeByHeader = None
1806 1812
1807 1813 self.filenameList = []
1808 1814
1809 1815 self.filename = None
1810 1816
1811 1817 self.fileSize = None
1812 1818
1813 1819 self.firstHeaderSize = 0
1814 1820
1815 1821 self.basicHeaderSize = 24
1816 1822
1817 1823 self.pathList = []
1818 1824
1819 1825 self.lastUTTime = 0
1820 1826
1821 1827 self.maxTimeStep = 30
1822 1828
1823 1829 self.flagNoMoreFiles = 0
1824 1830
1825 1831 self.set = 0
1826 1832
1827 1833 self.path = None
1828 1834
1829 1835 self.delay = 3 #seconds
1830 1836
1831 1837 self.nTries = 3 #quantity tries
1832 1838
1833 1839 self.nFiles = 3 #number of files for searching
1834 1840
1835 1841 self.nReadBlocks = 0
1836 1842
1837 1843 self.flagIsNewFile = 1
1838 1844
1839 1845 self.ippSeconds = 0
1840 1846
1841 1847 self.flagTimeBlock = 0
1842 1848
1843 1849 self.flagIsNewBlock = 0
1844 1850
1845 1851 self.nTotalBlocks = 0
1846 1852
1847 1853 self.blocksize = 0
1848 1854
1849 1855 self.dataOut = self.createObjByDefault()
1850 1856
1851 1857
1852 1858 def createObjByDefault(self):
1853 1859
1854 1860 dataObj = Spectra()
1855 1861
1856 1862 return dataObj
1857 1863
1858 1864 def __hasNotDataInBuffer(self):
1859 1865 return 1
1860 1866
1861 1867
1862 1868 def getBlockDimension(self):
1863 1869 """
1864 1870 Obtiene la cantidad de puntos a leer por cada bloque de datos
1865 1871
1866 1872 Affected:
1867 1873 self.nRdChannels
1868 1874 self.nRdPairs
1869 1875 self.pts2read_SelfSpectra
1870 1876 self.pts2read_CrossSpectra
1871 1877 self.pts2read_DCchannels
1872 1878 self.blocksize
1873 1879 self.dataOut.nChannels
1874 1880 self.dataOut.nPairs
1875 1881
1876 1882 Return:
1877 1883 None
1878 1884 """
1879 1885 self.nRdChannels = 0
1880 1886 self.nRdPairs = 0
1881 1887 self.rdPairList = []
1882 1888
1883 1889 for i in range(0, self.processingHeaderObj.totalSpectra*2, 2):
1884 1890 if self.processingHeaderObj.spectraComb[i] == self.processingHeaderObj.spectraComb[i+1]:
1885 1891 self.nRdChannels = self.nRdChannels + 1 #par de canales iguales
1886 1892 else:
1887 1893 self.nRdPairs = self.nRdPairs + 1 #par de canales diferentes
1888 1894 self.rdPairList.append((self.processingHeaderObj.spectraComb[i], self.processingHeaderObj.spectraComb[i+1]))
1889 1895
1890 1896 pts2read = self.processingHeaderObj.nHeights * self.processingHeaderObj.profilesPerBlock
1891 1897
1892 1898 self.pts2read_SelfSpectra = int(self.nRdChannels * pts2read)
1893 1899 self.blocksize = self.pts2read_SelfSpectra
1894 1900
1895 1901 if self.processingHeaderObj.flag_cspc:
1896 1902 self.pts2read_CrossSpectra = int(self.nRdPairs * pts2read)
1897 1903 self.blocksize += self.pts2read_CrossSpectra
1898 1904
1899 1905 if self.processingHeaderObj.flag_dc:
1900 1906 self.pts2read_DCchannels = int(self.systemHeaderObj.nChannels * self.processingHeaderObj.nHeights)
1901 1907 self.blocksize += self.pts2read_DCchannels
1902 1908
1903 1909 # self.blocksize = self.pts2read_SelfSpectra + self.pts2read_CrossSpectra + self.pts2read_DCchannels
1904 1910
1905 1911
1906 1912 def readBlock(self):
1907 1913 """
1908 1914 Lee el bloque de datos desde la posicion actual del puntero del archivo
1909 1915 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
1910 1916 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
1911 1917 es seteado a 0
1912 1918
1913 1919 Return: None
1914 1920
1915 1921 Variables afectadas:
1916 1922
1917 1923 self.flagIsNewFile
1918 1924 self.flagIsNewBlock
1919 1925 self.nTotalBlocks
1920 1926 self.data_spc
1921 1927 self.data_cspc
1922 1928 self.data_dc
1923 1929
1924 1930 Exceptions:
1925 1931 Si un bloque leido no es un bloque valido
1926 1932 """
1927 1933 blockOk_flag = False
1928 1934 fpointer = self.fp.tell()
1929 1935
1930 1936 spc = numpy.fromfile( self.fp, self.dtype[0], self.pts2read_SelfSpectra )
1931 1937 spc = spc.reshape( (self.nRdChannels, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
1932 1938
1933 1939 if self.processingHeaderObj.flag_cspc:
1934 1940 cspc = numpy.fromfile( self.fp, self.dtype, self.pts2read_CrossSpectra )
1935 1941 cspc = cspc.reshape( (self.nRdPairs, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
1936 1942
1937 1943 if self.processingHeaderObj.flag_dc:
1938 1944 dc = numpy.fromfile( self.fp, self.dtype, self.pts2read_DCchannels ) #int(self.processingHeaderObj.nHeights*self.systemHeaderObj.nChannels) )
1939 1945 dc = dc.reshape( (self.systemHeaderObj.nChannels, self.processingHeaderObj.nHeights) ) #transforma a un arreglo 2D
1940 1946
1941 1947
1942 1948 if not(self.processingHeaderObj.shif_fft):
1943 1949 #desplaza a la derecha en el eje 2 determinadas posiciones
1944 1950 shift = int(self.processingHeaderObj.profilesPerBlock/2)
1945 1951 spc = numpy.roll( spc, shift , axis=2 )
1946 1952
1947 1953 if self.processingHeaderObj.flag_cspc:
1948 1954 #desplaza a la derecha en el eje 2 determinadas posiciones
1949 1955 cspc = numpy.roll( cspc, shift, axis=2 )
1950 1956
1951 1957
1952 1958 spc = numpy.transpose( spc, (0,2,1) )
1953 1959 self.data_spc = spc
1954 1960
1955 1961 if self.processingHeaderObj.flag_cspc:
1956 1962 cspc = numpy.transpose( cspc, (0,2,1) )
1957 1963 self.data_cspc = cspc['real'] + cspc['imag']*1j
1958 1964 else:
1959 1965 self.data_cspc = None
1960 1966
1961 1967 if self.processingHeaderObj.flag_dc:
1962 1968 self.data_dc = dc['real'] + dc['imag']*1j
1963 1969 else:
1964 1970 self.data_dc = None
1965 1971
1966 1972 self.flagIsNewFile = 0
1967 1973 self.flagIsNewBlock = 1
1968 1974
1969 1975 self.nTotalBlocks += 1
1970 1976 self.nReadBlocks += 1
1971 1977
1972 1978 return 1
1973 1979
1974 1980
1975 1981 def getData(self):
1976 1982 """
1977 1983 Copia el buffer de lectura a la clase "Spectra",
1978 1984 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
1979 1985 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
1980 1986
1981 1987 Return:
1982 1988 0 : Si no hay mas archivos disponibles
1983 1989 1 : Si hizo una buena copia del buffer
1984 1990
1985 1991 Affected:
1986 1992 self.dataOut
1987 1993
1988 1994 self.flagTimeBlock
1989 1995 self.flagIsNewBlock
1990 1996 """
1991 1997
1992 1998 if self.flagNoMoreFiles:
1993 1999 self.dataOut.flagNoData = True
1994 2000 print 'Process finished'
1995 2001 return 0
1996 2002
1997 2003 self.flagTimeBlock = 0
1998 2004 self.flagIsNewBlock = 0
1999 2005
2000 2006 if self.__hasNotDataInBuffer():
2001 2007
2002 2008 if not( self.readNextBlock() ):
2003 2009 self.dataOut.flagNoData = True
2004 2010 return 0
2005 2011
2006 2012 # self.updateDataHeader()
2007 2013
2008 2014 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
2009 2015
2010 2016 if self.data_dc == None:
2011 2017 self.dataOut.flagNoData = True
2012 2018 return 0
2013 2019
2014 2020 self.dataOut.data_spc = self.data_spc
2015 2021
2016 2022 self.dataOut.data_cspc = self.data_cspc
2017 2023
2018 2024 self.dataOut.data_dc = self.data_dc
2019 2025
2020 2026 self.dataOut.flagTimeBlock = self.flagTimeBlock
2021 2027
2022 2028 self.dataOut.flagNoData = False
2023 2029
2024 2030 self.dataOut.dtype = self.dtype
2025 2031
2026 2032 # self.dataOut.nChannels = self.nRdChannels
2027 2033
2028 2034 self.dataOut.nPairs = self.nRdPairs
2029 2035
2030 2036 self.dataOut.pairsList = self.rdPairList
2031 2037
2032 2038 # self.dataOut.nHeights = self.processingHeaderObj.nHeights
2033 2039
2034 2040 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
2035 2041
2036 2042 self.dataOut.nFFTPoints = self.processingHeaderObj.profilesPerBlock
2037 2043
2038 2044 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
2039 2045
2040 2046 self.dataOut.nIncohInt = self.processingHeaderObj.nIncohInt
2041 2047
2042 2048 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
2043 2049
2044 2050 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
2045 2051
2046 2052 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
2047 2053
2048 2054 # self.dataOut.channelIndexList = range(self.systemHeaderObj.nChannels)
2049 2055
2050 2056 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond/1000.#+ self.profileIndex * self.ippSeconds
2051 2057
2052 2058 self.dataOut.ippSeconds = self.ippSeconds
2053 2059
2054 2060 self.dataOut.timeInterval = self.ippSeconds * self.processingHeaderObj.nCohInt * self.processingHeaderObj.nIncohInt * self.dataOut.nFFTPoints
2055 2061
2056 2062 self.dataOut.flagShiftFFT = self.processingHeaderObj.shif_fft
2057 2063
2058 2064 # self.profileIndex += 1
2059 2065
2060 2066 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
2061 2067
2062 2068 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
2063 2069
2064 2070 return self.dataOut.data_spc
2065 2071
2066 2072
2067 2073 class SpectraWriter(JRODataWriter):
2068 2074
2069 2075 """
2070 2076 Esta clase permite escribir datos de espectros a archivos procesados (.pdata). La escritura
2071 2077 de los datos siempre se realiza por bloques.
2072 2078 """
2073 2079
2074 2080 ext = ".pdata"
2075 2081
2076 2082 optchar = "P"
2077 2083
2078 2084 shape_spc_Buffer = None
2079 2085
2080 2086 shape_cspc_Buffer = None
2081 2087
2082 2088 shape_dc_Buffer = None
2083 2089
2084 2090 data_spc = None
2085 2091
2086 2092 data_cspc = None
2087 2093
2088 2094 data_dc = None
2089 2095
2090 2096 # dataOut = None
2091 2097
2092 2098 def __init__(self):
2093 2099 """
2094 2100 Inicializador de la clase SpectraWriter para la escritura de datos de espectros.
2095 2101
2096 2102 Affected:
2097 2103 self.dataOut
2098 2104 self.basicHeaderObj
2099 2105 self.systemHeaderObj
2100 2106 self.radarControllerHeaderObj
2101 2107 self.processingHeaderObj
2102 2108
2103 2109 Return: None
2104 2110 """
2105 2111
2106 2112 self.isConfig = False
2107 2113
2108 2114 self.nTotalBlocks = 0
2109 2115
2110 2116 self.data_spc = None
2111 2117
2112 2118 self.data_cspc = None
2113 2119
2114 2120 self.data_dc = None
2115 2121
2116 2122 self.fp = None
2117 2123
2118 2124 self.flagIsNewFile = 1
2119 2125
2120 2126 self.nTotalBlocks = 0
2121 2127
2122 2128 self.flagIsNewBlock = 0
2123 2129
2124 2130 self.setFile = None
2125 2131
2126 2132 self.dtype = None
2127 2133
2128 2134 self.path = None
2129 2135
2130 2136 self.noMoreFiles = 0
2131 2137
2132 2138 self.filename = None
2133 2139
2134 2140 self.basicHeaderObj = BasicHeader()
2135 2141
2136 2142 self.systemHeaderObj = SystemHeader()
2137 2143
2138 2144 self.radarControllerHeaderObj = RadarControllerHeader()
2139 2145
2140 2146 self.processingHeaderObj = ProcessingHeader()
2141 2147
2142 2148
2143 2149 def hasAllDataInBuffer(self):
2144 2150 return 1
2145 2151
2146 2152
2147 2153 def setBlockDimension(self):
2148 2154 """
2149 2155 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
2150 2156
2151 2157 Affected:
2152 2158 self.shape_spc_Buffer
2153 2159 self.shape_cspc_Buffer
2154 2160 self.shape_dc_Buffer
2155 2161
2156 2162 Return: None
2157 2163 """
2158 2164 self.shape_spc_Buffer = (self.dataOut.nChannels,
2159 2165 self.processingHeaderObj.nHeights,
2160 2166 self.processingHeaderObj.profilesPerBlock)
2161 2167
2162 2168 self.shape_cspc_Buffer = (self.dataOut.nPairs,
2163 2169 self.processingHeaderObj.nHeights,
2164 2170 self.processingHeaderObj.profilesPerBlock)
2165 2171
2166 2172 self.shape_dc_Buffer = (self.dataOut.nChannels,
2167 2173 self.processingHeaderObj.nHeights)
2168 2174
2169 2175
2170 2176 def writeBlock(self):
2171 2177 """
2172 2178 Escribe el buffer en el file designado
2173 2179
2174 2180 Affected:
2175 2181 self.data_spc
2176 2182 self.data_cspc
2177 2183 self.data_dc
2178 2184 self.flagIsNewFile
2179 2185 self.flagIsNewBlock
2180 2186 self.nTotalBlocks
2181 2187 self.nWriteBlocks
2182 2188
2183 2189 Return: None
2184 2190 """
2185 2191
2186 2192 spc = numpy.transpose( self.data_spc, (0,2,1) )
2187 2193 if not( self.processingHeaderObj.shif_fft ):
2188 2194 spc = numpy.roll( spc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
2189 2195 data = spc.reshape((-1))
2190 2196 data.tofile(self.fp)
2191 2197
2192 2198 if self.data_cspc != None:
2193 2199 data = numpy.zeros( self.shape_cspc_Buffer, self.dtype )
2194 2200 cspc = numpy.transpose( self.data_cspc, (0,2,1) )
2195 2201 if not( self.processingHeaderObj.shif_fft ):
2196 2202 cspc = numpy.roll( cspc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
2197 2203 data['real'] = cspc.real
2198 2204 data['imag'] = cspc.imag
2199 2205 data = data.reshape((-1))
2200 2206 data.tofile(self.fp)
2201 2207
2202 2208 if self.data_dc != None:
2203 2209 data = numpy.zeros( self.shape_dc_Buffer, self.dtype )
2204 2210 dc = self.data_dc
2205 2211 data['real'] = dc.real
2206 2212 data['imag'] = dc.imag
2207 2213 data = data.reshape((-1))
2208 2214 data.tofile(self.fp)
2209 2215
2210 2216 self.data_spc.fill(0)
2211 2217 self.data_dc.fill(0)
2212 2218 if self.data_cspc != None:
2213 2219 self.data_cspc.fill(0)
2214 2220
2215 2221 self.flagIsNewFile = 0
2216 2222 self.flagIsNewBlock = 1
2217 2223 self.nTotalBlocks += 1
2218 2224 self.nWriteBlocks += 1
2219 2225 self.blockIndex += 1
2220 2226
2221 2227
2222 2228 def putData(self):
2223 2229 """
2224 2230 Setea un bloque de datos y luego los escribe en un file
2225 2231
2226 2232 Affected:
2227 2233 self.data_spc
2228 2234 self.data_cspc
2229 2235 self.data_dc
2230 2236
2231 2237 Return:
2232 2238 0 : Si no hay data o no hay mas files que puedan escribirse
2233 2239 1 : Si se escribio la data de un bloque en un file
2234 2240 """
2235 2241
2236 2242 if self.dataOut.flagNoData:
2237 2243 return 0
2238 2244
2239 2245 self.flagIsNewBlock = 0
2240 2246
2241 2247 if self.dataOut.flagTimeBlock:
2242 2248 self.data_spc.fill(0)
2243 2249 self.data_cspc.fill(0)
2244 2250 self.data_dc.fill(0)
2245 2251 self.setNextFile()
2246 2252
2247 2253 if self.flagIsNewFile == 0:
2248 2254 self.getBasicHeader()
2249 2255
2250 2256 self.data_spc = self.dataOut.data_spc
2251 2257 self.data_cspc = self.dataOut.data_cspc
2252 2258 self.data_dc = self.dataOut.data_dc
2253 2259
2254 2260 # #self.processingHeaderObj.dataBlocksPerFile)
2255 2261 if self.hasAllDataInBuffer():
2256 2262 # self.getDataHeader()
2257 2263 self.writeNextBlock()
2258 2264
2259 2265 return 1
2260 2266
2261 2267
2262 2268 def __getProcessFlags(self):
2263 2269
2264 2270 processFlags = 0
2265 2271
2266 2272 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
2267 2273 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
2268 2274 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
2269 2275 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
2270 2276 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
2271 2277 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
2272 2278
2273 2279 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
2274 2280
2275 2281
2276 2282
2277 2283 datatypeValueList = [PROCFLAG.DATATYPE_CHAR,
2278 2284 PROCFLAG.DATATYPE_SHORT,
2279 2285 PROCFLAG.DATATYPE_LONG,
2280 2286 PROCFLAG.DATATYPE_INT64,
2281 2287 PROCFLAG.DATATYPE_FLOAT,
2282 2288 PROCFLAG.DATATYPE_DOUBLE]
2283 2289
2284 2290
2285 2291 for index in range(len(dtypeList)):
2286 2292 if self.dataOut.dtype == dtypeList[index]:
2287 2293 dtypeValue = datatypeValueList[index]
2288 2294 break
2289 2295
2290 2296 processFlags += dtypeValue
2291 2297
2292 2298 if self.dataOut.flagDecodeData:
2293 2299 processFlags += PROCFLAG.DECODE_DATA
2294 2300
2295 2301 if self.dataOut.flagDeflipData:
2296 2302 processFlags += PROCFLAG.DEFLIP_DATA
2297 2303
2298 2304 if self.dataOut.code != None:
2299 2305 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
2300 2306
2301 2307 if self.dataOut.nIncohInt > 1:
2302 2308 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
2303 2309
2304 2310 if self.dataOut.data_dc != None:
2305 2311 processFlags += PROCFLAG.SAVE_CHANNELS_DC
2306 2312
2307 2313 return processFlags
2308 2314
2309 2315
2310 2316 def __getBlockSize(self):
2311 2317 '''
2312 2318 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Spectra
2313 2319 '''
2314 2320
2315 2321 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
2316 2322 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
2317 2323 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
2318 2324 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
2319 2325 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
2320 2326 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
2321 2327
2322 2328 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
2323 2329 datatypeValueList = [1,2,4,8,4,8]
2324 2330 for index in range(len(dtypeList)):
2325 2331 if self.dataOut.dtype == dtypeList[index]:
2326 2332 datatypeValue = datatypeValueList[index]
2327 2333 break
2328 2334
2329 2335
2330 2336 pts2write = self.dataOut.nHeights * self.dataOut.nFFTPoints
2331 2337
2332 2338 pts2write_SelfSpectra = int(self.dataOut.nChannels * pts2write)
2333 2339 blocksize = (pts2write_SelfSpectra*datatypeValue)
2334 2340
2335 2341 if self.dataOut.data_cspc != None:
2336 2342 pts2write_CrossSpectra = int(self.dataOut.nPairs * pts2write)
2337 2343 blocksize += (pts2write_CrossSpectra*datatypeValue*2)
2338 2344
2339 2345 if self.dataOut.data_dc != None:
2340 2346 pts2write_DCchannels = int(self.dataOut.nChannels * self.dataOut.nHeights)
2341 2347 blocksize += (pts2write_DCchannels*datatypeValue*2)
2342 2348
2343 2349 blocksize = blocksize #* datatypeValue * 2 #CORREGIR ESTO
2344 2350
2345 2351 return blocksize
2346 2352
2347 2353 def getDataHeader(self):
2348 2354
2349 2355 """
2350 2356 Obtiene una copia del First Header
2351 2357
2352 2358 Affected:
2353 2359 self.systemHeaderObj
2354 2360 self.radarControllerHeaderObj
2355 2361 self.dtype
2356 2362
2357 2363 Return:
2358 2364 None
2359 2365 """
2360 2366
2361 2367 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
2362 2368 self.systemHeaderObj.nChannels = self.dataOut.nChannels
2363 2369 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
2364 2370
2365 2371 self.getBasicHeader()
2366 2372
2367 2373 processingHeaderSize = 40 # bytes
2368 2374 self.processingHeaderObj.dtype = 0 # Voltage
2369 2375 self.processingHeaderObj.blockSize = self.__getBlockSize()
2370 2376 self.processingHeaderObj.profilesPerBlock = self.dataOut.nFFTPoints
2371 2377 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
2372 2378 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
2373 2379 self.processingHeaderObj.processFlags = self.__getProcessFlags()
2374 2380 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt# Se requiere para determinar el valor de timeInterval
2375 2381 self.processingHeaderObj.nIncohInt = self.dataOut.nIncohInt
2376 2382 self.processingHeaderObj.totalSpectra = self.dataOut.nPairs + self.dataOut.nChannels
2377 2383
2378 2384 if self.processingHeaderObj.totalSpectra > 0:
2379 2385 channelList = []
2380 2386 for channel in range(self.dataOut.nChannels):
2381 2387 channelList.append(channel)
2382 2388 channelList.append(channel)
2383 2389
2384 2390 pairsList = []
2385 2391 for pair in self.dataOut.pairsList:
2386 2392 pairsList.append(pair[0])
2387 2393 pairsList.append(pair[1])
2388 2394 spectraComb = channelList + pairsList
2389 2395 spectraComb = numpy.array(spectraComb,dtype="u1")
2390 2396 self.processingHeaderObj.spectraComb = spectraComb
2391 2397 sizeOfSpcComb = len(spectraComb)
2392 2398 processingHeaderSize += sizeOfSpcComb
2393 2399
2394 2400 if self.dataOut.code != None:
2395 2401 self.processingHeaderObj.code = self.dataOut.code
2396 2402 self.processingHeaderObj.nCode = self.dataOut.nCode
2397 2403 self.processingHeaderObj.nBaud = self.dataOut.nBaud
2398 2404 nCodeSize = 4 # bytes
2399 2405 nBaudSize = 4 # bytes
2400 2406 codeSize = 4 # bytes
2401 2407 sizeOfCode = int(nCodeSize + nBaudSize + codeSize * self.dataOut.nCode * self.dataOut.nBaud)
2402 2408 processingHeaderSize += sizeOfCode
2403 2409
2404 2410 if self.processingHeaderObj.nWindows != 0:
2405 2411 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
2406 2412 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
2407 2413 self.processingHeaderObj.nHeights = self.dataOut.nHeights
2408 2414 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
2409 2415 sizeOfFirstHeight = 4
2410 2416 sizeOfdeltaHeight = 4
2411 2417 sizeOfnHeights = 4
2412 2418 sizeOfWindows = (sizeOfFirstHeight + sizeOfdeltaHeight + sizeOfnHeights)*self.processingHeaderObj.nWindows
2413 2419 processingHeaderSize += sizeOfWindows
2414 2420
2415 2421 self.processingHeaderObj.size = processingHeaderSize
2416 2422
2417 2423 class SpectraHeisWriter():
2418 2424
2419 2425 i=0
2420 2426
2421 2427 def __init__(self, dataOut):
2422 2428
2423 2429 self.wrObj = FITS()
2424 2430 self.dataOut = dataOut
2425 2431
2426 2432 def isNumber(str):
2427 2433 """
2428 2434 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
2429 2435
2430 2436 Excepciones:
2431 2437 Si un determinado string no puede ser convertido a numero
2432 2438 Input:
2433 2439 str, string al cual se le analiza para determinar si convertible a un numero o no
2434 2440
2435 2441 Return:
2436 2442 True : si el string es uno numerico
2437 2443 False : no es un string numerico
2438 2444 """
2439 2445 try:
2440 2446 float( str )
2441 2447 return True
2442 2448 except:
2443 2449 return False
2444 2450
2445 2451 def setup(self, wrpath,):
2446 2452
2447 2453 if not(os.path.exists(wrpath)):
2448 2454 os.mkdir(wrpath)
2449 2455
2450 2456 self.wrpath = wrpath
2451 2457 self.setFile = 0
2452 2458
2453 2459 def putData(self):
2454 2460 # self.wrObj.writeHeader(nChannels=self.dataOut.nChannels, nFFTPoints=self.dataOut.nFFTPoints)
2455 2461 #name = self.dataOut.utctime
2456 2462 name= time.localtime( self.dataOut.utctime)
2457 2463 ext=".fits"
2458 2464 #folder='D%4.4d%3.3d'%(name.tm_year,name.tm_yday)
2459 2465 subfolder = 'D%4.4d%3.3d' % (name.tm_year,name.tm_yday)
2460 2466
2461 2467 fullpath = os.path.join( self.wrpath, subfolder )
2462 2468 if not( os.path.exists(fullpath) ):
2463 2469 os.mkdir(fullpath)
2464 2470 self.setFile += 1
2465 2471 file = 'D%4.4d%3.3d%3.3d%s' % (name.tm_year,name.tm_yday,self.setFile,ext)
2466 2472
2467 2473 filename = os.path.join(self.wrpath,subfolder, file)
2468 2474
2469 2475 # print self.dataOut.ippSeconds
2470 2476 freq=numpy.arange(-1*self.dataOut.nHeights/2.,self.dataOut.nHeights/2.)/(2*self.dataOut.ippSeconds)
2471 2477
2472 2478 col1=self.wrObj.setColF(name="freq", format=str(self.dataOut.nFFTPoints)+'E', array=freq)
2473 2479 col2=self.wrObj.writeData(name="P_Ch1",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[0,:]))
2474 2480 col3=self.wrObj.writeData(name="P_Ch2",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[1,:]))
2475 2481 col4=self.wrObj.writeData(name="P_Ch3",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[2,:]))
2476 2482 col5=self.wrObj.writeData(name="P_Ch4",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[3,:]))
2477 2483 col6=self.wrObj.writeData(name="P_Ch5",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[4,:]))
2478 2484 col7=self.wrObj.writeData(name="P_Ch6",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[5,:]))
2479 2485 col8=self.wrObj.writeData(name="P_Ch7",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[6,:]))
2480 2486 col9=self.wrObj.writeData(name="P_Ch8",format=str(self.dataOut.nFFTPoints)+'E',data=10*numpy.log10(self.dataOut.data_spc[7,:]))
2481 2487 #n=numpy.arange((100))
2482 2488 n=self.dataOut.data_spc[6,:]
2483 2489 a=self.wrObj.cFImage(n)
2484 2490 b=self.wrObj.Ctable(col1,col2,col3,col4,col5,col6,col7,col8,col9)
2485 2491 self.wrObj.CFile(a,b)
2486 2492 self.wrObj.wFile(filename)
2487 2493 return 1
2488 2494
2489 2495 class FITS:
2490 2496
2491 2497 name=None
2492 2498 format=None
2493 2499 array =None
2494 2500 data =None
2495 2501 thdulist=None
2496 2502
2497 2503 def __init__(self):
2498 2504
2499 2505 pass
2500 2506
2501 2507 def setColF(self,name,format,array):
2502 2508 self.name=name
2503 2509 self.format=format
2504 2510 self.array=array
2505 2511 a1=numpy.array([self.array],dtype=numpy.float32)
2506 2512 self.col1 = pyfits.Column(name=self.name, format=self.format, array=a1)
2507 2513 return self.col1
2508 2514
2509 2515 # def setColP(self,name,format,data):
2510 2516 # self.name=name
2511 2517 # self.format=format
2512 2518 # self.data=data
2513 2519 # a2=numpy.array([self.data],dtype=numpy.float32)
2514 2520 # self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2)
2515 2521 # return self.col2
2516 2522
2517 2523 def writeHeader(self,):
2518 2524 pass
2519 2525
2520 2526 def writeData(self,name,format,data):
2521 2527 self.name=name
2522 2528 self.format=format
2523 2529 self.data=data
2524 2530 a2=numpy.array([self.data],dtype=numpy.float32)
2525 2531 self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2)
2526 2532 return self.col2
2527 2533
2528 2534 def cFImage(self,n):
2529 2535 self.hdu= pyfits.PrimaryHDU(n)
2530 2536 return self.hdu
2531 2537
2532 2538 def Ctable(self,col1,col2,col3,col4,col5,col6,col7,col8,col9):
2533 2539 self.cols=pyfits.ColDefs( [col1,col2,col3,col4,col5,col6,col7,col8,col9])
2534 2540 self.tbhdu = pyfits.new_table(self.cols)
2535 2541 return self.tbhdu
2536 2542
2537 2543 def CFile(self,hdu,tbhdu):
2538 2544 self.thdulist=pyfits.HDUList([hdu,tbhdu])
2539 2545
2540 2546 def wFile(self,filename):
2541 2547 self.thdulist.writeto(filename) No newline at end of file
@@ -1,818 +1,818
1 1 import numpy
2 2 import time, datetime
3 3 from graphics.figure import *
4 4
5 5 class CrossSpectraPlot(Figure):
6 6
7 7 __isConfig = None
8 8 __nsubplots = None
9 9
10 10 WIDTHPROF = None
11 11 HEIGHTPROF = None
12 12 PREFIX = 'cspc'
13 13
14 14 def __init__(self):
15 15
16 16 self.__isConfig = False
17 17 self.__nsubplots = 4
18 18
19 19 self.WIDTH = 300
20 20 self.HEIGHT = 400
21 21 self.WIDTHPROF = 0
22 22 self.HEIGHTPROF = 0
23 23
24 24 def getSubplots(self):
25 25
26 26 ncol = 4
27 27 nrow = self.nplots
28 28
29 29 return nrow, ncol
30 30
31 31 def setup(self, idfigure, nplots, wintitle, showprofile=True):
32 32
33 33 self.__showprofile = showprofile
34 34 self.nplots = nplots
35 35
36 36 ncolspan = 1
37 37 colspan = 1
38 38
39 39 self.createFigure(idfigure = idfigure,
40 40 wintitle = wintitle,
41 41 widthplot = self.WIDTH + self.WIDTHPROF,
42 42 heightplot = self.HEIGHT + self.HEIGHTPROF)
43 43
44 44 nrow, ncol = self.getSubplots()
45 45
46 46 counter = 0
47 47 for y in range(nrow):
48 48 for x in range(ncol):
49 49 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
50 50
51 51 counter += 1
52 52
53 53 def run(self, dataOut, idfigure, wintitle="", pairsList=None, showprofile='True',
54 54 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
55 55 save=False, figpath='./', figfile=None):
56 56
57 57 """
58 58
59 59 Input:
60 60 dataOut :
61 61 idfigure :
62 62 wintitle :
63 63 channelList :
64 64 showProfile :
65 65 xmin : None,
66 66 xmax : None,
67 67 ymin : None,
68 68 ymax : None,
69 69 zmin : None,
70 70 zmax : None
71 71 """
72 72
73 73 if pairsList == None:
74 74 pairsIndexList = dataOut.pairsIndexList
75 75 else:
76 76 pairsIndexList = []
77 77 for pair in pairsList:
78 78 if pair not in dataOut.pairsList:
79 79 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
80 80 pairsIndexList.append(dataOut.pairsList.index(pair))
81 81
82 82 if pairsIndexList == []:
83 83 return
84 84
85 85 if len(pairsIndexList) > 4:
86 86 pairsIndexList = pairsIndexList[0:4]
87 87
88 88 x = dataOut.getFreqRange(1)
89 89 y = dataOut.getHeiRange()
90 90 z = 10.*numpy.log10(dataOut.data_spc[:,:,:])
91 91 avg = numpy.average(numpy.abs(z), axis=1)
92 92
93 93 noise = dataOut.getNoise()
94 94
95 95 if not self.__isConfig:
96 96
97 97 nplots = len(pairsIndexList)
98 98
99 99 self.setup(idfigure=idfigure,
100 100 nplots=nplots,
101 101 wintitle=wintitle,
102 102 showprofile=showprofile)
103 103
104 104 if xmin == None: xmin = numpy.nanmin(x)
105 105 if xmax == None: xmax = numpy.nanmax(x)
106 106 if ymin == None: ymin = numpy.nanmin(y)
107 107 if ymax == None: ymax = numpy.nanmax(y)
108 108 if zmin == None: zmin = numpy.nanmin(avg)*0.9
109 109 if zmax == None: zmax = numpy.nanmax(avg)*0.9
110 110
111 111 self.__isConfig = True
112 112
113 113 thisDatetime = dataOut.datatime
114 114 title = "Cross-Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
115 115 xlabel = "Velocity (m/s)"
116 116 ylabel = "Range (Km)"
117 117
118 118 self.setWinTitle(title)
119 119
120 120 for i in range(self.nplots):
121 121 pair = dataOut.pairsList[pairsIndexList[i]]
122 122
123 123 title = "Channel %d: %4.2fdB" %(pair[0], noise[pair[0]])
124 124 z = 10.*numpy.log10(dataOut.data_spc[pair[0],:,:])
125 125 axes0 = self.axesList[i*self.__nsubplots]
126 126 axes0.pcolor(x, y, z,
127 127 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
128 128 xlabel=xlabel, ylabel=ylabel, title=title,
129 129 ticksize=9, cblabel='')
130 130
131 131 title = "Channel %d: %4.2fdB" %(pair[1], noise[pair[1]])
132 132 z = 10.*numpy.log10(dataOut.data_spc[pair[1],:,:])
133 133 axes0 = self.axesList[i*self.__nsubplots+1]
134 134 axes0.pcolor(x, y, z,
135 135 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
136 136 xlabel=xlabel, ylabel=ylabel, title=title,
137 137 ticksize=9, cblabel='')
138 138
139 139 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[pair[0],:,:]*dataOut.data_spc[pair[1],:,:])
140 140 coherence = numpy.abs(coherenceComplex)
141 141 phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
142 142
143 143
144 144 title = "Coherence %d%d" %(pair[0], pair[1])
145 145 axes0 = self.axesList[i*self.__nsubplots+2]
146 146 axes0.pcolor(x, y, coherence,
147 147 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=0, zmax=1,
148 148 xlabel=xlabel, ylabel=ylabel, title=title,
149 149 ticksize=9, cblabel='')
150 150
151 151 title = "Phase %d%d" %(pair[0], pair[1])
152 152 axes0 = self.axesList[i*self.__nsubplots+3]
153 153 axes0.pcolor(x, y, phase,
154 154 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=-180, zmax=180,
155 155 xlabel=xlabel, ylabel=ylabel, title=title,
156 156 ticksize=9, cblabel='', colormap='RdBu')
157 157
158 158
159 159
160 160 self.draw()
161 161
162 162 if save:
163 163 date = thisDatetime.strftime("%Y%m%d")
164 164 if figfile == None:
165 165 figfile = self.getFilename(name = date)
166 166
167 167 self.saveFigure(figpath, figfile)
168 168
169 169
170 170 class RTIPlot(Figure):
171 171
172 172 __isConfig = None
173 173 __nsubplots = None
174 174
175 175 WIDTHPROF = None
176 176 HEIGHTPROF = None
177 177 PREFIX = 'rti'
178 178
179 179 def __init__(self):
180 180
181 self.__timerange = 24*60*60
181 self.timerange = 24*60*60
182 182 self.__isConfig = False
183 183 self.__nsubplots = 1
184 184
185 185 self.WIDTH = 800
186 186 self.HEIGHT = 200
187 187 self.WIDTHPROF = 120
188 188 self.HEIGHTPROF = 0
189 189
190 190 def getSubplots(self):
191 191
192 192 ncol = 1
193 193 nrow = self.nplots
194 194
195 195 return nrow, ncol
196 196
197 197 def setup(self, idfigure, nplots, wintitle, showprofile=True):
198 198
199 199 self.__showprofile = showprofile
200 200 self.nplots = nplots
201 201
202 202 ncolspan = 1
203 203 colspan = 1
204 204 if showprofile:
205 205 ncolspan = 7
206 206 colspan = 6
207 207 self.__nsubplots = 2
208 208
209 209 self.createFigure(idfigure = idfigure,
210 210 wintitle = wintitle,
211 211 widthplot = self.WIDTH + self.WIDTHPROF,
212 212 heightplot = self.HEIGHT + self.HEIGHTPROF)
213 213
214 214 nrow, ncol = self.getSubplots()
215 215
216 216 counter = 0
217 217 for y in range(nrow):
218 218 for x in range(ncol):
219 219
220 220 if counter >= self.nplots:
221 221 break
222 222
223 223 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
224 224
225 225 if showprofile:
226 226 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
227 227
228 228 counter += 1
229 229
230 230 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
231 231 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
232 232 timerange=None,
233 233 save=False, figpath='./', figfile=None):
234 234
235 235 """
236 236
237 237 Input:
238 238 dataOut :
239 239 idfigure :
240 240 wintitle :
241 241 channelList :
242 242 showProfile :
243 243 xmin : None,
244 244 xmax : None,
245 245 ymin : None,
246 246 ymax : None,
247 247 zmin : None,
248 248 zmax : None
249 249 """
250 250
251 251 if channelList == None:
252 252 channelIndexList = dataOut.channelIndexList
253 253 else:
254 254 channelIndexList = []
255 255 for channel in channelList:
256 256 if channel not in dataOut.channelList:
257 257 raise ValueError, "Channel %d is not in dataOut.channelList"
258 258 channelIndexList.append(dataOut.channelList.index(channel))
259 259
260 260 if timerange != None:
261 self.__timerange = timerange
261 self.timerange = timerange
262 262
263 263 tmin = None
264 264 tmax = None
265 265 x = dataOut.getTimeRange()
266 266 y = dataOut.getHeiRange()
267 267 z = 10.*numpy.log10(dataOut.data_spc[channelIndexList,:,:])
268 268 avg = numpy.average(z, axis=1)
269 269
270 270 noise = dataOut.getNoise()
271 271
272 272 if not self.__isConfig:
273 273
274 274 nplots = len(channelIndexList)
275 275
276 276 self.setup(idfigure=idfigure,
277 277 nplots=nplots,
278 278 wintitle=wintitle,
279 279 showprofile=showprofile)
280 280
281 281 tmin, tmax = self.getTimeLim(x, xmin, xmax)
282 282 if ymin == None: ymin = numpy.nanmin(y)
283 283 if ymax == None: ymax = numpy.nanmax(y)
284 284 if zmin == None: zmin = numpy.nanmin(avg)*0.9
285 285 if zmax == None: zmax = numpy.nanmax(avg)*0.9
286 286
287 287 self.__isConfig = True
288 288
289 289 thisDatetime = dataOut.datatime
290 290 title = "RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
291 291 xlabel = "Velocity (m/s)"
292 292 ylabel = "Range (Km)"
293 293
294 294 self.setWinTitle(title)
295 295
296 296 for i in range(self.nplots):
297 297 title = "Channel %d: %s" %(dataOut.channelList[i], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
298 298 axes = self.axesList[i*self.__nsubplots]
299 299 z = avg[i].reshape((1,-1))
300 300 axes.pcolor(x, y, z,
301 301 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
302 302 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
303 303 ticksize=9, cblabel='', cbsize="1%")
304 304
305 305 if self.__showprofile:
306 306 axes = self.axesList[i*self.__nsubplots +1]
307 307 axes.pline(avg[i], y,
308 308 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
309 309 xlabel='dB', ylabel='', title='',
310 310 ytick_visible=False,
311 311 grid='x')
312 312
313 313 self.draw()
314 314
315 315 if save:
316 316 date = thisDatetime.strftime("%Y%m%d")
317 317 if figfile == None:
318 318 figfile = self.getFilename(name = date)
319 319
320 320 self.saveFigure(figpath, figfile)
321 321
322 322 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
323 323 self.__isConfig = False
324 324
325 325 class SpectraPlot(Figure):
326 326
327 327 __isConfig = None
328 328 __nsubplots = None
329 329
330 330 WIDTHPROF = None
331 331 HEIGHTPROF = None
332 332 PREFIX = 'spc'
333 333
334 334 def __init__(self):
335 335
336 336 self.__isConfig = False
337 337 self.__nsubplots = 1
338 338
339 339 self.WIDTH = 300
340 340 self.HEIGHT = 400
341 341 self.WIDTHPROF = 120
342 342 self.HEIGHTPROF = 0
343 343
344 344 def getSubplots(self):
345 345
346 346 ncol = int(numpy.sqrt(self.nplots)+0.9)
347 347 nrow = int(self.nplots*1./ncol + 0.9)
348 348
349 349 return nrow, ncol
350 350
351 351 def setup(self, idfigure, nplots, wintitle, showprofile=True):
352 352
353 353 self.__showprofile = showprofile
354 354 self.nplots = nplots
355 355
356 356 ncolspan = 1
357 357 colspan = 1
358 358 if showprofile:
359 359 ncolspan = 3
360 360 colspan = 2
361 361 self.__nsubplots = 2
362 362
363 363 self.createFigure(idfigure = idfigure,
364 364 wintitle = wintitle,
365 365 widthplot = self.WIDTH + self.WIDTHPROF,
366 366 heightplot = self.HEIGHT + self.HEIGHTPROF)
367 367
368 368 nrow, ncol = self.getSubplots()
369 369
370 370 counter = 0
371 371 for y in range(nrow):
372 372 for x in range(ncol):
373 373
374 374 if counter >= self.nplots:
375 375 break
376 376
377 377 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
378 378
379 379 if showprofile:
380 380 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
381 381
382 382 counter += 1
383 383
384 384 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
385 385 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
386 386 save=False, figpath='./', figfile=None):
387 387
388 388 """
389 389
390 390 Input:
391 391 dataOut :
392 392 idfigure :
393 393 wintitle :
394 394 channelList :
395 395 showProfile :
396 396 xmin : None,
397 397 xmax : None,
398 398 ymin : None,
399 399 ymax : None,
400 400 zmin : None,
401 401 zmax : None
402 402 """
403 403
404 404 if channelList == None:
405 405 channelIndexList = dataOut.channelIndexList
406 406 else:
407 407 channelIndexList = []
408 408 for channel in channelList:
409 409 if channel not in dataOut.channelList:
410 410 raise ValueError, "Channel %d is not in dataOut.channelList"
411 411 channelIndexList.append(dataOut.channelList.index(channel))
412 412
413 413 x = dataOut.getVelRange(1)
414 414 y = dataOut.getHeiRange()
415 415 z = 10.*numpy.log10(dataOut.data_spc[channelIndexList,:,:])
416 416 avg = numpy.average(z, axis=1)
417 417
418 418 noise = dataOut.getNoise()
419 419
420 420 if not self.__isConfig:
421 421
422 422 nplots = len(channelIndexList)
423 423
424 424 self.setup(idfigure=idfigure,
425 425 nplots=nplots,
426 426 wintitle=wintitle,
427 427 showprofile=showprofile)
428 428
429 429 if xmin == None: xmin = numpy.nanmin(x)
430 430 if xmax == None: xmax = numpy.nanmax(x)
431 431 if ymin == None: ymin = numpy.nanmin(y)
432 432 if ymax == None: ymax = numpy.nanmax(y)
433 433 if zmin == None: zmin = numpy.nanmin(avg)*0.9
434 434 if zmax == None: zmax = numpy.nanmax(avg)*0.9
435 435
436 436 self.__isConfig = True
437 437
438 438 thisDatetime = dataOut.datatime
439 439 title = "Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
440 440 xlabel = "Velocity (m/s)"
441 441 ylabel = "Range (Km)"
442 442
443 443 self.setWinTitle(title)
444 444
445 445 for i in range(self.nplots):
446 446 title = "Channel %d: %4.2fdB" %(dataOut.channelList[i], noise[i])
447 447 axes = self.axesList[i*self.__nsubplots]
448 448 axes.pcolor(x, y, z[i,:,:],
449 449 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
450 450 xlabel=xlabel, ylabel=ylabel, title=title,
451 451 ticksize=9, cblabel='')
452 452
453 453 if self.__showprofile:
454 454 axes = self.axesList[i*self.__nsubplots +1]
455 455 axes.pline(avg[i], y,
456 456 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
457 457 xlabel='dB', ylabel='', title='',
458 458 ytick_visible=False,
459 459 grid='x')
460 460
461 461 self.draw()
462 462
463 463 if save:
464 464 date = thisDatetime.strftime("%Y%m%d")
465 465 if figfile == None:
466 466 figfile = self.getFilename(name = date)
467 467
468 468 self.saveFigure(figpath, figfile)
469 469
470 470 class Scope(Figure):
471 471
472 472 __isConfig = None
473 473
474 474 def __init__(self):
475 475
476 476 self.__isConfig = False
477 477 self.WIDTH = 600
478 478 self.HEIGHT = 200
479 479
480 480 def getSubplots(self):
481 481
482 482 nrow = self.nplots
483 483 ncol = 3
484 484 return nrow, ncol
485 485
486 486 def setup(self, idfigure, nplots, wintitle):
487 487
488 488 self.createFigure(idfigure, wintitle)
489 489
490 490 nrow,ncol = self.getSubplots()
491 491 colspan = 3
492 492 rowspan = 1
493 493
494 494 for i in range(nplots):
495 495 self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
496 496
497 497 self.nplots = nplots
498 498
499 499 def run(self, dataOut, idfigure, wintitle="", channelList=None,
500 500 xmin=None, xmax=None, ymin=None, ymax=None, save=False, filename=None):
501 501
502 502 """
503 503
504 504 Input:
505 505 dataOut :
506 506 idfigure :
507 507 wintitle :
508 508 channelList :
509 509 xmin : None,
510 510 xmax : None,
511 511 ymin : None,
512 512 ymax : None,
513 513 """
514 514
515 515 if channelList == None:
516 516 channelIndexList = dataOut.channelIndexList
517 517 else:
518 518 channelIndexList = []
519 519 for channel in channelList:
520 520 if channel not in dataOut.channelList:
521 521 raise ValueError, "Channel %d is not in dataOut.channelList"
522 522 channelIndexList.append(dataOut.channelList.index(channel))
523 523
524 524 x = dataOut.heightList
525 525 y = dataOut.data[channelList,:] * numpy.conjugate(dataOut.data[channelList,:])
526 526 y = y.real
527 527
528 528 noise = dataOut.getNoise()
529 529
530 530 if not self.__isConfig:
531 531 nplots = len(channelList)
532 532
533 533 self.setup(idfigure=idfigure,
534 534 nplots=nplots,
535 535 wintitle=wintitle)
536 536
537 537 if xmin == None: xmin = numpy.nanmin(x)
538 538 if xmax == None: xmax = numpy.nanmax(x)
539 539 if ymin == None: ymin = numpy.nanmin(y)
540 540 if ymax == None: ymax = numpy.nanmax(y)
541 541
542 542 self.__isConfig = True
543 543
544 544
545 545 thisDatetime = dataOut.datatime
546 546 title = "Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
547 547 xlabel = "Range (Km)"
548 548 ylabel = "Intensity"
549 549
550 550 self.setWinTitle(title)
551 551
552 552 for i in range(len(self.axesList)):
553 553 title = "Channel %d: %4.2fdB" %(i, noise[i])
554 554 axes = self.axesList[i]
555 555 ychannel = y[i,:]
556 556 axes.pline(x, ychannel,
557 557 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
558 558 xlabel=xlabel, ylabel=ylabel, title=title)
559 559
560 560 self.draw()
561 561
562 562 if save:
563 563 self.saveFigure(filename)
564 564
565 565 class ProfilePlot(Figure):
566 566 __isConfig = None
567 567 __nsubplots = None
568 568
569 569 WIDTHPROF = None
570 570 HEIGHTPROF = None
571 571 PREFIX = 'spcprofile'
572 572
573 573 def __init__(self):
574 574 self.__isConfig = False
575 575 self.__nsubplots = 1
576 576
577 577 self.WIDTH = 300
578 578 self.HEIGHT = 500
579 579
580 580 def getSubplots(self):
581 581 ncol = 1
582 582 nrow = 1
583 583
584 584 return nrow, ncol
585 585
586 586 def setup(self, idfigure, nplots, wintitle):
587 587
588 588 self.nplots = nplots
589 589
590 590 ncolspan = 1
591 591 colspan = 1
592 592
593 593 self.createFigure(idfigure = idfigure,
594 594 wintitle = wintitle,
595 595 widthplot = self.WIDTH,
596 596 heightplot = self.HEIGHT)
597 597
598 598 nrow, ncol = self.getSubplots()
599 599
600 600 counter = 0
601 601 for y in range(nrow):
602 602 for x in range(ncol):
603 603 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
604 604
605 605 def run(self, dataOut, idfigure, wintitle="", channelList=None,
606 606 xmin=None, xmax=None, ymin=None, ymax=None,
607 607 save=False, figpath='./', figfile=None):
608 608
609 609 if channelList == None:
610 610 channelIndexList = dataOut.channelIndexList
611 611 channelList = dataOut.channelList
612 612 else:
613 613 channelIndexList = []
614 614 for channel in channelList:
615 615 if channel not in dataOut.channelList:
616 616 raise ValueError, "Channel %d is not in dataOut.channelList"
617 617 channelIndexList.append(dataOut.channelList.index(channel))
618 618
619 619
620 620 y = dataOut.getHeiRange()
621 621 x = 10.*numpy.log10(dataOut.data_spc[channelIndexList,:,:])
622 622 avg = numpy.average(x, axis=1)
623 623
624 624
625 625 if not self.__isConfig:
626 626
627 627 nplots = 1
628 628
629 629 self.setup(idfigure=idfigure,
630 630 nplots=nplots,
631 631 wintitle=wintitle)
632 632
633 633 if ymin == None: ymin = numpy.nanmin(y)
634 634 if ymax == None: ymax = numpy.nanmax(y)
635 635 if xmin == None: xmin = numpy.nanmin(avg)*0.9
636 636 if xmax == None: xmax = numpy.nanmax(avg)*0.9
637 637
638 638 self.__isConfig = True
639 639
640 640 thisDatetime = dataOut.datatime
641 641 title = "Power Profile"
642 642 xlabel = "dB"
643 643 ylabel = "Range (Km)"
644 644
645 645 self.setWinTitle(title)
646 646
647 647
648 648 title = "Power Profile: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
649 649 axes = self.axesList[0]
650 650
651 651 legendlabels = ["channel %d"%x for x in channelList]
652 652 axes.pmultiline(avg, y,
653 653 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
654 654 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
655 655 ytick_visible=True, nxticks=5,
656 656 grid='x')
657 657
658 658 self.draw()
659 659
660 660 if save:
661 661 date = thisDatetime.strftime("%Y%m%d")
662 662 if figfile == None:
663 663 figfile = self.getFilename(name = date)
664 664
665 665 self.saveFigure(figpath, figfile)
666 666
667 667 class CoherencePlot(Figure):
668 668 __isConfig = None
669 669 __nsubplots = None
670 670
671 671 WIDTHPROF = None
672 672 HEIGHTPROF = None
673 673 PREFIX = 'coherencemap'
674 674
675 675 def __init__(self):
676 self.__timerange = 24*60*60
676 self.timerange = 24*60*60
677 677 self.__isConfig = False
678 678 self.__nsubplots = 1
679 679
680 680 self.WIDTH = 800
681 681 self.HEIGHT = 200
682 682 self.WIDTHPROF = 120
683 683 self.HEIGHTPROF = 0
684 684
685 685 def getSubplots(self):
686 686 ncol = 1
687 687 nrow = self.nplots*2
688 688
689 689 return nrow, ncol
690 690
691 691 def setup(self, idfigure, nplots, wintitle, showprofile=True):
692 692 self.__showprofile = showprofile
693 693 self.nplots = nplots
694 694
695 695 ncolspan = 1
696 696 colspan = 1
697 697 if showprofile:
698 698 ncolspan = 7
699 699 colspan = 6
700 700 self.__nsubplots = 2
701 701
702 702 self.createFigure(idfigure = idfigure,
703 703 wintitle = wintitle,
704 704 widthplot = self.WIDTH + self.WIDTHPROF,
705 705 heightplot = self.HEIGHT + self.HEIGHTPROF)
706 706
707 707 nrow, ncol = self.getSubplots()
708 708
709 709 for y in range(nrow):
710 710 for x in range(ncol):
711 711
712 712 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
713 713
714 714 if showprofile:
715 715 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
716 716
717 717 def run(self, dataOut, idfigure, wintitle="", pairsList=None, showprofile='True',
718 718 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
719 719 timerange=None,
720 720 save=False, figpath='./', figfile=None):
721 721
722 722 if pairsList == None:
723 723 pairsIndexList = dataOut.pairsIndexList
724 724 else:
725 725 pairsIndexList = []
726 726 for pair in pairsList:
727 727 if pair not in dataOut.pairsList:
728 728 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
729 729 pairsIndexList.append(dataOut.pairsList.index(pair))
730 730
731 731 if timerange != None:
732 self.__timerange = timerange
732 self.timerange = timerange
733 733
734 734 tmin = None
735 735 tmax = None
736 736 x = dataOut.getTimeRange()
737 737 y = dataOut.getHeiRange()
738 738
739 739 if not self.__isConfig:
740 740 nplots = len(pairsIndexList)
741 741 self.setup(idfigure=idfigure,
742 742 nplots=nplots,
743 743 wintitle=wintitle,
744 744 showprofile=showprofile)
745 745
746 746 tmin, tmax = self.getTimeLim(x, xmin, xmax)
747 747 if ymin == None: ymin = numpy.nanmin(y)
748 748 if ymax == None: ymax = numpy.nanmax(y)
749 749
750 750 self.__isConfig = True
751 751
752 752 thisDatetime = dataOut.datatime
753 753 title = "CoherenceMap: %s" %(thisDatetime.strftime("%d-%b-%Y"))
754 754 xlabel = ""
755 755 ylabel = "Range (Km)"
756 756
757 757 self.setWinTitle(title)
758 758
759 759 for i in range(self.nplots):
760 760
761 761 pair = dataOut.pairsList[pairsIndexList[i]]
762 762 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[pair[0],:,:]*dataOut.data_spc[pair[1],:,:])
763 763 coherence = numpy.abs(coherenceComplex)
764 764 avg = numpy.average(coherence, axis=0)
765 765 z = avg.reshape((1,-1))
766 766
767 767 counter = 0
768 768
769 769 title = "Coherence %d%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
770 770 axes = self.axesList[i*self.__nsubplots*2]
771 771 axes.pcolor(x, y, z,
772 772 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=0, zmax=1,
773 773 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
774 774 ticksize=9, cblabel='', cbsize="1%")
775 775
776 776 if self.__showprofile:
777 777 counter += 1
778 778 axes = self.axesList[i*self.__nsubplots*2 + counter]
779 779 axes.pline(avg, y,
780 780 xmin=0, xmax=1, ymin=ymin, ymax=ymax,
781 781 xlabel='', ylabel='', title='', ticksize=7,
782 782 ytick_visible=False, nxticks=5,
783 783 grid='x')
784 784
785 785 counter += 1
786 786 phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
787 787 avg = numpy.average(phase, axis=0)
788 788 z = avg.reshape((1,-1))
789 789
790 790 title = "Phase %d%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
791 791 axes = self.axesList[i*self.__nsubplots*2 + counter]
792 792 axes.pcolor(x, y, z,
793 793 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=-180, zmax=180,
794 794 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
795 795 ticksize=9, cblabel='', colormap='RdBu', cbsize="1%")
796 796
797 797 if self.__showprofile:
798 798 counter += 1
799 799 axes = self.axesList[i*self.__nsubplots*2 + counter]
800 800 axes.pline(avg, y,
801 801 xmin=-180, xmax=180, ymin=ymin, ymax=ymax,
802 802 xlabel='', ylabel='', title='', ticksize=7,
803 803 ytick_visible=False, nxticks=4,
804 804 grid='x')
805 805
806 806 self.draw()
807 807
808 808 if save:
809 809 date = thisDatetime.strftime("%Y%m%d")
810 810 if figfile == None:
811 811 figfile = self.getFilename(name = date)
812 812
813 813 self.saveFigure(figpath, figfile)
814 814
815 815 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
816 816 self.__isConfig = False
817 817
818 818 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now