##// END OF EJS Templates
22/08/2017
ebocanegra -
r1006:8363978b5396
parent child
Show More
@@ -1,109 +1,106
1 <<<<<<< HEAD
2 1 # Byte-compiled / optimized / DLL files
3 2 __pycache__/
4 3 *.py[cod]
5 4 *$py.class
6 5
7 6 # C extensions
8 7 *.so
9 8
10 9 # Distribution / packaging
11 10 .Python
12 11 env/
13 12 build/
14 13 develop-eggs/
15 14 dist/
16 15 downloads/
17 16 eggs/
18 17 .eggs/
19 18 lib/
20 19 lib64/
21 20 parts/
22 21 sdist/
23 22 var/
24 23 wheels/
25 24 *.egg-info/
26 25 .installed.cfg
27 26 *.egg
28 27
29 28 # PyInstaller
30 29 # Usually these files are written by a python script from a template
31 30 # before PyInstaller builds the exe, so as to inject date/other infos into it.
32 31 *.manifest
33 32 *.spec
34 33
35 34 # Installer logs
36 35 pip-log.txt
37 36 pip-delete-this-directory.txt
38 37
39 38 # Unit test / coverage reports
40 39 htmlcov/
41 40 .tox/
42 41 .coverage
43 42 .coverage.*
44 43 .cache
45 44 nosetests.xml
46 45 coverage.xml
47 46 *,cover
48 47 .hypothesis/
49 48
50 49 # Translations
51 50 *.mo
52 51 *.pot
53 52
54 53 # Django stuff:
55 54 *.log
56 55 local_settings.py
57 56
58 57 # Flask stuff:
59 58 instance/
60 59 .webassets-cache
61 60
62 61 # Scrapy stuff:
63 62 .scrapy
64 63
65 64 # Sphinx documentation
66 65 docs/_build/
67 66
68 67 # PyBuilder
69 68 target/
70 69
71 70 # Jupyter Notebook
72 71 .ipynb_checkpoints
73 72
74 73 # pyenv
75 74 .python-version
76 75
77 76 # celery beat schedule file
78 77 celerybeat-schedule
79 78
80 79 # SageMath parsed files
81 80 *.sage.py
82 81
83 82 # dotenv
84 83 .env
85 84
86 85 # virtualenv
87 86 .venv
88 87 venv/
89 88 ENV/
90 89
91 90 # Spyder project settings
92 91 .spyderproject
93 92 .spyproject
94 93
95 94 # Rope project settings
96 95 .ropeproject
97 96
98 97 # mkdocs documentation
99 98 /site
100 99
101 100 # eclipse
102 101 .project
103 102 .pydevproject
104 =======
105 build/
106 dist/
107 schainpy.egg-info/
108 103 .svn/
109 >>>>>>> 08c4507d6c3c48f6c52326d5dedfa1972fb26356
104 *.png
105 *.pyc
106 schainpy/scripts
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
@@ -1,19 +1,19
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 from jroIO_voltage import *
8 8 from jroIO_spectra import *
9 9 from jroIO_heispectra import *
10 10 from jroIO_usrp import *
11 11
12 12 from jroIO_kamisr import *
13 13 from jroIO_param import *
14 14 from jroIO_hf import *
15 15
16 16 from jroIO_bltr import *
17 17 from jroIO_mira35c import *
18 #from io_bltr_block import *
18 from io_bltr_block import *
19 19
1 NO CONTENT: modified file, binary diff hidden
@@ -1,948 +1,950
1 1 '''
2 2 Created on Nov 9, 2016
3 3
4 4 @author: roj- LouVD
5 5 '''
6 6
7 7 import numpy
8 8 import os.path
9 9 import sys
10 10 import time
11 11 import datetime
12 12 from sys import path
13 13 from os.path import dirname
14 14 from mimify import HeaderFile
15 15 from numpy import size, asarray
16 16 from datetime import datetime
17 17 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation
18 18 from schainpy.model.data.jrodata import Parameters
19 19 from schainpy.model.data.jroheaderIO import RadarControllerHeader, SystemHeader
20 20 from schainpy.model.graphics.jroplot_parameters import WindProfilerPlot
21 21 from schainpy.model.io.jroIO_base import *
22 22
23 23 import schainpy
24 24 #import madrigal
25 25 #import madrigal.cedar
26 26 #from madrigal.cedar import MadrigalCatalogRecord
27 27
28 28 import warnings
29 29 from time import gmtime
30 30 from math import floor
31
31 32 warnings.simplefilter("error")
32 33 from numpy.lib.nanfunctions import nansum
33 34 warnings.simplefilter('ignore', FutureWarning)
34 35
35 36
36 37 class testBLTRReader(ProcessingUnit):
37 38
38 39
39 def __init__(self):
40 def __init__(self, **kwargs):
40 41
41 42 path = None
42 43 startDate = None
43 44 endDate = None
44 45 startTime = None
45 46 endTime = None
46 47 startTime = None
47 48 endTime = None
48 49
49 50 isConfig = False
50 51 dataOut = None
51 52 walk = None
52 53 ext = 'swwma'
53 54 fileList = []
54 55 fileIndex = -1
55 56 timezone = None
56 57 filename = None
57 58
58 59 timearray = None
59 60 height = None
60 61 snr_ref = None
61 62 zon_ref = None
62 63 ver_ref = None
63 64 mer_ref = None
64 65 nmodes = None
65 66 nchannels = None
66 67 nranges = None
67 68 year = None
68 69 month = None
69 70 day = None
70 71 lat = None
71 72 lon = None
72 73 siteFile = None
73 74
74 ProcessingUnit.__init__(self)
75 ProcessingUnit.__init__(self , **kwargs)
75 76 self.dataOut = self.createObjByDefault()
76 77 self.imode = 0
77 78 self.counter_records = 0
78 79
79 80 self.isConfig = False
80 81 self.flagNoMoreFiles = 0
81 82
82 83 self.buffer = None
83 84
84 85
85 86 def createObjByDefault(self):
86 87
87 88 dataObj = Parameters()
88 89
89 90 return dataObj
90 91
91 92 def info(self):
92 93 '''
93 94 Experience information
94 95
95 96 '''
96 97 self.hoy = datetime.datetime.now()
97 98 place = 'Jicamarca Radio Observatory'
98 99 signalchainweb='http://jro-dev.igp.gob.pe:3000/projects/signal-chain/wiki/Manual_de_Desarrollador'
99 100 print '{} at {}'.format(self.hoy,place)
100 101 print 'Boundary Layer and Tropospheric Radar (BLTR) script, Wind velocities and SNR from *.sswma files'
101 102 print '{} \n'.format(signalchainweb)
102 103
103 def run(self, path, startDate, endDate, ext, startTime, endTime):
104 def run(self, path, startDate, endDate, ext, startTime, endTime, queue=None):
104 105
105 106 if not(self.isConfig):
106 107 self.setup(path, startDate, endDate, ext)
107 108 self.isConfig = True
108 109
109 110 self.getData()
110 111
111 112 def setup(self,
112 113 path=None,
113 114 startDate=None,
114 115 endDate=None,
115 116 ext=None,
116 117 startTime=datetime.time(0, 0, 0),
117 118 endTime=datetime.time(23, 59, 59),
118 119 timezone=0):
119 120
120 121 self.info()
121 122 self.path = path
122 123 if self.path == None:
123 124 raise ValueError, "The path is not valid"
124 125
125 126 if ext == None:
126 127 ext = self.ext
127 128
128 129 self.searchFiles(self.path, startDate, endDate, ext)
129 130
130 131 self.timezone = timezone
131 132 self.ext = ext
132 133 self.fileIndex = -1
133 134
134 135 if not(self.fileList):
135 136 raise Warning, "There is no files matching these date in the folder: %s. \n Check 'startDate' and 'endDate' "%(path)
136 137
137 138
138 139 if not(self.setNextFile()):
139 140
140 141 print 'not next file'
141 142 if (startDate!=None) and (endDate!=None):
142 143 print "No files in range: %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime())
143 144 elif startDate != None:
144 145 print "No files in range: %s" %(datetime.datetime.combine(startDate,startTime).ctime())
145 146 else:
146 147 print "No files"
147 148
148 149 sys.exit(-1)
149 150
150 151 def searchFiles(self, path, startDate, endDate, ext=None):
151 152 '''
152 153 Searching for BLTR rawdata file in path
153 154 Creating a list of file to proces included in [startDate,endDate]
154 155
155 156 Input:
156 157 path - Path to find BLTR rawdata files
157 158 startDate - Select file from this date
158 159 enDate - Select file until this date
159 160 ext - Extension of the file to read
160 161
161 162 '''
162 163
163 164 fullpath = path
164 165 foldercounter = 0
165 166
166 167 print 'Searching file in %s ' % (fullpath)
167 168 fileList0 = glob.glob1(fullpath, "*%s" % ext)
168 169 fileList0.sort()
169 170
170 171 self.fileList = []
171 172 self.dateFileList = []
172 173
173 174 for thisFile in fileList0:
174 175 year = thisFile[-14:-10]
175 176 if not isNumber(year):
176 177 continue
177 178
178 179 month = thisFile[-10:-8]
179 180 if not isNumber(month):
180 181 continue
181 182
182 183 day = thisFile[-8:-6]
183 184 if not isNumber(day):
184 185 continue
185 186
186 187 year, month, day = int(year), int(month), int(day)
187 188 dateFile = datetime.date(year, month, day)
188 189
189 190 if not ((startDate <= dateFile) and (endDate > dateFile)):
190 191 continue
191 192
192 193 self.fileList.append(thisFile)
193 194 self.dateFileList.append(dateFile)
194 195
195 196 return 1
196 197
197 198
198 199 def setNextFile(self):
199 200
200 201 idFile = self.fileIndex
201 202
202 203 while (True):
203 204 idFile += 1
204 205 if idFile >= len(self.fileList):
205 206 print '\nNo more files in the folder'
206 207 print 'Total number of file(s) read : {}'.format(self.fileIndex + 1)
207 208 print 'Time of processing : {}'.format(datetime.datetime.now()- self.hoy)
208 209 self.flagNoMoreFiles = 1
209 210 return 0
210 211 if self.isConfig: print '------------------------[Next File]---------------------------'
211 212 filename = os.path.join(self.path, self.fileList[idFile])
212 213 self.Open(filename)
213 214
214 215 print '\n[Setting file] (%s) ...' % self.fileList[idFile]
215 216
216 217 break
217 218
218 219 self.flagIsNewFile =0
219 220
220 221 self.fileIndex = idFile
221 222 self.filename = filename
222 223 print 'File:',self.filename
223 224
224 225 return 1
225 226
226 227 def readDataBlock(self):
227 228
228 229
229 230 self.readHeader()
230 231 self.dataRecords(0)
231 232
232 233 print '[New Record] record: {} /{} // file {}/{}'.format(self.counter_records,self.nrecords,self.fileIndex+1,len(self.fileList))
233 234
234 235 self.setDataBuffer()
235 236
236 237 self.flagIsNewBlock = 1
237 238
238 239 if self.counter_records > self.nrecords:
239 240 self.flagIsNewFile = 1
240 241 return 0
241 242
242 243 return 1
243 244
244 245 def setDataBuffer(self):
245 246
246 247 '''
247 248 Storing data from one block
248 249
249 250 '''
250 251 self.t = datetime.datetime(self.year, self.month, self.day)
251 252 self.doy = time.localtime(time.mktime(self.t.timetuple())).tm_yday
252 253 self.buffer = numpy.squeeze(numpy.array([[self.one_snr],[self.one_zonal],[self.one_vertical],[self.one_meridional],
253 254 [self.time],[self.height],[self.fileIndex],
254 255 [self.year],[self.month],[self.day],[self.t],[self.doy]]))
255 256
256 257 self.dataOut.time1 = self.time1
257 258
258 259 def Open(self, filename):
259 260 '''
260 261 Opening BLTR rawdata file defined by filename
261 262
262 263 Inputs:
263 264
264 265 filename - Full path name of BLTR rawdata file
265 266
266 267 '''
267 268 [dir, name] = os.path.split(filename)
268 269 strFile = name.split('.')
269 270 self.siteFile = strFile[0] # 'peru2' ---> Piura - 'peru1' ---> Huancayo or Porcuya
270 271
271 272 self.filename = filename
272 273 if os.path.isfile(self.filename) == False:
273 274 print 'File do not exist. Check "filename"'
274 275 sys.exit(0)
275 276
276 277 self.h_file = numpy.dtype([
277 278 ('FMN', '<u4'),
278 279 ('nrec', '<u4'),
279 280 ('fr_offset', '<u4'),
280 281 ('id', '<u4'),
281 282 ('site', 'u1', (32,))
282 283 ])
283 284 self.pointer = open(self.filename, 'rb') # rb : Read Binary
284
285 print self.filename
285 286 self.header_file = numpy.fromfile(self.pointer, self.h_file, 1)
286
287 print self.header_file
287 288 self.nrecords = self.header_file['nrec'][0]
288 289
289 290 self.sizeOfFile = os.path.getsize(self.filename)
290 291
291 292 self.time = numpy.zeros([2, self.nrecords], dtype='u4')
292 293 self.counter_records = 0
293 294 self.count = 0
294 295 self.flag_initialArray = False
295 296
296 297 self.year = 0
297 298 self.month = 0
298 299 self.day = 0
299 300
300 301 def hasNotDataInBuffer(self):
301 302
302 303 if self.buffer == None:
303 304 return 1
304 305 return 0
305 306
306 307 def getData(self):
307 308 '''
308 309 Storing data from databuffer to dataOut object
309 310
310 311 '''
311 312 if self.flagNoMoreFiles==1:
312 313 self.dataOut.flagNoData = True
313 314 print 'No file left to process'
314 315 return 0
315 316
316 317 self.flagIsNewBlock = 0
317 318
318 319 if self.hasNotDataInBuffer():
319 320
320 321 if self.flagIsNewFile==0:
321 322
322 323 self.readNextBlock()
323 324 '''RETURN A BLOCK OF DATA'''
324 325 if self.flagNoMoreFiles==0:
325 326 self.dataOut.data_SNR = self.buffer[0]
326 327 self.dataOut.time = self.buffer[4]
327 328 self.dataOut.height = self.height
328 329
329 330 self.dataOut.height= self.height
330 331 self.dataOut.data_output = numpy.squeeze(numpy.array([[self.buffer[1]],
331 332 [self.buffer[3]],
332 333 [self.buffer[2]]]))
333 334
334 335 #
335 336
336 337 self.dataOut.day, self.dataOut.month, self.dataOut.year = self.buffer[9], self.buffer[8], self.buffer[7]
337 338
338 339 self.dataOut.utctimeInit = self.time1
339 340 self.dataOut.utctime = self.dataOut.utctimeInit
340 341 self.dataOut.counter_records = self.counter_records
341 342 self.dataOut.nrecords = self.nrecords
342 343
343 344 self.setHeader()
344 345
345 346 self.buffer = None
346 347 self.dataOut.flagNoData = False
347 348
348 349 def readNextBlock(self):
349 350
350 351 if not(self.setNewBlock()):
351 352 return 0
352 353
353 354 if not(self.readDataBlock()):
354 355 return 0
355 356
356 357 if self.flagIsNewFile:
357 358 self.setNextFile()
358 359
359 360 return 1
360 361
361 362 def setNewBlock(self):
362 363
363 364 if self.pointer==None:
364 365 return 0
365 366
366 367 if self.flagIsNewFile:
367 368 return 1
368 369
369 370 if self.counter_records < self.nrecords:
370 371 return 1
371 372
372 373 if not(self.setNextFile()):
373 374 return 0
374 375
375 376 return 1
376 377
377 378 def readHeader(self):
378 379 '''
379 380 RecordHeader of BLTR rawdata file
380 381 '''
381 382 if self.pointer.tell() == self.sizeOfFile:
382 383 print 'End of File'
383 384 return
384 385
385 386 self.h_rec1 = numpy.dtype([
386 387 ('rmn', '<u4'),
387 388 ('rcounter', '<u4'),
388 389 ('nr_offset', '<u4'),
389 390 ('tr_offset', '<u4'),
390 391 ('time', '<u4'),
391 392 ('time_msec', '<u4'),
392 393 ('tag', 'u1', (32,)),
393 394 ('comments', 'u1', (32,)),
394 395 ('lat', '<f4'),
395 396 ('lon', '<f4'),
396 397 ('gps_status', '<u4'),
397 398 ('freq', '<u4'),
398 399 ('freq0', '<u4'),
399 400 ('nchan', '<u4'),
400 401 ('delta_r', '<u4'),
401 402 ('nranges', '<u4'),
402 403 ('r0', '<u4'),
403 404 ('prf', '<u4'),
404 405 ('ncoh', '<u4'),
405 406 ('npoints', '<u4'),
406 407 ('polarization', '<i4'),
407 408 ('rx_filter', '<u4'),
408 409 ('nmodes', '<u4'),
409 410 ('dmode_index', '<u4'),
410 411 ('dmode_rngcorr', '<u4'),
411 412 ('nrxs', '<u4'),
412 413 ('acf_length', '<u4'),
413 414 ('acf_lags', '<u4'),
414 415 ('sea_to_atmos', '<f4'),
415 416 ('sea_notch', '<u4'),
416 417 ('lh_sea', '<u4'),
417 418 ('hh_sea', '<u4'),
418 419 ('nbins_sea', '<u4'),
419 420 ('min_snr', '<f4'),
420 421 ('min_cc', '<f4'),
421 422 ('max_time_diff', '<f4')
422 423 ])
423 424
424 425 self.header_rec1 = numpy.fromfile(self.pointer, self.h_rec1, 1)
425 426 self.lat = self.header_rec1['lat'][0]
426 427 self.lon = self.header_rec1['lon'][0]
427 428 self.nchannels = self.header_rec1['nchan'][0] / 2
428 429 self.kchan = self.header_rec1['nrxs'][0]
429 430 self.nranges = self.header_rec1['nranges'][0]
430 431 self.deltha = self.header_rec1['delta_r'][0]
431 432
432 433 self.correction = self.header_rec1['dmode_rngcorr'][0]
433 434 self.nmodes = self.header_rec1['nmodes'][0]
434 435 self.imode = self.header_rec1['dmode_index'][0]
435 436
436 437 self.h_rec2 = numpy.dtype([
437 438 ('antenna_coord', 'f4', (2, self.nchannels)),
438 439 ('rx_gains', 'u4', (self.nchannels,)),
439 440 ('rx_analysis', 'u4', (self.nchannels,))
440 441 ])
441 442
442 443 self.header_rec2 = numpy.fromfile(self.pointer, self.h_rec2, 1) # header rec2
443 444 self.antenna = self.header_rec2['antenna_coord']
444 445 self.rx_gains = self.header_rec2['rx_gains']
445 446
446 447 self.d_rec = numpy.dtype ([
447 448 ('range', '<u4'),
448 449 ('status', '<u4'),
449 450 ('zonal', '<f4'),
450 451 ('meridional', '<f4'),
451 452 ('vertical', '<f4'),
452 453 ('zonal_a', '<f4'),
453 454 ('meridional_a', '<f4'),
454 455 ('corrected_fading', '<f4'), # seconds
455 456 ('uncorrected_fading', '<f4'), # seconds
456 457 ('time_diff', '<f4'),
457 458 ('major_axis', '<f4'),
458 459 ('axial_ratio', '<f4'),
459 460 ('orientation', '<f4'),
460 461 ('sea_power', '<u4'),
461 462 ('sea_algorithm', '<u4'),
462 463 ('rx_saturation', 'u4', (self.nchannels,)),
463 464 ('chan_offset', 'u4', (2 * self.nchannels,)),
464 465 ('rx_amp', 'u4', (self.nchannels,)),
465 466 ('rx_snr', 'f4', (self.nchannels,)),
466 467 ('cross_snr', 'f4', (self.kchan,)),
467 468 ('sea_power_relative', 'f4', (self.kchan,))
468 469 ])
469 470
470 471 # Memory allocation
471 472 if not(self.flag_initialArray):
472 473 self.height = numpy.zeros([2, self.nranges], dtype='f4') + numpy.nan
473 474 self.p_zonal = numpy.zeros([self.nrecords, self.nranges, 2], dtype='f4') + numpy.nan
474 475 self.p_meridional = numpy.zeros([self.nrecords, self.nranges, 2], dtype='f4') + numpy.nan
475 476 self.p_vertical = numpy.zeros([self.nrecords, self.nranges, 2], dtype='f4') + numpy.nan
476 477 self.p_snr = numpy.zeros([self.nrecords, self.nranges, self.kchan, 2], dtype='f4') + numpy.nan
477 478 self.flag_initialArray = True
478 479
479 480 self.time[self.imode, self.count] = self.header_rec1['time'][0]
480 481 self.time1 = self.header_rec1['time'][0]
481 482 tseconds = self.header_rec1['time'][0]
482 483 local_t1 = time.localtime(tseconds)
483 484 self.year = local_t1.tm_year
484 485 self.month = local_t1.tm_mon
485 486 self.day = local_t1.tm_mday
486 487 self.t = datetime.datetime(self.year, self.month, self.day)
487 488
488 489
489 490 def setHeader(self):
490 491 '''
491 492 Saving metada on dataOut object
492 493
493 494 '''
494 495 self.dataOut.type = 'Parameters'
495 496 self.dataOut.useLocalTime = False
496 self.dataOut.outputInterval = 157
497 # self.dataOut.outputInterval = 157
498 self.dataOut.paramInterval = 157
497 499 self.dataOut.timezone = self.timezone
498 500 self.dataOut.site = self.siteFile
499 501 self.dataOut.nrecords = self.nrecords
500 502 self.dataOut.sizeOfFile = self.sizeOfFile
501 503 self.dataOut.lat = self.lat
502 504 self.dataOut.lon = self.lon
503 505 self.dataOut.nchannels = self.nchannels
504 506 self.dataOut.kchan = self.kchan
505 507 self.dataOut.nranges = self.nranges
506 508 self.dataOut.deltha = self.deltha
507 509 self.dataOut.correction = self.correction
508 510 self.dataOut.nmodes = self.nmodes
509 511 self.dataOut.imode = self.imode
510 512 self.dataOut.antenna = self.antenna
511 513 self.dataOut.rx_gains = self.rx_gains
512 514
513 515 def dataRecords(self, status_value):
514 516 '''
515 517 Reading and filtering data block record of BLTR rawdata file, filtering is according to status_value.
516 518
517 519 Input:
518 520 status_value - Array data is set to NAN for values that are not equal to status_value
519 521
520 522 '''
521 523 data_rec = numpy.fromfile(self.pointer, self.d_rec, self.nranges)
522 524 status = []
523 525 zonal = []
524 526 meridional = []
525 527 vertical = []
526 528 rx_snr = []
527 529
528 530 index = 0
529 531 for rec in data_rec:
530 532 status.append(rec['status'])
531 533 zonal.append(rec['zonal'])
532 534 meridional.append(rec['meridional'])
533 535 vertical.append(rec['vertical'])
534 536 self.height[self.imode, index] = (rec['range'] - self.correction) / 1000.
535 537 numpy.seterr(all='ignore')
536 538 index = index + 1
537 539 rx_snr.append(rec['rx_snr'])
538 540
539 541 status = numpy.array(status, dtype='int')
540 542 zonal = numpy.array(zonal, dtype='float')
541 543 meridional = numpy.array(meridional, dtype='float')
542 544 vertical = numpy.array(vertical, dtype='float')
543 545 rx_snr = numpy.array(rx_snr, dtype='float')
544 546
545 547
546 548
547 549 rx_snr = rx_snr.reshape((self.nranges, self.nchannels))
548 550
549 551 # FILTERING DATA
550 552 stvalue = status_value
551 553 zonal[numpy.where(zonal == -9999.)] = numpy.nan
552 554 zonal[numpy.where(status != stvalue)] = numpy.nan
553 555 self.p_zonal[self.count, :, self.imode] = zonal
554 556 self.one_zonal= self.p_zonal[self.count, :, :]
555 557
556 558 meridional[numpy.where(meridional == -9999.)] = numpy.nan
557 559 meridional[numpy.where(status != stvalue)] = numpy.nan
558 560 self.p_meridional[self.count, :, self.imode] = meridional
559 561 self.one_meridional = self.p_meridional[self.count, :, :]
560 562
561 563 vertical[numpy.where(vertical == -9999.)] = numpy.nan
562 564 vertical[numpy.where(status != stvalue)] = numpy.nan
563 565 self.p_vertical[self.count, :, self.imode] = vertical
564 566 self.one_vertical = self.p_vertical[self.count, :, :]
565 567
566 568 rx_snr[numpy.where(rx_snr == -9999.)] = numpy.nan
567 569 rx_snr[numpy.where(status != stvalue), :] = numpy.nan
568 570
569 571
570 572 for k in range(self.kchan):
571 573 self.p_snr[self.count, :, k, self.imode] = numpy.power(10, rx_snr[:, k] / 10)
572 574
573 575 self.one_snr = self.p_snr[self.count, :, :, :]
574 576 if self.nmodes == 2:
575 577 self.count = self.count + self.imode
576 578 else:
577 579 self.count = self.count + 1
578 580
579 581 self.imode +=1
580 582 self.counter_records = self.counter_records + 1
581 583
582 584 self.zon_ref = self.p_zonal
583 585 self.ver_ref = self.p_vertical
584 586 self.mer_ref = self.p_meridional
585 587 self.snr_ref = self.p_snr
586 588
587 589
588 590
589 591
590 592 def Close (self):
591 593 '''
592 594 Closing BLTR rawdata file
593 595 '''
594 596 if self.pointer.tell() == self.sizeOfFile:
595 597 self.pointer.close()
596 598 return
597 599
598 600
599 601
600 602 class testBLTRWriter(Operation):
601 603
602 604
603 605 def __init__(self):
604 606
605 607 Operation.__init__(self)
606 608 self.dataOut = Parameters()
607 609 self.path = None
608 610 self.dataOut = None
609 611 self.flagIsNewFile=1
610 612 self.ext = ".hdf5"
611 613
612 614 return
613 615
614 616 def run(self, dataOut, path , modetowrite,**kwargs):
615 617
616 618 if self.flagIsNewFile:
617 619 flagdata = self.setup(dataOut, path, modetowrite)
618 620
619 621 self.putData()
620 622 return
621 623
622 624 def setup(self, dataOut, path, modetowrite):
623 625 '''
624 626 Recovering data to write in new *.hdf5 file
625 627 Inputs:
626 628 modew -- mode to write (1 or 2)
627 629 path -- destination path
628 630
629 631 '''
630 632
631 633 self.im = modetowrite-1
632 634 if self.im!=0 and self.im!=1:
633 635 raise ValueError, 'Check "modetowrite" value. Must be egual to 1 or 2, "{}" is not valid. '.format(modetowrite)
634 636
635 637 self.dataOut = dataOut
636 638 self.nmodes = self.dataOut.nmodes
637 639 self.nchannels = self.dataOut.nchannels
638 640 self.lat = self.dataOut.lat
639 641 self.lon = self.dataOut.lon
640 642 self.hcm = 3
641 643 self.thisDate = self.dataOut.utctimeInit
642 644 self.year = self.dataOut.year
643 645 self.month = self.dataOut.month
644 646 self.day = self.dataOut.day
645 647 self.path = path
646 648
647 649 self.flagIsNewFile = 0
648 650
649 651 return 1
650 652
651 653 def setFile(self):
652 654 '''
653 655 - Determining the file name for each mode of operation
654 656 kinst - Kind of Instrument (mnemotic)
655 657 kindat - Kind of Data (mnemotic)
656 658
657 659 - Creating a cedarObject
658 660
659 661 '''
660 662 lat_piura = -5.17
661 663 lat_huancayo = -12.04
662 664 lat_porcuya = -5.8
663 665
664 666 if '%2.2f' % self.lat == '%2.2f' % lat_piura:
665 667 self.instMnemonic = 'pbr'
666 668
667 669 elif '%2.2f' % self.lat == '%2.2f' % lat_huancayo:
668 670 self.instMnemonic = 'hbr'
669 671
670 672 elif '%2.2f' % self.lat == '%2.2f' % lat_porcuya:
671 673 self.instMnemonic = 'obr'
672 674 else: raise Warning, "The site of file read doesn't match any site known. Only file from Huancayo, Piura and Porcuya can be processed.\n Check the file "
673 675
674 676 mode = ['_mode1','_mode2']
675 677
676 678 self.hdf5filename = '%s%4.4d%2.2d%2.2d%s%s' % (self.instMnemonic,
677 679 self.year,
678 680 self.month,
679 681 self.day,
680 682 mode[self.im],
681 683 self.ext)
682 684
683 685 self.fullname=os.path.join(self.path,self.hdf5filename)
684 686
685 687 if os.path.isfile(self.fullname) :
686 688 print "Destination path '%s' already exists. Previous file deleted. " %self.fullname
687 689 os.remove(self.fullname)
688 690
689 691 # Identify kinst and kindat
690 692 InstName = self.hdf5filename[0:3]
691 693 KinstList = [1000, 1001, 1002]
692 694 KinstId = {'pbr':0, 'hbr':1, 'obr':2} # pbr:piura, hbr:huancayo, obr:porcuya
693 695 KindatList = [1600, 1601] # mode 1, mode 2
694 696 self.type = KinstId[InstName]
695 697 self.kinst = KinstList[self.type]
696 698 self.kindat = KindatList[self.im]
697 699
698 700 try:
699 701 self.cedarObj = madrigal.cedar.MadrigalCedarFile(self.fullname, True)
700 702 except ValueError, message:
701 703 print '[Error]: Impossible to create a cedar object with "madrigal.cedar.MadrigalCedarFile" '
702 704 return
703 705
704 706 return 1
705 707
706 708 def writeBlock(self):
707 709 '''
708 710 - Selecting mode of operation:
709 711
710 712 bltr high resolution mode 1 - Low Atmosphere (0 - 3km) // bltr high resolution mode 2 - High Atmosphere (0 - 10km)
711 713 msnr - Average Signal Noise Ratio in dB
712 714 hcm - 3 km
713 715
714 716 - Filling the cedarObject by a block: each array data entry is assigned a code that defines the parameter to write to the file
715 717
716 718 GDLATR - Reference geod latitude (deg)
717 719 GDLONR - Reference geographic longitude (deg)
718 720 GDLAT2 - Geodetic latitude of second inst (deg)
719 721 GLON2 - Geographic longitude of second inst (deg)
720 722
721 723 GDALT - Geodetic altitude (height) (km)
722 724 SNL - Log10 (signal to noise ratio)
723 725 VN1P2 - Neutral wind in direction 1 (eastward) (m/s), ie zonal wind
724 726 VN2P2 - Neutral wind in direction 2 (northward) (m/s), ie meridional wind
725 727 EL2 - Ending elevation angle (deg), ie vertical wind
726 728
727 729 Other parameters: /madrigal3/metadata/parcodes.tab
728 730
729 731 '''
730 732
731 733 self.z_zon = self.dataOut.data_output[0,:,:]
732 734 self.z_mer =self.dataOut.data_output[1,:,:]
733 735 self.z_ver = self.dataOut.data_output[2,:,:]
734 736
735 737 if self.im == 0:
736 738 h_select = numpy.where(numpy.bitwise_and(self.dataOut.height[0, :] >= 0., self.dataOut.height[0, :] <= self.hcm, numpy.isfinite(self.dataOut.height[0, :])))
737 739 else:
738 740 h_select = numpy.where(numpy.bitwise_and(self.dataOut.height[0, :] >= 0., self.dataOut.height[0, :] < 20, numpy.isfinite(self.dataOut.height[0, :])))
739 741
740 742 ht = h_select[0]
741 743
742 744 self.o_height = self.dataOut.height[self.im, ht]
743 745 self.o_zon = self.z_zon[ht, self.im]
744 746 self.o_mer = self.z_mer[ht, self.im]
745 747 self.o_ver = self.z_ver[ht, self.im]
746 748 o_snr = self.dataOut.data_SNR[ :, :, self.im]
747 749
748 750 o_snr = o_snr[ht, :]
749 751
750 752 ndiv = numpy.nansum((numpy.isfinite(o_snr)), 1)
751 753 ndiv = ndiv.astype(float)
752 754
753 755 sel_div = numpy.where(ndiv == 0.)
754 756 ndiv[sel_div] = numpy.nan
755 757
756 758 if self.nchannels > 1:
757 759 msnr = numpy.nansum(o_snr, axis=1)
758 760 else:
759 761 msnr = o_snr
760 762
761 763 try:
762 764 self.msnr = 10 * numpy.log10(msnr / ndiv)
763 765 except ZeroDivisionError:
764 766 self.msnr = 10 * numpy.log10(msnr /1)
765 767 print 'Number of division (ndiv) egal to 1 by default. Check SNR'
766 768
767 769 time_t = time.gmtime(self.dataOut.time1)
768 770 year = time_t.tm_year
769 771 month = time_t.tm_mon
770 772 day = time_t.tm_mday
771 773 hour = time_t.tm_hour
772 774 minute = time_t.tm_min
773 775 second = time_t.tm_sec
774 776 timedate_0 = datetime.datetime(year, month, day, hour, minute, second)
775 777
776 778 # 1d parameters
777 779 GDLATR = self.lat
778 780 GDLONR = self.lon
779 781 GDLAT2 = self.lat
780 782 GLON2 = self.lon
781 783
782 784 # 2d parameters
783 785 GDALT = self.o_height
784 786
785 787 SNL = self.msnr
786 788 VN1P2 = self.o_zon
787 789 VN2P2 = self.o_mer
788 790 EL2 = self.o_ver
789 791 NROW = len(self.o_height)
790 792
791 793 startTime = timedate_0
792 794 endTime = startTime
793 795 self.dataRec = madrigal.cedar.MadrigalDataRecord(self.kinst,
794 796 self.kindat,
795 797 startTime.year,
796 798 startTime.month,
797 799 startTime.day,
798 800 startTime.hour,
799 801 startTime.minute,
800 802 startTime.second,
801 803 0,
802 804 endTime.year,
803 805 endTime.month,
804 806 endTime.day,
805 807 endTime.hour,
806 808 endTime.minute,
807 809 endTime.second,
808 810 0,
809 811 ('gdlatr', 'gdlonr', 'gdlat2', 'glon2'),
810 812 ('gdalt', 'snl', 'vn1p2', 'vn2p2', 'el2'),
811 813 NROW, ind2DList=['gdalt'])
812 814
813 815 # Setting 1d values
814 816 self.dataRec.set1D('gdlatr', GDLATR)
815 817 self.dataRec.set1D('gdlonr', GDLONR)
816 818 self.dataRec.set1D('gdlat2', GDLAT2)
817 819 self.dataRec.set1D('glon2', GLON2)
818 820
819 821 # Setting 2d values
820 822 for n in range(self.o_height.shape[0]):
821 823 self.dataRec.set2D('gdalt', n, GDALT[n])
822 824 self.dataRec.set2D('snl', n, SNL[n])
823 825 self.dataRec.set2D('vn1p2', n, VN1P2[n])
824 826 self.dataRec.set2D('vn2p2', n, VN2P2[n])
825 827 self.dataRec.set2D('el2', n, EL2[n])
826 828
827 829 # Appending new data record
828 830 '''
829 831 [MADRIGAL3]There are two ways to write to a MadrigalCedarFile. Either this method (write) is called after all the
830 832 records have been appended to the MadrigalCedarFile, or dump is called after a certain number of records are appended,
831 833 and then at the end dump is called a final time if there were any records not yet dumped, followed by addArray.
832 834 '''
833 835
834 836 self.cedarObj.append(self.dataRec)
835 837 print ' [Writing] records {} (mode {}).'.format(self.dataOut.counter_records,self.im+1)
836 838 self.cedarObj.dump()
837 839
838 840
839 841
840 842
841 843 def setHeader(self):
842 844 '''
843 845 - Creating self.catHeadObj
844 846 - Adding information catalog
845 847 - Writing file header
846 848
847 849 '''
848 850 self.catHeadObj = madrigal.cedar.CatalogHeaderCreator(self.fullname)
849 851 kindatDesc, comments, analyst, history, principleInvestigator = self._info_BLTR()
850 852
851 853 self.catHeadObj.createCatalog(principleInvestigator="Jarjar",
852 854 expPurpose='characterize the atmospheric dynamics in this region where frequently it happens the El Nino',
853 855 sciRemarks="http://madrigal3.haystack.mit.edu/static/CEDARMadrigalHdf5Format.pdf")
854 856
855 857 self.catHeadObj.createHeader(kindatDesc, analyst, comments, history)
856 858
857 859 self.catHeadObj.write()
858 860
859 861 print '[File created] path: %s' % (self.fullname)
860 862
861 863 def putData(self):
862 864
863 865 if self.dataOut.flagNoData:
864 866 return 0
865 867
866 868 if self.dataOut.counter_records == 1:
867 869 self.setFile()
868 870 print '[Writing] Setting new hdf5 file for the mode {}'.format(self.im+1)
869 871
870 872 if self.dataOut.counter_records <= self.dataOut.nrecords:
871 873 self.writeBlock()
872 874
873 875
874 876 if self.dataOut.counter_records == self.dataOut.nrecords:
875 877 self.cedarObj.addArray()
876 878
877 879 self.setHeader()
878 880 self.flagIsNewFile = 1
879 881
880 882 def _info_BLTR(self):
881 883
882 884 kindatDesc = '''--This header is for KINDAT = %d''' % self.kindat
883 885 history = None
884 886 analyst = '''Jarjar'''
885 887 principleInvestigator = '''
886 888 Jarjar
887 889 Radio Observatorio de Jicamarca
888 890 Instituto Geofisico del Peru
889 891
890 892 '''
891 893 if self.type == 1:
892 894 comments = '''
893 895
894 896 --These data are provided by two Boundary Layer and Tropospheric Radar (BLTR) deployed at two different locations at Peru(GMT-5), one of them at Piura(5.17 S, 80.64W) and another located at Huancayo (12.04 S, 75.32 W).
895 897
896 898 --The purpose of conducting these observations is to measure wind in the differents levels of height, this radar makes measurements the Zonal(U), Meridional(V) and Vertical(W) wind velocities component in northcoast from Peru. And the main purpose of these mensurations is to characterize the atmospheric dynamics in this region where frequently it happens the 'El Nino Phenomenon'
897 899
898 900 --In Kindat = 1600, contains information of wind velocities component since 0 Km to 3 Km.
899 901
900 902 --In Kindat = 1601, contains information of wind velocities component since 0 Km to 10 Km.
901 903
902 904 --The Huancayo-BLTR is a VHF Profiler Radar System is a 3 channel coherent receiver pulsed radar utilising state-of-the-art software and computing techniques to acquire, decode, and translate signals obtained from partial reflection echoes in the troposphere, lower stratosphere and mesosphere. It uses an array of three horizontal spaced and vertically directed receiving antennas. The data is recorded thirty seconds, averaged to one minute mean values of Height, Zonal, Meridional and Vertical wind.
903 905
904 906 --The Huancayo-BLTR was installed in January 2010. This instrument was designed and constructed by Genesis Soft Pty. Ltd. Is constituted by three groups of spaced antennas (distributed) forming an isosceles triangle.
905 907
906 908
907 909 Station _______ Geographic Coord ______ Geomagnetic Coord
908 910
909 911 _______________ Latitude _ Longitude __ Latitude _ Longitude
910 912
911 913 Huancayo (HUA) __12.04 S ___ 75.32 W _____ -12.05 ____ 352.85
912 914 Piura (PIU) _____ 5.17 S ___ 80.64 W ______ 5.18 ____ 350.93
913 915
914 916 WIND OBSERVATIONS
915 917
916 918 --To obtain wind the BLTR uses Spaced Antenna technique (e.g., Briggs 1984). The scatter and reflection it still provided by variations in the refractive index as in the Doppler method(Gage and Basley,1978; Balsley and Gage 1982; Larsen and Rottger 1982), but instead of using the Doppler shift to derive the velocity components, the cross-correlation between signals in an array of three horizontally spaced and vertically directed receiving antennas is used.
917 919
918 920 ......................................................................
919 921 For more information, consult the following references:
920 922 - Balsley, B. B., and K. S. Gage., On the use of radars for operational wind profiling, Bull. Amer. Meteor.Soc.,63, 1009-1018, 1982.
921 923
922 924 - Briggs, B. H., The analysis of spaced sensor data by correations techniques, Handbook for MAP, Vol. 13, SCOTEP Secretariat, University of Illinois, Urbana, 166-186, 1984.
923 925
924 926 - Gage, K. S., and B.B. Balsley., Doppler radar probing of the clear atmosphere, Bull. Amer. Meteor.Soc., 59, 1074-1093, 1978.
925 927
926 928 - Larsen, M. F., The Spaced Antenna Technique for Radar Wind Profiling, Journal of Atm. and Ocean. Technology. , Vol.6, 920-937, 1989.
927 929
928 930 - Larsen, M. F., A method for single radar voracity measurements?, Handbook for MAP,SCOSTEP Secretariat, University of the Illinois, Urban, in press, 1989.
929 931 ......................................................................
930 932
931 933 ACKNOWLEDGEMENTS:
932 934
933 935 --The Piura and Huancayo BLTR are part of the network of instruments operated by the Jicamarca Radio Observatory.
934 936
935 937 --The Jicamarca Radio Observatory is a facility of the Instituto Geofisico del Peru operated with support from the NSF Cooperative Agreement ATM-0432565 through Cornell University
936 938
937 939 ......................................................................
938 940
939 941 Further questions and comments should be addressed to:
940 942 Radio Observatorio de Jicamarca
941 943 Instituto Geofisico del Peru
942 944 Lima, Peru
943 945 Web URL: http://jro.igp.gob.pe
944 946 ......................................................................
945 947 '''
946 948
947 949 return kindatDesc, comments, analyst, history, principleInvestigator
948 950
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
@@ -1,16 +1,16
1 1 '''
2 2
3 3 $Author: murco $
4 4 $Id: Processor.py 1 2012-11-12 18:56:07Z murco $
5 5 '''
6 6
7 7 from jroproc_voltage import *
8 8 from jroproc_spectra import *
9 9 from jroproc_heispectra import *
10 10 from jroproc_amisr import *
11 11 from jroproc_correlation import *
12 12 from jroproc_parameters import *
13 13 from jroproc_spectra_lags import *
14 14 from jroproc_spectra_acf import *
15 #from jroproc_bltr import *
15 from jroproc_bltr import *
16 16
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
@@ -1,576 +1,576
1 1 '''
2 2 Created on Oct 24, 2016
3 3
4 4 @author: roj- LouVD
5 5 '''
6 6
7 7 import numpy
8 8 import copy
9 9 import datetime
10 10 import time
11 11 from time import gmtime
12 12
13 13 from jroproc_base import ProcessingUnit
14 14 from schainpy.model.data.jrodata import Parameters
15 15 from numpy import transpose
16 16
17 17 from matplotlib import cm
18 18 import matplotlib.pyplot as plt
19 19 from matplotlib.mlab import griddata
20 20
21 21
22 22
23 23
24 24 class BLTRProcess(ProcessingUnit):
25 25 isConfig = False
26 26 '''
27 27 Processing unit for BLTR rawdata
28 28
29 29 Inputs:
30 30 self.dataOut.nmodes - Number of operation modes
31 31 self.dataOut.nchannels - Number of channels
32 32 self.dataOut.nranges - Number of ranges
33 33
34 34 self.dataOut.data_SNR - SNR array
35 35 self.dataOut.data_output - Zonal, Vertical and Meridional velocity array
36 36 self.dataOut.height - Height array (km)
37 37 self.dataOut.time - Time array (seconds)
38 38
39 39 self.dataOut.fileIndex -Index of the file currently read
40 40 self.dataOut.lat - Latitude coordinate of BLTR location
41 41
42 42 self.dataOut.doy - Experiment doy (number of the day in the current year)
43 43 self.dataOut.month - Experiment month
44 44 self.dataOut.day - Experiment day
45 45 self.dataOut.year - Experiment year
46 46 '''
47 47
48 def __init__(self):
48 def __init__(self, **kwargs):
49 49 '''
50 50 Inputs: None
51 51
52 52 '''
53 ProcessingUnit.__init__(self)
53 ProcessingUnit.__init__(self, **kwargs)
54 54 self.dataOut = Parameters()
55 55
56 56 # Filters
57 57 snr_val = None
58 58 value = None
59 59 svalue2 = None
60 60 method = None
61 61 factor = None
62 62 filter = None
63 63 npoints = None
64 64 status_value = None
65 65 width = None
66 66 self.flagfirstmode = 0
67 67
68 68 def run (self):
69 69 if self.dataIn.type == "Parameters":
70 70 self.dataOut.copy(self.dataIn)
71 71
72 72
73 73 def TimeSelect(self):
74 74 '''
75 75 Selecting the time array according to the day of the experiment with a duration of 24 hours
76 76 '''
77 77
78 78 k1 = datetime.datetime(self.dataOut.year, self.dataOut.month, self.dataOut.day) - datetime.timedelta(hours=5)
79 79 k2 = datetime.datetime(self.dataOut.year, self.dataOut.month, self.dataOut.day) + datetime.timedelta(hours=25) - datetime.timedelta(hours=5)
80 80 limit_sec1 = time.mktime(k1.timetuple())
81 81 limit_sec2 = time.mktime(k2.timetuple())
82 82 valid_data = 0
83 83
84 84 doy = self.dataOut.doy
85 85 t1 = numpy.where(self.dataOut.time[0, :] >= limit_sec1)
86 86 t2 = numpy.where(self.dataOut.time[0, :] < limit_sec2)
87 87 time_select = []
88 88 for val_sec in t1[0]:
89 89 if val_sec in t2[0]:
90 90 time_select.append(val_sec)
91 91
92 92 time_select = numpy.array(time_select, dtype='int')
93 93 valid_data = valid_data + len(time_select)
94 94
95 95
96 96 if len(time_select) > 0:
97 97 self.f_timesec = self.dataOut.time[:, time_select]
98 98 snr = self.dataOut.data_SNR[time_select, :, :, :]
99 99 zon = self.dataOut.data_output[0][time_select, :, :]
100 100 mer = self.dataOut.data_output[1][time_select, :, :]
101 101 ver = self.dataOut.data_output[2][time_select, :, :]
102 102
103 103 if valid_data > 0:
104 104 self.timesec1 = self.f_timesec[0, :]
105 105 self.f_height = self.dataOut.height
106 106 self.f_zon = zon
107 107 self.f_mer = mer
108 108 self.f_ver = ver
109 109 self.f_snr = snr
110 110 self.f_timedate = []
111 111 self.f_time = []
112 112
113 113 for valuet in self.timesec1:
114 114 time_t = time.gmtime(valuet)
115 115 year = time_t.tm_year
116 116 month = time_t.tm_mon
117 117 day = time_t.tm_mday
118 118 hour = time_t.tm_hour
119 119 minute = time_t.tm_min
120 120 second = time_t.tm_sec
121 121 f_timedate_0 = datetime.datetime(year, month, day, hour, minute, second)
122 122 self.f_timedate.append(f_timedate_0)
123 123
124 124 return self.f_timedate, self.f_timesec, self.f_height, self.f_zon, self.f_mer, self.f_ver, self.f_snr
125 125
126 126 else:
127 127 self.f_timesec = None
128 128 self.f_timedate = None
129 129 self.f_height = None
130 130 self.f_zon = None
131 131 self.f_mer = None
132 132 self.f_ver = None
133 133 self.f_snr = None
134 134 print 'Invalid time'
135 135
136 136 return self.f_timedate, self.f_height, self.f_zon, self.f_mer, self.f_ver, self.f_snr
137 137
138 138 def SnrFilter(self, snr_val,modetofilter):
139 139 '''
140 140 Inputs: snr_val - Threshold value
141 141
142 142 '''
143 143 if modetofilter!=2 and modetofilter!=1 :
144 144 raise ValueError,'Mode to filter should be "1" or "2". {} is not valid, check "Modetofilter" value.'.format(modetofilter)
145 145 m = modetofilter-1
146 146
147 147 print ' SNR filter [mode {}]: SNR <= {}: data_output = NA'.format(modetofilter,snr_val)
148 148 for k in range(self.dataOut.nchannels):
149 149 for r in range(self.dataOut.nranges):
150 150 if self.dataOut.data_SNR[r,k,m] <= snr_val:
151 151 self.dataOut.data_output[2][r,m] = numpy.nan
152 152 self.dataOut.data_output[1][r,m] = numpy.nan
153 153 self.dataOut.data_output[0][r,m] = numpy.nan
154 154
155 155
156 156
157 157 def OutliersFilter(self,modetofilter,svalue,svalue2,method,factor,filter,npoints):
158 158 '''
159 159 Inputs:
160 160 svalue - string to select array velocity
161 161 svalue2 - string to choose axis filtering
162 162 method - 0 for SMOOTH or 1 for MEDIAN
163 163 factor - number used to set threshold
164 164 filter - 1 for data filtering using the standard deviation criteria else 0
165 165 npoints - number of points for mask filter
166 166
167 167 '''
168 168 if modetofilter!=2 and modetofilter!=1 :
169 169 raise ValueError,'Mode to filter should be "1" or "2". {} is not valid, check "Modetofilter" value.'.format(modetofilter)
170 170
171 171 m = modetofilter-1
172 172
173 173 print ' Outliers Filter [mode {}]: {} {} / threshold = {}'.format(modetofilter,svalue,svalue,factor)
174 174
175 175 npoints = 9
176 176 novalid = 0.1
177 177 if svalue == 'zonal':
178 178 value = self.dataOut.data_output[0]
179 179
180 180 elif svalue == 'meridional':
181 181 value = self.dataOut.data_output[1]
182 182
183 183 elif svalue == 'vertical':
184 184 value = self.dataOut.data_output[2]
185 185
186 186 else:
187 187 print 'value is not defined'
188 188 return
189 189
190 190 if svalue2 == 'inTime':
191 191 yaxis = self.dataOut.height
192 192 xaxis = numpy.array([[self.dataOut.time1],[self.dataOut.time1]])
193 193
194 194 elif svalue2 == 'inHeight':
195 195 yaxis = numpy.array([[self.dataOut.time1],[self.dataOut.time1]])
196 196 xaxis = self.dataOut.height
197 197
198 198 else:
199 199 print 'svalue2 is required, either inHeight or inTime'
200 200 return
201 201
202 202 output_array = value
203 203
204 204 value_temp = value[:,m]
205 205 error = numpy.zeros(len(self.dataOut.time[m,:]))
206 206 if svalue2 == 'inHeight':
207 207 value_temp = numpy.transpose(value_temp)
208 208 error = numpy.zeros(len(self.dataOut.height))
209 209
210 210 htemp = yaxis[m,:]
211 211 std = value_temp
212 212 for h in range(len(htemp)):
213 213 if filter: #standard deviation filtering
214 214 std[h] = numpy.std(value_temp[h],ddof = npoints)
215 215 value_temp[numpy.where(std[h] > 5),h] = numpy.nan
216 216 error[numpy.where(std[h] > 5)] = error[numpy.where(std[h] > 5)] + 1
217 217
218 218
219 219 nvalues_valid = len(numpy.where(numpy.isfinite(value_temp[h]))[0])
220 220 minvalid = novalid*len(xaxis[m,:])
221 221 if minvalid <= npoints:
222 222 minvalid = npoints
223 223
224 224 #only if valid values greater than the minimum required (10%)
225 225 if nvalues_valid > minvalid:
226 226
227 227 if method == 0:
228 228 #SMOOTH
229 229 w = value_temp[h] - self.Smooth(input=value_temp[h], width=npoints, edge_truncate=1)
230 230
231 231
232 232 if method == 1:
233 233 #MEDIAN
234 234 w = value_temp[h] - self.Median(input=value_temp[h], width = npoints)
235 235
236 236 dw = numpy.std(w[numpy.where(numpy.isfinite(w))],ddof = 1)
237 237
238 238 threshold = dw*factor
239 239 value_temp[numpy.where(w > threshold),h] = numpy.nan
240 240 value_temp[numpy.where(w < -1*threshold),h] = numpy.nan
241 241
242 242
243 243 #At the end
244 244 if svalue2 == 'inHeight':
245 245 value_temp = numpy.transpose(value_temp)
246 246 output_array[:,m] = value_temp
247 247
248 248 if svalue == 'zonal':
249 249 self.dataOut.data_output[0] = output_array
250 250
251 251 elif svalue == 'meridional':
252 252 self.dataOut.data_output[1] = output_array
253 253
254 254 elif svalue == 'vertical':
255 255 self.dataOut.data_output[2] = output_array
256 256
257 257 return self.dataOut.data_output
258 258
259 259
260 260 def Median(self,input,width):
261 261 '''
262 262 Inputs:
263 263 input - Velocity array
264 264 width - Number of points for mask filter
265 265
266 266 '''
267 267
268 268 if numpy.mod(width,2) == 1:
269 269 pc = int((width - 1) / 2)
270 270 cont = 0
271 271 output = []
272 272
273 273 for i in range(len(input)):
274 274 if i >= pc and i < len(input) - pc:
275 275 new2 = input[i-pc:i+pc+1]
276 276 temp = numpy.where(numpy.isfinite(new2))
277 277 new = new2[temp]
278 278 value = numpy.median(new)
279 279 output.append(value)
280 280
281 281 output = numpy.array(output)
282 282 output = numpy.hstack((input[0:pc],output))
283 283 output = numpy.hstack((output,input[-pc:len(input)]))
284 284
285 285 return output
286 286
287 287 def Smooth(self,input,width,edge_truncate = None):
288 288 '''
289 289 Inputs:
290 290 input - Velocity array
291 291 width - Number of points for mask filter
292 292 edge_truncate - 1 for truncate the convolution product else
293 293
294 294 '''
295 295
296 296 if numpy.mod(width,2) == 0:
297 297 real_width = width + 1
298 298 nzeros = width / 2
299 299 else:
300 300 real_width = width
301 301 nzeros = (width - 1) / 2
302 302
303 303 half_width = int(real_width)/2
304 304 length = len(input)
305 305
306 306 gate = numpy.ones(real_width,dtype='float')
307 307 norm_of_gate = numpy.sum(gate)
308 308
309 309 nan_process = 0
310 310 nan_id = numpy.where(numpy.isnan(input))
311 311 if len(nan_id[0]) > 0:
312 312 nan_process = 1
313 313 pb = numpy.zeros(len(input))
314 314 pb[nan_id] = 1.
315 315 input[nan_id] = 0.
316 316
317 317 if edge_truncate == True:
318 318 output = numpy.convolve(input/norm_of_gate,gate,mode='same')
319 319 elif edge_truncate == False or edge_truncate == None:
320 320 output = numpy.convolve(input/norm_of_gate,gate,mode='valid')
321 321 output = numpy.hstack((input[0:half_width],output))
322 322 output = numpy.hstack((output,input[len(input)-half_width:len(input)]))
323 323
324 324 if nan_process:
325 325 pb = numpy.convolve(pb/norm_of_gate,gate,mode='valid')
326 326 pb = numpy.hstack((numpy.zeros(half_width),pb))
327 327 pb = numpy.hstack((pb,numpy.zeros(half_width)))
328 328 output[numpy.where(pb > 0.9999)] = numpy.nan
329 329 input[nan_id] = numpy.nan
330 330 return output
331 331
332 332 def Average(self,aver=0,nhaver=1):
333 333 '''
334 334 Inputs:
335 335 aver - Indicates the time period over which is averaged or consensus data
336 336 nhaver - Indicates the decimation factor in heights
337 337
338 338 '''
339 339 nhpoints = 48
340 340
341 341 lat_piura = -5.17
342 342 lat_huancayo = -12.04
343 343 lat_porcuya = -5.8
344 344
345 345 if '%2.2f'%self.dataOut.lat == '%2.2f'%lat_piura:
346 346 hcm = 3.
347 347 if self.dataOut.year == 2003 :
348 348 if self.dataOut.doy >= 25 and self.dataOut.doy < 64:
349 349 nhpoints = 12
350 350
351 351 elif '%2.2f'%self.dataOut.lat == '%2.2f'%lat_huancayo:
352 352 hcm = 3.
353 353 if self.dataOut.year == 2003 :
354 354 if self.dataOut.doy >= 25 and self.dataOut.doy < 64:
355 355 nhpoints = 12
356 356
357 357
358 358 elif '%2.2f'%self.dataOut.lat == '%2.2f'%lat_porcuya:
359 359 hcm = 5.#2
360 360
361 361 pdata = 0.2
362 362 taver = [1,2,3,4,6,8,12,24]
363 363 t0 = 0
364 364 tf = 24
365 365 ntime =(tf-t0)/taver[aver]
366 366 ti = numpy.arange(ntime)
367 367 tf = numpy.arange(ntime) + taver[aver]
368 368
369 369
370 370 old_height = self.dataOut.heightList
371 371
372 372 if nhaver > 1:
373 373 num_hei = len(self.dataOut.heightList)/nhaver/self.dataOut.nmodes
374 374 deltha = 0.05*nhaver
375 375 minhvalid = pdata*nhaver
376 376 for im in range(self.dataOut.nmodes):
377 377 new_height = numpy.arange(num_hei)*deltha + self.dataOut.height[im,0] + deltha/2.
378 378
379 379
380 380 data_fHeigths_List = []
381 381 data_fZonal_List = []
382 382 data_fMeridional_List = []
383 383 data_fVertical_List = []
384 384 startDTList = []
385 385
386 386
387 387 for i in range(ntime):
388 388 height = old_height
389 389
390 390 start = datetime.datetime(self.dataOut.year,self.dataOut.month,self.dataOut.day) + datetime.timedelta(hours = int(ti[i])) - datetime.timedelta(hours = 5)
391 391 stop = datetime.datetime(self.dataOut.year,self.dataOut.month,self.dataOut.day) + datetime.timedelta(hours = int(tf[i])) - datetime.timedelta(hours = 5)
392 392
393 393
394 394 limit_sec1 = time.mktime(start.timetuple())
395 395 limit_sec2 = time.mktime(stop.timetuple())
396 396
397 397 t1 = numpy.where(self.f_timesec >= limit_sec1)
398 398 t2 = numpy.where(self.f_timesec < limit_sec2)
399 399 time_select = []
400 400 for val_sec in t1[0]:
401 401 if val_sec in t2[0]:
402 402 time_select.append(val_sec)
403 403
404 404
405 405 time_select = numpy.array(time_select,dtype = 'int')
406 406 minvalid = numpy.ceil(pdata*nhpoints)
407 407
408 408 zon_aver = numpy.zeros([self.dataOut.nranges,self.dataOut.nmodes],dtype='f4') + numpy.nan
409 409 mer_aver = numpy.zeros([self.dataOut.nranges,self.dataOut.nmodes],dtype='f4') + numpy.nan
410 410 ver_aver = numpy.zeros([self.dataOut.nranges,self.dataOut.nmodes],dtype='f4') + numpy.nan
411 411
412 412 if nhaver > 1:
413 413 new_zon_aver = numpy.zeros([num_hei,self.dataOut.nmodes],dtype='f4') + numpy.nan
414 414 new_mer_aver = numpy.zeros([num_hei,self.dataOut.nmodes],dtype='f4') + numpy.nan
415 415 new_ver_aver = numpy.zeros([num_hei,self.dataOut.nmodes],dtype='f4') + numpy.nan
416 416
417 417 if len(time_select) > minvalid:
418 418 time_average = self.f_timesec[time_select]
419 419
420 420 for im in range(self.dataOut.nmodes):
421 421
422 422 for ih in range(self.dataOut.nranges):
423 423 if numpy.sum(numpy.isfinite(self.f_zon[time_select,ih,im])) >= minvalid:
424 424 zon_aver[ih,im] = numpy.nansum(self.f_zon[time_select,ih,im]) / numpy.sum(numpy.isfinite(self.f_zon[time_select,ih,im]))
425 425
426 426 if numpy.sum(numpy.isfinite(self.f_mer[time_select,ih,im])) >= minvalid:
427 427 mer_aver[ih,im] = numpy.nansum(self.f_mer[time_select,ih,im]) / numpy.sum(numpy.isfinite(self.f_mer[time_select,ih,im]))
428 428
429 429 if numpy.sum(numpy.isfinite(self.f_ver[time_select,ih,im])) >= minvalid:
430 430 ver_aver[ih,im] = numpy.nansum(self.f_ver[time_select,ih,im]) / numpy.sum(numpy.isfinite(self.f_ver[time_select,ih,im]))
431 431
432 432 if nhaver > 1:
433 433 for ih in range(num_hei):
434 434 hvalid = numpy.arange(nhaver) + nhaver*ih
435 435
436 436 if numpy.sum(numpy.isfinite(zon_aver[hvalid,im])) >= minvalid:
437 437 new_zon_aver[ih,im] = numpy.nansum(zon_aver[hvalid,im]) / numpy.sum(numpy.isfinite(zon_aver[hvalid,im]))
438 438
439 439 if numpy.sum(numpy.isfinite(mer_aver[hvalid,im])) >= minvalid:
440 440 new_mer_aver[ih,im] = numpy.nansum(mer_aver[hvalid,im]) / numpy.sum(numpy.isfinite(mer_aver[hvalid,im]))
441 441
442 442 if numpy.sum(numpy.isfinite(ver_aver[hvalid,im])) >= minvalid:
443 443 new_ver_aver[ih,im] = numpy.nansum(ver_aver[hvalid,im]) / numpy.sum(numpy.isfinite(ver_aver[hvalid,im]))
444 444 if nhaver > 1:
445 445 zon_aver = new_zon_aver
446 446 mer_aver = new_mer_aver
447 447 ver_aver = new_ver_aver
448 448 height = new_height
449 449
450 450
451 451 tstart = time_average[0]
452 452 tend = time_average[-1]
453 453 startTime = time.gmtime(tstart)
454 454
455 455 year = startTime.tm_year
456 456 month = startTime.tm_mon
457 457 day = startTime.tm_mday
458 458 hour = startTime.tm_hour
459 459 minute = startTime.tm_min
460 460 second = startTime.tm_sec
461 461
462 462 startDTList.append(datetime.datetime(year,month,day,hour,minute,second))
463 463
464 464
465 465 o_height = numpy.array([])
466 466 o_zon_aver = numpy.array([])
467 467 o_mer_aver = numpy.array([])
468 468 o_ver_aver = numpy.array([])
469 469 if self.dataOut.nmodes > 1:
470 470 for im in range(self.dataOut.nmodes):
471 471
472 472 if im == 0:
473 473 h_select = numpy.where(numpy.bitwise_and(height[0,:] >=0,height[0,:] <= hcm,numpy.isfinite(height[0,:])))
474 474 else:
475 475 h_select = numpy.where(numpy.bitwise_and(height[1,:] > hcm,height[1,:] < 20,numpy.isfinite(height[1,:])))
476 476
477 477
478 478 ht = h_select[0]
479 479
480 480 o_height = numpy.hstack((o_height,height[im,ht]))
481 481 o_zon_aver = numpy.hstack((o_zon_aver,zon_aver[ht,im]))
482 482 o_mer_aver = numpy.hstack((o_mer_aver,mer_aver[ht,im]))
483 483 o_ver_aver = numpy.hstack((o_ver_aver,ver_aver[ht,im]))
484 484
485 485 data_fHeigths_List.append(o_height)
486 486 data_fZonal_List.append(o_zon_aver)
487 487 data_fMeridional_List.append(o_mer_aver)
488 488 data_fVertical_List.append(o_ver_aver)
489 489
490 490
491 491 else:
492 492 h_select = numpy.where(numpy.bitwise_and(height[0,:] <= hcm,numpy.isfinite(height[0,:])))
493 493 ht = h_select[0]
494 494 o_height = numpy.hstack((o_height,height[im,ht]))
495 495 o_zon_aver = numpy.hstack((o_zon_aver,zon_aver[ht,im]))
496 496 o_mer_aver = numpy.hstack((o_mer_aver,mer_aver[ht,im]))
497 497 o_ver_aver = numpy.hstack((o_ver_aver,ver_aver[ht,im]))
498 498
499 499 data_fHeigths_List.append(o_height)
500 500 data_fZonal_List.append(o_zon_aver)
501 501 data_fMeridional_List.append(o_mer_aver)
502 502 data_fVertical_List.append(o_ver_aver)
503 503
504 504
505 505 return startDTList, data_fHeigths_List, data_fZonal_List, data_fMeridional_List, data_fVertical_List
506 506
507 507
508 508 def prePlot(self,modeselect=None):
509 509
510 510 '''
511 511 Inputs:
512 512
513 513 self.dataOut.data_output - Zonal, Meridional and Vertical velocity array
514 514 self.dataOut.height - height array
515 515 self.dataOut.time - Time array (seconds)
516 516 self.dataOut.data_SNR - SNR array
517 517
518 518 '''
519 519
520 520 m = modeselect -1
521 521
522 522 print ' [Plotting mode {}]'.format(modeselect)
523 523 if not (m ==1 or m==0):
524 524 raise IndexError("'Mode' must be egual to : 1 or 2")
525 525 #
526 526 if self.flagfirstmode==0:
527 527 #copy of the data
528 528 self.data_output_copy = self.dataOut.data_output.copy()
529 529 self.data_height_copy = self.dataOut.height.copy()
530 530 self.data_time_copy = self.dataOut.time.copy()
531 531 self.data_SNR_copy = self.dataOut.data_SNR.copy()
532 532 self.flagfirstmode = 1
533 533
534 534 else:
535 535 self.dataOut.data_output = self.data_output_copy
536 536 self.dataOut.height = self.data_height_copy
537 537 self.dataOut.time = self.data_time_copy
538 538 self.dataOut.data_SNR = self.data_SNR_copy
539 539 self.flagfirstmode = 0
540 540
541 541
542 542 #select data for mode m
543 543 #self.dataOut.data_output = self.dataOut.data_output[:,:,m]
544 544 self.dataOut.heightList = self.dataOut.height[0,:]
545 545
546 546 data_SNR = self.dataOut.data_SNR[:,:,m]
547 547 self.dataOut.data_SNR= transpose(data_SNR)
548 548
549 549 if m==1 and self.dataOut.counter_records%2==0:
550 550 print '*********'
551 551 print 'MODO 2'
552 552 #print 'Zonal', self.dataOut.data_output[0]
553 553 #print 'Meridional', self.dataOut.data_output[1]
554 554 #print 'Vertical', self.dataOut.data_output[2]
555 555
556 556 print '*********'
557 557
558 558 Vx=self.dataOut.data_output[0,:,m]
559 559 Vy=self.dataOut.data_output[1,:,m]
560 560
561 561 Vmag=numpy.sqrt(Vx**2+Vy**2)
562 562 Vang=numpy.arctan2(Vy,Vx)
563 563 #print 'Vmag', Vmag
564 564 #print 'Vang', Vang
565 565
566 566 self.dataOut.data_output[0,:,m]=Vmag
567 567 self.dataOut.data_output[1,:,m]=Vang
568 568
569 569 prin= self.dataOut.data_output[0,:,m][~numpy.isnan(self.dataOut.data_output[0,:,m])]
570 570 print ' '
571 571 print 'VmagAverage',numpy.mean(prin)
572 572 print ' '
573 573 self.dataOut.data_output = self.dataOut.data_output[:,:,m]
574 574
575 575
576 576 No newline at end of file
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
@@ -1,3963 +1,3994
1 1 import numpy
2 2 import math
3 3 from scipy import optimize, interpolate, signal, stats, ndimage
4 4 import scipy
5 5 import re
6 6 import datetime
7 7 import copy
8 8 import sys
9 9 import importlib
10 10 import itertools
11 11 from multiprocessing import Pool, TimeoutError
12 12 from multiprocessing.pool import ThreadPool
13 13 import copy_reg
14 14 import cPickle
15 15 import types
16 16 from functools import partial
17 17 import time
18 18 #from sklearn.cluster import KMeans
19 19
20 20 import matplotlib.pyplot as plt
21 21
22 22 from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters
23 23 from jroproc_base import ProcessingUnit, Operation
24 24 from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon
25 25 from scipy import asarray as ar,exp
26 26 from scipy.optimize import curve_fit
27 27
28 28 import warnings
29 29 from numpy import NaN
30 from scipy.optimize.optimize import OptimizeWarning
30 31 warnings.filterwarnings('ignore')
31 32
33
32 34 SPEED_OF_LIGHT = 299792458
33 35
34 36
35 37 '''solving pickling issue'''
36 38
37 39 def _pickle_method(method):
38 40 func_name = method.im_func.__name__
39 41 obj = method.im_self
40 42 cls = method.im_class
41 43 return _unpickle_method, (func_name, obj, cls)
42 44
43 45 def _unpickle_method(func_name, obj, cls):
44 46 for cls in cls.mro():
45 47 try:
46 48 func = cls.__dict__[func_name]
47 49 except KeyError:
48 50 pass
49 51 else:
50 52 break
51 53 return func.__get__(obj, cls)
52 54
53 55
54 56
55 57
56 58
57 59
58 60
59 61
60 62 class ParametersProc(ProcessingUnit):
61 63
62 64 nSeconds = None
63 65
64 66 def __init__(self):
65 67 ProcessingUnit.__init__(self)
66 68
67 69 # self.objectDict = {}
68 70 self.buffer = None
69 71 self.firstdatatime = None
70 72 self.profIndex = 0
71 73 self.dataOut = Parameters()
72 74
73 75 def __updateObjFromInput(self):
74 76
75 77 self.dataOut.inputUnit = self.dataIn.type
76 78
77 79 self.dataOut.timeZone = self.dataIn.timeZone
78 80 self.dataOut.dstFlag = self.dataIn.dstFlag
79 81 self.dataOut.errorCount = self.dataIn.errorCount
80 82 self.dataOut.useLocalTime = self.dataIn.useLocalTime
81 83
82 84 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
83 85 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
84 86 self.dataOut.channelList = self.dataIn.channelList
85 87 self.dataOut.heightList = self.dataIn.heightList
86 88 self.dataOut.dtype = numpy.dtype([('real','<f4'),('imag','<f4')])
87 89 # self.dataOut.nHeights = self.dataIn.nHeights
88 90 # self.dataOut.nChannels = self.dataIn.nChannels
89 91 self.dataOut.nBaud = self.dataIn.nBaud
90 92 self.dataOut.nCode = self.dataIn.nCode
91 93 self.dataOut.code = self.dataIn.code
92 94 # self.dataOut.nProfiles = self.dataOut.nFFTPoints
93 95 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
94 96 # self.dataOut.utctime = self.firstdatatime
95 97 self.dataOut.utctime = self.dataIn.utctime
96 98 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData #asumo q la data esta decodificada
97 99 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData #asumo q la data esta sin flip
98 100 self.dataOut.nCohInt = self.dataIn.nCohInt
99 101 # self.dataOut.nIncohInt = 1
100 102 self.dataOut.ippSeconds = self.dataIn.ippSeconds
101 103 # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
102 104 self.dataOut.timeInterval1 = self.dataIn.timeInterval
103 105 self.dataOut.heightList = self.dataIn.getHeiRange()
104 106 self.dataOut.frequency = self.dataIn.frequency
105 107 self.dataOut.noise = self.dataIn.noise
106 108
107 109
108 110
109 111 def run(self):
110 112
111 113 #---------------------- Voltage Data ---------------------------
112 114
113 115 if self.dataIn.type == "Voltage":
114 116
115 117 self.__updateObjFromInput()
116 118 self.dataOut.data_pre = self.dataIn.data.copy()
117 119 self.dataOut.flagNoData = False
118 120 self.dataOut.utctimeInit = self.dataIn.utctime
119 121 self.dataOut.paramInterval = self.dataIn.nProfiles*self.dataIn.nCohInt*self.dataIn.ippSeconds
120 122 return
121 123
122 124 #---------------------- Spectra Data ---------------------------
123 125
124 126 if self.dataIn.type == "Spectra":
125 127
126 128 self.dataOut.data_pre = (self.dataIn.data_spc,self.dataIn.data_cspc)
127 129 print 'self.dataIn.data_spc', self.dataIn.data_spc.shape
128 130 self.dataOut.abscissaList = self.dataIn.getVelRange(1)
129 131 self.dataOut.spc_noise = self.dataIn.getNoise()
130 132 self.dataOut.spc_range = (self.dataIn.getFreqRange(1)/1000. , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1) )
131 133
132 134 self.dataOut.normFactor = self.dataIn.normFactor
133 135 #self.dataOut.outputInterval = self.dataIn.outputInterval
134 136 self.dataOut.groupList = self.dataIn.pairsList
135 137 self.dataOut.flagNoData = False
136 138 #print 'datain chandist ',self.dataIn.ChanDist
137 139 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
138 140 self.dataOut.ChanDist = self.dataIn.ChanDist
139 141 else: self.dataOut.ChanDist = None
140 142
141 143 print 'datain chandist ',self.dataOut.ChanDist
142 144
143 145 if hasattr(self.dataIn, 'VelRange'): #Velocities range
144 146 self.dataOut.VelRange = self.dataIn.VelRange
145 147 else: self.dataOut.VelRange = None
146 148
147 149 if hasattr(self.dataIn, 'RadarConst'): #Radar Constant
148 150 self.dataOut.RadarConst = self.dataIn.RadarConst
149 151
150 152 if hasattr(self.dataIn, 'NPW'): #NPW
151 153 self.dataOut.NPW = self.dataIn.NPW
152 154
153 155 if hasattr(self.dataIn, 'COFA'): #COFA
154 156 self.dataOut.COFA = self.dataIn.COFA
155 157
156 158
157 159
158 160 #---------------------- Correlation Data ---------------------------
159 161
160 162 if self.dataIn.type == "Correlation":
161 163 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.dataIn.splitFunctions()
162 164
163 165 self.dataOut.data_pre = (self.dataIn.data_cf[acf_ind,:], self.dataIn.data_cf[ccf_ind,:,:])
164 166 self.dataOut.normFactor = (self.dataIn.normFactor[acf_ind,:], self.dataIn.normFactor[ccf_ind,:])
165 167 self.dataOut.groupList = (acf_pairs, ccf_pairs)
166 168
167 169 self.dataOut.abscissaList = self.dataIn.lagRange
168 170 self.dataOut.noise = self.dataIn.noise
169 171 self.dataOut.data_SNR = self.dataIn.SNR
170 172 self.dataOut.flagNoData = False
171 173 self.dataOut.nAvg = self.dataIn.nAvg
172 174
173 175 #---------------------- Parameters Data ---------------------------
174 176
175 177 if self.dataIn.type == "Parameters":
176 178 self.dataOut.copy(self.dataIn)
177 179 self.dataOut.flagNoData = False
178 180
179 181 return True
180 182
181 183 self.__updateObjFromInput()
182 184 self.dataOut.utctimeInit = self.dataIn.utctime
183 185 self.dataOut.paramInterval = self.dataIn.timeInterval
184 186
185 187 return
186 188
187 189
188 190 def target(tups):
189 191
190 192 obj, args = tups
191 193 #print 'TARGETTT', obj, args
192 194 return obj.FitGau(args)
193 195
194 196 class GaussianFit(Operation):
195 197
196 198 '''
197 199 Function that fit of one and two generalized gaussians (gg) based
198 200 on the PSD shape across an "power band" identified from a cumsum of
199 201 the measured spectrum - noise.
200 202
201 203 Input:
202 204 self.dataOut.data_pre : SelfSpectra
203 205
204 206 Output:
205 207 self.dataOut.GauSPC : SPC_ch1, SPC_ch2
206 208
207 209 '''
208 210 def __init__(self, **kwargs):
209 211 Operation.__init__(self, **kwargs)
210 212 self.i=0
211 213
212 214
213 215 def run(self, dataOut, num_intg=7, pnoise=1., vel_arr=None, SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points
214 216 """This routine will find a couple of generalized Gaussians to a power spectrum
215 217 input: spc
216 218 output:
217 219 Amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1,noise
218 220 """
219 221
220 222 self.spc = dataOut.data_pre[0].copy()
221 223
222 224
223 225 print 'SelfSpectra Shape', numpy.asarray(self.spc).shape
224 226
225 227
226 228 #plt.figure(50)
227 229 #plt.subplot(121)
228 230 #plt.plot(self.spc,'k',label='spc(66)')
229 231 #plt.plot(xFrec,ySamples[1],'g',label='Ch1')
230 232 #plt.plot(xFrec,ySamples[2],'r',label='Ch2')
231 233 #plt.plot(xFrec,FitGauss,'yo:',label='fit')
232 234 #plt.legend()
233 235 #plt.title('DATOS A ALTURA DE 7500 METROS')
234 236 #plt.show()
235 237
236 238 self.Num_Hei = self.spc.shape[2]
237 239 #self.Num_Bin = len(self.spc)
238 240 self.Num_Bin = self.spc.shape[1]
239 241 self.Num_Chn = self.spc.shape[0]
240 242
241 243 Vrange = dataOut.abscissaList
242 244
243 245 #print 'self.spc2', numpy.asarray(self.spc).shape
244 246
245 247 GauSPC = numpy.empty([2,self.Num_Bin,self.Num_Hei])
246 248 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
247 249 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
248 250 SPC_ch1[:] = numpy.NaN
249 251 SPC_ch2[:] = numpy.NaN
250 252
251 253
252 254 start_time = time.time()
253 255
254 256 noise_ = dataOut.spc_noise[0].copy()
255 257
256 258
257 259
258 260 pool = Pool(processes=self.Num_Chn)
259 261 args = [(Vrange, Ch, pnoise, noise_, num_intg, SNRlimit) for Ch in range(self.Num_Chn)]
260 262 objs = [self for __ in range(self.Num_Chn)]
261 263 attrs = zip(objs, args)
262 264 gauSPC = pool.map(target, attrs)
263 265 dataOut.GauSPC = numpy.asarray(gauSPC)
264 266 # ret = []
265 267 # for n in range(self.Num_Chn):
266 268 # self.FitGau(args[n])
267 269 # dataOut.GauSPC = ret
268 270
269 271
270 272
271 273 # for ch in range(self.Num_Chn):
272 274 #
273 275 # for ht in range(self.Num_Hei):
274 276 # #print (numpy.asarray(self.spc).shape)
275 277 # spc = numpy.asarray(self.spc)[ch,:,ht]
276 278 #
277 279 # #############################################
278 280 # # normalizing spc and noise
279 281 # # This part differs from gg1
280 282 # spc_norm_max = max(spc)
281 283 # spc = spc / spc_norm_max
282 284 # pnoise = pnoise / spc_norm_max
283 285 # #############################################
284 286 #
285 287 # if abs(vel_arr[0])<15.0: # this switch is for spectra collected with different length IPP's
286 288 # fatspectra=1.0
287 289 # else:
288 290 # fatspectra=0.5
289 291 #
290 292 # wnoise = noise_ / spc_norm_max
291 293 # #print 'wnoise', noise_, dataOut.spc_noise[0], wnoise
292 294 # #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
293 295 # #if wnoise>1.1*pnoise: # to be tested later
294 296 # # wnoise=pnoise
295 297 # noisebl=wnoise*0.9; noisebh=wnoise*1.1
296 298 # spc=spc-wnoise
297 299 #
298 300 # minx=numpy.argmin(spc)
299 301 # spcs=numpy.roll(spc,-minx)
300 302 # cum=numpy.cumsum(spcs)
301 303 # tot_noise=wnoise * self.Num_Bin #64;
302 304 # #tot_signal=sum(cum[-5:])/5.; ''' How does this line work? '''
303 305 # #snr=tot_signal/tot_noise
304 306 # #snr=cum[-1]/tot_noise
305 307 #
306 308 # #print 'spc' , spcs[5:8] , 'tot_noise', tot_noise
307 309 #
308 310 # snr = sum(spcs)/tot_noise
309 311 # snrdB=10.*numpy.log10(snr)
310 312 #
311 313 # #if snrdB < -9 :
312 314 # # snrdB = numpy.NaN
313 315 # # continue
314 316 #
315 317 # #print 'snr',snrdB # , sum(spcs) , tot_noise
316 318 #
317 319 #
318 320 # #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
319 321 # # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
320 322 #
321 323 # cummax=max(cum); epsi=0.08*fatspectra # cumsum to narrow down the energy region
322 324 # cumlo=cummax*epsi;
323 325 # cumhi=cummax*(1-epsi)
324 326 # powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
325 327 #
326 328 # #if len(powerindex)==1:
327 329 # ##return [numpy.mod(powerindex[0]+minx,64),None,None,None,],[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
328 330 # #return [numpy.mod(powerindex[0]+minx, self.Num_Bin ),None,None,None,],[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
329 331 # #elif len(powerindex)<4*fatspectra:
330 332 # #return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
331 333 #
332 334 # if len(powerindex) < 1:# case for powerindex 0
333 335 # continue
334 336 # powerlo=powerindex[0]
335 337 # powerhi=powerindex[-1]
336 338 # powerwidth=powerhi-powerlo
337 339 #
338 340 # firstpeak=powerlo+powerwidth/10.# first gaussian energy location
339 341 # secondpeak=powerhi-powerwidth/10.#second gaussian energy location
340 342 # midpeak=(firstpeak+secondpeak)/2.
341 343 # firstamp=spcs[int(firstpeak)]
342 344 # secondamp=spcs[int(secondpeak)]
343 345 # midamp=spcs[int(midpeak)]
344 346 # #x=numpy.spc.shape[1]
345 347 #
346 348 # #x=numpy.arange(64)
347 349 # x=numpy.arange( self.Num_Bin )
348 350 # y_data=spc+wnoise
349 351 #
350 352 # # single gaussian
351 353 # #shift0=numpy.mod(midpeak+minx,64)
352 354 # shift0=numpy.mod(midpeak+minx, self.Num_Bin )
353 355 # width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
354 356 # power0=2.
355 357 # amplitude0=midamp
356 358 # state0=[shift0,width0,amplitude0,power0,wnoise]
357 359 # #bnds=((0,63),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
358 360 # bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
359 361 # #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(0.1,0.5))
360 362 # # bnds = range of fft, power width, amplitude, power, noise
361 363 # lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
362 364 #
363 365 # chiSq1=lsq1[1];
364 366 # jack1= self.y_jacobian1(x,lsq1[0])
365 367 #
366 368 #
367 369 # try:
368 370 # sigmas1=numpy.sqrt(chiSq1*numpy.diag(numpy.linalg.inv(numpy.dot(jack1.T,jack1))))
369 371 # except:
370 372 # std1=32.; sigmas1=numpy.ones(5)
371 373 # else:
372 374 # std1=sigmas1[0]
373 375 #
374 376 #
375 377 # if fatspectra<1.0 and powerwidth<4:
376 378 # choice=0
377 379 # Amplitude0=lsq1[0][2]
378 380 # shift0=lsq1[0][0]
379 381 # width0=lsq1[0][1]
380 382 # p0=lsq1[0][3]
381 383 # Amplitude1=0.
382 384 # shift1=0.
383 385 # width1=0.
384 386 # p1=0.
385 387 # noise=lsq1[0][4]
386 388 # #return (numpy.array([shift0,width0,Amplitude0,p0]),
387 389 # # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
388 390 #
389 391 # # two gaussians
390 392 # #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
391 393 # shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
392 394 # shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
393 395 # width0=powerwidth/6.;
394 396 # width1=width0
395 397 # power0=2.;
396 398 # power1=power0
397 399 # amplitude0=firstamp;
398 400 # amplitude1=secondamp
399 401 # state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
400 402 # #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
401 403 # bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
402 404 # #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(0.1,0.5))
403 405 #
404 406 # lsq2=fmin_l_bfgs_b(self.misfit2,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
405 407 #
406 408 #
407 409 # chiSq2=lsq2[1]; jack2=self.y_jacobian2(x,lsq2[0])
408 410 #
409 411 #
410 412 # try:
411 413 # sigmas2=numpy.sqrt(chiSq2*numpy.diag(numpy.linalg.inv(numpy.dot(jack2.T,jack2))))
412 414 # except:
413 415 # std2a=32.; std2b=32.; sigmas2=numpy.ones(9)
414 416 # else:
415 417 # std2a=sigmas2[0]; std2b=sigmas2[4]
416 418 #
417 419 #
418 420 #
419 421 # oneG=(chiSq1<5 and chiSq1/chiSq2<2.0) and (abs(lsq2[0][0]-lsq2[0][4])<(lsq2[0][1]+lsq2[0][5])/3. or abs(lsq2[0][0]-lsq2[0][4])<10)
420 422 #
421 423 # if snrdB>-9: # when SNR is strong pick the peak with least shift (LOS velocity) error
422 424 # if oneG:
423 425 # choice=0
424 426 # else:
425 427 # w1=lsq2[0][1]; w2=lsq2[0][5]
426 428 # a1=lsq2[0][2]; a2=lsq2[0][6]
427 429 # p1=lsq2[0][3]; p2=lsq2[0][7]
428 430 # s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1; s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
429 431 # gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
430 432 #
431 433 # if gp1>gp2:
432 434 # if a1>0.7*a2:
433 435 # choice=1
434 436 # else:
435 437 # choice=2
436 438 # elif gp2>gp1:
437 439 # if a2>0.7*a1:
438 440 # choice=2
439 441 # else:
440 442 # choice=1
441 443 # else:
442 444 # choice=numpy.argmax([a1,a2])+1
443 445 # #else:
444 446 # #choice=argmin([std2a,std2b])+1
445 447 #
446 448 # else: # with low SNR go to the most energetic peak
447 449 # choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
448 450 #
449 451 # #print 'choice',choice
450 452 #
451 453 # if choice==0: # pick the single gaussian fit
452 454 # Amplitude0=lsq1[0][2]
453 455 # shift0=lsq1[0][0]
454 456 # width0=lsq1[0][1]
455 457 # p0=lsq1[0][3]
456 458 # Amplitude1=0.
457 459 # shift1=0.
458 460 # width1=0.
459 461 # p1=0.
460 462 # noise=lsq1[0][4]
461 463 # elif choice==1: # take the first one of the 2 gaussians fitted
462 464 # Amplitude0 = lsq2[0][2]
463 465 # shift0 = lsq2[0][0]
464 466 # width0 = lsq2[0][1]
465 467 # p0 = lsq2[0][3]
466 468 # Amplitude1 = lsq2[0][6] # This is 0 in gg1
467 469 # shift1 = lsq2[0][4] # This is 0 in gg1
468 470 # width1 = lsq2[0][5] # This is 0 in gg1
469 471 # p1 = lsq2[0][7] # This is 0 in gg1
470 472 # noise = lsq2[0][8]
471 473 # else: # the second one
472 474 # Amplitude0 = lsq2[0][6]
473 475 # shift0 = lsq2[0][4]
474 476 # width0 = lsq2[0][5]
475 477 # p0 = lsq2[0][7]
476 478 # Amplitude1 = lsq2[0][2] # This is 0 in gg1
477 479 # shift1 = lsq2[0][0] # This is 0 in gg1
478 480 # width1 = lsq2[0][1] # This is 0 in gg1
479 481 # p1 = lsq2[0][3] # This is 0 in gg1
480 482 # noise = lsq2[0][8]
481 483 #
482 484 # #print len(noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0)
483 485 # SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
484 486 # SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
485 487 # #print 'SPC_ch1.shape',SPC_ch1.shape
486 488 # #print 'SPC_ch2.shape',SPC_ch2.shape
487 489 # #dataOut.data_param = SPC_ch1
488 490 # GauSPC[0] = SPC_ch1
489 491 # GauSPC[1] = SPC_ch2
490 492
491 493 # #plt.gcf().clear()
492 494 # plt.figure(50+self.i)
493 495 # self.i=self.i+1
494 496 # #plt.subplot(121)
495 497 # plt.plot(self.spc,'k')#,label='spc(66)')
496 498 # plt.plot(SPC_ch1[ch,ht],'b')#,label='gg1')
497 499 # #plt.plot(SPC_ch2,'r')#,label='gg2')
498 500 # #plt.plot(xFrec,ySamples[1],'g',label='Ch1')
499 501 # #plt.plot(xFrec,ySamples[2],'r',label='Ch2')
500 502 # #plt.plot(xFrec,FitGauss,'yo:',label='fit')
501 503 # plt.legend()
502 504 # plt.title('DATOS A ALTURA DE 7500 METROS')
503 505 # plt.show()
504 506 # print 'shift0', shift0
505 507 # print 'Amplitude0', Amplitude0
506 508 # print 'width0', width0
507 509 # print 'p0', p0
508 510 # print '========================'
509 511 # print 'shift1', shift1
510 512 # print 'Amplitude1', Amplitude1
511 513 # print 'width1', width1
512 514 # print 'p1', p1
513 515 # print 'noise', noise
514 516 # print 's_noise', wnoise
515 517
516 518 print '========================================================'
517 519 print 'total_time: ', time.time()-start_time
518 520
519 521 # re-normalizing spc and noise
520 522 # This part differs from gg1
521 523
522 524
523 525
524 526 ''' Parameters:
525 527 1. Amplitude
526 528 2. Shift
527 529 3. Width
528 530 4. Power
529 531 '''
530 532
531 533
532 534 ###############################################################################
533 535 def FitGau(self, X):
534 536
535 537 Vrange, ch, pnoise, noise_, num_intg, SNRlimit = X
536 538 #print 'VARSSSS', ch, pnoise, noise, num_intg
537 539
538 540 #print 'HEIGHTS', self.Num_Hei
539 541
540 542 GauSPC = []
541 543 SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei])
542 544 SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei])
543 545 SPC_ch1[:] = 0#numpy.NaN
544 546 SPC_ch2[:] = 0#numpy.NaN
545 547
546 548
547 549
548 550 for ht in range(self.Num_Hei):
549 551 #print (numpy.asarray(self.spc).shape)
550 552
551 553 #print 'TTTTT', ch , ht
552 554 #print self.spc.shape
553 555
554 556
555 557 spc = numpy.asarray(self.spc)[ch,:,ht]
556 558
557 559 #############################################
558 560 # normalizing spc and noise
559 561 # This part differs from gg1
560 562 spc_norm_max = max(spc)
561 563 spc = spc / spc_norm_max
562 564 pnoise = pnoise / spc_norm_max
563 565 #############################################
564 566
565 567 fatspectra=1.0
566 568
567 569 wnoise = noise_ / spc_norm_max
568 570 #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used
569 571 #if wnoise>1.1*pnoise: # to be tested later
570 572 # wnoise=pnoise
571 573 noisebl=wnoise*0.9; noisebh=wnoise*1.1
572 574 spc=spc-wnoise
573 575 # print 'wnoise', noise_[0], spc_norm_max, wnoise
574 576 minx=numpy.argmin(spc)
575 577 spcs=numpy.roll(spc,-minx)
576 578 cum=numpy.cumsum(spcs)
577 579 tot_noise=wnoise * self.Num_Bin #64;
578 580 #print 'spc' , spcs[5:8] , 'tot_noise', tot_noise
579 581 #tot_signal=sum(cum[-5:])/5.; ''' How does this line work? '''
580 582 #snr=tot_signal/tot_noise
581 583 #snr=cum[-1]/tot_noise
582 584 snr = sum(spcs)/tot_noise
583 585 snrdB=10.*numpy.log10(snr)
584 586
585 587 if snrdB < SNRlimit :
586 588 snr = numpy.NaN
587 589 SPC_ch1[:,ht] = 0#numpy.NaN
588 590 SPC_ch1[:,ht] = 0#numpy.NaN
589 591 GauSPC = (SPC_ch1,SPC_ch2)
590 592 continue
591 593 #print 'snr',snrdB #, sum(spcs) , tot_noise
592 594
593 595
594 596
595 597 #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4:
596 598 # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None
597 599
598 600 cummax=max(cum); epsi=0.08*fatspectra # cumsum to narrow down the energy region
599 601 cumlo=cummax*epsi;
600 602 cumhi=cummax*(1-epsi)
601 603 powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum<cumhi))[0])
602 604
603 605
604 606 if len(powerindex) < 1:# case for powerindex 0
605 607 continue
606 608 powerlo=powerindex[0]
607 609 powerhi=powerindex[-1]
608 610 powerwidth=powerhi-powerlo
609 611
610 612 firstpeak=powerlo+powerwidth/10.# first gaussian energy location
611 613 secondpeak=powerhi-powerwidth/10.#second gaussian energy location
612 614 midpeak=(firstpeak+secondpeak)/2.
613 615 firstamp=spcs[int(firstpeak)]
614 616 secondamp=spcs[int(secondpeak)]
615 617 midamp=spcs[int(midpeak)]
616 618
617 619 x=numpy.arange( self.Num_Bin )
618 620 y_data=spc+wnoise
619 621
620 622 # single gaussian
621 623 shift0=numpy.mod(midpeak+minx, self.Num_Bin )
622 624 width0=powerwidth/4.#Initialization entire power of spectrum divided by 4
623 625 power0=2.
624 626 amplitude0=midamp
625 627 state0=[shift0,width0,amplitude0,power0,wnoise]
626 628 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth),(0,None),(0.5,3.),(noisebl,noisebh))
627 629 lsq1=fmin_l_bfgs_b(self.misfit1,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
628 630
629 631 chiSq1=lsq1[1];
630 632 jack1= self.y_jacobian1(x,lsq1[0])
631 633
632 634
633 635 try:
634 636 sigmas1=numpy.sqrt(chiSq1*numpy.diag(numpy.linalg.inv(numpy.dot(jack1.T,jack1))))
635 637 except:
636 638 std1=32.; sigmas1=numpy.ones(5)
637 639 else:
638 640 std1=sigmas1[0]
639 641
640 642
641 643 if fatspectra<1.0 and powerwidth<4:
642 644 choice=0
643 645 Amplitude0=lsq1[0][2]
644 646 shift0=lsq1[0][0]
645 647 width0=lsq1[0][1]
646 648 p0=lsq1[0][3]
647 649 Amplitude1=0.
648 650 shift1=0.
649 651 width1=0.
650 652 p1=0.
651 653 noise=lsq1[0][4]
652 654 #return (numpy.array([shift0,width0,Amplitude0,p0]),
653 655 # numpy.array([shift1,width1,Amplitude1,p1]),noise,snrdB,chiSq1,6.,sigmas1,[None,]*9,choice)
654 656
655 657 # two gaussians
656 658 #shift0=numpy.mod(firstpeak+minx,64); shift1=numpy.mod(secondpeak+minx,64)
657 659 shift0=numpy.mod(firstpeak+minx, self.Num_Bin );
658 660 shift1=numpy.mod(secondpeak+minx, self.Num_Bin )
659 661 width0=powerwidth/6.;
660 662 width1=width0
661 663 power0=2.;
662 664 power1=power0
663 665 amplitude0=firstamp;
664 666 amplitude1=secondamp
665 667 state0=[shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,wnoise]
666 668 #bnds=((0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(0,63),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
667 669 bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(noisebl,noisebh))
668 670 #bnds=(( 0,(self.Num_Bin-1) ),(1,powerwidth/2.),(0,None),(0.5,3.),( 0,(self.Num_Bin-1)),(1,powerwidth/2.),(0,None),(0.5,3.),(0.1,0.5))
669 671
670 672 lsq2=fmin_l_bfgs_b(self.misfit2,state0,args=(y_data,x,num_intg),bounds=bnds,approx_grad=True)
671 673
672 674
673 675 chiSq2=lsq2[1]; jack2=self.y_jacobian2(x,lsq2[0])
674 676
675 677
676 678 try:
677 679 sigmas2=numpy.sqrt(chiSq2*numpy.diag(numpy.linalg.inv(numpy.dot(jack2.T,jack2))))
678 680 except:
679 681 std2a=32.; std2b=32.; sigmas2=numpy.ones(9)
680 682 else:
681 683 std2a=sigmas2[0]; std2b=sigmas2[4]
682 684
683 685
684 686
685 687 oneG=(chiSq1<5 and chiSq1/chiSq2<2.0) and (abs(lsq2[0][0]-lsq2[0][4])<(lsq2[0][1]+lsq2[0][5])/3. or abs(lsq2[0][0]-lsq2[0][4])<10)
686 688
687 689 if snrdB>-6: # when SNR is strong pick the peak with least shift (LOS velocity) error
688 690 if oneG:
689 691 choice=0
690 692 else:
691 693 w1=lsq2[0][1]; w2=lsq2[0][5]
692 694 a1=lsq2[0][2]; a2=lsq2[0][6]
693 695 p1=lsq2[0][3]; p2=lsq2[0][7]
694 696 s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1;
695 697 s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2;
696 698 gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling
697 699
698 700 if gp1>gp2:
699 701 if a1>0.7*a2:
700 702 choice=1
701 703 else:
702 704 choice=2
703 705 elif gp2>gp1:
704 706 if a2>0.7*a1:
705 707 choice=2
706 708 else:
707 709 choice=1
708 710 else:
709 711 choice=numpy.argmax([a1,a2])+1
710 712 #else:
711 713 #choice=argmin([std2a,std2b])+1
712 714
713 715 else: # with low SNR go to the most energetic peak
714 716 choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]])
715 717
716 718
717 719 shift0=lsq2[0][0]; vel0=Vrange[0] + shift0*(Vrange[1]-Vrange[0])
718 720 shift1=lsq2[0][4]; vel1=Vrange[0] + shift1*(Vrange[1]-Vrange[0])
719 721
720 722 max_vel = 20
721 723
722 724 #first peak will be 0, second peak will be 1
723 725 if vel0 > 0 and vel0 < max_vel : #first peak is in the correct range
724 726 shift0=lsq2[0][0]
725 727 width0=lsq2[0][1]
726 728 Amplitude0=lsq2[0][2]
727 729 p0=lsq2[0][3]
728 730
729 731 shift1=lsq2[0][4]
730 732 width1=lsq2[0][5]
731 733 Amplitude1=lsq2[0][6]
732 734 p1=lsq2[0][7]
733 735 noise=lsq2[0][8]
734 736 else:
735 737 shift1=lsq2[0][0]
736 738 width1=lsq2[0][1]
737 739 Amplitude1=lsq2[0][2]
738 740 p1=lsq2[0][3]
739 741
740 742 shift0=lsq2[0][4]
741 743 width0=lsq2[0][5]
742 744 Amplitude0=lsq2[0][6]
743 745 p0=lsq2[0][7]
744 746 noise=lsq2[0][8]
745 747
746 748 if Amplitude0<0.1: # in case the peak is noise
747 749 shift0,width0,Amplitude0,p0 = 4*[numpy.NaN]
748 750 if Amplitude1<0.1:
749 751 shift1,width1,Amplitude1,p1 = 4*[numpy.NaN]
750 752
751 753
752 754 # if choice==0: # pick the single gaussian fit
753 755 # Amplitude0=lsq1[0][2]
754 756 # shift0=lsq1[0][0]
755 757 # width0=lsq1[0][1]
756 758 # p0=lsq1[0][3]
757 759 # Amplitude1=0.
758 760 # shift1=0.
759 761 # width1=0.
760 762 # p1=0.
761 763 # noise=lsq1[0][4]
762 764 # elif choice==1: # take the first one of the 2 gaussians fitted
763 765 # Amplitude0 = lsq2[0][2]
764 766 # shift0 = lsq2[0][0]
765 767 # width0 = lsq2[0][1]
766 768 # p0 = lsq2[0][3]
767 769 # Amplitude1 = lsq2[0][6] # This is 0 in gg1
768 770 # shift1 = lsq2[0][4] # This is 0 in gg1
769 771 # width1 = lsq2[0][5] # This is 0 in gg1
770 772 # p1 = lsq2[0][7] # This is 0 in gg1
771 773 # noise = lsq2[0][8]
772 774 # else: # the second one
773 775 # Amplitude0 = lsq2[0][6]
774 776 # shift0 = lsq2[0][4]
775 777 # width0 = lsq2[0][5]
776 778 # p0 = lsq2[0][7]
777 779 # Amplitude1 = lsq2[0][2] # This is 0 in gg1
778 780 # shift1 = lsq2[0][0] # This is 0 in gg1
779 781 # width1 = lsq2[0][1] # This is 0 in gg1
780 782 # p1 = lsq2[0][3] # This is 0 in gg1
781 783 # noise = lsq2[0][8]
782 784
783 785 #print len(noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0)
784 786 SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0
785 787 SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1
786 788 #print 'SPC_ch1.shape',SPC_ch1.shape
787 789 #print 'SPC_ch2.shape',SPC_ch2.shape
788 790 #dataOut.data_param = SPC_ch1
789 791 GauSPC = (SPC_ch1,SPC_ch2)
790 792 #GauSPC[1] = SPC_ch2
791 793
792 794 # print 'shift0', shift0
793 795 # print 'Amplitude0', Amplitude0
794 796 # print 'width0', width0
795 797 # print 'p0', p0
796 798 # print '========================'
797 799 # print 'shift1', shift1
798 800 # print 'Amplitude1', Amplitude1
799 801 # print 'width1', width1
800 802 # print 'p1', p1
801 803 # print 'noise', noise
802 804 # print 's_noise', wnoise
803 805
804 806 return GauSPC
805 807
806 808
807 809 def y_jacobian1(self,x,state): # This function is for further analysis of generalized Gaussians, it is not too importan for the signal discrimination.
808 810 y_model=self.y_model1(x,state)
809 811 s0,w0,a0,p0,n=state
810 812 e0=((x-s0)/w0)**2;
811 813
812 814 e0u=((x-s0-self.Num_Bin)/w0)**2;
813 815
814 816 e0d=((x-s0+self.Num_Bin)/w0)**2
815 817 m0=numpy.exp(-0.5*e0**(p0/2.));
816 818 m0u=numpy.exp(-0.5*e0u**(p0/2.));
817 819 m0d=numpy.exp(-0.5*e0d**(p0/2.))
818 820 JA=m0+m0u+m0d
819 821 JP=(-1/4.)*a0*m0*e0**(p0/2.)*numpy.log(e0)+(-1/4.)*a0*m0u*e0u**(p0/2.)*numpy.log(e0u)+(-1/4.)*a0*m0d*e0d**(p0/2.)*numpy.log(e0d)
820 822
821 823 JS=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)
822 824
823 825 JW=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)**2+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)**2+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)**2
824 826 jack1=numpy.sqrt(7)*numpy.array([JS/y_model,JW/y_model,JA/y_model,JP/y_model,1./y_model])
825 827 return jack1.T
826 828
827 829 def y_jacobian2(self,x,state):
828 830 y_model=self.y_model2(x,state)
829 831 s0,w0,a0,p0,s1,w1,a1,p1,n=state
830 832 e0=((x-s0)/w0)**2;
831 833
832 834 e0u=((x-s0- self.Num_Bin )/w0)**2;
833 835
834 836 e0d=((x-s0+ self.Num_Bin )/w0)**2
835 837 e1=((x-s1)/w1)**2;
836 838
837 839 e1u=((x-s1- self.Num_Bin )/w1)**2;
838 840
839 841 e1d=((x-s1+ self.Num_Bin )/w1)**2
840 842 m0=numpy.exp(-0.5*e0**(p0/2.));
841 843 m0u=numpy.exp(-0.5*e0u**(p0/2.));
842 844 m0d=numpy.exp(-0.5*e0d**(p0/2.))
843 845 m1=numpy.exp(-0.5*e1**(p1/2.));
844 846 m1u=numpy.exp(-0.5*e1u**(p1/2.));
845 847 m1d=numpy.exp(-0.5*e1d**(p1/2.))
846 848 JA=m0+m0u+m0d
847 849 JA1=m1+m1u+m1d
848 850 JP=(-1/4.)*a0*m0*e0**(p0/2.)*numpy.log(e0)+(-1/4.)*a0*m0u*e0u**(p0/2.)*numpy.log(e0u)+(-1/4.)*a0*m0d*e0d**(p0/2.)*numpy.log(e0d)
849 851 JP1=(-1/4.)*a1*m1*e1**(p1/2.)*numpy.log(e1)+(-1/4.)*a1*m1u*e1u**(p1/2.)*numpy.log(e1u)+(-1/4.)*a1*m1d*e1d**(p1/2.)*numpy.log(e1d)
850 852
851 853 JS=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)
852 854
853 855 JS1=(p1/w1/2.)*a1*m1*e1**(p1/2.-1)*((x-s1)/w1)+(p1/w1/2.)*a1*m1u*e1u**(p1/2.-1)*((x-s1- self.Num_Bin )/w1)+(p1/w1/2.)*a1*m1d*e1d**(p1/2.-1)*((x-s1+ self.Num_Bin )/w1)
854 856
855 857 JW=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)**2+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)**2+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)**2
856 858
857 859 JW1=(p1/w1/2.)*a1*m1*e1**(p1/2.-1)*((x-s1)/w1)**2+(p1/w1/2.)*a1*m1u*e1u**(p1/2.-1)*((x-s1- self.Num_Bin )/w1)**2+(p1/w1/2.)*a1*m1d*e1d**(p1/2.-1)*((x-s1+ self.Num_Bin )/w1)**2
858 860 jack2=numpy.sqrt(7)*numpy.array([JS/y_model,JW/y_model,JA/y_model,JP/y_model,JS1/y_model,JW1/y_model,JA1/y_model,JP1/y_model,1./y_model])
859 861 return jack2.T
860 862
861 863 def y_model1(self,x,state):
862 864 shift0,width0,amplitude0,power0,noise=state
863 865 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
864 866
865 867 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
866 868
867 869 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
868 870 return model0+model0u+model0d+noise
869 871
870 872 def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist
871 873 shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,noise=state
872 874 model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0)
873 875
874 876 model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0)
875 877
876 878 model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0)
877 879 model1=amplitude1*numpy.exp(-0.5*abs((x-shift1)/width1)**power1)
878 880
879 881 model1u=amplitude1*numpy.exp(-0.5*abs((x-shift1- self.Num_Bin )/width1)**power1)
880 882
881 883 model1d=amplitude1*numpy.exp(-0.5*abs((x-shift1+ self.Num_Bin )/width1)**power1)
882 884 return model0+model0u+model0d+model1+model1u+model1d+noise
883 885
884 886 def misfit1(self,state,y_data,x,num_intg): # This function compares how close real data is with the model data, the close it is, the better it is.
885 887
886 888 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented
887 889
888 890 def misfit2(self,state,y_data,x,num_intg):
889 891 return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.)
890 892
891 893
892 894 class PrecipitationProc(Operation):
893 895
894 896 '''
895 897 Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R)
896 898
897 899 Input:
898 900 self.dataOut.data_pre : SelfSpectra
899 901
900 902 Output:
901 903
902 904 self.dataOut.data_output : Reflectivity factor, rainfall Rate
903 905
904 906
905 907 Parameters affected:
906 908 '''
907 909
908 910
909 911 def run(self, dataOut, radar=None, Pt=None, Gt=None, Gr=None, Lambda=None, aL=None,
910 912 tauW=None, ThetaT=None, ThetaR=None, Km = 0.93, Altitude=None):
911 913
912 914 self.spc = dataOut.data_pre[0].copy()
913 915 self.Num_Hei = self.spc.shape[2]
914 916 self.Num_Bin = self.spc.shape[1]
915 917 self.Num_Chn = self.spc.shape[0]
916 918
917 919 Velrange = dataOut.abscissaList
918 920
919 921 if radar == "MIRA35C" :
920 922
921 923 Ze = self.dBZeMODE2(dataOut)
922 924
923 925 else:
924 926
925 927 self.Pt = Pt
926 928 self.Gt = Gt
927 929 self.Gr = Gr
928 930 self.Lambda = Lambda
929 931 self.aL = aL
930 932 self.tauW = tauW
931 933 self.ThetaT = ThetaT
932 934 self.ThetaR = ThetaR
933 935
934 936 RadarConstant = GetRadarConstant()
935 937 SPCmean = numpy.mean(self.spc,0)
936 938 ETA = numpy.zeros(self.Num_Hei)
937 939 Pr = numpy.sum(SPCmean,0)
938 940
939 941 #for R in range(self.Num_Hei):
940 942 # ETA[R] = RadarConstant * Pr[R] * R**2 #Reflectivity (ETA)
941 943
942 944 D_range = numpy.zeros(self.Num_Hei)
943 945 EqSec = numpy.zeros(self.Num_Hei)
944 946 del_V = numpy.zeros(self.Num_Hei)
945 947
946 948 for R in range(self.Num_Hei):
947 949 ETA[R] = RadarConstant * Pr[R] * R**2 #Reflectivity (ETA)
948 950
949 951 h = R + Altitude #Range from ground to radar pulse altitude
950 952 del_V[R] = 1 + 3.68 * 10**-5 * h + 1.71 * 10**-9 * h**2 #Density change correction for velocity
951 953
952 954 D_range[R] = numpy.log( (9.65 - (Velrange[R]/del_V[R])) / 10.3 ) / -0.6 #Range of Diameter of drops related to velocity
953 955 SIGMA[R] = numpy.pi**5 / Lambda**4 * Km * D_range[R]**6 #Equivalent Section of drops (sigma)
954 956
955 957 N_dist[R] = ETA[R] / SIGMA[R]
956 958
957 959 Ze = (ETA * Lambda**4) / (numpy.pi * Km)
958 960 Z = numpy.sum( N_dist * D_range**6 )
959 961 RR = 6*10**-4*numpy.pi * numpy.sum( D_range**3 * N_dist * Velrange ) #Rainfall rate
960 962
961 963
962 964 RR = (Ze/200)**(1/1.6)
963 965 dBRR = 10*numpy.log10(RR)
964 966
965 967 dBZe = 10*numpy.log10(Ze)
966 968 dataOut.data_output = Ze
967 969 dataOut.data_param = numpy.ones([2,self.Num_Hei])
968 970 dataOut.channelList = [0,1]
969 971 print 'channelList', dataOut.channelList
970 972 dataOut.data_param[0]=dBZe
971 973 dataOut.data_param[1]=dBRR
972 974 print 'RR SHAPE', dBRR.shape
973 975 print 'Ze SHAPE', dBZe.shape
974 976 print 'dataOut.data_param SHAPE', dataOut.data_param.shape
975 977
976 978
977 979 def dBZeMODE2(self, dataOut): # Processing for MIRA35C
978 980
979 981 NPW = dataOut.NPW
980 982 COFA = dataOut.COFA
981 983
982 984 SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]])
983 985 RadarConst = dataOut.RadarConst
984 986 #frequency = 34.85*10**9
985 987
986 988 ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei]))
987 989 data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN
988 990
989 991 ETA = numpy.sum(SNR,1)
990 992 print 'ETA' , ETA
991 993 ETA = numpy.where(ETA is not 0. , ETA, numpy.NaN)
992 994
993 995 Ze = numpy.ones([self.Num_Chn, self.Num_Hei] )
994 996
995 997 for r in range(self.Num_Hei):
996 998
997 999 Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2)
998 1000 #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2)
999 1001
1000 1002 return Ze
1001 1003
1002 1004 def GetRadarConstant(self):
1003 1005
1004 1006 """
1005 1007 Constants:
1006 1008
1007 1009 Pt: Transmission Power dB
1008 1010 Gt: Transmission Gain dB
1009 1011 Gr: Reception Gain dB
1010 1012 Lambda: Wavelenght m
1011 1013 aL: Attenuation loses dB
1012 1014 tauW: Width of transmission pulse s
1013 1015 ThetaT: Transmission antenna bean angle rad
1014 1016 ThetaR: Reception antenna beam angle rad
1015 1017
1016 1018 """
1017 1019 Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) )
1018 1020 Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR)
1019 1021 RadarConstant = Numerator / Denominator
1020 1022
1021 1023 return RadarConstant
1022 1024
1023 1025
1024 1026
1025 1027 class FullSpectralAnalysis(Operation):
1026 1028
1027 1029 """
1028 1030 Function that implements Full Spectral Analisys technique.
1029 1031
1030 1032 Input:
1031 1033 self.dataOut.data_pre : SelfSpectra and CrossSPectra data
1032 1034 self.dataOut.groupList : Pairlist of channels
1033 1035 self.dataOut.ChanDist : Physical distance between receivers
1034 1036
1035 1037
1036 1038 Output:
1037 1039
1038 1040 self.dataOut.data_output : Zonal wind, Meridional wind and Vertical wind
1039 1041
1040 1042
1041 1043 Parameters affected: Winds, height range, SNR
1042 1044
1043 1045 """
1044 def run(self, dataOut, E01=None, E02=None, E12=None, N01=None, N02=None, N12=None):
1046 def run(self, dataOut, E01=None, E02=None, E12=None, N01=None, N02=None, N12=None, SNRlimit=7):
1045 1047
1046 1048 spc = dataOut.data_pre[0].copy()
1047 1049 cspc = dataOut.data_pre[1].copy()
1048 1050
1049 1051 nChannel = spc.shape[0]
1050 1052 nProfiles = spc.shape[1]
1051 1053 nHeights = spc.shape[2]
1052 1054
1053 1055 pairsList = dataOut.groupList
1054 1056 if dataOut.ChanDist is not None :
1055 1057 ChanDist = dataOut.ChanDist
1056 1058 else:
1057 1059 ChanDist = numpy.array([[E01, N01],[E02,N02],[E12,N12]])
1058 1060
1059 1061 #print 'ChanDist', ChanDist
1060 1062
1061 1063 if dataOut.VelRange is not None:
1062 1064 VelRange= dataOut.VelRange
1063 1065 else:
1064 1066 VelRange= dataOut.abscissaList
1065 1067
1066 1068 ySamples=numpy.ones([nChannel,nProfiles])
1067 1069 phase=numpy.ones([nChannel,nProfiles])
1068 1070 CSPCSamples=numpy.ones([nChannel,nProfiles],dtype=numpy.complex_)
1069 1071 coherence=numpy.ones([nChannel,nProfiles])
1070 1072 PhaseSlope=numpy.ones(nChannel)
1071 1073 PhaseInter=numpy.ones(nChannel)
1074 dataSNR = dataOut.data_SNR
1075
1076
1072 1077
1073 1078 data = dataOut.data_pre
1074 1079 noise = dataOut.noise
1075 1080 print 'noise',noise
1076 SNRdB = 10*numpy.log10(dataOut.data_SNR)
1081 #SNRdB = 10*numpy.log10(dataOut.data_SNR)
1077 1082
1078 FirstMoment = []
1079 SNRdBMean = []
1083 FirstMoment = numpy.average(dataOut.data_param[:,1,:],0)
1084 #SNRdBMean = []
1085
1080 1086
1081 for j in range(nHeights):
1082 FirstMoment = numpy.append(FirstMoment,numpy.mean([dataOut.data_param[0,1,j],dataOut.data_param[1,1,j],dataOut.data_param[2,1,j]]))
1083 SNRdBMean = numpy.append(SNRdBMean,numpy.mean([SNRdB[0,j],SNRdB[1,j],SNRdB[2,j]]))
1087 #for j in range(nHeights):
1088 # FirstMoment = numpy.append(FirstMoment,numpy.mean([dataOut.data_param[0,1,j],dataOut.data_param[1,1,j],dataOut.data_param[2,1,j]]))
1089 # SNRdBMean = numpy.append(SNRdBMean,numpy.mean([SNRdB[0,j],SNRdB[1,j],SNRdB[2,j]]))
1084 1090
1085 1091 data_output=numpy.ones([3,spc.shape[2]])*numpy.NaN
1086 1092
1087 1093 velocityX=[]
1088 1094 velocityY=[]
1089 1095 velocityV=[]
1090 1096
1097 dbSNR = 10*numpy.log10(dataSNR)
1098 dbSNR = numpy.average(dbSNR,0)
1091 1099 for Height in range(nHeights):
1092 1100
1093 [Vzon,Vmer,Vver, GaussCenter]= self.WindEstimation(spc, cspc, pairsList, ChanDist, Height, noise, VelRange)
1101 [Vzon,Vmer,Vver, GaussCenter]= self.WindEstimation(spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR[Height], SNRlimit)
1094 1102
1095 1103 if abs(Vzon)<100. and abs(Vzon)> 0.:
1096 1104 velocityX=numpy.append(velocityX, Vzon)#Vmag
1097 1105
1098 1106 else:
1099 1107 print 'Vzon',Vzon
1100 1108 velocityX=numpy.append(velocityX, numpy.NaN)
1101 1109
1102 1110 if abs(Vmer)<100. and abs(Vmer) > 0.:
1103 1111 velocityY=numpy.append(velocityY, Vmer)#Vang
1104 1112
1105 1113 else:
1106 1114 print 'Vmer',Vmer
1107 1115 velocityY=numpy.append(velocityY, numpy.NaN)
1108 1116
1109 if abs(GaussCenter)<10:
1110 velocityV=numpy.append(velocityV, Vver)
1117 if dbSNR[Height] > SNRlimit:
1118 velocityV=numpy.append(velocityV, FirstMoment[Height])
1111 1119 else:
1112 1120 velocityV=numpy.append(velocityV, numpy.NaN)
1113 1121 #FirstMoment[Height]= numpy.NaN
1114 1122 # if SNRdBMean[Height] <12:
1115 1123 # FirstMoment[Height] = numpy.NaN
1116 1124 # velocityX[Height] = numpy.NaN
1117 1125 # velocityY[Height] = numpy.NaN
1118 1126
1119 1127
1120 1128 data_output[0]=numpy.array(velocityX)
1121 1129 data_output[1]=numpy.array(velocityY)
1122 data_output[2]=-FirstMoment
1130 data_output[2]=-velocityV#FirstMoment
1123 1131
1124 1132 print ' '
1125 1133 #print 'FirstMoment'
1126 1134 #print FirstMoment
1127 1135 print 'velocityX',data_output[0]
1128 1136 print ' '
1129 1137 print 'velocityY',data_output[1]
1130 1138 #print numpy.array(velocityY)
1131 1139 print ' '
1132 1140 #print 'SNR'
1133 1141 #print 10*numpy.log10(dataOut.data_SNR)
1134 1142 #print numpy.shape(10*numpy.log10(dataOut.data_SNR))
1135 1143 print ' '
1136 1144
1137 1145
1138 1146 dataOut.data_output=data_output
1139 1147 return
1140 1148
1141 1149
1142 1150 def moving_average(self,x, N=2):
1143 1151 return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):]
1144 1152
1145 1153 def gaus(self,xSamples,a,x0,sigma):
1146 1154 return a*numpy.exp(-(xSamples-x0)**2/(2*sigma**2))
1147 1155
1148 1156 def Find(self,x,value):
1149 1157 for index in range(len(x)):
1150 1158 if x[index]==value:
1151 1159 return index
1152 1160
1153 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, VelRange):
1161 def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR, SNRlimit):
1154 1162
1155 1163 ySamples=numpy.ones([spc.shape[0],spc.shape[1]])
1156 1164 phase=numpy.ones([spc.shape[0],spc.shape[1]])
1157 1165 CSPCSamples=numpy.ones([spc.shape[0],spc.shape[1]],dtype=numpy.complex_)
1158 1166 coherence=numpy.ones([spc.shape[0],spc.shape[1]])
1159 1167 PhaseSlope=numpy.ones(spc.shape[0])
1160 1168 PhaseInter=numpy.ones(spc.shape[0])
1161 1169 xFrec=VelRange
1162 1170
1163 1171 '''Getting Eij and Nij'''
1164 1172
1165 1173 E01=ChanDist[0][0]
1166 1174 N01=ChanDist[0][1]
1167 1175
1168 1176 E02=ChanDist[1][0]
1169 1177 N02=ChanDist[1][1]
1170 1178
1171 1179 E12=ChanDist[2][0]
1172 1180 N12=ChanDist[2][1]
1173 1181
1174 1182 z = spc.copy()
1175 1183 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
1176 1184
1177 1185 for i in range(spc.shape[0]):
1178 1186
1179 1187 '''****** Line of Data SPC ******'''
1180 zline=z[i,:,Height]
1188 zline=z[i,:,Height]
1181 1189
1182 1190 '''****** SPC is normalized ******'''
1183 FactNorm= zline.copy() / numpy.sum(zline.copy())
1191 FactNorm= (zline.copy()-noise[i]) / numpy.sum(zline.copy())
1184 1192 FactNorm= FactNorm/numpy.sum(FactNorm)
1185 1193
1186 1194 SmoothSPC=self.moving_average(FactNorm,N=3)
1187 1195
1188 1196 xSamples = ar(range(len(SmoothSPC)))
1189 ySamples[i] = SmoothSPC-noise[i]
1190
1197 ySamples[i] = SmoothSPC
1198
1199 #dbSNR=10*numpy.log10(dataSNR)
1191 1200 print ' '
1192 1201 print ' '
1193 1202 print ' '
1194 print 'SmoothSPC',SmoothSPC
1203
1204 #print 'dataSNR', dbSNR.shape, dbSNR[0,40:120]
1205 print 'SmoothSPC', SmoothSPC.shape, SmoothSPC[0:20]
1195 1206 print 'noise',noise
1196 print'zline',zline
1197 print'FactNorm',FactNorm
1207 print 'zline',zline.shape, zline[0:20]
1208 print 'FactNorm',FactNorm.shape, FactNorm[0:20]
1209 print 'FactNorm suma', numpy.sum(FactNorm)
1198 1210
1199 1211 for i in range(spc.shape[0]):
1200 1212
1201 1213 '''****** Line of Data CSPC ******'''
1202 1214 cspcLine=cspc[i,:,Height].copy()
1203 1215
1204 1216 '''****** CSPC is normalized ******'''
1205 1217 chan_index0 = pairsList[i][0]
1206 1218 chan_index1 = pairsList[i][1]
1207 CSPCFactor= numpy.sum(ySamples[chan_index0]) * numpy.sum(ySamples[chan_index1])
1219 CSPCFactor= abs(numpy.sum(ySamples[chan_index0]) * numpy.sum(ySamples[chan_index1])) #
1208 1220
1209 CSPCNorm= cspcLine.copy() / numpy.sqrt(CSPCFactor)
1221 CSPCNorm = (cspcLine.copy() -noise[i]) / numpy.sqrt(CSPCFactor)
1210 1222
1211 CSPCSamples[i] = CSPCNorm-noise[i]
1223 CSPCSamples[i] = CSPCNorm
1212 1224 coherence[i] = numpy.abs(CSPCSamples[i]) / numpy.sqrt(CSPCFactor)
1213 1225
1214 1226 coherence[i]= self.moving_average(coherence[i],N=2)
1215 1227
1216 1228 phase[i] = self.moving_average( numpy.arctan2(CSPCSamples[i].imag, CSPCSamples[i].real),N=1)#*180/numpy.pi
1217 1229
1218 print 'CSPCSamples', CSPCSamples
1219
1230 print 'cspcLine', cspcLine.shape, cspcLine[0:20]
1231 print 'CSPCFactor', CSPCFactor#, CSPCFactor[0:20]
1232 print numpy.sum(ySamples[chan_index0]), numpy.sum(ySamples[chan_index1]), -noise[i]
1233 print 'CSPCNorm', CSPCNorm.shape, CSPCNorm[0:20]
1234 print 'CSPCNorm suma', numpy.sum(CSPCNorm)
1235 print 'CSPCSamples', CSPCSamples.shape, CSPCSamples[0,0:20]
1236
1220 1237 '''****** Getting fij width ******'''
1221 1238
1222 1239 yMean=[]
1223 1240 yMean2=[]
1224 1241
1225 1242 for j in range(len(ySamples[1])):
1226 1243 yMean=numpy.append(yMean,numpy.mean([ySamples[0,j],ySamples[1,j],ySamples[2,j]]))
1227 1244
1228 1245 '''******* Getting fitting Gaussian ******'''
1229 1246 meanGauss=sum(xSamples*yMean) / len(xSamples)
1230 1247 sigma=sum(yMean*(xSamples-meanGauss)**2) / len(xSamples)
1231 1248
1232 1249 print '****************************'
1233 1250 print 'len(xSamples): ',len(xSamples)
1234 print 'yMean: ', yMean
1235 print 'ySamples', ySamples
1236 print 'xSamples: ',xSamples
1251 print 'yMean: ', yMean.shape, yMean[0:20]
1252 print 'ySamples', ySamples.shape, ySamples[0,0:20]
1253 print 'xSamples: ',xSamples.shape, xSamples[0:20]
1237 1254
1238 1255 print 'meanGauss',meanGauss
1239 1256 print 'sigma',sigma
1240 if (abs(meanGauss/sigma**2) > 0.000000001):#0.00001) :
1241 1257
1258 #if (abs(meanGauss/sigma**2) > 0.0001) : #0.000000001):
1259 if dbSNR > SNRlimit :
1242 1260 try:
1243 1261 popt,pcov = curve_fit(self.gaus,xSamples,yMean,p0=[1,meanGauss,sigma])
1244 1262
1245 1263 if numpy.amax(popt)>numpy.amax(yMean)*0.3:
1246 1264 FitGauss=self.gaus(xSamples,*popt)
1247 1265
1248 1266 else:
1249 1267 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1250 1268 print 'Verificador: Dentro', Height
1251 except RuntimeError:
1269 except :#RuntimeError:
1252 1270 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1253 1271
1254 1272
1255 1273 else:
1256 1274 FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean)
1257 1275
1258 1276 Maximun=numpy.amax(yMean)
1259 eMinus1=Maximun*numpy.exp(-1)*0.8
1277 eMinus1=Maximun*numpy.exp(-1)#*0.8
1260 1278
1261 1279 HWpos=self.Find(FitGauss,min(FitGauss, key=lambda value:abs(value-eMinus1)))
1262 1280 HalfWidth= xFrec[HWpos]
1263 1281 GCpos=self.Find(FitGauss, numpy.amax(FitGauss))
1264 1282 Vpos=self.Find(FactNorm, numpy.amax(FactNorm))
1265 1283
1266 1284 #Vpos=FirstMoment[]
1267 1285
1268 1286 '''****** Getting Fij ******'''
1269 1287
1270 1288 GaussCenter=xFrec[GCpos]
1271 1289 if (GaussCenter<0 and HalfWidth>0) or (GaussCenter>0 and HalfWidth<0):
1272 1290 Fij=abs(GaussCenter)+abs(HalfWidth)+0.0000001
1273 1291 else:
1274 1292 Fij=abs(GaussCenter-HalfWidth)+0.0000001
1275 1293
1276 1294 '''****** Getting Frecuency range of significant data ******'''
1277 1295
1278 1296 Rangpos=self.Find(FitGauss,min(FitGauss, key=lambda value:abs(value-Maximun*0.10)))
1279 1297
1280 1298 if Rangpos<GCpos:
1281 1299 Range=numpy.array([Rangpos,2*GCpos-Rangpos])
1282 else:
1300 elif Rangpos< ( len(xFrec)- len(xFrec)*0.1):
1283 1301 Range=numpy.array([2*GCpos-Rangpos,Rangpos])
1302 else:
1303 Range = numpy.array([0,0])
1284 1304
1305 print ' '
1306 print 'GCpos',GCpos, ( len(xFrec)- len(xFrec)*0.1)
1307 print 'Rangpos',Rangpos
1308 print 'RANGE: ', Range
1285 1309 FrecRange=xFrec[Range[0]:Range[1]]
1286 1310
1287 1311 '''****** Getting SCPC Slope ******'''
1288 1312
1289 1313 for i in range(spc.shape[0]):
1290 1314
1291 1315 if len(FrecRange)>5 and len(FrecRange)<spc.shape[1]*0.5:
1292 1316 PhaseRange=self.moving_average(phase[i,Range[0]:Range[1]],N=3)
1293
1294 slope, intercept, r_value, p_value, std_err = stats.linregress(FrecRange,PhaseRange)
1295 PhaseSlope[i]=slope
1296 PhaseInter[i]=intercept
1317
1318 print 'FrecRange', len(FrecRange) , FrecRange
1319 print 'PhaseRange', len(PhaseRange), PhaseRange
1320 print ' '
1321 if len(FrecRange) == len(PhaseRange):
1322 slope, intercept, r_value, p_value, std_err = stats.linregress(FrecRange,PhaseRange)
1323 PhaseSlope[i]=slope
1324 PhaseInter[i]=intercept
1325 else:
1326 PhaseSlope[i]=0
1327 PhaseInter[i]=0
1297 1328 else:
1298 1329 PhaseSlope[i]=0
1299 1330 PhaseInter[i]=0
1300 1331
1301 1332 '''Getting constant C'''
1302 1333 cC=(Fij*numpy.pi)**2
1303 1334
1304 1335 '''****** Getting constants F and G ******'''
1305 1336 MijEijNij=numpy.array([[E02,N02], [E12,N12]])
1306 1337 MijResult0=(-PhaseSlope[1]*cC) / (2*numpy.pi)
1307 1338 MijResult1=(-PhaseSlope[2]*cC) / (2*numpy.pi)
1308 1339 MijResults=numpy.array([MijResult0,MijResult1])
1309 1340 (cF,cG) = numpy.linalg.solve(MijEijNij, MijResults)
1310 1341
1311 1342 '''****** Getting constants A, B and H ******'''
1312 1343 W01=numpy.amax(coherence[0])
1313 1344 W02=numpy.amax(coherence[1])
1314 1345 W12=numpy.amax(coherence[2])
1315 1346
1316 1347 WijResult0=((cF*E01+cG*N01)**2)/cC - numpy.log(W01 / numpy.sqrt(numpy.pi/cC))
1317 1348 WijResult1=((cF*E02+cG*N02)**2)/cC - numpy.log(W02 / numpy.sqrt(numpy.pi/cC))
1318 1349 WijResult2=((cF*E12+cG*N12)**2)/cC - numpy.log(W12 / numpy.sqrt(numpy.pi/cC))
1319 1350
1320 1351 WijResults=numpy.array([WijResult0, WijResult1, WijResult2])
1321 1352
1322 1353 WijEijNij=numpy.array([ [E01**2, N01**2, 2*E01*N01] , [E02**2, N02**2, 2*E02*N02] , [E12**2, N12**2, 2*E12*N12] ])
1323 1354 (cA,cB,cH) = numpy.linalg.solve(WijEijNij, WijResults)
1324 1355
1325 1356 VxVy=numpy.array([[cA,cH],[cH,cB]])
1326 1357
1327 1358 VxVyResults=numpy.array([-cF,-cG])
1328 1359 (Vx,Vy) = numpy.linalg.solve(VxVy, VxVyResults)
1329 1360
1330 1361 Vzon = Vy
1331 1362 Vmer = Vx
1332 1363 Vmag=numpy.sqrt(Vzon**2+Vmer**2)
1333 1364 Vang=numpy.arctan2(Vmer,Vzon)
1334 1365 Vver=xFrec[Vpos]
1335 1366 print 'vzon y vmer', Vzon, Vmer
1336 1367 return Vzon, Vmer, Vver, GaussCenter
1337 1368
1338 1369 class SpectralMoments(Operation):
1339 1370
1340 1371 '''
1341 1372 Function SpectralMoments()
1342 1373
1343 1374 Calculates moments (power, mean, standard deviation) and SNR of the signal
1344 1375
1345 1376 Type of dataIn: Spectra
1346 1377
1347 1378 Configuration Parameters:
1348 1379
1349 1380 dirCosx : Cosine director in X axis
1350 1381 dirCosy : Cosine director in Y axis
1351 1382
1352 1383 elevation :
1353 1384 azimuth :
1354 1385
1355 1386 Input:
1356 1387 channelList : simple channel list to select e.g. [2,3,7]
1357 1388 self.dataOut.data_pre : Spectral data
1358 1389 self.dataOut.abscissaList : List of frequencies
1359 1390 self.dataOut.noise : Noise level per channel
1360 1391
1361 1392 Affected:
1362 1393 self.dataOut.data_param : Parameters per channel
1363 1394 self.dataOut.data_SNR : SNR per channel
1364 1395
1365 1396 '''
1366 1397
1367 1398 def run(self, dataOut):
1368 1399
1369 1400 #dataOut.data_pre = dataOut.data_pre[0]
1370 1401 data = dataOut.data_pre[0]
1371 1402 absc = dataOut.abscissaList[:-1]
1372 1403 noise = dataOut.noise
1373 1404 nChannel = data.shape[0]
1374 1405 data_param = numpy.zeros((nChannel, 4, data.shape[2]))
1375 1406
1376 1407 for ind in range(nChannel):
1377 1408 data_param[ind,:,:] = self.__calculateMoments( data[ind,:,:] , absc , noise[ind] )
1378 1409
1379 1410 dataOut.data_param = data_param[:,1:,:]
1380 1411 dataOut.data_SNR = data_param[:,0]
1381 1412 return
1382 1413
1383 1414 def __calculateMoments(self, oldspec, oldfreq, n0,
1384 1415 nicoh = None, graph = None, smooth = None, type1 = None, fwindow = None, snrth = None, dc = None, aliasing = None, oldfd = None, wwauto = None):
1385 1416
1386 1417 if (nicoh == None): nicoh = 1
1387 1418 if (graph == None): graph = 0
1388 1419 if (smooth == None): smooth = 0
1389 1420 elif (self.smooth < 3): smooth = 0
1390 1421
1391 1422 if (type1 == None): type1 = 0
1392 1423 if (fwindow == None): fwindow = numpy.zeros(oldfreq.size) + 1
1393 1424 if (snrth == None): snrth = -3
1394 1425 if (dc == None): dc = 0
1395 1426 if (aliasing == None): aliasing = 0
1396 1427 if (oldfd == None): oldfd = 0
1397 1428 if (wwauto == None): wwauto = 0
1398 1429
1399 1430 if (n0 < 1.e-20): n0 = 1.e-20
1400 1431
1401 1432 freq = oldfreq
1402 1433 vec_power = numpy.zeros(oldspec.shape[1])
1403 1434 vec_fd = numpy.zeros(oldspec.shape[1])
1404 1435 vec_w = numpy.zeros(oldspec.shape[1])
1405 1436 vec_snr = numpy.zeros(oldspec.shape[1])
1406 1437
1407 1438 for ind in range(oldspec.shape[1]):
1408 1439
1409 1440 spec = oldspec[:,ind]
1410 1441 aux = spec*fwindow
1411 1442 max_spec = aux.max()
1412 1443 m = list(aux).index(max_spec)
1413 1444
1414 1445 #Smooth
1415 1446 if (smooth == 0): spec2 = spec
1416 1447 else: spec2 = scipy.ndimage.filters.uniform_filter1d(spec,size=smooth)
1417 1448
1418 1449 # Calculo de Momentos
1419 1450 bb = spec2[range(m,spec2.size)]
1420 1451 bb = (bb<n0).nonzero()
1421 1452 bb = bb[0]
1422 1453
1423 1454 ss = spec2[range(0,m + 1)]
1424 1455 ss = (ss<n0).nonzero()
1425 1456 ss = ss[0]
1426 1457
1427 1458 if (bb.size == 0):
1428 1459 bb0 = spec.size - 1 - m
1429 1460 else:
1430 1461 bb0 = bb[0] - 1
1431 1462 if (bb0 < 0):
1432 1463 bb0 = 0
1433 1464
1434 1465 if (ss.size == 0): ss1 = 1
1435 1466 else: ss1 = max(ss) + 1
1436 1467
1437 1468 if (ss1 > m): ss1 = m
1438 1469
1439 1470 valid = numpy.asarray(range(int(m + bb0 - ss1 + 1))) + ss1
1440 1471 power = ((spec2[valid] - n0)*fwindow[valid]).sum()
1441 1472 fd = ((spec2[valid]- n0)*freq[valid]*fwindow[valid]).sum()/power
1442 1473 w = math.sqrt(((spec2[valid] - n0)*fwindow[valid]*(freq[valid]- fd)**2).sum()/power)
1443 1474 snr = (spec2.mean()-n0)/n0
1444 1475
1445 1476 if (snr < 1.e-20) :
1446 1477 snr = 1.e-20
1447 1478
1448 1479 vec_power[ind] = power
1449 1480 vec_fd[ind] = fd
1450 1481 vec_w[ind] = w
1451 1482 vec_snr[ind] = snr
1452 1483
1453 1484 moments = numpy.vstack((vec_snr, vec_power, vec_fd, vec_w))
1454 1485 return moments
1455 1486
1456 1487 #------------------ Get SA Parameters --------------------------
1457 1488
1458 1489 def GetSAParameters(self):
1459 1490 #SA en frecuencia
1460 1491 pairslist = self.dataOut.groupList
1461 1492 num_pairs = len(pairslist)
1462 1493
1463 1494 vel = self.dataOut.abscissaList
1464 1495 spectra = self.dataOut.data_pre
1465 1496 cspectra = self.dataIn.data_cspc
1466 1497 delta_v = vel[1] - vel[0]
1467 1498
1468 1499 #Calculating the power spectrum
1469 1500 spc_pow = numpy.sum(spectra, 3)*delta_v
1470 1501 #Normalizing Spectra
1471 1502 norm_spectra = spectra/spc_pow
1472 1503 #Calculating the norm_spectra at peak
1473 1504 max_spectra = numpy.max(norm_spectra, 3)
1474 1505
1475 1506 #Normalizing Cross Spectra
1476 1507 norm_cspectra = numpy.zeros(cspectra.shape)
1477 1508
1478 1509 for i in range(num_chan):
1479 1510 norm_cspectra[i,:,:] = cspectra[i,:,:]/numpy.sqrt(spc_pow[pairslist[i][0],:]*spc_pow[pairslist[i][1],:])
1480 1511
1481 1512 max_cspectra = numpy.max(norm_cspectra,2)
1482 1513 max_cspectra_index = numpy.argmax(norm_cspectra, 2)
1483 1514
1484 1515 for i in range(num_pairs):
1485 1516 cspc_par[i,:,:] = __calculateMoments(norm_cspectra)
1486 1517 #------------------- Get Lags ----------------------------------
1487 1518
1488 1519 class SALags(Operation):
1489 1520 '''
1490 1521 Function GetMoments()
1491 1522
1492 1523 Input:
1493 1524 self.dataOut.data_pre
1494 1525 self.dataOut.abscissaList
1495 1526 self.dataOut.noise
1496 1527 self.dataOut.normFactor
1497 1528 self.dataOut.data_SNR
1498 1529 self.dataOut.groupList
1499 1530 self.dataOut.nChannels
1500 1531
1501 1532 Affected:
1502 1533 self.dataOut.data_param
1503 1534
1504 1535 '''
1505 1536 def run(self, dataOut):
1506 1537 data_acf = dataOut.data_pre[0]
1507 1538 data_ccf = dataOut.data_pre[1]
1508 1539 normFactor_acf = dataOut.normFactor[0]
1509 1540 normFactor_ccf = dataOut.normFactor[1]
1510 1541 pairs_acf = dataOut.groupList[0]
1511 1542 pairs_ccf = dataOut.groupList[1]
1512 1543
1513 1544 nHeights = dataOut.nHeights
1514 1545 absc = dataOut.abscissaList
1515 1546 noise = dataOut.noise
1516 1547 SNR = dataOut.data_SNR
1517 1548 nChannels = dataOut.nChannels
1518 1549 # pairsList = dataOut.groupList
1519 1550 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairsList, nChannels)
1520 1551
1521 1552 for l in range(len(pairs_acf)):
1522 1553 data_acf[l,:,:] = data_acf[l,:,:]/normFactor_acf[l,:]
1523 1554
1524 1555 for l in range(len(pairs_ccf)):
1525 1556 data_ccf[l,:,:] = data_ccf[l,:,:]/normFactor_ccf[l,:]
1526 1557
1527 1558 dataOut.data_param = numpy.zeros((len(pairs_ccf)*2 + 1, nHeights))
1528 1559 dataOut.data_param[:-1,:] = self.__calculateTaus(data_acf, data_ccf, absc)
1529 1560 dataOut.data_param[-1,:] = self.__calculateLag1Phase(data_acf, absc)
1530 1561 return
1531 1562
1532 1563 # def __getPairsAutoCorr(self, pairsList, nChannels):
1533 1564 #
1534 1565 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1535 1566 #
1536 1567 # for l in range(len(pairsList)):
1537 1568 # firstChannel = pairsList[l][0]
1538 1569 # secondChannel = pairsList[l][1]
1539 1570 #
1540 1571 # #Obteniendo pares de Autocorrelacion
1541 1572 # if firstChannel == secondChannel:
1542 1573 # pairsAutoCorr[firstChannel] = int(l)
1543 1574 #
1544 1575 # pairsAutoCorr = pairsAutoCorr.astype(int)
1545 1576 #
1546 1577 # pairsCrossCorr = range(len(pairsList))
1547 1578 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1548 1579 #
1549 1580 # return pairsAutoCorr, pairsCrossCorr
1550 1581
1551 1582 def __calculateTaus(self, data_acf, data_ccf, lagRange):
1552 1583
1553 1584 lag0 = data_acf.shape[1]/2
1554 1585 #Funcion de Autocorrelacion
1555 1586 mean_acf = stats.nanmean(data_acf, axis = 0)
1556 1587
1557 1588 #Obtencion Indice de TauCross
1558 1589 ind_ccf = data_ccf.argmax(axis = 1)
1559 1590 #Obtencion Indice de TauAuto
1560 1591 ind_acf = numpy.zeros(ind_ccf.shape,dtype = 'int')
1561 1592 ccf_lag0 = data_ccf[:,lag0,:]
1562 1593
1563 1594 for i in range(ccf_lag0.shape[0]):
1564 1595 ind_acf[i,:] = numpy.abs(mean_acf - ccf_lag0[i,:]).argmin(axis = 0)
1565 1596
1566 1597 #Obtencion de TauCross y TauAuto
1567 1598 tau_ccf = lagRange[ind_ccf]
1568 1599 tau_acf = lagRange[ind_acf]
1569 1600
1570 1601 Nan1, Nan2 = numpy.where(tau_ccf == lagRange[0])
1571 1602
1572 1603 tau_ccf[Nan1,Nan2] = numpy.nan
1573 1604 tau_acf[Nan1,Nan2] = numpy.nan
1574 1605 tau = numpy.vstack((tau_ccf,tau_acf))
1575 1606
1576 1607 return tau
1577 1608
1578 1609 def __calculateLag1Phase(self, data, lagTRange):
1579 1610 data1 = stats.nanmean(data, axis = 0)
1580 1611 lag1 = numpy.where(lagTRange == 0)[0][0] + 1
1581 1612
1582 1613 phase = numpy.angle(data1[lag1,:])
1583 1614
1584 1615 return phase
1585 1616
1586 1617 class SpectralFitting(Operation):
1587 1618 '''
1588 1619 Function GetMoments()
1589 1620
1590 1621 Input:
1591 1622 Output:
1592 1623 Variables modified:
1593 1624 '''
1594 1625
1595 1626 def run(self, dataOut, getSNR = True, path=None, file=None, groupList=None):
1596 1627
1597 1628
1598 1629 if path != None:
1599 1630 sys.path.append(path)
1600 1631 self.dataOut.library = importlib.import_module(file)
1601 1632
1602 1633 #To be inserted as a parameter
1603 1634 groupArray = numpy.array(groupList)
1604 1635 # groupArray = numpy.array([[0,1],[2,3]])
1605 1636 self.dataOut.groupList = groupArray
1606 1637
1607 1638 nGroups = groupArray.shape[0]
1608 1639 nChannels = self.dataIn.nChannels
1609 1640 nHeights=self.dataIn.heightList.size
1610 1641
1611 1642 #Parameters Array
1612 1643 self.dataOut.data_param = None
1613 1644
1614 1645 #Set constants
1615 1646 constants = self.dataOut.library.setConstants(self.dataIn)
1616 1647 self.dataOut.constants = constants
1617 1648 M = self.dataIn.normFactor
1618 1649 N = self.dataIn.nFFTPoints
1619 1650 ippSeconds = self.dataIn.ippSeconds
1620 1651 K = self.dataIn.nIncohInt
1621 1652 pairsArray = numpy.array(self.dataIn.pairsList)
1622 1653
1623 1654 #List of possible combinations
1624 1655 listComb = itertools.combinations(numpy.arange(groupArray.shape[1]),2)
1625 1656 indCross = numpy.zeros(len(list(listComb)), dtype = 'int')
1626 1657
1627 1658 if getSNR:
1628 1659 listChannels = groupArray.reshape((groupArray.size))
1629 1660 listChannels.sort()
1630 1661 noise = self.dataIn.getNoise()
1631 1662 self.dataOut.data_SNR = self.__getSNR(self.dataIn.data_spc[listChannels,:,:], noise[listChannels])
1632 1663
1633 1664 for i in range(nGroups):
1634 1665 coord = groupArray[i,:]
1635 1666
1636 1667 #Input data array
1637 1668 data = self.dataIn.data_spc[coord,:,:]/(M*N)
1638 1669 data = data.reshape((data.shape[0]*data.shape[1],data.shape[2]))
1639 1670
1640 1671 #Cross Spectra data array for Covariance Matrixes
1641 1672 ind = 0
1642 1673 for pairs in listComb:
1643 1674 pairsSel = numpy.array([coord[x],coord[y]])
1644 1675 indCross[ind] = int(numpy.where(numpy.all(pairsArray == pairsSel, axis = 1))[0][0])
1645 1676 ind += 1
1646 1677 dataCross = self.dataIn.data_cspc[indCross,:,:]/(M*N)
1647 1678 dataCross = dataCross**2/K
1648 1679
1649 1680 for h in range(nHeights):
1650 1681 # print self.dataOut.heightList[h]
1651 1682
1652 1683 #Input
1653 1684 d = data[:,h]
1654 1685
1655 1686 #Covariance Matrix
1656 1687 D = numpy.diag(d**2/K)
1657 1688 ind = 0
1658 1689 for pairs in listComb:
1659 1690 #Coordinates in Covariance Matrix
1660 1691 x = pairs[0]
1661 1692 y = pairs[1]
1662 1693 #Channel Index
1663 1694 S12 = dataCross[ind,:,h]
1664 1695 D12 = numpy.diag(S12)
1665 1696 #Completing Covariance Matrix with Cross Spectras
1666 1697 D[x*N:(x+1)*N,y*N:(y+1)*N] = D12
1667 1698 D[y*N:(y+1)*N,x*N:(x+1)*N] = D12
1668 1699 ind += 1
1669 1700 Dinv=numpy.linalg.inv(D)
1670 1701 L=numpy.linalg.cholesky(Dinv)
1671 1702 LT=L.T
1672 1703
1673 1704 dp = numpy.dot(LT,d)
1674 1705
1675 1706 #Initial values
1676 1707 data_spc = self.dataIn.data_spc[coord,:,h]
1677 1708
1678 1709 if (h>0)and(error1[3]<5):
1679 1710 p0 = self.dataOut.data_param[i,:,h-1]
1680 1711 else:
1681 1712 p0 = numpy.array(self.dataOut.library.initialValuesFunction(data_spc, constants, i))
1682 1713
1683 1714 try:
1684 1715 #Least Squares
1685 1716 minp,covp,infodict,mesg,ier = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants),full_output=True)
1686 1717 # minp,covp = optimize.leastsq(self.__residFunction,p0,args=(dp,LT,constants))
1687 1718 #Chi square error
1688 1719 error0 = numpy.sum(infodict['fvec']**2)/(2*N)
1689 1720 #Error with Jacobian
1690 1721 error1 = self.dataOut.library.errorFunction(minp,constants,LT)
1691 1722 except:
1692 1723 minp = p0*numpy.nan
1693 1724 error0 = numpy.nan
1694 1725 error1 = p0*numpy.nan
1695 1726
1696 1727 #Save
1697 1728 if self.dataOut.data_param == None:
1698 1729 self.dataOut.data_param = numpy.zeros((nGroups, p0.size, nHeights))*numpy.nan
1699 1730 self.dataOut.data_error = numpy.zeros((nGroups, p0.size + 1, nHeights))*numpy.nan
1700 1731
1701 1732 self.dataOut.data_error[i,:,h] = numpy.hstack((error0,error1))
1702 1733 self.dataOut.data_param[i,:,h] = minp
1703 1734 return
1704 1735
1705 1736 def __residFunction(self, p, dp, LT, constants):
1706 1737
1707 1738 fm = self.dataOut.library.modelFunction(p, constants)
1708 1739 fmp=numpy.dot(LT,fm)
1709 1740
1710 1741 return dp-fmp
1711 1742
1712 1743 def __getSNR(self, z, noise):
1713 1744
1714 1745 avg = numpy.average(z, axis=1)
1715 1746 SNR = (avg.T-noise)/noise
1716 1747 SNR = SNR.T
1717 1748 return SNR
1718 1749
1719 1750 def __chisq(p,chindex,hindex):
1720 1751 #similar to Resid but calculates CHI**2
1721 1752 [LT,d,fm]=setupLTdfm(p,chindex,hindex)
1722 1753 dp=numpy.dot(LT,d)
1723 1754 fmp=numpy.dot(LT,fm)
1724 1755 chisq=numpy.dot((dp-fmp).T,(dp-fmp))
1725 1756 return chisq
1726 1757
1727 1758 class WindProfiler(Operation):
1728 1759
1729 1760 __isConfig = False
1730 1761
1731 1762 __initime = None
1732 1763 __lastdatatime = None
1733 1764 __integrationtime = None
1734 1765
1735 1766 __buffer = None
1736 1767
1737 1768 __dataReady = False
1738 1769
1739 1770 __firstdata = None
1740 1771
1741 1772 n = None
1742 1773
1743 1774 def __init__(self):
1744 1775 Operation.__init__(self)
1745 1776
1746 1777 def __calculateCosDir(self, elev, azim):
1747 1778 zen = (90 - elev)*numpy.pi/180
1748 1779 azim = azim*numpy.pi/180
1749 1780 cosDirX = numpy.sqrt((1-numpy.cos(zen)**2)/((1+numpy.tan(azim)**2)))
1750 1781 cosDirY = numpy.sqrt(1-numpy.cos(zen)**2-cosDirX**2)
1751 1782
1752 1783 signX = numpy.sign(numpy.cos(azim))
1753 1784 signY = numpy.sign(numpy.sin(azim))
1754 1785
1755 1786 cosDirX = numpy.copysign(cosDirX, signX)
1756 1787 cosDirY = numpy.copysign(cosDirY, signY)
1757 1788 return cosDirX, cosDirY
1758 1789
1759 1790 def __calculateAngles(self, theta_x, theta_y, azimuth):
1760 1791
1761 1792 dir_cosw = numpy.sqrt(1-theta_x**2-theta_y**2)
1762 1793 zenith_arr = numpy.arccos(dir_cosw)
1763 1794 azimuth_arr = numpy.arctan2(theta_x,theta_y) + azimuth*math.pi/180
1764 1795
1765 1796 dir_cosu = numpy.sin(azimuth_arr)*numpy.sin(zenith_arr)
1766 1797 dir_cosv = numpy.cos(azimuth_arr)*numpy.sin(zenith_arr)
1767 1798
1768 1799 return azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw
1769 1800
1770 1801 def __calculateMatA(self, dir_cosu, dir_cosv, dir_cosw, horOnly):
1771 1802
1772 1803 #
1773 1804 if horOnly:
1774 1805 A = numpy.c_[dir_cosu,dir_cosv]
1775 1806 else:
1776 1807 A = numpy.c_[dir_cosu,dir_cosv,dir_cosw]
1777 1808 A = numpy.asmatrix(A)
1778 1809 A1 = numpy.linalg.inv(A.transpose()*A)*A.transpose()
1779 1810
1780 1811 return A1
1781 1812
1782 1813 def __correctValues(self, heiRang, phi, velRadial, SNR):
1783 1814 listPhi = phi.tolist()
1784 1815 maxid = listPhi.index(max(listPhi))
1785 1816 minid = listPhi.index(min(listPhi))
1786 1817
1787 1818 rango = range(len(phi))
1788 1819 # rango = numpy.delete(rango,maxid)
1789 1820
1790 1821 heiRang1 = heiRang*math.cos(phi[maxid])
1791 1822 heiRangAux = heiRang*math.cos(phi[minid])
1792 1823 indOut = (heiRang1 < heiRangAux[0]).nonzero()
1793 1824 heiRang1 = numpy.delete(heiRang1,indOut)
1794 1825
1795 1826 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
1796 1827 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
1797 1828
1798 1829 for i in rango:
1799 1830 x = heiRang*math.cos(phi[i])
1800 1831 y1 = velRadial[i,:]
1801 1832 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
1802 1833
1803 1834 x1 = heiRang1
1804 1835 y11 = f1(x1)
1805 1836
1806 1837 y2 = SNR[i,:]
1807 1838 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
1808 1839 y21 = f2(x1)
1809 1840
1810 1841 velRadial1[i,:] = y11
1811 1842 SNR1[i,:] = y21
1812 1843
1813 1844 return heiRang1, velRadial1, SNR1
1814 1845
1815 1846 def __calculateVelUVW(self, A, velRadial):
1816 1847
1817 1848 #Operacion Matricial
1818 1849 # velUVW = numpy.zeros((velRadial.shape[1],3))
1819 1850 # for ind in range(velRadial.shape[1]):
1820 1851 # velUVW[ind,:] = numpy.dot(A,velRadial[:,ind])
1821 1852 # velUVW = velUVW.transpose()
1822 1853 velUVW = numpy.zeros((A.shape[0],velRadial.shape[1]))
1823 1854 velUVW[:,:] = numpy.dot(A,velRadial)
1824 1855
1825 1856
1826 1857 return velUVW
1827 1858
1828 1859 # def techniqueDBS(self, velRadial0, dirCosx, disrCosy, azimuth, correct, horizontalOnly, heiRang, SNR0):
1829 1860
1830 1861 def techniqueDBS(self, kwargs):
1831 1862 """
1832 1863 Function that implements Doppler Beam Swinging (DBS) technique.
1833 1864
1834 1865 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1835 1866 Direction correction (if necessary), Ranges and SNR
1836 1867
1837 1868 Output: Winds estimation (Zonal, Meridional and Vertical)
1838 1869
1839 1870 Parameters affected: Winds, height range, SNR
1840 1871 """
1841 1872 velRadial0 = kwargs['velRadial']
1842 1873 heiRang = kwargs['heightList']
1843 1874 SNR0 = kwargs['SNR']
1844 1875
1845 1876 if kwargs.has_key('dirCosx') and kwargs.has_key('dirCosy'):
1846 1877 theta_x = numpy.array(kwargs['dirCosx'])
1847 1878 theta_y = numpy.array(kwargs['dirCosy'])
1848 1879 else:
1849 1880 elev = numpy.array(kwargs['elevation'])
1850 1881 azim = numpy.array(kwargs['azimuth'])
1851 1882 theta_x, theta_y = self.__calculateCosDir(elev, azim)
1852 1883 azimuth = kwargs['correctAzimuth']
1853 1884 if kwargs.has_key('horizontalOnly'):
1854 1885 horizontalOnly = kwargs['horizontalOnly']
1855 1886 else: horizontalOnly = False
1856 1887 if kwargs.has_key('correctFactor'):
1857 1888 correctFactor = kwargs['correctFactor']
1858 1889 else: correctFactor = 1
1859 1890 if kwargs.has_key('channelList'):
1860 1891 channelList = kwargs['channelList']
1861 1892 if len(channelList) == 2:
1862 1893 horizontalOnly = True
1863 1894 arrayChannel = numpy.array(channelList)
1864 1895 param = param[arrayChannel,:,:]
1865 1896 theta_x = theta_x[arrayChannel]
1866 1897 theta_y = theta_y[arrayChannel]
1867 1898
1868 1899 azimuth_arr, zenith_arr, dir_cosu, dir_cosv, dir_cosw = self.__calculateAngles(theta_x, theta_y, azimuth)
1869 1900 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, zenith_arr, correctFactor*velRadial0, SNR0)
1870 1901 A = self.__calculateMatA(dir_cosu, dir_cosv, dir_cosw, horizontalOnly)
1871 1902
1872 1903 #Calculo de Componentes de la velocidad con DBS
1873 1904 winds = self.__calculateVelUVW(A,velRadial1)
1874 1905
1875 1906 return winds, heiRang1, SNR1
1876 1907
1877 1908 def __calculateDistance(self, posx, posy, pairs_ccf, azimuth = None):
1878 1909
1879 1910 nPairs = len(pairs_ccf)
1880 1911 posx = numpy.asarray(posx)
1881 1912 posy = numpy.asarray(posy)
1882 1913
1883 1914 #Rotacion Inversa para alinear con el azimuth
1884 1915 if azimuth!= None:
1885 1916 azimuth = azimuth*math.pi/180
1886 1917 posx1 = posx*math.cos(azimuth) + posy*math.sin(azimuth)
1887 1918 posy1 = -posx*math.sin(azimuth) + posy*math.cos(azimuth)
1888 1919 else:
1889 1920 posx1 = posx
1890 1921 posy1 = posy
1891 1922
1892 1923 #Calculo de Distancias
1893 1924 distx = numpy.zeros(nPairs)
1894 1925 disty = numpy.zeros(nPairs)
1895 1926 dist = numpy.zeros(nPairs)
1896 1927 ang = numpy.zeros(nPairs)
1897 1928
1898 1929 for i in range(nPairs):
1899 1930 distx[i] = posx1[pairs_ccf[i][1]] - posx1[pairs_ccf[i][0]]
1900 1931 disty[i] = posy1[pairs_ccf[i][1]] - posy1[pairs_ccf[i][0]]
1901 1932 dist[i] = numpy.sqrt(distx[i]**2 + disty[i]**2)
1902 1933 ang[i] = numpy.arctan2(disty[i],distx[i])
1903 1934
1904 1935 return distx, disty, dist, ang
1905 1936 #Calculo de Matrices
1906 1937 # nPairs = len(pairs)
1907 1938 # ang1 = numpy.zeros((nPairs, 2, 1))
1908 1939 # dist1 = numpy.zeros((nPairs, 2, 1))
1909 1940 #
1910 1941 # for j in range(nPairs):
1911 1942 # dist1[j,0,0] = dist[pairs[j][0]]
1912 1943 # dist1[j,1,0] = dist[pairs[j][1]]
1913 1944 # ang1[j,0,0] = ang[pairs[j][0]]
1914 1945 # ang1[j,1,0] = ang[pairs[j][1]]
1915 1946 #
1916 1947 # return distx,disty, dist1,ang1
1917 1948
1918 1949
1919 1950 def __calculateVelVer(self, phase, lagTRange, _lambda):
1920 1951
1921 1952 Ts = lagTRange[1] - lagTRange[0]
1922 1953 velW = -_lambda*phase/(4*math.pi*Ts)
1923 1954
1924 1955 return velW
1925 1956
1926 1957 def __calculateVelHorDir(self, dist, tau1, tau2, ang):
1927 1958 nPairs = tau1.shape[0]
1928 1959 nHeights = tau1.shape[1]
1929 1960 vel = numpy.zeros((nPairs,3,nHeights))
1930 1961 dist1 = numpy.reshape(dist, (dist.size,1))
1931 1962
1932 1963 angCos = numpy.cos(ang)
1933 1964 angSin = numpy.sin(ang)
1934 1965
1935 1966 vel0 = dist1*tau1/(2*tau2**2)
1936 1967 vel[:,0,:] = (vel0*angCos).sum(axis = 1)
1937 1968 vel[:,1,:] = (vel0*angSin).sum(axis = 1)
1938 1969
1939 1970 ind = numpy.where(numpy.isinf(vel))
1940 1971 vel[ind] = numpy.nan
1941 1972
1942 1973 return vel
1943 1974
1944 1975 # def __getPairsAutoCorr(self, pairsList, nChannels):
1945 1976 #
1946 1977 # pairsAutoCorr = numpy.zeros(nChannels, dtype = 'int')*numpy.nan
1947 1978 #
1948 1979 # for l in range(len(pairsList)):
1949 1980 # firstChannel = pairsList[l][0]
1950 1981 # secondChannel = pairsList[l][1]
1951 1982 #
1952 1983 # #Obteniendo pares de Autocorrelacion
1953 1984 # if firstChannel == secondChannel:
1954 1985 # pairsAutoCorr[firstChannel] = int(l)
1955 1986 #
1956 1987 # pairsAutoCorr = pairsAutoCorr.astype(int)
1957 1988 #
1958 1989 # pairsCrossCorr = range(len(pairsList))
1959 1990 # pairsCrossCorr = numpy.delete(pairsCrossCorr,pairsAutoCorr)
1960 1991 #
1961 1992 # return pairsAutoCorr, pairsCrossCorr
1962 1993
1963 1994 # def techniqueSA(self, pairsSelected, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, lagTRange, correctFactor):
1964 1995 def techniqueSA(self, kwargs):
1965 1996
1966 1997 """
1967 1998 Function that implements Spaced Antenna (SA) technique.
1968 1999
1969 2000 Input: Radial velocities, Direction cosines (x and y) of the Beam, Antenna azimuth,
1970 2001 Direction correction (if necessary), Ranges and SNR
1971 2002
1972 2003 Output: Winds estimation (Zonal, Meridional and Vertical)
1973 2004
1974 2005 Parameters affected: Winds
1975 2006 """
1976 2007 position_x = kwargs['positionX']
1977 2008 position_y = kwargs['positionY']
1978 2009 azimuth = kwargs['azimuth']
1979 2010
1980 2011 if kwargs.has_key('correctFactor'):
1981 2012 correctFactor = kwargs['correctFactor']
1982 2013 else:
1983 2014 correctFactor = 1
1984 2015
1985 2016 groupList = kwargs['groupList']
1986 2017 pairs_ccf = groupList[1]
1987 2018 tau = kwargs['tau']
1988 2019 _lambda = kwargs['_lambda']
1989 2020
1990 2021 #Cross Correlation pairs obtained
1991 2022 # pairsAutoCorr, pairsCrossCorr = self.__getPairsAutoCorr(pairssList, nChannels)
1992 2023 # pairsArray = numpy.array(pairsList)[pairsCrossCorr]
1993 2024 # pairsSelArray = numpy.array(pairsSelected)
1994 2025 # pairs = []
1995 2026 #
1996 2027 # #Wind estimation pairs obtained
1997 2028 # for i in range(pairsSelArray.shape[0]/2):
1998 2029 # ind1 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i], axis = 1))[0][0]
1999 2030 # ind2 = numpy.where(numpy.all(pairsArray == pairsSelArray[2*i + 1], axis = 1))[0][0]
2000 2031 # pairs.append((ind1,ind2))
2001 2032
2002 2033 indtau = tau.shape[0]/2
2003 2034 tau1 = tau[:indtau,:]
2004 2035 tau2 = tau[indtau:-1,:]
2005 2036 # tau1 = tau1[pairs,:]
2006 2037 # tau2 = tau2[pairs,:]
2007 2038 phase1 = tau[-1,:]
2008 2039
2009 2040 #---------------------------------------------------------------------
2010 2041 #Metodo Directo
2011 2042 distx, disty, dist, ang = self.__calculateDistance(position_x, position_y, pairs_ccf,azimuth)
2012 2043 winds = self.__calculateVelHorDir(dist, tau1, tau2, ang)
2013 2044 winds = stats.nanmean(winds, axis=0)
2014 2045 #---------------------------------------------------------------------
2015 2046 #Metodo General
2016 2047 # distx, disty, dist = self.calculateDistance(position_x,position_y,pairsCrossCorr, pairsList, azimuth)
2017 2048 # #Calculo Coeficientes de Funcion de Correlacion
2018 2049 # F,G,A,B,H = self.calculateCoef(tau1,tau2,distx,disty,n)
2019 2050 # #Calculo de Velocidades
2020 2051 # winds = self.calculateVelUV(F,G,A,B,H)
2021 2052
2022 2053 #---------------------------------------------------------------------
2023 2054 winds[2,:] = self.__calculateVelVer(phase1, lagTRange, _lambda)
2024 2055 winds = correctFactor*winds
2025 2056 return winds
2026 2057
2027 2058 def __checkTime(self, currentTime, paramInterval, outputInterval):
2028 2059
2029 2060 dataTime = currentTime + paramInterval
2030 2061 deltaTime = dataTime - self.__initime
2031 2062
2032 2063 if deltaTime >= outputInterval or deltaTime < 0:
2033 2064 self.__dataReady = True
2034 2065 return
2035 2066
2036 2067 def techniqueMeteors(self, arrayMeteor, meteorThresh, heightMin, heightMax):
2037 2068 '''
2038 2069 Function that implements winds estimation technique with detected meteors.
2039 2070
2040 2071 Input: Detected meteors, Minimum meteor quantity to wind estimation
2041 2072
2042 2073 Output: Winds estimation (Zonal and Meridional)
2043 2074
2044 2075 Parameters affected: Winds
2045 2076 '''
2046 2077 # print arrayMeteor.shape
2047 2078 #Settings
2048 2079 nInt = (heightMax - heightMin)/2
2049 2080 # print nInt
2050 2081 nInt = int(nInt)
2051 2082 # print nInt
2052 2083 winds = numpy.zeros((2,nInt))*numpy.nan
2053 2084
2054 2085 #Filter errors
2055 2086 error = numpy.where(arrayMeteor[:,-1] == 0)[0]
2056 2087 finalMeteor = arrayMeteor[error,:]
2057 2088
2058 2089 #Meteor Histogram
2059 2090 finalHeights = finalMeteor[:,2]
2060 2091 hist = numpy.histogram(finalHeights, bins = nInt, range = (heightMin,heightMax))
2061 2092 nMeteorsPerI = hist[0]
2062 2093 heightPerI = hist[1]
2063 2094
2064 2095 #Sort of meteors
2065 2096 indSort = finalHeights.argsort()
2066 2097 finalMeteor2 = finalMeteor[indSort,:]
2067 2098
2068 2099 # Calculating winds
2069 2100 ind1 = 0
2070 2101 ind2 = 0
2071 2102
2072 2103 for i in range(nInt):
2073 2104 nMet = nMeteorsPerI[i]
2074 2105 ind1 = ind2
2075 2106 ind2 = ind1 + nMet
2076 2107
2077 2108 meteorAux = finalMeteor2[ind1:ind2,:]
2078 2109
2079 2110 if meteorAux.shape[0] >= meteorThresh:
2080 2111 vel = meteorAux[:, 6]
2081 2112 zen = meteorAux[:, 4]*numpy.pi/180
2082 2113 azim = meteorAux[:, 3]*numpy.pi/180
2083 2114
2084 2115 n = numpy.cos(zen)
2085 2116 # m = (1 - n**2)/(1 - numpy.tan(azim)**2)
2086 2117 # l = m*numpy.tan(azim)
2087 2118 l = numpy.sin(zen)*numpy.sin(azim)
2088 2119 m = numpy.sin(zen)*numpy.cos(azim)
2089 2120
2090 2121 A = numpy.vstack((l, m)).transpose()
2091 2122 A1 = numpy.dot(numpy.linalg.inv( numpy.dot(A.transpose(),A) ),A.transpose())
2092 2123 windsAux = numpy.dot(A1, vel)
2093 2124
2094 2125 winds[0,i] = windsAux[0]
2095 2126 winds[1,i] = windsAux[1]
2096 2127
2097 2128 return winds, heightPerI[:-1]
2098 2129
2099 2130 def techniqueNSM_SA(self, **kwargs):
2100 2131 metArray = kwargs['metArray']
2101 2132 heightList = kwargs['heightList']
2102 2133 timeList = kwargs['timeList']
2103 2134
2104 2135 rx_location = kwargs['rx_location']
2105 2136 groupList = kwargs['groupList']
2106 2137 azimuth = kwargs['azimuth']
2107 2138 dfactor = kwargs['dfactor']
2108 2139 k = kwargs['k']
2109 2140
2110 2141 azimuth1, dist = self.__calculateAzimuth1(rx_location, groupList, azimuth)
2111 2142 d = dist*dfactor
2112 2143 #Phase calculation
2113 2144 metArray1 = self.__getPhaseSlope(metArray, heightList, timeList)
2114 2145
2115 2146 metArray1[:,-2] = metArray1[:,-2]*metArray1[:,2]*1000/(k*d[metArray1[:,1].astype(int)]) #angles into velocities
2116 2147
2117 2148 velEst = numpy.zeros((heightList.size,2))*numpy.nan
2118 2149 azimuth1 = azimuth1*numpy.pi/180
2119 2150
2120 2151 for i in range(heightList.size):
2121 2152 h = heightList[i]
2122 2153 indH = numpy.where((metArray1[:,2] == h)&(numpy.abs(metArray1[:,-2]) < 100))[0]
2123 2154 metHeight = metArray1[indH,:]
2124 2155 if metHeight.shape[0] >= 2:
2125 2156 velAux = numpy.asmatrix(metHeight[:,-2]).T #Radial Velocities
2126 2157 iazim = metHeight[:,1].astype(int)
2127 2158 azimAux = numpy.asmatrix(azimuth1[iazim]).T #Azimuths
2128 2159 A = numpy.hstack((numpy.cos(azimAux),numpy.sin(azimAux)))
2129 2160 A = numpy.asmatrix(A)
2130 2161 A1 = numpy.linalg.pinv(A.transpose()*A)*A.transpose()
2131 2162 velHor = numpy.dot(A1,velAux)
2132 2163
2133 2164 velEst[i,:] = numpy.squeeze(velHor)
2134 2165 return velEst
2135 2166
2136 2167 def __getPhaseSlope(self, metArray, heightList, timeList):
2137 2168 meteorList = []
2138 2169 #utctime sec1 height SNR velRad ph0 ph1 ph2 coh0 coh1 coh2
2139 2170 #Putting back together the meteor matrix
2140 2171 utctime = metArray[:,0]
2141 2172 uniqueTime = numpy.unique(utctime)
2142 2173
2143 2174 phaseDerThresh = 0.5
2144 2175 ippSeconds = timeList[1] - timeList[0]
2145 2176 sec = numpy.where(timeList>1)[0][0]
2146 2177 nPairs = metArray.shape[1] - 6
2147 2178 nHeights = len(heightList)
2148 2179
2149 2180 for t in uniqueTime:
2150 2181 metArray1 = metArray[utctime==t,:]
2151 2182 # phaseDerThresh = numpy.pi/4 #reducir Phase thresh
2152 2183 tmet = metArray1[:,1].astype(int)
2153 2184 hmet = metArray1[:,2].astype(int)
2154 2185
2155 2186 metPhase = numpy.zeros((nPairs, heightList.size, timeList.size - 1))
2156 2187 metPhase[:,:] = numpy.nan
2157 2188 metPhase[:,hmet,tmet] = metArray1[:,6:].T
2158 2189
2159 2190 #Delete short trails
2160 2191 metBool = ~numpy.isnan(metPhase[0,:,:])
2161 2192 heightVect = numpy.sum(metBool, axis = 1)
2162 2193 metBool[heightVect<sec,:] = False
2163 2194 metPhase[:,heightVect<sec,:] = numpy.nan
2164 2195
2165 2196 #Derivative
2166 2197 metDer = numpy.abs(metPhase[:,:,1:] - metPhase[:,:,:-1])
2167 2198 phDerAux = numpy.dstack((numpy.full((nPairs,nHeights,1), False, dtype=bool),metDer > phaseDerThresh))
2168 2199 metPhase[phDerAux] = numpy.nan
2169 2200
2170 2201 #--------------------------METEOR DETECTION -----------------------------------------
2171 2202 indMet = numpy.where(numpy.any(metBool,axis=1))[0]
2172 2203
2173 2204 for p in numpy.arange(nPairs):
2174 2205 phase = metPhase[p,:,:]
2175 2206 phDer = metDer[p,:,:]
2176 2207
2177 2208 for h in indMet:
2178 2209 height = heightList[h]
2179 2210 phase1 = phase[h,:] #82
2180 2211 phDer1 = phDer[h,:]
2181 2212
2182 2213 phase1[~numpy.isnan(phase1)] = numpy.unwrap(phase1[~numpy.isnan(phase1)]) #Unwrap
2183 2214
2184 2215 indValid = numpy.where(~numpy.isnan(phase1))[0]
2185 2216 initMet = indValid[0]
2186 2217 endMet = 0
2187 2218
2188 2219 for i in range(len(indValid)-1):
2189 2220
2190 2221 #Time difference
2191 2222 inow = indValid[i]
2192 2223 inext = indValid[i+1]
2193 2224 idiff = inext - inow
2194 2225 #Phase difference
2195 2226 phDiff = numpy.abs(phase1[inext] - phase1[inow])
2196 2227
2197 2228 if idiff>sec or phDiff>numpy.pi/4 or inext==indValid[-1]: #End of Meteor
2198 2229 sizeTrail = inow - initMet + 1
2199 2230 if sizeTrail>3*sec: #Too short meteors
2200 2231 x = numpy.arange(initMet,inow+1)*ippSeconds
2201 2232 y = phase1[initMet:inow+1]
2202 2233 ynnan = ~numpy.isnan(y)
2203 2234 x = x[ynnan]
2204 2235 y = y[ynnan]
2205 2236 slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
2206 2237 ylin = x*slope + intercept
2207 2238 rsq = r_value**2
2208 2239 if rsq > 0.5:
2209 2240 vel = slope#*height*1000/(k*d)
2210 2241 estAux = numpy.array([utctime,p,height, vel, rsq])
2211 2242 meteorList.append(estAux)
2212 2243 initMet = inext
2213 2244 metArray2 = numpy.array(meteorList)
2214 2245
2215 2246 return metArray2
2216 2247
2217 2248 def __calculateAzimuth1(self, rx_location, pairslist, azimuth0):
2218 2249
2219 2250 azimuth1 = numpy.zeros(len(pairslist))
2220 2251 dist = numpy.zeros(len(pairslist))
2221 2252
2222 2253 for i in range(len(rx_location)):
2223 2254 ch0 = pairslist[i][0]
2224 2255 ch1 = pairslist[i][1]
2225 2256
2226 2257 diffX = rx_location[ch0][0] - rx_location[ch1][0]
2227 2258 diffY = rx_location[ch0][1] - rx_location[ch1][1]
2228 2259 azimuth1[i] = numpy.arctan2(diffY,diffX)*180/numpy.pi
2229 2260 dist[i] = numpy.sqrt(diffX**2 + diffY**2)
2230 2261
2231 2262 azimuth1 -= azimuth0
2232 2263 return azimuth1, dist
2233 2264
2234 2265 def techniqueNSM_DBS(self, **kwargs):
2235 2266 metArray = kwargs['metArray']
2236 2267 heightList = kwargs['heightList']
2237 2268 timeList = kwargs['timeList']
2238 2269 zenithList = kwargs['zenithList']
2239 2270 nChan = numpy.max(cmet) + 1
2240 2271 nHeights = len(heightList)
2241 2272
2242 2273 utctime = metArray[:,0]
2243 2274 cmet = metArray[:,1]
2244 2275 hmet = metArray1[:,3].astype(int)
2245 2276 h1met = heightList[hmet]*zenithList[cmet]
2246 2277 vmet = metArray1[:,5]
2247 2278
2248 2279 for i in range(nHeights - 1):
2249 2280 hmin = heightList[i]
2250 2281 hmax = heightList[i + 1]
2251 2282
2252 2283 vthisH = vmet[(h1met>=hmin) & (h1met<hmax)]
2253 2284
2254 2285
2255 2286
2256 2287 return data_output
2257 2288
2258 2289 def run(self, dataOut, technique, **kwargs):
2259 2290
2260 2291 param = dataOut.data_param
2261 2292 if dataOut.abscissaList != None:
2262 2293 absc = dataOut.abscissaList[:-1]
2263 2294 noise = dataOut.noise
2264 2295 heightList = dataOut.heightList
2265 2296 SNR = dataOut.data_SNR
2266 2297
2267 2298 if technique == 'DBS':
2268 2299
2269 2300 kwargs['velRadial'] = param[:,1,:] #Radial velocity
2270 2301 kwargs['heightList'] = heightList
2271 2302 kwargs['SNR'] = SNR
2272 2303
2273 2304 dataOut.data_output, dataOut.heightList, dataOut.data_SNR = self.techniqueDBS(kwargs) #DBS Function
2274 2305 dataOut.utctimeInit = dataOut.utctime
2275 2306 dataOut.outputInterval = dataOut.paramInterval
2276 2307
2277 2308 elif technique == 'SA':
2278 2309
2279 2310 #Parameters
2280 2311 # position_x = kwargs['positionX']
2281 2312 # position_y = kwargs['positionY']
2282 2313 # azimuth = kwargs['azimuth']
2283 2314 #
2284 2315 # if kwargs.has_key('crosspairsList'):
2285 2316 # pairs = kwargs['crosspairsList']
2286 2317 # else:
2287 2318 # pairs = None
2288 2319 #
2289 2320 # if kwargs.has_key('correctFactor'):
2290 2321 # correctFactor = kwargs['correctFactor']
2291 2322 # else:
2292 2323 # correctFactor = 1
2293 2324
2294 2325 # tau = dataOut.data_param
2295 2326 # _lambda = dataOut.C/dataOut.frequency
2296 2327 # pairsList = dataOut.groupList
2297 2328 # nChannels = dataOut.nChannels
2298 2329
2299 2330 kwargs['groupList'] = dataOut.groupList
2300 2331 kwargs['tau'] = dataOut.data_param
2301 2332 kwargs['_lambda'] = dataOut.C/dataOut.frequency
2302 2333 # dataOut.data_output = self.techniqueSA(pairs, pairsList, nChannels, tau, azimuth, _lambda, position_x, position_y, absc, correctFactor)
2303 2334 dataOut.data_output = self.techniqueSA(kwargs)
2304 2335 dataOut.utctimeInit = dataOut.utctime
2305 2336 dataOut.outputInterval = dataOut.timeInterval
2306 2337
2307 2338 elif technique == 'Meteors':
2308 2339 dataOut.flagNoData = True
2309 2340 self.__dataReady = False
2310 2341
2311 2342 if kwargs.has_key('nHours'):
2312 2343 nHours = kwargs['nHours']
2313 2344 else:
2314 2345 nHours = 1
2315 2346
2316 2347 if kwargs.has_key('meteorsPerBin'):
2317 2348 meteorThresh = kwargs['meteorsPerBin']
2318 2349 else:
2319 2350 meteorThresh = 6
2320 2351
2321 2352 if kwargs.has_key('hmin'):
2322 2353 hmin = kwargs['hmin']
2323 2354 else: hmin = 70
2324 2355 if kwargs.has_key('hmax'):
2325 2356 hmax = kwargs['hmax']
2326 2357 else: hmax = 110
2327 2358
2328 2359 dataOut.outputInterval = nHours*3600
2329 2360
2330 2361 if self.__isConfig == False:
2331 2362 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2332 2363 #Get Initial LTC time
2333 2364 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2334 2365 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2335 2366
2336 2367 self.__isConfig = True
2337 2368
2338 2369 if self.__buffer == None:
2339 2370 self.__buffer = dataOut.data_param
2340 2371 self.__firstdata = copy.copy(dataOut)
2341 2372
2342 2373 else:
2343 2374 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2344 2375
2345 2376 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2346 2377
2347 2378 if self.__dataReady:
2348 2379 dataOut.utctimeInit = self.__initime
2349 2380
2350 2381 self.__initime += dataOut.outputInterval #to erase time offset
2351 2382
2352 2383 dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax)
2353 2384 dataOut.flagNoData = False
2354 2385 self.__buffer = None
2355 2386
2356 2387 elif technique == 'Meteors1':
2357 2388 dataOut.flagNoData = True
2358 2389 self.__dataReady = False
2359 2390
2360 2391 if kwargs.has_key('nMins'):
2361 2392 nMins = kwargs['nMins']
2362 2393 else: nMins = 20
2363 2394 if kwargs.has_key('rx_location'):
2364 2395 rx_location = kwargs['rx_location']
2365 2396 else: rx_location = [(0,1),(1,1),(1,0)]
2366 2397 if kwargs.has_key('azimuth'):
2367 2398 azimuth = kwargs['azimuth']
2368 2399 else: azimuth = 51
2369 2400 if kwargs.has_key('dfactor'):
2370 2401 dfactor = kwargs['dfactor']
2371 2402 if kwargs.has_key('mode'):
2372 2403 mode = kwargs['mode']
2373 2404 else: mode = 'SA'
2374 2405
2375 2406 #Borrar luego esto
2376 2407 if dataOut.groupList == None:
2377 2408 dataOut.groupList = [(0,1),(0,2),(1,2)]
2378 2409 groupList = dataOut.groupList
2379 2410 C = 3e8
2380 2411 freq = 50e6
2381 2412 lamb = C/freq
2382 2413 k = 2*numpy.pi/lamb
2383 2414
2384 2415 timeList = dataOut.abscissaList
2385 2416 heightList = dataOut.heightList
2386 2417
2387 2418 if self.__isConfig == False:
2388 2419 dataOut.outputInterval = nMins*60
2389 2420 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
2390 2421 #Get Initial LTC time
2391 2422 initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
2392 2423 minuteAux = initime.minute
2393 2424 minuteNew = int(numpy.floor(minuteAux/nMins)*nMins)
2394 2425 self.__initime = (initime.replace(minute = minuteNew, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
2395 2426
2396 2427 self.__isConfig = True
2397 2428
2398 2429 if self.__buffer == None:
2399 2430 self.__buffer = dataOut.data_param
2400 2431 self.__firstdata = copy.copy(dataOut)
2401 2432
2402 2433 else:
2403 2434 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
2404 2435
2405 2436 self.__checkTime(dataOut.utctime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
2406 2437
2407 2438 if self.__dataReady:
2408 2439 dataOut.utctimeInit = self.__initime
2409 2440 self.__initime += dataOut.outputInterval #to erase time offset
2410 2441
2411 2442 metArray = self.__buffer
2412 2443 if mode == 'SA':
2413 2444 dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList)
2414 2445 elif mode == 'DBS':
2415 2446 dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList)
2416 2447 dataOut.data_output = dataOut.data_output.T
2417 2448 dataOut.flagNoData = False
2418 2449 self.__buffer = None
2419 2450
2420 2451 return
2421 2452
2422 2453 class EWDriftsEstimation(Operation):
2423 2454
2424 2455 def __init__(self):
2425 2456 Operation.__init__(self)
2426 2457
2427 2458 def __correctValues(self, heiRang, phi, velRadial, SNR):
2428 2459 listPhi = phi.tolist()
2429 2460 maxid = listPhi.index(max(listPhi))
2430 2461 minid = listPhi.index(min(listPhi))
2431 2462
2432 2463 rango = range(len(phi))
2433 2464 # rango = numpy.delete(rango,maxid)
2434 2465
2435 2466 heiRang1 = heiRang*math.cos(phi[maxid])
2436 2467 heiRangAux = heiRang*math.cos(phi[minid])
2437 2468 indOut = (heiRang1 < heiRangAux[0]).nonzero()
2438 2469 heiRang1 = numpy.delete(heiRang1,indOut)
2439 2470
2440 2471 velRadial1 = numpy.zeros([len(phi),len(heiRang1)])
2441 2472 SNR1 = numpy.zeros([len(phi),len(heiRang1)])
2442 2473
2443 2474 for i in rango:
2444 2475 x = heiRang*math.cos(phi[i])
2445 2476 y1 = velRadial[i,:]
2446 2477 f1 = interpolate.interp1d(x,y1,kind = 'cubic')
2447 2478
2448 2479 x1 = heiRang1
2449 2480 y11 = f1(x1)
2450 2481
2451 2482 y2 = SNR[i,:]
2452 2483 f2 = interpolate.interp1d(x,y2,kind = 'cubic')
2453 2484 y21 = f2(x1)
2454 2485
2455 2486 velRadial1[i,:] = y11
2456 2487 SNR1[i,:] = y21
2457 2488
2458 2489 return heiRang1, velRadial1, SNR1
2459 2490
2460 2491 def run(self, dataOut, zenith, zenithCorrection):
2461 2492 heiRang = dataOut.heightList
2462 2493 velRadial = dataOut.data_param[:,3,:]
2463 2494 SNR = dataOut.data_SNR
2464 2495
2465 2496 zenith = numpy.array(zenith)
2466 2497 zenith -= zenithCorrection
2467 2498 zenith *= numpy.pi/180
2468 2499
2469 2500 heiRang1, velRadial1, SNR1 = self.__correctValues(heiRang, numpy.abs(zenith), velRadial, SNR)
2470 2501
2471 2502 alp = zenith[0]
2472 2503 bet = zenith[1]
2473 2504
2474 2505 w_w = velRadial1[0,:]
2475 2506 w_e = velRadial1[1,:]
2476 2507
2477 2508 w = (w_w*numpy.sin(bet) - w_e*numpy.sin(alp))/(numpy.cos(alp)*numpy.sin(bet) - numpy.cos(bet)*numpy.sin(alp))
2478 2509 u = (w_w*numpy.cos(bet) - w_e*numpy.cos(alp))/(numpy.sin(alp)*numpy.cos(bet) - numpy.sin(bet)*numpy.cos(alp))
2479 2510
2480 2511 winds = numpy.vstack((u,w))
2481 2512
2482 2513 dataOut.heightList = heiRang1
2483 2514 dataOut.data_output = winds
2484 2515 dataOut.data_SNR = SNR1
2485 2516
2486 2517 dataOut.utctimeInit = dataOut.utctime
2487 2518 dataOut.outputInterval = dataOut.timeInterval
2488 2519 return
2489 2520
2490 2521 #--------------- Non Specular Meteor ----------------
2491 2522
2492 2523 class NonSpecularMeteorDetection(Operation):
2493 2524
2494 2525 def run(self, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False):
2495 2526 data_acf = self.dataOut.data_pre[0]
2496 2527 data_ccf = self.dataOut.data_pre[1]
2497 2528
2498 2529 lamb = self.dataOut.C/self.dataOut.frequency
2499 2530 tSamp = self.dataOut.ippSeconds*self.dataOut.nCohInt
2500 2531 paramInterval = self.dataOut.paramInterval
2501 2532
2502 2533 nChannels = data_acf.shape[0]
2503 2534 nLags = data_acf.shape[1]
2504 2535 nProfiles = data_acf.shape[2]
2505 2536 nHeights = self.dataOut.nHeights
2506 2537 nCohInt = self.dataOut.nCohInt
2507 2538 sec = numpy.round(nProfiles/self.dataOut.paramInterval)
2508 2539 heightList = self.dataOut.heightList
2509 2540 ippSeconds = self.dataOut.ippSeconds*self.dataOut.nCohInt*self.dataOut.nAvg
2510 2541 utctime = self.dataOut.utctime
2511 2542
2512 2543 self.dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds)
2513 2544
2514 2545 #------------------------ SNR --------------------------------------
2515 2546 power = data_acf[:,0,:,:].real
2516 2547 noise = numpy.zeros(nChannels)
2517 2548 SNR = numpy.zeros(power.shape)
2518 2549 for i in range(nChannels):
2519 2550 noise[i] = hildebrand_sekhon(power[i,:], nCohInt)
2520 2551 SNR[i] = (power[i]-noise[i])/noise[i]
2521 2552 SNRm = numpy.nanmean(SNR, axis = 0)
2522 2553 SNRdB = 10*numpy.log10(SNR)
2523 2554
2524 2555 if mode == 'SA':
2525 2556 nPairs = data_ccf.shape[0]
2526 2557 #---------------------- Coherence and Phase --------------------------
2527 2558 phase = numpy.zeros(data_ccf[:,0,:,:].shape)
2528 2559 # phase1 = numpy.copy(phase)
2529 2560 coh1 = numpy.zeros(data_ccf[:,0,:,:].shape)
2530 2561
2531 2562 for p in range(nPairs):
2532 2563 ch0 = self.dataOut.groupList[p][0]
2533 2564 ch1 = self.dataOut.groupList[p][1]
2534 2565 ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:])
2535 2566 phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter
2536 2567 # phase1[p,:,:] = numpy.angle(ccf) #median filter
2537 2568 coh1[p,:,:] = ndimage.median_filter(numpy.abs(ccf), 5) #median filter
2538 2569 # coh1[p,:,:] = numpy.abs(ccf) #median filter
2539 2570 coh = numpy.nanmax(coh1, axis = 0)
2540 2571 # struc = numpy.ones((5,1))
2541 2572 # coh = ndimage.morphology.grey_dilation(coh, size=(10,1))
2542 2573 #---------------------- Radial Velocity ----------------------------
2543 2574 phaseAux = numpy.mean(numpy.angle(data_acf[:,1,:,:]), axis = 0)
2544 2575 velRad = phaseAux*lamb/(4*numpy.pi*tSamp)
2545 2576
2546 2577 if allData:
2547 2578 boolMetFin = ~numpy.isnan(SNRm)
2548 2579 # coh[:-1,:] = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2549 2580 else:
2550 2581 #------------------------ Meteor mask ---------------------------------
2551 2582 # #SNR mask
2552 2583 # boolMet = (SNRdB>SNRthresh)#|(~numpy.isnan(SNRdB))
2553 2584 #
2554 2585 # #Erase small objects
2555 2586 # boolMet1 = self.__erase_small(boolMet, 2*sec, 5)
2556 2587 #
2557 2588 # auxEEJ = numpy.sum(boolMet1,axis=0)
2558 2589 # indOver = auxEEJ>nProfiles*0.8 #Use this later
2559 2590 # indEEJ = numpy.where(indOver)[0]
2560 2591 # indNEEJ = numpy.where(~indOver)[0]
2561 2592 #
2562 2593 # boolMetFin = boolMet1
2563 2594 #
2564 2595 # if indEEJ.size > 0:
2565 2596 # boolMet1[:,indEEJ] = False #Erase heights with EEJ
2566 2597 #
2567 2598 # boolMet2 = coh > cohThresh
2568 2599 # boolMet2 = self.__erase_small(boolMet2, 2*sec,5)
2569 2600 #
2570 2601 # #Final Meteor mask
2571 2602 # boolMetFin = boolMet1|boolMet2
2572 2603
2573 2604 #Coherence mask
2574 2605 boolMet1 = coh > 0.75
2575 2606 struc = numpy.ones((30,1))
2576 2607 boolMet1 = ndimage.morphology.binary_dilation(boolMet1, structure=struc)
2577 2608
2578 2609 #Derivative mask
2579 2610 derPhase = numpy.nanmean(numpy.abs(phase[:,1:,:] - phase[:,:-1,:]),axis=0)
2580 2611 boolMet2 = derPhase < 0.2
2581 2612 # boolMet2 = ndimage.morphology.binary_opening(boolMet2)
2582 2613 # boolMet2 = ndimage.morphology.binary_closing(boolMet2, structure = numpy.ones((10,1)))
2583 2614 boolMet2 = ndimage.median_filter(boolMet2,size=5)
2584 2615 boolMet2 = numpy.vstack((boolMet2,numpy.full((1,nHeights), True, dtype=bool)))
2585 2616 # #Final mask
2586 2617 # boolMetFin = boolMet2
2587 2618 boolMetFin = boolMet1&boolMet2
2588 2619 # boolMetFin = ndimage.morphology.binary_dilation(boolMetFin)
2589 2620 #Creating data_param
2590 2621 coordMet = numpy.where(boolMetFin)
2591 2622
2592 2623 tmet = coordMet[0]
2593 2624 hmet = coordMet[1]
2594 2625
2595 2626 data_param = numpy.zeros((tmet.size, 6 + nPairs))
2596 2627 data_param[:,0] = utctime
2597 2628 data_param[:,1] = tmet
2598 2629 data_param[:,2] = hmet
2599 2630 data_param[:,3] = SNRm[tmet,hmet]
2600 2631 data_param[:,4] = velRad[tmet,hmet]
2601 2632 data_param[:,5] = coh[tmet,hmet]
2602 2633 data_param[:,6:] = phase[:,tmet,hmet].T
2603 2634
2604 2635 elif mode == 'DBS':
2605 2636 self.dataOut.groupList = numpy.arange(nChannels)
2606 2637
2607 2638 #Radial Velocities
2608 2639 # phase = numpy.angle(data_acf[:,1,:,:])
2609 2640 phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1))
2610 2641 velRad = phase*lamb/(4*numpy.pi*tSamp)
2611 2642
2612 2643 #Spectral width
2613 2644 acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1))
2614 2645 acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1))
2615 2646
2616 2647 spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2))
2617 2648 # velRad = ndimage.median_filter(velRad, size = (1,5,1))
2618 2649 if allData:
2619 2650 boolMetFin = ~numpy.isnan(SNRdB)
2620 2651 else:
2621 2652 #SNR
2622 2653 boolMet1 = (SNRdB>SNRthresh) #SNR mask
2623 2654 boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5))
2624 2655
2625 2656 #Radial velocity
2626 2657 boolMet2 = numpy.abs(velRad) < 30
2627 2658 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5))
2628 2659
2629 2660 #Spectral Width
2630 2661 boolMet3 = spcWidth < 30
2631 2662 boolMet3 = ndimage.median_filter(boolMet3, (1,5,5))
2632 2663 # boolMetFin = self.__erase_small(boolMet1, 10,5)
2633 2664 boolMetFin = boolMet1&boolMet2&boolMet3
2634 2665
2635 2666 #Creating data_param
2636 2667 coordMet = numpy.where(boolMetFin)
2637 2668
2638 2669 cmet = coordMet[0]
2639 2670 tmet = coordMet[1]
2640 2671 hmet = coordMet[2]
2641 2672
2642 2673 data_param = numpy.zeros((tmet.size, 7))
2643 2674 data_param[:,0] = utctime
2644 2675 data_param[:,1] = cmet
2645 2676 data_param[:,2] = tmet
2646 2677 data_param[:,3] = hmet
2647 2678 data_param[:,4] = SNR[cmet,tmet,hmet].T
2648 2679 data_param[:,5] = velRad[cmet,tmet,hmet].T
2649 2680 data_param[:,6] = spcWidth[cmet,tmet,hmet].T
2650 2681
2651 2682 # self.dataOut.data_param = data_int
2652 2683 if len(data_param) == 0:
2653 2684 self.dataOut.flagNoData = True
2654 2685 else:
2655 2686 self.dataOut.data_param = data_param
2656 2687
2657 2688 def __erase_small(self, binArray, threshX, threshY):
2658 2689 labarray, numfeat = ndimage.measurements.label(binArray)
2659 2690 binArray1 = numpy.copy(binArray)
2660 2691
2661 2692 for i in range(1,numfeat + 1):
2662 2693 auxBin = (labarray==i)
2663 2694 auxSize = auxBin.sum()
2664 2695
2665 2696 x,y = numpy.where(auxBin)
2666 2697 widthX = x.max() - x.min()
2667 2698 widthY = y.max() - y.min()
2668 2699
2669 2700 #width X: 3 seg -> 12.5*3
2670 2701 #width Y:
2671 2702
2672 2703 if (auxSize < 50) or (widthX < threshX) or (widthY < threshY):
2673 2704 binArray1[auxBin] = False
2674 2705
2675 2706 return binArray1
2676 2707
2677 2708 #--------------- Specular Meteor ----------------
2678 2709
2679 2710 class SMDetection(Operation):
2680 2711 '''
2681 2712 Function DetectMeteors()
2682 2713 Project developed with paper:
2683 2714 HOLDSWORTH ET AL. 2004
2684 2715
2685 2716 Input:
2686 2717 self.dataOut.data_pre
2687 2718
2688 2719 centerReceiverIndex: From the channels, which is the center receiver
2689 2720
2690 2721 hei_ref: Height reference for the Beacon signal extraction
2691 2722 tauindex:
2692 2723 predefinedPhaseShifts: Predefined phase offset for the voltge signals
2693 2724
2694 2725 cohDetection: Whether to user Coherent detection or not
2695 2726 cohDet_timeStep: Coherent Detection calculation time step
2696 2727 cohDet_thresh: Coherent Detection phase threshold to correct phases
2697 2728
2698 2729 noise_timeStep: Noise calculation time step
2699 2730 noise_multiple: Noise multiple to define signal threshold
2700 2731
2701 2732 multDet_timeLimit: Multiple Detection Removal time limit in seconds
2702 2733 multDet_rangeLimit: Multiple Detection Removal range limit in km
2703 2734
2704 2735 phaseThresh: Maximum phase difference between receiver to be consider a meteor
2705 2736 SNRThresh: Minimum SNR threshold of the meteor signal to be consider a meteor
2706 2737
2707 2738 hmin: Minimum Height of the meteor to use it in the further wind estimations
2708 2739 hmax: Maximum Height of the meteor to use it in the further wind estimations
2709 2740 azimuth: Azimuth angle correction
2710 2741
2711 2742 Affected:
2712 2743 self.dataOut.data_param
2713 2744
2714 2745 Rejection Criteria (Errors):
2715 2746 0: No error; analysis OK
2716 2747 1: SNR < SNR threshold
2717 2748 2: angle of arrival (AOA) ambiguously determined
2718 2749 3: AOA estimate not feasible
2719 2750 4: Large difference in AOAs obtained from different antenna baselines
2720 2751 5: echo at start or end of time series
2721 2752 6: echo less than 5 examples long; too short for analysis
2722 2753 7: echo rise exceeds 0.3s
2723 2754 8: echo decay time less than twice rise time
2724 2755 9: large power level before echo
2725 2756 10: large power level after echo
2726 2757 11: poor fit to amplitude for estimation of decay time
2727 2758 12: poor fit to CCF phase variation for estimation of radial drift velocity
2728 2759 13: height unresolvable echo: not valid height within 70 to 110 km
2729 2760 14: height ambiguous echo: more then one possible height within 70 to 110 km
2730 2761 15: radial drift velocity or projected horizontal velocity exceeds 200 m/s
2731 2762 16: oscilatory echo, indicating event most likely not an underdense echo
2732 2763
2733 2764 17: phase difference in meteor Reestimation
2734 2765
2735 2766 Data Storage:
2736 2767 Meteors for Wind Estimation (8):
2737 2768 Utc Time | Range Height
2738 2769 Azimuth Zenith errorCosDir
2739 2770 VelRad errorVelRad
2740 2771 Phase0 Phase1 Phase2 Phase3
2741 2772 TypeError
2742 2773
2743 2774 '''
2744 2775
2745 2776 def run(self, dataOut, hei_ref = None, tauindex = 0,
2746 2777 phaseOffsets = None,
2747 2778 cohDetection = False, cohDet_timeStep = 1, cohDet_thresh = 25,
2748 2779 noise_timeStep = 4, noise_multiple = 4,
2749 2780 multDet_timeLimit = 1, multDet_rangeLimit = 3,
2750 2781 phaseThresh = 20, SNRThresh = 5,
2751 2782 hmin = 50, hmax=150, azimuth = 0,
2752 2783 channelPositions = None) :
2753 2784
2754 2785
2755 2786 #Getting Pairslist
2756 2787 if channelPositions == None:
2757 2788 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
2758 2789 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
2759 2790 meteorOps = SMOperations()
2760 2791 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
2761 2792 heiRang = dataOut.getHeiRange()
2762 2793 #Get Beacon signal - No Beacon signal anymore
2763 2794 # newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex])
2764 2795 #
2765 2796 # if hei_ref != None:
2766 2797 # newheis = numpy.where(self.dataOut.heightList>hei_ref)
2767 2798 #
2768 2799
2769 2800
2770 2801 #****************REMOVING HARDWARE PHASE DIFFERENCES***************
2771 2802 # see if the user put in pre defined phase shifts
2772 2803 voltsPShift = dataOut.data_pre.copy()
2773 2804
2774 2805 # if predefinedPhaseShifts != None:
2775 2806 # hardwarePhaseShifts = numpy.array(predefinedPhaseShifts)*numpy.pi/180
2776 2807 #
2777 2808 # # elif beaconPhaseShifts:
2778 2809 # # #get hardware phase shifts using beacon signal
2779 2810 # # hardwarePhaseShifts = self.__getHardwarePhaseDiff(self.dataOut.data_pre, pairslist, newheis, 10)
2780 2811 # # hardwarePhaseShifts = numpy.insert(hardwarePhaseShifts,centerReceiverIndex,0)
2781 2812 #
2782 2813 # else:
2783 2814 # hardwarePhaseShifts = numpy.zeros(5)
2784 2815 #
2785 2816 # voltsPShift = numpy.zeros((self.dataOut.data_pre.shape[0],self.dataOut.data_pre.shape[1],self.dataOut.data_pre.shape[2]), dtype = 'complex')
2786 2817 # for i in range(self.dataOut.data_pre.shape[0]):
2787 2818 # voltsPShift[i,:,:] = self.__shiftPhase(self.dataOut.data_pre[i,:,:], hardwarePhaseShifts[i])
2788 2819
2789 2820 #******************END OF REMOVING HARDWARE PHASE DIFFERENCES*********
2790 2821
2791 2822 #Remove DC
2792 2823 voltsDC = numpy.mean(voltsPShift,1)
2793 2824 voltsDC = numpy.mean(voltsDC,1)
2794 2825 for i in range(voltsDC.shape[0]):
2795 2826 voltsPShift[i] = voltsPShift[i] - voltsDC[i]
2796 2827
2797 2828 #Don't considerate last heights, theyre used to calculate Hardware Phase Shift
2798 2829 # voltsPShift = voltsPShift[:,:,:newheis[0][0]]
2799 2830
2800 2831 #************ FIND POWER OF DATA W/COH OR NON COH DETECTION (3.4) **********
2801 2832 #Coherent Detection
2802 2833 if cohDetection:
2803 2834 #use coherent detection to get the net power
2804 2835 cohDet_thresh = cohDet_thresh*numpy.pi/180
2805 2836 voltsPShift = self.__coherentDetection(voltsPShift, cohDet_timeStep, dataOut.timeInterval, pairslist0, cohDet_thresh)
2806 2837
2807 2838 #Non-coherent detection!
2808 2839 powerNet = numpy.nansum(numpy.abs(voltsPShift[:,:,:])**2,0)
2809 2840 #********** END OF COH/NON-COH POWER CALCULATION**********************
2810 2841
2811 2842 #********** FIND THE NOISE LEVEL AND POSSIBLE METEORS ****************
2812 2843 #Get noise
2813 2844 noise, noise1 = self.__getNoise(powerNet, noise_timeStep, dataOut.timeInterval)
2814 2845 # noise = self.getNoise1(powerNet, noise_timeStep, self.dataOut.timeInterval)
2815 2846 #Get signal threshold
2816 2847 signalThresh = noise_multiple*noise
2817 2848 #Meteor echoes detection
2818 2849 listMeteors = self.__findMeteors(powerNet, signalThresh)
2819 2850 #******* END OF NOISE LEVEL AND POSSIBLE METEORS CACULATION **********
2820 2851
2821 2852 #************** REMOVE MULTIPLE DETECTIONS (3.5) ***************************
2822 2853 #Parameters
2823 2854 heiRange = dataOut.getHeiRange()
2824 2855 rangeInterval = heiRange[1] - heiRange[0]
2825 2856 rangeLimit = multDet_rangeLimit/rangeInterval
2826 2857 timeLimit = multDet_timeLimit/dataOut.timeInterval
2827 2858 #Multiple detection removals
2828 2859 listMeteors1 = self.__removeMultipleDetections(listMeteors, rangeLimit, timeLimit)
2829 2860 #************ END OF REMOVE MULTIPLE DETECTIONS **********************
2830 2861
2831 2862 #********************* METEOR REESTIMATION (3.7, 3.8, 3.9, 3.10) ********************
2832 2863 #Parameters
2833 2864 phaseThresh = phaseThresh*numpy.pi/180
2834 2865 thresh = [phaseThresh, noise_multiple, SNRThresh]
2835 2866 #Meteor reestimation (Errors N 1, 6, 12, 17)
2836 2867 listMeteors2, listMeteorsPower, listMeteorsVolts = self.__meteorReestimation(listMeteors1, voltsPShift, pairslist0, thresh, noise, dataOut.timeInterval, dataOut.frequency)
2837 2868 # listMeteors2, listMeteorsPower, listMeteorsVolts = self.meteorReestimation3(listMeteors2, listMeteorsPower, listMeteorsVolts, voltsPShift, pairslist, thresh, noise)
2838 2869 #Estimation of decay times (Errors N 7, 8, 11)
2839 2870 listMeteors3 = self.__estimateDecayTime(listMeteors2, listMeteorsPower, dataOut.timeInterval, dataOut.frequency)
2840 2871 #******************* END OF METEOR REESTIMATION *******************
2841 2872
2842 2873 #********************* METEOR PARAMETERS CALCULATION (3.11, 3.12, 3.13) **************************
2843 2874 #Calculating Radial Velocity (Error N 15)
2844 2875 radialStdThresh = 10
2845 2876 listMeteors4 = self.__getRadialVelocity(listMeteors3, listMeteorsVolts, radialStdThresh, pairslist0, dataOut.timeInterval)
2846 2877
2847 2878 if len(listMeteors4) > 0:
2848 2879 #Setting New Array
2849 2880 date = dataOut.utctime
2850 2881 arrayParameters = self.__setNewArrays(listMeteors4, date, heiRang)
2851 2882
2852 2883 #Correcting phase offset
2853 2884 if phaseOffsets != None:
2854 2885 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
2855 2886 arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
2856 2887
2857 2888 #Second Pairslist
2858 2889 pairsList = []
2859 2890 pairx = (0,1)
2860 2891 pairy = (2,3)
2861 2892 pairsList.append(pairx)
2862 2893 pairsList.append(pairy)
2863 2894
2864 2895 jph = numpy.array([0,0,0,0])
2865 2896 h = (hmin,hmax)
2866 2897 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
2867 2898
2868 2899 # #Calculate AOA (Error N 3, 4)
2869 2900 # #JONES ET AL. 1998
2870 2901 # error = arrayParameters[:,-1]
2871 2902 # AOAthresh = numpy.pi/8
2872 2903 # phases = -arrayParameters[:,9:13]
2873 2904 # arrayParameters[:,4:7], arrayParameters[:,-1] = meteorOps.getAOA(phases, pairsList, error, AOAthresh, azimuth)
2874 2905 #
2875 2906 # #Calculate Heights (Error N 13 and 14)
2876 2907 # error = arrayParameters[:,-1]
2877 2908 # Ranges = arrayParameters[:,2]
2878 2909 # zenith = arrayParameters[:,5]
2879 2910 # arrayParameters[:,3], arrayParameters[:,-1] = meteorOps.getHeights(Ranges, zenith, error, hmin, hmax)
2880 2911 # error = arrayParameters[:,-1]
2881 2912 #********************* END OF PARAMETERS CALCULATION **************************
2882 2913
2883 2914 #***************************+ PASS DATA TO NEXT STEP **********************
2884 2915 # arrayFinal = arrayParameters.reshape((1,arrayParameters.shape[0],arrayParameters.shape[1]))
2885 2916 dataOut.data_param = arrayParameters
2886 2917
2887 2918 if arrayParameters == None:
2888 2919 dataOut.flagNoData = True
2889 2920 else:
2890 2921 dataOut.flagNoData = True
2891 2922
2892 2923 return
2893 2924
2894 2925 def __getHardwarePhaseDiff(self, voltage0, pairslist, newheis, n):
2895 2926
2896 2927 minIndex = min(newheis[0])
2897 2928 maxIndex = max(newheis[0])
2898 2929
2899 2930 voltage = voltage0[:,:,minIndex:maxIndex+1]
2900 2931 nLength = voltage.shape[1]/n
2901 2932 nMin = 0
2902 2933 nMax = 0
2903 2934 phaseOffset = numpy.zeros((len(pairslist),n))
2904 2935
2905 2936 for i in range(n):
2906 2937 nMax += nLength
2907 2938 phaseCCF = -numpy.angle(self.__calculateCCF(voltage[:,nMin:nMax,:], pairslist, [0]))
2908 2939 phaseCCF = numpy.mean(phaseCCF, axis = 2)
2909 2940 phaseOffset[:,i] = phaseCCF.transpose()
2910 2941 nMin = nMax
2911 2942 # phaseDiff, phaseArrival = self.estimatePhaseDifference(voltage, pairslist)
2912 2943
2913 2944 #Remove Outliers
2914 2945 factor = 2
2915 2946 wt = phaseOffset - signal.medfilt(phaseOffset,(1,5))
2916 2947 dw = numpy.std(wt,axis = 1)
2917 2948 dw = dw.reshape((dw.size,1))
2918 2949 ind = numpy.where(numpy.logical_or(wt>dw*factor,wt<-dw*factor))
2919 2950 phaseOffset[ind] = numpy.nan
2920 2951 phaseOffset = stats.nanmean(phaseOffset, axis=1)
2921 2952
2922 2953 return phaseOffset
2923 2954
2924 2955 def __shiftPhase(self, data, phaseShift):
2925 2956 #this will shift the phase of a complex number
2926 2957 dataShifted = numpy.abs(data) * numpy.exp((numpy.angle(data)+phaseShift)*1j)
2927 2958 return dataShifted
2928 2959
2929 2960 def __estimatePhaseDifference(self, array, pairslist):
2930 2961 nChannel = array.shape[0]
2931 2962 nHeights = array.shape[2]
2932 2963 numPairs = len(pairslist)
2933 2964 # phaseCCF = numpy.zeros((nChannel, 5, nHeights))
2934 2965 phaseCCF = numpy.angle(self.__calculateCCF(array, pairslist, [-2,-1,0,1,2]))
2935 2966
2936 2967 #Correct phases
2937 2968 derPhaseCCF = phaseCCF[:,1:,:] - phaseCCF[:,0:-1,:]
2938 2969 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
2939 2970
2940 2971 if indDer[0].shape[0] > 0:
2941 2972 for i in range(indDer[0].shape[0]):
2942 2973 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i],indDer[2][i]])
2943 2974 phaseCCF[indDer[0][i],indDer[1][i]+1:,:] += signo*2*numpy.pi
2944 2975
2945 2976 # for j in range(numSides):
2946 2977 # phaseCCFAux = self.calculateCCF(arrayCenter, arraySides[j,:,:], [-2,1,0,1,2])
2947 2978 # phaseCCF[j,:,:] = numpy.angle(phaseCCFAux)
2948 2979 #
2949 2980 #Linear
2950 2981 phaseInt = numpy.zeros((numPairs,1))
2951 2982 angAllCCF = phaseCCF[:,[0,1,3,4],0]
2952 2983 for j in range(numPairs):
2953 2984 fit = stats.linregress([-2,-1,1,2],angAllCCF[j,:])
2954 2985 phaseInt[j] = fit[1]
2955 2986 #Phase Differences
2956 2987 phaseDiff = phaseInt - phaseCCF[:,2,:]
2957 2988 phaseArrival = phaseInt.reshape(phaseInt.size)
2958 2989
2959 2990 #Dealias
2960 2991 phaseArrival = numpy.angle(numpy.exp(1j*phaseArrival))
2961 2992 # indAlias = numpy.where(phaseArrival > numpy.pi)
2962 2993 # phaseArrival[indAlias] -= 2*numpy.pi
2963 2994 # indAlias = numpy.where(phaseArrival < -numpy.pi)
2964 2995 # phaseArrival[indAlias] += 2*numpy.pi
2965 2996
2966 2997 return phaseDiff, phaseArrival
2967 2998
2968 2999 def __coherentDetection(self, volts, timeSegment, timeInterval, pairslist, thresh):
2969 3000 #this function will run the coherent detection used in Holdworth et al. 2004 and return the net power
2970 3001 #find the phase shifts of each channel over 1 second intervals
2971 3002 #only look at ranges below the beacon signal
2972 3003 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
2973 3004 numBlocks = int(volts.shape[1]/numProfPerBlock)
2974 3005 numHeights = volts.shape[2]
2975 3006 nChannel = volts.shape[0]
2976 3007 voltsCohDet = volts.copy()
2977 3008
2978 3009 pairsarray = numpy.array(pairslist)
2979 3010 indSides = pairsarray[:,1]
2980 3011 # indSides = numpy.array(range(nChannel))
2981 3012 # indSides = numpy.delete(indSides, indCenter)
2982 3013 #
2983 3014 # listCenter = numpy.array_split(volts[indCenter,:,:], numBlocks, 0)
2984 3015 listBlocks = numpy.array_split(volts, numBlocks, 1)
2985 3016
2986 3017 startInd = 0
2987 3018 endInd = 0
2988 3019
2989 3020 for i in range(numBlocks):
2990 3021 startInd = endInd
2991 3022 endInd = endInd + listBlocks[i].shape[1]
2992 3023
2993 3024 arrayBlock = listBlocks[i]
2994 3025 # arrayBlockCenter = listCenter[i]
2995 3026
2996 3027 #Estimate the Phase Difference
2997 3028 phaseDiff, aux = self.__estimatePhaseDifference(arrayBlock, pairslist)
2998 3029 #Phase Difference RMS
2999 3030 arrayPhaseRMS = numpy.abs(phaseDiff)
3000 3031 phaseRMSaux = numpy.sum(arrayPhaseRMS < thresh,0)
3001 3032 indPhase = numpy.where(phaseRMSaux==4)
3002 3033 #Shifting
3003 3034 if indPhase[0].shape[0] > 0:
3004 3035 for j in range(indSides.size):
3005 3036 arrayBlock[indSides[j],:,indPhase] = self.__shiftPhase(arrayBlock[indSides[j],:,indPhase], phaseDiff[j,indPhase].transpose())
3006 3037 voltsCohDet[:,startInd:endInd,:] = arrayBlock
3007 3038
3008 3039 return voltsCohDet
3009 3040
3010 3041 def __calculateCCF(self, volts, pairslist ,laglist):
3011 3042
3012 3043 nHeights = volts.shape[2]
3013 3044 nPoints = volts.shape[1]
3014 3045 voltsCCF = numpy.zeros((len(pairslist), len(laglist), nHeights),dtype = 'complex')
3015 3046
3016 3047 for i in range(len(pairslist)):
3017 3048 volts1 = volts[pairslist[i][0]]
3018 3049 volts2 = volts[pairslist[i][1]]
3019 3050
3020 3051 for t in range(len(laglist)):
3021 3052 idxT = laglist[t]
3022 3053 if idxT >= 0:
3023 3054 vStacked = numpy.vstack((volts2[idxT:,:],
3024 3055 numpy.zeros((idxT, nHeights),dtype='complex')))
3025 3056 else:
3026 3057 vStacked = numpy.vstack((numpy.zeros((-idxT, nHeights),dtype='complex'),
3027 3058 volts2[:(nPoints + idxT),:]))
3028 3059 voltsCCF[i,t,:] = numpy.sum((numpy.conjugate(volts1)*vStacked),axis=0)
3029 3060
3030 3061 vStacked = None
3031 3062 return voltsCCF
3032 3063
3033 3064 def __getNoise(self, power, timeSegment, timeInterval):
3034 3065 numProfPerBlock = numpy.ceil(timeSegment/timeInterval)
3035 3066 numBlocks = int(power.shape[0]/numProfPerBlock)
3036 3067 numHeights = power.shape[1]
3037 3068
3038 3069 listPower = numpy.array_split(power, numBlocks, 0)
3039 3070 noise = numpy.zeros((power.shape[0], power.shape[1]))
3040 3071 noise1 = numpy.zeros((power.shape[0], power.shape[1]))
3041 3072
3042 3073 startInd = 0
3043 3074 endInd = 0
3044 3075
3045 3076 for i in range(numBlocks): #split por canal
3046 3077 startInd = endInd
3047 3078 endInd = endInd + listPower[i].shape[0]
3048 3079
3049 3080 arrayBlock = listPower[i]
3050 3081 noiseAux = numpy.mean(arrayBlock, 0)
3051 3082 # noiseAux = numpy.median(noiseAux)
3052 3083 # noiseAux = numpy.mean(arrayBlock)
3053 3084 noise[startInd:endInd,:] = noise[startInd:endInd,:] + noiseAux
3054 3085
3055 3086 noiseAux1 = numpy.mean(arrayBlock)
3056 3087 noise1[startInd:endInd,:] = noise1[startInd:endInd,:] + noiseAux1
3057 3088
3058 3089 return noise, noise1
3059 3090
3060 3091 def __findMeteors(self, power, thresh):
3061 3092 nProf = power.shape[0]
3062 3093 nHeights = power.shape[1]
3063 3094 listMeteors = []
3064 3095
3065 3096 for i in range(nHeights):
3066 3097 powerAux = power[:,i]
3067 3098 threshAux = thresh[:,i]
3068 3099
3069 3100 indUPthresh = numpy.where(powerAux > threshAux)[0]
3070 3101 indDNthresh = numpy.where(powerAux <= threshAux)[0]
3071 3102
3072 3103 j = 0
3073 3104
3074 3105 while (j < indUPthresh.size - 2):
3075 3106 if (indUPthresh[j + 2] == indUPthresh[j] + 2):
3076 3107 indDNAux = numpy.where(indDNthresh > indUPthresh[j])
3077 3108 indDNthresh = indDNthresh[indDNAux]
3078 3109
3079 3110 if (indDNthresh.size > 0):
3080 3111 indEnd = indDNthresh[0] - 1
3081 3112 indInit = indUPthresh[j]
3082 3113
3083 3114 meteor = powerAux[indInit:indEnd + 1]
3084 3115 indPeak = meteor.argmax() + indInit
3085 3116 FLA = sum(numpy.conj(meteor)*numpy.hstack((meteor[1:],0)))
3086 3117
3087 3118 listMeteors.append(numpy.array([i,indInit,indPeak,indEnd,FLA])) #CHEQUEAR!!!!!
3088 3119 j = numpy.where(indUPthresh == indEnd)[0] + 1
3089 3120 else: j+=1
3090 3121 else: j+=1
3091 3122
3092 3123 return listMeteors
3093 3124
3094 3125 def __removeMultipleDetections(self,listMeteors, rangeLimit, timeLimit):
3095 3126
3096 3127 arrayMeteors = numpy.asarray(listMeteors)
3097 3128 listMeteors1 = []
3098 3129
3099 3130 while arrayMeteors.shape[0] > 0:
3100 3131 FLAs = arrayMeteors[:,4]
3101 3132 maxFLA = FLAs.argmax()
3102 3133 listMeteors1.append(arrayMeteors[maxFLA,:])
3103 3134
3104 3135 MeteorInitTime = arrayMeteors[maxFLA,1]
3105 3136 MeteorEndTime = arrayMeteors[maxFLA,3]
3106 3137 MeteorHeight = arrayMeteors[maxFLA,0]
3107 3138
3108 3139 #Check neighborhood
3109 3140 maxHeightIndex = MeteorHeight + rangeLimit
3110 3141 minHeightIndex = MeteorHeight - rangeLimit
3111 3142 minTimeIndex = MeteorInitTime - timeLimit
3112 3143 maxTimeIndex = MeteorEndTime + timeLimit
3113 3144
3114 3145 #Check Heights
3115 3146 indHeight = numpy.logical_and(arrayMeteors[:,0] >= minHeightIndex, arrayMeteors[:,0] <= maxHeightIndex)
3116 3147 indTime = numpy.logical_and(arrayMeteors[:,3] >= minTimeIndex, arrayMeteors[:,1] <= maxTimeIndex)
3117 3148 indBoth = numpy.where(numpy.logical_and(indTime,indHeight))
3118 3149
3119 3150 arrayMeteors = numpy.delete(arrayMeteors, indBoth, axis = 0)
3120 3151
3121 3152 return listMeteors1
3122 3153
3123 3154 def __meteorReestimation(self, listMeteors, volts, pairslist, thresh, noise, timeInterval,frequency):
3124 3155 numHeights = volts.shape[2]
3125 3156 nChannel = volts.shape[0]
3126 3157
3127 3158 thresholdPhase = thresh[0]
3128 3159 thresholdNoise = thresh[1]
3129 3160 thresholdDB = float(thresh[2])
3130 3161
3131 3162 thresholdDB1 = 10**(thresholdDB/10)
3132 3163 pairsarray = numpy.array(pairslist)
3133 3164 indSides = pairsarray[:,1]
3134 3165
3135 3166 pairslist1 = list(pairslist)
3136 3167 pairslist1.append((0,1))
3137 3168 pairslist1.append((3,4))
3138 3169
3139 3170 listMeteors1 = []
3140 3171 listPowerSeries = []
3141 3172 listVoltageSeries = []
3142 3173 #volts has the war data
3143 3174
3144 3175 if frequency == 30e6:
3145 3176 timeLag = 45*10**-3
3146 3177 else:
3147 3178 timeLag = 15*10**-3
3148 3179 lag = numpy.ceil(timeLag/timeInterval)
3149 3180
3150 3181 for i in range(len(listMeteors)):
3151 3182
3152 3183 ###################### 3.6 - 3.7 PARAMETERS REESTIMATION #########################
3153 3184 meteorAux = numpy.zeros(16)
3154 3185
3155 3186 #Loading meteor Data (mHeight, mStart, mPeak, mEnd)
3156 3187 mHeight = listMeteors[i][0]
3157 3188 mStart = listMeteors[i][1]
3158 3189 mPeak = listMeteors[i][2]
3159 3190 mEnd = listMeteors[i][3]
3160 3191
3161 3192 #get the volt data between the start and end times of the meteor
3162 3193 meteorVolts = volts[:,mStart:mEnd+1,mHeight]
3163 3194 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3164 3195
3165 3196 #3.6. Phase Difference estimation
3166 3197 phaseDiff, aux = self.__estimatePhaseDifference(meteorVolts, pairslist)
3167 3198
3168 3199 #3.7. Phase difference removal & meteor start, peak and end times reestimated
3169 3200 #meteorVolts0.- all Channels, all Profiles
3170 3201 meteorVolts0 = volts[:,:,mHeight]
3171 3202 meteorThresh = noise[:,mHeight]*thresholdNoise
3172 3203 meteorNoise = noise[:,mHeight]
3173 3204 meteorVolts0[indSides,:] = self.__shiftPhase(meteorVolts0[indSides,:], phaseDiff) #Phase Shifting
3174 3205 powerNet0 = numpy.nansum(numpy.abs(meteorVolts0)**2, axis = 0) #Power
3175 3206
3176 3207 #Times reestimation
3177 3208 mStart1 = numpy.where(powerNet0[:mPeak] < meteorThresh[:mPeak])[0]
3178 3209 if mStart1.size > 0:
3179 3210 mStart1 = mStart1[-1] + 1
3180 3211
3181 3212 else:
3182 3213 mStart1 = mPeak
3183 3214
3184 3215 mEnd1 = numpy.where(powerNet0[mPeak:] < meteorThresh[mPeak:])[0][0] + mPeak - 1
3185 3216 mEndDecayTime1 = numpy.where(powerNet0[mPeak:] < meteorNoise[mPeak:])[0]
3186 3217 if mEndDecayTime1.size == 0:
3187 3218 mEndDecayTime1 = powerNet0.size
3188 3219 else:
3189 3220 mEndDecayTime1 = mEndDecayTime1[0] + mPeak - 1
3190 3221 # mPeak1 = meteorVolts0[mStart1:mEnd1 + 1].argmax()
3191 3222
3192 3223 #meteorVolts1.- all Channels, from start to end
3193 3224 meteorVolts1 = meteorVolts0[:,mStart1:mEnd1 + 1]
3194 3225 meteorVolts2 = meteorVolts0[:,mPeak + lag:mEnd1 + 1]
3195 3226 if meteorVolts2.shape[1] == 0:
3196 3227 meteorVolts2 = meteorVolts0[:,mPeak:mEnd1 + 1]
3197 3228 meteorVolts1 = meteorVolts1.reshape(meteorVolts1.shape[0], meteorVolts1.shape[1], 1)
3198 3229 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1], 1)
3199 3230 ##################### END PARAMETERS REESTIMATION #########################
3200 3231
3201 3232 ##################### 3.8 PHASE DIFFERENCE REESTIMATION ########################
3202 3233 # if mEnd1 - mStart1 > 4: #Error Number 6: echo less than 5 samples long; too short for analysis
3203 3234 if meteorVolts2.shape[1] > 0:
3204 3235 #Phase Difference re-estimation
3205 3236 phaseDiff1, phaseDiffint = self.__estimatePhaseDifference(meteorVolts2, pairslist1) #Phase Difference Estimation
3206 3237 # phaseDiff1, phaseDiffint = self.estimatePhaseDifference(meteorVolts2, pairslist)
3207 3238 meteorVolts2 = meteorVolts2.reshape(meteorVolts2.shape[0], meteorVolts2.shape[1])
3208 3239 phaseDiff11 = numpy.reshape(phaseDiff1, (phaseDiff1.shape[0],1))
3209 3240 meteorVolts2[indSides,:] = self.__shiftPhase(meteorVolts2[indSides,:], phaseDiff11[0:4]) #Phase Shifting
3210 3241
3211 3242 #Phase Difference RMS
3212 3243 phaseRMS1 = numpy.sqrt(numpy.mean(numpy.square(phaseDiff1)))
3213 3244 powerNet1 = numpy.nansum(numpy.abs(meteorVolts1[:,:])**2,0)
3214 3245 #Data from Meteor
3215 3246 mPeak1 = powerNet1.argmax() + mStart1
3216 3247 mPeakPower1 = powerNet1.max()
3217 3248 noiseAux = sum(noise[mStart1:mEnd1 + 1,mHeight])
3218 3249 mSNR1 = (sum(powerNet1)-noiseAux)/noiseAux
3219 3250 Meteor1 = numpy.array([mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1])
3220 3251 Meteor1 = numpy.hstack((Meteor1,phaseDiffint))
3221 3252 PowerSeries = powerNet0[mStart1:mEndDecayTime1 + 1]
3222 3253 #Vectorize
3223 3254 meteorAux[0:7] = [mHeight, mStart1, mPeak1, mEnd1, mPeakPower1, mSNR1, phaseRMS1]
3224 3255 meteorAux[7:11] = phaseDiffint[0:4]
3225 3256
3226 3257 #Rejection Criterions
3227 3258 if phaseRMS1 > thresholdPhase: #Error Number 17: Phase variation
3228 3259 meteorAux[-1] = 17
3229 3260 elif mSNR1 < thresholdDB1: #Error Number 1: SNR < threshold dB
3230 3261 meteorAux[-1] = 1
3231 3262
3232 3263
3233 3264 else:
3234 3265 meteorAux[0:4] = [mHeight, mStart, mPeak, mEnd]
3235 3266 meteorAux[-1] = 6 #Error Number 6: echo less than 5 samples long; too short for analysis
3236 3267 PowerSeries = 0
3237 3268
3238 3269 listMeteors1.append(meteorAux)
3239 3270 listPowerSeries.append(PowerSeries)
3240 3271 listVoltageSeries.append(meteorVolts1)
3241 3272
3242 3273 return listMeteors1, listPowerSeries, listVoltageSeries
3243 3274
3244 3275 def __estimateDecayTime(self, listMeteors, listPower, timeInterval, frequency):
3245 3276
3246 3277 threshError = 10
3247 3278 #Depending if it is 30 or 50 MHz
3248 3279 if frequency == 30e6:
3249 3280 timeLag = 45*10**-3
3250 3281 else:
3251 3282 timeLag = 15*10**-3
3252 3283 lag = numpy.ceil(timeLag/timeInterval)
3253 3284
3254 3285 listMeteors1 = []
3255 3286
3256 3287 for i in range(len(listMeteors)):
3257 3288 meteorPower = listPower[i]
3258 3289 meteorAux = listMeteors[i]
3259 3290
3260 3291 if meteorAux[-1] == 0:
3261 3292
3262 3293 try:
3263 3294 indmax = meteorPower.argmax()
3264 3295 indlag = indmax + lag
3265 3296
3266 3297 y = meteorPower[indlag:]
3267 3298 x = numpy.arange(0, y.size)*timeLag
3268 3299
3269 3300 #first guess
3270 3301 a = y[0]
3271 3302 tau = timeLag
3272 3303 #exponential fit
3273 3304 popt, pcov = optimize.curve_fit(self.__exponential_function, x, y, p0 = [a, tau])
3274 3305 y1 = self.__exponential_function(x, *popt)
3275 3306 #error estimation
3276 3307 error = sum((y - y1)**2)/(numpy.var(y)*(y.size - popt.size))
3277 3308
3278 3309 decayTime = popt[1]
3279 3310 riseTime = indmax*timeInterval
3280 3311 meteorAux[11:13] = [decayTime, error]
3281 3312
3282 3313 #Table items 7, 8 and 11
3283 3314 if (riseTime > 0.3): #Number 7: Echo rise exceeds 0.3s
3284 3315 meteorAux[-1] = 7
3285 3316 elif (decayTime < 2*riseTime) : #Number 8: Echo decay time less than than twice rise time
3286 3317 meteorAux[-1] = 8
3287 3318 if (error > threshError): #Number 11: Poor fit to amplitude for estimation of decay time
3288 3319 meteorAux[-1] = 11
3289 3320
3290 3321
3291 3322 except:
3292 3323 meteorAux[-1] = 11
3293 3324
3294 3325
3295 3326 listMeteors1.append(meteorAux)
3296 3327
3297 3328 return listMeteors1
3298 3329
3299 3330 #Exponential Function
3300 3331
3301 3332 def __exponential_function(self, x, a, tau):
3302 3333 y = a*numpy.exp(-x/tau)
3303 3334 return y
3304 3335
3305 3336 def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval):
3306 3337
3307 3338 pairslist1 = list(pairslist)
3308 3339 pairslist1.append((0,1))
3309 3340 pairslist1.append((3,4))
3310 3341 numPairs = len(pairslist1)
3311 3342 #Time Lag
3312 3343 timeLag = 45*10**-3
3313 3344 c = 3e8
3314 3345 lag = numpy.ceil(timeLag/timeInterval)
3315 3346 freq = 30e6
3316 3347
3317 3348 listMeteors1 = []
3318 3349
3319 3350 for i in range(len(listMeteors)):
3320 3351 meteorAux = listMeteors[i]
3321 3352 if meteorAux[-1] == 0:
3322 3353 mStart = listMeteors[i][1]
3323 3354 mPeak = listMeteors[i][2]
3324 3355 mLag = mPeak - mStart + lag
3325 3356
3326 3357 #get the volt data between the start and end times of the meteor
3327 3358 meteorVolts = listVolts[i]
3328 3359 meteorVolts = meteorVolts.reshape(meteorVolts.shape[0], meteorVolts.shape[1], 1)
3329 3360
3330 3361 #Get CCF
3331 3362 allCCFs = self.__calculateCCF(meteorVolts, pairslist1, [-2,-1,0,1,2])
3332 3363
3333 3364 #Method 2
3334 3365 slopes = numpy.zeros(numPairs)
3335 3366 time = numpy.array([-2,-1,1,2])*timeInterval
3336 3367 angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0])
3337 3368
3338 3369 #Correct phases
3339 3370 derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1]
3340 3371 indDer = numpy.where(numpy.abs(derPhaseCCF) > numpy.pi)
3341 3372
3342 3373 if indDer[0].shape[0] > 0:
3343 3374 for i in range(indDer[0].shape[0]):
3344 3375 signo = -numpy.sign(derPhaseCCF[indDer[0][i],indDer[1][i]])
3345 3376 angAllCCF[indDer[0][i],indDer[1][i]+1:] += signo*2*numpy.pi
3346 3377
3347 3378 # fit = scipy.stats.linregress(numpy.array([-2,-1,1,2])*timeInterval, numpy.array([phaseLagN2s[i],phaseLagN1s[i],phaseLag1s[i],phaseLag2s[i]]))
3348 3379 for j in range(numPairs):
3349 3380 fit = stats.linregress(time, angAllCCF[j,:])
3350 3381 slopes[j] = fit[0]
3351 3382
3352 3383 #Remove Outlier
3353 3384 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3354 3385 # slopes = numpy.delete(slopes,indOut)
3355 3386 # indOut = numpy.argmax(numpy.abs(slopes - numpy.mean(slopes)))
3356 3387 # slopes = numpy.delete(slopes,indOut)
3357 3388
3358 3389 radialVelocity = -numpy.mean(slopes)*(0.25/numpy.pi)*(c/freq)
3359 3390 radialError = numpy.std(slopes)*(0.25/numpy.pi)*(c/freq)
3360 3391 meteorAux[-2] = radialError
3361 3392 meteorAux[-3] = radialVelocity
3362 3393
3363 3394 #Setting Error
3364 3395 #Number 15: Radial Drift velocity or projected horizontal velocity exceeds 200 m/s
3365 3396 if numpy.abs(radialVelocity) > 200:
3366 3397 meteorAux[-1] = 15
3367 3398 #Number 12: Poor fit to CCF variation for estimation of radial drift velocity
3368 3399 elif radialError > radialStdThresh:
3369 3400 meteorAux[-1] = 12
3370 3401
3371 3402 listMeteors1.append(meteorAux)
3372 3403 return listMeteors1
3373 3404
3374 3405 def __setNewArrays(self, listMeteors, date, heiRang):
3375 3406
3376 3407 #New arrays
3377 3408 arrayMeteors = numpy.array(listMeteors)
3378 3409 arrayParameters = numpy.zeros((len(listMeteors), 13))
3379 3410
3380 3411 #Date inclusion
3381 3412 # date = re.findall(r'\((.*?)\)', date)
3382 3413 # date = date[0].split(',')
3383 3414 # date = map(int, date)
3384 3415 #
3385 3416 # if len(date)<6:
3386 3417 # date.append(0)
3387 3418 #
3388 3419 # date = [date[0]*10000 + date[1]*100 + date[2], date[3]*10000 + date[4]*100 + date[5]]
3389 3420 # arrayDate = numpy.tile(date, (len(listMeteors), 1))
3390 3421 arrayDate = numpy.tile(date, (len(listMeteors)))
3391 3422
3392 3423 #Meteor array
3393 3424 # arrayMeteors[:,0] = heiRang[arrayMeteors[:,0].astype(int)]
3394 3425 # arrayMeteors = numpy.hstack((arrayDate, arrayMeteors))
3395 3426
3396 3427 #Parameters Array
3397 3428 arrayParameters[:,0] = arrayDate #Date
3398 3429 arrayParameters[:,1] = heiRang[arrayMeteors[:,0].astype(int)] #Range
3399 3430 arrayParameters[:,6:8] = arrayMeteors[:,-3:-1] #Radial velocity and its error
3400 3431 arrayParameters[:,8:12] = arrayMeteors[:,7:11] #Phases
3401 3432 arrayParameters[:,-1] = arrayMeteors[:,-1] #Error
3402 3433
3403 3434
3404 3435 return arrayParameters
3405 3436
3406 3437 class CorrectSMPhases(Operation):
3407 3438
3408 3439 def run(self, dataOut, phaseOffsets, hmin = 50, hmax = 150, azimuth = 45, channelPositions = None):
3409 3440
3410 3441 arrayParameters = dataOut.data_param
3411 3442 pairsList = []
3412 3443 pairx = (0,1)
3413 3444 pairy = (2,3)
3414 3445 pairsList.append(pairx)
3415 3446 pairsList.append(pairy)
3416 3447 jph = numpy.zeros(4)
3417 3448
3418 3449 phaseOffsets = numpy.array(phaseOffsets)*numpy.pi/180
3419 3450 # arrayParameters[:,8:12] = numpy.unwrap(arrayParameters[:,8:12] + phaseOffsets)
3420 3451 arrayParameters[:,8:12] = numpy.angle(numpy.exp(1j*(arrayParameters[:,8:12] + phaseOffsets)))
3421 3452
3422 3453 meteorOps = SMOperations()
3423 3454 if channelPositions == None:
3424 3455 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3425 3456 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3426 3457
3427 3458 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3428 3459 h = (hmin,hmax)
3429 3460
3430 3461 arrayParameters = meteorOps.getMeteorParams(arrayParameters, azimuth, h, pairsList, distances, jph)
3431 3462
3432 3463 dataOut.data_param = arrayParameters
3433 3464 return
3434 3465
3435 3466 class SMPhaseCalibration(Operation):
3436 3467
3437 3468 __buffer = None
3438 3469
3439 3470 __initime = None
3440 3471
3441 3472 __dataReady = False
3442 3473
3443 3474 __isConfig = False
3444 3475
3445 3476 def __checkTime(self, currentTime, initTime, paramInterval, outputInterval):
3446 3477
3447 3478 dataTime = currentTime + paramInterval
3448 3479 deltaTime = dataTime - initTime
3449 3480
3450 3481 if deltaTime >= outputInterval or deltaTime < 0:
3451 3482 return True
3452 3483
3453 3484 return False
3454 3485
3455 3486 def __getGammas(self, pairs, d, phases):
3456 3487 gammas = numpy.zeros(2)
3457 3488
3458 3489 for i in range(len(pairs)):
3459 3490
3460 3491 pairi = pairs[i]
3461 3492
3462 3493 phip3 = phases[:,pairi[1]]
3463 3494 d3 = d[pairi[1]]
3464 3495 phip2 = phases[:,pairi[0]]
3465 3496 d2 = d[pairi[0]]
3466 3497 #Calculating gamma
3467 3498 # jdcos = alp1/(k*d1)
3468 3499 # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0)))
3469 3500 jgamma = -phip2*d3/d2 - phip3
3470 3501 jgamma = numpy.angle(numpy.exp(1j*jgamma))
3471 3502 # jgamma[jgamma>numpy.pi] -= 2*numpy.pi
3472 3503 # jgamma[jgamma<-numpy.pi] += 2*numpy.pi
3473 3504
3474 3505 #Revised distribution
3475 3506 jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi))
3476 3507
3477 3508 #Histogram
3478 3509 nBins = 64.0
3479 3510 rmin = -0.5*numpy.pi
3480 3511 rmax = 0.5*numpy.pi
3481 3512 phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax))
3482 3513
3483 3514 meteorsY = phaseHisto[0]
3484 3515 phasesX = phaseHisto[1][:-1]
3485 3516 width = phasesX[1] - phasesX[0]
3486 3517 phasesX += width/2
3487 3518
3488 3519 #Gaussian aproximation
3489 3520 bpeak = meteorsY.argmax()
3490 3521 peak = meteorsY.max()
3491 3522 jmin = bpeak - 5
3492 3523 jmax = bpeak + 5 + 1
3493 3524
3494 3525 if jmin<0:
3495 3526 jmin = 0
3496 3527 jmax = 6
3497 3528 elif jmax > meteorsY.size:
3498 3529 jmin = meteorsY.size - 6
3499 3530 jmax = meteorsY.size
3500 3531
3501 3532 x0 = numpy.array([peak,bpeak,50])
3502 3533 coeff = optimize.leastsq(self.__residualFunction, x0, args=(meteorsY[jmin:jmax], phasesX[jmin:jmax]))
3503 3534
3504 3535 #Gammas
3505 3536 gammas[i] = coeff[0][1]
3506 3537
3507 3538 return gammas
3508 3539
3509 3540 def __residualFunction(self, coeffs, y, t):
3510 3541
3511 3542 return y - self.__gauss_function(t, coeffs)
3512 3543
3513 3544 def __gauss_function(self, t, coeffs):
3514 3545
3515 3546 return coeffs[0]*numpy.exp(-0.5*((t - coeffs[1]) / coeffs[2])**2)
3516 3547
3517 3548 def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray):
3518 3549 meteorOps = SMOperations()
3519 3550 nchan = 4
3520 3551 pairx = pairsList[0]
3521 3552 pairy = pairsList[1]
3522 3553 center_xangle = 0
3523 3554 center_yangle = 0
3524 3555 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4])
3525 3556 ntimes = len(range_angle)
3526 3557
3527 3558 nstepsx = 20.0
3528 3559 nstepsy = 20.0
3529 3560
3530 3561 for iz in range(ntimes):
3531 3562 min_xangle = -range_angle[iz]/2 + center_xangle
3532 3563 max_xangle = range_angle[iz]/2 + center_xangle
3533 3564 min_yangle = -range_angle[iz]/2 + center_yangle
3534 3565 max_yangle = range_angle[iz]/2 + center_yangle
3535 3566
3536 3567 inc_x = (max_xangle-min_xangle)/nstepsx
3537 3568 inc_y = (max_yangle-min_yangle)/nstepsy
3538 3569
3539 3570 alpha_y = numpy.arange(nstepsy)*inc_y + min_yangle
3540 3571 alpha_x = numpy.arange(nstepsx)*inc_x + min_xangle
3541 3572 penalty = numpy.zeros((nstepsx,nstepsy))
3542 3573 jph_array = numpy.zeros((nchan,nstepsx,nstepsy))
3543 3574 jph = numpy.zeros(nchan)
3544 3575
3545 3576 # Iterations looking for the offset
3546 3577 for iy in range(int(nstepsy)):
3547 3578 for ix in range(int(nstepsx)):
3548 3579 jph[pairy[1]] = alpha_y[iy]
3549 3580 jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]]
3550 3581
3551 3582 jph[pairx[1]] = alpha_x[ix]
3552 3583 jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]]
3553 3584
3554 3585 jph_array[:,ix,iy] = jph
3555 3586
3556 3587 meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph)
3557 3588 error = meteorsArray1[:,-1]
3558 3589 ind1 = numpy.where(error==0)[0]
3559 3590 penalty[ix,iy] = ind1.size
3560 3591
3561 3592 i,j = numpy.unravel_index(penalty.argmax(), penalty.shape)
3562 3593 phOffset = jph_array[:,i,j]
3563 3594
3564 3595 center_xangle = phOffset[pairx[1]]
3565 3596 center_yangle = phOffset[pairy[1]]
3566 3597
3567 3598 phOffset = numpy.angle(numpy.exp(1j*jph_array[:,i,j]))
3568 3599 phOffset = phOffset*180/numpy.pi
3569 3600 return phOffset
3570 3601
3571 3602
3572 3603 def run(self, dataOut, hmin, hmax, channelPositions=None, nHours = 1):
3573 3604
3574 3605 dataOut.flagNoData = True
3575 3606 self.__dataReady = False
3576 3607 dataOut.outputInterval = nHours*3600
3577 3608
3578 3609 if self.__isConfig == False:
3579 3610 # self.__initime = dataOut.datatime.replace(minute = 0, second = 0, microsecond = 03)
3580 3611 #Get Initial LTC time
3581 3612 self.__initime = datetime.datetime.utcfromtimestamp(dataOut.utctime)
3582 3613 self.__initime = (self.__initime.replace(minute = 0, second = 0, microsecond = 0) - datetime.datetime(1970, 1, 1)).total_seconds()
3583 3614
3584 3615 self.__isConfig = True
3585 3616
3586 3617 if self.__buffer == None:
3587 3618 self.__buffer = dataOut.data_param.copy()
3588 3619
3589 3620 else:
3590 3621 self.__buffer = numpy.vstack((self.__buffer, dataOut.data_param))
3591 3622
3592 3623 self.__dataReady = self.__checkTime(dataOut.utctime, self.__initime, dataOut.paramInterval, dataOut.outputInterval) #Check if the buffer is ready
3593 3624
3594 3625 if self.__dataReady:
3595 3626 dataOut.utctimeInit = self.__initime
3596 3627 self.__initime += dataOut.outputInterval #to erase time offset
3597 3628
3598 3629 freq = dataOut.frequency
3599 3630 c = dataOut.C #m/s
3600 3631 lamb = c/freq
3601 3632 k = 2*numpy.pi/lamb
3602 3633 azimuth = 0
3603 3634 h = (hmin, hmax)
3604 3635 pairs = ((0,1),(2,3))
3605 3636
3606 3637 if channelPositions == None:
3607 3638 # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T
3608 3639 channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella
3609 3640 meteorOps = SMOperations()
3610 3641 pairslist0, distances = meteorOps.getPhasePairs(channelPositions)
3611 3642
3612 3643 # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb]
3613 3644
3614 3645 meteorsArray = self.__buffer
3615 3646 error = meteorsArray[:,-1]
3616 3647 boolError = (error==0)|(error==3)|(error==4)|(error==13)|(error==14)
3617 3648 ind1 = numpy.where(boolError)[0]
3618 3649 meteorsArray = meteorsArray[ind1,:]
3619 3650 meteorsArray[:,-1] = 0
3620 3651 phases = meteorsArray[:,8:12]
3621 3652
3622 3653 #Calculate Gammas
3623 3654 gammas = self.__getGammas(pairs, distances, phases)
3624 3655 # gammas = numpy.array([-21.70409463,45.76935864])*numpy.pi/180
3625 3656 #Calculate Phases
3626 3657 phasesOff = self.__getPhases(azimuth, h, pairs, distances, gammas, meteorsArray)
3627 3658 phasesOff = phasesOff.reshape((1,phasesOff.size))
3628 3659 dataOut.data_output = -phasesOff
3629 3660 dataOut.flagNoData = False
3630 3661 self.__buffer = None
3631 3662
3632 3663
3633 3664 return
3634 3665
3635 3666 class SMOperations():
3636 3667
3637 3668 def __init__(self):
3638 3669
3639 3670 return
3640 3671
3641 3672 def getMeteorParams(self, arrayParameters0, azimuth, h, pairsList, distances, jph):
3642 3673
3643 3674 arrayParameters = arrayParameters0.copy()
3644 3675 hmin = h[0]
3645 3676 hmax = h[1]
3646 3677
3647 3678 #Calculate AOA (Error N 3, 4)
3648 3679 #JONES ET AL. 1998
3649 3680 AOAthresh = numpy.pi/8
3650 3681 error = arrayParameters[:,-1]
3651 3682 phases = -arrayParameters[:,8:12] + jph
3652 3683 # phases = numpy.unwrap(phases)
3653 3684 arrayParameters[:,3:6], arrayParameters[:,-1] = self.__getAOA(phases, pairsList, distances, error, AOAthresh, azimuth)
3654 3685
3655 3686 #Calculate Heights (Error N 13 and 14)
3656 3687 error = arrayParameters[:,-1]
3657 3688 Ranges = arrayParameters[:,1]
3658 3689 zenith = arrayParameters[:,4]
3659 3690 arrayParameters[:,2], arrayParameters[:,-1] = self.__getHeights(Ranges, zenith, error, hmin, hmax)
3660 3691
3661 3692 #----------------------- Get Final data ------------------------------------
3662 3693 # error = arrayParameters[:,-1]
3663 3694 # ind1 = numpy.where(error==0)[0]
3664 3695 # arrayParameters = arrayParameters[ind1,:]
3665 3696
3666 3697 return arrayParameters
3667 3698
3668 3699 def __getAOA(self, phases, pairsList, directions, error, AOAthresh, azimuth):
3669 3700
3670 3701 arrayAOA = numpy.zeros((phases.shape[0],3))
3671 3702 cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList,directions)
3672 3703
3673 3704 arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3674 3705 cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3675 3706 arrayAOA[:,2] = cosDirError
3676 3707
3677 3708 azimuthAngle = arrayAOA[:,0]
3678 3709 zenithAngle = arrayAOA[:,1]
3679 3710
3680 3711 #Setting Error
3681 3712 indError = numpy.where(numpy.logical_or(error == 3, error == 4))[0]
3682 3713 error[indError] = 0
3683 3714 #Number 3: AOA not fesible
3684 3715 indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3685 3716 error[indInvalid] = 3
3686 3717 #Number 4: Large difference in AOAs obtained from different antenna baselines
3687 3718 indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3688 3719 error[indInvalid] = 4
3689 3720 return arrayAOA, error
3690 3721
3691 3722 def __getDirectionCosines(self, arrayPhase, pairsList, distances):
3692 3723
3693 3724 #Initializing some variables
3694 3725 ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3695 3726 ang_aux = ang_aux.reshape(1,ang_aux.size)
3696 3727
3697 3728 cosdir = numpy.zeros((arrayPhase.shape[0],2))
3698 3729 cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3699 3730
3700 3731
3701 3732 for i in range(2):
3702 3733 ph0 = arrayPhase[:,pairsList[i][0]]
3703 3734 ph1 = arrayPhase[:,pairsList[i][1]]
3704 3735 d0 = distances[pairsList[i][0]]
3705 3736 d1 = distances[pairsList[i][1]]
3706 3737
3707 3738 ph0_aux = ph0 + ph1
3708 3739 ph0_aux = numpy.angle(numpy.exp(1j*ph0_aux))
3709 3740 # ph0_aux[ph0_aux > numpy.pi] -= 2*numpy.pi
3710 3741 # ph0_aux[ph0_aux < -numpy.pi] += 2*numpy.pi
3711 3742 #First Estimation
3712 3743 cosdir0[:,i] = (ph0_aux)/(2*numpy.pi*(d0 - d1))
3713 3744
3714 3745 #Most-Accurate Second Estimation
3715 3746 phi1_aux = ph0 - ph1
3716 3747 phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3717 3748 #Direction Cosine 1
3718 3749 cosdir1 = (phi1_aux + ang_aux)/(2*numpy.pi*(d0 + d1))
3719 3750
3720 3751 #Searching the correct Direction Cosine
3721 3752 cosdir0_aux = cosdir0[:,i]
3722 3753 cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3723 3754 #Minimum Distance
3724 3755 cosDiff = (cosdir1 - cosdir0_aux)**2
3725 3756 indcos = cosDiff.argmin(axis = 1)
3726 3757 #Saving Value obtained
3727 3758 cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3728 3759
3729 3760 return cosdir0, cosdir
3730 3761
3731 3762 def __calculateAOA(self, cosdir, azimuth):
3732 3763 cosdirX = cosdir[:,0]
3733 3764 cosdirY = cosdir[:,1]
3734 3765
3735 3766 zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3736 3767 azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth#0 deg north, 90 deg east
3737 3768 angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3738 3769
3739 3770 return angles
3740 3771
3741 3772 def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3742 3773
3743 3774 Ramb = 375 #Ramb = c/(2*PRF)
3744 3775 Re = 6371 #Earth Radius
3745 3776 heights = numpy.zeros(Ranges.shape)
3746 3777
3747 3778 R_aux = numpy.array([0,1,2])*Ramb
3748 3779 R_aux = R_aux.reshape(1,R_aux.size)
3749 3780
3750 3781 Ranges = Ranges.reshape(Ranges.size,1)
3751 3782
3752 3783 Ri = Ranges + R_aux
3753 3784 hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3754 3785
3755 3786 #Check if there is a height between 70 and 110 km
3756 3787 h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3757 3788 ind_h = numpy.where(h_bool == 1)[0]
3758 3789
3759 3790 hCorr = hi[ind_h, :]
3760 3791 ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3761 3792
3762 3793 hCorr = hi[ind_hCorr]
3763 3794 heights[ind_h] = hCorr
3764 3795
3765 3796 #Setting Error
3766 3797 #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3767 3798 #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3768 3799 indError = numpy.where(numpy.logical_or(error == 13, error == 14))[0]
3769 3800 error[indError] = 0
3770 3801 indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3771 3802 error[indInvalid2] = 14
3772 3803 indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3773 3804 error[indInvalid1] = 13
3774 3805
3775 3806 return heights, error
3776 3807
3777 3808 def getPhasePairs(self, channelPositions):
3778 3809 chanPos = numpy.array(channelPositions)
3779 3810 listOper = list(itertools.combinations(range(5),2))
3780 3811
3781 3812 distances = numpy.zeros(4)
3782 3813 axisX = []
3783 3814 axisY = []
3784 3815 distX = numpy.zeros(3)
3785 3816 distY = numpy.zeros(3)
3786 3817 ix = 0
3787 3818 iy = 0
3788 3819
3789 3820 pairX = numpy.zeros((2,2))
3790 3821 pairY = numpy.zeros((2,2))
3791 3822
3792 3823 for i in range(len(listOper)):
3793 3824 pairi = listOper[i]
3794 3825
3795 3826 posDif = numpy.abs(chanPos[pairi[0],:] - chanPos[pairi[1],:])
3796 3827
3797 3828 if posDif[0] == 0:
3798 3829 axisY.append(pairi)
3799 3830 distY[iy] = posDif[1]
3800 3831 iy += 1
3801 3832 elif posDif[1] == 0:
3802 3833 axisX.append(pairi)
3803 3834 distX[ix] = posDif[0]
3804 3835 ix += 1
3805 3836
3806 3837 for i in range(2):
3807 3838 if i==0:
3808 3839 dist0 = distX
3809 3840 axis0 = axisX
3810 3841 else:
3811 3842 dist0 = distY
3812 3843 axis0 = axisY
3813 3844
3814 3845 side = numpy.argsort(dist0)[:-1]
3815 3846 axis0 = numpy.array(axis0)[side,:]
3816 3847 chanC = int(numpy.intersect1d(axis0[0,:], axis0[1,:])[0])
3817 3848 axis1 = numpy.unique(numpy.reshape(axis0,4))
3818 3849 side = axis1[axis1 != chanC]
3819 3850 diff1 = chanPos[chanC,i] - chanPos[side[0],i]
3820 3851 diff2 = chanPos[chanC,i] - chanPos[side[1],i]
3821 3852 if diff1<0:
3822 3853 chan2 = side[0]
3823 3854 d2 = numpy.abs(diff1)
3824 3855 chan1 = side[1]
3825 3856 d1 = numpy.abs(diff2)
3826 3857 else:
3827 3858 chan2 = side[1]
3828 3859 d2 = numpy.abs(diff2)
3829 3860 chan1 = side[0]
3830 3861 d1 = numpy.abs(diff1)
3831 3862
3832 3863 if i==0:
3833 3864 chanCX = chanC
3834 3865 chan1X = chan1
3835 3866 chan2X = chan2
3836 3867 distances[0:2] = numpy.array([d1,d2])
3837 3868 else:
3838 3869 chanCY = chanC
3839 3870 chan1Y = chan1
3840 3871 chan2Y = chan2
3841 3872 distances[2:4] = numpy.array([d1,d2])
3842 3873 # axisXsides = numpy.reshape(axisX[ix,:],4)
3843 3874 #
3844 3875 # channelCentX = int(numpy.intersect1d(pairX[0,:], pairX[1,:])[0])
3845 3876 # channelCentY = int(numpy.intersect1d(pairY[0,:], pairY[1,:])[0])
3846 3877 #
3847 3878 # ind25X = numpy.where(pairX[0,:] != channelCentX)[0][0]
3848 3879 # ind20X = numpy.where(pairX[1,:] != channelCentX)[0][0]
3849 3880 # channel25X = int(pairX[0,ind25X])
3850 3881 # channel20X = int(pairX[1,ind20X])
3851 3882 # ind25Y = numpy.where(pairY[0,:] != channelCentY)[0][0]
3852 3883 # ind20Y = numpy.where(pairY[1,:] != channelCentY)[0][0]
3853 3884 # channel25Y = int(pairY[0,ind25Y])
3854 3885 # channel20Y = int(pairY[1,ind20Y])
3855 3886
3856 3887 # pairslist = [(channelCentX, channel25X),(channelCentX, channel20X),(channelCentY,channel25Y),(channelCentY, channel20Y)]
3857 3888 pairslist = [(chanCX, chan1X),(chanCX, chan2X),(chanCY,chan1Y),(chanCY, chan2Y)]
3858 3889
3859 3890 return pairslist, distances
3860 3891 # def __getAOA(self, phases, pairsList, error, AOAthresh, azimuth):
3861 3892 #
3862 3893 # arrayAOA = numpy.zeros((phases.shape[0],3))
3863 3894 # cosdir0, cosdir = self.__getDirectionCosines(phases, pairsList)
3864 3895 #
3865 3896 # arrayAOA[:,:2] = self.__calculateAOA(cosdir, azimuth)
3866 3897 # cosDirError = numpy.sum(numpy.abs(cosdir0 - cosdir), axis = 1)
3867 3898 # arrayAOA[:,2] = cosDirError
3868 3899 #
3869 3900 # azimuthAngle = arrayAOA[:,0]
3870 3901 # zenithAngle = arrayAOA[:,1]
3871 3902 #
3872 3903 # #Setting Error
3873 3904 # #Number 3: AOA not fesible
3874 3905 # indInvalid = numpy.where(numpy.logical_and((numpy.logical_or(numpy.isnan(zenithAngle), numpy.isnan(azimuthAngle))),error == 0))[0]
3875 3906 # error[indInvalid] = 3
3876 3907 # #Number 4: Large difference in AOAs obtained from different antenna baselines
3877 3908 # indInvalid = numpy.where(numpy.logical_and(cosDirError > AOAthresh,error == 0))[0]
3878 3909 # error[indInvalid] = 4
3879 3910 # return arrayAOA, error
3880 3911 #
3881 3912 # def __getDirectionCosines(self, arrayPhase, pairsList):
3882 3913 #
3883 3914 # #Initializing some variables
3884 3915 # ang_aux = numpy.array([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8])*2*numpy.pi
3885 3916 # ang_aux = ang_aux.reshape(1,ang_aux.size)
3886 3917 #
3887 3918 # cosdir = numpy.zeros((arrayPhase.shape[0],2))
3888 3919 # cosdir0 = numpy.zeros((arrayPhase.shape[0],2))
3889 3920 #
3890 3921 #
3891 3922 # for i in range(2):
3892 3923 # #First Estimation
3893 3924 # phi0_aux = arrayPhase[:,pairsList[i][0]] + arrayPhase[:,pairsList[i][1]]
3894 3925 # #Dealias
3895 3926 # indcsi = numpy.where(phi0_aux > numpy.pi)
3896 3927 # phi0_aux[indcsi] -= 2*numpy.pi
3897 3928 # indcsi = numpy.where(phi0_aux < -numpy.pi)
3898 3929 # phi0_aux[indcsi] += 2*numpy.pi
3899 3930 # #Direction Cosine 0
3900 3931 # cosdir0[:,i] = -(phi0_aux)/(2*numpy.pi*0.5)
3901 3932 #
3902 3933 # #Most-Accurate Second Estimation
3903 3934 # phi1_aux = arrayPhase[:,pairsList[i][0]] - arrayPhase[:,pairsList[i][1]]
3904 3935 # phi1_aux = phi1_aux.reshape(phi1_aux.size,1)
3905 3936 # #Direction Cosine 1
3906 3937 # cosdir1 = -(phi1_aux + ang_aux)/(2*numpy.pi*4.5)
3907 3938 #
3908 3939 # #Searching the correct Direction Cosine
3909 3940 # cosdir0_aux = cosdir0[:,i]
3910 3941 # cosdir0_aux = cosdir0_aux.reshape(cosdir0_aux.size,1)
3911 3942 # #Minimum Distance
3912 3943 # cosDiff = (cosdir1 - cosdir0_aux)**2
3913 3944 # indcos = cosDiff.argmin(axis = 1)
3914 3945 # #Saving Value obtained
3915 3946 # cosdir[:,i] = cosdir1[numpy.arange(len(indcos)),indcos]
3916 3947 #
3917 3948 # return cosdir0, cosdir
3918 3949 #
3919 3950 # def __calculateAOA(self, cosdir, azimuth):
3920 3951 # cosdirX = cosdir[:,0]
3921 3952 # cosdirY = cosdir[:,1]
3922 3953 #
3923 3954 # zenithAngle = numpy.arccos(numpy.sqrt(1 - cosdirX**2 - cosdirY**2))*180/numpy.pi
3924 3955 # azimuthAngle = numpy.arctan2(cosdirX,cosdirY)*180/numpy.pi + azimuth #0 deg north, 90 deg east
3925 3956 # angles = numpy.vstack((azimuthAngle, zenithAngle)).transpose()
3926 3957 #
3927 3958 # return angles
3928 3959 #
3929 3960 # def __getHeights(self, Ranges, zenith, error, minHeight, maxHeight):
3930 3961 #
3931 3962 # Ramb = 375 #Ramb = c/(2*PRF)
3932 3963 # Re = 6371 #Earth Radius
3933 3964 # heights = numpy.zeros(Ranges.shape)
3934 3965 #
3935 3966 # R_aux = numpy.array([0,1,2])*Ramb
3936 3967 # R_aux = R_aux.reshape(1,R_aux.size)
3937 3968 #
3938 3969 # Ranges = Ranges.reshape(Ranges.size,1)
3939 3970 #
3940 3971 # Ri = Ranges + R_aux
3941 3972 # hi = numpy.sqrt(Re**2 + Ri**2 + (2*Re*numpy.cos(zenith*numpy.pi/180)*Ri.transpose()).transpose()) - Re
3942 3973 #
3943 3974 # #Check if there is a height between 70 and 110 km
3944 3975 # h_bool = numpy.sum(numpy.logical_and(hi > minHeight, hi < maxHeight), axis = 1)
3945 3976 # ind_h = numpy.where(h_bool == 1)[0]
3946 3977 #
3947 3978 # hCorr = hi[ind_h, :]
3948 3979 # ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight))
3949 3980 #
3950 3981 # hCorr = hi[ind_hCorr]
3951 3982 # heights[ind_h] = hCorr
3952 3983 #
3953 3984 # #Setting Error
3954 3985 # #Number 13: Height unresolvable echo: not valid height within 70 to 110 km
3955 3986 # #Number 14: Height ambiguous echo: more than one possible height within 70 to 110 km
3956 3987 #
3957 3988 # indInvalid2 = numpy.where(numpy.logical_and(h_bool > 1, error == 0))[0]
3958 3989 # error[indInvalid2] = 14
3959 3990 # indInvalid1 = numpy.where(numpy.logical_and(h_bool == 0, error == 0))[0]
3960 3991 # error[indInvalid1] = 13
3961 3992 #
3962 3993 # return heights, error
3963 3994 No newline at end of file
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
@@ -1,1 +1,1
1 <Project description="Segundo Test" id="191" name="test01"><ReadUnit datatype="VoltageReader" id="1911" inputId="0" name="VoltageReader"><Operation id="19111" name="run" priority="1" type="self"><Parameter format="str" id="191111" name="datatype" value="VoltageReader" /><Parameter format="str" id="191112" name="path" value="/home/erick/Documents/Data/Claire_Data/raw" /><Parameter format="date" id="191113" name="startDate" value="2017/07/26" /><Parameter format="date" id="191114" name="endDate" value="2017/10/28" /><Parameter format="time" id="191115" name="startTime" value="09:40:00" /><Parameter format="time" id="191116" name="endTime" value="23:59:00" /><Parameter format="int" id="191118" name="online" value="0" /><Parameter format="int" id="191119" name="walk" value="1" /></Operation><Operation id="19112" name="printNumberOfBlock" priority="2" type="self" /></ReadUnit><ProcUnit datatype="SpectraProc" id="1913" inputId="1912" name="SpectraProc"><Operation id="19131" name="run" priority="1" type="self"><Parameter format="int" id="191311" name="nFFTPoints" value="256" /><Parameter format="pairslist" id="191312" name="pairsList" value="(0,1),(0,2),(1,2)" /></Operation><Operation id="19132" name="removeDC" priority="2" type="self" /><Operation id="19133" name="IncohInt" priority="3" type="external"><Parameter format="float" id="191331" name="n" value="30" /></Operation><Operation id="19134" name="SpectraPlot" priority="4" type="external"><Parameter format="int" id="191341" name="id" value="11" /><Parameter format="str" id="191342" name="wintitle" value="SpectraPlot" /><Parameter format="str" id="191343" name="xaxis" value="velocity" /><Parameter format="int" id="191344" name="zmin" value="0" /><Parameter format="float" id="191345" name="ymin" value="1.5" /><Parameter format="int" id="191346" name="ymax" value="7" /><Parameter format="int" id="191347" name="zmax" value="40" /><Parameter format="int" id="191348" name="save" value="1" /></Operation><Operation id="19135" name="RTIPlot" priority="5" type="other"><Parameter format="int" id="191351" name="id" value="30" /><Parameter format="str" id="191352" name="wintitle" value="RTI" /><Parameter format="int" id="191353" name="zmin" value="0" /><Parameter format="int" id="191354" name="zmax" value="40" /><Parameter format="float" id="191355" name="ymin" value="1.5" /><Parameter format="int" id="191356" name="ymax" value="8" /><Parameter format="int" id="191357" name="showprofile" value="1" /><Parameter format="float" id="191358" name="xmin" value="0" /><Parameter format="float" id="191359" name="xmax" value="23.9" /><Parameter format="int" id="191360" name="save" value="1" /></Operation><Operation id="19136" name="CrossSpectraPlot" priority="6" type="other"><Parameter format="str" id="191361" name="phase_cmap" value="bwr" /><Parameter format="int" id="191362" name="id" value="2005" /><Parameter format="str" id="191363" name="wintitle" value="CrossSpectraPlot_ShortPulse" /><Parameter format="str" id="191364" name="xaxis" value="Velocity" /><Parameter format="float" id="191365" name="ymin" value="1.5" /><Parameter format="int" id="191366" name="ymax" value="7" /></Operation></ProcUnit><ProcUnit datatype="VoltageProc" id="1912" inputId="1911" name="VoltageProc"><Operation id="19121" name="run" priority="1" type="self" /><Operation id="19122" name="setRadarFrequency" priority="2" type="self"><Parameter format="float" id="191221" name="frequency" value="445.09e6" /></Operation><Operation id="19123" name="selectHeights" priority="3" type="self"><Parameter format="float" id="191231" name="minHei" value="0" /><Parameter format="float" id="191232" name="maxHei" value="64" /></Operation></ProcUnit><ProcUnit datatype="Parameters" id="1914" inputId="1913" name="ParametersProc"><Operation id="19141" name="run" priority="1" type="self" /><Operation id="19142" name="SpectralMoments" priority="2" type="other" /><Operation id="19143" name="FullSpectralAnalysis" priority="3" type="other"><Parameter format="float" id="191431" name="E01" value="1.5" /><Parameter format="float" id="191432" name="E02" value="1.5" /><Parameter format="float" id="191433" name="E12" value="0" /><Parameter format="float" id="191434" name="N01" value="0.875" /><Parameter format="float" id="191435" name="N02" value="-0.875" /><Parameter format="float" id="191436" name="N12" value="-1.75" /></Operation><Operation id="19144" name="WindProfilerPlot" priority="4" type="other"><Parameter format="int" id="191441" name="id" value="4" /><Parameter format="str" id="191442" name="wintitle" value="Wind Profiler" /><Parameter format="bool" id="191443" name="save" value="1" /><Parameter format="float" id="191444" name="ymin" value="1.5" /><Parameter format="int" id="191445" name="ymax" value="7" /><Parameter format="float" id="191446" name="zmin" value="-0.00" /><Parameter format="float" id="191447" name="zmax" value="1.1" /></Operation></ProcUnit></Project> No newline at end of file
1 <Project description="read bltr data sswma file" id="191" name="test1"><ReadUnit datatype="testBLTRReader" id="1911" inputId="0" name="testBLTRReader"><Operation id="19111" name="run" priority="1" type="self"><Parameter format="str" id="191111" name="datatype" value="testBLTRReader" /><Parameter format="str" id="191112" name="path" value="/media/erick/6F60F7113095A154/BLTR" /><Parameter format="date" id="191113" name="startDate" value="2017/01/17" /><Parameter format="date" id="191114" name="endDate" value="2018/01/01" /><Parameter format="time" id="191115" name="startTime" value="00:00:00" /><Parameter format="time" id="191116" name="endTime" value="23:59:59" /><Parameter format="str" id="191118" name="ext" value="sswma" /></Operation></ReadUnit><ProcUnit datatype="BLTRProcess" id="1912" inputId="1911" name="BLTRProcess"><Operation id="19121" name="run" priority="1" type="self" /><Operation id="19122" name="SnrFilter" priority="2" type="self"><Parameter format="float" id="191221" name="snr_val" value="-20" /><Parameter format="int" id="191222" name="modetofilter" value="2" /></Operation><Operation id="19123" name="OutliersFilter" priority="3" type="self"><Parameter format="str" id="191231" name="svalue" value="meridional" /><Parameter format="str" id="191232" name="svalue2" value="inTime" /><Parameter format="float" id="191233" name="method" value="0" /><Parameter format="float" id="191234" name="factor" value="2" /><Parameter format="float" id="191235" name="filter" value="0" /><Parameter format="float" id="191236" name="npoints" value="9" /><Parameter format="int" id="191237" name="modetofilter" value="2" /></Operation><Operation id="19124" name="OutliersFilter" priority="4" type="self"><Parameter format="str" id="191241" name="svalue" value="zonal" /><Parameter format="str" id="191242" name="svalue2" value="inTime" /><Parameter format="float" id="191243" name="method" value="0" /><Parameter format="float" id="191244" name="factor" value="2" /><Parameter format="float" id="191245" name="filter" value="0" /><Parameter format="float" id="191246" name="npoints" value="9" /><Parameter format="int" id="191247" name="modetofilter" value="2" /></Operation><Operation id="19125" name="OutliersFilter" priority="5" type="self"><Parameter format="str" id="191251" name="svalue" value="vertical" /><Parameter format="str" id="191252" name="svalue2" value="inHeight" /><Parameter format="float" id="191253" name="method" value="0" /><Parameter format="float" id="191254" name="factor" value="2" /><Parameter format="float" id="191255" name="filter" value="0" /><Parameter format="float" id="191256" name="npoints" value="9" /><Parameter format="int" id="191257" name="modetofilter" value="2" /></Operation><Operation id="19126" name="prePlot" priority="6" type="self"><Parameter format="int" id="191261" name="modeselect" value="1" /></Operation><Operation id="19127" name="WindProfilerPlot" priority="7" type="other"><Parameter format="int" id="191271" name="id" value="1" /><Parameter format="str" id="191272" name="wintitle" value="" /><Parameter format="intlist" id="191273" name="channelList" value="0" /><Parameter format="int" id="191274" name="SNRmin" value="-10" /><Parameter format="int" id="191275" name="SNRmax" value="50" /><Parameter format="float" id="191276" name="SNRthresh" value="0" /><Parameter format="float" id="191277" name="xmin" value="0" /><Parameter format="float" id="191278" name="xmax" value="24" /><Parameter format="float" id="191279" name="ymax" value="3" /><Parameter format="float" id="191280" name="zmin" value="-20" /><Parameter format="float" id="191281" name="zmax" value="20" /><Parameter format="float" id="191282" name="zmin_ver" value="-200" /><Parameter format="float" id="191283" name="zmax_ver" value="200" /></Operation><Operation id="19128" name="prePlot" priority="8" type="self"><Parameter format="int" id="191281" name="modeselect" value="2" /></Operation><Operation id="19129" name="WindProfilerPlot" priority="9" type="other"><Parameter format="int" id="191291" name="id" value="2" /><Parameter format="str" id="191292" name="wintitle" value="" /><Parameter format="bool" id="191293" name="save" value="1" /><Parameter format="str" id="191294" name="figpath" value="/media/erick/6F60F7113095A154/BLTR/" /><Parameter format="int" id="191295" name="SNRmin" value="-20" /><Parameter format="int" id="191296" name="SNRmax" value="40" /><Parameter format="float" id="191297" name="SNRthresh" value="0" /><Parameter format="float" id="191298" name="xmin" value="0" /><Parameter format="float" id="191299" name="xmax" value="24" /><Parameter format="float" id="191300" name="ymin" value="0" /><Parameter format="float" id="191301" name="ymax" value="10" /><Parameter format="float" id="191302" name="zmin" value="-4" /><Parameter format="float" id="191303" name="zmax" value="4" /><Parameter format="float" id="191304" name="zmin_ver" value="-200" /><Parameter format="float" id="191305" name="zmax_ver" value="200" /></Operation></ProcUnit></Project> No newline at end of file
@@ -1,170 +1,171
1 1 '''
2 2 Created on Nov 09, 2016
3 3
4 4 @author: roj- LouVD
5 5 '''
6 6 import os, sys
7 7
8 8
9 9 path = os.path.split(os.getcwd())[0]
10 10 path = os.path.split(path)[0]
11 11
12 12 sys.path.insert(0, path)
13 13
14 14 from schainpy.controller import Project
15 15
16 16 filename = 'test1.xml'
17 17 # path = '/home/jespinoza/workspace/data/bltr/'
18 path = '/home/erick/Documents/Data/BLTR_Data/sswma/'
18 path = '/media/erick/6F60F7113095A154/BLTR/'
19 19 desc = "read bltr data sswma file"
20 figpath = '/home/erick/workspace'
20 figpath = '/media/erick/6F60F7113095A154/BLTR/'
21 21 pathhdf5 = '/tmp/'
22 22
23 23 controllerObj = Project()
24 24
25 25 controllerObj.setup(id = '191', name='test1', description=desc)
26 26 readUnitConfObj = controllerObj.addReadUnit(datatype='testBLTRReader',
27 27 path=path,
28 startDate='2015/01/17',
29 endDate='2017/01/01',
28 startDate='2017/01/17',
29 endDate='2018/01/01',
30 30 startTime='00:00:00',
31 31 endTime='23:59:59',
32 32 ext='sswma')
33 33
34 34 procUnitConfObj1 = controllerObj.addProcUnit(datatype='BLTRProcess',
35 35 inputId=readUnitConfObj.getId())
36 36
37 37 '''-------------------------------------------Processing--------------------------------------------'''
38 38
39 39 '''MODE 1: LOW ATMOSPHERE: 0- 3 km'''
40 40 # opObj10 = procUnitConfObj1.addOperation(name='SnrFilter')
41 41 # opObj10.addParameter(name='snr_val', value='-10', format='float')
42 42 # opObj10.addParameter(name='modetofilter', value='1', format='int')
43 43 #
44 44 # opObj10 = procUnitConfObj1.addOperation(name='OutliersFilter')
45 45 # opObj10.addParameter(name='svalue', value='meridional', format='str')
46 46 # opObj10.addParameter(name='svalue2', value='inTime', format='str')
47 47 # opObj10.addParameter(name='method', value='0', format='float')
48 48 # opObj10.addParameter(name='factor', value='1', format='float')
49 49 # opObj10.addParameter(name='filter', value='0', format='float')
50 50 # opObj10.addParameter(name='npoints', value='5', format='float')
51 51 # opObj10.addParameter(name='modetofilter', value='1', format='int')
52 52 # #
53 53 # opObj10 = procUnitConfObj1.addOperation(name='OutliersFilter')
54 54 # opObj10.addParameter(name='svalue', value='zonal', format='str')
55 55 # opObj10.addParameter(name='svalue2', value='inTime', format='str')
56 56 # opObj10.addParameter(name='method', value='0', format='float')
57 57 # opObj10.addParameter(name='factor', value='1', format='float')
58 58 # opObj10.addParameter(name='filter', value='0', format='float')
59 59 # opObj10.addParameter(name='npoints', value='5', format='float')
60 60 # opObj10.addParameter(name='modetofilter', value='1', format='int')
61 61 # #
62 62 # opObj10 = procUnitConfObj1.addOperation(name='OutliersFilter')
63 63 # opObj10.addParameter(name='svalue', value='vertical', format='str')
64 64 # opObj10.addParameter(name='svalue2', value='inHeight', format='str')
65 65 # opObj10.addParameter(name='method', value='0', format='float')
66 66 # opObj10.addParameter(name='factor', value='2', format='float')
67 67 # opObj10.addParameter(name='filter', value='0', format='float')
68 68 # opObj10.addParameter(name='npoints', value='9', format='float')
69 69 # opObj10.addParameter(name='modetofilter', value='1', format='int')
70 70 #
71 71
72 72 ''' MODE 2: 0 - 10 km '''
73 73
74 74 opObj10 = procUnitConfObj1.addOperation(name='SnrFilter')
75 75 opObj10.addParameter(name='snr_val', value='-20', format='float')
76 76 opObj10.addParameter(name='modetofilter', value='2', format='int')
77 77
78 78 opObj10 = procUnitConfObj1.addOperation(name='OutliersFilter')
79 79 opObj10.addParameter(name='svalue', value='meridional', format='str')
80 80 opObj10.addParameter(name='svalue2', value='inTime', format='str')
81 81 opObj10.addParameter(name='method', value='0', format='float')
82 82 opObj10.addParameter(name='factor', value='2', format='float')
83 83 opObj10.addParameter(name='filter', value='0', format='float')
84 84 opObj10.addParameter(name='npoints', value='9', format='float')
85 85 opObj10.addParameter(name='modetofilter', value='2', format='int')
86 86 # #
87 87 opObj10 = procUnitConfObj1.addOperation(name='OutliersFilter')
88 88 opObj10.addParameter(name='svalue', value='zonal', format='str')
89 89 opObj10.addParameter(name='svalue2', value='inTime', format='str')
90 90 opObj10.addParameter(name='method', value='0', format='float')
91 91 opObj10.addParameter(name='factor', value='2', format='float')
92 92 opObj10.addParameter(name='filter', value='0', format='float')
93 93 opObj10.addParameter(name='npoints', value='9', format='float')
94 94 opObj10.addParameter(name='modetofilter', value='2', format='int')
95 95 # #
96 96 opObj10 = procUnitConfObj1.addOperation(name='OutliersFilter')
97 97 opObj10.addParameter(name='svalue', value='vertical', format='str')
98 98 opObj10.addParameter(name='svalue2', value='inHeight', format='str')
99 99 opObj10.addParameter(name='method', value='0', format='float')
100 100 opObj10.addParameter(name='factor', value='2', format='float')
101 101 opObj10.addParameter(name='filter', value='0', format='float')
102 102 opObj10.addParameter(name='npoints', value='9', format='float')
103 103 opObj10.addParameter(name='modetofilter', value='2', format='int')
104 104
105 105 # '''-----------------------------------------Writing-------------------------------------------'''
106 106 #
107 107 # # opObj10 = procUnitConfObj1.addOperation(name='testBLTRWriter',optype='other')
108 108 # # opObj10.addParameter(name='path', value = pathhdf5)
109 109 # # opObj10.addParameter(name='modetowrite', value = '2',format='int')
110 110 # #
111 111 # # opObj10 = procUnitConfObj1.addOperation(name='testBLTRWriter',optype='other')
112 112 # # opObj10.addParameter(name='path', value = pathhdf5)
113 113 # # opObj10.addParameter(name='modetowrite', value = '1',format='int')
114 114 #
115 115 # '''----------------------------------------Plotting--------------------------------------------'''
116 116 #
117 117 opObj10 = procUnitConfObj1.addOperation(name='prePlot')
118 118 opObj10.addParameter(name='modeselect',value='1',format='int')
119 119 # #
120 120 opObj10 = procUnitConfObj1.addOperation(name='WindProfilerPlot', optype='other')
121 121 opObj10.addParameter(name='id', value='1', format='int')
122 122 opObj10.addParameter(name='wintitle', value='', format='str')
123 123 opObj10.addParameter(name='channelList', value='0', format='intlist')
124 124 #opObj10.addParameter(name='save', value='1', format='bool')
125 125 #opObj10.addParameter(name='figpath', value=figpath, format='str')
126 126 opObj10.addParameter(name='SNRmin', value='-10', format='int')
127 127 opObj10.addParameter(name='SNRmax', value='50', format='int')
128 128 opObj10.addParameter(name='SNRthresh', value='0', format='float')
129 129 opObj10.addParameter(name='xmin', value='0', format='float')
130 130 opObj10.addParameter(name='xmax', value='24', format='float')
131 131 opObj10.addParameter(name='ymax', value='3', format='float')
132 132 opObj10.addParameter(name='zmin', value='-20', format='float')
133 133 opObj10.addParameter(name='zmax', value='20', format='float')
134 134 opObj10.addParameter(name='zmin_ver', value='-200', format='float')
135 135 opObj10.addParameter(name='zmax_ver', value='200', format='float')
136 136 #opObj10.addParameter(name='showprofile', value='1', format='bool')
137 137 #opObj10.addParameter(name='show', value='1', format='bool')
138 138
139 139 opObj10 = procUnitConfObj1.addOperation(name='prePlot')
140 140 opObj10.addParameter(name='modeselect',value='2',format='int')
141 141 #
142 142 opObj10 = procUnitConfObj1.addOperation(name='WindProfilerPlot', optype='other')
143 143 opObj10.addParameter(name='id', value='2', format='int')
144 144 opObj10.addParameter(name='wintitle', value='', format='str')
145 145 #opObj10.addParameter(name='channelList', value='0', format='intlist')
146 #opObj10.addParameter(name='save', value='1', format='bool')
147 #opObj10.addParameter(name='figpath', value=figpath, format='str')
146 opObj10.addParameter(name='save', value='1', format='bool')
147 opObj10.addParameter(name='figpath', value=figpath, format='str')
148 148 opObj10.addParameter(name='SNRmin', value='-20', format='int')
149 149 opObj10.addParameter(name='SNRmax', value='40', format='int')
150 150 opObj10.addParameter(name='SNRthresh', value='0', format='float')
151 151 opObj10.addParameter(name='xmin', value='0', format='float')
152 152 opObj10.addParameter(name='xmax', value='24', format='float')
153 #opObj10.addParameter(name='ymax', value='8', format='float')
153 opObj10.addParameter(name='ymin', value='0', format='float')
154 opObj10.addParameter(name='ymax', value='10', format='float')
154 155 opObj10.addParameter(name='zmin', value='-4', format='float')
155 156 opObj10.addParameter(name='zmax', value='4', format='float')
156 157 opObj10.addParameter(name='zmin_ver', value='-200', format='float')
157 158 opObj10.addParameter(name='zmax_ver', value='200', format='float')
158 159 #opObj10.addParameter(name='showprofile', value='1', format='bool')
159 160 #opObj10.addParameter(name='show', value='1', format='bool')
160 161
161 162 # # print "Escribiendo el archivo XML"
162 163 # controllerObj.writeXml(filename)
163 164 # # print "Leyendo el archivo XML"
164 165 # controllerObj.readXml(filename)
165 166
166 167 # controllerObj.createObjects()
167 168 # controllerObj.connectObjects()
168 169 # controllerObj.run()
169 170 controllerObj.start()
170 171
@@ -1,146 +1,150
1 1 #!/usr/bin/env python
2 2 import os, sys
3 3
4 4 # path = os.path.dirname(os.getcwd())
5 5 # path = os.path.join(path, 'source')
6 6 # sys.path.insert(0, '../')
7 7
8 8 from schainpy.controller import Project
9 9
10 10 xmin = '15.5'
11 11 xmax = '24'
12 12
13
13 14 desc = "ProcBLTR Test"
14 15 filename = "ProcBLTR.xml"
16 figpath = '/media/erick/6F60F7113095A154/BLTR'
15 17
16 18 controllerObj = Project()
17 19
18 20
19 21 controllerObj.setup(id='191', name='test01', description=desc)
20 22
21 23 readUnitConfObj = controllerObj.addReadUnit(datatype='BLTRReader',
22 path='/home/erick/Documents/Data/BLTR_Data/fdt/',
24 path='/media/erick/6F60F7113095A154/BLTR/',
23 25
24 26 endDate='2017/10/19',
25 27 startTime='13:00:00',
26 28 startDate='2016/11/8',
27 29 endTime='23:59:59',
28 30
29 31
30 32 online=0,
31 33 walk=0,
32 34 ReadMode='1')
33 35 # expLabel='')
34 36
35 37 # opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock')
36 38
37 39 procUnitConfObj1 = controllerObj.addProcUnit(datatype='Spectra', inputId=readUnitConfObj.getId())
38 40
39 41
40 42
41 43 opObj11 = procUnitConfObj1.addOperation(name='IncohInt', optype='other')
42 opObj11.addParameter(name='n', value='2', format='float')
44 opObj11.addParameter(name='n', value='3', format='float')
43 45
44 46 opObj10 = procUnitConfObj1.addOperation(name='removeDC')
45 47
46 48 # opObj10 = procUnitConfObj1.addOperation(name='calcMag')
47 49
48 50 # opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other')
49 51 # opObj11.addParameter(name='id', value='21', format='int')
50 52 # opObj11.addParameter(name='wintitle', value='SpectraCutPlot', format='str')
51 53 # opObj11.addParameter(name='xaxis', value='frequency', format='str')
52 54 # opObj11.addParameter(name='colormap', value='winter', format='str')
53 55 # opObj11.addParameter(name='xmin', value='-0.005', format='float')
54 56 # opObj11.addParameter(name='xmax', value='0.005', format='float')
55 57 # #opObj10 = procUnitConfObj1.addOperation(name='selectChannels')
56 58 # #opObj10.addParameter(name='channelList', value='0,1', format='intlist')
57 59 # opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other')
58 60 # opObj11.addParameter(name='id', value='21', format='int')
59 61 # opObj11.addParameter(name='wintitle', value='SpectraPlot', format='str')
60 62 # #opObj11.addParameter(name='xaxis', value='Velocity', format='str')
61 63
62 64 # opObj11.addParameter(name='xaxis', value='velocity', format='str')
63 65 # opObj11.addParameter(name='xmin', value='-0.005', format='float')
64 66 # opObj11.addParameter(name='xmax', value='0.005', format='float')
65 67
66 68 # opObj11.addParameter(name='ymin', value='225', format='float')
67 69 # opObj11.addParameter(name='ymax', value='3000', format='float')
68 70 # opObj11.addParameter(name='zmin', value='-100', format='int')
69 71 # opObj11.addParameter(name='zmax', value='-65', format='int')
70 72
71 73 # opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other')
72 74 # opObj11.addParameter(name='id', value='10', format='int')
73 75 # opObj11.addParameter(name='wintitle', value='RTI', format='str')
74 76 # opObj11.addParameter(name='ymin', value='0', format='float')
75 77 # opObj11.addParameter(name='ymax', value='4000', format='float')
76 78 # #opObj11.addParameter(name='zmin', value='-100', format='int')
77 79 # #opObj11.addParameter(name='zmax', value='-70', format='int')
78 80 # opObj11.addParameter(name='zmin', value='-90', format='int')
79 81 # opObj11.addParameter(name='zmax', value='-40', format='int')
80 82 # opObj11.addParameter(name='showprofile', value='1', format='int')
81 83 # opObj11.addParameter(name='timerange', value=str(2*60*60), format='int')
82 84
83 85 opObj11 = procUnitConfObj1.addOperation(name='CrossSpectraPlot', optype='other')
84 86 procUnitConfObj1.addParameter(name='pairsList', value='(0,1),(0,2),(1,2)', format='pairsList')
85 87 opObj11.addParameter(name='id', value='2005', format='int')
86 88 opObj11.addParameter(name='wintitle', value='CrossSpectraPlot_ShortPulse', format='str')
87 89 # opObj11.addParameter(name='exp_code', value='13', format='int')
88 90 opObj11.addParameter(name='xaxis', value='Velocity', format='str')
89 91 #opObj11.addParameter(name='xmin', value='-10', format='float')
90 92 #opObj11.addParameter(name='xmax', value='10', format='float')
91 93 #opObj11.addParameter(name='ymin', value='225', format='float')
92 94 #opObj11.addParameter(name='ymax', value='3000', format='float')
93 95 #opObj11.addParameter(name='phase_min', value='-4', format='int')
94 96 #opObj11.addParameter(name='phase_max', value='4', format='int')
95 97
96 98 # procUnitConfObj2 = controllerObj.addProcUnit(datatype='CorrelationProc', inputId=procUnitConfObj1.getId())
97 99 # procUnitConfObj2.addParameter(name='pairsList', value='(0,1),(0,2),(1,2)', format='pairsList')
98 100
99 101 procUnitConfObj2 = controllerObj.addProcUnit(datatype='Parameters', inputId=procUnitConfObj1.getId())
100 102 opObj11 = procUnitConfObj2.addOperation(name='SpectralMoments', optype='other')
101 103 opObj22 = procUnitConfObj2.addOperation(name='FullSpectralAnalysis', optype='other')
102 104 #
103 105 opObj22 = procUnitConfObj2.addOperation(name='WindProfilerPlot', optype='other')
104 106 opObj22.addParameter(name='id', value='4', format='int')
105 107 opObj22.addParameter(name='wintitle', value='Wind Profiler', format='str')
106 108 opObj22.addParameter(name='save', value='1', format='bool')
107 109 # opObj22.addParameter(name='figpath', value = '/home/erick/Pictures', format='str')
108
110
109 111 opObj22.addParameter(name='zmin', value='-20', format='int')
110 112 opObj22.addParameter(name='zmax', value='20', format='int')
111 113 opObj22.addParameter(name='zmin_ver', value='-250', format='float')
112 114 opObj22.addParameter(name='zmax_ver', value='250', format='float')
113 115 opObj22.addParameter(name='SNRmin', value='-5', format='int')
114 116 opObj22.addParameter(name='SNRmax', value='30', format='int')
115 117 # opObj22.addParameter(name='SNRthresh', value='-3.5', format='float')
116 118 opObj22.addParameter(name='xmin', value=0, format='float')
117 119 opObj22.addParameter(name='xmax', value=24, format='float')
118 120 opObj22.addParameter(name='ymin', value='225', format='float')
119 121 #opObj22.addParameter(name='ymax', value='2000', format='float')
120
121
122 opObj22.addParameter(name='save', value='1', format='int')
123 opObj22.addParameter(name='figpath', value=figpath, format='str')
124
125
122 126 # opObj11.addParameter(name='pairlist', value='(1,0),(0,2),(1,2)', format='pairsList')
123 127 #opObj10 = procUnitConfObj1.addOperation(name='selectHeights')
124 128 #opObj10.addParameter(name='minHei', value='225', format='float')
125 129 #opObj10.addParameter(name='maxHei', value='1000', format='float')
126
130
127 131 # opObj11 = procUnitConfObj1.addOperation(name='CoherenceMap', optype='other')
128 132 # opObj11.addParameter(name='id', value='102', format='int')
129 133 # opObj11.addParameter(name='wintitle', value='Coherence', format='str')
130 134 # opObj11.addParameter(name='ymin', value='225', format='float')
131 135 # opObj11.addParameter(name='ymax', value='4000', format='float')
132
136
133 137 # opObj11.addParameter(name='phase_cmap', value='jet', format='str')
134 138 # opObj11.addParameter(name='xmin', value='8.5', format='float')
135 139 # opObj11.addParameter(name='xmax', value='9.5', format='float')
136 140 # opObj11.addParameter(name='figpath', value=figpath, format='str')
137 141 # opObj11.addParameter(name='save', value=1, format='bool')
138 142 # opObj11.addParameter(name='pairsList', value='(1,0),(3,2)', format='pairsList')
139 143
140 144 # opObj12 = procUnitConfObj1.addOperation(name='PublishData', optype='other')
141 145 # opObj12.addParameter(name='zeromq', value=1, format='int')
142 146 # opObj12.addParameter(name='verbose', value=0, format='bool')
143 147 # opObj12.addParameter(name='server', value='erick2', format='str')
144 148 controllerObj.start()
145 149
146 150
1 NO CONTENT: modified file, binary diff hidden
General Comments 0
You need to be logged in to leave comments. Login now