コード例 #1
0
ファイル: conflicts_solver.py プロジェクト: neutrons/FastGR
    def _add_tab(self, json=None):
        """will look at the json and will display the values in conflicts in a new tab to allow the user
        to fix the conflicts"""

        number_of_tabs = self.ui.tabWidget.count()

        _table = QTableWidget()

        # initialize each table
        columns_width = self._calculate_columns_width(json=json)
        for _col in np.arange(len(json[0])):
            _table.insertColumn(_col)
            _table.setColumnWidth(_col, columns_width[_col])
        for _row in np.arange(len(json)):
            _table.insertRow(_row)
        self.list_table.append(_table)

        _table.setHorizontalHeaderLabels(self.columns_label)

        for _row in np.arange(len(json)):

            # run number
            _col = 0
            list_runs = json[_row]["Run Number"]
            o_parser = ListRunsParser()
            checkbox = QRadioButton(o_parser.new_runs(list_runs=list_runs))
            if _row == 0:
                checkbox.setChecked(True)
            # QtCore.QObject.connect(checkbox, QtCore.SIGNAL("clicked(bool)"),
            #                        lambda bool, row=_row, table_id=_table:
            #                        self._changed_conflict_checkbox(bool, row, table_id))
            _table.setCellWidget(_row, _col, checkbox)

            _col += 1
            # chemical formula
            item = QTableWidgetItem(json[_row]["chemical_formula"])
            _table.setItem(_row, _col, item)

            _col += 1
            # geometry
            item = QTableWidgetItem(json[_row]["geometry"])
            _table.setItem(_row, _col, item)

            _col += 1
            # mass_density
            item = QTableWidgetItem(json[_row]["mass_density"])
            _table.setItem(_row, _col, item)

            _col += 1
            # sample_env_device
            item = QTableWidgetItem(json[_row]["sample_env_device"])
            _table.setItem(_row, _col, item)

        self.ui.tabWidget.insertTab(number_of_tabs, _table, "Conflict #{}".format(number_of_tabs))
コード例 #2
0
class GroupsPostView(QDialog):
    """
    +------------------------+
    |  Groups : Post/Delete  |
    +------------------------+
    |                        |
    |   check1      Name1    |
    |   check2      Name2    |
    |   check3      Name3    |
    |                        |
    |       SetAsMain        |
    |   Apply   OK   Close   |
    +------------------------+
    """
    def __init__(self, data, win_parent=None):
        self.win_parent = win_parent
        #Init the base class

        groups = data['groups']
        inames = data['inames']
        self.imain = data['imain']
        self.names = [group.name for group in groups]
        self.white = (255, 255, 255)
        self.light_grey = (211, 211, 211)
        self.inames = inames
        self.shown_set = data['shown']
        self.deleted_groups = set()
        #self.inames = argsort(self.names)
        #print('inames =', inames)

        anames = array(self.names)
        for iname, name in enumerate(anames[self.inames]):
            print('name[%s] = %r' % (iname, name))

        # ignore these...
        #self._default_name = data['name']
        #self._default_coords = data['coords']
        #self._default_elements = data['elements']
        #self._default_color = data['color']

        #self.coords_pound = data['coords_pound']
        #self.elements_pound = data['elements_pound']

        #self._default_is_discrete = data['is_discrete']

        self.out_data = data

        QDialog.__init__(self, win_parent)
        #self.setupUi(self)
        self.setWindowTitle('Groups: Post/View')
        self.create_widgets()
        self.create_layout()
        self.set_connections()
        #self.show()

    def create_widgets(self):
        # main/delete/supergroup
        self.set_as_main_button = QPushButton("Set As Main")
        self.create_super_group_button = QPushButton("Create Super Group")
        self.delete_groups_button = QPushButton("Delete Groups")
        self.revert_groups_button = QPushButton("Revert Groups")

        self.show_groups_button = QPushButton("Show Groups")
        self.hide_groups_button = QPushButton("Hide Groups")

        # closing
        self.apply_button = QPushButton("Apply")
        self.ok_button = QPushButton("OK")
        self.cancel_button = QPushButton("Cancel")

        #table
        self.table = QTableWidget()
        self.checks = []
        self.names_text = []

        bold = QtGui.QFont()
        bold.setBold(True)
        bold.setItalic(True)
        bold.setWeight(75)
        anames = array(self.names)
        for iname, name in enumerate(anames[self.inames]):
            check = QTableWidgetItem()
            check.setCheckState(False)

            # TODO: create right click menu ???
            name_text = QTableWidgetItem(str(name))
            if iname == self.imain:
                name_text.setFont(bold)
                self.shown_set.add(iname)
                check.setCheckState(2)
                name_text.setBackground(QtGui.QColor(*self.light_grey))
            elif iname in self.shown_set:
                name_text.setBackground(QtGui.QColor(*self.light_grey))

            self.checks.append(check)
            self.names_text.append(name_text)

    def create_layout(self):
        nrows = len(self.names)
        table = self.table
        table.setRowCount(nrows)
        table.setColumnCount(2)
        headers = [QString('Operate On'), QString('Name')]
        table.setHorizontalHeaderLabels(headers)

        header = table.horizontalHeader()
        header.setStretchLastSection(True)

        #table.setAlternatingRowColors(True)

        #header = table.verticalHeader()
        #header.setStretchLastSection(True)
        #table.resize(400, 250)

        #heighti = table.rowHeight(0)
        #total_height = nrows * heighti
        #table.setMaximumHeight(total_height)
        #table.resize(total_height, None)

        #for iname, name in enumerate(self.names[self.inames]):
        #print('name[%s] = %r' % (iname, name))
        for iname in self.inames:
            check = self.checks[iname]
            name_text = self.names_text[iname]
            # row, col, value
            table.setItem(iname, 0, check)
            table.setItem(iname, 1, name_text)
        table.resizeRowsToContents()
        #table.horizontalHeaderItem(1).setTextAlignment(QtCore.AlignHCenter)

        #= QVBoxLayout()
        ok_cancel_box = QHBoxLayout()
        ok_cancel_box.addWidget(self.apply_button)
        ok_cancel_box.addWidget(self.ok_button)
        ok_cancel_box.addWidget(self.cancel_button)

        vbox = QVBoxLayout()
        vbox.addWidget(table)
        vbox.addWidget(self.set_as_main_button)
        #vbox.addWidget(self.create_super_group_button)

        vbox.addStretch()
        vbox.addWidget(self.show_groups_button)
        vbox.addWidget(self.hide_groups_button)
        vbox.addStretch()
        vbox.addWidget(self.delete_groups_button)
        vbox.addWidget(self.revert_groups_button)
        vbox.addStretch()

        vbox.addStretch()
        vbox.addLayout(ok_cancel_box)

        self.setLayout(vbox)

    def set_connections(self):
        """creates the actions for the menu"""
        self.set_as_main_button.clicked.connect(self.on_set_as_main)
        self.delete_groups_button.clicked.connect(self.on_delete_groups)
        self.revert_groups_button.clicked.connect(self.on_revert_groups)

        self.show_groups_button.clicked.connect(self.on_show_groups)
        self.hide_groups_button.clicked.connect(self.on_hide_groups)

        self.create_super_group_button.clicked.connect(
            self.on_create_super_group)

        self.apply_button.clicked.connect(self.on_apply)
        self.ok_button.clicked.connect(self.on_ok)
        self.cancel_button.clicked.connect(self.on_cancel)

    def closeEvent(self, event):
        event.accept()

    @property
    def nrows(self):
        return self.table.rowCount()

    def on_hide_groups(self):
        self._set_highlight(self.white)

    def on_show_groups(self):
        self._set_highlight(self.light_grey)

    def _set_highlight(self, color):
        for irow in range(self.nrows):
            check = self.checks[irow]
            is_checked = check.checkState()

            # 0 - unchecked
            # 1 - partially checked (invalid)
            # 2 - checked
            if is_checked:
                name_text = self.names_text[irow]
                name_text.setBackground(QtGui.QColor(*color))

    def on_delete_groups(self):
        for irow in range(self.nrows):
            check = self.checks[irow]
            is_checked = check.checkState()

            # 0 - unchecked
            # 1 - partially checked (invalid)
            # 2 - checked
            if irow == 0 and is_checked:
                # TODO: change this to a log
                print('error deleting group ALL...change this to a log')
                #self.window_parent.log
                return
            if is_checked:
                self.table.hideRow(irow)
                self.deleted_groups.add(irow)
                check.setCheckState(0)

        if self.imain > 0 and self.shown_set == set([0]):
            bold = QtGui.QFont()
            bold.setBold(True)
            bold.setItalic(True)

            self.imain = 0
            irow = 0
            check = self.checks[irow]
            name_text = self.names_texts[irow]
            name_text.setFont(bold)
            name_text.setBackground(QtGui.QColor(*self.light_grey))

    def on_revert_groups(self):
        for irow in range(self.nrows):
            self.table.showRow(irow)
        self.deleted_groups = set()

    def on_create_super_group(self):
        inames = [
            iname for iname, check in enumerate(self.checks)
            if bool(check.checkState())
        ]

        if not len(inames):
            # TODO: add logging
            print('nothing is checked...')
            return
        if inames[0] == 0:
            # TODO: add logging
            print("cannot include 'ALL' in supergroup...")
            return

        name = 'SuperGroup'
        # popup gui and get a name

        irow = self.table.rowCount()
        self.table.insertRow(irow)

        check = QTableWidgetItem()
        check.setCheckState(False)
        name_text = QTableWidgetItem(str(name))

        self.names.extend(name)
        self.names_text.append(name_text)
        self.checks.append(check)

        self.table.setItem(irow, 0, check)
        self.table.setItem(irow, 1, name_text)

    def on_set_as_main(self):
        bold = QtGui.QFont()
        bold.setBold(True)
        bold.setItalic(True)

        normal = QtGui.QFont()
        normal.setBold(False)
        normal.setItalic(False)

        imain = None
        imain_set = False
        for irow in range(self.nrows):
            check = self.checks[irow]
            name_text = self.names_text[irow]
            is_checked = check.checkState()

            # 0 - unchecked
            # 1 - partially checked (invalid)
            # 2 - checked
            if is_checked and not imain_set:
                # TODO: change this to a log
                #self.window_parent.log
                imain_set = True
                imain = irow
                name_text.setFont(bold)
                name_text.setBackground(QtGui.QColor(*self.light_grey))
                self.shown_set.add(irow)
            elif irow == self.imain:
                name_text.setFont(normal)
                if irow == 0:
                    name_text.setBackground(QtGui.QColor(*self.white))
                    if irow in self.shown_set:
                        self.shown_set.remove(irow)
                elif imain == 0:
                    name_text.setBackground(QtGui.QColor(*self.white))
                    self.shown_set.remove(imain)
        self.imain = imain

    def get_main_group(self):
        return self.imain

    def get_shown_group(self):
        return self.shown_set

    def get_deleted_groups(self):
        return self.deleted_groups

    def on_validate(self):
        flag0 = flag1 = flag2 = True
        main_group_id = self.get_main_group()
        shown_groups_ids = self.get_shown_group()
        deleted_group_ids = self.get_deleted_groups()

        if flag0 and flag1 and flag2:
            self.out_data['imain'] = main_group_id
            self.out_data['shown'] = shown_groups_ids
            self.out_data['remove'] = deleted_group_ids
            self.out_data['clicked_ok'] = True
            return True
        return False

    def on_apply(self):
        passed = self.on_validate()
        if passed:
            self.win_parent.on_post_group(self.out_data)

    def on_ok(self):
        passed = self.on_validate()
        if passed:
            self.close()
            #self.destroy()

    def on_cancel(self):
        self.close()
