Example #1
0
def createList(labelText, slot, changedSlot, validator=None):
    widget = QWidget()
    layout = QVBoxLayout()
    layout.setObjectName('listLayout')
    widget.setLayout(layout)
    hboxWidget = QWidget()
    hboxLayout = QHBoxLayout()
    hboxLayout.setObjectName('hboxLayout for tableWidget')
    hboxWidget.setLayout(hboxLayout)
    tableWidget = QTableWidget(0, 2)
    tableWidget.setAlternatingRowColors(True)
    widget.connect(tableWidget, SIGNAL('cellChanged(int, int)'), changedSlot)
    tableWidget.setHorizontalHeaderLabels(createQStringList([labelText, '']))
    tableWidget.setColumnWidth(INPUT_IDX, contentColumnWidth)
    tableWidget.setColumnWidth(BUTTON_IDX, deleteButtonColumnWidth)
    hboxLayout.addWidget(tableWidget)

    add = QWidget()
    addLayout = QHBoxLayout()
    addLayout.setObjectName('addLayout')
    add.setLayout(addLayout)
    addLineEdit = createLineEdit(add, None, validator)
    addButton = createButton(translate('MainWindow', 'Add'), add, add,
            slot)
    add.connect(addLineEdit, SIGNAL('returnPressed()'), slot)
    for wid in addLineEdit, addButton:
        addLayout.addWidget(wid)

    for wid in add, hboxWidget:
        layout.addWidget(wid)
    return (widget, tableWidget, addLineEdit)
class InstalledWidget(QWidget):
    """
    This widget show the installed plugins
    """

    def __init__(self, parent, installed):
        QWidget.__init__(self, parent)
        self._parent = parent
        self._installed = installed
        vbox = QVBoxLayout(self)
        self._table = QTableWidget(1, 2)
        self._table.setSelectionMode(QTableWidget.SingleSelection)
        self._table.removeRow(0)
        vbox.addWidget(self._table)
        ui_tools.load_table(self._table, (self.tr('Name'), self.tr('Version')),
            _format_for_table(installed))
        self._table.setColumnWidth(0, 500)
        self._table.setSortingEnabled(True)
        self._table.setAlternatingRowColors(True)
        btnUninstall = QPushButton(self.tr("Uninstall"))
        btnUninstall.setMaximumWidth(100)
        vbox.addWidget(btnUninstall)

        self.connect(btnUninstall, SIGNAL("clicked()"),
            self._uninstall_plugins)
        self.connect(self._table, SIGNAL("itemSelectionChanged()"),
            self._show_item_description)

    def _show_item_description(self):
        item = self._table.currentItem()
        if item is not None:
            data = list(item.data(Qt.UserRole))
            self._parent.show_plugin_info(data)

    def remove_item(self, plugin_name):
        plugin = _get_plugin(plugin_name, self._installed)
        self._installed.remove(plugin)

    def add_table_items(self, plugs):
        self._installed += plugs
        data = _format_for_table(self._installed)
        ui_tools.load_table(self._table, (self.tr('Name'), self.tr('Version')),
            data)

    def _uninstall_plugins(self):
        data = _format_for_table(self._installed)
        plugins = ui_tools.remove_get_selected_items(self._table, data)
        self._parent.mark_as_available(plugins)

    def reset_table(self, installed):
        self._installed = installed
        while self._table.rowCount() > 0:
            self._table.removeRow(0)
        ui_tools.load_table(self._table, (self.tr('Name'), self.tr('Version')),
            self._installed)
Example #3
0
class AccountManagerDialog(QDialog):
    def __init__(self, emails, types, parent):
        self.emails, self.types = emails, types
        QDialog.__init__(self, parent)
        self.resize(560, 350)
        self.gridLayout = QGridLayout(self)
        self.tableWidget = QTableWidget(0, 2, self)
        self.tableWidget.setAlternatingRowColors(True)
        self.tableWidget.setSelectionBehavior(1)  # Rows
        self.tableWidget.setSelectionMode(1)  # Single
        self.tableWidget.horizontalHeader().setResizeMode(0, 1)  # 1 = Stretch
        self.tableWidget.setHorizontalHeaderLabels(['Email', 'Type'])
        self.addBtn = QPushButton('+', self)
        self.removeBtn = QPushButton('-', self)
        self.closeBtn = QPushButton('Close', self)
        self.spacer = QWidget(self)
        self.spacer.setSizePolicy(1 | 2 | 4, 1 | 4)
        self.gridLayout.addWidget(self.tableWidget, 0, 0, 1, 4)
        self.gridLayout.addWidget(self.addBtn, 1, 0, 1, 1)
        self.gridLayout.addWidget(self.removeBtn, 1, 1, 1, 1)
        self.gridLayout.addWidget(self.spacer, 1, 2, 1, 1)
        self.gridLayout.addWidget(self.closeBtn, 1, 3, 1, 1)
        self.addBtn.clicked.connect(self.addAccount)
        self.removeBtn.clicked.connect(self.removeAccount)
        self.closeBtn.clicked.connect(self.accept)
        for i in range(len(self.emails)):
            self.tableWidget.insertRow(i)
            self.tableWidget.setItem(i, 0, QTableWidgetItem(emails[i]))
            self.tableWidget.setItem(i, 1, QTableWidgetItem(types[i]))

    def addAccount(self):
        dialog = AddAccountDialog(self)
        if dialog.exec_() != QDialog.Accepted: return
        email = unicode(dialog.emailEdit.text())
        passwd = unicode(dialog.passwordEdit.text())
        ac_type = unicode(dialog.typeCombo.currentText())
        self.tableWidget.insertRow(0)
        self.tableWidget.setItem(0, 0, QTableWidgetItem(email))
        self.tableWidget.setItem(0, 1, QTableWidgetItem(ac_type))
        self.emails.insert(0, email)
        self.types.insert(0, ac_type)
        kr = Keyring()
        kr.setPassword(email, passwd)

    def removeAccount(self):
        row = self.tableWidget.selectionModel().selectedRows()[0].row()
        email = self.tableWidget.item(row, 0).text()
        kr = Keyring()
        kr.deletePassword(email)
        self.tableWidget.removeRow(row)
        self.emails.pop(row)
        self.types.pop(row)
class UpdatesWidget(QWidget):
    """
    This widget show the availables plugins to update
    """

    def __init__(self, parent, updates):
        QWidget.__init__(self, parent)
        self._parent = parent
        self._updates = updates
        vbox = QVBoxLayout(self)
        self._table = QTableWidget(1, 2)
        self._table.removeRow(0)
        self._table.setSelectionMode(QTableWidget.SingleSelection)
        self._table.setColumnWidth(0, 500)
        self._table.setSortingEnabled(True)
        self._table.setAlternatingRowColors(True)
        vbox.addWidget(self._table)
        ui_tools.load_table(self._table, (self.tr('Name'), self.tr('Version')),
            _format_for_table(updates))
        btnUpdate = QPushButton(self.tr("Update"))
        btnUpdate.setMaximumWidth(100)
        vbox.addWidget(btnUpdate)

        self.connect(btnUpdate, SIGNAL("clicked()"), self._update_plugins)
        self.connect(self._table, SIGNAL("itemSelectionChanged()"),
            self._show_item_description)

    def _show_item_description(self):
        item = self._table.currentItem()
        if item is not None:
            data = list(item.data(Qt.UserRole))
            self._parent.show_plugin_info(data)

    def _update_plugins(self):
        data = _format_for_table(self._updates)
        plugins = ui_tools.remove_get_selected_items(self._table, data)
        #get the download link of each plugin
        for p_row in plugins:
            #search the plugin
            for p_dict in self._updates:
                if p_dict["name"] == p_row[0]:
                    p_data = p_dict
                    break
            #append the downlod link
            p_row.append(p_data["download"])
        self._parent.update_plugin(plugins)
