##// END OF EJS Templates
Adicion del factor de normalizacion en la clase Spectra....
Daniel Valdez -
r245:0a5b40329524
parent child
Show More
@@ -1,396 +1,401
1 1 import os
2 2 import numpy
3 3 import time, datetime
4 4 import mpldriver
5 5
6 6
7 7 class Figure:
8 8
9 9 __driver = mpldriver
10 10 fig = None
11 11
12 12 idfigure = None
13 13 wintitle = None
14 14 width = None
15 15 height = None
16 16 nplots = None
17 17 timerange = None
18 18
19 19 axesObjList = []
20 20
21 21 WIDTH = None
22 22 HEIGHT = None
23 23 PREFIX = 'fig'
24 24
25 25 def __init__(self):
26 26
27 27 raise ValueError, "This method is not implemented"
28 28
29 29 def __del__(self):
30 30
31 31 self.__driver.closeFigure()
32 32
33 33 def getFilename(self, name, ext='.png'):
34 34
35 35 filename = '%s-%s_%s%s' %(self.wintitle[0:10], self.PREFIX, name, ext)
36 36
37 37 return filename
38 38
39 39 def getAxesObjList(self):
40 40
41 41 return self.axesObjList
42 42
43 43 def getSubplots(self):
44 44
45 45 raise ValueError, "Abstract method: This method should be defined"
46 46
47 47 def getScreenDim(self, widthplot, heightplot):
48 48
49 49 nrow, ncol = self.getSubplots()
50 50
51 51 widthscreen = widthplot*ncol
52 52 heightscreen = heightplot*nrow
53 53
54 54 return widthscreen, heightscreen
55 55
56 56 def getTimeLim(self, x, xmin, xmax):
57 57
58 58 thisdatetime = datetime.datetime.fromtimestamp(numpy.min(x))
59 59 thisdate = datetime.datetime.combine(thisdatetime.date(), datetime.time(0,0,0))
60 60
61 61 ####################################################
62 62 #If the x is out of xrange
63 63 if xmax < (thisdatetime - thisdate).seconds/(60*60.):
64 64 xmin = None
65 65 xmax = None
66 66
67 67 if xmin == None:
68 68 td = thisdatetime - thisdate
69 69 xmin = td.seconds/(60*60.)
70 70
71 71 if xmax == None:
72 72 xmax = xmin + self.timerange/(60*60.)
73 73
74 74 mindt = thisdate + datetime.timedelta(0,0,0,0,0, xmin)
75 75 tmin = time.mktime(mindt.timetuple())
76 76
77 77 maxdt = thisdate + datetime.timedelta(0,0,0,0,0, xmax)
78 78 tmax = time.mktime(maxdt.timetuple())
79 79
80 80 self.timerange = tmax - tmin
81 81
82 82 return tmin, tmax
83 83
84 84 def init(self, idfigure, nplots, wintitle):
85 85
86 86 raise ValueError, "This method has been replaced with createFigure"
87 87
88 88 def createFigure(self, idfigure, wintitle, widthplot=None, heightplot=None):
89 89
90 90 """
91 91 Crea la figura de acuerdo al driver y parametros seleccionados seleccionados.
92 92 Las dimensiones de la pantalla es calculada a partir de los atributos self.WIDTH
93 93 y self.HEIGHT y el numero de subplots (nrow, ncol)
94 94
95 95 Input:
96 96 idfigure : Los parametros necesarios son
97 97 wintitle :
98 98
99 99 """
100 100
101 101 if widthplot == None:
102 102 widthplot = self.WIDTH
103 103
104 104 if heightplot == None:
105 105 heightplot = self.HEIGHT
106 106
107 107 self.idfigure = idfigure
108 108
109 109 self.wintitle = wintitle
110 110
111 111 self.widthscreen, self.heightscreen = self.getScreenDim(widthplot, heightplot)
112 112
113 113 self.fig = self.__driver.createFigure(self.idfigure,
114 114 self.wintitle,
115 115 self.widthscreen,
116 116 self.heightscreen)
117 117
118 118 self.axesObjList = []
119 119
120 120 def setDriver(self, driver=mpldriver):
121 121
122 122 self.__driver = driver
123 123
124 124 def setTitle(self, title):
125 125
126 126 self.__driver.setTitle(self.fig, title)
127 127
128 128 def setWinTitle(self, title):
129 129
130 130 self.__driver.setWinTitle(self.fig, title=title)
131 131
132 132 def setTextFromAxes(self, text):
133 133
134 134 raise ValueError, "Este metodo ha sido reemplazaado con el metodo setText de la clase Axes"
135 135
136 136 def makeAxes(self, nrow, ncol, xpos, ypos, colspan, rowspan):
137 137
138 138 raise ValueError, "Este metodo ha sido reemplazaado con el metodo addAxes"
139 139
140 140 def addAxes(self, *args):
141 141 """
142 142
143 143 Input:
144 144 *args : Los parametros necesarios son
145 145 nrow, ncol, xpos, ypos, colspan, rowspan
146 146 """
147 147
148 148 axesObj = Axes(self.fig, *args)
149 149 self.axesObjList.append(axesObj)
150 150
151 151 def saveFigure(self, figpath, figfile, *args):
152 152
153 153 filename = os.path.join(figpath, figfile)
154 154 self.__driver.saveFigure(self.fig, filename, *args)
155 155
156 156 def draw(self):
157 157
158 158 self.__driver.draw(self.fig)
159 159
160 160 def run(self):
161 161
162 162 raise ValueError, "This method is not implemented"
163 163
164 164 axesList = property(getAxesObjList)
165 165
166 166
167 167 class Axes:
168 168
169 169 __driver = mpldriver
170 170 fig = None
171 171 ax = None
172 172 plot = None
173 173
174 174 __firsttime = None
175 175
176 176 __showprofile = False
177 177
178 178 xmin = None
179 179 xmax = None
180 180 ymin = None
181 181 ymax = None
182 182 zmin = None
183 183 zmax = None
184 184
185 185 def __init__(self, *args):
186 186
187 187 """
188 188
189 189 Input:
190 190 *args : Los parametros necesarios son
191 191 fig, nrow, ncol, xpos, ypos, colspan, rowspan
192 192 """
193 193
194 194 ax = self.__driver.createAxes(*args)
195 195 self.fig = args[0]
196 196 self.ax = ax
197 197 self.plot = None
198 198
199 199 self.__firsttime = True
200 200 self.idlineList = []
201 201
202 202 def setText(self, text):
203 203
204 204 self.__driver.setAxesText(self.ax, text)
205 205
206 206 def setXAxisAsTime(self):
207 207 pass
208 208
209 209 def pline(self, x, y,
210 210 xmin=None, xmax=None,
211 211 ymin=None, ymax=None,
212 212 xlabel='', ylabel='',
213 213 title='',
214 214 **kwargs):
215 215
216 216 """
217 217
218 218 Input:
219 219 x :
220 220 y :
221 221 xmin :
222 222 xmax :
223 223 ymin :
224 224 ymax :
225 225 xlabel :
226 226 ylabel :
227 227 title :
228 228 **kwargs : Los parametros aceptados son
229 229
230 230 ticksize
231 231 ytick_visible
232 232 """
233 233
234 234 if self.__firsttime:
235 235
236 236 if xmin == None: xmin = numpy.nanmin(x)
237 237 if xmax == None: xmax = numpy.nanmax(x)
238 238 if ymin == None: ymin = numpy.nanmin(y)
239 239 if ymax == None: ymax = numpy.nanmax(y)
240 240
241 241 self.plot = self.__driver.createPline(self.ax, x, y,
242 242 xmin, xmax,
243 243 ymin, ymax,
244 244 xlabel=xlabel,
245 245 ylabel=ylabel,
246 246 title=title,
247 247 **kwargs)
248 248
249 249 self.idlineList.append(0)
250 250 self.__firsttime = False
251 251 return
252 252
253 253 self.__driver.pline(self.plot, x, y, xlabel=xlabel,
254 254 ylabel=ylabel,
255 255 title=title)
256 256
257 257 def addpline(self, x, y, idline, **kwargs):
258 258 lines = self.ax.lines
259 259
260 260 if idline in self.idlineList:
261 261 self.__driver.set_linedata(self.ax, x, y, idline)
262 262
263 263 if idline not in(self.idlineList):
264 264 self.__driver.addpline(self.ax, x, y, **kwargs)
265 265 self.idlineList.append(idline)
266 266
267 267 return
268 268
269 269 def pmultiline(self, x, y,
270 270 xmin=None, xmax=None,
271 271 ymin=None, ymax=None,
272 272 xlabel='', ylabel='',
273 273 title='',
274 274 **kwargs):
275 275
276 276 if self.__firsttime:
277 277
278 278 if xmin == None: xmin = numpy.nanmin(x)
279 279 if xmax == None: xmax = numpy.nanmax(x)
280 280 if ymin == None: ymin = numpy.nanmin(y)
281 281 if ymax == None: ymax = numpy.nanmax(y)
282 282
283 283 self.plot = self.__driver.createPmultiline(self.ax, x, y,
284 284 xmin, xmax,
285 285 ymin, ymax,
286 286 xlabel=xlabel,
287 287 ylabel=ylabel,
288 288 title=title,
289 289 **kwargs)
290 290 self.__firsttime = False
291 291 return
292 292
293 293 self.__driver.pmultiline(self.plot, x, y, xlabel=xlabel,
294 294 ylabel=ylabel,
295 295 title=title)
296 296
297 297 def pmultilineyaxis(self, x, y,
298 298 xmin=None, xmax=None,
299 299 ymin=None, ymax=None,
300 300 xlabel='', ylabel='',
301 301 title='',
302 302 **kwargs):
303 303
304 304 if self.__firsttime:
305 305
306 306 if xmin == None: xmin = numpy.nanmin(x)
307 307 if xmax == None: xmax = numpy.nanmax(x)
308 308 if ymin == None: ymin = numpy.nanmin(y)
309 309 if ymax == None: ymax = numpy.nanmax(y)
310 310
311 311 self.plot = self.__driver.createPmultilineYAxis(self.ax, x, y,
312 312 xmin, xmax,
313 313 ymin, ymax,
314 314 xlabel=xlabel,
315 315 ylabel=ylabel,
316 316 title=title,
317 317 **kwargs)
318 if self.xmin == None: self.xmin = xmin
319 if self.xmax == None: self.xmax = xmax
320 if self.ymin == None: self.ymin = ymin
321 if self.ymax == None: self.ymax = ymax
322
318 323 self.__firsttime = False
319 324 return
320 325
321 326 self.__driver.pmultilineyaxis(self.plot, x, y, xlabel=xlabel,
322 327 ylabel=ylabel,
323 328 title=title)
324 329
325 330 def pcolor(self, x, y, z,
326 331 xmin=None, xmax=None,
327 332 ymin=None, ymax=None,
328 333 zmin=None, zmax=None,
329 334 xlabel='', ylabel='',
330 335 title='', rti = False, colormap='jet',
331 336 **kwargs):
332 337
333 338 """
334 339 Input:
335 340 x :
336 341 y :
337 342 x :
338 343 xmin :
339 344 xmax :
340 345 ymin :
341 346 ymax :
342 347 zmin :
343 348 zmax :
344 349 xlabel :
345 350 ylabel :
346 351 title :
347 352 **kwargs : Los parametros aceptados son
348 353 ticksize=9,
349 354 cblabel=''
350 355 rti = True or False
351 356 """
352 357
353 358 if self.__firsttime:
354 359
355 360 if xmin == None: xmin = numpy.nanmin(x)
356 361 if xmax == None: xmax = numpy.nanmax(x)
357 362 if ymin == None: ymin = numpy.nanmin(y)
358 363 if ymax == None: ymax = numpy.nanmax(y)
359 364 if zmin == None: zmin = numpy.nanmin(z)
360 365 if zmax == None: zmax = numpy.nanmax(z)
361 366
362 367
363 368 self.plot = self.__driver.createPcolor(self.ax, x, y, z,
364 369 xmin, xmax,
365 370 ymin, ymax,
366 371 zmin, zmax,
367 372 xlabel=xlabel,
368 373 ylabel=ylabel,
369 374 title=title,
370 375 colormap=colormap,
371 376 **kwargs)
372 377
373 378 if self.xmin == None: self.xmin = xmin
374 379 if self.xmax == None: self.xmax = xmax
375 380 if self.ymin == None: self.ymin = ymin
376 381 if self.ymax == None: self.ymax = ymax
377 382 if self.zmin == None: self.zmin = zmin
378 383 if self.zmax == None: self.zmax = zmax
379 384
380 385 self.__firsttime = False
381 386 return
382 387
383 388 if rti:
384 389 self.__driver.addpcolor(self.ax, x, y, z, self.zmin, self.zmax,
385 390 xlabel=xlabel,
386 391 ylabel=ylabel,
387 392 title=title,
388 393 colormap=colormap)
389 394 return
390 395
391 396 self.__driver.pcolor(self.plot, z,
392 397 xlabel=xlabel,
393 398 ylabel=ylabel,
394 399 title=title)
395 400
396 401 No newline at end of file
@@ -1,366 +1,370
1 1 import numpy
2 2 import datetime
3 import sys
3 4 import matplotlib
5 if sys.platform == 'linux':
4 6 matplotlib.use("GTKAgg")
7 if sys.platform == 'darwin':
8 matplotlib.use("TKAgg")
5 9 import matplotlib.pyplot
6 10 import matplotlib.dates
7 11 #import scitools.numpyutils
8 12 from mpl_toolkits.axes_grid1 import make_axes_locatable
9 13
10 14 from matplotlib.dates import DayLocator, HourLocator, MinuteLocator, SecondLocator, DateFormatter
11 15 from matplotlib.ticker import FuncFormatter
12 16 from matplotlib.ticker import *
13 17
14 18 ###########################################
15 19 #Actualizacion de las funciones del driver
16 20 ###########################################
17 21
18 22 def createFigure(idfigure, wintitle, width, height, facecolor="w"):
19 23
20 24 matplotlib.pyplot.ioff()
21 25 fig = matplotlib.pyplot.figure(num=idfigure, facecolor=facecolor)
22 26 fig.canvas.manager.set_window_title(wintitle)
23 27 fig.canvas.manager.resize(width, height)
24 28 matplotlib.pyplot.ion()
25 29 matplotlib.pyplot.show()
26 30
27 31 return fig
28 32
29 33 def closeFigure():
30 34
31 35 matplotlib.pyplot.ioff()
32 36 matplotlib.pyplot.show()
33 37
34 38 return
35 39
36 40 def saveFigure(fig, filename):
37 41
38 42 matplotlib.pyplot.ioff()
39 43 fig.savefig(filename)
40 44 matplotlib.pyplot.ion()
41 45
42 46 def setWinTitle(fig, title):
43 47
44 48 fig.canvas.manager.set_window_title(title)
45 49
46 50 def setTitle(fig, title):
47 51
48 52 fig.suptitle(title)
49 53
50 54 def createAxes(fig, nrow, ncol, xpos, ypos, colspan, rowspan):
51 55
52 56 matplotlib.pyplot.ioff()
53 57 matplotlib.pyplot.figure(fig.number)
54 58 axes = matplotlib.pyplot.subplot2grid((nrow, ncol),
55 59 (xpos, ypos),
56 60 colspan=colspan,
57 61 rowspan=rowspan)
58 62
59 63 matplotlib.pyplot.ion()
60 64 return axes
61 65
62 66 def setAxesText(ax, text):
63 67
64 68 ax.annotate(text,
65 69 xy = (.1, .99),
66 70 xycoords = 'figure fraction',
67 71 horizontalalignment = 'left',
68 72 verticalalignment = 'top',
69 73 fontsize = 10)
70 74
71 75 def printLabels(ax, xlabel, ylabel, title):
72 76
73 77 ax.set_xlabel(xlabel, size=11)
74 78 ax.set_ylabel(ylabel, size=11)
75 79 ax.set_title(title, size=12)
76 80
77 81 def createPline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='',
78 82 ticksize=9, xtick_visible=True, ytick_visible=True,
79 83 nxticks=4, nyticks=10,
80 84 grid=None):
81 85
82 86 """
83 87
84 88 Input:
85 89 grid : None, 'both', 'x', 'y'
86 90 """
87 91
88 92 matplotlib.pyplot.ioff()
89 93
90 94 ax.set_xlim([xmin,xmax])
91 95 ax.set_ylim([ymin,ymax])
92 96
93 97 printLabels(ax, xlabel, ylabel, title)
94 98
95 99 ######################################################
96 100 if (xmax-xmin)<=1:
97 101 xtickspos = numpy.linspace(xmin,xmax,nxticks)
98 102 xtickspos = numpy.array([float("%.1f"%i) for i in xtickspos])
99 103 ax.set_xticks(xtickspos)
100 104 else:
101 105 xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin)
102 106 ax.set_xticks(xtickspos)
103 107
104 108 for tick in ax.get_xticklabels():
105 109 tick.set_visible(xtick_visible)
106 110
107 111 for tick in ax.xaxis.get_major_ticks():
108 112 tick.label.set_fontsize(ticksize)
109 113
110 114 ######################################################
111 115 for tick in ax.get_yticklabels():
112 116 tick.set_visible(ytick_visible)
113 117
114 118 for tick in ax.yaxis.get_major_ticks():
115 119 tick.label.set_fontsize(ticksize)
116 120
117 121 ax.plot(x, y)
118 122 iplot = ax.lines[-1]
119 123
120 124 ######################################################
121 125 if '0.' in matplotlib.__version__[0:2]:
122 126 print "The matplotlib version has to be updated to 1.1 or newer"
123 127 return iplot
124 128
125 129 if '1.0.' in matplotlib.__version__[0:4]:
126 130 print "The matplotlib version has to be updated to 1.1 or newer"
127 131 return iplot
128 132
129 133 if grid != None:
130 134 ax.grid(b=True, which='major', axis=grid)
131 135
132 136 matplotlib.pyplot.tight_layout()
133 137
134 138 matplotlib.pyplot.ion()
135 139
136 140 return iplot
137 141
138 142 def set_linedata(ax, x, y, idline):
139 143
140 144 ax.lines[idline].set_data(x,y)
141 145
142 146 def pline(iplot, x, y, xlabel='', ylabel='', title=''):
143 147
144 148 ax = iplot.get_axes()
145 149
146 150 printLabels(ax, xlabel, ylabel, title)
147 151
148 152 set_linedata(ax, x, y, idline=0)
149 153
150 154 def addpline(ax, x, y, color, linestyle, lw):
151 155
152 156 ax.plot(x,y,color=color,linestyle=linestyle,lw=lw)
153 157
154 158
155 159 def createPcolor(ax, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax,
156 160 xlabel='', ylabel='', title='', ticksize = 9,
157 161 colormap='jet',cblabel='', cbsize="5%",
158 162 XAxisAsTime=False):
159 163
160 164 matplotlib.pyplot.ioff()
161 165
162 166 divider = make_axes_locatable(ax)
163 167 ax_cb = divider.new_horizontal(size=cbsize, pad=0.05)
164 168 fig = ax.get_figure()
165 169 fig.add_axes(ax_cb)
166 170
167 171 ax.set_xlim([xmin,xmax])
168 172 ax.set_ylim([ymin,ymax])
169 173
170 174 printLabels(ax, xlabel, ylabel, title)
171 175
172 176 imesh = ax.pcolormesh(x,y,z.T, vmin=zmin, vmax=zmax, cmap=matplotlib.pyplot.get_cmap(colormap))
173 177 cb = matplotlib.pyplot.colorbar(imesh, cax=ax_cb)
174 178 cb.set_label(cblabel)
175 179
176 180 # for tl in ax_cb.get_yticklabels():
177 181 # tl.set_visible(True)
178 182
179 183 for tick in ax.yaxis.get_major_ticks():
180 184 tick.label.set_fontsize(ticksize)
181 185
182 186 for tick in ax.xaxis.get_major_ticks():
183 187 tick.label.set_fontsize(ticksize)
184 188
185 189 for tick in cb.ax.get_yticklabels():
186 190 tick.set_fontsize(ticksize)
187 191
188 192 ax_cb.yaxis.tick_right()
189 193
190 194 if '0.' in matplotlib.__version__[0:2]:
191 195 print "The matplotlib version has to be updated to 1.1 or newer"
192 196 return imesh
193 197
194 198 if '1.0.' in matplotlib.__version__[0:4]:
195 199 print "The matplotlib version has to be updated to 1.1 or newer"
196 200 return imesh
197 201
198 202 matplotlib.pyplot.tight_layout()
199 203
200 204 if XAxisAsTime:
201 205
202 206 func = lambda x, pos: ('%s') %(datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S"))
203 207 ax.xaxis.set_major_formatter(FuncFormatter(func))
204 208 ax.xaxis.set_major_locator(LinearLocator(7))
205 209
206 210 matplotlib.pyplot.ion()
207 211 return imesh
208 212
209 213 def pcolor(imesh, z, xlabel='', ylabel='', title=''):
210 214
211 215 z = z.T
212 216
213 217 ax = imesh.get_axes()
214 218
215 219 printLabels(ax, xlabel, ylabel, title)
216 220
217 221 imesh.set_array(z.ravel())
218 222
219 223 def addpcolor(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', colormap='jet'):
220 224
221 225 printLabels(ax, xlabel, ylabel, title)
222 226
223 227 imesh = ax.pcolormesh(x,y,z.T,vmin=zmin,vmax=zmax, cmap=matplotlib.pyplot.get_cmap(colormap))
224 228
225 229 def createPmultiline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None,
226 230 ticksize=9, xtick_visible=True, ytick_visible=True,
227 231 nxticks=4, nyticks=10,
228 232 grid=None):
229 233
230 234 """
231 235
232 236 Input:
233 237 grid : None, 'both', 'x', 'y'
234 238 """
235 239
236 240 matplotlib.pyplot.ioff()
237 241
238 242 lines = ax.plot(x.T, y)
239 243 leg = ax.legend(lines, legendlabels, loc='upper right')
240 244 leg.get_frame().set_alpha(0.5)
241 245 ax.set_xlim([xmin,xmax])
242 246 ax.set_ylim([ymin,ymax])
243 247 printLabels(ax, xlabel, ylabel, title)
244 248
245 249 xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin)
246 250 ax.set_xticks(xtickspos)
247 251
248 252 for tick in ax.get_xticklabels():
249 253 tick.set_visible(xtick_visible)
250 254
251 255 for tick in ax.xaxis.get_major_ticks():
252 256 tick.label.set_fontsize(ticksize)
253 257
254 258 for tick in ax.get_yticklabels():
255 259 tick.set_visible(ytick_visible)
256 260
257 261 for tick in ax.yaxis.get_major_ticks():
258 262 tick.label.set_fontsize(ticksize)
259 263
260 264 iplot = ax.lines[-1]
261 265
262 266 if '0.' in matplotlib.__version__[0:2]:
263 267 print "The matplotlib version has to be updated to 1.1 or newer"
264 268 return iplot
265 269
266 270 if '1.0.' in matplotlib.__version__[0:4]:
267 271 print "The matplotlib version has to be updated to 1.1 or newer"
268 272 return iplot
269 273
270 274 if grid != None:
271 275 ax.grid(b=True, which='major', axis=grid)
272 276
273 277 matplotlib.pyplot.tight_layout()
274 278
275 279 matplotlib.pyplot.ion()
276 280
277 281 return iplot
278 282
279 283
280 284 def pmultiline(iplot, x, y, xlabel='', ylabel='', title=''):
281 285
282 286 ax = iplot.get_axes()
283 287
284 288 printLabels(ax, xlabel, ylabel, title)
285 289
286 290 for i in range(len(ax.lines)):
287 291 line = ax.lines[i]
288 292 line.set_data(x[i,:],y)
289 293
290 294 def createPmultilineYAxis(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None,
291 295 ticksize=9, xtick_visible=True, ytick_visible=True,
292 296 nxticks=4, nyticks=10, marker='^', markersize=8, linestyle="solid",
293 297 grid=None, XAxisAsTime=False):
294 298
295 299 """
296 300
297 301 Input:
298 302 grid : None, 'both', 'x', 'y'
299 303 """
300 304
301 305 matplotlib.pyplot.ioff()
302 306
303 307 lines = ax.plot(x, y.T, marker=marker,markersize=markersize,linestyle=linestyle)
304 308 leg = ax.legend(lines, legendlabels, bbox_to_anchor=(1.05, 1), loc='upper right', numpoints=1, handlelength=1.5, \
305 309 handletextpad=0.5, borderpad=0.2, labelspacing=0.2, borderaxespad=0.)
306 310
307 311 ax.set_xlim([xmin,xmax])
308 312 ax.set_ylim([ymin,ymax])
309 313 printLabels(ax, xlabel, ylabel, title)
310 314
311 315 # xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin)
312 316 # ax.set_xticks(xtickspos)
313 317
314 318 for tick in ax.get_xticklabels():
315 319 tick.set_visible(xtick_visible)
316 320
317 321 for tick in ax.xaxis.get_major_ticks():
318 322 tick.label.set_fontsize(ticksize)
319 323
320 324 for tick in ax.get_yticklabels():
321 325 tick.set_visible(ytick_visible)
322 326
323 327 for tick in ax.yaxis.get_major_ticks():
324 328 tick.label.set_fontsize(ticksize)
325 329
326 330 iplot = ax.lines[-1]
327 331
328 332 if '0.' in matplotlib.__version__[0:2]:
329 333 print "The matplotlib version has to be updated to 1.1 or newer"
330 334 return iplot
331 335
332 336 if '1.0.' in matplotlib.__version__[0:4]:
333 337 print "The matplotlib version has to be updated to 1.1 or newer"
334 338 return iplot
335 339
336 340 if grid != None:
337 341 ax.grid(b=True, which='major', axis=grid)
338 342
339 343 matplotlib.pyplot.tight_layout()
340 344
341 345 if XAxisAsTime:
342 346
343 347 func = lambda x, pos: ('%s') %(datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S"))
344 348 ax.xaxis.set_major_formatter(FuncFormatter(func))
345 349 ax.xaxis.set_major_locator(LinearLocator(7))
346 350
347 351 matplotlib.pyplot.ion()
348 352
349 353 return iplot
350 354
351 355 def pmultilineinyaxis(iplot, x, y, xlabel='', ylabel='', title=''):
352 356
353 357 ax = iplot.get_axes()
354 358
355 359 printLabels(ax, xlabel, ylabel, title)
356 360
357 361 for i in range(len(ax.lines)):
358 362 line = ax.lines[i]
359 363 line.set_data(x,y[i,:])
360 364
361 365 def draw(fig):
362 366
363 367 if type(fig) == 'int':
364 368 raise ValueError, "This parameter should be of tpye matplotlib figure"
365 369
366 370 fig.canvas.draw() No newline at end of file
@@ -1,525 +1,536
1 1 '''
2 2
3 3 $Author: murco $
4 4 $Id: JROData.py 173 2012-11-20 15:06:21Z murco $
5 5 '''
6 6
7 7 import os, sys
8 8 import copy
9 9 import numpy
10 10 import datetime
11 11
12 12 from jroheaderIO import SystemHeader, RadarControllerHeader
13 13
14 14 def hildebrand_sekhon(data, navg):
15 15 """
16 16 This method is for the objective determination of de noise level in Doppler spectra. This
17 17 implementation technique is based on the fact that the standard deviation of the spectral
18 18 densities is equal to the mean spectral density for white Gaussian noise
19 19
20 20 Inputs:
21 21 Data : heights
22 22 navg : numbers of averages
23 23
24 24 Return:
25 25 -1 : any error
26 26 anoise : noise's level
27 27 """
28 28
29 29 dataflat = data.copy().reshape(-1)
30 30 dataflat.sort()
31 31 npts = dataflat.size #numbers of points of the data
32 32 npts_noise = 0.2*npts
33 33
34 34 if npts < 32:
35 35 print "error in noise - requires at least 32 points"
36 36 return -1.0
37 37
38 38 dataflat2 = numpy.power(dataflat,2)
39 39
40 40 cs = numpy.cumsum(dataflat)
41 41 cs2 = numpy.cumsum(dataflat2)
42 42
43 43 # data sorted in ascending order
44 44 nmin = int((npts + 7.)/8)
45 45
46 46 for i in range(nmin, npts):
47 47 s = cs[i]
48 48 s2 = cs2[i]
49 49 p = s / float(i);
50 50 p2 = p**2;
51 51 q = s2 / float(i) - p2;
52 52 leftc = p2;
53 53 rightc = q * float(navg);
54 54 R2 = leftc/rightc
55 55
56 56 # Signal detect: R2 < 1 (R2 = leftc/rightc)
57 57 if R2 < 1:
58 58 npts_noise = i
59 59 break
60 60
61 61
62 62 anoise = numpy.average(dataflat[0:npts_noise])
63 63
64 64 return anoise;
65 65
66 66 def sorting_bruce(data, navg):
67 67
68 68 data = data.copy()
69 69
70 70 sortdata = numpy.sort(data)
71 71 lenOfData = len(data)
72 72 nums_min = lenOfData/10
73 73
74 74 if (lenOfData/10) > 0:
75 75 nums_min = lenOfData/10
76 76 else:
77 77 nums_min = 0
78 78
79 79 rtest = 1.0 + 1.0/navg
80 80
81 81 sum = 0.
82 82
83 83 sumq = 0.
84 84
85 85 j = 0
86 86
87 87 cont = 1
88 88
89 89 while((cont==1)and(j<lenOfData)):
90 90
91 91 sum += sortdata[j]
92 92
93 93 sumq += sortdata[j]**2
94 94
95 95 j += 1
96 96
97 97 if j > nums_min:
98 98 if ((sumq*j) <= (rtest*sum**2)):
99 99 lnoise = sum / j
100 100 else:
101 101 j = j - 1
102 102 sum = sum - sordata[j]
103 103 sumq = sumq - sordata[j]**2
104 104 cont = 0
105 105
106 106 if j == nums_min:
107 107 lnoise = sum /j
108 108
109 109 return lnoise
110 110
111 111 class JROData:
112 112
113 113 # m_BasicHeader = BasicHeader()
114 114 # m_ProcessingHeader = ProcessingHeader()
115 115
116 116 systemHeaderObj = SystemHeader()
117 117
118 118 radarControllerHeaderObj = RadarControllerHeader()
119 119
120 120 # data = None
121 121
122 122 type = None
123 123
124 124 dtype = None
125 125
126 126 # nChannels = None
127 127
128 128 # nHeights = None
129 129
130 130 nProfiles = None
131 131
132 132 heightList = None
133 133
134 134 channelList = None
135 135
136 136 flagNoData = True
137 137
138 138 flagTimeBlock = False
139 139
140 140 utctime = None
141 141
142 142 blocksize = None
143 143
144 144 nCode = None
145 145
146 146 nBaud = None
147 147
148 148 code = None
149 149
150 150 flagDecodeData = False #asumo q la data no esta decodificada
151 151
152 152 flagDeflipData = False #asumo q la data no esta sin flip
153 153
154 154 flagShiftFFT = False
155 155
156 156 ippSeconds = None
157 157
158 158 timeInterval = None
159 159
160 160 nCohInt = None
161 161
162 162 noise = None
163 163
164 windowOfFilter = 1
165
164 166 #Speed of ligth
165 167 C = 3e8
166 168
167 169 frequency = 49.92e6
168 170
169 171 def __init__(self):
170 172
171 173 raise ValueError, "This class has not been implemented"
172 174
173 175 def copy(self, inputObj=None):
174 176
175 177 if inputObj == None:
176 178 return copy.deepcopy(self)
177 179
178 180 for key in inputObj.__dict__.keys():
179 181 self.__dict__[key] = inputObj.__dict__[key]
180 182
181 183 def deepcopy(self):
182 184
183 185 return copy.deepcopy(self)
184 186
185 187 def isEmpty(self):
186 188
187 189 return self.flagNoData
188 190
189 191 def getNoise(self):
190 192
191 193 raise ValueError, "Not implemented"
192 194
193 195 def getNChannels(self):
194 196
195 197 return len(self.channelList)
196 198
197 199 def getChannelIndexList(self):
198 200
199 201 return range(self.nChannels)
200 202
201 203 def getNHeights(self):
202 204
203 205 return len(self.heightList)
204 206
205 207 def getHeiRange(self, extrapoints=0):
206 208
207 209 heis = self.heightList
208 210 # deltah = self.heightList[1] - self.heightList[0]
209 211 #
210 212 # heis.append(self.heightList[-1])
211 213
212 214 return heis
213 215
214 216 def getDatatime(self):
215 217
216 218 datatime = datetime.datetime.utcfromtimestamp(self.utctime)
217 219 return datatime
218 220
219 221 def getTimeRange(self):
220 222
221 223 datatime = []
222 224
223 225 datatime.append(self.utctime)
224 226 datatime.append(self.utctime + self.timeInterval)
225 227
226 228 datatime = numpy.array(datatime)
227 229
228 230 return datatime
229 231
230 232 def getFmax(self):
231 233
232 234 PRF = 1./(self.ippSeconds * self.nCohInt)
233 235
234 236 fmax = PRF/2.
235 237
236 238 return fmax
237 239
238 240 def getVmax(self):
239 241
240 242 _lambda = self.C/self.frequency
241 243
242 244 vmax = self.getFmax() * _lambda
243 245
244 246 return vmax
245 247
246 248 nChannels = property(getNChannels, "I'm the 'nChannel' property.")
247 249 channelIndexList = property(getChannelIndexList, "I'm the 'channelIndexList' property.")
248 250 nHeights = property(getNHeights, "I'm the 'nHeights' property.")
249 251 noise = property(getNoise, "I'm the 'nHeights' property.")
250 252 datatime = property(getDatatime, "I'm the 'datatime' property")
251 253
252 254 class Voltage(JROData):
253 255
254 256 #data es un numpy array de 2 dmensiones (canales, alturas)
255 257 data = None
256 258
257 259 def __init__(self):
258 260 '''
259 261 Constructor
260 262 '''
261 263
262 264 self.radarControllerHeaderObj = RadarControllerHeader()
263 265
264 266 self.systemHeaderObj = SystemHeader()
265 267
266 268 self.type = "Voltage"
267 269
268 270 self.data = None
269 271
270 272 self.dtype = None
271 273
272 274 # self.nChannels = 0
273 275
274 276 # self.nHeights = 0
275 277
276 278 self.nProfiles = None
277 279
278 280 self.heightList = None
279 281
280 282 self.channelList = None
281 283
282 284 # self.channelIndexList = None
283 285
284 286 self.flagNoData = True
285 287
286 288 self.flagTimeBlock = False
287 289
288 290 self.utctime = None
289 291
290 292 self.nCohInt = None
291 293
292 294 self.blocksize = None
293 295
294 296 self.flagDecodeData = False #asumo q la data no esta decodificada
295 297
296 298 self.flagDeflipData = False #asumo q la data no esta sin flip
297 299
298 300 self.flagShiftFFT = False
299 301
300 302
301 303 def getNoisebyHildebrand(self):
302 304 """
303 305 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
304 306
305 307 Return:
306 308 noiselevel
307 309 """
308 310
309 311 for channel in range(self.nChannels):
310 312 daux = self.data_spc[channel,:,:]
311 313 self.noise[channel] = hildebrand_sekhon(daux, self.nCohInt)
312 314
313 315 return self.noise
314 316
315 317 def getNoise(self, type = 1):
316 318
317 319 self.noise = numpy.zeros(self.nChannels)
318 320
319 321 if type == 1:
320 322 noise = self.getNoisebyHildebrand()
321 323
322 324 return 10*numpy.log10(noise)
323 325
324 326 class Spectra(JROData):
325 327
326 328 #data es un numpy array de 2 dmensiones (canales, perfiles, alturas)
327 329 data_spc = None
328 330
329 331 #data es un numpy array de 2 dmensiones (canales, pares, alturas)
330 332 data_cspc = None
331 333
332 334 #data es un numpy array de 2 dmensiones (canales, alturas)
333 335 data_dc = None
334 336
335 337 nFFTPoints = None
336 338
337 339 nPairs = None
338 340
339 341 pairsList = None
340 342
341 343 nIncohInt = None
342 344
343 345 wavelength = None #Necesario para cacular el rango de velocidad desde la frecuencia
344 346
345 347 nCohInt = None #se requiere para determinar el valor de timeInterval
346 348
347 349 def __init__(self):
348 350 '''
349 351 Constructor
350 352 '''
351 353
352 354 self.radarControllerHeaderObj = RadarControllerHeader()
353 355
354 356 self.systemHeaderObj = SystemHeader()
355 357
356 358 self.type = "Spectra"
357 359
358 360 # self.data = None
359 361
360 362 self.dtype = None
361 363
362 364 # self.nChannels = 0
363 365
364 366 # self.nHeights = 0
365 367
366 368 self.nProfiles = None
367 369
368 370 self.heightList = None
369 371
370 372 self.channelList = None
371 373
372 374 # self.channelIndexList = None
373 375
374 376 self.flagNoData = True
375 377
376 378 self.flagTimeBlock = False
377 379
378 380 self.utctime = None
379 381
380 382 self.nCohInt = None
381 383
382 384 self.nIncohInt = None
383 385
384 386 self.blocksize = None
385 387
386 388 self.nFFTPoints = None
387 389
388 390 self.wavelength = None
389 391
390 392 self.flagDecodeData = False #asumo q la data no esta decodificada
391 393
392 394 self.flagDeflipData = False #asumo q la data no esta sin flip
393 395
394 396 self.flagShiftFFT = False
395 397
396 398 def getNoisebyHildebrand(self):
397 399 """
398 400 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
399 401
400 402 Return:
401 403 noiselevel
402 404 """
403 405
404 406 for channel in range(self.nChannels):
405 407 daux = self.data_spc[channel,:,:]
406 408 self.noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
407 409
408 410 return self.noise
409 411
410 412 def getNoisebyWindow(self, heiIndexMin=0, heiIndexMax=-1, freqIndexMin=0, freqIndexMax=-1):
411 413 """
412 414 Determina el ruido del canal utilizando la ventana indicada con las coordenadas:
413 415 (heiIndexMIn, freqIndexMin) hasta (heiIndexMax, freqIndexMAx)
414 416
415 417 Inputs:
416 418 heiIndexMin: Limite inferior del eje de alturas
417 419 heiIndexMax: Limite superior del eje de alturas
418 420 freqIndexMin: Limite inferior del eje de frecuencia
419 421 freqIndexMax: Limite supoerior del eje de frecuencia
420 422 """
421 423
422 424 data = self.data_spc[:, heiIndexMin:heiIndexMax, freqIndexMin:freqIndexMax]
423 425
424 426 for channel in range(self.nChannels):
425 427 daux = data[channel,:,:]
426 428 self.noise[channel] = numpy.average(daux)
427 429
428 430 return self.noise
429 431
430 432 def getNoisebySort(self):
431 433
432 434 for channel in range(self.nChannels):
433 435 daux = self.data_spc[channel,:,:]
434 436 self.noise[channel] = sorting_bruce(daux, self.nIncohInt)
435 437
436 438 return self.noise
437 439
438 440 def getNoise(self, type = 1):
439 441
440 442 self.noise = numpy.zeros(self.nChannels)
441 443
442 444 if type == 1:
443 445 noise = self.getNoisebyHildebrand()
444 446
445 447 if type == 2:
446 448 noise = self.getNoisebySort()
447 449
448 450 if type == 3:
449 451 noise = self.getNoisebyWindow()
450 452
451 return 10*numpy.log10(noise)
453 return noise
452 454
453 455
454 456 def getFreqRange(self, extrapoints=0):
455 457
456 458 deltafreq = self.getFmax() / self.nFFTPoints
457 459 freqrange = deltafreq*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2
458 460
459 461 return freqrange
460 462
461 463 def getVelRange(self, extrapoints=0):
462 464
463 465 deltav = self.getVmax() / self.nFFTPoints
464 466 velrange = deltav*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltav/2
465 467
466 468 return velrange
467 469
468 470 def getNPairs(self):
469 471
470 472 return len(self.pairsList)
471 473
472 474 def getPairsIndexList(self):
473 475
474 476 return range(self.nPairs)
475 477
478 def getNormFactor(self):
479 pwcode = 1
480 if self.flagDecodeData:
481 pwcode = numpy.sum(self.code[0]**2)
482 normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*self.windowOfFilter*pwcode
483
484 return normFactor
485
476 486 nPairs = property(getNPairs, "I'm the 'nPairs' property.")
477 487 pairsIndexList = property(getPairsIndexList, "I'm the 'pairsIndexList' property.")
488 normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.")
478 489
479 490 class SpectraHeis(JROData):
480 491
481 492 data_spc = None
482 493
483 494 data_cspc = None
484 495
485 496 data_dc = None
486 497
487 498 nFFTPoints = None
488 499
489 500 nPairs = None
490 501
491 502 pairsList = None
492 503
493 504 nIncohInt = None
494 505
495 506 def __init__(self):
496 507
497 508 self.radarControllerHeaderObj = RadarControllerHeader()
498 509
499 510 self.systemHeaderObj = SystemHeader()
500 511
501 512 self.type = "SpectraHeis"
502 513
503 514 self.dtype = None
504 515
505 516 # self.nChannels = 0
506 517
507 518 # self.nHeights = 0
508 519
509 520 self.nProfiles = None
510 521
511 522 self.heightList = None
512 523
513 524 self.channelList = None
514 525
515 526 # self.channelIndexList = None
516 527
517 528 self.flagNoData = True
518 529
519 530 self.flagTimeBlock = False
520 531
521 532 self.nPairs = 0
522 533
523 534 self.utctime = None
524 535
525 536 self.blocksize = None
@@ -1,954 +1,986
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 WIDTH = None
11 11 HEIGHT = None
12 12 WIDTHPROF = None
13 13 HEIGHTPROF = None
14 14 PREFIX = 'cspc'
15 15
16 16 def __init__(self):
17 17
18 18 self.__isConfig = False
19 19 self.__nsubplots = 4
20 20
21 21 self.WIDTH = 250
22 22 self.HEIGHT = 250
23 23 self.WIDTHPROF = 0
24 24 self.HEIGHTPROF = 0
25 25
26 26 def getSubplots(self):
27 27
28 28 ncol = 4
29 29 nrow = self.nplots
30 30
31 31 return nrow, ncol
32 32
33 33 def setup(self, idfigure, nplots, wintitle, showprofile=True):
34 34
35 35 self.__showprofile = showprofile
36 36 self.nplots = nplots
37 37
38 38 ncolspan = 1
39 39 colspan = 1
40 40
41 41 self.createFigure(idfigure = idfigure,
42 42 wintitle = wintitle,
43 43 widthplot = self.WIDTH + self.WIDTHPROF,
44 44 heightplot = self.HEIGHT + self.HEIGHTPROF)
45 45
46 46 nrow, ncol = self.getSubplots()
47 47
48 48 counter = 0
49 49 for y in range(nrow):
50 50 for x in range(ncol):
51 51 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
52 52
53 53 counter += 1
54 54
55 55 def run(self, dataOut, idfigure, wintitle="", pairsList=None, showprofile='True',
56 56 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
57 57 save=False, figpath='./', figfile=None):
58 58
59 59 """
60 60
61 61 Input:
62 62 dataOut :
63 63 idfigure :
64 64 wintitle :
65 65 channelList :
66 66 showProfile :
67 67 xmin : None,
68 68 xmax : None,
69 69 ymin : None,
70 70 ymax : None,
71 71 zmin : None,
72 72 zmax : None
73 73 """
74 74
75 75 if pairsList == None:
76 76 pairsIndexList = dataOut.pairsIndexList
77 77 else:
78 78 pairsIndexList = []
79 79 for pair in pairsList:
80 80 if pair not in dataOut.pairsList:
81 81 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
82 82 pairsIndexList.append(dataOut.pairsList.index(pair))
83 83
84 84 if pairsIndexList == []:
85 85 return
86 86
87 87 if len(pairsIndexList) > 4:
88 88 pairsIndexList = pairsIndexList[0:4]
89
89 factor = dataOut.normFactor
90 90 x = dataOut.getVelRange(1)
91 91 y = dataOut.getHeiRange()
92 z = 10.*numpy.log10(dataOut.data_spc[:,:,:])
92 z = dataOut.data_spc[:,:,:]/factor
93 93 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
94 94 avg = numpy.average(numpy.abs(z), axis=1)
95 noise = dataOut.getNoise()/factor
96
97 zdB = 10*numpy.log10(z)
98 avgdB = 10*numpy.log10(avg)
99 noisedB = 10*numpy.log10(noise)
95 100
96 noise = dataOut.getNoise()
97 101
98 102 thisDatetime = dataOut.datatime
99 103 title = "Cross-Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
100 104 xlabel = "Velocity (m/s)"
101 105 ylabel = "Range (Km)"
102 106
103 107 if not self.__isConfig:
104 108
105 109 nplots = len(pairsIndexList)
106 110
107 111 self.setup(idfigure=idfigure,
108 112 nplots=nplots,
109 113 wintitle=wintitle,
110 114 showprofile=showprofile)
111 115
112 116 if xmin == None: xmin = numpy.nanmin(x)
113 117 if xmax == None: xmax = numpy.nanmax(x)
114 118 if ymin == None: ymin = numpy.nanmin(y)
115 119 if ymax == None: ymax = numpy.nanmax(y)
116 if zmin == None: zmin = numpy.nanmin(avg)*0.9
117 if zmax == None: zmax = numpy.nanmax(avg)*0.9
120 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
121 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
118 122
119 123 self.__isConfig = True
120 124
121 125 self.setWinTitle(title)
122 126
123 127 for i in range(self.nplots):
124 128 pair = dataOut.pairsList[pairsIndexList[i]]
125 129
126 title = "Channel %d: %4.2fdB" %(pair[0], noise[pair[0]])
127 z = 10.*numpy.log10(dataOut.data_spc[pair[0],:,:])
130 title = "Channel %d: %4.2fdB" %(pair[0], noisedB[pair[0]])
131 zdB = 10.*numpy.log10(dataOut.data_spc[pair[0],:,:]/factor)
128 132 axes0 = self.axesList[i*self.__nsubplots]
129 axes0.pcolor(x, y, z,
133 axes0.pcolor(x, y, zdB,
130 134 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
131 135 xlabel=xlabel, ylabel=ylabel, title=title,
132 136 ticksize=9, cblabel='')
133 137
134 title = "Channel %d: %4.2fdB" %(pair[1], noise[pair[1]])
135 z = 10.*numpy.log10(dataOut.data_spc[pair[1],:,:])
138 title = "Channel %d: %4.2fdB" %(pair[1], noisedB[pair[1]])
139 zdB = 10.*numpy.log10(dataOut.data_spc[pair[1],:,:]/factor)
136 140 axes0 = self.axesList[i*self.__nsubplots+1]
137 axes0.pcolor(x, y, z,
141 axes0.pcolor(x, y, zdB,
138 142 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
139 143 xlabel=xlabel, ylabel=ylabel, title=title,
140 144 ticksize=9, cblabel='')
141 145
142 146 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[pair[0],:,:]*dataOut.data_spc[pair[1],:,:])
143 147 coherence = numpy.abs(coherenceComplex)
144 148 phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
145 149
146 150
147 151 title = "Coherence %d%d" %(pair[0], pair[1])
148 152 axes0 = self.axesList[i*self.__nsubplots+2]
149 153 axes0.pcolor(x, y, coherence,
150 154 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=0, zmax=1,
151 155 xlabel=xlabel, ylabel=ylabel, title=title,
152 156 ticksize=9, cblabel='')
153 157
154 158 title = "Phase %d%d" %(pair[0], pair[1])
155 159 axes0 = self.axesList[i*self.__nsubplots+3]
156 160 axes0.pcolor(x, y, phase,
157 161 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=-180, zmax=180,
158 162 xlabel=xlabel, ylabel=ylabel, title=title,
159 163 ticksize=9, cblabel='', colormap='RdBu_r')
160 164
161 165
162 166
163 167 self.draw()
164 168
165 169 if save:
166 170 date = thisDatetime.strftime("%Y%m%d_%H%M%S")
167 171 if figfile == None:
168 172 figfile = self.getFilename(name = date)
169 173
170 174 self.saveFigure(figpath, figfile)
171 175
172 176
173 177 class RTIPlot(Figure):
174 178
175 179 __isConfig = None
176 180 __nsubplots = None
177 181
178 182 WIDTHPROF = None
179 183 HEIGHTPROF = None
180 184 PREFIX = 'rti'
181 185
182 186 def __init__(self):
183 187
184 188 self.timerange = 2*60*60
185 189 self.__isConfig = False
186 190 self.__nsubplots = 1
187 191
188 192 self.WIDTH = 800
189 193 self.HEIGHT = 200
190 194 self.WIDTHPROF = 120
191 195 self.HEIGHTPROF = 0
192 196
193 197 def getSubplots(self):
194 198
195 199 ncol = 1
196 200 nrow = self.nplots
197 201
198 202 return nrow, ncol
199 203
200 204 def setup(self, idfigure, nplots, wintitle, showprofile=True):
201 205
202 206 self.__showprofile = showprofile
203 207 self.nplots = nplots
204 208
205 209 ncolspan = 1
206 210 colspan = 1
207 211 if showprofile:
208 212 ncolspan = 7
209 213 colspan = 6
210 214 self.__nsubplots = 2
211 215
212 216 self.createFigure(idfigure = idfigure,
213 217 wintitle = wintitle,
214 218 widthplot = self.WIDTH + self.WIDTHPROF,
215 219 heightplot = self.HEIGHT + self.HEIGHTPROF)
216 220
217 221 nrow, ncol = self.getSubplots()
218 222
219 223 counter = 0
220 224 for y in range(nrow):
221 225 for x in range(ncol):
222 226
223 227 if counter >= self.nplots:
224 228 break
225 229
226 230 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
227 231
228 232 if showprofile:
229 233 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
230 234
231 235 counter += 1
232 236
233 237 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
234 238 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
235 239 timerange=None,
236 240 save=False, figpath='./', figfile=None):
237 241
238 242 """
239 243
240 244 Input:
241 245 dataOut :
242 246 idfigure :
243 247 wintitle :
244 248 channelList :
245 249 showProfile :
246 250 xmin : None,
247 251 xmax : None,
248 252 ymin : None,
249 253 ymax : None,
250 254 zmin : None,
251 255 zmax : None
252 256 """
253 257
254 258 if channelList == None:
255 259 channelIndexList = dataOut.channelIndexList
256 260 else:
257 261 channelIndexList = []
258 262 for channel in channelList:
259 263 if channel not in dataOut.channelList:
260 264 raise ValueError, "Channel %d is not in dataOut.channelList"
261 265 channelIndexList.append(dataOut.channelList.index(channel))
262 266
263 267 if timerange != None:
264 268 self.timerange = timerange
265 269
266 270 tmin = None
267 271 tmax = None
272 factor = dataOut.normFactor
268 273 x = dataOut.getTimeRange()
269 274 y = dataOut.getHeiRange()
270 z = 10.*numpy.log10(dataOut.data_spc[channelIndexList,:,:])
275
276 z = dataOut.data_spc[channelIndexList,:,:]/factor
271 277 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
272 278 avg = numpy.average(z, axis=1)
279 noise = dataOut.getNoise()/factor
273 280
274 noise = dataOut.getNoise()
281 # zdB = 10.*numpy.log10(z)
282 avgdB = 10.*numpy.log10(avg)
283 noisedB = 10.*numpy.log10(noise)
275 284
276 285 thisDatetime = dataOut.datatime
277 286 title = "RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
278 287 xlabel = "Velocity (m/s)"
279 288 ylabel = "Range (Km)"
280 289
281 290 if not self.__isConfig:
282 291
283 292 nplots = len(channelIndexList)
284 293
285 294 self.setup(idfigure=idfigure,
286 295 nplots=nplots,
287 296 wintitle=wintitle,
288 297 showprofile=showprofile)
289 298
290 299 tmin, tmax = self.getTimeLim(x, xmin, xmax)
291 300 if ymin == None: ymin = numpy.nanmin(y)
292 301 if ymax == None: ymax = numpy.nanmax(y)
293 if zmin == None: zmin = numpy.nanmin(avg)*0.9
294 if zmax == None: zmax = numpy.nanmax(avg)*0.9
302 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
303 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
295 304
296 305 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
297 306 self.__isConfig = True
298 307
299 308
300 309 self.setWinTitle(title)
301 310
302 311 for i in range(self.nplots):
303 312 title = "Channel %d: %s" %(dataOut.channelList[i], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
304 313 axes = self.axesList[i*self.__nsubplots]
305 z = avg[i].reshape((1,-1))
306 axes.pcolor(x, y, z,
314 zdB = avgdB[i].reshape((1,-1))
315 axes.pcolor(x, y, zdB,
307 316 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
308 317 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
309 318 ticksize=9, cblabel='', cbsize="1%")
310 319
311 320 if self.__showprofile:
312 321 axes = self.axesList[i*self.__nsubplots +1]
313 axes.pline(avg[i], y,
322 axes.pline(avgdB[i], y,
314 323 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
315 324 xlabel='dB', ylabel='', title='',
316 325 ytick_visible=False,
317 326 grid='x')
318 327
319 328 self.draw()
320 329
321 330 if save:
322 331
323 332 if figfile == None:
324 333 figfile = self.getFilename(name = self.name)
325 334
326 335 self.saveFigure(figpath, figfile)
327 336
328 337 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
329 338 self.__isConfig = False
330 339
331 340 class SpectraPlot(Figure):
332 341
333 342 __isConfig = None
334 343 __nsubplots = None
335 344
336 345 WIDTHPROF = None
337 346 HEIGHTPROF = None
338 347 PREFIX = 'spc'
339 348
340 349 def __init__(self):
341 350
342 351 self.__isConfig = False
343 352 self.__nsubplots = 1
344 353
345 354 self.WIDTH = 230
346 355 self.HEIGHT = 250
347 356 self.WIDTHPROF = 120
348 357 self.HEIGHTPROF = 0
349 358
350 359 def getSubplots(self):
351 360
352 361 ncol = int(numpy.sqrt(self.nplots)+0.9)
353 362 nrow = int(self.nplots*1./ncol + 0.9)
354 363
355 364 return nrow, ncol
356 365
357 366 def setup(self, idfigure, nplots, wintitle, showprofile=True):
358 367
359 368 self.__showprofile = showprofile
360 369 self.nplots = nplots
361 370
362 371 ncolspan = 1
363 372 colspan = 1
364 373 if showprofile:
365 374 ncolspan = 3
366 375 colspan = 2
367 376 self.__nsubplots = 2
368 377
369 378 self.createFigure(idfigure = idfigure,
370 379 wintitle = wintitle,
371 380 widthplot = self.WIDTH + self.WIDTHPROF,
372 381 heightplot = self.HEIGHT + self.HEIGHTPROF)
373 382
374 383 nrow, ncol = self.getSubplots()
375 384
376 385 counter = 0
377 386 for y in range(nrow):
378 387 for x in range(ncol):
379 388
380 389 if counter >= self.nplots:
381 390 break
382 391
383 392 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
384 393
385 394 if showprofile:
386 395 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
387 396
388 397 counter += 1
389 398
390 399 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
391 400 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
392 401 save=False, figpath='./', figfile=None):
393 402
394 403 """
395 404
396 405 Input:
397 406 dataOut :
398 407 idfigure :
399 408 wintitle :
400 409 channelList :
401 410 showProfile :
402 411 xmin : None,
403 412 xmax : None,
404 413 ymin : None,
405 414 ymax : None,
406 415 zmin : None,
407 416 zmax : None
408 417 """
409 418
410 419 if channelList == None:
411 420 channelIndexList = dataOut.channelIndexList
412 421 else:
413 422 channelIndexList = []
414 423 for channel in channelList:
415 424 if channel not in dataOut.channelList:
416 425 raise ValueError, "Channel %d is not in dataOut.channelList"
417 426 channelIndexList.append(dataOut.channelList.index(channel))
418
427 factor = dataOut.normFactor
419 428 x = dataOut.getVelRange(1)
420 429 y = dataOut.getHeiRange()
421 430
422 z = 10.*numpy.log10(dataOut.data_spc[channelIndexList,:,:])
431 z = dataOut.data_spc[channelIndexList,:,:]/factor
423 432 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
424 433 avg = numpy.average(z, axis=1)
434 noise = dataOut.getNoise()/factor
425 435
426 noise = dataOut.getNoise()
436 zdB = 10*numpy.log10(z)
437 avgdB = 10*numpy.log10(avg)
438 noisedB = 10*numpy.log10(noise)
427 439
428 440 thisDatetime = dataOut.datatime
429 441 title = "Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
430 442 xlabel = "Velocity (m/s)"
431 443 ylabel = "Range (Km)"
432 444
433 445 if not self.__isConfig:
434 446
435 447 nplots = len(channelIndexList)
436 448
437 449 self.setup(idfigure=idfigure,
438 450 nplots=nplots,
439 451 wintitle=wintitle,
440 452 showprofile=showprofile)
441 453
442 454 if xmin == None: xmin = numpy.nanmin(x)
443 455 if xmax == None: xmax = numpy.nanmax(x)
444 456 if ymin == None: ymin = numpy.nanmin(y)
445 457 if ymax == None: ymax = numpy.nanmax(y)
446 if zmin == None: zmin = numpy.nanmin(avg)*0.9
447 if zmax == None: zmax = numpy.nanmax(avg)*0.9
458 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
459 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
448 460
449 461 self.__isConfig = True
450 462
451 463 self.setWinTitle(title)
452 464
453 465 for i in range(self.nplots):
454 title = "Channel %d: %4.2fdB" %(dataOut.channelList[i], noise[i])
466 title = "Channel %d: %4.2fdB" %(dataOut.channelList[i], noisedB[i])
455 467 axes = self.axesList[i*self.__nsubplots]
456 axes.pcolor(x, y, z[i,:,:],
468 axes.pcolor(x, y, zdB[i,:,:],
457 469 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
458 470 xlabel=xlabel, ylabel=ylabel, title=title,
459 471 ticksize=9, cblabel='')
460 472
461 473 if self.__showprofile:
462 474 axes = self.axesList[i*self.__nsubplots +1]
463 axes.pline(avg[i], y,
475 axes.pline(avgdB[i], y,
464 476 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
465 477 xlabel='dB', ylabel='', title='',
466 478 ytick_visible=False,
467 479 grid='x')
468 480
469 noiseline = numpy.repeat(noise[i], len(y))
481 noiseline = numpy.repeat(noisedB[i], len(y))
470 482 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
471 483
472 484 self.draw()
473 485
474 486 if save:
475 487 date = thisDatetime.strftime("%Y%m%d_%H%M%S")
476 488 if figfile == None:
477 489 figfile = self.getFilename(name = date)
478 490
479 491 self.saveFigure(figpath, figfile)
480 492
481 493 class Scope(Figure):
482 494
483 495 __isConfig = None
484 496
485 497 def __init__(self):
486 498
487 499 self.__isConfig = False
488 500 self.WIDTH = 600
489 501 self.HEIGHT = 200
490 502
491 503 def getSubplots(self):
492 504
493 505 nrow = self.nplots
494 506 ncol = 3
495 507 return nrow, ncol
496 508
497 509 def setup(self, idfigure, nplots, wintitle):
498 510
499 511 self.nplots = nplots
500 512
501 513 self.createFigure(idfigure, wintitle)
502 514
503 515 nrow,ncol = self.getSubplots()
504 516 colspan = 3
505 517 rowspan = 1
506 518
507 519 for i in range(nplots):
508 520 self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
509 521
510 522
511 523
512 524 def run(self, dataOut, idfigure, wintitle="", channelList=None,
513 525 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
514 526 figpath='./', figfile=None):
515 527
516 528 """
517 529
518 530 Input:
519 531 dataOut :
520 532 idfigure :
521 533 wintitle :
522 534 channelList :
523 535 xmin : None,
524 536 xmax : None,
525 537 ymin : None,
526 538 ymax : None,
527 539 """
528 540
529 541 if channelList == None:
530 542 channelIndexList = dataOut.channelIndexList
531 543 else:
532 544 channelIndexList = []
533 545 for channel in channelList:
534 546 if channel not in dataOut.channelList:
535 547 raise ValueError, "Channel %d is not in dataOut.channelList"
536 548 channelIndexList.append(dataOut.channelList.index(channel))
537 549
538 550 x = dataOut.heightList
539 551 y = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
540 552 y = y.real
541 553
542 554 thisDatetime = dataOut.datatime
543 555 title = "Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
544 556 xlabel = "Range (Km)"
545 557 ylabel = "Intensity"
546 558
547 559 if not self.__isConfig:
548 560 nplots = len(channelIndexList)
549 561
550 562 self.setup(idfigure=idfigure,
551 563 nplots=nplots,
552 564 wintitle=wintitle)
553 565
554 566 if xmin == None: xmin = numpy.nanmin(x)
555 567 if xmax == None: xmax = numpy.nanmax(x)
556 568 if ymin == None: ymin = numpy.nanmin(y)
557 569 if ymax == None: ymax = numpy.nanmax(y)
558 570
559 571 self.__isConfig = True
560 572
561 573 self.setWinTitle(title)
562 574
563 575 for i in range(len(self.axesList)):
564 576 title = "Channel %d" %(i)
565 577 axes = self.axesList[i]
566 578 ychannel = y[i,:]
567 579 axes.pline(x, ychannel,
568 580 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
569 581 xlabel=xlabel, ylabel=ylabel, title=title)
570 582
571 583 self.draw()
572 584
573 585 if save:
574 586 date = thisDatetime.strftime("%Y%m%d_%H%M%S")
575 587 if figfile == None:
576 588 figfile = self.getFilename(name = date)
577 589
578 590 self.saveFigure(figpath, figfile)
579 591
580 592 class ProfilePlot(Figure):
581 593 __isConfig = None
582 594 __nsubplots = None
583 595
584 596 WIDTHPROF = None
585 597 HEIGHTPROF = None
586 598 PREFIX = 'spcprofile'
587 599
588 600 def __init__(self):
589 601 self.__isConfig = False
590 602 self.__nsubplots = 1
591 603
592 604 self.WIDTH = 300
593 605 self.HEIGHT = 500
594 606
595 607 def getSubplots(self):
596 608 ncol = 1
597 609 nrow = 1
598 610
599 611 return nrow, ncol
600 612
601 613 def setup(self, idfigure, nplots, wintitle):
602 614
603 615 self.nplots = nplots
604 616
605 617 ncolspan = 1
606 618 colspan = 1
607 619
608 620 self.createFigure(idfigure = idfigure,
609 621 wintitle = wintitle,
610 622 widthplot = self.WIDTH,
611 623 heightplot = self.HEIGHT)
612 624
613 625 nrow, ncol = self.getSubplots()
614 626
615 627 counter = 0
616 628 for y in range(nrow):
617 629 for x in range(ncol):
618 630 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
619 631
620 632 def run(self, dataOut, idfigure, wintitle="", channelList=None,
621 633 xmin=None, xmax=None, ymin=None, ymax=None,
622 634 save=False, figpath='./', figfile=None):
623 635
624 636 if channelList == None:
625 637 channelIndexList = dataOut.channelIndexList
626 638 channelList = dataOut.channelList
627 639 else:
628 640 channelIndexList = []
629 641 for channel in channelList:
630 642 if channel not in dataOut.channelList:
631 643 raise ValueError, "Channel %d is not in dataOut.channelList"
632 644 channelIndexList.append(dataOut.channelList.index(channel))
633 645
634
646 factor = dataOut.normFactor
635 647 y = dataOut.getHeiRange()
636 x = 10.*numpy.log10(dataOut.data_spc[channelIndexList,:,:])
648 x = dataOut.data_spc[channelIndexList,:,:]/factor
649 x = numpy.where(numpy.isfinite(x), x, numpy.NAN)
637 650 avg = numpy.average(x, axis=1)
638 651
652 avgdB = 10*numpy.log10(avg)
653
639 654 thisDatetime = dataOut.datatime
640 655 title = "Power Profile"
641 656 xlabel = "dB"
642 657 ylabel = "Range (Km)"
643 658
644 659 if not self.__isConfig:
645 660
646 661 nplots = 1
647 662
648 663 self.setup(idfigure=idfigure,
649 664 nplots=nplots,
650 665 wintitle=wintitle)
651 666
652 667 if ymin == None: ymin = numpy.nanmin(y)
653 668 if ymax == None: ymax = numpy.nanmax(y)
654 if xmin == None: xmin = numpy.nanmin(avg)*0.9
655 if xmax == None: xmax = numpy.nanmax(avg)*0.9
669 if xmin == None: xmin = numpy.nanmin(avgdB)*0.9
670 if xmax == None: xmax = numpy.nanmax(avgdB)*0.9
656 671
657 672 self.__isConfig = True
658 673
659 674 self.setWinTitle(title)
660 675
661 676
662 677 title = "Power Profile: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
663 678 axes = self.axesList[0]
664 679
665 680 legendlabels = ["channel %d"%x for x in channelList]
666 axes.pmultiline(avg, y,
681 axes.pmultiline(avgdB, y,
667 682 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
668 683 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
669 684 ytick_visible=True, nxticks=5,
670 685 grid='x')
671 686
672 687 self.draw()
673 688
674 689 if save:
675 690 date = thisDatetime.strftime("%Y%m%d")
676 691 if figfile == None:
677 692 figfile = self.getFilename(name = date)
678 693
679 694 self.saveFigure(figpath, figfile)
680 695
681 696 class CoherenceMap(Figure):
682 697 __isConfig = None
683 698 __nsubplots = None
684 699
685 700 WIDTHPROF = None
686 701 HEIGHTPROF = None
687 702 PREFIX = 'coherencemap'
688 703
689 704 def __init__(self):
690 705 self.timerange = 2*60*60
691 706 self.__isConfig = False
692 707 self.__nsubplots = 1
693 708
694 709 self.WIDTH = 800
695 710 self.HEIGHT = 200
696 711 self.WIDTHPROF = 120
697 712 self.HEIGHTPROF = 0
698 713
699 714 def getSubplots(self):
700 715 ncol = 1
701 716 nrow = self.nplots*2
702 717
703 718 return nrow, ncol
704 719
705 720 def setup(self, idfigure, nplots, wintitle, showprofile=True):
706 721 self.__showprofile = showprofile
707 722 self.nplots = nplots
708 723
709 724 ncolspan = 1
710 725 colspan = 1
711 726 if showprofile:
712 727 ncolspan = 7
713 728 colspan = 6
714 729 self.__nsubplots = 2
715 730
716 731 self.createFigure(idfigure = idfigure,
717 732 wintitle = wintitle,
718 733 widthplot = self.WIDTH + self.WIDTHPROF,
719 734 heightplot = self.HEIGHT + self.HEIGHTPROF)
720 735
721 736 nrow, ncol = self.getSubplots()
722 737
723 738 for y in range(nrow):
724 739 for x in range(ncol):
725 740
726 741 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
727 742
728 743 if showprofile:
729 744 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
730 745
731 746 def run(self, dataOut, idfigure, wintitle="", pairsList=None, showprofile='True',
732 747 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
733 748 timerange=None,
734 749 save=False, figpath='./', figfile=None):
735 750
736 751 if pairsList == None:
737 752 pairsIndexList = dataOut.pairsIndexList
738 753 else:
739 754 pairsIndexList = []
740 755 for pair in pairsList:
741 756 if pair not in dataOut.pairsList:
742 757 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
743 758 pairsIndexList.append(dataOut.pairsList.index(pair))
744 759
745 760 if timerange != None:
746 761 self.timerange = timerange
747 762
748 763 if pairsIndexList == []:
749 764 return
750 765
751 766 if len(pairsIndexList) > 4:
752 767 pairsIndexList = pairsIndexList[0:4]
753 768
754 769 tmin = None
755 770 tmax = None
756 771 x = dataOut.getTimeRange()
757 772 y = dataOut.getHeiRange()
758 773
759 774 thisDatetime = dataOut.datatime
760 775 title = "CoherenceMap: %s" %(thisDatetime.strftime("%d-%b-%Y"))
761 776 xlabel = ""
762 777 ylabel = "Range (Km)"
763 778
764 779 if not self.__isConfig:
765 780 nplots = len(pairsIndexList)
766 781 self.setup(idfigure=idfigure,
767 782 nplots=nplots,
768 783 wintitle=wintitle,
769 784 showprofile=showprofile)
770 785
771 786 tmin, tmax = self.getTimeLim(x, xmin, xmax)
772 787 if ymin == None: ymin = numpy.nanmin(y)
773 788 if ymax == None: ymax = numpy.nanmax(y)
774 789
775 790 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
776 791
777 792 self.__isConfig = True
778 793
779 794 self.setWinTitle(title)
780 795
781 796 for i in range(self.nplots):
782 797
783 798 pair = dataOut.pairsList[pairsIndexList[i]]
784 799 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[pair[0],:,:]*dataOut.data_spc[pair[1],:,:])
785 800 coherence = numpy.abs(coherenceComplex)
786 801 avg = numpy.average(coherence, axis=0)
787 802 z = avg.reshape((1,-1))
788 803
789 804 counter = 0
790 805
791 806 title = "Coherence %d%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
792 807 axes = self.axesList[i*self.__nsubplots*2]
793 808 axes.pcolor(x, y, z,
794 809 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=0, zmax=1,
795 810 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
796 811 ticksize=9, cblabel='', cbsize="1%")
797 812
798 813 if self.__showprofile:
799 814 counter += 1
800 815 axes = self.axesList[i*self.__nsubplots*2 + counter]
801 816 axes.pline(avg, y,
802 817 xmin=0, xmax=1, ymin=ymin, ymax=ymax,
803 818 xlabel='', ylabel='', title='', ticksize=7,
804 819 ytick_visible=False, nxticks=5,
805 820 grid='x')
806 821
807 822 counter += 1
808 823 phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
809 824 avg = numpy.average(phase, axis=0)
810 825 z = avg.reshape((1,-1))
811 826
812 827 title = "Phase %d%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
813 828 axes = self.axesList[i*self.__nsubplots*2 + counter]
814 829 axes.pcolor(x, y, z,
815 830 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=-180, zmax=180,
816 831 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
817 832 ticksize=9, cblabel='', colormap='RdBu', cbsize="1%")
818 833
819 834 if self.__showprofile:
820 835 counter += 1
821 836 axes = self.axesList[i*self.__nsubplots*2 + counter]
822 837 axes.pline(avg, y,
823 838 xmin=-180, xmax=180, ymin=ymin, ymax=ymax,
824 839 xlabel='', ylabel='', title='', ticksize=7,
825 840 ytick_visible=False, nxticks=4,
826 841 grid='x')
827 842
828 843 self.draw()
829 844
830 845 if save:
831 846
832 847 if figfile == None:
833 848 figfile = self.getFilename(name = self.name)
834 849
835 850 self.saveFigure(figpath, figfile)
836 851
837 852 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
838 853 self.__isConfig = False
839 854
840 855 class RTIfromNoise(Figure):
841 856
842 857 __isConfig = None
843 858 __nsubplots = None
844 859
845 860 PREFIX = 'rtinoise'
846 861
847 862 def __init__(self):
848 863
849 864 self.timerange = 24*60*60
850 865 self.__isConfig = False
851 866 self.__nsubplots = 1
852 867
853 868 self.WIDTH = 820
854 869 self.HEIGHT = 200
870 self.WIDTHPROF = 120
871 self.HEIGHTPROF = 0
872 self.xdata = None
873 self.ydata = None
855 874
856 875 def getSubplots(self):
857 876
858 877 ncol = 1
859 878 nrow = 1
860 879
861 880 return nrow, ncol
862 881
863 882 def setup(self, idfigure, nplots, wintitle, showprofile=True):
864 883
865 884 self.__showprofile = showprofile
866 885 self.nplots = nplots
867 886
868 ncolspan = 1
869 colspan = 1
887 ncolspan = 7
888 colspan = 6
889 self.__nsubplots = 2
870 890
871 891 self.createFigure(idfigure = idfigure,
872 892 wintitle = wintitle,
873 widthplot = self.WIDTH,
874 heightplot = self.HEIGHT)
893 widthplot = self.WIDTH+self.WIDTHPROF,
894 heightplot = self.HEIGHT+self.HEIGHTPROF)
875 895
876 896 nrow, ncol = self.getSubplots()
877 897
878 self.addAxes(nrow, ncol, 0, 0, 1, 1)
898 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
899
879 900
880 901 def run(self, dataOut, idfigure, wintitle="", channelList=None, showprofile='True',
881 902 xmin=None, xmax=None, ymin=None, ymax=None,
882 903 timerange=None,
883 904 save=False, figpath='./', figfile=None):
884 905
885 906 if channelList == None:
886 907 channelIndexList = dataOut.channelIndexList
887 908 channelList = dataOut.channelList
888 909 else:
889 910 channelIndexList = []
890 911 for channel in channelList:
891 912 if channel not in dataOut.channelList:
892 913 raise ValueError, "Channel %d is not in dataOut.channelList"
893 914 channelIndexList.append(dataOut.channelList.index(channel))
894 915
895 916 if timerange != None:
896 917 self.timerange = timerange
897 918
898 919 tmin = None
899 920 tmax = None
900 921 x = dataOut.getTimeRange()
901 922 y = dataOut.getHeiRange()
902
903 noise = dataOut.getNoise()
923 factor = dataOut.normFactor
924 noise = dataOut.getNoise()/factor
925 noisedB = 10*numpy.log10(noise)
904 926
905 927 thisDatetime = dataOut.datatime
906 928 title = "RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
907 xlabel = "Velocity (m/s)"
929 xlabel = ""
908 930 ylabel = "Range (Km)"
909 931
910 932 if not self.__isConfig:
911 933
912 934 nplots = 1
913 935
914 936 self.setup(idfigure=idfigure,
915 937 nplots=nplots,
916 938 wintitle=wintitle,
917 939 showprofile=showprofile)
918 940
919 941 tmin, tmax = self.getTimeLim(x, xmin, xmax)
920 if ymin == None: ymin = numpy.nanmin(noise)
921 if ymax == None: ymax = numpy.nanmax(noise)
942 if ymin == None: ymin = numpy.nanmin(noisedB)
943 if ymax == None: ymax = numpy.nanmax(noisedB)
922 944
923 945 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
924 946 self.__isConfig = True
925 947
948 self.xdata = numpy.array([])
949 self.ydata = numpy.array([])
926 950
927 951 self.setWinTitle(title)
928 952
929 953
930 954 title = "RTI Noise %s" %(thisDatetime.strftime("%d-%b-%Y"))
931 955
932 956 legendlabels = ["channel %d"%idchannel for idchannel in channelList]
933 957 axes = self.axesList[0]
934 xdata = x[0:1]
935 ydata = noise[channelIndexList].reshape(-1,1)
936 axes.pmultilineyaxis(x=xdata, y=ydata,
958
959 self.xdata = numpy.hstack((self.xdata, x[0:1]))
960
961 if len(self.ydata)==0:
962 self.ydata = noisedB[channelIndexList].reshape(-1,1)
963 else:
964 self.ydata = numpy.hstack((self.ydata, noisedB[channelIndexList].reshape(-1,1)))
965
966
967 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
937 968 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax,
938 969 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
939 970 XAxisAsTime=True
940 971 )
941 972
942
943 973 self.draw()
944 974
945 975 if save:
946 976
947 977 if figfile == None:
948 978 figfile = self.getFilename(name = self.name)
949 979
950 980 self.saveFigure(figpath, figfile)
951 981
952 982 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
953 983 self.__isConfig = False
984 del self.xdata
985 del self.ydata
954 986 No newline at end of file
@@ -1,1157 +1,1159
1 1 '''
2 2
3 3 $Author: dsuarez $
4 4 $Id: Processor.py 1 2012-11-12 18:56:07Z dsuarez $
5 5 '''
6 6 import os
7 7 import numpy
8 8 import datetime
9 9 import time
10 10
11 11 from jrodata import *
12 12 from jrodataIO import *
13 13 from jroplot import *
14 14
15 15 class ProcessingUnit:
16 16
17 17 """
18 18 Esta es la clase base para el procesamiento de datos.
19 19
20 20 Contiene el metodo "call" para llamar operaciones. Las operaciones pueden ser:
21 21 - Metodos internos (callMethod)
22 22 - Objetos del tipo Operation (callObject). Antes de ser llamados, estos objetos
23 23 tienen que ser agreagados con el metodo "add".
24 24
25 25 """
26 26 # objeto de datos de entrada (Voltage, Spectra o Correlation)
27 27 dataIn = None
28 28
29 29 # objeto de datos de entrada (Voltage, Spectra o Correlation)
30 30 dataOut = None
31 31
32 32
33 33 objectDict = None
34 34
35 35 def __init__(self):
36 36
37 37 self.objectDict = {}
38 38
39 39 def init(self):
40 40
41 41 raise ValueError, "Not implemented"
42 42
43 43 def addOperation(self, object, objId):
44 44
45 45 """
46 46 Agrega el objeto "object" a la lista de objetos "self.objectList" y retorna el
47 47 identificador asociado a este objeto.
48 48
49 49 Input:
50 50
51 51 object : objeto de la clase "Operation"
52 52
53 53 Return:
54 54
55 55 objId : identificador del objeto, necesario para ejecutar la operacion
56 56 """
57 57
58 58 self.objectDict[objId] = object
59 59
60 60 return objId
61 61
62 62 def operation(self, **kwargs):
63 63
64 64 """
65 65 Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los
66 66 atributos del objeto dataOut
67 67
68 68 Input:
69 69
70 70 **kwargs : Diccionario de argumentos de la funcion a ejecutar
71 71 """
72 72
73 73 raise ValueError, "ImplementedError"
74 74
75 75 def callMethod(self, name, **kwargs):
76 76
77 77 """
78 78 Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
79 79
80 80 Input:
81 81 name : nombre del metodo a ejecutar
82 82
83 83 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
84 84
85 85 """
86 86 if name != 'run':
87 87
88 88 if name == 'init' and self.dataIn.isEmpty():
89 89 self.dataOut.flagNoData = True
90 90 return False
91 91
92 92 if name != 'init' and self.dataOut.isEmpty():
93 93 return False
94 94
95 95 methodToCall = getattr(self, name)
96 96
97 97 methodToCall(**kwargs)
98 98
99 99 if name != 'run':
100 100 return True
101 101
102 102 if self.dataOut.isEmpty():
103 103 return False
104 104
105 105 return True
106 106
107 107 def callObject(self, objId, **kwargs):
108 108
109 109 """
110 110 Ejecuta la operacion asociada al identificador del objeto "objId"
111 111
112 112 Input:
113 113
114 114 objId : identificador del objeto a ejecutar
115 115
116 116 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
117 117
118 118 Return:
119 119
120 120 None
121 121 """
122 122
123 123 if self.dataOut.isEmpty():
124 124 return False
125 125
126 126 object = self.objectDict[objId]
127 127
128 128 object.run(self.dataOut, **kwargs)
129 129
130 130 return True
131 131
132 132 def call(self, operationConf, **kwargs):
133 133
134 134 """
135 135 Return True si ejecuta la operacion "operationConf.name" con los
136 136 argumentos "**kwargs". False si la operacion no se ha ejecutado.
137 137 La operacion puede ser de dos tipos:
138 138
139 139 1. Un metodo propio de esta clase:
140 140
141 141 operation.type = "self"
142 142
143 143 2. El metodo "run" de un objeto del tipo Operation o de un derivado de ella:
144 144 operation.type = "other".
145 145
146 146 Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
147 147 "addOperation" e identificado con el operation.id
148 148
149 149
150 150 con el id de la operacion.
151 151
152 152 Input:
153 153
154 154 Operation : Objeto del tipo operacion con los atributos: name, type y id.
155 155
156 156 """
157 157
158 158 if operationConf.type == 'self':
159 159 sts = self.callMethod(operationConf.name, **kwargs)
160 160
161 161 if operationConf.type == 'other':
162 162 sts = self.callObject(operationConf.id, **kwargs)
163 163
164 164 return sts
165 165
166 166 def setInput(self, dataIn):
167 167
168 168 self.dataIn = dataIn
169 169
170 170 def getOutput(self):
171 171
172 172 return self.dataOut
173 173
174 174 class Operation():
175 175
176 176 """
177 177 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
178 178 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
179 179 acumulacion dentro de esta clase
180 180
181 181 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
182 182
183 183 """
184 184
185 185 __buffer = None
186 186 __isConfig = False
187 187
188 188 def __init__(self):
189 189
190 190 pass
191 191
192 192 def run(self, dataIn, **kwargs):
193 193
194 194 """
195 195 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los atributos del objeto dataIn.
196 196
197 197 Input:
198 198
199 199 dataIn : objeto del tipo JROData
200 200
201 201 Return:
202 202
203 203 None
204 204
205 205 Affected:
206 206 __buffer : buffer de recepcion de datos.
207 207
208 208 """
209 209
210 210 raise ValueError, "ImplementedError"
211 211
212 212 class VoltageProc(ProcessingUnit):
213 213
214 214
215 215 def __init__(self):
216 216
217 217 self.objectDict = {}
218 218 self.dataOut = Voltage()
219 219 self.flip = 1
220 220
221 221 def init(self):
222 222
223 223 self.dataOut.copy(self.dataIn)
224 224 # No necesita copiar en cada init() los atributos de dataIn
225 225 # la copia deberia hacerse por cada nuevo bloque de datos
226 226
227 227 def selectChannels(self, channelList):
228 228
229 229 channelIndexList = []
230 230
231 231 for channel in channelList:
232 232 index = self.dataOut.channelList.index(channel)
233 233 channelIndexList.append(index)
234 234
235 235 self.selectChannelsByIndex(channelIndexList)
236 236
237 237 def selectChannelsByIndex(self, channelIndexList):
238 238 """
239 239 Selecciona un bloque de datos en base a canales segun el channelIndexList
240 240
241 241 Input:
242 242 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
243 243
244 244 Affected:
245 245 self.dataOut.data
246 246 self.dataOut.channelIndexList
247 247 self.dataOut.nChannels
248 248 self.dataOut.m_ProcessingHeader.totalSpectra
249 249 self.dataOut.systemHeaderObj.numChannels
250 250 self.dataOut.m_ProcessingHeader.blockSize
251 251
252 252 Return:
253 253 None
254 254 """
255 255
256 256 for channelIndex in channelIndexList:
257 257 if channelIndex not in self.dataOut.channelIndexList:
258 258 print channelIndexList
259 259 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
260 260
261 261 nChannels = len(channelIndexList)
262 262
263 263 data = self.dataOut.data[channelIndexList,:]
264 264
265 265 self.dataOut.data = data
266 266 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
267 267 # self.dataOut.nChannels = nChannels
268 268
269 269 return 1
270 270
271 271 def selectHeights(self, minHei, maxHei):
272 272 """
273 273 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
274 274 minHei <= height <= maxHei
275 275
276 276 Input:
277 277 minHei : valor minimo de altura a considerar
278 278 maxHei : valor maximo de altura a considerar
279 279
280 280 Affected:
281 281 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
282 282
283 283 Return:
284 284 1 si el metodo se ejecuto con exito caso contrario devuelve 0
285 285 """
286 286 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
287 287 raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
288 288
289 289 if (maxHei > self.dataOut.heightList[-1]):
290 290 maxHei = self.dataOut.heightList[-1]
291 291 # raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
292 292
293 293 minIndex = 0
294 294 maxIndex = 0
295 295 heights = self.dataOut.heightList
296 296
297 297 inda = numpy.where(heights >= minHei)
298 298 indb = numpy.where(heights <= maxHei)
299 299
300 300 try:
301 301 minIndex = inda[0][0]
302 302 except:
303 303 minIndex = 0
304 304
305 305 try:
306 306 maxIndex = indb[0][-1]
307 307 except:
308 308 maxIndex = len(heights)
309 309
310 310 self.selectHeightsByIndex(minIndex, maxIndex)
311 311
312 312 return 1
313 313
314 314
315 315 def selectHeightsByIndex(self, minIndex, maxIndex):
316 316 """
317 317 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
318 318 minIndex <= index <= maxIndex
319 319
320 320 Input:
321 321 minIndex : valor de indice minimo de altura a considerar
322 322 maxIndex : valor de indice maximo de altura a considerar
323 323
324 324 Affected:
325 325 self.dataOut.data
326 326 self.dataOut.heightList
327 327
328 328 Return:
329 329 1 si el metodo se ejecuto con exito caso contrario devuelve 0
330 330 """
331 331
332 332 if (minIndex < 0) or (minIndex > maxIndex):
333 333 raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
334 334
335 335 if (maxIndex >= self.dataOut.nHeights):
336 336 maxIndex = self.dataOut.nHeights-1
337 337 # raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
338 338
339 339 nHeights = maxIndex - minIndex + 1
340 340
341 341 #voltage
342 342 data = self.dataOut.data[:,minIndex:maxIndex+1]
343 343
344 344 firstHeight = self.dataOut.heightList[minIndex]
345 345
346 346 self.dataOut.data = data
347 347 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1]
348 348
349 349 return 1
350 350
351 351
352 352 def filterByHeights(self, window):
353 353 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
354 354
355 355 if window == None:
356 356 window = self.dataOut.radarControllerHeaderObj.txA / deltaHeight
357 357
358 358 newdelta = deltaHeight * window
359 359 r = self.dataOut.data.shape[1] % window
360 360 buffer = self.dataOut.data[:,0:self.dataOut.data.shape[1]-r]
361 361 buffer = buffer.reshape(self.dataOut.data.shape[0],self.dataOut.data.shape[1]/window,window)
362 buffer = numpy.average(buffer,2)
362 buffer = numpy.sum(buffer,2)
363 363 self.dataOut.data = buffer
364 364 self.dataOut.heightList = numpy.arange(self.dataOut.heightList[0],newdelta*self.dataOut.nHeights/window-newdelta,newdelta)
365 self.dataOut.windowOfFilter = window
365 366
366 367 def deFlip(self):
367 368 self.dataOut.data *= self.flip
368 369 self.flip *= -1.
369 370
370 371
371 372 class CohInt(Operation):
372 373
373 374 __isConfig = False
374 375
375 376 __profIndex = 0
376 377 __withOverapping = False
377 378
378 379 __byTime = False
379 380 __initime = None
380 381 __lastdatatime = None
381 382 __integrationtime = None
382 383
383 384 __buffer = None
384 385
385 386 __dataReady = False
386 387
387 388 n = None
388 389
389 390
390 391 def __init__(self):
391 392
392 393 self.__isConfig = False
393 394
394 395 def setup(self, n=None, timeInterval=None, overlapping=False):
395 396 """
396 397 Set the parameters of the integration class.
397 398
398 399 Inputs:
399 400
400 401 n : Number of coherent integrations
401 402 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
402 403 overlapping :
403 404
404 405 """
405 406
406 407 self.__initime = None
407 408 self.__lastdatatime = 0
408 409 self.__buffer = None
409 410 self.__dataReady = False
410 411
411 412
412 413 if n == None and timeInterval == None:
413 414 raise ValueError, "n or timeInterval should be specified ..."
414 415
415 416 if n != None:
416 417 self.n = n
417 418 self.__byTime = False
418 419 else:
419 420 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
420 421 self.n = 9999
421 422 self.__byTime = True
422 423
423 424 if overlapping:
424 425 self.__withOverapping = True
425 426 self.__buffer = None
426 427 else:
427 428 self.__withOverapping = False
428 429 self.__buffer = 0
429 430
430 431 self.__profIndex = 0
431 432
432 433 def putData(self, data):
433 434
434 435 """
435 436 Add a profile to the __buffer and increase in one the __profileIndex
436 437
437 438 """
438 439
439 440 if not self.__withOverapping:
440 441 self.__buffer += data.copy()
441 442 self.__profIndex += 1
442 443 return
443 444
444 445 #Overlapping data
445 446 nChannels, nHeis = data.shape
446 447 data = numpy.reshape(data, (1, nChannels, nHeis))
447 448
448 449 #If the buffer is empty then it takes the data value
449 450 if self.__buffer == None:
450 451 self.__buffer = data
451 452 self.__profIndex += 1
452 453 return
453 454
454 455 #If the buffer length is lower than n then stakcing the data value
455 456 if self.__profIndex < self.n:
456 457 self.__buffer = numpy.vstack((self.__buffer, data))
457 458 self.__profIndex += 1
458 459 return
459 460
460 461 #If the buffer length is equal to n then replacing the last buffer value with the data value
461 462 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
462 463 self.__buffer[self.n-1] = data
463 464 self.__profIndex = self.n
464 465 return
465 466
466 467
467 468 def pushData(self):
468 469 """
469 470 Return the sum of the last profiles and the profiles used in the sum.
470 471
471 472 Affected:
472 473
473 474 self.__profileIndex
474 475
475 476 """
476 477
477 478 if not self.__withOverapping:
478 479 data = self.__buffer
479 480 n = self.__profIndex
480 481
481 482 self.__buffer = 0
482 483 self.__profIndex = 0
483 484
484 485 return data, n
485 486
486 487 #Integration with Overlapping
487 488 data = numpy.sum(self.__buffer, axis=0)
488 489 n = self.__profIndex
489 490
490 491 return data, n
491 492
492 493 def byProfiles(self, data):
493 494
494 495 self.__dataReady = False
495 496 avgdata = None
496 497 n = None
497 498
498 499 self.putData(data)
499 500
500 501 if self.__profIndex == self.n:
501 502
502 503 avgdata, n = self.pushData()
503 504 self.__dataReady = True
504 505
505 506 return avgdata
506 507
507 508 def byTime(self, data, datatime):
508 509
509 510 self.__dataReady = False
510 511 avgdata = None
511 512 n = None
512 513
513 514 self.putData(data)
514 515
515 516 if (datatime - self.__initime) >= self.__integrationtime:
516 517 avgdata, n = self.pushData()
517 518 self.n = n
518 519 self.__dataReady = True
519 520
520 521 return avgdata
521 522
522 523 def integrate(self, data, datatime=None):
523 524
524 525 if self.__initime == None:
525 526 self.__initime = datatime
526 527
527 528 if self.__byTime:
528 529 avgdata = self.byTime(data, datatime)
529 530 else:
530 531 avgdata = self.byProfiles(data)
531 532
532 533
533 534 self.__lastdatatime = datatime
534 535
535 536 if avgdata == None:
536 537 return None, None
537 538
538 539 avgdatatime = self.__initime
539 540
540 541 deltatime = datatime -self.__lastdatatime
541 542
542 543 if not self.__withOverapping:
543 544 self.__initime = datatime
544 545 else:
545 546 self.__initime += deltatime
546 547
547 548 return avgdata, avgdatatime
548 549
549 550 def run(self, dataOut, **kwargs):
550 551
551 552 if not self.__isConfig:
552 553 self.setup(**kwargs)
553 554 self.__isConfig = True
554 555
555 556 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
556 557
557 558 # dataOut.timeInterval *= n
558 559 dataOut.flagNoData = True
559 560
560 561 if self.__dataReady:
561 562 dataOut.data = avgdata
562 563 dataOut.nCohInt *= self.n
563 564 dataOut.utctime = avgdatatime
564 565 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
565 566 dataOut.flagNoData = False
566 567
567 568
568 569 class Decoder(Operation):
569 570
570 571 __isConfig = False
571 572 __profIndex = 0
572 573
573 574 code = None
574 575
575 576 nCode = None
576 577 nBaud = None
577 578
578 579 def __init__(self):
579 580
580 581 self.__isConfig = False
581 582
582 583 def setup(self, code):
583 584
584 585 self.__profIndex = 0
585 586
586 587 self.code = code
587 588
588 589 self.nCode = len(code)
589 590 self.nBaud = len(code[0])
590 591
591 592 def convolutionInFreq(self, data):
592 593
593 594 nchannel, ndata = data.shape
594 595 newcode = numpy.zeros(ndata)
595 596 newcode[0:self.nBaud] = self.code[self.__profIndex]
596 597
597 598 fft_data = numpy.fft.fft(data, axis=1)
598 599 fft_code = numpy.conj(numpy.fft.fft(newcode))
599 600 fft_code = fft_code.reshape(1,len(fft_code))
600 601
601 602 # conv = fft_data.copy()
602 603 # conv.fill(0)
603 604
604 605 conv = fft_data*fft_code
605 606
606 607 data = numpy.fft.ifft(conv,axis=1)
607 608
608 609 datadec = data[:,:-self.nBaud+1]
609 610 ndatadec = ndata - self.nBaud + 1
610 611
611 612 if self.__profIndex == self.nCode-1:
612 613 self.__profIndex = 0
613 614 return ndatadec, datadec
614 615
615 616 self.__profIndex += 1
616 617
617 618 return ndatadec, datadec
618 619
619 620
620 621 def convolutionInTime(self, data):
621 622
622 623 nchannel, ndata = data.shape
623 624 newcode = self.code[self.__profIndex]
624 625 ndatadec = ndata - self.nBaud + 1
625 626
626 627 datadec = numpy.zeros((nchannel, ndatadec))
627 628
628 629 for i in range(nchannel):
629 630 datadec[i,:] = numpy.correlate(data[i,:], newcode)
630 631
631 632 if self.__profIndex == self.nCode-1:
632 633 self.__profIndex = 0
633 634 return ndatadec, datadec
634 635
635 636 self.__profIndex += 1
636 637
637 638 return ndatadec, datadec
638 639
639 640 def run(self, dataOut, code=None, mode = 0):
640 641
641 642 if not self.__isConfig:
642 643
643 644 if code == None:
644 645 code = dataOut.code
645 646
646 647 self.setup(code)
647 648 self.__isConfig = True
648 649
649 650 if mode == 0:
650 651 ndatadec, datadec = self.convolutionInFreq(dataOut.data)
651 652
652 653 if mode == 1:
653 654 print "This function is not implemented"
654 655 # ndatadec, datadec = self.convolutionInTime(dataOut.data)
655 656
656 657 dataOut.data = datadec
657 658
658 659 dataOut.heightList = dataOut.heightList[0:ndatadec]
659 660
660 661 dataOut.flagDecodeData = True #asumo q la data no esta decodificada
661 662
662 663 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
663 664
664 665
665 666 class SpectraProc(ProcessingUnit):
666 667
667 668 def __init__(self):
668 669
669 670 self.objectDict = {}
670 671 self.buffer = None
671 672 self.firstdatatime = None
672 673 self.profIndex = 0
673 674 self.dataOut = Spectra()
674 675
675 676 def __updateObjFromInput(self):
676 677
677 678 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
678 679 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
679 680 self.dataOut.channelList = self.dataIn.channelList
680 681 self.dataOut.heightList = self.dataIn.heightList
681 682 self.dataOut.dtype = self.dataIn.dtype
682 683 # self.dataOut.nHeights = self.dataIn.nHeights
683 684 # self.dataOut.nChannels = self.dataIn.nChannels
684 685 self.dataOut.nBaud = self.dataIn.nBaud
685 686 self.dataOut.nCode = self.dataIn.nCode
686 687 self.dataOut.code = self.dataIn.code
687 688 self.dataOut.nProfiles = self.dataOut.nFFTPoints
688 689 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
689 690 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
690 691 self.dataOut.utctime = self.firstdatatime
691 692 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
692 693 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
693 694 self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
694 695 self.dataOut.nCohInt = self.dataIn.nCohInt
695 696 self.dataOut.nIncohInt = 1
696 697 self.dataOut.ippSeconds = self.dataIn.ippSeconds
698 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
697 699
698 700 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nFFTPoints*self.dataOut.nIncohInt
699 701
700 702 def __getFft(self):
701 703 """
702 704 Convierte valores de Voltaje a Spectra
703 705
704 706 Affected:
705 707 self.dataOut.data_spc
706 708 self.dataOut.data_cspc
707 709 self.dataOut.data_dc
708 710 self.dataOut.heightList
709 711 self.profIndex
710 712 self.buffer
711 713 self.dataOut.flagNoData
712 714 """
713 715 fft_volt = numpy.fft.fft(self.buffer,axis=1)
714 716 dc = fft_volt[:,0,:]
715 717
716 718 #calculo de self-spectra
717 719 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
718 720 spc = fft_volt * numpy.conjugate(fft_volt)
719 721 spc = spc.real
720 722
721 723 blocksize = 0
722 724 blocksize += dc.size
723 725 blocksize += spc.size
724 726
725 727 cspc = None
726 728 pairIndex = 0
727 729 if self.dataOut.pairsList != None:
728 730 #calculo de cross-spectra
729 731 cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
730 732 for pair in self.dataOut.pairsList:
731 733 cspc[pairIndex,:,:] = fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:])
732 734 pairIndex += 1
733 735 blocksize += cspc.size
734 736
735 737 self.dataOut.data_spc = spc
736 738 self.dataOut.data_cspc = cspc
737 739 self.dataOut.data_dc = dc
738 740 self.dataOut.blockSize = blocksize
739 741
740 742 def init(self, nFFTPoints=None, pairsList=None):
741 743
742 744 self.dataOut.flagNoData = True
743 745
744 746 if self.dataIn.type == "Spectra":
745 747 self.dataOut.copy(self.dataIn)
746 748 return
747 749
748 750 if self.dataIn.type == "Voltage":
749 751
750 752 if nFFTPoints == None:
751 753 raise ValueError, "This SpectraProc.init() need nFFTPoints input variable"
752 754
753 755 if pairsList == None:
754 756 nPairs = 0
755 757 else:
756 758 nPairs = len(pairsList)
757 759
758 760 self.dataOut.nFFTPoints = nFFTPoints
759 761 self.dataOut.pairsList = pairsList
760 762 self.dataOut.nPairs = nPairs
761 763
762 764 if self.buffer == None:
763 765 self.buffer = numpy.zeros((self.dataIn.nChannels,
764 766 self.dataOut.nFFTPoints,
765 767 self.dataIn.nHeights),
766 768 dtype='complex')
767 769
768 770
769 771 self.buffer[:,self.profIndex,:] = self.dataIn.data.copy()
770 772 self.profIndex += 1
771 773
772 774 if self.firstdatatime == None:
773 775 self.firstdatatime = self.dataIn.utctime
774 776
775 777 if self.profIndex == self.dataOut.nFFTPoints:
776 778 self.__updateObjFromInput()
777 779 self.__getFft()
778 780
779 781 self.dataOut.flagNoData = False
780 782
781 783 self.buffer = None
782 784 self.firstdatatime = None
783 785 self.profIndex = 0
784 786
785 787 return
786 788
787 789 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
788 790
789 791 def selectChannels(self, channelList):
790 792
791 793 channelIndexList = []
792 794
793 795 for channel in channelList:
794 796 index = self.dataOut.channelList.index(channel)
795 797 channelIndexList.append(index)
796 798
797 799 self.selectChannelsByIndex(channelIndexList)
798 800
799 801 def selectChannelsByIndex(self, channelIndexList):
800 802 """
801 803 Selecciona un bloque de datos en base a canales segun el channelIndexList
802 804
803 805 Input:
804 806 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
805 807
806 808 Affected:
807 809 self.dataOut.data_spc
808 810 self.dataOut.channelIndexList
809 811 self.dataOut.nChannels
810 812
811 813 Return:
812 814 None
813 815 """
814 816
815 817 for channelIndex in channelIndexList:
816 818 if channelIndex not in self.dataOut.channelIndexList:
817 819 print channelIndexList
818 820 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
819 821
820 822 nChannels = len(channelIndexList)
821 823
822 824 data_spc = self.dataOut.data_spc[channelIndexList,:]
823 825
824 826 self.dataOut.data_spc = data_spc
825 827 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
826 828 # self.dataOut.nChannels = nChannels
827 829
828 830 return 1
829 831
830 832
831 833 class IncohInt(Operation):
832 834
833 835
834 836 __profIndex = 0
835 837 __withOverapping = False
836 838
837 839 __byTime = False
838 840 __initime = None
839 841 __lastdatatime = None
840 842 __integrationtime = None
841 843
842 844 __buffer_spc = None
843 845 __buffer_cspc = None
844 846 __buffer_dc = None
845 847
846 848 __dataReady = False
847 849
848 850 n = None
849 851
850 852
851 853 def __init__(self):
852 854
853 855 self.__isConfig = False
854 856
855 857 def setup(self, n=None, timeInterval=None, overlapping=False):
856 858 """
857 859 Set the parameters of the integration class.
858 860
859 861 Inputs:
860 862
861 863 n : Number of coherent integrations
862 864 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
863 865 overlapping :
864 866
865 867 """
866 868
867 869 self.__initime = None
868 870 self.__lastdatatime = 0
869 871 self.__buffer_spc = None
870 872 self.__buffer_cspc = None
871 873 self.__buffer_dc = None
872 874 self.__dataReady = False
873 875
874 876
875 877 if n == None and timeInterval == None:
876 878 raise ValueError, "n or timeInterval should be specified ..."
877 879
878 880 if n != None:
879 881 self.n = n
880 882 self.__byTime = False
881 883 else:
882 884 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
883 885 self.n = 9999
884 886 self.__byTime = True
885 887
886 888 if overlapping:
887 889 self.__withOverapping = True
888 890 else:
889 891 self.__withOverapping = False
890 892 self.__buffer_spc = 0
891 893 self.__buffer_cspc = 0
892 894 self.__buffer_dc = 0
893 895
894 896 self.__profIndex = 0
895 897
896 898 def putData(self, data_spc, data_cspc, data_dc):
897 899
898 900 """
899 901 Add a profile to the __buffer_spc and increase in one the __profileIndex
900 902
901 903 """
902 904
903 905 if not self.__withOverapping:
904 906 self.__buffer_spc += data_spc
905 907
906 908 if data_cspc == None:
907 909 self.__buffer_cspc = None
908 910 else:
909 911 self.__buffer_cspc += data_cspc
910 912
911 913 if data_dc == None:
912 914 self.__buffer_dc = None
913 915 else:
914 916 self.__buffer_dc += data_dc
915 917
916 918 self.__profIndex += 1
917 919 return
918 920
919 921 #Overlapping data
920 922 nChannels, nFFTPoints, nHeis = data_spc.shape
921 923 data_spc = numpy.reshape(data_spc, (1, nChannels, nFFTPoints, nHeis))
922 924 if data_cspc != None:
923 925 data_cspc = numpy.reshape(data_cspc, (1, -1, nFFTPoints, nHeis))
924 926 if data_dc != None:
925 927 data_dc = numpy.reshape(data_dc, (1, -1, nHeis))
926 928
927 929 #If the buffer is empty then it takes the data value
928 930 if self.__buffer_spc == None:
929 931 self.__buffer_spc = data_spc
930 932
931 933 if data_cspc == None:
932 934 self.__buffer_cspc = None
933 935 else:
934 936 self.__buffer_cspc += data_cspc
935 937
936 938 if data_dc == None:
937 939 self.__buffer_dc = None
938 940 else:
939 941 self.__buffer_dc += data_dc
940 942
941 943 self.__profIndex += 1
942 944 return
943 945
944 946 #If the buffer length is lower than n then stakcing the data value
945 947 if self.__profIndex < self.n:
946 948 self.__buffer_spc = numpy.vstack((self.__buffer_spc, data_spc))
947 949
948 950 if data_cspc != None:
949 951 self.__buffer_cspc = numpy.vstack((self.__buffer_cspc, data_cspc))
950 952
951 953 if data_dc != None:
952 954 self.__buffer_dc = numpy.vstack((self.__buffer_dc, data_dc))
953 955
954 956 self.__profIndex += 1
955 957 return
956 958
957 959 #If the buffer length is equal to n then replacing the last buffer value with the data value
958 960 self.__buffer_spc = numpy.roll(self.__buffer_spc, -1, axis=0)
959 961 self.__buffer_spc[self.n-1] = data_spc
960 962
961 963 if data_cspc != None:
962 964 self.__buffer_cspc = numpy.roll(self.__buffer_cspc, -1, axis=0)
963 965 self.__buffer_cspc[self.n-1] = data_cspc
964 966
965 967 if data_dc != None:
966 968 self.__buffer_dc = numpy.roll(self.__buffer_dc, -1, axis=0)
967 969 self.__buffer_dc[self.n-1] = data_dc
968 970
969 971 self.__profIndex = self.n
970 972 return
971 973
972 974
973 975 def pushData(self):
974 976 """
975 977 Return the sum of the last profiles and the profiles used in the sum.
976 978
977 979 Affected:
978 980
979 981 self.__profileIndex
980 982
981 983 """
982 984 data_spc = None
983 985 data_cspc = None
984 986 data_dc = None
985 987
986 988 if not self.__withOverapping:
987 989 data_spc = self.__buffer_spc
988 990 data_cspc = self.__buffer_cspc
989 991 data_dc = self.__buffer_dc
990 992
991 993 n = self.__profIndex
992 994
993 995 self.__buffer_spc = 0
994 996 self.__buffer_cspc = 0
995 997 self.__buffer_dc = 0
996 998 self.__profIndex = 0
997 999
998 1000 return data_spc, data_cspc, data_dc, n
999 1001
1000 1002 #Integration with Overlapping
1001 1003 data_spc = numpy.sum(self.__buffer_spc, axis=0)
1002 1004
1003 1005 if self.__buffer_cspc != None:
1004 1006 data_cspc = numpy.sum(self.__buffer_cspc, axis=0)
1005 1007
1006 1008 if self.__buffer_dc != None:
1007 1009 data_dc = numpy.sum(self.__buffer_dc, axis=0)
1008 1010
1009 1011 n = self.__profIndex
1010 1012
1011 1013 return data_spc, data_cspc, data_dc, n
1012 1014
1013 1015 def byProfiles(self, *args):
1014 1016
1015 1017 self.__dataReady = False
1016 1018 avgdata_spc = None
1017 1019 avgdata_cspc = None
1018 1020 avgdata_dc = None
1019 1021 n = None
1020 1022
1021 1023 self.putData(*args)
1022 1024
1023 1025 if self.__profIndex == self.n:
1024 1026
1025 1027 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1026 1028 self.__dataReady = True
1027 1029
1028 1030 return avgdata_spc, avgdata_cspc, avgdata_dc
1029 1031
1030 1032 def byTime(self, datatime, *args):
1031 1033
1032 1034 self.__dataReady = False
1033 1035 avgdata_spc = None
1034 1036 avgdata_cspc = None
1035 1037 avgdata_dc = None
1036 1038 n = None
1037 1039
1038 1040 self.putData(*args)
1039 1041
1040 1042 if (datatime - self.__initime) >= self.__integrationtime:
1041 1043 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1042 1044 self.n = n
1043 1045 self.__dataReady = True
1044 1046
1045 1047 return avgdata_spc, avgdata_cspc, avgdata_dc
1046 1048
1047 1049 def integrate(self, datatime, *args):
1048 1050
1049 1051 if self.__initime == None:
1050 1052 self.__initime = datatime
1051 1053
1052 1054 if self.__byTime:
1053 1055 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(datatime, *args)
1054 1056 else:
1055 1057 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1056 1058
1057 1059 self.__lastdatatime = datatime
1058 1060
1059 1061 if avgdata_spc == None:
1060 1062 return None, None, None, None
1061 1063
1062 1064 avgdatatime = self.__initime
1063 1065
1064 1066 deltatime = datatime -self.__lastdatatime
1065 1067
1066 1068 if not self.__withOverapping:
1067 1069 self.__initime = datatime
1068 1070 else:
1069 1071 self.__initime += deltatime
1070 1072
1071 1073 return avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc
1072 1074
1073 1075 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1074 1076
1075 1077 if not self.__isConfig:
1076 1078 self.setup(n, timeInterval, overlapping)
1077 1079 self.__isConfig = True
1078 1080
1079 1081 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1080 1082 dataOut.data_spc,
1081 1083 dataOut.data_cspc,
1082 1084 dataOut.data_dc)
1083 1085
1084 1086 # dataOut.timeInterval *= n
1085 1087 dataOut.flagNoData = True
1086 1088
1087 1089 if self.__dataReady:
1088 1090
1089 dataOut.data_spc = avgdata_spc / self.n
1090 dataOut.data_cspc = avgdata_cspc / self.n
1091 dataOut.data_dc = avgdata_dc / self.n
1091 dataOut.data_spc = avgdata_spc
1092 dataOut.data_cspc = avgdata_cspc
1093 dataOut.data_dc = avgdata_dc
1092 1094
1093 1095 dataOut.nIncohInt *= self.n
1094 1096 dataOut.utctime = avgdatatime
1095 1097 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt * dataOut.nIncohInt * dataOut.nFFTPoints
1096 1098 dataOut.flagNoData = False
1097 1099
1098 1100 class ProfileSelector(Operation):
1099 1101
1100 1102 profileIndex = None
1101 1103 # Tamanho total de los perfiles
1102 1104 nProfiles = None
1103 1105
1104 1106 def __init__(self):
1105 1107
1106 1108 self.profileIndex = 0
1107 1109
1108 1110 def incIndex(self):
1109 1111 self.profileIndex += 1
1110 1112
1111 1113 if self.profileIndex >= self.nProfiles:
1112 1114 self.profileIndex = 0
1113 1115
1114 1116 def isProfileInRange(self, minIndex, maxIndex):
1115 1117
1116 1118 if self.profileIndex < minIndex:
1117 1119 return False
1118 1120
1119 1121 if self.profileIndex > maxIndex:
1120 1122 return False
1121 1123
1122 1124 return True
1123 1125
1124 1126 def isProfileInList(self, profileList):
1125 1127
1126 1128 if self.profileIndex not in profileList:
1127 1129 return False
1128 1130
1129 1131 return True
1130 1132
1131 1133 def run(self, dataOut, profileList=None, profileRangeList=None):
1132 1134
1133 1135 dataOut.flagNoData = True
1134 1136 self.nProfiles = dataOut.nProfiles
1135 1137
1136 1138 if profileList != None:
1137 1139 if self.isProfileInList(profileList):
1138 1140 dataOut.flagNoData = False
1139 1141
1140 1142 self.incIndex()
1141 1143 return 1
1142 1144
1143 1145
1144 1146 elif profileRangeList != None:
1145 1147 minIndex = profileRangeList[0]
1146 1148 maxIndex = profileRangeList[1]
1147 1149 if self.isProfileInRange(minIndex, maxIndex):
1148 1150 dataOut.flagNoData = False
1149 1151
1150 1152 self.incIndex()
1151 1153 return 1
1152 1154
1153 1155 else:
1154 1156 raise ValueError, "ProfileSelector needs profileList or profileRangeList"
1155 1157
1156 1158 return 0
1157 1159
General Comments 0
You need to be logged in to leave comments. Login now