コード例 #3
0
class MCSDialog(QDialog):
    """A dialog to perform minimal cut set computation"""

    def __init__(self, appdata: CnaData, centralwidget):
        QDialog.__init__(self)
        self.setWindowTitle("Minimal Cut Sets Computation")

        self.appdata = appdata
        self.centralwidget = centralwidget
        self.eng = appdata.engine
        self.out = io.StringIO()
        self.err = io.StringIO()

        self.layout = QVBoxLayout()
        l1 = QLabel("Target Region(s)")
        self.layout.addWidget(l1)
        s1 = QHBoxLayout()

        completer = QCompleter(
            self.appdata.project.cobra_py_model.reactions.list_attr("id"), self)
        completer.setCaseSensitivity(Qt.CaseInsensitive)

        self.target_list = QTableWidget(1, 4)
        self.target_list.setHorizontalHeaderLabels(
            ["region no", "T", "≥/≤", "t"])
        self.target_list.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.target_list.horizontalHeader().setSectionResizeMode(0, QHeaderView.Fixed)
        self.target_list.horizontalHeader().resizeSection(0, 100)
        self.target_list.horizontalHeader().setSectionResizeMode(2, QHeaderView.Fixed)
        self.target_list.horizontalHeader().resizeSection(2, 50)
        item = QLineEdit("1")
        self.target_list.setCellWidget(0, 0, item)
        item2 = QLineEdit("")
        item2.setCompleter(completer)
        self.target_list.setCellWidget(0, 1, item2)
        combo = QComboBox(self.target_list)
        combo.insertItem(1, "≤")
        combo.insertItem(2, "≥")
        self.target_list.setCellWidget(0, 2, combo)
        item = QLineEdit("0")
        self.target_list.setCellWidget(0, 3, item)

        s1.addWidget(self.target_list)

        s11 = QVBoxLayout()
        self.add_target = QPushButton("+")
        self.add_target.clicked.connect(self.add_target_region)
        self.rem_target = QPushButton("-")
        self.rem_target.clicked.connect(self.rem_target_region)
        s11.addWidget(self.add_target)
        s11.addWidget(self.rem_target)
        s1.addItem(s11)
        self.layout.addItem(s1)

        l2 = QLabel("Desired Region(s)")
        self.layout.addWidget(l2)
        s2 = QHBoxLayout()
        self.desired_list = QTableWidget(1, 4)
        self.desired_list.setHorizontalHeaderLabels(
            ["region no", "D", "≥/≤", "d"])
        self.desired_list.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.desired_list.horizontalHeader().setSectionResizeMode(0, QHeaderView.Fixed)
        self.desired_list.horizontalHeader().resizeSection(0, 100)
        self.desired_list.horizontalHeader().setSectionResizeMode(2, QHeaderView.Fixed)
        self.desired_list.horizontalHeader().resizeSection(2, 50)
        item = QLineEdit("1")
        self.desired_list.setCellWidget(0, 0, item)
        item2 = QLineEdit("")
        item2.setCompleter(completer)
        self.desired_list.setCellWidget(0, 1, item2)
        combo = QComboBox(self.desired_list)
        combo.insertItem(1, "≤")
        combo.insertItem(2, "≥")
        self.desired_list.setCellWidget(0, 2, combo)
        item = QLineEdit("0")
        self.desired_list.setCellWidget(0, 3, item)
        s2.addWidget(self.desired_list)

        s21 = QVBoxLayout()
        self.add_desire = QPushButton("+")
        self.add_desire.clicked.connect(self.add_desired_region)
        self.rem_desire = QPushButton("-")
        self.rem_desire.clicked.connect(self.rem_desired_region)
        s21.addWidget(self.add_desire)
        s21.addWidget(self.rem_desire)
        s2.addItem(s21)
        self.layout.addItem(s2)

        s3 = QHBoxLayout()

        sgx = QVBoxLayout()
        self.gen_kos = QCheckBox("Gene KOs")
        self.exclude_boundary = QCheckBox(
            "Exclude boundary\nreactions as cuts")
        sg1 = QHBoxLayout()
        s31 = QVBoxLayout()
        l = QLabel("Max. Solutions")
        s31.addWidget(l)
        l = QLabel("Max. Size")
        s31.addWidget(l)
        l = QLabel("Time Limit [sec]")
        s31.addWidget(l)

        sg1.addItem(s31)

        s32 = QVBoxLayout()
        self.max_solu = QLineEdit("inf")
        self.max_solu.setMaximumWidth(50)
        s32.addWidget(self.max_solu)
        self.max_size = QLineEdit("7")
        self.max_size.setMaximumWidth(50)
        s32.addWidget(self.max_size)
        self.time_limit = QLineEdit("inf")
        self.time_limit.setMaximumWidth(50)
        s32.addWidget(self.time_limit)

        sg1.addItem(s32)
        sgx.addWidget(self.gen_kos)
        sgx.addWidget(self.exclude_boundary)
        sgx.addItem(sg1)
        s3.addItem(sgx)

        g3 = QGroupBox("Solver")
        s33 = QVBoxLayout()
        self.bg1 = QButtonGroup()
        optlang_solver_name = interface_to_str(
            appdata.project.cobra_py_model.problem)
        self.solver_optlang = QRadioButton(f"{optlang_solver_name} (optlang)")
        self.solver_optlang.setToolTip(
            "Uses the solver specified by the current model.")
        s33.addWidget(self.solver_optlang)
        self.bg1.addButton(self.solver_optlang)
        self.solver_cplex_matlab = QRadioButton("CPLEX (MATLAB)")
        self.solver_cplex_matlab.setToolTip(
            "Only enabled with MATLAB and CPLEX")
        s33.addWidget(self.solver_cplex_matlab)
        self.bg1.addButton(self.solver_cplex_matlab)
        self.solver_cplex_java = QRadioButton("CPLEX (Octave)")
        self.solver_cplex_java.setToolTip("Only enabled with Octave and CPLEX")
        s33.addWidget(self.solver_cplex_java)
        self.bg1.addButton(self.solver_cplex_java)
        self.solver_intlinprog = QRadioButton("intlinprog (MATLAB)")
        self.solver_intlinprog.setToolTip("Only enabled with MATLAB")
        s33.addWidget(self.solver_intlinprog)
        self.bg1.addButton(self.solver_intlinprog)
        self.solver_glpk = QRadioButton("GLPK (Octave/MATLAB)")
        s33.addWidget(self.solver_glpk)
        self.bg1.addButton(self.solver_glpk)
        self.bg1.buttonClicked.connect(self.configure_solver_options)
        g3.setLayout(s33)
        s3.addWidget(g3)

        g4 = QGroupBox("MCS search")
        s34 = QVBoxLayout()
        self.bg2 = QButtonGroup()
        self.any_mcs = QRadioButton("any MCS (fast)")
        self.any_mcs.setChecked(True)
        s34.addWidget(self.any_mcs)
        self.bg2.addButton(self.any_mcs)

        # Search type: by cardinality only with CPLEX possible
        self.mcs_by_cardinality = QRadioButton("by cardinality")
        s34.addWidget(self.mcs_by_cardinality)
        self.bg2.addButton(self.mcs_by_cardinality)

        self.smalles_mcs_first = QRadioButton("smallest MCS first")
        s34.addWidget(self.smalles_mcs_first)
        self.bg2.addButton(self.smalles_mcs_first)
        g4.setLayout(s34)

        s3.addWidget(g4)
        self.layout.addItem(s3)

        # Disable incompatible combinations
        if appdata.selected_engine == 'None':
            self.solver_optlang.setChecked(True)
            self.solver_cplex_matlab.setEnabled(False)
            self.solver_cplex_java.setEnabled(False)
            self.solver_glpk.setEnabled(False)
            self.solver_intlinprog.setEnabled(False)
            if optlang_solver_name != 'cplex':
                self.mcs_by_cardinality.setEnabled(False)
        else:
            self.solver_glpk.setChecked(True)
            if not self.eng.is_cplex_matlab_ready():
                self.solver_cplex_matlab.setEnabled(False)
            if not self.eng.is_cplex_java_ready():
                self.solver_cplex_java.setEnabled(False)
            if self.appdata.is_matlab_set():
                self.solver_cplex_java.setEnabled(False)
            if not self.appdata.is_matlab_set():
                self.solver_cplex_matlab.setEnabled(False)
                self.solver_intlinprog.setEnabled(False)
        self.configure_solver_options()

        s4 = QVBoxLayout()
        self.consider_scenario = QCheckBox(
            "Consider constraint given by scenario")
        s4.addWidget(self.consider_scenario)
        self.advanced = QCheckBox(
            "Advanced: Define knockout/addition costs for genes/reactions")
        self.advanced.setEnabled(False)
        s4.addWidget(self.advanced)
        self.layout.addItem(s4)

        buttons = QHBoxLayout()
        # self.save = QPushButton("save")
        # buttons.addWidget(self.save)
        # self.load = QPushButton("load")
        # buttons.addWidget(self.load)
        self.compute_mcs = QPushButton("Compute MCS")
        buttons.addWidget(self.compute_mcs)
        # self.compute_mcs2 = QPushButton("Compute MCS2")
        # buttons.addWidget(self.compute_mcs2)
        self.cancel = QPushButton("Close")
        buttons.addWidget(self.cancel)
        self.layout.addItem(buttons)

        # max width for buttons
        self.add_target.setMaximumWidth(20)
        self.rem_target.setMaximumWidth(20)
        self.add_desire.setMaximumWidth(20)
        self.rem_desire.setMaximumWidth(20)

        self.setLayout(self.layout)

        # Connecting the signal
        self.cancel.clicked.connect(self.reject)
        self.compute_mcs.clicked.connect(self.compute)

    @Slot()
    def configure_solver_options(self):
        optlang_solver_name = interface_to_str(
            self.appdata.project.cobra_py_model.problem)
        if self.solver_optlang.isChecked():
            self.gen_kos.setChecked(False)
            self.gen_kos.setEnabled(False)
            self.exclude_boundary.setEnabled(True)
            if optlang_solver_name != 'cplex':
                if self.mcs_by_cardinality.isChecked():
                    self.mcs_by_cardinality.setChecked(False)
                    self.any_mcs.setChecked(True)
                self.mcs_by_cardinality.setEnabled(False)
                self.mcs_by_cardinality.setChecked(False)

        else:
            self.gen_kos.setEnabled(True)
            self.exclude_boundary.setChecked(False)
            self.exclude_boundary.setEnabled(False)
            self.mcs_by_cardinality.setEnabled(True)

    def add_target_region(self):
        i = self.target_list.rowCount()
        self.target_list.insertRow(i)

        completer = QCompleter(
            self.appdata.project.cobra_py_model.reactions.list_attr("id"), self)
        completer.setCaseSensitivity(Qt.CaseInsensitive)

        item = QLineEdit("1")
        self.target_list.setCellWidget(i, 0, item)
        item2 = QLineEdit("")
        item2.setCompleter(completer)
        self.target_list.setCellWidget(i, 1, item2)
        combo = QComboBox(self.target_list)
        combo.insertItem(1, "≤")
        combo.insertItem(2, "≥")
        self.target_list.setCellWidget(i, 2, combo)
        item = QLineEdit("0")
        self.target_list.setCellWidget(i, 3, item)

    def add_desired_region(self):
        i = self.desired_list.rowCount()
        self.desired_list.insertRow(i)

        completer = QCompleter(
            self.appdata.project.cobra_py_model.reactions.list_attr("id"), self)
        completer.setCaseSensitivity(Qt.CaseInsensitive)

        item = QLineEdit("1")
        self.desired_list.setCellWidget(i, 0, item)
        item2 = QLineEdit("")
        item2.setCompleter(completer)
        self.desired_list.setCellWidget(i, 1, item2)
        combo = QComboBox(self.desired_list)
        combo.insertItem(1, "≤")
        combo.insertItem(2, "≥")
        self.desired_list.setCellWidget(i, 2, combo)
        item = QLineEdit("0")
        self.desired_list.setCellWidget(i, 3, item)

    def rem_target_region(self):
        i = self.target_list.rowCount()
        self.target_list.removeRow(i-1)

    def rem_desired_region(self):
        i = self.desired_list.rowCount()
        self.desired_list.removeRow(i-1)

    def compute(self):
        if self.solver_optlang.isChecked():
            self.compute_optlang()
        else:
            self.compute_legacy()

    def compute_legacy(self):
        self.setCursor(Qt.BusyCursor)
        # create CobraModel for matlab
        with self.appdata.project.cobra_py_model as model:
            if self.consider_scenario.isChecked():  # integrate scenario into model bounds
                for r in self.appdata.project.scen_values.keys():
                    model.reactions.get_by_id(
                        r).bounds = self.appdata.project.scen_values[r]
            cobra.io.save_matlab_model(model, os.path.join(
                self.appdata.cna_path, "cobra_model.mat"), varname="cbmodel")
        self.eng.eval("load('cobra_model.mat')",
                      nargout=0)

        try:
            self.eng.eval("cnap = CNAcobra2cna(cbmodel);",
                          nargout=0,
                          stdout=self.out, stderr=self.err)
        except Exception:
            output = io.StringIO()
            traceback.print_exc(file=output)
            exstr = output.getvalue()
            print(exstr)
            QMessageBox.warning(self, 'Unknown exception occured!',
                                exstr+'\nPlease report the problem to:\n\
                                    \nhttps://github.com/cnapy-org/CNApy/issues')
            return

        self.eng.eval("genes = [];", nargout=0,
                      stdout=self.out, stderr=self.err)
        cmd = "maxSolutions = " + str(float(self.max_solu.text())) + ";"
        self.eng.eval(cmd, nargout=0, stdout=self.out, stderr=self.err)

        cmd = "maxSize = " + str(int(self.max_size.text())) + ";"
        self.eng.eval(cmd, nargout=0, stdout=self.out, stderr=self.err)

        cmd = "milp_time_limit = " + str(float(self.time_limit.text())) + ";"
        self.eng.eval(cmd, nargout=0, stdout=self.out, stderr=self.err)

        if self.gen_kos.isChecked():
            self.eng.eval("gKOs = 1;", nargout=0)
        else:
            self.eng.eval("gKOs = 0;", nargout=0)
        if self.advanced.isChecked():
            self.eng.eval("advanced_on = 1;", nargout=0)
        else:
            self.eng.eval("advanced_on = 0;", nargout=0)

        if self.solver_intlinprog.isChecked():
            self.eng.eval("solver = 'intlinprog';", nargout=0)
        if self.solver_cplex_java.isChecked():
            self.eng.eval("solver = 'java_cplex_new';", nargout=0)
        if self.solver_cplex_matlab.isChecked():
            self.eng.eval("solver = 'matlab_cplex';", nargout=0)
        if self.solver_glpk.isChecked():
            self.eng.eval("solver = 'glpk';", nargout=0)
        if self.any_mcs.isChecked():
            self.eng.eval("mcs_search_mode = 'search_1';", nargout=0)
        elif self.mcs_by_cardinality.isChecked():
            self.eng.eval("mcs_search_mode = 'search_2';", nargout=0)
        elif self.smalles_mcs_first.isChecked():
            self.eng.eval("mcs_search_mode = 'search_3';", nargout=0)

        rows = self.target_list.rowCount()
        for i in range(0, rows):
            p1 = self.target_list.cellWidget(i, 0).text()
            p2 = self.target_list.cellWidget(i, 1).text()
            if self.target_list.cellWidget(i, 2).currentText() == '≤':
                p3 = "<="
            else:
                p3 = ">="
            p4 = self.target_list.cellWidget(i, 3).text()
            cmd = "dg_T = {[" + p1+"], '" + p2 + \
                "', '" + p3 + "', [" + p4 + "']};"
            self.eng.eval(cmd, nargout=0,
                          stdout=self.out, stderr=self.err)

        rows = self.desired_list.rowCount()
        for i in range(0, rows):
            p1 = self.desired_list.cellWidget(i, 0).text()
            p2 = self.desired_list.cellWidget(i, 1).text()
            if self.desired_list.cellWidget(i, 2).currentText() == '≤':
                p3 = "<="
            else:
                p3 = ">="
            p4 = self.desired_list.cellWidget(i, 3).text()
            cmd = "dg_D = {[" + p1+"], '" + p2 + \
                "', '" + p3 + "', [" + p4 + "']};"
            self.eng.eval(cmd, nargout=0)

        # get some data
        self.eng.eval("reac_id = cellstr(cnap.reacID).';",
                      nargout=0, stdout=self.out, stderr=self.err)

        mcs = []
        values = []
        reactions = []
        reac_id = []
        if self.appdata.is_matlab_set():
            reac_id = self.eng.workspace['reac_id']
            try:
                self.eng.eval("[mcs] = cnapy_compute_mcs(cnap, genes, maxSolutions, maxSize, milp_time_limit, gKOs, advanced_on, solver, mcs_search_mode, dg_T,dg_D);",
                              nargout=0)
            except Exception:
                output = io.StringIO()
                traceback.print_exc(file=output)
                exstr = output.getvalue()
                print(exstr)
                QMessageBox.warning(self, 'Unknown exception occured!',
                                    exstr+'\nPlease report the problem to:\n\
                                    \nhttps://github.com/cnapy-org/CNApy/issues')
                return
            else:
                self.eng.eval("[reaction, mcs, value] = find(mcs);", nargout=0,
                              stdout=self.out, stderr=self.err)
                reactions = self.eng.workspace['reaction']
                mcs = self.eng.workspace['mcs']
                values = self.eng.workspace['value']
        elif self.appdata.is_octave_ready():
            reac_id = self.eng.pull('reac_id')
            reac_id = reac_id[0]
            try:
                self.eng.eval("[mcs] = cnapy_compute_mcs(cnap, genes, maxSolutions, maxSize, milp_time_limit, gKOs, advanced_on, solver, mcs_search_mode, dg_T,dg_D);",
                              nargout=0)
            except Exception:
                output = io.StringIO()
                traceback.print_exc(file=output)
                exstr = output.getvalue()
                print(exstr)
                QMessageBox.warning(self, 'Unknown exception occured!',
                                    exstr+'\nPlease report the problem to:\n\
                                    \nhttps://github.com/cnapy-org/CNApy/issues')
                return
            else:
                self.eng.eval("[reaction, mcs, value] = find(mcs);", nargout=0,
                              stdout=self.out, stderr=self.err)
                reactions = self.eng.pull('reaction')
                mcs = self.eng.pull('mcs')
                values = self.eng.pull('value')

        if len(mcs) == 0:
            QMessageBox.information(self, 'No cut sets',
                                          'Cut sets have not been calculated or do not exist.')
        else:
            last_mcs = 1
            omcs = []
            current_mcs = {}
            for i in range(0, len(reactions)):
                reacid = int(reactions[i][0])
                reaction = reac_id[reacid-1]
                c_mcs = int(mcs[i][0])
                c_value = int(values[i][0])
                if c_value == -1:  # -1 stands for removed which is 0 in the ui
                    c_value = 0
                if c_mcs > last_mcs:
                    omcs.append(current_mcs)
                    last_mcs = c_mcs
                    current_mcs = {}
                current_mcs[reaction] = c_value
            omcs.append(current_mcs)
            self.appdata.project.modes = omcs
            self.centralwidget.mode_navigator.current = 0
            QMessageBox.information(self, 'Cut sets found',
                                          str(len(omcs))+' Cut sets have been calculated.')

        self.centralwidget.update_mode()
        self.centralwidget.mode_navigator.title.setText("MCS Navigation")

        self.setCursor(Qt.ArrowCursor)

    def compute_optlang(self):

        self.setCursor(Qt.BusyCursor)
        max_mcs_num = float(self.max_solu.text())
        max_mcs_size = int(self.max_size.text())
        timeout = float(self.time_limit.text())
        if timeout is float('inf'):
            timeout = None

        # if self.gen_kos.isChecked():
        #     self.eng.eval("gKOs = 1;", nargout=0)
        # else:
        #     self.eng.eval("gKOs = 0;", nargout=0)
        # if self.advanced.isChecked():
        #     self.eng.eval("advanced_on = 1;", nargout=0)
        # else:
        #     self.eng.eval("advanced_on = 0;", nargout=0)

        if self.smalles_mcs_first.isChecked():
            enum_method = 1
        elif self.mcs_by_cardinality.isChecked():
            enum_method = 2
        elif self.any_mcs.isChecked():
            enum_method = 3

        with self.appdata.project.cobra_py_model as model:
            if self.consider_scenario.isChecked():  # integrate scenario into model bounds
                for r in self.appdata.project.scen_values.keys():
                    model.reactions.get_by_id(
                        r).bounds = self.appdata.project.scen_values[r]
            reac_id = model.reactions.list_attr("id")
            reac_id_symbols = cMCS_enumerator.get_reac_id_symbols(reac_id)
            rows = self.target_list.rowCount()
            targets = dict()
            for i in range(0, rows):
                p1 = self.target_list.cellWidget(i, 0).text()
                p2 = self.target_list.cellWidget(i, 1).text()
                if len(p1) > 0 and len(p2) > 0:
                    if self.target_list.cellWidget(i, 2).currentText() == '≤':
                        p3 = "<="
                    else:
                        p3 = ">="
                    p4 = float(self.target_list.cellWidget(i, 3).text())
                    targets.setdefault(p1, []).append((p2, p3, p4))
            targets = list(targets.values())
            targets = [cMCS_enumerator.relations2leq_matrix(cMCS_enumerator.parse_relations(
                t, reac_id_symbols=reac_id_symbols), reac_id) for t in targets]

            rows = self.desired_list.rowCount()
            desired = dict()
            for i in range(0, rows):
                p1 = self.desired_list.cellWidget(i, 0).text()
                p2 = self.desired_list.cellWidget(i, 1).text()
                if len(p1) > 0 and len(p2) > 0:
                    if self.desired_list.cellWidget(i, 2).currentText() == '≤':
                        p3 = "<="
                    else:
                        p3 = ">="
                    p4 = float(self.desired_list.cellWidget(i, 3).text())
                    desired.setdefault(p1, []).append((p2, p3, p4))

            desired = list(desired.values())
            desired = [cMCS_enumerator.relations2leq_matrix(cMCS_enumerator.parse_relations(
                d, reac_id_symbols=reac_id_symbols), reac_id) for d in desired]

            try:
                mcs = cMCS_enumerator.compute_mcs(model,
                                                  targets=targets,
                                                  desired=desired,
                                                  enum_method=enum_method,
                                                  max_mcs_size=max_mcs_size,
                                                  max_mcs_num=max_mcs_num,
                                                  timeout=timeout,
                                                  exclude_boundary_reactions_as_cuts=self.exclude_boundary.isChecked())
            except cMCS_enumerator.InfeasibleRegion as e:
                QMessageBox.warning(self, 'Cannot calculate MCS', str(e))
                return targets, desired
            except Exception:
                output = io.StringIO()
                traceback.print_exc(file=output)
                exstr = output.getvalue()
                print(exstr)
                QMessageBox.warning(self, 'An exception has occured!',
                                    exstr+'\nPlease report the problem to:\n\
                                    \nhttps://github.com/cnapy-org/CNApy/issues')
                return targets, desired
            finally:
                self.setCursor(Qt.ArrowCursor)

        if len(mcs) == 0:
            QMessageBox.information(self, 'No cut sets',
                                          'Cut sets have not been calculated or do not exist.')
            return targets, desired

        omcs = [{reac_id[i]: 0 for i in m} for m in mcs]
        self.appdata.project.modes = omcs
        self.centralwidget.mode_navigator.current = 0
        QMessageBox.information(self, 'Cut sets found',
                                      str(len(omcs))+' Cut sets have been calculated.')

        self.centralwidget.update_mode()
        self.centralwidget.mode_navigator.title.setText("MCS Navigation")