class OWdabam_height_profile(OWWidget):
    name = "DABAM Height Profile"
    id = "dabam_height_profile"
    description = "Calculation of mirror surface error profile"
    icon = "icons/dabam.png"
    author = "Luca Rebuffi"
    maintainer_email = "[email protected]; [email protected]"
    priority = 6
    category = ""
    keywords = ["dabam_height_profile"]

    outputs = [{"name": "PreProcessor_Data",
                "type": ShadowPreProcessorData,
                "doc": "PreProcessor Data",
                "id": "PreProcessor_Data"}]

    want_main_area = 1
    want_control_area = 1

    MAX_WIDTH = 1320
    MAX_HEIGHT = 700

    IMAGE_WIDTH = 860
    IMAGE_HEIGHT = 645

    CONTROL_AREA_WIDTH = 405
    TABS_AREA_HEIGHT = 618

    xx = None
    yy = None
    zz = None

    entry_number = Setting(1)

    shape=Setting(0)
    slope_error_from = Setting(0.0)
    slope_error_to = Setting(1.5)
    dimension_y_from = Setting(0.0)
    dimension_y_to = Setting(200.0)

    use_undetrended = Setting(0)

    step_x = Setting(1.0)
    dimension_x = Setting(10.0)

    center_y = Setting(1)
    modify_y = Setting(0)
    new_length = Setting(200.0)
    filler_value = Setting(0.0)

    scale_factor_y = Setting(1.0)
    renormalize_y = Setting(1)
    error_type_y = Setting(0)
    rms_y = Setting(0.9)

    dabam_profile_index = Setting(1)

    heigth_profile_file_name = Setting('mirror.dat')

    tab=[]

    def __init__(self):
        super().__init__()

        self.runaction = widget.OWAction("Calculate Height Profile", self)
        self.runaction.triggered.connect(self.calculate_heigth_profile_ni)
        self.addAction(self.runaction)

        self.runaction = widget.OWAction("Generate Height Profile File", self)
        self.runaction.triggered.connect(self.generate_heigth_profile_file_ni)
        self.addAction(self.runaction)

        geom = QApplication.desktop().availableGeometry()
        self.setGeometry(QRect(round(geom.width() * 0.05),
                               round(geom.height() * 0.05),
                               round(min(geom.width() * 0.98, self.MAX_WIDTH)),
                               round(min(geom.height() * 0.95, self.MAX_HEIGHT))))

        self.setMaximumHeight(self.geometry().height())
        self.setMaximumWidth(self.geometry().width())

        # DABAM INITIALIZATION
        self.server = dabam.dabam()
        self.server.set_input_silent(True)

        gui.separator(self.controlArea)

        button_box = oasysgui.widgetBox(self.controlArea, "", addSpace=False, orientation="horizontal")

        button = gui.button(button_box, self, "Calculate Height\nProfile", callback=self.calculate_heigth_profile)
        button.setFixedHeight(45)

        button = gui.button(button_box, self, "Generate Height\nProfile File", callback=self.generate_heigth_profile_file)
        font = QFont(button.font())
        font.setBold(True)
        button.setFont(font)
        palette = QPalette(button.palette())  # make a copy of the palette
        palette.setColor(QPalette.ButtonText, QColor('Dark Blue'))
        button.setPalette(palette)  # assign new palette
        button.setFixedHeight(45)
        button.setFixedWidth(150)

        button = gui.button(button_box, self, "Reset Fields", callback=self.call_reset_settings)
        font = QFont(button.font())
        font.setItalic(True)
        button.setFont(font)
        palette = QPalette(button.palette())  # make a copy of the palette
        palette.setColor(QPalette.ButtonText, QColor('Dark Red'))
        button.setPalette(palette)  # assign new palette
        button.setFixedHeight(45)

        gui.separator(self.controlArea)

        tabs_setting = gui.tabWidget(self.controlArea)
        tabs_setting.setFixedHeight(self.TABS_AREA_HEIGHT)
        tabs_setting.setFixedWidth(self.CONTROL_AREA_WIDTH-5)

        tab_input = oasysgui.createTabPage(tabs_setting, "DABAM Search Setting")
        tab_gener = oasysgui.createTabPage(tabs_setting, "DABAM Generation Setting")
        tab_out = oasysgui.createTabPage(tabs_setting, "Output")

        manual_box = oasysgui.widgetBox(tab_input, "Manual Entry", addSpace=True, orientation="vertical")

        oasysgui.lineEdit(manual_box, self, "entry_number", "Entry Number",
                           labelWidth=300, valueType=int, orientation="horizontal")

        gui.separator(manual_box)

        button = gui.button(manual_box, self, "Retrieve Profile", callback=self.retrieve_profile)
        button.setFixedHeight(35)
        button.setFixedWidth(self.CONTROL_AREA_WIDTH-35)

        input_box = oasysgui.widgetBox(tab_input, "Search Parameters", addSpace=True, orientation="vertical")

        gui.comboBox(input_box, self, "shape", label="Mirror Shape", labelWidth=300,
                     items=["All", "Plane", "Cylindrical", "Elliptical", "Toroidal", "Spherical"],
                     sendSelectedValue=False, orientation="horizontal")

        gui.separator(input_box)
        
        input_box_1 = oasysgui.widgetBox(input_box, "", addSpace=True, orientation="horizontal")

        oasysgui.lineEdit(input_box_1, self, "slope_error_from", "Slope Error From (" + u"\u03BC" + "rad)",
                           labelWidth=150, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(input_box_1, self, "slope_error_to", "To (" + u"\u03BC" + "rad)",
                           labelWidth=60, valueType=float, orientation="horizontal")

        input_box_2 = oasysgui.widgetBox(input_box, "", addSpace=True, orientation="horizontal")

        self.le_dimension_y_from = oasysgui.lineEdit(input_box_2, self, "dimension_y_from", "Mirror Length From",
                           labelWidth=150, valueType=float, orientation="horizontal")
        self.le_dimension_y_to = oasysgui.lineEdit(input_box_2, self, "dimension_y_to", "To",
                           labelWidth=60, valueType=float, orientation="horizontal")

        table_box = oasysgui.widgetBox(tab_input, "Search Results", addSpace=True, orientation="vertical", height=290)

        self.overlay_search = Overlay(table_box, self.search_profiles)
        self.overlay_search.hide()

        button = gui.button(input_box, self, "Search", callback=self.overlay_search.show)
        button.setFixedHeight(35)
        button.setFixedWidth(self.CONTROL_AREA_WIDTH-35)

        gui.comboBox(table_box, self, "use_undetrended", label="Use Undetrended Profile", labelWidth=300,
                     items=["No", "Yes"], callback=self.table_item_clicked, sendSelectedValue=False, orientation="horizontal")

        gui.separator(table_box)

        self.scrollarea = QScrollArea()
        self.scrollarea.setMinimumWidth(self.CONTROL_AREA_WIDTH-35)

        table_box.layout().addWidget(self.scrollarea, alignment=Qt.AlignHCenter)

        self.table = QTableWidget(1, 5)
        self.table.setAlternatingRowColors(True)
        self.table.horizontalHeader().setResizeMode(QHeaderView.Fixed)
        self.table.verticalHeader().setVisible(False)

        self.table.setColumnWidth(0, 40)
        self.table.setColumnWidth(1, 70)
        self.table.setColumnWidth(2, 70)
        self.table.setColumnWidth(3, 85)
        self.table.setColumnWidth(4, 80)

        self.table.resizeRowsToContents()
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.itemClicked.connect(self.table_item_clicked)

        self.scrollarea.setWidget(self.table)
        self.scrollarea.setWidgetResizable(1)

        output_profile_box = oasysgui.widgetBox(tab_gener, "Surface Generation Parameters", addSpace=True, orientation="vertical", height=270)

        self.le_dimension_x = oasysgui.lineEdit(output_profile_box, self, "dimension_x", "Width",
                           labelWidth=300, valueType=float, orientation="horizontal")
        self.le_step_x = oasysgui.lineEdit(output_profile_box, self, "step_x", "Step Width",
                           labelWidth=300, valueType=float, orientation="horizontal")

        gui.comboBox(output_profile_box, self, "center_y", label="Center Profile in the middle of O.E.", labelWidth=300,
                     items=["No", "Yes"], sendSelectedValue=False, orientation="horizontal")

        gui.comboBox(output_profile_box, self, "modify_y", label="Modify Length?", labelWidth=240,
                     items=["No", "Rescale to new length", "Fit to new length (fill or cut)"], callback=self.set_ModifyY, sendSelectedValue=False, orientation="horizontal")

        self.modify_box_1 = oasysgui.widgetBox(output_profile_box, "", addSpace=False, orientation="vertical", height=50)

        self.modify_box_2 = oasysgui.widgetBox(output_profile_box, "", addSpace=False, orientation="vertical", height=50)
        oasysgui.lineEdit(self.modify_box_2, self, "scale_factor_y", "Scale Factor", labelWidth=300, valueType=float, orientation="horizontal")

        self.modify_box_3 = oasysgui.widgetBox(output_profile_box, "", addSpace=False, orientation="vertical", height=50)
        self.le_new_length = oasysgui.lineEdit(self.modify_box_3, self, "new_length", "New Length", labelWidth=300, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.modify_box_3, self, "filler_value", "Filler Value (if new length > profile length) [nm]", labelWidth=300, valueType=float, orientation="horizontal")

        self.set_ModifyY()

        gui.comboBox(output_profile_box, self, "renormalize_y", label="Renormalize Length Profile to different RMS", labelWidth=300,
                     items=["No", "Yes"], callback=self.set_RenormalizeY, sendSelectedValue=False, orientation="horizontal")

        self.output_profile_box_1 = oasysgui.widgetBox(output_profile_box, "", addSpace=True, orientation="vertical")

        gui.comboBox(self.output_profile_box_1, self, "error_type_y", label="Normalization to", labelWidth=270,
                     items=["Figure Error (nm)", "Slope Error (" + u"\u03BC" + "rad)"],
                     sendSelectedValue=False, orientation="horizontal")

        oasysgui.lineEdit(self.output_profile_box_1, self, "rms_y", "Rms Value",
                           labelWidth=300, valueType=float, orientation="horizontal")

        self.set_RenormalizeY()

        output_box = oasysgui.widgetBox(tab_gener, "Outputs", addSpace=True, orientation="vertical")

        select_file_box = oasysgui.widgetBox(output_box, "", addSpace=True, orientation="horizontal")

        self.le_heigth_profile_file_name = oasysgui.lineEdit(select_file_box, self, "heigth_profile_file_name", "Output File Name",
                                                        labelWidth=120, valueType=str, orientation="horizontal")

        gui.button(select_file_box, self, "...", callback=self.selectFile)

        self.shadow_output = QTextEdit()
        self.shadow_output.setReadOnly(True)

        out_box = oasysgui.widgetBox(tab_out, "System Output", addSpace=True, orientation="horizontal", height=500)
        out_box.layout().addWidget(self.shadow_output)

        gui.rubber(self.controlArea)

        self.initializeTabs()

        gui.rubber(self.mainArea)

        self.overlay_search.raise_()

    def resizeEvent(self, event):
        self.overlay_search.resize(self.CONTROL_AREA_WIDTH - 15, 290)
        event.accept()

    def after_change_workspace_units(self):
        self.si_to_user_units = 1e2 / self.workspace_units_to_cm

        self.horHeaders = ["Entry", "Shape", "Length\n[" + self.workspace_units_label + "]", "Heights St.Dev.\n[nm]",  "Slopes St.Dev.\n[" + u"\u03BC" + "rad]"]
        self.table.setHorizontalHeaderLabels(self.horHeaders)
        self.plot_canvas[0].setGraphXLabel("Y [" + self.workspace_units_label + "]")
        self.plot_canvas[1].setGraphXLabel("Y [" + self.workspace_units_label + "]")
        self.axis.set_xlabel("X [" + self.workspace_units_label + "]")
        self.axis.set_ylabel("Y [" + self.workspace_units_label + "]")

        label = self.le_dimension_y_from.parent().layout().itemAt(0).widget()
        label.setText(label.text() + " [" + self.workspace_units_label + "]")
        label = self.le_dimension_y_to.parent().layout().itemAt(0).widget()
        label.setText(label.text() + " [" + self.workspace_units_label + "]")
        label = self.le_dimension_x.parent().layout().itemAt(0).widget()
        label.setText(label.text() + " [" + self.workspace_units_label + "]")
        label = self.le_step_x.parent().layout().itemAt(0).widget()
        label.setText(label.text() + " [" + self.workspace_units_label + "]")
        label = self.le_new_length.parent().layout().itemAt(0).widget()
        label.setText(label.text() + " [" + self.workspace_units_label + "]")

    def initializeTabs(self):
        self.tabs = gui.tabWidget(self.mainArea)

        self.tab = [gui.createTabPage(self.tabs, "Info"),
                    gui.createTabPage(self.tabs, "Heights Profile"),
                    gui.createTabPage(self.tabs, "Slopes Profile"),
                    gui.createTabPage(self.tabs, "PSD Heights"),
                    gui.createTabPage(self.tabs, "CSD Heights"),
                    gui.createTabPage(self.tabs, "ACF"),
                    gui.createTabPage(self.tabs, "Generated 2D Profile"),
        ]

        for tab in self.tab:
            tab.setFixedHeight(self.IMAGE_HEIGHT)
            tab.setFixedWidth(self.IMAGE_WIDTH)

        self.plot_canvas = [None, None, None, None, None, None]

        self.plot_canvas[0] = PlotWindow(roi=False, control=False, position=True, plugins=False)
        self.plot_canvas[0].setDefaultPlotLines(True)
        self.plot_canvas[0].setActiveCurveColor(color='darkblue')
        self.plot_canvas[0].setGraphYLabel("Z [nm]")
        self.plot_canvas[0].setGraphTitle("Heights Profile")
        self.plot_canvas[0].setDrawModeEnabled(True, 'rectangle')
        self.plot_canvas[0].setZoomModeEnabled(True)

        self.plot_canvas[1] = PlotWindow(roi=False, control=False, position=True, plugins=False)
        self.plot_canvas[1].setDefaultPlotLines(True)
        self.plot_canvas[1].setActiveCurveColor(color='darkblue')
        self.plot_canvas[1].setGraphYLabel("Zp [$\mu$rad]")
        self.plot_canvas[1].setGraphTitle("Slopes Profile")
        self.plot_canvas[1].setDrawModeEnabled(True, 'rectangle')
        self.plot_canvas[1].setZoomModeEnabled(True)

        self.plot_canvas[2] = PlotWindow(roi=False, control=False, position=True, plugins=False)
        self.plot_canvas[2].setDefaultPlotLines(True)
        self.plot_canvas[2].setActiveCurveColor(color='darkblue')
        self.plot_canvas[2].setGraphXLabel("f [m^-1]")
        self.plot_canvas[2].setGraphYLabel("PSD [m^3]")
        self.plot_canvas[2].setGraphTitle("Power Spectral Density of Heights Profile")
        self.plot_canvas[2].setDrawModeEnabled(True, 'rectangle')
        self.plot_canvas[2].setZoomModeEnabled(True)
        self.plot_canvas[2].setXAxisLogarithmic(True)
        self.plot_canvas[2].setYAxisLogarithmic(True)

        self.plot_canvas[3] = PlotWindow(roi=False, control=False, position=True, plugins=False)
        self.plot_canvas[3].setDefaultPlotLines(True)
        self.plot_canvas[3].setActiveCurveColor(color='darkblue')
        self.plot_canvas[3].setGraphXLabel("f [m^-1]")
        self.plot_canvas[3].setGraphYLabel("CSD [m^3]")
        self.plot_canvas[3].setGraphTitle("Cumulative Spectral Density of Heights Profile")
        self.plot_canvas[3].setDrawModeEnabled(True, 'rectangle')
        self.plot_canvas[3].setZoomModeEnabled(True)
        self.plot_canvas[3].setXAxisLogarithmic(True)

        self.plot_canvas[4] = PlotWindow(roi=False, control=False, position=True, plugins=False)
        self.plot_canvas[4].setDefaultPlotLines(True)
        self.plot_canvas[4].setActiveCurveColor(color='darkblue')
        self.plot_canvas[4].setGraphXLabel("Length [m]")
        self.plot_canvas[4].setGraphYLabel("ACF")
        self.plot_canvas[4].setGraphTitle("Autocovariance Function of Heights Profile")
        self.plot_canvas[4].setDrawModeEnabled(True, 'rectangle')
        self.plot_canvas[4].setZoomModeEnabled(True)

        self.figure = Figure(figsize=(self.IMAGE_HEIGHT, self.IMAGE_HEIGHT)) # QUADRATA!
        self.figure.patch.set_facecolor('white')

        self.axis = self.figure.add_subplot(111, projection='3d')

        self.axis.set_zlabel("Z [nm]")

        self.plot_canvas[5] = FigureCanvasQTAgg(self.figure)

        self.profileInfo = QTextEdit()
        self.profileInfo.setReadOnly(True)
        self.profileInfo.setMinimumHeight(self.IMAGE_HEIGHT-5)
        self.profileInfo.setMaximumHeight(self.IMAGE_HEIGHT-5)
        self.profileInfo.setMinimumWidth(310)
        self.profileInfo.setMaximumWidth(310)

        profile_box = oasysgui.widgetBox(self.tab[0], "", addSpace=True, orientation="horizontal", height = self.IMAGE_HEIGHT, width=320)
        profile_box.layout().addWidget(self.profileInfo)

        for index in range(0, 6):
            self.tab[index+1].layout().addWidget(self.plot_canvas[index])

        self.tabs.setCurrentIndex(1)

    def plot_dabam_graph(self, plot_canvas_index, curve_name, x_values, y_values, xtitle, ytitle, color='blue', replace=True):
        self.plot_canvas[plot_canvas_index].addCurve(x_values, y_values, curve_name, symbol='', color=color, replace=replace) #'+', '^', ','
        self.plot_canvas[plot_canvas_index].setGraphXLabel(xtitle)
        self.plot_canvas[plot_canvas_index].setGraphYLabel(ytitle)
        self.plot_canvas[plot_canvas_index].replot()

    def set_ModifyY(self):
        self.modify_box_1.setVisible(self.modify_y == 0)
        self.modify_box_2.setVisible(self.modify_y == 1)
        self.modify_box_3.setVisible(self.modify_y == 2)

    def set_RenormalizeY(self):
        self.output_profile_box_1.setVisible(self.renormalize_y==1)

    def table_item_clicked(self):
        if self.table.selectionModel().hasSelection():
            if not self.table.rowCount() == 0:
                if not self.table.item(0, 0) is None:
                    row = self.table.selectionModel().selectedRows()[0].row()
                    self.entry_number = int(self.table.item(row, 0).text())

                    self.retrieve_profile()

    def retrieve_profile(self):
        try:
            if self.entry_number is None or self.entry_number <= 0:
                raise Exception("Entry number should be a strictly positive integer number")

            self.server.load(self.entry_number)
            self.profileInfo.setText(self.server.info_profiles())
            self.plot_canvas[0].setGraphTitle(
                "Heights Profile. St.Dev.=%.3f nm" % (self.server.stdev_profile_heights() * 1e9))
            self.plot_canvas[1].setGraphTitle(
                "Slopes Profile. St.Dev.=%.3f $\mu$rad" % (self.server.stdev_profile_slopes() * 1e6))
            if self.use_undetrended == 0:
                self.plot_dabam_graph(0, "heights_profile", self.si_to_user_units * self.server.y,
                                      1e9 * self.server.zHeights, "Y [" + self.workspace_units_label + "]", "Z [nm]")
                self.plot_dabam_graph(1, "slopes_profile", self.si_to_user_units * self.server.y, 1e6 * self.server.zSlopes,
                                      "Y [" + self.workspace_units_label + "]", "Zp [$\mu$rad]")
            else:
                self.plot_dabam_graph(0, "heights_profile", self.si_to_user_units * self.server.y,
                                      1e9 * self.server.zHeightsUndetrended, "Y [" + self.workspace_units_label + "]",
                                      "Z [nm]")
                self.plot_dabam_graph(1, "slopes_profile", self.si_to_user_units * self.server.y,
                                      1e6 * self.server.zSlopesUndetrended, "Y [" + self.workspace_units_label + "]",
                                      "Zp [$\mu$rad]")
            y = self.server.f ** (self.server.powerlaw["hgt_pendent"]) * 10 ** self.server.powerlaw["hgt_shift"]
            i0 = self.server.powerlaw["index_from"]
            i1 = self.server.powerlaw["index_to"]
            beta = -self.server.powerlaw["hgt_pendent"]
            self.plot_canvas[2].setGraphTitle(
                "Power Spectral Density of Heights Profile (beta=%.2f,Df=%.2f)" % (beta, (5 - beta) / 2))
            self.plot_dabam_graph(2, "psd_heights_2", self.server.f, self.server.psdHeights, "f [m^-1]", "PSD [m^3]")
            self.plot_dabam_graph(2, "psd_heights_1", self.server.f, y, "f [m^-1]", "PSD [m^3]", color='green',
                                  replace=False)
            self.plot_dabam_graph(2, "psd_heights_3", self.server.f[i0:i1], y[i0:i1], "f [m^-1]", "PSD [m^3]", color='red',
                                  replace=False)
            self.plot_dabam_graph(3, "csd", self.server.f, self.server.csd_heights(), "f [m^-1]", "CSD [m^3]")
            c1, c2, c3 = dabam.autocorrelationfunction(self.server.y, self.server.zHeights)
            self.plot_canvas[4].setGraphTitle(
                "Autocovariance Function of Heights Profile.\nAutocorrelation Length (ACF=0.5)=%.3f m" % (c3))
            self.plot_dabam_graph(4, "acf", c1[0:-1], c2, "Length [m]", "Heights Autocovariance")
            # surface error removal
            if not self.zz is None and not self.yy is None and not self.xx is None:
                self.xx = None
                self.yy = None
                self.zz = None
                self.axis.set_title("")
                self.axis.clear()
                self.plot_canvas[5].draw()

            if (self.tabs.currentIndex()==6): self.tabs.setCurrentIndex(1)

        except Exception as exception:
            QMessageBox.critical(self, "Error",
                                 exception.args[0],
                                 QMessageBox.Ok)

            #raise exception


    def search_profiles(self):
        try:
            self.table.itemClicked.disconnect(self.table_item_clicked)
            self.table.clear()

            row_count = self.table.rowCount()
            for n in range(0, row_count):
                self.table.removeRow(0)

            self.table.setHorizontalHeaderLabels(self.horHeaders)

            profiles = dabam.dabam_summary_dictionary(surface=self.get_dabam_shape(),
                                                      slp_err_from=self.slope_error_from*1e-6,
                                                      slp_err_to=self.slope_error_to*1e-6,
                                                      length_from=self.dimension_y_from / self.si_to_user_units,
                                                      length_to=self.dimension_y_to / self.si_to_user_units)

            for index in range(0, len(profiles)):
                self.table.insertRow(0)

            for index in range(0, len(profiles)):
                table_item = QTableWidgetItem(str(profiles[index]["entry"]))
                table_item.setTextAlignment(Qt.AlignCenter)
                self.table.setItem(index, 0, table_item)
                table_item = QTableWidgetItem(str(profiles[index]["surface"]))
                table_item.setTextAlignment(Qt.AlignLeft)
                self.table.setItem(index, 1, table_item)
                table_item = QTableWidgetItem(str(numpy.round(profiles[index]["length"]*self.si_to_user_units, 3)))
                table_item.setTextAlignment(Qt.AlignRight)
                self.table.setItem(index, 2, table_item)
                table_item = QTableWidgetItem(str(numpy.round(profiles[index]["hgt_err"]*1e9, 3)))
                table_item.setTextAlignment(Qt.AlignRight)
                self.table.setItem(index, 3, table_item)
                table_item = QTableWidgetItem(str(numpy.round(profiles[index]["slp_err"]*1e6, 3)))
                table_item.setTextAlignment(Qt.AlignRight)
                self.table.setItem(index, 4, table_item)

            self.table.setHorizontalHeaderLabels(self.horHeaders)
            self.table.resizeRowsToContents()
            self.table.setSelectionBehavior(QAbstractItemView.SelectRows)

            self.table.itemClicked.connect(self.table_item_clicked)

            self.overlay_search.hide()

        except Exception as exception:
            self.overlay_search.hide()

            QMessageBox.critical(self, "Error",
                                 exception.args[0],
                                 QMessageBox.Ok)

    def get_dabam_shape(self):
        if self.shape == 0: return None
        elif self.shape == 1: return "plane"
        elif self.shape == 2: return "cylindrical"
        elif self.shape == 3: return "elliptical"
        elif self.shape == 4: return "toroidal"
        elif self.shape == 5: return "spherical"

    def calculate_heigth_profile_ni(self):
        self.calculate_heigth_profile(not_interactive_mode=True)

    def calculate_heigth_profile(self, not_interactive_mode=False):
        try:
            if self.server.y is None: raise Exception("No Profile Selected")

            sys.stdout = EmittingStream(textWritten=self.writeStdOut)

            self.check_fields()

            combination = "EF"

            if self.modify_y == 2:
                profile_1D_y_x_temp = self.si_to_user_units * self.server.y
                if self.use_undetrended == 0: profile_1D_y_y_temp = self.si_to_user_units * self.server.zHeights
                else: profile_1D_y_y_temp = self.si_to_user_units * self.server.zHeightsUndetrended

                first_coord = profile_1D_y_x_temp[0]
                second_coord  = profile_1D_y_x_temp[1]
                last_coord = profile_1D_y_x_temp[-1]
                step = numpy.abs(second_coord - first_coord)
                length = numpy.abs(last_coord - first_coord)
                n_points_old = len(profile_1D_y_x_temp)

                if self.new_length > length:
                    difference = self.new_length - length

                    n_added_points = int(difference/step)
                    if difference % step == 0:
                        n_added_points += 1
                    if n_added_points % 2 != 0:
                        n_added_points += 1


                    profile_1D_y_x = numpy.arange(n_added_points + n_points_old) * step
                    profile_1D_y_y = numpy.ones(n_added_points + n_points_old) * self.filler_value * 1e-9 * self.si_to_user_units
                    profile_1D_y_y[int(n_added_points/2) : n_points_old + int(n_added_points/2)] = profile_1D_y_y_temp
                elif self.new_length < length:
                    difference = length - self.new_length

                    n_removed_points = int(difference/step)
                    if difference % step == 0:
                        n_removed_points -= 1
                    if n_removed_points % 2 != 0:
                        n_removed_points -= 1

                    if n_removed_points >= 2:
                        profile_1D_y_x = profile_1D_y_x_temp[0 : (n_points_old - n_removed_points)]
                        profile_1D_y_y = profile_1D_y_y_temp[(int(n_removed_points/2) - 1) : (n_points_old - int(n_removed_points/2) - 1)]

                    else:
                        profile_1D_y_x = profile_1D_y_x_temp
                        profile_1D_y_y = profile_1D_y_y_temp
                else:
                    profile_1D_y_x = profile_1D_y_x_temp
                    profile_1D_y_y = profile_1D_y_y_temp

            else:
                if self.modify_y == 0:
                    profile_1D_y_x = self.si_to_user_units * self.server.y
                elif self.modify_y == 1:
                    profile_1D_y_x = self.si_to_user_units * self.server.y * self.scale_factor_y

                if self.use_undetrended == 0: profile_1D_y_y = self.si_to_user_units * self.server.zHeights
                else: profile_1D_y_y = self.si_to_user_units * self.server.zHeightsUndetrended


            if self.center_y:
                first_coord = profile_1D_y_x[0]
                last_coord = profile_1D_y_x[-1]
                length = numpy.abs(last_coord - first_coord)

                profile_1D_y_x_temp = numpy.linspace(-length/2, length/2, len(profile_1D_y_x))

                profile_1D_y_x = profile_1D_y_x_temp

            if self.renormalize_y == 0:
                rms_y = None
            else:
                if self.error_type_y == profiles_simulation.FIGURE_ERROR:
                    rms_y = self.si_to_user_units * self.rms_y * 1e-9   # from nm to user units
                else:
                    rms_y = self.rms_y * 1e-6 # from urad to rad

            xx, yy, zz = profiles_simulation.simulate_profile_2D(combination = combination,
                                                                 error_type_l = self.error_type_y,
                                                                 rms_l = rms_y,
                                                                 x_l = profile_1D_y_x,
                                                                 y_l = profile_1D_y_y,
                                                                 mirror_width = self.dimension_x,
                                                                 step_w = self.step_x,
                                                                 rms_w = 0.0)

            self.xx = xx
            self.yy = yy
            self.zz = zz # in user units

            self.axis.clear()

            x_to_plot, y_to_plot = numpy.meshgrid(xx, yy)
            z_to_plot = zz * 1e9 / self.si_to_user_units #nm

            self.axis.plot_surface(x_to_plot, y_to_plot, z_to_plot,
                                   rstride=1, cstride=1, cmap=cm.autumn, linewidth=0.5, antialiased=True)

            sloperms = profiles_simulation.slopes(zz.T, xx, yy, return_only_rms=1)

            title = ' Slope error rms in X direction: %f $\mu$rad' % (sloperms[0]*1e6) + '\n' + \
                    ' Slope error rms in Y direction: %f $\mu$rad' % (sloperms[1]*1e6)

            self.axis.set_xlabel("X [" + self.workspace_units_label + "]")
            self.axis.set_ylabel("Y [" + self.workspace_units_label + "]")
            self.axis.set_zlabel("Z [nm]")

            self.axis.set_title(title)
            self.axis.mouse_init()

            if not not_interactive_mode:
                try:
                    self.plot_canvas[5].draw()
                except:
                    pass

                self.tabs.setCurrentIndex(6)

                QMessageBox.information(self, "QMessageBox.information()",
                                        "Height Profile calculated: if the result is satisfactory,\nclick \'Generate Height Profile File\' to complete the operation ",
                                        QMessageBox.Ok)
        except Exception as exception:
            QMessageBox.critical(self, "Error",
                                 exception.args[0],
                                 QMessageBox.Ok)

            #raise exception

    def generate_heigth_profile_file_ni(self):
        self.generate_heigth_profile_file(not_interactive_mode=True)

    def generate_heigth_profile_file(self, not_interactive_mode=False):
        if not self.zz is None and not self.yy is None and not self.xx is None:
            try:
                congruence.checkDir(self.heigth_profile_file_name)

                sys.stdout = EmittingStream(textWritten=self.writeStdOut)

                ST.write_shadow_surface(self.zz, self.xx, self.yy, outFile=congruence.checkFileName(self.heigth_profile_file_name))
                if not not_interactive_mode:
                    QMessageBox.information(self, "QMessageBox.information()",
                                            "Height Profile file " + self.heigth_profile_file_name + " written on disk",
                                            QMessageBox.Ok)
                if self.modify_y == 0:
                    dimension_y = self.si_to_user_units * (self.server.y[-1] - self.server.y[0])
                if self.modify_y == 1:
                    dimension_y = self.si_to_user_units * (self.server.y[-1] - self.server.y[0]) * self.scale_factor_y
                elif self.modify_y == 2:
                    dimension_y = self.new_length

                self.send("PreProcessor_Data", ShadowPreProcessorData(error_profile_data_file=self.heigth_profile_file_name,
                                                                      error_profile_x_dim=self.dimension_x,
                                                                      error_profile_y_dim=dimension_y))
            except Exception as exception:
                QMessageBox.critical(self, "Error",
                                     exception.args[0],
                                     QMessageBox.Ok)

    def call_reset_settings(self):
        if ConfirmDialog.confirmed(parent=self, message="Confirm Reset of the Fields?"):
            try:
                self.resetSettings()
            except:
                pass

    def check_fields(self):
        self.dimension_x = congruence.checkStrictlyPositiveNumber(self.dimension_x, "Dimension X")
        self.step_x = congruence.checkStrictlyPositiveNumber(self.step_x, "Step X")
        if self.step_x > self.dimension_x/2:
            raise Exception("Step Width should be smaller than or equal to Width/2")
        if self.modify_y == 1:
            self.scale_factor_y = congruence.checkStrictlyPositiveNumber(self.scale_factor_y, "Scale Factor")
        elif self.modify_y == 2:
            self.new_length = congruence.checkStrictlyPositiveNumber(self.new_length, "New Length")

        if self.renormalize_y == 1:
            self.rms_y = congruence.checkPositiveNumber(self.rms_y, "Rms Y")

        congruence.checkDir(self.heigth_profile_file_name)

    def writeStdOut(self, text):
        cursor = self.shadow_output.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertText(text)
        self.shadow_output.setTextCursor(cursor)
        self.shadow_output.ensureCursorVisible()

    def selectFile(self):
        self.le_heigth_profile_file_name.setText(oasysgui.selectFileFromDialog(self, self.heigth_profile_file_name, "Select Output File", file_extension_filter="Data Files (*.dat)"))
Example #6
0
class Main(plugin.Plugin):
    " Main Class "

    def initialize(self, *args, **kwargs):
        " Init Main Class "
        super(Main, self).initialize(*args, **kwargs)
        self.scriptPath, self.scriptArgs = "", []
        self.profilerPath, self.tempPath = profilerPath, tempPath
        self.output = " ERROR: FAIL: No output ! "

        self.process = QProcess()
        self.process.finished.connect(self.on_process_finished)
        self.process.error.connect(self.on_process_error)

        self.tabWidget, self.stat = QTabWidget(), QWidget()
        self.tabWidget.tabCloseRequested.connect(
            lambda: self.tabWidget.setTabPosition(1) if self.tabWidget.
            tabPosition() == 0 else self.tabWidget.setTabPosition(0))
        self.tabWidget.setStyleSheet('QTabBar{font-weight:bold;}')
        self.tabWidget.setMovable(True)
        self.tabWidget.setTabsClosable(True)
        self.vboxlayout1 = QVBoxLayout(self.stat)
        self.hboxlayout1 = QHBoxLayout()
        self.filterTableLabel = QLabel("<b>Type to Search : </b>", self.stat)
        self.hboxlayout1.addWidget(self.filterTableLabel)
        self.filterTableLineEdit = QLineEdit(self.stat)
        self.filterTableLineEdit.setPlaceholderText(' Type to Search . . . ')
        self.hboxlayout1.addWidget(self.filterTableLineEdit)
        self.filterHintTableLabel = QLabel(" ? ", self.stat)
        self.hboxlayout1.addWidget(self.filterHintTableLabel)
        self.vboxlayout1.addLayout(self.hboxlayout1)
        self.tableWidget = QTableWidget(self.stat)
        self.tableWidget.setAlternatingRowColors(True)
        self.tableWidget.setColumnCount(8)
        self.tableWidget.setRowCount(2)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(3, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(4, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(5, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(6, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(7, item)
        self.tableWidget.itemDoubleClicked.connect(
            self.on_tableWidget_itemDoubleClicked)
        self.vboxlayout1.addWidget(self.tableWidget)
        self.tabWidget.addTab(self.stat, " ? ")

        self.source = QWidget()
        self.gridlayout = QGridLayout(self.source)
        self.scintillaWarningLabel = QLabel(
            "QScintilla is not installed!. Falling back to basic text edit!.",
            self.source)
        self.gridlayout.addWidget(self.scintillaWarningLabel, 1, 0, 1, 2)
        self.sourceTreeWidget = QTreeWidget(self.source)
        self.sourceTreeWidget.setAlternatingRowColors(True)
        self.sourceTreeWidget.itemActivated.connect(
            self.on_sourceTreeWidget_itemActivated)
        self.sourceTreeWidget.itemClicked.connect(
            self.on_sourceTreeWidget_itemClicked)
        self.sourceTreeWidget.itemDoubleClicked.connect(
            self.on_sourceTreeWidget_itemClicked)

        self.gridlayout.addWidget(self.sourceTreeWidget, 0, 0, 1, 1)
        self.sourceTextEdit = QTextEdit(self.source)
        self.sourceTextEdit.setReadOnly(True)
        self.gridlayout.addWidget(self.sourceTextEdit, 0, 1, 1, 1)
        self.tabWidget.addTab(self.source, " ? ")

        self.result = QWidget()
        self.vlayout = QVBoxLayout(self.result)
        self.globalStatGroupBox = QGroupBox(self.result)
        self.hboxlayout = QHBoxLayout(self.globalStatGroupBox)
        self.totalTimeLcdNumber = QLCDNumber(self.globalStatGroupBox)
        self.totalTimeLcdNumber.setSegmentStyle(QLCDNumber.Filled)
        self.totalTimeLcdNumber.setNumDigits(7)
        self.totalTimeLcdNumber.display(1000000)
        self.totalTimeLcdNumber.setFrameShape(QFrame.StyledPanel)
        self.totalTimeLcdNumber.setSizePolicy(QSizePolicy.Expanding,
                                              QSizePolicy.Expanding)
        self.hboxlayout.addWidget(self.totalTimeLcdNumber)
        self.tTimeLabel = QLabel("<b>Total Time (Sec)</b>",
                                 self.globalStatGroupBox)
        self.tTimeLabel.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.hboxlayout.addWidget(self.tTimeLabel)
        self.numCallLcdNumber = QLCDNumber(self.globalStatGroupBox)
        self.numCallLcdNumber.setNumDigits(7)
        self.numCallLcdNumber.display(1000000)
        self.numCallLcdNumber.setSegmentStyle(QLCDNumber.Filled)
        self.numCallLcdNumber.setFrameShape(QFrame.StyledPanel)
        self.numCallLcdNumber.setSizePolicy(QSizePolicy.Expanding,
                                            QSizePolicy.Expanding)
        self.hboxlayout.addWidget(self.numCallLcdNumber)
        self.numCallLabel = QLabel("<b>Number of calls</b>",
                                   self.globalStatGroupBox)
        self.numCallLabel.setSizePolicy(QSizePolicy.Minimum,
                                        QSizePolicy.Minimum)
        self.hboxlayout.addWidget(self.numCallLabel)
        self.primCallLcdNumber = QLCDNumber(self.globalStatGroupBox)
        self.primCallLcdNumber.setSegmentStyle(QLCDNumber.Filled)
        self.primCallLcdNumber.setFrameShape(QFrame.StyledPanel)
        self.primCallLcdNumber.setNumDigits(7)
        self.primCallLcdNumber.display(1000000)
        self.primCallLcdNumber.setSizePolicy(QSizePolicy.Expanding,
                                             QSizePolicy.Expanding)
        self.hboxlayout.addWidget(self.primCallLcdNumber)
        self.primCallLabel = QLabel("<b>Primitive calls (%)</b>",
                                    self.globalStatGroupBox)
        self.primCallLabel.setSizePolicy(QSizePolicy.Minimum,
                                         QSizePolicy.Minimum)
        self.hboxlayout.addWidget(self.primCallLabel)
        self.vlayout.addWidget(self.globalStatGroupBox)
        try:
            from PyKDE4.kdeui import KRatingWidget
            self.rating = KRatingWidget(self.globalStatGroupBox)
            self.rating.setToolTip('Profiling Performance Rating')
        except ImportError:
            pass
        self.tabWidget.addTab(self.result, " Get Results ! ")

        self.resgraph = QWidget()
        self.vlayout2 = QVBoxLayout(self.result)
        self.graphz = QGroupBox(self.resgraph)
        self.hboxlayout2 = QHBoxLayout(self.graphz)
        try:
            from PyKDE4.kdeui import KLed
            KLed(self.graphz)
        except ImportError:
            pass
        self.hboxlayout2.addWidget(
            QLabel('''
            Work in Progress  :)  Not Ready Yet'''))
        self.vlayout2.addWidget(self.graphz)
        self.tabWidget.addTab(self.resgraph, " Graphs and Charts ")

        self.pathz = QWidget()
        self.vlayout3 = QVBoxLayout(self.pathz)
        self.patz = QGroupBox(self.pathz)
        self.hboxlayout3 = QVBoxLayout(self.patz)
        self.profilepath = QLineEdit(profilerPath)
        self.getprofile = QPushButton(QIcon.fromTheme("document-open"), 'Open')
        self.getprofile.setToolTip(
            'Dont touch if you dont know what are doing')
        self.getprofile.clicked.connect(lambda: self.profilepath.setText(
            str(
                QFileDialog.getOpenFileName(
                    self.patz, ' Open the profile.py file ',
                    path.expanduser("~"), ';;(profile.py)'))))
        self.hboxlayout3.addWidget(
            QLabel(
                '<center><b>Profile.py Python Library Full Path:</b></center>')
        )
        self.hboxlayout3.addWidget(self.profilepath)
        self.hboxlayout3.addWidget(self.getprofile)

        self.argGroupBox = QGroupBox(self.pathz)
        self.hbxlayout = QHBoxLayout(self.argGroupBox)
        self.argLineEdit = QLineEdit(self.argGroupBox)
        self.argLineEdit.setToolTip(
            'Not touch if you dont know what are doing')
        self.argLineEdit.setPlaceholderText(
            'Dont touch if you dont know what are doing')
        self.hbxlayout.addWidget(
            QLabel('<b>Additional Profile Arguments:</b>'))
        self.hbxlayout.addWidget(self.argLineEdit)
        self.hboxlayout3.addWidget(self.argGroupBox)

        self.vlayout3.addWidget(self.patz)
        self.tabWidget.addTab(self.pathz, " Paths and Configs ")

        self.outp = QWidget()
        self.vlayout4 = QVBoxLayout(self.outp)
        self.outgro = QGroupBox(self.outp)
        self.outgro.setTitle(" MultiProcessing Output Logs ")
        self.hboxlayout4 = QVBoxLayout(self.outgro)
        self.outputlog = QTextEdit()
        self.outputlog.setText('''
        I do not fear computers, I fear the lack of them.   -Isaac Asimov ''')
        self.hboxlayout4.addWidget(self.outputlog)
        self.vlayout4.addWidget(self.outgro)
        self.tabWidget.addTab(self.outp, " Logs ")

        self.actionNew_profiling = QAction(QIcon.fromTheme("document-new"),
                                           'New Profiling', self)
        self.actionLoad_profile = QAction(QIcon.fromTheme("document-open"),
                                          'Open Profiling', self)
        self.actionClean = QAction(QIcon.fromTheme("edit-clear"), 'Clean',
                                   self)
        self.actionClean.triggered.connect(lambda: self.clearContent)
        self.actionAbout = QAction(QIcon.fromTheme("help-about"), 'About',
                                   self)
        self.actionAbout.triggered.connect(lambda: QMessageBox.about(
            self.dock, __doc__, ', '.join(
                (__doc__, __license__, __author__, __email__))))
        self.actionSave_profile = QAction(QIcon.fromTheme("document-save"),
                                          'Save Profiling', self)
        self.actionManual = QAction(QIcon.fromTheme("help-contents"), 'Help',
                                    self)
        self.actionManual.triggered.connect(lambda: open_new_tab(
            'http://docs.python.org/library/profile.html'))

        self.tabWidget.setCurrentIndex(2)

        self.globalStatGroupBox.setTitle("Global Statistics")
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText("Number of Calls")
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText("Total Time")
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText("Per Call")
        item = self.tableWidget.horizontalHeaderItem(3)
        item.setText("Cumulative Time")
        item = self.tableWidget.horizontalHeaderItem(4)
        item.setText("Per Call")
        item = self.tableWidget.horizontalHeaderItem(5)
        item.setText("Filename")
        item = self.tableWidget.horizontalHeaderItem(6)
        item.setText("Line")
        item = self.tableWidget.horizontalHeaderItem(7)
        item.setText("Function")
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.stat),
                                  "Statistics per Function")

        self.sourceTreeWidget.headerItem().setText(0, "Source files")
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.source),
                                  "Sources Navigator")
        #######################################################################

        self.scrollable, self.dock = QScrollArea(), QDockWidget()
        self.scrollable.setWidgetResizable(True)
        self.scrollable.setWidget(self.tabWidget)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.dock.setWidget(self.scrollable)
        QToolBar(self.dock).addActions(
            (self.actionNew_profiling, self.actionClean,
             self.actionSave_profile, self.actionLoad_profile,
             self.actionManual, self.actionAbout))

        self.actionNew_profiling.triggered.connect(
            self.on_actionNew_profiling_triggered)
        self.actionLoad_profile.triggered.connect(
            self.on_actionLoad_profile_triggered)
        self.actionSave_profile.triggered.connect(
            self.on_actionSave_profile_triggered)

        self.locator.get_service('misc').add_widget(
            self.dock, QIcon.fromTheme("document-open-recent"), __doc__)

        if QSCI:
            # Scintilla source editor management
            self.scintillaWarningLabel.setText(' QScintilla is Ready ! ')
            layout = self.source.layout()
            layout.removeWidget(self.sourceTextEdit)
            self.sourceTextEdit = Qsci.QsciScintilla(self.source)
            layout.addWidget(self.sourceTextEdit, 0, 1)
            doc = self.sourceTextEdit
            doc.setLexer(Qsci.QsciLexerPython(self.sourceTextEdit))
            doc.setReadOnly(True)
            doc.setEdgeMode(Qsci.QsciScintilla.EdgeLine)
            doc.setEdgeColumn(80)
            doc.setEdgeColor(QColor("#FF0000"))
            doc.setFolding(Qsci.QsciScintilla.BoxedTreeFoldStyle)
            doc.setBraceMatching(Qsci.QsciScintilla.SloppyBraceMatch)
            doc.setCaretLineVisible(True)
            doc.setMarginLineNumbers(1, True)
            doc.setMarginWidth(1, 25)
            doc.setTabWidth(4)
            doc.setEolMode(Qsci.QsciScintilla.EolUnix)
            self.marker = {}
            for color in COLORS:
                mnr = doc.markerDefine(Qsci.QsciScintilla.Background)
                doc.setMarkerBackgroundColor(color, mnr)
                self.marker[color] = mnr
        self.currentSourcePath = None

        # Connect table and tree filter edit signal to unique slot
        self.filterTableLineEdit.textEdited.connect(
            self.on_filterLineEdit_textEdited)

        # Timer to display filter hint message
        self.filterHintTimer = QTimer(self)
        self.filterHintTimer.setSingleShot(True)
        self.filterHintTimer.timeout.connect(self.on_filterHintTimer_timeout)

        # Timer to start search
        self.filterSearchTimer = QTimer(self)
        self.filterSearchTimer.setSingleShot(True)
        self.filterSearchTimer.timeout.connect(
            self.on_filterSearchTimer_timeout)

        self.tabLoaded = {}
        for i in range(10):
            self.tabLoaded[i] = False
        self.backgroundTreeMatchedItems = {}
        self.resizeWidgetToContent(self.tableWidget)

    def on_actionNew_profiling_triggered(self):
        self.clearContent()
        self.scriptPath = str(
            QFileDialog.getOpenFileName(self.dock,
                                        "Choose your script to profile",
                                        path.expanduser("~"),
                                        "Python (*.py *.pyw)"))
        commandLine = [
            self.profilerPath, "-o", self.tempPath, self.scriptPath
        ] + self.scriptArgs
        commandLine = " ".join(commandLine)
        ##if self.termCheckBox.checkState() == Qt.Checked:
        #termList = ["xterm", "aterm"]
        #for term in termList:
        #termPath = which(term)
        #if termPath:
        #break
        #commandLine = """%s -e "%s ; echo 'Press ENTER Exit' ; read" """ \
        #% (termPath, commandLine)
        self.process.start(commandLine)
        if not self.process.waitForStarted():
            print((" ERROR: {} failed!".format(commandLine)))
            return

    def on_process_finished(self, exitStatus):
        ' whan the process end '
        print((" INFO: OK: QProcess is %s" % self.process.exitCode()))
        self.output = self.process.readAll().data()
        if not self.output:
            self.output = " ERROR: FAIL: No output ! "
        self.outputlog.setText(self.output + str(self.process.exitCode()))
        if path.exists(self.tempPath):
            self.setStat(self.tempPath)
            remove(self.tempPath)
        else:
            self.outputlog.setText(" ERROR: QProcess FAIL: Profiling failed.")
        self.tabWidget.setCurrentIndex(2)

    def on_process_error(self, error):
        ' when the process fail, I hope you never see this '
        print(" ERROR: QProcess FAIL: Profiler Dead, wheres your God now ? ")
        if error == QProcess.FailedToStart:
            self.outputlog.setText(" ERROR: FAIL: Profiler execution failed ")
        elif error == QProcess.Crashed:
            self.outputlog.setText(" ERROR: FAIL: Profiler execution crashed ")
        else:
            self.outputlog.setText(" ERROR: FAIL: Profiler unknown error ")

    def on_actionLoad_profile_triggered(self):
        """Load a previous profile sessions"""
        statPath = str(
            QFileDialog.getOpenFileName(self.dock, "Open profile dump",
                                        path.expanduser("~"),
                                        "Profile file (*)"))
        if statPath:
            self.clearContent()
            print(' INFO: OK: Loading profiling from ' + statPath)
            self.setStat(statPath)

    def on_actionSave_profile_triggered(self):
        """Save a profile sessions"""
        statPath = str(
            QFileDialog.getSaveFileName(self.dock, "Save profile dump",
                                        path.expanduser("~"),
                                        "Profile file (*)"))
        if statPath:
            #TODO: handle error case and give feelback to user
            print(' INFO: OK: Saving profiling to ' + statPath)
            self.stat.save(statPath)

    #=======================================================================#
    # Common parts                                                          #
    #=======================================================================#

    def on_tabWidget_currentChanged(self, index):
        """slot for tab change"""
        # Kill search and hint timer if running to avoid cross effect
        for timer in (self.filterHintTimer, self.filterSearchTimer):
            if timer.isActive():
                timer.stop()
        if not self.stat:
            #No stat loaded, nothing to do
            return
        self.populateTable()
        self.populateSource()

    def on_filterLineEdit_textEdited(self, text):
        """slot for filter change (table or tree"""
        if self.filterSearchTimer.isActive():
            # Already runnning, stop it
            self.filterSearchTimer.stop()
        # Start timer
        self.filterSearchTimer.start(300)

    def on_filterHintTimer_timeout(self):
        """Timeout to warn user about text length"""
        print("timeout")
        tab = self.tabWidget.currentIndex()
        if tab == TAB_FUNCTIONSTAT:
            label = self.filterHintTableLabel
        label.setText("Type > 2 characters to search")

    def on_filterSearchTimer_timeout(self):
        """timeout to start search"""
        tab = self.tabWidget.currentIndex()
        if tab == TAB_FUNCTIONSTAT:
            text = self.filterTableLineEdit.text()
            label = self.filterHintTableLabel
            edit = self.filterTableLineEdit
            widget = self.tableWidget
        else:
            print("Unknow tab for filterSearch timeout !")

        print(("do search for %s" % text))
        if not len(text):
            # Empty keyword, just clean all
            if self.filterHintTimer.isActive():
                self.filterHintTimer.stop()
            label.setText(" ? ")
            self.warnUSer(True, edit)
            self.clearSearch()
            return
        if len(text) < 2:
            # Don't filter if text is too short and tell it to user
            self.filterHintTimer.start(600)
            return
        else:
            if self.filterHintTimer.isActive():
                self.filterHintTimer.stop()
            label.setText(" ? ")

        # Search
        self.clearSearch()
        matchedItems = []
        if tab == TAB_FUNCTIONSTAT:
            # Find items
            matchedItems = widget.findItems(text, Qt.MatchContains)
            widget.setSortingEnabled(False)
            matchedRows = [item.row() for item in matchedItems]
            # Hide matched items
            header = widget.verticalHeader()
            for row in range(widget.rowCount()):
                if row not in matchedRows:
                    header.hideSection(row)
            widget.setSortingEnabled(True)
        else:
            print(" Unknow tab for filterSearch timeout ! ")

        print(("got %s members" % len(matchedItems)))
        self.warnUSer(matchedItems, edit)
        self.resizeWidgetToContent(widget)

    def resizeWidgetToContent(self, widget):
        """Resize all columns according to content"""
        for i in range(widget.columnCount()):
            widget.resizeColumnToContents(i)

    def clearSearch(self):
        """Clean search result
        For table, show all items
        For tree, remove colored items"""
        tab = self.tabWidget.currentIndex()
        if tab == TAB_FUNCTIONSTAT:
            header = self.tableWidget.verticalHeader()
            if header.hiddenSectionCount():
                for i in range(header.count()):
                    if header.isSectionHidden(i):
                        header.showSection(i)

    def clearContent(self):
        # Clear tabs
        self.tableWidget.clearContents()
        self.sourceTreeWidget.clear()
        # Reset LCD numbers
        for lcdNumber in (self.totalTimeLcdNumber, self.numCallLcdNumber,
                          self.primCallLcdNumber):
            lcdNumber.display(1000000)
        # Reset stat
        self.pstat = None
        # Disable save as menu
        self.actionSave_profile.setEnabled(False)
        # Mark all tabs as unloaded
        for i in range(10):
            self.tabLoaded[i] = False

    def warnUSer(self, result, inputWidget):
        palette = inputWidget.palette()
        if result:
            palette.setColor(QPalette.Normal, QPalette.Base,
                             QColor(255, 255, 255))
        else:
            palette.setColor(QPalette.Normal, QPalette.Base,
                             QColor(255, 136, 138))
        inputWidget.setPalette(palette)
        inputWidget.update()

    def setStat(self, statPath):
        self.stat = Stat(path=statPath)
        # Global stat update
        self.totalTimeLcdNumber.display(self.stat.getTotalTime())
        self.numCallLcdNumber.display(self.stat.getCallNumber())
        self.primCallLcdNumber.display(self.stat.getPrimitiveCallRatio())
        # Refresh current tab
        self.on_tabWidget_currentChanged(self.tabWidget.currentIndex())
        # Activate save as menu
        self.actionSave_profile.setEnabled(True)
        try:
            self.rating.setMaxRating(10)
            self.rating.setRating(
                int(self.stat.getPrimitiveCallRatio()) / 10 - 1)
        except:
            pass

    #========================================================================#
    # Statistics table                                                      #
    #=======================================================================#

    def populateTable(self):
        row = 0
        rowCount = self.stat.getStatNumber()
        progress = QProgressDialog("Populating statistics table...", "Abort",
                                   0, 2 * rowCount)
        self.tableWidget.setSortingEnabled(False)
        self.tableWidget.setRowCount(rowCount)

        progress.setWindowModality(Qt.WindowModal)
        for (key, value) in self.stat.getStatItems():
            #ncalls
            item = StatTableWidgetItem(str(value[0]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_NCALLS, item)
            colorTableItem(item, self.stat.getCallNumber(), value[0])
            #total time
            item = StatTableWidgetItem(str(value[2]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_TTIME, item)
            colorTableItem(item, self.stat.getTotalTime(), value[2])
            #per call (total time)
            if value[0] != 0:
                tPerCall = str(value[2] / value[0])
                cPerCall = str(value[3] / value[0])
            else:
                tPerCall = ""
                cPerCall = ""
            item = StatTableWidgetItem(tPerCall)
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_TPERCALL, item)
            colorTableItem(
                item,
                100.0 * self.stat.getTotalTime() / self.stat.getCallNumber(),
                tPerCall)
            #per call (cumulative time)
            item = StatTableWidgetItem(cPerCall)
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_CPERCALL, item)
            colorTableItem(
                item,
                100.0 * self.stat.getTotalTime() / self.stat.getCallNumber(),
                cPerCall)
            #cumulative time
            item = StatTableWidgetItem(str(value[3]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_CTIME, item)
            colorTableItem(item, self.stat.getTotalTime(), value[3])
            #Filename
            self.tableWidget.setItem(row, STAT_FILENAME,
                                     StatTableWidgetItem(str(key[0])))
            #Line
            item = StatTableWidgetItem(str(key[1]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_LINE, item)
            #Function name
            self.tableWidget.setItem(row, STAT_FUNCTION,
                                     StatTableWidgetItem(str(key[2])))
            row += 1
            # Store it in stat hash array
            self.stat.setStatLink(item, key, TAB_FUNCTIONSTAT)
            progress.setValue(row)
            if progress.wasCanceled():
                return

        for i in range(self.tableWidget.rowCount()):
            progress.setValue(row + i)
            for j in range(self.tableWidget.columnCount()):
                item = self.tableWidget.item(i, j)
                if item:
                    item.setFlags(Qt.ItemIsEnabled)

        self.tableWidget.setSortingEnabled(True)
        self.resizeWidgetToContent(self.tableWidget)
        progress.setValue(2 * rowCount)

    def on_tableWidget_itemDoubleClicked(self, item):
        matchedItems = []
        filename = str(self.tableWidget.item(item.row(), STAT_FILENAME).text())
        if not filename or filename.startswith("<"):
            # No source code associated, return immediatly
            return
        function = self.tableWidget.item(item.row(), STAT_FUNCTION).text()
        line = self.tableWidget.item(item.row(), STAT_LINE).text()

        self.on_tabWidget_currentChanged(TAB_SOURCE)  # load source tab
        function = "%s (%s)" % (function, line)
        fathers = self.sourceTreeWidget.findItems(filename, Qt.MatchContains,
                                                  SOURCE_FILENAME)
        print(("find %s father" % len(fathers)))
        for father in fathers:
            findItems(father, function, SOURCE_FILENAME, matchedItems)
        print(("find %s items" % len(matchedItems)))

        if matchedItems:
            self.tabWidget.setCurrentIndex(TAB_SOURCE)
            self.sourceTreeWidget.scrollToItem(matchedItems[0])
            self.on_sourceTreeWidget_itemClicked(matchedItems[0],
                                                 SOURCE_FILENAME)
            matchedItems[0].setSelected(True)
        else:
            print("oups, item found but cannot scroll to it !")

    #=======================================================================#
    # Source explorer                                                      #
    #=====================================================================#

    def populateSource(self):
        items = {}
        for stat in self.stat.getStatKeys():
            source = stat[0]
            function = "%s (%s)" % (stat[2], stat[1])
            if source in ("", "profile") or source.startswith("<"):
                continue
            # Create the function child
            child = QTreeWidgetItem([function])
            # Store it in stat hash array
            self.stat.setStatLink(child, stat, TAB_SOURCE)
            if source in items:
                father = items[source]
            else:
                # Create the father
                father = QTreeWidgetItem([source])
                items[source] = father
            father.addChild(child)
        self.sourceTreeWidget.setSortingEnabled(False)
        for value in list(items.values()):
            self.sourceTreeWidget.addTopLevelItem(value)
        self.sourceTreeWidget.setSortingEnabled(True)

    def on_sourceTreeWidget_itemActivated(self, item, column):
        self.on_sourceTreeWidget_itemClicked(item, column)

    def on_sourceTreeWidget_itemClicked(self, item, column):
        line = 0
        parent = item.parent()
        if QSCI:
            doc = self.sourceTextEdit
        if parent:
            pathz = parent.text(column)
            result = match("(.*) \(([0-9]+)\)", item.text(column))
            if result:
                try:
                    function = str(result.group(1))
                    line = int(result.group(2))
                except ValueError:
                    # We got garbage... falling back to line 0
                    pass
        else:
            pathz = item.text(column)
        pathz = path.abspath(str(pathz))
        if self.currentSourcePath != pathz:
            # Need to load source
            self.currentSourcePath == pathz
            try:
                if QSCI:
                    doc.clear()
                    doc.insert(file(pathz).read())
                else:
                    self.sourceTextEdit.setPlainText(file(pathz).read())
            except IOError:
                QMessageBox.warning(self, "Error",
                                    "Source file could not be found",
                                    QMessageBox.Ok)
                return

            if QSCI:
                for function, line in [(i[2], i[1])
                                       for i in self.stat.getStatKeys()
                                       if i[0] == pathz]:
                    # expr, regexp, case sensitive, whole word, wrap, forward
                    doc.findFirst("def", False, True, True, False, True, line,
                                  0, True)
                    end, foo = doc.getCursorPosition()
                    time = self.stat.getStatTotalTime((pathz, line, function))
                    colorSource(doc, self.stat.getTotalTime(), time, line, end,
                                self.marker)
        if QSCI:
            doc.ensureLineVisible(line)
Example #7
0
class ImportDataDlg(QDialog):
    __isJy = False  # 数据校验成功的标志
    __mlist = []  # 定义一个列表用于保存从excel表中取出的数据

    def __init__(self, iface, parent=None, impType=ImpDateType.SITEANDCELL):
        super(ImportDataDlg, self).__init__()
        self.iface = iface
        self.parent = parent
        self.impType = impType
        self.initView()

    def initView(self):
        if self.impType == ImpDateType.SERVINGCELL:
            self.setWindowTitle(u'相邻小区数据导入')
        else:
            self.setWindowTitle(u'基站和小区数据导入')
        self.setWindowIcon(QIcon('images/logo.png'))
        self.resize(620, 480)

        # 数据表格
        self.tableWidget = QTableWidget(self)
        self.tableWidget.setAlternatingRowColors(True)
        self.tableWidget.setRowCount(7)
        # 设置当前Table不能编辑
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 初始化表格上下文菜单
        self.initTableContextMenu()
        # 初始化表头
        self.initTableHeader()
        # 导入出错列表
        self.listWidget = QListWidget(self)
        # 按钮组
        impBtn = QPushButton(u"导入EXCEL表", self)
        yzBtn = QPushButton(u"数据检验", self)
        impdateBtn = QPushButton(u"导入数据", self)
        btnVBox = QVBoxLayout()
        btnVBox.addWidget(impBtn)
        btnVBox.addWidget(yzBtn)
        btnVBox.addWidget(impdateBtn)
        # 错误列表与按钮组
        hBox = QHBoxLayout()
        hBox.setMargin(20)
        hBox.addWidget(self.listWidget)
        hBox.addLayout(btnVBox)

        self.mbar = QStatusBar(self)
        self.mbar.showMessage(u'准备就绪...')

        self.maction = QToolBar(self)
        self.editAction = QAction(u'编辑', self.maction)
        self.editAction.setCheckable(True)

        self.combox = QComboBox(self)
        self.combox.addItems(HeadsConfig.ImpExcelName)

        self.maction.addWidget(self.combox)
        self.maction.addAction(self.editAction)

        vBox = QVBoxLayout()
        vBox.addWidget(self.maction)
        vBox.addWidget(self.tableWidget)
        vBox.addLayout(hBox)
        vBox.addWidget(self.mbar)

        vBox.setStretchFactor(self.tableWidget, 9)
        vBox.setStretchFactor(hBox, 5)
        vBox.setStretchFactor(self.mbar, 1)

        self.setLayout(vBox)

        QObject.connect(impBtn, SIGNAL('clicked()'), self.impClick)
        QObject.connect(yzBtn, SIGNAL('clicked()'), self.yzClick)
        QObject.connect(impdateBtn, SIGNAL('clicked()'), self.impdateClick)
        QObject.connect(self.editAction, SIGNAL('triggered()'), self.editClick)
        QObject.connect(self.combox, SIGNAL('currentIndexChanged(int)'),
                        self.comboxChange)

        self.listWidget.doubleClicked.connect(self.mlistClicked)
        # self.connect(self.listWidget, SIGNAL("itemDoubleClicked (QListWidgetItem)"), self.mlistClicked)

    def initTableContextMenu(self):
        self.tableWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.popMenu = QMenu(self.tableWidget)
        delAction = QAction(u'删除', self)  # 删除
        self.popMenu.addAction(delAction)

    # 设置表格可以双击修改数据
    def setEditTriggers(self, isTrigger):
        if isTrigger:
            self.tableWidget.setEditTriggers(QAbstractItemView.DoubleClicked)
        else:
            self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)

    # 提供给外部修改状态栏消息
    def setStatusBarMsg(self, msg):
        self.mbar.showMessage(msg)

    # 选框改变时,清空当前表格的全部内容,包括表格头
    def updateType(self, mtype):
        self.impType = mtype
        self.tableWidget.clear()  # 清空表格所有内容
        self.initTableHeader()

    # 初始化表格的每个Item
    def initTable(self, mlist):
        self.tableWidget.setRowCount(len(mlist))
        for (i, v) in enumerate(mlist):
            for (j, item) in enumerate(v):
                if type(item) != str:
                    item = unicode(item)
                if item == None:
                    item = u""
                tabItem = QTableWidgetItem(item)
                tabItem.setTextAlignment(Qt.AlignCenter)
                self.tableWidget.setItem(i, j, tabItem)

    # 初始化错误信息列表
    def initListView(self, mlist):

        for iv in mlist:
            lisItm = QListWidgetItem(self.listWidget)
            lisItm.setTextColor(Qt.red)
            lisItm.setData(Qt.UserRole, iv)
            if isinstance(iv, basestring):
                # 如果错误信息是一行字符串
                lisItm.setText(iv)
            else:
                lisItm.setText(u'第' + unicode(str(iv['row'] + 1)) + u'行,第' +
                               unicode(str(iv['col'] + 1)) + u'列:' + iv['msg'])

    # 初始化Table的头
    def initTableHeader(self):
        self.heads = []
        if self.impType == ImpDateType.SITEANDCELL:
            # 获取当前项目图层的字段名
            cell_layer = getLayerByName(u"小区", self.iface)
            for head in HeadsConfig.SiteANDCellHead:
                self.heads.append(head)
            if len(cell_layer.pendingFields()) > 55:
                for (index, field) in enumerate(cell_layer.pendingFields()):
                    if index > 54:
                        field_name = field.name().strip()
                        self.heads.append(field_name)

        else:
            self.heads = HeadsConfig.ServingCellHead

        self.tableWidget.setColumnCount(len(self.heads))  # 设置表格的列数
        for (i, h) in enumerate(self.heads):
            tabItem = QTableWidgetItem(h)
            self.tableWidget.setHorizontalHeaderItem(i, tabItem)

    # 自定义为Table添加Item
    def addTableItem(self, row, col, content):
        tabItem = QTableWidgetItem(content)
        self.tableWidget.setItem(row, col, tabItem)

    # 修改Item的内容
    def editTableItem(self, row, col, content):
        tabItem = self.tableWidget.item(row, col)
        tabItem.setText(content)
        self.tableWidget.setItem(row, col, tabItem)

    # 从Excel表读取数据(导入Excel表)
    def impClick(self):
        fileName = QFileDialog.getOpenFileName(self, u'基站小区数据导入', '/',
                                               'Excel Files (*.xls *.xlsx)')
        if fileName.strip() != "":
            self.setStatusBarMsg(u'选择完毕:' + fileName)
            importData = GetDataFromExcel(fileName, self.impType, self.heads)
            self.__mlist = []
            self.__mlist.extend(importData.getData())
            self.tableWidget.clearContents()
            self.listWidget.clear()
            self.initTable(self.__mlist)
            self.setStatusBarMsg(u'数据导入完成...')
            self.__isJy = False  # 导入完数据后,说明需要重新验证数据的正确性

        else:
            QMessageBox.information(self.parent, u"错误", u"请选中文件")

    # 数据验证按钮点击事件处理
    def yzClick(self):
        if len(self.__mlist) > 0:
            self.erlist = []  # 定义一个列表用于保存数据验证错误的数据
            # 清楚全部的Item
            if self.listWidget.count() > 0:
                self.listWidget.clear()

            # 根据tableWidget更新self.__mlist
            for (r, items) in enumerate(self.__mlist):
                for (v, item) in enumerate(self.__mlist[r]):
                    if self.tableWidget.item(r, v).text() == u"":
                        continue
                    else:
                        # 跟据self.__mlist[r][v]数据类型进行比对
                        if type(self.__mlist[r][v]) == int:
                            if unicode(self.__mlist[r][v]) != (
                                    self.tableWidget.item(r, v).text()):
                                self.__mlist[r][v] = int(
                                    self.tableWidget.item(r, v).text())
                        elif type(self.__mlist[r][v]) == float:
                            if unicode(self.__mlist[r][v]) != (
                                    self.tableWidget.item(r, v).text()):
                                self.__mlist[r][v] = float(
                                    self.tableWidget.item(r, v).text())
                        elif type(self.__mlist[r][v]) == str:
                            if unicode(self.__mlist[r][v]
                                       ) != self.tableWidget.item(r, v).text():
                                self.__mlist[r][v] = str(
                                    self.tableWidget.item(r, v).text())
                        elif type(self.__mlist[r][v]) == unicode:
                            if (self.__mlist[r][v]) != self.tableWidget.item(
                                    r, v).text():
                                self.__mlist[r][v] = self.tableWidget.item(
                                    r, v).text()
                        else:
                            print type(self.__mlist[r][v])
            # 执行数据校验函数
            self.erlist = checkDataByDataType(self.__mlist, self.impType)
            if len(self.erlist) > 0:
                self.initListView(self.erlist)
                QMessageBox.information(self.parent, u'数据校验',
                                        u'数据校验失败,请检查数据正确性后,再导入到地图中')
                self.__isJy = False
            else:
                QMessageBox.information(self.parent, u'数据校验', u'数据校验成功,没有错误数据')
                self.__isJy = True
        else:
            QMessageBox.warning(self.parent, u'数据校验', u'请先导入Excel数据后再操作!')

    # 导入数据到地图中
    def impdateClick(self):
        if self.__isJy:  # 如果数据校验成功
            if self.impType == ImpDateType.SITEANDCELL:
                # 导入基站小区
                importDataToLayer = ImportDataToLayer(self.iface, self.__mlist,
                                                      self.parent)
                if importDataToLayer.importSiteAndCellData():
                    QMessageBox.information(self.parent, u"导入数据", u"导入数据成功!")
                else:
                    QMessageBox.critical(self.parent, u"导入数据", u"导入数据失败!")

            else:
                # 导入相邻小区
                importDataToLayer = ImportDataToLayer(self.iface, self.__mlist,
                                                      self.parent)
                if importDataToLayer.importSCellData():
                    QMessageBox.information(self.parent, u"导入数据", u"导入数据成功!")
                else:
                    QMessageBox.critical(self.parent, u"导入数据", u"导入数据失败!")
        else:
            QMessageBox.warning(self.parent, u'数据导入', u'请确保校验数据成功后,再导入到地图中')

    # 编辑Action点击事件
    def editClick(self):
        self.setEditTriggers(self.editAction.isChecked())

    # 错误列表双击事件处理
    def mlistClicked(self, listItem):
        itemData = listItem.data(Qt.UserRole)
        self.tableWidget.setFocus()
        self.tableWidget.setCurrentCell(itemData['row'], itemData['col'])

    # 选框改变事件
    def comboxChange(self, index):
        self.updateType(index)

    # 字段验证是否为空
    def __validNull(self, name, col, row, itm, rowitm):
        if itm is None or itm == '':
            tmpMap = {}
            tmpMap['col'] = col
            tmpMap['row'] = row
            tmpMap['msg'] = unicode(name) + u'不能为空'
            tmpMap['item'] = rowitm
            return tmpMap
        else:
            return None

    # 导入数据线程开始信号  绑定函数
    def impStart(self):
        self.setStatusBarMsg(u'准备导入...')

    # 导入数据线程发生异常信号 绑定函数
    def impError(self, e, exception_string):
        self.setStatusBarMsg(u'发生错误:' + unicode(e))
        QMessageBox.warning(self.parent, u'Excel数据导入', u'发生错误:' + unicode(e))

    # 导入数据线程完成信号 绑定函数
    def impFinish(self, mylist):
        self.__mlist = []
        self.__mlist.extend(mylist)
        self.mthread.quit()
        self.mthread.wait()
        self.mthread.deleteLater()
        self.impDateThread.deleteLater()

        self.tableWidget.clearContents()
        self.listWidget.clear()
        self.initTable(self.__mlist)
        self.setStatusBarMsg(u'数据导入完成...')
        self.__isJy = False  # 导入完数据后,说明需要重新验证数据的正确性

    # 导入数据到地图线程发生异常信号 绑定函数
    def impError1(self, e, exception_string):
        self.setStatusBarMsg(u"导入数据发生错误")
        QMessageBox.critical(self, u'数据导入', u"发生错误:" + unicode(e))

    # 导入数据到地图线程完成信号 绑定函数
    def impFinish1(self, mylist):
        self.threadImp.quit()
        self.threadImp.wait()
        self.threadImp.deleteLater()
        self.impFeatureThread.deleteLater()
        remsg = u'数据导入完成!'
        layer = None
        if self.impType == LayerType.SITE:
            # remsg = u'基站' + remsg
            layer = getLayerByName(u'基站', self.iface)
        elif self.impType == LayerType.CELL:
            # remsg = u'小区' + remsg
            layer = getLayerByName(u'小区', self.iface)
        else:
            remsg = u'相邻小区' + remsg
            layer = getLayerByName(u'相邻小区', self.iface)
        self.setStatusBarMsg(remsg)
        layer.updateExtents()  # 更新地图数据
        self.iface.actionDraw().trigger()
        QMessageBox.information(self, u'数据导入', remsg)

        merlist = []
        for eritm in self.erlist:
            merlist.append(eritm['item'])
        self.tableWidget.clearContents()  # 先清楚表格的内容,再将错误的行显示到表格中
        self.initTable(merlist)
Example #8
0
 def process(self, node):
   for idx in xrange(0, self.tabs.count()):
     widget = self.tabs.widget(idx)
     del widget
   self.tabs.clear()
   self.node = node
   file = self.node.open()
   tags = EXIF.process_file(file)
   if len(tags) == 0:
     self.nometa.setSizePolicy(self.tabs.sizePolicy())
     self.tabs.hide()
     self.nometa.show()
   else:
     self.tabs.show()
     self.nometa.hide()
     sortedTags = {}
     for tag in tags.keys():
       if tag not in ('JPEGThumbnail', 'TIFFThumbnail', 'Filename', 'EXIF MakerNote'):
         spaceidx = tag.find(" ")
         ifd = tag[:spaceidx].strip()
         if ifd == "Image":
           ifd = "IFD 0 (Image)"
         if ifd == "Thumbnail":
           ifd = "IFD 1 (Thumbnail)"
         key = tag[spaceidx:].strip()
         try:
           val = str(tags[tag])
         except:
           val = "cannot be decoded"
         if ifd not in sortedTags.keys():
           sortedTags[ifd] = []
         sortedTags[ifd].append((key, val))
     for ifd in sortedTags.keys():
       table = QTableWidget(len(sortedTags[ifd]), 2)
       table.setShowGrid(False)
       table.setAlternatingRowColors(True)
       table.verticalHeader().hide()
       table.horizontalHeader().setClickable(False)
       table.horizontalHeader().setStretchLastSection(True)
       table.setHorizontalHeaderLabels(["Tag", "Value"])
       table.setSelectionBehavior(QAbstractItemView.SelectRows)
       self.tabs.addTab(table, ifd)
       row = 0
       for res in sortedTags[ifd]:
         key = QTableWidgetItem(res[0])
         key.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled)
         val = QTableWidgetItem(res[1])
         val.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled)
         table.setItem(row, 0, key)
         table.setItem(row, 1, val)
         row += 1
     if 'JPEGThumbnail' in tags.keys():
       label = QLabel()
       img = QImage()
       img.loadFromData(tags['JPEGThumbnail'])
       label.setPixmap(QPixmap.fromImage(img))
       label.setAlignment(Qt.AlignCenter)
       self.tabs.addTab(label, "Embedded Thumbnail")
     if 'TIFFThumbnail' in tags.keys():
       label = QLabel()
       img = QImage()
       img.loadFromData(tags['TIFFThumbnail'])
       label.setPixmap(QPixmap.fromImage(img))
       label.setAlignment(Qt.AlignCenter)
       self.tabs.addTab(label, "Embedded Thumbnail")
     file.close()	
