##// END OF EJS Templates
Alarm working ok
jespinoza -
r1130:d903be96a0b2
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:
973 for key, value in kwargs:
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,1824 +1,1824
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
27
27 LOCALTIME = True
28 LOCALTIME = True
28
29
29
30
30 def isNumber(cad):
31 def isNumber(cad):
31 """
32 """
32 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
33 Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero.
33
34
34 Excepciones:
35 Excepciones:
35 Si un determinado string no puede ser convertido a numero
36 Si un determinado string no puede ser convertido a numero
36 Input:
37 Input:
37 str, string al cual se le analiza para determinar si convertible a un numero o no
38 str, string al cual se le analiza para determinar si convertible a un numero o no
38
39
39 Return:
40 Return:
40 True : si el string es uno numerico
41 True : si el string es uno numerico
41 False : no es un string numerico
42 False : no es un string numerico
42 """
43 """
43 try:
44 try:
44 float(cad)
45 float(cad)
45 return True
46 return True
46 except:
47 except:
47 return False
48 return False
48
49
49
50
50 def isFileInEpoch(filename, startUTSeconds, endUTSeconds):
51 def isFileInEpoch(filename, startUTSeconds, endUTSeconds):
51 """
52 """
52 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
53 Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado.
53
54
54 Inputs:
55 Inputs:
55 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
56 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
56
57
57 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
58 startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en
58 segundos contados desde 01/01/1970.
59 segundos contados desde 01/01/1970.
59 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
60 endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en
60 segundos contados desde 01/01/1970.
61 segundos contados desde 01/01/1970.
61
62
62 Return:
63 Return:
63 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
64 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
64 fecha especificado, de lo contrario retorna False.
65 fecha especificado, de lo contrario retorna False.
65
66
66 Excepciones:
67 Excepciones:
67 Si el archivo no existe o no puede ser abierto
68 Si el archivo no existe o no puede ser abierto
68 Si la cabecera no puede ser leida.
69 Si la cabecera no puede ser leida.
69
70
70 """
71 """
71 basicHeaderObj = BasicHeader(LOCALTIME)
72 basicHeaderObj = BasicHeader(LOCALTIME)
72
73
73 try:
74 try:
74 fp = open(filename, 'rb')
75 fp = open(filename, 'rb')
75 except IOError:
76 except IOError:
76 print "The file %s can't be opened" % (filename)
77 print "The file %s can't be opened" % (filename)
77 return 0
78 return 0
78
79
79 sts = basicHeaderObj.read(fp)
80 sts = basicHeaderObj.read(fp)
80 fp.close()
81 fp.close()
81
82
82 if not(sts):
83 if not(sts):
83 print "Skipping the file %s because it has not a valid header" % (filename)
84 print "Skipping the file %s because it has not a valid header" % (filename)
84 return 0
85 return 0
85
86
86 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
87 if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)):
87 return 0
88 return 0
88
89
89 return 1
90 return 1
90
91
91
92
92 def isTimeInRange(thisTime, startTime, endTime):
93 def isTimeInRange(thisTime, startTime, endTime):
93 if endTime >= startTime:
94 if endTime >= startTime:
94 if (thisTime < startTime) or (thisTime > endTime):
95 if (thisTime < startTime) or (thisTime > endTime):
95 return 0
96 return 0
96 return 1
97 return 1
97 else:
98 else:
98 if (thisTime < startTime) and (thisTime > endTime):
99 if (thisTime < startTime) and (thisTime > endTime):
99 return 0
100 return 0
100 return 1
101 return 1
101
102
102
103
103 def isFileInTimeRange(filename, startDate, endDate, startTime, endTime):
104 def isFileInTimeRange(filename, startDate, endDate, startTime, endTime):
104 """
105 """
105 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
106 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
106
107
107 Inputs:
108 Inputs:
108 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
109 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
109
110
110 startDate : fecha inicial del rango seleccionado en formato datetime.date
111 startDate : fecha inicial del rango seleccionado en formato datetime.date
111
112
112 endDate : fecha final del rango seleccionado en formato datetime.date
113 endDate : fecha final del rango seleccionado en formato datetime.date
113
114
114 startTime : tiempo inicial del rango seleccionado en formato datetime.time
115 startTime : tiempo inicial del rango seleccionado en formato datetime.time
115
116
116 endTime : tiempo final del rango seleccionado en formato datetime.time
117 endTime : tiempo final del rango seleccionado en formato datetime.time
117
118
118 Return:
119 Return:
119 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
120 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
120 fecha especificado, de lo contrario retorna False.
121 fecha especificado, de lo contrario retorna False.
121
122
122 Excepciones:
123 Excepciones:
123 Si el archivo no existe o no puede ser abierto
124 Si el archivo no existe o no puede ser abierto
124 Si la cabecera no puede ser leida.
125 Si la cabecera no puede ser leida.
125
126
126 """
127 """
127
128
128 try:
129 try:
129 fp = open(filename, 'rb')
130 fp = open(filename, 'rb')
130 except IOError:
131 except IOError:
131 print "The file %s can't be opened" % (filename)
132 print "The file %s can't be opened" % (filename)
132 return None
133 return None
133
134
134 firstBasicHeaderObj = BasicHeader(LOCALTIME)
135 firstBasicHeaderObj = BasicHeader(LOCALTIME)
135 systemHeaderObj = SystemHeader()
136 systemHeaderObj = SystemHeader()
136 radarControllerHeaderObj = RadarControllerHeader()
137 radarControllerHeaderObj = RadarControllerHeader()
137 processingHeaderObj = ProcessingHeader()
138 processingHeaderObj = ProcessingHeader()
138
139
139 lastBasicHeaderObj = BasicHeader(LOCALTIME)
140 lastBasicHeaderObj = BasicHeader(LOCALTIME)
140
141
141 sts = firstBasicHeaderObj.read(fp)
142 sts = firstBasicHeaderObj.read(fp)
142
143
143 if not(sts):
144 if not(sts):
144 print "[Reading] Skipping the file %s because it has not a valid header" % (filename)
145 print "[Reading] Skipping the file %s because it has not a valid header" % (filename)
145 return None
146 return None
146
147
147 if not systemHeaderObj.read(fp):
148 if not systemHeaderObj.read(fp):
148 return None
149 return None
149
150
150 if not radarControllerHeaderObj.read(fp):
151 if not radarControllerHeaderObj.read(fp):
151 return None
152 return None
152
153
153 if not processingHeaderObj.read(fp):
154 if not processingHeaderObj.read(fp):
154 return None
155 return None
155
156
156 filesize = os.path.getsize(filename)
157 filesize = os.path.getsize(filename)
157
158
158 offset = processingHeaderObj.blockSize + 24 # header size
159 offset = processingHeaderObj.blockSize + 24 # header size
159
160
160 if filesize <= offset:
161 if filesize <= offset:
161 print "[Reading] %s: This file has not enough data" % filename
162 print "[Reading] %s: This file has not enough data" % filename
162 return None
163 return None
163
164
164 fp.seek(-offset, 2)
165 fp.seek(-offset, 2)
165
166
166 sts = lastBasicHeaderObj.read(fp)
167 sts = lastBasicHeaderObj.read(fp)
167
168
168 fp.close()
169 fp.close()
169
170
170 thisDatetime = lastBasicHeaderObj.datatime
171 thisDatetime = lastBasicHeaderObj.datatime
171 thisTime_last_block = thisDatetime.time()
172 thisTime_last_block = thisDatetime.time()
172
173
173 thisDatetime = firstBasicHeaderObj.datatime
174 thisDatetime = firstBasicHeaderObj.datatime
174 thisDate = thisDatetime.date()
175 thisDate = thisDatetime.date()
175 thisTime_first_block = thisDatetime.time()
176 thisTime_first_block = thisDatetime.time()
176
177
177 # General case
178 # General case
178 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
179 # o>>>>>>>>>>>>>><<<<<<<<<<<<<<o
179 #-----------o----------------------------o-----------
180 #-----------o----------------------------o-----------
180 # startTime endTime
181 # startTime endTime
181
182
182 if endTime >= startTime:
183 if endTime >= startTime:
183 if (thisTime_last_block < startTime) or (thisTime_first_block > endTime):
184 if (thisTime_last_block < startTime) or (thisTime_first_block > endTime):
184 return None
185 return None
185
186
186 return thisDatetime
187 return thisDatetime
187
188
188 # If endTime < startTime then endTime belongs to the next day
189 # If endTime < startTime then endTime belongs to the next day
189
190
190 #<<<<<<<<<<<o o>>>>>>>>>>>
191 #<<<<<<<<<<<o o>>>>>>>>>>>
191 #-----------o----------------------------o-----------
192 #-----------o----------------------------o-----------
192 # endTime startTime
193 # endTime startTime
193
194
194 if (thisDate == startDate) and (thisTime_last_block < startTime):
195 if (thisDate == startDate) and (thisTime_last_block < startTime):
195 return None
196 return None
196
197
197 if (thisDate == endDate) and (thisTime_first_block > endTime):
198 if (thisDate == endDate) and (thisTime_first_block > endTime):
198 return None
199 return None
199
200
200 if (thisTime_last_block < startTime) and (thisTime_first_block > endTime):
201 if (thisTime_last_block < startTime) and (thisTime_first_block > endTime):
201 return None
202 return None
202
203
203 return thisDatetime
204 return thisDatetime
204
205
205
206
206 def isFolderInDateRange(folder, startDate=None, endDate=None):
207 def isFolderInDateRange(folder, startDate=None, endDate=None):
207 """
208 """
208 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
209 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
209
210
210 Inputs:
211 Inputs:
211 folder : nombre completo del directorio.
212 folder : nombre completo del directorio.
212 Su formato deberia ser "/path_root/?YYYYDDD"
213 Su formato deberia ser "/path_root/?YYYYDDD"
213
214
214 siendo:
215 siendo:
215 YYYY : Anio (ejemplo 2015)
216 YYYY : Anio (ejemplo 2015)
216 DDD : Dia del anio (ejemplo 305)
217 DDD : Dia del anio (ejemplo 305)
217
218
218 startDate : fecha inicial del rango seleccionado en formato datetime.date
219 startDate : fecha inicial del rango seleccionado en formato datetime.date
219
220
220 endDate : fecha final del rango seleccionado en formato datetime.date
221 endDate : fecha final del rango seleccionado en formato datetime.date
221
222
222 Return:
223 Return:
223 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
224 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
224 fecha especificado, de lo contrario retorna False.
225 fecha especificado, de lo contrario retorna False.
225 Excepciones:
226 Excepciones:
226 Si el directorio no tiene el formato adecuado
227 Si el directorio no tiene el formato adecuado
227 """
228 """
228
229
229 basename = os.path.basename(folder)
230 basename = os.path.basename(folder)
230
231
231 if not isRadarFolder(basename):
232 if not isRadarFolder(basename):
232 print "The folder %s has not the rigth format" % folder
233 print "The folder %s has not the rigth format" % folder
233 return 0
234 return 0
234
235
235 if startDate and endDate:
236 if startDate and endDate:
236 thisDate = getDateFromRadarFolder(basename)
237 thisDate = getDateFromRadarFolder(basename)
237
238
238 if thisDate < startDate:
239 if thisDate < startDate:
239 return 0
240 return 0
240
241
241 if thisDate > endDate:
242 if thisDate > endDate:
242 return 0
243 return 0
243
244
244 return 1
245 return 1
245
246
246
247
247 def isFileInDateRange(filename, startDate=None, endDate=None):
248 def isFileInDateRange(filename, startDate=None, endDate=None):
248 """
249 """
249 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
250 Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado.
250
251
251 Inputs:
252 Inputs:
252 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
253 filename : nombre completo del archivo de datos en formato Jicamarca (.r)
253
254
254 Su formato deberia ser "?YYYYDDDsss"
255 Su formato deberia ser "?YYYYDDDsss"
255
256
256 siendo:
257 siendo:
257 YYYY : Anio (ejemplo 2015)
258 YYYY : Anio (ejemplo 2015)
258 DDD : Dia del anio (ejemplo 305)
259 DDD : Dia del anio (ejemplo 305)
259 sss : set
260 sss : set
260
261
261 startDate : fecha inicial del rango seleccionado en formato datetime.date
262 startDate : fecha inicial del rango seleccionado en formato datetime.date
262
263
263 endDate : fecha final del rango seleccionado en formato datetime.date
264 endDate : fecha final del rango seleccionado en formato datetime.date
264
265
265 Return:
266 Return:
266 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
267 Boolean : Retorna True si el archivo de datos contiene datos en el rango de
267 fecha especificado, de lo contrario retorna False.
268 fecha especificado, de lo contrario retorna False.
268 Excepciones:
269 Excepciones:
269 Si el archivo no tiene el formato adecuado
270 Si el archivo no tiene el formato adecuado
270 """
271 """
271
272
272 basename = os.path.basename(filename)
273 basename = os.path.basename(filename)
273
274
274 if not isRadarFile(basename):
275 if not isRadarFile(basename):
275 print "The filename %s has not the rigth format" % filename
276 print "The filename %s has not the rigth format" % filename
276 return 0
277 return 0
277
278
278 if startDate and endDate:
279 if startDate and endDate:
279 thisDate = getDateFromRadarFile(basename)
280 thisDate = getDateFromRadarFile(basename)
280
281
281 if thisDate < startDate:
282 if thisDate < startDate:
282 return 0
283 return 0
283
284
284 if thisDate > endDate:
285 if thisDate > endDate:
285 return 0
286 return 0
286
287
287 return 1
288 return 1
288
289
289
290
290 def getFileFromSet(path, ext, set):
291 def getFileFromSet(path, ext, set):
291 validFilelist = []
292 validFilelist = []
292 fileList = os.listdir(path)
293 fileList = os.listdir(path)
293
294
294 # 0 1234 567 89A BCDE
295 # 0 1234 567 89A BCDE
295 # H YYYY DDD SSS .ext
296 # H YYYY DDD SSS .ext
296
297
297 for thisFile in fileList:
298 for thisFile in fileList:
298 try:
299 try:
299 year = int(thisFile[1:5])
300 year = int(thisFile[1:5])
300 doy = int(thisFile[5:8])
301 doy = int(thisFile[5:8])
301 except:
302 except:
302 continue
303 continue
303
304
304 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
305 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
305 continue
306 continue
306
307
307 validFilelist.append(thisFile)
308 validFilelist.append(thisFile)
308
309
309 myfile = fnmatch.filter(
310 myfile = fnmatch.filter(
310 validFilelist, '*%4.4d%3.3d%3.3d*' % (year, doy, set))
311 validFilelist, '*%4.4d%3.3d%3.3d*' % (year, doy, set))
311
312
312 if len(myfile) != 0:
313 if len(myfile) != 0:
313 return myfile[0]
314 return myfile[0]
314 else:
315 else:
315 filename = '*%4.4d%3.3d%3.3d%s' % (year, doy, set, ext.lower())
316 filename = '*%4.4d%3.3d%3.3d%s' % (year, doy, set, ext.lower())
316 print 'the filename %s does not exist' % filename
317 print 'the filename %s does not exist' % filename
317 print '...going to the last file: '
318 print '...going to the last file: '
318
319
319 if validFilelist:
320 if validFilelist:
320 validFilelist = sorted(validFilelist, key=str.lower)
321 validFilelist = sorted(validFilelist, key=str.lower)
321 return validFilelist[-1]
322 return validFilelist[-1]
322
323
323 return None
324 return None
324
325
325
326
326 def getlastFileFromPath(path, ext):
327 def getlastFileFromPath(path, ext):
327 """
328 """
328 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
329 Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext"
329 al final de la depuracion devuelve el ultimo file de la lista que quedo.
330 al final de la depuracion devuelve el ultimo file de la lista que quedo.
330
331
331 Input:
332 Input:
332 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
333 fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta
333 ext : extension de los files contenidos en una carpeta
334 ext : extension de los files contenidos en una carpeta
334
335
335 Return:
336 Return:
336 El ultimo file de una determinada carpeta, no se considera el path.
337 El ultimo file de una determinada carpeta, no se considera el path.
337 """
338 """
338 validFilelist = []
339 validFilelist = []
339 fileList = os.listdir(path)
340 fileList = os.listdir(path)
340
341
341 # 0 1234 567 89A BCDE
342 # 0 1234 567 89A BCDE
342 # H YYYY DDD SSS .ext
343 # H YYYY DDD SSS .ext
343
344
344 for thisFile in fileList:
345 for thisFile in fileList:
345
346
346 year = thisFile[1:5]
347 year = thisFile[1:5]
347 if not isNumber(year):
348 if not isNumber(year):
348 continue
349 continue
349
350
350 doy = thisFile[5:8]
351 doy = thisFile[5:8]
351 if not isNumber(doy):
352 if not isNumber(doy):
352 continue
353 continue
353
354
354 year = int(year)
355 year = int(year)
355 doy = int(doy)
356 doy = int(doy)
356
357
357 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
358 if (os.path.splitext(thisFile)[-1].lower() != ext.lower()):
358 continue
359 continue
359
360
360 validFilelist.append(thisFile)
361 validFilelist.append(thisFile)
361
362
362 if validFilelist:
363 if validFilelist:
363 validFilelist = sorted(validFilelist, key=str.lower)
364 validFilelist = sorted(validFilelist, key=str.lower)
364 return validFilelist[-1]
365 return validFilelist[-1]
365
366
366 return None
367 return None
367
368
368
369
369 def checkForRealPath(path, foldercounter, year, doy, set, ext):
370 def checkForRealPath(path, foldercounter, year, doy, set, ext):
370 """
371 """
371 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
372 Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path,
372 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
373 Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar
373 el path exacto de un determinado file.
374 el path exacto de un determinado file.
374
375
375 Example :
376 Example :
376 nombre correcto del file es .../.../D2009307/P2009307367.ext
377 nombre correcto del file es .../.../D2009307/P2009307367.ext
377
378
378 Entonces la funcion prueba con las siguientes combinaciones
379 Entonces la funcion prueba con las siguientes combinaciones
379 .../.../y2009307367.ext
380 .../.../y2009307367.ext
380 .../.../Y2009307367.ext
381 .../.../Y2009307367.ext
381 .../.../x2009307/y2009307367.ext
382 .../.../x2009307/y2009307367.ext
382 .../.../x2009307/Y2009307367.ext
383 .../.../x2009307/Y2009307367.ext
383 .../.../X2009307/y2009307367.ext
384 .../.../X2009307/y2009307367.ext
384 .../.../X2009307/Y2009307367.ext
385 .../.../X2009307/Y2009307367.ext
385 siendo para este caso, la ultima combinacion de letras, identica al file buscado
386 siendo para este caso, la ultima combinacion de letras, identica al file buscado
386
387
387 Return:
388 Return:
388 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
389 Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file
389 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
390 caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas
390 para el filename
391 para el filename
391 """
392 """
392 fullfilename = None
393 fullfilename = None
393 find_flag = False
394 find_flag = False
394 filename = None
395 filename = None
395
396
396 prefixDirList = [None, 'd', 'D']
397 prefixDirList = [None, 'd', 'D']
397 if ext.lower() == ".r": # voltage
398 if ext.lower() == ".r": # voltage
398 prefixFileList = ['d', 'D']
399 prefixFileList = ['d', 'D']
399 elif ext.lower() == ".pdata": # spectra
400 elif ext.lower() == ".pdata": # spectra
400 prefixFileList = ['p', 'P']
401 prefixFileList = ['p', 'P']
401 else:
402 else:
402 return None, filename
403 return None, filename
403
404
404 # barrido por las combinaciones posibles
405 # barrido por las combinaciones posibles
405 for prefixDir in prefixDirList:
406 for prefixDir in prefixDirList:
406 thispath = path
407 thispath = path
407 if prefixDir != None:
408 if prefixDir != None:
408 # formo el nombre del directorio xYYYYDDD (x=d o x=D)
409 # formo el nombre del directorio xYYYYDDD (x=d o x=D)
409 if foldercounter == 0:
410 if foldercounter == 0:
410 thispath = os.path.join(path, "%s%04d%03d" %
411 thispath = os.path.join(path, "%s%04d%03d" %
411 (prefixDir, year, doy))
412 (prefixDir, year, doy))
412 else:
413 else:
413 thispath = os.path.join(path, "%s%04d%03d_%02d" % (
414 thispath = os.path.join(path, "%s%04d%03d_%02d" % (
414 prefixDir, year, doy, foldercounter))
415 prefixDir, year, doy, foldercounter))
415 for prefixFile in prefixFileList: # barrido por las dos combinaciones posibles de "D"
416 for prefixFile in prefixFileList: # barrido por las dos combinaciones posibles de "D"
416 # formo el nombre del file xYYYYDDDSSS.ext
417 # formo el nombre del file xYYYYDDDSSS.ext
417 filename = "%s%04d%03d%03d%s" % (prefixFile, year, doy, set, ext)
418 filename = "%s%04d%03d%03d%s" % (prefixFile, year, doy, set, ext)
418 fullfilename = os.path.join(
419 fullfilename = os.path.join(
419 thispath, filename) # formo el path completo
420 thispath, filename) # formo el path completo
420
421
421 if os.path.exists(fullfilename): # verifico que exista
422 if os.path.exists(fullfilename): # verifico que exista
422 find_flag = True
423 find_flag = True
423 break
424 break
424 if find_flag:
425 if find_flag:
425 break
426 break
426
427
427 if not(find_flag):
428 if not(find_flag):
428 return None, filename
429 return None, filename
429
430
430 return fullfilename, filename
431 return fullfilename, filename
431
432
432
433
433 def isRadarFolder(folder):
434 def isRadarFolder(folder):
434 try:
435 try:
435 year = int(folder[1:5])
436 year = int(folder[1:5])
436 doy = int(folder[5:8])
437 doy = int(folder[5:8])
437 except:
438 except:
438 return 0
439 return 0
439
440
440 return 1
441 return 1
441
442
442
443
443 def isRadarFile(file):
444 def isRadarFile(file):
444 try:
445 try:
445 year = int(file[1:5])
446 year = int(file[1:5])
446 doy = int(file[5:8])
447 doy = int(file[5:8])
447 set = int(file[8:11])
448 set = int(file[8:11])
448 except:
449 except:
449 return 0
450 return 0
450
451
451 return 1
452 return 1
452
453
453
454
454 def getDateFromRadarFile(file):
455 def getDateFromRadarFile(file):
455 try:
456 try:
456 year = int(file[1:5])
457 year = int(file[1:5])
457 doy = int(file[5:8])
458 doy = int(file[5:8])
458 set = int(file[8:11])
459 set = int(file[8:11])
459 except:
460 except:
460 return None
461 return None
461
462
462 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
463 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
463 return thisDate
464 return thisDate
464
465
465
466
466 def getDateFromRadarFolder(folder):
467 def getDateFromRadarFolder(folder):
467 try:
468 try:
468 year = int(folder[1:5])
469 year = int(folder[1:5])
469 doy = int(folder[5:8])
470 doy = int(folder[5:8])
470 except:
471 except:
471 return None
472 return None
472
473
473 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
474 thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1)
474 return thisDate
475 return thisDate
475
476
476
477
477 class JRODataIO:
478 class JRODataIO:
478
479
479 c = 3E8
480 c = 3E8
480
481
481 isConfig = False
482 isConfig = False
482
483
483 basicHeaderObj = None
484 basicHeaderObj = None
484
485
485 systemHeaderObj = None
486 systemHeaderObj = None
486
487
487 radarControllerHeaderObj = None
488 radarControllerHeaderObj = None
488
489
489 processingHeaderObj = None
490 processingHeaderObj = None
490
491
491 dtype = None
492 dtype = None
492
493
493 pathList = []
494 pathList = []
494
495
495 filenameList = []
496 filenameList = []
496
497
497 filename = None
498 filename = None
498
499
499 ext = None
500 ext = None
500
501
501 flagIsNewFile = 1
502 flagIsNewFile = 1
502
503
503 flagDiscontinuousBlock = 0
504 flagDiscontinuousBlock = 0
504
505
505 flagIsNewBlock = 0
506 flagIsNewBlock = 0
506
507
507 fp = None
508 fp = None
508
509
509 firstHeaderSize = 0
510 firstHeaderSize = 0
510
511
511 basicHeaderSize = 24
512 basicHeaderSize = 24
512
513
513 versionFile = 1103
514 versionFile = 1103
514
515
515 fileSize = None
516 fileSize = None
516
517
517 # ippSeconds = None
518 # ippSeconds = None
518
519
519 fileSizeByHeader = None
520 fileSizeByHeader = None
520
521
521 fileIndex = None
522 fileIndex = None
522
523
523 profileIndex = None
524 profileIndex = None
524
525
525 blockIndex = None
526 blockIndex = None
526
527
527 nTotalBlocks = None
528 nTotalBlocks = None
528
529
529 maxTimeStep = 30
530 maxTimeStep = 30
530
531
531 lastUTTime = None
532 lastUTTime = None
532
533
533 datablock = None
534 datablock = None
534
535
535 dataOut = None
536 dataOut = None
536
537
537 blocksize = None
538 blocksize = None
538
539
539 getByBlock = False
540 getByBlock = False
540
541
541 def __init__(self):
542 def __init__(self):
542
543
543 raise NotImplementedError
544 raise NotImplementedError
544
545
545 def run(self):
546 def run(self):
546
547
547 raise NotImplementedError
548 raise NotImplementedError
548
549
549 def getDtypeWidth(self):
550 def getDtypeWidth(self):
550
551
551 dtype_index = get_dtype_index(self.dtype)
552 dtype_index = get_dtype_index(self.dtype)
552 dtype_width = get_dtype_width(dtype_index)
553 dtype_width = get_dtype_width(dtype_index)
553
554
554 return dtype_width
555 return dtype_width
555
556
556 def getAllowedArgs(self):
557 def getAllowedArgs(self):
557 if hasattr(self, '__attrs__'):
558 if hasattr(self, '__attrs__'):
558 return self.__attrs__
559 return self.__attrs__
559 else:
560 else:
560 return inspect.getargspec(self.run).args
561 return inspect.getargspec(self.run).args
561
562
562
563
563 class JRODataReader(JRODataIO):
564 class JRODataReader(JRODataIO):
564
565
565 online = 0
566 online = 0
566
567
567 realtime = 0
568 realtime = 0
568
569
569 nReadBlocks = 0
570 nReadBlocks = 0
570
571
571 delay = 10 # number of seconds waiting a new file
572 delay = 10 # number of seconds waiting a new file
572
573
573 nTries = 3 # quantity tries
574 nTries = 3 # quantity tries
574
575
575 nFiles = 3 # number of files for searching
576 nFiles = 3 # number of files for searching
576
577
577 path = None
578 path = None
578
579
579 foldercounter = 0
580 foldercounter = 0
580
581
581 flagNoMoreFiles = 0
582 flagNoMoreFiles = 0
582
583
583 datetimeList = []
584 datetimeList = []
584
585
585 __isFirstTimeOnline = 1
586 __isFirstTimeOnline = 1
586
587
587 __printInfo = True
588 __printInfo = True
588
589
589 profileIndex = None
590 profileIndex = None
590
591
591 nTxs = 1
592 nTxs = 1
592
593
593 txIndex = None
594 txIndex = None
594
595
595 # Added--------------------
596 # Added--------------------
596
597
597 selBlocksize = None
598 selBlocksize = None
598
599
599 selBlocktime = None
600 selBlocktime = None
600
601
601 def __init__(self):
602 def __init__(self):
602 """
603 """
603 This class is used to find data files
604 This class is used to find data files
604
605
605 Example:
606 Example:
606 reader = JRODataReader()
607 reader = JRODataReader()
607 fileList = reader.findDataFiles()
608 fileList = reader.findDataFiles()
608
609
609 """
610 """
610 pass
611 pass
611
612
612 def createObjByDefault(self):
613 def createObjByDefault(self):
613 """
614 """
614
615
615 """
616 """
616 raise NotImplementedError
617 raise NotImplementedError
617
618
618 def getBlockDimension(self):
619 def getBlockDimension(self):
619
620
620 raise NotImplementedError
621 raise NotImplementedError
621
622
622 def searchFilesOffLine(self,
623 def searchFilesOffLine(self,
623 path,
624 path,
624 startDate=None,
625 startDate=None,
625 endDate=None,
626 endDate=None,
626 startTime=datetime.time(0, 0, 0),
627 startTime=datetime.time(0, 0, 0),
627 endTime=datetime.time(23, 59, 59),
628 endTime=datetime.time(23, 59, 59),
628 set=None,
629 set=None,
629 expLabel='',
630 expLabel='',
630 ext='.r',
631 ext='.r',
631 cursor=None,
632 cursor=None,
632 skip=None,
633 skip=None,
633 walk=True):
634 walk=True):
634
635
635 self.filenameList = []
636 self.filenameList = []
636 self.datetimeList = []
637 self.datetimeList = []
637
638
638 pathList = []
639 pathList = []
639
640
640 dateList, pathList = self.findDatafiles(
641 dateList, pathList = self.findDatafiles(
641 path, startDate, endDate, expLabel, ext, walk, include_path=True)
642 path, startDate, endDate, expLabel, ext, walk, include_path=True)
642
643
643 if dateList == []:
644 if dateList == []:
644 return [], []
645 return [], []
645
646
646 if len(dateList) > 1:
647 if len(dateList) > 1:
647 print "[Reading] Data found for date range [%s - %s]: total days = %d" % (startDate, endDate, len(dateList))
648 print "[Reading] Data found for date range [%s - %s]: total days = %d" % (startDate, endDate, len(dateList))
648 else:
649 else:
649 print "[Reading] Data found for date range [%s - %s]: date = %s" % (startDate, endDate, dateList[0])
650 print "[Reading] Data found for date range [%s - %s]: date = %s" % (startDate, endDate, dateList[0])
650
651
651 filenameList = []
652 filenameList = []
652 datetimeList = []
653 datetimeList = []
653
654
654 for thisPath in pathList:
655 for thisPath in pathList:
655
656
656 fileList = glob.glob1(thisPath, "*%s" % ext)
657 fileList = glob.glob1(thisPath, "*%s" % ext)
657 fileList.sort()
658 fileList.sort()
658
659
659 for file in fileList:
660 for file in fileList:
660
661
661 filename = os.path.join(thisPath, file)
662 filename = os.path.join(thisPath, file)
662
663
663 if not isFileInDateRange(filename, startDate, endDate):
664 if not isFileInDateRange(filename, startDate, endDate):
664 continue
665 continue
665
666
666 thisDatetime = isFileInTimeRange(
667 thisDatetime = isFileInTimeRange(
667 filename, startDate, endDate, startTime, endTime)
668 filename, startDate, endDate, startTime, endTime)
668
669
669 if not(thisDatetime):
670 if not(thisDatetime):
670 continue
671 continue
671
672
672 filenameList.append(filename)
673 filenameList.append(filename)
673 datetimeList.append(thisDatetime)
674 datetimeList.append(thisDatetime)
674
675
675 if cursor is not None and skip is not None:
676 if cursor is not None and skip is not None:
676 filenameList = filenameList[cursor * skip:cursor * skip + skip]
677 filenameList = filenameList[cursor * skip:cursor * skip + skip]
677 datetimeList = datetimeList[cursor * skip:cursor * skip + skip]
678 datetimeList = datetimeList[cursor * skip:cursor * skip + skip]
678
679
679 if not(filenameList):
680 if not(filenameList):
680 print "[Reading] Time range selected invalid [%s - %s]: No *%s files in %s)" % (startTime, endTime, ext, path)
681 print "[Reading] Time range selected invalid [%s - %s]: No *%s files in %s)" % (startTime, endTime, ext, path)
681 return [], []
682 return [], []
682
683
683 print "[Reading] %d file(s) was(were) found in time range: %s - %s" % (len(filenameList), startTime, endTime)
684 print "[Reading] %d file(s) was(were) found in time range: %s - %s" % (len(filenameList), startTime, endTime)
684
685
685 # for i in range(len(filenameList)):
686 # for i in range(len(filenameList)):
686 # print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
687 # print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime())
687
688
688 self.filenameList = filenameList
689 self.filenameList = filenameList
689 self.datetimeList = datetimeList
690 self.datetimeList = datetimeList
690
691
691 return pathList, filenameList
692 return pathList, filenameList
692
693
693 def __searchFilesOnLine(self, path, expLabel="", ext=None, walk=True, set=None):
694 def __searchFilesOnLine(self, path, expLabel="", ext=None, walk=True, set=None):
694 """
695 """
695 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
696 Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y
696 devuelve el archivo encontrado ademas de otros datos.
697 devuelve el archivo encontrado ademas de otros datos.
697
698
698 Input:
699 Input:
699 path : carpeta donde estan contenidos los files que contiene data
700 path : carpeta donde estan contenidos los files que contiene data
700
701
701 expLabel : Nombre del subexperimento (subfolder)
702 expLabel : Nombre del subexperimento (subfolder)
702
703
703 ext : extension de los files
704 ext : extension de los files
704
705
705 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
706 walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath)
706
707
707 Return:
708 Return:
708 directory : eL directorio donde esta el file encontrado
709 directory : eL directorio donde esta el file encontrado
709 filename : el ultimo file de una determinada carpeta
710 filename : el ultimo file de una determinada carpeta
710 year : el anho
711 year : el anho
711 doy : el numero de dia del anho
712 doy : el numero de dia del anho
712 set : el set del archivo
713 set : el set del archivo
713
714
714
715
715 """
716 """
716 if not os.path.isdir(path):
717 if not os.path.isdir(path):
717 return None, None, None, None, None, None
718 return None, None, None, None, None, None
718
719
719 dirList = []
720 dirList = []
720
721
721 if not walk:
722 if not walk:
722 fullpath = path
723 fullpath = path
723 foldercounter = 0
724 foldercounter = 0
724 else:
725 else:
725 # Filtra solo los directorios
726 # Filtra solo los directorios
726 for thisPath in os.listdir(path):
727 for thisPath in os.listdir(path):
727 if not os.path.isdir(os.path.join(path, thisPath)):
728 if not os.path.isdir(os.path.join(path, thisPath)):
728 continue
729 continue
729 if not isRadarFolder(thisPath):
730 if not isRadarFolder(thisPath):
730 continue
731 continue
731
732
732 dirList.append(thisPath)
733 dirList.append(thisPath)
733
734
734 if not(dirList):
735 if not(dirList):
735 return None, None, None, None, None, None
736 return None, None, None, None, None, None
736
737
737 dirList = sorted(dirList, key=str.lower)
738 dirList = sorted(dirList, key=str.lower)
738
739
739 doypath = dirList[-1]
740 doypath = dirList[-1]
740 foldercounter = int(doypath.split('_')[1]) if len(
741 foldercounter = int(doypath.split('_')[1]) if len(
741 doypath.split('_')) > 1 else 0
742 doypath.split('_')) > 1 else 0
742 fullpath = os.path.join(path, doypath, expLabel)
743 fullpath = os.path.join(path, doypath, expLabel)
743
744
744 print "[Reading] %s folder was found: " % (fullpath)
745 print "[Reading] %s folder was found: " % (fullpath)
745
746
746 if set == None:
747 if set == None:
747 filename = getlastFileFromPath(fullpath, ext)
748 filename = getlastFileFromPath(fullpath, ext)
748 else:
749 else:
749 filename = getFileFromSet(fullpath, ext, set)
750 filename = getFileFromSet(fullpath, ext, set)
750
751
751 if not(filename):
752 if not(filename):
752 return None, None, None, None, None, None
753 return None, None, None, None, None, None
753
754
754 print "[Reading] %s file was found" % (filename)
755 print "[Reading] %s file was found" % (filename)
755
756
756 if not(self.__verifyFile(os.path.join(fullpath, filename))):
757 if not(self.__verifyFile(os.path.join(fullpath, filename))):
757 return None, None, None, None, None, None
758 return None, None, None, None, None, None
758
759
759 year = int(filename[1:5])
760 year = int(filename[1:5])
760 doy = int(filename[5:8])
761 doy = int(filename[5:8])
761 set = int(filename[8:11])
762 set = int(filename[8:11])
762
763
763 return fullpath, foldercounter, filename, year, doy, set
764 return fullpath, foldercounter, filename, year, doy, set
764
765
765 def __setNextFileOffline(self):
766 def __setNextFileOffline(self):
766
767
767 idFile = self.fileIndex
768 idFile = self.fileIndex
768
769
769 while (True):
770 while (True):
770 idFile += 1
771 idFile += 1
771 if not(idFile < len(self.filenameList)):
772 if not(idFile < len(self.filenameList)):
772 self.flagNoMoreFiles = 1
773 self.flagNoMoreFiles = 1
773 # print "[Reading] No more Files"
774 # print "[Reading] No more Files"
774 return 0
775 return 0
775
776
776 filename = self.filenameList[idFile]
777 filename = self.filenameList[idFile]
777
778
778 if not(self.__verifyFile(filename)):
779 if not(self.__verifyFile(filename)):
779 continue
780 continue
780
781
781 fileSize = os.path.getsize(filename)
782 fileSize = os.path.getsize(filename)
782 fp = open(filename, 'rb')
783 fp = open(filename, 'rb')
783 break
784 break
784
785
785 self.flagIsNewFile = 1
786 self.flagIsNewFile = 1
786 self.fileIndex = idFile
787 self.fileIndex = idFile
787 self.filename = filename
788 self.filename = filename
788 self.fileSize = fileSize
789 self.fileSize = fileSize
789 self.fp = fp
790 self.fp = fp
790
791
791 # print "[Reading] Setting the file: %s"%self.filename
792 # print "[Reading] Setting the file: %s"%self.filename
792
793
793 return 1
794 return 1
794
795
795 def __setNextFileOnline(self):
796 def __setNextFileOnline(self):
796 """
797 """
797 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
798 Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si
798 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
799 no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files
799 siguientes.
800 siguientes.
800
801
801 Affected:
802 Affected:
802 self.flagIsNewFile
803 self.flagIsNewFile
803 self.filename
804 self.filename
804 self.fileSize
805 self.fileSize
805 self.fp
806 self.fp
806 self.set
807 self.set
807 self.flagNoMoreFiles
808 self.flagNoMoreFiles
808
809
809 Return:
810 Return:
810 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
811 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado
811 1 : si el file fue abierto con exito y esta listo a ser leido
812 1 : si el file fue abierto con exito y esta listo a ser leido
812
813
813 Excepciones:
814 Excepciones:
814 Si un determinado file no puede ser abierto
815 Si un determinado file no puede ser abierto
815 """
816 """
816 nFiles = 0
817 nFiles = 0
817 fileOk_flag = False
818 fileOk_flag = False
818 firstTime_flag = True
819 firstTime_flag = True
819
820
820 self.set += 1
821 self.set += 1
821
822
822 if self.set > 999:
823 if self.set > 999:
823 self.set = 0
824 self.set = 0
824 self.foldercounter += 1
825 self.foldercounter += 1
825
826
826 # busca el 1er file disponible
827 # busca el 1er file disponible
827 fullfilename, filename = checkForRealPath(
828 fullfilename, filename = checkForRealPath(
828 self.path, self.foldercounter, self.year, self.doy, self.set, self.ext)
829 self.path, self.foldercounter, self.year, self.doy, self.set, self.ext)
829 if fullfilename:
830 if fullfilename:
830 if self.__verifyFile(fullfilename, False):
831 if self.__verifyFile(fullfilename, False):
831 fileOk_flag = True
832 fileOk_flag = True
832
833
833 # si no encuentra un file entonces espera y vuelve a buscar
834 # si no encuentra un file entonces espera y vuelve a buscar
834 if not(fileOk_flag):
835 if not(fileOk_flag):
835 # busco en los siguientes self.nFiles+1 files posibles
836 # busco en los siguientes self.nFiles+1 files posibles
836 for nFiles in range(self.nFiles + 1):
837 for nFiles in range(self.nFiles + 1):
837
838
838 if firstTime_flag: # si es la 1era vez entonces hace el for self.nTries veces
839 if firstTime_flag: # si es la 1era vez entonces hace el for self.nTries veces
839 tries = self.nTries
840 tries = self.nTries
840 else:
841 else:
841 tries = 1 # si no es la 1era vez entonces solo lo hace una vez
842 tries = 1 # si no es la 1era vez entonces solo lo hace una vez
842
843
843 for nTries in range(tries):
844 for nTries in range(tries):
844 if firstTime_flag:
845 if firstTime_flag:
845 print "\t[Reading] Waiting %0.2f sec for the next file: \"%s\" , try %03d ..." % (self.delay, filename, nTries + 1)
846 print "\t[Reading] Waiting %0.2f sec for the next file: \"%s\" , try %03d ..." % (self.delay, filename, nTries + 1)
846 sleep(self.delay)
847 sleep(self.delay)
847 else:
848 else:
848 print "\t[Reading] Searching the next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext)
849 print "\t[Reading] Searching the next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext)
849
850
850 fullfilename, filename = checkForRealPath(
851 fullfilename, filename = checkForRealPath(
851 self.path, self.foldercounter, self.year, self.doy, self.set, self.ext)
852 self.path, self.foldercounter, self.year, self.doy, self.set, self.ext)
852 if fullfilename:
853 if fullfilename:
853 if self.__verifyFile(fullfilename):
854 if self.__verifyFile(fullfilename):
854 fileOk_flag = True
855 fileOk_flag = True
855 break
856 break
856
857
857 if fileOk_flag:
858 if fileOk_flag:
858 break
859 break
859
860
860 firstTime_flag = False
861 firstTime_flag = False
861
862
862 print "\t[Reading] Skipping the file \"%s\" due to this file doesn't exist" % filename
863 log.warning('Skipping the file {} due to this file doesn\'t exist'.format(filename))
863 self.set += 1
864 self.set += 1
864
865
865 # si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
866 # si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta
866 if nFiles == (self.nFiles - 1):
867 if nFiles == (self.nFiles - 1):
867 self.set = 0
868 self.set = 0
868 self.doy += 1
869 self.doy += 1
869 self.foldercounter = 0
870 self.foldercounter = 0
870
871
871 if fileOk_flag:
872 if fileOk_flag:
872 self.fileSize = os.path.getsize(fullfilename)
873 self.fileSize = os.path.getsize(fullfilename)
873 self.filename = fullfilename
874 self.filename = fullfilename
874 self.flagIsNewFile = 1
875 self.flagIsNewFile = 1
875 if self.fp != None:
876 if self.fp != None:
876 self.fp.close()
877 self.fp.close()
877 self.fp = open(fullfilename, 'rb')
878 self.fp = open(fullfilename, 'rb')
878 self.flagNoMoreFiles = 0
879 self.flagNoMoreFiles = 0
879 # print '[Reading] Setting the file: %s' % fullfilename
880 # print '[Reading] Setting the file: %s' % fullfilename
880 else:
881 else:
881 self.fileSize = 0
882 self.fileSize = 0
882 self.filename = None
883 self.filename = None
883 self.flagIsNewFile = 0
884 self.flagIsNewFile = 0
884 self.fp = None
885 self.fp = None
885 self.flagNoMoreFiles = 1
886 self.flagNoMoreFiles = 1
886 # print '[Reading] No more files to read'
887
887
888 return fileOk_flag
888 return fileOk_flag
889
889
890 def setNextFile(self):
890 def setNextFile(self):
891 if self.fp != None:
891 if self.fp != None:
892 self.fp.close()
892 self.fp.close()
893
893
894 if self.online:
894 if self.online:
895 newFile = self.__setNextFileOnline()
895 newFile = self.__setNextFileOnline()
896 else:
896 else:
897 newFile = self.__setNextFileOffline()
897 newFile = self.__setNextFileOffline()
898
898
899 if not(newFile):
899 if not(newFile):
900 print '[Reading] No more files to read'
900 raise schainpy.admin.SchainWarning('No more files to read')
901 return 0
901 return 0
902
902
903 if self.verbose:
903 if self.verbose:
904 print '[Reading] Setting the file: %s' % self.filename
904 print '[Reading] Setting the file: %s' % self.filename
905
905
906 self.__readFirstHeader()
906 self.__readFirstHeader()
907 self.nReadBlocks = 0
907 self.nReadBlocks = 0
908 return 1
908 return 1
909
909
910 def __waitNewBlock(self):
910 def __waitNewBlock(self):
911 """
911 """
912 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
912 Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma.
913
913
914 Si el modo de lectura es OffLine siempre retorn 0
914 Si el modo de lectura es OffLine siempre retorn 0
915 """
915 """
916 if not self.online:
916 if not self.online:
917 return 0
917 return 0
918
918
919 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
919 if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile):
920 return 0
920 return 0
921
921
922 currentPointer = self.fp.tell()
922 currentPointer = self.fp.tell()
923
923
924 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
924 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
925
925
926 for nTries in range(self.nTries):
926 for nTries in range(self.nTries):
927
927
928 self.fp.close()
928 self.fp.close()
929 self.fp = open(self.filename, 'rb')
929 self.fp = open(self.filename, 'rb')
930 self.fp.seek(currentPointer)
930 self.fp.seek(currentPointer)
931
931
932 self.fileSize = os.path.getsize(self.filename)
932 self.fileSize = os.path.getsize(self.filename)
933 currentSize = self.fileSize - currentPointer
933 currentSize = self.fileSize - currentPointer
934
934
935 if (currentSize >= neededSize):
935 if (currentSize >= neededSize):
936 self.basicHeaderObj.read(self.fp)
936 self.basicHeaderObj.read(self.fp)
937 return 1
937 return 1
938
938
939 if self.fileSize == self.fileSizeByHeader:
939 if self.fileSize == self.fileSizeByHeader:
940 # self.flagEoF = True
940 # self.flagEoF = True
941 return 0
941 return 0
942
942
943 print "[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1)
943 print "[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1)
944 sleep(self.delay)
944 sleep(self.delay)
945
945
946 return 0
946 return 0
947
947
948 def waitDataBlock(self, pointer_location):
948 def waitDataBlock(self, pointer_location):
949
949
950 currentPointer = pointer_location
950 currentPointer = pointer_location
951
951
952 neededSize = self.processingHeaderObj.blockSize # + self.basicHeaderSize
952 neededSize = self.processingHeaderObj.blockSize # + self.basicHeaderSize
953
953
954 for nTries in range(self.nTries):
954 for nTries in range(self.nTries):
955 self.fp.close()
955 self.fp.close()
956 self.fp = open(self.filename, 'rb')
956 self.fp = open(self.filename, 'rb')
957 self.fp.seek(currentPointer)
957 self.fp.seek(currentPointer)
958
958
959 self.fileSize = os.path.getsize(self.filename)
959 self.fileSize = os.path.getsize(self.filename)
960 currentSize = self.fileSize - currentPointer
960 currentSize = self.fileSize - currentPointer
961
961
962 if (currentSize >= neededSize):
962 if (currentSize >= neededSize):
963 return 1
963 return 1
964
964
965 print "[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1)
965 print "[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1)
966 sleep(self.delay)
966 sleep(self.delay)
967
967
968 return 0
968 return 0
969
969
970 def __jumpToLastBlock(self):
970 def __jumpToLastBlock(self):
971
971
972 if not(self.__isFirstTimeOnline):
972 if not(self.__isFirstTimeOnline):
973 return
973 return
974
974
975 csize = self.fileSize - self.fp.tell()
975 csize = self.fileSize - self.fp.tell()
976 blocksize = self.processingHeaderObj.blockSize
976 blocksize = self.processingHeaderObj.blockSize
977
977
978 # salta el primer bloque de datos
978 # salta el primer bloque de datos
979 if csize > self.processingHeaderObj.blockSize:
979 if csize > self.processingHeaderObj.blockSize:
980 self.fp.seek(self.fp.tell() + blocksize)
980 self.fp.seek(self.fp.tell() + blocksize)
981 else:
981 else:
982 return
982 return
983
983
984 csize = self.fileSize - self.fp.tell()
984 csize = self.fileSize - self.fp.tell()
985 neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
985 neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
986 while True:
986 while True:
987
987
988 if self.fp.tell() < self.fileSize:
988 if self.fp.tell() < self.fileSize:
989 self.fp.seek(self.fp.tell() + neededsize)
989 self.fp.seek(self.fp.tell() + neededsize)
990 else:
990 else:
991 self.fp.seek(self.fp.tell() - neededsize)
991 self.fp.seek(self.fp.tell() - neededsize)
992 break
992 break
993
993
994 # csize = self.fileSize - self.fp.tell()
994 # csize = self.fileSize - self.fp.tell()
995 # neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
995 # neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize
996 # factor = int(csize/neededsize)
996 # factor = int(csize/neededsize)
997 # if factor > 0:
997 # if factor > 0:
998 # self.fp.seek(self.fp.tell() + factor*neededsize)
998 # self.fp.seek(self.fp.tell() + factor*neededsize)
999
999
1000 self.flagIsNewFile = 0
1000 self.flagIsNewFile = 0
1001 self.__isFirstTimeOnline = 0
1001 self.__isFirstTimeOnline = 0
1002
1002
1003 def __setNewBlock(self):
1003 def __setNewBlock(self):
1004 # if self.server is None:
1004 # if self.server is None:
1005 if self.fp == None:
1005 if self.fp == None:
1006 return 0
1006 return 0
1007
1007
1008 # if self.online:
1008 # if self.online:
1009 # self.__jumpToLastBlock()
1009 # self.__jumpToLastBlock()
1010
1010
1011 if self.flagIsNewFile:
1011 if self.flagIsNewFile:
1012 self.lastUTTime = self.basicHeaderObj.utc
1012 self.lastUTTime = self.basicHeaderObj.utc
1013 return 1
1013 return 1
1014
1014
1015 if self.realtime:
1015 if self.realtime:
1016 self.flagDiscontinuousBlock = 1
1016 self.flagDiscontinuousBlock = 1
1017 if not(self.setNextFile()):
1017 if not(self.setNextFile()):
1018 return 0
1018 return 0
1019 else:
1019 else:
1020 return 1
1020 return 1
1021 # if self.server is None:
1021 # if self.server is None:
1022 currentSize = self.fileSize - self.fp.tell()
1022 currentSize = self.fileSize - self.fp.tell()
1023 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
1023 neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize
1024 if (currentSize >= neededSize):
1024 if (currentSize >= neededSize):
1025 self.basicHeaderObj.read(self.fp)
1025 self.basicHeaderObj.read(self.fp)
1026 self.lastUTTime = self.basicHeaderObj.utc
1026 self.lastUTTime = self.basicHeaderObj.utc
1027 return 1
1027 return 1
1028 # else:
1028 # else:
1029 # self.basicHeaderObj.read(self.zHeader)
1029 # self.basicHeaderObj.read(self.zHeader)
1030 # self.lastUTTime = self.basicHeaderObj.utc
1030 # self.lastUTTime = self.basicHeaderObj.utc
1031 # return 1
1031 # return 1
1032 if self.__waitNewBlock():
1032 if self.__waitNewBlock():
1033 self.lastUTTime = self.basicHeaderObj.utc
1033 self.lastUTTime = self.basicHeaderObj.utc
1034 return 1
1034 return 1
1035 # if self.server is None:
1035 # if self.server is None:
1036 if not(self.setNextFile()):
1036 if not(self.setNextFile()):
1037 return 0
1037 return 0
1038
1038
1039 deltaTime = self.basicHeaderObj.utc - self.lastUTTime
1039 deltaTime = self.basicHeaderObj.utc - self.lastUTTime
1040 self.lastUTTime = self.basicHeaderObj.utc
1040 self.lastUTTime = self.basicHeaderObj.utc
1041
1041
1042 self.flagDiscontinuousBlock = 0
1042 self.flagDiscontinuousBlock = 0
1043
1043
1044 if deltaTime > self.maxTimeStep:
1044 if deltaTime > self.maxTimeStep:
1045 self.flagDiscontinuousBlock = 1
1045 self.flagDiscontinuousBlock = 1
1046
1046
1047 return 1
1047 return 1
1048
1048
1049 def readNextBlock(self):
1049 def readNextBlock(self):
1050
1050
1051 # Skip block out of startTime and endTime
1051 # Skip block out of startTime and endTime
1052 while True:
1052 while True:
1053 if not(self.__setNewBlock()):
1053 if not(self.__setNewBlock()):
1054 return 0
1054 return 0
1055
1055
1056 if not(self.readBlock()):
1056 if not(self.readBlock()):
1057 return 0
1057 return 0
1058
1058
1059 self.getBasicHeader()
1059 self.getBasicHeader()
1060 if (self.dataOut.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or (self.dataOut.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
1060 if (self.dataOut.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or (self.dataOut.datatime > datetime.datetime.combine(self.endDate, self.endTime)):
1061 print "[Reading] Block No. %d/%d -> %s [Skipping]" % (self.nReadBlocks,
1061 print "[Reading] Block No. %d/%d -> %s [Skipping]" % (self.nReadBlocks,
1062 self.processingHeaderObj.dataBlocksPerFile,
1062 self.processingHeaderObj.dataBlocksPerFile,
1063 self.dataOut.datatime.ctime())
1063 self.dataOut.datatime.ctime())
1064 continue
1064 continue
1065
1065
1066 break
1066 break
1067
1067
1068 if self.verbose:
1068 if self.verbose:
1069 print "[Reading] Block No. %d/%d -> %s" % (self.nReadBlocks,
1069 print "[Reading] Block No. %d/%d -> %s" % (self.nReadBlocks,
1070 self.processingHeaderObj.dataBlocksPerFile,
1070 self.processingHeaderObj.dataBlocksPerFile,
1071 self.dataOut.datatime.ctime())
1071 self.dataOut.datatime.ctime())
1072 return 1
1072 return 1
1073
1073
1074 def __readFirstHeader(self):
1074 def __readFirstHeader(self):
1075
1075
1076 self.basicHeaderObj.read(self.fp)
1076 self.basicHeaderObj.read(self.fp)
1077 self.systemHeaderObj.read(self.fp)
1077 self.systemHeaderObj.read(self.fp)
1078 self.radarControllerHeaderObj.read(self.fp)
1078 self.radarControllerHeaderObj.read(self.fp)
1079 self.processingHeaderObj.read(self.fp)
1079 self.processingHeaderObj.read(self.fp)
1080
1080
1081 self.firstHeaderSize = self.basicHeaderObj.size
1081 self.firstHeaderSize = self.basicHeaderObj.size
1082
1082
1083 datatype = int(numpy.log2((self.processingHeaderObj.processFlags &
1083 datatype = int(numpy.log2((self.processingHeaderObj.processFlags &
1084 PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR))
1084 PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR))
1085 if datatype == 0:
1085 if datatype == 0:
1086 datatype_str = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
1086 datatype_str = numpy.dtype([('real', '<i1'), ('imag', '<i1')])
1087 elif datatype == 1:
1087 elif datatype == 1:
1088 datatype_str = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
1088 datatype_str = numpy.dtype([('real', '<i2'), ('imag', '<i2')])
1089 elif datatype == 2:
1089 elif datatype == 2:
1090 datatype_str = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
1090 datatype_str = numpy.dtype([('real', '<i4'), ('imag', '<i4')])
1091 elif datatype == 3:
1091 elif datatype == 3:
1092 datatype_str = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
1092 datatype_str = numpy.dtype([('real', '<i8'), ('imag', '<i8')])
1093 elif datatype == 4:
1093 elif datatype == 4:
1094 datatype_str = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
1094 datatype_str = numpy.dtype([('real', '<f4'), ('imag', '<f4')])
1095 elif datatype == 5:
1095 elif datatype == 5:
1096 datatype_str = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
1096 datatype_str = numpy.dtype([('real', '<f8'), ('imag', '<f8')])
1097 else:
1097 else:
1098 raise ValueError, 'Data type was not defined'
1098 raise ValueError, 'Data type was not defined'
1099
1099
1100 self.dtype = datatype_str
1100 self.dtype = datatype_str
1101 #self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
1101 #self.ippSeconds = 2 * 1000 * self.radarControllerHeaderObj.ipp / self.c
1102 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + \
1102 self.fileSizeByHeader = self.processingHeaderObj.dataBlocksPerFile * self.processingHeaderObj.blockSize + \
1103 self.firstHeaderSize + self.basicHeaderSize * \
1103 self.firstHeaderSize + self.basicHeaderSize * \
1104 (self.processingHeaderObj.dataBlocksPerFile - 1)
1104 (self.processingHeaderObj.dataBlocksPerFile - 1)
1105 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
1105 # self.dataOut.channelList = numpy.arange(self.systemHeaderObj.numChannels)
1106 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
1106 # self.dataOut.channelIndexList = numpy.arange(self.systemHeaderObj.numChannels)
1107 self.getBlockDimension()
1107 self.getBlockDimension()
1108
1108
1109 def __verifyFile(self, filename, msgFlag=True):
1109 def __verifyFile(self, filename, msgFlag=True):
1110
1110
1111 msg = None
1111 msg = None
1112
1112
1113 try:
1113 try:
1114 fp = open(filename, 'rb')
1114 fp = open(filename, 'rb')
1115 except IOError:
1115 except IOError:
1116
1116
1117 if msgFlag:
1117 if msgFlag:
1118 print "[Reading] File %s can't be opened" % (filename)
1118 print "[Reading] File %s can't be opened" % (filename)
1119
1119
1120 return False
1120 return False
1121
1121
1122 currentPosition = fp.tell()
1122 currentPosition = fp.tell()
1123 neededSize = self.processingHeaderObj.blockSize + self.firstHeaderSize
1123 neededSize = self.processingHeaderObj.blockSize + self.firstHeaderSize
1124
1124
1125 if neededSize == 0:
1125 if neededSize == 0:
1126 basicHeaderObj = BasicHeader(LOCALTIME)
1126 basicHeaderObj = BasicHeader(LOCALTIME)
1127 systemHeaderObj = SystemHeader()
1127 systemHeaderObj = SystemHeader()
1128 radarControllerHeaderObj = RadarControllerHeader()
1128 radarControllerHeaderObj = RadarControllerHeader()
1129 processingHeaderObj = ProcessingHeader()
1129 processingHeaderObj = ProcessingHeader()
1130
1130
1131 if not(basicHeaderObj.read(fp)):
1131 if not(basicHeaderObj.read(fp)):
1132 fp.close()
1132 fp.close()
1133 return False
1133 return False
1134
1134
1135 if not(systemHeaderObj.read(fp)):
1135 if not(systemHeaderObj.read(fp)):
1136 fp.close()
1136 fp.close()
1137 return False
1137 return False
1138
1138
1139 if not(radarControllerHeaderObj.read(fp)):
1139 if not(radarControllerHeaderObj.read(fp)):
1140 fp.close()
1140 fp.close()
1141 return False
1141 return False
1142
1142
1143 if not(processingHeaderObj.read(fp)):
1143 if not(processingHeaderObj.read(fp)):
1144 fp.close()
1144 fp.close()
1145 return False
1145 return False
1146
1146
1147 neededSize = processingHeaderObj.blockSize + basicHeaderObj.size
1147 neededSize = processingHeaderObj.blockSize + basicHeaderObj.size
1148 else:
1148 else:
1149 msg = "[Reading] Skipping the file %s due to it hasn't enough data" % filename
1149 msg = "[Reading] Skipping the file %s due to it hasn't enough data" % filename
1150
1150
1151 fp.close()
1151 fp.close()
1152
1152
1153 fileSize = os.path.getsize(filename)
1153 fileSize = os.path.getsize(filename)
1154 currentSize = fileSize - currentPosition
1154 currentSize = fileSize - currentPosition
1155
1155
1156 if currentSize < neededSize:
1156 if currentSize < neededSize:
1157 if msgFlag and (msg != None):
1157 if msgFlag and (msg != None):
1158 print msg
1158 print msg
1159 return False
1159 return False
1160
1160
1161 return True
1161 return True
1162
1162
1163 def findDatafiles(self, path, startDate=None, endDate=None, expLabel='', ext='.r', walk=True, include_path=False):
1163 def findDatafiles(self, path, startDate=None, endDate=None, expLabel='', ext='.r', walk=True, include_path=False):
1164
1164
1165 path_empty = True
1165 path_empty = True
1166
1166
1167 dateList = []
1167 dateList = []
1168 pathList = []
1168 pathList = []
1169
1169
1170 multi_path = path.split(',')
1170 multi_path = path.split(',')
1171
1171
1172 if not walk:
1172 if not walk:
1173
1173
1174 for single_path in multi_path:
1174 for single_path in multi_path:
1175
1175
1176 if not os.path.isdir(single_path):
1176 if not os.path.isdir(single_path):
1177 continue
1177 continue
1178
1178
1179 fileList = glob.glob1(single_path, "*" + ext)
1179 fileList = glob.glob1(single_path, "*" + ext)
1180
1180
1181 if not fileList:
1181 if not fileList:
1182 continue
1182 continue
1183
1183
1184 path_empty = False
1184 path_empty = False
1185
1185
1186 fileList.sort()
1186 fileList.sort()
1187
1187
1188 for thisFile in fileList:
1188 for thisFile in fileList:
1189
1189
1190 if not os.path.isfile(os.path.join(single_path, thisFile)):
1190 if not os.path.isfile(os.path.join(single_path, thisFile)):
1191 continue
1191 continue
1192
1192
1193 if not isRadarFile(thisFile):
1193 if not isRadarFile(thisFile):
1194 continue
1194 continue
1195
1195
1196 if not isFileInDateRange(thisFile, startDate, endDate):
1196 if not isFileInDateRange(thisFile, startDate, endDate):
1197 continue
1197 continue
1198
1198
1199 thisDate = getDateFromRadarFile(thisFile)
1199 thisDate = getDateFromRadarFile(thisFile)
1200
1200
1201 if thisDate in dateList:
1201 if thisDate in dateList:
1202 continue
1202 continue
1203
1203
1204 dateList.append(thisDate)
1204 dateList.append(thisDate)
1205 pathList.append(single_path)
1205 pathList.append(single_path)
1206
1206
1207 else:
1207 else:
1208 for single_path in multi_path:
1208 for single_path in multi_path:
1209
1209
1210 if not os.path.isdir(single_path):
1210 if not os.path.isdir(single_path):
1211 continue
1211 continue
1212
1212
1213 dirList = []
1213 dirList = []
1214
1214
1215 for thisPath in os.listdir(single_path):
1215 for thisPath in os.listdir(single_path):
1216
1216
1217 if not os.path.isdir(os.path.join(single_path, thisPath)):
1217 if not os.path.isdir(os.path.join(single_path, thisPath)):
1218 continue
1218 continue
1219
1219
1220 if not isRadarFolder(thisPath):
1220 if not isRadarFolder(thisPath):
1221 continue
1221 continue
1222
1222
1223 if not isFolderInDateRange(thisPath, startDate, endDate):
1223 if not isFolderInDateRange(thisPath, startDate, endDate):
1224 continue
1224 continue
1225
1225
1226 dirList.append(thisPath)
1226 dirList.append(thisPath)
1227
1227
1228 if not dirList:
1228 if not dirList:
1229 continue
1229 continue
1230
1230
1231 dirList.sort()
1231 dirList.sort()
1232
1232
1233 for thisDir in dirList:
1233 for thisDir in dirList:
1234
1234
1235 datapath = os.path.join(single_path, thisDir, expLabel)
1235 datapath = os.path.join(single_path, thisDir, expLabel)
1236 fileList = glob.glob1(datapath, "*" + ext)
1236 fileList = glob.glob1(datapath, "*" + ext)
1237
1237
1238 if not fileList:
1238 if not fileList:
1239 continue
1239 continue
1240
1240
1241 path_empty = False
1241 path_empty = False
1242
1242
1243 thisDate = getDateFromRadarFolder(thisDir)
1243 thisDate = getDateFromRadarFolder(thisDir)
1244
1244
1245 pathList.append(datapath)
1245 pathList.append(datapath)
1246 dateList.append(thisDate)
1246 dateList.append(thisDate)
1247
1247
1248 dateList.sort()
1248 dateList.sort()
1249
1249
1250 if walk:
1250 if walk:
1251 pattern_path = os.path.join(multi_path[0], "[dYYYYDDD]", expLabel)
1251 pattern_path = os.path.join(multi_path[0], "[dYYYYDDD]", expLabel)
1252 else:
1252 else:
1253 pattern_path = multi_path[0]
1253 pattern_path = multi_path[0]
1254
1254
1255 if path_empty:
1255 if path_empty:
1256 print "[Reading] No *%s files in %s for %s to %s" % (ext, pattern_path, startDate, endDate)
1256 print "[Reading] No *%s files in %s for %s to %s" % (ext, pattern_path, startDate, endDate)
1257 else:
1257 else:
1258 if not dateList:
1258 if not dateList:
1259 print "[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" % (startDate, endDate, ext, path)
1259 print "[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" % (startDate, endDate, ext, path)
1260
1260
1261 if include_path:
1261 if include_path:
1262 return dateList, pathList
1262 return dateList, pathList
1263
1263
1264 return dateList
1264 return dateList
1265
1265
1266 def setup(self,
1266 def setup(self,
1267 path=None,
1267 path=None,
1268 startDate=None,
1268 startDate=None,
1269 endDate=None,
1269 endDate=None,
1270 startTime=datetime.time(0, 0, 0),
1270 startTime=datetime.time(0, 0, 0),
1271 endTime=datetime.time(23, 59, 59),
1271 endTime=datetime.time(23, 59, 59),
1272 set=None,
1272 set=None,
1273 expLabel="",
1273 expLabel="",
1274 ext=None,
1274 ext=None,
1275 online=False,
1275 online=False,
1276 delay=60,
1276 delay=60,
1277 walk=True,
1277 walk=True,
1278 getblock=False,
1278 getblock=False,
1279 nTxs=1,
1279 nTxs=1,
1280 realtime=False,
1280 realtime=False,
1281 blocksize=None,
1281 blocksize=None,
1282 blocktime=None,
1282 blocktime=None,
1283 skip=None,
1283 skip=None,
1284 cursor=None,
1284 cursor=None,
1285 warnings=True,
1285 warnings=True,
1286 verbose=True,
1286 verbose=True,
1287 server=None,
1287 server=None,
1288 format=None,
1288 format=None,
1289 oneDDict=None,
1289 oneDDict=None,
1290 twoDDict=None,
1290 twoDDict=None,
1291 ind2DList=None):
1291 ind2DList=None):
1292 if server is not None:
1292 if server is not None:
1293 if 'tcp://' in server:
1293 if 'tcp://' in server:
1294 address = server
1294 address = server
1295 else:
1295 else:
1296 address = 'ipc:///tmp/%s' % server
1296 address = 'ipc:///tmp/%s' % server
1297 self.server = address
1297 self.server = address
1298 self.context = zmq.Context()
1298 self.context = zmq.Context()
1299 self.receiver = self.context.socket(zmq.PULL)
1299 self.receiver = self.context.socket(zmq.PULL)
1300 self.receiver.connect(self.server)
1300 self.receiver.connect(self.server)
1301 time.sleep(0.5)
1301 time.sleep(0.5)
1302 print '[Starting] ReceiverData from {}'.format(self.server)
1302 print '[Starting] ReceiverData from {}'.format(self.server)
1303 else:
1303 else:
1304 self.server = None
1304 self.server = None
1305 if path == None:
1305 if path == None:
1306 raise ValueError, "[Reading] The path is not valid"
1306 raise ValueError, "[Reading] The path is not valid"
1307
1307
1308 if ext == None:
1308 if ext == None:
1309 ext = self.ext
1309 ext = self.ext
1310
1310
1311 if online:
1311 if online:
1312 print "[Reading] Searching files in online mode..."
1312 print "[Reading] Searching files in online mode..."
1313
1313
1314 for nTries in range(self.nTries):
1314 for nTries in range(self.nTries):
1315 fullpath, foldercounter, file, year, doy, set = self.__searchFilesOnLine(
1315 fullpath, foldercounter, file, year, doy, set = self.__searchFilesOnLine(
1316 path=path, expLabel=expLabel, ext=ext, walk=walk, set=set)
1316 path=path, expLabel=expLabel, ext=ext, walk=walk, set=set)
1317
1317
1318 if fullpath:
1318 if fullpath:
1319 break
1319 break
1320
1320
1321 print '[Reading] Waiting %0.2f sec for an valid file in %s: try %02d ...' % (self.delay, path, nTries + 1)
1321 print '[Reading] Waiting %0.2f sec for an valid file in %s: try %02d ...' % (delay, path, nTries + 1)
1322 sleep(self.delay)
1322 sleep(delay)
1323
1323
1324 if not(fullpath):
1324 if not(fullpath):
1325 print "[Reading] There 'isn't any valid file in %s" % path
1325 raise schainpy.admin.SchainWarning('There isn\'t any valid file in {}'.format(path))
1326 return
1326 return
1327
1327
1328 self.year = year
1328 self.year = year
1329 self.doy = doy
1329 self.doy = doy
1330 self.set = set - 1
1330 self.set = set - 1
1331 self.path = path
1331 self.path = path
1332 self.foldercounter = foldercounter
1332 self.foldercounter = foldercounter
1333 last_set = None
1333 last_set = None
1334 else:
1334 else:
1335 print "[Reading] Searching files in offline mode ..."
1335 print "[Reading] Searching files in offline mode ..."
1336 pathList, filenameList = self.searchFilesOffLine(path, startDate=startDate, endDate=endDate,
1336 pathList, filenameList = self.searchFilesOffLine(path, startDate=startDate, endDate=endDate,
1337 startTime=startTime, endTime=endTime,
1337 startTime=startTime, endTime=endTime,
1338 set=set, expLabel=expLabel, ext=ext,
1338 set=set, expLabel=expLabel, ext=ext,
1339 walk=walk, cursor=cursor,
1339 walk=walk, cursor=cursor,
1340 skip=skip)
1340 skip=skip)
1341
1341
1342 if not(pathList):
1342 if not(pathList):
1343 self.fileIndex = -1
1343 self.fileIndex = -1
1344 self.pathList = []
1344 self.pathList = []
1345 self.filenameList = []
1345 self.filenameList = []
1346 return
1346 return
1347
1347
1348 self.fileIndex = -1
1348 self.fileIndex = -1
1349 self.pathList = pathList
1349 self.pathList = pathList
1350 self.filenameList = filenameList
1350 self.filenameList = filenameList
1351 file_name = os.path.basename(filenameList[-1])
1351 file_name = os.path.basename(filenameList[-1])
1352 basename, ext = os.path.splitext(file_name)
1352 basename, ext = os.path.splitext(file_name)
1353 last_set = int(basename[-3:])
1353 last_set = int(basename[-3:])
1354
1354
1355 self.online = online
1355 self.online = online
1356 self.realtime = realtime
1356 self.realtime = realtime
1357 self.delay = delay
1357 self.delay = delay
1358 ext = ext.lower()
1358 ext = ext.lower()
1359 self.ext = ext
1359 self.ext = ext
1360 self.getByBlock = getblock
1360 self.getByBlock = getblock
1361 self.nTxs = nTxs
1361 self.nTxs = nTxs
1362 self.startTime = startTime
1362 self.startTime = startTime
1363 self.endTime = endTime
1363 self.endTime = endTime
1364 self.endDate = endDate
1364 self.endDate = endDate
1365 self.startDate = startDate
1365 self.startDate = startDate
1366 # Added-----------------
1366 # Added-----------------
1367 self.selBlocksize = blocksize
1367 self.selBlocksize = blocksize
1368 self.selBlocktime = blocktime
1368 self.selBlocktime = blocktime
1369
1369
1370 # Verbose-----------
1370 # Verbose-----------
1371 self.verbose = verbose
1371 self.verbose = verbose
1372 self.warnings = warnings
1372 self.warnings = warnings
1373
1373
1374 if not(self.setNextFile()):
1374 if not(self.setNextFile()):
1375 if (startDate != None) and (endDate != None):
1375 if (startDate != None) and (endDate != None):
1376 print "[Reading] No files in range: %s - %s" % (datetime.datetime.combine(startDate, startTime).ctime(), datetime.datetime.combine(endDate, endTime).ctime())
1376 print "[Reading] No files in range: %s - %s" % (datetime.datetime.combine(startDate, startTime).ctime(), datetime.datetime.combine(endDate, endTime).ctime())
1377 elif startDate != None:
1377 elif startDate != None:
1378 print "[Reading] No files in range: %s" % (datetime.datetime.combine(startDate, startTime).ctime())
1378 print "[Reading] No files in range: %s" % (datetime.datetime.combine(startDate, startTime).ctime())
1379 else:
1379 else:
1380 print "[Reading] No files"
1380 print "[Reading] No files"
1381
1381
1382 self.fileIndex = -1
1382 self.fileIndex = -1
1383 self.pathList = []
1383 self.pathList = []
1384 self.filenameList = []
1384 self.filenameList = []
1385 return
1385 return
1386
1386
1387 # self.getBasicHeader()
1387 # self.getBasicHeader()
1388
1388
1389 if last_set != None:
1389 if last_set != None:
1390 self.dataOut.last_block = last_set * \
1390 self.dataOut.last_block = last_set * \
1391 self.processingHeaderObj.dataBlocksPerFile + self.basicHeaderObj.dataBlock
1391 self.processingHeaderObj.dataBlocksPerFile + self.basicHeaderObj.dataBlock
1392 return
1392 return
1393
1393
1394 def getBasicHeader(self):
1394 def getBasicHeader(self):
1395
1395
1396 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond / \
1396 self.dataOut.utctime = self.basicHeaderObj.utc + self.basicHeaderObj.miliSecond / \
1397 1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds
1397 1000. + self.profileIndex * self.radarControllerHeaderObj.ippSeconds
1398
1398
1399 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
1399 self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock
1400
1400
1401 self.dataOut.timeZone = self.basicHeaderObj.timeZone
1401 self.dataOut.timeZone = self.basicHeaderObj.timeZone
1402
1402
1403 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
1403 self.dataOut.dstFlag = self.basicHeaderObj.dstFlag
1404
1404
1405 self.dataOut.errorCount = self.basicHeaderObj.errorCount
1405 self.dataOut.errorCount = self.basicHeaderObj.errorCount
1406
1406
1407 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
1407 self.dataOut.useLocalTime = self.basicHeaderObj.useLocalTime
1408
1408
1409 self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
1409 self.dataOut.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs
1410
1410
1411 # self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock*self.nTxs
1411 # self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock*self.nTxs
1412
1412
1413 def getFirstHeader(self):
1413 def getFirstHeader(self):
1414
1414
1415 raise NotImplementedError
1415 raise NotImplementedError
1416
1416
1417 def getData(self):
1417 def getData(self):
1418
1418
1419 raise NotImplementedError
1419 raise NotImplementedError
1420
1420
1421 def hasNotDataInBuffer(self):
1421 def hasNotDataInBuffer(self):
1422
1422
1423 raise NotImplementedError
1423 raise NotImplementedError
1424
1424
1425 def readBlock(self):
1425 def readBlock(self):
1426
1426
1427 raise NotImplementedError
1427 raise NotImplementedError
1428
1428
1429 def isEndProcess(self):
1429 def isEndProcess(self):
1430
1430
1431 return self.flagNoMoreFiles
1431 return self.flagNoMoreFiles
1432
1432
1433 def printReadBlocks(self):
1433 def printReadBlocks(self):
1434
1434
1435 print "[Reading] Number of read blocks per file %04d" % self.nReadBlocks
1435 print "[Reading] Number of read blocks per file %04d" % self.nReadBlocks
1436
1436
1437 def printTotalBlocks(self):
1437 def printTotalBlocks(self):
1438
1438
1439 print "[Reading] Number of read blocks %04d" % self.nTotalBlocks
1439 print "[Reading] Number of read blocks %04d" % self.nTotalBlocks
1440
1440
1441 def printNumberOfBlock(self):
1441 def printNumberOfBlock(self):
1442 'SPAM!'
1442 'SPAM!'
1443
1443
1444 # if self.flagIsNewBlock:
1444 # if self.flagIsNewBlock:
1445 # print "[Reading] Block No. %d/%d -> %s" %(self.nReadBlocks,
1445 # print "[Reading] Block No. %d/%d -> %s" %(self.nReadBlocks,
1446 # self.processingHeaderObj.dataBlocksPerFile,
1446 # self.processingHeaderObj.dataBlocksPerFile,
1447 # self.dataOut.datatime.ctime())
1447 # self.dataOut.datatime.ctime())
1448
1448
1449 def printInfo(self):
1449 def printInfo(self):
1450
1450
1451 if self.__printInfo == False:
1451 if self.__printInfo == False:
1452 return
1452 return
1453
1453
1454 self.basicHeaderObj.printInfo()
1454 self.basicHeaderObj.printInfo()
1455 self.systemHeaderObj.printInfo()
1455 self.systemHeaderObj.printInfo()
1456 self.radarControllerHeaderObj.printInfo()
1456 self.radarControllerHeaderObj.printInfo()
1457 self.processingHeaderObj.printInfo()
1457 self.processingHeaderObj.printInfo()
1458
1458
1459 self.__printInfo = False
1459 self.__printInfo = False
1460
1460
1461 def run(self,
1461 def run(self,
1462 path=None,
1462 path=None,
1463 startDate=None,
1463 startDate=None,
1464 endDate=None,
1464 endDate=None,
1465 startTime=datetime.time(0, 0, 0),
1465 startTime=datetime.time(0, 0, 0),
1466 endTime=datetime.time(23, 59, 59),
1466 endTime=datetime.time(23, 59, 59),
1467 set=None,
1467 set=None,
1468 expLabel="",
1468 expLabel="",
1469 ext=None,
1469 ext=None,
1470 online=False,
1470 online=False,
1471 delay=60,
1471 delay=60,
1472 walk=True,
1472 walk=True,
1473 getblock=False,
1473 getblock=False,
1474 nTxs=1,
1474 nTxs=1,
1475 realtime=False,
1475 realtime=False,
1476 blocksize=None,
1476 blocksize=None,
1477 blocktime=None,
1477 blocktime=None,
1478 skip=None,
1478 skip=None,
1479 cursor=None,
1479 cursor=None,
1480 warnings=True,
1480 warnings=True,
1481 server=None,
1481 server=None,
1482 verbose=True,
1482 verbose=True,
1483 format=None,
1483 format=None,
1484 oneDDict=None,
1484 oneDDict=None,
1485 twoDDict=None,
1485 twoDDict=None,
1486 ind2DList=None, **kwargs):
1486 ind2DList=None, **kwargs):
1487
1487
1488 if not(self.isConfig):
1488 if not(self.isConfig):
1489 self.setup(path=path,
1489 self.setup(path=path,
1490 startDate=startDate,
1490 startDate=startDate,
1491 endDate=endDate,
1491 endDate=endDate,
1492 startTime=startTime,
1492 startTime=startTime,
1493 endTime=endTime,
1493 endTime=endTime,
1494 set=set,
1494 set=set,
1495 expLabel=expLabel,
1495 expLabel=expLabel,
1496 ext=ext,
1496 ext=ext,
1497 online=online,
1497 online=online,
1498 delay=delay,
1498 delay=delay,
1499 walk=walk,
1499 walk=walk,
1500 getblock=getblock,
1500 getblock=getblock,
1501 nTxs=nTxs,
1501 nTxs=nTxs,
1502 realtime=realtime,
1502 realtime=realtime,
1503 blocksize=blocksize,
1503 blocksize=blocksize,
1504 blocktime=blocktime,
1504 blocktime=blocktime,
1505 skip=skip,
1505 skip=skip,
1506 cursor=cursor,
1506 cursor=cursor,
1507 warnings=warnings,
1507 warnings=warnings,
1508 server=server,
1508 server=server,
1509 verbose=verbose,
1509 verbose=verbose,
1510 format=format,
1510 format=format,
1511 oneDDict=oneDDict,
1511 oneDDict=oneDDict,
1512 twoDDict=twoDDict,
1512 twoDDict=twoDDict,
1513 ind2DList=ind2DList)
1513 ind2DList=ind2DList)
1514 self.isConfig = True
1514 self.isConfig = True
1515 if server is None:
1515 if server is None:
1516 self.getData()
1516 self.getData()
1517 else:
1517 else:
1518 self.getFromServer()
1518 self.getFromServer()
1519
1519
1520
1520
1521 class JRODataWriter(JRODataIO):
1521 class JRODataWriter(JRODataIO):
1522
1522
1523 """
1523 """
1524 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1524 Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura
1525 de los datos siempre se realiza por bloques.
1525 de los datos siempre se realiza por bloques.
1526 """
1526 """
1527
1527
1528 blockIndex = 0
1528 blockIndex = 0
1529
1529
1530 path = None
1530 path = None
1531
1531
1532 setFile = None
1532 setFile = None
1533
1533
1534 profilesPerBlock = None
1534 profilesPerBlock = None
1535
1535
1536 blocksPerFile = None
1536 blocksPerFile = None
1537
1537
1538 nWriteBlocks = 0
1538 nWriteBlocks = 0
1539
1539
1540 fileDate = None
1540 fileDate = None
1541
1541
1542 def __init__(self, dataOut=None):
1542 def __init__(self, dataOut=None):
1543 raise NotImplementedError
1543 raise NotImplementedError
1544
1544
1545 def hasAllDataInBuffer(self):
1545 def hasAllDataInBuffer(self):
1546 raise NotImplementedError
1546 raise NotImplementedError
1547
1547
1548 def setBlockDimension(self):
1548 def setBlockDimension(self):
1549 raise NotImplementedError
1549 raise NotImplementedError
1550
1550
1551 def writeBlock(self):
1551 def writeBlock(self):
1552 raise NotImplementedError
1552 raise NotImplementedError
1553
1553
1554 def putData(self):
1554 def putData(self):
1555 raise NotImplementedError
1555 raise NotImplementedError
1556
1556
1557 def getProcessFlags(self):
1557 def getProcessFlags(self):
1558
1558
1559 processFlags = 0
1559 processFlags = 0
1560
1560
1561 dtype_index = get_dtype_index(self.dtype)
1561 dtype_index = get_dtype_index(self.dtype)
1562 procflag_dtype = get_procflag_dtype(dtype_index)
1562 procflag_dtype = get_procflag_dtype(dtype_index)
1563
1563
1564 processFlags += procflag_dtype
1564 processFlags += procflag_dtype
1565
1565
1566 if self.dataOut.flagDecodeData:
1566 if self.dataOut.flagDecodeData:
1567 processFlags += PROCFLAG.DECODE_DATA
1567 processFlags += PROCFLAG.DECODE_DATA
1568
1568
1569 if self.dataOut.flagDeflipData:
1569 if self.dataOut.flagDeflipData:
1570 processFlags += PROCFLAG.DEFLIP_DATA
1570 processFlags += PROCFLAG.DEFLIP_DATA
1571
1571
1572 if self.dataOut.code is not None:
1572 if self.dataOut.code is not None:
1573 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1573 processFlags += PROCFLAG.DEFINE_PROCESS_CODE
1574
1574
1575 if self.dataOut.nCohInt > 1:
1575 if self.dataOut.nCohInt > 1:
1576 processFlags += PROCFLAG.COHERENT_INTEGRATION
1576 processFlags += PROCFLAG.COHERENT_INTEGRATION
1577
1577
1578 if self.dataOut.type == "Spectra":
1578 if self.dataOut.type == "Spectra":
1579 if self.dataOut.nIncohInt > 1:
1579 if self.dataOut.nIncohInt > 1:
1580 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
1580 processFlags += PROCFLAG.INCOHERENT_INTEGRATION
1581
1581
1582 if self.dataOut.data_dc is not None:
1582 if self.dataOut.data_dc is not None:
1583 processFlags += PROCFLAG.SAVE_CHANNELS_DC
1583 processFlags += PROCFLAG.SAVE_CHANNELS_DC
1584
1584
1585 if self.dataOut.flagShiftFFT:
1585 if self.dataOut.flagShiftFFT:
1586 processFlags += PROCFLAG.SHIFT_FFT_DATA
1586 processFlags += PROCFLAG.SHIFT_FFT_DATA
1587
1587
1588 return processFlags
1588 return processFlags
1589
1589
1590 def setBasicHeader(self):
1590 def setBasicHeader(self):
1591
1591
1592 self.basicHeaderObj.size = self.basicHeaderSize # bytes
1592 self.basicHeaderObj.size = self.basicHeaderSize # bytes
1593 self.basicHeaderObj.version = self.versionFile
1593 self.basicHeaderObj.version = self.versionFile
1594 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1594 self.basicHeaderObj.dataBlock = self.nTotalBlocks
1595
1595
1596 utc = numpy.floor(self.dataOut.utctime)
1596 utc = numpy.floor(self.dataOut.utctime)
1597 milisecond = (self.dataOut.utctime - utc) * 1000.0
1597 milisecond = (self.dataOut.utctime - utc) * 1000.0
1598
1598
1599 self.basicHeaderObj.utc = utc
1599 self.basicHeaderObj.utc = utc
1600 self.basicHeaderObj.miliSecond = milisecond
1600 self.basicHeaderObj.miliSecond = milisecond
1601 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1601 self.basicHeaderObj.timeZone = self.dataOut.timeZone
1602 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1602 self.basicHeaderObj.dstFlag = self.dataOut.dstFlag
1603 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1603 self.basicHeaderObj.errorCount = self.dataOut.errorCount
1604
1604
1605 def setFirstHeader(self):
1605 def setFirstHeader(self):
1606 """
1606 """
1607 Obtiene una copia del First Header
1607 Obtiene una copia del First Header
1608
1608
1609 Affected:
1609 Affected:
1610
1610
1611 self.basicHeaderObj
1611 self.basicHeaderObj
1612 self.systemHeaderObj
1612 self.systemHeaderObj
1613 self.radarControllerHeaderObj
1613 self.radarControllerHeaderObj
1614 self.processingHeaderObj self.
1614 self.processingHeaderObj self.
1615
1615
1616 Return:
1616 Return:
1617 None
1617 None
1618 """
1618 """
1619
1619
1620 raise NotImplementedError
1620 raise NotImplementedError
1621
1621
1622 def __writeFirstHeader(self):
1622 def __writeFirstHeader(self):
1623 """
1623 """
1624 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1624 Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader)
1625
1625
1626 Affected:
1626 Affected:
1627 __dataType
1627 __dataType
1628
1628
1629 Return:
1629 Return:
1630 None
1630 None
1631 """
1631 """
1632
1632
1633 # CALCULAR PARAMETROS
1633 # CALCULAR PARAMETROS
1634
1634
1635 sizeLongHeader = self.systemHeaderObj.size + \
1635 sizeLongHeader = self.systemHeaderObj.size + \
1636 self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1636 self.radarControllerHeaderObj.size + self.processingHeaderObj.size
1637 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1637 self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader
1638
1638
1639 self.basicHeaderObj.write(self.fp)
1639 self.basicHeaderObj.write(self.fp)
1640 self.systemHeaderObj.write(self.fp)
1640 self.systemHeaderObj.write(self.fp)
1641 self.radarControllerHeaderObj.write(self.fp)
1641 self.radarControllerHeaderObj.write(self.fp)
1642 self.processingHeaderObj.write(self.fp)
1642 self.processingHeaderObj.write(self.fp)
1643
1643
1644 def __setNewBlock(self):
1644 def __setNewBlock(self):
1645 """
1645 """
1646 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1646 Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header
1647
1647
1648 Return:
1648 Return:
1649 0 : si no pudo escribir nada
1649 0 : si no pudo escribir nada
1650 1 : Si escribio el Basic el First Header
1650 1 : Si escribio el Basic el First Header
1651 """
1651 """
1652 if self.fp == None:
1652 if self.fp == None:
1653 self.setNextFile()
1653 self.setNextFile()
1654
1654
1655 if self.flagIsNewFile:
1655 if self.flagIsNewFile:
1656 return 1
1656 return 1
1657
1657
1658 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1658 if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile:
1659 self.basicHeaderObj.write(self.fp)
1659 self.basicHeaderObj.write(self.fp)
1660 return 1
1660 return 1
1661
1661
1662 if not(self.setNextFile()):
1662 if not(self.setNextFile()):
1663 return 0
1663 return 0
1664
1664
1665 return 1
1665 return 1
1666
1666
1667 def writeNextBlock(self):
1667 def writeNextBlock(self):
1668 """
1668 """
1669 Selecciona el bloque siguiente de datos y los escribe en un file
1669 Selecciona el bloque siguiente de datos y los escribe en un file
1670
1670
1671 Return:
1671 Return:
1672 0 : Si no hizo pudo escribir el bloque de datos
1672 0 : Si no hizo pudo escribir el bloque de datos
1673 1 : Si no pudo escribir el bloque de datos
1673 1 : Si no pudo escribir el bloque de datos
1674 """
1674 """
1675 if not(self.__setNewBlock()):
1675 if not(self.__setNewBlock()):
1676 return 0
1676 return 0
1677
1677
1678 self.writeBlock()
1678 self.writeBlock()
1679
1679
1680 print "[Writing] Block No. %d/%d" % (self.blockIndex,
1680 print "[Writing] Block No. %d/%d" % (self.blockIndex,
1681 self.processingHeaderObj.dataBlocksPerFile)
1681 self.processingHeaderObj.dataBlocksPerFile)
1682
1682
1683 return 1
1683 return 1
1684
1684
1685 def setNextFile(self):
1685 def setNextFile(self):
1686 """
1686 """
1687 Determina el siguiente file que sera escrito
1687 Determina el siguiente file que sera escrito
1688
1688
1689 Affected:
1689 Affected:
1690 self.filename
1690 self.filename
1691 self.subfolder
1691 self.subfolder
1692 self.fp
1692 self.fp
1693 self.setFile
1693 self.setFile
1694 self.flagIsNewFile
1694 self.flagIsNewFile
1695
1695
1696 Return:
1696 Return:
1697 0 : Si el archivo no puede ser escrito
1697 0 : Si el archivo no puede ser escrito
1698 1 : Si el archivo esta listo para ser escrito
1698 1 : Si el archivo esta listo para ser escrito
1699 """
1699 """
1700 ext = self.ext
1700 ext = self.ext
1701 path = self.path
1701 path = self.path
1702
1702
1703 if self.fp != None:
1703 if self.fp != None:
1704 self.fp.close()
1704 self.fp.close()
1705
1705
1706 timeTuple = time.localtime(self.dataOut.utctime)
1706 timeTuple = time.localtime(self.dataOut.utctime)
1707 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year, timeTuple.tm_yday)
1707 subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year, timeTuple.tm_yday)
1708
1708
1709 fullpath = os.path.join(path, subfolder)
1709 fullpath = os.path.join(path, subfolder)
1710 setFile = self.setFile
1710 setFile = self.setFile
1711
1711
1712 if not(os.path.exists(fullpath)):
1712 if not(os.path.exists(fullpath)):
1713 os.mkdir(fullpath)
1713 os.mkdir(fullpath)
1714 setFile = -1 # inicializo mi contador de seteo
1714 setFile = -1 # inicializo mi contador de seteo
1715 else:
1715 else:
1716 filesList = os.listdir(fullpath)
1716 filesList = os.listdir(fullpath)
1717 if len(filesList) > 0:
1717 if len(filesList) > 0:
1718 filesList = sorted(filesList, key=str.lower)
1718 filesList = sorted(filesList, key=str.lower)
1719 filen = filesList[-1]
1719 filen = filesList[-1]
1720 # el filename debera tener el siguiente formato
1720 # el filename debera tener el siguiente formato
1721 # 0 1234 567 89A BCDE (hex)
1721 # 0 1234 567 89A BCDE (hex)
1722 # x YYYY DDD SSS .ext
1722 # x YYYY DDD SSS .ext
1723 if isNumber(filen[8:11]):
1723 if isNumber(filen[8:11]):
1724 # inicializo mi contador de seteo al seteo del ultimo file
1724 # inicializo mi contador de seteo al seteo del ultimo file
1725 setFile = int(filen[8:11])
1725 setFile = int(filen[8:11])
1726 else:
1726 else:
1727 setFile = -1
1727 setFile = -1
1728 else:
1728 else:
1729 setFile = -1 # inicializo mi contador de seteo
1729 setFile = -1 # inicializo mi contador de seteo
1730
1730
1731 setFile += 1
1731 setFile += 1
1732
1732
1733 # If this is a new day it resets some values
1733 # If this is a new day it resets some values
1734 if self.dataOut.datatime.date() > self.fileDate:
1734 if self.dataOut.datatime.date() > self.fileDate:
1735 setFile = 0
1735 setFile = 0
1736 self.nTotalBlocks = 0
1736 self.nTotalBlocks = 0
1737
1737
1738 filen = '{}{:04d}{:03d}{:03d}{}'.format(
1738 filen = '{}{:04d}{:03d}{:03d}{}'.format(
1739 self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext)
1739 self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext)
1740
1740
1741 filename = os.path.join(path, subfolder, filen)
1741 filename = os.path.join(path, subfolder, filen)
1742
1742
1743 fp = open(filename, 'wb')
1743 fp = open(filename, 'wb')
1744
1744
1745 self.blockIndex = 0
1745 self.blockIndex = 0
1746
1746
1747 # guardando atributos
1747 # guardando atributos
1748 self.filename = filename
1748 self.filename = filename
1749 self.subfolder = subfolder
1749 self.subfolder = subfolder
1750 self.fp = fp
1750 self.fp = fp
1751 self.setFile = setFile
1751 self.setFile = setFile
1752 self.flagIsNewFile = 1
1752 self.flagIsNewFile = 1
1753 self.fileDate = self.dataOut.datatime.date()
1753 self.fileDate = self.dataOut.datatime.date()
1754
1754
1755 self.setFirstHeader()
1755 self.setFirstHeader()
1756
1756
1757 print '[Writing] Opening file: %s' % self.filename
1757 print '[Writing] Opening file: %s' % self.filename
1758
1758
1759 self.__writeFirstHeader()
1759 self.__writeFirstHeader()
1760
1760
1761 return 1
1761 return 1
1762
1762
1763 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4):
1763 def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4):
1764 """
1764 """
1765 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1765 Setea el tipo de formato en la cual sera guardada la data y escribe el First Header
1766
1766
1767 Inputs:
1767 Inputs:
1768 path : directory where data will be saved
1768 path : directory where data will be saved
1769 profilesPerBlock : number of profiles per block
1769 profilesPerBlock : number of profiles per block
1770 set : initial file set
1770 set : initial file set
1771 datatype : An integer number that defines data type:
1771 datatype : An integer number that defines data type:
1772 0 : int8 (1 byte)
1772 0 : int8 (1 byte)
1773 1 : int16 (2 bytes)
1773 1 : int16 (2 bytes)
1774 2 : int32 (4 bytes)
1774 2 : int32 (4 bytes)
1775 3 : int64 (8 bytes)
1775 3 : int64 (8 bytes)
1776 4 : float32 (4 bytes)
1776 4 : float32 (4 bytes)
1777 5 : double64 (8 bytes)
1777 5 : double64 (8 bytes)
1778
1778
1779 Return:
1779 Return:
1780 0 : Si no realizo un buen seteo
1780 0 : Si no realizo un buen seteo
1781 1 : Si realizo un buen seteo
1781 1 : Si realizo un buen seteo
1782 """
1782 """
1783
1783
1784 if ext == None:
1784 if ext == None:
1785 ext = self.ext
1785 ext = self.ext
1786
1786
1787 self.ext = ext.lower()
1787 self.ext = ext.lower()
1788
1788
1789 self.path = path
1789 self.path = path
1790
1790
1791 if set is None:
1791 if set is None:
1792 self.setFile = -1
1792 self.setFile = -1
1793 else:
1793 else:
1794 self.setFile = set - 1
1794 self.setFile = set - 1
1795
1795
1796 self.blocksPerFile = blocksPerFile
1796 self.blocksPerFile = blocksPerFile
1797
1797
1798 self.profilesPerBlock = profilesPerBlock
1798 self.profilesPerBlock = profilesPerBlock
1799
1799
1800 self.dataOut = dataOut
1800 self.dataOut = dataOut
1801 self.fileDate = self.dataOut.datatime.date()
1801 self.fileDate = self.dataOut.datatime.date()
1802 # By default
1802 # By default
1803 self.dtype = self.dataOut.dtype
1803 self.dtype = self.dataOut.dtype
1804
1804
1805 if datatype is not None:
1805 if datatype is not None:
1806 self.dtype = get_numpy_dtype(datatype)
1806 self.dtype = get_numpy_dtype(datatype)
1807
1807
1808 if not(self.setNextFile()):
1808 if not(self.setNextFile()):
1809 print "[Writing] There isn't a next file"
1809 print "[Writing] There isn't a next file"
1810 return 0
1810 return 0
1811
1811
1812 self.setBlockDimension()
1812 self.setBlockDimension()
1813
1813
1814 return 1
1814 return 1
1815
1815
1816 def run(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs):
1816 def run(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs):
1817
1817
1818 if not(self.isConfig):
1818 if not(self.isConfig):
1819
1819
1820 self.setup(dataOut, path, blocksPerFile, profilesPerBlock=profilesPerBlock,
1820 self.setup(dataOut, path, blocksPerFile, profilesPerBlock=profilesPerBlock,
1821 set=set, ext=ext, datatype=datatype, **kwargs)
1821 set=set, ext=ext, datatype=datatype, **kwargs)
1822 self.isConfig = True
1822 self.isConfig = True
1823
1823
1824 self.putData()
1824 self.putData()
General Comments 0
You need to be logged in to leave comments. Login now