Example #1
0
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)"))
Example #3
0
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 &phi;&prime;', '28 Anomalous scattering factor &phi;&Prime;', '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()
Example #4
0
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>|&gt;&gt;&gt;&nbsp;%s</b><br>' % formatPyLine(line))
            else:
                self.cursor.insertHtml('<br><b>|.&nbsp;.&nbsp;.&nbsp;&nbsp;%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)
Example #7
0
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()
Example #8
0
class OWxsh_waviness(widget.OWWidget):
    name = "xsh_waviness"
    id = "orange.widgets.preprocessor.xsh_waviness"
    description = "xoppy application to compute..."
    icon = "icons/waviness.png"
    author = "Luca Rebuffi"
    maintainer_email = "[email protected]; [email protected]"
    priority = 10
    category = ""
    keywords = ["xoppy", "xsh_waviness"]

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

    want_main_area = 1
    want_control_area = 1

    WIDGET_WIDTH = 1100
    WIDGET_HEIGHT = 650

    xx = None
    yy = None
    zz = None

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

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

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

    waviness_file_name = Setting('waviness.dat')

    harmonic_maximum_index = Setting(60)

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

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

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

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

        tabs_setting = gui.tabWidget(gen_box)

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

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

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

        gui.separator(self.input_box)

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

        gui.separator(self.input_box)

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

        gui.separator(self.input_box)

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

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

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

        gui.separator(self.output_box)

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

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

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

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

        gui.separator(self.harmonics_box)

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

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

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

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

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

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

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

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

        gui.rubber(self.controlArea)

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

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

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

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

        gui.rubber(self.mainArea)

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

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

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

        horHeaders = []
        verHeaders = []

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

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

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

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

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

        gui.rubber(self.controlArea)

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

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

        self.table.clear()

        row_count = self.table.rowCount()

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

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

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

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

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

        self.table.resizeRowsToContents()

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

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

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

        try:
            row_count = self.harmonic_maximum_index + 1

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

                row_content = []

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

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

                        row_content.append(str(value))

                dict[column_name] = row_content

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

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

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

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

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

            self.reload_harmonics_table()

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

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

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

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

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

                self.reload_harmonics_table()

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

            self.check_fields()

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

            dict = {}

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

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

            ST.waviness_write(dict, file=file_name)

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

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

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

            self.check_fields()

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

            self.axis.clear()

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

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

            z_to_plot = numpy.array(z_to_plot)

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

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

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

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

            self.figure_canvas.draw()

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


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

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

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

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

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

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

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

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

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

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

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

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


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

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

        return float_array

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

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

        return string_array

    def writeStdOut(self, text):
        cursor = self.shadow_output.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertText(text)
        self.shadow_output.setTextCursor(cursor)
        self.shadow_output.ensureCursorVisible()
Example #9
0
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()
Example #11
0
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()