class AvailableWidget(QWidget):

    def __init__(self, parent, available):
        QWidget.__init__(self, parent)
        self._parent = parent
        self._available = available
        vbox = QVBoxLayout(self)
        self._table = QTableWidget(1, 2)
        self._table.setSelectionMode(QTableWidget.SingleSelection)
        self._table.removeRow(0)
        vbox.addWidget(self._table)
        ui_tools.load_table(self._table, (self.tr('Name'), self.tr('Version')),
            _format_for_table(available))
        self._table.setColumnWidth(0, 500)
        self._table.setSortingEnabled(True)
        self._table.setAlternatingRowColors(True)
        hbox = QHBoxLayout()
        btnInstall = QPushButton(self.tr('Install'))
        btnInstall.setMaximumWidth(100)
        hbox.addWidget(btnInstall)
        hbox.addWidget(QLabel(self.tr("NINJA needs to be restarted for "
            "changes to take effect.")))
        vbox.addLayout(hbox)

        self.connect(btnInstall, SIGNAL("clicked()"), self._install_plugins)
        self.connect(self._table, SIGNAL("itemSelectionChanged()"),
            self._show_item_description)

    def _show_item_description(self):
        item = self._table.currentItem()
        if item is not None:
            data = list(item.data(Qt.UserRole))
            self._parent.show_plugin_info(data)

    def _install_plugins(self):
        data = _format_for_table(self._available)
        plugins = ui_tools.remove_get_selected_items(self._table, data)
        #get the download link of each plugin
        for p_row in plugins:
            #search the plugin
            for p_dict in self._available:
                if p_dict["name"] == p_row[0]:
                    p_data = p_dict
                    break
            #append the downlod link
            p_row.append(p_data["download"])
        #download
        self._parent.download_plugins(plugins)

    def remove_item(self, plugin_name):
        plugin = _get_plugin(plugin_name, self._available)
        self._available.remove(plugin)

    def _install_external(self):
        if self._link.text().isEmpty():
            QMessageBox.information(self, self.tr("External Plugins"),
                self.tr("URL from Plugin missing..."))
            return
        plug = [
            file_manager.get_module_name(str(self._link.text())),
            'External Plugin',
            '1.0',
            str(self._link.text())]
        self.parent().download_plugins(plug)
        self._link.setText('')

    def add_table_items(self, plugs):
        self._available += plugs
        data = _format_for_table(self._available)
        ui_tools.load_table(self._table, (self.tr('Name'), self.tr('Version')),
            data)
