##// END OF EJS Templates
grafico outliers, grafico de integraciones, funciones de obtención ruído, etc
joabAM -
r1540:c8092aa564c5
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,126 +1,126
1 #include <Python.h>
1 #include <Python.h>
2 #include <numpy/arrayobject.h>
2 #include <numpy/arrayobject.h>
3 #include <math.h>
3 #include <math.h>
4
4
5
5
6 static PyObject *hildebrand_sekhon(PyObject *self, PyObject *args) {
6 static PyObject *hildebrand_sekhon(PyObject *self, PyObject *args) {
7 double navg;
7 double navg;
8 PyObject *data_obj, *data_array;
8 PyObject *data_obj, *data_array;
9
9
10 if (!PyArg_ParseTuple(args, "Od", &data_obj, &navg)) {
10 if (!PyArg_ParseTuple(args, "Od", &data_obj, &navg)) {
11 return NULL;
11 return NULL;
12 }
12 }
13
13
14 data_array = PyArray_FROM_OTF(data_obj, NPY_FLOAT64, NPY_IN_ARRAY);
14 data_array = PyArray_FROM_OTF(data_obj, NPY_FLOAT64, NPY_IN_ARRAY);
15
15
16 if (data_array == NULL) {
16 if (data_array == NULL) {
17 Py_XDECREF(data_array);
17 Py_XDECREF(data_array);
18 Py_XDECREF(data_obj);
18 Py_XDECREF(data_obj);
19 return NULL;
19 return NULL;
20 }
20 }
21 double *sortdata = (double*)PyArray_DATA(data_array);
21 double *sortdata = (double*)PyArray_DATA(data_array);
22 int lenOfData = (int)PyArray_SIZE(data_array) ;
22 int lenOfData = (int)PyArray_SIZE(data_array) ;
23 double nums_min = lenOfData*0.2;
23 double nums_min = lenOfData*0.5;//0.2
24 if (nums_min <= 5) nums_min = 5;
24 if (nums_min <= 5) nums_min = 5;
25 double sump = 0;
25 double sump = 0;
26 double sumq = 0;
26 double sumq = 0;
27 long j = 0;
27 long j = 0;
28 int cont = 1;
28 int cont = 1;
29 double rtest = 0;
29 double rtest = 0;
30 while ((cont == 1) && (j < lenOfData)) {
30 while ((cont == 1) && (j < lenOfData)) {
31 sump = sump + sortdata[j];
31 sump = sump + sortdata[j];
32 sumq = sumq + pow(sortdata[j], 2);
32 sumq = sumq + pow(sortdata[j], 2);
33 if (j > nums_min) {
33 if (j > nums_min) {
34 rtest = (double)j/(j-1) + 1/navg;
34 rtest = (double)j/(j-1) + 1/navg;
35 if ((sumq*j) > (rtest*pow(sump, 2))) {
35 if ((sumq*j) > (rtest*pow(sump, 2))) {
36 j = j - 1;
36 j = j - 1;
37 sump = sump - sortdata[j];
37 sump = sump - sortdata[j];
38 sumq = sumq - pow(sortdata[j],2);
38 sumq = sumq - pow(sortdata[j],2);
39 cont = 0;
39 cont = 0;
40 }
40 }
41 }
41 }
42 j = j + 1;
42 j = j + 1;
43 }
43 }
44
44
45 double lnoise = sump / j;
45 double lnoise = sump / j;
46
46
47 Py_DECREF(data_array);
47 Py_DECREF(data_array);
48
48
49 // return PyLong_FromLong(lnoise);
49 // return PyLong_FromLong(lnoise);
50 return PyFloat_FromDouble(lnoise);
50 return PyFloat_FromDouble(lnoise);
51 }
51 }
52
52
53 static PyObject *hildebrand_sekhon2(PyObject *self, PyObject *args) {
53 static PyObject *hildebrand_sekhon2(PyObject *self, PyObject *args) {
54 double navg;
54 double navg;
55 PyObject *data_obj, *data_array;
55 PyObject *data_obj, *data_array;
56
56
57 if (!PyArg_ParseTuple(args, "Od", &data_obj, &navg)) {
57 if (!PyArg_ParseTuple(args, "Od", &data_obj, &navg)) {
58 return NULL;
58 return NULL;
59 }
59 }
60 data_array = PyArray_FROM_OTF(data_obj, NPY_FLOAT64, NPY_IN_ARRAY);
60 data_array = PyArray_FROM_OTF(data_obj, NPY_FLOAT64, NPY_IN_ARRAY);
61
61
62 if (data_array == NULL) {
62 if (data_array == NULL) {
63 Py_XDECREF(data_array);
63 Py_XDECREF(data_array);
64 Py_XDECREF(data_obj);
64 Py_XDECREF(data_obj);
65 return NULL;
65 return NULL;
66 }
66 }
67 double *sortdata = (double*)PyArray_DATA(data_array);
67 double *sortdata = (double*)PyArray_DATA(data_array);
68 int lenOfData = (int)PyArray_SIZE(data_array) ;
68 int lenOfData = (int)PyArray_SIZE(data_array) ;
69 double nums_min = lenOfData*0.85;
69 double nums_min = lenOfData*0.85;
70 if (nums_min <= 5) nums_min = 5;
70 if (nums_min <= 5) nums_min = 5;
71 double sump = 0;
71 double sump = 0;
72 double sumq = 0;
72 double sumq = 0;
73 long j = 0;
73 long j = 0;
74 int cont = 1;
74 int cont = 1;
75 double rtest = 0;
75 double rtest = 0;
76 while ((cont == 1) && (j < lenOfData)) {
76 while ((cont == 1) && (j < lenOfData)) {
77 sump = sump + sortdata[j];
77 sump = sump + sortdata[j];
78 sumq = sumq + pow(sortdata[j], 2);
78 sumq = sumq + pow(sortdata[j], 2);
79 if (j > nums_min) {
79 if (j > nums_min) {
80 rtest = (double)j/(j-1) + 1/navg;
80 rtest = (double)j/(j-1) + 1/navg;
81 if ((sumq*j) > (rtest*pow(sump, 2))) {
81 if ((sumq*j) > (rtest*pow(sump, 2))) {
82 j = j - 1;
82 j = j - 1;
83 sump = sump - sortdata[j];
83 sump = sump - sortdata[j];
84 sumq = sumq - pow(sortdata[j],2);
84 sumq = sumq - pow(sortdata[j],2);
85 cont = 0;
85 cont = 0;
86 }
86 }
87 }
87 }
88 j = j + 1;
88 j = j + 1;
89 }
89 }
90
90
91 Py_DECREF(data_array);
91 Py_DECREF(data_array);
92
92
93 return PyLong_FromLong(j);
93 return PyLong_FromLong(j);
94 }
94 }
95
95
96
96
97 static PyMethodDef noiseMethods[] = {
97 static PyMethodDef noiseMethods[] = {
98 { "hildebrand_sekhon", hildebrand_sekhon, METH_VARARGS, "Get noise with hildebrand_sekhon algorithm" },
98 { "hildebrand_sekhon", hildebrand_sekhon, METH_VARARGS, "Get noise with hildebrand_sekhon algorithm" },
99 { "hildebrand_sekhon2", hildebrand_sekhon2, METH_VARARGS, "Variation for satellite cleaning" },
99 { "hildebrand_sekhon2", hildebrand_sekhon2, METH_VARARGS, "Variation for satellite cleaning" },
100 { NULL, NULL, 0, NULL }
100 { NULL, NULL, 0, NULL }
101 };
101 };
102
102
103 #if PY_MAJOR_VERSION >= 3
103 #if PY_MAJOR_VERSION >= 3
104
104
105 static struct PyModuleDef noisemodule = {
105 static struct PyModuleDef noisemodule = {
106 PyModuleDef_HEAD_INIT,
106 PyModuleDef_HEAD_INIT,
107 "_noise",
107 "_noise",
108 "Get noise with hildebrand_sekhon algorithm",
108 "Get noise with hildebrand_sekhon algorithm",
109 -1,
109 -1,
110 noiseMethods
110 noiseMethods
111 };
111 };
112
112
113 #endif
113 #endif
114
114
115 #if PY_MAJOR_VERSION >= 3
115 #if PY_MAJOR_VERSION >= 3
116 PyMODINIT_FUNC PyInit__noise(void) {
116 PyMODINIT_FUNC PyInit__noise(void) {
117 Py_Initialize();
117 Py_Initialize();
118 import_array();
118 import_array();
119 return PyModule_Create(&noisemodule);
119 return PyModule_Create(&noisemodule);
120 }
120 }
121 #else
121 #else
122 PyMODINIT_FUNC init_noise() {
122 PyMODINIT_FUNC init_noise() {
123 Py_InitModule("_noise", noiseMethods);
123 Py_InitModule("_noise", noiseMethods);
124 import_array();
124 import_array();
125 }
125 }
126 #endif
126 #endif
@@ -1,685 +1,686
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.name, self.id, self.project_id, self.err_queue, **kwargs)
165 opObj = className(self.name, 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... id: {}, inputId: {}'.format(self.id,self.inputId), self.name)
254 log.success('creating process... id: {}, inputId: {}'.format(self.id,self.inputId), 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(conf.name,conf.type), self.name)
260 log.success('adding operation: {}, type:{}'.format(conf.name,conf.type), self.name)
261
261
262 procUnitObj.addOperation(conf, opObj)
262 procUnitObj.addOperation(conf, opObj)
263
263
264 self.object = procUnitObj
264 self.object = procUnitObj
265
265
266 def run(self):
266 def run(self):
267 '''
267 '''
268 '''
268 '''
269 return self.object.call(**self.getKwargs())
269 return self.object.call(**self.getKwargs())
270
270
271 class ReadUnitConf(ProcUnitConf):
271 class ReadUnitConf(ProcUnitConf):
272
272
273 ELEMENTNAME = 'ReadUnit'
273 ELEMENTNAME = 'ReadUnit'
274
274
275 def __init__(self):
275 def __init__(self):
276
276
277 self.id = None
277 self.id = None
278 self.datatype = None
278 self.datatype = None
279 self.name = None
279 self.name = None
280 self.inputId = None
280 self.inputId = None
281 self.operations = []
281 self.operations = []
282 self.parameters = {}
282 self.parameters = {}
283
283
284 def setup(self, project_id, id, name, datatype, err_queue, path='', startDate='', endDate='',
284 def setup(self, project_id, id, name, datatype, err_queue, path='', startDate='', endDate='',
285 startTime='', endTime='', server=None, **kwargs):
285 startTime='', endTime='', server=None, **kwargs):
286
286
287 if datatype == None and name == None:
287 if datatype == None and name == None:
288 raise ValueError('datatype or name should be defined')
288 raise ValueError('datatype or name should be defined')
289 if name == None:
289 if name == None:
290 if 'Reader' in datatype:
290 if 'Reader' in datatype:
291 name = datatype
291 name = datatype
292 datatype = name.replace('Reader','')
292 datatype = name.replace('Reader','')
293 else:
293 else:
294 name = '{}Reader'.format(datatype)
294 name = '{}Reader'.format(datatype)
295 if datatype == None:
295 if datatype == None:
296 if 'Reader' in name:
296 if 'Reader' in name:
297 datatype = name.replace('Reader','')
297 datatype = name.replace('Reader','')
298 else:
298 else:
299 datatype = name
299 datatype = name
300 name = '{}Reader'.format(name)
300 name = '{}Reader'.format(name)
301
301
302 self.id = id
302 self.id = id
303 self.project_id = project_id
303 self.project_id = project_id
304 self.name = name
304 self.name = name
305 self.datatype = datatype
305 self.datatype = datatype
306 self.err_queue = err_queue
306 self.err_queue = err_queue
307
307
308 self.addParameter(name='path', value=path)
308 self.addParameter(name='path', value=path)
309 self.addParameter(name='startDate', value=startDate)
309 self.addParameter(name='startDate', value=startDate)
310 self.addParameter(name='endDate', value=endDate)
310 self.addParameter(name='endDate', value=endDate)
311 self.addParameter(name='startTime', value=startTime)
311 self.addParameter(name='startTime', value=startTime)
312 self.addParameter(name='endTime', value=endTime)
312 self.addParameter(name='endTime', value=endTime)
313
313
314 for key, value in kwargs.items():
314 for key, value in kwargs.items():
315 self.addParameter(name=key, value=value)
315 self.addParameter(name=key, value=value)
316
316
317
317
318 class Project(Process):
318 class Project(Process):
319 """API to create signal chain projects"""
319 """API to create signal chain projects"""
320
320
321 ELEMENTNAME = 'Project'
321 ELEMENTNAME = 'Project'
322
322
323 def __init__(self, name=''):
323 def __init__(self, name=''):
324
324
325 Process.__init__(self)
325 Process.__init__(self)
326 self.id = '1'
326 self.id = '1'
327 if name:
327 if name:
328 self.name = '{} ({})'.format(Process.__name__, name)
328 self.name = '{} ({})'.format(Process.__name__, name)
329 self.filename = None
329 self.filename = None
330 self.description = None
330 self.description = None
331 self.email = None
331 self.email = None
332 self.alarm = []
332 self.alarm = []
333 self.configurations = {}
333 self.configurations = {}
334 # self.err_queue = Queue()
334 # self.err_queue = Queue()
335 self.err_queue = None
335 self.err_queue = None
336 self.started = False
336 self.started = False
337
337
338 def getNewId(self):
338 def getNewId(self):
339
339
340 idList = list(self.configurations.keys())
340 idList = list(self.configurations.keys())
341 id = int(self.id) * 10
341 id = int(self.id) * 10
342
342
343 while True:
343 while 1:
344 id += 1
344 id += 1
345
345
346 if str(id) in idList:
346 if str(id) in idList:
347 continue
347 continue
348
348
349 break
349 break
350
350
351 return str(id)
351 return str(id)
352
352
353 def updateId(self, new_id):
353 def updateId(self, new_id):
354
354
355 self.id = str(new_id)
355 self.id = str(new_id)
356
356
357 keyList = list(self.configurations.keys())
357 keyList = list(self.configurations.keys())
358 keyList.sort()
358 keyList.sort()
359
359
360 n = 1
360 n = 1
361 new_confs = {}
361 new_confs = {}
362
362
363 for procKey in keyList:
363 for procKey in keyList:
364
364
365 conf = self.configurations[procKey]
365 conf = self.configurations[procKey]
366 idProcUnit = str(int(self.id) * 10 + n)
366 idProcUnit = str(int(self.id) * 10 + n)
367 conf.updateId(idProcUnit)
367 conf.updateId(idProcUnit)
368 new_confs[idProcUnit] = conf
368 new_confs[idProcUnit] = conf
369 n += 1
369 n += 1
370
370
371 self.configurations = new_confs
371 self.configurations = new_confs
372
372
373 def setup(self, id=1, name='', description='', email=None, alarm=[]):
373 def setup(self, id=1, name='', description='', email=None, alarm=[]):
374
374
375 self.id = str(id)
375 self.id = str(id)
376 self.description = description
376 self.description = description
377 self.email = email
377 self.email = email
378 self.alarm = alarm
378 self.alarm = alarm
379 if name:
379 if name:
380 self.name = '{} ({})'.format(Process.__name__, name)
380 self.name = '{} ({})'.format(Process.__name__, name)
381
381
382 def update(self, **kwargs):
382 def update(self, **kwargs):
383
383
384 for key, value in kwargs.items():
384 for key, value in kwargs.items():
385 setattr(self, key, value)
385 setattr(self, key, value)
386
386
387 def clone(self):
387 def clone(self):
388
388
389 p = Project()
389 p = Project()
390 p.id = self.id
390 p.id = self.id
391 p.name = self.name
391 p.name = self.name
392 p.description = self.description
392 p.description = self.description
393 p.configurations = self.configurations.copy()
393 p.configurations = self.configurations.copy()
394
394
395 return p
395 return p
396
396
397 def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
397 def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
398
398
399 '''
399 '''
400 '''
400 '''
401
401
402 if id is None:
402 if id is None:
403 idReadUnit = self.getNewId()
403 idReadUnit = self.getNewId()
404 else:
404 else:
405 idReadUnit = str(id)
405 idReadUnit = str(id)
406
406
407 conf = ReadUnitConf()
407 conf = ReadUnitConf()
408 conf.setup(self.id, idReadUnit, name, datatype, self.err_queue, **kwargs)
408 conf.setup(self.id, idReadUnit, name, datatype, self.err_queue, **kwargs)
409 self.configurations[conf.id] = conf
409 self.configurations[conf.id] = conf
410
410
411 return conf
411 return conf
412
412
413 def addProcUnit(self, id=None, inputId='0', datatype=None, name=None):
413 def addProcUnit(self, id=None, inputId='0', datatype=None, name=None):
414
414
415 '''
415 '''
416 '''
416 '''
417
417
418 if id is None:
418 if id is None:
419 idProcUnit = self.getNewId()
419 idProcUnit = self.getNewId()
420 else:
420 else:
421 idProcUnit = id
421 idProcUnit = id
422
422
423 conf = ProcUnitConf()
423 conf = ProcUnitConf()
424 conf.setup(self.id, idProcUnit, name, datatype, inputId, self.err_queue)
424 conf.setup(self.id, idProcUnit, name, datatype, inputId, self.err_queue)
425 self.configurations[conf.id] = conf
425 self.configurations[conf.id] = conf
426
426
427 return conf
427 return conf
428
428
429 def removeProcUnit(self, id):
429 def removeProcUnit(self, id):
430
430
431 if id in self.configurations:
431 if id in self.configurations:
432 self.configurations.pop(id)
432 self.configurations.pop(id)
433
433
434 def getReadUnit(self):
434 def getReadUnit(self):
435
435
436 for obj in list(self.configurations.values()):
436 for obj in list(self.configurations.values()):
437 if obj.ELEMENTNAME == 'ReadUnit':
437 if obj.ELEMENTNAME == 'ReadUnit':
438 return obj
438 return obj
439
439
440 return None
440 return None
441
441
442 def getProcUnit(self, id):
442 def getProcUnit(self, id):
443
443
444 return self.configurations[id]
444 return self.configurations[id]
445
445
446 def getUnits(self):
446 def getUnits(self):
447
447
448 keys = list(self.configurations)
448 keys = list(self.configurations)
449 keys.sort()
449 keys.sort()
450
450
451 for key in keys:
451 for key in keys:
452 yield self.configurations[key]
452 yield self.configurations[key]
453
453
454 def updateUnit(self, id, **kwargs):
454 def updateUnit(self, id, **kwargs):
455
455
456 conf = self.configurations[id].update(**kwargs)
456 conf = self.configurations[id].update(**kwargs)
457
457
458 def makeXml(self):
458 def makeXml(self):
459
459
460 xml = Element('Project')
460 xml = Element('Project')
461 xml.set('id', str(self.id))
461 xml.set('id', str(self.id))
462 xml.set('name', self.name)
462 xml.set('name', self.name)
463 xml.set('description', self.description)
463 xml.set('description', self.description)
464
464
465 for conf in self.configurations.values():
465 for conf in self.configurations.values():
466 conf.makeXml(xml)
466 conf.makeXml(xml)
467
467
468 self.xml = xml
468 self.xml = xml
469
469
470 def writeXml(self, filename=None):
470 def writeXml(self, filename=None):
471
471
472 if filename == None:
472 if filename == None:
473 if self.filename:
473 if self.filename:
474 filename = self.filename
474 filename = self.filename
475 else:
475 else:
476 filename = 'schain.xml'
476 filename = 'schain.xml'
477
477
478 if not filename:
478 if not filename:
479 print('filename has not been defined. Use setFilename(filename) for do it.')
479 print('filename has not been defined. Use setFilename(filename) for do it.')
480 return 0
480 return 0
481
481
482 abs_file = os.path.abspath(filename)
482 abs_file = os.path.abspath(filename)
483
483
484 if not os.access(os.path.dirname(abs_file), os.W_OK):
484 if not os.access(os.path.dirname(abs_file), os.W_OK):
485 print('No write permission on %s' % os.path.dirname(abs_file))
485 print('No write permission on %s' % os.path.dirname(abs_file))
486 return 0
486 return 0
487
487
488 if os.path.isfile(abs_file) and not(os.access(abs_file, os.W_OK)):
488 if os.path.isfile(abs_file) and not(os.access(abs_file, os.W_OK)):
489 print('File %s already exists and it could not be overwriten' % abs_file)
489 print('File %s already exists and it could not be overwriten' % abs_file)
490 return 0
490 return 0
491
491
492 self.makeXml()
492 self.makeXml()
493
493
494 ElementTree(self.xml).write(abs_file, method='xml')
494 ElementTree(self.xml).write(abs_file, method='xml')
495
495
496 self.filename = abs_file
496 self.filename = abs_file
497
497
498 return 1
498 return 1
499
499
500 def readXml(self, filename):
500 def readXml(self, filename):
501
501
502 abs_file = os.path.abspath(filename)
502 abs_file = os.path.abspath(filename)
503
503
504 self.configurations = {}
504 self.configurations = {}
505
505
506 try:
506 try:
507 self.xml = ElementTree().parse(abs_file)
507 self.xml = ElementTree().parse(abs_file)
508 except:
508 except:
509 log.error('Error reading %s, verify file format' % filename)
509 log.error('Error reading %s, verify file format' % filename)
510 return 0
510 return 0
511
511
512 self.id = self.xml.get('id')
512 self.id = self.xml.get('id')
513 self.name = self.xml.get('name')
513 self.name = self.xml.get('name')
514 self.description = self.xml.get('description')
514 self.description = self.xml.get('description')
515
515
516 for element in self.xml:
516 for element in self.xml:
517 if element.tag == 'ReadUnit':
517 if element.tag == 'ReadUnit':
518 conf = ReadUnitConf()
518 conf = ReadUnitConf()
519 conf.readXml(element, self.id, self.err_queue)
519 conf.readXml(element, self.id, self.err_queue)
520 self.configurations[conf.id] = conf
520 self.configurations[conf.id] = conf
521 elif element.tag == 'ProcUnit':
521 elif element.tag == 'ProcUnit':
522 conf = ProcUnitConf()
522 conf = ProcUnitConf()
523 input_proc = self.configurations[element.get('inputId')]
523 input_proc = self.configurations[element.get('inputId')]
524 conf.readXml(element, self.id, self.err_queue)
524 conf.readXml(element, self.id, self.err_queue)
525 self.configurations[conf.id] = conf
525 self.configurations[conf.id] = conf
526
526
527 self.filename = abs_file
527 self.filename = abs_file
528
528
529 return 1
529 return 1
530
530
531 def __str__(self):
531 def __str__(self):
532
532
533 text = '\nProject[id=%s, name=%s, description=%s]\n\n' % (
533 text = '\nProject[id=%s, name=%s, description=%s]\n\n' % (
534 self.id,
534 self.id,
535 self.name,
535 self.name,
536 self.description,
536 self.description,
537 )
537 )
538
538
539 for conf in self.configurations.values():
539 for conf in self.configurations.values():
540 text += '{}'.format(conf)
540 text += '{}'.format(conf)
541
541
542 return text
542 return text
543
543
544 def createObjects(self):
544 def createObjects(self):
545
545
546 keys = list(self.configurations.keys())
546 keys = list(self.configurations.keys())
547 keys.sort()
547 keys.sort()
548 for key in keys:
548 for key in keys:
549 conf = self.configurations[key]
549 conf = self.configurations[key]
550 conf.createObjects()
550 conf.createObjects()
551 if conf.inputId is not None:
551 if conf.inputId is not None:
552 conf.object.setInput(self.configurations[conf.inputId].object)
552 conf.object.setInput(self.configurations[conf.inputId].object)
553
553
554 def monitor(self):
554 def monitor(self):
555
555
556 t = Thread(target=self._monitor, args=(self.err_queue, self.ctx))
556 t = Thread(target=self._monitor, args=(self.err_queue, self.ctx))
557 t.start()
557 t.start()
558
558
559 def _monitor(self, queue, ctx):
559 def _monitor(self, queue, ctx):
560
560
561 import socket
561 import socket
562
562
563 procs = 0
563 procs = 0
564 err_msg = ''
564 err_msg = ''
565
565
566 while True:
566 while True:
567 msg = queue.get()
567 msg = queue.get()
568 if '#_start_#' in msg:
568 if '#_start_#' in msg:
569 procs += 1
569 procs += 1
570 elif '#_end_#' in msg:
570 elif '#_end_#' in msg:
571 procs -=1
571 procs -=1
572 else:
572 else:
573 err_msg = msg
573 err_msg = msg
574
574
575 if procs == 0 or 'Traceback' in err_msg:
575 if procs == 0 or 'Traceback' in err_msg:
576 break
576 break
577 time.sleep(0.1)
577 time.sleep(0.1)
578
578
579 if '|' in err_msg:
579 if '|' in err_msg:
580 name, err = err_msg.split('|')
580 name, err = err_msg.split('|')
581 if 'SchainWarning' in err:
581 if 'SchainWarning' in err:
582 log.warning(err.split('SchainWarning:')[-1].split('\n')[0].strip(), name)
582 log.warning(err.split('SchainWarning:')[-1].split('\n')[0].strip(), name)
583 elif 'SchainError' in err:
583 elif 'SchainError' in err:
584 log.error(err.split('SchainError:')[-1].split('\n')[0].strip(), name)
584 log.error(err.split('SchainError:')[-1].split('\n')[0].strip(), name)
585 else:
585 else:
586 log.error(err, name)
586 log.error(err, name)
587 else:
587 else:
588 name, err = self.name, err_msg
588 name, err = self.name, err_msg
589
589
590 time.sleep(1)
590 time.sleep(1)
591
591
592 ctx.term()
592 ctx.term()
593
593
594 message = ''.join(err)
594 message = ''.join(err)
595
595
596 if err_msg:
596 if err_msg:
597 subject = 'SChain v%s: Error running %s\n' % (
597 subject = 'SChain v%s: Error running %s\n' % (
598 schainpy.__version__, self.name)
598 schainpy.__version__, self.name)
599
599
600 subtitle = 'Hostname: %s\n' % socket.gethostbyname(
600 subtitle = 'Hostname: %s\n' % socket.gethostbyname(
601 socket.gethostname())
601 socket.gethostname())
602 subtitle += 'Working directory: %s\n' % os.path.abspath('./')
602 subtitle += 'Working directory: %s\n' % os.path.abspath('./')
603 subtitle += 'Configuration file: %s\n' % self.filename
603 subtitle += 'Configuration file: %s\n' % self.filename
604 subtitle += 'Time: %s\n' % str(datetime.datetime.now())
604 subtitle += 'Time: %s\n' % str(datetime.datetime.now())
605
605
606 readUnitConfObj = self.getReadUnit()
606 readUnitConfObj = self.getReadUnit()
607 if readUnitConfObj:
607 if readUnitConfObj:
608 subtitle += '\nInput parameters:\n'
608 subtitle += '\nInput parameters:\n'
609 subtitle += '[Data path = %s]\n' % readUnitConfObj.parameters['path']
609 subtitle += '[Data path = %s]\n' % readUnitConfObj.parameters['path']
610 subtitle += '[Start date = %s]\n' % readUnitConfObj.parameters['startDate']
610 subtitle += '[Start date = %s]\n' % readUnitConfObj.parameters['startDate']
611 subtitle += '[End date = %s]\n' % readUnitConfObj.parameters['endDate']
611 subtitle += '[End date = %s]\n' % readUnitConfObj.parameters['endDate']
612 subtitle += '[Start time = %s]\n' % readUnitConfObj.parameters['startTime']
612 subtitle += '[Start time = %s]\n' % readUnitConfObj.parameters['startTime']
613 subtitle += '[End time = %s]\n' % readUnitConfObj.parameters['endTime']
613 subtitle += '[End time = %s]\n' % readUnitConfObj.parameters['endTime']
614
614
615 a = Alarm(
615 a = Alarm(
616 modes=self.alarm,
616 modes=self.alarm,
617 email=self.email,
617 email=self.email,
618 message=message,
618 message=message,
619 subject=subject,
619 subject=subject,
620 subtitle=subtitle,
620 subtitle=subtitle,
621 filename=self.filename
621 filename=self.filename
622 )
622 )
623
623
624 a.start()
624 a.start()
625
625
626 def setFilename(self, filename):
626 def setFilename(self, filename):
627
627
628 self.filename = filename
628 self.filename = filename
629
629
630 def runProcs(self):
630 def runProcs(self):
631
631
632 err = False
632 err = False
633 n = len(self.configurations)
633 n = len(self.configurations)
634 flag_no_read = False
634 flag_no_read = False
635 nProc_noRead = 0
635 nProc_noRead = 0
636 while not err:
636 while 1:
637 #print("STAR")
637 #print("STAR")
638 n_proc = 0
638 n_proc = 0
639 for conf in self.getUnits():
639 for conf in self.getUnits():
640 #print("CONF: ",conf)
640 #print("CONF: ",conf)
641 #print( n_proc, nProc_noRead,flag_no_read)
641 #print( n_proc, nProc_noRead,flag_no_read)
642 if flag_no_read:
642 if flag_no_read:
643 if n_proc >= nProc_noRead:
643 if n_proc >= nProc_noRead:
644 ok = conf.run()
644 ok = conf.run()
645 else:
645 else:
646 #print("break")
646 #print("break")
647 #print(ok, n_proc, nProc_noRead, n, flag_no_read)
647 #print(ok, n_proc, nProc_noRead, n, flag_no_read)
648 n_proc += 1
648 n_proc += 1
649 continue
649 continue
650 else:
650 else:
651 ok = conf.run()
651 ok = conf.run()
652
652
653 n_proc += 1
653 n_proc += 1
654 #print(ok, n_proc, nProc_noRead, n, flag_no_read)
654 #print(ok, n_proc, nProc_noRead, n, flag_no_read)
655
655
656 if ok == 'Error':
656 if ok == 'Error':
657 #self.removeProcUnit(conf.id) #remove proc Unit
657 #self.removeProcUnit(conf.id) #remove proc Unit
658 n -= 1
658 n -= 1
659 continue
659 continue
660
660
661 elif ok == 'no_Read' and (not flag_no_read):
661 elif ok == 'no_Read' and (not flag_no_read):
662 nProc_noRead = n_proc - 1
662 nProc_noRead = n_proc - 1
663 flag_no_read = True
663 flag_no_read = True
664 continue
664 continue
665 elif ok == 'new_Read':
665 elif ok == 'new_Read':
666 nProc_noRead = 0
666 nProc_noRead = 0
667 flag_no_read = False
667 flag_no_read = False
668 continue
668 continue
669 elif not ok:
669 elif not ok:
670 #print("not ok",ok)
670 #print("not ok",ok)
671 break
671 break
672
672
673 if n == 0:
673 if n == 0:
674 err = True
674 err = True
675 break
675
676
676 def run(self):
677 def run(self):
677
678
678 log.success('\nStarting Project {} [id={}]'.format(self.name, self.id), tag='')
679 log.success('\nStarting Project {} [id={}]'.format(self.name, self.id), tag='')
679 self.started = True
680 self.started = True
680 self.start_time = time.time()
681 self.start_time = time.time()
681 self.createObjects()
682 self.createObjects()
682 self.runProcs()
683 self.runProcs()
683 log.success('{} Done (Time: {:4.2f}s)'.format(
684 log.success('{} Done (Time: {:4.2f}s)'.format(
684 self.name,
685 self.name,
685 time.time()-self.start_time), '')
686 time.time()-self.start_time), '')
@@ -1,1102 +1,1104
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 """Definition of diferent Data objects for different types of data
5 """Definition of diferent Data objects for different types of data
6
6
7 Here you will find the diferent data objects for the different types
7 Here you will find the diferent data objects for the different types
8 of data, this data objects must be used as dataIn or dataOut objects in
8 of data, this data objects must be used as dataIn or dataOut objects in
9 processing units and operations. Currently the supported data objects are:
9 processing units and operations. Currently the supported data objects are:
10 Voltage, Spectra, SpectraHeis, Fits, Correlation and Parameters
10 Voltage, Spectra, SpectraHeis, Fits, Correlation and Parameters
11 """
11 """
12
12
13 import copy
13 import copy
14 import numpy
14 import numpy
15 import datetime
15 import datetime
16 import json
16 import json
17
17
18 import schainpy.admin
18 import schainpy.admin
19 from schainpy.utils import log
19 from schainpy.utils import log
20 from .jroheaderIO import SystemHeader, RadarControllerHeader
20 from .jroheaderIO import SystemHeader, RadarControllerHeader
21 from schainpy.model.data import _noise
21 from schainpy.model.data import _noise
22
22
23
23
24 def getNumpyDtype(dataTypeCode):
24 def getNumpyDtype(dataTypeCode):
25
25
26 if dataTypeCode == 0:
26 if dataTypeCode == 0:
27 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
27 numpyDtype = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
28 elif dataTypeCode == 1:
28 elif dataTypeCode == 1:
29 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
29 numpyDtype = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
30 elif dataTypeCode == 2:
30 elif dataTypeCode == 2:
31 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
31 numpyDtype = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
32 elif dataTypeCode == 3:
32 elif dataTypeCode == 3:
33 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
33 numpyDtype = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
34 elif dataTypeCode == 4:
34 elif dataTypeCode == 4:
35 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
35 numpyDtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
36 elif dataTypeCode == 5:
36 elif dataTypeCode == 5:
37 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
37 numpyDtype = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
38 else:
38 else:
39 raise ValueError('dataTypeCode was not defined')
39 raise ValueError('dataTypeCode was not defined')
40
40
41 return numpyDtype
41 return numpyDtype
42
42
43
43
44 def getDataTypeCode(numpyDtype):
44 def getDataTypeCode(numpyDtype):
45
45
46 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
46 if numpyDtype == numpy.dtype([('real', '<i1'), ('imag', '<i1')]):
47 datatype = 0
47 datatype = 0
48 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
48 elif numpyDtype == numpy.dtype([('real', '<i2'), ('imag', '<i2')]):
49 datatype = 1
49 datatype = 1
50 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
50 elif numpyDtype == numpy.dtype([('real', '<i4'), ('imag', '<i4')]):
51 datatype = 2
51 datatype = 2
52 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
52 elif numpyDtype == numpy.dtype([('real', '<i8'), ('imag', '<i8')]):
53 datatype = 3
53 datatype = 3
54 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
54 elif numpyDtype == numpy.dtype([('real', '<f4'), ('imag', '<f4')]):
55 datatype = 4
55 datatype = 4
56 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
56 elif numpyDtype == numpy.dtype([('real', '<f8'), ('imag', '<f8')]):
57 datatype = 5
57 datatype = 5
58 else:
58 else:
59 datatype = None
59 datatype = None
60
60
61 return datatype
61 return datatype
62
62
63
63
64 def hildebrand_sekhon(data, navg):
64 def hildebrand_sekhon(data, navg):
65 """
65 """
66 This method is for the objective determination of the noise level in Doppler spectra. This
66 This method is for the objective determination of the noise level in Doppler spectra. This
67 implementation technique is based on the fact that the standard deviation of the spectral
67 implementation technique is based on the fact that the standard deviation of the spectral
68 densities is equal to the mean spectral density for white Gaussian noise
68 densities is equal to the mean spectral density for white Gaussian noise
69
69
70 Inputs:
70 Inputs:
71 Data : heights
71 Data : heights
72 navg : numbers of averages
72 navg : numbers of averages
73
73
74 Return:
74 Return:
75 mean : noise's level
75 mean : noise's level
76 """
76 """
77
77
78 sortdata = numpy.sort(data, axis=None)
78 sortdata = numpy.sort(data, axis=None)
79 '''
79 '''
80 lenOfData = len(sortdata)
80 lenOfData = len(sortdata)
81 nums_min = lenOfData*0.5
81 nums_min = lenOfData*0.5
82
82
83 if nums_min <= 5:
83 if nums_min <= 5:
84
84
85 nums_min = 5
85 nums_min = 5
86
86
87 sump = 0.
87 sump = 0.
88 sumq = 0.
88 sumq = 0.
89
89
90 j = 0
90 j = 0
91 cont = 1
91 cont = 1
92
92
93 while((cont == 1)and(j < lenOfData)):
93 while((cont == 1)and(j < lenOfData)):
94
94
95 sump += sortdata[j]
95 sump += sortdata[j]
96 sumq += sortdata[j]**2
96 sumq += sortdata[j]**2
97
97
98 if j > nums_min:
98 if j > nums_min:
99 rtest = float(j)/(j-1) + 1.0/navg
99 rtest = float(j)/(j-1) + 1.0/navg
100 if ((sumq*j) > (rtest*sump**2)):
100 if ((sumq*j) > (rtest*sump**2)):
101 j = j - 1
101 j = j - 1
102 sump = sump - sortdata[j]
102 sump = sump - sortdata[j]
103 sumq = sumq - sortdata[j]**2
103 sumq = sumq - sortdata[j]**2
104 cont = 0
104 cont = 0
105
105
106 j += 1
106 j += 1
107
107
108 lnoise = sump / j
108 lnoise = sump / j
109 return lnoise
109 return lnoise
110 '''
110 '''
111 return _noise.hildebrand_sekhon(sortdata, navg)
111 return _noise.hildebrand_sekhon(sortdata, navg)
112
112
113
113
114 class Beam:
114 class Beam:
115
115
116 def __init__(self):
116 def __init__(self):
117 self.codeList = []
117 self.codeList = []
118 self.azimuthList = []
118 self.azimuthList = []
119 self.zenithList = []
119 self.zenithList = []
120
120
121
121
122
122
123 class GenericData(object):
123 class GenericData(object):
124
124
125 flagNoData = True
125 flagNoData = True
126
126
127 def copy(self, inputObj=None):
127 def copy(self, inputObj=None):
128
128
129 if inputObj == None:
129 if inputObj == None:
130 return copy.deepcopy(self)
130 return copy.deepcopy(self)
131
131
132 for key in list(inputObj.__dict__.keys()):
132 for key in list(inputObj.__dict__.keys()):
133
133
134 attribute = inputObj.__dict__[key]
134 attribute = inputObj.__dict__[key]
135
135
136 # If this attribute is a tuple or list
136 # If this attribute is a tuple or list
137 if type(inputObj.__dict__[key]) in (tuple, list):
137 if type(inputObj.__dict__[key]) in (tuple, list):
138 self.__dict__[key] = attribute[:]
138 self.__dict__[key] = attribute[:]
139 continue
139 continue
140
140
141 # If this attribute is another object or instance
141 # If this attribute is another object or instance
142 if hasattr(attribute, '__dict__'):
142 if hasattr(attribute, '__dict__'):
143 self.__dict__[key] = attribute.copy()
143 self.__dict__[key] = attribute.copy()
144 continue
144 continue
145
145
146 self.__dict__[key] = inputObj.__dict__[key]
146 self.__dict__[key] = inputObj.__dict__[key]
147
147
148 def deepcopy(self):
148 def deepcopy(self):
149
149
150 return copy.deepcopy(self)
150 return copy.deepcopy(self)
151
151
152 def isEmpty(self):
152 def isEmpty(self):
153
153
154 return self.flagNoData
154 return self.flagNoData
155
155
156 def isReady(self):
156 def isReady(self):
157
157
158 return not self.flagNoData
158 return not self.flagNoData
159
159
160
160
161 class JROData(GenericData):
161 class JROData(GenericData):
162
162
163 useInputBuffer = False
163 useInputBuffer = False
164 buffer_empty = True
164 buffer_empty = True
165
165
166 systemHeaderObj = SystemHeader()
166 systemHeaderObj = SystemHeader()
167 radarControllerHeaderObj = RadarControllerHeader()
167 radarControllerHeaderObj = RadarControllerHeader()
168 type = None
168 type = None
169 datatype = None # dtype but in string
169 datatype = None # dtype but in string
170 nProfiles = None
170 nProfiles = None
171 heightList = None
171 heightList = None
172 channelList = None
172 channelList = None
173 flagDiscontinuousBlock = False
173 flagDiscontinuousBlock = False
174 useLocalTime = False
174 useLocalTime = False
175 utctime = None
175 utctime = None
176 timeZone = None
176 timeZone = None
177 dstFlag = None
177 dstFlag = None
178 errorCount = None
178 errorCount = None
179 blocksize = None
179 blocksize = None
180 flagDecodeData = False # asumo q la data no esta decodificada
180 flagDecodeData = False # asumo q la data no esta decodificada
181 flagDeflipData = False # asumo q la data no esta sin flip
181 flagDeflipData = False # asumo q la data no esta sin flip
182 flagShiftFFT = False
182 flagShiftFFT = False
183 nCohInt = None
183 nCohInt = None
184 windowOfFilter = 1
184 windowOfFilter = 1
185 C = 3e8
185 C = 3e8
186 frequency = 49.92e6
186 frequency = 49.92e6
187 realtime = False
187 realtime = False
188 beacon_heiIndexList = None
188 beacon_heiIndexList = None
189 last_block = None
189 last_block = None
190 blocknow = None
190 blocknow = None
191 azimuth = None
191 azimuth = None
192 zenith = None
192 zenith = None
193 beam = Beam()
193 beam = Beam()
194 profileIndex = None
194 profileIndex = None
195 error = None
195 error = None
196 data = None
196 data = None
197 nmodes = None
197 nmodes = None
198 metadata_list = ['heightList', 'timeZone', 'type']
198 metadata_list = ['heightList', 'timeZone', 'type']
199 codeList = []
199 codeList = []
200 azimuthList = []
200 azimuthList = []
201 elevationList = []
201 elevationList = []
202 last_noise = None
202
203
203 def __str__(self):
204 def __str__(self):
204
205
205 return '{} - {}'.format(self.type, self.datatime())
206 return '{} - {}'.format(self.type, self.datatime())
206
207
207 def getNoise(self):
208 def getNoise(self):
208
209
209 raise NotImplementedError
210 raise NotImplementedError
210
211
211 @property
212 @property
212 def nChannels(self):
213 def nChannels(self):
213
214
214 return len(self.channelList)
215 return len(self.channelList)
215
216
216 @property
217 @property
217 def channelIndexList(self):
218 def channelIndexList(self):
218
219
219 return list(range(self.nChannels))
220 return list(range(self.nChannels))
220
221
221 @property
222 @property
222 def nHeights(self):
223 def nHeights(self):
223
224
224 return len(self.heightList)
225 return len(self.heightList)
225
226
226 def getDeltaH(self):
227 def getDeltaH(self):
227
228
228 return self.heightList[1] - self.heightList[0]
229 return self.heightList[1] - self.heightList[0]
229
230
230 @property
231 @property
231 def ltctime(self):
232 def ltctime(self):
232
233
233 if self.useLocalTime:
234 if self.useLocalTime:
234 return self.utctime - self.timeZone * 60
235 return self.utctime - self.timeZone * 60
235
236
236 return self.utctime
237 return self.utctime
237
238
238 @property
239 @property
239 def datatime(self):
240 def datatime(self):
240
241
241 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
242 datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime)
242 return datatimeValue
243 return datatimeValue
243
244
244 def getTimeRange(self):
245 def getTimeRange(self):
245
246
246 datatime = []
247 datatime = []
247
248
248 datatime.append(self.ltctime)
249 datatime.append(self.ltctime)
249 datatime.append(self.ltctime + self.timeInterval + 1)
250 datatime.append(self.ltctime + self.timeInterval + 1)
250
251
251 datatime = numpy.array(datatime)
252 datatime = numpy.array(datatime)
252
253
253 return datatime
254 return datatime
254
255
255 def getFmaxTimeResponse(self):
256 def getFmaxTimeResponse(self):
256
257
257 period = (10**-6) * self.getDeltaH() / (0.15)
258 period = (10**-6) * self.getDeltaH() / (0.15)
258
259
259 PRF = 1. / (period * self.nCohInt)
260 PRF = 1. / (period * self.nCohInt)
260
261
261 fmax = PRF
262 fmax = PRF
262
263
263 return fmax
264 return fmax
264
265
265 def getFmax(self):
266 def getFmax(self):
266 PRF = 1. / (self.ippSeconds * self.nCohInt)
267 PRF = 1. / (self.ippSeconds * self.nCohInt)
267
268
268 fmax = PRF
269 fmax = PRF
269 return fmax
270 return fmax
270
271
271 def getVmax(self):
272 def getVmax(self):
272
273
273 _lambda = self.C / self.frequency
274 _lambda = self.C / self.frequency
274
275
275 vmax = self.getFmax() * _lambda / 2
276 vmax = self.getFmax() * _lambda / 2
276
277
277 return vmax
278 return vmax
278
279
279 @property
280 @property
280 def ippSeconds(self):
281 def ippSeconds(self):
281 '''
282 '''
282 '''
283 '''
283 return self.radarControllerHeaderObj.ippSeconds
284 return self.radarControllerHeaderObj.ippSeconds
284
285
285 @ippSeconds.setter
286 @ippSeconds.setter
286 def ippSeconds(self, ippSeconds):
287 def ippSeconds(self, ippSeconds):
287 '''
288 '''
288 '''
289 '''
289 self.radarControllerHeaderObj.ippSeconds = ippSeconds
290 self.radarControllerHeaderObj.ippSeconds = ippSeconds
290
291
291 @property
292 @property
292 def code(self):
293 def code(self):
293 '''
294 '''
294 '''
295 '''
295 return self.radarControllerHeaderObj.code
296 return self.radarControllerHeaderObj.code
296
297
297 @code.setter
298 @code.setter
298 def code(self, code):
299 def code(self, code):
299 '''
300 '''
300 '''
301 '''
301 self.radarControllerHeaderObj.code = code
302 self.radarControllerHeaderObj.code = code
302
303
303 @property
304 @property
304 def nCode(self):
305 def nCode(self):
305 '''
306 '''
306 '''
307 '''
307 return self.radarControllerHeaderObj.nCode
308 return self.radarControllerHeaderObj.nCode
308
309
309 @nCode.setter
310 @nCode.setter
310 def nCode(self, ncode):
311 def nCode(self, ncode):
311 '''
312 '''
312 '''
313 '''
313 self.radarControllerHeaderObj.nCode = ncode
314 self.radarControllerHeaderObj.nCode = ncode
314
315
315 @property
316 @property
316 def nBaud(self):
317 def nBaud(self):
317 '''
318 '''
318 '''
319 '''
319 return self.radarControllerHeaderObj.nBaud
320 return self.radarControllerHeaderObj.nBaud
320
321
321 @nBaud.setter
322 @nBaud.setter
322 def nBaud(self, nbaud):
323 def nBaud(self, nbaud):
323 '''
324 '''
324 '''
325 '''
325 self.radarControllerHeaderObj.nBaud = nbaud
326 self.radarControllerHeaderObj.nBaud = nbaud
326
327
327 @property
328 @property
328 def ipp(self):
329 def ipp(self):
329 '''
330 '''
330 '''
331 '''
331 return self.radarControllerHeaderObj.ipp
332 return self.radarControllerHeaderObj.ipp
332
333
333 @ipp.setter
334 @ipp.setter
334 def ipp(self, ipp):
335 def ipp(self, ipp):
335 '''
336 '''
336 '''
337 '''
337 self.radarControllerHeaderObj.ipp = ipp
338 self.radarControllerHeaderObj.ipp = ipp
338
339
339 @property
340 @property
340 def metadata(self):
341 def metadata(self):
341 '''
342 '''
342 '''
343 '''
343
344
344 return {attr: getattr(self, attr) for attr in self.metadata_list}
345 return {attr: getattr(self, attr) for attr in self.metadata_list}
345
346
346
347
347 class Voltage(JROData):
348 class Voltage(JROData):
348
349
349 dataPP_POW = None
350 dataPP_POW = None
350 dataPP_DOP = None
351 dataPP_DOP = None
351 dataPP_WIDTH = None
352 dataPP_WIDTH = None
352 dataPP_SNR = None
353 dataPP_SNR = None
353
354
354 def __init__(self):
355 def __init__(self):
355 '''
356 '''
356 Constructor
357 Constructor
357 '''
358 '''
358
359
359 self.useLocalTime = True
360 self.useLocalTime = True
360 self.radarControllerHeaderObj = RadarControllerHeader()
361 self.radarControllerHeaderObj = RadarControllerHeader()
361 self.systemHeaderObj = SystemHeader()
362 self.systemHeaderObj = SystemHeader()
362 self.type = "Voltage"
363 self.type = "Voltage"
363 self.data = None
364 self.data = None
364 self.nProfiles = None
365 self.nProfiles = None
365 self.heightList = None
366 self.heightList = None
366 self.channelList = None
367 self.channelList = None
367 self.flagNoData = True
368 self.flagNoData = True
368 self.flagDiscontinuousBlock = False
369 self.flagDiscontinuousBlock = False
369 self.utctime = None
370 self.utctime = None
370 self.timeZone = 0
371 self.timeZone = 0
371 self.dstFlag = None
372 self.dstFlag = None
372 self.errorCount = None
373 self.errorCount = None
373 self.nCohInt = None
374 self.nCohInt = None
374 self.blocksize = None
375 self.blocksize = None
375 self.flagCohInt = False
376 self.flagCohInt = False
376 self.flagDecodeData = False # asumo q la data no esta decodificada
377 self.flagDecodeData = False # asumo q la data no esta decodificada
377 self.flagDeflipData = False # asumo q la data no esta sin flip
378 self.flagDeflipData = False # asumo q la data no esta sin flip
378 self.flagShiftFFT = False
379 self.flagShiftFFT = False
379 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
380 self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil
380 self.profileIndex = 0
381 self.profileIndex = 0
381 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
382 self.metadata_list = ['type', 'heightList', 'timeZone', 'nProfiles', 'channelList', 'nCohInt',
382 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
383 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp']
383
384
384 def getNoisebyHildebrand(self, channel=None, ymin_index=None, ymax_index=None):
385 def getNoisebyHildebrand(self, channel=None, ymin_index=None, ymax_index=None):
385 """
386 """
386 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
387 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
387
388
388 Return:
389 Return:
389 noiselevel
390 noiselevel
390 """
391 """
391
392
392 if channel != None:
393 if channel != None:
393 data = self.data[channel,ymin_index:ymax_index]
394 data = self.data[channel,ymin_index:ymax_index]
394 nChannels = 1
395 nChannels = 1
395 else:
396 else:
396 data = self.data[:,ymin_index:ymax_index]
397 data = self.data[:,ymin_index:ymax_index]
397 nChannels = self.nChannels
398 nChannels = self.nChannels
398
399
399 noise = numpy.zeros(nChannels)
400 noise = numpy.zeros(nChannels)
400 power = data * numpy.conjugate(data)
401 power = data * numpy.conjugate(data)
401
402
402 for thisChannel in range(nChannels):
403 for thisChannel in range(nChannels):
403 if nChannels == 1:
404 if nChannels == 1:
404 daux = power[:].real
405 daux = power[:].real
405 else:
406 else:
406 daux = power[thisChannel, :].real
407 daux = power[thisChannel, :].real
407 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
408 noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt)
408
409
409 return noise
410 return noise
410
411
411 def getNoise(self, type=1, channel=None,ymin_index=None, ymax_index=None):
412 def getNoise(self, type=1, channel=None,ymin_index=None, ymax_index=None):
412
413
413 if type == 1:
414 if type == 1:
414 noise = self.getNoisebyHildebrand(channel,ymin_index, ymax_index)
415 noise = self.getNoisebyHildebrand(channel,ymin_index, ymax_index)
415
416
416 return noise
417 return noise
417
418
418 def getPower(self, channel=None):
419 def getPower(self, channel=None):
419
420
420 if channel != None:
421 if channel != None:
421 data = self.data[channel]
422 data = self.data[channel]
422 else:
423 else:
423 data = self.data
424 data = self.data
424
425
425 power = data * numpy.conjugate(data)
426 power = data * numpy.conjugate(data)
426 powerdB = 10 * numpy.log10(power.real)
427 powerdB = 10 * numpy.log10(power.real)
427 powerdB = numpy.squeeze(powerdB)
428 powerdB = numpy.squeeze(powerdB)
428
429
429 return powerdB
430 return powerdB
430
431
431 @property
432 @property
432 def timeInterval(self):
433 def timeInterval(self):
433
434
434 return self.ippSeconds * self.nCohInt
435 return self.ippSeconds * self.nCohInt
435
436
436 noise = property(getNoise, "I'm the 'nHeights' property.")
437 noise = property(getNoise, "I'm the 'nHeights' property.")
437
438
438
439
439 class Spectra(JROData):
440 class Spectra(JROData):
440
441
441 data_outlier = 0
442 data_outlier = 0
442
443
443 def __init__(self):
444 def __init__(self):
444 '''
445 '''
445 Constructor
446 Constructor
446 '''
447 '''
447
448
448 self.data_dc = None
449 self.data_dc = None
449 self.data_spc = None
450 self.data_spc = None
450 self.data_cspc = None
451 self.data_cspc = None
451 self.useLocalTime = True
452 self.useLocalTime = True
452 self.radarControllerHeaderObj = RadarControllerHeader()
453 self.radarControllerHeaderObj = RadarControllerHeader()
453 self.systemHeaderObj = SystemHeader()
454 self.systemHeaderObj = SystemHeader()
454 self.type = "Spectra"
455 self.type = "Spectra"
455 self.timeZone = 0
456 self.timeZone = 0
456 self.nProfiles = None
457 self.nProfiles = None
457 self.heightList = None
458 self.heightList = None
458 self.channelList = None
459 self.channelList = None
459 self.pairsList = None
460 self.pairsList = None
460 self.flagNoData = True
461 self.flagNoData = True
461 self.flagDiscontinuousBlock = False
462 self.flagDiscontinuousBlock = False
462 self.utctime = None
463 self.utctime = None
463 self.nCohInt = None
464 self.nCohInt = None
464 self.nIncohInt = None
465 self.nIncohInt = None
465 self.blocksize = None
466 self.blocksize = None
466 self.nFFTPoints = None
467 self.nFFTPoints = None
467 self.wavelength = None
468 self.wavelength = None
468 self.flagDecodeData = False # asumo q la data no esta decodificada
469 self.flagDecodeData = False # asumo q la data no esta decodificada
469 self.flagDeflipData = False # asumo q la data no esta sin flip
470 self.flagDeflipData = False # asumo q la data no esta sin flip
470 self.flagShiftFFT = False
471 self.flagShiftFFT = False
471 self.ippFactor = 1
472 self.ippFactor = 1
472 self.beacon_heiIndexList = []
473 self.beacon_heiIndexList = []
473 self.noise_estimation = None
474 self.noise_estimation = None
474 self.codeList = []
475 self.codeList = []
475 self.azimuthList = []
476 self.azimuthList = []
476 self.elevationList = []
477 self.elevationList = []
477 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
478 self.metadata_list = ['type', 'heightList', 'timeZone', 'pairsList', 'channelList', 'nCohInt',
478 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp','nIncohInt', 'nFFTPoints', 'nProfiles']
479 'code', 'nCode', 'nBaud', 'ippSeconds', 'ipp','nIncohInt', 'nFFTPoints', 'nProfiles']
479
480
480
481
481 self.max_nIncohInt = 1
482 self.max_nIncohInt = 1
482
483
483
484
484 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
485 def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
485 """
486 """
486 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
487 Determino el nivel de ruido usando el metodo Hildebrand-Sekhon
487
488
488 Return:
489 Return:
489 noiselevel
490 noiselevel
490 """
491 """
491 # if hasattr(self.nIncohInt, "__len__"): #nIncohInt is a matrix
492 # if hasattr(self.nIncohInt, "__len__"): #nIncohInt is a matrix
492 #
493 #
493 # heis = self.data_spc.shape[2]
494 # heis = self.data_spc.shape[2]
494 #
495 #
495 # noise = numpy.zeros((self.nChannels, heis))
496 # noise = numpy.zeros((self.nChannels, heis))
496 # for hei in range(heis):
497 # for hei in range(heis):
497 # for channel in range(self.nChannels):
498 # for channel in range(self.nChannels):
498 # daux = self.data_spc[channel, xmin_index:xmax_index, hei]
499 # daux = self.data_spc[channel, xmin_index:xmax_index, hei]
499 #
500 #
500 # noise[channel,hei] = hildebrand_sekhon(daux, self.nIncohInt[channel,hei])
501 # noise[channel,hei] = hildebrand_sekhon(daux, self.nIncohInt[channel,hei])
501 #
502 #
502 # else:
503 # else:
503 # noise = numpy.zeros(self.nChannels)
504 # noise = numpy.zeros(self.nChannels)
504 # for channel in range(self.nChannels):
505 # for channel in range(self.nChannels):
505 # daux = self.data_spc[channel,xmin_index:xmax_index, ymin_index:ymax_index]
506 # daux = self.data_spc[channel,xmin_index:xmax_index, ymin_index:ymax_index]
506 #
507 #
507 # noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
508 # noise[channel] = hildebrand_sekhon(daux, self.nIncohInt)
508 noise = numpy.zeros(self.nChannels)
509 noise = numpy.zeros(self.nChannels)
509 for channel in range(self.nChannels):
510 for channel in range(self.nChannels):
510 daux = self.data_spc[channel,xmin_index:xmax_index, ymin_index:ymax_index]
511 daux = self.data_spc[channel,xmin_index:xmax_index, ymin_index:ymax_index]
511
512
512 noise[channel] = hildebrand_sekhon(daux, self.max_nIncohInt)
513 noise[channel] = hildebrand_sekhon(daux, self.max_nIncohInt)
513
514
514 return noise
515 return noise
515
516
516 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
517 def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None):
517
518
518 if self.noise_estimation is not None:
519 if self.noise_estimation is not None:
519 # this was estimated by getNoise Operation defined in jroproc_spectra.py
520 # this was estimated by getNoise Operation defined in jroproc_spectra.py
520 return self.noise_estimation
521 return self.noise_estimation
521 else:
522 else:
522 noise = self.getNoisebyHildebrand(
523 noise = self.getNoisebyHildebrand(
523 xmin_index, xmax_index, ymin_index, ymax_index)
524 xmin_index, xmax_index, ymin_index, ymax_index)
524 return noise
525 return noise
525
526
526 def getFreqRangeTimeResponse(self, extrapoints=0):
527 def getFreqRangeTimeResponse(self, extrapoints=0):
527
528
528 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
529 deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor)
529 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
530 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.) - deltafreq / 2
530
531
531 return freqrange
532 return freqrange
532
533
533 def getAcfRange(self, extrapoints=0):
534 def getAcfRange(self, extrapoints=0):
534
535
535 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
536 deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor))
536 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
537 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
537
538
538 return freqrange
539 return freqrange
539
540
540 def getFreqRange(self, extrapoints=0):
541 def getFreqRange(self, extrapoints=0):
541
542
542 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
543 deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor)
543 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
544 freqrange = deltafreq * (numpy.arange(self.nFFTPoints + extrapoints) -self.nFFTPoints / 2.) - deltafreq / 2
544
545
545 return freqrange
546 return freqrange
546
547
547 def getVelRange(self, extrapoints=0):
548 def getVelRange(self, extrapoints=0):
548
549
549 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
550 deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor)
550 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
551 velrange = deltav * (numpy.arange(self.nFFTPoints + extrapoints) - self.nFFTPoints / 2.)
551
552
552 if self.nmodes:
553 if self.nmodes:
553 return velrange/self.nmodes
554 return velrange/self.nmodes
554 else:
555 else:
555 return velrange
556 return velrange
556
557
557 @property
558 @property
558 def nPairs(self):
559 def nPairs(self):
559
560
560 return len(self.pairsList)
561 return len(self.pairsList)
561
562
562 @property
563 @property
563 def pairsIndexList(self):
564 def pairsIndexList(self):
564
565
565 return list(range(self.nPairs))
566 return list(range(self.nPairs))
566
567
567 @property
568 @property
568 def normFactor(self):
569 def normFactor(self):
569
570
570 pwcode = 1
571 pwcode = 1
571
572
572 if self.flagDecodeData:
573 if self.flagDecodeData:
573 pwcode = numpy.sum(self.code[0]**2)
574 pwcode = numpy.sum(self.code[0]**2)
574 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
575 #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter
575 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
576 normFactor = self.nProfiles * self.nIncohInt * self.nCohInt * pwcode * self.windowOfFilter
576
577
577
578
578 return normFactor
579 return normFactor
579
580
580 @property
581 @property
581 def flag_cspc(self):
582 def flag_cspc(self):
582
583
583 if self.data_cspc is None:
584 if self.data_cspc is None:
584 return True
585 return True
585
586
586 return False
587 return False
587
588
588 @property
589 @property
589 def flag_dc(self):
590 def flag_dc(self):
590
591
591 if self.data_dc is None:
592 if self.data_dc is None:
592 return True
593 return True
593
594
594 return False
595 return False
595
596
596 @property
597 @property
597 def timeInterval(self):
598 def timeInterval(self):
598
599
599 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
600 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor
600 if self.nmodes:
601 if self.nmodes:
601 return self.nmodes*timeInterval
602 return self.nmodes*timeInterval
602 else:
603 else:
603 return timeInterval
604 return timeInterval
604
605
605 def getPower(self):
606 def getPower(self):
606
607
607 factor = self.normFactor
608 factor = self.normFactor
608 z = numpy.divide(self.data_spc,factor)
609 z = numpy.divide(self.data_spc,factor)
609 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
610 z = numpy.where(numpy.isfinite(z), z, numpy.NAN)
610 avg = numpy.average(z, axis=1)
611 avg = numpy.average(z, axis=1)
611
612
612 return 10 * numpy.log10(avg)
613 return 10 * numpy.log10(avg)
613
614
614 def getCoherence(self, pairsList=None, phase=False):
615 def getCoherence(self, pairsList=None, phase=False):
615
616
616 z = []
617 z = []
617 if pairsList is None:
618 if pairsList is None:
618 pairsIndexList = self.pairsIndexList
619 pairsIndexList = self.pairsIndexList
619 else:
620 else:
620 pairsIndexList = []
621 pairsIndexList = []
621 for pair in pairsList:
622 for pair in pairsList:
622 if pair not in self.pairsList:
623 if pair not in self.pairsList:
623 raise ValueError("Pair %s is not in dataOut.pairsList" % (
624 raise ValueError("Pair %s is not in dataOut.pairsList" % (
624 pair))
625 pair))
625 pairsIndexList.append(self.pairsList.index(pair))
626 pairsIndexList.append(self.pairsList.index(pair))
626 for i in range(len(pairsIndexList)):
627 for i in range(len(pairsIndexList)):
627 pair = self.pairsList[pairsIndexList[i]]
628 pair = self.pairsList[pairsIndexList[i]]
628 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
629 ccf = numpy.average(self.data_cspc[pairsIndexList[i], :, :], axis=0)
629 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
630 powa = numpy.average(self.data_spc[pair[0], :, :], axis=0)
630 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
631 powb = numpy.average(self.data_spc[pair[1], :, :], axis=0)
631 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
632 avgcoherenceComplex = ccf / numpy.sqrt(powa * powb)
632 if phase:
633 if phase:
633 data = numpy.arctan2(avgcoherenceComplex.imag,
634 data = numpy.arctan2(avgcoherenceComplex.imag,
634 avgcoherenceComplex.real) * 180 / numpy.pi
635 avgcoherenceComplex.real) * 180 / numpy.pi
635 else:
636 else:
636 data = numpy.abs(avgcoherenceComplex)
637 data = numpy.abs(avgcoherenceComplex)
637
638
638 z.append(data)
639 z.append(data)
639
640
640 return numpy.array(z)
641 return numpy.array(z)
641
642
642 def setValue(self, value):
643 def setValue(self, value):
643
644
644 print("This property should not be initialized")
645 print("This property should not be initialized", value)
645
646
646 return
647 return
647
648
648 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
649 noise = property(getNoise, setValue, "I'm the 'nHeights' property.")
649
650
650
651
651 class SpectraHeis(Spectra):
652 class SpectraHeis(Spectra):
652
653
653 def __init__(self):
654 def __init__(self):
654
655
655 self.radarControllerHeaderObj = RadarControllerHeader()
656 self.radarControllerHeaderObj = RadarControllerHeader()
656 self.systemHeaderObj = SystemHeader()
657 self.systemHeaderObj = SystemHeader()
657 self.type = "SpectraHeis"
658 self.type = "SpectraHeis"
658 self.nProfiles = None
659 self.nProfiles = None
659 self.heightList = None
660 self.heightList = None
660 self.channelList = None
661 self.channelList = None
661 self.flagNoData = True
662 self.flagNoData = True
662 self.flagDiscontinuousBlock = False
663 self.flagDiscontinuousBlock = False
663 self.utctime = None
664 self.utctime = None
664 self.blocksize = None
665 self.blocksize = None
665 self.profileIndex = 0
666 self.profileIndex = 0
666 self.nCohInt = 1
667 self.nCohInt = 1
667 self.nIncohInt = 1
668 self.nIncohInt = 1
668
669
669 @property
670 @property
670 def normFactor(self):
671 def normFactor(self):
671 pwcode = 1
672 pwcode = 1
672 if self.flagDecodeData:
673 if self.flagDecodeData:
673 pwcode = numpy.sum(self.code[0]**2)
674 pwcode = numpy.sum(self.code[0]**2)
674
675
675 normFactor = self.nIncohInt * self.nCohInt * pwcode
676 normFactor = self.nIncohInt * self.nCohInt * pwcode
676
677
677 return normFactor
678 return normFactor
678
679
679 @property
680 @property
680 def timeInterval(self):
681 def timeInterval(self):
681
682
682 return self.ippSeconds * self.nCohInt * self.nIncohInt
683 return self.ippSeconds * self.nCohInt * self.nIncohInt
683
684
684
685
685 class Fits(JROData):
686 class Fits(JROData):
686
687
687 def __init__(self):
688 def __init__(self):
688
689
689 self.type = "Fits"
690 self.type = "Fits"
690 self.nProfiles = None
691 self.nProfiles = None
691 self.heightList = None
692 self.heightList = None
692 self.channelList = None
693 self.channelList = None
693 self.flagNoData = True
694 self.flagNoData = True
694 self.utctime = None
695 self.utctime = None
695 self.nCohInt = 1
696 self.nCohInt = 1
696 self.nIncohInt = 1
697 self.nIncohInt = 1
697 self.useLocalTime = True
698 self.useLocalTime = True
698 self.profileIndex = 0
699 self.profileIndex = 0
699 self.timeZone = 0
700 self.timeZone = 0
700
701
701 def getTimeRange(self):
702 def getTimeRange(self):
702
703
703 datatime = []
704 datatime = []
704
705
705 datatime.append(self.ltctime)
706 datatime.append(self.ltctime)
706 datatime.append(self.ltctime + self.timeInterval)
707 datatime.append(self.ltctime + self.timeInterval)
707
708
708 datatime = numpy.array(datatime)
709 datatime = numpy.array(datatime)
709
710
710 return datatime
711 return datatime
711
712
712 def getChannelIndexList(self):
713 def getChannelIndexList(self):
713
714
714 return list(range(self.nChannels))
715 return list(range(self.nChannels))
715
716
716 def getNoise(self, type=1):
717 def getNoise(self, type=1):
717
718
718
719
719 if type == 1:
720 if type == 1:
720 noise = self.getNoisebyHildebrand()
721 noise = self.getNoisebyHildebrand()
721
722
722 if type == 2:
723 if type == 2:
723 noise = self.getNoisebySort()
724 noise = self.getNoisebySort()
724
725
725 if type == 3:
726 if type == 3:
726 noise = self.getNoisebyWindow()
727 noise = self.getNoisebyWindow()
727
728
728 return noise
729 return noise
729
730
730 @property
731 @property
731 def timeInterval(self):
732 def timeInterval(self):
732
733
733 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
734 timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt
734
735
735 return timeInterval
736 return timeInterval
736
737
737 @property
738 @property
738 def ippSeconds(self):
739 def ippSeconds(self):
739 '''
740 '''
740 '''
741 '''
741 return self.ipp_sec
742 return self.ipp_sec
742
743
743 noise = property(getNoise, "I'm the 'nHeights' property.")
744 noise = property(getNoise, "I'm the 'nHeights' property.")
744
745
745
746
746 class Correlation(JROData):
747 class Correlation(JROData):
747
748
748 def __init__(self):
749 def __init__(self):
749 '''
750 '''
750 Constructor
751 Constructor
751 '''
752 '''
752 self.radarControllerHeaderObj = RadarControllerHeader()
753 self.radarControllerHeaderObj = RadarControllerHeader()
753 self.systemHeaderObj = SystemHeader()
754 self.systemHeaderObj = SystemHeader()
754 self.type = "Correlation"
755 self.type = "Correlation"
755 self.data = None
756 self.data = None
756 self.dtype = None
757 self.dtype = None
757 self.nProfiles = None
758 self.nProfiles = None
758 self.heightList = None
759 self.heightList = None
759 self.channelList = None
760 self.channelList = None
760 self.flagNoData = True
761 self.flagNoData = True
761 self.flagDiscontinuousBlock = False
762 self.flagDiscontinuousBlock = False
762 self.utctime = None
763 self.utctime = None
763 self.timeZone = 0
764 self.timeZone = 0
764 self.dstFlag = None
765 self.dstFlag = None
765 self.errorCount = None
766 self.errorCount = None
766 self.blocksize = None
767 self.blocksize = None
767 self.flagDecodeData = False # asumo q la data no esta decodificada
768 self.flagDecodeData = False # asumo q la data no esta decodificada
768 self.flagDeflipData = False # asumo q la data no esta sin flip
769 self.flagDeflipData = False # asumo q la data no esta sin flip
769 self.pairsList = None
770 self.pairsList = None
770 self.nPoints = None
771 self.nPoints = None
771
772
772 def getPairsList(self):
773 def getPairsList(self):
773
774
774 return self.pairsList
775 return self.pairsList
775
776
776 def getNoise(self, mode=2):
777 def getNoise(self, mode=2):
777
778
778 indR = numpy.where(self.lagR == 0)[0][0]
779 indR = numpy.where(self.lagR == 0)[0][0]
779 indT = numpy.where(self.lagT == 0)[0][0]
780 indT = numpy.where(self.lagT == 0)[0][0]
780
781
781 jspectra0 = self.data_corr[:, :, indR, :]
782 jspectra0 = self.data_corr[:, :, indR, :]
782 jspectra = copy.copy(jspectra0)
783 jspectra = copy.copy(jspectra0)
783
784
784 num_chan = jspectra.shape[0]
785 num_chan = jspectra.shape[0]
785 num_hei = jspectra.shape[2]
786 num_hei = jspectra.shape[2]
786
787
787 freq_dc = jspectra.shape[1] / 2
788 freq_dc = jspectra.shape[1] / 2
788 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
789 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
789
790
790 if ind_vel[0] < 0:
791 if ind_vel[0] < 0:
791 ind_vel[list(range(0, 1))] = ind_vel[list(
792 ind_vel[list(range(0, 1))] = ind_vel[list(
792 range(0, 1))] + self.num_prof
793 range(0, 1))] + self.num_prof
793
794
794 if mode == 1:
795 if mode == 1:
795 jspectra[:, freq_dc, :] = (
796 jspectra[:, freq_dc, :] = (
796 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
797 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
797
798
798 if mode == 2:
799 if mode == 2:
799
800
800 vel = numpy.array([-2, -1, 1, 2])
801 vel = numpy.array([-2, -1, 1, 2])
801 xx = numpy.zeros([4, 4])
802 xx = numpy.zeros([4, 4])
802
803
803 for fil in range(4):
804 for fil in range(4):
804 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
805 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
805
806
806 xx_inv = numpy.linalg.inv(xx)
807 xx_inv = numpy.linalg.inv(xx)
807 xx_aux = xx_inv[0, :]
808 xx_aux = xx_inv[0, :]
808
809
809 for ich in range(num_chan):
810 for ich in range(num_chan):
810 yy = jspectra[ich, ind_vel, :]
811 yy = jspectra[ich, ind_vel, :]
811 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
812 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
812
813
813 junkid = jspectra[ich, freq_dc, :] <= 0
814 junkid = jspectra[ich, freq_dc, :] <= 0
814 cjunkid = sum(junkid)
815 cjunkid = sum(junkid)
815
816
816 if cjunkid.any():
817 if cjunkid.any():
817 jspectra[ich, freq_dc, junkid.nonzero()] = (
818 jspectra[ich, freq_dc, junkid.nonzero()] = (
818 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
819 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
819
820
820 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
821 noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :]
821
822
822 return noise
823 return noise
823
824
824 @property
825 @property
825 def timeInterval(self):
826 def timeInterval(self):
826
827
827 return self.ippSeconds * self.nCohInt * self.nProfiles
828 return self.ippSeconds * self.nCohInt * self.nProfiles
828
829
829 def splitFunctions(self):
830 def splitFunctions(self):
830
831
831 pairsList = self.pairsList
832 pairsList = self.pairsList
832 ccf_pairs = []
833 ccf_pairs = []
833 acf_pairs = []
834 acf_pairs = []
834 ccf_ind = []
835 ccf_ind = []
835 acf_ind = []
836 acf_ind = []
836 for l in range(len(pairsList)):
837 for l in range(len(pairsList)):
837 chan0 = pairsList[l][0]
838 chan0 = pairsList[l][0]
838 chan1 = pairsList[l][1]
839 chan1 = pairsList[l][1]
839
840
840 # Obteniendo pares de Autocorrelacion
841 # Obteniendo pares de Autocorrelacion
841 if chan0 == chan1:
842 if chan0 == chan1:
842 acf_pairs.append(chan0)
843 acf_pairs.append(chan0)
843 acf_ind.append(l)
844 acf_ind.append(l)
844 else:
845 else:
845 ccf_pairs.append(pairsList[l])
846 ccf_pairs.append(pairsList[l])
846 ccf_ind.append(l)
847 ccf_ind.append(l)
847
848
848 data_acf = self.data_cf[acf_ind]
849 data_acf = self.data_cf[acf_ind]
849 data_ccf = self.data_cf[ccf_ind]
850 data_ccf = self.data_cf[ccf_ind]
850
851
851 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
852 return acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf
852
853
853 @property
854 @property
854 def normFactor(self):
855 def normFactor(self):
855 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
856 acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions()
856 acf_pairs = numpy.array(acf_pairs)
857 acf_pairs = numpy.array(acf_pairs)
857 normFactor = numpy.zeros((self.nPairs, self.nHeights))
858 normFactor = numpy.zeros((self.nPairs, self.nHeights))
858
859
859 for p in range(self.nPairs):
860 for p in range(self.nPairs):
860 pair = self.pairsList[p]
861 pair = self.pairsList[p]
861
862
862 ch0 = pair[0]
863 ch0 = pair[0]
863 ch1 = pair[1]
864 ch1 = pair[1]
864
865
865 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
866 ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1)
866 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
867 ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1)
867 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
868 normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max)
868
869
869 return normFactor
870 return normFactor
870
871
871
872
872 class Parameters(Spectra):
873 class Parameters(Spectra):
873
874
874 groupList = None # List of Pairs, Groups, etc
875 groupList = None # List of Pairs, Groups, etc
875 data_param = None # Parameters obtained
876 data_param = None # Parameters obtained
876 data_pre = None # Data Pre Parametrization
877 data_pre = None # Data Pre Parametrization
877 data_SNR = None # Signal to Noise Ratio
878 data_SNR = None # Signal to Noise Ratio
879 data_outlier = None
878 abscissaList = None # Abscissa, can be velocities, lags or time
880 abscissaList = None # Abscissa, can be velocities, lags or time
879 utctimeInit = None # Initial UTC time
881 utctimeInit = None # Initial UTC time
880 paramInterval = None # Time interval to calculate Parameters in seconds
882 paramInterval = None # Time interval to calculate Parameters in seconds
881 useLocalTime = True
883 useLocalTime = True
882 # Fitting
884 # Fitting
883 data_error = None # Error of the estimation
885 data_error = None # Error of the estimation
884 constants = None
886 constants = None
885 library = None
887 library = None
886 # Output signal
888 # Output signal
887 outputInterval = None # Time interval to calculate output signal in seconds
889 outputInterval = None # Time interval to calculate output signal in seconds
888 data_output = None # Out signal
890 data_output = None # Out signal
889 nAvg = None
891 nAvg = None
890 noise_estimation = None
892 noise_estimation = None
891 GauSPC = None # Fit gaussian SPC
893 GauSPC = None # Fit gaussian SPC
892
894 max_nIncohInt = 1
893 def __init__(self):
895 def __init__(self):
894 '''
896 '''
895 Constructor
897 Constructor
896 '''
898 '''
897 self.radarControllerHeaderObj = RadarControllerHeader()
899 self.radarControllerHeaderObj = RadarControllerHeader()
898 self.systemHeaderObj = SystemHeader()
900 self.systemHeaderObj = SystemHeader()
899 self.type = "Parameters"
901 self.type = "Parameters"
900 self.timeZone = 0
902 self.timeZone = 0
901
903
902 def getTimeRange1(self, interval):
904 def getTimeRange1(self, interval):
903
905
904 datatime = []
906 datatime = []
905
907
906 if self.useLocalTime:
908 if self.useLocalTime:
907 time1 = self.utctimeInit - self.timeZone * 60
909 time1 = self.utctimeInit - self.timeZone * 60
908 else:
910 else:
909 time1 = self.utctimeInit
911 time1 = self.utctimeInit
910
912
911 datatime.append(time1)
913 datatime.append(time1)
912 datatime.append(time1 + interval)
914 datatime.append(time1 + interval)
913 datatime = numpy.array(datatime)
915 datatime = numpy.array(datatime)
914
916
915 return datatime
917 return datatime
916
918
917 @property
919 @property
918 def timeInterval(self):
920 def timeInterval(self):
919
921
920 if hasattr(self, 'timeInterval1'):
922 if hasattr(self, 'timeInterval1'):
921 return self.timeInterval1
923 return self.timeInterval1
922 else:
924 else:
923 return self.paramInterval
925 return self.paramInterval
924
926
925 def setValue(self, value):
927 def setValue(self, value):
926
928
927 print("This property should not be initialized")
929 print("This property should not be initialized")
928
930
929 return
931 return
930
932
931 def getNoise(self):
933 def getNoise(self):
932
934
933 return self.spc_noise
935 return self.spc_noise
934
936
935 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
937 noise = property(getNoise, setValue, "I'm the 'Noise' property.")
936
938
937
939
938 class PlotterData(object):
940 class PlotterData(object):
939 '''
941 '''
940 Object to hold data to be plotted
942 Object to hold data to be plotted
941 '''
943 '''
942
944
943 MAXNUMX = 200
945 MAXNUMX = 200
944 MAXNUMY = 200
946 MAXNUMY = 200
945
947
946 def __init__(self, code, exp_code, localtime=True):
948 def __init__(self, code, exp_code, localtime=True):
947
949
948 self.key = code
950 self.key = code
949 self.exp_code = exp_code
951 self.exp_code = exp_code
950 self.ready = False
952 self.ready = False
951 self.flagNoData = False
953 self.flagNoData = False
952 self.localtime = localtime
954 self.localtime = localtime
953 self.data = {}
955 self.data = {}
954 self.meta = {}
956 self.meta = {}
955 self.__heights = []
957 self.__heights = []
956
958
957 def __str__(self):
959 def __str__(self):
958 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
960 dum = ['{}{}'.format(key, self.shape(key)) for key in self.data]
959 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
961 return 'Data[{}][{}]'.format(';'.join(dum), len(self.times))
960
962
961 def __len__(self):
963 def __len__(self):
962 return len(self.data)
964 return len(self.data)
963
965
964 def __getitem__(self, key):
966 def __getitem__(self, key):
965 if isinstance(key, int):
967 if isinstance(key, int):
966 return self.data[self.times[key]]
968 return self.data[self.times[key]]
967 elif isinstance(key, str):
969 elif isinstance(key, str):
968 ret = numpy.array([self.data[x][key] for x in self.times])
970 ret = numpy.array([self.data[x][key] for x in self.times])
969 if ret.ndim > 1:
971 if ret.ndim > 1:
970 ret = numpy.swapaxes(ret, 0, 1)
972 ret = numpy.swapaxes(ret, 0, 1)
971 return ret
973 return ret
972
974
973 def __contains__(self, key):
975 def __contains__(self, key):
974 return key in self.data[self.min_time]
976 return key in self.data[self.min_time]
975
977
976 def setup(self):
978 def setup(self):
977 '''
979 '''
978 Configure object
980 Configure object
979 '''
981 '''
980 self.type = ''
982 self.type = ''
981 self.ready = False
983 self.ready = False
982 del self.data
984 del self.data
983 self.data = {}
985 self.data = {}
984 self.__heights = []
986 self.__heights = []
985 self.__all_heights = set()
987 self.__all_heights = set()
986
988
987 def shape(self, key):
989 def shape(self, key):
988 '''
990 '''
989 Get the shape of the one-element data for the given key
991 Get the shape of the one-element data for the given key
990 '''
992 '''
991
993
992 if len(self.data[self.min_time][key]):
994 if len(self.data[self.min_time][key]):
993 return self.data[self.min_time][key].shape
995 return self.data[self.min_time][key].shape
994 return (0,)
996 return (0,)
995
997
996 def update(self, data, tm, meta={}):
998 def update(self, data, tm, meta={}):
997 '''
999 '''
998 Update data object with new dataOut
1000 Update data object with new dataOut
999 '''
1001 '''
1000
1002
1001 self.data[tm] = data
1003 self.data[tm] = data
1002
1004
1003 for key, value in meta.items():
1005 for key, value in meta.items():
1004 setattr(self, key, value)
1006 setattr(self, key, value)
1005
1007
1006 def normalize_heights(self):
1008 def normalize_heights(self):
1007 '''
1009 '''
1008 Ensure same-dimension of the data for different heighList
1010 Ensure same-dimension of the data for different heighList
1009 '''
1011 '''
1010
1012
1011 H = numpy.array(list(self.__all_heights))
1013 H = numpy.array(list(self.__all_heights))
1012 H.sort()
1014 H.sort()
1013 for key in self.data:
1015 for key in self.data:
1014 shape = self.shape(key)[:-1] + H.shape
1016 shape = self.shape(key)[:-1] + H.shape
1015 for tm, obj in list(self.data[key].items()):
1017 for tm, obj in list(self.data[key].items()):
1016 h = self.__heights[self.times.tolist().index(tm)]
1018 h = self.__heights[self.times.tolist().index(tm)]
1017 if H.size == h.size:
1019 if H.size == h.size:
1018 continue
1020 continue
1019 index = numpy.where(numpy.in1d(H, h))[0]
1021 index = numpy.where(numpy.in1d(H, h))[0]
1020 dummy = numpy.zeros(shape) + numpy.nan
1022 dummy = numpy.zeros(shape) + numpy.nan
1021 if len(shape) == 2:
1023 if len(shape) == 2:
1022 dummy[:, index] = obj
1024 dummy[:, index] = obj
1023 else:
1025 else:
1024 dummy[index] = obj
1026 dummy[index] = obj
1025 self.data[key][tm] = dummy
1027 self.data[key][tm] = dummy
1026
1028
1027 self.__heights = [H for tm in self.times]
1029 self.__heights = [H for tm in self.times]
1028
1030
1029 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1031 def jsonify(self, tm, plot_name, plot_type, decimate=False):
1030 '''
1032 '''
1031 Convert data to json
1033 Convert data to json
1032 '''
1034 '''
1033
1035
1034 meta = {}
1036 meta = {}
1035 meta['xrange'] = []
1037 meta['xrange'] = []
1036 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1038 dy = int(len(self.yrange)/self.MAXNUMY) + 1
1037 tmp = self.data[tm][self.key]
1039 tmp = self.data[tm][self.key]
1038 shape = tmp.shape
1040 shape = tmp.shape
1039 if len(shape) == 2:
1041 if len(shape) == 2:
1040 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1042 data = self.roundFloats(self.data[tm][self.key][::, ::dy].tolist())
1041 elif len(shape) == 3:
1043 elif len(shape) == 3:
1042 dx = int(self.data[tm][self.key].shape[1]/self.MAXNUMX) + 1
1044 dx = int(self.data[tm][self.key].shape[1]/self.MAXNUMX) + 1
1043 data = self.roundFloats(
1045 data = self.roundFloats(
1044 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1046 self.data[tm][self.key][::, ::dx, ::dy].tolist())
1045 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1047 meta['xrange'] = self.roundFloats(self.xrange[2][::dx].tolist())
1046 else:
1048 else:
1047 data = self.roundFloats(self.data[tm][self.key].tolist())
1049 data = self.roundFloats(self.data[tm][self.key].tolist())
1048
1050
1049 ret = {
1051 ret = {
1050 'plot': plot_name,
1052 'plot': plot_name,
1051 'code': self.exp_code,
1053 'code': self.exp_code,
1052 'time': float(tm),
1054 'time': float(tm),
1053 'data': data,
1055 'data': data,
1054 }
1056 }
1055 meta['type'] = plot_type
1057 meta['type'] = plot_type
1056 meta['interval'] = float(self.interval)
1058 meta['interval'] = float(self.interval)
1057 meta['localtime'] = self.localtime
1059 meta['localtime'] = self.localtime
1058 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1060 meta['yrange'] = self.roundFloats(self.yrange[::dy].tolist())
1059 meta.update(self.meta)
1061 meta.update(self.meta)
1060 ret['metadata'] = meta
1062 ret['metadata'] = meta
1061 return json.dumps(ret)
1063 return json.dumps(ret)
1062
1064
1063 @property
1065 @property
1064 def times(self):
1066 def times(self):
1065 '''
1067 '''
1066 Return the list of times of the current data
1068 Return the list of times of the current data
1067 '''
1069 '''
1068
1070
1069 ret = [t for t in self.data]
1071 ret = [t for t in self.data]
1070 ret.sort()
1072 ret.sort()
1071 return numpy.array(ret)
1073 return numpy.array(ret)
1072
1074
1073 @property
1075 @property
1074 def min_time(self):
1076 def min_time(self):
1075 '''
1077 '''
1076 Return the minimun time value
1078 Return the minimun time value
1077 '''
1079 '''
1078
1080
1079 return self.times[0]
1081 return self.times[0]
1080
1082
1081 @property
1083 @property
1082 def max_time(self):
1084 def max_time(self):
1083 '''
1085 '''
1084 Return the maximun time value
1086 Return the maximun time value
1085 '''
1087 '''
1086
1088
1087 return self.times[-1]
1089 return self.times[-1]
1088
1090
1089 # @property
1091 # @property
1090 # def heights(self):
1092 # def heights(self):
1091 # '''
1093 # '''
1092 # Return the list of heights of the current data
1094 # Return the list of heights of the current data
1093 # '''
1095 # '''
1094
1096
1095 # return numpy.array(self.__heights[-1])
1097 # return numpy.array(self.__heights[-1])
1096
1098
1097 @staticmethod
1099 @staticmethod
1098 def roundFloats(obj):
1100 def roundFloats(obj):
1099 if isinstance(obj, list):
1101 if isinstance(obj, list):
1100 return list(map(PlotterData.roundFloats, obj))
1102 return list(map(PlotterData.roundFloats, obj))
1101 elif isinstance(obj, float):
1103 elif isinstance(obj, float):
1102 return round(obj, 2)
1104 return round(obj, 2)
@@ -1,705 +1,705
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 """Base class to create plot operations
5 """Base class to create plot operations
6
6
7 """
7 """
8
8
9 import os
9 import os
10 import sys
10 import sys
11 import zmq
11 import zmq
12 import time
12 import time
13 import numpy
13 import numpy
14 import datetime
14 import datetime
15 from collections import deque
15 from collections import deque
16 from functools import wraps
16 from functools import wraps
17 from threading import Thread
17 from threading import Thread
18 import matplotlib
18 import matplotlib
19
19
20 if 'BACKEND' in os.environ:
20 if 'BACKEND' in os.environ:
21 matplotlib.use(os.environ['BACKEND'])
21 matplotlib.use(os.environ['BACKEND'])
22 elif 'linux' in sys.platform:
22 elif 'linux' in sys.platform:
23 matplotlib.use("TkAgg")
23 matplotlib.use("TkAgg")
24 elif 'darwin' in sys.platform:
24 elif 'darwin' in sys.platform:
25 matplotlib.use('MacOSX')
25 matplotlib.use('MacOSX')
26 else:
26 else:
27 from schainpy.utils import log
27 from schainpy.utils import log
28 log.warning('Using default Backend="Agg"', 'INFO')
28 log.warning('Using default Backend="Agg"', 'INFO')
29 matplotlib.use('Agg')
29 matplotlib.use('Agg')
30
30
31 import matplotlib.pyplot as plt
31 import matplotlib.pyplot as plt
32 from matplotlib.patches import Polygon
32 from matplotlib.patches import Polygon
33 from mpl_toolkits.axes_grid1 import make_axes_locatable
33 from mpl_toolkits.axes_grid1 import make_axes_locatable
34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
34 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
35
35
36 from schainpy.model.data.jrodata import PlotterData
36 from schainpy.model.data.jrodata import PlotterData
37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
37 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
38 from schainpy.utils import log
38 from schainpy.utils import log
39
39
40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
40 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
41 blu_values = matplotlib.pyplot.get_cmap(
41 blu_values = matplotlib.pyplot.get_cmap(
42 'seismic_r', 20)(numpy.arange(20))[10:15]
42 'seismic_r', 20)(numpy.arange(20))[10:15]
43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
43 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
44 'jro', numpy.vstack((blu_values, jet_values)))
44 'jro', numpy.vstack((blu_values, jet_values)))
45 matplotlib.pyplot.register_cmap(cmap=ncmap)
45 matplotlib.pyplot.register_cmap(cmap=ncmap)
46
46
47 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
47 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
48 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
48 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
49
49
50 EARTH_RADIUS = 6.3710e3
50 EARTH_RADIUS = 6.3710e3
51
51
52 def ll2xy(lat1, lon1, lat2, lon2):
52 def ll2xy(lat1, lon1, lat2, lon2):
53
53
54 p = 0.017453292519943295
54 p = 0.017453292519943295
55 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
55 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
56 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
56 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
57 r = 12742 * numpy.arcsin(numpy.sqrt(a))
57 r = 12742 * numpy.arcsin(numpy.sqrt(a))
58 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
58 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
59 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
59 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
60 theta = -theta + numpy.pi/2
60 theta = -theta + numpy.pi/2
61 return r*numpy.cos(theta), r*numpy.sin(theta)
61 return r*numpy.cos(theta), r*numpy.sin(theta)
62
62
63
63
64 def km2deg(km):
64 def km2deg(km):
65 '''
65 '''
66 Convert distance in km to degrees
66 Convert distance in km to degrees
67 '''
67 '''
68
68
69 return numpy.rad2deg(km/EARTH_RADIUS)
69 return numpy.rad2deg(km/EARTH_RADIUS)
70
70
71
71
72 def figpause(interval):
72 def figpause(interval):
73 backend = plt.rcParams['backend']
73 backend = plt.rcParams['backend']
74 if backend in matplotlib.rcsetup.interactive_bk:
74 if backend in matplotlib.rcsetup.interactive_bk:
75 figManager = matplotlib._pylab_helpers.Gcf.get_active()
75 figManager = matplotlib._pylab_helpers.Gcf.get_active()
76 if figManager is not None:
76 if figManager is not None:
77 canvas = figManager.canvas
77 canvas = figManager.canvas
78 if canvas.figure.stale:
78 if canvas.figure.stale:
79 canvas.draw()
79 canvas.draw()
80 try:
80 try:
81 canvas.start_event_loop(interval)
81 canvas.start_event_loop(interval)
82 except:
82 except:
83 pass
83 pass
84 return
84 return
85
85
86 def popup(message):
86 def popup(message):
87 '''
87 '''
88 '''
88 '''
89
89
90 fig = plt.figure(figsize=(12, 8), facecolor='r')
90 fig = plt.figure(figsize=(12, 8), facecolor='r')
91 text = '\n'.join([s.strip() for s in message.split(':')])
91 text = '\n'.join([s.strip() for s in message.split(':')])
92 fig.text(0.01, 0.5, text, ha='left', va='center',
92 fig.text(0.01, 0.5, text, ha='left', va='center',
93 size='20', weight='heavy', color='w')
93 size='20', weight='heavy', color='w')
94 fig.show()
94 fig.show()
95 figpause(1000)
95 figpause(1000)
96
96
97
97
98 class Throttle(object):
98 class Throttle(object):
99 '''
99 '''
100 Decorator that prevents a function from being called more than once every
100 Decorator that prevents a function from being called more than once every
101 time period.
101 time period.
102 To create a function that cannot be called more than once a minute, but
102 To create a function that cannot be called more than once a minute, but
103 will sleep until it can be called:
103 will sleep until it can be called:
104 @Throttle(minutes=1)
104 @Throttle(minutes=1)
105 def foo():
105 def foo():
106 pass
106 pass
107
107
108 for i in range(10):
108 for i in range(10):
109 foo()
109 foo()
110 print "This function has run %s times." % i
110 print "This function has run %s times." % i
111 '''
111 '''
112
112
113 def __init__(self, seconds=0, minutes=0, hours=0):
113 def __init__(self, seconds=0, minutes=0, hours=0):
114 self.throttle_period = datetime.timedelta(
114 self.throttle_period = datetime.timedelta(
115 seconds=seconds, minutes=minutes, hours=hours
115 seconds=seconds, minutes=minutes, hours=hours
116 )
116 )
117
117
118 self.time_of_last_call = datetime.datetime.min
118 self.time_of_last_call = datetime.datetime.min
119
119
120 def __call__(self, fn):
120 def __call__(self, fn):
121 @wraps(fn)
121 @wraps(fn)
122 def wrapper(*args, **kwargs):
122 def wrapper(*args, **kwargs):
123 coerce = kwargs.pop('coerce', None)
123 coerce = kwargs.pop('coerce', None)
124 if coerce:
124 if coerce:
125 self.time_of_last_call = datetime.datetime.now()
125 self.time_of_last_call = datetime.datetime.now()
126 return fn(*args, **kwargs)
126 return fn(*args, **kwargs)
127 else:
127 else:
128 now = datetime.datetime.now()
128 now = datetime.datetime.now()
129 time_since_last_call = now - self.time_of_last_call
129 time_since_last_call = now - self.time_of_last_call
130 time_left = self.throttle_period - time_since_last_call
130 time_left = self.throttle_period - time_since_last_call
131
131
132 if time_left > datetime.timedelta(seconds=0):
132 if time_left > datetime.timedelta(seconds=0):
133 return
133 return
134
134
135 self.time_of_last_call = datetime.datetime.now()
135 self.time_of_last_call = datetime.datetime.now()
136 return fn(*args, **kwargs)
136 return fn(*args, **kwargs)
137
137
138 return wrapper
138 return wrapper
139
139
140 def apply_throttle(value):
140 def apply_throttle(value):
141
141
142 @Throttle(seconds=value)
142 @Throttle(seconds=value)
143 def fnThrottled(fn):
143 def fnThrottled(fn):
144 fn()
144 fn()
145
145
146 return fnThrottled
146 return fnThrottled
147
147
148
148
149 @MPDecorator
149 @MPDecorator
150 class Plot(Operation):
150 class Plot(Operation):
151 """Base class for Schain plotting operations
151 """Base class for Schain plotting operations
152
152
153 This class should never be use directtly you must subclass a new operation,
153 This class should never be use directtly you must subclass a new operation,
154 children classes must be defined as follow:
154 children classes must be defined as follow:
155
155
156 ExamplePlot(Plot):
156 ExamplePlot(Plot):
157
157
158 CODE = 'code'
158 CODE = 'code'
159 colormap = 'jet'
159 colormap = 'jet'
160 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
160 plot_type = 'pcolor' # options are ('pcolor', 'pcolorbuffer', 'scatter', 'scatterbuffer')
161
161
162 def setup(self):
162 def setup(self):
163 pass
163 pass
164
164
165 def plot(self):
165 def plot(self):
166 pass
166 pass
167
167
168 """
168 """
169
169
170 CODE = 'Figure'
170 CODE = 'Figure'
171 colormap = 'jet'
171 colormap = 'jet'
172 bgcolor = 'white'
172 bgcolor = 'white'
173 buffering = True
173 buffering = True
174 __missing = 1E30
174 __missing = 1E30
175
175
176 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
176 __attrs__ = ['show', 'save', 'ymin', 'ymax', 'zmin', 'zmax', 'title',
177 'showprofile']
177 'showprofile']
178
178
179 def __init__(self):
179 def __init__(self):
180
180
181 Operation.__init__(self)
181 Operation.__init__(self)
182 self.isConfig = False
182 self.isConfig = False
183 self.isPlotConfig = False
183 self.isPlotConfig = False
184 self.save_time = 0
184 self.save_time = 0
185 self.sender_time = 0
185 self.sender_time = 0
186 self.data = None
186 self.data = None
187 self.firsttime = True
187 self.firsttime = True
188 self.sender_queue = deque(maxlen=10)
188 self.sender_queue = deque(maxlen=10)
189 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
189 self.plots_adjust = {'left': 0.125, 'right': 0.9, 'bottom': 0.15, 'top': 0.9, 'wspace': 0.2, 'hspace': 0.2}
190
190
191 def __fmtTime(self, x, pos):
191 def __fmtTime(self, x, pos):
192 '''
192 '''
193 '''
193 '''
194 if self.t_units == "h_m":
194 if self.t_units == "h_m":
195 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
195 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
196 if self.t_units == "h":
196 if self.t_units == "h":
197 return '{}'.format(self.getDateTime(x).strftime('%H'))
197 return '{}'.format(self.getDateTime(x).strftime('%H'))
198
198
199 def __setup(self, **kwargs):
199 def __setup(self, **kwargs):
200 '''
200 '''
201 Initialize variables
201 Initialize variables
202 '''
202 '''
203
203
204 self.figures = []
204 self.figures = []
205 self.axes = []
205 self.axes = []
206 self.cb_axes = []
206 self.cb_axes = []
207 self.pf_axes = []
207 self.pf_axes = []
208 self.localtime = kwargs.pop('localtime', True)
208 self.localtime = kwargs.pop('localtime', True)
209 self.show = kwargs.get('show', True)
209 self.show = kwargs.get('show', True)
210 self.save = kwargs.get('save', False)
210 self.save = kwargs.get('save', False)
211 self.save_period = kwargs.get('save_period', 0)
211 self.save_period = kwargs.get('save_period', 0)
212 self.colormap = kwargs.get('colormap', self.colormap)
212 self.colormap = kwargs.get('colormap', self.colormap)
213 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
213 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
214 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
214 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
215 self.colormaps = kwargs.get('colormaps', None)
215 self.colormaps = kwargs.get('colormaps', None)
216 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
216 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
217 self.showprofile = kwargs.get('showprofile', False)
217 self.showprofile = kwargs.get('showprofile', False)
218 self.title = kwargs.get('wintitle', self.CODE.upper())
218 self.title = kwargs.get('wintitle', self.CODE.upper())
219 self.cb_label = kwargs.get('cb_label', None)
219 self.cb_label = kwargs.get('cb_label', None)
220 self.cb_labels = kwargs.get('cb_labels', None)
220 self.cb_labels = kwargs.get('cb_labels', None)
221 self.labels = kwargs.get('labels', None)
221 self.labels = kwargs.get('labels', None)
222 self.xaxis = kwargs.get('xaxis', 'frequency')
222 self.xaxis = kwargs.get('xaxis', 'frequency')
223 self.zmin = kwargs.get('zmin', None)
223 self.zmin = kwargs.get('zmin', None)
224 self.zmax = kwargs.get('zmax', None)
224 self.zmax = kwargs.get('zmax', None)
225 self.zlimits = kwargs.get('zlimits', None)
225 self.zlimits = kwargs.get('zlimits', None)
226 self.xmin = kwargs.get('xmin', None)
226 self.xmin = kwargs.get('xmin', None)
227 self.xmax = kwargs.get('xmax', None)
227 self.xmax = kwargs.get('xmax', None)
228 self.xrange = kwargs.get('xrange', 12)
228 self.xrange = kwargs.get('xrange', 12)
229 self.xscale = kwargs.get('xscale', None)
229 self.xscale = kwargs.get('xscale', None)
230 self.ymin = kwargs.get('ymin', None)
230 self.ymin = kwargs.get('ymin', None)
231 self.ymax = kwargs.get('ymax', None)
231 self.ymax = kwargs.get('ymax', None)
232 self.yscale = kwargs.get('yscale', None)
232 self.yscale = kwargs.get('yscale', None)
233 self.xlabel = kwargs.get('xlabel', None)
233 self.xlabel = kwargs.get('xlabel', None)
234 self.attr_time = kwargs.get('attr_time', 'utctime')
234 self.attr_time = kwargs.get('attr_time', 'utctime')
235 self.attr_data = kwargs.get('attr_data', 'data_param')
235 self.attr_data = kwargs.get('attr_data', 'data_param')
236 self.decimation = kwargs.get('decimation', None)
236 self.decimation = kwargs.get('decimation', None)
237 self.oneFigure = kwargs.get('oneFigure', True)
237 self.oneFigure = kwargs.get('oneFigure', True)
238 self.width = kwargs.get('width', None)
238 self.width = kwargs.get('width', None)
239 self.height = kwargs.get('height', None)
239 self.height = kwargs.get('height', None)
240 self.colorbar = kwargs.get('colorbar', True)
240 self.colorbar = kwargs.get('colorbar', True)
241 self.factors = kwargs.get('factors', range(18))
241 self.factors = kwargs.get('factors', range(18))
242 self.channels = kwargs.get('channels', None)
242 self.channels = kwargs.get('channels', None)
243 self.titles = kwargs.get('titles', [])
243 self.titles = kwargs.get('titles', [])
244 self.polar = False
244 self.polar = False
245 self.type = kwargs.get('type', 'iq')
245 self.type = kwargs.get('type', 'iq')
246 self.grid = kwargs.get('grid', False)
246 self.grid = kwargs.get('grid', False)
247 self.pause = kwargs.get('pause', False)
247 self.pause = kwargs.get('pause', False)
248 self.save_code = kwargs.get('save_code', self.CODE)
248 self.save_code = kwargs.get('save_code', self.CODE)
249 self.throttle = kwargs.get('throttle', 0)
249 self.throttle = kwargs.get('throttle', 0)
250 self.exp_code = kwargs.get('exp_code', None)
250 self.exp_code = kwargs.get('exp_code', None)
251 self.server = kwargs.get('server', False)
251 self.server = kwargs.get('server', False)
252 self.sender_period = kwargs.get('sender_period', 60)
252 self.sender_period = kwargs.get('sender_period', 60)
253 self.tag = kwargs.get('tag', '')
253 self.tag = kwargs.get('tag', '')
254 self.height_index = kwargs.get('height_index', [])
254 self.height_index = kwargs.get('height_index', [])
255 self.__throttle_plot = apply_throttle(self.throttle)
255 self.__throttle_plot = apply_throttle(self.throttle)
256 code = self.attr_data if self.attr_data else self.CODE
256 code = self.attr_data if self.attr_data else self.CODE
257 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
257 self.data = PlotterData(self.CODE, self.exp_code, self.localtime)
258 self.tmin = kwargs.get('tmin', None)
258 self.tmin = kwargs.get('tmin', None)
259 self.t_units = kwargs.get('t_units', "h_m")
259 self.t_units = kwargs.get('t_units', "h_m")
260 self.selectedHeightsList = kwargs.get('selectedHeightsList', [])
260 self.selectedHeightsList = kwargs.get('selectedHeightsList', [])
261 if isinstance(self.selectedHeightsList, int):
261 if isinstance(self.selectedHeightsList, int):
262 self.selectedHeightsList = [self.selectedHeightsList]
262 self.selectedHeightsList = [self.selectedHeightsList]
263
263
264 if self.server:
264 if self.server:
265 if not self.server.startswith('tcp://'):
265 if not self.server.startswith('tcp://'):
266 self.server = 'tcp://{}'.format(self.server)
266 self.server = 'tcp://{}'.format(self.server)
267 log.success(
267 log.success(
268 'Sending to server: {}'.format(self.server),
268 'Sending to server: {}'.format(self.server),
269 self.name
269 self.name
270 )
270 )
271
271
272 if isinstance(self.attr_data, str):
272 if isinstance(self.attr_data, str):
273 self.attr_data = [self.attr_data]
273 self.attr_data = [self.attr_data]
274
274
275 def __setup_plot(self):
275 def __setup_plot(self):
276 '''
276 '''
277 Common setup for all figures, here figures and axes are created
277 Common setup for all figures, here figures and axes are created
278 '''
278 '''
279
279
280 self.setup()
280 self.setup()
281
281
282 self.time_label = 'LT' if self.localtime else 'UTC'
282 self.time_label = 'LT' if self.localtime else 'UTC'
283
283
284 if self.width is None:
284 if self.width is None:
285 self.width = 8
285 self.width = 8
286
286
287 self.figures = []
287 self.figures = []
288 self.axes = []
288 self.axes = []
289 self.cb_axes = []
289 self.cb_axes = []
290 self.pf_axes = []
290 self.pf_axes = []
291 self.cmaps = []
291 self.cmaps = []
292
292
293 size = '15%' if self.ncols == 1 else '30%'
293 size = '15%' if self.ncols == 1 else '30%'
294 pad = '4%' if self.ncols == 1 else '8%'
294 pad = '4%' if self.ncols == 1 else '8%'
295
295
296 if self.oneFigure:
296 if self.oneFigure:
297 if self.height is None:
297 if self.height is None:
298 self.height = 1.4 * self.nrows + 1
298 self.height = 1.4 * self.nrows + 1
299 fig = plt.figure(figsize=(self.width, self.height),
299 fig = plt.figure(figsize=(self.width, self.height),
300 edgecolor='k',
300 edgecolor='k',
301 facecolor='w')
301 facecolor='w')
302 self.figures.append(fig)
302 self.figures.append(fig)
303 for n in range(self.nplots):
303 for n in range(self.nplots):
304 ax = fig.add_subplot(self.nrows, self.ncols,
304 ax = fig.add_subplot(self.nrows, self.ncols,
305 n + 1, polar=self.polar)
305 n + 1, polar=self.polar)
306 ax.tick_params(labelsize=8)
306 ax.tick_params(labelsize=8)
307 ax.firsttime = True
307 ax.firsttime = True
308 ax.index = 0
308 ax.index = 0
309 ax.press = None
309 ax.press = None
310 self.axes.append(ax)
310 self.axes.append(ax)
311 if self.showprofile:
311 if self.showprofile:
312 cax = self.__add_axes(ax, size=size, pad=pad)
312 cax = self.__add_axes(ax, size=size, pad=pad)
313 cax.tick_params(labelsize=8)
313 cax.tick_params(labelsize=8)
314 self.pf_axes.append(cax)
314 self.pf_axes.append(cax)
315 else:
315 else:
316 if self.height is None:
316 if self.height is None:
317 self.height = 3
317 self.height = 3
318 for n in range(self.nplots):
318 for n in range(self.nplots):
319 fig = plt.figure(figsize=(self.width, self.height),
319 fig = plt.figure(figsize=(self.width, self.height),
320 edgecolor='k',
320 edgecolor='k',
321 facecolor='w')
321 facecolor='w')
322 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
322 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
323 ax.tick_params(labelsize=8)
323 ax.tick_params(labelsize=8)
324 ax.firsttime = True
324 ax.firsttime = True
325 ax.index = 0
325 ax.index = 0
326 ax.press = None
326 ax.press = None
327 self.figures.append(fig)
327 self.figures.append(fig)
328 self.axes.append(ax)
328 self.axes.append(ax)
329 if self.showprofile:
329 if self.showprofile:
330 cax = self.__add_axes(ax, size=size, pad=pad)
330 cax = self.__add_axes(ax, size=size, pad=pad)
331 cax.tick_params(labelsize=8)
331 cax.tick_params(labelsize=8)
332 self.pf_axes.append(cax)
332 self.pf_axes.append(cax)
333
333
334 for n in range(self.nrows):
334 for n in range(self.nrows):
335 if self.colormaps is not None:
335 if self.colormaps is not None:
336 cmap = plt.get_cmap(self.colormaps[n])
336 cmap = plt.get_cmap(self.colormaps[n])
337 else:
337 else:
338 cmap = plt.get_cmap(self.colormap)
338 cmap = plt.get_cmap(self.colormap)
339 cmap.set_bad(self.bgcolor, 1.)
339 cmap.set_bad(self.bgcolor, 1.)
340 self.cmaps.append(cmap)
340 self.cmaps.append(cmap)
341
341
342 def __add_axes(self, ax, size='30%', pad='8%'):
342 def __add_axes(self, ax, size='30%', pad='8%'):
343 '''
343 '''
344 Add new axes to the given figure
344 Add new axes to the given figure
345 '''
345 '''
346 divider = make_axes_locatable(ax)
346 divider = make_axes_locatable(ax)
347 nax = divider.new_horizontal(size=size, pad=pad)
347 nax = divider.new_horizontal(size=size, pad=pad)
348 ax.figure.add_axes(nax)
348 ax.figure.add_axes(nax)
349 return nax
349 return nax
350
350
351 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
351 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
352 '''
352 '''
353 Create a masked array for missing data
353 Create a masked array for missing data
354 '''
354 '''
355 if x_buffer.shape[0] < 2:
355 if x_buffer.shape[0] < 2:
356 return x_buffer, y_buffer, z_buffer
356 return x_buffer, y_buffer, z_buffer
357
357
358 deltas = x_buffer[1:] - x_buffer[0:-1]
358 deltas = x_buffer[1:] - x_buffer[0:-1]
359 x_median = numpy.median(deltas)
359 x_median = numpy.median(deltas)
360
360
361 index = numpy.where(deltas > 5 * x_median)
361 index = numpy.where(deltas > 5 * x_median)
362
362
363 if len(index[0]) != 0:
363 if len(index[0]) != 0:
364 z_buffer[::, index[0], ::] = self.__missing
364 z_buffer[::, index[0], ::] = self.__missing
365 z_buffer = numpy.ma.masked_inside(z_buffer,
365 z_buffer = numpy.ma.masked_inside(z_buffer,
366 0.99 * self.__missing,
366 0.99 * self.__missing,
367 1.01 * self.__missing)
367 1.01 * self.__missing)
368
368
369 return x_buffer, y_buffer, z_buffer
369 return x_buffer, y_buffer, z_buffer
370
370
371 def decimate(self):
371 def decimate(self):
372
372
373 # dx = int(len(self.x)/self.__MAXNUMX) + 1
373 # dx = int(len(self.x)/self.__MAXNUMX) + 1
374 dy = int(len(self.y) / self.decimation) + 1
374 dy = int(len(self.y) / self.decimation) + 1
375
375
376 # x = self.x[::dx]
376 # x = self.x[::dx]
377 x = self.x
377 x = self.x
378 y = self.y[::dy]
378 y = self.y[::dy]
379 z = self.z[::, ::, ::dy]
379 z = self.z[::, ::, ::dy]
380
380
381 return x, y, z
381 return x, y, z
382
382
383 def format(self):
383 def format(self):
384 '''
384 '''
385 Set min and max values, labels, ticks and titles
385 Set min and max values, labels, ticks and titles
386 '''
386 '''
387
387
388 for n, ax in enumerate(self.axes):
388 for n, ax in enumerate(self.axes):
389 if ax.firsttime:
389 if ax.firsttime:
390 if self.xaxis != 'time':
390 if self.xaxis != 'time':
391 xmin = self.xmin
391 xmin = self.xmin
392 xmax = self.xmax
392 xmax = self.xmax
393 else:
393 else:
394 xmin = self.tmin
394 xmin = self.tmin
395 xmax = self.tmin + self.xrange*60*60
395 xmax = self.tmin + self.xrange*60*60
396 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
396 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
397 if self.t_units == "h_m":
397 if self.t_units == "h_m":
398 ax.xaxis.set_major_locator(LinearLocator(9))
398 ax.xaxis.set_major_locator(LinearLocator(9))
399 if self.t_units == "h":
399 if self.t_units == "h":
400 ax.xaxis.set_major_locator(LinearLocator(int((xmax-xmin)/3600)+1))
400 ax.xaxis.set_major_locator(LinearLocator(int((xmax-xmin)/3600)+1))
401 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
401 ymin = self.ymin if self.ymin is not None else numpy.nanmin(self.y[numpy.isfinite(self.y)])
402 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
402 ymax = self.ymax if self.ymax is not None else numpy.nanmax(self.y[numpy.isfinite(self.y)])
403 ax.set_facecolor(self.bgcolor)
403 ax.set_facecolor(self.bgcolor)
404 if self.xscale:
404 if self.xscale:
405 ax.xaxis.set_major_formatter(FuncFormatter(
405 ax.xaxis.set_major_formatter(FuncFormatter(
406 lambda x, pos: '{0:g}'.format(x*self.xscale)))
406 lambda x, pos: '{0:g}'.format(x*self.xscale)))
407 if self.yscale:
407 if self.yscale:
408 ax.yaxis.set_major_formatter(FuncFormatter(
408 ax.yaxis.set_major_formatter(FuncFormatter(
409 lambda x, pos: '{0:g}'.format(x*self.yscale)))
409 lambda x, pos: '{0:g}'.format(x*self.yscale)))
410 if self.xlabel is not None:
410 if self.xlabel is not None:
411 ax.set_xlabel(self.xlabel)
411 ax.set_xlabel(self.xlabel)
412 if self.ylabel is not None:
412 if self.ylabel is not None:
413 ax.set_ylabel(self.ylabel)
413 ax.set_ylabel(self.ylabel)
414 if self.showprofile:
414 if self.showprofile:
415 self.pf_axes[n].set_ylim(ymin, ymax)
415 self.pf_axes[n].set_ylim(ymin, ymax)
416 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
416 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
417 self.pf_axes[n].set_xlabel('dB')
417 self.pf_axes[n].set_xlabel('dB')
418 self.pf_axes[n].grid(b=True, axis='x')
418 self.pf_axes[n].grid(b=True, axis='x')
419 [tick.set_visible(False)
419 [tick.set_visible(False)
420 for tick in self.pf_axes[n].get_yticklabels()]
420 for tick in self.pf_axes[n].get_yticklabels()]
421 if self.colorbar:
421 if self.colorbar:
422 ax.cbar = plt.colorbar(
422 ax.cbar = plt.colorbar(
423 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
423 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
424 ax.cbar.ax.tick_params(labelsize=8)
424 ax.cbar.ax.tick_params(labelsize=8)
425 ax.cbar.ax.press = None
425 ax.cbar.ax.press = None
426 if self.cb_label:
426 if self.cb_label:
427 ax.cbar.set_label(self.cb_label, size=8)
427 ax.cbar.set_label(self.cb_label, size=8)
428 elif self.cb_labels:
428 elif self.cb_labels:
429 ax.cbar.set_label(self.cb_labels[n], size=8)
429 ax.cbar.set_label(self.cb_labels[n], size=8)
430 else:
430 else:
431 ax.cbar = None
431 ax.cbar = None
432 ax.set_xlim(xmin, xmax)
432 ax.set_xlim(xmin, xmax)
433 ax.set_ylim(ymin, ymax)
433 ax.set_ylim(ymin, ymax)
434 ax.firsttime = False
434 ax.firsttime = False
435 if self.grid:
435 if self.grid:
436 ax.grid(True)
436 ax.grid(True)
437
437
438 if not self.polar:
438 if not self.polar:
439 ax.set_title('{} {} {}'.format(
439 ax.set_title('{} {} {}'.format(
440 self.titles[n],
440 self.titles[n],
441 self.getDateTime(self.data.max_time).strftime(
441 self.getDateTime(self.data.max_time).strftime(
442 '%Y-%m-%d %H:%M:%S'),
442 '%Y-%m-%d %H:%M:%S'),
443 self.time_label),
443 self.time_label),
444 size=8)
444 size=8)
445 else:
445 else:
446
446
447 ax.set_title('{}'.format(self.titles[n]), size=8)
447 ax.set_title('{}'.format(self.titles[n]), size=8)
448 ax.set_ylim(0, 90)
448 ax.set_ylim(0, 90)
449 ax.set_yticks(numpy.arange(0, 90, 20))
449 ax.set_yticks(numpy.arange(0, 90, 20))
450 ax.yaxis.labelpad = 40
450 ax.yaxis.labelpad = 40
451
451
452 if self.firsttime:
452 if self.firsttime:
453 for n, fig in enumerate(self.figures):
453 for n, fig in enumerate(self.figures):
454 fig.subplots_adjust(**self.plots_adjust)
454 fig.subplots_adjust(**self.plots_adjust)
455 self.firsttime = False
455 self.firsttime = False
456
456
457 def clear_figures(self):
457 def clear_figures(self):
458 '''
458 '''
459 Reset axes for redraw plots
459 Reset axes for redraw plots
460 '''
460 '''
461
461
462 for ax in self.axes+self.pf_axes+self.cb_axes:
462 for ax in self.axes+self.pf_axes+self.cb_axes:
463 ax.clear()
463 ax.clear()
464 ax.firsttime = True
464 ax.firsttime = True
465 if hasattr(ax, 'cbar') and ax.cbar:
465 if hasattr(ax, 'cbar') and ax.cbar:
466 ax.cbar.remove()
466 ax.cbar.remove()
467
467
468 def __plot(self):
468 def __plot(self):
469 '''
469 '''
470 Main function to plot, format and save figures
470 Main function to plot, format and save figures
471 '''
471 '''
472
472
473 self.plot()
473 self.plot()
474 self.format()
474 self.format()
475
475
476 for n, fig in enumerate(self.figures):
476 for n, fig in enumerate(self.figures):
477 if self.nrows == 0 or self.nplots == 0:
477 if self.nrows == 0 or self.nplots == 0:
478 log.warning('No data', self.name)
478 log.warning('No data', self.name)
479 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
479 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
480 fig.canvas.manager.set_window_title(self.CODE)
480 fig.canvas.manager.set_window_title(self.CODE)
481 continue
481 continue
482
482
483 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
483 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
484 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
484 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
485
485
486 fig.canvas.draw()
486 fig.canvas.draw()
487 if self.show:
487 if self.show:
488 fig.show()
488 fig.show()
489 figpause(0.01)
489 figpause(0.01)
490
490
491 if self.save:
491 if self.save:
492 self.save_figure(n)
492 self.save_figure(n)
493
493
494 if self.server:
494 if self.server:
495 self.send_to_server()
495 self.send_to_server()
496
496
497 def __update(self, dataOut, timestamp):
497 def __update(self, dataOut, timestamp):
498 '''
498 '''
499 '''
499 '''
500
500
501 metadata = {
501 metadata = {
502 'yrange': dataOut.heightList,
502 'yrange': dataOut.heightList,
503 'interval': dataOut.timeInterval,
503 'interval': dataOut.timeInterval,
504 'channels': dataOut.channelList
504 'channels': dataOut.channelList
505 }
505 }
506 data, meta = self.update(dataOut)
506 data, meta = self.update(dataOut)
507 metadata.update(meta)
507 metadata.update(meta)
508 self.data.update(data, timestamp, metadata)
508 self.data.update(data, timestamp, metadata)
509
509
510 def save_figure(self, n):
510 def save_figure(self, n):
511 '''
511 '''
512 '''
512 '''
513
513
514 if (self.data.max_time - self.save_time) <= self.save_period:
514 if (self.data.max_time - self.save_time) <= self.save_period:
515 return
515 return
516
516
517 self.save_time = self.data.max_time
517 self.save_time = self.data.max_time
518
518
519 fig = self.figures[n]
519 fig = self.figures[n]
520
520
521 if self.throttle == 0:
521 if self.throttle == 0:
522 figname = os.path.join(
522 figname = os.path.join(
523 self.save,
523 self.save,
524 self.save_code,
524 self.save_code,
525 '{}_{}.png'.format(
525 '{}_{}.png'.format(
526 self.save_code,
526 self.save_code,
527 self.getDateTime(self.data.max_time).strftime(
527 self.getDateTime(self.data.max_time).strftime(
528 '%Y%m%d_%H%M%S'
528 '%Y%m%d_%H%M%S'
529 ),
529 ),
530 )
530 )
531 )
531 )
532 log.log('Saving figure: {}'.format(figname), self.name)
532 log.log('Saving figure: {}'.format(figname), self.name)
533 if not os.path.isdir(os.path.dirname(figname)):
533 if not os.path.isdir(os.path.dirname(figname)):
534 os.makedirs(os.path.dirname(figname))
534 os.makedirs(os.path.dirname(figname))
535 fig.savefig(figname)
535 fig.savefig(figname)
536
536
537 figname = os.path.join(
537 figname = os.path.join(
538 self.save,
538 self.save,
539 '{}_{}.png'.format(
539 '{}_{}.png'.format(
540 self.save_code,
540 self.save_code,
541 self.getDateTime(self.data.min_time).strftime(
541 self.getDateTime(self.data.min_time).strftime(
542 '%Y%m%d'
542 '%Y%m%d'
543 ),
543 ),
544 )
544 )
545 )
545 )
546
546
547 log.log('Saving figure: {}'.format(figname), self.name)
547 log.log('Saving figure: {}'.format(figname), self.name)
548 if not os.path.isdir(os.path.dirname(figname)):
548 if not os.path.isdir(os.path.dirname(figname)):
549 os.makedirs(os.path.dirname(figname))
549 os.makedirs(os.path.dirname(figname))
550 fig.savefig(figname)
550 fig.savefig(figname)
551
551
552 def send_to_server(self):
552 def send_to_server(self):
553 '''
553 '''
554 '''
554 '''
555
555
556 if self.exp_code == None:
556 if self.exp_code == None:
557 log.warning('Missing `exp_code` skipping sending to server...')
557 log.warning('Missing `exp_code` skipping sending to server...')
558
558
559 last_time = self.data.max_time
559 last_time = self.data.max_time
560 interval = last_time - self.sender_time
560 interval = last_time - self.sender_time
561 if interval < self.sender_period:
561 if interval < self.sender_period:
562 return
562 return
563
563
564 self.sender_time = last_time
564 self.sender_time = last_time
565
565
566 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
566 attrs = ['titles', 'zmin', 'zmax', 'tag', 'ymin', 'ymax']
567 for attr in attrs:
567 for attr in attrs:
568 value = getattr(self, attr)
568 value = getattr(self, attr)
569 if value:
569 if value:
570 if isinstance(value, (numpy.float32, numpy.float64)):
570 if isinstance(value, (numpy.float32, numpy.float64)):
571 value = round(float(value), 2)
571 value = round(float(value), 2)
572 self.data.meta[attr] = value
572 self.data.meta[attr] = value
573 if self.colormap == 'jet':
573 if self.colormap == 'jet':
574 self.data.meta['colormap'] = 'Jet'
574 self.data.meta['colormap'] = 'Jet'
575 elif 'RdBu' in self.colormap:
575 elif 'RdBu' in self.colormap:
576 self.data.meta['colormap'] = 'RdBu'
576 self.data.meta['colormap'] = 'RdBu'
577 else:
577 else:
578 self.data.meta['colormap'] = 'Viridis'
578 self.data.meta['colormap'] = 'Viridis'
579 self.data.meta['interval'] = int(interval)
579 self.data.meta['interval'] = int(interval)
580
580
581 self.sender_queue.append(last_time)
581 self.sender_queue.append(last_time)
582
582
583 while True:
583 while 1:
584 try:
584 try:
585 tm = self.sender_queue.popleft()
585 tm = self.sender_queue.popleft()
586 except IndexError:
586 except IndexError:
587 break
587 break
588 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
588 msg = self.data.jsonify(tm, self.save_code, self.plot_type)
589 self.socket.send_string(msg)
589 self.socket.send_string(msg)
590 socks = dict(self.poll.poll(2000))
590 socks = dict(self.poll.poll(2000))
591 if socks.get(self.socket) == zmq.POLLIN:
591 if socks.get(self.socket) == zmq.POLLIN:
592 reply = self.socket.recv_string()
592 reply = self.socket.recv_string()
593 if reply == 'ok':
593 if reply == 'ok':
594 log.log("Response from server ok", self.name)
594 log.log("Response from server ok", self.name)
595 time.sleep(0.1)
595 time.sleep(0.1)
596 continue
596 continue
597 else:
597 else:
598 log.warning(
598 log.warning(
599 "Malformed reply from server: {}".format(reply), self.name)
599 "Malformed reply from server: {}".format(reply), self.name)
600 else:
600 else:
601 log.warning(
601 log.warning(
602 "No response from server, retrying...", self.name)
602 "No response from server, retrying...", self.name)
603 self.sender_queue.appendleft(tm)
603 self.sender_queue.appendleft(tm)
604 self.socket.setsockopt(zmq.LINGER, 0)
604 self.socket.setsockopt(zmq.LINGER, 0)
605 self.socket.close()
605 self.socket.close()
606 self.poll.unregister(self.socket)
606 self.poll.unregister(self.socket)
607 self.socket = self.context.socket(zmq.REQ)
607 self.socket = self.context.socket(zmq.REQ)
608 self.socket.connect(self.server)
608 self.socket.connect(self.server)
609 self.poll.register(self.socket, zmq.POLLIN)
609 self.poll.register(self.socket, zmq.POLLIN)
610 break
610 break
611
611
612 def setup(self):
612 def setup(self):
613 '''
613 '''
614 This method should be implemented in the child class, the following
614 This method should be implemented in the child class, the following
615 attributes should be set:
615 attributes should be set:
616
616
617 self.nrows: number of rows
617 self.nrows: number of rows
618 self.ncols: number of cols
618 self.ncols: number of cols
619 self.nplots: number of plots (channels or pairs)
619 self.nplots: number of plots (channels or pairs)
620 self.ylabel: label for Y axes
620 self.ylabel: label for Y axes
621 self.titles: list of axes title
621 self.titles: list of axes title
622
622
623 '''
623 '''
624 raise NotImplementedError
624 raise NotImplementedError
625
625
626 def plot(self):
626 def plot(self):
627 '''
627 '''
628 Must be defined in the child class, the actual plotting method
628 Must be defined in the child class, the actual plotting method
629 '''
629 '''
630 raise NotImplementedError
630 raise NotImplementedError
631
631
632 def update(self, dataOut):
632 def update(self, dataOut):
633 '''
633 '''
634 Must be defined in the child class, update self.data with new data
634 Must be defined in the child class, update self.data with new data
635 '''
635 '''
636
636
637 data = {
637 data = {
638 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
638 self.CODE: getattr(dataOut, 'data_{}'.format(self.CODE))
639 }
639 }
640 meta = {}
640 meta = {}
641
641
642 return data, meta
642 return data, meta
643
643
644 def run(self, dataOut, **kwargs):
644 def run(self, dataOut, **kwargs):
645 '''
645 '''
646 Main plotting routine
646 Main plotting routine
647 '''
647 '''
648 if self.isConfig is False:
648 if self.isConfig is False:
649 self.__setup(**kwargs)
649 self.__setup(**kwargs)
650
650
651 if self.localtime:
651 if self.localtime:
652 self.getDateTime = datetime.datetime.fromtimestamp
652 self.getDateTime = datetime.datetime.fromtimestamp
653 else:
653 else:
654 self.getDateTime = datetime.datetime.utcfromtimestamp
654 self.getDateTime = datetime.datetime.utcfromtimestamp
655
655
656 self.data.setup()
656 self.data.setup()
657 self.isConfig = True
657 self.isConfig = True
658 if self.server:
658 if self.server:
659 self.context = zmq.Context()
659 self.context = zmq.Context()
660 self.socket = self.context.socket(zmq.REQ)
660 self.socket = self.context.socket(zmq.REQ)
661 self.socket.connect(self.server)
661 self.socket.connect(self.server)
662 self.poll = zmq.Poller()
662 self.poll = zmq.Poller()
663 self.poll.register(self.socket, zmq.POLLIN)
663 self.poll.register(self.socket, zmq.POLLIN)
664
664
665 tm = getattr(dataOut, self.attr_time)
665 tm = getattr(dataOut, self.attr_time)
666
666
667 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
667 if self.data and 'time' in self.xaxis and (tm - self.tmin) >= self.xrange*60*60:
668 self.save_time = tm
668 self.save_time = tm
669 self.__plot()
669 self.__plot()
670 self.tmin += self.xrange*60*60
670 self.tmin += self.xrange*60*60
671 self.data.setup()
671 self.data.setup()
672 self.clear_figures()
672 self.clear_figures()
673
673
674 self.__update(dataOut, tm)
674 self.__update(dataOut, tm)
675
675
676 if self.isPlotConfig is False:
676 if self.isPlotConfig is False:
677 self.__setup_plot()
677 self.__setup_plot()
678 self.isPlotConfig = True
678 self.isPlotConfig = True
679 if self.xaxis == 'time':
679 if self.xaxis == 'time':
680 dt = self.getDateTime(tm)
680 dt = self.getDateTime(tm)
681 if self.xmin is None:
681 if self.xmin is None:
682 self.tmin = tm
682 self.tmin = tm
683 self.xmin = dt.hour
683 self.xmin = dt.hour
684 minutes = (self.xmin-int(self.xmin)) * 60
684 minutes = (self.xmin-int(self.xmin)) * 60
685 seconds = (minutes - int(minutes)) * 60
685 seconds = (minutes - int(minutes)) * 60
686 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
686 self.tmin = (dt.replace(hour=int(self.xmin), minute=int(minutes), second=int(seconds)) -
687 datetime.datetime(1970, 1, 1)).total_seconds()
687 datetime.datetime(1970, 1, 1)).total_seconds()
688 if self.localtime:
688 if self.localtime:
689 self.tmin += time.timezone
689 self.tmin += time.timezone
690
690
691 if self.xmin is not None and self.xmax is not None:
691 if self.xmin is not None and self.xmax is not None:
692 self.xrange = self.xmax - self.xmin
692 self.xrange = self.xmax - self.xmin
693
693
694 if self.throttle == 0:
694 if self.throttle == 0:
695 self.__plot()
695 self.__plot()
696 else:
696 else:
697 self.__throttle_plot(self.__plot)#, coerce=coerce)
697 self.__throttle_plot(self.__plot)#, coerce=coerce)
698
698
699 def close(self):
699 def close(self):
700
700
701 if self.data and not self.data.flagNoData:
701 if self.data and not self.data.flagNoData:
702 self.save_time = 0
702 self.save_time = 0
703 self.__plot()
703 self.__plot()
704 if self.data and not self.data.flagNoData and self.pause:
704 if self.data and not self.data.flagNoData and self.pause:
705 figpause(10)
705 figpause(10)
@@ -1,362 +1,362
1 import os
1 import os
2 import datetime
2 import datetime
3 import numpy
3 import numpy
4
4
5 from schainpy.model.graphics.jroplot_base import Plot, plt
5 from schainpy.model.graphics.jroplot_base import Plot, plt
6 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot
6 from schainpy.model.graphics.jroplot_spectra import SpectraPlot, RTIPlot, CoherencePlot
7 from schainpy.utils import log
7 from schainpy.utils import log
8
8
9 EARTH_RADIUS = 6.3710e3
9 EARTH_RADIUS = 6.3710e3
10
10
11
11
12 def ll2xy(lat1, lon1, lat2, lon2):
12 def ll2xy(lat1, lon1, lat2, lon2):
13
13
14 p = 0.017453292519943295
14 p = 0.017453292519943295
15 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
15 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
16 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
16 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
17 r = 12742 * numpy.arcsin(numpy.sqrt(a))
17 r = 12742 * numpy.arcsin(numpy.sqrt(a))
18 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
18 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
19 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
19 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
20 theta = -theta + numpy.pi/2
20 theta = -theta + numpy.pi/2
21 return r*numpy.cos(theta), r*numpy.sin(theta)
21 return r*numpy.cos(theta), r*numpy.sin(theta)
22
22
23
23
24 def km2deg(km):
24 def km2deg(km):
25 '''
25 '''
26 Convert distance in km to degrees
26 Convert distance in km to degrees
27 '''
27 '''
28
28
29 return numpy.rad2deg(km/EARTH_RADIUS)
29 return numpy.rad2deg(km/EARTH_RADIUS)
30
30
31
31
32
32
33 class SpectralMomentsPlot(SpectraPlot):
33 class SpectralMomentsPlot(SpectraPlot):
34 '''
34 '''
35 Plot for Spectral Moments
35 Plot for Spectral Moments
36 '''
36 '''
37 CODE = 'spc_moments'
37 CODE = 'spc_moments'
38 colormap = 'jet'
38 colormap = 'jet'
39 plot_type = 'pcolor'
39 plot_type = 'pcolor'
40
40
41
41
42 class SnrPlot(RTIPlot):
42 class SnrPlot(RTIPlot):
43 '''
43 '''
44 Plot for SNR Data
44 Plot for SNR Data
45 '''
45 '''
46
46
47 CODE = 'snr'
47 CODE = 'snr'
48 colormap = 'jet'
48 colormap = 'jet'
49
49
50 def update(self, dataOut):
50 def update(self, dataOut):
51 if len(self.channelList) == 0:
51 if len(self.channelList) == 0:
52 self.update_list(dataOut)
52 self.update_list(dataOut)
53
53
54 meta = {}
54 meta = {}
55 data = {
55 data = {
56 'snr': 10 * numpy.log10(dataOut.data_snr)
56 'snr': 10 * numpy.log10(dataOut.data_snr * dataOut.nIncohInt/ dataOut.max_nIncohInt)
57 }
57 }
58 #print(data['snr'])
58 #print(data['snr'])
59 return data, meta
59 return data, meta
60
60
61 class DopplerPlot(RTIPlot):
61 class DopplerPlot(RTIPlot):
62 '''
62 '''
63 Plot for DOPPLER Data (1st moment)
63 Plot for DOPPLER Data (1st moment)
64 '''
64 '''
65
65
66 CODE = 'dop'
66 CODE = 'dop'
67 colormap = 'jet'
67 colormap = 'jet'
68
68
69 def update(self, dataOut):
69 def update(self, dataOut):
70 self.update_list(dataOut)
70 self.update_list(dataOut)
71 data = {
71 data = {
72 'dop': 10*numpy.log10(dataOut.data_dop)
72 'dop': 10*numpy.log10(dataOut.data_dop)
73 }
73 }
74
74
75 return data, {}
75 return data, {}
76
76
77 class PowerPlot(RTIPlot):
77 class PowerPlot(RTIPlot):
78 '''
78 '''
79 Plot for Power Data (0 moment)
79 Plot for Power Data (0 moment)
80 '''
80 '''
81
81
82 CODE = 'pow'
82 CODE = 'pow'
83 colormap = 'jet'
83 colormap = 'jet'
84
84
85 def update(self, dataOut):
85 def update(self, dataOut):
86 self.update_list(dataOut)
86 self.update_list(dataOut)
87 data = {
87 data = {
88 'pow': 10*numpy.log10(dataOut.data_pow)
88 'pow': 10*numpy.log10(dataOut.data_pow)
89 }
89 }
90 try:
90 try:
91 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
91 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
92 except:
92 except:
93 pass
93 pass
94 return data, {}
94 return data, {}
95
95
96 class SpectralWidthPlot(RTIPlot):
96 class SpectralWidthPlot(RTIPlot):
97 '''
97 '''
98 Plot for Spectral Width Data (2nd moment)
98 Plot for Spectral Width Data (2nd moment)
99 '''
99 '''
100
100
101 CODE = 'width'
101 CODE = 'width'
102 colormap = 'jet'
102 colormap = 'jet'
103
103
104 def update(self, dataOut):
104 def update(self, dataOut):
105 self.update_list(dataOut)
105 self.update_list(dataOut)
106 data = {
106 data = {
107 'width': dataOut.data_width
107 'width': dataOut.data_width
108 }
108 }
109 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
109 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
110 return data, {}
110 return data, {}
111
111
112 class SkyMapPlot(Plot):
112 class SkyMapPlot(Plot):
113 '''
113 '''
114 Plot for meteors detection data
114 Plot for meteors detection data
115 '''
115 '''
116
116
117 CODE = 'param'
117 CODE = 'param'
118
118
119 def setup(self):
119 def setup(self):
120
120
121 self.ncols = 1
121 self.ncols = 1
122 self.nrows = 1
122 self.nrows = 1
123 self.width = 7.2
123 self.width = 7.2
124 self.height = 7.2
124 self.height = 7.2
125 self.nplots = 1
125 self.nplots = 1
126 self.xlabel = 'Zonal Zenith Angle (deg)'
126 self.xlabel = 'Zonal Zenith Angle (deg)'
127 self.ylabel = 'Meridional Zenith Angle (deg)'
127 self.ylabel = 'Meridional Zenith Angle (deg)'
128 self.polar = True
128 self.polar = True
129 self.ymin = -180
129 self.ymin = -180
130 self.ymax = 180
130 self.ymax = 180
131 self.colorbar = False
131 self.colorbar = False
132
132
133 def plot(self):
133 def plot(self):
134
134
135 arrayParameters = numpy.concatenate(self.data['param'])
135 arrayParameters = numpy.concatenate(self.data['param'])
136 error = arrayParameters[:, -1]
136 error = arrayParameters[:, -1]
137 indValid = numpy.where(error == 0)[0]
137 indValid = numpy.where(error == 0)[0]
138 finalMeteor = arrayParameters[indValid, :]
138 finalMeteor = arrayParameters[indValid, :]
139 finalAzimuth = finalMeteor[:, 3]
139 finalAzimuth = finalMeteor[:, 3]
140 finalZenith = finalMeteor[:, 4]
140 finalZenith = finalMeteor[:, 4]
141
141
142 x = finalAzimuth * numpy.pi / 180
142 x = finalAzimuth * numpy.pi / 180
143 y = finalZenith
143 y = finalZenith
144
144
145 ax = self.axes[0]
145 ax = self.axes[0]
146
146
147 if ax.firsttime:
147 if ax.firsttime:
148 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
148 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
149 else:
149 else:
150 ax.plot.set_data(x, y)
150 ax.plot.set_data(x, y)
151
151
152 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
152 dt1 = self.getDateTime(self.data.min_time).strftime('%y/%m/%d %H:%M:%S')
153 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
153 dt2 = self.getDateTime(self.data.max_time).strftime('%y/%m/%d %H:%M:%S')
154 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
154 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
155 dt2,
155 dt2,
156 len(x))
156 len(x))
157 self.titles[0] = title
157 self.titles[0] = title
158
158
159
159
160 class GenericRTIPlot(Plot):
160 class GenericRTIPlot(Plot):
161 '''
161 '''
162 Plot for data_xxxx object
162 Plot for data_xxxx object
163 '''
163 '''
164
164
165 CODE = 'param'
165 CODE = 'param'
166 colormap = 'viridis'
166 colormap = 'viridis'
167 plot_type = 'pcolorbuffer'
167 plot_type = 'pcolorbuffer'
168
168
169 def setup(self):
169 def setup(self):
170 self.xaxis = 'time'
170 self.xaxis = 'time'
171 self.ncols = 1
171 self.ncols = 1
172 self.nrows = self.data.shape('param')[0]
172 self.nrows = self.data.shape('param')[0]
173 self.nplots = self.nrows
173 self.nplots = self.nrows
174 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
174 self.plots_adjust.update({'hspace':0.8, 'left': 0.1, 'bottom': 0.08, 'right':0.95, 'top': 0.95})
175
175
176 if not self.xlabel:
176 if not self.xlabel:
177 self.xlabel = 'Time'
177 self.xlabel = 'Time'
178
178
179 self.ylabel = 'Height [km]'
179 self.ylabel = 'Height [km]'
180 if not self.titles:
180 if not self.titles:
181 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
181 self.titles = ['Param {}'.format(x) for x in range(self.nrows)]
182
182
183 def update(self, dataOut):
183 def update(self, dataOut):
184
184
185 data = {
185 data = {
186 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
186 'param' : numpy.concatenate([getattr(dataOut, attr) for attr in self.attr_data], axis=0)
187 }
187 }
188
188
189 meta = {}
189 meta = {}
190
190
191 return data, meta
191 return data, meta
192
192
193 def plot(self):
193 def plot(self):
194 # self.data.normalize_heights()
194 # self.data.normalize_heights()
195 self.x = self.data.times
195 self.x = self.data.times
196 self.y = self.data.yrange
196 self.y = self.data.yrange
197 self.z = self.data['param']
197 self.z = self.data['param']
198
198
199 self.z = numpy.ma.masked_invalid(self.z)
199 self.z = numpy.ma.masked_invalid(self.z)
200
200
201 if self.decimation is None:
201 if self.decimation is None:
202 x, y, z = self.fill_gaps(self.x, self.y, self.z)
202 x, y, z = self.fill_gaps(self.x, self.y, self.z)
203 else:
203 else:
204 x, y, z = self.fill_gaps(*self.decimate())
204 x, y, z = self.fill_gaps(*self.decimate())
205
205
206 for n, ax in enumerate(self.axes):
206 for n, ax in enumerate(self.axes):
207
207
208 self.zmax = self.zmax if self.zmax is not None else numpy.max(
208 self.zmax = self.zmax if self.zmax is not None else numpy.max(
209 self.z[n])
209 self.z[n])
210 self.zmin = self.zmin if self.zmin is not None else numpy.min(
210 self.zmin = self.zmin if self.zmin is not None else numpy.min(
211 self.z[n])
211 self.z[n])
212
212
213 if ax.firsttime:
213 if ax.firsttime:
214 if self.zlimits is not None:
214 if self.zlimits is not None:
215 self.zmin, self.zmax = self.zlimits[n]
215 self.zmin, self.zmax = self.zlimits[n]
216
216
217 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
217 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
218 vmin=self.zmin,
218 vmin=self.zmin,
219 vmax=self.zmax,
219 vmax=self.zmax,
220 cmap=self.cmaps[n]
220 cmap=self.cmaps[n]
221 )
221 )
222 else:
222 else:
223 if self.zlimits is not None:
223 if self.zlimits is not None:
224 self.zmin, self.zmax = self.zlimits[n]
224 self.zmin, self.zmax = self.zlimits[n]
225 ax.collections.remove(ax.collections[0])
225 ax.collections.remove(ax.collections[0])
226 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
226 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
227 vmin=self.zmin,
227 vmin=self.zmin,
228 vmax=self.zmax,
228 vmax=self.zmax,
229 cmap=self.cmaps[n]
229 cmap=self.cmaps[n]
230 )
230 )
231
231
232
232
233 class PolarMapPlot(Plot):
233 class PolarMapPlot(Plot):
234 '''
234 '''
235 Plot for weather radar
235 Plot for weather radar
236 '''
236 '''
237
237
238 CODE = 'param'
238 CODE = 'param'
239 colormap = 'seismic'
239 colormap = 'seismic'
240
240
241 def setup(self):
241 def setup(self):
242 self.ncols = 1
242 self.ncols = 1
243 self.nrows = 1
243 self.nrows = 1
244 self.width = 9
244 self.width = 9
245 self.height = 8
245 self.height = 8
246 self.mode = self.data.meta['mode']
246 self.mode = self.data.meta['mode']
247 if self.channels is not None:
247 if self.channels is not None:
248 self.nplots = len(self.channels)
248 self.nplots = len(self.channels)
249 self.nrows = len(self.channels)
249 self.nrows = len(self.channels)
250 else:
250 else:
251 self.nplots = self.data.shape(self.CODE)[0]
251 self.nplots = self.data.shape(self.CODE)[0]
252 self.nrows = self.nplots
252 self.nrows = self.nplots
253 self.channels = list(range(self.nplots))
253 self.channels = list(range(self.nplots))
254 if self.mode == 'E':
254 if self.mode == 'E':
255 self.xlabel = 'Longitude'
255 self.xlabel = 'Longitude'
256 self.ylabel = 'Latitude'
256 self.ylabel = 'Latitude'
257 else:
257 else:
258 self.xlabel = 'Range (km)'
258 self.xlabel = 'Range (km)'
259 self.ylabel = 'Height (km)'
259 self.ylabel = 'Height (km)'
260 self.bgcolor = 'white'
260 self.bgcolor = 'white'
261 self.cb_labels = self.data.meta['units']
261 self.cb_labels = self.data.meta['units']
262 self.lat = self.data.meta['latitude']
262 self.lat = self.data.meta['latitude']
263 self.lon = self.data.meta['longitude']
263 self.lon = self.data.meta['longitude']
264 self.xmin, self.xmax = float(
264 self.xmin, self.xmax = float(
265 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
265 km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon)
266 self.ymin, self.ymax = float(
266 self.ymin, self.ymax = float(
267 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
267 km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat)
268 # self.polar = True
268 # self.polar = True
269
269
270 def plot(self):
270 def plot(self):
271
271
272 for n, ax in enumerate(self.axes):
272 for n, ax in enumerate(self.axes):
273 data = self.data['param'][self.channels[n]]
273 data = self.data['param'][self.channels[n]]
274
274
275 zeniths = numpy.linspace(
275 zeniths = numpy.linspace(
276 0, self.data.meta['max_range'], data.shape[1])
276 0, self.data.meta['max_range'], data.shape[1])
277 if self.mode == 'E':
277 if self.mode == 'E':
278 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
278 azimuths = -numpy.radians(self.data.yrange)+numpy.pi/2
279 r, theta = numpy.meshgrid(zeniths, azimuths)
279 r, theta = numpy.meshgrid(zeniths, azimuths)
280 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
280 x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(
281 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
281 theta)*numpy.cos(numpy.radians(self.data.meta['elevation']))
282 x = km2deg(x) + self.lon
282 x = km2deg(x) + self.lon
283 y = km2deg(y) + self.lat
283 y = km2deg(y) + self.lat
284 else:
284 else:
285 azimuths = numpy.radians(self.data.yrange)
285 azimuths = numpy.radians(self.data.yrange)
286 r, theta = numpy.meshgrid(zeniths, azimuths)
286 r, theta = numpy.meshgrid(zeniths, azimuths)
287 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
287 x, y = r*numpy.cos(theta), r*numpy.sin(theta)
288 self.y = zeniths
288 self.y = zeniths
289
289
290 if ax.firsttime:
290 if ax.firsttime:
291 if self.zlimits is not None:
291 if self.zlimits is not None:
292 self.zmin, self.zmax = self.zlimits[n]
292 self.zmin, self.zmax = self.zlimits[n]
293 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
293 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
294 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
294 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
295 vmin=self.zmin,
295 vmin=self.zmin,
296 vmax=self.zmax,
296 vmax=self.zmax,
297 cmap=self.cmaps[n])
297 cmap=self.cmaps[n])
298 else:
298 else:
299 if self.zlimits is not None:
299 if self.zlimits is not None:
300 self.zmin, self.zmax = self.zlimits[n]
300 self.zmin, self.zmax = self.zlimits[n]
301 ax.collections.remove(ax.collections[0])
301 ax.collections.remove(ax.collections[0])
302 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
302 ax.plt = ax.pcolormesh( # r, theta, numpy.ma.array(data, mask=numpy.isnan(data)),
303 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
303 x, y, numpy.ma.array(data, mask=numpy.isnan(data)),
304 vmin=self.zmin,
304 vmin=self.zmin,
305 vmax=self.zmax,
305 vmax=self.zmax,
306 cmap=self.cmaps[n])
306 cmap=self.cmaps[n])
307
307
308 if self.mode == 'A':
308 if self.mode == 'A':
309 continue
309 continue
310
310
311 # plot district names
311 # plot district names
312 f = open('/data/workspace/schain_scripts/distrito.csv')
312 f = open('/data/workspace/schain_scripts/distrito.csv')
313 for line in f:
313 for line in f:
314 label, lon, lat = [s.strip() for s in line.split(',') if s]
314 label, lon, lat = [s.strip() for s in line.split(',') if s]
315 lat = float(lat)
315 lat = float(lat)
316 lon = float(lon)
316 lon = float(lon)
317 # ax.plot(lon, lat, '.b', ms=2)
317 # ax.plot(lon, lat, '.b', ms=2)
318 ax.text(lon, lat, label.decode('utf8'), ha='center',
318 ax.text(lon, lat, label.decode('utf8'), ha='center',
319 va='bottom', size='8', color='black')
319 va='bottom', size='8', color='black')
320
320
321 # plot limites
321 # plot limites
322 limites = []
322 limites = []
323 tmp = []
323 tmp = []
324 for line in open('/data/workspace/schain_scripts/lima.csv'):
324 for line in open('/data/workspace/schain_scripts/lima.csv'):
325 if '#' in line:
325 if '#' in line:
326 if tmp:
326 if tmp:
327 limites.append(tmp)
327 limites.append(tmp)
328 tmp = []
328 tmp = []
329 continue
329 continue
330 values = line.strip().split(',')
330 values = line.strip().split(',')
331 tmp.append((float(values[0]), float(values[1])))
331 tmp.append((float(values[0]), float(values[1])))
332 for points in limites:
332 for points in limites:
333 ax.add_patch(
333 ax.add_patch(
334 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
334 Polygon(points, ec='k', fc='none', ls='--', lw=0.5))
335
335
336 # plot Cuencas
336 # plot Cuencas
337 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
337 for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'):
338 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
338 f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca))
339 values = [line.strip().split(',') for line in f]
339 values = [line.strip().split(',') for line in f]
340 points = [(float(s[0]), float(s[1])) for s in values]
340 points = [(float(s[0]), float(s[1])) for s in values]
341 ax.add_patch(Polygon(points, ec='b', fc='none'))
341 ax.add_patch(Polygon(points, ec='b', fc='none'))
342
342
343 # plot grid
343 # plot grid
344 for r in (15, 30, 45, 60):
344 for r in (15, 30, 45, 60):
345 ax.add_artist(plt.Circle((self.lon, self.lat),
345 ax.add_artist(plt.Circle((self.lon, self.lat),
346 km2deg(r), color='0.6', fill=False, lw=0.2))
346 km2deg(r), color='0.6', fill=False, lw=0.2))
347 ax.text(
347 ax.text(
348 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
348 self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180),
349 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
349 self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180),
350 '{}km'.format(r),
350 '{}km'.format(r),
351 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
351 ha='center', va='bottom', size='8', color='0.6', weight='heavy')
352
352
353 if self.mode == 'E':
353 if self.mode == 'E':
354 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
354 title = 'El={}$^\circ$'.format(self.data.meta['elevation'])
355 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
355 label = 'E{:02d}'.format(int(self.data.meta['elevation']))
356 else:
356 else:
357 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
357 title = 'Az={}$^\circ$'.format(self.data.meta['azimuth'])
358 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
358 label = 'A{:02d}'.format(int(self.data.meta['azimuth']))
359
359
360 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
360 self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels]
361 self.titles = ['{} {}'.format(
361 self.titles = ['{} {}'.format(
362 self.data.parameters[x], title) for x in self.channels]
362 self.data.parameters[x], title) for x in self.channels]
@@ -1,1180 +1,1187
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 """Classes to plot Spectra data
5 """Classes to plot Spectra data
6
6
7 """
7 """
8
8
9 import os
9 import os
10 import numpy
10 import numpy
11
11
12 from schainpy.model.graphics.jroplot_base import Plot, plt, log
12 from schainpy.model.graphics.jroplot_base import Plot, plt, log
13 from itertools import combinations
13 from itertools import combinations
14 from matplotlib.ticker import LinearLocator
14 from matplotlib.ticker import LinearLocator
15
15
16 class SpectraPlot(Plot):
16 class SpectraPlot(Plot):
17 '''
17 '''
18 Plot for Spectra data
18 Plot for Spectra data
19 '''
19 '''
20
20
21 CODE = 'spc'
21 CODE = 'spc'
22 colormap = 'jet'
22 colormap = 'jet'
23 plot_type = 'pcolor'
23 plot_type = 'pcolor'
24 buffering = False
24 buffering = False
25 channelList = []
25 channelList = []
26 elevationList = []
26 elevationList = []
27 azimuthList = []
27 azimuthList = []
28
28
29 def setup(self):
29 def setup(self):
30
30
31 self.nplots = len(self.data.channels)
31 self.nplots = len(self.data.channels)
32 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
32 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
33 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
33 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
34 self.height = 3.4 * self.nrows
34 self.height = 3.4 * self.nrows
35
35
36 self.cb_label = 'dB'
36 self.cb_label = 'dB'
37 if self.showprofile:
37 if self.showprofile:
38 self.width = 5.2 * self.ncols
38 self.width = 5.2 * self.ncols
39 else:
39 else:
40 self.width = 4.2* self.ncols
40 self.width = 4.2* self.ncols
41 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.12})
41 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.12})
42 self.ylabel = 'Range [km]'
42 self.ylabel = 'Range [km]'
43
43
44
44
45 def update_list(self,dataOut):
45 def update_list(self,dataOut):
46 if len(self.channelList) == 0:
46 if len(self.channelList) == 0:
47 self.channelList = dataOut.channelList
47 self.channelList = dataOut.channelList
48 if len(self.elevationList) == 0:
48 if len(self.elevationList) == 0:
49 self.elevationList = dataOut.elevationList
49 self.elevationList = dataOut.elevationList
50 if len(self.azimuthList) == 0:
50 if len(self.azimuthList) == 0:
51 self.azimuthList = dataOut.azimuthList
51 self.azimuthList = dataOut.azimuthList
52
52
53 def update(self, dataOut):
53 def update(self, dataOut):
54
54
55 self.update_list(dataOut)
55 self.update_list(dataOut)
56 data = {}
56 data = {}
57 meta = {}
57 meta = {}
58 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
58 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
59 data['spc'] = spc
59 data['spc'] = spc
60 data['rti'] = dataOut.getPower()
60 data['rti'] = dataOut.getPower()
61 #data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
61 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
62 noise = 10*numpy.log10(dataOut.getNoise()/float(norm))
63 data['noise'] = noise[0]
64
62 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
65 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
63 if self.CODE == 'spc_moments':
66 if self.CODE == 'spc_moments':
64 data['moments'] = dataOut.moments
67 data['moments'] = dataOut.moments
65
68
66 return data, meta
69 return data, meta
67
70
68 def plot(self):
71 def plot(self):
69 if self.xaxis == "frequency":
72 if self.xaxis == "frequency":
70 x = self.data.xrange[0]
73 x = self.data.xrange[0]
71 self.xlabel = "Frequency (kHz)"
74 self.xlabel = "Frequency (kHz)"
72 elif self.xaxis == "time":
75 elif self.xaxis == "time":
73 x = self.data.xrange[1]
76 x = self.data.xrange[1]
74 self.xlabel = "Time (ms)"
77 self.xlabel = "Time (ms)"
75 else:
78 else:
76 x = self.data.xrange[2]
79 x = self.data.xrange[2]
77 self.xlabel = "Velocity (m/s)"
80 self.xlabel = "Velocity (m/s)"
78
81
79 if self.CODE == 'spc_moments':
82 if self.CODE == 'spc_moments':
80 x = self.data.xrange[2]
83 x = self.data.xrange[2]
81 self.xlabel = "Velocity (m/s)"
84 self.xlabel = "Velocity (m/s)"
82
85
83 self.titles = []
86 self.titles = []
84 y = self.data.yrange
87 y = self.data.yrange
85 self.y = y
88 self.y = y
86
89
87 data = self.data[-1]
90 data = self.data[-1]
88 z = data['spc']
91 z = data['spc']
89 #print(z.shape, x.shape, y.shape)
92 #print(z.shape, x.shape, y.shape)
90 for n, ax in enumerate(self.axes):
93 for n, ax in enumerate(self.axes):
91 #noise = data['noise'][n]
94 noise = self.data['noise'][n]
92 noise=62
95 #print(noise)
93 if self.CODE == 'spc_moments':
96 if self.CODE == 'spc_moments':
94 mean = data['moments'][n, 1]
97 mean = data['moments'][n, 1]
95 if ax.firsttime:
98 if ax.firsttime:
96 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
99 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
97 self.xmin = self.xmin if self.xmin else -self.xmax
100 self.xmin = self.xmin if self.xmin else -self.xmax
98 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
101 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
99 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
102 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
100 ax.plt = ax.pcolormesh(x, y, z[n].T,
103 ax.plt = ax.pcolormesh(x, y, z[n].T,
101 vmin=self.zmin,
104 vmin=self.zmin,
102 vmax=self.zmax,
105 vmax=self.zmax,
103 cmap=plt.get_cmap(self.colormap)
106 cmap=plt.get_cmap(self.colormap)
104 )
107 )
105
108
106 if self.showprofile:
109 if self.showprofile:
107 ax.plt_profile = self.pf_axes[n].plot(
110 ax.plt_profile = self.pf_axes[n].plot(
108 data['rti'][n], y)[0]
111 data['rti'][n], y)[0]
109 # ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
112 # ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
110 # color="k", linestyle="dashed", lw=1)[0]
113 # color="k", linestyle="dashed", lw=1)[0]
111 if self.CODE == 'spc_moments':
114 if self.CODE == 'spc_moments':
112 ax.plt_mean = ax.plot(mean, y, color='k')[0]
115 ax.plt_mean = ax.plot(mean, y, color='k')[0]
113 else:
116 else:
114 ax.plt.set_array(z[n].T.ravel())
117 ax.plt.set_array(z[n].T.ravel())
115 if self.showprofile:
118 if self.showprofile:
116 ax.plt_profile.set_data(data['rti'][n], y)
119 ax.plt_profile.set_data(data['rti'][n], y)
117 #ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
120 #ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
118 if self.CODE == 'spc_moments':
121 if self.CODE == 'spc_moments':
119 ax.plt_mean.set_data(mean, y)
122 ax.plt_mean.set_data(mean, y)
120 if len(self.azimuthList) > 0 and len(self.elevationList) > 0:
123 if len(self.azimuthList) > 0 and len(self.elevationList) > 0:
121 self.titles.append('CH {}: {:2.1f}elv {:2.1f}az {:3.2f}dB'.format(self.channelList[n], noise, self.elevationList[n], self.azimuthList[n]))
124 self.titles.append('CH {}: {:2.1f}elv {:2.1f}az {:3.2f}dB'.format(self.channelList[n], noise, self.elevationList[n], self.azimuthList[n]))
122 else:
125 else:
123 self.titles.append('CH {}: {:3.2f}dB'.format(self.channelList[n], noise))
126 self.titles.append('CH {}: {:3.2f}dB'.format(self.channelList[n], noise))
124
127
125
128
126 class CrossSpectraPlot(Plot):
129 class CrossSpectraPlot(Plot):
127
130
128 CODE = 'cspc'
131 CODE = 'cspc'
129 colormap = 'jet'
132 colormap = 'jet'
130 plot_type = 'pcolor'
133 plot_type = 'pcolor'
131 zmin_coh = None
134 zmin_coh = None
132 zmax_coh = None
135 zmax_coh = None
133 zmin_phase = None
136 zmin_phase = None
134 zmax_phase = None
137 zmax_phase = None
135 realChannels = None
138 realChannels = None
136 crossPairs = None
139 crossPairs = None
137
140
138 def setup(self):
141 def setup(self):
139
142
140 self.ncols = 4
143 self.ncols = 4
141 self.nplots = len(self.data.pairs) * 2
144 self.nplots = len(self.data.pairs) * 2
142 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
145 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
143 self.width = 3.1 * self.ncols
146 self.width = 3.1 * self.ncols
144 self.height = 2.6 * self.nrows
147 self.height = 2.6 * self.nrows
145 self.ylabel = 'Range [km]'
148 self.ylabel = 'Range [km]'
146 self.showprofile = False
149 self.showprofile = False
147 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
150 self.plots_adjust.update({'left': 0.08, 'right': 0.92, 'wspace': 0.5, 'hspace':0.4, 'top':0.95, 'bottom': 0.08})
148
151
149 def update(self, dataOut):
152 def update(self, dataOut):
150
153
151 data = {}
154 data = {}
152 meta = {}
155 meta = {}
153
156
154 spc = dataOut.data_spc
157 spc = dataOut.data_spc
155 cspc = dataOut.data_cspc
158 cspc = dataOut.data_cspc
156 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
159 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
157 rawPairs = list(combinations(list(range(dataOut.nChannels)), 2))
160 rawPairs = list(combinations(list(range(dataOut.nChannels)), 2))
158 meta['pairs'] = rawPairs
161 meta['pairs'] = rawPairs
159
162
160 if self.crossPairs == None:
163 if self.crossPairs == None:
161 self.crossPairs = dataOut.pairsList
164 self.crossPairs = dataOut.pairsList
162
165
163 tmp = []
166 tmp = []
164
167
165 for n, pair in enumerate(meta['pairs']):
168 for n, pair in enumerate(meta['pairs']):
166
169
167 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
170 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
168 coh = numpy.abs(out)
171 coh = numpy.abs(out)
169 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
172 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
170 tmp.append(coh)
173 tmp.append(coh)
171 tmp.append(phase)
174 tmp.append(phase)
172
175
173 data['cspc'] = numpy.array(tmp)
176 data['cspc'] = numpy.array(tmp)
174
177
175 return data, meta
178 return data, meta
176
179
177 def plot(self):
180 def plot(self):
178
181
179 if self.xaxis == "frequency":
182 if self.xaxis == "frequency":
180 x = self.data.xrange[0]
183 x = self.data.xrange[0]
181 self.xlabel = "Frequency (kHz)"
184 self.xlabel = "Frequency (kHz)"
182 elif self.xaxis == "time":
185 elif self.xaxis == "time":
183 x = self.data.xrange[1]
186 x = self.data.xrange[1]
184 self.xlabel = "Time (ms)"
187 self.xlabel = "Time (ms)"
185 else:
188 else:
186 x = self.data.xrange[2]
189 x = self.data.xrange[2]
187 self.xlabel = "Velocity (m/s)"
190 self.xlabel = "Velocity (m/s)"
188
191
189 self.titles = []
192 self.titles = []
190
193
191 y = self.data.yrange
194 y = self.data.yrange
192 self.y = y
195 self.y = y
193
196
194 data = self.data[-1]
197 data = self.data[-1]
195 cspc = data['cspc']
198 cspc = data['cspc']
196
199
197 for n in range(len(self.data.pairs)):
200 for n in range(len(self.data.pairs)):
198
201
199 pair = self.crossPairs[n]
202 pair = self.crossPairs[n]
200
203
201 coh = cspc[n*2]
204 coh = cspc[n*2]
202 phase = cspc[n*2+1]
205 phase = cspc[n*2+1]
203 ax = self.axes[2 * n]
206 ax = self.axes[2 * n]
204
207
205 if ax.firsttime:
208 if ax.firsttime:
206 ax.plt = ax.pcolormesh(x, y, coh.T,
209 ax.plt = ax.pcolormesh(x, y, coh.T,
207 vmin=self.zmin_coh,
210 vmin=self.zmin_coh,
208 vmax=self.zmax_coh,
211 vmax=self.zmax_coh,
209 cmap=plt.get_cmap(self.colormap_coh)
212 cmap=plt.get_cmap(self.colormap_coh)
210 )
213 )
211 else:
214 else:
212 ax.plt.set_array(coh.T.ravel())
215 ax.plt.set_array(coh.T.ravel())
213 self.titles.append(
216 self.titles.append(
214 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
217 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
215
218
216 ax = self.axes[2 * n + 1]
219 ax = self.axes[2 * n + 1]
217 if ax.firsttime:
220 if ax.firsttime:
218 ax.plt = ax.pcolormesh(x, y, phase.T,
221 ax.plt = ax.pcolormesh(x, y, phase.T,
219 vmin=-180,
222 vmin=-180,
220 vmax=180,
223 vmax=180,
221 cmap=plt.get_cmap(self.colormap_phase)
224 cmap=plt.get_cmap(self.colormap_phase)
222 )
225 )
223 else:
226 else:
224 ax.plt.set_array(phase.T.ravel())
227 ax.plt.set_array(phase.T.ravel())
225
228
226 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
229 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
227
230
228
231
229 class RTIPlot(Plot):
232 class RTIPlot(Plot):
230 '''
233 '''
231 Plot for RTI data
234 Plot for RTI data
232 '''
235 '''
233
236
234 CODE = 'rti'
237 CODE = 'rti'
235 colormap = 'jet'
238 colormap = 'jet'
236 plot_type = 'pcolorbuffer'
239 plot_type = 'pcolorbuffer'
237 titles = None
240 titles = None
238 channelList = []
241 channelList = []
239 elevationList = []
242 elevationList = []
240 azimuthList = []
243 azimuthList = []
241
244
242 def setup(self):
245 def setup(self):
243 self.xaxis = 'time'
246 self.xaxis = 'time'
244 self.ncols = 1
247 self.ncols = 1
245 #print("dataChannels ",self.data.channels)
248 #print("dataChannels ",self.data.channels)
246 self.nrows = len(self.data.channels)
249 self.nrows = len(self.data.channels)
247 self.nplots = len(self.data.channels)
250 self.nplots = len(self.data.channels)
248 self.ylabel = 'Range [km]'
251 self.ylabel = 'Range [km]'
249 self.xlabel = 'Time'
252 self.xlabel = 'Time'
250 self.cb_label = 'dB'
253 self.cb_label = 'dB'
251 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
254 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
252 self.titles = ['{} Channel {}'.format(
255 self.titles = ['{} Channel {}'.format(
253 self.CODE.upper(), x) for x in range(self.nplots)]
256 self.CODE.upper(), x) for x in range(self.nplots)]
254
257
255 def update_list(self,dataOut):
258 def update_list(self,dataOut):
256
259
257 if len(self.channelList) == 0:
260 if len(self.channelList) == 0:
258 self.channelList = dataOut.channelList
261 self.channelList = dataOut.channelList
259 if len(self.elevationList) == 0:
262 if len(self.elevationList) == 0:
260 self.elevationList = dataOut.elevationList
263 self.elevationList = dataOut.elevationList
261 if len(self.azimuthList) == 0:
264 if len(self.azimuthList) == 0:
262 self.azimuthList = dataOut.azimuthList
265 self.azimuthList = dataOut.azimuthList
263
266
264
267
265 def update(self, dataOut):
268 def update(self, dataOut):
266 if len(self.channelList) == 0:
269 if len(self.channelList) == 0:
267 self.update_list(dataOut)
270 self.update_list(dataOut)
268 data = {}
271 data = {}
269 meta = {}
272 meta = {}
270 data['rti'] = dataOut.getPower()
273 data['rti'] = dataOut.getPower()
271 data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
274
275 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
276 noise = 10*numpy.log10(dataOut.getNoise()/float(norm))
277 data['noise'] = noise
278
272 return data, meta
279 return data, meta
273
280
274 def plot(self):
281 def plot(self):
275
282
276 self.x = self.data.times
283 self.x = self.data.times
277 self.y = self.data.yrange
284 self.y = self.data.yrange
278 #print(" x, y: ",self.x, self.y)
285 #print(" x, y: ",self.x, self.y)
279 self.z = self.data[self.CODE]
286 self.z = self.data[self.CODE]
280 self.z = numpy.array(self.z, dtype=float)
287 self.z = numpy.array(self.z, dtype=float)
281 self.z = numpy.ma.masked_invalid(self.z)
288 self.z = numpy.ma.masked_invalid(self.z)
282
289
283 try:
290 try:
284 if self.channelList != None:
291 if self.channelList != None:
285 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
292 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
286 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
293 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
287 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
294 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
288 else:
295 else:
289 self.titles = ['{} Channel {}'.format(
296 self.titles = ['{} Channel {}'.format(
290 self.CODE.upper(), x) for x in self.channelList]
297 self.CODE.upper(), x) for x in self.channelList]
291 except:
298 except:
292 if self.channelList.any() != None:
299 if self.channelList.any() != None:
293
300
294 self.titles = ['{} Channel {}'.format(
301 self.titles = ['{} Channel {}'.format(
295 self.CODE.upper(), x) for x in self.channelList]
302 self.CODE.upper(), x) for x in self.channelList]
296
303
297 if self.decimation is None:
304 if self.decimation is None:
298 x, y, z = self.fill_gaps(self.x, self.y, self.z)
305 x, y, z = self.fill_gaps(self.x, self.y, self.z)
299 else:
306 else:
300 x, y, z = self.fill_gaps(*self.decimate())
307 x, y, z = self.fill_gaps(*self.decimate())
301
308
302 #dummy_var = self.axes #Extrañamente esto actualiza el valor axes
309 #dummy_var = self.axes #Extrañamente esto actualiza el valor axes
303 for n, ax in enumerate(self.axes):
310 for n, ax in enumerate(self.axes):
304 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
311 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
305 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
312 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
306 data = self.data[-1]
313 data = self.data[-1]
307
314
308 if ax.firsttime:
315 if ax.firsttime:
309 ax.plt = ax.pcolormesh(x, y, z[n].T,
316 ax.plt = ax.pcolormesh(x, y, z[n].T,
310 vmin=self.zmin,
317 vmin=self.zmin,
311 vmax=self.zmax,
318 vmax=self.zmax,
312 cmap=plt.get_cmap(self.colormap)
319 cmap=plt.get_cmap(self.colormap)
313 )
320 )
314 if self.showprofile:
321 if self.showprofile:
315 ax.plot_profile = self.pf_axes[n].plot(data[self.CODE][n], self.y)[0]
322 ax.plot_profile = self.pf_axes[n].plot(data[self.CODE][n], self.y)[0]
316 if "noise" in self.data:
323 if "noise" in self.data:
317
324
318 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
325 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(data['noise'][n], len(self.y)), self.y,
319 color="k", linestyle="dashed", lw=1)[0]
326 color="k", linestyle="dashed", lw=1)[0]
320 else:
327 else:
321 ax.collections.remove(ax.collections[0])
328 ax.collections.remove(ax.collections[0])
322 ax.plt = ax.pcolormesh(x, y, z[n].T,
329 ax.plt = ax.pcolormesh(x, y, z[n].T,
323 vmin=self.zmin,
330 vmin=self.zmin,
324 vmax=self.zmax,
331 vmax=self.zmax,
325 cmap=plt.get_cmap(self.colormap)
332 cmap=plt.get_cmap(self.colormap)
326 )
333 )
327 if self.showprofile:
334 if self.showprofile:
328 ax.plot_profile.set_data(data[self.CODE][n], self.y)
335 ax.plot_profile.set_data(data[self.CODE][n], self.y)
329 if "noise" in self.data:
336 if "noise" in self.data:
330
337 ax.plot_noise.set_data(numpy.repeat(data['noise'][n], len(self.y)), self.y)
331 ax.plot_noise.set_data(numpy.repeat(
332 data['noise'][n], len(self.y)), self.y)
333
338
334
339
335 class CoherencePlot(RTIPlot):
340 class CoherencePlot(RTIPlot):
336 '''
341 '''
337 Plot for Coherence data
342 Plot for Coherence data
338 '''
343 '''
339
344
340 CODE = 'coh'
345 CODE = 'coh'
341
346
342 def setup(self):
347 def setup(self):
343 self.xaxis = 'time'
348 self.xaxis = 'time'
344 self.ncols = 1
349 self.ncols = 1
345 self.nrows = len(self.data.pairs)
350 self.nrows = len(self.data.pairs)
346 self.nplots = len(self.data.pairs)
351 self.nplots = len(self.data.pairs)
347 self.ylabel = 'Range [km]'
352 self.ylabel = 'Range [km]'
348 self.xlabel = 'Time'
353 self.xlabel = 'Time'
349 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
354 self.plots_adjust.update({'hspace':0.6, 'left': 0.1, 'bottom': 0.1,'right':0.95})
350 if self.CODE == 'coh':
355 if self.CODE == 'coh':
351 self.cb_label = ''
356 self.cb_label = ''
352 self.titles = [
357 self.titles = [
353 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
358 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
354 else:
359 else:
355 self.cb_label = 'Degrees'
360 self.cb_label = 'Degrees'
356 self.titles = [
361 self.titles = [
357 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
362 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
358
363
359 def update(self, dataOut):
364 def update(self, dataOut):
360 self.update_list(dataOut)
365 self.update_list(dataOut)
361 data = {}
366 data = {}
362 meta = {}
367 meta = {}
363 data['coh'] = dataOut.getCoherence()
368 data['coh'] = dataOut.getCoherence()
364 meta['pairs'] = dataOut.pairsList
369 meta['pairs'] = dataOut.pairsList
365
370
366
371
367 return data, meta
372 return data, meta
368
373
369 class PhasePlot(CoherencePlot):
374 class PhasePlot(CoherencePlot):
370 '''
375 '''
371 Plot for Phase map data
376 Plot for Phase map data
372 '''
377 '''
373
378
374 CODE = 'phase'
379 CODE = 'phase'
375 colormap = 'seismic'
380 colormap = 'seismic'
376
381
377 def update(self, dataOut):
382 def update(self, dataOut):
378
383
379 data = {}
384 data = {}
380 meta = {}
385 meta = {}
381 data['phase'] = dataOut.getCoherence(phase=True)
386 data['phase'] = dataOut.getCoherence(phase=True)
382 meta['pairs'] = dataOut.pairsList
387 meta['pairs'] = dataOut.pairsList
383
388
384 return data, meta
389 return data, meta
385
390
386 class NoisePlot(Plot):
391 class NoisePlot(Plot):
387 '''
392 '''
388 Plot for noise
393 Plot for noise
389 '''
394 '''
390
395
391 CODE = 'noise'
396 CODE = 'noise'
392 plot_type = 'scatterbuffer'
397 plot_type = 'scatterbuffer'
393
398
394 def setup(self):
399 def setup(self):
395 self.xaxis = 'time'
400 self.xaxis = 'time'
396 self.ncols = 1
401 self.ncols = 1
397 self.nrows = 1
402 self.nrows = 1
398 self.nplots = 1
403 self.nplots = 1
399 self.ylabel = 'Intensity [dB]'
404 self.ylabel = 'Intensity [dB]'
400 self.xlabel = 'Time'
405 self.xlabel = 'Time'
401 self.titles = ['Noise']
406 self.titles = ['Noise']
402 self.colorbar = False
407 self.colorbar = False
403 self.plots_adjust.update({'right': 0.85 })
408 self.plots_adjust.update({'right': 0.85 })
409 #if not self.titles:
410 self.titles = ['Noise Plot']
404
411
405 def update(self, dataOut):
412 def update(self, dataOut):
406
413
407 data = {}
414 data = {}
408 meta = {}
415 meta = {}
409 noise = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor).reshape(dataOut.nChannels, 1)
416 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
417 #noise = 10*numpy.log10(dataOut.getNoise()/norm)
418 noise = 10*numpy.log10(dataOut.getNoise())
419 noise = noise.reshape(dataOut.nChannels, 1)
410 data['noise'] = noise
420 data['noise'] = noise
411 meta['yrange'] = numpy.array([])
421 meta['yrange'] = numpy.array([])
412
422
413 return data, meta
423 return data, meta
414
424
415 def plot(self):
425 def plot(self):
416
426
417 x = self.data.times
427 x = self.data.times
418 xmin = self.data.min_time
428 xmin = self.data.min_time
419 xmax = xmin + self.xrange * 60 * 60
429 xmax = xmin + self.xrange * 60 * 60
420 Y = self.data['noise']
430 Y = self.data['noise']
421
431
422 if self.axes[0].firsttime:
432 if self.axes[0].firsttime:
423 if self.ymin is None: self.ymin = numpy.nanmin(Y) - 5
433 if self.ymin is None: self.ymin = numpy.nanmin(Y) - 5
424 if self.ymax is None: self.ymax = numpy.nanmax(Y) + 5
434 if self.ymax is None: self.ymax = numpy.nanmax(Y) + 5
425 for ch in self.data.channels:
435 for ch in self.data.channels:
426 y = Y[ch]
436 y = Y[ch]
427 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
437 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
428 plt.legend(bbox_to_anchor=(1.18, 1.0))
438 plt.legend(bbox_to_anchor=(1.18, 1.0))
429 else:
439 else:
430 for ch in self.data.channels:
440 for ch in self.data.channels:
431 y = Y[ch]
441 y = Y[ch]
432 self.axes[0].lines[ch].set_data(x, y)
442 self.axes[0].lines[ch].set_data(x, y)
433
443
434
444
435 class PowerProfilePlot(Plot):
445 class PowerProfilePlot(Plot):
436
446
437 CODE = 'pow_profile'
447 CODE = 'pow_profile'
438 plot_type = 'scatter'
448 plot_type = 'scatter'
439
449
440 def setup(self):
450 def setup(self):
441
451
442 self.ncols = 1
452 self.ncols = 1
443 self.nrows = 1
453 self.nrows = 1
444 self.nplots = 1
454 self.nplots = 1
445 self.height = 4
455 self.height = 4
446 self.width = 3
456 self.width = 3
447 self.ylabel = 'Range [km]'
457 self.ylabel = 'Range [km]'
448 self.xlabel = 'Intensity [dB]'
458 self.xlabel = 'Intensity [dB]'
449 self.titles = ['Power Profile']
459 self.titles = ['Power Profile']
450 self.colorbar = False
460 self.colorbar = False
451
461
452 def update(self, dataOut):
462 def update(self, dataOut):
453
463
454 data = {}
464 data = {}
455 meta = {}
465 meta = {}
456 data[self.CODE] = dataOut.getPower()
466 data[self.CODE] = dataOut.getPower()
457
467
458 return data, meta
468 return data, meta
459
469
460 def plot(self):
470 def plot(self):
461
471
462 y = self.data.yrange
472 y = self.data.yrange
463 self.y = y
473 self.y = y
464
474
465 x = self.data[-1][self.CODE]
475 x = self.data[-1][self.CODE]
466
476
467 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
477 if self.xmin is None: self.xmin = numpy.nanmin(x)*0.9
468 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
478 if self.xmax is None: self.xmax = numpy.nanmax(x)*1.1
469
479
470 if self.axes[0].firsttime:
480 if self.axes[0].firsttime:
471 for ch in self.data.channels:
481 for ch in self.data.channels:
472 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
482 self.axes[0].plot(x[ch], y, lw=1, label='Ch{}'.format(ch))
473 plt.legend()
483 plt.legend()
474 else:
484 else:
475 for ch in self.data.channels:
485 for ch in self.data.channels:
476 self.axes[0].lines[ch].set_data(x[ch], y)
486 self.axes[0].lines[ch].set_data(x[ch], y)
477
487
478
488
479 class SpectraCutPlot(Plot):
489 class SpectraCutPlot(Plot):
480
490
481 CODE = 'spc_cut'
491 CODE = 'spc_cut'
482 plot_type = 'scatter'
492 plot_type = 'scatter'
483 buffering = False
493 buffering = False
484 heights = []
494 heights = []
485 channelList = []
495 channelList = []
486 maintitle = "Spectra Cuts"
496 maintitle = "Spectra Cuts"
487 flag_setIndex = False
497 flag_setIndex = False
488
498
489 def setup(self):
499 def setup(self):
490
500
491 self.nplots = len(self.data.channels)
501 self.nplots = len(self.data.channels)
492 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
502 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
493 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
503 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
494 self.width = 4.2 * self.ncols + 2.5
504 self.width = 4.5 * self.ncols + 2.5
495 self.height = 4.8 * self.nrows
505 self.height = 4.8 * self.nrows
496 self.ylabel = 'Power [dB]'
506 self.ylabel = 'Power [dB]'
497 self.colorbar = False
507 self.colorbar = False
498 self.plots_adjust.update({'left':0.05, 'hspace':0.3, 'right': 0.9, 'bottom':0.08})
508 self.plots_adjust.update({'left':0.1, 'hspace':0.3, 'right': 0.9, 'bottom':0.08})
499
509
500 if len(self.selectedHeightsList) > 0:
510 if len(self.selectedHeightsList) > 0:
501 self.maintitle = "Spectra Cut"# for %d km " %(int(self.selectedHeight))
511 self.maintitle = "Spectra Cut"# for %d km " %(int(self.selectedHeight))
502
512
503
513
504
514
505 def update(self, dataOut):
515 def update(self, dataOut):
506 if len(self.channelList) == 0:
516 if len(self.channelList) == 0:
507 self.channelList = dataOut.channelList
517 self.channelList = dataOut.channelList
508
518
509 self.heights = dataOut.heightList
519 self.heights = dataOut.heightList
510 #print("sels: ",self.selectedHeightsList)
520 #print("sels: ",self.selectedHeightsList)
511 if len(self.selectedHeightsList)>0 and not self.flag_setIndex:
521 if len(self.selectedHeightsList)>0 and not self.flag_setIndex:
512
522
513 for sel_height in self.selectedHeightsList:
523 for sel_height in self.selectedHeightsList:
514 index_list = numpy.where(self.heights >= sel_height)
524 index_list = numpy.where(self.heights >= sel_height)
515 index_list = index_list[0]
525 index_list = index_list[0]
516 self.height_index.append(index_list[0])
526 self.height_index.append(index_list[0])
517 #print("sels i:"", self.height_index)
527 #print("sels i:"", self.height_index)
518 self.flag_setIndex = True
528 self.flag_setIndex = True
519 #print(self.height_index)
529 #print(self.height_index)
520 data = {}
530 data = {}
521 meta = {}
531 meta = {}
522 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
532
533 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
534 n0 = 10*numpy.log10(dataOut.getNoise()/float(norm))
535
536 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor) - n0
523
537
524 data['spc'] = spc
538 data['spc'] = spc
525 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
539 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
526
540
527 return data, meta
541 return data, meta
528
542
529 def plot(self):
543 def plot(self):
530 if self.xaxis == "frequency":
544 if self.xaxis == "frequency":
531 x = self.data.xrange[0][1:]
545 x = self.data.xrange[0][1:]
532 self.xlabel = "Frequency (kHz)"
546 self.xlabel = "Frequency (kHz)"
533 elif self.xaxis == "time":
547 elif self.xaxis == "time":
534 x = self.data.xrange[1]
548 x = self.data.xrange[1]
535 self.xlabel = "Time (ms)"
549 self.xlabel = "Time (ms)"
536 else:
550 else:
537 x = self.data.xrange[2]
551 x = self.data.xrange[2]
538 self.xlabel = "Velocity (m/s)"
552 self.xlabel = "Velocity (m/s)"
539
553
540 self.titles = []
554 self.titles = []
541
555
542 y = self.data.yrange
556 y = self.data.yrange
543 z = self.data[-1]['spc']
557 z = self.data[-1]['spc']
544 #print(z.shape)
558 #print(z.shape)
545 if len(self.height_index) > 0:
559 if len(self.height_index) > 0:
546 index = self.height_index
560 index = self.height_index
547 else:
561 else:
548 index = numpy.arange(0, len(y), int((len(y))/9))
562 index = numpy.arange(0, len(y), int((len(y))/9))
549 #print("inde x ", index, self.axes)
563 #print("inde x ", index, self.axes)
550
564
551 for n, ax in enumerate(self.axes):
565 for n, ax in enumerate(self.axes):
552
566
553 if ax.firsttime:
567 if ax.firsttime:
554
568
555
569
556 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
570 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
557 self.xmin = self.xmin if self.xmin else -self.xmax
571 self.xmin = self.xmin if self.xmin else -self.xmax
558 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
572 self.ymin = self.ymin if self.ymin else numpy.nanmin(z)
559 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
573 self.ymax = self.ymax if self.ymax else numpy.nanmax(z)
560
574
561
575
562 ax.plt = ax.plot(x, z[n, :, index].T)
576 ax.plt = ax.plot(x, z[n, :, index].T)
563 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
577 labels = ['Range = {:2.1f}km'.format(y[i]) for i in index]
564 self.figures[0].legend(ax.plt, labels, loc='center right', prop={'size': 8})
578 self.figures[0].legend(ax.plt, labels, loc='center right', prop={'size': 8})
565 ax.minorticks_on()
579 ax.minorticks_on()
566 ax.grid(which='major', axis='both')
580 ax.grid(which='major', axis='both')
567 ax.grid(which='minor', axis='x')
581 ax.grid(which='minor', axis='x')
568 else:
582 else:
569 for i, line in enumerate(ax.plt):
583 for i, line in enumerate(ax.plt):
570 line.set_data(x, z[n, :, index[i]])
584 line.set_data(x, z[n, :, index[i]])
571
585
572
586
573 self.titles.append('CH {}'.format(self.channelList[n]))
587 self.titles.append('CH {}'.format(self.channelList[n]))
574 plt.suptitle(self.maintitle, fontsize=10)
588 plt.suptitle(self.maintitle, fontsize=10)
575
589
576
590
577 class BeaconPhase(Plot):
591 class BeaconPhase(Plot):
578
592
579 __isConfig = None
593 __isConfig = None
580 __nsubplots = None
594 __nsubplots = None
581
595
582 PREFIX = 'beacon_phase'
596 PREFIX = 'beacon_phase'
583
597
584 def __init__(self):
598 def __init__(self):
585 Plot.__init__(self)
599 Plot.__init__(self)
586 self.timerange = 24*60*60
600 self.timerange = 24*60*60
587 self.isConfig = False
601 self.isConfig = False
588 self.__nsubplots = 1
602 self.__nsubplots = 1
589 self.counter_imagwr = 0
603 self.counter_imagwr = 0
590 self.WIDTH = 800
604 self.WIDTH = 800
591 self.HEIGHT = 400
605 self.HEIGHT = 400
592 self.WIDTHPROF = 120
606 self.WIDTHPROF = 120
593 self.HEIGHTPROF = 0
607 self.HEIGHTPROF = 0
594 self.xdata = None
608 self.xdata = None
595 self.ydata = None
609 self.ydata = None
596
610
597 self.PLOT_CODE = BEACON_CODE
611 self.PLOT_CODE = BEACON_CODE
598
612
599 self.FTP_WEI = None
613 self.FTP_WEI = None
600 self.EXP_CODE = None
614 self.EXP_CODE = None
601 self.SUB_EXP_CODE = None
615 self.SUB_EXP_CODE = None
602 self.PLOT_POS = None
616 self.PLOT_POS = None
603
617
604 self.filename_phase = None
618 self.filename_phase = None
605
619
606 self.figfile = None
620 self.figfile = None
607
621
608 self.xmin = None
622 self.xmin = None
609 self.xmax = None
623 self.xmax = None
610
624
611 def getSubplots(self):
625 def getSubplots(self):
612
626
613 ncol = 1
627 ncol = 1
614 nrow = 1
628 nrow = 1
615
629
616 return nrow, ncol
630 return nrow, ncol
617
631
618 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
632 def setup(self, id, nplots, wintitle, showprofile=True, show=True):
619
633
620 self.__showprofile = showprofile
634 self.__showprofile = showprofile
621 self.nplots = nplots
635 self.nplots = nplots
622
636
623 ncolspan = 7
637 ncolspan = 7
624 colspan = 6
638 colspan = 6
625 self.__nsubplots = 2
639 self.__nsubplots = 2
626
640
627 self.createFigure(id = id,
641 self.createFigure(id = id,
628 wintitle = wintitle,
642 wintitle = wintitle,
629 widthplot = self.WIDTH+self.WIDTHPROF,
643 widthplot = self.WIDTH+self.WIDTHPROF,
630 heightplot = self.HEIGHT+self.HEIGHTPROF,
644 heightplot = self.HEIGHT+self.HEIGHTPROF,
631 show=show)
645 show=show)
632
646
633 nrow, ncol = self.getSubplots()
647 nrow, ncol = self.getSubplots()
634
648
635 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
649 self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1)
636
650
637 def save_phase(self, filename_phase):
651 def save_phase(self, filename_phase):
638 f = open(filename_phase,'w+')
652 f = open(filename_phase,'w+')
639 f.write('\n\n')
653 f.write('\n\n')
640 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
654 f.write('JICAMARCA RADIO OBSERVATORY - Beacon Phase \n')
641 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
655 f.write('DD MM YYYY HH MM SS pair(2,0) pair(2,1) pair(2,3) pair(2,4)\n\n' )
642 f.close()
656 f.close()
643
657
644 def save_data(self, filename_phase, data, data_datetime):
658 def save_data(self, filename_phase, data, data_datetime):
645 f=open(filename_phase,'a')
659 f=open(filename_phase,'a')
646 timetuple_data = data_datetime.timetuple()
660 timetuple_data = data_datetime.timetuple()
647 day = str(timetuple_data.tm_mday)
661 day = str(timetuple_data.tm_mday)
648 month = str(timetuple_data.tm_mon)
662 month = str(timetuple_data.tm_mon)
649 year = str(timetuple_data.tm_year)
663 year = str(timetuple_data.tm_year)
650 hour = str(timetuple_data.tm_hour)
664 hour = str(timetuple_data.tm_hour)
651 minute = str(timetuple_data.tm_min)
665 minute = str(timetuple_data.tm_min)
652 second = str(timetuple_data.tm_sec)
666 second = str(timetuple_data.tm_sec)
653 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
667 f.write(day+' '+month+' '+year+' '+hour+' '+minute+' '+second+' '+str(data[0])+' '+str(data[1])+' '+str(data[2])+' '+str(data[3])+'\n')
654 f.close()
668 f.close()
655
669
656 def plot(self):
670 def plot(self):
657 log.warning('TODO: Not yet implemented...')
671 log.warning('TODO: Not yet implemented...')
658
672
659 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
673 def run(self, dataOut, id, wintitle="", pairsList=None, showprofile='True',
660 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
674 xmin=None, xmax=None, ymin=None, ymax=None, hmin=None, hmax=None,
661 timerange=None,
675 timerange=None,
662 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
676 save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1,
663 server=None, folder=None, username=None, password=None,
677 server=None, folder=None, username=None, password=None,
664 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
678 ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0):
665
679
666 if dataOut.flagNoData:
680 if dataOut.flagNoData:
667 return dataOut
681 return dataOut
668
682
669 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
683 if not isTimeInHourRange(dataOut.datatime, xmin, xmax):
670 return
684 return
671
685
672 if pairsList == None:
686 if pairsList == None:
673 pairsIndexList = dataOut.pairsIndexList[:10]
687 pairsIndexList = dataOut.pairsIndexList[:10]
674 else:
688 else:
675 pairsIndexList = []
689 pairsIndexList = []
676 for pair in pairsList:
690 for pair in pairsList:
677 if pair not in dataOut.pairsList:
691 if pair not in dataOut.pairsList:
678 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
692 raise ValueError("Pair %s is not in dataOut.pairsList" %(pair))
679 pairsIndexList.append(dataOut.pairsList.index(pair))
693 pairsIndexList.append(dataOut.pairsList.index(pair))
680
694
681 if pairsIndexList == []:
695 if pairsIndexList == []:
682 return
696 return
683
697
684 # if len(pairsIndexList) > 4:
698 # if len(pairsIndexList) > 4:
685 # pairsIndexList = pairsIndexList[0:4]
699 # pairsIndexList = pairsIndexList[0:4]
686
700
687 hmin_index = None
701 hmin_index = None
688 hmax_index = None
702 hmax_index = None
689
703
690 if hmin != None and hmax != None:
704 if hmin != None and hmax != None:
691 indexes = numpy.arange(dataOut.nHeights)
705 indexes = numpy.arange(dataOut.nHeights)
692 hmin_list = indexes[dataOut.heightList >= hmin]
706 hmin_list = indexes[dataOut.heightList >= hmin]
693 hmax_list = indexes[dataOut.heightList <= hmax]
707 hmax_list = indexes[dataOut.heightList <= hmax]
694
708
695 if hmin_list.any():
709 if hmin_list.any():
696 hmin_index = hmin_list[0]
710 hmin_index = hmin_list[0]
697
711
698 if hmax_list.any():
712 if hmax_list.any():
699 hmax_index = hmax_list[-1]+1
713 hmax_index = hmax_list[-1]+1
700
714
701 x = dataOut.getTimeRange()
715 x = dataOut.getTimeRange()
702
716
703 thisDatetime = dataOut.datatime
717 thisDatetime = dataOut.datatime
704
718
705 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
719 title = wintitle + " Signal Phase" # : %s" %(thisDatetime.strftime("%d-%b-%Y"))
706 xlabel = "Local Time"
720 xlabel = "Local Time"
707 ylabel = "Phase (degrees)"
721 ylabel = "Phase (degrees)"
708
722
709 update_figfile = False
723 update_figfile = False
710
724
711 nplots = len(pairsIndexList)
725 nplots = len(pairsIndexList)
712 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
726 #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList)))
713 phase_beacon = numpy.zeros(len(pairsIndexList))
727 phase_beacon = numpy.zeros(len(pairsIndexList))
714 for i in range(nplots):
728 for i in range(nplots):
715 pair = dataOut.pairsList[pairsIndexList[i]]
729 pair = dataOut.pairsList[pairsIndexList[i]]
716 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
730 ccf = numpy.average(dataOut.data_cspc[pairsIndexList[i], :, hmin_index:hmax_index], axis=0)
717 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
731 powa = numpy.average(dataOut.data_spc[pair[0], :, hmin_index:hmax_index], axis=0)
718 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
732 powb = numpy.average(dataOut.data_spc[pair[1], :, hmin_index:hmax_index], axis=0)
719 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
733 avgcoherenceComplex = ccf/numpy.sqrt(powa*powb)
720 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
734 phase = numpy.arctan2(avgcoherenceComplex.imag, avgcoherenceComplex.real)*180/numpy.pi
721
735
722 if dataOut.beacon_heiIndexList:
736 if dataOut.beacon_heiIndexList:
723 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
737 phase_beacon[i] = numpy.average(phase[dataOut.beacon_heiIndexList])
724 else:
738 else:
725 phase_beacon[i] = numpy.average(phase)
739 phase_beacon[i] = numpy.average(phase)
726
740
727 if not self.isConfig:
741 if not self.isConfig:
728
742
729 nplots = len(pairsIndexList)
743 nplots = len(pairsIndexList)
730
744
731 self.setup(id=id,
745 self.setup(id=id,
732 nplots=nplots,
746 nplots=nplots,
733 wintitle=wintitle,
747 wintitle=wintitle,
734 showprofile=showprofile,
748 showprofile=showprofile,
735 show=show)
749 show=show)
736
750
737 if timerange != None:
751 if timerange != None:
738 self.timerange = timerange
752 self.timerange = timerange
739
753
740 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
754 self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange)
741
755
742 if ymin == None: ymin = 0
756 if ymin == None: ymin = 0
743 if ymax == None: ymax = 360
757 if ymax == None: ymax = 360
744
758
745 self.FTP_WEI = ftp_wei
759 self.FTP_WEI = ftp_wei
746 self.EXP_CODE = exp_code
760 self.EXP_CODE = exp_code
747 self.SUB_EXP_CODE = sub_exp_code
761 self.SUB_EXP_CODE = sub_exp_code
748 self.PLOT_POS = plot_pos
762 self.PLOT_POS = plot_pos
749
763
750 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
764 self.name = thisDatetime.strftime("%Y%m%d_%H%M%S")
751 self.isConfig = True
765 self.isConfig = True
752 self.figfile = figfile
766 self.figfile = figfile
753 self.xdata = numpy.array([])
767 self.xdata = numpy.array([])
754 self.ydata = numpy.array([])
768 self.ydata = numpy.array([])
755
769
756 update_figfile = True
770 update_figfile = True
757
771
758 #open file beacon phase
772 #open file beacon phase
759 path = '%s%03d' %(self.PREFIX, self.id)
773 path = '%s%03d' %(self.PREFIX, self.id)
760 beacon_file = os.path.join(path,'%s.txt'%self.name)
774 beacon_file = os.path.join(path,'%s.txt'%self.name)
761 self.filename_phase = os.path.join(figpath,beacon_file)
775 self.filename_phase = os.path.join(figpath,beacon_file)
762 #self.save_phase(self.filename_phase)
776 #self.save_phase(self.filename_phase)
763
777
764
778
765 #store data beacon phase
779 #store data beacon phase
766 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
780 #self.save_data(self.filename_phase, phase_beacon, thisDatetime)
767
781
768 self.setWinTitle(title)
782 self.setWinTitle(title)
769
783
770
784
771 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
785 title = "Phase Plot %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S"))
772
786
773 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
787 legendlabels = ["Pair (%d,%d)"%(pair[0], pair[1]) for pair in dataOut.pairsList]
774
788
775 axes = self.axesList[0]
789 axes = self.axesList[0]
776
790
777 self.xdata = numpy.hstack((self.xdata, x[0:1]))
791 self.xdata = numpy.hstack((self.xdata, x[0:1]))
778
792
779 if len(self.ydata)==0:
793 if len(self.ydata)==0:
780 self.ydata = phase_beacon.reshape(-1,1)
794 self.ydata = phase_beacon.reshape(-1,1)
781 else:
795 else:
782 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
796 self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1)))
783
797
784
798
785 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
799 axes.pmultilineyaxis(x=self.xdata, y=self.ydata,
786 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
800 xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax,
787 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
801 xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid",
788 XAxisAsTime=True, grid='both'
802 XAxisAsTime=True, grid='both'
789 )
803 )
790
804
791 self.draw()
805 self.draw()
792
806
793 if dataOut.ltctime >= self.xmax:
807 if dataOut.ltctime >= self.xmax:
794 self.counter_imagwr = wr_period
808 self.counter_imagwr = wr_period
795 self.isConfig = False
809 self.isConfig = False
796 update_figfile = True
810 update_figfile = True
797
811
798 self.save(figpath=figpath,
812 self.save(figpath=figpath,
799 figfile=figfile,
813 figfile=figfile,
800 save=save,
814 save=save,
801 ftp=ftp,
815 ftp=ftp,
802 wr_period=wr_period,
816 wr_period=wr_period,
803 thisDatetime=thisDatetime,
817 thisDatetime=thisDatetime,
804 update_figfile=update_figfile)
818 update_figfile=update_figfile)
805
819
806 return dataOut
820 return dataOut
807
821
808 class NoiselessSpectraPlot(Plot):
822 class NoiselessSpectraPlot(Plot):
809 '''
823 '''
810 Plot for Spectra data, subtracting
824 Plot for Spectra data, subtracting
811 the noise in all channels, using for
825 the noise in all channels, using for
812 amisr-14 data
826 amisr-14 data
813 '''
827 '''
814
828
815 CODE = 'noiseless_spc'
829 CODE = 'noiseless_spc'
816 colormap = 'nipy_spectral'
830 colormap = 'nipy_spectral'
817 plot_type = 'pcolor'
831 plot_type = 'pcolor'
818 buffering = False
832 buffering = False
819 channelList = []
833 channelList = []
820 last_noise = None
834 last_noise = None
821
835
822 def setup(self):
836 def setup(self):
823
837
824 self.nplots = len(self.data.channels)
838 self.nplots = len(self.data.channels)
825 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
839 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
826 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
840 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
827 self.height = 2.6 * self.nrows
841 self.height = 3.5 * self.nrows
828
842
829 self.cb_label = 'dB'
843 self.cb_label = 'dB'
830 if self.showprofile:
844 if self.showprofile:
831 self.width = 4 * self.ncols
845 self.width = 5.8 * self.ncols
832 else:
846 else:
833 self.width = 3.5 * self.ncols
847 self.width = 4.8* self.ncols
834 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.9, 'bottom': 0.08})
848 self.plots_adjust.update({'wspace': 0.4, 'hspace':0.4, 'left': 0.1, 'right': 0.92, 'bottom': 0.12})
849
835 self.ylabel = 'Range [km]'
850 self.ylabel = 'Range [km]'
836
851
837
852
838 def update_list(self,dataOut):
853 def update_list(self,dataOut):
839 if len(self.channelList) == 0:
854 if len(self.channelList) == 0:
840 self.channelList = dataOut.channelList
855 self.channelList = dataOut.channelList
841
856
842 def update(self, dataOut):
857 def update(self, dataOut):
843
858
844 self.update_list(dataOut)
859 self.update_list(dataOut)
845 data = {}
860 data = {}
846 meta = {}
861 meta = {}
847
862
848 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
863 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
849 n0 = 10*numpy.log10(dataOut.getNoise()/float(norm))
864 n0 = 10*numpy.log10(dataOut.getNoise()/float(norm))
850
865
851 if self.last_noise == None:
852 self.last_noise = n0
853 else:
854 n0 = (n0*0.2 + self.last_noise*0.8)
855 self.last_noise = n0
856
866
857 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
867 spc = 10*numpy.log10(dataOut.data_spc/dataOut.normFactor)
858
868
859 data['spc'] = spc - n0
869 data['spc'] = spc - n0
860 data['rti'] = dataOut.getPower() - n0
870 data['rti'] = dataOut.getPower() - n0
861
871
862 #data['noise'] = noise
872 # data['noise'] = noise
863 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
873 meta['xrange'] = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1))
864
874
865 return data, meta
875 return data, meta
866
876
867 def plot(self):
877 def plot(self):
868 if self.xaxis == "frequency":
878 if self.xaxis == "frequency":
869 x = self.data.xrange[0]
879 x = self.data.xrange[0]
870 self.xlabel = "Frequency (kHz)"
880 self.xlabel = "Frequency (kHz)"
871 elif self.xaxis == "time":
881 elif self.xaxis == "time":
872 x = self.data.xrange[1]
882 x = self.data.xrange[1]
873 self.xlabel = "Time (ms)"
883 self.xlabel = "Time (ms)"
874 else:
884 else:
875 x = self.data.xrange[2]
885 x = self.data.xrange[2]
876 self.xlabel = "Velocity (m/s)"
886 self.xlabel = "Velocity (m/s)"
877
887
878 self.titles = []
888 self.titles = []
879 y = self.data.yrange
889 y = self.data.yrange
880 self.y = y
890 self.y = y
881
891
882 data = self.data[-1]
892 data = self.data[-1]
883 z = data['spc']
893 z = data['spc']
884
894
885 for n, ax in enumerate(self.axes):
895 for n, ax in enumerate(self.axes):
886 #noise = data['noise'][n]
896 #noise = data['noise'][n]
887
897
888 if ax.firsttime:
898 if ax.firsttime:
889 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
899 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
890 self.xmin = self.xmin if self.xmin else -self.xmax
900 self.xmin = self.xmin if self.xmin else -self.xmax
891 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
901 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
892 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
902 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
893 ax.plt = ax.pcolormesh(x, y, z[n].T,
903 ax.plt = ax.pcolormesh(x, y, z[n].T,
894 vmin=self.zmin,
904 vmin=self.zmin,
895 vmax=self.zmax,
905 vmax=self.zmax,
896 cmap=plt.get_cmap(self.colormap)
906 cmap=plt.get_cmap(self.colormap)
897 )
907 )
898
908
899 if self.showprofile:
909 if self.showprofile:
900 ax.plt_profile = self.pf_axes[n].plot(
910 ax.plt_profile = self.pf_axes[n].plot(
901 data['rti'][n], y)[0]
911 data['rti'][n], y)[0]
902
912
903
913
904 else:
914 else:
905 ax.plt.set_array(z[n].T.ravel())
915 ax.plt.set_array(z[n].T.ravel())
906 if self.showprofile:
916 if self.showprofile:
907 ax.plt_profile.set_data(data['rti'][n], y)
917 ax.plt_profile.set_data(data['rti'][n], y)
908
918
909
919
910 self.titles.append('CH {}'.format(self.channelList[n]))
920 self.titles.append('CH {}'.format(self.channelList[n]))
911
921
912
922
913 class NoiselessRTIPlot(Plot):
923 class NoiselessRTIPlot(Plot):
914 '''
924 '''
915 Plot for RTI data
925 Plot for RTI data
916 '''
926 '''
917
927
918 CODE = 'noiseless_rti'
928 CODE = 'noiseless_rti'
919 colormap = 'jet'
929 colormap = 'jet'
920 plot_type = 'pcolorbuffer'
930 plot_type = 'pcolorbuffer'
921 titles = None
931 titles = None
922 channelList = []
932 channelList = []
923 elevationList = []
933 elevationList = []
924 azimuthList = []
934 azimuthList = []
925 last_noise = None
935 last_noise = None
926
936
927 def setup(self):
937 def setup(self):
928 self.xaxis = 'time'
938 self.xaxis = 'time'
929 self.ncols = 1
939 self.ncols = 1
930 #print("dataChannels ",self.data.channels)
940 #print("dataChannels ",self.data.channels)
931 self.nrows = len(self.data.channels)
941 self.nrows = len(self.data.channels)
932 self.nplots = len(self.data.channels)
942 self.nplots = len(self.data.channels)
933 self.ylabel = 'Range [km]'
943 self.ylabel = 'Range [km]'
934 self.xlabel = 'Time'
944 self.xlabel = 'Time'
935 self.cb_label = 'dB'
945 self.cb_label = 'dB'
936 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
946 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
937 self.titles = ['{} Channel {}'.format(
947 self.titles = ['{} Channel {}'.format(
938 self.CODE.upper(), x) for x in range(self.nplots)]
948 self.CODE.upper(), x) for x in range(self.nplots)]
939
949
940 def update_list(self,dataOut):
950 def update_list(self,dataOut):
941 if len(self.channelList) == 0:
951 if len(self.channelList) == 0:
942 self.channelList = dataOut.channelList
952 self.channelList = dataOut.channelList
943 if len(self.elevationList) == 0:
953 if len(self.elevationList) == 0:
944 self.elevationList = dataOut.elevationList
954 self.elevationList = dataOut.elevationList
945 if len(self.azimuthList) == 0:
955 if len(self.azimuthList) == 0:
946 self.azimuthList = dataOut.azimuthList
956 self.azimuthList = dataOut.azimuthList
947
957
948 def update(self, dataOut):
958 def update(self, dataOut):
949 if len(self.channelList) == 0:
959 if len(self.channelList) == 0:
950 self.update_list(dataOut)
960 self.update_list(dataOut)
951 data = {}
961 data = {}
952 meta = {}
962 meta = {}
953
963
954
964
955 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
965 norm = dataOut.nProfiles * dataOut.max_nIncohInt * dataOut.nCohInt * dataOut.windowOfFilter
956 n0 = 10*numpy.log10(dataOut.getNoise()/float(norm))
966 n0 = 10*numpy.log10(dataOut.getNoise()/float(norm))
957 #print("noise: ",n0, dataOut.normFactor, norm, dataOut.nIncohInt, dataOut.max_nIncohInt)
958 if self.last_noise == None:
959 self.last_noise = n0
960 else:
961 n0 = (n0*0.2 + self.last_noise*0.8)
962 self.last_noise = n0
963
967
968 data['noise'] = n0[0]
964
969
965 data['noiseless_rti'] = dataOut.getPower() - n0
970 data['noiseless_rti'] = dataOut.getPower() - n0
966
971
967 #data['noise'] = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor)
968 #print(noise)
969 return data, meta
972 return data, meta
970
973
971 def plot(self):
974 def plot(self):
972
975
973 self.x = self.data.times
976 self.x = self.data.times
974 self.y = self.data.yrange
977 self.y = self.data.yrange
975 self.z = self.data['noiseless_rti']
978 self.z = self.data['noiseless_rti']
976 self.z = numpy.array(self.z, dtype=float)
979 self.z = numpy.array(self.z, dtype=float)
977 self.z = numpy.ma.masked_invalid(self.z)
980 self.z = numpy.ma.masked_invalid(self.z)
978
981
982
979 try:
983 try:
980 if self.channelList != None:
984 if self.channelList != None:
981 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
985 if len(self.elevationList) > 0 and len(self.azimuthList) > 0:
982 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
986 self.titles = ['{} Channel {} ({:2.1f} Elev, {:2.1f} Azth)'.format(
983 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
987 self.CODE.upper(), x, self.elevationList[x], self.azimuthList[x]) for x in self.channelList]
984 else:
988 else:
985 self.titles = ['{} Channel {}'.format(
989 self.titles = ['{} Channel {}'.format(
986 self.CODE.upper(), x) for x in self.channelList]
990 self.CODE.upper(), x) for x in self.channelList]
987 except:
991 except:
988 if self.channelList.any() != None:
992 if self.channelList.any() != None:
989
993
990 self.titles = ['{} Channel {}'.format(
994 self.titles = ['{} Channel {}'.format(
991 self.CODE.upper(), x) for x in self.channelList]
995 self.CODE.upper(), x) for x in self.channelList]
996
997
992 if self.decimation is None:
998 if self.decimation is None:
993 x, y, z = self.fill_gaps(self.x, self.y, self.z)
999 x, y, z = self.fill_gaps(self.x, self.y, self.z)
994 else:
1000 else:
995 x, y, z = self.fill_gaps(*self.decimate())
1001 x, y, z = self.fill_gaps(*self.decimate())
996 dummy_var = self.axes #Extrañamente esto actualiza el valor axes
1002 dummy_var = self.axes #Extrañamente esto actualiza el valor axes
997 #print("plot shapes ", z.shape, x.shape, y.shape)
1003 #print("plot shapes ", z.shape, x.shape, y.shape)
998 for n, ax in enumerate(self.axes):
1004 for n, ax in enumerate(self.axes):
1005
1006
999 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
1007 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
1000 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
1008 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
1001 data = self.data[-1]
1009 data = self.data[-1]
1002 if ax.firsttime:
1010 if ax.firsttime:
1003 ax.plt = ax.pcolormesh(x, y, z[n].T,
1011 ax.plt = ax.pcolormesh(x, y, z[n].T,
1004 vmin=self.zmin,
1012 vmin=self.zmin,
1005 vmax=self.zmax,
1013 vmax=self.zmax,
1006 cmap=plt.get_cmap(self.colormap)
1014 cmap=plt.get_cmap(self.colormap)
1007 )
1015 )
1008 if self.showprofile:
1016 if self.showprofile:
1009 ax.plot_profile = self.pf_axes[n].plot(data['noiseless_rti'][n], self.y)[0]
1017 ax.plot_profile = self.pf_axes[n].plot(data['noiseless_rti'][n], self.y)[0]
1010
1018
1011 else:
1019 else:
1012 ax.collections.remove(ax.collections[0])
1020 ax.collections.remove(ax.collections[0])
1013 ax.plt = ax.pcolormesh(x, y, z[n].T,
1021 ax.plt = ax.pcolormesh(x, y, z[n].T,
1014 vmin=self.zmin,
1022 vmin=self.zmin,
1015 vmax=self.zmax,
1023 vmax=self.zmax,
1016 cmap=plt.get_cmap(self.colormap)
1024 cmap=plt.get_cmap(self.colormap)
1017 )
1025 )
1018 if self.showprofile:
1026 if self.showprofile:
1019 ax.plot_profile.set_data(data['noiseless_rti'][n], self.y)
1027 ax.plot_profile.set_data(data['noiseless_rti'][n], self.y)
1020 # if "noise" in self.data:
1028 # if "noise" in self.data:
1021 # #ax.plot_noise.set_data(numpy.repeat(data['noise'][n], len(self.y)), self.y)
1029 # #ax.plot_noise.set_data(numpy.repeat(data['noise'][n], len(self.y)), self.y)
1022 # ax.plot_noise.set_data(data['noise'][n], self.y)
1030 # ax.plot_noise.set_data(data['noise'][n], self.y)
1023
1031
1024
1032
1025 class OutliersRTIPlot(Plot):
1033 class OutliersRTIPlot(Plot):
1026 '''
1034 '''
1027 Plot for data_xxxx object
1035 Plot for data_xxxx object
1028 '''
1036 '''
1029
1037
1030 CODE = 'outlier'
1038 CODE = 'outlier_rtc' # Range Time Counts
1031 colormap = 'cool'
1039 colormap = 'cool'
1032 plot_type = 'pcolorbuffer'
1040 plot_type = 'pcolorbuffer'
1033
1041
1034 def setup(self):
1042 def setup(self):
1035 self.xaxis = 'time'
1043 self.xaxis = 'time'
1036 self.ncols = 1
1044 self.ncols = 1
1037 self.nrows = self.data.shape('outlier')[0]
1045 self.nrows = self.data.shape('outlier_rtc')[0]
1038 self.nplots = self.nrows
1046 self.nplots = self.nrows
1039 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1047 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1040
1048
1041
1049
1042 if not self.xlabel:
1050 if not self.xlabel:
1043 self.xlabel = 'Time'
1051 self.xlabel = 'Time'
1044
1052
1045 self.ylabel = 'Height [km]'
1053 self.ylabel = 'Height [km]'
1046 if not self.titles:
1054 if not self.titles:
1047 self.titles = ['Outliers Ch:{}'.format(x) for x in range(self.nrows)]
1055 self.titles = ['Outliers Ch:{}'.format(x) for x in range(self.nrows)]
1048
1056
1049 def update(self, dataOut):
1057 def update(self, dataOut):
1050
1058
1051 data = {}
1059 data = {}
1052 data['outlier'] = dataOut.data_outlier
1060 data['outlier_rtc'] = dataOut.data_outlier
1053
1061
1054 meta = {}
1062 meta = {}
1055
1063
1056 return data, meta
1064 return data, meta
1057
1065
1058 def plot(self):
1066 def plot(self):
1059 # self.data.normalize_heights()
1067 # self.data.normalize_heights()
1060 self.x = self.data.times
1068 self.x = self.data.times
1061 self.y = self.data.yrange
1069 self.y = self.data.yrange
1062 self.z = self.data['outlier']
1070 self.z = self.data['outlier_rtc']
1063
1071
1064 #self.z = numpy.ma.masked_invalid(self.z)
1072 #self.z = numpy.ma.masked_invalid(self.z)
1065
1073
1066 if self.decimation is None:
1074 if self.decimation is None:
1067 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1075 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1068 else:
1076 else:
1069 x, y, z = self.fill_gaps(*self.decimate())
1077 x, y, z = self.fill_gaps(*self.decimate())
1070
1078
1071 for n, ax in enumerate(self.axes):
1079 for n, ax in enumerate(self.axes):
1072
1080
1073 self.zmax = self.zmax if self.zmax is not None else numpy.max(
1081 self.zmax = self.zmax if self.zmax is not None else numpy.max(
1074 self.z[n])
1082 self.z[n])
1075 self.zmin = self.zmin if self.zmin is not None else numpy.min(
1083 self.zmin = self.zmin if self.zmin is not None else numpy.min(
1076 self.z[n])
1084 self.z[n])
1077 data = self.data[-1]
1085 data = self.data[-1]
1078 if ax.firsttime:
1086 if ax.firsttime:
1079 if self.zlimits is not None:
1087 if self.zlimits is not None:
1080 self.zmin, self.zmax = self.zlimits[n]
1088 self.zmin, self.zmax = self.zlimits[n]
1081
1089
1082 ax.plt = ax.pcolormesh(x, y, z[n].T,
1090 ax.plt = ax.pcolormesh(x, y, z[n].T,
1083 vmin=self.zmin,
1091 vmin=self.zmin,
1084 vmax=self.zmax,
1092 vmax=self.zmax,
1085 cmap=self.cmaps[n]
1093 cmap=self.cmaps[n]
1086 )
1094 )
1087 if self.showprofile:
1095 if self.showprofile:
1088 ax.plot_profile = self.pf_axes[n].plot(data['outlier'][n], self.y)[0]
1096 ax.plot_profile = self.pf_axes[n].plot(data['outlier_rtc'][n], self.y)[0]
1089 self.pf_axes[n].set_xlabel('')
1097 self.pf_axes[n].set_xlabel('')
1090 else:
1098 else:
1091 if self.zlimits is not None:
1099 if self.zlimits is not None:
1092 self.zmin, self.zmax = self.zlimits[n]
1100 self.zmin, self.zmax = self.zlimits[n]
1093 ax.collections.remove(ax.collections[0])
1101 ax.collections.remove(ax.collections[0])
1094 ax.plt = ax.pcolormesh(x, y, z[n].T ,
1102 ax.plt = ax.pcolormesh(x, y, z[n].T ,
1095 vmin=self.zmin,
1103 vmin=self.zmin,
1096 vmax=self.zmax,
1104 vmax=self.zmax,
1097 cmap=self.cmaps[n]
1105 cmap=self.cmaps[n]
1098 )
1106 )
1099 if self.showprofile:
1107 if self.showprofile:
1100 ax.plot_profile.set_data(data['outlier'][n], self.y)
1108 ax.plot_profile.set_data(data['outlier_rtc'][n], self.y)
1101 self.pf_axes[n].set_xlabel('')
1109 self.pf_axes[n].set_xlabel('')
1102
1110
1103 # class NoiseRTIPlot(Plot):
1111 class NIncohIntRTIPlot(Plot):
1104 # '''
1112 '''
1105 # Plot for data_xxxx object
1113 Plot for data_xxxx object
1106 # '''
1114 '''
1107 #
1115
1108 # CODE = 'noise'
1116 CODE = 'integrations_rtc' # Range Time Counts
1109 # colormap = 'jet'
1117 colormap = 'BuGn'
1110 # plot_type = 'pcolorbuffer'
1118 plot_type = 'pcolorbuffer'
1111 #
1119
1112 # def setup(self):
1120 def setup(self):
1113 # self.xaxis = 'time'
1121 self.xaxis = 'time'
1114 # self.ncols = 1
1122 self.ncols = 1
1115 # self.nrows = self.data.shape('noise')[0]
1123 self.nrows = self.data.shape('integrations_rtc')[0]
1116 # self.nplots = self.nrows
1124 self.nplots = self.nrows
1117 # self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1125 self.plots_adjust.update({'hspace':0.8, 'left': 0.08, 'bottom': 0.2, 'right':0.94})
1118 #
1126
1119 #
1127
1120 # if not self.xlabel:
1128 if not self.xlabel:
1121 # self.xlabel = 'Time'
1129 self.xlabel = 'Time'
1122 #
1130
1123 # self.ylabel = 'Height [km]'
1131 self.ylabel = 'Height [km]'
1124 # if not self.titles:
1132 if not self.titles:
1125 # self.titles = ['noise Ch:{}'.format(x) for x in range(self.nrows)]
1133 self.titles = ['Integration Ch:{}'.format(x) for x in range(self.nrows)]
1126 #
1134
1127 # def update(self, dataOut):
1135 def update(self, dataOut):
1128 #
1136
1129 # data = {}
1137 data = {}
1130 # norm = dataOut.max_nIncohInt*dataOut.nProfiles* dataOut.nCohInt*dataOut.windowOfFilter
1138 data['integrations_rtc'] = dataOut.nIncohInt
1131 # print("max incoh: ",dataOut.max_nIncohInt )
1139
1132 # n0 = 10*numpy.log10(dataOut.getNoise()/norm)
1140 meta = {}
1133 # data['noise'] = n0
1141
1134 #
1142 return data, meta
1135 # meta = {}
1143
1136 #
1144 def plot(self):
1137 # return data, meta
1145 # self.data.normalize_heights()
1138 #
1146 self.x = self.data.times
1139 # def plot(self):
1147 self.y = self.data.yrange
1140 # # self.data.normalize_heights()
1148 self.z = self.data['integrations_rtc']
1141 # self.x = self.data.times
1149
1142 # self.y = self.data.yrange
1150 #self.z = numpy.ma.masked_invalid(self.z)
1143 # self.z = self.data['noise']
1151
1144 #
1152 if self.decimation is None:
1145 # #self.z = numpy.ma.masked_invalid(self.z)
1153 x, y, z = self.fill_gaps(self.x, self.y, self.z)
1146 #
1154 else:
1147 # if self.decimation is None:
1155 x, y, z = self.fill_gaps(*self.decimate())
1148 # x, y, z = self.fill_gaps(self.x, self.y, self.z)
1156
1149 # else:
1157 for n, ax in enumerate(self.axes):
1150 # x, y, z = self.fill_gaps(*self.decimate())
1158
1151 #
1159 self.zmax = self.zmax if self.zmax is not None else numpy.max(
1152 # for n, ax in enumerate(self.axes):
1160 self.z[n])
1153 #
1161 self.zmin = self.zmin if self.zmin is not None else numpy.min(
1154 # self.zmax = self.zmax if self.zmax is not None else numpy.max(
1162 self.z[n])
1155 # self.z[n])
1163 data = self.data[-1]
1156 # self.zmin = self.zmin if self.zmin is not None else numpy.min(
1164 if ax.firsttime:
1157 # self.z[n])
1165 if self.zlimits is not None:
1158 # data = self.data[-1]
1166 self.zmin, self.zmax = self.zlimits[n]
1159 # if ax.firsttime:
1167
1160 # if self.zlimits is not None:
1168 ax.plt = ax.pcolormesh(x, y, z[n].T,
1161 # self.zmin, self.zmax = self.zlimits[n]
1169 vmin=self.zmin,
1162 #
1170 vmax=self.zmax,
1163 # ax.plt = ax.pcolormesh(x, y, z[n].T,
1171 cmap=self.cmaps[n]
1164 # vmin=self.zmin,
1172 )
1165 # vmax=self.zmax,
1173 if self.showprofile:
1166 # cmap=self.cmaps[n]
1174 ax.plot_profile = self.pf_axes[n].plot(data['integrations_rtc'][n], self.y)[0]
1167 # )
1175 self.pf_axes[n].set_xlabel('')
1168 # if self.showprofile:
1176 else:
1169 # ax.plot_profile = self.pf_axes[n].plot(data['noise'][n], self.y)[0]
1177 if self.zlimits is not None:
1170 # else:
1178 self.zmin, self.zmax = self.zlimits[n]
1171 # if self.zlimits is not None:
1179 ax.collections.remove(ax.collections[0])
1172 # self.zmin, self.zmax = self.zlimits[n]
1180 ax.plt = ax.pcolormesh(x, y, z[n].T ,
1173 # ax.collections.remove(ax.collections[0])
1181 vmin=self.zmin,
1174 # ax.plt = ax.pcolormesh(x, y, z[n].T ,
1182 vmax=self.zmax,
1175 # vmin=self.zmin,
1183 cmap=self.cmaps[n]
1176 # vmax=self.zmax,
1184 )
1177 # cmap=self.cmaps[n]
1185 if self.showprofile:
1178 # )
1186 ax.plot_profile.set_data(data['integrations_rtc'][n], self.y)
1179 # if self.showprofile:
1187 self.pf_axes[n].set_xlabel('')
1180 # ax.plot_profile.set_data(data['noise'][n], self.y)
@@ -1,685 +1,686
1 import os
1 import os
2 import time
2 import time
3 import datetime
3 import datetime
4
4
5 import numpy
5 import numpy
6 import h5py
6 import h5py
7
7
8 import schainpy.admin
8 import schainpy.admin
9 from schainpy.model.data.jrodata import *
9 from schainpy.model.data.jrodata import *
10 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
10 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
11 from schainpy.model.io.jroIO_base import *
11 from schainpy.model.io.jroIO_base import *
12 from schainpy.utils import log
12 from schainpy.utils import log
13
13
14
14
15 class HDFReader(Reader, ProcessingUnit):
15 class HDFReader(Reader, ProcessingUnit):
16 """Processing unit to read HDF5 format files
16 """Processing unit to read HDF5 format files
17
17
18 This unit reads HDF5 files created with `HDFWriter` operation contains
18 This unit reads HDF5 files created with `HDFWriter` operation contains
19 by default two groups Data and Metadata all variables would be saved as `dataOut`
19 by default two groups Data and Metadata all variables would be saved as `dataOut`
20 attributes.
20 attributes.
21 It is possible to read any HDF5 file by given the structure in the `description`
21 It is possible to read any HDF5 file by given the structure in the `description`
22 parameter, also you can add extra values to metadata with the parameter `extras`.
22 parameter, also you can add extra values to metadata with the parameter `extras`.
23
23
24 Parameters:
24 Parameters:
25 -----------
25 -----------
26 path : str
26 path : str
27 Path where files are located.
27 Path where files are located.
28 startDate : date
28 startDate : date
29 Start date of the files
29 Start date of the files
30 endDate : list
30 endDate : list
31 End date of the files
31 End date of the files
32 startTime : time
32 startTime : time
33 Start time of the files
33 Start time of the files
34 endTime : time
34 endTime : time
35 End time of the files
35 End time of the files
36 description : dict, optional
36 description : dict, optional
37 Dictionary with the description of the HDF5 file
37 Dictionary with the description of the HDF5 file
38 extras : dict, optional
38 extras : dict, optional
39 Dictionary with extra metadata to be be added to `dataOut`
39 Dictionary with extra metadata to be be added to `dataOut`
40
40
41 Examples
41 Examples
42 --------
42 --------
43
43
44 desc = {
44 desc = {
45 'Data': {
45 'Data': {
46 'data_output': ['u', 'v', 'w'],
46 'data_output': ['u', 'v', 'w'],
47 'utctime': 'timestamps',
47 'utctime': 'timestamps',
48 } ,
48 } ,
49 'Metadata': {
49 'Metadata': {
50 'heightList': 'heights'
50 'heightList': 'heights'
51 }
51 }
52 }
52 }
53
53
54 desc = {
54 desc = {
55 'Data': {
55 'Data': {
56 'data_output': 'winds',
56 'data_output': 'winds',
57 'utctime': 'timestamps'
57 'utctime': 'timestamps'
58 },
58 },
59 'Metadata': {
59 'Metadata': {
60 'heightList': 'heights'
60 'heightList': 'heights'
61 }
61 }
62 }
62 }
63
63
64 extras = {
64 extras = {
65 'timeZone': 300
65 'timeZone': 300
66 }
66 }
67
67
68 reader = project.addReadUnit(
68 reader = project.addReadUnit(
69 name='HDFReader',
69 name='HDFReader',
70 path='/path/to/files',
70 path='/path/to/files',
71 startDate='2019/01/01',
71 startDate='2019/01/01',
72 endDate='2019/01/31',
72 endDate='2019/01/31',
73 startTime='00:00:00',
73 startTime='00:00:00',
74 endTime='23:59:59',
74 endTime='23:59:59',
75 # description=json.dumps(desc),
75 # description=json.dumps(desc),
76 # extras=json.dumps(extras),
76 # extras=json.dumps(extras),
77 )
77 )
78
78
79 """
79 """
80
80
81 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'description', 'extras']
81 __attrs__ = ['path', 'startDate', 'endDate', 'startTime', 'endTime', 'description', 'extras']
82
82
83 def __init__(self):
83 def __init__(self):
84 ProcessingUnit.__init__(self)
84 ProcessingUnit.__init__(self)
85
85
86 self.ext = ".hdf5"
86 self.ext = ".hdf5"
87 self.optchar = "D"
87 self.optchar = "D"
88 self.meta = {}
88 self.meta = {}
89 self.data = {}
89 self.data = {}
90 self.open_file = h5py.File
90 self.open_file = h5py.File
91 self.open_mode = 'r'
91 self.open_mode = 'r'
92 self.description = {}
92 self.description = {}
93 self.extras = {}
93 self.extras = {}
94 self.filefmt = "*%Y%j***"
94 self.filefmt = "*%Y%j***"
95 self.folderfmt = "*%Y%j"
95 self.folderfmt = "*%Y%j"
96 self.utcoffset = 0
96 self.utcoffset = 0
97
97
98 self.dataOut = Parameters()
98 self.dataOut = Parameters()
99 self.dataOut.error=False ## NOTE: Importante definir esto antes inicio
99 self.dataOut.error=False ## NOTE: Importante definir esto antes inicio
100 self.dataOut.flagNoData = True
100 self.dataOut.flagNoData = True
101
101
102 def setup(self, **kwargs):
102 def setup(self, **kwargs):
103
103
104 self.set_kwargs(**kwargs)
104 self.set_kwargs(**kwargs)
105 if not self.ext.startswith('.'):
105 if not self.ext.startswith('.'):
106 self.ext = '.{}'.format(self.ext)
106 self.ext = '.{}'.format(self.ext)
107
107
108 if self.online:
108 if self.online:
109 log.log("Searching files in online mode...", self.name)
109 log.log("Searching files in online mode...", self.name)
110
110
111 for nTries in range(self.nTries):
111 for nTries in range(self.nTries):
112 fullpath = self.searchFilesOnLine(self.path, self.startDate,
112 fullpath = self.searchFilesOnLine(self.path, self.startDate,
113 self.endDate, self.expLabel, self.ext, self.walk,
113 self.endDate, self.expLabel, self.ext, self.walk,
114 self.filefmt, self.folderfmt)
114 self.filefmt, self.folderfmt)
115 pathname, filename = os.path.split(fullpath)
115 pathname, filename = os.path.split(fullpath)
116
116
117 try:
117 try:
118 fullpath = next(fullpath)
118 fullpath = next(fullpath)
119
119
120 except:
120 except:
121 fullpath = None
121 fullpath = None
122
122
123 if fullpath:
123 if fullpath:
124 break
124 break
125
125
126 log.warning(
126 log.warning(
127 'Waiting {} sec for a valid file in {}: try {} ...'.format(
127 'Waiting {} sec for a valid file in {}: try {} ...'.format(
128 self.delay, self.path, nTries + 1),
128 self.delay, self.path, nTries + 1),
129 self.name)
129 self.name)
130 time.sleep(self.delay)
130 time.sleep(self.delay)
131
131
132 if not(fullpath):
132 if not(fullpath):
133 raise schainpy.admin.SchainError(
133 raise schainpy.admin.SchainError(
134 'There isn\'t any valid file in {}'.format(self.path))
134 'There isn\'t any valid file in {}'.format(self.path))
135
135
136 pathname, filename = os.path.split(fullpath)
136 pathname, filename = os.path.split(fullpath)
137 self.year = int(filename[1:5])
137 self.year = int(filename[1:5])
138 self.doy = int(filename[5:8])
138 self.doy = int(filename[5:8])
139 self.set = int(filename[8:11]) - 1
139 self.set = int(filename[8:11]) - 1
140 else:
140 else:
141 log.log("Searching files in {}".format(self.path), self.name)
141 log.log("Searching files in {}".format(self.path), self.name)
142 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
142 self.filenameList = self.searchFilesOffLine(self.path, self.startDate,
143 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
143 self.endDate, self.expLabel, self.ext, self.walk, self.filefmt, self.folderfmt)
144
144
145 self.setNextFile()
145 self.setNextFile()
146
146
147
147
148
148
149
149
150 def readFirstHeader(self):
150 def readFirstHeader(self):
151 '''Read metadata and data'''
151 '''Read metadata and data'''
152
152
153 self.__readMetadata()
153 self.__readMetadata()
154 self.__readData()
154 self.__readData()
155 self.__setBlockList()
155 self.__setBlockList()
156
156
157 for attr in self.meta:
157 for attr in self.meta:
158 setattr(self.dataOut, attr, self.meta[attr])
158 setattr(self.dataOut, attr, self.meta[attr])
159 self.blockIndex = 0
159 self.blockIndex = 0
160
160
161 return
161 return
162
162
163 def __setBlockList(self):
163 def __setBlockList(self):
164 '''
164 '''
165 Selects the data within the times defined
165 Selects the data within the times defined
166
166
167 self.fp
167 self.fp
168 self.startTime
168 self.startTime
169 self.endTime
169 self.endTime
170 self.blockList
170 self.blockList
171 self.blocksPerFile
171 self.blocksPerFile
172
172
173 '''
173 '''
174
174
175 startTime = self.startTime
175 startTime = self.startTime
176 endTime = self.endTime
176 endTime = self.endTime
177 thisUtcTime = self.data['utctime'] + self.utcoffset
177 thisUtcTime = self.data['utctime'] + self.utcoffset
178 self.interval = numpy.min(thisUtcTime[1:] - thisUtcTime[:-1])
178 self.interval = numpy.min(thisUtcTime[1:] - thisUtcTime[:-1])
179 thisDatetime = datetime.datetime.utcfromtimestamp(thisUtcTime[0])
179 thisDatetime = datetime.datetime.utcfromtimestamp(thisUtcTime[0])
180 self.startFileDatetime = thisDatetime
180 self.startFileDatetime = thisDatetime
181 thisDate = thisDatetime.date()
181 thisDate = thisDatetime.date()
182 thisTime = thisDatetime.time()
182 thisTime = thisDatetime.time()
183
183
184 startUtcTime = (datetime.datetime.combine(thisDate, startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
184 startUtcTime = (datetime.datetime.combine(thisDate, startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
185 endUtcTime = (datetime.datetime.combine(thisDate, endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
185 endUtcTime = (datetime.datetime.combine(thisDate, endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
186
186
187 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
187 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
188
188
189 self.blockList = ind
189 self.blockList = ind
190 self.blocksPerFile = len(ind)
190 self.blocksPerFile = len(ind)
191 self.blocksPerFile = len(thisUtcTime)
191 self.blocksPerFile = len(thisUtcTime)
192 return
192 return
193
193
194 def __readMetadata(self):
194 def __readMetadata(self):
195 '''
195 '''
196 Reads Metadata
196 Reads Metadata
197 '''
197 '''
198
198
199 meta = {}
199 meta = {}
200
200
201 if self.description:
201 if self.description:
202 for key, value in self.description['Metadata'].items():
202 for key, value in self.description['Metadata'].items():
203 meta[key] = self.fp[value][()]
203 meta[key] = self.fp[value][()]
204 else:
204 else:
205 grp = self.fp['Metadata']
205 grp = self.fp['Metadata']
206 for name in grp:
206 for name in grp:
207 meta[name] = grp[name][()]
207 meta[name] = grp[name][()]
208
208
209 if self.extras:
209 if self.extras:
210 for key, value in self.extras.items():
210 for key, value in self.extras.items():
211 meta[key] = value
211 meta[key] = value
212 self.meta = meta
212 self.meta = meta
213
213
214 return
214 return
215
215
216
216
217
217
218 def checkForRealPath(self, nextFile, nextDay):
218 def checkForRealPath(self, nextFile, nextDay):
219
219
220 # print("check FRP")
220 # print("check FRP")
221 # dt = self.startFileDatetime + datetime.timedelta(1)
221 # dt = self.startFileDatetime + datetime.timedelta(1)
222 # filename = '{}.{}{}'.format(self.path, dt.strftime('%Y%m%d'), self.ext)
222 # filename = '{}.{}{}'.format(self.path, dt.strftime('%Y%m%d'), self.ext)
223 # fullfilename = os.path.join(self.path, filename)
223 # fullfilename = os.path.join(self.path, filename)
224 # print("check Path ",fullfilename,filename)
224 # print("check Path ",fullfilename,filename)
225 # if os.path.exists(fullfilename):
225 # if os.path.exists(fullfilename):
226 # return fullfilename, filename
226 # return fullfilename, filename
227 # return None, filename
227 # return None, filename
228 return None,None
228 return None,None
229
229
230 def __readData(self):
230 def __readData(self):
231
231
232 data = {}
232 data = {}
233
233
234 if self.description:
234 if self.description:
235 for key, value in self.description['Data'].items():
235 for key, value in self.description['Data'].items():
236 if isinstance(value, str):
236 if isinstance(value, str):
237 if isinstance(self.fp[value], h5py.Dataset):
237 if isinstance(self.fp[value], h5py.Dataset):
238 data[key] = self.fp[value][()]
238 data[key] = self.fp[value][()]
239 elif isinstance(self.fp[value], h5py.Group):
239 elif isinstance(self.fp[value], h5py.Group):
240 array = []
240 array = []
241 for ch in self.fp[value]:
241 for ch in self.fp[value]:
242 array.append(self.fp[value][ch][()])
242 array.append(self.fp[value][ch][()])
243 data[key] = numpy.array(array)
243 data[key] = numpy.array(array)
244 elif isinstance(value, list):
244 elif isinstance(value, list):
245 array = []
245 array = []
246 for ch in value:
246 for ch in value:
247 array.append(self.fp[ch][()])
247 array.append(self.fp[ch][()])
248 data[key] = numpy.array(array)
248 data[key] = numpy.array(array)
249 else:
249 else:
250 grp = self.fp['Data']
250 grp = self.fp['Data']
251 for name in grp:
251 for name in grp:
252 if isinstance(grp[name], h5py.Dataset):
252 if isinstance(grp[name], h5py.Dataset):
253 array = grp[name][()]
253 array = grp[name][()]
254 elif isinstance(grp[name], h5py.Group):
254 elif isinstance(grp[name], h5py.Group):
255 array = []
255 array = []
256 for ch in grp[name]:
256 for ch in grp[name]:
257 array.append(grp[name][ch][()])
257 array.append(grp[name][ch][()])
258 array = numpy.array(array)
258 array = numpy.array(array)
259 else:
259 else:
260 log.warning('Unknown type: {}'.format(name))
260 log.warning('Unknown type: {}'.format(name))
261
261
262 if name in self.description:
262 if name in self.description:
263 key = self.description[name]
263 key = self.description[name]
264 else:
264 else:
265 key = name
265 key = name
266 data[key] = array
266 data[key] = array
267
267
268 self.data = data
268 self.data = data
269 return
269 return
270
270
271 def getData(self):
271 def getData(self):
272 if not self.isDateTimeInRange(self.startFileDatetime, self.startDate, self.endDate, self.startTime, self.endTime):
272 if not self.isDateTimeInRange(self.startFileDatetime, self.startDate, self.endDate, self.startTime, self.endTime):
273 self.dataOut.flagNoData = True
273 self.dataOut.flagNoData = True
274 self.blockIndex = self.blocksPerFile
274 self.blockIndex = self.blocksPerFile
275 self.dataOut.error = True # TERMINA EL PROGRAMA
275 self.dataOut.error = True # TERMINA EL PROGRAMA
276 return
276 return
277 for attr in self.data:
277 for attr in self.data:
278
278
279 if self.data[attr].ndim == 1:
279 if self.data[attr].ndim == 1:
280 setattr(self.dataOut, attr, self.data[attr][self.blockIndex])
280 setattr(self.dataOut, attr, self.data[attr][self.blockIndex])
281 else:
281 else:
282 setattr(self.dataOut, attr, self.data[attr][:, self.blockIndex])
282 setattr(self.dataOut, attr, self.data[attr][:, self.blockIndex])
283
283
284
284
285 self.blockIndex += 1
285 self.blockIndex += 1
286
286
287 if self.blockIndex == 1:
287 if self.blockIndex == 1:
288 log.log("Block No. {}/{} -> {}".format(
288 log.log("Block No. {}/{} -> {}".format(
289 self.blockIndex,
289 self.blockIndex,
290 self.blocksPerFile,
290 self.blocksPerFile,
291 self.dataOut.datatime.ctime()), self.name)
291 self.dataOut.datatime.ctime()), self.name)
292 else:
292 else:
293 log.log("Block No. {}/{} ".format(
293 log.log("Block No. {}/{} ".format(
294 self.blockIndex,
294 self.blockIndex,
295 self.blocksPerFile),self.name)
295 self.blocksPerFile),self.name)
296
296
297 if self.blockIndex == self.blocksPerFile:
297 if self.blockIndex == self.blocksPerFile:
298 self.setNextFile()
298 self.setNextFile()
299
299
300 self.dataOut.flagNoData = False
300 self.dataOut.flagNoData = False
301
301
302
302
303 def run(self, **kwargs):
303 def run(self, **kwargs):
304
304
305 if not(self.isConfig):
305 if not(self.isConfig):
306 self.setup(**kwargs)
306 self.setup(**kwargs)
307 self.isConfig = True
307 self.isConfig = True
308
308
309 self.getData()
309 self.getData()
310
310
311 @MPDecorator
311 @MPDecorator
312 class HDFWriter(Operation):
312 class HDFWriter(Operation):
313 """Operation to write HDF5 files.
313 """Operation to write HDF5 files.
314
314
315 The HDF5 file contains by default two groups Data and Metadata where
315 The HDF5 file contains by default two groups Data and Metadata where
316 you can save any `dataOut` attribute specified by `dataList` and `metadataList`
316 you can save any `dataOut` attribute specified by `dataList` and `metadataList`
317 parameters, data attributes are normaly time dependent where the metadata
317 parameters, data attributes are normaly time dependent where the metadata
318 are not.
318 are not.
319 It is possible to customize the structure of the HDF5 file with the
319 It is possible to customize the structure of the HDF5 file with the
320 optional description parameter see the examples.
320 optional description parameter see the examples.
321
321
322 Parameters:
322 Parameters:
323 -----------
323 -----------
324 path : str
324 path : str
325 Path where files will be saved.
325 Path where files will be saved.
326 blocksPerFile : int
326 blocksPerFile : int
327 Number of blocks per file
327 Number of blocks per file
328 metadataList : list
328 metadataList : list
329 List of the dataOut attributes that will be saved as metadata
329 List of the dataOut attributes that will be saved as metadata
330 dataList : int
330 dataList : int
331 List of the dataOut attributes that will be saved as data
331 List of the dataOut attributes that will be saved as data
332 setType : bool
332 setType : bool
333 If True the name of the files corresponds to the timestamp of the data
333 If True the name of the files corresponds to the timestamp of the data
334 description : dict, optional
334 description : dict, optional
335 Dictionary with the desired description of the HDF5 file
335 Dictionary with the desired description of the HDF5 file
336
336
337 Examples
337 Examples
338 --------
338 --------
339
339
340 desc = {
340 desc = {
341 'data_output': {'winds': ['z', 'w', 'v']},
341 'data_output': {'winds': ['z', 'w', 'v']},
342 'utctime': 'timestamps',
342 'utctime': 'timestamps',
343 'heightList': 'heights'
343 'heightList': 'heights'
344 }
344 }
345 desc = {
345 desc = {
346 'data_output': ['z', 'w', 'v'],
346 'data_output': ['z', 'w', 'v'],
347 'utctime': 'timestamps',
347 'utctime': 'timestamps',
348 'heightList': 'heights'
348 'heightList': 'heights'
349 }
349 }
350 desc = {
350 desc = {
351 'Data': {
351 'Data': {
352 'data_output': 'winds',
352 'data_output': 'winds',
353 'utctime': 'timestamps'
353 'utctime': 'timestamps'
354 },
354 },
355 'Metadata': {
355 'Metadata': {
356 'heightList': 'heights'
356 'heightList': 'heights'
357 }
357 }
358 }
358 }
359
359
360 writer = proc_unit.addOperation(name='HDFWriter')
360 writer = proc_unit.addOperation(name='HDFWriter')
361 writer.addParameter(name='path', value='/path/to/file')
361 writer.addParameter(name='path', value='/path/to/file')
362 writer.addParameter(name='blocksPerFile', value='32')
362 writer.addParameter(name='blocksPerFile', value='32')
363 writer.addParameter(name='metadataList', value='heightList,timeZone')
363 writer.addParameter(name='metadataList', value='heightList,timeZone')
364 writer.addParameter(name='dataList',value='data_output,utctime')
364 writer.addParameter(name='dataList',value='data_output,utctime')
365 # writer.addParameter(name='description',value=json.dumps(desc))
365 # writer.addParameter(name='description',value=json.dumps(desc))
366
366
367 """
367 """
368
368
369 ext = ".hdf5"
369 ext = ".hdf5"
370 optchar = "D"
370 optchar = "D"
371 filename = None
371 filename = None
372 path = None
372 path = None
373 setFile = None
373 setFile = None
374 fp = None
374 fp = None
375 firsttime = True
375 firsttime = True
376 #Configurations
376 #Configurations
377 blocksPerFile = None
377 blocksPerFile = None
378 blockIndex = None
378 blockIndex = None
379 dataOut = None #eval ??????
379 dataOut = None #eval ??????
380 #Data Arrays
380 #Data Arrays
381 dataList = None
381 dataList = None
382 metadataList = None
382 metadataList = None
383 currentDay = None
383 currentDay = None
384 lastTime = None
384 lastTime = None
385 timeZone = "ut"
385 timeZone = "ut"
386 hourLimit = 3
386 hourLimit = 3
387 breakDays = True
387 breakDays = True
388
388
389 def __init__(self):
389 def __init__(self):
390
390
391 Operation.__init__(self)
391 Operation.__init__(self)
392
392
393
393
394 def setup(self, path=None, blocksPerFile=10, metadataList=None, dataList=None, setType=None,
394 def setup(self, path=None, blocksPerFile=10, metadataList=None, dataList=None, setType=None,
395 description={},timeZone = "ut",hourLimit = 3, breakDays=True):
395 description={},timeZone = "ut",hourLimit = 3, breakDays=True):
396 self.path = path
396 self.path = path
397 self.blocksPerFile = blocksPerFile
397 self.blocksPerFile = blocksPerFile
398 self.metadataList = metadataList
398 self.metadataList = metadataList
399 self.dataList = [s.strip() for s in dataList]
399 self.dataList = [s.strip() for s in dataList]
400 self.setType = setType
400 self.setType = setType
401 self.description = description
401 self.description = description
402 self.timeZone = timeZone
402 self.timeZone = timeZone
403 self.hourLimit = hourLimit
403 self.hourLimit = hourLimit
404 self.breakDays = breakDays
404 self.breakDays = breakDays
405
405
406 if self.metadataList is None:
406 if self.metadataList is None:
407 self.metadataList = self.dataOut.metadata_list
407 self.metadataList = self.dataOut.metadata_list
408
408
409 tableList = []
409 tableList = []
410 dsList = []
410 dsList = []
411
411
412 for i in range(len(self.dataList)):
412 for i in range(len(self.dataList)):
413 dsDict = {}
413 dsDict = {}
414 if hasattr(self.dataOut, self.dataList[i]):
414 if hasattr(self.dataOut, self.dataList[i]):
415 dataAux = getattr(self.dataOut, self.dataList[i])
415 dataAux = getattr(self.dataOut, self.dataList[i])
416 dsDict['variable'] = self.dataList[i]
416 dsDict['variable'] = self.dataList[i]
417 else:
417 else:
418 log.warning('Attribute {} not found in dataOut'.format(self.dataList[i]),self.name)
418 log.warning('Attribute {} not found in dataOut'.format(self.dataList[i]),self.name)
419 continue
419 continue
420
420
421 if dataAux is None:
421 if dataAux is None:
422 continue
422 continue
423 elif isinstance(dataAux, (int, float, numpy.integer, numpy.float)):
423 elif isinstance(dataAux, (int, float, numpy.integer, numpy.float)):
424 dsDict['nDim'] = 0
424 dsDict['nDim'] = 0
425 else:
425 else:
426 dsDict['nDim'] = len(dataAux.shape)
426 dsDict['nDim'] = len(dataAux.shape)
427 dsDict['shape'] = dataAux.shape
427 dsDict['shape'] = dataAux.shape
428 dsDict['dsNumber'] = dataAux.shape[0]
428 dsDict['dsNumber'] = dataAux.shape[0]
429 dsDict['dtype'] = dataAux.dtype
429 dsDict['dtype'] = dataAux.dtype
430
430
431 dsList.append(dsDict)
431 dsList.append(dsDict)
432
432
433 self.blockIndex = 0
433 self.blockIndex = 0
434 self.dsList = dsList
434 self.dsList = dsList
435 self.currentDay = self.dataOut.datatime.date()
435 self.currentDay = self.dataOut.datatime.date()
436
436
437
437
438 def timeFlag(self):
438 def timeFlag(self):
439 currentTime = self.dataOut.utctime
439 currentTime = self.dataOut.utctime
440 timeTuple = None
440 timeTuple = None
441 if self.timeZone == "lt":
441 if self.timeZone == "lt":
442 timeTuple = time.localtime(currentTime)
442 timeTuple = time.localtime(currentTime)
443 else :
443 else :
444 timeTuple = time.gmtime(currentTime)
444 timeTuple = time.gmtime(currentTime)
445
445
446 dataDay = timeTuple.tm_yday
446 dataDay = timeTuple.tm_yday
447
447
448 if self.lastTime is None:
448 if self.lastTime is None:
449 self.lastTime = currentTime
449 self.lastTime = currentTime
450 self.currentDay = dataDay
450 self.currentDay = dataDay
451 return False
451 return False
452
452
453 timeDiff = currentTime - self.lastTime
453 timeDiff = currentTime - self.lastTime
454
454
455 #Si el dia es diferente o si la diferencia entre un dato y otro supera self.hourLimit
455 #Si el dia es diferente o si la diferencia entre un dato y otro supera self.hourLimit
456 if (dataDay != self.currentDay) and self.breakDays:
456 if (dataDay != self.currentDay) and self.breakDays:
457 self.currentDay = dataDay
457 self.currentDay = dataDay
458 return True
458 return True
459 elif timeDiff > self.hourLimit*60*60:
459 elif timeDiff > self.hourLimit*60*60:
460 self.lastTime = currentTime
460 self.lastTime = currentTime
461 return True
461 return True
462 else:
462 else:
463 self.lastTime = currentTime
463 self.lastTime = currentTime
464 return False
464 return False
465
465
466 def run(self, dataOut,**kwargs):
466 def run(self, dataOut,**kwargs):
467
467
468 self.dataOut = dataOut.copy()
468 self.dataOut = dataOut
469
469 if not(self.isConfig):
470 if not(self.isConfig):
470 self.setup(**kwargs)
471 self.setup(**kwargs)
471
472
472 self.isConfig = True
473 self.isConfig = True
473 self.setNextFile()
474 self.setNextFile()
474
475
475 self.putData()
476 self.putData()
476
477
477 #return self.dataOut
478 #return self.dataOut
478
479
479 def setNextFile(self):
480 def setNextFile(self):
480
481
481 ext = self.ext
482 ext = self.ext
482 path = self.path
483 path = self.path
483 setFile = self.setFile
484 setFile = self.setFile
484 timeTuple = None
485 timeTuple = None
485 if self.timeZone == "lt":
486 if self.timeZone == "lt":
486 timeTuple = time.localtime(self.dataOut.utctime)
487 timeTuple = time.localtime(self.dataOut.utctime)
487 elif self.timeZone == "ut":
488 elif self.timeZone == "ut":
488 timeTuple = time.gmtime(self.dataOut.utctime)
489 timeTuple = time.gmtime(self.dataOut.utctime)
489 #print("path: ",timeTuple)
490 #print("path: ",timeTuple)
490 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
491 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
491 fullpath = os.path.join(path, subfolder)
492 fullpath = os.path.join(path, subfolder)
492
493
493 if os.path.exists(fullpath):
494 if os.path.exists(fullpath):
494 filesList = os.listdir(fullpath)
495 filesList = os.listdir(fullpath)
495 filesList = [k for k in filesList if k.startswith(self.optchar)]
496 filesList = [k for k in filesList if k.startswith(self.optchar)]
496 if len( filesList ) > 0:
497 if len( filesList ) > 0:
497 filesList = sorted(filesList, key=str.lower)
498 filesList = sorted(filesList, key=str.lower)
498 filen = filesList[-1]
499 filen = filesList[-1]
499 # el filename debera tener el siguiente formato
500 # el filename debera tener el siguiente formato
500 # 0 1234 567 89A BCDE (hex)
501 # 0 1234 567 89A BCDE (hex)
501 # x YYYY DDD SSS .ext
502 # x YYYY DDD SSS .ext
502 if isNumber(filen[8:11]):
503 if isNumber(filen[8:11]):
503 setFile = int(filen[8:11]) #inicializo mi contador de seteo al seteo del ultimo file
504 setFile = int(filen[8:11]) #inicializo mi contador de seteo al seteo del ultimo file
504 else:
505 else:
505 setFile = -1
506 setFile = -1
506 else:
507 else:
507 setFile = -1 #inicializo mi contador de seteo
508 setFile = -1 #inicializo mi contador de seteo
508 else:
509 else:
509 os.makedirs(fullpath)
510 os.makedirs(fullpath)
510 setFile = -1 #inicializo mi contador de seteo
511 setFile = -1 #inicializo mi contador de seteo
511
512
512 if self.setType is None:
513 if self.setType is None:
513 setFile += 1
514 setFile += 1
514 file = '%s%4.4d%3.3d%03d%s' % (self.optchar,
515 file = '%s%4.4d%3.3d%03d%s' % (self.optchar,
515 timeTuple.tm_year,
516 timeTuple.tm_year,
516 timeTuple.tm_yday,
517 timeTuple.tm_yday,
517 setFile,
518 setFile,
518 ext )
519 ext )
519 else:
520 else:
520 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
521 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
521 file = '%s%4.4d%3.3d%04d%s' % (self.optchar,
522 file = '%s%4.4d%3.3d%04d%s' % (self.optchar,
522 timeTuple.tm_year,
523 timeTuple.tm_year,
523 timeTuple.tm_yday,
524 timeTuple.tm_yday,
524 setFile,
525 setFile,
525 ext )
526 ext )
526
527
527 self.filename = os.path.join( path, subfolder, file )
528 self.filename = os.path.join( path, subfolder, file )
528
529
529
530
530
531
531 def getLabel(self, name, x=None):
532 def getLabel(self, name, x=None):
532
533
533 if x is None:
534 if x is None:
534 if 'Data' in self.description:
535 if 'Data' in self.description:
535 data = self.description['Data']
536 data = self.description['Data']
536 if 'Metadata' in self.description:
537 if 'Metadata' in self.description:
537 data.update(self.description['Metadata'])
538 data.update(self.description['Metadata'])
538 else:
539 else:
539 data = self.description
540 data = self.description
540 if name in data:
541 if name in data:
541 if isinstance(data[name], str):
542 if isinstance(data[name], str):
542 return data[name]
543 return data[name]
543 elif isinstance(data[name], list):
544 elif isinstance(data[name], list):
544 return None
545 return None
545 elif isinstance(data[name], dict):
546 elif isinstance(data[name], dict):
546 for key, value in data[name].items():
547 for key, value in data[name].items():
547 return key
548 return key
548 return name
549 return name
549 else:
550 else:
550 if 'Metadata' in self.description:
551 if 'Metadata' in self.description:
551 meta = self.description['Metadata']
552 meta = self.description['Metadata']
552 else:
553 else:
553 meta = self.description
554 meta = self.description
554 if name in meta:
555 if name in meta:
555 if isinstance(meta[name], list):
556 if isinstance(meta[name], list):
556 return meta[name][x]
557 return meta[name][x]
557 elif isinstance(meta[name], dict):
558 elif isinstance(meta[name], dict):
558 for key, value in meta[name].items():
559 for key, value in meta[name].items():
559 return value[x]
560 return value[x]
560 if 'cspc' in name:
561 if 'cspc' in name:
561 return 'pair{:02d}'.format(x)
562 return 'pair{:02d}'.format(x)
562 else:
563 else:
563 return 'channel{:02d}'.format(x)
564 return 'channel{:02d}'.format(x)
564
565
565 def writeMetadata(self, fp):
566 def writeMetadata(self, fp):
566
567
567 if self.description:
568 if self.description:
568 if 'Metadata' in self.description:
569 if 'Metadata' in self.description:
569 grp = fp.create_group('Metadata')
570 grp = fp.create_group('Metadata')
570 else:
571 else:
571 grp = fp
572 grp = fp
572 else:
573 else:
573 grp = fp.create_group('Metadata')
574 grp = fp.create_group('Metadata')
574
575
575 for i in range(len(self.metadataList)):
576 for i in range(len(self.metadataList)):
576 if not hasattr(self.dataOut, self.metadataList[i]):
577 if not hasattr(self.dataOut, self.metadataList[i]):
577 log.warning('Metadata: `{}` not found'.format(self.metadataList[i]), self.name)
578 log.warning('Metadata: `{}` not found'.format(self.metadataList[i]), self.name)
578 continue
579 continue
579 value = getattr(self.dataOut, self.metadataList[i])
580 value = getattr(self.dataOut, self.metadataList[i])
580 if isinstance(value, bool):
581 if isinstance(value, bool):
581 if value is True:
582 if value is True:
582 value = 1
583 value = 1
583 else:
584 else:
584 value = 0
585 value = 0
585 grp.create_dataset(self.getLabel(self.metadataList[i]), data=value)
586 grp.create_dataset(self.getLabel(self.metadataList[i]), data=value)
586 return
587 return
587
588
588 def writeData(self, fp):
589 def writeData(self, fp):
589
590
590 if self.description:
591 if self.description:
591 if 'Data' in self.description:
592 if 'Data' in self.description:
592 grp = fp.create_group('Data')
593 grp = fp.create_group('Data')
593 else:
594 else:
594 grp = fp
595 grp = fp
595 else:
596 else:
596 grp = fp.create_group('Data')
597 grp = fp.create_group('Data')
597
598
598 dtsets = []
599 dtsets = []
599 data = []
600 data = []
600
601
601 for dsInfo in self.dsList:
602 for dsInfo in self.dsList:
602 if dsInfo['nDim'] == 0:
603 if dsInfo['nDim'] == 0:
603 ds = grp.create_dataset(
604 ds = grp.create_dataset(
604 self.getLabel(dsInfo['variable']),
605 self.getLabel(dsInfo['variable']),
605 (self.blocksPerFile, ),
606 (self.blocksPerFile, ),
606 chunks=True,
607 chunks=True,
607 dtype=numpy.float64)
608 dtype=numpy.float64)
608 dtsets.append(ds)
609 dtsets.append(ds)
609 data.append((dsInfo['variable'], -1))
610 data.append((dsInfo['variable'], -1))
610 else:
611 else:
611 label = self.getLabel(dsInfo['variable'])
612 label = self.getLabel(dsInfo['variable'])
612 if label is not None:
613 if label is not None:
613 sgrp = grp.create_group(label)
614 sgrp = grp.create_group(label)
614 else:
615 else:
615 sgrp = grp
616 sgrp = grp
616 for i in range(dsInfo['dsNumber']):
617 for i in range(dsInfo['dsNumber']):
617 ds = sgrp.create_dataset(
618 ds = sgrp.create_dataset(
618 self.getLabel(dsInfo['variable'], i),
619 self.getLabel(dsInfo['variable'], i),
619 (self.blocksPerFile, ) + dsInfo['shape'][1:],
620 (self.blocksPerFile, ) + dsInfo['shape'][1:],
620 chunks=True,
621 chunks=True,
621 dtype=dsInfo['dtype'])
622 dtype=dsInfo['dtype'])
622 dtsets.append(ds)
623 dtsets.append(ds)
623 data.append((dsInfo['variable'], i))
624 data.append((dsInfo['variable'], i))
624 fp.flush()
625 fp.flush()
625
626
626 log.log('Creating file: {}'.format(fp.filename), self.name)
627 log.log('Creating file: {}'.format(fp.filename), self.name)
627
628
628 self.ds = dtsets
629 self.ds = dtsets
629 self.data = data
630 self.data = data
630 self.firsttime = True
631 self.firsttime = True
631
632
632 return
633 return
633
634
634 def putData(self):
635 def putData(self):
635
636
636 if (self.blockIndex == self.blocksPerFile) or self.timeFlag():
637 if (self.blockIndex == self.blocksPerFile) or self.timeFlag():
637 self.closeFile()
638 self.closeFile()
638 self.setNextFile()
639 self.setNextFile()
639 self.dataOut.flagNoData = False
640 self.dataOut.flagNoData = False
640 self.blockIndex = 0
641 self.blockIndex = 0
641 return
642 return
642
643
643
644
644
645
645 if self.blockIndex == 0:
646 if self.blockIndex == 0:
646 #Escribir metadata Aqui???
647 #Escribir metadata Aqui???
647 #Setting HDF5 File
648 #Setting HDF5 File
648 self.fp = h5py.File(self.filename, 'w')
649 self.fp = h5py.File(self.filename, 'w')
649 #write metadata
650 #write metadata
650 self.writeMetadata(self.fp)
651 self.writeMetadata(self.fp)
651 #Write data
652 #Write data
652 self.writeData(self.fp)
653 self.writeData(self.fp)
653 log.log('Block No. {}/{} --> {}'.format(self.blockIndex+1, self.blocksPerFile,self.dataOut.datatime.ctime()), self.name)
654 log.log('Block No. {}/{} --> {}'.format(self.blockIndex+1, self.blocksPerFile,self.dataOut.datatime.ctime()), self.name)
654 elif (self.blockIndex % 10 ==0):
655 elif (self.blockIndex % 10 ==0):
655 log.log('Block No. {}/{} --> {}'.format(self.blockIndex+1, self.blocksPerFile,self.dataOut.datatime.ctime()), self.name)
656 log.log('Block No. {}/{} --> {}'.format(self.blockIndex+1, self.blocksPerFile,self.dataOut.datatime.ctime()), self.name)
656 else:
657 else:
657
658
658 log.log('Block No. {}/{}'.format(self.blockIndex+1, self.blocksPerFile), self.name)
659 log.log('Block No. {}/{}'.format(self.blockIndex+1, self.blocksPerFile), self.name)
659
660
660 for i, ds in enumerate(self.ds):
661 for i, ds in enumerate(self.ds):
661 attr, ch = self.data[i]
662 attr, ch = self.data[i]
662 if ch == -1:
663 if ch == -1:
663 ds[self.blockIndex] = getattr(self.dataOut, attr)
664 ds[self.blockIndex] = getattr(self.dataOut, attr)
664 else:
665 else:
665 ds[self.blockIndex] = getattr(self.dataOut, attr)[ch]
666 ds[self.blockIndex] = getattr(self.dataOut, attr)[ch]
666
667
667 self.blockIndex += 1
668 self.blockIndex += 1
668
669
669 self.fp.flush()
670 self.fp.flush()
670 self.dataOut.flagNoData = True
671 self.dataOut.flagNoData = True
671
672
672
673
673 def closeFile(self):
674 def closeFile(self):
674
675
675 if self.blockIndex != self.blocksPerFile:
676 if self.blockIndex != self.blocksPerFile:
676 for ds in self.ds:
677 for ds in self.ds:
677 ds.resize(self.blockIndex, axis=0)
678 ds.resize(self.blockIndex, axis=0)
678
679
679 if self.fp:
680 if self.fp:
680 self.fp.flush()
681 self.fp.flush()
681 self.fp.close()
682 self.fp.close()
682
683
683 def close(self):
684 def close(self):
684
685
685 self.closeFile()
686 self.closeFile()
@@ -1,233 +1,233
1 '''
1 '''
2 Base clases to create Processing units and operations, the MPDecorator
2 Base clases to create Processing units and operations, the MPDecorator
3 must be used in plotting and writing operations to allow to run as an
3 must be used in plotting and writing operations to allow to run as an
4 external process.
4 external process.
5 '''
5 '''
6 import os
6 import os
7 import inspect
7 import inspect
8 import zmq
8 import zmq
9 import time
9 import time
10 import pickle
10 import pickle
11 import traceback
11 import traceback
12 from threading import Thread
12 from threading import Thread
13 from multiprocessing import Process, Queue
13 from multiprocessing import Process, Queue
14 from schainpy.utils import log
14 from schainpy.utils import log
15 import copy
15 import copy
16 QUEUE_SIZE = int(os.environ.get('QUEUE_MAX_SIZE', '10'))
16 QUEUE_SIZE = int(os.environ.get('QUEUE_MAX_SIZE', '10'))
17 class ProcessingUnit(object):
17 class ProcessingUnit(object):
18 '''
18 '''
19 Base class to create Signal Chain Units
19 Base class to create Signal Chain Units
20 '''
20 '''
21
21
22 proc_type = 'processing'
22 proc_type = 'processing'
23
23
24 def __init__(self):
24 def __init__(self):
25
25
26 self.dataIn = None
26 self.dataIn = None
27 self.dataOut = None
27 self.dataOut = None
28 self.isConfig = False
28 self.isConfig = False
29 self.operations = []
29 self.operations = []
30
30
31 def setInput(self, unit):
31 def setInput(self, unit):
32
32
33 self.dataIn = unit.dataOut
33 self.dataIn = unit.dataOut
34
34
35
35
36 def getAllowedArgs(self):
36 def getAllowedArgs(self):
37 if hasattr(self, '__attrs__'):
37 if hasattr(self, '__attrs__'):
38 return self.__attrs__
38 return self.__attrs__
39 else:
39 else:
40 return inspect.getargspec(self.run).args
40 return inspect.getargspec(self.run).args
41
41
42 def addOperation(self, conf, operation):
42 def addOperation(self, conf, operation):
43 '''
43 '''
44 '''
44 '''
45
45
46 self.operations.append((operation, conf.type, conf.getKwargs()))
46 self.operations.append((operation, conf.type, conf.getKwargs()))
47
47
48 def getOperationObj(self, objId):
48 def getOperationObj(self, objId):
49
49
50 if objId not in list(self.operations.keys()):
50 if objId not in list(self.operations.keys()):
51 return None
51 return None
52
52
53 return self.operations[objId]
53 return self.operations[objId]
54
54
55 def call(self, **kwargs):
55 def call(self, **kwargs):
56
56
57 mybool = (self.dataOut.type == 'Voltage') and self.dataOut.useInputBuffer and (not self.dataOut.buffer_empty) #liberar desde buffer
57 mybool = (self.dataOut.type == 'Voltage') and self.dataOut.useInputBuffer and (not self.dataOut.buffer_empty) #liberar desde buffer
58 try:
58 try:
59
59
60
60
61 if mybool:
61 if mybool:
62 #print("run jeje")
62 #print("run yeah")
63 self.run(**kwargs)
63 self.run(**kwargs)
64 else:
64 else:
65 if self.dataIn is not None and self.dataIn.flagNoData and not self.dataIn.error:
65 if self.dataIn is not None and self.dataIn.flagNoData and not self.dataIn.error:
66 return self.dataIn.isReady()
66 return self.dataIn.isReady()
67 elif self.dataIn is None or not self.dataIn.error: #unidad de lectura o procesamiento regular
67 elif self.dataIn is None or not self.dataIn.error: #unidad de lectura o procesamiento regular
68 self.run(**kwargs)
68 self.run(**kwargs)
69 elif self.dataIn.error:
69 elif self.dataIn.error:
70 self.dataOut.error = self.dataIn.error
70 self.dataOut.error = self.dataIn.error
71 self.dataOut.flagNoData = True
71 self.dataOut.flagNoData = True
72 print("exec proc error")
72 print("exec proc error")
73
73
74 except:
74 except:
75
75
76 err = traceback.format_exc()
76 err = traceback.format_exc()
77 if 'SchainWarning' in err:
77 if 'SchainWarning' in err:
78 log.warning(err.split('SchainWarning:')[-1].split('\n')[0].strip(), self.name)
78 log.warning(err.split('SchainWarning:')[-1].split('\n')[0].strip(), self.name)
79 elif 'SchainError' in err:
79 elif 'SchainError' in err:
80 log.error(err.split('SchainError:')[-1].split('\n')[0].strip(), self.name)
80 log.error(err.split('SchainError:')[-1].split('\n')[0].strip(), self.name)
81 else:
81 else:
82 log.error(err, self.name)
82 log.error(err, self.name)
83 self.dataOut.error = True
83 self.dataOut.error = True
84
84
85
85
86 for op, optype, opkwargs in self.operations:
86 for op, optype, opkwargs in self.operations:
87
87
88 if (optype == 'other' and self.dataOut.isReady()) or mybool:
88 if (optype == 'other' and self.dataOut.isReady()) or mybool:
89 try:
89 try:
90 self.dataOut = op.run(self.dataOut, **opkwargs)
90 self.dataOut = op.run(self.dataOut, **opkwargs)
91 except Exception as e:
91 except Exception as e:
92 print(e)
92 print(e)
93 self.dataOut.error = True
93 self.dataOut.error = True
94 return 'Error'
94 return 'Error'
95 elif optype == 'external' and self.dataOut.isReady() :
95 elif optype == 'external' and self.dataOut.isReady() :
96 op.queue.put(copy.deepcopy(self.dataOut))
96 op.queue.put(copy.deepcopy(self.dataOut))
97 elif optype == 'external' and self.dataOut.error:
97 elif optype == 'external' and self.dataOut.error:
98 op.queue.put(copy.deepcopy(self.dataOut))
98 op.queue.put(copy.deepcopy(self.dataOut))
99
99
100
100
101 if not self.dataOut.error:
101 if not self.dataOut.error:
102 if self.dataOut.type == 'Voltage':
102 if self.dataOut.type == 'Voltage':
103 if not self.dataOut.buffer_empty : #continue
103 if not self.dataOut.buffer_empty : #continue
104 return 'no_Read'
104 return 'no_Read'
105 elif self.dataOut.useInputBuffer and (self.dataOut.buffer_empty) and self.dataOut.isReady() :
105 elif self.dataOut.useInputBuffer and (self.dataOut.buffer_empty) and self.dataOut.isReady() :
106 return 'new_Read'
106 return 'new_Read'
107 else:
107 else:
108 return True
108 return True
109 else:
109 else:
110 #print("ret True")
110 #print("ret True")
111 return True
111 return True
112 else:
112 else:
113 return 'Error'
113 return 'Error'
114 #return 'Error' if self.dataOut.error else True #self.dataOut.isReady()
114 #return 'Error' if self.dataOut.error else True #self.dataOut.isReady()
115
115
116 def setup(self):
116 def setup(self):
117
117
118 raise NotImplementedError
118 raise NotImplementedError
119
119
120 def run(self):
120 def run(self):
121
121
122 raise NotImplementedError
122 raise NotImplementedError
123
123
124 def close(self):
124 def close(self):
125
125
126 return
126 return
127
127
128
128
129 class Operation(object):
129 class Operation(object):
130
130
131 '''
131 '''
132 '''
132 '''
133
133
134 proc_type = 'operation'
134 proc_type = 'operation'
135
135
136 def __init__(self):
136 def __init__(self):
137
137
138 self.id = None
138 self.id = None
139 self.isConfig = False
139 self.isConfig = False
140
140
141 if not hasattr(self, 'name'):
141 if not hasattr(self, 'name'):
142 self.name = self.__class__.__name__
142 self.name = self.__class__.__name__
143
143
144 def getAllowedArgs(self):
144 def getAllowedArgs(self):
145 if hasattr(self, '__attrs__'):
145 if hasattr(self, '__attrs__'):
146 return self.__attrs__
146 return self.__attrs__
147 else:
147 else:
148 return inspect.getargspec(self.run).args
148 return inspect.getargspec(self.run).args
149
149
150 def setup(self):
150 def setup(self):
151
151
152 self.isConfig = True
152 self.isConfig = True
153
153
154 raise NotImplementedError
154 raise NotImplementedError
155
155
156 def run(self, dataIn, **kwargs):
156 def run(self, dataIn, **kwargs):
157 """
157 """
158 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
158 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
159 atributos del objeto dataIn.
159 atributos del objeto dataIn.
160
160
161 Input:
161 Input:
162
162
163 dataIn : objeto del tipo JROData
163 dataIn : objeto del tipo JROData
164
164
165 Return:
165 Return:
166
166
167 None
167 None
168
168
169 Affected:
169 Affected:
170 __buffer : buffer de recepcion de datos.
170 __buffer : buffer de recepcion de datos.
171
171
172 """
172 """
173 if not self.isConfig:
173 if not self.isConfig:
174 self.setup(**kwargs)
174 self.setup(**kwargs)
175
175
176 raise NotImplementedError
176 raise NotImplementedError
177
177
178 def close(self):
178 def close(self):
179
179
180 return
180 return
181
181
182
182
183 def MPDecorator(BaseClass):
183 def MPDecorator(BaseClass):
184 """
184 """
185 Multiprocessing class decorator
185 Multiprocessing class decorator
186
186
187 This function add multiprocessing features to a BaseClass.
187 This function add multiprocessing features to a BaseClass.
188 """
188 """
189
189
190 class MPClass(BaseClass, Process):
190 class MPClass(BaseClass, Process):
191
191
192 def __init__(self, *args, **kwargs):
192 def __init__(self, *args, **kwargs):
193 super(MPClass, self).__init__()
193 super(MPClass, self).__init__()
194 Process.__init__(self)
194 Process.__init__(self)
195
195
196 self.args = args
196 self.args = args
197 self.kwargs = kwargs
197 self.kwargs = kwargs
198 self.t = time.time()
198 self.t = time.time()
199 self.op_type = 'external'
199 self.op_type = 'external'
200 self.name = BaseClass.__name__
200 self.name = BaseClass.__name__
201 self.__doc__ = BaseClass.__doc__
201 self.__doc__ = BaseClass.__doc__
202
202
203 if 'plot' in self.name.lower() and not self.name.endswith('_'):
203 if 'plot' in self.name.lower() and not self.name.endswith('_'):
204 self.name = '{}{}'.format(self.CODE.upper(), 'Plot')
204 self.name = '{}{}'.format(self.CODE.upper(), 'Plot')
205
205
206 self.start_time = time.time()
206 self.start_time = time.time()
207 self.err_queue = args[3]
207 self.err_queue = args[3]
208 self.queue = Queue(maxsize=QUEUE_SIZE)
208 self.queue = Queue(maxsize=QUEUE_SIZE)
209 self.myrun = BaseClass.run
209 self.myrun = BaseClass.run
210
210
211 def run(self):
211 def run(self):
212
212
213 while True:
213 while 1:
214
214
215 dataOut = self.queue.get()
215 dataOut = self.queue.get()
216
216
217 if not dataOut.error:
217 if not dataOut.error:
218 try:
218 try:
219 BaseClass.run(self, dataOut, **self.kwargs)
219 BaseClass.run(self, dataOut, **self.kwargs)
220 except:
220 except:
221 err = traceback.format_exc()
221 err = traceback.format_exc()
222 log.error(err, self.name)
222 log.error(err, self.name)
223 else:
223 else:
224 break
224 break
225
225
226 self.close()
226 self.close()
227
227
228 def close(self):
228 def close(self):
229
229
230 BaseClass.close(self)
230 BaseClass.close(self)
231 log.success('Done...(Time:{:4.2f} secs)'.format(time.time()-self.start_time), self.name)
231 log.success('Done...(Time:{:4.2f} secs)'.format(time.time()-self.start_time), self.name)
232
232
233 return MPClass
233 return MPClass
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,1948 +1,2076
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
13
14 import numpy
14 import numpy
15 import math
15 import math
16
16
17 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
17 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator, Operation
18 from schainpy.model.data.jrodata import Spectra
18 from schainpy.model.data.jrodata import Spectra
19 from schainpy.model.data.jrodata import hildebrand_sekhon
19 from schainpy.model.data.jrodata import hildebrand_sekhon
20 from schainpy.model.data import _noise
20 from schainpy.model.data import _noise
21
21
22 from schainpy.utils import log
22 from schainpy.utils import log
23 import matplotlib.pyplot as plt
23 import matplotlib.pyplot as plt
24 from scipy.optimize import curve_fit
24 #from scipy.optimize import curve_fit
25
25
26 class SpectraProc(ProcessingUnit):
26 class SpectraProc(ProcessingUnit):
27
27
28 def __init__(self):
28 def __init__(self):
29
29
30 ProcessingUnit.__init__(self)
30 ProcessingUnit.__init__(self)
31
31
32 self.buffer = None
32 self.buffer = None
33 self.firstdatatime = None
33 self.firstdatatime = None
34 self.profIndex = 0
34 self.profIndex = 0
35 self.dataOut = Spectra()
35 self.dataOut = Spectra()
36 self.id_min = None
36 self.id_min = None
37 self.id_max = None
37 self.id_max = None
38 self.setupReq = False #Agregar a todas las unidades de proc
38 self.setupReq = False #Agregar a todas las unidades de proc
39
39
40 def __updateSpecFromVoltage(self):
40 def __updateSpecFromVoltage(self):
41
41
42
42
43
43
44 self.dataOut.timeZone = self.dataIn.timeZone
44 self.dataOut.timeZone = self.dataIn.timeZone
45 self.dataOut.dstFlag = self.dataIn.dstFlag
45 self.dataOut.dstFlag = self.dataIn.dstFlag
46 self.dataOut.errorCount = self.dataIn.errorCount
46 self.dataOut.errorCount = self.dataIn.errorCount
47 self.dataOut.useLocalTime = self.dataIn.useLocalTime
47 self.dataOut.useLocalTime = self.dataIn.useLocalTime
48 try:
48 try:
49 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
49 self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy()
50 except:
50 except:
51 pass
51 pass
52 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
52 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
53 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
53 self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()
54 self.dataOut.channelList = self.dataIn.channelList
54 self.dataOut.channelList = self.dataIn.channelList
55 self.dataOut.heightList = self.dataIn.heightList
55 self.dataOut.heightList = self.dataIn.heightList
56 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
56 self.dataOut.dtype = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
57 self.dataOut.nProfiles = self.dataOut.nFFTPoints
57 self.dataOut.nProfiles = self.dataOut.nFFTPoints
58 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
58 self.dataOut.flagDiscontinuousBlock = self.dataIn.flagDiscontinuousBlock
59 self.dataOut.utctime = self.firstdatatime
59 self.dataOut.utctime = self.firstdatatime
60 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
60 self.dataOut.flagDecodeData = self.dataIn.flagDecodeData
61 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
61 self.dataOut.flagDeflipData = self.dataIn.flagDeflipData
62 self.dataOut.flagShiftFFT = False
62 self.dataOut.flagShiftFFT = False
63 self.dataOut.nCohInt = self.dataIn.nCohInt
63 self.dataOut.nCohInt = self.dataIn.nCohInt
64 self.dataOut.nIncohInt = 1
64 self.dataOut.nIncohInt = 1
65 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
65 self.dataOut.windowOfFilter = self.dataIn.windowOfFilter
66 self.dataOut.frequency = self.dataIn.frequency
66 self.dataOut.frequency = self.dataIn.frequency
67 self.dataOut.realtime = self.dataIn.realtime
67 self.dataOut.realtime = self.dataIn.realtime
68 self.dataOut.azimuth = self.dataIn.azimuth
68 self.dataOut.azimuth = self.dataIn.azimuth
69 self.dataOut.zenith = self.dataIn.zenith
69 self.dataOut.zenith = self.dataIn.zenith
70 self.dataOut.codeList = self.dataIn.codeList
70 self.dataOut.codeList = self.dataIn.codeList
71 self.dataOut.azimuthList = self.dataIn.azimuthList
71 self.dataOut.azimuthList = self.dataIn.azimuthList
72 self.dataOut.elevationList = self.dataIn.elevationList
72 self.dataOut.elevationList = self.dataIn.elevationList
73
73
74
74
75 def __getFft(self):
75 def __getFft(self):
76 """
76 """
77 Convierte valores de Voltaje a Spectra
77 Convierte valores de Voltaje a Spectra
78
78
79 Affected:
79 Affected:
80 self.dataOut.data_spc
80 self.dataOut.data_spc
81 self.dataOut.data_cspc
81 self.dataOut.data_cspc
82 self.dataOut.data_dc
82 self.dataOut.data_dc
83 self.dataOut.heightList
83 self.dataOut.heightList
84 self.profIndex
84 self.profIndex
85 self.buffer
85 self.buffer
86 self.dataOut.flagNoData
86 self.dataOut.flagNoData
87 """
87 """
88 fft_volt = numpy.fft.fft(
88 fft_volt = numpy.fft.fft(
89 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
89 self.buffer, n=self.dataOut.nFFTPoints, axis=1)
90 fft_volt = fft_volt.astype(numpy.dtype('complex'))
90 fft_volt = fft_volt.astype(numpy.dtype('complex'))
91 dc = fft_volt[:, 0, :]
91 dc = fft_volt[:, 0, :]
92
92
93 # calculo de self-spectra
93 # calculo de self-spectra
94 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
94 fft_volt = numpy.fft.fftshift(fft_volt, axes=(1,))
95 spc = fft_volt * numpy.conjugate(fft_volt)
95 spc = fft_volt * numpy.conjugate(fft_volt)
96 spc = spc.real
96 spc = spc.real
97
97
98 blocksize = 0
98 blocksize = 0
99 blocksize += dc.size
99 blocksize += dc.size
100 blocksize += spc.size
100 blocksize += spc.size
101
101
102 cspc = None
102 cspc = None
103 pairIndex = 0
103 pairIndex = 0
104 if self.dataOut.pairsList != None:
104 if self.dataOut.pairsList != None:
105 # calculo de cross-spectra
105 # calculo de cross-spectra
106 cspc = numpy.zeros(
106 cspc = numpy.zeros(
107 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
107 (self.dataOut.nPairs, self.dataOut.nFFTPoints, self.dataOut.nHeights), dtype='complex')
108 for pair in self.dataOut.pairsList:
108 for pair in self.dataOut.pairsList:
109 if pair[0] not in self.dataOut.channelList:
109 if pair[0] not in self.dataOut.channelList:
110 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
110 raise ValueError("Error getting CrossSpectra: pair 0 of %s is not in channelList = %s" % (
111 str(pair), str(self.dataOut.channelList)))
111 str(pair), str(self.dataOut.channelList)))
112 if pair[1] not in self.dataOut.channelList:
112 if pair[1] not in self.dataOut.channelList:
113 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
113 raise ValueError("Error getting CrossSpectra: pair 1 of %s is not in channelList = %s" % (
114 str(pair), str(self.dataOut.channelList)))
114 str(pair), str(self.dataOut.channelList)))
115
115
116 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
116 cspc[pairIndex, :, :] = fft_volt[pair[0], :, :] * \
117 numpy.conjugate(fft_volt[pair[1], :, :])
117 numpy.conjugate(fft_volt[pair[1], :, :])
118 pairIndex += 1
118 pairIndex += 1
119 blocksize += cspc.size
119 blocksize += cspc.size
120
120
121 self.dataOut.data_spc = spc
121 self.dataOut.data_spc = spc
122 self.dataOut.data_cspc = cspc
122 self.dataOut.data_cspc = cspc
123 self.dataOut.data_dc = dc
123 self.dataOut.data_dc = dc
124 self.dataOut.blockSize = blocksize
124 self.dataOut.blockSize = blocksize
125 self.dataOut.flagShiftFFT = False
125 self.dataOut.flagShiftFFT = False
126
126
127 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False):
127 def run(self, nProfiles=None, nFFTPoints=None, pairsList=None, ippFactor=None, shift_fft=False):
128 #print("run spc proc")
128 #print("run spc proc")
129 try:
130 type = self.dataIn.type.decode("utf-8")
131 self.dataIn.type = type
132 except:
133 pass
129 if self.dataIn.type == "Spectra":
134 if self.dataIn.type == "Spectra":
130
135
131 try:
136 try:
132 self.dataOut.copy(self.dataIn)
137 self.dataOut.copy(self.dataIn)
133
138
134 except Exception as e:
139 except Exception as e:
135 print("Error dataIn ",e)
140 print("Error dataIn ",e)
136
141
137 if shift_fft:
142 if shift_fft:
138 #desplaza a la derecha en el eje 2 determinadas posiciones
143 #desplaza a la derecha en el eje 2 determinadas posiciones
139 shift = int(self.dataOut.nFFTPoints/2)
144 shift = int(self.dataOut.nFFTPoints/2)
140 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
145 self.dataOut.data_spc = numpy.roll(self.dataOut.data_spc, shift , axis=1)
141
146
142 if self.dataOut.data_cspc is not None:
147 if self.dataOut.data_cspc is not None:
143 #desplaza a la derecha en el eje 2 determinadas posiciones
148 #desplaza a la derecha en el eje 2 determinadas posiciones
144 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
149 self.dataOut.data_cspc = numpy.roll(self.dataOut.data_cspc, shift, axis=1)
145 if pairsList:
150 if pairsList:
146 self.__selectPairs(pairsList)
151 self.__selectPairs(pairsList)
147
152
148
153
149 elif self.dataIn.type == "Voltage":
154 elif self.dataIn.type == "Voltage":
150
155
151 self.dataOut.flagNoData = True
156 self.dataOut.flagNoData = True
152
157
153 if nFFTPoints == None:
158 if nFFTPoints == None:
154 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
159 raise ValueError("This SpectraProc.run() need nFFTPoints input variable")
155
160
156 if nProfiles == None:
161 if nProfiles == None:
157 nProfiles = nFFTPoints
162 nProfiles = nFFTPoints
158
163
159 if ippFactor == None:
164 if ippFactor == None:
160 self.dataOut.ippFactor = 1
165 self.dataOut.ippFactor = 1
161
166
162 self.dataOut.nFFTPoints = nFFTPoints
167 self.dataOut.nFFTPoints = nFFTPoints
163 #print(" volts ch,prof, h: ", self.dataIn.data.shape)
168 #print(" volts ch,prof, h: ", self.dataIn.data.shape)
164 if self.buffer is None:
169 if self.buffer is None:
165 self.buffer = numpy.zeros((self.dataIn.nChannels,
170 self.buffer = numpy.zeros((self.dataIn.nChannels,
166 nProfiles,
171 nProfiles,
167 self.dataIn.nHeights),
172 self.dataIn.nHeights),
168 dtype='complex')
173 dtype='complex')
169
174
170 if self.dataIn.flagDataAsBlock:
175 if self.dataIn.flagDataAsBlock:
171 nVoltProfiles = self.dataIn.data.shape[1]
176 nVoltProfiles = self.dataIn.data.shape[1]
172
177
173 if nVoltProfiles == nProfiles:
178 if nVoltProfiles == nProfiles:
174 self.buffer = self.dataIn.data.copy()
179 self.buffer = self.dataIn.data.copy()
175 self.profIndex = nVoltProfiles
180 self.profIndex = nVoltProfiles
176
181
177 elif nVoltProfiles < nProfiles:
182 elif nVoltProfiles < nProfiles:
178
183
179 if self.profIndex == 0:
184 if self.profIndex == 0:
180 self.id_min = 0
185 self.id_min = 0
181 self.id_max = nVoltProfiles
186 self.id_max = nVoltProfiles
182
187
183 self.buffer[:, self.id_min:self.id_max,
188 self.buffer[:, self.id_min:self.id_max,
184 :] = self.dataIn.data
189 :] = self.dataIn.data
185 self.profIndex += nVoltProfiles
190 self.profIndex += nVoltProfiles
186 self.id_min += nVoltProfiles
191 self.id_min += nVoltProfiles
187 self.id_max += nVoltProfiles
192 self.id_max += nVoltProfiles
188 else:
193 else:
189 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
194 raise ValueError("The type object %s has %d profiles, it should just has %d profiles" % (
190 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
195 self.dataIn.type, self.dataIn.data.shape[1], nProfiles))
191 self.dataOut.flagNoData = True
196 self.dataOut.flagNoData = True
192 else:
197 else:
193 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
198 self.buffer[:, self.profIndex, :] = self.dataIn.data.copy()
194 self.profIndex += 1
199 self.profIndex += 1
195
200
196 if self.firstdatatime == None:
201 if self.firstdatatime == None:
197 self.firstdatatime = self.dataIn.utctime
202 self.firstdatatime = self.dataIn.utctime
198
203
199 if self.profIndex == nProfiles:
204 if self.profIndex == nProfiles:
200
205
201 self.__updateSpecFromVoltage()
206 self.__updateSpecFromVoltage()
202
207
203 if pairsList == None:
208 if pairsList == None:
204 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
209 self.dataOut.pairsList = [pair for pair in itertools.combinations(self.dataOut.channelList, 2)]
205 else:
210 else:
206 self.dataOut.pairsList = pairsList
211 self.dataOut.pairsList = pairsList
207 self.__getFft()
212 self.__getFft()
208 self.dataOut.flagNoData = False
213 self.dataOut.flagNoData = False
209 self.firstdatatime = None
214 self.firstdatatime = None
210 self.profIndex = 0
215 self.profIndex = 0
211
216
217 elif self.dataIn.type == "Parameters":
218
219 self.dataOut.data_spc = self.dataIn.data_spc
220 self.dataOut.data_cspc = self.dataIn.data_cspc
221 self.dataOut.data_outlier = self.dataIn.data_outlier
222 self.dataOut.nProfiles = self.dataIn.nProfiles
223 self.dataOut.nIncohInt = self.dataIn.nIncohInt
224 self.dataOut.nFFTPoints = self.dataIn.nFFTPoints
225 self.dataOut.ippFactor = self.dataIn.ippFactor
226 self.dataOut.max_nIncohInt = self.dataIn.max_nIncohInt
227 self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()
228 self.dataOut.ipp = self.dataIn.ipp
229 #self.dataOut.abscissaList = self.dataIn.getVelRange(1)
230 #self.dataOut.spc_noise = self.dataIn.getNoise()
231 #self.dataOut.spc_range = (self.dataIn.getFreqRange(1) , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1))
232 # self.dataOut.normFactor = self.dataIn.normFactor
233 if hasattr(self.dataIn, 'channelList'):
234 self.dataOut.channelList = self.dataIn.channelList
235 if hasattr(self.dataIn, 'pairsList'):
236 self.dataOut.pairsList = self.dataIn.pairsList
237 self.dataOut.groupList = self.dataIn.pairsList
238
239 self.dataOut.flagNoData = False
240
241 if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels
242 self.dataOut.ChanDist = self.dataIn.ChanDist
243 else: self.dataOut.ChanDist = None
244
245 #if hasattr(self.dataIn, 'VelRange'): #Velocities range
246 # self.dataOut.VelRange = self.dataIn.VelRange
247 #else: self.dataOut.VelRange = None
248
249
212
250
213 else:
251 else:
214 raise ValueError("The type of input object '%s' is not valid".format(
252 raise ValueError("The type of input object {} is not valid".format(
215 self.dataIn.type))
253 self.dataIn.type))
216
254
217
255
218 def __selectPairs(self, pairsList):
256 def __selectPairs(self, pairsList):
219
257
220 if not pairsList:
258 if not pairsList:
221 return
259 return
222
260
223 pairs = []
261 pairs = []
224 pairsIndex = []
262 pairsIndex = []
225
263
226 for pair in pairsList:
264 for pair in pairsList:
227 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
265 if pair[0] not in self.dataOut.channelList or pair[1] not in self.dataOut.channelList:
228 continue
266 continue
229 pairs.append(pair)
267 pairs.append(pair)
230 pairsIndex.append(pairs.index(pair))
268 pairsIndex.append(pairs.index(pair))
231
269
232 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
270 self.dataOut.data_cspc = self.dataOut.data_cspc[pairsIndex]
233 self.dataOut.pairsList = pairs
271 self.dataOut.pairsList = pairs
234
272
235 return
273 return
236
274
237 def selectFFTs(self, minFFT, maxFFT ):
275 def selectFFTs(self, minFFT, maxFFT ):
238 """
276 """
239 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
277 Selecciona un bloque de datos en base a un grupo de valores de puntos FFTs segun el rango
240 minFFT<= FFT <= maxFFT
278 minFFT<= FFT <= maxFFT
241 """
279 """
242
280
243 if (minFFT > maxFFT):
281 if (minFFT > maxFFT):
244 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
282 raise ValueError("Error selecting heights: Height range (%d,%d) is not valid" % (minFFT, maxFFT))
245
283
246 if (minFFT < self.dataOut.getFreqRange()[0]):
284 if (minFFT < self.dataOut.getFreqRange()[0]):
247 minFFT = self.dataOut.getFreqRange()[0]
285 minFFT = self.dataOut.getFreqRange()[0]
248
286
249 if (maxFFT > self.dataOut.getFreqRange()[-1]):
287 if (maxFFT > self.dataOut.getFreqRange()[-1]):
250 maxFFT = self.dataOut.getFreqRange()[-1]
288 maxFFT = self.dataOut.getFreqRange()[-1]
251
289
252 minIndex = 0
290 minIndex = 0
253 maxIndex = 0
291 maxIndex = 0
254 FFTs = self.dataOut.getFreqRange()
292 FFTs = self.dataOut.getFreqRange()
255
293
256 inda = numpy.where(FFTs >= minFFT)
294 inda = numpy.where(FFTs >= minFFT)
257 indb = numpy.where(FFTs <= maxFFT)
295 indb = numpy.where(FFTs <= maxFFT)
258
296
259 try:
297 try:
260 minIndex = inda[0][0]
298 minIndex = inda[0][0]
261 except:
299 except:
262 minIndex = 0
300 minIndex = 0
263
301
264 try:
302 try:
265 maxIndex = indb[0][-1]
303 maxIndex = indb[0][-1]
266 except:
304 except:
267 maxIndex = len(FFTs)
305 maxIndex = len(FFTs)
268
306
269 self.selectFFTsByIndex(minIndex, maxIndex)
307 self.selectFFTsByIndex(minIndex, maxIndex)
270
308
271 return 1
309 return 1
272
310
273 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
311 def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None):
274 newheis = numpy.where(
312 newheis = numpy.where(
275 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
313 self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex])
276
314
277 if hei_ref != None:
315 if hei_ref != None:
278 newheis = numpy.where(self.dataOut.heightList > hei_ref)
316 newheis = numpy.where(self.dataOut.heightList > hei_ref)
279
317
280 minIndex = min(newheis[0])
318 minIndex = min(newheis[0])
281 maxIndex = max(newheis[0])
319 maxIndex = max(newheis[0])
282 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
320 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
283 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
321 heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
284
322
285 # determina indices
323 # determina indices
286 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
324 nheis = int(self.dataOut.radarControllerHeaderObj.txB /
287 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
325 (self.dataOut.heightList[1] - self.dataOut.heightList[0]))
288 avg_dB = 10 * \
326 avg_dB = 10 * \
289 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
327 numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0))
290 beacon_dB = numpy.sort(avg_dB)[-nheis:]
328 beacon_dB = numpy.sort(avg_dB)[-nheis:]
291 beacon_heiIndexList = []
329 beacon_heiIndexList = []
292 for val in avg_dB.tolist():
330 for val in avg_dB.tolist():
293 if val >= beacon_dB[0]:
331 if val >= beacon_dB[0]:
294 beacon_heiIndexList.append(avg_dB.tolist().index(val))
332 beacon_heiIndexList.append(avg_dB.tolist().index(val))
295
333
296 #data_spc = data_spc[:,:,beacon_heiIndexList]
334 #data_spc = data_spc[:,:,beacon_heiIndexList]
297 data_cspc = None
335 data_cspc = None
298 if self.dataOut.data_cspc is not None:
336 if self.dataOut.data_cspc is not None:
299 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
337 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
300 #data_cspc = data_cspc[:,:,beacon_heiIndexList]
338 #data_cspc = data_cspc[:,:,beacon_heiIndexList]
301
339
302 data_dc = None
340 data_dc = None
303 if self.dataOut.data_dc is not None:
341 if self.dataOut.data_dc is not None:
304 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
342 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
305 #data_dc = data_dc[:,beacon_heiIndexList]
343 #data_dc = data_dc[:,beacon_heiIndexList]
306
344
307 self.dataOut.data_spc = data_spc
345 self.dataOut.data_spc = data_spc
308 self.dataOut.data_cspc = data_cspc
346 self.dataOut.data_cspc = data_cspc
309 self.dataOut.data_dc = data_dc
347 self.dataOut.data_dc = data_dc
310 self.dataOut.heightList = heightList
348 self.dataOut.heightList = heightList
311 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
349 self.dataOut.beacon_heiIndexList = beacon_heiIndexList
312
350
313 return 1
351 return 1
314
352
315 def selectFFTsByIndex(self, minIndex, maxIndex):
353 def selectFFTsByIndex(self, minIndex, maxIndex):
316 """
354 """
317
355
318 """
356 """
319
357
320 if (minIndex < 0) or (minIndex > maxIndex):
358 if (minIndex < 0) or (minIndex > maxIndex):
321 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
359 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex))
322
360
323 if (maxIndex >= self.dataOut.nProfiles):
361 if (maxIndex >= self.dataOut.nProfiles):
324 maxIndex = self.dataOut.nProfiles-1
362 maxIndex = self.dataOut.nProfiles-1
325
363
326 #Spectra
364 #Spectra
327 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
365 data_spc = self.dataOut.data_spc[:,minIndex:maxIndex+1,:]
328
366
329 data_cspc = None
367 data_cspc = None
330 if self.dataOut.data_cspc is not None:
368 if self.dataOut.data_cspc is not None:
331 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
369 data_cspc = self.dataOut.data_cspc[:,minIndex:maxIndex+1,:]
332
370
333 data_dc = None
371 data_dc = None
334 if self.dataOut.data_dc is not None:
372 if self.dataOut.data_dc is not None:
335 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
373 data_dc = self.dataOut.data_dc[minIndex:maxIndex+1,:]
336
374
337 self.dataOut.data_spc = data_spc
375 self.dataOut.data_spc = data_spc
338 self.dataOut.data_cspc = data_cspc
376 self.dataOut.data_cspc = data_cspc
339 self.dataOut.data_dc = data_dc
377 self.dataOut.data_dc = data_dc
340
378
341 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
379 self.dataOut.ippSeconds = self.dataOut.ippSeconds*(self.dataOut.nFFTPoints / numpy.shape(data_cspc)[1])
342 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
380 self.dataOut.nFFTPoints = numpy.shape(data_cspc)[1]
343 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
381 self.dataOut.profilesPerBlock = numpy.shape(data_cspc)[1]
344
382
345 return 1
383 return 1
346
384
347 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
385 def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None):
348 # validacion de rango
386 # validacion de rango
349 if minHei == None:
387 if minHei == None:
350 minHei = self.dataOut.heightList[0]
388 minHei = self.dataOut.heightList[0]
351
389
352 if maxHei == None:
390 if maxHei == None:
353 maxHei = self.dataOut.heightList[-1]
391 maxHei = self.dataOut.heightList[-1]
354
392
355 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
393 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
356 print('minHei: %.2f is out of the heights range' % (minHei))
394 print('minHei: %.2f is out of the heights range' % (minHei))
357 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
395 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
358 minHei = self.dataOut.heightList[0]
396 minHei = self.dataOut.heightList[0]
359
397
360 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
398 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
361 print('maxHei: %.2f is out of the heights range' % (maxHei))
399 print('maxHei: %.2f is out of the heights range' % (maxHei))
362 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
400 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
363 maxHei = self.dataOut.heightList[-1]
401 maxHei = self.dataOut.heightList[-1]
364
402
365 # validacion de velocidades
403 # validacion de velocidades
366 velrange = self.dataOut.getVelRange(1)
404 velrange = self.dataOut.getVelRange(1)
367
405
368 if minVel == None:
406 if minVel == None:
369 minVel = velrange[0]
407 minVel = velrange[0]
370
408
371 if maxVel == None:
409 if maxVel == None:
372 maxVel = velrange[-1]
410 maxVel = velrange[-1]
373
411
374 if (minVel < velrange[0]) or (minVel > maxVel):
412 if (minVel < velrange[0]) or (minVel > maxVel):
375 print('minVel: %.2f is out of the velocity range' % (minVel))
413 print('minVel: %.2f is out of the velocity range' % (minVel))
376 print('minVel is setting to %.2f' % (velrange[0]))
414 print('minVel is setting to %.2f' % (velrange[0]))
377 minVel = velrange[0]
415 minVel = velrange[0]
378
416
379 if (maxVel > velrange[-1]) or (maxVel < minVel):
417 if (maxVel > velrange[-1]) or (maxVel < minVel):
380 print('maxVel: %.2f is out of the velocity range' % (maxVel))
418 print('maxVel: %.2f is out of the velocity range' % (maxVel))
381 print('maxVel is setting to %.2f' % (velrange[-1]))
419 print('maxVel is setting to %.2f' % (velrange[-1]))
382 maxVel = velrange[-1]
420 maxVel = velrange[-1]
383
421
384 # seleccion de indices para rango
422 # seleccion de indices para rango
385 minIndex = 0
423 minIndex = 0
386 maxIndex = 0
424 maxIndex = 0
387 heights = self.dataOut.heightList
425 heights = self.dataOut.heightList
388
426
389 inda = numpy.where(heights >= minHei)
427 inda = numpy.where(heights >= minHei)
390 indb = numpy.where(heights <= maxHei)
428 indb = numpy.where(heights <= maxHei)
391
429
392 try:
430 try:
393 minIndex = inda[0][0]
431 minIndex = inda[0][0]
394 except:
432 except:
395 minIndex = 0
433 minIndex = 0
396
434
397 try:
435 try:
398 maxIndex = indb[0][-1]
436 maxIndex = indb[0][-1]
399 except:
437 except:
400 maxIndex = len(heights)
438 maxIndex = len(heights)
401
439
402 if (minIndex < 0) or (minIndex > maxIndex):
440 if (minIndex < 0) or (minIndex > maxIndex):
403 raise ValueError("some value in (%d,%d) is not valid" % (
441 raise ValueError("some value in (%d,%d) is not valid" % (
404 minIndex, maxIndex))
442 minIndex, maxIndex))
405
443
406 if (maxIndex >= self.dataOut.nHeights):
444 if (maxIndex >= self.dataOut.nHeights):
407 maxIndex = self.dataOut.nHeights - 1
445 maxIndex = self.dataOut.nHeights - 1
408
446
409 # seleccion de indices para velocidades
447 # seleccion de indices para velocidades
410 indminvel = numpy.where(velrange >= minVel)
448 indminvel = numpy.where(velrange >= minVel)
411 indmaxvel = numpy.where(velrange <= maxVel)
449 indmaxvel = numpy.where(velrange <= maxVel)
412 try:
450 try:
413 minIndexVel = indminvel[0][0]
451 minIndexVel = indminvel[0][0]
414 except:
452 except:
415 minIndexVel = 0
453 minIndexVel = 0
416
454
417 try:
455 try:
418 maxIndexVel = indmaxvel[0][-1]
456 maxIndexVel = indmaxvel[0][-1]
419 except:
457 except:
420 maxIndexVel = len(velrange)
458 maxIndexVel = len(velrange)
421
459
422 # seleccion del espectro
460 # seleccion del espectro
423 data_spc = self.dataOut.data_spc[:,
461 data_spc = self.dataOut.data_spc[:,
424 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
462 minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1]
425 # estimacion de ruido
463 # estimacion de ruido
426 noise = numpy.zeros(self.dataOut.nChannels)
464 noise = numpy.zeros(self.dataOut.nChannels)
427
465
428 for channel in range(self.dataOut.nChannels):
466 for channel in range(self.dataOut.nChannels):
429 daux = data_spc[channel, :, :]
467 daux = data_spc[channel, :, :]
430 sortdata = numpy.sort(daux, axis=None)
468 sortdata = numpy.sort(daux, axis=None)
431 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
469 noise[channel] = hildebrand_sekhon(sortdata, self.dataOut.nIncohInt)
432
470
433 self.dataOut.noise_estimation = noise.copy()
471 self.dataOut.noise_estimation = noise.copy()
434
472
435 return 1
473 return 1
436
474
437 class removeDC(Operation):
475 class removeDC(Operation):
438
476
439 def run(self, dataOut, mode=2):
477 def run(self, dataOut, mode=2):
440 self.dataOut = dataOut
478 self.dataOut = dataOut
441 jspectra = self.dataOut.data_spc
479 jspectra = self.dataOut.data_spc
442 jcspectra = self.dataOut.data_cspc
480 jcspectra = self.dataOut.data_cspc
443
481
444 num_chan = jspectra.shape[0]
482 num_chan = jspectra.shape[0]
445 num_hei = jspectra.shape[2]
483 num_hei = jspectra.shape[2]
446
484
447 if jcspectra is not None:
485 if jcspectra is not None:
448 jcspectraExist = True
486 jcspectraExist = True
449 num_pairs = jcspectra.shape[0]
487 num_pairs = jcspectra.shape[0]
450 else:
488 else:
451 jcspectraExist = False
489 jcspectraExist = False
452
490
453 freq_dc = int(jspectra.shape[1] / 2)
491 freq_dc = int(jspectra.shape[1] / 2)
454 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
492 ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc
455 ind_vel = ind_vel.astype(int)
493 ind_vel = ind_vel.astype(int)
456
494
457 if ind_vel[0] < 0:
495 if ind_vel[0] < 0:
458 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
496 ind_vel[list(range(0, 1))] = ind_vel[list(range(0, 1))] + self.num_prof
459
497
460 if mode == 1:
498 if mode == 1:
461 jspectra[:, freq_dc, :] = (
499 jspectra[:, freq_dc, :] = (
462 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
500 jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION
463
501
464 if jcspectraExist:
502 if jcspectraExist:
465 jcspectra[:, freq_dc, :] = (
503 jcspectra[:, freq_dc, :] = (
466 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
504 jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2
467
505
468 if mode == 2:
506 if mode == 2:
469
507
470 vel = numpy.array([-2, -1, 1, 2])
508 vel = numpy.array([-2, -1, 1, 2])
471 xx = numpy.zeros([4, 4])
509 xx = numpy.zeros([4, 4])
472
510
473 for fil in range(4):
511 for fil in range(4):
474 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
512 xx[fil, :] = vel[fil]**numpy.asarray(list(range(4)))
475
513
476 xx_inv = numpy.linalg.inv(xx)
514 xx_inv = numpy.linalg.inv(xx)
477 xx_aux = xx_inv[0, :]
515 xx_aux = xx_inv[0, :]
478
516
479 for ich in range(num_chan):
517 for ich in range(num_chan):
480 yy = jspectra[ich, ind_vel, :]
518 yy = jspectra[ich, ind_vel, :]
481 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
519 jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy)
482
520
483 junkid = jspectra[ich, freq_dc, :] <= 0
521 junkid = jspectra[ich, freq_dc, :] <= 0
484 cjunkid = sum(junkid)
522 cjunkid = sum(junkid)
485
523
486 if cjunkid.any():
524 if cjunkid.any():
487 jspectra[ich, freq_dc, junkid.nonzero()] = (
525 jspectra[ich, freq_dc, junkid.nonzero()] = (
488 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
526 jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2
489
527
490 if jcspectraExist:
528 if jcspectraExist:
491 for ip in range(num_pairs):
529 for ip in range(num_pairs):
492 yy = jcspectra[ip, ind_vel, :]
530 yy = jcspectra[ip, ind_vel, :]
493 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
531 jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy)
494
532
495 self.dataOut.data_spc = jspectra
533 self.dataOut.data_spc = jspectra
496 self.dataOut.data_cspc = jcspectra
534 self.dataOut.data_cspc = jcspectra
497
535
498 return self.dataOut
536 return self.dataOut
499
537
500 class getNoise(Operation):
538 class getNoiseB(Operation):
501 warnings = False
539
540 __slots__ =('offset','warnings', 'isConfig', 'minIndex','maxIndex','minIndexFFT','maxIndexFFT')
502 def __init__(self):
541 def __init__(self):
503
542
504 Operation.__init__(self)
543 Operation.__init__(self)
544 self.isConfig = False
545
546 def setup(self, offset=None, minHei=None, maxHei=None,minVel=None, maxVel=None, minFreq= None, maxFreq=None, warnings=False):
505
547
506 def run(self, dataOut, minHei=None, maxHei=None,minVel=None, maxVel=None, minFreq= None, maxFreq=None, warnings=False):
507 self.dataOut = dataOut
508 self.warnings = warnings
548 self.warnings = warnings
509 if minHei == None:
549 if minHei == None:
510 minHei = self.dataOut.heightList[0]
550 minHei = self.dataOut.heightList[0]
511
551
512 if maxHei == None:
552 if maxHei == None:
513 maxHei = self.dataOut.heightList[-1]
553 maxHei = self.dataOut.heightList[-1]
514
554
515 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
555 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
516 if self.warnings:
556 if self.warnings:
517 print('minHei: %.2f is out of the heights range' % (minHei))
557 print('minHei: %.2f is out of the heights range' % (minHei))
518 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
558 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
519 minHei = self.dataOut.heightList[0]
559 minHei = self.dataOut.heightList[0]
520
560
521 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
561 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
522 if self.warnings:
562 if self.warnings:
523 print('maxHei: %.2f is out of the heights range' % (maxHei))
563 print('maxHei: %.2f is out of the heights range' % (maxHei))
524 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
564 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
525 maxHei = self.dataOut.heightList[-1]
565 maxHei = self.dataOut.heightList[-1]
526
566
527
567
528 #indices relativos a los puntos de fft, puede ser de acuerdo a velocidad o frecuencia
568 #indices relativos a los puntos de fft, puede ser de acuerdo a velocidad o frecuencia
529 minIndexFFT = 0
569 minIndexFFT = 0
530 maxIndexFFT = 0
570 maxIndexFFT = 0
531 # validacion de velocidades
571 # validacion de velocidades
532 indminPoint = None
572 indminPoint = None
533 indmaxPoint = None
573 indmaxPoint = None
534 if self.dataOut.type == 'Spectra':
574 if self.dataOut.type == 'Spectra':
535 if minVel == None and maxVel == None :
575 if minVel == None and maxVel == None :
536
576
537 freqrange = self.dataOut.getFreqRange(1)
577 freqrange = self.dataOut.getFreqRange(1)
538
578
539 if minFreq == None:
579 if minFreq == None:
540 minFreq = freqrange[0]
580 minFreq = freqrange[0]
541
581
542 if maxFreq == None:
582 if maxFreq == None:
543 maxFreq = freqrange[-1]
583 maxFreq = freqrange[-1]
544
584
545 if (minFreq < freqrange[0]) or (minFreq > maxFreq):
585 if (minFreq < freqrange[0]) or (minFreq > maxFreq):
546 if self.warnings:
586 if self.warnings:
547 print('minFreq: %.2f is out of the frequency range' % (minFreq))
587 print('minFreq: %.2f is out of the frequency range' % (minFreq))
548 print('minFreq is setting to %.2f' % (freqrange[0]))
588 print('minFreq is setting to %.2f' % (freqrange[0]))
549 minFreq = freqrange[0]
589 minFreq = freqrange[0]
550
590
551 if (maxFreq > freqrange[-1]) or (maxFreq < minFreq):
591 if (maxFreq > freqrange[-1]) or (maxFreq < minFreq):
552 if self.warnings:
592 if self.warnings:
553 print('maxFreq: %.2f is out of the frequency range' % (maxFreq))
593 print('maxFreq: %.2f is out of the frequency range' % (maxFreq))
554 print('maxFreq is setting to %.2f' % (freqrange[-1]))
594 print('maxFreq is setting to %.2f' % (freqrange[-1]))
555 maxFreq = freqrange[-1]
595 maxFreq = freqrange[-1]
556
596
557 indminPoint = numpy.where(freqrange >= minFreq)
597 indminPoint = numpy.where(freqrange >= minFreq)
558 indmaxPoint = numpy.where(freqrange <= maxFreq)
598 indmaxPoint = numpy.where(freqrange <= maxFreq)
559
599
560 else:
600 else:
561
601
562 velrange = self.dataOut.getVelRange(1)
602 velrange = self.dataOut.getVelRange(1)
563
603
564 if minVel == None:
604 if minVel == None:
565 minVel = velrange[0]
605 minVel = velrange[0]
566
606
567 if maxVel == None:
607 if maxVel == None:
568 maxVel = velrange[-1]
608 maxVel = velrange[-1]
569
609
570 if (minVel < velrange[0]) or (minVel > maxVel):
610 if (minVel < velrange[0]) or (minVel > maxVel):
571 if self.warnings:
611 if self.warnings:
572 print('minVel: %.2f is out of the velocity range' % (minVel))
612 print('minVel: %.2f is out of the velocity range' % (minVel))
573 print('minVel is setting to %.2f' % (velrange[0]))
613 print('minVel is setting to %.2f' % (velrange[0]))
574 minVel = velrange[0]
614 minVel = velrange[0]
575
615
576 if (maxVel > velrange[-1]) or (maxVel < minVel):
616 if (maxVel > velrange[-1]) or (maxVel < minVel):
577 if self.warnings:
617 if self.warnings:
578 print('maxVel: %.2f is out of the velocity range' % (maxVel))
618 print('maxVel: %.2f is out of the velocity range' % (maxVel))
579 print('maxVel is setting to %.2f' % (velrange[-1]))
619 print('maxVel is setting to %.2f' % (velrange[-1]))
580 maxVel = velrange[-1]
620 maxVel = velrange[-1]
581
621
582 indminPoint = numpy.where(velrange >= minVel)
622 indminPoint = numpy.where(velrange >= minVel)
583 indmaxPoint = numpy.where(velrange <= maxVel)
623 indmaxPoint = numpy.where(velrange <= maxVel)
584
624
585
625
586 # seleccion de indices para rango
626 # seleccion de indices para rango
587 minIndex = 0
627 minIndex = 0
588 maxIndex = 0
628 maxIndex = 0
589 heights = self.dataOut.heightList
629 heights = self.dataOut.heightList
590
630
591 inda = numpy.where(heights >= minHei)
631 inda = numpy.where(heights >= minHei)
592 indb = numpy.where(heights <= maxHei)
632 indb = numpy.where(heights <= maxHei)
593
633
594 try:
634 try:
595 minIndex = inda[0][0]
635 minIndex = inda[0][0]
596 except:
636 except:
597 minIndex = 0
637 minIndex = 0
598
638
599 try:
639 try:
600 maxIndex = indb[0][-1]
640 maxIndex = indb[0][-1]
601 except:
641 except:
602 maxIndex = len(heights)
642 maxIndex = len(heights)
603
643
604 if (minIndex < 0) or (minIndex > maxIndex):
644 if (minIndex < 0) or (minIndex > maxIndex):
605 raise ValueError("some value in (%d,%d) is not valid" % (
645 raise ValueError("some value in (%d,%d) is not valid" % (
606 minIndex, maxIndex))
646 minIndex, maxIndex))
607
647
608 if (maxIndex >= self.dataOut.nHeights):
648 if (maxIndex >= self.dataOut.nHeights):
609 maxIndex = self.dataOut.nHeights - 1
649 maxIndex = self.dataOut.nHeights - 1
610 #############################################################3
650 #############################################################3
611 # seleccion de indices para velocidades
651 # seleccion de indices para velocidades
612 if self.dataOut.type == 'Spectra':
652 if self.dataOut.type == 'Spectra':
613 try:
653 try:
614 minIndexFFT = indminPoint[0][0]
654 minIndexFFT = indminPoint[0][0]
615 except:
655 except:
616 minIndexFFT = 0
656 minIndexFFT = 0
617
657
618 try:
658 try:
619 maxIndexFFT = indmaxPoint[0][-1]
659 maxIndexFFT = indmaxPoint[0][-1]
620 except:
660 except:
621 maxIndexFFT = len( self.dataOut.getFreqRange(1))
661 maxIndexFFT = len( self.dataOut.getFreqRange(1))
622
662
663 self.minIndex, self.maxIndex, self.minIndexFFT, self.maxIndexFFT = minIndex, maxIndex, minIndexFFT, maxIndexFFT
664 self.isConfig = True
665 if offset!=None:
666 self.offset = 10**(offset/10)
667 #print("config getNoise Done")
668
669 def run(self, dataOut, offset=None, minHei=None, maxHei=None,minVel=None, maxVel=None, minFreq= None, maxFreq=None, warnings=False):
670 self.dataOut = dataOut
671
672 if not self.isConfig:
673 self.setup(offset, minHei, maxHei,minVel, maxVel, minFreq, maxFreq, warnings)
623
674
624 self.dataOut.noise_estimation = None
675 self.dataOut.noise_estimation = None
625 noise = None
676 noise = None
626 if self.dataOut.type == 'Voltage':
677 if self.dataOut.type == 'Voltage':
627 noise = self.dataOut.getNoise(ymin_index=minIndex, ymax_index=maxIndex)
678 noise = self.dataOut.getNoise(ymin_index=self.minIndex, ymax_index=self.maxIndex)
628 #print(minIndex, maxIndex,minIndexVel, maxIndexVel)
679 #print(minIndex, maxIndex,minIndexVel, maxIndexVel)
629 elif self.dataOut.type == 'Spectra':
680 elif self.dataOut.type == 'Spectra':
630 noise = self.dataOut.getNoise(xmin_index=minIndexFFT, xmax_index=maxIndexFFT, ymin_index=minIndex, ymax_index=maxIndex)
681
682 noise = numpy.zeros( self.dataOut.nChannels)
683 for channel in range( self.dataOut.nChannels):
684 norm = self.dataOut.max_nIncohInt/self.dataOut.nIncohInt[channel, self.minIndex:self.maxIndex]
685 #print("norm nIncoh: ", norm )
686 daux = self.dataOut.data_spc[channel,self.minIndexFFT:self.maxIndexFFT, self.minIndex:self.maxIndex]
687 daux = numpy.multiply(daux, norm)
688 #print("offset: ", self.offset, 10*numpy.log10(self.offset))
689 #noise[channel] = self.getNoiseByMean(daux)/self.offset
690 noise[channel] = self.getNoiseByHS(daux, self.dataOut.max_nIncohInt)/self.offset
691
692 #noise = self.dataOut.getNoise(xmin_index=self.minIndexFFT, xmax_index=self.maxIndexFFT, ymin_index=self.minIndex, ymax_index=self.maxIndex)
631 else:
693 else:
632 noise = self.dataOut.getNoise(xmin_index=minIndexFFT, xmax_index=maxIndexFFT, ymin_index=minIndex, ymax_index=maxIndex)
694 noise = self.dataOut.getNoise(xmin_index=self.minIndexFFT, xmax_index=self.maxIndexFFT, ymin_index=self.minIndex, ymax_index=self.maxIndex)
633 self.dataOut.noise_estimation = noise.copy() # dataOut.noise
695 self.dataOut.noise_estimation = noise.copy() # dataOut.noise
634 #print("2: ",10*numpy.log10(self.dataOut.noise_estimation/64))
696 #print("2: ",10*numpy.log10(self.dataOut.noise_estimation/64))
635
697
698 #print(self.dataOut.flagNoData)
636 return self.dataOut
699 return self.dataOut
637
700
701 def getNoiseByMean(self,data):
702 #data debe estar ordenado
703 data = numpy.mean(data,axis=1)
704 sortdata = numpy.sort(data, axis=None)
705 #sortID=data.argsort()
706 #print(data.shape)
707
708 pnoise = None
709 j = 0
710
711 mean = numpy.mean(sortdata)
712 min = numpy.min(sortdata)
713 delta = mean - min
714 indexes = numpy.where(sortdata > (mean+delta))[0] #only array of indexes
715 #print(len(indexes))
716 if len(indexes)==0:
717 pnoise = numpy.mean(sortdata)
718 else:
719 j = indexes[0]
720 pnoise = numpy.mean(sortdata[0:j])
721
722 # from matplotlib import pyplot as plt
723 # plt.plot(sortdata)
724 # plt.vlines(j,(pnoise-delta),(pnoise+delta), color='r')
725 # plt.show()
726 #print("noise: ", 10*numpy.log10(pnoise))
727 return pnoise
728
729 def getNoiseByHS(self,data, navg):
730 #data debe estar ordenado
731 #data = numpy.mean(data,axis=1)
732 sortdata = numpy.sort(data, axis=None)
733
734 lenOfData = len(sortdata)
735 nums_min = lenOfData*0.05
736
737 if nums_min <= 5:
738
739 nums_min = 5
740
741 sump = 0.
742 sumq = 0.
743
744 j = 0
745 cont = 1
746
747 while((cont == 1)and(j < lenOfData)):
748
749 sump += sortdata[j]
750 sumq += sortdata[j]**2
751 #sumq -= sump**2
752 if j > nums_min:
753 rtest = float(j)/(j-1) + 1.0/0.1
754 #if ((sumq*j) > (sump**2)):
755 if ((sumq*j) > (rtest*sump**2)):
756 j = j - 1
757 sump = sump - sortdata[j]
758 sumq = sumq - sortdata[j]**2
759 cont = 0
760
761 j += 1
762
763 lnoise = sump / j
764
765 return lnoise
638
766
639
767
640 # import matplotlib.pyplot as plt
641
768
642 def fit_func( x, a0, a1, a2): #, a3, a4, a5):
769 def fit_func( x, a0, a1, a2): #, a3, a4, a5):
643 z = (x - a1) / a2
770 z = (x - a1) / a2
644 y = a0 * numpy.exp(-z**2 / a2) #+ a3 + a4 * x + a5 * x**2
771 y = a0 * numpy.exp(-z**2 / a2) #+ a3 + a4 * x + a5 * x**2
645 return y
772 return y
646
773
647
774
648 class CleanRayleigh(Operation):
775 class CleanRayleigh(Operation):
649
776
650 def __init__(self):
777 def __init__(self):
651
778
652 Operation.__init__(self)
779 Operation.__init__(self)
653 self.i=0
780 self.i=0
654 self.isConfig = False
781 self.isConfig = False
655 self.__dataReady = False
782 self.__dataReady = False
656 self.__profIndex = 0
783 self.__profIndex = 0
657 self.byTime = False
784 self.byTime = False
658 self.byProfiles = False
785 self.byProfiles = False
659
786
660 self.bloques = None
787 self.bloques = None
661 self.bloque0 = None
788 self.bloque0 = None
662
789
663 self.index = 0
790 self.index = 0
664
791
665 self.buffer = 0
792 self.buffer = 0
666 self.buffer2 = 0
793 self.buffer2 = 0
667 self.buffer3 = 0
794 self.buffer3 = 0
668
795
669
796
670 def setup(self,dataOut,min_hei,max_hei,n, timeInterval,factor_stdv):
797 def setup(self,dataOut,min_hei,max_hei,n, timeInterval,factor_stdv):
671
798
672 self.nChannels = dataOut.nChannels
799 self.nChannels = dataOut.nChannels
673 self.nProf = dataOut.nProfiles
800 self.nProf = dataOut.nProfiles
674 self.nPairs = dataOut.data_cspc.shape[0]
801 self.nPairs = dataOut.data_cspc.shape[0]
675 self.pairsArray = numpy.array(dataOut.pairsList)
802 self.pairsArray = numpy.array(dataOut.pairsList)
676 self.spectra = dataOut.data_spc
803 self.spectra = dataOut.data_spc
677 self.cspectra = dataOut.data_cspc
804 self.cspectra = dataOut.data_cspc
678 self.heights = dataOut.heightList #alturas totales
805 self.heights = dataOut.heightList #alturas totales
679 self.nHeights = len(self.heights)
806 self.nHeights = len(self.heights)
680 self.min_hei = min_hei
807 self.min_hei = min_hei
681 self.max_hei = max_hei
808 self.max_hei = max_hei
682 if (self.min_hei == None):
809 if (self.min_hei == None):
683 self.min_hei = 0
810 self.min_hei = 0
684 if (self.max_hei == None):
811 if (self.max_hei == None):
685 self.max_hei = dataOut.heightList[-1]
812 self.max_hei = dataOut.heightList[-1]
686 self.hval = ((self.max_hei>=self.heights) & (self.heights >= self.min_hei)).nonzero()
813 self.hval = ((self.max_hei>=self.heights) & (self.heights >= self.min_hei)).nonzero()
687 self.heightsClean = self.heights[self.hval] #alturas filtradas
814 self.heightsClean = self.heights[self.hval] #alturas filtradas
688 self.hval = self.hval[0] # forma (N,), an solo N elementos -> Indices de alturas
815 self.hval = self.hval[0] # forma (N,), an solo N elementos -> Indices de alturas
689 self.nHeightsClean = len(self.heightsClean)
816 self.nHeightsClean = len(self.heightsClean)
690 self.channels = dataOut.channelList
817 self.channels = dataOut.channelList
691 self.nChan = len(self.channels)
818 self.nChan = len(self.channels)
692 self.nIncohInt = dataOut.nIncohInt
819 self.nIncohInt = dataOut.nIncohInt
693 self.__initime = dataOut.utctime
820 self.__initime = dataOut.utctime
694 self.maxAltInd = self.hval[-1]+1
821 self.maxAltInd = self.hval[-1]+1
695 self.minAltInd = self.hval[0]
822 self.minAltInd = self.hval[0]
696
823
697 self.crosspairs = dataOut.pairsList
824 self.crosspairs = dataOut.pairsList
698 self.nPairs = len(self.crosspairs)
825 self.nPairs = len(self.crosspairs)
699 self.normFactor = dataOut.normFactor
826 self.normFactor = dataOut.normFactor
700 self.nFFTPoints = dataOut.nFFTPoints
827 self.nFFTPoints = dataOut.nFFTPoints
701 self.ippSeconds = dataOut.ippSeconds
828 self.ippSeconds = dataOut.ippSeconds
702 self.currentTime = self.__initime
829 self.currentTime = self.__initime
703 self.pairsArray = numpy.array(dataOut.pairsList)
830 self.pairsArray = numpy.array(dataOut.pairsList)
704 self.factor_stdv = factor_stdv
831 self.factor_stdv = factor_stdv
705
832
706 if n != None :
833 if n != None :
707 self.byProfiles = True
834 self.byProfiles = True
708 self.nIntProfiles = n
835 self.nIntProfiles = n
709 else:
836 else:
710 self.__integrationtime = timeInterval
837 self.__integrationtime = timeInterval
711
838
712 self.__dataReady = False
839 self.__dataReady = False
713 self.isConfig = True
840 self.isConfig = True
714
841
715
842
716
843
717 def run(self, dataOut,min_hei=None,max_hei=None, n=None, timeInterval=10,factor_stdv=2.5):
844 def run(self, dataOut,min_hei=None,max_hei=None, n=None, timeInterval=10,factor_stdv=2.5):
718 #print("runing cleanRayleigh")
845 #print("runing cleanRayleigh")
719 if not self.isConfig :
846 if not self.isConfig :
720
847
721 self.setup(dataOut, min_hei,max_hei,n,timeInterval,factor_stdv)
848 self.setup(dataOut, min_hei,max_hei,n,timeInterval,factor_stdv)
722
849
723 tini=dataOut.utctime
850 tini=dataOut.utctime
724
851
725 if self.byProfiles:
852 if self.byProfiles:
726 if self.__profIndex == self.nIntProfiles:
853 if self.__profIndex == self.nIntProfiles:
727 self.__dataReady = True
854 self.__dataReady = True
728 else:
855 else:
729 if (tini - self.__initime) >= self.__integrationtime:
856 if (tini - self.__initime) >= self.__integrationtime:
730
857
731 self.__dataReady = True
858 self.__dataReady = True
732 self.__initime = tini
859 self.__initime = tini
733
860
734 #if (tini.tm_min % 2) == 0 and (tini.tm_sec < 5 and self.fint==0):
861 #if (tini.tm_min % 2) == 0 and (tini.tm_sec < 5 and self.fint==0):
735
862
736 if self.__dataReady:
863 if self.__dataReady:
737
864
738 self.__profIndex = 0
865 self.__profIndex = 0
739 jspc = self.buffer
866 jspc = self.buffer
740 jcspc = self.buffer2
867 jcspc = self.buffer2
741 #jnoise = self.buffer3
868 #jnoise = self.buffer3
742 self.buffer = dataOut.data_spc
869 self.buffer = dataOut.data_spc
743 self.buffer2 = dataOut.data_cspc
870 self.buffer2 = dataOut.data_cspc
744 #self.buffer3 = dataOut.noise
871 #self.buffer3 = dataOut.noise
745 self.currentTime = dataOut.utctime
872 self.currentTime = dataOut.utctime
746 if numpy.any(jspc) :
873 if numpy.any(jspc) :
747 #print( jspc.shape, jcspc.shape)
874 #print( jspc.shape, jcspc.shape)
748 jspc = numpy.reshape(jspc,(int(len(jspc)/self.nChannels),self.nChannels,self.nFFTPoints,self.nHeights))
875 jspc = numpy.reshape(jspc,(int(len(jspc)/self.nChannels),self.nChannels,self.nFFTPoints,self.nHeights))
749 try:
876 try:
750 jcspc= numpy.reshape(jcspc,(int(len(jcspc)/self.nPairs),self.nPairs,self.nFFTPoints,self.nHeights))
877 jcspc= numpy.reshape(jcspc,(int(len(jcspc)/self.nPairs),self.nPairs,self.nFFTPoints,self.nHeights))
751 except:
878 except:
752 print("no cspc")
879 print("no cspc")
753 self.__dataReady = False
880 self.__dataReady = False
754 #print( jspc.shape, jcspc.shape)
881 #print( jspc.shape, jcspc.shape)
755 dataOut.flagNoData = False
882 dataOut.flagNoData = False
756 else:
883 else:
757 dataOut.flagNoData = True
884 dataOut.flagNoData = True
758 self.__dataReady = False
885 self.__dataReady = False
759 return dataOut
886 return dataOut
760 else:
887 else:
761 #print( len(self.buffer))
888 #print( len(self.buffer))
762 if numpy.any(self.buffer):
889 if numpy.any(self.buffer):
763 self.buffer = numpy.concatenate((self.buffer,dataOut.data_spc), axis=0)
890 self.buffer = numpy.concatenate((self.buffer,dataOut.data_spc), axis=0)
764 try:
891 try:
765 self.buffer2 = numpy.concatenate((self.buffer2,dataOut.data_cspc), axis=0)
892 self.buffer2 = numpy.concatenate((self.buffer2,dataOut.data_cspc), axis=0)
766 self.buffer3 += dataOut.data_dc
893 self.buffer3 += dataOut.data_dc
767 except:
894 except:
768 pass
895 pass
769 else:
896 else:
770 self.buffer = dataOut.data_spc
897 self.buffer = dataOut.data_spc
771 self.buffer2 = dataOut.data_cspc
898 self.buffer2 = dataOut.data_cspc
772 self.buffer3 = dataOut.data_dc
899 self.buffer3 = dataOut.data_dc
773 #print self.index, self.fint
900 #print self.index, self.fint
774 #print self.buffer2.shape
901 #print self.buffer2.shape
775 dataOut.flagNoData = True ## NOTE: ?? revisar LUEGO
902 dataOut.flagNoData = True ## NOTE: ?? revisar LUEGO
776 self.__profIndex += 1
903 self.__profIndex += 1
777 return dataOut ## NOTE: REV
904 return dataOut ## NOTE: REV
778
905
779
906
780 #index = tini.tm_hour*12+tini.tm_min/5
907 #index = tini.tm_hour*12+tini.tm_min/5
781 '''
908 '''
782 REVISAR
909 #REVISAR
783 '''
910 '''
784 # jspc = jspc/self.nFFTPoints/self.normFactor
911 # jspc = jspc/self.nFFTPoints/self.normFactor
785 # jcspc = jcspc/self.nFFTPoints/self.normFactor
912 # jcspc = jcspc/self.nFFTPoints/self.normFactor
786
913
787
914
788
915
789 tmp_spectra,tmp_cspectra = self.cleanRayleigh(dataOut,jspc,jcspc,self.factor_stdv)
916 tmp_spectra,tmp_cspectra = self.cleanRayleigh(dataOut,jspc,jcspc,self.factor_stdv)
790 dataOut.data_spc = tmp_spectra
917 dataOut.data_spc = tmp_spectra
791 dataOut.data_cspc = tmp_cspectra
918 dataOut.data_cspc = tmp_cspectra
792
919
793 #dataOut.data_spc,dataOut.data_cspc = self.cleanRayleigh(dataOut,jspc,jcspc,self.factor_stdv)
920 #dataOut.data_spc,dataOut.data_cspc = self.cleanRayleigh(dataOut,jspc,jcspc,self.factor_stdv)
794
921
795 dataOut.data_dc = self.buffer3
922 dataOut.data_dc = self.buffer3
796 dataOut.nIncohInt *= self.nIntProfiles
923 dataOut.nIncohInt *= self.nIntProfiles
797 dataOut.max_nIncohInt = self.nIntProfiles
924 dataOut.max_nIncohInt = self.nIntProfiles
798 dataOut.utctime = self.currentTime #tiempo promediado
925 dataOut.utctime = self.currentTime #tiempo promediado
799 #print("Time: ",time.localtime(dataOut.utctime))
926 #print("Time: ",time.localtime(dataOut.utctime))
800 # dataOut.data_spc = sat_spectra
927 # dataOut.data_spc = sat_spectra
801 # dataOut.data_cspc = sat_cspectra
928 # dataOut.data_cspc = sat_cspectra
802 self.buffer = 0
929 self.buffer = 0
803 self.buffer2 = 0
930 self.buffer2 = 0
804 self.buffer3 = 0
931 self.buffer3 = 0
805
932
806 return dataOut
933 return dataOut
807
934
808 def cleanRayleigh(self,dataOut,spectra,cspectra,factor_stdv):
935 def cleanRayleigh(self,dataOut,spectra,cspectra,factor_stdv):
809 print("OP cleanRayleigh")
936 print("OP cleanRayleigh")
810 #import matplotlib.pyplot as plt
937 #import matplotlib.pyplot as plt
811 #for k in range(149):
938 #for k in range(149):
812 #channelsProcssd = []
939 #channelsProcssd = []
813 #channelA_ok = False
940 #channelA_ok = False
814 #rfunc = cspectra.copy() #self.bloques
941 #rfunc = cspectra.copy() #self.bloques
815 rfunc = spectra.copy()
942 rfunc = spectra.copy()
816 #rfunc = cspectra
943 #rfunc = cspectra
817 #val_spc = spectra*0.0 #self.bloque0*0.0
944 #val_spc = spectra*0.0 #self.bloque0*0.0
818 #val_cspc = cspectra*0.0 #self.bloques*0.0
945 #val_cspc = cspectra*0.0 #self.bloques*0.0
819 #in_sat_spectra = spectra.copy() #self.bloque0
946 #in_sat_spectra = spectra.copy() #self.bloque0
820 #in_sat_cspectra = cspectra.copy() #self.bloques
947 #in_sat_cspectra = cspectra.copy() #self.bloques
821
948
822
949
823 ###ONLY FOR TEST:
950 ###ONLY FOR TEST:
824 raxs = math.ceil(math.sqrt(self.nPairs))
951 raxs = math.ceil(math.sqrt(self.nPairs))
825 if raxs == 0:
952 if raxs == 0:
826 raxs = 1
953 raxs = 1
827 caxs = math.ceil(self.nPairs/raxs)
954 caxs = math.ceil(self.nPairs/raxs)
828 if self.nPairs <4:
955 if self.nPairs <4:
829 raxs = 2
956 raxs = 2
830 caxs = 2
957 caxs = 2
831 #print(raxs, caxs)
958 #print(raxs, caxs)
832 fft_rev = 14 #nFFT to plot
959 fft_rev = 14 #nFFT to plot
833 hei_rev = ((self.heights >= 550) & (self.heights <= 551)).nonzero() #hei to plot
960 hei_rev = ((self.heights >= 550) & (self.heights <= 551)).nonzero() #hei to plot
834 hei_rev = hei_rev[0]
961 hei_rev = hei_rev[0]
835 #print(hei_rev)
962 #print(hei_rev)
836
963
837 #print numpy.absolute(rfunc[:,0,0,14])
964 #print numpy.absolute(rfunc[:,0,0,14])
838
965
839 gauss_fit, covariance = None, None
966 gauss_fit, covariance = None, None
840 for ih in range(self.minAltInd,self.maxAltInd):
967 for ih in range(self.minAltInd,self.maxAltInd):
841 for ifreq in range(self.nFFTPoints):
968 for ifreq in range(self.nFFTPoints):
842 '''
969 '''
843 ###ONLY FOR TEST:
970 ###ONLY FOR TEST:
844 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
971 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
845 fig, axs = plt.subplots(raxs, caxs)
972 fig, axs = plt.subplots(raxs, caxs)
846 fig2, axs2 = plt.subplots(raxs, caxs)
973 fig2, axs2 = plt.subplots(raxs, caxs)
847 col_ax = 0
974 col_ax = 0
848 row_ax = 0
975 row_ax = 0
849 '''
976 '''
850 #print(self.nPairs)
977 #print(self.nPairs)
851 for ii in range(self.nChan): #PARES DE CANALES SELF y CROSS
978 for ii in range(self.nChan): #PARES DE CANALES SELF y CROSS
852 # if self.crosspairs[ii][1]-self.crosspairs[ii][0] > 1: # APLICAR SOLO EN PARES CONTIGUOS
979 # if self.crosspairs[ii][1]-self.crosspairs[ii][0] > 1: # APLICAR SOLO EN PARES CONTIGUOS
853 # continue
980 # continue
854 # if not self.crosspairs[ii][0] in channelsProcssd:
981 # if not self.crosspairs[ii][0] in channelsProcssd:
855 # channelA_ok = True
982 # channelA_ok = True
856 #print("pair: ",self.crosspairs[ii])
983 #print("pair: ",self.crosspairs[ii])
857 '''
984 '''
858 ###ONLY FOR TEST:
985 ###ONLY FOR TEST:
859 if (col_ax%caxs==0 and col_ax!=0 and self.nPairs !=1):
986 if (col_ax%caxs==0 and col_ax!=0 and self.nPairs !=1):
860 col_ax = 0
987 col_ax = 0
861 row_ax += 1
988 row_ax += 1
862 '''
989 '''
863 func2clean = 10*numpy.log10(numpy.absolute(rfunc[:,ii,ifreq,ih])) #Potencia?
990 func2clean = 10*numpy.log10(numpy.absolute(rfunc[:,ii,ifreq,ih])) #Potencia?
864 #print(func2clean.shape)
991 #print(func2clean.shape)
865 val = (numpy.isfinite(func2clean)==True).nonzero()
992 val = (numpy.isfinite(func2clean)==True).nonzero()
866
993
867 if len(val)>0: #limitador
994 if len(val)>0: #limitador
868 min_val = numpy.around(numpy.amin(func2clean)-2) #> (-40)
995 min_val = numpy.around(numpy.amin(func2clean)-2) #> (-40)
869 if min_val <= -40 :
996 if min_val <= -40 :
870 min_val = -40
997 min_val = -40
871 max_val = numpy.around(numpy.amax(func2clean)+2) #< 200
998 max_val = numpy.around(numpy.amax(func2clean)+2) #< 200
872 if max_val >= 200 :
999 if max_val >= 200 :
873 max_val = 200
1000 max_val = 200
874 #print min_val, max_val
1001 #print min_val, max_val
875 step = 1
1002 step = 1
876 #print("Getting bins and the histogram")
1003 #print("Getting bins and the histogram")
877 x_dist = min_val + numpy.arange(1 + ((max_val-(min_val))/step))*step
1004 x_dist = min_val + numpy.arange(1 + ((max_val-(min_val))/step))*step
878 y_dist,binstep = numpy.histogram(func2clean,bins=range(int(min_val),int(max_val+2),step))
1005 y_dist,binstep = numpy.histogram(func2clean,bins=range(int(min_val),int(max_val+2),step))
879 #print(len(y_dist),len(binstep[:-1]))
1006 #print(len(y_dist),len(binstep[:-1]))
880 #print(row_ax,col_ax, " ..")
1007 #print(row_ax,col_ax, " ..")
881 #print(self.pairsArray[ii][0],self.pairsArray[ii][1])
1008 #print(self.pairsArray[ii][0],self.pairsArray[ii][1])
882 mean = numpy.sum(x_dist * y_dist) / numpy.sum(y_dist)
1009 mean = numpy.sum(x_dist * y_dist) / numpy.sum(y_dist)
883 sigma = numpy.sqrt(numpy.sum(y_dist * (x_dist - mean)**2) / numpy.sum(y_dist))
1010 sigma = numpy.sqrt(numpy.sum(y_dist * (x_dist - mean)**2) / numpy.sum(y_dist))
884 parg = [numpy.amax(y_dist),mean,sigma]
1011 parg = [numpy.amax(y_dist),mean,sigma]
885
1012
886 newY = None
1013 newY = None
887
1014
888 try :
1015 try :
889 gauss_fit, covariance = curve_fit(fit_func, x_dist, y_dist,p0=parg)
1016 gauss_fit, covariance = curve_fit(fit_func, x_dist, y_dist,p0=parg)
890 mode = gauss_fit[1]
1017 mode = gauss_fit[1]
891 stdv = gauss_fit[2]
1018 stdv = gauss_fit[2]
892 #print(" FIT OK",gauss_fit)
1019 #print(" FIT OK",gauss_fit)
893 '''
1020 '''
894 ###ONLY FOR TEST:
1021 ###ONLY FOR TEST:
895 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
1022 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
896 newY = fit_func(x_dist,gauss_fit[0],gauss_fit[1],gauss_fit[2])
1023 newY = fit_func(x_dist,gauss_fit[0],gauss_fit[1],gauss_fit[2])
897 axs[row_ax,col_ax].plot(binstep[:-1],y_dist,color='green')
1024 axs[row_ax,col_ax].plot(binstep[:-1],y_dist,color='green')
898 axs[row_ax,col_ax].plot(binstep[:-1],newY,color='red')
1025 axs[row_ax,col_ax].plot(binstep[:-1],newY,color='red')
899 axs[row_ax,col_ax].set_title("CH "+str(self.channels[ii]))
1026 axs[row_ax,col_ax].set_title("CH "+str(self.channels[ii]))
900 '''
1027 '''
901 except:
1028 except:
902 mode = mean
1029 mode = mean
903 stdv = sigma
1030 stdv = sigma
904 #print("FIT FAIL")
1031 #print("FIT FAIL")
905 #continue
1032 #continue
906
1033
907
1034
908 #print(mode,stdv)
1035 #print(mode,stdv)
909 #Removing echoes greater than mode + std_factor*stdv
1036 #Removing echoes greater than mode + std_factor*stdv
910 noval = (abs(func2clean - mode)>=(factor_stdv*stdv)).nonzero()
1037 noval = (abs(func2clean - mode)>=(factor_stdv*stdv)).nonzero()
911 #noval tiene los indices que se van a remover
1038 #noval tiene los indices que se van a remover
912 #print("Chan ",ii," novals: ",len(noval[0]))
1039 #print("Chan ",ii," novals: ",len(noval[0]))
913 if len(noval[0]) > 0: #forma de array (N,) es igual a longitud (N)
1040 if len(noval[0]) > 0: #forma de array (N,) es igual a longitud (N)
914 novall = ((func2clean - mode) >= (factor_stdv*stdv)).nonzero()
1041 novall = ((func2clean - mode) >= (factor_stdv*stdv)).nonzero()
915 #print(novall)
1042 #print(novall)
916 #print(" ",self.pairsArray[ii])
1043 #print(" ",self.pairsArray[ii])
917 #cross_pairs = self.pairsArray[ii]
1044 #cross_pairs = self.pairsArray[ii]
918 #Getting coherent echoes which are removed.
1045 #Getting coherent echoes which are removed.
919 # if len(novall[0]) > 0:
1046 # if len(novall[0]) > 0:
920 #
1047 #
921 # val_spc[novall[0],cross_pairs[0],ifreq,ih] = 1
1048 # val_spc[novall[0],cross_pairs[0],ifreq,ih] = 1
922 # val_spc[novall[0],cross_pairs[1],ifreq,ih] = 1
1049 # val_spc[novall[0],cross_pairs[1],ifreq,ih] = 1
923 # val_cspc[novall[0],ii,ifreq,ih] = 1
1050 # val_cspc[novall[0],ii,ifreq,ih] = 1
924 #print("OUT NOVALL 1")
1051 #print("OUT NOVALL 1")
925 try:
1052 try:
926 pair = (self.channels[ii],self.channels[ii + 1])
1053 pair = (self.channels[ii],self.channels[ii + 1])
927 except:
1054 except:
928 pair = (99,99)
1055 pair = (99,99)
929 #print("par ", pair)
1056 #print("par ", pair)
930 if ( pair in self.crosspairs):
1057 if ( pair in self.crosspairs):
931 q = self.crosspairs.index(pair)
1058 q = self.crosspairs.index(pair)
932 #print("está aqui: ", q, (ii,ii + 1))
1059 #print("está aqui: ", q, (ii,ii + 1))
933 new_a = numpy.delete(cspectra[:,q,ifreq,ih], noval[0])
1060 new_a = numpy.delete(cspectra[:,q,ifreq,ih], noval[0])
934 cspectra[noval,q,ifreq,ih] = numpy.mean(new_a) #mean CrossSpectra
1061 cspectra[noval,q,ifreq,ih] = numpy.mean(new_a) #mean CrossSpectra
935
1062
936 #if channelA_ok:
1063 #if channelA_ok:
937 #chA = self.channels.index(cross_pairs[0])
1064 #chA = self.channels.index(cross_pairs[0])
938 new_b = numpy.delete(spectra[:,ii,ifreq,ih], noval[0])
1065 new_b = numpy.delete(spectra[:,ii,ifreq,ih], noval[0])
939 spectra[noval,ii,ifreq,ih] = numpy.mean(new_b) #mean Spectra Pair A
1066 spectra[noval,ii,ifreq,ih] = numpy.mean(new_b) #mean Spectra Pair A
940 #channelA_ok = False
1067 #channelA_ok = False
941
1068
942 # chB = self.channels.index(cross_pairs[1])
1069 # chB = self.channels.index(cross_pairs[1])
943 # new_c = numpy.delete(spectra[:,chB,ifreq,ih], noval[0])
1070 # new_c = numpy.delete(spectra[:,chB,ifreq,ih], noval[0])
944 # spectra[noval,chB,ifreq,ih] = numpy.mean(new_c) #mean Spectra Pair B
1071 # spectra[noval,chB,ifreq,ih] = numpy.mean(new_c) #mean Spectra Pair B
945 #
1072 #
946 # channelsProcssd.append(self.crosspairs[ii][0]) # save channel A
1073 # channelsProcssd.append(self.crosspairs[ii][0]) # save channel A
947 # channelsProcssd.append(self.crosspairs[ii][1]) # save channel B
1074 # channelsProcssd.append(self.crosspairs[ii][1]) # save channel B
948 '''
1075 '''
949 ###ONLY FOR TEST:
1076 ###ONLY FOR TEST:
950 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
1077 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
951 func2clean = 10*numpy.log10(numpy.absolute(spectra[:,ii,ifreq,ih]))
1078 func2clean = 10*numpy.log10(numpy.absolute(spectra[:,ii,ifreq,ih]))
952 y_dist,binstep = numpy.histogram(func2clean,bins=range(int(min_val),int(max_val+2),step))
1079 y_dist,binstep = numpy.histogram(func2clean,bins=range(int(min_val),int(max_val+2),step))
953 axs2[row_ax,col_ax].plot(binstep[:-1],newY,color='red')
1080 axs2[row_ax,col_ax].plot(binstep[:-1],newY,color='red')
954 axs2[row_ax,col_ax].plot(binstep[:-1],y_dist,color='green')
1081 axs2[row_ax,col_ax].plot(binstep[:-1],y_dist,color='green')
955 axs2[row_ax,col_ax].set_title("CH "+str(self.channels[ii]))
1082 axs2[row_ax,col_ax].set_title("CH "+str(self.channels[ii]))
956 '''
1083 '''
957 '''
1084 '''
958 ###ONLY FOR TEST:
1085 ###ONLY FOR TEST:
959 col_ax += 1 #contador de ploteo columnas
1086 col_ax += 1 #contador de ploteo columnas
960 ##print(col_ax)
1087 ##print(col_ax)
961 ###ONLY FOR TEST:
1088 ###ONLY FOR TEST:
962 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
1089 if ifreq ==fft_rev and ih==hei_rev: #TO VIEW A SIGNLE FREQUENCY
963 title = str(dataOut.datatime)+" nFFT: "+str(ifreq)+" Alt: "+str(self.heights[ih])+ " km"
1090 title = str(dataOut.datatime)+" nFFT: "+str(ifreq)+" Alt: "+str(self.heights[ih])+ " km"
964 title2 = str(dataOut.datatime)+" nFFT: "+str(ifreq)+" Alt: "+str(self.heights[ih])+ " km CLEANED"
1091 title2 = str(dataOut.datatime)+" nFFT: "+str(ifreq)+" Alt: "+str(self.heights[ih])+ " km CLEANED"
965 fig.suptitle(title)
1092 fig.suptitle(title)
966 fig2.suptitle(title2)
1093 fig2.suptitle(title2)
967 plt.show()
1094 plt.show()
968 '''
1095 '''
969 ##################################################################################################
1096 ##################################################################################################
970
1097
971 #print("Getting average of the spectra and cross-spectra from incoherent echoes.")
1098 #print("Getting average of the spectra and cross-spectra from incoherent echoes.")
972 out_spectra = numpy.zeros([self.nChan,self.nFFTPoints,self.nHeights], dtype=float) #+numpy.nan
1099 out_spectra = numpy.zeros([self.nChan,self.nFFTPoints,self.nHeights], dtype=float) #+numpy.nan
973 out_cspectra = numpy.zeros([self.nPairs,self.nFFTPoints,self.nHeights], dtype=complex) #+numpy.nan
1100 out_cspectra = numpy.zeros([self.nPairs,self.nFFTPoints,self.nHeights], dtype=complex) #+numpy.nan
974 for ih in range(self.nHeights):
1101 for ih in range(self.nHeights):
975 for ifreq in range(self.nFFTPoints):
1102 for ifreq in range(self.nFFTPoints):
976 for ich in range(self.nChan):
1103 for ich in range(self.nChan):
977 tmp = spectra[:,ich,ifreq,ih]
1104 tmp = spectra[:,ich,ifreq,ih]
978 valid = (numpy.isfinite(tmp[:])==True).nonzero()
1105 valid = (numpy.isfinite(tmp[:])==True).nonzero()
979
1106
980 if len(valid[0]) >0 :
1107 if len(valid[0]) >0 :
981 out_spectra[ich,ifreq,ih] = numpy.nansum(tmp)#/len(valid[0])
1108 out_spectra[ich,ifreq,ih] = numpy.nansum(tmp)#/len(valid[0])
982
1109
983 for icr in range(self.nPairs):
1110 for icr in range(self.nPairs):
984 tmp = numpy.squeeze(cspectra[:,icr,ifreq,ih])
1111 tmp = numpy.squeeze(cspectra[:,icr,ifreq,ih])
985 valid = (numpy.isfinite(tmp)==True).nonzero()
1112 valid = (numpy.isfinite(tmp)==True).nonzero()
986 if len(valid[0]) > 0:
1113 if len(valid[0]) > 0:
987 out_cspectra[icr,ifreq,ih] = numpy.nansum(tmp)#/len(valid[0])
1114 out_cspectra[icr,ifreq,ih] = numpy.nansum(tmp)#/len(valid[0])
988
1115
989 return out_spectra, out_cspectra
1116 return out_spectra, out_cspectra
990
1117
991 def REM_ISOLATED_POINTS(self,array,rth):
1118 def REM_ISOLATED_POINTS(self,array,rth):
992 # import matplotlib.pyplot as plt
1119 # import matplotlib.pyplot as plt
993 if rth == None :
1120 if rth == None :
994 rth = 4
1121 rth = 4
995 #print("REM ISO")
1122 #print("REM ISO")
996 num_prof = len(array[0,:,0])
1123 num_prof = len(array[0,:,0])
997 num_hei = len(array[0,0,:])
1124 num_hei = len(array[0,0,:])
998 n2d = len(array[:,0,0])
1125 n2d = len(array[:,0,0])
999
1126
1000 for ii in range(n2d) :
1127 for ii in range(n2d) :
1001 #print ii,n2d
1128 #print ii,n2d
1002 tmp = array[ii,:,:]
1129 tmp = array[ii,:,:]
1003 #print tmp.shape, array[ii,101,:],array[ii,102,:]
1130 #print tmp.shape, array[ii,101,:],array[ii,102,:]
1004
1131
1005 # fig = plt.figure(figsize=(6,5))
1132 # fig = plt.figure(figsize=(6,5))
1006 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
1133 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
1007 # ax = fig.add_axes([left, bottom, width, height])
1134 # ax = fig.add_axes([left, bottom, width, height])
1008 # x = range(num_prof)
1135 # x = range(num_prof)
1009 # y = range(num_hei)
1136 # y = range(num_hei)
1010 # cp = ax.contour(y,x,tmp)
1137 # cp = ax.contour(y,x,tmp)
1011 # ax.clabel(cp, inline=True,fontsize=10)
1138 # ax.clabel(cp, inline=True,fontsize=10)
1012 # plt.show()
1139 # plt.show()
1013
1140
1014 #indxs = WHERE(FINITE(tmp) AND tmp GT 0,cindxs)
1141 #indxs = WHERE(FINITE(tmp) AND tmp GT 0,cindxs)
1015 tmp = numpy.reshape(tmp,num_prof*num_hei)
1142 tmp = numpy.reshape(tmp,num_prof*num_hei)
1016 indxs1 = (numpy.isfinite(tmp)==True).nonzero()
1143 indxs1 = (numpy.isfinite(tmp)==True).nonzero()
1017 indxs2 = (tmp > 0).nonzero()
1144 indxs2 = (tmp > 0).nonzero()
1018
1145
1019 indxs1 = (indxs1[0])
1146 indxs1 = (indxs1[0])
1020 indxs2 = indxs2[0]
1147 indxs2 = indxs2[0]
1021 #indxs1 = numpy.array(indxs1[0])
1148 #indxs1 = numpy.array(indxs1[0])
1022 #indxs2 = numpy.array(indxs2[0])
1149 #indxs2 = numpy.array(indxs2[0])
1023 indxs = None
1150 indxs = None
1024 #print indxs1 , indxs2
1151 #print indxs1 , indxs2
1025 for iv in range(len(indxs2)):
1152 for iv in range(len(indxs2)):
1026 indv = numpy.array((indxs1 == indxs2[iv]).nonzero())
1153 indv = numpy.array((indxs1 == indxs2[iv]).nonzero())
1027 #print len(indxs2), indv
1154 #print len(indxs2), indv
1028 if len(indv[0]) > 0 :
1155 if len(indv[0]) > 0 :
1029 indxs = numpy.concatenate((indxs,indxs2[iv]), axis=None)
1156 indxs = numpy.concatenate((indxs,indxs2[iv]), axis=None)
1030 # print indxs
1157 # print indxs
1031 indxs = indxs[1:]
1158 indxs = indxs[1:]
1032 #print(indxs, len(indxs))
1159 #print(indxs, len(indxs))
1033 if len(indxs) < 4 :
1160 if len(indxs) < 4 :
1034 array[ii,:,:] = 0.
1161 array[ii,:,:] = 0.
1035 return
1162 return
1036
1163
1037 xpos = numpy.mod(indxs ,num_hei)
1164 xpos = numpy.mod(indxs ,num_hei)
1038 ypos = (indxs / num_hei)
1165 ypos = (indxs / num_hei)
1039 sx = numpy.argsort(xpos) # Ordering respect to "x" (time)
1166 sx = numpy.argsort(xpos) # Ordering respect to "x" (time)
1040 #print sx
1167 #print sx
1041 xpos = xpos[sx]
1168 xpos = xpos[sx]
1042 ypos = ypos[sx]
1169 ypos = ypos[sx]
1043
1170
1044 # *********************************** Cleaning isolated points **********************************
1171 # *********************************** Cleaning isolated points **********************************
1045 ic = 0
1172 ic = 0
1046 while True :
1173 while True :
1047 r = numpy.sqrt(list(numpy.power((xpos[ic]-xpos),2)+ numpy.power((ypos[ic]-ypos),2)))
1174 r = numpy.sqrt(list(numpy.power((xpos[ic]-xpos),2)+ numpy.power((ypos[ic]-ypos),2)))
1048 #no_coh = WHERE(FINITE(r) AND (r LE rth),cno_coh)
1175 #no_coh = WHERE(FINITE(r) AND (r LE rth),cno_coh)
1049 #plt.plot(r)
1176 #plt.plot(r)
1050 #plt.show()
1177 #plt.show()
1051 no_coh1 = (numpy.isfinite(r)==True).nonzero()
1178 no_coh1 = (numpy.isfinite(r)==True).nonzero()
1052 no_coh2 = (r <= rth).nonzero()
1179 no_coh2 = (r <= rth).nonzero()
1053 #print r, no_coh1, no_coh2
1180 #print r, no_coh1, no_coh2
1054 no_coh1 = numpy.array(no_coh1[0])
1181 no_coh1 = numpy.array(no_coh1[0])
1055 no_coh2 = numpy.array(no_coh2[0])
1182 no_coh2 = numpy.array(no_coh2[0])
1056 no_coh = None
1183 no_coh = None
1057 #print valid1 , valid2
1184 #print valid1 , valid2
1058 for iv in range(len(no_coh2)):
1185 for iv in range(len(no_coh2)):
1059 indv = numpy.array((no_coh1 == no_coh2[iv]).nonzero())
1186 indv = numpy.array((no_coh1 == no_coh2[iv]).nonzero())
1060 if len(indv[0]) > 0 :
1187 if len(indv[0]) > 0 :
1061 no_coh = numpy.concatenate((no_coh,no_coh2[iv]), axis=None)
1188 no_coh = numpy.concatenate((no_coh,no_coh2[iv]), axis=None)
1062 no_coh = no_coh[1:]
1189 no_coh = no_coh[1:]
1063 #print len(no_coh), no_coh
1190 #print len(no_coh), no_coh
1064 if len(no_coh) < 4 :
1191 if len(no_coh) < 4 :
1065 #print xpos[ic], ypos[ic], ic
1192 #print xpos[ic], ypos[ic], ic
1066 # plt.plot(r)
1193 # plt.plot(r)
1067 # plt.show()
1194 # plt.show()
1068 xpos[ic] = numpy.nan
1195 xpos[ic] = numpy.nan
1069 ypos[ic] = numpy.nan
1196 ypos[ic] = numpy.nan
1070
1197
1071 ic = ic + 1
1198 ic = ic + 1
1072 if (ic == len(indxs)) :
1199 if (ic == len(indxs)) :
1073 break
1200 break
1074 #print( xpos, ypos)
1201 #print( xpos, ypos)
1075
1202
1076 indxs = (numpy.isfinite(list(xpos))==True).nonzero()
1203 indxs = (numpy.isfinite(list(xpos))==True).nonzero()
1077 #print indxs[0]
1204 #print indxs[0]
1078 if len(indxs[0]) < 4 :
1205 if len(indxs[0]) < 4 :
1079 array[ii,:,:] = 0.
1206 array[ii,:,:] = 0.
1080 return
1207 return
1081
1208
1082 xpos = xpos[indxs[0]]
1209 xpos = xpos[indxs[0]]
1083 ypos = ypos[indxs[0]]
1210 ypos = ypos[indxs[0]]
1084 for i in range(0,len(ypos)):
1211 for i in range(0,len(ypos)):
1085 ypos[i]=int(ypos[i])
1212 ypos[i]=int(ypos[i])
1086 junk = tmp
1213 junk = tmp
1087 tmp = junk*0.0
1214 tmp = junk*0.0
1088
1215
1089 tmp[list(xpos + (ypos*num_hei))] = junk[list(xpos + (ypos*num_hei))]
1216 tmp[list(xpos + (ypos*num_hei))] = junk[list(xpos + (ypos*num_hei))]
1090 array[ii,:,:] = numpy.reshape(tmp,(num_prof,num_hei))
1217 array[ii,:,:] = numpy.reshape(tmp,(num_prof,num_hei))
1091
1218
1092 #print array.shape
1219 #print array.shape
1093 #tmp = numpy.reshape(tmp,(num_prof,num_hei))
1220 #tmp = numpy.reshape(tmp,(num_prof,num_hei))
1094 #print tmp.shape
1221 #print tmp.shape
1095
1222
1096 # fig = plt.figure(figsize=(6,5))
1223 # fig = plt.figure(figsize=(6,5))
1097 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
1224 # left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
1098 # ax = fig.add_axes([left, bottom, width, height])
1225 # ax = fig.add_axes([left, bottom, width, height])
1099 # x = range(num_prof)
1226 # x = range(num_prof)
1100 # y = range(num_hei)
1227 # y = range(num_hei)
1101 # cp = ax.contour(y,x,array[ii,:,:])
1228 # cp = ax.contour(y,x,array[ii,:,:])
1102 # ax.clabel(cp, inline=True,fontsize=10)
1229 # ax.clabel(cp, inline=True,fontsize=10)
1103 # plt.show()
1230 # plt.show()
1104 return array
1231 return array
1105
1232
1106
1233
1107 class IntegrationFaradaySpectra(Operation):
1234 class IntegrationFaradaySpectra(Operation):
1108
1235
1109 __profIndex = 0
1236 __profIndex = 0
1110 __withOverapping = False
1237 __withOverapping = False
1111
1238
1112 __byTime = False
1239 __byTime = False
1113 __initime = None
1240 __initime = None
1114 __lastdatatime = None
1241 __lastdatatime = None
1115 __integrationtime = None
1242 __integrationtime = None
1116
1243
1117 __buffer_spc = None
1244 __buffer_spc = None
1118 __buffer_cspc = None
1245 __buffer_cspc = None
1119 __buffer_dc = None
1246 __buffer_dc = None
1120
1247
1121 __dataReady = False
1248 __dataReady = False
1122
1249
1123 __timeInterval = None
1250 __timeInterval = None
1124 n_ints = None #matriz de numero de integracions (CH,HEI)
1251 n_ints = None #matriz de numero de integracions (CH,HEI)
1125 n = None
1252 n = None
1126 minHei_ind = None
1253 minHei_ind = None
1127 maxHei_ind = None
1254 maxHei_ind = None
1128 navg = 1.0
1255 navg = 1.0
1129 factor = 0.0
1256 factor = 0.0
1130 dataoutliers = None # (CHANNELS, HEIGHTS)
1257 dataoutliers = None # (CHANNELS, HEIGHTS)
1131
1258
1132 def __init__(self):
1259 def __init__(self):
1133
1260
1134 Operation.__init__(self)
1261 Operation.__init__(self)
1135
1262
1136 def setup(self, dataOut,n=None, timeInterval=None, overlapping=False, DPL=None, minHei=None, maxHei=None, avg=1,factor=0.75):
1263 def setup(self, dataOut,n=None, timeInterval=None, overlapping=False, DPL=None, minHei=None, maxHei=None, avg=1,factor=0.75):
1137 """
1264 """
1138 Set the parameters of the integration class.
1265 Set the parameters of the integration class.
1139
1266
1140 Inputs:
1267 Inputs:
1141
1268
1142 n : Number of coherent integrations
1269 n : Number of coherent integrations
1143 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1270 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1144 overlapping :
1271 overlapping :
1145
1272
1146 """
1273 """
1147
1274
1148 self.__initime = None
1275 self.__initime = None
1149 self.__lastdatatime = 0
1276 self.__lastdatatime = 0
1150
1277
1151 self.__buffer_spc = []
1278 self.__buffer_spc = []
1152 self.__buffer_cspc = []
1279 self.__buffer_cspc = []
1153 self.__buffer_dc = 0
1280 self.__buffer_dc = 0
1154
1281
1155 self.__profIndex = 0
1282 self.__profIndex = 0
1156 self.__dataReady = False
1283 self.__dataReady = False
1157 self.__byTime = False
1284 self.__byTime = False
1158
1285
1159 self.factor = factor
1286 self.factor = factor
1160 self.navg = avg
1287 self.navg = avg
1161 #self.ByLags = dataOut.ByLags ###REDEFINIR
1288 #self.ByLags = dataOut.ByLags ###REDEFINIR
1162 self.ByLags = False
1289 self.ByLags = False
1163 self.maxProfilesInt = 1
1290 self.maxProfilesInt = 1
1164
1291
1165 if DPL != None:
1292 if DPL != None:
1166 self.DPL=DPL
1293 self.DPL=DPL
1167 else:
1294 else:
1168 #self.DPL=dataOut.DPL ###REDEFINIR
1295 #self.DPL=dataOut.DPL ###REDEFINIR
1169 self.DPL=0
1296 self.DPL=0
1170
1297
1171 if n is None and timeInterval is None:
1298 if n is None and timeInterval is None:
1172 raise ValueError("n or timeInterval should be specified ...")
1299 raise ValueError("n or timeInterval should be specified ...")
1173
1300
1174 if n is not None:
1301 if n is not None:
1175 self.n = int(n)
1302 self.n = int(n)
1176 else:
1303 else:
1177 self.__integrationtime = int(timeInterval)
1304 self.__integrationtime = int(timeInterval)
1178 self.n = None
1305 self.n = None
1179 self.__byTime = True
1306 self.__byTime = True
1180
1307
1181 if minHei == None:
1308 if minHei == None:
1182 minHei = self.dataOut.heightList[0]
1309 minHei = self.dataOut.heightList[0]
1183
1310
1184 if maxHei == None:
1311 if maxHei == None:
1185 maxHei = self.dataOut.heightList[-1]
1312 maxHei = self.dataOut.heightList[-1]
1186
1313
1187 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
1314 if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei):
1188 print('minHei: %.2f is out of the heights range' % (minHei))
1315 print('minHei: %.2f is out of the heights range' % (minHei))
1189 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
1316 print('minHei is setting to %.2f' % (self.dataOut.heightList[0]))
1190 minHei = self.dataOut.heightList[0]
1317 minHei = self.dataOut.heightList[0]
1191
1318
1192 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
1319 if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei):
1193 print('maxHei: %.2f is out of the heights range' % (maxHei))
1320 print('maxHei: %.2f is out of the heights range' % (maxHei))
1194 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
1321 print('maxHei is setting to %.2f' % (self.dataOut.heightList[-1]))
1195 maxHei = self.dataOut.heightList[-1]
1322 maxHei = self.dataOut.heightList[-1]
1196
1323
1197 ind_list1 = numpy.where(self.dataOut.heightList >= minHei)
1324 ind_list1 = numpy.where(self.dataOut.heightList >= minHei)
1198 ind_list2 = numpy.where(self.dataOut.heightList <= maxHei)
1325 ind_list2 = numpy.where(self.dataOut.heightList <= maxHei)
1199 self.minHei_ind = ind_list1[0][0]
1326 self.minHei_ind = ind_list1[0][0]
1200 self.maxHei_ind = ind_list2[0][-1]
1327 self.maxHei_ind = ind_list2[0][-1]
1201
1328
1202 def putData(self, data_spc, data_cspc, data_dc):
1329 def putData(self, data_spc, data_cspc, data_dc):
1203 """
1330 """
1204 Add a profile to the __buffer_spc and increase in one the __profileIndex
1331 Add a profile to the __buffer_spc and increase in one the __profileIndex
1205
1332
1206 """
1333 """
1207
1334
1208 self.__buffer_spc.append(data_spc)
1335 self.__buffer_spc.append(data_spc)
1209
1336
1210 if data_cspc is None:
1337 if data_cspc is None:
1211 self.__buffer_cspc = None
1338 self.__buffer_cspc = None
1212 else:
1339 else:
1213 self.__buffer_cspc.append(data_cspc)
1340 self.__buffer_cspc.append(data_cspc)
1214
1341
1215 if data_dc is None:
1342 if data_dc is None:
1216 self.__buffer_dc = None
1343 self.__buffer_dc = None
1217 else:
1344 else:
1218 self.__buffer_dc += data_dc
1345 self.__buffer_dc += data_dc
1219
1346
1220 self.__profIndex += 1
1347 self.__profIndex += 1
1221
1348
1222 return
1349 return
1223
1350
1224 def hildebrand_sekhon_Integration(self,sortdata,navg, factor):
1351 def hildebrand_sekhon_Integration(self,sortdata,navg, factor):
1225 #data debe estar ordenado
1352 #data debe estar ordenado
1226 #sortdata = numpy.sort(data, axis=None)
1353 #sortdata = numpy.sort(data, axis=None)
1227 #sortID=data.argsort()
1354 #sortID=data.argsort()
1228 lenOfData = len(sortdata)
1355 lenOfData = len(sortdata)
1229 nums_min = lenOfData*factor
1356 nums_min = lenOfData*factor
1230 if nums_min <= 5:
1357 if nums_min <= 5:
1231 nums_min = 5
1358 nums_min = 5
1232 sump = 0.
1359 sump = 0.
1233 sumq = 0.
1360 sumq = 0.
1234 j = 0
1361 j = 0
1235 cont = 1
1362 cont = 1
1236 while((cont == 1)and(j < lenOfData)):
1363 while((cont == 1)and(j < lenOfData)):
1237 sump += sortdata[j]
1364 sump += sortdata[j]
1238 sumq += sortdata[j]**2
1365 sumq += sortdata[j]**2
1239 if j > nums_min:
1366 if j > nums_min:
1240 rtest = float(j)/(j-1) + 1.0/navg
1367 rtest = float(j)/(j-1) + 1.0/navg
1241 if ((sumq*j) > (rtest*sump**2)):
1368 if ((sumq*j) > (rtest*sump**2)):
1242 j = j - 1
1369 j = j - 1
1243 sump = sump - sortdata[j]
1370 sump = sump - sortdata[j]
1244 sumq = sumq - sortdata[j]**2
1371 sumq = sumq - sortdata[j]**2
1245 cont = 0
1372 cont = 0
1246 j += 1
1373 j += 1
1247 #lnoise = sump / j
1374 #lnoise = sump / j
1248 #print("H S done")
1375 #print("H S done")
1249 #return j,sortID
1376 #return j,sortID
1250 return j
1377 return j
1251
1378
1252
1379
1253 def pushData(self):
1380 def pushData(self):
1254 """
1381 """
1255 Return the sum of the last profiles and the profiles used in the sum.
1382 Return the sum of the last profiles and the profiles used in the sum.
1256
1383
1257 Affected:
1384 Affected:
1258
1385
1259 self.__profileIndex
1386 self.__profileIndex
1260
1387
1261 """
1388 """
1262 bufferH=None
1389 bufferH=None
1263 buffer=None
1390 buffer=None
1264 buffer1=None
1391 buffer1=None
1265 buffer_cspc=None
1392 buffer_cspc=None
1266 self.__buffer_spc=numpy.array(self.__buffer_spc)
1393 self.__buffer_spc=numpy.array(self.__buffer_spc)
1267 try:
1394 try:
1268 self.__buffer_cspc=numpy.array(self.__buffer_cspc)
1395 self.__buffer_cspc=numpy.array(self.__buffer_cspc)
1269 except :
1396 except :
1270 #print("No cpsc",e)
1397 #print("No cpsc",e)
1271 pass
1398 pass
1272 #print("FREQ_DC",self.__buffer_spc.shape,self.__buffer_cspc.shape)
1399 #print("FREQ_DC",self.__buffer_spc.shape,self.__buffer_cspc.shape)
1273
1400
1274 freq_dc = int(self.__buffer_spc.shape[2] / 2)
1401 freq_dc = int(self.__buffer_spc.shape[2] / 2)
1275 #print("FREQ_DC",freq_dc,self.__buffer_spc.shape,self.nHeights)
1402 #print("FREQ_DC",freq_dc,self.__buffer_spc.shape,self.nHeights)
1276
1403
1277 self.dataOutliers = numpy.zeros((self.nChannels,self.nHeights)) # --> almacen de outliers
1404 self.dataOutliers = numpy.zeros((self.nChannels,self.nHeights)) # --> almacen de outliers
1278
1405
1279 for k in range(self.minHei_ind,self.maxHei_ind):
1406 for k in range(self.minHei_ind,self.maxHei_ind):
1280 try:
1407 try:
1281 buffer_cspc=numpy.copy(self.__buffer_cspc[:,:,:,k])
1408 buffer_cspc=numpy.copy(self.__buffer_cspc[:,:,:,k])
1282 except:
1409 except:
1283 #print("No cpsc",e)
1410 #print("No cpsc",e)
1284 pass
1411 pass
1285 outliers_IDs_cspc=[]
1412 outliers_IDs_cspc=[]
1286 cspc_outliers_exist=False
1413 cspc_outliers_exist=False
1287 for i in range(self.nChannels):#dataOut.nChannels):
1414 for i in range(self.nChannels):#dataOut.nChannels):
1288
1415
1289 buffer1=numpy.copy(self.__buffer_spc[:,i,:,k])
1416 buffer1=numpy.copy(self.__buffer_spc[:,i,:,k])
1290 indexes=[]
1417 indexes=[]
1291 #sortIDs=[]
1418 #sortIDs=[]
1292 outliers_IDs=[]
1419 outliers_IDs=[]
1293
1420
1294 for j in range(self.nProfiles): #frecuencias en el tiempo
1421 for j in range(self.nProfiles): #frecuencias en el tiempo
1295 # if i==0 and j==freq_dc: #NOT CONSIDERING DC PROFILE AT CHANNEL 0
1422 # if i==0 and j==freq_dc: #NOT CONSIDERING DC PROFILE AT CHANNEL 0
1296 # continue
1423 # continue
1297 # if i==1 and j==0: #NOT CONSIDERING DC PROFILE AT CHANNEL 1
1424 # if i==1 and j==0: #NOT CONSIDERING DC PROFILE AT CHANNEL 1
1298 # continue
1425 # continue
1299 buffer=buffer1[:,j]
1426 buffer=buffer1[:,j]
1300 sortdata = numpy.sort(buffer, axis=None)
1427 sortdata = numpy.sort(buffer, axis=None)
1301
1428
1302 sortID=buffer.argsort()
1429 sortID=buffer.argsort()
1303 index = _noise.hildebrand_sekhon2(sortdata,self.navg)
1430 index = _noise.hildebrand_sekhon2(sortdata,self.navg)
1304
1431
1305 #index,sortID=self.hildebrand_sekhon_Integration(buffer,1,self.factor)
1432 #index,sortID=self.hildebrand_sekhon_Integration(buffer,1,self.factor)
1306
1433
1307 # fig,ax = plt.subplots()
1434 # fig,ax = plt.subplots()
1308 # ax.set_title(str(k)+" "+str(j))
1435 # ax.set_title(str(k)+" "+str(j))
1309 # x=range(len(sortdata))
1436 # x=range(len(sortdata))
1310 # ax.scatter(x,sortdata)
1437 # ax.scatter(x,sortdata)
1311 # ax.axvline(index)
1438 # ax.axvline(index)
1312 # plt.show()
1439 # plt.show()
1313
1440
1314 indexes.append(index)
1441 indexes.append(index)
1315 #sortIDs.append(sortID)
1442 #sortIDs.append(sortID)
1316 outliers_IDs=numpy.append(outliers_IDs,sortID[index:])
1443 outliers_IDs=numpy.append(outliers_IDs,sortID[index:])
1317
1444
1318 #print("Outliers: ",outliers_IDs)
1445 #print("Outliers: ",outliers_IDs)
1319 outliers_IDs=numpy.array(outliers_IDs)
1446 outliers_IDs=numpy.array(outliers_IDs)
1320 outliers_IDs=outliers_IDs.ravel()
1447 outliers_IDs=outliers_IDs.ravel()
1321 outliers_IDs=numpy.unique(outliers_IDs)
1448 outliers_IDs=numpy.unique(outliers_IDs)
1322 outliers_IDs=outliers_IDs.astype(numpy.dtype('int64'))
1449 outliers_IDs=outliers_IDs.astype(numpy.dtype('int64'))
1323 indexes=numpy.array(indexes)
1450 indexes=numpy.array(indexes)
1324 indexmin=numpy.min(indexes)
1451 indexmin=numpy.min(indexes)
1325
1452
1326
1453
1327 #print(indexmin,buffer1.shape[0], k)
1454 #print(indexmin,buffer1.shape[0], k)
1328
1455
1329 # fig,ax = plt.subplots()
1456 # fig,ax = plt.subplots()
1330 # ax.plot(sortdata)
1457 # ax.plot(sortdata)
1331 # ax2 = ax.twinx()
1458 # ax2 = ax.twinx()
1332 # x=range(len(indexes))
1459 # x=range(len(indexes))
1333 # #plt.scatter(x,indexes)
1460 # #plt.scatter(x,indexes)
1334 # ax2.scatter(x,indexes)
1461 # ax2.scatter(x,indexes)
1335 # plt.show()
1462 # plt.show()
1336
1463
1337 if indexmin != buffer1.shape[0]:
1464 if indexmin != buffer1.shape[0]:
1338 if self.nChannels > 1:
1465 if self.nChannels > 1:
1339 cspc_outliers_exist= True
1466 cspc_outliers_exist= True
1340
1467
1341 lt=outliers_IDs
1468 lt=outliers_IDs
1342 #avg=numpy.mean(buffer1[[t for t in range(buffer1.shape[0]) if t not in lt],:],axis=0)
1469 #avg=numpy.mean(buffer1[[t for t in range(buffer1.shape[0]) if t not in lt],:],axis=0)
1343
1470
1344 for p in list(outliers_IDs):
1471 for p in list(outliers_IDs):
1345 #buffer1[p,:]=avg
1472 #buffer1[p,:]=avg
1346 buffer1[p,:] = numpy.NaN
1473 buffer1[p,:] = numpy.NaN
1347
1474
1348 self.dataOutliers[i,k] = len(outliers_IDs)
1475 self.dataOutliers[i,k] = len(outliers_IDs)
1349
1476
1350 self.__buffer_spc[:,i,:,k]=numpy.copy(buffer1)
1477 self.__buffer_spc[:,i,:,k]=numpy.copy(buffer1)
1351
1478
1352 outliers_IDs_cspc=numpy.append(outliers_IDs_cspc,outliers_IDs)
1479 outliers_IDs_cspc=numpy.append(outliers_IDs_cspc,outliers_IDs)
1353
1480
1354
1481
1355
1482
1356 outliers_IDs_cspc=outliers_IDs_cspc.astype(numpy.dtype('int64'))
1483 outliers_IDs_cspc=outliers_IDs_cspc.astype(numpy.dtype('int64'))
1357 if cspc_outliers_exist :
1484 if cspc_outliers_exist :
1358
1485
1359 lt=outliers_IDs_cspc
1486 lt=outliers_IDs_cspc
1360
1487
1361 #avg=numpy.mean(buffer_cspc[[t for t in range(buffer_cspc.shape[0]) if t not in lt],:],axis=0)
1488 #avg=numpy.mean(buffer_cspc[[t for t in range(buffer_cspc.shape[0]) if t not in lt],:],axis=0)
1362 for p in list(outliers_IDs_cspc):
1489 for p in list(outliers_IDs_cspc):
1363 #buffer_cspc[p,:]=avg
1490 #buffer_cspc[p,:]=avg
1364 buffer_cspc[p,:] = numpy.NaN
1491 buffer_cspc[p,:] = numpy.NaN
1365
1492
1366 try:
1493 try:
1367 self.__buffer_cspc[:,:,:,k]=numpy.copy(buffer_cspc)
1494 self.__buffer_cspc[:,:,:,k]=numpy.copy(buffer_cspc)
1368 except:
1495 except:
1369 #print("No cpsc",e)
1496 #print("No cpsc",e)
1370 pass
1497 pass
1371 #else:
1498 #else:
1372 #break
1499 #break
1373
1500
1374
1501
1375
1502
1376 nOutliers = len(outliers_IDs)
1503 nOutliers = len(outliers_IDs)
1377 #print("Outliers n: ",self.dataOutliers,nOutliers)
1504 #print("Outliers n: ",self.dataOutliers,nOutliers)
1378 buffer=None
1505 buffer=None
1379 bufferH=None
1506 bufferH=None
1380 buffer1=None
1507 buffer1=None
1381 buffer_cspc=None
1508 buffer_cspc=None
1382
1509
1383
1510
1384 buffer=None
1511 buffer=None
1385
1512
1386 #data_spc = numpy.sum(self.__buffer_spc,axis=0)
1513 #data_spc = numpy.sum(self.__buffer_spc,axis=0)
1387 data_spc = numpy.nansum(self.__buffer_spc,axis=0)
1514 data_spc = numpy.nansum(self.__buffer_spc,axis=0)
1388 try:
1515 try:
1389 #data_cspc = numpy.sum(self.__buffer_cspc,axis=0)
1516 #data_cspc = numpy.sum(self.__buffer_cspc,axis=0)
1390 data_cspc = numpy.nansum(self.__buffer_cspc,axis=0)
1517 data_cspc = numpy.nansum(self.__buffer_cspc,axis=0)
1391 except:
1518 except:
1392 #print("No cpsc",e)
1519 #print("No cpsc",e)
1393 pass
1520 pass
1394
1521
1395
1522
1396 data_dc = self.__buffer_dc
1523 data_dc = self.__buffer_dc
1397 #(CH, HEIGH)
1524 #(CH, HEIGH)
1398 self.maxProfilesInt = self.__profIndex
1525 self.maxProfilesInt = self.__profIndex
1399 n = self.__profIndex - self.dataOutliers
1526 n = self.__profIndex - self.dataOutliers # n becomes a matrix
1400
1527
1401 self.__buffer_spc = []
1528 self.__buffer_spc = []
1402 self.__buffer_cspc = []
1529 self.__buffer_cspc = []
1403 self.__buffer_dc = 0
1530 self.__buffer_dc = 0
1404 self.__profIndex = 0
1531 self.__profIndex = 0
1405
1532
1406 return data_spc, data_cspc, data_dc, n
1533 return data_spc, data_cspc, data_dc, n
1407
1534
1408 def byProfiles(self, *args):
1535 def byProfiles(self, *args):
1409
1536
1410 self.__dataReady = False
1537 self.__dataReady = False
1411 avgdata_spc = None
1538 avgdata_spc = None
1412 avgdata_cspc = None
1539 avgdata_cspc = None
1413 avgdata_dc = None
1540 avgdata_dc = None
1414
1541
1415 self.putData(*args)
1542 self.putData(*args)
1416
1543
1417 if self.__profIndex == self.n:
1544 if self.__profIndex == self.n:
1418
1545
1419 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1546 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1420 self.n_ints = n
1547 self.n_ints = n
1421 self.__dataReady = True
1548 self.__dataReady = True
1422
1549
1423 return avgdata_spc, avgdata_cspc, avgdata_dc
1550 return avgdata_spc, avgdata_cspc, avgdata_dc
1424
1551
1425 def byTime(self, datatime, *args):
1552 def byTime(self, datatime, *args):
1426
1553
1427 self.__dataReady = False
1554 self.__dataReady = False
1428 avgdata_spc = None
1555 avgdata_spc = None
1429 avgdata_cspc = None
1556 avgdata_cspc = None
1430 avgdata_dc = None
1557 avgdata_dc = None
1431
1558
1432 self.putData(*args)
1559 self.putData(*args)
1433
1560
1434 if (datatime - self.__initime) >= self.__integrationtime:
1561 if (datatime - self.__initime) >= self.__integrationtime:
1435 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1562 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1436 self.n_ints = n
1563 self.n_ints = n
1437 self.__dataReady = True
1564 self.__dataReady = True
1438
1565
1439 return avgdata_spc, avgdata_cspc, avgdata_dc
1566 return avgdata_spc, avgdata_cspc, avgdata_dc
1440
1567
1441 def integrate(self, datatime, *args):
1568 def integrate(self, datatime, *args):
1442
1569
1443 if self.__profIndex == 0:
1570 if self.__profIndex == 0:
1444 self.__initime = datatime
1571 self.__initime = datatime
1445
1572
1446 if self.__byTime:
1573 if self.__byTime:
1447 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1574 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1448 datatime, *args)
1575 datatime, *args)
1449 else:
1576 else:
1450 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1577 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1451
1578
1452 if not self.__dataReady:
1579 if not self.__dataReady:
1453 return None, None, None, None
1580 return None, None, None, None
1454
1581
1455 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1582 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1456
1583
1457 def run(self, dataOut, n=None, DPL = None,timeInterval=None, overlapping=False, minHei=None, maxHei=None, avg=1, factor=0.75):
1584 def run(self, dataOut, n=None, DPL = None,timeInterval=None, overlapping=False, minHei=None, maxHei=None, avg=1, factor=0.75):
1458 self.dataOut = dataOut.copy()
1585 self.dataOut = dataOut
1459 if n == 1:
1586 if n == 1:
1460 return self.dataOut
1587 return self.dataOut
1461
1588
1462 self.dataOut.flagNoData = True
1589
1463 if self.dataOut.nChannels == 1:
1590 if self.dataOut.nChannels == 1:
1464 self.dataOut.data_cspc = None #si es un solo canal no vale la pena acumular DATOS
1591 self.dataOut.data_cspc = None #si es un solo canal no vale la pena acumular DATOS
1465 #print(self.dataOut.data_spc.shape, self.dataOut.data_cspc)
1592 #print(self.dataOut.data_spc.shape, self.dataOut.data_cspc)
1466 if not self.isConfig:
1593 if not self.isConfig:
1467 self.setup(self.dataOut, n, timeInterval, overlapping,DPL ,minHei, maxHei, avg, factor)
1594 self.setup(self.dataOut, n, timeInterval, overlapping,DPL ,minHei, maxHei, avg, factor)
1468 self.isConfig = True
1595 self.isConfig = True
1469
1596
1470 if not self.ByLags:
1597 if not self.ByLags:
1471 self.nProfiles=self.dataOut.nProfiles
1598 self.nProfiles=self.dataOut.nProfiles
1472 self.nChannels=self.dataOut.nChannels
1599 self.nChannels=self.dataOut.nChannels
1473 self.nHeights=self.dataOut.nHeights
1600 self.nHeights=self.dataOut.nHeights
1474 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(self.dataOut.utctime,
1601 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(self.dataOut.utctime,
1475 self.dataOut.data_spc,
1602 self.dataOut.data_spc,
1476 self.dataOut.data_cspc,
1603 self.dataOut.data_cspc,
1477 self.dataOut.data_dc)
1604 self.dataOut.data_dc)
1478 else:
1605 else:
1479 self.nProfiles=self.dataOut.nProfiles
1606 self.nProfiles=self.dataOut.nProfiles
1480 self.nChannels=self.dataOut.nChannels
1607 self.nChannels=self.dataOut.nChannels
1481 self.nHeights=self.dataOut.nHeights
1608 self.nHeights=self.dataOut.nHeights
1482 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(self.dataOut.utctime,
1609 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(self.dataOut.utctime,
1483 self.dataOut.dataLag_spc,
1610 self.dataOut.dataLag_spc,
1484 self.dataOut.dataLag_cspc,
1611 self.dataOut.dataLag_cspc,
1485 self.dataOut.dataLag_dc)
1612 self.dataOut.dataLag_dc)
1486
1613 self.dataOut.flagNoData = True
1487 if self.__dataReady:
1614 if self.__dataReady:
1488
1615
1489 if not self.ByLags:
1616 if not self.ByLags:
1490 if self.nChannels == 1:
1617 if self.nChannels == 1:
1491 #print("f int", avgdata_spc.shape)
1618 #print("f int", avgdata_spc.shape)
1492 self.dataOut.data_spc = avgdata_spc
1619 self.dataOut.data_spc = avgdata_spc
1493 self.dataOut.data_cspc = avgdata_spc
1620 self.dataOut.data_cspc = avgdata_spc
1494 else:
1621 else:
1495 self.dataOut.data_spc = numpy.squeeze(avgdata_spc)
1622 self.dataOut.data_spc = numpy.squeeze(avgdata_spc)
1496 self.dataOut.data_cspc = numpy.squeeze(avgdata_cspc)
1623 self.dataOut.data_cspc = numpy.squeeze(avgdata_cspc)
1497 self.dataOut.data_dc = avgdata_dc
1624 self.dataOut.data_dc = avgdata_dc
1498 self.dataOut.data_outlier = self.dataOutliers
1625 self.dataOut.data_outlier = self.dataOutliers
1499
1626
1500 else:
1627 else:
1501 self.dataOut.dataLag_spc = avgdata_spc
1628 self.dataOut.dataLag_spc = avgdata_spc
1502 self.dataOut.dataLag_cspc = avgdata_cspc
1629 self.dataOut.dataLag_cspc = avgdata_cspc
1503 self.dataOut.dataLag_dc = avgdata_dc
1630 self.dataOut.dataLag_dc = avgdata_dc
1504
1631
1505 self.dataOut.data_spc=self.dataOut.dataLag_spc[:,:,:,self.dataOut.LagPlot]
1632 self.dataOut.data_spc=self.dataOut.dataLag_spc[:,:,:,self.dataOut.LagPlot]
1506 self.dataOut.data_cspc=self.dataOut.dataLag_cspc[:,:,:,self.dataOut.LagPlot]
1633 self.dataOut.data_cspc=self.dataOut.dataLag_cspc[:,:,:,self.dataOut.LagPlot]
1507 self.dataOut.data_dc=self.dataOut.dataLag_dc[:,:,self.dataOut.LagPlot]
1634 self.dataOut.data_dc=self.dataOut.dataLag_dc[:,:,self.dataOut.LagPlot]
1508
1635
1509
1636
1510 self.dataOut.nIncohInt *= self.n_ints
1637 self.dataOut.nIncohInt *= self.n_ints
1511 self.dataOut.max_nIncohInt = self.maxProfilesInt
1638 self.dataOut.max_nIncohInt = self.maxProfilesInt
1512 #print(self.dataOut.max_nIncohInt)
1639 #print(self.dataOut.max_nIncohInt)
1513 self.dataOut.utctime = avgdatatime
1640 self.dataOut.utctime = avgdatatime
1514 self.dataOut.flagNoData = False
1641 self.dataOut.flagNoData = False
1515 #print("Faraday Integration DONE...")
1642 #print("Faraday Integration DONE...")
1643 #print(self.dataOut.flagNoData)
1516 return self.dataOut
1644 return self.dataOut
1517
1645
1518 class removeInterference(Operation):
1646 class removeInterference(Operation):
1519
1647
1520 def removeInterference2(self):
1648 def removeInterference2(self):
1521
1649
1522 cspc = self.dataOut.data_cspc
1650 cspc = self.dataOut.data_cspc
1523 spc = self.dataOut.data_spc
1651 spc = self.dataOut.data_spc
1524 Heights = numpy.arange(cspc.shape[2])
1652 Heights = numpy.arange(cspc.shape[2])
1525 realCspc = numpy.abs(cspc)
1653 realCspc = numpy.abs(cspc)
1526
1654
1527 for i in range(cspc.shape[0]):
1655 for i in range(cspc.shape[0]):
1528 LinePower= numpy.sum(realCspc[i], axis=0)
1656 LinePower= numpy.sum(realCspc[i], axis=0)
1529 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
1657 Threshold = numpy.amax(LinePower)-numpy.sort(LinePower)[len(Heights)-int(len(Heights)*0.1)]
1530 SelectedHeights = Heights[ numpy.where( LinePower < Threshold ) ]
1658 SelectedHeights = Heights[ numpy.where( LinePower < Threshold ) ]
1531 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
1659 InterferenceSum = numpy.sum( realCspc[i,:,SelectedHeights], axis=0 )
1532 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
1660 InterferenceThresholdMin = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.98)]
1533 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
1661 InterferenceThresholdMax = numpy.sort(InterferenceSum)[int(len(InterferenceSum)*0.99)]
1534
1662
1535
1663
1536 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
1664 InterferenceRange = numpy.where( ([InterferenceSum > InterferenceThresholdMin]))# , InterferenceSum < InterferenceThresholdMax]) )
1537 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
1665 #InterferenceRange = numpy.where( ([InterferenceRange < InterferenceThresholdMax]))
1538 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
1666 if len(InterferenceRange)<int(cspc.shape[1]*0.3):
1539 cspc[i,InterferenceRange,:] = numpy.NaN
1667 cspc[i,InterferenceRange,:] = numpy.NaN
1540
1668
1541 self.dataOut.data_cspc = cspc
1669 self.dataOut.data_cspc = cspc
1542
1670
1543 def removeInterference(self, interf = 2, hei_interf = None, nhei_interf = None, offhei_interf = None):
1671 def removeInterference(self, interf = 2, hei_interf = None, nhei_interf = None, offhei_interf = None):
1544
1672
1545 jspectra = self.dataOut.data_spc
1673 jspectra = self.dataOut.data_spc
1546 jcspectra = self.dataOut.data_cspc
1674 jcspectra = self.dataOut.data_cspc
1547 jnoise = self.dataOut.getNoise()
1675 jnoise = self.dataOut.getNoise()
1548 num_incoh = self.dataOut.nIncohInt
1676 num_incoh = self.dataOut.nIncohInt
1549
1677
1550 num_channel = jspectra.shape[0]
1678 num_channel = jspectra.shape[0]
1551 num_prof = jspectra.shape[1]
1679 num_prof = jspectra.shape[1]
1552 num_hei = jspectra.shape[2]
1680 num_hei = jspectra.shape[2]
1553
1681
1554 # hei_interf
1682 # hei_interf
1555 if hei_interf is None:
1683 if hei_interf is None:
1556 count_hei = int(num_hei / 2)
1684 count_hei = int(num_hei / 2)
1557 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
1685 hei_interf = numpy.asmatrix(list(range(count_hei))) + num_hei - count_hei
1558 hei_interf = numpy.asarray(hei_interf)[0]
1686 hei_interf = numpy.asarray(hei_interf)[0]
1559 # nhei_interf
1687 # nhei_interf
1560 if (nhei_interf == None):
1688 if (nhei_interf == None):
1561 nhei_interf = 5
1689 nhei_interf = 5
1562 if (nhei_interf < 1):
1690 if (nhei_interf < 1):
1563 nhei_interf = 1
1691 nhei_interf = 1
1564 if (nhei_interf > count_hei):
1692 if (nhei_interf > count_hei):
1565 nhei_interf = count_hei
1693 nhei_interf = count_hei
1566 if (offhei_interf == None):
1694 if (offhei_interf == None):
1567 offhei_interf = 0
1695 offhei_interf = 0
1568
1696
1569 ind_hei = list(range(num_hei))
1697 ind_hei = list(range(num_hei))
1570 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
1698 # mask_prof = numpy.asarray(range(num_prof - 2)) + 1
1571 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
1699 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1
1572 mask_prof = numpy.asarray(list(range(num_prof)))
1700 mask_prof = numpy.asarray(list(range(num_prof)))
1573 num_mask_prof = mask_prof.size
1701 num_mask_prof = mask_prof.size
1574 comp_mask_prof = [0, num_prof / 2]
1702 comp_mask_prof = [0, num_prof / 2]
1575
1703
1576 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
1704 # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal
1577 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
1705 if (jnoise.size < num_channel or numpy.isnan(jnoise).any()):
1578 jnoise = numpy.nan
1706 jnoise = numpy.nan
1579 noise_exist = jnoise[0] < numpy.Inf
1707 noise_exist = jnoise[0] < numpy.Inf
1580
1708
1581 # Subrutina de Remocion de la Interferencia
1709 # Subrutina de Remocion de la Interferencia
1582 for ich in range(num_channel):
1710 for ich in range(num_channel):
1583 # Se ordena los espectros segun su potencia (menor a mayor)
1711 # Se ordena los espectros segun su potencia (menor a mayor)
1584 power = jspectra[ich, mask_prof, :]
1712 power = jspectra[ich, mask_prof, :]
1585 power = power[:, hei_interf]
1713 power = power[:, hei_interf]
1586 power = power.sum(axis=0)
1714 power = power.sum(axis=0)
1587 psort = power.ravel().argsort()
1715 psort = power.ravel().argsort()
1588
1716
1589 # Se estima la interferencia promedio en los Espectros de Potencia empleando
1717 # Se estima la interferencia promedio en los Espectros de Potencia empleando
1590 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
1718 junkspc_interf = jspectra[ich, :, hei_interf[psort[list(range(
1591 offhei_interf, nhei_interf + offhei_interf))]]]
1719 offhei_interf, nhei_interf + offhei_interf))]]]
1592
1720
1593 if noise_exist:
1721 if noise_exist:
1594 # tmp_noise = jnoise[ich] / num_prof
1722 # tmp_noise = jnoise[ich] / num_prof
1595 tmp_noise = jnoise[ich]
1723 tmp_noise = jnoise[ich]
1596 junkspc_interf = junkspc_interf - tmp_noise
1724 junkspc_interf = junkspc_interf - tmp_noise
1597 #junkspc_interf[:,comp_mask_prof] = 0
1725 #junkspc_interf[:,comp_mask_prof] = 0
1598
1726
1599 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
1727 jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf
1600 jspc_interf = jspc_interf.transpose()
1728 jspc_interf = jspc_interf.transpose()
1601 # Calculando el espectro de interferencia promedio
1729 # Calculando el espectro de interferencia promedio
1602 noiseid = numpy.where(
1730 noiseid = numpy.where(
1603 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
1731 jspc_interf <= tmp_noise / numpy.sqrt(num_incoh))
1604 noiseid = noiseid[0]
1732 noiseid = noiseid[0]
1605 cnoiseid = noiseid.size
1733 cnoiseid = noiseid.size
1606 interfid = numpy.where(
1734 interfid = numpy.where(
1607 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
1735 jspc_interf > tmp_noise / numpy.sqrt(num_incoh))
1608 interfid = interfid[0]
1736 interfid = interfid[0]
1609 cinterfid = interfid.size
1737 cinterfid = interfid.size
1610
1738
1611 if (cnoiseid > 0):
1739 if (cnoiseid > 0):
1612 jspc_interf[noiseid] = 0
1740 jspc_interf[noiseid] = 0
1613
1741
1614 # Expandiendo los perfiles a limpiar
1742 # Expandiendo los perfiles a limpiar
1615 if (cinterfid > 0):
1743 if (cinterfid > 0):
1616 new_interfid = (
1744 new_interfid = (
1617 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
1745 numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof
1618 new_interfid = numpy.asarray(new_interfid)
1746 new_interfid = numpy.asarray(new_interfid)
1619 new_interfid = {x for x in new_interfid}
1747 new_interfid = {x for x in new_interfid}
1620 new_interfid = numpy.array(list(new_interfid))
1748 new_interfid = numpy.array(list(new_interfid))
1621 new_cinterfid = new_interfid.size
1749 new_cinterfid = new_interfid.size
1622 else:
1750 else:
1623 new_cinterfid = 0
1751 new_cinterfid = 0
1624
1752
1625 for ip in range(new_cinterfid):
1753 for ip in range(new_cinterfid):
1626 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
1754 ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort()
1627 jspc_interf[new_interfid[ip]
1755 jspc_interf[new_interfid[ip]
1628 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
1756 ] = junkspc_interf[ind[nhei_interf // 2], new_interfid[ip]]
1629
1757
1630 jspectra[ich, :, ind_hei] = jspectra[ich, :,
1758 jspectra[ich, :, ind_hei] = jspectra[ich, :,
1631 ind_hei] - jspc_interf # Corregir indices
1759 ind_hei] - jspc_interf # Corregir indices
1632
1760
1633 # Removiendo la interferencia del punto de mayor interferencia
1761 # Removiendo la interferencia del punto de mayor interferencia
1634 ListAux = jspc_interf[mask_prof].tolist()
1762 ListAux = jspc_interf[mask_prof].tolist()
1635 maxid = ListAux.index(max(ListAux))
1763 maxid = ListAux.index(max(ListAux))
1636
1764
1637 if cinterfid > 0:
1765 if cinterfid > 0:
1638 for ip in range(cinterfid * (interf == 2) - 1):
1766 for ip in range(cinterfid * (interf == 2) - 1):
1639 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
1767 ind = (jspectra[ich, interfid[ip], :] < tmp_noise *
1640 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
1768 (1 + 1 / numpy.sqrt(num_incoh))).nonzero()
1641 cind = len(ind)
1769 cind = len(ind)
1642
1770
1643 if (cind > 0):
1771 if (cind > 0):
1644 jspectra[ich, interfid[ip], ind] = tmp_noise * \
1772 jspectra[ich, interfid[ip], ind] = tmp_noise * \
1645 (1 + (numpy.random.uniform(cind) - 0.5) /
1773 (1 + (numpy.random.uniform(cind) - 0.5) /
1646 numpy.sqrt(num_incoh))
1774 numpy.sqrt(num_incoh))
1647
1775
1648 ind = numpy.array([-2, -1, 1, 2])
1776 ind = numpy.array([-2, -1, 1, 2])
1649 xx = numpy.zeros([4, 4])
1777 xx = numpy.zeros([4, 4])
1650
1778
1651 for id1 in range(4):
1779 for id1 in range(4):
1652 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1780 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1653
1781
1654 xx_inv = numpy.linalg.inv(xx)
1782 xx_inv = numpy.linalg.inv(xx)
1655 xx = xx_inv[:, 0]
1783 xx = xx_inv[:, 0]
1656 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1784 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1657 yy = jspectra[ich, mask_prof[ind], :]
1785 yy = jspectra[ich, mask_prof[ind], :]
1658 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
1786 jspectra[ich, mask_prof[maxid], :] = numpy.dot(
1659 yy.transpose(), xx)
1787 yy.transpose(), xx)
1660
1788
1661 indAux = (jspectra[ich, :, :] < tmp_noise *
1789 indAux = (jspectra[ich, :, :] < tmp_noise *
1662 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
1790 (1 - 1 / numpy.sqrt(num_incoh))).nonzero()
1663 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
1791 jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \
1664 (1 - 1 / numpy.sqrt(num_incoh))
1792 (1 - 1 / numpy.sqrt(num_incoh))
1665
1793
1666 # Remocion de Interferencia en el Cross Spectra
1794 # Remocion de Interferencia en el Cross Spectra
1667 if jcspectra is None:
1795 if jcspectra is None:
1668 return jspectra, jcspectra
1796 return jspectra, jcspectra
1669 num_pairs = int(jcspectra.size / (num_prof * num_hei))
1797 num_pairs = int(jcspectra.size / (num_prof * num_hei))
1670 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
1798 jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei)
1671
1799
1672 for ip in range(num_pairs):
1800 for ip in range(num_pairs):
1673
1801
1674 #-------------------------------------------
1802 #-------------------------------------------
1675
1803
1676 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
1804 cspower = numpy.abs(jcspectra[ip, mask_prof, :])
1677 cspower = cspower[:, hei_interf]
1805 cspower = cspower[:, hei_interf]
1678 cspower = cspower.sum(axis=0)
1806 cspower = cspower.sum(axis=0)
1679
1807
1680 cspsort = cspower.ravel().argsort()
1808 cspsort = cspower.ravel().argsort()
1681 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
1809 junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[list(range(
1682 offhei_interf, nhei_interf + offhei_interf))]]]
1810 offhei_interf, nhei_interf + offhei_interf))]]]
1683 junkcspc_interf = junkcspc_interf.transpose()
1811 junkcspc_interf = junkcspc_interf.transpose()
1684 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
1812 jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf
1685
1813
1686 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
1814 ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort()
1687
1815
1688 median_real = int(numpy.median(numpy.real(
1816 median_real = int(numpy.median(numpy.real(
1689 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1817 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1690 median_imag = int(numpy.median(numpy.imag(
1818 median_imag = int(numpy.median(numpy.imag(
1691 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1819 junkcspc_interf[mask_prof[ind[list(range(3 * num_prof // 4))]], :])))
1692 comp_mask_prof = [int(e) for e in comp_mask_prof]
1820 comp_mask_prof = [int(e) for e in comp_mask_prof]
1693 junkcspc_interf[comp_mask_prof, :] = numpy.complex(
1821 junkcspc_interf[comp_mask_prof, :] = numpy.complex(
1694 median_real, median_imag)
1822 median_real, median_imag)
1695
1823
1696 for iprof in range(num_prof):
1824 for iprof in range(num_prof):
1697 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
1825 ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort()
1698 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
1826 jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf // 2]]
1699
1827
1700 # Removiendo la Interferencia
1828 # Removiendo la Interferencia
1701 jcspectra[ip, :, ind_hei] = jcspectra[ip,
1829 jcspectra[ip, :, ind_hei] = jcspectra[ip,
1702 :, ind_hei] - jcspc_interf
1830 :, ind_hei] - jcspc_interf
1703
1831
1704 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
1832 ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist()
1705 maxid = ListAux.index(max(ListAux))
1833 maxid = ListAux.index(max(ListAux))
1706
1834
1707 ind = numpy.array([-2, -1, 1, 2])
1835 ind = numpy.array([-2, -1, 1, 2])
1708 xx = numpy.zeros([4, 4])
1836 xx = numpy.zeros([4, 4])
1709
1837
1710 for id1 in range(4):
1838 for id1 in range(4):
1711 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1839 xx[:, id1] = ind[id1]**numpy.asarray(list(range(4)))
1712
1840
1713 xx_inv = numpy.linalg.inv(xx)
1841 xx_inv = numpy.linalg.inv(xx)
1714 xx = xx_inv[:, 0]
1842 xx = xx_inv[:, 0]
1715
1843
1716 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1844 ind = (ind + maxid + num_mask_prof) % num_mask_prof
1717 yy = jcspectra[ip, mask_prof[ind], :]
1845 yy = jcspectra[ip, mask_prof[ind], :]
1718 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
1846 jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx)
1719
1847
1720 # Guardar Resultados
1848 # Guardar Resultados
1721 self.dataOut.data_spc = jspectra
1849 self.dataOut.data_spc = jspectra
1722 self.dataOut.data_cspc = jcspectra
1850 self.dataOut.data_cspc = jcspectra
1723
1851
1724 return 1
1852 return 1
1725
1853
1726 def run(self, dataOut, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None, mode=1):
1854 def run(self, dataOut, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None, mode=1):
1727
1855
1728 self.dataOut = dataOut
1856 self.dataOut = dataOut
1729
1857
1730 if mode == 1:
1858 if mode == 1:
1731 self.removeInterference(interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None)
1859 self.removeInterference(interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None)
1732 elif mode == 2:
1860 elif mode == 2:
1733 self.removeInterference2()
1861 self.removeInterference2()
1734
1862
1735 return self.dataOut
1863 return self.dataOut
1736
1864
1737
1865
1738 class IncohInt(Operation):
1866 class IncohInt(Operation):
1739
1867
1740 __profIndex = 0
1868 __profIndex = 0
1741 __withOverapping = False
1869 __withOverapping = False
1742
1870
1743 __byTime = False
1871 __byTime = False
1744 __initime = None
1872 __initime = None
1745 __lastdatatime = None
1873 __lastdatatime = None
1746 __integrationtime = None
1874 __integrationtime = None
1747
1875
1748 __buffer_spc = None
1876 __buffer_spc = None
1749 __buffer_cspc = None
1877 __buffer_cspc = None
1750 __buffer_dc = None
1878 __buffer_dc = None
1751
1879
1752 __dataReady = False
1880 __dataReady = False
1753
1881
1754 __timeInterval = None
1882 __timeInterval = None
1755 incohInt = 0
1883 incohInt = 0
1756 nOutliers = 0
1884 nOutliers = 0
1757 n = None
1885 n = None
1758
1886
1759 def __init__(self):
1887 def __init__(self):
1760
1888
1761 Operation.__init__(self)
1889 Operation.__init__(self)
1762
1890
1763 def setup(self, n=None, timeInterval=None, overlapping=False):
1891 def setup(self, n=None, timeInterval=None, overlapping=False):
1764 """
1892 """
1765 Set the parameters of the integration class.
1893 Set the parameters of the integration class.
1766
1894
1767 Inputs:
1895 Inputs:
1768
1896
1769 n : Number of coherent integrations
1897 n : Number of coherent integrations
1770 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1898 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
1771 overlapping :
1899 overlapping :
1772
1900
1773 """
1901 """
1774
1902
1775 self.__initime = None
1903 self.__initime = None
1776 self.__lastdatatime = 0
1904 self.__lastdatatime = 0
1777
1905
1778 self.__buffer_spc = 0
1906 self.__buffer_spc = 0
1779 self.__buffer_cspc = 0
1907 self.__buffer_cspc = 0
1780 self.__buffer_dc = 0
1908 self.__buffer_dc = 0
1781
1909
1782 self.__profIndex = 0
1910 self.__profIndex = 0
1783 self.__dataReady = False
1911 self.__dataReady = False
1784 self.__byTime = False
1912 self.__byTime = False
1785 self.incohInt = 0
1913 self.incohInt = 0
1786 self.nOutliers = 0
1914 self.nOutliers = 0
1787 if n is None and timeInterval is None:
1915 if n is None and timeInterval is None:
1788 raise ValueError("n or timeInterval should be specified ...")
1916 raise ValueError("n or timeInterval should be specified ...")
1789
1917
1790 if n is not None:
1918 if n is not None:
1791 self.n = int(n)
1919 self.n = int(n)
1792 else:
1920 else:
1793
1921
1794 self.__integrationtime = int(timeInterval)
1922 self.__integrationtime = int(timeInterval)
1795 self.n = None
1923 self.n = None
1796 self.__byTime = True
1924 self.__byTime = True
1797
1925
1798 def putData(self, data_spc, data_cspc, data_dc):
1926 def putData(self, data_spc, data_cspc, data_dc):
1799 """
1927 """
1800 Add a profile to the __buffer_spc and increase in one the __profileIndex
1928 Add a profile to the __buffer_spc and increase in one the __profileIndex
1801
1929
1802 """
1930 """
1803 if data_spc.all() == numpy.nan :
1931 if data_spc.all() == numpy.nan :
1804 print("nan ")
1932 print("nan ")
1805 return
1933 return
1806 self.__buffer_spc += data_spc
1934 self.__buffer_spc += data_spc
1807
1935
1808 if data_cspc is None:
1936 if data_cspc is None:
1809 self.__buffer_cspc = None
1937 self.__buffer_cspc = None
1810 else:
1938 else:
1811 self.__buffer_cspc += data_cspc
1939 self.__buffer_cspc += data_cspc
1812
1940
1813 if data_dc is None:
1941 if data_dc is None:
1814 self.__buffer_dc = None
1942 self.__buffer_dc = None
1815 else:
1943 else:
1816 self.__buffer_dc += data_dc
1944 self.__buffer_dc += data_dc
1817
1945
1818 self.__profIndex += 1
1946 self.__profIndex += 1
1819
1947
1820 return
1948 return
1821
1949
1822 def pushData(self):
1950 def pushData(self):
1823 """
1951 """
1824 Return the sum of the last profiles and the profiles used in the sum.
1952 Return the sum of the last profiles and the profiles used in the sum.
1825
1953
1826 Affected:
1954 Affected:
1827
1955
1828 self.__profileIndex
1956 self.__profileIndex
1829
1957
1830 """
1958 """
1831
1959
1832 data_spc = self.__buffer_spc
1960 data_spc = self.__buffer_spc
1833 data_cspc = self.__buffer_cspc
1961 data_cspc = self.__buffer_cspc
1834 data_dc = self.__buffer_dc
1962 data_dc = self.__buffer_dc
1835 n = self.__profIndex
1963 n = self.__profIndex
1836
1964
1837 self.__buffer_spc = 0
1965 self.__buffer_spc = 0
1838 self.__buffer_cspc = 0
1966 self.__buffer_cspc = 0
1839 self.__buffer_dc = 0
1967 self.__buffer_dc = 0
1840
1968
1841
1969
1842 return data_spc, data_cspc, data_dc, n
1970 return data_spc, data_cspc, data_dc, n
1843
1971
1844 def byProfiles(self, *args):
1972 def byProfiles(self, *args):
1845
1973
1846 self.__dataReady = False
1974 self.__dataReady = False
1847 avgdata_spc = None
1975 avgdata_spc = None
1848 avgdata_cspc = None
1976 avgdata_cspc = None
1849 avgdata_dc = None
1977 avgdata_dc = None
1850
1978
1851 self.putData(*args)
1979 self.putData(*args)
1852
1980
1853 if self.__profIndex == self.n:
1981 if self.__profIndex == self.n:
1854
1982
1855 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1983 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1856 self.n = n
1984 self.n = n
1857 self.__dataReady = True
1985 self.__dataReady = True
1858
1986
1859 return avgdata_spc, avgdata_cspc, avgdata_dc
1987 return avgdata_spc, avgdata_cspc, avgdata_dc
1860
1988
1861 def byTime(self, datatime, *args):
1989 def byTime(self, datatime, *args):
1862
1990
1863 self.__dataReady = False
1991 self.__dataReady = False
1864 avgdata_spc = None
1992 avgdata_spc = None
1865 avgdata_cspc = None
1993 avgdata_cspc = None
1866 avgdata_dc = None
1994 avgdata_dc = None
1867
1995
1868 self.putData(*args)
1996 self.putData(*args)
1869
1997
1870 if (datatime - self.__initime) >= self.__integrationtime:
1998 if (datatime - self.__initime) >= self.__integrationtime:
1871 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1999 avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData()
1872 self.n = n
2000 self.n = n
1873 self.__dataReady = True
2001 self.__dataReady = True
1874
2002
1875 return avgdata_spc, avgdata_cspc, avgdata_dc
2003 return avgdata_spc, avgdata_cspc, avgdata_dc
1876
2004
1877 def integrate(self, datatime, *args):
2005 def integrate(self, datatime, *args):
1878
2006
1879 if self.__profIndex == 0:
2007 if self.__profIndex == 0:
1880 self.__initime = datatime
2008 self.__initime = datatime
1881
2009
1882 if self.__byTime:
2010 if self.__byTime:
1883 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
2011 avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(
1884 datatime, *args)
2012 datatime, *args)
1885 else:
2013 else:
1886 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
2014 avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args)
1887
2015
1888 if not self.__dataReady:
2016 if not self.__dataReady:
1889 return None, None, None, None
2017 return None, None, None, None
1890
2018
1891 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
2019 return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc
1892
2020
1893 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
2021 def run(self, dataOut, n=None, timeInterval=None, overlapping=False):
1894 if n == 1:
2022 if n == 1:
1895 return dataOut
2023 return dataOut
1896
2024
1897 if dataOut.flagNoData == True:
2025 if dataOut.flagNoData == True:
1898 return dataOut
2026 return dataOut
1899
2027
1900 dataOut.flagNoData = True
2028 dataOut.flagNoData = True
1901
2029
1902 if not self.isConfig:
2030 if not self.isConfig:
1903 self.setup(n, timeInterval, overlapping)
2031 self.setup(n, timeInterval, overlapping)
1904 self.isConfig = True
2032 self.isConfig = True
1905
2033
1906 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
2034 avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime,
1907 dataOut.data_spc,
2035 dataOut.data_spc,
1908 dataOut.data_cspc,
2036 dataOut.data_cspc,
1909 dataOut.data_dc)
2037 dataOut.data_dc)
1910 self.incohInt += dataOut.nIncohInt
2038 self.incohInt += dataOut.nIncohInt
1911 self.nOutliers += dataOut.data_outlier
2039 self.nOutliers += dataOut.data_outlier
1912 if self.__dataReady:
2040 if self.__dataReady:
1913
2041 #print("prof: ",dataOut.max_nIncohInt,self.__profIndex)
1914 dataOut.data_spc = avgdata_spc
2042 dataOut.data_spc = avgdata_spc
1915 dataOut.data_cspc = avgdata_cspc
2043 dataOut.data_cspc = avgdata_cspc
1916 dataOut.data_dc = avgdata_dc
2044 dataOut.data_dc = avgdata_dc
1917 dataOut.nIncohInt = self.incohInt
2045 dataOut.nIncohInt = self.incohInt
1918 dataOut.data_outlier = self.nOutliers
2046 dataOut.data_outlier = self.nOutliers
1919 dataOut.utctime = avgdatatime
2047 dataOut.utctime = avgdatatime
1920 dataOut.flagNoData = False
2048 dataOut.flagNoData = False
1921 dataOut.max_nIncohInt = self.__profIndex
2049 dataOut.max_nIncohInt += self.__profIndex
1922 self.incohInt = 0
2050 self.incohInt = 0
1923 self.nOutliers = 0
2051 self.nOutliers = 0
1924 self.__profIndex = 0
2052 self.__profIndex = 0
1925
2053
1926 return dataOut
2054 return dataOut
1927
2055
1928 class dopplerFlip(Operation):
2056 class dopplerFlip(Operation):
1929
2057
1930 def run(self, dataOut):
2058 def run(self, dataOut):
1931 # arreglo 1: (num_chan, num_profiles, num_heights)
2059 # arreglo 1: (num_chan, num_profiles, num_heights)
1932 self.dataOut = dataOut
2060 self.dataOut = dataOut
1933 # JULIA-oblicua, indice 2
2061 # JULIA-oblicua, indice 2
1934 # arreglo 2: (num_profiles, num_heights)
2062 # arreglo 2: (num_profiles, num_heights)
1935 jspectra = self.dataOut.data_spc[2]
2063 jspectra = self.dataOut.data_spc[2]
1936 jspectra_tmp = numpy.zeros(jspectra.shape)
2064 jspectra_tmp = numpy.zeros(jspectra.shape)
1937 num_profiles = jspectra.shape[0]
2065 num_profiles = jspectra.shape[0]
1938 freq_dc = int(num_profiles / 2)
2066 freq_dc = int(num_profiles / 2)
1939 # Flip con for
2067 # Flip con for
1940 for j in range(num_profiles):
2068 for j in range(num_profiles):
1941 jspectra_tmp[num_profiles-j-1]= jspectra[j]
2069 jspectra_tmp[num_profiles-j-1]= jspectra[j]
1942 # Intercambio perfil de DC con perfil inmediato anterior
2070 # Intercambio perfil de DC con perfil inmediato anterior
1943 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
2071 jspectra_tmp[freq_dc-1]= jspectra[freq_dc-1]
1944 jspectra_tmp[freq_dc]= jspectra[freq_dc]
2072 jspectra_tmp[freq_dc]= jspectra[freq_dc]
1945 # canal modificado es re-escrito en el arreglo de canales
2073 # canal modificado es re-escrito en el arreglo de canales
1946 self.dataOut.data_spc[2] = jspectra_tmp
2074 self.dataOut.data_spc[2] = jspectra_tmp
1947
2075
1948 return self.dataOut
2076 return self.dataOut
@@ -1,2361 +1,2369
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 schainpy.model.io.utils import getHei_index
7 from schainpy.model.io.utils import getHei_index
8 from time import time
8 from time import time
9 import datetime
9 #import datetime
10 import numpy
10 import numpy
11 #import copy
11 #import copy
12 from schainpy.model.data import _noise
12 from schainpy.model.data import _noise
13
13
14 class VoltageProc(ProcessingUnit):
14 class VoltageProc(ProcessingUnit):
15
15
16 def __init__(self):
16 def __init__(self):
17
17
18 ProcessingUnit.__init__(self)
18 ProcessingUnit.__init__(self)
19
19
20 self.dataOut = Voltage()
20 self.dataOut = Voltage()
21 self.flip = 1
21 self.flip = 1
22 self.setupReq = False
22 self.setupReq = False
23
23
24 def run(self):
24 def run(self):
25 #print("running volt proc")
25 #print("running volt proc")
26 if self.dataIn.type == 'AMISR':
26 if self.dataIn.type == 'AMISR':
27 self.__updateObjFromAmisrInput()
27 self.__updateObjFromAmisrInput()
28
28
29 if self.dataOut.buffer_empty:
29 if self.dataOut.buffer_empty:
30 if self.dataIn.type == 'Voltage':
30 if self.dataIn.type == 'Voltage':
31 self.dataOut.copy(self.dataIn)
31 self.dataOut.copy(self.dataIn)
32 #print("new volts reading")
32 #print("new volts reading")
33
33
34
34
35 def __updateObjFromAmisrInput(self):
35 def __updateObjFromAmisrInput(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
41
42 self.dataOut.flagNoData = self.dataIn.flagNoData
42 self.dataOut.flagNoData = self.dataIn.flagNoData
43 self.dataOut.data = self.dataIn.data
43 self.dataOut.data = self.dataIn.data
44 self.dataOut.utctime = self.dataIn.utctime
44 self.dataOut.utctime = self.dataIn.utctime
45 self.dataOut.channelList = self.dataIn.channelList
45 self.dataOut.channelList = self.dataIn.channelList
46 #self.dataOut.timeInterval = self.dataIn.timeInterval
46 #self.dataOut.timeInterval = self.dataIn.timeInterval
47 self.dataOut.heightList = self.dataIn.heightList
47 self.dataOut.heightList = self.dataIn.heightList
48 self.dataOut.nProfiles = self.dataIn.nProfiles
48 self.dataOut.nProfiles = self.dataIn.nProfiles
49
49
50 self.dataOut.nCohInt = self.dataIn.nCohInt
50 self.dataOut.nCohInt = self.dataIn.nCohInt
51 self.dataOut.ippSeconds = self.dataIn.ippSeconds
51 self.dataOut.ippSeconds = self.dataIn.ippSeconds
52 self.dataOut.frequency = self.dataIn.frequency
52 self.dataOut.frequency = self.dataIn.frequency
53
53
54 self.dataOut.azimuth = self.dataIn.azimuth
54 self.dataOut.azimuth = self.dataIn.azimuth
55 self.dataOut.zenith = self.dataIn.zenith
55 self.dataOut.zenith = self.dataIn.zenith
56
56
57 self.dataOut.beam.codeList = self.dataIn.beam.codeList
57 self.dataOut.beam.codeList = self.dataIn.beam.codeList
58 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
58 self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList
59 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
59 self.dataOut.beam.zenithList = self.dataIn.beam.zenithList
60
60
61
61
62 class selectChannels(Operation):
62 class selectChannels(Operation):
63
63
64 def run(self, dataOut, channelList=None):
64 def run(self, dataOut, channelList=None):
65 self.channelList = channelList
65 self.channelList = channelList
66 if self.channelList == None:
66 if self.channelList == None:
67 print("Missing channelList")
67 print("Missing channelList")
68 return dataOut
68 return dataOut
69 channelIndexList = []
69 channelIndexList = []
70
70
71 if type(dataOut.channelList) is not list: #leer array desde HDF5
71 if type(dataOut.channelList) is not list: #leer array desde HDF5
72 try:
72 try:
73 dataOut.channelList = dataOut.channelList.tolist()
73 dataOut.channelList = dataOut.channelList.tolist()
74 except Exception as e:
74 except Exception as e:
75 print("Select Channels: ",e)
75 print("Select Channels: ",e)
76 for channel in self.channelList:
76 for channel in self.channelList:
77 if channel not in dataOut.channelList:
77 if channel not in dataOut.channelList:
78 raise ValueError("Channel %d is not in %s" %(channel, str(dataOut.channelList)))
78 raise ValueError("Channel %d is not in %s" %(channel, str(dataOut.channelList)))
79
79
80 index = dataOut.channelList.index(channel)
80 index = dataOut.channelList.index(channel)
81 channelIndexList.append(index)
81 channelIndexList.append(index)
82 dataOut = self.selectChannelsByIndex(dataOut,channelIndexList)
82 dataOut = self.selectChannelsByIndex(dataOut,channelIndexList)
83 return dataOut
83 return dataOut
84
84
85 def selectChannelsByIndex(self, dataOut, channelIndexList):
85 def selectChannelsByIndex(self, dataOut, channelIndexList):
86 """
86 """
87 Selecciona un bloque de datos en base a canales segun el channelIndexList
87 Selecciona un bloque de datos en base a canales segun el channelIndexList
88
88
89 Input:
89 Input:
90 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
90 channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7]
91
91
92 Affected:
92 Affected:
93 dataOut.data
93 dataOut.data
94 dataOut.channelIndexList
94 dataOut.channelIndexList
95 dataOut.nChannels
95 dataOut.nChannels
96 dataOut.m_ProcessingHeader.totalSpectra
96 dataOut.m_ProcessingHeader.totalSpectra
97 dataOut.systemHeaderObj.numChannels
97 dataOut.systemHeaderObj.numChannels
98 dataOut.m_ProcessingHeader.blockSize
98 dataOut.m_ProcessingHeader.blockSize
99
99
100 Return:
100 Return:
101 None
101 None
102 """
102 """
103 #print("selectChannelsByIndex")
103 #print("selectChannelsByIndex")
104 # for channelIndex in channelIndexList:
104 # for channelIndex in channelIndexList:
105 # if channelIndex not in dataOut.channelIndexList:
105 # if channelIndex not in dataOut.channelIndexList:
106 # raise ValueError("The value %d in channelIndexList is not valid" %channelIndex)
106 # raise ValueError("The value %d in channelIndexList is not valid" %channelIndex)
107
107
108 if dataOut.type == 'Voltage':
108 if dataOut.type == 'Voltage':
109 if dataOut.flagDataAsBlock:
109 if dataOut.flagDataAsBlock:
110 """
110 """
111 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
111 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
112 """
112 """
113 data = dataOut.data[channelIndexList,:,:]
113 data = dataOut.data[channelIndexList,:,:]
114 else:
114 else:
115 data = dataOut.data[channelIndexList,:]
115 data = dataOut.data[channelIndexList,:]
116
116
117 dataOut.data = data
117 dataOut.data = data
118 # dataOut.channelList = [dataOut.channelList[i] for i in channelIndexList]
118 # dataOut.channelList = [dataOut.channelList[i] for i in channelIndexList]
119 dataOut.channelList = range(len(channelIndexList))
119 dataOut.channelList = range(len(channelIndexList))
120
120
121 elif dataOut.type == 'Spectra':
121 elif dataOut.type == 'Spectra':
122 if hasattr(dataOut, 'data_spc'):
122 if hasattr(dataOut, 'data_spc'):
123 if dataOut.data_spc is None:
123 if dataOut.data_spc is None:
124 raise ValueError("data_spc is None")
124 raise ValueError("data_spc is None")
125 return dataOut
125 return dataOut
126 else:
126 else:
127 data_spc = dataOut.data_spc[channelIndexList, :]
127 data_spc = dataOut.data_spc[channelIndexList, :]
128 dataOut.data_spc = data_spc
128 dataOut.data_spc = data_spc
129
129
130 # if hasattr(dataOut, 'data_dc') :# and
130 # if hasattr(dataOut, 'data_dc') :# and
131 # if dataOut.data_dc is None:
131 # if dataOut.data_dc is None:
132 # raise ValueError("data_dc is None")
132 # raise ValueError("data_dc is None")
133 # return dataOut
133 # return dataOut
134 # else:
134 # else:
135 # data_dc = dataOut.data_dc[channelIndexList, :]
135 # data_dc = dataOut.data_dc[channelIndexList, :]
136 # dataOut.data_dc = data_dc
136 # dataOut.data_dc = data_dc
137 # dataOut.channelList = [dataOut.channelList[i] for i in channelIndexList]
137 # dataOut.channelList = [dataOut.channelList[i] for i in channelIndexList]
138 dataOut.channelList = channelIndexList
138 dataOut.channelList = channelIndexList
139 dataOut = self.__selectPairsByChannel(dataOut,channelIndexList)
139 dataOut = self.__selectPairsByChannel(dataOut,channelIndexList)
140
140
141 return dataOut
141 return dataOut
142
142
143 def __selectPairsByChannel(self, dataOut, channelList=None):
143 def __selectPairsByChannel(self, dataOut, channelList=None):
144 #print("__selectPairsByChannel")
144 #print("__selectPairsByChannel")
145 if channelList == None:
145 if channelList == None:
146 return
146 return
147
147
148 pairsIndexListSelected = []
148 pairsIndexListSelected = []
149 for pairIndex in dataOut.pairsIndexList:
149 for pairIndex in dataOut.pairsIndexList:
150 # First pair
150 # First pair
151 if dataOut.pairsList[pairIndex][0] not in channelList:
151 if dataOut.pairsList[pairIndex][0] not in channelList:
152 continue
152 continue
153 # Second pair
153 # Second pair
154 if dataOut.pairsList[pairIndex][1] not in channelList:
154 if dataOut.pairsList[pairIndex][1] not in channelList:
155 continue
155 continue
156
156
157 pairsIndexListSelected.append(pairIndex)
157 pairsIndexListSelected.append(pairIndex)
158 if not pairsIndexListSelected:
158 if not pairsIndexListSelected:
159 dataOut.data_cspc = None
159 dataOut.data_cspc = None
160 dataOut.pairsList = []
160 dataOut.pairsList = []
161 return
161 return
162
162
163 dataOut.data_cspc = dataOut.data_cspc[pairsIndexListSelected]
163 dataOut.data_cspc = dataOut.data_cspc[pairsIndexListSelected]
164 dataOut.pairsList = [dataOut.pairsList[i]
164 dataOut.pairsList = [dataOut.pairsList[i]
165 for i in pairsIndexListSelected]
165 for i in pairsIndexListSelected]
166
166
167 return dataOut
167 return dataOut
168
168
169 class selectHeights(Operation):
169 class selectHeights(Operation):
170
170
171 def run(self, dataOut, minHei=None, maxHei=None, minIndex=None, maxIndex=None):
171 def run(self, dataOut, minHei=None, maxHei=None, minIndex=None, maxIndex=None):
172 """
172 """
173 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
173 Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango
174 minHei <= height <= maxHei
174 minHei <= height <= maxHei
175
175
176 Input:
176 Input:
177 minHei : valor minimo de altura a considerar
177 minHei : valor minimo de altura a considerar
178 maxHei : valor maximo de altura a considerar
178 maxHei : valor maximo de altura a considerar
179
179
180 Affected:
180 Affected:
181 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
181 Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex
182
182
183 Return:
183 Return:
184 1 si el metodo se ejecuto con exito caso contrario devuelve 0
184 1 si el metodo se ejecuto con exito caso contrario devuelve 0
185 """
185 """
186
186
187 self.dataOut = dataOut
187 self.dataOut = dataOut
188
188
189 if minHei and maxHei:
189 if minHei and maxHei:
190
190
191 if (minHei < dataOut.heightList[0]):
191 if (minHei < dataOut.heightList[0]):
192 minHei = dataOut.heightList[0]
192 minHei = dataOut.heightList[0]
193
193
194 if (maxHei > dataOut.heightList[-1]):
194 if (maxHei > dataOut.heightList[-1]):
195 maxHei = dataOut.heightList[-1]
195 maxHei = dataOut.heightList[-1]
196
196
197 minIndex = 0
197 minIndex = 0
198 maxIndex = 0
198 maxIndex = 0
199 heights = dataOut.heightList
199 heights = dataOut.heightList
200
200
201 inda = numpy.where(heights >= minHei)
201 inda = numpy.where(heights >= minHei)
202 indb = numpy.where(heights <= maxHei)
202 indb = numpy.where(heights <= maxHei)
203
203
204 try:
204 try:
205 minIndex = inda[0][0]
205 minIndex = inda[0][0]
206 except:
206 except:
207 minIndex = 0
207 minIndex = 0
208
208
209 try:
209 try:
210 maxIndex = indb[0][-1]
210 maxIndex = indb[0][-1]
211 except:
211 except:
212 maxIndex = len(heights)
212 maxIndex = len(heights)
213
213
214 self.selectHeightsByIndex(minIndex, maxIndex)
214 self.selectHeightsByIndex(minIndex, maxIndex)
215
215
216 return dataOut
216 return dataOut
217
217
218 def selectHeightsByIndex(self, minIndex, maxIndex):
218 def selectHeightsByIndex(self, minIndex, maxIndex):
219 """
219 """
220 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
220 Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango
221 minIndex <= index <= maxIndex
221 minIndex <= index <= maxIndex
222
222
223 Input:
223 Input:
224 minIndex : valor de indice minimo de altura a considerar
224 minIndex : valor de indice minimo de altura a considerar
225 maxIndex : valor de indice maximo de altura a considerar
225 maxIndex : valor de indice maximo de altura a considerar
226
226
227 Affected:
227 Affected:
228 self.dataOut.data
228 self.dataOut.data
229 self.dataOut.heightList
229 self.dataOut.heightList
230
230
231 Return:
231 Return:
232 1 si el metodo se ejecuto con exito caso contrario devuelve 0
232 1 si el metodo se ejecuto con exito caso contrario devuelve 0
233 """
233 """
234
234
235 if self.dataOut.type == 'Voltage':
235 if self.dataOut.type == 'Voltage':
236 if (minIndex < 0) or (minIndex > maxIndex):
236 if (minIndex < 0) or (minIndex > maxIndex):
237 raise ValueError("Height index range (%d,%d) is not valid" % (minIndex, maxIndex))
237 raise ValueError("Height index range (%d,%d) is not valid" % (minIndex, maxIndex))
238
238
239 if (maxIndex >= self.dataOut.nHeights):
239 if (maxIndex >= self.dataOut.nHeights):
240 maxIndex = self.dataOut.nHeights
240 maxIndex = self.dataOut.nHeights
241
241
242 #voltage
242 #voltage
243 if self.dataOut.flagDataAsBlock:
243 if self.dataOut.flagDataAsBlock:
244 """
244 """
245 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
245 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
246 """
246 """
247 data = self.dataOut.data[:,:, minIndex:maxIndex]
247 data = self.dataOut.data[:,:, minIndex:maxIndex]
248 else:
248 else:
249 data = self.dataOut.data[:, minIndex:maxIndex]
249 data = self.dataOut.data[:, minIndex:maxIndex]
250
250
251 # firstHeight = self.dataOut.heightList[minIndex]
251 # firstHeight = self.dataOut.heightList[minIndex]
252
252
253 self.dataOut.data = data
253 self.dataOut.data = data
254 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex]
254 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex]
255
255
256 if self.dataOut.nHeights <= 1:
256 if self.dataOut.nHeights <= 1:
257 raise ValueError("selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights))
257 raise ValueError("selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights))
258 elif self.dataOut.type == 'Spectra':
258 elif self.dataOut.type == 'Spectra':
259 if (minIndex < 0) or (minIndex > maxIndex):
259 if (minIndex < 0) or (minIndex > maxIndex):
260 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (
260 raise ValueError("Error selecting heights: Index range (%d,%d) is not valid" % (
261 minIndex, maxIndex))
261 minIndex, maxIndex))
262
262
263 if (maxIndex >= self.dataOut.nHeights):
263 if (maxIndex >= self.dataOut.nHeights):
264 maxIndex = self.dataOut.nHeights - 1
264 maxIndex = self.dataOut.nHeights - 1
265
265
266 # Spectra
266 # Spectra
267 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
267 data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1]
268
268
269 data_cspc = None
269 data_cspc = None
270 if self.dataOut.data_cspc is not None:
270 if self.dataOut.data_cspc is not None:
271 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
271 data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1]
272
272
273 data_dc = None
273 data_dc = None
274 if self.dataOut.data_dc is not None:
274 if self.dataOut.data_dc is not None:
275 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
275 data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1]
276
276
277 self.dataOut.data_spc = data_spc
277 self.dataOut.data_spc = data_spc
278 self.dataOut.data_cspc = data_cspc
278 self.dataOut.data_cspc = data_cspc
279 self.dataOut.data_dc = data_dc
279 self.dataOut.data_dc = data_dc
280
280
281 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
281 self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex + 1]
282
282
283 return 1
283 return 1
284
284
285
285
286 class filterByHeights(Operation):
286 class filterByHeights(Operation):
287
287
288 def run(self, dataOut, window):
288 def run(self, dataOut, window):
289
289
290 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
290 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
291
291
292 if window == None:
292 if window == None:
293 window = (dataOut.radarControllerHeaderObj.txA/dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
293 window = (dataOut.radarControllerHeaderObj.txA/dataOut.radarControllerHeaderObj.nBaud) / deltaHeight
294
294
295 newdelta = deltaHeight * window
295 newdelta = deltaHeight * window
296 r = dataOut.nHeights % window
296 r = dataOut.nHeights % window
297 newheights = (dataOut.nHeights-r)/window
297 newheights = (dataOut.nHeights-r)/window
298
298
299 if newheights <= 1:
299 if newheights <= 1:
300 raise ValueError("filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(dataOut.nHeights, window))
300 raise ValueError("filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(dataOut.nHeights, window))
301
301
302 if dataOut.flagDataAsBlock:
302 if dataOut.flagDataAsBlock:
303 """
303 """
304 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
304 Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis]
305 """
305 """
306 buffer = dataOut.data[:, :, 0:int(dataOut.nHeights-r)]
306 buffer = dataOut.data[:, :, 0:int(dataOut.nHeights-r)]
307 buffer = buffer.reshape(dataOut.nChannels, dataOut.nProfiles, int(dataOut.nHeights/window), window)
307 buffer = buffer.reshape(dataOut.nChannels, dataOut.nProfiles, int(dataOut.nHeights/window), window)
308 buffer = numpy.sum(buffer,3)
308 buffer = numpy.sum(buffer,3)
309
309
310 else:
310 else:
311 buffer = dataOut.data[:,0:int(dataOut.nHeights-r)]
311 buffer = dataOut.data[:,0:int(dataOut.nHeights-r)]
312 buffer = buffer.reshape(dataOut.nChannels,int(dataOut.nHeights/window),int(window))
312 buffer = buffer.reshape(dataOut.nChannels,int(dataOut.nHeights/window),int(window))
313 buffer = numpy.sum(buffer,2)
313 buffer = numpy.sum(buffer,2)
314
314
315 dataOut.data = buffer
315 dataOut.data = buffer
316 dataOut.heightList = dataOut.heightList[0] + numpy.arange( newheights )*newdelta
316 dataOut.heightList = dataOut.heightList[0] + numpy.arange( newheights )*newdelta
317 dataOut.windowOfFilter = window
317 dataOut.windowOfFilter = window
318
318
319 return dataOut
319 return dataOut
320
320
321
321
322 class setH0(Operation):
322 class setH0(Operation):
323
323
324 def run(self, dataOut, h0, deltaHeight = None):
324 def run(self, dataOut, h0, deltaHeight = None):
325
325
326 if not deltaHeight:
326 if not deltaHeight:
327 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
327 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
328
328
329 nHeights = dataOut.nHeights
329 nHeights = dataOut.nHeights
330
330
331 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
331 newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight
332
332
333 dataOut.heightList = newHeiRange
333 dataOut.heightList = newHeiRange
334
334
335 return dataOut
335 return dataOut
336
336
337
337
338 class deFlip(Operation):
338 class deFlip(Operation):
339
339
340 def run(self, dataOut, channelList = []):
340 def run(self, dataOut, channelList = []):
341
341
342 data = dataOut.data.copy()
342 data = dataOut.data.copy()
343
343
344 if dataOut.flagDataAsBlock:
344 if dataOut.flagDataAsBlock:
345 flip = self.flip
345 flip = self.flip
346 profileList = list(range(dataOut.nProfiles))
346 profileList = list(range(dataOut.nProfiles))
347
347
348 if not channelList:
348 if not channelList:
349 for thisProfile in profileList:
349 for thisProfile in profileList:
350 data[:,thisProfile,:] = data[:,thisProfile,:]*flip
350 data[:,thisProfile,:] = data[:,thisProfile,:]*flip
351 flip *= -1.0
351 flip *= -1.0
352 else:
352 else:
353 for thisChannel in channelList:
353 for thisChannel in channelList:
354 if thisChannel not in dataOut.channelList:
354 if thisChannel not in dataOut.channelList:
355 continue
355 continue
356
356
357 for thisProfile in profileList:
357 for thisProfile in profileList:
358 data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip
358 data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip
359 flip *= -1.0
359 flip *= -1.0
360
360
361 self.flip = flip
361 self.flip = flip
362
362
363 else:
363 else:
364 if not channelList:
364 if not channelList:
365 data[:,:] = data[:,:]*self.flip
365 data[:,:] = data[:,:]*self.flip
366 else:
366 else:
367 for thisChannel in channelList:
367 for thisChannel in channelList:
368 if thisChannel not in dataOut.channelList:
368 if thisChannel not in dataOut.channelList:
369 continue
369 continue
370
370
371 data[thisChannel,:] = data[thisChannel,:]*self.flip
371 data[thisChannel,:] = data[thisChannel,:]*self.flip
372
372
373 self.flip *= -1.
373 self.flip *= -1.
374
374
375 dataOut.data = data
375 dataOut.data = data
376
376
377 return dataOut
377 return dataOut
378
378
379
379
380 class setAttribute(Operation):
380 class setAttribute(Operation):
381 '''
381 '''
382 Set an arbitrary attribute(s) to dataOut
382 Set an arbitrary attribute(s) to dataOut
383 '''
383 '''
384
384
385 def __init__(self):
385 def __init__(self):
386
386
387 Operation.__init__(self)
387 Operation.__init__(self)
388 self._ready = False
388 self._ready = False
389
389
390 def run(self, dataOut, **kwargs):
390 def run(self, dataOut, **kwargs):
391
391
392 for key, value in kwargs.items():
392 for key, value in kwargs.items():
393 setattr(dataOut, key, value)
393 setattr(dataOut, key, value)
394
394
395 return dataOut
395 return dataOut
396
396
397
397
398 @MPDecorator
398 @MPDecorator
399 class printAttribute(Operation):
399 class printAttribute(Operation):
400 '''
400 '''
401 Print an arbitrary attribute of dataOut
401 Print an arbitrary attribute of dataOut
402 '''
402 '''
403
403
404 def __init__(self):
404 def __init__(self):
405
405
406 Operation.__init__(self)
406 Operation.__init__(self)
407
407
408 def run(self, dataOut, attributes):
408 def run(self, dataOut, attributes):
409
409
410 if isinstance(attributes, str):
410 if isinstance(attributes, str):
411 attributes = [attributes]
411 attributes = [attributes]
412 for attr in attributes:
412 for attr in attributes:
413 if hasattr(dataOut, attr):
413 if hasattr(dataOut, attr):
414 log.log(getattr(dataOut, attr), attr)
414 log.log(getattr(dataOut, attr), attr)
415
415
416
416
417 class interpolateHeights(Operation):
417 class interpolateHeights(Operation):
418
418
419 def run(self, dataOut, topLim, botLim):
419 def run(self, dataOut, topLim, botLim):
420 #69 al 72 para julia
420 #69 al 72 para julia
421 #82-84 para meteoros
421 #82-84 para meteoros
422 if len(numpy.shape(dataOut.data))==2:
422 if len(numpy.shape(dataOut.data))==2:
423 sampInterp = (dataOut.data[:,botLim-1] + dataOut.data[:,topLim+1])/2
423 sampInterp = (dataOut.data[:,botLim-1] + dataOut.data[:,topLim+1])/2
424 sampInterp = numpy.transpose(numpy.tile(sampInterp,(topLim-botLim + 1,1)))
424 sampInterp = numpy.transpose(numpy.tile(sampInterp,(topLim-botLim + 1,1)))
425 #dataOut.data[:,botLim:limSup+1] = sampInterp
425 #dataOut.data[:,botLim:limSup+1] = sampInterp
426 dataOut.data[:,botLim:topLim+1] = sampInterp
426 dataOut.data[:,botLim:topLim+1] = sampInterp
427 else:
427 else:
428 nHeights = dataOut.data.shape[2]
428 nHeights = dataOut.data.shape[2]
429 x = numpy.hstack((numpy.arange(botLim),numpy.arange(topLim+1,nHeights)))
429 x = numpy.hstack((numpy.arange(botLim),numpy.arange(topLim+1,nHeights)))
430 y = dataOut.data[:,:,list(range(botLim))+list(range(topLim+1,nHeights))]
430 y = dataOut.data[:,:,list(range(botLim))+list(range(topLim+1,nHeights))]
431 f = interpolate.interp1d(x, y, axis = 2)
431 f = interpolate.interp1d(x, y, axis = 2)
432 xnew = numpy.arange(botLim,topLim+1)
432 xnew = numpy.arange(botLim,topLim+1)
433 ynew = f(xnew)
433 ynew = f(xnew)
434 dataOut.data[:,:,botLim:topLim+1] = ynew
434 dataOut.data[:,:,botLim:topLim+1] = ynew
435
435
436 return dataOut
436 return dataOut
437
437
438
438
439 class CohInt(Operation):
439 class CohInt(Operation):
440
440
441 isConfig = False
441 isConfig = False
442 __profIndex = 0
442 __profIndex = 0
443 __byTime = False
443 __byTime = False
444 __initime = None
444 __initime = None
445 __lastdatatime = None
445 __lastdatatime = None
446 __integrationtime = None
446 __integrationtime = None
447 __buffer = None
447 __buffer = None
448 __bufferStride = []
448 __bufferStride = []
449 __dataReady = False
449 __dataReady = False
450 __profIndexStride = 0
450 __profIndexStride = 0
451 __dataToPutStride = False
451 __dataToPutStride = False
452 n = None
452 n = None
453
453
454 def __init__(self, **kwargs):
454 def __init__(self, **kwargs):
455
455
456 Operation.__init__(self, **kwargs)
456 Operation.__init__(self, **kwargs)
457
457
458 def setup(self, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False):
458 def setup(self, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False):
459 """
459 """
460 Set the parameters of the integration class.
460 Set the parameters of the integration class.
461
461
462 Inputs:
462 Inputs:
463
463
464 n : Number of coherent integrations
464 n : Number of coherent integrations
465 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
465 timeInterval : Time of integration. If the parameter "n" is selected this one does not work
466 overlapping :
466 overlapping :
467 """
467 """
468
468
469 self.__initime = None
469 self.__initime = None
470 self.__lastdatatime = 0
470 self.__lastdatatime = 0
471 self.__buffer = None
471 self.__buffer = None
472 self.__dataReady = False
472 self.__dataReady = False
473 self.byblock = byblock
473 self.byblock = byblock
474 self.stride = stride
474 self.stride = stride
475
475
476 if n == None and timeInterval == None:
476 if n == None and timeInterval == None:
477 raise ValueError("n or timeInterval should be specified ...")
477 raise ValueError("n or timeInterval should be specified ...")
478
478
479 if n != None:
479 if n != None:
480 self.n = n
480 self.n = n
481 self.__byTime = False
481 self.__byTime = False
482 else:
482 else:
483 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
483 self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line
484 self.n = 9999
484 self.n = 9999
485 self.__byTime = True
485 self.__byTime = True
486
486
487 if overlapping:
487 if overlapping:
488 self.__withOverlapping = True
488 self.__withOverlapping = True
489 self.__buffer = None
489 self.__buffer = None
490 else:
490 else:
491 self.__withOverlapping = False
491 self.__withOverlapping = False
492 self.__buffer = 0
492 self.__buffer = 0
493
493
494 self.__profIndex = 0
494 self.__profIndex = 0
495
495
496 def putData(self, data):
496 def putData(self, data):
497
497
498 """
498 """
499 Add a profile to the __buffer and increase in one the __profileIndex
499 Add a profile to the __buffer and increase in one the __profileIndex
500
500
501 """
501 """
502
502
503 if not self.__withOverlapping:
503 if not self.__withOverlapping:
504 self.__buffer += data.copy()
504 self.__buffer += data.copy()
505 self.__profIndex += 1
505 self.__profIndex += 1
506 return
506 return
507
507
508 #Overlapping data
508 #Overlapping data
509 nChannels, nHeis = data.shape
509 nChannels, nHeis = data.shape
510 data = numpy.reshape(data, (1, nChannels, nHeis))
510 data = numpy.reshape(data, (1, nChannels, nHeis))
511
511
512 #If the buffer is empty then it takes the data value
512 #If the buffer is empty then it takes the data value
513 if self.__buffer is None:
513 if self.__buffer is None:
514 self.__buffer = data
514 self.__buffer = data
515 self.__profIndex += 1
515 self.__profIndex += 1
516 return
516 return
517
517
518 #If the buffer length is lower than n then stakcing the data value
518 #If the buffer length is lower than n then stakcing the data value
519 if self.__profIndex < self.n:
519 if self.__profIndex < self.n:
520 self.__buffer = numpy.vstack((self.__buffer, data))
520 self.__buffer = numpy.vstack((self.__buffer, data))
521 self.__profIndex += 1
521 self.__profIndex += 1
522 return
522 return
523
523
524 #If the buffer length is equal to n then replacing the last buffer value with the data value
524 #If the buffer length is equal to n then replacing the last buffer value with the data value
525 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
525 self.__buffer = numpy.roll(self.__buffer, -1, axis=0)
526 self.__buffer[self.n-1] = data
526 self.__buffer[self.n-1] = data
527 self.__profIndex = self.n
527 self.__profIndex = self.n
528 return
528 return
529
529
530
530
531 def pushData(self):
531 def pushData(self):
532 """
532 """
533 Return the sum of the last profiles and the profiles used in the sum.
533 Return the sum of the last profiles and the profiles used in the sum.
534
534
535 Affected:
535 Affected:
536
536
537 self.__profileIndex
537 self.__profileIndex
538
538
539 """
539 """
540
540
541 if not self.__withOverlapping:
541 if not self.__withOverlapping:
542 data = self.__buffer
542 data = self.__buffer
543 n = self.__profIndex
543 n = self.__profIndex
544
544
545 self.__buffer = 0
545 self.__buffer = 0
546 self.__profIndex = 0
546 self.__profIndex = 0
547
547
548 return data, n
548 return data, n
549
549
550 #Integration with Overlapping
550 #Integration with Overlapping
551 data = numpy.sum(self.__buffer, axis=0)
551 data = numpy.sum(self.__buffer, axis=0)
552 # print data
552 # print data
553 # raise
553 # raise
554 n = self.__profIndex
554 n = self.__profIndex
555
555
556 return data, n
556 return data, n
557
557
558 def byProfiles(self, data):
558 def byProfiles(self, data):
559
559
560 self.__dataReady = False
560 self.__dataReady = False
561 avgdata = None
561 avgdata = None
562 # n = None
562 # n = None
563 # print data
563 # print data
564 # raise
564 # raise
565 self.putData(data)
565 self.putData(data)
566
566
567 if self.__profIndex == self.n:
567 if self.__profIndex == self.n:
568 avgdata, n = self.pushData()
568 avgdata, n = self.pushData()
569 self.__dataReady = True
569 self.__dataReady = True
570
570
571 return avgdata
571 return avgdata
572
572
573 def byTime(self, data, datatime):
573 def byTime(self, data, datatime):
574
574
575 self.__dataReady = False
575 self.__dataReady = False
576 avgdata = None
576 avgdata = None
577 n = None
577 n = None
578
578
579 self.putData(data)
579 self.putData(data)
580
580
581 if (datatime - self.__initime) >= self.__integrationtime:
581 if (datatime - self.__initime) >= self.__integrationtime:
582 avgdata, n = self.pushData()
582 avgdata, n = self.pushData()
583 self.n = n
583 self.n = n
584 self.__dataReady = True
584 self.__dataReady = True
585
585
586 return avgdata
586 return avgdata
587
587
588 def integrateByStride(self, data, datatime):
588 def integrateByStride(self, data, datatime):
589 # print data
589 # print data
590 if self.__profIndex == 0:
590 if self.__profIndex == 0:
591 self.__buffer = [[data.copy(), datatime]]
591 self.__buffer = [[data.copy(), datatime]]
592 else:
592 else:
593 self.__buffer.append([data.copy(),datatime])
593 self.__buffer.append([data.copy(),datatime])
594 self.__profIndex += 1
594 self.__profIndex += 1
595 self.__dataReady = False
595 self.__dataReady = False
596
596
597 if self.__profIndex == self.n * self.stride :
597 if self.__profIndex == self.n * self.stride :
598 self.__dataToPutStride = True
598 self.__dataToPutStride = True
599 self.__profIndexStride = 0
599 self.__profIndexStride = 0
600 self.__profIndex = 0
600 self.__profIndex = 0
601 self.__bufferStride = []
601 self.__bufferStride = []
602 for i in range(self.stride):
602 for i in range(self.stride):
603 current = self.__buffer[i::self.stride]
603 current = self.__buffer[i::self.stride]
604 data = numpy.sum([t[0] for t in current], axis=0)
604 data = numpy.sum([t[0] for t in current], axis=0)
605 avgdatatime = numpy.average([t[1] for t in current])
605 avgdatatime = numpy.average([t[1] for t in current])
606 # print data
606 # print data
607 self.__bufferStride.append((data, avgdatatime))
607 self.__bufferStride.append((data, avgdatatime))
608
608
609 if self.__dataToPutStride:
609 if self.__dataToPutStride:
610 self.__dataReady = True
610 self.__dataReady = True
611 self.__profIndexStride += 1
611 self.__profIndexStride += 1
612 if self.__profIndexStride == self.stride:
612 if self.__profIndexStride == self.stride:
613 self.__dataToPutStride = False
613 self.__dataToPutStride = False
614 # print self.__bufferStride[self.__profIndexStride - 1]
614 # print self.__bufferStride[self.__profIndexStride - 1]
615 # raise
615 # raise
616 return self.__bufferStride[self.__profIndexStride - 1]
616 return self.__bufferStride[self.__profIndexStride - 1]
617
617
618
618
619 return None, None
619 return None, None
620
620
621 def integrate(self, data, datatime=None):
621 def integrate(self, data, datatime=None):
622
622
623 if self.__initime == None:
623 if self.__initime == None:
624 self.__initime = datatime
624 self.__initime = datatime
625
625
626 if self.__byTime:
626 if self.__byTime:
627 avgdata = self.byTime(data, datatime)
627 avgdata = self.byTime(data, datatime)
628 else:
628 else:
629 avgdata = self.byProfiles(data)
629 avgdata = self.byProfiles(data)
630
630
631
631
632 self.__lastdatatime = datatime
632 self.__lastdatatime = datatime
633
633
634 if avgdata is None:
634 if avgdata is None:
635 return None, None
635 return None, None
636
636
637 avgdatatime = self.__initime
637 avgdatatime = self.__initime
638
638
639 deltatime = datatime - self.__lastdatatime
639 deltatime = datatime - self.__lastdatatime
640
640
641 if not self.__withOverlapping:
641 if not self.__withOverlapping:
642 self.__initime = datatime
642 self.__initime = datatime
643 else:
643 else:
644 self.__initime += deltatime
644 self.__initime += deltatime
645
645
646 return avgdata, avgdatatime
646 return avgdata, avgdatatime
647
647
648 def integrateByBlock(self, dataOut):
648 def integrateByBlock(self, dataOut):
649
649
650 times = int(dataOut.data.shape[1]/self.n)
650 times = int(dataOut.data.shape[1]/self.n)
651 avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex)
651 avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex)
652
652
653 id_min = 0
653 id_min = 0
654 id_max = self.n
654 id_max = self.n
655
655
656 for i in range(times):
656 for i in range(times):
657 junk = dataOut.data[:,id_min:id_max,:]
657 junk = dataOut.data[:,id_min:id_max,:]
658 avgdata[:,i,:] = junk.sum(axis=1)
658 avgdata[:,i,:] = junk.sum(axis=1)
659 id_min += self.n
659 id_min += self.n
660 id_max += self.n
660 id_max += self.n
661
661
662 timeInterval = dataOut.ippSeconds*self.n
662 timeInterval = dataOut.ippSeconds*self.n
663 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
663 avgdatatime = (times - 1) * timeInterval + dataOut.utctime
664 self.__dataReady = True
664 self.__dataReady = True
665 return avgdata, avgdatatime
665 return avgdata, avgdatatime
666
666
667 def run(self, dataOut, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False, **kwargs):
667 def run(self, dataOut, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False, **kwargs):
668
668
669 if not self.isConfig:
669 if not self.isConfig:
670 self.setup(n=n, stride=stride, timeInterval=timeInterval, overlapping=overlapping, byblock=byblock, **kwargs)
670 self.setup(n=n, stride=stride, timeInterval=timeInterval, overlapping=overlapping, byblock=byblock, **kwargs)
671 self.isConfig = True
671 self.isConfig = True
672
672
673 if dataOut.flagDataAsBlock:
673 if dataOut.flagDataAsBlock:
674 """
674 """
675 Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis]
675 Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis]
676 """
676 """
677 avgdata, avgdatatime = self.integrateByBlock(dataOut)
677 avgdata, avgdatatime = self.integrateByBlock(dataOut)
678 dataOut.nProfiles /= self.n
678 dataOut.nProfiles /= self.n
679 else:
679 else:
680 if stride is None:
680 if stride is None:
681 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
681 avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime)
682 else:
682 else:
683 avgdata, avgdatatime = self.integrateByStride(dataOut.data, dataOut.utctime)
683 avgdata, avgdatatime = self.integrateByStride(dataOut.data, dataOut.utctime)
684
684
685
685
686 # dataOut.timeInterval *= n
686 # dataOut.timeInterval *= n
687 dataOut.flagNoData = True
687 dataOut.flagNoData = True
688
688
689 if self.__dataReady:
689 if self.__dataReady:
690 dataOut.data = avgdata
690 dataOut.data = avgdata
691 if not dataOut.flagCohInt:
691 if not dataOut.flagCohInt:
692 dataOut.nCohInt *= self.n
692 dataOut.nCohInt *= self.n
693 dataOut.flagCohInt = True
693 dataOut.flagCohInt = True
694 dataOut.utctime = avgdatatime
694 dataOut.utctime = avgdatatime
695 # print avgdata, avgdatatime
695 # print avgdata, avgdatatime
696 # raise
696 # raise
697 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
697 # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt
698 dataOut.flagNoData = False
698 dataOut.flagNoData = False
699 return dataOut
699 return dataOut
700
700
701 class Decoder(Operation):
701 class Decoder(Operation):
702
702
703 isConfig = False
703 isConfig = False
704 __profIndex = 0
704 __profIndex = 0
705
705
706 code = None
706 code = None
707
707
708 nCode = None
708 nCode = None
709 nBaud = None
709 nBaud = None
710
710
711 def __init__(self, **kwargs):
711 def __init__(self, **kwargs):
712
712
713 Operation.__init__(self, **kwargs)
713 Operation.__init__(self, **kwargs)
714
714
715 self.times = None
715 self.times = None
716 self.osamp = None
716 self.osamp = None
717 # self.__setValues = False
717 # self.__setValues = False
718 self.isConfig = False
718 self.isConfig = False
719 self.setupReq = False
719 self.setupReq = False
720 def setup(self, code, osamp, dataOut):
720 def setup(self, code, osamp, dataOut):
721
721
722 self.__profIndex = 0
722 self.__profIndex = 0
723
723
724 self.code = code
724 self.code = code
725
725
726 self.nCode = len(code)
726 self.nCode = len(code)
727 self.nBaud = len(code[0])
727 self.nBaud = len(code[0])
728 if (osamp != None) and (osamp >1):
728 if (osamp != None) and (osamp >1):
729 self.osamp = osamp
729 self.osamp = osamp
730 self.code = numpy.repeat(code, repeats=self.osamp, axis=1)
730 self.code = numpy.repeat(code, repeats=self.osamp, axis=1)
731 self.nBaud = self.nBaud*self.osamp
731 self.nBaud = self.nBaud*self.osamp
732
732
733 self.__nChannels = dataOut.nChannels
733 self.__nChannels = dataOut.nChannels
734 self.__nProfiles = dataOut.nProfiles
734 self.__nProfiles = dataOut.nProfiles
735 self.__nHeis = dataOut.nHeights
735 self.__nHeis = dataOut.nHeights
736
736
737 if self.__nHeis < self.nBaud:
737 if self.__nHeis < self.nBaud:
738 raise ValueError('Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud))
738 raise ValueError('Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud))
739
739
740 #Frequency
740 #Frequency
741 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
741 __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex)
742
742
743 __codeBuffer[:,0:self.nBaud] = self.code
743 __codeBuffer[:,0:self.nBaud] = self.code
744
744
745 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
745 self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1))
746
746
747 if dataOut.flagDataAsBlock:
747 if dataOut.flagDataAsBlock:
748
748
749 self.ndatadec = self.__nHeis #- self.nBaud + 1
749 self.ndatadec = self.__nHeis #- self.nBaud + 1
750
750
751 self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex)
751 self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex)
752
752
753 else:
753 else:
754
754
755 #Time
755 #Time
756 self.ndatadec = self.__nHeis #- self.nBaud + 1
756 self.ndatadec = self.__nHeis #- self.nBaud + 1
757
757
758 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
758 self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex)
759
759
760 def __convolutionInFreq(self, data):
760 def __convolutionInFreq(self, data):
761
761
762 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
762 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
763
763
764 fft_data = numpy.fft.fft(data, axis=1)
764 fft_data = numpy.fft.fft(data, axis=1)
765
765
766 conv = fft_data*fft_code
766 conv = fft_data*fft_code
767
767
768 data = numpy.fft.ifft(conv,axis=1)
768 data = numpy.fft.ifft(conv,axis=1)
769
769
770 return data
770 return data
771
771
772 def __convolutionInFreqOpt(self, data):
772 def __convolutionInFreqOpt(self, data):
773
773
774 raise NotImplementedError
774 raise NotImplementedError
775
775
776 def __convolutionInTime(self, data):
776 def __convolutionInTime(self, data):
777
777
778 code = self.code[self.__profIndex]
778 code = self.code[self.__profIndex]
779 for i in range(self.__nChannels):
779 for i in range(self.__nChannels):
780 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:]
780 self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:]
781
781
782 return self.datadecTime
782 return self.datadecTime
783
783
784 def __convolutionByBlockInTime(self, data):
784 def __convolutionByBlockInTime(self, data):
785
785
786 repetitions = int(self.__nProfiles / self.nCode)
786 repetitions = int(self.__nProfiles / self.nCode)
787 junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize))
787 junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize))
788 junk = junk.flatten()
788 junk = junk.flatten()
789 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
789 code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud))
790 profilesList = range(self.__nProfiles)
790 profilesList = range(self.__nProfiles)
791
791
792 for i in range(self.__nChannels):
792 for i in range(self.__nChannels):
793 for j in profilesList:
793 for j in profilesList:
794 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
794 self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:]
795 return self.datadecTime
795 return self.datadecTime
796
796
797 def __convolutionByBlockInFreq(self, data):
797 def __convolutionByBlockInFreq(self, data):
798
798
799 raise NotImplementedError("Decoder by frequency fro Blocks not implemented")
799 raise NotImplementedError("Decoder by frequency fro Blocks not implemented")
800
800
801
801
802 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
802 fft_code = self.fft_code[self.__profIndex].reshape(1,-1)
803
803
804 fft_data = numpy.fft.fft(data, axis=2)
804 fft_data = numpy.fft.fft(data, axis=2)
805
805
806 conv = fft_data*fft_code
806 conv = fft_data*fft_code
807
807
808 data = numpy.fft.ifft(conv,axis=2)
808 data = numpy.fft.ifft(conv,axis=2)
809
809
810 return data
810 return data
811
811
812
812
813 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
813 def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None):
814
814
815 if dataOut.flagDecodeData:
815 if dataOut.flagDecodeData:
816 print("This data is already decoded, recoding again ...")
816 print("This data is already decoded, recoding again ...")
817
817
818 if not self.isConfig:
818 if not self.isConfig:
819
819
820 if code is None:
820 if code is None:
821 if dataOut.code is None:
821 if dataOut.code is None:
822 raise ValueError("Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type)
822 raise ValueError("Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type)
823
823
824 code = dataOut.code
824 code = dataOut.code
825 else:
825 else:
826 code = numpy.array(code).reshape(nCode,nBaud)
826 code = numpy.array(code).reshape(nCode,nBaud)
827 self.setup(code, osamp, dataOut)
827 self.setup(code, osamp, dataOut)
828
828
829 self.isConfig = True
829 self.isConfig = True
830
830
831 if mode == 3:
831 if mode == 3:
832 sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode)
832 sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode)
833
833
834 if times != None:
834 if times != None:
835 sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n")
835 sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n")
836
836
837 if self.code is None:
837 if self.code is None:
838 print("Fail decoding: Code is not defined.")
838 print("Fail decoding: Code is not defined.")
839 return
839 return
840
840
841 self.__nProfiles = dataOut.nProfiles
841 self.__nProfiles = dataOut.nProfiles
842 datadec = None
842 datadec = None
843
843
844 if mode == 3:
844 if mode == 3:
845 mode = 0
845 mode = 0
846
846
847 if dataOut.flagDataAsBlock:
847 if dataOut.flagDataAsBlock:
848 """
848 """
849 Decoding when data have been read as block,
849 Decoding when data have been read as block,
850 """
850 """
851
851
852 if mode == 0:
852 if mode == 0:
853 datadec = self.__convolutionByBlockInTime(dataOut.data)
853 datadec = self.__convolutionByBlockInTime(dataOut.data)
854 if mode == 1:
854 if mode == 1:
855 datadec = self.__convolutionByBlockInFreq(dataOut.data)
855 datadec = self.__convolutionByBlockInFreq(dataOut.data)
856 else:
856 else:
857 """
857 """
858 Decoding when data have been read profile by profile
858 Decoding when data have been read profile by profile
859 """
859 """
860 if mode == 0:
860 if mode == 0:
861 datadec = self.__convolutionInTime(dataOut.data)
861 datadec = self.__convolutionInTime(dataOut.data)
862
862
863 if mode == 1:
863 if mode == 1:
864 datadec = self.__convolutionInFreq(dataOut.data)
864 datadec = self.__convolutionInFreq(dataOut.data)
865
865
866 if mode == 2:
866 if mode == 2:
867 datadec = self.__convolutionInFreqOpt(dataOut.data)
867 datadec = self.__convolutionInFreqOpt(dataOut.data)
868
868
869 if datadec is None:
869 if datadec is None:
870 raise ValueError("Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode)
870 raise ValueError("Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode)
871
871
872 dataOut.code = self.code
872 dataOut.code = self.code
873 dataOut.nCode = self.nCode
873 dataOut.nCode = self.nCode
874 dataOut.nBaud = self.nBaud
874 dataOut.nBaud = self.nBaud
875
875
876 dataOut.data = datadec
876 dataOut.data = datadec
877
877
878 dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]]
878 dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]]
879
879
880 dataOut.flagDecodeData = True #asumo q la data esta decodificada
880 dataOut.flagDecodeData = True #asumo q la data esta decodificada
881
881
882 if self.__profIndex == self.nCode-1:
882 if self.__profIndex == self.nCode-1:
883 self.__profIndex = 0
883 self.__profIndex = 0
884 return dataOut
884 return dataOut
885
885
886 self.__profIndex += 1
886 self.__profIndex += 1
887
887
888 return dataOut
888 return dataOut
889 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
889 # dataOut.flagDeflipData = True #asumo q la data no esta sin flip
890
890
891
891
892 class ProfileConcat(Operation):
892 class ProfileConcat(Operation):
893
893
894 isConfig = False
894 isConfig = False
895 buffer = None
895 buffer = None
896
896
897 def __init__(self, **kwargs):
897 def __init__(self, **kwargs):
898
898
899 Operation.__init__(self, **kwargs)
899 Operation.__init__(self, **kwargs)
900 self.profileIndex = 0
900 self.profileIndex = 0
901
901
902 def reset(self):
902 def reset(self):
903 self.buffer = numpy.zeros_like(self.buffer)
903 self.buffer = numpy.zeros_like(self.buffer)
904 self.start_index = 0
904 self.start_index = 0
905 self.times = 1
905 self.times = 1
906
906
907 def setup(self, data, m, n=1):
907 def setup(self, data, m, n=1):
908 self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0]))
908 self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0]))
909 self.nHeights = data.shape[1]#.nHeights
909 self.nHeights = data.shape[1]#.nHeights
910 self.start_index = 0
910 self.start_index = 0
911 self.times = 1
911 self.times = 1
912
912
913 def concat(self, data):
913 def concat(self, data):
914
914
915 self.buffer[:,self.start_index:self.nHeights*self.times] = data.copy()
915 self.buffer[:,self.start_index:self.nHeights*self.times] = data.copy()
916 self.start_index = self.start_index + self.nHeights
916 self.start_index = self.start_index + self.nHeights
917
917
918 def run(self, dataOut, m):
918 def run(self, dataOut, m):
919 dataOut.flagNoData = True
919 dataOut.flagNoData = True
920
920
921 if not self.isConfig:
921 if not self.isConfig:
922 self.setup(dataOut.data, m, 1)
922 self.setup(dataOut.data, m, 1)
923 self.isConfig = True
923 self.isConfig = True
924
924
925 if dataOut.flagDataAsBlock:
925 if dataOut.flagDataAsBlock:
926 raise ValueError("ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False")
926 raise ValueError("ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False")
927
927
928 else:
928 else:
929 self.concat(dataOut.data)
929 self.concat(dataOut.data)
930 self.times += 1
930 self.times += 1
931 if self.times > m:
931 if self.times > m:
932 dataOut.data = self.buffer
932 dataOut.data = self.buffer
933 self.reset()
933 self.reset()
934 dataOut.flagNoData = False
934 dataOut.flagNoData = False
935 # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas
935 # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas
936 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
936 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
937 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m
937 xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m
938 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
938 dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight)
939 dataOut.ippSeconds *= m
939 dataOut.ippSeconds *= m
940 return dataOut
940 return dataOut
941
941
942 class ProfileSelector(Operation):
942 class ProfileSelector(Operation):
943
943
944 profileIndex = None
944 profileIndex = None
945 # Tamanho total de los perfiles
945 # Tamanho total de los perfiles
946 nProfiles = None
946 nProfiles = None
947
947
948 def __init__(self, **kwargs):
948 def __init__(self, **kwargs):
949
949
950 Operation.__init__(self, **kwargs)
950 Operation.__init__(self, **kwargs)
951 self.profileIndex = 0
951 self.profileIndex = 0
952
952
953 def incProfileIndex(self):
953 def incProfileIndex(self):
954
954
955 self.profileIndex += 1
955 self.profileIndex += 1
956
956
957 if self.profileIndex >= self.nProfiles:
957 if self.profileIndex >= self.nProfiles:
958 self.profileIndex = 0
958 self.profileIndex = 0
959
959
960 def isThisProfileInRange(self, profileIndex, minIndex, maxIndex):
960 def isThisProfileInRange(self, profileIndex, minIndex, maxIndex):
961
961
962 if profileIndex < minIndex:
962 if profileIndex < minIndex:
963 return False
963 return False
964
964
965 if profileIndex > maxIndex:
965 if profileIndex > maxIndex:
966 return False
966 return False
967
967
968 return True
968 return True
969
969
970 def isThisProfileInList(self, profileIndex, profileList):
970 def isThisProfileInList(self, profileIndex, profileList):
971
971
972 if profileIndex not in profileList:
972 if profileIndex not in profileList:
973 return False
973 return False
974
974
975 return True
975 return True
976
976
977 def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None):
977 def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None):
978
978
979 """
979 """
980 ProfileSelector:
980 ProfileSelector:
981
981
982 Inputs:
982 Inputs:
983 profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8)
983 profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8)
984
984
985 profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30)
985 profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30)
986
986
987 rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256))
987 rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256))
988
988
989 """
989 """
990
990
991 if rangeList is not None:
991 if rangeList is not None:
992 if type(rangeList[0]) not in (tuple, list):
992 if type(rangeList[0]) not in (tuple, list):
993 rangeList = [rangeList]
993 rangeList = [rangeList]
994
994
995 dataOut.flagNoData = True
995 dataOut.flagNoData = True
996
996
997 if dataOut.flagDataAsBlock:
997 if dataOut.flagDataAsBlock:
998 """
998 """
999 data dimension = [nChannels, nProfiles, nHeis]
999 data dimension = [nChannels, nProfiles, nHeis]
1000 """
1000 """
1001 if profileList != None:
1001 if profileList != None:
1002 dataOut.data = dataOut.data[:,profileList,:]
1002 dataOut.data = dataOut.data[:,profileList,:]
1003
1003
1004 if profileRangeList != None:
1004 if profileRangeList != None:
1005 minIndex = profileRangeList[0]
1005 minIndex = profileRangeList[0]
1006 maxIndex = profileRangeList[1]
1006 maxIndex = profileRangeList[1]
1007 profileList = list(range(minIndex, maxIndex+1))
1007 profileList = list(range(minIndex, maxIndex+1))
1008
1008
1009 dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:]
1009 dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:]
1010
1010
1011 if rangeList != None:
1011 if rangeList != None:
1012
1012
1013 profileList = []
1013 profileList = []
1014
1014
1015 for thisRange in rangeList:
1015 for thisRange in rangeList:
1016 minIndex = thisRange[0]
1016 minIndex = thisRange[0]
1017 maxIndex = thisRange[1]
1017 maxIndex = thisRange[1]
1018
1018
1019 profileList.extend(list(range(minIndex, maxIndex+1)))
1019 profileList.extend(list(range(minIndex, maxIndex+1)))
1020
1020
1021 dataOut.data = dataOut.data[:,profileList,:]
1021 dataOut.data = dataOut.data[:,profileList,:]
1022
1022
1023 dataOut.nProfiles = len(profileList)
1023 dataOut.nProfiles = len(profileList)
1024 dataOut.profileIndex = dataOut.nProfiles - 1
1024 dataOut.profileIndex = dataOut.nProfiles - 1
1025 dataOut.flagNoData = False
1025 dataOut.flagNoData = False
1026
1026
1027 return dataOut
1027 return dataOut
1028
1028
1029 """
1029 """
1030 data dimension = [nChannels, nHeis]
1030 data dimension = [nChannels, nHeis]
1031 """
1031 """
1032
1032
1033 if profileList != None:
1033 if profileList != None:
1034
1034
1035 if self.isThisProfileInList(dataOut.profileIndex, profileList):
1035 if self.isThisProfileInList(dataOut.profileIndex, profileList):
1036
1036
1037 self.nProfiles = len(profileList)
1037 self.nProfiles = len(profileList)
1038 dataOut.nProfiles = self.nProfiles
1038 dataOut.nProfiles = self.nProfiles
1039 dataOut.profileIndex = self.profileIndex
1039 dataOut.profileIndex = self.profileIndex
1040 dataOut.flagNoData = False
1040 dataOut.flagNoData = False
1041
1041
1042 self.incProfileIndex()
1042 self.incProfileIndex()
1043 return dataOut
1043 return dataOut
1044
1044
1045 if profileRangeList != None:
1045 if profileRangeList != None:
1046
1046
1047 minIndex = profileRangeList[0]
1047 minIndex = profileRangeList[0]
1048 maxIndex = profileRangeList[1]
1048 maxIndex = profileRangeList[1]
1049
1049
1050 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1050 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1051
1051
1052 self.nProfiles = maxIndex - minIndex + 1
1052 self.nProfiles = maxIndex - minIndex + 1
1053 dataOut.nProfiles = self.nProfiles
1053 dataOut.nProfiles = self.nProfiles
1054 dataOut.profileIndex = self.profileIndex
1054 dataOut.profileIndex = self.profileIndex
1055 dataOut.flagNoData = False
1055 dataOut.flagNoData = False
1056
1056
1057 self.incProfileIndex()
1057 self.incProfileIndex()
1058 return dataOut
1058 return dataOut
1059
1059
1060 if rangeList != None:
1060 if rangeList != None:
1061
1061
1062 nProfiles = 0
1062 nProfiles = 0
1063
1063
1064 for thisRange in rangeList:
1064 for thisRange in rangeList:
1065 minIndex = thisRange[0]
1065 minIndex = thisRange[0]
1066 maxIndex = thisRange[1]
1066 maxIndex = thisRange[1]
1067
1067
1068 nProfiles += maxIndex - minIndex + 1
1068 nProfiles += maxIndex - minIndex + 1
1069
1069
1070 for thisRange in rangeList:
1070 for thisRange in rangeList:
1071
1071
1072 minIndex = thisRange[0]
1072 minIndex = thisRange[0]
1073 maxIndex = thisRange[1]
1073 maxIndex = thisRange[1]
1074
1074
1075 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1075 if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex):
1076
1076
1077 self.nProfiles = nProfiles
1077 self.nProfiles = nProfiles
1078 dataOut.nProfiles = self.nProfiles
1078 dataOut.nProfiles = self.nProfiles
1079 dataOut.profileIndex = self.profileIndex
1079 dataOut.profileIndex = self.profileIndex
1080 dataOut.flagNoData = False
1080 dataOut.flagNoData = False
1081
1081
1082 self.incProfileIndex()
1082 self.incProfileIndex()
1083
1083
1084 break
1084 break
1085
1085
1086 return dataOut
1086 return dataOut
1087
1087
1088
1088
1089 if beam != None: #beam is only for AMISR data
1089 if beam != None: #beam is only for AMISR data
1090 if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]):
1090 if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]):
1091 dataOut.flagNoData = False
1091 dataOut.flagNoData = False
1092 dataOut.profileIndex = self.profileIndex
1092 dataOut.profileIndex = self.profileIndex
1093
1093
1094 self.incProfileIndex()
1094 self.incProfileIndex()
1095
1095
1096 return dataOut
1096 return dataOut
1097
1097
1098 raise ValueError("ProfileSelector needs profileList, profileRangeList or rangeList parameter")
1098 raise ValueError("ProfileSelector needs profileList, profileRangeList or rangeList parameter")
1099
1099
1100
1100
1101 class Reshaper(Operation):
1101 class Reshaper(Operation):
1102
1102
1103 def __init__(self, **kwargs):
1103 def __init__(self, **kwargs):
1104
1104
1105 Operation.__init__(self, **kwargs)
1105 Operation.__init__(self, **kwargs)
1106
1106
1107 self.__buffer = None
1107 self.__buffer = None
1108 self.__nitems = 0
1108 self.__nitems = 0
1109
1109
1110 def __appendProfile(self, dataOut, nTxs):
1110 def __appendProfile(self, dataOut, nTxs):
1111
1111
1112 if self.__buffer is None:
1112 if self.__buffer is None:
1113 shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) )
1113 shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) )
1114 self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype)
1114 self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype)
1115
1115
1116 ini = dataOut.nHeights * self.__nitems
1116 ini = dataOut.nHeights * self.__nitems
1117 end = ini + dataOut.nHeights
1117 end = ini + dataOut.nHeights
1118
1118
1119 self.__buffer[:, ini:end] = dataOut.data
1119 self.__buffer[:, ini:end] = dataOut.data
1120
1120
1121 self.__nitems += 1
1121 self.__nitems += 1
1122
1122
1123 return int(self.__nitems*nTxs)
1123 return int(self.__nitems*nTxs)
1124
1124
1125 def __getBuffer(self):
1125 def __getBuffer(self):
1126
1126
1127 if self.__nitems == int(1./self.__nTxs):
1127 if self.__nitems == int(1./self.__nTxs):
1128
1128
1129 self.__nitems = 0
1129 self.__nitems = 0
1130
1130
1131 return self.__buffer.copy()
1131 return self.__buffer.copy()
1132
1132
1133 return None
1133 return None
1134
1134
1135 def __checkInputs(self, dataOut, shape, nTxs):
1135 def __checkInputs(self, dataOut, shape, nTxs):
1136
1136
1137 if shape is None and nTxs is None:
1137 if shape is None and nTxs is None:
1138 raise ValueError("Reshaper: shape of factor should be defined")
1138 raise ValueError("Reshaper: shape of factor should be defined")
1139
1139
1140 if nTxs:
1140 if nTxs:
1141 if nTxs < 0:
1141 if nTxs < 0:
1142 raise ValueError("nTxs should be greater than 0")
1142 raise ValueError("nTxs should be greater than 0")
1143
1143
1144 if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0:
1144 if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0:
1145 raise ValueError("nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs)))
1145 raise ValueError("nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs)))
1146
1146
1147 shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs]
1147 shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs]
1148
1148
1149 return shape, nTxs
1149 return shape, nTxs
1150
1150
1151 if len(shape) != 2 and len(shape) != 3:
1151 if len(shape) != 2 and len(shape) != 3:
1152 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))
1152 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))
1153
1153
1154 if len(shape) == 2:
1154 if len(shape) == 2:
1155 shape_tuple = [dataOut.nChannels]
1155 shape_tuple = [dataOut.nChannels]
1156 shape_tuple.extend(shape)
1156 shape_tuple.extend(shape)
1157 else:
1157 else:
1158 shape_tuple = list(shape)
1158 shape_tuple = list(shape)
1159
1159
1160 nTxs = 1.0*shape_tuple[1]/dataOut.nProfiles
1160 nTxs = 1.0*shape_tuple[1]/dataOut.nProfiles
1161
1161
1162 return shape_tuple, nTxs
1162 return shape_tuple, nTxs
1163
1163
1164 def run(self, dataOut, shape=None, nTxs=None):
1164 def run(self, dataOut, shape=None, nTxs=None):
1165
1165
1166 shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs)
1166 shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs)
1167
1167
1168 dataOut.flagNoData = True
1168 dataOut.flagNoData = True
1169 profileIndex = None
1169 profileIndex = None
1170
1170
1171 if dataOut.flagDataAsBlock:
1171 if dataOut.flagDataAsBlock:
1172
1172
1173 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
1173 dataOut.data = numpy.reshape(dataOut.data, shape_tuple)
1174 dataOut.flagNoData = False
1174 dataOut.flagNoData = False
1175
1175
1176 profileIndex = int(dataOut.nProfiles*self.__nTxs) - 1
1176 profileIndex = int(dataOut.nProfiles*self.__nTxs) - 1
1177
1177
1178 else:
1178 else:
1179
1179
1180 if self.__nTxs < 1:
1180 if self.__nTxs < 1:
1181
1181
1182 self.__appendProfile(dataOut, self.__nTxs)
1182 self.__appendProfile(dataOut, self.__nTxs)
1183 new_data = self.__getBuffer()
1183 new_data = self.__getBuffer()
1184
1184
1185 if new_data is not None:
1185 if new_data is not None:
1186 dataOut.data = new_data
1186 dataOut.data = new_data
1187 dataOut.flagNoData = False
1187 dataOut.flagNoData = False
1188
1188
1189 profileIndex = dataOut.profileIndex*nTxs
1189 profileIndex = dataOut.profileIndex*nTxs
1190
1190
1191 else:
1191 else:
1192 raise ValueError("nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)")
1192 raise ValueError("nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)")
1193
1193
1194 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1194 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1195
1195
1196 dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0]
1196 dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0]
1197
1197
1198 dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs)
1198 dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs)
1199
1199
1200 dataOut.profileIndex = profileIndex
1200 dataOut.profileIndex = profileIndex
1201
1201
1202 dataOut.ippSeconds /= self.__nTxs
1202 dataOut.ippSeconds /= self.__nTxs
1203
1203
1204 return dataOut
1204 return dataOut
1205
1205
1206 class SplitProfiles(Operation):
1206 class SplitProfiles(Operation):
1207
1207
1208 def __init__(self, **kwargs):
1208 def __init__(self, **kwargs):
1209
1209
1210 Operation.__init__(self, **kwargs)
1210 Operation.__init__(self, **kwargs)
1211
1211
1212 def run(self, dataOut, n):
1212 def run(self, dataOut, n):
1213
1213
1214 dataOut.flagNoData = True
1214 dataOut.flagNoData = True
1215 profileIndex = None
1215 profileIndex = None
1216
1216
1217 if dataOut.flagDataAsBlock:
1217 if dataOut.flagDataAsBlock:
1218
1218
1219 #nchannels, nprofiles, nsamples
1219 #nchannels, nprofiles, nsamples
1220 shape = dataOut.data.shape
1220 shape = dataOut.data.shape
1221
1221
1222 if shape[2] % n != 0:
1222 if shape[2] % n != 0:
1223 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[2]))
1223 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[2]))
1224
1224
1225 new_shape = shape[0], shape[1]*n, int(shape[2]/n)
1225 new_shape = shape[0], shape[1]*n, int(shape[2]/n)
1226
1226
1227 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1227 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1228 dataOut.flagNoData = False
1228 dataOut.flagNoData = False
1229
1229
1230 profileIndex = int(dataOut.nProfiles/n) - 1
1230 profileIndex = int(dataOut.nProfiles/n) - 1
1231
1231
1232 else:
1232 else:
1233
1233
1234 raise ValueError("Could not split the data when is read Profile by Profile. Use VoltageReader(..., getblock=True)")
1234 raise ValueError("Could not split the data when is read Profile by Profile. Use VoltageReader(..., getblock=True)")
1235
1235
1236 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1236 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1237
1237
1238 dataOut.heightList = numpy.arange(dataOut.nHeights/n) * deltaHeight + dataOut.heightList[0]
1238 dataOut.heightList = numpy.arange(dataOut.nHeights/n) * deltaHeight + dataOut.heightList[0]
1239
1239
1240 dataOut.nProfiles = int(dataOut.nProfiles*n)
1240 dataOut.nProfiles = int(dataOut.nProfiles*n)
1241
1241
1242 dataOut.profileIndex = profileIndex
1242 dataOut.profileIndex = profileIndex
1243
1243
1244 dataOut.ippSeconds /= n
1244 dataOut.ippSeconds /= n
1245
1245
1246 return dataOut
1246 return dataOut
1247
1247
1248 class CombineProfiles(Operation):
1248 class CombineProfiles(Operation):
1249 def __init__(self, **kwargs):
1249 def __init__(self, **kwargs):
1250
1250
1251 Operation.__init__(self, **kwargs)
1251 Operation.__init__(self, **kwargs)
1252
1252
1253 self.__remData = None
1253 self.__remData = None
1254 self.__profileIndex = 0
1254 self.__profileIndex = 0
1255
1255
1256 def run(self, dataOut, n):
1256 def run(self, dataOut, n):
1257
1257
1258 dataOut.flagNoData = True
1258 dataOut.flagNoData = True
1259 profileIndex = None
1259 profileIndex = None
1260
1260
1261 if dataOut.flagDataAsBlock:
1261 if dataOut.flagDataAsBlock:
1262
1262
1263 #nchannels, nprofiles, nsamples
1263 #nchannels, nprofiles, nsamples
1264 shape = dataOut.data.shape
1264 shape = dataOut.data.shape
1265 new_shape = shape[0], shape[1]/n, shape[2]*n
1265 new_shape = shape[0], shape[1]/n, shape[2]*n
1266
1266
1267 if shape[1] % n != 0:
1267 if shape[1] % n != 0:
1268 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[1]))
1268 raise ValueError("Could not split the data, n=%d has to be multiple of %d" %(n, shape[1]))
1269
1269
1270 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1270 dataOut.data = numpy.reshape(dataOut.data, new_shape)
1271 dataOut.flagNoData = False
1271 dataOut.flagNoData = False
1272
1272
1273 profileIndex = int(dataOut.nProfiles*n) - 1
1273 profileIndex = int(dataOut.nProfiles*n) - 1
1274
1274
1275 else:
1275 else:
1276
1276
1277 #nchannels, nsamples
1277 #nchannels, nsamples
1278 if self.__remData is None:
1278 if self.__remData is None:
1279 newData = dataOut.data
1279 newData = dataOut.data
1280 else:
1280 else:
1281 newData = numpy.concatenate((self.__remData, dataOut.data), axis=1)
1281 newData = numpy.concatenate((self.__remData, dataOut.data), axis=1)
1282
1282
1283 self.__profileIndex += 1
1283 self.__profileIndex += 1
1284
1284
1285 if self.__profileIndex < n:
1285 if self.__profileIndex < n:
1286 self.__remData = newData
1286 self.__remData = newData
1287 #continue
1287 #continue
1288 return
1288 return
1289
1289
1290 self.__profileIndex = 0
1290 self.__profileIndex = 0
1291 self.__remData = None
1291 self.__remData = None
1292
1292
1293 dataOut.data = newData
1293 dataOut.data = newData
1294 dataOut.flagNoData = False
1294 dataOut.flagNoData = False
1295
1295
1296 profileIndex = dataOut.profileIndex/n
1296 profileIndex = dataOut.profileIndex/n
1297
1297
1298
1298
1299 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1299 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1300
1300
1301 dataOut.heightList = numpy.arange(dataOut.nHeights*n) * deltaHeight + dataOut.heightList[0]
1301 dataOut.heightList = numpy.arange(dataOut.nHeights*n) * deltaHeight + dataOut.heightList[0]
1302
1302
1303 dataOut.nProfiles = int(dataOut.nProfiles/n)
1303 dataOut.nProfiles = int(dataOut.nProfiles/n)
1304
1304
1305 dataOut.profileIndex = profileIndex
1305 dataOut.profileIndex = profileIndex
1306
1306
1307 dataOut.ippSeconds *= n
1307 dataOut.ippSeconds *= n
1308
1308
1309 return dataOut
1309 return dataOut
1310
1310
1311 class PulsePairVoltage(Operation):
1311 class PulsePairVoltage(Operation):
1312 '''
1312 '''
1313 Function PulsePair(Signal Power, Velocity)
1313 Function PulsePair(Signal Power, Velocity)
1314 The real component of Lag[0] provides Intensity Information
1314 The real component of Lag[0] provides Intensity Information
1315 The imag component of Lag[1] Phase provides Velocity Information
1315 The imag component of Lag[1] Phase provides Velocity Information
1316
1316
1317 Configuration Parameters:
1317 Configuration Parameters:
1318 nPRF = Number of Several PRF
1318 nPRF = Number of Several PRF
1319 theta = Degree Azimuth angel Boundaries
1319 theta = Degree Azimuth angel Boundaries
1320
1320
1321 Input:
1321 Input:
1322 self.dataOut
1322 self.dataOut
1323 lag[N]
1323 lag[N]
1324 Affected:
1324 Affected:
1325 self.dataOut.spc
1325 self.dataOut.spc
1326 '''
1326 '''
1327 isConfig = False
1327 isConfig = False
1328 __profIndex = 0
1328 __profIndex = 0
1329 __initime = None
1329 __initime = None
1330 __lastdatatime = None
1330 __lastdatatime = None
1331 __buffer = None
1331 __buffer = None
1332 noise = None
1332 noise = None
1333 __dataReady = False
1333 __dataReady = False
1334 n = None
1334 n = None
1335 __nch = 0
1335 __nch = 0
1336 __nHeis = 0
1336 __nHeis = 0
1337 removeDC = False
1337 removeDC = False
1338 ipp = None
1338 ipp = None
1339 lambda_ = 0
1339 lambda_ = 0
1340
1340
1341 def __init__(self,**kwargs):
1341 def __init__(self,**kwargs):
1342 Operation.__init__(self,**kwargs)
1342 Operation.__init__(self,**kwargs)
1343
1343
1344 def setup(self, dataOut, n = None, removeDC=False):
1344 def setup(self, dataOut, n = None, removeDC=False):
1345 '''
1345 '''
1346 n= Numero de PRF's de entrada
1346 n= Numero de PRF's de entrada
1347 '''
1347 '''
1348 self.__initime = None
1348 self.__initime = None
1349 self.__lastdatatime = 0
1349 self.__lastdatatime = 0
1350 self.__dataReady = False
1350 self.__dataReady = False
1351 self.__buffer = 0
1351 self.__buffer = 0
1352 self.__profIndex = 0
1352 self.__profIndex = 0
1353 self.noise = None
1353 self.noise = None
1354 self.__nch = dataOut.nChannels
1354 self.__nch = dataOut.nChannels
1355 self.__nHeis = dataOut.nHeights
1355 self.__nHeis = dataOut.nHeights
1356 self.removeDC = removeDC
1356 self.removeDC = removeDC
1357 self.lambda_ = 3.0e8/(9345.0e6)
1357 self.lambda_ = 3.0e8/(9345.0e6)
1358 self.ippSec = dataOut.ippSeconds
1358 self.ippSec = dataOut.ippSeconds
1359 self.nCohInt = dataOut.nCohInt
1359 self.nCohInt = dataOut.nCohInt
1360
1360
1361 if n == None:
1361 if n == None:
1362 raise ValueError("n should be specified.")
1362 raise ValueError("n should be specified.")
1363
1363
1364 if n != None:
1364 if n != None:
1365 if n<2:
1365 if n<2:
1366 raise ValueError("n should be greater than 2")
1366 raise ValueError("n should be greater than 2")
1367
1367
1368 self.n = n
1368 self.n = n
1369 self.__nProf = n
1369 self.__nProf = n
1370
1370
1371 self.__buffer = numpy.zeros((dataOut.nChannels,
1371 self.__buffer = numpy.zeros((dataOut.nChannels,
1372 n,
1372 n,
1373 dataOut.nHeights),
1373 dataOut.nHeights),
1374 dtype='complex')
1374 dtype='complex')
1375
1375
1376 def putData(self,data):
1376 def putData(self,data):
1377 '''
1377 '''
1378 Add a profile to he __buffer and increase in one the __profiel Index
1378 Add a profile to he __buffer and increase in one the __profiel Index
1379 '''
1379 '''
1380 self.__buffer[:,self.__profIndex,:]= data
1380 self.__buffer[:,self.__profIndex,:]= data
1381 self.__profIndex += 1
1381 self.__profIndex += 1
1382 return
1382 return
1383
1383
1384 def pushData(self,dataOut):
1384 def pushData(self,dataOut):
1385 '''
1385 '''
1386 Return the PULSEPAIR and the profiles used in the operation
1386 Return the PULSEPAIR and the profiles used in the operation
1387 Affected : self.__profileIndex
1387 Affected : self.__profileIndex
1388 '''
1388 '''
1389 #----------------- Remove DC-----------------------------------
1389 #----------------- Remove DC-----------------------------------
1390 if self.removeDC==True:
1390 if self.removeDC==True:
1391 mean = numpy.mean(self.__buffer,1)
1391 mean = numpy.mean(self.__buffer,1)
1392 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1392 tmp = mean.reshape(self.__nch,1,self.__nHeis)
1393 dc= numpy.tile(tmp,[1,self.__nProf,1])
1393 dc= numpy.tile(tmp,[1,self.__nProf,1])
1394 self.__buffer = self.__buffer - dc
1394 self.__buffer = self.__buffer - dc
1395 #------------------Calculo de Potencia ------------------------
1395 #------------------Calculo de Potencia ------------------------
1396 pair0 = self.__buffer*numpy.conj(self.__buffer)
1396 pair0 = self.__buffer*numpy.conj(self.__buffer)
1397 pair0 = pair0.real
1397 pair0 = pair0.real
1398 lag_0 = numpy.sum(pair0,1)
1398 lag_0 = numpy.sum(pair0,1)
1399 #------------------Calculo de Ruido x canal--------------------
1399 #------------------Calculo de Ruido x canal--------------------
1400 self.noise = numpy.zeros(self.__nch)
1400 self.noise = numpy.zeros(self.__nch)
1401 for i in range(self.__nch):
1401 for i in range(self.__nch):
1402 daux = numpy.sort(pair0[i,:,:],axis= None)
1402 daux = numpy.sort(pair0[i,:,:],axis= None)
1403 self.noise[i]=hildebrand_sekhon( daux ,self.nCohInt)
1403 self.noise[i]=hildebrand_sekhon( daux ,self.nCohInt)
1404
1404
1405 self.noise = self.noise.reshape(self.__nch,1)
1405 self.noise = self.noise.reshape(self.__nch,1)
1406 self.noise = numpy.tile(self.noise,[1,self.__nHeis])
1406 self.noise = numpy.tile(self.noise,[1,self.__nHeis])
1407 noise_buffer = self.noise.reshape(self.__nch,1,self.__nHeis)
1407 noise_buffer = self.noise.reshape(self.__nch,1,self.__nHeis)
1408 noise_buffer = numpy.tile(noise_buffer,[1,self.__nProf,1])
1408 noise_buffer = numpy.tile(noise_buffer,[1,self.__nProf,1])
1409 #------------------ Potencia recibida= P , Potencia senal = S , Ruido= N--
1409 #------------------ Potencia recibida= P , Potencia senal = S , Ruido= N--
1410 #------------------ P= S+N ,P=lag_0/N ---------------------------------
1410 #------------------ P= S+N ,P=lag_0/N ---------------------------------
1411 #-------------------- Power --------------------------------------------------
1411 #-------------------- Power --------------------------------------------------
1412 data_power = lag_0/(self.n*self.nCohInt)
1412 data_power = lag_0/(self.n*self.nCohInt)
1413 #------------------ Senal ---------------------------------------------------
1413 #------------------ Senal ---------------------------------------------------
1414 data_intensity = pair0 - noise_buffer
1414 data_intensity = pair0 - noise_buffer
1415 data_intensity = numpy.sum(data_intensity,axis=1)*(self.n*self.nCohInt)#*self.nCohInt)
1415 data_intensity = numpy.sum(data_intensity,axis=1)*(self.n*self.nCohInt)#*self.nCohInt)
1416 #data_intensity = (lag_0-self.noise*self.n)*(self.n*self.nCohInt)
1416 #data_intensity = (lag_0-self.noise*self.n)*(self.n*self.nCohInt)
1417 for i in range(self.__nch):
1417 for i in range(self.__nch):
1418 for j in range(self.__nHeis):
1418 for j in range(self.__nHeis):
1419 if data_intensity[i][j] < 0:
1419 if data_intensity[i][j] < 0:
1420 data_intensity[i][j] = numpy.min(numpy.absolute(data_intensity[i][j]))
1420 data_intensity[i][j] = numpy.min(numpy.absolute(data_intensity[i][j]))
1421
1421
1422 #----------------- Calculo de Frecuencia y Velocidad doppler--------
1422 #----------------- Calculo de Frecuencia y Velocidad doppler--------
1423 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1423 pair1 = self.__buffer[:,:-1,:]*numpy.conjugate(self.__buffer[:,1:,:])
1424 lag_1 = numpy.sum(pair1,1)
1424 lag_1 = numpy.sum(pair1,1)
1425 data_freq = (-1/(2.0*math.pi*self.ippSec*self.nCohInt))*numpy.angle(lag_1)
1425 data_freq = (-1/(2.0*math.pi*self.ippSec*self.nCohInt))*numpy.angle(lag_1)
1426 data_velocity = (self.lambda_/2.0)*data_freq
1426 data_velocity = (self.lambda_/2.0)*data_freq
1427
1427
1428 #---------------- Potencia promedio estimada de la Senal-----------
1428 #---------------- Potencia promedio estimada de la Senal-----------
1429 lag_0 = lag_0/self.n
1429 lag_0 = lag_0/self.n
1430 S = lag_0-self.noise
1430 S = lag_0-self.noise
1431
1431
1432 #---------------- Frecuencia Doppler promedio ---------------------
1432 #---------------- Frecuencia Doppler promedio ---------------------
1433 lag_1 = lag_1/(self.n-1)
1433 lag_1 = lag_1/(self.n-1)
1434 R1 = numpy.abs(lag_1)
1434 R1 = numpy.abs(lag_1)
1435
1435
1436 #---------------- Calculo del SNR----------------------------------
1436 #---------------- Calculo del SNR----------------------------------
1437 data_snrPP = S/self.noise
1437 data_snrPP = S/self.noise
1438 for i in range(self.__nch):
1438 for i in range(self.__nch):
1439 for j in range(self.__nHeis):
1439 for j in range(self.__nHeis):
1440 if data_snrPP[i][j] < 1.e-20:
1440 if data_snrPP[i][j] < 1.e-20:
1441 data_snrPP[i][j] = 1.e-20
1441 data_snrPP[i][j] = 1.e-20
1442
1442
1443 #----------------- Calculo del ancho espectral ----------------------
1443 #----------------- Calculo del ancho espectral ----------------------
1444 L = S/R1
1444 L = S/R1
1445 L = numpy.where(L<0,1,L)
1445 L = numpy.where(L<0,1,L)
1446 L = numpy.log(L)
1446 L = numpy.log(L)
1447 tmp = numpy.sqrt(numpy.absolute(L))
1447 tmp = numpy.sqrt(numpy.absolute(L))
1448 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec*self.nCohInt))*tmp*numpy.sign(L)
1448 data_specwidth = (self.lambda_/(2*math.sqrt(2)*math.pi*self.ippSec*self.nCohInt))*tmp*numpy.sign(L)
1449 n = self.__profIndex
1449 n = self.__profIndex
1450
1450
1451 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1451 self.__buffer = numpy.zeros((self.__nch, self.__nProf,self.__nHeis), dtype='complex')
1452 self.__profIndex = 0
1452 self.__profIndex = 0
1453 return data_power,data_intensity,data_velocity,data_snrPP,data_specwidth,n
1453 return data_power,data_intensity,data_velocity,data_snrPP,data_specwidth,n
1454
1454
1455
1455
1456 def pulsePairbyProfiles(self,dataOut):
1456 def pulsePairbyProfiles(self,dataOut):
1457
1457
1458 self.__dataReady = False
1458 self.__dataReady = False
1459 data_power = None
1459 data_power = None
1460 data_intensity = None
1460 data_intensity = None
1461 data_velocity = None
1461 data_velocity = None
1462 data_specwidth = None
1462 data_specwidth = None
1463 data_snrPP = None
1463 data_snrPP = None
1464 self.putData(data=dataOut.data)
1464 self.putData(data=dataOut.data)
1465 if self.__profIndex == self.n:
1465 if self.__profIndex == self.n:
1466 data_power,data_intensity, data_velocity,data_snrPP,data_specwidth, n = self.pushData(dataOut=dataOut)
1466 data_power,data_intensity, data_velocity,data_snrPP,data_specwidth, n = self.pushData(dataOut=dataOut)
1467 self.__dataReady = True
1467 self.__dataReady = True
1468
1468
1469 return data_power, data_intensity, data_velocity, data_snrPP, data_specwidth
1469 return data_power, data_intensity, data_velocity, data_snrPP, data_specwidth
1470
1470
1471
1471
1472 def pulsePairOp(self, dataOut, datatime= None):
1472 def pulsePairOp(self, dataOut, datatime= None):
1473
1473
1474 if self.__initime == None:
1474 if self.__initime == None:
1475 self.__initime = datatime
1475 self.__initime = datatime
1476 data_power, data_intensity, data_velocity, data_snrPP, data_specwidth = self.pulsePairbyProfiles(dataOut)
1476 data_power, data_intensity, data_velocity, data_snrPP, data_specwidth = self.pulsePairbyProfiles(dataOut)
1477 self.__lastdatatime = datatime
1477 self.__lastdatatime = datatime
1478
1478
1479 if data_power is None:
1479 if data_power is None:
1480 return None, None, None,None,None,None
1480 return None, None, None,None,None,None
1481
1481
1482 avgdatatime = self.__initime
1482 avgdatatime = self.__initime
1483 deltatime = datatime - self.__lastdatatime
1483 deltatime = datatime - self.__lastdatatime
1484 self.__initime = datatime
1484 self.__initime = datatime
1485
1485
1486 return data_power, data_intensity, data_velocity, data_snrPP, data_specwidth, avgdatatime
1486 return data_power, data_intensity, data_velocity, data_snrPP, data_specwidth, avgdatatime
1487
1487
1488 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1488 def run(self, dataOut,n = None,removeDC= False, overlapping= False,**kwargs):
1489
1489
1490 if not self.isConfig:
1490 if not self.isConfig:
1491 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1491 self.setup(dataOut = dataOut, n = n , removeDC=removeDC , **kwargs)
1492 self.isConfig = True
1492 self.isConfig = True
1493 data_power, data_intensity, data_velocity,data_snrPP,data_specwidth, avgdatatime = self.pulsePairOp(dataOut, dataOut.utctime)
1493 data_power, data_intensity, data_velocity,data_snrPP,data_specwidth, avgdatatime = self.pulsePairOp(dataOut, dataOut.utctime)
1494 dataOut.flagNoData = True
1494 dataOut.flagNoData = True
1495
1495
1496 if self.__dataReady:
1496 if self.__dataReady:
1497 dataOut.nCohInt *= self.n
1497 dataOut.nCohInt *= self.n
1498 dataOut.dataPP_POW = data_intensity # S
1498 dataOut.dataPP_POW = data_intensity # S
1499 dataOut.dataPP_POWER = data_power # P
1499 dataOut.dataPP_POWER = data_power # P
1500 dataOut.dataPP_DOP = data_velocity
1500 dataOut.dataPP_DOP = data_velocity
1501 dataOut.dataPP_SNR = data_snrPP
1501 dataOut.dataPP_SNR = data_snrPP
1502 dataOut.dataPP_WIDTH = data_specwidth
1502 dataOut.dataPP_WIDTH = data_specwidth
1503 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1503 dataOut.PRFbyAngle = self.n #numero de PRF*cada angulo rotado que equivale a un tiempo.
1504 dataOut.utctime = avgdatatime
1504 dataOut.utctime = avgdatatime
1505 dataOut.flagNoData = False
1505 dataOut.flagNoData = False
1506 return dataOut
1506 return dataOut
1507
1507
1508
1508
1509
1509
1510 # import collections
1510 # import collections
1511 # from scipy.stats import mode
1511 # from scipy.stats import mode
1512 #
1512 #
1513 # class Synchronize(Operation):
1513 # class Synchronize(Operation):
1514 #
1514 #
1515 # isConfig = False
1515 # isConfig = False
1516 # __profIndex = 0
1516 # __profIndex = 0
1517 #
1517 #
1518 # def __init__(self, **kwargs):
1518 # def __init__(self, **kwargs):
1519 #
1519 #
1520 # Operation.__init__(self, **kwargs)
1520 # Operation.__init__(self, **kwargs)
1521 # # self.isConfig = False
1521 # # self.isConfig = False
1522 # self.__powBuffer = None
1522 # self.__powBuffer = None
1523 # self.__startIndex = 0
1523 # self.__startIndex = 0
1524 # self.__pulseFound = False
1524 # self.__pulseFound = False
1525 #
1525 #
1526 # def __findTxPulse(self, dataOut, channel=0, pulse_with = None):
1526 # def __findTxPulse(self, dataOut, channel=0, pulse_with = None):
1527 #
1527 #
1528 # #Read data
1528 # #Read data
1529 #
1529 #
1530 # powerdB = dataOut.getPower(channel = channel)
1530 # powerdB = dataOut.getPower(channel = channel)
1531 # noisedB = dataOut.getNoise(channel = channel)[0]
1531 # noisedB = dataOut.getNoise(channel = channel)[0]
1532 #
1532 #
1533 # self.__powBuffer.extend(powerdB.flatten())
1533 # self.__powBuffer.extend(powerdB.flatten())
1534 #
1534 #
1535 # dataArray = numpy.array(self.__powBuffer)
1535 # dataArray = numpy.array(self.__powBuffer)
1536 #
1536 #
1537 # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same")
1537 # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same")
1538 #
1538 #
1539 # maxValue = numpy.nanmax(filteredPower)
1539 # maxValue = numpy.nanmax(filteredPower)
1540 #
1540 #
1541 # if maxValue < noisedB + 10:
1541 # if maxValue < noisedB + 10:
1542 # #No se encuentra ningun pulso de transmision
1542 # #No se encuentra ningun pulso de transmision
1543 # return None
1543 # return None
1544 #
1544 #
1545 # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0]
1545 # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0]
1546 #
1546 #
1547 # if len(maxValuesIndex) < 2:
1547 # if len(maxValuesIndex) < 2:
1548 # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX
1548 # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX
1549 # return None
1549 # return None
1550 #
1550 #
1551 # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples
1551 # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples
1552 #
1552 #
1553 # #Seleccionar solo valores con un espaciamiento de nSamples
1553 # #Seleccionar solo valores con un espaciamiento de nSamples
1554 # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex)
1554 # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex)
1555 #
1555 #
1556 # if len(pulseIndex) < 2:
1556 # if len(pulseIndex) < 2:
1557 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1557 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1558 # return None
1558 # return None
1559 #
1559 #
1560 # spacing = pulseIndex[1:] - pulseIndex[:-1]
1560 # spacing = pulseIndex[1:] - pulseIndex[:-1]
1561 #
1561 #
1562 # #remover senales que se distancien menos de 10 unidades o muestras
1562 # #remover senales que se distancien menos de 10 unidades o muestras
1563 # #(No deberian existir IPP menor a 10 unidades)
1563 # #(No deberian existir IPP menor a 10 unidades)
1564 #
1564 #
1565 # realIndex = numpy.where(spacing > 10 )[0]
1565 # realIndex = numpy.where(spacing > 10 )[0]
1566 #
1566 #
1567 # if len(realIndex) < 2:
1567 # if len(realIndex) < 2:
1568 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1568 # #Solo se encontro un pulso de transmision con ancho mayor a 1
1569 # return None
1569 # return None
1570 #
1570 #
1571 # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs)
1571 # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs)
1572 # realPulseIndex = pulseIndex[realIndex]
1572 # realPulseIndex = pulseIndex[realIndex]
1573 #
1573 #
1574 # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0]
1574 # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0]
1575 #
1575 #
1576 # print "IPP = %d samples" %period
1576 # print "IPP = %d samples" %period
1577 #
1577 #
1578 # self.__newNSamples = dataOut.nHeights #int(period)
1578 # self.__newNSamples = dataOut.nHeights #int(period)
1579 # self.__startIndex = int(realPulseIndex[0])
1579 # self.__startIndex = int(realPulseIndex[0])
1580 #
1580 #
1581 # return 1
1581 # return 1
1582 #
1582 #
1583 #
1583 #
1584 # def setup(self, nSamples, nChannels, buffer_size = 4):
1584 # def setup(self, nSamples, nChannels, buffer_size = 4):
1585 #
1585 #
1586 # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float),
1586 # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float),
1587 # maxlen = buffer_size*nSamples)
1587 # maxlen = buffer_size*nSamples)
1588 #
1588 #
1589 # bufferList = []
1589 # bufferList = []
1590 #
1590 #
1591 # for i in range(nChannels):
1591 # for i in range(nChannels):
1592 # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN,
1592 # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN,
1593 # maxlen = buffer_size*nSamples)
1593 # maxlen = buffer_size*nSamples)
1594 #
1594 #
1595 # bufferList.append(bufferByChannel)
1595 # bufferList.append(bufferByChannel)
1596 #
1596 #
1597 # self.__nSamples = nSamples
1597 # self.__nSamples = nSamples
1598 # self.__nChannels = nChannels
1598 # self.__nChannels = nChannels
1599 # self.__bufferList = bufferList
1599 # self.__bufferList = bufferList
1600 #
1600 #
1601 # def run(self, dataOut, channel = 0):
1601 # def run(self, dataOut, channel = 0):
1602 #
1602 #
1603 # if not self.isConfig:
1603 # if not self.isConfig:
1604 # nSamples = dataOut.nHeights
1604 # nSamples = dataOut.nHeights
1605 # nChannels = dataOut.nChannels
1605 # nChannels = dataOut.nChannels
1606 # self.setup(nSamples, nChannels)
1606 # self.setup(nSamples, nChannels)
1607 # self.isConfig = True
1607 # self.isConfig = True
1608 #
1608 #
1609 # #Append new data to internal buffer
1609 # #Append new data to internal buffer
1610 # for thisChannel in range(self.__nChannels):
1610 # for thisChannel in range(self.__nChannels):
1611 # bufferByChannel = self.__bufferList[thisChannel]
1611 # bufferByChannel = self.__bufferList[thisChannel]
1612 # bufferByChannel.extend(dataOut.data[thisChannel])
1612 # bufferByChannel.extend(dataOut.data[thisChannel])
1613 #
1613 #
1614 # if self.__pulseFound:
1614 # if self.__pulseFound:
1615 # self.__startIndex -= self.__nSamples
1615 # self.__startIndex -= self.__nSamples
1616 #
1616 #
1617 # #Finding Tx Pulse
1617 # #Finding Tx Pulse
1618 # if not self.__pulseFound:
1618 # if not self.__pulseFound:
1619 # indexFound = self.__findTxPulse(dataOut, channel)
1619 # indexFound = self.__findTxPulse(dataOut, channel)
1620 #
1620 #
1621 # if indexFound == None:
1621 # if indexFound == None:
1622 # dataOut.flagNoData = True
1622 # dataOut.flagNoData = True
1623 # return
1623 # return
1624 #
1624 #
1625 # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex)
1625 # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex)
1626 # self.__pulseFound = True
1626 # self.__pulseFound = True
1627 # self.__startIndex = indexFound
1627 # self.__startIndex = indexFound
1628 #
1628 #
1629 # #If pulse was found ...
1629 # #If pulse was found ...
1630 # for thisChannel in range(self.__nChannels):
1630 # for thisChannel in range(self.__nChannels):
1631 # bufferByChannel = self.__bufferList[thisChannel]
1631 # bufferByChannel = self.__bufferList[thisChannel]
1632 # #print self.__startIndex
1632 # #print self.__startIndex
1633 # x = numpy.array(bufferByChannel)
1633 # x = numpy.array(bufferByChannel)
1634 # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples]
1634 # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples]
1635 #
1635 #
1636 # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1636 # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1637 # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight
1637 # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight
1638 # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6
1638 # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6
1639 #
1639 #
1640 # dataOut.data = self.__arrayBuffer
1640 # dataOut.data = self.__arrayBuffer
1641 #
1641 #
1642 # self.__startIndex += self.__newNSamples
1642 # self.__startIndex += self.__newNSamples
1643 #
1643 #
1644 # return
1644 # return
1645 class SSheightProfiles(Operation):
1645 class SSheightProfiles(Operation):
1646
1646
1647 step = None
1647 step = None
1648 nsamples = None
1648 nsamples = None
1649 bufferShape = None
1649 bufferShape = None
1650 profileShape = None
1650 profileShape = None
1651 sshProfiles = None
1651 sshProfiles = None
1652 profileIndex = None
1652 profileIndex = None
1653
1653
1654 def __init__(self, **kwargs):
1654 def __init__(self, **kwargs):
1655
1655
1656 Operation.__init__(self, **kwargs)
1656 Operation.__init__(self, **kwargs)
1657 self.isConfig = False
1657 self.isConfig = False
1658
1658
1659 def setup(self,dataOut ,step = None , nsamples = None):
1659 def setup(self,dataOut ,step = None , nsamples = None):
1660
1660
1661 if step == None and nsamples == None:
1661 if step == None and nsamples == None:
1662 raise ValueError("step or nheights should be specified ...")
1662 raise ValueError("step or nheights should be specified ...")
1663
1663
1664 self.step = step
1664 self.step = step
1665 self.nsamples = nsamples
1665 self.nsamples = nsamples
1666 self.__nChannels = dataOut.nChannels
1666 self.__nChannels = dataOut.nChannels
1667 self.__nProfiles = dataOut.nProfiles
1667 self.__nProfiles = dataOut.nProfiles
1668 self.__nHeis = dataOut.nHeights
1668 self.__nHeis = dataOut.nHeights
1669 shape = dataOut.data.shape #nchannels, nprofiles, nsamples
1669 shape = dataOut.data.shape #nchannels, nprofiles, nsamples
1670
1670
1671 residue = (shape[1] - self.nsamples) % self.step
1671 residue = (shape[1] - self.nsamples) % self.step
1672 if residue != 0:
1672 if residue != 0:
1673 print("The residue is %d, step=%d should be multiple of %d to avoid loss of %d samples"%(residue,step,shape[1] - self.nsamples,residue))
1673 print("The residue is %d, step=%d should be multiple of %d to avoid loss of %d samples"%(residue,step,shape[1] - self.nsamples,residue))
1674
1674
1675 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1675 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1676 numberProfile = self.nsamples
1676 numberProfile = self.nsamples
1677 numberSamples = (shape[1] - self.nsamples)/self.step
1677 numberSamples = (shape[1] - self.nsamples)/self.step
1678
1678
1679 self.bufferShape = int(shape[0]), int(numberSamples), int(numberProfile) # nchannels, nsamples , nprofiles
1679 self.bufferShape = int(shape[0]), int(numberSamples), int(numberProfile) # nchannels, nsamples , nprofiles
1680 self.profileShape = int(shape[0]), int(numberProfile), int(numberSamples) # nchannels, nprofiles, nsamples
1680 self.profileShape = int(shape[0]), int(numberProfile), int(numberSamples) # nchannels, nprofiles, nsamples
1681
1681
1682 self.buffer = numpy.zeros(self.bufferShape , dtype=numpy.complex)
1682 self.buffer = numpy.zeros(self.bufferShape , dtype=numpy.complex)
1683 self.sshProfiles = numpy.zeros(self.profileShape, dtype=numpy.complex)
1683 self.sshProfiles = numpy.zeros(self.profileShape, dtype=numpy.complex)
1684
1684
1685 def run(self, dataOut, step, nsamples, code = None, repeat = None):
1685 def run(self, dataOut, step, nsamples, code = None, repeat = None):
1686 dataOut.flagNoData = True
1686 dataOut.flagNoData = True
1687
1687
1688 profileIndex = None
1688 profileIndex = None
1689 #print("nProfiles, nHeights ",dataOut.nProfiles, dataOut.nHeights)
1689 #print("nProfiles, nHeights ",dataOut.nProfiles, dataOut.nHeights)
1690 #print(dataOut.getFreqRange(1)/1000.)
1690 #print(dataOut.getFreqRange(1)/1000.)
1691 #exit(1)
1691 #exit(1)
1692 if dataOut.flagDataAsBlock:
1692 if dataOut.flagDataAsBlock:
1693 dataOut.data = numpy.average(dataOut.data,axis=1)
1693 dataOut.data = numpy.average(dataOut.data,axis=1)
1694 #print("jee")
1694 #print("jee")
1695 dataOut.flagDataAsBlock = False
1695 dataOut.flagDataAsBlock = False
1696 if not self.isConfig:
1696 if not self.isConfig:
1697 self.setup(dataOut, step=step , nsamples=nsamples)
1697 self.setup(dataOut, step=step , nsamples=nsamples)
1698 #print("Setup done")
1698 #print("Setup done")
1699 self.isConfig = True
1699 self.isConfig = True
1700
1700
1701
1701
1702 if code is not None:
1702 if code is not None:
1703 code = numpy.array(code)
1703 code = numpy.array(code)
1704 code_block = code
1704 code_block = code
1705
1705
1706 if repeat is not None:
1706 if repeat is not None:
1707 code_block = numpy.repeat(code_block, repeats=repeat, axis=1)
1707 code_block = numpy.repeat(code_block, repeats=repeat, axis=1)
1708 #print(code_block.shape)
1708 #print(code_block.shape)
1709 for i in range(self.buffer.shape[1]):
1709 for i in range(self.buffer.shape[1]):
1710
1710
1711 if code is not None:
1711 if code is not None:
1712 self.buffer[:,i] = dataOut.data[:,i*self.step:i*self.step + self.nsamples]*code_block
1712 self.buffer[:,i] = dataOut.data[:,i*self.step:i*self.step + self.nsamples]*code_block
1713
1713
1714 else:
1714 else:
1715
1715
1716 self.buffer[:,i] = dataOut.data[:,i*self.step:i*self.step + self.nsamples]#*code[dataOut.profileIndex,:]
1716 self.buffer[:,i] = dataOut.data[:,i*self.step:i*self.step + self.nsamples]#*code[dataOut.profileIndex,:]
1717
1717
1718 #self.buffer[:,j,self.__nHeis-j*self.step - self.nheights:self.__nHeis-j*self.step] = numpy.flip(dataOut.data[:,j*self.step:j*self.step + self.nheights])
1718 #self.buffer[:,j,self.__nHeis-j*self.step - self.nheights:self.__nHeis-j*self.step] = numpy.flip(dataOut.data[:,j*self.step:j*self.step + self.nheights])
1719
1719
1720 for j in range(self.buffer.shape[0]):
1720 for j in range(self.buffer.shape[0]):
1721 self.sshProfiles[j] = numpy.transpose(self.buffer[j])
1721 self.sshProfiles[j] = numpy.transpose(self.buffer[j])
1722
1722
1723 profileIndex = self.nsamples
1723 profileIndex = self.nsamples
1724 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1724 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1725 ippSeconds = (deltaHeight*1.0e-6)/(0.15)
1725 ippSeconds = (deltaHeight*1.0e-6)/(0.15)
1726 #print("ippSeconds, dH: ",ippSeconds,deltaHeight)
1726 #print("ippSeconds, dH: ",ippSeconds,deltaHeight)
1727 try:
1727 try:
1728 if dataOut.concat_m is not None:
1728 if dataOut.concat_m is not None:
1729 ippSeconds= ippSeconds/float(dataOut.concat_m)
1729 ippSeconds= ippSeconds/float(dataOut.concat_m)
1730 #print "Profile concat %d"%dataOut.concat_m
1730 #print "Profile concat %d"%dataOut.concat_m
1731 except:
1731 except:
1732 pass
1732 pass
1733
1733
1734 dataOut.data = self.sshProfiles
1734 dataOut.data = self.sshProfiles
1735 dataOut.flagNoData = False
1735 dataOut.flagNoData = False
1736 dataOut.heightList = numpy.arange(self.buffer.shape[1]) *self.step*deltaHeight + dataOut.heightList[0]
1736 dataOut.heightList = numpy.arange(self.buffer.shape[1]) *self.step*deltaHeight + dataOut.heightList[0]
1737 dataOut.nProfiles = int(dataOut.nProfiles*self.nsamples)
1737 dataOut.nProfiles = int(dataOut.nProfiles*self.nsamples)
1738
1738
1739 dataOut.profileIndex = profileIndex
1739 dataOut.profileIndex = profileIndex
1740 dataOut.flagDataAsBlock = True
1740 dataOut.flagDataAsBlock = True
1741 dataOut.ippSeconds = ippSeconds
1741 dataOut.ippSeconds = ippSeconds
1742 dataOut.step = self.step
1742 dataOut.step = self.step
1743 #print(numpy.shape(dataOut.data))
1743 #print(numpy.shape(dataOut.data))
1744 #exit(1)
1744 #exit(1)
1745 #print("new data shape and time:", dataOut.data.shape, dataOut.utctime)
1745
1746
1746 return dataOut
1747 return dataOut
1747 ################################################################################3############################3
1748 ################################################################################3############################3
1748 ################################################################################3############################3
1749 ################################################################################3############################3
1749 ################################################################################3############################3
1750 ################################################################################3############################3
1750 ################################################################################3############################3
1751 ################################################################################3############################3
1751
1752
1752 class SSheightProfiles2(Operation):
1753 class SSheightProfiles2(Operation):
1753 '''
1754 '''
1754 Procesa por perfiles y por bloques
1755 Procesa por perfiles y por bloques
1755 '''
1756 '''
1756
1757
1757 step = None
1758
1758 nsamples = None
1759 bufferShape = None
1759 bufferShape = None
1760 profileShape = None
1760 profileShape = None
1761 sshProfiles = None
1761 sshProfiles = None
1762 profileIndex = None
1762 profileIndex = None
1763 deltaHeight = None
1763 #nsamples = None
1764 init_range = None
1764 #step = None
1765 #deltaHeight = None
1766 #init_range = None
1767 __slots__ = ('step', 'nsamples', 'deltaHeight', 'init_range', 'isConfig', '__nChannels',
1768 '__nProfiles', '__nHeis', 'deltaHeight', 'new_nHeights')
1765
1769
1766 def __init__(self, **kwargs):
1770 def __init__(self, **kwargs):
1767
1771
1768 Operation.__init__(self, **kwargs)
1772 Operation.__init__(self, **kwargs)
1769 self.isConfig = False
1773 self.isConfig = False
1770
1774
1771 def setup(self,dataOut ,step = None , nsamples = None):
1775 def setup(self,dataOut ,step = None , nsamples = None):
1772
1776
1773 if step == None and nsamples == None:
1777 if step == None and nsamples == None:
1774 raise ValueError("step or nheights should be specified ...")
1778 raise ValueError("step or nheights should be specified ...")
1775
1779
1776 self.step = step
1780 self.step = step
1777 self.nsamples = nsamples
1781 self.nsamples = nsamples
1778 self.__nChannels = int(dataOut.nChannels)
1782 self.__nChannels = int(dataOut.nChannels)
1779 self.__nProfiles = int(dataOut.nProfiles)
1783 self.__nProfiles = int(dataOut.nProfiles)
1780 self.__nHeis = int(dataOut.nHeights)
1784 self.__nHeis = int(dataOut.nHeights)
1781
1785
1782 residue = (self.__nHeis - self.nsamples) % self.step
1786 residue = (self.__nHeis - self.nsamples) % self.step
1783 if residue != 0:
1787 if residue != 0:
1784 print("The residue is %d, step=%d should be multiple of %d to avoid loss of %d samples"%(residue,step,shape[1] - self.nsamples,residue))
1788 print("The residue is %d, step=%d should be multiple of %d to avoid loss of %d samples"%(residue,step,shape[1] - self.nsamples,residue))
1785
1789
1786 self.deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1790 self.deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1787 self.init_range = dataOut.heightList[0]
1791 self.init_range = dataOut.heightList[0]
1788 #numberProfile = self.nsamples
1792 #numberProfile = self.nsamples
1789 self.numberSamples = (self.__nHeis - self.nsamples)/self.step
1793 numberSamples = (self.__nHeis - self.nsamples)/self.step
1790
1794
1791 self.new_nHeights = self.numberSamples
1795 self.new_nHeights = numberSamples
1792
1796
1793 self.bufferShape = int(self.__nChannels), int(self.numberSamples), int(self.nsamples) # nchannels, nsamples , nprofiles
1797 self.bufferShape = int(self.__nChannels), int(numberSamples), int(self.nsamples) # nchannels, nsamples , nprofiles
1794 self.profileShape = int(self.__nChannels), int(self.nsamples), int(self.numberSamples) # nchannels, nprofiles, nsamples
1798 self.profileShape = int(self.__nChannels), int(self.nsamples), int(numberSamples) # nchannels, nprofiles, nsamples
1795
1799
1796 self.buffer = numpy.zeros(self.bufferShape , dtype=numpy.complex)
1800 self.buffer = numpy.zeros(self.bufferShape , dtype=numpy.complex)
1797 self.sshProfiles = numpy.zeros(self.profileShape, dtype=numpy.complex)
1801 self.sshProfiles = numpy.zeros(self.profileShape, dtype=numpy.complex)
1798
1802
1799 def getNewProfiles(self, data, code=None, repeat=None):
1803 def getNewProfiles(self, data, code=None, repeat=None):
1800
1804
1801 if code is not None:
1805 if code is not None:
1802 code = numpy.array(code)
1806 code = numpy.array(code)
1803 code_block = code
1807 code_block = code
1804
1808
1805 if repeat is not None:
1809 if repeat is not None:
1806 code_block = numpy.repeat(code_block, repeats=repeat, axis=1)
1810 code_block = numpy.repeat(code_block, repeats=repeat, axis=1)
1807 if data.ndim == 2:
1811 if data.ndim == 2:
1808 data = data.reshape(1,1,self.__nHeis )
1812 data = data.reshape(1,1,self.__nHeis )
1809 #print("buff, data, :",self.buffer.shape, data.shape,self.sshProfiles.shape)
1813 #print("buff, data, :",self.buffer.shape, data.shape,self.sshProfiles.shape)
1810 for i in range(int(self.new_nHeights)): #nuevas alturas
1814 for i in range(int(self.new_nHeights)): #nuevas alturas
1811 if code is not None:
1815 if code is not None:
1812 self.buffer[:,i,:] = data[:,:,i*self.step:i*self.step + self.nsamples]*code_block
1816 self.buffer[:,i,:] = data[:,:,i*self.step:i*self.step + self.nsamples]*code_block
1813 else:
1817 else:
1814 self.buffer[:,i,:] = data[:,:,i*self.step:i*self.step + self.nsamples]#*code[dataOut.profileIndex,:]
1818 self.buffer[:,i,:] = data[:,:,i*self.step:i*self.step + self.nsamples]#*code[dataOut.profileIndex,:]
1815
1819
1816 for j in range(self.__nChannels): #en los cananles
1820 for j in range(self.__nChannels): #en los cananles
1817 self.sshProfiles[j,:,:] = numpy.transpose(self.buffer[j,:,:])
1821 self.sshProfiles[j,:,:] = numpy.transpose(self.buffer[j,:,:])
1818 #print("new profs Done")
1822 #print("new profs Done")
1819
1823
1820
1824
1821
1825
1822 def run(self, dataOut, step, nsamples, code = None, repeat = None):
1826 def run(self, dataOut, step, nsamples, code = None, repeat = None):
1823
1827
1824 if dataOut.flagNoData == True:
1828 if dataOut.flagNoData == True:
1825 return dataOut
1829 return dataOut
1826 dataOut.flagNoData = True
1830 dataOut.flagNoData = True
1827 #print("init data shape:", dataOut.data.shape)
1831 #print("init data shape:", dataOut.data.shape)
1828 #print("ch: {} prof: {} hs: {}".format(int(dataOut.nChannels),
1832 #print("ch: {} prof: {} hs: {}".format(int(dataOut.nChannels),
1829 # int(dataOut.nProfiles),int(dataOut.nHeights)))
1833 # int(dataOut.nProfiles),int(dataOut.nHeights)))
1830
1834
1831 profileIndex = None
1835 profileIndex = None
1832 # if not dataOut.flagDataAsBlock:
1836 # if not dataOut.flagDataAsBlock:
1833 # dataOut.nProfiles = 1
1837 # dataOut.nProfiles = 1
1834
1838
1835 if not self.isConfig:
1839 if not self.isConfig:
1836 self.setup(dataOut, step=step , nsamples=nsamples)
1840 self.setup(dataOut, step=step , nsamples=nsamples)
1837 #print("Setup done")
1841 #print("Setup done")
1838 self.isConfig = True
1842 self.isConfig = True
1839
1843
1840 dataBlock = None
1844 dataBlock = None
1841
1845
1842 nprof = 1
1846 nprof = 1
1843 if dataOut.flagDataAsBlock:
1847 if dataOut.flagDataAsBlock:
1844 nprof = int(dataOut.nProfiles)
1848 nprof = int(dataOut.nProfiles)
1845
1849
1846 #print("dataOut nProfiles:", dataOut.nProfiles)
1850 #print("dataOut nProfiles:", dataOut.nProfiles)
1847 for profile in range(nprof):
1851 for profile in range(nprof):
1848 if dataOut.flagDataAsBlock:
1852 if dataOut.flagDataAsBlock:
1849 #print("read blocks")
1853 #print("read blocks")
1850 self.getNewProfiles(dataOut.data[:,profile,:], code=code, repeat=repeat)
1854 self.getNewProfiles(dataOut.data[:,profile,:], code=code, repeat=repeat)
1851 else:
1855 else:
1852 #print("read profiles")
1856 #print("read profiles")
1853 self.getNewProfiles(dataOut.data, code=code, repeat=repeat) #only one channe
1857 self.getNewProfiles(dataOut.data, code=code, repeat=repeat) #only one channe
1854 if profile == 0:
1858 if profile == 0:
1855 dataBlock = self.sshProfiles.copy()
1859 dataBlock = self.sshProfiles.copy()
1856 else: #by blocks
1860 else: #by blocks
1857 dataBlock = numpy.concatenate((dataBlock,self.sshProfiles), axis=1) #profile axis
1861 dataBlock = numpy.concatenate((dataBlock,self.sshProfiles), axis=1) #profile axis
1858 #print("by blocks: ",dataBlock.shape, self.sshProfiles.shape)
1862 #print("by blocks: ",dataBlock.shape, self.sshProfiles.shape)
1859
1863
1860 profileIndex = self.nsamples
1864 profileIndex = self.nsamples
1861 #deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1865 #deltaHeight = dataOut.heightList[1] - dataOut.heightList[0]
1862 ippSeconds = (self.deltaHeight*1.0e-6)/(0.15)
1866 ippSeconds = (self.deltaHeight*1.0e-6)/(0.15)
1863
1867
1864
1868
1865 dataOut.data = dataBlock
1869 dataOut.data = dataBlock
1866 #print("show me: ",self.step,self.deltaHeight, dataOut.heightList, self.new_nHeights)
1870 #print("show me: ",self.step,self.deltaHeight, dataOut.heightList, self.new_nHeights)
1867 dataOut.heightList = numpy.arange(int(self.new_nHeights)) *self.step*self.deltaHeight + self.init_range
1871 dataOut.heightList = numpy.arange(int(self.new_nHeights)) *self.step*self.deltaHeight + self.init_range
1868
1872
1869 dataOut.ippSeconds = ippSeconds
1873 dataOut.ippSeconds = ippSeconds
1870 dataOut.step = self.step
1874 dataOut.step = self.step
1871 dataOut.flagNoData = False
1875 dataOut.flagNoData = False
1872 if dataOut.flagDataAsBlock:
1876 if dataOut.flagDataAsBlock:
1873 dataOut.nProfiles = int(dataOut.nProfiles*self.nsamples)
1877 dataOut.nProfiles = int(dataOut.nProfiles*self.nsamples)
1874
1878
1875 else:
1879 else:
1876 dataOut.nProfiles = int(self.nsamples)
1880 dataOut.nProfiles = int(self.nsamples)
1877 dataOut.profileIndex = dataOut.nProfiles
1881 dataOut.profileIndex = dataOut.nProfiles
1878 dataOut.flagDataAsBlock = True
1882 dataOut.flagDataAsBlock = True
1879
1883
1880 dataBlock = None
1884 dataBlock = None
1881 #print("new data shape:", dataOut.data.shape)
1885
1886 #print("new data shape:", dataOut.data.shape, dataOut.utctime)
1882
1887
1883 return dataOut
1888 return dataOut
1884
1889
1885
1890
1886
1891
1887
1892
1888 #import skimage.color
1893 #import skimage.color
1889 #import skimage.io
1894 #import skimage.io
1890 #import matplotlib.pyplot as plt
1895 #import matplotlib.pyplot as plt
1891
1896
1892 class removeProfileByFaradayHS(Operation):
1897 class removeProfileByFaradayHS(Operation):
1893 '''
1898 '''
1894
1899
1895 '''
1900 '''
1896 isConfig = False
1901 #isConfig = False
1897 n = None
1902 #n = None
1898
1899 __profIndex = 0
1900
1903
1901 __dataReady = False
1904 #__dataReady = False
1902 __buffer_data = []
1905 __buffer_data = []
1903 __buffer_times = []
1906 __buffer_times = []
1904 __initime = None
1907 #__initime = None
1905 __count_exec = 0
1908 #__count_exec = 0
1906 __profIndex = 0
1909 #__profIndex = 0
1907 buffer = None
1910 buffer = None
1908 lenProfileOut = 1
1911 #lenProfileOut = 1
1912
1913 #init_prof = 0
1914 #end_prof = 0
1909
1915
1910 init_prof = 0
1916 #first_utcBlock = None
1911 end_prof = 0
1912 n_profiles = 0
1913 first_utcBlock = None
1914 outliers_IDs_list = []
1917 outliers_IDs_list = []
1915 __dh = 0
1918 #__dh = 0
1916
1919
1920 __slots__ = ('n','navg','profileMargin','thHistOutlier','minHei_idx','maxHei_idx','nHeights',
1921 '__dh','first_utcBlock','__profIndex','init_prof','end_prof','lenProfileOut','nChannels',
1922 '__count_exec','__initime','__dataReady','__ipp')
1917 def __init__(self, **kwargs):
1923 def __init__(self, **kwargs):
1918
1924
1919 Operation.__init__(self, **kwargs)
1925 Operation.__init__(self, **kwargs)
1920 self.isConfig = False
1926 self.isConfig = False
1921
1927
1922 def setup(self,dataOut, n=None , navg=0.8, profileMargin=50,thHistOutlier=3, minHei=None, maxHei=None):
1928 def setup(self,dataOut, n=None , navg=0.8, profileMargin=50,thHistOutlier=3, minHei=None, maxHei=None):
1923
1929
1924 if n == None and timeInterval == None:
1930 if n == None and timeInterval == None:
1925 raise ValueError("nprofiles or timeInterval should be specified ...")
1931 raise ValueError("nprofiles or timeInterval should be specified ...")
1926
1932
1927 if n != None:
1933 if n != None:
1928 self.n = n
1934 self.n = n
1929
1935
1930 self.navg = navg
1936 self.navg = navg
1931 self.profileMargin = profileMargin
1937 self.profileMargin = profileMargin
1932 self.thHistOutlier = thHistOutlier
1938 self.thHistOutlier = thHistOutlier
1933 self.__profIndex = 0
1939 self.__profIndex = 0
1934 self.buffer = None
1940 self.buffer = None
1935 self.lenProfileOut = 1
1941 self._ipp = dataOut.ippSeconds
1936 self.n_prof_released = 0
1942 self.n_prof_released = 0
1937 self.heightList = dataOut.heightList
1943 self.heightList = dataOut.heightList
1938 self.init_prof = 0
1944 self.init_prof = 0
1939 self.end_prof = 0
1945 self.end_prof = 0
1940 self.n_profiles = 0
1946 self.__count_exec = 0
1947 self.__profIndex = 0
1941 self.first_utcBlock = None
1948 self.first_utcBlock = None
1942 self.__dh = dataOut.heightList[1] - dataOut.heightList[0]
1949 self.__dh = dataOut.heightList[1] - dataOut.heightList[0]
1943 minHei = minHei
1950 minHei = minHei
1944 maxHei = maxHei
1951 maxHei = maxHei
1945 if minHei==None :
1952 if minHei==None :
1946 minHei = dataOut.heightList[0]
1953 minHei = dataOut.heightList[0]
1947 if maxHei==None :
1954 if maxHei==None :
1948 maxHei = dataOut.heightList[-1]
1955 maxHei = dataOut.heightList[-1]
1949 self.minHei_idx,self.maxHei_idx = getHei_index(minHei, maxHei, dataOut.heightList)
1956 self.minHei_idx,self.maxHei_idx = getHei_index(minHei, maxHei, dataOut.heightList)
1950
1957
1958 self.nChannels = dataOut.nChannels
1959 self.nHeights = dataOut.nHeights
1951
1960
1952 def filterSatsProfiles(self):
1961 def filterSatsProfiles(self):
1953 data = self.__buffer_data
1962 data = self.__buffer_data
1954 #print(data.shape)
1963 #print(data.shape)
1955 nChannels, profiles, heights = data.shape
1964 nChannels, profiles, heights = data.shape
1956 indexes=[]
1965 indexes=[]
1957 outliers_IDs=[]
1966 outliers_IDs=[]
1958 for c in range(nChannels):
1967 for c in range(nChannels):
1959 for h in range(self.minHei_idx, self.maxHei_idx):
1968 for h in range(self.minHei_idx, self.maxHei_idx):
1960 power = data[c,:,h] * numpy.conjugate(data[c,:,h])
1969 power = data[c,:,h] * numpy.conjugate(data[c,:,h])
1961 power = power.real
1970 power = power.real
1962 #power = (numpy.abs(data[c,:,h].real))
1971 #power = (numpy.abs(data[c,:,h].real))
1963 sortdata = numpy.sort(power, axis=None)
1972 sortdata = numpy.sort(power, axis=None)
1964 sortID=power.argsort()
1973 sortID=power.argsort()
1965 index = _noise.hildebrand_sekhon2(sortdata,self.navg) #0.75-> buen valor
1974 index = _noise.hildebrand_sekhon2(sortdata,self.navg) #0.75-> buen valor
1966
1975
1967 indexes.append(index)
1976 indexes.append(index)
1968 outliers_IDs=numpy.append(outliers_IDs,sortID[index:])
1977 outliers_IDs=numpy.append(outliers_IDs,sortID[index:])
1969 # print(outliers_IDs)
1978 # print(outliers_IDs)
1970 # fig,ax = plt.subplots()
1979 # fig,ax = plt.subplots()
1971 # #ax.set_title(str(k)+" "+str(j))
1980 # #ax.set_title(str(k)+" "+str(j))
1972 # x=range(len(sortdata))
1981 # x=range(len(sortdata))
1973 # ax.scatter(x,sortdata)
1982 # ax.scatter(x,sortdata)
1974 # ax.axvline(index)
1983 # ax.axvline(index)
1975 # plt.grid()
1984 # plt.grid()
1976 # plt.show()
1985 # plt.show()
1977
1986
1978 outliers_IDs = outliers_IDs.astype(numpy.dtype('int64'))
1987 outliers_IDs = outliers_IDs.astype(numpy.dtype('int64'))
1979 outliers_IDs = numpy.unique(outliers_IDs)
1988 outliers_IDs = numpy.unique(outliers_IDs)
1980 outs_lines = numpy.sort(outliers_IDs)
1989 outs_lines = numpy.sort(outliers_IDs)
1981 # #print("outliers Ids: ", outs_lines, outs_lines.shape)
1990 # #print("outliers Ids: ", outs_lines, outs_lines.shape)
1982 #hist, bin_edges = numpy.histogram(outs_lines, bins=10, density=True)
1991 #hist, bin_edges = numpy.histogram(outs_lines, bins=10, density=True)
1983
1992
1984
1993
1985 #Agrupando el histograma de outliers,
1994 #Agrupando el histograma de outliers,
1986 my_bins = numpy.linspace(0,9600, 96, endpoint=False)
1995 my_bins = numpy.linspace(0,9600, 96, endpoint=False)
1987
1996
1988
1997
1989 hist, bins = numpy.histogram(outs_lines,bins=my_bins)
1998 hist, bins = numpy.histogram(outs_lines,bins=my_bins)
1990 hist_outliers_indexes = numpy.where(hist > self.thHistOutlier) #es outlier
1999 hist_outliers_indexes = numpy.where(hist > self.thHistOutlier) #es outlier
1991 #print(hist_outliers_indexes[0])
2000 #print(hist_outliers_indexes[0])
1992 bins_outliers_indexes = [int(i) for i in bins[hist_outliers_indexes]] #
2001 bins_outliers_indexes = [int(i) for i in bins[hist_outliers_indexes]] #
1993 #print(bins_outliers_indexes)
2002 #print(bins_outliers_indexes)
1994 outlier_loc_index = []
2003 outlier_loc_index = []
1995
2004
1996 #outlier_loc_index = [k for k in range(bins_outliers_indexes[n]-50,bins_outliers_indexes[n+1]+50) for n in range(len(bins_outliers_indexes)-1) ]
2005 #outlier_loc_index = [k for k in range(bins_outliers_indexes[n]-50,bins_outliers_indexes[n+1]+50) for n in range(len(bins_outliers_indexes)-1) ]
1997 for n in range(len(bins_outliers_indexes)-1):
2006 for n in range(len(bins_outliers_indexes)-1):
1998 #outlier_loc_index = [k for k in range(bins_outliers_indexes[n]-50,bins_outliers_indexes[n+1]+50)]
2007 #outlier_loc_index = [k for k in range(bins_outliers_indexes[n]-50,bins_outliers_indexes[n+1]+50)]
1999 for k in range(bins_outliers_indexes[n]-self.profileMargin,bins_outliers_indexes[n+1]+self.profileMargin):
2008 for k in range(bins_outliers_indexes[n]-self.profileMargin,bins_outliers_indexes[n+1]+self.profileMargin):
2000 outlier_loc_index.append(k)
2009 outlier_loc_index.append(k)
2001
2010
2002 outlier_loc_index = numpy.asarray(outlier_loc_index)
2011 outlier_loc_index = numpy.asarray(outlier_loc_index)
2003 #print(numpy.unique(outlier_loc_index))
2012 #print(numpy.unique(outlier_loc_index))
2004
2013
2005
2014
2006
2015
2007 # x, y = numpy.meshgrid(numpy.arange(profiles), self.heightList)
2016 # x, y = numpy.meshgrid(numpy.arange(profiles), self.heightList)
2008 # fig, ax = plt.subplots(1,2,figsize=(8, 6))
2017 # fig, ax = plt.subplots(1,2,figsize=(8, 6))
2009 #
2018 #
2010 # dat = data[0,:,:].real
2019 # dat = data[0,:,:].real
2011 # m = numpy.nanmean(dat)
2020 # m = numpy.nanmean(dat)
2012 # o = numpy.nanstd(dat)
2021 # o = numpy.nanstd(dat)
2013 # #print(m, o, x.shape, y.shape)
2022 # #print(m, o, x.shape, y.shape)
2014 # c = ax[0].pcolormesh(x, y, dat.T, cmap ='YlGnBu', vmin = (m-2*o), vmax = (m+2*o))
2023 # c = ax[0].pcolormesh(x, y, dat.T, cmap ='YlGnBu', vmin = (m-2*o), vmax = (m+2*o))
2015 # ax[0].vlines(outs_lines,200,600, linestyles='dashed', label = 'outs', color='w')
2024 # ax[0].vlines(outs_lines,200,600, linestyles='dashed', label = 'outs', color='w')
2016 # fig.colorbar(c)
2025 # fig.colorbar(c)
2017 # ax[0].vlines(outlier_loc_index,650,750, linestyles='dashed', label = 'outs', color='r')
2026 # ax[0].vlines(outlier_loc_index,650,750, linestyles='dashed', label = 'outs', color='r')
2018 # ax[1].hist(outs_lines,bins=my_bins)
2027 # ax[1].hist(outs_lines,bins=my_bins)
2019 # plt.show()
2028 # plt.show()
2020
2029
2021
2030
2022 self.outliers_IDs_list = numpy.unique(outlier_loc_index)
2031 self.outliers_IDs_list = numpy.unique(outlier_loc_index)
2023 return data
2032 return data
2024
2033
2025 def cleanOutliersByBlock(self):
2034 def cleanOutliersByBlock(self):
2026 #print(self.__buffer_data[0].shape)
2035 #print(self.__buffer_data[0].shape)
2027 data = self.__buffer_data#.copy()
2036 data = self.__buffer_data#.copy()
2028 #print("cleaning shape inpt: ",data.shape)
2037 #print("cleaning shape inpt: ",data.shape)
2029 '''
2038 '''
2030 self.__buffer_data = []
2039 self.__buffer_data = []
2031
2040
2032 spectrum = numpy.fft.fft2(data, axes=(0,2))
2041 spectrum = numpy.fft.fft2(data, axes=(0,2))
2033 #print("spc : ",spectrum.shape)
2042 #print("spc : ",spectrum.shape)
2034 (nch,nsamples, nh) = spectrum.shape
2043 (nch,nsamples, nh) = spectrum.shape
2035 data2 = None
2044 data2 = None
2036 #print(data.shape)
2045 #print(data.shape)
2037 spectrum2 = spectrum.copy()
2046 spectrum2 = spectrum.copy()
2038 for ch in range(nch):
2047 for ch in range(nch):
2039 dh = self.__dh
2048 dh = self.__dh
2040 dt1 = (dh*1.0e-6)/(0.15)
2049 dt1 = (dh*1.0e-6)/(0.15)
2041 dt2 = self.__buffer_times[1]-self.__buffer_times[0]
2050 dt2 = self.__buffer_times[1]-self.__buffer_times[0]
2042 freqv = numpy.fft.fftfreq(nh, d=dt1)
2051 freqv = numpy.fft.fftfreq(nh, d=dt1)
2043 freqh = numpy.fft.fftfreq(self.n, d=dt2)
2052 freqh = numpy.fft.fftfreq(self.n, d=dt2)
2044 #print("spc loop: ")
2053 #print("spc loop: ")
2045
2054
2046
2055
2047
2056
2048 x, y = numpy.meshgrid(numpy.sort(freqh),numpy.sort(freqv))
2057 x, y = numpy.meshgrid(numpy.sort(freqh),numpy.sort(freqv))
2049 z = numpy.abs(spectrum[ch,:,:])
2058 z = numpy.abs(spectrum[ch,:,:])
2050 # Find all peaks higher than the 98th percentile
2059 # Find all peaks higher than the 98th percentile
2051 peaks = z < numpy.percentile(z, 98)
2060 peaks = z < numpy.percentile(z, 98)
2052 #print(peaks)
2061 #print(peaks)
2053 # Set those peak coefficients to zero
2062 # Set those peak coefficients to zero
2054 spectrum2 = spectrum2 * peaks.astype(int)
2063 spectrum2 = spectrum2 * peaks.astype(int)
2055 data2 = numpy.fft.ifft2(spectrum2)
2064 data2 = numpy.fft.ifft2(spectrum2)
2056
2065
2057 dat = numpy.log10(z.T)
2066 dat = numpy.log10(z.T)
2058 dat2 = numpy.log10(spectrum2.T)
2067 dat2 = numpy.log10(spectrum2.T)
2059
2068
2060 # m = numpy.mean(dat)
2069 # m = numpy.mean(dat)
2061 # o = numpy.std(dat)
2070 # o = numpy.std(dat)
2062 # fig, ax = plt.subplots(2,1,figsize=(8, 6))
2071 # fig, ax = plt.subplots(2,1,figsize=(8, 6))
2063 #
2072 #
2064 # c = ax[0].pcolormesh(x, y, dat, cmap ='YlGnBu', vmin = (m-2*o), vmax = (m+2*o))
2073 # c = ax[0].pcolormesh(x, y, dat, cmap ='YlGnBu', vmin = (m-2*o), vmax = (m+2*o))
2065 # #c = ax.pcolor( z.T , cmap ='gray', vmin = (m-2*o), vmax = (m+2*o))
2074 # #c = ax.pcolor( z.T , cmap ='gray', vmin = (m-2*o), vmax = (m+2*o))
2066 # date_time = datetime.datetime.fromtimestamp(self.__buffer_times[0]).strftime('%Y-%m-%d %H:%M:%S.%f')
2075 # date_time = datetime.datetime.fromtimestamp(self.__buffer_times[0]).strftime('%Y-%m-%d %H:%M:%S.%f')
2067 # #strftime('%Y-%m-%d %H:%M:%S')
2076 # #strftime('%Y-%m-%d %H:%M:%S')
2068 # ax[0].set_title('Spectrum magnitude '+date_time)
2077 # ax[0].set_title('Spectrum magnitude '+date_time)
2069 # fig.canvas.set_window_title('Spectrum magnitude {} '.format(self.n)+date_time)
2078 # fig.canvas.set_window_title('Spectrum magnitude {} '.format(self.n)+date_time)
2070 #
2079 #
2071 #
2080 #
2072 # c = ax[1].pcolormesh(x, y, dat, cmap ='YlGnBu', vmin = (m-2*o), vmax = (m+2*o))
2081 # c = ax[1].pcolormesh(x, y, dat, cmap ='YlGnBu', vmin = (m-2*o), vmax = (m+2*o))
2073 # fig.colorbar(c)
2082 # fig.colorbar(c)
2074 # plt.show()
2083 # plt.show()
2075
2084
2076 #print(data2.shape)
2085 #print(data2.shape)
2077
2086
2078 data = data2
2087 data = data2
2079
2088
2080 #cleanBlock = numpy.fft.ifft2(spectrum, axes=(0,2)).reshape()
2089 #cleanBlock = numpy.fft.ifft2(spectrum, axes=(0,2)).reshape()
2081 '''
2090 '''
2082 #print("cleanOutliersByBlock Done")
2091 #print("cleanOutliersByBlock Done")
2083
2092
2084 return self.filterSatsProfiles()
2093 return self.filterSatsProfiles()
2085
2094
2086
2095
2087
2096
2088 def fillBuffer(self, data, datatime):
2097 def fillBuffer(self, data, datatime):
2089
2098
2090 if self.__profIndex == 0:
2099 if self.__profIndex == 0:
2091 self.__buffer_data = data.copy()
2100 self.__buffer_data = data.copy()
2092
2101
2093 else:
2102 else:
2094 self.__buffer_data = numpy.concatenate((self.__buffer_data,data), axis=1)#en perfiles
2103 self.__buffer_data = numpy.concatenate((self.__buffer_data,data), axis=1)#en perfiles
2095 self.__profIndex += 1
2104 self.__profIndex += 1
2096 #self.__buffer_times.append(datatime)
2105 #self.__buffer_times.append(datatime)
2097
2106
2098 def getData(self, data, datatime=None):
2107 def getData(self, data, datatime=None):
2099
2108
2100 if self.__profIndex == 0:
2109 if self.__profIndex == 0:
2101 self.__initime = datatime
2110 self.__initime = datatime
2102
2111
2103
2112
2104 self.__dataReady = False
2113 self.__dataReady = False
2105
2114
2106 self.fillBuffer(data, datatime)
2115 self.fillBuffer(data, datatime)
2107 dataBlock = None
2116 dataBlock = None
2108
2117
2109 if self.__profIndex == self.n:
2118 if self.__profIndex == self.n:
2110 #print("apnd : ",data)
2119 #print("apnd : ",data)
2111 #dataBlock = self.cleanOutliersByBlock()
2120 #dataBlock = self.cleanOutliersByBlock()
2112 dataBlock = self.filterSatsProfiles()
2121 dataBlock = self.filterSatsProfiles()
2113 self.__dataReady = True
2122 self.__dataReady = True
2114
2123
2115 return dataBlock
2124 return dataBlock
2116
2125
2117 if dataBlock is None:
2126 if dataBlock is None:
2118 return None, None
2127 return None, None
2119
2128
2120
2129
2121
2130
2122 return dataBlock
2131 return dataBlock
2123
2132
2124 def releaseBlock(self):
2133 def releaseBlock(self):
2125
2134
2126 if self.n % self.lenProfileOut != 0:
2135 if self.n % self.lenProfileOut != 0:
2127 raise ValueError("lenProfileOut %d must be submultiple of nProfiles %d" %(self.lenProfileOut, self.n_profiles))
2136 raise ValueError("lenProfileOut %d must be submultiple of nProfiles %d" %(self.lenProfileOut, self.n))
2128 return None
2137 return None
2129
2138
2130 data = self.buffer[:,self.init_prof:self.end_prof:,:] #ch, prof, alt
2139 data = self.buffer[:,self.init_prof:self.end_prof:,:] #ch, prof, alt
2131
2140
2132 self.init_prof = self.end_prof
2141 self.init_prof = self.end_prof
2133 self.end_prof += self.lenProfileOut
2142 self.end_prof += self.lenProfileOut
2134 #print("data release shape: ",dataOut.data.shape, self.end_prof)
2143 #print("data release shape: ",dataOut.data.shape, self.end_prof)
2135 self.n_prof_released += 1
2144 self.n_prof_released += 1
2136
2145
2137
2146
2138 #print("f_no_data ", dataOut.flagNoData)
2147 #print("f_no_data ", dataOut.flagNoData)
2139 return data
2148 return data
2140
2149
2141 def run(self, dataOut, n=None, navg=0.8, nProfilesOut=1, profile_margin=50,th_hist_outlier=3,minHei=None, maxHei=None):
2150 def run(self, dataOut, n=None, navg=0.8, nProfilesOut=1, profile_margin=50,th_hist_outlier=3,minHei=None, maxHei=None):
2142 #print("run op buffer 2D")
2151 #print("run op buffer 2D",dataOut.ippSeconds)
2143 self.nChannels = dataOut.nChannels
2152 # self.nChannels = dataOut.nChannels
2144 self.nHeights = dataOut.nHeights
2153 # self.nHeights = dataOut.nHeights
2145
2154
2146 if not self.isConfig:
2155 if not self.isConfig:
2147 #print("init p idx: ", dataOut.profileIndex )
2156 #print("init p idx: ", dataOut.profileIndex )
2148 self.setup(dataOut,n=n, navg=navg,profileMargin=profile_margin,
2157 self.setup(dataOut,n=n, navg=navg,profileMargin=profile_margin,
2149 thHistOutlier=th_hist_outlier,minHei=minHei, maxHei=maxHei)
2158 thHistOutlier=th_hist_outlier,minHei=minHei, maxHei=maxHei)
2150 self.isConfig = True
2159 self.isConfig = True
2151
2160
2152 dataBlock = None
2161 dataBlock = None
2153
2162
2154 if not dataOut.buffer_empty: #hay datos acumulados
2163 if not dataOut.buffer_empty: #hay datos acumulados
2155
2164
2156 if self.init_prof == 0:
2165 if self.init_prof == 0:
2157 self.n_prof_released = 0
2166 self.n_prof_released = 0
2158 self.lenProfileOut = nProfilesOut
2167 self.lenProfileOut = nProfilesOut
2159 dataOut.flagNoData = False
2168 dataOut.flagNoData = False
2160 #print("tp 2 ",dataOut.data.shape)
2169 #print("tp 2 ",dataOut.data.shape)
2161 #(ch, self.n_profiles, nh) = self.buffer.shape
2170
2162 #print("tp 3 ",self.dataOut.data.shape)
2163 #print("rel: ",self.buffer[:,-1,:])
2164 self.init_prof = 0
2171 self.init_prof = 0
2165 self.end_prof = self.lenProfileOut
2172 self.end_prof = self.lenProfileOut
2166
2173
2167 dataOut.nProfiles = self.lenProfileOut
2174 dataOut.nProfiles = self.lenProfileOut
2168 if nProfilesOut == 1:
2175 if nProfilesOut == 1:
2169 dataOut.flagDataAsBlock = False
2176 dataOut.flagDataAsBlock = False
2170 else:
2177 else:
2171 dataOut.flagDataAsBlock = True
2178 dataOut.flagDataAsBlock = True
2172 #print("prof: ",self.init_prof)
2179 #print("prof: ",self.init_prof)
2173 dataOut.flagNoData = False
2180 dataOut.flagNoData = False
2174 if numpy.isin(self.n_prof_released, self.outliers_IDs_list):
2181 if numpy.isin(self.n_prof_released, self.outliers_IDs_list):
2175 #print("omitting: ", self.n_prof_released)
2182 #print("omitting: ", self.n_prof_released)
2176 dataOut.flagNoData = True
2183 dataOut.flagNoData = True
2177
2184 dataOut.ippSeconds = self._ipp
2178 dataOut.utctime = self.first_utcBlock + self.init_prof*dataOut.ippSeconds
2185 dataOut.utctime = self.first_utcBlock + self.init_prof*self._ipp
2186 # print("time: ", dataOut.utctime, self.first_utcBlock, self.init_prof,self._ipp,dataOut.ippSeconds)
2179 #dataOut.data = self.releaseBlock()
2187 #dataOut.data = self.releaseBlock()
2180 #########################################################3
2188 #########################################################3
2181 if self.n % self.lenProfileOut != 0:
2189 if self.n % self.lenProfileOut != 0:
2182 raise ValueError("lenProfileOut %d must be submultiple of nProfiles %d" %(self.lenProfileOut, self.n_profiles))
2190 raise ValueError("lenProfileOut %d must be submultiple of nProfiles %d" %(self.lenProfileOut, self.n))
2183 return None
2191 return None
2184
2192
2185 dataOut.data = self.buffer[:,self.init_prof:self.end_prof:,:] #ch, prof, alt
2193 dataOut.data = self.buffer[:,self.init_prof:self.end_prof:,:] #ch, prof, alt
2186
2194
2187 self.init_prof = self.end_prof
2195 self.init_prof = self.end_prof
2188 self.end_prof += self.lenProfileOut
2196 self.end_prof += self.lenProfileOut
2189 #print("data release shape: ",dataOut.data.shape, self.end_prof)
2197 #print("data release shape: ",dataOut.data.shape, self.end_prof)
2190 self.n_prof_released += 1
2198 self.n_prof_released += 1
2191
2199
2192 if self.end_prof >= (self.n +self.lenProfileOut):
2200 if self.end_prof >= (self.n +self.lenProfileOut):
2193
2201
2194 self.init_prof = 0
2202 self.init_prof = 0
2195 self.__profIndex = 0
2203 self.__profIndex = 0
2196 self.buffer = None
2204 self.buffer = None
2197 dataOut.buffer_empty = True
2205 dataOut.buffer_empty = True
2198 self.outliers_IDs_list = []
2206 self.outliers_IDs_list = []
2199 self.n_prof_released = 0
2207 self.n_prof_released = 0
2200 dataOut.flagNoData = False #enviar ultimo aunque sea outlier :(
2208 dataOut.flagNoData = False #enviar ultimo aunque sea outlier :(
2201 #print("cleaning...", dataOut.buffer_empty)
2209 #print("cleaning...", dataOut.buffer_empty)
2202 dataOut.profileIndex = 0 #self.lenProfileOut
2210 dataOut.profileIndex = 0 #self.lenProfileOut
2203 ####################################################################
2211 ####################################################################
2204 return dataOut
2212 return dataOut
2205
2213
2206
2214
2207 #print("tp 223 ",dataOut.data.shape)
2215 #print("tp 223 ",dataOut.data.shape)
2208 dataOut.flagNoData = True
2216 dataOut.flagNoData = True
2209
2217
2210
2218
2211
2219
2212 try:
2220 try:
2213 #dataBlock = self.getData(dataOut.data.reshape(self.nChannels,1,self.nHeights), dataOut.utctime)
2221 #dataBlock = self.getData(dataOut.data.reshape(self.nChannels,1,self.nHeights), dataOut.utctime)
2214 dataBlock = self.getData(numpy.reshape(dataOut.data,(self.nChannels,1,self.nHeights)), dataOut.utctime)
2222 dataBlock = self.getData(numpy.reshape(dataOut.data,(self.nChannels,1,self.nHeights)), dataOut.utctime)
2215 self.__count_exec +=1
2223 self.__count_exec +=1
2216 except Exception as e:
2224 except Exception as e:
2217 print("Error getting profiles data",self.__count_exec )
2225 print("Error getting profiles data",self.__count_exec )
2218 print(e)
2226 print(e)
2219 sys.exit()
2227 sys.exit()
2220
2228
2221 if self.__dataReady:
2229 if self.__dataReady:
2222 #print("omitting: ", len(self.outliers_IDs_list))
2230 #print("omitting: ", len(self.outliers_IDs_list))
2223 self.__count_exec = 0
2231 self.__count_exec = 0
2224 #dataOut.data =
2232 #dataOut.data =
2225 #self.buffer = numpy.flip(dataBlock, axis=1)
2233 #self.buffer = numpy.flip(dataBlock, axis=1)
2226 self.buffer = dataBlock
2234 self.buffer = dataBlock
2227 self.first_utcBlock = self.__initime
2235 self.first_utcBlock = self.__initime
2228 dataOut.utctime = self.__initime
2236 dataOut.utctime = self.__initime
2229 dataOut.nProfiles = self.__profIndex
2237 dataOut.nProfiles = self.__profIndex
2230 #dataOut.flagNoData = False
2238 #dataOut.flagNoData = False
2231 self.init_prof = 0
2239 self.init_prof = 0
2232 self.__profIndex = 0
2240 self.__profIndex = 0
2233 self.__initime = None
2241 self.__initime = None
2234 dataBlock = None
2242 dataBlock = None
2235 self.__buffer_times = []
2243 self.__buffer_times = []
2236 dataOut.error = False
2244 dataOut.error = False
2237 dataOut.useInputBuffer = True
2245 dataOut.useInputBuffer = True
2238 dataOut.buffer_empty = False
2246 dataOut.buffer_empty = False
2239 #print("1 ch: {} prof: {} hs: {}".format(int(dataOut.nChannels),int(dataOut.nProfiles),int(dataOut.nHeights)))
2247 #print("1 ch: {} prof: {} hs: {}".format(int(dataOut.nChannels),int(dataOut.nProfiles),int(dataOut.nHeights)))
2240
2248
2241
2249
2242
2250
2243 #print(self.__count_exec)
2251 #print(self.__count_exec)
2244
2252
2245 return dataOut
2253 return dataOut
2246
2254
2247 class RemoveProfileSats(Operation):
2255 class RemoveProfileSats(Operation):
2248 '''
2256 '''
2249 Omite los perfiles contaminados con señal de satelites,
2257 Omite los perfiles contaminados con señal de satelites,
2250 In: minHei = min_sat_range
2258 In: minHei = min_sat_range
2251 max_sat_range
2259 max_sat_range
2252 min_hei_ref
2260 min_hei_ref
2253 max_hei_ref
2261 max_hei_ref
2254 th = diference between profiles mean, ref and sats
2262 th = diference between profiles mean, ref and sats
2255 Out:
2263 Out:
2256 profile clean
2264 profile clean
2257 '''
2265 '''
2258
2266
2259 isConfig = False
2267 isConfig = False
2260 min_sats = 0
2268 min_sats = 0
2261 max_sats = 999999999
2269 max_sats = 999999999
2262 min_ref= 0
2270 min_ref= 0
2263 max_ref= 9999999999
2271 max_ref= 9999999999
2264 needReshape = False
2272 needReshape = False
2265 count = 0
2273 count = 0
2266 thdB = 0
2274 thdB = 0
2267 byRanges = False
2275 byRanges = False
2268 min_sats = None
2276 min_sats = None
2269 max_sats = None
2277 max_sats = None
2270 noise = 0
2278 noise = 0
2271
2279
2272 def __init__(self, **kwargs):
2280 def __init__(self, **kwargs):
2273
2281
2274 Operation.__init__(self, **kwargs)
2282 Operation.__init__(self, **kwargs)
2275 self.isConfig = False
2283 self.isConfig = False
2276
2284
2277
2285
2278 def setup(self, dataOut, minHei, maxHei, minRef, maxRef, th, thdB, rangeHeiList):
2286 def setup(self, dataOut, minHei, maxHei, minRef, maxRef, th, thdB, rangeHeiList):
2279
2287
2280 if rangeHeiList!=None:
2288 if rangeHeiList!=None:
2281 self.byRanges = True
2289 self.byRanges = True
2282 else:
2290 else:
2283 if minHei==None or maxHei==None :
2291 if minHei==None or maxHei==None :
2284 raise ValueError("Parameters heights are required")
2292 raise ValueError("Parameters heights are required")
2285 if minRef==None or maxRef==None:
2293 if minRef==None or maxRef==None:
2286 raise ValueError("Parameters heights are required")
2294 raise ValueError("Parameters heights are required")
2287
2295
2288 if self.byRanges:
2296 if self.byRanges:
2289 self.min_sats = []
2297 self.min_sats = []
2290 self.max_sats = []
2298 self.max_sats = []
2291 for min,max in rangeHeiList:
2299 for min,max in rangeHeiList:
2292 a,b = getHei_index(min, max, dataOut.heightList)
2300 a,b = getHei_index(min, max, dataOut.heightList)
2293 self.min_sats.append(a)
2301 self.min_sats.append(a)
2294 self.max_sats.append(b)
2302 self.max_sats.append(b)
2295 else:
2303 else:
2296 self.min_sats, self.max_sats = getHei_index(minHei, maxHei, dataOut.heightList)
2304 self.min_sats, self.max_sats = getHei_index(minHei, maxHei, dataOut.heightList)
2297 self.min_ref, self.max_ref = getHei_index(minRef, maxRef, dataOut.heightList)
2305 self.min_ref, self.max_ref = getHei_index(minRef, maxRef, dataOut.heightList)
2298 self.th = th
2306 self.th = th
2299 self.thdB = thdB
2307 self.thdB = thdB
2300 self.isConfig = True
2308 self.isConfig = True
2301
2309
2302
2310
2303 def compareRanges(self,data, minHei,maxHei):
2311 def compareRanges(self,data, minHei,maxHei):
2304
2312
2305 # ref = data[0,self.min_ref:self.max_ref] * numpy.conjugate(data[0,self.min_ref:self.max_ref])
2313 # ref = data[0,self.min_ref:self.max_ref] * numpy.conjugate(data[0,self.min_ref:self.max_ref])
2306 # p_ref = 10*numpy.log10(ref.real)
2314 # p_ref = 10*numpy.log10(ref.real)
2307 # m_ref = numpy.mean(p_ref)
2315 # m_ref = numpy.mean(p_ref)
2308
2316
2309 m_ref = self.noise
2317 m_ref = self.noise
2310
2318
2311 sats = data[0,minHei:maxHei] * numpy.conjugate(data[0,minHei:maxHei])
2319 sats = data[0,minHei:maxHei] * numpy.conjugate(data[0,minHei:maxHei])
2312 p_sats = 10*numpy.log10(sats.real)
2320 p_sats = 10*numpy.log10(sats.real)
2313 m_sats = numpy.mean(p_sats)
2321 m_sats = numpy.mean(p_sats)
2314
2322
2315 if m_sats > (m_ref + self.th): #and (m_sats > self.thdB):
2323 if m_sats > (m_ref + self.th): #and (m_sats > self.thdB):
2316 #print("msats: ",m_sats," \tmRef: ", m_ref, "\t",(m_sats - m_ref))
2324 #print("msats: ",m_sats," \tmRef: ", m_ref, "\t",(m_sats - m_ref))
2317 #print("Removing profiles...")
2325 #print("Removing profiles...")
2318 return False
2326 return False
2319
2327
2320 return True
2328 return True
2321
2329
2322 def isProfileClean(self, data):
2330 def isProfileClean(self, data):
2323 '''
2331 '''
2324 Analiza solo 1 canal, y descarta todos...
2332 Analiza solo 1 canal, y descarta todos...
2325 '''
2333 '''
2326
2334
2327 clean = True
2335 clean = True
2328
2336
2329 if self.byRanges:
2337 if self.byRanges:
2330
2338
2331 for n in range(len(self.min_sats)):
2339 for n in range(len(self.min_sats)):
2332 c = self.compareRanges(data,self.min_sats[n],self.max_sats[n])
2340 c = self.compareRanges(data,self.min_sats[n],self.max_sats[n])
2333 clean = clean and c
2341 clean = clean and c
2334 else:
2342 else:
2335
2343
2336 clean = (self.compareRanges(data, self.min_sats,self.max_sats))
2344 clean = (self.compareRanges(data, self.min_sats,self.max_sats))
2337
2345
2338 return clean
2346 return clean
2339
2347
2340
2348
2341
2349
2342 def run(self, dataOut, minHei=None, maxHei=None, minRef=None, maxRef=None, th=5, thdB=65, rangeHeiList=None):
2350 def run(self, dataOut, minHei=None, maxHei=None, minRef=None, maxRef=None, th=5, thdB=65, rangeHeiList=None):
2343 dataOut.flagNoData = True
2351 dataOut.flagNoData = True
2344
2352
2345 if not self.isConfig:
2353 if not self.isConfig:
2346 self.setup(dataOut, minHei, maxHei, minRef, maxRef, th, thdB, rangeHeiList)
2354 self.setup(dataOut, minHei, maxHei, minRef, maxRef, th, thdB, rangeHeiList)
2347 self.isConfig = True
2355 self.isConfig = True
2348 #print(self.min_sats,self.max_sats)
2356 #print(self.min_sats,self.max_sats)
2349 if dataOut.flagDataAsBlock:
2357 if dataOut.flagDataAsBlock:
2350 raise ValueError("ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False")
2358 raise ValueError("ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False")
2351
2359
2352 else:
2360 else:
2353 self.noise =10*numpy.log10(dataOut.getNoisebyHildebrand(ymin_index=self.min_ref, ymax_index=self.max_ref))
2361 self.noise =10*numpy.log10(dataOut.getNoisebyHildebrand(ymin_index=self.min_ref, ymax_index=self.max_ref))
2354 if not self.isProfileClean(dataOut.data):
2362 if not self.isProfileClean(dataOut.data):
2355 return dataOut
2363 return dataOut
2356 #dataOut.data = numpy.full((dataOut.nChannels,dataOut.nHeights),numpy.NAN)
2364 #dataOut.data = numpy.full((dataOut.nChannels,dataOut.nHeights),numpy.NAN)
2357 #self.count += 1
2365 #self.count += 1
2358
2366
2359 dataOut.flagNoData = False
2367 dataOut.flagNoData = False
2360
2368
2361 return dataOut
2369 return dataOut
General Comments 0
You need to be logged in to leave comments. Login now