コード例 #4
0
ファイル: camera.py プロジェクト: xuliangyin/pyNastran
class CameraWindow(PyDialog):
    """defines the CameraWindow class"""
    def __init__(self, data, win_parent=None):
        """
        +--------+
        | Camera |
        +--------+---------------+
        |  Camera Name           |
        |  +-------------------+ |
        |  |                   | |
        |  |                   | |
        |  |                   | |
        |  |                   | |
        |  |                   | |
        |  +-------------------+ |
        |                        |
        | Name xxx       Save    |
        | Delete   Set           |
        |                        |
        |    Apply   OK  Cancel  |
        +--------+---------------+
        """
        PyDialog.__init__(self, data, win_parent)
        self.setWindowTitle('Camera Views')
        #self.setWindowIcon(view_icon)

        self._default_name = 'Camera'
        self.out_data['clicked_ok'] = False

        self.cameras = deepcopy(data['cameras'])
        self.names = sorted(self.cameras.keys())

        self.name = QLabel("Name:")
        self.name_edit = QLineEdit(str(self._default_name))

        self.delete_button = QPushButton("Delete")
        self.set_button = QPushButton("Set")
        self.save_button = QPushButton("Save")

        # closing
        self.apply_button = QPushButton("Apply")
        self.close_button = QPushButton("Close")
        self.cancel_button = QPushButton("Cancel")

        self.table = QTableWidget()
        names_text = []
        for name in self.names:
            name_text = QTableWidgetItem(str(name))
            names_text.append(name_text)
        self.create_layout(names_text)
        self.set_connections()

    def create_layout(self, names_text):
        nrows = len(self.names)
        table = self.table
        table.setRowCount(nrows)
        table.setColumnCount(1)
        headers = ['Camera Name']
        table.setHorizontalHeaderLabels(headers)

        header = table.horizontalHeader()
        header.setStretchLastSection(True)

        for iname, name_text in enumerate(names_text):
            # row, col, value
            table.setItem(iname, 0, name_text)
        table.resizeRowsToContents()

        ok_cancel_box = QHBoxLayout()
        ok_cancel_box.addWidget(self.apply_button)
        ok_cancel_box.addWidget(self.close_button)
        ok_cancel_box.addWidget(self.cancel_button)

        grid = QGridLayout()

        irow = 0
        grid.addWidget(self.name, irow, 0)
        grid.addWidget(self.name_edit, irow, 1)
        grid.addWidget(self.save_button, irow, 2)
        irow += 1

        grid.addWidget(self.delete_button, irow, 0)
        grid.addWidget(self.set_button, irow, 1)
        irow += 1

        vbox = QVBoxLayout()
        vbox.addWidget(self.table)

        vbox.addLayout(grid)
        vbox.addStretch()
        vbox.addLayout(ok_cancel_box)
        self.setLayout(vbox)

    def set_connections(self):
        """creates the actions for the menu"""
        #if qt_version == 4:
        #self.connect(self.ok_button, QtCore.SIGNAL('clicked()'), self.on_ok)
        self.set_button.clicked.connect(self.on_set)
        self.save_button.clicked.connect(self.on_save)
        self.delete_button.clicked.connect(self.on_delete)
        self.apply_button.clicked.connect(self.on_apply)
        self.close_button.clicked.connect(self.on_close)
        self.cancel_button.clicked.connect(self.on_cancel)

    def on_set(self):
        objs = self.table.selectedIndexes()
        if len(objs) == 1:
            obj = objs[0]
            irow = obj.row()
            name = self.names[irow]
            self.set_camera(name)
            return True
        return False

    def on_save(self):
        name = str(self.name_edit.text()).strip()
        if name in self.cameras:
            return
        irow = self.nrows
        if len(name):
            self.table.insertRow(irow)
            name_text = QTableWidgetItem(str(name))
            self.table.setItem(irow, 0, name_text)
            self.name_edit.setText('')
            self.save_camera(name)

    def set_camera(self, name):
        camera_data = self.cameras[name]
        if self.win_parent is None:
            return
        self.win_parent.on_set_camera_data(camera_data)

    def save_camera(self, name):
        self.names.append(name)
        if self.win_parent is None:
            self.cameras[name] = None
            return
        self.cameras[name] = self.win_parent.get_camera_data()

    @property
    def nrows(self):
        return self.table.rowCount()

    def on_delete(self):
        irows = []
        for obj in self.table.selectedIndexes():
            irow = obj.row()
            irows.append(irow)
        irows.sort()

        for irow in reversed(irows):
            self.table.removeRow(irow)
            name = self.names.pop(irow)
            del self.cameras[name]
            #print('  removing irow=%s name=%r' % (irow, name))

    def closeEvent(self, event):
        event.accept()

    def on_apply(self):
        passed = self.on_set()
        #if passed:
        #    self.win_parent.create_plane(self.out_data)
        return passed

    def on_close(self):
        self.out_data['clicked_ok'] = True
        self.out_data['cameras'] = self.cameras
        self.close()

    def on_ok(self):
        passed = self.on_apply()
        if passed:
            name = str(self.name_edit.text()).strip()
            self.out_data['name'] = name
            self.out_data['cameras'] = self.cameras
            self.out_data['clicked_ok'] = True
            self.close()
            #self.destroy()

    def on_cancel(self):
        self.close()
