##// END OF EJS Templates
Merge branch 'schain_alarm' into v2.3
Juan C. Espinoza -
r1159:d0480f11c356 merge
parent child
Show More
@@ -1,498 +1,503
1 """The admin module contains all administrative classes relating to the schain python api.
1 """
2 The admin module contains all administrative classes relating to the schain python api.
2
3
3 The main role of this module is to send some reports. It contains a
4 The main role of this module is to send some reports. It contains a
4 notification class and a standard error handing class.
5 notification class and a standard error handing class.
5
6
6 $Id: admin.py 3966 2015-12-01 14:32:29Z miguel.urco $
7 $Id: admin.py 3966 2015-12-01 14:32:29Z miguel.urco $
7 """
8 """
8 import os
9 import os
9 import sys
10 import sys
10 import time
11 import time
11 import traceback
12 import traceback
12 import smtplib
13 import smtplib
13 import ConfigParser
14 import ConfigParser
14 import StringIO
15 import StringIO
15 from threading import Thread
16 from threading import Thread
16 from multiprocessing import Process
17 from multiprocessing import Process
17 from email.mime.text import MIMEText
18 from email.mime.text import MIMEText
18 from email.mime.application import MIMEApplication
19 from email.mime.application import MIMEApplication
19 from email.mime.multipart import MIMEMultipart
20 from email.mime.multipart import MIMEMultipart
20
21
22 import schainpy
21 from schainpy.utils import log
23 from schainpy.utils import log
22 from schainpy.model.graphics.jroplot_data import popup
24 from schainpy.model.graphics.jroplot_data import popup
23
25
24 def get_path():
26 def get_path():
25 '''
27 '''
26 Return schainpy path
28 Return schainpy path
27 '''
29 '''
28
30
29 try:
31 try:
30 root = __file__
32 root = __file__
31 if os.path.islink(root):
33 if os.path.islink(root):
32 root = os.path.realpath(root)
34 root = os.path.realpath(root)
33
35
34 return os.path.dirname(os.path.abspath(root))
36 return os.path.dirname(os.path.abspath(root))
35 except:
37 except:
36 log.error('I am sorry, but something is wrong... __file__ not found')
38 log.error('I am sorry, but something is wrong... __file__ not found')
37
39
38 class Alarm(Process):
40 class Alarm(Process):
39 '''
41 '''
40 modes:
42 modes:
41 0 - All
43 0 - All
42 1 - Sound alarm
44 1 - Send email
43 2 - Send email
45 2 - Popup message
44 3 - Popup message
46 3 - Sound alarm
45 4 - Send to alarm system TODO
47 4 - Send to alarm system TODO
46 '''
48 '''
47
49
48 def __init__(self, modes=[1], **kwargs):
50 def __init__(self, modes=[], **kwargs):
49 Process.__init__(self)
51 Process.__init__(self)
50 self.modes = modes
52 self.modes = modes
51 self.kwargs = kwargs
53 self.kwargs = kwargs
52
54
53 @staticmethod
55 @staticmethod
54 def play_sound():
56 def play_sound():
55 sound = os.path.join(get_path(), 'alarm1.oga')
57 sound = os.path.join(get_path(), 'alarm1.oga')
56 if os.path.exists(sound):
58 if os.path.exists(sound):
57 for __ in range(2):
59 for __ in range(2):
58 os.system('paplay {}'.format(sound))
60 os.system('paplay {}'.format(sound))
59 time.sleep(0.5)
61 time.sleep(0.5)
60 else:
62 else:
61 log.warning('Unable to play alarm, sound file not found', 'ADMIN')
63 log.warning('Unable to play alarm, sound file not found', 'ADMIN')
62
64
63 @staticmethod
65 @staticmethod
64 def send_email(**kwargs):
66 def send_email(**kwargs):
65 notifier = SchainNotify()
67 notifier = SchainNotify()
68 print kwargs
66 notifier.notify(**kwargs)
69 notifier.notify(**kwargs)
67
70
68 @staticmethod
71 @staticmethod
69 def show_popup(message='Error'):
72 def show_popup(message):
73 if isinstance(message, list):
74 message = message[-1]
70 popup(message)
75 popup(message)
71
76
72 @staticmethod
77 @staticmethod
73 def send_alarm():
78 def send_alarm():
74 pass
79 pass
75
80
76 @staticmethod
81 @staticmethod
77 def get_kwargs(kwargs, keys):
82 def get_kwargs(kwargs, keys):
78 ret = {}
83 ret = {}
79 for key in keys:
84 for key in keys:
80 ret[key] = kwargs[key]
85 ret[key] = kwargs[key]
81 return ret
86 return ret
82
87
83 def run(self):
88 def run(self):
84 tasks = {
89 tasks = {
85 1 : self.send_email,
90 1 : self.send_email,
86 2 : self.play_sound,
91 2 : self.show_popup,
87 3 : self.show_popup,
92 3 : self.play_sound,
88 4 : self.send_alarm,
93 4 : self.send_alarm,
89 }
94 }
90
95
91 tasks_args = {
96 tasks_args = {
92 1: ['email', 'message', 'subject', 'subtitle', 'filename'],
97 1: ['email', 'message', 'subject', 'subtitle', 'filename'],
93 2: [],
98 2: ['message'],
94 3: ['message'],
99 3: [],
95 4: [],
100 4: [],
96 }
101 }
97 procs = []
102 procs = []
98 for mode in self.modes:
103 for mode in self.modes:
99 if 0 in self.modes:
104 if 0 in self.modes:
100 for x in tasks:
105 for x in tasks:
101 t = Thread(target=tasks[x], kwargs=self.get_kwargs(self.kwargs, tasks_args[x]))
106 t = Thread(target=tasks[x], kwargs=self.get_kwargs(self.kwargs, tasks_args[x]))
102 t.start()
107 t.start()
103 procs.append(t)
108 procs.append(t)
104 break
109 break
105 else:
110 else:
106 t = Thread(target=tasks[mode], kwargs=self.get_kwargs(self.kwargs, tasks_args[mode]))
111 t = Thread(target=tasks[mode], kwargs=self.get_kwargs(self.kwargs, tasks_args[mode]))
107 t.start()
112 t.start()
108 procs.append(t)
113 procs.append(t)
109 for t in procs:
114 for t in procs:
110 t.join()
115 t.join()
111
116
112
117
113 class SchainConfigure():
118 class SchainConfigure():
114
119
115 __DEFAULT_ADMINISTRATOR_EMAIL = "juan.espinoza@jro.igp.gob.pe"
120 __DEFAULT_ADMINISTRATOR_EMAIL = "juan.espinoza@jro.igp.gob.pe"
116 __DEFAULT_EMAIL_SERVER = "jro-zimbra.igp.gob.pe"
121 __DEFAULT_EMAIL_SERVER = "jro-zimbra.igp.gob.pe"
117 __DEFAULT_SENDER_EMAIL = "notifier-schain@jro.igp.gob.pe"
122 __DEFAULT_SENDER_EMAIL = "notifier-schain@jro.igp.gob.pe"
118 __DEFAULT_SENDER_PASS = ""
123 __DEFAULT_SENDER_PASS = ""
119
124
120 __SCHAIN_ADMINISTRATOR_EMAIL = "CONTACT"
125 __SCHAIN_ADMINISTRATOR_EMAIL = "CONTACT"
121 __SCHAIN_EMAIL_SERVER = "MAILSERVER"
126 __SCHAIN_EMAIL_SERVER = "MAILSERVER"
122 __SCHAIN_SENDER_EMAIL = "MAILSERVER_ACCOUNT"
127 __SCHAIN_SENDER_EMAIL = "MAILSERVER_ACCOUNT"
123 __SCHAIN_SENDER_PASS = "MAILSERVER_PASSWORD"
128 __SCHAIN_SENDER_PASS = "MAILSERVER_PASSWORD"
124
129
125 def __init__(self, initFile = None):
130 def __init__(self, initFile = None):
126
131
127 # Set configuration file
132 # Set configuration file
128 if (initFile == None):
133 if (initFile == None):
129 self.__confFilePath = "/etc/schain.conf"
134 self.__confFilePath = "/etc/schain.conf"
130 else:
135 else:
131 self.__confFilePath = initFile
136 self.__confFilePath = initFile
132
137
133 # open configuration file
138 # open configuration file
134 try:
139 try:
135 self.__confFile = open(self.__confFilePath, "r")
140 self.__confFile = open(self.__confFilePath, "r")
136 except IOError:
141 except IOError:
137 # can't read from file - use all hard-coded values
142 # can't read from file - use all hard-coded values
138 self.__initFromHardCode()
143 self.__initFromHardCode()
139 return
144 return
140
145
141 # create Parser using standard module ConfigParser
146 # create Parser using standard module ConfigParser
142 self.__parser = ConfigParser.ConfigParser()
147 self.__parser = ConfigParser.ConfigParser()
143
148
144 # read conf file into a StringIO with "[madrigal]\n" section heading prepended
149 # read conf file into a StringIO with "[madrigal]\n" section heading prepended
145 strConfFile = StringIO.StringIO("[schain]\n" + self.__confFile.read())
150 strConfFile = StringIO.StringIO("[schain]\n" + self.__confFile.read())
146
151
147 # parse StringIO configuration file
152 # parse StringIO configuration file
148 self.__parser.readfp(strConfFile)
153 self.__parser.readfp(strConfFile)
149
154
150 # read information from configuration file
155 # read information from configuration file
151 self.__readConfFile()
156 self.__readConfFile()
152
157
153 # close conf file
158 # close conf file
154 self.__confFile.close()
159 self.__confFile.close()
155
160
156
161
157 def __initFromHardCode(self):
162 def __initFromHardCode(self):
158
163
159 self.__sender_email = self.__DEFAULT_SENDER_EMAIL
164 self.__sender_email = self.__DEFAULT_SENDER_EMAIL
160 self.__sender_pass = self.__DEFAULT_SENDER_PASS
165 self.__sender_pass = self.__DEFAULT_SENDER_PASS
161 self.__admin_email = self.__DEFAULT_ADMINISTRATOR_EMAIL
166 self.__admin_email = self.__DEFAULT_ADMINISTRATOR_EMAIL
162 self.__email_server = self.__DEFAULT_EMAIL_SERVER
167 self.__email_server = self.__DEFAULT_EMAIL_SERVER
163
168
164 def __readConfFile(self):
169 def __readConfFile(self):
165 """__readConfFile is a private helper function that reads information from the parsed config file.
170 """__readConfFile is a private helper function that reads information from the parsed config file.
166
171
167 Inputs: None
172 Inputs: None
168
173
169 Returns: Void.
174 Returns: Void.
170
175
171 Affects: Initializes class member variables that are found in the config file.
176 Affects: Initializes class member variables that are found in the config file.
172
177
173 Exceptions: MadrigalError thrown if any key not found.
178 Exceptions: MadrigalError thrown if any key not found.
174 """
179 """
175
180
176 # get the sender email
181 # get the sender email
177 try:
182 try:
178 self.__sender_email = self.__parser.get("schain", self.__SCHAIN_SENDER_EMAIL)
183 self.__sender_email = self.__parser.get("schain", self.__SCHAIN_SENDER_EMAIL)
179 except:
184 except:
180 self.__sender_email = self.__DEFAULT_SENDER_EMAIL
185 self.__sender_email = self.__DEFAULT_SENDER_EMAIL
181
186
182 # get the sender password
187 # get the sender password
183 try:
188 try:
184 self.__sender_pass = self.__parser.get("schain", self.__SCHAIN_SENDER_PASS)
189 self.__sender_pass = self.__parser.get("schain", self.__SCHAIN_SENDER_PASS)
185 except:
190 except:
186 self.__sender_pass = self.__DEFAULT_SENDER_PASS
191 self.__sender_pass = self.__DEFAULT_SENDER_PASS
187
192
188 # get the administrator email
193 # get the administrator email
189 try:
194 try:
190 self.__admin_email = self.__parser.get("schain", self.__SCHAIN_ADMINISTRATOR_EMAIL)
195 self.__admin_email = self.__parser.get("schain", self.__SCHAIN_ADMINISTRATOR_EMAIL)
191 except:
196 except:
192 self.__admin_email = self.__DEFAULT_ADMINISTRATOR_EMAIL
197 self.__admin_email = self.__DEFAULT_ADMINISTRATOR_EMAIL
193
198
194 # get the server email
199 # get the server email
195 try:
200 try:
196 self.__email_server = self.__parser.get("schain", self.__SCHAIN_EMAIL_SERVER)
201 self.__email_server = self.__parser.get("schain", self.__SCHAIN_EMAIL_SERVER)
197 except:
202 except:
198 self.__email_server = self.__DEFAULT_EMAIL_SERVER
203 self.__email_server = self.__DEFAULT_EMAIL_SERVER
199
204
200 def getEmailServer(self):
205 def getEmailServer(self):
201
206
202 return self.__email_server
207 return self.__email_server
203
208
204 def getSenderEmail(self):
209 def getSenderEmail(self):
205
210
206 return self.__sender_email
211 return self.__sender_email
207
212
208 def getSenderPass(self):
213 def getSenderPass(self):
209
214
210 return self.__sender_pass
215 return self.__sender_pass
211
216
212 def getAdminEmail(self):
217 def getAdminEmail(self):
213
218
214 return self.__admin_email
219 return self.__admin_email
215
220
216 class SchainNotify:
221 class SchainNotify:
217 """SchainNotify is an object used to send messages to an administrator about a Schain software.
222 """SchainNotify is an object used to send messages to an administrator about a Schain software.
218
223
219 This object provides functions needed to send messages to an administrator about a Schain , for now
224 This object provides functions needed to send messages to an administrator about a Schain , for now
220 only sendAlert, which sends an email to the site administrator found is ADMIN_EMAIL
225 only sendAlert, which sends an email to the site administrator found is ADMIN_EMAIL
221
226
222 Usage example:
227 Usage example:
223
228
224 import schainpy.admin
229 import schainpy.admin
225
230
226 try:
231 try:
227
232
228 adminObj = schainpy.admin.SchainNotify()
233 adminObj = schainpy.admin.SchainNotify()
229 adminObj.sendAlert('This is important!', 'Important Message')
234 adminObj.sendAlert('This is important!', 'Important Message')
230
235
231 except schainpy.admin.SchainError, e:
236 except schainpy.admin.SchainError, e:
232
237
233 print e.getExceptionStr()
238 print e.getExceptionStr()
234
239
235
240
236 Non-standard Python modules used:
241 Non-standard Python modules used:
237 None
242 None
238
243
239 Exceptions thrown: None - Note that SchainNotify tries every trick it knows to avoid
244 Exceptions thrown: None - Note that SchainNotify tries every trick it knows to avoid
240 throwing exceptions, since this is the class that will generally be called when there is a problem.
245 throwing exceptions, since this is the class that will generally be called when there is a problem.
241
246
242 Change history:
247 Change history:
243
248
244 Written by "Miguel Urco":mailto:miguel.urco@jro.igp.gob.pe Dec. 1, 2015
249 Written by "Miguel Urco":mailto:miguel.urco@jro.igp.gob.pe Dec. 1, 2015
245 """
250 """
246
251
247 #constants
252 #constants
248
253
249 def __init__(self):
254 def __init__(self):
250 """__init__ initializes SchainNotify by getting some basic information from SchainDB and SchainSite.
255 """__init__ initializes SchainNotify by getting some basic information from SchainDB and SchainSite.
251
256
252 Note that SchainNotify tries every trick it knows to avoid throwing exceptions, since
257 Note that SchainNotify tries every trick it knows to avoid throwing exceptions, since
253 this is the class that will generally be called when there is a problem.
258 this is the class that will generally be called when there is a problem.
254
259
255 Inputs: Existing SchainDB object, by default = None.
260 Inputs: Existing SchainDB object, by default = None.
256
261
257 Returns: void
262 Returns: void
258
263
259 Affects: Initializes self.__binDir.
264 Affects: Initializes self.__binDir.
260
265
261 Exceptions: None.
266 Exceptions: None.
262 """
267 """
263
268
264 # note that the main configuration file is unavailable
269 # note that the main configuration file is unavailable
265 # the best that can be done is send an email to root using localhost mailserver
270 # the best that can be done is send an email to root using localhost mailserver
266 confObj = SchainConfigure()
271 confObj = SchainConfigure()
267
272
268 self.__emailFromAddress = confObj.getSenderEmail()
273 self.__emailFromAddress = confObj.getSenderEmail()
269 self.__emailPass = confObj.getSenderPass()
274 self.__emailPass = confObj.getSenderPass()
270 self.__emailToAddress = confObj.getAdminEmail()
275 self.__emailToAddress = confObj.getAdminEmail()
271 self.__emailServer = confObj.getEmailServer()
276 self.__emailServer = confObj.getEmailServer()
272
277
273 def sendEmail(self, email_from, email_to, subject='Error running ...', message="", subtitle="", filename="", html_format=True):
278 def sendEmail(self, email_from, email_to, subject='Error running ...', message="", subtitle="", filename="", html_format=True):
274
279
275 if not email_to:
280 if not email_to:
276 return 0
281 return 0
277
282
278 if not self.__emailServer:
283 if not self.__emailServer:
279 return 0
284 return 0
280
285
281 log.success('Sending email to {}...'.format(email_to), 'System')
286 log.success('Sending email to {}...'.format(email_to), 'System')
282
287
283 msg = MIMEMultipart()
288 msg = MIMEMultipart()
284 msg['Subject'] = subject
289 msg['Subject'] = subject
285 msg['From'] = "(Python SChain API): " + email_from
290 msg['From'] = "(Python SChain API): " + email_from
286 msg['Reply-to'] = email_from
291 msg['Reply-to'] = email_from
287 msg['To'] = email_to
292 msg['To'] = email_to
288
293
289 # That is what u see if dont have an email reader:
294 # That is what u see if dont have an email reader:
290 msg.preamble = 'SChainPy'
295 msg.preamble = 'SChainPy'
291
296
292 if html_format:
297 if html_format:
293 message = "<h1> %s </h1>" %subject + "<h3>" + subtitle.replace("\n", "</h3><h3>\n") + "</h3>" + message.replace("\n", "<br>\n")
298 message = "<h1> %s </h1>" %subject + "<h3>" + subtitle.replace("\n", "</h3><h3>\n") + "</h3>" + message.replace("\n", "<br>\n")
294 message = "<html>\n" + message + '</html>'
299 message = "<html>\n" + message + '</html>'
295
300
296 # This is the textual part:
301 # This is the textual part:
297 part = MIMEText(message, "html")
302 part = MIMEText(message, "html")
298 else:
303 else:
299 message = subject + "\n" + subtitle + "\n" + message
304 message = subject + "\n" + subtitle + "\n" + message
300 part = MIMEText(message)
305 part = MIMEText(message)
301
306
302 msg.attach(part)
307 msg.attach(part)
303
308
304 if filename and os.path.isfile(filename):
309 if filename and os.path.isfile(filename):
305 # This is the binary part(The Attachment):
310 # This is the binary part(The Attachment):
306 part = MIMEApplication(open(filename,"rb").read())
311 part = MIMEApplication(open(filename,"rb").read())
307 part.add_header('Content-Disposition',
312 part.add_header('Content-Disposition',
308 'attachment',
313 'attachment',
309 filename=os.path.basename(filename))
314 filename=os.path.basename(filename))
310 msg.attach(part)
315 msg.attach(part)
311
316
312 # Create an instance in SMTP server
317 # Create an instance in SMTP server
313 try:
318 try:
314 smtp = smtplib.SMTP(self.__emailServer)
319 smtp = smtplib.SMTP(self.__emailServer)
315 except:
320 except:
316 log.error('Could not connect to server {}'.format(self.__emailServer), 'System')
321 log.error('Could not connect to server {}'.format(self.__emailServer), 'System')
317 return 0
322 return 0
318
323
319 # Start the server:
324 # Start the server:
320 # smtp.ehlo()
325 # smtp.ehlo()
321 if self.__emailPass:
326 if self.__emailPass:
322 smtp.login(self.__emailFromAddress, self.__emailPass)
327 smtp.login(self.__emailFromAddress, self.__emailPass)
323
328
324 # Send the email
329 # Send the email
325 try:
330 try:
326 smtp.sendmail(msg['From'], msg['To'], msg.as_string())
331 smtp.sendmail(msg['From'], msg['To'], msg.as_string())
327 except:
332 except:
328 log.error('Could not send the email to {}'.format(msg['To']), 'System')
333 log.error('Could not send the email to {}'.format(msg['To']), 'System')
329 smtp.quit()
334 smtp.quit()
330 return 0
335 return 0
331
336
332 smtp.quit()
337 smtp.quit()
333
338
334 log.success('Email sent ', 'System')
339 log.success('Email sent ', 'System')
335
340
336 return 1
341 return 1
337
342
338 def sendAlert(self, message, subject = "", subtitle="", filename=""):
343 def sendAlert(self, message, subject = "", subtitle="", filename=""):
339 """sendAlert sends an email with the given message and optional title.
344 """sendAlert sends an email with the given message and optional title.
340
345
341 Inputs: message (string), and optional title (string)
346 Inputs: message (string), and optional title (string)
342
347
343 Returns: void
348 Returns: void
344
349
345 Affects: none
350 Affects: none
346
351
347 Exceptions: None.
352 Exceptions: None.
348 """
353 """
349
354
350 if not self.__emailToAddress:
355 if not self.__emailToAddress:
351 return 0
356 return 0
352
357
353 print "***** Sending alert to %s *****" %self.__emailToAddress
358 print "***** Sending alert to %s *****" %self.__emailToAddress
354 # set up message
359 # set up message
355
360
356 sent=self.sendEmail(email_from=self.__emailFromAddress,
361 sent=self.sendEmail(email_from=self.__emailFromAddress,
357 email_to=self.__emailToAddress,
362 email_to=self.__emailToAddress,
358 subject=subject,
363 subject=subject,
359 message=message,
364 message=message,
360 subtitle=subtitle,
365 subtitle=subtitle,
361 filename=filename)
366 filename=filename)
362
367
363 if not sent:
368 if not sent:
364 return 0
369 return 0
365
370
366 return 1
371 return 1
367
372
368 def notify(self, email, message, subject = "", subtitle="", filename=""):
373 def notify(self, email, message, subject = "", subtitle="", filename=""):
369 """notify sends an email with the given message and title to email.
374 """notify sends an email with the given message and title to email.
370
375
371 Inputs: email (string), message (string), and subject (string)
376 Inputs: email (string), message (string), and subject (string)
372
377
373 Returns: void
378 Returns: void
374
379
375 Affects: none
380 Affects: none
376
381
377 Exceptions: None.
382 Exceptions: None.
378 """
383 """
379
384
380 if email is None:
385 if email is None:
381 email = self.__emailToAddress
386 email = self.__emailToAddress
382
387
383 self.sendEmail(
388 self.sendEmail(
384 email_from=self.__emailFromAddress,
389 email_from=self.__emailFromAddress,
385 email_to=email,
390 email_to=email,
386 subject=subject,
391 subject=subject,
387 message=message,
392 message=message,
388 subtitle=subtitle,
393 subtitle=subtitle,
389 filename=filename
394 filename=filename
390 )
395 )
391
396
392
397
393 class SchainError(Exception):
398 class SchainError(Exception):
394 """SchainError is an exception class that is thrown for all known errors using Schain Py lib.
399 """SchainError is an exception class that is thrown for all known errors using Schain Py lib.
395
400
396 Usage example:
401 Usage example:
397
402
398 import sys, traceback
403 import sys, traceback
399 import schainpy.admin
404 import schainpy.admin
400
405
401 try:
406 try:
402
407
403 test = open('ImportantFile.txt', 'r')
408 test = open('ImportantFile.txt', 'r')
404
409
405 except:
410 except:
406
411
407 raise schainpy.admin.SchainError('ImportantFile.txt not opened!',
412 raise schainpy.admin.SchainError('ImportantFile.txt not opened!',
408 traceback.format_exception(sys.exc_info()[0],
413 traceback.format_exception(sys.exc_info()[0],
409 sys.exc_info()[1],
414 sys.exc_info()[1],
410 sys.exc_info()[2]))
415 sys.exc_info()[2]))
411 """
416 """
412
417
413
418
414 def __init__(self, strInterpretation, exceptionList=None):
419 def __init__(self, strInterpretation, exceptionList=None):
415 """ __init__ gathers the interpretation string along with all information from sys.exc_info().
420 """ __init__ gathers the interpretation string along with all information from sys.exc_info().
416
421
417 Inputs:
422 Inputs:
418 strIntepretation - A string representing the programmer's interpretation of
423 strIntepretation - A string representing the programmer's interpretation of
419 why the exception occurred
424 why the exception occurred
420
425
421 exceptionList - a list of strings completely describing the exception.
426 exceptionList - a list of strings completely describing the exception.
422 Generated by traceback.format_exception(sys.exc_info()[0],
427 Generated by traceback.format_exception(sys.exc_info()[0],
423 sys.exc_info()[1],
428 sys.exc_info()[1],
424 sys.exc_info()[2])
429 sys.exc_info()[2])
425
430
426 Returns: Void.
431 Returns: Void.
427
432
428 Affects: Initializes class member variables _strInterp, _strExcList.
433 Affects: Initializes class member variables _strInterp, _strExcList.
429
434
430 Exceptions: None.
435 Exceptions: None.
431 """
436 """
432
437
433 if not exceptionList:
438 if not exceptionList:
434 exceptionList = traceback.format_exception(sys.exc_info()[0],
439 exceptionList = traceback.format_exception(sys.exc_info()[0],
435 sys.exc_info()[1],
440 sys.exc_info()[1],
436 sys.exc_info()[2])
441 sys.exc_info()[2])
437
442
438 self._strInterp = strInterpretation
443 self._strInterp = strInterpretation
439 self._strExcList = exceptionList
444 self._strExcList = exceptionList
440
445
441
446
442 def getExceptionStr(self):
447 def getExceptionStr(self):
443 """ getExceptionStr returns a formatted string ready for printing completely describing the exception.
448 """ getExceptionStr returns a formatted string ready for printing completely describing the exception.
444
449
445 Inputs: None
450 Inputs: None
446
451
447 Returns: A formatted string ready for printing completely describing the exception.
452 Returns: A formatted string ready for printing completely describing the exception.
448
453
449 Affects: None
454 Affects: None
450
455
451 Exceptions: None.
456 Exceptions: None.
452 """
457 """
453 excStr = ''
458 excStr = ''
454 excStr = excStr + self._strInterp + '\n\n'
459 excStr = excStr + self._strInterp + '\n\n'
455
460
456 if self._strExcList != None:
461 if self._strExcList != None:
457 for item in self._strExcList:
462 for item in self._strExcList:
458 excStr = excStr + str(item) + '\n'
463 excStr = excStr + str(item) + '\n'
459
464
460 return excStr
465 return excStr
461
466
462 def __str__(self):
467 def __str__(self):
463
468
464 return(self.getExceptionStr())
469 return(self.getExceptionStr())
465
470
466
471
467 def getExceptionHtml(self):
472 def getExceptionHtml(self):
468 """ getExceptionHtml returns an Html formatted string completely describing the exception.
473 """ getExceptionHtml returns an Html formatted string completely describing the exception.
469
474
470 Inputs: None
475 Inputs: None
471
476
472 Returns: A formatted string ready for printing completely describing the exception.
477 Returns: A formatted string ready for printing completely describing the exception.
473
478
474 Affects: None
479 Affects: None
475
480
476 Exceptions: None.
481 Exceptions: None.
477 """
482 """
478
483
479 excStr = '<BR>The following Schain Python exception has occurred:\n<BR>'
484 excStr = '<BR>The following Schain Python exception has occurred:\n<BR>'
480 excStr = excStr + self._strInterp + '\n<BR>\n'
485 excStr = excStr + self._strInterp + '\n<BR>\n'
481
486
482 if self._strExcList != None:
487 if self._strExcList != None:
483 for item in self._strExcList:
488 for item in self._strExcList:
484 excStr = excStr + str(item) + '\n<BR>'
489 excStr = excStr + str(item) + '\n<BR>'
485
490
486 return excStr
491 return excStr
487
492
488 class SchainWarning(Exception):
493 class SchainWarning(Exception):
489 pass
494 pass
490
495
491
496
492 if __name__ == '__main__':
497 if __name__ == '__main__':
493
498
494 test = SchainNotify()
499 test = SchainNotify()
495
500
496 test.sendAlert('This is a message from the python module SchainNotify', 'Test from SchainNotify')
501 test.sendAlert('This is a message from the python module SchainNotify', 'Test from SchainNotify')
497
502
498 print 'Hopefully message sent - check.'
503 print 'Hopefully message sent - check.'
@@ -1,1330 +1,1337
1 '''
1 '''
2 Created on September , 2012
2 Created on September , 2012
3 @author:
3 @author:
4 '''
4 '''
5
5
6 import sys
6 import sys
7 import ast
7 import ast
8 import datetime
8 import datetime
9 import traceback
9 import traceback
10 import math
10 import math
11 import time
11 import time
12 from multiprocessing import Process, cpu_count
12 from multiprocessing import Process, cpu_count
13
13
14 from xml.etree.ElementTree import ElementTree, Element, SubElement, tostring
14 from xml.etree.ElementTree import ElementTree, Element, SubElement, tostring
15 from xml.dom import minidom
15 from xml.dom import minidom
16
16
17 import schainpy
17 import schainpy
18 from schainpy.admin import Alarm, SchainWarning
18 from schainpy.admin import Alarm, SchainWarning
19 from schainpy.model import *
19 from schainpy.model import *
20 from schainpy.utils import log
20 from schainpy.utils import log
21
21
22 DTYPES = {
22 DTYPES = {
23 'Voltage': '.r',
23 'Voltage': '.r',
24 'Spectra': '.pdata'
24 'Spectra': '.pdata'
25 }
25 }
26
26
27
27
28 def MPProject(project, n=cpu_count()):
28 def MPProject(project, n=cpu_count()):
29 '''
29 '''
30 Project wrapper to run schain in n processes
30 Project wrapper to run schain in n processes
31 '''
31 '''
32
32
33 rconf = project.getReadUnitObj()
33 rconf = project.getReadUnitObj()
34 op = rconf.getOperationObj('run')
34 op = rconf.getOperationObj('run')
35 dt1 = op.getParameterValue('startDate')
35 dt1 = op.getParameterValue('startDate')
36 dt2 = op.getParameterValue('endDate')
36 dt2 = op.getParameterValue('endDate')
37 tm1 = op.getParameterValue('startTime')
37 tm1 = op.getParameterValue('startTime')
38 tm2 = op.getParameterValue('endTime')
38 tm2 = op.getParameterValue('endTime')
39 days = (dt2 - dt1).days
39 days = (dt2 - dt1).days
40
40
41 for day in range(days + 1):
41 for day in range(days + 1):
42 skip = 0
42 skip = 0
43 cursor = 0
43 cursor = 0
44 processes = []
44 processes = []
45 dt = dt1 + datetime.timedelta(day)
45 dt = dt1 + datetime.timedelta(day)
46 dt_str = dt.strftime('%Y/%m/%d')
46 dt_str = dt.strftime('%Y/%m/%d')
47 reader = JRODataReader()
47 reader = JRODataReader()
48 paths, files = reader.searchFilesOffLine(path=rconf.path,
48 paths, files = reader.searchFilesOffLine(path=rconf.path,
49 startDate=dt,
49 startDate=dt,
50 endDate=dt,
50 endDate=dt,
51 startTime=tm1,
51 startTime=tm1,
52 endTime=tm2,
52 endTime=tm2,
53 ext=DTYPES[rconf.datatype])
53 ext=DTYPES[rconf.datatype])
54 nFiles = len(files)
54 nFiles = len(files)
55 if nFiles == 0:
55 if nFiles == 0:
56 continue
56 continue
57 skip = int(math.ceil(nFiles / n))
57 skip = int(math.ceil(nFiles / n))
58 while nFiles > cursor * skip:
58 while nFiles > cursor * skip:
59 rconf.update(startDate=dt_str, endDate=dt_str, cursor=cursor,
59 rconf.update(startDate=dt_str, endDate=dt_str, cursor=cursor,
60 skip=skip)
60 skip=skip)
61 p = project.clone()
61 p = project.clone()
62 p.start()
62 p.start()
63 processes.append(p)
63 processes.append(p)
64 cursor += 1
64 cursor += 1
65
65
66 def beforeExit(exctype, value, trace):
66 def beforeExit(exctype, value, trace):
67 for process in processes:
67 for process in processes:
68 process.terminate()
68 process.terminate()
69 process.join()
69 process.join()
70 print traceback.print_tb(trace)
70 print traceback.print_tb(trace)
71
71
72 sys.excepthook = beforeExit
72 sys.excepthook = beforeExit
73
73
74 for process in processes:
74 for process in processes:
75 process.join()
75 process.join()
76 process.terminate()
76 process.terminate()
77
77
78 time.sleep(3)
78 time.sleep(3)
79
79
80
80
81 class ParameterConf():
81 class ParameterConf():
82
82
83 id = None
83 id = None
84 name = None
84 name = None
85 value = None
85 value = None
86 format = None
86 format = None
87
87
88 __formated_value = None
88 __formated_value = None
89
89
90 ELEMENTNAME = 'Parameter'
90 ELEMENTNAME = 'Parameter'
91
91
92 def __init__(self):
92 def __init__(self):
93
93
94 self.format = 'str'
94 self.format = 'str'
95
95
96 def getElementName(self):
96 def getElementName(self):
97
97
98 return self.ELEMENTNAME
98 return self.ELEMENTNAME
99
99
100 def getValue(self):
100 def getValue(self):
101
101
102 value = self.value
102 value = self.value
103 format = self.format
103 format = self.format
104
104
105 if self.__formated_value != None:
105 if self.__formated_value != None:
106
106
107 return self.__formated_value
107 return self.__formated_value
108
108
109 if format == 'obj':
109 if format == 'obj':
110 return value
110 return value
111
111
112 if format == 'str':
112 if format == 'str':
113 self.__formated_value = str(value)
113 self.__formated_value = str(value)
114 return self.__formated_value
114 return self.__formated_value
115
115
116 if value == '':
116 if value == '':
117 raise ValueError, '%s: This parameter value is empty' % self.name
117 raise ValueError, '%s: This parameter value is empty' % self.name
118
118
119 if format == 'list':
119 if format == 'list':
120 strList = value.split(',')
120 strList = value.split(',')
121
121
122 self.__formated_value = strList
122 self.__formated_value = strList
123
123
124 return self.__formated_value
124 return self.__formated_value
125
125
126 if format == 'intlist':
126 if format == 'intlist':
127 '''
127 '''
128 Example:
128 Example:
129 value = (0,1,2)
129 value = (0,1,2)
130 '''
130 '''
131
131
132 new_value = ast.literal_eval(value)
132 new_value = ast.literal_eval(value)
133
133
134 if type(new_value) not in (tuple, list):
134 if type(new_value) not in (tuple, list):
135 new_value = [int(new_value)]
135 new_value = [int(new_value)]
136
136
137 self.__formated_value = new_value
137 self.__formated_value = new_value
138
138
139 return self.__formated_value
139 return self.__formated_value
140
140
141 if format == 'floatlist':
141 if format == 'floatlist':
142 '''
142 '''
143 Example:
143 Example:
144 value = (0.5, 1.4, 2.7)
144 value = (0.5, 1.4, 2.7)
145 '''
145 '''
146
146
147 new_value = ast.literal_eval(value)
147 new_value = ast.literal_eval(value)
148
148
149 if type(new_value) not in (tuple, list):
149 if type(new_value) not in (tuple, list):
150 new_value = [float(new_value)]
150 new_value = [float(new_value)]
151
151
152 self.__formated_value = new_value
152 self.__formated_value = new_value
153
153
154 return self.__formated_value
154 return self.__formated_value
155
155
156 if format == 'date':
156 if format == 'date':
157 strList = value.split('/')
157 strList = value.split('/')
158 intList = [int(x) for x in strList]
158 intList = [int(x) for x in strList]
159 date = datetime.date(intList[0], intList[1], intList[2])
159 date = datetime.date(intList[0], intList[1], intList[2])
160
160
161 self.__formated_value = date
161 self.__formated_value = date
162
162
163 return self.__formated_value
163 return self.__formated_value
164
164
165 if format == 'time':
165 if format == 'time':
166 strList = value.split(':')
166 strList = value.split(':')
167 intList = [int(x) for x in strList]
167 intList = [int(x) for x in strList]
168 time = datetime.time(intList[0], intList[1], intList[2])
168 time = datetime.time(intList[0], intList[1], intList[2])
169
169
170 self.__formated_value = time
170 self.__formated_value = time
171
171
172 return self.__formated_value
172 return self.__formated_value
173
173
174 if format == 'pairslist':
174 if format == 'pairslist':
175 '''
175 '''
176 Example:
176 Example:
177 value = (0,1),(1,2)
177 value = (0,1),(1,2)
178 '''
178 '''
179
179
180 new_value = ast.literal_eval(value)
180 new_value = ast.literal_eval(value)
181
181
182 if type(new_value) not in (tuple, list):
182 if type(new_value) not in (tuple, list):
183 raise ValueError, '%s has to be a tuple or list of pairs' % value
183 raise ValueError, '%s has to be a tuple or list of pairs' % value
184
184
185 if type(new_value[0]) not in (tuple, list):
185 if type(new_value[0]) not in (tuple, list):
186 if len(new_value) != 2:
186 if len(new_value) != 2:
187 raise ValueError, '%s has to be a tuple or list of pairs' % value
187 raise ValueError, '%s has to be a tuple or list of pairs' % value
188 new_value = [new_value]
188 new_value = [new_value]
189
189
190 for thisPair in new_value:
190 for thisPair in new_value:
191 if len(thisPair) != 2:
191 if len(thisPair) != 2:
192 raise ValueError, '%s has to be a tuple or list of pairs' % value
192 raise ValueError, '%s has to be a tuple or list of pairs' % value
193
193
194 self.__formated_value = new_value
194 self.__formated_value = new_value
195
195
196 return self.__formated_value
196 return self.__formated_value
197
197
198 if format == 'multilist':
198 if format == 'multilist':
199 '''
199 '''
200 Example:
200 Example:
201 value = (0,1,2),(3,4,5)
201 value = (0,1,2),(3,4,5)
202 '''
202 '''
203 multiList = ast.literal_eval(value)
203 multiList = ast.literal_eval(value)
204
204
205 if type(multiList[0]) == int:
205 if type(multiList[0]) == int:
206 multiList = ast.literal_eval('(' + value + ')')
206 multiList = ast.literal_eval('(' + value + ')')
207
207
208 self.__formated_value = multiList
208 self.__formated_value = multiList
209
209
210 return self.__formated_value
210 return self.__formated_value
211
211
212 if format == 'bool':
212 if format == 'bool':
213 value = int(value)
213 value = int(value)
214
214
215 if format == 'int':
215 if format == 'int':
216 value = float(value)
216 value = float(value)
217
217
218 format_func = eval(format)
218 format_func = eval(format)
219
219
220 self.__formated_value = format_func(value)
220 self.__formated_value = format_func(value)
221
221
222 return self.__formated_value
222 return self.__formated_value
223
223
224 def updateId(self, new_id):
224 def updateId(self, new_id):
225
225
226 self.id = str(new_id)
226 self.id = str(new_id)
227
227
228 def setup(self, id, name, value, format='str'):
228 def setup(self, id, name, value, format='str'):
229 self.id = str(id)
229 self.id = str(id)
230 self.name = name
230 self.name = name
231 if format == 'obj':
231 if format == 'obj':
232 self.value = value
232 self.value = value
233 else:
233 else:
234 self.value = str(value)
234 self.value = str(value)
235 self.format = str.lower(format)
235 self.format = str.lower(format)
236
236
237 self.getValue()
237 self.getValue()
238
238
239 return 1
239 return 1
240
240
241 def update(self, name, value, format='str'):
241 def update(self, name, value, format='str'):
242
242
243 self.name = name
243 self.name = name
244 self.value = str(value)
244 self.value = str(value)
245 self.format = format
245 self.format = format
246
246
247 def makeXml(self, opElement):
247 def makeXml(self, opElement):
248 if self.name not in ('queue',):
248 if self.name not in ('queue',):
249 parmElement = SubElement(opElement, self.ELEMENTNAME)
249 parmElement = SubElement(opElement, self.ELEMENTNAME)
250 parmElement.set('id', str(self.id))
250 parmElement.set('id', str(self.id))
251 parmElement.set('name', self.name)
251 parmElement.set('name', self.name)
252 parmElement.set('value', self.value)
252 parmElement.set('value', self.value)
253 parmElement.set('format', self.format)
253 parmElement.set('format', self.format)
254
254
255 def readXml(self, parmElement):
255 def readXml(self, parmElement):
256
256
257 self.id = parmElement.get('id')
257 self.id = parmElement.get('id')
258 self.name = parmElement.get('name')
258 self.name = parmElement.get('name')
259 self.value = parmElement.get('value')
259 self.value = parmElement.get('value')
260 self.format = str.lower(parmElement.get('format'))
260 self.format = str.lower(parmElement.get('format'))
261
261
262 # Compatible with old signal chain version
262 # Compatible with old signal chain version
263 if self.format == 'int' and self.name == 'idfigure':
263 if self.format == 'int' and self.name == 'idfigure':
264 self.name = 'id'
264 self.name = 'id'
265
265
266 def printattr(self):
266 def printattr(self):
267
267
268 print 'Parameter[%s]: name = %s, value = %s, format = %s' % (self.id, self.name, self.value, self.format)
268 print 'Parameter[%s]: name = %s, value = %s, format = %s' % (self.id, self.name, self.value, self.format)
269
269
270
270
271 class OperationConf():
271 class OperationConf():
272
272
273 id = None
273 id = None
274 name = None
274 name = None
275 priority = None
275 priority = None
276 type = None
276 type = None
277
277
278 parmConfObjList = []
278 parmConfObjList = []
279
279
280 ELEMENTNAME = 'Operation'
280 ELEMENTNAME = 'Operation'
281
281
282 def __init__(self):
282 def __init__(self):
283
283
284 self.id = '0'
284 self.id = '0'
285 self.name = None
285 self.name = None
286 self.priority = None
286 self.priority = None
287 self.type = 'self'
287 self.type = 'self'
288
288
289 def __getNewId(self):
289 def __getNewId(self):
290
290
291 return int(self.id) * 10 + len(self.parmConfObjList) + 1
291 return int(self.id) * 10 + len(self.parmConfObjList) + 1
292
292
293 def updateId(self, new_id):
293 def updateId(self, new_id):
294
294
295 self.id = str(new_id)
295 self.id = str(new_id)
296
296
297 n = 1
297 n = 1
298 for parmObj in self.parmConfObjList:
298 for parmObj in self.parmConfObjList:
299
299
300 idParm = str(int(new_id) * 10 + n)
300 idParm = str(int(new_id) * 10 + n)
301 parmObj.updateId(idParm)
301 parmObj.updateId(idParm)
302
302
303 n += 1
303 n += 1
304
304
305 def getElementName(self):
305 def getElementName(self):
306
306
307 return self.ELEMENTNAME
307 return self.ELEMENTNAME
308
308
309 def getParameterObjList(self):
309 def getParameterObjList(self):
310
310
311 return self.parmConfObjList
311 return self.parmConfObjList
312
312
313 def getParameterObj(self, parameterName):
313 def getParameterObj(self, parameterName):
314
314
315 for parmConfObj in self.parmConfObjList:
315 for parmConfObj in self.parmConfObjList:
316
316
317 if parmConfObj.name != parameterName:
317 if parmConfObj.name != parameterName:
318 continue
318 continue
319
319
320 return parmConfObj
320 return parmConfObj
321
321
322 return None
322 return None
323
323
324 def getParameterObjfromValue(self, parameterValue):
324 def getParameterObjfromValue(self, parameterValue):
325
325
326 for parmConfObj in self.parmConfObjList:
326 for parmConfObj in self.parmConfObjList:
327
327
328 if parmConfObj.getValue() != parameterValue:
328 if parmConfObj.getValue() != parameterValue:
329 continue
329 continue
330
330
331 return parmConfObj.getValue()
331 return parmConfObj.getValue()
332
332
333 return None
333 return None
334
334
335 def getParameterValue(self, parameterName):
335 def getParameterValue(self, parameterName):
336
336
337 parameterObj = self.getParameterObj(parameterName)
337 parameterObj = self.getParameterObj(parameterName)
338
338
339 # if not parameterObj:
339 # if not parameterObj:
340 # return None
340 # return None
341
341
342 value = parameterObj.getValue()
342 value = parameterObj.getValue()
343
343
344 return value
344 return value
345
345
346 def getKwargs(self):
346 def getKwargs(self):
347
347
348 kwargs = {}
348 kwargs = {}
349
349
350 for parmConfObj in self.parmConfObjList:
350 for parmConfObj in self.parmConfObjList:
351 if self.name == 'run' and parmConfObj.name == 'datatype':
351 if self.name == 'run' and parmConfObj.name == 'datatype':
352 continue
352 continue
353
353
354 kwargs[parmConfObj.name] = parmConfObj.getValue()
354 kwargs[parmConfObj.name] = parmConfObj.getValue()
355
355
356 return kwargs
356 return kwargs
357
357
358 def setup(self, id, name, priority, type):
358 def setup(self, id, name, priority, type):
359
359
360 self.id = str(id)
360 self.id = str(id)
361 self.name = name
361 self.name = name
362 self.type = type
362 self.type = type
363 self.priority = priority
363 self.priority = priority
364
364
365 self.parmConfObjList = []
365 self.parmConfObjList = []
366
366
367 def removeParameters(self):
367 def removeParameters(self):
368
368
369 for obj in self.parmConfObjList:
369 for obj in self.parmConfObjList:
370 del obj
370 del obj
371
371
372 self.parmConfObjList = []
372 self.parmConfObjList = []
373
373
374 def addParameter(self, name, value, format='str'):
374 def addParameter(self, name, value, format='str'):
375
375
376 if value is None:
376 if value is None:
377 return None
377 return None
378 id = self.__getNewId()
378 id = self.__getNewId()
379
379
380 parmConfObj = ParameterConf()
380 parmConfObj = ParameterConf()
381 if not parmConfObj.setup(id, name, value, format):
381 if not parmConfObj.setup(id, name, value, format):
382 return None
382 return None
383
383
384 self.parmConfObjList.append(parmConfObj)
384 self.parmConfObjList.append(parmConfObj)
385
385
386 return parmConfObj
386 return parmConfObj
387
387
388 def changeParameter(self, name, value, format='str'):
388 def changeParameter(self, name, value, format='str'):
389
389
390 parmConfObj = self.getParameterObj(name)
390 parmConfObj = self.getParameterObj(name)
391 parmConfObj.update(name, value, format)
391 parmConfObj.update(name, value, format)
392
392
393 return parmConfObj
393 return parmConfObj
394
394
395 def makeXml(self, procUnitElement):
395 def makeXml(self, procUnitElement):
396
396
397 opElement = SubElement(procUnitElement, self.ELEMENTNAME)
397 opElement = SubElement(procUnitElement, self.ELEMENTNAME)
398 opElement.set('id', str(self.id))
398 opElement.set('id', str(self.id))
399 opElement.set('name', self.name)
399 opElement.set('name', self.name)
400 opElement.set('type', self.type)
400 opElement.set('type', self.type)
401 opElement.set('priority', str(self.priority))
401 opElement.set('priority', str(self.priority))
402
402
403 for parmConfObj in self.parmConfObjList:
403 for parmConfObj in self.parmConfObjList:
404 parmConfObj.makeXml(opElement)
404 parmConfObj.makeXml(opElement)
405
405
406 def readXml(self, opElement):
406 def readXml(self, opElement):
407
407
408 self.id = opElement.get('id')
408 self.id = opElement.get('id')
409 self.name = opElement.get('name')
409 self.name = opElement.get('name')
410 self.type = opElement.get('type')
410 self.type = opElement.get('type')
411 self.priority = opElement.get('priority')
411 self.priority = opElement.get('priority')
412
412
413 # Compatible with old signal chain version
413 # Compatible with old signal chain version
414 # Use of 'run' method instead 'init'
414 # Use of 'run' method instead 'init'
415 if self.type == 'self' and self.name == 'init':
415 if self.type == 'self' and self.name == 'init':
416 self.name = 'run'
416 self.name = 'run'
417
417
418 self.parmConfObjList = []
418 self.parmConfObjList = []
419
419
420 parmElementList = opElement.iter(ParameterConf().getElementName())
420 parmElementList = opElement.iter(ParameterConf().getElementName())
421
421
422 for parmElement in parmElementList:
422 for parmElement in parmElementList:
423 parmConfObj = ParameterConf()
423 parmConfObj = ParameterConf()
424 parmConfObj.readXml(parmElement)
424 parmConfObj.readXml(parmElement)
425
425
426 # Compatible with old signal chain version
426 # Compatible with old signal chain version
427 # If an 'plot' OPERATION is found, changes name operation by the value of its type PARAMETER
427 # If an 'plot' OPERATION is found, changes name operation by the value of its type PARAMETER
428 if self.type != 'self' and self.name == 'Plot':
428 if self.type != 'self' and self.name == 'Plot':
429 if parmConfObj.format == 'str' and parmConfObj.name == 'type':
429 if parmConfObj.format == 'str' and parmConfObj.name == 'type':
430 self.name = parmConfObj.value
430 self.name = parmConfObj.value
431 continue
431 continue
432
432
433 self.parmConfObjList.append(parmConfObj)
433 self.parmConfObjList.append(parmConfObj)
434
434
435 def printattr(self):
435 def printattr(self):
436
436
437 print '%s[%s]: name = %s, type = %s, priority = %s' % (self.ELEMENTNAME,
437 print '%s[%s]: name = %s, type = %s, priority = %s' % (self.ELEMENTNAME,
438 self.id,
438 self.id,
439 self.name,
439 self.name,
440 self.type,
440 self.type,
441 self.priority)
441 self.priority)
442
442
443 for parmConfObj in self.parmConfObjList:
443 for parmConfObj in self.parmConfObjList:
444 parmConfObj.printattr()
444 parmConfObj.printattr()
445
445
446 def createObject(self, plotter_queue=None):
446 def createObject(self, plotter_queue=None):
447
447
448 if self.type == 'self':
448 if self.type == 'self':
449 raise ValueError, 'This operation type cannot be created'
449 raise ValueError, 'This operation type cannot be created'
450
450
451 if self.type == 'plotter':
451 if self.type == 'plotter':
452 if not plotter_queue:
452 if not plotter_queue:
453 raise ValueError, 'plotter_queue is not defined. Use:\nmyProject = Project()\nmyProject.setPlotterQueue(plotter_queue)'
453 raise ValueError, 'plotter_queue is not defined. Use:\nmyProject = Project()\nmyProject.setPlotterQueue(plotter_queue)'
454
454
455 opObj = Plotter(self.name, plotter_queue)
455 opObj = Plotter(self.name, plotter_queue)
456
456
457 if self.type == 'external' or self.type == 'other':
457 if self.type == 'external' or self.type == 'other':
458
458
459 className = eval(self.name)
459 className = eval(self.name)
460 kwargs = self.getKwargs()
460 kwargs = self.getKwargs()
461
461
462 opObj = className(**kwargs)
462 opObj = className(**kwargs)
463
463
464 return opObj
464 return opObj
465
465
466
466
467 class ProcUnitConf():
467 class ProcUnitConf():
468
468
469 id = None
469 id = None
470 name = None
470 name = None
471 datatype = None
471 datatype = None
472 inputId = None
472 inputId = None
473 parentId = None
473 parentId = None
474
474
475 opConfObjList = []
475 opConfObjList = []
476
476
477 procUnitObj = None
477 procUnitObj = None
478 opObjList = []
478 opObjList = []
479
479
480 ELEMENTNAME = 'ProcUnit'
480 ELEMENTNAME = 'ProcUnit'
481
481
482 def __init__(self):
482 def __init__(self):
483
483
484 self.id = None
484 self.id = None
485 self.datatype = None
485 self.datatype = None
486 self.name = None
486 self.name = None
487 self.inputId = None
487 self.inputId = None
488
488
489 self.opConfObjList = []
489 self.opConfObjList = []
490
490
491 self.procUnitObj = None
491 self.procUnitObj = None
492 self.opObjDict = {}
492 self.opObjDict = {}
493
493
494 def __getPriority(self):
494 def __getPriority(self):
495
495
496 return len(self.opConfObjList) + 1
496 return len(self.opConfObjList) + 1
497
497
498 def __getNewId(self):
498 def __getNewId(self):
499
499
500 return int(self.id) * 10 + len(self.opConfObjList) + 1
500 return int(self.id) * 10 + len(self.opConfObjList) + 1
501
501
502 def getElementName(self):
502 def getElementName(self):
503
503
504 return self.ELEMENTNAME
504 return self.ELEMENTNAME
505
505
506 def getId(self):
506 def getId(self):
507
507
508 return self.id
508 return self.id
509
509
510 def updateId(self, new_id, parentId=parentId):
510 def updateId(self, new_id, parentId=parentId):
511
511
512 new_id = int(parentId) * 10 + (int(self.id) % 10)
512 new_id = int(parentId) * 10 + (int(self.id) % 10)
513 new_inputId = int(parentId) * 10 + (int(self.inputId) % 10)
513 new_inputId = int(parentId) * 10 + (int(self.inputId) % 10)
514
514
515 # If this proc unit has not inputs
515 # If this proc unit has not inputs
516 if self.inputId == '0':
516 if self.inputId == '0':
517 new_inputId = 0
517 new_inputId = 0
518
518
519 n = 1
519 n = 1
520 for opConfObj in self.opConfObjList:
520 for opConfObj in self.opConfObjList:
521
521
522 idOp = str(int(new_id) * 10 + n)
522 idOp = str(int(new_id) * 10 + n)
523 opConfObj.updateId(idOp)
523 opConfObj.updateId(idOp)
524
524
525 n += 1
525 n += 1
526
526
527 self.parentId = str(parentId)
527 self.parentId = str(parentId)
528 self.id = str(new_id)
528 self.id = str(new_id)
529 self.inputId = str(new_inputId)
529 self.inputId = str(new_inputId)
530
530
531 def getInputId(self):
531 def getInputId(self):
532
532
533 return self.inputId
533 return self.inputId
534
534
535 def getOperationObjList(self):
535 def getOperationObjList(self):
536
536
537 return self.opConfObjList
537 return self.opConfObjList
538
538
539 def getOperationObj(self, name=None):
539 def getOperationObj(self, name=None):
540
540
541 for opConfObj in self.opConfObjList:
541 for opConfObj in self.opConfObjList:
542
542
543 if opConfObj.name != name:
543 if opConfObj.name != name:
544 continue
544 continue
545
545
546 return opConfObj
546 return opConfObj
547
547
548 return None
548 return None
549
549
550 def getOpObjfromParamValue(self, value=None):
550 def getOpObjfromParamValue(self, value=None):
551
551
552 for opConfObj in self.opConfObjList:
552 for opConfObj in self.opConfObjList:
553 if opConfObj.getParameterObjfromValue(parameterValue=value) != value:
553 if opConfObj.getParameterObjfromValue(parameterValue=value) != value:
554 continue
554 continue
555 return opConfObj
555 return opConfObj
556 return None
556 return None
557
557
558 def getProcUnitObj(self):
558 def getProcUnitObj(self):
559
559
560 return self.procUnitObj
560 return self.procUnitObj
561
561
562 def setup(self, id, name, datatype, inputId, parentId=None):
562 def setup(self, id, name, datatype, inputId, parentId=None):
563
563
564 # Compatible with old signal chain version
564 # Compatible with old signal chain version
565 if datatype == None and name == None:
565 if datatype == None and name == None:
566 raise ValueError, 'datatype or name should be defined'
566 raise ValueError, 'datatype or name should be defined'
567
567
568 if name == None:
568 if name == None:
569 if 'Proc' in datatype:
569 if 'Proc' in datatype:
570 name = datatype
570 name = datatype
571 else:
571 else:
572 name = '%sProc' % (datatype)
572 name = '%sProc' % (datatype)
573
573
574 if datatype == None:
574 if datatype == None:
575 datatype = name.replace('Proc', '')
575 datatype = name.replace('Proc', '')
576
576
577 self.id = str(id)
577 self.id = str(id)
578 self.name = name
578 self.name = name
579 self.datatype = datatype
579 self.datatype = datatype
580 self.inputId = inputId
580 self.inputId = inputId
581 self.parentId = parentId
581 self.parentId = parentId
582
582
583 self.opConfObjList = []
583 self.opConfObjList = []
584
584
585 self.addOperation(name='run', optype='self')
585 self.addOperation(name='run', optype='self')
586
586
587 def removeOperations(self):
587 def removeOperations(self):
588
588
589 for obj in self.opConfObjList:
589 for obj in self.opConfObjList:
590 del obj
590 del obj
591
591
592 self.opConfObjList = []
592 self.opConfObjList = []
593 self.addOperation(name='run')
593 self.addOperation(name='run')
594
594
595 def addParameter(self, **kwargs):
595 def addParameter(self, **kwargs):
596 '''
596 '''
597 Add parameters to 'run' operation
597 Add parameters to 'run' operation
598 '''
598 '''
599 opObj = self.opConfObjList[0]
599 opObj = self.opConfObjList[0]
600
600
601 opObj.addParameter(**kwargs)
601 opObj.addParameter(**kwargs)
602
602
603 return opObj
603 return opObj
604
604
605 def addOperation(self, name, optype='self'):
605 def addOperation(self, name, optype='self'):
606
606
607 id = self.__getNewId()
607 id = self.__getNewId()
608 priority = self.__getPriority()
608 priority = self.__getPriority()
609
609
610 opConfObj = OperationConf()
610 opConfObj = OperationConf()
611 opConfObj.setup(id, name=name, priority=priority, type=optype)
611 opConfObj.setup(id, name=name, priority=priority, type=optype)
612
612
613 self.opConfObjList.append(opConfObj)
613 self.opConfObjList.append(opConfObj)
614
614
615 return opConfObj
615 return opConfObj
616
616
617 def makeXml(self, projectElement):
617 def makeXml(self, projectElement):
618
618
619 procUnitElement = SubElement(projectElement, self.ELEMENTNAME)
619 procUnitElement = SubElement(projectElement, self.ELEMENTNAME)
620 procUnitElement.set('id', str(self.id))
620 procUnitElement.set('id', str(self.id))
621 procUnitElement.set('name', self.name)
621 procUnitElement.set('name', self.name)
622 procUnitElement.set('datatype', self.datatype)
622 procUnitElement.set('datatype', self.datatype)
623 procUnitElement.set('inputId', str(self.inputId))
623 procUnitElement.set('inputId', str(self.inputId))
624
624
625 for opConfObj in self.opConfObjList:
625 for opConfObj in self.opConfObjList:
626 opConfObj.makeXml(procUnitElement)
626 opConfObj.makeXml(procUnitElement)
627
627
628 def readXml(self, upElement):
628 def readXml(self, upElement):
629
629
630 self.id = upElement.get('id')
630 self.id = upElement.get('id')
631 self.name = upElement.get('name')
631 self.name = upElement.get('name')
632 self.datatype = upElement.get('datatype')
632 self.datatype = upElement.get('datatype')
633 self.inputId = upElement.get('inputId')
633 self.inputId = upElement.get('inputId')
634
634
635 if self.ELEMENTNAME == 'ReadUnit':
635 if self.ELEMENTNAME == 'ReadUnit':
636 self.datatype = self.datatype.replace('Reader', '')
636 self.datatype = self.datatype.replace('Reader', '')
637
637
638 if self.ELEMENTNAME == 'ProcUnit':
638 if self.ELEMENTNAME == 'ProcUnit':
639 self.datatype = self.datatype.replace('Proc', '')
639 self.datatype = self.datatype.replace('Proc', '')
640
640
641 if self.inputId == 'None':
641 if self.inputId == 'None':
642 self.inputId = '0'
642 self.inputId = '0'
643
643
644 self.opConfObjList = []
644 self.opConfObjList = []
645
645
646 opElementList = upElement.iter(OperationConf().getElementName())
646 opElementList = upElement.iter(OperationConf().getElementName())
647
647
648 for opElement in opElementList:
648 for opElement in opElementList:
649 opConfObj = OperationConf()
649 opConfObj = OperationConf()
650 opConfObj.readXml(opElement)
650 opConfObj.readXml(opElement)
651 self.opConfObjList.append(opConfObj)
651 self.opConfObjList.append(opConfObj)
652
652
653 def printattr(self):
653 def printattr(self):
654
654
655 print '%s[%s]: name = %s, datatype = %s, inputId = %s' % (self.ELEMENTNAME,
655 print '%s[%s]: name = %s, datatype = %s, inputId = %s' % (self.ELEMENTNAME,
656 self.id,
656 self.id,
657 self.name,
657 self.name,
658 self.datatype,
658 self.datatype,
659 self.inputId)
659 self.inputId)
660
660
661 for opConfObj in self.opConfObjList:
661 for opConfObj in self.opConfObjList:
662 opConfObj.printattr()
662 opConfObj.printattr()
663
663
664 def getKwargs(self):
664 def getKwargs(self):
665
665
666 opObj = self.opConfObjList[0]
666 opObj = self.opConfObjList[0]
667 kwargs = opObj.getKwargs()
667 kwargs = opObj.getKwargs()
668
668
669 return kwargs
669 return kwargs
670
670
671 def createObjects(self, plotter_queue=None):
671 def createObjects(self, plotter_queue=None):
672
672
673 className = eval(self.name)
673 className = eval(self.name)
674 kwargs = self.getKwargs()
674 kwargs = self.getKwargs()
675 procUnitObj = className(**kwargs)
675 procUnitObj = className(**kwargs)
676
676
677 for opConfObj in self.opConfObjList:
677 for opConfObj in self.opConfObjList:
678
678
679 if opConfObj.type == 'self' and self.name == 'run':
679 if opConfObj.type == 'self' and self.name == 'run':
680 continue
680 continue
681 elif opConfObj.type == 'self':
681 elif opConfObj.type == 'self':
682 procUnitObj.addOperationKwargs(
682 procUnitObj.addOperationKwargs(
683 opConfObj.id, **opConfObj.getKwargs())
683 opConfObj.id, **opConfObj.getKwargs())
684 continue
684 continue
685
685
686 opObj = opConfObj.createObject(plotter_queue)
686 opObj = opConfObj.createObject(plotter_queue)
687
687
688 self.opObjDict[opConfObj.id] = opObj
688 self.opObjDict[opConfObj.id] = opObj
689
689
690 procUnitObj.addOperation(opObj, opConfObj.id)
690 procUnitObj.addOperation(opObj, opConfObj.id)
691
691
692 self.procUnitObj = procUnitObj
692 self.procUnitObj = procUnitObj
693
693
694 return procUnitObj
694 return procUnitObj
695
695
696 def run(self):
696 def run(self):
697
697
698 is_ok = False
698 is_ok = False
699
699
700 for opConfObj in self.opConfObjList:
700 for opConfObj in self.opConfObjList:
701
701
702 kwargs = {}
702 kwargs = {}
703 for parmConfObj in opConfObj.getParameterObjList():
703 for parmConfObj in opConfObj.getParameterObjList():
704 if opConfObj.name == 'run' and parmConfObj.name == 'datatype':
704 if opConfObj.name == 'run' and parmConfObj.name == 'datatype':
705 continue
705 continue
706
706
707 kwargs[parmConfObj.name] = parmConfObj.getValue()
707 kwargs[parmConfObj.name] = parmConfObj.getValue()
708
708
709 sts = self.procUnitObj.call(opType=opConfObj.type,
709 sts = self.procUnitObj.call(opType=opConfObj.type,
710 opName=opConfObj.name,
710 opName=opConfObj.name,
711 opId=opConfObj.id)
711 opId=opConfObj.id)
712
712
713 is_ok = is_ok or sts
713 is_ok = is_ok or sts
714
714
715 return is_ok
715 return is_ok
716
716
717 def close(self):
717 def close(self):
718
718
719 for opConfObj in self.opConfObjList:
719 for opConfObj in self.opConfObjList:
720 if opConfObj.type == 'self':
720 if opConfObj.type == 'self':
721 continue
721 continue
722
722
723 opObj = self.procUnitObj.getOperationObj(opConfObj.id)
723 opObj = self.procUnitObj.getOperationObj(opConfObj.id)
724 opObj.close()
724 opObj.close()
725
725
726 self.procUnitObj.close()
726 self.procUnitObj.close()
727
727
728 return
728 return
729
729
730
730
731 class ReadUnitConf(ProcUnitConf):
731 class ReadUnitConf(ProcUnitConf):
732
732
733 path = None
733 path = None
734 startDate = None
734 startDate = None
735 endDate = None
735 endDate = None
736 startTime = None
736 startTime = None
737 endTime = None
737 endTime = None
738
738
739 ELEMENTNAME = 'ReadUnit'
739 ELEMENTNAME = 'ReadUnit'
740
740
741 def __init__(self):
741 def __init__(self):
742
742
743 self.id = None
743 self.id = None
744 self.datatype = None
744 self.datatype = None
745 self.name = None
745 self.name = None
746 self.inputId = None
746 self.inputId = None
747
747
748 self.parentId = None
748 self.parentId = None
749
749
750 self.opConfObjList = []
750 self.opConfObjList = []
751 self.opObjList = []
751 self.opObjList = []
752
752
753 def getElementName(self):
753 def getElementName(self):
754
754
755 return self.ELEMENTNAME
755 return self.ELEMENTNAME
756
756
757 def setup(self, id, name, datatype, path='', startDate='', endDate='',
757 def setup(self, id, name, datatype, path='', startDate='', endDate='',
758 startTime='', endTime='', parentId=None, server=None, **kwargs):
758 startTime='', endTime='', parentId=None, server=None, **kwargs):
759
759
760 # Compatible with old signal chain version
760 # Compatible with old signal chain version
761 if datatype == None and name == None:
761 if datatype == None and name == None:
762 raise ValueError, 'datatype or name should be defined'
762 raise ValueError, 'datatype or name should be defined'
763 if name == None:
763 if name == None:
764 if 'Reader' in datatype:
764 if 'Reader' in datatype:
765 name = datatype
765 name = datatype
766 datatype = name.replace('Reader','')
766 datatype = name.replace('Reader','')
767 else:
767 else:
768 name = '{}Reader'.format(datatype)
768 name = '{}Reader'.format(datatype)
769 if datatype == None:
769 if datatype == None:
770 if 'Reader' in name:
770 if 'Reader' in name:
771 datatype = name.replace('Reader','')
771 datatype = name.replace('Reader','')
772 else:
772 else:
773 datatype = name
773 datatype = name
774 name = '{}Reader'.format(name)
774 name = '{}Reader'.format(name)
775
775
776 self.id = id
776 self.id = id
777 self.name = name
777 self.name = name
778 self.datatype = datatype
778 self.datatype = datatype
779 if path != '':
779 if path != '':
780 self.path = os.path.abspath(path)
780 self.path = os.path.abspath(path)
781 self.startDate = startDate
781 self.startDate = startDate
782 self.endDate = endDate
782 self.endDate = endDate
783 self.startTime = startTime
783 self.startTime = startTime
784 self.endTime = endTime
784 self.endTime = endTime
785 self.inputId = '0'
785 self.inputId = '0'
786 self.parentId = parentId
786 self.parentId = parentId
787 self.server = server
787 self.server = server
788 self.addRunOperation(**kwargs)
788 self.addRunOperation(**kwargs)
789
789
790 def update(self, **kwargs):
790 def update(self, **kwargs):
791
791
792 if 'datatype' in kwargs:
792 if 'datatype' in kwargs:
793 datatype = kwargs.pop('datatype')
793 datatype = kwargs.pop('datatype')
794 if 'Reader' in datatype:
794 if 'Reader' in datatype:
795 self.name = datatype
795 self.name = datatype
796 else:
796 else:
797 self.name = '%sReader' % (datatype)
797 self.name = '%sReader' % (datatype)
798 self.datatype = self.name.replace('Reader', '')
798 self.datatype = self.name.replace('Reader', '')
799
799
800 attrs = ('path', 'startDate', 'endDate',
800 attrs = ('path', 'startDate', 'endDate',
801 'startTime', 'endTime', 'parentId')
801 'startTime', 'endTime', 'parentId')
802
802
803 for attr in attrs:
803 for attr in attrs:
804 if attr in kwargs:
804 if attr in kwargs:
805 setattr(self, attr, kwargs.pop(attr))
805 setattr(self, attr, kwargs.pop(attr))
806
806
807 self.inputId = '0'
807 self.inputId = '0'
808 self.updateRunOperation(**kwargs)
808 self.updateRunOperation(**kwargs)
809
809
810 def removeOperations(self):
810 def removeOperations(self):
811
811
812 for obj in self.opConfObjList:
812 for obj in self.opConfObjList:
813 del obj
813 del obj
814
814
815 self.opConfObjList = []
815 self.opConfObjList = []
816
816
817 def addRunOperation(self, **kwargs):
817 def addRunOperation(self, **kwargs):
818
818
819 opObj = self.addOperation(name='run', optype='self')
819 opObj = self.addOperation(name='run', optype='self')
820
820
821 if self.server is None:
821 if self.server is None:
822 opObj.addParameter(
822 opObj.addParameter(
823 name='datatype', value=self.datatype, format='str')
823 name='datatype', value=self.datatype, format='str')
824 opObj.addParameter(name='path', value=self.path, format='str')
824 opObj.addParameter(name='path', value=self.path, format='str')
825 opObj.addParameter(
825 opObj.addParameter(
826 name='startDate', value=self.startDate, format='date')
826 name='startDate', value=self.startDate, format='date')
827 opObj.addParameter(
827 opObj.addParameter(
828 name='endDate', value=self.endDate, format='date')
828 name='endDate', value=self.endDate, format='date')
829 opObj.addParameter(
829 opObj.addParameter(
830 name='startTime', value=self.startTime, format='time')
830 name='startTime', value=self.startTime, format='time')
831 opObj.addParameter(
831 opObj.addParameter(
832 name='endTime', value=self.endTime, format='time')
832 name='endTime', value=self.endTime, format='time')
833
833
834 for key, value in kwargs.items():
834 for key, value in kwargs.items():
835 opObj.addParameter(name=key, value=value,
835 opObj.addParameter(name=key, value=value,
836 format=type(value).__name__)
836 format=type(value).__name__)
837 else:
837 else:
838 opObj.addParameter(name='server', value=self.server, format='str')
838 opObj.addParameter(name='server', value=self.server, format='str')
839
839
840 return opObj
840 return opObj
841
841
842 def updateRunOperation(self, **kwargs):
842 def updateRunOperation(self, **kwargs):
843
843
844 opObj = self.getOperationObj(name='run')
844 opObj = self.getOperationObj(name='run')
845 opObj.removeParameters()
845 opObj.removeParameters()
846
846
847 opObj.addParameter(name='datatype', value=self.datatype, format='str')
847 opObj.addParameter(name='datatype', value=self.datatype, format='str')
848 opObj.addParameter(name='path', value=self.path, format='str')
848 opObj.addParameter(name='path', value=self.path, format='str')
849 opObj.addParameter(
849 opObj.addParameter(
850 name='startDate', value=self.startDate, format='date')
850 name='startDate', value=self.startDate, format='date')
851 opObj.addParameter(name='endDate', value=self.endDate, format='date')
851 opObj.addParameter(name='endDate', value=self.endDate, format='date')
852 opObj.addParameter(
852 opObj.addParameter(
853 name='startTime', value=self.startTime, format='time')
853 name='startTime', value=self.startTime, format='time')
854 opObj.addParameter(name='endTime', value=self.endTime, format='time')
854 opObj.addParameter(name='endTime', value=self.endTime, format='time')
855
855
856 for key, value in kwargs.items():
856 for key, value in kwargs.items():
857 opObj.addParameter(name=key, value=value,
857 opObj.addParameter(name=key, value=value,
858 format=type(value).__name__)
858 format=type(value).__name__)
859
859
860 return opObj
860 return opObj
861
861
862 def readXml(self, upElement):
862 def readXml(self, upElement):
863
863
864 self.id = upElement.get('id')
864 self.id = upElement.get('id')
865 self.name = upElement.get('name')
865 self.name = upElement.get('name')
866 self.datatype = upElement.get('datatype')
866 self.datatype = upElement.get('datatype')
867 self.inputId = upElement.get('inputId')
867 self.inputId = upElement.get('inputId')
868
868
869 if self.ELEMENTNAME == 'ReadUnit':
869 if self.ELEMENTNAME == 'ReadUnit':
870 self.datatype = self.datatype.replace('Reader', '')
870 self.datatype = self.datatype.replace('Reader', '')
871
871
872 if self.inputId == 'None':
872 if self.inputId == 'None':
873 self.inputId = '0'
873 self.inputId = '0'
874
874
875 self.opConfObjList = []
875 self.opConfObjList = []
876
876
877 opElementList = upElement.iter(OperationConf().getElementName())
877 opElementList = upElement.iter(OperationConf().getElementName())
878
878
879 for opElement in opElementList:
879 for opElement in opElementList:
880 opConfObj = OperationConf()
880 opConfObj = OperationConf()
881 opConfObj.readXml(opElement)
881 opConfObj.readXml(opElement)
882 self.opConfObjList.append(opConfObj)
882 self.opConfObjList.append(opConfObj)
883
883
884 if opConfObj.name == 'run':
884 if opConfObj.name == 'run':
885 self.path = opConfObj.getParameterValue('path')
885 self.path = opConfObj.getParameterValue('path')
886 self.startDate = opConfObj.getParameterValue('startDate')
886 self.startDate = opConfObj.getParameterValue('startDate')
887 self.endDate = opConfObj.getParameterValue('endDate')
887 self.endDate = opConfObj.getParameterValue('endDate')
888 self.startTime = opConfObj.getParameterValue('startTime')
888 self.startTime = opConfObj.getParameterValue('startTime')
889 self.endTime = opConfObj.getParameterValue('endTime')
889 self.endTime = opConfObj.getParameterValue('endTime')
890
890
891
891
892 class Project(Process):
892 class Project(Process):
893
893
894 id = None
894 id = None
895 # name = None
895 # name = None
896 description = None
896 description = None
897 filename = None
897 filename = None
898
898
899 procUnitConfObjDict = None
899 procUnitConfObjDict = None
900
900
901 ELEMENTNAME = 'Project'
901 ELEMENTNAME = 'Project'
902
902
903 plotterQueue = None
903 plotterQueue = None
904
904
905 def __init__(self, plotter_queue=None):
905 def __init__(self, plotter_queue=None):
906
906
907 Process.__init__(self)
907 Process.__init__(self)
908 self.id = None
908 self.id = None
909 self.description = None
909 self.description = None
910 self.email = None
910 self.email = None
911 self.alarm = [0]
911 self.alarm = None
912 self.plotterQueue = plotter_queue
912 self.plotterQueue = plotter_queue
913 self.procUnitConfObjDict = {}
913 self.procUnitConfObjDict = {}
914
914
915 def __getNewId(self):
915 def __getNewId(self):
916
916
917 idList = self.procUnitConfObjDict.keys()
917 idList = self.procUnitConfObjDict.keys()
918
918
919 id = int(self.id) * 10
919 id = int(self.id) * 10
920
920
921 while True:
921 while True:
922 id += 1
922 id += 1
923
923
924 if str(id) in idList:
924 if str(id) in idList:
925 continue
925 continue
926
926
927 break
927 break
928
928
929 return str(id)
929 return str(id)
930
930
931 def getElementName(self):
931 def getElementName(self):
932
932
933 return self.ELEMENTNAME
933 return self.ELEMENTNAME
934
934
935 def getId(self):
935 def getId(self):
936
936
937 return self.id
937 return self.id
938
938
939 def updateId(self, new_id):
939 def updateId(self, new_id):
940
940
941 self.id = str(new_id)
941 self.id = str(new_id)
942
942
943 keyList = self.procUnitConfObjDict.keys()
943 keyList = self.procUnitConfObjDict.keys()
944 keyList.sort()
944 keyList.sort()
945
945
946 n = 1
946 n = 1
947 newProcUnitConfObjDict = {}
947 newProcUnitConfObjDict = {}
948
948
949 for procKey in keyList:
949 for procKey in keyList:
950
950
951 procUnitConfObj = self.procUnitConfObjDict[procKey]
951 procUnitConfObj = self.procUnitConfObjDict[procKey]
952 idProcUnit = str(int(self.id) * 10 + n)
952 idProcUnit = str(int(self.id) * 10 + n)
953 procUnitConfObj.updateId(idProcUnit, parentId=self.id)
953 procUnitConfObj.updateId(idProcUnit, parentId=self.id)
954 newProcUnitConfObjDict[idProcUnit] = procUnitConfObj
954 newProcUnitConfObjDict[idProcUnit] = procUnitConfObj
955 n += 1
955 n += 1
956
956
957 self.procUnitConfObjDict = newProcUnitConfObjDict
957 self.procUnitConfObjDict = newProcUnitConfObjDict
958
958
959 def setup(self, id, name='', description='', email=None, alarm=[0]):
959 def setup(self, id, name='', description='', email=None, alarm=[3]):
960
960
961 print
961 print
962 print '*' * 60
962 print '*' * 60
963 print ' Starting SIGNAL CHAIN PROCESSING v%s ' % schainpy.__version__
963 print ' Starting SIGNAL CHAIN PROCESSING v%s ' % schainpy.__version__
964 print '*' * 60
964 print '*' * 60
965 print
965 print
966 self.id = str(id)
966 self.id = str(id)
967 self.description = description
967 self.description = description
968 self.email = email
968 self.email = email
969 self.alarm = alarm
969 self.alarm = alarm
970
970
971 def update(self, **kwargs):
971 def update(self, **kwargs):
972
972
973 for key, value in kwargs.items():
973 for key, value in kwargs.items():
974 setattr(self, key, value)
974 setattr(self, key, value)
975
975
976 def clone(self):
976 def clone(self):
977
977
978 p = Project()
978 p = Project()
979 p.procUnitConfObjDict = self.procUnitConfObjDict
979 p.procUnitConfObjDict = self.procUnitConfObjDict
980 return p
980 return p
981
981
982 def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
982 def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
983
983
984 if id is None:
984 if id is None:
985 idReadUnit = self.__getNewId()
985 idReadUnit = self.__getNewId()
986 else:
986 else:
987 idReadUnit = str(id)
987 idReadUnit = str(id)
988
988
989 readUnitConfObj = ReadUnitConf()
989 readUnitConfObj = ReadUnitConf()
990 readUnitConfObj.setup(idReadUnit, name, datatype,
990 readUnitConfObj.setup(idReadUnit, name, datatype,
991 parentId=self.id, **kwargs)
991 parentId=self.id, **kwargs)
992
992
993 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
993 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
994
994
995 return readUnitConfObj
995 return readUnitConfObj
996
996
997 def addProcUnit(self, inputId='0', datatype=None, name=None):
997 def addProcUnit(self, inputId='0', datatype=None, name=None):
998
998
999 idProcUnit = self.__getNewId()
999 idProcUnit = self.__getNewId()
1000
1000
1001 procUnitConfObj = ProcUnitConf()
1001 procUnitConfObj = ProcUnitConf()
1002 procUnitConfObj.setup(idProcUnit, name, datatype,
1002 procUnitConfObj.setup(idProcUnit, name, datatype,
1003 inputId, parentId=self.id)
1003 inputId, parentId=self.id)
1004
1004
1005 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
1005 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
1006
1006
1007 return procUnitConfObj
1007 return procUnitConfObj
1008
1008
1009 def removeProcUnit(self, id):
1009 def removeProcUnit(self, id):
1010
1010
1011 if id in self.procUnitConfObjDict.keys():
1011 if id in self.procUnitConfObjDict.keys():
1012 self.procUnitConfObjDict.pop(id)
1012 self.procUnitConfObjDict.pop(id)
1013
1013
1014 def getReadUnitId(self):
1014 def getReadUnitId(self):
1015
1015
1016 readUnitConfObj = self.getReadUnitObj()
1016 readUnitConfObj = self.getReadUnitObj()
1017
1017
1018 return readUnitConfObj.id
1018 return readUnitConfObj.id
1019
1019
1020 def getReadUnitObj(self):
1020 def getReadUnitObj(self):
1021
1021
1022 for obj in self.procUnitConfObjDict.values():
1022 for obj in self.procUnitConfObjDict.values():
1023 if obj.getElementName() == 'ReadUnit':
1023 if obj.getElementName() == 'ReadUnit':
1024 return obj
1024 return obj
1025
1025
1026 return None
1026 return None
1027
1027
1028 def getProcUnitObj(self, id=None, name=None):
1028 def getProcUnitObj(self, id=None, name=None):
1029
1029
1030 if id != None:
1030 if id != None:
1031 return self.procUnitConfObjDict[id]
1031 return self.procUnitConfObjDict[id]
1032
1032
1033 if name != None:
1033 if name != None:
1034 return self.getProcUnitObjByName(name)
1034 return self.getProcUnitObjByName(name)
1035
1035
1036 return None
1036 return None
1037
1037
1038 def getProcUnitObjByName(self, name):
1038 def getProcUnitObjByName(self, name):
1039
1039
1040 for obj in self.procUnitConfObjDict.values():
1040 for obj in self.procUnitConfObjDict.values():
1041 if obj.name == name:
1041 if obj.name == name:
1042 return obj
1042 return obj
1043
1043
1044 return None
1044 return None
1045
1045
1046 def procUnitItems(self):
1046 def procUnitItems(self):
1047
1047
1048 return self.procUnitConfObjDict.items()
1048 return self.procUnitConfObjDict.items()
1049
1049
1050 def makeXml(self):
1050 def makeXml(self):
1051
1051
1052 projectElement = Element('Project')
1052 projectElement = Element('Project')
1053 projectElement.set('id', str(self.id))
1053 projectElement.set('id', str(self.id))
1054 projectElement.set('name', self.name)
1054 projectElement.set('name', self.name)
1055 projectElement.set('description', self.description)
1055 projectElement.set('description', self.description)
1056
1056
1057 for procUnitConfObj in self.procUnitConfObjDict.values():
1057 for procUnitConfObj in self.procUnitConfObjDict.values():
1058 procUnitConfObj.makeXml(projectElement)
1058 procUnitConfObj.makeXml(projectElement)
1059
1059
1060 self.projectElement = projectElement
1060 self.projectElement = projectElement
1061
1061
1062 def writeXml(self, filename=None):
1062 def writeXml(self, filename=None):
1063
1063
1064 if filename == None:
1064 if filename == None:
1065 if self.filename:
1065 if self.filename:
1066 filename = self.filename
1066 filename = self.filename
1067 else:
1067 else:
1068 filename = 'schain.xml'
1068 filename = 'schain.xml'
1069
1069
1070 if not filename:
1070 if not filename:
1071 print 'filename has not been defined. Use setFilename(filename) for do it.'
1071 print 'filename has not been defined. Use setFilename(filename) for do it.'
1072 return 0
1072 return 0
1073
1073
1074 abs_file = os.path.abspath(filename)
1074 abs_file = os.path.abspath(filename)
1075
1075
1076 if not os.access(os.path.dirname(abs_file), os.W_OK):
1076 if not os.access(os.path.dirname(abs_file), os.W_OK):
1077 print 'No write permission on %s' % os.path.dirname(abs_file)
1077 print 'No write permission on %s' % os.path.dirname(abs_file)
1078 return 0
1078 return 0
1079
1079
1080 if os.path.isfile(abs_file) and not(os.access(abs_file, os.W_OK)):
1080 if os.path.isfile(abs_file) and not(os.access(abs_file, os.W_OK)):
1081 print 'File %s already exists and it could not be overwriten' % abs_file
1081 print 'File %s already exists and it could not be overwriten' % abs_file
1082 return 0
1082 return 0
1083
1083
1084 self.makeXml()
1084 self.makeXml()
1085
1085
1086 ElementTree(self.projectElement).write(abs_file, method='xml')
1086 ElementTree(self.projectElement).write(abs_file, method='xml')
1087
1087
1088 self.filename = abs_file
1088 self.filename = abs_file
1089
1089
1090 return 1
1090 return 1
1091
1091
1092 def readXml(self, filename=None):
1092 def readXml(self, filename=None):
1093
1093
1094 if not filename:
1094 if not filename:
1095 print 'filename is not defined'
1095 print 'filename is not defined'
1096 return 0
1096 return 0
1097
1097
1098 abs_file = os.path.abspath(filename)
1098 abs_file = os.path.abspath(filename)
1099
1099
1100 if not os.path.isfile(abs_file):
1100 if not os.path.isfile(abs_file):
1101 print '%s file does not exist' % abs_file
1101 print '%s file does not exist' % abs_file
1102 return 0
1102 return 0
1103
1103
1104 self.projectElement = None
1104 self.projectElement = None
1105 self.procUnitConfObjDict = {}
1105 self.procUnitConfObjDict = {}
1106
1106
1107 try:
1107 try:
1108 self.projectElement = ElementTree().parse(abs_file)
1108 self.projectElement = ElementTree().parse(abs_file)
1109 except:
1109 except:
1110 print 'Error reading %s, verify file format' % filename
1110 print 'Error reading %s, verify file format' % filename
1111 return 0
1111 return 0
1112
1112
1113 self.project = self.projectElement.tag
1113 self.project = self.projectElement.tag
1114
1114
1115 self.id = self.projectElement.get('id')
1115 self.id = self.projectElement.get('id')
1116 self.name = self.projectElement.get('name')
1116 self.name = self.projectElement.get('name')
1117 self.description = self.projectElement.get('description')
1117 self.description = self.projectElement.get('description')
1118
1118
1119 readUnitElementList = self.projectElement.iter(
1119 readUnitElementList = self.projectElement.iter(
1120 ReadUnitConf().getElementName())
1120 ReadUnitConf().getElementName())
1121
1121
1122 for readUnitElement in readUnitElementList:
1122 for readUnitElement in readUnitElementList:
1123 readUnitConfObj = ReadUnitConf()
1123 readUnitConfObj = ReadUnitConf()
1124 readUnitConfObj.readXml(readUnitElement)
1124 readUnitConfObj.readXml(readUnitElement)
1125
1125
1126 if readUnitConfObj.parentId == None:
1126 if readUnitConfObj.parentId == None:
1127 readUnitConfObj.parentId = self.id
1127 readUnitConfObj.parentId = self.id
1128
1128
1129 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
1129 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
1130
1130
1131 procUnitElementList = self.projectElement.iter(
1131 procUnitElementList = self.projectElement.iter(
1132 ProcUnitConf().getElementName())
1132 ProcUnitConf().getElementName())
1133
1133
1134 for procUnitElement in procUnitElementList:
1134 for procUnitElement in procUnitElementList:
1135 procUnitConfObj = ProcUnitConf()
1135 procUnitConfObj = ProcUnitConf()
1136 procUnitConfObj.readXml(procUnitElement)
1136 procUnitConfObj.readXml(procUnitElement)
1137
1137
1138 if procUnitConfObj.parentId == None:
1138 if procUnitConfObj.parentId == None:
1139 procUnitConfObj.parentId = self.id
1139 procUnitConfObj.parentId = self.id
1140
1140
1141 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
1141 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
1142
1142
1143 self.filename = abs_file
1143 self.filename = abs_file
1144
1144
1145 return 1
1145 return 1
1146
1146
1147 def printattr(self):
1147 def printattr(self):
1148
1148
1149 print 'Project[%s]: name = %s, description = %s' % (self.id,
1149 print 'Project[%s]: name = %s, description = %s' % (self.id,
1150 self.name,
1150 self.name,
1151 self.description)
1151 self.description)
1152
1152
1153 for procUnitConfObj in self.procUnitConfObjDict.values():
1153 for procUnitConfObj in self.procUnitConfObjDict.values():
1154 procUnitConfObj.printattr()
1154 procUnitConfObj.printattr()
1155
1155
1156 def createObjects(self):
1156 def createObjects(self):
1157
1157
1158 for procUnitConfObj in self.procUnitConfObjDict.values():
1158 for procUnitConfObj in self.procUnitConfObjDict.values():
1159 procUnitConfObj.createObjects(self.plotterQueue)
1159 procUnitConfObj.createObjects(self.plotterQueue)
1160
1160
1161 def __connect(self, objIN, thisObj):
1161 def __connect(self, objIN, thisObj):
1162
1162
1163 thisObj.setInput(objIN.getOutputObj())
1163 thisObj.setInput(objIN.getOutputObj())
1164
1164
1165 def connectObjects(self):
1165 def connectObjects(self):
1166
1166
1167 for thisPUConfObj in self.procUnitConfObjDict.values():
1167 for thisPUConfObj in self.procUnitConfObjDict.values():
1168
1168
1169 inputId = thisPUConfObj.getInputId()
1169 inputId = thisPUConfObj.getInputId()
1170
1170
1171 if int(inputId) == 0:
1171 if int(inputId) == 0:
1172 continue
1172 continue
1173
1173
1174 # Get input object
1174 # Get input object
1175 puConfINObj = self.procUnitConfObjDict[inputId]
1175 puConfINObj = self.procUnitConfObjDict[inputId]
1176 puObjIN = puConfINObj.getProcUnitObj()
1176 puObjIN = puConfINObj.getProcUnitObj()
1177
1177
1178 # Get current object
1178 # Get current object
1179 thisPUObj = thisPUConfObj.getProcUnitObj()
1179 thisPUObj = thisPUConfObj.getProcUnitObj()
1180
1180
1181 self.__connect(puObjIN, thisPUObj)
1181 self.__connect(puObjIN, thisPUObj)
1182
1182
1183 def __handleError(self, procUnitConfObj, modes=None):
1183 def __handleError(self, procUnitConfObj, modes=None, stdout=True):
1184
1184
1185 import socket
1185 import socket
1186
1186
1187 if modes is None:
1187 if modes is None:
1188 modes = self.alarm
1188 modes = self.alarm
1189
1189
1190 err = traceback.format_exception(sys.exc_info()[0],
1190 err = traceback.format_exception(sys.exc_info()[0],
1191 sys.exc_info()[1],
1191 sys.exc_info()[1],
1192 sys.exc_info()[2])
1192 sys.exc_info()[2])
1193
1193
1194 log.error('{}'.format(err[-1]), procUnitConfObj.name)
1194 log.error('{}'.format(err[-1]), procUnitConfObj.name)
1195
1195
1196 message = ''.join(err)
1196 message = ''.join(err)
1197
1197
1198 sys.stderr.write(message)
1198 if stdout:
1199 sys.stderr.write(message)
1199
1200
1200 subject = 'SChain v%s: Error running %s\n' % (
1201 subject = 'SChain v%s: Error running %s\n' % (
1201 schainpy.__version__, procUnitConfObj.name)
1202 schainpy.__version__, procUnitConfObj.name)
1202
1203
1203 subtitle = '%s: %s\n' % (
1204 subtitle = '%s: %s\n' % (
1204 procUnitConfObj.getElementName(), procUnitConfObj.name)
1205 procUnitConfObj.getElementName(), procUnitConfObj.name)
1205 subtitle += 'Hostname: %s\n' % socket.gethostbyname(
1206 subtitle += 'Hostname: %s\n' % socket.gethostbyname(
1206 socket.gethostname())
1207 socket.gethostname())
1207 subtitle += 'Working directory: %s\n' % os.path.abspath('./')
1208 subtitle += 'Working directory: %s\n' % os.path.abspath('./')
1208 subtitle += 'Configuration file: %s\n' % self.filename
1209 subtitle += 'Configuration file: %s\n' % self.filename
1209 subtitle += 'Time: %s\n' % str(datetime.datetime.now())
1210 subtitle += 'Time: %s\n' % str(datetime.datetime.now())
1210
1211
1211 readUnitConfObj = self.getReadUnitObj()
1212 readUnitConfObj = self.getReadUnitObj()
1212 if readUnitConfObj:
1213 if readUnitConfObj:
1213 subtitle += '\nInput parameters:\n'
1214 subtitle += '\nInput parameters:\n'
1214 subtitle += '[Data path = %s]\n' % readUnitConfObj.path
1215 subtitle += '[Data path = %s]\n' % readUnitConfObj.path
1215 subtitle += '[Data type = %s]\n' % readUnitConfObj.datatype
1216 subtitle += '[Data type = %s]\n' % readUnitConfObj.datatype
1216 subtitle += '[Start date = %s]\n' % readUnitConfObj.startDate
1217 subtitle += '[Start date = %s]\n' % readUnitConfObj.startDate
1217 subtitle += '[End date = %s]\n' % readUnitConfObj.endDate
1218 subtitle += '[End date = %s]\n' % readUnitConfObj.endDate
1218 subtitle += '[Start time = %s]\n' % readUnitConfObj.startTime
1219 subtitle += '[Start time = %s]\n' % readUnitConfObj.startTime
1219 subtitle += '[End time = %s]\n' % readUnitConfObj.endTime
1220 subtitle += '[End time = %s]\n' % readUnitConfObj.endTime
1220
1221
1221 a = Alarm(
1222 a = Alarm(
1222 modes=modes,
1223 modes=modes,
1223 email=self.email,
1224 email=self.email,
1224 message=message,
1225 message=message,
1225 subject=subject,
1226 subject=subject,
1226 subtitle=subtitle,
1227 subtitle=subtitle,
1227 filename=self.filename
1228 filename=self.filename
1228 )
1229 )
1229
1230
1230 a.start()
1231 return a
1231
1232
1232 def isPaused(self):
1233 def isPaused(self):
1233 return 0
1234 return 0
1234
1235
1235 def isStopped(self):
1236 def isStopped(self):
1236 return 0
1237 return 0
1237
1238
1238 def runController(self):
1239 def runController(self):
1239 '''
1240 '''
1240 returns 0 when this process has been stopped, 1 otherwise
1241 returns 0 when this process has been stopped, 1 otherwise
1241 '''
1242 '''
1242
1243
1243 if self.isPaused():
1244 if self.isPaused():
1244 print 'Process suspended'
1245 print 'Process suspended'
1245
1246
1246 while True:
1247 while True:
1247 time.sleep(0.1)
1248 time.sleep(0.1)
1248
1249
1249 if not self.isPaused():
1250 if not self.isPaused():
1250 break
1251 break
1251
1252
1252 if self.isStopped():
1253 if self.isStopped():
1253 break
1254 break
1254
1255
1255 print 'Process reinitialized'
1256 print 'Process reinitialized'
1256
1257
1257 if self.isStopped():
1258 if self.isStopped():
1258 print 'Process stopped'
1259 print 'Process stopped'
1259 return 0
1260 return 0
1260
1261
1261 return 1
1262 return 1
1262
1263
1263 def setFilename(self, filename):
1264 def setFilename(self, filename):
1264
1265
1265 self.filename = filename
1266 self.filename = filename
1266
1267
1267 def setPlotterQueue(self, plotter_queue):
1268 def setPlotterQueue(self, plotter_queue):
1268
1269
1269 raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class'
1270 raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class'
1270
1271
1271 def getPlotterQueue(self):
1272 def getPlotterQueue(self):
1272
1273
1273 raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class'
1274 raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class'
1274
1275
1275 def useExternalPlotter(self):
1276 def useExternalPlotter(self):
1276
1277
1277 raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class'
1278 raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class'
1278
1279
1279 def run(self):
1280 def run(self):
1280
1281
1281 log.success('Starting {}'.format(self.name))
1282 log.success('Starting {}'.format(self.name))
1282 self.start_time = time.time()
1283 self.start_time = time.time()
1283 self.createObjects()
1284 self.createObjects()
1284 self.connectObjects()
1285 self.connectObjects()
1285
1286
1286 keyList = self.procUnitConfObjDict.keys()
1287 keyList = self.procUnitConfObjDict.keys()
1287 keyList.sort()
1288 keyList.sort()
1288
1289
1290 err = None
1291
1289 while(True):
1292 while(True):
1290
1293
1291 is_ok = False
1294 is_ok = False
1292
1295
1293 for procKey in keyList:
1296 for procKey in keyList:
1294
1297
1295 procUnitConfObj = self.procUnitConfObjDict[procKey]
1298 procUnitConfObj = self.procUnitConfObjDict[procKey]
1296
1299
1297 try:
1300 try:
1298 sts = procUnitConfObj.run()
1301 sts = procUnitConfObj.run()
1299 is_ok = is_ok or sts
1302 is_ok = is_ok or sts
1300 except SchainWarning:
1303 except SchainWarning:
1301 self.__handleError(procUnitConfObj, modes=[2, 3])
1304 err = self.__handleError(procUnitConfObj, modes=[2, 3], stdout=False)
1302 except KeyboardInterrupt:
1305 except KeyboardInterrupt:
1303 is_ok = False
1306 is_ok = False
1304 break
1307 break
1305 except ValueError, e:
1308 except ValueError, e:
1306 time.sleep(0.5)
1309 time.sleep(0.5)
1307 self.__handleError(procUnitConfObj)
1310 err = self.__handleError(procUnitConfObj)
1308 is_ok = False
1311 is_ok = False
1309 break
1312 break
1310 except:
1313 except:
1311 time.sleep(0.5)
1314 time.sleep(0.5)
1312 self.__handleError(procUnitConfObj)
1315 err = self.__handleError(procUnitConfObj)
1313 is_ok = False
1316 is_ok = False
1314 break
1317 break
1315
1318
1316 # If every process unit finished so end process
1319 # If every process unit finished so end process
1317 if not(is_ok):
1320 if not(is_ok):
1318 break
1321 break
1319
1322
1320 if not self.runController():
1323 if not self.runController():
1321 break
1324 break
1322
1325
1323 # Closing every process
1326 # Closing every process
1324 for procKey in keyList:
1327 for procKey in keyList:
1325 procUnitConfObj = self.procUnitConfObjDict[procKey]
1328 procUnitConfObj = self.procUnitConfObjDict[procKey]
1326 procUnitConfObj.close()
1329 procUnitConfObj.close()
1327
1330
1331 if err is not None:
1332 err.start()
1333 # err.join()
1334
1328 log.success('{} finished (time: {}s)'.format(
1335 log.success('{} finished (time: {}s)'.format(
1329 self.name,
1336 self.name,
1330 time.time()-self.start_time))
1337 time.time()-self.start_time))
@@ -1,971 +1,978
1
1
2 import os
2 import os
3 import time
3 import time
4 import glob
4 import glob
5 import datetime
5 import datetime
6 from multiprocessing import Process
6 from multiprocessing import Process
7
7
8 import zmq
8 import zmq
9 import numpy
9 import numpy
10 import matplotlib
10 import matplotlib
11 import matplotlib.pyplot as plt
11 import matplotlib.pyplot as plt
12 from mpl_toolkits.axes_grid1 import make_axes_locatable
12 from mpl_toolkits.axes_grid1 import make_axes_locatable
13 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
13 from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator
14
14
15 from schainpy.model.proc.jroproc_base import Operation
15 from schainpy.model.proc.jroproc_base import Operation
16 from schainpy.utils import log
16 from schainpy.utils import log
17
17
18 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
18 jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90]
19 blu_values = matplotlib.pyplot.get_cmap(
19 blu_values = matplotlib.pyplot.get_cmap(
20 'seismic_r', 20)(numpy.arange(20))[10:15]
20 'seismic_r', 20)(numpy.arange(20))[10:15]
21 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
21 ncmap = matplotlib.colors.LinearSegmentedColormap.from_list(
22 'jro', numpy.vstack((blu_values, jet_values)))
22 'jro', numpy.vstack((blu_values, jet_values)))
23 matplotlib.pyplot.register_cmap(cmap=ncmap)
23 matplotlib.pyplot.register_cmap(cmap=ncmap)
24
24
25 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis', 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
25 CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis', 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')]
26
26
27
27
28 def figpause(interval):
28 def figpause(interval):
29 backend = plt.rcParams['backend']
29 backend = plt.rcParams['backend']
30 if backend in matplotlib.rcsetup.interactive_bk:
30 if backend in matplotlib.rcsetup.interactive_bk:
31 figManager = matplotlib._pylab_helpers.Gcf.get_active()
31 figManager = matplotlib._pylab_helpers.Gcf.get_active()
32 if figManager is not None:
32 if figManager is not None:
33 canvas = figManager.canvas
33 canvas = figManager.canvas
34 if canvas.figure.stale:
34 if canvas.figure.stale:
35 canvas.draw()
35 canvas.draw()
36 canvas.start_event_loop(interval)
36 try:
37 canvas.start_event_loop(interval)
38 except:
39 pass
37 return
40 return
38
41
39 def popup(message):
42 def popup(message):
40 fig = plt.figure(figsize=(12, 8), facecolor='r')
43 '''
41 fig.text(0.5, 0.5, message, ha='center', va='center', size='20', weight='heavy', color='w')
44 '''
45
46 fig = plt.figure(figsize=(12, 8), facecolor='r')
47 text = '\n'.join([s.strip() for s in message.split(':')])
48 fig.text(0.01, 0.5, text, ha='left', va='center', size='20', weight='heavy', color='w')
42 fig.show()
49 fig.show()
43 figpause(1000)
50 figpause(1000)
44
51
45
52
46 class PlotData(Operation, Process):
53 class PlotData(Operation, Process):
47 '''
54 '''
48 Base class for Schain plotting operations
55 Base class for Schain plotting operations
49 '''
56 '''
50
57
51 CODE = 'Figure'
58 CODE = 'Figure'
52 colormap = 'jro'
59 colormap = 'jro'
53 bgcolor = 'white'
60 bgcolor = 'white'
54 CONFLATE = False
61 CONFLATE = False
55 __missing = 1E30
62 __missing = 1E30
56
63
57 __attrs__ = ['show', 'save', 'xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax',
64 __attrs__ = ['show', 'save', 'xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax',
58 'zlimits', 'xlabel', 'ylabel', 'xaxis','cb_label', 'title',
65 'zlimits', 'xlabel', 'ylabel', 'xaxis','cb_label', 'title',
59 'colorbar', 'bgcolor', 'width', 'height', 'localtime', 'oneFigure',
66 'colorbar', 'bgcolor', 'width', 'height', 'localtime', 'oneFigure',
60 'showprofile', 'decimation']
67 'showprofile', 'decimation']
61
68
62 def __init__(self, **kwargs):
69 def __init__(self, **kwargs):
63
70
64 Operation.__init__(self, plot=True, **kwargs)
71 Operation.__init__(self, plot=True, **kwargs)
65 Process.__init__(self)
72 Process.__init__(self)
66
73
67 self.kwargs['code'] = self.CODE
74 self.kwargs['code'] = self.CODE
68 self.mp = False
75 self.mp = False
69 self.data = None
76 self.data = None
70 self.isConfig = False
77 self.isConfig = False
71 self.figures = []
78 self.figures = []
72 self.axes = []
79 self.axes = []
73 self.cb_axes = []
80 self.cb_axes = []
74 self.localtime = kwargs.pop('localtime', True)
81 self.localtime = kwargs.pop('localtime', True)
75 self.show = kwargs.get('show', True)
82 self.show = kwargs.get('show', True)
76 self.save = kwargs.get('save', False)
83 self.save = kwargs.get('save', False)
77 self.colormap = kwargs.get('colormap', self.colormap)
84 self.colormap = kwargs.get('colormap', self.colormap)
78 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
85 self.colormap_coh = kwargs.get('colormap_coh', 'jet')
79 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
86 self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r')
80 self.colormaps = kwargs.get('colormaps', None)
87 self.colormaps = kwargs.get('colormaps', None)
81 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
88 self.bgcolor = kwargs.get('bgcolor', self.bgcolor)
82 self.showprofile = kwargs.get('showprofile', False)
89 self.showprofile = kwargs.get('showprofile', False)
83 self.title = kwargs.get('wintitle', self.CODE.upper())
90 self.title = kwargs.get('wintitle', self.CODE.upper())
84 self.cb_label = kwargs.get('cb_label', None)
91 self.cb_label = kwargs.get('cb_label', None)
85 self.cb_labels = kwargs.get('cb_labels', None)
92 self.cb_labels = kwargs.get('cb_labels', None)
86 self.xaxis = kwargs.get('xaxis', 'frequency')
93 self.xaxis = kwargs.get('xaxis', 'frequency')
87 self.zmin = kwargs.get('zmin', None)
94 self.zmin = kwargs.get('zmin', None)
88 self.zmax = kwargs.get('zmax', None)
95 self.zmax = kwargs.get('zmax', None)
89 self.zlimits = kwargs.get('zlimits', None)
96 self.zlimits = kwargs.get('zlimits', None)
90 self.xmin = kwargs.get('xmin', None)
97 self.xmin = kwargs.get('xmin', None)
91 self.xmax = kwargs.get('xmax', None)
98 self.xmax = kwargs.get('xmax', None)
92 self.xrange = kwargs.get('xrange', 24)
99 self.xrange = kwargs.get('xrange', 24)
93 self.ymin = kwargs.get('ymin', None)
100 self.ymin = kwargs.get('ymin', None)
94 self.ymax = kwargs.get('ymax', None)
101 self.ymax = kwargs.get('ymax', None)
95 self.xlabel = kwargs.get('xlabel', None)
102 self.xlabel = kwargs.get('xlabel', None)
96 self.decimation = kwargs.get('decimation', None)
103 self.decimation = kwargs.get('decimation', None)
97 self.showSNR = kwargs.get('showSNR', False)
104 self.showSNR = kwargs.get('showSNR', False)
98 self.oneFigure = kwargs.get('oneFigure', True)
105 self.oneFigure = kwargs.get('oneFigure', True)
99 self.width = kwargs.get('width', None)
106 self.width = kwargs.get('width', None)
100 self.height = kwargs.get('height', None)
107 self.height = kwargs.get('height', None)
101 self.colorbar = kwargs.get('colorbar', True)
108 self.colorbar = kwargs.get('colorbar', True)
102 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
109 self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1])
103 self.titles = kwargs.get('titles', [])
110 self.titles = kwargs.get('titles', [])
104 self.polar = False
111 self.polar = False
105
112
106 def __fmtTime(self, x, pos):
113 def __fmtTime(self, x, pos):
107 '''
114 '''
108 '''
115 '''
109
116
110 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
117 return '{}'.format(self.getDateTime(x).strftime('%H:%M'))
111
118
112 def __setup(self):
119 def __setup(self):
113 '''
120 '''
114 Common setup for all figures, here figures and axes are created
121 Common setup for all figures, here figures and axes are created
115 '''
122 '''
116
123
117 if self.CODE not in self.data:
124 if self.CODE not in self.data:
118 raise ValueError(log.error('Missing data for {}'.format(self.CODE),
125 raise ValueError(log.error('Missing data for {}'.format(self.CODE),
119 self.name))
126 self.name))
120
127
121 self.setup()
128 self.setup()
122
129
123 self.time_label = 'LT' if self.localtime else 'UTC'
130 self.time_label = 'LT' if self.localtime else 'UTC'
124 if self.data.localtime:
131 if self.data.localtime:
125 self.getDateTime = datetime.datetime.fromtimestamp
132 self.getDateTime = datetime.datetime.fromtimestamp
126 else:
133 else:
127 self.getDateTime = datetime.datetime.utcfromtimestamp
134 self.getDateTime = datetime.datetime.utcfromtimestamp
128
135
129 if self.width is None:
136 if self.width is None:
130 self.width = 8
137 self.width = 8
131
138
132 self.figures = []
139 self.figures = []
133 self.axes = []
140 self.axes = []
134 self.cb_axes = []
141 self.cb_axes = []
135 self.pf_axes = []
142 self.pf_axes = []
136 self.cmaps = []
143 self.cmaps = []
137
144
138 size = '15%' if self.ncols == 1 else '30%'
145 size = '15%' if self.ncols == 1 else '30%'
139 pad = '4%' if self.ncols == 1 else '8%'
146 pad = '4%' if self.ncols == 1 else '8%'
140
147
141 if self.oneFigure:
148 if self.oneFigure:
142 if self.height is None:
149 if self.height is None:
143 self.height = 1.4 * self.nrows + 1
150 self.height = 1.4 * self.nrows + 1
144 fig = plt.figure(figsize=(self.width, self.height),
151 fig = plt.figure(figsize=(self.width, self.height),
145 edgecolor='k',
152 edgecolor='k',
146 facecolor='w')
153 facecolor='w')
147 self.figures.append(fig)
154 self.figures.append(fig)
148 for n in range(self.nplots):
155 for n in range(self.nplots):
149 ax = fig.add_subplot(self.nrows, self.ncols,
156 ax = fig.add_subplot(self.nrows, self.ncols,
150 n + 1, polar=self.polar)
157 n + 1, polar=self.polar)
151 ax.tick_params(labelsize=8)
158 ax.tick_params(labelsize=8)
152 ax.firsttime = True
159 ax.firsttime = True
153 ax.index = 0
160 ax.index = 0
154 ax.press = None
161 ax.press = None
155 self.axes.append(ax)
162 self.axes.append(ax)
156 if self.showprofile:
163 if self.showprofile:
157 cax = self.__add_axes(ax, size=size, pad=pad)
164 cax = self.__add_axes(ax, size=size, pad=pad)
158 cax.tick_params(labelsize=8)
165 cax.tick_params(labelsize=8)
159 self.pf_axes.append(cax)
166 self.pf_axes.append(cax)
160 else:
167 else:
161 if self.height is None:
168 if self.height is None:
162 self.height = 3
169 self.height = 3
163 for n in range(self.nplots):
170 for n in range(self.nplots):
164 fig = plt.figure(figsize=(self.width, self.height),
171 fig = plt.figure(figsize=(self.width, self.height),
165 edgecolor='k',
172 edgecolor='k',
166 facecolor='w')
173 facecolor='w')
167 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
174 ax = fig.add_subplot(1, 1, 1, polar=self.polar)
168 ax.tick_params(labelsize=8)
175 ax.tick_params(labelsize=8)
169 ax.firsttime = True
176 ax.firsttime = True
170 ax.index = 0
177 ax.index = 0
171 ax.press = None
178 ax.press = None
172 self.figures.append(fig)
179 self.figures.append(fig)
173 self.axes.append(ax)
180 self.axes.append(ax)
174 if self.showprofile:
181 if self.showprofile:
175 cax = self.__add_axes(ax, size=size, pad=pad)
182 cax = self.__add_axes(ax, size=size, pad=pad)
176 cax.tick_params(labelsize=8)
183 cax.tick_params(labelsize=8)
177 self.pf_axes.append(cax)
184 self.pf_axes.append(cax)
178
185
179 for n in range(self.nrows):
186 for n in range(self.nrows):
180 if self.colormaps is not None:
187 if self.colormaps is not None:
181 cmap = plt.get_cmap(self.colormaps[n])
188 cmap = plt.get_cmap(self.colormaps[n])
182 else:
189 else:
183 cmap = plt.get_cmap(self.colormap)
190 cmap = plt.get_cmap(self.colormap)
184 cmap.set_bad(self.bgcolor, 1.)
191 cmap.set_bad(self.bgcolor, 1.)
185 self.cmaps.append(cmap)
192 self.cmaps.append(cmap)
186
193
187 for fig in self.figures:
194 for fig in self.figures:
188 fig.canvas.mpl_connect('key_press_event', self.OnKeyPress)
195 fig.canvas.mpl_connect('key_press_event', self.OnKeyPress)
189 fig.canvas.mpl_connect('scroll_event', self.OnBtnScroll)
196 fig.canvas.mpl_connect('scroll_event', self.OnBtnScroll)
190 fig.canvas.mpl_connect('button_press_event', self.onBtnPress)
197 fig.canvas.mpl_connect('button_press_event', self.onBtnPress)
191 fig.canvas.mpl_connect('motion_notify_event', self.onMotion)
198 fig.canvas.mpl_connect('motion_notify_event', self.onMotion)
192 fig.canvas.mpl_connect('button_release_event', self.onBtnRelease)
199 fig.canvas.mpl_connect('button_release_event', self.onBtnRelease)
193 if self.show:
200 if self.show:
194 fig.show()
201 fig.show()
195
202
196 def OnKeyPress(self, event):
203 def OnKeyPress(self, event):
197 '''
204 '''
198 Event for pressing keys (up, down) change colormap
205 Event for pressing keys (up, down) change colormap
199 '''
206 '''
200 ax = event.inaxes
207 ax = event.inaxes
201 if ax in self.axes:
208 if ax in self.axes:
202 if event.key == 'down':
209 if event.key == 'down':
203 ax.index += 1
210 ax.index += 1
204 elif event.key == 'up':
211 elif event.key == 'up':
205 ax.index -= 1
212 ax.index -= 1
206 if ax.index < 0:
213 if ax.index < 0:
207 ax.index = len(CMAPS) - 1
214 ax.index = len(CMAPS) - 1
208 elif ax.index == len(CMAPS):
215 elif ax.index == len(CMAPS):
209 ax.index = 0
216 ax.index = 0
210 cmap = CMAPS[ax.index]
217 cmap = CMAPS[ax.index]
211 ax.cbar.set_cmap(cmap)
218 ax.cbar.set_cmap(cmap)
212 ax.cbar.draw_all()
219 ax.cbar.draw_all()
213 ax.plt.set_cmap(cmap)
220 ax.plt.set_cmap(cmap)
214 ax.cbar.patch.figure.canvas.draw()
221 ax.cbar.patch.figure.canvas.draw()
215 self.colormap = cmap.name
222 self.colormap = cmap.name
216
223
217 def OnBtnScroll(self, event):
224 def OnBtnScroll(self, event):
218 '''
225 '''
219 Event for scrolling, scale figure
226 Event for scrolling, scale figure
220 '''
227 '''
221 cb_ax = event.inaxes
228 cb_ax = event.inaxes
222 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
229 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
223 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
230 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
224 pt = ax.cbar.ax.bbox.get_points()[:, 1]
231 pt = ax.cbar.ax.bbox.get_points()[:, 1]
225 nrm = ax.cbar.norm
232 nrm = ax.cbar.norm
226 vmin, vmax, p0, p1, pS = (
233 vmin, vmax, p0, p1, pS = (
227 nrm.vmin, nrm.vmax, pt[0], pt[1], event.y)
234 nrm.vmin, nrm.vmax, pt[0], pt[1], event.y)
228 scale = 2 if event.step == 1 else 0.5
235 scale = 2 if event.step == 1 else 0.5
229 point = vmin + (vmax - vmin) / (p1 - p0) * (pS - p0)
236 point = vmin + (vmax - vmin) / (p1 - p0) * (pS - p0)
230 ax.cbar.norm.vmin = point - scale * (point - vmin)
237 ax.cbar.norm.vmin = point - scale * (point - vmin)
231 ax.cbar.norm.vmax = point - scale * (point - vmax)
238 ax.cbar.norm.vmax = point - scale * (point - vmax)
232 ax.plt.set_norm(ax.cbar.norm)
239 ax.plt.set_norm(ax.cbar.norm)
233 ax.cbar.draw_all()
240 ax.cbar.draw_all()
234 ax.cbar.patch.figure.canvas.draw()
241 ax.cbar.patch.figure.canvas.draw()
235
242
236 def onBtnPress(self, event):
243 def onBtnPress(self, event):
237 '''
244 '''
238 Event for mouse button press
245 Event for mouse button press
239 '''
246 '''
240 cb_ax = event.inaxes
247 cb_ax = event.inaxes
241 if cb_ax is None:
248 if cb_ax is None:
242 return
249 return
243
250
244 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
251 if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]:
245 cb_ax.press = event.x, event.y
252 cb_ax.press = event.x, event.y
246 else:
253 else:
247 cb_ax.press = None
254 cb_ax.press = None
248
255
249 def onMotion(self, event):
256 def onMotion(self, event):
250 '''
257 '''
251 Event for move inside colorbar
258 Event for move inside colorbar
252 '''
259 '''
253 cb_ax = event.inaxes
260 cb_ax = event.inaxes
254 if cb_ax is None:
261 if cb_ax is None:
255 return
262 return
256 if cb_ax not in [ax.cbar.ax for ax in self.axes if ax.cbar]:
263 if cb_ax not in [ax.cbar.ax for ax in self.axes if ax.cbar]:
257 return
264 return
258 if cb_ax.press is None:
265 if cb_ax.press is None:
259 return
266 return
260
267
261 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
268 ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0]
262 xprev, yprev = cb_ax.press
269 xprev, yprev = cb_ax.press
263 dx = event.x - xprev
270 dx = event.x - xprev
264 dy = event.y - yprev
271 dy = event.y - yprev
265 cb_ax.press = event.x, event.y
272 cb_ax.press = event.x, event.y
266 scale = ax.cbar.norm.vmax - ax.cbar.norm.vmin
273 scale = ax.cbar.norm.vmax - ax.cbar.norm.vmin
267 perc = 0.03
274 perc = 0.03
268
275
269 if event.button == 1:
276 if event.button == 1:
270 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
277 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
271 ax.cbar.norm.vmax -= (perc * scale) * numpy.sign(dy)
278 ax.cbar.norm.vmax -= (perc * scale) * numpy.sign(dy)
272 elif event.button == 3:
279 elif event.button == 3:
273 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
280 ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy)
274 ax.cbar.norm.vmax += (perc * scale) * numpy.sign(dy)
281 ax.cbar.norm.vmax += (perc * scale) * numpy.sign(dy)
275
282
276 ax.cbar.draw_all()
283 ax.cbar.draw_all()
277 ax.plt.set_norm(ax.cbar.norm)
284 ax.plt.set_norm(ax.cbar.norm)
278 ax.cbar.patch.figure.canvas.draw()
285 ax.cbar.patch.figure.canvas.draw()
279
286
280 def onBtnRelease(self, event):
287 def onBtnRelease(self, event):
281 '''
288 '''
282 Event for mouse button release
289 Event for mouse button release
283 '''
290 '''
284 cb_ax = event.inaxes
291 cb_ax = event.inaxes
285 if cb_ax is not None:
292 if cb_ax is not None:
286 cb_ax.press = None
293 cb_ax.press = None
287
294
288 def __add_axes(self, ax, size='30%', pad='8%'):
295 def __add_axes(self, ax, size='30%', pad='8%'):
289 '''
296 '''
290 Add new axes to the given figure
297 Add new axes to the given figure
291 '''
298 '''
292 divider = make_axes_locatable(ax)
299 divider = make_axes_locatable(ax)
293 nax = divider.new_horizontal(size=size, pad=pad)
300 nax = divider.new_horizontal(size=size, pad=pad)
294 ax.figure.add_axes(nax)
301 ax.figure.add_axes(nax)
295 return nax
302 return nax
296
303
297 self.setup()
304 self.setup()
298
305
299 def setup(self):
306 def setup(self):
300 '''
307 '''
301 This method should be implemented in the child class, the following
308 This method should be implemented in the child class, the following
302 attributes should be set:
309 attributes should be set:
303
310
304 self.nrows: number of rows
311 self.nrows: number of rows
305 self.ncols: number of cols
312 self.ncols: number of cols
306 self.nplots: number of plots (channels or pairs)
313 self.nplots: number of plots (channels or pairs)
307 self.ylabel: label for Y axes
314 self.ylabel: label for Y axes
308 self.titles: list of axes title
315 self.titles: list of axes title
309
316
310 '''
317 '''
311 raise(NotImplementedError, 'Implement this method in child class')
318 raise(NotImplementedError, 'Implement this method in child class')
312
319
313 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
320 def fill_gaps(self, x_buffer, y_buffer, z_buffer):
314 '''
321 '''
315 Create a masked array for missing data
322 Create a masked array for missing data
316 '''
323 '''
317 if x_buffer.shape[0] < 2:
324 if x_buffer.shape[0] < 2:
318 return x_buffer, y_buffer, z_buffer
325 return x_buffer, y_buffer, z_buffer
319
326
320 deltas = x_buffer[1:] - x_buffer[0:-1]
327 deltas = x_buffer[1:] - x_buffer[0:-1]
321 x_median = numpy.median(deltas)
328 x_median = numpy.median(deltas)
322
329
323 index = numpy.where(deltas > 5 * x_median)
330 index = numpy.where(deltas > 5 * x_median)
324
331
325 if len(index[0]) != 0:
332 if len(index[0]) != 0:
326 z_buffer[::, index[0], ::] = self.__missing
333 z_buffer[::, index[0], ::] = self.__missing
327 z_buffer = numpy.ma.masked_inside(z_buffer,
334 z_buffer = numpy.ma.masked_inside(z_buffer,
328 0.99 * self.__missing,
335 0.99 * self.__missing,
329 1.01 * self.__missing)
336 1.01 * self.__missing)
330
337
331 return x_buffer, y_buffer, z_buffer
338 return x_buffer, y_buffer, z_buffer
332
339
333 def decimate(self):
340 def decimate(self):
334
341
335 # dx = int(len(self.x)/self.__MAXNUMX) + 1
342 # dx = int(len(self.x)/self.__MAXNUMX) + 1
336 dy = int(len(self.y) / self.decimation) + 1
343 dy = int(len(self.y) / self.decimation) + 1
337
344
338 # x = self.x[::dx]
345 # x = self.x[::dx]
339 x = self.x
346 x = self.x
340 y = self.y[::dy]
347 y = self.y[::dy]
341 z = self.z[::, ::, ::dy]
348 z = self.z[::, ::, ::dy]
342
349
343 return x, y, z
350 return x, y, z
344
351
345 def format(self):
352 def format(self):
346 '''
353 '''
347 Set min and max values, labels, ticks and titles
354 Set min and max values, labels, ticks and titles
348 '''
355 '''
349
356
350 if self.xmin is None:
357 if self.xmin is None:
351 xmin = self.min_time
358 xmin = self.min_time
352 else:
359 else:
353 if self.xaxis is 'time':
360 if self.xaxis is 'time':
354 dt = self.getDateTime(self.min_time)
361 dt = self.getDateTime(self.min_time)
355 xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) -
362 xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) -
356 datetime.datetime(1970, 1, 1)).total_seconds()
363 datetime.datetime(1970, 1, 1)).total_seconds()
357 if self.data.localtime:
364 if self.data.localtime:
358 xmin += time.timezone
365 xmin += time.timezone
359 else:
366 else:
360 xmin = self.xmin
367 xmin = self.xmin
361
368
362 if self.xmax is None:
369 if self.xmax is None:
363 xmax = xmin + self.xrange * 60 * 60
370 xmax = xmin + self.xrange * 60 * 60
364 else:
371 else:
365 if self.xaxis is 'time':
372 if self.xaxis is 'time':
366 dt = self.getDateTime(self.max_time)
373 dt = self.getDateTime(self.max_time)
367 xmax = (dt.replace(hour=int(self.xmax), minute=59, second=59) -
374 xmax = (dt.replace(hour=int(self.xmax), minute=59, second=59) -
368 datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds()
375 datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds()
369 if self.data.localtime:
376 if self.data.localtime:
370 xmax += time.timezone
377 xmax += time.timezone
371 else:
378 else:
372 xmax = self.xmax
379 xmax = self.xmax
373
380
374 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
381 ymin = self.ymin if self.ymin else numpy.nanmin(self.y)
375 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
382 ymax = self.ymax if self.ymax else numpy.nanmax(self.y)
376
383
377 Y = numpy.array([5, 10, 20, 50, 100, 200, 500, 1000, 2000])
384 Y = numpy.array([5, 10, 20, 50, 100, 200, 500, 1000, 2000])
378 i = 1 if numpy.where(ymax-ymin < Y)[0][0] < 0 else numpy.where(ymax-ymin < Y)[0][0]
385 i = 1 if numpy.where(ymax-ymin < Y)[0][0] < 0 else numpy.where(ymax-ymin < Y)[0][0]
379 ystep = Y[i] / 5
386 ystep = Y[i] / 5
380
387
381 for n, ax in enumerate(self.axes):
388 for n, ax in enumerate(self.axes):
382 if ax.firsttime:
389 if ax.firsttime:
383 ax.set_facecolor(self.bgcolor)
390 ax.set_facecolor(self.bgcolor)
384 ax.yaxis.set_major_locator(MultipleLocator(ystep))
391 ax.yaxis.set_major_locator(MultipleLocator(ystep))
385 if self.xaxis is 'time':
392 if self.xaxis is 'time':
386 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
393 ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime))
387 ax.xaxis.set_major_locator(LinearLocator(9))
394 ax.xaxis.set_major_locator(LinearLocator(9))
388 if self.xlabel is not None:
395 if self.xlabel is not None:
389 ax.set_xlabel(self.xlabel)
396 ax.set_xlabel(self.xlabel)
390 ax.set_ylabel(self.ylabel)
397 ax.set_ylabel(self.ylabel)
391 ax.firsttime = False
398 ax.firsttime = False
392 if self.showprofile:
399 if self.showprofile:
393 self.pf_axes[n].set_ylim(ymin, ymax)
400 self.pf_axes[n].set_ylim(ymin, ymax)
394 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
401 self.pf_axes[n].set_xlim(self.zmin, self.zmax)
395 self.pf_axes[n].set_xlabel('dB')
402 self.pf_axes[n].set_xlabel('dB')
396 self.pf_axes[n].grid(b=True, axis='x')
403 self.pf_axes[n].grid(b=True, axis='x')
397 [tick.set_visible(False)
404 [tick.set_visible(False)
398 for tick in self.pf_axes[n].get_yticklabels()]
405 for tick in self.pf_axes[n].get_yticklabels()]
399 if self.colorbar:
406 if self.colorbar:
400 ax.cbar = plt.colorbar(
407 ax.cbar = plt.colorbar(
401 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
408 ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10)
402 ax.cbar.ax.tick_params(labelsize=8)
409 ax.cbar.ax.tick_params(labelsize=8)
403 ax.cbar.ax.press = None
410 ax.cbar.ax.press = None
404 if self.cb_label:
411 if self.cb_label:
405 ax.cbar.set_label(self.cb_label, size=8)
412 ax.cbar.set_label(self.cb_label, size=8)
406 elif self.cb_labels:
413 elif self.cb_labels:
407 ax.cbar.set_label(self.cb_labels[n], size=8)
414 ax.cbar.set_label(self.cb_labels[n], size=8)
408 else:
415 else:
409 ax.cbar = None
416 ax.cbar = None
410
417
411 if not self.polar:
418 if not self.polar:
412 ax.set_xlim(xmin, xmax)
419 ax.set_xlim(xmin, xmax)
413 ax.set_ylim(ymin, ymax)
420 ax.set_ylim(ymin, ymax)
414 ax.set_title('{} - {} {}'.format(
421 ax.set_title('{} - {} {}'.format(
415 self.titles[n],
422 self.titles[n],
416 self.getDateTime(self.max_time).strftime('%H:%M:%S'),
423 self.getDateTime(self.max_time).strftime('%H:%M:%S'),
417 self.time_label),
424 self.time_label),
418 size=8)
425 size=8)
419 else:
426 else:
420 ax.set_title('{}'.format(self.titles[n]), size=8)
427 ax.set_title('{}'.format(self.titles[n]), size=8)
421 ax.set_ylim(0, 90)
428 ax.set_ylim(0, 90)
422 ax.set_yticks(numpy.arange(0, 90, 20))
429 ax.set_yticks(numpy.arange(0, 90, 20))
423 ax.yaxis.labelpad = 40
430 ax.yaxis.labelpad = 40
424
431
425 def __plot(self):
432 def __plot(self):
426 '''
433 '''
427 '''
434 '''
428 log.success('Plotting', self.name)
435 log.success('Plotting', self.name)
429
436
430 try:
437 try:
431 self.plot()
438 self.plot()
432 self.format()
439 self.format()
433 except:
440 except:
434 log.warning('{} Plot could not be updated... check data'.format(self.CODE), self.name)
441 log.warning('{} Plot could not be updated... check data'.format(self.CODE), self.name)
435
442
436 for n, fig in enumerate(self.figures):
443 for n, fig in enumerate(self.figures):
437 if self.nrows == 0 or self.nplots == 0:
444 if self.nrows == 0 or self.nplots == 0:
438 log.warning('No data', self.name)
445 log.warning('No data', self.name)
439 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
446 fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center')
440 fig.canvas.manager.set_window_title(self.CODE)
447 fig.canvas.manager.set_window_title(self.CODE)
441 continue
448 continue
442
449
443 fig.tight_layout()
450 fig.tight_layout()
444 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
451 fig.canvas.manager.set_window_title('{} - {}'.format(self.title,
445 self.getDateTime(self.max_time).strftime('%Y/%m/%d')))
452 self.getDateTime(self.max_time).strftime('%Y/%m/%d')))
446 fig.canvas.draw()
453 fig.canvas.draw()
447
454
448 if self.save and self.data.ended:
455 if self.save and self.data.ended:
449 channels = range(self.nrows)
456 channels = range(self.nrows)
450 if self.oneFigure:
457 if self.oneFigure:
451 label = ''
458 label = ''
452 else:
459 else:
453 label = '_{}'.format(channels[n])
460 label = '_{}'.format(channels[n])
454 figname = os.path.join(
461 figname = os.path.join(
455 self.save,
462 self.save,
456 '{}{}_{}.png'.format(
463 '{}{}_{}.png'.format(
457 self.CODE,
464 self.CODE,
458 label,
465 label,
459 self.getDateTime(self.saveTime).strftime(
466 self.getDateTime(self.saveTime).strftime(
460 '%Y%m%d_%H%M%S'),
467 '%Y%m%d_%H%M%S'),
461 )
468 )
462 )
469 )
463 log.log('Saving figure: {}'.format(figname), self.name)
470 log.log('Saving figure: {}'.format(figname), self.name)
464 fig.savefig(figname)
471 fig.savefig(figname)
465
472
466 def plot(self):
473 def plot(self):
467 '''
474 '''
468 '''
475 '''
469 raise(NotImplementedError, 'Implement this method in child class')
476 raise(NotImplementedError, 'Implement this method in child class')
470
477
471 def run(self):
478 def run(self):
472
479
473 log.success('Starting', self.name)
480 log.success('Starting', self.name)
474
481
475 context = zmq.Context()
482 context = zmq.Context()
476 receiver = context.socket(zmq.SUB)
483 receiver = context.socket(zmq.SUB)
477 receiver.setsockopt(zmq.SUBSCRIBE, '')
484 receiver.setsockopt(zmq.SUBSCRIBE, '')
478 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
485 receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
479
486
480 if 'server' in self.kwargs['parent']:
487 if 'server' in self.kwargs['parent']:
481 receiver.connect(
488 receiver.connect(
482 'ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
489 'ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
483 else:
490 else:
484 receiver.connect("ipc:///tmp/zmq.plots")
491 receiver.connect("ipc:///tmp/zmq.plots")
485
492
486 while True:
493 while True:
487 try:
494 try:
488 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
495 self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)
489 if self.data.localtime and self.localtime:
496 if self.data.localtime and self.localtime:
490 self.times = self.data.times
497 self.times = self.data.times
491 elif self.data.localtime and not self.localtime:
498 elif self.data.localtime and not self.localtime:
492 self.times = self.data.times + time.timezone
499 self.times = self.data.times + time.timezone
493 elif not self.data.localtime and self.localtime:
500 elif not self.data.localtime and self.localtime:
494 self.times = self.data.times - time.timezone
501 self.times = self.data.times - time.timezone
495 else:
502 else:
496 self.times = self.data.times
503 self.times = self.data.times
497
504
498 self.min_time = self.times[0]
505 self.min_time = self.times[0]
499 self.max_time = self.times[-1]
506 self.max_time = self.times[-1]
500
507
501 if self.isConfig is False:
508 if self.isConfig is False:
502 self.__setup()
509 self.__setup()
503 self.isConfig = True
510 self.isConfig = True
504
511
505 self.__plot()
512 self.__plot()
506
513
507 except zmq.Again as e:
514 except zmq.Again as e:
508 log.log('Waiting for data...')
515 log.log('Waiting for data...')
509 if self.data:
516 if self.data:
510 figpause(self.data.throttle)
517 figpause(self.data.throttle)
511 else:
518 else:
512 time.sleep(2)
519 time.sleep(2)
513
520
514 def close(self):
521 def close(self):
515 if self.data:
522 if self.data:
516 self.__plot()
523 self.__plot()
517
524
518
525
519 class PlotSpectraData(PlotData):
526 class PlotSpectraData(PlotData):
520 '''
527 '''
521 Plot for Spectra data
528 Plot for Spectra data
522 '''
529 '''
523
530
524 CODE = 'spc'
531 CODE = 'spc'
525 colormap = 'jro'
532 colormap = 'jro'
526
533
527 def setup(self):
534 def setup(self):
528 self.nplots = len(self.data.channels)
535 self.nplots = len(self.data.channels)
529 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
536 self.ncols = int(numpy.sqrt(self.nplots) + 0.9)
530 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
537 self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9)
531 self.width = 3.4 * self.ncols
538 self.width = 3.4 * self.ncols
532 self.height = 3 * self.nrows
539 self.height = 3 * self.nrows
533 self.cb_label = 'dB'
540 self.cb_label = 'dB'
534 if self.showprofile:
541 if self.showprofile:
535 self.width += 0.8 * self.ncols
542 self.width += 0.8 * self.ncols
536
543
537 self.ylabel = 'Range [km]'
544 self.ylabel = 'Range [km]'
538
545
539 def plot(self):
546 def plot(self):
540 if self.xaxis == "frequency":
547 if self.xaxis == "frequency":
541 x = self.data.xrange[0]
548 x = self.data.xrange[0]
542 self.xlabel = "Frequency (kHz)"
549 self.xlabel = "Frequency (kHz)"
543 elif self.xaxis == "time":
550 elif self.xaxis == "time":
544 x = self.data.xrange[1]
551 x = self.data.xrange[1]
545 self.xlabel = "Time (ms)"
552 self.xlabel = "Time (ms)"
546 else:
553 else:
547 x = self.data.xrange[2]
554 x = self.data.xrange[2]
548 self.xlabel = "Velocity (m/s)"
555 self.xlabel = "Velocity (m/s)"
549
556
550 if self.CODE == 'spc_mean':
557 if self.CODE == 'spc_mean':
551 x = self.data.xrange[2]
558 x = self.data.xrange[2]
552 self.xlabel = "Velocity (m/s)"
559 self.xlabel = "Velocity (m/s)"
553
560
554 self.titles = []
561 self.titles = []
555
562
556 y = self.data.heights
563 y = self.data.heights
557 self.y = y
564 self.y = y
558 z = self.data['spc']
565 z = self.data['spc']
559
566
560 for n, ax in enumerate(self.axes):
567 for n, ax in enumerate(self.axes):
561 noise = self.data['noise'][n][-1]
568 noise = self.data['noise'][n][-1]
562 if self.CODE == 'spc_mean':
569 if self.CODE == 'spc_mean':
563 mean = self.data['mean'][n][-1]
570 mean = self.data['mean'][n][-1]
564 if ax.firsttime:
571 if ax.firsttime:
565 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
572 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
566 self.xmin = self.xmin if self.xmin else -self.xmax
573 self.xmin = self.xmin if self.xmin else -self.xmax
567 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
574 self.zmin = self.zmin if self.zmin else numpy.nanmin(z)
568 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
575 self.zmax = self.zmax if self.zmax else numpy.nanmax(z)
569 ax.plt = ax.pcolormesh(x, y, z[n].T,
576 ax.plt = ax.pcolormesh(x, y, z[n].T,
570 vmin=self.zmin,
577 vmin=self.zmin,
571 vmax=self.zmax,
578 vmax=self.zmax,
572 cmap=plt.get_cmap(self.colormap)
579 cmap=plt.get_cmap(self.colormap)
573 )
580 )
574
581
575 if self.showprofile:
582 if self.showprofile:
576 ax.plt_profile = self.pf_axes[n].plot(
583 ax.plt_profile = self.pf_axes[n].plot(
577 self.data['rti'][n][-1], y)[0]
584 self.data['rti'][n][-1], y)[0]
578 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
585 ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y,
579 color="k", linestyle="dashed", lw=1)[0]
586 color="k", linestyle="dashed", lw=1)[0]
580 if self.CODE == 'spc_mean':
587 if self.CODE == 'spc_mean':
581 ax.plt_mean = ax.plot(mean, y, color='k')[0]
588 ax.plt_mean = ax.plot(mean, y, color='k')[0]
582 else:
589 else:
583 ax.plt.set_array(z[n].T.ravel())
590 ax.plt.set_array(z[n].T.ravel())
584 if self.showprofile:
591 if self.showprofile:
585 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
592 ax.plt_profile.set_data(self.data['rti'][n][-1], y)
586 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
593 ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y)
587 if self.CODE == 'spc_mean':
594 if self.CODE == 'spc_mean':
588 ax.plt_mean.set_data(mean, y)
595 ax.plt_mean.set_data(mean, y)
589
596
590 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
597 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
591 self.saveTime = self.max_time
598 self.saveTime = self.max_time
592
599
593
600
594 class PlotCrossSpectraData(PlotData):
601 class PlotCrossSpectraData(PlotData):
595
602
596 CODE = 'cspc'
603 CODE = 'cspc'
597 zmin_coh = None
604 zmin_coh = None
598 zmax_coh = None
605 zmax_coh = None
599 zmin_phase = None
606 zmin_phase = None
600 zmax_phase = None
607 zmax_phase = None
601
608
602 def setup(self):
609 def setup(self):
603
610
604 self.ncols = 4
611 self.ncols = 4
605 self.nrows = len(self.data.pairs)
612 self.nrows = len(self.data.pairs)
606 self.nplots = self.nrows * 4
613 self.nplots = self.nrows * 4
607 self.width = 3.4 * self.ncols
614 self.width = 3.4 * self.ncols
608 self.height = 3 * self.nrows
615 self.height = 3 * self.nrows
609 self.ylabel = 'Range [km]'
616 self.ylabel = 'Range [km]'
610 self.showprofile = False
617 self.showprofile = False
611
618
612 def plot(self):
619 def plot(self):
613
620
614 if self.xaxis == "frequency":
621 if self.xaxis == "frequency":
615 x = self.data.xrange[0]
622 x = self.data.xrange[0]
616 self.xlabel = "Frequency (kHz)"
623 self.xlabel = "Frequency (kHz)"
617 elif self.xaxis == "time":
624 elif self.xaxis == "time":
618 x = self.data.xrange[1]
625 x = self.data.xrange[1]
619 self.xlabel = "Time (ms)"
626 self.xlabel = "Time (ms)"
620 else:
627 else:
621 x = self.data.xrange[2]
628 x = self.data.xrange[2]
622 self.xlabel = "Velocity (m/s)"
629 self.xlabel = "Velocity (m/s)"
623
630
624 self.titles = []
631 self.titles = []
625
632
626 y = self.data.heights
633 y = self.data.heights
627 self.y = y
634 self.y = y
628 spc = self.data['spc']
635 spc = self.data['spc']
629 cspc = self.data['cspc']
636 cspc = self.data['cspc']
630
637
631 for n in range(self.nrows):
638 for n in range(self.nrows):
632 noise = self.data['noise'][n][-1]
639 noise = self.data['noise'][n][-1]
633 pair = self.data.pairs[n]
640 pair = self.data.pairs[n]
634 ax = self.axes[4 * n]
641 ax = self.axes[4 * n]
635 ax3 = self.axes[4 * n + 3]
642 ax3 = self.axes[4 * n + 3]
636 if ax.firsttime:
643 if ax.firsttime:
637 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
644 self.xmax = self.xmax if self.xmax else numpy.nanmax(x)
638 self.xmin = self.xmin if self.xmin else -self.xmax
645 self.xmin = self.xmin if self.xmin else -self.xmax
639 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
646 self.zmin = self.zmin if self.zmin else numpy.nanmin(spc)
640 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
647 self.zmax = self.zmax if self.zmax else numpy.nanmax(spc)
641 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
648 ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T,
642 vmin=self.zmin,
649 vmin=self.zmin,
643 vmax=self.zmax,
650 vmax=self.zmax,
644 cmap=plt.get_cmap(self.colormap)
651 cmap=plt.get_cmap(self.colormap)
645 )
652 )
646 else:
653 else:
647 ax.plt.set_array(spc[pair[0]].T.ravel())
654 ax.plt.set_array(spc[pair[0]].T.ravel())
648 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
655 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
649
656
650 ax = self.axes[4 * n + 1]
657 ax = self.axes[4 * n + 1]
651 if ax.firsttime:
658 if ax.firsttime:
652 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
659 ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T,
653 vmin=self.zmin,
660 vmin=self.zmin,
654 vmax=self.zmax,
661 vmax=self.zmax,
655 cmap=plt.get_cmap(self.colormap)
662 cmap=plt.get_cmap(self.colormap)
656 )
663 )
657 else:
664 else:
658 ax.plt.set_array(spc[pair[1]].T.ravel())
665 ax.plt.set_array(spc[pair[1]].T.ravel())
659 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
666 self.titles.append('CH {}: {:3.2f}dB'.format(n, noise))
660
667
661 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
668 out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]])
662 coh = numpy.abs(out)
669 coh = numpy.abs(out)
663 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
670 phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi
664
671
665 ax = self.axes[4 * n + 2]
672 ax = self.axes[4 * n + 2]
666 if ax.firsttime:
673 if ax.firsttime:
667 ax.plt = ax.pcolormesh(x, y, coh.T,
674 ax.plt = ax.pcolormesh(x, y, coh.T,
668 vmin=0,
675 vmin=0,
669 vmax=1,
676 vmax=1,
670 cmap=plt.get_cmap(self.colormap_coh)
677 cmap=plt.get_cmap(self.colormap_coh)
671 )
678 )
672 else:
679 else:
673 ax.plt.set_array(coh.T.ravel())
680 ax.plt.set_array(coh.T.ravel())
674 self.titles.append(
681 self.titles.append(
675 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
682 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1]))
676
683
677 ax = self.axes[4 * n + 3]
684 ax = self.axes[4 * n + 3]
678 if ax.firsttime:
685 if ax.firsttime:
679 ax.plt = ax.pcolormesh(x, y, phase.T,
686 ax.plt = ax.pcolormesh(x, y, phase.T,
680 vmin=-180,
687 vmin=-180,
681 vmax=180,
688 vmax=180,
682 cmap=plt.get_cmap(self.colormap_phase)
689 cmap=plt.get_cmap(self.colormap_phase)
683 )
690 )
684 else:
691 else:
685 ax.plt.set_array(phase.T.ravel())
692 ax.plt.set_array(phase.T.ravel())
686 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
693 self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1]))
687
694
688 self.saveTime = self.max_time
695 self.saveTime = self.max_time
689
696
690
697
691 class PlotSpectraMeanData(PlotSpectraData):
698 class PlotSpectraMeanData(PlotSpectraData):
692 '''
699 '''
693 Plot for Spectra and Mean
700 Plot for Spectra and Mean
694 '''
701 '''
695 CODE = 'spc_mean'
702 CODE = 'spc_mean'
696 colormap = 'jro'
703 colormap = 'jro'
697
704
698
705
699 class PlotRTIData(PlotData):
706 class PlotRTIData(PlotData):
700 '''
707 '''
701 Plot for RTI data
708 Plot for RTI data
702 '''
709 '''
703
710
704 CODE = 'rti'
711 CODE = 'rti'
705 colormap = 'jro'
712 colormap = 'jro'
706
713
707 def setup(self):
714 def setup(self):
708 self.xaxis = 'time'
715 self.xaxis = 'time'
709 self.ncols = 1
716 self.ncols = 1
710 self.nrows = len(self.data.channels)
717 self.nrows = len(self.data.channels)
711 self.nplots = len(self.data.channels)
718 self.nplots = len(self.data.channels)
712 self.ylabel = 'Range [km]'
719 self.ylabel = 'Range [km]'
713 self.cb_label = 'dB'
720 self.cb_label = 'dB'
714 self.titles = ['{} Channel {}'.format(
721 self.titles = ['{} Channel {}'.format(
715 self.CODE.upper(), x) for x in range(self.nrows)]
722 self.CODE.upper(), x) for x in range(self.nrows)]
716
723
717 def plot(self):
724 def plot(self):
718 self.x = self.times
725 self.x = self.times
719 self.y = self.data.heights
726 self.y = self.data.heights
720 self.z = self.data[self.CODE]
727 self.z = self.data[self.CODE]
721 self.z = numpy.ma.masked_invalid(self.z)
728 self.z = numpy.ma.masked_invalid(self.z)
722
729
723 if self.decimation is None:
730 if self.decimation is None:
724 x, y, z = self.fill_gaps(self.x, self.y, self.z)
731 x, y, z = self.fill_gaps(self.x, self.y, self.z)
725 else:
732 else:
726 x, y, z = self.fill_gaps(*self.decimate())
733 x, y, z = self.fill_gaps(*self.decimate())
727
734
728 for n, ax in enumerate(self.axes):
735 for n, ax in enumerate(self.axes):
729 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
736 self.zmin = self.zmin if self.zmin else numpy.min(self.z)
730 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
737 self.zmax = self.zmax if self.zmax else numpy.max(self.z)
731 if ax.firsttime:
738 if ax.firsttime:
732 ax.plt = ax.pcolormesh(x, y, z[n].T,
739 ax.plt = ax.pcolormesh(x, y, z[n].T,
733 vmin=self.zmin,
740 vmin=self.zmin,
734 vmax=self.zmax,
741 vmax=self.zmax,
735 cmap=plt.get_cmap(self.colormap)
742 cmap=plt.get_cmap(self.colormap)
736 )
743 )
737 if self.showprofile:
744 if self.showprofile:
738 ax.plot_profile = self.pf_axes[n].plot(
745 ax.plot_profile = self.pf_axes[n].plot(
739 self.data['rti'][n][-1], self.y)[0]
746 self.data['rti'][n][-1], self.y)[0]
740 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
747 ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y,
741 color="k", linestyle="dashed", lw=1)[0]
748 color="k", linestyle="dashed", lw=1)[0]
742 else:
749 else:
743 ax.collections.remove(ax.collections[0])
750 ax.collections.remove(ax.collections[0])
744 ax.plt = ax.pcolormesh(x, y, z[n].T,
751 ax.plt = ax.pcolormesh(x, y, z[n].T,
745 vmin=self.zmin,
752 vmin=self.zmin,
746 vmax=self.zmax,
753 vmax=self.zmax,
747 cmap=plt.get_cmap(self.colormap)
754 cmap=plt.get_cmap(self.colormap)
748 )
755 )
749 if self.showprofile:
756 if self.showprofile:
750 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
757 ax.plot_profile.set_data(self.data['rti'][n][-1], self.y)
751 ax.plot_noise.set_data(numpy.repeat(
758 ax.plot_noise.set_data(numpy.repeat(
752 self.data['noise'][n][-1], len(self.y)), self.y)
759 self.data['noise'][n][-1], len(self.y)), self.y)
753
760
754 self.saveTime = self.min_time
761 self.saveTime = self.min_time
755
762
756
763
757 class PlotCOHData(PlotRTIData):
764 class PlotCOHData(PlotRTIData):
758 '''
765 '''
759 Plot for Coherence data
766 Plot for Coherence data
760 '''
767 '''
761
768
762 CODE = 'coh'
769 CODE = 'coh'
763
770
764 def setup(self):
771 def setup(self):
765 self.xaxis = 'time'
772 self.xaxis = 'time'
766 self.ncols = 1
773 self.ncols = 1
767 self.nrows = len(self.data.pairs)
774 self.nrows = len(self.data.pairs)
768 self.nplots = len(self.data.pairs)
775 self.nplots = len(self.data.pairs)
769 self.ylabel = 'Range [km]'
776 self.ylabel = 'Range [km]'
770 if self.CODE == 'coh':
777 if self.CODE == 'coh':
771 self.cb_label = ''
778 self.cb_label = ''
772 self.titles = [
779 self.titles = [
773 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
780 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
774 else:
781 else:
775 self.cb_label = 'Degrees'
782 self.cb_label = 'Degrees'
776 self.titles = [
783 self.titles = [
777 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
784 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs]
778
785
779
786
780 class PlotPHASEData(PlotCOHData):
787 class PlotPHASEData(PlotCOHData):
781 '''
788 '''
782 Plot for Phase map data
789 Plot for Phase map data
783 '''
790 '''
784
791
785 CODE = 'phase'
792 CODE = 'phase'
786 colormap = 'seismic'
793 colormap = 'seismic'
787
794
788
795
789 class PlotNoiseData(PlotData):
796 class PlotNoiseData(PlotData):
790 '''
797 '''
791 Plot for noise
798 Plot for noise
792 '''
799 '''
793
800
794 CODE = 'noise'
801 CODE = 'noise'
795
802
796 def setup(self):
803 def setup(self):
797 self.xaxis = 'time'
804 self.xaxis = 'time'
798 self.ncols = 1
805 self.ncols = 1
799 self.nrows = 1
806 self.nrows = 1
800 self.nplots = 1
807 self.nplots = 1
801 self.ylabel = 'Intensity [dB]'
808 self.ylabel = 'Intensity [dB]'
802 self.titles = ['Noise']
809 self.titles = ['Noise']
803 self.colorbar = False
810 self.colorbar = False
804
811
805 def plot(self):
812 def plot(self):
806
813
807 x = self.times
814 x = self.times
808 xmin = self.min_time
815 xmin = self.min_time
809 xmax = xmin + self.xrange * 60 * 60
816 xmax = xmin + self.xrange * 60 * 60
810 Y = self.data[self.CODE]
817 Y = self.data[self.CODE]
811
818
812 if self.axes[0].firsttime:
819 if self.axes[0].firsttime:
813 for ch in self.data.channels:
820 for ch in self.data.channels:
814 y = Y[ch]
821 y = Y[ch]
815 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
822 self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch))
816 plt.legend()
823 plt.legend()
817 else:
824 else:
818 for ch in self.data.channels:
825 for ch in self.data.channels:
819 y = Y[ch]
826 y = Y[ch]
820 self.axes[0].lines[ch].set_data(x, y)
827 self.axes[0].lines[ch].set_data(x, y)
821
828
822 self.ymin = numpy.nanmin(Y) - 5
829 self.ymin = numpy.nanmin(Y) - 5
823 self.ymax = numpy.nanmax(Y) + 5
830 self.ymax = numpy.nanmax(Y) + 5
824 self.saveTime = self.min_time
831 self.saveTime = self.min_time
825
832
826
833
827 class PlotSNRData(PlotRTIData):
834 class PlotSNRData(PlotRTIData):
828 '''
835 '''
829 Plot for SNR Data
836 Plot for SNR Data
830 '''
837 '''
831
838
832 CODE = 'snr'
839 CODE = 'snr'
833 colormap = 'jet'
840 colormap = 'jet'
834
841
835
842
836 class PlotDOPData(PlotRTIData):
843 class PlotDOPData(PlotRTIData):
837 '''
844 '''
838 Plot for DOPPLER Data
845 Plot for DOPPLER Data
839 '''
846 '''
840
847
841 CODE = 'dop'
848 CODE = 'dop'
842 colormap = 'jet'
849 colormap = 'jet'
843
850
844
851
845 class PlotSkyMapData(PlotData):
852 class PlotSkyMapData(PlotData):
846 '''
853 '''
847 Plot for meteors detection data
854 Plot for meteors detection data
848 '''
855 '''
849
856
850 CODE = 'param'
857 CODE = 'param'
851
858
852 def setup(self):
859 def setup(self):
853
860
854 self.ncols = 1
861 self.ncols = 1
855 self.nrows = 1
862 self.nrows = 1
856 self.width = 7.2
863 self.width = 7.2
857 self.height = 7.2
864 self.height = 7.2
858 self.nplots = 1
865 self.nplots = 1
859 self.xlabel = 'Zonal Zenith Angle (deg)'
866 self.xlabel = 'Zonal Zenith Angle (deg)'
860 self.ylabel = 'Meridional Zenith Angle (deg)'
867 self.ylabel = 'Meridional Zenith Angle (deg)'
861 self.polar = True
868 self.polar = True
862 self.ymin = -180
869 self.ymin = -180
863 self.ymax = 180
870 self.ymax = 180
864 self.colorbar = False
871 self.colorbar = False
865
872
866 def plot(self):
873 def plot(self):
867
874
868 arrayParameters = numpy.concatenate(self.data['param'])
875 arrayParameters = numpy.concatenate(self.data['param'])
869 error = arrayParameters[:, -1]
876 error = arrayParameters[:, -1]
870 indValid = numpy.where(error == 0)[0]
877 indValid = numpy.where(error == 0)[0]
871 finalMeteor = arrayParameters[indValid, :]
878 finalMeteor = arrayParameters[indValid, :]
872 finalAzimuth = finalMeteor[:, 3]
879 finalAzimuth = finalMeteor[:, 3]
873 finalZenith = finalMeteor[:, 4]
880 finalZenith = finalMeteor[:, 4]
874
881
875 x = finalAzimuth * numpy.pi / 180
882 x = finalAzimuth * numpy.pi / 180
876 y = finalZenith
883 y = finalZenith
877
884
878 ax = self.axes[0]
885 ax = self.axes[0]
879
886
880 if ax.firsttime:
887 if ax.firsttime:
881 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
888 ax.plot = ax.plot(x, y, 'bo', markersize=5)[0]
882 else:
889 else:
883 ax.plot.set_data(x, y)
890 ax.plot.set_data(x, y)
884
891
885 dt1 = self.getDateTime(self.min_time).strftime('%y/%m/%d %H:%M:%S')
892 dt1 = self.getDateTime(self.min_time).strftime('%y/%m/%d %H:%M:%S')
886 dt2 = self.getDateTime(self.max_time).strftime('%y/%m/%d %H:%M:%S')
893 dt2 = self.getDateTime(self.max_time).strftime('%y/%m/%d %H:%M:%S')
887 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
894 title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1,
888 dt2,
895 dt2,
889 len(x))
896 len(x))
890 self.titles[0] = title
897 self.titles[0] = title
891 self.saveTime = self.max_time
898 self.saveTime = self.max_time
892
899
893
900
894 class PlotParamData(PlotRTIData):
901 class PlotParamData(PlotRTIData):
895 '''
902 '''
896 Plot for data_param object
903 Plot for data_param object
897 '''
904 '''
898
905
899 CODE = 'param'
906 CODE = 'param'
900 colormap = 'seismic'
907 colormap = 'seismic'
901
908
902 def setup(self):
909 def setup(self):
903 self.xaxis = 'time'
910 self.xaxis = 'time'
904 self.ncols = 1
911 self.ncols = 1
905 self.nrows = self.data.shape(self.CODE)[0]
912 self.nrows = self.data.shape(self.CODE)[0]
906 self.nplots = self.nrows
913 self.nplots = self.nrows
907 if self.showSNR:
914 if self.showSNR:
908 self.nrows += 1
915 self.nrows += 1
909 self.nplots += 1
916 self.nplots += 1
910
917
911 self.ylabel = 'Height [km]'
918 self.ylabel = 'Height [km]'
912 if not self.titles:
919 if not self.titles:
913 self.titles = self.data.parameters \
920 self.titles = self.data.parameters \
914 if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)]
921 if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)]
915 if self.showSNR:
922 if self.showSNR:
916 self.titles.append('SNR')
923 self.titles.append('SNR')
917
924
918 def plot(self):
925 def plot(self):
919 self.data.normalize_heights()
926 self.data.normalize_heights()
920 self.x = self.times
927 self.x = self.times
921 self.y = self.data.heights
928 self.y = self.data.heights
922 if self.showSNR:
929 if self.showSNR:
923 self.z = numpy.concatenate(
930 self.z = numpy.concatenate(
924 (self.data[self.CODE], self.data['snr'])
931 (self.data[self.CODE], self.data['snr'])
925 )
932 )
926 else:
933 else:
927 self.z = self.data[self.CODE]
934 self.z = self.data[self.CODE]
928
935
929 self.z = numpy.ma.masked_invalid(self.z)
936 self.z = numpy.ma.masked_invalid(self.z)
930
937
931 if self.decimation is None:
938 if self.decimation is None:
932 x, y, z = self.fill_gaps(self.x, self.y, self.z)
939 x, y, z = self.fill_gaps(self.x, self.y, self.z)
933 else:
940 else:
934 x, y, z = self.fill_gaps(*self.decimate())
941 x, y, z = self.fill_gaps(*self.decimate())
935
942
936 for n, ax in enumerate(self.axes):
943 for n, ax in enumerate(self.axes):
937
944
938 self.zmax = self.zmax if self.zmax is not None else numpy.max(
945 self.zmax = self.zmax if self.zmax is not None else numpy.max(
939 self.z[n])
946 self.z[n])
940 self.zmin = self.zmin if self.zmin is not None else numpy.min(
947 self.zmin = self.zmin if self.zmin is not None else numpy.min(
941 self.z[n])
948 self.z[n])
942
949
943 if ax.firsttime:
950 if ax.firsttime:
944 if self.zlimits is not None:
951 if self.zlimits is not None:
945 self.zmin, self.zmax = self.zlimits[n]
952 self.zmin, self.zmax = self.zlimits[n]
946
953
947 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
954 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
948 vmin=self.zmin,
955 vmin=self.zmin,
949 vmax=self.zmax,
956 vmax=self.zmax,
950 cmap=self.cmaps[n]
957 cmap=self.cmaps[n]
951 )
958 )
952 else:
959 else:
953 if self.zlimits is not None:
960 if self.zlimits is not None:
954 self.zmin, self.zmax = self.zlimits[n]
961 self.zmin, self.zmax = self.zlimits[n]
955 ax.collections.remove(ax.collections[0])
962 ax.collections.remove(ax.collections[0])
956 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
963 ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n],
957 vmin=self.zmin,
964 vmin=self.zmin,
958 vmax=self.zmax,
965 vmax=self.zmax,
959 cmap=self.cmaps[n]
966 cmap=self.cmaps[n]
960 )
967 )
961
968
962 self.saveTime = self.min_time
969 self.saveTime = self.min_time
963
970
964
971
965 class PlotOutputData(PlotParamData):
972 class PlotOutputData(PlotParamData):
966 '''
973 '''
967 Plot data_output object
974 Plot data_output object
968 '''
975 '''
969
976
970 CODE = 'output'
977 CODE = 'output'
971 colormap = 'seismic'
978 colormap = 'seismic'
@@ -1,1826 +1,1826
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 import schainpy.admin
23 from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader
24 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
25 from schainpy.model.data.jroheaderIO import get_dtype_index, get_numpy_dtype, get_procflag_dtype, get_dtype_width
25 from schainpy.utils import log
26 from schainpy.utils import log
26 import schainpy.admin
27 import schainpy.admin
27
28
28 LOCALTIME = True
29 LOCALTIME = True
29
30
30
31
31 def isNumber(cad):
32 def isNumber(cad):
32 """
33 """
33 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
34 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
34
35
35 Excepciones:
36 Excepciones:
36 Si un determinado string no puede ser convertido a numero
37 Si un determinado string no puede ser convertido a numero
37 Input:
38 Input:
38 str, string al cual se le analiza para determinar si convertible a un numero o no
39 str, string al cual se le analiza para determinar si convertible a un numero o no
39
40
40 Return:
41 Return:
41 True : si el string es uno numerico
42 True : si el string es uno numerico
42 False : no es un string numerico
43 False : no es un string numerico
43 """
44 """
44 try:
45 try:
45 float(cad)
46 float(cad)
46 return True
47 return True
47 except:
48 except:
48 return False
49 return False
49
50
50
51
51 def isFileInEpoch(filename, startUTSeconds, endUTSeconds):
52 def isFileInEpoch(filename, startUTSeconds, endUTSeconds):
52 """
53 """
53 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
54 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
54
55
55 Inputs:
56 Inputs:
56 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
57 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
57
58
58 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
59 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
59 segundos contados desde 01/01/1970.
60 segundos contados desde 01/01/1970.
60 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
61 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
61 segundos contados desde 01/01/1970.
62 segundos contados desde 01/01/1970.
62
63
63 Return:
64 Return:
64 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
65 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
65 fecha especificado, de lo contrario retorna False.
66 fecha especificado, de lo contrario retorna False.
66
67
67 Excepciones:
68 Excepciones:
68 Si el archivo no existe o no puede ser abierto
69 Si el archivo no existe o no puede ser abierto
69 Si la cabecera no puede ser leida.
70 Si la cabecera no puede ser leida.
70
71
71 """
72 """
72 basicHeaderObj = BasicHeader(LOCALTIME)
73 basicHeaderObj = BasicHeader(LOCALTIME)
73
74
74 try:
75 try:
75 fp = open(filename, 'rb')
76 fp = open(filename, 'rb')
76 except IOError:
77 except IOError:
77 print "The file %s can't be opened" % (filename)
78 print "The file %s can't be opened" % (filename)
78 return 0
79 return 0
79
80
80 sts = basicHeaderObj.read(fp)
81 sts = basicHeaderObj.read(fp)
81 fp.close()
82 fp.close()
82
83
83 if not(sts):
84 if not(sts):
84 print "Skipping the file %s because it has not a valid header" % (filename)
85 print "Skipping the file %s because it has not a valid header" % (filename)
85 return 0
86 return 0
86
87
87 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
88 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
88 return 0
89 return 0
89
90
90 return 1
91 return 1
91
92
92
93
93 def isTimeInRange(thisTime, startTime, endTime):
94 def isTimeInRange(thisTime, startTime, endTime):
94 if endTime >= startTime:
95 if endTime >= startTime:
95 if (thisTime < startTime) or (thisTime > endTime):
96 if (thisTime < startTime) or (thisTime > endTime):
96 return 0
97 return 0
97 return 1
98 return 1
98 else:
99 else:
99 if (thisTime < startTime) and (thisTime > endTime):
100 if (thisTime < startTime) and (thisTime > endTime):
100 return 0
101 return 0
101 return 1
102 return 1
102
103
103
104
104 def isFileInTimeRange(filename, startDate, endDate, startTime, endTime):
105 def isFileInTimeRange(filename, startDate, endDate, startTime, endTime):
105 """
106 """
106 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
107 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
107
108
108 Inputs:
109 Inputs:
109 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
110 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
110
111
111 startDate : fecha inicial del rango seleccionado en formato datetime.date
112 startDate : fecha inicial del rango seleccionado en formato datetime.date
112
113
113 endDate : fecha final del rango seleccionado en formato datetime.date
114 endDate : fecha final del rango seleccionado en formato datetime.date
114
115
115 startTime : tiempo inicial del rango seleccionado en formato datetime.time
116 startTime : tiempo inicial del rango seleccionado en formato datetime.time
116
117
117 endTime : tiempo final del rango seleccionado en formato datetime.time
118 endTime : tiempo final del rango seleccionado en formato datetime.time
118
119
119 Return:
120 Return:
120 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
121 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
121 fecha especificado, de lo contrario retorna False.
122 fecha especificado, de lo contrario retorna False.
122
123
123 Excepciones:
124 Excepciones:
124 Si el archivo no existe o no puede ser abierto
125 Si el archivo no existe o no puede ser abierto
125 Si la cabecera no puede ser leida.
126 Si la cabecera no puede ser leida.
126
127
127 """
128 """
128
129
129 try:
130 try:
130 fp = open(filename, 'rb')
131 fp = open(filename, 'rb')
131 except IOError:
132 except IOError:
132 print "The file %s can't be opened" % (filename)
133 print "The file %s can't be opened" % (filename)
133 return None
134 return None
134
135
135 firstBasicHeaderObj = BasicHeader(LOCALTIME)
136 firstBasicHeaderObj = BasicHeader(LOCALTIME)
136 systemHeaderObj = SystemHeader()
137 systemHeaderObj = SystemHeader()
137 radarControllerHeaderObj = RadarControllerHeader()
138 radarControllerHeaderObj = RadarControllerHeader()
138 processingHeaderObj = ProcessingHeader()
139 processingHeaderObj = ProcessingHeader()
139
140
140 lastBasicHeaderObj = BasicHeader(LOCALTIME)
141 lastBasicHeaderObj = BasicHeader(LOCALTIME)
141
142
142 sts = firstBasicHeaderObj.read(fp)
143 sts = firstBasicHeaderObj.read(fp)
143
144
144 if not(sts):
145 if not(sts):
145 print "[Reading] Skipping the file %s because it has not a valid header" % (filename)
146 print "[Reading] Skipping the file %s because it has not a valid header" % (filename)
146 return None
147 return None
147
148
148 if not systemHeaderObj.read(fp):
149 if not systemHeaderObj.read(fp):
149 return None
150 return None
150
151
151 if not radarControllerHeaderObj.read(fp):
152 if not radarControllerHeaderObj.read(fp):
152 return None
153 return None
153
154
154 if not processingHeaderObj.read(fp):
155 if not processingHeaderObj.read(fp):
155 return None
156 return None
156
157
157 filesize = os.path.getsize(filename)
158 filesize = os.path.getsize(filename)
158
159
159 offset = processingHeaderObj.blockSize + 24 # header size
160 offset = processingHeaderObj.blockSize + 24 # header size
160
161
161 if filesize <= offset:
162 if filesize <= offset:
162 print "[Reading] %s: This file has not enough data" % filename
163 print "[Reading] %s: This file has not enough data" % filename
163 return None
164 return None
164
165
165 fp.seek(-offset, 2)
166 fp.seek(-offset, 2)
166
167
167 sts = lastBasicHeaderObj.read(fp)
168 sts = lastBasicHeaderObj.read(fp)
168
169
169 fp.close()
170 fp.close()
170
171
171 thisDatetime = lastBasicHeaderObj.datatime
172 thisDatetime = lastBasicHeaderObj.datatime
172 thisTime_last_block = thisDatetime.time()
173 thisTime_last_block = thisDatetime.time()
173
174
174 thisDatetime = firstBasicHeaderObj.datatime
175 thisDatetime = firstBasicHeaderObj.datatime
175 thisDate = thisDatetime.date()
176 thisDate = thisDatetime.date()
176 thisTime_first_block = thisDatetime.time()
177 thisTime_first_block = thisDatetime.time()
177
178
178 # General case
179 # General case
179 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
180 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
180 #-----------o----------------------------o-----------
181 #-----------o----------------------------o-----------
181 # startTime endTime
182 # startTime endTime
182
183
183 if endTime >= startTime:
184 if endTime >= startTime:
184 if (thisTime_last_block < startTime) or (thisTime_first_block > endTime):
185 if (thisTime_last_block < startTime) or (thisTime_first_block > endTime):
185 return None
186 return None
186
187
187 return thisDatetime
188 return thisDatetime
188
189
189 # If endTime < startTime then endTime belongs to the next day
190 # If endTime < startTime then endTime belongs to the next day
190
191
191 #<<<<<<<<<<<o o>>>>>>>>>>>
192 #<<<<<<<<<<<o o>>>>>>>>>>>
192 #-----------o----------------------------o-----------
193 #-----------o----------------------------o-----------
193 # endTime startTime
194 # endTime startTime
194
195
195 if (thisDate == startDate) and (thisTime_last_block < startTime):
196 if (thisDate == startDate) and (thisTime_last_block < startTime):
196 return None
197 return None
197
198
198 if (thisDate == endDate) and (thisTime_first_block > endTime):
199 if (thisDate == endDate) and (thisTime_first_block > endTime):
199 return None
200 return None
200
201
201 if (thisTime_last_block < startTime) and (thisTime_first_block > endTime):
202 if (thisTime_last_block < startTime) and (thisTime_first_block > endTime):
202 return None
203 return None
203
204
204 return thisDatetime
205 return thisDatetime
205
206
206
207
207 def isFolderInDateRange(folder, startDate=None, endDate=None):
208 def isFolderInDateRange(folder, startDate=None, endDate=None):
208 """
209 """
209 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
210 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
210
211
211 Inputs:
212 Inputs:
212 folder : nombre completo del directorio.
213 folder : nombre completo del directorio.
213 Su formato deberia ser "/path_root/?YYYYDDD"
214 Su formato deberia ser "/path_root/?YYYYDDD"
214
215
215 siendo:
216 siendo:
216 YYYY : Anio (ejemplo 2015)
217 YYYY : Anio (ejemplo 2015)
217 DDD : Dia del anio (ejemplo 305)
218 DDD : Dia del anio (ejemplo 305)
218
219
219 startDate : fecha inicial del rango seleccionado en formato datetime.date
220 startDate : fecha inicial del rango seleccionado en formato datetime.date
220
221
221 endDate : fecha final del rango seleccionado en formato datetime.date
222 endDate : fecha final del rango seleccionado en formato datetime.date
222
223
223 Return:
224 Return:
224 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
225 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
225 fecha especificado, de lo contrario retorna False.
226 fecha especificado, de lo contrario retorna False.
226 Excepciones:
227 Excepciones:
227 Si el directorio no tiene el formato adecuado
228 Si el directorio no tiene el formato adecuado
228 """
229 """
229
230
230 basename = os.path.basename(folder)
231 basename = os.path.basename(folder)
231
232
232 if not isRadarFolder(basename):
233 if not isRadarFolder(basename):
233 print "The folder %s has not the rigth format" % folder
234 print "The folder %s has not the rigth format" % folder
234 return 0
235 return 0
235
236
236 if startDate and endDate:
237 if startDate and endDate:
237 thisDate = getDateFromRadarFolder(basename)
238 thisDate = getDateFromRadarFolder(basename)
238
239
239 if thisDate < startDate:
240 if thisDate < startDate:
240 return 0
241 return 0
241
242
242 if thisDate > endDate:
243 if thisDate > endDate:
243 return 0
244 return 0
244
245
245 return 1
246 return 1
246
247
247
248
248 def isFileInDateRange(filename, startDate=None, endDate=None):
249 def isFileInDateRange(filename, startDate=None, endDate=None):
249 """
250 """
250 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
251 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
251
252
252 Inputs:
253 Inputs:
253 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
254 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
254
255
255 Su formato deberia ser "?YYYYDDDsss"
256 Su formato deberia ser "?YYYYDDDsss"
256
257
257 siendo:
258 siendo:
258 YYYY : Anio (ejemplo 2015)
259 YYYY : Anio (ejemplo 2015)
259 DDD : Dia del anio (ejemplo 305)
260 DDD : Dia del anio (ejemplo 305)
260 sss : set
261 sss : set
261
262
262 startDate : fecha inicial del rango seleccionado en formato datetime.date
263 startDate : fecha inicial del rango seleccionado en formato datetime.date
263
264
264 endDate : fecha final del rango seleccionado en formato datetime.date
265 endDate : fecha final del rango seleccionado en formato datetime.date
265
266
266 Return:
267 Return:
267 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
268 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
268 fecha especificado, de lo contrario retorna False.
269 fecha especificado, de lo contrario retorna False.
269 Excepciones:
270 Excepciones:
270 Si el archivo no tiene el formato adecuado
271 Si el archivo no tiene el formato adecuado
271 """
272 """
272
273
273 basename = os.path.basename(filename)
274 basename = os.path.basename(filename)
274
275
275 if not isRadarFile(basename):
276 if not isRadarFile(basename):
276 print "The filename %s has not the rigth format" % filename
277 print "The filename %s has not the rigth format" % filename
277 return 0
278 return 0
278
279
279 if startDate and endDate:
280 if startDate and endDate:
280 thisDate = getDateFromRadarFile(basename)
281 thisDate = getDateFromRadarFile(basename)
281
282
282 if thisDate < startDate:
283 if thisDate < startDate:
283 return 0
284 return 0
284
285
285 if thisDate > endDate:
286 if thisDate > endDate:
286 return 0
287 return 0
287
288
288 return 1
289 return 1
289
290
290
291
291 def getFileFromSet(path, ext, set):
292 def getFileFromSet(path, ext, set):
292 validFilelist = []
293 validFilelist = []
293 fileList = os.listdir(path)
294 fileList = os.listdir(path)
294
295
295 # 0 1234 567 89A BCDE
296 # 0 1234 567 89A BCDE
296 # H YYYY DDD SSS .ext
297 # H YYYY DDD SSS .ext
297
298
298 for thisFile in fileList:
299 for thisFile in fileList:
299 try:
300 try:
300 year = int(thisFile[1:5])
301 year = int(thisFile[1:5])
301 doy = int(thisFile[5:8])
302 doy = int(thisFile[5:8])
302 except:
303 except:
303 continue
304 continue
304
305
305 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
306 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
306 continue
307 continue
307
308
308 validFilelist.append(thisFile)
309 validFilelist.append(thisFile)
309
310
310 myfile = fnmatch.filter(
311 myfile = fnmatch.filter(
311 validFilelist, '*%4.4d%3.3d%3.3d*' % (year, doy, set))
312 validFilelist, '*%4.4d%3.3d%3.3d*' % (year, doy, set))
312
313
313 if len(myfile) != 0:
314 if len(myfile) != 0:
314 return myfile[0]
315 return myfile[0]
315 else:
316 else:
316 filename = '*%4.4d%3.3d%3.3d%s' % (year, doy, set, ext.lower())
317 filename = '*%4.4d%3.3d%3.3d%s' % (year, doy, set, ext.lower())
317 print 'the filename %s does not exist' % filename
318 print 'the filename %s does not exist' % filename
318 print '...going to the last file: '
319 print '...going to the last file: '
319
320
320 if validFilelist:
321 if validFilelist:
321 validFilelist = sorted(validFilelist, key=str.lower)
322 validFilelist = sorted(validFilelist, key=str.lower)
322 return validFilelist[-1]
323 return validFilelist[-1]
323
324
324 return None
325 return None
325
326
326
327
327 def getlastFileFromPath(path, ext):
328 def getlastFileFromPath(path, ext):
328 """
329 """
329 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
330 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.
331 al final de la depuracion devuelve el ultimo file de la lista que quedo.
331
332
332 Input:
333 Input:
333 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
334 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
334 ext : extension de los files contenidos en una carpeta
335 ext : extension de los files contenidos en una carpeta
335
336
336 Return:
337 Return:
337 El ultimo file de una determinada carpeta, no se considera el path.
338 El ultimo file de una determinada carpeta, no se considera el path.
338 """
339 """
339 validFilelist = []
340 validFilelist = []
340 fileList = os.listdir(path)
341 fileList = os.listdir(path)
341
342
342 # 0 1234 567 89A BCDE
343 # 0 1234 567 89A BCDE
343 # H YYYY DDD SSS .ext
344 # H YYYY DDD SSS .ext
344
345
345 for thisFile in fileList:
346 for thisFile in fileList:
346
347
347 year = thisFile[1:5]
348 year = thisFile[1:5]
348 if not isNumber(year):
349 if not isNumber(year):
349 continue
350 continue
350
351
351 doy = thisFile[5:8]
352 doy = thisFile[5:8]
352 if not isNumber(doy):
353 if not isNumber(doy):
353 continue
354 continue
354
355
355 year = int(year)
356 year = int(year)
356 doy = int(doy)
357 doy = int(doy)
357
358
358 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
359 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
359 continue
360 continue
360
361
361 validFilelist.append(thisFile)
362 validFilelist.append(thisFile)
362
363
363 if validFilelist:
364 if validFilelist:
364 validFilelist = sorted(validFilelist, key=str.lower)
365 validFilelist = sorted(validFilelist, key=str.lower)
365 return validFilelist[-1]
366 return validFilelist[-1]
366
367
367 return None
368 return None
368
369
369
370
370 def checkForRealPath(path, foldercounter, year, doy, set, ext):
371 def checkForRealPath(path, foldercounter, year, doy, set, ext):
371 """
372 """
372 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
373 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
374 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
374 el path exacto de un determinado file.
375 el path exacto de un determinado file.
375
376
376 Example :
377 Example :
377 nombre correcto del file es .../.../D2009307/P2009307367.ext
378 nombre correcto del file es .../.../D2009307/P2009307367.ext
378
379
379 Entonces la funcion prueba con las siguientes combinaciones
380 Entonces la funcion prueba con las siguientes combinaciones
380 .../.../y2009307367.ext
381 .../.../y2009307367.ext
381 .../.../Y2009307367.ext
382 .../.../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 .../.../X2009307/Y2009307367.ext
386 siendo para este caso, la ultima combinacion de letras, identica al file buscado
387 siendo para este caso, la ultima combinacion de letras, identica al file buscado
387
388
388 Return:
389 Return:
389 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
390 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
391 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
391 para el filename
392 para el filename
392 """
393 """
393 fullfilename = None
394 fullfilename = None
394 find_flag = False
395 find_flag = False
395 filename = None
396 filename = None
396
397
397 prefixDirList = [None, 'd', 'D']
398 prefixDirList = [None, 'd', 'D']
398 if ext.lower() == ".r": # voltage
399 if ext.lower() == ".r": # voltage
399 prefixFileList = ['d', 'D']
400 prefixFileList = ['d', 'D']
400 elif ext.lower() == ".pdata": # spectra
401 elif ext.lower() == ".pdata": # spectra
401 prefixFileList = ['p', 'P']
402 prefixFileList = ['p', 'P']
402 else:
403 else:
403 return None, filename
404 return None, filename
404
405
405 # barrido por las combinaciones posibles
406 # barrido por las combinaciones posibles
406 for prefixDir in prefixDirList:
407 for prefixDir in prefixDirList:
407 thispath = path
408 thispath = path
408 if prefixDir != None:
409 if prefixDir != None:
409 # formo el nombre del directorio xYYYYDDD (x=d o x=D)
410 # formo el nombre del directorio xYYYYDDD (x=d o x=D)
410 if foldercounter == 0:
411 if foldercounter == 0:
411 thispath = os.path.join(path, "%s%04d%03d" %
412 thispath = os.path.join(path, "%s%04d%03d" %
412 (prefixDir, year, doy))
413 (prefixDir, year, doy))
413 else:
414 else:
414 thispath = os.path.join(path, "%s%04d%03d_%02d" % (
415 thispath = os.path.join(path, "%s%04d%03d_%02d" % (
415 prefixDir, year, doy, foldercounter))
416 prefixDir, year, doy, foldercounter))
416 for prefixFile in prefixFileList: # barrido por las dos combinaciones posibles de "D"
417 for prefixFile in prefixFileList: # barrido por las dos combinaciones posibles de "D"
417 # formo el nombre del file xYYYYDDDSSS.ext
418 # formo el nombre del file xYYYYDDDSSS.ext
418 filename = "%s%04d%03d%03d%s" % (prefixFile, year, doy, set, ext)
419 filename = "%s%04d%03d%03d%s" % (prefixFile, year, doy, set, ext)
419 fullfilename = os.path.join(
420 fullfilename = os.path.join(
420 thispath, filename) # formo el path completo
421 thispath, filename) # formo el path completo
421
422
422 if os.path.exists(fullfilename): # verifico que exista
423 if os.path.exists(fullfilename): # verifico que exista
423 find_flag = True
424 find_flag = True
424 break
425 break
425 if find_flag:
426 if find_flag:
426 break
427 break
427
428
428 if not(find_flag):
429 if not(find_flag):
429 return None, filename
430 return None, filename
430
431
431 return fullfilename, filename
432 return fullfilename, filename
432
433
433
434
434 def isRadarFolder(folder):
435 def isRadarFolder(folder):
435 try:
436 try:
436 year = int(folder[1:5])
437 year = int(folder[1:5])
437 doy = int(folder[5:8])
438 doy = int(folder[5:8])
438 except:
439 except:
439 return 0
440 return 0
440
441
441 return 1
442 return 1
442
443
443
444
444 def isRadarFile(file):
445 def isRadarFile(file):
445 try:
446 try:
446 year = int(file[1:5])
447 year = int(file[1:5])
447 doy = int(file[5:8])
448 doy = int(file[5:8])
448 set = int(file[8:11])
449 set = int(file[8:11])
449 except:
450 except:
450 return 0
451 return 0
451
452
452 return 1
453 return 1
453
454
454
455
455 def getDateFromRadarFile(file):
456 def getDateFromRadarFile(file):
456 try:
457 try:
457 year = int(file[1:5])
458 year = int(file[1:5])
458 doy = int(file[5:8])
459 doy = int(file[5:8])
459 set = int(file[8:11])
460 set = int(file[8:11])
460 except:
461 except:
461 return None
462 return None
462
463
463 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
464 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
464 return thisDate
465 return thisDate
465
466
466
467
467 def getDateFromRadarFolder(folder):
468 def getDateFromRadarFolder(folder):
468 try:
469 try:
469 year = int(folder[1:5])
470 year = int(folder[1:5])
470 doy = int(folder[5:8])
471 doy = int(folder[5:8])
471 except:
472 except:
472 return None
473 return None
473
474
474 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
475 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
475 return thisDate
476 return thisDate
476
477
477
478
478 class JRODataIO:
479 class JRODataIO:
479
480
480 c = 3E8
481 c = 3E8
481
482
482 isConfig = False
483 isConfig = False
483
484
484 basicHeaderObj = None
485 basicHeaderObj = None
485
486
486 systemHeaderObj = None
487 systemHeaderObj = None
487
488
488 radarControllerHeaderObj = None
489 radarControllerHeaderObj = None
489
490
490 processingHeaderObj = None
491 processingHeaderObj = None
491
492
492 dtype = None
493 dtype = None
493
494
494 pathList = []
495 pathList = []
495
496
496 filenameList = []
497 filenameList = []
497
498
498 filename = None
499 filename = None
499
500
500 ext = None
501 ext = None
501
502
502 flagIsNewFile = 1
503 flagIsNewFile = 1
503
504
504 flagDiscontinuousBlock = 0
505 flagDiscontinuousBlock = 0
505
506
506 flagIsNewBlock = 0
507 flagIsNewBlock = 0
507
508
508 fp = None
509 fp = None
509
510
510 firstHeaderSize = 0
511 firstHeaderSize = 0
511
512
512 basicHeaderSize = 24
513 basicHeaderSize = 24
513
514
514 versionFile = 1103
515 versionFile = 1103
515
516
516 fileSize = None
517 fileSize = None
517
518
518 # ippSeconds = None
519 # ippSeconds = None
519
520
520 fileSizeByHeader = None
521 fileSizeByHeader = None
521
522
522 fileIndex = None
523 fileIndex = None
523
524
524 profileIndex = None
525 profileIndex = None
525
526
526 blockIndex = None
527 blockIndex = None
527
528
528 nTotalBlocks = None
529 nTotalBlocks = None
529
530
530 maxTimeStep = 30
531 maxTimeStep = 30
531
532
532 lastUTTime = None
533 lastUTTime = None
533
534
534 datablock = None
535 datablock = None
535
536
536 dataOut = None
537 dataOut = None
537
538
538 blocksize = None
539 blocksize = None
539
540
540 getByBlock = False
541 getByBlock = False
541
542
542 def __init__(self):
543 def __init__(self):
543
544
544 raise NotImplementedError
545 raise NotImplementedError
545
546
546 def run(self):
547 def run(self):
547
548
548 raise NotImplementedError
549 raise NotImplementedError
549
550
550 def getDtypeWidth(self):
551 def getDtypeWidth(self):
551
552
552 dtype_index = get_dtype_index(self.dtype)
553 dtype_index = get_dtype_index(self.dtype)
553 dtype_width = get_dtype_width(dtype_index)
554 dtype_width = get_dtype_width(dtype_index)
554
555
555 return dtype_width
556 return dtype_width
556
557
557 def getAllowedArgs(self):
558 def getAllowedArgs(self):
558 if hasattr(self, '__attrs__'):
559 if hasattr(self, '__attrs__'):
559 return self.__attrs__
560 return self.__attrs__
560 else:
561 else:
561 return inspect.getargspec(self.run).args
562 return inspect.getargspec(self.run).args
562
563
563
564
564 class JRODataReader(JRODataIO):
565 class JRODataReader(JRODataIO):
565
566
566 online = 0
567 online = 0
567
568
568 realtime = 0
569 realtime = 0
569
570
570 nReadBlocks = 0
571 nReadBlocks = 0
571
572
572 delay = 10 # number of seconds waiting a new file
573 delay = 10 # number of seconds waiting a new file
573
574
574 nTries = 3 # quantity tries
575 nTries = 3 # quantity tries
575
576
576 nFiles = 3 # number of files for searching
577 nFiles = 3 # number of files for searching
577
578
578 path = None
579 path = None
579
580
580 foldercounter = 0
581 foldercounter = 0
581
582
582 flagNoMoreFiles = 0
583 flagNoMoreFiles = 0
583
584
584 datetimeList = []
585 datetimeList = []
585
586
586 __isFirstTimeOnline = 1
587 __isFirstTimeOnline = 1
587
588
588 __printInfo = True
589 __printInfo = True
589
590
590 profileIndex = None
591 profileIndex = None
591
592
592 nTxs = 1
593 nTxs = 1
593
594
594 txIndex = None
595 txIndex = None
595
596
596 # Added--------------------
597 # Added--------------------
597
598
598 selBlocksize = None
599 selBlocksize = None
599
600
600 selBlocktime = None
601 selBlocktime = None
601
602
602 def __init__(self):
603 def __init__(self):
603 """
604 """
604 This class is used to find data files
605 This class is used to find data files
605
606
606 Example:
607 Example:
607 reader = JRODataReader()
608 reader = JRODataReader()
608 fileList = reader.findDataFiles()
609 fileList = reader.findDataFiles()
609
610
610 """
611 """
611 pass
612 pass
612
613
613 def createObjByDefault(self):
614 def createObjByDefault(self):
614 """
615 """
615
616
616 """
617 """
617 raise NotImplementedError
618 raise NotImplementedError
618
619
619 def getBlockDimension(self):
620 def getBlockDimension(self):
620
621
621 raise NotImplementedError
622 raise NotImplementedError
622
623
623 def searchFilesOffLine(self,
624 def searchFilesOffLine(self,
624 path,
625 path,
625 startDate=None,
626 startDate=None,
626 endDate=None,
627 endDate=None,
627 startTime=datetime.time(0, 0, 0),
628 startTime=datetime.time(0, 0, 0),
628 endTime=datetime.time(23, 59, 59),
629 endTime=datetime.time(23, 59, 59),
629 set=None,
630 set=None,
630 expLabel='',
631 expLabel='',
631 ext='.r',
632 ext='.r',
632 cursor=None,
633 cursor=None,
633 skip=None,
634 skip=None,
634 walk=True):
635 walk=True):
635
636
636 self.filenameList = []
637 self.filenameList = []
637 self.datetimeList = []
638 self.datetimeList = []
638
639
639 pathList = []
640 pathList = []
640
641
641 dateList, pathList = self.findDatafiles(
642 dateList, pathList = self.findDatafiles(
642 path, startDate, endDate, expLabel, ext, walk, include_path=True)
643 path, startDate, endDate, expLabel, ext, walk, include_path=True)
643
644
644 if dateList == []:
645 if dateList == []:
645 return [], []
646 return [], []
646
647
647 if len(dateList) > 1:
648 if len(dateList) > 1:
648 print "[Reading] Data found for date range [%s - %s]: total days = %d" % (startDate, endDate, len(dateList))
649 print "[Reading] Data found for date range [%s - %s]: total days = %d" % (startDate, endDate, len(dateList))
649 else:
650 else:
650 print "[Reading] Data found for date range [%s - %s]: date = %s" % (startDate, endDate, dateList[0])
651 print "[Reading] Data found for date range [%s - %s]: date = %s" % (startDate, endDate, dateList[0])
651
652
652 filenameList = []
653 filenameList = []
653 datetimeList = []
654 datetimeList = []
654
655
655 for thisPath in pathList:
656 for thisPath in pathList:
656
657
657 fileList = glob.glob1(thisPath, "*%s" % ext)
658 fileList = glob.glob1(thisPath, "*%s" % ext)
658 fileList.sort()
659 fileList.sort()
659
660
660 for file in fileList:
661 for file in fileList:
661
662
662 filename = os.path.join(thisPath, file)
663 filename = os.path.join(thisPath, file)
663
664
664 if not isFileInDateRange(filename, startDate, endDate):
665 if not isFileInDateRange(filename, startDate, endDate):
665 continue
666 continue
666
667
667 thisDatetime = isFileInTimeRange(
668 thisDatetime = isFileInTimeRange(
668 filename, startDate, endDate, startTime, endTime)
669 filename, startDate, endDate, startTime, endTime)
669
670
670 if not(thisDatetime):
671 if not(thisDatetime):
671 continue
672 continue
672
673
673 filenameList.append(filename)
674 filenameList.append(filename)
674 datetimeList.append(thisDatetime)
675 datetimeList.append(thisDatetime)
675
676
676 if cursor is not None and skip is not None:
677 if cursor is not None and skip is not None:
677 filenameList = filenameList[cursor * skip:cursor * skip + skip]
678 filenameList = filenameList[cursor * skip:cursor * skip + skip]
678 datetimeList = datetimeList[cursor * skip:cursor * skip + skip]
679 datetimeList = datetimeList[cursor * skip:cursor * skip + skip]
679
680
680 if not(filenameList):
681 if not(filenameList):
681 print "[Reading] Time range selected invalid [%s - %s]: No *%s files in %s)" % (startTime, endTime, ext, path)
682 print "[Reading] Time range selected invalid [%s - %s]: No *%s files in %s)" % (startTime, endTime, ext, path)
682 return [], []
683 return [], []
683
684
684 print "[Reading] %d file(s) was(were) found in time range: %s - %s" % (len(filenameList), startTime, endTime)
685 print "[Reading] %d file(s) was(were) found in time range: %s - %s" % (len(filenameList), startTime, endTime)
685
686
686 # for i in range(len(filenameList)):
687 # for i in range(len(filenameList)):
687 # print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
688 # print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
688
689
689 self.filenameList = filenameList
690 self.filenameList = filenameList
690 self.datetimeList = datetimeList
691 self.datetimeList = datetimeList
691
692
692 return pathList, filenameList
693 return pathList, filenameList
693
694
694 def __searchFilesOnLine(self, path, expLabel="", ext=None, walk=True, set=None):
695 def __searchFilesOnLine(self, path, expLabel="", ext=None, walk=True, set=None):
695 """
696 """
696 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
697 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
697 devuelve el archivo encontrado ademas de otros datos.
698 devuelve el archivo encontrado ademas de otros datos.
698
699
699 Input:
700 Input:
700 path : carpeta donde estan contenidos los files que contiene data
701 path : carpeta donde estan contenidos los files que contiene data
701
702
702 expLabel : Nombre del subexperimento (subfolder)
703 expLabel : Nombre del subexperimento (subfolder)
703
704
704 ext : extension de los files
705 ext : extension de los files
705
706
706 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
707 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
707
708
708 Return:
709 Return:
709 directory : eL directorio donde esta el file encontrado
710 directory : eL directorio donde esta el file encontrado
710 filename : el ultimo file de una determinada carpeta
711 filename : el ultimo file de una determinada carpeta
711 year : el anho
712 year : el anho
712 doy : el numero de dia del anho
713 doy : el numero de dia del anho
713 set : el set del archivo
714 set : el set del archivo
714
715
715
716
716 """
717 """
717 if not os.path.isdir(path):
718 if not os.path.isdir(path):
718 return None, None, None, None, None, None
719 return None, None, None, None, None, None
719
720
720 dirList = []
721 dirList = []
721
722
722 if not walk:
723 if not walk:
723 fullpath = path
724 fullpath = path
724 foldercounter = 0
725 foldercounter = 0
725 else:
726 else:
726 # Filtra solo los directorios
727 # Filtra solo los directorios
727 for thisPath in os.listdir(path):
728 for thisPath in os.listdir(path):
728 if not os.path.isdir(os.path.join(path, thisPath)):
729 if not os.path.isdir(os.path.join(path, thisPath)):
729 continue
730 continue
730 if not isRadarFolder(thisPath):
731 if not isRadarFolder(thisPath):
731 continue
732 continue
732
733
733 dirList.append(thisPath)
734 dirList.append(thisPath)
734
735
735 if not(dirList):
736 if not(dirList):
736 return None, None, None, None, None, None
737 return None, None, None, None, None, None
737
738
738 dirList = sorted(dirList, key=str.lower)
739 dirList = sorted(dirList, key=str.lower)
739
740
740 doypath = dirList[-1]
741 doypath = dirList[-1]
741 foldercounter = int(doypath.split('_')[1]) if len(
742 foldercounter = int(doypath.split('_')[1]) if len(
742 doypath.split('_')) > 1 else 0
743 doypath.split('_')) > 1 else 0
743 fullpath = os.path.join(path, doypath, expLabel)
744 fullpath = os.path.join(path, doypath, expLabel)
744
745
745 print "[Reading] %s folder was found: " % (fullpath)
746 print "[Reading] %s folder was found: " % (fullpath)
746
747
747 if set == None:
748 if set == None:
748 filename = getlastFileFromPath(fullpath, ext)
749 filename = getlastFileFromPath(fullpath, ext)
749 else:
750 else:
750 filename = getFileFromSet(fullpath, ext, set)
751 filename = getFileFromSet(fullpath, ext, set)
751
752
752 if not(filename):
753 if not(filename):
753 return None, None, None, None, None, None
754 return None, None, None, None, None, None
754
755
755 print "[Reading] %s file was found" % (filename)
756 print "[Reading] %s file was found" % (filename)
756
757
757 if not(self.__verifyFile(os.path.join(fullpath, filename))):
758 if not(self.__verifyFile(os.path.join(fullpath, filename))):
758 return None, None, None, None, None, None
759 return None, None, None, None, None, None
759
760
760 year = int(filename[1:5])
761 year = int(filename[1:5])
761 doy = int(filename[5:8])
762 doy = int(filename[5:8])
762 set = int(filename[8:11])
763 set = int(filename[8:11])
763
764
764 return fullpath, foldercounter, filename, year, doy, set
765 return fullpath, foldercounter, filename, year, doy, set
765
766
766 def __setNextFileOffline(self):
767 def __setNextFileOffline(self):
767
768
768 idFile = self.fileIndex
769 idFile = self.fileIndex
769
770
770 while (True):
771 while (True):
771 idFile += 1
772 idFile += 1
772 if not(idFile < len(self.filenameList)):
773 if not(idFile < len(self.filenameList)):
773 self.flagNoMoreFiles = 1
774 self.flagNoMoreFiles = 1
774 # print "[Reading] No more Files"
775 # print "[Reading] No more Files"
775 return 0
776 return 0
776
777
777 filename = self.filenameList[idFile]
778 filename = self.filenameList[idFile]
778
779
779 if not(self.__verifyFile(filename)):
780 if not(self.__verifyFile(filename)):
780 continue
781 continue
781
782
782 fileSize = os.path.getsize(filename)
783 fileSize = os.path.getsize(filename)
783 fp = open(filename, 'rb')
784 fp = open(filename, 'rb')
784 break
785 break
785
786
786 self.flagIsNewFile = 1
787 self.flagIsNewFile = 1
787 self.fileIndex = idFile
788 self.fileIndex = idFile
788 self.filename = filename
789 self.filename = filename
789 self.fileSize = fileSize
790 self.fileSize = fileSize
790 self.fp = fp
791 self.fp = fp
791
792
792 # print "[Reading] Setting the file: %s"%self.filename
793 # print "[Reading] Setting the file: %s"%self.filename
793
794
794 return 1
795 return 1
795
796
796 def __setNextFileOnline(self):
797 def __setNextFileOnline(self):
797 """
798 """
798 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
799 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
800 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
800 siguientes.
801 siguientes.
801
802
802 Affected:
803 Affected:
803 self.flagIsNewFile
804 self.flagIsNewFile
804 self.filename
805 self.filename
805 self.fileSize
806 self.fileSize
806 self.fp
807 self.fp
807 self.set
808 self.set
808 self.flagNoMoreFiles
809 self.flagNoMoreFiles
809
810
810 Return:
811 Return:
811 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
812 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
813 1 : si el file fue abierto con exito y esta listo a ser leido
813
814
814 Excepciones:
815 Excepciones:
815 Si un determinado file no puede ser abierto
816 Si un determinado file no puede ser abierto
816 """
817 """
817 nFiles = 0
818 nFiles = 0
818 fileOk_flag = False
819 fileOk_flag = False
819 firstTime_flag = True
820 firstTime_flag = True
820
821
821 self.set += 1
822 self.set += 1
822
823
823 if self.set > 999:
824 if self.set > 999:
824 self.set = 0
825 self.set = 0
825 self.foldercounter += 1
826 self.foldercounter += 1
826
827
827 # busca el 1er file disponible
828 # busca el 1er file disponible
828 fullfilename, filename = checkForRealPath(
829 fullfilename, filename = checkForRealPath(
829 self.path, self.foldercounter, self.year, self.doy, self.set, self.ext)
830 self.path, self.foldercounter, self.year, self.doy, self.set, self.ext)
830 if fullfilename:
831 if fullfilename:
831 if self.__verifyFile(fullfilename, False):
832 if self.__verifyFile(fullfilename, False):
832 fileOk_flag = True
833 fileOk_flag = True
833
834
834 # si no encuentra un file entonces espera y vuelve a buscar
835 # si no encuentra un file entonces espera y vuelve a buscar
835 if not(fileOk_flag):
836 if not(fileOk_flag):
836 # busco en los siguientes self.nFiles+1 files posibles
837 # busco en los siguientes self.nFiles+1 files posibles
837 for nFiles in range(self.nFiles + 1):
838 for nFiles in range(self.nFiles + 1):
838
839
839 if firstTime_flag: # si es la 1era vez entonces hace el for self.nTries veces
840 if firstTime_flag: # si es la 1era vez entonces hace el for self.nTries veces
840 tries = self.nTries
841 tries = self.nTries
841 else:
842 else:
842 tries = 1 # si no es la 1era vez entonces solo lo hace una vez
843 tries = 1 # si no es la 1era vez entonces solo lo hace una vez
843
844
844 for nTries in range(tries):
845 for nTries in range(tries):
845 if firstTime_flag:
846 if firstTime_flag:
846 print "\t[Reading] Waiting %0.2f sec for the next file: \"%s\" , try %03d ..." % (self.delay, filename, nTries + 1)
847 print "\t[Reading] Waiting %0.2f sec for the next file: \"%s\" , try %03d ..." % (self.delay, filename, nTries + 1)
847 sleep(self.delay)
848 sleep(self.delay)
848 else:
849 else:
849 print "\t[Reading] Searching the next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext)
850 print "\t[Reading] Searching the next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext)
850
851
851 fullfilename, filename = checkForRealPath(
852 fullfilename, filename = checkForRealPath(
852 self.path, self.foldercounter, self.year, self.doy, self.set, self.ext)
853 self.path, self.foldercounter, self.year, self.doy, self.set, self.ext)
853 if fullfilename:
854 if fullfilename:
854 if self.__verifyFile(fullfilename):
855 if self.__verifyFile(fullfilename):
855 fileOk_flag = True
856 fileOk_flag = True
856 break
857 break
857
858
858 if fileOk_flag:
859 if fileOk_flag:
859 break
860 break
860
861
861 firstTime_flag = False
862 firstTime_flag = False
862
863
863 print "\t[Reading] Skipping the file \"%s\" due to this file doesn't exist" % filename
864 log.warning('Skipping the file {} due to this file doesn\'t exist'.format(filename))
864 self.set += 1
865 self.set += 1
865
866
866 # si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
867 # si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
867 if nFiles == (self.nFiles - 1):
868 if nFiles == (self.nFiles - 1):
868 self.set = 0
869 self.set = 0
869 self.doy += 1
870 self.doy += 1
870 self.foldercounter = 0
871 self.foldercounter = 0
871
872
872 if fileOk_flag:
873 if fileOk_flag:
873 self.fileSize = os.path.getsize(fullfilename)
874 self.fileSize = os.path.getsize(fullfilename)
874 self.filename = fullfilename
875 self.filename = fullfilename
875 self.flagIsNewFile = 1
876 self.flagIsNewFile = 1
876 if self.fp != None:
877 if self.fp != None:
877 self.fp.close()
878 self.fp.close()
878 self.fp = open(fullfilename, 'rb')
879 self.fp = open(fullfilename, 'rb')
879 self.flagNoMoreFiles = 0
880 self.flagNoMoreFiles = 0
880 # print '[Reading] Setting the file: %s' % fullfilename
881 # print '[Reading] Setting the file: %s' % fullfilename
881 else:
882 else:
882 self.fileSize = 0
883 self.fileSize = 0
883 self.filename = None
884 self.filename = None
884 self.flagIsNewFile = 0
885 self.flagIsNewFile = 0
885 self.fp = None
886 self.fp = None
886 self.flagNoMoreFiles = 1
887 self.flagNoMoreFiles = 1
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 print '[Reading] No more files to read'
901 raise schainpy.admin.SchainWarning('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 raise(schainpy.admin.SchainWarning('No more files'))
1055 raise(schainpy.admin.SchainWarning('No more files'))
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 ...' % (delay, path, nTries + 1)
1324 sleep(self.delay)
1324 sleep(delay)
1325
1325
1326 if not(fullpath):
1326 if not(fullpath):
1327 print "[Reading] There 'isn't any valid file in %s" % path
1327 raise schainpy.admin.SchainWarning('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, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs):
1818 def run(self, dataOut, path, blocksPerFile, 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.putData()
1826 self.putData()
General Comments 0
You need to be logged in to leave comments. Login now