##// END OF EJS Templates
update readNextUnit y minHei case equal 0
Alexander Valdez -
r1675:d3470f93cd6c
parent child
Show More
@@ -1,661 +1,661
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """API to create signal chain projects
5 """API to create signal chain projects
6
6
7 The API is provide through class: Project
7 The API is provide through class: Project
8 """
8 """
9
9
10 import re
10 import re
11 import sys
11 import sys
12 import ast
12 import ast
13 import datetime
13 import datetime
14 import traceback
14 import traceback
15 import time
15 import time
16 import multiprocessing
16 import multiprocessing
17 from multiprocessing import Process, Queue
17 from multiprocessing import Process, Queue
18 from threading import Thread
18 from threading import Thread
19 from xml.etree.ElementTree import ElementTree, Element, SubElement
19 from xml.etree.ElementTree import ElementTree, Element, SubElement
20
20
21 from schainpy.admin import Alarm, SchainWarning
21 from schainpy.admin import Alarm, SchainWarning
22 from schainpy.model import *
22 from schainpy.model import *
23 from schainpy.utils import log
23 from schainpy.utils import log
24
24
25 if 'darwin' in sys.platform and sys.version_info[0] == 3 and sys.version_info[1] > 7:
25 if 'darwin' in sys.platform and sys.version_info[0] == 3 and sys.version_info[1] > 7:
26 multiprocessing.set_start_method('fork')
26 multiprocessing.set_start_method('fork')
27
27
28 class ConfBase():
28 class ConfBase():
29
29
30 def __init__(self):
30 def __init__(self):
31
31
32 self.id = '0'
32 self.id = '0'
33 self.name = None
33 self.name = None
34 self.priority = None
34 self.priority = None
35 self.parameters = {}
35 self.parameters = {}
36 self.object = None
36 self.object = None
37 self.operations = []
37 self.operations = []
38
38
39 def getId(self):
39 def getId(self):
40
40
41 return self.id
41 return self.id
42
42
43 def getNewId(self):
43 def getNewId(self):
44
44
45 return int(self.id) * 10 + len(self.operations) + 1
45 return int(self.id) * 10 + len(self.operations) + 1
46
46
47 def updateId(self, new_id):
47 def updateId(self, new_id):
48
48
49 self.id = str(new_id)
49 self.id = str(new_id)
50
50
51 n = 1
51 n = 1
52 for conf in self.operations:
52 for conf in self.operations:
53 conf_id = str(int(new_id) * 10 + n)
53 conf_id = str(int(new_id) * 10 + n)
54 conf.updateId(conf_id)
54 conf.updateId(conf_id)
55 n += 1
55 n += 1
56
56
57 def getKwargs(self):
57 def getKwargs(self):
58
58
59 params = {}
59 params = {}
60
60
61 for key, value in self.parameters.items():
61 for key, value in self.parameters.items():
62 if value not in (None, '', ' '):
62 if value not in (None, '', ' '):
63 params[key] = value
63 params[key] = value
64
64
65 return params
65 return params
66
66
67 def update(self, **kwargs):
67 def update(self, **kwargs):
68
68
69 for key, value in kwargs.items():
69 for key, value in kwargs.items():
70 self.addParameter(name=key, value=value)
70 self.addParameter(name=key, value=value)
71
71
72 def addParameter(self, name, value, format=None):
72 def addParameter(self, name, value, format=None):
73 '''
73 '''
74 '''
74 '''
75
75
76 if isinstance(value, str) and re.search(r'(\d+/\d+/\d+)', value):
76 if isinstance(value, str) and re.search(r'(\d+/\d+/\d+)', value):
77 self.parameters[name] = datetime.date(*[int(x) for x in value.split('/')])
77 self.parameters[name] = datetime.date(*[int(x) for x in value.split('/')])
78 elif isinstance(value, str) and re.search(r'(\d+:\d+:\d+)', value):
78 elif isinstance(value, str) and re.search(r'(\d+:\d+:\d+)', value):
79 self.parameters[name] = datetime.time(*[int(x) for x in value.split(':')])
79 self.parameters[name] = datetime.time(*[int(x) for x in value.split(':')])
80 else:
80 else:
81 try:
81 try:
82 self.parameters[name] = ast.literal_eval(value)
82 self.parameters[name] = ast.literal_eval(value)
83 except:
83 except:
84 if isinstance(value, str) and ',' in value:
84 if isinstance(value, str) and ',' in value:
85 self.parameters[name] = value.split(',')
85 self.parameters[name] = value.split(',')
86 else:
86 else:
87 self.parameters[name] = value
87 self.parameters[name] = value
88
88
89 def getParameters(self):
89 def getParameters(self):
90
90
91 params = {}
91 params = {}
92 for key, value in self.parameters.items():
92 for key, value in self.parameters.items():
93 s = type(value).__name__
93 s = type(value).__name__
94 if s == 'date':
94 if s == 'date':
95 params[key] = value.strftime('%Y/%m/%d')
95 params[key] = value.strftime('%Y/%m/%d')
96 elif s == 'time':
96 elif s == 'time':
97 params[key] = value.strftime('%H:%M:%S')
97 params[key] = value.strftime('%H:%M:%S')
98 else:
98 else:
99 params[key] = str(value)
99 params[key] = str(value)
100
100
101 return params
101 return params
102
102
103 def makeXml(self, element):
103 def makeXml(self, element):
104
104
105 xml = SubElement(element, self.ELEMENTNAME)
105 xml = SubElement(element, self.ELEMENTNAME)
106 for label in self.xml_labels:
106 for label in self.xml_labels:
107 xml.set(label, str(getattr(self, label)))
107 xml.set(label, str(getattr(self, label)))
108
108
109 for key, value in self.getParameters().items():
109 for key, value in self.getParameters().items():
110 xml_param = SubElement(xml, 'Parameter')
110 xml_param = SubElement(xml, 'Parameter')
111 xml_param.set('name', key)
111 xml_param.set('name', key)
112 xml_param.set('value', value)
112 xml_param.set('value', value)
113
113
114 for conf in self.operations:
114 for conf in self.operations:
115 conf.makeXml(xml)
115 conf.makeXml(xml)
116
116
117 def __str__(self):
117 def __str__(self):
118
118
119 if self.ELEMENTNAME == 'Operation':
119 if self.ELEMENTNAME == 'Operation':
120 s = ' {}[id={}]\n'.format(self.name, self.id)
120 s = ' {}[id={}]\n'.format(self.name, self.id)
121 else:
121 else:
122 s = '{}[id={}, inputId={}]\n'.format(self.name, self.id, self.inputId)
122 s = '{}[id={}, inputId={}]\n'.format(self.name, self.id, self.inputId)
123
123
124 for key, value in self.parameters.items():
124 for key, value in self.parameters.items():
125 if self.ELEMENTNAME == 'Operation':
125 if self.ELEMENTNAME == 'Operation':
126 s += ' {}: {}\n'.format(key, value)
126 s += ' {}: {}\n'.format(key, value)
127 else:
127 else:
128 s += ' {}: {}\n'.format(key, value)
128 s += ' {}: {}\n'.format(key, value)
129
129
130 for conf in self.operations:
130 for conf in self.operations:
131 s += str(conf)
131 s += str(conf)
132
132
133 return s
133 return s
134
134
135 class OperationConf(ConfBase):
135 class OperationConf(ConfBase):
136
136
137 ELEMENTNAME = 'Operation'
137 ELEMENTNAME = 'Operation'
138 xml_labels = ['id', 'name']
138 xml_labels = ['id', 'name']
139
139
140 def setup(self, id, name, priority, project_id, err_queue):
140 def setup(self, id, name, priority, project_id, err_queue):
141
141
142 self.id = str(id)
142 self.id = str(id)
143 self.project_id = project_id
143 self.project_id = project_id
144 self.name = name
144 self.name = name
145 self.type = 'other'
145 self.type = 'other'
146 self.err_queue = err_queue
146 self.err_queue = err_queue
147
147
148 def readXml(self, element, project_id, err_queue):
148 def readXml(self, element, project_id, err_queue):
149
149
150 self.id = element.get('id')
150 self.id = element.get('id')
151 self.name = element.get('name')
151 self.name = element.get('name')
152 self.type = 'other'
152 self.type = 'other'
153 self.project_id = str(project_id)
153 self.project_id = str(project_id)
154 self.err_queue = err_queue
154 self.err_queue = err_queue
155
155
156 for elm in element.iter('Parameter'):
156 for elm in element.iter('Parameter'):
157 self.addParameter(elm.get('name'), elm.get('value'))
157 self.addParameter(elm.get('name'), elm.get('value'))
158
158
159 def createObject(self):
159 def createObject(self):
160
160
161 className = eval(self.name)
161 className = eval(self.name)
162
162
163 if 'Plot' in self.name or 'Writer' in self.name or 'Send' in self.name or 'print' in self.name:
163 if 'Plot' in self.name or 'Writer' in self.name or 'Send' in self.name or 'print' in self.name:
164 kwargs = self.getKwargs()
164 kwargs = self.getKwargs()
165 opObj = className(self.id, self.id, self.project_id, self.err_queue, **kwargs)
165 opObj = className(self.id, self.id, self.project_id, self.err_queue, **kwargs)
166 opObj.start()
166 opObj.start()
167 self.type = 'external'
167 self.type = 'external'
168 else:
168 else:
169 opObj = className()
169 opObj = className()
170
170
171 self.object = opObj
171 self.object = opObj
172 return opObj
172 return opObj
173
173
174 class ProcUnitConf(ConfBase):
174 class ProcUnitConf(ConfBase):
175
175
176 ELEMENTNAME = 'ProcUnit'
176 ELEMENTNAME = 'ProcUnit'
177 xml_labels = ['id', 'inputId', 'name']
177 xml_labels = ['id', 'inputId', 'name']
178
178
179 def setup(self, project_id, id, name, datatype, inputId, err_queue):
179 def setup(self, project_id, id, name, datatype, inputId, err_queue):
180 '''
180 '''
181 '''
181 '''
182
182
183 if datatype == None and name == None:
183 if datatype == None and name == None:
184 raise ValueError('datatype or name should be defined')
184 raise ValueError('datatype or name should be defined')
185
185
186 if name == None:
186 if name == None:
187 if 'Proc' in datatype:
187 if 'Proc' in datatype:
188 name = datatype
188 name = datatype
189 else:
189 else:
190 name = '%sProc' % (datatype)
190 name = '%sProc' % (datatype)
191
191
192 if datatype == None:
192 if datatype == None:
193 datatype = name.replace('Proc', '')
193 datatype = name.replace('Proc', '')
194
194
195 self.id = str(id)
195 self.id = str(id)
196 self.project_id = project_id
196 self.project_id = project_id
197 self.name = name
197 self.name = name
198 self.datatype = datatype
198 self.datatype = datatype
199 self.inputId = inputId
199 self.inputId = inputId
200 self.err_queue = err_queue
200 self.err_queue = err_queue
201 self.operations = []
201 self.operations = []
202 self.parameters = {}
202 self.parameters = {}
203
203
204 def removeOperation(self, id):
204 def removeOperation(self, id):
205
205
206 i = [1 if x.id==id else 0 for x in self.operations]
206 i = [1 if x.id==id else 0 for x in self.operations]
207 self.operations.pop(i.index(1))
207 self.operations.pop(i.index(1))
208
208
209 def getOperation(self, id):
209 def getOperation(self, id):
210
210
211 for conf in self.operations:
211 for conf in self.operations:
212 if conf.id == id:
212 if conf.id == id:
213 return conf
213 return conf
214
214
215 def addOperation(self, name, optype='self'):
215 def addOperation(self, name, optype='self'):
216 '''
216 '''
217 '''
217 '''
218
218
219 id = self.getNewId()
219 id = self.getNewId()
220 conf = OperationConf()
220 conf = OperationConf()
221 conf.setup(id, name=name, priority='0', project_id=self.project_id, err_queue=self.err_queue)
221 conf.setup(id, name=name, priority='0', project_id=self.project_id, err_queue=self.err_queue)
222 self.operations.append(conf)
222 self.operations.append(conf)
223
223
224 return conf
224 return conf
225
225
226 def readXml(self, element, project_id, err_queue):
226 def readXml(self, element, project_id, err_queue):
227
227
228 self.id = element.get('id')
228 self.id = element.get('id')
229 self.name = element.get('name')
229 self.name = element.get('name')
230 self.inputId = None if element.get('inputId') == 'None' else element.get('inputId')
230 self.inputId = None if element.get('inputId') == 'None' else element.get('inputId')
231 self.datatype = element.get('datatype', self.name.replace(self.ELEMENTNAME.replace('Unit', ''), ''))
231 self.datatype = element.get('datatype', self.name.replace(self.ELEMENTNAME.replace('Unit', ''), ''))
232 self.project_id = str(project_id)
232 self.project_id = str(project_id)
233 self.err_queue = err_queue
233 self.err_queue = err_queue
234 self.operations = []
234 self.operations = []
235 self.parameters = {}
235 self.parameters = {}
236
236
237 for elm in element:
237 for elm in element:
238 if elm.tag == 'Parameter':
238 if elm.tag == 'Parameter':
239 self.addParameter(elm.get('name'), elm.get('value'))
239 self.addParameter(elm.get('name'), elm.get('value'))
240 elif elm.tag == 'Operation':
240 elif elm.tag == 'Operation':
241 conf = OperationConf()
241 conf = OperationConf()
242 conf.readXml(elm, project_id, err_queue)
242 conf.readXml(elm, project_id, err_queue)
243 self.operations.append(conf)
243 self.operations.append(conf)
244
244
245 def createObjects(self):
245 def createObjects(self):
246 '''
246 '''
247 Instancia de unidades de procesamiento.
247 Instancia de unidades de procesamiento.
248 '''
248 '''
249
249
250 className = eval(self.name)
250 className = eval(self.name)
251 kwargs = self.getKwargs()
251 kwargs = self.getKwargs()
252 procUnitObj = className()
252 procUnitObj = className()
253 procUnitObj.name = self.name
253 procUnitObj.name = self.name
254 log.success('creating process...', self.name)
254 log.success('creating process...', self.name)
255
255
256 for conf in self.operations:
256 for conf in self.operations:
257
257
258 opObj = conf.createObject()
258 opObj = conf.createObject()
259
259
260 log.success('adding operation: {}, type:{}'.format(
260 log.success('adding operation: {}, type:{}'.format(
261 conf.name,
261 conf.name,
262 conf.type), self.name)
262 conf.type), self.name)
263
263
264 procUnitObj.addOperation(conf, opObj)
264 procUnitObj.addOperation(conf, opObj)
265
265
266 self.object = procUnitObj
266 self.object = procUnitObj
267
267
268 def run(self):
268 def run(self):
269 '''
269 '''
270 '''
270 '''
271
271
272 return self.object.call(**self.getKwargs())
272 return self.object.call(**self.getKwargs())
273
273
274
274
275 class ReadUnitConf(ProcUnitConf):
275 class ReadUnitConf(ProcUnitConf):
276
276
277 ELEMENTNAME = 'ReadUnit'
277 ELEMENTNAME = 'ReadUnit'
278
278
279 def __init__(self):
279 def __init__(self):
280
280
281 self.id = None
281 self.id = None
282 self.datatype = None
282 self.datatype = None
283 self.name = None
283 self.name = None
284 self.inputId = None
284 self.inputId = None
285 self.operations = []
285 self.operations = []
286 self.parameters = {}
286 self.parameters = {}
287
287
288 def setup(self, project_id, id, name, datatype, err_queue, path='', startDate='', endDate='',
288 def setup(self, project_id, id, name, datatype, err_queue, path='', startDate='', endDate='',
289 startTime='', endTime='', server=None, **kwargs):
289 startTime='', endTime='', server=None, **kwargs):
290
290
291 if datatype == None and name == None:
291 if datatype == None and name == None:
292 raise ValueError('datatype or name should be defined')
292 raise ValueError('datatype or name should be defined')
293 if name == None:
293 if name == None:
294 if 'Reader' in datatype:
294 if 'Reader' in datatype:
295 name = datatype
295 name = datatype
296 datatype = name.replace('Reader','')
296 datatype = name.replace('Reader', '')
297 else:
297 else:
298 name = '{}Reader'.format(datatype)
298 name = '{}Reader'.format(datatype)
299 if datatype == None:
299 if datatype == None:
300 if 'Reader' in name:
300 if 'Reader' in name:
301 datatype = name.replace('Reader','')
301 datatype = name.replace('Reader', '')
302 else:
302 else:
303 datatype = name
303 datatype = name
304 name = '{}Reader'.format(name)
304 name = '{}Reader'.format(name)
305
305
306 self.id = id
306 self.id = id
307 self.project_id = project_id
307 self.project_id = project_id
308 self.name = name
308 self.name = name
309 self.datatype = datatype
309 self.datatype = datatype
310 self.err_queue = err_queue
310 self.err_queue = err_queue
311
311
312 self.addParameter(name='path', value=path)
312 self.addParameter(name='path', value=path)
313 self.addParameter(name='startDate', value=startDate)
313 self.addParameter(name='startDate', value=startDate)
314 self.addParameter(name='endDate', value=endDate)
314 self.addParameter(name='endDate', value=endDate)
315 self.addParameter(name='startTime', value=startTime)
315 self.addParameter(name='startTime', value=startTime)
316 self.addParameter(name='endTime', value=endTime)
316 self.addParameter(name='endTime', value=endTime)
317
317
318 for key, value in kwargs.items():
318 for key, value in kwargs.items():
319 self.addParameter(name=key, value=value)
319 self.addParameter(name=key, value=value)
320
320
321
321
322 class Project(Process):
322 class Project(Process):
323 """API to create signal chain projects"""
323 """API to create signal chain projects"""
324
324
325 ELEMENTNAME = 'Project'
325 ELEMENTNAME = 'Project'
326
326
327 def __init__(self, name=''):
327 def __init__(self, name=''):
328
328
329 Process.__init__(self)
329 Process.__init__(self)
330 self.id = '1'
330 self.id = '1'
331 if name:
331 if name:
332 self.name = '{} ({})'.format(Process.__name__, name)
332 self.name = '{} ({})'.format(Process.__name__, name)
333 self.filename = None
333 self.filename = None
334 self.description = None
334 self.description = None
335 self.email = None
335 self.email = None
336 self.alarm = []
336 self.alarm = []
337 self.configurations = {}
337 self.configurations = {}
338 # self.err_queue = Queue()
338 # self.err_queue = Queue()
339 self.err_queue = None
339 self.err_queue = None
340 self.started = False
340 self.started = False
341
341
342 def getNewId(self):
342 def getNewId(self):
343
343
344 idList = list(self.configurations.keys())
344 idList = list(self.configurations.keys())
345 id = int(self.id) * 10
345 id = int(self.id) * 10
346
346
347 while True:
347 while True:
348 id += 1
348 id += 1
349
349
350 if str(id) in idList:
350 if str(id) in idList:
351 continue
351 continue
352
352
353 break
353 break
354
354
355 return str(id)
355 return str(id)
356
356
357 def updateId(self, new_id):
357 def updateId(self, new_id):
358
358
359 self.id = str(new_id)
359 self.id = str(new_id)
360
360
361 keyList = list(self.configurations.keys())
361 keyList = list(self.configurations.keys())
362 keyList.sort()
362 keyList.sort()
363
363
364 n = 1
364 n = 1
365 new_confs = {}
365 new_confs = {}
366
366
367 for procKey in keyList:
367 for procKey in keyList:
368
368
369 conf = self.configurations[procKey]
369 conf = self.configurations[procKey]
370 idProcUnit = str(int(self.id) * 10 + n)
370 idProcUnit = str(int(self.id) * 10 + n)
371 conf.updateId(idProcUnit)
371 conf.updateId(idProcUnit)
372 new_confs[idProcUnit] = conf
372 new_confs[idProcUnit] = conf
373 n += 1
373 n += 1
374
374
375 self.configurations = new_confs
375 self.configurations = new_confs
376
376
377 def setup(self, id=1, name='', description='', email=None, alarm=[]):
377 def setup(self, id=1, name='', description='', email=None, alarm=[]):
378
378
379 self.id = str(id)
379 self.id = str(id)
380 self.description = description
380 self.description = description
381 self.email = email
381 self.email = email
382 self.alarm = alarm
382 self.alarm = alarm
383 if name:
383 if name:
384 self.name = '{} ({})'.format(Process.__name__, name)
384 self.name = '{} ({})'.format(Process.__name__, name)
385
385
386 def update(self, **kwargs):
386 def update(self, **kwargs):
387
387
388 for key, value in kwargs.items():
388 for key, value in kwargs.items():
389 setattr(self, key, value)
389 setattr(self, key, value)
390
390
391 def clone(self):
391 def clone(self):
392
392
393 p = Project()
393 p = Project()
394 p.id = self.id
394 p.id = self.id
395 p.name = self.name
395 p.name = self.name
396 p.description = self.description
396 p.description = self.description
397 p.configurations = self.configurations.copy()
397 p.configurations = self.configurations.copy()
398
398
399 return p
399 return p
400
400
401 def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
401 def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
402
402
403 '''
403 '''
404 '''
404 '''
405
405
406 if id is None:
406 if id is None:
407 idReadUnit = self.getNewId()
407 idReadUnit = self.getNewId()
408 else:
408 else:
409 idReadUnit = str(id)
409 idReadUnit = str(id)
410
410
411 conf = ReadUnitConf()
411 conf = ReadUnitConf()
412 conf.setup(self.id, idReadUnit, name, datatype, self.err_queue, **kwargs)
412 conf.setup(self.id, idReadUnit, name, datatype, self.err_queue, **kwargs)
413 self.configurations[conf.id] = conf
413 self.configurations[conf.id] = conf
414
414
415 return conf
415 return conf
416
416
417 def addProcUnit(self, id=None, inputId='0', datatype=None, name=None):
417 def addProcUnit(self, id=None, inputId='0', datatype=None, name=None):
418
418
419 '''
419 '''
420 '''
420 '''
421
421
422 if id is None:
422 if id is None:
423 idProcUnit = self.getNewId()
423 idProcUnit = self.getNewId()
424 else:
424 else:
425 idProcUnit = id
425 idProcUnit = id
426
426
427 conf = ProcUnitConf()
427 conf = ProcUnitConf()
428 conf.setup(self.id, idProcUnit, name, datatype, inputId, self.err_queue)
428 conf.setup(self.id, idProcUnit, name, datatype, inputId, self.err_queue)
429 self.configurations[conf.id] = conf
429 self.configurations[conf.id] = conf
430
430
431 return conf
431 return conf
432
432
433 def removeProcUnit(self, id):
433 def removeProcUnit(self, id):
434
434
435 if id in self.configurations:
435 if id in self.configurations:
436 self.configurations.pop(id)
436 self.configurations.pop(id)
437
437
438 def getReadUnit(self):
438 def getReadUnit(self):
439
439
440 for obj in list(self.configurations.values()):
440 for obj in list(self.configurations.values()):
441 if obj.ELEMENTNAME == 'ReadUnit':
441 if obj.ELEMENTNAME == 'ReadUnit':
442 return obj
442 return obj
443
443
444 return None
444 return None
445
445
446 def getProcUnit(self, id):
446 def getProcUnit(self, id):
447
447
448 return self.configurations[id]
448 return self.configurations[id]
449
449
450 def getUnits(self):
450 def getUnits(self):
451
451
452 keys = list(self.configurations)
452 keys = list(self.configurations)
453 keys.sort()
453 keys.sort()
454
454
455 for key in keys:
455 for key in keys:
456 yield self.configurations[key]
456 yield self.configurations[key]
457
457
458 def updateUnit(self, id, **kwargs):
458 def updateUnit(self, id, **kwargs):
459
459
460 conf = self.configurations[id].update(**kwargs)
460 conf = self.configurations[id].update(**kwargs)
461
461
462 def makeXml(self):
462 def makeXml(self):
463
463
464 xml = Element('Project')
464 xml = Element('Project')
465 xml.set('id', str(self.id))
465 xml.set('id', str(self.id))
466 xml.set('name', self.name)
466 xml.set('name', self.name)
467 xml.set('description', self.description)
467 xml.set('description', self.description)
468
468
469 for conf in self.configurations.values():
469 for conf in self.configurations.values():
470 conf.makeXml(xml)
470 conf.makeXml(xml)
471
471
472 self.xml = xml
472 self.xml = xml
473
473
474 def writeXml(self, filename=None):
474 def writeXml(self, filename=None):
475
475
476 if filename == None:
476 if filename == None:
477 if self.filename:
477 if self.filename:
478 filename = self.filename
478 filename = self.filename
479 else:
479 else:
480 filename = 'schain.xml'
480 filename = 'schain.xml'
481
481
482 if not filename:
482 if not filename:
483 print('filename has not been defined. Use setFilename(filename) for do it.')
483 print('filename has not been defined. Use setFilename(filename) for do it.')
484 return 0
484 return 0
485
485
486 abs_file = os.path.abspath(filename)
486 abs_file = os.path.abspath(filename)
487
487
488 if not os.access(os.path.dirname(abs_file), os.W_OK):
488 if not os.access(os.path.dirname(abs_file), os.W_OK):
489 print('No write permission on %s' % os.path.dirname(abs_file))
489 print('No write permission on %s' % os.path.dirname(abs_file))
490 return 0
490 return 0
491
491
492 if os.path.isfile(abs_file) and not(os.access(abs_file, os.W_OK)):
492 if os.path.isfile(abs_file) and not(os.access(abs_file, os.W_OK)):
493 print('File %s already exists and it could not be overwriten' % abs_file)
493 print('File %s already exists and it could not be overwriten' % abs_file)
494 return 0
494 return 0
495
495
496 self.makeXml()
496 self.makeXml()
497
497
498 ElementTree(self.xml).write(abs_file, method='xml')
498 ElementTree(self.xml).write(abs_file, method='xml')
499
499
500 self.filename = abs_file
500 self.filename = abs_file
501
501
502 return 1
502 return 1
503
503
504 def readXml(self, filename):
504 def readXml(self, filename):
505
505
506 abs_file = os.path.abspath(filename)
506 abs_file = os.path.abspath(filename)
507
507
508 self.configurations = {}
508 self.configurations = {}
509
509
510 try:
510 try:
511 self.xml = ElementTree().parse(abs_file)
511 self.xml = ElementTree().parse(abs_file)
512 except:
512 except:
513 log.error('Error reading %s, verify file format' % filename)
513 log.error('Error reading %s, verify file format' % filename)
514 return 0
514 return 0
515
515
516 self.id = self.xml.get('id')
516 self.id = self.xml.get('id')
517 self.name = self.xml.get('name')
517 self.name = self.xml.get('name')
518 self.description = self.xml.get('description')
518 self.description = self.xml.get('description')
519
519
520 for element in self.xml:
520 for element in self.xml:
521 if element.tag == 'ReadUnit':
521 if element.tag == 'ReadUnit':
522 conf = ReadUnitConf()
522 conf = ReadUnitConf()
523 conf.readXml(element, self.id, self.err_queue)
523 conf.readXml(element, self.id, self.err_queue)
524 self.configurations[conf.id] = conf
524 self.configurations[conf.id] = conf
525 elif element.tag == 'ProcUnit':
525 elif element.tag == 'ProcUnit':
526 conf = ProcUnitConf()
526 conf = ProcUnitConf()
527 input_proc = self.configurations[element.get('inputId')]
527 input_proc = self.configurations[element.get('inputId')]
528 conf.readXml(element, self.id, self.err_queue)
528 conf.readXml(element, self.id, self.err_queue)
529 self.configurations[conf.id] = conf
529 self.configurations[conf.id] = conf
530
530
531 self.filename = abs_file
531 self.filename = abs_file
532
532
533 return 1
533 return 1
534
534
535 def __str__(self):
535 def __str__(self):
536
536
537 text = '\nProject[id=%s, name=%s, description=%s]\n\n' % (
537 text = '\nProject[id=%s, name=%s, description=%s]\n\n' % (
538 self.id,
538 self.id,
539 self.name,
539 self.name,
540 self.description,
540 self.description,
541 )
541 )
542
542
543 for conf in self.configurations.values():
543 for conf in self.configurations.values():
544 text += '{}'.format(conf)
544 text += '{}'.format(conf)
545
545
546 return text
546 return text
547
547
548 def createObjects(self):
548 def createObjects(self):
549
549
550 keys = list(self.configurations.keys())
550 keys = list(self.configurations.keys())
551 keys.sort()
551 keys.sort()
552 for key in keys:
552 for key in keys:
553 conf = self.configurations[key]
553 conf = self.configurations[key]
554 conf.createObjects()
554 conf.createObjects()
555 if conf.inputId is not None:
555 if conf.inputId is not None:
556 if isinstance(conf.inputId, list):
556 if isinstance(conf.inputId, list):
557 conf.object.setInput([self.configurations[x].object for x in conf.inputId])
557 conf.object.setInput([self.configurations[x].object for x in conf.inputId])
558 else:
558 else:
559 conf.object.setInput([self.configurations[conf.inputId].object])
559 conf.object.setInput([self.configurations[conf.inputId].object])
560
560
561 def monitor(self):
561 def monitor(self):
562
562
563 t = Thread(target=self._monitor, args=(self.err_queue, self.ctx))
563 t = Thread(target=self._monitor, args=(self.err_queue, self.ctx))
564 t.start()
564 t.start()
565
565
566 def _monitor(self, queue, ctx):
566 def _monitor(self, queue, ctx):
567
567
568 import socket
568 import socket
569
569
570 procs = 0
570 procs = 0
571 err_msg = ''
571 err_msg = ''
572
572
573 while True:
573 while True:
574 msg = queue.get()
574 msg = queue.get()
575 if '#_start_#' in msg:
575 if '#_start_#' in msg:
576 procs += 1
576 procs += 1
577 elif '#_end_#' in msg:
577 elif '#_end_#' in msg:
578 procs -=1
578 procs -=1
579 else:
579 else:
580 err_msg = msg
580 err_msg = msg
581
581
582 if procs == 0 or 'Traceback' in err_msg:
582 if procs == 0 or 'Traceback' in err_msg:
583 break
583 break
584 time.sleep(0.1)
584 time.sleep(0.1)
585
585
586 if '|' in err_msg:
586 if '|' in err_msg:
587 name, err = err_msg.split('|')
587 name, err = err_msg.split('|')
588 if 'SchainWarning' in err:
588 if 'SchainWarning' in err:
589 log.warning(err.split('SchainWarning:')[-1].split('\n')[0].strip(), name)
589 log.warning(err.split('SchainWarning:')[-1].split('\n')[0].strip(), name)
590 elif 'SchainError' in err:
590 elif 'SchainError' in err:
591 log.error(err.split('SchainError:')[-1].split('\n')[0].strip(), name)
591 log.error(err.split('SchainError:')[-1].split('\n')[0].strip(), name)
592 else:
592 else:
593 log.error(err, name)
593 log.error(err, name)
594 else:
594 else:
595 name, err = self.name, err_msg
595 name, err = self.name, err_msg
596
596
597 time.sleep(1)
597 time.sleep(1)
598
598
599 ctx.term()
599 ctx.term()
600
600
601 message = ''.join(err)
601 message = ''.join(err)
602
602
603 if err_msg:
603 if err_msg:
604 subject = 'SChain v%s: Error running %s\n' % (
604 subject = 'SChain v%s: Error running %s\n' % (
605 schainpy.__version__, self.name)
605 schainpy.__version__, self.name)
606
606
607 subtitle = 'Hostname: %s\n' % socket.gethostbyname(
607 subtitle = 'Hostname: %s\n' % socket.gethostbyname(
608 socket.gethostname())
608 socket.gethostname())
609 subtitle += 'Working directory: %s\n' % os.path.abspath('./')
609 subtitle += 'Working directory: %s\n' % os.path.abspath('./')
610 subtitle += 'Configuration file: %s\n' % self.filename
610 subtitle += 'Configuration file: %s\n' % self.filename
611 subtitle += 'Time: %s\n' % str(datetime.datetime.now())
611 subtitle += 'Time: %s\n' % str(datetime.datetime.now())
612
612
613 readUnitConfObj = self.getReadUnit()
613 readUnitConfObj = self.getReadUnit()
614 if readUnitConfObj:
614 if readUnitConfObj:
615 subtitle += '\nInput parameters:\n'
615 subtitle += '\nInput parameters:\n'
616 subtitle += '[Data path = %s]\n' % readUnitConfObj.parameters['path']
616 subtitle += '[Data path = %s]\n' % readUnitConfObj.parameters['path']
617 subtitle += '[Start date = %s]\n' % readUnitConfObj.parameters['startDate']
617 subtitle += '[Start date = %s]\n' % readUnitConfObj.parameters['startDate']
618 subtitle += '[End date = %s]\n' % readUnitConfObj.parameters['endDate']
618 subtitle += '[End date = %s]\n' % readUnitConfObj.parameters['endDate']
619 subtitle += '[Start time = %s]\n' % readUnitConfObj.parameters['startTime']
619 subtitle += '[Start time = %s]\n' % readUnitConfObj.parameters['startTime']
620 subtitle += '[End time = %s]\n' % readUnitConfObj.parameters['endTime']
620 subtitle += '[End time = %s]\n' % readUnitConfObj.parameters['endTime']
621
621
622 a = Alarm(
622 a = Alarm(
623 modes=self.alarm,
623 modes=self.alarm,
624 email=self.email,
624 email=self.email,
625 message=message,
625 message=message,
626 subject=subject,
626 subject=subject,
627 subtitle=subtitle,
627 subtitle=subtitle,
628 filename=self.filename
628 filename=self.filename
629 )
629 )
630
630
631 a.start()
631 a.start()
632
632
633 def setFilename(self, filename):
633 def setFilename(self, filename):
634
634
635 self.filename = filename
635 self.filename = filename
636
636
637 def runProcs(self):
637 def runProcs(self):
638
638
639 err = False
639 err = False
640 n = len(self.configurations)
640 n = len(self.configurations)
641 while not err:
641 while not err:
642 for conf in self.getUnits():
642 for conf in self.getUnits():
643 ok = conf.run()
643 ok = conf.run()
644 if ok == 'Error':
644 if ok == 'Error':
645 n -= 1
645 n -= 1
646 continue
646 continue
647 elif not ok:
647 elif not ok:
648 break
648 break
649 if n == 0:
649 if n == 0:
650 err = True
650 err = True
651
651
652 def run(self):
652 def run(self):
653
653
654 log.success('\nStarting Project {} [id={}]'.format(self.name, self.id), tag='')
654 log.success('\nStarting Project {} [id={}]'.format(self.name, self.id), tag='')
655 self.started = True
655 self.started = True
656 self.start_time = time.time()
656 self.start_time = time.time()
657 self.createObjects()
657 self.createObjects()
658 self.runProcs()
658 self.runProcs()
659 log.success('{} Done (Time: {:4.2f}s)'.format(
659 log.success('{} Done (Time: {:4.2f}s)'.format(
660 self.name,
660 self.name,
661 time.time()-self.start_time), '') No newline at end of file
661 time.time()-self.start_time), '')
@@ -1,931 +1,937
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
2 # All rights reserved.
3 #
3 #
4 # Distributed under the terms of the BSD 3-clause license.
4 # Distributed under the terms of the BSD 3-clause license.
5 """Spectra processing Unit and operations
5 """Spectra processing Unit and operations
6
6
7 Here you will find the processing unit `SpectraProc` and several operations
7 Here you will find the processing unit `SpectraProc` and several operations
8 to work with Spectra data type
8 to work with Spectra data type
9 """
9 """
10
10
11 import time
11 import time
12 import itertools
12 import itertools
13 import numpy
13 import numpy
14 # repositorio
14 # repositorio
15 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
15 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
16 from schainpy.model.data.jrodata import Spectra
16 from schainpy.model.data.jrodata import Spectra
17 from schainpy.model.data.jrodata import hildebrand_sekhon
17 from schainpy.model.data.jrodata import hildebrand_sekhon
18 from schainpy.utils import log
18 from schainpy.utils import log
19
19
20
20
21 class SpectraProc(ProcessingUnit):
21 class SpectraProc(ProcessingUnit):
22
22
23 def __init__(self):
23 def __init__(self):
24
24
25 ProcessingUnit.__init__(self)
25 ProcessingUnit.__init__(self)
26
26
27 self.buffer = None
27 self.buffer = None
28 self.firstdatatime = None
28 self.firstdatatime = None
29 self.profIndex = 0
29 self.profIndex = 0
30 self.dataOut = Spectra()
30 self.dataOut = Spectra()
31 self.id_min = None
31 self.id_min = None
32 self.id_max = None
32 self.id_max = None
33 self.setupReq = False #Agregar a todas las unidades de proc
33 self.setupReq = False #Agregar a todas las unidades de proc
34
34
35 def __updateSpecFromVoltage(self):
35 def __updateSpecFromVoltage(self):
36
36
37 self.dataOut.timeZone = self.dataIn.timeZone
37 self.dataOut.timeZone = self.dataIn.timeZone
38 self.dataOut.dstFlag = self.dataIn.dstFlag
38 self.dataOut.dstFlag = self.dataIn.dstFlag
39 self.dataOut.errorCount = self.dataIn.errorCount
39 self.dataOut.errorCount = self.dataIn.errorCount
40 self.dataOut.useLocalTime = self.dataIn.useLocalTime
40 self.dataOut.useLocalTime = self.dataIn.useLocalTime
41 try:
41 try:
42 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
42 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
43 except:
43 except:
44 pass
44 pass
45 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
45 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
46 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
46 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
47 self.dataOut.channelList = self.dataIn.channelList
47 self.dataOut.channelList = self.dataIn.channelList
48 self.dataOut.heightList = self.dataIn.heightList
48 self.dataOut.heightList = self.dataIn.heightList
49 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
49 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
50 self.dataOut.nProfiles = self.dataOut.nFFTPoints
50 self.dataOut.nProfiles = self.dataOut.nFFTPoints
51 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
51 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
52 self.dataOut.utctime = self.firstdatatime
52 self.dataOut.utctime = self.firstdatatime
53 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
53 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
54 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
54 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
55 self.dataOut.flagShiftFFT = False
55 self.dataOut.flagShiftFFT = False
56 self.dataOut.nCohInt = self.dataIn.nCohInt
56 self.dataOut.nCohInt = self.dataIn.nCohInt
57 self.dataOut.nIncohInt = 1
57 self.dataOut.nIncohInt = 1
58 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
58 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
59 self.dataOut.frequency = self.dataIn.frequency
59 self.dataOut.frequency = self.dataIn.frequency
60 self.dataOut.realtime = self.dataIn.realtime
60 self.dataOut.realtime = self.dataIn.realtime
61 self.dataOut.azimuth = self.dataIn.azimuth
61 self.dataOut.azimuth = self.dataIn.azimuth
62 self.dataOut.zenith = self.dataIn.zenith
62 self.dataOut.zenith = self.dataIn.zenith
63 self.dataOut.beam.codeList = self.dataIn.beam.codeList
63 self.dataOut.beam.codeList = self.dataIn.beam.codeList
64 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
64 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
65 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
65 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
66 self.dataOut.runNextUnit = self.dataIn.runNextUnit
67 try:
68 self.dataOut.step = self.dataIn.step
69 except:
70 pass
66
71
67 def __getFft(self):
72 def __getFft(self):
68 """
73 """
69 Convierte valores de Voltaje a Spectra
74 Convierte valores de Voltaje a Spectra
70
75
71 Affected:
76 Affected:
72 self.dataOut.data_spc
77 self.dataOut.data_spc
73 self.dataOut.data_cspc
78 self.dataOut.data_cspc
74 self.dataOut.data_dc
79 self.dataOut.data_dc
75 self.dataOut.heightList
80 self.dataOut.heightList
76 self.profIndex
81 self.profIndex
77 self.buffer
82 self.buffer
78 self.dataOut.flagNoData
83 self.dataOut.flagNoData
79 """
84 """
80 fft_volt = numpy.fft.fft(
85 fft_volt = numpy.fft.fft(
81 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
86 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
82 fft_volt = fft_volt.astype(numpy.dtype('complex'))
87 fft_volt = fft_volt.astype(numpy.dtype('complex'))
83 dc = fft_volt[:, 0, :]
88 dc = fft_volt[:, 0, :]
84
89
85 # calculo de self-spectra
90 # calculo de self-spectra
86 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
91 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
87 spc = fft_volt * numpy.conjugate(fft_volt)
92 spc = fft_volt * numpy.conjugate(fft_volt)
88 spc = spc.real
93 spc = spc.real
89
94
90 blocksize = 0
95 blocksize = 0
91 blocksize += dc.size
96 blocksize += dc.size
92 blocksize += spc.size
97 blocksize += spc.size
93
98
94 cspc = None
99 cspc = None
95 pairIndex = 0
100 pairIndex = 0
96 if self.dataOut.pairsList != None:
101 if self.dataOut.pairsList != None:
97 # calculo de cross-spectra
102 # calculo de cross-spectra
98 cspc = numpy.zeros(
103 cspc = numpy.zeros(
99 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
104 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
100 for pair in self.dataOut.pairsList:
105 for pair in self.dataOut.pairsList:
101 if pair[0] not in self.dataOut.channelList:
106 if pair[0] not in self.dataOut.channelList:
102 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
107 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
103 str(pair), str(self.dataOut.channelList)))
108 str(pair), str(self.dataOut.channelList)))
104 if pair[1] not in self.dataOut.channelList:
109 if pair[1] not in self.dataOut.channelList:
105 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
110 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
106 str(pair), str(self.dataOut.channelList)))
111 str(pair), str(self.dataOut.channelList)))
107
112
108 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
113 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
109 numpy.conjugate(fft_volt[pair[1], :, :])
114 numpy.conjugate(fft_volt[pair[1], :, :])
110 pairIndex += 1
115 pairIndex += 1
111 blocksize += cspc.size
116 blocksize += cspc.size
112
117
113 self.dataOut.data_spc = spc
118 self.dataOut.data_spc = spc
114 self.dataOut.data_cspc = cspc
119 self.dataOut.data_cspc = cspc
115 self.dataOut.data_dc = dc
120 self.dataOut.data_dc = dc
116 self.dataOut.blockSize = blocksize
121 self.dataOut.blockSize = blocksize
117 self.dataOut.flagShiftFFT = False
122 self.dataOut.flagShiftFFT = False
118
123
119 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False):
124 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False, runNextUnit = 0):
120
125
126 self.dataIn.runNextUnit = runNextUnit
121 if self.dataIn.type == "Spectra":
127 if self.dataIn.type == "Spectra":
122 self.dataOut.copy(self.dataIn)
128 self.dataOut.copy(self.dataIn)
123 if shift_fft:
129 if shift_fft:
124 #desplaza a la derecha en el eje 2 determinadas posiciones
130 #desplaza a la derecha en el eje 2 determinadas posiciones
125 shift = int(self.dataOut.nFFTPoints/2)
131 shift = int(self.dataOut.nFFTPoints/2)
126 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
132 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
127
133
128 if self.dataOut.data_cspc is not None:
134 if self.dataOut.data_cspc is not None:
129 #desplaza a la derecha en el eje 2 determinadas posiciones
135 #desplaza a la derecha en el eje 2 determinadas posiciones
130 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
136 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
131 if pairsList:
137 if pairsList:
132 self.__selectPairs(pairsList)
138 self.__selectPairs(pairsList)
133
139
134 elif self.dataIn.type == "Voltage":
140 elif self.dataIn.type == "Voltage":
135
141
136 self.dataOut.flagNoData = True
142 self.dataOut.flagNoData = True
137
143
138 if nFFTPoints == None:
144 if nFFTPoints == None:
139 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
145 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
140
146
141 if nProfiles == None:
147 if nProfiles == None:
142 nProfiles = nFFTPoints
148 nProfiles = nFFTPoints
143
149
144 if ippFactor == None:
150 if ippFactor == None:
145 self.dataOut.ippFactor = 1
151 self.dataOut.ippFactor = 1
146
152
147 self.dataOut.nFFTPoints = nFFTPoints
153 self.dataOut.nFFTPoints = nFFTPoints
148
154
149 if self.buffer is None:
155 if self.buffer is None:
150 self.buffer = numpy.zeros((self.dataIn.nChannels,
156 self.buffer = numpy.zeros((self.dataIn.nChannels,
151 nProfiles,
157 nProfiles,
152 self.dataIn.nHeights),
158 self.dataIn.nHeights),
153 dtype='complex')
159 dtype='complex')
154
160
155 if self.dataIn.flagDataAsBlock:
161 if self.dataIn.flagDataAsBlock:
156 nVoltProfiles = self.dataIn.data.shape[1]
162 nVoltProfiles = self.dataIn.data.shape[1]
157 if nVoltProfiles == nProfiles:
163 if nVoltProfiles == nProfiles:
158 self.buffer = self.dataIn.data.copy()
164 self.buffer = self.dataIn.data.copy()
159 self.profIndex = nVoltProfiles
165 self.profIndex = nVoltProfiles
160
166
161 elif nVoltProfiles < nProfiles:
167 elif nVoltProfiles < nProfiles:
162
168
163 if self.profIndex == 0:
169 if self.profIndex == 0:
164 self.id_min = 0
170 self.id_min = 0
165 self.id_max = nVoltProfiles
171 self.id_max = nVoltProfiles
166
172
167 self.buffer[:, self.id_min:self.id_max,
173 self.buffer[:, self.id_min:self.id_max,
168 :] = self.dataIn.data
174 :] = self.dataIn.data
169 self.profIndex += nVoltProfiles
175 self.profIndex += nVoltProfiles
170 self.id_min += nVoltProfiles
176 self.id_min += nVoltProfiles
171 self.id_max += nVoltProfiles
177 self.id_max += nVoltProfiles
172 elif nVoltProfiles > nProfiles:
178 elif nVoltProfiles > nProfiles:
173 self.reader.bypass = True
179 self.reader.bypass = True
174 if self.profIndex == 0:
180 if self.profIndex == 0:
175 self.id_min = 0
181 self.id_min = 0
176 self.id_max = nProfiles
182 self.id_max = nProfiles
177
183
178 self.buffer = self.dataIn.data[:, self.id_min:self.id_max,:]
184 self.buffer = self.dataIn.data[:, self.id_min:self.id_max,:]
179 self.profIndex += nProfiles
185 self.profIndex += nProfiles
180 self.id_min += nProfiles
186 self.id_min += nProfiles
181 self.id_max += nProfiles
187 self.id_max += nProfiles
182 if self.id_max == nVoltProfiles:
188 if self.id_max == nVoltProfiles:
183 self.reader.bypass = False
189 self.reader.bypass = False
184
190
185 else:
191 else:
186 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
192 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
187 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
193 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
188 self.dataOut.flagNoData = True
194 self.dataOut.flagNoData = True
189 else:
195 else:
190 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
196 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
191 self.profIndex += 1
197 self.profIndex += 1
192
198
193 if self.firstdatatime == None:
199 if self.firstdatatime == None:
194 self.firstdatatime = self.dataIn.utctime
200 self.firstdatatime = self.dataIn.utctime
195
201
196 if self.profIndex == nProfiles:
202 if self.profIndex == nProfiles:
197 self.__updateSpecFromVoltage()
203 self.__updateSpecFromVoltage()
198 if pairsList == None:
204 if pairsList == None:
199 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
205 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
200 else:
206 else:
201 self.dataOut.pairsList = pairsList
207 self.dataOut.pairsList = pairsList
202 self.__getFft()
208 self.__getFft()
203 self.dataOut.flagNoData = False
209 self.dataOut.flagNoData = False
204 self.firstdatatime = None
210 self.firstdatatime = None
205 if not self.reader.bypass:
211 if not self.reader.bypass:
206 self.profIndex = 0
212 self.profIndex = 0
207 else:
213 else:
208 raise ValueError("The type of input object '%s' is not valid".format(
214 raise ValueError("The type of input object '%s' is not valid".format(
209 self.dataIn.type))
215 self.dataIn.type))
210
216
211 def __selectPairs(self, pairsList):
217 def __selectPairs(self, pairsList):
212
218
213 if not pairsList:
219 if not pairsList:
214 return
220 return
215
221
216 pairs = []
222 pairs = []
217 pairsIndex = []
223 pairsIndex = []
218
224
219 for pair in pairsList:
225 for pair in pairsList:
220 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
226 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
221 continue
227 continue
222 pairs.append(pair)
228 pairs.append(pair)
223 pairsIndex.append(pairs.index(pair))
229 pairsIndex.append(pairs.index(pair))
224
230
225 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
231 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
226 self.dataOut.pairsList = pairs
232 self.dataOut.pairsList = pairs
227
233
228 return
234 return
229
235
230 def selectFFTs(self, minFFT, maxFFT):
236 def selectFFTs(self, minFFT, maxFFT ):
231 """
237 """
232 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
238 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
233 minFFT<= FFT <= maxFFT
239 minFFT<= FFT <= maxFFT
234 """
240 """
235
241
236 if (minFFT > maxFFT):
242 if (minFFT > maxFFT):
237 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
243 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
238
244
239 if (minFFT < self.dataOut.getFreqRange()[0]):
245 if (minFFT < self.dataOut.getFreqRange()[0]):
240 minFFT = self.dataOut.getFreqRange()[0]
246 minFFT = self.dataOut.getFreqRange()[0]
241
247
242 if (maxFFT > self.dataOut.getFreqRange()[-1]):
248 if (maxFFT > self.dataOut.getFreqRange()[-1]):
243 maxFFT = self.dataOut.getFreqRange()[-1]
249 maxFFT = self.dataOut.getFreqRange()[-1]
244
250
245 minIndex = 0
251 minIndex = 0
246 maxIndex = 0
252 maxIndex = 0
247 FFTs = self.dataOut.getFreqRange()
253 FFTs = self.dataOut.getFreqRange()
248
254
249 inda = numpy.where(FFTs >= minFFT)
255 inda = numpy.where(FFTs >= minFFT)
250 indb = numpy.where(FFTs <= maxFFT)
256 indb = numpy.where(FFTs <= maxFFT)
251
257
252 try:
258 try:
253 minIndex = inda[0][0]
259 minIndex = inda[0][0]
254 except:
260 except:
255 minIndex = 0
261 minIndex = 0
256
262
257 try:
263 try:
258 maxIndex = indb[0][-1]
264 maxIndex = indb[0][-1]
259 except:
265 except:
260 maxIndex = len(FFTs)
266 maxIndex = len(FFTs)
261
267
262 self.selectFFTsByIndex(minIndex, maxIndex)
268 self.selectFFTsByIndex(minIndex, maxIndex)
263
269
264 return 1
270 return 1
265
271
266 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
272 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
267 newheis = numpy.where(
273 newheis = numpy.where(
268 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
274 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
269
275
270 if hei_ref != None:
276 if hei_ref != None:
271 newheis = numpy.where(self.dataOut.heightList > hei_ref)
277 newheis = numpy.where(self.dataOut.heightList > hei_ref)
272
278
273 minIndex = min(newheis[0])
279 minIndex = min(newheis[0])
274 maxIndex = max(newheis[0])
280 maxIndex = max(newheis[0])
275 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
281 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
276 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
282 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
277
283
278 # determina indices
284 # determina indices
279 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
285 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
280 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
286 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
281 avg_dB = 10 * \
287 avg_dB = 10 * \
282 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
288 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
283 beacon_dB = numpy.sort(avg_dB)[-nheis:]
289 beacon_dB = numpy.sort(avg_dB)[-nheis:]
284 beacon_heiIndexList = []
290 beacon_heiIndexList = []
285 for val in avg_dB.tolist():
291 for val in avg_dB.tolist():
286 if val >= beacon_dB[0]:
292 if val >= beacon_dB[0]:
287 beacon_heiIndexList.append(avg_dB.tolist().index(val))
293 beacon_heiIndexList.append(avg_dB.tolist().index(val))
288
294
289 data_cspc = None
295 data_cspc = None
290 if self.dataOut.data_cspc is not None:
296 if self.dataOut.data_cspc is not None:
291 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
297 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
292
298
293 data_dc = None
299 data_dc = None
294 if self.dataOut.data_dc is not None:
300 if self.dataOut.data_dc is not None:
295 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
301 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
296
302
297 self.dataOut.data_spc = data_spc
303 self.dataOut.data_spc = data_spc
298 self.dataOut.data_cspc = data_cspc
304 self.dataOut.data_cspc = data_cspc
299 self.dataOut.data_dc = data_dc
305 self.dataOut.data_dc = data_dc
300 self.dataOut.heightList = heightList
306 self.dataOut.heightList = heightList
301 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
307 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
302
308
303 return 1
309 return 1
304
310
305 def selectFFTsByIndex(self, minIndex, maxIndex):
311 def selectFFTsByIndex(self, minIndex, maxIndex):
306 """
312 """
307
313
308 """
314 """
309
315
310 if (minIndex < 0) or (minIndex > maxIndex):
316 if (minIndex < 0) or (minIndex > maxIndex):
311 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
317 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
312
318
313 if (maxIndex >= self.dataOut.nProfiles):
319 if (maxIndex >= self.dataOut.nProfiles):
314 maxIndex = self.dataOut.nProfiles-1
320 maxIndex = self.dataOut.nProfiles-1
315
321
316 #Spectra
322 #Spectra
317 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
323 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
318
324
319 data_cspc = None
325 data_cspc = None
320 if self.dataOut.data_cspc is not None:
326 if self.dataOut.data_cspc is not None:
321 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
327 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
322
328
323 data_dc = None
329 data_dc = None
324 if self.dataOut.data_dc is not None:
330 if self.dataOut.data_dc is not None:
325 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
331 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
326
332
327 self.dataOut.data_spc = data_spc
333 self.dataOut.data_spc = data_spc
328 self.dataOut.data_cspc = data_cspc
334 self.dataOut.data_cspc = data_cspc
329 self.dataOut.data_dc = data_dc
335 self.dataOut.data_dc = data_dc
330
336
331 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
337 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
332 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
338 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
333 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
339 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
334
340
335 return 1
341 return 1
336
342
337 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
343 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
338 # validacion de rango
344 # validacion de rango
339 if minHei == None:
345 if minHei == None:
340 minHei = self.dataOut.heightList[0]
346 minHei = self.dataOut.heightList[0]
341
347
342 if maxHei == None:
348 if maxHei == None:
343 maxHei = self.dataOut.heightList[-1]
349 maxHei = self.dataOut.heightList[-1]
344
350
345 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
351 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
346 print('minHei: %.2f is out of the heights range' % (minHei))
352 print('minHei: %.2f is out of the heights range' % (minHei))
347 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
353 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
348 minHei = self.dataOut.heightList[0]
354 minHei = self.dataOut.heightList[0]
349
355
350 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
356 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
351 print('maxHei: %.2f is out of the heights range' % (maxHei))
357 print('maxHei: %.2f is out of the heights range' % (maxHei))
352 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
358 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
353 maxHei = self.dataOut.heightList[-1]
359 maxHei = self.dataOut.heightList[-1]
354
360
355 # validacion de velocidades
361 # validacion de velocidades
356 velrange = self.dataOut.getVelRange(1)
362 velrange = self.dataOut.getVelRange(1)
357
363
358 if minVel == None:
364 if minVel == None:
359 minVel = velrange[0]
365 minVel = velrange[0]
360
366
361 if maxVel == None:
367 if maxVel == None:
362 maxVel = velrange[-1]
368 maxVel = velrange[-1]
363
369
364 if (minVel < velrange[0]) or (minVel > maxVel):
370 if (minVel < velrange[0]) or (minVel > maxVel):
365 print('minVel: %.2f is out of the velocity range' % (minVel))
371 print('minVel: %.2f is out of the velocity range' % (minVel))
366 print('minVel is setting to %.2f' % (velrange[0]))
372 print('minVel is setting to %.2f' % (velrange[0]))
367 minVel = velrange[0]
373 minVel = velrange[0]
368
374
369 if (maxVel > velrange[-1]) or (maxVel < minVel):
375 if (maxVel > velrange[-1]) or (maxVel < minVel):
370 print('maxVel: %.2f is out of the velocity range' % (maxVel))
376 print('maxVel: %.2f is out of the velocity range' % (maxVel))
371 print('maxVel is setting to %.2f' % (velrange[-1]))
377 print('maxVel is setting to %.2f' % (velrange[-1]))
372 maxVel = velrange[-1]
378 maxVel = velrange[-1]
373
379
374 # seleccion de indices para rango
380 # seleccion de indices para rango
375 minIndex = 0
381 minIndex = 0
376 maxIndex = 0
382 maxIndex = 0
377 heights = self.dataOut.heightList
383 heights = self.dataOut.heightList
378
384
379 inda = numpy.where(heights >= minHei)
385 inda = numpy.where(heights >= minHei)
380 indb = numpy.where(heights <= maxHei)
386 indb = numpy.where(heights <= maxHei)
381
387
382 try:
388 try:
383 minIndex = inda[0][0]
389 minIndex = inda[0][0]
384 except:
390 except:
385 minIndex = 0
391 minIndex = 0
386
392
387 try:
393 try:
388 maxIndex = indb[0][-1]
394 maxIndex = indb[0][-1]
389 except:
395 except:
390 maxIndex = len(heights)
396 maxIndex = len(heights)
391
397
392 if (minIndex < 0) or (minIndex > maxIndex):
398 if (minIndex < 0) or (minIndex > maxIndex):
393 raise ValueError("some value in (%d,%d) is not valid" % (
399 raise ValueError("some value in (%d,%d) is not valid" % (
394 minIndex, maxIndex))
400 minIndex, maxIndex))
395
401
396 if (maxIndex >= self.dataOut.nHeights):
402 if (maxIndex >= self.dataOut.nHeights):
397 maxIndex = self.dataOut.nHeights - 1
403 maxIndex = self.dataOut.nHeights - 1
398
404
399 # seleccion de indices para velocidades
405 # seleccion de indices para velocidades
400 indminvel = numpy.where(velrange >= minVel)
406 indminvel = numpy.where(velrange >= minVel)
401 indmaxvel = numpy.where(velrange <= maxVel)
407 indmaxvel = numpy.where(velrange <= maxVel)
402 try:
408 try:
403 minIndexVel = indminvel[0][0]
409 minIndexVel = indminvel[0][0]
404 except:
410 except:
405 minIndexVel = 0
411 minIndexVel = 0
406
412
407 try:
413 try:
408 maxIndexVel = indmaxvel[0][-1]
414 maxIndexVel = indmaxvel[0][-1]
409 except:
415 except:
410 maxIndexVel = len(velrange)
416 maxIndexVel = len(velrange)
411
417
412 # seleccion del espectro
418 # seleccion del espectro
413 data_spc = self.dataOut.data_spc[:,
419 data_spc = self.dataOut.data_spc[:,
414 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
420 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
415 # estimacion de ruido
421 # estimacion de ruido
416 noise = numpy.zeros(self.dataOut.nChannels)
422 noise = numpy.zeros(self.dataOut.nChannels)
417
423
418 for channel in range(self.dataOut.nChannels):
424 for channel in range(self.dataOut.nChannels):
419 daux = data_spc[channel, :, :]
425 daux = data_spc[channel, :, :]
420 sortdata = numpy.sort(daux, axis=None)
426 sortdata = numpy.sort(daux, axis=None)
421 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
427 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
422
428
423 self.dataOut.noise_estimation = noise.copy()
429 self.dataOut.noise_estimation = noise.copy()
424
430
425 return 1
431 return 1
426
432
427 class removeDC(Operation):
433 class removeDC(Operation):
428
434
429 def run(self, dataOut, mode=2):
435 def run(self, dataOut, mode=2):
430 self.dataOut = dataOut
436 self.dataOut = dataOut
431 jspectra = self.dataOut.data_spc
437 jspectra = self.dataOut.data_spc
432 jcspectra = self.dataOut.data_cspc
438 jcspectra = self.dataOut.data_cspc
433
439
434 num_chan = jspectra.shape[0]
440 num_chan = jspectra.shape[0]
435 num_hei = jspectra.shape[2]
441 num_hei = jspectra.shape[2]
436
442
437 if jcspectra is not None:
443 if jcspectra is not None:
438 jcspectraExist = True
444 jcspectraExist = True
439 num_pairs = jcspectra.shape[0]
445 num_pairs = jcspectra.shape[0]
440 else:
446 else:
441 jcspectraExist = False
447 jcspectraExist = False
442
448
443 freq_dc = int(jspectra.shape[1] / 2)
449 freq_dc = int(jspectra.shape[1] / 2)
444 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
450 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
445 ind_vel = ind_vel.astype(int)
451 ind_vel = ind_vel.astype(int)
446
452
447 if ind_vel[0] < 0:
453 if ind_vel[0] < 0:
448 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
454 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
449
455
450 if mode == 1:
456 if mode == 1:
451 jspectra[:, freq_dc, :] = (
457 jspectra[:, freq_dc, :] = (
452 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
458 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
453
459
454 if jcspectraExist:
460 if jcspectraExist:
455 jcspectra[:, freq_dc, :] = (
461 jcspectra[:, freq_dc, :] = (
456 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
462 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
457
463
458 if mode == 2:
464 if mode == 2:
459
465
460 vel = numpy.array([-2, -1, 1, 2])
466 vel = numpy.array([-2, -1, 1, 2])
461 xx = numpy.zeros([4, 4])
467 xx = numpy.zeros([4, 4])
462
468
463 for fil in range(4):
469 for fil in range(4):
464 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
470 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
465
471
466 xx_inv = numpy.linalg.inv(xx)
472 xx_inv = numpy.linalg.inv(xx)
467 xx_aux = xx_inv[0, :]
473 xx_aux = xx_inv[0, :]
468
474
469 for ich in range(num_chan):
475 for ich in range(num_chan):
470 yy = jspectra[ich, ind_vel, :]
476 yy = jspectra[ich, ind_vel, :]
471 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
477 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
472
478
473 junkid = jspectra[ich, freq_dc, :] <= 0
479 junkid = jspectra[ich, freq_dc, :] <= 0
474 cjunkid = sum(junkid)
480 cjunkid = sum(junkid)
475
481
476 if cjunkid.any():
482 if cjunkid.any():
477 jspectra[ich, freq_dc, junkid.nonzero()] = (
483 jspectra[ich, freq_dc, junkid.nonzero()] = (
478 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
484 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
479
485
480 if jcspectraExist:
486 if jcspectraExist:
481 for ip in range(num_pairs):
487 for ip in range(num_pairs):
482 yy = jcspectra[ip, ind_vel, :]
488 yy = jcspectra[ip, ind_vel, :]
483 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
489 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
484
490
485 self.dataOut.data_spc = jspectra
491 self.dataOut.data_spc = jspectra
486 self.dataOut.data_cspc = jcspectra
492 self.dataOut.data_cspc = jcspectra
487
493
488 return self.dataOut
494 return self.dataOut
489
495
490 class removeInterference(Operation):
496 class removeInterference(Operation):
491
497
492 def removeInterference2(self):
498 def removeInterference2(self):
493
499
494 cspc = self.dataOut.data_cspc
500 cspc = self.dataOut.data_cspc
495 spc = self.dataOut.data_spc
501 spc = self.dataOut.data_spc
496 Heights = numpy.arange(cspc.shape[2])
502 Heights = numpy.arange(cspc.shape[2])
497 realCspc = numpy.abs(cspc)
503 realCspc = numpy.abs(cspc)
498
504
499 for i in range(cspc.shape[0]):
505 for i in range(cspc.shape[0]):
500 LinePower= numpy.sum(realCspc[i], axis=0)
506 LinePower= numpy.sum(realCspc[i], axis=0)
501 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
507 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
502 SelectedHeights = Heights[ numpy.where(LinePower < Threshold) ]
508 SelectedHeights = Heights[ numpy.where(LinePower < Threshold) ]
503 InterferenceSum = numpy.sum(realCspc[i,:,SelectedHeights],axis=0)
509 InterferenceSum = numpy.sum(realCspc[i,:,SelectedHeights],axis=0)
504 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
510 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
505 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
511 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
506
512
507
513
508 InterferenceRange = numpy.where(([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
514 InterferenceRange = numpy.where(([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
509 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
515 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
510 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
516 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
511 cspc[i,InterferenceRange,:] = numpy.NaN
517 cspc[i,InterferenceRange,:] = numpy.NaN
512
518
513 self.dataOut.data_cspc = cspc
519 self.dataOut.data_cspc = cspc
514
520
515 def removeInterference(self, interf=2, hei_interf=None, nhei_interf=None, offhei_interf=None):
521 def removeInterference(self, interf=2, hei_interf=None, nhei_interf=None, offhei_interf=None):
516
522
517 jspectra = self.dataOut.data_spc
523 jspectra = self.dataOut.data_spc
518 jcspectra = self.dataOut.data_cspc
524 jcspectra = self.dataOut.data_cspc
519 jnoise = self.dataOut.getNoise()
525 jnoise = self.dataOut.getNoise()
520 num_incoh = self.dataOut.nIncohInt
526 num_incoh = self.dataOut.nIncohInt
521
527
522 num_channel = jspectra.shape[0]
528 num_channel = jspectra.shape[0]
523 num_prof = jspectra.shape[1]
529 num_prof = jspectra.shape[1]
524 num_hei = jspectra.shape[2]
530 num_hei = jspectra.shape[2]
525
531
526 # hei_interf
532 # hei_interf
527 if hei_interf is None:
533 if hei_interf is None:
528 count_hei = int(num_hei / 2)
534 count_hei = int(num_hei / 2)
529 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
535 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
530 hei_interf = numpy.asarray(hei_interf)[0]
536 hei_interf = numpy.asarray(hei_interf)[0]
531 # nhei_interf
537 # nhei_interf
532 if (nhei_interf == None):
538 if (nhei_interf == None):
533 nhei_interf = 5
539 nhei_interf = 5
534 if (nhei_interf < 1):
540 if (nhei_interf < 1):
535 nhei_interf = 1
541 nhei_interf = 1
536 if (nhei_interf > count_hei):
542 if (nhei_interf > count_hei):
537 nhei_interf = count_hei
543 nhei_interf = count_hei
538 if (offhei_interf == None):
544 if (offhei_interf == None):
539 offhei_interf = 0
545 offhei_interf = 0
540
546
541 ind_hei = list(range(num_hei))
547 ind_hei = list(range(num_hei))
542 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
548 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
543 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
549 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
544 mask_prof = numpy.asarray(list(range(num_prof)))
550 mask_prof = numpy.asarray(list(range(num_prof)))
545 num_mask_prof = mask_prof.size
551 num_mask_prof = mask_prof.size
546 comp_mask_prof = [0, num_prof / 2]
552 comp_mask_prof = [0, num_prof / 2]
547
553
548 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
554 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
549 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
555 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
550 jnoise = numpy.nan
556 jnoise = numpy.nan
551 noise_exist = jnoise[0] < numpy.Inf
557 noise_exist = jnoise[0] < numpy.Inf
552
558
553 # Subrutina de Remocion de la Interferencia
559 # Subrutina de Remocion de la Interferencia
554 for ich in range(num_channel):
560 for ich in range(num_channel):
555 # Se ordena los espectros segun su potencia (menor a mayor)
561 # Se ordena los espectros segun su potencia (menor a mayor)
556 power = jspectra[ich, mask_prof, :]
562 power = jspectra[ich, mask_prof, :]
557 power = power[:, hei_interf]
563 power = power[:, hei_interf]
558 power = power.sum(axis=0)
564 power = power.sum(axis=0)
559 psort = power.ravel().argsort()
565 psort = power.ravel().argsort()
560
566
561 # Se estima la interferencia promedio en los Espectros de Potencia empleando
567 # Se estima la interferencia promedio en los Espectros de Potencia empleando
562 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
568 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
563 offhei_interf, nhei_interf + offhei_interf))]]]
569 offhei_interf, nhei_interf + offhei_interf))]]]
564
570
565 if noise_exist:
571 if noise_exist:
566 # tmp_noise = jnoise[ich] / num_prof
572 # tmp_noise = jnoise[ich] / num_prof
567 tmp_noise = jnoise[ich]
573 tmp_noise = jnoise[ich]
568 junkspc_interf = junkspc_interf - tmp_noise
574 junkspc_interf = junkspc_interf - tmp_noise
569 #junkspc_interf[:,comp_mask_prof] = 0
575 #junkspc_interf[:,comp_mask_prof] = 0
570
576
571 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
577 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
572 jspc_interf = jspc_interf.transpose()
578 jspc_interf = jspc_interf.transpose()
573 # Calculando el espectro de interferencia promedio
579 # Calculando el espectro de interferencia promedio
574 noiseid = numpy.where(
580 noiseid = numpy.where(
575 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
581 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
576 noiseid = noiseid[0]
582 noiseid = noiseid[0]
577 cnoiseid = noiseid.size
583 cnoiseid = noiseid.size
578 interfid = numpy.where(
584 interfid = numpy.where(
579 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
585 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
580 interfid = interfid[0]
586 interfid = interfid[0]
581 cinterfid = interfid.size
587 cinterfid = interfid.size
582
588
583 if (cnoiseid > 0):
589 if (cnoiseid > 0):
584 jspc_interf[noiseid] = 0
590 jspc_interf[noiseid] = 0
585
591
586 # Expandiendo los perfiles a limpiar
592 # Expandiendo los perfiles a limpiar
587 if (cinterfid > 0):
593 if (cinterfid > 0):
588 new_interfid = (
594 new_interfid = (
589 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
595 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
590 new_interfid = numpy.asarray(new_interfid)
596 new_interfid = numpy.asarray(new_interfid)
591 new_interfid = {x for x in new_interfid}
597 new_interfid = {x for x in new_interfid}
592 new_interfid = numpy.array(list(new_interfid))
598 new_interfid = numpy.array(list(new_interfid))
593 new_cinterfid = new_interfid.size
599 new_cinterfid = new_interfid.size
594 else:
600 else:
595 new_cinterfid = 0
601 new_cinterfid = 0
596
602
597 for ip in range(new_cinterfid):
603 for ip in range(new_cinterfid):
598 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
604 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
599 jspc_interf[new_interfid[ip]
605 jspc_interf[new_interfid[ip]
600 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
606 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
601
607
602 jspectra[ich, :, ind_hei] = jspectra[ich, :,
608 jspectra[ich, :, ind_hei] = jspectra[ich, :,
603 ind_hei] - jspc_interf # Corregir indices
609 ind_hei] - jspc_interf # Corregir indices
604
610
605 # Removiendo la interferencia del punto de mayor interferencia
611 # Removiendo la interferencia del punto de mayor interferencia
606 ListAux = jspc_interf[mask_prof].tolist()
612 ListAux = jspc_interf[mask_prof].tolist()
607 maxid = ListAux.index(max(ListAux))
613 maxid = ListAux.index(max(ListAux))
608
614
609 if cinterfid > 0:
615 if cinterfid > 0:
610 for ip in range(cinterfid * (interf == 2) - 1):
616 for ip in range(cinterfid * (interf == 2) - 1):
611 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
617 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
612 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
618 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
613 cind = len(ind)
619 cind = len(ind)
614
620
615 if (cind > 0):
621 if (cind > 0):
616 jspectra[ich, interfid[ip], ind] = tmp_noise * \
622 jspectra[ich, interfid[ip], ind] = tmp_noise * \
617 (1 + (numpy.random.uniform(cind) - 0.5) /
623 (1 + (numpy.random.uniform(cind) - 0.5) /
618 numpy.sqrt(num_incoh))
624 numpy.sqrt(num_incoh))
619
625
620 ind = numpy.array([-2, -1, 1, 2])
626 ind = numpy.array([-2, -1, 1, 2])
621 xx = numpy.zeros([4, 4])
627 xx = numpy.zeros([4, 4])
622
628
623 for id1 in range(4):
629 for id1 in range(4):
624 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
630 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
625
631
626 xx_inv = numpy.linalg.inv(xx)
632 xx_inv = numpy.linalg.inv(xx)
627 xx = xx_inv[:, 0]
633 xx = xx_inv[:, 0]
628 ind = (ind + maxid + num_mask_prof) % num_mask_prof
634 ind = (ind + maxid + num_mask_prof) % num_mask_prof
629 yy = jspectra[ich, mask_prof[ind], :]
635 yy = jspectra[ich, mask_prof[ind], :]
630 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
636 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
631 yy.transpose(), xx)
637 yy.transpose(), xx)
632
638
633 indAux = (jspectra[ich, :, :] < tmp_noise *
639 indAux = (jspectra[ich, :, :] < tmp_noise *
634 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
640 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
635 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
641 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
636 (1 - 1 / numpy.sqrt(num_incoh))
642 (1 - 1 / numpy.sqrt(num_incoh))
637
643
638 # Remocion de Interferencia en el Cross Spectra
644 # Remocion de Interferencia en el Cross Spectra
639 if jcspectra is None:
645 if jcspectra is None:
640 return jspectra, jcspectra
646 return jspectra, jcspectra
641 num_pairs = int(jcspectra.size / (num_prof * num_hei))
647 num_pairs = int(jcspectra.size / (num_prof * num_hei))
642 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
648 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
643
649
644 for ip in range(num_pairs):
650 for ip in range(num_pairs):
645
651
646 #-------------------------------------------
652 #-------------------------------------------
647
653
648 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
654 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
649 cspower = cspower[:, hei_interf]
655 cspower = cspower[:, hei_interf]
650 cspower = cspower.sum(axis=0)
656 cspower = cspower.sum(axis=0)
651
657
652 cspsort = cspower.ravel().argsort()
658 cspsort = cspower.ravel().argsort()
653 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
659 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
654 offhei_interf, nhei_interf + offhei_interf))]]]
660 offhei_interf, nhei_interf + offhei_interf))]]]
655 junkcspc_interf = junkcspc_interf.transpose()
661 junkcspc_interf = junkcspc_interf.transpose()
656 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
662 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
657
663
658 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
664 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
659
665
660 median_real = int(numpy.median(numpy.real(
666 median_real = int(numpy.median(numpy.real(
661 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
667 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
662 median_imag = int(numpy.median(numpy.imag(
668 median_imag = int(numpy.median(numpy.imag(
663 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
669 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
664 comp_mask_prof = [int(e) for e in comp_mask_prof]
670 comp_mask_prof = [int(e) for e in comp_mask_prof]
665 junkcspc_interf[comp_mask_prof, :] = numpy.complex(
671 junkcspc_interf[comp_mask_prof, :] = numpy.complex(
666 median_real, median_imag)
672 median_real, median_imag)
667
673
668 for iprof in range(num_prof):
674 for iprof in range(num_prof):
669 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
675 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
670 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
676 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
671
677
672 # Removiendo la Interferencia
678 # Removiendo la Interferencia
673 jcspectra[ip, :, ind_hei] = jcspectra[ip,
679 jcspectra[ip, :, ind_hei] = jcspectra[ip,
674 :, ind_hei] - jcspc_interf
680 :, ind_hei] - jcspc_interf
675
681
676 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
682 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
677 maxid = ListAux.index(max(ListAux))
683 maxid = ListAux.index(max(ListAux))
678
684
679 ind = numpy.array([-2, -1, 1, 2])
685 ind = numpy.array([-2, -1, 1, 2])
680 xx = numpy.zeros([4, 4])
686 xx = numpy.zeros([4, 4])
681
687
682 for id1 in range(4):
688 for id1 in range(4):
683 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
689 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
684
690
685 xx_inv = numpy.linalg.inv(xx)
691 xx_inv = numpy.linalg.inv(xx)
686 xx = xx_inv[:, 0]
692 xx = xx_inv[:, 0]
687
693
688 ind = (ind + maxid + num_mask_prof) % num_mask_prof
694 ind = (ind + maxid + num_mask_prof) % num_mask_prof
689 yy = jcspectra[ip, mask_prof[ind], :]
695 yy = jcspectra[ip, mask_prof[ind], :]
690 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
696 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
691
697
692 # Guardar Resultados
698 # Guardar Resultados
693 self.dataOut.data_spc = jspectra
699 self.dataOut.data_spc = jspectra
694 self.dataOut.data_cspc = jcspectra
700 self.dataOut.data_cspc = jcspectra
695
701
696 return 1
702 return 1
697
703
698 def run(self, dataOut, interf=2,hei_interf=None, nhei_interf=None, offhei_interf=None, mode=1):
704 def run(self, dataOut, interf=2,hei_interf=None, nhei_interf=None, offhei_interf=None, mode=1):
699
705
700 self.dataOut = dataOut
706 self.dataOut = dataOut
701
707
702 if mode == 1:
708 if mode == 1:
703 self.removeInterference(interf=2,hei_interf=None, nhei_interf=None, offhei_interf=None)
709 self.removeInterference(interf=2,hei_interf=None, nhei_interf=None, offhei_interf=None)
704 elif mode == 2:
710 elif mode == 2:
705 self.removeInterference2()
711 self.removeInterference2()
706
712
707 return self.dataOut
713 return self.dataOut
708
714
709
715
710 class deflip(Operation):
716 class deflip(Operation):
711
717
712 def run(self, dataOut):
718 def run(self, dataOut):
713 # arreglo 1: (num_chan, num_profiles, num_heights)
719 # arreglo 1: (num_chan, num_profiles, num_heights)
714 self.dataOut = dataOut
720 self.dataOut = dataOut
715
721
716 # JULIA-oblicua, indice 2
722 # JULIA-oblicua, indice 2
717 # arreglo 2: (num_profiles, num_heights)
723 # arreglo 2: (num_profiles, num_heights)
718 jspectra = self.dataOut.data_spc[2]
724 jspectra = self.dataOut.data_spc[2]
719 jspectra_tmp=numpy.zeros(jspectra.shape)
725 jspectra_tmp=numpy.zeros(jspectra.shape)
720 num_profiles=jspectra.shape[0]
726 num_profiles=jspectra.shape[0]
721 freq_dc = int(num_profiles / 2)
727 freq_dc = int(num_profiles / 2)
722 # Flip con for
728 # Flip con for
723 for j in range(num_profiles):
729 for j in range(num_profiles):
724 jspectra_tmp[num_profiles-j-1]= jspectra[j]
730 jspectra_tmp[num_profiles-j-1]= jspectra[j]
725 # Intercambio perfil de DC con perfil inmediato anterior
731 # Intercambio perfil de DC con perfil inmediato anterior
726 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
732 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
727 jspectra_tmp[freq_dc]= jspectra[freq_dc]
733 jspectra_tmp[freq_dc]= jspectra[freq_dc]
728 # canal modificado es re-escrito en el arreglo de canales
734 # canal modificado es re-escrito en el arreglo de canales
729 self.dataOut.data_spc[2] = jspectra_tmp
735 self.dataOut.data_spc[2] = jspectra_tmp
730
736
731 return self.dataOut
737 return self.dataOut
732
738
733
739
734 class IncohInt(Operation):
740 class IncohInt(Operation):
735
741
736 __profIndex = 0
742 __profIndex = 0
737 __withOverapping = False
743 __withOverapping = False
738
744
739 __byTime = False
745 __byTime = False
740 __initime = None
746 __initime = None
741 __lastdatatime = None
747 __lastdatatime = None
742 __integrationtime = None
748 __integrationtime = None
743
749
744 __buffer_spc = None
750 __buffer_spc = None
745 __buffer_cspc = None
751 __buffer_cspc = None
746 __buffer_dc = None
752 __buffer_dc = None
747
753
748 __dataReady = False
754 __dataReady = False
749
755
750 __timeInterval = None
756 __timeInterval = None
751
757
752 n = None
758 n = None
753
759
754 def __init__(self):
760 def __init__(self):
755
761
756 Operation.__init__(self)
762 Operation.__init__(self)
757
763
758 def setup(self, n=None, timeInterval=None, overlapping=False):
764 def setup(self, n=None, timeInterval=None, overlapping=False):
759 """
765 """
760 Set the parameters of the integration class.
766 Set the parameters of the integration class.
761
767
762 Inputs:
768 Inputs:
763
769
764 n : Number of coherent integrations
770 n : Number of coherent integrations
765 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
771 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
766 overlapping :
772 overlapping :
767
773
768 """
774 """
769
775
770 self.__initime = None
776 self.__initime = None
771 self.__lastdatatime = 0
777 self.__lastdatatime = 0
772
778
773 self.__buffer_spc = 0
779 self.__buffer_spc = 0
774 self.__buffer_cspc = 0
780 self.__buffer_cspc = 0
775 self.__buffer_dc = 0
781 self.__buffer_dc = 0
776
782
777 self.__profIndex = 0
783 self.__profIndex = 0
778 self.__dataReady = False
784 self.__dataReady = False
779 self.__byTime = False
785 self.__byTime = False
780
786
781 if n is None and timeInterval is None:
787 if n is None and timeInterval is None:
782 raise ValueError("n or timeInterval should be specified ...")
788 raise ValueError("n or timeInterval should be specified ...")
783
789
784 if n is not None:
790 if n is not None:
785 self.n = int(n)
791 self.n = int(n)
786 else:
792 else:
787
793
788 self.__integrationtime = int(timeInterval)
794 self.__integrationtime = int(timeInterval)
789 self.n = None
795 self.n = None
790 self.__byTime = True
796 self.__byTime = True
791
797
792 def putData(self, data_spc, data_cspc, data_dc):
798 def putData(self, data_spc, data_cspc, data_dc):
793 """
799 """
794 Add a profile to the __buffer_spc and increase in one the __profileIndex
800 Add a profile to the __buffer_spc and increase in one the __profileIndex
795
801
796 """
802 """
797
803
798 self.__buffer_spc += data_spc
804 self.__buffer_spc += data_spc
799
805
800 if data_cspc is None:
806 if data_cspc is None:
801 self.__buffer_cspc = None
807 self.__buffer_cspc = None
802 else:
808 else:
803 self.__buffer_cspc += data_cspc
809 self.__buffer_cspc += data_cspc
804
810
805 if data_dc is None:
811 if data_dc is None:
806 self.__buffer_dc = None
812 self.__buffer_dc = None
807 else:
813 else:
808 self.__buffer_dc += data_dc
814 self.__buffer_dc += data_dc
809
815
810 self.__profIndex += 1
816 self.__profIndex += 1
811
817
812 return
818 return
813
819
814 def pushData(self):
820 def pushData(self):
815 """
821 """
816 Return the sum of the last profiles and the profiles used in the sum.
822 Return the sum of the last profiles and the profiles used in the sum.
817
823
818 Affected:
824 Affected:
819
825
820 self.__profileIndex
826 self.__profileIndex
821
827
822 """
828 """
823
829
824 data_spc = self.__buffer_spc
830 data_spc = self.__buffer_spc
825 data_cspc = self.__buffer_cspc
831 data_cspc = self.__buffer_cspc
826 data_dc = self.__buffer_dc
832 data_dc = self.__buffer_dc
827 n = self.__profIndex
833 n = self.__profIndex
828
834
829 self.__buffer_spc = 0
835 self.__buffer_spc = 0
830 self.__buffer_cspc = 0
836 self.__buffer_cspc = 0
831 self.__buffer_dc = 0
837 self.__buffer_dc = 0
832 self.__profIndex = 0
838 self.__profIndex = 0
833
839
834 return data_spc, data_cspc, data_dc, n
840 return data_spc, data_cspc, data_dc, n
835
841
836 def byProfiles(self, *args):
842 def byProfiles(self, *args):
837
843
838 self.__dataReady = False
844 self.__dataReady = False
839 avgdata_spc = None
845 avgdata_spc = None
840 avgdata_cspc = None
846 avgdata_cspc = None
841 avgdata_dc = None
847 avgdata_dc = None
842
848
843 self.putData(*args)
849 self.putData(*args)
844
850
845 if self.__profIndex == self.n:
851 if self.__profIndex == self.n:
846
852
847 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
853 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
848 self.n = n
854 self.n = n
849 self.__dataReady = True
855 self.__dataReady = True
850
856
851 return avgdata_spc, avgdata_cspc, avgdata_dc
857 return avgdata_spc, avgdata_cspc, avgdata_dc
852
858
853 def byTime(self, datatime, *args):
859 def byTime(self, datatime, *args):
854
860
855 self.__dataReady = False
861 self.__dataReady = False
856 avgdata_spc = None
862 avgdata_spc = None
857 avgdata_cspc = None
863 avgdata_cspc = None
858 avgdata_dc = None
864 avgdata_dc = None
859
865
860 self.putData(*args)
866 self.putData(*args)
861
867
862 if (datatime - self.__initime) >= self.__integrationtime:
868 if (datatime - self.__initime) >= self.__integrationtime:
863 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
869 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
864 self.n = n
870 self.n = n
865 self.__dataReady = True
871 self.__dataReady = True
866
872
867 return avgdata_spc, avgdata_cspc, avgdata_dc
873 return avgdata_spc, avgdata_cspc, avgdata_dc
868
874
869 def integrate(self, datatime, *args):
875 def integrate(self, datatime, *args):
870
876
871 if self.__profIndex == 0:
877 if self.__profIndex == 0:
872 self.__initime = datatime
878 self.__initime = datatime
873
879
874 if self.__byTime:
880 if self.__byTime:
875 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
881 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
876 datatime, *args)
882 datatime, *args)
877 else:
883 else:
878 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
884 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
879
885
880 if not self.__dataReady:
886 if not self.__dataReady:
881 return None, None, None, None
887 return None, None, None, None
882
888
883 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
889 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
884
890
885 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
891 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
886 if n == 1:
892 if n == 1:
887 return dataOut
893 return dataOut
888
894
889 dataOut.flagNoData = True
895 dataOut.flagNoData = True
890
896
891 if not self.isConfig:
897 if not self.isConfig:
892 self.setup(n, timeInterval, overlapping)
898 self.setup(n, timeInterval, overlapping)
893 self.isConfig = True
899 self.isConfig = True
894
900
895 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
901 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
896 dataOut.data_spc,
902 dataOut.data_spc,
897 dataOut.data_cspc,
903 dataOut.data_cspc,
898 dataOut.data_dc)
904 dataOut.data_dc)
899
905
900 if self.__dataReady:
906 if self.__dataReady:
901
907
902 dataOut.data_spc = avgdata_spc
908 dataOut.data_spc = avgdata_spc
903 dataOut.data_cspc = avgdata_cspc
909 dataOut.data_cspc = avgdata_cspc
904 dataOut.data_dc = avgdata_dc
910 dataOut.data_dc = avgdata_dc
905 dataOut.nIncohInt *= self.n
911 dataOut.nIncohInt *= self.n
906 dataOut.utctime = avgdatatime
912 dataOut.utctime = avgdatatime
907 dataOut.flagNoData = False
913 dataOut.flagNoData = False
908
914
909 return dataOut
915 return dataOut
910
916
911 class dopplerFlip(Operation):
917 class dopplerFlip(Operation):
912
918
913 def run(self, dataOut):
919 def run(self, dataOut):
914 # arreglo 1: (num_chan, num_profiles, num_heights)
920 # arreglo 1: (num_chan, num_profiles, num_heights)
915 self.dataOut = dataOut
921 self.dataOut = dataOut
916 # JULIA-oblicua, indice 2
922 # JULIA-oblicua, indice 2
917 # arreglo 2: (num_profiles, num_heights)
923 # arreglo 2: (num_profiles, num_heights)
918 jspectra = self.dataOut.data_spc[2]
924 jspectra = self.dataOut.data_spc[2]
919 jspectra_tmp = numpy.zeros(jspectra.shape)
925 jspectra_tmp = numpy.zeros(jspectra.shape)
920 num_profiles = jspectra.shape[0]
926 num_profiles = jspectra.shape[0]
921 freq_dc = int(num_profiles / 2)
927 freq_dc = int(num_profiles / 2)
922 # Flip con for
928 # Flip con for
923 for j in range(num_profiles):
929 for j in range(num_profiles):
924 jspectra_tmp[num_profiles-j-1]= jspectra[j]
930 jspectra_tmp[num_profiles-j-1]= jspectra[j]
925 # Intercambio perfil de DC con perfil inmediato anterior
931 # Intercambio perfil de DC con perfil inmediato anterior
926 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
932 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
927 jspectra_tmp[freq_dc]= jspectra[freq_dc]
933 jspectra_tmp[freq_dc]= jspectra[freq_dc]
928 # canal modificado es re-escrito en el arreglo de canales
934 # canal modificado es re-escrito en el arreglo de canales
929 self.dataOut.data_spc[2] = jspectra_tmp
935 self.dataOut.data_spc[2] = jspectra_tmp
930
936
931 return self.dataOut No newline at end of file
937 return self.dataOut
@@ -1,1625 +1,1629
1 import sys
1 import sys
2 import numpy,math
2 import numpy,math
3 from scipy import interpolate
3 from scipy import interpolate
4 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
4 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
5 from schainpy.model.data.jrodata import Voltage,hildebrand_sekhon
5 from schainpy.model.data.jrodata import Voltage,hildebrand_sekhon
6 from schainpy.utils import log
6 from schainpy.utils import log
7 from time import time
7 from time import time
8
8 # voltage proc master
9
10
9
11 class VoltageProc(ProcessingUnit):
10 class VoltageProc(ProcessingUnit):
12
11
13 def __init__(self):
12 def __init__(self):
14
13
15 ProcessingUnit.__init__(self)
14 ProcessingUnit.__init__(self)
16
15
17 self.dataOut = Voltage()
16 self.dataOut = Voltage()
18 self.flip = 1
17 self.flip = 1
19 self.setupReq = False
18 self.setupReq = False
20
19
21 def run(self):
20 def run(self, runNextUnit = 0):
22
21
23 if self.dataIn.type == 'AMISR':
22 if self.dataIn.type == 'AMISR':
24 self.__updateObjFromAmisrInput()
23 self.__updateObjFromAmisrInput()
25
24
26 if self.dataIn.type == 'Voltage':
25 if self.dataIn.type == 'Voltage':
27 self.dataOut.copy(self.dataIn)
26 self.dataOut.copy(self.dataIn)
27 self.dataOut.runNextUnit = runNextUnit
28
28
29
29 def __updateObjFromAmisrInput(self):
30 def __updateObjFromAmisrInput(self):
30
31
31 self.dataOut.timeZone = self.dataIn.timeZone
32 self.dataOut.timeZone = self.dataIn.timeZone
32 self.dataOut.dstFlag = self.dataIn.dstFlag
33 self.dataOut.dstFlag = self.dataIn.dstFlag
33 self.dataOut.errorCount = self.dataIn.errorCount
34 self.dataOut.errorCount = self.dataIn.errorCount
34 self.dataOut.useLocalTime = self.dataIn.useLocalTime
35 self.dataOut.useLocalTime = self.dataIn.useLocalTime
35
36
36 self.dataOut.flagNoData = self.dataIn.flagNoData
37 self.dataOut.flagNoData = self.dataIn.flagNoData
37 self.dataOut.data = self.dataIn.data
38 self.dataOut.data = self.dataIn.data
38 self.dataOut.utctime = self.dataIn.utctime
39 self.dataOut.utctime = self.dataIn.utctime
39 self.dataOut.channelList = self.dataIn.channelList
40 self.dataOut.channelList = self.dataIn.channelList
40 #self.dataOut.timeInterval = self.dataIn.timeInterval
41 #self.dataOut.timeInterval = self.dataIn.timeInterval
41 self.dataOut.heightList = self.dataIn.heightList
42 self.dataOut.heightList = self.dataIn.heightList
42 self.dataOut.nProfiles = self.dataIn.nProfiles
43 self.dataOut.nProfiles = self.dataIn.nProfiles
43
44
44 self.dataOut.nCohInt = self.dataIn.nCohInt
45 self.dataOut.nCohInt = self.dataIn.nCohInt
45 self.dataOut.ippSeconds = self.dataIn.ippSeconds
46 self.dataOut.ippSeconds = self.dataIn.ippSeconds
46 self.dataOut.frequency = self.dataIn.frequency
47 self.dataOut.frequency = self.dataIn.frequency
47
48
48 self.dataOut.azimuth = self.dataIn.azimuth
49 self.dataOut.azimuth = self.dataIn.azimuth
49 self.dataOut.zenith = self.dataIn.zenith
50 self.dataOut.zenith = self.dataIn.zenith
50
51
51 self.dataOut.beam.codeList = self.dataIn.beam.codeList
52 self.dataOut.beam.codeList = self.dataIn.beam.codeList
52 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
53 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
53 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
54 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
54
55
55
56
56 class selectChannels(Operation):
57 class selectChannels(Operation):
57
58
58 def run(self, dataOut, channelList):
59 def run(self, dataOut, channelList):
59
60
60 channelIndexList = []
61 channelIndexList = []
61 self.dataOut = dataOut
62 self.dataOut = dataOut
62 for channel in channelList:
63 for channel in channelList:
63 if channel not in self.dataOut.channelList:
64 if channel not in self.dataOut.channelList:
64 raise ValueError("Channel %d is not in %s" %(channel, str(self.dataOut.channelList)))
65 raise ValueError("Channel %d is not in %s" %(channel, str(self.dataOut.channelList)))
65
66
66 index = self.dataOut.channelList.index(channel)
67 index = self.dataOut.channelList.index(channel)
67 channelIndexList.append(index)
68 channelIndexList.append(index)
68 self.selectChannelsByIndex(channelIndexList)
69 self.selectChannelsByIndex(channelIndexList)
69 return self.dataOut
70 return self.dataOut
70
71
71 def selectChannelsByIndex(self, channelIndexList):
72 def selectChannelsByIndex(self, channelIndexList):
72 """
73 """
73 Selecciona un bloque de datos en base a canales segun el channelIndexList
74 Selecciona un bloque de datos en base a canales segun el channelIndexList
74
75
75 Input:
76 Input:
76 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
77 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
77
78
78 Affected:
79 Affected:
79 self.dataOut.data
80 self.dataOut.data
80 self.dataOut.channelIndexList
81 self.dataOut.channelIndexList
81 self.dataOut.nChannels
82 self.dataOut.nChannels
82 self.dataOut.m_ProcessingHeader.totalSpectra
83 self.dataOut.m_ProcessingHeader.totalSpectra
83 self.dataOut.systemHeaderObj.numChannels
84 self.dataOut.systemHeaderObj.numChannels
84 self.dataOut.m_ProcessingHeader.blockSize
85 self.dataOut.m_ProcessingHeader.blockSize
85
86
86 Return:
87 Return:
87 None
88 None
88 """
89 """
89
90
90 for channelIndex in channelIndexList:
91 for channelIndex in channelIndexList:
91 if channelIndex not in self.dataOut.channelIndexList:
92 if channelIndex not in self.dataOut.channelIndexList:
92 raise ValueError("The value %d in channelIndexList is not valid" %channelIndex)
93 raise ValueError("The value %d in channelIndexList is not valid" %channelIndex)
93
94
94 if self.dataOut.type == 'Voltage':
95 if self.dataOut.type == 'Voltage':
95 if self.dataOut.flagDataAsBlock:
96 if self.dataOut.flagDataAsBlock:
96 """
97 """
97 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
98 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
98 """
99 """
99 data = self.dataOut.data[channelIndexList,:,:]
100 data = self.dataOut.data[channelIndexList,:,:]
100 else:
101 else:
101 data = self.dataOut.data[channelIndexList,:]
102 data = self.dataOut.data[channelIndexList,:]
102
103
103 self.dataOut.data = data
104 self.dataOut.data = data
104 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
105 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
105 self.dataOut.channelList = range(len(channelIndexList))
106 self.dataOut.channelList = range(len(channelIndexList))
106
107
107 elif self.dataOut.type == 'Spectra':
108 elif self.dataOut.type == 'Spectra':
108 data_spc = self.dataOut.data_spc[channelIndexList, :]
109 data_spc = self.dataOut.data_spc[channelIndexList, :]
109 data_dc = self.dataOut.data_dc[channelIndexList, :]
110 data_dc = self.dataOut.data_dc[channelIndexList, :]
110
111
111 self.dataOut.data_spc = data_spc
112 self.dataOut.data_spc = data_spc
112 self.dataOut.data_dc = data_dc
113 self.dataOut.data_dc = data_dc
113
114
114 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
115 # self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList]
115 self.dataOut.channelList = range(len(channelIndexList))
116 self.dataOut.channelList = range(len(channelIndexList))
116 self.__selectPairsByChannel(channelIndexList)
117 self.__selectPairsByChannel(channelIndexList)
117
118
118 return 1
119 return 1
119
120
120 def __selectPairsByChannel(self, channelList=None):
121 def __selectPairsByChannel(self, channelList=None):
121
122
122 if channelList == None:
123 if channelList == None:
123 return
124 return
124
125
125 pairsIndexListSelected = []
126 pairsIndexListSelected = []
126 for pairIndex in self.dataOut.pairsIndexList:
127 for pairIndex in self.dataOut.pairsIndexList:
127 # First pair
128 # First pair
128 if self.dataOut.pairsList[pairIndex][0] not in channelList:
129 if self.dataOut.pairsList[pairIndex][0] not in channelList:
129 continue
130 continue
130 # Second pair
131 # Second pair
131 if self.dataOut.pairsList[pairIndex][1] not in channelList:
132 if self.dataOut.pairsList[pairIndex][1] not in channelList:
132 continue
133 continue
133
134
134 pairsIndexListSelected.append(pairIndex)
135 pairsIndexListSelected.append(pairIndex)
135
136
136 if not pairsIndexListSelected:
137 if not pairsIndexListSelected:
137 self.dataOut.data_cspc = None
138 self.dataOut.data_cspc = None
138 self.dataOut.pairsList = []
139 self.dataOut.pairsList = []
139 return
140 return
140
141
141 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndexListSelected]
142 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndexListSelected]
142 self.dataOut.pairsList = [self.dataOut.pairsList[i]
143 self.dataOut.pairsList = [self.dataOut.pairsList[i]
143 for i in pairsIndexListSelected]
144 for i in pairsIndexListSelected]
144
145
145 return
146 return
146
147
147 class selectHeights(Operation):
148 class selectHeights(Operation):
148
149
149 def run(self, dataOut, minHei=None, maxHei=None, minIndex=None, maxIndex=None):
150 def run(self, dataOut, minHei=None, maxHei=None, minIndex=None, maxIndex=None):
150 """
151 """
151 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
152 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
152 minHei <= height <= maxHei
153 minHei <= height <= maxHei
153
154
154 Input:
155 Input:
155 minHei : valor minimo de altura a considerar
156 minHei : valor minimo de altura a considerar
156 maxHei : valor maximo de altura a considerar
157 maxHei : valor maximo de altura a considerar
157
158
158 Affected:
159 Affected:
159 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
160 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
160
161
161 Return:
162 Return:
162 1 si el metodo se ejecuto con exito caso contrario devuelve 0
163 1 si el metodo se ejecuto con exito caso contrario devuelve 0
163 """
164 """
164
165
165 self.dataOut = dataOut
166 self.dataOut = dataOut
166
167
167 if minHei and maxHei:
168 if type(minHei) == int or type(minHei) == float:
169 v_minHei= True
170 else:
171 v_minHei= False
168
172
173 if v_minHei and maxHei:
169 if (minHei < self.dataOut.heightList[0]):
174 if (minHei < self.dataOut.heightList[0]):
170 minHei = self.dataOut.heightList[0]
175 minHei = self.dataOut.heightList[0]
171
176
172 if (maxHei > self.dataOut.heightList[-1]):
177 if (maxHei > self.dataOut.heightList[-1]):
173 maxHei = self.dataOut.heightList[-1]
178 maxHei = self.dataOut.heightList[-1]
174
179
175 minIndex = 0
180 minIndex = 0
176 maxIndex = 0
181 maxIndex = 0
177 heights = self.dataOut.heightList
182 heights = self.dataOut.heightList
178
179 inda = numpy.where(heights >= minHei)
183 inda = numpy.where(heights >= minHei)
180 indb = numpy.where(heights <= maxHei)
184 indb = numpy.where(heights <= maxHei)
181
185
182 try:
186 try:
183 minIndex = inda[0][0]
187 minIndex = inda[0][0]
184 except:
188 except:
185 minIndex = 0
189 minIndex = 0
186
190
187 try:
191 try:
188 maxIndex = indb[0][-1]
192 maxIndex = indb[0][-1]
189 except:
193 except:
190 maxIndex = len(heights)
194 maxIndex = len(heights)
191
195 print(minIndex)
196 print(maxIndex)
192 self.selectHeightsByIndex(minIndex, maxIndex)
197 self.selectHeightsByIndex(minIndex, maxIndex)
193
198
194 return self.dataOut
199 return self.dataOut
195
200
196 def selectHeightsByIndex(self, minIndex, maxIndex):
201 def selectHeightsByIndex(self, minIndex, maxIndex):
197 """
202 """
198 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
203 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
199 minIndex <= index <= maxIndex
204 minIndex <= index <= maxIndex
200
205
201 Input:
206 Input:
202 minIndex : valor de indice minimo de altura a considerar
207 minIndex : valor de indice minimo de altura a considerar
203 maxIndex : valor de indice maximo de altura a considerar
208 maxIndex : valor de indice maximo de altura a considerar
204
209
205 Affected:
210 Affected:
206 self.dataOut.data
211 self.dataOut.data
207 self.dataOut.heightList
212 self.dataOut.heightList
208
213
209 Return:
214 Return:
210 1 si el metodo se ejecuto con exito caso contrario devuelve 0
215 1 si el metodo se ejecuto con exito caso contrario devuelve 0
211 """
216 """
212
217
213 if self.dataOut.type == 'Voltage':
218 if self.dataOut.type == 'Voltage':
219 print(minIndex)
220 print(maxIndex)
214 if (minIndex < 0) or (minIndex > maxIndex):
221 if (minIndex < 0) or (minIndex > maxIndex):
215 raise ValueError("Height index range (%d,%d) is not valid" % (minIndex, maxIndex))
222 raise ValueError("Height index range (%d,%d) is not valid" % (minIndex, maxIndex))
216
223
217 if (maxIndex >= self.dataOut.nHeights):
224 if (maxIndex >= self.dataOut.nHeights):
218 maxIndex = self.dataOut.nHeights
225 maxIndex = self.dataOut.nHeights
219
226
220 #voltage
227 #voltage
221 if self.dataOut.flagDataAsBlock:
228 if self.dataOut.flagDataAsBlock:
222 """
229 """
223 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
230 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
224 """
231 """
225 data = self.dataOut.data[:,:, minIndex:maxIndex]
232 data = self.dataOut.data[:,:, minIndex:maxIndex]
226 else:
233 else:
227 data = self.dataOut.data[:, minIndex:maxIndex]
234 data = self.dataOut.data[:, minIndex:maxIndex]
228
235
229 # firstHeight = self.dataOut.heightList[minIndex]
236 # firstHeight = self.dataOut.heightList[minIndex]
230
237
231 self.dataOut.data = data
238 self.dataOut.data = data
232 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex]
239 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex]
233
240
234 if self.dataOut.nHeights <= 1:
241 if self.dataOut.nHeights <= 1:
235 raise ValueError("selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights))
242 raise ValueError("selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights))
236 elif self.dataOut.type == 'Spectra':
243 elif self.dataOut.type == 'Spectra':
237 if (minIndex < 0) or (minIndex > maxIndex):
244 if (minIndex < 0) or (minIndex > maxIndex):
238 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (
245 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (
239 minIndex, maxIndex))
246 minIndex, maxIndex))
240
247
241 if (maxIndex >= self.dataOut.nHeights):
248 if (maxIndex >= self.dataOut.nHeights):
242 maxIndex = self.dataOut.nHeights - 1
249 maxIndex = self.dataOut.nHeights - 1
243
250
244 # Spectra
251 # Spectra
245 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
252 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
246
253
247 data_cspc = None
254 data_cspc = None
248 if self.dataOut.data_cspc is not None:
255 if self.dataOut.data_cspc is not None:
249 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
256 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
250
257
251 data_dc = None
258 data_dc = None
252 if self.dataOut.data_dc is not None:
259 if self.dataOut.data_dc is not None:
253 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
260 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
254
261
255 self.dataOut.data_spc = data_spc
262 self.dataOut.data_spc = data_spc
256 self.dataOut.data_cspc = data_cspc
263 self.dataOut.data_cspc = data_cspc
257 self.dataOut.data_dc = data_dc
264 self.dataOut.data_dc = data_dc
258
265
259 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
266 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
260
267
261 return 1
268 return 1
262
269
263
270
264 class filterByHeights(Operation):
271 class filterByHeights(Operation):
265
272
266 def run(self, dataOut, window):
273 def run(self, dataOut, window):
267
274
268 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
275 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
269
276
270 if window == None:
277 if window == None:
271 window = (dataOut.radarControllerHeaderObj.txA/dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
278 window = (dataOut.radarControllerHeaderObj.txA/dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
272
279
273 newdelta = deltaHeight * window
280 newdelta = deltaHeight * window
274 r = dataOut.nHeights % window
281 r = dataOut.nHeights % window
275 newheights = (dataOut.nHeights-r)/window
282 newheights = (dataOut.nHeights-r)/window
276
283
277 if newheights <= 1:
284 if newheights <= 1:
278 raise ValueError("filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(dataOut.nHeights, window))
285 raise ValueError("filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(dataOut.nHeights, window))
279
286
280 if dataOut.flagDataAsBlock:
287 if dataOut.flagDataAsBlock:
281 """
288 """
282 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
289 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
283 """
290 """
284 buffer = dataOut.data[:, :, 0:int(dataOut.nHeights-r)]
291 buffer = dataOut.data[:, :, 0:int(dataOut.nHeights-r)]
285 buffer = buffer.reshape(dataOut.nChannels, dataOut.nProfiles, int(dataOut.nHeights/window), window)
292 buffer = buffer.reshape(dataOut.nChannels, dataOut.nProfiles, int(dataOut.nHeights/window), window)
286 buffer = numpy.sum(buffer,3)
293 buffer = numpy.sum(buffer,3)
287
294
288 else:
295 else:
289 buffer = dataOut.data[:,0:int(dataOut.nHeights-r)]
296 buffer = dataOut.data[:,0:int(dataOut.nHeights-r)]
290 buffer = buffer.reshape(dataOut.nChannels,int(dataOut.nHeights/window),int(window))
297 buffer = buffer.reshape(dataOut.nChannels,int(dataOut.nHeights/window),int(window))
291 buffer = numpy.sum(buffer,2)
298 buffer = numpy.sum(buffer,2)
292
299
293 dataOut.data = buffer
300 dataOut.data = buffer
294 dataOut.heightList = dataOut.heightList[0] + numpy.arange( newheights )*newdelta
301 dataOut.heightList = dataOut.heightList[0] + numpy.arange( newheights )*newdelta
295 dataOut.windowOfFilter = window
302 dataOut.windowOfFilter = window
296
303
297 return dataOut
304 return dataOut
298
305
299
306
300 class setH0(Operation):
307 class setH0(Operation):
301
308
302 def run(self, dataOut, h0, deltaHeight = None):
309 def run(self, dataOut, h0, deltaHeight = None):
303
310
304 if not deltaHeight:
311 if not deltaHeight:
305 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
312 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
306
313
307 nHeights = dataOut.nHeights
314 nHeights = dataOut.nHeights
308
315
309 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
316 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
310
317
311 dataOut.heightList = newHeiRange
318 dataOut.heightList = newHeiRange
312
319
313 return dataOut
320 return dataOut
314
321
315
322
316 class deFlip(Operation):
323 class deFlip(Operation):
317
324
318 def run(self, dataOut, channelList = []):
325 def run(self, dataOut, channelList = []):
319
326
320 data = dataOut.data.copy()
327 data = dataOut.data.copy()
321
328
322 if dataOut.flagDataAsBlock:
329 if dataOut.flagDataAsBlock:
323 flip = self.flip
330 flip = self.flip
324 profileList = list(range(dataOut.nProfiles))
331 profileList = list(range(dataOut.nProfiles))
325
332
326 if not channelList:
333 if not channelList:
327 for thisProfile in profileList:
334 for thisProfile in profileList:
328 data[:,thisProfile,:] = data[:,thisProfile,:]*flip
335 data[:,thisProfile,:] = data[:,thisProfile,:]*flip
329 flip *= -1.0
336 flip *= -1.0
330 else:
337 else:
331 for thisChannel in channelList:
338 for thisChannel in channelList:
332 if thisChannel not in dataOut.channelList:
339 if thisChannel not in dataOut.channelList:
333 continue
340 continue
334
341
335 for thisProfile in profileList:
342 for thisProfile in profileList:
336 data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip
343 data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip
337 flip *= -1.0
344 flip *= -1.0
338
345
339 self.flip = flip
346 self.flip = flip
340
347
341 else:
348 else:
342 if not channelList:
349 if not channelList:
343 data[:,:] = data[:,:]*self.flip
350 data[:,:] = data[:,:]*self.flip
344 else:
351 else:
345 for thisChannel in channelList:
352 for thisChannel in channelList:
346 if thisChannel not in dataOut.channelList:
353 if thisChannel not in dataOut.channelList:
347 continue
354 continue
348
355
349 data[thisChannel,:] = data[thisChannel,:]*self.flip
356 data[thisChannel,:] = data[thisChannel,:]*self.flip
350
357
351 self.flip *= -1.
358 self.flip *= -1.
352
359
353 dataOut.data = data
360 dataOut.data = data
354
361
355 return dataOut
362 return dataOut
356
363
357
364
358 class setAttribute(Operation):
365 class setAttribute(Operation):
359 '''
366 '''
360 Set an arbitrary attribute(s) to dataOut
367 Set an arbitrary attribute(s) to dataOut
361 '''
368 '''
362
369
363 def __init__(self):
370 def __init__(self):
364
371
365 Operation.__init__(self)
372 Operation.__init__(self)
366 self._ready = False
373 self._ready = False
367
374
368 def run(self, dataOut, **kwargs):
375 def run(self, dataOut, **kwargs):
369
376
370 for key, value in kwargs.items():
377 for key, value in kwargs.items():
371 setattr(dataOut, key, value)
378 setattr(dataOut, key, value)
372
379
373 return dataOut
380 return dataOut
374
381
375
382
376 @MPDecorator
383 @MPDecorator
377 class printAttribute(Operation):
384 class printAttribute(Operation):
378 '''
385 '''
379 Print an arbitrary attribute of dataOut
386 Print an arbitrary attribute of dataOut
380 '''
387 '''
381
388
382 def __init__(self):
389 def __init__(self):
383
390
384 Operation.__init__(self)
391 Operation.__init__(self)
385
392
386 def run(self, dataOut, attributes):
393 def run(self, dataOut, attributes):
387
394
388 if isinstance(attributes, str):
395 if isinstance(attributes, str):
389 attributes = [attributes]
396 attributes = [attributes]
390 for attr in attributes:
397 for attr in attributes:
391 if hasattr(dataOut, attr):
398 if hasattr(dataOut, attr):
392 log.log(getattr(dataOut, attr), attr)
399 log.log(getattr(dataOut, attr), attr)
393
400
394
401
395 class interpolateHeights(Operation):
402 class interpolateHeights(Operation):
396
403
397 def run(self, dataOut, topLim, botLim):
404 def run(self, dataOut, topLim, botLim):
398 #69 al 72 para julia
405 #69 al 72 para julia
399 #82-84 para meteoros
406 #82-84 para meteoros
400 if len(numpy.shape(dataOut.data))==2:
407 if len(numpy.shape(dataOut.data))==2:
401 sampInterp = (dataOut.data[:,botLim-1] + dataOut.data[:,topLim+1])/2
408 sampInterp = (dataOut.data[:,botLim-1] + dataOut.data[:,topLim+1])/2
402 sampInterp = numpy.transpose(numpy.tile(sampInterp,(topLim-botLim + 1,1)))
409 sampInterp = numpy.transpose(numpy.tile(sampInterp,(topLim-botLim + 1,1)))
403 #dataOut.data[:,botLim:limSup+1] = sampInterp
410 #dataOut.data[:,botLim:limSup+1] = sampInterp
404 dataOut.data[:,botLim:topLim+1] = sampInterp
411 dataOut.data[:,botLim:topLim+1] = sampInterp
405 else:
412 else:
406 nHeights = dataOut.data.shape[2]
413 nHeights = dataOut.data.shape[2]
407 x = numpy.hstack((numpy.arange(botLim),numpy.arange(topLim+1,nHeights)))
414 x = numpy.hstack((numpy.arange(botLim),numpy.arange(topLim+1,nHeights)))
408 y = dataOut.data[:,:,list(range(botLim))+list(range(topLim+1,nHeights))]
415 y = dataOut.data[:,:,list(range(botLim))+list(range(topLim+1,nHeights))]
409 f = interpolate.interp1d(x, y, axis = 2)
416 f = interpolate.interp1d(x, y, axis = 2)
410 xnew = numpy.arange(botLim,topLim+1)
417 xnew = numpy.arange(botLim,topLim+1)
411 ynew = f(xnew)
418 ynew = f(xnew)
412 dataOut.data[:,:,botLim:topLim+1] = ynew
419 dataOut.data[:,:,botLim:topLim+1] = ynew
413
420
414 return dataOut
421 return dataOut
415
422
416
423
417 class CohInt(Operation):
424 class CohInt(Operation):
418
425
419 isConfig = False
426 isConfig = False
420 __profIndex = 0
427 __profIndex = 0
421 __byTime = False
428 __byTime = False
422 __initime = None
429 __initime = None
423 __lastdatatime = None
430 __lastdatatime = None
424 __integrationtime = None
431 __integrationtime = None
425 __buffer = None
432 __buffer = None
426 __bufferStride = []
433 __bufferStride = []
427 __dataReady = False
434 __dataReady = False
428 __profIndexStride = 0
435 __profIndexStride = 0
429 __dataToPutStride = False
436 __dataToPutStride = False
430 n = None
437 n = None
431
438
432 def __init__(self, **kwargs):
439 def __init__(self, **kwargs):
433
440
434 Operation.__init__(self, **kwargs)
441 Operation.__init__(self, **kwargs)
435
442
436 def setup(self, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False):
443 def setup(self, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False):
437 """
444 """
438 Set the parameters of the integration class.
445 Set the parameters of the integration class.
439
446
440 Inputs:
447 Inputs:
441
448
442 n : Number of coherent integrations
449 n : Number of coherent integrations
443 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
450 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
444 overlapping :
451 overlapping :
445 """
452 """
446
453
447 self.__initime = None
454 self.__initime = None
448 self.__lastdatatime = 0
455 self.__lastdatatime = 0
449 self.__buffer = None
456 self.__buffer = None
450 self.__dataReady = False
457 self.__dataReady = False
451 self.byblock = byblock
458 self.byblock = byblock
452 self.stride = stride
459 self.stride = stride
453
460
454 if n == None and timeInterval == None:
461 if n == None and timeInterval == None:
455 raise ValueError("n or timeInterval should be specified ...")
462 raise ValueError("n or timeInterval should be specified ...")
456
463
457 if n != None:
464 if n != None:
458 self.n = n
465 self.n = n
459 self.__byTime = False
466 self.__byTime = False
460 else:
467 else:
461 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
468 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
462 self.n = 9999
469 self.n = 9999
463 self.__byTime = True
470 self.__byTime = True
464
471
465 if overlapping:
472 if overlapping:
466 self.__withOverlapping = True
473 self.__withOverlapping = True
467 self.__buffer = None
474 self.__buffer = None
468 else:
475 else:
469 self.__withOverlapping = False
476 self.__withOverlapping = False
470 self.__buffer = 0
477 self.__buffer = 0
471
478
472 self.__profIndex = 0
479 self.__profIndex = 0
473
480
474 def putData(self, data):
481 def putData(self, data):
475
482
476 """
483 """
477 Add a profile to the __buffer and increase in one the __profileIndex
484 Add a profile to the __buffer and increase in one the __profileIndex
478
485
479 """
486 """
480
487
481 if not self.__withOverlapping:
488 if not self.__withOverlapping:
482 self.__buffer += data.copy()
489 self.__buffer += data.copy()
483 self.__profIndex += 1
490 self.__profIndex += 1
484 return
491 return
485
492
486 #Overlapping data
493 #Overlapping data
487 nChannels, nHeis = data.shape
494 nChannels, nHeis = data.shape
488 data = numpy.reshape(data, (1, nChannels, nHeis))
495 data = numpy.reshape(data, (1, nChannels, nHeis))
489
496
490 #If the buffer is empty then it takes the data value
497 #If the buffer is empty then it takes the data value
491 if self.__buffer is None:
498 if self.__buffer is None:
492 self.__buffer = data
499 self.__buffer = data
493 self.__profIndex += 1
500 self.__profIndex += 1
494 return
501 return
495
502
496 #If the buffer length is lower than n then stakcing the data value
503 #If the buffer length is lower than n then stakcing the data value
497 if self.__profIndex < self.n:
504 if self.__profIndex < self.n:
498 self.__buffer = numpy.vstack((self.__buffer, data))
505 self.__buffer = numpy.vstack((self.__buffer, data))
499 self.__profIndex += 1
506 self.__profIndex += 1
500 return
507 return
501
508
502 #If the buffer length is equal to n then replacing the last buffer value with the data value
509 #If the buffer length is equal to n then replacing the last buffer value with the data value
503 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
510 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
504 self.__buffer[self.n-1] = data
511 self.__buffer[self.n-1] = data
505 self.__profIndex = self.n
512 self.__profIndex = self.n
506 return
513 return
507
514
508
515
509 def pushData(self):
516 def pushData(self):
510 """
517 """
511 Return the sum of the last profiles and the profiles used in the sum.
518 Return the sum of the last profiles and the profiles used in the sum.
512
519
513 Affected:
520 Affected:
514
521
515 self.__profileIndex
522 self.__profileIndex
516
523
517 """
524 """
518
525
519 if not self.__withOverlapping:
526 if not self.__withOverlapping:
520 data = self.__buffer
527 data = self.__buffer
521 n = self.__profIndex
528 n = self.__profIndex
522
529
523 self.__buffer = 0
530 self.__buffer = 0
524 self.__profIndex = 0
531 self.__profIndex = 0
525
532
526 return data, n
533 return data, n
527
534
528 #Integration with Overlapping
535 #Integration with Overlapping
529 data = numpy.sum(self.__buffer, axis=0)
536 data = numpy.sum(self.__buffer, axis=0)
530 # print data
537 # print data
531 # raise
538 # raise
532 n = self.__profIndex
539 n = self.__profIndex
533
540
534 return data, n
541 return data, n
535
542
536 def byProfiles(self, data):
543 def byProfiles(self, data):
537
544
538 self.__dataReady = False
545 self.__dataReady = False
539 avgdata = None
546 avgdata = None
540 # n = None
547 # n = None
541 # print data
548 # print data
542 # raise
549 # raise
543 self.putData(data)
550 self.putData(data)
544
551
545 if self.__profIndex == self.n:
552 if self.__profIndex == self.n:
546 avgdata, n = self.pushData()
553 avgdata, n = self.pushData()
547 self.__dataReady = True
554 self.__dataReady = True
548
555
549 return avgdata
556 return avgdata
550
557
551 def byTime(self, data, datatime):
558 def byTime(self, data, datatime):
552
559
553 self.__dataReady = False
560 self.__dataReady = False
554 avgdata = None
561 avgdata = None
555 n = None
562 n = None
556
563
557 self.putData(data)
564 self.putData(data)
558
565
559 if (datatime - self.__initime) >= self.__integrationtime:
566 if (datatime - self.__initime) >= self.__integrationtime:
560 avgdata, n = self.pushData()
567 avgdata, n = self.pushData()
561 self.n = n
568 self.n = n
562 self.__dataReady = True
569 self.__dataReady = True
563
570
564 return avgdata
571 return avgdata
565
572
566 def integrateByStride(self, data, datatime):
573 def integrateByStride(self, data, datatime):
567 # print data
574 # print data
568 if self.__profIndex == 0:
575 if self.__profIndex == 0:
569 self.__buffer = [[data.copy(), datatime]]
576 self.__buffer = [[data.copy(), datatime]]
570 else:
577 else:
571 self.__buffer.append([data.copy(),datatime])
578 self.__buffer.append([data.copy(),datatime])
572 self.__profIndex += 1
579 self.__profIndex += 1
573 self.__dataReady = False
580 self.__dataReady = False
574
581
575 if self.__profIndex == self.n * self.stride :
582 if self.__profIndex == self.n * self.stride :
576 self.__dataToPutStride = True
583 self.__dataToPutStride = True
577 self.__profIndexStride = 0
584 self.__profIndexStride = 0
578 self.__profIndex = 0
585 self.__profIndex = 0
579 self.__bufferStride = []
586 self.__bufferStride = []
580 for i in range(self.stride):
587 for i in range(self.stride):
581 current = self.__buffer[i::self.stride]
588 current = self.__buffer[i::self.stride]
582 data = numpy.sum([t[0] for t in current], axis=0)
589 data = numpy.sum([t[0] for t in current], axis=0)
583 avgdatatime = numpy.average([t[1] for t in current])
590 avgdatatime = numpy.average([t[1] for t in current])
584 # print data
591 # print data
585 self.__bufferStride.append((data, avgdatatime))
592 self.__bufferStride.append((data, avgdatatime))
586
593
587 if self.__dataToPutStride:
594 if self.__dataToPutStride:
588 self.__dataReady = True
595 self.__dataReady = True
589 self.__profIndexStride += 1
596 self.__profIndexStride += 1
590 if self.__profIndexStride == self.stride:
597 if self.__profIndexStride == self.stride:
591 self.__dataToPutStride = False
598 self.__dataToPutStride = False
592 # print self.__bufferStride[self.__profIndexStride - 1]
599 # print self.__bufferStride[self.__profIndexStride - 1]
593 # raise
600 # raise
594 return self.__bufferStride[self.__profIndexStride - 1]
601 return self.__bufferStride[self.__profIndexStride - 1]
595
602
596
603
597 return None, None
604 return None, None
598
605
599 def integrate(self, data, datatime=None):
606 def integrate(self, data, datatime=None):
600
607
601 if self.__initime == None:
608 if self.__initime == None:
602 self.__initime = datatime
609 self.__initime = datatime
603
610
604 if self.__byTime:
611 if self.__byTime:
605 avgdata = self.byTime(data, datatime)
612 avgdata = self.byTime(data, datatime)
606 else:
613 else:
607 avgdata = self.byProfiles(data)
614 avgdata = self.byProfiles(data)
608
615
609
616
610 self.__lastdatatime = datatime
617 self.__lastdatatime = datatime
611
618
612 if avgdata is None:
619 if avgdata is None:
613 return None, None
620 return None, None
614
621
615 avgdatatime = self.__initime
622 avgdatatime = self.__initime
616
623
617 deltatime = datatime - self.__lastdatatime
624 deltatime = datatime - self.__lastdatatime
618
625
619 if not self.__withOverlapping:
626 if not self.__withOverlapping:
620 self.__initime = datatime
627 self.__initime = datatime
621 else:
628 else:
622 self.__initime += deltatime
629 self.__initime += deltatime
623
630
624 return avgdata, avgdatatime
631 return avgdata, avgdatatime
625
632
626 def integrateByBlock(self, dataOut):
633 def integrateByBlock(self, dataOut):
627
634
628 times = int(dataOut.data.shape[1]/self.n)
635 times = int(dataOut.data.shape[1]/self.n)
629 avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex)
636 avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex)
630
637
631 id_min = 0
638 id_min = 0
632 id_max = self.n
639 id_max = self.n
633
640
634 for i in range(times):
641 for i in range(times):
635 junk = dataOut.data[:,id_min:id_max,:]
642 junk = dataOut.data[:,id_min:id_max,:]
636 avgdata[:,i,:] = junk.sum(axis=1)
643 avgdata[:,i,:] = junk.sum(axis=1)
637 id_min += self.n
644 id_min += self.n
638 id_max += self.n
645 id_max += self.n
639
646
640 timeInterval = dataOut.ippSeconds*self.n
647 timeInterval = dataOut.ippSeconds*self.n
641 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
648 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
642 self.__dataReady = True
649 self.__dataReady = True
643 return avgdata, avgdatatime
650 return avgdata, avgdatatime
644
651
645 def run(self, dataOut, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False, **kwargs):
652 def run(self, dataOut, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False, **kwargs):
646
653
647 if not self.isConfig:
654 if not self.isConfig:
648 self.setup(n=n, stride=stride, timeInterval=timeInterval, overlapping=overlapping, byblock=byblock, **kwargs)
655 self.setup(n=n, stride=stride, timeInterval=timeInterval, overlapping=overlapping, byblock=byblock, **kwargs)
649 self.isConfig = True
656 self.isConfig = True
650
651 if dataOut.flagDataAsBlock:
657 if dataOut.flagDataAsBlock:
652 """
658 """
653 Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis]
659 Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis]
654 """
660 """
655 avgdata, avgdatatime = self.integrateByBlock(dataOut)
661 avgdata, avgdatatime = self.integrateByBlock(dataOut)
656 dataOut.nProfiles /= self.n
662 dataOut.nProfiles /= self.n
657 else:
663 else:
658 if stride is None:
664 if stride is None:
659 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
665 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
660 else:
666 else:
661 avgdata, avgdatatime = self.integrateByStride(dataOut.data, dataOut.utctime)
667 avgdata, avgdatatime = self.integrateByStride(dataOut.data, dataOut.utctime)
662
668
663
669
664 # dataOut.timeInterval *= n
670 # dataOut.timeInterval *= n
665 dataOut.flagNoData = True
671 dataOut.flagNoData = True
666
672
667 if self.__dataReady:
673 if self.__dataReady:
668 dataOut.data = avgdata
674 dataOut.data = avgdata
669 if not dataOut.flagCohInt:
675 if not dataOut.flagCohInt:
670 dataOut.nCohInt *= self.n
676 dataOut.nCohInt *= self.n
671 dataOut.flagCohInt = True
677 dataOut.flagCohInt = True
672 dataOut.utctime = avgdatatime
678 dataOut.utctime = avgdatatime
673 # print avgdata, avgdatatime
679 # print avgdata, avgdatatime
674 # raise
680 # raise
675 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
681 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
676 dataOut.flagNoData = False
682 dataOut.flagNoData = False
677 return dataOut
683 return dataOut
678
684
679 class Decoder(Operation):
685 class Decoder(Operation):
680
686
681 isConfig = False
687 isConfig = False
682 __profIndex = 0
688 __profIndex = 0
683
689
684 code = None
690 code = None
685
691
686 nCode = None
692 nCode = None
687 nBaud = None
693 nBaud = None
688
694
689 def __init__(self, **kwargs):
695 def __init__(self, **kwargs):
690
696
691 Operation.__init__(self, **kwargs)
697 Operation.__init__(self, **kwargs)
692
698
693 self.times = None
699 self.times = None
694 self.osamp = None
700 self.osamp = None
695 # self.__setValues = False
701 # self.__setValues = False
696 self.isConfig = False
702 self.isConfig = False
697 self.setupReq = False
703 self.setupReq = False
698 def setup(self, code, osamp, dataOut):
704 def setup(self, code, osamp, dataOut):
699
705
700 self.__profIndex = 0
706 self.__profIndex = 0
701
707
702 self.code = code
708 self.code = code
703
709
704 self.nCode = len(code)
710 self.nCode = len(code)
705 self.nBaud = len(code[0])
711 self.nBaud = len(code[0])
706
712
707 if (osamp != None) and (osamp >1):
713 if (osamp != None) and (osamp >1):
708 self.osamp = osamp
714 self.osamp = osamp
709 self.code = numpy.repeat(code, repeats=self.osamp, axis=1)
715 self.code = numpy.repeat(code, repeats=self.osamp, axis=1)
710 self.nBaud = self.nBaud*self.osamp
716 self.nBaud = self.nBaud*self.osamp
711
717
712 self.__nChannels = dataOut.nChannels
718 self.__nChannels = dataOut.nChannels
713 self.__nProfiles = dataOut.nProfiles
719 self.__nProfiles = dataOut.nProfiles
714 self.__nHeis = dataOut.nHeights
720 self.__nHeis = dataOut.nHeights
715
721
716 if self.__nHeis < self.nBaud:
722 if self.__nHeis < self.nBaud:
717 raise ValueError('Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud))
723 raise ValueError('Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud))
718
724
719 #Frequency
725 #Frequency
720 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
726 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
721
727
722 __codeBuffer[:,0:self.nBaud] = self.code
728 __codeBuffer[:,0:self.nBaud] = self.code
723
729
724 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
730 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
725
731
726 if dataOut.flagDataAsBlock:
732 if dataOut.flagDataAsBlock:
727
733
728 self.ndatadec = self.__nHeis #- self.nBaud + 1
734 self.ndatadec = self.__nHeis #- self.nBaud + 1
729
735
730 self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex)
736 self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex)
731
737
732 else:
738 else:
733
739
734 #Time
740 #Time
735 self.ndatadec = self.__nHeis #- self.nBaud + 1
741 self.ndatadec = self.__nHeis #- self.nBaud + 1
736
742
737 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
743 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
738
744
739 def __convolutionInFreq(self, data):
745 def __convolutionInFreq(self, data):
740
746
741 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
747 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
742
748
743 fft_data = numpy.fft.fft(data, axis=1)
749 fft_data = numpy.fft.fft(data, axis=1)
744
750
745 conv = fft_data*fft_code
751 conv = fft_data*fft_code
746
752
747 data = numpy.fft.ifft(conv,axis=1)
753 data = numpy.fft.ifft(conv,axis=1)
748
754
749 return data
755 return data
750
756
751 def __convolutionInFreqOpt(self, data):
757 def __convolutionInFreqOpt(self, data):
752
758
753 raise NotImplementedError
759 raise NotImplementedError
754
760
755 def __convolutionInTime(self, data):
761 def __convolutionInTime(self, data):
756
762
757 code = self.code[self.__profIndex]
763 code = self.code[self.__profIndex]
758 for i in range(self.__nChannels):
764 for i in range(self.__nChannels):
759 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:]
765 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:]
760
766
761 return self.datadecTime
767 return self.datadecTime
762
768
763 def __convolutionByBlockInTime(self, data):
769 def __convolutionByBlockInTime(self, data):
764
770
765 repetitions = int(self.__nProfiles / self.nCode)
771 repetitions = int(self.__nProfiles / self.nCode)
766 junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize))
772 junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize))
767 junk = junk.flatten()
773 junk = junk.flatten()
768 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
774 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
769 profilesList = range(self.__nProfiles)
775 profilesList = range(self.__nProfiles)
770
776
771 for i in range(self.__nChannels):
777 for i in range(self.__nChannels):
772 for j in profilesList:
778 for j in profilesList:
773 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
779 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
774 return self.datadecTime
780 return self.datadecTime
775
781
776 def __convolutionByBlockInFreq(self, data):
782 def __convolutionByBlockInFreq(self, data):
777
783
778 raise NotImplementedError("Decoder by frequency fro Blocks not implemented")
784 raise NotImplementedError("Decoder by frequency fro Blocks not implemented")
779
785
780
786
781 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
787 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
782
788
783 fft_data = numpy.fft.fft(data, axis=2)
789 fft_data = numpy.fft.fft(data, axis=2)
784
790
785 conv = fft_data*fft_code
791 conv = fft_data*fft_code
786
792
787 data = numpy.fft.ifft(conv,axis=2)
793 data = numpy.fft.ifft(conv,axis=2)
788
794
789 return data
795 return data
790
796
791
797
792 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
798 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
793
799
794 if dataOut.flagDecodeData:
800 if dataOut.flagDecodeData:
795 print("This data is already decoded, recoding again ...")
801 print("This data is already decoded, recoding again ...")
796
802
797 if not self.isConfig:
803 if not self.isConfig:
798
804
799 if code is None:
805 if code is None:
800 if dataOut.code is None:
806 if dataOut.code is None:
801 raise ValueError("Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type)
807 raise ValueError("Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type)
802
808
803 code = dataOut.code
809 code = dataOut.code
804 else:
810 else:
805 code = numpy.array(code).reshape(nCode,nBaud)
811 code = numpy.array(code).reshape(nCode,nBaud)
806 self.setup(code, osamp, dataOut)
812 self.setup(code, osamp, dataOut)
807
813
808 self.isConfig = True
814 self.isConfig = True
809
815
810 if mode == 3:
816 if mode == 3:
811 sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode)
817 sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode)
812
818
813 if times != None:
819 if times != None:
814 sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n")
820 sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n")
815
821
816 if self.code is None:
822 if self.code is None:
817 print("Fail decoding: Code is not defined.")
823 print("Fail decoding: Code is not defined.")
818 return
824 return
819
825
820 self.__nProfiles = dataOut.nProfiles
826 self.__nProfiles = dataOut.nProfiles
821 datadec = None
827 datadec = None
822
828
823 if mode == 3:
829 if mode == 3:
824 mode = 0
830 mode = 0
825
831
826 if dataOut.flagDataAsBlock:
832 if dataOut.flagDataAsBlock:
827 """
833 """
828 Decoding when data have been read as block,
834 Decoding when data have been read as block,
829 """
835 """
830
836
831 if mode == 0:
837 if mode == 0:
832 datadec = self.__convolutionByBlockInTime(dataOut.data)
838 datadec = self.__convolutionByBlockInTime(dataOut.data)
833 if mode == 1:
839 if mode == 1:
834 datadec = self.__convolutionByBlockInFreq(dataOut.data)
840 datadec = self.__convolutionByBlockInFreq(dataOut.data)
835 else:
841 else:
836 """
842 """
837 Decoding when data have been read profile by profile
843 Decoding when data have been read profile by profile
838 """
844 """
839 if mode == 0:
845 if mode == 0:
840 datadec = self.__convolutionInTime(dataOut.data)
846 datadec = self.__convolutionInTime(dataOut.data)
841
847
842 if mode == 1:
848 if mode == 1:
843 datadec = self.__convolutionInFreq(dataOut.data)
849 datadec = self.__convolutionInFreq(dataOut.data)
844
850
845 if mode == 2:
851 if mode == 2:
846 datadec = self.__convolutionInFreqOpt(dataOut.data)
852 datadec = self.__convolutionInFreqOpt(dataOut.data)
847
853
848 if datadec is None:
854 if datadec is None:
849 raise ValueError("Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode)
855 raise ValueError("Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode)
850
856
851 dataOut.code = self.code
857 dataOut.code = self.code
852 dataOut.nCode = self.nCode
858 dataOut.nCode = self.nCode
853 dataOut.nBaud = self.nBaud
859 dataOut.nBaud = self.nBaud
854
860
855 dataOut.data = datadec
861 dataOut.data = datadec
856
857 dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]]
862 dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]]
858
863
859 dataOut.flagDecodeData = True #asumo q la data esta decodificada
864 dataOut.flagDecodeData = True #asumo q la data esta decodificada
860
865
861 if self.__profIndex == self.nCode-1:
866 if self.__profIndex == self.nCode-1:
862 self.__profIndex = 0
867 self.__profIndex = 0
863 return dataOut
868 return dataOut
864
869
865 self.__profIndex += 1
870 self.__profIndex += 1
866
871
867 return dataOut
872 return dataOut
868 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
869
873
870
874
871 class ProfileConcat(Operation):
875 class ProfileConcat(Operation):
872
876
873 isConfig = False
877 isConfig = False
874 buffer = None
878 buffer = None
875
879
876 def __init__(self, **kwargs):
880 def __init__(self, **kwargs):
877
881
878 Operation.__init__(self, **kwargs)
882 Operation.__init__(self, **kwargs)
879 self.profileIndex = 0
883 self.profileIndex = 0
880
884
881 def reset(self):
885 def reset(self):
882 self.buffer = numpy.zeros_like(self.buffer)
886 self.buffer = numpy.zeros_like(self.buffer)
883 self.start_index = 0
887 self.start_index = 0
884 self.times = 1
888 self.times = 1
885
889
886 def setup(self, data, m, n=1):
890 def setup(self, data, m, n=1):
887 self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0]))
891 self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0]))
888 self.nHeights = data.shape[1]#.nHeights
892 self.nHeights = data.shape[1]#.nHeights
889 self.start_index = 0
893 self.start_index = 0
890 self.times = 1
894 self.times = 1
891
895
892 def concat(self, data):
896 def concat(self, data):
893
897
894 self.buffer[:,self.start_index:self.nHeights*self.times] = data.copy()
898 self.buffer[:,self.start_index:self.nHeights*self.times] = data.copy()
895 self.start_index = self.start_index + self.nHeights
899 self.start_index = self.start_index + self.nHeights
896
900
897 def run(self, dataOut, m):
901 def run(self, dataOut, m):
898 dataOut.flagNoData = True
902 dataOut.flagNoData = True
899
903
900 if not self.isConfig:
904 if not self.isConfig:
901 self.setup(dataOut.data, m, 1)
905 self.setup(dataOut.data, m, 1)
902 self.isConfig = True
906 self.isConfig = True
903
907
904 if dataOut.flagDataAsBlock:
908 if dataOut.flagDataAsBlock:
905 raise ValueError("ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False")
909 raise ValueError("ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False")
906
910
907 else:
911 else:
908 self.concat(dataOut.data)
912 self.concat(dataOut.data)
909 self.times += 1
913 self.times += 1
910 if self.times > m:
914 if self.times > m:
911 dataOut.data = self.buffer
915 dataOut.data = self.buffer
912 self.reset()
916 self.reset()
913 dataOut.flagNoData = False
917 dataOut.flagNoData = False
914 # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas
918 # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas
915 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
919 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
916 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m
920 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m
917 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
921 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
918 dataOut.ippSeconds *= m
922 dataOut.ippSeconds *= m
919 return dataOut
923 return dataOut
920
924
921 class ProfileSelector(Operation):
925 class ProfileSelector(Operation):
922
926
923 profileIndex = None
927 profileIndex = None
924 # Tamanho total de los perfiles
928 # Tamanho total de los perfiles
925 nProfiles = None
929 nProfiles = None
926
930
927 def __init__(self, **kwargs):
931 def __init__(self, **kwargs):
928
932
929 Operation.__init__(self, **kwargs)
933 Operation.__init__(self, **kwargs)
930 self.profileIndex = 0
934 self.profileIndex = 0
931
935
932 def incProfileIndex(self):
936 def incProfileIndex(self):
933
937
934 self.profileIndex += 1
938 self.profileIndex += 1
935
939
936 if self.profileIndex >= self.nProfiles:
940 if self.profileIndex >= self.nProfiles:
937 self.profileIndex = 0
941 self.profileIndex = 0
938
942
939 def isThisProfileInRange(self, profileIndex, minIndex, maxIndex):
943 def isThisProfileInRange(self, profileIndex, minIndex, maxIndex):
940
944
941 if profileIndex < minIndex:
945 if profileIndex < minIndex:
942 return False
946 return False
943
947
944 if profileIndex > maxIndex:
948 if profileIndex > maxIndex:
945 return False
949 return False
946
950
947 return True
951 return True
948
952
949 def isThisProfileInList(self, profileIndex, profileList):
953 def isThisProfileInList(self, profileIndex, profileList):
950
954
951 if profileIndex not in profileList:
955 if profileIndex not in profileList:
952 return False
956 return False
953
957
954 return True
958 return True
955
959
956 def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None):
960 def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None):
957
961
958 """
962 """
959 ProfileSelector:
963 ProfileSelector:
960
964
961 Inputs:
965 Inputs:
962 profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8)
966 profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8)
963
967
964 profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30)
968 profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30)
965
969
966 rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256))
970 rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256))
967
971
968 """
972 """
969
973
970 if rangeList is not None:
974 if rangeList is not None:
971 if type(rangeList[0]) not in (tuple, list):
975 if type(rangeList[0]) not in (tuple, list):
972 rangeList = [rangeList]
976 rangeList = [rangeList]
973
977
974 dataOut.flagNoData = True
978 dataOut.flagNoData = True
975
979
976 if dataOut.flagDataAsBlock:
980 if dataOut.flagDataAsBlock:
977 """
981 """
978 data dimension = [nChannels, nProfiles, nHeis]
982 data dimension = [nChannels, nProfiles, nHeis]
979 """
983 """
980 if profileList != None:
984 if profileList != None:
981 dataOut.data = dataOut.data[:,profileList,:]
985 dataOut.data = dataOut.data[:,profileList,:]
982
986
983 if profileRangeList != None:
987 if profileRangeList != None:
984 minIndex = profileRangeList[0]
988 minIndex = profileRangeList[0]
985 maxIndex = profileRangeList[1]
989 maxIndex = profileRangeList[1]
986 profileList = list(range(minIndex, maxIndex+1))
990 profileList = list(range(minIndex, maxIndex+1))
987
991
988 dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:]
992 dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:]
989
993
990 if rangeList != None:
994 if rangeList != None:
991
995
992 profileList = []
996 profileList = []
993
997
994 for thisRange in rangeList:
998 for thisRange in rangeList:
995 minIndex = thisRange[0]
999 minIndex = thisRange[0]
996 maxIndex = thisRange[1]
1000 maxIndex = thisRange[1]
997
1001
998 profileList.extend(list(range(minIndex, maxIndex+1)))
1002 profileList.extend(list(range(minIndex, maxIndex+1)))
999
1003
1000 dataOut.data = dataOut.data[:,profileList,:]
1004 dataOut.data = dataOut.data[:,profileList,:]
1001
1005
1002 dataOut.nProfiles = len(profileList)
1006 dataOut.nProfiles = len(profileList)
1003 dataOut.profileIndex = dataOut.nProfiles - 1
1007 dataOut.profileIndex = dataOut.nProfiles - 1
1004 dataOut.flagNoData = False
1008 dataOut.flagNoData = False
1005
1009
1006 return dataOut
1010 return dataOut
1007
1011
1008 """
1012 """
1009 data dimension = [nChannels, nHeis]
1013 data dimension = [nChannels, nHeis]
1010 """
1014 """
1011
1015
1012 if profileList != None:
1016 if profileList != None:
1013
1017
1014 if self.isThisProfileInList(dataOut.profileIndex, profileList):
1018 if self.isThisProfileInList(dataOut.profileIndex, profileList):
1015
1019
1016 self.nProfiles = len(profileList)
1020 self.nProfiles = len(profileList)
1017 dataOut.nProfiles = self.nProfiles
1021 dataOut.nProfiles = self.nProfiles
1018 dataOut.profileIndex = self.profileIndex
1022 dataOut.profileIndex = self.profileIndex
1019 dataOut.flagNoData = False
1023 dataOut.flagNoData = False
1020
1024
1021 self.incProfileIndex()
1025 self.incProfileIndex()
1022 return dataOut
1026 return dataOut
1023
1027
1024 if profileRangeList != None:
1028 if profileRangeList != None:
1025
1029
1026 minIndex = profileRangeList[0]
1030 minIndex = profileRangeList[0]
1027 maxIndex = profileRangeList[1]
1031 maxIndex = profileRangeList[1]
1028
1032
1029 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1033 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1030
1034
1031 self.nProfiles = maxIndex - minIndex + 1
1035 self.nProfiles = maxIndex - minIndex + 1
1032 dataOut.nProfiles = self.nProfiles
1036 dataOut.nProfiles = self.nProfiles
1033 dataOut.profileIndex = self.profileIndex
1037 dataOut.profileIndex = self.profileIndex
1034 dataOut.flagNoData = False
1038 dataOut.flagNoData = False
1035
1039
1036 self.incProfileIndex()
1040 self.incProfileIndex()
1037 return dataOut
1041 return dataOut
1038
1042
1039 if rangeList != None:
1043 if rangeList != None:
1040
1044
1041 nProfiles = 0
1045 nProfiles = 0
1042
1046
1043 for thisRange in rangeList:
1047 for thisRange in rangeList:
1044 minIndex = thisRange[0]
1048 minIndex = thisRange[0]
1045 maxIndex = thisRange[1]
1049 maxIndex = thisRange[1]
1046
1050
1047 nProfiles += maxIndex - minIndex + 1
1051 nProfiles += maxIndex - minIndex + 1
1048
1052
1049 for thisRange in rangeList:
1053 for thisRange in rangeList:
1050
1054
1051 minIndex = thisRange[0]
1055 minIndex = thisRange[0]
1052 maxIndex = thisRange[1]
1056 maxIndex = thisRange[1]
1053
1057
1054 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1058 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1055
1059
1056 self.nProfiles = nProfiles
1060 self.nProfiles = nProfiles
1057 dataOut.nProfiles = self.nProfiles
1061 dataOut.nProfiles = self.nProfiles
1058 dataOut.profileIndex = self.profileIndex
1062 dataOut.profileIndex = self.profileIndex
1059 dataOut.flagNoData = False
1063 dataOut.flagNoData = False
1060
1064
1061 self.incProfileIndex()
1065 self.incProfileIndex()
1062
1066
1063 break
1067 break
1064
1068
1065 return dataOut
1069 return dataOut
1066
1070
1067
1071
1068 if beam != None: #beam is only for AMISR data
1072 if beam != None: #beam is only for AMISR data
1069 if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]):
1073 if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]):
1070 dataOut.flagNoData = False
1074 dataOut.flagNoData = False
1071 dataOut.profileIndex = self.profileIndex
1075 dataOut.profileIndex = self.profileIndex
1072
1076
1073 self.incProfileIndex()
1077 self.incProfileIndex()
1074
1078
1075 return dataOut
1079 return dataOut
1076
1080
1077 raise ValueError("ProfileSelector needs profileList, profileRangeList or rangeList parameter")
1081 raise ValueError("ProfileSelector needs profileList, profileRangeList or rangeList parameter")
1078
1082
1079
1083
1080 class Reshaper(Operation):
1084 class Reshaper(Operation):
1081
1085
1082 def __init__(self, **kwargs):
1086 def __init__(self, **kwargs):
1083
1087
1084 Operation.__init__(self, **kwargs)
1088 Operation.__init__(self, **kwargs)
1085
1089
1086 self.__buffer = None
1090 self.__buffer = None
1087 self.__nitems = 0
1091 self.__nitems = 0
1088
1092
1089 def __appendProfile(self, dataOut, nTxs):
1093 def __appendProfile(self, dataOut, nTxs):
1090
1094
1091 if self.__buffer is None:
1095 if self.__buffer is None:
1092 shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) )
1096 shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) )
1093 self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype)
1097 self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype)
1094
1098
1095 ini = dataOut.nHeights * self.__nitems
1099 ini = dataOut.nHeights * self.__nitems
1096 end = ini + dataOut.nHeights
1100 end = ini + dataOut.nHeights
1097
1101
1098 self.__buffer[:, ini:end] = dataOut.data
1102 self.__buffer[:, ini:end] = dataOut.data
1099
1103
1100 self.__nitems += 1
1104 self.__nitems += 1
1101
1105
1102 return int(self.__nitems*nTxs)
1106 return int(self.__nitems*nTxs)
1103
1107
1104 def __getBuffer(self):
1108 def __getBuffer(self):
1105
1109
1106 if self.__nitems == int(1./self.__nTxs):
1110 if self.__nitems == int(1./self.__nTxs):
1107
1111
1108 self.__nitems = 0
1112 self.__nitems = 0
1109
1113
1110 return self.__buffer.copy()
1114 return self.__buffer.copy()
1111
1115
1112 return None
1116 return None
1113
1117
1114 def __checkInputs(self, dataOut, shape, nTxs):
1118 def __checkInputs(self, dataOut, shape, nTxs):
1115
1119
1116 if shape is None and nTxs is None:
1120 if shape is None and nTxs is None:
1117 raise ValueError("Reshaper: shape of factor should be defined")
1121 raise ValueError("Reshaper: shape of factor should be defined")
1118
1122
1119 if nTxs:
1123 if nTxs:
1120 if nTxs < 0:
1124 if nTxs < 0:
1121 raise ValueError("nTxs should be greater than 0")
1125 raise ValueError("nTxs should be greater than 0")
1122
1126
1123 if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0:
1127 if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0:
1124 raise ValueError("nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs)))
1128 raise ValueError("nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs)))
1125
1129
1126 shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs]
1130 shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs]
1127
1131
1128 return shape, nTxs
1132 return shape, nTxs
1129
1133
1130 if len(shape) != 2 and len(shape) != 3:
1134 if len(shape) != 2 and len(shape) != 3:
1131 raise ValueError("shape dimension should be equal to 2 or 3. shape = (nProfiles, nHeis) or (nChannels, nProfiles, nHeis). Actually shape = (%d, %d, %d)" %(dataOut.nChannels, dataOut.nProfiles, dataOut.nHeights))
1135 raise ValueError("shape dimension should be equal to 2 or 3. shape = (nProfiles, nHeis) or (nChannels, nProfiles, nHeis). Actually shape = (%d, %d, %d)" %(dataOut.nChannels, dataOut.nProfiles, dataOut.nHeights))
1132
1136
1133 if len(shape) == 2:
1137 if len(shape) == 2:
1134 shape_tuple = [dataOut.nChannels]
1138 shape_tuple = [dataOut.nChannels]
1135 shape_tuple.extend(shape)
1139 shape_tuple.extend(shape)
1136 else:
1140 else:
1137 shape_tuple = list(shape)
1141 shape_tuple = list(shape)
1138
1142
1139 nTxs = 1.0*shape_tuple[1]/dataOut.nProfiles
1143 nTxs = 1.0*shape_tuple[1]/dataOut.nProfiles
1140
1144
1141 return shape_tuple, nTxs
1145 return shape_tuple, nTxs
1142
1146
1143 def run(self, dataOut, shape=None, nTxs=None):
1147 def run(self, dataOut, shape=None, nTxs=None):
1144
1148
1145 shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs)
1149 shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs)
1146
1150
1147 dataOut.flagNoData = True
1151 dataOut.flagNoData = True
1148 profileIndex = None
1152 profileIndex = None
1149
1153
1150 if dataOut.flagDataAsBlock:
1154 if dataOut.flagDataAsBlock:
1151
1155
1152 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
1156 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
1153 dataOut.flagNoData = False
1157 dataOut.flagNoData = False
1154
1158
1155 profileIndex = int(dataOut.nProfiles*self.__nTxs) - 1
1159 profileIndex = int(dataOut.nProfiles*self.__nTxs) - 1
1156
1160
1157 else:
1161 else:
1158
1162
1159 if self.__nTxs < 1:
1163 if self.__nTxs < 1:
1160
1164
1161 self.__appendProfile(dataOut, self.__nTxs)
1165 self.__appendProfile(dataOut, self.__nTxs)
1162 new_data = self.__getBuffer()
1166 new_data = self.__getBuffer()
1163
1167
1164 if new_data is not None:
1168 if new_data is not None:
1165 dataOut.data = new_data
1169 dataOut.data = new_data
1166 dataOut.flagNoData = False
1170 dataOut.flagNoData = False
1167
1171
1168 profileIndex = dataOut.profileIndex*nTxs
1172 profileIndex = dataOut.profileIndex*nTxs
1169
1173
1170 else:
1174 else:
1171 raise ValueError("nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)")
1175 raise ValueError("nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)")
1172
1176
1173 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1177 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1174
1178
1175 dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0]
1179 dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0]
1176
1180
1177 dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs)
1181 dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs)
1178
1182
1179 dataOut.profileIndex = profileIndex
1183 dataOut.profileIndex = profileIndex
1180
1184
1181 dataOut.ippSeconds /= self.__nTxs
1185 dataOut.ippSeconds /= self.__nTxs
1182
1186
1183 return dataOut
1187 return dataOut
1184
1188
1185 class SplitProfiles(Operation):
1189 class SplitProfiles(Operation):
1186
1190
1187 def __init__(self, **kwargs):
1191 def __init__(self, **kwargs):
1188
1192
1189 Operation.__init__(self, **kwargs)
1193 Operation.__init__(self, **kwargs)
1190
1194
1191 def run(self, dataOut, n):
1195 def run(self, dataOut, n):
1192
1196
1193 dataOut.flagNoData = True
1197 dataOut.flagNoData = True
1194 profileIndex = None
1198 profileIndex = None
1195
1199
1196 if dataOut.flagDataAsBlock:
1200 if dataOut.flagDataAsBlock:
1197
1201
1198 #nchannels, nprofiles, nsamples
1202 #nchannels, nprofiles, nsamples
1199 shape = dataOut.data.shape
1203 shape = dataOut.data.shape
1200
1204
1201 if shape[2] % n != 0:
1205 if shape[2] % n != 0:
1202 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[2]))
1206 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[2]))
1203
1207
1204 new_shape = shape[0], shape[1]*n, int(shape[2]/n)
1208 new_shape = shape[0], shape[1]*n, int(shape[2]/n)
1205
1209
1206 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1210 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1207 dataOut.flagNoData = False
1211 dataOut.flagNoData = False
1208
1212
1209 profileIndex = int(dataOut.nProfiles/n) - 1
1213 profileIndex = int(dataOut.nProfiles/n) - 1
1210
1214
1211 else:
1215 else:
1212
1216
1213 raise ValueError("Could not split the data when is read Profile by Profile. Use VoltageReader(..., getblock=True)")
1217 raise ValueError("Could not split the data when is read Profile by Profile. Use VoltageReader(..., getblock=True)")
1214
1218
1215 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1219 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1216
1220
1217 dataOut.heightList = numpy.arange(dataOut.nHeights/n) * deltaHeight + dataOut.heightList[0]
1221 dataOut.heightList = numpy.arange(dataOut.nHeights/n) * deltaHeight + dataOut.heightList[0]
1218
1222
1219 dataOut.nProfiles = int(dataOut.nProfiles*n)
1223 dataOut.nProfiles = int(dataOut.nProfiles*n)
1220
1224
1221 dataOut.profileIndex = profileIndex
1225 dataOut.profileIndex = profileIndex
1222
1226
1223 dataOut.ippSeconds /= n
1227 dataOut.ippSeconds /= n
1224
1228
1225 return dataOut
1229 return dataOut
1226
1230
1227 class CombineProfiles(Operation):
1231 class CombineProfiles(Operation):
1228 def __init__(self, **kwargs):
1232 def __init__(self, **kwargs):
1229
1233
1230 Operation.__init__(self, **kwargs)
1234 Operation.__init__(self, **kwargs)
1231
1235
1232 self.__remData = None
1236 self.__remData = None
1233 self.__profileIndex = 0
1237 self.__profileIndex = 0
1234
1238
1235 def run(self, dataOut, n):
1239 def run(self, dataOut, n):
1236
1240
1237 dataOut.flagNoData = True
1241 dataOut.flagNoData = True
1238 profileIndex = None
1242 profileIndex = None
1239
1243
1240 if dataOut.flagDataAsBlock:
1244 if dataOut.flagDataAsBlock:
1241
1245
1242 #nchannels, nprofiles, nsamples
1246 #nchannels, nprofiles, nsamples
1243 shape = dataOut.data.shape
1247 shape = dataOut.data.shape
1244 new_shape = shape[0], shape[1]/n, shape[2]*n
1248 new_shape = shape[0], shape[1]/n, shape[2]*n
1245
1249
1246 if shape[1] % n != 0:
1250 if shape[1] % n != 0:
1247 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[1]))
1251 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[1]))
1248
1252
1249 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1253 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1250 dataOut.flagNoData = False
1254 dataOut.flagNoData = False
1251
1255
1252 profileIndex = int(dataOut.nProfiles*n) - 1
1256 profileIndex = int(dataOut.nProfiles*n) - 1
1253
1257
1254 else:
1258 else:
1255
1259
1256 #nchannels, nsamples
1260 #nchannels, nsamples
1257 if self.__remData is None:
1261 if self.__remData is None:
1258 newData = dataOut.data
1262 newData = dataOut.data
1259 else:
1263 else:
1260 newData = numpy.concatenate((self.__remData, dataOut.data), axis=1)
1264 newData = numpy.concatenate((self.__remData, dataOut.data), axis=1)
1261
1265
1262 self.__profileIndex += 1
1266 self.__profileIndex += 1
1263
1267
1264 if self.__profileIndex < n:
1268 if self.__profileIndex < n:
1265 self.__remData = newData
1269 self.__remData = newData
1266 #continue
1270 #continue
1267 return
1271 return
1268
1272
1269 self.__profileIndex = 0
1273 self.__profileIndex = 0
1270 self.__remData = None
1274 self.__remData = None
1271
1275
1272 dataOut.data = newData
1276 dataOut.data = newData
1273 dataOut.flagNoData = False
1277 dataOut.flagNoData = False
1274
1278
1275 profileIndex = dataOut.profileIndex/n
1279 profileIndex = dataOut.profileIndex/n
1276
1280
1277
1281
1278 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1282 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1279
1283
1280 dataOut.heightList = numpy.arange(dataOut.nHeights*n) * deltaHeight + dataOut.heightList[0]
1284 dataOut.heightList = numpy.arange(dataOut.nHeights*n) * deltaHeight + dataOut.heightList[0]
1281
1285
1282 dataOut.nProfiles = int(dataOut.nProfiles/n)
1286 dataOut.nProfiles = int(dataOut.nProfiles/n)
1283
1287
1284 dataOut.profileIndex = profileIndex
1288 dataOut.profileIndex = profileIndex
1285
1289
1286 dataOut.ippSeconds *= n
1290 dataOut.ippSeconds *= n
1287
1291
1288 return dataOut
1292 return dataOut
1289
1293
1290 class PulsePairVoltage(Operation):
1294 class PulsePairVoltage(Operation):
1291 '''
1295 '''
1292 Function PulsePair(Signal Power, Velocity)
1296 Function PulsePair(Signal Power, Velocity)
1293 The real component of Lag[0] provides Intensity Information
1297 The real component of Lag[0] provides Intensity Information
1294 The imag component of Lag[1] Phase provides Velocity Information
1298 The imag component of Lag[1] Phase provides Velocity Information
1295
1299
1296 Configuration Parameters:
1300 Configuration Parameters:
1297 nPRF = Number of Several PRF
1301 nPRF = Number of Several PRF
1298 theta = Degree Azimuth angel Boundaries
1302 theta = Degree Azimuth angel Boundaries
1299
1303
1300 Input:
1304 Input:
1301 self.dataOut
1305 self.dataOut
1302 lag[N]
1306 lag[N]
1303 Affected:
1307 Affected:
1304 self.dataOut.spc
1308 self.dataOut.spc
1305 '''
1309 '''
1306 isConfig = False
1310 isConfig = False
1307 __profIndex = 0
1311 __profIndex = 0
1308 __initime = None
1312 __initime = None
1309 __lastdatatime = None
1313 __lastdatatime = None
1310 __buffer = None
1314 __buffer = None
1311 noise = None
1315 noise = None
1312 __dataReady = False
1316 __dataReady = False
1313 n = None
1317 n = None
1314 __nch = 0
1318 __nch = 0
1315 __nHeis = 0
1319 __nHeis = 0
1316 removeDC = False
1320 removeDC = False
1317 ipp = None
1321 ipp = None
1318 lambda_ = 0
1322 lambda_ = 0
1319
1323
1320 def __init__(self,**kwargs):
1324 def __init__(self,**kwargs):
1321 Operation.__init__(self,**kwargs)
1325 Operation.__init__(self,**kwargs)
1322
1326
1323 def setup(self, dataOut, n = None, removeDC=False):
1327 def setup(self, dataOut, n = None, removeDC=False):
1324 '''
1328 '''
1325 n= Numero de PRF's de entrada
1329 n= Numero de PRF's de entrada
1326 '''
1330 '''
1327 self.__initime = None
1331 self.__initime = None
1328 self.__lastdatatime = 0
1332 self.__lastdatatime = 0
1329 self.__dataReady = False
1333 self.__dataReady = False
1330 self.__buffer = 0
1334 self.__buffer = 0
1331 self.__profIndex = 0
1335 self.__profIndex = 0
1332 self.noise = None
1336 self.noise = None
1333 self.__nch = dataOut.nChannels
1337 self.__nch = dataOut.nChannels
1334 self.__nHeis = dataOut.nHeights
1338 self.__nHeis = dataOut.nHeights
1335 self.removeDC = removeDC
1339 self.removeDC = removeDC
1336 self.lambda_ = 3.0e8/(9345.0e6)
1340 self.lambda_ = 3.0e8/(9345.0e6)
1337 self.ippSec = dataOut.ippSeconds
1341 self.ippSec = dataOut.ippSeconds
1338 self.nCohInt = dataOut.nCohInt
1342 self.nCohInt = dataOut.nCohInt
1339 print("IPPseconds",dataOut.ippSeconds)
1343 print("IPPseconds",dataOut.ippSeconds)
1340
1344
1341 print("ELVALOR DE n es:", n)
1345 print("ELVALOR DE n es:", n)
1342 if n == None:
1346 if n == None:
1343 raise ValueError("n should be specified.")
1347 raise ValueError("n should be specified.")
1344
1348
1345 if n != None:
1349 if n != None:
1346 if n<2:
1350 if n<2:
1347 raise ValueError("n should be greater than 2")
1351 raise ValueError("n should be greater than 2")
1348
1352
1349 self.n = n
1353 self.n = n
1350 self.__nProf = n
1354 self.__nProf = n
1351
1355
1352 self.__buffer = numpy.zeros((dataOut.nChannels,
1356 self.__buffer = numpy.zeros((dataOut.nChannels,
1353 n,
1357 n,
1354 dataOut.nHeights),
1358 dataOut.nHeights),
1355 dtype='complex')
1359 dtype='complex')
1356
1360
1357 def putData(self,data):
1361 def putData(self,data):
1358 '''
1362 '''
1359 Add a profile to he __buffer and increase in one the __profiel Index
1363 Add a profile to he __buffer and increase in one the __profiel Index
1360 '''
1364 '''
1361 self.__buffer[:,self.__profIndex,:]= data
1365 self.__buffer[:,self.__profIndex,:]= data
1362 self.__profIndex += 1
1366 self.__profIndex += 1
1363 return
1367 return
1364
1368
1365 def pushData(self,dataOut):
1369 def pushData(self,dataOut):
1366 '''
1370 '''
1367 Return the PULSEPAIR and the profiles used in the operation
1371 Return the PULSEPAIR and the profiles used in the operation
1368 Affected : self.__profileIndex
1372 Affected : self.__profileIndex
1369 '''
1373 '''
1370 #----------------- Remove DC-----------------------------------
1374 #----------------- Remove DC-----------------------------------
1371 if self.removeDC==True:
1375 if self.removeDC==True:
1372 mean = numpy.mean(self.__buffer,1)
1376 mean = numpy.mean(self.__buffer,1)
1373 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1377 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1374 dc= numpy.tile(tmp,[1,self.__nProf,1])
1378 dc= numpy.tile(tmp,[1,self.__nProf,1])
1375 self.__buffer = self.__buffer - dc
1379 self.__buffer = self.__buffer - dc
1376 #------------------Calculo de Potencia ------------------------
1380 #------------------Calculo de Potencia ------------------------
1377 pair0 = self.__buffer*numpy.conj(self.__buffer)
1381 pair0 = self.__buffer*numpy.conj(self.__buffer)
1378 pair0 = pair0.real
1382 pair0 = pair0.real
1379 lag_0 = numpy.sum(pair0,1)
1383 lag_0 = numpy.sum(pair0,1)
1380 #------------------Calculo de Ruido x canal--------------------
1384 #------------------Calculo de Ruido x canal--------------------
1381 self.noise = numpy.zeros(self.__nch)
1385 self.noise = numpy.zeros(self.__nch)
1382 for i in range(self.__nch):
1386 for i in range(self.__nch):
1383 daux = numpy.sort(pair0[i,:,:],axis= None)
1387 daux = numpy.sort(pair0[i,:,:],axis= None)
1384 self.noise[i]=hildebrand_sekhon( daux ,self.nCohInt)
1388 self.noise[i]=hildebrand_sekhon( daux ,self.nCohInt)
1385
1389
1386 self.noise = self.noise.reshape(self.__nch,1)
1390 self.noise = self.noise.reshape(self.__nch,1)
1387 self.noise = numpy.tile(self.noise,[1,self.__nHeis])
1391 self.noise = numpy.tile(self.noise,[1,self.__nHeis])
1388 noise_buffer = self.noise.reshape(self.__nch,1,self.__nHeis)
1392 noise_buffer = self.noise.reshape(self.__nch,1,self.__nHeis)
1389 noise_buffer = numpy.tile(noise_buffer,[1,self.__nProf,1])
1393 noise_buffer = numpy.tile(noise_buffer,[1,self.__nProf,1])
1390 #------------------ Potencia recibida= P , Potencia senal = S , Ruido= N--
1394 #------------------ Potencia recibida= P , Potencia senal = S , Ruido= N--
1391 #------------------ P= S+N ,P=lag_0/N ---------------------------------
1395 #------------------ P= S+N ,P=lag_0/N ---------------------------------
1392 #-------------------- Power --------------------------------------------------
1396 #-------------------- Power --------------------------------------------------
1393 data_power = lag_0/(self.n*self.nCohInt)
1397 data_power = lag_0/(self.n*self.nCohInt)
1394 #------------------ Senal ---------------------------------------------------
1398 #------------------ Senal ---------------------------------------------------
1395 data_intensity = pair0 - noise_buffer
1399 data_intensity = pair0 - noise_buffer
1396 data_intensity = numpy.sum(data_intensity,axis=1)*(self.n*self.nCohInt)#*self.nCohInt)
1400 data_intensity = numpy.sum(data_intensity,axis=1)*(self.n*self.nCohInt)#*self.nCohInt)
1397 #data_intensity = (lag_0-self.noise*self.n)*(self.n*self.nCohInt)
1401 #data_intensity = (lag_0-self.noise*self.n)*(self.n*self.nCohInt)
1398 for i in range(self.__nch):
1402 for i in range(self.__nch):
1399 for j in range(self.__nHeis):
1403 for j in range(self.__nHeis):
1400 if data_intensity[i][j] < 0:
1404 if data_intensity[i][j] < 0:
1401 data_intensity[i][j] = numpy.min(numpy.absolute(data_intensity[i][j]))
1405 data_intensity[i][j] = numpy.min(numpy.absolute(data_intensity[i][j]))
1402
1406
1403 #----------------- Calculo de Frecuencia y Velocidad doppler--------
1407 #----------------- Calculo de Frecuencia y Velocidad doppler--------
1404 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1408 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1405 lag_1 = numpy.sum(pair1,1)
1409 lag_1 = numpy.sum(pair1,1)
1406 data_freq = (-1/(2.0*math.pi*self.ippSec*self.nCohInt))*numpy.angle(lag_1)
1410 data_freq = (-1/(2.0*math.pi*self.ippSec*self.nCohInt))*numpy.angle(lag_1)
1407 data_velocity = (self.lambda_/2.0)*data_freq
1411 data_velocity = (self.lambda_/2.0)*data_freq
1408
1412
1409 #---------------- Potencia promedio estimada de la Senal-----------
1413 #---------------- Potencia promedio estimada de la Senal-----------
1410 lag_0 = lag_0/self.n
1414 lag_0 = lag_0/self.n
1411 S = lag_0-self.noise
1415 S = lag_0-self.noise
1412
1416
1413 #---------------- Frecuencia Doppler promedio ---------------------
1417 #---------------- Frecuencia Doppler promedio ---------------------
1414 lag_1 = lag_1/(self.n-1)
1418 lag_1 = lag_1/(self.n-1)
1415 R1 = numpy.abs(lag_1)
1419 R1 = numpy.abs(lag_1)
1416
1420
1417 #---------------- Calculo del SNR----------------------------------
1421 #---------------- Calculo del SNR----------------------------------
1418 data_snrPP = S/self.noise
1422 data_snrPP = S/self.noise
1419 for i in range(self.__nch):
1423 for i in range(self.__nch):
1420 for j in range(self.__nHeis):
1424 for j in range(self.__nHeis):
1421 if data_snrPP[i][j] < 1.e-20:
1425 if data_snrPP[i][j] < 1.e-20:
1422 data_snrPP[i][j] = 1.e-20
1426 data_snrPP[i][j] = 1.e-20
1423
1427
1424 #----------------- Calculo del ancho espectral ----------------------
1428 #----------------- Calculo del ancho espectral ----------------------
1425 L = S/R1
1429 L = S/R1
1426 L = numpy.where(L<0,1,L)
1430 L = numpy.where(L<0,1,L)
1427 L = numpy.log(L)
1431 L = numpy.log(L)
1428 tmp = numpy.sqrt(numpy.absolute(L))
1432 tmp = numpy.sqrt(numpy.absolute(L))
1429 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec*self.nCohInt))*tmp*numpy.sign(L)
1433 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec*self.nCohInt))*tmp*numpy.sign(L)
1430 n = self.__profIndex
1434 n = self.__profIndex
1431
1435
1432 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1436 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1433 self.__profIndex = 0
1437 self.__profIndex = 0
1434 return data_power,data_intensity,data_velocity,data_snrPP,data_specwidth,n
1438 return data_power,data_intensity,data_velocity,data_snrPP,data_specwidth,n
1435
1439
1436
1440
1437 def pulsePairbyProfiles(self,dataOut):
1441 def pulsePairbyProfiles(self,dataOut):
1438
1442
1439 self.__dataReady = False
1443 self.__dataReady = False
1440 data_power = None
1444 data_power = None
1441 data_intensity = None
1445 data_intensity = None
1442 data_velocity = None
1446 data_velocity = None
1443 data_specwidth = None
1447 data_specwidth = None
1444 data_snrPP = None
1448 data_snrPP = None
1445 self.putData(data=dataOut.data)
1449 self.putData(data=dataOut.data)
1446 if self.__profIndex == self.n:
1450 if self.__profIndex == self.n:
1447 data_power,data_intensity, data_velocity,data_snrPP,data_specwidth, n = self.pushData(dataOut=dataOut)
1451 data_power,data_intensity, data_velocity,data_snrPP,data_specwidth, n = self.pushData(dataOut=dataOut)
1448 self.__dataReady = True
1452 self.__dataReady = True
1449
1453
1450 return data_power, data_intensity, data_velocity, data_snrPP, data_specwidth
1454 return data_power, data_intensity, data_velocity, data_snrPP, data_specwidth
1451
1455
1452
1456
1453 def pulsePairOp(self, dataOut, datatime= None):
1457 def pulsePairOp(self, dataOut, datatime= None):
1454
1458
1455 if self.__initime == None:
1459 if self.__initime == None:
1456 self.__initime = datatime
1460 self.__initime = datatime
1457 data_power, data_intensity, data_velocity, data_snrPP, data_specwidth = self.pulsePairbyProfiles(dataOut)
1461 data_power, data_intensity, data_velocity, data_snrPP, data_specwidth = self.pulsePairbyProfiles(dataOut)
1458 self.__lastdatatime = datatime
1462 self.__lastdatatime = datatime
1459
1463
1460 if data_power is None:
1464 if data_power is None:
1461 return None, None, None,None,None,None
1465 return None, None, None,None,None,None
1462
1466
1463 avgdatatime = self.__initime
1467 avgdatatime = self.__initime
1464 deltatime = datatime - self.__lastdatatime
1468 deltatime = datatime - self.__lastdatatime
1465 self.__initime = datatime
1469 self.__initime = datatime
1466
1470
1467 return data_power, data_intensity, data_velocity, data_snrPP, data_specwidth, avgdatatime
1471 return data_power, data_intensity, data_velocity, data_snrPP, data_specwidth, avgdatatime
1468
1472
1469 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1473 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1470
1474
1471 if not self.isConfig:
1475 if not self.isConfig:
1472 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1476 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1473 self.isConfig = True
1477 self.isConfig = True
1474 data_power, data_intensity, data_velocity,data_snrPP,data_specwidth, avgdatatime = self.pulsePairOp(dataOut, dataOut.utctime)
1478 data_power, data_intensity, data_velocity,data_snrPP,data_specwidth, avgdatatime = self.pulsePairOp(dataOut, dataOut.utctime)
1475 dataOut.flagNoData = True
1479 dataOut.flagNoData = True
1476
1480
1477 if self.__dataReady:
1481 if self.__dataReady:
1478 dataOut.nCohInt *= self.n
1482 dataOut.nCohInt *= self.n
1479 dataOut.dataPP_POW = data_intensity # S
1483 dataOut.dataPP_POW = data_intensity # S
1480 dataOut.dataPP_POWER = data_power # P
1484 dataOut.dataPP_POWER = data_power # P
1481 dataOut.dataPP_DOP = data_velocity
1485 dataOut.dataPP_DOP = data_velocity
1482 dataOut.dataPP_SNR = data_snrPP
1486 dataOut.dataPP_SNR = data_snrPP
1483 dataOut.dataPP_WIDTH = data_specwidth
1487 dataOut.dataPP_WIDTH = data_specwidth
1484 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1488 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1485 dataOut.utctime = avgdatatime
1489 dataOut.utctime = avgdatatime
1486 dataOut.flagNoData = False
1490 dataOut.flagNoData = False
1487 return dataOut
1491 return dataOut
1488
1492
1489
1493
1490
1494
1491 # import collections
1495 # import collections
1492 # from scipy.stats import mode
1496 # from scipy.stats import mode
1493 #
1497 #
1494 # class Synchronize(Operation):
1498 # class Synchronize(Operation):
1495 #
1499 #
1496 # isConfig = False
1500 # isConfig = False
1497 # __profIndex = 0
1501 # __profIndex = 0
1498 #
1502 #
1499 # def __init__(self, **kwargs):
1503 # def __init__(self, **kwargs):
1500 #
1504 #
1501 # Operation.__init__(self, **kwargs)
1505 # Operation.__init__(self, **kwargs)
1502 # # self.isConfig = False
1506 # # self.isConfig = False
1503 # self.__powBuffer = None
1507 # self.__powBuffer = None
1504 # self.__startIndex = 0
1508 # self.__startIndex = 0
1505 # self.__pulseFound = False
1509 # self.__pulseFound = False
1506 #
1510 #
1507 # def __findTxPulse(self, dataOut, channel=0, pulse_with = None):
1511 # def __findTxPulse(self, dataOut, channel=0, pulse_with = None):
1508 #
1512 #
1509 # #Read data
1513 # #Read data
1510 #
1514 #
1511 # powerdB = dataOut.getPower(channel = channel)
1515 # powerdB = dataOut.getPower(channel = channel)
1512 # noisedB = dataOut.getNoise(channel = channel)[0]
1516 # noisedB = dataOut.getNoise(channel = channel)[0]
1513 #
1517 #
1514 # self.__powBuffer.extend(powerdB.flatten())
1518 # self.__powBuffer.extend(powerdB.flatten())
1515 #
1519 #
1516 # dataArray = numpy.array(self.__powBuffer)
1520 # dataArray = numpy.array(self.__powBuffer)
1517 #
1521 #
1518 # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same")
1522 # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same")
1519 #
1523 #
1520 # maxValue = numpy.nanmax(filteredPower)
1524 # maxValue = numpy.nanmax(filteredPower)
1521 #
1525 #
1522 # if maxValue < noisedB + 10:
1526 # if maxValue < noisedB + 10:
1523 # #No se encuentra ningun pulso de transmision
1527 # #No se encuentra ningun pulso de transmision
1524 # return None
1528 # return None
1525 #
1529 #
1526 # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0]
1530 # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0]
1527 #
1531 #
1528 # if len(maxValuesIndex) < 2:
1532 # if len(maxValuesIndex) < 2:
1529 # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX
1533 # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX
1530 # return None
1534 # return None
1531 #
1535 #
1532 # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples
1536 # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples
1533 #
1537 #
1534 # #Seleccionar solo valores con un espaciamiento de nSamples
1538 # #Seleccionar solo valores con un espaciamiento de nSamples
1535 # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex)
1539 # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex)
1536 #
1540 #
1537 # if len(pulseIndex) < 2:
1541 # if len(pulseIndex) < 2:
1538 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1542 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1539 # return None
1543 # return None
1540 #
1544 #
1541 # spacing = pulseIndex[1:] - pulseIndex[:-1]
1545 # spacing = pulseIndex[1:] - pulseIndex[:-1]
1542 #
1546 #
1543 # #remover senales que se distancien menos de 10 unidades o muestras
1547 # #remover senales que se distancien menos de 10 unidades o muestras
1544 # #(No deberian existir IPP menor a 10 unidades)
1548 # #(No deberian existir IPP menor a 10 unidades)
1545 #
1549 #
1546 # realIndex = numpy.where(spacing > 10 )[0]
1550 # realIndex = numpy.where(spacing > 10 )[0]
1547 #
1551 #
1548 # if len(realIndex) < 2:
1552 # if len(realIndex) < 2:
1549 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1553 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1550 # return None
1554 # return None
1551 #
1555 #
1552 # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs)
1556 # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs)
1553 # realPulseIndex = pulseIndex[realIndex]
1557 # realPulseIndex = pulseIndex[realIndex]
1554 #
1558 #
1555 # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0]
1559 # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0]
1556 #
1560 #
1557 # print "IPP = %d samples" %period
1561 # print "IPP = %d samples" %period
1558 #
1562 #
1559 # self.__newNSamples = dataOut.nHeights #int(period)
1563 # self.__newNSamples = dataOut.nHeights #int(period)
1560 # self.__startIndex = int(realPulseIndex[0])
1564 # self.__startIndex = int(realPulseIndex[0])
1561 #
1565 #
1562 # return 1
1566 # return 1
1563 #
1567 #
1564 #
1568 #
1565 # def setup(self, nSamples, nChannels, buffer_size = 4):
1569 # def setup(self, nSamples, nChannels, buffer_size = 4):
1566 #
1570 #
1567 # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float),
1571 # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float),
1568 # maxlen = buffer_size*nSamples)
1572 # maxlen = buffer_size*nSamples)
1569 #
1573 #
1570 # bufferList = []
1574 # bufferList = []
1571 #
1575 #
1572 # for i in range(nChannels):
1576 # for i in range(nChannels):
1573 # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN,
1577 # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN,
1574 # maxlen = buffer_size*nSamples)
1578 # maxlen = buffer_size*nSamples)
1575 #
1579 #
1576 # bufferList.append(bufferByChannel)
1580 # bufferList.append(bufferByChannel)
1577 #
1581 #
1578 # self.__nSamples = nSamples
1582 # self.__nSamples = nSamples
1579 # self.__nChannels = nChannels
1583 # self.__nChannels = nChannels
1580 # self.__bufferList = bufferList
1584 # self.__bufferList = bufferList
1581 #
1585 #
1582 # def run(self, dataOut, channel = 0):
1586 # def run(self, dataOut, channel = 0):
1583 #
1587 #
1584 # if not self.isConfig:
1588 # if not self.isConfig:
1585 # nSamples = dataOut.nHeights
1589 # nSamples = dataOut.nHeights
1586 # nChannels = dataOut.nChannels
1590 # nChannels = dataOut.nChannels
1587 # self.setup(nSamples, nChannels)
1591 # self.setup(nSamples, nChannels)
1588 # self.isConfig = True
1592 # self.isConfig = True
1589 #
1593 #
1590 # #Append new data to internal buffer
1594 # #Append new data to internal buffer
1591 # for thisChannel in range(self.__nChannels):
1595 # for thisChannel in range(self.__nChannels):
1592 # bufferByChannel = self.__bufferList[thisChannel]
1596 # bufferByChannel = self.__bufferList[thisChannel]
1593 # bufferByChannel.extend(dataOut.data[thisChannel])
1597 # bufferByChannel.extend(dataOut.data[thisChannel])
1594 #
1598 #
1595 # if self.__pulseFound:
1599 # if self.__pulseFound:
1596 # self.__startIndex -= self.__nSamples
1600 # self.__startIndex -= self.__nSamples
1597 #
1601 #
1598 # #Finding Tx Pulse
1602 # #Finding Tx Pulse
1599 # if not self.__pulseFound:
1603 # if not self.__pulseFound:
1600 # indexFound = self.__findTxPulse(dataOut, channel)
1604 # indexFound = self.__findTxPulse(dataOut, channel)
1601 #
1605 #
1602 # if indexFound == None:
1606 # if indexFound == None:
1603 # dataOut.flagNoData = True
1607 # dataOut.flagNoData = True
1604 # return
1608 # return
1605 #
1609 #
1606 # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex)
1610 # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex)
1607 # self.__pulseFound = True
1611 # self.__pulseFound = True
1608 # self.__startIndex = indexFound
1612 # self.__startIndex = indexFound
1609 #
1613 #
1610 # #If pulse was found ...
1614 # #If pulse was found ...
1611 # for thisChannel in range(self.__nChannels):
1615 # for thisChannel in range(self.__nChannels):
1612 # bufferByChannel = self.__bufferList[thisChannel]
1616 # bufferByChannel = self.__bufferList[thisChannel]
1613 # #print self.__startIndex
1617 # #print self.__startIndex
1614 # x = numpy.array(bufferByChannel)
1618 # x = numpy.array(bufferByChannel)
1615 # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples]
1619 # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples]
1616 #
1620 #
1617 # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1621 # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1618 # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight
1622 # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight
1619 # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6
1623 # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6
1620 #
1624 #
1621 # dataOut.data = self.__arrayBuffer
1625 # dataOut.data = self.__arrayBuffer
1622 #
1626 #
1623 # self.__startIndex += self.__newNSamples
1627 # self.__startIndex += self.__newNSamples
1624 #
1628 #
1625 # return
1629 # return No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now