Example #10
0
class ElemCompDialog(QtGui.QDialog):

    def __init__(self,mz, mass,xp,parent=None):
        QtGui.QDialog.__init__(self, parent)
        settings = QSettings()
        size = settings.value("MainWindow/Size",QVariant(QSize(1024,650))).toSize()
        self.resize(size)

        self.setWindowTitle('Elenmental Composition')
        self.xp=xp
        self.mass=mass
        self.mz=mz
        print mz
        self.initControls()
#        self.initPlots()
    def initControls(self):
        self.plot1 = Qwt.QwtPlot(self)
        self.plot1.setCanvasBackground(Qt.white)
        self.plot2 = Qwt.QwtPlot(self)
        self.plot2.setCanvasBackground(Qt.white)
        self.list = QTreeWidget()
        self.list.setColumnCount(11)
        self.list.setColumnWidth(0,80)
        self.list.setColumnWidth(1,80)
        self.list.setColumnWidth(2,60)
        self.list.setColumnWidth(3,60)
        self.list.setColumnWidth(4,60)
        self.list.setColumnWidth(5,150)
        self.list.setColumnWidth(7,30)
        self.list.setColumnWidth(8,30)
        self.list.setColumnWidth(9,30)
        self.list.setColumnWidth(10,30)
        self.list.setHeaderLabels(['Mass','Calc.Mass','mDa','PPM','DBE','Formula','Fit Conf %','C','H','N','O'])
        self.list.setSortingEnabled(True)
        
        self.table = QTableWidget(1,11)
        self.table.setColumnWidth(0,80)
        self.table.setColumnWidth(1,80)
        self.table.setColumnWidth(2,60)
        self.table.setColumnWidth(3,60)
        self.table.setColumnWidth(4,60)
        self.table.setColumnWidth(5,150)
        self.table.setColumnWidth(7,30)
        self.table.setColumnWidth(8,30)
        self.table.setColumnWidth(9,30)
        self.table.setColumnWidth(10,30)
        self.table.setHorizontalHeaderLabels(['Mass','Calc.Mass','mDa','PPM','DBE','Formula','Fit Conf %','C','H','N','O'])
        self.table.setEditTriggers(QTableWidget.NoEditTriggers)  
        self.table.setSelectionBehavior(QTableWidget.SelectRows)  
        self.table.setSelectionMode(QTableWidget.SingleSelection)  
        self.table.setAlternatingRowColors(True)
        print self.connect(self.table, SIGNAL("itemActivated(QTableWidgetItem*)"), self.tableClicked)