コード例 #5
0
class EventsDialog(QDialog):
    def __init__(self, parent, pos, desc):
        super().__init__(parent)
        self.setWindowTitle("Edit Events")

        self.table = QTableWidget(len(pos), 2)

        for row, (p, d) in enumerate(zip(pos, desc)):
            self.table.setItem(row, 0, IntTableWidgetItem(p))
            self.table.setItem(row, 1, IntTableWidgetItem(d))

        self.table.setHorizontalHeaderLabels(["Position", "Type"])
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.verticalHeader().setVisible(False)
        self.table.setShowGrid(False)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.setSortingEnabled(True)
        self.table.sortByColumn(0, Qt.AscendingOrder)

        vbox = QVBoxLayout(self)
        vbox.addWidget(self.table)
        hbox = QHBoxLayout()
        self.add_button = QPushButton("+")
        self.remove_button = QPushButton("-")
        buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        hbox.addWidget(self.add_button)
        hbox.addWidget(self.remove_button)
        hbox.addStretch()
        hbox.addWidget(buttonbox)
        vbox.addLayout(hbox)
        buttonbox.accepted.connect(self.accept)
        buttonbox.rejected.connect(self.reject)
        self.table.itemSelectionChanged.connect(self.toggle_buttons)
        self.remove_button.clicked.connect(self.remove_event)
        self.add_button.clicked.connect(self.add_event)
        self.toggle_buttons()
        self.resize(300, 500)

    @Slot()
    def toggle_buttons(self):
        """Toggle + and - buttons."""
        n_items = len(self.table.selectedItems())
        if n_items == 2:  # one row (2 items) selected
            self.add_button.setEnabled(True)
            self.remove_button.setEnabled(True)
        elif n_items > 2:  # more than one row selected
            self.add_button.setEnabled(False)
            self.remove_button.setEnabled(True)
        else:  # no rows selected
            self.add_button.setEnabled(False)
            self.remove_button.setEnabled(False)

    def add_event(self):
        current_row = self.table.selectedIndexes()[0].row()
        pos = int(self.table.item(current_row, 0).data(Qt.DisplayRole))
        self.table.setSortingEnabled(False)
        self.table.insertRow(current_row)
        self.table.setItem(current_row, 0, IntTableWidgetItem(pos))
        self.table.setItem(current_row, 1, IntTableWidgetItem(0))
        self.table.setSortingEnabled(True)

    def remove_event(self):
        rows = {index.row() for index in self.table.selectedIndexes()}
        self.table.clearSelection()
        for row in sorted(rows, reverse=True):
            self.table.removeRow(row)
