예제 #1
0
class Module(Thread):
    HEADER = '\033[95m'
    BLUE = '\033[94m'
    CYAN = '\033[36m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'
    print_lock = Lock()

    def reset(self):
        return

    def __init__(self, next_module=None, **kwargs):
        Thread.__init__(self)
        self.output = next_module
        self.mutex = Lock()
        self.stop = False
        self.plt = None
        self.fig = 1
        self.base = time()
        self.passthrough = False
        self.quitted = False
        # if main = True, then the thread will not start and be expected to be called from the
        # main thread
        self.main = False
        # TODO: legacy code that enabled calling matplotlib, needs to be replaced with Scope
        self.debug = False
        self.input = Queue()
        # Variable to update the ncurses interface to display zero data in queue
        self.zeroed = False

        # Scope represents our way of calling matplotlib
        # from the module. Since the module is on a separate
        # thread, scope is a queue mechanism to send data over
        # to the main thread.
        # A separate controller will manage calling the scope from
        # the main thread.
        self.scope = None

        # times is a dictionary to keep track of all the execution times of methods
        # and print it out in the end
        self.times = {}

        for key in kwargs:
            if key == 'fig':
                self.fig = int(kwargs[key])
            elif key == 'passthrough':
                self.passthrough = bool(kwargs[key])
            elif key == 'plt':
                self.plt = kwargs[key]
            elif key == 'main':
                self.main = bool(kwargs[key])
            elif key == 'debug':
                self.debug = bool(kwargs[key])
            elif key == 'scope_size':
                self.scope_size = int(kwargs[key])

        if output_redirection:
            self.box = Box(0, 0, 0, 0)
            self.box_title = self.box.add_label(self.__class__.__name__)
            self.box_queue_size = self.box.add_label('0')
            self.box_queue_bar = self.box.add_bar(0)
            self.box_plot_on = self.box.add_label('plot: off')
        else:
            self.box = None

    def set_scope(self, scope):
        if scope is not None:
            self.box.notify(self.box_plot_on, 'plot: on')
        else:
            self.box.notify(self.box_plot_on, 'plot: off')
        self.mutex.acquire()
        self.scope = scope
        self.mutex.release()

    def num_scopes(self):
        return 1

    def work(self):
        if not self.input.empty():
            queue_size = len(self.input.queue)
            if self.box is not None:
                self.box.notify(self.box_queue_size, queue_size)
                self.box.notify(self.box_queue_bar, queue_size)
                self.zeroed = False

            in_data = self.input.get()
            if self.passthrough == True:
                self.output.input.put(in_data)
                return True
            start = time()
            out_dat = self.process(in_data)
            stop = time()
            #print self.YELLOW + self.__class__.__name__+':\t [%4.3f ms]'%(1000.0*(stop-start))+self.ENDC

            if self.output is not None:
                if out_dat is not None:
                    self.output.input.put(out_dat)
            return True
        else:
            if self.box is not None and not self.zeroed:
                self.zeroed = True
                self.box.notify(self.box_queue_size, 0)
                self.box.notify(self.box_queue_bar, 0)
            return True

    def quit(self, all=False):
        # TODO: Quit gracefully
        self.print_times()
        self.mutex.acquire()
        self.stop = True
        self.mutex.release()
        if all and self.output != None:
            self.output.quit(True)
        if not self.main:
            self.join()

    def start(self):
        if self.box is not None:
            self.box_log = self.box.add_label('log:')
        if not self.main:
            Thread.start(self)
        if self.output != None:
            self.output.start()

    def run(self):
        Module.print_lock.acquire()
        self.log(self.__class__.__name__ + ' starting')
        Module.print_lock.release()
        base = time()
        try:
            while True:
                self.mutex.acquire()
                busy = self.work()
                self.mutex.release()
                if busy:
                    base = time()
                else:
                    if time() - base > 5.0:
                        #sleep(0.5)
                        pass

                self.mutex.acquire()
                if self.stop:
                    self.mutex.release()
                    break
                else:
                    self.mutex.release()

        except Exception as e:
            Module.print_lock.acquire()
            self.log(self.FAIL + 'Exception in ' + self.__class__.__name__ +
                     self.ENDC)
            traceback.print_exc()
            Module.print_lock.release()

        Module.print_lock.acquire()
        self.log(self.__class__.__name__ + ' quitting')
        self.quitted = True
        Module.print_lock.release()

    def process(self):
        return None

    def blog(self, msg):
        if self.box is not None:
            self.box.box_log(msg)

    def log(self, msg):
        if type(msg) != str:
            msg = str(msg)
        stdout.write(self.GREEN + self.__class__.__name__ + ':\t' + self.ENDC +
                     msg + '\n')

    def print_kw_error(self, arg_name):
        msg = Module.FAIL + self.__class__.__name__ + ' requires key word argument %s!' % arg_name + Module.ENDC
        self.log(msg)
        self.box_log(msg)

    def print_pam(self, pam):
        msg = '\n'
        count = 0
        byte = np.zeros(4)
        for p in pam:
            byte[count % 4] = p
            count += 1
            if count % 4 == 0:
                msg += '%d: [%2d %2d %2d %2d]\n' % (count / 4, byte[0],
                                                    byte[1], byte[2], byte[3])

        if count % 4 > 0:
            msg += '%d: [' % (1 + count / 4) + ('%2d ' * (count % 4)) % tuple(
                byte[:count % 4]) + '...\n'

        self.log(msg)

    def start_timer(self, key):
        if self.times.has_key(key):
            self.times[key].append(time())
        else:
            self.times[key] = [time()]

    def stop_timer(self, key):
        self.times[key][-1] = time() - self.times[key][-1]

    def print_times(self):
        msg = '\n'
        for key in self.times:
            msg += '%s, %.3f ms\n' % (key,
                                      1000.0 * np.average(self.times[key]))
        self.log(msg)

    def cmd_info(self):
        msgs = [('pon', 'enable plot'), ('poff', 'disable plot'),
                ('q', 'quit the program')]
        return msgs

    def interpret_cmd(self, cmd):
        return