#        self.connect(self.library_list, SIGNAL("itemSelectionChanged()"), self.libraryListClicked)
        up_hbox=QVBoxLayout()
        up_hbox.addWidget(self.table)
        down_hbox = QVBoxLayout()
        down_hbox.addWidget(self.plot1)
        down_hbox.addWidget(self.plot2)
        hbox = QVBoxLayout()
        hbox.addLayout(up_hbox, 3.5)
        hbox.addLayout(down_hbox, 3.5)
        self.setLayout(hbox)
        self.cal_mass()
    def tableClicked(self,item):
        self.C=self.table.item(item.row(),7).text()
        self.H=self.table.item(item.row(),8).text()
        self.N=self.table.item(item.row(),9).text()
        self.O=self.table.item(item.row(),10).text()
        self.cal_isotopic()
        self.initPlots()
    def initPlots(self):
        self.plot1.clear()
#        self.plot1.setTitle("Observed Isotope Distribution")
#        self.plot1.setAxisTitle(Qwt.QwtPlot.xBottom, 'Raman shift (cm-1)')
#        self.plot1.setAxisTitle(Qwt.QwtPlot.yLeft, 'Intensity')
#        grid = Qwt.QwtPlotGrid()
        pen = QPen(Qt.DotLine)
        pen.setColor(Qt.black)
        pen.setWidth(0)
#        grid.setPen(pen)
#        grid.attach(self.plot1)
        self.mass1=self.mass/self.massy*100
        self.plot1.setAxisScale(self.plot1.xBottom,self.x_min,self.x_max)
        self.plot1.setAxisScale(self.plot1.yLeft,0,1.1*100)
        color = QColor('black')
        curve = Qwt.QwtPlotCurve("test1")
        pen = QPen(color)
        pen.setWidth(1)
        curve.setPen(pen)
        curve.setData(self.mass_x,self.mass_y)
        curve.setStyle(Qwt.QwtPlotCurve.Sticks)
        curve.attach(self.plot1)  
        self.plot1.replot()
        
        self.plot2.clear()
#        self.plot2.setTitle("Theoretical Isotope Distribution")
#        self.plot2.setAxisTitle(Qwt.QwtPlot.xBottom, 'Raman shift (cm-1)')
#        self.plot2.setAxisTitle(Qwt.QwtPlot.yLeft, 'Intensity')
#        grid = Qwt.QwtPlotGrid()
        pen = QPen(Qt.DotLine)
        pen.setColor(Qt.blue)
        
        self.plot2.setAxisScale(self.plot1.xBottom,self.x_min,self.x_max)
        self.plot2.setAxisScale(self.plot1.yLeft,0,1.1*100)
        color = QColor('blue')
        curve = Qwt.QwtPlotCurve("test1")
        pen = QPen(color)
        pen.setWidth(1)
        curve.setPen(pen)
#        self.axis= np.arange(len(self.mass))
        curve.setData(self.x,self.y)
        curve.setStyle(Qwt.QwtPlotCurve.Sticks)
        curve.attach(self.plot2)  
        pen.setWidth(0)
#        grid.setPen(pen)
#        grid.attach(self.plot2)
        self.plot2.replot()

    def cal_mass(self):
#        charge=0.0
        tol = 10.0
#        electron=0.000549
        measured_mass=np.round(self.xp)
        limit_lo = measured_mass - (tol/1000.0)
        limit_hi = measured_mass + (tol/1000.0)
        mass=[]
        mass.append((12.000000000,2.0,"C"))
        #mass.append((78.9183376,-1.0,"Br"))
        #mass.append((34.96885271,-1.0,"Cl"))
        #mass.append((31.97207069,0.0,"S"))
        #mass.append((30.97376151,1.0,"P"))
        #mass.append((27.9769265327,2.0,"Si"))
        #mass.append((22.98976967,-1.0,"Na"))
        #mass.append((18.99840320,-1.0,"F"))
        mass.append((15.9949146221,0.0,"O"))
        mass.append((14.0030740052,1.0,"N"))
        mass.append((1.0078250321,-1.0,"H"))
        print range(1,10)
        print mass[0][0]
        print mass[1][0]
        print mass[2][0]
        calc_mass=[]
        for i in range(1,int(floor(measured_mass/mass[0][0]))+1):
            for j in range(0,int(floor((measured_mass-mass[0][0]*i)/mass[1][0]))+1):
                for k in range(0,int(floor((measured_mass-mass[0][0]*i-mass[1][0]*j)/mass[2][0]))+1):
        #            rr=(measured_mass-mass[0][0]*i-mass[1][0]*j-mass[2][0]*k)/mass[3][0]
        #            rrr=round((measured_mass-mass[0][0]*i-mass[1][0]*j-mass[2][0]*k)/mass[3][0])
        #            rrrr=int(round((measured_mass-mass[0][0]*i-mass[1][0]*j-mass[2][0]*k)/mass[3][0]))
        #            print "rr:%s"%rr+" rrr:%s"%rrr+" rrrr:%s"%rrrr
                    r=int(round((measured_mass-mass[0][0]*i-mass[1][0]*j-mass[2][0]*k)/mass[3][0]))
                    calmass=mass[0][0]*i+mass[1][0]*j+mass[2][0]*k+mass[3][0]*r
                    if (mass[0][1]*i+mass[2][1]*k+mass[3][1]*r)>=-1 and calmass>limit_lo and calmass<limit_hi:
                        calc_mass.append((calmass,i,j,k,r))
        print len(calc_mass)
        for ii in range(0,len(calc_mass)):
            mda=(measured_mass-calc_mass[ii][0])*1000
            ppm=(measured_mass-calc_mass[ii][0])/measured_mass*1000000
            DBE=(calc_mass[ii][1]*2+calc_mass[ii][3]-calc_mass[ii][4]+2)/2.0
            self.calmass="%.4f"%calc_mass[ii][0]
            self.mda="%.1f"%mda
            self.ppm="%.1f"%ppm
            self.DBE="%.1f"%DBE
            self.C="%s"%calc_mass[ii][1]
            self.H="%s"%calc_mass[ii][4]
            self.N="%s"%calc_mass[ii][3]
            self.O="%s"%calc_mass[ii][2]
            self.Formula="C%2s"%self.C+" H%2s"%self.H+" N%2s"%self.N+" O%2s"%self.O
            mass=str(self.xp)
#            if not(ii==0):
#                mass=""
            self.cal_isotopic()
            self.initPlots()
            self.conf="%.1f"%self.mass_diff
            self.table.insertRow(ii)
            self.table.setRowHeight(ii,20)
            self.table.setItem(ii, 0,QTableWidgetItem(mass))  
            self.table.setItem(ii, 1,QTableWidgetItem(self.calmass))
            self.table.setItem(ii, 2,QTableWidgetItem(self.mda))
            self.table.setItem(ii, 3,QTableWidgetItem(self.ppm))
            self.table.setItem(ii, 4,QTableWidgetItem(self.DBE))
            self.table.setItem(ii, 5,QTableWidgetItem(self.Formula))
            self.table.setItem(ii, 6,QTableWidgetItem(self.conf))
            self.table.setItem(ii, 7,QTableWidgetItem(self.C))
            self.table.setItem(ii, 8,QTableWidgetItem(self.H))
            self.table.setItem(ii, 9,QTableWidgetItem(self.N))
            self.table.setItem(ii, 10,QTableWidgetItem(self.O))

            item=QTreeWidgetItem([mass,str(self.calmass),str(self.mda),str(self.ppm),str(self.DBE),self.Formula,str(self.conf),str(self.C),str(self.H),str(self.N),str(self.O)])
            self.list.addTopLevelItem(item)
        self.table.removeRow(len(calc_mass))
        self.table.setSortingEnabled(True)
       
#        self.table.sortByColumn(1,Qt.DescendingOrder)
    def next2pow(self):
        return 2**int(np.ceil(np.log(float(self.xx))/np.log(2.0)))
    def cal_isotopic(self):
        MAX_ELEMENTS=5+1  # add 1 due to mass correction 'element'
        MAX_ISOTOPES=4    # maxiumum # of isotopes for one element
        CUTOFF=1e-4       # relative intensity cutoff for plotting
        
        WINDOW_SIZE = 500
        #WINDOW_SIZE=input('Window size (in Da) ---> ');
        
        #RESOLUTION=input('Resolution (in Da) ----> ');  % mass unit used in vectors
        RESOLUTION = 1
        if RESOLUTION < 0.00001:#  % minimal mass step allowed
          RESOLUTION = 0.00001
        elif RESOLUTION > 0.5:  # maximal mass step allowed
          RESOLUTION = 0.5
        
        R=0.00001/RESOLUTION#  % R is used to scale nuclide masses (see below)
        
        WINDOW_SIZE=WINDOW_SIZE/RESOLUTION; 
        self.xx=WINDOW_SIZE  # convert window size to new mass units
        WINDOW_SIZE=self.next2pow();  # fast radix-2 fast-Fourier transform algorithm
        
        if WINDOW_SIZE < np.round(496708*R)+1:
          WINDOW_SIZE = self.next2pow(np.round(496708*R)+1)  # just to make sure window is big enough
        
        
        #H378 C254 N65 O75 S6
        M=np.array([int(self.H),int(self.C),int(self.N),int(self.O),0,0]) #% empiric formula, e.g. bovine insulin
        
        # isotopic abundances stored in matrix A (one row for each element)
        A=np.zeros((MAX_ELEMENTS,MAX_ISOTOPES,2));
        
        A[0][0,:] = [100783,0.9998443]#                 % 1H
        A[0][1,:] = [201410,0.0001557]#                 % 2H
        A[1][0,:] = [100000,0.98889]#                   % 12C
        A[1][1,:] = [200336,0.01111]#                   % 13C
        A[2][0,:] = [100307,0.99634]#                   % 14N
        A[2][1,:] = [200011,0.00366]#                   % 15N
        A[3][0,:] = [99492,0.997628]#                  % 16O
        A[3][1,:] = [199913,0.000372]#                  % 17O
        A[3][2,:] = [299916,0.002000]#                  % 18O
        A[4][0,:] = [97207,0.95018]#                   % 32S
        A[4][1,:] = [197146,0.00750]#                   % 33S
        A[4][2,:] = [296787,0.04215]#                   % 34S
        A[4][3,:] = [496708,0.00017]#                   % 36S
        A[5][0,:] = [100000,1.00000]#                   % for shifting mass so that Mmi is
        #                                             % near left limit of window
        
        Mmi=np.array([np.round(100783*R), np.round(100000*R),\
                     np.round(100307*R),np.round(99492*R), np.round(97207*R), 0])*M#  % (Virtual) monoisotopic mass in new units
        Mmi = Mmi.sum()
        #% mass shift so Mmi is in left limit of window:
        FOLDED=np.floor(Mmi/(WINDOW_SIZE-1))+1#  % folded FOLDED times (always one folding due to shift below)
        #% shift distribution to 1 Da from lower window limit:
        M[MAX_ELEMENTS-1]=np.ceil(((WINDOW_SIZE-1)-np.mod(Mmi,WINDOW_SIZE-1)+np.round(100000*R))*RESOLUTION)
        
        MASS_REMOVED=np.array([0,11,13,15,31,-1])*M#% correction for 'virtual' elements and mass shift
        begin=WINDOW_SIZE*RESOLUTION+MASS_REMOVED.sum()
        end=2*(WINDOW_SIZE-1)*RESOLUTION+MASS_REMOVED.sum()
        
        ptA=np.ones(WINDOW_SIZE);
        t_fft=0
        t_mult=0
        
        for i in xrange(MAX_ELEMENTS):
        
            tA=np.zeros(WINDOW_SIZE)
            for j in xrange(MAX_ISOTOPES):
                if A[i][j,0] != 0:
                    #removed +1 after R)+1 --we're using python
                    tA[np.round(A[i][j,0]*R)]=A[i][j,1]#;  % put isotopic distribution in tA
            t0 = time.clock()
            tA=F.fft(tA) # FFT along elements isotopic distribution  O(nlogn)
            t_fft = time.clock()-t0
            t0 = time.clock()
            tA=tA**M[i]#  % O(n)
            #################
            ptA = ptA*tA#  % O(n)#this is where it is messing UP
            #################
            t1 = time.clock()
            t_mult=t1-t0
        

        t0=time.clock()
        ptA=F.ifft(ptA).real#;  % O(nlogn)

        t0=time.clock()
        
        MA=np.linspace(begin,end,WINDOW_SIZE-1)
        ind=np.where(ptA>CUTOFF)[0]
        
        self.x = MA[ind]
        self.y = ptA[ind]
        self.x_min=int(np.min(self.x)-(np.max(self.x)-np.min(self.x)))
        self.x_max=int(np.min(self.x)+(np.max(self.x)-np.min(self.x)))
        
        self.mass_y=np.ones(len(self.x))
        mass_diff=np.ones(len(self.x))
        
        mzInd= np.logical_and((self.mz>=self.x_min),(self.mz<=self.x_max))
        self.mass_y=self.mass[mzInd]
        self.mass_x=self.mz[mzInd]
        
        
#         for i in range(len(self.x)):
#             self.mass_y[i]=self.mass[int(self.x[i])]
        self.massy=np.max(self.mass_y)
        print self.massy
        self.mass_y=self.mass_y/max(self.mass_y)*100
        self.y=self.y/max(self.y)*100
#        k=(self.mass_y*self.y).sum()/(self.mass_y*self.mass_y).sum()
#        self.fit=((k*self.mass_y-self.y)*(k*self.mass_y-self.y)).sum()/(self.y*self.y).sum()
        for i in range(len(self.y)):
            mass_diff[i]=np.abs(self.mass_y[i]-self.y[i])/(self.mass_y[i]+self.y[i])
        self.mass_diff=(1-mass_diff.sum()/len(mass_diff))*100
