<commit_before># -*- coding: utf-8 -*-
from __future__ import print_function, division, absolute_import, unicode_literals
import sys
from functools import wraps
from contextlib import contextmanager
from collections import namedtuple
from .util import to_list
from .ast import AST
from .exceptions import FailedParse, FailedCut, FailedLookahead

__all__ = ['ParseInfo', 'ParseContext']

ParseInfo = namedtuple('ParseInfo', ['buffer', 'rule', 'pos', 'endpos'])

class ParseContext(object):
    def __init__(self,
                 buffer=None,
                 semantics=None,
                 parseinfo=False,
                 trace=False,
                 encoding='utf-8',
                 comments_re=None,
                 **kwargs):
        super(ParseContext, self).__init__()

        self._buffer = buffer
        self.semantics = semantics
        self.encoding = encoding
        self.comments_re = comments_re
        self.parseinfo = parseinfo
        self.trace = trace

        self._ast_stack = []
        self._concrete_stack = [None]
        self._rule_stack = []
        self._cut_stack = [False]
        self._memoization_cache = dict()
        self._last_node = None

    def _reset_context(self, buffer=None, semantics=None):
        self._buffer = buffer
        self._ast_stack = []
        self._concrete_stack = [None]
        self._rule_stack = []
        self._cut_stack = [False]
        self._memoization_cache = dict()
        if semantics is not None:
            self.semantics = semantics

    def goto(self, pos):
        self._buffer.goto(pos)

    @property
    def last_node(self):
        return self._last_node

    @property
    def _pos(self):
        return self._buffer.pos

    def _goto(self, pos):
        self._buffer.goto(pos)

    def _next_token(self):
        self._buffer.next_token()

    @property
    def ast(self):
        return self._ast_stack[-1]

    @ast.setter
    def ast(self, value):
        self._ast_stack[-1] = value

    def _push_ast(self):
        self._push_cst()
        self._ast_stack.append(AST())

    def _pop_ast(self):
        self._pop_cst()
        return self._ast_stack.pop()

    def _add_ast_node(self, name, node, force_list=False):
        if name is not None:  # and node:
            self.ast.add(name, node, force_list)
        return node

    def _update_ast(self, ast):
        for key, value in ast.items():
            if key not in self.ast or not isinstance(value, list):
                self._add_ast_node(key, value)
            else:
                prev = self.ast[key]
                if isinstance(prev, list):
                    prev.extend(value)
                else:
                    self.ast[key] = [prev] + value

    @property
    def cst(self):
        return self._concrete_stack[-1]

    @cst.setter
    def cst(self, cst):
        self._concrete_stack[-1] = cst

    def _push_cst(self):
        self._concrete_stack.append(None)

    def _pop_cst(self):
        return self._concrete_stack.pop()

    def _add_cst_node(self, node):
        if node is None:
            return
        previous = self._concrete_stack[-1]
        if previous is None:
            self._concrete_stack[-1] = node
        elif previous == node:  # FIXME: Don't know how this happens, but it does
            return
        elif isinstance(previous, list):
            previous.append(node)
        else:
            self._concrete_stack[-1] = [previous, node]

    def _extend_cst(self, cst):
        if cst is None:
            return
        if self.cst is None:
            self.cst = cst
        elif isinstance(self.cst, list):
            if isinstance(cst, list):
                self.cst.extend(cst)
            else:
                self.cst.append(cst)
        elif isinstance(cst, list):
            self.cst = [self.cst] + cst
        else:
            self.cst = [self.cst, cst]

    def _is_cut_set(self):
        return self._cut_stack[-1]

    def _cut(self):
        self._cut_stack[-1] = True

        # Kota Mizushima et al say that we can throw away
        # memos for previous positions in the buffer.
        #   http://goo.gl/VaGpj
        cutpos = self._pos
        cache = self._memoization_cache
        cutkeys = [(p, n) for p, n in cache.keys() if p < cutpos]
        for key in cutkeys:
            del cache[key]

    def _push_cut(self):
        self._cut_stack.append(False)

    def _pop_cut(self):
        return self._cut_stack.pop()

    def _rulestack(self):
        stack = '.'.join(self._rule_stack)
        if len(stack) > 60:
            stack = '...' + stack[-60:]
        return stack

    def _find_rule(self, name):
        return None

    def _find_semantic_rule(self, name):
        if self.semantics is None:
            return None
        result = getattr(self.semantics, name, None)
        if result is None or not isinstance(result, type(self._find_semantic_rule)):
            return None
        return result

    def _trace(self, msg, *params):
        if self.trace:
            print(unicode(msg % params).encode(self.encoding), file=sys.stderr)

    def _trace_event(self, event):
        if self.trace:
            self._trace('%s \n%s   \n%s \n\t%s \n',
                        event,
                        self._buffer.line_info().filename,
                        self._rulestack(),
                        self._buffer.lookahead()
                        )

    def _trace_match(self, token, name=None):
        if self.trace:
            name = name if name else ''
            self._trace('MATCHED <%s> /%s/\n\t%s', token, name, self._buffer.lookahead())

    def _error(self, item, etype=FailedParse):
        raise etype(self._buffer, item)

    def _fail(self):
        self._error('fail')

    @contextmanager
    def _try(self):
        p = self._pos
        self._push_ast()
        try:
            yield None
            ast = self.ast
            cst = self.cst
        except:
            self._goto(p)
            raise
        finally:
            self._pop_ast()
        self._update_ast(ast)
        self._add_cst_node(cst)

    @contextmanager
    def _option(self):
        self._push_cut()
        try:
            with self._try():
                yield None
        except FailedCut:
            raise
        except FailedParse as e:
            if self._is_cut_set():
                raise FailedCut(e)
        finally:
            self._pop_cut()

    @contextmanager
    def _choice_context(self):
        try:
            yield None
        except FailedCut as e:
            raise e.nested

    #decorator
    def _choice(self, f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            with self._choice_context():
                f()
                return self.last_node
        return wrapper

    @contextmanager
    def _optional(self):
        with self._choice_context():
            with self._option():
                yield None

    @contextmanager
    def _group(self):
        self._push_cst()
        try:
            yield None
            cst = self.cst
        finally:
            self._pop_cst()
        self._add_cst_node(cst)
        self._last_node = cst

    @contextmanager
    def _if(self):
        p = self._pos
        self._push_ast()
        try:
            yield None
        finally:
            self._goto(p)
            self._pop_ast()  # simply discard
            self._last_node = None

    @contextmanager
    def _ifnot(self):
        p = self._pos
        self._push_ast()
        self._last_node = None
        try:
            yield None
        except FailedParse:
            pass
        else:
            self._error('', etype=FailedLookahead)
        finally:
            self._goto(p)
            self._pop_ast()  # simply discard
            self._last_node = None

    def _repeater(self, f):
        result = []
        while True:
            self._push_cut()
            try:
                p = self._pos
                with self._try():
                    value = f()
                if value is not None:
                    result.append(value)
                if self._pos == p:
                    self._error('empty closure')
            except FailedCut:
                raise
            except FailedParse as e:
                if self._is_cut_set():
                    raise FailedCut(e)
                return result
            finally:
                self._pop_cut()

    #decorator
    def _closure(self, f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            self._push_cst()
            try:
                result = self._repeater(f)
                cst = to_list(self.cst)
            finally:
                self._pop_cst()
            self._add_cst_node(cst)
            self._last_node = cst
            return result
        return wrapper

    #decorator
    def _closure_plus(self, f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            self._push_cst()
            try:
                with self._try():
                    one = [f()]
                result = one + self._repeater(f)
                cst = to_list(self.cst)
            finally:
                self._pop_cst()
            self._add_cst_node(cst)
            self._last_node = cst
            return result
        return wrapper
<commit_msg>Simplifications to closure.<commit_after># -*- coding: utf-8 -*-
from __future__ import print_function, division, absolute_import, unicode_literals
import sys
from functools import wraps
from contextlib import contextmanager
from collections import namedtuple
from .util import to_list
from .ast import AST
from .exceptions import FailedParse, FailedCut, FailedLookahead

__all__ = ['ParseInfo', 'ParseContext']

ParseInfo = namedtuple('ParseInfo', ['buffer', 'rule', 'pos', 'endpos'])

class ParseContext(object):
    def __init__(self,
                 buffer=None,
                 semantics=None,
                 parseinfo=False,
                 trace=False,
                 encoding='utf-8',
                 comments_re=None,
                 **kwargs):
        super(ParseContext, self).__init__()

        self._buffer = buffer
        self.semantics = semantics
        self.encoding = encoding
        self.comments_re = comments_re
        self.parseinfo = parseinfo
        self.trace = trace

        self._ast_stack = []
        self._concrete_stack = [None]
        self._rule_stack = []
        self._cut_stack = [False]
        self._memoization_cache = dict()
        self._last_node = None

    def _reset_context(self, buffer=None, semantics=None):
        self._buffer = buffer
        self._ast_stack = []
        self._concrete_stack = [None]
        self._rule_stack = []
        self._cut_stack = [False]
        self._memoization_cache = dict()
        if semantics is not None:
            self.semantics = semantics

    def goto(self, pos):
        self._buffer.goto(pos)

    @property
    def last_node(self):
        return self._last_node

    @property
    def _pos(self):
        return self._buffer.pos

    def _goto(self, pos):
        self._buffer.goto(pos)

    def _next_token(self):
        self._buffer.next_token()

    @property
    def ast(self):
        return self._ast_stack[-1]

    @ast.setter
    def ast(self, value):
        self._ast_stack[-1] = value

    def _push_ast(self):
        self._push_cst()
        self._ast_stack.append(AST())

    def _pop_ast(self):
        self._pop_cst()
        return self._ast_stack.pop()

    def _add_ast_node(self, name, node, force_list=False):
        if name is not None:  # and node:
            self.ast.add(name, node, force_list)
        return node

    def _update_ast(self, ast):
        for key, value in ast.items():
            if key not in self.ast or not isinstance(value, list):
                self._add_ast_node(key, value)
            else:
                prev = self.ast[key]
                if isinstance(prev, list):
                    prev.extend(value)
                else:
                    self.ast[key] = [prev] + value

    @property
    def cst(self):
        return self._concrete_stack[-1]

    @cst.setter
    def cst(self, cst):
        self._concrete_stack[-1] = cst

    def _push_cst(self):
        self._concrete_stack.append(None)

    def _pop_cst(self):
        return self._concrete_stack.pop()

    def _add_cst_node(self, node):
        if node is None:
            return
        previous = self._concrete_stack[-1]
        if previous is None:
            self._concrete_stack[-1] = node
        elif previous == node:  # FIXME: Don't know how this happens, but it does
            return
        elif isinstance(previous, list):
            previous.append(node)
        else:
            self._concrete_stack[-1] = [previous, node]

    def _extend_cst(self, cst):
        if cst is None:
            return
        if self.cst is None:
            self.cst = cst
        elif isinstance(self.cst, list):
            if isinstance(cst, list):
                self.cst.extend(cst)
            else:
                self.cst.append(cst)
        elif isinstance(cst, list):
            self.cst = [self.cst] + cst
        else:
            self.cst = [self.cst, cst]

    def _is_cut_set(self):
        return self._cut_stack[-1]

    def _cut(self):
        self._cut_stack[-1] = True

        # Kota Mizushima et al say that we can throw away
        # memos for previous positions in the buffer.
        #   http://goo.gl/VaGpj
        cutpos = self._pos
        cache = self._memoization_cache
        cutkeys = [(p, n) for p, n in cache.keys() if p < cutpos]
        for key in cutkeys:
            del cache[key]

    def _push_cut(self):
        self._cut_stack.append(False)

    def _pop_cut(self):
        return self._cut_stack.pop()

    def _rulestack(self):
        stack = '.'.join(self._rule_stack)
        if len(stack) > 60:
            stack = '...' + stack[-60:]
        return stack

    def _find_rule(self, name):
        return None

    def _find_semantic_rule(self, name):
        if self.semantics is None:
            return None
        result = getattr(self.semantics, name, None)
        if result is None or not isinstance(result, type(self._find_semantic_rule)):
            return None
        return result

    def _trace(self, msg, *params):
        if self.trace:
            print(unicode(msg % params).encode(self.encoding), file=sys.stderr)

    def _trace_event(self, event):
        if self.trace:
            self._trace('%s \n%s   \n%s \n\t%s \n',
                        event,
                        self._buffer.line_info().filename,
                        self._rulestack(),
                        self._buffer.lookahead()
                        )

    def _trace_match(self, token, name=None):
        if self.trace:
            name = name if name else ''
            self._trace('MATCHED <%s> /%s/\n\t%s', token, name, self._buffer.lookahead())

    def _error(self, item, etype=FailedParse):
        raise etype(self._buffer, item)

    def _fail(self):
        self._error('fail')

    @contextmanager
    def _try(self):
        p = self._pos
        self._push_ast()
        try:
            yield None
            ast = self.ast
            cst = self.cst
        except:
            self._goto(p)
            raise
        finally:
            self._pop_ast()
        self._update_ast(ast)
        self._add_cst_node(cst)

    @contextmanager
    def _option(self):
        self._push_cut()
        try:
            with self._try():
                yield None
        except FailedCut:
            raise
        except FailedParse as e:
            if self._is_cut_set():
                raise FailedCut(e)
        finally:
            self._pop_cut()

    @contextmanager
    def _choice_context(self):
        try:
            yield None
        except FailedCut as e:
            raise e.nested

    #decorator
    def _choice(self, f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            with self._choice_context():
                f()
                return self.last_node
        return wrapper

    @contextmanager
    def _optional(self):
        with self._choice_context():
            with self._option():
                yield None

    @contextmanager
    def _group(self):
        self._push_cst()
        try:
            yield None
            cst = self.cst
        finally:
            self._pop_cst()
        self._add_cst_node(cst)
        self._last_node = cst

    @contextmanager
    def _if(self):
        p = self._pos
        self._push_ast()
        try:
            yield None
        finally:
            self._goto(p)
            self._pop_ast()  # simply discard
            self._last_node = None

    @contextmanager
    def _ifnot(self):
        p = self._pos
        self._push_ast()
        self._last_node = None
        try:
            yield None
        except FailedParse:
            pass
        else:
            self._error('', etype=FailedLookahead)
        finally:
            self._goto(p)
            self._pop_ast()  # simply discard
            self._last_node = None

    def _repeater(self, f):
        result = []
        while True:
            self._push_cut()
            try:
                p = self._pos
                with self._try():
                    value = f()
                if value is not None:
                    result.append(value)
                if self._pos == p:
                    self._error('empty closure')
            except FailedCut:
                raise
            except FailedParse as e:
                if self._is_cut_set():
                    raise FailedCut(e)
                return result
            finally:
                self._pop_cut()

    #decorator
    def _closure(self, f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            self._push_cst()
            try:
                self._repeater(f)
                cst = to_list(self.cst)
            finally:
                self._pop_cst()
            self._add_cst_node(cst)
            self._last_node = cst
            return cst
        return wrapper

    #decorator
    def _closure_plus(self, f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            self._push_cst()
            try:
                with self._try():
                    f()
                self._repeater(f)
                cst = to_list(self.cst)
            finally:
                self._pop_cst()
            self._add_cst_node(cst)
            self._last_node = cst
            return cst
        return wrapper
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
    Library tagger GUI

    When tagging libraries using this script, you could refer to
    https://raw.githubusercontent.com/pkumza/LibRadar/master/data/tgst5.dat and
    https://github.com/pkumza/LibRadar/blob/dev/extract/step2.py

"""

import lib_tagging
import csv
import os
from _settings import FILE_RULE

from Tkinter import *           # 导入 Tkinter 库
import ttk

class TaggerGui(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        # Frame 1 Welcome
        self.create_f1_welcome()
        # read csv
        # contains items like android/support/v4, org/apache/http,
        self.labeled_prefix = list()
        # contains items like com/android, com/google
        self.no_lib_prefix = list()
        if os.path.exists(FILE_RULE):
            file_rules = open(FILE_RULE, 'r')
            csv_rules_reader = csv.reader(file_rules, delimiter=',', quotechar='|')
            for row in csv_rules_reader:
                if row[1] == "no":
                    self.no_lib_prefix.append(row[0])
                else:
                    self.labeled_prefix.append(row[0])
            file_rules.close()
        self.file_rules_w = open(FILE_RULE, 'a')
        self.csv_rule_writer = csv.writer(self.file_rules_w, delimiter=',', quotechar='|')

    def create_f1_welcome(self):
        self.hello_label = Label(self, text='\nHello!\nThis is LibRadar Tagging System.\n'
                                           'Version: 2.0.1.dev1\n'
                                           'Author:  Zachary Ma')
        self.hello_label.pack(side=TOP)
        self.next_button = Button(self, text="Next", command=self.destroy_f1)
        self.next_button.pack()
        self.quit_button = Button(self, text='Quit', command=self.quit)
        self.quit_button.pack()

    def destroy_f1(self):
        self.hello_label.destroy()
        self.next_button.destroy()
        self.quit_button.destroy()
        self.create_f2_init()

    def create_f2_init(self):
        self.master.geometry("300x210")
        self.hello_label = Label(self, text="\nPlease input some arguments for this system.\nThis would take a few moments, please wait.")
        self.hello_label.pack()
        self.count_label = Label(self, text="Base count (default 20):")
        self.count_label.pack()
        self.count_text = StringVar()
        self.count_entry = Entry(self, textvariable=self.count_text)
        self.count_entry.pack()
        self.weight_text = StringVar()
        self.weight_label = Label(self, text="Weight count (default 20):")
        self.weight_label.pack()
        self.weight_entry = Entry(self, textvariable=self.weight_text)
        self.weight_entry.pack()
        self.d2c3_button = Button(self, text="Next", command=self.destroy_f2)
        self.d2c3_button.pack()

    def destroy_f2(self):
        self.base_count = -1
        self.base_weight = -1
        good_flag = True
        try:
            if self.weight_text.get() == "":
                self.base_weight = 20
            else:
                self.base_weight = int(self.weight_text.get())
            if self.count_text.get() == "":
                self.base_count = 20
            else:
                self.base_count = int(self.count_text.get())

        except:
            good_flag = False
        if self.base_count < 0:
            good_flag = False
        if self.base_weight < 0:
            good_flag = False
        self.hello_label.destroy()
        self.count_label.destroy()
        self.count_entry.destroy()
        self.weight_label.destroy()
        self.weight_entry.destroy()
        self.d2c3_button.destroy()
        if good_flag:
            self.init_data_for_f3()
        else:
            self.create_f2_init()

    def init_data_for_f3(self):
        """frame for tagging"""
        # self.master.geometry("300x120")
        self.tagger = lib_tagging.Tagger(self.base_count, self.base_weight)
        self.features = self.tagger.get_potential_list()
        self.create_f3_init()

    def create_f3_init(self):
        """

        :return:
        """
        """
        INFO
        """
        self.master.geometry("300x520")
        self.label_index = -1
        self.labeled_cnt = 0

        """
        GUI
        """
        self.label_message = Label(self, text="")
        self.label_message.pack()
        self.label_progress = Label(self, text="\nProgress:")
        self.label_progress.pack()

        self.label_count = Label(self, text="\nPopularity:")
        self.label_count.pack()
        self.n_label_count = Label(self, text="")
        self.n_label_count.pack()
        self.label_weight = Label(self, text="API number:")
        self.label_weight.pack()
        self.n_label_weight = Label(self, text="")
        self.n_label_weight.pack()
        self.label_package_name = Label(self, text="Package Name:")
        self.label_package_name.pack()
        self.n_label_package_name = Label(self, text="")
        self.n_label_package_name.pack()
        self.label_tagging = Label(self, text="Library prefix:")
        self.label_tagging.pack()
        self.t_lib_prefix = StringVar()
        self.entry_prefix = Entry(self, textvariable=self.t_lib_prefix)
        self.entry_prefix.pack()
        self.label_lib_name = Label(self, text="Library Name:")
        self.label_lib_name.pack()
        self.t_lib_name = StringVar()
        self.entry_name = Entry(self, textvariable=self.t_lib_name)
        self.entry_name.pack()
        self.label_type = Label(self, text="Library Type:")
        self.label_type.pack()
        self.t_lib_type = StringVar()
        self.type_chosen = ttk.Combobox(self, textvariable=self.t_lib_type)
        self.type_chosen['values'] = (
            "Development Aid",
            "Social Network",
            "Advertisement",
            "App Market",
            "Mobile Analytics",
            "Payment",
            "Game Engine",
            "Map/LBS",
            "GUI Component",
            "Development Framework",
            "Not Sure"
        )
        self.type_chosen.current(0)
        self.type_chosen.pack()
        self.label_website = Label(self, text="Official SDK Website:")
        self.label_website.pack()
        self.t_website = StringVar()
        self.entry_website = Entry(self, textvariable=self.t_website)
        self.entry_website.pack()
        self.button_tag = Button(self, text="Tag!", command=self.insert_csv)
        self.button_tag.pack()
        self.button_ignore = Button(self, text="I don't know", command=self.ignore_f3)
        self.button_ignore.pack()
        self.button_not = Button(self, text="This package is definitely not a library!", command=self.insert_not_csv)
        self.button_not.pack()

        self.create_f3()

    def tagged(self, package_name):
        """
        Determine if package_name needed to be tagged.
        :param package_name: the package name to be determined.
        :return: boolean
        """
        # never found it is tagged.
        flag = False
        for prefix in self.labeled_prefix:
            if prefix in package_name:
                flag = True
                break
        if flag:
            return flag
        for prefix in self.no_lib_prefix:
            if prefix == package_name:
                flag = True
                break
        return flag

    def create_f3(self):
        """
        loop and loop
        :return:
        """

        # Clear Text
        self.t_website.set("")
        self.t_lib_name.set("")

        # Index++
        self.label_index += 1
        # Ignore those tagged libs.
        while self.label_index < len(self.features) and self.tagged(self.features[self.label_index][3]):
            self.label_index += 1
        if self.label_index >= len(self.features):
            self.destroy_f3()
            return

        self.t_lib_prefix.set(self.features[self.label_index][3])
        # Show information
        self.label_progress["text"] = "\nProgress: %d/%d" % (self.label_index + 1, len(self.features))
        self.n_label_count["text"] = str(self.features[self.label_index][1])
        self.n_label_weight["text"] = str(self.features[self.label_index][2])
        self.n_label_package_name["text"] = str(self.features[self.label_index][3])

    def ignore_f3(self):
        self.label_message["text"] = ""
        self.create_f3()

    def insert_csv(self):
        """

        :return:
        """
        self.label_message["text"] = ""
        good_flag = True
        try:
            prefix = self.t_lib_prefix.get()
            if self.features[self.label_index][3][:len(prefix)] != prefix:
                self.label_message["text"] = "Prefix not the same! try again!"
                self.label_index -= 1
                self.create_f3()
                return
            lib_name = self.t_lib_name.get()
            website = self.t_website.get()
            lib_type = self.t_lib_type.get()
        except:
            good_flag = False
        if good_flag:
            # insert into csv
            self.csv_rule_writer.writerow([prefix, lib_name, lib_type, website])
            # insert the prefix into list
            self.labeled_prefix.append(prefix)
        else:
            # ignore
            pass
        self.create_f3()

    def insert_not_csv(self):
        """

        :return:
        """
        self.label_message["text"] = ""
        good_flag = True
        try:
            prefix = str(self.features[self.label_index][3])
            lib_name = "no"
            website = "no"
        except:
            good_flag = False
        if good_flag:
            # insert into csv
            self.csv_rule_writer.writerow([prefix, lib_name, "no", website])
            # insert the prefix into list
            self.no_lib_prefix.append(prefix)
        else:
            # ignore
            pass
        self.create_f3()

    def destroy_f3(self):
        self.label_message.destroy()
        self.label_progress.destroy()
        self.label_count.destroy()
        self.n_label_count.destroy()
        self.label_weight.destroy()
        self.n_label_weight.destroy()
        self.label_package_name.destroy()
        self.n_label_package_name.destroy()
        self.label_tagging.destroy()
        self.entry_prefix.destroy()
        self.label_lib_name.destroy()
        self.entry_name.destroy()
        self.label_website.destroy()
        self.entry_website.destroy()
        self.button_tag.destroy()
        self.button_ignore.destroy()
        self.button_not.destroy()

        # Create Exit
        self.create_f4()

    def create_f4(self):
        """
        You have tagged XXXX libs.
        :param self:
        :return:
        """
        self.hello_label = Label(self, text='The End\nplease exit.')
        self.hello_label.pack(side=TOP)
        pass

if __name__ == '__main__':
    app = TaggerGui()
    # Set title
    app.master.title('LibRadar Tagging System')
    # Size
    app.master.geometry("300x160")
    # Main loop
    app.mainloop()<commit_msg>Slightly Change for GUI component.<commit_after># -*- coding: utf-8 -*-
"""
    Library tagger GUI

    When tagging libraries using this script, you could refer to
    https://raw.githubusercontent.com/pkumza/LibRadar/master/data/tgst5.dat and
    https://github.com/pkumza/LibRadar/blob/dev/extract/step2.py

    Introduction:
        This script is not used for tagging libraries actually, It gives you some untagged libraries and you could set a
        rule for tagging.
        As there would be so many packages and so many libraries, it not possible to tag them one by one.
        There could be many versions of libraries, so there's some repeat work.

        We presume that more than half package names of a library is un-obfuscated, in this case, we could know the true
        package name but we could not get the real library name, the website, type, or the other information.

        tag_rules.csv is a projection from un-obfuscated package name to its detailed information.

    Usage:
        Run this script or just modify Data/IntermediateData/tag_rules.csv

"""

import lib_tagging
import csv
import os
from _settings import FILE_RULE

from Tkinter import *           # 导入 Tkinter 库
import ttk

class TaggerGui(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        # Frame 1 Welcome
        self.create_f1_welcome()
        # read csv
        # contains items like android/support/v4, org/apache/http,
        self.labeled_prefix = list()
        # contains items like com/android, com/google
        self.no_lib_prefix = list()
        if os.path.exists(FILE_RULE):
            file_rules = open(FILE_RULE, 'r')
            csv_rules_reader = csv.reader(file_rules, delimiter=',', quotechar='|')
            for row in csv_rules_reader:
                if row[1] == "no":
                    self.no_lib_prefix.append(row[0])
                else:
                    self.labeled_prefix.append(row[0])
            file_rules.close()
        self.file_rules_w = open(FILE_RULE, 'a')
        self.csv_rule_writer = csv.writer(self.file_rules_w, delimiter=',', quotechar='|')
        # Init items
        self.hello_label = None
        self.next_button = None
        self.quit_button = None
        self.count_label = None
        self.count_text = None
        self.count_entry = None
        self.weight_text = None
        self.weight_label = None
        self.weight_entry = None
        self.d2c3_button = None
        self.tagger = None
        self.features = None
        self.labeled_prefix = None
        self.labeled_cnt = None

    def create_f1_welcome(self):
        self.hello_label = Label(self,
                                 text='\nHello!\nThis is LibRadar Tagging System.\nVersion: 2.0.1.dev1\n'
                                      'Author:  Zachary Ma')
        self.hello_label.pack(side=TOP)
        self.next_button = Button(self, text="Next", command=self.destroy_f1)
        self.next_button.pack()
        self.quit_button = Button(self, text='Quit', command=self.quit)
        self.quit_button.pack()

    def destroy_f1(self):
        self.hello_label.destroy()
        self.next_button.destroy()
        self.quit_button.destroy()
        self.create_f2_init()

    def create_f2_init(self):
        self.master.geometry("300x210")
        self.hello_label = Label(self,
                                 text="\nPlease input some arguments for this system.\nThis would take a few moments,"
                                      " please wait.")
        self.hello_label.pack()
        self.count_label = Label(self, text="Base count (default 20):")
        self.count_label.pack()
        self.count_text = StringVar()
        self.count_entry = Entry(self, textvariable=self.count_text)
        self.count_entry.pack()
        self.weight_text = StringVar()
        self.weight_label = Label(self, text="Weight count (default 20):")
        self.weight_label.pack()
        self.weight_entry = Entry(self, textvariable=self.weight_text)
        self.weight_entry.pack()
        self.d2c3_button = Button(self, text="Next", command=self.destroy_f2)
        self.d2c3_button.pack()

    def destroy_f2(self):
        self.base_count = -1
        self.base_weight = -1
        good_flag = True
        try:
            if self.weight_text.get() == "":
                self.base_weight = 20
            else:
                self.base_weight = int(self.weight_text.get())
            if self.count_text.get() == "":
                self.base_count = 20
            else:
                self.base_count = int(self.count_text.get())

        except:
            good_flag = False
        if self.base_count < 0:
            good_flag = False
        if self.base_weight < 0:
            good_flag = False
        self.hello_label.destroy()
        self.count_label.destroy()
        self.count_entry.destroy()
        self.weight_label.destroy()
        self.weight_entry.destroy()
        self.d2c3_button.destroy()
        if good_flag:
            self.init_data_for_f3()
        else:
            self.create_f2_init()

    def init_data_for_f3(self):
        """frame for tagging"""
        # self.master.geometry("300x120")
        self.tagger = lib_tagging.Tagger(self.base_count, self.base_weight)
        self.features = self.tagger.get_potential_list()
        self.create_f3_init()

    def create_f3_init(self):
        """

        :return:
        """
        """
        INFO
        """
        self.master.geometry("300x520")
        self.label_index = -1
        self.labeled_cnt = 0

        """
        GUI
        """
        self.label_message = Label(self, text="")
        self.label_message.pack()
        self.label_progress = Label(self, text="\nProgress:")
        self.label_progress.pack()

        self.label_count = Label(self, text="\nPopularity:")
        self.label_count.pack()
        self.n_label_count = Label(self, text="")
        self.n_label_count.pack()
        self.label_weight = Label(self, text="API number:")
        self.label_weight.pack()
        self.n_label_weight = Label(self, text="")
        self.n_label_weight.pack()
        self.label_package_name = Label(self, text="Package Name:")
        self.label_package_name.pack()
        self.n_label_package_name = Label(self, text="")
        self.n_label_package_name.pack()
        self.label_tagging = Label(self, text="Library prefix:")
        self.label_tagging.pack()
        self.t_lib_prefix = StringVar()
        self.entry_prefix = Entry(self, textvariable=self.t_lib_prefix)
        self.entry_prefix.pack()
        self.label_lib_name = Label(self, text="Library Name:")
        self.label_lib_name.pack()
        self.t_lib_name = StringVar()
        self.entry_name = Entry(self, textvariable=self.t_lib_name)
        self.entry_name.pack()
        self.label_type = Label(self, text="Library Type:")
        self.label_type.pack()
        self.t_lib_type = StringVar()
        self.type_chosen = ttk.Combobox(self, textvariable=self.t_lib_type)
        self.type_chosen['values'] = (
            "Development Aid",
            "Social Network",
            "Advertisement",
            "App Market",
            "Mobile Analytics",
            "Payment",
            "Game Engine",
            "Map/LBS",
            "GUI Component",
            "Development Framework",
            "Not Sure"
        )
        self.type_chosen.current(0)
        self.type_chosen.pack()
        self.label_website = Label(self, text="Official SDK Website:")
        self.label_website.pack()
        self.t_website = StringVar()
        self.entry_website = Entry(self, textvariable=self.t_website)
        self.entry_website.pack()
        self.button_tag = Button(self, text="Tag!", command=self.insert_csv)
        self.button_tag.pack()
        self.button_ignore = Button(self, text="I don't know", command=self.ignore_f3)
        self.button_ignore.pack()
        self.button_not = Button(self, text="This package is definitely not a library!", command=self.insert_not_csv)
        self.button_not.pack()

        self.create_f3()

    def tagged(self, package_name):
        """
        Determine if package_name needed to be tagged.
        :param package_name: the package name to be determined.
        :return: boolean
        """
        # never found it is tagged.
        flag = False
        for prefix in self.labeled_prefix:
            if prefix in package_name:
                flag = True
                break
        if flag:
            return flag
        for prefix in self.no_lib_prefix:
            if prefix == package_name:
                flag = True
                break
        return flag

    def create_f3(self):
        """
        loop and loop
        :return:
        """

        # Clear Text
        self.t_website.set("")
        self.t_lib_name.set("")

        # Index++
        self.label_index += 1
        # Ignore those tagged libs.
        while self.label_index < len(self.features) and self.tagged(self.features[self.label_index][3]):
            self.label_index += 1
        if self.label_index >= len(self.features):
            self.destroy_f3()
            return

        self.t_lib_prefix.set(self.features[self.label_index][3])
        # Show information
        self.label_progress["text"] = "\nProgress: %d/%d" % (self.label_index + 1, len(self.features))
        self.n_label_count["text"] = str(self.features[self.label_index][1])
        self.n_label_weight["text"] = str(self.features[self.label_index][2])
        self.n_label_package_name["text"] = str(self.features[self.label_index][3])

    def ignore_f3(self):
        self.label_message["text"] = ""
        self.create_f3()

    def insert_csv(self):
        """

        :return:
        """
        self.label_message["text"] = ""
        good_flag = True
        lib_name = ""
        lib_type = ""
        website = ""
        prefix = ""
        try:
            prefix = self.t_lib_prefix.get()
            if self.features[self.label_index][3][:len(prefix)] != prefix:
                self.label_message["text"] = "Prefix not the same! try again!"
                self.label_index -= 1
                self.create_f3()
                return
            lib_name = self.t_lib_name.get()
            website = self.t_website.get()
            lib_type = self.t_lib_type.get()
        except:
            good_flag = False
        if good_flag:
            # insert into csv
            self.csv_rule_writer.writerow([prefix, lib_name, lib_type, website])
            # insert the prefix into list
            self.labeled_prefix.append(prefix)
        else:
            # ignore
            pass
        self.create_f3()

    def insert_not_csv(self):
        """

        :return:
        """
        self.label_message["text"] = ""
        good_flag = True
        lib_name = ""
        website = ""
        prefix = ""
        try:
            prefix = str(self.features[self.label_index][3])
            lib_name = "no"
            website = "no"
        except:
            good_flag = False
        if good_flag:
            # insert into csv
            self.csv_rule_writer.writerow([prefix, lib_name, "no", website])
            # insert the prefix into list
            self.no_lib_prefix.append(prefix)
        else:
            # ignore
            pass
        self.create_f3()

    def destroy_f3(self):
        self.label_message.destroy()
        self.label_progress.destroy()
        self.label_count.destroy()
        self.n_label_count.destroy()
        self.label_weight.destroy()
        self.n_label_weight.destroy()
        self.label_package_name.destroy()
        self.n_label_package_name.destroy()
        self.label_tagging.destroy()
        self.entry_prefix.destroy()
        self.label_lib_name.destroy()
        self.entry_name.destroy()
        self.label_website.destroy()
        self.entry_website.destroy()
        self.button_tag.destroy()
        self.button_ignore.destroy()
        self.button_not.destroy()

        # Create Exit
        self.create_f4()

    def create_f4(self):
        """
        You have tagged XXXX libs.
        :param self:
        :return:
        """
        self.hello_label = Label(self, text='The End\nplease exit.')
        self.hello_label.pack(side=TOP)
        pass

if __name__ == '__main__':
    app = TaggerGui()
    # Set title
    app.master.title('LibRadar Tagging System')
    # Size
    app.master.geometry("300x160")
    # Main loop
    app.mainloop()
<|endoftext|>


<commit_before>{
  'variables': {
    'platform': '<(OS)',
  },
  "targets":
  [
    {
      "target_name": "zookeeper",
      'dependencies': ['libzk'],
      "sources": [ "src/node-zk.cpp" ],
      'cflags': ['-Wall', '-O0'],
      'conditions': [
        ['OS=="solaris"', {
          'cflags': ['-Wno-strict-aliasing'],
          'defines': ['_POSIX_PTHREAD_SEMANTICS'],
          'include_dirs': ['/opt/local/include/zookeeper'],
    	  'ldflags': ['-lzookeeper_st'],
        }],['OS=="mac"',{
	      'include_dirs': [
              '<(module_root_dir)/deps/zookeeper/src/c/include',
              '<(module_root_dir)/deps/zookeeper/src/c/generated'
          ],
          'libraries': ['<(module_root_dir)/deps/zookeeper/src/c/.libs/libzookeeper_st.a'],
          'xcode_settings': {
            'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
            'MACOSX_DEPLOYMENT_TARGET': '10.5'
          }
        }],['OS=="linux"',{
          'include_dirs': [
                '<(module_root_dir)/deps/zookeeper/src/c/include',
                '<(module_root_dir)/deps/zookeeper/src/c/generated'

          ],
          'libraries': ['<(module_root_dir)/deps/zookeeper/src/c/.libs/libzookeeper_st.a'],
        }]
      ]
    },
    {
      'target_name': 'libzk',
      'type': 'none',
      'actions': [{
        'action_name': 'build_zk_client_lib',
        'inputs': [''],
        'outputs': [''],
        'action': ['sh', 'scripts/build.sh']
      }]
    },
    {
      "target_name": "after_build",
      "type": "none",
      "dependencies": ["zookeeper"],
      "actions": [{
        "action_name": "symlink",
        "inputs": ["<@(PRODUCT_DIR)/zookeeper.node"],
        "outputs": ["<(module_root_dir)/build/zookeeper.node"],
        "action": ["sh", "scripts/symlink.sh", "<@(_inputs)"]
      }]
    }
  ],
}
<commit_msg>retab<commit_after>{
    'variables': {
        'platform': '<(OS)',
    },
    "targets": [{
        "target_name": "zookeeper",
        'dependencies': ['libzk'],
        "sources": ["src/node-zk.cpp"],
        'cflags': ['-Wall', '-O0'],
        'conditions': [
            ['OS=="solaris"', {
                'cflags': ['-Wno-strict-aliasing'],
                'defines': ['_POSIX_PTHREAD_SEMANTICS'],
                'include_dirs': ['/opt/local/include/zookeeper'],
                'ldflags': ['-lzookeeper_st'],
            }],
            ['OS=="mac"',{
                'include_dirs': [
                    '<(module_root_dir)/deps/zookeeper/src/c/include',
                    '<(module_root_dir)/deps/zookeeper/src/c/generated'
                ],
                'libraries': ['<(module_root_dir)/deps/zookeeper/src/c/.libs/libzookeeper_st.a'],
                'xcode_settings': {
                    'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
                    'MACOSX_DEPLOYMENT_TARGET': '10.5'
                }
            }],['OS=="linux"',{
                'include_dirs': [
                    '<(module_root_dir)/deps/zookeeper/src/c/include',
                    '<(module_root_dir)/deps/zookeeper/src/c/generated'
                ],
                'libraries': ['<(module_root_dir)/deps/zookeeper/src/c/.libs/libzookeeper_st.a'],
            }]
        ]},
        {
            'target_name': 'libzk',
            'type': 'none',
            'actions': [{
                'action_name': 'build_zk_client_lib',
                'inputs': [''],
                'outputs': [''],
                'action': ['sh', 'scripts/build.sh']
            }]
        },
        {
            "target_name": "after_build",
            "type": "none",
            "dependencies": ["zookeeper"],
            "actions": [{
                "action_name": "symlink",
                "inputs": ["<@(PRODUCT_DIR)/zookeeper.node"],
                "outputs": ["<(module_root_dir)/build/zookeeper.node"],
                "action": ["sh", "scripts/symlink.sh", "<@(_inputs)"]
            }]
    }],
}
<|endoftext|>


<commit_before>{
  'targets': [
    {
      'target_name': 'bcrypt_lib',
      'sources': [
        'src/blowfish.cc',
        'src/bcrypt.cc',
        'src/bcrypt_node.cc'
      ],
      'include_dirs' : [
          "<!@(node -p \"require('node-addon-api').include\")"
      ],
      'msvs_settings': {
        'VCCLCompilerTool': { 'ExceptionHandling': 1 },
      },
      "xcode_settings": {
        "CLANG_CXX_LIBRARY": "libc++",
        'GCC_ENABLE_CPP_EXCEPTIONS': 'YES'
      },
      'conditions': [
        [ 'OS=="win"', {
          'defines': [
            'uint=unsigned int',
          ],
        }],
      ],
    },
    {
      "target_name": "action_after_build",
      "type": "none",
      "dependencies": [ "<(module_name)" ],
      "copies": [
        {
          "files": [ "<(PRODUCT_DIR)/<(module_name).node" ],
          "destination": "<(module_path)"
        }
      ]
    }
  ]
}
<commit_msg>Update binding.gyp due to compilation problem on linux and windows<commit_after>{
  'targets': [
    {
      'target_name': 'bcrypt_lib',
      'sources': [
        'src/blowfish.cc',
        'src/bcrypt.cc',
        'src/bcrypt_node.cc'
      ],
      'cflags!': [ '-fno-exceptions' ],
      'cflags_cc!': [ '-fno-exceptions' ],
      'include_dirs' : [
          "<!@(node -p \"require('node-addon-api').include\")"
      ],
      "xcode_settings": {
        "CLANG_CXX_LIBRARY": "libc++",
        'GCC_ENABLE_CPP_EXCEPTIONS': 'YES'
      },
      'conditions': [
        [ 'OS=="win"', {
          "msvs_settings": {
            "VCCLCompilerTool": {
              "ExceptionHandling": 1
            }
          },
          'defines': [
            'uint=unsigned int',
          ]
        }]
      ]
    },
    {
      "target_name": "action_after_build",
      "type": "none",
      "dependencies": [ "<(module_name)" ],
      "copies": [
        {
          "files": [ "<(PRODUCT_DIR)/<(module_name).node" ],
          "destination": "<(module_path)"
        }
      ]
    }
  ]
}
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: UTF-8 -*-

"""
Wheel plot that shows continuous data in radial axes.
"""

import numpy as np
import sys

from jcvi.graphics.base import plt, savefig, normalize_axes, set2
from jcvi.apps.base import OptionParser, ActionDispatcher

def main():

    actions = (
        ('wheel', 'wheel plot that shows continuous data in radial axes'),
            )
    p = ActionDispatcher(actions)
    p.dispatch(globals())

def closed_plot(ax, theta, r, *args, **kwargs):
    theta = list(theta) + [theta[0]]
    r = list(r) + [r[0]]
    ax.plot(theta, r, *args, **kwargs)

def sector(ax, theta_min, theta_max, theta_pad, r, *args, **kwargs):
    theta = np.linspace(theta_min - theta_pad, theta_max + theta_pad, num=100)
    r = len(theta) * [r]
    theta = list(theta) + [0]
    r = list(r) + [0]
    closed_plot(ax, theta, r, *args, **kwargs)

def wheel(args):
    """
    %prog wheel datafile

    Wheel plot that shows continous data in radial axes.
    """
    p = OptionParser(wheel.__doc__)
    opts, args, iopts = p.set_image_options(args)

    if len(args) != 1:
        sys.exit(not p.print_help())

    datafile, = args
    pf = datafile.rsplit(".", 1)[0]
    fig = plt.figure(1, (iopts.w, iopts.h))
    root = fig.add_axes([0, 0, 1, 1])
    categories = 20
    ax = plt.subplot(111, projection='polar')
    R = 2

    # Baseline
    r = [R / 2] * categories
    theta = np.linspace(0, 2 * np.pi, endpoint=False, num=categories)
    closed_plot(ax, theta, r, "k:", lw=2)

    # Grid
    for t in theta:
        ax.plot([t, t], [0, R], color="gainsboro")
    ax.axis('off')

    # Sectors (groupings)
    groups = {1: [0, 1, 2, 3],
              2: [4, 5, 6, 7, 8],
              3: [9, 10, 11],
              4: [12, 13, 14, 15, 16],
              5: [17],
              6: [18, 19]}

    theta_interval = 2 * np.pi / categories
    theta_pad = theta_interval / 2 * .9
    for color, group in zip(set2, groups.values()):
        tmin, tmax = min(group), max(group)
        sector(ax, theta[tmin], theta[tmax], theta_pad, R * .95,
                   "-", color=color)

    # Data
    r = np.random.uniform(0, R, size=categories)
    closed_plot(ax, theta, r, color="lightslategray")
    ax.set_rmax(R)

    normalize_axes(root)

    image_name = pf + "." + iopts.format
    savefig(image_name, dpi=iopts.dpi, iopts=iopts)

if __name__ == '__main__':
    main()
<commit_msg>[graphics] Add colors<commit_after>#!/usr/bin/env python
# -*- coding: UTF-8 -*-

"""
Wheel plot that shows continuous data in radial axes.
"""

import numpy as np
import sys

from collections import OrderedDict
from itertools import groupby

from jcvi.graphics.base import plt, savefig, normalize_axes, set2
from jcvi.apps.base import OptionParser, ActionDispatcher

R = 30

def main():

    actions = (
        ('wheel', 'wheel plot that shows continuous data in radial axes'),
            )
    p = ActionDispatcher(actions)
    p.dispatch(globals())

def closed_plot(ax, theta, r, *args, **kwargs):
    theta = list(theta) + [theta[0]]
    r = list(r) + [r[0]]
    ax.plot(theta, r, *args, **kwargs)

def sector(ax, theta_min, theta_max, theta_pad, r, *args, **kwargs):
    theta = np.linspace(theta_min - theta_pad, theta_max + theta_pad, num=100)
    r = len(theta) * [r]
    theta = list(theta) + [0]
    r = list(r) + [-R]
    closed_plot(ax, theta, r, *args, **kwargs)

def parse_data(datafile):
    data = {}
    fp = open(datafile)
    for row in fp:
        label, score, percentile = row.split(",")
        label = label.strip()
        score = float(score.strip())
        data[label] = score
    return data

def parse_groups(groupsfile):
    groups = OrderedDict()
    fp = open(groupsfile)
    for row in fp:
        group, label = row.split(",")
        group = group.strip()
        label = label.strip()
        groups[label] = group
    return groups

def wheel(args):
    """
    %prog wheel datafile.csv groups.csv

    Wheel plot that shows continous data in radial axes.
    """
    p = OptionParser(wheel.__doc__)
    opts, args, iopts = p.set_image_options(args, figsize="10x10")

    if len(args) != 2:
        sys.exit(not p.print_help())

    datafile, groupsfile = args
    df = parse_data(datafile)
    groups = parse_groups(groupsfile)
    labels = [g for g in groups if g in df]
    print labels
    df = [df[g] for g in labels]
    print df
    groups = [groups[g] for g in labels]
    print groups

    pf = datafile.rsplit(".", 1)[0]
    fig = plt.figure(1, (iopts.w, iopts.h))
    root = fig.add_axes([0, 0, 1, 1])
    categories = len(df)
    ax = plt.subplot(111, projection='polar')

    brewer = ["#a6cee3", "#1f78b4", "#b2df8a", "#33a02c",
              "#fb9a99", "#e31a1c", "#fdbf6f", "#ff7f00",
              "#cab2d6", "#6a3d9a", "#ffff99", "#b15928"]
    # Baseline
    theta = np.linspace(0, 2 * np.pi, endpoint=False, num=categories)
    _theta = np.linspace(0, 2 * np.pi)
    _r = len(_theta) * [0]
    closed_plot(ax, _theta, _r, "k:", lw=2)

    # Grid
    for t in theta:
        ax.plot([t, t], [-R, R], color="gainsboro")
    ax.axis('off')

    # Sectors (groupings)
    gg = {}
    for group, c in groupby(enumerate(groups), lambda x: x[1]):
        c = [x[0] for x in list(c)]
        gg[group] = c
    print gg

    theta_interval = 2 * np.pi / categories
    theta_pad = theta_interval / 2 * .9
    for color, group in zip(brewer, gg.values()):
        tmin, tmax = min(group), max(group)
        sector(ax, theta[tmin], theta[tmax], theta_pad, R * .95,
                   "-", color=color)

    # Data
    r = df
    closed_plot(ax, theta, r, color="lightslategray")
    for color, group in zip(brewer, gg.values()):
        color_theta = [theta[x] for x in group]
        color_r = [r[x] for x in group]
        ax.plot(color_theta, color_r, "o")

    ax.set_rmin(-R)
    ax.set_rmax(R)

    normalize_axes(root)

    image_name = pf + "." + iopts.format
    savefig(image_name, dpi=iopts.dpi, iopts=iopts)

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# NAME
#
#        med2image
#
# DESCRIPTION
#
#        'med2image' converts from medical image data files to
#        display-friendly formats (like png and jpg).
#
# HISTORY
#
# 23 February 2015
# o Initial design and coding.
#

# System imports
import     os
import     sys
import     getpass
import     argparse
import     time
import     numpy             as         np
from       random            import     randint

# System dependency imports
import     nibabel           as         nib
import     dicom
import     pylab
import     matplotlib.cm     as         cm

# Project specific imports
import     error
import     message           as msg
from       _common           import     systemMisc     as misc
from       _common._colors   import     Colors

class med2image(object):
    """
        med2image accepts as input certain medical image formatted data
        and converts each (or specified) slice of this data to a graphical
        display format such as png or jpg.

    """

    _dictErr = {
        'inputFileFail'   : {
            'action'        : 'trying to read input file, ',
            'error'         : 'could not access/read file -- does it exist? Do you have permission?',
            'exitCode'      : 10},
        'emailFail'   : {
            'action'        : 'attempting to send notification email, ',
            'error'         : 'sending failed. Perhaps host is not email configured?',
            'exitCode'      : 20},
    }

    def description(self, *args):
        '''
        Get / set internal object description.
        '''
        if len(args):
            self._str_desc = args[0]
        else:
            return self._str_desc

    def log(self): return self._log

    def __init__(self, **kwargs):

        #
        # Object desc block
        #
        self._str_desc                  = ''

        # Directory and filenames
        self._str_workingDir            = ''
        self._str_inputFile             = ''
        self._str_outputFileStem        = ''
        self._str_outputFileType        = ''
        self._str_outputDir             = ''

        self._b_convertAllSlices        = False
        self._str_sliceToConvert        = ''
        self._str_frameToConvert        = ''
        self._sliceToConvert            = -1
        self._frameToConvert            = -1

        self._str_stdout                = ""
        self._str_stderr                = ""
        self._exitCode                  = 0

        # The actual data volume and slice
        # are numpy ndarrays
        self._b_4D                      = False
        self._b_3D                      = False
        self._b_DICOM                   = False
        self._Vnp_4DVol                 = None
        self._Vnp_3DVol                 = None
        self._Mnp_2Dslice               = None
        self._dcm                       = None

        # A logger
        self._log                       = msg.Message()
        self._log.syslog(True)

        # Flags
        self._b_showSlices              = False
        self._b_convertMiddleSlice      = False
        self._b_convertMiddleFrame      = False

        for key, value in kwargs.iteritems():
            if key == "inputFile":          self._str_inputFile         = value
            if key == "outputDir":          self._str_outputDir         = value
            if key == "outputFileStem":     self._str_outputFileStem    = value
            if key == "outputFileType":     self._str_outputFileType    = value
            if key == "sliceToConvert":     self._str_sliceToConvert    = value
            if key == "frameToConvert":     self._str_frameToConvert    = value
            if key == "showSlices":         self._b_showSlices          = value

        if self._str_frameToConvert.lower() == 'm':
            self._b_convertMiddleFrame = True
        elif len(self._str_frameToConvert):
            self._frameToConvert = int(self._str_frameToConvert)

        if self._str_sliceToConvert.lower() == 'm':
            self._b_convertMiddleSlice = True
        elif len(self._str_sliceToConvert):
            self._sliceToConvert = int(self._str_sliceToConvert)

        str_fileName, str_fileExtension  = os.path.splitext(self._str_outputFileStem)
        if len(self._str_outputFileType):
            str_fileExtension            = '.%s' % self._str_outputFileType

        if len(str_fileExtension) and not len(self._str_outputFileType):
            self._str_outputFileType     = str_fileExtension

        if not len(self._str_outputFileType) and not len(str_fileExtension):
            self._str_outputFileType     = '.png'

    def run(self):
        '''
        The main 'engine' of the class.
        '''

    def echo(self, *args):
        self._b_echoCmd         = True
        if len(args):
            self._b_echoCmd     = args[0]

    def echoStdOut(self, *args):
        self._b_echoStdOut      = True
        if len(args):
            self._b_echoStdOut  = args[0]

    def stdout(self):
        return self._str_stdout

    def stderr(self):
        return self._str_stderr

    def exitCode(self):
        return self._exitCode

    def echoStdErr(self, *args):
        self._b_echoStdErr      = True
        if len(args):
            self._b_echoStdErr  = args[0]

    def dontRun(self, *args):
        self._b_runCmd          = False
        if len(args):
            self._b_runCmd      = args[0]

    def workingDir(self, *args):
        if len(args):
            self._str_workingDir = args[0]
        else:
            return self._str_workingDir

    def slice_save(self, astr_outputFile):
        '''
        Processes/saves a single slice.

        ARGS

        o astr_output
        The output filename to save the slice to.

        '''
        self._log('outputfile = %s\n' % astr_outputFile)
        pylab.imsave(astr_outputFile, self._Mnp_2Dslice, cmap = cm.Greys_r)

class med2image_dcm(med2image):
    '''
    Sub class that handles DICOM data.
    '''
    def __init__(self, **kwargs):
        med2image.__init__(self, **kwargs)
        self._dcm = dicom.read_file(self._str_inputFile)
        image = self._dcm.pixel_array
        self._Mnp_2Dslice = image

    def run(self):
        '''
        Runs the DICOM conversion based on internal state.
        '''
        self._log('Converting DICOM image.\n')
        self._log('PatientName:    %s\n' % self._dcm.PatientName)
        self._log('PatientAge:     %s\n' % self._dcm.PatientAge)
        self._log('PatientSex:     %s\n' % self._dcm.PatientSex)
        self._log('PatientID:      %s\n' % self._dcm.PatientID)
        misc.mkdir(self._str_outputDir)
        str_outputFile = '%s/%s.%s' % (self._str_outputDir,
                                       self._str_outputFileStem,
                                       self._str_outputFileType)
        self.slice_save(str_outputFile)

class med2image_nii(med2image):
    '''
    Sub class that handles NIfTI data.
    '''

    def __init__(self, **kwargs):
        med2image.__init__(self, **kwargs)
        nimg = nib.load(self._str_inputFile)
        data = nimg.get_data()
        if data.ndim == 4:
            self._Vnp_4DVol     = data
            self._b_4D          = True
        if data.ndim == 3:
            self._Vnp_3DVol     = data
            self._b_3D          = True

    def run(self):
        '''
        Runs the NIfTI conversion based on internal state.
        '''

        self._log('About to perform NifTI to %s conversion...\n' %
                  self._str_outputFileType)

        frames     = 1
        frameStart = 0
        frameEnd   = 0

        sliceStart = 0
        sliceEnd   = 0

        if self._b_4D:
            self._log('4D volume detected.\n')
            frames = self._Vnp_4DVol.shape[3]
        if self._b_3D:
            self._log('3D volume detected.\n')

        if self._b_convertMiddleFrame:
            self._frameToConvert = int(frames/2)

        if self._frameToConvert == -1:
            frameEnd    = frames
        else:
            frameStart  = self._frameToConvert
            frameEnd    = self._frameToConvert + 1

        for f in range(frameStart, frameEnd):
            if self._b_4D:
                self._Vnp_3DVol = self._Vnp_4DVol[:,:,:,f]
            slices     = self._Vnp_3DVol.shape[2]
            if self._b_convertMiddleSlice:
                self._sliceToConvert = int(slices/2)

            if self._sliceToConvert == -1:
                sliceEnd    = self._Vnp_3DVol.shape[2]
            else:
                sliceStart  = self._sliceToConvert
                sliceEnd    = self._sliceToConvert + 1

            misc.mkdir(self._str_outputDir)
            for i in range(sliceStart, sliceEnd):
                imslice                 = self._Vnp_3DVol[:,:,i]
                # rotate the slice by 90 for conventional display
                self._Mnp_2Dslice       = np.rot90(imslice)

                if self._b_4D:
                    str_outputFile = '%s/%s-frame%03d-slice%03d.%s' % (
                                                            self._str_outputDir,
                                                            self._str_outputFileStem,
                                                            f, i,
                                                            self._str_outputFileType)
                else:
                    str_outputFile = '%s/%s-slice%03d.%s' % (self._str_outputDir,
                                                            self._str_outputFileStem,
                                                            i,
                                                            self._str_outputFileType)
                self.slice_save(str_outputFile)

def synopsis(ab_shortOnly = False):
    scriptName = os.path.basename(sys.argv[0])
    shortSynopsis =  '''
    SYNOPSIS

            %s                                   \\
                    -i|--input <inputFile>                 \\
                    [-d|--outputDir <outputDir>]           \\
                    -o|--output <outputFileStem>           \\
                    [--outputFileType <outputFileType>]    \\
                    [--sliceToConvert <sliceToConvert>]    \\
                    [--frameToConvert <frameToConvert>]    \\
                    [--showSlices]                         \\
                    [--man|--synopsis]
    ''' % scriptName

    description =  '''
    DESCRIPTION

        `%s' converts input medical image formatted data to a more
        display friendly format.

        Currently understands nifti and dicom.

    ARGS

        -i|--inputFile <inputFile>
        Input file to convert. Typically a DICOM file or a nifti volume.

        [-d|--outputDir <outputDir>]
        The directory to contain the converted output image files.

        -o|--outputFileStem <outputFileStem>
        The output file stem to store conversion. If this is specified
        with an extension, this extension will be used to specify the
        output file type.

        [--outputFileType <outputFileType>]
        The output file type. If different to <outputFileStem> extension,
        will override extension in favour of <outputFileType>.

        [--sliceToConvert <sliceToConvert>]
        In the case of volume files, the slice (z) index to convert. Ignored
        for 2D input data. If a '-1' is sent, then convert *all* the slices.
        If an 'm' is specified, only convert the middle slice in an input
        volume.

        [--frameToConvert <sliceToConvert>]
        In the case of 4D volume files, the volume (V) containing the
        slice (z) index to convert. Ignored for 3D input data. If a '-1' is
        sent, then convert *all* the frames. If an 'm' is specified, only
        convert the middle frame in the 4D input stack.

        [--showSlices]
        If specified, render/show image slices as they are created.

        [--man|--synopsis]
        Show either full help or short synopsis.

    EXAMPLES

    NIfTI

    o Convert each slice in a NIfTI volume to a jpg in a sub dir called
      'out' and start the name each converted file with 'vol', do

    med2image.py -i input.nii -d out -o vol --outputFileType jpg --sliceToConvert -1

    o Convert only the middle slice in an input volume

    med2image.py -i input.nii -d out -o vol --outputFileType jpg --sliceToConvert m

    o Convert a specific slice, i.e. slice 20

    med2image.py -i input.nii -d out -o vol --outputFileType jpg --sliceToConvert 20

    DICOM

    o Convert a DICOM file called slice.dcm

    med2image.py -i slice.dcm -d out -o slice --outputFileType jpg

    o Convert all DICOM in a directory/series

    for F in *dcm ; do med2image.py -i $F -d out -o $F --outputFileType jpg ; done

    GITHUB

        o See https://github.com/FNNDSC/med2image for more help and source.

    ''' % (scriptName)
    if ab_shortOnly:
        return shortSynopsis
    else:
        return shortSynopsis + description

if __name__ == '__main__':

    parser = argparse.ArgumentParser(description="med2view converts an input medical image file to a more conventional graphical format.")
    parser.add_argument("-i", "--inputFile",
                        help="input file",
                        dest='inputFile')
    parser.add_argument("-o", "--outputFileStem",
                        help="output file",
                        dest='outputFileStem')
    parser.add_argument("-d", "--outputDir",
                        help="output image directory",
                        dest='outputDir',
                        default='./')
    parser.add_argument("-t", "--outputFileType",
                        help="output image type",
                        dest='outputFileType',
                        default='none')
    parser.add_argument("-s", "--sliceToConvert",
                        help="slice to convert (for 3D data)",
                        dest='sliceToConvert',
                        default='-1')
    parser.add_argument("-f", "--frameToConvert",
                        help="frame to convert (for 4D data)",
                        dest='frameToConvert',
                        default='-1')
    parser.add_argument("--printElapsedTime",
                        help="print program run time",
                        dest='printElapsedTime',
                        action='store_true',
                        default=False)
    parser.add_argument('--showSlices',
                        help="show slices that are converted",
                        dest='showSlices',
                        action='store_true',
                        default='False')
    parser.add_argument("--man",
                        help="man",
                        dest='man',
                        action='store_true',
                        default=False)
    parser.add_argument("--synopsis",
                        help="short synopsis",
                        dest='synopsis',
                        action='store_true',
                        default=False)
    args = parser.parse_args()

    if args.man or args.synopsis:
        if args.man:
            str_help     = synopsis(False)
        else:
            str_help     = synopsis(True)
        print(str_help)
        sys.exit(1)

    str_fileName, str_fileExtension  = os.path.splitext(args.inputFile)
    b_niftiExt           = (str_fileExtension   == '.nii'    or \
                            str_fileExtension   == '.gz')
    b_dicomExt           =  str_fileExtension   == '.dcm'
    if b_niftiExt:
        C_convert     = med2image_nii(
                                inputFile         = args.inputFile,
                                outputDir         = args.outputDir,
                                outputFileStem    = args.outputFileStem,
                                outputFileType    = args.outputFileType,
                                sliceToConvert    = args.sliceToConvert,
                                frameToConvert    = args.frameToConvert,
                                showSlices        = args.showSlices
                            )

    if b_dicomExt:
        C_convert   = med2image_dcm(
                                inputFile         = args.inputFile,
                                outputDir         = args.outputDir,
                                outputFileStem    = args.outputFileStem,
                                outputFileType    = args.outputFileType,
                             )

    # And now run it!
    misc.tic()
    C_convert.run()
    if args.printElapsedTime: print("Elapsed time = %f seconds" % misc.toc())
    sys.exit(0)

<commit_msg>Add more short CLI options.<commit_after>#!/usr/bin/env python
#
# NAME
#
#        med2image
#
# DESCRIPTION
#
#        'med2image' converts from medical image data files to
#        display-friendly formats (like png and jpg).
#
# HISTORY
#
# 23 February 2015
# o Initial design and coding.
#

# System imports
import     os
import     sys
import     getpass
import     argparse
import     time
import     numpy             as         np
from       random            import     randint

# System dependency imports
import     nibabel           as         nib
import     dicom
import     pylab
import     matplotlib.cm     as         cm

# Project specific imports
import     error
import     message           as msg
from       _common           import     systemMisc     as misc
from       _common._colors   import     Colors

class med2image(object):
    """
        med2image accepts as input certain medical image formatted data
        and converts each (or specified) slice of this data to a graphical
        display format such as png or jpg.

    """

    _dictErr = {
        'inputFileFail'   : {
            'action'        : 'trying to read input file, ',
            'error'         : 'could not access/read file -- does it exist? Do you have permission?',
            'exitCode'      : 10},
        'emailFail'   : {
            'action'        : 'attempting to send notification email, ',
            'error'         : 'sending failed. Perhaps host is not email configured?',
            'exitCode'      : 20},
    }

    def description(self, *args):
        '''
        Get / set internal object description.
        '''
        if len(args):
            self._str_desc = args[0]
        else:
            return self._str_desc

    def log(self): return self._log

    def __init__(self, **kwargs):

        #
        # Object desc block
        #
        self._str_desc                  = ''

        # Directory and filenames
        self._str_workingDir            = ''
        self._str_inputFile             = ''
        self._str_outputFileStem        = ''
        self._str_outputFileType        = ''
        self._str_outputDir             = ''

        self._b_convertAllSlices        = False
        self._str_sliceToConvert        = ''
        self._str_frameToConvert        = ''
        self._sliceToConvert            = -1
        self._frameToConvert            = -1

        self._str_stdout                = ""
        self._str_stderr                = ""
        self._exitCode                  = 0

        # The actual data volume and slice
        # are numpy ndarrays
        self._b_4D                      = False
        self._b_3D                      = False
        self._b_DICOM                   = False
        self._Vnp_4DVol                 = None
        self._Vnp_3DVol                 = None
        self._Mnp_2Dslice               = None
        self._dcm                       = None

        # A logger
        self._log                       = msg.Message()
        self._log.syslog(True)

        # Flags
        self._b_showSlices              = False
        self._b_convertMiddleSlice      = False
        self._b_convertMiddleFrame      = False

        for key, value in kwargs.iteritems():
            if key == "inputFile":          self._str_inputFile         = value
            if key == "outputDir":          self._str_outputDir         = value
            if key == "outputFileStem":     self._str_outputFileStem    = value
            if key == "outputFileType":     self._str_outputFileType    = value
            if key == "sliceToConvert":     self._str_sliceToConvert    = value
            if key == "frameToConvert":     self._str_frameToConvert    = value
            if key == "showSlices":         self._b_showSlices          = value

        if self._str_frameToConvert.lower() == 'm':
            self._b_convertMiddleFrame = True
        elif len(self._str_frameToConvert):
            self._frameToConvert = int(self._str_frameToConvert)

        if self._str_sliceToConvert.lower() == 'm':
            self._b_convertMiddleSlice = True
        elif len(self._str_sliceToConvert):
            self._sliceToConvert = int(self._str_sliceToConvert)

        str_fileName, str_fileExtension  = os.path.splitext(self._str_outputFileStem)
        if len(self._str_outputFileType):
            str_fileExtension            = '.%s' % self._str_outputFileType

        if len(str_fileExtension) and not len(self._str_outputFileType):
            self._str_outputFileType     = str_fileExtension

        if not len(self._str_outputFileType) and not len(str_fileExtension):
            self._str_outputFileType     = '.png'

    def run(self):
        '''
        The main 'engine' of the class.
        '''

    def echo(self, *args):
        self._b_echoCmd         = True
        if len(args):
            self._b_echoCmd     = args[0]

    def echoStdOut(self, *args):
        self._b_echoStdOut      = True
        if len(args):
            self._b_echoStdOut  = args[0]

    def stdout(self):
        return self._str_stdout

    def stderr(self):
        return self._str_stderr

    def exitCode(self):
        return self._exitCode

    def echoStdErr(self, *args):
        self._b_echoStdErr      = True
        if len(args):
            self._b_echoStdErr  = args[0]

    def dontRun(self, *args):
        self._b_runCmd          = False
        if len(args):
            self._b_runCmd      = args[0]

    def workingDir(self, *args):
        if len(args):
            self._str_workingDir = args[0]
        else:
            return self._str_workingDir

    def slice_save(self, astr_outputFile):
        '''
        Processes/saves a single slice.

        ARGS

        o astr_output
        The output filename to save the slice to.

        '''
        self._log('outputfile = %s\n' % astr_outputFile)
        pylab.imsave(astr_outputFile, self._Mnp_2Dslice, cmap = cm.Greys_r)

class med2image_dcm(med2image):
    '''
    Sub class that handles DICOM data.
    '''
    def __init__(self, **kwargs):
        med2image.__init__(self, **kwargs)
        self._dcm = dicom.read_file(self._str_inputFile)
        image = self._dcm.pixel_array
        self._Mnp_2Dslice = image

    def run(self):
        '''
        Runs the DICOM conversion based on internal state.
        '''
        self._log('Converting DICOM image.\n')
        self._log('PatientName:    %s\n' % self._dcm.PatientName)
        self._log('PatientAge:     %s\n' % self._dcm.PatientAge)
        self._log('PatientSex:     %s\n' % self._dcm.PatientSex)
        self._log('PatientID:      %s\n' % self._dcm.PatientID)
        misc.mkdir(self._str_outputDir)
        str_outputFile = '%s/%s.%s' % (self._str_outputDir,
                                       self._str_outputFileStem,
                                       self._str_outputFileType)
        self.slice_save(str_outputFile)

class med2image_nii(med2image):
    '''
    Sub class that handles NIfTI data.
    '''

    def __init__(self, **kwargs):
        med2image.__init__(self, **kwargs)
        nimg = nib.load(self._str_inputFile)
        data = nimg.get_data()
        if data.ndim == 4:
            self._Vnp_4DVol     = data
            self._b_4D          = True
        if data.ndim == 3:
            self._Vnp_3DVol     = data
            self._b_3D          = True

    def run(self):
        '''
        Runs the NIfTI conversion based on internal state.
        '''

        self._log('About to perform NifTI to %s conversion...\n' %
                  self._str_outputFileType)

        frames     = 1
        frameStart = 0
        frameEnd   = 0

        sliceStart = 0
        sliceEnd   = 0

        if self._b_4D:
            self._log('4D volume detected.\n')
            frames = self._Vnp_4DVol.shape[3]
        if self._b_3D:
            self._log('3D volume detected.\n')

        if self._b_convertMiddleFrame:
            self._frameToConvert = int(frames/2)

        if self._frameToConvert == -1:
            frameEnd    = frames
        else:
            frameStart  = self._frameToConvert
            frameEnd    = self._frameToConvert + 1

        for f in range(frameStart, frameEnd):
            if self._b_4D:
                self._Vnp_3DVol = self._Vnp_4DVol[:,:,:,f]
            slices     = self._Vnp_3DVol.shape[2]
            if self._b_convertMiddleSlice:
                self._sliceToConvert = int(slices/2)

            if self._sliceToConvert == -1:
                sliceEnd    = self._Vnp_3DVol.shape[2]
            else:
                sliceStart  = self._sliceToConvert
                sliceEnd    = self._sliceToConvert + 1

            misc.mkdir(self._str_outputDir)
            for i in range(sliceStart, sliceEnd):
                imslice                 = self._Vnp_3DVol[:,:,i]
                # rotate the slice by 90 for conventional display
                self._Mnp_2Dslice       = np.rot90(imslice)

                if self._b_4D:
                    str_outputFile = '%s/%s-frame%03d-slice%03d.%s' % (
                                                            self._str_outputDir,
                                                            self._str_outputFileStem,
                                                            f, i,
                                                            self._str_outputFileType)
                else:
                    str_outputFile = '%s/%s-slice%03d.%s' % (self._str_outputDir,
                                                            self._str_outputFileStem,
                                                            i,
                                                            self._str_outputFileType)
                self.slice_save(str_outputFile)

def synopsis(ab_shortOnly = False):
    scriptName = os.path.basename(sys.argv[0])
    shortSynopsis =  '''
    SYNOPSIS

            %s                                   \\
                     -i|--input <inputFile>                \\
                    [-d|--outputDir <outputDir>]           \\
                     -o|--output <outputFileStem>          \\
                    [-t|--outputFileType <outputFileType>] \\
                    [-s|--sliceToConvert <sliceToConvert>] \\
                    [-f|--frameToConvert <frameToConvert>] \\
                    [--showSlices]                         \\
                    [--man|--synopsis]
    ''' % scriptName

    description =  '''
    DESCRIPTION

        `%s' converts input medical image formatted data to a more
        display friendly format.

        Currently understands nifti and dicom.

    ARGS

        -i|--inputFile <inputFile>
        Input file to convert. Typically a DICOM file or a nifti volume.

        [-d|--outputDir <outputDir>]
        The directory to contain the converted output image files.

        -o|--outputFileStem <outputFileStem>
        The output file stem to store conversion. If this is specified
        with an extension, this extension will be used to specify the
        output file type.

        [-t|--outputFileType <outputFileType>]
        The output file type. If different to <outputFileStem> extension,
        will override extension in favour of <outputFileType>.

        [-s|--sliceToConvert <sliceToConvert>]
        In the case of volume files, the slice (z) index to convert. Ignored
        for 2D input data. If a '-1' is sent, then convert *all* the slices.
        If an 'm' is specified, only convert the middle slice in an input
        volume.

        [-f|--frameToConvert <sliceToConvert>]
        In the case of 4D volume files, the volume (V) containing the
        slice (z) index to convert. Ignored for 3D input data. If a '-1' is
        sent, then convert *all* the frames. If an 'm' is specified, only
        convert the middle frame in the 4D input stack.

        [--showSlices]
        If specified, render/show image slices as they are created.

        [--man|--synopsis]
        Show either full help or short synopsis.

    EXAMPLES

    NIfTI

    o Convert each slice in a NIfTI volume to a jpg in a sub dir called
      'out' and start the name each converted file with 'vol', do

    med2image.py -i input.nii -d out -o vol --outputFileType jpg --sliceToConvert -1

    o Convert only the middle slice in an input volume

    med2image.py -i input.nii -d out -o vol --outputFileType jpg --sliceToConvert m

    o Convert a specific slice, i.e. slice 20

    med2image.py -i input.nii -d out -o vol --outputFileType jpg --sliceToConvert 20

    DICOM

    o Convert a DICOM file called slice.dcm

    med2image.py -i slice.dcm -d out -o slice --outputFileType jpg

    o Convert all DICOM in a directory/series

    for F in *dcm ; do med2image.py -i $F -d out -o $F --outputFileType jpg ; done

    GITHUB

        o See https://github.com/FNNDSC/med2image for more help and source.

    ''' % (scriptName)
    if ab_shortOnly:
        return shortSynopsis
    else:
        return shortSynopsis + description

if __name__ == '__main__':

    parser = argparse.ArgumentParser(description="med2view converts an input medical image file to a more conventional graphical format.")
    parser.add_argument("-i", "--inputFile",
                        help="input file",
                        dest='inputFile')
    parser.add_argument("-o", "--outputFileStem",
                        help="output file",
                        dest='outputFileStem')
    parser.add_argument("-d", "--outputDir",
                        help="output image directory",
                        dest='outputDir',
                        default='./')
    parser.add_argument("-t", "--outputFileType",
                        help="output image type",
                        dest='outputFileType',
                        default='none')
    parser.add_argument("-s", "--sliceToConvert",
                        help="slice to convert (for 3D data)",
                        dest='sliceToConvert',
                        default='-1')
    parser.add_argument("-f", "--frameToConvert",
                        help="frame to convert (for 4D data)",
                        dest='frameToConvert',
                        default='-1')
    parser.add_argument("--printElapsedTime",
                        help="print program run time",
                        dest='printElapsedTime',
                        action='store_true',
                        default=False)
    parser.add_argument('--showSlices',
                        help="show slices that are converted",
                        dest='showSlices',
                        action='store_true',
                        default='False')
    parser.add_argument("--man",
                        help="man",
                        dest='man',
                        action='store_true',
                        default=False)
    parser.add_argument("--synopsis",
                        help="short synopsis",
                        dest='synopsis',
                        action='store_true',
                        default=False)
    args = parser.parse_args()

    if args.man or args.synopsis:
        if args.man:
            str_help     = synopsis(False)
        else:
            str_help     = synopsis(True)
        print(str_help)
        sys.exit(1)

    str_fileName, str_fileExtension  = os.path.splitext(args.inputFile)
    b_niftiExt           = (str_fileExtension   == '.nii'    or \
                            str_fileExtension   == '.gz')
    b_dicomExt           =  str_fileExtension   == '.dcm'
    if b_niftiExt:
        C_convert     = med2image_nii(
                                inputFile         = args.inputFile,
                                outputDir         = args.outputDir,
                                outputFileStem    = args.outputFileStem,
                                outputFileType    = args.outputFileType,
                                sliceToConvert    = args.sliceToConvert,
                                frameToConvert    = args.frameToConvert,
                                showSlices        = args.showSlices
                            )

    if b_dicomExt:
        C_convert   = med2image_dcm(
                                inputFile         = args.inputFile,
                                outputDir         = args.outputDir,
                                outputFileStem    = args.outputFileStem,
                                outputFileType    = args.outputFileType,
                             )

    # And now run it!
    misc.tic()
    C_convert.run()
    if args.printElapsedTime: print("Elapsed time = %f seconds" % misc.toc())
    sys.exit(0)

<|endoftext|>