##// END OF EJS Templates
Review decorator logic for ending process
Juan C. Espinoza -
r1193:c3967e412107
parent child
Show More
@@ -1,1257 +1,1256
1 '''
1 '''
2 Updated on January , 2018, for multiprocessing purposes
2 Updated on January , 2018, for multiprocessing purposes
3 Author: Sergio Cortez
3 Author: Sergio Cortez
4 Created on September , 2012
4 Created on September , 2012
5 '''
5 '''
6 from platform import python_version
6 from platform import python_version
7 import sys
7 import sys
8 import ast
8 import ast
9 import datetime
9 import datetime
10 import traceback
10 import traceback
11 import math
11 import math
12 import time
12 import time
13 import zmq
13 import zmq
14 from multiprocessing import Process, cpu_count
14 from multiprocessing import Process, cpu_count
15 from threading import Thread
15 from threading import Thread
16 from xml.etree.ElementTree import ElementTree, Element, SubElement, tostring
16 from xml.etree.ElementTree import ElementTree, Element, SubElement, tostring
17 from xml.dom import minidom
17 from xml.dom import minidom
18
18
19
19
20 from schainpy.admin import Alarm, SchainWarning
20 from schainpy.admin import Alarm, SchainWarning
21 from schainpy.model import *
21 from schainpy.model import *
22 from schainpy.utils import log
22 from schainpy.utils import log
23
23
24
24
25 DTYPES = {
25 DTYPES = {
26 'Voltage': '.r',
26 'Voltage': '.r',
27 'Spectra': '.pdata'
27 'Spectra': '.pdata'
28 }
28 }
29
29
30
30
31 def MPProject(project, n=cpu_count()):
31 def MPProject(project, n=cpu_count()):
32 '''
32 '''
33 Project wrapper to run schain in n processes
33 Project wrapper to run schain in n processes
34 '''
34 '''
35
35
36 rconf = project.getReadUnitObj()
36 rconf = project.getReadUnitObj()
37 op = rconf.getOperationObj('run')
37 op = rconf.getOperationObj('run')
38 dt1 = op.getParameterValue('startDate')
38 dt1 = op.getParameterValue('startDate')
39 dt2 = op.getParameterValue('endDate')
39 dt2 = op.getParameterValue('endDate')
40 tm1 = op.getParameterValue('startTime')
40 tm1 = op.getParameterValue('startTime')
41 tm2 = op.getParameterValue('endTime')
41 tm2 = op.getParameterValue('endTime')
42 days = (dt2 - dt1).days
42 days = (dt2 - dt1).days
43
43
44 for day in range(days + 1):
44 for day in range(days + 1):
45 skip = 0
45 skip = 0
46 cursor = 0
46 cursor = 0
47 processes = []
47 processes = []
48 dt = dt1 + datetime.timedelta(day)
48 dt = dt1 + datetime.timedelta(day)
49 dt_str = dt.strftime('%Y/%m/%d')
49 dt_str = dt.strftime('%Y/%m/%d')
50 reader = JRODataReader()
50 reader = JRODataReader()
51 paths, files = reader.searchFilesOffLine(path=rconf.path,
51 paths, files = reader.searchFilesOffLine(path=rconf.path,
52 startDate=dt,
52 startDate=dt,
53 endDate=dt,
53 endDate=dt,
54 startTime=tm1,
54 startTime=tm1,
55 endTime=tm2,
55 endTime=tm2,
56 ext=DTYPES[rconf.datatype])
56 ext=DTYPES[rconf.datatype])
57 nFiles = len(files)
57 nFiles = len(files)
58 if nFiles == 0:
58 if nFiles == 0:
59 continue
59 continue
60 skip = int(math.ceil(nFiles / n))
60 skip = int(math.ceil(nFiles / n))
61 while nFiles > cursor * skip:
61 while nFiles > cursor * skip:
62 rconf.update(startDate=dt_str, endDate=dt_str, cursor=cursor,
62 rconf.update(startDate=dt_str, endDate=dt_str, cursor=cursor,
63 skip=skip)
63 skip=skip)
64 p = project.clone()
64 p = project.clone()
65 p.start()
65 p.start()
66 processes.append(p)
66 processes.append(p)
67 cursor += 1
67 cursor += 1
68
68
69 def beforeExit(exctype, value, trace):
69 def beforeExit(exctype, value, trace):
70 for process in processes:
70 for process in processes:
71 process.terminate()
71 process.terminate()
72 process.join()
72 process.join()
73 print(traceback.print_tb(trace))
73 print(traceback.print_tb(trace))
74
74
75 sys.excepthook = beforeExit
75 sys.excepthook = beforeExit
76
76
77 for process in processes:
77 for process in processes:
78 process.join()
78 process.join()
79 process.terminate()
79 process.terminate()
80
80
81 time.sleep(3)
81 time.sleep(3)
82
82
83 def wait(context):
83 def wait(context):
84
84
85 time.sleep(1)
85 time.sleep(1)
86 c = zmq.Context()
86 c = zmq.Context()
87 receiver = c.socket(zmq.SUB)
87 receiver = c.socket(zmq.SUB)
88 receiver.connect('ipc:///tmp/schain_{}_pub'.format(self.id))
88 receiver.connect('ipc:///tmp/schain_{}_pub'.format(self.id))
89 receiver.setsockopt(zmq.SUBSCRIBE, self.id.encode())
89 receiver.setsockopt(zmq.SUBSCRIBE, self.id.encode())
90 msg = receiver.recv_multipart()[1]
90 msg = receiver.recv_multipart()[1]
91 context.terminate()
91 context.terminate()
92
92
93 class ParameterConf():
93 class ParameterConf():
94
94
95 id = None
95 id = None
96 name = None
96 name = None
97 value = None
97 value = None
98 format = None
98 format = None
99
99
100 __formated_value = None
100 __formated_value = None
101
101
102 ELEMENTNAME = 'Parameter'
102 ELEMENTNAME = 'Parameter'
103
103
104 def __init__(self):
104 def __init__(self):
105
105
106 self.format = 'str'
106 self.format = 'str'
107
107
108 def getElementName(self):
108 def getElementName(self):
109
109
110 return self.ELEMENTNAME
110 return self.ELEMENTNAME
111
111
112 def getValue(self):
112 def getValue(self):
113
113
114 value = self.value
114 value = self.value
115 format = self.format
115 format = self.format
116
116
117 if self.__formated_value != None:
117 if self.__formated_value != None:
118
118
119 return self.__formated_value
119 return self.__formated_value
120
120
121 if format == 'obj':
121 if format == 'obj':
122 return value
122 return value
123
123
124 if format == 'str':
124 if format == 'str':
125 self.__formated_value = str(value)
125 self.__formated_value = str(value)
126 return self.__formated_value
126 return self.__formated_value
127
127
128 if value == '':
128 if value == '':
129 raise ValueError('%s: This parameter value is empty' % self.name)
129 raise ValueError('%s: This parameter value is empty' % self.name)
130
130
131 if format == 'list':
131 if format == 'list':
132 strList = value.split(',')
132 strList = [s.strip() for s in value.split(',')]
133
134 self.__formated_value = strList
133 self.__formated_value = strList
135
134
136 return self.__formated_value
135 return self.__formated_value
137
136
138 if format == 'intlist':
137 if format == 'intlist':
139 '''
138 '''
140 Example:
139 Example:
141 value = (0,1,2)
140 value = (0,1,2)
142 '''
141 '''
143
142
144 new_value = ast.literal_eval(value)
143 new_value = ast.literal_eval(value)
145
144
146 if type(new_value) not in (tuple, list):
145 if type(new_value) not in (tuple, list):
147 new_value = [int(new_value)]
146 new_value = [int(new_value)]
148
147
149 self.__formated_value = new_value
148 self.__formated_value = new_value
150
149
151 return self.__formated_value
150 return self.__formated_value
152
151
153 if format == 'floatlist':
152 if format == 'floatlist':
154 '''
153 '''
155 Example:
154 Example:
156 value = (0.5, 1.4, 2.7)
155 value = (0.5, 1.4, 2.7)
157 '''
156 '''
158
157
159 new_value = ast.literal_eval(value)
158 new_value = ast.literal_eval(value)
160
159
161 if type(new_value) not in (tuple, list):
160 if type(new_value) not in (tuple, list):
162 new_value = [float(new_value)]
161 new_value = [float(new_value)]
163
162
164 self.__formated_value = new_value
163 self.__formated_value = new_value
165
164
166 return self.__formated_value
165 return self.__formated_value
167
166
168 if format == 'date':
167 if format == 'date':
169 strList = value.split('/')
168 strList = value.split('/')
170 intList = [int(x) for x in strList]
169 intList = [int(x) for x in strList]
171 date = datetime.date(intList[0], intList[1], intList[2])
170 date = datetime.date(intList[0], intList[1], intList[2])
172
171
173 self.__formated_value = date
172 self.__formated_value = date
174
173
175 return self.__formated_value
174 return self.__formated_value
176
175
177 if format == 'time':
176 if format == 'time':
178 strList = value.split(':')
177 strList = value.split(':')
179 intList = [int(x) for x in strList]
178 intList = [int(x) for x in strList]
180 time = datetime.time(intList[0], intList[1], intList[2])
179 time = datetime.time(intList[0], intList[1], intList[2])
181
180
182 self.__formated_value = time
181 self.__formated_value = time
183
182
184 return self.__formated_value
183 return self.__formated_value
185
184
186 if format == 'pairslist':
185 if format == 'pairslist':
187 '''
186 '''
188 Example:
187 Example:
189 value = (0,1),(1,2)
188 value = (0,1),(1,2)
190 '''
189 '''
191
190
192 new_value = ast.literal_eval(value)
191 new_value = ast.literal_eval(value)
193
192
194 if type(new_value) not in (tuple, list):
193 if type(new_value) not in (tuple, list):
195 raise ValueError('%s has to be a tuple or list of pairs' % value)
194 raise ValueError('%s has to be a tuple or list of pairs' % value)
196
195
197 if type(new_value[0]) not in (tuple, list):
196 if type(new_value[0]) not in (tuple, list):
198 if len(new_value) != 2:
197 if len(new_value) != 2:
199 raise ValueError('%s has to be a tuple or list of pairs' % value)
198 raise ValueError('%s has to be a tuple or list of pairs' % value)
200 new_value = [new_value]
199 new_value = [new_value]
201
200
202 for thisPair in new_value:
201 for thisPair in new_value:
203 if len(thisPair) != 2:
202 if len(thisPair) != 2:
204 raise ValueError('%s has to be a tuple or list of pairs' % value)
203 raise ValueError('%s has to be a tuple or list of pairs' % value)
205
204
206 self.__formated_value = new_value
205 self.__formated_value = new_value
207
206
208 return self.__formated_value
207 return self.__formated_value
209
208
210 if format == 'multilist':
209 if format == 'multilist':
211 '''
210 '''
212 Example:
211 Example:
213 value = (0,1,2),(3,4,5)
212 value = (0,1,2),(3,4,5)
214 '''
213 '''
215 multiList = ast.literal_eval(value)
214 multiList = ast.literal_eval(value)
216
215
217 if type(multiList[0]) == int:
216 if type(multiList[0]) == int:
218 multiList = ast.literal_eval('(' + value + ')')
217 multiList = ast.literal_eval('(' + value + ')')
219
218
220 self.__formated_value = multiList
219 self.__formated_value = multiList
221
220
222 return self.__formated_value
221 return self.__formated_value
223
222
224 if format == 'bool':
223 if format == 'bool':
225 value = int(value)
224 value = int(value)
226
225
227 if format == 'int':
226 if format == 'int':
228 value = float(value)
227 value = float(value)
229
228
230 format_func = eval(format)
229 format_func = eval(format)
231
230
232 self.__formated_value = format_func(value)
231 self.__formated_value = format_func(value)
233
232
234 return self.__formated_value
233 return self.__formated_value
235
234
236 def updateId(self, new_id):
235 def updateId(self, new_id):
237
236
238 self.id = str(new_id)
237 self.id = str(new_id)
239
238
240 def setup(self, id, name, value, format='str'):
239 def setup(self, id, name, value, format='str'):
241 self.id = str(id)
240 self.id = str(id)
242 self.name = name
241 self.name = name
243 if format == 'obj':
242 if format == 'obj':
244 self.value = value
243 self.value = value
245 else:
244 else:
246 self.value = str(value)
245 self.value = str(value)
247 self.format = str.lower(format)
246 self.format = str.lower(format)
248
247
249 self.getValue()
248 self.getValue()
250
249
251 return 1
250 return 1
252
251
253 def update(self, name, value, format='str'):
252 def update(self, name, value, format='str'):
254
253
255 self.name = name
254 self.name = name
256 self.value = str(value)
255 self.value = str(value)
257 self.format = format
256 self.format = format
258
257
259 def makeXml(self, opElement):
258 def makeXml(self, opElement):
260 if self.name not in ('queue',):
259 if self.name not in ('queue',):
261 parmElement = SubElement(opElement, self.ELEMENTNAME)
260 parmElement = SubElement(opElement, self.ELEMENTNAME)
262 parmElement.set('id', str(self.id))
261 parmElement.set('id', str(self.id))
263 parmElement.set('name', self.name)
262 parmElement.set('name', self.name)
264 parmElement.set('value', self.value)
263 parmElement.set('value', self.value)
265 parmElement.set('format', self.format)
264 parmElement.set('format', self.format)
266
265
267 def readXml(self, parmElement):
266 def readXml(self, parmElement):
268
267
269 self.id = parmElement.get('id')
268 self.id = parmElement.get('id')
270 self.name = parmElement.get('name')
269 self.name = parmElement.get('name')
271 self.value = parmElement.get('value')
270 self.value = parmElement.get('value')
272 self.format = str.lower(parmElement.get('format'))
271 self.format = str.lower(parmElement.get('format'))
273
272
274 # Compatible with old signal chain version
273 # Compatible with old signal chain version
275 if self.format == 'int' and self.name == 'idfigure':
274 if self.format == 'int' and self.name == 'idfigure':
276 self.name = 'id'
275 self.name = 'id'
277
276
278 def printattr(self):
277 def printattr(self):
279
278
280 print('Parameter[%s]: name = %s, value = %s, format = %s, project_id = %s' % (self.id, self.name, self.value, self.format, self.project_id))
279 print('Parameter[%s]: name = %s, value = %s, format = %s, project_id = %s' % (self.id, self.name, self.value, self.format, self.project_id))
281
280
282 class OperationConf():
281 class OperationConf():
283
282
284 ELEMENTNAME = 'Operation'
283 ELEMENTNAME = 'Operation'
285
284
286 def __init__(self):
285 def __init__(self):
287
286
288 self.id = '0'
287 self.id = '0'
289 self.name = None
288 self.name = None
290 self.priority = None
289 self.priority = None
291 self.topic = None
290 self.topic = None
292
291
293 def __getNewId(self):
292 def __getNewId(self):
294
293
295 return int(self.id) * 10 + len(self.parmConfObjList) + 1
294 return int(self.id) * 10 + len(self.parmConfObjList) + 1
296
295
297 def getId(self):
296 def getId(self):
298 return self.id
297 return self.id
299
298
300 def updateId(self, new_id):
299 def updateId(self, new_id):
301
300
302 self.id = str(new_id)
301 self.id = str(new_id)
303
302
304 n = 1
303 n = 1
305 for parmObj in self.parmConfObjList:
304 for parmObj in self.parmConfObjList:
306
305
307 idParm = str(int(new_id) * 10 + n)
306 idParm = str(int(new_id) * 10 + n)
308 parmObj.updateId(idParm)
307 parmObj.updateId(idParm)
309
308
310 n += 1
309 n += 1
311
310
312 def getElementName(self):
311 def getElementName(self):
313
312
314 return self.ELEMENTNAME
313 return self.ELEMENTNAME
315
314
316 def getParameterObjList(self):
315 def getParameterObjList(self):
317
316
318 return self.parmConfObjList
317 return self.parmConfObjList
319
318
320 def getParameterObj(self, parameterName):
319 def getParameterObj(self, parameterName):
321
320
322 for parmConfObj in self.parmConfObjList:
321 for parmConfObj in self.parmConfObjList:
323
322
324 if parmConfObj.name != parameterName:
323 if parmConfObj.name != parameterName:
325 continue
324 continue
326
325
327 return parmConfObj
326 return parmConfObj
328
327
329 return None
328 return None
330
329
331 def getParameterObjfromValue(self, parameterValue):
330 def getParameterObjfromValue(self, parameterValue):
332
331
333 for parmConfObj in self.parmConfObjList:
332 for parmConfObj in self.parmConfObjList:
334
333
335 if parmConfObj.getValue() != parameterValue:
334 if parmConfObj.getValue() != parameterValue:
336 continue
335 continue
337
336
338 return parmConfObj.getValue()
337 return parmConfObj.getValue()
339
338
340 return None
339 return None
341
340
342 def getParameterValue(self, parameterName):
341 def getParameterValue(self, parameterName):
343
342
344 parameterObj = self.getParameterObj(parameterName)
343 parameterObj = self.getParameterObj(parameterName)
345
344
346 # if not parameterObj:
345 # if not parameterObj:
347 # return None
346 # return None
348
347
349 value = parameterObj.getValue()
348 value = parameterObj.getValue()
350
349
351 return value
350 return value
352
351
353 def getKwargs(self):
352 def getKwargs(self):
354
353
355 kwargs = {}
354 kwargs = {}
356
355
357 for parmConfObj in self.parmConfObjList:
356 for parmConfObj in self.parmConfObjList:
358 if self.name == 'run' and parmConfObj.name == 'datatype':
357 if self.name == 'run' and parmConfObj.name == 'datatype':
359 continue
358 continue
360
359
361 kwargs[parmConfObj.name] = parmConfObj.getValue()
360 kwargs[parmConfObj.name] = parmConfObj.getValue()
362
361
363 return kwargs
362 return kwargs
364
363
365 def setup(self, id, name, priority, type, project_id):
364 def setup(self, id, name, priority, type, project_id):
366
365
367 self.id = str(id)
366 self.id = str(id)
368 self.project_id = project_id
367 self.project_id = project_id
369 self.name = name
368 self.name = name
370 self.type = type
369 self.type = type
371 self.priority = priority
370 self.priority = priority
372 self.parmConfObjList = []
371 self.parmConfObjList = []
373
372
374 def removeParameters(self):
373 def removeParameters(self):
375
374
376 for obj in self.parmConfObjList:
375 for obj in self.parmConfObjList:
377 del obj
376 del obj
378
377
379 self.parmConfObjList = []
378 self.parmConfObjList = []
380
379
381 def addParameter(self, name, value, format='str'):
380 def addParameter(self, name, value, format='str'):
382
381
383 if value is None:
382 if value is None:
384 return None
383 return None
385 id = self.__getNewId()
384 id = self.__getNewId()
386
385
387 parmConfObj = ParameterConf()
386 parmConfObj = ParameterConf()
388 if not parmConfObj.setup(id, name, value, format):
387 if not parmConfObj.setup(id, name, value, format):
389 return None
388 return None
390
389
391 self.parmConfObjList.append(parmConfObj)
390 self.parmConfObjList.append(parmConfObj)
392
391
393 return parmConfObj
392 return parmConfObj
394
393
395 def changeParameter(self, name, value, format='str'):
394 def changeParameter(self, name, value, format='str'):
396
395
397 parmConfObj = self.getParameterObj(name)
396 parmConfObj = self.getParameterObj(name)
398 parmConfObj.update(name, value, format)
397 parmConfObj.update(name, value, format)
399
398
400 return parmConfObj
399 return parmConfObj
401
400
402 def makeXml(self, procUnitElement):
401 def makeXml(self, procUnitElement):
403
402
404 opElement = SubElement(procUnitElement, self.ELEMENTNAME)
403 opElement = SubElement(procUnitElement, self.ELEMENTNAME)
405 opElement.set('id', str(self.id))
404 opElement.set('id', str(self.id))
406 opElement.set('name', self.name)
405 opElement.set('name', self.name)
407 opElement.set('type', self.type)
406 opElement.set('type', self.type)
408 opElement.set('priority', str(self.priority))
407 opElement.set('priority', str(self.priority))
409
408
410 for parmConfObj in self.parmConfObjList:
409 for parmConfObj in self.parmConfObjList:
411 parmConfObj.makeXml(opElement)
410 parmConfObj.makeXml(opElement)
412
411
413 def readXml(self, opElement, project_id):
412 def readXml(self, opElement, project_id):
414
413
415 self.id = opElement.get('id')
414 self.id = opElement.get('id')
416 self.name = opElement.get('name')
415 self.name = opElement.get('name')
417 self.type = opElement.get('type')
416 self.type = opElement.get('type')
418 self.priority = opElement.get('priority')
417 self.priority = opElement.get('priority')
419 self.project_id = str(project_id)
418 self.project_id = str(project_id)
420
419
421 # Compatible with old signal chain version
420 # Compatible with old signal chain version
422 # Use of 'run' method instead 'init'
421 # Use of 'run' method instead 'init'
423 if self.type == 'self' and self.name == 'init':
422 if self.type == 'self' and self.name == 'init':
424 self.name = 'run'
423 self.name = 'run'
425
424
426 self.parmConfObjList = []
425 self.parmConfObjList = []
427
426
428 parmElementList = opElement.iter(ParameterConf().getElementName())
427 parmElementList = opElement.iter(ParameterConf().getElementName())
429
428
430 for parmElement in parmElementList:
429 for parmElement in parmElementList:
431 parmConfObj = ParameterConf()
430 parmConfObj = ParameterConf()
432 parmConfObj.readXml(parmElement)
431 parmConfObj.readXml(parmElement)
433
432
434 # Compatible with old signal chain version
433 # Compatible with old signal chain version
435 # If an 'plot' OPERATION is found, changes name operation by the value of its type PARAMETER
434 # If an 'plot' OPERATION is found, changes name operation by the value of its type PARAMETER
436 if self.type != 'self' and self.name == 'Plot':
435 if self.type != 'self' and self.name == 'Plot':
437 if parmConfObj.format == 'str' and parmConfObj.name == 'type':
436 if parmConfObj.format == 'str' and parmConfObj.name == 'type':
438 self.name = parmConfObj.value
437 self.name = parmConfObj.value
439 continue
438 continue
440
439
441 self.parmConfObjList.append(parmConfObj)
440 self.parmConfObjList.append(parmConfObj)
442
441
443 def printattr(self):
442 def printattr(self):
444
443
445 print('%s[%s]: name = %s, type = %s, priority = %s, project_id = %s' % (self.ELEMENTNAME,
444 print('%s[%s]: name = %s, type = %s, priority = %s, project_id = %s' % (self.ELEMENTNAME,
446 self.id,
445 self.id,
447 self.name,
446 self.name,
448 self.type,
447 self.type,
449 self.priority,
448 self.priority,
450 self.project_id))
449 self.project_id))
451
450
452 for parmConfObj in self.parmConfObjList:
451 for parmConfObj in self.parmConfObjList:
453 parmConfObj.printattr()
452 parmConfObj.printattr()
454
453
455 def createObject(self):
454 def createObject(self):
456
455
457 className = eval(self.name)
456 className = eval(self.name)
458
457
459 if self.type == 'other':
458 if self.type == 'other':
460 opObj = className()
459 opObj = className()
461 elif self.type == 'external':
460 elif self.type == 'external':
462 kwargs = self.getKwargs()
461 kwargs = self.getKwargs()
463 opObj = className(self.id, self.project_id, **kwargs)
462 opObj = className(self.id, self.project_id, **kwargs)
464 opObj.start()
463 opObj.start()
465
464
466 return opObj
465 return opObj
467
466
468 class ProcUnitConf():
467 class ProcUnitConf():
469
468
470 ELEMENTNAME = 'ProcUnit'
469 ELEMENTNAME = 'ProcUnit'
471
470
472 def __init__(self):
471 def __init__(self):
473
472
474 self.id = None
473 self.id = None
475 self.datatype = None
474 self.datatype = None
476 self.name = None
475 self.name = None
477 self.inputId = None
476 self.inputId = None
478 self.opConfObjList = []
477 self.opConfObjList = []
479 self.procUnitObj = None
478 self.procUnitObj = None
480 self.opObjDict = {}
479 self.opObjDict = {}
481
480
482 def __getPriority(self):
481 def __getPriority(self):
483
482
484 return len(self.opConfObjList) + 1
483 return len(self.opConfObjList) + 1
485
484
486 def __getNewId(self):
485 def __getNewId(self):
487
486
488 return int(self.id) * 10 + len(self.opConfObjList) + 1
487 return int(self.id) * 10 + len(self.opConfObjList) + 1
489
488
490 def getElementName(self):
489 def getElementName(self):
491
490
492 return self.ELEMENTNAME
491 return self.ELEMENTNAME
493
492
494 def getId(self):
493 def getId(self):
495
494
496 return self.id
495 return self.id
497
496
498 def updateId(self, new_id):
497 def updateId(self, new_id):
499 '''
498 '''
500 new_id = int(parentId) * 10 + (int(self.id) % 10)
499 new_id = int(parentId) * 10 + (int(self.id) % 10)
501 new_inputId = int(parentId) * 10 + (int(self.inputId) % 10)
500 new_inputId = int(parentId) * 10 + (int(self.inputId) % 10)
502
501
503 # If this proc unit has not inputs
502 # If this proc unit has not inputs
504 #if self.inputId == '0':
503 #if self.inputId == '0':
505 #new_inputId = 0
504 #new_inputId = 0
506
505
507 n = 1
506 n = 1
508 for opConfObj in self.opConfObjList:
507 for opConfObj in self.opConfObjList:
509
508
510 idOp = str(int(new_id) * 10 + n)
509 idOp = str(int(new_id) * 10 + n)
511 opConfObj.updateId(idOp)
510 opConfObj.updateId(idOp)
512
511
513 n += 1
512 n += 1
514
513
515 self.parentId = str(parentId)
514 self.parentId = str(parentId)
516 self.id = str(new_id)
515 self.id = str(new_id)
517 #self.inputId = str(new_inputId)
516 #self.inputId = str(new_inputId)
518 '''
517 '''
519 n = 1
518 n = 1
520
519
521 def getInputId(self):
520 def getInputId(self):
522
521
523 return self.inputId
522 return self.inputId
524
523
525 def getOperationObjList(self):
524 def getOperationObjList(self):
526
525
527 return self.opConfObjList
526 return self.opConfObjList
528
527
529 def getOperationObj(self, name=None):
528 def getOperationObj(self, name=None):
530
529
531 for opConfObj in self.opConfObjList:
530 for opConfObj in self.opConfObjList:
532
531
533 if opConfObj.name != name:
532 if opConfObj.name != name:
534 continue
533 continue
535
534
536 return opConfObj
535 return opConfObj
537
536
538 return None
537 return None
539
538
540 def getOpObjfromParamValue(self, value=None):
539 def getOpObjfromParamValue(self, value=None):
541
540
542 for opConfObj in self.opConfObjList:
541 for opConfObj in self.opConfObjList:
543 if opConfObj.getParameterObjfromValue(parameterValue=value) != value:
542 if opConfObj.getParameterObjfromValue(parameterValue=value) != value:
544 continue
543 continue
545 return opConfObj
544 return opConfObj
546 return None
545 return None
547
546
548 def getProcUnitObj(self):
547 def getProcUnitObj(self):
549
548
550 return self.procUnitObj
549 return self.procUnitObj
551
550
552 def setup(self, project_id, id, name, datatype, inputId):
551 def setup(self, project_id, id, name, datatype, inputId):
553 '''
552 '''
554 id sera el topico a publicar
553 id sera el topico a publicar
555 inputId sera el topico a subscribirse
554 inputId sera el topico a subscribirse
556 '''
555 '''
557
556
558 # Compatible with old signal chain version
557 # Compatible with old signal chain version
559 if datatype == None and name == None:
558 if datatype == None and name == None:
560 raise ValueError('datatype or name should be defined')
559 raise ValueError('datatype or name should be defined')
561
560
562 #Definir una condicion para inputId cuando sea 0
561 #Definir una condicion para inputId cuando sea 0
563
562
564 if name == None:
563 if name == None:
565 if 'Proc' in datatype:
564 if 'Proc' in datatype:
566 name = datatype
565 name = datatype
567 else:
566 else:
568 name = '%sProc' % (datatype)
567 name = '%sProc' % (datatype)
569
568
570 if datatype == None:
569 if datatype == None:
571 datatype = name.replace('Proc', '')
570 datatype = name.replace('Proc', '')
572
571
573 self.id = str(id)
572 self.id = str(id)
574 self.project_id = project_id
573 self.project_id = project_id
575 self.name = name
574 self.name = name
576 self.datatype = datatype
575 self.datatype = datatype
577 self.inputId = inputId
576 self.inputId = inputId
578 self.opConfObjList = []
577 self.opConfObjList = []
579
578
580 self.addOperation(name='run', optype='self')
579 self.addOperation(name='run', optype='self')
581
580
582 def removeOperations(self):
581 def removeOperations(self):
583
582
584 for obj in self.opConfObjList:
583 for obj in self.opConfObjList:
585 del obj
584 del obj
586
585
587 self.opConfObjList = []
586 self.opConfObjList = []
588 self.addOperation(name='run')
587 self.addOperation(name='run')
589
588
590 def addParameter(self, **kwargs):
589 def addParameter(self, **kwargs):
591 '''
590 '''
592 Add parameters to 'run' operation
591 Add parameters to 'run' operation
593 '''
592 '''
594 opObj = self.opConfObjList[0]
593 opObj = self.opConfObjList[0]
595
594
596 opObj.addParameter(**kwargs)
595 opObj.addParameter(**kwargs)
597
596
598 return opObj
597 return opObj
599
598
600 def addOperation(self, name, optype='self'):
599 def addOperation(self, name, optype='self'):
601 '''
600 '''
602 Actualizacion - > proceso comunicacion
601 Actualizacion - > proceso comunicacion
603 En el caso de optype='self', elminar. DEfinir comuncacion IPC -> Topic
602 En el caso de optype='self', elminar. DEfinir comuncacion IPC -> Topic
604 definir el tipoc de socket o comunicacion ipc++
603 definir el tipoc de socket o comunicacion ipc++
605
604
606 '''
605 '''
607
606
608 id = self.__getNewId()
607 id = self.__getNewId()
609 priority = self.__getPriority() # Sin mucho sentido, pero puede usarse
608 priority = self.__getPriority() # Sin mucho sentido, pero puede usarse
610 opConfObj = OperationConf()
609 opConfObj = OperationConf()
611 opConfObj.setup(id, name=name, priority=priority, type=optype, project_id=self.project_id)
610 opConfObj.setup(id, name=name, priority=priority, type=optype, project_id=self.project_id)
612 self.opConfObjList.append(opConfObj)
611 self.opConfObjList.append(opConfObj)
613
612
614 return opConfObj
613 return opConfObj
615
614
616 def makeXml(self, projectElement):
615 def makeXml(self, projectElement):
617
616
618 procUnitElement = SubElement(projectElement, self.ELEMENTNAME)
617 procUnitElement = SubElement(projectElement, self.ELEMENTNAME)
619 procUnitElement.set('id', str(self.id))
618 procUnitElement.set('id', str(self.id))
620 procUnitElement.set('name', self.name)
619 procUnitElement.set('name', self.name)
621 procUnitElement.set('datatype', self.datatype)
620 procUnitElement.set('datatype', self.datatype)
622 procUnitElement.set('inputId', str(self.inputId))
621 procUnitElement.set('inputId', str(self.inputId))
623
622
624 for opConfObj in self.opConfObjList:
623 for opConfObj in self.opConfObjList:
625 opConfObj.makeXml(procUnitElement)
624 opConfObj.makeXml(procUnitElement)
626
625
627 def readXml(self, upElement, project_id):
626 def readXml(self, upElement, project_id):
628
627
629 self.id = upElement.get('id')
628 self.id = upElement.get('id')
630 self.name = upElement.get('name')
629 self.name = upElement.get('name')
631 self.datatype = upElement.get('datatype')
630 self.datatype = upElement.get('datatype')
632 self.inputId = upElement.get('inputId')
631 self.inputId = upElement.get('inputId')
633 self.project_id = str(project_id)
632 self.project_id = str(project_id)
634
633
635 if self.ELEMENTNAME == 'ReadUnit':
634 if self.ELEMENTNAME == 'ReadUnit':
636 self.datatype = self.datatype.replace('Reader', '')
635 self.datatype = self.datatype.replace('Reader', '')
637
636
638 if self.ELEMENTNAME == 'ProcUnit':
637 if self.ELEMENTNAME == 'ProcUnit':
639 self.datatype = self.datatype.replace('Proc', '')
638 self.datatype = self.datatype.replace('Proc', '')
640
639
641 if self.inputId == 'None':
640 if self.inputId == 'None':
642 self.inputId = '0'
641 self.inputId = '0'
643
642
644 self.opConfObjList = []
643 self.opConfObjList = []
645
644
646 opElementList = upElement.iter(OperationConf().getElementName())
645 opElementList = upElement.iter(OperationConf().getElementName())
647
646
648 for opElement in opElementList:
647 for opElement in opElementList:
649 opConfObj = OperationConf()
648 opConfObj = OperationConf()
650 opConfObj.readXml(opElement, project_id)
649 opConfObj.readXml(opElement, project_id)
651 self.opConfObjList.append(opConfObj)
650 self.opConfObjList.append(opConfObj)
652
651
653 def printattr(self):
652 def printattr(self):
654
653
655 print('%s[%s]: name = %s, datatype = %s, inputId = %s, project_id = %s' % (self.ELEMENTNAME,
654 print('%s[%s]: name = %s, datatype = %s, inputId = %s, project_id = %s' % (self.ELEMENTNAME,
656 self.id,
655 self.id,
657 self.name,
656 self.name,
658 self.datatype,
657 self.datatype,
659 self.inputId,
658 self.inputId,
660 self.project_id))
659 self.project_id))
661
660
662 for opConfObj in self.opConfObjList:
661 for opConfObj in self.opConfObjList:
663 opConfObj.printattr()
662 opConfObj.printattr()
664
663
665 def getKwargs(self):
664 def getKwargs(self):
666
665
667 opObj = self.opConfObjList[0]
666 opObj = self.opConfObjList[0]
668 kwargs = opObj.getKwargs()
667 kwargs = opObj.getKwargs()
669
668
670 return kwargs
669 return kwargs
671
670
672 def createObjects(self):
671 def createObjects(self):
673 '''
672 '''
674 Instancia de unidades de procesamiento.
673 Instancia de unidades de procesamiento.
675 '''
674 '''
676
675
677 className = eval(self.name)
676 className = eval(self.name)
678 kwargs = self.getKwargs()
677 kwargs = self.getKwargs()
679 procUnitObj = className(self.id, self.inputId, self.project_id, **kwargs) # necesitan saber su id y su entrada por fines de ipc
678 procUnitObj = className(self.id, self.inputId, self.project_id, **kwargs) # necesitan saber su id y su entrada por fines de ipc
680 log.success('creating process...', self.name)
679 log.success('creating process...', self.name)
681
680
682 for opConfObj in self.opConfObjList:
681 for opConfObj in self.opConfObjList:
683
682
684 if opConfObj.type == 'self' and opConfObj.name == 'run':
683 if opConfObj.type == 'self' and opConfObj.name == 'run':
685 continue
684 continue
686 elif opConfObj.type == 'self':
685 elif opConfObj.type == 'self':
687 opObj = getattr(procUnitObj, opConfObj.name)
686 opObj = getattr(procUnitObj, opConfObj.name)
688 else:
687 else:
689 opObj = opConfObj.createObject()
688 opObj = opConfObj.createObject()
690
689
691 log.success('creating operation: {}, type:{}'.format(
690 log.success('creating operation: {}, type:{}'.format(
692 opConfObj.name,
691 opConfObj.name,
693 opConfObj.type), self.name)
692 opConfObj.type), self.name)
694
693
695 procUnitObj.addOperation(opConfObj, opObj)
694 procUnitObj.addOperation(opConfObj, opObj)
696
695
697 procUnitObj.start()
696 procUnitObj.start()
698 self.procUnitObj = procUnitObj
697 self.procUnitObj = procUnitObj
699
698
700 def close(self):
699 def close(self):
701
700
702 for opConfObj in self.opConfObjList:
701 for opConfObj in self.opConfObjList:
703 if opConfObj.type == 'self':
702 if opConfObj.type == 'self':
704 continue
703 continue
705
704
706 opObj = self.procUnitObj.getOperationObj(opConfObj.id)
705 opObj = self.procUnitObj.getOperationObj(opConfObj.id)
707 opObj.close()
706 opObj.close()
708
707
709 self.procUnitObj.close()
708 self.procUnitObj.close()
710
709
711 return
710 return
712
711
713
712
714 class ReadUnitConf(ProcUnitConf):
713 class ReadUnitConf(ProcUnitConf):
715
714
716 ELEMENTNAME = 'ReadUnit'
715 ELEMENTNAME = 'ReadUnit'
717
716
718 def __init__(self):
717 def __init__(self):
719
718
720 self.id = None
719 self.id = None
721 self.datatype = None
720 self.datatype = None
722 self.name = None
721 self.name = None
723 self.inputId = None
722 self.inputId = None
724 self.opConfObjList = []
723 self.opConfObjList = []
725
724
726 def getElementName(self):
725 def getElementName(self):
727
726
728 return self.ELEMENTNAME
727 return self.ELEMENTNAME
729
728
730 def setup(self, project_id, id, name, datatype, path='', startDate='', endDate='',
729 def setup(self, project_id, id, name, datatype, path='', startDate='', endDate='',
731 startTime='', endTime='', server=None, **kwargs):
730 startTime='', endTime='', server=None, **kwargs):
732
731
733
732
734 '''
733 '''
735 *****el id del proceso sera el Topico
734 *****el id del proceso sera el Topico
736
735
737 Adicion de {topic}, si no esta presente -> error
736 Adicion de {topic}, si no esta presente -> error
738 kwargs deben ser trasmitidos en la instanciacion
737 kwargs deben ser trasmitidos en la instanciacion
739
738
740 '''
739 '''
741
740
742 # Compatible with old signal chain version
741 # Compatible with old signal chain version
743 if datatype == None and name == None:
742 if datatype == None and name == None:
744 raise ValueError('datatype or name should be defined')
743 raise ValueError('datatype or name should be defined')
745 if name == None:
744 if name == None:
746 if 'Reader' in datatype:
745 if 'Reader' in datatype:
747 name = datatype
746 name = datatype
748 datatype = name.replace('Reader','')
747 datatype = name.replace('Reader','')
749 else:
748 else:
750 name = '{}Reader'.format(datatype)
749 name = '{}Reader'.format(datatype)
751 if datatype == None:
750 if datatype == None:
752 if 'Reader' in name:
751 if 'Reader' in name:
753 datatype = name.replace('Reader','')
752 datatype = name.replace('Reader','')
754 else:
753 else:
755 datatype = name
754 datatype = name
756 name = '{}Reader'.format(name)
755 name = '{}Reader'.format(name)
757
756
758 self.id = id
757 self.id = id
759 self.project_id = project_id
758 self.project_id = project_id
760 self.name = name
759 self.name = name
761 self.datatype = datatype
760 self.datatype = datatype
762 if path != '':
761 if path != '':
763 self.path = os.path.abspath(path)
762 self.path = os.path.abspath(path)
764 self.startDate = startDate
763 self.startDate = startDate
765 self.endDate = endDate
764 self.endDate = endDate
766 self.startTime = startTime
765 self.startTime = startTime
767 self.endTime = endTime
766 self.endTime = endTime
768 self.server = server
767 self.server = server
769 self.addRunOperation(**kwargs)
768 self.addRunOperation(**kwargs)
770
769
771 def update(self, **kwargs):
770 def update(self, **kwargs):
772
771
773 if 'datatype' in kwargs:
772 if 'datatype' in kwargs:
774 datatype = kwargs.pop('datatype')
773 datatype = kwargs.pop('datatype')
775 if 'Reader' in datatype:
774 if 'Reader' in datatype:
776 self.name = datatype
775 self.name = datatype
777 else:
776 else:
778 self.name = '%sReader' % (datatype)
777 self.name = '%sReader' % (datatype)
779 self.datatype = self.name.replace('Reader', '')
778 self.datatype = self.name.replace('Reader', '')
780
779
781 attrs = ('path', 'startDate', 'endDate',
780 attrs = ('path', 'startDate', 'endDate',
782 'startTime', 'endTime')
781 'startTime', 'endTime')
783
782
784 for attr in attrs:
783 for attr in attrs:
785 if attr in kwargs:
784 if attr in kwargs:
786 setattr(self, attr, kwargs.pop(attr))
785 setattr(self, attr, kwargs.pop(attr))
787
786
788 self.updateRunOperation(**kwargs)
787 self.updateRunOperation(**kwargs)
789
788
790 def removeOperations(self):
789 def removeOperations(self):
791
790
792 for obj in self.opConfObjList:
791 for obj in self.opConfObjList:
793 del obj
792 del obj
794
793
795 self.opConfObjList = []
794 self.opConfObjList = []
796
795
797 def addRunOperation(self, **kwargs):
796 def addRunOperation(self, **kwargs):
798
797
799 opObj = self.addOperation(name='run', optype='self')
798 opObj = self.addOperation(name='run', optype='self')
800
799
801 if self.server is None:
800 if self.server is None:
802 opObj.addParameter(
801 opObj.addParameter(
803 name='datatype', value=self.datatype, format='str')
802 name='datatype', value=self.datatype, format='str')
804 opObj.addParameter(name='path', value=self.path, format='str')
803 opObj.addParameter(name='path', value=self.path, format='str')
805 opObj.addParameter(
804 opObj.addParameter(
806 name='startDate', value=self.startDate, format='date')
805 name='startDate', value=self.startDate, format='date')
807 opObj.addParameter(
806 opObj.addParameter(
808 name='endDate', value=self.endDate, format='date')
807 name='endDate', value=self.endDate, format='date')
809 opObj.addParameter(
808 opObj.addParameter(
810 name='startTime', value=self.startTime, format='time')
809 name='startTime', value=self.startTime, format='time')
811 opObj.addParameter(
810 opObj.addParameter(
812 name='endTime', value=self.endTime, format='time')
811 name='endTime', value=self.endTime, format='time')
813
812
814 for key, value in list(kwargs.items()):
813 for key, value in list(kwargs.items()):
815 opObj.addParameter(name=key, value=value,
814 opObj.addParameter(name=key, value=value,
816 format=type(value).__name__)
815 format=type(value).__name__)
817 else:
816 else:
818 opObj.addParameter(name='server', value=self.server, format='str')
817 opObj.addParameter(name='server', value=self.server, format='str')
819
818
820 return opObj
819 return opObj
821
820
822 def updateRunOperation(self, **kwargs):
821 def updateRunOperation(self, **kwargs):
823
822
824 opObj = self.getOperationObj(name='run')
823 opObj = self.getOperationObj(name='run')
825 opObj.removeParameters()
824 opObj.removeParameters()
826
825
827 opObj.addParameter(name='datatype', value=self.datatype, format='str')
826 opObj.addParameter(name='datatype', value=self.datatype, format='str')
828 opObj.addParameter(name='path', value=self.path, format='str')
827 opObj.addParameter(name='path', value=self.path, format='str')
829 opObj.addParameter(
828 opObj.addParameter(
830 name='startDate', value=self.startDate, format='date')
829 name='startDate', value=self.startDate, format='date')
831 opObj.addParameter(name='endDate', value=self.endDate, format='date')
830 opObj.addParameter(name='endDate', value=self.endDate, format='date')
832 opObj.addParameter(
831 opObj.addParameter(
833 name='startTime', value=self.startTime, format='time')
832 name='startTime', value=self.startTime, format='time')
834 opObj.addParameter(name='endTime', value=self.endTime, format='time')
833 opObj.addParameter(name='endTime', value=self.endTime, format='time')
835
834
836 for key, value in list(kwargs.items()):
835 for key, value in list(kwargs.items()):
837 opObj.addParameter(name=key, value=value,
836 opObj.addParameter(name=key, value=value,
838 format=type(value).__name__)
837 format=type(value).__name__)
839
838
840 return opObj
839 return opObj
841
840
842 def readXml(self, upElement, project_id):
841 def readXml(self, upElement, project_id):
843
842
844 self.id = upElement.get('id')
843 self.id = upElement.get('id')
845 self.name = upElement.get('name')
844 self.name = upElement.get('name')
846 self.datatype = upElement.get('datatype')
845 self.datatype = upElement.get('datatype')
847 self.project_id = str(project_id) #yong
846 self.project_id = str(project_id) #yong
848
847
849 if self.ELEMENTNAME == 'ReadUnit':
848 if self.ELEMENTNAME == 'ReadUnit':
850 self.datatype = self.datatype.replace('Reader', '')
849 self.datatype = self.datatype.replace('Reader', '')
851
850
852 self.opConfObjList = []
851 self.opConfObjList = []
853
852
854 opElementList = upElement.iter(OperationConf().getElementName())
853 opElementList = upElement.iter(OperationConf().getElementName())
855
854
856 for opElement in opElementList:
855 for opElement in opElementList:
857 opConfObj = OperationConf()
856 opConfObj = OperationConf()
858 opConfObj.readXml(opElement, project_id)
857 opConfObj.readXml(opElement, project_id)
859 self.opConfObjList.append(opConfObj)
858 self.opConfObjList.append(opConfObj)
860
859
861 if opConfObj.name == 'run':
860 if opConfObj.name == 'run':
862 self.path = opConfObj.getParameterValue('path')
861 self.path = opConfObj.getParameterValue('path')
863 self.startDate = opConfObj.getParameterValue('startDate')
862 self.startDate = opConfObj.getParameterValue('startDate')
864 self.endDate = opConfObj.getParameterValue('endDate')
863 self.endDate = opConfObj.getParameterValue('endDate')
865 self.startTime = opConfObj.getParameterValue('startTime')
864 self.startTime = opConfObj.getParameterValue('startTime')
866 self.endTime = opConfObj.getParameterValue('endTime')
865 self.endTime = opConfObj.getParameterValue('endTime')
867
866
868
867
869 class Project(Process):
868 class Project(Process):
870
869
871 ELEMENTNAME = 'Project'
870 ELEMENTNAME = 'Project'
872
871
873 def __init__(self):
872 def __init__(self):
874
873
875 Process.__init__(self)
874 Process.__init__(self)
876 self.id = None
875 self.id = None
877 self.filename = None
876 self.filename = None
878 self.description = None
877 self.description = None
879 self.email = None
878 self.email = None
880 self.alarm = None
879 self.alarm = None
881 self.procUnitConfObjDict = {}
880 self.procUnitConfObjDict = {}
882
881
883 def __getNewId(self):
882 def __getNewId(self):
884
883
885 idList = list(self.procUnitConfObjDict.keys())
884 idList = list(self.procUnitConfObjDict.keys())
886 id = int(self.id) * 10
885 id = int(self.id) * 10
887
886
888 while True:
887 while True:
889 id += 1
888 id += 1
890
889
891 if str(id) in idList:
890 if str(id) in idList:
892 continue
891 continue
893
892
894 break
893 break
895
894
896 return str(id)
895 return str(id)
897
896
898 def getElementName(self):
897 def getElementName(self):
899
898
900 return self.ELEMENTNAME
899 return self.ELEMENTNAME
901
900
902 def getId(self):
901 def getId(self):
903
902
904 return self.id
903 return self.id
905
904
906 def updateId(self, new_id):
905 def updateId(self, new_id):
907
906
908 self.id = str(new_id)
907 self.id = str(new_id)
909
908
910 keyList = list(self.procUnitConfObjDict.keys())
909 keyList = list(self.procUnitConfObjDict.keys())
911 keyList.sort()
910 keyList.sort()
912
911
913 n = 1
912 n = 1
914 newProcUnitConfObjDict = {}
913 newProcUnitConfObjDict = {}
915
914
916 for procKey in keyList:
915 for procKey in keyList:
917
916
918 procUnitConfObj = self.procUnitConfObjDict[procKey]
917 procUnitConfObj = self.procUnitConfObjDict[procKey]
919 idProcUnit = str(int(self.id) * 10 + n)
918 idProcUnit = str(int(self.id) * 10 + n)
920 procUnitConfObj.updateId(idProcUnit)
919 procUnitConfObj.updateId(idProcUnit)
921 newProcUnitConfObjDict[idProcUnit] = procUnitConfObj
920 newProcUnitConfObjDict[idProcUnit] = procUnitConfObj
922 n += 1
921 n += 1
923
922
924 self.procUnitConfObjDict = newProcUnitConfObjDict
923 self.procUnitConfObjDict = newProcUnitConfObjDict
925
924
926 def setup(self, id=1, name='', description='', email=None, alarm=[]):
925 def setup(self, id=1, name='', description='', email=None, alarm=[]):
927
926
928 print(' ')
927 print(' ')
929 print('*' * 60)
928 print('*' * 60)
930 print('* Starting SIGNAL CHAIN PROCESSING (Multiprocessing) v%s *' % schainpy.__version__)
929 print('* Starting SIGNAL CHAIN PROCESSING (Multiprocessing) v%s *' % schainpy.__version__)
931 print('*' * 60)
930 print('*' * 60)
932 print("* Python " + python_version() + " *")
931 print("* Python " + python_version() + " *")
933 print('*' * 19)
932 print('*' * 19)
934 print(' ')
933 print(' ')
935 self.id = str(id)
934 self.id = str(id)
936 self.description = description
935 self.description = description
937 self.email = email
936 self.email = email
938 self.alarm = alarm
937 self.alarm = alarm
939
938
940 def update(self, **kwargs):
939 def update(self, **kwargs):
941
940
942 for key, value in list(kwargs.items()):
941 for key, value in list(kwargs.items()):
943 setattr(self, key, value)
942 setattr(self, key, value)
944
943
945 def clone(self):
944 def clone(self):
946
945
947 p = Project()
946 p = Project()
948 p.procUnitConfObjDict = self.procUnitConfObjDict
947 p.procUnitConfObjDict = self.procUnitConfObjDict
949 return p
948 return p
950
949
951 def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
950 def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
952
951
953 '''
952 '''
954 Actualizacion:
953 Actualizacion:
955 Se agrego un nuevo argumento: topic -relativo a la forma de comunicar los procesos simultaneos
954 Se agrego un nuevo argumento: topic -relativo a la forma de comunicar los procesos simultaneos
956
955
957 * El id del proceso sera el topico al que se deben subscribir los procUnits para recibir la informacion(data)
956 * El id del proceso sera el topico al que se deben subscribir los procUnits para recibir la informacion(data)
958
957
959 '''
958 '''
960
959
961 if id is None:
960 if id is None:
962 idReadUnit = self.__getNewId()
961 idReadUnit = self.__getNewId()
963 else:
962 else:
964 idReadUnit = str(id)
963 idReadUnit = str(id)
965
964
966 readUnitConfObj = ReadUnitConf()
965 readUnitConfObj = ReadUnitConf()
967 readUnitConfObj.setup(self.id, idReadUnit, name, datatype, **kwargs)
966 readUnitConfObj.setup(self.id, idReadUnit, name, datatype, **kwargs)
968 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
967 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
969
968
970 return readUnitConfObj
969 return readUnitConfObj
971
970
972 def addProcUnit(self, inputId='0', datatype=None, name=None):
971 def addProcUnit(self, inputId='0', datatype=None, name=None):
973
972
974 '''
973 '''
975 Actualizacion:
974 Actualizacion:
976 Se agrego dos nuevos argumentos: topic_read (lee data de otro procUnit) y topic_write(escribe o envia data a otro procUnit)
975 Se agrego dos nuevos argumentos: topic_read (lee data de otro procUnit) y topic_write(escribe o envia data a otro procUnit)
977 Deberia reemplazar a "inputId"
976 Deberia reemplazar a "inputId"
978
977
979 ** A fin de mantener el inputID, este sera la representaacion del topicoal que deben subscribirse. El ID propio de la intancia
978 ** A fin de mantener el inputID, este sera la representaacion del topicoal que deben subscribirse. El ID propio de la intancia
980 (proceso) sera el topico de la publicacion, todo sera asignado de manera dinamica.
979 (proceso) sera el topico de la publicacion, todo sera asignado de manera dinamica.
981
980
982 '''
981 '''
983
982
984 idProcUnit = self.__getNewId() #Topico para subscripcion
983 idProcUnit = self.__getNewId() #Topico para subscripcion
985 procUnitConfObj = ProcUnitConf()
984 procUnitConfObj = ProcUnitConf()
986 procUnitConfObj.setup(self.id, idProcUnit, name, datatype, inputId) #topic_read, topic_write,
985 procUnitConfObj.setup(self.id, idProcUnit, name, datatype, inputId) #topic_read, topic_write,
987 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
986 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
988
987
989 return procUnitConfObj
988 return procUnitConfObj
990
989
991 def removeProcUnit(self, id):
990 def removeProcUnit(self, id):
992
991
993 if id in list(self.procUnitConfObjDict.keys()):
992 if id in list(self.procUnitConfObjDict.keys()):
994 self.procUnitConfObjDict.pop(id)
993 self.procUnitConfObjDict.pop(id)
995
994
996 def getReadUnitId(self):
995 def getReadUnitId(self):
997
996
998 readUnitConfObj = self.getReadUnitObj()
997 readUnitConfObj = self.getReadUnitObj()
999
998
1000 return readUnitConfObj.id
999 return readUnitConfObj.id
1001
1000
1002 def getReadUnitObj(self):
1001 def getReadUnitObj(self):
1003
1002
1004 for obj in list(self.procUnitConfObjDict.values()):
1003 for obj in list(self.procUnitConfObjDict.values()):
1005 if obj.getElementName() == 'ReadUnit':
1004 if obj.getElementName() == 'ReadUnit':
1006 return obj
1005 return obj
1007
1006
1008 return None
1007 return None
1009
1008
1010 def getProcUnitObj(self, id=None, name=None):
1009 def getProcUnitObj(self, id=None, name=None):
1011
1010
1012 if id != None:
1011 if id != None:
1013 return self.procUnitConfObjDict[id]
1012 return self.procUnitConfObjDict[id]
1014
1013
1015 if name != None:
1014 if name != None:
1016 return self.getProcUnitObjByName(name)
1015 return self.getProcUnitObjByName(name)
1017
1016
1018 return None
1017 return None
1019
1018
1020 def getProcUnitObjByName(self, name):
1019 def getProcUnitObjByName(self, name):
1021
1020
1022 for obj in list(self.procUnitConfObjDict.values()):
1021 for obj in list(self.procUnitConfObjDict.values()):
1023 if obj.name == name:
1022 if obj.name == name:
1024 return obj
1023 return obj
1025
1024
1026 return None
1025 return None
1027
1026
1028 def procUnitItems(self):
1027 def procUnitItems(self):
1029
1028
1030 return list(self.procUnitConfObjDict.items())
1029 return list(self.procUnitConfObjDict.items())
1031
1030
1032 def makeXml(self):
1031 def makeXml(self):
1033
1032
1034 projectElement = Element('Project')
1033 projectElement = Element('Project')
1035 projectElement.set('id', str(self.id))
1034 projectElement.set('id', str(self.id))
1036 projectElement.set('name', self.name)
1035 projectElement.set('name', self.name)
1037 projectElement.set('description', self.description)
1036 projectElement.set('description', self.description)
1038
1037
1039 for procUnitConfObj in list(self.procUnitConfObjDict.values()):
1038 for procUnitConfObj in list(self.procUnitConfObjDict.values()):
1040 procUnitConfObj.makeXml(projectElement)
1039 procUnitConfObj.makeXml(projectElement)
1041
1040
1042 self.projectElement = projectElement
1041 self.projectElement = projectElement
1043
1042
1044 def writeXml(self, filename=None):
1043 def writeXml(self, filename=None):
1045
1044
1046 if filename == None:
1045 if filename == None:
1047 if self.filename:
1046 if self.filename:
1048 filename = self.filename
1047 filename = self.filename
1049 else:
1048 else:
1050 filename = 'schain.xml'
1049 filename = 'schain.xml'
1051
1050
1052 if not filename:
1051 if not filename:
1053 print('filename has not been defined. Use setFilename(filename) for do it.')
1052 print('filename has not been defined. Use setFilename(filename) for do it.')
1054 return 0
1053 return 0
1055
1054
1056 abs_file = os.path.abspath(filename)
1055 abs_file = os.path.abspath(filename)
1057
1056
1058 if not os.access(os.path.dirname(abs_file), os.W_OK):
1057 if not os.access(os.path.dirname(abs_file), os.W_OK):
1059 print('No write permission on %s' % os.path.dirname(abs_file))
1058 print('No write permission on %s' % os.path.dirname(abs_file))
1060 return 0
1059 return 0
1061
1060
1062 if os.path.isfile(abs_file) and not(os.access(abs_file, os.W_OK)):
1061 if os.path.isfile(abs_file) and not(os.access(abs_file, os.W_OK)):
1063 print('File %s already exists and it could not be overwriten' % abs_file)
1062 print('File %s already exists and it could not be overwriten' % abs_file)
1064 return 0
1063 return 0
1065
1064
1066 self.makeXml()
1065 self.makeXml()
1067
1066
1068 ElementTree(self.projectElement).write(abs_file, method='xml')
1067 ElementTree(self.projectElement).write(abs_file, method='xml')
1069
1068
1070 self.filename = abs_file
1069 self.filename = abs_file
1071
1070
1072 return 1
1071 return 1
1073
1072
1074 def readXml(self, filename=None):
1073 def readXml(self, filename=None):
1075
1074
1076 if not filename:
1075 if not filename:
1077 print('filename is not defined')
1076 print('filename is not defined')
1078 return 0
1077 return 0
1079
1078
1080 abs_file = os.path.abspath(filename)
1079 abs_file = os.path.abspath(filename)
1081
1080
1082 if not os.path.isfile(abs_file):
1081 if not os.path.isfile(abs_file):
1083 print('%s file does not exist' % abs_file)
1082 print('%s file does not exist' % abs_file)
1084 return 0
1083 return 0
1085
1084
1086 self.projectElement = None
1085 self.projectElement = None
1087 self.procUnitConfObjDict = {}
1086 self.procUnitConfObjDict = {}
1088
1087
1089 try:
1088 try:
1090 self.projectElement = ElementTree().parse(abs_file)
1089 self.projectElement = ElementTree().parse(abs_file)
1091 except:
1090 except:
1092 print('Error reading %s, verify file format' % filename)
1091 print('Error reading %s, verify file format' % filename)
1093 return 0
1092 return 0
1094
1093
1095 self.project = self.projectElement.tag
1094 self.project = self.projectElement.tag
1096
1095
1097 self.id = self.projectElement.get('id')
1096 self.id = self.projectElement.get('id')
1098 self.name = self.projectElement.get('name')
1097 self.name = self.projectElement.get('name')
1099 self.description = self.projectElement.get('description')
1098 self.description = self.projectElement.get('description')
1100
1099
1101 readUnitElementList = self.projectElement.iter(
1100 readUnitElementList = self.projectElement.iter(
1102 ReadUnitConf().getElementName())
1101 ReadUnitConf().getElementName())
1103
1102
1104 for readUnitElement in readUnitElementList:
1103 for readUnitElement in readUnitElementList:
1105 readUnitConfObj = ReadUnitConf()
1104 readUnitConfObj = ReadUnitConf()
1106 readUnitConfObj.readXml(readUnitElement, self.id)
1105 readUnitConfObj.readXml(readUnitElement, self.id)
1107 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
1106 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
1108
1107
1109 procUnitElementList = self.projectElement.iter(
1108 procUnitElementList = self.projectElement.iter(
1110 ProcUnitConf().getElementName())
1109 ProcUnitConf().getElementName())
1111
1110
1112 for procUnitElement in procUnitElementList:
1111 for procUnitElement in procUnitElementList:
1113 procUnitConfObj = ProcUnitConf()
1112 procUnitConfObj = ProcUnitConf()
1114 procUnitConfObj.readXml(procUnitElement, self.id)
1113 procUnitConfObj.readXml(procUnitElement, self.id)
1115 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
1114 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
1116
1115
1117 self.filename = abs_file
1116 self.filename = abs_file
1118
1117
1119 return 1
1118 return 1
1120
1119
1121 def __str__(self):
1120 def __str__(self):
1122
1121
1123 print('Project[%s]: name = %s, description = %s, project_id = %s' % (self.id,
1122 print('Project[%s]: name = %s, description = %s, project_id = %s' % (self.id,
1124 self.name,
1123 self.name,
1125 self.description,
1124 self.description,
1126 self.project_id))
1125 self.project_id))
1127
1126
1128 for procUnitConfObj in self.procUnitConfObjDict.values():
1127 for procUnitConfObj in self.procUnitConfObjDict.values():
1129 print(procUnitConfObj)
1128 print(procUnitConfObj)
1130
1129
1131 def createObjects(self):
1130 def createObjects(self):
1132
1131
1133
1132
1134 keys = list(self.procUnitConfObjDict.keys())
1133 keys = list(self.procUnitConfObjDict.keys())
1135 keys.sort()
1134 keys.sort()
1136 for key in keys:
1135 for key in keys:
1137 self.procUnitConfObjDict[key].createObjects()
1136 self.procUnitConfObjDict[key].createObjects()
1138
1137
1139 def __handleError(self, procUnitConfObj, modes=None, stdout=True):
1138 def __handleError(self, procUnitConfObj, modes=None, stdout=True):
1140
1139
1141 import socket
1140 import socket
1142
1141
1143 if modes is None:
1142 if modes is None:
1144 modes = self.alarm
1143 modes = self.alarm
1145
1144
1146 if not self.alarm:
1145 if not self.alarm:
1147 modes = []
1146 modes = []
1148
1147
1149 err = traceback.format_exception(sys.exc_info()[0],
1148 err = traceback.format_exception(sys.exc_info()[0],
1150 sys.exc_info()[1],
1149 sys.exc_info()[1],
1151 sys.exc_info()[2])
1150 sys.exc_info()[2])
1152
1151
1153 log.error('{}'.format(err[-1]), procUnitConfObj.name)
1152 log.error('{}'.format(err[-1]), procUnitConfObj.name)
1154
1153
1155 message = ''.join(err)
1154 message = ''.join(err)
1156
1155
1157 if stdout:
1156 if stdout:
1158 sys.stderr.write(message)
1157 sys.stderr.write(message)
1159
1158
1160 subject = 'SChain v%s: Error running %s\n' % (
1159 subject = 'SChain v%s: Error running %s\n' % (
1161 schainpy.__version__, procUnitConfObj.name)
1160 schainpy.__version__, procUnitConfObj.name)
1162
1161
1163 subtitle = '%s: %s\n' % (
1162 subtitle = '%s: %s\n' % (
1164 procUnitConfObj.getElementName(), procUnitConfObj.name)
1163 procUnitConfObj.getElementName(), procUnitConfObj.name)
1165 subtitle += 'Hostname: %s\n' % socket.gethostbyname(
1164 subtitle += 'Hostname: %s\n' % socket.gethostbyname(
1166 socket.gethostname())
1165 socket.gethostname())
1167 subtitle += 'Working directory: %s\n' % os.path.abspath('./')
1166 subtitle += 'Working directory: %s\n' % os.path.abspath('./')
1168 subtitle += 'Configuration file: %s\n' % self.filename
1167 subtitle += 'Configuration file: %s\n' % self.filename
1169 subtitle += 'Time: %s\n' % str(datetime.datetime.now())
1168 subtitle += 'Time: %s\n' % str(datetime.datetime.now())
1170
1169
1171 readUnitConfObj = self.getReadUnitObj()
1170 readUnitConfObj = self.getReadUnitObj()
1172 if readUnitConfObj:
1171 if readUnitConfObj:
1173 subtitle += '\nInput parameters:\n'
1172 subtitle += '\nInput parameters:\n'
1174 subtitle += '[Data path = %s]\n' % readUnitConfObj.path
1173 subtitle += '[Data path = %s]\n' % readUnitConfObj.path
1175 subtitle += '[Data type = %s]\n' % readUnitConfObj.datatype
1174 subtitle += '[Data type = %s]\n' % readUnitConfObj.datatype
1176 subtitle += '[Start date = %s]\n' % readUnitConfObj.startDate
1175 subtitle += '[Start date = %s]\n' % readUnitConfObj.startDate
1177 subtitle += '[End date = %s]\n' % readUnitConfObj.endDate
1176 subtitle += '[End date = %s]\n' % readUnitConfObj.endDate
1178 subtitle += '[Start time = %s]\n' % readUnitConfObj.startTime
1177 subtitle += '[Start time = %s]\n' % readUnitConfObj.startTime
1179 subtitle += '[End time = %s]\n' % readUnitConfObj.endTime
1178 subtitle += '[End time = %s]\n' % readUnitConfObj.endTime
1180
1179
1181 a = Alarm(
1180 a = Alarm(
1182 modes=modes,
1181 modes=modes,
1183 email=self.email,
1182 email=self.email,
1184 message=message,
1183 message=message,
1185 subject=subject,
1184 subject=subject,
1186 subtitle=subtitle,
1185 subtitle=subtitle,
1187 filename=self.filename
1186 filename=self.filename
1188 )
1187 )
1189
1188
1190 return a
1189 return a
1191
1190
1192 def isPaused(self):
1191 def isPaused(self):
1193 return 0
1192 return 0
1194
1193
1195 def isStopped(self):
1194 def isStopped(self):
1196 return 0
1195 return 0
1197
1196
1198 def runController(self):
1197 def runController(self):
1199 '''
1198 '''
1200 returns 0 when this process has been stopped, 1 otherwise
1199 returns 0 when this process has been stopped, 1 otherwise
1201 '''
1200 '''
1202
1201
1203 if self.isPaused():
1202 if self.isPaused():
1204 print('Process suspended')
1203 print('Process suspended')
1205
1204
1206 while True:
1205 while True:
1207 time.sleep(0.1)
1206 time.sleep(0.1)
1208
1207
1209 if not self.isPaused():
1208 if not self.isPaused():
1210 break
1209 break
1211
1210
1212 if self.isStopped():
1211 if self.isStopped():
1213 break
1212 break
1214
1213
1215 print('Process reinitialized')
1214 print('Process reinitialized')
1216
1215
1217 if self.isStopped():
1216 if self.isStopped():
1218 print('Process stopped')
1217 print('Process stopped')
1219 return 0
1218 return 0
1220
1219
1221 return 1
1220 return 1
1222
1221
1223 def setFilename(self, filename):
1222 def setFilename(self, filename):
1224
1223
1225 self.filename = filename
1224 self.filename = filename
1226
1225
1227 def setProxyCom(self):
1226 def setProxyCom(self):
1228
1227
1229 if not os.path.exists('/tmp/schain'):
1228 if not os.path.exists('/tmp/schain'):
1230 os.mkdir('/tmp/schain')
1229 os.mkdir('/tmp/schain')
1231
1230
1232 self.ctx = zmq.Context()
1231 self.ctx = zmq.Context()
1233 xpub = self.ctx.socket(zmq.XPUB)
1232 xpub = self.ctx.socket(zmq.XPUB)
1234 xpub.bind('ipc:///tmp/schain/{}_pub'.format(self.id))
1233 xpub.bind('ipc:///tmp/schain/{}_pub'.format(self.id))
1235 xsub = self.ctx.socket(zmq.XSUB)
1234 xsub = self.ctx.socket(zmq.XSUB)
1236 xsub.bind('ipc:///tmp/schain/{}_sub'.format(self.id))
1235 xsub.bind('ipc:///tmp/schain/{}_sub'.format(self.id))
1237
1236
1238 try:
1237 try:
1239 zmq.proxy(xpub, xsub)
1238 zmq.proxy(xpub, xsub)
1240 except: # zmq.ContextTerminated:
1239 except: # zmq.ContextTerminated:
1241 xpub.close()
1240 xpub.close()
1242 xsub.close()
1241 xsub.close()
1243
1242
1244 def run(self):
1243 def run(self):
1245
1244
1246 log.success('Starting {}: {}'.format(self.name, self.id), tag='')
1245 log.success('Starting {}: {}'.format(self.name, self.id), tag='')
1247 self.start_time = time.time()
1246 self.start_time = time.time()
1248 self.createObjects()
1247 self.createObjects()
1249 # t = Thread(target=wait, args=(self.ctx, ))
1248 # t = Thread(target=wait, args=(self.ctx, ))
1250 # t.start()
1249 # t.start()
1251 self.setProxyCom()
1250 self.setProxyCom()
1252
1251
1253 # Iniciar todos los procesos .start(), monitoreo de procesos. ELiminar lo de abajo
1252 # Iniciar todos los procesos .start(), monitoreo de procesos. ELiminar lo de abajo
1254
1253
1255 log.success('{} Done (time: {}s)'.format(
1254 log.success('{} Done (time: {}s)'.format(
1256 self.name,
1255 self.name,
1257 time.time()-self.start_time))
1256 time.time()-self.start_time))
@@ -1,803 +1,800
1
1
2 import os
2 import os
3 import sys
3 import sys
4 import zmq
4 import zmq
5 import time
5 import time
6 import datetime
6 import datetime
7 from functools import wraps
7 from functools import wraps
8 import numpy
8 import numpy
9 import matplotlib
9 import matplotlib
10
10
11 if 'BACKEND' in os.environ:
11 if 'BACKEND' in os.environ:
12 matplotlib.use(os.environ['BACKEND'])
12 matplotlib.use(os.environ['BACKEND'])
13 elif 'linux' in sys.platform:
13 elif 'linux' in sys.platform:
14 matplotlib.use("TkAgg")
14 matplotlib.use("TkAgg")
15 elif 'darwin' in sys.platform:
15 elif 'darwin' in sys.platform:
16 matplotlib.use('TkAgg')
16 matplotlib.use('TkAgg')
17 else:
17 else:
18 from schainpy.utils import log
18 from schainpy.utils import log
19 log.warning('Using default Backend="Agg"', 'INFO')
19 log.warning('Using default Backend="Agg"', 'INFO')
20 matplotlib.use('Agg')
20 matplotlib.use('Agg')
21
21
22 import matplotlib.pyplot as plt
22 import matplotlib.pyplot as plt
23 from matplotlib.patches import Polygon
23 from matplotlib.patches import Polygon
24 from mpl_toolkits.axes_grid1 import make_axes_locatable
24 from mpl_toolkits.axes_grid1 import make_axes_locatable
25 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
25 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
26
26
27 from schainpy.model.data.jrodata import PlotterData
27 from schainpy.model.data.jrodata import PlotterData
28 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
28 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
29 from schainpy.utils import log
29 from schainpy.utils import log
30
30
31 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
31 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
32 blu_values = matplotlib.pyplot.get_cmap(
32 blu_values = matplotlib.pyplot.get_cmap(
33 'seismic_r', 20)(numpy.arange(20))[10:15]
33 'seismic_r', 20)(numpy.arange(20))[10:15]
34 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
34 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
35 'jro', numpy.vstack((blu_values, jet_values)))
35 'jro', numpy.vstack((blu_values, jet_values)))
36 matplotlib.pyplot.register_cmap(cmap=ncmap)
36 matplotlib.pyplot.register_cmap(cmap=ncmap)
37
37
38 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
38 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis',
39 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
39 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
40
40
41 EARTH_RADIUS = 6.3710e3
41 EARTH_RADIUS = 6.3710e3
42
42
43
43
44 def ll2xy(lat1, lon1, lat2, lon2):
44 def ll2xy(lat1, lon1, lat2, lon2):
45
45
46 p = 0.017453292519943295
46 p = 0.017453292519943295
47 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
47 a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * \
48 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
48 numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2
49 r = 12742 * numpy.arcsin(numpy.sqrt(a))
49 r = 12742 * numpy.arcsin(numpy.sqrt(a))
50 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
50 theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)
51 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
51 * numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p))
52 theta = -theta + numpy.pi/2
52 theta = -theta + numpy.pi/2
53 return r*numpy.cos(theta), r*numpy.sin(theta)
53 return r*numpy.cos(theta), r*numpy.sin(theta)
54
54
55
55
56 def km2deg(km):
56 def km2deg(km):
57 '''
57 '''
58 Convert distance in km to degrees
58 Convert distance in km to degrees
59 '''
59 '''
60
60
61 return numpy.rad2deg(km/EARTH_RADIUS)
61 return numpy.rad2deg(km/EARTH_RADIUS)
62
62
63
63
64 def figpause(interval):
64 def figpause(interval):
65 backend = plt.rcParams['backend']
65 backend = plt.rcParams['backend']
66 if backend in matplotlib.rcsetup.interactive_bk:
66 if backend in matplotlib.rcsetup.interactive_bk:
67 figManager = matplotlib._pylab_helpers.Gcf.get_active()
67 figManager = matplotlib._pylab_helpers.Gcf.get_active()
68 if figManager is not None:
68 if figManager is not None:
69 canvas = figManager.canvas
69 canvas = figManager.canvas
70 if canvas.figure.stale:
70 if canvas.figure.stale:
71 canvas.draw()
71 canvas.draw()
72 try:
72 try:
73 canvas.start_event_loop(interval)
73 canvas.start_event_loop(interval)
74 except:
74 except:
75 pass
75 pass
76 return
76 return
77
77
78
78
79 def popup(message):
79 def popup(message):
80 '''
80 '''
81 '''
81 '''
82
82
83 fig = plt.figure(figsize=(12, 8), facecolor='r')
83 fig = plt.figure(figsize=(12, 8), facecolor='r')
84 text = '\n'.join([s.strip() for s in message.split(':')])
84 text = '\n'.join([s.strip() for s in message.split(':')])
85 fig.text(0.01, 0.5, text, ha='left', va='center',
85 fig.text(0.01, 0.5, text, ha='left', va='center',
86 size='20', weight='heavy', color='w')
86 size='20', weight='heavy', color='w')
87 fig.show()
87 fig.show()
88 figpause(1000)
88 figpause(1000)
89
89
90
90
91 class Throttle(object):
91 class Throttle(object):
92 '''
92 '''
93 Decorator that prevents a function from being called more than once every
93 Decorator that prevents a function from being called more than once every
94 time period.
94 time period.
95 To create a function that cannot be called more than once a minute, but
95 To create a function that cannot be called more than once a minute, but
96 will sleep until it can be called:
96 will sleep until it can be called:
97 @Throttle(minutes=1)
97 @Throttle(minutes=1)
98 def foo():
98 def foo():
99 pass
99 pass
100
100
101 for i in range(10):
101 for i in range(10):
102 foo()
102 foo()
103 print "This function has run %s times." % i
103 print "This function has run %s times." % i
104 '''
104 '''
105
105
106 def __init__(self, seconds=0, minutes=0, hours=0):
106 def __init__(self, seconds=0, minutes=0, hours=0):
107 self.throttle_period = datetime.timedelta(
107 self.throttle_period = datetime.timedelta(
108 seconds=seconds, minutes=minutes, hours=hours
108 seconds=seconds, minutes=minutes, hours=hours
109 )
109 )
110
110
111 self.time_of_last_call = datetime.datetime.min
111 self.time_of_last_call = datetime.datetime.min
112
112
113 def __call__(self, fn):
113 def __call__(self, fn):
114 @wraps(fn)
114 @wraps(fn)
115 def wrapper(*args, **kwargs):
115 def wrapper(*args, **kwargs):
116 coerce = kwargs.pop('coerce', None)
116 coerce = kwargs.pop('coerce', None)
117 if coerce:
117 if coerce:
118 self.time_of_last_call = datetime.datetime.now()
118 self.time_of_last_call = datetime.datetime.now()
119 return fn(*args, **kwargs)
119 return fn(*args, **kwargs)
120 else:
120 else:
121 now = datetime.datetime.now()
121 now = datetime.datetime.now()
122 time_since_last_call = now - self.time_of_last_call
122 time_since_last_call = now - self.time_of_last_call
123 time_left = self.throttle_period - time_since_last_call
123 time_left = self.throttle_period - time_since_last_call
124
124
125 if time_left > datetime.timedelta(seconds=0):
125 if time_left > datetime.timedelta(seconds=0):
126 return
126 return
127
127
128 self.time_of_last_call = datetime.datetime.now()
128 self.time_of_last_call = datetime.datetime.now()
129 return fn(*args, **kwargs)
129 return fn(*args, **kwargs)
130
130
131 return wrapper
131 return wrapper
132
132
133 def apply_throttle(value):
133 def apply_throttle(value):
134
134
135 @Throttle(seconds=value)
135 @Throttle(seconds=value)
136 def fnThrottled(fn):
136 def fnThrottled(fn):
137 fn()
137 fn()
138
138
139 return fnThrottled
139 return fnThrottled
140
140
141 @MPDecorator
141 @MPDecorator
142 class Plotter(ProcessingUnit):
142 class Plotter(ProcessingUnit):
143 '''
143 '''
144 Proccessing unit to handle plot operations
144 Proccessing unit to handle plot operations
145 '''
145 '''
146
146
147 def __init__(self):
147 def __init__(self):
148
148
149 ProcessingUnit.__init__(self)
149 ProcessingUnit.__init__(self)
150
150
151 def setup(self, **kwargs):
151 def setup(self, **kwargs):
152
152
153 self.connections = 0
153 self.connections = 0
154 self.web_address = kwargs.get('web_server', False)
154 self.web_address = kwargs.get('web_server', False)
155 self.realtime = kwargs.get('realtime', False)
155 self.realtime = kwargs.get('realtime', False)
156 self.localtime = kwargs.get('localtime', True)
156 self.localtime = kwargs.get('localtime', True)
157 self.buffering = kwargs.get('buffering', True)
157 self.buffering = kwargs.get('buffering', True)
158 self.throttle = kwargs.get('throttle', 2)
158 self.throttle = kwargs.get('throttle', 2)
159 self.exp_code = kwargs.get('exp_code', None)
159 self.exp_code = kwargs.get('exp_code', None)
160 self.set_ready = apply_throttle(self.throttle)
160 self.set_ready = apply_throttle(self.throttle)
161 self.dates = []
161 self.dates = []
162 self.data = PlotterData(
162 self.data = PlotterData(
163 self.plots, self.throttle, self.exp_code, self.buffering)
163 self.plots, self.throttle, self.exp_code, self.buffering)
164 self.isConfig = True
164 self.isConfig = True
165
165
166 def ready(self):
166 def ready(self):
167 '''
167 '''
168 Set dataOut ready
168 Set dataOut ready
169 '''
169 '''
170
170
171 self.data.ready = True
171 self.data.ready = True
172 self.dataOut.data_plt = self.data
172 self.dataOut.data_plt = self.data
173
173
174 def run(self, realtime=True, localtime=True, buffering=True,
174 def run(self, realtime=True, localtime=True, buffering=True,
175 throttle=2, exp_code=None, web_server=None):
175 throttle=2, exp_code=None, web_server=None):
176
176
177 if not self.isConfig:
177 if not self.isConfig:
178 self.setup(realtime=realtime, localtime=localtime,
178 self.setup(realtime=realtime, localtime=localtime,
179 buffering=buffering, throttle=throttle, exp_code=exp_code,
179 buffering=buffering, throttle=throttle, exp_code=exp_code,
180 web_server=web_server)
180 web_server=web_server)
181
181
182 if self.web_address:
182 if self.web_address:
183 log.success(
183 log.success(
184 'Sending to web: {}'.format(self.web_address),
184 'Sending to web: {}'.format(self.web_address),
185 self.name
185 self.name
186 )
186 )
187 self.context = zmq.Context()
187 self.context = zmq.Context()
188 self.sender_web = self.context.socket(zmq.REQ)
188 self.sender_web = self.context.socket(zmq.REQ)
189 self.sender_web.connect(self.web_address)
189 self.sender_web.connect(self.web_address)
190 self.poll = zmq.Poller()
190 self.poll = zmq.Poller()
191 self.poll.register(self.sender_web, zmq.POLLIN)
191 self.poll.register(self.sender_web, zmq.POLLIN)
192 time.sleep(1)
192 time.sleep(1)
193
193
194 # t = Thread(target=self.event_monitor, args=(monitor,))
194 # t = Thread(target=self.event_monitor, args=(monitor,))
195 # t.start()
195 # t.start()
196
196
197 self.dataOut = self.dataIn
197 self.dataOut = self.dataIn
198 self.data.ready = False
198 self.data.ready = False
199
199
200 if self.dataOut.flagNoData:
200 if self.dataOut.flagNoData:
201 coerce = True
201 coerce = True
202 else:
202 else:
203 coerce = False
203 coerce = False
204
204
205 if self.dataOut.type == 'Parameters':
205 if self.dataOut.type == 'Parameters':
206 tm = self.dataOut.utctimeInit
206 tm = self.dataOut.utctimeInit
207 else:
207 else:
208 tm = self.dataOut.utctime
208 tm = self.dataOut.utctime
209 if self.dataOut.useLocalTime:
209 if self.dataOut.useLocalTime:
210 if not self.localtime:
210 if not self.localtime:
211 tm += time.timezone
211 tm += time.timezone
212 dt = datetime.datetime.fromtimestamp(tm).date()
212 dt = datetime.datetime.fromtimestamp(tm).date()
213 else:
213 else:
214 if self.localtime:
214 if self.localtime:
215 tm -= time.timezone
215 tm -= time.timezone
216 dt = datetime.datetime.utcfromtimestamp(tm).date()
216 dt = datetime.datetime.utcfromtimestamp(tm).date()
217 if dt not in self.dates:
217 if dt not in self.dates:
218 if self.data:
218 if self.data:
219 self.ready()
219 self.ready()
220 self.data.setup()
220 self.data.setup()
221 self.dates.append(dt)
221 self.dates.append(dt)
222
222
223 self.data.update(self.dataOut, tm)
223 self.data.update(self.dataOut, tm)
224
224
225 if False: # TODO check when publishers ends
225 if False: # TODO check when publishers ends
226 self.connections -= 1
226 self.connections -= 1
227 if self.connections == 0 and dt in self.dates:
227 if self.connections == 0 and dt in self.dates:
228 self.data.ended = True
228 self.data.ended = True
229 self.ready()
229 self.ready()
230 time.sleep(1)
230 time.sleep(1)
231 else:
231 else:
232 if self.realtime:
232 if self.realtime:
233 self.ready()
233 self.ready()
234 if self.web_address:
234 if self.web_address:
235 retries = 5
235 retries = 5
236 while True:
236 while True:
237 self.sender_web.send(self.data.jsonify())
237 self.sender_web.send(self.data.jsonify())
238 socks = dict(self.poll.poll(5000))
238 socks = dict(self.poll.poll(5000))
239 if socks.get(self.sender_web) == zmq.POLLIN:
239 if socks.get(self.sender_web) == zmq.POLLIN:
240 reply = self.sender_web.recv_string()
240 reply = self.sender_web.recv_string()
241 if reply == 'ok':
241 if reply == 'ok':
242 log.log("Response from server ok", self.name)
242 log.log("Response from server ok", self.name)
243 break
243 break
244 else:
244 else:
245 log.warning(
245 log.warning(
246 "Malformed reply from server: {}".format(reply), self.name)
246 "Malformed reply from server: {}".format(reply), self.name)
247
247
248 else:
248 else:
249 log.warning(
249 log.warning(
250 "No response from server, retrying...", self.name)
250 "No response from server, retrying...", self.name)
251 self.sender_web.setsockopt(zmq.LINGER, 0)
251 self.sender_web.setsockopt(zmq.LINGER, 0)
252 self.sender_web.close()
252 self.sender_web.close()
253 self.poll.unregister(self.sender_web)
253 self.poll.unregister(self.sender_web)
254 retries -= 1
254 retries -= 1
255 if retries == 0:
255 if retries == 0:
256 log.error(
256 log.error(
257 "Server seems to be offline, abandoning", self.name)
257 "Server seems to be offline, abandoning", self.name)
258 self.sender_web = self.context.socket(zmq.REQ)
258 self.sender_web = self.context.socket(zmq.REQ)
259 self.sender_web.connect(self.web_address)
259 self.sender_web.connect(self.web_address)
260 self.poll.register(self.sender_web, zmq.POLLIN)
260 self.poll.register(self.sender_web, zmq.POLLIN)
261 time.sleep(1)
261 time.sleep(1)
262 break
262 break
263 self.sender_web = self.context.socket(zmq.REQ)
263 self.sender_web = self.context.socket(zmq.REQ)
264 self.sender_web.connect(self.web_address)
264 self.sender_web.connect(self.web_address)
265 self.poll.register(self.sender_web, zmq.POLLIN)
265 self.poll.register(self.sender_web, zmq.POLLIN)
266 time.sleep(1)
266 time.sleep(1)
267 else:
267 else:
268 self.set_ready(self.ready, coerce=coerce)
268 self.set_ready(self.ready, coerce=coerce)
269
269
270 return
270 return
271
271
272 def close(self):
272 def close(self):
273 pass
273 pass
274
274
275
275
276 @MPDecorator
276 @MPDecorator
277 class Plot(Operation):
277 class Plot(Operation):
278 '''
278 '''
279 Base class for Schain plotting operations
279 Base class for Schain plotting operations
280 '''
280 '''
281
281
282 CODE = 'Figure'
282 CODE = 'Figure'
283 colormap = 'jro'
283 colormap = 'jro'
284 bgcolor = 'white'
284 bgcolor = 'white'
285 __missing = 1E30
285 __missing = 1E30
286
286
287 __attrs__ = ['show', 'save', 'xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax',
287 __attrs__ = ['show', 'save', 'xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax',
288 'zlimits', 'xlabel', 'ylabel', 'xaxis', 'cb_label', 'title',
288 'zlimits', 'xlabel', 'ylabel', 'xaxis', 'cb_label', 'title',
289 'colorbar', 'bgcolor', 'width', 'height', 'localtime', 'oneFigure',
289 'colorbar', 'bgcolor', 'width', 'height', 'localtime', 'oneFigure',
290 'showprofile', 'decimation', 'pause']
290 'showprofile', 'decimation', 'pause']
291
291
292 def __init__(self):
292 def __init__(self):
293
293
294 Operation.__init__(self)
294 Operation.__init__(self)
295 self.isConfig = False
295 self.isConfig = False
296 self.isPlotConfig = False
296 self.isPlotConfig = False
297
297
298 def __fmtTime(self, x, pos):
298 def __fmtTime(self, x, pos):
299 '''
299 '''
300 '''
300 '''
301
301
302 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
302 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
303
303
304 def __setup(self, **kwargs):
304 def __setup(self, **kwargs):
305 '''
305 '''
306 Initialize variables
306 Initialize variables
307 '''
307 '''
308
308
309 self.figures = []
309 self.figures = []
310 self.axes = []
310 self.axes = []
311 self.cb_axes = []
311 self.cb_axes = []
312 self.localtime = kwargs.pop('localtime', True)
312 self.localtime = kwargs.pop('localtime', True)
313 self.show = kwargs.get('show', True)
313 self.show = kwargs.get('show', True)
314 self.save = kwargs.get('save', False)
314 self.save = kwargs.get('save', False)
315 self.ftp = kwargs.get('ftp', False)
315 self.ftp = kwargs.get('ftp', False)
316 self.colormap = kwargs.get('colormap', self.colormap)
316 self.colormap = kwargs.get('colormap', self.colormap)
317 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
317 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
318 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
318 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
319 self.colormaps = kwargs.get('colormaps', None)
319 self.colormaps = kwargs.get('colormaps', None)
320 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
320 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
321 self.showprofile = kwargs.get('showprofile', False)
321 self.showprofile = kwargs.get('showprofile', False)
322 self.title = kwargs.get('wintitle', self.CODE.upper())
322 self.title = kwargs.get('wintitle', self.CODE.upper())
323 self.cb_label = kwargs.get('cb_label', None)
323 self.cb_label = kwargs.get('cb_label', None)
324 self.cb_labels = kwargs.get('cb_labels', None)
324 self.cb_labels = kwargs.get('cb_labels', None)
325 self.labels = kwargs.get('labels', None)
325 self.labels = kwargs.get('labels', None)
326 self.xaxis = kwargs.get('xaxis', 'frequency')
326 self.xaxis = kwargs.get('xaxis', 'frequency')
327 self.zmin = kwargs.get('zmin', None)
327 self.zmin = kwargs.get('zmin', None)
328 self.zmax = kwargs.get('zmax', None)
328 self.zmax = kwargs.get('zmax', None)
329 self.zlimits = kwargs.get('zlimits', None)
329 self.zlimits = kwargs.get('zlimits', None)
330 self.xmin = kwargs.get('xmin', None)
330 self.xmin = kwargs.get('xmin', None)
331 self.xmax = kwargs.get('xmax', None)
331 self.xmax = kwargs.get('xmax', None)
332 self.xrange = kwargs.get('xrange', 12)
332 self.xrange = kwargs.get('xrange', 12)
333 self.xscale = kwargs.get('xscale', None)
333 self.xscale = kwargs.get('xscale', None)
334 self.ymin = kwargs.get('ymin', None)
334 self.ymin = kwargs.get('ymin', None)
335 self.ymax = kwargs.get('ymax', None)
335 self.ymax = kwargs.get('ymax', None)
336 self.yscale = kwargs.get('yscale', None)
336 self.yscale = kwargs.get('yscale', None)
337 self.xlabel = kwargs.get('xlabel', None)
337 self.xlabel = kwargs.get('xlabel', None)
338 self.decimation = kwargs.get('decimation', None)
338 self.decimation = kwargs.get('decimation', None)
339 self.showSNR = kwargs.get('showSNR', False)
339 self.showSNR = kwargs.get('showSNR', False)
340 self.oneFigure = kwargs.get('oneFigure', True)
340 self.oneFigure = kwargs.get('oneFigure', True)
341 self.width = kwargs.get('width', None)
341 self.width = kwargs.get('width', None)
342 self.height = kwargs.get('height', None)
342 self.height = kwargs.get('height', None)
343 self.colorbar = kwargs.get('colorbar', True)
343 self.colorbar = kwargs.get('colorbar', True)
344 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
344 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
345 self.channels = kwargs.get('channels', None)
345 self.channels = kwargs.get('channels', None)
346 self.titles = kwargs.get('titles', [])
346 self.titles = kwargs.get('titles', [])
347 self.polar = False
347 self.polar = False
348 self.grid = kwargs.get('grid', False)
348 self.grid = kwargs.get('grid', False)
349 self.pause = kwargs.get('pause', False)
349 self.pause = kwargs.get('pause', False)
350 self.save_labels = kwargs.get('save_labels', None)
350 self.save_labels = kwargs.get('save_labels', None)
351 self.realtime = kwargs.get('realtime', True)
351 self.realtime = kwargs.get('realtime', True)
352 self.buffering = kwargs.get('buffering', True)
352 self.buffering = kwargs.get('buffering', True)
353 self.throttle = kwargs.get('throttle', 2)
353 self.throttle = kwargs.get('throttle', 2)
354 self.exp_code = kwargs.get('exp_code', None)
354 self.exp_code = kwargs.get('exp_code', None)
355 self.__throttle_plot = apply_throttle(self.throttle)
355 self.__throttle_plot = apply_throttle(self.throttle)
356 self.data = PlotterData(
356 self.data = PlotterData(
357 self.CODE, self.throttle, self.exp_code, self.buffering)
357 self.CODE, self.throttle, self.exp_code, self.buffering)
358
358
359 def __setup_plot(self):
359 def __setup_plot(self):
360 '''
360 '''
361 Common setup for all figures, here figures and axes are created
361 Common setup for all figures, here figures and axes are created
362 '''
362 '''
363
363
364 self.setup()
364 self.setup()
365
365
366 self.time_label = 'LT' if self.localtime else 'UTC'
366 self.time_label = 'LT' if self.localtime else 'UTC'
367 if self.data.localtime:
367 if self.data.localtime:
368 self.getDateTime = datetime.datetime.fromtimestamp
368 self.getDateTime = datetime.datetime.fromtimestamp
369 else:
369 else:
370 self.getDateTime = datetime.datetime.utcfromtimestamp
370 self.getDateTime = datetime.datetime.utcfromtimestamp
371
371
372 if self.width is None:
372 if self.width is None:
373 self.width = 8
373 self.width = 8
374
374
375 self.figures = []
375 self.figures = []
376 self.axes = []
376 self.axes = []
377 self.cb_axes = []
377 self.cb_axes = []
378 self.pf_axes = []
378 self.pf_axes = []
379 self.cmaps = []
379 self.cmaps = []
380
380
381 size = '15%' if self.ncols == 1 else '30%'
381 size = '15%' if self.ncols == 1 else '30%'
382 pad = '4%' if self.ncols == 1 else '8%'
382 pad = '4%' if self.ncols == 1 else '8%'
383
383
384 if self.oneFigure:
384 if self.oneFigure:
385 if self.height is None:
385 if self.height is None:
386 self.height = 1.4 * self.nrows + 1
386 self.height = 1.4 * self.nrows + 1
387 fig = plt.figure(figsize=(self.width, self.height),
387 fig = plt.figure(figsize=(self.width, self.height),
388 edgecolor='k',
388 edgecolor='k',
389 facecolor='w')
389 facecolor='w')
390 self.figures.append(fig)
390 self.figures.append(fig)
391 for n in range(self.nplots):
391 for n in range(self.nplots):
392 ax = fig.add_subplot(self.nrows, self.ncols,
392 ax = fig.add_subplot(self.nrows, self.ncols,
393 n + 1, polar=self.polar)
393 n + 1, polar=self.polar)
394 ax.tick_params(labelsize=8)
394 ax.tick_params(labelsize=8)
395 ax.firsttime = True
395 ax.firsttime = True
396 ax.index = 0
396 ax.index = 0
397 ax.press = None
397 ax.press = None
398 self.axes.append(ax)
398 self.axes.append(ax)
399 if self.showprofile:
399 if self.showprofile:
400 cax = self.__add_axes(ax, size=size, pad=pad)
400 cax = self.__add_axes(ax, size=size, pad=pad)
401 cax.tick_params(labelsize=8)
401 cax.tick_params(labelsize=8)
402 self.pf_axes.append(cax)
402 self.pf_axes.append(cax)
403 else:
403 else:
404 if self.height is None:
404 if self.height is None:
405 self.height = 3
405 self.height = 3
406 for n in range(self.nplots):
406 for n in range(self.nplots):
407 fig = plt.figure(figsize=(self.width, self.height),
407 fig = plt.figure(figsize=(self.width, self.height),
408 edgecolor='k',
408 edgecolor='k',
409 facecolor='w')
409 facecolor='w')
410 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
410 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
411 ax.tick_params(labelsize=8)
411 ax.tick_params(labelsize=8)
412 ax.firsttime = True
412 ax.firsttime = True
413 ax.index = 0
413 ax.index = 0
414 ax.press = None
414 ax.press = None
415 self.figures.append(fig)
415 self.figures.append(fig)
416 self.axes.append(ax)
416 self.axes.append(ax)
417 if self.showprofile:
417 if self.showprofile:
418 cax = self.__add_axes(ax, size=size, pad=pad)
418 cax = self.__add_axes(ax, size=size, pad=pad)
419 cax.tick_params(labelsize=8)
419 cax.tick_params(labelsize=8)
420 self.pf_axes.append(cax)
420 self.pf_axes.append(cax)
421
421
422 for n in range(self.nrows):
422 for n in range(self.nrows):
423 if self.colormaps is not None:
423 if self.colormaps is not None:
424 cmap = plt.get_cmap(self.colormaps[n])
424 cmap = plt.get_cmap(self.colormaps[n])
425 else:
425 else:
426 cmap = plt.get_cmap(self.colormap)
426 cmap = plt.get_cmap(self.colormap)
427 cmap.set_bad(self.bgcolor, 1.)
427 cmap.set_bad(self.bgcolor, 1.)
428 self.cmaps.append(cmap)
428 self.cmaps.append(cmap)
429
429
430 for fig in self.figures:
430 for fig in self.figures:
431 fig.canvas.mpl_connect('key_press_event', self.OnKeyPress)
431 fig.canvas.mpl_connect('key_press_event', self.OnKeyPress)
432 fig.canvas.mpl_connect('scroll_event', self.OnBtnScroll)
432 fig.canvas.mpl_connect('scroll_event', self.OnBtnScroll)
433 fig.canvas.mpl_connect('button_press_event', self.onBtnPress)
433 fig.canvas.mpl_connect('button_press_event', self.onBtnPress)
434 fig.canvas.mpl_connect('motion_notify_event', self.onMotion)
434 fig.canvas.mpl_connect('motion_notify_event', self.onMotion)
435 fig.canvas.mpl_connect('button_release_event', self.onBtnRelease)
435 fig.canvas.mpl_connect('button_release_event', self.onBtnRelease)
436 if self.show:
436 if self.show:
437 fig.show()
437 fig.show()
438
438
439 def OnKeyPress(self, event):
439 def OnKeyPress(self, event):
440 '''
440 '''
441 Event for pressing keys (up, down) change colormap
441 Event for pressing keys (up, down) change colormap
442 '''
442 '''
443 ax = event.inaxes
443 ax = event.inaxes
444 if ax in self.axes:
444 if ax in self.axes:
445 if event.key == 'down':
445 if event.key == 'down':
446 ax.index += 1
446 ax.index += 1
447 elif event.key == 'up':
447 elif event.key == 'up':
448 ax.index -= 1
448 ax.index -= 1
449 if ax.index < 0:
449 if ax.index < 0:
450 ax.index = len(CMAPS) - 1
450 ax.index = len(CMAPS) - 1
451 elif ax.index == len(CMAPS):
451 elif ax.index == len(CMAPS):
452 ax.index = 0
452 ax.index = 0
453 cmap = CMAPS[ax.index]
453 cmap = CMAPS[ax.index]
454 ax.cbar.set_cmap(cmap)
454 ax.cbar.set_cmap(cmap)
455 ax.cbar.draw_all()
455 ax.cbar.draw_all()
456 ax.plt.set_cmap(cmap)
456 ax.plt.set_cmap(cmap)
457 ax.cbar.patch.figure.canvas.draw()
457 ax.cbar.patch.figure.canvas.draw()
458 self.colormap = cmap.name
458 self.colormap = cmap.name
459
459
460 def OnBtnScroll(self, event):
460 def OnBtnScroll(self, event):
461 '''
461 '''
462 Event for scrolling, scale figure
462 Event for scrolling, scale figure
463 '''
463 '''
464 cb_ax = event.inaxes
464 cb_ax = event.inaxes
465 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
465 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
466 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
466 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
467 pt = ax.cbar.ax.bbox.get_points()[:, 1]
467 pt = ax.cbar.ax.bbox.get_points()[:, 1]
468 nrm = ax.cbar.norm
468 nrm = ax.cbar.norm
469 vmin, vmax, p0, p1, pS = (
469 vmin, vmax, p0, p1, pS = (
470 nrm.vmin, nrm.vmax, pt[0], pt[1], event.y)
470 nrm.vmin, nrm.vmax, pt[0], pt[1], event.y)
471 scale = 2 if event.step == 1 else 0.5
471 scale = 2 if event.step == 1 else 0.5
472 point = vmin + (vmax - vmin) / (p1 - p0) * (pS - p0)
472 point = vmin + (vmax - vmin) / (p1 - p0) * (pS - p0)
473 ax.cbar.norm.vmin = point - scale * (point - vmin)
473 ax.cbar.norm.vmin = point - scale * (point - vmin)
474 ax.cbar.norm.vmax = point - scale * (point - vmax)
474 ax.cbar.norm.vmax = point - scale * (point - vmax)
475 ax.plt.set_norm(ax.cbar.norm)
475 ax.plt.set_norm(ax.cbar.norm)
476 ax.cbar.draw_all()
476 ax.cbar.draw_all()
477 ax.cbar.patch.figure.canvas.draw()
477 ax.cbar.patch.figure.canvas.draw()
478
478
479 def onBtnPress(self, event):
479 def onBtnPress(self, event):
480 '''
480 '''
481 Event for mouse button press
481 Event for mouse button press
482 '''
482 '''
483 cb_ax = event.inaxes
483 cb_ax = event.inaxes
484 if cb_ax is None:
484 if cb_ax is None:
485 return
485 return
486
486
487 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
487 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
488 cb_ax.press = event.x, event.y
488 cb_ax.press = event.x, event.y
489 else:
489 else:
490 cb_ax.press = None
490 cb_ax.press = None
491
491
492 def onMotion(self, event):
492 def onMotion(self, event):
493 '''
493 '''
494 Event for move inside colorbar
494 Event for move inside colorbar
495 '''
495 '''
496 cb_ax = event.inaxes
496 cb_ax = event.inaxes
497 if cb_ax is None:
497 if cb_ax is None:
498 return
498 return
499 if cb_ax not in [ax.cbar.ax for ax in self.axes if ax.cbar]:
499 if cb_ax not in [ax.cbar.ax for ax in self.axes if ax.cbar]:
500 return
500 return
501 if cb_ax.press is None:
501 if cb_ax.press is None:
502 return
502 return
503
503
504 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
504 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
505 xprev, yprev = cb_ax.press
505 xprev, yprev = cb_ax.press
506 dx = event.x - xprev
506 dx = event.x - xprev
507 dy = event.y - yprev
507 dy = event.y - yprev
508 cb_ax.press = event.x, event.y
508 cb_ax.press = event.x, event.y
509 scale = ax.cbar.norm.vmax - ax.cbar.norm.vmin
509 scale = ax.cbar.norm.vmax - ax.cbar.norm.vmin
510 perc = 0.03
510 perc = 0.03
511
511
512 if event.button == 1:
512 if event.button == 1:
513 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
513 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
514 ax.cbar.norm.vmax -= (perc * scale) * numpy.sign(dy)
514 ax.cbar.norm.vmax -= (perc * scale) * numpy.sign(dy)
515 elif event.button == 3:
515 elif event.button == 3:
516 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
516 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
517 ax.cbar.norm.vmax += (perc * scale) * numpy.sign(dy)
517 ax.cbar.norm.vmax += (perc * scale) * numpy.sign(dy)
518
518
519 ax.cbar.draw_all()
519 ax.cbar.draw_all()
520 ax.plt.set_norm(ax.cbar.norm)
520 ax.plt.set_norm(ax.cbar.norm)
521 ax.cbar.patch.figure.canvas.draw()
521 ax.cbar.patch.figure.canvas.draw()
522
522
523 def onBtnRelease(self, event):
523 def onBtnRelease(self, event):
524 '''
524 '''
525 Event for mouse button release
525 Event for mouse button release
526 '''
526 '''
527 cb_ax = event.inaxes
527 cb_ax = event.inaxes
528 if cb_ax is not None:
528 if cb_ax is not None:
529 cb_ax.press = None
529 cb_ax.press = None
530
530
531 def __add_axes(self, ax, size='30%', pad='8%'):
531 def __add_axes(self, ax, size='30%', pad='8%'):
532 '''
532 '''
533 Add new axes to the given figure
533 Add new axes to the given figure
534 '''
534 '''
535 divider = make_axes_locatable(ax)
535 divider = make_axes_locatable(ax)
536 nax = divider.new_horizontal(size=size, pad=pad)
536 nax = divider.new_horizontal(size=size, pad=pad)
537 ax.figure.add_axes(nax)
537 ax.figure.add_axes(nax)
538 return nax
538 return nax
539
539
540 def setup(self):
540 def setup(self):
541 '''
541 '''
542 This method should be implemented in the child class, the following
542 This method should be implemented in the child class, the following
543 attributes should be set:
543 attributes should be set:
544
544
545 self.nrows: number of rows
545 self.nrows: number of rows
546 self.ncols: number of cols
546 self.ncols: number of cols
547 self.nplots: number of plots (channels or pairs)
547 self.nplots: number of plots (channels or pairs)
548 self.ylabel: label for Y axes
548 self.ylabel: label for Y axes
549 self.titles: list of axes title
549 self.titles: list of axes title
550
550
551 '''
551 '''
552 raise NotImplementedError
552 raise NotImplementedError
553
553
554 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
554 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
555 '''
555 '''
556 Create a masked array for missing data
556 Create a masked array for missing data
557 '''
557 '''
558 if x_buffer.shape[0] < 2:
558 if x_buffer.shape[0] < 2:
559 return x_buffer, y_buffer, z_buffer
559 return x_buffer, y_buffer, z_buffer
560
560
561 deltas = x_buffer[1:] - x_buffer[0:-1]
561 deltas = x_buffer[1:] - x_buffer[0:-1]
562 x_median = numpy.median(deltas)
562 x_median = numpy.median(deltas)
563
563
564 index = numpy.where(deltas > 5 * x_median)
564 index = numpy.where(deltas > 5 * x_median)
565
565
566 if len(index[0]) != 0:
566 if len(index[0]) != 0:
567 z_buffer[::, index[0], ::] = self.__missing
567 z_buffer[::, index[0], ::] = self.__missing
568 z_buffer = numpy.ma.masked_inside(z_buffer,
568 z_buffer = numpy.ma.masked_inside(z_buffer,
569 0.99 * self.__missing,
569 0.99 * self.__missing,
570 1.01 * self.__missing)
570 1.01 * self.__missing)
571
571
572 return x_buffer, y_buffer, z_buffer
572 return x_buffer, y_buffer, z_buffer
573
573
574 def decimate(self):
574 def decimate(self):
575
575
576 # dx = int(len(self.x)/self.__MAXNUMX) + 1
576 # dx = int(len(self.x)/self.__MAXNUMX) + 1
577 dy = int(len(self.y) / self.decimation) + 1
577 dy = int(len(self.y) / self.decimation) + 1
578
578
579 # x = self.x[::dx]
579 # x = self.x[::dx]
580 x = self.x
580 x = self.x
581 y = self.y[::dy]
581 y = self.y[::dy]
582 z = self.z[::, ::, ::dy]
582 z = self.z[::, ::, ::dy]
583
583
584 return x, y, z
584 return x, y, z
585
585
586 def format(self):
586 def format(self):
587 '''
587 '''
588 Set min and max values, labels, ticks and titles
588 Set min and max values, labels, ticks and titles
589 '''
589 '''
590
590
591 if self.xmin is None:
591 if self.xmin is None:
592 xmin = self.data.min_time
592 xmin = self.data.min_time
593 else:
593 else:
594 if self.xaxis is 'time':
594 if self.xaxis is 'time':
595 dt = self.getDateTime(self.data.min_time)
595 dt = self.getDateTime(self.data.min_time)
596 xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) -
596 xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) -
597 datetime.datetime(1970, 1, 1)).total_seconds()
597 datetime.datetime(1970, 1, 1)).total_seconds()
598 if self.data.localtime:
598 if self.data.localtime:
599 xmin += time.timezone
599 xmin += time.timezone
600 else:
600 else:
601 xmin = self.xmin
601 xmin = self.xmin
602
602
603 if self.xmax is None:
603 if self.xmax is None:
604 xmax = xmin + self.xrange * 60 * 60
604 xmax = xmin + self.xrange * 60 * 60
605 else:
605 else:
606 if self.xaxis is 'time':
606 if self.xaxis is 'time':
607 dt = self.getDateTime(self.data.max_time)
607 dt = self.getDateTime(self.data.max_time)
608 xmax = (dt.replace(hour=int(self.xmax), minute=59, second=59) -
608 xmax = (dt.replace(hour=int(self.xmax), minute=59, second=59) -
609 datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds()
609 datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds()
610 if self.data.localtime:
610 if self.data.localtime:
611 xmax += time.timezone
611 xmax += time.timezone
612 else:
612 else:
613 xmax = self.xmax
613 xmax = self.xmax
614
614
615 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
615 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
616 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
616 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
617
617
618 Y = numpy.array([1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000])
618 Y = numpy.array([1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000])
619 i = 1 if numpy.where(
619 i = 1 if numpy.where(
620 abs(ymax-ymin) <= Y)[0][0] < 0 else numpy.where(abs(ymax-ymin) <= Y)[0][0]
620 abs(ymax-ymin) <= Y)[0][0] < 0 else numpy.where(abs(ymax-ymin) <= Y)[0][0]
621 ystep = Y[i] / 10.
621 ystep = Y[i] / 10.
622
622
623 if self.xaxis is not 'time':
623 if self.xaxis is not 'time':
624 X = numpy.array([1, 2, 5, 10, 20, 50, 100,
624 X = numpy.array([1, 2, 5, 10, 20, 50, 100,
625 200, 500, 1000, 2000, 5000])/2.
625 200, 500, 1000, 2000, 5000])/2.
626 i = 1 if numpy.where(
626 i = 1 if numpy.where(
627 abs(xmax-xmin) <= X)[0][0] < 0 else numpy.where(abs(xmax-xmin) <= X)[0][0]
627 abs(xmax-xmin) <= X)[0][0] < 0 else numpy.where(abs(xmax-xmin) <= X)[0][0]
628 xstep = X[i] / 10.
628 xstep = X[i] / 10.
629
629
630 for n, ax in enumerate(self.axes):
630 for n, ax in enumerate(self.axes):
631 if ax.firsttime:
631 if ax.firsttime:
632 ax.set_facecolor(self.bgcolor)
632 ax.set_facecolor(self.bgcolor)
633 ax.yaxis.set_major_locator(MultipleLocator(ystep))
633 ax.yaxis.set_major_locator(MultipleLocator(ystep))
634 if self.xscale:
634 if self.xscale:
635 ax.xaxis.set_major_formatter(FuncFormatter(
635 ax.xaxis.set_major_formatter(FuncFormatter(
636 lambda x, pos: '{0:g}'.format(x*self.xscale)))
636 lambda x, pos: '{0:g}'.format(x*self.xscale)))
637 if self.xscale:
637 if self.xscale:
638 ax.yaxis.set_major_formatter(FuncFormatter(
638 ax.yaxis.set_major_formatter(FuncFormatter(
639 lambda x, pos: '{0:g}'.format(x*self.yscale)))
639 lambda x, pos: '{0:g}'.format(x*self.yscale)))
640 if self.xaxis is 'time':
640 if self.xaxis is 'time':
641 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
641 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
642 ax.xaxis.set_major_locator(LinearLocator(9))
642 ax.xaxis.set_major_locator(LinearLocator(9))
643 else:
643 else:
644 ax.xaxis.set_major_locator(MultipleLocator(xstep))
644 ax.xaxis.set_major_locator(MultipleLocator(xstep))
645 if self.xlabel is not None:
645 if self.xlabel is not None:
646 ax.set_xlabel(self.xlabel)
646 ax.set_xlabel(self.xlabel)
647 ax.set_ylabel(self.ylabel)
647 ax.set_ylabel(self.ylabel)
648 ax.firsttime = False
648 ax.firsttime = False
649 if self.showprofile:
649 if self.showprofile:
650 self.pf_axes[n].set_ylim(ymin, ymax)
650 self.pf_axes[n].set_ylim(ymin, ymax)
651 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
651 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
652 self.pf_axes[n].set_xlabel('dB')
652 self.pf_axes[n].set_xlabel('dB')
653 self.pf_axes[n].grid(b=True, axis='x')
653 self.pf_axes[n].grid(b=True, axis='x')
654 [tick.set_visible(False)
654 [tick.set_visible(False)
655 for tick in self.pf_axes[n].get_yticklabels()]
655 for tick in self.pf_axes[n].get_yticklabels()]
656 if self.colorbar:
656 if self.colorbar:
657 ax.cbar = plt.colorbar(
657 ax.cbar = plt.colorbar(
658 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
658 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
659 ax.cbar.ax.tick_params(labelsize=8)
659 ax.cbar.ax.tick_params(labelsize=8)
660 ax.cbar.ax.press = None
660 ax.cbar.ax.press = None
661 if self.cb_label:
661 if self.cb_label:
662 ax.cbar.set_label(self.cb_label, size=8)
662 ax.cbar.set_label(self.cb_label, size=8)
663 elif self.cb_labels:
663 elif self.cb_labels:
664 ax.cbar.set_label(self.cb_labels[n], size=8)
664 ax.cbar.set_label(self.cb_labels[n], size=8)
665 else:
665 else:
666 ax.cbar = None
666 ax.cbar = None
667 if self.grid:
667 if self.grid:
668 ax.grid(True)
668 ax.grid(True)
669
669
670 if not self.polar:
670 if not self.polar:
671 ax.set_xlim(xmin, xmax)
671 ax.set_xlim(xmin, xmax)
672 ax.set_ylim(ymin, ymax)
672 ax.set_ylim(ymin, ymax)
673 ax.set_title('{} {} {}'.format(
673 ax.set_title('{} {} {}'.format(
674 self.titles[n],
674 self.titles[n],
675 self.getDateTime(self.data.max_time).strftime(
675 self.getDateTime(self.data.max_time).strftime(
676 '%Y-%m-%dT%H:%M:%S'),
676 '%Y-%m-%dT%H:%M:%S'),
677 self.time_label),
677 self.time_label),
678 size=8)
678 size=8)
679 else:
679 else:
680 ax.set_title('{}'.format(self.titles[n]), size=8)
680 ax.set_title('{}'.format(self.titles[n]), size=8)
681 ax.set_ylim(0, 90)
681 ax.set_ylim(0, 90)
682 ax.set_yticks(numpy.arange(0, 90, 20))
682 ax.set_yticks(numpy.arange(0, 90, 20))
683 ax.yaxis.labelpad = 40
683 ax.yaxis.labelpad = 40
684
684
685 def clear_figures(self):
685 def clear_figures(self):
686 '''
686 '''
687 Reset axes for redraw plots
687 Reset axes for redraw plots
688 '''
688 '''
689
689
690 for ax in self.axes:
690 for ax in self.axes:
691 ax.clear()
691 ax.clear()
692 ax.firsttime = True
692 ax.firsttime = True
693 if ax.cbar:
693 if ax.cbar:
694 ax.cbar.remove()
694 ax.cbar.remove()
695
695
696 def __plot(self):
696 def __plot(self):
697 '''
697 '''
698 Main function to plot, format and save figures
698 Main function to plot, format and save figures
699 '''
699 '''
700
700
701 #try:
701 #try:
702 self.plot()
702 self.plot()
703 self.format()
703 self.format()
704 #except Exception as e:
704 #except Exception as e:
705 # log.warning('{} Plot could not be updated... check data'.format(
705 # log.warning('{} Plot could not be updated... check data'.format(
706 # self.CODE), self.name)
706 # self.CODE), self.name)
707 # log.error(str(e), '')
707 # log.error(str(e), '')
708 # return
708 # return
709
709
710 for n, fig in enumerate(self.figures):
710 for n, fig in enumerate(self.figures):
711 if self.nrows == 0 or self.nplots == 0:
711 if self.nrows == 0 or self.nplots == 0:
712 log.warning('No data', self.name)
712 log.warning('No data', self.name)
713 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
713 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
714 fig.canvas.manager.set_window_title(self.CODE)
714 fig.canvas.manager.set_window_title(self.CODE)
715 continue
715 continue
716
716
717 fig.tight_layout()
717 fig.tight_layout()
718 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
718 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
719 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
719 self.getDateTime(self.data.max_time).strftime('%Y/%m/%d')))
720 fig.canvas.draw()
720 fig.canvas.draw()
721
721
722 if self.save:
722 if self.save:
723
723
724 if self.save_labels:
724 if self.save_labels:
725 labels = self.save_labels
725 labels = self.save_labels
726 else:
726 else:
727 labels = list(range(self.nrows))
727 labels = list(range(self.nrows))
728
728
729 if self.oneFigure:
729 if self.oneFigure:
730 label = ''
730 label = ''
731 else:
731 else:
732 label = '-{}'.format(labels[n])
732 label = '-{}'.format(labels[n])
733 figname = os.path.join(
733 figname = os.path.join(
734 self.save,
734 self.save,
735 self.CODE,
735 self.CODE,
736 '{}{}_{}.png'.format(
736 '{}{}_{}.png'.format(
737 self.CODE,
737 self.CODE,
738 label,
738 label,
739 self.getDateTime(self.data.max_time).strftime(
739 self.getDateTime(self.data.max_time).strftime(
740 '%Y%m%d_%H%M%S'),
740 '%Y%m%d_%H%M%S'),
741 )
741 )
742 )
742 )
743 log.log('Saving figure: {}'.format(figname), self.name)
743 log.log('Saving figure: {}'.format(figname), self.name)
744 if not os.path.isdir(os.path.dirname(figname)):
744 if not os.path.isdir(os.path.dirname(figname)):
745 os.makedirs(os.path.dirname(figname))
745 os.makedirs(os.path.dirname(figname))
746 fig.savefig(figname)
746 fig.savefig(figname)
747
747
748 def plot(self):
748 def plot(self):
749 '''
749 '''
750 Must be defined in the child class
750 Must be defined in the child class
751 '''
751 '''
752 raise NotImplementedError
752 raise NotImplementedError
753
753
754 def run(self, dataOut, **kwargs):
754 def run(self, dataOut, **kwargs):
755
755
756 if dataOut.flagNoData and not dataOut.error:
757 return dataOut
758
759 if dataOut.error:
756 if dataOut.error:
760 coerce = True
757 coerce = True
761 else:
758 else:
762 coerce = False
759 coerce = False
763
760
764 if self.isConfig is False:
761 if self.isConfig is False:
765 self.__setup(**kwargs)
762 self.__setup(**kwargs)
766 self.data.setup()
763 self.data.setup()
767 self.isConfig = True
764 self.isConfig = True
768
765
769 if dataOut.type == 'Parameters':
766 if dataOut.type == 'Parameters':
770 tm = dataOut.utctimeInit
767 tm = dataOut.utctimeInit
771 else:
768 else:
772 tm = dataOut.utctime
769 tm = dataOut.utctime
773
770
774 if dataOut.useLocalTime:
771 if dataOut.useLocalTime:
775 if not self.localtime:
772 if not self.localtime:
776 tm += time.timezone
773 tm += time.timezone
777 else:
774 else:
778 if self.localtime:
775 if self.localtime:
779 tm -= time.timezone
776 tm -= time.timezone
780
777
781 if self.data and (tm - self.data.min_time) >= self.xrange*60*60:
778 if self.data and (tm - self.data.min_time) >= self.xrange*60*60:
782 self.__plot()
779 self.__plot()
783 self.data.setup()
780 self.data.setup()
784 self.clear_figures()
781 self.clear_figures()
785
782
786 self.data.update(dataOut, tm)
783 self.data.update(dataOut, tm)
787
784
788 if self.isPlotConfig is False:
785 if self.isPlotConfig is False:
789 self.__setup_plot()
786 self.__setup_plot()
790 self.isPlotConfig = True
787 self.isPlotConfig = True
791
788
792 if self.realtime:
789 if self.realtime:
793 self.__plot()
790 self.__plot()
794 else:
791 else:
795 self.__throttle_plot(self.__plot, coerce=coerce)
792 self.__throttle_plot(self.__plot, coerce=coerce)
796
793
797 figpause(0.001)
794 figpause(0.001)
798
795
799 def close(self):
796 def close(self):
800
797
801 if self.data and self.pause:
798 if self.data and self.pause:
802 figpause(10)
799 figpause(10)
803
800
@@ -1,368 +1,368
1 '''
1 '''
2 Created on Nov 9, 2016
2 Created on Nov 9, 2016
3
3
4 @author: roj- LouVD
4 @author: roj- LouVD
5 '''
5 '''
6
6
7
7
8 import os
8 import os
9 import sys
9 import sys
10 import time
10 import time
11 import glob
11 import glob
12 import datetime
12 import datetime
13
13
14 import numpy
14 import numpy
15
15
16 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator
16 from schainpy.model.proc.jroproc_base import ProcessingUnit, MPDecorator
17 from schainpy.model.data.jrodata import Parameters
17 from schainpy.model.data.jrodata import Parameters
18 from schainpy.model.io.jroIO_base import JRODataReader, isNumber
18 from schainpy.model.io.jroIO_base import JRODataReader, isNumber
19 from schainpy.utils import log
19 from schainpy.utils import log
20
20
21 FILE_HEADER_STRUCTURE = numpy.dtype([
21 FILE_HEADER_STRUCTURE = numpy.dtype([
22 ('FMN', '<u4'),
22 ('FMN', '<u4'),
23 ('nrec', '<u4'),
23 ('nrec', '<u4'),
24 ('fr_offset', '<u4'),
24 ('fr_offset', '<u4'),
25 ('id', '<u4'),
25 ('id', '<u4'),
26 ('site', 'u1', (32,))
26 ('site', 'u1', (32,))
27 ])
27 ])
28
28
29 REC_HEADER_STRUCTURE = numpy.dtype([
29 REC_HEADER_STRUCTURE = numpy.dtype([
30 ('rmn', '<u4'),
30 ('rmn', '<u4'),
31 ('rcounter', '<u4'),
31 ('rcounter', '<u4'),
32 ('nr_offset', '<u4'),
32 ('nr_offset', '<u4'),
33 ('tr_offset', '<u4'),
33 ('tr_offset', '<u4'),
34 ('time', '<u4'),
34 ('time', '<u4'),
35 ('time_msec', '<u4'),
35 ('time_msec', '<u4'),
36 ('tag', 'u1', (32,)),
36 ('tag', 'u1', (32,)),
37 ('comments', 'u1', (32,)),
37 ('comments', 'u1', (32,)),
38 ('lat', '<f4'),
38 ('lat', '<f4'),
39 ('lon', '<f4'),
39 ('lon', '<f4'),
40 ('gps_status', '<u4'),
40 ('gps_status', '<u4'),
41 ('freq', '<u4'),
41 ('freq', '<u4'),
42 ('freq0', '<u4'),
42 ('freq0', '<u4'),
43 ('nchan', '<u4'),
43 ('nchan', '<u4'),
44 ('delta_r', '<u4'),
44 ('delta_r', '<u4'),
45 ('nranges', '<u4'),
45 ('nranges', '<u4'),
46 ('r0', '<u4'),
46 ('r0', '<u4'),
47 ('prf', '<u4'),
47 ('prf', '<u4'),
48 ('ncoh', '<u4'),
48 ('ncoh', '<u4'),
49 ('npoints', '<u4'),
49 ('npoints', '<u4'),
50 ('polarization', '<i4'),
50 ('polarization', '<i4'),
51 ('rx_filter', '<u4'),
51 ('rx_filter', '<u4'),
52 ('nmodes', '<u4'),
52 ('nmodes', '<u4'),
53 ('dmode_index', '<u4'),
53 ('dmode_index', '<u4'),
54 ('dmode_rngcorr', '<u4'),
54 ('dmode_rngcorr', '<u4'),
55 ('nrxs', '<u4'),
55 ('nrxs', '<u4'),
56 ('acf_length', '<u4'),
56 ('acf_length', '<u4'),
57 ('acf_lags', '<u4'),
57 ('acf_lags', '<u4'),
58 ('sea_to_atmos', '<f4'),
58 ('sea_to_atmos', '<f4'),
59 ('sea_notch', '<u4'),
59 ('sea_notch', '<u4'),
60 ('lh_sea', '<u4'),
60 ('lh_sea', '<u4'),
61 ('hh_sea', '<u4'),
61 ('hh_sea', '<u4'),
62 ('nbins_sea', '<u4'),
62 ('nbins_sea', '<u4'),
63 ('min_snr', '<f4'),
63 ('min_snr', '<f4'),
64 ('min_cc', '<f4'),
64 ('min_cc', '<f4'),
65 ('max_time_diff', '<f4')
65 ('max_time_diff', '<f4')
66 ])
66 ])
67
67
68 DATA_STRUCTURE = numpy.dtype([
68 DATA_STRUCTURE = numpy.dtype([
69 ('range', '<u4'),
69 ('range', '<u4'),
70 ('status', '<u4'),
70 ('status', '<u4'),
71 ('zonal', '<f4'),
71 ('zonal', '<f4'),
72 ('meridional', '<f4'),
72 ('meridional', '<f4'),
73 ('vertical', '<f4'),
73 ('vertical', '<f4'),
74 ('zonal_a', '<f4'),
74 ('zonal_a', '<f4'),
75 ('meridional_a', '<f4'),
75 ('meridional_a', '<f4'),
76 ('corrected_fading', '<f4'), # seconds
76 ('corrected_fading', '<f4'), # seconds
77 ('uncorrected_fading', '<f4'), # seconds
77 ('uncorrected_fading', '<f4'), # seconds
78 ('time_diff', '<f4'),
78 ('time_diff', '<f4'),
79 ('major_axis', '<f4'),
79 ('major_axis', '<f4'),
80 ('axial_ratio', '<f4'),
80 ('axial_ratio', '<f4'),
81 ('orientation', '<f4'),
81 ('orientation', '<f4'),
82 ('sea_power', '<u4'),
82 ('sea_power', '<u4'),
83 ('sea_algorithm', '<u4')
83 ('sea_algorithm', '<u4')
84 ])
84 ])
85
85
86 @MPDecorator
86 @MPDecorator
87 class BLTRParamReader(JRODataReader, ProcessingUnit):
87 class BLTRParamReader(JRODataReader, ProcessingUnit):
88 '''
88 '''
89 Boundary Layer and Tropospheric Radar (BLTR) reader, Wind velocities and SNR from *.sswma files
89 Boundary Layer and Tropospheric Radar (BLTR) reader, Wind velocities and SNR from *.sswma files
90 '''
90 '''
91
91
92 ext = '.sswma'
92 ext = '.sswma'
93
93
94 def __init__(self):
94 def __init__(self):
95
95
96 ProcessingUnit.__init__(self)
96 ProcessingUnit.__init__(self)
97
97
98 self.dataOut = Parameters()
98 self.dataOut = Parameters()
99 self.counter_records = 0
99 self.counter_records = 0
100 self.flagNoMoreFiles = 0
100 self.flagNoMoreFiles = 0
101 self.isConfig = False
101 self.isConfig = False
102 self.filename = None
102 self.filename = None
103
103
104 def setup(self,
104 def setup(self,
105 path=None,
105 path=None,
106 startDate=None,
106 startDate=None,
107 endDate=None,
107 endDate=None,
108 ext=None,
108 ext=None,
109 startTime=datetime.time(0, 0, 0),
109 startTime=datetime.time(0, 0, 0),
110 endTime=datetime.time(23, 59, 59),
110 endTime=datetime.time(23, 59, 59),
111 timezone=0,
111 timezone=0,
112 status_value=0,
112 status_value=0,
113 **kwargs):
113 **kwargs):
114 self.path = path
114 self.path = path
115 self.startDate = startDate
115 self.startDate = startDate
116 self.endDate = endDate
116 self.endDate = endDate
117 self.startTime = startTime
117 self.startTime = startTime
118 self.endTime = endTime
118 self.endTime = endTime
119 self.status_value = status_value
119 self.status_value = status_value
120 self.datatime = datetime.datetime(1900,1,1)
120 self.datatime = datetime.datetime(1900,1,1)
121
121
122 if self.path is None:
122 if self.path is None:
123 raise ValueError("The path is not valid")
123 raise ValueError("The path is not valid")
124
124
125 if ext is None:
125 if ext is None:
126 ext = self.ext
126 ext = self.ext
127
127
128 self.search_files(self.path, startDate, endDate, ext)
128 self.search_files(self.path, startDate, endDate, ext)
129 self.timezone = timezone
129 self.timezone = timezone
130 self.fileIndex = 0
130 self.fileIndex = 0
131
131
132 if not self.fileList:
132 if not self.fileList:
133 raise Warning("There is no files matching these date in the folder: %s. \n Check 'startDate' and 'endDate' " % (
133 raise Warning("There is no files matching these date in the folder: %s. \n Check 'startDate' and 'endDate' " % (
134 path))
134 path))
135
135
136 self.setNextFile()
136 self.setNextFile()
137
137
138 def search_files(self, path, startDate, endDate, ext):
138 def search_files(self, path, startDate, endDate, ext):
139 '''
139 '''
140 Searching for BLTR rawdata file in path
140 Searching for BLTR rawdata file in path
141 Creating a list of file to proces included in [startDate,endDate]
141 Creating a list of file to proces included in [startDate,endDate]
142
142
143 Input:
143 Input:
144 path - Path to find BLTR rawdata files
144 path - Path to find BLTR rawdata files
145 startDate - Select file from this date
145 startDate - Select file from this date
146 enDate - Select file until this date
146 enDate - Select file until this date
147 ext - Extension of the file to read
147 ext - Extension of the file to read
148 '''
148 '''
149
149
150 log.success('Searching files in {} '.format(path), 'BLTRParamReader')
150 log.success('Searching files in {} '.format(path), 'BLTRParamReader')
151 foldercounter = 0
151 foldercounter = 0
152 fileList0 = glob.glob1(path, "*%s" % ext)
152 fileList0 = glob.glob1(path, "*%s" % ext)
153 fileList0.sort()
153 fileList0.sort()
154
154
155 self.fileList = []
155 self.fileList = []
156 self.dateFileList = []
156 self.dateFileList = []
157
157
158 for thisFile in fileList0:
158 for thisFile in fileList0:
159 year = thisFile[-14:-10]
159 year = thisFile[-14:-10]
160 if not isNumber(year):
160 if not isNumber(year):
161 continue
161 continue
162
162
163 month = thisFile[-10:-8]
163 month = thisFile[-10:-8]
164 if not isNumber(month):
164 if not isNumber(month):
165 continue
165 continue
166
166
167 day = thisFile[-8:-6]
167 day = thisFile[-8:-6]
168 if not isNumber(day):
168 if not isNumber(day):
169 continue
169 continue
170
170
171 year, month, day = int(year), int(month), int(day)
171 year, month, day = int(year), int(month), int(day)
172 dateFile = datetime.date(year, month, day)
172 dateFile = datetime.date(year, month, day)
173
173
174 if (startDate > dateFile) or (endDate < dateFile):
174 if (startDate > dateFile) or (endDate < dateFile):
175 continue
175 continue
176
176
177 self.fileList.append(thisFile)
177 self.fileList.append(thisFile)
178 self.dateFileList.append(dateFile)
178 self.dateFileList.append(dateFile)
179
179
180 return
180 return
181
181
182 def setNextFile(self):
182 def setNextFile(self):
183
183
184 file_id = self.fileIndex
184 file_id = self.fileIndex
185
185
186 if file_id == len(self.fileList):
186 if file_id == len(self.fileList):
187 self.flagNoMoreFiles = 1
187 self.flagNoMoreFiles = 1
188 return 0
188 return 0
189
189
190 log.success('Opening {}'.format(self.fileList[file_id]), 'BLTRParamReader')
190 log.success('Opening {}'.format(self.fileList[file_id]), 'BLTRParamReader')
191 filename = os.path.join(self.path, self.fileList[file_id])
191 filename = os.path.join(self.path, self.fileList[file_id])
192
192
193 dirname, name = os.path.split(filename)
193 dirname, name = os.path.split(filename)
194 # 'peru2' ---> Piura - 'peru1' ---> Huancayo or Porcuya
194 # 'peru2' ---> Piura - 'peru1' ---> Huancayo or Porcuya
195 self.siteFile = name.split('.')[0]
195 self.siteFile = name.split('.')[0]
196 if self.filename is not None:
196 if self.filename is not None:
197 self.fp.close()
197 self.fp.close()
198 self.filename = filename
198 self.filename = filename
199 self.fp = open(self.filename, 'rb')
199 self.fp = open(self.filename, 'rb')
200 self.header_file = numpy.fromfile(self.fp, FILE_HEADER_STRUCTURE, 1)
200 self.header_file = numpy.fromfile(self.fp, FILE_HEADER_STRUCTURE, 1)
201 self.nrecords = self.header_file['nrec'][0]
201 self.nrecords = self.header_file['nrec'][0]
202 self.sizeOfFile = os.path.getsize(self.filename)
202 self.sizeOfFile = os.path.getsize(self.filename)
203 self.counter_records = 0
203 self.counter_records = 0
204 self.flagIsNewFile = 0
204 self.flagIsNewFile = 0
205 self.fileIndex += 1
205 self.fileIndex += 1
206
206
207 return 1
207 return 1
208
208
209 def readNextBlock(self):
209 def readNextBlock(self):
210
210
211 while True:
211 while True:
212 if self.counter_records == self.nrecords:
212 if self.counter_records == self.nrecords:
213 self.flagIsNewFile = 1
213 self.flagIsNewFile = 1
214 if not self.setNextFile():
214 if not self.setNextFile():
215 return 0
215 return 0
216
216
217 self.readBlock()
217 self.readBlock()
218
218
219 if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \
219 if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \
220 (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
220 (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
221 log.warning(
221 log.warning(
222 'Reading Record No. {}/{} -> {} [Skipping]'.format(
222 'Reading Record No. {}/{} -> {} [Skipping]'.format(
223 self.counter_records,
223 self.counter_records,
224 self.nrecords,
224 self.nrecords,
225 self.datatime.ctime()),
225 self.datatime.ctime()),
226 'BLTRParamReader')
226 'BLTRParamReader')
227 continue
227 continue
228 break
228 break
229
229
230 log.log('Reading Record No. {}/{} -> {}'.format(
230 log.log('Reading Record No. {}/{} -> {}'.format(
231 self.counter_records,
231 self.counter_records,
232 self.nrecords,
232 self.nrecords,
233 self.datatime.ctime()), 'BLTRParamReader')
233 self.datatime.ctime()), 'BLTRParamReader')
234
234
235 return 1
235 return 1
236
236
237 def readBlock(self):
237 def readBlock(self):
238
238
239 pointer = self.fp.tell()
239 pointer = self.fp.tell()
240 header_rec = numpy.fromfile(self.fp, REC_HEADER_STRUCTURE, 1)
240 header_rec = numpy.fromfile(self.fp, REC_HEADER_STRUCTURE, 1)
241 self.nchannels = int(header_rec['nchan'][0] / 2)
241 self.nchannels = int(header_rec['nchan'][0] / 2)
242 self.kchan = header_rec['nrxs'][0]
242 self.kchan = header_rec['nrxs'][0]
243 self.nmodes = header_rec['nmodes'][0]
243 self.nmodes = header_rec['nmodes'][0]
244 self.nranges = header_rec['nranges'][0]
244 self.nranges = header_rec['nranges'][0]
245 self.fp.seek(pointer)
245 self.fp.seek(pointer)
246 self.height = numpy.empty((self.nmodes, self.nranges))
246 self.height = numpy.empty((self.nmodes, self.nranges))
247 self.snr = numpy.empty((self.nmodes, int(self.nchannels), self.nranges))
247 self.snr = numpy.empty((self.nmodes, int(self.nchannels), self.nranges))
248 self.buffer = numpy.empty((self.nmodes, 3, self.nranges))
248 self.buffer = numpy.empty((self.nmodes, 3, self.nranges))
249 self.flagDiscontinuousBlock = 0
249 self.flagDiscontinuousBlock = 0
250
250
251 for mode in range(self.nmodes):
251 for mode in range(self.nmodes):
252 self.readHeader()
252 self.readHeader()
253 data = self.readData()
253 data = self.readData()
254 self.height[mode] = (data[0] - self.correction) / 1000.
254 self.height[mode] = (data[0] - self.correction) / 1000.
255 self.buffer[mode] = data[1]
255 self.buffer[mode] = data[1]
256 self.snr[mode] = data[2]
256 self.snr[mode] = data[2]
257
257
258 self.counter_records = self.counter_records + self.nmodes
258 self.counter_records = self.counter_records + self.nmodes
259
259
260 return
260 return
261
261
262 def readHeader(self):
262 def readHeader(self):
263 '''
263 '''
264 RecordHeader of BLTR rawdata file
264 RecordHeader of BLTR rawdata file
265 '''
265 '''
266
266
267 header_structure = numpy.dtype(
267 header_structure = numpy.dtype(
268 REC_HEADER_STRUCTURE.descr + [
268 REC_HEADER_STRUCTURE.descr + [
269 ('antenna_coord', 'f4', (2, int(self.nchannels))),
269 ('antenna_coord', 'f4', (2, int(self.nchannels))),
270 ('rx_gains', 'u4', (int(self.nchannels),)),
270 ('rx_gains', 'u4', (int(self.nchannels),)),
271 ('rx_analysis', 'u4', (int(self.nchannels),))
271 ('rx_analysis', 'u4', (int(self.nchannels),))
272 ]
272 ]
273 )
273 )
274
274
275 self.header_rec = numpy.fromfile(self.fp, header_structure, 1)
275 self.header_rec = numpy.fromfile(self.fp, header_structure, 1)
276 self.lat = self.header_rec['lat'][0]
276 self.lat = self.header_rec['lat'][0]
277 self.lon = self.header_rec['lon'][0]
277 self.lon = self.header_rec['lon'][0]
278 self.delta = self.header_rec['delta_r'][0]
278 self.delta = self.header_rec['delta_r'][0]
279 self.correction = self.header_rec['dmode_rngcorr'][0]
279 self.correction = self.header_rec['dmode_rngcorr'][0]
280 self.imode = self.header_rec['dmode_index'][0]
280 self.imode = self.header_rec['dmode_index'][0]
281 self.antenna = self.header_rec['antenna_coord']
281 self.antenna = self.header_rec['antenna_coord']
282 self.rx_gains = self.header_rec['rx_gains']
282 self.rx_gains = self.header_rec['rx_gains']
283 self.time = self.header_rec['time'][0]
283 self.time = self.header_rec['time'][0]
284 dt = datetime.datetime.utcfromtimestamp(self.time)
284 dt = datetime.datetime.utcfromtimestamp(self.time)
285 if dt.date()>self.datatime.date():
285 if dt.date()>self.datatime.date():
286 self.flagDiscontinuousBlock = 1
286 self.flagDiscontinuousBlock = 1
287 self.datatime = dt
287 self.datatime = dt
288
288
289 def readData(self):
289 def readData(self):
290 '''
290 '''
291 Reading and filtering data block record of BLTR rawdata file, filtering is according to status_value.
291 Reading and filtering data block record of BLTR rawdata file, filtering is according to status_value.
292
292
293 Input:
293 Input:
294 status_value - Array data is set to NAN for values that are not equal to status_value
294 status_value - Array data is set to NAN for values that are not equal to status_value
295
295
296 '''
296 '''
297 self.nchannels = int(self.nchannels)
297 self.nchannels = int(self.nchannels)
298
298
299 data_structure = numpy.dtype(
299 data_structure = numpy.dtype(
300 DATA_STRUCTURE.descr + [
300 DATA_STRUCTURE.descr + [
301 ('rx_saturation', 'u4', (self.nchannels,)),
301 ('rx_saturation', 'u4', (self.nchannels,)),
302 ('chan_offset', 'u4', (2 * self.nchannels,)),
302 ('chan_offset', 'u4', (2 * self.nchannels,)),
303 ('rx_amp', 'u4', (self.nchannels,)),
303 ('rx_amp', 'u4', (self.nchannels,)),
304 ('rx_snr', 'f4', (self.nchannels,)),
304 ('rx_snr', 'f4', (self.nchannels,)),
305 ('cross_snr', 'f4', (self.kchan,)),
305 ('cross_snr', 'f4', (self.kchan,)),
306 ('sea_power_relative', 'f4', (self.kchan,))]
306 ('sea_power_relative', 'f4', (self.kchan,))]
307 )
307 )
308
308
309 data = numpy.fromfile(self.fp, data_structure, self.nranges)
309 data = numpy.fromfile(self.fp, data_structure, self.nranges)
310
310
311 height = data['range']
311 height = data['range']
312 winds = numpy.array(
312 winds = numpy.array(
313 (data['zonal'], data['meridional'], data['vertical']))
313 (data['zonal'], data['meridional'], data['vertical']))
314 snr = data['rx_snr'].T
314 snr = data['rx_snr'].T
315
315
316 winds[numpy.where(winds == -9999.)] = numpy.nan
316 winds[numpy.where(winds == -9999.)] = numpy.nan
317 winds[:, numpy.where(data['status'] != self.status_value)] = numpy.nan
317 winds[:, numpy.where(data['status'] != self.status_value)] = numpy.nan
318 snr[numpy.where(snr == -9999.)] = numpy.nan
318 snr[numpy.where(snr == -9999.)] = numpy.nan
319 snr[:, numpy.where(data['status'] != self.status_value)] = numpy.nan
319 snr[:, numpy.where(data['status'] != self.status_value)] = numpy.nan
320 snr = numpy.power(10, snr / 10)
320 snr = numpy.power(10, snr / 10)
321
321
322 return height, winds, snr
322 return height, winds, snr
323
323
324 def set_output(self):
324 def set_output(self):
325 '''
325 '''
326 Storing data from databuffer to dataOut object
326 Storing data from databuffer to dataOut object
327 '''
327 '''
328
328
329 self.dataOut.data_SNR = self.snr
329 self.dataOut.data_SNR = self.snr
330 self.dataOut.height = self.height
330 self.dataOut.height = self.height
331 self.dataOut.data = self.buffer
331 self.dataOut.data = self.buffer
332 self.dataOut.utctimeInit = self.time
332 self.dataOut.utctimeInit = self.time
333 self.dataOut.utctime = self.dataOut.utctimeInit
333 self.dataOut.utctime = self.dataOut.utctimeInit
334 self.dataOut.useLocalTime = False
334 self.dataOut.useLocalTime = False
335 self.dataOut.paramInterval = 157
335 self.dataOut.paramInterval = 157
336 self.dataOut.timezone = self.timezone
336 self.dataOut.timezone = self.timezone
337 self.dataOut.site = self.siteFile
337 self.dataOut.site = self.siteFile
338 self.dataOut.nrecords = self.nrecords / self.nmodes
338 self.dataOut.nrecords = self.nrecords / self.nmodes
339 self.dataOut.sizeOfFile = self.sizeOfFile
339 self.dataOut.sizeOfFile = self.sizeOfFile
340 self.dataOut.lat = self.lat
340 self.dataOut.lat = self.lat
341 self.dataOut.lon = self.lon
341 self.dataOut.lon = self.lon
342 self.dataOut.channelList = list(range(self.nchannels))
342 self.dataOut.channelList = list(range(self.nchannels))
343 self.dataOut.kchan = self.kchan
343 self.dataOut.kchan = self.kchan
344 self.dataOut.delta = self.delta
344 self.dataOut.delta = self.delta
345 self.dataOut.correction = self.correction
345 self.dataOut.correction = self.correction
346 self.dataOut.nmodes = self.nmodes
346 self.dataOut.nmodes = self.nmodes
347 self.dataOut.imode = self.imode
347 self.dataOut.imode = self.imode
348 self.dataOut.antenna = self.antenna
348 self.dataOut.antenna = self.antenna
349 self.dataOut.rx_gains = self.rx_gains
349 self.dataOut.rx_gains = self.rx_gains
350 self.dataOut.flagNoData = False
350 self.dataOut.flagNoData = False
351 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
351 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
352
352
353 def getData(self):
353 def getData(self):
354 '''
354 '''
355 Storing data from databuffer to dataOut object
355 Storing data from databuffer to dataOut object
356 '''
356 '''
357 if self.flagNoMoreFiles:
357 if self.flagNoMoreFiles:
358 self.dataOut.flagNoData = True
358 self.dataOut.flagNoData = True
359 self.dataOut.error = (1, 'No More files to read')
359 self.dataOut.error = 'No More files to read'
360
360
361 if not self.readNextBlock():
361 if not self.readNextBlock():
362 self.dataOut.flagNoData = True
362 self.dataOut.flagNoData = True
363 return 0
363 return 0
364
364
365 self.set_output()
365 self.set_output()
366
366
367 return 1
367 return 1
368 No newline at end of file
368
@@ -1,1828 +1,1828
1 '''
1 '''
2 Created on Jul 2, 2014
2 Created on Jul 2, 2014
3
3
4 @author: roj-idl71
4 @author: roj-idl71
5 '''
5 '''
6 import os
6 import os
7 import sys
7 import sys
8 import glob
8 import glob
9 import time
9 import time
10 import numpy
10 import numpy
11 import fnmatch
11 import fnmatch
12 import inspect
12 import inspect
13 import time
13 import time
14 import datetime
14 import datetime
15 import traceback
15 import traceback
16 import zmq
16 import zmq
17
17
18 try:
18 try:
19 from gevent import sleep
19 from gevent import sleep
20 except:
20 except:
21 from time import sleep
21 from time import sleep
22
22
23 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
23 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
24 from schainpy.model.data.jroheaderIO import get_dtype_index, get_numpy_dtype, get_procflag_dtype, get_dtype_width
24 from schainpy.model.data.jroheaderIO import get_dtype_index, get_numpy_dtype, get_procflag_dtype, get_dtype_width
25 from schainpy.utils import log
25 from schainpy.utils import log
26 import schainpy.admin
26 import schainpy.admin
27
27
28 LOCALTIME = True
28 LOCALTIME = True
29
29
30
30
31 def isNumber(cad):
31 def isNumber(cad):
32 """
32 """
33 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
33 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
34
34
35 Excepciones:
35 Excepciones:
36 Si un determinado string no puede ser convertido a numero
36 Si un determinado string no puede ser convertido a numero
37 Input:
37 Input:
38 str, string al cual se le analiza para determinar si convertible a un numero o no
38 str, string al cual se le analiza para determinar si convertible a un numero o no
39
39
40 Return:
40 Return:
41 True : si el string es uno numerico
41 True : si el string es uno numerico
42 False : no es un string numerico
42 False : no es un string numerico
43 """
43 """
44 try:
44 try:
45 float(cad)
45 float(cad)
46 return True
46 return True
47 except:
47 except:
48 return False
48 return False
49
49
50
50
51 def isFileInEpoch(filename, startUTSeconds, endUTSeconds):
51 def isFileInEpoch(filename, startUTSeconds, endUTSeconds):
52 """
52 """
53 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
53 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
54
54
55 Inputs:
55 Inputs:
56 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
56 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
57
57
58 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
58 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
59 segundos contados desde 01/01/1970.
59 segundos contados desde 01/01/1970.
60 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
60 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
61 segundos contados desde 01/01/1970.
61 segundos contados desde 01/01/1970.
62
62
63 Return:
63 Return:
64 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
64 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
65 fecha especificado, de lo contrario retorna False.
65 fecha especificado, de lo contrario retorna False.
66
66
67 Excepciones:
67 Excepciones:
68 Si el archivo no existe o no puede ser abierto
68 Si el archivo no existe o no puede ser abierto
69 Si la cabecera no puede ser leida.
69 Si la cabecera no puede ser leida.
70
70
71 """
71 """
72 basicHeaderObj = BasicHeader(LOCALTIME)
72 basicHeaderObj = BasicHeader(LOCALTIME)
73
73
74 try:
74 try:
75 fp = open(filename, 'rb')
75 fp = open(filename, 'rb')
76 except IOError:
76 except IOError:
77 print("The file %s can't be opened" % (filename))
77 print("The file %s can't be opened" % (filename))
78 return 0
78 return 0
79
79
80 sts = basicHeaderObj.read(fp)
80 sts = basicHeaderObj.read(fp)
81 fp.close()
81 fp.close()
82
82
83 if not(sts):
83 if not(sts):
84 print("Skipping the file %s because it has not a valid header" % (filename))
84 print("Skipping the file %s because it has not a valid header" % (filename))
85 return 0
85 return 0
86
86
87 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
87 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
88 return 0
88 return 0
89
89
90 return 1
90 return 1
91
91
92
92
93 def isTimeInRange(thisTime, startTime, endTime):
93 def isTimeInRange(thisTime, startTime, endTime):
94 if endTime >= startTime:
94 if endTime >= startTime:
95 if (thisTime < startTime) or (thisTime > endTime):
95 if (thisTime < startTime) or (thisTime > endTime):
96 return 0
96 return 0
97 return 1
97 return 1
98 else:
98 else:
99 if (thisTime < startTime) and (thisTime > endTime):
99 if (thisTime < startTime) and (thisTime > endTime):
100 return 0
100 return 0
101 return 1
101 return 1
102
102
103
103
104 def isFileInTimeRange(filename, startDate, endDate, startTime, endTime):
104 def isFileInTimeRange(filename, startDate, endDate, startTime, endTime):
105 """
105 """
106 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
106 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
107
107
108 Inputs:
108 Inputs:
109 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
109 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
110
110
111 startDate : fecha inicial del rango seleccionado en formato datetime.date
111 startDate : fecha inicial del rango seleccionado en formato datetime.date
112
112
113 endDate : fecha final del rango seleccionado en formato datetime.date
113 endDate : fecha final del rango seleccionado en formato datetime.date
114
114
115 startTime : tiempo inicial del rango seleccionado en formato datetime.time
115 startTime : tiempo inicial del rango seleccionado en formato datetime.time
116
116
117 endTime : tiempo final del rango seleccionado en formato datetime.time
117 endTime : tiempo final del rango seleccionado en formato datetime.time
118
118
119 Return:
119 Return:
120 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
120 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
121 fecha especificado, de lo contrario retorna False.
121 fecha especificado, de lo contrario retorna False.
122
122
123 Excepciones:
123 Excepciones:
124 Si el archivo no existe o no puede ser abierto
124 Si el archivo no existe o no puede ser abierto
125 Si la cabecera no puede ser leida.
125 Si la cabecera no puede ser leida.
126
126
127 """
127 """
128
128
129 try:
129 try:
130 fp = open(filename, 'rb')
130 fp = open(filename, 'rb')
131 except IOError:
131 except IOError:
132 print("The file %s can't be opened" % (filename))
132 print("The file %s can't be opened" % (filename))
133 return None
133 return None
134
134
135 firstBasicHeaderObj = BasicHeader(LOCALTIME)
135 firstBasicHeaderObj = BasicHeader(LOCALTIME)
136 systemHeaderObj = SystemHeader()
136 systemHeaderObj = SystemHeader()
137 radarControllerHeaderObj = RadarControllerHeader()
137 radarControllerHeaderObj = RadarControllerHeader()
138 processingHeaderObj = ProcessingHeader()
138 processingHeaderObj = ProcessingHeader()
139
139
140 lastBasicHeaderObj = BasicHeader(LOCALTIME)
140 lastBasicHeaderObj = BasicHeader(LOCALTIME)
141
141
142 sts = firstBasicHeaderObj.read(fp)
142 sts = firstBasicHeaderObj.read(fp)
143
143
144 if not(sts):
144 if not(sts):
145 print("[Reading] Skipping the file %s because it has not a valid header" % (filename))
145 print("[Reading] Skipping the file %s because it has not a valid header" % (filename))
146 return None
146 return None
147
147
148 if not systemHeaderObj.read(fp):
148 if not systemHeaderObj.read(fp):
149 return None
149 return None
150
150
151 if not radarControllerHeaderObj.read(fp):
151 if not radarControllerHeaderObj.read(fp):
152 return None
152 return None
153
153
154 if not processingHeaderObj.read(fp):
154 if not processingHeaderObj.read(fp):
155 return None
155 return None
156
156
157 filesize = os.path.getsize(filename)
157 filesize = os.path.getsize(filename)
158
158
159 offset = processingHeaderObj.blockSize + 24 # header size
159 offset = processingHeaderObj.blockSize + 24 # header size
160
160
161 if filesize <= offset:
161 if filesize <= offset:
162 print("[Reading] %s: This file has not enough data" % filename)
162 print("[Reading] %s: This file has not enough data" % filename)
163 return None
163 return None
164
164
165 fp.seek(-offset, 2)
165 fp.seek(-offset, 2)
166
166
167 sts = lastBasicHeaderObj.read(fp)
167 sts = lastBasicHeaderObj.read(fp)
168
168
169 fp.close()
169 fp.close()
170
170
171 thisDatetime = lastBasicHeaderObj.datatime
171 thisDatetime = lastBasicHeaderObj.datatime
172 thisTime_last_block = thisDatetime.time()
172 thisTime_last_block = thisDatetime.time()
173
173
174 thisDatetime = firstBasicHeaderObj.datatime
174 thisDatetime = firstBasicHeaderObj.datatime
175 thisDate = thisDatetime.date()
175 thisDate = thisDatetime.date()
176 thisTime_first_block = thisDatetime.time()
176 thisTime_first_block = thisDatetime.time()
177
177
178 # General case
178 # General case
179 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
179 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
180 #-----------o----------------------------o-----------
180 #-----------o----------------------------o-----------
181 # startTime endTime
181 # startTime endTime
182
182
183 if endTime >= startTime:
183 if endTime >= startTime:
184 if (thisTime_last_block < startTime) or (thisTime_first_block > endTime):
184 if (thisTime_last_block < startTime) or (thisTime_first_block > endTime):
185 return None
185 return None
186
186
187 return thisDatetime
187 return thisDatetime
188
188
189 # If endTime < startTime then endTime belongs to the next day
189 # If endTime < startTime then endTime belongs to the next day
190
190
191 #<<<<<<<<<<<o o>>>>>>>>>>>
191 #<<<<<<<<<<<o o>>>>>>>>>>>
192 #-----------o----------------------------o-----------
192 #-----------o----------------------------o-----------
193 # endTime startTime
193 # endTime startTime
194
194
195 if (thisDate == startDate) and (thisTime_last_block < startTime):
195 if (thisDate == startDate) and (thisTime_last_block < startTime):
196 return None
196 return None
197
197
198 if (thisDate == endDate) and (thisTime_first_block > endTime):
198 if (thisDate == endDate) and (thisTime_first_block > endTime):
199 return None
199 return None
200
200
201 if (thisTime_last_block < startTime) and (thisTime_first_block > endTime):
201 if (thisTime_last_block < startTime) and (thisTime_first_block > endTime):
202 return None
202 return None
203
203
204 return thisDatetime
204 return thisDatetime
205
205
206
206
207 def isFolderInDateRange(folder, startDate=None, endDate=None):
207 def isFolderInDateRange(folder, startDate=None, endDate=None):
208 """
208 """
209 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
209 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
210
210
211 Inputs:
211 Inputs:
212 folder : nombre completo del directorio.
212 folder : nombre completo del directorio.
213 Su formato deberia ser "/path_root/?YYYYDDD"
213 Su formato deberia ser "/path_root/?YYYYDDD"
214
214
215 siendo:
215 siendo:
216 YYYY : Anio (ejemplo 2015)
216 YYYY : Anio (ejemplo 2015)
217 DDD : Dia del anio (ejemplo 305)
217 DDD : Dia del anio (ejemplo 305)
218
218
219 startDate : fecha inicial del rango seleccionado en formato datetime.date
219 startDate : fecha inicial del rango seleccionado en formato datetime.date
220
220
221 endDate : fecha final del rango seleccionado en formato datetime.date
221 endDate : fecha final del rango seleccionado en formato datetime.date
222
222
223 Return:
223 Return:
224 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
224 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
225 fecha especificado, de lo contrario retorna False.
225 fecha especificado, de lo contrario retorna False.
226 Excepciones:
226 Excepciones:
227 Si el directorio no tiene el formato adecuado
227 Si el directorio no tiene el formato adecuado
228 """
228 """
229
229
230 basename = os.path.basename(folder)
230 basename = os.path.basename(folder)
231
231
232 if not isRadarFolder(basename):
232 if not isRadarFolder(basename):
233 print("The folder %s has not the rigth format" % folder)
233 print("The folder %s has not the rigth format" % folder)
234 return 0
234 return 0
235
235
236 if startDate and endDate:
236 if startDate and endDate:
237 thisDate = getDateFromRadarFolder(basename)
237 thisDate = getDateFromRadarFolder(basename)
238
238
239 if thisDate < startDate:
239 if thisDate < startDate:
240 return 0
240 return 0
241
241
242 if thisDate > endDate:
242 if thisDate > endDate:
243 return 0
243 return 0
244
244
245 return 1
245 return 1
246
246
247
247
248 def isFileInDateRange(filename, startDate=None, endDate=None):
248 def isFileInDateRange(filename, startDate=None, endDate=None):
249 """
249 """
250 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
250 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
251
251
252 Inputs:
252 Inputs:
253 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
253 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
254
254
255 Su formato deberia ser "?YYYYDDDsss"
255 Su formato deberia ser "?YYYYDDDsss"
256
256
257 siendo:
257 siendo:
258 YYYY : Anio (ejemplo 2015)
258 YYYY : Anio (ejemplo 2015)
259 DDD : Dia del anio (ejemplo 305)
259 DDD : Dia del anio (ejemplo 305)
260 sss : set
260 sss : set
261
261
262 startDate : fecha inicial del rango seleccionado en formato datetime.date
262 startDate : fecha inicial del rango seleccionado en formato datetime.date
263
263
264 endDate : fecha final del rango seleccionado en formato datetime.date
264 endDate : fecha final del rango seleccionado en formato datetime.date
265
265
266 Return:
266 Return:
267 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
267 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
268 fecha especificado, de lo contrario retorna False.
268 fecha especificado, de lo contrario retorna False.
269 Excepciones:
269 Excepciones:
270 Si el archivo no tiene el formato adecuado
270 Si el archivo no tiene el formato adecuado
271 """
271 """
272
272
273 basename = os.path.basename(filename)
273 basename = os.path.basename(filename)
274
274
275 if not isRadarFile(basename):
275 if not isRadarFile(basename):
276 print("The filename %s has not the rigth format" % filename)
276 print("The filename %s has not the rigth format" % filename)
277 return 0
277 return 0
278
278
279 if startDate and endDate:
279 if startDate and endDate:
280 thisDate = getDateFromRadarFile(basename)
280 thisDate = getDateFromRadarFile(basename)
281
281
282 if thisDate < startDate:
282 if thisDate < startDate:
283 return 0
283 return 0
284
284
285 if thisDate > endDate:
285 if thisDate > endDate:
286 return 0
286 return 0
287
287
288 return 1
288 return 1
289
289
290
290
291 def getFileFromSet(path, ext, set):
291 def getFileFromSet(path, ext, set):
292 validFilelist = []
292 validFilelist = []
293 fileList = os.listdir(path)
293 fileList = os.listdir(path)
294
294
295 # 0 1234 567 89A BCDE
295 # 0 1234 567 89A BCDE
296 # H YYYY DDD SSS .ext
296 # H YYYY DDD SSS .ext
297
297
298 for thisFile in fileList:
298 for thisFile in fileList:
299 try:
299 try:
300 year = int(thisFile[1:5])
300 year = int(thisFile[1:5])
301 doy = int(thisFile[5:8])
301 doy = int(thisFile[5:8])
302 except:
302 except:
303 continue
303 continue
304
304
305 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
305 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
306 continue
306 continue
307
307
308 validFilelist.append(thisFile)
308 validFilelist.append(thisFile)
309
309
310 myfile = fnmatch.filter(
310 myfile = fnmatch.filter(
311 validFilelist, '*%4.4d%3.3d%3.3d*' % (year, doy, set))
311 validFilelist, '*%4.4d%3.3d%3.3d*' % (year, doy, set))
312
312
313 if len(myfile) != 0:
313 if len(myfile) != 0:
314 return myfile[0]
314 return myfile[0]
315 else:
315 else:
316 filename = '*%4.4d%3.3d%3.3d%s' % (year, doy, set, ext.lower())
316 filename = '*%4.4d%3.3d%3.3d%s' % (year, doy, set, ext.lower())
317 print('the filename %s does not exist' % filename)
317 print('the filename %s does not exist' % filename)
318 print('...going to the last file: ')
318 print('...going to the last file: ')
319
319
320 if validFilelist:
320 if validFilelist:
321 validFilelist = sorted(validFilelist, key=str.lower)
321 validFilelist = sorted(validFilelist, key=str.lower)
322 return validFilelist[-1]
322 return validFilelist[-1]
323
323
324 return None
324 return None
325
325
326
326
327 def getlastFileFromPath(path, ext):
327 def getlastFileFromPath(path, ext):
328 """
328 """
329 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
329 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
330 al final de la depuracion devuelve el ultimo file de la lista que quedo.
330 al final de la depuracion devuelve el ultimo file de la lista que quedo.
331
331
332 Input:
332 Input:
333 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
333 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
334 ext : extension de los files contenidos en una carpeta
334 ext : extension de los files contenidos en una carpeta
335
335
336 Return:
336 Return:
337 El ultimo file de una determinada carpeta, no se considera el path.
337 El ultimo file de una determinada carpeta, no se considera el path.
338 """
338 """
339 validFilelist = []
339 validFilelist = []
340 fileList = os.listdir(path)
340 fileList = os.listdir(path)
341
341
342 # 0 1234 567 89A BCDE
342 # 0 1234 567 89A BCDE
343 # H YYYY DDD SSS .ext
343 # H YYYY DDD SSS .ext
344
344
345 for thisFile in fileList:
345 for thisFile in fileList:
346
346
347 year = thisFile[1:5]
347 year = thisFile[1:5]
348 if not isNumber(year):
348 if not isNumber(year):
349 continue
349 continue
350
350
351 doy = thisFile[5:8]
351 doy = thisFile[5:8]
352 if not isNumber(doy):
352 if not isNumber(doy):
353 continue
353 continue
354
354
355 year = int(year)
355 year = int(year)
356 doy = int(doy)
356 doy = int(doy)
357
357
358 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
358 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
359 continue
359 continue
360
360
361 validFilelist.append(thisFile)
361 validFilelist.append(thisFile)
362
362
363 if validFilelist:
363 if validFilelist:
364 validFilelist = sorted(validFilelist, key=str.lower)
364 validFilelist = sorted(validFilelist, key=str.lower)
365 return validFilelist[-1]
365 return validFilelist[-1]
366
366
367 return None
367 return None
368
368
369
369
370 def checkForRealPath(path, foldercounter, year, doy, set, ext):
370 def checkForRealPath(path, foldercounter, year, doy, set, ext):
371 """
371 """
372 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
372 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
373 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
373 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
374 el path exacto de un determinado file.
374 el path exacto de un determinado file.
375
375
376 Example :
376 Example :
377 nombre correcto del file es .../.../D2009307/P2009307367.ext
377 nombre correcto del file es .../.../D2009307/P2009307367.ext
378
378
379 Entonces la funcion prueba con las siguientes combinaciones
379 Entonces la funcion prueba con las siguientes combinaciones
380 .../.../y2009307367.ext
380 .../.../y2009307367.ext
381 .../.../Y2009307367.ext
381 .../.../Y2009307367.ext
382 .../.../x2009307/y2009307367.ext
382 .../.../x2009307/y2009307367.ext
383 .../.../x2009307/Y2009307367.ext
383 .../.../x2009307/Y2009307367.ext
384 .../.../X2009307/y2009307367.ext
384 .../.../X2009307/y2009307367.ext
385 .../.../X2009307/Y2009307367.ext
385 .../.../X2009307/Y2009307367.ext
386 siendo para este caso, la ultima combinacion de letras, identica al file buscado
386 siendo para este caso, la ultima combinacion de letras, identica al file buscado
387
387
388 Return:
388 Return:
389 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
389 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
390 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
390 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
391 para el filename
391 para el filename
392 """
392 """
393 fullfilename = None
393 fullfilename = None
394 find_flag = False
394 find_flag = False
395 filename = None
395 filename = None
396
396
397 prefixDirList = [None, 'd', 'D']
397 prefixDirList = [None, 'd', 'D']
398 if ext.lower() == ".r": # voltage
398 if ext.lower() == ".r": # voltage
399 prefixFileList = ['d', 'D']
399 prefixFileList = ['d', 'D']
400 elif ext.lower() == ".pdata": # spectra
400 elif ext.lower() == ".pdata": # spectra
401 prefixFileList = ['p', 'P']
401 prefixFileList = ['p', 'P']
402 else:
402 else:
403 return None, filename
403 return None, filename
404
404
405 # barrido por las combinaciones posibles
405 # barrido por las combinaciones posibles
406 for prefixDir in prefixDirList:
406 for prefixDir in prefixDirList:
407 thispath = path
407 thispath = path
408 if prefixDir != None:
408 if prefixDir != None:
409 # formo el nombre del directorio xYYYYDDD (x=d o x=D)
409 # formo el nombre del directorio xYYYYDDD (x=d o x=D)
410 if foldercounter == 0:
410 if foldercounter == 0:
411 thispath = os.path.join(path, "%s%04d%03d" %
411 thispath = os.path.join(path, "%s%04d%03d" %
412 (prefixDir, year, doy))
412 (prefixDir, year, doy))
413 else:
413 else:
414 thispath = os.path.join(path, "%s%04d%03d_%02d" % (
414 thispath = os.path.join(path, "%s%04d%03d_%02d" % (
415 prefixDir, year, doy, foldercounter))
415 prefixDir, year, doy, foldercounter))
416 for prefixFile in prefixFileList: # barrido por las dos combinaciones posibles de "D"
416 for prefixFile in prefixFileList: # barrido por las dos combinaciones posibles de "D"
417 # formo el nombre del file xYYYYDDDSSS.ext
417 # formo el nombre del file xYYYYDDDSSS.ext
418 filename = "%s%04d%03d%03d%s" % (prefixFile, year, doy, set, ext)
418 filename = "%s%04d%03d%03d%s" % (prefixFile, year, doy, set, ext)
419 fullfilename = os.path.join(
419 fullfilename = os.path.join(
420 thispath, filename) # formo el path completo
420 thispath, filename) # formo el path completo
421
421
422 if os.path.exists(fullfilename): # verifico que exista
422 if os.path.exists(fullfilename): # verifico que exista
423 find_flag = True
423 find_flag = True
424 break
424 break
425 if find_flag:
425 if find_flag:
426 break
426 break
427
427
428 if not(find_flag):
428 if not(find_flag):
429 return None, filename
429 return None, filename
430
430
431 return fullfilename, filename
431 return fullfilename, filename
432
432
433
433
434 def isRadarFolder(folder):
434 def isRadarFolder(folder):
435 try:
435 try:
436 year = int(folder[1:5])
436 year = int(folder[1:5])
437 doy = int(folder[5:8])
437 doy = int(folder[5:8])
438 except:
438 except:
439 return 0
439 return 0
440
440
441 return 1
441 return 1
442
442
443
443
444 def isRadarFile(file):
444 def isRadarFile(file):
445 try:
445 try:
446 year = int(file[1:5])
446 year = int(file[1:5])
447 doy = int(file[5:8])
447 doy = int(file[5:8])
448 set = int(file[8:11])
448 set = int(file[8:11])
449 except:
449 except:
450 return 0
450 return 0
451
451
452 return 1
452 return 1
453
453
454
454
455 def getDateFromRadarFile(file):
455 def getDateFromRadarFile(file):
456 try:
456 try:
457 year = int(file[1:5])
457 year = int(file[1:5])
458 doy = int(file[5:8])
458 doy = int(file[5:8])
459 set = int(file[8:11])
459 set = int(file[8:11])
460 except:
460 except:
461 return None
461 return None
462
462
463 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
463 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
464 return thisDate
464 return thisDate
465
465
466
466
467 def getDateFromRadarFolder(folder):
467 def getDateFromRadarFolder(folder):
468 try:
468 try:
469 year = int(folder[1:5])
469 year = int(folder[1:5])
470 doy = int(folder[5:8])
470 doy = int(folder[5:8])
471 except:
471 except:
472 return None
472 return None
473
473
474 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
474 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
475 return thisDate
475 return thisDate
476
476
477
477
478 class JRODataIO:
478 class JRODataIO:
479
479
480 c = 3E8
480 c = 3E8
481
481
482 isConfig = False
482 isConfig = False
483
483
484 basicHeaderObj = None
484 basicHeaderObj = None
485
485
486 systemHeaderObj = None
486 systemHeaderObj = None
487
487
488 radarControllerHeaderObj = None
488 radarControllerHeaderObj = None
489
489
490 processingHeaderObj = None
490 processingHeaderObj = None
491
491
492 dtype = None
492 dtype = None
493
493
494 pathList = []
494 pathList = []
495
495
496 filenameList = []
496 filenameList = []
497
497
498 filename = None
498 filename = None
499
499
500 ext = None
500 ext = None
501
501
502 flagIsNewFile = 1
502 flagIsNewFile = 1
503
503
504 flagDiscontinuousBlock = 0
504 flagDiscontinuousBlock = 0
505
505
506 flagIsNewBlock = 0
506 flagIsNewBlock = 0
507
507
508 fp = None
508 fp = None
509
509
510 firstHeaderSize = 0
510 firstHeaderSize = 0
511
511
512 basicHeaderSize = 24
512 basicHeaderSize = 24
513
513
514 versionFile = 1103
514 versionFile = 1103
515
515
516 fileSize = None
516 fileSize = None
517
517
518 # ippSeconds = None
518 # ippSeconds = None
519
519
520 fileSizeByHeader = None
520 fileSizeByHeader = None
521
521
522 fileIndex = None
522 fileIndex = None
523
523
524 profileIndex = None
524 profileIndex = None
525
525
526 blockIndex = None
526 blockIndex = None
527
527
528 nTotalBlocks = None
528 nTotalBlocks = None
529
529
530 maxTimeStep = 30
530 maxTimeStep = 30
531
531
532 lastUTTime = None
532 lastUTTime = None
533
533
534 datablock = None
534 datablock = None
535
535
536 dataOut = None
536 dataOut = None
537
537
538 blocksize = None
538 blocksize = None
539
539
540 getByBlock = False
540 getByBlock = False
541
541
542 def __init__(self):
542 def __init__(self):
543
543
544 raise NotImplementedError
544 raise NotImplementedError
545
545
546 def run(self):
546 def run(self):
547
547
548 raise NotImplementedError
548 raise NotImplementedError
549
549
550 def getDtypeWidth(self):
550 def getDtypeWidth(self):
551
551
552 dtype_index = get_dtype_index(self.dtype)
552 dtype_index = get_dtype_index(self.dtype)
553 dtype_width = get_dtype_width(dtype_index)
553 dtype_width = get_dtype_width(dtype_index)
554
554
555 return dtype_width
555 return dtype_width
556
556
557 def getAllowedArgs(self):
557 def getAllowedArgs(self):
558 if hasattr(self, '__attrs__'):
558 if hasattr(self, '__attrs__'):
559 return self.__attrs__
559 return self.__attrs__
560 else:
560 else:
561 return inspect.getargspec(self.run).args
561 return inspect.getargspec(self.run).args
562
562
563
563
564 class JRODataReader(JRODataIO):
564 class JRODataReader(JRODataIO):
565
565
566 online = 0
566 online = 0
567
567
568 realtime = 0
568 realtime = 0
569
569
570 nReadBlocks = 0
570 nReadBlocks = 0
571
571
572 delay = 10 # number of seconds waiting a new file
572 delay = 10 # number of seconds waiting a new file
573
573
574 nTries = 3 # quantity tries
574 nTries = 3 # quantity tries
575
575
576 nFiles = 3 # number of files for searching
576 nFiles = 3 # number of files for searching
577
577
578 path = None
578 path = None
579
579
580 foldercounter = 0
580 foldercounter = 0
581
581
582 flagNoMoreFiles = 0
582 flagNoMoreFiles = 0
583
583
584 datetimeList = []
584 datetimeList = []
585
585
586 __isFirstTimeOnline = 1
586 __isFirstTimeOnline = 1
587
587
588 __printInfo = True
588 __printInfo = True
589
589
590 profileIndex = None
590 profileIndex = None
591
591
592 nTxs = 1
592 nTxs = 1
593
593
594 txIndex = None
594 txIndex = None
595
595
596 # Added--------------------
596 # Added--------------------
597
597
598 selBlocksize = None
598 selBlocksize = None
599
599
600 selBlocktime = None
600 selBlocktime = None
601
601
602 def __init__(self):
602 def __init__(self):
603 """
603 """
604 This class is used to find data files
604 This class is used to find data files
605
605
606 Example:
606 Example:
607 reader = JRODataReader()
607 reader = JRODataReader()
608 fileList = reader.findDataFiles()
608 fileList = reader.findDataFiles()
609
609
610 """
610 """
611 pass
611 pass
612
612
613 def createObjByDefault(self):
613 def createObjByDefault(self):
614 """
614 """
615
615
616 """
616 """
617 raise NotImplementedError
617 raise NotImplementedError
618
618
619 def getBlockDimension(self):
619 def getBlockDimension(self):
620
620
621 raise NotImplementedError
621 raise NotImplementedError
622
622
623 def searchFilesOffLine(self,
623 def searchFilesOffLine(self,
624 path,
624 path,
625 startDate=None,
625 startDate=None,
626 endDate=None,
626 endDate=None,
627 startTime=datetime.time(0, 0, 0),
627 startTime=datetime.time(0, 0, 0),
628 endTime=datetime.time(23, 59, 59),
628 endTime=datetime.time(23, 59, 59),
629 set=None,
629 set=None,
630 expLabel='',
630 expLabel='',
631 ext='.r',
631 ext='.r',
632 cursor=None,
632 cursor=None,
633 skip=None,
633 skip=None,
634 walk=True):
634 walk=True):
635
635
636 self.filenameList = []
636 self.filenameList = []
637 self.datetimeList = []
637 self.datetimeList = []
638
638
639 pathList = []
639 pathList = []
640
640
641 dateList, pathList = self.findDatafiles(
641 dateList, pathList = self.findDatafiles(
642 path, startDate, endDate, expLabel, ext, walk, include_path=True)
642 path, startDate, endDate, expLabel, ext, walk, include_path=True)
643
643
644 if dateList == []:
644 if dateList == []:
645 return [], []
645 return [], []
646
646
647 if len(dateList) > 1:
647 if len(dateList) > 1:
648 print("[Reading] Data found for date range [%s - %s]: total days = %d" % (startDate, endDate, len(dateList)))
648 print("[Reading] Data found for date range [%s - %s]: total days = %d" % (startDate, endDate, len(dateList)))
649 else:
649 else:
650 print("[Reading] Data found for date range [%s - %s]: date = %s" % (startDate, endDate, dateList[0]))
650 print("[Reading] Data found for date range [%s - %s]: date = %s" % (startDate, endDate, dateList[0]))
651
651
652 filenameList = []
652 filenameList = []
653 datetimeList = []
653 datetimeList = []
654
654
655 for thisPath in pathList:
655 for thisPath in pathList:
656
656
657 fileList = glob.glob1(thisPath, "*%s" % ext)
657 fileList = glob.glob1(thisPath, "*%s" % ext)
658 fileList.sort()
658 fileList.sort()
659
659
660 for file in fileList:
660 for file in fileList:
661
661
662 filename = os.path.join(thisPath, file)
662 filename = os.path.join(thisPath, file)
663
663
664 if not isFileInDateRange(filename, startDate, endDate):
664 if not isFileInDateRange(filename, startDate, endDate):
665 continue
665 continue
666
666
667 thisDatetime = isFileInTimeRange(
667 thisDatetime = isFileInTimeRange(
668 filename, startDate, endDate, startTime, endTime)
668 filename, startDate, endDate, startTime, endTime)
669
669
670 if not(thisDatetime):
670 if not(thisDatetime):
671 continue
671 continue
672
672
673 filenameList.append(filename)
673 filenameList.append(filename)
674 datetimeList.append(thisDatetime)
674 datetimeList.append(thisDatetime)
675
675
676 if cursor is not None and skip is not None:
676 if cursor is not None and skip is not None:
677 filenameList = filenameList[cursor * skip:cursor * skip + skip]
677 filenameList = filenameList[cursor * skip:cursor * skip + skip]
678 datetimeList = datetimeList[cursor * skip:cursor * skip + skip]
678 datetimeList = datetimeList[cursor * skip:cursor * skip + skip]
679
679
680 if not(filenameList):
680 if not(filenameList):
681 print("[Reading] Time range selected invalid [%s - %s]: No *%s files in %s)" % (startTime, endTime, ext, path))
681 print("[Reading] Time range selected invalid [%s - %s]: No *%s files in %s)" % (startTime, endTime, ext, path))
682 return [], []
682 return [], []
683
683
684 print("[Reading] %d file(s) was(were) found in time range: %s - %s" % (len(filenameList), startTime, endTime))
684 print("[Reading] %d file(s) was(were) found in time range: %s - %s" % (len(filenameList), startTime, endTime))
685
685
686 # for i in range(len(filenameList)):
686 # for i in range(len(filenameList)):
687 # print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
687 # print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
688
688
689 self.filenameList = filenameList
689 self.filenameList = filenameList
690 self.datetimeList = datetimeList
690 self.datetimeList = datetimeList
691
691
692 return pathList, filenameList
692 return pathList, filenameList
693
693
694 def __searchFilesOnLine(self, path, expLabel="", ext=None, walk=True, set=None):
694 def __searchFilesOnLine(self, path, expLabel="", ext=None, walk=True, set=None):
695 """
695 """
696 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
696 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
697 devuelve el archivo encontrado ademas de otros datos.
697 devuelve el archivo encontrado ademas de otros datos.
698
698
699 Input:
699 Input:
700 path : carpeta donde estan contenidos los files que contiene data
700 path : carpeta donde estan contenidos los files que contiene data
701
701
702 expLabel : Nombre del subexperimento (subfolder)
702 expLabel : Nombre del subexperimento (subfolder)
703
703
704 ext : extension de los files
704 ext : extension de los files
705
705
706 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
706 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
707
707
708 Return:
708 Return:
709 directory : eL directorio donde esta el file encontrado
709 directory : eL directorio donde esta el file encontrado
710 filename : el ultimo file de una determinada carpeta
710 filename : el ultimo file de una determinada carpeta
711 year : el anho
711 year : el anho
712 doy : el numero de dia del anho
712 doy : el numero de dia del anho
713 set : el set del archivo
713 set : el set del archivo
714
714
715
715
716 """
716 """
717 if not os.path.isdir(path):
717 if not os.path.isdir(path):
718 return None, None, None, None, None, None
718 return None, None, None, None, None, None
719
719
720 dirList = []
720 dirList = []
721
721
722 if not walk:
722 if not walk:
723 fullpath = path
723 fullpath = path
724 foldercounter = 0
724 foldercounter = 0
725 else:
725 else:
726 # Filtra solo los directorios
726 # Filtra solo los directorios
727 for thisPath in os.listdir(path):
727 for thisPath in os.listdir(path):
728 if not os.path.isdir(os.path.join(path, thisPath)):
728 if not os.path.isdir(os.path.join(path, thisPath)):
729 continue
729 continue
730 if not isRadarFolder(thisPath):
730 if not isRadarFolder(thisPath):
731 continue
731 continue
732
732
733 dirList.append(thisPath)
733 dirList.append(thisPath)
734
734
735 if not(dirList):
735 if not(dirList):
736 return None, None, None, None, None, None
736 return None, None, None, None, None, None
737
737
738 dirList = sorted(dirList, key=str.lower)
738 dirList = sorted(dirList, key=str.lower)
739
739
740 doypath = dirList[-1]
740 doypath = dirList[-1]
741 foldercounter = int(doypath.split('_')[1]) if len(
741 foldercounter = int(doypath.split('_')[1]) if len(
742 doypath.split('_')) > 1 else 0
742 doypath.split('_')) > 1 else 0
743 fullpath = os.path.join(path, doypath, expLabel)
743 fullpath = os.path.join(path, doypath, expLabel)
744
744
745 print("[Reading] %s folder was found: " % (fullpath))
745 print("[Reading] %s folder was found: " % (fullpath))
746
746
747 if set == None:
747 if set == None:
748 filename = getlastFileFromPath(fullpath, ext)
748 filename = getlastFileFromPath(fullpath, ext)
749 else:
749 else:
750 filename = getFileFromSet(fullpath, ext, set)
750 filename = getFileFromSet(fullpath, ext, set)
751
751
752 if not(filename):
752 if not(filename):
753 return None, None, None, None, None, None
753 return None, None, None, None, None, None
754
754
755 print("[Reading] %s file was found" % (filename))
755 print("[Reading] %s file was found" % (filename))
756
756
757 if not(self.__verifyFile(os.path.join(fullpath, filename))):
757 if not(self.__verifyFile(os.path.join(fullpath, filename))):
758 return None, None, None, None, None, None
758 return None, None, None, None, None, None
759
759
760 year = int(filename[1:5])
760 year = int(filename[1:5])
761 doy = int(filename[5:8])
761 doy = int(filename[5:8])
762 set = int(filename[8:11])
762 set = int(filename[8:11])
763
763
764 return fullpath, foldercounter, filename, year, doy, set
764 return fullpath, foldercounter, filename, year, doy, set
765
765
766 def __setNextFileOffline(self):
766 def __setNextFileOffline(self):
767
767
768 idFile = self.fileIndex
768 idFile = self.fileIndex
769
769
770 while (True):
770 while (True):
771 idFile += 1
771 idFile += 1
772 if not(idFile < len(self.filenameList)):
772 if not(idFile < len(self.filenameList)):
773 self.flagNoMoreFiles = 1
773 self.flagNoMoreFiles = 1
774 # print "[Reading] No more Files"
774 # print "[Reading] No more Files"
775 return 0
775 return 0
776
776
777 filename = self.filenameList[idFile]
777 filename = self.filenameList[idFile]
778
778
779 if not(self.__verifyFile(filename)):
779 if not(self.__verifyFile(filename)):
780 continue
780 continue
781
781
782 fileSize = os.path.getsize(filename)
782 fileSize = os.path.getsize(filename)
783 fp = open(filename, 'rb')
783 fp = open(filename, 'rb')
784 break
784 break
785
785
786 self.flagIsNewFile = 1
786 self.flagIsNewFile = 1
787 self.fileIndex = idFile
787 self.fileIndex = idFile
788 self.filename = filename
788 self.filename = filename
789 self.fileSize = fileSize
789 self.fileSize = fileSize
790 self.fp = fp
790 self.fp = fp
791
791
792 # print "[Reading] Setting the file: %s"%self.filename
792 # print "[Reading] Setting the file: %s"%self.filename
793
793
794 return 1
794 return 1
795
795
796 def __setNextFileOnline(self):
796 def __setNextFileOnline(self):
797 """
797 """
798 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
798 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
799 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
799 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
800 siguientes.
800 siguientes.
801
801
802 Affected:
802 Affected:
803 self.flagIsNewFile
803 self.flagIsNewFile
804 self.filename
804 self.filename
805 self.fileSize
805 self.fileSize
806 self.fp
806 self.fp
807 self.set
807 self.set
808 self.flagNoMoreFiles
808 self.flagNoMoreFiles
809
809
810 Return:
810 Return:
811 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
811 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
812 1 : si el file fue abierto con exito y esta listo a ser leido
812 1 : si el file fue abierto con exito y esta listo a ser leido
813
813
814 Excepciones:
814 Excepciones:
815 Si un determinado file no puede ser abierto
815 Si un determinado file no puede ser abierto
816 """
816 """
817 nFiles = 0
817 nFiles = 0
818 fileOk_flag = False
818 fileOk_flag = False
819 firstTime_flag = True
819 firstTime_flag = True
820
820
821 self.set += 1
821 self.set += 1
822
822
823 if self.set > 999:
823 if self.set > 999:
824 self.set = 0
824 self.set = 0
825 self.foldercounter += 1
825 self.foldercounter += 1
826
826
827 # busca el 1er file disponible
827 # busca el 1er file disponible
828 fullfilename, filename = checkForRealPath(
828 fullfilename, filename = checkForRealPath(
829 self.path, self.foldercounter, self.year, self.doy, self.set, self.ext)
829 self.path, self.foldercounter, self.year, self.doy, self.set, self.ext)
830 if fullfilename:
830 if fullfilename:
831 if self.__verifyFile(fullfilename, False):
831 if self.__verifyFile(fullfilename, False):
832 fileOk_flag = True
832 fileOk_flag = True
833
833
834 # si no encuentra un file entonces espera y vuelve a buscar
834 # si no encuentra un file entonces espera y vuelve a buscar
835 if not(fileOk_flag):
835 if not(fileOk_flag):
836 # busco en los siguientes self.nFiles+1 files posibles
836 # busco en los siguientes self.nFiles+1 files posibles
837 for nFiles in range(self.nFiles + 1):
837 for nFiles in range(self.nFiles + 1):
838
838
839 if firstTime_flag: # si es la 1era vez entonces hace el for self.nTries veces
839 if firstTime_flag: # si es la 1era vez entonces hace el for self.nTries veces
840 tries = self.nTries
840 tries = self.nTries
841 else:
841 else:
842 tries = 1 # si no es la 1era vez entonces solo lo hace una vez
842 tries = 1 # si no es la 1era vez entonces solo lo hace una vez
843
843
844 for nTries in range(tries):
844 for nTries in range(tries):
845 if firstTime_flag:
845 if firstTime_flag:
846 print("\t[Reading] Waiting %0.2f sec for the next file: \"%s\" , try %03d ..." % (self.delay, filename, nTries + 1))
846 print("\t[Reading] Waiting %0.2f sec for the next file: \"%s\" , try %03d ..." % (self.delay, filename, nTries + 1))
847 sleep(self.delay)
847 sleep(self.delay)
848 else:
848 else:
849 print("\t[Reading] Searching the next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext))
849 print("\t[Reading] Searching the next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext))
850
850
851 fullfilename, filename = checkForRealPath(
851 fullfilename, filename = checkForRealPath(
852 self.path, self.foldercounter, self.year, self.doy, self.set, self.ext)
852 self.path, self.foldercounter, self.year, self.doy, self.set, self.ext)
853 if fullfilename:
853 if fullfilename:
854 if self.__verifyFile(fullfilename):
854 if self.__verifyFile(fullfilename):
855 fileOk_flag = True
855 fileOk_flag = True
856 break
856 break
857
857
858 if fileOk_flag:
858 if fileOk_flag:
859 break
859 break
860
860
861 firstTime_flag = False
861 firstTime_flag = False
862
862
863 log.warning('Skipping the file {} due to this file doesn\'t exist'.format(filename))
863 log.warning('Skipping the file {} due to this file doesn\'t exist'.format(filename))
864 self.set += 1
864 self.set += 1
865
865
866 # si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
866 # si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
867 if nFiles == (self.nFiles - 1):
867 if nFiles == (self.nFiles - 1):
868 self.set = 0
868 self.set = 0
869 self.doy += 1
869 self.doy += 1
870 self.foldercounter = 0
870 self.foldercounter = 0
871
871
872 if fileOk_flag:
872 if fileOk_flag:
873 self.fileSize = os.path.getsize(fullfilename)
873 self.fileSize = os.path.getsize(fullfilename)
874 self.filename = fullfilename
874 self.filename = fullfilename
875 self.flagIsNewFile = 1
875 self.flagIsNewFile = 1
876 if self.fp != None:
876 if self.fp != None:
877 self.fp.close()
877 self.fp.close()
878 self.fp = open(fullfilename, 'rb')
878 self.fp = open(fullfilename, 'rb')
879 self.flagNoMoreFiles = 0
879 self.flagNoMoreFiles = 0
880 # print '[Reading] Setting the file: %s' % fullfilename
880 # print '[Reading] Setting the file: %s' % fullfilename
881 else:
881 else:
882 self.fileSize = 0
882 self.fileSize = 0
883 self.filename = None
883 self.filename = None
884 self.flagIsNewFile = 0
884 self.flagIsNewFile = 0
885 self.fp = None
885 self.fp = None
886 self.flagNoMoreFiles = 1
886 self.flagNoMoreFiles = 1
887 # print '[Reading] No more files to read'
887 # print '[Reading] No more files to read'
888
888
889 return fileOk_flag
889 return fileOk_flag
890
890
891 def setNextFile(self):
891 def setNextFile(self):
892 if self.fp != None:
892 if self.fp != None:
893 self.fp.close()
893 self.fp.close()
894
894
895 if self.online:
895 if self.online:
896 newFile = self.__setNextFileOnline()
896 newFile = self.__setNextFileOnline()
897 else:
897 else:
898 newFile = self.__setNextFileOffline()
898 newFile = self.__setNextFileOffline()
899
899
900 if not(newFile):
900 if not(newFile):
901 self.dataOut.error = (-1, 'No more files to read')
901 self.dataOut.error = 'No more files to read'
902 return 0
902 return 0
903
903
904 if self.verbose:
904 if self.verbose:
905 print('[Reading] Setting the file: %s' % self.filename)
905 print('[Reading] Setting the file: %s' % self.filename)
906
906
907 self.__readFirstHeader()
907 self.__readFirstHeader()
908 self.nReadBlocks = 0
908 self.nReadBlocks = 0
909 return 1
909 return 1
910
910
911 def __waitNewBlock(self):
911 def __waitNewBlock(self):
912 """
912 """
913 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
913 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
914
914
915 Si el modo de lectura es OffLine siempre retorn 0
915 Si el modo de lectura es OffLine siempre retorn 0
916 """
916 """
917 if not self.online:
917 if not self.online:
918 return 0
918 return 0
919
919
920 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
920 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
921 return 0
921 return 0
922
922
923 currentPointer = self.fp.tell()
923 currentPointer = self.fp.tell()
924
924
925 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
925 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
926
926
927 for nTries in range(self.nTries):
927 for nTries in range(self.nTries):
928
928
929 self.fp.close()
929 self.fp.close()
930 self.fp = open(self.filename, 'rb')
930 self.fp = open(self.filename, 'rb')
931 self.fp.seek(currentPointer)
931 self.fp.seek(currentPointer)
932
932
933 self.fileSize = os.path.getsize(self.filename)
933 self.fileSize = os.path.getsize(self.filename)
934 currentSize = self.fileSize - currentPointer
934 currentSize = self.fileSize - currentPointer
935
935
936 if (currentSize >= neededSize):
936 if (currentSize >= neededSize):
937 self.basicHeaderObj.read(self.fp)
937 self.basicHeaderObj.read(self.fp)
938 return 1
938 return 1
939
939
940 if self.fileSize == self.fileSizeByHeader:
940 if self.fileSize == self.fileSizeByHeader:
941 # self.flagEoF = True
941 # self.flagEoF = True
942 return 0
942 return 0
943
943
944 print("[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1))
944 print("[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1))
945 sleep(self.delay)
945 sleep(self.delay)
946
946
947 return 0
947 return 0
948
948
949 def waitDataBlock(self, pointer_location):
949 def waitDataBlock(self, pointer_location):
950
950
951 currentPointer = pointer_location
951 currentPointer = pointer_location
952
952
953 neededSize = self.processingHeaderObj.blockSize # + self.basicHeaderSize
953 neededSize = self.processingHeaderObj.blockSize # + self.basicHeaderSize
954
954
955 for nTries in range(self.nTries):
955 for nTries in range(self.nTries):
956 self.fp.close()
956 self.fp.close()
957 self.fp = open(self.filename, 'rb')
957 self.fp = open(self.filename, 'rb')
958 self.fp.seek(currentPointer)
958 self.fp.seek(currentPointer)
959
959
960 self.fileSize = os.path.getsize(self.filename)
960 self.fileSize = os.path.getsize(self.filename)
961 currentSize = self.fileSize - currentPointer
961 currentSize = self.fileSize - currentPointer
962
962
963 if (currentSize >= neededSize):
963 if (currentSize >= neededSize):
964 return 1
964 return 1
965
965
966 print("[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1))
966 print("[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1))
967 sleep(self.delay)
967 sleep(self.delay)
968
968
969 return 0
969 return 0
970
970
971 def __jumpToLastBlock(self):
971 def __jumpToLastBlock(self):
972
972
973 if not(self.__isFirstTimeOnline):
973 if not(self.__isFirstTimeOnline):
974 return
974 return
975
975
976 csize = self.fileSize - self.fp.tell()
976 csize = self.fileSize - self.fp.tell()
977 blocksize = self.processingHeaderObj.blockSize
977 blocksize = self.processingHeaderObj.blockSize
978
978
979 # salta el primer bloque de datos
979 # salta el primer bloque de datos
980 if csize > self.processingHeaderObj.blockSize:
980 if csize > self.processingHeaderObj.blockSize:
981 self.fp.seek(self.fp.tell() + blocksize)
981 self.fp.seek(self.fp.tell() + blocksize)
982 else:
982 else:
983 return
983 return
984
984
985 csize = self.fileSize - self.fp.tell()
985 csize = self.fileSize - self.fp.tell()
986 neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
986 neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
987 while True:
987 while True:
988
988
989 if self.fp.tell() < self.fileSize:
989 if self.fp.tell() < self.fileSize:
990 self.fp.seek(self.fp.tell() + neededsize)
990 self.fp.seek(self.fp.tell() + neededsize)
991 else:
991 else:
992 self.fp.seek(self.fp.tell() - neededsize)
992 self.fp.seek(self.fp.tell() - neededsize)
993 break
993 break
994
994
995 # csize = self.fileSize - self.fp.tell()
995 # csize = self.fileSize - self.fp.tell()
996 # neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
996 # neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
997 # factor = int(csize/neededsize)
997 # factor = int(csize/neededsize)
998 # if factor > 0:
998 # if factor > 0:
999 # self.fp.seek(self.fp.tell() + factor*neededsize)
999 # self.fp.seek(self.fp.tell() + factor*neededsize)
1000
1000
1001 self.flagIsNewFile = 0
1001 self.flagIsNewFile = 0
1002 self.__isFirstTimeOnline = 0
1002 self.__isFirstTimeOnline = 0
1003
1003
1004 def __setNewBlock(self):
1004 def __setNewBlock(self):
1005 # if self.server is None:
1005 # if self.server is None:
1006 if self.fp == None:
1006 if self.fp == None:
1007 return 0
1007 return 0
1008
1008
1009 # if self.online:
1009 # if self.online:
1010 # self.__jumpToLastBlock()
1010 # self.__jumpToLastBlock()
1011
1011
1012 if self.flagIsNewFile:
1012 if self.flagIsNewFile:
1013 self.lastUTTime = self.basicHeaderObj.utc
1013 self.lastUTTime = self.basicHeaderObj.utc
1014 return 1
1014 return 1
1015
1015
1016 if self.realtime:
1016 if self.realtime:
1017 self.flagDiscontinuousBlock = 1
1017 self.flagDiscontinuousBlock = 1
1018 if not(self.setNextFile()):
1018 if not(self.setNextFile()):
1019 return 0
1019 return 0
1020 else:
1020 else:
1021 return 1
1021 return 1
1022 # if self.server is None:
1022 # if self.server is None:
1023 currentSize = self.fileSize - self.fp.tell()
1023 currentSize = self.fileSize - self.fp.tell()
1024 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
1024 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
1025 if (currentSize >= neededSize):
1025 if (currentSize >= neededSize):
1026 self.basicHeaderObj.read(self.fp)
1026 self.basicHeaderObj.read(self.fp)
1027 self.lastUTTime = self.basicHeaderObj.utc
1027 self.lastUTTime = self.basicHeaderObj.utc
1028 return 1
1028 return 1
1029 # else:
1029 # else:
1030 # self.basicHeaderObj.read(self.zHeader)
1030 # self.basicHeaderObj.read(self.zHeader)
1031 # self.lastUTTime = self.basicHeaderObj.utc
1031 # self.lastUTTime = self.basicHeaderObj.utc
1032 # return 1
1032 # return 1
1033 if self.__waitNewBlock():
1033 if self.__waitNewBlock():
1034 self.lastUTTime = self.basicHeaderObj.utc
1034 self.lastUTTime = self.basicHeaderObj.utc
1035 return 1
1035 return 1
1036 # if self.server is None:
1036 # if self.server is None:
1037 if not(self.setNextFile()):
1037 if not(self.setNextFile()):
1038 return 0
1038 return 0
1039
1039
1040 deltaTime = self.basicHeaderObj.utc - self.lastUTTime
1040 deltaTime = self.basicHeaderObj.utc - self.lastUTTime
1041 self.lastUTTime = self.basicHeaderObj.utc
1041 self.lastUTTime = self.basicHeaderObj.utc
1042
1042
1043 self.flagDiscontinuousBlock = 0
1043 self.flagDiscontinuousBlock = 0
1044
1044
1045 if deltaTime > self.maxTimeStep:
1045 if deltaTime > self.maxTimeStep:
1046 self.flagDiscontinuousBlock = 1
1046 self.flagDiscontinuousBlock = 1
1047
1047
1048 return 1
1048 return 1
1049
1049
1050 def readNextBlock(self):
1050 def readNextBlock(self):
1051
1051
1052 # Skip block out of startTime and endTime
1052 # Skip block out of startTime and endTime
1053 while True:
1053 while True:
1054 if not(self.__setNewBlock()):
1054 if not(self.__setNewBlock()):
1055 self.dataOut.error = (-1, 'No more files to read')
1055 self.dataOut.error = 'No more files to read'
1056 return 0
1056 return 0
1057
1057
1058 if not(self.readBlock()):
1058 if not(self.readBlock()):
1059 return 0
1059 return 0
1060
1060
1061 self.getBasicHeader()
1061 self.getBasicHeader()
1062 if (self.dataOut.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or (self.dataOut.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
1062 if (self.dataOut.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or (self.dataOut.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
1063 print("[Reading] Block No. %d/%d -> %s [Skipping]" % (self.nReadBlocks,
1063 print("[Reading] Block No. %d/%d -> %s [Skipping]" % (self.nReadBlocks,
1064 self.processingHeaderObj.dataBlocksPerFile,
1064 self.processingHeaderObj.dataBlocksPerFile,
1065 self.dataOut.datatime.ctime()))
1065 self.dataOut.datatime.ctime()))
1066 continue
1066 continue
1067
1067
1068 break
1068 break
1069
1069
1070 if self.verbose:
1070 if self.verbose:
1071 print("[Reading] Block No. %d/%d -> %s" % (self.nReadBlocks,
1071 print("[Reading] Block No. %d/%d -> %s" % (self.nReadBlocks,
1072 self.processingHeaderObj.dataBlocksPerFile,
1072 self.processingHeaderObj.dataBlocksPerFile,
1073 self.dataOut.datatime.ctime()))
1073 self.dataOut.datatime.ctime()))
1074 return 1
1074 return 1
1075
1075
1076 def __readFirstHeader(self):
1076 def __readFirstHeader(self):
1077
1077
1078 self.basicHeaderObj.read(self.fp)
1078 self.basicHeaderObj.read(self.fp)
1079 self.systemHeaderObj.read(self.fp)
1079 self.systemHeaderObj.read(self.fp)
1080 self.radarControllerHeaderObj.read(self.fp)
1080 self.radarControllerHeaderObj.read(self.fp)
1081 self.processingHeaderObj.read(self.fp)
1081 self.processingHeaderObj.read(self.fp)
1082
1082
1083 self.firstHeaderSize = self.basicHeaderObj.size
1083 self.firstHeaderSize = self.basicHeaderObj.size
1084
1084
1085 datatype = int(numpy.log2((self.processingHeaderObj.processFlags &
1085 datatype = int(numpy.log2((self.processingHeaderObj.processFlags &
1086 PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR))
1086 PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR))
1087 if datatype == 0:
1087 if datatype == 0:
1088 datatype_str = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
1088 datatype_str = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
1089 elif datatype == 1:
1089 elif datatype == 1:
1090 datatype_str = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
1090 datatype_str = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
1091 elif datatype == 2:
1091 elif datatype == 2:
1092 datatype_str = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
1092 datatype_str = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
1093 elif datatype == 3:
1093 elif datatype == 3:
1094 datatype_str = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
1094 datatype_str = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
1095 elif datatype == 4:
1095 elif datatype == 4:
1096 datatype_str = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
1096 datatype_str = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
1097 elif datatype == 5:
1097 elif datatype == 5:
1098 datatype_str = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
1098 datatype_str = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
1099 else:
1099 else:
1100 raise ValueError('Data type was not defined')
1100 raise ValueError('Data type was not defined')
1101
1101
1102 self.dtype = datatype_str
1102 self.dtype = datatype_str
1103 #self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
1103 #self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
1104 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + \
1104 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + \
1105 self.firstHeaderSize + self.basicHeaderSize * \
1105 self.firstHeaderSize + self.basicHeaderSize * \
1106 (self.processingHeaderObj.dataBlocksPerFile - 1)
1106 (self.processingHeaderObj.dataBlocksPerFile - 1)
1107 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
1107 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
1108 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
1108 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
1109 self.getBlockDimension()
1109 self.getBlockDimension()
1110
1110
1111 def __verifyFile(self, filename, msgFlag=True):
1111 def __verifyFile(self, filename, msgFlag=True):
1112
1112
1113 msg = None
1113 msg = None
1114
1114
1115 try:
1115 try:
1116 fp = open(filename, 'rb')
1116 fp = open(filename, 'rb')
1117 except IOError:
1117 except IOError:
1118
1118
1119 if msgFlag:
1119 if msgFlag:
1120 print("[Reading] File %s can't be opened" % (filename))
1120 print("[Reading] File %s can't be opened" % (filename))
1121
1121
1122 return False
1122 return False
1123
1123
1124 currentPosition = fp.tell()
1124 currentPosition = fp.tell()
1125 neededSize = self.processingHeaderObj.blockSize + self.firstHeaderSize
1125 neededSize = self.processingHeaderObj.blockSize + self.firstHeaderSize
1126
1126
1127 if neededSize == 0:
1127 if neededSize == 0:
1128 basicHeaderObj = BasicHeader(LOCALTIME)
1128 basicHeaderObj = BasicHeader(LOCALTIME)
1129 systemHeaderObj = SystemHeader()
1129 systemHeaderObj = SystemHeader()
1130 radarControllerHeaderObj = RadarControllerHeader()
1130 radarControllerHeaderObj = RadarControllerHeader()
1131 processingHeaderObj = ProcessingHeader()
1131 processingHeaderObj = ProcessingHeader()
1132
1132
1133 if not(basicHeaderObj.read(fp)):
1133 if not(basicHeaderObj.read(fp)):
1134 fp.close()
1134 fp.close()
1135 return False
1135 return False
1136
1136
1137 if not(systemHeaderObj.read(fp)):
1137 if not(systemHeaderObj.read(fp)):
1138 fp.close()
1138 fp.close()
1139 return False
1139 return False
1140
1140
1141 if not(radarControllerHeaderObj.read(fp)):
1141 if not(radarControllerHeaderObj.read(fp)):
1142 fp.close()
1142 fp.close()
1143 return False
1143 return False
1144
1144
1145 if not(processingHeaderObj.read(fp)):
1145 if not(processingHeaderObj.read(fp)):
1146 fp.close()
1146 fp.close()
1147 return False
1147 return False
1148
1148
1149 neededSize = processingHeaderObj.blockSize + basicHeaderObj.size
1149 neededSize = processingHeaderObj.blockSize + basicHeaderObj.size
1150 else:
1150 else:
1151 msg = "[Reading] Skipping the file %s due to it hasn't enough data" % filename
1151 msg = "[Reading] Skipping the file %s due to it hasn't enough data" % filename
1152
1152
1153 fp.close()
1153 fp.close()
1154
1154
1155 fileSize = os.path.getsize(filename)
1155 fileSize = os.path.getsize(filename)
1156 currentSize = fileSize - currentPosition
1156 currentSize = fileSize - currentPosition
1157
1157
1158 if currentSize < neededSize:
1158 if currentSize < neededSize:
1159 if msgFlag and (msg != None):
1159 if msgFlag and (msg != None):
1160 print(msg)
1160 print(msg)
1161 return False
1161 return False
1162
1162
1163 return True
1163 return True
1164
1164
1165 def findDatafiles(self, path, startDate=None, endDate=None, expLabel='', ext='.r', walk=True, include_path=False):
1165 def findDatafiles(self, path, startDate=None, endDate=None, expLabel='', ext='.r', walk=True, include_path=False):
1166
1166
1167 path_empty = True
1167 path_empty = True
1168
1168
1169 dateList = []
1169 dateList = []
1170 pathList = []
1170 pathList = []
1171
1171
1172 multi_path = path.split(',')
1172 multi_path = path.split(',')
1173
1173
1174 if not walk:
1174 if not walk:
1175
1175
1176 for single_path in multi_path:
1176 for single_path in multi_path:
1177
1177
1178 if not os.path.isdir(single_path):
1178 if not os.path.isdir(single_path):
1179 continue
1179 continue
1180
1180
1181 fileList = glob.glob1(single_path, "*" + ext)
1181 fileList = glob.glob1(single_path, "*" + ext)
1182
1182
1183 if not fileList:
1183 if not fileList:
1184 continue
1184 continue
1185
1185
1186 path_empty = False
1186 path_empty = False
1187
1187
1188 fileList.sort()
1188 fileList.sort()
1189
1189
1190 for thisFile in fileList:
1190 for thisFile in fileList:
1191
1191
1192 if not os.path.isfile(os.path.join(single_path, thisFile)):
1192 if not os.path.isfile(os.path.join(single_path, thisFile)):
1193 continue
1193 continue
1194
1194
1195 if not isRadarFile(thisFile):
1195 if not isRadarFile(thisFile):
1196 continue
1196 continue
1197
1197
1198 if not isFileInDateRange(thisFile, startDate, endDate):
1198 if not isFileInDateRange(thisFile, startDate, endDate):
1199 continue
1199 continue
1200
1200
1201 thisDate = getDateFromRadarFile(thisFile)
1201 thisDate = getDateFromRadarFile(thisFile)
1202
1202
1203 if thisDate in dateList:
1203 if thisDate in dateList:
1204 continue
1204 continue
1205
1205
1206 dateList.append(thisDate)
1206 dateList.append(thisDate)
1207 pathList.append(single_path)
1207 pathList.append(single_path)
1208
1208
1209 else:
1209 else:
1210 for single_path in multi_path:
1210 for single_path in multi_path:
1211
1211
1212 if not os.path.isdir(single_path):
1212 if not os.path.isdir(single_path):
1213 continue
1213 continue
1214
1214
1215 dirList = []
1215 dirList = []
1216
1216
1217 for thisPath in os.listdir(single_path):
1217 for thisPath in os.listdir(single_path):
1218
1218
1219 if not os.path.isdir(os.path.join(single_path, thisPath)):
1219 if not os.path.isdir(os.path.join(single_path, thisPath)):
1220 continue
1220 continue
1221
1221
1222 if not isRadarFolder(thisPath):
1222 if not isRadarFolder(thisPath):
1223 continue
1223 continue
1224
1224
1225 if not isFolderInDateRange(thisPath, startDate, endDate):
1225 if not isFolderInDateRange(thisPath, startDate, endDate):
1226 continue
1226 continue
1227
1227
1228 dirList.append(thisPath)
1228 dirList.append(thisPath)
1229
1229
1230 if not dirList:
1230 if not dirList:
1231 continue
1231 continue
1232
1232
1233 dirList.sort()
1233 dirList.sort()
1234
1234
1235 for thisDir in dirList:
1235 for thisDir in dirList:
1236
1236
1237 datapath = os.path.join(single_path, thisDir, expLabel)
1237 datapath = os.path.join(single_path, thisDir, expLabel)
1238 fileList = glob.glob1(datapath, "*" + ext)
1238 fileList = glob.glob1(datapath, "*" + ext)
1239
1239
1240 if not fileList:
1240 if not fileList:
1241 continue
1241 continue
1242
1242
1243 path_empty = False
1243 path_empty = False
1244
1244
1245 thisDate = getDateFromRadarFolder(thisDir)
1245 thisDate = getDateFromRadarFolder(thisDir)
1246
1246
1247 pathList.append(datapath)
1247 pathList.append(datapath)
1248 dateList.append(thisDate)
1248 dateList.append(thisDate)
1249
1249
1250 dateList.sort()
1250 dateList.sort()
1251
1251
1252 if walk:
1252 if walk:
1253 pattern_path = os.path.join(multi_path[0], "[dYYYYDDD]", expLabel)
1253 pattern_path = os.path.join(multi_path[0], "[dYYYYDDD]", expLabel)
1254 else:
1254 else:
1255 pattern_path = multi_path[0]
1255 pattern_path = multi_path[0]
1256
1256
1257 if path_empty:
1257 if path_empty:
1258 print("[Reading] No *%s files in %s for %s to %s" % (ext, pattern_path, startDate, endDate))
1258 print("[Reading] No *%s files in %s for %s to %s" % (ext, pattern_path, startDate, endDate))
1259 else:
1259 else:
1260 if not dateList:
1260 if not dateList:
1261 print("[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" % (startDate, endDate, ext, path))
1261 print("[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" % (startDate, endDate, ext, path))
1262
1262
1263 if include_path:
1263 if include_path:
1264 return dateList, pathList
1264 return dateList, pathList
1265
1265
1266 return dateList
1266 return dateList
1267
1267
1268 def setup(self,
1268 def setup(self,
1269 path=None,
1269 path=None,
1270 startDate=None,
1270 startDate=None,
1271 endDate=None,
1271 endDate=None,
1272 startTime=datetime.time(0, 0, 0),
1272 startTime=datetime.time(0, 0, 0),
1273 endTime=datetime.time(23, 59, 59),
1273 endTime=datetime.time(23, 59, 59),
1274 set=None,
1274 set=None,
1275 expLabel="",
1275 expLabel="",
1276 ext=None,
1276 ext=None,
1277 online=False,
1277 online=False,
1278 delay=60,
1278 delay=60,
1279 walk=True,
1279 walk=True,
1280 getblock=False,
1280 getblock=False,
1281 nTxs=1,
1281 nTxs=1,
1282 realtime=False,
1282 realtime=False,
1283 blocksize=None,
1283 blocksize=None,
1284 blocktime=None,
1284 blocktime=None,
1285 skip=None,
1285 skip=None,
1286 cursor=None,
1286 cursor=None,
1287 warnings=True,
1287 warnings=True,
1288 verbose=True,
1288 verbose=True,
1289 server=None,
1289 server=None,
1290 format=None,
1290 format=None,
1291 oneDDict=None,
1291 oneDDict=None,
1292 twoDDict=None,
1292 twoDDict=None,
1293 ind2DList=None):
1293 ind2DList=None):
1294 if server is not None:
1294 if server is not None:
1295 if 'tcp://' in server:
1295 if 'tcp://' in server:
1296 address = server
1296 address = server
1297 else:
1297 else:
1298 address = 'ipc:///tmp/%s' % server
1298 address = 'ipc:///tmp/%s' % server
1299 self.server = address
1299 self.server = address
1300 self.context = zmq.Context()
1300 self.context = zmq.Context()
1301 self.receiver = self.context.socket(zmq.PULL)
1301 self.receiver = self.context.socket(zmq.PULL)
1302 self.receiver.connect(self.server)
1302 self.receiver.connect(self.server)
1303 time.sleep(0.5)
1303 time.sleep(0.5)
1304 print('[Starting] ReceiverData from {}'.format(self.server))
1304 print('[Starting] ReceiverData from {}'.format(self.server))
1305 else:
1305 else:
1306 self.server = None
1306 self.server = None
1307 if path == None:
1307 if path == None:
1308 raise ValueError("[Reading] The path is not valid")
1308 raise ValueError("[Reading] The path is not valid")
1309
1309
1310 if ext == None:
1310 if ext == None:
1311 ext = self.ext
1311 ext = self.ext
1312
1312
1313 if online:
1313 if online:
1314 print("[Reading] Searching files in online mode...")
1314 print("[Reading] Searching files in online mode...")
1315
1315
1316 for nTries in range(self.nTries):
1316 for nTries in range(self.nTries):
1317 fullpath, foldercounter, file, year, doy, set = self.__searchFilesOnLine(
1317 fullpath, foldercounter, file, year, doy, set = self.__searchFilesOnLine(
1318 path=path, expLabel=expLabel, ext=ext, walk=walk, set=set)
1318 path=path, expLabel=expLabel, ext=ext, walk=walk, set=set)
1319
1319
1320 if fullpath:
1320 if fullpath:
1321 break
1321 break
1322
1322
1323 print('[Reading] Waiting %0.2f sec for an valid file in %s: try %02d ...' % (self.delay, path, nTries + 1))
1323 print('[Reading] Waiting %0.2f sec for an valid file in %s: try %02d ...' % (self.delay, path, nTries + 1))
1324 sleep(self.delay)
1324 sleep(self.delay)
1325
1325
1326 if not(fullpath):
1326 if not(fullpath):
1327 self.dataOut.error = (-1, 'There isn\'t any valid file in {}'.format(path))
1327 self.dataOut.error = 'There isn\'t any valid file in {}'.format(path)
1328 return
1328 return
1329
1329
1330 self.year = year
1330 self.year = year
1331 self.doy = doy
1331 self.doy = doy
1332 self.set = set - 1
1332 self.set = set - 1
1333 self.path = path
1333 self.path = path
1334 self.foldercounter = foldercounter
1334 self.foldercounter = foldercounter
1335 last_set = None
1335 last_set = None
1336 else:
1336 else:
1337 print("[Reading] Searching files in offline mode ...")
1337 print("[Reading] Searching files in offline mode ...")
1338 pathList, filenameList = self.searchFilesOffLine(path, startDate=startDate, endDate=endDate,
1338 pathList, filenameList = self.searchFilesOffLine(path, startDate=startDate, endDate=endDate,
1339 startTime=startTime, endTime=endTime,
1339 startTime=startTime, endTime=endTime,
1340 set=set, expLabel=expLabel, ext=ext,
1340 set=set, expLabel=expLabel, ext=ext,
1341 walk=walk, cursor=cursor,
1341 walk=walk, cursor=cursor,
1342 skip=skip)
1342 skip=skip)
1343
1343
1344 if not(pathList):
1344 if not(pathList):
1345 self.fileIndex = -1
1345 self.fileIndex = -1
1346 self.pathList = []
1346 self.pathList = []
1347 self.filenameList = []
1347 self.filenameList = []
1348 return
1348 return
1349
1349
1350 self.fileIndex = -1
1350 self.fileIndex = -1
1351 self.pathList = pathList
1351 self.pathList = pathList
1352 self.filenameList = filenameList
1352 self.filenameList = filenameList
1353 file_name = os.path.basename(filenameList[-1])
1353 file_name = os.path.basename(filenameList[-1])
1354 basename, ext = os.path.splitext(file_name)
1354 basename, ext = os.path.splitext(file_name)
1355 last_set = int(basename[-3:])
1355 last_set = int(basename[-3:])
1356
1356
1357 self.online = online
1357 self.online = online
1358 self.realtime = realtime
1358 self.realtime = realtime
1359 self.delay = delay
1359 self.delay = delay
1360 ext = ext.lower()
1360 ext = ext.lower()
1361 self.ext = ext
1361 self.ext = ext
1362 self.getByBlock = getblock
1362 self.getByBlock = getblock
1363 self.nTxs = nTxs
1363 self.nTxs = nTxs
1364 self.startTime = startTime
1364 self.startTime = startTime
1365 self.endTime = endTime
1365 self.endTime = endTime
1366 self.endDate = endDate
1366 self.endDate = endDate
1367 self.startDate = startDate
1367 self.startDate = startDate
1368 # Added-----------------
1368 # Added-----------------
1369 self.selBlocksize = blocksize
1369 self.selBlocksize = blocksize
1370 self.selBlocktime = blocktime
1370 self.selBlocktime = blocktime
1371
1371
1372 # Verbose-----------
1372 # Verbose-----------
1373 self.verbose = verbose
1373 self.verbose = verbose
1374 self.warnings = warnings
1374 self.warnings = warnings
1375
1375
1376 if not(self.setNextFile()):
1376 if not(self.setNextFile()):
1377 if (startDate != None) and (endDate != None):
1377 if (startDate != None) and (endDate != None):
1378 print("[Reading] No files in range: %s - %s" % (datetime.datetime.combine(startDate, startTime).ctime(), datetime.datetime.combine(endDate, endTime).ctime()))
1378 print("[Reading] No files in range: %s - %s" % (datetime.datetime.combine(startDate, startTime).ctime(), datetime.datetime.combine(endDate, endTime).ctime()))
1379 elif startDate != None:
1379 elif startDate != None:
1380 print("[Reading] No files in range: %s" % (datetime.datetime.combine(startDate, startTime).ctime()))
1380 print("[Reading] No files in range: %s" % (datetime.datetime.combine(startDate, startTime).ctime()))
1381 else:
1381 else:
1382 print("[Reading] No files")
1382 print("[Reading] No files")
1383
1383
1384 self.fileIndex = -1
1384 self.fileIndex = -1
1385 self.pathList = []
1385 self.pathList = []
1386 self.filenameList = []
1386 self.filenameList = []
1387 return
1387 return
1388
1388
1389 # self.getBasicHeader()
1389 # self.getBasicHeader()
1390
1390
1391 if last_set != None:
1391 if last_set != None:
1392 self.dataOut.last_block = last_set * \
1392 self.dataOut.last_block = last_set * \
1393 self.processingHeaderObj.dataBlocksPerFile + self.basicHeaderObj.dataBlock
1393 self.processingHeaderObj.dataBlocksPerFile + self.basicHeaderObj.dataBlock
1394 return
1394 return
1395
1395
1396 def getBasicHeader(self):
1396 def getBasicHeader(self):
1397
1397
1398 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond / \
1398 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond / \
1399 1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds
1399 1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds
1400
1400
1401 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
1401 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
1402
1402
1403 self.dataOut.timeZone = self.basicHeaderObj.timeZone
1403 self.dataOut.timeZone = self.basicHeaderObj.timeZone
1404
1404
1405 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
1405 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
1406
1406
1407 self.dataOut.errorCount = self.basicHeaderObj.errorCount
1407 self.dataOut.errorCount = self.basicHeaderObj.errorCount
1408
1408
1409 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
1409 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
1410
1410
1411 self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
1411 self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
1412
1412
1413 # self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock*self.nTxs
1413 # self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock*self.nTxs
1414
1414
1415 def getFirstHeader(self):
1415 def getFirstHeader(self):
1416
1416
1417 raise NotImplementedError
1417 raise NotImplementedError
1418
1418
1419 def getData(self):
1419 def getData(self):
1420
1420
1421 raise NotImplementedError
1421 raise NotImplementedError
1422
1422
1423 def hasNotDataInBuffer(self):
1423 def hasNotDataInBuffer(self):
1424
1424
1425 raise NotImplementedError
1425 raise NotImplementedError
1426
1426
1427 def readBlock(self):
1427 def readBlock(self):
1428
1428
1429 raise NotImplementedError
1429 raise NotImplementedError
1430
1430
1431 def isEndProcess(self):
1431 def isEndProcess(self):
1432
1432
1433 return self.flagNoMoreFiles
1433 return self.flagNoMoreFiles
1434
1434
1435 def printReadBlocks(self):
1435 def printReadBlocks(self):
1436
1436
1437 print("[Reading] Number of read blocks per file %04d" % self.nReadBlocks)
1437 print("[Reading] Number of read blocks per file %04d" % self.nReadBlocks)
1438
1438
1439 def printTotalBlocks(self):
1439 def printTotalBlocks(self):
1440
1440
1441 print("[Reading] Number of read blocks %04d" % self.nTotalBlocks)
1441 print("[Reading] Number of read blocks %04d" % self.nTotalBlocks)
1442
1442
1443 def printNumberOfBlock(self):
1443 def printNumberOfBlock(self):
1444 'SPAM!'
1444 'SPAM!'
1445
1445
1446 # if self.flagIsNewBlock:
1446 # if self.flagIsNewBlock:
1447 # print "[Reading] Block No. %d/%d -> %s" %(self.nReadBlocks,
1447 # print "[Reading] Block No. %d/%d -> %s" %(self.nReadBlocks,
1448 # self.processingHeaderObj.dataBlocksPerFile,
1448 # self.processingHeaderObj.dataBlocksPerFile,
1449 # self.dataOut.datatime.ctime())
1449 # self.dataOut.datatime.ctime())
1450
1450
1451 def printInfo(self):
1451 def printInfo(self):
1452
1452
1453 if self.__printInfo == False:
1453 if self.__printInfo == False:
1454 return
1454 return
1455
1455
1456 self.basicHeaderObj.printInfo()
1456 self.basicHeaderObj.printInfo()
1457 self.systemHeaderObj.printInfo()
1457 self.systemHeaderObj.printInfo()
1458 self.radarControllerHeaderObj.printInfo()
1458 self.radarControllerHeaderObj.printInfo()
1459 self.processingHeaderObj.printInfo()
1459 self.processingHeaderObj.printInfo()
1460
1460
1461 self.__printInfo = False
1461 self.__printInfo = False
1462
1462
1463 def run(self,
1463 def run(self,
1464 path=None,
1464 path=None,
1465 startDate=None,
1465 startDate=None,
1466 endDate=None,
1466 endDate=None,
1467 startTime=datetime.time(0, 0, 0),
1467 startTime=datetime.time(0, 0, 0),
1468 endTime=datetime.time(23, 59, 59),
1468 endTime=datetime.time(23, 59, 59),
1469 set=None,
1469 set=None,
1470 expLabel="",
1470 expLabel="",
1471 ext=None,
1471 ext=None,
1472 online=False,
1472 online=False,
1473 delay=60,
1473 delay=60,
1474 walk=True,
1474 walk=True,
1475 getblock=False,
1475 getblock=False,
1476 nTxs=1,
1476 nTxs=1,
1477 realtime=False,
1477 realtime=False,
1478 blocksize=None,
1478 blocksize=None,
1479 blocktime=None,
1479 blocktime=None,
1480 skip=None,
1480 skip=None,
1481 cursor=None,
1481 cursor=None,
1482 warnings=True,
1482 warnings=True,
1483 server=None,
1483 server=None,
1484 verbose=True,
1484 verbose=True,
1485 format=None,
1485 format=None,
1486 oneDDict=None,
1486 oneDDict=None,
1487 twoDDict=None,
1487 twoDDict=None,
1488 ind2DList=None, **kwargs):
1488 ind2DList=None, **kwargs):
1489
1489
1490 if not(self.isConfig):
1490 if not(self.isConfig):
1491 self.setup(path=path,
1491 self.setup(path=path,
1492 startDate=startDate,
1492 startDate=startDate,
1493 endDate=endDate,
1493 endDate=endDate,
1494 startTime=startTime,
1494 startTime=startTime,
1495 endTime=endTime,
1495 endTime=endTime,
1496 set=set,
1496 set=set,
1497 expLabel=expLabel,
1497 expLabel=expLabel,
1498 ext=ext,
1498 ext=ext,
1499 online=online,
1499 online=online,
1500 delay=delay,
1500 delay=delay,
1501 walk=walk,
1501 walk=walk,
1502 getblock=getblock,
1502 getblock=getblock,
1503 nTxs=nTxs,
1503 nTxs=nTxs,
1504 realtime=realtime,
1504 realtime=realtime,
1505 blocksize=blocksize,
1505 blocksize=blocksize,
1506 blocktime=blocktime,
1506 blocktime=blocktime,
1507 skip=skip,
1507 skip=skip,
1508 cursor=cursor,
1508 cursor=cursor,
1509 warnings=warnings,
1509 warnings=warnings,
1510 server=server,
1510 server=server,
1511 verbose=verbose,
1511 verbose=verbose,
1512 format=format,
1512 format=format,
1513 oneDDict=oneDDict,
1513 oneDDict=oneDDict,
1514 twoDDict=twoDDict,
1514 twoDDict=twoDDict,
1515 ind2DList=ind2DList)
1515 ind2DList=ind2DList)
1516 self.isConfig = True
1516 self.isConfig = True
1517 if server is None:
1517 if server is None:
1518 self.getData()
1518 self.getData()
1519 else:
1519 else:
1520 self.getFromServer()
1520 self.getFromServer()
1521
1521
1522
1522
1523 class JRODataWriter(JRODataIO):
1523 class JRODataWriter(JRODataIO):
1524
1524
1525 """
1525 """
1526 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1526 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1527 de los datos siempre se realiza por bloques.
1527 de los datos siempre se realiza por bloques.
1528 """
1528 """
1529
1529
1530 blockIndex = 0
1530 blockIndex = 0
1531
1531
1532 path = None
1532 path = None
1533
1533
1534 setFile = None
1534 setFile = None
1535
1535
1536 profilesPerBlock = None
1536 profilesPerBlock = None
1537
1537
1538 blocksPerFile = None
1538 blocksPerFile = None
1539
1539
1540 nWriteBlocks = 0
1540 nWriteBlocks = 0
1541
1541
1542 fileDate = None
1542 fileDate = None
1543
1543
1544 def __init__(self, dataOut=None):
1544 def __init__(self, dataOut=None):
1545 raise NotImplementedError
1545 raise NotImplementedError
1546
1546
1547 def hasAllDataInBuffer(self):
1547 def hasAllDataInBuffer(self):
1548 raise NotImplementedError
1548 raise NotImplementedError
1549
1549
1550 def setBlockDimension(self):
1550 def setBlockDimension(self):
1551 raise NotImplementedError
1551 raise NotImplementedError
1552
1552
1553 def writeBlock(self):
1553 def writeBlock(self):
1554 raise NotImplementedError
1554 raise NotImplementedError
1555
1555
1556 def putData(self):
1556 def putData(self):
1557 raise NotImplementedError
1557 raise NotImplementedError
1558
1558
1559 def getProcessFlags(self):
1559 def getProcessFlags(self):
1560
1560
1561 processFlags = 0
1561 processFlags = 0
1562
1562
1563 dtype_index = get_dtype_index(self.dtype)
1563 dtype_index = get_dtype_index(self.dtype)
1564 procflag_dtype = get_procflag_dtype(dtype_index)
1564 procflag_dtype = get_procflag_dtype(dtype_index)
1565
1565
1566 processFlags += procflag_dtype
1566 processFlags += procflag_dtype
1567
1567
1568 if self.dataOut.flagDecodeData:
1568 if self.dataOut.flagDecodeData:
1569 processFlags += PROCFLAG.DECODE_DATA
1569 processFlags += PROCFLAG.DECODE_DATA
1570
1570
1571 if self.dataOut.flagDeflipData:
1571 if self.dataOut.flagDeflipData:
1572 processFlags += PROCFLAG.DEFLIP_DATA
1572 processFlags += PROCFLAG.DEFLIP_DATA
1573
1573
1574 if self.dataOut.code is not None:
1574 if self.dataOut.code is not None:
1575 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1575 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1576
1576
1577 if self.dataOut.nCohInt > 1:
1577 if self.dataOut.nCohInt > 1:
1578 processFlags += PROCFLAG.COHERENT_INTEGRATION
1578 processFlags += PROCFLAG.COHERENT_INTEGRATION
1579
1579
1580 if self.dataOut.type == "Spectra":
1580 if self.dataOut.type == "Spectra":
1581 if self.dataOut.nIncohInt > 1:
1581 if self.dataOut.nIncohInt > 1:
1582 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
1582 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
1583
1583
1584 if self.dataOut.data_dc is not None:
1584 if self.dataOut.data_dc is not None:
1585 processFlags += PROCFLAG.SAVE_CHANNELS_DC
1585 processFlags += PROCFLAG.SAVE_CHANNELS_DC
1586
1586
1587 if self.dataOut.flagShiftFFT:
1587 if self.dataOut.flagShiftFFT:
1588 processFlags += PROCFLAG.SHIFT_FFT_DATA
1588 processFlags += PROCFLAG.SHIFT_FFT_DATA
1589
1589
1590 return processFlags
1590 return processFlags
1591
1591
1592 def setBasicHeader(self):
1592 def setBasicHeader(self):
1593
1593
1594 self.basicHeaderObj.size = self.basicHeaderSize # bytes
1594 self.basicHeaderObj.size = self.basicHeaderSize # bytes
1595 self.basicHeaderObj.version = self.versionFile
1595 self.basicHeaderObj.version = self.versionFile
1596 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1596 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1597
1597
1598 utc = numpy.floor(self.dataOut.utctime)
1598 utc = numpy.floor(self.dataOut.utctime)
1599 milisecond = (self.dataOut.utctime - utc) * 1000.0
1599 milisecond = (self.dataOut.utctime - utc) * 1000.0
1600
1600
1601 self.basicHeaderObj.utc = utc
1601 self.basicHeaderObj.utc = utc
1602 self.basicHeaderObj.miliSecond = milisecond
1602 self.basicHeaderObj.miliSecond = milisecond
1603 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1603 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1604 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1604 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1605 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1605 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1606
1606
1607 def setFirstHeader(self):
1607 def setFirstHeader(self):
1608 """
1608 """
1609 Obtiene una copia del First Header
1609 Obtiene una copia del First Header
1610
1610
1611 Affected:
1611 Affected:
1612
1612
1613 self.basicHeaderObj
1613 self.basicHeaderObj
1614 self.systemHeaderObj
1614 self.systemHeaderObj
1615 self.radarControllerHeaderObj
1615 self.radarControllerHeaderObj
1616 self.processingHeaderObj self.
1616 self.processingHeaderObj self.
1617
1617
1618 Return:
1618 Return:
1619 None
1619 None
1620 """
1620 """
1621
1621
1622 raise NotImplementedError
1622 raise NotImplementedError
1623
1623
1624 def __writeFirstHeader(self):
1624 def __writeFirstHeader(self):
1625 """
1625 """
1626 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1626 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1627
1627
1628 Affected:
1628 Affected:
1629 __dataType
1629 __dataType
1630
1630
1631 Return:
1631 Return:
1632 None
1632 None
1633 """
1633 """
1634
1634
1635 # CALCULAR PARAMETROS
1635 # CALCULAR PARAMETROS
1636
1636
1637 sizeLongHeader = self.systemHeaderObj.size + \
1637 sizeLongHeader = self.systemHeaderObj.size + \
1638 self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1638 self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1639 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1639 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1640
1640
1641 self.basicHeaderObj.write(self.fp)
1641 self.basicHeaderObj.write(self.fp)
1642 self.systemHeaderObj.write(self.fp)
1642 self.systemHeaderObj.write(self.fp)
1643 self.radarControllerHeaderObj.write(self.fp)
1643 self.radarControllerHeaderObj.write(self.fp)
1644 self.processingHeaderObj.write(self.fp)
1644 self.processingHeaderObj.write(self.fp)
1645
1645
1646 def __setNewBlock(self):
1646 def __setNewBlock(self):
1647 """
1647 """
1648 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1648 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1649
1649
1650 Return:
1650 Return:
1651 0 : si no pudo escribir nada
1651 0 : si no pudo escribir nada
1652 1 : Si escribio el Basic el First Header
1652 1 : Si escribio el Basic el First Header
1653 """
1653 """
1654 if self.fp == None:
1654 if self.fp == None:
1655 self.setNextFile()
1655 self.setNextFile()
1656
1656
1657 if self.flagIsNewFile:
1657 if self.flagIsNewFile:
1658 return 1
1658 return 1
1659
1659
1660 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1660 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1661 self.basicHeaderObj.write(self.fp)
1661 self.basicHeaderObj.write(self.fp)
1662 return 1
1662 return 1
1663
1663
1664 if not(self.setNextFile()):
1664 if not(self.setNextFile()):
1665 return 0
1665 return 0
1666
1666
1667 return 1
1667 return 1
1668
1668
1669 def writeNextBlock(self):
1669 def writeNextBlock(self):
1670 """
1670 """
1671 Selecciona el bloque siguiente de datos y los escribe en un file
1671 Selecciona el bloque siguiente de datos y los escribe en un file
1672
1672
1673 Return:
1673 Return:
1674 0 : Si no hizo pudo escribir el bloque de datos
1674 0 : Si no hizo pudo escribir el bloque de datos
1675 1 : Si no pudo escribir el bloque de datos
1675 1 : Si no pudo escribir el bloque de datos
1676 """
1676 """
1677 if not(self.__setNewBlock()):
1677 if not(self.__setNewBlock()):
1678 return 0
1678 return 0
1679
1679
1680 self.writeBlock()
1680 self.writeBlock()
1681
1681
1682 print("[Writing] Block No. %d/%d" % (self.blockIndex,
1682 print("[Writing] Block No. %d/%d" % (self.blockIndex,
1683 self.processingHeaderObj.dataBlocksPerFile))
1683 self.processingHeaderObj.dataBlocksPerFile))
1684
1684
1685 return 1
1685 return 1
1686
1686
1687 def setNextFile(self):
1687 def setNextFile(self):
1688 """
1688 """
1689 Determina el siguiente file que sera escrito
1689 Determina el siguiente file que sera escrito
1690
1690
1691 Affected:
1691 Affected:
1692 self.filename
1692 self.filename
1693 self.subfolder
1693 self.subfolder
1694 self.fp
1694 self.fp
1695 self.setFile
1695 self.setFile
1696 self.flagIsNewFile
1696 self.flagIsNewFile
1697
1697
1698 Return:
1698 Return:
1699 0 : Si el archivo no puede ser escrito
1699 0 : Si el archivo no puede ser escrito
1700 1 : Si el archivo esta listo para ser escrito
1700 1 : Si el archivo esta listo para ser escrito
1701 """
1701 """
1702 ext = self.ext
1702 ext = self.ext
1703 path = self.path
1703 path = self.path
1704
1704
1705 if self.fp != None:
1705 if self.fp != None:
1706 self.fp.close()
1706 self.fp.close()
1707
1707
1708 timeTuple = time.localtime(self.dataOut.utctime)
1708 timeTuple = time.localtime(self.dataOut.utctime)
1709 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year, timeTuple.tm_yday)
1709 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year, timeTuple.tm_yday)
1710
1710
1711 fullpath = os.path.join(path, subfolder)
1711 fullpath = os.path.join(path, subfolder)
1712 setFile = self.setFile
1712 setFile = self.setFile
1713
1713
1714 if not(os.path.exists(fullpath)):
1714 if not(os.path.exists(fullpath)):
1715 os.mkdir(fullpath)
1715 os.mkdir(fullpath)
1716 setFile = -1 # inicializo mi contador de seteo
1716 setFile = -1 # inicializo mi contador de seteo
1717 else:
1717 else:
1718 filesList = os.listdir(fullpath)
1718 filesList = os.listdir(fullpath)
1719 if len(filesList) > 0:
1719 if len(filesList) > 0:
1720 filesList = sorted(filesList, key=str.lower)
1720 filesList = sorted(filesList, key=str.lower)
1721 filen = filesList[-1]
1721 filen = filesList[-1]
1722 # el filename debera tener el siguiente formato
1722 # el filename debera tener el siguiente formato
1723 # 0 1234 567 89A BCDE (hex)
1723 # 0 1234 567 89A BCDE (hex)
1724 # x YYYY DDD SSS .ext
1724 # x YYYY DDD SSS .ext
1725 if isNumber(filen[8:11]):
1725 if isNumber(filen[8:11]):
1726 # inicializo mi contador de seteo al seteo del ultimo file
1726 # inicializo mi contador de seteo al seteo del ultimo file
1727 setFile = int(filen[8:11])
1727 setFile = int(filen[8:11])
1728 else:
1728 else:
1729 setFile = -1
1729 setFile = -1
1730 else:
1730 else:
1731 setFile = -1 # inicializo mi contador de seteo
1731 setFile = -1 # inicializo mi contador de seteo
1732
1732
1733 setFile += 1
1733 setFile += 1
1734
1734
1735 # If this is a new day it resets some values
1735 # If this is a new day it resets some values
1736 if self.dataOut.datatime.date() > self.fileDate:
1736 if self.dataOut.datatime.date() > self.fileDate:
1737 setFile = 0
1737 setFile = 0
1738 self.nTotalBlocks = 0
1738 self.nTotalBlocks = 0
1739
1739
1740 filen = '{}{:04d}{:03d}{:03d}{}'.format(
1740 filen = '{}{:04d}{:03d}{:03d}{}'.format(
1741 self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext)
1741 self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext)
1742
1742
1743 filename = os.path.join(path, subfolder, filen)
1743 filename = os.path.join(path, subfolder, filen)
1744
1744
1745 fp = open(filename, 'wb')
1745 fp = open(filename, 'wb')
1746
1746
1747 self.blockIndex = 0
1747 self.blockIndex = 0
1748
1748
1749 # guardando atributos
1749 # guardando atributos
1750 self.filename = filename
1750 self.filename = filename
1751 self.subfolder = subfolder
1751 self.subfolder = subfolder
1752 self.fp = fp
1752 self.fp = fp
1753 self.setFile = setFile
1753 self.setFile = setFile
1754 self.flagIsNewFile = 1
1754 self.flagIsNewFile = 1
1755 self.fileDate = self.dataOut.datatime.date()
1755 self.fileDate = self.dataOut.datatime.date()
1756
1756
1757 self.setFirstHeader()
1757 self.setFirstHeader()
1758
1758
1759 print('[Writing] Opening file: %s' % self.filename)
1759 print('[Writing] Opening file: %s' % self.filename)
1760
1760
1761 self.__writeFirstHeader()
1761 self.__writeFirstHeader()
1762
1762
1763 return 1
1763 return 1
1764
1764
1765 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4):
1765 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4):
1766 """
1766 """
1767 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1767 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1768
1768
1769 Inputs:
1769 Inputs:
1770 path : directory where data will be saved
1770 path : directory where data will be saved
1771 profilesPerBlock : number of profiles per block
1771 profilesPerBlock : number of profiles per block
1772 set : initial file set
1772 set : initial file set
1773 datatype : An integer number that defines data type:
1773 datatype : An integer number that defines data type:
1774 0 : int8 (1 byte)
1774 0 : int8 (1 byte)
1775 1 : int16 (2 bytes)
1775 1 : int16 (2 bytes)
1776 2 : int32 (4 bytes)
1776 2 : int32 (4 bytes)
1777 3 : int64 (8 bytes)
1777 3 : int64 (8 bytes)
1778 4 : float32 (4 bytes)
1778 4 : float32 (4 bytes)
1779 5 : double64 (8 bytes)
1779 5 : double64 (8 bytes)
1780
1780
1781 Return:
1781 Return:
1782 0 : Si no realizo un buen seteo
1782 0 : Si no realizo un buen seteo
1783 1 : Si realizo un buen seteo
1783 1 : Si realizo un buen seteo
1784 """
1784 """
1785
1785
1786 if ext == None:
1786 if ext == None:
1787 ext = self.ext
1787 ext = self.ext
1788
1788
1789 self.ext = ext.lower()
1789 self.ext = ext.lower()
1790
1790
1791 self.path = path
1791 self.path = path
1792
1792
1793 if set is None:
1793 if set is None:
1794 self.setFile = -1
1794 self.setFile = -1
1795 else:
1795 else:
1796 self.setFile = set - 1
1796 self.setFile = set - 1
1797
1797
1798 self.blocksPerFile = blocksPerFile
1798 self.blocksPerFile = blocksPerFile
1799
1799
1800 self.profilesPerBlock = profilesPerBlock
1800 self.profilesPerBlock = profilesPerBlock
1801
1801
1802 self.dataOut = dataOut
1802 self.dataOut = dataOut
1803 self.fileDate = self.dataOut.datatime.date()
1803 self.fileDate = self.dataOut.datatime.date()
1804 # By default
1804 # By default
1805 self.dtype = self.dataOut.dtype
1805 self.dtype = self.dataOut.dtype
1806
1806
1807 if datatype is not None:
1807 if datatype is not None:
1808 self.dtype = get_numpy_dtype(datatype)
1808 self.dtype = get_numpy_dtype(datatype)
1809
1809
1810 if not(self.setNextFile()):
1810 if not(self.setNextFile()):
1811 print("[Writing] There isn't a next file")
1811 print("[Writing] There isn't a next file")
1812 return 0
1812 return 0
1813
1813
1814 self.setBlockDimension()
1814 self.setBlockDimension()
1815
1815
1816 return 1
1816 return 1
1817
1817
1818 def run(self, dataOut, path, blocksPerFile=100, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs):
1818 def run(self, dataOut, path, blocksPerFile=100, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs):
1819
1819
1820 if not(self.isConfig):
1820 if not(self.isConfig):
1821
1821
1822 self.setup(dataOut, path, blocksPerFile, profilesPerBlock=profilesPerBlock,
1822 self.setup(dataOut, path, blocksPerFile, profilesPerBlock=profilesPerBlock,
1823 set=set, ext=ext, datatype=datatype, **kwargs)
1823 set=set, ext=ext, datatype=datatype, **kwargs)
1824 self.isConfig = True
1824 self.isConfig = True
1825
1825
1826 self.dataOut = dataOut
1826 self.dataOut = dataOut
1827 self.putData()
1827 self.putData()
1828 return self.dataOut No newline at end of file
1828 return self.dataOut
@@ -1,797 +1,796
1
1
2 '''
2 '''
3 Created on Jul 3, 2014
3 Created on Jul 3, 2014
4
4
5 @author: roj-idl71
5 @author: roj-idl71
6 '''
6 '''
7 # SUBCHANNELS EN VEZ DE CHANNELS
7 # SUBCHANNELS EN VEZ DE CHANNELS
8 # BENCHMARKS -> PROBLEMAS CON ARCHIVOS GRANDES -> INCONSTANTE EN EL TIEMPO
8 # BENCHMARKS -> PROBLEMAS CON ARCHIVOS GRANDES -> INCONSTANTE EN EL TIEMPO
9 # ACTUALIZACION DE VERSION
9 # ACTUALIZACION DE VERSION
10 # HEADERS
10 # HEADERS
11 # MODULO DE ESCRITURA
11 # MODULO DE ESCRITURA
12 # METADATA
12 # METADATA
13
13
14 import os
14 import os
15 import datetime
15 import datetime
16 import numpy
16 import numpy
17 import timeit
17 import timeit
18 from fractions import Fraction
18 from fractions import Fraction
19
19
20 try:
20 try:
21 from gevent import sleep
21 from gevent import sleep
22 except:
22 except:
23 from time import sleep
23 from time import sleep
24
24
25 from schainpy.model.data.jroheaderIO import RadarControllerHeader, SystemHeader
25 from schainpy.model.data.jroheaderIO import RadarControllerHeader, SystemHeader
26 from schainpy.model.data.jrodata import Voltage
26 from schainpy.model.data.jrodata import Voltage
27 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
27 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
28 from time import time
28 from time import time
29
29
30 import pickle
30 import pickle
31 try:
31 try:
32 import digital_rf
32 import digital_rf
33 except:
33 except:
34 print('You should install "digital_rf" module if you want to read Digital RF data')
34 print('You should install "digital_rf" module if you want to read Digital RF data')
35
35
36 @MPDecorator
36 @MPDecorator
37 class DigitalRFReader(ProcessingUnit):
37 class DigitalRFReader(ProcessingUnit):
38 '''
38 '''
39 classdocs
39 classdocs
40 '''
40 '''
41
41
42 def __init__(self):
42 def __init__(self):
43 '''
43 '''
44 Constructor
44 Constructor
45 '''
45 '''
46
46
47 ProcessingUnit.__init__(self)
47 ProcessingUnit.__init__(self)
48
48
49 self.dataOut = Voltage()
49 self.dataOut = Voltage()
50 self.__printInfo = True
50 self.__printInfo = True
51 self.__flagDiscontinuousBlock = False
51 self.__flagDiscontinuousBlock = False
52 self.__bufferIndex = 9999999
52 self.__bufferIndex = 9999999
53 self.__ippKm = None
53 self.__ippKm = None
54 self.__codeType = 0
54 self.__codeType = 0
55 self.__nCode = None
55 self.__nCode = None
56 self.__nBaud = None
56 self.__nBaud = None
57 self.__code = None
57 self.__code = None
58 self.dtype = None
58 self.dtype = None
59 self.oldAverage = None
59 self.oldAverage = None
60
60
61 def close(self):
61 def close(self):
62 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
62 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
63 return
63 return
64
64
65 def __getCurrentSecond(self):
65 def __getCurrentSecond(self):
66
66
67 return self.__thisUnixSample / self.__sample_rate
67 return self.__thisUnixSample / self.__sample_rate
68
68
69 thisSecond = property(__getCurrentSecond, "I'm the 'thisSecond' property.")
69 thisSecond = property(__getCurrentSecond, "I'm the 'thisSecond' property.")
70
70
71 def __setFileHeader(self):
71 def __setFileHeader(self):
72 '''
72 '''
73 In this method will be initialized every parameter of dataOut object (header, no data)
73 In this method will be initialized every parameter of dataOut object (header, no data)
74 '''
74 '''
75 ippSeconds = 1.0 * self.__nSamples / self.__sample_rate
75 ippSeconds = 1.0 * self.__nSamples / self.__sample_rate
76
76
77 nProfiles = 1.0 / ippSeconds # Number of profiles in one second
77 nProfiles = 1.0 / ippSeconds # Number of profiles in one second
78
78
79 try:
79 try:
80 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
80 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
81 self.__radarControllerHeader)
81 self.__radarControllerHeader)
82 except:
82 except:
83 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
83 self.dataOut.radarControllerHeaderObj = RadarControllerHeader(
84 txA=0,
84 txA=0,
85 txB=0,
85 txB=0,
86 nWindows=1,
86 nWindows=1,
87 nHeights=self.__nSamples,
87 nHeights=self.__nSamples,
88 firstHeight=self.__firstHeigth,
88 firstHeight=self.__firstHeigth,
89 deltaHeight=self.__deltaHeigth,
89 deltaHeight=self.__deltaHeigth,
90 codeType=self.__codeType,
90 codeType=self.__codeType,
91 nCode=self.__nCode, nBaud=self.__nBaud,
91 nCode=self.__nCode, nBaud=self.__nBaud,
92 code=self.__code)
92 code=self.__code)
93
93
94 try:
94 try:
95 self.dataOut.systemHeaderObj = SystemHeader(self.__systemHeader)
95 self.dataOut.systemHeaderObj = SystemHeader(self.__systemHeader)
96 except:
96 except:
97 self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples,
97 self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples,
98 nProfiles=nProfiles,
98 nProfiles=nProfiles,
99 nChannels=len(
99 nChannels=len(
100 self.__channelList),
100 self.__channelList),
101 adcResolution=14)
101 adcResolution=14)
102 self.dataOut.type = "Voltage"
102 self.dataOut.type = "Voltage"
103
103
104 self.dataOut.data = None
104 self.dataOut.data = None
105
105
106 self.dataOut.dtype = self.dtype
106 self.dataOut.dtype = self.dtype
107
107
108 # self.dataOut.nChannels = 0
108 # self.dataOut.nChannels = 0
109
109
110 # self.dataOut.nHeights = 0
110 # self.dataOut.nHeights = 0
111
111
112 self.dataOut.nProfiles = int(nProfiles)
112 self.dataOut.nProfiles = int(nProfiles)
113
113
114 self.dataOut.heightList = self.__firstHeigth + \
114 self.dataOut.heightList = self.__firstHeigth + \
115 numpy.arange(self.__nSamples, dtype=numpy.float) * \
115 numpy.arange(self.__nSamples, dtype=numpy.float) * \
116 self.__deltaHeigth
116 self.__deltaHeigth
117
117
118 self.dataOut.channelList = list(range(self.__num_subchannels))
118 self.dataOut.channelList = list(range(self.__num_subchannels))
119
119
120 self.dataOut.blocksize = self.dataOut.getNChannels() * self.dataOut.getNHeights()
120 self.dataOut.blocksize = self.dataOut.getNChannels() * self.dataOut.getNHeights()
121
121
122 # self.dataOut.channelIndexList = None
122 # self.dataOut.channelIndexList = None
123
123
124 self.dataOut.flagNoData = True
124 self.dataOut.flagNoData = True
125
125
126 self.dataOut.flagDataAsBlock = False
126 self.dataOut.flagDataAsBlock = False
127 # Set to TRUE if the data is discontinuous
127 # Set to TRUE if the data is discontinuous
128 self.dataOut.flagDiscontinuousBlock = False
128 self.dataOut.flagDiscontinuousBlock = False
129
129
130 self.dataOut.utctime = None
130 self.dataOut.utctime = None
131
131
132 # timezone like jroheader, difference in minutes between UTC and localtime
132 # timezone like jroheader, difference in minutes between UTC and localtime
133 self.dataOut.timeZone = self.__timezone / 60
133 self.dataOut.timeZone = self.__timezone / 60
134
134
135 self.dataOut.dstFlag = 0
135 self.dataOut.dstFlag = 0
136
136
137 self.dataOut.errorCount = 0
137 self.dataOut.errorCount = 0
138
138
139 try:
139 try:
140 self.dataOut.nCohInt = self.fixed_metadata_dict.get(
140 self.dataOut.nCohInt = self.fixed_metadata_dict.get(
141 'nCohInt', self.nCohInt)
141 'nCohInt', self.nCohInt)
142
142
143 # asumo que la data esta decodificada
143 # asumo que la data esta decodificada
144 self.dataOut.flagDecodeData = self.fixed_metadata_dict.get(
144 self.dataOut.flagDecodeData = self.fixed_metadata_dict.get(
145 'flagDecodeData', self.flagDecodeData)
145 'flagDecodeData', self.flagDecodeData)
146
146
147 # asumo que la data esta sin flip
147 # asumo que la data esta sin flip
148 self.dataOut.flagDeflipData = self.fixed_metadata_dict['flagDeflipData']
148 self.dataOut.flagDeflipData = self.fixed_metadata_dict['flagDeflipData']
149
149
150 self.dataOut.flagShiftFFT = self.fixed_metadata_dict['flagShiftFFT']
150 self.dataOut.flagShiftFFT = self.fixed_metadata_dict['flagShiftFFT']
151
151
152 self.dataOut.useLocalTime = self.fixed_metadata_dict['useLocalTime']
152 self.dataOut.useLocalTime = self.fixed_metadata_dict['useLocalTime']
153 except:
153 except:
154 pass
154 pass
155
155
156 self.dataOut.ippSeconds = ippSeconds
156 self.dataOut.ippSeconds = ippSeconds
157
157
158 # Time interval between profiles
158 # Time interval between profiles
159 # self.dataOut.timeInterval = self.dataOut.ippSeconds * self.dataOut.nCohInt
159 # self.dataOut.timeInterval = self.dataOut.ippSeconds * self.dataOut.nCohInt
160
160
161 self.dataOut.frequency = self.__frequency
161 self.dataOut.frequency = self.__frequency
162
162
163 self.dataOut.realtime = self.__online
163 self.dataOut.realtime = self.__online
164
164
165 def findDatafiles(self, path, startDate=None, endDate=None):
165 def findDatafiles(self, path, startDate=None, endDate=None):
166
166
167 if not os.path.isdir(path):
167 if not os.path.isdir(path):
168 return []
168 return []
169
169
170 try:
170 try:
171 digitalReadObj = digital_rf.DigitalRFReader(
171 digitalReadObj = digital_rf.DigitalRFReader(
172 path, load_all_metadata=True)
172 path, load_all_metadata=True)
173 except:
173 except:
174 digitalReadObj = digital_rf.DigitalRFReader(path)
174 digitalReadObj = digital_rf.DigitalRFReader(path)
175
175
176 channelNameList = digitalReadObj.get_channels()
176 channelNameList = digitalReadObj.get_channels()
177
177
178 if not channelNameList:
178 if not channelNameList:
179 return []
179 return []
180
180
181 metadata_dict = digitalReadObj.get_rf_file_metadata(channelNameList[0])
181 metadata_dict = digitalReadObj.get_rf_file_metadata(channelNameList[0])
182
182
183 sample_rate = metadata_dict['sample_rate'][0]
183 sample_rate = metadata_dict['sample_rate'][0]
184
184
185 this_metadata_file = digitalReadObj.get_metadata(channelNameList[0])
185 this_metadata_file = digitalReadObj.get_metadata(channelNameList[0])
186
186
187 try:
187 try:
188 timezone = this_metadata_file['timezone'].value
188 timezone = this_metadata_file['timezone'].value
189 except:
189 except:
190 timezone = 0
190 timezone = 0
191
191
192 startUTCSecond, endUTCSecond = digitalReadObj.get_bounds(
192 startUTCSecond, endUTCSecond = digitalReadObj.get_bounds(
193 channelNameList[0]) / sample_rate - timezone
193 channelNameList[0]) / sample_rate - timezone
194
194
195 startDatetime = datetime.datetime.utcfromtimestamp(startUTCSecond)
195 startDatetime = datetime.datetime.utcfromtimestamp(startUTCSecond)
196 endDatatime = datetime.datetime.utcfromtimestamp(endUTCSecond)
196 endDatatime = datetime.datetime.utcfromtimestamp(endUTCSecond)
197
197
198 if not startDate:
198 if not startDate:
199 startDate = startDatetime.date()
199 startDate = startDatetime.date()
200
200
201 if not endDate:
201 if not endDate:
202 endDate = endDatatime.date()
202 endDate = endDatatime.date()
203
203
204 dateList = []
204 dateList = []
205
205
206 thisDatetime = startDatetime
206 thisDatetime = startDatetime
207
207
208 while(thisDatetime <= endDatatime):
208 while(thisDatetime <= endDatatime):
209
209
210 thisDate = thisDatetime.date()
210 thisDate = thisDatetime.date()
211
211
212 if thisDate < startDate:
212 if thisDate < startDate:
213 continue
213 continue
214
214
215 if thisDate > endDate:
215 if thisDate > endDate:
216 break
216 break
217
217
218 dateList.append(thisDate)
218 dateList.append(thisDate)
219 thisDatetime += datetime.timedelta(1)
219 thisDatetime += datetime.timedelta(1)
220
220
221 return dateList
221 return dateList
222
222
223 def setup(self, path=None,
223 def setup(self, path=None,
224 startDate=None,
224 startDate=None,
225 endDate=None,
225 endDate=None,
226 startTime=datetime.time(0, 0, 0),
226 startTime=datetime.time(0, 0, 0),
227 endTime=datetime.time(23, 59, 59),
227 endTime=datetime.time(23, 59, 59),
228 channelList=None,
228 channelList=None,
229 nSamples=None,
229 nSamples=None,
230 online=False,
230 online=False,
231 delay=60,
231 delay=60,
232 buffer_size=1024,
232 buffer_size=1024,
233 ippKm=None,
233 ippKm=None,
234 nCohInt=1,
234 nCohInt=1,
235 nCode=1,
235 nCode=1,
236 nBaud=1,
236 nBaud=1,
237 flagDecodeData=False,
237 flagDecodeData=False,
238 code=numpy.ones((1, 1), dtype=numpy.int),
238 code=numpy.ones((1, 1), dtype=numpy.int),
239 **kwargs):
239 **kwargs):
240 '''
240 '''
241 In this method we should set all initial parameters.
241 In this method we should set all initial parameters.
242
242
243 Inputs:
243 Inputs:
244 path
244 path
245 startDate
245 startDate
246 endDate
246 endDate
247 startTime
247 startTime
248 endTime
248 endTime
249 set
249 set
250 expLabel
250 expLabel
251 ext
251 ext
252 online
252 online
253 delay
253 delay
254 '''
254 '''
255 self.nCohInt = nCohInt
255 self.nCohInt = nCohInt
256 self.flagDecodeData = flagDecodeData
256 self.flagDecodeData = flagDecodeData
257 self.i = 0
257 self.i = 0
258 if not os.path.isdir(path):
258 if not os.path.isdir(path):
259 raise ValueError("[Reading] Directory %s does not exist" % path)
259 raise ValueError("[Reading] Directory %s does not exist" % path)
260
260
261 try:
261 try:
262 self.digitalReadObj = digital_rf.DigitalRFReader(
262 self.digitalReadObj = digital_rf.DigitalRFReader(
263 path, load_all_metadata=True)
263 path, load_all_metadata=True)
264 except:
264 except:
265 self.digitalReadObj = digital_rf.DigitalRFReader(path)
265 self.digitalReadObj = digital_rf.DigitalRFReader(path)
266
266
267 channelNameList = self.digitalReadObj.get_channels()
267 channelNameList = self.digitalReadObj.get_channels()
268
268
269 if not channelNameList:
269 if not channelNameList:
270 raise ValueError("[Reading] Directory %s does not have any files" % path)
270 raise ValueError("[Reading] Directory %s does not have any files" % path)
271
271
272 if not channelList:
272 if not channelList:
273 channelList = list(range(len(channelNameList)))
273 channelList = list(range(len(channelNameList)))
274
274
275 ########## Reading metadata ######################
275 ########## Reading metadata ######################
276
276
277 top_properties = self.digitalReadObj.get_properties(
277 top_properties = self.digitalReadObj.get_properties(
278 channelNameList[channelList[0]])
278 channelNameList[channelList[0]])
279
279
280 self.__num_subchannels = top_properties['num_subchannels']
280 self.__num_subchannels = top_properties['num_subchannels']
281 self.__sample_rate = 1.0 * \
281 self.__sample_rate = 1.0 * \
282 top_properties['sample_rate_numerator'] / \
282 top_properties['sample_rate_numerator'] / \
283 top_properties['sample_rate_denominator']
283 top_properties['sample_rate_denominator']
284 # self.__samples_per_file = top_properties['samples_per_file'][0]
284 # self.__samples_per_file = top_properties['samples_per_file'][0]
285 self.__deltaHeigth = 1e6 * 0.15 / self.__sample_rate # why 0.15?
285 self.__deltaHeigth = 1e6 * 0.15 / self.__sample_rate # why 0.15?
286
286
287 this_metadata_file = self.digitalReadObj.get_digital_metadata(
287 this_metadata_file = self.digitalReadObj.get_digital_metadata(
288 channelNameList[channelList[0]])
288 channelNameList[channelList[0]])
289 metadata_bounds = this_metadata_file.get_bounds()
289 metadata_bounds = this_metadata_file.get_bounds()
290 self.fixed_metadata_dict = this_metadata_file.read(
290 self.fixed_metadata_dict = this_metadata_file.read(
291 metadata_bounds[0])[metadata_bounds[0]] # GET FIRST HEADER
291 metadata_bounds[0])[metadata_bounds[0]] # GET FIRST HEADER
292
292
293 try:
293 try:
294 self.__processingHeader = self.fixed_metadata_dict['processingHeader']
294 self.__processingHeader = self.fixed_metadata_dict['processingHeader']
295 self.__radarControllerHeader = self.fixed_metadata_dict['radarControllerHeader']
295 self.__radarControllerHeader = self.fixed_metadata_dict['radarControllerHeader']
296 self.__systemHeader = self.fixed_metadata_dict['systemHeader']
296 self.__systemHeader = self.fixed_metadata_dict['systemHeader']
297 self.dtype = pickle.loads(self.fixed_metadata_dict['dtype'])
297 self.dtype = pickle.loads(self.fixed_metadata_dict['dtype'])
298 except:
298 except:
299 pass
299 pass
300
300
301 self.__frequency = None
301 self.__frequency = None
302
302
303 self.__frequency = self.fixed_metadata_dict.get('frequency', 1)
303 self.__frequency = self.fixed_metadata_dict.get('frequency', 1)
304
304
305 self.__timezone = self.fixed_metadata_dict.get('timezone', 300)
305 self.__timezone = self.fixed_metadata_dict.get('timezone', 300)
306
306
307 try:
307 try:
308 nSamples = self.fixed_metadata_dict['nSamples']
308 nSamples = self.fixed_metadata_dict['nSamples']
309 except:
309 except:
310 nSamples = None
310 nSamples = None
311
311
312 self.__firstHeigth = 0
312 self.__firstHeigth = 0
313
313
314 try:
314 try:
315 codeType = self.__radarControllerHeader['codeType']
315 codeType = self.__radarControllerHeader['codeType']
316 except:
316 except:
317 codeType = 0
317 codeType = 0
318
318
319 try:
319 try:
320 if codeType:
320 if codeType:
321 nCode = self.__radarControllerHeader['nCode']
321 nCode = self.__radarControllerHeader['nCode']
322 nBaud = self.__radarControllerHeader['nBaud']
322 nBaud = self.__radarControllerHeader['nBaud']
323 code = self.__radarControllerHeader['code']
323 code = self.__radarControllerHeader['code']
324 except:
324 except:
325 pass
325 pass
326
326
327 if not ippKm:
327 if not ippKm:
328 try:
328 try:
329 # seconds to km
329 # seconds to km
330 ippKm = self.__radarControllerHeader['ipp']
330 ippKm = self.__radarControllerHeader['ipp']
331 except:
331 except:
332 ippKm = None
332 ippKm = None
333 ####################################################
333 ####################################################
334 self.__ippKm = ippKm
334 self.__ippKm = ippKm
335 startUTCSecond = None
335 startUTCSecond = None
336 endUTCSecond = None
336 endUTCSecond = None
337
337
338 if startDate:
338 if startDate:
339 startDatetime = datetime.datetime.combine(startDate, startTime)
339 startDatetime = datetime.datetime.combine(startDate, startTime)
340 startUTCSecond = (
340 startUTCSecond = (
341 startDatetime - datetime.datetime(1970, 1, 1)).total_seconds() + self.__timezone
341 startDatetime - datetime.datetime(1970, 1, 1)).total_seconds() + self.__timezone
342
342
343 if endDate:
343 if endDate:
344 endDatetime = datetime.datetime.combine(endDate, endTime)
344 endDatetime = datetime.datetime.combine(endDate, endTime)
345 endUTCSecond = (endDatetime - datetime.datetime(1970,
345 endUTCSecond = (endDatetime - datetime.datetime(1970,
346 1, 1)).total_seconds() + self.__timezone
346 1, 1)).total_seconds() + self.__timezone
347
347
348 start_index, end_index = self.digitalReadObj.get_bounds(
348 start_index, end_index = self.digitalReadObj.get_bounds(
349 channelNameList[channelList[0]])
349 channelNameList[channelList[0]])
350
350
351 if not startUTCSecond:
351 if not startUTCSecond:
352 startUTCSecond = start_index / self.__sample_rate
352 startUTCSecond = start_index / self.__sample_rate
353
353
354 if start_index > startUTCSecond * self.__sample_rate:
354 if start_index > startUTCSecond * self.__sample_rate:
355 startUTCSecond = start_index / self.__sample_rate
355 startUTCSecond = start_index / self.__sample_rate
356
356
357 if not endUTCSecond:
357 if not endUTCSecond:
358 endUTCSecond = end_index / self.__sample_rate
358 endUTCSecond = end_index / self.__sample_rate
359
359
360 if end_index < endUTCSecond * self.__sample_rate:
360 if end_index < endUTCSecond * self.__sample_rate:
361 endUTCSecond = end_index / self.__sample_rate
361 endUTCSecond = end_index / self.__sample_rate
362 if not nSamples:
362 if not nSamples:
363 if not ippKm:
363 if not ippKm:
364 raise ValueError("[Reading] nSamples or ippKm should be defined")
364 raise ValueError("[Reading] nSamples or ippKm should be defined")
365 nSamples = int(ippKm / (1e6 * 0.15 / self.__sample_rate))
365 nSamples = int(ippKm / (1e6 * 0.15 / self.__sample_rate))
366 channelBoundList = []
366 channelBoundList = []
367 channelNameListFiltered = []
367 channelNameListFiltered = []
368
368
369 for thisIndexChannel in channelList:
369 for thisIndexChannel in channelList:
370 thisChannelName = channelNameList[thisIndexChannel]
370 thisChannelName = channelNameList[thisIndexChannel]
371 start_index, end_index = self.digitalReadObj.get_bounds(
371 start_index, end_index = self.digitalReadObj.get_bounds(
372 thisChannelName)
372 thisChannelName)
373 channelBoundList.append((start_index, end_index))
373 channelBoundList.append((start_index, end_index))
374 channelNameListFiltered.append(thisChannelName)
374 channelNameListFiltered.append(thisChannelName)
375
375
376 self.profileIndex = 0
376 self.profileIndex = 0
377 self.i = 0
377 self.i = 0
378 self.__delay = delay
378 self.__delay = delay
379
379
380 self.__codeType = codeType
380 self.__codeType = codeType
381 self.__nCode = nCode
381 self.__nCode = nCode
382 self.__nBaud = nBaud
382 self.__nBaud = nBaud
383 self.__code = code
383 self.__code = code
384
384
385 self.__datapath = path
385 self.__datapath = path
386 self.__online = online
386 self.__online = online
387 self.__channelList = channelList
387 self.__channelList = channelList
388 self.__channelNameList = channelNameListFiltered
388 self.__channelNameList = channelNameListFiltered
389 self.__channelBoundList = channelBoundList
389 self.__channelBoundList = channelBoundList
390 self.__nSamples = nSamples
390 self.__nSamples = nSamples
391 self.__samples_to_read = int(nSamples) # FIJO: AHORA 40
391 self.__samples_to_read = int(nSamples) # FIJO: AHORA 40
392 self.__nChannels = len(self.__channelList)
392 self.__nChannels = len(self.__channelList)
393
393
394 self.__startUTCSecond = startUTCSecond
394 self.__startUTCSecond = startUTCSecond
395 self.__endUTCSecond = endUTCSecond
395 self.__endUTCSecond = endUTCSecond
396
396
397 self.__timeInterval = 1.0 * self.__samples_to_read / \
397 self.__timeInterval = 1.0 * self.__samples_to_read / \
398 self.__sample_rate # Time interval
398 self.__sample_rate # Time interval
399
399
400 if online:
400 if online:
401 # self.__thisUnixSample = int(endUTCSecond*self.__sample_rate - 4*self.__samples_to_read)
401 # self.__thisUnixSample = int(endUTCSecond*self.__sample_rate - 4*self.__samples_to_read)
402 startUTCSecond = numpy.floor(endUTCSecond)
402 startUTCSecond = numpy.floor(endUTCSecond)
403
403
404 # por que en el otro metodo lo primero q se hace es sumar samplestoread
404 # por que en el otro metodo lo primero q se hace es sumar samplestoread
405 self.__thisUnixSample = int(
405 self.__thisUnixSample = int(
406 startUTCSecond * self.__sample_rate) - self.__samples_to_read
406 startUTCSecond * self.__sample_rate) - self.__samples_to_read
407
407
408 self.__data_buffer = numpy.zeros(
408 self.__data_buffer = numpy.zeros(
409 (self.__num_subchannels, self.__samples_to_read), dtype=numpy.complex)
409 (self.__num_subchannels, self.__samples_to_read), dtype=numpy.complex)
410
410
411 self.__setFileHeader()
411 self.__setFileHeader()
412 self.isConfig = True
412 self.isConfig = True
413
413
414 print("[Reading] Digital RF Data was found from %s to %s " % (
414 print("[Reading] Digital RF Data was found from %s to %s " % (
415 datetime.datetime.utcfromtimestamp(
415 datetime.datetime.utcfromtimestamp(
416 self.__startUTCSecond - self.__timezone),
416 self.__startUTCSecond - self.__timezone),
417 datetime.datetime.utcfromtimestamp(
417 datetime.datetime.utcfromtimestamp(
418 self.__endUTCSecond - self.__timezone)
418 self.__endUTCSecond - self.__timezone)
419 ))
419 ))
420
420
421 print("[Reading] Starting process from %s to %s" % (datetime.datetime.utcfromtimestamp(startUTCSecond - self.__timezone),
421 print("[Reading] Starting process from %s to %s" % (datetime.datetime.utcfromtimestamp(startUTCSecond - self.__timezone),
422 datetime.datetime.utcfromtimestamp(
422 datetime.datetime.utcfromtimestamp(
423 endUTCSecond - self.__timezone)
423 endUTCSecond - self.__timezone)
424 ))
424 ))
425 self.oldAverage = None
425 self.oldAverage = None
426 self.count = 0
426 self.count = 0
427 self.executionTime = 0
427 self.executionTime = 0
428
428
429 def __reload(self):
429 def __reload(self):
430 # print
430 # print
431 # print "%s not in range [%s, %s]" %(
431 # print "%s not in range [%s, %s]" %(
432 # datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
432 # datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
433 # datetime.datetime.utcfromtimestamp(self.__startUTCSecond - self.__timezone),
433 # datetime.datetime.utcfromtimestamp(self.__startUTCSecond - self.__timezone),
434 # datetime.datetime.utcfromtimestamp(self.__endUTCSecond - self.__timezone)
434 # datetime.datetime.utcfromtimestamp(self.__endUTCSecond - self.__timezone)
435 # )
435 # )
436 print("[Reading] reloading metadata ...")
436 print("[Reading] reloading metadata ...")
437
437
438 try:
438 try:
439 self.digitalReadObj.reload(complete_update=True)
439 self.digitalReadObj.reload(complete_update=True)
440 except:
440 except:
441 self.digitalReadObj.reload()
441 self.digitalReadObj.reload()
442
442
443 start_index, end_index = self.digitalReadObj.get_bounds(
443 start_index, end_index = self.digitalReadObj.get_bounds(
444 self.__channelNameList[self.__channelList[0]])
444 self.__channelNameList[self.__channelList[0]])
445
445
446 if start_index > self.__startUTCSecond * self.__sample_rate:
446 if start_index > self.__startUTCSecond * self.__sample_rate:
447 self.__startUTCSecond = 1.0 * start_index / self.__sample_rate
447 self.__startUTCSecond = 1.0 * start_index / self.__sample_rate
448
448
449 if end_index > self.__endUTCSecond * self.__sample_rate:
449 if end_index > self.__endUTCSecond * self.__sample_rate:
450 self.__endUTCSecond = 1.0 * end_index / self.__sample_rate
450 self.__endUTCSecond = 1.0 * end_index / self.__sample_rate
451 print()
451 print()
452 print("[Reading] New timerange found [%s, %s] " % (
452 print("[Reading] New timerange found [%s, %s] " % (
453 datetime.datetime.utcfromtimestamp(
453 datetime.datetime.utcfromtimestamp(
454 self.__startUTCSecond - self.__timezone),
454 self.__startUTCSecond - self.__timezone),
455 datetime.datetime.utcfromtimestamp(
455 datetime.datetime.utcfromtimestamp(
456 self.__endUTCSecond - self.__timezone)
456 self.__endUTCSecond - self.__timezone)
457 ))
457 ))
458
458
459 return True
459 return True
460
460
461 return False
461 return False
462
462
463 def timeit(self, toExecute):
463 def timeit(self, toExecute):
464 t0 = time()
464 t0 = time()
465 toExecute()
465 toExecute()
466 self.executionTime = time() - t0
466 self.executionTime = time() - t0
467 if self.oldAverage is None:
467 if self.oldAverage is None:
468 self.oldAverage = self.executionTime
468 self.oldAverage = self.executionTime
469 self.oldAverage = (self.executionTime + self.count *
469 self.oldAverage = (self.executionTime + self.count *
470 self.oldAverage) / (self.count + 1.0)
470 self.oldAverage) / (self.count + 1.0)
471 self.count = self.count + 1.0
471 self.count = self.count + 1.0
472 return
472 return
473
473
474 def __readNextBlock(self, seconds=30, volt_scale=1):
474 def __readNextBlock(self, seconds=30, volt_scale=1):
475 '''
475 '''
476 '''
476 '''
477
477
478 # Set the next data
478 # Set the next data
479 self.__flagDiscontinuousBlock = False
479 self.__flagDiscontinuousBlock = False
480 self.__thisUnixSample += self.__samples_to_read
480 self.__thisUnixSample += self.__samples_to_read
481
481
482 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
482 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
483 print("[Reading] There are no more data into selected time-range")
483 print("[Reading] There are no more data into selected time-range")
484 if self.__online:
484 if self.__online:
485 self.__reload()
485 self.__reload()
486 else:
486 else:
487 return False
487 return False
488
488
489 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
489 if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate:
490 return False
490 return False
491 self.__thisUnixSample -= self.__samples_to_read
491 self.__thisUnixSample -= self.__samples_to_read
492
492
493 indexChannel = 0
493 indexChannel = 0
494
494
495 dataOk = False
495 dataOk = False
496 for thisChannelName in self.__channelNameList: # TODO VARIOS CHANNELS?
496 for thisChannelName in self.__channelNameList: # TODO VARIOS CHANNELS?
497 for indexSubchannel in range(self.__num_subchannels):
497 for indexSubchannel in range(self.__num_subchannels):
498 try:
498 try:
499 t0 = time()
499 t0 = time()
500 result = self.digitalReadObj.read_vector_c81d(self.__thisUnixSample,
500 result = self.digitalReadObj.read_vector_c81d(self.__thisUnixSample,
501 self.__samples_to_read,
501 self.__samples_to_read,
502 thisChannelName, sub_channel=indexSubchannel)
502 thisChannelName, sub_channel=indexSubchannel)
503 self.executionTime = time() - t0
503 self.executionTime = time() - t0
504 if self.oldAverage is None:
504 if self.oldAverage is None:
505 self.oldAverage = self.executionTime
505 self.oldAverage = self.executionTime
506 self.oldAverage = (
506 self.oldAverage = (
507 self.executionTime + self.count * self.oldAverage) / (self.count + 1.0)
507 self.executionTime + self.count * self.oldAverage) / (self.count + 1.0)
508 self.count = self.count + 1.0
508 self.count = self.count + 1.0
509
509
510 except IOError as e:
510 except IOError as e:
511 # read next profile
511 # read next profile
512 self.__flagDiscontinuousBlock = True
512 self.__flagDiscontinuousBlock = True
513 print("[Reading] %s" % datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), e)
513 print("[Reading] %s" % datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), e)
514 break
514 break
515
515
516 if result.shape[0] != self.__samples_to_read:
516 if result.shape[0] != self.__samples_to_read:
517 self.__flagDiscontinuousBlock = True
517 self.__flagDiscontinuousBlock = True
518 print("[Reading] %s: Too few samples were found, just %d/%d samples" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
518 print("[Reading] %s: Too few samples were found, just %d/%d samples" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
519 result.shape[0],
519 result.shape[0],
520 self.__samples_to_read))
520 self.__samples_to_read))
521 break
521 break
522
522
523 self.__data_buffer[indexSubchannel, :] = result * volt_scale
523 self.__data_buffer[indexSubchannel, :] = result * volt_scale
524
524
525 indexChannel += 1
525 indexChannel += 1
526
526
527 dataOk = True
527 dataOk = True
528
528
529 self.__utctime = self.__thisUnixSample / self.__sample_rate
529 self.__utctime = self.__thisUnixSample / self.__sample_rate
530
530
531 if not dataOk:
531 if not dataOk:
532 return False
532 return False
533
533
534 print("[Reading] %s: %d samples <> %f sec" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
534 print("[Reading] %s: %d samples <> %f sec" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone),
535 self.__samples_to_read,
535 self.__samples_to_read,
536 self.__timeInterval))
536 self.__timeInterval))
537
537
538 self.__bufferIndex = 0
538 self.__bufferIndex = 0
539
539
540 return True
540 return True
541
541
542 def __isBufferEmpty(self):
542 def __isBufferEmpty(self):
543 return self.__bufferIndex > self.__samples_to_read - self.__nSamples # 40960 - 40
543 return self.__bufferIndex > self.__samples_to_read - self.__nSamples # 40960 - 40
544
544
545 def getData(self, seconds=30, nTries=5):
545 def getData(self, seconds=30, nTries=5):
546 '''
546 '''
547 This method gets the data from files and put the data into the dataOut object
547 This method gets the data from files and put the data into the dataOut object
548
548
549 In addition, increase el the buffer counter in one.
549 In addition, increase el the buffer counter in one.
550
550
551 Return:
551 Return:
552 data : retorna un perfil de voltages (alturas * canales) copiados desde el
552 data : retorna un perfil de voltages (alturas * canales) copiados desde el
553 buffer. Si no hay mas archivos a leer retorna None.
553 buffer. Si no hay mas archivos a leer retorna None.
554
554
555 Affected:
555 Affected:
556 self.dataOut
556 self.dataOut
557 self.profileIndex
557 self.profileIndex
558 self.flagDiscontinuousBlock
558 self.flagDiscontinuousBlock
559 self.flagIsNewBlock
559 self.flagIsNewBlock
560 '''
560 '''
561
561
562 err_counter = 0
562 err_counter = 0
563 self.dataOut.flagNoData = True
563 self.dataOut.flagNoData = True
564
564
565 if self.__isBufferEmpty():
565 if self.__isBufferEmpty():
566 self.__flagDiscontinuousBlock = False
566 self.__flagDiscontinuousBlock = False
567
567
568 while True:
568 while True:
569 if self.__readNextBlock():
569 if self.__readNextBlock():
570 break
570 break
571 if self.__thisUnixSample > self.__endUTCSecond * self.__sample_rate:
571 if self.__thisUnixSample > self.__endUTCSecond * self.__sample_rate:
572 self.dataOut.error = (1, '')
572 self.dataOut.error = 'Error'
573 return
573 return
574
574
575 if self.__flagDiscontinuousBlock:
575 if self.__flagDiscontinuousBlock:
576 print('[Reading] discontinuous block found ... continue with the next block')
576 self.dataOut.error = 'discontinuous block found'
577 self.dataOut.error = (1, '')
578 return
577 return
579
578
580 if not self.__online:
579 if not self.__online:
581 self.dataOut.error = (1, '')
580 self.dataOut.error = 'Online?'
582 return
581 return
583
582
584 err_counter += 1
583 err_counter += 1
585 if err_counter > nTries:
584 if err_counter > nTries:
586 self.dataOut.error = (1, '')
585 self.dataOut.error = 'Max retrys reach'
587 return
586 return
588
587
589 print('[Reading] waiting %d seconds to read a new block' % seconds)
588 print('[Reading] waiting %d seconds to read a new block' % seconds)
590 sleep(seconds)
589 sleep(seconds)
591
590
592 self.dataOut.data = self.__data_buffer[:,
591 self.dataOut.data = self.__data_buffer[:,
593 self.__bufferIndex:self.__bufferIndex + self.__nSamples]
592 self.__bufferIndex:self.__bufferIndex + self.__nSamples]
594 self.dataOut.utctime = (
593 self.dataOut.utctime = (
595 self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate
594 self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate
596 self.dataOut.flagNoData = False
595 self.dataOut.flagNoData = False
597 self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock
596 self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock
598 self.dataOut.profileIndex = self.profileIndex
597 self.dataOut.profileIndex = self.profileIndex
599
598
600 self.__bufferIndex += self.__nSamples
599 self.__bufferIndex += self.__nSamples
601 self.profileIndex += 1
600 self.profileIndex += 1
602
601
603 if self.profileIndex == self.dataOut.nProfiles:
602 if self.profileIndex == self.dataOut.nProfiles:
604 self.profileIndex = 0
603 self.profileIndex = 0
605
604
606 return
605 return
607
606
608 def printInfo(self):
607 def printInfo(self):
609 '''
608 '''
610 '''
609 '''
611 if self.__printInfo == False:
610 if self.__printInfo == False:
612 return
611 return
613
612
614 # self.systemHeaderObj.printInfo()
613 # self.systemHeaderObj.printInfo()
615 # self.radarControllerHeaderObj.printInfo()
614 # self.radarControllerHeaderObj.printInfo()
616
615
617 self.__printInfo = False
616 self.__printInfo = False
618
617
619 def printNumberOfBlock(self):
618 def printNumberOfBlock(self):
620 '''
619 '''
621 '''
620 '''
622 return
621 return
623 # print self.profileIndex
622 # print self.profileIndex
624
623
625 def run(self, **kwargs):
624 def run(self, **kwargs):
626 '''
625 '''
627 This method will be called many times so here you should put all your code
626 This method will be called many times so here you should put all your code
628 '''
627 '''
629
628
630 if not self.isConfig:
629 if not self.isConfig:
631 self.setup(**kwargs)
630 self.setup(**kwargs)
632 #self.i = self.i+1
631 #self.i = self.i+1
633 self.getData(seconds=self.__delay)
632 self.getData(seconds=self.__delay)
634
633
635 return
634 return
636
635
637
636
638 class DigitalRFWriter(Operation):
637 class DigitalRFWriter(Operation):
639 '''
638 '''
640 classdocs
639 classdocs
641 '''
640 '''
642
641
643 def __init__(self, **kwargs):
642 def __init__(self, **kwargs):
644 '''
643 '''
645 Constructor
644 Constructor
646 '''
645 '''
647 Operation.__init__(self, **kwargs)
646 Operation.__init__(self, **kwargs)
648 self.metadata_dict = {}
647 self.metadata_dict = {}
649 self.dataOut = None
648 self.dataOut = None
650 self.dtype = None
649 self.dtype = None
651 self.oldAverage = 0
650 self.oldAverage = 0
652
651
653 def setHeader(self):
652 def setHeader(self):
654
653
655 self.metadata_dict['frequency'] = self.dataOut.frequency
654 self.metadata_dict['frequency'] = self.dataOut.frequency
656 self.metadata_dict['timezone'] = self.dataOut.timeZone
655 self.metadata_dict['timezone'] = self.dataOut.timeZone
657 self.metadata_dict['dtype'] = pickle.dumps(self.dataOut.dtype)
656 self.metadata_dict['dtype'] = pickle.dumps(self.dataOut.dtype)
658 self.metadata_dict['nProfiles'] = self.dataOut.nProfiles
657 self.metadata_dict['nProfiles'] = self.dataOut.nProfiles
659 self.metadata_dict['heightList'] = self.dataOut.heightList
658 self.metadata_dict['heightList'] = self.dataOut.heightList
660 self.metadata_dict['channelList'] = self.dataOut.channelList
659 self.metadata_dict['channelList'] = self.dataOut.channelList
661 self.metadata_dict['flagDecodeData'] = self.dataOut.flagDecodeData
660 self.metadata_dict['flagDecodeData'] = self.dataOut.flagDecodeData
662 self.metadata_dict['flagDeflipData'] = self.dataOut.flagDeflipData
661 self.metadata_dict['flagDeflipData'] = self.dataOut.flagDeflipData
663 self.metadata_dict['flagShiftFFT'] = self.dataOut.flagShiftFFT
662 self.metadata_dict['flagShiftFFT'] = self.dataOut.flagShiftFFT
664 self.metadata_dict['useLocalTime'] = self.dataOut.useLocalTime
663 self.metadata_dict['useLocalTime'] = self.dataOut.useLocalTime
665 self.metadata_dict['nCohInt'] = self.dataOut.nCohInt
664 self.metadata_dict['nCohInt'] = self.dataOut.nCohInt
666 self.metadata_dict['type'] = self.dataOut.type
665 self.metadata_dict['type'] = self.dataOut.type
667 self.metadata_dict['flagDataAsBlock'] = getattr(
666 self.metadata_dict['flagDataAsBlock'] = getattr(
668 self.dataOut, 'flagDataAsBlock', None) # chequear
667 self.dataOut, 'flagDataAsBlock', None) # chequear
669
668
670 def setup(self, dataOut, path, frequency, fileCadence, dirCadence, metadataCadence, set=0, metadataFile='metadata', ext='.h5'):
669 def setup(self, dataOut, path, frequency, fileCadence, dirCadence, metadataCadence, set=0, metadataFile='metadata', ext='.h5'):
671 '''
670 '''
672 In this method we should set all initial parameters.
671 In this method we should set all initial parameters.
673 Input:
672 Input:
674 dataOut: Input data will also be outputa data
673 dataOut: Input data will also be outputa data
675 '''
674 '''
676 self.setHeader()
675 self.setHeader()
677 self.__ippSeconds = dataOut.ippSeconds
676 self.__ippSeconds = dataOut.ippSeconds
678 self.__deltaH = dataOut.getDeltaH()
677 self.__deltaH = dataOut.getDeltaH()
679 self.__sample_rate = 1e6 * 0.15 / self.__deltaH
678 self.__sample_rate = 1e6 * 0.15 / self.__deltaH
680 self.__dtype = dataOut.dtype
679 self.__dtype = dataOut.dtype
681 if len(dataOut.dtype) == 2:
680 if len(dataOut.dtype) == 2:
682 self.__dtype = dataOut.dtype[0]
681 self.__dtype = dataOut.dtype[0]
683 self.__nSamples = dataOut.systemHeaderObj.nSamples
682 self.__nSamples = dataOut.systemHeaderObj.nSamples
684 self.__nProfiles = dataOut.nProfiles
683 self.__nProfiles = dataOut.nProfiles
685
684
686 if self.dataOut.type != 'Voltage':
685 if self.dataOut.type != 'Voltage':
687 raise 'Digital RF cannot be used with this data type'
686 raise 'Digital RF cannot be used with this data type'
688 self.arr_data = numpy.ones((1, dataOut.nFFTPoints * len(
687 self.arr_data = numpy.ones((1, dataOut.nFFTPoints * len(
689 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
688 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
690 else:
689 else:
691 self.arr_data = numpy.ones((self.__nSamples, len(
690 self.arr_data = numpy.ones((self.__nSamples, len(
692 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
691 self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)])
693
692
694 file_cadence_millisecs = 1000
693 file_cadence_millisecs = 1000
695
694
696 sample_rate_fraction = Fraction(self.__sample_rate).limit_denominator()
695 sample_rate_fraction = Fraction(self.__sample_rate).limit_denominator()
697 sample_rate_numerator = int(sample_rate_fraction.numerator)
696 sample_rate_numerator = int(sample_rate_fraction.numerator)
698 sample_rate_denominator = int(sample_rate_fraction.denominator)
697 sample_rate_denominator = int(sample_rate_fraction.denominator)
699 start_global_index = dataOut.utctime * self.__sample_rate
698 start_global_index = dataOut.utctime * self.__sample_rate
700
699
701 uuid = 'prueba'
700 uuid = 'prueba'
702 compression_level = 0
701 compression_level = 0
703 checksum = False
702 checksum = False
704 is_complex = True
703 is_complex = True
705 num_subchannels = len(dataOut.channelList)
704 num_subchannels = len(dataOut.channelList)
706 is_continuous = True
705 is_continuous = True
707 marching_periods = False
706 marching_periods = False
708
707
709 self.digitalWriteObj = digital_rf.DigitalRFWriter(path, self.__dtype, dirCadence,
708 self.digitalWriteObj = digital_rf.DigitalRFWriter(path, self.__dtype, dirCadence,
710 fileCadence, start_global_index,
709 fileCadence, start_global_index,
711 sample_rate_numerator, sample_rate_denominator, uuid, compression_level, checksum,
710 sample_rate_numerator, sample_rate_denominator, uuid, compression_level, checksum,
712 is_complex, num_subchannels, is_continuous, marching_periods)
711 is_complex, num_subchannels, is_continuous, marching_periods)
713 metadata_dir = os.path.join(path, 'metadata')
712 metadata_dir = os.path.join(path, 'metadata')
714 os.system('mkdir %s' % (metadata_dir))
713 os.system('mkdir %s' % (metadata_dir))
715 self.digitalMetadataWriteObj = digital_rf.DigitalMetadataWriter(metadata_dir, dirCadence, 1, # 236, file_cadence_millisecs / 1000
714 self.digitalMetadataWriteObj = digital_rf.DigitalMetadataWriter(metadata_dir, dirCadence, 1, # 236, file_cadence_millisecs / 1000
716 sample_rate_numerator, sample_rate_denominator,
715 sample_rate_numerator, sample_rate_denominator,
717 metadataFile)
716 metadataFile)
718 self.isConfig = True
717 self.isConfig = True
719 self.currentSample = 0
718 self.currentSample = 0
720 self.oldAverage = 0
719 self.oldAverage = 0
721 self.count = 0
720 self.count = 0
722 return
721 return
723
722
724 def writeMetadata(self):
723 def writeMetadata(self):
725 start_idx = self.__sample_rate * self.dataOut.utctime
724 start_idx = self.__sample_rate * self.dataOut.utctime
726
725
727 self.metadata_dict['processingHeader'] = self.dataOut.processingHeaderObj.getAsDict(
726 self.metadata_dict['processingHeader'] = self.dataOut.processingHeaderObj.getAsDict(
728 )
727 )
729 self.metadata_dict['radarControllerHeader'] = self.dataOut.radarControllerHeaderObj.getAsDict(
728 self.metadata_dict['radarControllerHeader'] = self.dataOut.radarControllerHeaderObj.getAsDict(
730 )
729 )
731 self.metadata_dict['systemHeader'] = self.dataOut.systemHeaderObj.getAsDict(
730 self.metadata_dict['systemHeader'] = self.dataOut.systemHeaderObj.getAsDict(
732 )
731 )
733 self.digitalMetadataWriteObj.write(start_idx, self.metadata_dict)
732 self.digitalMetadataWriteObj.write(start_idx, self.metadata_dict)
734 return
733 return
735
734
736 def timeit(self, toExecute):
735 def timeit(self, toExecute):
737 t0 = time()
736 t0 = time()
738 toExecute()
737 toExecute()
739 self.executionTime = time() - t0
738 self.executionTime = time() - t0
740 if self.oldAverage is None:
739 if self.oldAverage is None:
741 self.oldAverage = self.executionTime
740 self.oldAverage = self.executionTime
742 self.oldAverage = (self.executionTime + self.count *
741 self.oldAverage = (self.executionTime + self.count *
743 self.oldAverage) / (self.count + 1.0)
742 self.oldAverage) / (self.count + 1.0)
744 self.count = self.count + 1.0
743 self.count = self.count + 1.0
745 return
744 return
746
745
747 def writeData(self):
746 def writeData(self):
748 if self.dataOut.type != 'Voltage':
747 if self.dataOut.type != 'Voltage':
749 raise 'Digital RF cannot be used with this data type'
748 raise 'Digital RF cannot be used with this data type'
750 for channel in self.dataOut.channelList:
749 for channel in self.dataOut.channelList:
751 for i in range(self.dataOut.nFFTPoints):
750 for i in range(self.dataOut.nFFTPoints):
752 self.arr_data[1][channel * self.dataOut.nFFTPoints +
751 self.arr_data[1][channel * self.dataOut.nFFTPoints +
753 i]['r'] = self.dataOut.data[channel][i].real
752 i]['r'] = self.dataOut.data[channel][i].real
754 self.arr_data[1][channel * self.dataOut.nFFTPoints +
753 self.arr_data[1][channel * self.dataOut.nFFTPoints +
755 i]['i'] = self.dataOut.data[channel][i].imag
754 i]['i'] = self.dataOut.data[channel][i].imag
756 else:
755 else:
757 for i in range(self.dataOut.systemHeaderObj.nSamples):
756 for i in range(self.dataOut.systemHeaderObj.nSamples):
758 for channel in self.dataOut.channelList:
757 for channel in self.dataOut.channelList:
759 self.arr_data[i][channel]['r'] = self.dataOut.data[channel][i].real
758 self.arr_data[i][channel]['r'] = self.dataOut.data[channel][i].real
760 self.arr_data[i][channel]['i'] = self.dataOut.data[channel][i].imag
759 self.arr_data[i][channel]['i'] = self.dataOut.data[channel][i].imag
761
760
762 def f(): return self.digitalWriteObj.rf_write(self.arr_data)
761 def f(): return self.digitalWriteObj.rf_write(self.arr_data)
763 self.timeit(f)
762 self.timeit(f)
764
763
765 return
764 return
766
765
767 def run(self, dataOut, frequency=49.92e6, path=None, fileCadence=1000, dirCadence=36000, metadataCadence=1, **kwargs):
766 def run(self, dataOut, frequency=49.92e6, path=None, fileCadence=1000, dirCadence=36000, metadataCadence=1, **kwargs):
768 '''
767 '''
769 This method will be called many times so here you should put all your code
768 This method will be called many times so here you should put all your code
770 Inputs:
769 Inputs:
771 dataOut: object with the data
770 dataOut: object with the data
772 '''
771 '''
773 # print dataOut.__dict__
772 # print dataOut.__dict__
774 self.dataOut = dataOut
773 self.dataOut = dataOut
775 if not self.isConfig:
774 if not self.isConfig:
776 self.setup(dataOut, path, frequency, fileCadence,
775 self.setup(dataOut, path, frequency, fileCadence,
777 dirCadence, metadataCadence, **kwargs)
776 dirCadence, metadataCadence, **kwargs)
778 self.writeMetadata()
777 self.writeMetadata()
779
778
780 self.writeData()
779 self.writeData()
781
780
782 ## self.currentSample += 1
781 ## self.currentSample += 1
783 # if self.dataOut.flagDataAsBlock or self.currentSample == 1:
782 # if self.dataOut.flagDataAsBlock or self.currentSample == 1:
784 # self.writeMetadata()
783 # self.writeMetadata()
785 ## if self.currentSample == self.__nProfiles: self.currentSample = 0
784 ## if self.currentSample == self.__nProfiles: self.currentSample = 0
786
785
787 return dataOut
786 return dataOut
788
787
789 def close(self):
788 def close(self):
790 print('[Writing] - Closing files ')
789 print('[Writing] - Closing files ')
791 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
790 print('Average of writing to digital rf format is ', self.oldAverage * 1000)
792 try:
791 try:
793 self.digitalWriteObj.close()
792 self.digitalWriteObj.close()
794 except:
793 except:
795 pass
794 pass
796
795
797
796
@@ -1,642 +1,642
1 '''
1 '''
2 Created on Aug 1, 2017
2 Created on Aug 1, 2017
3
3
4 @author: Juan C. Espinoza
4 @author: Juan C. Espinoza
5 '''
5 '''
6
6
7 import os
7 import os
8 import sys
8 import sys
9 import time
9 import time
10 import json
10 import json
11 import glob
11 import glob
12 import datetime
12 import datetime
13
13
14 import numpy
14 import numpy
15 import h5py
15 import h5py
16
16
17 from schainpy.model.io.jroIO_base import JRODataReader
17 from schainpy.model.io.jroIO_base import JRODataReader
18 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
18 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
19 from schainpy.model.data.jrodata import Parameters
19 from schainpy.model.data.jrodata import Parameters
20 from schainpy.utils import log
20 from schainpy.utils import log
21
21
22 try:
22 try:
23 import madrigal.cedar
23 import madrigal.cedar
24 except:
24 except:
25 log.warning(
25 log.warning(
26 'You should install "madrigal library" module if you want to read/write Madrigal data'
26 'You should install "madrigal library" module if you want to read/write Madrigal data'
27 )
27 )
28
28
29 DEF_CATALOG = {
29 DEF_CATALOG = {
30 'principleInvestigator': 'Marco Milla',
30 'principleInvestigator': 'Marco Milla',
31 'expPurpose': None,
31 'expPurpose': None,
32 'cycleTime': None,
32 'cycleTime': None,
33 'correlativeExp': None,
33 'correlativeExp': None,
34 'sciRemarks': None,
34 'sciRemarks': None,
35 'instRemarks': None
35 'instRemarks': None
36 }
36 }
37 DEF_HEADER = {
37 DEF_HEADER = {
38 'kindatDesc': None,
38 'kindatDesc': None,
39 'analyst': 'Jicamarca User',
39 'analyst': 'Jicamarca User',
40 'comments': None,
40 'comments': None,
41 'history': None
41 'history': None
42 }
42 }
43 MNEMONICS = {
43 MNEMONICS = {
44 10: 'jro',
44 10: 'jro',
45 11: 'jbr',
45 11: 'jbr',
46 840: 'jul',
46 840: 'jul',
47 13: 'jas',
47 13: 'jas',
48 1000: 'pbr',
48 1000: 'pbr',
49 1001: 'hbr',
49 1001: 'hbr',
50 1002: 'obr',
50 1002: 'obr',
51 }
51 }
52
52
53 UT1970 = datetime.datetime(1970, 1, 1) - datetime.timedelta(seconds=time.timezone)
53 UT1970 = datetime.datetime(1970, 1, 1) - datetime.timedelta(seconds=time.timezone)
54
54
55 def load_json(obj):
55 def load_json(obj):
56 '''
56 '''
57 Parse json as string instead of unicode
57 Parse json as string instead of unicode
58 '''
58 '''
59
59
60 if isinstance(obj, str):
60 if isinstance(obj, str):
61 iterable = json.loads(obj)
61 iterable = json.loads(obj)
62 else:
62 else:
63 iterable = obj
63 iterable = obj
64
64
65 if isinstance(iterable, dict):
65 if isinstance(iterable, dict):
66 return {str(k): load_json(v) if isinstance(v, dict) else str(v) if isinstance(v, str) else v
66 return {str(k): load_json(v) if isinstance(v, dict) else str(v) if isinstance(v, str) else v
67 for k, v in list(iterable.items())}
67 for k, v in list(iterable.items())}
68 elif isinstance(iterable, (list, tuple)):
68 elif isinstance(iterable, (list, tuple)):
69 return [str(v) if isinstance(v, str) else v for v in iterable]
69 return [str(v) if isinstance(v, str) else v for v in iterable]
70
70
71 return iterable
71 return iterable
72
72
73 @MPDecorator
73 @MPDecorator
74 class MADReader(JRODataReader, ProcessingUnit):
74 class MADReader(JRODataReader, ProcessingUnit):
75
75
76 def __init__(self):
76 def __init__(self):
77
77
78 ProcessingUnit.__init__(self)
78 ProcessingUnit.__init__(self)
79
79
80 self.dataOut = Parameters()
80 self.dataOut = Parameters()
81 self.counter_records = 0
81 self.counter_records = 0
82 self.nrecords = None
82 self.nrecords = None
83 self.flagNoMoreFiles = 0
83 self.flagNoMoreFiles = 0
84 self.isConfig = False
84 self.isConfig = False
85 self.filename = None
85 self.filename = None
86 self.intervals = set()
86 self.intervals = set()
87
87
88 def setup(self,
88 def setup(self,
89 path=None,
89 path=None,
90 startDate=None,
90 startDate=None,
91 endDate=None,
91 endDate=None,
92 format=None,
92 format=None,
93 startTime=datetime.time(0, 0, 0),
93 startTime=datetime.time(0, 0, 0),
94 endTime=datetime.time(23, 59, 59),
94 endTime=datetime.time(23, 59, 59),
95 **kwargs):
95 **kwargs):
96
96
97 self.path = path
97 self.path = path
98 self.startDate = startDate
98 self.startDate = startDate
99 self.endDate = endDate
99 self.endDate = endDate
100 self.startTime = startTime
100 self.startTime = startTime
101 self.endTime = endTime
101 self.endTime = endTime
102 self.datatime = datetime.datetime(1900,1,1)
102 self.datatime = datetime.datetime(1900,1,1)
103 self.oneDDict = load_json(kwargs.get('oneDDict',
103 self.oneDDict = load_json(kwargs.get('oneDDict',
104 "{\"GDLATR\":\"lat\", \"GDLONR\":\"lon\"}"))
104 "{\"GDLATR\":\"lat\", \"GDLONR\":\"lon\"}"))
105 self.twoDDict = load_json(kwargs.get('twoDDict',
105 self.twoDDict = load_json(kwargs.get('twoDDict',
106 "{\"GDALT\": \"heightList\"}"))
106 "{\"GDALT\": \"heightList\"}"))
107 self.ind2DList = load_json(kwargs.get('ind2DList',
107 self.ind2DList = load_json(kwargs.get('ind2DList',
108 "[\"GDALT\"]"))
108 "[\"GDALT\"]"))
109 if self.path is None:
109 if self.path is None:
110 raise ValueError('The path is not valid')
110 raise ValueError('The path is not valid')
111
111
112 if format is None:
112 if format is None:
113 raise ValueError('The format is not valid choose simple or hdf5')
113 raise ValueError('The format is not valid choose simple or hdf5')
114 elif format.lower() in ('simple', 'txt'):
114 elif format.lower() in ('simple', 'txt'):
115 self.ext = '.txt'
115 self.ext = '.txt'
116 elif format.lower() in ('cedar',):
116 elif format.lower() in ('cedar',):
117 self.ext = '.001'
117 self.ext = '.001'
118 else:
118 else:
119 self.ext = '.hdf5'
119 self.ext = '.hdf5'
120
120
121 self.search_files(self.path)
121 self.search_files(self.path)
122 self.fileId = 0
122 self.fileId = 0
123
123
124 if not self.fileList:
124 if not self.fileList:
125 raise Warning('There is no files matching these date in the folder: {}. \n Check startDate and endDate'.format(path))
125 raise Warning('There is no files matching these date in the folder: {}. \n Check startDate and endDate'.format(path))
126
126
127 self.setNextFile()
127 self.setNextFile()
128
128
129 def search_files(self, path):
129 def search_files(self, path):
130 '''
130 '''
131 Searching for madrigal files in path
131 Searching for madrigal files in path
132 Creating a list of files to procces included in [startDate,endDate]
132 Creating a list of files to procces included in [startDate,endDate]
133
133
134 Input:
134 Input:
135 path - Path to find files
135 path - Path to find files
136 '''
136 '''
137
137
138 log.log('Searching files {} in {} '.format(self.ext, path), 'MADReader')
138 log.log('Searching files {} in {} '.format(self.ext, path), 'MADReader')
139 foldercounter = 0
139 foldercounter = 0
140 fileList0 = glob.glob1(path, '*{}'.format(self.ext))
140 fileList0 = glob.glob1(path, '*{}'.format(self.ext))
141 fileList0.sort()
141 fileList0.sort()
142
142
143 self.fileList = []
143 self.fileList = []
144 self.dateFileList = []
144 self.dateFileList = []
145
145
146 startDate = self.startDate - datetime.timedelta(1)
146 startDate = self.startDate - datetime.timedelta(1)
147 endDate = self.endDate + datetime.timedelta(1)
147 endDate = self.endDate + datetime.timedelta(1)
148
148
149 for thisFile in fileList0:
149 for thisFile in fileList0:
150 year = thisFile[3:7]
150 year = thisFile[3:7]
151 if not year.isdigit():
151 if not year.isdigit():
152 continue
152 continue
153
153
154 month = thisFile[7:9]
154 month = thisFile[7:9]
155 if not month.isdigit():
155 if not month.isdigit():
156 continue
156 continue
157
157
158 day = thisFile[9:11]
158 day = thisFile[9:11]
159 if not day.isdigit():
159 if not day.isdigit():
160 continue
160 continue
161
161
162 year, month, day = int(year), int(month), int(day)
162 year, month, day = int(year), int(month), int(day)
163 dateFile = datetime.date(year, month, day)
163 dateFile = datetime.date(year, month, day)
164
164
165 if (startDate > dateFile) or (endDate < dateFile):
165 if (startDate > dateFile) or (endDate < dateFile):
166 continue
166 continue
167
167
168 self.fileList.append(thisFile)
168 self.fileList.append(thisFile)
169 self.dateFileList.append(dateFile)
169 self.dateFileList.append(dateFile)
170
170
171 return
171 return
172
172
173 def parseHeader(self):
173 def parseHeader(self):
174 '''
174 '''
175 '''
175 '''
176
176
177 self.output = {}
177 self.output = {}
178 self.version = '2'
178 self.version = '2'
179 s_parameters = None
179 s_parameters = None
180 if self.ext == '.txt':
180 if self.ext == '.txt':
181 self.parameters = [s.strip().lower() for s in self.fp.readline().strip().split(' ') if s]
181 self.parameters = [s.strip().lower() for s in self.fp.readline().strip().split(' ') if s]
182 elif self.ext == '.hdf5':
182 elif self.ext == '.hdf5':
183 metadata = self.fp['Metadata']
183 metadata = self.fp['Metadata']
184 data = self.fp['Data']['Array Layout']
184 data = self.fp['Data']['Array Layout']
185 if 'Independent Spatial Parameters' in metadata:
185 if 'Independent Spatial Parameters' in metadata:
186 s_parameters = [s[0].lower() for s in metadata['Independent Spatial Parameters']]
186 s_parameters = [s[0].lower() for s in metadata['Independent Spatial Parameters']]
187 self.version = '3'
187 self.version = '3'
188 one = [s[0].lower() for s in data['1D Parameters']['Data Parameters']]
188 one = [s[0].lower() for s in data['1D Parameters']['Data Parameters']]
189 one_d = [1 for s in one]
189 one_d = [1 for s in one]
190 two = [s[0].lower() for s in data['2D Parameters']['Data Parameters']]
190 two = [s[0].lower() for s in data['2D Parameters']['Data Parameters']]
191 two_d = [2 for s in two]
191 two_d = [2 for s in two]
192 self.parameters = one + two
192 self.parameters = one + two
193 self.parameters_d = one_d + two_d
193 self.parameters_d = one_d + two_d
194
194
195 log.success('Parameters found: {}'.format(','.join(self.parameters)),
195 log.success('Parameters found: {}'.format(','.join(self.parameters)),
196 'MADReader')
196 'MADReader')
197 if s_parameters:
197 if s_parameters:
198 log.success('Spatial parameters: {}'.format(','.join(s_parameters)),
198 log.success('Spatial parameters: {}'.format(','.join(s_parameters)),
199 'MADReader')
199 'MADReader')
200
200
201 for param in list(self.oneDDict.keys()):
201 for param in list(self.oneDDict.keys()):
202 if param.lower() not in self.parameters:
202 if param.lower() not in self.parameters:
203 log.warning(
203 log.warning(
204 'Parameter {} not found will be ignored'.format(
204 'Parameter {} not found will be ignored'.format(
205 param),
205 param),
206 'MADReader')
206 'MADReader')
207 self.oneDDict.pop(param, None)
207 self.oneDDict.pop(param, None)
208
208
209 for param, value in list(self.twoDDict.items()):
209 for param, value in list(self.twoDDict.items()):
210 if param.lower() not in self.parameters:
210 if param.lower() not in self.parameters:
211 log.warning(
211 log.warning(
212 'Parameter {} not found, it will be ignored'.format(
212 'Parameter {} not found, it will be ignored'.format(
213 param),
213 param),
214 'MADReader')
214 'MADReader')
215 self.twoDDict.pop(param, None)
215 self.twoDDict.pop(param, None)
216 continue
216 continue
217 if isinstance(value, list):
217 if isinstance(value, list):
218 if value[0] not in self.output:
218 if value[0] not in self.output:
219 self.output[value[0]] = []
219 self.output[value[0]] = []
220 self.output[value[0]].append(None)
220 self.output[value[0]].append(None)
221
221
222 def parseData(self):
222 def parseData(self):
223 '''
223 '''
224 '''
224 '''
225
225
226 if self.ext == '.txt':
226 if self.ext == '.txt':
227 self.data = numpy.genfromtxt(self.fp, missing_values=('missing'))
227 self.data = numpy.genfromtxt(self.fp, missing_values=('missing'))
228 self.nrecords = self.data.shape[0]
228 self.nrecords = self.data.shape[0]
229 self.ranges = numpy.unique(self.data[:,self.parameters.index(self.ind2DList[0].lower())])
229 self.ranges = numpy.unique(self.data[:,self.parameters.index(self.ind2DList[0].lower())])
230 elif self.ext == '.hdf5':
230 elif self.ext == '.hdf5':
231 self.data = self.fp['Data']['Array Layout']
231 self.data = self.fp['Data']['Array Layout']
232 self.nrecords = len(self.data['timestamps'].value)
232 self.nrecords = len(self.data['timestamps'].value)
233 self.ranges = self.data['range'].value
233 self.ranges = self.data['range'].value
234
234
235 def setNextFile(self):
235 def setNextFile(self):
236 '''
236 '''
237 '''
237 '''
238
238
239 file_id = self.fileId
239 file_id = self.fileId
240
240
241 if file_id == len(self.fileList):
241 if file_id == len(self.fileList):
242 log.success('No more files', 'MADReader')
242 log.success('No more files', 'MADReader')
243 self.flagNoMoreFiles = 1
243 self.flagNoMoreFiles = 1
244 return 0
244 return 0
245
245
246 log.success(
246 log.success(
247 'Opening: {}'.format(self.fileList[file_id]),
247 'Opening: {}'.format(self.fileList[file_id]),
248 'MADReader'
248 'MADReader'
249 )
249 )
250
250
251 filename = os.path.join(self.path, self.fileList[file_id])
251 filename = os.path.join(self.path, self.fileList[file_id])
252
252
253 if self.filename is not None:
253 if self.filename is not None:
254 self.fp.close()
254 self.fp.close()
255
255
256 self.filename = filename
256 self.filename = filename
257 self.filedate = self.dateFileList[file_id]
257 self.filedate = self.dateFileList[file_id]
258
258
259 if self.ext=='.hdf5':
259 if self.ext=='.hdf5':
260 self.fp = h5py.File(self.filename, 'r')
260 self.fp = h5py.File(self.filename, 'r')
261 else:
261 else:
262 self.fp = open(self.filename, 'rb')
262 self.fp = open(self.filename, 'rb')
263
263
264 self.parseHeader()
264 self.parseHeader()
265 self.parseData()
265 self.parseData()
266 self.sizeOfFile = os.path.getsize(self.filename)
266 self.sizeOfFile = os.path.getsize(self.filename)
267 self.counter_records = 0
267 self.counter_records = 0
268 self.flagIsNewFile = 0
268 self.flagIsNewFile = 0
269 self.fileId += 1
269 self.fileId += 1
270
270
271 return 1
271 return 1
272
272
273 def readNextBlock(self):
273 def readNextBlock(self):
274
274
275 while True:
275 while True:
276 self.flagDiscontinuousBlock = 0
276 self.flagDiscontinuousBlock = 0
277 if self.flagIsNewFile:
277 if self.flagIsNewFile:
278 if not self.setNextFile():
278 if not self.setNextFile():
279 return 0
279 return 0
280
280
281 self.readBlock()
281 self.readBlock()
282
282
283 if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \
283 if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \
284 (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
284 (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
285 log.warning(
285 log.warning(
286 'Reading Record No. {}/{} -> {} [Skipping]'.format(
286 'Reading Record No. {}/{} -> {} [Skipping]'.format(
287 self.counter_records,
287 self.counter_records,
288 self.nrecords,
288 self.nrecords,
289 self.datatime.ctime()),
289 self.datatime.ctime()),
290 'MADReader')
290 'MADReader')
291 continue
291 continue
292 break
292 break
293
293
294 log.log(
294 log.log(
295 'Reading Record No. {}/{} -> {}'.format(
295 'Reading Record No. {}/{} -> {}'.format(
296 self.counter_records,
296 self.counter_records,
297 self.nrecords,
297 self.nrecords,
298 self.datatime.ctime()),
298 self.datatime.ctime()),
299 'MADReader')
299 'MADReader')
300
300
301 return 1
301 return 1
302
302
303 def readBlock(self):
303 def readBlock(self):
304 '''
304 '''
305 '''
305 '''
306 dum = []
306 dum = []
307 if self.ext == '.txt':
307 if self.ext == '.txt':
308 dt = self.data[self.counter_records][:6].astype(int)
308 dt = self.data[self.counter_records][:6].astype(int)
309 if datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5]).date() > self.datatime.date():
309 if datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5]).date() > self.datatime.date():
310 self.flagDiscontinuousBlock = 1
310 self.flagDiscontinuousBlock = 1
311 self.datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
311 self.datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
312 while True:
312 while True:
313 dt = self.data[self.counter_records][:6].astype(int)
313 dt = self.data[self.counter_records][:6].astype(int)
314 datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
314 datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5])
315 if datatime == self.datatime:
315 if datatime == self.datatime:
316 dum.append(self.data[self.counter_records])
316 dum.append(self.data[self.counter_records])
317 self.counter_records += 1
317 self.counter_records += 1
318 if self.counter_records == self.nrecords:
318 if self.counter_records == self.nrecords:
319 self.flagIsNewFile = True
319 self.flagIsNewFile = True
320 break
320 break
321 continue
321 continue
322 self.intervals.add((datatime-self.datatime).seconds)
322 self.intervals.add((datatime-self.datatime).seconds)
323 break
323 break
324 elif self.ext == '.hdf5':
324 elif self.ext == '.hdf5':
325 datatime = datetime.datetime.utcfromtimestamp(
325 datatime = datetime.datetime.utcfromtimestamp(
326 self.data['timestamps'][self.counter_records])
326 self.data['timestamps'][self.counter_records])
327 nHeights = len(self.ranges)
327 nHeights = len(self.ranges)
328 for n, param in enumerate(self.parameters):
328 for n, param in enumerate(self.parameters):
329 if self.parameters_d[n] == 1:
329 if self.parameters_d[n] == 1:
330 dum.append(numpy.ones(nHeights)*self.data['1D Parameters'][param][self.counter_records])
330 dum.append(numpy.ones(nHeights)*self.data['1D Parameters'][param][self.counter_records])
331 else:
331 else:
332 if self.version == '2':
332 if self.version == '2':
333 dum.append(self.data['2D Parameters'][param][self.counter_records])
333 dum.append(self.data['2D Parameters'][param][self.counter_records])
334 else:
334 else:
335 tmp = self.data['2D Parameters'][param].value.T
335 tmp = self.data['2D Parameters'][param].value.T
336 dum.append(tmp[self.counter_records])
336 dum.append(tmp[self.counter_records])
337 self.intervals.add((datatime-self.datatime).seconds)
337 self.intervals.add((datatime-self.datatime).seconds)
338 if datatime.date()>self.datatime.date():
338 if datatime.date()>self.datatime.date():
339 self.flagDiscontinuousBlock = 1
339 self.flagDiscontinuousBlock = 1
340 self.datatime = datatime
340 self.datatime = datatime
341 self.counter_records += 1
341 self.counter_records += 1
342 if self.counter_records == self.nrecords:
342 if self.counter_records == self.nrecords:
343 self.flagIsNewFile = True
343 self.flagIsNewFile = True
344
344
345 self.buffer = numpy.array(dum)
345 self.buffer = numpy.array(dum)
346 return
346 return
347
347
348 def set_output(self):
348 def set_output(self):
349 '''
349 '''
350 Storing data from buffer to dataOut object
350 Storing data from buffer to dataOut object
351 '''
351 '''
352
352
353 parameters = [None for __ in self.parameters]
353 parameters = [None for __ in self.parameters]
354
354
355 for param, attr in list(self.oneDDict.items()):
355 for param, attr in list(self.oneDDict.items()):
356 x = self.parameters.index(param.lower())
356 x = self.parameters.index(param.lower())
357 setattr(self.dataOut, attr, self.buffer[0][x])
357 setattr(self.dataOut, attr, self.buffer[0][x])
358
358
359 for param, value in list(self.twoDDict.items()):
359 for param, value in list(self.twoDDict.items()):
360 x = self.parameters.index(param.lower())
360 x = self.parameters.index(param.lower())
361 if self.ext == '.txt':
361 if self.ext == '.txt':
362 y = self.parameters.index(self.ind2DList[0].lower())
362 y = self.parameters.index(self.ind2DList[0].lower())
363 ranges = self.buffer[:,y]
363 ranges = self.buffer[:,y]
364 if self.ranges.size == ranges.size:
364 if self.ranges.size == ranges.size:
365 continue
365 continue
366 index = numpy.where(numpy.in1d(self.ranges, ranges))[0]
366 index = numpy.where(numpy.in1d(self.ranges, ranges))[0]
367 dummy = numpy.zeros(self.ranges.shape) + numpy.nan
367 dummy = numpy.zeros(self.ranges.shape) + numpy.nan
368 dummy[index] = self.buffer[:,x]
368 dummy[index] = self.buffer[:,x]
369 else:
369 else:
370 dummy = self.buffer[x]
370 dummy = self.buffer[x]
371
371
372 if isinstance(value, str):
372 if isinstance(value, str):
373 if value not in self.ind2DList:
373 if value not in self.ind2DList:
374 setattr(self.dataOut, value, dummy.reshape(1,-1))
374 setattr(self.dataOut, value, dummy.reshape(1,-1))
375 elif isinstance(value, list):
375 elif isinstance(value, list):
376 self.output[value[0]][value[1]] = dummy
376 self.output[value[0]][value[1]] = dummy
377 parameters[value[1]] = param
377 parameters[value[1]] = param
378
378
379 for key, value in list(self.output.items()):
379 for key, value in list(self.output.items()):
380 setattr(self.dataOut, key, numpy.array(value))
380 setattr(self.dataOut, key, numpy.array(value))
381
381
382 self.dataOut.parameters = [s for s in parameters if s]
382 self.dataOut.parameters = [s for s in parameters if s]
383 self.dataOut.heightList = self.ranges
383 self.dataOut.heightList = self.ranges
384 self.dataOut.utctime = (self.datatime - datetime.datetime(1970, 1, 1)).total_seconds()
384 self.dataOut.utctime = (self.datatime - datetime.datetime(1970, 1, 1)).total_seconds()
385 self.dataOut.utctimeInit = self.dataOut.utctime
385 self.dataOut.utctimeInit = self.dataOut.utctime
386 self.dataOut.paramInterval = min(self.intervals)
386 self.dataOut.paramInterval = min(self.intervals)
387 self.dataOut.useLocalTime = False
387 self.dataOut.useLocalTime = False
388 self.dataOut.flagNoData = False
388 self.dataOut.flagNoData = False
389 self.dataOut.nrecords = self.nrecords
389 self.dataOut.nrecords = self.nrecords
390 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
390 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
391
391
392 def getData(self):
392 def getData(self):
393 '''
393 '''
394 Storing data from databuffer to dataOut object
394 Storing data from databuffer to dataOut object
395 '''
395 '''
396 if self.flagNoMoreFiles:
396 if self.flagNoMoreFiles:
397 self.dataOut.flagNoData = True
397 self.dataOut.flagNoData = True
398 log.error('No file left to process', 'MADReader')
398 self.dataOut.error = 'No file left to process'
399 return 0
399 return 0
400
400
401 if not self.readNextBlock():
401 if not self.readNextBlock():
402 self.dataOut.flagNoData = True
402 self.dataOut.flagNoData = True
403 return 0
403 return 0
404
404
405 self.set_output()
405 self.set_output()
406
406
407 return 1
407 return 1
408
408
409
409
410 class MADWriter(Operation):
410 class MADWriter(Operation):
411
411
412 missing = -32767
412 missing = -32767
413
413
414 def __init__(self, **kwargs):
414 def __init__(self, **kwargs):
415
415
416 Operation.__init__(self, **kwargs)
416 Operation.__init__(self, **kwargs)
417 self.dataOut = Parameters()
417 self.dataOut = Parameters()
418 self.counter = 0
418 self.counter = 0
419 self.path = None
419 self.path = None
420 self.fp = None
420 self.fp = None
421
421
422 def run(self, dataOut, path, oneDDict, ind2DList='[]', twoDDict='{}',
422 def run(self, dataOut, path, oneDDict, ind2DList='[]', twoDDict='{}',
423 metadata='{}', format='cedar', **kwargs):
423 metadata='{}', format='cedar', **kwargs):
424 '''
424 '''
425 Inputs:
425 Inputs:
426 path - path where files will be created
426 path - path where files will be created
427 oneDDict - json of one-dimensional parameters in record where keys
427 oneDDict - json of one-dimensional parameters in record where keys
428 are Madrigal codes (integers or mnemonics) and values the corresponding
428 are Madrigal codes (integers or mnemonics) and values the corresponding
429 dataOut attribute e.g: {
429 dataOut attribute e.g: {
430 'gdlatr': 'lat',
430 'gdlatr': 'lat',
431 'gdlonr': 'lon',
431 'gdlonr': 'lon',
432 'gdlat2':'lat',
432 'gdlat2':'lat',
433 'glon2':'lon'}
433 'glon2':'lon'}
434 ind2DList - list of independent spatial two-dimensional parameters e.g:
434 ind2DList - list of independent spatial two-dimensional parameters e.g:
435 ['heighList']
435 ['heighList']
436 twoDDict - json of two-dimensional parameters in record where keys
436 twoDDict - json of two-dimensional parameters in record where keys
437 are Madrigal codes (integers or mnemonics) and values the corresponding
437 are Madrigal codes (integers or mnemonics) and values the corresponding
438 dataOut attribute if multidimensional array specify as tupple
438 dataOut attribute if multidimensional array specify as tupple
439 ('attr', pos) e.g: {
439 ('attr', pos) e.g: {
440 'gdalt': 'heightList',
440 'gdalt': 'heightList',
441 'vn1p2': ('data_output', 0),
441 'vn1p2': ('data_output', 0),
442 'vn2p2': ('data_output', 1),
442 'vn2p2': ('data_output', 1),
443 'vn3': ('data_output', 2),
443 'vn3': ('data_output', 2),
444 'snl': ('data_SNR', 'db')
444 'snl': ('data_SNR', 'db')
445 }
445 }
446 metadata - json of madrigal metadata (kinst, kindat, catalog and header)
446 metadata - json of madrigal metadata (kinst, kindat, catalog and header)
447 '''
447 '''
448 if not self.isConfig:
448 if not self.isConfig:
449 self.setup(path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs)
449 self.setup(path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs)
450 self.isConfig = True
450 self.isConfig = True
451
451
452 self.dataOut = dataOut
452 self.dataOut = dataOut
453 self.putData()
453 self.putData()
454 return
454 return
455
455
456 def setup(self, path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs):
456 def setup(self, path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs):
457 '''
457 '''
458 Configure Operation
458 Configure Operation
459 '''
459 '''
460
460
461 self.path = path
461 self.path = path
462 self.blocks = kwargs.get('blocks', None)
462 self.blocks = kwargs.get('blocks', None)
463 self.counter = 0
463 self.counter = 0
464 self.oneDDict = load_json(oneDDict)
464 self.oneDDict = load_json(oneDDict)
465 self.twoDDict = load_json(twoDDict)
465 self.twoDDict = load_json(twoDDict)
466 self.ind2DList = load_json(ind2DList)
466 self.ind2DList = load_json(ind2DList)
467 meta = load_json(metadata)
467 meta = load_json(metadata)
468 self.kinst = meta.get('kinst')
468 self.kinst = meta.get('kinst')
469 self.kindat = meta.get('kindat')
469 self.kindat = meta.get('kindat')
470 self.catalog = meta.get('catalog', DEF_CATALOG)
470 self.catalog = meta.get('catalog', DEF_CATALOG)
471 self.header = meta.get('header', DEF_HEADER)
471 self.header = meta.get('header', DEF_HEADER)
472 if format == 'cedar':
472 if format == 'cedar':
473 self.ext = '.dat'
473 self.ext = '.dat'
474 self.extra_args = {}
474 self.extra_args = {}
475 elif format == 'hdf5':
475 elif format == 'hdf5':
476 self.ext = '.hdf5'
476 self.ext = '.hdf5'
477 self.extra_args = {'ind2DList': self.ind2DList}
477 self.extra_args = {'ind2DList': self.ind2DList}
478
478
479 self.keys = [k.lower() for k in self.twoDDict]
479 self.keys = [k.lower() for k in self.twoDDict]
480 if 'range' in self.keys:
480 if 'range' in self.keys:
481 self.keys.remove('range')
481 self.keys.remove('range')
482 if 'gdalt' in self.keys:
482 if 'gdalt' in self.keys:
483 self.keys.remove('gdalt')
483 self.keys.remove('gdalt')
484
484
485 def setFile(self):
485 def setFile(self):
486 '''
486 '''
487 Create new cedar file object
487 Create new cedar file object
488 '''
488 '''
489
489
490 self.mnemonic = MNEMONICS[self.kinst] #TODO get mnemonic from madrigal
490 self.mnemonic = MNEMONICS[self.kinst] #TODO get mnemonic from madrigal
491 date = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
491 date = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
492
492
493 filename = '{}{}{}'.format(self.mnemonic,
493 filename = '{}{}{}'.format(self.mnemonic,
494 date.strftime('%Y%m%d_%H%M%S'),
494 date.strftime('%Y%m%d_%H%M%S'),
495 self.ext)
495 self.ext)
496
496
497 self.fullname = os.path.join(self.path, filename)
497 self.fullname = os.path.join(self.path, filename)
498
498
499 if os.path.isfile(self.fullname) :
499 if os.path.isfile(self.fullname) :
500 log.warning(
500 log.warning(
501 'Destination file {} already exists, previous file deleted.'.format(
501 'Destination file {} already exists, previous file deleted.'.format(
502 self.fullname),
502 self.fullname),
503 'MADWriter')
503 'MADWriter')
504 os.remove(self.fullname)
504 os.remove(self.fullname)
505
505
506 try:
506 try:
507 log.success(
507 log.success(
508 'Creating file: {}'.format(self.fullname),
508 'Creating file: {}'.format(self.fullname),
509 'MADWriter')
509 'MADWriter')
510 self.fp = madrigal.cedar.MadrigalCedarFile(self.fullname, True)
510 self.fp = madrigal.cedar.MadrigalCedarFile(self.fullname, True)
511 except ValueError as e:
511 except ValueError as e:
512 log.error(
512 log.error(
513 'Impossible to create a cedar object with "madrigal.cedar.MadrigalCedarFile"',
513 'Impossible to create a cedar object with "madrigal.cedar.MadrigalCedarFile"',
514 'MADWriter')
514 'MADWriter')
515 return
515 return
516
516
517 return 1
517 return 1
518
518
519 def writeBlock(self):
519 def writeBlock(self):
520 '''
520 '''
521 Add data records to cedar file taking data from oneDDict and twoDDict
521 Add data records to cedar file taking data from oneDDict and twoDDict
522 attributes.
522 attributes.
523 Allowed parameters in: parcodes.tab
523 Allowed parameters in: parcodes.tab
524 '''
524 '''
525
525
526 startTime = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
526 startTime = datetime.datetime.utcfromtimestamp(self.dataOut.utctime)
527 endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval)
527 endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval)
528 heights = self.dataOut.heightList
528 heights = self.dataOut.heightList
529
529
530 if self.ext == '.dat':
530 if self.ext == '.dat':
531 for key, value in list(self.twoDDict.items()):
531 for key, value in list(self.twoDDict.items()):
532 if isinstance(value, str):
532 if isinstance(value, str):
533 data = getattr(self.dataOut, value)
533 data = getattr(self.dataOut, value)
534 invalid = numpy.isnan(data)
534 invalid = numpy.isnan(data)
535 data[invalid] = self.missing
535 data[invalid] = self.missing
536 elif isinstance(value, (tuple, list)):
536 elif isinstance(value, (tuple, list)):
537 attr, key = value
537 attr, key = value
538 data = getattr(self.dataOut, attr)
538 data = getattr(self.dataOut, attr)
539 invalid = numpy.isnan(data)
539 invalid = numpy.isnan(data)
540 data[invalid] = self.missing
540 data[invalid] = self.missing
541
541
542 out = {}
542 out = {}
543 for key, value in list(self.twoDDict.items()):
543 for key, value in list(self.twoDDict.items()):
544 key = key.lower()
544 key = key.lower()
545 if isinstance(value, str):
545 if isinstance(value, str):
546 if 'db' in value.lower():
546 if 'db' in value.lower():
547 tmp = getattr(self.dataOut, value.replace('_db', ''))
547 tmp = getattr(self.dataOut, value.replace('_db', ''))
548 SNRavg = numpy.average(tmp, axis=0)
548 SNRavg = numpy.average(tmp, axis=0)
549 tmp = 10*numpy.log10(SNRavg)
549 tmp = 10*numpy.log10(SNRavg)
550 else:
550 else:
551 tmp = getattr(self.dataOut, value)
551 tmp = getattr(self.dataOut, value)
552 out[key] = tmp.flatten()
552 out[key] = tmp.flatten()
553 elif isinstance(value, (tuple, list)):
553 elif isinstance(value, (tuple, list)):
554 attr, x = value
554 attr, x = value
555 data = getattr(self.dataOut, attr)
555 data = getattr(self.dataOut, attr)
556 out[key] = data[int(x)]
556 out[key] = data[int(x)]
557
557
558 a = numpy.array([out[k] for k in self.keys])
558 a = numpy.array([out[k] for k in self.keys])
559 nrows = numpy.array([numpy.isnan(a[:, x]).all() for x in range(len(heights))])
559 nrows = numpy.array([numpy.isnan(a[:, x]).all() for x in range(len(heights))])
560 index = numpy.where(nrows == False)[0]
560 index = numpy.where(nrows == False)[0]
561
561
562 rec = madrigal.cedar.MadrigalDataRecord(
562 rec = madrigal.cedar.MadrigalDataRecord(
563 self.kinst,
563 self.kinst,
564 self.kindat,
564 self.kindat,
565 startTime.year,
565 startTime.year,
566 startTime.month,
566 startTime.month,
567 startTime.day,
567 startTime.day,
568 startTime.hour,
568 startTime.hour,
569 startTime.minute,
569 startTime.minute,
570 startTime.second,
570 startTime.second,
571 startTime.microsecond/10000,
571 startTime.microsecond/10000,
572 endTime.year,
572 endTime.year,
573 endTime.month,
573 endTime.month,
574 endTime.day,
574 endTime.day,
575 endTime.hour,
575 endTime.hour,
576 endTime.minute,
576 endTime.minute,
577 endTime.second,
577 endTime.second,
578 endTime.microsecond/10000,
578 endTime.microsecond/10000,
579 list(self.oneDDict.keys()),
579 list(self.oneDDict.keys()),
580 list(self.twoDDict.keys()),
580 list(self.twoDDict.keys()),
581 len(index),
581 len(index),
582 **self.extra_args
582 **self.extra_args
583 )
583 )
584
584
585 # Setting 1d values
585 # Setting 1d values
586 for key in self.oneDDict:
586 for key in self.oneDDict:
587 rec.set1D(key, getattr(self.dataOut, self.oneDDict[key]))
587 rec.set1D(key, getattr(self.dataOut, self.oneDDict[key]))
588
588
589 # Setting 2d values
589 # Setting 2d values
590 nrec = 0
590 nrec = 0
591 for n in index:
591 for n in index:
592 for key in out:
592 for key in out:
593 rec.set2D(key, nrec, out[key][n])
593 rec.set2D(key, nrec, out[key][n])
594 nrec += 1
594 nrec += 1
595
595
596 self.fp.append(rec)
596 self.fp.append(rec)
597 if self.ext == '.hdf5' and self.counter % 500 == 0 and self.counter > 0:
597 if self.ext == '.hdf5' and self.counter % 500 == 0 and self.counter > 0:
598 self.fp.dump()
598 self.fp.dump()
599 if self.counter % 100 == 0 and self.counter > 0:
599 if self.counter % 100 == 0 and self.counter > 0:
600 log.log(
600 log.log(
601 'Writing {} records'.format(
601 'Writing {} records'.format(
602 self.counter),
602 self.counter),
603 'MADWriter')
603 'MADWriter')
604
604
605 def setHeader(self):
605 def setHeader(self):
606 '''
606 '''
607 Create an add catalog and header to cedar file
607 Create an add catalog and header to cedar file
608 '''
608 '''
609
609
610 log.success('Closing file {}'.format(self.fullname), 'MADWriter')
610 log.success('Closing file {}'.format(self.fullname), 'MADWriter')
611
611
612 if self.ext == '.dat':
612 if self.ext == '.dat':
613 self.fp.write()
613 self.fp.write()
614 else:
614 else:
615 self.fp.dump()
615 self.fp.dump()
616 self.fp.close()
616 self.fp.close()
617
617
618 header = madrigal.cedar.CatalogHeaderCreator(self.fullname)
618 header = madrigal.cedar.CatalogHeaderCreator(self.fullname)
619 header.createCatalog(**self.catalog)
619 header.createCatalog(**self.catalog)
620 header.createHeader(**self.header)
620 header.createHeader(**self.header)
621 header.write()
621 header.write()
622
622
623 def putData(self):
623 def putData(self):
624
624
625 if self.dataOut.flagNoData:
625 if self.dataOut.flagNoData:
626 return 0
626 return 0
627
627
628 if self.dataOut.flagDiscontinuousBlock or self.counter == self.blocks:
628 if self.dataOut.flagDiscontinuousBlock or self.counter == self.blocks:
629 if self.counter > 0:
629 if self.counter > 0:
630 self.setHeader()
630 self.setHeader()
631 self.counter = 0
631 self.counter = 0
632
632
633 if self.counter == 0:
633 if self.counter == 0:
634 self.setFile()
634 self.setFile()
635
635
636 self.writeBlock()
636 self.writeBlock()
637 self.counter += 1
637 self.counter += 1
638
638
639 def close(self):
639 def close(self):
640
640
641 if self.counter > 0:
641 if self.counter > 0:
642 self.setHeader() No newline at end of file
642 self.setHeader()
@@ -1,1093 +1,1036
1 import numpy
1 import numpy
2 import time
2 import time
3 import os
3 import os
4 import h5py
4 import h5py
5 import re
5 import re
6 import datetime
6 import datetime
7
7
8 from schainpy.model.data.jrodata import *
8 from schainpy.model.data.jrodata import *
9 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
9 from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation, MPDecorator
10 # from .jroIO_base import *
10 # from .jroIO_base import *
11 from schainpy.model.io.jroIO_base import *
11 from schainpy.model.io.jroIO_base import *
12 import schainpy
12 import schainpy
13 from schainpy.utils import log
13 from schainpy.utils import log
14
14
15 @MPDecorator
15 @MPDecorator
16 class ParamReader(JRODataReader,ProcessingUnit):
16 class ParamReader(JRODataReader,ProcessingUnit):
17 '''
17 '''
18 Reads HDF5 format files
18 Reads HDF5 format files
19
19
20 path
20 path
21
21
22 startDate
22 startDate
23
23
24 endDate
24 endDate
25
25
26 startTime
26 startTime
27
27
28 endTime
28 endTime
29 '''
29 '''
30
30
31 ext = ".hdf5"
31 ext = ".hdf5"
32
32
33 optchar = "D"
33 optchar = "D"
34
34
35 timezone = None
35 timezone = None
36
36
37 startTime = None
37 startTime = None
38
38
39 endTime = None
39 endTime = None
40
40
41 fileIndex = None
41 fileIndex = None
42
42
43 utcList = None #To select data in the utctime list
43 utcList = None #To select data in the utctime list
44
44
45 blockList = None #List to blocks to be read from the file
45 blockList = None #List to blocks to be read from the file
46
46
47 blocksPerFile = None #Number of blocks to be read
47 blocksPerFile = None #Number of blocks to be read
48
48
49 blockIndex = None
49 blockIndex = None
50
50
51 path = None
51 path = None
52
52
53 #List of Files
53 #List of Files
54
54
55 filenameList = None
55 filenameList = None
56
56
57 datetimeList = None
57 datetimeList = None
58
58
59 #Hdf5 File
59 #Hdf5 File
60
60
61 listMetaname = None
61 listMetaname = None
62
62
63 listMeta = None
63 listMeta = None
64
64
65 listDataname = None
65 listDataname = None
66
66
67 listData = None
67 listData = None
68
68
69 listShapes = None
69 listShapes = None
70
70
71 fp = None
71 fp = None
72
72
73 #dataOut reconstruction
73 #dataOut reconstruction
74
74
75 dataOut = None
75 dataOut = None
76
76
77
77
78 def __init__(self):#, **kwargs):
78 def __init__(self):#, **kwargs):
79 ProcessingUnit.__init__(self) #, **kwargs)
79 ProcessingUnit.__init__(self) #, **kwargs)
80 self.dataOut = Parameters()
80 self.dataOut = Parameters()
81 return
81 return
82
82
83 def setup(self, **kwargs):
83 def setup(self, **kwargs):
84
84
85 path = kwargs['path']
85 path = kwargs['path']
86 startDate = kwargs['startDate']
86 startDate = kwargs['startDate']
87 endDate = kwargs['endDate']
87 endDate = kwargs['endDate']
88 startTime = kwargs['startTime']
88 startTime = kwargs['startTime']
89 endTime = kwargs['endTime']
89 endTime = kwargs['endTime']
90 walk = kwargs['walk']
90 walk = kwargs['walk']
91 if 'ext' in kwargs:
91 if 'ext' in kwargs:
92 ext = kwargs['ext']
92 ext = kwargs['ext']
93 else:
93 else:
94 ext = '.hdf5'
94 ext = '.hdf5'
95 if 'timezone' in kwargs:
95 if 'timezone' in kwargs:
96 self.timezone = kwargs['timezone']
96 self.timezone = kwargs['timezone']
97 else:
97 else:
98 self.timezone = 'lt'
98 self.timezone = 'lt'
99
99
100 print("[Reading] Searching files in offline mode ...")
100 print("[Reading] Searching files in offline mode ...")
101 pathList, filenameList = self.searchFilesOffLine(path, startDate=startDate, endDate=endDate,
101 pathList, filenameList = self.searchFilesOffLine(path, startDate=startDate, endDate=endDate,
102 startTime=startTime, endTime=endTime,
102 startTime=startTime, endTime=endTime,
103 ext=ext, walk=walk)
103 ext=ext, walk=walk)
104
104
105 if not(filenameList):
105 if not(filenameList):
106 print("There is no files into the folder: %s"%(path))
106 print("There is no files into the folder: %s"%(path))
107 sys.exit(-1)
107 sys.exit(-1)
108
108
109 self.fileIndex = -1
109 self.fileIndex = -1
110 self.startTime = startTime
110 self.startTime = startTime
111 self.endTime = endTime
111 self.endTime = endTime
112
112
113 self.__readMetadata()
113 self.__readMetadata()
114
114
115 self.__setNextFileOffline()
115 self.__setNextFileOffline()
116
116
117 return
117 return
118
118
119 def searchFilesOffLine(self,
119 def searchFilesOffLine(self,
120 path,
120 path,
121 startDate=None,
121 startDate=None,
122 endDate=None,
122 endDate=None,
123 startTime=datetime.time(0,0,0),
123 startTime=datetime.time(0,0,0),
124 endTime=datetime.time(23,59,59),
124 endTime=datetime.time(23,59,59),
125 ext='.hdf5',
125 ext='.hdf5',
126 walk=True):
126 walk=True):
127
127
128 expLabel = ''
128 expLabel = ''
129 self.filenameList = []
129 self.filenameList = []
130 self.datetimeList = []
130 self.datetimeList = []
131
131
132 pathList = []
132 pathList = []
133
133
134 JRODataObj = JRODataReader()
134 JRODataObj = JRODataReader()
135 dateList, pathList = JRODataObj.findDatafiles(path, startDate, endDate, expLabel, ext, walk, include_path=True)
135 dateList, pathList = JRODataObj.findDatafiles(path, startDate, endDate, expLabel, ext, walk, include_path=True)
136
136
137 if dateList == []:
137 if dateList == []:
138 print("[Reading] No *%s files in %s from %s to %s)"%(ext, path,
138 print("[Reading] No *%s files in %s from %s to %s)"%(ext, path,
139 datetime.datetime.combine(startDate,startTime).ctime(),
139 datetime.datetime.combine(startDate,startTime).ctime(),
140 datetime.datetime.combine(endDate,endTime).ctime()))
140 datetime.datetime.combine(endDate,endTime).ctime()))
141
141
142 return None, None
142 return None, None
143
143
144 if len(dateList) > 1:
144 if len(dateList) > 1:
145 print("[Reading] %d days were found in date range: %s - %s" %(len(dateList), startDate, endDate))
145 print("[Reading] %d days were found in date range: %s - %s" %(len(dateList), startDate, endDate))
146 else:
146 else:
147 print("[Reading] data was found for the date %s" %(dateList[0]))
147 print("[Reading] data was found for the date %s" %(dateList[0]))
148
148
149 filenameList = []
149 filenameList = []
150 datetimeList = []
150 datetimeList = []
151
151
152 #----------------------------------------------------------------------------------
152 #----------------------------------------------------------------------------------
153
153
154 for thisPath in pathList:
154 for thisPath in pathList:
155 # thisPath = pathList[pathDict[file]]
155 # thisPath = pathList[pathDict[file]]
156
156
157 fileList = glob.glob1(thisPath, "*%s" %ext)
157 fileList = glob.glob1(thisPath, "*%s" %ext)
158 fileList.sort()
158 fileList.sort()
159
159
160 for file in fileList:
160 for file in fileList:
161
161
162 filename = os.path.join(thisPath,file)
162 filename = os.path.join(thisPath,file)
163
163
164 if not isFileInDateRange(filename, startDate, endDate):
164 if not isFileInDateRange(filename, startDate, endDate):
165 continue
165 continue
166
166
167 thisDatetime = self.__isFileInTimeRange(filename, startDate, endDate, startTime, endTime)
167 thisDatetime = self.__isFileInTimeRange(filename, startDate, endDate, startTime, endTime)
168
168
169 if not(thisDatetime):
169 if not(thisDatetime):
170 continue
170 continue
171
171
172 filenameList.append(filename)
172 filenameList.append(filename)
173 datetimeList.append(thisDatetime)
173 datetimeList.append(thisDatetime)
174
174
175 if not(filenameList):
175 if not(filenameList):
176 print("[Reading] Any file was found int time range %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime()))
176 print("[Reading] Any file was found int time range %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime()))
177 return None, None
177 return None, None
178
178
179 print("[Reading] %d file(s) was(were) found in time range: %s - %s" %(len(filenameList), startTime, endTime))
179 print("[Reading] %d file(s) was(were) found in time range: %s - %s" %(len(filenameList), startTime, endTime))
180 print()
180 print()
181
181
182 self.filenameList = filenameList
182 self.filenameList = filenameList
183 self.datetimeList = datetimeList
183 self.datetimeList = datetimeList
184
184
185 return pathList, filenameList
185 return pathList, filenameList
186
186
187 def __isFileInTimeRange(self,filename, startDate, endDate, startTime, endTime):
187 def __isFileInTimeRange(self,filename, startDate, endDate, startTime, endTime):
188
188
189 """
189 """
190 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
190 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
191
191
192 Inputs:
192 Inputs:
193 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
193 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
194
194
195 startDate : fecha inicial del rango seleccionado en formato datetime.date
195 startDate : fecha inicial del rango seleccionado en formato datetime.date
196
196
197 endDate : fecha final del rango seleccionado en formato datetime.date
197 endDate : fecha final del rango seleccionado en formato datetime.date
198
198
199 startTime : tiempo inicial del rango seleccionado en formato datetime.time
199 startTime : tiempo inicial del rango seleccionado en formato datetime.time
200
200
201 endTime : tiempo final del rango seleccionado en formato datetime.time
201 endTime : tiempo final del rango seleccionado en formato datetime.time
202
202
203 Return:
203 Return:
204 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
204 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
205 fecha especificado, de lo contrario retorna False.
205 fecha especificado, de lo contrario retorna False.
206
206
207 Excepciones:
207 Excepciones:
208 Si el archivo no existe o no puede ser abierto
208 Si el archivo no existe o no puede ser abierto
209 Si la cabecera no puede ser leida.
209 Si la cabecera no puede ser leida.
210
210
211 """
211 """
212
212
213 try:
213 try:
214 fp = h5py.File(filename,'r')
214 fp = h5py.File(filename,'r')
215 grp1 = fp['Data']
215 grp1 = fp['Data']
216
216
217 except IOError:
217 except IOError:
218 traceback.print_exc()
218 traceback.print_exc()
219 raise IOError("The file %s can't be opened" %(filename))
219 raise IOError("The file %s can't be opened" %(filename))
220 #chino rata
220 #chino rata
221 #In case has utctime attribute
221 #In case has utctime attribute
222 grp2 = grp1['utctime']
222 grp2 = grp1['utctime']
223 # thisUtcTime = grp2.value[0] - 5*3600 #To convert to local time
223 # thisUtcTime = grp2.value[0] - 5*3600 #To convert to local time
224 thisUtcTime = grp2.value[0]
224 thisUtcTime = grp2.value[0]
225
225
226 fp.close()
226 fp.close()
227
227
228 if self.timezone == 'lt':
228 if self.timezone == 'lt':
229 thisUtcTime -= 5*3600
229 thisUtcTime -= 5*3600
230
230
231 thisDatetime = datetime.datetime.fromtimestamp(thisUtcTime[0] + 5*3600)
231 thisDatetime = datetime.datetime.fromtimestamp(thisUtcTime[0] + 5*3600)
232 # thisDatetime = datetime.datetime.fromtimestamp(thisUtcTime[0])
232 # thisDatetime = datetime.datetime.fromtimestamp(thisUtcTime[0])
233 thisDate = thisDatetime.date()
233 thisDate = thisDatetime.date()
234 thisTime = thisDatetime.time()
234 thisTime = thisDatetime.time()
235
235
236 startUtcTime = (datetime.datetime.combine(thisDate,startTime)- datetime.datetime(1970, 1, 1)).total_seconds()
236 startUtcTime = (datetime.datetime.combine(thisDate,startTime)- datetime.datetime(1970, 1, 1)).total_seconds()
237 endUtcTime = (datetime.datetime.combine(thisDate,endTime)- datetime.datetime(1970, 1, 1)).total_seconds()
237 endUtcTime = (datetime.datetime.combine(thisDate,endTime)- datetime.datetime(1970, 1, 1)).total_seconds()
238
238
239 #General case
239 #General case
240 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
240 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
241 #-----------o----------------------------o-----------
241 #-----------o----------------------------o-----------
242 # startTime endTime
242 # startTime endTime
243
243
244 if endTime >= startTime:
244 if endTime >= startTime:
245 thisUtcLog = numpy.logical_and(thisUtcTime > startUtcTime, thisUtcTime < endUtcTime)
245 thisUtcLog = numpy.logical_and(thisUtcTime > startUtcTime, thisUtcTime < endUtcTime)
246 if numpy.any(thisUtcLog): #If there is one block between the hours mentioned
246 if numpy.any(thisUtcLog): #If there is one block between the hours mentioned
247 return thisDatetime
247 return thisDatetime
248 return None
248 return None
249
249
250 #If endTime < startTime then endTime belongs to the next day
250 #If endTime < startTime then endTime belongs to the next day
251 #<<<<<<<<<<<o o>>>>>>>>>>>
251 #<<<<<<<<<<<o o>>>>>>>>>>>
252 #-----------o----------------------------o-----------
252 #-----------o----------------------------o-----------
253 # endTime startTime
253 # endTime startTime
254
254
255 if (thisDate == startDate) and numpy.all(thisUtcTime < startUtcTime):
255 if (thisDate == startDate) and numpy.all(thisUtcTime < startUtcTime):
256 return None
256 return None
257
257
258 if (thisDate == endDate) and numpy.all(thisUtcTime > endUtcTime):
258 if (thisDate == endDate) and numpy.all(thisUtcTime > endUtcTime):
259 return None
259 return None
260
260
261 if numpy.all(thisUtcTime < startUtcTime) and numpy.all(thisUtcTime > endUtcTime):
261 if numpy.all(thisUtcTime < startUtcTime) and numpy.all(thisUtcTime > endUtcTime):
262 return None
262 return None
263
263
264 return thisDatetime
264 return thisDatetime
265
265
266 def __setNextFileOffline(self):
266 def __setNextFileOffline(self):
267
267
268 self.fileIndex += 1
268 self.fileIndex += 1
269 idFile = self.fileIndex
269 idFile = self.fileIndex
270
270
271 if not(idFile < len(self.filenameList)):
271 if not(idFile < len(self.filenameList)):
272 print("No more Files")
272 print("No more Files")
273 return 0
273 return 0
274
274
275 filename = self.filenameList[idFile]
275 filename = self.filenameList[idFile]
276
276
277 filePointer = h5py.File(filename,'r')
277 filePointer = h5py.File(filename,'r')
278
278
279 self.filename = filename
279 self.filename = filename
280
280
281 self.fp = filePointer
281 self.fp = filePointer
282
282
283 print("Setting the file: %s"%self.filename)
283 print("Setting the file: %s"%self.filename)
284
284
285 # self.__readMetadata()
285 # self.__readMetadata()
286 self.__setBlockList()
286 self.__setBlockList()
287 self.__readData()
287 self.__readData()
288 # self.nRecords = self.fp['Data'].attrs['blocksPerFile']
288 # self.nRecords = self.fp['Data'].attrs['blocksPerFile']
289 # self.nRecords = self.fp['Data'].attrs['nRecords']
289 # self.nRecords = self.fp['Data'].attrs['nRecords']
290 self.blockIndex = 0
290 self.blockIndex = 0
291 return 1
291 return 1
292
292
293 def __setBlockList(self):
293 def __setBlockList(self):
294 '''
294 '''
295 Selects the data within the times defined
295 Selects the data within the times defined
296
296
297 self.fp
297 self.fp
298 self.startTime
298 self.startTime
299 self.endTime
299 self.endTime
300
300
301 self.blockList
301 self.blockList
302 self.blocksPerFile
302 self.blocksPerFile
303
303
304 '''
304 '''
305 fp = self.fp
305 fp = self.fp
306 startTime = self.startTime
306 startTime = self.startTime
307 endTime = self.endTime
307 endTime = self.endTime
308
308
309 grp = fp['Data']
309 grp = fp['Data']
310 thisUtcTime = grp['utctime'].value.astype(numpy.float)[0]
310 thisUtcTime = grp['utctime'].value.astype(numpy.float)[0]
311
311
312 #ERROOOOR
312 #ERROOOOR
313 if self.timezone == 'lt':
313 if self.timezone == 'lt':
314 thisUtcTime -= 5*3600
314 thisUtcTime -= 5*3600
315
315
316 thisDatetime = datetime.datetime.fromtimestamp(thisUtcTime[0] + 5*3600)
316 thisDatetime = datetime.datetime.fromtimestamp(thisUtcTime[0] + 5*3600)
317
317
318 thisDate = thisDatetime.date()
318 thisDate = thisDatetime.date()
319 thisTime = thisDatetime.time()
319 thisTime = thisDatetime.time()
320
320
321 startUtcTime = (datetime.datetime.combine(thisDate,startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
321 startUtcTime = (datetime.datetime.combine(thisDate,startTime) - datetime.datetime(1970, 1, 1)).total_seconds()
322 endUtcTime = (datetime.datetime.combine(thisDate,endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
322 endUtcTime = (datetime.datetime.combine(thisDate,endTime) - datetime.datetime(1970, 1, 1)).total_seconds()
323
323
324 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
324 ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0]
325
325
326 self.blockList = ind
326 self.blockList = ind
327 self.blocksPerFile = len(ind)
327 self.blocksPerFile = len(ind)
328
328
329 return
329 return
330
330
331 def __readMetadata(self):
331 def __readMetadata(self):
332 '''
332 '''
333 Reads Metadata
333 Reads Metadata
334
334
335 self.pathMeta
335 self.pathMeta
336
336
337 self.listShapes
337 self.listShapes
338 self.listMetaname
338 self.listMetaname
339 self.listMeta
339 self.listMeta
340
340
341 '''
341 '''
342
342
343 # grp = self.fp['Data']
343 # grp = self.fp['Data']
344 # pathMeta = os.path.join(self.path, grp.attrs['metadata'])
344 # pathMeta = os.path.join(self.path, grp.attrs['metadata'])
345 #
345 #
346 # if pathMeta == self.pathMeta:
346 # if pathMeta == self.pathMeta:
347 # return
347 # return
348 # else:
348 # else:
349 # self.pathMeta = pathMeta
349 # self.pathMeta = pathMeta
350 #
350 #
351 # filePointer = h5py.File(self.pathMeta,'r')
351 # filePointer = h5py.File(self.pathMeta,'r')
352 # groupPointer = filePointer['Metadata']
352 # groupPointer = filePointer['Metadata']
353
353
354 filename = self.filenameList[0]
354 filename = self.filenameList[0]
355
355
356 fp = h5py.File(filename,'r')
356 fp = h5py.File(filename,'r')
357
357
358 gp = fp['Metadata']
358 gp = fp['Metadata']
359
359
360 listMetaname = []
360 listMetaname = []
361 listMetadata = []
361 listMetadata = []
362 for item in list(gp.items()):
362 for item in list(gp.items()):
363 name = item[0]
363 name = item[0]
364
364
365 if name=='array dimensions':
365 if name=='array dimensions':
366 table = gp[name][:]
366 table = gp[name][:]
367 listShapes = {}
367 listShapes = {}
368 for shapes in table:
368 for shapes in table:
369 listShapes[shapes[0]] = numpy.array([shapes[1],shapes[2],shapes[3],shapes[4],shapes[5]])
369 listShapes[shapes[0]] = numpy.array([shapes[1],shapes[2],shapes[3],shapes[4],shapes[5]])
370 else:
370 else:
371 data = gp[name].value
371 data = gp[name].value
372 listMetaname.append(name)
372 listMetaname.append(name)
373 listMetadata.append(data)
373 listMetadata.append(data)
374
374
375 # if name=='type':
375 # if name=='type':
376 # self.__initDataOut(data)
376 # self.__initDataOut(data)
377
377
378 self.listShapes = listShapes
378 self.listShapes = listShapes
379 self.listMetaname = listMetaname
379 self.listMetaname = listMetaname
380 self.listMeta = listMetadata
380 self.listMeta = listMetadata
381
381
382 fp.close()
382 fp.close()
383 return
383 return
384
384
385 def __readData(self):
385 def __readData(self):
386 grp = self.fp['Data']
386 grp = self.fp['Data']
387 listdataname = []
387 listdataname = []
388 listdata = []
388 listdata = []
389
389
390 for item in list(grp.items()):
390 for item in list(grp.items()):
391 name = item[0]
391 name = item[0]
392 listdataname.append(name)
392 listdataname.append(name)
393
393
394 array = self.__setDataArray(grp[name],self.listShapes[name])
394 array = self.__setDataArray(grp[name],self.listShapes[name])
395 listdata.append(array)
395 listdata.append(array)
396
396
397 self.listDataname = listdataname
397 self.listDataname = listdataname
398 self.listData = listdata
398 self.listData = listdata
399 return
399 return
400
400
401 def __setDataArray(self, dataset, shapes):
401 def __setDataArray(self, dataset, shapes):
402
402
403 nDims = shapes[0]
403 nDims = shapes[0]
404
404
405 nDim2 = shapes[1] #Dimension 0
405 nDim2 = shapes[1] #Dimension 0
406
406
407 nDim1 = shapes[2] #Dimension 1, number of Points or Parameters
407 nDim1 = shapes[2] #Dimension 1, number of Points or Parameters
408
408
409 nDim0 = shapes[3] #Dimension 2, number of samples or ranges
409 nDim0 = shapes[3] #Dimension 2, number of samples or ranges
410
410
411 mode = shapes[4] #Mode of storing
411 mode = shapes[4] #Mode of storing
412
412
413 blockList = self.blockList
413 blockList = self.blockList
414
414
415 blocksPerFile = self.blocksPerFile
415 blocksPerFile = self.blocksPerFile
416
416
417 #Depending on what mode the data was stored
417 #Depending on what mode the data was stored
418 if mode == 0: #Divided in channels
418 if mode == 0: #Divided in channels
419 arrayData = dataset.value.astype(numpy.float)[0][blockList]
419 arrayData = dataset.value.astype(numpy.float)[0][blockList]
420 if mode == 1: #Divided in parameter
420 if mode == 1: #Divided in parameter
421 strds = 'table'
421 strds = 'table'
422 nDatas = nDim1
422 nDatas = nDim1
423 newShapes = (blocksPerFile,nDim2,nDim0)
423 newShapes = (blocksPerFile,nDim2,nDim0)
424 elif mode==2: #Concatenated in a table
424 elif mode==2: #Concatenated in a table
425 strds = 'table0'
425 strds = 'table0'
426 arrayData = dataset[strds].value
426 arrayData = dataset[strds].value
427 #Selecting part of the dataset
427 #Selecting part of the dataset
428 utctime = arrayData[:,0]
428 utctime = arrayData[:,0]
429 u, indices = numpy.unique(utctime, return_index=True)
429 u, indices = numpy.unique(utctime, return_index=True)
430
430
431 if blockList.size != indices.size:
431 if blockList.size != indices.size:
432 indMin = indices[blockList[0]]
432 indMin = indices[blockList[0]]
433 if blockList[1] + 1 >= indices.size:
433 if blockList[1] + 1 >= indices.size:
434 arrayData = arrayData[indMin:,:]
434 arrayData = arrayData[indMin:,:]
435 else:
435 else:
436 indMax = indices[blockList[1] + 1]
436 indMax = indices[blockList[1] + 1]
437 arrayData = arrayData[indMin:indMax,:]
437 arrayData = arrayData[indMin:indMax,:]
438 return arrayData
438 return arrayData
439
439
440 # One dimension
440 # One dimension
441 if nDims == 0:
441 if nDims == 0:
442 arrayData = dataset.value.astype(numpy.float)[0][blockList]
442 arrayData = dataset.value.astype(numpy.float)[0][blockList]
443
443
444 # Two dimensions
444 # Two dimensions
445 elif nDims == 2:
445 elif nDims == 2:
446 arrayData = numpy.zeros((blocksPerFile,nDim1,nDim0))
446 arrayData = numpy.zeros((blocksPerFile,nDim1,nDim0))
447 newShapes = (blocksPerFile,nDim0)
447 newShapes = (blocksPerFile,nDim0)
448 nDatas = nDim1
448 nDatas = nDim1
449
449
450 for i in range(nDatas):
450 for i in range(nDatas):
451 data = dataset[strds + str(i)].value
451 data = dataset[strds + str(i)].value
452 arrayData[:,i,:] = data[blockList,:]
452 arrayData[:,i,:] = data[blockList,:]
453
453
454 # Three dimensions
454 # Three dimensions
455 else:
455 else:
456 arrayData = numpy.zeros((blocksPerFile,nDim2,nDim1,nDim0))
456 arrayData = numpy.zeros((blocksPerFile,nDim2,nDim1,nDim0))
457 for i in range(nDatas):
457 for i in range(nDatas):
458
458
459 data = dataset[strds + str(i)].value
459 data = dataset[strds + str(i)].value
460
460
461 for b in range(blockList.size):
461 for b in range(blockList.size):
462 arrayData[b,:,i,:] = data[:,:,blockList[b]]
462 arrayData[b,:,i,:] = data[:,:,blockList[b]]
463
463
464 return arrayData
464 return arrayData
465
465
466 def __setDataOut(self):
466 def __setDataOut(self):
467 listMeta = self.listMeta
467 listMeta = self.listMeta
468 listMetaname = self.listMetaname
468 listMetaname = self.listMetaname
469 listDataname = self.listDataname
469 listDataname = self.listDataname
470 listData = self.listData
470 listData = self.listData
471 listShapes = self.listShapes
471 listShapes = self.listShapes
472
472
473 blockIndex = self.blockIndex
473 blockIndex = self.blockIndex
474 # blockList = self.blockList
474 # blockList = self.blockList
475
475
476 for i in range(len(listMeta)):
476 for i in range(len(listMeta)):
477 setattr(self.dataOut,listMetaname[i],listMeta[i])
477 setattr(self.dataOut,listMetaname[i],listMeta[i])
478
478
479 for j in range(len(listData)):
479 for j in range(len(listData)):
480 nShapes = listShapes[listDataname[j]][0]
480 nShapes = listShapes[listDataname[j]][0]
481 mode = listShapes[listDataname[j]][4]
481 mode = listShapes[listDataname[j]][4]
482 if nShapes == 1:
482 if nShapes == 1:
483 setattr(self.dataOut,listDataname[j],listData[j][blockIndex])
483 setattr(self.dataOut,listDataname[j],listData[j][blockIndex])
484 elif nShapes > 1:
484 elif nShapes > 1:
485 setattr(self.dataOut,listDataname[j],listData[j][blockIndex,:])
485 setattr(self.dataOut,listDataname[j],listData[j][blockIndex,:])
486 elif mode==0:
486 elif mode==0:
487 setattr(self.dataOut,listDataname[j],listData[j][blockIndex])
487 setattr(self.dataOut,listDataname[j],listData[j][blockIndex])
488 #Mode Meteors
488 #Mode Meteors
489 elif mode ==2:
489 elif mode ==2:
490 selectedData = self.__selectDataMode2(listData[j], blockIndex)
490 selectedData = self.__selectDataMode2(listData[j], blockIndex)
491 setattr(self.dataOut, listDataname[j], selectedData)
491 setattr(self.dataOut, listDataname[j], selectedData)
492 return
492 return
493
493
494 def __selectDataMode2(self, data, blockIndex):
494 def __selectDataMode2(self, data, blockIndex):
495 utctime = data[:,0]
495 utctime = data[:,0]
496 aux, indices = numpy.unique(utctime, return_inverse=True)
496 aux, indices = numpy.unique(utctime, return_inverse=True)
497 selInd = numpy.where(indices == blockIndex)[0]
497 selInd = numpy.where(indices == blockIndex)[0]
498 selData = data[selInd,:]
498 selData = data[selInd,:]
499
499
500 return selData
500 return selData
501
501
502 def getData(self):
502 def getData(self):
503
503
504 if self.blockIndex==self.blocksPerFile:
504 if self.blockIndex==self.blocksPerFile:
505 if not( self.__setNextFileOffline() ):
505 if not( self.__setNextFileOffline() ):
506 self.dataOut.flagNoData = True
506 self.dataOut.flagNoData = True
507 return 0
507 return 0
508
508
509 self.__setDataOut()
509 self.__setDataOut()
510 self.dataOut.flagNoData = False
510 self.dataOut.flagNoData = False
511
511
512 self.blockIndex += 1
512 self.blockIndex += 1
513
513
514 return
514 return
515
515
516 def run(self, **kwargs):
516 def run(self, **kwargs):
517
517
518 if not(self.isConfig):
518 if not(self.isConfig):
519 self.setup(**kwargs)
519 self.setup(**kwargs)
520 # self.setObjProperties()
520 # self.setObjProperties()
521 self.isConfig = True
521 self.isConfig = True
522
522
523 self.getData()
523 self.getData()
524
524
525 return
525 return
526
526 @MPDecorator
527 @MPDecorator
527 class ParamWriter(Operation):
528 class ParamWriter(Operation):
528 '''
529 '''
529 HDF5 Writer, stores parameters data in HDF5 format files
530 HDF5 Writer, stores parameters data in HDF5 format files
530
531
531 path: path where the files will be stored
532 path: path where the files will be stored
532
533
533 blocksPerFile: number of blocks that will be saved in per HDF5 format file
534 blocksPerFile: number of blocks that will be saved in per HDF5 format file
534
535
535 mode: selects the data stacking mode: '0' channels, '1' parameters, '3' table (for meteors)
536 mode: selects the data stacking mode: '0' channels, '1' parameters, '3' table (for meteors)
536
537
537 metadataList: list of attributes that will be stored as metadata
538 metadataList: list of attributes that will be stored as metadata
538
539
539 dataList: list of attributes that will be stores as data
540 dataList: list of attributes that will be stores as data
540
541
541 '''
542 '''
542
543
543
544
544 ext = ".hdf5"
545 ext = ".hdf5"
545
546 optchar = "D"
546 optchar = "D"
547
548 metaoptchar = "M"
547 metaoptchar = "M"
549
550 metaFile = None
548 metaFile = None
551
552 filename = None
549 filename = None
553
554 path = None
550 path = None
555
556 setFile = None
551 setFile = None
557
558 fp = None
552 fp = None
559
560 grp = None
553 grp = None
561
562 ds = None
554 ds = None
563
564 firsttime = True
555 firsttime = True
565
566 #Configurations
556 #Configurations
567
568 blocksPerFile = None
557 blocksPerFile = None
569
570 blockIndex = None
558 blockIndex = None
571
572 dataOut = None
559 dataOut = None
573
574 #Data Arrays
560 #Data Arrays
575
576 dataList = None
561 dataList = None
577
578 metadataList = None
562 metadataList = None
579
580 # arrayDim = None
581
582 dsList = None #List of dictionaries with dataset properties
563 dsList = None #List of dictionaries with dataset properties
583
584 tableDim = None
564 tableDim = None
585
586 # dtype = [('arrayName', 'S20'),('nChannels', 'i'), ('nPoints', 'i'), ('nSamples', 'i'),('mode', 'b')]
587
588 dtype = [('arrayName', 'S20'),('nDimensions', 'i'), ('dim2', 'i'), ('dim1', 'i'),('dim0', 'i'),('mode', 'b')]
565 dtype = [('arrayName', 'S20'),('nDimensions', 'i'), ('dim2', 'i'), ('dim1', 'i'),('dim0', 'i'),('mode', 'b')]
589
590 currentDay = None
566 currentDay = None
591
592 lastTime = None
567 lastTime = None
593
568
594 def __init__(self):#, **kwargs):
569 def __init__(self):
595 Operation.__init__(self)#, **kwargs)
570
596 #self.isConfig = False
571 Operation.__init__(self)
597 return
572 return
598
573
599 def setup(self, dataOut, path=None, blocksPerFile=10, metadataList=None, dataList=None, mode=None, **kwargs):
574 def setup(self, dataOut, path=None, blocksPerFile=10, metadataList=None, dataList=None, mode=None, setType=None):
600 self.path = path
575 self.path = path
601 self.blocksPerFile = blocksPerFile
576 self.blocksPerFile = blocksPerFile
602 self.metadataList = metadataList
577 self.metadataList = metadataList
603 self.dataList = dataList
578 self.dataList = dataList
604 self.dataOut = dataOut
579 self.dataOut = dataOut
605 self.mode = mode
580 self.mode = mode
606 if self.mode is not None:
581 if self.mode is not None:
607 self.mode = numpy.zeros(len(self.dataList)) + mode
582 self.mode = numpy.zeros(len(self.dataList)) + mode
608 else:
583 else:
609 #self.mode = numpy.ones(len(self.dataList),int)
610 self.mode = numpy.ones(len(self.dataList))
584 self.mode = numpy.ones(len(self.dataList))
611 log.error(self.mode)#yong
585
586 self.setType = setType
612
587
613 arrayDim = numpy.zeros((len(self.dataList),5))
588 arrayDim = numpy.zeros((len(self.dataList),5))
614
589
615 #Table dimensions
590 #Table dimensions
616 dtype0 = self.dtype
591 dtype0 = self.dtype
617 tableList = []
592 tableList = []
618
593
619 #Dictionary and list of tables
594 #Dictionary and list of tables
620 dsList = []
595 dsList = []
621
596
622 for i in range(len(self.dataList)):
597 for i in range(len(self.dataList)):
623 dsDict = {}
598 dsDict = {}
624 dataAux = getattr(self.dataOut, self.dataList[i])
599 dataAux = getattr(self.dataOut, self.dataList[i])
625 dsDict['variable'] = self.dataList[i]
600 dsDict['variable'] = self.dataList[i]
626 #--------------------- Conditionals ------------------------
601 #--------------------- Conditionals ------------------------
627 #There is no data
602 #There is no data
628
603
629
604
630 if dataAux is None:
605 if dataAux is None:
631
606
632 return 0
607 return 0
633
608
634 #Not array, just a number
635 #Mode 0
636 #log.error(mode)#yong
637 #log.error(len(mode))#yong
638 #log.error(type(mode))#yong
639 if type(dataAux)==float or type(dataAux)==int:
609 if type(dataAux)==float or type(dataAux)==int:
640 dsDict['mode'] = 0
610 dsDict['mode'] = 0
641 dsDict['nDim'] = 0
611 dsDict['nDim'] = 0
642 arrayDim[i,0] = 0
612 arrayDim[i,0] = 0
643 dsList.append(dsDict)
613 dsList.append(dsDict)
644
614
645 #Mode 2: meteors
615 #Mode 2: meteors
646 elif self.mode[i] == 2:
616 elif self.mode[i] == 2:
647 # dsDict['nDim'] = 0
648 dsDict['dsName'] = 'table0'
617 dsDict['dsName'] = 'table0'
649 dsDict['mode'] = 2 # Mode meteors
618 dsDict['mode'] = 2 # Mode meteors
650 dsDict['shape'] = dataAux.shape[-1]
619 dsDict['shape'] = dataAux.shape[-1]
651 dsDict['nDim'] = 0
620 dsDict['nDim'] = 0
652 dsDict['dsNumber'] = 1
621 dsDict['dsNumber'] = 1
653
654 arrayDim[i,3] = dataAux.shape[-1]
622 arrayDim[i,3] = dataAux.shape[-1]
655 arrayDim[i,4] = self.mode[i] #Mode the data was stored
623 arrayDim[i,4] = self.mode[i] #Mode the data was stored
656
657 dsList.append(dsDict)
624 dsList.append(dsDict)
658
625
659 #Mode 1
626 #Mode 1
660 else:
627 else:
661 arrayDim0 = dataAux.shape #Data dimensions
628 arrayDim0 = dataAux.shape #Data dimensions
662 arrayDim[i,0] = len(arrayDim0) #Number of array dimensions
629 arrayDim[i,0] = len(arrayDim0) #Number of array dimensions
663 arrayDim[i,4] = self.mode[i] #Mode the data was stored
630 arrayDim[i,4] = self.mode[i] #Mode the data was stored
664
665 strtable = 'table'
631 strtable = 'table'
666 dsDict['mode'] = 1 # Mode parameters
632 dsDict['mode'] = 1 # Mode parameters
667
633
668 # Three-dimension arrays
634 # Three-dimension arrays
669 if len(arrayDim0) == 3:
635 if len(arrayDim0) == 3:
670 arrayDim[i,1:-1] = numpy.array(arrayDim0)
636 arrayDim[i,1:-1] = numpy.array(arrayDim0)
671 nTables = int(arrayDim[i,2])
637 nTables = int(arrayDim[i,2])
672 dsDict['dsNumber'] = nTables
638 dsDict['dsNumber'] = nTables
673 dsDict['shape'] = arrayDim[i,2:4]
639 dsDict['shape'] = arrayDim[i,2:4]
674 dsDict['nDim'] = 3
640 dsDict['nDim'] = 3
675
641
676 for j in range(nTables):
642 for j in range(nTables):
677 dsDict = dsDict.copy()
643 dsDict = dsDict.copy()
678 dsDict['dsName'] = strtable + str(j)
644 dsDict['dsName'] = strtable + str(j)
679 dsList.append(dsDict)
645 dsList.append(dsDict)
680
646
681 # Two-dimension arrays
647 # Two-dimension arrays
682 elif len(arrayDim0) == 2:
648 elif len(arrayDim0) == 2:
683 arrayDim[i,2:-1] = numpy.array(arrayDim0)
649 arrayDim[i,2:-1] = numpy.array(arrayDim0)
684 nTables = int(arrayDim[i,2])
650 nTables = int(arrayDim[i,2])
685 dsDict['dsNumber'] = nTables
651 dsDict['dsNumber'] = nTables
686 dsDict['shape'] = arrayDim[i,3]
652 dsDict['shape'] = arrayDim[i,3]
687 dsDict['nDim'] = 2
653 dsDict['nDim'] = 2
688
654
689 for j in range(nTables):
655 for j in range(nTables):
690 dsDict = dsDict.copy()
656 dsDict = dsDict.copy()
691 dsDict['dsName'] = strtable + str(j)
657 dsDict['dsName'] = strtable + str(j)
692 dsList.append(dsDict)
658 dsList.append(dsDict)
693
659
694 # One-dimension arrays
660 # One-dimension arrays
695 elif len(arrayDim0) == 1:
661 elif len(arrayDim0) == 1:
696 arrayDim[i,3] = arrayDim0[0]
662 arrayDim[i,3] = arrayDim0[0]
697 dsDict['shape'] = arrayDim0[0]
663 dsDict['shape'] = arrayDim0[0]
698 dsDict['dsNumber'] = 1
664 dsDict['dsNumber'] = 1
699 dsDict['dsName'] = strtable + str(0)
665 dsDict['dsName'] = strtable + str(0)
700 dsDict['nDim'] = 1
666 dsDict['nDim'] = 1
701 dsList.append(dsDict)
667 dsList.append(dsDict)
702
668
703 table = numpy.array((self.dataList[i],) + tuple(arrayDim[i,:]),dtype = dtype0)
669 table = numpy.array((self.dataList[i],) + tuple(arrayDim[i,:]),dtype = dtype0)
704 tableList.append(table)
670 tableList.append(table)
705
671
706 # self.arrayDim = arrayDim
707 self.dsList = dsList
672 self.dsList = dsList
708 self.tableDim = numpy.array(tableList, dtype = dtype0)
673 self.tableDim = numpy.array(tableList, dtype = dtype0)
709 self.blockIndex = 0
674 self.blockIndex = 0
710
711 timeTuple = time.localtime(dataOut.utctime)
675 timeTuple = time.localtime(dataOut.utctime)
712 self.currentDay = timeTuple.tm_yday
676 self.currentDay = timeTuple.tm_yday
713 return 1
714
677
715 def putMetadata(self):
678 def putMetadata(self):
716
679
717 fp = self.createMetadataFile()
680 fp = self.createMetadataFile()
718 self.writeMetadata(fp)
681 self.writeMetadata(fp)
719 fp.close()
682 fp.close()
720 return
683 return
721
684
722 def createMetadataFile(self):
685 def createMetadataFile(self):
723 ext = self.ext
686 ext = self.ext
724 path = self.path
687 path = self.path
725 setFile = self.setFile
688 setFile = self.setFile
726
689
727 timeTuple = time.localtime(self.dataOut.utctime)
690 timeTuple = time.localtime(self.dataOut.utctime)
728
691
729 subfolder = ''
692 subfolder = ''
730 fullpath = os.path.join( path, subfolder )
693 fullpath = os.path.join( path, subfolder )
731
694
732 if not( os.path.exists(fullpath) ):
695 if not( os.path.exists(fullpath) ):
733 os.mkdir(fullpath)
696 os.mkdir(fullpath)
734 setFile = -1 #inicializo mi contador de seteo
697 setFile = -1 #inicializo mi contador de seteo
735
698
736 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
699 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
737 fullpath = os.path.join( path, subfolder )
700 fullpath = os.path.join( path, subfolder )
738
701
739 if not( os.path.exists(fullpath) ):
702 if not( os.path.exists(fullpath) ):
740 os.mkdir(fullpath)
703 os.mkdir(fullpath)
741 setFile = -1 #inicializo mi contador de seteo
704 setFile = -1 #inicializo mi contador de seteo
742
705
743 else:
706 else:
744 filesList = os.listdir( fullpath )
707 filesList = os.listdir( fullpath )
745 filesList = sorted( filesList, key=str.lower )
708 filesList = sorted( filesList, key=str.lower )
746 if len( filesList ) > 0:
709 if len( filesList ) > 0:
747 filesList = [k for k in filesList if 'M' in k]
710 filesList = [k for k in filesList if k.startswith(self.metaoptchar)]
748 filen = filesList[-1]
711 filen = filesList[-1]
749 # el filename debera tener el siguiente formato
712 # el filename debera tener el siguiente formato
750 # 0 1234 567 89A BCDE (hex)
713 # 0 1234 567 89A BCDE (hex)
751 # x YYYY DDD SSS .ext
714 # x YYYY DDD SSS .ext
752 if isNumber( filen[8:11] ):
715 if isNumber( filen[8:11] ):
753 setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
716 setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
754 else:
717 else:
755 setFile = -1
718 setFile = -1
756 else:
719 else:
757 setFile = -1 #inicializo mi contador de seteo
720 setFile = -1 #inicializo mi contador de seteo
758
721
759 if self.setType is None:
722 if self.setType is None:
760 setFile += 1
723 setFile += 1
761 file = '%s%4.4d%3.3d%03d%s' % (self.metaoptchar,
724 file = '%s%4.4d%3.3d%03d%s' % (self.metaoptchar,
762 timeTuple.tm_year,
725 timeTuple.tm_year,
763 timeTuple.tm_yday,
726 timeTuple.tm_yday,
764 setFile,
727 setFile,
765 ext )
728 ext )
766 else:
729 else:
767 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
730 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
768 file = '%s%4.4d%3.3d%04d%s' % (self.metaoptchar,
731 file = '%s%4.4d%3.3d%04d%s' % (self.metaoptchar,
769 timeTuple.tm_year,
732 timeTuple.tm_year,
770 timeTuple.tm_yday,
733 timeTuple.tm_yday,
771 setFile,
734 setFile,
772 ext )
735 ext )
773
736
774 filename = os.path.join( path, subfolder, file )
737 filename = os.path.join( path, subfolder, file )
775 self.metaFile = file
738 self.metaFile = file
776 #Setting HDF5 File
739 #Setting HDF5 File
777 fp = h5py.File(filename,'w')
740 fp = h5py.File(filename,'w')
778
741
779 return fp
742 return fp
780
743
781 def writeMetadata(self, fp):
744 def writeMetadata(self, fp):
782
745
783 grp = fp.create_group("Metadata")
746 grp = fp.create_group("Metadata")
784 grp.create_dataset('array dimensions', data = self.tableDim, dtype = self.dtype)
747 grp.create_dataset('array dimensions', data = self.tableDim, dtype = self.dtype)
785
748
786 for i in range(len(self.metadataList)):
749 for i in range(len(self.metadataList)):
787 grp.create_dataset(self.metadataList[i], data=getattr(self.dataOut, self.metadataList[i]))
750 grp.create_dataset(self.metadataList[i], data=getattr(self.dataOut, self.metadataList[i]))
788 return
751 return
789
752
790 def timeFlag(self):
753 def timeFlag(self):
791 currentTime = self.dataOut.utctime
754 currentTime = self.dataOut.utctime
792
755
793 if self.lastTime is None:
756 if self.lastTime is None:
794 self.lastTime = currentTime
757 self.lastTime = currentTime
795
758
796 #Day
759 #Day
797 timeTuple = time.localtime(currentTime)
760 timeTuple = time.localtime(currentTime)
798 dataDay = timeTuple.tm_yday
761 dataDay = timeTuple.tm_yday
799
762
800 #Time
763 #Time
801 timeDiff = currentTime - self.lastTime
764 timeDiff = currentTime - self.lastTime
802
765
803 #Si el dia es diferente o si la diferencia entre un dato y otro supera la hora
766 #Si el dia es diferente o si la diferencia entre un dato y otro supera la hora
804 if dataDay != self.currentDay:
767 if dataDay != self.currentDay:
805 self.currentDay = dataDay
768 self.currentDay = dataDay
806 return True
769 return True
807 elif timeDiff > 3*60*60:
770 elif timeDiff > 3*60*60:
808 self.lastTime = currentTime
771 self.lastTime = currentTime
809 return True
772 return True
810 else:
773 else:
811 self.lastTime = currentTime
774 self.lastTime = currentTime
812 return False
775 return False
813
776
814 def setNextFile(self):
777 def setNextFile(self):
815
778
816 ext = self.ext
779 ext = self.ext
817 path = self.path
780 path = self.path
818 setFile = self.setFile
781 setFile = self.setFile
819 mode = self.mode
782 mode = self.mode
820
783
821 timeTuple = time.localtime(self.dataOut.utctime)
784 timeTuple = time.localtime(self.dataOut.utctime)
822 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
785 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday)
823
786
824 fullpath = os.path.join( path, subfolder )
787 fullpath = os.path.join( path, subfolder )
825
788
826 if os.path.exists(fullpath):
789 if os.path.exists(fullpath):
827 filesList = os.listdir( fullpath )
790 filesList = os.listdir( fullpath )
828 filesList = [k for k in filesList if 'D' in k]
791 filesList = [k for k in filesList if k.startswith(self.optchar)]
829 if len( filesList ) > 0:
792 if len( filesList ) > 0:
830 filesList = sorted( filesList, key=str.lower )
793 filesList = sorted( filesList, key=str.lower )
831 filen = filesList[-1]
794 filen = filesList[-1]
832 # el filename debera tener el siguiente formato
795 # el filename debera tener el siguiente formato
833 # 0 1234 567 89A BCDE (hex)
796 # 0 1234 567 89A BCDE (hex)
834 # x YYYY DDD SSS .ext
797 # x YYYY DDD SSS .ext
835 if isNumber( filen[8:11] ):
798 if isNumber( filen[8:11] ):
836 setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
799 setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file
837 else:
800 else:
838 setFile = -1
801 setFile = -1
839 else:
802 else:
840 setFile = -1 #inicializo mi contador de seteo
803 setFile = -1 #inicializo mi contador de seteo
841 else:
804 else:
842 os.makedirs(fullpath)
805 os.makedirs(fullpath)
843 setFile = -1 #inicializo mi contador de seteo
806 setFile = -1 #inicializo mi contador de seteo
844
807
845 if None is None:
808 if self.setType is None:
846 setFile += 1
809 setFile += 1
847 file = '%s%4.4d%3.3d%03d%s' % (self.metaoptchar,
810 file = '%s%4.4d%3.3d%03d%s' % (self.optchar,
848 timeTuple.tm_year,
811 timeTuple.tm_year,
849 timeTuple.tm_yday,
812 timeTuple.tm_yday,
850 setFile,
813 setFile,
851 ext )
814 ext )
852 else:
815 else:
853 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
816 setFile = timeTuple.tm_hour*60+timeTuple.tm_min
854 file = '%s%4.4d%3.3d%04d%s' % (self.metaoptchar,
817 file = '%s%4.4d%3.3d%04d%s' % (self.optchar,
855 timeTuple.tm_year,
818 timeTuple.tm_year,
856 timeTuple.tm_yday,
819 timeTuple.tm_yday,
857 setFile,
820 setFile,
858 ext )
821 ext )
859
822
860 filename = os.path.join( path, subfolder, file )
823 filename = os.path.join( path, subfolder, file )
861
824
862 #Setting HDF5 File
825 #Setting HDF5 File
863 fp = h5py.File(filename,'w')
826 fp = h5py.File(filename,'w')
864 #write metadata
827 #write metadata
865 self.writeMetadata(fp)
828 self.writeMetadata(fp)
866 #Write data
829 #Write data
867 grp = fp.create_group("Data")
830 grp = fp.create_group("Data")
868 # grp.attrs['metadata'] = self.metaFile
869
870 # grp.attrs['blocksPerFile'] = 0
871 ds = []
831 ds = []
872 data = []
832 data = []
873 dsList = self.dsList
833 dsList = self.dsList
874 i = 0
834 i = 0
875 while i < len(dsList):
835 while i < len(dsList):
876 dsInfo = dsList[i]
836 dsInfo = dsList[i]
877 #One-dimension data
837 #One-dimension data
878 if dsInfo['mode'] == 0:
838 if dsInfo['mode'] == 0:
879 # ds0 = grp.create_dataset(self.dataList[i], (1,1), maxshape=(1,self.blocksPerFile) , chunks = True, dtype='S20')
880 ds0 = grp.create_dataset(dsInfo['variable'], (1,1), maxshape=(1,self.blocksPerFile) , chunks = True, dtype=numpy.float64)
839 ds0 = grp.create_dataset(dsInfo['variable'], (1,1), maxshape=(1,self.blocksPerFile) , chunks = True, dtype=numpy.float64)
881 ds.append(ds0)
840 ds.append(ds0)
882 data.append([])
841 data.append([])
883 i += 1
842 i += 1
884 continue
843 continue
885 # nDimsForDs.append(nDims[i])
886
844
887 elif dsInfo['mode'] == 2:
845 elif dsInfo['mode'] == 2:
888 grp0 = grp.create_group(dsInfo['variable'])
846 grp0 = grp.create_group(dsInfo['variable'])
889 ds0 = grp0.create_dataset(dsInfo['dsName'], (1,dsInfo['shape']), data = numpy.zeros((1,dsInfo['shape'])) , maxshape=(None,dsInfo['shape']), chunks=True)
847 ds0 = grp0.create_dataset(dsInfo['dsName'], (1,dsInfo['shape']), data = numpy.zeros((1,dsInfo['shape'])) , maxshape=(None,dsInfo['shape']), chunks=True)
890 ds.append(ds0)
848 ds.append(ds0)
891 data.append([])
849 data.append([])
892 i += 1
850 i += 1
893 continue
851 continue
894
852
895 elif dsInfo['mode'] == 1:
853 elif dsInfo['mode'] == 1:
896 grp0 = grp.create_group(dsInfo['variable'])
854 grp0 = grp.create_group(dsInfo['variable'])
897
855
898 for j in range(dsInfo['dsNumber']):
856 for j in range(dsInfo['dsNumber']):
899 dsInfo = dsList[i]
857 dsInfo = dsList[i]
900 tableName = dsInfo['dsName']
858 tableName = dsInfo['dsName']
901
859
902
860
903 if dsInfo['nDim'] == 3:
861 if dsInfo['nDim'] == 3:
904 shape = dsInfo['shape'].astype(int)
862 shape = dsInfo['shape'].astype(int)
905 ds0 = grp0.create_dataset(tableName, (shape[0],shape[1],1) , data = numpy.zeros((shape[0],shape[1],1)), maxshape = (None,shape[1],None), chunks=True)
863 ds0 = grp0.create_dataset(tableName, (shape[0],shape[1],1) , data = numpy.zeros((shape[0],shape[1],1)), maxshape = (None,shape[1],None), chunks=True)
906 else:
864 else:
907 shape = int(dsInfo['shape'])
865 shape = int(dsInfo['shape'])
908 ds0 = grp0.create_dataset(tableName, (1,shape), data = numpy.zeros((1,shape)) , maxshape=(None,shape), chunks=True)
866 ds0 = grp0.create_dataset(tableName, (1,shape), data = numpy.zeros((1,shape)) , maxshape=(None,shape), chunks=True)
909
867
910 ds.append(ds0)
868 ds.append(ds0)
911 data.append([])
869 data.append([])
912 i += 1
870 i += 1
913 # nDimsForDs.append(nDims[i])
914
871
915 fp.flush()
872 fp.flush()
916 fp.close()
873 fp.close()
917
874
918 # self.nDatas = nDatas
875 log.log('creating file: {}'.format(filename), 'Writing')
919 # self.nDims = nDims
920 # self.nDimsForDs = nDimsForDs
921 #Saving variables
922 print('Writing the file: %s'%filename)
923 self.filename = filename
876 self.filename = filename
924 # self.fp = fp
925 # self.grp = grp
926 # self.grp.attrs.modify('nRecords', 1)
927 self.ds = ds
877 self.ds = ds
928 self.data = data
878 self.data = data
929 # self.setFile = setFile
930 self.firsttime = True
879 self.firsttime = True
931 self.blockIndex = 0
880 self.blockIndex = 0
932 return
881 return
933
882
934 def putData(self):
883 def putData(self):
935
884
936 if self.blockIndex == self.blocksPerFile or self.timeFlag():
885 if self.blockIndex == self.blocksPerFile or self.timeFlag():
937 self.setNextFile()
886 self.setNextFile()
938
887
939 # if not self.firsttime:
940 self.readBlock()
888 self.readBlock()
941 self.setBlock() #Prepare data to be written
889 self.setBlock() #Prepare data to be written
942 self.writeBlock() #Write data
890 self.writeBlock() #Write data
943
891
944 return
892 return
945
893
946 def readBlock(self):
894 def readBlock(self):
947
895
948 '''
896 '''
949 data Array configured
897 data Array configured
950
898
951
899
952 self.data
900 self.data
953 '''
901 '''
954 dsList = self.dsList
902 dsList = self.dsList
955 ds = self.ds
903 ds = self.ds
956 #Setting HDF5 File
904 #Setting HDF5 File
957 fp = h5py.File(self.filename,'r+')
905 fp = h5py.File(self.filename,'r+')
958 grp = fp["Data"]
906 grp = fp["Data"]
959 ind = 0
907 ind = 0
960
908
961 # grp.attrs['blocksPerFile'] = 0
962 while ind < len(dsList):
909 while ind < len(dsList):
963 dsInfo = dsList[ind]
910 dsInfo = dsList[ind]
964
911
965 if dsInfo['mode'] == 0:
912 if dsInfo['mode'] == 0:
966 ds0 = grp[dsInfo['variable']]
913 ds0 = grp[dsInfo['variable']]
967 ds[ind] = ds0
914 ds[ind] = ds0
968 ind += 1
915 ind += 1
969 else:
916 else:
970
917
971 grp0 = grp[dsInfo['variable']]
918 grp0 = grp[dsInfo['variable']]
972
919
973 for j in range(dsInfo['dsNumber']):
920 for j in range(dsInfo['dsNumber']):
974 dsInfo = dsList[ind]
921 dsInfo = dsList[ind]
975 ds0 = grp0[dsInfo['dsName']]
922 ds0 = grp0[dsInfo['dsName']]
976 ds[ind] = ds0
923 ds[ind] = ds0
977 ind += 1
924 ind += 1
978
925
979 self.fp = fp
926 self.fp = fp
980 self.grp = grp
927 self.grp = grp
981 self.ds = ds
928 self.ds = ds
982
929
983 return
930 return
984
931
985 def setBlock(self):
932 def setBlock(self):
986 '''
933 '''
987 data Array configured
934 data Array configured
988
935
989
936
990 self.data
937 self.data
991 '''
938 '''
992 #Creating Arrays
939 #Creating Arrays
993 dsList = self.dsList
940 dsList = self.dsList
994 data = self.data
941 data = self.data
995 ind = 0
942 ind = 0
996
943
997 while ind < len(dsList):
944 while ind < len(dsList):
998 dsInfo = dsList[ind]
945 dsInfo = dsList[ind]
999 dataAux = getattr(self.dataOut, dsInfo['variable'])
946 dataAux = getattr(self.dataOut, dsInfo['variable'])
1000
947
1001 mode = dsInfo['mode']
948 mode = dsInfo['mode']
1002 nDim = dsInfo['nDim']
949 nDim = dsInfo['nDim']
1003
950
1004 if mode == 0 or mode == 2 or nDim == 1:
951 if mode == 0 or mode == 2 or nDim == 1:
1005 data[ind] = dataAux
952 data[ind] = dataAux
1006 ind += 1
953 ind += 1
1007 # elif nDim == 1:
954 # elif nDim == 1:
1008 # data[ind] = numpy.reshape(dataAux,(numpy.size(dataAux),1))
955 # data[ind] = numpy.reshape(dataAux,(numpy.size(dataAux),1))
1009 # ind += 1
956 # ind += 1
1010 elif nDim == 2:
957 elif nDim == 2:
1011 for j in range(dsInfo['dsNumber']):
958 for j in range(dsInfo['dsNumber']):
1012 data[ind] = dataAux[j,:]
959 data[ind] = dataAux[j,:]
1013 ind += 1
960 ind += 1
1014 elif nDim == 3:
961 elif nDim == 3:
1015 for j in range(dsInfo['dsNumber']):
962 for j in range(dsInfo['dsNumber']):
1016 data[ind] = dataAux[:,j,:]
963 data[ind] = dataAux[:,j,:]
1017 ind += 1
964 ind += 1
1018
965
1019 self.data = data
966 self.data = data
1020 return
967 return
1021
968
1022 def writeBlock(self):
969 def writeBlock(self):
1023 '''
970 '''
1024 Saves the block in the HDF5 file
971 Saves the block in the HDF5 file
1025 '''
972 '''
1026 dsList = self.dsList
973 dsList = self.dsList
1027
974
1028 for i in range(len(self.ds)):
975 for i in range(len(self.ds)):
1029 dsInfo = dsList[i]
976 dsInfo = dsList[i]
1030 nDim = dsInfo['nDim']
977 nDim = dsInfo['nDim']
1031 mode = dsInfo['mode']
978 mode = dsInfo['mode']
1032
979
1033 # First time
980 # First time
1034 if self.firsttime:
981 if self.firsttime:
1035 # self.ds[i].resize(self.data[i].shape)
1036 # self.ds[i][self.blockIndex,:] = self.data[i]
1037 if type(self.data[i]) == numpy.ndarray:
982 if type(self.data[i]) == numpy.ndarray:
1038
983
1039 if nDim == 3:
984 if nDim == 3:
1040 self.data[i] = self.data[i].reshape((self.data[i].shape[0],self.data[i].shape[1],1))
985 self.data[i] = self.data[i].reshape((self.data[i].shape[0],self.data[i].shape[1],1))
1041 self.ds[i].resize(self.data[i].shape)
986 self.ds[i].resize(self.data[i].shape)
1042 if mode == 2:
987 if mode == 2:
1043 self.ds[i].resize(self.data[i].shape)
988 self.ds[i].resize(self.data[i].shape)
1044 self.ds[i][:] = self.data[i]
989 self.ds[i][:] = self.data[i]
1045 else:
990 else:
1046
991
1047 # From second time
992 # From second time
1048 # Meteors!
993 # Meteors!
1049 if mode == 2:
994 if mode == 2:
1050 dataShape = self.data[i].shape
995 dataShape = self.data[i].shape
1051 dsShape = self.ds[i].shape
996 dsShape = self.ds[i].shape
1052 self.ds[i].resize((self.ds[i].shape[0] + dataShape[0],self.ds[i].shape[1]))
997 self.ds[i].resize((self.ds[i].shape[0] + dataShape[0],self.ds[i].shape[1]))
1053 self.ds[i][dsShape[0]:,:] = self.data[i]
998 self.ds[i][dsShape[0]:,:] = self.data[i]
1054 # No dimension
999 # No dimension
1055 elif mode == 0:
1000 elif mode == 0:
1056 self.ds[i].resize((self.ds[i].shape[0], self.ds[i].shape[1] + 1))
1001 self.ds[i].resize((self.ds[i].shape[0], self.ds[i].shape[1] + 1))
1057 self.ds[i][0,-1] = self.data[i]
1002 self.ds[i][0,-1] = self.data[i]
1058 # One dimension
1003 # One dimension
1059 elif nDim == 1:
1004 elif nDim == 1:
1060 self.ds[i].resize((self.ds[i].shape[0] + 1, self.ds[i].shape[1]))
1005 self.ds[i].resize((self.ds[i].shape[0] + 1, self.ds[i].shape[1]))
1061 self.ds[i][-1,:] = self.data[i]
1006 self.ds[i][-1,:] = self.data[i]
1062 # Two dimension
1007 # Two dimension
1063 elif nDim == 2:
1008 elif nDim == 2:
1064 self.ds[i].resize((self.ds[i].shape[0] + 1,self.ds[i].shape[1]))
1009 self.ds[i].resize((self.ds[i].shape[0] + 1,self.ds[i].shape[1]))
1065 self.ds[i][self.blockIndex,:] = self.data[i]
1010 self.ds[i][self.blockIndex,:] = self.data[i]
1066 # Three dimensions
1011 # Three dimensions
1067 elif nDim == 3:
1012 elif nDim == 3:
1068 self.ds[i].resize((self.ds[i].shape[0],self.ds[i].shape[1],self.ds[i].shape[2]+1))
1013 self.ds[i].resize((self.ds[i].shape[0],self.ds[i].shape[1],self.ds[i].shape[2]+1))
1069 self.ds[i][:,:,-1] = self.data[i]
1014 self.ds[i][:,:,-1] = self.data[i]
1070
1015
1071 self.firsttime = False
1016 self.firsttime = False
1072 self.blockIndex += 1
1017 self.blockIndex += 1
1073
1018
1074 #Close to save changes
1019 #Close to save changes
1075 self.fp.flush()
1020 self.fp.flush()
1076 self.fp.close()
1021 self.fp.close()
1077 return
1022 return
1078
1023
1079 def run(self, dataOut, path, blocksPerFile=10, metadataList=None, dataList=None, mode=None, **kwargs):
1024 def run(self, dataOut, path, blocksPerFile=10, metadataList=None, dataList=None, mode=None, setType=None):
1080
1025
1081 if not(self.isConfig):
1026 if not(self.isConfig):
1082 flagdata = self.setup(dataOut, path=path, blocksPerFile=blocksPerFile,
1027 self.setup(dataOut, path=path, blocksPerFile=blocksPerFile,
1083 metadataList=metadataList, dataList=dataList, mode=mode, **kwargs)
1028 metadataList=metadataList, dataList=dataList, mode=mode,
1084
1029 setType=setType)
1085 if not(flagdata):
1086 return
1087
1030
1088 self.isConfig = True
1031 self.isConfig = True
1089 self.setNextFile()
1032 self.setNextFile()
1090
1033
1091 self.putData()
1034 self.putData()
1092 return
1035 return
1093 No newline at end of file
1036
@@ -1,380 +1,382
1 '''
1 '''
2 Updated for multiprocessing
2 Updated for multiprocessing
3 Author : Sergio Cortez
3 Author : Sergio Cortez
4 Jan 2018
4 Jan 2018
5 Abstract:
5 Abstract:
6 Base class for processing units and operations. A decorator provides multiprocessing features and interconnect the processes created.
6 Base class for processing units and operations. A decorator provides multiprocessing features and interconnect the processes created.
7 The argument (kwargs) sent from the controller is parsed and filtered via the decorator for each processing unit or operation instantiated.
7 The argument (kwargs) sent from the controller is parsed and filtered via the decorator for each processing unit or operation instantiated.
8 The decorator handle also the methods inside the processing unit to be called from the main script (not as operations) (OPERATION -> type ='self').
8 The decorator handle also the methods inside the processing unit to be called from the main script (not as operations) (OPERATION -> type ='self').
9
9
10 Based on:
10 Based on:
11 $Author: murco $
11 $Author: murco $
12 $Id: jroproc_base.py 1 2012-11-12 18:56:07Z murco $
12 $Id: jroproc_base.py 1 2012-11-12 18:56:07Z murco $
13 '''
13 '''
14
14
15 import inspect
15 import inspect
16 import zmq
16 import zmq
17 import time
17 import time
18 import pickle
18 import pickle
19 import os
19 import os
20 from multiprocessing import Process
20 from multiprocessing import Process
21 from zmq.utils.monitor import recv_monitor_message
21 from zmq.utils.monitor import recv_monitor_message
22
22
23 from schainpy.utils import log
23 from schainpy.utils import log
24
24
25
25
26 class ProcessingUnit(object):
26 class ProcessingUnit(object):
27
27
28 """
28 """
29 Update - Jan 2018 - MULTIPROCESSING
29 Update - Jan 2018 - MULTIPROCESSING
30 All the "call" methods present in the previous base were removed.
30 All the "call" methods present in the previous base were removed.
31 The majority of operations are independant processes, thus
31 The majority of operations are independant processes, thus
32 the decorator is in charge of communicate the operation processes
32 the decorator is in charge of communicate the operation processes
33 with the proccessing unit via IPC.
33 with the proccessing unit via IPC.
34
34
35 The constructor does not receive any argument. The remaining methods
35 The constructor does not receive any argument. The remaining methods
36 are related with the operations to execute.
36 are related with the operations to execute.
37
37
38
38
39 """
39 """
40
40
41 def __init__(self):
41 def __init__(self):
42
42
43 self.dataIn = None
43 self.dataIn = None
44 self.dataOut = None
44 self.dataOut = None
45 self.isConfig = False
45 self.isConfig = False
46 self.operations = []
46 self.operations = []
47 self.plots = []
47 self.plots = []
48
48
49 def getAllowedArgs(self):
49 def getAllowedArgs(self):
50 if hasattr(self, '__attrs__'):
50 if hasattr(self, '__attrs__'):
51 return self.__attrs__
51 return self.__attrs__
52 else:
52 else:
53 return inspect.getargspec(self.run).args
53 return inspect.getargspec(self.run).args
54
54
55 def addOperation(self, conf, operation):
55 def addOperation(self, conf, operation):
56 """
56 """
57 This method is used in the controller, and update the dictionary containing the operations to execute. The dict
57 This method is used in the controller, and update the dictionary containing the operations to execute. The dict
58 posses the id of the operation process (IPC purposes)
58 posses the id of the operation process (IPC purposes)
59
59
60 Agrega un objeto del tipo "Operation" (opObj) a la lista de objetos "self.objectList" y retorna el
60 Agrega un objeto del tipo "Operation" (opObj) a la lista de objetos "self.objectList" y retorna el
61 identificador asociado a este objeto.
61 identificador asociado a este objeto.
62
62
63 Input:
63 Input:
64
64
65 object : objeto de la clase "Operation"
65 object : objeto de la clase "Operation"
66
66
67 Return:
67 Return:
68
68
69 objId : identificador del objeto, necesario para comunicar con master(procUnit)
69 objId : identificador del objeto, necesario para comunicar con master(procUnit)
70 """
70 """
71
71
72 self.operations.append(
72 self.operations.append(
73 (operation, conf.type, conf.id, conf.getKwargs()))
73 (operation, conf.type, conf.id, conf.getKwargs()))
74
74
75 if 'plot' in self.name.lower():
75 if 'plot' in self.name.lower():
76 self.plots.append(operation.CODE)
76 self.plots.append(operation.CODE)
77
77
78 def getOperationObj(self, objId):
78 def getOperationObj(self, objId):
79
79
80 if objId not in list(self.operations.keys()):
80 if objId not in list(self.operations.keys()):
81 return None
81 return None
82
82
83 return self.operations[objId]
83 return self.operations[objId]
84
84
85 def operation(self, **kwargs):
85 def operation(self, **kwargs):
86 """
86 """
87 Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los
87 Operacion directa sobre la data (dataOut.data). Es necesario actualizar los valores de los
88 atributos del objeto dataOut
88 atributos del objeto dataOut
89
89
90 Input:
90 Input:
91
91
92 **kwargs : Diccionario de argumentos de la funcion a ejecutar
92 **kwargs : Diccionario de argumentos de la funcion a ejecutar
93 """
93 """
94
94
95 raise NotImplementedError
95 raise NotImplementedError
96
96
97 def setup(self):
97 def setup(self):
98
98
99 raise NotImplementedError
99 raise NotImplementedError
100
100
101 def run(self):
101 def run(self):
102
102
103 raise NotImplementedError
103 raise NotImplementedError
104
104
105 def close(self):
105 def close(self):
106
106
107 return
107 return
108
108
109
109
110 class Operation(object):
110 class Operation(object):
111
111
112 """
112 """
113 Update - Jan 2018 - MULTIPROCESSING
113 Update - Jan 2018 - MULTIPROCESSING
114
114
115 Most of the methods remained the same. The decorator parse the arguments and executed the run() method for each process.
115 Most of the methods remained the same. The decorator parse the arguments and executed the run() method for each process.
116 The constructor doe snot receive any argument, neither the baseclass.
116 The constructor doe snot receive any argument, neither the baseclass.
117
117
118
118
119 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
119 Clase base para definir las operaciones adicionales que se pueden agregar a la clase ProcessingUnit
120 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
120 y necesiten acumular informacion previa de los datos a procesar. De preferencia usar un buffer de
121 acumulacion dentro de esta clase
121 acumulacion dentro de esta clase
122
122
123 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
123 Ejemplo: Integraciones coherentes, necesita la informacion previa de los n perfiles anteriores (bufffer)
124
124
125 """
125 """
126
126
127 def __init__(self):
127 def __init__(self):
128
128
129 self.id = None
129 self.id = None
130 self.isConfig = False
130 self.isConfig = False
131
131
132 if not hasattr(self, 'name'):
132 if not hasattr(self, 'name'):
133 self.name = self.__class__.__name__
133 self.name = self.__class__.__name__
134
134
135 def getAllowedArgs(self):
135 def getAllowedArgs(self):
136 if hasattr(self, '__attrs__'):
136 if hasattr(self, '__attrs__'):
137 return self.__attrs__
137 return self.__attrs__
138 else:
138 else:
139 return inspect.getargspec(self.run).args
139 return inspect.getargspec(self.run).args
140
140
141 def setup(self):
141 def setup(self):
142
142
143 self.isConfig = True
143 self.isConfig = True
144
144
145 raise NotImplementedError
145 raise NotImplementedError
146
146
147 def run(self, dataIn, **kwargs):
147 def run(self, dataIn, **kwargs):
148 """
148 """
149 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
149 Realiza las operaciones necesarias sobre la dataIn.data y actualiza los
150 atributos del objeto dataIn.
150 atributos del objeto dataIn.
151
151
152 Input:
152 Input:
153
153
154 dataIn : objeto del tipo JROData
154 dataIn : objeto del tipo JROData
155
155
156 Return:
156 Return:
157
157
158 None
158 None
159
159
160 Affected:
160 Affected:
161 __buffer : buffer de recepcion de datos.
161 __buffer : buffer de recepcion de datos.
162
162
163 """
163 """
164 if not self.isConfig:
164 if not self.isConfig:
165 self.setup(**kwargs)
165 self.setup(**kwargs)
166
166
167 raise NotImplementedError
167 raise NotImplementedError
168
168
169 def close(self):
169 def close(self):
170
170
171 return
171 return
172
172
173
173
174 def MPDecorator(BaseClass):
174 def MPDecorator(BaseClass):
175 """
175 """
176 Multiprocessing class decorator
176 Multiprocessing class decorator
177
177
178 This function add multiprocessing features to a BaseClass. Also, it handle
178 This function add multiprocessing features to a BaseClass. Also, it handle
179 the communication beetween processes (readers, procUnits and operations).
179 the communication beetween processes (readers, procUnits and operations).
180 """
180 """
181
181
182 class MPClass(BaseClass, Process):
182 class MPClass(BaseClass, Process):
183
183
184 def __init__(self, *args, **kwargs):
184 def __init__(self, *args, **kwargs):
185 super(MPClass, self).__init__()
185 super(MPClass, self).__init__()
186 Process.__init__(self)
186 Process.__init__(self)
187 self.operationKwargs = {}
187 self.operationKwargs = {}
188 self.args = args
188 self.args = args
189 self.kwargs = kwargs
189 self.kwargs = kwargs
190 self.sender = None
190 self.sender = None
191 self.receiver = None
191 self.receiver = None
192 self.name = BaseClass.__name__
192 self.name = BaseClass.__name__
193 if 'plot' in self.name.lower():
194 self.name = '{}{}'.format(self.CODE.upper(), 'Plot')
193 self.start_time = time.time()
195 self.start_time = time.time()
194
196
195 if len(self.args) is 3:
197 if len(self.args) is 3:
196 self.typeProc = "ProcUnit"
198 self.typeProc = "ProcUnit"
197 self.id = args[0]
199 self.id = args[0]
198 self.inputId = args[1]
200 self.inputId = args[1]
199 self.project_id = args[2]
201 self.project_id = args[2]
200 elif len(self.args) is 2:
202 elif len(self.args) is 2:
201 self.id = args[0]
203 self.id = args[0]
202 self.inputId = args[0]
204 self.inputId = args[0]
203 self.project_id = args[1]
205 self.project_id = args[1]
204 self.typeProc = "Operation"
206 self.typeProc = "Operation"
205
207
206 def subscribe(self):
208 def subscribe(self):
207 '''
209 '''
208 This function create a socket to receive objects from the
210 This function create a socket to receive objects from the
209 topic `inputId`.
211 topic `inputId`.
210 '''
212 '''
211
213
212 c = zmq.Context()
214 c = zmq.Context()
213 self.receiver = c.socket(zmq.SUB)
215 self.receiver = c.socket(zmq.SUB)
214 self.receiver.connect(
216 self.receiver.connect(
215 'ipc:///tmp/schain/{}_pub'.format(self.project_id))
217 'ipc:///tmp/schain/{}_pub'.format(self.project_id))
216 self.receiver.setsockopt(zmq.SUBSCRIBE, self.inputId.encode())
218 self.receiver.setsockopt(zmq.SUBSCRIBE, self.inputId.encode())
217
219
218 def listen(self):
220 def listen(self):
219 '''
221 '''
220 This function waits for objects and deserialize using pickle
222 This function waits for objects and deserialize using pickle
221 '''
223 '''
222
224
223 data = pickle.loads(self.receiver.recv_multipart()[1])
225 data = pickle.loads(self.receiver.recv_multipart()[1])
224
226
225 return data
227 return data
226
228
227 def set_publisher(self):
229 def set_publisher(self):
228 '''
230 '''
229 This function create a socket for publishing purposes.
231 This function create a socket for publishing purposes.
230 '''
232 '''
231
233
232 time.sleep(1)
234 time.sleep(1)
233 c = zmq.Context()
235 c = zmq.Context()
234 self.sender = c.socket(zmq.PUB)
236 self.sender = c.socket(zmq.PUB)
235 self.sender.connect(
237 self.sender.connect(
236 'ipc:///tmp/schain/{}_sub'.format(self.project_id))
238 'ipc:///tmp/schain/{}_sub'.format(self.project_id))
237
239
238 def publish(self, data, id):
240 def publish(self, data, id):
239 '''
241 '''
240 This function publish an object, to a specific topic.
242 This function publish an object, to a specific topic.
241 '''
243 '''
242 self.sender.send_multipart([str(id).encode(), pickle.dumps(data)])
244 self.sender.send_multipart([str(id).encode(), pickle.dumps(data)])
243
245
244 def runReader(self):
246 def runReader(self):
245 '''
247 '''
246 Run fuction for read units
248 Run fuction for read units
247 '''
249 '''
248 while True:
250 while True:
249
251
250 BaseClass.run(self, **self.kwargs)
252 BaseClass.run(self, **self.kwargs)
251
253
252 for op, optype, opId, kwargs in self.operations:
254 for op, optype, opId, kwargs in self.operations:
253 if optype == 'self':
255 if optype == 'self':
254 op(**kwargs)
256 op(**kwargs)
255 elif optype == 'other':
257 elif optype == 'other':
256 self.dataOut = op.run(self.dataOut, **self.kwargs)
258 self.dataOut = op.run(self.dataOut, **self.kwargs)
257 elif optype == 'external':
259 elif optype == 'external':
258 self.publish(self.dataOut, opId)
260 self.publish(self.dataOut, opId)
259
261
260 if self.dataOut.flagNoData and self.dataOut.error is None:
262 if self.dataOut.flagNoData and not self.dataOut.error:
261 continue
263 continue
262
264
263 self.publish(self.dataOut, self.id)
265 self.publish(self.dataOut, self.id)
264
266
265 if self.dataOut.error:
267 if self.dataOut.error:
266 if self.dataOut.error[0] == -1:
268 log.error(self.dataOut.error, self.name)
267 log.error(self.dataOut.error[1], self.name)
268 if self.dataOut.error[0] == 1:
269 log.success(self.dataOut.error[1], self.name)
270 # self.sender.send_multipart([str(self.project_id).encode(), 'end'.encode()])
269 # self.sender.send_multipart([str(self.project_id).encode(), 'end'.encode()])
271 break
270 break
272
271
273 time.sleep(1)
272 time.sleep(1)
274
273
275 def runProc(self):
274 def runProc(self):
276 '''
275 '''
277 Run function for proccessing units
276 Run function for proccessing units
278 '''
277 '''
279
278
280 while True:
279 while True:
281 self.dataIn = self.listen()
280 self.dataIn = self.listen()
282
281
283 if self.dataIn.flagNoData and self.dataIn.error is None:
282 if self.dataIn.flagNoData and self.dataIn.error is None:
284 continue
283 continue
285
284
286 BaseClass.run(self, **self.kwargs)
285 BaseClass.run(self, **self.kwargs)
287
286
288 if self.dataOut.flagNoData:
287 if self.dataIn.error:
289 continue
288 self.dataOut.error = self.dataIn.error
289 self.dataOut.flagNoData = True
290
290
291 for op, optype, opId, kwargs in self.operations:
291 for op, optype, opId, kwargs in self.operations:
292 if optype == 'self':
292 if optype == 'self':
293 op(**kwargs)
293 op(**kwargs)
294 elif optype == 'other':
294 elif optype == 'other':
295 self.dataOut = op.run(self.dataOut, **kwargs)
295 self.dataOut = op.run(self.dataOut, **kwargs)
296 elif optype == 'external':
296 elif optype == 'external':
297 if not self.dataOut.flagNoData or self.dataOut.error:
297 self.publish(self.dataOut, opId)
298 self.publish(self.dataOut, opId)
298
299
299 self.publish(self.dataOut, self.id)
300 self.publish(self.dataOut, self.id)
300 if self.dataIn.error:
301 if self.dataIn.error:
301 break
302 break
302
303
303 time.sleep(1)
304 time.sleep(1)
304
305
305 def runOp(self):
306 def runOp(self):
306 '''
307 '''
307 Run function for external operations (this operations just receive data
308 Run function for external operations (this operations just receive data
308 ex: plots, writers, publishers)
309 ex: plots, writers, publishers)
309 '''
310 '''
310
311
311 while True:
312 while True:
312
313
313 dataOut = self.listen()
314 dataOut = self.listen()
314
315
315 BaseClass.run(self, dataOut, **self.kwargs)
316 BaseClass.run(self, dataOut, **self.kwargs)
316
317
317 if dataOut.error:
318 if dataOut.error:
318 break
319 break
320
319 time.sleep(1)
321 time.sleep(1)
320
322
321 def run(self):
323 def run(self):
322 if self.typeProc is "ProcUnit":
324 if self.typeProc is "ProcUnit":
323
325
324 if self.inputId is not None:
326 if self.inputId is not None:
325
327
326 self.subscribe()
328 self.subscribe()
327
329
328 self.set_publisher()
330 self.set_publisher()
329
331
330 if 'Reader' not in BaseClass.__name__:
332 if 'Reader' not in BaseClass.__name__:
331 self.runProc()
333 self.runProc()
332 else:
334 else:
333 self.runReader()
335 self.runReader()
334
336
335 elif self.typeProc is "Operation":
337 elif self.typeProc is "Operation":
336
338
337 self.subscribe()
339 self.subscribe()
338 self.runOp()
340 self.runOp()
339
341
340 else:
342 else:
341 raise ValueError("Unknown type")
343 raise ValueError("Unknown type")
342
344
343 self.close()
345 self.close()
344
346
345 def event_monitor(self, monitor):
347 def event_monitor(self, monitor):
346
348
347 events = {}
349 events = {}
348
350
349 for name in dir(zmq):
351 for name in dir(zmq):
350 if name.startswith('EVENT_'):
352 if name.startswith('EVENT_'):
351 value = getattr(zmq, name)
353 value = getattr(zmq, name)
352 events[value] = name
354 events[value] = name
353
355
354 while monitor.poll():
356 while monitor.poll():
355 evt = recv_monitor_message(monitor)
357 evt = recv_monitor_message(monitor)
356 if evt['event'] == 32:
358 if evt['event'] == 32:
357 self.connections += 1
359 self.connections += 1
358 if evt['event'] == 512:
360 if evt['event'] == 512:
359 pass
361 pass
360
362
361 evt.update({'description': events[evt['event']]})
363 evt.update({'description': events[evt['event']]})
362
364
363 if evt['event'] == zmq.EVENT_MONITOR_STOPPED:
365 if evt['event'] == zmq.EVENT_MONITOR_STOPPED:
364 break
366 break
365 monitor.close()
367 monitor.close()
366 print('event monitor thread done!')
368 print('event monitor thread done!')
367
369
368 def close(self):
370 def close(self):
369
371
370 BaseClass.close(self)
372 BaseClass.close(self)
371
373
372 if self.sender:
374 if self.sender:
373 self.sender.close()
375 self.sender.close()
374
376
375 if self.receiver:
377 if self.receiver:
376 self.receiver.close()
378 self.receiver.close()
377
379
378 log.success('Done...(Time:{:4.2f} secs)'.format(time.time()-self.start_time), self.name)
380 log.success('Done...(Time:{:4.2f} secs)'.format(time.time()-self.start_time), self.name)
379
381
380 return MPClass
382 return MPClass
General Comments 0
You need to be logged in to leave comments. Login now