Example #11
0
class OWxsh_waviness(widget.OWWidget):
    name = "xsh_waviness"
    id = "orange.widgets.preprocessor.xsh_waviness"
    description = "xoppy application to compute..."
    icon = "icons/waviness.png"
    author = "Luca Rebuffi"
    maintainer_email = "[email protected]; [email protected]"
    priority = 10
    category = ""
    keywords = ["xoppy", "xsh_waviness"]

    outputs = [{"name": "PreProcessor_Data",
                "type": ShadowPreProcessorData,
                "doc": "PreProcessor Data",
                "id": "PreProcessor_Data"}]

    want_main_area = 1
    want_control_area = 1

    WIDGET_WIDTH = 1100
    WIDGET_HEIGHT = 650

    xx = None
    yy = None
    zz = None

    number_of_points_x = Setting(10)
    number_of_points_y = Setting(100)

    dimension_x = Setting(20.1)
    dimension_y = Setting(113.1)

    estimated_slope_error = Setting(0.9)
    montecarlo_seed = Setting(2387427)

    waviness_file_name = Setting('waviness.dat')

    harmonic_maximum_index = Setting(60)

    data = Setting({'c': ['0.3',
                          '0.1',
                          '0.1',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.3',
                          '0.0',
                          '0.0',
                          '0.3',
                          '0.0',
                          '0.0',
                          '0.5',
                          '0.0',
                          '0.0',
                          '0.2',
                          '0.2',
                          '0.2',
                          '0.9',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.4',
                          '0.0',
                          '0.0',
                          '0.4',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.6',
                          '0.6',
                          '0.0',
                          '0.4',
                          '0.4',
                          '0.0',
                          '0.4',
                          '0.4',
                          '0.1',
                          '0.4',
                          '0.4',
                          '0.1',
                          '0.2',
                          '0.2',
                          '0.0',
                          '0.2',
                          '0.2',
                          '0.0',
                          '0.3',
                          '0.3',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0'],
                    'y': ['0.0',
                          '-0.1',
                          '-0.1',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.03',
                          '0.0',
                          '0.0',
                          '0.2',
                          '0.0',
                          '0.0',
                          '0.2',
                          '0.0',
                          '0.0',
                          '0.1',
                          '0.1',
                          '0.1',
                          '0.1',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.01',
                          '0.0',
                          '0.0',
                          '0.03',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.02',
                          '0.02',
                          '0.0',
                          '0.1',
                          '0.1',
                          '0.0',
                          '0.1',
                          '0.1',
                          '0.0',
                          '0.1',
                          '0.1',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.3',
                          '0.3',
                          '0.0',
                          '0.2',
                          '0.2',
                          '0.0',
                          '0.2',
                          '0.2',
                          '0.0',
                          '0.2',
                          '0.2',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0'],
                    'g': ['0.0',
                          '0.3',
                          '0.3',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.05',
                          '0.0',
                          '0.0',
                          '0.05',
                          '0.0',
                          '0.0',
                          '0.1',
                          '0.0',
                          '0.0',
                          '0.05',
                          '0.05',
                          '0.05',
                          '0.2',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.1',
                          '0.0',
                          '0.0',
                          '0.1',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.2',
                          '0.2',
                          '0.0',
                          '0.1',
                          '0.1',
                          '0.0',
                          '0.1',
                          '0.1',
                          '0.0',
                          '0.1',
                          '0.1',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.1',
                          '0.1',
                          '0.0',
                          '0.2',
                          '0.2',
                          '0.0',
                          '0.1',
                          '0.1',
                          '0.0',
                          '0.1',
                          '0.1',
                          '0.0',
                          '0.0',
                          '0.0',
                          '0.0']})

    def __init__(self):
        super().__init__()

        geom = QApplication.desktop().availableGeometry()
        self.setGeometry(QRect(round(geom.width() * 0.05),
                               round(geom.height() * 0.05),
                               round(min(geom.width() * 0.98, self.WIDGET_WIDTH)),
                               round(min(geom.height() * 0.95, self.WIDGET_HEIGHT))))

        gen_box = ShadowGui.widgetBox(self.controlArea, "Waviness Parameters", addSpace=True, orientation="horizontal",
                                      width=500)

        tabs_setting = gui.tabWidget(gen_box)

        tab_input = ShadowGui.createTabPage(tabs_setting, "Input Parameter")
        tab_harmonics = ShadowGui.createTabPage(tabs_setting, "Harmonics")
        tab_out = ShadowGui.createTabPage(tabs_setting, "Output")

        self.input_box = ShadowGui.widgetBox(tab_input, "Inputs", addSpace=True, orientation="vertical", width=470)

        gui.button(self.input_box, self, "Load xsh_waviness input file ...", callback=self.load_inp_file)

        gui.separator(self.input_box)

        ShadowGui.lineEdit(self.input_box, self, "number_of_points_x", "Number of Points (<201)           X (width)",
                           labelWidth=300, valueType=int, orientation="horizontal")
        ShadowGui.lineEdit(self.input_box, self, "number_of_points_y",
                           "                                                 Y (length)", labelWidth=300, valueType=int,
                           orientation="horizontal")

        gui.separator(self.input_box)

        ShadowGui.lineEdit(self.input_box, self, "dimension_x", "Dimensions [cm]                        X (width)",
                           labelWidth=300, valueType=float, orientation="horizontal")
        ShadowGui.lineEdit(self.input_box, self, "dimension_y",
                           "                                                 Y (length)", labelWidth=300,
                           valueType=float, orientation="horizontal")

        gui.separator(self.input_box)

        ShadowGui.lineEdit(self.input_box, self, "estimated_slope_error", "Estimated slope error [arcsec]",
                           labelWidth=300, valueType=float, orientation="horizontal")
        ShadowGui.lineEdit(self.input_box, self, "montecarlo_seed", "Monte Carlo initial seed", labelWidth=300,
                           valueType=int, orientation="horizontal")

        self.output_box = ShadowGui.widgetBox(tab_input, "Outputs", addSpace=True, orientation="vertical", width=470)

        self.select_file_box = ShadowGui.widgetBox(self.output_box, "", addSpace=True, orientation="horizontal")

        gui.separator(self.output_box)

        gui.button(self.output_box, self, "Write xsh_waviness input file (optional) ...", callback=self.write_inp_file)

        ShadowGui.lineEdit(self.select_file_box, self, "waviness_file_name", "Output File Name", labelWidth=120,
                           valueType=str, orientation="horizontal")

        self.harmonics_box = ShadowGui.widgetBox(tab_harmonics, "Harmonics", addSpace=True, orientation="vertical",
                                                 width=470, height=690)

        ShadowGui.lineEdit(self.harmonics_box, self, "harmonic_maximum_index", "Harmonic Maximum Index", labelWidth=300,
                           valueType=int, orientation="horizontal", callback=self.set_harmonics)

        gui.separator(self.harmonics_box)

        self.scrollarea = QScrollArea()
        self.scrollarea.setMaximumWidth(400)

        self.harmonics_box.layout().addWidget(self.scrollarea, alignment=Qt.AlignHCenter)

        self.shadow_output = QTextEdit()
        self.shadow_output.setReadOnly(True)

        out_box = ShadowGui.widgetBox(tab_out, "System Output", addSpace=True, orientation="horizontal", height=600)
        out_box.layout().addWidget(self.shadow_output)

        button_box = ShadowGui.widgetBox(self.controlArea, "", addSpace=False, orientation="horizontal")

        button = gui.button(button_box, self, "Calculate Waviness", callback=self.calculate_waviness)
        button.setFixedHeight(45)
        button.setFixedWidth(170)

        button = gui.button(button_box, self, "Generate Waviness File", callback=self.generate_waviness_file)
        font = QFont(button.font())
        font.setBold(True)
        button.setFont(font)
        palette = QPalette(button.palette())  # make a copy of the palette
        palette.setColor(QPalette.ButtonText, QColor('Dark Blue'))
        button.setPalette(palette)  # assign new palette
        button.setFixedHeight(45)
        button.setFixedWidth(200)

        button = gui.button(button_box, self, "Reset Fields", callback=self.call_reset_settings)
        font = QFont(button.font())
        font.setItalic(True)
        button.setFont(font)
        palette = QPalette(button.palette())  # make a copy of the palette
        palette.setColor(QPalette.ButtonText, QColor('Dark Red'))
        button.setPalette(palette)  # assign new palette
        button.setFixedHeight(45)
        button.setFixedWidth(120)

        gui.rubber(self.controlArea)

        self.figure = Figure(figsize=(600, 600))
        self.figure.patch.set_facecolor('white')

        self.axis = self.figure.add_subplot(111, projection='3d')

        self.axis.set_xlabel("X (cm)")
        self.axis.set_ylabel("Y (cm)")
        self.axis.set_zlabel("Z (µm)")

        self.figure_canvas = FigureCanvasQTAgg(self.figure)
        self.mainArea.layout().addWidget(self.figure_canvas)

        gui.rubber(self.mainArea)

    def restoreWidgetPosition(self):
        super().restoreWidgetPosition()

        self.table = QTableWidget(self.harmonic_maximum_index + 1, 3)
        self.table.setAlternatingRowColors(True)
        self.table.horizontalHeader().setResizeMode(QHeaderView.Fixed)

        for i in range(0, 3):
            self.table.setColumnWidth(i, 70)

        horHeaders = []
        verHeaders = []

        for n, key in enumerate(sorted(self.data.keys())):
            horHeaders.append(key)

            for m, item in enumerate(self.data[key]):
                table_item = QTableWidgetItem(str(item))
                table_item.setTextAlignment(Qt.AlignRight)
                self.table.setItem(m, n, table_item)
                verHeaders.append(str(m))

        self.table.setHorizontalHeaderLabels(horHeaders)
        self.table.setVerticalHeaderLabels(verHeaders)
        self.table.resizeRowsToContents()

        self.table.itemChanged.connect(self.table_item_changed)

        self.scrollarea.setWidget(self.table)
        self.scrollarea.setWidgetResizable(1)

        gui.rubber(self.controlArea)

    def reload_harmonics_table(self):
        horHeaders = []
        verHeaders = []

        self.table.itemChanged.disconnect(self.table_item_changed)

        self.table.clear()

        row_count = self.table.rowCount()

        for n in range(0, row_count):
            self.table.removeRow(0)

        for index in range(0, self.harmonic_maximum_index + 1):
            self.table.insertRow(0)

        for n, key in enumerate(sorted(self.data.keys())):
            horHeaders.append(key)

            for m, item in enumerate(self.data[key]):
                table_item = QTableWidgetItem(str(item))
                table_item.setTextAlignment(Qt.AlignRight)
                self.table.setItem(m, n, table_item)
                verHeaders.append(str(m))

        self.table.setHorizontalHeaderLabels(horHeaders)
        self.table.setVerticalHeaderLabels(verHeaders)

        self.table.resizeRowsToContents()

        for i in range(0, 3):
            self.table.setColumnWidth(i, 70)

        self.table.itemChanged.connect(self.table_item_changed)

    def table_item_changed(self):
        dict = {}
        message = ""
        error_row_index = -1
        error_column_index = -1
        previous_value = ""

        try:
            row_count = self.harmonic_maximum_index + 1

            for column_index in range(0, self.table.columnCount()):
                column_name = self.table.horizontalHeaderItem(column_index).data(0)

                row_content = []

                for row_index in range(0, row_count):
                    if not self.table.item(row_index, column_index) is None:
                        message = "Value at row " + str(
                            row_index) + " and column \'" + column_name + "\' is not numeric"
                        error_row_index = row_index
                        error_column_index = column_index
                        previous_value = self.data[column_name][row_index]

                        value = float(self.table.item(row_index, column_index).data(0))  # to raise exception

                        row_content.append(str(value))

                dict[column_name] = row_content

            self.data = dict
        except ValueError:
            QMessageBox.critical(self, "QMessageBox.critical()",
                                 message + "\nValue is reset to previous value",
                                 QMessageBox.Ok)

            table_item = QTableWidgetItem(previous_value)
            table_item.setTextAlignment(Qt.AlignRight)
            self.table.setItem(error_row_index, error_column_index, table_item)
            self.table.setCurrentCell(error_row_index, error_column_index)

        except Exception as exception:
            QMessageBox.critical(self, "QMessageBox.critical()",
                                 exception.args[0],
                                 QMessageBox.Ok)

    def set_harmonics(self):
        if self.harmonic_maximum_index < 0:
            QMessageBox.critical(self, "QMessageBox.critical()",
                                 "Harmonic Maximum Index should be a positive integer number",
                                 QMessageBox.Ok)
        else:
            row_count = len(self.data["c"])

            if self.harmonic_maximum_index + 1 > row_count:
                for n, key in enumerate(sorted(self.data.keys())):
                    for m in range(row_count, self.harmonic_maximum_index + 1):
                        self.data[key].append('0.0')
            else:
                for n, key in enumerate(sorted(self.data.keys())):
                    self.data[key] = copy.deepcopy(self.data[key][0: self.harmonic_maximum_index + 1])

            self.reload_harmonics_table()

    def load_inp_file(self):
        file_name = QFileDialog.getOpenFileName(self, "Select a input file for XSH_WAVINESS", ".", "*.inp")

        if not file_name is None:
            sys.stdout = EmittingStream(textWritten=self.writeStdOut)

            if not file_name.strip() == "":
                dict = ST.waviness_read(file=file_name)

                self.number_of_points_x = dict["npointx"]
                self.number_of_points_y = dict["npointy"]
                self.dimension_y = dict["xlength"]
                self.dimension_x = dict["width"]
                self.estimated_slope_error = dict["slp"]
                self.montecarlo_seed = dict["iseed"]
                self.waviness_file_name = dict["file"].strip('\n\r').strip()
                self.harmonic_maximum_index = dict["nharmonics"]

                self.data["c"] = self.to_str_array(dict["c"])
                self.data["y"] = self.to_str_array(dict["y"])
                self.data["g"] = self.to_str_array(dict["g"])

                self.reload_harmonics_table()

    def write_inp_file(self):
        try:
            sys.stdout = EmittingStream(textWritten=self.writeStdOut)

            self.check_fields()

            file_name = self.waviness_file_name.strip().split(sep=".dat")[0] + ".inp"

            dict = {}

            dict["npointx"] = self.number_of_points_x
            dict["npointy"] = self.number_of_points_y
            dict["xlength"] = self.dimension_y
            dict["width"] = self.dimension_x
            dict["slp"] = self.estimated_slope_error
            dict["iseed"] = self.montecarlo_seed
            dict["file"] = self.waviness_file_name.strip('\n\r')
            dict["nharmonics"] = self.harmonic_maximum_index

            dict["c"] = self.to_float_array(self.data["c"])
            dict["y"] = self.to_float_array(self.data["y"])
            dict["g"] = self.to_float_array(self.data["g"])

            ST.waviness_write(dict, file=file_name)

            QMessageBox.information(self, "QMessageBox.information()",
                                    "File \'" + file_name + "\' written to disk",
                                    QMessageBox.Ok)

        except Exception as exception:
            QMessageBox.critical(self, "QMessageBox.critical()",
                                 exception.args[0],
                                 QMessageBox.Ok)

    def calculate_waviness(self):
        try:
            sys.stdout = EmittingStream(textWritten=self.writeStdOut)

            self.check_fields()

            xx, yy, zz = ST.waviness_calc(npointx=self.number_of_points_x,
                                          npointy=self.number_of_points_y,
                                          width=self.dimension_x,
                                          xlength=self.dimension_y,
                                          slp=self.estimated_slope_error,
                                          nharmonics=self.harmonic_maximum_index,
                                          iseed=self.montecarlo_seed,
                                          c=self.to_float_array(self.data["c"]),
                                          y=self.to_float_array(self.data["y"]),
                                          g=self.to_float_array(self.data["g"]))
            self.xx = xx
            self.yy = yy
            self.zz = zz

            self.axis.clear()

            x_to_plot, y_to_plot = numpy.meshgrid(xx, yy)
            z_to_plot = []

            for y_index in range(0, len(yy)):
                z_array = []
                for x_index in range(0, len(xx)):
                    z_array.append(1e4 * float(zz[x_index][y_index]))  # to micron
                z_to_plot.append(z_array)

            z_to_plot = numpy.array(z_to_plot)

            self.axis.plot_surface(x_to_plot, y_to_plot, z_to_plot,
                                   rstride=1, cstride=1, cmap=cm.autumn, linewidth=0.5, antialiased=True)

            slope, sloperms = ST.slopes(zz, xx, yy)

            title = ' Slope error rms in X direction: %f arcsec' % (sloperms[0]) + '\n' + \
                    '                                            : %f urad' % (sloperms[2]) + '\n' + \
                    ' Slope error rms in Y direction: %f arcsec' % (sloperms[1]) + '\n' + \
                    '                                            : %f urad' % (sloperms[3])

            self.axis.set_xlabel("X (cm)")
            self.axis.set_ylabel("Y (cm)")
            self.axis.set_zlabel("Z (µm)")
            self.axis.set_title(title)
            self.axis.mouse_init()

            self.figure_canvas.draw()

            QMessageBox.information(self, "QMessageBox.information()",
                                    "Waviness calculated: if the result is satisfactory,\nclick \'Generate Waviness File\' to complete the operation ",
                                    QMessageBox.Ok)
        except Exception as exception:
            QMessageBox.critical(self, "QMessageBox.critical()",
                                 exception.args[0],
                                 QMessageBox.Ok)


    def generate_waviness_file(self):
        if not self.zz is None and not self.yy is None and not self.xx is None:
            if not self.waviness_file_name is None:
                self.waviness_file_name = self.waviness_file_name.strip()

                if self.waviness_file_name == "": raise Exception("Output File Name missing")
            else:
                raise Exception("Output File Name missing")

            sys.stdout = EmittingStream(textWritten=self.writeStdOut)

            ST.write_shadow_surface(self.zz.T, self.xx, self.yy, outFile=self.waviness_file_name)
            QMessageBox.information(self, "QMessageBox.information()",
                                    "Waviness file " + self.waviness_file_name + " written on disk",
                                    QMessageBox.Ok)

            self.send("PreProcessor_Data", ShadowPreProcessorData(waviness_data_file=self.waviness_file_name))

    def call_reset_settings(self):
        if ConfirmDialog.confirmed(parent=self, message="Confirm Reset of the Fields?"):
            try:
                self.resetSettings()
                self.reload_harmonics_table()
            except:
                pass

    def check_fields(self):
        self.number_of_points_x = ShadowGui.checkStrictlyPositiveNumber(self.number_of_points_x, "Number of Points X")
        self.number_of_points_y = ShadowGui.checkStrictlyPositiveNumber(self.number_of_points_y, "Number of Points Y")

        self.dimension_x = ShadowGui.checkStrictlyPositiveNumber(self.dimension_x, "Dimension X")
        self.dimension_y = ShadowGui.checkStrictlyPositiveNumber(self.dimension_y, "Dimension Y")

        self.estimated_slope_error = ShadowGui.checkPositiveNumber(self.estimated_slope_error, "Estimated slope error")
        self.montecarlo_seed = ShadowGui.checkPositiveNumber(self.montecarlo_seed, "Monte Carlo initial seed")

        self.harmonic_maximum_index = ShadowGui.checkPositiveNumber(self.harmonic_maximum_index,
                                                                    "Harmonic Maximum Index")

        if not self.waviness_file_name is None:
            self.waviness_file_name = self.waviness_file_name.strip()

            if self.waviness_file_name == "": raise Exception("Output File Name missing")
        else:
            raise Exception("Output File Name missing")


    def to_float_array(self, string_array):
        float_array = []

        for index in range(len(string_array)):
            float_array.append(float(string_array[index]))

        return float_array

    def to_str_array(self, float_array):
        string_array = []

        for index in range(len(float_array)):
            string_array.append(str(float_array[index]))

        return string_array

    def writeStdOut(self, text):
        cursor = self.shadow_output.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertText(text)
        self.shadow_output.setTextCursor(cursor)
        self.shadow_output.ensureCursorVisible()
Example #12
0
 def process(self, node):
     for idx in xrange(0, self.tabs.count()):
         widget = self.tabs.widget(idx)
         del widget
     self.tabs.clear()
     self.node = node
     file = self.node.open()
     tags = EXIF.process_file(file)
     if len(tags) == 0:
         self.nometa.setSizePolicy(self.tabs.sizePolicy())
         self.tabs.hide()
         self.nometa.show()
     else:
         self.tabs.show()
         self.nometa.hide()
         sortedTags = {}
         for tag in tags.keys():
             if tag not in ('JPEGThumbnail', 'TIFFThumbnail', 'Filename',
                            'EXIF MakerNote'):
                 spaceidx = tag.find(" ")
                 ifd = tag[:spaceidx].strip()
                 if ifd == "Image":
                     ifd = "IFD 0 (Image)"
                 if ifd == "Thumbnail":
                     ifd = "IFD 1 (Thumbnail)"
                 key = tag[spaceidx:].strip()
                 try:
                     val = str(tags[tag])
                 except:
                     val = "cannot be decoded"
                 if ifd not in sortedTags.keys():
                     sortedTags[ifd] = []
                 sortedTags[ifd].append((key, val))
         for ifd in sortedTags.keys():
             table = QTableWidget(len(sortedTags[ifd]), 2)
             table.setShowGrid(False)
             table.setAlternatingRowColors(True)
             table.verticalHeader().hide()
             table.horizontalHeader().setClickable(False)
             table.horizontalHeader().setStretchLastSection(True)
             table.setHorizontalHeaderLabels(["Tag", "Value"])
             table.setSelectionBehavior(QAbstractItemView.SelectRows)
             self.tabs.addTab(table, ifd)
             row = 0
             for res in sortedTags[ifd]:
                 key = QTableWidgetItem(res[0])
                 key.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                 val = QTableWidgetItem(res[1])
                 val.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                 table.setItem(row, 0, key)
                 table.setItem(row, 1, val)
                 row += 1
         if 'JPEGThumbnail' in tags.keys():
             label = QLabel()
             img = QImage()
             img.loadFromData(tags['JPEGThumbnail'])
             label.setPixmap(QPixmap.fromImage(img))
             label.setAlignment(Qt.AlignCenter)
             self.tabs.addTab(label, "Embedded Thumbnail")
         if 'TIFFThumbnail' in tags.keys():
             label = QLabel()
             img = QImage()
             img.loadFromData(tags['TIFFThumbnail'])
             label.setPixmap(QPixmap.fromImage(img))
             label.setAlignment(Qt.AlignCenter)
             self.tabs.addTab(label, "Embedded Thumbnail")
         file.close()
Example #13
0
class edycja_proby(QDialog):
    def __init__(self, sample, defpol={}, defpol_order=[], parent=None):
        ''' defpol and defpol_order should contains the same values, it will
        not be checked in this class is it valid, pay attention to it'''
        super(edycja_proby, self).__init__(parent)

        # self.dane = globals()["daneW"][0]
        # self.defpol = globals()["daneW"][1]
        # globals()["daneW"] = []
        self.sample = copy.deepcopy(sample)
        self.sample._edytowany = 'E'
        self.org_sample = sample
        self.newName = self.sample.KeyCode()

        self.setWindowTitle("Sample: " + self.sample.KeyCode())
        self.resize(691, 749)
        self.setMinimumSize(QSize(691, 749))
        # self.setMaximumSize(QSize(691, 749))

        # Prepare headers
        self.defpol = defpol
        self.defpol_order = defpol_order
        self.prepareDefPol()
        self.selected = []  # list with index of selected ring in sample

        # ustawienie pol z danymi
        self.p_naglowek = QTableWidget()
        self.p_naglowek.setObjectName("p_naglowek")
        self.p_naglowek.setColumnCount(1)
        self.p_naglowek.setRowCount(len(self.headers))
        self.p_naglowek.setHorizontalHeaderLabels(["Value"])
        self.p_naglowek.setVerticalHeaderLabels(self.headers)
        self.p_naglowek.setAlternatingRowColors(True)
        self.p_naglowek.setSortingEnabled(False)

        self.p_dane = QTableWidget()
        self.p_dane.setObjectName("p_dane")
        self.p_dane.setColumnCount(10)
        self.p_dane.setHorizontalHeaderLabels(
            ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"])

        self.dodaj = QPushButton("Add")
        self.usun = QPushButton("Delete")
        self.przerysuj = QPushButton("Redraw")
        self.podziel = QPushButton("Divide")
        self.polacz = QPushButton("Join")
        self.anuluj = QPushButton("Cancel")
        self.wykonaj = QPushButton("Update")

        self.vbl = QVBoxLayout()
        self.qmc = Qt4MplCanvas(self)
        self.ntb = NavigationToolbar(self.qmc, self)
        self.vbl.addWidget(self.qmc)
        self.vbl.addWidget(self.ntb)

        self.updateHeaderTable()
        self.wpisz_pomiary()
        self.przerysuj_wykres()

        # ustawiamy wyglad okna
        layout = QGridLayout()
        layout.addWidget(self.p_naglowek, 0, 0)

        layout1 = QGridLayout()
        layout1.addWidget(self.p_dane, 0, 0, 1, 5)
        layout1.addWidget(self.dodaj, 1, 0)
        layout1.addWidget(self.usun, 1, 1)
        layout1.addWidget(self.podziel, 1, 2)
        layout1.addWidget(self.polacz, 1, 3)
        layout1.addWidget(self.przerysuj, 1, 4)
        layout1.setRowMinimumHeight(1, 25)
        layout1.setRowStretch(0, 1)

        layout.addLayout(layout1, 0, 1)
        layout.addLayout(self.vbl, 1, 0, 1, 2)
        layout.addWidget(self.anuluj, 2, 0)
        layout.addWidget(self.wykonaj, 2, 1)
        layout.setColumnMinimumWidth(0, 290)
        layout.setColumnStretch(1, 1)
        layout.setRowStretch(0, 1)
        layout.setRowMinimumHeight(0, 350)
        self.setLayout(layout)

        # Sygnaly
        self.connect(self.anuluj, SIGNAL("clicked()"), self.schowaj)
        self.connect(self.wykonaj, SIGNAL("clicked()"), self.wykonaj_odczytanie)
        self.connect(self.dodaj, SIGNAL("clicked()"), self.dodaj_wartosc)
        self.connect(self.przerysuj, SIGNAL("clicked()"), self.przerysuj_wykres)
        self.connect(self.usun, SIGNAL("clicked()"), self.usun_wartosc)
        self.connect(self.podziel, SIGNAL("clicked()"), self.podziel_wartosc)
        self.connect(self.polacz, SIGNAL("clicked()"), self.polacz_wartosc)
        self.p_naglowek.cellChanged.connect(self.edytowana_kom_nagl)
        self.p_dane.itemSelectionChanged.connect(self.przerysuj_wykres)
        self.p_dane.cellChanged.connect(self.przerysuj_wykres)

    def prepareDefPol(self):
        """Prepare Headers for metadata,
        BEAWARE! measurements are delete on the end"""
        self.headers = [
                        'KeyCode',
                        'DateBegin',
                        'DateEnd',
                        'Length',
                        'Gat',
                        'SapWoodRings',
                        'measurements',
                        ]
        add_table = []
        if len(self.defpol_order):
            add_table = self.defpol_order[:]
        elif len(self.defpol.keys()):
            add_table = sorted(list(self.defpol.keys()))
        else:
            add_table = sorted(self.sample.unikalneNaglowki())

        for val in add_table:
            if val not in self.headers:
                self.headers.append(val)
        self.headers.remove('measurements')

    def updateHeaderTable(self):
        # Dodaj wartosci wierszow dla tabeli naglowka proby
        self.p_naglowek.blockSignals(True)
        for i, val in enumerate(self.headers):
            if self.sample.wypiszMetadana(val):
                komorka = QTableWidgetItem(str(self.sample.wypiszMetadana(val)))
            else:
                komorka = QTableWidgetItem('---')

            if val == 'Length':
                komorka.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)

            self.p_naglowek.setItem(i, 0, komorka)
        self.p_naglowek.blockSignals(False)

    def wykonaj_odczytanie(self):
        # spisz cala probe z edytowanych tabel i zapisz ja do zmiennej globalnej
        # daneW
        self.odczytaj_dane(origin='org')
        self.newName = self.org_sample.KeyCode()
        self.hide()

    def przerysuj_wykres(self):
        self.odczytaj_dane()
        self.updateHeaderTable()
        self.chartData = [
                     [],  # X axis - years
                     [],  # Y axis - measurements
                    ]

        self.chartData[1] = self.sample.wypiszPomiary()
        self.chartData[0] = range(1, self.sample.Length() + 1)

        self.qmc.axes.clear()
        # draw sample curve
        self.qmc.axes.plot(self.chartData[0], self.chartData[1])

        # draw selected years
        Xpoints = []
        Ypoints = []
        self.selected = []
        j = 0
        for i in range(self.sample.Length()):
            if i == 11:
                j += 1
            item = self.p_dane.item(j, i-(j*10))
            if item.isSelected():
                Xpoints.append(i+1)
                self.selected.append(i)
                Ypoints.append(int(item.text()))
        self.qmc.axes.plot(Xpoints, Ypoints, 'ro')

        # formatting of support lines
        self.qmc.axes.xaxis.set_major_locator(MultipleLocator(10))
        self.qmc.axes.xaxis.set_minor_locator(MultipleLocator(2))

        # Prepare axis dimensions
        Xmax = 40
        if self.sample.Length() > 40:
            Xmax = self.sample.Length() + 2
        Ymax = max(self.sample.wypiszPomiary()) + 30
        self.qmc.axes.axis([0, Xmax, 0, Ymax])

        self.qmc.axes.xaxis.grid(
            True,
            'minor',
            linewidth=0.4,
            ls='-',
            color='0.20')
        self.qmc.axes.xaxis.grid(
            True,
            'major',
            linewidth=1,
            ls='-',
            color='0.80')
        self.qmc.axes.tick_params(axis='both', which='major', labelsize=10)
        self.qmc.axes.set_axisbelow(True)
        # ustawienie obszaru wykresu
        self.qmc.axes.set_position([0.03, 0.05, 0.96, 0.94])
        self.qmc.draw()

    def odczytaj_dane(self, origin='copy'):
        """update sample - read all metadata and measurements which could be
            altered by user. If origin of sample has to be modified use any
            string in origin
        """
        if origin == 'copy':
            target = self.sample
        else:
            target = self.org_sample

        for i, head in enumerate(self.headers):
            ins = unicode(self.p_naglowek.item(i, 0).text())
            if head not in ['Length'] and ins not in ['---', 0]:
                target.wpiszMetadana(
                    head,
                    ins
                    )

        rowNum = self.p_dane.rowCount()
        colNum = self.p_dane.columnCount()
        measurements = []
        check = 'ok'
        redraw = 0
        for w in range(rowNum):
            for k in range(colNum):
                item = self.p_dane.item(w, k)
                try:
                    if int(item.text()) != 0 and str(item.text()).isdigit:
                        measurements.append(int(item.text()))
                        # if after notOk we find number there is something wrong
                        # and we neef to reread measuremnts to tabel
                        if check == 'notOk':
                            redraw = 1
                except:
                    check = 'notOk'

        target.uaktualnijPom(measurements)
        if redraw == 1:
            self.wpisz_pomiary()

    def dodaj_wartosc(self):
        kk = 0
        self.ile_wierszy = self.p_dane.rowCount()
        self.ile_kol = self.p_dane.columnCount()
        for wiersz in range(self.ile_wierszy):
            for kolumna in range(self.ile_kol):
                item = self.p_dane.item(wiersz, kolumna)
                if self.p_dane.isItemSelected(item) == True and kk == 0:
                    kk = 1
                    text, ok = QInputDialog.getText(
                        self, 'Value', 'inser value: ')
                    if ok:
                        measurements = self.sample.wypiszPomiary()
                        measurements.insert((wiersz*10)+kolumna, int(text))
                        self.sample.uaktualnijPom(measurements)
        self.wpisz_pomiary()
        self.przerysuj_wykres()

    def usun_wartosc(self):
        sel = self.selected[:]
        sel.reverse()
        for s in sel:
            self.sample.usunOstatniPomiar(position=int(s))
        self.wpisz_pomiary()
        self.przerysuj_wykres()

    def wpisz_pomiary(self):
        # przygotowanie labelek poziomych dla tablicy z pomiarami
        self.w = (len(self.sample.wypiszPomiary()))/10
        if (len(self.sample.wypiszPomiary())) % 10 > 0:
            self.w += 1
        i = 0
        self.ww = []
        while i < self.w:
            self.ww.append(str(i*10))
            i += 1
        self.p_dane.blockSignals(True)
        self.p_dane.clear()
        self.p_dane.setRowCount(self.w)
        self.p_dane.setVerticalHeaderLabels(self.ww)
        self.p_dane.setAlternatingRowColors(True)
        self.p_dane.setSortingEnabled(False)

        # Dodajemy wartosci pomiarow
        i = 0
        j = 0
        k = 0
        measurements = self.sample.wypiszPomiary()
        while k < len(measurements):
            if j == 10:
                j = 0
                i += 1
            komorka = QTableWidgetItem(str(measurements[k]))
            self.p_dane.setItem(i, j, komorka)
            j += 1
            k += 1
        # uzupelniamy pozostale pola pustymi wartosciami
        while j % 10 != 0:
            komorka = QTableWidgetItem("")
            self.p_dane.setItem(i, j, komorka)
            j += 1
        self.p_dane.resizeColumnsToContents()
        self.p_dane.blockSignals(False)

    def podziel_wartosc(self):
        if len(self.selected) != 1:
            pass
        else:
            measurements = self.sample.wypiszPomiary()
            val = measurements[self.selected[0]]
            self.divideWindow = okno_podzialu(val)
            self.divideWindow.exec_()
            measurements.pop(self.selected[0])
            self.sample.uaktualnijPom(measurements)
            self.sample.dodajPomiar(self.divideWindow.val1,
                                    position=self.selected[0])
            self.sample.dodajPomiar(self.divideWindow.val0,
                                    position=self.selected[0])

            self.wpisz_pomiary()
            self.przerysuj_wykres()

    def polacz_wartosc(self):
        measurements = self.sample.wypiszPomiary()
        i = len(measurements) - 1
        selectionRange = []
        newMeasurements = []
        while i > -1:
            if i in self.selected:
                selectionRange.append(measurements[i])
            elif i not in self.selected:
                if len(selectionRange) > 0:
                    newMeasurements.append(sum(selectionRange))
                    selectionRange = []
                newMeasurements.append(measurements[i])
            i -= 1
        if len(selectionRange) > 0:
            newMeasurements.append(selectionRange)
        newMeasurements.reverse()
        self.sample.uaktualnijPom(newMeasurements)

        self.wpisz_pomiary()
        self.przerysuj_wykres()

    def schowaj(self):
        self.odczytaj_dane()
        self.hide()

    def edytowana_kom_nagl(self):
        # neccessary to maintain user specific date, otherwise it will be
        # shuflled
        row = self.p_naglowek.currentRow()
        self.p_naglowek.blockSignals(True)
        if self.headers[row] in ['DateBegin', 'DateEnd']:
            head_temp = self.headers[row]
            if head_temp == "DateBegin":
                self.sample.ustawDateBegin(
                    int(self.p_naglowek.item(row, 0).text()))
                it = QTableWidgetItem(str(self.sample.DateEnd()))
                self.p_naglowek.setItem(self.headers.index("DateEnd"), 0, it)
            if head_temp == "DateEnd":
                self.sample.ustawDateEnd(
                    int(self.p_naglowek.item(row, 0).text()))
                it = QTableWidgetItem(str(self.sample.DateBegin()))
                self.p_naglowek.setItem(self.headers.index("DateBegin"), 0, it)
        self.p_naglowek.blockSignals(False)
        self.przerysuj_wykres()
Example #14
0
class OptimizateNewSiteUI(QDialog):
    def __init__(self, iface, parent=None):
        super(OptimizateNewSiteUI, self).__init__()
        self.iface = iface
        self.parent = parent

        self.initUI()

    # 初始化界面
    def initUI(self):
        self.setWindowTitle(u'自动规划基站优化')
        self.setWindowIcon(QIcon('images/logo.png'))
        self.resize(600, 300)
        self.setWindowFlags(Qt.WindowMinMaxButtonsHint)
        self.initView()

    def initView(self):
        # 数据表格
        self.tableWidget = QTableWidget(self)
        self.tableWidget.setAlternatingRowColors(True)
        self.tableWidget.setRowCount(7)
        # 设置当前Table不能编辑
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 初始化表格上下文菜单
        self.initTableContextMenu()

        self.initTableHeader()
        # 定义按钮
        impBtn = QPushButton(u"导入EXCEL表", self)
        self.connect(impBtn, SIGNAL('clicked()'), self.impData)
        startBtn = QPushButton(u"开始合并", self)
        self.connect(startBtn, SIGNAL('clicked()'), self.mergeJSite)
        #布局
        hbox = QHBoxLayout()
        hbox.addWidget(impBtn)
        hbox.addWidget(startBtn)
        vbox = QVBoxLayout()
        vbox.addWidget(self.tableWidget)
        vbox.addLayout(hbox)

        self.setLayout(vbox)
        # 判断是否已有规划基站结果
        layer = getLayerByName(u'规划基站结果', self.iface)
        if layer:
            data_list = []
            for feature in layer.getFeatures():
                temp_list = []
                for value in feature.attributes():
                    temp_list.append(value)
                data_list.append(temp_list)
                del temp_list
            self.initTable(data_list)
            self.__mlist = data_list

    def initTableContextMenu(self):
        self.tableWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.popMenu = QMenu(self.tableWidget)
        delAction = QAction(u'删除', self)  # 删除
        self.popMenu.addAction(delAction)

    # 初始化Table的头
    def initTableHeader(self):
        self.heads = []
        self.heads = MergeSiteHead
        self.tableWidget.setColumnCount(len(self.heads))  # 设置表格的列数
        for (i, h) in enumerate(self.heads):
            tabItem = QTableWidgetItem(h)
            self.tableWidget.setHorizontalHeaderItem(i, tabItem)

    # 导入Excel表数据
    def impData(self):
        fileName = QFileDialog.getOpenFileName(self, u'数据导入', '/',
                                               'Excel Files (*.xls *.xlsx)')
        if fileName != None and fileName != '':
            self.impType = ExcelType.MERGESITE
            getDataFromExcel = GetDataFromExcel(fileName, self.impType)
            datas_list = getDataFromExcel.getData()
            self.impFinish(datas_list)

    # 导入数据完成绑定函数
    def impFinish(self, mylist):
        self.__mlist = []
        self.__mlist.extend(mylist)
        self.tableWidget.clearContents()
        self.initTable(self.__mlist)

    # 初始化表格的每个Item
    def initTable(self, mlist):
        self.tableWidget.setRowCount(len(mlist))
        for (i, v) in enumerate(mlist):
            for (j, item) in enumerate(v):
                if type(item) != str:
                    item = unicode(item)
                if item == None:
                    item = ''
                tabItem = QTableWidgetItem(item)
                tabItem.setTextAlignment(Qt.AlignCenter)
                self.tableWidget.setItem(i, j, tabItem)

    # 开始运行
    def mergeJSite(self):
        self.accept()
        merge = OptimizateNewSite(self.__mlist, self)
        merge.calculationResult.connect(self.calculationFinish)
        merge.run()

    def calculationFinish(self, merge_result):
        self.setResultLayer(merge_result)
        fileName = QFileDialog.getSaveFileName(self, u'合并结果导出到 ...', '/',
                                               'Excel File(*.xls *.xlsx)')
        if fileName:
            self.sphead = [u'规划基站名称', u'经度', u'纬度', u'区域类型', u"平均距离"]
            for i in range(6):  # 根据输入的参数增加表头
                self.sphead.append(u'基站名称')
                self.sphead.append(u'距离')
                self.sphead.append(u'经度')
                self.sphead.append(u'纬度')

            layer = getLayerByName(u"基站合并结果", self.iface)
            if not layer:
                QMessageBox.critical(self, u"错误", u"找不到基站合并结果图层")
            exportData = ExportData(self.iface, self)
            if exportData.exportDataToExcel(layer, fileName):
                QMessageBox.information(self, u"成功", u"数据导出成功!")
            else:
                QMessageBox.critical(self, u"错误", u"数据导出失败!")

        else:
            self.close()

    # 生成规划基站结果图层
    def setResultLayer(self, result_list):
        layerName = u'规划基站优化结果'
        layerType = QGis.WKBPoint

        project_dir = getProjectDir(self.iface)
        # 先判断是否已存在规划基站结果图层
        result_layer = getLayerByName(layerName, self.iface)
        if result_layer:
            # 清空数据
            delAllFeatures(result_layer)
        else:
            # 删除原有图层文件
            deleteShapefile(project_dir, layerName)
            shapPath = os.path.join(project_dir, layerName + u".shp")
            # 生成图层
            fileds = self.createFields()
            # 创建出Shap文件
            # 数据源编码模式为GBK2312(否则中文字段会乱码)
            wr = QgsVectorFileWriter(shapPath, "GBK2312", fileds, layerType,
                                     None, "ESRI Shapefile")
            # 如果保存的时候没有错误
            if wr.hasError() == QgsVectorFileWriter.NoError:
                pass
            else:
                print wr.hasError()
                raise Exception, wr.errorMessage()  # 发生错误,抛出异常交给外面的方法处理异常
            del wr  # 使添加的字段生效

            result_layer = QgsVectorLayer(shapPath, layerName, 'ogr')
            QgsMapLayerRegistry.instance().addMapLayer(result_layer)

        # 添加数据
        features_list = []
        for result in result_list:
            feature = createABasicPointFeature(
                QgsPoint(float(result[1]), float(result[2])), result)
            features_list.append(feature)
        importFeaturesToLayer(result_layer, features_list)

    def createFields(self):
        names = PLANNINGHead
        types = PLANNINGType2
        lengs = PLANNINGLength
        precs = PLANNINGPrec

        fields = QgsFields()
        for (i, itm) in enumerate(names):
            cuType = types[i]
            mtype = 'String'
            if cuType == QVariant.Int:
                mtype = 'Integer'
            elif cuType == QVariant.Double:
                mtype = 'Real'
            field = QgsField(itm, cuType, mtype, lengs[i], precs[i])
            fields.append(field)
        return fields

    def exportFinish(self, result):
        QMessageBox.information(self, u'新建基站结果', u'数据导出到Excel表完成,请查看')

    def exportError(self, e, erStr):
        QMessageBox.information(self, u'新建结果', u'生成基站时,发生错误,请重试+' + erStr)
Example #15
0
class RLibraryBrowser(QDialog):

    def __init__(self, parent=None, paths=None):
        QDialog.__init__(self, parent)
        QShortcut(QKeySequence("Escape"), self, self.reject)
        self.setWindowTitle("manageR - Library Browser")
        self.resize(500, 500)
        port = robjects.r('tools:::httpdPort')[0]
        if not port > 0:
            robjects.r('tools::startDynamicHelp()')
            port = robjects.r('tools:::httpdPort')[0]
        robjects.r("""make.packages.html()""")
        host = "localhost"
        home = "/doc/html/packages.html"
        #splitter = QSplitter(self)
        #splitter.setOrientation(Qt.Vertical)
        #splitter.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken)
        labels = QStringList(["Loaded", "Package",
                              "Title",  "Path"])
        self.parent = parent
        self.home = home
        self.packageTable = QTableWidget(0, 4, self)
        self.htmlViewer = HtmlBrowser(self, host, port, home, paths)
        #splitter.addWidget(self.packageTable)
        #splitter.addWidget(self.htmlViewer)
        vbox = QVBoxLayout(self)
        #hbox.addWidget(splitter)
        vbox.addWidget(self.packageTable)
        vbox.addWidget(self.htmlViewer)
        self.packageTable.setHorizontalHeaderLabels(labels)
        self.packageTable.setShowGrid(True)
        self.packageTable.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.packageTable.setSelectionMode(QAbstractItemView.SingleSelection)
        self.packageTable.setAlternatingRowColors(True)
        self.updatePackages()
        self.connect(self.packageTable,
            SIGNAL("itemChanged(QTableWidgetItem*)"), self.loadPackage)
        self.connect(self.packageTable,
            SIGNAL("itemDoubleClicked(QTableWidgetItem*)"), self.showPackage)

    def setSource(self, source):
        self.htmlViewer.setSource(source)

    def showPackage(self, item):
        row = item.row()
        tmp = self.packageTable.item(row, 1)
        package = tmp.text()
        home = QUrl(self.home)
        curr = QUrl("../../library/%s/html/00Index.html" % package)
        self.htmlViewer.setSource(home.resolved(curr))

    def loadPackage(self, item):
        row = item.row()
        tmp = self.packageTable.item(row, 1)
        package = tmp.text()
        if item.checkState() == Qt.Checked:
            command = "library(%s)" % package
        else:
            command = "detach('package:%s')" % package
        robjects.r(command)
        #self.emit(SIGNAL(...(command)

    def updatePackages(self):
        library_ = robjects.r.get('library', mode='function')
        packages_ = robjects.r.get('.packages', mode='function')
        loaded = list(packages_())
        packages = list(library_()[1])
        length = len(packages)
        self.packageTable.clearContents()
        #self.table.setRowCount(length/3)
        packageList = []
        for i in range(length/3):
            package = unicode(packages[i])
            if not package in packageList:
                packageList.append(package)
                self.packageTable.setRowCount(len(packageList))
                item = QTableWidgetItem("Loaded")
                item.setFlags(
                Qt.ItemIsUserCheckable|Qt.ItemIsEnabled|Qt.ItemIsSelectable)
                if package in loaded:
                    item.setCheckState(Qt.Checked)
                else:
                    item.setCheckState(Qt.Unchecked)
                self.packageTable.setItem(i, 0, item)
                item = QTableWidgetItem(unicode(packages[i]))
                item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsSelectable)
                self.packageTable.setItem(i, 1, item)
                item = QTableWidgetItem(unicode(packages[i+(2*(length/3))]))
                item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsSelectable)
                self.packageTable.setItem(i, 2, item)
                item = QTableWidgetItem(unicode(packages[i+(length/3)]))
                item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsSelectable)
                self.packageTable.setItem(i, 3, item)
        self.packageTable.resizeColumnsToContents()
