@@ -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 |
|
|
|
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 |
|
|
|
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, |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
|
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='201 |
|
|
29 |
endDate='201 |
|
|
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 |
|
|
|
147 |
|
|
|
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 |
|
|
|
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='/ |
|
|
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=' |
|
|
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