コード例 #6
0
ファイル: reactions_list.py プロジェクト: rmahadevan12/CNApy
class ReactionMask(QWidget):
    """The input mask for a reaction"""

    def __init__(self, parent: ReactionList):
        QWidget.__init__(self)

        self.parent = parent
        self.reaction = None
        self.is_valid = True
        self.changed = False
        self.setAcceptDrops(False)

        layout = QVBoxLayout()
        l = QHBoxLayout()
        self.delete_button = QPushButton("Delete reaction")
        self.delete_button.setIcon(QIcon.fromTheme("edit-delete"))
        policy = QSizePolicy()
        policy.ShrinkFlag = True
        self.delete_button.setSizePolicy(policy)
        l.addWidget(self.delete_button)
        layout.addItem(l)

        l = QHBoxLayout()
        label = QLabel("Id:")
        self.id = QLineEdit()
        l.addWidget(label)
        l.addWidget(self.id)
        layout.addItem(l)

        l = QHBoxLayout()
        label = QLabel("Name:")
        self.name = QLineEdit()
        l.addWidget(label)
        l.addWidget(self.name)
        layout.addItem(l)

        l = QHBoxLayout()
        label = QLabel("Equation:")
        self.equation = QLineEdit()
        l.addWidget(label)
        l.addWidget(self.equation)
        layout.addItem(l)

        l = QHBoxLayout()
        label = QLabel("Rate min:")
        self.lower_bound = QLineEdit()
        l.addWidget(label)
        l.addWidget(self.lower_bound)
        layout.addItem(l)

        l = QHBoxLayout()
        label = QLabel("Rate max:")
        self.upper_bound = QLineEdit()
        l.addWidget(label)
        l.addWidget(self.upper_bound)
        layout.addItem(l)

        l = QHBoxLayout()
        label = QLabel("Coefficient in obj. function:")
        self.coefficent = QLineEdit()
        l.addWidget(label)
        l.addWidget(self.coefficent)
        layout.addItem(l)

        l = QHBoxLayout()
        label = QLabel("Gene reaction rule:")
        self.gene_reaction_rule = QLineEdit()
        l.addWidget(label)
        l.addWidget(self.gene_reaction_rule)
        layout.addItem(l)

        l = QVBoxLayout()
        label = QLabel("Annotations:")
        l.addWidget(label)
        l2 = QHBoxLayout()
        self.annotation = QTableWidget(0, 2)
        self.annotation.setHorizontalHeaderLabels(
            ["key", "value"])
        self.annotation.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        l2.addWidget(self.annotation)

        self.add_anno = QPushButton("+")
        self.add_anno.clicked.connect(self.add_anno_row)
        l2.addWidget(self.add_anno)
        l.addItem(l2)
        layout.addItem(l)

        l = QVBoxLayout()
        label = QLabel("Metabolites involved in this reaction:")
        l.addWidget(label)
        l2 = QHBoxLayout()
        self.metabolites = QTreeWidget()
        self.metabolites.setHeaderLabels(["Id"])
        self.metabolites.setSortingEnabled(True)
        l2.addWidget(self.metabolites)
        l.addItem(l2)
        self.metabolites.itemDoubleClicked.connect(
            self.emit_jump_to_metabolite)
        layout.addItem(l)

        self.jump_list = JumpList(self)
        layout.addWidget(self.jump_list)

        self.setLayout(layout)

        self.delete_button.clicked.connect(self.delete_reaction)

        self.throttler = SignalThrottler(500)
        self.throttler.triggered.connect(self.reaction_data_changed)

        self.id.textEdited.connect(self.throttler.throttle)
        self.name.textEdited.connect(self.throttler.throttle)
        self.equation.textEdited.connect(self.throttler.throttle)
        self.lower_bound.textEdited.connect(self.throttler.throttle)
        self.upper_bound.textEdited.connect(self.throttler.throttle)
        self.coefficent.textEdited.connect(self.throttler.throttle)
        self.gene_reaction_rule.textEdited.connect(self.throttler.throttle)
        self.annotation.itemChanged.connect(self.throttler.throttle)

        self.validate_mask()

    def add_anno_row(self):
        i = self.annotation.rowCount()
        self.annotation.insertRow(i)
        self.changed = True

    def apply(self):
        try:
            self.reaction.id = self.id.text()
        except ValueError:
            turn_red(self.id)
            QMessageBox.information(
                self, 'Invalid id', 'Could not apply changes identifier ' +
                self.id.text() + ' already used.')
        else:
            self.reaction.name = self.name.text()
            self.reaction.build_reaction_from_string(self.equation.text())
            self.reaction.lower_bound = float(self.lower_bound.text())
            self.reaction.upper_bound = float(self.upper_bound.text())
            self.reaction.objective_coefficient = float(self.coefficent.text())
            self.reaction.gene_reaction_rule = self.gene_reaction_rule.text()
            self.reaction.annotation = {}
            rows = self.annotation.rowCount()
            for i in range(0, rows):
                key = self.annotation.item(i, 0).text()
                if self.annotation.item(i, 1) is None:
                    value = ""
                else:
                    value = self.annotation.item(i, 1).text()

                self.reaction.annotation[key] = value

            self.changed = False
            self.reactionChanged.emit(self.reaction)

    def delete_reaction(self):
        self.hide()
        self.reactionDeleted.emit(self.reaction)

    def validate_id(self):

        with self.parent.appdata.project.cobra_py_model as model:
            try:
                r = cobra.Reaction(id=self.id.text())
                model.add_reaction(r)
            except ValueError:
                turn_red(self.id)
                return False
            else:
                turn_white(self.id)
                return True

    def validate_name(self):
        with self.parent.appdata.project.cobra_py_model as model:
            try:
                r = cobra.Reaction(id="testid", name=self.name.text())
                model.add_reaction(r)
            except ValueError:
                turn_red(self.name)
                return False
            else:
                turn_white(self.name)
                return True

    def validate_equation(self):
        ok = False
        test_reaction = cobra.Reaction(
            "xxxx_cnapy_test_reaction", name="cnapy test reaction")
        with self.parent.appdata.project.cobra_py_model as model:
            model.add_reaction(test_reaction)

            try:
                eqtxt = self.equation.text().rstrip()
                if len(eqtxt) > 0 and eqtxt[-1] == '+':
                    turn_red(self.equation)
                else:
                    test_reaction.build_reaction_from_string(eqtxt)
                    turn_white(self.equation)
                    ok = True
            except ValueError:
                turn_red(self.equation)

        try:
            test_reaction = self.parent.appdata.project.cobra_py_model.reactions.get_by_id(
                "xxxx_cnapy_test_reaction")
            self.parent.appdata.project.cobra_py_model.remove_reactions(
                [test_reaction], remove_orphans=True)
        except KeyError:
            pass

        return ok

    def validate_lowerbound(self):
        try:
            _x = float(self.lower_bound.text())
        except ValueError:
            turn_red(self.lower_bound)
            return False
        else:
            turn_white(self.lower_bound)
            return True

    def validate_upperbound(self):
        try:
            _x = float(self.upper_bound.text())
        except ValueError:
            turn_red(self.upper_bound)
            return False
        else:
            turn_white(self.upper_bound)
            return True

    def validate_coefficient(self):
        try:
            _x = float(self.coefficent.text())
        except ValueError:
            turn_red(self.coefficent)
            return False
        else:
            turn_white(self.coefficent)
            return True

    def validate_gene_reaction_rule(self):
        try:
            _x = float(self.gene_reaction_rule.text())
        except ValueError:
            turn_red(self.gene_reaction_rule)
            return False
        else:
            turn_white(self.gene_reaction_rule)
            return True

    def validate_mask(self):

        valid_id = self.validate_id()
        valid_name = self.validate_name()
        valid_equation = self.validate_equation()
        valid_lb = self.validate_lowerbound()
        valid_ub = self.validate_upperbound()
        valid_coefficient = self.validate_coefficient()
        if valid_id & valid_name & valid_equation & valid_lb & valid_ub & valid_coefficient:
            self.is_valid = True
        else:
            self.is_valid = False

    def reaction_data_changed(self):
        self.changed = True
        self.validate_mask()
        if self.is_valid:
            self.apply()
            self.update_state()

    def update_state(self):
        self.jump_list.clear()
        for name, m in self.parent.appdata.project.maps.items():
            if self.id.text() in m["boxes"]:
                self.jump_list.add(name)

        self.metabolites.clear()
        if self.parent.appdata.project.cobra_py_model.reactions.has_id(self.id.text()):
            reaction = self.parent.appdata.project.cobra_py_model.reactions.get_by_id(
                self.id.text())
            for m in reaction.metabolites:
                item = QTreeWidgetItem(self.metabolites)
                item.setText(0, m.id)
                item.setText(1, m.name)
                item.setData(2, 0, m)
                text = "Id: " + m.id + "\nName: " + m.name
                item.setToolTip(1, text)

    def emit_jump_to_map(self, name):
        self.jumpToMap.emit(name, self.id.text())

    def emit_jump_to_metabolite(self, metabolite):
        self.jumpToMetabolite.emit(str(metabolite.data(2, 0)))

    jumpToMap = Signal(str, str)
    jumpToMetabolite = Signal(str)
    reactionChanged = Signal(cobra.Reaction)
    reactionDeleted = Signal(cobra.Reaction)