Example #16
0
class Main(plugin.Plugin):
    " Main Class "
    def initialize(self, *args, **kwargs):
        " Init Main Class "
        super(Main, self).initialize(*args, **kwargs)
        self.scriptPath, self.scriptArgs = "", []
        self.profilerPath, self.tempPath = profilerPath, tempPath
        self.output = " ERROR: FAIL: No output ! "

        self.process = QProcess()
        self.process.finished.connect(self.on_process_finished)
        self.process.error.connect(self.on_process_error)

        self.tabWidget, self.stat = QTabWidget(), QWidget()
        self.tabWidget.tabCloseRequested.connect(lambda:
            self.tabWidget.setTabPosition(1)
            if self.tabWidget.tabPosition() == 0
            else self.tabWidget.setTabPosition(0))
        self.tabWidget.setStyleSheet('QTabBar{font-weight:bold;}')
        self.tabWidget.setMovable(True)
        self.tabWidget.setTabsClosable(True)
        self.vboxlayout1 = QVBoxLayout(self.stat)
        self.hboxlayout1 = QHBoxLayout()
        self.filterTableLabel = QLabel("<b>Type to Search : </b>", self.stat)
        self.hboxlayout1.addWidget(self.filterTableLabel)
        self.filterTableLineEdit = QLineEdit(self.stat)
        self.filterTableLineEdit.setPlaceholderText(' Type to Search . . . ')
        self.hboxlayout1.addWidget(self.filterTableLineEdit)
        self.filterHintTableLabel = QLabel(" ? ", self.stat)
        self.hboxlayout1.addWidget(self.filterHintTableLabel)
        self.vboxlayout1.addLayout(self.hboxlayout1)
        self.tableWidget = QTableWidget(self.stat)
        self.tableWidget.setAlternatingRowColors(True)
        self.tableWidget.setColumnCount(8)
        self.tableWidget.setRowCount(2)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(3, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(4, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(5, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(6, item)
        item = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(7, item)
        self.tableWidget.itemDoubleClicked.connect(
                                        self.on_tableWidget_itemDoubleClicked)
        self.vboxlayout1.addWidget(self.tableWidget)
        self.tabWidget.addTab(self.stat, " ? ")

        self.source = QWidget()
        self.gridlayout = QGridLayout(self.source)
        self.scintillaWarningLabel = QLabel(
            "QScintilla is not installed!. Falling back to basic text edit!.",
            self.source)
        self.gridlayout.addWidget(self.scintillaWarningLabel, 1, 0, 1, 2)
        self.sourceTreeWidget = QTreeWidget(self.source)
        self.sourceTreeWidget.setAlternatingRowColors(True)
        self.sourceTreeWidget.itemActivated.connect(
                                        self.on_sourceTreeWidget_itemActivated)
        self.sourceTreeWidget.itemClicked.connect(
                                          self.on_sourceTreeWidget_itemClicked)
        self.sourceTreeWidget.itemDoubleClicked.connect(
                                          self.on_sourceTreeWidget_itemClicked)

        self.gridlayout.addWidget(self.sourceTreeWidget, 0, 0, 1, 1)
        self.sourceTextEdit = QTextEdit(self.source)
        self.sourceTextEdit.setReadOnly(True)
        self.gridlayout.addWidget(self.sourceTextEdit, 0, 1, 1, 1)
        self.tabWidget.addTab(self.source, " ? ")

        self.result = QWidget()
        self.vlayout = QVBoxLayout(self.result)
        self.globalStatGroupBox = QGroupBox(self.result)
        self.hboxlayout = QHBoxLayout(self.globalStatGroupBox)
        self.totalTimeLcdNumber = QLCDNumber(self.globalStatGroupBox)
        self.totalTimeLcdNumber.setSegmentStyle(QLCDNumber.Filled)
        self.totalTimeLcdNumber.setNumDigits(7)
        self.totalTimeLcdNumber.display(1000000)
        self.totalTimeLcdNumber.setFrameShape(QFrame.StyledPanel)
        self.totalTimeLcdNumber.setSizePolicy(QSizePolicy.Expanding,
                                              QSizePolicy.Expanding)
        self.hboxlayout.addWidget(self.totalTimeLcdNumber)
        self.tTimeLabel = QLabel("<b>Total Time (Sec)</b>",
                                 self.globalStatGroupBox)
        self.tTimeLabel.setSizePolicy(QSizePolicy.Minimum,
                                      QSizePolicy.Minimum)
        self.hboxlayout.addWidget(self.tTimeLabel)
        self.numCallLcdNumber = QLCDNumber(self.globalStatGroupBox)
        self.numCallLcdNumber.setNumDigits(7)
        self.numCallLcdNumber.display(1000000)
        self.numCallLcdNumber.setSegmentStyle(QLCDNumber.Filled)
        self.numCallLcdNumber.setFrameShape(QFrame.StyledPanel)
        self.numCallLcdNumber.setSizePolicy(QSizePolicy.Expanding,
                                            QSizePolicy.Expanding)
        self.hboxlayout.addWidget(self.numCallLcdNumber)
        self.numCallLabel = QLabel("<b>Number of calls</b>",
                                   self.globalStatGroupBox)
        self.numCallLabel.setSizePolicy(QSizePolicy.Minimum,
                                        QSizePolicy.Minimum)
        self.hboxlayout.addWidget(self.numCallLabel)
        self.primCallLcdNumber = QLCDNumber(self.globalStatGroupBox)
        self.primCallLcdNumber.setSegmentStyle(QLCDNumber.Filled)
        self.primCallLcdNumber.setFrameShape(QFrame.StyledPanel)
        self.primCallLcdNumber.setNumDigits(7)
        self.primCallLcdNumber.display(1000000)
        self.primCallLcdNumber.setSizePolicy(QSizePolicy.Expanding,
                                             QSizePolicy.Expanding)
        self.hboxlayout.addWidget(self.primCallLcdNumber)
        self.primCallLabel = QLabel("<b>Primitive calls (%)</b>",
                                    self.globalStatGroupBox)
        self.primCallLabel.setSizePolicy(QSizePolicy.Minimum,
                                         QSizePolicy.Minimum)
        self.hboxlayout.addWidget(self.primCallLabel)
        self.vlayout.addWidget(self.globalStatGroupBox)
        try:
            from PyKDE4.kdeui import KRatingWidget
            self.rating = KRatingWidget(self.globalStatGroupBox)
            self.rating.setToolTip('Profiling Performance Rating')
        except ImportError:
            pass
        self.tabWidget.addTab(self.result, " Get Results ! ")

        self.resgraph = QWidget()
        self.vlayout2 = QVBoxLayout(self.result)
        self.graphz = QGroupBox(self.resgraph)
        self.hboxlayout2 = QHBoxLayout(self.graphz)
        try:
            from PyKDE4.kdeui import KLed
            KLed(self.graphz)
        except ImportError:
            pass
        self.hboxlayout2.addWidget(QLabel('''
            Work in Progress  :)  Not Ready Yet'''))
        self.vlayout2.addWidget(self.graphz)
        self.tabWidget.addTab(self.resgraph, " Graphs and Charts ")

        self.pathz = QWidget()
        self.vlayout3 = QVBoxLayout(self.pathz)
        self.patz = QGroupBox(self.pathz)
        self.hboxlayout3 = QVBoxLayout(self.patz)
        self.profilepath = QLineEdit(profilerPath)
        self.getprofile = QPushButton(QIcon.fromTheme("document-open"), 'Open')
        self.getprofile.setToolTip('Dont touch if you dont know what are doing')
        self.getprofile.clicked.connect(lambda: self.profilepath.setText(str(
            QFileDialog.getOpenFileName(self.patz, ' Open the profile.py file ',
            path.expanduser("~"), ';;(profile.py)'))))
        self.hboxlayout3.addWidget(QLabel(
            '<center><b>Profile.py Python Library Full Path:</b></center>'))
        self.hboxlayout3.addWidget(self.profilepath)
        self.hboxlayout3.addWidget(self.getprofile)

        self.argGroupBox = QGroupBox(self.pathz)
        self.hbxlayout = QHBoxLayout(self.argGroupBox)
        self.argLineEdit = QLineEdit(self.argGroupBox)
        self.argLineEdit.setToolTip('Not touch if you dont know what are doing')
        self.argLineEdit.setPlaceholderText(
            'Dont touch if you dont know what are doing')
        self.hbxlayout.addWidget(QLabel('<b>Additional Profile Arguments:</b>'))
        self.hbxlayout.addWidget(self.argLineEdit)
        self.hboxlayout3.addWidget(self.argGroupBox)

        self.vlayout3.addWidget(self.patz)
        self.tabWidget.addTab(self.pathz, " Paths and Configs ")

        self.outp = QWidget()
        self.vlayout4 = QVBoxLayout(self.outp)
        self.outgro = QGroupBox(self.outp)
        self.outgro.setTitle(" MultiProcessing Output Logs ")
        self.hboxlayout4 = QVBoxLayout(self.outgro)
        self.outputlog = QTextEdit()
        self.outputlog.setText('''
        I do not fear computers, I fear the lack of them.   -Isaac Asimov ''')
        self.hboxlayout4.addWidget(self.outputlog)
        self.vlayout4.addWidget(self.outgro)
        self.tabWidget.addTab(self.outp, " Logs ")

        self.actionNew_profiling = QAction(QIcon.fromTheme("document-new"),
                                           'New Profiling', self)
        self.actionLoad_profile = QAction(QIcon.fromTheme("document-open"),
                                          'Open Profiling', self)
        self.actionClean = QAction(QIcon.fromTheme("edit-clear"), 'Clean', self)
        self.actionClean.triggered.connect(lambda: self.clearContent)
        self.actionAbout = QAction(QIcon.fromTheme("help-about"), 'About', self)
        self.actionAbout.triggered.connect(lambda: QMessageBox.about(self.dock,
            __doc__, ', '.join((__doc__, __license__, __author__, __email__))))
        self.actionSave_profile = QAction(QIcon.fromTheme("document-save"),
                                          'Save Profiling', self)
        self.actionManual = QAction(QIcon.fromTheme("help-contents"),
                                    'Help', self)
        self.actionManual.triggered.connect(lambda:
                    open_new_tab('http://docs.python.org/library/profile.html'))

        self.tabWidget.setCurrentIndex(2)

        self.globalStatGroupBox.setTitle("Global Statistics")
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText("Number of Calls")
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText("Total Time")
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText("Per Call")
        item = self.tableWidget.horizontalHeaderItem(3)
        item.setText("Cumulative Time")
        item = self.tableWidget.horizontalHeaderItem(4)
        item.setText("Per Call")
        item = self.tableWidget.horizontalHeaderItem(5)
        item.setText("Filename")
        item = self.tableWidget.horizontalHeaderItem(6)
        item.setText("Line")
        item = self.tableWidget.horizontalHeaderItem(7)
        item.setText("Function")
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.stat),
                                  "Statistics per Function")

        self.sourceTreeWidget.headerItem().setText(0, "Source files")
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.source),
                                  "Sources Navigator")
        #######################################################################

        self.scrollable, self.dock = QScrollArea(), QDockWidget()
        self.scrollable.setWidgetResizable(True)
        self.scrollable.setWidget(self.tabWidget)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.dock.setWidget(self.scrollable)
        QToolBar(self.dock).addActions((self.actionNew_profiling,
            self.actionClean, self.actionSave_profile, self.actionLoad_profile,
            self.actionManual, self.actionAbout))

        self.actionNew_profiling.triggered.connect(
                                        self.on_actionNew_profiling_triggered)
        self.actionLoad_profile.triggered.connect(
                                        self.on_actionLoad_profile_triggered)
        self.actionSave_profile.triggered.connect(
                                        self.on_actionSave_profile_triggered)

        self.locator.get_service('misc').add_widget(self.dock,
                            QIcon.fromTheme("document-open-recent"), __doc__)

        if QSCI:
            # Scintilla source editor management
            self.scintillaWarningLabel.setText(' QScintilla is Ready ! ')
            layout = self.source.layout()
            layout.removeWidget(self.sourceTextEdit)
            self.sourceTextEdit = Qsci.QsciScintilla(self.source)
            layout.addWidget(self.sourceTextEdit, 0, 1)
            doc = self.sourceTextEdit
            doc.setLexer(Qsci.QsciLexerPython(self.sourceTextEdit))
            doc.setReadOnly(True)
            doc.setEdgeMode(Qsci.QsciScintilla.EdgeLine)
            doc.setEdgeColumn(80)
            doc.setEdgeColor(QColor("#FF0000"))
            doc.setFolding(Qsci.QsciScintilla.BoxedTreeFoldStyle)
            doc.setBraceMatching(Qsci.QsciScintilla.SloppyBraceMatch)
            doc.setCaretLineVisible(True)
            doc.setMarginLineNumbers(1, True)
            doc.setMarginWidth(1, 25)
            doc.setTabWidth(4)
            doc.setEolMode(Qsci.QsciScintilla.EolUnix)
            self.marker = {}
            for color in COLORS:
                mnr = doc.markerDefine(Qsci.QsciScintilla.Background)
                doc.setMarkerBackgroundColor(color, mnr)
                self.marker[color] = mnr
        self.currentSourcePath = None

        # Connect table and tree filter edit signal to unique slot
        self.filterTableLineEdit.textEdited.connect(
                                            self.on_filterLineEdit_textEdited)

        # Timer to display filter hint message
        self.filterHintTimer = QTimer(self)
        self.filterHintTimer.setSingleShot(True)
        self.filterHintTimer.timeout.connect(self.on_filterHintTimer_timeout)

        # Timer to start search
        self.filterSearchTimer = QTimer(self)
        self.filterSearchTimer.setSingleShot(True)
        self.filterSearchTimer.timeout.connect(
                                            self.on_filterSearchTimer_timeout)

        self.tabLoaded = {}
        for i in range(10):
            self.tabLoaded[i] = False
        self.backgroundTreeMatchedItems = {}
        self.resizeWidgetToContent(self.tableWidget)

    def on_actionNew_profiling_triggered(self):
        self.clearContent()
        self.scriptPath = str(QFileDialog.getOpenFileName(self.dock,
            "Choose your script to profile", path.expanduser("~"),
            "Python (*.py *.pyw)"))
        commandLine = [self.profilerPath, "-o", self.tempPath,
                       self.scriptPath] + self.scriptArgs
        commandLine = " ".join(commandLine)
        ##if self.termCheckBox.checkState() == Qt.Checked:
        #termList = ["xterm", "aterm"]
        #for term in termList:
            #termPath = which(term)
            #if termPath:
                #break
        #commandLine = """%s -e "%s ; echo 'Press ENTER Exit' ; read" """ \
                      #% (termPath, commandLine)
        self.process.start(commandLine)
        if not self.process.waitForStarted():
            print((" ERROR: {} failed!".format(commandLine)))
            return

    def on_process_finished(self, exitStatus):
        ' whan the process end '
        print((" INFO: OK: QProcess is %s" % self.process.exitCode()))
        self.output = self.process.readAll().data()
        if not self.output:
            self.output = " ERROR: FAIL: No output ! "
        self.outputlog.setText(self.output + str(self.process.exitCode()))
        if path.exists(self.tempPath):
            self.setStat(self.tempPath)
            remove(self.tempPath)
        else:
            self.outputlog.setText(" ERROR: QProcess FAIL: Profiling failed.")
        self.tabWidget.setCurrentIndex(2)

    def on_process_error(self, error):
        ' when the process fail, I hope you never see this '
        print(" ERROR: QProcess FAIL: Profiler Dead, wheres your God now ? ")
        if error == QProcess.FailedToStart:
            self.outputlog.setText(" ERROR: FAIL: Profiler execution failed ")
        elif error == QProcess.Crashed:
            self.outputlog.setText(" ERROR: FAIL: Profiler execution crashed ")
        else:
            self.outputlog.setText(" ERROR: FAIL: Profiler unknown error ")

    def on_actionLoad_profile_triggered(self):
        """Load a previous profile sessions"""
        statPath = str(QFileDialog.getOpenFileName(self.dock,
            "Open profile dump", path.expanduser("~"), "Profile file (*)"))
        if statPath:
            self.clearContent()
            print(' INFO: OK: Loading profiling from ' + statPath)
            self.setStat(statPath)

    def on_actionSave_profile_triggered(self):
        """Save a profile sessions"""
        statPath = str(QFileDialog.getSaveFileName(self.dock,
                "Save profile dump", path.expanduser("~"), "Profile file (*)"))
        if statPath:
            #TODO: handle error case and give feelback to user
            print(' INFO: OK: Saving profiling to ' + statPath)
            self.stat.save(statPath)

    #=======================================================================#
    # Common parts                                                          #
    #=======================================================================#

    def on_tabWidget_currentChanged(self, index):
        """slot for tab change"""
        # Kill search and hint timer if running to avoid cross effect
        for timer in (self.filterHintTimer, self.filterSearchTimer):
            if timer.isActive():
                timer.stop()
        if not self.stat:
            #No stat loaded, nothing to do
            return
        self.populateTable()
        self.populateSource()

    def on_filterLineEdit_textEdited(self, text):
        """slot for filter change (table or tree"""
        if self.filterSearchTimer.isActive():
            # Already runnning, stop it
            self.filterSearchTimer.stop()
        # Start timer
        self.filterSearchTimer.start(300)

    def on_filterHintTimer_timeout(self):
        """Timeout to warn user about text length"""
        print("timeout")
        tab = self.tabWidget.currentIndex()
        if tab == TAB_FUNCTIONSTAT:
            label = self.filterHintTableLabel
        label.setText("Type > 2 characters to search")

    def on_filterSearchTimer_timeout(self):
        """timeout to start search"""
        tab = self.tabWidget.currentIndex()
        if tab == TAB_FUNCTIONSTAT:
            text = self.filterTableLineEdit.text()
            label = self.filterHintTableLabel
            edit = self.filterTableLineEdit
            widget = self.tableWidget
        else:
            print("Unknow tab for filterSearch timeout !")

        print(("do search for %s" % text))
        if not len(text):
            # Empty keyword, just clean all
            if self.filterHintTimer.isActive():
                self.filterHintTimer.stop()
            label.setText(" ? ")
            self.warnUSer(True, edit)
            self.clearSearch()
            return
        if len(text) < 2:
            # Don't filter if text is too short and tell it to user
            self.filterHintTimer.start(600)
            return
        else:
            if self.filterHintTimer.isActive():
                self.filterHintTimer.stop()
            label.setText(" ? ")

        # Search
        self.clearSearch()
        matchedItems = []
        if tab == TAB_FUNCTIONSTAT:
            # Find items
            matchedItems = widget.findItems(text, Qt.MatchContains)
            widget.setSortingEnabled(False)
            matchedRows = [item.row() for item in matchedItems]
            # Hide matched items
            header = widget.verticalHeader()
            for row in range(widget.rowCount()):
                if row not in matchedRows:
                    header.hideSection(row)
            widget.setSortingEnabled(True)
        else:
            print(" Unknow tab for filterSearch timeout ! ")

        print(("got %s members" % len(matchedItems)))
        self.warnUSer(matchedItems, edit)
        self.resizeWidgetToContent(widget)

    def resizeWidgetToContent(self, widget):
        """Resize all columns according to content"""
        for i in range(widget.columnCount()):
            widget.resizeColumnToContents(i)

    def clearSearch(self):
        """Clean search result
        For table, show all items
        For tree, remove colored items"""
        tab = self.tabWidget.currentIndex()
        if tab == TAB_FUNCTIONSTAT:
            header = self.tableWidget.verticalHeader()
            if header.hiddenSectionCount():
                for i in range(header.count()):
                    if header.isSectionHidden(i):
                        header.showSection(i)

    def clearContent(self):
        # Clear tabs
        self.tableWidget.clearContents()
        self.sourceTreeWidget.clear()
        # Reset LCD numbers
        for lcdNumber in (self.totalTimeLcdNumber, self.numCallLcdNumber,
                          self.primCallLcdNumber):
            lcdNumber.display(1000000)
        # Reset stat
        self.pstat = None
        # Disable save as menu
        self.actionSave_profile.setEnabled(False)
        # Mark all tabs as unloaded
        for i in range(10):
            self.tabLoaded[i] = False

    def warnUSer(self, result, inputWidget):
        palette = inputWidget.palette()
        if result:
            palette.setColor(QPalette.Normal, QPalette.Base,
                             QColor(255, 255, 255))
        else:
            palette.setColor(QPalette.Normal, QPalette.Base,
                             QColor(255, 136, 138))
        inputWidget.setPalette(palette)
        inputWidget.update()

    def setStat(self, statPath):
        self.stat = Stat(path=statPath)
        # Global stat update
        self.totalTimeLcdNumber.display(self.stat.getTotalTime())
        self.numCallLcdNumber.display(self.stat.getCallNumber())
        self.primCallLcdNumber.display(self.stat.getPrimitiveCallRatio())
        # Refresh current tab
        self.on_tabWidget_currentChanged(self.tabWidget.currentIndex())
        # Activate save as menu
        self.actionSave_profile.setEnabled(True)
        try:
            self.rating.setMaxRating(10)
            self.rating.setRating(
                                int(self.stat.getPrimitiveCallRatio()) / 10 - 1)
        except:
            pass

    #========================================================================#
    # Statistics table                                                      #
    #=======================================================================#

    def populateTable(self):
        row = 0
        rowCount = self.stat.getStatNumber()
        progress = QProgressDialog("Populating statistics table...",
                                         "Abort", 0, 2 * rowCount)
        self.tableWidget.setSortingEnabled(False)
        self.tableWidget.setRowCount(rowCount)

        progress.setWindowModality(Qt.WindowModal)
        for (key, value) in self.stat.getStatItems():
            #ncalls
            item = StatTableWidgetItem(str(value[0]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_NCALLS, item)
            colorTableItem(item, self.stat.getCallNumber(), value[0])
            #total time
            item = StatTableWidgetItem(str(value[2]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_TTIME, item)
            colorTableItem(item, self.stat.getTotalTime(), value[2])
            #per call (total time)
            if value[0] != 0:
                tPerCall = str(value[2] / value[0])
                cPerCall = str(value[3] / value[0])
            else:
                tPerCall = ""
                cPerCall = ""
            item = StatTableWidgetItem(tPerCall)
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_TPERCALL, item)
            colorTableItem(item, 100.0 * self.stat.getTotalTime() /
                           self.stat.getCallNumber(), tPerCall)
            #per call (cumulative time)
            item = StatTableWidgetItem(cPerCall)
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_CPERCALL, item)
            colorTableItem(item, 100.0 * self.stat.getTotalTime() /
                           self.stat.getCallNumber(), cPerCall)
            #cumulative time
            item = StatTableWidgetItem(str(value[3]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_CTIME, item)
            colorTableItem(item, self.stat.getTotalTime(), value[3])
            #Filename
            self.tableWidget.setItem(row, STAT_FILENAME,
                                        StatTableWidgetItem(str(key[0])))
            #Line
            item = StatTableWidgetItem(str(key[1]))
            item.setTextAlignment(Qt.AlignRight)
            self.tableWidget.setItem(row, STAT_LINE, item)
            #Function name
            self.tableWidget.setItem(row, STAT_FUNCTION,
                                        StatTableWidgetItem(str(key[2])))
            row += 1
            # Store it in stat hash array
            self.stat.setStatLink(item, key, TAB_FUNCTIONSTAT)
            progress.setValue(row)
            if progress.wasCanceled():
                return

        for i in range(self.tableWidget.rowCount()):
            progress.setValue(row + i)
            for j in range(self.tableWidget.columnCount()):
                item = self.tableWidget.item(i, j)
                if item:
                    item.setFlags(Qt.ItemIsEnabled)

        self.tableWidget.setSortingEnabled(True)
        self.resizeWidgetToContent(self.tableWidget)
        progress.setValue(2 * rowCount)

    def on_tableWidget_itemDoubleClicked(self, item):
        matchedItems = []
        filename = str(self.tableWidget.item(item.row(), STAT_FILENAME).text())
        if not filename or filename.startswith("<"):
            # No source code associated, return immediatly
            return
        function = self.tableWidget.item(item.row(), STAT_FUNCTION).text()
        line = self.tableWidget.item(item.row(), STAT_LINE).text()

        self.on_tabWidget_currentChanged(TAB_SOURCE)  # load source tab
        function = "%s (%s)" % (function, line)
        fathers = self.sourceTreeWidget.findItems(filename, Qt.MatchContains,
                                                  SOURCE_FILENAME)
        print(("find %s father" % len(fathers)))
        for father in fathers:
            findItems(father, function, SOURCE_FILENAME, matchedItems)
        print(("find %s items" % len(matchedItems)))

        if matchedItems:
            self.tabWidget.setCurrentIndex(TAB_SOURCE)
            self.sourceTreeWidget.scrollToItem(matchedItems[0])
            self.on_sourceTreeWidget_itemClicked(matchedItems[0],
                                                 SOURCE_FILENAME)
            matchedItems[0].setSelected(True)
        else:
            print("oups, item found but cannot scroll to it !")

    #=======================================================================#
    # Source explorer                                                      #
    #=====================================================================#

    def populateSource(self):
        items = {}
        for stat in self.stat.getStatKeys():
            source = stat[0]
            function = "%s (%s)" % (stat[2], stat[1])
            if source in ("", "profile") or source.startswith("<"):
                continue
            # Create the function child
            child = QTreeWidgetItem([function])
            # Store it in stat hash array
            self.stat.setStatLink(child, stat, TAB_SOURCE)
            if source in items:
                father = items[source]
            else:
                # Create the father
                father = QTreeWidgetItem([source])
                items[source] = father
            father.addChild(child)
        self.sourceTreeWidget.setSortingEnabled(False)
        for value in list(items.values()):
            self.sourceTreeWidget.addTopLevelItem(value)
        self.sourceTreeWidget.setSortingEnabled(True)

    def on_sourceTreeWidget_itemActivated(self, item, column):
        self.on_sourceTreeWidget_itemClicked(item, column)

    def on_sourceTreeWidget_itemClicked(self, item, column):
        line = 0
        parent = item.parent()
        if QSCI:
            doc = self.sourceTextEdit
        if parent:
            pathz = parent.text(column)
            result = match("(.*) \(([0-9]+)\)", item.text(column))
            if result:
                try:
                    function = str(result.group(1))
                    line = int(result.group(2))
                except ValueError:
                    # We got garbage... falling back to line 0
                    pass
        else:
            pathz = item.text(column)
        pathz = path.abspath(str(pathz))
        if self.currentSourcePath != pathz:
            # Need to load source
            self.currentSourcePath == pathz
            try:
                if QSCI:
                    doc.clear()
                    doc.insert(file(pathz).read())
                else:
                    self.sourceTextEdit.setPlainText(file(pathz).read())
            except IOError:
                QMessageBox.warning(self,
                                     "Error", "Source file could not be found",
                                     QMessageBox.Ok)
                return

            if QSCI:
                for function, line in [(i[2], i[1]
                           ) for i in self.stat.getStatKeys() if i[0] == pathz]:
                    # expr, regexp, case sensitive, whole word, wrap, forward
                    doc.findFirst("def", False, True, True, False, True, line,
                                  0, True)
                    end, foo = doc.getCursorPosition()
                    time = self.stat.getStatTotalTime((pathz, line, function))
                    colorSource(doc, self.stat.getTotalTime(), time, line, end,
                                self.marker)
        if QSCI:
            doc.ensureLineVisible(line)