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