コード例 #7
0
ファイル: metabolite_list.py プロジェクト: rmahadevan12/CNApy
class MetabolitesMask(QWidget):
    """The input mask for a metabolites"""

    def __init__(self, appdata):
        QWidget.__init__(self)
        self.appdata = appdata
        self.metabolite = None
        self.is_valid = True
        self.changed = False
        self.setAcceptDrops(False)

        layout = QVBoxLayout()
        l = QHBoxLayout()
        label = QLabel("Id:")
        self.id = QLineEdit()
        l.addWidget(label)
        l.addWidget(self.id)
        layout.addItem(l)

        l = QHBoxLayout()
        label = QLabel("Name:")
        self.name = QLineEdit()
        l.addWidget(label)
        l.addWidget(self.name)
        layout.addItem(l)

        l = QHBoxLayout()
        label = QLabel("Formula:")
        self.formula = QLineEdit()
        l.addWidget(label)
        l.addWidget(self.formula)
        layout.addItem(l)

        l = QHBoxLayout()
        label = QLabel("Charge:")
        self.charge = QLineEdit()
        l.addWidget(label)
        l.addWidget(self.charge)
        layout.addItem(l)

        l = QHBoxLayout()
        label = QLabel("Compartment:")
        self.compartment = QLineEdit()
        l.addWidget(label)
        l.addWidget(self.compartment)
        layout.addItem(l)

        l = QVBoxLayout()
        label = QLabel("Annotations:")
        l.addWidget(label)
        l2 = QHBoxLayout()
        self.annotation = QTableWidget(0, 2)
        self.annotation.setHorizontalHeaderLabels(
            ["key", "value"])
        self.annotation.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        l2.addWidget(self.annotation)

        self.add_anno = QPushButton("+")
        self.add_anno.clicked.connect(self.add_anno_row)
        l2.addWidget(self.add_anno)
        l.addItem(l2)
        layout.addItem(l)

        l = QVBoxLayout()
        label = QLabel("Reactions using this metabolite:")
        l.addWidget(label)
        l2 = QHBoxLayout()
        self.reactions = QTreeWidget()
        self.reactions.setHeaderLabels(["Id"])
        self.reactions.setSortingEnabled(True)
        l2.addWidget(self.reactions)
        l.addItem(l2)
        self.reactions.itemDoubleClicked.connect(self.emit_jump_to_reaction)
        layout.addItem(l)

        self.setLayout(layout)

        self.throttler = SignalThrottler(500)
        self.throttler.triggered.connect(self.metabolites_data_changed)

        self.id.textEdited.connect(self.throttler.throttle)
        self.name.textEdited.connect(self.throttler.throttle)
        self.formula.textEdited.connect(self.throttler.throttle)
        self.charge.textEdited.connect(self.throttler.throttle)
        self.compartment.textEdited.connect(self.throttler.throttle)
        self.annotation.itemChanged.connect(self.throttler.throttle)
        self.validate_mask()

    def add_anno_row(self):
        i = self.annotation.rowCount()
        self.annotation.insertRow(i)
        self.changed = True

    def apply(self):
        try:
            self.metabolite.id = self.id.text()
        except ValueError:
            turn_red(self.id)
            QMessageBox.information(
                self, 'Invalid id', 'Could not apply changes identifier ' +
                self.id.text()+' already used.')
        else:
            self.metabolite.name = self.name.text()
            self.metabolite.formula = self.formula.text()
            if self.charge.text() == "":
                self.metabolite.charge = None
            else:
                self.metabolite.charge = int(self.charge.text())
            self.metabolite.compartment = self.compartment.text()
            self.metabolite.annotation = {}
            rows = self.annotation.rowCount()
            for i in range(0, rows):
                key = self.annotation.item(i, 0).text()
                if self.annotation.item(i, 1) is None:
                    value = ""
                else:
                    value = self.annotation.item(i, 1).text()

                self.metabolite.annotation[key] = value

            self.changed = False
            self.metaboliteChanged.emit(self.metabolite)

    def validate_id(self):
        with self.appdata.project.cobra_py_model as model:
            text = self.id.text()
            if text == "":
                turn_red(self.id)
                return False
            if ' ' in text:
                turn_red(self.id)
                return False
            try:
                m = cobra.Metabolite(id=self.id.text())
                model.add_metabolites([m])
            except ValueError:
                turn_red(self.id)
                return False
            else:
                turn_white(self.id)
                return True

    def validate_name(self):
        with self.appdata.project.cobra_py_model as model:
            try:
                m = cobra.Metabolite(id="test_id", name=self.name.text())
                model.add_metabolites([m])
            except ValueError:
                turn_red(self.name)
                return False
            else:
                turn_white(self.name)
                return True

    def validate_formula(self):
        return True

    def validate_charge(self):
        try:
            if self.charge.text() != "":
                _x = int(self.charge.text())
        except ValueError:
            turn_red(self.charge)
            return False
        else:
            turn_white(self.charge)
            return True

    def validate_compartment(self):
        try:
            if ' ' in self.compartment.text():
                turn_red(self.compartment)
                return False
            if '-' in self.compartment.text():
                turn_red(self.compartment)
                return False
            _m = cobra.Metabolite(id="test_id", name=self.compartment.text())
        except ValueError:
            turn_red(self.compartment)
            return False
        else:
            turn_white(self.compartment)
            return True

    def validate_mask(self):
        valid_id = self.validate_id()
        valid_name = self.validate_name()
        valid_formula = self.validate_formula()
        valid_charge = self.validate_charge()
        valid_compartment = self.validate_compartment()
        if valid_id & valid_name & valid_formula & valid_charge & valid_compartment:
            self.is_valid = True
        else:
            self.is_valid = False

    def metabolites_data_changed(self):
        self.changed = True
        self.validate_mask()
        if self.is_valid:
            self.apply()
            self.update_state()

    def update_state(self):
        self.reactions.clear()
        if self.appdata.project.cobra_py_model.metabolites.has_id(self.id.text()):
            metabolite = self.appdata.project.cobra_py_model.metabolites.get_by_id(
                self.id.text())
            for r in metabolite.reactions:
                item = QTreeWidgetItem(self.reactions)
                item.setText(0, r.id)
                item.setText(1, r.name)
                item.setData(2, 0, r)
                text = "Id: " + r.id + "\nName: " + r.name
                item.setToolTip(1, text)

    def emit_jump_to_reaction(self, reaction):
        self.jumpToReaction.emit(reaction.data(2, 0).id)

    jumpToReaction = Signal(str)
    metaboliteChanged = Signal(cobra.Metabolite)
