class OWxsh_prerefl(widget.OWWidget): name = "xsh_prerefl" id = "orange.widgets.preprocessor.xsh_prerefl" description = "xoppy application to compute..." icon = "icons/prerefl.png" author = "create_widget.py" maintainer_email = "*****@*****.**" priority = 10 category = "" keywords = ["xoppy", "xsh_prerefl"] outputs = [{"name":"PreProcessor_Data", "type":ShadowPreProcessorData, "doc":"PreProcessor Data", "id":"PreProcessor_Data"}] want_main_area = False SYMBOL = Setting("SiC") DENSITY = Setting(3.217) SHADOW_FILE = Setting("reflec.dat") E_MIN = Setting(100.0) E_MAX = Setting(20000.0) E_STEP = Setting(100.0) def __init__(self): super().__init__() self.process_showers() box = ShadowGui.widgetBox(self.controlArea, "Reflectivity Parameters", orientation="vertical") idx = -1 #widget index 0 idx += 1 ShadowGui.lineEdit(box, self, "SYMBOL", label=self.unitLabels()[idx], addSpace=True, labelWidth=350, orientation="horizontal") self.show_at(self.unitFlags()[idx], box) #widget index 1 idx += 1 ShadowGui.lineEdit(box, self, "DENSITY", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal") self.show_at(self.unitFlags()[idx], box) #widget index 2 idx += 1 ShadowGui.lineEdit(box, self, "SHADOW_FILE", label=self.unitLabels()[idx], addSpace=True, labelWidth=200, orientation="horizontal") self.show_at(self.unitFlags()[idx], box) #widget index 3 idx += 1 ShadowGui.lineEdit(box, self, "E_MIN", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal") self.show_at(self.unitFlags()[idx], box) #widget index 4 idx += 1 ShadowGui.lineEdit(box, self, "E_MAX", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal") self.show_at(self.unitFlags()[idx], box) #widget index 5 idx += 1 ShadowGui.lineEdit(box, self, "E_STEP", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal") self.show_at(self.unitFlags()[idx], box) self.shadow_output = QTextEdit() self.shadow_output.setReadOnly(True) out_box = ShadowGui.widgetBox(self.controlArea, "System Output", addSpace=True, orientation="horizontal", height=150) out_box.layout().addWidget(self.shadow_output) box0 = gui.widgetBox(self.controlArea, "",orientation="horizontal") #widget buttons: compute, set defaults, help button = gui.button(box0, self, "Compute", callback=self.compute) button.setFixedHeight(45) button = gui.button(box0, self, "Defaults", callback=self.defaults) button.setFixedHeight(45) button = gui.button(box0, self, "Help", callback=self.help1) button.setFixedHeight(45) gui.rubber(self.controlArea) def unitLabels(self): return ['Element/Compound formula','Density [ g/cm3 ]','File for SHADOW (trace):','Minimum energy [eV]','Maximum energy [eV]','Energy step [eV]'] def unitFlags(self): return ['True','True','True','True','True','True'] def compute(self): sys.stdout = EmittingStream(textWritten=self.writeStdOut) tmp = prerefl(interactive=False,SYMBOL=self.SYMBOL,DENSITY=self.DENSITY,FILE=self.SHADOW_FILE,E_MIN=self.E_MIN,E_MAX=self.E_MAX,E_STEP=self.E_STEP) self.send("PreProcessor_Data", ShadowPreProcessorData(prerefl_data_file=self.SHADOW_FILE)) def defaults(self): self.resetSettings() self.compute() return def help1(self): print("help pressed.") xoppy_doc('xsh_prerefl') 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()
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)"))
class OWxraylib_widget(widget.OWWidget): name = "Xraylib" id = "orange.widgets.dataxraylib_widget" description = "XRAYLIB data" icon = "icons/xraylib.png" author = "Manuel Sanchez del Rio, Luca Rebuffi " maintainer_email = "*****@*****.**" priority = 12 category = "" keywords = ["xoppy", "xraylib_widget"] want_main_area = False FUNCTION = Setting(0) ELEMENT = Setting(26) ELEMENTORCOMPOUND = Setting("FeSO4") COMPOUND = Setting("Ca5(PO4)3") TRANSITION_IUPAC_OR_SIEGBAHN = Setting(1) TRANSITION_IUPAC_TO = Setting(0) TRANSITION_IUPAC_FROM = Setting(0) TRANSITION_SIEGBAHN = Setting(0) SHELL = Setting(0) ENERGY = Setting(10.0) MAX_WIDTH = 700 MAX_HEIGHT = 700 CONTROL_AREA_WIDTH = 690 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.MAX_WIDTH)), round(min(geom.height()*0.95, self.MAX_HEIGHT)))) self.setMaximumHeight(self.geometry().height()) self.setMaximumWidth(self.geometry().width()) self.controlArea.setFixedWidth(self.CONTROL_AREA_WIDTH) box0 = gui.widgetBox(self.controlArea, "", orientation="horizontal") #widget buttons: compute, set defaults, help gui.button(box0, self, "Compute", callback=self.compute) gui.button(box0, self, "Defaults", callback=self.defaults) gui.button(box0, self, "Help", callback=self.help1) gui.separator(self.controlArea, height=10) box = oasysgui.widgetBox(self.controlArea, self.name + " Input Parameters",orientation="vertical", width=self.CONTROL_AREA_WIDTH-5, height=150) self.xoppy_output = QTextEdit() self.xoppy_output.setReadOnly(True) self.xoppy_output.setFixedHeight(440) self.xoppy_output.setFixedWidth(self.CONTROL_AREA_WIDTH-25) out_box = gui.widgetBox(self.controlArea, "Calculation Output", addSpace=True, orientation="horizontal") out_box.layout().addWidget(self.xoppy_output) idx = -1 #widget index 0 idx += 1 box1 = gui.widgetBox(box) gui.comboBox(box1, self, "FUNCTION", label=self.unitLabels()[idx], addSpace=False, items=['0 Fluorescence line energy', '1 Absorption edge energy', '2 Atomic weight', '3 Elemental density', '4 Total absorption cross section', '5 Photoionization cross section', '6 Partial photoionization cross section', '7 Rayleigh scattering cross section', '8 Compton scattering cross section', '9 Klein-Nishina cross section', '10 Mass energy-absorption cross section', '11 Differential unpolarized Klein-Nishina cross section', '12 Differential unpolarized Thomson cross section', '13 Differential unpolarized Rayleigh cross section', '14 Differential unpolarized Compton cross section', '15 Differential polarized Klein-Nishina cross section', '16 Differential polarized Thomson cross section', '17 Differential polarized Rayleigh cross section', '18 Differential polarized Compton cross section', '19 Atomic form factor', '20 Incoherent scattering function', '21 Momentum transfer function', '22 Coster-Kronig transition probability', '23 Fluorescence yield', '24 Jump factor', '25 Radiative transition probability', '26 Energy after Compton scattering', '27 Anomalous scattering factor φ′', '28 Anomalous scattering factor φ″', '29 Electronic configuration', '30 X-ray fluorescence production cross section (with full cascade)', '31 X-ray fluorescence production cross section (with radiative cascade)', '32 X-ray fluorescence production cross section (with non-radiative cascade)', '33 X-ray fluorescence production cross section (without cascade)', '34 Atomic level width', '35 Auger yield', '36 Auger rate', '37 Refractive index', '38 Compton broadening profile', '39 Partial Compton broadening profile', '40 List of NIST catalog compounds', '41 Get composition of NIST catalog compound', '42 List of X-ray emitting radionuclides', '43 Get excitation profile of X-ray emitting radionuclide', '44 Compoundparser'], valueType=int, orientation="horizontal", labelWidth=250) self.show_at(self.unitFlags()[idx], box1) #widget index 1 idx += 1 box1 = gui.widgetBox(box) oasysgui.lineEdit(box1, self, "ELEMENT", label=self.unitLabels()[idx], addSpace=False, valueType=int, validator=QIntValidator(), orientation="horizontal", labelWidth=250) self.show_at(self.unitFlags()[idx], box1) #widget index 2 idx += 1 box1 = gui.widgetBox(box) oasysgui.lineEdit(box1, self, "ELEMENTORCOMPOUND", label=self.unitLabels()[idx], addSpace=False, orientation="horizontal", labelWidth=250) self.show_at(self.unitFlags()[idx], box1) #widget index 3 idx += 1 box1 = gui.widgetBox(box) oasysgui.lineEdit(box1, self, "COMPOUND", label=self.unitLabels()[idx], addSpace=False, orientation="horizontal", labelWidth=250) self.show_at(self.unitFlags()[idx], box1) #widget index 4 idx += 1 box1 = gui.widgetBox(box) gui.comboBox(box1, self, "TRANSITION_IUPAC_OR_SIEGBAHN", label=self.unitLabels()[idx], addSpace=False, items=['IUPAC', 'SIEGBAHN', 'ALL TRANSITIONS'], valueType=int, orientation="horizontal", labelWidth=250) self.show_at(self.unitFlags()[idx], box1) #widget index 5 idx += 1 box1 = gui.widgetBox(box) gui.comboBox(box1, self, "TRANSITION_IUPAC_TO", label=self.unitLabels()[idx], addSpace=False, items=['K', 'L1', 'L2', 'L3', 'M1', 'M2', 'M3', 'M4', 'M5', 'N1', 'N2', 'N3', 'N4', 'N5', 'N6', 'N7', 'O1', 'O2', 'O3', 'O4', 'O5', 'O6', 'O7', 'P1', 'P2', 'P3', 'P4', 'P5', 'Q1', 'Q2', 'Q3'], valueType=int, orientation="horizontal", labelWidth=250) self.show_at(self.unitFlags()[idx], box1) #widget index 6 idx += 1 box1 = gui.widgetBox(box) gui.comboBox(box1, self, "TRANSITION_IUPAC_FROM", label=self.unitLabels()[idx], addSpace=False, items=['K', 'L1', 'L2', 'L3', 'M1', 'M2', 'M3', 'M4', 'M5', 'N1', 'N2', 'N3', 'N4', 'N5', 'N6', 'N7', 'O1', 'O2', 'O3', 'O4', 'O5', 'O6', 'O7', 'P1', 'P2', 'P3', 'P4', 'P5', 'Q1', 'Q2', 'Q3'], valueType=int, orientation="horizontal", labelWidth=250) self.show_at(self.unitFlags()[idx], box1) #widget index 7 idx += 1 box1 = gui.widgetBox(box) gui.comboBox(box1, self, "TRANSITION_SIEGBAHN", label=self.unitLabels()[idx], addSpace=False, items=['KA1_LINE', 'KA2_LINE', 'KB1_LINE', 'KB2_LINE', 'KB3_LINE', 'KB4_LINE', 'KB5_LINE', 'LA1_LINE', 'LA2_LINE', 'LB1_LINE', 'LB2_LINE', 'LB3_LINE', 'LB4_LINE', 'LB5_LINE', 'LB6_LINE', 'LB7_LINE', 'LB9_LINE', 'LB10_LINE', 'LB15_LINE', 'LB17_LINE', 'LG1_LINE', 'LG2_LINE', 'LG3_LINE', 'LG4_LINE', 'LG5_LINE', 'LG6_LINE', 'LG8_LINE', 'LE_LINE', 'LL_LINE', 'LS_LINE', 'LT_LINE', 'LU_LINE', 'LV_LINE'], valueType=int, orientation="horizontal", labelWidth=250) self.show_at(self.unitFlags()[idx], box1) #widget index 8 idx += 1 box1 = gui.widgetBox(box) gui.comboBox(box1, self, "SHELL", label=self.unitLabels()[idx], addSpace=False, items=['All shells', 'K_SHELL', 'L1_SHELL', 'L2_SHELL', 'L3_SHELL', 'M1_SHELL', 'M2_SHELL', 'M3_SHELL', 'M4_SHELL', 'M5_SHELL', 'N1_SHELL', 'N2_SHELL', 'N3_SHELL', 'N4_SHELL', 'N5_SHELL', 'N6_SHELL', 'N7_SHELL', 'O1_SHELL', 'O2_SHELL', 'O3_SHELL', 'O4_SHELL', 'O5_SHELL', 'O6_SHELL', 'O7_SHELL', 'P1_SHELL', 'P2_SHELL', 'P3_SHELL', 'P4_SHELL', 'P5_SHELL', 'Q1_SHELL', 'Q2_SHELL', 'Q3_SHELL'], valueType=int, orientation="horizontal", labelWidth=250) self.show_at(self.unitFlags()[idx], box1) #widget index 9 idx += 1 box1 = gui.widgetBox(box) oasysgui.lineEdit(box1, self, "ENERGY", label=self.unitLabels()[idx], addSpace=False, valueType=float, validator=QDoubleValidator(), orientation="horizontal", labelWidth=250) self.show_at(self.unitFlags()[idx], box1) self.process_showers() gui.rubber(self.controlArea) def unitLabels(self): return ["Calculate", "Atomic number", "Element or compound name", "Compound name", "Transition notation", "Transition to (iupac)","Transition from (iupac)","Transition (Siegbahn)","Shell","Energy [keV]"] def unitFlags(self): return ["True", "self.FUNCTION <= 3 or self.FUNCTION == 6", "self.FUNCTION == 4 or self.FUNCTION == 5 or self.FUNCTION == 7 or self.FUNCTION == 8 or self.FUNCTION == 10", "self.FUNCTION > 100","self.FUNCTION == 0", "(self.FUNCTION == 0 and self.TRANSITION_IUPAC_OR_SIEGBAHN == 0)", "(self.FUNCTION == 0 and self.TRANSITION_IUPAC_OR_SIEGBAHN == 0)", "(self.FUNCTION == 0 and self.TRANSITION_IUPAC_OR_SIEGBAHN == 1)","self.FUNCTION == 1 or self.FUNCTION == 6","self.FUNCTION >= 4 "] def compute(self): self.setStatusMessage("Running XRAYLIB") try: sys.stdout = xoppy_util.EmittingStream(textWritten=self.writeStdOut) xoppy_calc_xraylib_widget(FUNCTION=self.FUNCTION,ELEMENT=self.ELEMENT,ELEMENTORCOMPOUND=self.ELEMENTORCOMPOUND,COMPOUND=self.COMPOUND,TRANSITION_IUPAC_OR_SIEGBAHN=self.TRANSITION_IUPAC_OR_SIEGBAHN,TRANSITION_IUPAC_TO=self.TRANSITION_IUPAC_TO,TRANSITION_IUPAC_FROM=self.TRANSITION_IUPAC_FROM,TRANSITION_SIEGBAHN=self.TRANSITION_SIEGBAHN,SHELL=self.SHELL,ENERGY=self.ENERGY) self.setStatusMessage("") except Exception as exception: QMessageBox.critical(self, "Error", str(exception), QMessageBox.Ok) self.setStatusMessage("Error!") raise exception def defaults(self): self.resetSettings() def help1(self): xoppy_util.xoppy_doc('xraylib_widget') def writeStdOut(self, text): cursor = self.xoppy_output.textCursor() cursor.movePosition(QTextCursor.End) cursor.insertText(text) self.xoppy_output.setTextCursor(cursor) self.xoppy_output.ensureCursorVisible()
class OWxsh_pre_mlayer(widget.OWWidget): name = "xsh_pre_mlayer" id = "orange.widgets.preprocessor.xsh_pre_mlayer" description = "xoppy application to compute..." icon = "icons/premlayer.png" author = "create_widget.py" maintainer_email = "*****@*****.**" priority = 10 category = "" keywords = ["xoppy", "xsh_pre_mlayer"] outputs = [ { "name": "PreProcessor_Data", "type": ShadowPreProcessorData, "doc": "PreProcessor Data", "id": "PreProcessor_Data", } ] want_main_area = False FILE = Setting("mlayer.dat") E_MIN = Setting(5000.0) E_MAX = Setting(20000.0) S_DENSITY = Setting("2.33") S_MATERIAL = Setting("Si") E_DENSITY = Setting("2.40") E_MATERIAL = Setting("B4C") O_DENSITY = Setting("9.40") O_MATERIAL = Setting("Ru") GRADE_DEPTH = Setting(0) N_PAIRS = Setting(70) THICKNESS = Setting(33.1) GAMMA = Setting(0.483) ROUGHNESS_EVEN = Setting(3.3) ROUGHNESS_ODD = Setting(3.1) FILE_DEPTH = Setting("myfile_depth.dat") GRADE_SURFACE = Setting(0) FILE_SHADOW = Setting("mlayer1.sha") FILE_THICKNESS = Setting("mythick.dat") FILE_GAMMA = Setting("mygamma.dat") AA0 = Setting(1.0) AA1 = Setting(0.0) AA2 = Setting(0.0) def __init__(self): super().__init__() self.process_showers() self.setFixedWidth(800) self.setFixedHeight(900) box = gui.widgetBox(self.controlArea, "Multilayer Parameters", orientation="vertical") idx = -1 # widget index 0 idx += 1 ShadowGui.lineEdit( box, self, "FILE", label=self.unitLabels()[idx], addSpace=True, labelWidth=350, orientation="horizontal" ) self.show_at(self.unitFlags()[idx], box) # widget index 1 idx += 1 ShadowGui.lineEdit( box, self, "E_MIN", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 2 idx += 1 ShadowGui.lineEdit( box, self, "E_MAX", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 3 idx += 1 ShadowGui.lineEdit( box, self, "S_DENSITY", label=self.unitLabels()[idx], addSpace=True, labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 4 idx += 1 ShadowGui.lineEdit( box, self, "S_MATERIAL", label=self.unitLabels()[idx], addSpace=True, labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 5 idx += 1 ShadowGui.lineEdit( box, self, "E_DENSITY", label=self.unitLabels()[idx], addSpace=True, labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 6 idx += 1 ShadowGui.lineEdit( box, self, "E_MATERIAL", label=self.unitLabels()[idx], addSpace=True, labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 7 idx += 1 ShadowGui.lineEdit( box, self, "O_DENSITY", label=self.unitLabels()[idx], addSpace=True, labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 8 idx += 1 ShadowGui.lineEdit( box, self, "O_MATERIAL", label=self.unitLabels()[idx], addSpace=True, labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 9 idx += 1 gui.comboBox( box, self, "GRADE_DEPTH", label=self.unitLabels()[idx], addSpace=True, items=["No (Constant)", "thicknesses,gamma,rough_even and rough_off from file "], valueType=int, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 10 idx += 1 ShadowGui.lineEdit( box, self, "N_PAIRS", label=self.unitLabels()[idx], addSpace=True, valueType=int, validator=QIntValidator(), labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 11 idx += 1 ShadowGui.lineEdit( box, self, "THICKNESS", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 12 idx += 1 ShadowGui.lineEdit( box, self, "GAMMA", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 13 idx += 1 ShadowGui.lineEdit( box, self, "ROUGHNESS_EVEN", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 14 idx += 1 ShadowGui.lineEdit( box, self, "ROUGHNESS_ODD", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 15 idx += 1 ShadowGui.lineEdit( box, self, "FILE_DEPTH", label=self.unitLabels()[idx], addSpace=True, labelWidth=450, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 16 idx += 1 gui.comboBox( box, self, "GRADE_SURFACE", label=self.unitLabels()[idx], addSpace=True, items=[ "No (Constant)", "thick and gamma graded (from spline files)", "thickness graded (from quadratic fit)", ], valueType=int, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 17 idx += 1 ShadowGui.lineEdit( box, self, "FILE_SHADOW", label=self.unitLabels()[idx], addSpace=True, labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 18 idx += 1 ShadowGui.lineEdit( box, self, "FILE_THICKNESS", label=self.unitLabels()[idx], addSpace=True, labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 19 idx += 1 ShadowGui.lineEdit( box, self, "FILE_GAMMA", label=self.unitLabels()[idx], addSpace=True, labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 20 idx += 1 ShadowGui.lineEdit( box, self, "AA0", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 21 idx += 1 ShadowGui.lineEdit( box, self, "AA1", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) # widget index 22 idx += 1 ShadowGui.lineEdit( box, self, "AA2", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal", ) self.show_at(self.unitFlags()[idx], box) self.shadow_output = QTextEdit() self.shadow_output.setReadOnly(True) out_box = ShadowGui.widgetBox( self.controlArea, "System Output", addSpace=True, orientation="horizontal", height=150 ) out_box.layout().addWidget(self.shadow_output) box0 = gui.widgetBox(self.controlArea, "", orientation="horizontal") # widget buttons: compute, set defaults, help button = gui.button(box0, self, "Compute", callback=self.compute) button.setFixedHeight(45) button = gui.button(box0, self, "Defaults", callback=self.defaults) button.setFixedHeight(45) button = gui.button(box0, self, "Help", callback=self.help1) button.setFixedHeight(45) gui.rubber(self.controlArea) def unitLabels(self): return [ "Output file (for SHADOW/trace): ", "Min Energy [eV]", "Max Energy [eV]", "Density (substrate) [g/cm3]", "Material (substrate) (element or formula)", 'Density (even "bottom" sublayer) [g/cm3]', "Material (even sublayer) (element or formula)", 'Density (odd "top" sublayer) [g/cm3]', "Material (odd sublayer) (element or formula)", "Bilayer thicknesses graded along the depth? ", "Number of bilayers ", "bilayer thickness t [A]", "gamma ratio [t_even/(t_odd+t_even)]", "Roughness even layer [A]", "Roughness odd layer [A]", "File with list of t_bilayer,gamma,roughness_even,roughness_odd:", "Bilayer thicknesses/gamma graded along the surface? ", "Output binary file (for SHADOW) with splines", "File with bilayer thicknesses versus surface (PRESURFACE format)", "File with bilayer gamma versus surface (PRESURFACE format)", "Fit bilayer t(y)/t(y=0) vs y: zero-order coefficient (constant)", "Fit bilayer t(y)/t(y=0) vs y: linear coefficient (slope)", "Fit bilayer t(y)/t(y=0) vs y: 2nd degree coefficient", ] def unitFlags(self): return [ "True", "True", "True", "True", "True", "True", "True", "True", "True", "True", "self.GRADE_DEPTH == 0", "self.GRADE_DEPTH == 0", "self.GRADE_DEPTH == 0", "self.GRADE_DEPTH == 0", "self.GRADE_DEPTH == 0", "self.GRADE_DEPTH == 1", "True", "self.GRADE_SURFACE == 1", "self.GRADE_SURFACE == 1", "self.GRADE_SURFACE == 1", "self.GRADE_SURFACE == 2", "self.GRADE_SURFACE == 2", "self.GRADE_SURFACE == 2", ] def compute(self): sys.stdout = EmittingStream(textWritten=self.writeStdOut) tmp = pre_mlayer( interactive=False, FILE=self.FILE, E_MIN=self.E_MIN, E_MAX=self.E_MAX, S_DENSITY=self.S_DENSITY, S_MATERIAL=self.S_MATERIAL, E_DENSITY=self.E_DENSITY, E_MATERIAL=self.E_MATERIAL, O_DENSITY=self.O_DENSITY, O_MATERIAL=self.O_MATERIAL, GRADE_DEPTH=self.GRADE_DEPTH, N_PAIRS=self.N_PAIRS, THICKNESS=self.THICKNESS, GAMMA=self.GAMMA, ROUGHNESS_EVEN=self.ROUGHNESS_EVEN, ROUGHNESS_ODD=self.ROUGHNESS_ODD, FILE_DEPTH=self.FILE_DEPTH, GRADE_SURFACE=self.GRADE_SURFACE, FILE_SHADOW=self.FILE_SHADOW, FILE_THICKNESS=self.FILE_THICKNESS, FILE_GAMMA=self.FILE_GAMMA, AA0=self.AA0, AA1=self.AA1, AA2=self.AA2, ) self.send( "PreProcessor_Data", ShadowPreProcessorData(m_layer_data_file_dat=self.FILE, m_layer_data_file_sha=self.FILE_SHADOW), ) def defaults(self): self.resetSettings() self.compute() return def help1(self): print("help pressed.") xoppy_doc("xsh_pre_mlayer") 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()
class OWheight_profile_simulator(OWWidget): name = "Height Profile Simulator" id = "height_profile_simulator" description = "Calculation of mirror surface height profile" icon = "icons/simulator.png" author = "Luca Rebuffi" maintainer_email = "[email protected]; [email protected]" priority = 5 category = "" keywords = ["height_profile_simulator"] 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 kind_of_profile_x = Setting(0) kind_of_profile_y = Setting(0) step_x = Setting(1.0) step_y = Setting(1.0) dimension_x = Setting(20.1) dimension_y = Setting(200.1) power_law_exponent_beta_x = Setting(1.5) power_law_exponent_beta_y = Setting(1.5) correlation_length_x = Setting(30.0) correlation_length_y = Setting(30.0) error_type_x = Setting(profiles_simulation.FIGURE_ERROR) error_type_y = Setting(profiles_simulation.FIGURE_ERROR) rms_x = Setting(0.1) montecarlo_seed_x = Setting(8787) rms_y = Setting(1) montecarlo_seed_y = Setting(8788) heigth_profile_1D_file_name_x= Setting("mirror_1D_x.dat") delimiter_x = Setting(0) conversion_factor_x_x = Setting(0.1) conversion_factor_x_y = Setting(1e-6) center_x = Setting(1) modify_x = Setting(0) new_length = Setting(20.1) filler_value = Setting(0.0) scale_factor_x = Setting(1.0) renormalize_x = Setting(0) heigth_profile_1D_file_name_y = Setting("mirror_1D_y.dat") delimiter_y = Setting(0) conversion_factor_y_x = Setting(0.1) conversion_factor_y_y = Setting(1e-6) center_y = Setting(1) modify_y = Setting(0) new_length = Setting(200.1) filler_value = Setting(0.0) scale_factor_y = Setting(1.0) renormalize_y = Setting(0) heigth_profile_file_name = Setting('mirror.dat') 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()) 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, "Input Parameters") tab_out = oasysgui.createTabPage(tabs_setting, "Output") tabs_input = gui.tabWidget(tab_input) tab_length = oasysgui.createTabPage(tabs_input, "Length") tab_width = oasysgui.createTabPage(tabs_input, "Width") #/ --------------------------------------- input_box_l = oasysgui.widgetBox(tab_length, "Calculation Parameters", addSpace=True, orientation="vertical") gui.comboBox(input_box_l, self, "kind_of_profile_y", label="Kind of Profile", labelWidth=260, items=["Fractal", "Gaussian", "User File"], callback=self.set_KindOfProfileY, sendSelectedValue=False, orientation="horizontal") gui.separator(input_box_l) self.kind_of_profile_y_box_1 = oasysgui.widgetBox(input_box_l, "", addSpace=True, orientation="vertical", height=350) self.le_dimension_y = oasysgui.lineEdit(self.kind_of_profile_y_box_1, self, "dimension_y", "Dimensions", labelWidth=260, valueType=float, orientation="horizontal") self.le_step_y = oasysgui.lineEdit(self.kind_of_profile_y_box_1, self, "step_y", "Step", labelWidth=260, valueType=float, orientation="horizontal") oasysgui.lineEdit(self.kind_of_profile_y_box_1, self, "montecarlo_seed_y", "Monte Carlo initial seed", labelWidth=260, valueType=int, orientation="horizontal") self.kind_of_profile_y_box_1_1 = oasysgui.widgetBox(self.kind_of_profile_y_box_1, "", addSpace=True, orientation="vertical") oasysgui.lineEdit(self.kind_of_profile_y_box_1_1, self, "power_law_exponent_beta_y", "Beta Value", labelWidth=260, valueType=float, orientation="horizontal") self.kind_of_profile_y_box_1_2 = oasysgui.widgetBox(self.kind_of_profile_y_box_1, "", addSpace=True, orientation="vertical") self.le_correlation_length_y = oasysgui.lineEdit(self.kind_of_profile_y_box_1_2, self, "correlation_length_y", "Correlation Length", labelWidth=260, valueType=float, orientation="horizontal") gui.separator(self.kind_of_profile_y_box_1) gui.comboBox(self.kind_of_profile_y_box_1, self, "error_type_y", label="Normalization to", labelWidth=270, items=["Figure Error (nm)", "Slope Error (" + "\u03BC" + "rad)"], sendSelectedValue=False, orientation="horizontal") oasysgui.lineEdit(self.kind_of_profile_y_box_1, self, "rms_y", "Rms Value", labelWidth=260, valueType=float, orientation="horizontal") self.kind_of_profile_y_box_2 = oasysgui.widgetBox(input_box_l, "", addSpace=True, orientation="vertical", height=350) select_file_box_2 = oasysgui.widgetBox(self.kind_of_profile_y_box_2, "", addSpace=True, orientation="horizontal") self.le_heigth_profile_1D_file_name_y = oasysgui.lineEdit(select_file_box_2, self, "heigth_profile_1D_file_name_y", "1D Profile File Name", labelWidth=120, valueType=str, orientation="horizontal") gui.button(select_file_box_2, self, "...", callback=self.selectFile1D_Y) gui.comboBox(self.kind_of_profile_y_box_2, self, "delimiter_y", label="Fields delimiter", labelWidth=260, items=["Spaces", "Tabs"], sendSelectedValue=False, orientation="horizontal") oasysgui.lineEdit(self.kind_of_profile_y_box_2, self, "conversion_factor_y_x", "Conversion from file\nto workspace units(Abscissa)", labelWidth=260, valueType=float, orientation="horizontal") oasysgui.lineEdit(self.kind_of_profile_y_box_2, self, "conversion_factor_y_y", "Conversion from file\nto workspace units (Height Profile Values)", labelWidth=260, valueType=float, orientation="horizontal") gui.separator(self.kind_of_profile_y_box_2) gui.comboBox(self.kind_of_profile_y_box_2, self, "center_y", label="Center Profile in the middle of O.E.", labelWidth=300, items=["No", "Yes"], sendSelectedValue=False, orientation="horizontal") gui.comboBox(self.kind_of_profile_y_box_2, 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_2_1 = oasysgui.widgetBox(self.kind_of_profile_y_box_2, "", addSpace=False, orientation="vertical", height=70) self.modify_box_2_2 = oasysgui.widgetBox(self.kind_of_profile_y_box_2, "", addSpace=False, orientation="vertical", height=70) oasysgui.lineEdit(self.modify_box_2_2, self, "scale_factor_y", "Scale Factor", labelWidth=300, valueType=float, orientation="horizontal") self.modify_box_2_3 = oasysgui.widgetBox(self.kind_of_profile_y_box_2, "", addSpace=False, orientation="vertical", height=70) self.le_new_length = oasysgui.lineEdit(self.modify_box_2_3, self, "new_length", "New Length", labelWidth=300, valueType=float, orientation="horizontal") oasysgui.lineEdit(self.modify_box_2_3, self, "filler_value", "Filler Value (if new length > profile length) [nm]", labelWidth=300, valueType=float, orientation="horizontal") self.set_ModifyY() gui.comboBox(self.kind_of_profile_y_box_2, self, "renormalize_y", label="Renormalize to different RMS", labelWidth=260, items=["No", "Yes"], callback=self.set_KindOfProfileY, sendSelectedValue=False, orientation="horizontal") self.kind_of_profile_y_box_2_1 = oasysgui.widgetBox(self.kind_of_profile_y_box_2, "", addSpace=True, orientation="vertical") gui.comboBox(self.kind_of_profile_y_box_2_1, self, "error_type_y", label="Normalization to", labelWidth=270, items=["Figure Error (nm)", "Slope Error (" + "\u03BC" + "rad)"], sendSelectedValue=False, orientation="horizontal") oasysgui.lineEdit(self.kind_of_profile_y_box_2_1, self, "rms_y", "Rms Value", labelWidth=260, valueType=float, orientation="horizontal") self.set_KindOfProfileY() #/ --------------------------------------- input_box_w = oasysgui.widgetBox(tab_width, "Calculation Parameters", addSpace=True, orientation="vertical") gui.comboBox(input_box_w, self, "kind_of_profile_x", label="Kind of Profile", labelWidth=260, items=["Fractal", "Gaussian", "User File"], callback=self.set_KindOfProfileX, sendSelectedValue=False, orientation="horizontal") gui.separator(input_box_w) self.kind_of_profile_x_box_1 = oasysgui.widgetBox(input_box_w, "", addSpace=True, orientation="vertical", height=300) self.le_dimension_x = oasysgui.lineEdit(self.kind_of_profile_x_box_1, self, "dimension_x", "Dimensions", labelWidth=260, valueType=float, orientation="horizontal") self.le_step_x = oasysgui.lineEdit(self.kind_of_profile_x_box_1, self, "step_x", "Step", labelWidth=260, valueType=float, orientation="horizontal") oasysgui.lineEdit(self.kind_of_profile_x_box_1, self, "montecarlo_seed_x", "Monte Carlo initial seed", labelWidth=260, valueType=int, orientation="horizontal") self.kind_of_profile_x_box_1_1 = oasysgui.widgetBox(self.kind_of_profile_x_box_1, "", addSpace=True, orientation="vertical") oasysgui.lineEdit(self.kind_of_profile_x_box_1_1, self, "power_law_exponent_beta_x", "Beta Value", labelWidth=260, valueType=float, orientation="horizontal") self.kind_of_profile_x_box_1_2 = oasysgui.widgetBox(self.kind_of_profile_x_box_1, "", addSpace=True, orientation="vertical") self.le_correlation_length_x = oasysgui.lineEdit(self.kind_of_profile_x_box_1_2, self, "correlation_length_x", "Correlation Length", labelWidth=260, valueType=float, orientation="horizontal") gui.separator(self.kind_of_profile_x_box_1) gui.comboBox(self.kind_of_profile_x_box_1, self, "error_type_x", label="Normalization to", labelWidth=270, items=["Figure Error (nm)", "Slope Error (" + "\u03BC" + "rad)"], sendSelectedValue=False, orientation="horizontal") oasysgui.lineEdit(self.kind_of_profile_x_box_1, self, "rms_x", "Rms Value", labelWidth=260, valueType=float, orientation="horizontal") ##---------------------------------- self.kind_of_profile_x_box_2 = oasysgui.widgetBox(input_box_w, "", addSpace=True, orientation="vertical", height=300) select_file_box_1 = oasysgui.widgetBox(self.kind_of_profile_x_box_2, "", addSpace=True, orientation="horizontal") self.le_heigth_profile_1D_file_name_x = oasysgui.lineEdit(select_file_box_1, self, "heigth_profile_1D_file_name_x", "1D Profile File Name", labelWidth=120, valueType=str, orientation="horizontal") gui.button(select_file_box_1, self, "...", callback=self.selectFile1D_X) gui.comboBox(self.kind_of_profile_x_box_2 , self, "delimiter_x", label="Fields delimiter", labelWidth=260, items=["Spaces", "Tabs"], sendSelectedValue=False, orientation="horizontal") oasysgui.lineEdit(self.kind_of_profile_x_box_2, self, "conversion_factor_x_x", "Conversion from file\nto workspace units(Abscissa)", labelWidth=260, valueType=float, orientation="horizontal") oasysgui.lineEdit(self.kind_of_profile_x_box_2, self, "conversion_factor_x_y", "Conversion from file\nto workspace units (Height Profile Values)", labelWidth=260, valueType=float, orientation="horizontal") gui.separator(self.kind_of_profile_x_box_2) gui.comboBox(self.kind_of_profile_x_box_2, self, "center_x", label="Center Profile in the middle of O.E.", labelWidth=300, items=["No", "Yes"], sendSelectedValue=False, orientation="horizontal") gui.comboBox(self.kind_of_profile_x_box_2, self, "modify_x", label="Modify Length?", labelWidth=240, items=["No", "Rescale to new length", "Fit to new length (fill or cut)"], callback=self.set_ModifyX, sendSelectedValue=False, orientation="horizontal") self.modify_box_1_1 = oasysgui.widgetBox(self.kind_of_profile_x_box_2, "", addSpace=False, orientation="vertical", height=70) self.modify_box_1_2 = oasysgui.widgetBox(self.kind_of_profile_x_box_2, "", addSpace=False, orientation="vertical", height=70) oasysgui.lineEdit(self.modify_box_1_2, self, "scale_factor_x", "Scale Factor", labelWidth=300, valueType=float, orientation="horizontal") self.modify_box_1_3 = oasysgui.widgetBox(self.kind_of_profile_x_box_2, "", addSpace=False, orientation="vertical", height=70) self.le_new_length = oasysgui.lineEdit(self.modify_box_1_3, self, "new_length", "New Length", labelWidth=300, valueType=float, orientation="horizontal") oasysgui.lineEdit(self.modify_box_1_3, self, "filler_value", "Filler Value (if new length > profile length) [nm]", labelWidth=300, valueType=float, orientation="horizontal") self.set_ModifyX() gui.comboBox(self.kind_of_profile_x_box_2, self, "renormalize_x", label="Renormalize to different RMS", labelWidth=260, items=["No", "Yes"], callback=self.set_KindOfProfileX, sendSelectedValue=False, orientation="horizontal") self.kind_of_profile_x_box_2_1 = oasysgui.widgetBox(self.kind_of_profile_x_box_2, "", addSpace=True, orientation="vertical") gui.comboBox(self.kind_of_profile_x_box_2_1, self, "error_type_x", label="Normalization to", labelWidth=270, items=["Figure Error (nm)", "Slope Error (" + "\u03BC" + "rad)"], sendSelectedValue=False, orientation="horizontal") oasysgui.lineEdit(self.kind_of_profile_x_box_2_1, self, "rms_x", "Rms Value", labelWidth=260, valueType=float, orientation="horizontal") self.set_KindOfProfileX() #/ --------------------------------------- self.output_box = oasysgui.widgetBox(tab_input, "Outputs", addSpace=True, orientation="vertical") self.select_file_box = oasysgui.widgetBox(self.output_box, "", addSpace=True, orientation="horizontal") self.le_heigth_profile_file_name = oasysgui.lineEdit(self.select_file_box, self, "heigth_profile_file_name", "Output File Name", labelWidth=120, valueType=str, orientation="horizontal") gui.button(self.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=580) out_box.layout().addWidget(self.shadow_output) 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_zlabel("Z [nm]") self.figure_canvas = FigureCanvasQTAgg(self.figure) self.mainArea.layout().addWidget(self.figure_canvas) gui.rubber(self.mainArea) def after_change_workspace_units(self): self.si_to_user_units = 1e2 / self.workspace_units_to_cm self.axis.set_xlabel("X [" + self.workspace_units_label + "]") self.axis.set_ylabel("Y [" + self.workspace_units_label + "]") label = self.le_dimension_y.parent().layout().itemAt(0).widget() label.setText(label.text() + " [" + self.workspace_units_label + "]") label = self.le_step_y.parent().layout().itemAt(0).widget() label.setText(label.text() + " [" + self.workspace_units_label + "]") label = self.le_correlation_length_y.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_correlation_length_x.parent().layout().itemAt(0).widget() label.setText(label.text() + " [" + self.workspace_units_label + "]") def set_KindOfProfileX(self): self.kind_of_profile_x_box_1.setVisible(self.kind_of_profile_x<2) self.kind_of_profile_x_box_1_1.setVisible(self.kind_of_profile_x==0) self.kind_of_profile_x_box_1_2.setVisible(self.kind_of_profile_x==1) self.kind_of_profile_x_box_2.setVisible(self.kind_of_profile_x==2) self.kind_of_profile_x_box_2_1.setVisible(self.kind_of_profile_x==2 and self.renormalize_x==1) def set_KindOfProfileY(self): self.kind_of_profile_y_box_1.setVisible(self.kind_of_profile_y<2) self.kind_of_profile_y_box_1_1.setVisible(self.kind_of_profile_y==0) self.kind_of_profile_y_box_1_2.setVisible(self.kind_of_profile_y==1) self.kind_of_profile_y_box_2.setVisible(self.kind_of_profile_y==2) self.kind_of_profile_y_box_2_1.setVisible(self.kind_of_profile_y==2 and self.renormalize_y==1) def set_ModifyY(self): self.modify_box_2_1.setVisible(self.modify_y == 0) self.modify_box_2_2.setVisible(self.modify_y == 1) self.modify_box_2_3.setVisible(self.modify_y == 2) def set_ModifyX(self): self.modify_box_1_1.setVisible(self.modify_x == 0) self.modify_box_1_2.setVisible(self.modify_x == 1) self.modify_box_1_3.setVisible(self.modify_x == 2) def calculate_heigth_profile_ni(self): self.calculate_heigth_profile(not_interactive_mode=True) def calculate_heigth_profile(self, not_interactive_mode=False): try: sys.stdout = EmittingStream(textWritten=self.writeStdOut) self.check_fields() #### LENGTH if self.kind_of_profile_y == 2: combination = "E" if self.delimiter_y == 1: profile_1D_y_x, profile_1D_y_y = numpy.loadtxt(self.heigth_profile_1D_file_name_y, delimiter='\t', unpack=True) else: profile_1D_y_x, profile_1D_y_y = numpy.loadtxt(self.heigth_profile_1D_file_name_y, unpack=True) profile_1D_y_x *= self.conversion_factor_y_x * self.workspace_units_to_cm # to cm profile_1D_y_y *= self.conversion_factor_y_y * self.workspace_units_to_cm # to cm if self.modify_y == 2: profile_1D_y_x_temp = profile_1D_y_x profile_1D_y_y_temp = profile_1D_y_y 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 elif self.modify_y == 1: profile_1D_y_x *= self.scale_factor_y 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.rms_y * 1e-7 # from nm to cm else: rms_y = self.rms_y * 1e-6 # from urad to rad else: if self.kind_of_profile_y == 0: combination = "F" else: combination = "G" profile_1D_y_x = None profile_1D_y_y = None if self.error_type_y == profiles_simulation.FIGURE_ERROR: rms_y = self.rms_y * 1e-7 # from nm to cm else: rms_y = self.rms_y * 1e-6 # from urad to rad #### WIDTH if self.kind_of_profile_x == 2: combination += "E" if self.delimiter_x == 1: profile_1D_x_x, profile_1D_x_y = numpy.loadtxt(self.heigth_profile_1D_file_name_x, delimiter='\t', unpack=True) else: profile_1D_x_x, profile_1D_x_y = numpy.loadtxt(self.heigth_profile_1D_file_name_x, unpack=True) profile_1D_x_x *= self.conversion_factor_x_x * self.workspace_units_to_cm profile_1D_x_y *= self.conversion_factor_x_y * self.workspace_units_to_cm if self.modify_x == 2: profile_1D_x_x_temp = profile_1D_x_x profile_1D_x_y_temp = profile_1D_x_y first_coord = profile_1D_x_x_temp[0] second_coord = profile_1D_x_x_temp[1] last_coord = profile_1D_x_x_temp[-1] step = numpy.abs(second_coord - first_coord) length = numpy.abs(last_coord - first_coord) n_points_old = len(profile_1D_x_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_x_x = numpy.arange(n_added_points + n_points_old) * step profile_1D_x_y = numpy.ones(n_added_points + n_points_old) * self.filler_value * 1e-9 * self.si_to_user_units profile_1D_x_y[int(n_added_points/2) : n_points_old + int(n_added_points/2)] = profile_1D_x_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_x_x = profile_1D_x_x_temp[0 : (n_points_old - n_removed_points)] profile_1D_x_y = profile_1D_x_y_temp[(int(n_removed_points/2) - 1) : (n_points_old - int(n_removed_points/2) - 1)] else: profile_1D_x_x = profile_1D_x_x_temp profile_1D_x_y = profile_1D_x_y_temp else: profile_1D_x_x = profile_1D_x_x_temp profile_1D_x_y = profile_1D_x_y_temp elif self.modify_x == 1: profile_1D_x_x *= self.scale_factor_x if self.center_x: first_coord = profile_1D_x_x[0] last_coord = profile_1D_x_x[-1] length = numpy.abs(last_coord - first_coord) profile_1D_x_x_temp = numpy.linspace(-length/2, length/2, len(profile_1D_x_x)) profile_1D_x_x = profile_1D_x_x_temp if self.renormalize_x == 0: rms_x = None else: if self.error_type_x == profiles_simulation.FIGURE_ERROR: rms_x = self.rms_x * 1e-7 # from nm to cm else: rms_x = self.rms_x * 1e-6 # from urad to rad else: profile_1D_x_x = None profile_1D_x_y = None if self.kind_of_profile_x == 0: combination += "F" else: combination += "G" if self.error_type_x == profiles_simulation.FIGURE_ERROR: rms_x = self.rms_x * 1e-7 # from nm to cm else: rms_x = self.rms_x * 1e-6 # from urad to rad xx, yy, zz = profiles_simulation.simulate_profile_2D(combination = combination, mirror_length = self.dimension_y * self.workspace_units_to_cm, # to cm step_l = self.step_y * self.workspace_units_to_cm, # to cm random_seed_l = self.montecarlo_seed_y, error_type_l = self.error_type_y, rms_l = rms_y, power_law_exponent_beta_l = self.power_law_exponent_beta_y, correlation_length_l = self.correlation_length_y * self.workspace_units_to_cm, # to cm x_l = profile_1D_y_x, y_l = profile_1D_y_y, mirror_width = self.dimension_x * self.workspace_units_to_cm, # to cm step_w = self.step_x * self.workspace_units_to_cm, random_seed_w = self.montecarlo_seed_x, error_type_w = self.error_type_x, rms_w = rms_x, power_law_exponent_beta_w = self.power_law_exponent_beta_x, correlation_length_w = self.correlation_length_x * self.workspace_units_to_cm, # to cm x_w = profile_1D_x_x, y_w = profile_1D_x_y) self.xx = xx / self.workspace_units_to_cm # to user units self.yy = yy / self.workspace_units_to_cm # to user units self.zz = zz / self.workspace_units_to_cm # to user units self.axis.clear() x_to_plot, y_to_plot = numpy.meshgrid(self.xx, self.yy) z_to_plot = zz * 1e7 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: self.figure_canvas.draw() 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) dimension_x = self.dimension_x dimension_y = self.dimension_y if self.kind_of_profile_x == 2: #user defined dimension_x = (self.xx[-1] - self.xx[0]) if self.kind_of_profile_y == 2: #user defined dimension_y = (self.yy[-1] - self.yy[0]) self.send("PreProcessor_Data", ShadowPreProcessorData(error_profile_data_file=self.heigth_profile_file_name, error_profile_x_dim=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): if self.kind_of_profile_y < 2: self.dimension_y = congruence.checkStrictlyPositiveNumber(self.dimension_y, "Dimension Y") self.step_y = congruence.checkStrictlyPositiveNumber(self.step_y, "Step Y") if self.kind_of_profile_y == 0: self.power_law_exponent_beta_y = congruence.checkPositiveNumber(self.power_law_exponent_beta_y, "Beta Value Y") if self.kind_of_profile_y == 1: self.correlation_length_y = congruence.checkStrictlyPositiveNumber(self.correlation_length_y, "Correlation Length Y") self.rms_y = congruence.checkPositiveNumber(self.rms_y, "Rms Y") self.montecarlo_seed_y = congruence.checkPositiveNumber(self.montecarlo_seed_y, "Monte Carlo initial seed y") else: congruence.checkFile(self.heigth_profile_1D_file_name_y) self.conversion_factor_y_x = congruence.checkStrictlyPositiveNumber(self.conversion_factor_y_x, "Conversion from file to workspace units(Abscissa)") self.conversion_factor_y_y = congruence.checkStrictlyPositiveNumber(self.conversion_factor_y_y, "Conversion from file to workspace units (Height Profile Values)") if self.renormalize_y == 1: self.rms_y = congruence.checkPositiveNumber(self.rms_y, "Rms Y") if self.kind_of_profile_x < 2: self.dimension_x = congruence.checkStrictlyPositiveNumber(self.dimension_x, "Dimension X") self.step_x = congruence.checkStrictlyPositiveNumber(self.step_x, "Step X") if self.kind_of_profile_x == 0: self.power_law_exponent_beta_x = congruence.checkPositiveNumber(self.power_law_exponent_beta_x, "Beta Value X") if self.kind_of_profile_x == 1: self.correlation_length_x = congruence.checkStrictlyPositiveNumber(self.correlation_length_x, "Correlation Length X") self.rms_x = congruence.checkPositiveNumber(self.rms_x, "Rms X") self.montecarlo_seed_x = congruence.checkPositiveNumber(self.montecarlo_seed_x, "Monte Carlo initial seed X") else: congruence.checkFile(self.heigth_profile_1D_file_name_x) self.conversion_factor_x_x = congruence.checkStrictlyPositiveNumber(self.conversion_factor_x_x, "Conversion from file to workspace units(Abscissa)") self.conversion_factor_x_y = congruence.checkStrictlyPositiveNumber(self.conversion_factor_x_y, "Conversion from file to workspace units (Height Profile Values)") if self.renormalize_x == 1: self.rms_x = congruence.checkPositiveNumber(self.rms_x, "Rms X") 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 selectFile1D_X(self): self.le_heigth_profile_1D_file_name_x.setText(oasysgui.selectFileFromDialog(self, self.heigth_profile_1D_file_name_x, "Select 1D Height Profile File", file_extension_filter="Data Files (*.dat *.txt)")) def selectFile1D_Y(self): self.le_heigth_profile_1D_file_name_y.setText(oasysgui.selectFileFromDialog(self, self.heigth_profile_1D_file_name_y, "Select 1D Height Profile File", file_extension_filter="Data Files (*.dat *.txt)")) 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)"))
class QPyShell(QWidget): """QPyShell - a Qt based python command shell based on code.InteractiveInterpreter. Because it catches stdout and stderr there can be only one active instance of this class. Make sure initInterpreter() and exitInterpreter() is called! """ activeInstance = None def __init__(self, parent=None): QWidget.__init__(self, parent) if parent: self.standalone = False else: self.standalone = True self.setWindowTitle(QCoreApplication.translate("QPyShell", "QPyShell - a simple python shell widget for Qt")) self.mainLayout = QVBoxLayout(self) self.outputBrowser = QTextEdit(self) self.outputBrowser.setMinimumSize(QSize(100,100)) self.outputBrowser.setReadOnly(True) self.mainLayout.addWidget(self.outputBrowser) self.clLayout = QHBoxLayout() self.mainLayout.addLayout(self.clLayout) self.promptLabel = QLabel() self.promptLabel.setText(">>>") self.clLayout.addWidget(self.promptLabel) self.lineInput = QLineEdit() self.lineInput.setToolTip(QCoreApplication.translate('QPyShell', 'The python commandline: enter code her')) self.clLayout.addWidget(self.lineInput) self.enterButton = QToolButton(self) self.enterButton.setText(QCoreApplication.translate("QPyShell", "Enter")) self.enterButton.setToolTip(QCoreApplication.translate('QPyShell', 'This button or [Enter] executes the command')) self.enterButton.setIcon(QIcon(QPixmap(enterXPM))) self.clLayout.addWidget(self.enterButton) self.clLayout.addSpacing(8) self.clearButton = QToolButton(self) self.clearButton.setText(QCoreApplication.translate("QPyShell", "Clear")) self.clearButton.setToolTip(QCoreApplication.translate('QPyShell', 'Clear the output window')) self.clearButton.setIcon(QIcon(QPixmap(clearXPM))) self.clLayout.addWidget(self.clearButton) self.saveButton = QToolButton(self) self.saveButton.setText(QCoreApplication.translate("QPyShell", "Save ...")) self.saveButton.setToolTip(QCoreApplication.translate('QPyShell', 'Save the contents of the output window')) self.saveButton.setIcon(QIcon(QPixmap(saveXPM))) self.clLayout.addWidget(self.saveButton) self.printButton = QToolButton(self) self.printButton.setText(QCoreApplication.translate("QPyShell", "Print")) self.printButton.setToolTip(QCoreApplication.translate('QPyShell', 'Print the contents of the output window')) self.printButton.setIcon(QIcon(QPixmap(printXPM))) self.clLayout.addWidget(self.printButton) self.history = [] self.historyFile = None self.history_i = -1 self.cmdBuffer = [] self.showCompletionLimit = 100 self.interpreter = None self.old_displayhook = None self.cursor = QTextCursor(self.outputBrowser.document()) self.outputBrowser.setTextCursor(self.cursor) self.outputBrowser.append(greeting) self.setTabOrder(self.lineInput, self.outputBrowser) self.setTabOrder(self.outputBrowser, self.enterButton) self.setTabOrder(self.enterButton, self.saveButton) self.setTabOrder(self.saveButton, self.clearButton) self.connect(self.enterButton, SIGNAL("pressed()"), self.run) self.connect(self.saveButton, SIGNAL("pressed()"), self.saveContents) self.connect(self.printButton, SIGNAL("pressed()"), self.printContents) self.connect(self.clearButton, SIGNAL("pressed()"), self.outputBrowser.clear) def initInterpreter(self, loc=None, greet=greeting, historyFile=None): if QPyShell.activeInstance: raise Exception(QCoreApplication.translate("QPyShell", "QPyShell: There can be only one highlander... sorry, I mean one active QPyShell widget!")) QPyShell.activeInstance = self self.loadHistoryFile(historyFile) self.interpreter = InteractiveInterpreter(loc) self.completer = Completer(loc) self.old_stdout = sys.stdout self.old_stderr = sys.stderr sys.stdout = DummyFileW(self.write) sys.stderr = sys.stdout # there's a strange problem with gettext and interactive interpreters # gettext's "_"" will be overwritten by the standard sys.displayhook... self.old_displayhook = sys.displayhook sys.displayhook = mydisplayhook def loadHistoryFile(self, historyFile): self.historyFile = historyFile if historyFile and os.path.exists(historyFile): lines = open(historyFile, 'r').read().split(os.linesep) self.history = [l for l in lines if not l.startswith('#')] def saveHistoryFile(self): if self.historyFile: h = self.history if len(h) > 100: h = h[:100] h.insert(0, unicode(QCoreApplication.translate('QPyShell', '# this is the command history of the QPyShell'))) open(self.historyFile, 'w').write(os.linesep.join(h)) def exitInterpreter(self, loc=None): sys.stdout = self.old_stdout sys.stderr = self.old_stderr self.saveHistoryFile() del self.interpreter self.interpreter = None sys.displayhook = self.old_displayhook QPyShell.ativeInstance = None def run(self): if not self.interpreter: raise Exception(QCoreApplication.translate("QPyShell", "No interpreter found! You need to call QPyShell.initInterpreter() first!")) line = unicode(self.lineInput.text()) self.lineInput.clear() if line: if (not self.history) or line != self.history[0]: # no consecutive identical entries self.history.insert(0, line) self.history_i = -1 self.cursor.movePosition(QTextCursor.End) if not self.cmdBuffer: self.cursor.insertHtml('<br><b>|>>> %s</b><br>' % formatPyLine(line)) else: self.cursor.insertHtml('<br><b>|. . . %s</b><br>' % formatPyLine(line)) self.cursor.movePosition(QTextCursor.End) self.outputBrowser.ensureCursorVisible() self.cmdBuffer.append(line) more = self.interpreter.runsource('\n'.join(self.cmdBuffer)) if more: self.promptLabel.setText('...') else: self.cmdBuffer = [] self.promptLabel.setText('>>>') def appendHtml(self, txt): self.cursor.movePosition(QTextCursor.End) self.cursor.insertHtml(txt) self.cursor.movePosition(QTextCursor.End) self.outputBrowser.ensureCursorVisible() def appendText(self, txt): self.cursor.movePosition(QTextCursor.End) self.outputBrowser.insertPlainText(txt) self.cursor.movePosition(QTextCursor.End) self.outputBrowser.ensureCursorVisible() write = appendText def keyPressEvent(self, event): key = event.key() mod = event.modifiers() if key == Qt.Key_Up and self.history: self.history_i = min(self.history_i+1, len(self.history)-1) self.lineInput.setText(self.history[self.history_i]) elif key == Qt.Key_Down and self.history: self.history_i = max(self.history_i-1, -1) if self.history_i >= 0: self.lineInput.setText(self.history[self.history_i]) else: self.lineInput.setText('') elif key == Qt.Key_Enter or key == Qt.Key_Return: if mod & Qt.ShiftModifier: self.complete() else: self.run() elif key == Qt.Key_Escape: txt, r = QInputDialog.getItem(self, QCoreApplication.translate("QPyShell", "Command line history"), QCoreApplication.translate("QPyShell", "Please select a history item:"), self.history, 0, False) if r and txt: self.lineInput.setText(txt) elif self.standalone and key == Qt.Key_Print: self.printContents() elif self.standalone and key == Qt.Key_Q and (mod & Qt.ControlModifier): self.close() else: QWidget.keyPressEvent(self, event) def closeEvent(self, event): if self.standalone: self.exitInterpreter() QWidget.closeEvent(self, event) def printContents(self, printer=None): if not printer: printer = QPrinter() dialog = QPrintDialog(printer, self) dialog.setWindowTitle(QCoreApplication.translate("QPyShell", "Print Document")) if dialog.exec_() != QDialog.Accepted: return self.outputBrowser.document().print_(printer) def saveContents(self, fileName=None): if not fileName: fileTypes = {'Text':('txt',), 'HTML':('htm', 'html')} filters = ';;'.join(['%s (%s)' % (k, ' '.join(['*.'+e for e in v])) for k, v in fileTypes.items()]) dlg = QFileDialog(self, QCoreApplication.translate('QPyShell', 'Select name of file to save'), os.getcwd(), filters) dlg.setFileMode(QFileDialog.AnyFile) dlg.setAcceptMode(QFileDialog.AcceptSave) if dlg.exec_() != QDialog.Accepted: return tmp = unicode(dlg.selectedFilter()) fileType = tmp[:tmp.find('(')-1] dlg.setDefaultSuffix(fileTypes[fileType][0]) files = dlg.selectedFiles() if not files: return fileName = unicode(files[0]) if fileType == 'Text': txt = self.outputBrowser.toPlainText() elif fileType == 'HTML': txt = self.outputBrowser.toHtml() else: raise IOError('Unknown FileType: %s' % fileType) try: open(fileName, 'w').write(txt) except IOError: QMessageBox.critical(self, QCoreApplication.translate('QPyShell', 'Could not save file!'), QCoreApplication.translate('QPyShell', 'Writing failed! Make sure you have write permissions!')) def complete(self): """ a very simple, quick and dirty completion of identifiers in the namespace """ # FIXME: fertig machen! txt = unicode(self.lineInput.text()) cur = self.lineInput.cursorPosition() s = cur while s>0 and txt[s-1] in identChars: s -= 1 try: completions = self.completer.matches(txt[s:cur]) except: return if not completions: return n_comp = len(completions) if n_comp == 1: comp = completions.pop() self.lineInput.insert(comp[cur-s:]) elif n_comp < self.showCompletionLimit: tmp = list(completions) tmp.sort() self.appendHtml('<font color="#0000ff">[%s]</font>' % ', '.join(tmp)) # get common prefix ... stolen from the python cookbook pref = tmp[0][:([min([x[0]==elem for elem in x]) for x in zip(*tmp)]+[0]).index(0)] if len(pref) > (cur-s): self.lineInput.insert(pref[cur-s:]) else: self.appendHtml(unicode(QCoreApplication.translate("QPyShell", '<font color="#0000ff">[Too many completions: %d]</font>')) % n_comp)
class OWxsh_bragg(OWWidget): name = "Bragg" id = "xsh_bragg" description = "Calculation of crystal diffraction profile" icon = "icons/bragg.png" author = "create_widget.py" maintainer_email = "*****@*****.**" priority = 1 category = "" keywords = ["oasys", "bragg"] outputs = [{"name":"PreProcessor_Data", "type":ShadowPreProcessorData, "doc":"PreProcessor Data", "id":"PreProcessor_Data"}] want_main_area = False DESCRIPTOR = Setting(0) H_MILLER_INDEX = Setting(1) K_MILLER_INDEX = Setting(1) L_MILLER_INDEX = Setting(1) TEMPERATURE_FACTOR = Setting(1.0) E_MIN = Setting(5000.0) E_MAX = Setting(15000.0) E_STEP = Setting(100.0) SHADOW_FILE = Setting("bragg.dat") crystals = [ "Si", "Si_NIST", "Si2", "Ge", "Diamond", "GaAs", "GaSb", "GaP", "InAs", "InP", "InSb", "SiC", "NaCl", "CsF", "LiF", "KCl", "CsCl", "Be", "Graphite", "PET", "Beryl", "KAP", "RbAP", "TlAP", "Muscovite", "AlphaQuartz", "Copper", "LiNbO3", "Platinum", "Gold", "Sapphire", "LaB6", "LaB6_NIST", "KTP", "AlphaAlumina", "Aluminum", "Iron", "Titanium" ] def __init__(self): super().__init__() self.runaction = widget.OWAction("Compute", self) self.runaction.triggered.connect(self.compute) self.addAction(self.runaction) self.setFixedWidth(500) self.setFixedHeight(520) idx = -1 gui.separator(self.controlArea) box0 = oasysgui.widgetBox(self.controlArea, "",orientation="horizontal") #widget buttons: compute, set defaults, help button = gui.button(box0, self, "Compute", callback=self.compute) button.setFixedHeight(45) button = gui.button(box0, self, "Defaults", callback=self.defaults) button.setFixedHeight(45) button = gui.button(box0, self, "Help", callback=self.help1) button.setFixedHeight(45) gui.separator(self.controlArea) #widget index 0 idx += 1 box = oasysgui.widgetBox(self.controlArea, "Crystal Parameters", orientation="vertical") gui.comboBox(box, self, "DESCRIPTOR", label=self.unitLabels()[idx], addSpace=True, items=self.crystals, sendSelectedValue=False, valueType=int, orientation="horizontal", labelWidth=350) self.show_at(self.unitFlags()[idx], box) #widget index 1 idx += 1 box_miller = oasysgui.widgetBox(box, "", orientation = "horizontal") oasysgui.lineEdit(box_miller, self, "H_MILLER_INDEX", label="Miller Indices [h k l]", addSpace=True, valueType=int, validator=QIntValidator(), labelWidth=350, orientation="horizontal") self.show_at(self.unitFlags()[idx], box_miller) #widget index 2 idx += 1 oasysgui.lineEdit(box_miller, self, "K_MILLER_INDEX", addSpace=True, valueType=int, validator=QIntValidator()) self.show_at(self.unitFlags()[idx], box) #widget index 3 idx += 1 oasysgui.lineEdit(box_miller, self, "L_MILLER_INDEX", addSpace=True, valueType=int, validator=QIntValidator(), orientation="horizontal") self.show_at(self.unitFlags()[idx], box) gui.separator(box) #widget index 4 idx += 1 oasysgui.lineEdit(box, self, "TEMPERATURE_FACTOR", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal") self.show_at(self.unitFlags()[idx], box) #widget index 5 idx += 1 oasysgui.lineEdit(box, self, "E_MIN", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal") self.show_at(self.unitFlags()[idx], box) #widget index 6 idx += 1 oasysgui.lineEdit(box, self, "E_MAX", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal") self.show_at(self.unitFlags()[idx], box) #widget index 7 idx += 1 oasysgui.lineEdit(box, self, "E_STEP", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal") self.show_at(self.unitFlags()[idx], box) #widget index 8 idx += 1 box_2 = oasysgui.widgetBox(box, "", addSpace=True, orientation="horizontal") self.le_SHADOW_FILE = oasysgui.lineEdit(box_2, self, "SHADOW_FILE", label=self.unitLabels()[idx], addSpace=True, labelWidth=180, orientation="horizontal") gui.button(box_2, self, "...", callback=self.selectFile) self.show_at(self.unitFlags()[idx], box) self.shadow_output = QTextEdit() self.shadow_output.setReadOnly(True) out_box = oasysgui.widgetBox(self.controlArea, "System Output", addSpace=True, orientation="horizontal", height=150) out_box.layout().addWidget(self.shadow_output) self.process_showers() gui.rubber(self.controlArea) def unitLabels(self): return ['Crystal descriptor','H miller index','K miller index','L miller index','Temperature factor','Minimum energy [eV]','Maximum energy [eV]','Energy step [eV]','File name (for SHADOW)'] def unitFlags(self): return ['True','True','True','True','True','True','True','True','True'] def selectFile(self): self.le_SHADOW_FILE.setText(oasysgui.selectFileFromDialog(self, self.SHADOW_FILE, "Select Output File")) def compute(self): try: sys.stdout = EmittingStream(textWritten=self.writeStdOut) self.checkFields() tmp = bragg(interactive=False, DESCRIPTOR=self.crystals[self.DESCRIPTOR], H_MILLER_INDEX=self.H_MILLER_INDEX, K_MILLER_INDEX=self.K_MILLER_INDEX, L_MILLER_INDEX=self.L_MILLER_INDEX, TEMPERATURE_FACTOR=self.TEMPERATURE_FACTOR, E_MIN=self.E_MIN, E_MAX=self.E_MAX, E_STEP=self.E_STEP, SHADOW_FILE=congruence.checkFileName(self.SHADOW_FILE)) self.send("PreProcessor_Data", ShadowPreProcessorData(bragg_data_file=self.SHADOW_FILE)) except Exception as exception: QMessageBox.critical(self, "Error", str(exception), QMessageBox.Ok) def checkFields(self): if type(self.DESCRIPTOR) == str: # back compatibility with old version try: self.DESCRIPTOR = self.crystals.index(self.DESCRIPTOR) except: self.DESCRIPTOR = 0 self.H_MILLER_INDEX = congruence.checkNumber(self.H_MILLER_INDEX, "H miller index") self.K_MILLER_INDEX = congruence.checkNumber(self.K_MILLER_INDEX, "K miller index") self.L_MILLER_INDEX = congruence.checkNumber(self.L_MILLER_INDEX, "L miller index") self.TEMPERATURE_FACTOR = congruence.checkNumber(self.TEMPERATURE_FACTOR, "Temperature factor") self.E_MIN = congruence.checkPositiveNumber(self.E_MIN , "Minimum energy") self.E_MAX = congruence.checkStrictlyPositiveNumber(self.E_MAX , "Maximum Energy") self.E_STEP = congruence.checkStrictlyPositiveNumber(self.E_STEP, "Energy step") if self.E_MIN > self.E_MAX: raise Exception("From Energy cannot be bigger than To Energy") congruence.checkDir(self.SHADOW_FILE) def defaults(self): self.resetSettings() self.compute() return def help1(self): print("help pressed.") try: xoppy_doc('xsh_bragg') except: pass 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()
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()
class OWxsh_prerefl(OWWidget): name = "PreRefl" id = "xsh_prerefl" description = "Calculation of mirror reflectivity profile" icon = "icons/prerefl.png" author = "create_widget.py" maintainer_email = "*****@*****.**" priority = 2 category = "" keywords = ["xoppy", "xsh_prerefl"] outputs = [{"name":"PreProcessor_Data", "type":ShadowPreProcessorData, "doc":"PreProcessor Data", "id":"PreProcessor_Data"}] want_main_area = False SYMBOL = Setting("SiC") DENSITY = Setting(3.217) SHADOW_FILE = Setting("reflec.dat") E_MIN = Setting(100.0) E_MAX = Setting(20000.0) E_STEP = Setting(100.0) def __init__(self): super().__init__() self.runaction = widget.OWAction("Compute", self) self.runaction.triggered.connect(self.compute) self.addAction(self.runaction) self.setFixedWidth(500) self.setFixedHeight(485) gui.separator(self.controlArea) box0 = gui.widgetBox(self.controlArea, "",orientation="horizontal") #widget buttons: compute, set defaults, help button = gui.button(box0, self, "Compute", callback=self.compute) button.setFixedHeight(45) button = gui.button(box0, self, "Defaults", callback=self.defaults) button.setFixedHeight(45) button = gui.button(box0, self, "Help", callback=self.help1) button.setFixedHeight(45) gui.separator(self.controlArea) box = oasysgui.widgetBox(self.controlArea, "Reflectivity Parameters", orientation="vertical") idx = -1 #widget index 0 idx += 1 oasysgui.lineEdit(box, self, "SYMBOL", label=self.unitLabels()[idx], addSpace=True, labelWidth=350, orientation="horizontal", callback=self.set_Density) self.show_at(self.unitFlags()[idx], box) #widget index 1 idx += 1 oasysgui.lineEdit(box, self, "DENSITY", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal") self.show_at(self.unitFlags()[idx], box) #widget index 2 idx += 1 box_2 = oasysgui.widgetBox(box, "", addSpace=True, orientation="horizontal") self.le_SHADOW_FILE = oasysgui.lineEdit(box_2, self, "SHADOW_FILE", label=self.unitLabels()[idx], addSpace=True, labelWidth=180, orientation="horizontal") gui.button(box_2, self, "...", callback=self.selectFile) self.show_at(self.unitFlags()[idx], box) #widget index 3 idx += 1 oasysgui.lineEdit(box, self, "E_MIN", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal") self.show_at(self.unitFlags()[idx], box) #widget index 4 idx += 1 oasysgui.lineEdit(box, self, "E_MAX", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal") self.show_at(self.unitFlags()[idx], box) #widget index 5 idx += 1 oasysgui.lineEdit(box, self, "E_STEP", label=self.unitLabels()[idx], addSpace=True, valueType=float, validator=QDoubleValidator(), labelWidth=350, orientation="horizontal") self.show_at(self.unitFlags()[idx], box) self.process_showers() self.shadow_output = QTextEdit() self.shadow_output.setReadOnly(True) out_box = oasysgui.widgetBox(self.controlArea, "System Output", addSpace=True, orientation="horizontal", height=150) out_box.layout().addWidget(self.shadow_output) gui.rubber(self.controlArea) def unitLabels(self): return ['Element/Compound formula','Density [ g/cm3 ]','File for SHADOW (trace):','Minimum energy [eV]','Maximum energy [eV]','Energy step [eV]'] def unitFlags(self): return ['True','True','True','True','True','True'] def selectFile(self): self.le_SHADOW_FILE.setText(oasysgui.selectFileFromDialog(self, self.SHADOW_FILE, "Select Output File", file_extension_filter="Data Files (*.dat)")) def set_Density(self): if not self.SYMBOL is None: if not self.SYMBOL.strip() == "": self.SYMBOL = self.SYMBOL.strip() self.DENSITY = ShadowPhysics.getMaterialDensity(self.SYMBOL) def compute(self): try: sys.stdout = EmittingStream(textWritten=self.writeStdOut) self.checkFields() tmp = prerefl(interactive=False, SYMBOL=self.SYMBOL, DENSITY=self.DENSITY, FILE=congruence.checkFileName(self.SHADOW_FILE), E_MIN=self.E_MIN, E_MAX=self.E_MAX, E_STEP=self.E_STEP) self.send("PreProcessor_Data", ShadowPreProcessorData(prerefl_data_file=self.SHADOW_FILE)) except Exception as exception: QMessageBox.critical(self, "Error", str(exception), QMessageBox.Ok) def checkFields(self): self.SYMBOL = ShadowPhysics.checkCompoundName(self.SYMBOL) self.DENSITY = congruence.checkStrictlyPositiveNumber(self.DENSITY, "Density") self.E_MIN = congruence.checkPositiveNumber(self.E_MIN , "Minimum Energy") self.E_MAX = congruence.checkStrictlyPositiveNumber(self.E_MAX , "Maximum Energy") self.E_STEP = congruence.checkStrictlyPositiveNumber(self.E_STEP, "Energy step") if self.E_MIN > self.E_MAX: raise Exception("Minimum Energy cannot be bigger than Maximum Energy") congruence.checkDir(self.SHADOW_FILE) def defaults(self): self.resetSettings() self.compute() return def help1(self): print("help pressed.") xoppy_doc('xsh_prerefl') 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()
class OWVlsPgmCoefficientsCalculator(OWWidget): name = "VlsPgmCoefficientsCalculator" id = "VlsPgmCoefficientsCalculator" description = "Calculation of coefficients for VLS PGM" icon = "icons/vls_pgm.png" author = "Luca Rebuffi" maintainer_email = "*****@*****.**" priority = 10 category = "" keywords = ["oasys", "vls", "pgm"] outputs = [ { "name": "PreProcessor_Data", "type": ShadowPreProcessorData, "doc": "PreProcessor Data", "id": "PreProcessor_Data", } ] want_main_area = False r_a = Setting(0.0) r_b = Setting(0.0) k = Setting(1000) h = Setting(20) units_in_use = Setting(0) photon_wavelength = Setting(25.0) photon_energy = Setting(500.0) c = Setting(1.2) grating_diffraction_order = Setting(-1) new_units_in_use = Setting(0) new_photon_wavelength = Setting(25.0) new_photon_energy = Setting(500.0) def __init__(self): super().__init__() self.runaction = widget.OWAction("Compute", self) self.runaction.triggered.connect(self.compute) self.addAction(self.runaction) self.setFixedWidth(500) self.setFixedHeight(520) gui.separator(self.controlArea) box0 = oasysgui.widgetBox(self.controlArea, "", orientation="horizontal") # widget buttons: compute, set defaults, help button = gui.button(box0, self, "Compute", callback=self.compute) button.setFixedHeight(45) button = gui.button(box0, self, "Defaults", callback=self.defaults) button.setFixedHeight(45) tabs_setting = oasysgui.tabWidget(self.controlArea) tab_step_1 = oasysgui.createTabPage(tabs_setting, "Line Density") tab_step_2 = oasysgui.createTabPage(tabs_setting, "Angles") box = oasysgui.widgetBox(tab_step_1, "VLS-PGM Parameters", orientation="vertical") self.le_r_a = oasysgui.lineEdit( box, self, "r_a", "Distance Source-Grating", labelWidth=260, valueType=float, orientation="horizontal" ) self.le_r_b = oasysgui.lineEdit( box, self, "r_b", "Distance Grating-Exit Slits", labelWidth=260, valueType=float, orientation="horizontal" ) self.le_h = oasysgui.lineEdit( box, self, "h", "Vertical Distance Mirror-Grating", labelWidth=260, valueType=float, orientation="horizontal", ) self.le_k = oasysgui.lineEdit( box, self, "k", "Line Density (0th coeff.)", labelWidth=260, valueType=float, orientation="horizontal" ) gui.separator(box) box_2 = oasysgui.widgetBox(tab_step_1, "Grating Design Parameters", orientation="vertical") gui.comboBox( box_2, self, "units_in_use", label="Units in use", labelWidth=260, items=["eV", "Angstroms"], callback=self.set_UnitsInUse, sendSelectedValue=False, orientation="horizontal", ) self.autosetting_box_units_1 = oasysgui.widgetBox(box_2, "", addSpace=False, orientation="vertical") oasysgui.lineEdit( self.autosetting_box_units_1, self, "photon_energy", "Photon energy [eV]", labelWidth=260, valueType=float, orientation="horizontal", ) self.autosetting_box_units_2 = oasysgui.widgetBox(box_2, "", addSpace=False, orientation="vertical") oasysgui.lineEdit( self.autosetting_box_units_2, self, "photon_wavelength", "Wavelength [Å]", labelWidth=260, valueType=float, orientation="horizontal", ) self.set_UnitsInUse() oasysgui.lineEdit( box_2, self, "c", "C factor for optimized energy", labelWidth=260, valueType=float, orientation="horizontal" ) oasysgui.lineEdit( box_2, self, "grating_diffraction_order", "Diffraction Order (- for inside orders)", labelWidth=260, valueType=int, orientation="horizontal", ) ################################## box_3 = oasysgui.widgetBox(tab_step_2, "Ray-Tracing Parameter", orientation="vertical") gui.comboBox( box_3, self, "new_units_in_use", label="Units in use", labelWidth=260, items=["eV", "Angstroms"], callback=self.set_UnitsInUse2, sendSelectedValue=False, orientation="horizontal", ) self.autosetting_box_units_3 = oasysgui.widgetBox(box_3, "", addSpace=False, orientation="vertical") oasysgui.lineEdit( self.autosetting_box_units_3, self, "new_photon_energy", "New photon energy [eV]", labelWidth=260, valueType=float, orientation="horizontal", ) self.autosetting_box_units_4 = oasysgui.widgetBox(box_3, "", addSpace=False, orientation="vertical") oasysgui.lineEdit( self.autosetting_box_units_4, self, "new_photon_wavelength", "New wavelength [Å]", labelWidth=260, valueType=float, orientation="horizontal", ) self.set_UnitsInUse2() self.shadow_output = QTextEdit() self.shadow_output.setReadOnly(True) out_box = oasysgui.widgetBox( self.controlArea, "System Output", addSpace=True, orientation="horizontal", height=150 ) out_box.layout().addWidget(self.shadow_output) gui.rubber(self.controlArea) def after_change_workspace_units(self): label = self.le_r_a.parent().layout().itemAt(0).widget() label.setText(label.text() + " [" + self.workspace_units_label + "]") label = self.le_r_b.parent().layout().itemAt(0).widget() label.setText(label.text() + " [" + self.workspace_units_label + "]") label = self.le_k.parent().layout().itemAt(0).widget() label.setText(label.text() + " [Lines/" + self.workspace_units_label + "]") def set_UnitsInUse(self): self.autosetting_box_units_1.setVisible(self.units_in_use == 0) self.autosetting_box_units_2.setVisible(self.units_in_use == 1) def set_UnitsInUse2(self): self.autosetting_box_units_3.setVisible(self.new_units_in_use == 0) self.autosetting_box_units_4.setVisible(self.new_units_in_use == 1) def compute(self): try: self.shadow_output.setText("") sys.stdout = EmittingStream(textWritten=self.writeStdOut) self.checkFields() m = -self.grating_diffraction_order if self.units_in_use == 0: _lambda = ShadowPhysics.getWavelengthFromEnergy(self.photon_energy) / self.workspace_units_to_m * 1e-10 elif self.units_in_use == 1: _lambda = self.photon_wavelength / self.workspace_units_to_m * 1e-10 sin_alpha = (-m * self.k * _lambda / (self.c ** 2 - 1)) + numpy.sqrt( 1 + (m * m * self.c * self.c * self.k * self.k * _lambda * _lambda) / ((self.c ** 2 - 1) ** 2) ) alpha = numpy.arcsin(sin_alpha) beta = numpy.arcsin(sin_alpha - m * self.k * _lambda) _beta = numpy.arccos(self.c * numpy.cos(alpha)) print("Lambda:", _lambda, self.workspace_units_label) print("ALPHA:", numpy.degrees(alpha), "deg") print("BETA:", numpy.degrees(beta), numpy.degrees(_beta), "deg") b2 = (((numpy.cos(alpha) ** 2) / self.r_a) + ((numpy.cos(beta) ** 2) / self.r_b)) / ( -2 * m * self.k * _lambda ) b3 = ( (numpy.sin(alpha) * numpy.cos(alpha) ** 2) / self.r_a ** 2 - (numpy.sin(beta) * numpy.cos(beta) ** 2) / self.r_b ** 2 ) / (-2 * m * self.k * _lambda) b4 = ( ((4 * numpy.sin(alpha) ** 2 - numpy.cos(alpha) ** 2) * numpy.cos(alpha) ** 2) / self.r_a ** 3 + ((4 * numpy.sin(beta) ** 2 - numpy.cos(beta) ** 2) * numpy.cos(beta) ** 2) / self.r_b ** 3 ) / (-8 * m * self.k * _lambda) print("\nb2", b2) print("b3", b3) print("b4", b4) shadow_coeff_0 = self.k shadow_coeff_1 = -2 * self.k * b2 shadow_coeff_2 = 3 * self.k * b3 shadow_coeff_3 = -4 * self.k * b4 print("\nshadow_coeff_0", shadow_coeff_0) print("shadow_coeff_1", shadow_coeff_1) print("shadow_coeff_2", shadow_coeff_2) print("shadow_coeff_3", shadow_coeff_3) ############################################ # # 1 - in case of mirror recalculate real ray tracing distance (r_a') from initial r_a and vertical distance # between grating and mirror (h) # gamma = (alpha + beta) / 2 d_source_to_mirror = self.r_a - (self.h / numpy.abs(numpy.tan(numpy.pi - 2 * gamma))) d_mirror_to_grating = self.h / numpy.abs(numpy.sin(numpy.pi - 2 * gamma)) r_a_first = d_source_to_mirror + d_mirror_to_grating print("\ngamma", numpy.degrees(gamma)) print("d_source_to_mirror", d_source_to_mirror, self.workspace_units_label) print("d_mirror_to_grating", d_mirror_to_grating, self.workspace_units_label) print("r_a_first", r_a_first, self.workspace_units_label) ############################################ if self.new_units_in_use == 0: new_lambda = ( ShadowPhysics.getWavelengthFromEnergy(self.new_photon_energy) / self.workspace_units_to_m * 1e-10 ) elif self.new_units_in_use == 1: new_lambda = self.new_photon_wavelength / self.workspace_units_to_m * 1e-10 r = self.r_b / r_a_first A0 = self.k * new_lambda A2 = self.k * new_lambda * self.r_b * b2 new_c_num = ( 2 * A2 + 4 * (A2 / A0) ** 2 + (4 + 2 * A2 - A0 ** 2) * r - 4 * (A2 / A0) * numpy.sqrt((1 + r) ** 2 + 2 * A2 * (1 + r) - r * A0 ** 2) ) new_c_den = -4 + A0 ** 2 - 4 * A2 + 4 * (A2 / A0) ** 2 new_c = numpy.sqrt(new_c_num / new_c_den) new_sin_alpha = (-m * self.k * new_lambda / (new_c ** 2 - 1)) + numpy.sqrt( 1 + (m * m * new_c * new_c * self.k * self.k * new_lambda * new_lambda) / ((new_c ** 2 - 1) ** 2) ) new_alpha = numpy.arcsin(new_sin_alpha) new_beta = numpy.arcsin(new_sin_alpha - m * self.k * new_lambda) _new_beta = numpy.arccos(new_c * numpy.cos(new_alpha)) print("New Lambda:", new_lambda, self.workspace_units_label) print("New C:", new_c) print("NEW ALPHA:", numpy.degrees(new_alpha), "deg") print("NEW BETA:", numpy.degrees(new_beta), numpy.degrees(_new_beta), "deg") gamma = (new_alpha + new_beta) / 2 d_source_to_mirror = self.r_a - (self.h / numpy.abs(numpy.tan(numpy.pi - 2 * gamma))) d_mirror_to_grating = self.h / numpy.abs(numpy.sin(numpy.pi - 2 * gamma)) r_a_first = d_source_to_mirror + d_mirror_to_grating print("\ngamma", numpy.degrees(gamma)) print("d_source_to_mirror", d_source_to_mirror, self.workspace_units_label) print("d_mirror_to_grating", d_mirror_to_grating, self.workspace_units_label) print("r_a_first", r_a_first, self.workspace_units_label) self.send("PreProcessor_Data", ShadowPreProcessorData()) except Exception as exception: QMessageBox.critical(self, "Error", str(exception), QMessageBox.Ok) def checkFields(self): self.r_a = congruence.checkPositiveNumber(self.r_a, "Distance Source-Grating") self.r_b = congruence.checkPositiveNumber(self.r_b, "Distance Grating-Exit Slits") self.k = congruence.checkStrictlyPositiveNumber(self.k, "Line Densityg") if self.units_in_use == 0: self.photon_energy = congruence.checkPositiveNumber(self.photon_energy, "Photon Energy") elif self.units_in_use == 1: self.photon_wavelength = congruence.checkPositiveNumber(self.photon_wavelength, "Photon Wavelength") def defaults(self): self.resetSettings() 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()
class RRepositoryBrowser(QDialog): def __init__(self, pipe, parent=None): QDialog.__init__(self, parent) mirror = robjects.r.getOption('repos') contrib_url = robjects.r.get('contrib.url', mode='function') available_packages = robjects.r.get('available.packages', mode='function') self.setWindowTitle("manageR - Install R Packages") self.setWindowIcon(QIcon(":icon")) p = available_packages() self.pipe = pipe self.names = QStringList(p.rownames) self.parent = parent self.packageList = QListWidget(self) self.packageList.setAlternatingRowColors(True) self.packageList.setEditTriggers(QAbstractItemView.NoEditTriggers) self.packageList.setSortingEnabled(True) self.packageList.setSelectionMode(QAbstractItemView.ExtendedSelection) self.packageList.setToolTip("Select packages to install") self.packageList.setWhatsThis("List of packages available on CRAN") self.packageList.insertItems(0, self.names) self.dependCheckbox = QCheckBox(self) self.dependCheckbox.setText("Install all dependencies") self.dependCheckbox.setChecked(True) self.closeCheckbox = QCheckBox(self) self.closeCheckbox.setText("Close dialog on completion") self.closeCheckbox.setChecked(False) filterEdit = QLineEdit(self) filterLabel = QLabel("Filter packages", self) self.outputEdit = QTextEdit(self) self.outputEdit.setReadOnly(True) self.outputEdit.setVisible(False) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Apply|QDialogButtonBox.Close) self.buttonBox.addButton("Details >>", QDialogButtonBox.ActionRole) vbox = QVBoxLayout(self) hbox = QHBoxLayout() hbox.addWidget(filterLabel) hbox.addWidget(filterEdit) vbox.addLayout(hbox) vbox.addWidget(self.dependCheckbox) vbox.addWidget(self.packageList) vbox.addWidget(self.closeCheckbox) vbox.addWidget(self.outputEdit) vbox.addWidget(self.buttonBox) self.started = False self.setMinimumSize(80,50) self.connect(filterEdit, SIGNAL("textChanged(QString)"), self.filterPackages) #self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject) self.connect(self.buttonBox, SIGNAL("clicked(QAbstractButton*)"), self.buttonClicked) def buttonClicked(self, button): if button.text() == "Details >>": self.showDetails() button.setText("Details <<") elif button.text() == "Details <<": self.hideDetails() button.setText("Details >>") if not self.started: if self.buttonBox.standardButton(button) == QDialogButtonBox.Apply: self.installPackages() else: self.reject() def showDetails(self): self.outputEdit.setVisible(True) def hideDetails(self): self.outputEdit.setVisible(False) def filterPackages(self, text): self.packageList.clear() self.packageList.insertItems(0, self.names.filter(QRegExp(r"^%s" % text))) firstItem = self.packageList.item(0) if firstItem.text().startsWith(text): self.packageList.setCurrentItem(firstItem) # else: # self.packageList.clearSelection() def currentPackages(self): return [unicode(item.text()) for item in self.packageList.selectedItems()] def installPackages(self): pkgs = self.currentPackages() count = len(pkgs) if count < 1: QMessageBox.warning(self, "manageR - Warning", "Please choose at least one valid package") return False pkgs = QStringList(pkgs).join("','") checked = self.dependCheckbox.isChecked() if checked: depends = "TRUE" else: depends = "FALSE" self.pipe.send("install.packages(c('%s'), dependencies=%s, repos=%s)" % (pkgs, depends, robjects.r.getOption("repos"))) self.started = True self.startTimer(30) return True def timerEvent(self, e): if self.started: try: output = self.pipe.recv() if output is None: self.started=False self.killTimer(e.timerId()) else: self.printOutput(output) except EOFError: pass QApplication.processEvents() def printOutput(self, output): self.outputEdit.insertPlainText(output) self.outputEdit.ensureCursorVisible()