##// END OF EJS Templates
Optimizacion de Salvado de Spectros...
Daniel Valdez -
r404:334499cc45be
parent child
Show More
@@ -1,383 +1,383
1 1 import numpy
2 2 import datetime
3 3 import sys
4 4 import matplotlib
5 5
6 6 if 'linux' in sys.platform:
7 7 matplotlib.use("TKAgg")
8 8
9 9 if 'darwin' in sys.platform:
10 10 matplotlib.use("GTKAgg")
11 11
12 12 import matplotlib.pyplot
13 13
14 14 from mpl_toolkits.axes_grid1 import make_axes_locatable
15 15 from matplotlib.ticker import *
16 16
17 17 ###########################################
18 18 #Actualizacion de las funciones del driver
19 19 ###########################################
20 20
21 21 def createFigure(id, wintitle, width, height, facecolor="w", show=True):
22 22
23 23 matplotlib.pyplot.ioff()
24 24 fig = matplotlib.pyplot.figure(num=id, facecolor=facecolor)
25 25 fig.canvas.manager.set_window_title(wintitle)
26 26 fig.canvas.manager.resize(width, height)
27 27 matplotlib.pyplot.ion()
28 28 if show:
29 29 matplotlib.pyplot.show()
30 30
31 31 return fig
32 32
33 33 def closeFigure(show=True):
34 34
35 35 matplotlib.pyplot.ioff()
36 36 if show:
37 37 matplotlib.pyplot.show()
38 38
39 39 return
40 40
41 41 def saveFigure(fig, filename):
42 42
43 43 matplotlib.pyplot.ioff()
44 44 fig.savefig(filename)
45 45 matplotlib.pyplot.ion()
46 46
47 47 def setWinTitle(fig, title):
48 48
49 49 fig.canvas.manager.set_window_title(title)
50 50
51 51 def setTitle(fig, title):
52 52
53 53 fig.suptitle(title)
54 54
55 55 def createAxes(fig, nrow, ncol, xpos, ypos, colspan, rowspan):
56 56
57 57 matplotlib.pyplot.ioff()
58 58 matplotlib.pyplot.figure(fig.number)
59 59 axes = matplotlib.pyplot.subplot2grid((nrow, ncol),
60 60 (xpos, ypos),
61 61 colspan=colspan,
62 62 rowspan=rowspan)
63 63
64 64 matplotlib.pyplot.ion()
65 65 return axes
66 66
67 67 def setAxesText(ax, text):
68 68
69 69 ax.annotate(text,
70 70 xy = (.1, .99),
71 71 xycoords = 'figure fraction',
72 72 horizontalalignment = 'left',
73 73 verticalalignment = 'top',
74 74 fontsize = 10)
75 75
76 76 def printLabels(ax, xlabel, ylabel, title):
77 77
78 78 ax.set_xlabel(xlabel, size=11)
79 79 ax.set_ylabel(ylabel, size=11)
80 80 ax.set_title(title, size=12)
81 81
82 82 def createPline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='',
83 83 ticksize=9, xtick_visible=True, ytick_visible=True,
84 84 nxticks=4, nyticks=10,
85 85 grid=None):
86 86
87 87 """
88 88
89 89 Input:
90 90 grid : None, 'both', 'x', 'y'
91 91 """
92 92
93 93 matplotlib.pyplot.ioff()
94 94
95 95 ax.set_xlim([xmin,xmax])
96 96 ax.set_ylim([ymin,ymax])
97 97
98 98 printLabels(ax, xlabel, ylabel, title)
99 99
100 100 ######################################################
101 101 if (xmax-xmin)<=1:
102 102 xtickspos = numpy.linspace(xmin,xmax,nxticks)
103 103 xtickspos = numpy.array([float("%.1f"%i) for i in xtickspos])
104 104 ax.set_xticks(xtickspos)
105 105 else:
106 106 xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin)
107 107 # xtickspos = numpy.arange(nxticks)*float(xmax-xmin)/float(nxticks) + int(xmin)
108 108 ax.set_xticks(xtickspos)
109 109
110 110 for tick in ax.get_xticklabels():
111 111 tick.set_visible(xtick_visible)
112 112
113 113 for tick in ax.xaxis.get_major_ticks():
114 114 tick.label.set_fontsize(ticksize)
115 115
116 116 ######################################################
117 117 for tick in ax.get_yticklabels():
118 118 tick.set_visible(ytick_visible)
119 119
120 120 for tick in ax.yaxis.get_major_ticks():
121 121 tick.label.set_fontsize(ticksize)
122 122
123 123 ax.plot(x, y)
124 124 iplot = ax.lines[-1]
125 125
126 126 ######################################################
127 127 if '0.' in matplotlib.__version__[0:2]:
128 128 print "The matplotlib version has to be updated to 1.1 or newer"
129 129 return iplot
130 130
131 131 if '1.0.' in matplotlib.__version__[0:4]:
132 132 print "The matplotlib version has to be updated to 1.1 or newer"
133 133 return iplot
134 134
135 135 if grid != None:
136 136 ax.grid(b=True, which='major', axis=grid)
137 137
138 138 matplotlib.pyplot.tight_layout()
139 139
140 140 matplotlib.pyplot.ion()
141 141
142 142 return iplot
143 143
144 144 def set_linedata(ax, x, y, idline):
145 145
146 146 ax.lines[idline].set_data(x,y)
147 147
148 148 def pline(iplot, x, y, xlabel='', ylabel='', title=''):
149 149
150 150 ax = iplot.get_axes()
151 151
152 152 printLabels(ax, xlabel, ylabel, title)
153 153
154 154 set_linedata(ax, x, y, idline=0)
155 155
156 156 def addpline(ax, x, y, color, linestyle, lw):
157 157
158 158 ax.plot(x,y,color=color,linestyle=linestyle,lw=lw)
159 159
160 160
161 161 def createPcolor(ax, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax,
162 162 xlabel='', ylabel='', title='', ticksize = 9,
163 163 colormap='jet',cblabel='', cbsize="5%",
164 164 XAxisAsTime=False):
165 165
166 166 matplotlib.pyplot.ioff()
167 167
168 168 divider = make_axes_locatable(ax)
169 169 ax_cb = divider.new_horizontal(size=cbsize, pad=0.05)
170 170 fig = ax.get_figure()
171 171 fig.add_axes(ax_cb)
172 172
173 173 ax.set_xlim([xmin,xmax])
174 174 ax.set_ylim([ymin,ymax])
175 175
176 176 printLabels(ax, xlabel, ylabel, title)
177 177
178 178 imesh = ax.pcolormesh(x,y,z.T, vmin=zmin, vmax=zmax, cmap=matplotlib.pyplot.get_cmap(colormap))
179 179 cb = matplotlib.pyplot.colorbar(imesh, cax=ax_cb)
180 180 cb.set_label(cblabel)
181 181
182 182 # for tl in ax_cb.get_yticklabels():
183 183 # tl.set_visible(True)
184 184
185 185 for tick in ax.yaxis.get_major_ticks():
186 186 tick.label.set_fontsize(ticksize)
187 187
188 188 for tick in ax.xaxis.get_major_ticks():
189 189 tick.label.set_fontsize(ticksize)
190 190
191 191 for tick in cb.ax.get_yticklabels():
192 192 tick.set_fontsize(ticksize)
193 193
194 194 ax_cb.yaxis.tick_right()
195 195
196 196 if '0.' in matplotlib.__version__[0:2]:
197 197 print "The matplotlib version has to be updated to 1.1 or newer"
198 198 return imesh
199 199
200 200 if '1.0.' in matplotlib.__version__[0:4]:
201 201 print "The matplotlib version has to be updated to 1.1 or newer"
202 202 return imesh
203 203
204 204 matplotlib.pyplot.tight_layout()
205 205
206 206 if XAxisAsTime:
207 207
208 208 func = lambda x, pos: ('%s') %(datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S"))
209 209 ax.xaxis.set_major_formatter(FuncFormatter(func))
210 210 ax.xaxis.set_major_locator(LinearLocator(7))
211 211
212 212 matplotlib.pyplot.ion()
213 213 return imesh
214 214
215 215 def pcolor(imesh, z, xlabel='', ylabel='', title=''):
216 216
217 217 z = z.T
218 218
219 219 ax = imesh.get_axes()
220 220
221 221 printLabels(ax, xlabel, ylabel, title)
222 222
223 223 imesh.set_array(z.ravel())
224 224
225 225 def addpcolor(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', colormap='jet'):
226 226
227 227 printLabels(ax, xlabel, ylabel, title)
228 228
229 229 ax.pcolormesh(x,y,z.T,vmin=zmin,vmax=zmax, cmap=matplotlib.pyplot.get_cmap(colormap))
230 230
231 231 def addpcolorbuffer(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', colormap='jet'):
232 232
233 233 printLabels(ax, xlabel, ylabel, title)
234 234
235 235 ax.collections.remove(ax.collections[0])
236 236
237 237 ax.pcolormesh(x,y,z.T,vmin=zmin,vmax=zmax, cmap=matplotlib.pyplot.get_cmap(colormap))
238 238
239 239 def createPmultiline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None,
240 240 ticksize=9, xtick_visible=True, ytick_visible=True,
241 241 nxticks=4, nyticks=10,
242 242 grid=None):
243 243
244 244 """
245 245
246 246 Input:
247 247 grid : None, 'both', 'x', 'y'
248 248 """
249 249
250 250 matplotlib.pyplot.ioff()
251 251
252 252 lines = ax.plot(x.T, y)
253 253 leg = ax.legend(lines, legendlabels, loc='upper right')
254 254 leg.get_frame().set_alpha(0.5)
255 255 ax.set_xlim([xmin,xmax])
256 256 ax.set_ylim([ymin,ymax])
257 257 printLabels(ax, xlabel, ylabel, title)
258 258
259 259 xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin)
260 260 ax.set_xticks(xtickspos)
261 261
262 262 for tick in ax.get_xticklabels():
263 263 tick.set_visible(xtick_visible)
264 264
265 265 for tick in ax.xaxis.get_major_ticks():
266 266 tick.label.set_fontsize(ticksize)
267 267
268 268 for tick in ax.get_yticklabels():
269 269 tick.set_visible(ytick_visible)
270 270
271 271 for tick in ax.yaxis.get_major_ticks():
272 272 tick.label.set_fontsize(ticksize)
273 273
274 274 iplot = ax.lines[-1]
275 275
276 276 if '0.' in matplotlib.__version__[0:2]:
277 277 print "The matplotlib version has to be updated to 1.1 or newer"
278 278 return iplot
279 279
280 280 if '1.0.' in matplotlib.__version__[0:4]:
281 281 print "The matplotlib version has to be updated to 1.1 or newer"
282 282 return iplot
283 283
284 284 if grid != None:
285 285 ax.grid(b=True, which='major', axis=grid)
286 286
287 287 matplotlib.pyplot.tight_layout()
288 288
289 289 matplotlib.pyplot.ion()
290 290
291 291 return iplot
292 292
293 293
294 294 def pmultiline(iplot, x, y, xlabel='', ylabel='', title=''):
295 295
296 296 ax = iplot.get_axes()
297 297
298 298 printLabels(ax, xlabel, ylabel, title)
299 299
300 300 for i in range(len(ax.lines)):
301 301 line = ax.lines[i]
302 302 line.set_data(x[i,:],y)
303 303
304 304 def createPmultilineYAxis(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None,
305 305 ticksize=9, xtick_visible=True, ytick_visible=True,
306 306 nxticks=4, nyticks=10, marker='.', markersize=10, linestyle="None",
307 307 grid=None, XAxisAsTime=False):
308 308
309 309 """
310 310
311 311 Input:
312 312 grid : None, 'both', 'x', 'y'
313 313 """
314 314
315 315 matplotlib.pyplot.ioff()
316 316
317 317 # lines = ax.plot(x, y.T, marker=marker,markersize=markersize,linestyle=linestyle)
318 318 lines = ax.plot(x, y.T, linestyle='None', marker='.', markersize=markersize)
319 319 leg = ax.legend(lines, legendlabels, loc='upper left', bbox_to_anchor=(1.01, 1.00), numpoints=1, handlelength=1.5, \
320 320 handletextpad=0.5, borderpad=0.5, labelspacing=0.5, borderaxespad=0.)
321 321
322 322 for label in leg.get_texts(): label.set_fontsize(9)
323 323
324 324 ax.set_xlim([xmin,xmax])
325 325 ax.set_ylim([ymin,ymax])
326 326 printLabels(ax, xlabel, ylabel, title)
327 327
328 328 # xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin)
329 329 # ax.set_xticks(xtickspos)
330 330
331 331 for tick in ax.get_xticklabels():
332 332 tick.set_visible(xtick_visible)
333 333
334 334 for tick in ax.xaxis.get_major_ticks():
335 335 tick.label.set_fontsize(ticksize)
336 336
337 337 for tick in ax.get_yticklabels():
338 338 tick.set_visible(ytick_visible)
339 339
340 340 for tick in ax.yaxis.get_major_ticks():
341 341 tick.label.set_fontsize(ticksize)
342 342
343 343 iplot = ax.lines[-1]
344 344
345 345 if '0.' in matplotlib.__version__[0:2]:
346 346 print "The matplotlib version has to be updated to 1.1 or newer"
347 347 return iplot
348 348
349 349 if '1.0.' in matplotlib.__version__[0:4]:
350 350 print "The matplotlib version has to be updated to 1.1 or newer"
351 351 return iplot
352 352
353 353 if grid != None:
354 354 ax.grid(b=True, which='major', axis=grid)
355 355
356 356 matplotlib.pyplot.tight_layout()
357 357
358 358 if XAxisAsTime:
359 359
360 360 func = lambda x, pos: ('%s') %(datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S"))
361 361 ax.xaxis.set_major_formatter(FuncFormatter(func))
362 362 ax.xaxis.set_major_locator(LinearLocator(7))
363 363
364 364 matplotlib.pyplot.ion()
365 365
366 366 return iplot
367 367
368 368 def pmultilineyaxis(iplot, x, y, xlabel='', ylabel='', title=''):
369 369
370 370 ax = iplot.get_axes()
371 371
372 372 printLabels(ax, xlabel, ylabel, title)
373 373
374 374 for i in range(len(ax.lines)):
375 375 line = ax.lines[i]
376 376 line.set_data(x,y[i,:])
377 377
378 378 def draw(fig):
379 379
380 380 if type(fig) == 'int':
381 381 raise ValueError, "This parameter should be of tpye matplotlib figure"
382 382
383 fig.canvas.draw() No newline at end of file
383 fig.canvas.draw()
@@ -1,3372 +1,3378
1 1 '''
2 2
3 3 $Author: murco $
4 4 $Id: JRODataIO.py 169 2012-11-19 21:57:03Z murco $
5 5 '''
6 6
7 7 import os, sys
8 8 import glob
9 9 import time
10 10 import numpy
11 11 import fnmatch
12 12 import time, datetime
13 13 from xml.etree.ElementTree import Element, SubElement, ElementTree
14 14 try:
15 15 import pyfits
16 16 except:
17 17 print "pyfits module has not been imported, it should be installed to save files in fits format"
18 18
19 19 from jrodata import *
20 20 from jroheaderIO import *
21 21 from jroprocessing import *
22 22
23 23 LOCALTIME = True #-18000
24 24
25 25 def isNumber(str):
26 26 """
27 27 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
28 28
29 29 Excepciones:
30 30 Si un determinado string no puede ser convertido a numero
31 31 Input:
32 32 str, string al cual se le analiza para determinar si convertible a un numero o no
33 33
34 34 Return:
35 35 True : si el string es uno numerico
36 36 False : no es un string numerico
37 37 """
38 38 try:
39 39 float( str )
40 40 return True
41 41 except:
42 42 return False
43 43
44 44 def isThisFileinRange(filename, startUTSeconds, endUTSeconds):
45 45 """
46 46 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
47 47
48 48 Inputs:
49 49 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
50 50
51 51 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
52 52 segundos contados desde 01/01/1970.
53 53 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
54 54 segundos contados desde 01/01/1970.
55 55
56 56 Return:
57 57 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
58 58 fecha especificado, de lo contrario retorna False.
59 59
60 60 Excepciones:
61 61 Si el archivo no existe o no puede ser abierto
62 62 Si la cabecera no puede ser leida.
63 63
64 64 """
65 65 basicHeaderObj = BasicHeader(LOCALTIME)
66 66
67 67 try:
68 68 fp = open(filename,'rb')
69 69 except:
70 70 raise IOError, "The file %s can't be opened" %(filename)
71 71
72 72 sts = basicHeaderObj.read(fp)
73 73 fp.close()
74 74
75 75 if not(sts):
76 76 print "Skipping the file %s because it has not a valid header" %(filename)
77 77 return 0
78 78
79 79 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
80 80 return 0
81 81
82 82 return 1
83 83
84 84 def isFileinThisTime(filename, startTime, endTime):
85 85 """
86 86 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
87 87
88 88 Inputs:
89 89 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
90 90
91 91 startTime : tiempo inicial del rango seleccionado en formato datetime.time
92 92
93 93 endTime : tiempo final del rango seleccionado en formato datetime.time
94 94
95 95 Return:
96 96 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
97 97 fecha especificado, de lo contrario retorna False.
98 98
99 99 Excepciones:
100 100 Si el archivo no existe o no puede ser abierto
101 101 Si la cabecera no puede ser leida.
102 102
103 103 """
104 104
105 105
106 106 try:
107 107 fp = open(filename,'rb')
108 108 except:
109 109 raise IOError, "The file %s can't be opened" %(filename)
110 110
111 111 basicHeaderObj = BasicHeader(LOCALTIME)
112 112 sts = basicHeaderObj.read(fp)
113 113 fp.close()
114 114
115 115 thisDatetime = basicHeaderObj.datatime
116 116 thisTime = basicHeaderObj.datatime.time()
117 117
118 118 if not(sts):
119 119 print "Skipping the file %s because it has not a valid header" %(filename)
120 120 return None
121 121
122 122 if not ((startTime <= thisTime) and (endTime > thisTime)):
123 123 return None
124 124
125 125 return thisDatetime
126 126
127 127 def getFileFromSet(path,ext,set):
128 128 validFilelist = []
129 129 fileList = os.listdir(path)
130 130
131 131 # 0 1234 567 89A BCDE
132 132 # H YYYY DDD SSS .ext
133 133
134 134 for file in fileList:
135 135 try:
136 136 year = int(file[1:5])
137 137 doy = int(file[5:8])
138 138
139 139
140 140 except:
141 141 continue
142 142
143 143 if (os.path.splitext(file)[-1].lower() != ext.lower()):
144 144 continue
145 145
146 146 validFilelist.append(file)
147 147
148 148 myfile = fnmatch.filter(validFilelist,'*%4.4d%3.3d%3.3d*'%(year,doy,set))
149 149
150 150 if len(myfile)!= 0:
151 151 return myfile[0]
152 152 else:
153 153 filename = '*%4.4d%3.3d%3.3d%s'%(year,doy,set,ext.lower())
154 154 print 'the filename %s does not exist'%filename
155 155 print '...going to the last file: '
156 156
157 157 if validFilelist:
158 158 validFilelist = sorted( validFilelist, key=str.lower )
159 159 return validFilelist[-1]
160 160
161 161 return None
162 162
163 163
164 164 def getlastFileFromPath(path, ext):
165 165 """
166 166 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
167 167 al final de la depuracion devuelve el ultimo file de la lista que quedo.
168 168
169 169 Input:
170 170 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
171 171 ext : extension de los files contenidos en una carpeta
172 172
173 173 Return:
174 174 El ultimo file de una determinada carpeta, no se considera el path.
175 175 """
176 176 validFilelist = []
177 177 fileList = os.listdir(path)
178 178
179 179 # 0 1234 567 89A BCDE
180 180 # H YYYY DDD SSS .ext
181 181
182 182 for file in fileList:
183 183 try:
184 184 year = int(file[1:5])
185 185 doy = int(file[5:8])
186 186
187 187
188 188 except:
189 189 continue
190 190
191 191 if (os.path.splitext(file)[-1].lower() != ext.lower()):
192 192 continue
193 193
194 194 validFilelist.append(file)
195 195
196 196 if validFilelist:
197 197 validFilelist = sorted( validFilelist, key=str.lower )
198 198 return validFilelist[-1]
199 199
200 200 return None
201 201
202 202 def checkForRealPath(path, foldercounter, year, doy, set, ext):
203 203 """
204 204 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
205 205 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
206 206 el path exacto de un determinado file.
207 207
208 208 Example :
209 209 nombre correcto del file es .../.../D2009307/P2009307367.ext
210 210
211 211 Entonces la funcion prueba con las siguientes combinaciones
212 212 .../.../y2009307367.ext
213 213 .../.../Y2009307367.ext
214 214 .../.../x2009307/y2009307367.ext
215 215 .../.../x2009307/Y2009307367.ext
216 216 .../.../X2009307/y2009307367.ext
217 217 .../.../X2009307/Y2009307367.ext
218 218 siendo para este caso, la ultima combinacion de letras, identica al file buscado
219 219
220 220 Return:
221 221 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
222 222 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
223 223 para el filename
224 224 """
225 225 fullfilename = None
226 226 find_flag = False
227 227 filename = None
228 228
229 229 prefixDirList = [None,'d','D']
230 230 if ext.lower() == ".r": #voltage
231 231 prefixFileList = ['d','D']
232 232 elif ext.lower() == ".pdata": #spectra
233 233 prefixFileList = ['p','P']
234 234 else:
235 235 return None, filename
236 236
237 237 #barrido por las combinaciones posibles
238 238 for prefixDir in prefixDirList:
239 239 thispath = path
240 240 if prefixDir != None:
241 241 #formo el nombre del directorio xYYYYDDD (x=d o x=D)
242 242 if foldercounter == 0:
243 243 thispath = os.path.join(path, "%s%04d%03d" % ( prefixDir, year, doy ))
244 244 else:
245 245 thispath = os.path.join(path, "%s%04d%03d_%02d" % ( prefixDir, year, doy , foldercounter))
246 246 for prefixFile in prefixFileList: #barrido por las dos combinaciones posibles de "D"
247 247 filename = "%s%04d%03d%03d%s" % ( prefixFile, year, doy, set, ext ) #formo el nombre del file xYYYYDDDSSS.ext
248 248 fullfilename = os.path.join( thispath, filename ) #formo el path completo
249 249
250 250 if os.path.exists( fullfilename ): #verifico que exista
251 251 find_flag = True
252 252 break
253 253 if find_flag:
254 254 break
255 255
256 256 if not(find_flag):
257 257 return None, filename
258 258
259 259 return fullfilename, filename
260 260
261 261 def isDoyFolder(folder):
262 262 try:
263 263 year = int(folder[1:5])
264 264 except:
265 265 return 0
266 266
267 267 try:
268 268 doy = int(folder[5:8])
269 269 except:
270 270 return 0
271 271
272 272 return 1
273 273
274 274 class JRODataIO:
275 275
276 276 c = 3E8
277 277
278 278 isConfig = False
279 279
280 280 basicHeaderObj = BasicHeader(LOCALTIME)
281 281
282 282 systemHeaderObj = SystemHeader()
283 283
284 284 radarControllerHeaderObj = RadarControllerHeader()
285 285
286 286 processingHeaderObj = ProcessingHeader()
287 287
288 288 online = 0
289 289
290 290 dtype = None
291 291
292 292 pathList = []
293 293
294 294 filenameList = []
295 295
296 296 filename = None
297 297
298 298 ext = None
299 299
300 300 flagIsNewFile = 1
301 301
302 302 flagTimeBlock = 0
303 303
304 304 flagIsNewBlock = 0
305 305
306 306 fp = None
307 307
308 308 firstHeaderSize = 0
309 309
310 310 basicHeaderSize = 24
311 311
312 312 versionFile = 1103
313 313
314 314 fileSize = None
315 315
316 316 ippSeconds = None
317 317
318 318 fileSizeByHeader = None
319 319
320 320 fileIndex = None
321 321
322 322 profileIndex = None
323 323
324 324 blockIndex = None
325 325
326 326 nTotalBlocks = None
327 327
328 328 maxTimeStep = 30
329 329
330 330 lastUTTime = None
331 331
332 332 datablock = None
333 333
334 334 dataOut = None
335 335
336 336 blocksize = None
337 337
338 338 def __init__(self):
339 339
340 340 raise ValueError, "Not implemented"
341 341
342 342 def run(self):
343 343
344 344 raise ValueError, "Not implemented"
345 345
346 346 def getOutput(self):
347 347
348 348 return self.dataOut
349 349
350 350 class JRODataReader(JRODataIO, ProcessingUnit):
351 351
352 352 nReadBlocks = 0
353 353
354 354 delay = 10 #number of seconds waiting a new file
355 355
356 356 nTries = 3 #quantity tries
357 357
358 358 nFiles = 3 #number of files for searching
359 359
360 360 path = None
361 361
362 362 foldercounter = 0
363 363
364 364 flagNoMoreFiles = 0
365 365
366 366 datetimeList = []
367 367
368 368 __isFirstTimeOnline = 1
369 369
370 370 __printInfo = True
371 371
372 372 profileIndex = None
373 373
374 374 def __init__(self):
375 375
376 376 """
377 377
378 378 """
379 379
380 380 raise ValueError, "This method has not been implemented"
381 381
382 382
383 383 def createObjByDefault(self):
384 384 """
385 385
386 386 """
387 387 raise ValueError, "This method has not been implemented"
388 388
389 389 def getBlockDimension(self):
390 390
391 391 raise ValueError, "No implemented"
392 392
393 393 def __searchFilesOffLine(self,
394 394 path,
395 395 startDate,
396 396 endDate,
397 397 startTime=datetime.time(0,0,0),
398 398 endTime=datetime.time(23,59,59),
399 399 set=None,
400 400 expLabel='',
401 401 ext='.r',
402 402 walk=True):
403 403
404 404 pathList = []
405 405
406 406 if not walk:
407 407 pathList.append(path)
408 408
409 409 else:
410 410 dirList = []
411 411 for thisPath in os.listdir(path):
412 412 if not os.path.isdir(os.path.join(path,thisPath)):
413 413 continue
414 414 if not isDoyFolder(thisPath):
415 415 continue
416 416
417 417 dirList.append(thisPath)
418 418
419 419 if not(dirList):
420 420 return None, None
421 421
422 422 thisDate = startDate
423 423
424 424 while(thisDate <= endDate):
425 425 year = thisDate.timetuple().tm_year
426 426 doy = thisDate.timetuple().tm_yday
427 427
428 428 matchlist = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy) + '*')
429 429 if len(matchlist) == 0:
430 430 thisDate += datetime.timedelta(1)
431 431 continue
432 432 for match in matchlist:
433 433 pathList.append(os.path.join(path,match,expLabel))
434 434
435 435 thisDate += datetime.timedelta(1)
436 436
437 437 if pathList == []:
438 438 print "Any folder was found for the date range: %s-%s" %(startDate, endDate)
439 439 return None, None
440 440
441 441 print "%d folder(s) was(were) found for the date range: %s - %s" %(len(pathList), startDate, endDate)
442 442
443 443 filenameList = []
444 444 datetimeList = []
445 445
446 446 for i in range(len(pathList)):
447 447
448 448 thisPath = pathList[i]
449 449
450 450 fileList = glob.glob1(thisPath, "*%s" %ext)
451 451 fileList.sort()
452 452
453 453 for file in fileList:
454 454
455 455 filename = os.path.join(thisPath,file)
456 456 thisDatetime = isFileinThisTime(filename, startTime, endTime)
457 457
458 458 if not(thisDatetime):
459 459 continue
460 460
461 461 filenameList.append(filename)
462 462 datetimeList.append(thisDatetime)
463 463
464 464 if not(filenameList):
465 465 print "Any file was found for the time range %s - %s" %(startTime, endTime)
466 466 return None, None
467 467
468 468 print "%d file(s) was(were) found for the time range: %s - %s" %(len(filenameList), startTime, endTime)
469 469 print
470 470
471 471 for i in range(len(filenameList)):
472 472 print "%s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
473 473
474 474 self.filenameList = filenameList
475 475 self.datetimeList = datetimeList
476 476
477 477 return pathList, filenameList
478 478
479 479 def __searchFilesOnLine(self, path, expLabel = "", ext = None, walk=True, set=None):
480 480
481 481 """
482 482 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
483 483 devuelve el archivo encontrado ademas de otros datos.
484 484
485 485 Input:
486 486 path : carpeta donde estan contenidos los files que contiene data
487 487
488 488 expLabel : Nombre del subexperimento (subfolder)
489 489
490 490 ext : extension de los files
491 491
492 492 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
493 493
494 494 Return:
495 495 directory : eL directorio donde esta el file encontrado
496 496 filename : el ultimo file de una determinada carpeta
497 497 year : el anho
498 498 doy : el numero de dia del anho
499 499 set : el set del archivo
500 500
501 501
502 502 """
503 503 dirList = []
504 504
505 505 if not walk:
506 506 fullpath = path
507 507 foldercounter = 0
508 508 else:
509 509 #Filtra solo los directorios
510 510 for thisPath in os.listdir(path):
511 511 if not os.path.isdir(os.path.join(path,thisPath)):
512 512 continue
513 513 if not isDoyFolder(thisPath):
514 514 continue
515 515
516 516 dirList.append(thisPath)
517 517
518 518 if not(dirList):
519 519 return None, None, None, None, None, None
520 520
521 521 dirList = sorted( dirList, key=str.lower )
522 522
523 523 doypath = dirList[-1]
524 524 foldercounter = int(doypath.split('_')[1]) if len(doypath.split('_'))>1 else 0
525 525 fullpath = os.path.join(path, doypath, expLabel)
526 526
527 527
528 528 print "%s folder was found: " %(fullpath )
529 529
530 530 if set == None:
531 531 filename = getlastFileFromPath(fullpath, ext)
532 532 else:
533 533 filename = getFileFromSet(fullpath, ext, set)
534 534
535 535 if not(filename):
536 536 return None, None, None, None, None, None
537 537
538 538 print "%s file was found" %(filename)
539 539
540 540 if not(self.__verifyFile(os.path.join(fullpath, filename))):
541 541 return None, None, None, None, None, None
542 542
543 543 year = int( filename[1:5] )
544 544 doy = int( filename[5:8] )
545 545 set = int( filename[8:11] )
546 546
547 547 return fullpath, foldercounter, filename, year, doy, set
548 548
549 549 def __setNextFileOffline(self):
550 550
551 551 idFile = self.fileIndex
552 552
553 553 while (True):
554 554 idFile += 1
555 555 if not(idFile < len(self.filenameList)):
556 556 self.flagNoMoreFiles = 1
557 557 print "No more Files"
558 558 return 0
559 559
560 560 filename = self.filenameList[idFile]
561 561
562 562 if not(self.__verifyFile(filename)):
563 563 continue
564 564
565 565 fileSize = os.path.getsize(filename)
566 566 fp = open(filename,'rb')
567 567 break
568 568
569 569 self.flagIsNewFile = 1
570 570 self.fileIndex = idFile
571 571 self.filename = filename
572 572 self.fileSize = fileSize
573 573 self.fp = fp
574 574
575 575 print "Setting the file: %s"%self.filename
576 576
577 577 return 1
578 578
579 579 def __setNextFileOnline(self):
580 580 """
581 581 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
582 582 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
583 583 siguientes.
584 584
585 585 Affected:
586 586 self.flagIsNewFile
587 587 self.filename
588 588 self.fileSize
589 589 self.fp
590 590 self.set
591 591 self.flagNoMoreFiles
592 592
593 593 Return:
594 594 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
595 595 1 : si el file fue abierto con exito y esta listo a ser leido
596 596
597 597 Excepciones:
598 598 Si un determinado file no puede ser abierto
599 599 """
600 600 nFiles = 0
601 601 fileOk_flag = False
602 602 firstTime_flag = True
603 603
604 604 self.set += 1
605 605
606 606 if self.set > 999:
607 607 self.set = 0
608 608 self.foldercounter += 1
609 609
610 610 #busca el 1er file disponible
611 611 fullfilename, filename = checkForRealPath( self.path, self.foldercounter, self.year, self.doy, self.set, self.ext )
612 612 if fullfilename:
613 613 if self.__verifyFile(fullfilename, False):
614 614 fileOk_flag = True
615 615
616 616 #si no encuentra un file entonces espera y vuelve a buscar
617 617 if not(fileOk_flag):
618 618 for nFiles in range(self.nFiles+1): #busco en los siguientes self.nFiles+1 files posibles
619 619
620 620 if firstTime_flag: #si es la 1era vez entonces hace el for self.nTries veces
621 621 tries = self.nTries
622 622 else:
623 623 tries = 1 #si no es la 1era vez entonces solo lo hace una vez
624 624
625 625 for nTries in range( tries ):
626 626 if firstTime_flag:
627 627 print "\tWaiting %0.2f sec for the file \"%s\" , try %03d ..." % ( self.delay, filename, nTries+1 )
628 628 time.sleep( self.delay )
629 629 else:
630 630 print "\tSearching next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext)
631 631
632 632 fullfilename, filename = checkForRealPath( self.path, self.foldercounter, self.year, self.doy, self.set, self.ext )
633 633 if fullfilename:
634 634 if self.__verifyFile(fullfilename):
635 635 fileOk_flag = True
636 636 break
637 637
638 638 if fileOk_flag:
639 639 break
640 640
641 641 firstTime_flag = False
642 642
643 643 print "\tSkipping the file \"%s\" due to this file doesn't exist" % filename
644 644 self.set += 1
645 645
646 646 if nFiles == (self.nFiles-1): #si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
647 647 self.set = 0
648 648 self.doy += 1
649 649 self.foldercounter = 0
650 650
651 651 if fileOk_flag:
652 652 self.fileSize = os.path.getsize( fullfilename )
653 653 self.filename = fullfilename
654 654 self.flagIsNewFile = 1
655 655 if self.fp != None: self.fp.close()
656 656 self.fp = open(fullfilename, 'rb')
657 657 self.flagNoMoreFiles = 0
658 658 print 'Setting the file: %s' % fullfilename
659 659 else:
660 660 self.fileSize = 0
661 661 self.filename = None
662 662 self.flagIsNewFile = 0
663 663 self.fp = None
664 664 self.flagNoMoreFiles = 1
665 665 print 'No more Files'
666 666
667 667 return fileOk_flag
668 668
669 669
670 670 def setNextFile(self):
671 671 if self.fp != None:
672 672 self.fp.close()
673 673
674 674 if self.online:
675 675 newFile = self.__setNextFileOnline()
676 676 else:
677 677 newFile = self.__setNextFileOffline()
678 678
679 679 if not(newFile):
680 680 return 0
681 681
682 682 self.__readFirstHeader()
683 683 self.nReadBlocks = 0
684 684 return 1
685 685
686 686 def __waitNewBlock(self):
687 687 """
688 688 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
689 689
690 690 Si el modo de lectura es OffLine siempre retorn 0
691 691 """
692 692 if not self.online:
693 693 return 0
694 694
695 695 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
696 696 return 0
697 697
698 698 currentPointer = self.fp.tell()
699 699
700 700 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
701 701
702 702 for nTries in range( self.nTries ):
703 703
704 704 self.fp.close()
705 705 self.fp = open( self.filename, 'rb' )
706 706 self.fp.seek( currentPointer )
707 707
708 708 self.fileSize = os.path.getsize( self.filename )
709 709 currentSize = self.fileSize - currentPointer
710 710
711 711 if ( currentSize >= neededSize ):
712 712 self.__rdBasicHeader()
713 713 return 1
714 714
715 715 if self.fileSize == self.fileSizeByHeader:
716 716 # self.flagEoF = True
717 717 return 0
718 718
719 719 print "\tWaiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1)
720 720 time.sleep( self.delay )
721 721
722 722
723 723 return 0
724 724
725 725 def __jumpToLastBlock(self):
726 726
727 727 if not(self.__isFirstTimeOnline):
728 728 return
729 729
730 730 csize = self.fileSize - self.fp.tell()
731 731 blocksize = self.processingHeaderObj.blockSize
732 732
733 733 #salta el primer bloque de datos
734 734 if csize > self.processingHeaderObj.blockSize:
735 735 self.fp.seek(self.fp.tell() + blocksize)
736 736 else:
737 737 return
738 738
739 739 csize = self.fileSize - self.fp.tell()
740 740 neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
741 741 while True:
742 742
743 743 if self.fp.tell()<self.fileSize:
744 744 self.fp.seek(self.fp.tell() + neededsize)
745 745 else:
746 746 self.fp.seek(self.fp.tell() - neededsize)
747 747 break
748 748
749 749 # csize = self.fileSize - self.fp.tell()
750 750 # neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
751 751 # factor = int(csize/neededsize)
752 752 # if factor > 0:
753 753 # self.fp.seek(self.fp.tell() + factor*neededsize)
754 754
755 755 self.flagIsNewFile = 0
756 756 self.__isFirstTimeOnline = 0
757 757
758 758
759 759 def __setNewBlock(self):
760 760
761 761 if self.fp == None:
762 762 return 0
763 763
764 764 if self.online:
765 765 self.__jumpToLastBlock()
766 766
767 767 if self.flagIsNewFile:
768 768 return 1
769 769
770 770 self.lastUTTime = self.basicHeaderObj.utc
771 771 currentSize = self.fileSize - self.fp.tell()
772 772 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
773 773
774 774 if (currentSize >= neededSize):
775 775 self.__rdBasicHeader()
776 776 return 1
777 777
778 778 if self.__waitNewBlock():
779 779 return 1
780 780
781 781 if not(self.setNextFile()):
782 782 return 0
783 783
784 784 deltaTime = self.basicHeaderObj.utc - self.lastUTTime #
785 785
786 786 self.flagTimeBlock = 0
787 787
788 788 if deltaTime > self.maxTimeStep:
789 789 self.flagTimeBlock = 1
790 790
791 791 return 1
792 792
793 793
794 794 def readNextBlock(self):
795 795 if not(self.__setNewBlock()):
796 796 return 0
797 797
798 798 if not(self.readBlock()):
799 799 return 0
800 800
801 801 return 1
802 802
803 803 def __rdProcessingHeader(self, fp=None):
804 804 if fp == None:
805 805 fp = self.fp
806 806
807 807 self.processingHeaderObj.read(fp)
808 808
809 809 def __rdRadarControllerHeader(self, fp=None):
810 810 if fp == None:
811 811 fp = self.fp
812 812
813 813 self.radarControllerHeaderObj.read(fp)
814 814
815 815 def __rdSystemHeader(self, fp=None):
816 816 if fp == None:
817 817 fp = self.fp
818 818
819 819 self.systemHeaderObj.read(fp)
820 820
821 821 def __rdBasicHeader(self, fp=None):
822 822 if fp == None:
823 823 fp = self.fp
824 824
825 825 self.basicHeaderObj.read(fp)
826 826
827 827
828 828 def __readFirstHeader(self):
829 829 self.__rdBasicHeader()
830 830 self.__rdSystemHeader()
831 831 self.__rdRadarControllerHeader()
832 832 self.__rdProcessingHeader()
833 833
834 834 self.firstHeaderSize = self.basicHeaderObj.size
835 835
836 836 datatype = int(numpy.log2((self.processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
837 837 if datatype == 0:
838 838 datatype_str = numpy.dtype([('real','<i1'),('imag','<i1')])
839 839 elif datatype == 1:
840 840 datatype_str = numpy.dtype([('real','<i2'),('imag','<i2')])
841 841 elif datatype == 2:
842 842 datatype_str = numpy.dtype([('real','<i4'),('imag','<i4')])
843 843 elif datatype == 3:
844 844 datatype_str = numpy.dtype([('real','<i8'),('imag','<i8')])
845 845 elif datatype == 4:
846 846 datatype_str = numpy.dtype([('real','<f4'),('imag','<f4')])
847 847 elif datatype == 5:
848 848 datatype_str = numpy.dtype([('real','<f8'),('imag','<f8')])
849 849 else:
850 850 raise ValueError, 'Data type was not defined'
851 851
852 852 self.dtype = datatype_str
853 853 self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
854 854 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + self.firstHeaderSize + self.basicHeaderSize*(self.processingHeaderObj.dataBlocksPerFile - 1)
855 855 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
856 856 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
857 857 self.getBlockDimension()
858 858
859 859
860 860 def __verifyFile(self, filename, msgFlag=True):
861 861 msg = None
862 862 try:
863 863 fp = open(filename, 'rb')
864 864 currentPosition = fp.tell()
865 865 except:
866 866 if msgFlag:
867 867 print "The file %s can't be opened" % (filename)
868 868 return False
869 869
870 870 neededSize = self.processingHeaderObj.blockSize + self.firstHeaderSize
871 871
872 872 if neededSize == 0:
873 873 basicHeaderObj = BasicHeader(LOCALTIME)
874 874 systemHeaderObj = SystemHeader()
875 875 radarControllerHeaderObj = RadarControllerHeader()
876 876 processingHeaderObj = ProcessingHeader()
877 877
878 878 try:
879 879 if not( basicHeaderObj.read(fp) ): raise IOError
880 880 if not( systemHeaderObj.read(fp) ): raise IOError
881 881 if not( radarControllerHeaderObj.read(fp) ): raise IOError
882 882 if not( processingHeaderObj.read(fp) ): raise IOError
883 883 data_type = int(numpy.log2((processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR))
884 884
885 885 neededSize = processingHeaderObj.blockSize + basicHeaderObj.size
886 886
887 887 except:
888 888 if msgFlag:
889 889 print "\tThe file %s is empty or it hasn't enough data" % filename
890 890
891 891 fp.close()
892 892 return False
893 893 else:
894 894 msg = "\tSkipping the file %s due to it hasn't enough data" %filename
895 895
896 896 fp.close()
897 897 fileSize = os.path.getsize(filename)
898 898 currentSize = fileSize - currentPosition
899 899 if currentSize < neededSize:
900 900 if msgFlag and (msg != None):
901 901 print msg #print"\tSkipping the file %s due to it hasn't enough data" %filename
902 902 return False
903 903
904 904 return True
905 905
906 906 def setup(self,
907 907 path=None,
908 908 startDate=None,
909 909 endDate=None,
910 910 startTime=datetime.time(0,0,0),
911 911 endTime=datetime.time(23,59,59),
912 912 set=None,
913 913 expLabel = "",
914 914 ext = None,
915 915 online = False,
916 916 delay = 60,
917 917 walk = True):
918 918
919 919 if path == None:
920 920 raise ValueError, "The path is not valid"
921 921
922 922 if ext == None:
923 923 ext = self.ext
924 924
925 925 if online:
926 926 print "Searching files in online mode..."
927 927
928 928 for nTries in range( self.nTries ):
929 929 fullpath, foldercounter, file, year, doy, set = self.__searchFilesOnLine(path=path, expLabel=expLabel, ext=ext, walk=walk, set=set)
930 930
931 931 if fullpath:
932 932 break
933 933
934 934 print '\tWaiting %0.2f sec for an valid file in %s: try %02d ...' % (self.delay, path, nTries+1)
935 935 time.sleep( self.delay )
936 936
937 937 if not(fullpath):
938 938 print "There 'isn't valied files in %s" % path
939 939 return None
940 940
941 941 self.year = year
942 942 self.doy = doy
943 943 self.set = set - 1
944 944 self.path = path
945 945 self.foldercounter = foldercounter
946 946
947 947 else:
948 948 print "Searching files in offline mode ..."
949 949 pathList, filenameList = self.__searchFilesOffLine(path, startDate=startDate, endDate=endDate,
950 950 startTime=startTime, endTime=endTime,
951 951 set=set, expLabel=expLabel, ext=ext,
952 952 walk=walk)
953 953
954 954 if not(pathList):
955 955 print "No *%s files into the folder %s \nfor the range: %s - %s"%(ext, path,
956 956 datetime.datetime.combine(startDate,startTime).ctime(),
957 957 datetime.datetime.combine(endDate,endTime).ctime())
958 958
959 959 sys.exit(-1)
960 960
961 961
962 962 self.fileIndex = -1
963 963 self.pathList = pathList
964 964 self.filenameList = filenameList
965 965
966 966 self.online = online
967 967 self.delay = delay
968 968 ext = ext.lower()
969 969 self.ext = ext
970 970
971 971 if not(self.setNextFile()):
972 972 if (startDate!=None) and (endDate!=None):
973 973 print "No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
974 974 elif startDate != None:
975 975 print "No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime())
976 976 else:
977 977 print "No files"
978 978
979 979 sys.exit(-1)
980 980
981 981 # self.updateDataHeader()
982 982
983 983 return self.dataOut
984 984
985 985 def getBasicHeader(self):
986 986
987 987 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond/1000. + self.profileIndex * self.ippSeconds
988 988
989 989 self.dataOut.flagTimeBlock = self.flagTimeBlock
990 990
991 991 self.dataOut.timeZone = self.basicHeaderObj.timeZone
992 992
993 993 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
994 994
995 995 self.dataOut.errorCount = self.basicHeaderObj.errorCount
996 996
997 997 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
998 998
999 999 def getFirstHeader(self):
1000 1000
1001 1001 raise ValueError, "This method has not been implemented"
1002 1002
1003 1003 def getData():
1004 1004
1005 1005 raise ValueError, "This method has not been implemented"
1006 1006
1007 1007 def hasNotDataInBuffer():
1008 1008
1009 1009 raise ValueError, "This method has not been implemented"
1010 1010
1011 1011 def readBlock():
1012 1012
1013 1013 raise ValueError, "This method has not been implemented"
1014 1014
1015 1015 def isEndProcess(self):
1016 1016
1017 1017 return self.flagNoMoreFiles
1018 1018
1019 1019 def printReadBlocks(self):
1020 1020
1021 1021 print "Number of read blocks per file %04d" %self.nReadBlocks
1022 1022
1023 1023 def printTotalBlocks(self):
1024 1024
1025 1025 print "Number of read blocks %04d" %self.nTotalBlocks
1026 1026
1027 1027 def printNumberOfBlock(self):
1028 1028
1029 1029 if self.flagIsNewBlock:
1030 1030 print "Block No. %04d, Total blocks %04d -> %s" %(self.basicHeaderObj.dataBlock, self.nTotalBlocks, self.dataOut.datatime.ctime())
1031 1031
1032 1032 def printInfo(self):
1033 1033
1034 1034 if self.__printInfo == False:
1035 1035 return
1036 1036
1037 1037 self.basicHeaderObj.printInfo()
1038 1038 self.systemHeaderObj.printInfo()
1039 1039 self.radarControllerHeaderObj.printInfo()
1040 1040 self.processingHeaderObj.printInfo()
1041 1041
1042 1042 self.__printInfo = False
1043 1043
1044 1044
1045 1045 def run(self, **kwargs):
1046 1046
1047 1047 if not(self.isConfig):
1048 1048
1049 1049 # self.dataOut = dataOut
1050 1050 self.setup(**kwargs)
1051 1051 self.isConfig = True
1052 1052
1053 1053 self.getData()
1054 1054
1055 1055 class JRODataWriter(JRODataIO, Operation):
1056 1056
1057 1057 """
1058 1058 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1059 1059 de los datos siempre se realiza por bloques.
1060 1060 """
1061 1061
1062 1062 blockIndex = 0
1063 1063
1064 1064 path = None
1065 1065
1066 1066 setFile = None
1067 1067
1068 1068 profilesPerBlock = None
1069 1069
1070 1070 blocksPerFile = None
1071 1071
1072 1072 nWriteBlocks = 0
1073 1073
1074 1074 def __init__(self, dataOut=None):
1075 1075 raise ValueError, "Not implemented"
1076 1076
1077 1077
1078 1078 def hasAllDataInBuffer(self):
1079 1079 raise ValueError, "Not implemented"
1080 1080
1081 1081
1082 1082 def setBlockDimension(self):
1083 1083 raise ValueError, "Not implemented"
1084 1084
1085 1085
1086 1086 def writeBlock(self):
1087 1087 raise ValueError, "No implemented"
1088 1088
1089 1089
1090 1090 def putData(self):
1091 1091 raise ValueError, "No implemented"
1092 1092
1093 1093
1094 1094 def setBasicHeader(self):
1095 1095
1096 1096 self.basicHeaderObj.size = self.basicHeaderSize #bytes
1097 1097 self.basicHeaderObj.version = self.versionFile
1098 1098 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1099 1099
1100 1100 utc = numpy.floor(self.dataOut.utctime)
1101 1101 milisecond = (self.dataOut.utctime - utc)* 1000.0
1102 1102
1103 1103 self.basicHeaderObj.utc = utc
1104 1104 self.basicHeaderObj.miliSecond = milisecond
1105 1105 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1106 1106 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1107 1107 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1108 1108
1109 1109 def setFirstHeader(self):
1110 1110 """
1111 1111 Obtiene una copia del First Header
1112 1112
1113 1113 Affected:
1114 1114
1115 1115 self.basicHeaderObj
1116 1116 self.systemHeaderObj
1117 1117 self.radarControllerHeaderObj
1118 1118 self.processingHeaderObj self.
1119 1119
1120 1120 Return:
1121 1121 None
1122 1122 """
1123 1123
1124 1124 raise ValueError, "No implemented"
1125 1125
1126 1126 def __writeFirstHeader(self):
1127 1127 """
1128 1128 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1129 1129
1130 1130 Affected:
1131 1131 __dataType
1132 1132
1133 1133 Return:
1134 1134 None
1135 1135 """
1136 1136
1137 1137 # CALCULAR PARAMETROS
1138 1138
1139 1139 sizeLongHeader = self.systemHeaderObj.size + self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1140 1140 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1141 1141
1142 1142 self.basicHeaderObj.write(self.fp)
1143 1143 self.systemHeaderObj.write(self.fp)
1144 1144 self.radarControllerHeaderObj.write(self.fp)
1145 1145 self.processingHeaderObj.write(self.fp)
1146 1146
1147 1147 self.dtype = self.dataOut.dtype
1148 1148
1149 1149 def __setNewBlock(self):
1150 1150 """
1151 1151 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1152 1152
1153 1153 Return:
1154 1154 0 : si no pudo escribir nada
1155 1155 1 : Si escribio el Basic el First Header
1156 1156 """
1157 1157 if self.fp == None:
1158 1158 self.setNextFile()
1159 1159
1160 1160 if self.flagIsNewFile:
1161 1161 return 1
1162 1162
1163 1163 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1164 1164 self.basicHeaderObj.write(self.fp)
1165 1165 return 1
1166 1166
1167 1167 if not( self.setNextFile() ):
1168 1168 return 0
1169 1169
1170 1170 return 1
1171 1171
1172 1172
1173 1173 def writeNextBlock(self):
1174 1174 """
1175 1175 Selecciona el bloque siguiente de datos y los escribe en un file
1176 1176
1177 1177 Return:
1178 1178 0 : Si no hizo pudo escribir el bloque de datos
1179 1179 1 : Si no pudo escribir el bloque de datos
1180 1180 """
1181 1181 if not( self.__setNewBlock() ):
1182 1182 return 0
1183 1183
1184 1184 self.writeBlock()
1185 1185
1186 1186 return 1
1187 1187
1188 1188 def setNextFile(self):
1189 1189 """
1190 1190 Determina el siguiente file que sera escrito
1191 1191
1192 1192 Affected:
1193 1193 self.filename
1194 1194 self.subfolder
1195 1195 self.fp
1196 1196 self.setFile
1197 1197 self.flagIsNewFile
1198 1198
1199 1199 Return:
1200 1200 0 : Si el archivo no puede ser escrito
1201 1201 1 : Si el archivo esta listo para ser escrito
1202 1202 """
1203 1203 ext = self.ext
1204 1204 path = self.path
1205 1205
1206 1206 if self.fp != None:
1207 1207 self.fp.close()
1208 1208
1209 1209 timeTuple = time.localtime( self.dataOut.utctime)
1210 1210 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
1211 1211
1212 1212 fullpath = os.path.join( path, subfolder )
1213 1213 if not( os.path.exists(fullpath) ):
1214 1214 os.mkdir(fullpath)
1215 1215 self.setFile = -1 #inicializo mi contador de seteo
1216 1216 else:
1217 1217 filesList = os.listdir( fullpath )
1218 1218 if len( filesList ) > 0:
1219 1219 filesList = sorted( filesList, key=str.lower )
1220 1220 filen = filesList[-1]
1221 1221 # el filename debera tener el siguiente formato
1222 1222 # 0 1234 567 89A BCDE (hex)
1223 1223 # x YYYY DDD SSS .ext
1224 1224 if isNumber( filen[8:11] ):
1225 1225 self.setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
1226 1226 else:
1227 1227 self.setFile = -1
1228 1228 else:
1229 1229 self.setFile = -1 #inicializo mi contador de seteo
1230 1230
1231 1231 setFile = self.setFile
1232 1232 setFile += 1
1233 1233
1234 1234 file = '%s%4.4d%3.3d%3.3d%s' % (self.optchar,
1235 1235 timeTuple.tm_year,
1236 1236 timeTuple.tm_yday,
1237 1237 setFile,
1238 1238 ext )
1239 1239
1240 1240 filename = os.path.join( path, subfolder, file )
1241 1241
1242 1242 fp = open( filename,'wb' )
1243 1243
1244 1244 self.blockIndex = 0
1245 1245
1246 1246 #guardando atributos
1247 1247 self.filename = filename
1248 1248 self.subfolder = subfolder
1249 1249 self.fp = fp
1250 1250 self.setFile = setFile
1251 1251 self.flagIsNewFile = 1
1252 1252
1253 1253 self.setFirstHeader()
1254 1254
1255 1255 print 'Writing the file: %s'%self.filename
1256 1256
1257 1257 self.__writeFirstHeader()
1258 1258
1259 1259 return 1
1260 1260
1261 1261 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=None, set=0, ext=None):
1262 1262 """
1263 1263 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1264 1264
1265 1265 Inputs:
1266 1266 path : el path destino en el cual se escribiran los files a crear
1267 1267 format : formato en el cual sera salvado un file
1268 1268 set : el setebo del file
1269 1269
1270 1270 Return:
1271 1271 0 : Si no realizo un buen seteo
1272 1272 1 : Si realizo un buen seteo
1273 1273 """
1274 1274
1275 1275 if ext == None:
1276 1276 ext = self.ext
1277 1277
1278 1278 ext = ext.lower()
1279 1279
1280 1280 self.ext = ext
1281 1281
1282 1282 self.path = path
1283 1283
1284 1284 self.setFile = set - 1
1285 1285
1286 1286 self.blocksPerFile = blocksPerFile
1287 1287
1288 1288 self.profilesPerBlock = profilesPerBlock
1289 1289
1290 1290 self.dataOut = dataOut
1291 1291
1292 1292 if not(self.setNextFile()):
1293 1293 print "There isn't a next file"
1294 1294 return 0
1295 1295
1296 1296 self.setBlockDimension()
1297 1297
1298 1298 return 1
1299 1299
1300 1300 def run(self, dataOut, **kwargs):
1301 1301
1302 1302 if not(self.isConfig):
1303 1303
1304 1304 self.setup(dataOut, **kwargs)
1305 1305 self.isConfig = True
1306 1306
1307 1307 self.putData()
1308 1308
1309 1309 class VoltageReader(JRODataReader):
1310 1310 """
1311 1311 Esta clase permite leer datos de voltage desde archivos en formato rawdata (.r). La lectura
1312 1312 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones:
1313 1313 perfiles*alturas*canales) son almacenados en la variable "buffer".
1314 1314
1315 1315 perfiles * alturas * canales
1316 1316
1317 1317 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
1318 1318 RadarControllerHeader y Voltage. Los tres primeros se usan para almacenar informacion de la
1319 1319 cabecera de datos (metadata), y el cuarto (Voltage) para obtener y almacenar un perfil de
1320 1320 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
1321 1321
1322 1322 Example:
1323 1323
1324 1324 dpath = "/home/myuser/data"
1325 1325
1326 1326 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
1327 1327
1328 1328 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
1329 1329
1330 1330 readerObj = VoltageReader()
1331 1331
1332 1332 readerObj.setup(dpath, startTime, endTime)
1333 1333
1334 1334 while(True):
1335 1335
1336 1336 #to get one profile
1337 1337 profile = readerObj.getData()
1338 1338
1339 1339 #print the profile
1340 1340 print profile
1341 1341
1342 1342 #If you want to see all datablock
1343 1343 print readerObj.datablock
1344 1344
1345 1345 if readerObj.flagNoMoreFiles:
1346 1346 break
1347 1347
1348 1348 """
1349 1349
1350 1350 ext = ".r"
1351 1351
1352 1352 optchar = "D"
1353 1353 dataOut = None
1354 1354
1355 1355
1356 1356 def __init__(self):
1357 1357 """
1358 1358 Inicializador de la clase VoltageReader para la lectura de datos de voltage.
1359 1359
1360 1360 Input:
1361 1361 dataOut : Objeto de la clase Voltage. Este objeto sera utilizado para
1362 1362 almacenar un perfil de datos cada vez que se haga un requerimiento
1363 1363 (getData). El perfil sera obtenido a partir del buffer de datos,
1364 1364 si el buffer esta vacio se hara un nuevo proceso de lectura de un
1365 1365 bloque de datos.
1366 1366 Si este parametro no es pasado se creara uno internamente.
1367 1367
1368 1368 Variables afectadas:
1369 1369 self.dataOut
1370 1370
1371 1371 Return:
1372 1372 None
1373 1373 """
1374 1374
1375 1375 self.isConfig = False
1376 1376
1377 1377 self.datablock = None
1378 1378
1379 1379 self.utc = 0
1380 1380
1381 1381 self.ext = ".r"
1382 1382
1383 1383 self.optchar = "D"
1384 1384
1385 1385 self.basicHeaderObj = BasicHeader(LOCALTIME)
1386 1386
1387 1387 self.systemHeaderObj = SystemHeader()
1388 1388
1389 1389 self.radarControllerHeaderObj = RadarControllerHeader()
1390 1390
1391 1391 self.processingHeaderObj = ProcessingHeader()
1392 1392
1393 1393 self.online = 0
1394 1394
1395 1395 self.fp = None
1396 1396
1397 1397 self.idFile = None
1398 1398
1399 1399 self.dtype = None
1400 1400
1401 1401 self.fileSizeByHeader = None
1402 1402
1403 1403 self.filenameList = []
1404 1404
1405 1405 self.filename = None
1406 1406
1407 1407 self.fileSize = None
1408 1408
1409 1409 self.firstHeaderSize = 0
1410 1410
1411 1411 self.basicHeaderSize = 24
1412 1412
1413 1413 self.pathList = []
1414 1414
1415 1415 self.filenameList = []
1416 1416
1417 1417 self.lastUTTime = 0
1418 1418
1419 1419 self.maxTimeStep = 30
1420 1420
1421 1421 self.flagNoMoreFiles = 0
1422 1422
1423 1423 self.set = 0
1424 1424
1425 1425 self.path = None
1426 1426
1427 1427 self.profileIndex = 2**32-1
1428 1428
1429 1429 self.delay = 3 #seconds
1430 1430
1431 1431 self.nTries = 3 #quantity tries
1432 1432
1433 1433 self.nFiles = 3 #number of files for searching
1434 1434
1435 1435 self.nReadBlocks = 0
1436 1436
1437 1437 self.flagIsNewFile = 1
1438 1438
1439 1439 self.__isFirstTimeOnline = 1
1440 1440
1441 1441 self.ippSeconds = 0
1442 1442
1443 1443 self.flagTimeBlock = 0
1444 1444
1445 1445 self.flagIsNewBlock = 0
1446 1446
1447 1447 self.nTotalBlocks = 0
1448 1448
1449 1449 self.blocksize = 0
1450 1450
1451 1451 self.dataOut = self.createObjByDefault()
1452 1452
1453 1453 def createObjByDefault(self):
1454 1454
1455 1455 dataObj = Voltage()
1456 1456
1457 1457 return dataObj
1458 1458
1459 1459 def __hasNotDataInBuffer(self):
1460 1460 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock:
1461 1461 return 1
1462 1462 return 0
1463 1463
1464 1464
1465 1465 def getBlockDimension(self):
1466 1466 """
1467 1467 Obtiene la cantidad de puntos a leer por cada bloque de datos
1468 1468
1469 1469 Affected:
1470 1470 self.blocksize
1471 1471
1472 1472 Return:
1473 1473 None
1474 1474 """
1475 1475 pts2read = self.processingHeaderObj.profilesPerBlock * self.processingHeaderObj.nHeights * self.systemHeaderObj.nChannels
1476 1476 self.blocksize = pts2read
1477 1477
1478 1478
1479 1479 def readBlock(self):
1480 1480 """
1481 1481 readBlock lee el bloque de datos desde la posicion actual del puntero del archivo
1482 1482 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
1483 1483 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
1484 1484 es seteado a 0
1485 1485
1486 1486 Inputs:
1487 1487 None
1488 1488
1489 1489 Return:
1490 1490 None
1491 1491
1492 1492 Affected:
1493 1493 self.profileIndex
1494 1494 self.datablock
1495 1495 self.flagIsNewFile
1496 1496 self.flagIsNewBlock
1497 1497 self.nTotalBlocks
1498 1498
1499 1499 Exceptions:
1500 1500 Si un bloque leido no es un bloque valido
1501 1501 """
1502 1502
1503 1503 junk = numpy.fromfile( self.fp, self.dtype, self.blocksize )
1504 1504
1505 1505 try:
1506 1506 junk = junk.reshape( (self.processingHeaderObj.profilesPerBlock, self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels) )
1507 1507 except:
1508 1508 print "The read block (%3d) has not enough data" %self.nReadBlocks
1509 1509 return 0
1510 1510
1511 1511 junk = numpy.transpose(junk, (2,0,1))
1512 1512 self.datablock = junk['real'] + junk['imag']*1j
1513 1513
1514 1514 self.profileIndex = 0
1515 1515
1516 1516 self.flagIsNewFile = 0
1517 1517 self.flagIsNewBlock = 1
1518 1518
1519 1519 self.nTotalBlocks += 1
1520 1520 self.nReadBlocks += 1
1521 1521
1522 1522 return 1
1523 1523
1524 1524 def getFirstHeader(self):
1525 1525
1526 1526 self.dataOut.dtype = self.dtype
1527 1527
1528 1528 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
1529 1529
1530 1530 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
1531 1531
1532 1532 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
1533 1533
1534 1534 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
1535 1535
1536 1536 self.dataOut.ippSeconds = self.ippSeconds
1537 1537
1538 1538 self.dataOut.timeInterval = self.ippSeconds * self.processingHeaderObj.nCohInt
1539 1539
1540 1540 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
1541 1541
1542 1542 self.dataOut.flagShiftFFT = False
1543 1543
1544 1544 if self.radarControllerHeaderObj.code != None:
1545 1545
1546 1546 self.dataOut.nCode = self.radarControllerHeaderObj.nCode
1547 1547
1548 1548 self.dataOut.nBaud = self.radarControllerHeaderObj.nBaud
1549 1549
1550 1550 self.dataOut.code = self.radarControllerHeaderObj.code
1551 1551
1552 1552 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
1553 1553
1554 1554 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
1555 1555
1556 1556 self.dataOut.flagDecodeData = False #asumo q la data no esta decodificada
1557 1557
1558 1558 self.dataOut.flagDeflipData = False #asumo q la data no esta sin flip
1559 1559
1560 1560 self.dataOut.flagShiftFFT = False
1561 1561
1562 1562 def getData(self):
1563 1563 """
1564 1564 getData obtiene una unidad de datos del buffer de lectura y la copia a la clase "Voltage"
1565 1565 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
1566 1566 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
1567 1567
1568 1568 Ademas incrementa el contador del buffer en 1.
1569 1569
1570 1570 Return:
1571 1571 data : retorna un perfil de voltages (alturas * canales) copiados desde el
1572 1572 buffer. Si no hay mas archivos a leer retorna None.
1573 1573
1574 1574 Variables afectadas:
1575 1575 self.dataOut
1576 1576 self.profileIndex
1577 1577
1578 1578 Affected:
1579 1579 self.dataOut
1580 1580 self.profileIndex
1581 1581 self.flagTimeBlock
1582 1582 self.flagIsNewBlock
1583 1583 """
1584 1584
1585 1585 if self.flagNoMoreFiles:
1586 1586 self.dataOut.flagNoData = True
1587 1587 print 'Process finished'
1588 1588 return 0
1589 1589
1590 1590 self.flagTimeBlock = 0
1591 1591 self.flagIsNewBlock = 0
1592 1592
1593 1593 if self.__hasNotDataInBuffer():
1594 1594
1595 1595 if not( self.readNextBlock() ):
1596 1596 return 0
1597 1597
1598 1598 self.getFirstHeader()
1599 1599
1600 1600 if self.datablock == None:
1601 1601 self.dataOut.flagNoData = True
1602 1602 return 0
1603 1603
1604 1604 self.dataOut.data = self.datablock[:,self.profileIndex,:]
1605 1605
1606 1606 self.dataOut.flagNoData = False
1607 1607
1608 1608 self.getBasicHeader()
1609 1609
1610 1610 self.profileIndex += 1
1611 1611
1612 1612 self.dataOut.realtime = self.online
1613 1613
1614 1614 return self.dataOut.data
1615 1615
1616 1616
1617 1617 class VoltageWriter(JRODataWriter):
1618 1618 """
1619 1619 Esta clase permite escribir datos de voltajes a archivos procesados (.r). La escritura
1620 1620 de los datos siempre se realiza por bloques.
1621 1621 """
1622 1622
1623 1623 ext = ".r"
1624 1624
1625 1625 optchar = "D"
1626 1626
1627 1627 shapeBuffer = None
1628 1628
1629 1629
1630 1630 def __init__(self):
1631 1631 """
1632 1632 Inicializador de la clase VoltageWriter para la escritura de datos de espectros.
1633 1633
1634 1634 Affected:
1635 1635 self.dataOut
1636 1636
1637 1637 Return: None
1638 1638 """
1639 1639
1640 1640 self.nTotalBlocks = 0
1641 1641
1642 1642 self.profileIndex = 0
1643 1643
1644 1644 self.isConfig = False
1645 1645
1646 1646 self.fp = None
1647 1647
1648 1648 self.flagIsNewFile = 1
1649 1649
1650 1650 self.nTotalBlocks = 0
1651 1651
1652 1652 self.flagIsNewBlock = 0
1653 1653
1654 1654 self.setFile = None
1655 1655
1656 1656 self.dtype = None
1657 1657
1658 1658 self.path = None
1659 1659
1660 1660 self.filename = None
1661 1661
1662 1662 self.basicHeaderObj = BasicHeader(LOCALTIME)
1663 1663
1664 1664 self.systemHeaderObj = SystemHeader()
1665 1665
1666 1666 self.radarControllerHeaderObj = RadarControllerHeader()
1667 1667
1668 1668 self.processingHeaderObj = ProcessingHeader()
1669 1669
1670 1670 def hasAllDataInBuffer(self):
1671 1671 if self.profileIndex >= self.processingHeaderObj.profilesPerBlock:
1672 1672 return 1
1673 1673 return 0
1674 1674
1675 1675
1676 1676 def setBlockDimension(self):
1677 1677 """
1678 1678 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
1679 1679
1680 1680 Affected:
1681 1681 self.shape_spc_Buffer
1682 1682 self.shape_cspc_Buffer
1683 1683 self.shape_dc_Buffer
1684 1684
1685 1685 Return: None
1686 1686 """
1687 1687 self.shapeBuffer = (self.processingHeaderObj.profilesPerBlock,
1688 1688 self.processingHeaderObj.nHeights,
1689 1689 self.systemHeaderObj.nChannels)
1690 1690
1691 1691 self.datablock = numpy.zeros((self.systemHeaderObj.nChannels,
1692 1692 self.processingHeaderObj.profilesPerBlock,
1693 1693 self.processingHeaderObj.nHeights),
1694 1694 dtype=numpy.dtype('complex64'))
1695 1695
1696 1696
1697 1697 def writeBlock(self):
1698 1698 """
1699 1699 Escribe el buffer en el file designado
1700 1700
1701 1701 Affected:
1702 1702 self.profileIndex
1703 1703 self.flagIsNewFile
1704 1704 self.flagIsNewBlock
1705 1705 self.nTotalBlocks
1706 1706 self.blockIndex
1707 1707
1708 1708 Return: None
1709 1709 """
1710 1710 data = numpy.zeros( self.shapeBuffer, self.dtype )
1711 1711
1712 1712 junk = numpy.transpose(self.datablock, (1,2,0))
1713 1713
1714 1714 data['real'] = junk.real
1715 1715 data['imag'] = junk.imag
1716 1716
1717 1717 data = data.reshape( (-1) )
1718 1718
1719 1719 data.tofile( self.fp )
1720 1720
1721 1721 self.datablock.fill(0)
1722 1722
1723 1723 self.profileIndex = 0
1724 1724 self.flagIsNewFile = 0
1725 1725 self.flagIsNewBlock = 1
1726 1726
1727 1727 self.blockIndex += 1
1728 1728 self.nTotalBlocks += 1
1729 1729
1730 1730 def putData(self):
1731 1731 """
1732 1732 Setea un bloque de datos y luego los escribe en un file
1733 1733
1734 1734 Affected:
1735 1735 self.flagIsNewBlock
1736 1736 self.profileIndex
1737 1737
1738 1738 Return:
1739 1739 0 : Si no hay data o no hay mas files que puedan escribirse
1740 1740 1 : Si se escribio la data de un bloque en un file
1741 1741 """
1742 1742 if self.dataOut.flagNoData:
1743 1743 return 0
1744 1744
1745 1745 self.flagIsNewBlock = 0
1746 1746
1747 1747 if self.dataOut.flagTimeBlock:
1748 1748
1749 1749 self.datablock.fill(0)
1750 1750 self.profileIndex = 0
1751 1751 self.setNextFile()
1752 1752
1753 1753 if self.profileIndex == 0:
1754 1754 self.setBasicHeader()
1755 1755
1756 1756 self.datablock[:,self.profileIndex,:] = self.dataOut.data
1757 1757
1758 1758 self.profileIndex += 1
1759 1759
1760 1760 if self.hasAllDataInBuffer():
1761 1761 #if self.flagIsNewFile:
1762 1762 self.writeNextBlock()
1763 1763 # self.setFirstHeader()
1764 1764
1765 1765 return 1
1766 1766
1767 1767 def __getProcessFlags(self):
1768 1768
1769 1769 processFlags = 0
1770 1770
1771 1771 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
1772 1772 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
1773 1773 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
1774 1774 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
1775 1775 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
1776 1776 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
1777 1777
1778 1778 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
1779 1779
1780 1780
1781 1781
1782 1782 datatypeValueList = [PROCFLAG.DATATYPE_CHAR,
1783 1783 PROCFLAG.DATATYPE_SHORT,
1784 1784 PROCFLAG.DATATYPE_LONG,
1785 1785 PROCFLAG.DATATYPE_INT64,
1786 1786 PROCFLAG.DATATYPE_FLOAT,
1787 1787 PROCFLAG.DATATYPE_DOUBLE]
1788 1788
1789 1789
1790 1790 for index in range(len(dtypeList)):
1791 1791 if self.dataOut.dtype == dtypeList[index]:
1792 1792 dtypeValue = datatypeValueList[index]
1793 1793 break
1794 1794
1795 1795 processFlags += dtypeValue
1796 1796
1797 1797 if self.dataOut.flagDecodeData:
1798 1798 processFlags += PROCFLAG.DECODE_DATA
1799 1799
1800 1800 if self.dataOut.flagDeflipData:
1801 1801 processFlags += PROCFLAG.DEFLIP_DATA
1802 1802
1803 1803 if self.dataOut.code != None:
1804 1804 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1805 1805
1806 1806 if self.dataOut.nCohInt > 1:
1807 1807 processFlags += PROCFLAG.COHERENT_INTEGRATION
1808 1808
1809 1809 return processFlags
1810 1810
1811 1811
1812 1812 def __getBlockSize(self):
1813 1813 '''
1814 1814 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Voltage
1815 1815 '''
1816 1816
1817 1817 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
1818 1818 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
1819 1819 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
1820 1820 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
1821 1821 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
1822 1822 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
1823 1823
1824 1824 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
1825 1825 datatypeValueList = [1,2,4,8,4,8]
1826 1826 for index in range(len(dtypeList)):
1827 1827 if self.dataOut.dtype == dtypeList[index]:
1828 1828 datatypeValue = datatypeValueList[index]
1829 1829 break
1830 1830
1831 1831 blocksize = int(self.dataOut.nHeights * self.dataOut.nChannels * self.dataOut.nProfiles * datatypeValue * 2)
1832 1832
1833 1833 return blocksize
1834 1834
1835 1835 def setFirstHeader(self):
1836 1836
1837 1837 """
1838 1838 Obtiene una copia del First Header
1839 1839
1840 1840 Affected:
1841 1841 self.systemHeaderObj
1842 1842 self.radarControllerHeaderObj
1843 1843 self.dtype
1844 1844
1845 1845 Return:
1846 1846 None
1847 1847 """
1848 1848
1849 1849 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
1850 1850 self.systemHeaderObj.nChannels = self.dataOut.nChannels
1851 1851 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
1852 1852
1853 1853 self.setBasicHeader()
1854 1854
1855 1855 processingHeaderSize = 40 # bytes
1856 1856 self.processingHeaderObj.dtype = 0 # Voltage
1857 1857 self.processingHeaderObj.blockSize = self.__getBlockSize()
1858 1858 self.processingHeaderObj.profilesPerBlock = self.profilesPerBlock
1859 1859 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
1860 1860 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
1861 1861 self.processingHeaderObj.processFlags = self.__getProcessFlags()
1862 1862 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt
1863 1863 self.processingHeaderObj.nIncohInt = 1 # Cuando la data de origen es de tipo Voltage
1864 1864 self.processingHeaderObj.totalSpectra = 0 # Cuando la data de origen es de tipo Voltage
1865 1865
1866 1866 if self.dataOut.code != None:
1867 1867 self.processingHeaderObj.code = self.dataOut.code
1868 1868 self.processingHeaderObj.nCode = self.dataOut.nCode
1869 1869 self.processingHeaderObj.nBaud = self.dataOut.nBaud
1870 1870 codesize = int(8 + 4 * self.dataOut.nCode * self.dataOut.nBaud)
1871 1871 processingHeaderSize += codesize
1872 1872
1873 1873 if self.processingHeaderObj.nWindows != 0:
1874 1874 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
1875 1875 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
1876 1876 self.processingHeaderObj.nHeights = self.dataOut.nHeights
1877 1877 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
1878 1878 processingHeaderSize += 12
1879 1879
1880 1880 self.processingHeaderObj.size = processingHeaderSize
1881 1881
1882 1882 class SpectraReader(JRODataReader):
1883 1883 """
1884 1884 Esta clase permite leer datos de espectros desde archivos procesados (.pdata). La lectura
1885 1885 de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones)
1886 1886 son almacenados en tres buffer's para el Self Spectra, el Cross Spectra y el DC Channel.
1887 1887
1888 1888 paresCanalesIguales * alturas * perfiles (Self Spectra)
1889 1889 paresCanalesDiferentes * alturas * perfiles (Cross Spectra)
1890 1890 canales * alturas (DC Channels)
1891 1891
1892 1892 Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader,
1893 1893 RadarControllerHeader y Spectra. Los tres primeros se usan para almacenar informacion de la
1894 1894 cabecera de datos (metadata), y el cuarto (Spectra) para obtener y almacenar un bloque de
1895 1895 datos desde el "buffer" cada vez que se ejecute el metodo "getData".
1896 1896
1897 1897 Example:
1898 1898 dpath = "/home/myuser/data"
1899 1899
1900 1900 startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0)
1901 1901
1902 1902 endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0)
1903 1903
1904 1904 readerObj = SpectraReader()
1905 1905
1906 1906 readerObj.setup(dpath, startTime, endTime)
1907 1907
1908 1908 while(True):
1909 1909
1910 1910 readerObj.getData()
1911 1911
1912 1912 print readerObj.data_spc
1913 1913
1914 1914 print readerObj.data_cspc
1915 1915
1916 1916 print readerObj.data_dc
1917 1917
1918 1918 if readerObj.flagNoMoreFiles:
1919 1919 break
1920 1920
1921 1921 """
1922 1922
1923 1923 pts2read_SelfSpectra = 0
1924 1924
1925 1925 pts2read_CrossSpectra = 0
1926 1926
1927 1927 pts2read_DCchannels = 0
1928 1928
1929 1929 ext = ".pdata"
1930 1930
1931 1931 optchar = "P"
1932 1932
1933 1933 dataOut = None
1934 1934
1935 1935 nRdChannels = None
1936 1936
1937 1937 nRdPairs = None
1938 1938
1939 1939 rdPairList = []
1940 1940
1941 1941 def __init__(self):
1942 1942 """
1943 1943 Inicializador de la clase SpectraReader para la lectura de datos de espectros.
1944 1944
1945 1945 Inputs:
1946 1946 dataOut : Objeto de la clase Spectra. Este objeto sera utilizado para
1947 1947 almacenar un perfil de datos cada vez que se haga un requerimiento
1948 1948 (getData). El perfil sera obtenido a partir del buffer de datos,
1949 1949 si el buffer esta vacio se hara un nuevo proceso de lectura de un
1950 1950 bloque de datos.
1951 1951 Si este parametro no es pasado se creara uno internamente.
1952 1952
1953 1953 Affected:
1954 1954 self.dataOut
1955 1955
1956 1956 Return : None
1957 1957 """
1958 1958
1959 1959 self.isConfig = False
1960 1960
1961 1961 self.pts2read_SelfSpectra = 0
1962 1962
1963 1963 self.pts2read_CrossSpectra = 0
1964 1964
1965 1965 self.pts2read_DCchannels = 0
1966 1966
1967 1967 self.datablock = None
1968 1968
1969 1969 self.utc = None
1970 1970
1971 1971 self.ext = ".pdata"
1972 1972
1973 1973 self.optchar = "P"
1974 1974
1975 1975 self.basicHeaderObj = BasicHeader(LOCALTIME)
1976 1976
1977 1977 self.systemHeaderObj = SystemHeader()
1978 1978
1979 1979 self.radarControllerHeaderObj = RadarControllerHeader()
1980 1980
1981 1981 self.processingHeaderObj = ProcessingHeader()
1982 1982
1983 1983 self.online = 0
1984 1984
1985 1985 self.fp = None
1986 1986
1987 1987 self.idFile = None
1988 1988
1989 1989 self.dtype = None
1990 1990
1991 1991 self.fileSizeByHeader = None
1992 1992
1993 1993 self.filenameList = []
1994 1994
1995 1995 self.filename = None
1996 1996
1997 1997 self.fileSize = None
1998 1998
1999 1999 self.firstHeaderSize = 0
2000 2000
2001 2001 self.basicHeaderSize = 24
2002 2002
2003 2003 self.pathList = []
2004 2004
2005 2005 self.lastUTTime = 0
2006 2006
2007 2007 self.maxTimeStep = 30
2008 2008
2009 2009 self.flagNoMoreFiles = 0
2010 2010
2011 2011 self.set = 0
2012 2012
2013 2013 self.path = None
2014 2014
2015 2015 self.delay = 60 #seconds
2016 2016
2017 2017 self.nTries = 3 #quantity tries
2018 2018
2019 2019 self.nFiles = 3 #number of files for searching
2020 2020
2021 2021 self.nReadBlocks = 0
2022 2022
2023 2023 self.flagIsNewFile = 1
2024 2024
2025 2025 self.__isFirstTimeOnline = 1
2026 2026
2027 2027 self.ippSeconds = 0
2028 2028
2029 2029 self.flagTimeBlock = 0
2030 2030
2031 2031 self.flagIsNewBlock = 0
2032 2032
2033 2033 self.nTotalBlocks = 0
2034 2034
2035 2035 self.blocksize = 0
2036 2036
2037 2037 self.dataOut = self.createObjByDefault()
2038 2038
2039 2039 self.profileIndex = 1 #Always
2040 2040
2041 2041
2042 2042 def createObjByDefault(self):
2043 2043
2044 2044 dataObj = Spectra()
2045 2045
2046 2046 return dataObj
2047 2047
2048 2048 def __hasNotDataInBuffer(self):
2049 2049 return 1
2050 2050
2051 2051
2052 2052 def getBlockDimension(self):
2053 2053 """
2054 2054 Obtiene la cantidad de puntos a leer por cada bloque de datos
2055 2055
2056 2056 Affected:
2057 2057 self.nRdChannels
2058 2058 self.nRdPairs
2059 2059 self.pts2read_SelfSpectra
2060 2060 self.pts2read_CrossSpectra
2061 2061 self.pts2read_DCchannels
2062 2062 self.blocksize
2063 2063 self.dataOut.nChannels
2064 2064 self.dataOut.nPairs
2065 2065
2066 2066 Return:
2067 2067 None
2068 2068 """
2069 2069 self.nRdChannels = 0
2070 2070 self.nRdPairs = 0
2071 2071 self.rdPairList = []
2072 2072
2073 2073 for i in range(0, self.processingHeaderObj.totalSpectra*2, 2):
2074 2074 if self.processingHeaderObj.spectraComb[i] == self.processingHeaderObj.spectraComb[i+1]:
2075 2075 self.nRdChannels = self.nRdChannels + 1 #par de canales iguales
2076 2076 else:
2077 2077 self.nRdPairs = self.nRdPairs + 1 #par de canales diferentes
2078 2078 self.rdPairList.append((self.processingHeaderObj.spectraComb[i], self.processingHeaderObj.spectraComb[i+1]))
2079 2079
2080 2080 pts2read = self.processingHeaderObj.nHeights * self.processingHeaderObj.profilesPerBlock
2081 2081
2082 2082 self.pts2read_SelfSpectra = int(self.nRdChannels * pts2read)
2083 2083 self.blocksize = self.pts2read_SelfSpectra
2084 2084
2085 2085 if self.processingHeaderObj.flag_cspc:
2086 2086 self.pts2read_CrossSpectra = int(self.nRdPairs * pts2read)
2087 2087 self.blocksize += self.pts2read_CrossSpectra
2088 2088
2089 2089 if self.processingHeaderObj.flag_dc:
2090 2090 self.pts2read_DCchannels = int(self.systemHeaderObj.nChannels * self.processingHeaderObj.nHeights)
2091 2091 self.blocksize += self.pts2read_DCchannels
2092 2092
2093 2093 # self.blocksize = self.pts2read_SelfSpectra + self.pts2read_CrossSpectra + self.pts2read_DCchannels
2094 2094
2095 2095
2096 2096 def readBlock(self):
2097 2097 """
2098 2098 Lee el bloque de datos desde la posicion actual del puntero del archivo
2099 2099 (self.fp) y actualiza todos los parametros relacionados al bloque de datos
2100 2100 (metadata + data). La data leida es almacenada en el buffer y el contador del buffer
2101 2101 es seteado a 0
2102 2102
2103 2103 Return: None
2104 2104
2105 2105 Variables afectadas:
2106 2106
2107 2107 self.flagIsNewFile
2108 2108 self.flagIsNewBlock
2109 2109 self.nTotalBlocks
2110 2110 self.data_spc
2111 2111 self.data_cspc
2112 2112 self.data_dc
2113 2113
2114 2114 Exceptions:
2115 2115 Si un bloque leido no es un bloque valido
2116 2116 """
2117 2117 blockOk_flag = False
2118 2118 fpointer = self.fp.tell()
2119 2119
2120 2120 spc = numpy.fromfile( self.fp, self.dtype[0], self.pts2read_SelfSpectra )
2121 2121 spc = spc.reshape( (self.nRdChannels, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
2122 2122
2123 2123 if self.processingHeaderObj.flag_cspc:
2124 2124 cspc = numpy.fromfile( self.fp, self.dtype, self.pts2read_CrossSpectra )
2125 2125 cspc = cspc.reshape( (self.nRdPairs, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D
2126 2126
2127 2127 if self.processingHeaderObj.flag_dc:
2128 2128 dc = numpy.fromfile( self.fp, self.dtype, self.pts2read_DCchannels ) #int(self.processingHeaderObj.nHeights*self.systemHeaderObj.nChannels) )
2129 2129 dc = dc.reshape( (self.systemHeaderObj.nChannels, self.processingHeaderObj.nHeights) ) #transforma a un arreglo 2D
2130 2130
2131 2131
2132 2132 if not(self.processingHeaderObj.shif_fft):
2133 2133 #desplaza a la derecha en el eje 2 determinadas posiciones
2134 2134 shift = int(self.processingHeaderObj.profilesPerBlock/2)
2135 2135 spc = numpy.roll( spc, shift , axis=2 )
2136 2136
2137 2137 if self.processingHeaderObj.flag_cspc:
2138 2138 #desplaza a la derecha en el eje 2 determinadas posiciones
2139 2139 cspc = numpy.roll( cspc, shift, axis=2 )
2140 2140
2141 2141 # self.processingHeaderObj.shif_fft = True
2142 2142
2143 2143 spc = numpy.transpose( spc, (0,2,1) )
2144 2144 self.data_spc = spc
2145 2145
2146 2146 if self.processingHeaderObj.flag_cspc:
2147 2147 cspc = numpy.transpose( cspc, (0,2,1) )
2148 2148 self.data_cspc = cspc['real'] + cspc['imag']*1j
2149 2149 else:
2150 2150 self.data_cspc = None
2151 2151
2152 2152 if self.processingHeaderObj.flag_dc:
2153 2153 self.data_dc = dc['real'] + dc['imag']*1j
2154 2154 else:
2155 2155 self.data_dc = None
2156 2156
2157 2157 self.flagIsNewFile = 0
2158 2158 self.flagIsNewBlock = 1
2159 2159
2160 2160 self.nTotalBlocks += 1
2161 2161 self.nReadBlocks += 1
2162 2162
2163 2163 return 1
2164 2164
2165 2165 def getFirstHeader(self):
2166 2166
2167 2167 self.dataOut.dtype = self.dtype
2168 2168
2169 2169 self.dataOut.nPairs = self.nRdPairs
2170 2170
2171 2171 self.dataOut.pairsList = self.rdPairList
2172 2172
2173 2173 self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock
2174 2174
2175 2175 self.dataOut.nFFTPoints = self.processingHeaderObj.profilesPerBlock
2176 2176
2177 2177 self.dataOut.nCohInt = self.processingHeaderObj.nCohInt
2178 2178
2179 2179 self.dataOut.nIncohInt = self.processingHeaderObj.nIncohInt
2180 2180
2181 2181 xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight
2182 2182
2183 2183 self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight)
2184 2184
2185 2185 self.dataOut.channelList = range(self.systemHeaderObj.nChannels)
2186 2186
2187 2187 self.dataOut.ippSeconds = self.ippSeconds
2188 2188
2189 2189 self.dataOut.timeInterval = self.ippSeconds * self.processingHeaderObj.nCohInt * self.processingHeaderObj.nIncohInt * self.dataOut.nFFTPoints
2190 2190
2191 2191 self.dataOut.systemHeaderObj = self.systemHeaderObj.copy()
2192 2192
2193 2193 self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy()
2194 2194
2195 2195 self.dataOut.flagShiftFFT = self.processingHeaderObj.shif_fft
2196 2196
2197 2197 self.dataOut.flagDecodeData = False #asumo q la data no esta decodificada
2198 2198
2199 2199 self.dataOut.flagDeflipData = True #asumo q la data no esta sin flip
2200 2200
2201 2201 if self.processingHeaderObj.code != None:
2202 2202
2203 2203 self.dataOut.nCode = self.processingHeaderObj.nCode
2204 2204
2205 2205 self.dataOut.nBaud = self.processingHeaderObj.nBaud
2206 2206
2207 2207 self.dataOut.code = self.processingHeaderObj.code
2208 2208
2209 2209 self.dataOut.flagDecodeData = True
2210 2210
2211 2211 def getData(self):
2212 2212 """
2213 2213 Copia el buffer de lectura a la clase "Spectra",
2214 2214 con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de
2215 2215 lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock"
2216 2216
2217 2217 Return:
2218 2218 0 : Si no hay mas archivos disponibles
2219 2219 1 : Si hizo una buena copia del buffer
2220 2220
2221 2221 Affected:
2222 2222 self.dataOut
2223 2223
2224 2224 self.flagTimeBlock
2225 2225 self.flagIsNewBlock
2226 2226 """
2227 2227
2228 2228 if self.flagNoMoreFiles:
2229 2229 self.dataOut.flagNoData = True
2230 2230 print 'Process finished'
2231 2231 return 0
2232 2232
2233 2233 self.flagTimeBlock = 0
2234 2234 self.flagIsNewBlock = 0
2235 2235
2236 2236 if self.__hasNotDataInBuffer():
2237 2237
2238 2238 if not( self.readNextBlock() ):
2239 2239 self.dataOut.flagNoData = True
2240 2240 return 0
2241 2241
2242 2242 #data es un numpy array de 3 dmensiones (perfiles, alturas y canales)
2243 2243
2244 2244 if self.data_dc == None:
2245 2245 self.dataOut.flagNoData = True
2246 2246 return 0
2247 2247
2248 2248 self.getBasicHeader()
2249 2249
2250 2250 self.getFirstHeader()
2251 2251
2252 2252 self.dataOut.data_spc = self.data_spc
2253 2253
2254 2254 self.dataOut.data_cspc = self.data_cspc
2255 2255
2256 2256 self.dataOut.data_dc = self.data_dc
2257 2257
2258 2258 self.dataOut.flagNoData = False
2259 2259
2260 2260 self.dataOut.realtime = self.online
2261 2261
2262 2262 return self.dataOut.data_spc
2263 2263
2264 2264
2265 2265 class SpectraWriter(JRODataWriter):
2266 2266
2267 2267 """
2268 2268 Esta clase permite escribir datos de espectros a archivos procesados (.pdata). La escritura
2269 2269 de los datos siempre se realiza por bloques.
2270 2270 """
2271 2271
2272 2272 ext = ".pdata"
2273 2273
2274 2274 optchar = "P"
2275 2275
2276 2276 shape_spc_Buffer = None
2277 2277
2278 2278 shape_cspc_Buffer = None
2279 2279
2280 2280 shape_dc_Buffer = None
2281 2281
2282 2282 data_spc = None
2283 2283
2284 2284 data_cspc = None
2285 2285
2286 2286 data_dc = None
2287 2287
2288 2288 # dataOut = None
2289 2289
2290 2290 def __init__(self):
2291 2291 """
2292 2292 Inicializador de la clase SpectraWriter para la escritura de datos de espectros.
2293 2293
2294 2294 Affected:
2295 2295 self.dataOut
2296 2296 self.basicHeaderObj
2297 2297 self.systemHeaderObj
2298 2298 self.radarControllerHeaderObj
2299 2299 self.processingHeaderObj
2300 2300
2301 2301 Return: None
2302 2302 """
2303 2303
2304 2304 self.isConfig = False
2305 2305
2306 2306 self.nTotalBlocks = 0
2307 2307
2308 2308 self.data_spc = None
2309 2309
2310 2310 self.data_cspc = None
2311 2311
2312 2312 self.data_dc = None
2313 2313
2314 2314 self.fp = None
2315 2315
2316 2316 self.flagIsNewFile = 1
2317 2317
2318 2318 self.nTotalBlocks = 0
2319 2319
2320 2320 self.flagIsNewBlock = 0
2321 2321
2322 2322 self.setFile = None
2323 2323
2324 2324 self.dtype = None
2325 2325
2326 2326 self.path = None
2327 2327
2328 2328 self.noMoreFiles = 0
2329 2329
2330 2330 self.filename = None
2331 2331
2332 2332 self.basicHeaderObj = BasicHeader(LOCALTIME)
2333 2333
2334 2334 self.systemHeaderObj = SystemHeader()
2335 2335
2336 2336 self.radarControllerHeaderObj = RadarControllerHeader()
2337 2337
2338 2338 self.processingHeaderObj = ProcessingHeader()
2339 2339
2340 2340
2341 2341 def hasAllDataInBuffer(self):
2342 2342 return 1
2343 2343
2344 2344
2345 2345 def setBlockDimension(self):
2346 2346 """
2347 2347 Obtiene las formas dimensionales del los subbloques de datos que componen un bloque
2348 2348
2349 2349 Affected:
2350 2350 self.shape_spc_Buffer
2351 2351 self.shape_cspc_Buffer
2352 2352 self.shape_dc_Buffer
2353 2353
2354 2354 Return: None
2355 2355 """
2356 2356 self.shape_spc_Buffer = (self.dataOut.nChannels,
2357 2357 self.processingHeaderObj.nHeights,
2358 2358 self.processingHeaderObj.profilesPerBlock)
2359 2359
2360 2360 self.shape_cspc_Buffer = (self.dataOut.nPairs,
2361 2361 self.processingHeaderObj.nHeights,
2362 2362 self.processingHeaderObj.profilesPerBlock)
2363 2363
2364 2364 self.shape_dc_Buffer = (self.dataOut.nChannels,
2365 2365 self.processingHeaderObj.nHeights)
2366 2366
2367 2367
2368 2368 def writeBlock(self):
2369 2369 """
2370 2370 Escribe el buffer en el file designado
2371 2371
2372 2372 Affected:
2373 2373 self.data_spc
2374 2374 self.data_cspc
2375 2375 self.data_dc
2376 2376 self.flagIsNewFile
2377 2377 self.flagIsNewBlock
2378 2378 self.nTotalBlocks
2379 2379 self.nWriteBlocks
2380 2380
2381 2381 Return: None
2382 2382 """
2383 2383
2384 2384 spc = numpy.transpose( self.data_spc, (0,2,1) )
2385 2385 if not( self.processingHeaderObj.shif_fft ):
2386 2386 spc = numpy.roll( spc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
2387 2387 data = spc.reshape((-1))
2388 2388 data = data.astype(self.dtype[0])
2389 2389 data.tofile(self.fp)
2390 2390
2391 2391 if self.data_cspc != None:
2392 2392 data = numpy.zeros( self.shape_cspc_Buffer, self.dtype )
2393 2393 cspc = numpy.transpose( self.data_cspc, (0,2,1) )
2394 2394 if not( self.processingHeaderObj.shif_fft ):
2395 2395 cspc = numpy.roll( cspc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones
2396 2396 data['real'] = cspc.real
2397 2397 data['imag'] = cspc.imag
2398 2398 data = data.reshape((-1))
2399 2399 data.tofile(self.fp)
2400 2400
2401 2401 if self.data_dc != None:
2402 2402 data = numpy.zeros( self.shape_dc_Buffer, self.dtype )
2403 2403 dc = self.data_dc
2404 2404 data['real'] = dc.real
2405 2405 data['imag'] = dc.imag
2406 2406 data = data.reshape((-1))
2407 2407 data.tofile(self.fp)
2408 2408
2409 2409 self.data_spc.fill(0)
2410 self.data_dc.fill(0)
2410
2411 if self.data_dc != None:
2412 self.data_dc.fill(0)
2413
2411 2414 if self.data_cspc != None:
2412 2415 self.data_cspc.fill(0)
2413 2416
2414 2417 self.flagIsNewFile = 0
2415 2418 self.flagIsNewBlock = 1
2416 2419 self.nTotalBlocks += 1
2417 2420 self.nWriteBlocks += 1
2418 2421 self.blockIndex += 1
2419 2422
2420 2423
2421 2424 def putData(self):
2422 2425 """
2423 2426 Setea un bloque de datos y luego los escribe en un file
2424 2427
2425 2428 Affected:
2426 2429 self.data_spc
2427 2430 self.data_cspc
2428 2431 self.data_dc
2429 2432
2430 2433 Return:
2431 2434 0 : Si no hay data o no hay mas files que puedan escribirse
2432 2435 1 : Si se escribio la data de un bloque en un file
2433 2436 """
2434 2437
2435 2438 if self.dataOut.flagNoData:
2436 2439 return 0
2437 2440
2438 2441 self.flagIsNewBlock = 0
2439 2442
2440 2443 if self.dataOut.flagTimeBlock:
2441 2444 self.data_spc.fill(0)
2442 2445 self.data_cspc.fill(0)
2443 2446 self.data_dc.fill(0)
2444 2447 self.setNextFile()
2445 2448
2446 2449 if self.flagIsNewFile == 0:
2447 2450 self.setBasicHeader()
2448 2451
2449 2452 self.data_spc = self.dataOut.data_spc.copy()
2450 self.data_cspc = self.dataOut.data_cspc.copy()
2453 if self.dataOut.data_cspc != None:
2454 self.data_cspc = self.dataOut.data_cspc.copy()
2451 2455 self.data_dc = self.dataOut.data_dc.copy()
2452 2456
2453 2457 # #self.processingHeaderObj.dataBlocksPerFile)
2454 2458 if self.hasAllDataInBuffer():
2455 2459 # self.setFirstHeader()
2456 2460 self.writeNextBlock()
2457 2461
2458 2462 return 1
2459 2463
2460 2464
2461 2465 def __getProcessFlags(self):
2462 2466
2463 2467 processFlags = 0
2464 2468
2465 2469 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
2466 2470 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
2467 2471 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
2468 2472 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
2469 2473 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
2470 2474 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
2471 2475
2472 2476 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
2473 2477
2474 2478
2475 2479
2476 2480 datatypeValueList = [PROCFLAG.DATATYPE_CHAR,
2477 2481 PROCFLAG.DATATYPE_SHORT,
2478 2482 PROCFLAG.DATATYPE_LONG,
2479 2483 PROCFLAG.DATATYPE_INT64,
2480 2484 PROCFLAG.DATATYPE_FLOAT,
2481 2485 PROCFLAG.DATATYPE_DOUBLE]
2482 2486
2483 2487
2484 2488 for index in range(len(dtypeList)):
2485 2489 if self.dataOut.dtype == dtypeList[index]:
2486 2490 dtypeValue = datatypeValueList[index]
2487 2491 break
2488 2492
2489 2493 processFlags += dtypeValue
2490 2494
2491 2495 if self.dataOut.flagDecodeData:
2492 2496 processFlags += PROCFLAG.DECODE_DATA
2493 2497
2494 2498 if self.dataOut.flagDeflipData:
2495 2499 processFlags += PROCFLAG.DEFLIP_DATA
2496 2500
2497 2501 if self.dataOut.code != None:
2498 2502 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
2499 2503
2500 2504 if self.dataOut.nIncohInt > 1:
2501 2505 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
2502 2506
2503 2507 if self.dataOut.data_dc != None:
2504 2508 processFlags += PROCFLAG.SAVE_CHANNELS_DC
2505 2509
2506 2510 return processFlags
2507 2511
2508 2512
2509 2513 def __getBlockSize(self):
2510 2514 '''
2511 2515 Este metodos determina el cantidad de bytes para un bloque de datos de tipo Spectra
2512 2516 '''
2513 2517
2514 2518 dtype0 = numpy.dtype([('real','<i1'),('imag','<i1')])
2515 2519 dtype1 = numpy.dtype([('real','<i2'),('imag','<i2')])
2516 2520 dtype2 = numpy.dtype([('real','<i4'),('imag','<i4')])
2517 2521 dtype3 = numpy.dtype([('real','<i8'),('imag','<i8')])
2518 2522 dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')])
2519 2523 dtype5 = numpy.dtype([('real','<f8'),('imag','<f8')])
2520 2524
2521 2525 dtypeList = [dtype0, dtype1, dtype2, dtype3, dtype4, dtype5]
2522 2526 datatypeValueList = [1,2,4,8,4,8]
2523 2527 for index in range(len(dtypeList)):
2524 2528 if self.dataOut.dtype == dtypeList[index]:
2525 2529 datatypeValue = datatypeValueList[index]
2526 2530 break
2527 2531
2528 2532
2529 2533 pts2write = self.dataOut.nHeights * self.dataOut.nFFTPoints
2530 2534
2531 2535 pts2write_SelfSpectra = int(self.dataOut.nChannels * pts2write)
2532 2536 blocksize = (pts2write_SelfSpectra*datatypeValue)
2533 2537
2534 2538 if self.dataOut.data_cspc != None:
2535 2539 pts2write_CrossSpectra = int(self.dataOut.nPairs * pts2write)
2536 2540 blocksize += (pts2write_CrossSpectra*datatypeValue*2)
2537 2541
2538 2542 if self.dataOut.data_dc != None:
2539 2543 pts2write_DCchannels = int(self.dataOut.nChannels * self.dataOut.nHeights)
2540 2544 blocksize += (pts2write_DCchannels*datatypeValue*2)
2541 2545
2542 2546 blocksize = blocksize #* datatypeValue * 2 #CORREGIR ESTO
2543 2547
2544 2548 return blocksize
2545 2549
2546 2550 def setFirstHeader(self):
2547 2551
2548 2552 """
2549 2553 Obtiene una copia del First Header
2550 2554
2551 2555 Affected:
2552 2556 self.systemHeaderObj
2553 2557 self.radarControllerHeaderObj
2554 2558 self.dtype
2555 2559
2556 2560 Return:
2557 2561 None
2558 2562 """
2559 2563
2560 2564 self.systemHeaderObj = self.dataOut.systemHeaderObj.copy()
2561 2565 self.systemHeaderObj.nChannels = self.dataOut.nChannels
2562 2566 self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy()
2563 2567
2564 2568 self.setBasicHeader()
2565 2569
2566 2570 processingHeaderSize = 40 # bytes
2567 2571 self.processingHeaderObj.dtype = 1 # Spectra
2568 2572 self.processingHeaderObj.blockSize = self.__getBlockSize()
2569 2573 self.processingHeaderObj.profilesPerBlock = self.dataOut.nFFTPoints
2570 2574 self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile
2571 2575 self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows
2572 2576 self.processingHeaderObj.processFlags = self.__getProcessFlags()
2573 2577 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt# Se requiere para determinar el valor de timeInterval
2574 2578 self.processingHeaderObj.nIncohInt = self.dataOut.nIncohInt
2575 2579 self.processingHeaderObj.totalSpectra = self.dataOut.nPairs + self.dataOut.nChannels
2576 2580 self.processingHeaderObj.shif_fft = self.dataOut.flagShiftFFT
2577 2581
2578 2582 if self.processingHeaderObj.totalSpectra > 0:
2579 2583 channelList = []
2580 2584 for channel in range(self.dataOut.nChannels):
2581 2585 channelList.append(channel)
2582 2586 channelList.append(channel)
2583
2587
2584 2588 pairsList = []
2585 for pair in self.dataOut.pairsList:
2586 pairsList.append(pair[0])
2587 pairsList.append(pair[1])
2589 if self.dataOut.nPairs > 0:
2590 for pair in self.dataOut.pairsList:
2591 pairsList.append(pair[0])
2592 pairsList.append(pair[1])
2593
2588 2594 spectraComb = channelList + pairsList
2589 2595 spectraComb = numpy.array(spectraComb,dtype="u1")
2590 2596 self.processingHeaderObj.spectraComb = spectraComb
2591 2597 sizeOfSpcComb = len(spectraComb)
2592 2598 processingHeaderSize += sizeOfSpcComb
2593 2599
2594 2600 # The processing header should not have information about code
2595 2601 # if self.dataOut.code != None:
2596 2602 # self.processingHeaderObj.code = self.dataOut.code
2597 2603 # self.processingHeaderObj.nCode = self.dataOut.nCode
2598 2604 # self.processingHeaderObj.nBaud = self.dataOut.nBaud
2599 2605 # nCodeSize = 4 # bytes
2600 2606 # nBaudSize = 4 # bytes
2601 2607 # codeSize = 4 # bytes
2602 2608 # sizeOfCode = int(nCodeSize + nBaudSize + codeSize * self.dataOut.nCode * self.dataOut.nBaud)
2603 2609 # processingHeaderSize += sizeOfCode
2604 2610
2605 2611 if self.processingHeaderObj.nWindows != 0:
2606 2612 self.processingHeaderObj.firstHeight = self.dataOut.heightList[0]
2607 2613 self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
2608 2614 self.processingHeaderObj.nHeights = self.dataOut.nHeights
2609 2615 self.processingHeaderObj.samplesWin = self.dataOut.nHeights
2610 2616 sizeOfFirstHeight = 4
2611 2617 sizeOfdeltaHeight = 4
2612 2618 sizeOfnHeights = 4
2613 2619 sizeOfWindows = (sizeOfFirstHeight + sizeOfdeltaHeight + sizeOfnHeights)*self.processingHeaderObj.nWindows
2614 2620 processingHeaderSize += sizeOfWindows
2615 2621
2616 2622 self.processingHeaderObj.size = processingHeaderSize
2617 2623
2618 2624 class SpectraHeisWriter(Operation):
2619 2625 # set = None
2620 2626 setFile = None
2621 2627 idblock = None
2622 2628 doypath = None
2623 2629 subfolder = None
2624 2630
2625 2631 def __init__(self):
2626 2632 self.wrObj = FITS()
2627 2633 # self.dataOut = dataOut
2628 2634 self.nTotalBlocks=0
2629 2635 # self.set = None
2630 2636 self.setFile = None
2631 2637 self.idblock = 0
2632 2638 self.wrpath = None
2633 2639 self.doypath = None
2634 2640 self.subfolder = None
2635 2641 self.isConfig = False
2636 2642
2637 2643 def isNumber(str):
2638 2644 """
2639 2645 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
2640 2646
2641 2647 Excepciones:
2642 2648 Si un determinado string no puede ser convertido a numero
2643 2649 Input:
2644 2650 str, string al cual se le analiza para determinar si convertible a un numero o no
2645 2651
2646 2652 Return:
2647 2653 True : si el string es uno numerico
2648 2654 False : no es un string numerico
2649 2655 """
2650 2656 try:
2651 2657 float( str )
2652 2658 return True
2653 2659 except:
2654 2660 return False
2655 2661
2656 2662 def setup(self, dataOut, wrpath):
2657 2663
2658 2664 if not(os.path.exists(wrpath)):
2659 2665 os.mkdir(wrpath)
2660 2666
2661 2667 self.wrpath = wrpath
2662 2668 # self.setFile = 0
2663 2669 self.dataOut = dataOut
2664 2670
2665 2671 def putData(self):
2666 2672 name= time.localtime( self.dataOut.utctime)
2667 2673 ext=".fits"
2668 2674
2669 2675 if self.doypath == None:
2670 2676 self.subfolder = 'F%4.4d%3.3d_%d' % (name.tm_year,name.tm_yday,time.mktime(datetime.datetime.now().timetuple()))
2671 2677 self.doypath = os.path.join( self.wrpath, self.subfolder )
2672 2678 os.mkdir(self.doypath)
2673 2679
2674 2680 if self.setFile == None:
2675 2681 # self.set = self.dataOut.set
2676 2682 self.setFile = 0
2677 2683 # if self.set != self.dataOut.set:
2678 2684 ## self.set = self.dataOut.set
2679 2685 # self.setFile = 0
2680 2686
2681 2687 #make the filename
2682 2688 file = 'D%4.4d%3.3d_%3.3d%s' % (name.tm_year,name.tm_yday,self.setFile,ext)
2683 2689
2684 2690 filename = os.path.join(self.wrpath,self.subfolder, file)
2685 2691
2686 2692 idblock = numpy.array([self.idblock],dtype="int64")
2687 2693 header=self.wrObj.cFImage(idblock=idblock,
2688 2694 year=time.gmtime(self.dataOut.utctime).tm_year,
2689 2695 month=time.gmtime(self.dataOut.utctime).tm_mon,
2690 2696 day=time.gmtime(self.dataOut.utctime).tm_mday,
2691 2697 hour=time.gmtime(self.dataOut.utctime).tm_hour,
2692 2698 minute=time.gmtime(self.dataOut.utctime).tm_min,
2693 2699 second=time.gmtime(self.dataOut.utctime).tm_sec)
2694 2700
2695 2701 c=3E8
2696 2702 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
2697 2703 freq=numpy.arange(-1*self.dataOut.nHeights/2.,self.dataOut.nHeights/2.)*(c/(2*deltaHeight*1000))
2698 2704
2699 2705 colList = []
2700 2706
2701 2707 colFreq=self.wrObj.setColF(name="freq", format=str(self.dataOut.nFFTPoints)+'E', array=freq)
2702 2708
2703 2709 colList.append(colFreq)
2704 2710
2705 2711 nchannel=self.dataOut.nChannels
2706 2712
2707 2713 for i in range(nchannel):
2708 2714 col = self.wrObj.writeData(name="PCh"+str(i+1),
2709 2715 format=str(self.dataOut.nFFTPoints)+'E',
2710 2716 data=10*numpy.log10(self.dataOut.data_spc[i,:]))
2711 2717
2712 2718 colList.append(col)
2713 2719
2714 2720 data=self.wrObj.Ctable(colList=colList)
2715 2721
2716 2722 self.wrObj.CFile(header,data)
2717 2723
2718 2724 self.wrObj.wFile(filename)
2719 2725
2720 2726 #update the setFile
2721 2727 self.setFile += 1
2722 2728 self.idblock += 1
2723 2729
2724 2730 return 1
2725 2731
2726 2732 def run(self, dataOut, **kwargs):
2727 2733
2728 2734 if not(self.isConfig):
2729 2735
2730 2736 self.setup(dataOut, **kwargs)
2731 2737 self.isConfig = True
2732 2738
2733 2739 self.putData()
2734 2740
2735 2741
2736 2742 class FITS:
2737 2743 name=None
2738 2744 format=None
2739 2745 array =None
2740 2746 data =None
2741 2747 thdulist=None
2742 2748 prihdr=None
2743 2749 hdu=None
2744 2750
2745 2751 def __init__(self):
2746 2752
2747 2753 pass
2748 2754
2749 2755 def setColF(self,name,format,array):
2750 2756 self.name=name
2751 2757 self.format=format
2752 2758 self.array=array
2753 2759 a1=numpy.array([self.array],dtype=numpy.float32)
2754 2760 self.col1 = pyfits.Column(name=self.name, format=self.format, array=a1)
2755 2761 return self.col1
2756 2762
2757 2763 # def setColP(self,name,format,data):
2758 2764 # self.name=name
2759 2765 # self.format=format
2760 2766 # self.data=data
2761 2767 # a2=numpy.array([self.data],dtype=numpy.float32)
2762 2768 # self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2)
2763 2769 # return self.col2
2764 2770
2765 2771
2766 2772 def writeData(self,name,format,data):
2767 2773 self.name=name
2768 2774 self.format=format
2769 2775 self.data=data
2770 2776 a2=numpy.array([self.data],dtype=numpy.float32)
2771 2777 self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2)
2772 2778 return self.col2
2773 2779
2774 2780 def cFImage(self,idblock,year,month,day,hour,minute,second):
2775 2781 self.hdu= pyfits.PrimaryHDU(idblock)
2776 2782 self.hdu.header.set("Year",year)
2777 2783 self.hdu.header.set("Month",month)
2778 2784 self.hdu.header.set("Day",day)
2779 2785 self.hdu.header.set("Hour",hour)
2780 2786 self.hdu.header.set("Minute",minute)
2781 2787 self.hdu.header.set("Second",second)
2782 2788 return self.hdu
2783 2789
2784 2790
2785 2791 def Ctable(self,colList):
2786 2792 self.cols=pyfits.ColDefs(colList)
2787 2793 self.tbhdu = pyfits.new_table(self.cols)
2788 2794 return self.tbhdu
2789 2795
2790 2796
2791 2797 def CFile(self,hdu,tbhdu):
2792 2798 self.thdulist=pyfits.HDUList([hdu,tbhdu])
2793 2799
2794 2800 def wFile(self,filename):
2795 2801 if os.path.isfile(filename):
2796 2802 os.remove(filename)
2797 2803 self.thdulist.writeto(filename)
2798 2804
2799 2805
2800 2806 class ParameterConf:
2801 2807 ELEMENTNAME = 'Parameter'
2802 2808 def __init__(self):
2803 2809 self.name = ''
2804 2810 self.value = ''
2805 2811
2806 2812 def readXml(self, parmElement):
2807 2813 self.name = parmElement.get('name')
2808 2814 self.value = parmElement.get('value')
2809 2815
2810 2816 def getElementName(self):
2811 2817 return self.ELEMENTNAME
2812 2818
2813 2819 class Metadata:
2814 2820
2815 2821 def __init__(self, filename):
2816 2822 self.parmConfObjList = []
2817 2823 self.readXml(filename)
2818 2824
2819 2825 def readXml(self, filename):
2820 2826 self.projectElement = None
2821 2827 self.procUnitConfObjDict = {}
2822 2828 self.projectElement = ElementTree().parse(filename)
2823 2829 self.project = self.projectElement.tag
2824 2830
2825 2831 parmElementList = self.projectElement.getiterator(ParameterConf().getElementName())
2826 2832
2827 2833 for parmElement in parmElementList:
2828 2834 parmConfObj = ParameterConf()
2829 2835 parmConfObj.readXml(parmElement)
2830 2836 self.parmConfObjList.append(parmConfObj)
2831 2837
2832 2838 class FitsWriter(Operation):
2833 2839
2834 2840 def __init__(self):
2835 2841 self.isConfig = False
2836 2842 self.dataBlocksPerFile = None
2837 2843 self.blockIndex = 0
2838 2844 self.flagIsNewFile = 1
2839 2845 self.fitsObj = None
2840 2846 self.optchar = 'P'
2841 2847 self.ext = '.fits'
2842 2848 self.setFile = 0
2843 2849
2844 2850 def setFitsHeader(self, dataOut, metadatafile):
2845 2851
2846 2852 header_data = pyfits.PrimaryHDU()
2847 2853
2848 2854 metadata4fits = Metadata(metadatafile)
2849 2855 for parameter in metadata4fits.parmConfObjList:
2850 2856 parm_name = parameter.name
2851 2857 parm_value = parameter.value
2852 2858
2853 2859 if parm_value == 'fromdatadatetime':
2854 2860 value = time.strftime("%b %d %Y %H:%M:%S", dataOut.datatime.timetuple())
2855 2861 elif parm_value == 'fromdataheights':
2856 2862 value = dataOut.nHeights
2857 2863 elif parm_value == 'fromdatachannel':
2858 2864 value = dataOut.nChannels
2859 2865 elif parm_value == 'fromdatasamples':
2860 2866 value = dataOut.nFFTPoints
2861 2867 else:
2862 2868 value = parm_value
2863 2869
2864 2870 header_data.header[parm_name] = value
2865 2871
2866 2872 header_data.header['NBLOCK'] = self.blockIndex
2867 2873
2868 2874 header_data.writeto(self.filename)
2869 2875
2870 2876
2871 2877 def setup(self, dataOut, path, dataBlocksPerFile, metadatafile):
2872 2878
2873 2879 self.path = path
2874 2880 self.dataOut = dataOut
2875 2881 self.metadatafile = metadatafile
2876 2882 self.dataBlocksPerFile = dataBlocksPerFile
2877 2883
2878 2884 def open(self):
2879 2885 self.fitsObj = pyfits.open(self.filename, mode='update')
2880 2886
2881 2887
2882 2888 def addData(self, data):
2883 2889 self.open()
2884 2890 extension = pyfits.ImageHDU(data=data, name=self.fitsObj[0].header['DATA'])
2885 2891 extension.header['UTCTIME'] = self.dataOut.utctime
2886 2892 self.fitsObj.append(extension)
2887 2893 self.blockIndex += 1
2888 2894 self.fitsObj[0].header['NBLOCK'] = self.blockIndex
2889 2895
2890 2896 self.write()
2891 2897
2892 2898 def write(self):
2893 2899
2894 2900 self.fitsObj.flush(verbose=True)
2895 2901 self.fitsObj.close()
2896 2902
2897 2903
2898 2904 def setNextFile(self):
2899 2905
2900 2906 ext = self.ext
2901 2907 path = self.path
2902 2908
2903 2909 timeTuple = time.localtime( self.dataOut.utctime)
2904 2910 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
2905 2911
2906 2912 fullpath = os.path.join( path, subfolder )
2907 2913 if not( os.path.exists(fullpath) ):
2908 2914 os.mkdir(fullpath)
2909 2915 self.setFile = -1 #inicializo mi contador de seteo
2910 2916 else:
2911 2917 filesList = os.listdir( fullpath )
2912 2918 if len( filesList ) > 0:
2913 2919 filesList = sorted( filesList, key=str.lower )
2914 2920 filen = filesList[-1]
2915 2921
2916 2922 if isNumber( filen[8:11] ):
2917 2923 self.setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
2918 2924 else:
2919 2925 self.setFile = -1
2920 2926 else:
2921 2927 self.setFile = -1 #inicializo mi contador de seteo
2922 2928
2923 2929 setFile = self.setFile
2924 2930 setFile += 1
2925 2931
2926 2932 file = '%s%4.4d%3.3d%3.3d%s' % (self.optchar,
2927 2933 timeTuple.tm_year,
2928 2934 timeTuple.tm_yday,
2929 2935 setFile,
2930 2936 ext )
2931 2937
2932 2938 filename = os.path.join( path, subfolder, file )
2933 2939
2934 2940 self.blockIndex = 0
2935 2941 self.filename = filename
2936 2942 self.setFile = setFile
2937 2943 self.flagIsNewFile = 1
2938 2944
2939 2945 print 'Writing the file: %s'%self.filename
2940 2946
2941 2947 self.setFitsHeader(self.dataOut, self.metadatafile)
2942 2948
2943 2949 return 1
2944 2950
2945 2951 def writeBlock(self):
2946 2952 self.addData(self.dataOut.data_spc)
2947 2953 self.flagIsNewFile = 0
2948 2954
2949 2955
2950 2956 def __setNewBlock(self):
2951 2957
2952 2958 if self.flagIsNewFile:
2953 2959 return 1
2954 2960
2955 2961 if self.blockIndex < self.dataBlocksPerFile:
2956 2962 return 1
2957 2963
2958 2964 if not( self.setNextFile() ):
2959 2965 return 0
2960 2966
2961 2967 return 1
2962 2968
2963 2969 def writeNextBlock(self):
2964 2970 if not( self.__setNewBlock() ):
2965 2971 return 0
2966 2972 self.writeBlock()
2967 2973 return 1
2968 2974
2969 2975 def putData(self):
2970 2976 if self.flagIsNewFile:
2971 2977 self.setNextFile()
2972 2978 self.writeNextBlock()
2973 2979
2974 2980 def run(self, dataOut, **kwargs):
2975 2981 if not(self.isConfig):
2976 2982 self.setup(dataOut, **kwargs)
2977 2983 self.isConfig = True
2978 2984 self.putData()
2979 2985
2980 2986
2981 2987 class FitsReader(ProcessingUnit):
2982 2988
2983 2989 __TIMEZONE = time.timezone
2984 2990
2985 2991 expName = None
2986 2992 datetimestr = None
2987 2993 utc = None
2988 2994 nChannels = None
2989 2995 nSamples = None
2990 2996 dataBlocksPerFile = None
2991 2997 comments = None
2992 2998 lastUTTime = None
2993 2999 header_dict = None
2994 3000 data = None
2995 3001 data_header_dict = None
2996 3002
2997 3003 def __init__(self):
2998 3004 self.isConfig = False
2999 3005 self.ext = '.fits'
3000 3006 self.setFile = 0
3001 3007 self.flagNoMoreFiles = 0
3002 3008 self.flagIsNewFile = 1
3003 3009 self.flagTimeBlock = None
3004 3010 self.fileIndex = None
3005 3011 self.filename = None
3006 3012 self.fileSize = None
3007 3013 self.fitsObj = None
3008 3014 self.nReadBlocks = 0
3009 3015 self.nTotalBlocks = 0
3010 3016 self.dataOut = self.createObjByDefault()
3011 3017 self.maxTimeStep = 10# deberia ser definido por el usuario usando el metodo setup()
3012 3018 self.blockIndex = 1
3013 3019
3014 3020 def createObjByDefault(self):
3015 3021
3016 3022 dataObj = Fits()
3017 3023
3018 3024 return dataObj
3019 3025
3020 3026 def isFileinThisTime(self, filename, startTime, endTime, useLocalTime=False):
3021 3027 try:
3022 3028 fitsObj = pyfits.open(filename,'readonly')
3023 3029 except:
3024 3030 raise IOError, "The file %s can't be opened" %(filename)
3025 3031
3026 3032 header = fitsObj[0].header
3027 3033 struct_time = time.strptime(header['DATETIME'], "%b %d %Y %H:%M:%S")
3028 3034 utc = time.mktime(struct_time) - time.timezone #TIMEZONE debe ser un parametro del header FITS
3029 3035
3030 3036 ltc = utc
3031 3037 if useLocalTime:
3032 3038 ltc -= time.timezone
3033 3039 thisDatetime = datetime.datetime.utcfromtimestamp(ltc)
3034 3040 thisTime = thisDatetime.time()
3035 3041
3036 3042 if not ((startTime <= thisTime) and (endTime > thisTime)):
3037 3043 return None
3038 3044
3039 3045 return thisDatetime
3040 3046
3041 3047 def __setNextFileOnline(self):
3042 3048 raise ValueError, "No implemented"
3043 3049
3044 3050 def __setNextFileOffline(self):
3045 3051 idFile = self.fileIndex
3046 3052
3047 3053 while (True):
3048 3054 idFile += 1
3049 3055 if not(idFile < len(self.filenameList)):
3050 3056 self.flagNoMoreFiles = 1
3051 3057 print "No more Files"
3052 3058 return 0
3053 3059
3054 3060 filename = self.filenameList[idFile]
3055 3061
3056 3062 # if not(self.__verifyFile(filename)):
3057 3063 # continue
3058 3064
3059 3065 fileSize = os.path.getsize(filename)
3060 3066 fitsObj = pyfits.open(filename,'readonly')
3061 3067 break
3062 3068
3063 3069 self.flagIsNewFile = 1
3064 3070 self.fileIndex = idFile
3065 3071 self.filename = filename
3066 3072 self.fileSize = fileSize
3067 3073 self.fitsObj = fitsObj
3068 3074
3069 3075 print "Setting the file: %s"%self.filename
3070 3076
3071 3077 return 1
3072 3078
3073 3079 def readHeader(self):
3074 3080 headerObj = self.fitsObj[0]
3075 3081
3076 3082 self.header_dict = headerObj.header
3077 3083 self.expName = headerObj.header['EXPNAME']
3078 3084 self.datetimestr = headerObj.header['DATETIME']
3079 3085 struct_time = time.strptime(headerObj.header['DATETIME'], "%b %d %Y %H:%M:%S")
3080 3086 # self.utc = time.mktime(struct_time) - self.__TIMEZONE
3081 3087 self.nChannels = headerObj.header['NCHANNEL']
3082 3088 self.nSamples = headerObj.header['NSAMPLE']
3083 3089 self.dataBlocksPerFile = headerObj.header['NBLOCK']
3084 3090 self.comments = headerObj.header['COMMENT']
3085 3091
3086 3092
3087 3093 def setNextFile(self):
3088 3094
3089 3095 if self.online:
3090 3096 newFile = self.__setNextFileOnline()
3091 3097 else:
3092 3098 newFile = self.__setNextFileOffline()
3093 3099
3094 3100 if not(newFile):
3095 3101 return 0
3096 3102
3097 3103 self.readHeader()
3098 3104
3099 3105 self.nReadBlocks = 0
3100 3106 self.blockIndex = 1
3101 3107 return 1
3102 3108
3103 3109 def __searchFilesOffLine(self,
3104 3110 path,
3105 3111 startDate,
3106 3112 endDate,
3107 3113 startTime=datetime.time(0,0,0),
3108 3114 endTime=datetime.time(23,59,59),
3109 3115 set=None,
3110 3116 expLabel='',
3111 3117 ext='.fits',
3112 3118 walk=True):
3113 3119
3114 3120 pathList = []
3115 3121
3116 3122 if not walk:
3117 3123 pathList.append(path)
3118 3124
3119 3125 else:
3120 3126 dirList = []
3121 3127 for thisPath in os.listdir(path):
3122 3128 if not os.path.isdir(os.path.join(path,thisPath)):
3123 3129 continue
3124 3130 if not isDoyFolder(thisPath):
3125 3131 continue
3126 3132
3127 3133 dirList.append(thisPath)
3128 3134
3129 3135 if not(dirList):
3130 3136 return None, None
3131 3137
3132 3138 thisDate = startDate
3133 3139
3134 3140 while(thisDate <= endDate):
3135 3141 year = thisDate.timetuple().tm_year
3136 3142 doy = thisDate.timetuple().tm_yday
3137 3143
3138 3144 matchlist = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy) + '*')
3139 3145 if len(matchlist) == 0:
3140 3146 thisDate += datetime.timedelta(1)
3141 3147 continue
3142 3148 for match in matchlist:
3143 3149 pathList.append(os.path.join(path,match,expLabel))
3144 3150
3145 3151 thisDate += datetime.timedelta(1)
3146 3152
3147 3153 if pathList == []:
3148 3154 print "Any folder was found for the date range: %s-%s" %(startDate, endDate)
3149 3155 return None, None
3150 3156
3151 3157 print "%d folder(s) was(were) found for the date range: %s - %s" %(len(pathList), startDate, endDate)
3152 3158
3153 3159 filenameList = []
3154 3160 datetimeList = []
3155 3161
3156 3162 for i in range(len(pathList)):
3157 3163
3158 3164 thisPath = pathList[i]
3159 3165
3160 3166 fileList = glob.glob1(thisPath, "*%s" %ext)
3161 3167 fileList.sort()
3162 3168
3163 3169 for file in fileList:
3164 3170
3165 3171 filename = os.path.join(thisPath,file)
3166 3172 thisDatetime = self.isFileinThisTime(filename, startTime, endTime, useLocalTime=True)
3167 3173
3168 3174 if not(thisDatetime):
3169 3175 continue
3170 3176
3171 3177 filenameList.append(filename)
3172 3178 datetimeList.append(thisDatetime)
3173 3179
3174 3180 if not(filenameList):
3175 3181 print "Any file was found for the time range %s - %s" %(startTime, endTime)
3176 3182 return None, None
3177 3183
3178 3184 print "%d file(s) was(were) found for the time range: %s - %s" %(len(filenameList), startTime, endTime)
3179 3185 print
3180 3186
3181 3187 for i in range(len(filenameList)):
3182 3188 print "%s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
3183 3189
3184 3190 self.filenameList = filenameList
3185 3191 self.datetimeList = datetimeList
3186 3192
3187 3193 return pathList, filenameList
3188 3194
3189 3195 def setup(self, path=None,
3190 3196 startDate=None,
3191 3197 endDate=None,
3192 3198 startTime=datetime.time(0,0,0),
3193 3199 endTime=datetime.time(23,59,59),
3194 3200 set=0,
3195 3201 expLabel = "",
3196 3202 ext = None,
3197 3203 online = False,
3198 3204 delay = 60,
3199 3205 walk = True):
3200 3206
3201 3207 if path == None:
3202 3208 raise ValueError, "The path is not valid"
3203 3209
3204 3210 if ext == None:
3205 3211 ext = self.ext
3206 3212
3207 3213 if not(online):
3208 3214 print "Searching files in offline mode ..."
3209 3215 pathList, filenameList = self.__searchFilesOffLine(path, startDate=startDate, endDate=endDate,
3210 3216 startTime=startTime, endTime=endTime,
3211 3217 set=set, expLabel=expLabel, ext=ext,
3212 3218 walk=walk)
3213 3219
3214 3220 if not(pathList):
3215 3221 print "No *%s files into the folder %s \nfor the range: %s - %s"%(ext, path,
3216 3222 datetime.datetime.combine(startDate,startTime).ctime(),
3217 3223 datetime.datetime.combine(endDate,endTime).ctime())
3218 3224
3219 3225 sys.exit(-1)
3220 3226
3221 3227 self.fileIndex = -1
3222 3228 self.pathList = pathList
3223 3229 self.filenameList = filenameList
3224 3230
3225 3231 self.online = online
3226 3232 self.delay = delay
3227 3233 ext = ext.lower()
3228 3234 self.ext = ext
3229 3235
3230 3236 if not(self.setNextFile()):
3231 3237 if (startDate!=None) and (endDate!=None):
3232 3238 print "No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
3233 3239 elif startDate != None:
3234 3240 print "No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime())
3235 3241 else:
3236 3242 print "No files"
3237 3243
3238 3244 sys.exit(-1)
3239 3245
3240 3246
3241 3247
3242 3248 def readBlock(self):
3243 3249 dataObj = self.fitsObj[self.blockIndex]
3244 3250
3245 3251 self.data = dataObj.data
3246 3252 self.data_header_dict = dataObj.header
3247 3253 self.utc = self.data_header_dict['UTCTIME']
3248 3254
3249 3255 self.flagIsNewFile = 0
3250 3256 self.blockIndex += 1
3251 3257 self.nTotalBlocks += 1
3252 3258 self.nReadBlocks += 1
3253 3259
3254 3260 return 1
3255 3261
3256 3262 def __jumpToLastBlock(self):
3257 3263 raise ValueError, "No implemented"
3258 3264
3259 3265 def __waitNewBlock(self):
3260 3266 """
3261 3267 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
3262 3268
3263 3269 Si el modo de lectura es OffLine siempre retorn 0
3264 3270 """
3265 3271 if not self.online:
3266 3272 return 0
3267 3273
3268 3274 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
3269 3275 return 0
3270 3276
3271 3277 currentPointer = self.fp.tell()
3272 3278
3273 3279 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
3274 3280
3275 3281 for nTries in range( self.nTries ):
3276 3282
3277 3283 self.fp.close()
3278 3284 self.fp = open( self.filename, 'rb' )
3279 3285 self.fp.seek( currentPointer )
3280 3286
3281 3287 self.fileSize = os.path.getsize( self.filename )
3282 3288 currentSize = self.fileSize - currentPointer
3283 3289
3284 3290 if ( currentSize >= neededSize ):
3285 3291 self.__rdBasicHeader()
3286 3292 return 1
3287 3293
3288 3294 print "\tWaiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1)
3289 3295 time.sleep( self.delay )
3290 3296
3291 3297
3292 3298 return 0
3293 3299
3294 3300 def __setNewBlock(self):
3295 3301
3296 3302 if self.online:
3297 3303 self.__jumpToLastBlock()
3298 3304
3299 3305 if self.flagIsNewFile:
3300 3306 return 1
3301 3307
3302 3308 self.lastUTTime = self.utc
3303 3309
3304 3310 if self.online:
3305 3311 if self.__waitNewBlock():
3306 3312 return 1
3307 3313
3308 3314 if self.nReadBlocks < self.dataBlocksPerFile:
3309 3315 return 1
3310 3316
3311 3317 if not(self.setNextFile()):
3312 3318 return 0
3313 3319
3314 3320 deltaTime = self.utc - self.lastUTTime
3315 3321
3316 3322 self.flagTimeBlock = 0
3317 3323
3318 3324 if deltaTime > self.maxTimeStep:
3319 3325 self.flagTimeBlock = 1
3320 3326
3321 3327 return 1
3322 3328
3323 3329
3324 3330 def readNextBlock(self):
3325 3331 if not(self.__setNewBlock()):
3326 3332 return 0
3327 3333
3328 3334 if not(self.readBlock()):
3329 3335 return 0
3330 3336
3331 3337 return 1
3332 3338
3333 3339
3334 3340 def getData(self):
3335 3341
3336 3342 if self.flagNoMoreFiles:
3337 3343 self.dataOut.flagNoData = True
3338 3344 print 'Process finished'
3339 3345 return 0
3340 3346
3341 3347 self.flagTimeBlock = 0
3342 3348 self.flagIsNewBlock = 0
3343 3349
3344 3350 if not(self.readNextBlock()):
3345 3351 return 0
3346 3352
3347 3353 if self.data == None:
3348 3354 self.dataOut.flagNoData = True
3349 3355 return 0
3350 3356
3351 3357 self.dataOut.data = self.data
3352 3358 self.dataOut.data_header = self.data_header_dict
3353 3359 self.dataOut.utctime = self.utc
3354 3360
3355 3361 self.dataOut.header = self.header_dict
3356 3362 self.dataOut.expName = self.expName
3357 3363 self.dataOut.nChannels = self.nChannels
3358 3364 self.dataOut.nSamples = self.nSamples
3359 3365 self.dataOut.dataBlocksPerFile = self.dataBlocksPerFile
3360 3366 self.dataOut.comments = self.comments
3361 3367
3362 3368 self.dataOut.flagNoData = False
3363 3369
3364 3370 return self.dataOut.data
3365 3371
3366 3372 def run(self, **kwargs):
3367 3373
3368 3374 if not(self.isConfig):
3369 3375 self.setup(**kwargs)
3370 3376 self.isConfig = True
3371 3377
3372 3378 self.getData() No newline at end of file
@@ -1,1475 +1,1480
1 1 import numpy
2 2 import time, datetime, os
3 3 from graphics.figure import *
4 4 def isRealtime(utcdatatime):
5 5 utcnow = time.mktime(datetime.datetime.utcnow().timetuple())
6 6 delta = utcnow - utcdatatime # abs
7 if delta >= 5*60.:
7 if delta >= 30.:
8 8 return False
9 9 return True
10 10
11 11 class CrossSpectraPlot(Figure):
12 12
13 13 __isConfig = None
14 14 __nsubplots = None
15 15
16 16 WIDTH = None
17 17 HEIGHT = None
18 18 WIDTHPROF = None
19 19 HEIGHTPROF = None
20 20 PREFIX = 'cspc'
21 21
22 22 def __init__(self):
23 23
24 24 self.__isConfig = False
25 25 self.__nsubplots = 4
26 26 self.counter_imagwr = 0
27 27 self.WIDTH = 250
28 28 self.HEIGHT = 250
29 29 self.WIDTHPROF = 0
30 30 self.HEIGHTPROF = 0
31 31
32 32 self.PLOT_CODE = 1
33 33 self.FTP_WEI = None
34 34 self.EXP_CODE = None
35 35 self.SUB_EXP_CODE = None
36 36 self.PLOT_POS = None
37 37
38 38 def getSubplots(self):
39 39
40 40 ncol = 4
41 41 nrow = self.nplots
42 42
43 43 return nrow, ncol
44 44
45 45 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
46 46
47 47 self.__showprofile = showprofile
48 48 self.nplots = nplots
49 49
50 50 ncolspan = 1
51 51 colspan = 1
52 52
53 53 self.createFigure(id = id,
54 54 wintitle = wintitle,
55 55 widthplot = self.WIDTH + self.WIDTHPROF,
56 56 heightplot = self.HEIGHT + self.HEIGHTPROF,
57 57 show=True)
58 58
59 59 nrow, ncol = self.getSubplots()
60 60
61 61 counter = 0
62 62 for y in range(nrow):
63 63 for x in range(ncol):
64 64 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
65 65
66 66 counter += 1
67 67
68 68 def run(self, dataOut, id, wintitle="", pairsList=None,
69 69 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
70 70 save=False, figpath='./', figfile=None, ftp=False, wr_period=1,
71 71 power_cmap='jet', coherence_cmap='jet', phase_cmap='RdBu_r', show=True,
72 72 server=None, folder=None, username=None, password=None,
73 73 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
74 74
75 75 """
76 76
77 77 Input:
78 78 dataOut :
79 79 id :
80 80 wintitle :
81 81 channelList :
82 82 showProfile :
83 83 xmin : None,
84 84 xmax : None,
85 85 ymin : None,
86 86 ymax : None,
87 87 zmin : None,
88 88 zmax : None
89 89 """
90 90
91 91 if pairsList == None:
92 92 pairsIndexList = dataOut.pairsIndexList
93 93 else:
94 94 pairsIndexList = []
95 95 for pair in pairsList:
96 96 if pair not in dataOut.pairsList:
97 97 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
98 98 pairsIndexList.append(dataOut.pairsList.index(pair))
99 99
100 100 if pairsIndexList == []:
101 101 return
102 102
103 103 if len(pairsIndexList) > 4:
104 104 pairsIndexList = pairsIndexList[0:4]
105 105 factor = dataOut.normFactor
106 106 x = dataOut.getVelRange(1)
107 107 y = dataOut.getHeiRange()
108 108 z = dataOut.data_spc[:,:,:]/factor
109 109 # z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
110 110 avg = numpy.abs(numpy.average(z, axis=1))
111 111 noise = dataOut.getNoise()/factor
112 112
113 113 zdB = 10*numpy.log10(z)
114 114 avgdB = 10*numpy.log10(avg)
115 115 noisedB = 10*numpy.log10(noise)
116 116
117 117
118 118 #thisDatetime = dataOut.datatime
119 119 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
120 120 title = wintitle + " Cross-Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
121 121 xlabel = "Velocity (m/s)"
122 122 ylabel = "Range (Km)"
123 123
124 124 if not self.__isConfig:
125 125
126 126 nplots = len(pairsIndexList)
127 127
128 128 self.setup(id=id,
129 129 nplots=nplots,
130 130 wintitle=wintitle,
131 131 showprofile=False,
132 132 show=show)
133 133
134 134 if xmin == None: xmin = numpy.nanmin(x)
135 135 if xmax == None: xmax = numpy.nanmax(x)
136 136 if ymin == None: ymin = numpy.nanmin(y)
137 137 if ymax == None: ymax = numpy.nanmax(y)
138 138 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
139 139 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
140 140
141 141 self.FTP_WEI = ftp_wei
142 142 self.EXP_CODE = exp_code
143 143 self.SUB_EXP_CODE = sub_exp_code
144 144 self.PLOT_POS = plot_pos
145 145
146 146 self.__isConfig = True
147 147
148 148 self.setWinTitle(title)
149 149
150 150 for i in range(self.nplots):
151 151 pair = dataOut.pairsList[pairsIndexList[i]]
152 152 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
153 153 title = "Ch%d: %4.2fdB: %s" %(pair[0], noisedB[pair[0]], str_datetime)
154 154 zdB = 10.*numpy.log10(dataOut.data_spc[pair[0],:,:]/factor)
155 155 axes0 = self.axesList[i*self.__nsubplots]
156 156 axes0.pcolor(x, y, zdB,
157 157 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
158 158 xlabel=xlabel, ylabel=ylabel, title=title,
159 159 ticksize=9, colormap=power_cmap, cblabel='')
160 160
161 161 title = "Ch%d: %4.2fdB: %s" %(pair[1], noisedB[pair[1]], str_datetime)
162 162 zdB = 10.*numpy.log10(dataOut.data_spc[pair[1],:,:]/factor)
163 163 axes0 = self.axesList[i*self.__nsubplots+1]
164 164 axes0.pcolor(x, y, zdB,
165 165 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
166 166 xlabel=xlabel, ylabel=ylabel, title=title,
167 167 ticksize=9, colormap=power_cmap, cblabel='')
168 168
169 169 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[pair[0],:,:]*dataOut.data_spc[pair[1],:,:])
170 170 coherence = numpy.abs(coherenceComplex)
171 171 # phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
172 172 phase = numpy.arctan2(coherenceComplex.imag, coherenceComplex.real)*180/numpy.pi
173 173
174 174 title = "Coherence %d%d" %(pair[0], pair[1])
175 175 axes0 = self.axesList[i*self.__nsubplots+2]
176 176 axes0.pcolor(x, y, coherence,
177 177 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=0, zmax=1,
178 178 xlabel=xlabel, ylabel=ylabel, title=title,
179 179 ticksize=9, colormap=coherence_cmap, cblabel='')
180 180
181 181 title = "Phase %d%d" %(pair[0], pair[1])
182 182 axes0 = self.axesList[i*self.__nsubplots+3]
183 183 axes0.pcolor(x, y, phase,
184 184 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=-180, zmax=180,
185 185 xlabel=xlabel, ylabel=ylabel, title=title,
186 186 ticksize=9, colormap=phase_cmap, cblabel='')
187 187
188 188
189 189
190 190 self.draw()
191 191
192 192 if save:
193 193
194 194 self.counter_imagwr += 1
195 195 if (self.counter_imagwr==wr_period):
196 196 if figfile == None:
197 197 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
198 198 figfile = self.getFilename(name = str_datetime)
199 199
200 200 self.saveFigure(figpath, figfile)
201 201
202 202 if ftp:
203 203 #provisionalmente envia archivos en el formato de la web en tiempo real
204 204 name = self.getNameToFtp(thisDatetime, self.FTP_WEI, self.EXP_CODE, self.SUB_EXP_CODE, self.PLOT_CODE, self.PLOT_POS)
205 205 path = '%s%03d' %(self.PREFIX, self.id)
206 206 ftp_file = os.path.join(path,'ftp','%s.png'%name)
207 207 self.saveFigure(figpath, ftp_file)
208 208 ftp_filename = os.path.join(figpath,ftp_file)
209 209
210 210 try:
211 211 self.sendByFTP(ftp_filename, server, folder, username, password)
212 212 except:
213 213 raise ValueError, 'Error FTP'
214 214
215 215 self.counter_imagwr = 0
216 216
217 217
218 218 class RTIPlot(Figure):
219 219
220 220 __isConfig = None
221 221 __nsubplots = None
222 222
223 223 WIDTHPROF = None
224 224 HEIGHTPROF = None
225 225 PREFIX = 'rti'
226 226
227 227 def __init__(self):
228 228
229 229 self.timerange = 2*60*60
230 230 self.__isConfig = False
231 231 self.__nsubplots = 1
232 232
233 233 self.WIDTH = 800
234 234 self.HEIGHT = 150
235 235 self.WIDTHPROF = 120
236 236 self.HEIGHTPROF = 0
237 237 self.counter_imagwr = 0
238 238
239 239 self.PLOT_CODE = 0
240 240 self.FTP_WEI = None
241 241 self.EXP_CODE = None
242 242 self.SUB_EXP_CODE = None
243 243 self.PLOT_POS = None
244 244
245 245 def getSubplots(self):
246 246
247 247 ncol = 1
248 248 nrow = self.nplots
249 249
250 250 return nrow, ncol
251 251
252 252 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
253 253
254 254 self.__showprofile = showprofile
255 255 self.nplots = nplots
256 256
257 257 ncolspan = 1
258 258 colspan = 1
259 259 if showprofile:
260 260 ncolspan = 7
261 261 colspan = 6
262 262 self.__nsubplots = 2
263 263
264 264 self.createFigure(id = id,
265 265 wintitle = wintitle,
266 266 widthplot = self.WIDTH + self.WIDTHPROF,
267 267 heightplot = self.HEIGHT + self.HEIGHTPROF,
268 268 show=show)
269 269
270 270 nrow, ncol = self.getSubplots()
271 271
272 272 counter = 0
273 273 for y in range(nrow):
274 274 for x in range(ncol):
275 275
276 276 if counter >= self.nplots:
277 277 break
278 278
279 279 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
280 280
281 281 if showprofile:
282 282 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
283 283
284 284 counter += 1
285 285
286 286 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
287 287 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
288 288 timerange=None,
289 289 save=False, figpath='./', figfile=None, ftp=False, wr_period=1, show=True,
290 290 server=None, folder=None, username=None, password=None,
291 291 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
292 292
293 293 """
294 294
295 295 Input:
296 296 dataOut :
297 297 id :
298 298 wintitle :
299 299 channelList :
300 300 showProfile :
301 301 xmin : None,
302 302 xmax : None,
303 303 ymin : None,
304 304 ymax : None,
305 305 zmin : None,
306 306 zmax : None
307 307 """
308 308
309 309 if channelList == None:
310 310 channelIndexList = dataOut.channelIndexList
311 311 else:
312 312 channelIndexList = []
313 313 for channel in channelList:
314 314 if channel not in dataOut.channelList:
315 315 raise ValueError, "Channel %d is not in dataOut.channelList"
316 316 channelIndexList.append(dataOut.channelList.index(channel))
317 317
318 318 if timerange != None:
319 319 self.timerange = timerange
320 320
321 321 tmin = None
322 322 tmax = None
323 323 factor = dataOut.normFactor
324 324 x = dataOut.getTimeRange()
325 325 y = dataOut.getHeiRange()
326 326
327 327 z = dataOut.data_spc[channelIndexList,:,:]/factor
328 328 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
329 329 avg = numpy.average(z, axis=1)
330 330
331 331 avgdB = 10.*numpy.log10(avg)
332 332
333 333
334 334 # thisDatetime = dataOut.datatime
335 335 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
336 336 title = wintitle + " RTI" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
337 337 xlabel = ""
338 338 ylabel = "Range (Km)"
339 339
340 340 if not self.__isConfig:
341 341
342 342 nplots = len(channelIndexList)
343 343
344 344 self.setup(id=id,
345 345 nplots=nplots,
346 346 wintitle=wintitle,
347 347 showprofile=showprofile,
348 348 show=show)
349 349
350 350 tmin, tmax = self.getTimeLim(x, xmin, xmax)
351 351 if ymin == None: ymin = numpy.nanmin(y)
352 352 if ymax == None: ymax = numpy.nanmax(y)
353 353 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
354 354 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
355 355
356 356 self.FTP_WEI = ftp_wei
357 357 self.EXP_CODE = exp_code
358 358 self.SUB_EXP_CODE = sub_exp_code
359 359 self.PLOT_POS = plot_pos
360 360
361 361 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
362 362 self.__isConfig = True
363 363
364 364
365 365 self.setWinTitle(title)
366 366
367 367 for i in range(self.nplots):
368 368 title = "Channel %d: %s" %(dataOut.channelList[i]+1, thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
369 369 axes = self.axesList[i*self.__nsubplots]
370 370 zdB = avgdB[i].reshape((1,-1))
371 371 axes.pcolorbuffer(x, y, zdB,
372 372 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
373 373 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
374 374 ticksize=9, cblabel='', cbsize="1%")
375 375
376 376 if self.__showprofile:
377 377 axes = self.axesList[i*self.__nsubplots +1]
378 378 axes.pline(avgdB[i], y,
379 379 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
380 380 xlabel='dB', ylabel='', title='',
381 381 ytick_visible=False,
382 382 grid='x')
383 383
384 384 self.draw()
385 385
386 386 if save:
387 387
388 388 self.counter_imagwr += 1
389 389 if (self.counter_imagwr==wr_period):
390 390 if figfile == None:
391 391 figfile = self.getFilename(name = self.name)
392 392 self.saveFigure(figpath, figfile)
393 393
394 394 if ftp:
395 395 #provisionalmente envia archivos en el formato de la web en tiempo real
396 396 name = self.getNameToFtp(thisDatetime, self.FTP_WEI, self.EXP_CODE, self.SUB_EXP_CODE, self.PLOT_CODE, self.PLOT_POS)
397 397 path = '%s%03d' %(self.PREFIX, self.id)
398 398 ftp_file = os.path.join(path,'ftp','%s.png'%name)
399 399 self.saveFigure(figpath, ftp_file)
400 400 ftp_filename = os.path.join(figpath,ftp_file)
401 401 try:
402 402 self.sendByFTP(ftp_filename, server, folder, username, password)
403 403 except:
404 404 raise ValueError, 'Error FTP'
405 405
406 406 self.counter_imagwr = 0
407 407
408 408 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
409 409 self.__isConfig = False
410 410
411 411 class SpectraPlot(Figure):
412 412
413 413 __isConfig = None
414 414 __nsubplots = None
415 415
416 416 WIDTHPROF = None
417 417 HEIGHTPROF = None
418 418 PREFIX = 'spc'
419 419
420 420 def __init__(self):
421 421
422 422 self.__isConfig = False
423 423 self.__nsubplots = 1
424 424
425 425 self.WIDTH = 280
426 426 self.HEIGHT = 250
427 427 self.WIDTHPROF = 120
428 428 self.HEIGHTPROF = 0
429 429 self.counter_imagwr = 0
430 430
431 431 self.PLOT_CODE = 1
432 432 self.FTP_WEI = None
433 433 self.EXP_CODE = None
434 434 self.SUB_EXP_CODE = None
435 435 self.PLOT_POS = None
436 436
437 437 def getSubplots(self):
438 438
439 439 ncol = int(numpy.sqrt(self.nplots)+0.9)
440 440 nrow = int(self.nplots*1./ncol + 0.9)
441 441
442 442 return nrow, ncol
443 443
444 444 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
445 445
446 446 self.__showprofile = showprofile
447 447 self.nplots = nplots
448 448
449 449 ncolspan = 1
450 450 colspan = 1
451 451 if showprofile:
452 452 ncolspan = 3
453 453 colspan = 2
454 454 self.__nsubplots = 2
455 455
456 456 self.createFigure(id = id,
457 457 wintitle = wintitle,
458 458 widthplot = self.WIDTH + self.WIDTHPROF,
459 459 heightplot = self.HEIGHT + self.HEIGHTPROF,
460 460 show=show)
461 461
462 462 nrow, ncol = self.getSubplots()
463 463
464 464 counter = 0
465 465 for y in range(nrow):
466 466 for x in range(ncol):
467 467
468 468 if counter >= self.nplots:
469 469 break
470 470
471 471 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
472 472
473 473 if showprofile:
474 474 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
475 475
476 476 counter += 1
477 477
478 478 def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True,
479 479 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
480 480 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
481 481 server=None, folder=None, username=None, password=None,
482 482 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
483 483
484 484 """
485 485
486 486 Input:
487 487 dataOut :
488 488 id :
489 489 wintitle :
490 490 channelList :
491 491 showProfile :
492 492 xmin : None,
493 493 xmax : None,
494 494 ymin : None,
495 495 ymax : None,
496 496 zmin : None,
497 497 zmax : None
498 498 """
499 499
500 if dataOut.realtime:
501 if not(isRealtime(utcdatatime = dataOut.utctime)):
502 print 'Skipping this plot function'
503 return
504
500 505 if channelList == None:
501 506 channelIndexList = dataOut.channelIndexList
502 507 else:
503 508 channelIndexList = []
504 509 for channel in channelList:
505 510 if channel not in dataOut.channelList:
506 511 raise ValueError, "Channel %d is not in dataOut.channelList"
507 512 channelIndexList.append(dataOut.channelList.index(channel))
508 513 factor = dataOut.normFactor
509 514 x = dataOut.getVelRange(1)
510 515 y = dataOut.getHeiRange()
511 516
512 517 z = dataOut.data_spc[channelIndexList,:,:]/factor
513 518 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
514 519 avg = numpy.average(z, axis=1)
515 520 noise = dataOut.getNoise()/factor
516 521
517 522 zdB = 10*numpy.log10(z)
518 523 avgdB = 10*numpy.log10(avg)
519 524 noisedB = 10*numpy.log10(noise)
520 525
521 526 #thisDatetime = dataOut.datatime
522 527 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
523 528 title = wintitle + " Spectra"
524 529 xlabel = "Velocity (m/s)"
525 530 ylabel = "Range (Km)"
526 531
527 532 if not self.__isConfig:
528 533
529 534 nplots = len(channelIndexList)
530 535
531 536 self.setup(id=id,
532 537 nplots=nplots,
533 538 wintitle=wintitle,
534 539 showprofile=showprofile,
535 540 show=show)
536 541
537 542 if xmin == None: xmin = numpy.nanmin(x)
538 543 if xmax == None: xmax = numpy.nanmax(x)
539 544 if ymin == None: ymin = numpy.nanmin(y)
540 545 if ymax == None: ymax = numpy.nanmax(y)
541 546 if zmin == None: zmin = numpy.nanmin(avgdB)*0.9
542 547 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9
543 548
544 549 self.FTP_WEI = ftp_wei
545 550 self.EXP_CODE = exp_code
546 551 self.SUB_EXP_CODE = sub_exp_code
547 552 self.PLOT_POS = plot_pos
548 553
549 554 self.__isConfig = True
550 555
551 556 self.setWinTitle(title)
552 557
553 558 for i in range(self.nplots):
554 559 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S"))
555 560 title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[i]+1, noisedB[i], str_datetime)
556 561 axes = self.axesList[i*self.__nsubplots]
557 562 axes.pcolor(x, y, zdB[i,:,:],
558 563 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
559 564 xlabel=xlabel, ylabel=ylabel, title=title,
560 565 ticksize=9, cblabel='')
561 566
562 567 if self.__showprofile:
563 568 axes = self.axesList[i*self.__nsubplots +1]
564 569 axes.pline(avgdB[i], y,
565 570 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
566 571 xlabel='dB', ylabel='', title='',
567 572 ytick_visible=False,
568 573 grid='x')
569 574
570 575 noiseline = numpy.repeat(noisedB[i], len(y))
571 576 axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2)
572 577
573 578 self.draw()
574 579
575 580 if save:
576 581
577 582 self.counter_imagwr += 1
578 583 if (self.counter_imagwr==wr_period):
579 584 if figfile == None:
580 585 str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S")
581 586 figfile = self.getFilename(name = str_datetime)
582 587
583 588 self.saveFigure(figpath, figfile)
584 589
585 590 if ftp:
586 591 #provisionalmente envia archivos en el formato de la web en tiempo real
587 592 name = self.getNameToFtp(thisDatetime, self.FTP_WEI, self.EXP_CODE, self.SUB_EXP_CODE, self.PLOT_CODE, self.PLOT_POS)
588 593 path = '%s%03d' %(self.PREFIX, self.id)
589 594 ftp_file = os.path.join(path,'ftp','%s.png'%name)
590 595 self.saveFigure(figpath, ftp_file)
591 596 ftp_filename = os.path.join(figpath,ftp_file)
592 597 try:
593 598 self.sendByFTP(ftp_filename, server, folder, username, password)
594 599 except:
595 600 raise ValueError, 'Error FTP'
596 601
597 602 self.counter_imagwr = 0
598 603
599 604
600 605 class Scope(Figure):
601 606
602 607 __isConfig = None
603 608
604 609 def __init__(self):
605 610
606 611 self.__isConfig = False
607 612 self.WIDTH = 600
608 613 self.HEIGHT = 200
609 614
610 615 def getSubplots(self):
611 616
612 617 nrow = self.nplots
613 618 ncol = 3
614 619 return nrow, ncol
615 620
616 621 def setup(self, id, nplots, wintitle, show):
617 622
618 623 self.nplots = nplots
619 624
620 625 self.createFigure(id=id,
621 626 wintitle=wintitle,
622 627 show=show)
623 628
624 629 nrow,ncol = self.getSubplots()
625 630 colspan = 3
626 631 rowspan = 1
627 632
628 633 for i in range(nplots):
629 634 self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
630 635
631 636
632 637
633 638 def run(self, dataOut, id, wintitle="", channelList=None,
634 639 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
635 640 figpath='./', figfile=None, show=True):
636 641
637 642 """
638 643
639 644 Input:
640 645 dataOut :
641 646 id :
642 647 wintitle :
643 648 channelList :
644 649 xmin : None,
645 650 xmax : None,
646 651 ymin : None,
647 652 ymax : None,
648 653 """
649 654
650 655 if channelList == None:
651 656 channelIndexList = dataOut.channelIndexList
652 657 else:
653 658 channelIndexList = []
654 659 for channel in channelList:
655 660 if channel not in dataOut.channelList:
656 661 raise ValueError, "Channel %d is not in dataOut.channelList"
657 662 channelIndexList.append(dataOut.channelList.index(channel))
658 663
659 664 x = dataOut.heightList
660 665 y = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
661 666 y = y.real
662 667
663 668 #thisDatetime = dataOut.datatime
664 669 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
665 670 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
666 671 xlabel = "Range (Km)"
667 672 ylabel = "Intensity"
668 673
669 674 if not self.__isConfig:
670 675 nplots = len(channelIndexList)
671 676
672 677 self.setup(id=id,
673 678 nplots=nplots,
674 679 wintitle=wintitle,
675 680 show=show)
676 681
677 682 if xmin == None: xmin = numpy.nanmin(x)
678 683 if xmax == None: xmax = numpy.nanmax(x)
679 684 if ymin == None: ymin = numpy.nanmin(y)
680 685 if ymax == None: ymax = numpy.nanmax(y)
681 686
682 687 self.__isConfig = True
683 688
684 689 self.setWinTitle(title)
685 690
686 691 for i in range(len(self.axesList)):
687 692 title = "Channel %d" %(i)
688 693 axes = self.axesList[i]
689 694 ychannel = y[i,:]
690 695 axes.pline(x, ychannel,
691 696 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
692 697 xlabel=xlabel, ylabel=ylabel, title=title)
693 698
694 699 self.draw()
695 700
696 701 if save:
697 702 date = thisDatetime.strftime("%Y%m%d_%H%M%S")
698 703 if figfile == None:
699 704 figfile = self.getFilename(name = date)
700 705
701 706 self.saveFigure(figpath, figfile)
702 707
703 708 class PowerProfilePlot(Figure):
704 709 __isConfig = None
705 710 __nsubplots = None
706 711
707 712 WIDTHPROF = None
708 713 HEIGHTPROF = None
709 714 PREFIX = 'spcprofile'
710 715
711 716 def __init__(self):
712 717 self.__isConfig = False
713 718 self.__nsubplots = 1
714 719
715 720 self.WIDTH = 300
716 721 self.HEIGHT = 500
717 722
718 723 def getSubplots(self):
719 724 ncol = 1
720 725 nrow = 1
721 726
722 727 return nrow, ncol
723 728
724 729 def setup(self, id, nplots, wintitle, show):
725 730
726 731 self.nplots = nplots
727 732
728 733 ncolspan = 1
729 734 colspan = 1
730 735
731 736 self.createFigure(id = id,
732 737 wintitle = wintitle,
733 738 widthplot = self.WIDTH,
734 739 heightplot = self.HEIGHT,
735 740 show=show)
736 741
737 742 nrow, ncol = self.getSubplots()
738 743
739 744 counter = 0
740 745 for y in range(nrow):
741 746 for x in range(ncol):
742 747 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
743 748
744 749 def run(self, dataOut, id, wintitle="", channelList=None,
745 750 xmin=None, xmax=None, ymin=None, ymax=None,
746 751 save=False, figpath='./', figfile=None, show=True):
747 752
748 753 if channelList == None:
749 754 channelIndexList = dataOut.channelIndexList
750 755 channelList = dataOut.channelList
751 756 else:
752 757 channelIndexList = []
753 758 for channel in channelList:
754 759 if channel not in dataOut.channelList:
755 760 raise ValueError, "Channel %d is not in dataOut.channelList"
756 761 channelIndexList.append(dataOut.channelList.index(channel))
757 762
758 763 factor = dataOut.normFactor
759 764 y = dataOut.getHeiRange()
760 765 x = dataOut.data_spc[channelIndexList,:,:]/factor
761 766 x = numpy.where(numpy.isfinite(x), x, numpy.NAN)
762 767 avg = numpy.average(x, axis=1)
763 768
764 769 avgdB = 10*numpy.log10(avg)
765 770
766 771 #thisDatetime = dataOut.datatime
767 772 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
768 773 title = wintitle + " Power Profile %s" %(thisDatetime.strftime("%d-%b-%Y"))
769 774 xlabel = "dB"
770 775 ylabel = "Range (Km)"
771 776
772 777 if not self.__isConfig:
773 778
774 779 nplots = 1
775 780
776 781 self.setup(id=id,
777 782 nplots=nplots,
778 783 wintitle=wintitle,
779 784 show=show)
780 785
781 786 if ymin == None: ymin = numpy.nanmin(y)
782 787 if ymax == None: ymax = numpy.nanmax(y)
783 788 if xmin == None: xmin = numpy.nanmin(avgdB)*0.9
784 789 if xmax == None: xmax = numpy.nanmax(avgdB)*0.9
785 790
786 791 self.__isConfig = True
787 792
788 793 self.setWinTitle(title)
789 794
790 795
791 796 title = "Power Profile: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
792 797 axes = self.axesList[0]
793 798
794 799 legendlabels = ["channel %d"%x for x in channelList]
795 800 axes.pmultiline(avgdB, y,
796 801 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
797 802 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels,
798 803 ytick_visible=True, nxticks=5,
799 804 grid='x')
800 805
801 806 self.draw()
802 807
803 808 if save:
804 809 date = thisDatetime.strftime("%Y%m%d")
805 810 if figfile == None:
806 811 figfile = self.getFilename(name = date)
807 812
808 813 self.saveFigure(figpath, figfile)
809 814
810 815 class CoherenceMap(Figure):
811 816 __isConfig = None
812 817 __nsubplots = None
813 818
814 819 WIDTHPROF = None
815 820 HEIGHTPROF = None
816 821 PREFIX = 'cmap'
817 822
818 823 def __init__(self):
819 824 self.timerange = 2*60*60
820 825 self.__isConfig = False
821 826 self.__nsubplots = 1
822 827
823 828 self.WIDTH = 800
824 829 self.HEIGHT = 150
825 830 self.WIDTHPROF = 120
826 831 self.HEIGHTPROF = 0
827 832 self.counter_imagwr = 0
828 833
829 834 self.PLOT_CODE = 3
830 835 self.FTP_WEI = None
831 836 self.EXP_CODE = None
832 837 self.SUB_EXP_CODE = None
833 838 self.PLOT_POS = None
834 839 self.counter_imagwr = 0
835 840
836 841 def getSubplots(self):
837 842 ncol = 1
838 843 nrow = self.nplots*2
839 844
840 845 return nrow, ncol
841 846
842 847 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
843 848 self.__showprofile = showprofile
844 849 self.nplots = nplots
845 850
846 851 ncolspan = 1
847 852 colspan = 1
848 853 if showprofile:
849 854 ncolspan = 7
850 855 colspan = 6
851 856 self.__nsubplots = 2
852 857
853 858 self.createFigure(id = id,
854 859 wintitle = wintitle,
855 860 widthplot = self.WIDTH + self.WIDTHPROF,
856 861 heightplot = self.HEIGHT + self.HEIGHTPROF,
857 862 show=True)
858 863
859 864 nrow, ncol = self.getSubplots()
860 865
861 866 for y in range(nrow):
862 867 for x in range(ncol):
863 868
864 869 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
865 870
866 871 if showprofile:
867 872 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
868 873
869 874 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
870 875 xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,
871 876 timerange=None,
872 877 save=False, figpath='./', figfile=None, ftp=False, wr_period=1,
873 878 coherence_cmap='jet', phase_cmap='RdBu_r', show=True,
874 879 server=None, folder=None, username=None, password=None,
875 880 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
876 881
877 882 if pairsList == None:
878 883 pairsIndexList = dataOut.pairsIndexList
879 884 else:
880 885 pairsIndexList = []
881 886 for pair in pairsList:
882 887 if pair not in dataOut.pairsList:
883 888 raise ValueError, "Pair %s is not in dataOut.pairsList" %(pair)
884 889 pairsIndexList.append(dataOut.pairsList.index(pair))
885 890
886 891 if timerange != None:
887 892 self.timerange = timerange
888 893
889 894 if pairsIndexList == []:
890 895 return
891 896
892 897 if len(pairsIndexList) > 4:
893 898 pairsIndexList = pairsIndexList[0:4]
894 899
895 900 tmin = None
896 901 tmax = None
897 902 x = dataOut.getTimeRange()
898 903 y = dataOut.getHeiRange()
899 904
900 905 #thisDatetime = dataOut.datatime
901 906 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
902 907 title = wintitle + " CoherenceMap" #: %s" %(thisDatetime.strftime("%d-%b-%Y"))
903 908 xlabel = ""
904 909 ylabel = "Range (Km)"
905 910
906 911 if not self.__isConfig:
907 912 nplots = len(pairsIndexList)
908 913 self.setup(id=id,
909 914 nplots=nplots,
910 915 wintitle=wintitle,
911 916 showprofile=showprofile,
912 917 show=show)
913 918
914 919 tmin, tmax = self.getTimeLim(x, xmin, xmax)
915 920 if ymin == None: ymin = numpy.nanmin(y)
916 921 if ymax == None: ymax = numpy.nanmax(y)
917 922 if zmin == None: zmin = 0.
918 923 if zmax == None: zmax = 1.
919 924
920 925 self.FTP_WEI = ftp_wei
921 926 self.EXP_CODE = exp_code
922 927 self.SUB_EXP_CODE = sub_exp_code
923 928 self.PLOT_POS = plot_pos
924 929
925 930 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
926 931
927 932 self.__isConfig = True
928 933
929 934 self.setWinTitle(title)
930 935
931 936 for i in range(self.nplots):
932 937
933 938 pair = dataOut.pairsList[pairsIndexList[i]]
934 939 coherenceComplex = dataOut.data_cspc[pairsIndexList[i],:,:]/numpy.sqrt(dataOut.data_spc[pair[0],:,:]*dataOut.data_spc[pair[1],:,:])
935 940 avgcoherenceComplex = numpy.average(coherenceComplex, axis=0)
936 941 coherence = numpy.abs(avgcoherenceComplex)
937 942 # coherence = numpy.abs(coherenceComplex)
938 943 # avg = numpy.average(coherence, axis=0)
939 944
940 945 z = coherence.reshape((1,-1))
941 946
942 947 counter = 0
943 948
944 949 title = "Coherence %d%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
945 950 axes = self.axesList[i*self.__nsubplots*2]
946 951 axes.pcolorbuffer(x, y, z,
947 952 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax,
948 953 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
949 954 ticksize=9, cblabel='', colormap=coherence_cmap, cbsize="1%")
950 955
951 956 if self.__showprofile:
952 957 counter += 1
953 958 axes = self.axesList[i*self.__nsubplots*2 + counter]
954 959 axes.pline(coherence, y,
955 960 xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax,
956 961 xlabel='', ylabel='', title='', ticksize=7,
957 962 ytick_visible=False, nxticks=5,
958 963 grid='x')
959 964
960 965 counter += 1
961 966 # phase = numpy.arctan(-1*coherenceComplex.imag/coherenceComplex.real)*180/numpy.pi
962 967 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
963 968 # avg = numpy.average(phase, axis=0)
964 969 z = phase.reshape((1,-1))
965 970
966 971 title = "Phase %d%d: %s" %(pair[0], pair[1], thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
967 972 axes = self.axesList[i*self.__nsubplots*2 + counter]
968 973 axes.pcolorbuffer(x, y, z,
969 974 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax, zmin=-180, zmax=180,
970 975 xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,
971 976 ticksize=9, cblabel='', colormap=phase_cmap, cbsize="1%")
972 977
973 978 if self.__showprofile:
974 979 counter += 1
975 980 axes = self.axesList[i*self.__nsubplots*2 + counter]
976 981 axes.pline(phase, y,
977 982 xmin=-180, xmax=180, ymin=ymin, ymax=ymax,
978 983 xlabel='', ylabel='', title='', ticksize=7,
979 984 ytick_visible=False, nxticks=4,
980 985 grid='x')
981 986
982 987 self.draw()
983 988
984 989 if save:
985 990
986 991 self.counter_imagwr += 1
987 992 if (self.counter_imagwr==wr_period):
988 993 if figfile == None:
989 994 figfile = self.getFilename(name = self.name)
990 995 self.saveFigure(figpath, figfile)
991 996
992 997 if ftp:
993 998 #provisionalmente envia archivos en el formato de la web en tiempo real
994 999 name = self.getNameToFtp(thisDatetime, self.FTP_WEI, self.EXP_CODE, self.SUB_EXP_CODE, self.PLOT_CODE, self.PLOT_POS)
995 1000 path = '%s%03d' %(self.PREFIX, self.id)
996 1001 ftp_file = os.path.join(path,'ftp','%s.png'%name)
997 1002 self.saveFigure(figpath, ftp_file)
998 1003 ftp_filename = os.path.join(figpath,ftp_file)
999 1004 try:
1000 1005 self.sendByFTP(ftp_filename, server, folder, username, password)
1001 1006 except:
1002 1007 raise ValueError, 'Error FTP'
1003 1008
1004 1009 self.counter_imagwr = 0
1005 1010
1006 1011
1007 1012 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
1008 1013 self.__isConfig = False
1009 1014
1010 1015 class RTIfromNoise(Figure):
1011 1016
1012 1017 __isConfig = None
1013 1018 __nsubplots = None
1014 1019
1015 1020 PREFIX = 'rtinoise'
1016 1021
1017 1022 def __init__(self):
1018 1023
1019 1024 self.timerange = 24*60*60
1020 1025 self.__isConfig = False
1021 1026 self.__nsubplots = 1
1022 1027
1023 1028 self.WIDTH = 820
1024 1029 self.HEIGHT = 200
1025 1030 self.WIDTHPROF = 120
1026 1031 self.HEIGHTPROF = 0
1027 1032 self.xdata = None
1028 1033 self.ydata = None
1029 1034
1030 1035 def getSubplots(self):
1031 1036
1032 1037 ncol = 1
1033 1038 nrow = 1
1034 1039
1035 1040 return nrow, ncol
1036 1041
1037 1042 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1038 1043
1039 1044 self.__showprofile = showprofile
1040 1045 self.nplots = nplots
1041 1046
1042 1047 ncolspan = 7
1043 1048 colspan = 6
1044 1049 self.__nsubplots = 2
1045 1050
1046 1051 self.createFigure(id = id,
1047 1052 wintitle = wintitle,
1048 1053 widthplot = self.WIDTH+self.WIDTHPROF,
1049 1054 heightplot = self.HEIGHT+self.HEIGHTPROF,
1050 1055 show=show)
1051 1056
1052 1057 nrow, ncol = self.getSubplots()
1053 1058
1054 1059 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1055 1060
1056 1061
1057 1062 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
1058 1063 xmin=None, xmax=None, ymin=None, ymax=None,
1059 1064 timerange=None,
1060 1065 save=False, figpath='./', figfile=None, show=True):
1061 1066
1062 1067 if channelList == None:
1063 1068 channelIndexList = dataOut.channelIndexList
1064 1069 channelList = dataOut.channelList
1065 1070 else:
1066 1071 channelIndexList = []
1067 1072 for channel in channelList:
1068 1073 if channel not in dataOut.channelList:
1069 1074 raise ValueError, "Channel %d is not in dataOut.channelList"
1070 1075 channelIndexList.append(dataOut.channelList.index(channel))
1071 1076
1072 1077 if timerange != None:
1073 1078 self.timerange = timerange
1074 1079
1075 1080 tmin = None
1076 1081 tmax = None
1077 1082 x = dataOut.getTimeRange()
1078 1083 y = dataOut.getHeiRange()
1079 1084 factor = dataOut.normFactor
1080 1085 noise = dataOut.getNoise()/factor
1081 1086 noisedB = 10*numpy.log10(noise)
1082 1087
1083 1088 #thisDatetime = dataOut.datatime
1084 1089 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
1085 1090 title = wintitle + " RTI Noise: %s" %(thisDatetime.strftime("%d-%b-%Y"))
1086 1091 xlabel = ""
1087 1092 ylabel = "Range (Km)"
1088 1093
1089 1094 if not self.__isConfig:
1090 1095
1091 1096 nplots = 1
1092 1097
1093 1098 self.setup(id=id,
1094 1099 nplots=nplots,
1095 1100 wintitle=wintitle,
1096 1101 showprofile=showprofile,
1097 1102 show=show)
1098 1103
1099 1104 tmin, tmax = self.getTimeLim(x, xmin, xmax)
1100 1105 if ymin == None: ymin = numpy.nanmin(noisedB)
1101 1106 if ymax == None: ymax = numpy.nanmax(noisedB)
1102 1107
1103 1108 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1104 1109 self.__isConfig = True
1105 1110
1106 1111 self.xdata = numpy.array([])
1107 1112 self.ydata = numpy.array([])
1108 1113
1109 1114 self.setWinTitle(title)
1110 1115
1111 1116
1112 1117 title = "RTI Noise %s" %(thisDatetime.strftime("%d-%b-%Y"))
1113 1118
1114 1119 legendlabels = ["channel %d"%idchannel for idchannel in channelList]
1115 1120 axes = self.axesList[0]
1116 1121
1117 1122 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1118 1123
1119 1124 if len(self.ydata)==0:
1120 1125 self.ydata = noisedB[channelIndexList].reshape(-1,1)
1121 1126 else:
1122 1127 self.ydata = numpy.hstack((self.ydata, noisedB[channelIndexList].reshape(-1,1)))
1123 1128
1124 1129
1125 1130 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1126 1131 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax,
1127 1132 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
1128 1133 XAxisAsTime=True
1129 1134 )
1130 1135
1131 1136 self.draw()
1132 1137
1133 1138 if save:
1134 1139
1135 1140 if figfile == None:
1136 1141 figfile = self.getFilename(name = self.name)
1137 1142
1138 1143 self.saveFigure(figpath, figfile)
1139 1144
1140 1145 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
1141 1146 self.__isConfig = False
1142 1147 del self.xdata
1143 1148 del self.ydata
1144 1149
1145 1150
1146 1151 class SpectraHeisScope(Figure):
1147 1152
1148 1153
1149 1154 __isConfig = None
1150 1155 __nsubplots = None
1151 1156
1152 1157 WIDTHPROF = None
1153 1158 HEIGHTPROF = None
1154 1159 PREFIX = 'spc'
1155 1160
1156 1161 def __init__(self):
1157 1162
1158 1163 self.__isConfig = False
1159 1164 self.__nsubplots = 1
1160 1165
1161 1166 self.WIDTH = 230
1162 1167 self.HEIGHT = 250
1163 1168 self.WIDTHPROF = 120
1164 1169 self.HEIGHTPROF = 0
1165 1170 self.counter_imagwr = 0
1166 1171
1167 1172 def getSubplots(self):
1168 1173
1169 1174 ncol = int(numpy.sqrt(self.nplots)+0.9)
1170 1175 nrow = int(self.nplots*1./ncol + 0.9)
1171 1176
1172 1177 return nrow, ncol
1173 1178
1174 1179 def setup(self, id, nplots, wintitle, show):
1175 1180
1176 1181 showprofile = False
1177 1182 self.__showprofile = showprofile
1178 1183 self.nplots = nplots
1179 1184
1180 1185 ncolspan = 1
1181 1186 colspan = 1
1182 1187 if showprofile:
1183 1188 ncolspan = 3
1184 1189 colspan = 2
1185 1190 self.__nsubplots = 2
1186 1191
1187 1192 self.createFigure(id = id,
1188 1193 wintitle = wintitle,
1189 1194 widthplot = self.WIDTH + self.WIDTHPROF,
1190 1195 heightplot = self.HEIGHT + self.HEIGHTPROF,
1191 1196 show = show)
1192 1197
1193 1198 nrow, ncol = self.getSubplots()
1194 1199
1195 1200 counter = 0
1196 1201 for y in range(nrow):
1197 1202 for x in range(ncol):
1198 1203
1199 1204 if counter >= self.nplots:
1200 1205 break
1201 1206
1202 1207 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1)
1203 1208
1204 1209 if showprofile:
1205 1210 self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1)
1206 1211
1207 1212 counter += 1
1208 1213
1209 1214 # __isConfig = None
1210 1215 # def __init__(self):
1211 1216 #
1212 1217 # self.__isConfig = False
1213 1218 # self.WIDTH = 600
1214 1219 # self.HEIGHT = 200
1215 1220 #
1216 1221 # def getSubplots(self):
1217 1222 #
1218 1223 # nrow = self.nplots
1219 1224 # ncol = 3
1220 1225 # return nrow, ncol
1221 1226 #
1222 1227 # def setup(self, id, nplots, wintitle):
1223 1228 #
1224 1229 # self.nplots = nplots
1225 1230 #
1226 1231 # self.createFigure(id, wintitle)
1227 1232 #
1228 1233 # nrow,ncol = self.getSubplots()
1229 1234 # colspan = 3
1230 1235 # rowspan = 1
1231 1236 #
1232 1237 # for i in range(nplots):
1233 1238 # self.addAxes(nrow, ncol, i, 0, colspan, rowspan)
1234 1239
1235 1240 def run(self, dataOut, id, wintitle="", channelList=None,
1236 1241 xmin=None, xmax=None, ymin=None, ymax=None, save=False,
1237 1242 figpath='./', figfile=None, ftp=False, wr_period=1, show=True):
1238 1243
1239 1244 """
1240 1245
1241 1246 Input:
1242 1247 dataOut :
1243 1248 id :
1244 1249 wintitle :
1245 1250 channelList :
1246 1251 xmin : None,
1247 1252 xmax : None,
1248 1253 ymin : None,
1249 1254 ymax : None,
1250 1255 """
1251 1256
1252 1257 if dataOut.realtime:
1253 1258 if not(isRealtime(utcdatatime = dataOut.utctime)):
1254 1259 print 'Skipping this plot function'
1255 1260 return
1256 1261
1257 1262 if channelList == None:
1258 1263 channelIndexList = dataOut.channelIndexList
1259 1264 else:
1260 1265 channelIndexList = []
1261 1266 for channel in channelList:
1262 1267 if channel not in dataOut.channelList:
1263 1268 raise ValueError, "Channel %d is not in dataOut.channelList"
1264 1269 channelIndexList.append(dataOut.channelList.index(channel))
1265 1270
1266 1271 # x = dataOut.heightList
1267 1272 c = 3E8
1268 1273 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1269 1274 #deberia cambiar para el caso de 1Mhz y 100KHz
1270 1275 x = numpy.arange(-1*dataOut.nHeights/2.,dataOut.nHeights/2.)*(c/(2*deltaHeight*dataOut.nHeights*1000))
1271 1276 x= x/(10000.0)
1272 1277 # y = dataOut.data[channelIndexList,:] * numpy.conjugate(dataOut.data[channelIndexList,:])
1273 1278 # y = y.real
1274 1279 datadB = 10.*numpy.log10(dataOut.data_spc)
1275 1280 y = datadB
1276 1281
1277 1282 #thisDatetime = dataOut.datatime
1278 1283 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
1279 1284 title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1280 1285 xlabel = "Frequency x 10000"
1281 1286 ylabel = "Intensity (dB)"
1282 1287
1283 1288 if not self.__isConfig:
1284 1289 nplots = len(channelIndexList)
1285 1290
1286 1291 self.setup(id=id,
1287 1292 nplots=nplots,
1288 1293 wintitle=wintitle,
1289 1294 show=show)
1290 1295
1291 1296 if xmin == None: xmin = numpy.nanmin(x)
1292 1297 if xmax == None: xmax = numpy.nanmax(x)
1293 1298 if ymin == None: ymin = numpy.nanmin(y)
1294 1299 if ymax == None: ymax = numpy.nanmax(y)
1295 1300
1296 1301 self.__isConfig = True
1297 1302
1298 1303 self.setWinTitle(title)
1299 1304
1300 1305 for i in range(len(self.axesList)):
1301 1306 ychannel = y[i,:]
1302 1307 title = "Channel %d - peak:%.2f" %(i,numpy.max(ychannel))
1303 1308 axes = self.axesList[i]
1304 1309 axes.pline(x, ychannel,
1305 1310 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
1306 1311 xlabel=xlabel, ylabel=ylabel, title=title, grid='both')
1307 1312
1308 1313
1309 1314 self.draw()
1310 1315
1311 1316 if save:
1312 1317 date = thisDatetime.strftime("%Y%m%d_%H%M%S")
1313 1318 if figfile == None:
1314 1319 figfile = self.getFilename(name = date)
1315 1320
1316 1321 self.saveFigure(figpath, figfile)
1317 1322
1318 1323 self.counter_imagwr += 1
1319 1324 if (ftp and (self.counter_imagwr==wr_period)):
1320 1325 figfilename = os.path.join(figpath,figfile)
1321 1326 self.sendByFTP(figfilename)
1322 1327 self.counter_imagwr = 0
1323 1328
1324 1329
1325 1330 class RTIfromSpectraHeis(Figure):
1326 1331
1327 1332 __isConfig = None
1328 1333 __nsubplots = None
1329 1334
1330 1335 PREFIX = 'rtinoise'
1331 1336
1332 1337 def __init__(self):
1333 1338
1334 1339 self.timerange = 24*60*60
1335 1340 self.__isConfig = False
1336 1341 self.__nsubplots = 1
1337 1342
1338 1343 self.WIDTH = 820
1339 1344 self.HEIGHT = 200
1340 1345 self.WIDTHPROF = 120
1341 1346 self.HEIGHTPROF = 0
1342 1347 self.counter_imagwr = 0
1343 1348 self.xdata = None
1344 1349 self.ydata = None
1345 1350
1346 1351 def getSubplots(self):
1347 1352
1348 1353 ncol = 1
1349 1354 nrow = 1
1350 1355
1351 1356 return nrow, ncol
1352 1357
1353 1358 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
1354 1359
1355 1360 self.__showprofile = showprofile
1356 1361 self.nplots = nplots
1357 1362
1358 1363 ncolspan = 7
1359 1364 colspan = 6
1360 1365 self.__nsubplots = 2
1361 1366
1362 1367 self.createFigure(id = id,
1363 1368 wintitle = wintitle,
1364 1369 widthplot = self.WIDTH+self.WIDTHPROF,
1365 1370 heightplot = self.HEIGHT+self.HEIGHTPROF,
1366 1371 show = show)
1367 1372
1368 1373 nrow, ncol = self.getSubplots()
1369 1374
1370 1375 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
1371 1376
1372 1377
1373 1378 def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True',
1374 1379 xmin=None, xmax=None, ymin=None, ymax=None,
1375 1380 timerange=None,
1376 1381 save=False, figpath='./', figfile=None, ftp=False, wr_period=1, show=True):
1377 1382
1378 1383 if channelList == None:
1379 1384 channelIndexList = dataOut.channelIndexList
1380 1385 channelList = dataOut.channelList
1381 1386 else:
1382 1387 channelIndexList = []
1383 1388 for channel in channelList:
1384 1389 if channel not in dataOut.channelList:
1385 1390 raise ValueError, "Channel %d is not in dataOut.channelList"
1386 1391 channelIndexList.append(dataOut.channelList.index(channel))
1387 1392
1388 1393 if timerange != None:
1389 1394 self.timerange = timerange
1390 1395
1391 1396 tmin = None
1392 1397 tmax = None
1393 1398 x = dataOut.getTimeRange()
1394 1399 y = dataOut.getHeiRange()
1395 1400
1396 1401 factor = 1
1397 1402 data = dataOut.data_spc/factor
1398 1403 data = numpy.average(data,axis=1)
1399 1404 datadB = 10*numpy.log10(data)
1400 1405
1401 1406 # factor = dataOut.normFactor
1402 1407 # noise = dataOut.getNoise()/factor
1403 1408 # noisedB = 10*numpy.log10(noise)
1404 1409
1405 1410 #thisDatetime = dataOut.datatime
1406 1411 thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[1])
1407 1412 title = wintitle + " RTI: %s" %(thisDatetime.strftime("%d-%b-%Y"))
1408 1413 xlabel = "Local Time"
1409 1414 ylabel = "Intensity (dB)"
1410 1415
1411 1416 if not self.__isConfig:
1412 1417
1413 1418 nplots = 1
1414 1419
1415 1420 self.setup(id=id,
1416 1421 nplots=nplots,
1417 1422 wintitle=wintitle,
1418 1423 showprofile=showprofile,
1419 1424 show=show)
1420 1425
1421 1426 tmin, tmax = self.getTimeLim(x, xmin, xmax)
1422 1427 if ymin == None: ymin = numpy.nanmin(datadB)
1423 1428 if ymax == None: ymax = numpy.nanmax(datadB)
1424 1429
1425 1430 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
1426 1431 self.__isConfig = True
1427 1432
1428 1433 self.xdata = numpy.array([])
1429 1434 self.ydata = numpy.array([])
1430 1435
1431 1436 self.setWinTitle(title)
1432 1437
1433 1438
1434 1439 # title = "RTI %s" %(thisDatetime.strftime("%d-%b-%Y"))
1435 1440 title = "RTI-Noise - %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S"))
1436 1441
1437 1442 legendlabels = ["channel %d"%idchannel for idchannel in channelList]
1438 1443 axes = self.axesList[0]
1439 1444
1440 1445 self.xdata = numpy.hstack((self.xdata, x[0:1]))
1441 1446
1442 1447 if len(self.ydata)==0:
1443 1448 self.ydata = datadB[channelIndexList].reshape(-1,1)
1444 1449 else:
1445 1450 self.ydata = numpy.hstack((self.ydata, datadB[channelIndexList].reshape(-1,1)))
1446 1451
1447 1452
1448 1453 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
1449 1454 xmin=tmin, xmax=tmax, ymin=ymin, ymax=ymax,
1450 1455 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='.', markersize=8, linestyle="solid", grid='both',
1451 1456 XAxisAsTime=True
1452 1457 )
1453 1458
1454 1459 self.draw()
1455 1460
1456 1461 if save:
1457 1462
1458 1463 if figfile == None:
1459 1464 figfile = self.getFilename(name = self.name)
1460 1465
1461 1466 self.saveFigure(figpath, figfile)
1462 1467
1463 1468 self.counter_imagwr += 1
1464 1469 if (ftp and (self.counter_imagwr==wr_period)):
1465 1470 figfilename = os.path.join(figpath,figfile)
1466 1471 self.sendByFTP(figfilename)
1467 1472 self.counter_imagwr = 0
1468 1473
1469 1474 if x[1] + (x[1]-x[0]) >= self.axesList[0].xmax:
1470 1475 self.__isConfig = False
1471 1476 del self.xdata
1472 1477 del self.ydata
1473 1478
1474 1479
1475 1480 No newline at end of file
@@ -1,1655 +1,1655
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 try:
16 16 import cfunctions
17 17 except:
18 18 pass
19 19
20 20 class ProcessingUnit:
21 21
22 22 """
23 23 Esta es la clase base para el procesamiento de datos.
24 24
25 25 Contiene el metodo "call" para llamar operaciones. Las operaciones pueden ser:
26 26 - Metodos internos (callMethod)
27 27 - Objetos del tipo Operation (callObject). Antes de ser llamados, estos objetos
28 28 tienen que ser agreagados con el metodo "add".
29 29
30 30 """
31 31 # objeto de datos de entrada (Voltage, Spectra o Correlation)
32 32 dataIn = None
33 33
34 34 # objeto de datos de entrada (Voltage, Spectra o Correlation)
35 35 dataOut = None
36 36
37 37
38 38 objectDict = None
39 39
40 40 def __init__(self):
41 41
42 42 self.objectDict = {}
43 43
44 44 def init(self):
45 45
46 46 raise ValueError, "Not implemented"
47 47
48 48 def addOperation(self, object, objId):
49 49
50 50 """
51 51 Agrega el objeto "object" a la lista de objetos "self.objectList" y retorna el
52 52 identificador asociado a este objeto.
53 53
54 54 Input:
55 55
56 56 object : objeto de la clase "Operation"
57 57
58 58 Return:
59 59
60 60 objId : identificador del objeto, necesario para ejecutar la operacion
61 61 """
62 62
63 63 self.objectDict[objId] = object
64 64
65 65 return objId
66 66
67 67 def operation(self, **kwargs):
68 68
69 69 """
70 70 Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los
71 71 atributos del objeto dataOut
72 72
73 73 Input:
74 74
75 75 **kwargs : Diccionario de argumentos de la funcion a ejecutar
76 76 """
77 77
78 78 raise ValueError, "ImplementedError"
79 79
80 80 def callMethod(self, name, **kwargs):
81 81
82 82 """
83 83 Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase.
84 84
85 85 Input:
86 86 name : nombre del metodo a ejecutar
87 87
88 88 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
89 89
90 90 """
91 91 if name != 'run':
92 92
93 93 if name == 'init' and self.dataIn.isEmpty():
94 94 self.dataOut.flagNoData = True
95 95 return False
96 96
97 97 if name != 'init' and self.dataOut.isEmpty():
98 98 return False
99 99
100 100 methodToCall = getattr(self, name)
101 101
102 102 methodToCall(**kwargs)
103 103
104 104 if name != 'run':
105 105 return True
106 106
107 107 if self.dataOut.isEmpty():
108 108 return False
109 109
110 110 return True
111 111
112 112 def callObject(self, objId, **kwargs):
113 113
114 114 """
115 115 Ejecuta la operacion asociada al identificador del objeto "objId"
116 116
117 117 Input:
118 118
119 119 objId : identificador del objeto a ejecutar
120 120
121 121 **kwargs : diccionario con los nombres y valores de la funcion a ejecutar.
122 122
123 123 Return:
124 124
125 125 None
126 126 """
127 127
128 128 if self.dataOut.isEmpty():
129 129 return False
130 130
131 131 object = self.objectDict[objId]
132 132
133 133 object.run(self.dataOut, **kwargs)
134 134
135 135 return True
136 136
137 137 def call(self, operationConf, **kwargs):
138 138
139 139 """
140 140 Return True si ejecuta la operacion "operationConf.name" con los
141 141 argumentos "**kwargs". False si la operacion no se ha ejecutado.
142 142 La operacion puede ser de dos tipos:
143 143
144 144 1. Un metodo propio de esta clase:
145 145
146 146 operation.type = "self"
147 147
148 148 2. El metodo "run" de un objeto del tipo Operation o de un derivado de ella:
149 149 operation.type = "other".
150 150
151 151 Este objeto de tipo Operation debe de haber sido agregado antes con el metodo:
152 152 "addOperation" e identificado con el operation.id
153 153
154 154
155 155 con el id de la operacion.
156 156
157 157 Input:
158 158
159 159 Operation : Objeto del tipo operacion con los atributos: name, type y id.
160 160
161 161 """
162 162
163 163 if operationConf.type == 'self':
164 164 sts = self.callMethod(operationConf.name, **kwargs)
165 165
166 166 if operationConf.type == 'other':
167 167 sts = self.callObject(operationConf.id, **kwargs)
168 168
169 169 return sts
170 170
171 171 def setInput(self, dataIn):
172 172
173 173 self.dataIn = dataIn
174 174
175 175 def getOutput(self):
176 176
177 177 return self.dataOut
178 178
179 179 class Operation():
180 180
181 181 """
182 182 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
183 183 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
184 184 acumulacion dentro de esta clase
185 185
186 186 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
187 187
188 188 """
189 189
190 190 __buffer = None
191 191 __isConfig = False
192 192
193 193 def __init__(self):
194 194
195 195 pass
196 196
197 197 def run(self, dataIn, **kwargs):
198 198
199 199 """
200 200 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los atributos del objeto dataIn.
201 201
202 202 Input:
203 203
204 204 dataIn : objeto del tipo JROData
205 205
206 206 Return:
207 207
208 208 None
209 209
210 210 Affected:
211 211 __buffer : buffer de recepcion de datos.
212 212
213 213 """
214 214
215 215 raise ValueError, "ImplementedError"
216 216
217 217 class VoltageProc(ProcessingUnit):
218 218
219 219
220 220 def __init__(self):
221 221
222 222 self.objectDict = {}
223 223 self.dataOut = Voltage()
224 224 self.flip = 1
225 225
226 226 def init(self):
227 227
228 228 self.dataOut.copy(self.dataIn)
229 229 # No necesita copiar en cada init() los atributos de dataIn
230 230 # la copia deberia hacerse por cada nuevo bloque de datos
231 231
232 232 def selectChannels(self, channelList):
233 233
234 234 channelIndexList = []
235 235
236 236 for channel in channelList:
237 237 index = self.dataOut.channelList.index(channel)
238 238 channelIndexList.append(index)
239 239
240 240 self.selectChannelsByIndex(channelIndexList)
241 241
242 242 def selectChannelsByIndex(self, channelIndexList):
243 243 """
244 244 Selecciona un bloque de datos en base a canales segun el channelIndexList
245 245
246 246 Input:
247 247 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
248 248
249 249 Affected:
250 250 self.dataOut.data
251 251 self.dataOut.channelIndexList
252 252 self.dataOut.nChannels
253 253 self.dataOut.m_ProcessingHeader.totalSpectra
254 254 self.dataOut.systemHeaderObj.numChannels
255 255 self.dataOut.m_ProcessingHeader.blockSize
256 256
257 257 Return:
258 258 None
259 259 """
260 260
261 261 for channelIndex in channelIndexList:
262 262 if channelIndex not in self.dataOut.channelIndexList:
263 263 print channelIndexList
264 264 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
265 265
266 266 nChannels = len(channelIndexList)
267 267
268 268 data = self.dataOut.data[channelIndexList,:]
269 269
270 270 self.dataOut.data = data
271 271 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
272 272 # self.dataOut.nChannels = nChannels
273 273
274 274 return 1
275 275
276 276 def selectHeights(self, minHei=None, maxHei=None):
277 277 """
278 278 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
279 279 minHei <= height <= maxHei
280 280
281 281 Input:
282 282 minHei : valor minimo de altura a considerar
283 283 maxHei : valor maximo de altura a considerar
284 284
285 285 Affected:
286 286 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
287 287
288 288 Return:
289 289 1 si el metodo se ejecuto con exito caso contrario devuelve 0
290 290 """
291 291
292 292 if minHei == None:
293 293 minHei = self.dataOut.heightList[0]
294 294
295 295 if maxHei == None:
296 296 maxHei = self.dataOut.heightList[-1]
297 297
298 298 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
299 299 raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
300 300
301 301
302 302 if (maxHei > self.dataOut.heightList[-1]):
303 303 maxHei = self.dataOut.heightList[-1]
304 304 # raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
305 305
306 306 minIndex = 0
307 307 maxIndex = 0
308 308 heights = self.dataOut.heightList
309 309
310 310 inda = numpy.where(heights >= minHei)
311 311 indb = numpy.where(heights <= maxHei)
312 312
313 313 try:
314 314 minIndex = inda[0][0]
315 315 except:
316 316 minIndex = 0
317 317
318 318 try:
319 319 maxIndex = indb[0][-1]
320 320 except:
321 321 maxIndex = len(heights)
322 322
323 323 self.selectHeightsByIndex(minIndex, maxIndex)
324 324
325 325 return 1
326 326
327 327
328 328 def selectHeightsByIndex(self, minIndex, maxIndex):
329 329 """
330 330 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
331 331 minIndex <= index <= maxIndex
332 332
333 333 Input:
334 334 minIndex : valor de indice minimo de altura a considerar
335 335 maxIndex : valor de indice maximo de altura a considerar
336 336
337 337 Affected:
338 338 self.dataOut.data
339 339 self.dataOut.heightList
340 340
341 341 Return:
342 342 1 si el metodo se ejecuto con exito caso contrario devuelve 0
343 343 """
344 344
345 345 if (minIndex < 0) or (minIndex > maxIndex):
346 346 raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
347 347
348 348 if (maxIndex >= self.dataOut.nHeights):
349 349 maxIndex = self.dataOut.nHeights-1
350 350 # raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
351 351
352 352 nHeights = maxIndex - minIndex + 1
353 353
354 354 #voltage
355 355 data = self.dataOut.data[:,minIndex:maxIndex+1]
356 356
357 357 firstHeight = self.dataOut.heightList[minIndex]
358 358
359 359 self.dataOut.data = data
360 360 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1]
361 361
362 362 return 1
363 363
364 364
365 365 def filterByHeights(self, window):
366 366 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0]
367 367
368 368 if window == None:
369 369 window = (self.dataOut.radarControllerHeaderObj.txA/self.dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
370 370
371 371 newdelta = deltaHeight * window
372 372 r = self.dataOut.data.shape[1] % window
373 373 buffer = self.dataOut.data[:,0:self.dataOut.data.shape[1]-r]
374 374 buffer = buffer.reshape(self.dataOut.data.shape[0],self.dataOut.data.shape[1]/window,window)
375 375 buffer = numpy.sum(buffer,2)
376 376 self.dataOut.data = buffer
377 377 self.dataOut.heightList = numpy.arange(self.dataOut.heightList[0],newdelta*(self.dataOut.nHeights-r)/window,newdelta)
378 378 self.dataOut.windowOfFilter = window
379 379
380 380 def deFlip(self):
381 381 self.dataOut.data *= self.flip
382 382 self.flip *= -1.
383 383
384 384 def setRadarFrequency(self, frequency=None):
385 385 if frequency != None:
386 386 self.dataOut.frequency = frequency
387 387
388 388 return 1
389 389
390 390 class CohInt(Operation):
391 391
392 392 __isConfig = False
393 393
394 394 __profIndex = 0
395 395 __withOverapping = False
396 396
397 397 __byTime = False
398 398 __initime = None
399 399 __lastdatatime = None
400 400 __integrationtime = None
401 401
402 402 __buffer = None
403 403
404 404 __dataReady = False
405 405
406 406 n = None
407 407
408 408
409 409 def __init__(self):
410 410
411 411 self.__isConfig = False
412 412
413 413 def setup(self, n=None, timeInterval=None, overlapping=False):
414 414 """
415 415 Set the parameters of the integration class.
416 416
417 417 Inputs:
418 418
419 419 n : Number of coherent integrations
420 420 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
421 421 overlapping :
422 422
423 423 """
424 424
425 425 self.__initime = None
426 426 self.__lastdatatime = 0
427 427 self.__buffer = None
428 428 self.__dataReady = False
429 429
430 430
431 431 if n == None and timeInterval == None:
432 432 raise ValueError, "n or timeInterval should be specified ..."
433 433
434 434 if n != None:
435 435 self.n = n
436 436 self.__byTime = False
437 437 else:
438 438 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
439 439 self.n = 9999
440 440 self.__byTime = True
441 441
442 442 if overlapping:
443 443 self.__withOverapping = True
444 444 self.__buffer = None
445 445 else:
446 446 self.__withOverapping = False
447 447 self.__buffer = 0
448 448
449 449 self.__profIndex = 0
450 450
451 451 def putData(self, data):
452 452
453 453 """
454 454 Add a profile to the __buffer and increase in one the __profileIndex
455 455
456 456 """
457 457
458 458 if not self.__withOverapping:
459 459 self.__buffer += data.copy()
460 460 self.__profIndex += 1
461 461 return
462 462
463 463 #Overlapping data
464 464 nChannels, nHeis = data.shape
465 465 data = numpy.reshape(data, (1, nChannels, nHeis))
466 466
467 467 #If the buffer is empty then it takes the data value
468 468 if self.__buffer == None:
469 469 self.__buffer = data
470 470 self.__profIndex += 1
471 471 return
472 472
473 473 #If the buffer length is lower than n then stakcing the data value
474 474 if self.__profIndex < self.n:
475 475 self.__buffer = numpy.vstack((self.__buffer, data))
476 476 self.__profIndex += 1
477 477 return
478 478
479 479 #If the buffer length is equal to n then replacing the last buffer value with the data value
480 480 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
481 481 self.__buffer[self.n-1] = data
482 482 self.__profIndex = self.n
483 483 return
484 484
485 485
486 486 def pushData(self):
487 487 """
488 488 Return the sum of the last profiles and the profiles used in the sum.
489 489
490 490 Affected:
491 491
492 492 self.__profileIndex
493 493
494 494 """
495 495
496 496 if not self.__withOverapping:
497 497 data = self.__buffer
498 498 n = self.__profIndex
499 499
500 500 self.__buffer = 0
501 501 self.__profIndex = 0
502 502
503 503 return data, n
504 504
505 505 #Integration with Overlapping
506 506 data = numpy.sum(self.__buffer, axis=0)
507 507 n = self.__profIndex
508 508
509 509 return data, n
510 510
511 511 def byProfiles(self, data):
512 512
513 513 self.__dataReady = False
514 514 avgdata = None
515 515 n = None
516 516
517 517 self.putData(data)
518 518
519 519 if self.__profIndex == self.n:
520 520
521 521 avgdata, n = self.pushData()
522 522 self.__dataReady = True
523 523
524 524 return avgdata
525 525
526 526 def byTime(self, data, datatime):
527 527
528 528 self.__dataReady = False
529 529 avgdata = None
530 530 n = None
531 531
532 532 self.putData(data)
533 533
534 534 if (datatime - self.__initime) >= self.__integrationtime:
535 535 avgdata, n = self.pushData()
536 536 self.n = n
537 537 self.__dataReady = True
538 538
539 539 return avgdata
540 540
541 541 def integrate(self, data, datatime=None):
542 542
543 543 if self.__initime == None:
544 544 self.__initime = datatime
545 545
546 546 if self.__byTime:
547 547 avgdata = self.byTime(data, datatime)
548 548 else:
549 549 avgdata = self.byProfiles(data)
550 550
551 551
552 552 self.__lastdatatime = datatime
553 553
554 554 if avgdata == None:
555 555 return None, None
556 556
557 557 avgdatatime = self.__initime
558 558
559 559 deltatime = datatime -self.__lastdatatime
560 560
561 561 if not self.__withOverapping:
562 562 self.__initime = datatime
563 563 else:
564 564 self.__initime += deltatime
565 565
566 566 return avgdata, avgdatatime
567 567
568 568 def run(self, dataOut, **kwargs):
569 569
570 570 if not self.__isConfig:
571 571 self.setup(**kwargs)
572 572 self.__isConfig = True
573 573
574 574 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
575 575
576 576 # dataOut.timeInterval *= n
577 577 dataOut.flagNoData = True
578 578
579 579 if self.__dataReady:
580 580 dataOut.data = avgdata
581 581 dataOut.nCohInt *= self.n
582 582 dataOut.utctime = avgdatatime
583 583 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
584 584 dataOut.flagNoData = False
585 585
586 586
587 587 class Decoder(Operation):
588 588
589 589 __isConfig = False
590 590 __profIndex = 0
591 591
592 592 code = None
593 593
594 594 nCode = None
595 595 nBaud = None
596 596
597 597 def __init__(self):
598 598
599 599 self.__isConfig = False
600 600
601 601 def setup(self, code, shape):
602 602
603 603 self.__profIndex = 0
604 604
605 605 self.code = code
606 606
607 607 self.nCode = len(code)
608 608 self.nBaud = len(code[0])
609 609
610 610 self.__nChannels, self.__nHeis = shape
611 611
612 612 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
613 613
614 614 __codeBuffer[:,0:self.nBaud] = self.code
615 615
616 616 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
617 617
618 618 self.ndatadec = self.__nHeis - self.nBaud + 1
619 619
620 620 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
621 621
622 622 def convolutionInFreq(self, data):
623 623
624 624 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
625 625
626 626 fft_data = numpy.fft.fft(data, axis=1)
627 627
628 628 conv = fft_data*fft_code
629 629
630 630 data = numpy.fft.ifft(conv,axis=1)
631 631
632 632 datadec = data[:,:-self.nBaud+1]
633 633
634 634 return datadec
635 635
636 636 def convolutionInFreqOpt(self, data):
637 637
638 638 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
639 639
640 640 data = cfunctions.decoder(fft_code, data)
641 641
642 642 datadec = data[:,:-self.nBaud+1]
643 643
644 644 return datadec
645 645
646 646 def convolutionInTime(self, data):
647 647
648 648 code = self.code[self.__profIndex]
649 649
650 650 for i in range(self.__nChannels):
651 651 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='valid')
652 652
653 653 return self.datadecTime
654 654
655 655 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0):
656 656
657 657 if not self.__isConfig:
658 658
659 659 if code == None:
660 660 code = dataOut.code
661 661 else:
662 662 code = numpy.array(code).reshape(nCode,nBaud)
663 663 dataOut.code = code
664 664 dataOut.nCode = nCode
665 665 dataOut.nBaud = nBaud
666 666
667 667 if code == None:
668 668 return 1
669 669
670 670 self.setup(code, dataOut.data.shape)
671 671 self.__isConfig = True
672 672
673 673 if mode == 0:
674 674 datadec = self.convolutionInTime(dataOut.data)
675 675
676 676 if mode == 1:
677 677 datadec = self.convolutionInFreq(dataOut.data)
678 678
679 679 if mode == 2:
680 680 datadec = self.convolutionInFreqOpt(dataOut.data)
681 681
682 682 dataOut.data = datadec
683 683
684 684 dataOut.heightList = dataOut.heightList[0:self.ndatadec]
685 685
686 686 dataOut.flagDecodeData = True #asumo q la data no esta decodificada
687 687
688 688 if self.__profIndex == self.nCode-1:
689 689 self.__profIndex = 0
690 690 return 1
691 691
692 692 self.__profIndex += 1
693 693
694 694 return 1
695 695 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
696 696
697 697
698 698
699 699 class SpectraProc(ProcessingUnit):
700 700
701 701 def __init__(self):
702 702
703 703 self.objectDict = {}
704 704 self.buffer = None
705 705 self.firstdatatime = None
706 706 self.profIndex = 0
707 707 self.dataOut = Spectra()
708 708
709 709 def __updateObjFromInput(self):
710 710
711 711 self.dataOut.timeZone = self.dataIn.timeZone
712 712 self.dataOut.dstFlag = self.dataIn.dstFlag
713 713 self.dataOut.errorCount = self.dataIn.errorCount
714 714 self.dataOut.useLocalTime = self.dataIn.useLocalTime
715 715
716 716 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
717 717 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
718 718 self.dataOut.channelList = self.dataIn.channelList
719 719 self.dataOut.heightList = self.dataIn.heightList
720 720 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
721 721 # self.dataOut.nHeights = self.dataIn.nHeights
722 722 # self.dataOut.nChannels = self.dataIn.nChannels
723 723 self.dataOut.nBaud = self.dataIn.nBaud
724 724 self.dataOut.nCode = self.dataIn.nCode
725 725 self.dataOut.code = self.dataIn.code
726 726 self.dataOut.nProfiles = self.dataOut.nFFTPoints
727 727 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
728 728 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
729 729 self.dataOut.utctime = self.firstdatatime
730 730 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
731 731 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
732 732 # self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
733 733 self.dataOut.nCohInt = self.dataIn.nCohInt
734 734 self.dataOut.nIncohInt = 1
735 735 self.dataOut.ippSeconds = self.dataIn.ippSeconds
736 736 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
737 737
738 738 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nFFTPoints*self.dataOut.nIncohInt
739 739 self.dataOut.frequency = self.dataIn.frequency
740 740
741 741 def __getFft(self):
742 742 """
743 743 Convierte valores de Voltaje a Spectra
744 744
745 745 Affected:
746 746 self.dataOut.data_spc
747 747 self.dataOut.data_cspc
748 748 self.dataOut.data_dc
749 749 self.dataOut.heightList
750 750 self.profIndex
751 751 self.buffer
752 752 self.dataOut.flagNoData
753 753 """
754 fft_volt = numpy.fft.fft(self.buffer,axis=1)
754 fft_volt = numpy.fft.fft(self.buffer,n=self.dataOut.nFFTPoints,axis=1)
755 755 fft_volt = fft_volt.astype(numpy.dtype('complex'))
756 756 dc = fft_volt[:,0,:]
757 757
758 758 #calculo de self-spectra
759 759 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
760 760 spc = fft_volt * numpy.conjugate(fft_volt)
761 761 spc = spc.real
762 762
763 763 blocksize = 0
764 764 blocksize += dc.size
765 765 blocksize += spc.size
766 766
767 767 cspc = None
768 768 pairIndex = 0
769 769 if self.dataOut.pairsList != None:
770 770 #calculo de cross-spectra
771 771 cspc = numpy.zeros((self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
772 772 for pair in self.dataOut.pairsList:
773 773 cspc[pairIndex,:,:] = fft_volt[pair[0],:,:] * numpy.conjugate(fft_volt[pair[1],:,:])
774 774 pairIndex += 1
775 775 blocksize += cspc.size
776 776
777 777 self.dataOut.data_spc = spc
778 778 self.dataOut.data_cspc = cspc
779 779 self.dataOut.data_dc = dc
780 780 self.dataOut.blockSize = blocksize
781 781 self.dataOut.flagShiftFFT = False
782 782
783 def init(self, nFFTPoints=None, pairsList=None):
783 def init(self, nProfiles, nFFTPoints=None, pairsList=None):
784 784
785 785 self.dataOut.flagNoData = True
786 786
787 787 if self.dataIn.type == "Spectra":
788 788 self.dataOut.copy(self.dataIn)
789 789 return
790 790
791 791 if self.dataIn.type == "Voltage":
792 792
793 793 if nFFTPoints == None:
794 794 raise ValueError, "This SpectraProc.init() need nFFTPoints input variable"
795 795
796 796 if pairsList == None:
797 797 nPairs = 0
798 798 else:
799 799 nPairs = len(pairsList)
800 800
801 801 self.dataOut.nFFTPoints = nFFTPoints
802 802 self.dataOut.pairsList = pairsList
803 803 self.dataOut.nPairs = nPairs
804 804
805 805 if self.buffer == None:
806 806 self.buffer = numpy.zeros((self.dataIn.nChannels,
807 self.dataOut.nFFTPoints,
807 nProfiles,
808 808 self.dataIn.nHeights),
809 809 dtype='complex')
810 810
811 811
812 812 self.buffer[:,self.profIndex,:] = self.dataIn.data.copy()
813 813 self.profIndex += 1
814 814
815 815 if self.firstdatatime == None:
816 816 self.firstdatatime = self.dataIn.utctime
817 817
818 818 if self.profIndex == self.dataOut.nFFTPoints:
819 819 self.__updateObjFromInput()
820 820 self.__getFft()
821 821
822 822 self.dataOut.flagNoData = False
823 823
824 824 self.buffer = None
825 825 self.firstdatatime = None
826 826 self.profIndex = 0
827 827
828 828 return
829 829
830 830 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
831 831
832 832 def selectChannels(self, channelList):
833 833
834 834 channelIndexList = []
835 835
836 836 for channel in channelList:
837 837 index = self.dataOut.channelList.index(channel)
838 838 channelIndexList.append(index)
839 839
840 840 self.selectChannelsByIndex(channelIndexList)
841 841
842 842 def selectChannelsByIndex(self, channelIndexList):
843 843 """
844 844 Selecciona un bloque de datos en base a canales segun el channelIndexList
845 845
846 846 Input:
847 847 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
848 848
849 849 Affected:
850 850 self.dataOut.data_spc
851 851 self.dataOut.channelIndexList
852 852 self.dataOut.nChannels
853 853
854 854 Return:
855 855 None
856 856 """
857 857
858 858 for channelIndex in channelIndexList:
859 859 if channelIndex not in self.dataOut.channelIndexList:
860 860 print channelIndexList
861 861 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
862 862
863 863 nChannels = len(channelIndexList)
864 864
865 865 data_spc = self.dataOut.data_spc[channelIndexList,:]
866 866
867 867 self.dataOut.data_spc = data_spc
868 868 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
869 869 # self.dataOut.nChannels = nChannels
870 870
871 871 return 1
872 872
873 873 def selectHeights(self, minHei, maxHei):
874 874 """
875 875 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
876 876 minHei <= height <= maxHei
877 877
878 878 Input:
879 879 minHei : valor minimo de altura a considerar
880 880 maxHei : valor maximo de altura a considerar
881 881
882 882 Affected:
883 883 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
884 884
885 885 Return:
886 886 1 si el metodo se ejecuto con exito caso contrario devuelve 0
887 887 """
888 888 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
889 889 raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
890 890
891 891 if (maxHei > self.dataOut.heightList[-1]):
892 892 maxHei = self.dataOut.heightList[-1]
893 893 # raise ValueError, "some value in (%d,%d) is not valid" % (minHei, maxHei)
894 894
895 895 minIndex = 0
896 896 maxIndex = 0
897 897 heights = self.dataOut.heightList
898 898
899 899 inda = numpy.where(heights >= minHei)
900 900 indb = numpy.where(heights <= maxHei)
901 901
902 902 try:
903 903 minIndex = inda[0][0]
904 904 except:
905 905 minIndex = 0
906 906
907 907 try:
908 908 maxIndex = indb[0][-1]
909 909 except:
910 910 maxIndex = len(heights)
911 911
912 912 self.selectHeightsByIndex(minIndex, maxIndex)
913 913
914 914 return 1
915 915
916 916
917 917 def selectHeightsByIndex(self, minIndex, maxIndex):
918 918 """
919 919 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
920 920 minIndex <= index <= maxIndex
921 921
922 922 Input:
923 923 minIndex : valor de indice minimo de altura a considerar
924 924 maxIndex : valor de indice maximo de altura a considerar
925 925
926 926 Affected:
927 927 self.dataOut.data_spc
928 928 self.dataOut.data_cspc
929 929 self.dataOut.data_dc
930 930 self.dataOut.heightList
931 931
932 932 Return:
933 933 1 si el metodo se ejecuto con exito caso contrario devuelve 0
934 934 """
935 935
936 936 if (minIndex < 0) or (minIndex > maxIndex):
937 937 raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
938 938
939 939 if (maxIndex >= self.dataOut.nHeights):
940 940 maxIndex = self.dataOut.nHeights-1
941 941 # raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex)
942 942
943 943 nHeights = maxIndex - minIndex + 1
944 944
945 945 #Spectra
946 946 data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1]
947 947
948 948 data_cspc = None
949 949 if self.dataOut.data_cspc != None:
950 950 data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1]
951 951
952 952 data_dc = None
953 953 if self.dataOut.data_dc != None:
954 954 data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1]
955 955
956 956 self.dataOut.data_spc = data_spc
957 957 self.dataOut.data_cspc = data_cspc
958 958 self.dataOut.data_dc = data_dc
959 959
960 960 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1]
961 961
962 962 return 1
963 963
964 964 def removeDC(self, mode = 1):
965 965
966 966 dc_index = 0
967 967 freq_index = numpy.array([-2,-1,1,2])
968 968 data_spc = self.dataOut.data_spc
969 969 data_cspc = self.dataOut.data_cspc
970 970 data_dc = self.dataOut.data_dc
971 971
972 972 if self.dataOut.flagShiftFFT:
973 973 dc_index += self.dataOut.nFFTPoints/2
974 974 freq_index += self.dataOut.nFFTPoints/2
975 975
976 976 if mode == 1:
977 977 data_spc[dc_index] = (data_spc[:,freq_index[1],:] + data_spc[:,freq_index[2],:])/2
978 978 if data_cspc != None:
979 979 data_cspc[dc_index] = (data_cspc[:,freq_index[1],:] + data_cspc[:,freq_index[2],:])/2
980 980 return 1
981 981
982 982 if mode == 2:
983 983 pass
984 984
985 985 if mode == 3:
986 986 pass
987 987
988 988 raise ValueError, "mode parameter has to be 1, 2 or 3"
989 989
990 990 def removeInterference(self):
991 991
992 992 pass
993 993
994 994 def setRadarFrequency(self, frequency=None):
995 995 if frequency != None:
996 996 self.dataOut.frequency = frequency
997 997
998 998 return 1
999 999
1000 1000
1001 1001 class IncohInt(Operation):
1002 1002
1003 1003
1004 1004 __profIndex = 0
1005 1005 __withOverapping = False
1006 1006
1007 1007 __byTime = False
1008 1008 __initime = None
1009 1009 __lastdatatime = None
1010 1010 __integrationtime = None
1011 1011
1012 1012 __buffer_spc = None
1013 1013 __buffer_cspc = None
1014 1014 __buffer_dc = None
1015 1015
1016 1016 __dataReady = False
1017 1017
1018 1018 __timeInterval = None
1019 1019
1020 1020 n = None
1021 1021
1022 1022
1023 1023
1024 1024 def __init__(self):
1025 1025
1026 1026 self.__isConfig = False
1027 1027
1028 1028 def setup(self, n=None, timeInterval=None, overlapping=False):
1029 1029 """
1030 1030 Set the parameters of the integration class.
1031 1031
1032 1032 Inputs:
1033 1033
1034 1034 n : Number of coherent integrations
1035 1035 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1036 1036 overlapping :
1037 1037
1038 1038 """
1039 1039
1040 1040 self.__initime = None
1041 1041 self.__lastdatatime = 0
1042 1042 self.__buffer_spc = None
1043 1043 self.__buffer_cspc = None
1044 1044 self.__buffer_dc = None
1045 1045 self.__dataReady = False
1046 1046
1047 1047
1048 1048 if n == None and timeInterval == None:
1049 1049 raise ValueError, "n or timeInterval should be specified ..."
1050 1050
1051 1051 if n != None:
1052 1052 self.n = n
1053 1053 self.__byTime = False
1054 1054 else:
1055 1055 self.__integrationtime = timeInterval * 60. #if (type(timeInterval)!=integer) -> change this line
1056 1056 self.n = 9999
1057 1057 self.__byTime = True
1058 1058
1059 1059 if overlapping:
1060 1060 self.__withOverapping = True
1061 1061 else:
1062 1062 self.__withOverapping = False
1063 1063 self.__buffer_spc = 0
1064 1064 self.__buffer_cspc = 0
1065 1065 self.__buffer_dc = 0
1066 1066
1067 1067 self.__profIndex = 0
1068 1068
1069 1069 def putData(self, data_spc, data_cspc, data_dc):
1070 1070
1071 1071 """
1072 1072 Add a profile to the __buffer_spc and increase in one the __profileIndex
1073 1073
1074 1074 """
1075 1075
1076 1076 if not self.__withOverapping:
1077 1077 self.__buffer_spc += data_spc
1078 1078
1079 1079 if data_cspc == None:
1080 1080 self.__buffer_cspc = None
1081 1081 else:
1082 1082 self.__buffer_cspc += data_cspc
1083 1083
1084 1084 if data_dc == None:
1085 1085 self.__buffer_dc = None
1086 1086 else:
1087 1087 self.__buffer_dc += data_dc
1088 1088
1089 1089 self.__profIndex += 1
1090 1090 return
1091 1091
1092 1092 #Overlapping data
1093 1093 nChannels, nFFTPoints, nHeis = data_spc.shape
1094 1094 data_spc = numpy.reshape(data_spc, (1, nChannels, nFFTPoints, nHeis))
1095 1095 if data_cspc != None:
1096 1096 data_cspc = numpy.reshape(data_cspc, (1, -1, nFFTPoints, nHeis))
1097 1097 if data_dc != None:
1098 1098 data_dc = numpy.reshape(data_dc, (1, -1, nHeis))
1099 1099
1100 1100 #If the buffer is empty then it takes the data value
1101 1101 if self.__buffer_spc == None:
1102 1102 self.__buffer_spc = data_spc
1103 1103
1104 1104 if data_cspc == None:
1105 1105 self.__buffer_cspc = None
1106 1106 else:
1107 1107 self.__buffer_cspc += data_cspc
1108 1108
1109 1109 if data_dc == None:
1110 1110 self.__buffer_dc = None
1111 1111 else:
1112 1112 self.__buffer_dc += data_dc
1113 1113
1114 1114 self.__profIndex += 1
1115 1115 return
1116 1116
1117 1117 #If the buffer length is lower than n then stakcing the data value
1118 1118 if self.__profIndex < self.n:
1119 1119 self.__buffer_spc = numpy.vstack((self.__buffer_spc, data_spc))
1120 1120
1121 1121 if data_cspc != None:
1122 1122 self.__buffer_cspc = numpy.vstack((self.__buffer_cspc, data_cspc))
1123 1123
1124 1124 if data_dc != None:
1125 1125 self.__buffer_dc = numpy.vstack((self.__buffer_dc, data_dc))
1126 1126
1127 1127 self.__profIndex += 1
1128 1128 return
1129 1129
1130 1130 #If the buffer length is equal to n then replacing the last buffer value with the data value
1131 1131 self.__buffer_spc = numpy.roll(self.__buffer_spc, -1, axis=0)
1132 1132 self.__buffer_spc[self.n-1] = data_spc
1133 1133
1134 1134 if data_cspc != None:
1135 1135 self.__buffer_cspc = numpy.roll(self.__buffer_cspc, -1, axis=0)
1136 1136 self.__buffer_cspc[self.n-1] = data_cspc
1137 1137
1138 1138 if data_dc != None:
1139 1139 self.__buffer_dc = numpy.roll(self.__buffer_dc, -1, axis=0)
1140 1140 self.__buffer_dc[self.n-1] = data_dc
1141 1141
1142 1142 self.__profIndex = self.n
1143 1143 return
1144 1144
1145 1145
1146 1146 def pushData(self):
1147 1147 """
1148 1148 Return the sum of the last profiles and the profiles used in the sum.
1149 1149
1150 1150 Affected:
1151 1151
1152 1152 self.__profileIndex
1153 1153
1154 1154 """
1155 1155 data_spc = None
1156 1156 data_cspc = None
1157 1157 data_dc = None
1158 1158
1159 1159 if not self.__withOverapping:
1160 1160 data_spc = self.__buffer_spc
1161 1161 data_cspc = self.__buffer_cspc
1162 1162 data_dc = self.__buffer_dc
1163 1163
1164 1164 n = self.__profIndex
1165 1165
1166 1166 self.__buffer_spc = 0
1167 1167 self.__buffer_cspc = 0
1168 1168 self.__buffer_dc = 0
1169 1169 self.__profIndex = 0
1170 1170
1171 1171 return data_spc, data_cspc, data_dc, n
1172 1172
1173 1173 #Integration with Overlapping
1174 1174 data_spc = numpy.sum(self.__buffer_spc, axis=0)
1175 1175
1176 1176 if self.__buffer_cspc != None:
1177 1177 data_cspc = numpy.sum(self.__buffer_cspc, axis=0)
1178 1178
1179 1179 if self.__buffer_dc != None:
1180 1180 data_dc = numpy.sum(self.__buffer_dc, axis=0)
1181 1181
1182 1182 n = self.__profIndex
1183 1183
1184 1184 return data_spc, data_cspc, data_dc, n
1185 1185
1186 1186 def byProfiles(self, *args):
1187 1187
1188 1188 self.__dataReady = False
1189 1189 avgdata_spc = None
1190 1190 avgdata_cspc = None
1191 1191 avgdata_dc = None
1192 1192 n = None
1193 1193
1194 1194 self.putData(*args)
1195 1195
1196 1196 if self.__profIndex == self.n:
1197 1197
1198 1198 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1199 1199 self.__dataReady = True
1200 1200
1201 1201 return avgdata_spc, avgdata_cspc, avgdata_dc
1202 1202
1203 1203 def byTime(self, datatime, *args):
1204 1204
1205 1205 self.__dataReady = False
1206 1206 avgdata_spc = None
1207 1207 avgdata_cspc = None
1208 1208 avgdata_dc = None
1209 1209 n = None
1210 1210
1211 1211 self.putData(*args)
1212 1212
1213 1213 if (datatime - self.__initime) >= self.__integrationtime:
1214 1214 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1215 1215 self.n = n
1216 1216 self.__dataReady = True
1217 1217
1218 1218 return avgdata_spc, avgdata_cspc, avgdata_dc
1219 1219
1220 1220 def integrate(self, datatime, *args):
1221 1221
1222 1222 if self.__initime == None:
1223 1223 self.__initime = datatime
1224 1224
1225 1225 if self.__byTime:
1226 1226 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(datatime, *args)
1227 1227 else:
1228 1228 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1229 1229
1230 1230 self.__lastdatatime = datatime
1231 1231
1232 1232 if avgdata_spc == None:
1233 1233 return None, None, None, None
1234 1234
1235 1235 avgdatatime = self.__initime
1236 1236 try:
1237 1237 self.__timeInterval = (self.__lastdatatime - self.__initime)/(self.n - 1)
1238 1238 except:
1239 1239 self.__timeInterval = self.__lastdatatime - self.__initime
1240 1240
1241 1241 deltatime = datatime -self.__lastdatatime
1242 1242
1243 1243 if not self.__withOverapping:
1244 1244 self.__initime = datatime
1245 1245 else:
1246 1246 self.__initime += deltatime
1247 1247
1248 1248 return avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc
1249 1249
1250 1250 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1251 1251
1252 1252 if n==1:
1253 1253 dataOut.flagNoData = False
1254 1254 return
1255 1255
1256 1256 if not self.__isConfig:
1257 1257 self.setup(n, timeInterval, overlapping)
1258 1258 self.__isConfig = True
1259 1259
1260 1260 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1261 1261 dataOut.data_spc,
1262 1262 dataOut.data_cspc,
1263 1263 dataOut.data_dc)
1264 1264
1265 1265 # dataOut.timeInterval *= n
1266 1266 dataOut.flagNoData = True
1267 1267
1268 1268 if self.__dataReady:
1269 1269
1270 1270 dataOut.data_spc = avgdata_spc
1271 1271 dataOut.data_cspc = avgdata_cspc
1272 1272 dataOut.data_dc = avgdata_dc
1273 1273
1274 1274 dataOut.nIncohInt *= self.n
1275 1275 dataOut.utctime = avgdatatime
1276 1276 #dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt * dataOut.nIncohInt * dataOut.nFFTPoints
1277 1277 dataOut.timeInterval = self.__timeInterval*self.n
1278 1278 dataOut.flagNoData = False
1279 1279
1280 1280 class ProfileSelector(Operation):
1281 1281
1282 1282 profileIndex = None
1283 1283 # Tamanho total de los perfiles
1284 1284 nProfiles = None
1285 1285
1286 1286 def __init__(self):
1287 1287
1288 1288 self.profileIndex = 0
1289 1289
1290 1290 def incIndex(self):
1291 1291 self.profileIndex += 1
1292 1292
1293 1293 if self.profileIndex >= self.nProfiles:
1294 1294 self.profileIndex = 0
1295 1295
1296 1296 def isProfileInRange(self, minIndex, maxIndex):
1297 1297
1298 1298 if self.profileIndex < minIndex:
1299 1299 return False
1300 1300
1301 1301 if self.profileIndex > maxIndex:
1302 1302 return False
1303 1303
1304 1304 return True
1305 1305
1306 1306 def isProfileInList(self, profileList):
1307 1307
1308 1308 if self.profileIndex not in profileList:
1309 1309 return False
1310 1310
1311 1311 return True
1312 1312
1313 1313 def run(self, dataOut, profileList=None, profileRangeList=None):
1314 1314
1315 1315 dataOut.flagNoData = True
1316 1316 self.nProfiles = dataOut.nProfiles
1317 1317
1318 1318 if profileList != None:
1319 1319 if self.isProfileInList(profileList):
1320 1320 dataOut.flagNoData = False
1321 1321
1322 1322 self.incIndex()
1323 1323 return 1
1324 1324
1325 1325
1326 1326 elif profileRangeList != None:
1327 1327 minIndex = profileRangeList[0]
1328 1328 maxIndex = profileRangeList[1]
1329 1329 if self.isProfileInRange(minIndex, maxIndex):
1330 1330 dataOut.flagNoData = False
1331 1331
1332 1332 self.incIndex()
1333 1333 return 1
1334 1334
1335 1335 else:
1336 1336 raise ValueError, "ProfileSelector needs profileList or profileRangeList"
1337 1337
1338 1338 return 0
1339 1339
1340 1340 class SpectraHeisProc(ProcessingUnit):
1341 1341 def __init__(self):
1342 1342 self.objectDict = {}
1343 1343 # self.buffer = None
1344 1344 # self.firstdatatime = None
1345 1345 # self.profIndex = 0
1346 1346 self.dataOut = SpectraHeis()
1347 1347
1348 1348 def __updateObjFromInput(self):
1349 1349 self.dataOut.timeZone = self.dataIn.timeZone
1350 1350 self.dataOut.dstFlag = self.dataIn.dstFlag
1351 1351 self.dataOut.errorCount = self.dataIn.errorCount
1352 1352 self.dataOut.useLocalTime = self.dataIn.useLocalTime
1353 1353
1354 1354 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()#
1355 1355 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()#
1356 1356 self.dataOut.channelList = self.dataIn.channelList
1357 1357 self.dataOut.heightList = self.dataIn.heightList
1358 1358 # self.dataOut.dtype = self.dataIn.dtype
1359 1359 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
1360 1360 # self.dataOut.nHeights = self.dataIn.nHeights
1361 1361 # self.dataOut.nChannels = self.dataIn.nChannels
1362 1362 self.dataOut.nBaud = self.dataIn.nBaud
1363 1363 self.dataOut.nCode = self.dataIn.nCode
1364 1364 self.dataOut.code = self.dataIn.code
1365 1365 # self.dataOut.nProfiles = 1
1366 1366 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
1367 1367 self.dataOut.nFFTPoints = self.dataIn.nHeights
1368 1368 # self.dataOut.channelIndexList = self.dataIn.channelIndexList
1369 1369 # self.dataOut.flagNoData = self.dataIn.flagNoData
1370 1370 self.dataOut.flagTimeBlock = self.dataIn.flagTimeBlock
1371 1371 self.dataOut.utctime = self.dataIn.utctime
1372 1372 # self.dataOut.utctime = self.firstdatatime
1373 1373 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
1374 1374 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
1375 1375 # self.dataOut.flagShiftFFT = self.dataIn.flagShiftFFT
1376 1376 self.dataOut.nCohInt = self.dataIn.nCohInt
1377 1377 self.dataOut.nIncohInt = 1
1378 1378 self.dataOut.ippSeconds= self.dataIn.ippSeconds
1379 1379 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
1380 1380
1381 1381 self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nIncohInt
1382 1382 # self.dataOut.set=self.dataIn.set
1383 1383 # self.dataOut.deltaHeight=self.dataIn.deltaHeight
1384 1384
1385 1385
1386 1386 def __getFft(self):
1387 1387
1388 1388 fft_volt = numpy.fft.fft(self.dataIn.data, axis=1)
1389 1389 fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,))
1390 1390 spc = numpy.abs(fft_volt * numpy.conjugate(fft_volt))/(self.dataOut.nFFTPoints)
1391 1391 self.dataOut.data_spc = spc
1392 1392
1393 1393 def init(self):
1394 1394
1395 1395 self.dataOut.flagNoData = True
1396 1396
1397 1397 if self.dataIn.type == "SpectraHeis":
1398 1398 self.dataOut.copy(self.dataIn)
1399 1399 return
1400 1400
1401 1401 if self.dataIn.type == "Voltage":
1402 1402 self.__updateObjFromInput()
1403 1403 self.__getFft()
1404 1404 self.dataOut.flagNoData = False
1405 1405
1406 1406 return
1407 1407
1408 1408 raise ValuError, "The type object %s is not valid"%(self.dataIn.type)
1409 1409
1410 1410
1411 1411 def selectChannels(self, channelList):
1412 1412
1413 1413 channelIndexList = []
1414 1414
1415 1415 for channel in channelList:
1416 1416 index = self.dataOut.channelList.index(channel)
1417 1417 channelIndexList.append(index)
1418 1418
1419 1419 self.selectChannelsByIndex(channelIndexList)
1420 1420
1421 1421 def selectChannelsByIndex(self, channelIndexList):
1422 1422 """
1423 1423 Selecciona un bloque de datos en base a canales segun el channelIndexList
1424 1424
1425 1425 Input:
1426 1426 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
1427 1427
1428 1428 Affected:
1429 1429 self.dataOut.data
1430 1430 self.dataOut.channelIndexList
1431 1431 self.dataOut.nChannels
1432 1432 self.dataOut.m_ProcessingHeader.totalSpectra
1433 1433 self.dataOut.systemHeaderObj.numChannels
1434 1434 self.dataOut.m_ProcessingHeader.blockSize
1435 1435
1436 1436 Return:
1437 1437 None
1438 1438 """
1439 1439
1440 1440 for channelIndex in channelIndexList:
1441 1441 if channelIndex not in self.dataOut.channelIndexList:
1442 1442 print channelIndexList
1443 1443 raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex
1444 1444
1445 1445 nChannels = len(channelIndexList)
1446 1446
1447 1447 data_spc = self.dataOut.data_spc[channelIndexList,:]
1448 1448
1449 1449 self.dataOut.data_spc = data_spc
1450 1450 self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
1451 1451
1452 1452 return 1
1453 1453
1454 1454 class IncohInt4SpectraHeis(Operation):
1455 1455
1456 1456 __isConfig = False
1457 1457
1458 1458 __profIndex = 0
1459 1459 __withOverapping = False
1460 1460
1461 1461 __byTime = False
1462 1462 __initime = None
1463 1463 __lastdatatime = None
1464 1464 __integrationtime = None
1465 1465
1466 1466 __buffer = None
1467 1467
1468 1468 __dataReady = False
1469 1469
1470 1470 n = None
1471 1471
1472 1472
1473 1473 def __init__(self):
1474 1474
1475 1475 self.__isConfig = False
1476 1476
1477 1477 def setup(self, n=None, timeInterval=None, overlapping=False):
1478 1478 """
1479 1479 Set the parameters of the integration class.
1480 1480
1481 1481 Inputs:
1482 1482
1483 1483 n : Number of coherent integrations
1484 1484 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1485 1485 overlapping :
1486 1486
1487 1487 """
1488 1488
1489 1489 self.__initime = None
1490 1490 self.__lastdatatime = 0
1491 1491 self.__buffer = None
1492 1492 self.__dataReady = False
1493 1493
1494 1494
1495 1495 if n == None and timeInterval == None:
1496 1496 raise ValueError, "n or timeInterval should be specified ..."
1497 1497
1498 1498 if n != None:
1499 1499 self.n = n
1500 1500 self.__byTime = False
1501 1501 else:
1502 1502 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
1503 1503 self.n = 9999
1504 1504 self.__byTime = True
1505 1505
1506 1506 if overlapping:
1507 1507 self.__withOverapping = True
1508 1508 self.__buffer = None
1509 1509 else:
1510 1510 self.__withOverapping = False
1511 1511 self.__buffer = 0
1512 1512
1513 1513 self.__profIndex = 0
1514 1514
1515 1515 def putData(self, data):
1516 1516
1517 1517 """
1518 1518 Add a profile to the __buffer and increase in one the __profileIndex
1519 1519
1520 1520 """
1521 1521
1522 1522 if not self.__withOverapping:
1523 1523 self.__buffer += data.copy()
1524 1524 self.__profIndex += 1
1525 1525 return
1526 1526
1527 1527 #Overlapping data
1528 1528 nChannels, nHeis = data.shape
1529 1529 data = numpy.reshape(data, (1, nChannels, nHeis))
1530 1530
1531 1531 #If the buffer is empty then it takes the data value
1532 1532 if self.__buffer == None:
1533 1533 self.__buffer = data
1534 1534 self.__profIndex += 1
1535 1535 return
1536 1536
1537 1537 #If the buffer length is lower than n then stakcing the data value
1538 1538 if self.__profIndex < self.n:
1539 1539 self.__buffer = numpy.vstack((self.__buffer, data))
1540 1540 self.__profIndex += 1
1541 1541 return
1542 1542
1543 1543 #If the buffer length is equal to n then replacing the last buffer value with the data value
1544 1544 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
1545 1545 self.__buffer[self.n-1] = data
1546 1546 self.__profIndex = self.n
1547 1547 return
1548 1548
1549 1549
1550 1550 def pushData(self):
1551 1551 """
1552 1552 Return the sum of the last profiles and the profiles used in the sum.
1553 1553
1554 1554 Affected:
1555 1555
1556 1556 self.__profileIndex
1557 1557
1558 1558 """
1559 1559
1560 1560 if not self.__withOverapping:
1561 1561 data = self.__buffer
1562 1562 n = self.__profIndex
1563 1563
1564 1564 self.__buffer = 0
1565 1565 self.__profIndex = 0
1566 1566
1567 1567 return data, n
1568 1568
1569 1569 #Integration with Overlapping
1570 1570 data = numpy.sum(self.__buffer, axis=0)
1571 1571 n = self.__profIndex
1572 1572
1573 1573 return data, n
1574 1574
1575 1575 def byProfiles(self, data):
1576 1576
1577 1577 self.__dataReady = False
1578 1578 avgdata = None
1579 1579 n = None
1580 1580
1581 1581 self.putData(data)
1582 1582
1583 1583 if self.__profIndex == self.n:
1584 1584
1585 1585 avgdata, n = self.pushData()
1586 1586 self.__dataReady = True
1587 1587
1588 1588 return avgdata
1589 1589
1590 1590 def byTime(self, data, datatime):
1591 1591
1592 1592 self.__dataReady = False
1593 1593 avgdata = None
1594 1594 n = None
1595 1595
1596 1596 self.putData(data)
1597 1597
1598 1598 if (datatime - self.__initime) >= self.__integrationtime:
1599 1599 avgdata, n = self.pushData()
1600 1600 self.n = n
1601 1601 self.__dataReady = True
1602 1602
1603 1603 return avgdata
1604 1604
1605 1605 def integrate(self, data, datatime=None):
1606 1606
1607 1607 if self.__initime == None:
1608 1608 self.__initime = datatime
1609 1609
1610 1610 if self.__byTime:
1611 1611 avgdata = self.byTime(data, datatime)
1612 1612 else:
1613 1613 avgdata = self.byProfiles(data)
1614 1614
1615 1615
1616 1616 self.__lastdatatime = datatime
1617 1617
1618 1618 if avgdata == None:
1619 1619 return None, None
1620 1620
1621 1621 avgdatatime = self.__initime
1622 1622
1623 1623 deltatime = datatime -self.__lastdatatime
1624 1624
1625 1625 if not self.__withOverapping:
1626 1626 self.__initime = datatime
1627 1627 else:
1628 1628 self.__initime += deltatime
1629 1629
1630 1630 return avgdata, avgdatatime
1631 1631
1632 1632 def run(self, dataOut, **kwargs):
1633 1633
1634 1634 if not self.__isConfig:
1635 1635 self.setup(**kwargs)
1636 1636 self.__isConfig = True
1637 1637
1638 1638 avgdata, avgdatatime = self.integrate(dataOut.data_spc, dataOut.utctime)
1639 1639
1640 1640 # dataOut.timeInterval *= n
1641 1641 dataOut.flagNoData = True
1642 1642
1643 1643 if self.__dataReady:
1644 1644 dataOut.data_spc = avgdata
1645 1645 dataOut.nIncohInt *= self.n
1646 1646 # dataOut.nCohInt *= self.n
1647 1647 dataOut.utctime = avgdatatime
1648 1648 dataOut.timeInterval = dataOut.ippSeconds * dataOut.nIncohInt
1649 1649 # dataOut.timeInterval = self.__timeInterval*self.n
1650 1650 dataOut.flagNoData = False
1651 1651
1652 1652
1653 1653
1654 1654
1655 1655 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now