コード例 #8
0
ファイル: qt_extension2reader.py プロジェクト: kne42/napari
class Extension2ReaderTable(QWidget):
    """Table showing extension to reader mappings with removal button.

    Widget presented in preferences-plugin dialog."""

    valueChanged = Signal(int)

    def __init__(self, parent=None, npe2_readers=None, npe1_readers=None):
        super().__init__(parent=parent)

        npe2, npe1 = get_all_readers()
        if npe2_readers is None:
            npe2_readers = npe2
        if npe1_readers is None:
            npe1_readers = npe1

        self._npe2_readers = npe2_readers
        self._npe1_readers = npe1_readers

        self._table = QTableWidget()
        self._table.setShowGrid(False)
        self._set_up_table()
        self._edit_row = self._make_new_preference_row()
        self._populate_table()

        instructions = QLabel(
            trans.
            _('Enter a filename pattern to associate with a reader e.g. "*.tif" for all TIFF files.'
              ) + trans.
            _('Available readers will be filtered to those compatible with your pattern. Hover over a reader to see what patterns it accepts.'
              ) + trans.
            _('\n\nPreference saving for folder readers is not supported, so these readers are not shown.'
              ) + trans.
            _('\n\nFor documentation on valid filename patterns, see https://docs.python.org/3/library/fnmatch.html'
              ))
        instructions.setWordWrap(True)
        instructions.setOpenExternalLinks(True)

        layout = QVBoxLayout()
        instructions.setSizePolicy(QSizePolicy.MinimumExpanding,
                                   QSizePolicy.Expanding)
        layout.addWidget(instructions)
        layout.addWidget(self._edit_row)
        layout.addWidget(self._table)
        self.setLayout(layout)

    def _set_up_table(self):
        """Add table columns and headers, define styling"""
        self._fn_pattern_col = 0
        self._reader_col = 1

        header_strs = [trans._('Filename Pattern'), trans._('Reader Plugin')]

        self._table.setColumnCount(2)
        self._table.setColumnWidth(self._fn_pattern_col, 200)
        self._table.setColumnWidth(self._reader_col, 200)
        self._table.verticalHeader().setVisible(False)
        self._table.setMinimumHeight(120)
        self._table.horizontalHeader().setStyleSheet(
            'border-bottom: 2px solid white;')
        self._table.setHorizontalHeaderLabels(header_strs)
        self._table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    def _populate_table(self):
        """Add row for each extension to reader mapping in settings"""

        fnpattern2reader = get_settings().plugins.extension2reader
        if len(fnpattern2reader) > 0:
            for fn_pattern, plugin_name in fnpattern2reader.items():
                self._add_new_row(fn_pattern, plugin_name)
        else:
            # Display that there are no filename patterns with reader associations
            self._display_no_preferences_found()

    def _make_new_preference_row(self):
        """Make row for user to add a new filename pattern assignment"""
        edit_row_widget = QWidget()
        edit_row_widget.setLayout(QGridLayout())
        edit_row_widget.layout().setContentsMargins(0, 0, 0, 0)

        self._fn_pattern_edit = QLineEdit()
        self._fn_pattern_edit.setPlaceholderText(
            "Start typing filename pattern...")
        self._fn_pattern_edit.textChanged.connect(
            self._filter_compatible_readers)

        add_reader_widg = QWidget()
        add_reader_widg.setLayout(QHBoxLayout())
        add_reader_widg.layout().setContentsMargins(0, 0, 0, 0)

        self._new_reader_dropdown = QComboBox()
        for i, (plugin_name, display_name) in enumerate(
                sorted(dict(self._npe2_readers,
                            **self._npe1_readers).items())):
            self._add_reader_choice(i, plugin_name, display_name)

        add_btn = QPushButton('Add')
        add_btn.setToolTip(trans._('Save reader preference for pattern'))
        add_btn.clicked.connect(self._save_new_preference)

        add_reader_widg.layout().addWidget(self._new_reader_dropdown)
        add_reader_widg.layout().addWidget(add_btn)

        edit_row_widget.layout().addWidget(
            self._fn_pattern_edit,
            0,
            0,
        )
        edit_row_widget.layout().addWidget(add_reader_widg, 0, 1)

        return edit_row_widget

    def _display_no_preferences_found(self):
        self._table.setRowCount(1)
        item = QTableWidgetItem(trans._('No filename preferences found.'))
        item.setFlags(Qt.NoItemFlags)
        self._table.setItem(self._fn_pattern_col, 0, item)

    def _add_reader_choice(self, i, plugin_name, display_name):
        """Add dropdown item for plugin_name with reader pattern tooltip"""
        reader_patterns = get_filename_patterns_for_reader(plugin_name)
        # TODO: no reader_patterns means directory reader,
        # we don't support preference association yet
        if not reader_patterns:
            return

        self._new_reader_dropdown.addItem(display_name, plugin_name)
        if '*' in reader_patterns:
            tooltip_text = 'Accepts all'
        else:
            reader_patterns_formatted = ', '.join(sorted(
                list(reader_patterns)))
            tooltip_text = f'Accepts: {reader_patterns_formatted}'
        self._new_reader_dropdown.setItemData(i,
                                              tooltip_text,
                                              role=Qt.ToolTipRole)

    def _filter_compatible_readers(self, new_pattern):
        """Filter reader dropwdown items to those that accept `new_extension`"""
        self._new_reader_dropdown.clear()

        readers = self._npe2_readers.copy()
        to_delete = []

        compatible_readers = get_potential_readers(new_pattern)
        for plugin_name, display_name in readers.items():
            if plugin_name not in compatible_readers:
                to_delete.append(plugin_name)

        for reader in to_delete:
            del readers[reader]
        readers.update(self._npe1_readers)

        if not readers:
            self._new_reader_dropdown.addItem("None available")
        else:
            for i, (plugin_name,
                    display_name) in enumerate(sorted(readers.items())):
                self._add_reader_choice(i, plugin_name, display_name)

    def _save_new_preference(self, event):
        """Save current preference to settings and show in table"""
        fn_pattern = self._fn_pattern_edit.text()
        reader = self._new_reader_dropdown.currentData()

        if not fn_pattern or not reader:
            return

        # if user types pattern that starts with a . it's probably a file extension so prepend the *
        if fn_pattern.startswith('.'):
            fn_pattern = f'*{fn_pattern}'

        if fn_pattern in get_settings().plugins.extension2reader:
            self._edit_existing_preference(fn_pattern, reader)
        else:
            self._add_new_row(fn_pattern, reader)
        get_settings().plugins.extension2reader = {
            **get_settings().plugins.extension2reader,
            fn_pattern: reader,
        }

    def _edit_existing_preference(self, fn_pattern, reader):
        """Edit existing extension preference"""
        current_reader_label = self.findChild(QLabel, fn_pattern)
        if reader in self._npe2_readers:
            reader = self._npe2_readers[reader]
        current_reader_label.setText(reader)

    def _add_new_row(self, fn_pattern, reader):
        """Add new reader preference to table"""
        last_row = self._table.rowCount()

        if (last_row == 1 and 'No filename preferences found'
                in self._table.item(0, 0).text()):
            self._table.removeRow(0)
            last_row = 0

        self._table.insertRow(last_row)
        item = QTableWidgetItem(fn_pattern)
        item.setFlags(Qt.NoItemFlags)
        self._table.setItem(last_row, self._fn_pattern_col, item)

        plugin_widg = QWidget()
        # need object name to easily find row
        plugin_widg.setObjectName(f'{fn_pattern}')
        plugin_widg.setLayout(QHBoxLayout())
        plugin_widg.layout().setContentsMargins(0, 0, 0, 0)

        if reader in self._npe2_readers:
            reader = self._npe2_readers[reader]
        plugin_label = QLabel(reader, objectName=fn_pattern)
        # need object name to easily work out which button was clicked
        remove_btn = QPushButton('X', objectName=fn_pattern)
        remove_btn.setFixedWidth(30)
        remove_btn.setStyleSheet('margin: 4px;')
        remove_btn.setToolTip(
            trans._('Remove this filename pattern to reader association'))
        remove_btn.clicked.connect(self.remove_existing_preference)

        plugin_widg.layout().addWidget(plugin_label)
        plugin_widg.layout().addWidget(remove_btn)
        self._table.setCellWidget(last_row, self._reader_col, plugin_widg)

    def remove_existing_preference(self, event):
        """Delete extension to reader mapping setting and remove table row"""
        pattern_to_remove = self.sender().objectName()
        current_settings = get_settings().plugins.extension2reader
        # need explicit assignment to new object here for persistence
        get_settings().plugins.extension2reader = {
            k: v
            for k, v in current_settings.items() if k != pattern_to_remove
        }

        for i in range(self._table.rowCount()):
            row_widg_name = self._table.cellWidget(
                i, self._reader_col).objectName()
            if row_widg_name == pattern_to_remove:
                self._table.removeRow(i)
                break

        if self._table.rowCount() == 0:
            self._display_no_preferences_found()

    def value(self):
        """Return extension:reader mapping from settings.

        Returns
        -------
        Dict[str, str]
            mapping of extension to reader plugin display name
        """
        return get_settings().plugins.extension2reader