class OWRadiation(OWGenericInstrumentalDiffractionPatternParametersWidget):

    name = "Incident Radiation"
    description = "Incident Radiation"
    icon = "icons/lambda.png"
    priority = 1.1

    is_multiple_wavelength = Setting([0])

    wavelength = Setting([0.0826])
    wavelength_fixed = Setting([0])
    wavelength_has_min = Setting([0])
    wavelength_min = Setting([0.0])
    wavelength_has_max = Setting([0])
    wavelength_max = Setting([0.0])
    wavelength_function = Setting([0])
    wavelength_function_value = Setting([""])

    xray_tube_key = Setting(["CuKa2"])

    wavelength_2 = Setting([0])
    wavelength_2_fixed = Setting([1])
    wavelength_2_has_min = Setting([0])
    wavelength_2_min = Setting([0.0])
    wavelength_2_has_max = Setting([0])
    wavelength_2_max = Setting([0.0])
    wavelength_2_function = Setting([0])
    wavelength_2_function_value = Setting([""])

    wavelength_3 = Setting([0])
    wavelength_3_fixed = Setting([1])
    wavelength_3_has_min = Setting([0])
    wavelength_3_min = Setting([0.0])
    wavelength_3_has_max = Setting([0])
    wavelength_3_max = Setting([0.0])
    wavelength_3_function = Setting([0])
    wavelength_3_function_value = Setting([""])

    wavelength_4 = Setting([0])
    wavelength_4_fixed = Setting([1])
    wavelength_4_has_min = Setting([0])
    wavelength_4_min = Setting([0.0])
    wavelength_4_has_max = Setting([0])
    wavelength_4_max = Setting([0.0])
    wavelength_4_function = Setting([0])
    wavelength_4_function_value = Setting([""])

    wavelength_5 = Setting([0])
    wavelength_5_fixed = Setting([1])
    wavelength_5_has_min = Setting([0])
    wavelength_5_min = Setting([0.0])
    wavelength_5_has_max = Setting([0])
    wavelength_5_max = Setting([0.0])
    wavelength_5_function = Setting([0])
    wavelength_5_function_value = Setting([""])

    weight_2 = Setting([0])
    weight_2_fixed = Setting([1])
    weight_2_has_min = Setting([0])
    weight_2_min = Setting([0.0])
    weight_2_has_max = Setting([0])
    weight_2_max = Setting([0.0])
    weight_2_function = Setting([0])
    weight_2_function_value = Setting([""])

    weight_3 = Setting([0])
    weight_3_fixed = Setting([1])
    weight_3_has_min = Setting([0])
    weight_3_min = Setting([0.0])
    weight_3_has_max = Setting([0])
    weight_3_max = Setting([0.0])
    weight_3_function = Setting([0])
    weight_3_function_value = Setting([""])

    weight_4 = Setting([0])
    weight_4_fixed = Setting([1])
    weight_4_has_min = Setting([0])
    weight_4_min = Setting([0.0])
    weight_4_has_max = Setting([0])
    weight_4_max = Setting([0.0])
    weight_4_function = Setting([0])
    weight_4_function_value = Setting([""])

    weight_5 = Setting([0])
    weight_5_fixed = Setting([1])
    weight_5_has_min = Setting([0])
    weight_5_min = Setting([0.0])
    weight_5_has_max = Setting([0])
    weight_5_max = Setting([0.0])
    weight_5_function = Setting([0])
    weight_5_function_value = Setting([""])

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

    def get_parameter_name(self):
        return "Radiation"

    def get_current_dimension(self):
        return len(self.is_multiple_wavelength)

    def get_parameter_box_instance(self, parameter_tab, index):
        return RadiationBox(
            widget=self,
            parent=parameter_tab,
            index=index,
            is_multiple_wavelength=self.is_multiple_wavelength[index],
            wavelength=self.wavelength[index],
            wavelength_fixed=self.wavelength_fixed[index],
            wavelength_has_min=self.wavelength_has_min[index],
            wavelength_min=self.wavelength_min[index],
            wavelength_has_max=self.wavelength_has_max[index],
            wavelength_max=self.wavelength_max[index],
            wavelength_function=self.wavelength_function[index],
            wavelength_function_value=self.wavelength_function_value[index],
            xray_tube_key=self.xray_tube_key[index],
            wavelength_2=self.wavelength_2[index],
            wavelength_2_fixed=self.wavelength_2_fixed[index],
            wavelength_2_has_min=self.wavelength_2_has_min[index],
            wavelength_2_min=self.wavelength_2_min[index],
            wavelength_2_has_max=self.wavelength_2_has_max[index],
            wavelength_2_max=self.wavelength_2_max[index],
            wavelength_2_function=self.wavelength_2_function[index],
            wavelength_2_function_value=self.
            wavelength_2_function_value[index],
            wavelength_3=self.wavelength_3[index],
            wavelength_3_fixed=self.wavelength_3_fixed[index],
            wavelength_3_has_min=self.wavelength_3_has_min[index],
            wavelength_3_min=self.wavelength_3_min[index],
            wavelength_3_has_max=self.wavelength_3_has_max[index],
            wavelength_3_max=self.wavelength_3_max[index],
            wavelength_3_function=self.wavelength_3_function[index],
            wavelength_3_function_value=self.
            wavelength_3_function_value[index],
            wavelength_4=self.wavelength_4[index],
            wavelength_4_fixed=self.wavelength_4_fixed[index],
            wavelength_4_has_min=self.wavelength_4_has_min[index],
            wavelength_4_min=self.wavelength_4_min[index],
            wavelength_4_has_max=self.wavelength_4_has_max[index],
            wavelength_4_max=self.wavelength_4_max[index],
            wavelength_4_function=self.wavelength_4_function[index],
            wavelength_4_function_value=self.
            wavelength_4_function_value[index],
            wavelength_5=self.wavelength_5[index],
            wavelength_5_fixed=self.wavelength_5_fixed[index],
            wavelength_5_has_min=self.wavelength_5_has_min[index],
            wavelength_5_min=self.wavelength_5_min[index],
            wavelength_5_has_max=self.wavelength_5_has_max[index],
            wavelength_5_max=self.wavelength_5_max[index],
            wavelength_5_function=self.wavelength_5_function[index],
            wavelength_5_function_value=self.
            wavelength_5_function_value[index],
            weight_2=self.weight_2[index],
            weight_2_fixed=self.weight_2_fixed[index],
            weight_2_has_min=self.weight_2_has_min[index],
            weight_2_min=self.weight_2_min[index],
            weight_2_has_max=self.weight_2_has_max[index],
            weight_2_max=self.weight_2_max[index],
            weight_2_function=self.weight_2_function[index],
            weight_2_function_value=self.weight_2_function_value[index],
            weight_3=self.weight_3[index],
            weight_3_fixed=self.weight_3_fixed[index],
            weight_3_has_min=self.weight_3_has_min[index],
            weight_3_min=self.weight_3_min[index],
            weight_3_has_max=self.weight_3_has_max[index],
            weight_3_max=self.weight_3_max[index],
            weight_3_function=self.weight_3_function[index],
            weight_3_function_value=self.weight_3_function_value[index],
            weight_4=self.weight_4[index],
            weight_4_fixed=self.weight_4_fixed[index],
            weight_4_has_min=self.weight_4_has_min[index],
            weight_4_min=self.weight_4_min[index],
            weight_4_has_max=self.weight_4_has_max[index],
            weight_4_max=self.weight_4_max[index],
            weight_4_function=self.weight_4_function[index],
            weight_4_function_value=self.weight_4_function_value[index],
            weight_5=self.weight_5[index],
            weight_5_fixed=self.weight_5_fixed[index],
            weight_5_has_min=self.weight_5_has_min[index],
            weight_5_min=self.weight_5_min[index],
            weight_5_has_max=self.weight_5_has_max[index],
            weight_5_max=self.weight_5_max[index],
            weight_5_function=self.weight_5_function[index],
            weight_5_function_value=self.weight_5_function_value[index])

    def get_empty_parameter_box_instance(self, parameter_tab, index):
        return RadiationBox(widget=self, parent=parameter_tab, index=index)

    def set_parameter_data(self):
        incident_radiations = []

        if self.use_single_parameter_set == 1:
            incident_radiation = self.get_parameter_box(
                0).get_incident_radiation()
            incident_radiations.append(incident_radiation)

            for diffraction_pattern in self.fit_global_parameters.measured_dataset.diffraction_patterns:
                diffraction_pattern.apply_wavelength(
                    incident_radiation.wavelength)
        else:
            for index in range(self.get_current_dimension()):
                incident_radiation = self.get_parameter_box(
                    index).get_incident_radiation()
                incident_radiations.append(incident_radiation)

                self.fit_global_parameters.measured_dataset.diffraction_patterns[
                    index].apply_wavelength(incident_radiation.wavelength)

        self.fit_global_parameters.measured_dataset.incident_radiations = incident_radiations

    def get_parameter_array(self):
        return self.fit_global_parameters.measured_dataset.incident_radiations

    def get_parameter_item(self, diffraction_pattern_index):
        return self.fit_global_parameters.measured_dataset.incident_radiations[
            diffraction_pattern_index]

    def get_instrumental_parameter_array(self, instrumental_parameters):
        return instrumental_parameters.incident_radiations

    def get_instrumental_parameter_item(self, instrumental_parameters,
                                        diffraction_pattern_index):
        return instrumental_parameters.get_incident_radiations_item(
            diffraction_pattern_index)

    ##############################
    # SINGLE FIELDS SIGNALS
    ##############################

    def dumpSettings(self):
        self.dump_is_multiple_wavelength()
        self.dump_wavelength()
        self.dump_xray_tube_key()
        self.dump_wavelength_2()
        self.dump_wavelength_3()
        self.dump_wavelength_4()
        self.dump_wavelength_5()
        self.dump_weight_2()
        self.dump_weight_3()
        self.dump_weight_4()
        self.dump_weight_5()

    def dump_is_multiple_wavelength(self):
        self.dump_variable("is_multiple_wavelength")

    def dump_xray_tube_key(self):
        self.dump_variable("xray_tube_key")

    def dump_wavelength(self):
        self.dump_parameter("wavelength")

    def dump_wavelength_2(self):
        self.dump_parameter("wavelength_2")

    def dump_wavelength_3(self):
        self.dump_parameter("wavelength_3")

    def dump_wavelength_4(self):
        self.dump_parameter("wavelength_4")

    def dump_wavelength_5(self):
        self.dump_parameter("wavelength_5")

    def dump_weight_2(self):
        self.dump_parameter("weight_2")

    def dump_weight_3(self):
        self.dump_parameter("weight_3")

    def dump_weight_4(self):
        self.dump_parameter("weight_4")

    def dump_weight_5(self):
        self.dump_parameter("weight_5")
Example #2
0
class MergeBeams(OWWidget):

    name = "Merge Shadow Beam"
    description = "Display Data: Merge Shadow Beam"
    icon = "icons/merge.png"
    maintainer = "Luca Rebuffi"
    maintainer_email = "lrebuffi(@at@)anl.gov"
    priority = 4
    category = "Data Display Tools"
    keywords = ["data", "file", "load", "read"]

    inputs = [
        ("Input Beam # 1", ShadowBeam, "setBeam1"),
        ("Input Beam # 2", ShadowBeam, "setBeam2"),
        ("Input Beam # 3", ShadowBeam, "setBeam3"),
        ("Input Beam # 4", ShadowBeam, "setBeam4"),
        ("Input Beam # 5", ShadowBeam, "setBeam5"),
        ("Input Beam # 6", ShadowBeam, "setBeam6"),
        ("Input Beam # 7", ShadowBeam, "setBeam7"),
        ("Input Beam # 8", ShadowBeam, "setBeam8"),
        ("Input Beam # 9", ShadowBeam, "setBeam9"),
        ("Input Beam # 10", ShadowBeam, "setBeam10"),
    ]

    outputs = [{
        "name": "Beam",
        "type": ShadowBeam,
        "doc": "Shadow Beam",
        "id": "beam"
    }]

    want_main_area = 0
    want_control_area = 1

    input_beam1 = None
    input_beam2 = None
    input_beam3 = None
    input_beam4 = None
    input_beam5 = None
    input_beam6 = None
    input_beam7 = None
    input_beam8 = None
    input_beam9 = None
    input_beam10 = None

    use_weights = Setting(0)

    weight_input_beam1 = Setting(0.0)
    weight_input_beam2 = Setting(0.0)
    weight_input_beam3 = Setting(0.0)
    weight_input_beam4 = Setting(0.0)
    weight_input_beam5 = Setting(0.0)
    weight_input_beam6 = Setting(0.0)
    weight_input_beam7 = Setting(0.0)
    weight_input_beam8 = Setting(0.0)
    weight_input_beam9 = Setting(0.0)
    weight_input_beam10 = Setting(0.0)

    def __init__(self, show_automatic_box=True):
        super().__init__()

        self.runaction = widget.OWAction("Merge Beams", self)
        self.runaction.triggered.connect(self.merge_beams)
        self.addAction(self.runaction)

        self.setFixedWidth(470)
        self.setFixedHeight(470)

        gen_box = gui.widgetBox(self.controlArea,
                                "Merge Shadow Beams",
                                addSpace=True,
                                orientation="vertical")

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

        button = gui.button(button_box,
                            self,
                            "Merge Beams and Send",
                            callback=self.merge_beams)
        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)

        weight_box = oasysgui.widgetBox(gen_box,
                                        "Relative Weights",
                                        addSpace=False,
                                        orientation="vertical")

        gui.comboBox(weight_box,
                     self,
                     "use_weights",
                     label="Use Relative Weights?",
                     labelWidth=350,
                     items=["No", "Yes"],
                     callback=self.set_UseWeights,
                     sendSelectedValue=False,
                     orientation="horizontal")

        gui.separator(weight_box, height=10)

        self.le_weight_input_beam1 = oasysgui.lineEdit(
            weight_box,
            self,
            "weight_input_beam1",
            "Input Beam 1 weight",
            labelWidth=300,
            valueType=float,
            orientation="horizontal")

        self.le_weight_input_beam2 = oasysgui.lineEdit(
            weight_box,
            self,
            "weight_input_beam2",
            "Input Beam 2 weight",
            labelWidth=300,
            valueType=float,
            orientation="horizontal")

        self.le_weight_input_beam3 = oasysgui.lineEdit(
            weight_box,
            self,
            "weight_input_beam3",
            "Input Beam 3 weight",
            labelWidth=300,
            valueType=float,
            orientation="horizontal")

        self.le_weight_input_beam4 = oasysgui.lineEdit(
            weight_box,
            self,
            "weight_input_beam4",
            "Input Beam 4 weight",
            labelWidth=300,
            valueType=float,
            orientation="horizontal")

        self.le_weight_input_beam5 = oasysgui.lineEdit(
            weight_box,
            self,
            "weight_input_beam5",
            "Input Beam 5 weight",
            labelWidth=300,
            valueType=float,
            orientation="horizontal")

        self.le_weight_input_beam6 = oasysgui.lineEdit(
            weight_box,
            self,
            "weight_input_beam6",
            "Input Beam 6 weight",
            labelWidth=300,
            valueType=float,
            orientation="horizontal")

        self.le_weight_input_beam7 = oasysgui.lineEdit(
            weight_box,
            self,
            "weight_input_beam7",
            "Input Beam 7 weight",
            labelWidth=300,
            valueType=float,
            orientation="horizontal")

        self.le_weight_input_beam8 = oasysgui.lineEdit(
            weight_box,
            self,
            "weight_input_beam8",
            "Input Beam 8 weight",
            labelWidth=300,
            valueType=float,
            orientation="horizontal")

        self.le_weight_input_beam9 = oasysgui.lineEdit(
            weight_box,
            self,
            "weight_input_beam9",
            "Input Beam 9 weight",
            labelWidth=300,
            valueType=float,
            orientation="horizontal")

        self.le_weight_input_beam10 = oasysgui.lineEdit(
            weight_box,
            self,
            "weight_input_beam10",
            "Input Beam 10 weight",
            labelWidth=300,
            valueType=float,
            orientation="horizontal")

        self.le_weight_input_beam1.setEnabled(False)
        self.le_weight_input_beam2.setEnabled(False)
        self.le_weight_input_beam3.setEnabled(False)
        self.le_weight_input_beam4.setEnabled(False)
        self.le_weight_input_beam5.setEnabled(False)
        self.le_weight_input_beam6.setEnabled(False)
        self.le_weight_input_beam7.setEnabled(False)
        self.le_weight_input_beam8.setEnabled(False)
        self.le_weight_input_beam9.setEnabled(False)
        self.le_weight_input_beam10.setEnabled(False)

    def setBeam1(self, beam):
        self.le_weight_input_beam1.setEnabled(False)
        self.input_beam1 = None

        if ShadowCongruence.checkEmptyBeam(beam):
            if ShadowCongruence.checkGoodBeam(beam):
                self.input_beam1 = beam
                if self.use_weights == 1:
                    self.le_weight_input_beam1.setEnabled(True)
            else:
                QtWidgets.QMessageBox.critical(
                    self, "Error",
                    "Data #1 not displayable: No good rays or bad content",
                    QtWidgets.QMessageBox.Ok)

    def setBeam2(self, beam):
        self.le_weight_input_beam2.setEnabled(False)
        self.input_beam2 = None

        if ShadowCongruence.checkEmptyBeam(beam):
            if ShadowCongruence.checkGoodBeam(beam):
                self.input_beam2 = beam
                if self.use_weights == 1:
                    self.le_weight_input_beam2.setEnabled(True)
            else:
                QtWidgets.QMessageBox.critical(
                    self, "Error",
                    "Data #2 not displayable: No good rays or bad content",
                    QtWidgets.QMessageBox.Ok)

    def setBeam3(self, beam):
        self.le_weight_input_beam3.setEnabled(False)
        self.input_beam3 = None

        if ShadowCongruence.checkEmptyBeam(beam):
            if ShadowCongruence.checkGoodBeam(beam):
                self.input_beam3 = beam
                if self.use_weights == 1:
                    self.le_weight_input_beam3.setEnabled(True)
            else:
                QtWidgets.QMessageBox.critical(
                    self, "Error",
                    "Data #3 not displayable: No good rays or bad content",
                    QtWidgets.QMessageBox.Ok)

    def setBeam4(self, beam):
        self.le_weight_input_beam4.setEnabled(False)
        self.input_beam4 = None

        if ShadowCongruence.checkEmptyBeam(beam):
            if ShadowCongruence.checkGoodBeam(beam):
                self.input_beam4 = beam
                if self.use_weights == 1:
                    self.le_weight_input_beam4.setEnabled(True)
            else:
                QtWidgets.QMessageBox.critical(
                    self, "Error",
                    "Data #4 not displayable: No good rays or bad content",
                    QtWidgets.QMessageBox.Ok)

    def setBeam5(self, beam):
        self.le_weight_input_beam5.setEnabled(False)
        self.input_beam5 = None

        if ShadowCongruence.checkEmptyBeam(beam):
            if ShadowCongruence.checkGoodBeam(beam):
                self.input_beam5 = beam
                if self.use_weights == 1:
                    self.le_weight_input_beam5.setEnabled(True)
            else:
                QtWidgets.QMessageBox.critical(
                    self, "Error",
                    "Data #5 not displayable: No good rays or bad content",
                    QtWidgets.QMessageBox.Ok)

    def setBeam6(self, beam):
        self.le_weight_input_beam6.setEnabled(False)
        self.input_beam6 = None

        if ShadowCongruence.checkEmptyBeam(beam):
            if ShadowCongruence.checkGoodBeam(beam):
                self.input_beam6 = beam
                if self.use_weights == 1:
                    self.le_weight_input_beam6.setEnabled(True)
            else:
                QtWidgets.QMessageBox.critical(
                    self, "Error",
                    "Data #6 not displayable: No good rays or bad content",
                    QtWidgets.QMessageBox.Ok)

    def setBeam7(self, beam):
        self.le_weight_input_beam7.setEnabled(False)
        self.input_beam7 = None

        if ShadowCongruence.checkEmptyBeam(beam):
            if ShadowCongruence.checkGoodBeam(beam):
                self.input_beam7 = beam
                if self.use_weights == 1:
                    self.le_weight_input_beam7.setEnabled(True)
            else:
                QtWidgets.QMessageBox.critical(
                    self, "Error",
                    "Data #7 not displayable: No good rays or bad content",
                    QtWidgets.QMessageBox.Ok)

    def setBeam8(self, beam):
        self.le_weight_input_beam8.setEnabled(False)
        self.input_beam8 = None

        if ShadowCongruence.checkEmptyBeam(beam):
            if ShadowCongruence.checkGoodBeam(beam):
                self.input_beam8 = beam
                if self.use_weights == 1:
                    self.le_weight_input_beam8.setEnabled(True)
            else:
                QtWidgets.QMessageBox.critical(
                    self, "Error",
                    "Data #8 not displayable: No good rays or bad content",
                    QtWidgets.QMessageBox.Ok)

    def setBeam9(self, beam):
        self.le_weight_input_beam9.setEnabled(False)
        self.input_beam9 = None

        if ShadowCongruence.checkEmptyBeam(beam):
            if ShadowCongruence.checkGoodBeam(beam):
                self.input_beam9 = beam
                if self.use_weights == 1:
                    self.le_weight_input_beam9.setEnabled(True)
            else:
                QtWidgets.QMessageBox.critical(
                    self, "Error",
                    "Data #9 not displayable: No good rays or bad content",
                    QtWidgets.QMessageBox.Ok)

    def setBeam10(self, beam):
        self.le_weight_input_beam10.setEnabled(False)
        self.input_beam10 = None

        if ShadowCongruence.checkEmptyBeam(beam):
            if ShadowCongruence.checkGoodBeam(beam):
                self.input_beam10 = beam
                if self.use_weights == 1:
                    self.le_weight_input_beam10.setEnabled(True)
            else:
                QtWidgets.QMessageBox.critical(
                    self, "Error",
                    "Data #10 not displayable: No good rays or bad content",
                    QtWidgets.QMessageBox.Ok)

    def merge_beams(self):
        merged_beam = None

        if self.use_weights == 1:
            total_intensity = 0.0
            for index in range(1, 11):
                current_beam = getattr(self, "input_beam" + str(index))
                if not current_beam is None:
                    total_intensity += current_beam._beam.rays[:, 6]**2 + current_beam._beam.rays[:, 7]**2 + current_beam._beam.rays[:, 8]**2 + \
                                       current_beam._beam.rays[:, 15]**2 + current_beam._beam.rays[:, 16]**2 + current_beam._beam.rays[:, 17]**2

        for index in range(1, 11):
            current_beam = getattr(self, "input_beam" + str(index))
            if not current_beam is None:
                current_beam = current_beam.duplicate()

                if self.use_weights == 1:
                    current_intensity = current_beam._beam.rays[:, 6]**2 + current_beam._beam.rays[:, 7]**2 + current_beam._beam.rays[:, 8]**2 + \
                                        current_beam._beam.rays[:, 15]**2 + current_beam._beam.rays[:, 16]**2 + current_beam._beam.rays[:, 17]**2

                    current_weight = current_intensity / total_intensity
                    new_weight = getattr(self,
                                         "weight_input_beam" + str(index))
                    ratio = new_weight / current_weight

                    current_beam._beam.rays[:, 6] *= numpy.sqrt(ratio)
                    current_beam._beam.rays[:, 7] *= numpy.sqrt(ratio)
                    current_beam._beam.rays[:, 8] *= numpy.sqrt(ratio)
                    current_beam._beam.rays[:, 15] *= numpy.sqrt(ratio)
                    current_beam._beam.rays[:, 16] *= numpy.sqrt(ratio)
                    current_beam._beam.rays[:, 17] *= numpy.sqrt(ratio)

                if merged_beam is None: merged_beam = current_beam
                else:
                    merged_beam = ShadowBeam.mergeBeams(merged_beam,
                                                        current_beam,
                                                        which_flux=3,
                                                        merge_history=2)

        self.send("Beam", merged_beam)

    def set_UseWeights(self):
        self.le_weight_input_beam1.setEnabled(self.use_weights == 1
                                              and not self.input_beam1 is None)
        self.le_weight_input_beam2.setEnabled(self.use_weights == 1
                                              and not self.input_beam2 is None)
        self.le_weight_input_beam3.setEnabled(self.use_weights == 1
                                              and not self.input_beam3 is None)
        self.le_weight_input_beam4.setEnabled(self.use_weights == 1
                                              and not self.input_beam4 is None)
        self.le_weight_input_beam5.setEnabled(self.use_weights == 1
                                              and not self.input_beam5 is None)
        self.le_weight_input_beam6.setEnabled(self.use_weights == 1
                                              and not self.input_beam6 is None)
        self.le_weight_input_beam7.setEnabled(self.use_weights == 1
                                              and not self.input_beam7 is None)
        self.le_weight_input_beam8.setEnabled(self.use_weights == 1
                                              and not self.input_beam8 is None)
        self.le_weight_input_beam9.setEnabled(self.use_weights == 1
                                              and not self.input_beam9 is None)
        self.le_weight_input_beam10.setEnabled(
            self.use_weights == 1 and not self.input_beam10 is None)
Example #3
0
class OWCRL(WPGWidget):
    name = "CRL"
    id = "CRL"
    description = "CRL"
    icon = "icons/crl.png"
    priority = 2
    category = ""
    keywords = ["wpg", "gaussian"]

    inputs = [("Input", WPGOutput, "set_input")]

    nCRL = Setting(1)  #number of lenses, collimating
    delta = Setting(7.511e-06)
    attenLen = Setting(3.88E-3)
    diamCRL = 3.58e-03  #CRL diameter
    wallThickCRL = Setting(30e-06)  #CRL wall thickness [m])

    file_name = Setting("opd_CRL1.pkl")

    # beam parameters:
    distance = Setting(55.0)

    def build_gui(self):

        main_box = oasysgui.widgetBox(self.controlArea,
                                      "CRL Input Parameters",
                                      orientation="vertical",
                                      width=self.CONTROL_AREA_WIDTH - 5,
                                      height=200)

        oasysgui.lineEdit(main_box,
                          self,
                          "nCRL",
                          "Number of Lenses",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(main_box,
                          self,
                          "delta",
                          "Delta",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(main_box,
                          self,
                          "attenLen",
                          "Attenuation length",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(main_box,
                          self,
                          "diamCRL",
                          "CRL diameter",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(main_box,
                          self,
                          "wallThickCRL",
                          "CRL wall Thickness",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")

        oasysgui.lineEdit(main_box,
                          self,
                          "file_name",
                          "CRL file",
                          labelWidth=160,
                          valueType=str,
                          orientation="horizontal")

        gui.separator(main_box, height=5)

        oasysgui.lineEdit(main_box,
                          self,
                          "distance",
                          "Distance to next [m]",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")

    def after_change_workspace_units(self):
        pass

    def check_fields(self):
        congruence.checkStrictlyPositiveNumber(self.nCRL, "Number of Lenses")
        congruence.checkPositiveNumber(self.delta, "delta")
        congruence.checkPositiveNumber(self.attenLen, "Attenuation length")
        congruence.checkPositiveNumber(self.diamCRL, "CRL diameter")

        congruence.checkPositiveNumber(self.distance, "Distance to next")

    def set_input(self, input_data):
        self.setStatusMessage("")

        if not input_data is None:
            self.input_data = input_data

            if self.is_automatic_run: self.compute()

    def do_wpg_calculation(self):
        rMinCRL = 2 * self.delta * self.input_data.get_distance_to_previous(
        ) / self.nCRL  #CRL radius at the tip of parabola [m]

        opCRL = create_CRL_from_file(self.working_directory, self.file_name, 3,
                                     self.delta, self.attenLen, 1,
                                     self.diamCRL, self.diamCRL, rMinCRL,
                                     self.nCRL, self.wallThickCRL, 0, 0, None)

        wavefront = self.input_data.get_wavefront()

        beamline_for_propagation = Beamline()
        beamline_for_propagation.append(opCRL, Use_PP())
        beamline_for_propagation.append(Drift(self.distance),
                                        Use_PP(semi_analytical_treatment=1))

        beamline_for_propagation.propagate(wavefront)

        return wavefront

    def extract_plot_data_from_calculation_output(self, calculation_output):
        self.reset_plotting()

        plot_wfront(
            calculation_output, 'at ' +
            str(self.distance + self.input_data.get_total_distance()) + ' m',
            False, False, 1e-5, 1e-5, 'x', False)

        return self.getFigureCanvas(1), \
               self.getFigureCanvas(2), \
               self.getFigureCanvas(3)

    def getTabTitles(self):
        return ["Intensity", "Vertical Cut", "Horizontal Cut"]

    def extract_wpg_output_from_calculation_output(self, calculation_output):
        return WPGOutput(thetaOM=self.input_data.get_thetaOM(),
                         range_xy=self.input_data.get_range_xy(),
                         wavefront=calculation_output,
                         distance_to_previous=self.distance,
                         total_distance=(self.distance +
                                         self.input_data.get_total_distance()))
Example #4
0
class OWxpower(XoppyWidget):
    name = "POWER"
    id = "orange.widgets.dataxpower"
    description = "Power Absorbed and Transmitted by Optical Elements"
    icon = "icons/xoppy_xpower.png"
    priority = 3
    category = ""
    keywords = ["xoppy", "power"]

    inputs = [("ExchangeData", DataExchangeObject, "acceptExchangeData")]

    SOURCE = Setting(2)
    ENER_MIN = Setting(1000.0)
    ENER_MAX = Setting(50000.0)
    ENER_N = Setting(100)
    SOURCE_FILE = Setting("?")
    NELEMENTS = Setting(1)
    EL1_FOR = Setting("Be")
    EL1_FLAG = Setting(0)
    EL1_THI = Setting(0.5)
    EL1_ANG = Setting(3.0)
    EL1_ROU = Setting(0.0)
    EL1_DEN = Setting("?")
    EL2_FOR = Setting("Rh")
    EL2_FLAG = Setting(1)
    EL2_THI = Setting(0.5)
    EL2_ANG = Setting(3.0)
    EL2_ROU = Setting(0.0)
    EL2_DEN = Setting("?")
    EL3_FOR = Setting("Al")
    EL3_FLAG = Setting(0)
    EL3_THI = Setting(0.5)
    EL3_ANG = Setting(3.0)
    EL3_ROU = Setting(0.0)
    EL3_DEN = Setting("?")
    EL4_FOR = Setting("B")
    EL4_FLAG = Setting(0)
    EL4_THI = Setting(0.5)
    EL4_ANG = Setting(3.0)
    EL4_ROU = Setting(0.0)
    EL4_DEN = Setting("?")
    EL5_FOR = Setting("Pt")
    EL5_FLAG = Setting(1)
    EL5_THI = Setting(0.5)
    EL5_ANG = Setting(3.0)
    EL5_ROU = Setting(0.0)
    EL5_DEN = Setting("?")
    PLOT_SETS = Setting(2)
    FILE_DUMP = 0

    def build_gui(self):

        self.leftWidgetPart.setSizePolicy(
            QSizePolicy(QSizePolicy.MinimumExpanding,
                        QSizePolicy.MinimumExpanding))
        self.leftWidgetPart.setMaximumWidth(self.CONTROL_AREA_WIDTH + 20)
        self.leftWidgetPart.updateGeometry()

        box = oasysgui.widgetBox(self.controlArea,
                                 self.name + " Input Parameters",
                                 orientation="vertical",
                                 width=self.CONTROL_AREA_WIDTH - 10)

        idx = -1

        #widget index 2
        idx += 1
        box1 = gui.widgetBox(box)
        self.box_source = gui.comboBox(
            box1,
            self,
            "SOURCE",
            label=self.unitLabels()[idx],
            addSpace=False,
            items=[
                'From Oasys wire', 'Normalized to 1',
                'From external file.                '
            ],
            valueType=int,
            orientation="horizontal",
            labelWidth=150)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 6
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "ENER_MIN",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 7
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "ENER_MAX",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 8
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "ENER_N",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          validator=QIntValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 9
        idx += 1
        box1 = gui.widgetBox(box)

        file_box = oasysgui.widgetBox(box1,
                                      "",
                                      addSpace=False,
                                      orientation="horizontal",
                                      height=25)

        self.le_file = oasysgui.lineEdit(file_box,
                                         self,
                                         "SOURCE_FILE",
                                         label=self.unitLabels()[idx],
                                         addSpace=False,
                                         orientation="horizontal")
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 10
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "NELEMENTS",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=['1', '2', '3', '4', '5'],
                     valueType=int,
                     orientation="horizontal",
                     callback=self.set_NELEMENTS,
                     labelWidth=330)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 11
        idx += 1
        box1 = gui.widgetBox(box)
        gui.separator(box1, height=7)

        oasysgui.lineEdit(box1,
                          self,
                          "EL1_FOR",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 12
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "EL1_FLAG",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=['Filter', 'Mirror'],
                     valueType=int,
                     orientation="horizontal",
                     callback=self.set_EL_FLAG,
                     labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 13
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL1_THI",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 14
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL1_ANG",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 15
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL1_ROU",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 16
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL1_DEN",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 17
        idx += 1
        box1 = gui.widgetBox(box)
        gui.separator(box1, height=7)

        oasysgui.lineEdit(box1,
                          self,
                          "EL2_FOR",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 18
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "EL2_FLAG",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=['Filter', 'Mirror'],
                     valueType=int,
                     orientation="horizontal",
                     callback=self.set_EL_FLAG,
                     labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 19
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL2_THI",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 20
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL2_ANG",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 21
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL2_ROU",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 22
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL2_DEN",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 23
        idx += 1
        box1 = gui.widgetBox(box)
        gui.separator(box1, height=7)

        oasysgui.lineEdit(box1,
                          self,
                          "EL3_FOR",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 24
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "EL3_FLAG",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=['Filter', 'Mirror'],
                     valueType=int,
                     orientation="horizontal",
                     callback=self.set_EL_FLAG,
                     labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 25
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL3_THI",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 26
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL3_ANG",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 27
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL3_ROU",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 28
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL3_DEN",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 29
        idx += 1
        box1 = gui.widgetBox(box)
        gui.separator(box1, height=7)

        oasysgui.lineEdit(box1,
                          self,
                          "EL4_FOR",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 30
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "EL4_FLAG",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=['Filter', 'Mirror'],
                     valueType=int,
                     orientation="horizontal",
                     callback=self.set_EL_FLAG,
                     labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 31
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL4_THI",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 32
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL4_ANG",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 33
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL4_ROU",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 34
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL4_DEN",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 35
        idx += 1
        box1 = gui.widgetBox(box)
        gui.separator(box1, height=7)

        oasysgui.lineEdit(box1,
                          self,
                          "EL5_FOR",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 36
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "EL5_FLAG",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=['Filter', 'Mirror'],
                     valueType=int,
                     orientation="horizontal",
                     callback=self.set_EL_FLAG,
                     labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 37
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL5_THI",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 38
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL5_ANG",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 39
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL5_ROU",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 40
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "EL5_DEN",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 41
        idx += 1
        box1 = gui.widgetBox(box)
        gui.separator(box1, height=7)

        gui.comboBox(
            box1,
            self,
            "PLOT_SETS",
            label=self.unitLabels()[idx],
            addSpace=False,
            items=['Local properties', 'Cumulated intensities', 'All'],
            valueType=int,
            orientation="horizontal",
            labelWidth=250,
            callback=self.set_NELEMENTS)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 42
        idx += 1
        box1 = gui.widgetBox(box)
        gui.separator(box1, height=7)

        gui.comboBox(box1,
                     self,
                     "FILE_DUMP",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=['No', 'Yes (power.spec)'],
                     valueType=int,
                     orientation="horizontal",
                     labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        self.input_spectrum = None

    def set_NELEMENTS(self):
        self.initializeTabs()

    def set_EL_FLAG(self):
        self.initializeTabs()

    def unitLabels(self):
        return [
            'Input beam:', 'From energy [eV]:      ', 'To energy [eV]:',
            'Energy points:  ', 'File with input beam spectral power:',
            'Number of elements:', '1st oe formula', 'kind:',
            'Filter thick[mm]', 'Mirror angle[mrad]', 'Roughness[A]',
            'Density [g/cm^3]', '2nd oe formula', 'kind:', 'Filter thick[mm]',
            'Mirror angle[mrad]', 'Roughness[A]', 'Density [g/cm^3]',
            '3rd oe formula', 'kind:', 'Filter thick[mm]',
            'Mirror angle[mrad]', 'Roughness[A]', 'Density [g/cm^3]',
            '4th oe formula', 'kind:', 'Filter thick[mm]',
            'Mirror angle[mrad]', 'Roughness[A]', 'Density [g/cm^3]',
            '5th oe formula', 'kind:', 'Filter thick[mm]',
            'Mirror angle[mrad]', 'Roughness[A]', 'Density [g/cm^3]', "Plot",
            "Dump file"
        ]

    def unitFlags(self):
        return [
            'True', 'self.SOURCE  ==  1', 'self.SOURCE  ==  1',
            'self.SOURCE  ==  1', 'self.SOURCE  ==  2', 'True',
            'self.NELEMENTS  >=  0', ' self.NELEMENTS  >=  0',
            'self.EL1_FLAG  ==  0  and  self.NELEMENTS  >=  0',
            'self.EL1_FLAG  !=  0  and  self.NELEMENTS  >=  0',
            'self.EL1_FLAG  !=  0  and  self.NELEMENTS  >=  0',
            ' self.NELEMENTS  >=  0', 'self.NELEMENTS  >=  1',
            ' self.NELEMENTS  >=  1',
            'self.EL2_FLAG  ==  0  and  self.NELEMENTS  >=  1',
            'self.EL2_FLAG  !=  0  and  self.NELEMENTS  >=  1',
            'self.EL2_FLAG  !=  0  and  self.NELEMENTS  >=  1',
            ' self.NELEMENTS  >=  1', 'self.NELEMENTS  >=  2',
            ' self.NELEMENTS  >=  2',
            'self.EL3_FLAG  ==  0  and  self.NELEMENTS  >=  2',
            'self.EL3_FLAG  !=  0  and  self.NELEMENTS  >=  2',
            'self.EL3_FLAG  !=  0  and  self.NELEMENTS  >=  2',
            ' self.NELEMENTS  >=  2', 'self.NELEMENTS  >=  3',
            ' self.NELEMENTS  >=  3',
            'self.EL4_FLAG  ==  0  and  self.NELEMENTS  >=  3',
            'self.EL4_FLAG  !=  0  and  self.NELEMENTS  >=  3',
            'self.EL4_FLAG  !=  0  and  self.NELEMENTS  >=  3',
            ' self.NELEMENTS  >=  3', 'self.NELEMENTS  >=  4',
            ' self.NELEMENTS  >=  4',
            'self.EL5_FLAG  ==  0  and  self.NELEMENTS  >=  4',
            'self.EL5_FLAG  !=  0  and  self.NELEMENTS  >=  4',
            'self.EL5_FLAG  !=  0  and  self.NELEMENTS  >=  4',
            ' self.NELEMENTS  >=  4', 'True', 'True'
        ]

    def get_help_name(self):
        return 'power'

    def selectFile(self):
        self.le_source_file.setText(
            oasysgui.selectFileFromDialog(self,
                                          self.SOURCE_FILE,
                                          "Open Source File",
                                          file_extension_filter="*.*"))

    def acceptExchangeData(self, exchangeData):

        self.input_spectrum = None
        self.SOURCE = 0
        # self.box_source.setCurrentIndex(self.SOURCE)

        try:
            if not exchangeData is None:
                if exchangeData.get_program_name() == "XOPPY":
                    no_bandwidth = False
                    if exchangeData.get_widget_name() == "UNDULATOR_FLUX":
                        # self.SOURCE_FILE = "xoppy_undulator_flux"
                        no_bandwidth = True
                        index_flux = 2
                    elif exchangeData.get_widget_name() == "BM":
                        if exchangeData.get_content("is_log_plot") == 1:
                            raise Exception(
                                "Logaritmic X scale of Xoppy Energy distribution not supported"
                            )
                        if exchangeData.get_content(
                                "calculation_type"
                        ) == 0 and exchangeData.get_content("psi") == 0:
                            # self.SOURCE_FILE = "xoppy_bm_flux"
                            no_bandwidth = True
                            index_flux = 6
                        else:
                            raise Exception(
                                "Xoppy result is not an Flux vs Energy distribution integrated in Psi"
                            )
                    elif exchangeData.get_widget_name() == "XWIGGLER":
                        # self.SOURCE_FILE = "xoppy_xwiggler_flux"
                        no_bandwidth = True
                        index_flux = 2
                    elif exchangeData.get_widget_name() == "WS":
                        # self.SOURCE_FILE = "xoppy_xwiggler_flux"
                        no_bandwidth = True
                        index_flux = 2
                    elif exchangeData.get_widget_name() == "XTUBES":
                        # self.SOURCE_FILE = "xoppy_xtubes_flux"
                        index_flux = 1
                        no_bandwidth = True
                    elif exchangeData.get_widget_name() == "XTUBE_W":
                        # self.SOURCE_FILE = "xoppy_xtube_w_flux"
                        index_flux = 1
                        no_bandwidth = True
                    elif exchangeData.get_widget_name() == "BLACK_BODY":
                        # self.SOURCE_FILE = "xoppy_black_body_flux"
                        no_bandwidth = True
                        index_flux = 2

                    elif exchangeData.get_widget_name(
                    ) == "UNDULATOR_RADIATION":
                        # self.SOURCE_FILE = "xoppy_undulator_radiation"
                        no_bandwidth = True
                        index_flux = 1
                    elif exchangeData.get_widget_name() == "POWER":
                        # self.SOURCE_FILE = "xoppy_undulator_power"
                        no_bandwidth = True
                        index_flux = -1
                    elif exchangeData.get_widget_name() == "POWER3D":
                        # self.SOURCE_FILE = "xoppy_power3d"
                        no_bandwidth = True
                        index_flux = 1

                    else:
                        raise Exception("Xoppy Source not recognized")

                    # self.SOURCE_FILE += "_" + str(id(self)) + ".dat"

                    spectrum = exchangeData.get_content("xoppy_data")

                    if exchangeData.get_widget_name() =="UNDULATOR_RADIATION" or \
                        exchangeData.get_widget_name() =="POWER3D":
                        [p, e, h, v] = spectrum
                        tmp = p.sum(axis=2).sum(axis=1) * (h[1] - h[0]) * (
                            v[1] - v[0]) * codata.e * 1e3
                        spectrum = numpy.vstack(
                            (e, p.sum(axis=2).sum(axis=1) * (h[1] - h[0]) *
                             (v[1] - v[0]) * codata.e * 1e3))
                        self.input_spectrum = spectrum
                    else:

                        if not no_bandwidth:
                            spectrum[:, index_flux] /= 0.001 * spectrum[:, 0]

                        self.input_spectrum = numpy.vstack(
                            (spectrum[:, 0], spectrum[:, index_flux]))

                    self.process_showers()
                    self.compute()

        except Exception as exception:
            QMessageBox.critical(self, "Error", str(exception), QMessageBox.Ok)

            #raise exception

    def check_fields(self):

        if self.SOURCE == 1:
            self.ENER_MIN = congruence.checkPositiveNumber(
                self.ENER_MIN, "Energy from")
            self.ENER_MAX = congruence.checkStrictlyPositiveNumber(
                self.ENER_MAX, "Energy to")
            congruence.checkLessThan(self.ENER_MIN, self.ENER_MAX,
                                     "Energy from", "Energy to")
            self.NPOINTS = congruence.checkStrictlyPositiveNumber(
                self.ENER_N, "Energy Points")
        elif self.SOURCE == 2:
            congruence.checkFile(self.SOURCE_FILE)

        if self.NELEMENTS >= 1:
            self.EL1_FOR = congruence.checkEmptyString(self.EL1_FOR,
                                                       "1st oe formula")

            if self.EL1_FLAG == 0:  # filter
                self.EL1_THI = congruence.checkStrictlyPositiveNumber(
                    self.EL1_THI, "1st oe filter thickness")
            elif self.EL1_FLAG == 1:  # mirror
                self.EL1_ANG = congruence.checkStrictlyPositiveNumber(
                    self.EL1_ANG, "1st oe mirror angle")
                self.EL1_ROU = congruence.checkPositiveNumber(
                    self.EL1_ROU, "1st oe mirror roughness")

            if not self.EL1_DEN.strip() == "?":
                self.EL1_DEN = str(
                    congruence.checkStrictlyPositiveNumber(
                        float(
                            congruence.checkNumber(self.EL1_DEN,
                                                   "1st oe density")),
                        "1st oe density"))

        if self.NELEMENTS >= 2:
            self.EL2_FOR = congruence.checkEmptyString(self.EL2_FOR,
                                                       "2nd oe formula")

            if self.EL2_FLAG == 0:  # filter
                self.EL2_THI = congruence.checkStrictlyPositiveNumber(
                    self.EL2_THI, "2nd oe filter thickness")
            elif self.EL2_FLAG == 1:  # mirror
                self.EL2_ANG = congruence.checkStrictlyPositiveNumber(
                    self.EL2_ANG, "2nd oe mirror angle")
                self.EL2_ROU = congruence.checkPositiveNumber(
                    self.EL2_ROU, "2nd oe mirror roughness")

            if not self.EL2_DEN.strip() == "?":
                self.EL2_DEN = str(
                    congruence.checkStrictlyPositiveNumber(
                        float(
                            congruence.checkNumber(self.EL2_DEN,
                                                   "2nd oe density")),
                        "2nd oe density"))

        if self.NELEMENTS >= 3:
            self.EL3_FOR = congruence.checkEmptyString(self.EL3_FOR,
                                                       "3rd oe formula")

            if self.EL3_FLAG == 0:  # filter
                self.EL3_THI = congruence.checkStrictlyPositiveNumber(
                    self.EL3_THI, "3rd oe filter thickness")
            elif self.EL3_FLAG == 1:  # mirror
                self.EL3_ANG = congruence.checkStrictlyPositiveNumber(
                    self.EL3_ANG, "3rd oe mirror angle")
                self.EL3_ROU = congruence.checkPositiveNumber(
                    self.EL3_ROU, "3rd oe mirror roughness")

            if not self.EL3_DEN.strip() == "?":
                self.EL3_DEN = str(
                    congruence.checkStrictlyPositiveNumber(
                        float(
                            congruence.checkNumber(self.EL3_DEN,
                                                   "3rd oe density")),
                        "3rd oe density"))

        if self.NELEMENTS >= 4:
            self.EL4_FOR = congruence.checkEmptyString(self.EL4_FOR,
                                                       "4th oe formula")

            if self.EL4_FLAG == 0:  # filter
                self.EL4_THI = congruence.checkStrictlyPositiveNumber(
                    self.EL4_THI, "4th oe filter thickness")
            elif self.EL4_FLAG == 1:  # mirror
                self.EL4_ANG = congruence.checkStrictlyPositiveNumber(
                    self.EL4_ANG, "4th oe mirror angle")
                self.EL4_ROU = congruence.checkPositiveNumber(
                    self.EL4_ROU, "4th oe mirror roughness")

            if not self.EL4_DEN.strip() == "?":

                self.EL4_DEN = str(
                    congruence.checkStrictlyPositiveNumber(
                        float(
                            congruence.checkNumber(self.EL4_DEN,
                                                   "4th oe density")),
                        "4th oe density"))

        if self.NELEMENTS >= 5:
            self.EL5_FOR = congruence.checkEmptyString(self.EL5_FOR,
                                                       "5th oe formula")

            if self.EL5_FLAG == 0:  # filter
                self.EL5_THI = congruence.checkStrictlyPositiveNumber(
                    self.EL5_THI, "5th oe filter thickness")
            elif self.EL5_FLAG == 1:  # mirror
                self.EL5_ANG = congruence.checkStrictlyPositiveNumber(
                    self.EL5_ANG, "5th oe mirror angle")
                self.EL5_ROU = congruence.checkPositiveNumber(
                    self.EL5_ROU, "5th oe mirror roughness")

            if not self.EL5_DEN.strip() == "?":
                self.EL5_DEN = str(
                    congruence.checkStrictlyPositiveNumber(
                        float(
                            congruence.checkNumber(self.EL5_DEN,
                                                   "5th oe density")),
                        "5th oe density"))

    def do_xoppy_calculation(self):
        return self.xoppy_calc_xpower()

    def extract_data_from_xoppy_output(self, calculation_output):
        return calculation_output

    def get_data_exchange_widget_name(self):
        return "POWER"

    def getKind(self, oe_n):
        if oe_n == 1:
            return self.EL1_FLAG
        elif oe_n == 2:
            return self.EL2_FLAG
        elif oe_n == 3:
            return self.EL3_FLAG
        elif oe_n == 4:
            return self.EL4_FLAG
        elif oe_n == 5:
            return self.EL5_FLAG

    def do_plot_local(self):
        out = False
        if self.PLOT_SETS == 0: out = True
        if self.PLOT_SETS == 2: out = True
        return out

    def do_plot_intensity(self):
        out = False
        if self.PLOT_SETS == 1: out = True
        if self.PLOT_SETS == 2: out = True
        return out

    def getTitles(self):
        titles = []

        if self.do_plot_intensity(): titles.append("Input beam")

        for oe_n in range(1, self.NELEMENTS + 2):
            kind = self.getKind(oe_n)

            if kind == 0:  # FILTER
                if self.do_plot_local():
                    titles.append("[oe " + str(oe_n) + "] Total CS")
                if self.do_plot_local():
                    titles.append("[oe " + str(oe_n) + "] Mu")
                if self.do_plot_local():
                    titles.append("[oe " + str(oe_n) + "] Transmitivity")
                if self.do_plot_local():
                    titles.append("[oe " + str(oe_n) + "] Absorption")
                if self.do_plot_intensity():
                    titles.append("Intensity after oe " + str(oe_n))
            else:  # MIRROR
                if self.do_plot_local():
                    titles.append("[oe " + str(oe_n) + "] 1-Re[n]=delta")
                if self.do_plot_local():
                    titles.append("[oe " + str(oe_n) + "] Im[n]=beta")
                if self.do_plot_local():
                    titles.append("[oe " + str(oe_n) + "] delta/beta")
                if self.do_plot_local():
                    titles.append("[oe " + str(oe_n) + "] Reflectivity-s")
                if self.do_plot_local():
                    titles.append("[oe " + str(oe_n) + "] Transmitivity")
                if self.do_plot_intensity():
                    titles.append("Intensity after oe " + str(oe_n))

        return titles

    def getXTitles(self):

        xtitles = []

        if self.do_plot_intensity(): xtitles.append("Photon Energy [eV]")

        for oe_n in range(1, self.NELEMENTS + 2):
            kind = self.getKind(oe_n)

            if kind == 0:  # FILTER
                if self.do_plot_local(): xtitles.append("Photon Energy [eV]")
                if self.do_plot_local(): xtitles.append("Photon Energy [eV]")
                if self.do_plot_local(): xtitles.append("Photon Energy [eV]")
                if self.do_plot_local(): xtitles.append("Photon Energy [eV]")
                if self.do_plot_intensity():
                    xtitles.append("Photon Energy [eV]")
            else:  # MIRROR
                if self.do_plot_local(): xtitles.append("Photon Energy [eV]")
                if self.do_plot_local(): xtitles.append("Photon Energy [eV]")
                if self.do_plot_local(): xtitles.append("Photon Energy [eV]")
                if self.do_plot_local(): xtitles.append("Photon Energy [eV]")
                if self.do_plot_local(): xtitles.append("Photon Energy [eV]")
                if self.do_plot_intensity():
                    xtitles.append("Photon Energy [eV]")

        return xtitles

    def getYTitles(self):
        ytitles = []

        if self.do_plot_intensity(): ytitles.append("Source")

        for oe_n in range(1, self.NELEMENTS + 2):
            kind = self.getKind(oe_n)

            if kind == 0:  # FILTER
                if self.do_plot_local():
                    ytitles.append("[oe " + str(oe_n) + "] Total CS cm2/g")
                if self.do_plot_local():
                    ytitles.append("[oe " + str(oe_n) + "] Mu cm^-1")
                if self.do_plot_local():
                    ytitles.append("[oe " + str(oe_n) + "] Transmitivity")
                if self.do_plot_local():
                    ytitles.append("[oe " + str(oe_n) + "] Absorption")
                if self.do_plot_intensity():
                    ytitles.append("Intensity after oe " + str(oe_n))
            else:  # MIRROR
                if self.do_plot_local():
                    ytitles.append("[oe " + str(oe_n) + "] 1-Re[n]=delta")
                if self.do_plot_local():
                    ytitles.append("[oe " + str(oe_n) + "] Im[n]=beta")
                if self.do_plot_local():
                    ytitles.append("[oe " + str(oe_n) + "] delta/beta")
                if self.do_plot_local():
                    ytitles.append("[oe " + str(oe_n) + "] Reflectivity-s")
                if self.do_plot_local():
                    ytitles.append("[oe " + str(oe_n) + "] Transmitivity")
                if self.do_plot_intensity():
                    ytitles.append("Intensity after oe " + str(oe_n))

        return ytitles

    def getVariablesToPlot(self):
        variables = []

        if self.do_plot_intensity():
            variables.append((0, 1))  # start plotting the source
        shift = 0

        for oe_n in range(1, self.NELEMENTS + 2):
            kind = self.getKind(oe_n)

            if oe_n == 1:
                shift = 0
            else:
                kind_previous = self.getKind(oe_n - 1)

                if kind_previous == 0:  # FILTER
                    shift += 5
                else:
                    shift += 6

            if kind == 0:  # FILTER
                if self.do_plot_local(): variables.append((0, 2 + shift))
                if self.do_plot_local(): variables.append((0, 3 + shift))
                if self.do_plot_local(): variables.append((0, 4 + shift))
                if self.do_plot_local(): variables.append((0, 5 + shift))
                if self.do_plot_intensity(): variables.append((0, 6 + shift))
            else:
                if self.do_plot_local(): variables.append((0, 2 + shift))
                if self.do_plot_local(): variables.append((0, 3 + shift))
                if self.do_plot_local(): variables.append((0, 4 + shift))
                if self.do_plot_local(): variables.append((0, 5 + shift))
                if self.do_plot_local(): variables.append((0, 6 + shift))
                if self.do_plot_intensity(): variables.append((0, 7 + shift))

        return variables

    def getLogPlot(self):

        logplot = []

        if self.do_plot_intensity(): logplot.append((False, False))

        for oe_n in range(1, self.NELEMENTS + 2):
            kind = self.getKind(oe_n)

            if kind == 0:  # FILTER
                if self.do_plot_local(): logplot.append((False, True))
                if self.do_plot_local(): logplot.append((False, True))
                if self.do_plot_local(): logplot.append((False, False))
                if self.do_plot_local(): logplot.append((False, False))
                if self.do_plot_intensity(): logplot.append((False, False))
            else:  # MIRROR
                if self.do_plot_local(): logplot.append((False, True))
                if self.do_plot_local(): logplot.append((False, True))
                if self.do_plot_local(): logplot.append((False, False))
                if self.do_plot_local(): logplot.append((False, False))
                if self.do_plot_local(): logplot.append((False, False))
                if self.do_plot_intensity(): logplot.append((False, False))

        return logplot

    def xoppy_calc_xpower(self):

        #
        # prepare input for xpower_calc
        # Note that the input for xpower_calc accepts any number of elements.
        #

        substance = [
            self.EL1_FOR, self.EL2_FOR, self.EL3_FOR, self.EL4_FOR,
            self.EL5_FOR
        ]
        thick = numpy.array((self.EL1_THI, self.EL2_THI, self.EL3_THI,
                             self.EL4_THI, self.EL5_THI))
        angle = numpy.array((self.EL1_ANG, self.EL2_ANG, self.EL3_ANG,
                             self.EL4_ANG, self.EL5_ANG))
        dens = [
            self.EL1_DEN, self.EL2_DEN, self.EL3_DEN, self.EL4_DEN,
            self.EL5_DEN
        ]
        roughness = numpy.array((self.EL1_ROU, self.EL2_ROU, self.EL3_ROU,
                                 self.EL4_ROU, self.EL5_ROU))
        flags = numpy.array((self.EL1_FLAG, self.EL2_FLAG, self.EL3_FLAG,
                             self.EL4_FLAG, self.EL5_FLAG))

        substance = substance[0:self.NELEMENTS + 1]
        thick = thick[0:self.NELEMENTS + 1]
        angle = angle[0:self.NELEMENTS + 1]
        dens = dens[0:self.NELEMENTS + 1]
        roughness = roughness[0:self.NELEMENTS + 1]
        flags = flags[0:self.NELEMENTS + 1]

        if self.SOURCE == 0:
            # energies = numpy.arange(0,500)
            # elefactor = numpy.log10(10000.0 / 30.0) / 300.0
            # energies = 10.0 * 10**(energies * elefactor)
            # source = numpy.ones(energies.size)
            # tmp = numpy.vstack( (energies,source))
            if self.input_spectrum is None:
                raise Exception("No input beam")
            else:
                energies = self.input_spectrum[0, :].copy()
                source = self.input_spectrum[1, :].copy()
        elif self.SOURCE == 1:
            energies = numpy.linspace(self.ENER_MIN, self.ENER_MAX,
                                      self.ENER_N)
            source = numpy.ones(energies.size)
            tmp = numpy.vstack((energies, source))
            self.input_spectrum = source
        elif self.SOURCE == 2:
            if self.SOURCE == 2: source_file = self.SOURCE_FILE
            # if self.SOURCE == 3: source_file = "SRCOMPE"
            # if self.SOURCE == 4: source_file = "SRCOMPF"
            try:
                tmp = numpy.loadtxt(source_file)
                energies = tmp[:, 0]
                source = tmp[:, 1]
                self.input_spectrum = source
            except:
                print("Error loading file %s " % (source_file))
                raise

        if self.FILE_DUMP == 0:
            output_file = None
        else:
            output_file = "power.spec"
        out_dictionary = xpower_calc(energies=energies,
                                     source=source,
                                     substance=substance,
                                     flags=flags,
                                     dens=dens,
                                     thick=thick,
                                     angle=angle,
                                     roughness=roughness,
                                     output_file=output_file)

        try:
            print(out_dictionary["info"])
        except:
            pass
        #send exchange
        calculated_data = DataExchangeObject(
            "XOPPY", self.get_data_exchange_widget_name())

        try:
            calculated_data.add_content("xoppy_data", out_dictionary["data"].T)
            calculated_data.add_content("plot_x_col", 0)
            calculated_data.add_content("plot_y_col", -1)
        except:
            pass
        try:
            # print(out_dictionary["labels"])
            calculated_data.add_content("labels", out_dictionary["labels"])
        except:
            pass
        try:
            calculated_data.add_content("info", out_dictionary["info"])
        except:
            pass

        return calculated_data
class BendableEllipsoidMirror(ow_ellipsoid_element.EllipsoidElement):
    name = "Bendable Ellipsoid Mirror"
    description = "Shadow OE: Bendable Ellipsoid Mirror"
    icon = "icons/bendable_ellipsoid_mirror.png"
    maintainer = "Luca Rebuffi"
    maintainer_email = "lrebuffi(@at@)anl.gov"
    priority = 6
    category = "Optical Elements"
    keywords = ["data", "file", "load", "read"]

    send_footprint_beam = QSettings().value("output/send-footprint", 0,
                                            int) == 1

    if send_footprint_beam:
        outputs = [{
            "name": "Beam",
            "type": ShadowBeam,
            "doc": "Shadow Beam",
            "id": "beam"
        }, {
            "name": "Footprint",
            "type": list,
            "doc": "Footprint",
            "id": "beam"
        }, {
            "name": "Trigger",
            "type": TriggerIn,
            "doc": "Feedback signal to start a new beam simulation",
            "id": "Trigger"
        }, {
            "name": "PreProcessor_Data",
            "type": ShadowPreProcessorData,
            "doc": "PreProcessor Data",
            "id": "PreProcessor_Data"
        }]
    else:
        outputs = [{
            "name": "Beam",
            "type": ShadowBeam,
            "doc": "Shadow Beam",
            "id": "beam"
        }, {
            "name": "Trigger",
            "type": TriggerIn,
            "doc": "Feedback signal to start a new beam simulation",
            "id": "Trigger"
        }, {
            "name": "PreProcessor_Data",
            "type": ShadowPreProcessorData,
            "doc": "PreProcessor Data",
            "id": "PreProcessor_Data"
        }]

    show_bender_plots = Setting(0)

    bender_bin_x = Setting(100)
    bender_bin_y = Setting(500)

    E = Setting(131000)
    h = Setting(10)

    kind_of_bender = Setting(1)
    shape = Setting(0)

    output_file_name = Setting("mirror_bender.dat")

    which_length = Setting(0)
    optimized_length = Setting(0.0)

    M1 = Setting(0.0)
    ratio = Setting(0.5)
    e = Setting(0.3)

    M1_out = 0.0
    ratio_out = 0.0
    e_out = 0.0

    M1_fixed = Setting(False)
    ratio_fixed = Setting(False)
    e_fixed = Setting(False)

    M1_min = Setting(0.0)
    ratio_min = Setting(0.0)
    e_min = Setting(0.0)

    M1_max = Setting(1000.0)
    ratio_max = Setting(10.0)
    e_max = Setting(1.0)

    def __init__(self):
        graphical_Options = ow_optical_element.GraphicalOptions(is_mirror=True)

        super().__init__(graphical_Options)

        tabs = gui.tabWidget(
            oasysgui.createTabPage(self.tabs_basic_setting, "Bender"))

        tab_bender = oasysgui.createTabPage(tabs, "Bender Setting")

        surface_box = oasysgui.widgetBox(tab_bender,
                                         "Surface Setting",
                                         addSpace=False,
                                         orientation="vertical")

        oasysgui.lineEdit(surface_box,
                          self,
                          "bender_bin_x",
                          "bins Sagittal",
                          labelWidth=260,
                          valueType=int,
                          orientation="horizontal")
        oasysgui.lineEdit(surface_box,
                          self,
                          "bender_bin_y",
                          "bins Transversal",
                          labelWidth=260,
                          valueType=int,
                          orientation="horizontal")

        material_box = oasysgui.widgetBox(tab_bender,
                                          "Bender Setting",
                                          addSpace=False,
                                          orientation="vertical")

        self.le_E = oasysgui.lineEdit(material_box,
                                      self,
                                      "E",
                                      "Young's Modulus ",
                                      labelWidth=260,
                                      valueType=float,
                                      orientation="horizontal")
        self.le_h = oasysgui.lineEdit(material_box,
                                      self,
                                      "h",
                                      "Thickness ",
                                      labelWidth=260,
                                      valueType=float,
                                      orientation="horizontal")

        gui.comboBox(material_box,
                     self,
                     "kind_of_bender",
                     label="Kind Of Bender ",
                     items=["Single Momentum", "Double Momentum"],
                     labelWidth=150,
                     orientation="horizontal",
                     callback=self.set_kind_of_bender)

        gui.comboBox(material_box,
                     self,
                     "shape",
                     label="Shape ",
                     items=["Trapezium", "Rectangle"],
                     labelWidth=150,
                     orientation="horizontal",
                     callback=self.set_shape)

        tab_fit = oasysgui.createTabPage(tabs, "Fit Setting")

        fit_box = oasysgui.widgetBox(tab_fit,
                                     "",
                                     addSpace=False,
                                     orientation="vertical")

        file_box = oasysgui.widgetBox(fit_box,
                                      "",
                                      addSpace=False,
                                      orientation="horizontal",
                                      height=25)
        self.le_output_file_name = oasysgui.lineEdit(file_box,
                                                     self,
                                                     "output_file_name",
                                                     "Out File Name",
                                                     labelWidth=100,
                                                     valueType=str,
                                                     orientation="horizontal")
        gui.button(file_box,
                   self,
                   "...",
                   callback=self.select_output_file,
                   width=20)

        length_box = oasysgui.widgetBox(fit_box,
                                        "",
                                        addSpace=False,
                                        orientation="horizontal")

        self.cb_optimized_length = gui.comboBox(length_box,
                                                self,
                                                "which_length",
                                                label="Optimized Length ",
                                                items=["Total", "Partial"],
                                                labelWidth=150,
                                                orientation="horizontal",
                                                callback=self.set_which_length)
        self.le_optimized_length = oasysgui.lineEdit(length_box,
                                                     self,
                                                     "optimized_length",
                                                     " ",
                                                     labelWidth=10,
                                                     valueType=float,
                                                     orientation="horizontal")
        self.set_which_length()

        gui.separator(fit_box)

        def add_parameter_box(container_box, variable, label):
            box = oasysgui.widgetBox(container_box,
                                     "",
                                     addSpace=False,
                                     orientation="horizontal")
            oasysgui.lineEdit(box,
                              self,
                              variable,
                              label,
                              labelWidth=50,
                              valueType=float,
                              orientation="horizontal")
            gui.label(box, self, " ", labelWidth=58)

            box = oasysgui.widgetBox(container_box,
                                     "",
                                     addSpace=False,
                                     orientation="horizontal")

            setattr(
                self, "le_" + variable + "_min",
                oasysgui.lineEdit(box,
                                  self,
                                  variable + "_min",
                                  "Min",
                                  labelWidth=50,
                                  valueType=float,
                                  orientation="horizontal"))
            setattr(
                self, "le_" + variable + "_max",
                oasysgui.lineEdit(box,
                                  self,
                                  variable + "_max",
                                  "Max",
                                  labelWidth=35,
                                  valueType=float,
                                  orientation="horizontal"))

            gui.checkBox(box,
                         self,
                         variable + "_fixed",
                         "Fixed",
                         callback=getattr(self, "set_" + variable))

            box = oasysgui.widgetBox(container_box,
                                     "",
                                     addSpace=False,
                                     orientation="horizontal")

            le = oasysgui.lineEdit(box,
                                   self,
                                   variable + "_out",
                                   "Fitted",
                                   labelWidth=50,
                                   valueType=float,
                                   orientation="horizontal")
            le.setEnabled(False)
            le.setStyleSheet(
                "color: blue; background-color: rgb(254, 244, 205); font:bold")

            def set_variable_fit():
                setattr(self, variable, getattr(self, variable + "_out"))

            gui.button(box,
                       self,
                       "<- Use",
                       width=58,
                       callback=set_variable_fit)

            getattr(self, "set_" + variable)()

        m1_box = oasysgui.widgetBox(fit_box,
                                    "",
                                    addSpace=False,
                                    orientation="vertical")
        gui.separator(fit_box, 10)
        self.ratio_box = oasysgui.widgetBox(fit_box,
                                            "",
                                            addSpace=False,
                                            orientation="vertical")
        gui.separator(fit_box, 10)
        self.e_box = oasysgui.widgetBox(fit_box,
                                        "",
                                        addSpace=False,
                                        orientation="vertical")
        gui.separator(fit_box, 10)

        add_parameter_box(m1_box, "M1", "M1")
        add_parameter_box(self.ratio_box, "ratio", "M1/M2")
        add_parameter_box(self.e_box, "e", "e")

        self.set_kind_of_bender()
        self.set_shape()

        #######################################################

        plot_tab = oasysgui.createTabPage(self.main_tabs, "Bender Plots")

        view_box = oasysgui.widgetBox(plot_tab,
                                      "Plotting Style",
                                      addSpace=False,
                                      orientation="vertical",
                                      width=350)

        self.view_type_combo = gui.comboBox(view_box,
                                            self,
                                            "show_bender_plots",
                                            label="Show Plots",
                                            labelWidth=220,
                                            items=["No", "Yes"],
                                            sendSelectedValue=False,
                                            orientation="horizontal")

        bender_tabs = oasysgui.tabWidget(plot_tab)

        tabs = [
            oasysgui.createTabPage(bender_tabs, "Bender vs. Ideal (1D)"),
            oasysgui.createTabPage(bender_tabs, "Ideal - Bender (1D)"),
            oasysgui.createTabPage(bender_tabs, "Ideal - Bender (3D)"),
            oasysgui.createTabPage(bender_tabs, "Figure Error (3D)"),
            oasysgui.createTabPage(bender_tabs,
                                   "Ideal - Bender + Figure Error (3D)")
        ]

        def create_figure_canvas(mode="3D"):
            figure = Figure(figsize=(100, 100))
            figure.patch.set_facecolor('white')
            if mode == "3D": figure.add_subplot(111, projection='3d')
            else: figure.add_subplot(111)

            figure_canvas = FigureCanvasQTAgg(figure)
            figure_canvas.setFixedWidth(self.IMAGE_WIDTH)
            figure_canvas.setFixedHeight(self.IMAGE_HEIGHT - 10)

            return figure_canvas

        self.figure_canvas = [
            create_figure_canvas("1D"),
            create_figure_canvas("1D"),
            create_figure_canvas(),
            create_figure_canvas(),
            create_figure_canvas()
        ]

        for tab, figure_canvas in zip(tabs, self.figure_canvas):
            tab.layout().addWidget(figure_canvas)

        gui.rubber(self.controlArea)
        gui.rubber(self.mainArea)

    ################################################################
    #
    #  SHADOW MANAGEMENT
    #
    ################################################################

    def select_output_file(self):
        self.le_output_file_name.setText(
            oasysgui.selectFileFromDialog(
                self,
                self.output_file_name,
                "Select Output File",
                file_extension_filter="Data Files (*.dat)"))

    def set_kind_of_bender(self):
        self.ratio_box.setVisible(self.kind_of_bender == 1)

    def set_shape(self):
        self.e_box.setVisible(self.shape == 0)

    def set_which_length(self):
        self.le_optimized_length.setEnabled(self.which_length == 1)

    def set_M1(self):
        self.le_M1_min.setEnabled(self.M1_fixed == False)
        self.le_M1_max.setEnabled(self.M1_fixed == False)

    def set_ratio(self):
        self.le_ratio_min.setEnabled(self.ratio_fixed == False)
        self.le_ratio_max.setEnabled(self.ratio_fixed == False)

    def set_e(self):
        self.le_e_min.setEnabled(self.e_fixed == False)
        self.le_e_max.setEnabled(self.e_fixed == False)

    def after_change_workspace_units(self):
        super().after_change_workspace_units()

        label = self.le_E.parent().layout().itemAt(0).widget()
        label.setText(label.text() + " [N/" + self.workspace_units_label +
                      "^2]")
        label = self.le_h.parent().layout().itemAt(0).widget()
        label.setText(label.text() + " [" + self.workspace_units_label + "]")
        label = self.cb_optimized_length.parent().layout().itemAt(0).widget()
        label.setText(label.text() + " [" + self.workspace_units_label + "]")

    def checkFields(self):
        super().checkFields()

        if self.is_cylinder != 1:
            raise ValueError("Bender Ellipse must be a cylinder")
        if self.cylinder_orientation != 0:
            raise ValueError("Cylinder orientation must be 0")
        if self.is_infinite == 0:
            raise ValueError("This OE can't have infinite dimensions")
        if self.which_length == 1:
            congruence.checkStrictlyPositiveNumber(self.optimized_length,
                                                   "Optimized Length")
            congruence.checkLessOrEqualThan(self.optimized_length,
                                            self.dim_y_plus + self.dim_y_minus,
                                            "Optimized Length", "Total Length")

        if self.modified_surface > 0:
            if not (self.modified_surface == 1
                    and self.ms_type_of_defect == 2):
                raise ValueError(
                    "Only Preprocessor generated error profiles are admitted")

        congruence.checkStrictlyPositiveNumber(self.bender_bin_x, "Bins X")
        congruence.checkStrictlyPositiveNumber(self.bender_bin_y, "Bins Y")
        self.output_file_name_full = congruence.checkFileName(
            self.output_file_name)

    def completeOperations(self, shadow_oe):
        shadow_oe_temp = shadow_oe.duplicate()
        input_beam_temp = self.input_beam.duplicate(history=False)

        self.manage_acceptance_slits(shadow_oe_temp)

        ShadowBeam.traceFromOE(input_beam_temp,
                               shadow_oe_temp,
                               write_start_file=0,
                               write_end_file=0,
                               widget_class_name=type(self).__name__)

        x, y, z = self.calculate_ideal_surface(shadow_oe_temp)

        bender_parameter, z_bender_correction = self.calculate_bender_correction(
            y, z, self.kind_of_bender, self.shape)

        self.M1_out = round(bender_parameter[0],
                            int(6 * self.workspace_units_to_mm))
        if self.shape == TRAPEZIUM:
            self.e_out = round(bender_parameter[1], 5)
            if self.kind_of_bender == DOUBLE_MOMENTUM:
                self.ratio_out = round(bender_parameter[2], 5)
        elif self.shape == RECTANGLE:
            if self.kind_of_bender == DOUBLE_MOMENTUM:
                self.ratio_out = round(bender_parameter[1], 5)

        self.plot3D(x, y, z_bender_correction, 2, "Ideal - Bender Surfaces")

        if self.modified_surface > 0:
            x_e, y_e, z_e = ShadowPreProcessor.read_surface_error_file(
                self.ms_defect_file_name)

            if len(x) == len(x_e) and len(y) == len(y_e) and \
                    x[0] == x_e[0] and x[-1] == x_e[-1] and \
                    y[0] == y_e[0] and y[-1] == y_e[-1]:
                z_figure_error = z_e
            else:
                z_figure_error = interp2d(y_e, x_e, z_e, kind='cubic')(y, x)

            z_bender_correction += z_figure_error

            self.plot3D(x, y, z_figure_error, 3, "Figure Error Surface")
            self.plot3D(x, y, z_bender_correction, 4,
                        "Ideal - Bender + Figure Error Surfaces")

        ST.write_shadow_surface(z_bender_correction.T, numpy.round(x, 6),
                                numpy.round(y, 6), self.output_file_name_full)

        # Add new surface as figure error
        shadow_oe._oe.F_RIPPLE = 1
        shadow_oe._oe.F_G_S = 2
        shadow_oe._oe.FILE_RIP = bytes(self.output_file_name_full, 'utf-8')

        # Redo Raytracing with the new file
        super().completeOperations(shadow_oe)

        self.send(
            "PreProcessor_Data",
            ShadowPreProcessorData(
                error_profile_data_file=self.output_file_name,
                error_profile_x_dim=self.dim_x_plus + self.dim_x_minus,
                error_profile_y_dim=self.dim_y_plus + self.dim_y_minus))

    def instantiateShadowOE(self):
        return ShadowOpticalElement.create_ellipsoid_mirror()

    def calculate_ideal_surface(self, shadow_oe, sign=-1):
        x = numpy.linspace(-self.dim_x_minus, self.dim_x_plus,
                           self.bender_bin_x + 1)
        y = numpy.linspace(-self.dim_y_minus, self.dim_y_plus,
                           self.bender_bin_y + 1)

        c1 = round(shadow_oe._oe.CCC[0], 10)
        c2 = round(shadow_oe._oe.CCC[1], 10)
        c3 = round(shadow_oe._oe.CCC[2], 10)
        c4 = round(shadow_oe._oe.CCC[3], 10)
        c5 = round(shadow_oe._oe.CCC[4], 10)
        c6 = round(shadow_oe._oe.CCC[5], 10)
        c7 = round(shadow_oe._oe.CCC[6], 10)
        c8 = round(shadow_oe._oe.CCC[7], 10)
        c9 = round(shadow_oe._oe.CCC[8], 10)
        c10 = round(shadow_oe._oe.CCC[9], 10)

        xx, yy = numpy.meshgrid(x, y)

        c = c1 * (xx**2) + c2 * (yy**
                                 2) + c4 * xx * yy + c7 * xx + c8 * yy + c10
        b = c5 * yy + c6 * xx + c9
        a = c3

        z = (-b + sign * numpy.sqrt(b**2 - 4 * a * c)) / (2 * a)
        z[b**2 - 4 * a * c < 0] = numpy.nan

        return x, y, z.T

    def calculate_bender_correction(self, y, z, kind_of_bender, shape):
        b0 = self.dim_x_plus + self.dim_x_minus
        L = self.dim_y_plus + self.dim_y_minus  # add optimization length

        # flip the coordinate system to be consistent with Mike's formulas
        ideal_profile = z[
            0, :][::
                  -1]  # one row is the profile of the cylinder, enough for the minimizer
        ideal_profile += -ideal_profile[0] + (
            (L / 2 + y) *
            (ideal_profile[0] - ideal_profile[-1])) / L  # Rotation

        if self.which_length == 0:
            y_fit = y
            ideal_profile_fit = ideal_profile
        else:
            cursor = numpy.where(
                numpy.logical_and(y >= -self.optimized_length / 2,
                                  y <= self.optimized_length / 2))
            y_fit = y[cursor]
            ideal_profile_fit = ideal_profile[cursor]

        epsilon_minus = 1 - 1e-8
        epsilon_plus = 1 + 1e-8

        Eh_3 = self.E * self.h**3

        initial_guess = None
        constraints = None
        bender_function = None

        if shape == TRAPEZIUM:

            def general_bender_function(Y, M1, e, ratio):
                M2 = M1 * ratio
                A = (M1 + M2) / 2
                B = (M1 - M2) / L
                C = Eh_3 * (2 * b0 + e * b0) / 24
                D = Eh_3 * e * b0 / (12 * L)
                H = (A * D + B * C) / D**2
                CDLP = C + D * L / 2
                CDLM = C - D * L / 2
                F = (H / L) * (
                    (CDLM * numpy.log(CDLM) - CDLP * numpy.log(CDLP)) / D + L)
                G = (-H * ((CDLM * numpy.log(CDLM) + CDLP * numpy.log(CDLP))) +
                     (B * L**2) / 4) / (2 * D)
                CDY = C + D * Y

                return H * ((CDY / D) * numpy.log(CDY) -
                            Y) - (B * Y**2) / (2 * D) + F * Y + G

            def bender_function_2m(Y, M1, e, ratio):
                return general_bender_function(Y, M1, e, ratio)

            def bender_function_1m(Y, M1, e):
                return general_bender_function(Y, M1, e, 1.0)

            if kind_of_bender == SINGLE_MOMENTUM:
                bender_function = bender_function_1m
                initial_guess = [self.M1, self.e]
                constraints = [[
                    self.M1_min if self.M1_fixed == False else
                    (self.M1 * epsilon_minus),
                    self.e_min if self.e_fixed == False else
                    (self.e * epsilon_minus)
                ],
                               [
                                   self.M1_max if self.M1_fixed == False else
                                   (self.M1 * epsilon_plus),
                                   self.e_max if self.e_fixed == False else
                                   (self.e * epsilon_plus)
                               ]]
            elif kind_of_bender == DOUBLE_MOMENTUM:
                bender_function = bender_function_2m
                initial_guess = [self.M1, self.e, self.ratio]
                constraints = [
                    [
                        self.M1_min if self.M1_fixed == False else
                        (self.M1 * epsilon_minus),
                        self.e_min if self.e_fixed == False else
                        (self.e * epsilon_minus),
                        self.ratio_min if self.ratio_fixed == False else
                        (self.ratio * epsilon_minus)
                    ],
                    [
                        self.M1_max if self.M1_fixed == False else
                        (self.M1 * epsilon_plus),
                        self.e_max if self.e_fixed == False else
                        (self.e * epsilon_plus),
                        self.ratio_max if self.ratio_fixed == False else
                        (self.ratio * epsilon_plus)
                    ]
                ]
        elif shape == RECTANGLE:

            def general_bender_function(Y, M1, ratio):
                M2 = M1 * ratio
                A = (M1 + M2) / 2
                B = (M1 - M2) / L
                C = Eh_3 * b0 / 12
                F = (B * L**2) / (24 * C)
                G = -(A * L**2) / (8 * C)

                return -(B * Y**3) / (6 * C) + (A * Y**2) / (2 * C) + F * Y + G

            def bender_function_2m(Y, M1, ratio):
                return general_bender_function(Y, M1, ratio)

            def bender_function_1m(Y, M1):
                return general_bender_function(Y, M1, 1.0)

            if kind_of_bender == SINGLE_MOMENTUM:
                bender_function = bender_function_1m
                initial_guess = [self.M1]
                constraints = [[
                    self.M1_min if self.M1_fixed == False else
                    (self.M1 * epsilon_minus)
                ],
                               [
                                   self.M1_max if self.M1_fixed == False else
                                   (self.M1 * epsilon_plus)
                               ]]
            elif kind_of_bender == DOUBLE_MOMENTUM:
                bender_function = bender_function_2m
                initial_guess = [self.M1, self.ratio]
                constraints = [
                    [
                        self.M1_min if self.M1_fixed == False else
                        (self.M1 * epsilon_minus),
                        self.ratio_min if self.ratio_fixed == False else
                        (self.ratio * epsilon_minus)
                    ],
                    [
                        self.M1_max if self.M1_fixed == False else
                        (self.M1 * epsilon_plus),
                        self.ratio_max if self.ratio_fixed == False else
                        (self.ratio * epsilon_plus)
                    ]
                ]

        parameters, _ = curve_fit(f=bender_function,
                                  xdata=y_fit,
                                  ydata=ideal_profile_fit,
                                  p0=initial_guess,
                                  bounds=constraints,
                                  method='trf')

        if len(parameters) == 1:
            bender_profile = bender_function(y, parameters[0])
        elif len(parameters) == 2:
            bender_profile = bender_function(y, parameters[0], parameters[1])
        else:
            bender_profile = bender_function(y, parameters[0], parameters[1],
                                             parameters[2])

        # rotate back to Shadow system
        bender_profile = bender_profile[::-1]
        ideal_profile = ideal_profile[::-1]

        # from here it's Shadow Axis system
        correction_profile = ideal_profile - bender_profile
        if self.which_length == 1:
            correction_profile_fit = correction_profile[cursor]

        # r-squared = 1 - residual sum of squares / total sum of squares
        r_squared = 1 - (numpy.sum(correction_profile**2) / numpy.sum(
            (ideal_profile - numpy.mean(ideal_profile))**2))
        rms = round(correction_profile.std() * 1e9 * self.workspace_units_to_m,
                    6)
        if self.which_length == 1:
            rms_opt = round(
                correction_profile_fit.std() * 1e9 * self.workspace_units_to_m,
                6)

        self.plot1D(y,
                    bender_profile,
                    y_values_2=ideal_profile,
                    index=0,
                    title="Bender vs. Ideal Profiles" + "\n" + r'$R^2$ = ' +
                    str(r_squared),
                    um=1)
        self.plot1D(y,
                    correction_profile,
                    index=1,
                    title="Correction Profile 1D, r.m.s. = " + str(rms) +
                    " nm" + ("" if self.which_length == 0 else
                             (", " + str(rms_opt) + " nm (optimized)")))

        z_bender_correction = numpy.zeros(z.shape)
        for i in range(z_bender_correction.shape[0]):
            z_bender_correction[i, :] = numpy.copy(correction_profile)

        return parameters, z_bender_correction

    def plot1D(self,
               x_coords,
               y_values,
               y_values_2=None,
               index=0,
               title="",
               um=0):
        if self.show_bender_plots == 1:
            figure = self.figure_canvas[index].figure

            axis = figure.gca()
            axis.clear()

            axis.set_xlabel("Y [" + self.workspace_units_label + "]")
            axis.set_ylabel("Z [" + ("nm" if um == 0 else "\u03bcm") + "]")
            axis.set_title(title)

            axis.plot(x_coords, (y_values * self.workspace_units_to_m *
                                 (1e9 if um == 0 else 1e6)),
                      color="blue",
                      label="bender",
                      linewidth=2)
            if not y_values_2 is None:
                axis.plot(x_coords, (y_values_2 * self.workspace_units_to_m *
                                     (1e9 if um == 0 else 1e6)),
                          "-.r",
                          label="ideal")

            axis.legend(loc=0, fontsize='small')

            figure.canvas.draw()

    def plot3D(self, x_coords, y_coords, z_values, index, title=""):
        if self.show_bender_plots == 1:
            figure = self.figure_canvas[index].figure
            x_to_plot, y_to_plot = numpy.meshgrid(x_coords, y_coords)
            z_to_plot = z_values.T

            axis = figure.gca()
            axis.clear()

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

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

            figure.canvas.draw()

            axis.mouse_init()
Example #6
0
class OWxfh(XoppyWidget):
    name = "Fh"
    id = "orange.widgets.dataxfh"
    description = "Crystal Structure Factors"
    icon = "icons/xoppy_xfh.png"
    priority = 17
    category = ""
    keywords = ["xoppy", "xfh"]

    ILATTICE = Setting(32)
    HMILLER = Setting(1)
    KMILLER = Setting(1)
    LMILLER = Setting(1)
    plot_variable = Setting(0)
    I_PLOT = Setting(2)
    TEMPER = Setting(1.0)
    ENERGY = Setting(8000.0)
    ENERGY_END = Setting(18000.0)
    NPOINTS = Setting(20)
    DUMP_TO_FILE = Setting(0)  # No
    FILE_NAME = Setting("Fh.dat")

    def build_gui(self):

        box = oasysgui.widgetBox(self.controlArea,
                                 self.name + " Input Parameters",
                                 orientation="vertical",
                                 width=self.CONTROL_AREA_WIDTH - 5)

        idx = -1

        #widget index 3
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "ILATTICE",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=Crystal_GetCrystalsList(),
                     valueType=int,
                     orientation="horizontal",
                     labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 4
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "HMILLER",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          validator=QIntValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 5
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "KMILLER",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          validator=QIntValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 6
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "LMILLER",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          validator=QIntValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 7
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "plot_variable",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=self.plotOptionList()[2:],
                     valueType=int,
                     orientation="horizontal",
                     labelWidth=150)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 8
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "TEMPER",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          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)

        #widget index 10
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "ENERGY_END",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 11
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "NPOINTS",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          validator=QIntValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        # widget index 12
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "DUMP_TO_FILE",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     items=["No", "Yes"],
                     orientation="horizontal")
        self.show_at(self.unitFlags()[idx], box1)

        # widget index 13
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "FILE_NAME",
                     label=self.unitLabels()[idx],
                     addSpace=True)
        self.show_at(self.unitFlags()[idx], box1)

        gui.rubber(self.controlArea)

    def unitLabels(self):
        return [
            'Crystal:', 'h miller index', 'k miller index', 'l miller index',
            'Plot:', 'Temperature factor [see help]:', 'From Energy [eV]',
            'To energy [eV]', 'Number of points', 'Dump to file', 'File name'
        ]

    def unitFlags(self):
        return [
            'True', 'True', 'True', 'True', 'True', 'True', 'True', 'True',
            'True', "True", "self.DUMP_TO_FILE == 1"
        ]

    def plotOptionList(self):
        return [
            "Photon energy [eV]", "Wavelength [A]", "Bragg angle [deg]",
            "Re(f_0)", "Im(f_0)  ", "Re(FH)", "Im(FH)", "Re(FH_BAR)",
            "Im(FH_BAR)", "Re(psi_0)", "Im(psi_0)  ", "Re(psi_H)", "Im(psi_H)",
            "Re(psi_BAR)", "Im(psi_BAR)", "Re(F(h,k,l))", "Im(F(h,k,l))",
            "delta (1-Re(refrac))", "Re(refrac index)", "Im(refrac index)",
            "absorption coeff", "s-pol Darwin width [microrad]",
            "p-pol Darwin width [microrad]", "Sin(Bragg angle)/Lambda",
            "psi_over_f"
        ]

    def get_help_name(self):
        return 'fh'

    def check_fields(self):
        self.HMILLER = congruence.checkNumber(self.HMILLER, "h miller index")
        self.KMILLER = congruence.checkNumber(self.KMILLER, "k miller index")
        self.LMILLER = congruence.checkNumber(self.LMILLER, "l miller index")

        self.TEMPER = congruence.checkNumber(self.TEMPER, "Temperature factor")

        self.ENERGY = congruence.checkPositiveNumber(self.ENERGY,
                                                     "Energy from")
        self.ENERGY_END = congruence.checkStrictlyPositiveNumber(
            self.ENERGY_END, "Energy to")
        congruence.checkLessThan(self.ENERGY, self.ENERGY_END, "Energy from",
                                 "Energy to")
        self.NPOINTS = congruence.checkStrictlyPositiveNumber(
            self.NPOINTS, "Number of Points")

    def do_xoppy_calculation(self):
        self.I_PLOT = self.plot_variable + 2

        return self.xoppy_calc_xfh()

    def extract_data_from_xoppy_output(self, calculation_output):
        return calculation_output

    def get_data_exchange_widget_name(self):
        return "XFH"

    def getTitles(self):
        return ["Calculation Result"]

    def getXTitles(self):
        return ["Energy [eV]"]

    def getYTitles(self):
        return [self.plotOptionList()[self.I_PLOT]]

    def getVariablesToPlot(self):
        return [(0, self.I_PLOT)]

    def getLogPlot(self):
        return [(False, False)]

    def xoppy_calc_xfh(self):
        #TODO: remove I_ABSORP
        ILATTICE = self.ILATTICE
        HMILLER = self.HMILLER
        KMILLER = self.KMILLER
        LMILLER = self.LMILLER
        I_PLOT = self.I_PLOT
        TEMPER = self.TEMPER
        ENERGY = self.ENERGY
        ENERGY_END = self.ENERGY_END
        NPOINTS = self.NPOINTS

        descriptor = Crystal_GetCrystalsList()[ILATTICE]
        print("Using crystal descriptor: ", descriptor)
        bragg_dictionary = bragg_calc(descriptor=descriptor,
                                      hh=HMILLER,
                                      kk=KMILLER,
                                      ll=LMILLER,
                                      temper=TEMPER,
                                      emin=ENERGY,
                                      emax=ENERGY_END,
                                      estep=50.0,
                                      fileout=None)

        energy = numpy.linspace(ENERGY, ENERGY_END, NPOINTS)

        out = numpy.zeros((25, NPOINTS))

        info = ""
        for i, ienergy in enumerate(energy):
            dic2 = crystal_fh(bragg_dictionary, ienergy)
            print("Energy=%g eV FH=(%g,%g)" %
                  (ienergy, dic2["STRUCT"].real, dic2["STRUCT"].imag))

            out[0, i] = ienergy
            out[1, i] = dic2["WAVELENGTH"] * 1e10
            out[2, i] = dic2["THETA"] * 180 / numpy.pi
            out[3, i] = dic2["F_0"].real
            out[4, i] = dic2["F_0"].imag
            out[5, i] = dic2["FH"].real
            out[6, i] = dic2["FH"].imag
            out[7, i] = dic2["FH_BAR"].real
            out[8, i] = dic2["FH_BAR"].imag
            out[9, i] = dic2["psi_0"].real
            out[10, i] = dic2["psi_0"].imag
            out[11, i] = dic2["psi_h"].real
            out[12, i] = dic2["psi_h"].imag
            out[13, i] = dic2["psi_hbar"].real
            out[14, i] = dic2["psi_hbar"].imag
            out[15, i] = dic2["STRUCT"].real
            out[16, i] = dic2["STRUCT"].imag
            out[17, i] = dic2["DELTA_REF"]
            out[18, i] = dic2["REFRAC"].real
            out[19, i] = dic2["REFRAC"].imag
            out[20, i] = dic2["ABSORP"]
            out[21, i] = 1e6 * dic2["ssr"]  # in microrads
            out[22, i] = 1e6 * dic2["spr"]  # in microrads
            out[23, i] = dic2["RATIO"]
            out[24, i] = dic2["psi_over_f"]
            info += "#\n#\n#\n"
            info += dic2["info"]

        #send exchange
        calculated_data = DataExchangeObject(
            "XOPPY", self.get_data_exchange_widget_name())

        try:
            calculated_data.add_content("xoppy_data", out.T)
            calculated_data.add_content("plot_x_col", 0)
            calculated_data.add_content("plot_y_col", I_PLOT)
        except:
            pass
        try:
            calculated_data.add_content("labels", self.plotOptionList())
        except:
            pass
        try:
            calculated_data.add_content("info", info)
        except:
            pass

        if self.DUMP_TO_FILE:
            with open(self.FILE_NAME, "w") as file:
                try:
                    file.write("#F %s\n" % self.FILE_NAME)
                    file.write("\n#S 1 xoppy CrossSec results\n")
                    file.write("#N %d\n" % (out.shape[0]))
                    tmp = "#L"
                    for item in self.plotOptionList():
                        tmp += "  %s" % (item)
                    tmp += "\n"
                    file.write(tmp)
                    for j in range(out.shape[1]):
                        file.write(
                            ("%19.12e  " * out.shape[0] + "\n") %
                            tuple(out[i, j] for i in range(out.shape[0])))
                    file.close()
                    print("File written to disk: %s \n" % self.FILE_NAME)
                except:
                    raise Exception(
                        "CrossSec: The data could not be dumped onto the specified file!\n"
                    )

        return calculated_data
Example #7
0
class OWMlultilayer(XoppyWidget):
    name = "Multilayer"
    id = "orange.widgets.datamlayer"
    description = "Multilayer Reflectivity"
    icon = "icons/xoppy_mlayer.png"
    priority = 11
    category = ""
    keywords = ["xoppy", "multilayer"]

    MATERIAL_S = Setting("Si")
    DENSITY_S = Setting("?")
    ROUGHNESS_S = Setting(0.0)

    MATERIAL_E = Setting("W")
    DENSITY_E = Setting("?")
    ROUGHNESS_E = Setting(0.0)

    MATERIAL_O = Setting("Si")
    DENSITY_O = Setting("?")
    ROUGHNESS_O = Setting(0.0)

    THICKNESS = Setting(50.0)
    GAMMA = Setting(0.5)
    NLAYERS = Setting(50)

    THETA_FLAG = Setting(1)
    THETA_N = Setting(600)
    THETA = Setting(0.0)
    THETA_END = Setting(6.0)

    ENERGY_FLAG = Setting(0)
    ENERGY_N = Setting(100)
    ENERGY = Setting(8050.)
    ENERGY_END = Setting(15000.0)

    DUMP_TO_FILE = Setting(0)
    FILE_NAME = Setting("multilayer.h5")

    def __init__(self):
        super().__init__(show_script_tab=True)

    def build_gui(self):

        box0 = oasysgui.widgetBox(self.controlArea,
                                  self.name + " Input Parameters",
                                  orientation="vertical",
                                  width=self.CONTROL_AREA_WIDTH - 5)

        idx = -1

        #
        #
        #
        box = gui.widgetBox(box0, "Substrate", orientation="vertical")

        #widget index 0
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "MATERIAL_S",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 1
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "DENSITY_S",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 2
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "ROUGHNESS_S",
                          valueType=float,
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #
        #
        #
        box = gui.widgetBox(box0,
                            "Even layer (closer to substrate)",
                            orientation="vertical")

        #widget index 3
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "MATERIAL_E",
                          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)
        oasysgui.lineEdit(box1,
                          self,
                          "DENSITY_E",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 5
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "ROUGHNESS_E",
                          valueType=float,
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #
        #
        #
        box = gui.widgetBox(box0,
                            "Odd layer (close to vacuum)",
                            orientation="vertical")
        #widget index 6
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "MATERIAL_O",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 7
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "DENSITY_O",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 8
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "ROUGHNESS_O",
                          valueType=float,
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #
        #
        #
        box = gui.widgetBox(box0, "Bilayers", orientation="vertical")
        #widget index 9
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "THICKNESS",
                          valueType=float,
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 10
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "GAMMA",
                          valueType=float,
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 11
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "NLAYERS",
                          valueType=int,
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #
        #
        #
        box = gui.widgetBox(box0, "scan - angle", orientation="vertical")
        #widget index 12
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "THETA_FLAG",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=['Single Value', 'Scan'],
                     valueType=int,
                     orientation="horizontal",
                     labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        # widget index 13
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "THETA",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        # widget index 14
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "THETA_END",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        # widget index 15
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "THETA_N",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #
        #
        #
        box = gui.widgetBox(box0, "scan - energy", orientation="vertical")
        #widget index 16
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "ENERGY_FLAG",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=['Single Value', 'Scan'],
                     valueType=int,
                     orientation="horizontal",
                     labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        # widget index 17
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "ENERGY",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        # widget index 18
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "ENERGY_END",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        # widget index 19
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "ENERGY_N",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #
        #
        #
        box = gui.widgetBox(box0, "output", orientation="vertical")

        # widget index 20
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "DUMP_TO_FILE",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     items=["No", "Yes"],
                     orientation="horizontal")
        self.show_at(self.unitFlags()[idx], box1)

        # widget index 21
        idx += 1
        box1 = gui.widgetBox(box, orientation="horizontal")
        gui.lineEdit(box1,
                     self,
                     "FILE_NAME",
                     label=self.unitLabels()[idx],
                     addSpace=True)
        self.show_at(self.unitFlags()[idx], box1)

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

        gui.rubber(self.controlArea)

    def unitLabels(self):
        return [
            'material: ',
            'density [g/cm3]:',
            'roughness [A]',
            'material: ',
            'density [g/cm3]:',
            'roughness [A]',
            'material: ',
            'density [g/cm3]:',
            'roughness [A]',
            'Bilayer thickness [A]',
            'Bilayer gamma [t_even/(t_even+t_odd)]',
            'Number of bilayers:',
            'Grazing angle [deg]',
            'Start Graz angle [deg]',
            'End Graz angle [deg]',
            'Number of angular points',
            'Photon energy',
            'Start Energy [eV]: ',
            'End Energy [eV]: ',
            'Number of energy points',
            'Dump to file',
            'File name',
        ]

    def unitFlags(self):
        return [
            "True",  #  'material: ',
            "True",  #  'density [g/cm3]:',
            "True",  #  'roughness [A]',
            "True",  #  'material: ',
            "True",  #  'density [g/cm3]:',
            "True",  #  'roughness [A]',
            "True",  #  'material: ',
            "True",  #  'density [g/cm3]:',
            "True",  #  'roughness [A]',
            "True",  #  'Bilayer thickness [A]',
            "True",  #  'Bilayer gamma [t_even/(t_even+t_odd)]',,
            "True",  #  'Number of bilayers:',
            "True",  #  'Grazing angle [deg]',
            "True",  #  'Start Graz angle [deg]',
            "self.THETA_FLAG == 1",  #  'End Graz angle [deg]',
            "self.THETA_FLAG == 1",  #  'Number of angular points',
            "True",  #  'Photon energy',
            "True",  #  'Start Energy [eV]: ',
            "self.ENERGY_FLAG == 1",  #  'End Energy [eV]: ',
            "self.ENERGY_FLAG == 1",  #  'Number of energy points',
            "True",  #  'Dump to file',
            "self.DUMP_TO_FILE == 1",  #  'File name',
        ]

    def get_help_name(self):
        return 'multilayer'

    def selectFile(self):
        self.FILE_NAME.setText(
            oasysgui.selectFileFromDialog(self,
                                          self.FILE,
                                          "Open File For Output",
                                          file_extension_filter="*.h5 *.hdf"))

    def check_fields(self):
        self.MATERIAL_S = congruence.checkEmptyString(self.MATERIAL_S,
                                                      "Substrate")
        self.MATERIAL_E = congruence.checkEmptyString(self.MATERIAL_E,
                                                      "Substrate")
        self.MATERIAL_O = congruence.checkEmptyString(self.MATERIAL_O,
                                                      "Substrate")

        self.ENERGY = congruence.checkStrictlyPositiveNumber(
            self.ENERGY, "Photon energy")
        self.THETA = congruence.checkPositiveNumber(self.THETA,
                                                    "Grazing angle")

        if self.ENERGY_FLAG == 1:
            self.ENERGY_END = congruence.checkStrictlyPositiveNumber(
                self.ENERGY_END, "Photon energy")
            self.ENERGY_N = congruence.checkStrictlyPositiveNumber(
                self.ENERGY_N, "Number of energy points")

        if self.THETA_FLAG == 1:
            self.THETA_END = congruence.checkStrictlyPositiveNumber(
                self.THETA_END, "Grazing angle")
            self.THETA_N = congruence.checkStrictlyPositiveNumber(
                self.THETA_N, "Number of angle points")

        self.THICKNESS = congruence.checkStrictlyPositiveNumber(
            self.THICKNESS, "Bilayer thickness")
        self.GAMMA = congruence.checkStrictlyPositiveNumber(
            self.GAMMA, "Bilayer gamma")
        self.NLAYERS = congruence.checkStrictlyPositiveNumber(
            self.NLAYERS, "Number of bilayers")
        #
        self.ROUGHNESS_O = congruence.checkPositiveNumber(
            self.ROUGHNESS_O, "Roughness odd material")
        self.ROUGHNESS_E = congruence.checkPositiveNumber(
            self.ROUGHNESS_E, "Roughness even material")
        self.ROUGHNESS_S = congruence.checkPositiveNumber(
            self.ROUGHNESS_S, "Roughness substrate material")

    def do_xoppy_calculation(self):

        # density_S = self.DENSITY_S
        # density_E = self.DENSITY_E
        # density_O = self.DENSITY_O
        #
        # if density_S == "?": density_S = None
        # if density_E == "?": density_E = None
        # if density_O == "?": density_O = None

        try:
            density_S = float(self.DENSITY_S)
        except:
            density_S = density(self.MATERIAL_S)

        try:
            density_E = float(self.DENSITY_E)
        except:
            density_E = density(self.MATERIAL_E)

        try:
            density_O = float(self.DENSITY_O)
        except:
            density_O = density(self.MATERIAL_O)

        print(
            "Using density:\n  substrate(%s): %f\n  even(%s): %f\n  odd(%s): %f"
            % (
                self.MATERIAL_S,
                density_S,
                self.MATERIAL_E,
                density_E,
                self.MATERIAL_O,
                density_O,
            ))

        out = MLayer.initialize_from_bilayer_stack(
            material_S=self.MATERIAL_S,
            density_S=density_S,
            roughness_S=self.ROUGHNESS_S,  # 2.33
            material_E=self.MATERIAL_E,
            density_E=density_E,
            roughness_E=self.ROUGHNESS_E,  # 19.3
            material_O=self.MATERIAL_O,
            density_O=density_O,
            roughness_O=self.ROUGHNESS_O,  # 2.33
            bilayer_pairs=self.NLAYERS,
            bilayer_thickness=self.THICKNESS,
            bilayer_gamma=self.GAMMA,
        )

        for key in out.pre_mlayer_dict.keys():
            print(key, out.pre_mlayer_dict[key])
        #
        if self.ENERGY_FLAG == 0:
            energyN = 1
        else:
            energyN = self.ENERGY_N

        if self.THETA_FLAG == 0:
            thetaN = 1
        else:
            thetaN = self.THETA_N

        if self.DUMP_TO_FILE:
            h5file = self.FILE_NAME
        else:
            h5file = ""

        if energyN * thetaN > 10000:
            result = QMessageBox.question(
                self, "Confirmation",
                "Are you sure you want to calculate %d points in E times %d points in theta (total: %d points):\n \n That will take long time... \n"
                % (energyN, thetaN, energyN * thetaN), QMessageBox.Yes,
                QMessageBox.No)

            if result == QMessageBox.No:
                raise Exception("Calculation cancelled.")

        rs, rp, e, t = out.scan(h5file=h5file,
                                energyN=energyN,
                                energy1=self.ENERGY,
                                energy2=self.ENERGY_END,
                                thetaN=thetaN,
                                theta1=self.THETA,
                                theta2=self.THETA_END)

        #
        #
        #
        out_dict = {}

        if self.THETA_FLAG == 1 and self.ENERGY_FLAG == 0:  # theta scan
            out = numpy.zeros((t.size, 3))

            out[:, 0] = t
            out[:, 1] = rs[0]**2
            out[:, 2] = rp[0]**2

            out_dict["data"] = out
            myscan = 0

        elif self.THETA_FLAG == 0 and self.ENERGY_FLAG == 1:  # energy scan
            out = numpy.zeros((e.size, 3))

            out[:, 0] = e
            out[:, 1] = rs[:, 0]**2
            out[:, 2] = rp[:, 0]**2

            out_dict["data"] = out
            myscan = 1

        elif self.THETA_FLAG == 1 and self.ENERGY_FLAG == 1:  # double scan

            out_dict["data2D_rs"] = rs**2
            out_dict["data2D_rp"] = rs**2
            out_dict["dataX"] = e
            out_dict["dataY"] = t
            myscan = 2

        elif self.THETA_FLAG == 0 and self.ENERGY_FLAG == 0:  # single point
            out = numpy.zeros((t.size, 3))
            out[:, 0] = t
            out[:, 1] = rs[0]**2
            out[:, 2] = rp[0]**2

            out_dict["data"] = out
            myscan = 0

        calculated_data = DataExchangeObject(
            "XOPPY", self.get_data_exchange_widget_name())

        try:
            calculated_data.add_content("xoppy_data", out_dict["data"])
            calculated_data.add_content("plot_x_col", 0)
            calculated_data.add_content("plot_y_col", 1)
        except:
            pass

        try:
            calculated_data.add_content("data2D_rs", out_dict["data2D_rs"])
            calculated_data.add_content("data2D_rp", out_dict["data2D_rp"])
            calculated_data.add_content("dataX", out_dict["dataX"])
            calculated_data.add_content("dataY", out_dict["dataY"])
        except:
            pass

        # script

        dict_parameters = {
            "material_S":    self.MATERIAL_S,
            "density_S":     density_S, \
            "roughness_S":   self.ROUGHNESS_S, \
            "material_E":    self.MATERIAL_E, \
            "density_E":     density_E, \
            "roughness_E":   self.ROUGHNESS_E, \
            "material_O":    self.MATERIAL_O, \
            "density_O":     density_O, \
            "roughness_O":   self.ROUGHNESS_O, \
            "bilayer_pairs": self.NLAYERS, \
            "bilayer_thickness": self.THICKNESS, \
            "bilayer_gamma":     self.GAMMA, \
            "energyN":           energyN, \
            "energy1":           self.ENERGY, \
            "energy2":           self.ENERGY_END, \
            "thetaN":            thetaN, \
            "theta1":            self.THETA,\
            "theta2":            self.THETA_END,
            "myscan":            myscan, \
            "h5file":            h5file, \
            }

        # write python script
        self.xoppy_script.set_code(
            self.script_template().format_map(dict_parameters))

        return calculated_data

    def script_template(self):
        return """
from orangecontrib.xoppy.util.mlayer import MLayer

out = MLayer.initialize_from_bilayer_stack(
    material_S="{material_S}", density_S={density_S}, roughness_S={roughness_S},
    material_E="{material_E}", density_E={density_E}, roughness_E={roughness_E},
    material_O="{material_O}", density_O={density_O}, roughness_O={roughness_O},
    bilayer_pairs={bilayer_pairs},
    bilayer_thickness={bilayer_thickness},
    bilayer_gamma={bilayer_gamma},
)

for key in out.pre_mlayer_dict.keys():
    print(key, out.pre_mlayer_dict[key])
# reflectivity is for amplitude
rs, rp, e, t = out.scan(h5file="{h5file}",
                energyN={energyN}, energy1={energy1}, energy2={energy2},
                thetaN={thetaN}, theta1={theta1}, theta2={theta2} )
                
#
# plot (example)
#
myscan = {myscan}
from srxraylib.plot.gol import plot,plot_image

if myscan == 0: # angle scan 
    plot(t, rs[0]**2, xtitle="angle [deg]", ytitle="Reflectivity-s", title="")
elif myscan == 1: # energy scan 
    plot(e,rs[:,0]**2,xtitle="Photon energy [eV]",ytitle="Reflectivity-s",title="")
elif myscan == 2: # double scan 
    plot_image(rs**2,e,t,xtitle="Photon energy [eV]",ytitle="Grazing angle [deg]",title="Reflectivity-s",aspect="auto")
               
"""

    def extract_data_from_xoppy_output(self, calculation_output):
        return calculation_output

    def get_data_exchange_widget_name(self):
        return "MULTILAYER"

    def getTitles(self):
        return ["Reflectivity-s", "Reflectivity-p"]

    def getXTitles(self):
        if self.THETA_FLAG == 1 and self.ENERGY_FLAG == 0:  # theta scan
            return 2 * ["Grazing angle [deg]"]
        elif self.THETA_FLAG == 0 and self.ENERGY_FLAG == 1:  # energy scan
            return 2 * ["Photon energy [eV]"]
        elif self.THETA_FLAG == 1 and self.ENERGY_FLAG == 1:  # double scan
            pass
        elif self.THETA_FLAG == 0 and self.ENERGY_FLAG == 0:  # single point
            return 2 * ["Grazing angle [deg]"]

    def getYTitles(self):
        return ["reflectivity-s", "reflectivity-p"]

    def getVariablesToPlot(self):
        return [(0, 1), (0, 2)]

    def getLogPlot(self):
        return [(False, False), (False, False)]

    def plot_histo(self,
                   x,
                   y,
                   progressBarValue,
                   tabs_canvas_index,
                   plot_canvas_index,
                   title="",
                   xtitle="",
                   ytitle="",
                   log_x=False,
                   log_y=False):
        super().plot_histo(x, y, progressBarValue, tabs_canvas_index,
                           plot_canvas_index, title, xtitle, ytitle, log_x,
                           log_y)

        # place a big dot if there is only a single value
        if ((x.size == 1) and (y.size == 1)):
            self.plot_canvas[plot_canvas_index].setDefaultPlotLines(False)
            self.plot_canvas[plot_canvas_index].setDefaultPlotPoints(True)

    def plot_results(self, calculated_data, progressBarValue=80):
        self.initializeTabs()

        try:

            self.tab[0].layout().removeItem(self.tab[0].layout().itemAt(0))
            self.plot_canvas[0] = None

            super().plot_results(calculated_data, progressBarValue)

            if self.ENERGY_FLAG == 0 and self.THETA_FLAG == 0:  # single point
                tmp = calculated_data.get_content("xoppy_data")
                txt = ""
                txt += "------------------------------------------------------------------------\n"
                txt += "Inputs: \n"
                txt += "   energy [eV]:           %6.3f \n" % self.ENERGY
                txt += "   grazing angle [deg]:   %6.3f \n" % tmp[0, 0]
                txt += "Outputs: \n"
                txt += "   R_S:    %5.2f  \n" % tmp[0, 1]
                txt += "   R_P:    %5.2f  \n" % tmp[0, 2]
                txt += "------------------------------------------------------------------------\n"

                QMessageBox.information(self, "Calculation Result",
                                        "Calculation Result:\n %s" % txt,
                                        QMessageBox.Ok)
        except:
            try:
                data2D_rs = calculated_data.get_content("data2D_rs")
                data2D_rp = calculated_data.get_content("data2D_rp")
                dataX = calculated_data.get_content("dataX")
                dataY = calculated_data.get_content("dataY")

                self.plot_data2D(data2D_rs,
                                 dataX,
                                 dataY,
                                 0,
                                 0,
                                 xtitle='Energy [eV]',
                                 ytitle='Grazing angle [deg]',
                                 title='Reflectivity-s')

                self.plot_data2D(data2D_rp,
                                 dataX,
                                 dataY,
                                 1,
                                 0,
                                 xtitle='Energy [eV]',
                                 ytitle='Grazing angle [deg]',
                                 title='Reflectivity-p')
            except:
                raise Exception("Error retieving data.")

    def defaults(self):
        self.resetSettings()
        self.compute()
        return

    def get_help_name(self):
        return 'multilayer'
Example #8
0
class OWSpecimenDisplacementPeakShift(OWGenericDiffractionPatternParametersWidget):

    name = "Specimen Displacement Peak Shift"
    description = "Specimen Displacement Peak Shift"
    icon = "icons/specimen_displacement_peak_shift.png"
    priority = 15

    goniometer_radius = Setting([1.0])

    displacement = Setting([0.0])
    displacement_fixed = Setting([0])
    displacement_has_min = Setting([0])
    displacement_min = Setting([0.0])
    displacement_has_max = Setting([0])
    displacement_max = Setting([0.0])
    displacement_function = Setting([0])
    displacement_function_value = Setting([""])

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

    def get_max_height(self):
        return 350

    def get_parameter_name(self):
        return "Specimen Displacement"

    def get_current_dimension(self):
        return len(self.displacement)

    def get_parameter_box_instance(self, parameter_tab, index):
        return SpecimenDisplacementPeakShiftBox(widget=self,
                                         parent=parameter_tab,
                                         index=index,
                                         goniometer_radius=self.goniometer_radius[index],
                                         displacement=self.displacement[index],
                                         displacement_fixed=self.displacement_fixed[index],
                                         displacement_has_min=self.displacement_has_min[index],
                                         displacement_min=self.displacement_min[index],
                                         displacement_has_max=self.displacement_has_max[index],
                                         displacement_max=self.displacement_max[index],
                                         displacement_function=self.displacement_function[index],
                                         displacement_function_value=self.displacement_function_value[index])

    def get_empty_parameter_box_instance(self, parameter_tab, index):
        return SpecimenDisplacementPeakShiftBox(widget=self, parent=parameter_tab, index=index)

    def set_parameter_data(self):
        self.fit_global_parameters.set_shift_parameters([self.get_parameter_box(index).get_peak_shift() for index in range(self.get_current_dimension())])

    def get_parameter_array(self):
        return self.fit_global_parameters.get_shift_parameters(SpecimenDisplacement.__name__)

    def get_parameter_item(self, diffraction_pattern_index):
        return self.fit_global_parameters.get_shift_parameters_item(SpecimenDisplacement.__name__, diffraction_pattern_index)

    def dumpSettings(self):
        self.dump_goniometer_radius()
        self.dump_displacement()

    def dump_goniometer_radius(self): self.dump_variable("goniometer_radius")

    def dump_displacement(self): self.dump_parameter("displacement")
Example #9
0
class OWxinpro(XoppyWidget):
    name = "INPRO"
    id = "orange.widgets.dataxinpro"
    description = "Crystal Reflectivity (perfect)"
    icon = "icons/xoppy_xinpro.png"
    priority = 7
    category = ""
    keywords = ["xoppy", "xinpro"]

    CRYSTAL_MATERIAL = Setting(0)
    MODE = Setting(0)
    ENERGY = Setting(8000.0)
    MILLER_INDEX_H = Setting(1)
    MILLER_INDEX_K = Setting(1)
    MILLER_INDEX_L = Setting(1)
    ASYMMETRY_ANGLE = Setting(0.0)
    THICKNESS = Setting(500.0)
    TEMPERATURE = Setting(300.0)
    NPOINTS = Setting(100)
    SCALE = Setting(0)
    XFROM = Setting(-50.0)
    XTO = Setting(50.0)

    def build_gui(self):

        box = oasysgui.widgetBox(self.controlArea,
                                 self.name + " Input Parameters",
                                 orientation="vertical",
                                 width=self.CONTROL_AREA_WIDTH - 5)

        idx = -1

        #widget index 0
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "CRYSTAL_MATERIAL",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=[
                         'Silicon', 'Germanium', 'Diamond', 'GaAs', 'GaP',
                         'InAs', 'InP', 'InSb', 'SiC', 'CsF', 'KCl', 'LiF',
                         'NaCl', 'Graphite', 'Beryllium'
                     ],
                     valueType=int,
                     orientation="horizontal",
                     labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 1
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "MODE",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=[
                         'Reflectivity in Bragg case',
                         'Transmission in Bragg case',
                         'Reflectivity in Laue case',
                         'Transmission in Laue case'
                     ],
                     valueType=int,
                     orientation="horizontal",
                     labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 2
        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)

        #widget index 3
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "MILLER_INDEX_H",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          validator=QIntValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 4
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "MILLER_INDEX_K",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          validator=QIntValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 5
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "MILLER_INDEX_L",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          validator=QIntValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 6
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "ASYMMETRY_ANGLE",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 7
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "THICKNESS",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 8
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "TEMPERATURE",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 9
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "NPOINTS",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          validator=QIntValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 10
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "SCALE",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=['Automatic', 'External'],
                     valueType=int,
                     orientation="horizontal",
                     labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 11
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "XFROM",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 12
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "XTO",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        gui.rubber(self.controlArea)

    def unitLabels(self):
        return [
            'Crystal material: ', 'Calculation mode:', 'Energy [eV]:',
            'Miller index H:', 'Miller index K:', 'Miller index L:',
            'Asymmetry angle:', 'Crystal thickness [microns]:',
            'Crystal temperature [K]:', 'Number of points: ',
            'Angular limits: ', 'Theta min [arcsec]:', 'Theta max [arcsec]:'
        ]

    def unitFlags(self):
        return [
            'True', 'True', 'True', 'True', 'True', 'True', 'True', 'True',
            'True', 'True', 'True', 'self.SCALE  ==  1', 'self.SCALE  ==  1'
        ]

    def get_help_name(self):
        return 'inpro'

    def check_fields(self):
        self.ENERGY = congruence.checkStrictlyPositiveNumber(
            self.ENERGY, "Energy")
        self.MILLER_INDEX_H = congruence.checkNumber(self.MILLER_INDEX_H,
                                                     "Miller index H")
        self.MILLER_INDEX_K = congruence.checkNumber(self.MILLER_INDEX_K,
                                                     "Miller index K")
        self.MILLER_INDEX_L = congruence.checkNumber(self.MILLER_INDEX_L,
                                                     "Miller index L")
        self.ASYMMETRY_ANGLE = congruence.checkNumber(self.ASYMMETRY_ANGLE,
                                                      "Asymmetry angle")
        self.THICKNESS = congruence.checkStrictlyPositiveNumber(
            self.THICKNESS, "Crystal thickness")
        self.TEMPERATURE = congruence.checkNumber(self.TEMPERATURE,
                                                  "Crystal temperature")
        self.NPOINTS = congruence.checkStrictlyPositiveNumber(
            self.NPOINTS, "Number of points")

        if self.SCALE == 1:
            self.XFROM = congruence.checkNumber(self.XFROM, "Theta min")
            self.XTO = congruence.checkNumber(self.XTO, "Theta max")
            congruence.checkLessThan(self.XFROM, self.XTO, "Theta min",
                                     "Theta max")

    def do_xoppy_calculation(self):
        return xoppy_calc_xinpro(CRYSTAL_MATERIAL=self.CRYSTAL_MATERIAL,
                                 MODE=self.MODE,
                                 ENERGY=self.ENERGY,
                                 MILLER_INDEX_H=self.MILLER_INDEX_H,
                                 MILLER_INDEX_K=self.MILLER_INDEX_K,
                                 MILLER_INDEX_L=self.MILLER_INDEX_L,
                                 ASYMMETRY_ANGLE=self.ASYMMETRY_ANGLE,
                                 THICKNESS=self.THICKNESS,
                                 TEMPERATURE=self.TEMPERATURE,
                                 NPOINTS=self.NPOINTS,
                                 SCALE=self.SCALE,
                                 XFROM=self.XFROM,
                                 XTO=self.XTO)

    def get_data_exchange_widget_name(self):
        return "XINPRO"

    def add_specific_content_to_calculated_data(self, calculated_data):
        calculated_data.add_content("units_to_degrees", 0.000277777805)

    def getTitles(self):
        return ['s-polarized reflectivity', 'p-polarized reflectivity']

    def getXTitles(self):
        return ["Theta-ThetaB [arcsec]", "Theta-ThetaB [arcsec]"]

    def getYTitles(self):
        return ['s-polarized reflectivity', 'p-polarized reflectivity']

    def getVariablesToPlot(self):
        return [(0, 1), (0, 2)]

    def getLogPlot(self):
        return [(False, False), (False, False)]
Example #10
0
class OWundulator_power_density(XoppyWidget, WidgetDecorator):
    name = "Undulator Power Density"
    id = "orange.widgets.dataundulator_power_density"
    description = "Undulator Power Density"
    icon = "icons/xoppy_undulator_power_density.png"
    priority = 3
    category = ""
    keywords = ["xoppy", "undulator_power_density"]

    USEEMITTANCES = Setting(1)
    ELECTRONENERGY = Setting(6.04)
    ELECTRONENERGYSPREAD = Setting(0.001)
    ELECTRONCURRENT = Setting(0.2)
    ELECTRONBEAMSIZEH = Setting(0.000395)
    ELECTRONBEAMSIZEV = Setting(9.9e-06)
    ELECTRONBEAMDIVERGENCEH = Setting(1.05e-05)
    ELECTRONBEAMDIVERGENCEV = Setting(3.9e-06)
    PERIODID = Setting(0.018)
    NPERIODS = Setting(222)
    KV = Setting(1.68)
    DISTANCE = Setting(30.0)
    GAPH = Setting(0.003)
    GAPV = Setting(0.003)
    HSLITPOINTS = Setting(41)
    VSLITPOINTS = Setting(41)
    METHOD = Setting(0)

    inputs = [WidgetDecorator.syned_input_data()]

    def build_gui(self):

        box = oasysgui.widgetBox(self.controlArea,
                                 self.name + " Input Parameters",
                                 orientation="vertical",
                                 width=self.CONTROL_AREA_WIDTH - 5)

        idx = -1
        #
        #
        #

        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "USEEMITTANCES",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=['No', 'Yes'],
                     valueType=int,
                     orientation="horizontal",
                     labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 0
        idx += 1
        box1 = gui.widgetBox(box)
        self.id_ELECTRONENERGY = oasysgui.lineEdit(
            box1,
            self,
            "ELECTRONENERGY",
            label=self.unitLabels()[idx],
            addSpace=False,
            valueType=float,
            validator=QDoubleValidator(),
            orientation="horizontal",
            labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 1
        idx += 1
        box1 = gui.widgetBox(box)
        self.id_ELECTRONENERGYSPREAD = oasysgui.lineEdit(
            box1,
            self,
            "ELECTRONENERGYSPREAD",
            label=self.unitLabels()[idx],
            addSpace=False,
            valueType=float,
            validator=QDoubleValidator(),
            orientation="horizontal",
            labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 2
        idx += 1
        box1 = gui.widgetBox(box)
        self.id_ELECTRONCURRENT = oasysgui.lineEdit(
            box1,
            self,
            "ELECTRONCURRENT",
            label=self.unitLabels()[idx],
            addSpace=False,
            valueType=float,
            validator=QDoubleValidator(),
            orientation="horizontal",
            labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 3
        idx += 1
        box1 = gui.widgetBox(box)
        self.id_ELECTRONBEAMSIZEH = oasysgui.lineEdit(
            box1,
            self,
            "ELECTRONBEAMSIZEH",
            label=self.unitLabels()[idx],
            addSpace=False,
            valueType=float,
            validator=QDoubleValidator(),
            orientation="horizontal",
            labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 4
        idx += 1
        box1 = gui.widgetBox(box)
        self.id_ELECTRONBEAMSIZEV = oasysgui.lineEdit(
            box1,
            self,
            "ELECTRONBEAMSIZEV",
            label=self.unitLabels()[idx],
            addSpace=False,
            valueType=float,
            validator=QDoubleValidator(),
            orientation="horizontal",
            labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 5
        idx += 1
        box1 = gui.widgetBox(box)
        self.id_ELECTRONBEAMDIVERGENCEH = oasysgui.lineEdit(
            box1,
            self,
            "ELECTRONBEAMDIVERGENCEH",
            label=self.unitLabels()[idx],
            addSpace=False,
            valueType=float,
            validator=QDoubleValidator(),
            orientation="horizontal",
            labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 6
        idx += 1
        box1 = gui.widgetBox(box)
        self.id_ELECTRONBEAMDIVERGENCEV = oasysgui.lineEdit(
            box1,
            self,
            "ELECTRONBEAMDIVERGENCEV",
            label=self.unitLabels()[idx],
            addSpace=False,
            valueType=float,
            validator=QDoubleValidator(),
            orientation="horizontal",
            labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 7
        idx += 1
        box1 = gui.widgetBox(box)
        self.id_PERIODID = oasysgui.lineEdit(box1,
                                             self,
                                             "PERIODID",
                                             label=self.unitLabels()[idx],
                                             addSpace=False,
                                             valueType=float,
                                             validator=QDoubleValidator(),
                                             orientation="horizontal",
                                             labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 8
        idx += 1
        box1 = gui.widgetBox(box)
        self.id_NPERIODS = oasysgui.lineEdit(box1,
                                             self,
                                             "NPERIODS",
                                             label=self.unitLabels()[idx],
                                             addSpace=False,
                                             valueType=int,
                                             validator=QIntValidator(),
                                             orientation="horizontal",
                                             labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 9
        idx += 1
        box1 = gui.widgetBox(box)
        self.id_KV = oasysgui.lineEdit(box1,
                                       self,
                                       "KV",
                                       label=self.unitLabels()[idx],
                                       addSpace=False,
                                       valueType=float,
                                       validator=QDoubleValidator(),
                                       orientation="horizontal",
                                       labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 10
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "DISTANCE",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 11
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "GAPH",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 12
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "GAPV",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 13
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "HSLITPOINTS",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          validator=QIntValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 14
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "VSLITPOINTS",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          validator=QIntValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 15
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "METHOD",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=['US', 'URGENT', 'SRW'],
                     valueType=int,
                     orientation="horizontal",
                     labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

    def unitLabels(self):
        return [
            "Use emittances", "Electron Energy [GeV]",
            "Electron Energy Spread", "Electron Current [A]",
            "Electron Beam Size H [m]", "Electron Beam Size V [m]",
            "Electron Beam Divergence H [rad]",
            "Electron Beam Divergence V [rad]", "Period ID [m]",
            "Number of periods", "Kv [undulator K value vertical field]",
            "Distance to slit [m]", "Slit gap H [m]", "Slit gap V [m]",
            "Number of slit mesh points in H",
            "Number of slit mesh points in V", "calculation code"
        ]

    def unitFlags(self):
        return [
            "True", "True", "self.USEEMITTANCES == 1 and self.METHOD != 1",
            "True", "self.USEEMITTANCES == 1", "self.USEEMITTANCES == 1",
            "self.USEEMITTANCES == 1", "self.USEEMITTANCES == 1", "True",
            "True", "True", "True", "True", "True", "True", "True", "True"
        ]

    def get_help_name(self):
        return 'undulator_power_density'

    def check_fields(self):

        self.ELECTRONENERGY = congruence.checkStrictlyPositiveNumber(
            self.ELECTRONENERGY, "Electron Energy")
        if not self.METHOD == 1:
            self.ELECTRONENERGYSPREAD = congruence.checkPositiveNumber(
                self.ELECTRONENERGYSPREAD, "Electron Energy Spread")
        self.ELECTRONCURRENT = congruence.checkStrictlyPositiveNumber(
            self.ELECTRONCURRENT, "Electron Current")
        self.ELECTRONBEAMSIZEH = congruence.checkPositiveNumber(
            self.ELECTRONBEAMSIZEH, "Electron Beam Size H")
        self.ELECTRONBEAMSIZEV = congruence.checkPositiveNumber(
            self.ELECTRONBEAMSIZEV, "Electron Beam Size V")
        self.ELECTRONBEAMDIVERGENCEH = congruence.checkPositiveNumber(
            self.ELECTRONBEAMDIVERGENCEH, "Electron Beam Divergence H")
        self.ELECTRONBEAMDIVERGENCEV = congruence.checkPositiveNumber(
            self.ELECTRONBEAMDIVERGENCEV, "Electron Beam Divergence V")
        self.PERIODID = congruence.checkStrictlyPositiveNumber(
            self.PERIODID, "Period ID")
        self.NPERIODS = congruence.checkStrictlyPositiveNumber(
            self.NPERIODS, "Number of Periods")
        self.KV = congruence.checkPositiveNumber(self.KV, "Kv")
        self.DISTANCE = congruence.checkPositiveNumber(self.DISTANCE,
                                                       "Distance to slit")
        self.GAPH = congruence.checkPositiveNumber(self.GAPH, "Slit gap H")
        self.GAPV = congruence.checkPositiveNumber(self.GAPV, "Slit gap V")
        self.HSLITPOINTS = congruence.checkStrictlyPositiveNumber(
            self.HSLITPOINTS, "Number of slit mesh points in H")
        self.VSLITPOINTS = congruence.checkStrictlyPositiveNumber(
            self.VSLITPOINTS, "Number of slit mesh points in V")

        if self.METHOD == 1:  # URGENT
            congruence.checkLessOrEqualThan(
                self.HSLITPOINTS, 51, "Number of slit mesh points for URGENT ",
                " 51")
            congruence.checkLessOrEqualThan(
                self.VSLITPOINTS, 51, "Number of slit mesh points for URGENT ",
                " 51")

        # if sys.platform == 'linux' and self.METHOD == 2:
        #     raise Exception("SRW calculation code not supported under Linux")

    def plot_results(self, calculated_data, progressBarValue=80):
        if not self.view_type == 0:
            if not calculated_data is None:

                self.initializeTabs(
                )  # added by srio to avoid overlapping graphs

                self.view_type_combo.setEnabled(False)

                data = calculated_data.get_content("xoppy_data")
                code = calculated_data.get_content("xoppy_code")

                h = data[0]
                v = data[1]
                p = data[2]

                try:

                    print("Result arrays (shapes): ", h.shape, v.shape,
                          p.shape)

                    self.plot_data2D(p,
                                     h,
                                     v,
                                     0,
                                     0,
                                     xtitle='H [mm]',
                                     ytitle='V [mm]',
                                     title='Code ' + code +
                                     '; Power density [W/mm^2]')

                except Exception as e:
                    self.view_type_combo.setEnabled(True)

                    raise Exception("Data not plottable: bad content\n" +
                                    str(e))

                self.view_type_combo.setEnabled(True)
            else:
                raise Exception("Empty Data")

    def do_xoppy_calculation(self):
        return xoppy_calc_undulator_power_density(
            ELECTRONENERGY=self.ELECTRONENERGY,
            ELECTRONENERGYSPREAD=self.ELECTRONENERGYSPREAD,
            ELECTRONCURRENT=self.ELECTRONCURRENT,
            ELECTRONBEAMSIZEH=self.ELECTRONBEAMSIZEH,
            ELECTRONBEAMSIZEV=self.ELECTRONBEAMSIZEV,
            ELECTRONBEAMDIVERGENCEH=self.ELECTRONBEAMDIVERGENCEH,
            ELECTRONBEAMDIVERGENCEV=self.ELECTRONBEAMDIVERGENCEV,
            PERIODID=self.PERIODID,
            NPERIODS=self.NPERIODS,
            KV=self.KV,
            DISTANCE=self.DISTANCE,
            GAPH=self.GAPH,
            GAPV=self.GAPV,
            HSLITPOINTS=self.HSLITPOINTS,
            VSLITPOINTS=self.VSLITPOINTS,
            METHOD=self.METHOD,
            USEEMITTANCES=self.USEEMITTANCES)

    def extract_data_from_xoppy_output(self, calculation_output):
        h, v, p, code = calculation_output

        calculated_data = DataExchangeObject(
            "XOPPY", self.get_data_exchange_widget_name())

        calculated_data.add_content("xoppy_data", [h, v, p])
        calculated_data.add_content("xoppy_code", code)

        return calculated_data

    def get_data_exchange_widget_name(self):
        return "UNDULATOR_POWER_DENSITY"

    def getTitles(self):
        return ['Undulator Power Density']

    def receive_syned_data(self, data):

        if isinstance(data, synedb.Beamline):
            if not data._light_source is None and isinstance(
                    data._light_source._magnetic_structure,
                    synedid.InsertionDevice):
                light_source = data._light_source

                self.ELECTRONENERGY = light_source._electron_beam._energy_in_GeV
                self.ELECTRONENERGYSPREAD = light_source._electron_beam._energy_spread
                self.ELECTRONCURRENT = light_source._electron_beam._current

                x, xp, y, yp = light_source._electron_beam.get_sigmas_all()

                self.ELECTRONBEAMSIZEH = x
                self.ELECTRONBEAMSIZEV = y
                self.ELECTRONBEAMDIVERGENCEH = xp
                self.ELECTRONBEAMDIVERGENCEV = yp
                self.PERIODID = light_source._magnetic_structure._period_length
                self.NPERIODS = light_source._magnetic_structure._number_of_periods
                self.KV = light_source._magnetic_structure._K_vertical

                self.set_enabled(False)

            else:
                self.set_enabled(True)
                # raise ValueError("Syned data not correct")
        else:
            self.set_enabled(True)
            # raise ValueError("Syned data not correct")

    def set_enabled(self, value):
        if value == True:
            self.id_ELECTRONENERGY.setEnabled(True)
            self.id_ELECTRONENERGYSPREAD.setEnabled(True)
            self.id_ELECTRONBEAMSIZEH.setEnabled(True)
            self.id_ELECTRONBEAMSIZEV.setEnabled(True)
            self.id_ELECTRONBEAMDIVERGENCEH.setEnabled(True)
            self.id_ELECTRONBEAMDIVERGENCEV.setEnabled(True)
            self.id_ELECTRONCURRENT.setEnabled(True)
            self.id_PERIODID.setEnabled(True)
            self.id_NPERIODS.setEnabled(True)
            self.id_KV.setEnabled(True)
        else:
            self.id_ELECTRONENERGY.setEnabled(False)
            self.id_ELECTRONENERGYSPREAD.setEnabled(False)
            self.id_ELECTRONBEAMSIZEH.setEnabled(False)
            self.id_ELECTRONBEAMSIZEV.setEnabled(False)
            self.id_ELECTRONBEAMDIVERGENCEH.setEnabled(False)
            self.id_ELECTRONBEAMDIVERGENCEV.setEnabled(False)
            self.id_ELECTRONCURRENT.setEnabled(False)
            self.id_PERIODID.setEnabled(False)
            self.id_NPERIODS.setEnabled(False)
            self.id_KV.setEnabled(False)
Example #11
0
class OWWiseSourceToWofryWavefront1d(AutomaticWidget):
    name = "Wise Wavefront To Wofry Wavefront 1D"
    id = "toWofryWavefront1D"
    description = "Wise Wavefront To Wofry Wavefront 1D"
    icon = "icons/wf_to_wofry_wavefront_1d.png"
    priority = 3
    category = ""
    keywords = ["wise", "gaussian"]

    inputs = [("WiseOutput", WiseOutput, "set_input")]

    outputs = [{
        "name": "GenericWavefront1D",
        "type": GenericWavefront1D,
        "doc": "GenericWavefront1D",
        "id": "GenericWavefront1D"
    }]

    MAX_WIDTH = 420
    MAX_HEIGHT = 250
    CONTROL_AREA_WIDTH = 410

    want_main_area = 0

    number_of_points = Setting(500)
    area_size = Setting(50.0)
    defocus_sweep = Setting(0.0)

    _defocus_sign = -1

    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.setMinimumHeight(self.geometry().height())
        self.setMinimumWidth(self.geometry().width())
        self.setMaximumHeight(self.geometry().height())
        self.setMaximumWidth(self.geometry().width())

        self.controlArea.setFixedWidth(self.MAX_WIDTH - 10)
        self.controlArea.setFixedHeight(self.MAX_HEIGHT - 10)

        main_box = oasysgui.widgetBox(
            self.controlArea,
            "WISE Wavefront to Wofry Wavefront Converter",
            orientation="vertical",
            width=self.CONTROL_AREA_WIDTH - 5,
            height=160)

        oasysgui.lineEdit(main_box,
                          self,
                          "area_size",
                          "Area Size [" + u"\u03BC" + "m]",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(main_box,
                          self,
                          "number_of_points",
                          "Number of Points",
                          labelWidth=260,
                          valueType=int,
                          orientation="horizontal")
        self.le_defocus_sweep = oasysgui.lineEdit(main_box,
                                                  self,
                                                  "defocus_sweep",
                                                  "Defocus sweep",
                                                  labelWidth=260,
                                                  valueType=float,
                                                  orientation="horizontal")

        gui.button(main_box, self, "Compute", height=40, callback=self.compute)

    def after_change_workspace_units(self):
        label = self.le_defocus_sweep.parent().layout().itemAt(0).widget()
        label.setText(label.text() + " [" + self.workspace_units_label + "]")

    def compute(self):
        if not self.input_data is None:
            try:
                detector_size = self.area_size * 1e-6
                number_of_points = self.number_of_points

                previous_numerical_integration_parameters = self.input_data.get_numerical_integration_parameters(
                )
                numerical_integration_parameters = WiseNumericalIntegrationParameters(
                    WiseNumericalIntegrationParameters.USER_DEFINED,
                    detector_size, number_of_points)

                propagation_type = WisePropagationParameters.MIRROR_AND_DETECTOR

                #
                # No need to recalculated wavefront on previous mirror surface
                # if numerical integration parameters are identical
                #
                if WiseNumericalIntegrationParameters.USER_DEFINED == previous_numerical_integration_parameters.calculation_type:
                    if self.number_of_points == previous_numerical_integration_parameters.number_of_points:
                        propagation_type = WisePropagationParameters.DETECTOR_ONLY
                        numerical_integration_parameters.calculated_number_of_points = previous_numerical_integration_parameters.calculated_number_of_points

                propagation_parameter = WisePropagationParameters(
                    propagation_type=propagation_type,
                    source=self.input_data.get_source().inner_wise_source,
                    optical_element=self.input_data.get_optical_element(
                    ).inner_wise_optical_element,
                    wavefront=self.input_data.get_wavefront(),
                    numerical_integration_parameters=
                    numerical_integration_parameters,
                    defocus_sweep=self._defocus_sign * self.defocus_sweep *
                    self.workspace_units_to_m)

                propagation_output = WisePropagatorsChain.Instance(
                ).do_propagation(propagation_parameter,
                                 WisePropagationAlgorithms.HuygensIntegral)

                wavefront = WiseWavefront(
                    wavelength=self.input_data.get_source(
                    ).inner_wise_source.Lambda,
                    positions=propagation_output.det_s,
                    electric_fields=propagation_output.electric_fields,
                    residuals=numpy.zeros(self.number_of_points))

                self.send("GenericWavefront1D", wavefront.toGenericWavefront())
            except Exception as exception:
                QMessageBox.critical(self, "Error", str(exception),
                                     QMessageBox.Ok)

                #raise exception

    def set_input(self, input_data):
        self.setStatusMessage("")

        if not input_data is None:
            try:
                if input_data.has_wavefront():

                    self.input_data = input_data

                    if self.is_automatic_execution:
                        self.compute()
                else:
                    raise ValueError("No wavefront is present in input data")
            except Exception as exception:
                QMessageBox.critical(self, "Error", str(exception),
                                     QMessageBox.Ok)
Example #12
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)

    usage_path = os.path.join(
        resources.package_dirname("orangecontrib.shadow.widgets.gui"), "misc",
        "prerefl_usage.png")

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

        self.runaction = widget.OWAction("Compute", self)
        self.runaction.triggered.connect(self.compute)
        self.addAction(self.runaction)

        self.setFixedWidth(550)
        self.setFixedHeight(550)

        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)

        tabs_setting = oasysgui.tabWidget(self.controlArea)

        tab_bas = oasysgui.createTabPage(tabs_setting, "Reflectivity Settings")
        tab_out = oasysgui.createTabPage(tabs_setting, "Output")
        tab_usa = oasysgui.createTabPage(tabs_setting, "Use of the Widget")
        tab_usa.setStyleSheet("background-color: white;")

        usage_box = oasysgui.widgetBox(tab_usa,
                                       "",
                                       addSpace=True,
                                       orientation="horizontal")

        label = QLabel("")
        label.setAlignment(Qt.AlignCenter)
        label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        label.setPixmap(QPixmap(self.usage_path))

        usage_box.layout().addWidget(label)

        box = oasysgui.widgetBox(tab_bas,
                                 "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 = oasysgui.textArea()

        out_box = oasysgui.widgetBox(tab_out,
                                     "System Output",
                                     addSpace=True,
                                     orientation="horizontal",
                                     height=400)
        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")
        congruence.checkLessOrEqualThan(self.E_MIN, self.E_MAX,
                                        "Minimum Energy", "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()
Example #13
0
class OWSRWSpectrum(SRWWavefrontViewer):

    maintainer = "Luca Rebuffi"
    maintainer_email = "lrebuffi(@at@)anl.gov"
    category = "Source"
    keywords = ["data", "file", "load", "read"]
    name = "Source Spectrum"
    description = "SRW Source: Source Spectrum"
    icon = "icons/spectrum.png"
    priority = 5

    inputs = [("SRWData", SRWData, "receive_srw_data")]

    outputs = [{"name": "srw_data", "type": DataExchangeObject, "doc": ""}]

    want_main_area = 1

    source_name = "SRW Source"
    electron_energy_in_GeV = 0.0
    electron_energy_spread = 0.0
    ring_current = 0.0
    electron_beam_size_h = 0.0
    electron_beam_size_v = 0.0
    electron_beam_divergence_h = 0.0
    electron_beam_divergence_v = 0.0
    moment_x = 0.0
    moment_y = 0.0
    moment_z = 0.0
    moment_xp = 0.0
    moment_yp = 0.0
    moment_xx = 0.0
    moment_xxp = 0.0
    moment_xpxp = 0.0
    moment_yy = 0.0
    moment_yyp = 0.0
    moment_ypyp = 0.0

    spe_photon_energy_min = Setting(100.0)
    spe_photon_energy_max = Setting(100100.0)
    spe_photon_energy_points = Setting(10000)
    spe_h_slit_gap = Setting(0.0001)
    spe_v_slit_gap = Setting(0.0001)
    spe_h_slit_points = Setting(1)
    spe_v_slit_points = Setting(1)
    spe_distance = Setting(1.0)
    spe_on_axis_x = Setting(0.0)
    spe_on_axis_y = Setting(0.0)
    spe_polarization_component_to_be_extracted = Setting(6)

    spe_sr_method = Setting(1)
    spe_relative_precision = Setting(0.01)
    spe_start_integration_longitudinal_position = Setting(0.0)
    spe_end_integration_longitudinal_position = Setting(0.0)
    spe_number_of_points_for_trajectory_calculation = Setting(50000)
    spe_use_terminating_terms = Setting(1)
    spe_sampling_factor_for_adjusting_nx_ny = Setting(0.0)

    spe_initial_UR_harmonic = Setting(1)
    spe_final_UR_harmonic = Setting(21)
    spe_longitudinal_integration_precision_parameter = Setting(1.5)
    spe_azimuthal_integration_precision_parameter = Setting(1.5)

    calculated_total_power = 0.0

    received_light_source = None

    TABS_AREA_HEIGHT = 618
    CONTROL_AREA_WIDTH = 405

    def __init__(self, show_automatic_box=False):
        super().__init__(show_automatic_box=show_automatic_box,
                         show_view_box=False)

        self.general_options_box.setVisible(False)

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

        button = gui.button(button_box,
                            self,
                            "Calculate Spectrum",
                            callback=self.calculateRadiation)
        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 = gui.button(button_box,
                            self,
                            "Reset Fields",
                            callback=self.callResetSettings)
        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(150)

        gui.separator(self.controlArea)

        self.controlArea.setFixedWidth(self.CONTROL_AREA_WIDTH)

        # FLUX -------------------------------------------

        spe_box = oasysgui.widgetBox(self.controlArea,
                                     "Wavefront Parameters",
                                     addSpace=False,
                                     orientation="vertical",
                                     width=self.CONTROL_AREA_WIDTH - 5)

        oasysgui.lineEdit(spe_box,
                          self,
                          "spe_photon_energy_min",
                          "Photon Energy Min [eV]",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(spe_box,
                          self,
                          "spe_photon_energy_max",
                          "Photon Energy Max [eV]",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(spe_box,
                          self,
                          "spe_photon_energy_points",
                          "Photon Energy Points",
                          labelWidth=260,
                          valueType=int,
                          orientation="horizontal")
        oasysgui.lineEdit(spe_box,
                          self,
                          "spe_h_slit_gap",
                          "H Slit Gap [m]",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(spe_box,
                          self,
                          "spe_v_slit_gap",
                          "V Slit Gap [m]",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")

        self.box_points = oasysgui.widgetBox(spe_box,
                                             "",
                                             addSpace=False,
                                             orientation="vertical")

        oasysgui.lineEdit(self.box_points,
                          self,
                          "spe_h_slit_points",
                          "H Slit Points",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(self.box_points,
                          self,
                          "spe_v_slit_points",
                          "V Slit Points",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")

        oasysgui.lineEdit(spe_box,
                          self,
                          "spe_distance",
                          "Propagation Distance [m]",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")

        gui.comboBox(spe_box,
                     self,
                     "spe_polarization_component_to_be_extracted",
                     label="Polarization Component",
                     items=PolarizationComponent.tuple(),
                     labelWidth=150,
                     sendSelectedValue=False,
                     orientation="horizontal")

        oasysgui.lineEdit(spe_box,
                          self,
                          "spe_on_axis_x",
                          "H On-Axis Position [m]",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(spe_box,
                          self,
                          "spe_on_axis_y",
                          "V On-Axis Position [m]",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")

        pre_box = oasysgui.widgetBox(self.controlArea,
                                     "Precision Parameters",
                                     addSpace=False,
                                     orientation="vertical",
                                     width=self.CONTROL_AREA_WIDTH - 5)

        self.tabs_precision = oasysgui.tabWidget(pre_box)

        tab_prop = oasysgui.createTabPage(self.tabs_precision, "Propagation")

        gui.comboBox(tab_prop,
                     self,
                     "spe_sr_method",
                     label="Calculation Method",
                     items=["Manual", "Auto"],
                     labelWidth=260,
                     sendSelectedValue=False,
                     orientation="horizontal")

        oasysgui.lineEdit(tab_prop,
                          self,
                          "spe_relative_precision",
                          "Relative Precision",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(tab_prop,
                          self,
                          "spe_start_integration_longitudinal_position",
                          "Longitudinal pos. to start integration [m]",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(tab_prop,
                          self,
                          "spe_end_integration_longitudinal_position",
                          "Longitudinal pos. to finish integration [m]",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(tab_prop,
                          self,
                          "spe_number_of_points_for_trajectory_calculation",
                          "Number of points for trajectory calculation",
                          labelWidth=260,
                          valueType=int,
                          orientation="horizontal")

        gui.comboBox(tab_prop,
                     self,
                     "spe_use_terminating_terms",
                     label="Use \"terminating terms\"or not",
                     items=["No", "Yes"],
                     labelWidth=260,
                     sendSelectedValue=False,
                     orientation="horizontal")

        oasysgui.lineEdit(tab_prop,
                          self,
                          "spe_sampling_factor_for_adjusting_nx_ny",
                          "Sampling factor for adjusting nx/ny",
                          labelWidth=260,
                          valueType=int,
                          orientation="horizontal")

        # FLUX  -------------------------------------------

        gui.rubber(self.controlArea)

    def calculateRadiation(self):
        if not self.received_light_source is None:

            self.setStatusMessage("")
            self.progressBarInit()

            try:
                self.checkFields()

                srw_source = self.get_srw_source(self.get_electron_beam())

                self.progressBarSet(10)

                self.setStatusMessage("Running SRW")

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

                print(srw_source.get_electron_beam().
                      get_electron_beam_geometrical_properties().to_info())

                self.print_specific_infos(srw_source)

                self.progressBarSet(20)

                tickets = []

                self.run_calculation_flux(srw_source, tickets)

                self.setStatusMessage("Plotting Results")

                self.plot_results(tickets)

                self.setStatusMessage("")

                self.send("srw_data", self.create_exchange_data(tickets))

            except Exception as exception:
                QMessageBox.critical(self, "Error", str(exception),
                                     QMessageBox.Ok)

                if self.IS_DEVELOP: raise exception

            self.progressBarFinished()

    def get_electron_beam(self):
        received_electron_beam = self.received_light_source.get_electron_beam()

        electron_beam = SRWElectronBeam(
            energy_in_GeV=received_electron_beam._energy_in_GeV,
            energy_spread=received_electron_beam._energy_spread,
            current=received_electron_beam._current)

        electron_beam._moment_x = 0.0
        electron_beam._moment_y = 0.0
        electron_beam._moment_z = self.get_default_initial_z()
        electron_beam._moment_xp = 0.0
        electron_beam._moment_yp = 0.0
        electron_beam._moment_xx = received_electron_beam._moment_xx
        electron_beam._moment_xxp = received_electron_beam._moment_xxp
        electron_beam._moment_xpxp = received_electron_beam._moment_xpxp
        electron_beam._moment_yy = received_electron_beam._moment_yy
        electron_beam._moment_yyp = received_electron_beam._moment_yyp
        electron_beam._moment_ypyp = received_electron_beam._moment_ypyp

        return electron_beam

    def print_specific_infos(self, srw_source):
        if isinstance(self.received_light_source, SRWUndulatorLightSource):
            print("1st Harmonic Energy", srw_source.get_resonance_energy())
            print(
                srw_source.get_photon_source_properties(harmonic=1).to_info())

    def get_default_initial_z(self):
        if isinstance(self.received_light_source, SRWBendingMagnetLightSource):
            return -0.5 * self.received_light_source._magnetic_structure._length
        elif isinstance(self.received_light_source, SRWUndulatorLightSource):
            return -0.5 * self.received_light_source._magnetic_structure._period_length * (
                self.received_light_source._magnetic_structure.
                _number_of_periods + 4
            )  # initial Longitudinal Coordinate (set before the ID)

    def get_srw_source(self, electron_beam=ElectronBeam()):
        if isinstance(self.received_light_source, SRWBendingMagnetLightSource):
            return SRWBendingMagnetLightSource(
                name=self.received_light_source._name,
                electron_beam=electron_beam,
                bending_magnet_magnetic_structure=self.received_light_source.
                _magnetic_structure)
        elif isinstance(self.received_light_source, SRWUndulatorLightSource):
            return SRWUndulatorLightSource(
                name=self.received_light_source._name,
                electron_beam=electron_beam,
                undulator_magnetic_structure=self.received_light_source.
                _magnetic_structure)

    def getCalculatedTotalPowerString(self):
        if self.calculated_total_power == 0:
            return ""
        else:
            return "Total: " + str(int(self.calculated_total_power)) + " W"

    def get_automatic_sr_method(self):
        if isinstance(self.received_light_source, SRWBendingMagnetLightSource):
            return 2
        elif isinstance(self.received_light_source, SRWUndulatorLightSource):
            return 1

    def get_minimum_propagation_distance(self):
        return round(self.get_source_length() * 1.01, 6)

    def get_source_length(self):
        if isinstance(self.received_light_source, SRWBendingMagnetLightSource):
            return self.received_light_source._magnetic_structure._length
        elif isinstance(self.received_light_source, SRWUndulatorLightSource):
            return self.received_light_source._magnetic_structure._period_length * self.received_light_source._magnetic_structure._number_of_periods

    def checkFields(self):

        # FLUX
        congruence.checkStrictlyPositiveNumber(self.spe_photon_energy_min,
                                               "Photon Energy Min")
        congruence.checkStrictlyPositiveNumber(self.spe_photon_energy_max,
                                               "Photon Energy Max")
        congruence.checkGreaterOrEqualThan(self.spe_photon_energy_max,
                                           self.spe_photon_energy_min,
                                           "Photon Energy Max",
                                           "Photon Energy Min")
        congruence.checkStrictlyPositiveNumber(self.spe_photon_energy_points,
                                               "Photon Energy Points")

        congruence.checkStrictlyPositiveNumber(self.spe_h_slit_gap,
                                               "H Slit Gap")
        congruence.checkStrictlyPositiveNumber(self.spe_v_slit_gap,
                                               "V Slit Gap")
        congruence.checkGreaterOrEqualThan(
            self.spe_distance, self.get_minimum_propagation_distance(),
            "Distance", "Minimum Distance out of the Source: " +
            str(self.get_minimum_propagation_distance()))

        congruence.checkStrictlyPositiveNumber(self.spe_relative_precision,
                                               "Relative Precision")
        congruence.checkStrictlyPositiveNumber(
            self.spe_number_of_points_for_trajectory_calculation,
            "Number of points for trajectory calculation")
        congruence.checkPositiveNumber(
            self.spe_sampling_factor_for_adjusting_nx_ny,
            "Sampling Factor for adjusting nx/ny")

        self.checkFluxSpecificFields()

    def checkFluxSpecificFields(self):
        if isinstance(self.received_light_source, SRWUndulatorLightSource):
            congruence.checkStrictlyPositiveNumber(
                self.spe_initial_UR_harmonic, "Flux Initial Harmonic")
            congruence.checkStrictlyPositiveNumber(self.spe_final_UR_harmonic,
                                                   "Flux Final Harmonic")
            congruence.checkGreaterOrEqualThan(self.spe_final_UR_harmonic,
                                               self.spe_initial_UR_harmonic,
                                               "Flux Final Harmonic",
                                               "Flux Initial Harmonic")
            congruence.checkStrictlyPositiveNumber(
                self.spe_longitudinal_integration_precision_parameter,
                "Flux Longitudinal integration precision parameter")
            congruence.checkStrictlyPositiveNumber(
                self.spe_azimuthal_integration_precision_parameter,
                "Flux Azimuthal integration precision parameter")

    def run_calculation_flux(self, srw_source, tickets, progress_bar_value=50):
        wf_parameters = WavefrontParameters(
            photon_energy_min=self.spe_photon_energy_min,
            photon_energy_max=self.spe_photon_energy_max,
            photon_energy_points=self.spe_photon_energy_points,
            h_slit_gap=self.spe_h_slit_gap,
            v_slit_gap=self.spe_v_slit_gap,
            h_slit_points=self.spe_h_slit_points,
            v_slit_points=self.spe_v_slit_points,
            distance=self.spe_distance,
            wavefront_precision_parameters=WavefrontPrecisionParameters(
                sr_method=0
                if self.spe_sr_method == 0 else self.get_automatic_sr_method(),
                relative_precision=self.spe_relative_precision,
                start_integration_longitudinal_position=self.
                spe_start_integration_longitudinal_position,
                end_integration_longitudinal_position=self.
                spe_end_integration_longitudinal_position,
                number_of_points_for_trajectory_calculation=self.
                spe_number_of_points_for_trajectory_calculation,
                use_terminating_terms=self.spe_use_terminating_terms,
                sampling_factor_for_adjusting_nx_ny=self.
                spe_sampling_factor_for_adjusting_nx_ny))

        srw_wavefront = srw_source.get_SRW_Wavefront(
            source_wavefront_parameters=wf_parameters)

        if isinstance(self.received_light_source, SRWBendingMagnetLightSource):
            e, i = srw_wavefront.get_flux(
                multi_electron=True,
                polarization_component_to_be_extracted=self.
                spe_polarization_component_to_be_extracted)
        elif isinstance(self.received_light_source, SRWUndulatorLightSource):
            e, i = srw_source.get_undulator_flux(
                source_wavefront_parameters=wf_parameters,
                flux_precision_parameters=FluxPrecisionParameters(
                    initial_UR_harmonic=self.spe_initial_UR_harmonic,
                    final_UR_harmonic=self.spe_final_UR_harmonic,
                    longitudinal_integration_precision_parameter=self.
                    spe_longitudinal_integration_precision_parameter,
                    azimuthal_integration_precision_parameter=self.
                    spe_azimuthal_integration_precision_parameter,
                    calculation_type=1))

        tickets.append(SRWPlot.get_ticket_1D(e, i))

        wf_parameters = WavefrontParameters(
            photon_energy_min=self.spe_photon_energy_min,
            photon_energy_max=self.spe_photon_energy_max,
            photon_energy_points=self.spe_photon_energy_points,
            h_slit_gap=0.0,
            v_slit_gap=0.0,
            h_slit_points=1,
            v_slit_points=1,
            h_position=self.spe_on_axis_x,
            v_position=self.spe_on_axis_y,
            distance=self.spe_distance,
            wavefront_precision_parameters=WavefrontPrecisionParameters(
                sr_method=0
                if self.spe_sr_method == 0 else self.get_automatic_sr_method(),
                relative_precision=self.spe_relative_precision,
                start_integration_longitudinal_position=self.
                spe_start_integration_longitudinal_position,
                end_integration_longitudinal_position=self.
                spe_end_integration_longitudinal_position,
                number_of_points_for_trajectory_calculation=self.
                spe_number_of_points_for_trajectory_calculation,
                use_terminating_terms=self.spe_use_terminating_terms,
                sampling_factor_for_adjusting_nx_ny=self.
                spe_sampling_factor_for_adjusting_nx_ny))

        srw_wavefront = srw_source.get_SRW_Wavefront(
            source_wavefront_parameters=wf_parameters)

        e, i = srw_wavefront.get_flux(
            multi_electron=False,
            polarization_component_to_be_extracted=self.
            spe_polarization_component_to_be_extracted)

        tickets.append(SRWPlot.get_ticket_1D(e, i))

        self.progressBarSet(progress_bar_value)

    def create_exchange_data(self, tickets):
        ticket = tickets[0]

        if isinstance(ticket['histogram'].shape, list):
            f = ticket['histogram'][0]
        else:
            f = ticket['histogram']

        e = ticket['bins']

        data = numpy.zeros((len(e), 2))
        data[:, 0] = numpy.array(e)
        data[:, 1] = numpy.array(f)

        calculated_data = DataExchangeObject(program_name="SRW",
                                             widget_name="UNDULATOR_SPECTRUM")
        calculated_data.add_content("srw_data", data)

        return calculated_data

    def getVariablesToPlot(self):
        return [[1], [1]]

    def getTitles(self, with_um=False):
        if with_um:
            return [
                "Flux Through Finite Aperture",
                "On Axis Spectrum from 0-Emittance Beam"
            ]
        else:
            return [
                "Spectral Flux (ME) vs E",
                "Spectral Spatial Flux Density (SE) vs E"
            ]

    def getXTitles(self):
        return ["E [eV]", "E [eV]"]

    def getYTitles(self):
        if not self.received_light_source is None and isinstance(
                self.received_light_source, SRWBendingMagnetLightSource):
            return [
                "Spectral Flux Density [ph/s/.1%bw/mm\u00b2]",
                "Spectral Spatial Flux Density [ph/s/.1%bw/mm\u00b2]"
            ]
        else:
            return [
                "Spectral Flux [ph/s/.1%bw]",
                "Spectral Spatial Flux Density [ph/s/.1%bw/mm\u00b2]"
            ]

    def getXUM(self):
        return ["E [eV]", "E [eV]"]

    def getYUM(self):
        if not self.received_light_source is None and isinstance(
                self.received_light_source, SRWBendingMagnetLightSource):
            return [
                "Spectral Flux Density [ph/s/.1%bw/mm\u00b2]",
                "Spectral Spatial Flux Density [ph/s/.1%bw/mm\u00b2]"
            ]
        else:
            return [
                "Spectral Flux [ph/s/.1%bw]",
                "Spectral Spatial Flux Density [ph/s/.1%bw/mm\u00b2]"
            ]

    def receive_srw_data(self, data):
        if not data is None:
            try:
                if isinstance(data, SRWData):
                    self.received_light_source = data.get_srw_beamline(
                    ).get_light_source()
                    received_wavefront = data.get_srw_wavefront()

                    if not received_wavefront is None:
                        if self.spe_photon_energy_min == 0.0 and self.spe_photon_energy_max == 0.0:
                            self.spe_photon_energy_min = received_wavefront.mesh.eStart
                            self.spe_photon_energy_max = received_wavefront.mesh.eFin
                            self.spe_photon_energy_points = received_wavefront.mesh.ne
                        self.spe_h_slit_gap = received_wavefront.mesh.xFin - received_wavefront.mesh.xStart
                        self.spe_v_slit_gap = received_wavefront.mesh.yFin - received_wavefront.mesh.yStart
                        self.spe_distance = received_wavefront.mesh.zStart

                    n_tab = len(self.tabs_precision)

                    if isinstance(self.received_light_source,
                                  SRWBendingMagnetLightSource):
                        self.spe_h_slit_points = received_wavefront.mesh.nx
                        self.spe_v_slit_points = received_wavefront.mesh.ny
                        self.box_points.setVisible(True)

                        if n_tab > 1: self.tabs_precision.removeTab(n_tab - 1)
                    elif isinstance(self.received_light_source,
                                    SRWUndulatorLightSource):
                        self.spe_h_slit_points = 1
                        self.spe_v_slit_points = 1
                        self.box_points.setVisible(False)

                        if n_tab == 1:
                            tab_flu = oasysgui.createTabPage(
                                self.tabs_precision, "Flux")

                            oasysgui.lineEdit(tab_flu,
                                              self,
                                              "spe_initial_UR_harmonic",
                                              "Initial Harmonic",
                                              labelWidth=260,
                                              valueType=int,
                                              orientation="horizontal")
                            oasysgui.lineEdit(tab_flu,
                                              self,
                                              "spe_final_UR_harmonic",
                                              "Final Harmonic",
                                              labelWidth=260,
                                              valueType=int,
                                              orientation="horizontal")
                            oasysgui.lineEdit(
                                tab_flu,
                                self,
                                "spe_longitudinal_integration_precision_parameter",
                                "Longitudinal integration precision param.",
                                labelWidth=260,
                                valueType=float,
                                orientation="horizontal")
                            oasysgui.lineEdit(
                                tab_flu,
                                self,
                                "spe_azimuthal_integration_precision_parameter",
                                "Azimuthal integration precision param.",
                                labelWidth=260,
                                valueType=int,
                                orientation="horizontal")
                    else:
                        raise ValueError("This source is not supported")
                else:
                    raise ValueError("SRW data not correct")
            except Exception as exception:
                QMessageBox.critical(self, "Error", str(exception),
                                     QMessageBox.Ok)
Example #14
0
class OWxcrosssec(XoppyWidget):
    name = "CrossSec"
    id = "orange.widgets.dataxcrosssec"
    description = "X-ray Matter Cross Sections"
    icon = "icons/xoppy_xcrosssec.png"
    priority = 19
    category = ""
    keywords = ["xoppy", "xcrosssec"]

    MAT_FLAG = Setting(0)
    MAT_LIST = Setting(0)
    DESCRIPTOR = Setting("Si")
    DENSITY = Setting(1.0)
    CALCULATE = Setting(1)
    GRID = Setting(0)
    GRIDSTART = Setting(100.0)
    GRIDEND = Setting(10000.0)
    GRIDN = Setting(200)
    UNIT = Setting(0)
    DUMP_TO_FILE = Setting(0)  # No
    FILE_NAME = Setting("CrossSec.dat")

    xtitle = None
    ytitle = None

    def build_gui(self):

        box = oasysgui.widgetBox(self.controlArea, self.name + " Input Parameters", orientation="vertical", width=self.CONTROL_AREA_WIDTH-5)

        idx = -1
        
        #widget index 1 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.comboBox(box1, self, "MAT_FLAG",
                     label=self.unitLabels()[idx], addSpace=False,
                    items=['Element(formula)', 'Mixture(formula)', 'Mixture(table)'],
                    valueType=int, orientation="horizontal", labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 2 
        idx += 1 
        box1 = gui.widgetBox(box)
        items = xraylib.GetCompoundDataNISTList()
        gui.comboBox(box1, self, "MAT_LIST",
                     label=self.unitLabels()[idx], addSpace=False,
                     items=items,
                     valueType=int, orientation="horizontal", labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 3 
        idx += 1 
        box1 = gui.widgetBox(box) 
        oasysgui.lineEdit(box1, self, "DESCRIPTOR",
                     label=self.unitLabels()[idx], addSpace=False, orientation="horizontal")
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 4 
        idx += 1 
        box1 = gui.widgetBox(box) 
        oasysgui.lineEdit(box1, self, "DENSITY",
                     label=self.unitLabels()[idx], addSpace=False,
                    valueType=float, validator=QDoubleValidator(), orientation="horizontal", labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 5 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.comboBox(box1, self, "CALCULATE",
                     label=self.unitLabels()[idx], addSpace=False,
                     items=['Total','PhotoElectric','Rayleigh','Compton','Total-Rayleigh'],
                     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, "GRID",
                     label=self.unitLabels()[idx], addSpace=False,
                    items=['Standard', 'User defined', 'Single Value'],
                    valueType=int, orientation="horizontal", labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 7 
        idx += 1 
        box1 = gui.widgetBox(box) 
        oasysgui.lineEdit(box1, self, "GRIDSTART",
                     label=self.unitLabels()[idx], addSpace=False,
                    valueType=float, validator=QDoubleValidator(), orientation="horizontal", labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 8 
        idx += 1 
        box1 = gui.widgetBox(box) 
        oasysgui.lineEdit(box1, self, "GRIDEND",
                     label=self.unitLabels()[idx], addSpace=False,
                    valueType=float, validator=QDoubleValidator(), orientation="horizontal", labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 9 
        idx += 1 
        box1 = gui.widgetBox(box) 
        oasysgui.lineEdit(box1, self, "GRIDN",
                     label=self.unitLabels()[idx], addSpace=False,
                    valueType=int, validator=QIntValidator(), orientation="horizontal", labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 10 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.comboBox(box1, self, "UNIT",
                     label=self.unitLabels()[idx], addSpace=False,
                    items=['barn/atom [Cross Section] *see help*', 'cm^2 [Cross Section] *see help*', 'cm^2/g [Mass abs coef]', 'cm^-1 [Linear abs coef]'],
                    valueType=int, orientation="horizontal", labelWidth=130)
        self.show_at(self.unitFlags()[idx], box1) 

        # widget index 11
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1, self, "DUMP_TO_FILE",
                     label=self.unitLabels()[idx], addSpace=True,
                     items=["No", "Yes"],
                     orientation="horizontal")
        self.show_at(self.unitFlags()[idx], box1)

        # widget index 12
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1, self, "FILE_NAME",
                     label=self.unitLabels()[idx], addSpace=True)
        self.show_at(self.unitFlags()[idx], box1)




        gui.rubber(self.controlArea)

    def unitLabels(self):
         return ['material','table','formula','density','Cross section','Energy [eV] grid:',
                 'Starting Energy [eV]: ','To: ','Number of points','Units',
                 'Dump to file','File name']

    def unitFlags(self):
         return ['True','self.MAT_FLAG  ==  2','self.MAT_FLAG  <=  1 ','self.MAT_FLAG  ==  1  &  self.UNIT  ==  3',
                 'True','True','self.GRID  !=  0','self.GRID  ==  1','self.GRID  ==  1','True',
                 'True','self.DUMP_TO_FILE == 1']

    def get_help_name(self):
        return 'crosssec'

    def check_fields(self):
        self.DESCRIPTOR = congruence.checkEmptyString(self.DESCRIPTOR, "formula")
        if self.MAT_FLAG == 1:
            self.DENSITY = congruence.checkStrictlyPositiveNumber(self.DENSITY, "density")

        if self.GRID > 0:
            self.GRIDSTART = congruence.checkPositiveNumber(self.GRIDSTART, "Starting Energy")

            if self.GRID == 1:
                self.GRIDEND = congruence.checkStrictlyPositiveNumber(self.GRIDEND, "Energy to")
                congruence.checkLessThan(self.GRIDSTART, self.GRIDEND, "Starting Energy", "Energy to")
                self.GRIDN = congruence.checkStrictlyPositiveNumber(self.GRIDN, "Number of points")


    def do_xoppy_calculation(self):
        out_dict = self.xoppy_calc_xcrosssec()

        if "info" in out_dict.keys():
            print(out_dict["info"])

        #send exchange
        calculated_data = DataExchangeObject("XOPPY", self.get_data_exchange_widget_name())
        
        try:
            calculated_data.add_content("xoppy_data", out_dict["data"].T)
            calculated_data.add_content("plot_x_col",0)
            calculated_data.add_content("plot_y_col",-1)
        except:
            pass
        try:
            calculated_data.add_content("labels", out_dict["labels"])
        except:
            pass
        try:
            calculated_data.add_content("info",out_dict["info"])
        except:
            pass

        return calculated_data

    def extract_data_from_xoppy_output(self, calculation_output):
        try:
            calculation_output.get_content("xoppy_data")

            labels = calculation_output.get_content("labels")

            self.xtitle = labels[0]
            self.ytitle = labels[1]
        except:
            QMessageBox.information(self,
                                    "Calculation Result",
                                    "Calculation Result:\n"+calculation_output.get_content("info"),
                                    QMessageBox.Ok)

            self.xtitle = None
            self.ytitle = None

        return calculation_output

    def plot_results(self, calculated_data, progressBarValue=80):
        self.initializeTabs()

        try:
            calculated_data.get_content("xoppy_data")

            super().plot_results(calculated_data, progressBarValue)
        except:
            self.plot_info(calculated_data.get_content("info") + "\n", progressBarValue, 0, 0)


    def get_data_exchange_widget_name(self):
        return "XCROSSSEC"

    def getTitles(self):
        return ["Calculation Result"]

    def getXTitles(self):
        if self.xtitle is None:
            return [""]
        else:
            return [self.xtitle]

    def getYTitles(self):
        if self.ytitle is None:
            return [""]
        else:
            return [self.ytitle]

    def getLogPlot(self):
        return [(True, True)]

    def getVariablesToPlot(self):
        return [(0, 1)]

    def getLogPlot(self):
        return[(True, True)]


    def xoppy_calc_xcrosssec(self):

        MAT_FLAG = self.MAT_FLAG
        MAT_LIST = self.MAT_LIST
        DESCRIPTOR = self.DESCRIPTOR
        density = self.DENSITY
        CALCULATE = self.CALCULATE
        GRID = self.GRID
        GRIDSTART = self.GRIDSTART
        GRIDEND = self.GRIDEND
        GRIDN = self.GRIDN
        UNIT = self.UNIT


        if MAT_FLAG == 0: # element
            descriptor = DESCRIPTOR
            density = xraylib.ElementDensity(xraylib.SymbolToAtomicNumber(DESCRIPTOR))
        elif MAT_FLAG == 1: # formula
            descriptor = DESCRIPTOR
        elif MAT_FLAG == 2:
            tmp = xraylib.GetCompoundDataNISTByIndex(MAT_LIST)
            descriptor = tmp["name"]
            density = tmp["density"]

        print("xoppy_calc_xcrosssec: using density = %g g/cm3"%density)
        if GRID == 0:
            energy = numpy.arange(0,500)
            elefactor = numpy.log10(10000.0 / 30.0) / 300.0
            energy = 10.0 * 10**(energy * elefactor)
        elif GRID == 1:
            if GRIDN == 1:
                energy = numpy.array([GRIDSTART])
            else:
                energy = numpy.linspace(GRIDSTART,GRIDEND,GRIDN)
        elif GRID == 2:
            energy = numpy.array([GRIDSTART])

        if MAT_FLAG == 0: # element
            out =  cross_calc(descriptor,energy,calculate=CALCULATE,density=density)
        elif MAT_FLAG == 1: # compound parse
            out =  cross_calc_mix(descriptor,energy,calculate=CALCULATE,density=density,parse_or_nist=0)
        elif MAT_FLAG == 2: # NIST compound
            out =  cross_calc_mix(descriptor,energy,calculate=CALCULATE,density=density,parse_or_nist=1)

        calculate_items = ['Total','PhotoElectric','Rayleigh','Compton','Total minus Rayleigh']
        unit_items = ['barn/atom','cm^2','cm^2/g','cm^-1']
        if energy.size > 1:
            tmp_x = out[0,:].copy()
            tmp_y = out[UNIT+1,:].copy()
            tmp = numpy.vstack((tmp_x,tmp_y))
            labels = ["Photon energy [eV]","%s cross section [%s]"%(calculate_items[CALCULATE],unit_items[UNIT])]
            to_return = {"application":"xoppy","name":"xcrosssec","data":tmp,"labels":labels}
        else:
            tmp = None
            txt = "xoppy_calc_xcrosssec: Calculated %s cross section: %g %s"%(calculate_items[CALCULATE],out[UNIT+1,0],unit_items[UNIT])
            print(txt)
            to_return  = {"application":"xoppy","name":"xcrosssec","info":txt}

        if self.DUMP_TO_FILE:
            with open(self.FILE_NAME, "w") as file:
                try:
                    file.write("#F %s\n"%self.FILE_NAME)
                    file.write("\n#S 1 xoppy CrossSec results\n")
                    file.write("#N 5\n")
                    tmp = "#L  Photon energy [eV]"
                    for unit_item in unit_items:
                        tmp += "  %s [%s]"%(calculate_items[CALCULATE],unit_item)
                    tmp += "\n"
                    file.write(tmp)
                    for j in range(out.shape[1]):
                        # file.write("%19.12e  "%energy[j])
                        file.write(("%19.12e  "*out.shape[0]+"\n")%tuple(out[i,j] for i in range(out.shape[0])))
                    file.close()
                    print("File written to disk: %s \n"%self.FILE_NAME)
                except:
                    raise Exception("CrossSec: The data could not be dumped onto the specified file!\n")

        return to_return
Example #15
0
class UndulatorFull(ow_source.Source, WidgetDecorator):

    name = "Full Undulator"
    description = "Shadow Source: Full Undulator"
    icon = "icons/undulator.png"
    priority = 4


    K = Setting(0.25)
    period_length = Setting(0.032)
    periods_number = Setting(50)

    energy_in_GeV = Setting(6.04)
    current = Setting(0.2)
    use_emittances_combo=Setting(1)
    sigma_x = Setting(400e-6)
    sigma_z = Setting(10e-6)
    sigma_divergence_x = Setting(10e-06)
    sigma_divergence_z = Setting(4e-06)

    number_of_rays = Setting(5000)
    seed = Setting(6775431)
    photon_energy = Setting(10500.0)
    harmonic = Setting(1.0)
    set_at_resonance = Setting(0)
    delta_e = Setting(1000.0)
    maxangle_urad = Setting(15)

    # advanced setting
    ng_t = Setting(51)
    ng_p = Setting(11)
    ng_j = Setting(20)
    ng_e = Setting(11)
    code_undul_phot = Setting(0) # 0=internal 1=pySRU 2=SRW
    flag_size = Setting(1) # 0=Point 1=Gaussian 2=backpropagate divergences
    coherent = Setting(0)  # 0=No 1=Yes

    # aux
    file_to_write_out = 0
    plot_aux_graph = 1
    sourceundulator = None

    add_power = False
    power_step = None

    inputs = [("Trigger", TriggerOut, "sendNewBeam2")]
    WidgetDecorator.append_syned_input_data(inputs)

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

        self.controlArea.setFixedWidth(self.CONTROL_AREA_WIDTH)

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

        tab_bas = oasysgui.createTabPage(tabs_setting, "Basic Setting")
        tab_sou = oasysgui.createTabPage(tabs_setting, "Source Setting")
        tab_grid = oasysgui.createTabPage(tabs_setting, "Advanced Settings")

        left_box_1 = oasysgui.widgetBox(tab_bas, "Monte Carlo", addSpace=True, orientation="vertical")

        oasysgui.lineEdit(left_box_1, self, "number_of_rays", "Number of rays", tooltip="Number of Rays", labelWidth=250, valueType=int, orientation="horizontal")
        oasysgui.lineEdit(left_box_1, self, "seed", "Seed", tooltip="Seed (0=clock)", labelWidth=250, valueType=int, orientation="horizontal")

        left_box_2 = oasysgui.widgetBox(tab_sou, "Machine Parameters", addSpace=True, orientation="vertical")

        oasysgui.lineEdit(left_box_2, self, "energy_in_GeV", "Energy [GeV]", labelWidth=250, tooltip="Energy [GeV]", valueType=float, orientation="horizontal")
        oasysgui.lineEdit(left_box_2, self, "current", "Current [A]", labelWidth=250, tooltip="Current [A]", valueType=float, orientation="horizontal")

        gui.comboBox(left_box_2, self, "use_emittances_combo", label="Use Emittances?", items=["No", "Yes"], callback=self.set_UseEmittances, labelWidth=260, orientation="horizontal")

        self.box_use_emittances = oasysgui.widgetBox(left_box_2, "", addSpace=False, orientation="vertical")


        self.le_sigma_x = oasysgui.lineEdit(self.box_use_emittances, self, "sigma_x", "Size RMS H [m]", labelWidth=250, tooltip="Size RMS H [m]", valueType=float, orientation="horizontal")
        self.le_sigma_z = oasysgui.lineEdit(self.box_use_emittances, self, "sigma_z", "Size RMS V [m]", labelWidth=250, tooltip="Size RMS V [m]", valueType=float, orientation="horizontal")

        oasysgui.lineEdit(self.box_use_emittances, self, "sigma_divergence_x", "Divergence RMS H [rad]", labelWidth=250, tooltip="Divergence RMS H [rad]", valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.box_use_emittances, self, "sigma_divergence_z", "Divergence RMS V [rad]", labelWidth=250, tooltip="Divergence RMS V [rad]", valueType=float, orientation="horizontal")

        self.set_UseEmittances()

        left_box_3 = oasysgui.widgetBox(tab_sou, "Undulator Parameters", addSpace=True, orientation="vertical")

        oasysgui.lineEdit(left_box_3, self, "K", "K", labelWidth=250, tooltip="Undulator Deflection Parameter K", valueType=float, orientation="horizontal")
        oasysgui.lineEdit(left_box_3, self, "period_length", "period Length [m]", labelWidth=250, tooltip="Undulator Period Length [m]", valueType=float, orientation="horizontal")
        oasysgui.lineEdit(left_box_3, self, "periods_number", "Number of periods", labelWidth=250, tooltip="Number of periods", valueType=int, orientation="horizontal")

        left_box_4 = oasysgui.widgetBox(tab_sou, "Photon energy", addSpace=True, orientation="vertical")

        #
        gui.comboBox(left_box_4, self, "set_at_resonance",
                     label="Set photon energy", addSpace=False,
                    items=['User defined', 'Set to resonance'],
                    valueType=int, orientation="horizontal", labelWidth=250,callback=self.set_UseResonance)

        self.box_photon_energy = gui.widgetBox(left_box_4)
        oasysgui.lineEdit(self.box_photon_energy, self, "photon_energy", "Photon energy [eV] (center)",
                        tooltip="Photon energy [eV]", labelWidth=250, valueType=float, orientation="horizontal")

        self.box_harmonic = gui.widgetBox(left_box_4)
        oasysgui.lineEdit(self.box_harmonic, self, "harmonic", "Photon energy [N x Resonance]; N: ",
                        tooltip="Photon energy [N x Resonance]; N: ", labelWidth=250, valueType=float, orientation="horizontal")

        self.box_maxangle_urad = gui.widgetBox(left_box_4)
        oasysgui.lineEdit(self.box_maxangle_urad, self, "maxangle_urad", "Max elevation angle for radiation [urad]",
                          tooltip="Max elevation angle for radiation theta [urad]", labelWidth=250, valueType=float, orientation="horizontal")

        self.set_UseResonance()


        #self.box_photon_energy.setEnabled(False)

        oasysgui.lineEdit(left_box_4, self, "delta_e", "Photon energy width [eV] (0=monochr.)", tooltip="Photon energy interval [eV] (0=monochromatic)", labelWidth=250, valueType=float, orientation="horizontal")

        adv_other_box = oasysgui.widgetBox(tab_bas, "Optional file output", addSpace=False, orientation="vertical")

        gui.comboBox(adv_other_box, self, "file_to_write_out", label="Files to write out", labelWidth=120,
                     items=["None", "begin.dat","begin.dat+radiation.h5"],
                     sendSelectedValue=False, orientation="horizontal")


        # advanced
        left_box_5 = oasysgui.widgetBox(tab_grid, "Advanced Settings", addSpace=True, orientation="vertical")
    # ng_t = 51
    # ng_p = 11
    # ng_j = 20
    # ng_e = 11
    # code_undul_phot = 0
    # flag_size = 0
        oasysgui.lineEdit(left_box_5, self, "ng_e", "Points in Photon energy (if polychromatic)",       tooltip="Points in Photon energy",       labelWidth=260, valueType=int, orientation="horizontal")
        oasysgui.lineEdit(left_box_5, self, "ng_t", "Points in theta [elevation]",   tooltip="Points in theta [elevation]",   labelWidth=260, valueType=int, orientation="horizontal")
        oasysgui.lineEdit(left_box_5, self, "ng_p", "Points in phi [azimuthal]",     tooltip="Points in phi [azimuthal]",     labelWidth=260, valueType=int, orientation="horizontal")
        oasysgui.lineEdit(left_box_5, self, "ng_j", "Points in electron trajectory", tooltip="Points in electron trajectory", labelWidth=260, valueType=int, orientation="horizontal")

        gui.comboBox(left_box_5, self, "code_undul_phot", label="Calculation method", labelWidth=120,
                     items=["internal", "pySRU","SRW"],sendSelectedValue=False, orientation="horizontal")

        gui.comboBox(left_box_5, self, "flag_size", label="Radiation Size", labelWidth=120,
                     items=["point", "Gaussian", "Far field backpropagated"],sendSelectedValue=False, orientation="horizontal")

        gui.comboBox(left_box_5, self, "coherent", label="Coherent beam", labelWidth=120,
                     items=["No", "Yes"],sendSelectedValue=False, orientation="horizontal")

        gui.rubber(self.controlArea)


        undulator_plot_tab = oasysgui.widgetBox(self.main_tabs, addToLayout=0, margin=4)

        self.main_tabs.insertTab(1, undulator_plot_tab, "Undulator Plots")

        view_box = oasysgui.widgetBox(undulator_plot_tab, "Plotting Style", addSpace=False, orientation="horizontal")
        view_box_1 = oasysgui.widgetBox(view_box, "", addSpace=False, orientation="vertical", width=350)

        self.undulator_view_type_combo = gui.comboBox(view_box_1, self, "plot_aux_graph", label="Plot Graphs?",
                                            labelWidth=220,
                                            items=["No", "Yes"],
                                            callback=self.set_PlotAuxGraphs, sendSelectedValue=False, orientation="horizontal")

        self.undulator_tab = []
        self.undulator_tabs = oasysgui.tabWidget(undulator_plot_tab)

        self.initializeUndulatorTabs()

        gui.rubber(self.mainArea)

    def sendNewBeam2(self, trigger):
        self.power_step = None
        self.add_power = False

        try:
            if trigger and trigger.new_object == True:
                if trigger.has_additional_parameter("seed_increment"):
                    self.seed += trigger.get_additional_parameter("seed_increment")

                if trigger.has_additional_parameter("energy_value") and trigger.has_additional_parameter("energy_step"):
                    self.set_at_resonance = 0
                    self.photon_energy = trigger.get_additional_parameter("energy_value")
                    self.delta_e = trigger.get_additional_parameter("energy_step")
                    self.power_step = trigger.get_additional_parameter("power_step")

                    self.set_UseResonance()

                    self.add_power = True

                self.runShadowSource()
        except:
            pass

    def set_UseEmittances(self):
        self.box_use_emittances.setVisible(self.use_emittances_combo == 1)

    def set_UseResonance(self):
        self.box_photon_energy.setVisible(self.set_at_resonance == 0)
        self.box_maxangle_urad.setVisible(self.set_at_resonance == 0)
        self.box_harmonic.setVisible(self.set_at_resonance > 0)

    def set_PlotAuxGraphs(self):
        # self.progressBarInit()

        self.initializeUndulatorTabs() # update number of tabs if monochromatic/polychromatic

        if self.sourceundulator is not None:
            try:
                self.initializeUndulatorTabs()

                self.plot_undulator_results()
            except Exception as exception:
                QtWidgets.QMessageBox.critical(self, "Error",
                                           str(exception),
                    QtWidgets.QMessageBox.Ok)

        # self.progressBarFinished()

    def plot_undulator_results(self):
        if self.plot_aux_graph == 1:
            try:

                radiation,photon_energy,theta,phi = self.sourceundulator.get_radiation_polar()

                tabs_canvas_index = 0
                plot_canvas_index = 0
                polarization = self.sourceundulator.get_result_polarization()


                if self.delta_e == 0.0:
                    self.plot_data2D(radiation[0], 1e6*theta, phi,
                                     tabs_canvas_index, plot_canvas_index, title="radiation (photons/s/eV/rad2)", xtitle="theta [urad]", ytitle="phi [rad]")

                    tabs_canvas_index += 1
                    self.plot_data2D(polarization[0], 1e6*theta, phi,
                                     tabs_canvas_index, plot_canvas_index, title="polarization |Es|/(|Es|+|Ep|)", xtitle="theta [urad]", ytitle="phi [rad]")

                    tabs_canvas_index += 1
                    radiation_interpolated,photon_energy,vx,vz = self.sourceundulator.get_radiation_interpolated_cartesian()
                    self.plot_data2D(radiation_interpolated[0], 1e6*vx, 1e6*vz,
                                     tabs_canvas_index, plot_canvas_index, title="radiation", xtitle="vx [urad]", ytitle="vz [rad]")

                    tabs_canvas_index += 1
                    x,y = self.sourceundulator.get_photon_size_distribution()
                    self.plot_data1D(x*1e6,y,
                                     tabs_canvas_index, plot_canvas_index,
                                     title="Photon emission size distribution", xtitle="Distance [um]", ytitle="Intensity [arbitrary units]")

                else:
                    self.plot_data3D(radiation, photon_energy, 1e6*theta, phi,
                                     tabs_canvas_index, plot_canvas_index,
                                     title="radiation (photons/s/eV/rad2)", xtitle="theta [urad]", ytitle="phi [rad]",
                                     callback_for_title=self.get_title_for_stack_view_flux)

                    tabs_canvas_index += 1
                    self.plot_data3D(polarization, photon_energy, 1e6*theta, phi,
                                     tabs_canvas_index, plot_canvas_index,
                                     title="polarization |Es|/(|Es|+|Ep|)", xtitle="theta [urad]", ytitle="phi [rad]",
                                     callback_for_title=self.get_title_for_stack_view_polarization)

                    tabs_canvas_index += 1
                    radiation_interpolated,photon_energy,vx,vz = self.sourceundulator.get_radiation_interpolated_cartesian()
                    self.plot_data3D(radiation_interpolated, photon_energy, 1e6*vx, 1e6*vz,
                                     tabs_canvas_index, plot_canvas_index,
                                     title="radiation", xtitle="vx [urad]", ytitle="vz [rad]",
                                     callback_for_title=self.get_title_for_stack_view_flux)

                    tabs_canvas_index += 1
                    x,y = self.sourceundulator.get_photon_size_distribution()
                    self.plot_data1D(x*1e6,y,
                                     tabs_canvas_index, plot_canvas_index,
                                     title="Photon emission size distribution", xtitle="Distance [um]", ytitle="Intensity [arbitrary units]")
                    #
                    # if polychromatic, plot power density
                    #

                    intens_xy,vx,vz = self.sourceundulator.get_power_density_interpolated_cartesian()

                    tabs_canvas_index += 1
                    self.plot_data2D(1e-6*intens_xy,1e6*vx,1e6*vz,
                                     tabs_canvas_index, plot_canvas_index,
                                     title="power density W/mrad2", xtitle="vx [urad]", ytitle="vz [rad]")


                    #
                    # if polychromatic, plot flux(energy)
                    #


                    flux,spectral_power,photon_energy = self.sourceundulator.get_flux_and_spectral_power()

                    tabs_canvas_index += 1
                    self.plot_data1D(photon_energy,flux,
                                     tabs_canvas_index, plot_canvas_index,
                                     title="Flux", xtitle="Photon Energy [eV]", ytitle="Flux [photons/s/0.1%bw]")


                    tabs_canvas_index += 1
                    self.plot_data1D(photon_energy,spectral_power,
                                     tabs_canvas_index, plot_canvas_index,
                                     title="Spectral Power", xtitle="Photon Energy [eV]", ytitle="Spectral Power [W/eV]")

                    print("\n\n")
                    # print("Total power (integral [sum] of spectral power) [W]: ",spectral_power.sum()*(photon_energy[1]-photon_energy[0]))
                    print("Total power (integral [trapz] of spectral power) [W]: ",numpy.trapz(spectral_power,photon_energy))
                    print("Total number of photons (integral [trapz] of flux): ",numpy.trapz(flux/(1e-3*photon_energy),photon_energy))
                    print("\n\n")




            except Exception as exception:
                QtWidgets.QMessageBox.critical(self, "Error",
                                           str(exception),
                    QtWidgets.QMessageBox.Ok)

    def get_title_for_stack_view_flux(self,idx):
        photon_energy = self.sourceundulator.get_result_photon_energy()
        return "Units: Photons/s/eV/rad2; Photon energy: %8.3f eV"%(photon_energy[idx])


    #
    # these are plottting routines hacked from xoppy code TODO: promote to higher level/superclass ?
    #
    def get_title_for_stack_view_polarization(self,idx):
        photon_energy = self.sourceundulator.get_result_photon_energy()
        return "|Es| / (|Es|+|Ep|); Photon energy: %8.3f eV"%(photon_energy[idx])

    def plot_data3D(self, data3D, dataE, dataX, dataY, tabs_canvas_index, plot_canvas_index, title="", xtitle="", ytitle="",
                    callback_for_title=(lambda idx: "")):

        for i in range(1+self.undulator_tab[tabs_canvas_index].layout().count()):
            self.undulator_tab[tabs_canvas_index].layout().removeItem(self.undulator_tab[tabs_canvas_index].layout().itemAt(i))

        ##self.tab[tabs_canvas_index].layout().removeItem(self.tab[tabs_canvas_index].layout().itemAt(0))


        xmin = numpy.min(dataX)
        xmax = numpy.max(dataX)
        ymin = numpy.min(dataY)
        ymax = numpy.max(dataY)


        stepX = dataX[1]-dataX[0]
        stepY = dataY[1]-dataY[0]
        if len(dataE) > 1: stepE = dataE[1]-dataE[0]
        else: stepE = 1.0

        if stepE == 0.0: stepE = 1.0
        if stepX == 0.0: stepX = 1.0
        if stepY == 0.0: stepY = 1.0

        dim0_calib = (dataE[0],stepE)
        dim1_calib = (ymin, stepY)
        dim2_calib = (xmin, stepX)


        data_to_plot = numpy.swapaxes(data3D,1,2)

        colormap = {"name":"temperature", "normalization":"linear", "autoscale":True, "vmin":0, "vmax":0, "colors":256}

        self.und_plot_canvas[plot_canvas_index] = StackViewMainWindow()
        self.und_plot_canvas[plot_canvas_index].setGraphTitle(title)
        self.und_plot_canvas[plot_canvas_index].setLabels(["Photon Energy [eV]",ytitle,xtitle])
        self.und_plot_canvas[plot_canvas_index].setColormap(colormap=colormap)
        self.und_plot_canvas[plot_canvas_index].setStack(numpy.array(data_to_plot),
                                                     calibrations=[dim0_calib, dim1_calib, dim2_calib] )

        self.und_plot_canvas[plot_canvas_index].setTitleCallback( callback_for_title )
        self.undulator_tab[tabs_canvas_index].layout().addWidget(self.und_plot_canvas[plot_canvas_index])



    def plot_data2D(self, data2D, dataX, dataY, tabs_canvas_index, plot_canvas_index, title="", xtitle="", ytitle=""):

        for i in range(1+self.undulator_tab[tabs_canvas_index].layout().count()):
            self.undulator_tab[tabs_canvas_index].layout().removeItem(self.undulator_tab[tabs_canvas_index].layout().itemAt(i))

        origin = (dataX[0],dataY[0])
        scale = (dataX[1]-dataX[0],dataY[1]-dataY[0])

        data_to_plot = data2D.T

        colormap = {"name":"temperature", "normalization":"linear", "autoscale":True, "vmin":0, "vmax":0, "colors":256}

        self.und_plot_canvas[plot_canvas_index] = Plot2D()
        self.und_plot_canvas[plot_canvas_index].resetZoom()
        self.und_plot_canvas[plot_canvas_index].setXAxisAutoScale(True)
        self.und_plot_canvas[plot_canvas_index].setYAxisAutoScale(True)
        self.und_plot_canvas[plot_canvas_index].setGraphGrid(False)
        self.und_plot_canvas[plot_canvas_index].setKeepDataAspectRatio(True)
        self.und_plot_canvas[plot_canvas_index].yAxisInvertedAction.setVisible(False)
        self.und_plot_canvas[plot_canvas_index].setXAxisLogarithmic(False)
        self.und_plot_canvas[plot_canvas_index].setYAxisLogarithmic(False)
        self.und_plot_canvas[plot_canvas_index].getMaskAction().setVisible(False)
        self.und_plot_canvas[plot_canvas_index].getRoiAction().setVisible(False)
        self.und_plot_canvas[plot_canvas_index].getColormapAction().setVisible(False)
        self.und_plot_canvas[plot_canvas_index].setKeepDataAspectRatio(False)



        self.und_plot_canvas[plot_canvas_index].addImage(numpy.array(data_to_plot),
                                                     legend="",
                                                     scale=scale,
                                                     origin=origin,
                                                     colormap=colormap,
                                                     replace=True)

        self.und_plot_canvas[plot_canvas_index].setActiveImage("")
        self.und_plot_canvas[plot_canvas_index].setGraphXLabel(xtitle)
        self.und_plot_canvas[plot_canvas_index].setGraphYLabel(ytitle)
        self.und_plot_canvas[plot_canvas_index].setGraphTitle(title)

        self.undulator_tab[tabs_canvas_index].layout().addWidget(self.und_plot_canvas[plot_canvas_index])

    def plot_data1D(self, dataX, dataY, tabs_canvas_index, plot_canvas_index, title="", xtitle="", ytitle=""):

        self.undulator_tab[tabs_canvas_index].layout().removeItem(self.undulator_tab[tabs_canvas_index].layout().itemAt(0))

        self.und_plot_canvas[plot_canvas_index] = oasysgui.plotWindow()

        self.und_plot_canvas[plot_canvas_index].addCurve(dataX, dataY,)

        self.und_plot_canvas[plot_canvas_index].resetZoom()
        self.und_plot_canvas[plot_canvas_index].setXAxisAutoScale(True)
        self.und_plot_canvas[plot_canvas_index].setYAxisAutoScale(True)
        self.und_plot_canvas[plot_canvas_index].setGraphGrid(False)

        self.und_plot_canvas[plot_canvas_index].setXAxisLogarithmic(False)
        self.und_plot_canvas[plot_canvas_index].setYAxisLogarithmic(False)
        self.und_plot_canvas[plot_canvas_index].setGraphXLabel(xtitle)
        self.und_plot_canvas[plot_canvas_index].setGraphYLabel(ytitle)
        self.und_plot_canvas[plot_canvas_index].setGraphTitle(title)

        self.undulator_tab[tabs_canvas_index].layout().addWidget(self.und_plot_canvas[plot_canvas_index])

    #
    # end plotting routines
    #

    def initializeUndulatorTabs(self):
        current_tab = self.undulator_tabs.currentIndex()

        size = len(self.undulator_tab)
        indexes = range(0, size)
        for index in indexes:
            self.undulator_tabs.removeTab(size-1-index)

        if self.delta_e == 0.0:
            self.undulator_tab = [
                gui.createTabPage(self.undulator_tabs, "Radiation intensity (polar)"),
                gui.createTabPage(self.undulator_tabs, "Polarization (polar)"),
                gui.createTabPage(self.undulator_tabs, "Radiation intensity (cartesian - interpolated)"),
                gui.createTabPage(self.undulator_tabs, "Photon source size"),
            ]

            self.und_plot_canvas = [None,None,None,None,]
        else:
            self.undulator_tab = [
                gui.createTabPage(self.undulator_tabs, "Radiation (polar)"),
                gui.createTabPage(self.undulator_tabs, "Polarization (polar)"),
                gui.createTabPage(self.undulator_tabs, "Radiation (interpolated)"),
                gui.createTabPage(self.undulator_tabs, "Photon source size"),
                gui.createTabPage(self.undulator_tabs, "Power Density (interpolated)"),
                gui.createTabPage(self.undulator_tabs, "Flux"),
                gui.createTabPage(self.undulator_tabs, "Spectral Power"),
            ]

            self.und_plot_canvas = [None,None,None,None,None,None,None,]

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

        # self.undulator_plot_canvas = [None, None, None]

        self.undulator_tabs.setCurrentIndex(current_tab)


    def runShadowSource(self):

        self.setStatusMessage("")
        self.progressBarInit()

        # this is to be able to start the widget out of Oasys
        try:
            tmp = self.workspace_units
        except:
            self.workspace_units = 'm'
            self.workspace_units_label = 'm'
            self.workspace_units_to_m = 1.0
            self.workspace_units_to_cm = 1e2
            self.workspace_units_to_mm = 1e3


        self.checkFields()

        self.progressBarSet(10)

        self.setStatusMessage("Running SHADOW")

        sys.stdout = EmittingStream(textWritten=self.writeStdOut)
        if self.trace_shadow:
            grabber = TTYGrabber()
            grabber.start()

        self.progressBarSet(50)

        try:
            self.shadow_output.setText("")
            su = Undulator.initialize_as_vertical_undulator(
                K=self.K,
                period_length=self.period_length,
                periods_number=int(self.periods_number))


            ebeam = ElectronBeam(
                energy_in_GeV=self.energy_in_GeV,
                energy_spread = 0.0,
                current = self.current,
                number_of_bunches = 1,
                moment_xx=(self.sigma_x)**2,
                moment_xxp=0.0,
                moment_xpxp=(self.sigma_divergence_x)**2,
                moment_yy=(self.sigma_z)**2,
                moment_yyp=0.0,
                moment_ypyp=(self.sigma_divergence_z)**2 )

            print(ebeam.info())


            codes = ["internal","pySRU","SRW"]
            selected_code = codes[self.code_undul_phot]

            self.sourceundulator = SourceUndulator(
                name="shadowOui-Full-Undulator",
                syned_electron_beam=ebeam,
                syned_undulator=su,
                flag_emittance=self.use_emittances_combo,
                flag_size=self.flag_size,
                emin=1000, # to be set later
                emax=1001, # to be set later
                ng_e=2,    # to be set later
                maxangle=self.maxangle_urad*1e-6,
                ng_t=self.ng_t,
                ng_p=self.ng_p,
                ng_j=self.ng_j,
                code_undul_phot=selected_code)

            if self.set_at_resonance == 0:
                if self.delta_e == 0:
                    self.sourceundulator.set_energy_box(self.photon_energy,self.photon_energy,1)
                else:
                    self.sourceundulator.set_energy_box(self.photon_energy-0.5*self.delta_e,
                                                        self.photon_energy+0.5*self.delta_e,self.ng_e)
            else:
                self.sourceundulator.set_energy_monochromatic_at_resonance(self.harmonic)
                if self.delta_e > 0.0:
                    e0,e1,ne = self.sourceundulator.get_energy_box()
                    self.sourceundulator.set_energy_box(e0-0.5*self.delta_e,e0+0.5*self.delta_e,self.ng_e)

            rays = self.sourceundulator.calculate_rays(
                user_unit_to_m=self.workspace_units_to_m,
                F_COHER=self.coherent,
                SEED=self.seed,
                NRAYS=self.number_of_rays)

            if self.plot_aux_graph:
                self.set_PlotAuxGraphs()

            print(self.sourceundulator.info())

            shadow3_beam = Shadow3Beam(N=rays.shape[0])
            shadow3_beam.rays = rays

            if self.file_to_write_out >= 1:
                shadow3_beam.write("begin.dat")
                print("File written to disk: begin.dat")

            if self.file_to_write_out >= 2:
                SourceUndulatorInputOutput.write_file_undul_phot_h5(self.sourceundulator.get_result_dictionary(),
                                            file_out="radiation.h5",mode="w",entry_name="radiation")

            beam_out = ShadowBeam(beam=shadow3_beam)
            beam_out.getOEHistory().append(ShadowOEHistoryItem(shadow_source_start=ShadowSource.create_src(),
                                                               shadow_source_end=ShadowSource.create_src(),
                                                               widget_class_name="Full Undulator"))

            if self.add_power:
                additional_parameters = {}

                pd, vx, vy = self.sourceundulator.get_power_density_interpolated_cartesian()

                total_power = self.power_step if self.power_step > 0 else pd.sum()*(vx[1]-vx[0])*(vy[1]-vy[0])

                additional_parameters["total_power"]        = total_power
                additional_parameters["photon_energy_step"] = self.delta_e

                beam_out.setScanningData(ShadowBeam.ScanningData("photon_energy",
                                                                 self.photon_energy,
                                                                 "Energy for Power Calculation",
                                                                 "eV",
                                                                 additional_parameters))

            if self.delta_e == 0.0:
                beam_out.set_initial_flux(self.sourceundulator.get_flux()[0])

            self.progressBarSet(80)
            self.plot_results(beam_out)

            #
            # create python script for creating the shadow3 beam and display the script in the standard output
            #
            dict_parameters = {
                "K"                  : self.K,
                "period_length"      : self.period_length,
                "periods_number"     : self.periods_number,
                "energy_in_GeV"      : self.energy_in_GeV,
                "energy_spread"      : 0.0,
                "current"            : self.current,
                "number_of_bunches"  : 1,
                "moment_xx"          : (self.sigma_x) ** 2,
                "moment_xxp"         : 0.0,
                "moment_xpxp"        : (self.sigma_divergence_x) ** 2,
                "moment_yy"          : (self.sigma_z) ** 2,
                "moment_yyp"         : 0.0,
                "moment_ypyp"        : (self.sigma_divergence_z) ** 2,
                "name"               : "shadowOui-Full-Undulator",
                "flag_emittance"     : self.use_emittances_combo,
                "flag_size"          : self.flag_size,
                "emin"               : 1000,  # to be set later
                "emax"               : 1001,  # to be set later
                "ng_e"               : 2,  # to be set later
                "maxangle"           : self.maxangle_urad * 1e-6,
                "ng_t"               : self.ng_t,
                "ng_p"               : self.ng_p,
                "ng_j"               : self.ng_j,
                "code_undul_phot"    : selected_code,
                "user_unit_to_m"     : self.workspace_units_to_m,
                "F_COHER"            : self.coherent,
                "SEED"               : self.seed,
                "NRAYS"              : self.number_of_rays,
                "EMIN": self.sourceundulator._EMIN,
                "EMAX": self.sourceundulator._EMAX,
                "NG_E": self.sourceundulator._NG_E,
                "MAXANGLE": self.sourceundulator._MAXANGLE,

            }

            # write python script in standard output
            print(self.script_template().format_map(dict_parameters))


            self.setStatusMessage("")
            self.send("Beam", beam_out)

        except Exception as exception:
            QtWidgets.QMessageBox.critical(self, "Error",
                                       str(exception),
                QtWidgets.QMessageBox.Ok)

            if self.IS_DEVELOP: raise exception

        self.progressBarFinished()

    def script_template(self):
     return """
#
# script to calculate the shadow3 beam for the full undulator (created by ShadowOui:UndulatorFull\)
#
from syned.storage_ring.electron_beam import ElectronBeam
from syned.storage_ring.magnetic_structures.undulator import Undulator
from orangecontrib.shadow.util.undulator.source_undulator import SourceUndulator
import Shadow
from Shadow import Beam as Shadow3Beam

su = Undulator.initialize_as_vertical_undulator(
    K={K},
    period_length={period_length},
    periods_number={periods_number})


ebeam = ElectronBeam(
    energy_in_GeV={energy_in_GeV},
    energy_spread = {energy_spread},
    current = {current},
    number_of_bunches = {number_of_bunches},
    moment_xx   ={moment_xx},
    moment_xxp  ={moment_xxp},
    moment_xpxp ={moment_xpxp},
    moment_yy  ={moment_yy},
    moment_yyp ={moment_yyp},
    moment_ypyp={moment_ypyp})

print(ebeam.info())

sourceundulator = SourceUndulator(
    name="{name}",
    syned_electron_beam=ebeam,
    syned_undulator=su,
    flag_emittance={flag_emittance},
    flag_size={flag_size},
    emin       = {emin},
    emax       = {emax},
    ng_e       = {ng_e},
    maxangle   = {maxangle},
    ng_t={ng_t},
    ng_p={ng_p},
    ng_j={ng_j},
    code_undul_phot="{code_undul_phot}")
    
sourceundulator._EMIN = {EMIN}
sourceundulator._EMAX = {EMAX}
sourceundulator._NG_E = {NG_E}
sourceundulator._MAXANGLE = {MAXANGLE}

rays = sourceundulator.calculate_rays(
    user_unit_to_m={user_unit_to_m},
    F_COHER={F_COHER},
    SEED={SEED},
    NRAYS={NRAYS})

print(sourceundulator.info())

beam = Shadow3Beam(N=rays.shape[0])
beam.rays = rays

Shadow.ShadowTools.plotxy(beam,1,3,nbins=101,nolost=1,title="Real space")
# Shadow.ShadowTools.plotxy(beam,1,4,nbins=101,nolost=1,title="Phase space X")
# Shadow.ShadowTools.plotxy(beam,3,6,nbins=101,nolost=1,title="Phase space Z")
    
#
# end script
#
"""


    def sendNewBeam(self, trigger):
       if trigger and trigger.new_object == True:
           self.runShadowSource()

    def checkFields(self):
        self.number_of_rays = congruence.checkPositiveNumber(self.number_of_rays, "Number of rays")
        self.seed = congruence.checkPositiveNumber(self.seed, "Seed")
        self.photon_energy = congruence.checkPositiveNumber(self.photon_energy, "Energy")
        self.delta_e = congruence.checkPositiveNumber(self.delta_e, "Delta Energy")

        self.energy_in_GeV = congruence.checkPositiveNumber(self.energy_in_GeV,"Energy [GeV]")
        self.current = congruence.checkPositiveNumber(self.current,"Current [A]")

        self.sigma_x = congruence.checkPositiveNumber(self.sigma_x, "Size RMS H")
        self.sigma_z = congruence.checkPositiveNumber(self.sigma_z, "Size RMS V")
        self.sigma_divergence_x = congruence.checkPositiveNumber(self.sigma_divergence_x, "Divergence RMS H")
        self.sigma_divergence_z = congruence.checkPositiveNumber(self.sigma_divergence_z, "Divergence RMS V")

        self.K = congruence.checkPositiveNumber(self.K,"K")
        self.period_length = congruence.checkPositiveNumber(self.period_length,"period length [m]")
        self.periods_number = congruence.checkStrictlyPositiveNumber(self.periods_number,"Number of periods")

        self.ng_t = int( congruence.checkStrictlyPositiveNumber(self.ng_t,"Number of points in theta") )
        self.ng_p = int( congruence.checkStrictlyPositiveNumber(self.ng_p,"Number of points in phi") )
        self.ng_j = int( congruence.checkStrictlyPositiveNumber(self.ng_j,"Number of points in trajectory") )
        self.ng_e = int( congruence.checkStrictlyPositiveNumber(self.ng_e,"Number of points in energy") )


    def receive_syned_data(self, data):
        if not data is None:
            if isinstance(data, synedb.Beamline):
                if not data.get_light_source() is None:
                    if isinstance(data.get_light_source().get_magnetic_structure(), synedu.Undulator):
                        light_source = data.get_light_source()

                        # self.photon_energy =  round(light_source.get_magnetic_structure().resonance_energy(light_source.get_electron_beam().gamma()), 3)
                        self.set_at_resonance = 1
                        self.set_UseResonance()
                        self.delta_e = 0.0

                        self.energy_in_GeV = light_source.get_electron_beam().energy()
                        self.current = light_source.get_electron_beam().current()

                        x, xp, y, yp = light_source.get_electron_beam().get_sigmas_all()

                        self.sigma_x = x
                        self.sigma_z = y
                        self.sigma_divergence_x = xp
                        self.sigma_divergence_z = yp

                        self.period_length = light_source.get_magnetic_structure().period_length()
                        self.periods_number = int(light_source.get_magnetic_structure().number_of_periods()) # in meter
                        self.K = light_source.get_magnetic_structure().K_vertical()
                    else:
                        raise ValueError("Syned light source not congruent")
                else:
                    raise ValueError("Syned data not correct: light source not present")
            else:
                raise ValueError("Syned data not correct")
Example #16
0
class OWxtubes(XoppyWidget):
    name = "Tubes"
    id = "orange.widgets.dataxtubes"
    description = "X-ray tube Spectrum (Mo,Rh,W)"
    icon = "icons/xoppy_xtubes.png"
    priority = 15
    category = ""
    keywords = ["xoppy", "xtubes"]

    ITUBE = Setting(0)
    VOLTAGE = Setting(30.0)

    def build_gui(self):

        box = oasysgui.widgetBox(self.controlArea, self.name + " Input Parameters",orientation="vertical", width=self.CONTROL_AREA_WIDTH-5)

        idx = -1 
        
        #widget index 0 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.comboBox(box1, self, "ITUBE",
                     label=self.unitLabels()[idx], addSpace=False,
                    items=['Mo', 'Rh', 'W'],
                    valueType=int, orientation="horizontal", labelWidth=330)
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 1 
        idx += 1 
        box1 = gui.widgetBox(box) 
        oasysgui.lineEdit(box1, self, "VOLTAGE",
                     label=self.unitLabels()[idx], addSpace=False,
                    valueType=float, validator=QDoubleValidator(), orientation="horizontal", labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1) 

    def unitLabels(self):
         return ['Target element ','Voltage  [kV] (18<V<42)']

    def unitFlags(self):
         return ['True','True']

    def get_help_name(self):
        return 'xtubes'

    def check_fields(self):
        if self.VOLTAGE <= 18 or self.VOLTAGE >= 42: raise Exception("Voltage out of range")

    def do_xoppy_calculation(self):
        return xoppy_calc_xtubes(ITUBE=self.ITUBE,VOLTAGE=self.VOLTAGE)

    def get_data_exchange_widget_name(self):
        return "XTUBES"

    def getTitles(self):
        return ['X-Ray Tube Spectrum']

    def getXTitles(self):
        return ["Energy [eV]"]

    def getYTitles(self):
        return ["Fluence [photons/s/mm^2/0.5keV(bw)/mA]"]
Example #17
0
class OWxurgent(widget.OWWidget):
    name = "xurgent"
    id = "orange.widgets.dataxurgent"
    description = "xoppy application to compute..."
    icon = "icons/xoppy_xurgent.png"
    author = "create_widget.py"
    maintainer_email = "*****@*****.**"
    priority = 10
    category = ""
    keywords = ["xoppy", "xurgent"]
    outputs = [{
        "name": "xoppy_data",
        "type": np.ndarray,
        "doc": ""
    }, {
        "name": "xoppy_specfile",
        "type": str,
        "doc": ""
    }]

    #inputs = [{"name": "Name",
    #           "type": type,
    #           "handler": None,
    #           "doc": ""}]

    want_main_area = False

    TITLE = Setting("ESRF HIGH BETA UNDULATOR")
    ENERGY = Setting(6.039999961853027)
    CUR = Setting(0.100000001490116)
    SIGX = Setting(0.400000005960464)
    SIGY = Setting(0.079999998211861)
    SIGX1 = Setting(0.016000000759959)
    SIGY1 = Setting(0.00899999961257)
    ITYPE = Setting(1)
    PERIOD = Setting(0.046000000089407)
    N = Setting(32)
    KX = Setting(0.0)
    KY = Setting(1.700000047683716)
    PHASE = Setting(0.0)
    EMIN = Setting(10000.0)
    EMAX = Setting(50000.0)
    NENERGY = Setting(100)
    D = Setting(27.0)
    XPC = Setting(0.0)
    YPC = Setting(0.0)
    XPS = Setting(3.0)
    YPS = Setting(3.0)
    NXP = Setting(25)
    NYP = Setting(25)
    MODE = Setting(4)
    ICALC = Setting(2)
    IHARM = Setting(-1)
    NPHI = Setting(0)
    NSIG = Setting(0)
    NALPHA = Setting(0)
    DALPHA = Setting(0.0)
    NOMEGA = Setting(0)
    DOMEGA = Setting(0.0)

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

        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)
        self.process_showers()
        box = gui.widgetBox(self.controlArea, " ", orientation="vertical")

        idx = -1

        #widget index 0
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "TITLE",
                     label=self.unitLabels()[idx],
                     addSpace=True)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 1
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "ENERGY",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 2
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "CUR",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 3
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "SIGX",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 4
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "SIGY",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 5
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "SIGX1",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 6
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "SIGY1",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 7
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "ITYPE",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=int,
                     validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 8
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "PERIOD",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 9
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "N",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=int,
                     validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 10
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "KX",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 11
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "KY",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 12
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "PHASE",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 13
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "EMIN",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 14
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "EMAX",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 15
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "NENERGY",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=int,
                     validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 16
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "D",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 17
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "XPC",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 18
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "YPC",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 19
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "XPS",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 20
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "YPS",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 21
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "NXP",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=int,
                     validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 22
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "NYP",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=int,
                     validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 23
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "MODE",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=int,
                     validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 24
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "ICALC",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=int,
                     validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 25
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "IHARM",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=int,
                     validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 26
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "NPHI",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=int,
                     validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 27
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "NSIG",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=int,
                     validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 28
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "NALPHA",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=int,
                     validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 29
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "DALPHA",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 30
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "NOMEGA",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=int,
                     validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 31
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "DOMEGA",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        gui.rubber(self.controlArea)

    def unitLabels(self):
        return [
            'Dummy_title', 'Dummy_title', 'Dummy_title', 'Dummy_title',
            'Dummy_title', 'Dummy_title', 'Dummy_title', 'Dummy_title',
            'Dummy_title', 'Dummy_title', 'Dummy_title', 'Dummy_title',
            'Dummy_title', 'Dummy_title', 'Dummy_title', 'Dummy_title',
            'Dummy_title', 'Dummy_title', 'Dummy_title', 'Dummy_title',
            'Dummy_title', 'Dummy_title', 'Dummy_title', 'Dummy_title',
            'Dummy_title', 'Dummy_title', 'Dummy_title', 'Dummy_title',
            'Dummy_title', 'Dummy_title', 'Dummy_title', 'Dummy_title'
        ]

    def unitFlags(self):
        return [
            'True', 'True', 'True', 'True', 'True', 'True', 'True', 'True',
            'True', 'True', 'True', 'True', 'True', 'True', 'True', 'True',
            'True', 'True', 'True', 'True', 'True', 'True', 'True', 'True',
            'True', 'True', 'True', 'True', 'True', 'True', 'True', 'True'
        ]

    #def unitNames(self):
    #     return ['TITLE','ENERGY','CUR','SIGX','SIGY','SIGX1','SIGY1','ITYPE','PERIOD','N','KX','KY','PHASE','EMIN','EMAX','NENERGY','D','XPC','YPC','XPS','YPS','NXP','NYP','MODE','ICALC','IHARM','NPHI','NSIG','NALPHA','DALPHA','NOMEGA','DOMEGA']

    def compute(self):
        fileName = xoppy_calc_xurgent(TITLE=self.TITLE,
                                      ENERGY=self.ENERGY,
                                      CUR=self.CUR,
                                      SIGX=self.SIGX,
                                      SIGY=self.SIGY,
                                      SIGX1=self.SIGX1,
                                      SIGY1=self.SIGY1,
                                      ITYPE=self.ITYPE,
                                      PERIOD=self.PERIOD,
                                      N=self.N,
                                      KX=self.KX,
                                      KY=self.KY,
                                      PHASE=self.PHASE,
                                      EMIN=self.EMIN,
                                      EMAX=self.EMAX,
                                      NENERGY=self.NENERGY,
                                      D=self.D,
                                      XPC=self.XPC,
                                      YPC=self.YPC,
                                      XPS=self.XPS,
                                      YPS=self.YPS,
                                      NXP=self.NXP,
                                      NYP=self.NYP,
                                      MODE=self.MODE,
                                      ICALC=self.ICALC,
                                      IHARM=self.IHARM,
                                      NPHI=self.NPHI,
                                      NSIG=self.NSIG,
                                      NALPHA=self.NALPHA,
                                      DALPHA=self.DALPHA,
                                      NOMEGA=self.NOMEGA,
                                      DOMEGA=self.DOMEGA)
        #send specfile

        if fileName == None:
            print("Nothing to send")
        else:
            self.send("xoppy_specfile", fileName)
            sf = specfile.Specfile(fileName)
            if sf.scanno() == 1:
                #load spec file with one scan, # is comment
                print("Loading file:  ", fileName)
                out = np.loadtxt(fileName)
                print("data shape: ", out.shape)
                #get labels
                txt = open(fileName).readlines()
                tmp = [line.find("#L") for line in txt]
                itmp = np.where(np.array(tmp) != (-1))
                labels = txt[itmp[0]].replace("#L ", "").split("  ")
                print("data labels: ", labels)
                self.send("xoppy_data", out)
            else:
                print(
                    "File %s contains %d scans. Cannot send it as xoppy_table"
                    % (fileName, sf.scanno()))

    def defaults(self):
        self.resetSettings()
        self.compute()
        return

    def help1(self):
        print("help pressed.")
        xoppy_doc('xurgent')
Example #18
0
class OWxwiggler(XoppyWidget):
    name = "WIGGLER"
    id = "orange.widgets.dataxwiggler"
    description = "Wiggler Spectrum (Full Emission)"
    icon = "icons/xoppy_xwiggler.png"
    priority = 9
    category = ""
    keywords = ["xoppy", "xwiggler"]

    FIELD = Setting(0)
    NPERIODS = Setting(12)
    ULAMBDA = Setting(0.125)
    K = Setting(14.0)
    ENERGY = Setting(6.04)
    PHOT_ENERGY_MIN = Setting(100.0)
    PHOT_ENERGY_MAX = Setting(100100.0)
    NPOINTS = Setting(100)
    NTRAJPOINTS = Setting(101)
    CURRENT = Setting(200.0)
    FILE = Setting("?")

    def build_gui(self):

        box = oasysgui.widgetBox(self.controlArea,
                                 self.name + " Input Parameters",
                                 orientation="vertical",
                                 width=self.CONTROL_AREA_WIDTH - 5)

        idx = -1

        #widget index 0
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "FIELD",
                     label=self.unitLabels()[idx],
                     addSpace=False,
                     items=['Sinusoidal', 'B from file', 'B from harmonics'],
                     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,
                          "NPERIODS",
                          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,
                          "ULAMBDA",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 3
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "K",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 4
        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)

        #widget index 5
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "PHOT_ENERGY_MIN",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 6
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "PHOT_ENERGY_MAX",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 7
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "NPOINTS",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          validator=QIntValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 9
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "NTRAJPOINTS",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=int,
                          validator=QIntValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 10
        idx += 1
        box1 = gui.widgetBox(box)
        oasysgui.lineEdit(box1,
                          self,
                          "CURRENT",
                          label=self.unitLabels()[idx],
                          addSpace=False,
                          valueType=float,
                          validator=QDoubleValidator(),
                          orientation="horizontal",
                          labelWidth=250)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 11
        idx += 1

        box1 = gui.widgetBox(box)

        file_box = oasysgui.widgetBox(box1,
                                      "",
                                      addSpace=False,
                                      orientation="horizontal",
                                      height=25)

        self.le_file = oasysgui.lineEdit(file_box,
                                         self,
                                         "FILE",
                                         label=self.unitLabels()[idx],
                                         addSpace=False,
                                         orientation="horizontal")
        self.show_at(self.unitFlags()[idx], box1)

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

    def unitLabels(self):
        return [
            'Magnetic field: ', 'Number of periods', 'Wiggler period [m]',
            'K value', 'Beam energy [GeV]', 'Min Photon Energy [eV]',
            'Max Photon Energy [eV]', 'Number of energy points',
            'Number of traj points per period', 'Electron Beam Current [mA]',
            'File with Magnetic Field'
        ]

    def unitFlags(self):
        return [
            'True', 'True', 'self.FIELD  !=  1', 'self.FIELD  ==  0', 'True',
            'True', 'True', 'True', 'self.FIELD  !=  1', 'True',
            'self.FIELD  !=  0'
        ]

    def selectFile(self):
        self.le_file.setText(
            oasysgui.selectFileFromDialog(self, self.FILE, "Open B File"))

    def get_help_name(self):
        return 'wiggler'

    def check_fields(self):
        self.NPERIODS = congruence.checkStrictlyPositiveNumber(
            self.NPERIODS, "Number of Periods")
        self.ENERGY = congruence.checkStrictlyPositiveNumber(
            self.ENERGY, "Beam Energy")
        self.PHOT_ENERGY_MIN = congruence.checkPositiveNumber(
            self.PHOT_ENERGY_MIN, "Min Photon Energy")
        self.PHOT_ENERGY_MAX = congruence.checkStrictlyPositiveNumber(
            self.PHOT_ENERGY_MAX, "Max Photon Energy")
        congruence.checkLessThan(self.PHOT_ENERGY_MIN, self.PHOT_ENERGY_MAX,
                                 "Min Photon Energy", "Max Photon Energy")
        self.NPOINTS = congruence.checkStrictlyPositiveNumber(
            self.NPOINTS, "Number of Energy Points")
        self.CURRENT = congruence.checkStrictlyPositiveNumber(
            self.CURRENT, "Electron Beam Current")

        if self.FIELD == 0:
            self.ULAMBDA = congruence.checkStrictlyPositiveNumber(
                self.ULAMBDA, "Wiggler period")
            self.K = congruence.checkStrictlyPositiveNumber(self.K, "K")
            self.NTRAJPOINTS = congruence.checkStrictlyPositiveNumber(
                self.NTRAJPOINTS, "Number of traj points per period")
        elif self.FIELD == 1:
            self.ULAMBDA = congruence.checkStrictlyPositiveNumber(
                self.ULAMBDA, "Wiggler period")
            self.NTRAJPOINTS = congruence.checkStrictlyPositiveNumber(
                self.NTRAJPOINTS, "Number of traj points per period")
            congruence.checkFile(self.FILE)
        elif self.FIELD == 2:
            congruence.checkFile(self.FILE)

    def do_xoppy_calculation(self):
        return xoppy_calc_xwiggler(FIELD=self.FIELD,
                                   NPERIODS=self.NPERIODS,
                                   ULAMBDA=self.ULAMBDA,
                                   K=self.K,
                                   ENERGY=self.ENERGY,
                                   PHOT_ENERGY_MIN=self.PHOT_ENERGY_MIN,
                                   PHOT_ENERGY_MAX=self.PHOT_ENERGY_MAX,
                                   NPOINTS=self.NPOINTS,
                                   NTRAJPOINTS=self.NTRAJPOINTS,
                                   CURRENT=self.CURRENT,
                                   FILE=self.FILE)

    def extract_data_from_xoppy_output(self, calculation_output):
        e, f, sp = calculation_output

        data = numpy.zeros((len(e), 3))
        data[:, 0] = numpy.array(e)
        data[:, 1] = numpy.array(f)
        data[:, 2] = numpy.array(sp)

        calculated_data = DataExchangeObject(
            "XOPPY", self.get_data_exchange_widget_name())
        calculated_data.add_content("xoppy_data", data)

        return calculated_data

    def get_data_exchange_widget_name(self):
        return "XWIGGLER"

    def getTitles(self):
        return ['Flux', 'Spectral Power']

    def getXTitles(self):
        return ["Energy [eV]", "Energy [eV]"]

    def getYTitles(self):
        return ["Flux [Phot/sec/0.1%bw]", "Spectral Power [W/eV]"]

    def getLogPlot(self):
        return [(True, True), (True, True)]

    def getVariablesToPlot(self):
        return [(0, 1), (0, 2)]
Example #19
0
class OWLDAvis(OWWidget):
    name = "LDAvis"
    description = "Interactive exploration of LDA topics."
    priority = 410
    icon = "icons/LDAvis.svg"

    selected_topic = Setting(0, schema_only=True)
    relevance = Setting(0.5)
    visual_settings = Setting({}, schema_only=True)

    graph = SettingProvider(BarPlotGraph)
    graph_name = "graph.plotItem"

    class Inputs:
        topics = Input("Topics", Topics)

    class Error(OWWidget.Error):
        # Relevant Terms cannot work with LSI or HDP, because it expects
        # topic-term probabilities.
        wrong_model = Msg("Relevant Terms only accepts output from LDA.")

    def __init__(self):
        OWWidget.__init__(self)
        self.data = None
        self.topic_list = []
        self.term_topic_matrix = None
        self.term_frequency = None
        self.num_tokens = None
        # should be used later for bar chart
        self.graph: Optional[BarPlotGraph] = None
        self._create_layout()

        VisualSettingsDialog(self,
                             self.graph.parameter_setter.initial_settings)

    def _create_layout(self):
        self._add_graph()
        box = gui.widgetBox(self.controlArea, "Relevance")
        self.rel_slider = gui.hSlider(
            box,
            self,
            "relevance",
            minValue=0,
            maxValue=1,
            step=0.1,
            intOnly=False,
            labelFormat="%.1f",
            callback_finished=self.on_params_change,
            createLabel=True,
        )

        self.topic_box = gui.listBox(
            self.controlArea,
            self,
            "selected_topic",
            "topic_list",
            box="Topics",
            callback=self.on_params_change,
        )

    def _add_graph(self):
        self.graph = BarPlotGraph(self)
        self.mainArea.layout().addWidget(self.graph)

    def compute_relevance(self, topic: np.ndarray) -> np.ndarray:
        """
        Relevance is defined as lambda*log(topic_probability) + (
        1-lambda)*log(topic_probability/marginal_probability).
        https://nlp.stanford.edu/events/illvi2014/papers/sievert-illvi2014.pdf
        """
        nonzero = (topic > 0) & (self.term_frequency > 0)
        tp, mp = topic[nonzero], self.term_frequency[nonzero]
        adj_prob = np.zeros(topic.shape)
        rel = self.relevance
        adj_prob[nonzero] = rel * np.log(tp) + (1 - rel) * np.log(tp / mp)
        return adj_prob

    @staticmethod
    def compute_distributions(data: Topics) -> np.ndarray:
        """
        Compute how likely is the term in each topic
        Term-topic column is multiplied by marginal topic probability
        """
        topic_frequency = data.get_column_view("Marginal Topic Probability")[0]
        return data.X * topic_frequency[:, None].astype(float)

    def on_params_change(self):
        if self.data is None:
            return
        topic = self.data.X[:, self.selected_topic]
        adj_prob = self.compute_relevance(topic)

        idx = np.argsort(adj_prob, axis=None)[::-1][:N_BEST_PLOTTED]

        words = self.data.metas[:, 0][idx]
        term_topic_freq = self.term_topic_matrix[self.selected_topic].T[idx]
        marg_prob = self.term_frequency[idx]

        # convert to absolute frequencies
        term_topic_freq = term_topic_freq * self.num_tokens
        marg_prob = marg_prob * self.num_tokens

        self.graph.update_graph(words, term_topic_freq, marg_prob)

    @Inputs.topics
    def set_data(self, data: Optional[Topics]):
        prev_topic = self.selected_topic
        self.clear()
        if data is None:
            return
        if data.attributes.get("Model", "") != "Latent Dirichlet Allocation":
            self.Error.wrong_model()
            return

        self.data = Table.transpose(data, "Topics", "Words")
        self.topic_list = [var.name for var in self.data.domain.attributes]
        self.num_tokens = data.attributes.get("Number of tokens", "")
        self.term_topic_matrix = self.compute_distributions(data)
        self.term_frequency = np.sum(self.term_topic_matrix, axis=0)

        self.selected_topic = prev_topic if prev_topic < len(
            self.topic_list) else 0
        self.on_params_change()

    def set_visual_settings(self, key: KeyType, value: ValueType):
        self.graph.parameter_setter.set_parameter(key, value)
        self.visual_settings[key] = value

    def clear(self):
        self.Error.clear()
        self.graph.clear_all()
        self.data = None
        self.topic_list = []
        self.term_topic_matrix = None
        self.term_frequency = None
        self.num_tokens = None

    def send_report(self):
        self.report_items((
            ("Relevance", self.relevance),
            ("Shown topic", self.topic_list[self.selected_topic]),
        ))
        self.report_plot()
Example #20
0
class OWModesFileWriter(widget.OWWidget):
    name = "Modes to File"
    description = "Utility: COMSYL Modes File Writer"
    icon = "icons/file_writer.png"
    maintainer = "Manuel Sanchez del Rio"
    maintainer_email = "srio(@at@)esrf.eu"
    priority = 61
    category = "Utility"
    keywords = ["COMSYL", "coherent modes"]

    want_main_area = 0

    file_name = Setting("tmp.h5")
    index_format = Setting("%04d")
    is_automatic_run = Setting(1)
    TYPE_OF_OUTPUT = Setting(
        1
    )  # 'COMSYL hdf5 with multi-mode','WOFRY hdf5 with multi-mode','WOFRY multiple files'
    ALL_MODES = Setting(0)
    MODE_TO = Setting(10)

    inputs = [("COMSYL modes", CompactAFReader, "setCompactAFReader")]

    af = None

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

        self.runaction = widget.OWAction("Write HDF5 File", self)
        self.runaction.triggered.connect(self.write_file)
        self.addAction(self.runaction)

        self.setFixedWidth(590)
        self.setFixedHeight(500)

        left_box_1 = oasysgui.widgetBox(self.controlArea,
                                        "HDF5 File Selection",
                                        addSpace=True,
                                        orientation="vertical",
                                        width=570,
                                        height=400)

        gui.checkBox(left_box_1, self, 'is_automatic_run',
                     'Automatic Execution')

        gui.separator(left_box_1, height=10)

        figure_box = oasysgui.widgetBox(left_box_1,
                                        "",
                                        addSpace=True,
                                        orientation="horizontal",
                                        width=550,
                                        height=50)

        #
        #
        #
        self.le_file_name = oasysgui.lineEdit(figure_box,
                                              self,
                                              "file_name",
                                              "Output File Name",
                                              labelWidth=120,
                                              valueType=str,
                                              orientation="horizontal")
        self.le_file_name.setFixedWidth(330)

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

        gui.separator(left_box_1, height=10)

        #
        #
        #

        gui.comboBox(
            left_box_1,
            self,
            "TYPE_OF_OUTPUT",
            label=" Type of output file",
            labelWidth=260,
            items=[
                'COMSYL hdf5 with multi-mode', 'WOFRY hdf5 with multi-mode',
                'WOFRY multiple files'
            ],
            #callback=self.set_Propagator,
            sendSelectedValue=False,
            orientation="horizontal")

        self.le_index_format = oasysgui.lineEdit(
            left_box_1,
            self,
            "index_format",
            "index format [for individual files]",
            labelWidth=200,
            valueType=str,
            orientation="horizontal")
        gui.separator(left_box_1, height=10)

        #
        #
        #
        gui.comboBox(
            left_box_1,
            self,
            "ALL_MODES",
            label=" Modes to write",
            labelWidth=260,
            items=['Selected modes', 'All modes'],
            #callback=self.set_Propagator,
            sendSelectedValue=False,
            orientation="horizontal")

        oasysgui.lineEdit(left_box_1,
                          self,
                          "MODE_TO",
                          "To mode index:",
                          labelWidth=200,
                          valueType=int,
                          orientation="horizontal")

        gui.separator(left_box_1, height=10)
        #
        #
        #
        button = gui.button(self.controlArea,
                            self,
                            "Write File",
                            callback=self.write_file)
        button.setFixedHeight(45)
        self.le_index_format.setFixedWidth(330)

        gui.rubber(self.controlArea)

    def selectFile(self):
        self.le_file_name.setText(
            oasysgui.selectFileFromDialog(self, self.file_name,
                                          "Open HDF5 File"))

    def setCompactAFReader(self, data):
        if not data is None:
            self.af = data

            if self.is_automatic_run:
                self.write_file()

    def write_file(self):
        self.setStatusMessage("")

        try:
            if not self.af is None:
                congruence.checkDir(self.file_name)

                if self.TYPE_OF_OUTPUT == 0:  # ['COMSYL hdf5 with multi-mode','WOFRY hdf5 with multi-mode','WOFRY multiple files'
                    if self.ALL_MODES:
                        self.af.write_h5(self.file_name,
                                         maximum_number_of_modes=None)
                    else:
                        self.af.write_h5(self.file_name,
                                         maximum_number_of_modes=self.MODE_TO)
                        path, file_name = os.path.split(self.file_name)
                        self.setStatusMessage("File Out: " + file_name)
                else:  # WOFRY
                    if self.ALL_MODES == 0 and (self.MODE_TO <
                                                self.af.number_of_modes()):
                        nmax = self.MODE_TO
                    else:
                        nmax = self.af.number_of_modes()

                    for i in range(nmax + 1):
                        eigenvalue = numpy.real(self.af.eigenvalue(i), )
                        eigenfunction = self.af.mode(i)
                        w = GenericWavefront2D.initialize_wavefront_from_arrays(
                            self.af.x_coordinates(), self.af.y_coordinates(),
                            eigenfunction * numpy.sqrt(eigenvalue))
                        w.set_photon_energy(self.af.photon_energy())

                        if self.TYPE_OF_OUTPUT == 1:  #
                            file_name = self.file_name
                            subgroupname = "mode" + self.index_format % (i)
                            overwrite = False
                        elif self.TYPE_OF_OUTPUT == 2:
                            subgroupname = "mode" + self.index_format % (i)
                            file_name = self.file_name.split(".")[0] + "_" + (
                                self.index_format % i) + ".h5"
                            overwrite = True

                        if i == 0:
                            w.save_h5_file(file_name,
                                           subgroupname=subgroupname,
                                           intensity=True,
                                           phase=True,
                                           overwrite=True)
                        else:
                            w.save_h5_file(file_name,
                                           subgroupname=subgroupname,
                                           intensity=True,
                                           phase=True,
                                           overwrite=overwrite)
                        path, file_name = os.path.split(file_name)
                        self.setStatusMessage("File Out: " + file_name)

                # path, file_name = os.path.split(self.file_name)

                # self.setStatusMessage("File Out: " + file_name)

            else:
                QMessageBox.critical(self, "Error", "COMSYL modes not present",
                                     QMessageBox.Ok)
        except Exception as exception:
            QMessageBox.critical(self, "Error", str(exception), QMessageBox.Ok)
Example #21
0
class OWElectronBeam(GenericElement):

    # name = "Electron Beam"

    syned_file_name = Setting("Select *.json file")

    source_name         = Setting("Undefined")

    electron_energy_in_GeV = Setting(2.0)
    electron_energy_spread = Setting(0.001)
    ring_current           = Setting(0.5)
    number_of_bunches      = Setting(400)

    moment_xx           = Setting(0.0)
    moment_xxp          = Setting(0.0)
    moment_xpxp         = Setting(0.0)
    moment_yy           = Setting(0.0)
    moment_yyp          = Setting(0.0)
    moment_ypyp         = Setting(0.0)

    electron_beam_size_h       = Setting(0.0)
    electron_beam_divergence_h = Setting(0.0)
    electron_beam_size_v       = Setting(0.0)
    electron_beam_divergence_v = Setting(0.0)

    electron_beam_emittance_h = Setting(0.0)
    electron_beam_emittance_v = Setting(0.0)
    electron_beam_beta_h = Setting(0.0)
    electron_beam_beta_v = Setting(0.0)
    electron_beam_alpha_h = Setting(0.0)
    electron_beam_alpha_v = Setting(0.0)
    electron_beam_eta_h = Setting(0.0)
    electron_beam_eta_v = Setting(0.0)
    electron_beam_etap_h = Setting(0.0)
    electron_beam_etap_v = Setting(0.0)


    type_of_properties = Setting(0)


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

        self.runaction = widget.OWAction("Run Shadow4/Source", self)
        self.runaction.triggered.connect(self.run_shadow4)
        self.addAction(self.runaction)

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

        button = gui.button(button_box, self, "Run shadow4/source", callback=self.run_shadow4)
        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 = gui.button(button_box, self, "Reset Fields", callback=self.callResetSettings)
        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(150)


        self.tabs_control_area = oasysgui.tabWidget(self.controlArea)
        self.tabs_control_area.setFixedHeight(self.TABS_AREA_HEIGHT)
        self.tabs_control_area.setFixedWidth(self.CONTROL_AREA_WIDTH-5)

        self.tab_electron_beam = oasysgui.createTabPage(self.tabs_control_area, "Electron Beam Setting")



        oasysgui.lineEdit(self.tab_electron_beam, self, "source_name", "Electron Beam Name", labelWidth=260, valueType=str, orientation="horizontal")

        self.electron_beam_box = oasysgui.widgetBox(self.tab_electron_beam, "Electron Beam/Machine Parameters", addSpace=False, orientation="vertical")

        oasysgui.lineEdit(self.electron_beam_box, self, "electron_energy_in_GeV", "Energy [GeV]", labelWidth=260, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.electron_beam_box, self, "electron_energy_spread", "Energy Spread", labelWidth=260, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.electron_beam_box, self, "ring_current", "Ring Current [A]", labelWidth=260, valueType=float, orientation="horizontal")

        gui.comboBox(self.electron_beam_box, self, "type_of_properties", label="Electron Beam Properties", labelWidth=350,
                     items=["From 2nd Moments", "From Size/Divergence", "From Twiss parameters","Zero emittance"],
                     callback=self.set_TypeOfProperties,
                     sendSelectedValue=False, orientation="horizontal")

        self.left_box_2_1 = oasysgui.widgetBox(self.electron_beam_box, "", addSpace=False, orientation="vertical", height=150)

        oasysgui.lineEdit(self.left_box_2_1, self, "moment_xx",   "<x x>   [m^2]", labelWidth=260, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_1, self, "moment_xxp",  "<x x'>  [m.rad]", labelWidth=260, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_1, self, "moment_xpxp", "<x' x'> [rad^2]", labelWidth=260, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_1, self, "moment_yy",   "<y y>   [m^2]", labelWidth=260, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_1, self, "moment_yyp",  "<y y'>  [m.rad]", labelWidth=260, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_1, self, "moment_ypyp", "<y' y'> [rad^2]", labelWidth=260, valueType=float, orientation="horizontal")


        self.left_box_2_2 = oasysgui.widgetBox(self.electron_beam_box, "", addSpace=False, orientation="vertical", height=150)

        oasysgui.lineEdit(self.left_box_2_2, self, "electron_beam_size_h",       "Horizontal Beam Size \u03c3x [m]", labelWidth=260, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_2, self, "electron_beam_size_v",       "Vertical Beam Size \u03c3y [m]",  labelWidth=260, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_2, self, "electron_beam_divergence_h", "Horizontal Beam Divergence \u03c3'x [rad]", labelWidth=260, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_2, self, "electron_beam_divergence_v", "Vertical Beam Divergence \u03c3'y [rad]", labelWidth=260, valueType=float, orientation="horizontal")

        self.left_box_2_3 = oasysgui.widgetBox(self.electron_beam_box, "", addSpace=False, orientation="horizontal",height=150)
        self.left_box_2_3_l = oasysgui.widgetBox(self.left_box_2_3, "", addSpace=False, orientation="vertical")
        self.left_box_2_3_r = oasysgui.widgetBox(self.left_box_2_3, "", addSpace=False, orientation="vertical")
        oasysgui.lineEdit(self.left_box_2_3_l, self, "electron_beam_emittance_h", "\u03B5x [m.rad]",labelWidth=75, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_3_l, self, "electron_beam_alpha_h",     "\u03B1x",        labelWidth=75, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_3_l, self, "electron_beam_beta_h",      "\u03B2x [m]",    labelWidth=75, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_3_l, self, "electron_beam_eta_h",       "\u03B7x",        labelWidth=75, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_3_l, self, "electron_beam_etap_h",      "\u03B7'x",       labelWidth=75, valueType=float, orientation="horizontal")


        oasysgui.lineEdit(self.left_box_2_3_r, self, "electron_beam_emittance_v", "\u03B5y [m.rad]",labelWidth=75, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_3_r, self, "electron_beam_alpha_v",     "\u03B1y",        labelWidth=75,valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_3_r, self, "electron_beam_beta_v",      "\u03B2y [m]",    labelWidth=75, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_3_r, self, "electron_beam_eta_v",       "\u03B7y",        labelWidth=75, valueType=float, orientation="horizontal")
        oasysgui.lineEdit(self.left_box_2_3_r, self, "electron_beam_etap_v",      "\u03B7'y",       labelWidth=75, valueType=float, orientation="horizontal")

        self.set_TypeOfProperties()

        gui.rubber(self.controlArea)


    def set_TypeOfProperties(self):
        self.left_box_2_1.setVisible(self.type_of_properties == 0)
        self.left_box_2_2.setVisible(self.type_of_properties == 1)
        self.left_box_2_3.setVisible(self.type_of_properties == 2)


    def check_data(self):
        congruence.checkStrictlyPositiveNumber(self.electron_energy_in_GeV , "Energy")
        congruence.checkStrictlyPositiveNumber(self.electron_energy_spread, "Energy Spread")
        congruence.checkStrictlyPositiveNumber(self.ring_current, "Ring Current")

        if self.type_of_properties == 0:
            congruence.checkPositiveNumber(self.moment_xx   , "Moment xx")
            congruence.checkPositiveNumber(self.moment_xpxp , "Moment xpxp")
            congruence.checkPositiveNumber(self.moment_yy   , "Moment yy")
            congruence.checkPositiveNumber(self.moment_ypyp , "Moment ypyp")
        elif self.type_of_properties == 1:
            congruence.checkPositiveNumber(self.electron_beam_size_h       , "Horizontal Beam Size")
            congruence.checkPositiveNumber(self.electron_beam_divergence_h , "Vertical Beam Size")
            congruence.checkPositiveNumber(self.electron_beam_size_v       , "Horizontal Beam Divergence")
            congruence.checkPositiveNumber(self.electron_beam_divergence_v , "Vertical Beam Divergence")
        elif self.type_of_properties == 2:
            congruence.checkPositiveNumber(self.electron_beam_emittance_h, "Horizontal Beam Emittance")
            congruence.checkPositiveNumber(self.electron_beam_emittance_v, "Vertical Beam Emittance")
            congruence.checkNumber(self.electron_beam_alpha_h, "Horizontal Beam Alpha")
            congruence.checkNumber(self.electron_beam_alpha_v, "Vertical Beam Alpha")
            congruence.checkNumber(self.electron_beam_beta_h, "Horizontal Beam Beta")
            congruence.checkNumber(self.electron_beam_beta_v, "Vertical Beam Beta")
            congruence.checkNumber(self.electron_beam_eta_h, "Horizontal Beam Dispersion Eta")
            congruence.checkNumber(self.electron_beam_eta_v, "Vertical Beam Dispersion Eta")
            congruence.checkNumber(self.electron_beam_etap_h, "Horizontal Beam Dispersion Eta'")
            congruence.checkNumber(self.electron_beam_etap_v, "Vertical Beam Dispersion Eta'")

        self.check_magnetic_structure()


    def run_shadow4(self):
        raise Exception("To be defined in the superclass")
        # try:
        #     self.check_data()
        #
        #     self.send("SynedData", Beamline(light_source=self.get_syned_light_source()))
        # except Exception as e:
        #     QMessageBox.critical(self, "Error", str(e.args[0]), QMessageBox.Ok)
        #
        #     self.setStatusMessage("")
        #     self.progressBarFinished()


    def get_syned_electron_beam(self):
        electron_beam = ElectronBeam(energy_in_GeV=self.electron_energy_in_GeV,
                                     energy_spread=self.electron_energy_spread,
                                     current=self.ring_current,
                                     number_of_bunches=self.number_of_bunches)

        recalculate_fields = False

        if self.type_of_properties == 0:
            electron_beam.set_moments_horizontal(self.moment_xx,self.moment_xxp,self.moment_xpxp)
            electron_beam.set_moments_vertical(self.moment_yy, self.moment_yyp, self.moment_ypyp)

            if recalculate_fields:

                x, xp, y, yp = electron_beam.get_sigmas_all()

                self.electron_beam_size_h = x
                self.electron_beam_size_v = y
                self.electron_beam_divergence_h = xp
                self.electron_beam_divergence_v = yp

                twiss_all = electron_beam.get_twiss_no_dispersion_all()
                self.electron_beam_emittance_h = twiss_all[0]
                self.electron_beam_alpha_h     = twiss_all[1]
                self.electron_beam_beta_h      = twiss_all[2]
                self.electron_beam_eta_h       = 0.0
                self.electron_beam_etap_h      = 0.0
                self.electron_beam_emittance_v = twiss_all[3]
                self.electron_beam_alpha_v     = twiss_all[4]
                self.electron_beam_beta_v      = twiss_all[5]
                self.electron_beam_eta_v       = 0.0
                self.electron_beam_etap_v      = 0.0


        elif self.type_of_properties == 1:
            electron_beam.set_sigmas_all(sigma_x=self.electron_beam_size_h,
                                         sigma_y=self.electron_beam_size_v,
                                         sigma_xp=self.electron_beam_divergence_h,
                                         sigma_yp=self.electron_beam_divergence_v)

            if recalculate_fields:
                moments_all = electron_beam.get_moments_all()

                self.moment_xx   = moments_all[0]
                self.moment_xxp  = moments_all[1]
                self.moment_xpxp = moments_all[2]
                self.moment_yy   = moments_all[3]
                self.moment_yy   = moments_all[4]
                self.moment_ypyp = moments_all[5]

                twiss_all = electron_beam.get_twiss_no_dispersion_all()
                self.electron_beam_emittance_h = twiss_all[0]
                self.electron_beam_alpha_h     = twiss_all[1]
                self.electron_beam_beta_h      = twiss_all[2]
                self.electron_beam_eta_h       = 0.0
                self.electron_beam_etap_h      = 0.0
                self.electron_beam_emittance_v = twiss_all[3]
                self.electron_beam_alpha_v     = twiss_all[4]
                self.electron_beam_beta_v      = twiss_all[5]
                self.electron_beam_eta_v       = 0.0
                self.electron_beam_etap_v      = 0.0

        elif self.type_of_properties == 2:
            electron_beam.set_twiss_horizontal(self.electron_beam_emittance_h,
                                             self.electron_beam_alpha_h,
                                             self.electron_beam_beta_h,
                                             self.electron_beam_eta_h,
                                             self.electron_beam_etap_h)
            electron_beam.set_twiss_vertical(self.electron_beam_emittance_v,
                                             self.electron_beam_alpha_v,
                                             self.electron_beam_beta_v,
                                             self.electron_beam_eta_v,
                                             self.electron_beam_etap_v)

            if recalculate_fields:
                x, xp, y, yp = electron_beam.get_sigmas_all()

                self.electron_beam_size_h = x
                self.electron_beam_size_v = y
                self.electron_beam_divergence_h = xp
                self.electron_beam_divergence_v = yp

                moments_all = electron_beam.get_moments_all()

                self.moment_xx   = moments_all[0]
                self.moment_xxp  = moments_all[1]
                self.moment_xpxp = moments_all[2]
                self.moment_yy   = moments_all[3]
                self.moment_yy   = moments_all[4]
                self.moment_ypyp = moments_all[5]

        elif self.type_of_properties == 3:
            electron_beam.set_moments_all(0,0,0,0,0,0)


        return electron_beam

    # def check_magnetic_structure(self):
    #     raise NotImplementedError("Shoudl be implemented in subclasses")
    #
    # def get_magnetic_structure(self):
    #     raise NotImplementedError("Shoudl be implemented in subclasses")
    #
    # def callResetSettings(self):
    #     if ConfirmDialog.confirmed(parent=self, message="Confirm Reset of the Fields?"):
    #         try:
    #             self.resetSettings()
    #         except:
    #             pass
    #
    # def select_syned_file(self):
    #     self.le_syned_file_name.setText(oasysgui.selectFileFromDialog(self, self.syned_file_name, "Open Syned File"))
    #
    # def read_syned_file(self):
    #     try:
    #         congruence.checkEmptyString(self.syned_file_name, "Syned File Name/Url")
    #
    #         if len(self.syned_file_name) > 7 and self.syned_file_name[:7] == "http://":
    #             is_remote = True
    #         else:
    #             congruence.checkFile(self.syned_file_name)
    #             is_remote = False
    #
    #         try:
    #             if is_remote:
    #                 content = load_from_json_url(self.syned_file_name)
    #             else:
    #                 content = load_from_json_file(self.syned_file_name)
    #
    #             if isinstance(content, LightSource):
    #                 self.populate_fields(content)
    #             elif isinstance(content, Beamline) and not content._light_source is None:
    #                 self.populate_fields(content._light_source)
    #             else:
    #                 raise Exception("json file must contain a SYNED LightSource")
    #         except Exception as e:
    #             raise Exception("Error reading SYNED LightSource from file: " + str(e))
    #     except Exception as e:
    #         QMessageBox.critical(self, "Error", str(e.args[0]), QMessageBox.Ok)


    def populate_fields_from_syned_electron_beam(self, electron_beam):

        self.check_magnetic_structure_instance(magnetic_structure)

        self.source_name = electron_beam._name

        self.electron_energy_in_GeV = electron_beam._energy_in_GeV
        self.electron_energy_spread = electron_beam._energy_spread
        self.ring_current = electron_beam._current
        self.number_of_bunches = electron_beam._number_of_bunches

        self.type_of_properties = 0

        self.moment_xx   = electron_beam._moment_xx
        self.moment_xxp  = electron_beam._moment_xxp
        self.moment_xpxp = electron_beam._moment_xpxp
        self.moment_yy   = electron_beam._moment_yy
        self.moment_yyp  = electron_beam._moment_yyp
        self.moment_ypyp = electron_beam._moment_ypyp

        x, xp, y, yp = electron_beam.get_sigmas_all()

        self.electron_beam_size_h = x
        self.electron_beam_size_v = y
        self.electron_beam_divergence_h = xp
        self.electron_beam_divergence_v = yp

        self.set_TypeOfProperties()
Example #22
0
class CollimatingPolycapillary(ow_generic_element.GenericElement):
    name = "Collimating Polycapillary Lens"
    description = "User Defined: Collimating Polycapillary Lens"
    icon = "icons/collimating_polycapillary.png"
    maintainer = "Luca Rebuffi"
    maintainer_email = "luca.rebuffi(@at@)elettra.eu"
    priority = 6
    category = "User Defined"
    keywords = ["data", "file", "load", "read"]

    inputs = [("Input Beam", ShadowBeam, "setBeam")]

    outputs = [{
        "name": "Beam",
        "type": ShadowBeam,
        "doc": "Shadow Beam",
        "id": "beam"
    }, {
        "name": "Trigger",
        "type": ShadowTriggerIn,
        "doc": "Feedback signal to start a new beam simulation",
        "id": "Trigger"
    }]

    input_beam = None

    NONE_SPECIFIED = "NONE SPECIFIED"

    CONTROL_AREA_HEIGHT = 440
    CONTROL_AREA_WIDTH = 470

    input_diameter = Setting(0.5)
    output_diameter = Setting(1.5)

    angular_acceptance = Setting(20.0)
    residual_divergence = Setting(0.001)

    lens_length = Setting(10.0)

    source_plane_distance = Setting(0.0)
    image_plane_distance = Setting(0)

    transmittance = Setting(40.0)

    file_to_write_out = Setting(3)

    want_main_area = 1

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

        self.controlArea.setFixedWidth(self.CONTROL_AREA_WIDTH)

        tabs_setting = gui.tabWidget(self.controlArea)

        tab_bas = oasysgui.createTabPage(tabs_setting, "Basic Setting")
        tab_adv = oasysgui.createTabPage(tabs_setting, "Advanced Setting")

        lens_box = oasysgui.widgetBox(tab_bas,
                                      "Input Parameters",
                                      addSpace=False,
                                      orientation="vertical",
                                      width=450,
                                      height=600)

        oasysgui.lineEdit(lens_box,
                          self,
                          "source_plane_distance",
                          "Source Plane Distance [cm]",
                          labelWidth=350,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(lens_box,
                          self,
                          "image_plane_distance",
                          "Image Plane Distance [cm]",
                          labelWidth=350,
                          valueType=float,
                          orientation="horizontal")

        gui.separator(lens_box)

        oasysgui.lineEdit(lens_box,
                          self,
                          "input_diameter",
                          "Input Diameter [cm]",
                          labelWidth=350,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(lens_box,
                          self,
                          "angular_acceptance",
                          "Angular Acceptance [deg]",
                          labelWidth=350,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(lens_box,
                          self,
                          "output_diameter",
                          "Output Diameter [cm]",
                          labelWidth=350,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(lens_box,
                          self,
                          "residual_divergence",
                          "Residual Output Divergence [rad]",
                          labelWidth=350,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(lens_box,
                          self,
                          "lens_length",
                          "Lens Total Length [cm]",
                          labelWidth=350,
                          valueType=float,
                          orientation="horizontal")

        gui.separator(lens_box)

        oasysgui.lineEdit(lens_box,
                          self,
                          "transmittance",
                          "Lens Transmittance [%]",
                          labelWidth=350,
                          valueType=float,
                          orientation="horizontal")

        gui.separator(self.controlArea, height=80)

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

        button = gui.button(button_box,
                            self,
                            "Run Shadow/trace",
                            callback=self.traceOpticalElement)
        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 = gui.button(button_box,
                            self,
                            "Reset Fields",
                            callback=self.callResetSettings)
        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(100)

    def callResetSettings(self):
        super().callResetSettings()
        self.setupUI()

    ############################################################
    #
    # GRAPHIC USER INTERFACE MANAGEMENT
    #
    ############################################################

    def get_slits_distance(self):
        return (0.5 *
                (self.output_diameter - self.input_diameter)) / numpy.tan(
                    numpy.radians(0.5 * self.angular_acceptance))

        ############################################################

    #
    # USER INPUT MANAGEMENT
    #
    ############################################################

    def adjust_divergence_and_intensity(self, beam_out):
        image_plane_distance = self.image_plane_distance + (
            self.lens_length - self.get_slits_distance())
        reduction_factor = numpy.sqrt(self.transmittance / 100)

        for index in range(len(beam_out.beam.rays)):
            if beam_out.beam.rays[index, 9] == 1:
                beam_out.beam.rays[
                    index, 6] = beam_out.beam.rays[index, 6] * reduction_factor
                beam_out.beam.rays[
                    index, 7] = beam_out.beam.rays[index, 7] * reduction_factor
                beam_out.beam.rays[
                    index, 8] = beam_out.beam.rays[index, 8] * reduction_factor
                beam_out.beam.rays[
                    index,
                    15] = beam_out.beam.rays[index, 15] * reduction_factor
                beam_out.beam.rays[
                    index,
                    16] = beam_out.beam.rays[index, 16] * reduction_factor
                beam_out.beam.rays[
                    index,
                    17] = beam_out.beam.rays[index, 17] * reduction_factor

                direction = [0.0, 1.0, 0.0]

                if self.residual_divergence > 0.0:
                    rotation_axis = [1.0, 0.0, 0.0]
                    rotation_angle = numpy.random.normal(
                        scale=self.residual_divergence)

                    # random rotation around x with a random gaussian angle residual divergence=sigma
                    direction = ShadowMath.vector_rotate(
                        rotation_axis, rotation_angle, direction)

                    rotation_axis = [0.0, 1.0, 0.0]
                    rotation_angle = 2 * numpy.pi * numpy.random.random()

                    # random rotation around y with a random angle from 0 to 2pi
                    direction = ShadowMath.vector_rotate(
                        rotation_axis, rotation_angle, direction)

                    E_s_modulus = ShadowMath.vector_modulus([
                        beam_out.beam.rays[index, 6],
                        beam_out.beam.rays[index, 7], beam_out.beam.rays[index,
                                                                         8]
                    ])
                    E_p_modulus = ShadowMath.vector_modulus([
                        beam_out.beam.rays[index,
                                           15], beam_out.beam.rays[index, 16],
                        beam_out.beam.rays[index, 17]
                    ])

                beam_out.beam.rays[index, 3] = direction[0]
                beam_out.beam.rays[index, 4] = direction[1]
                beam_out.beam.rays[index, 5] = direction[2]

        beam_out.beam.retrace(image_plane_distance)

        return beam_out

    def populateFields(self, shadow_oe):

        slits_distance = self.get_slits_distance()

        shadow_oe.oe.T_SOURCE = self.source_plane_distance
        shadow_oe.oe.T_IMAGE = slits_distance
        shadow_oe.oe.T_INCIDENCE = 0.0
        shadow_oe.oe.T_REFLECTION = 180.0
        shadow_oe.oe.ALPHA = 0.0

        n_screen = 2
        i_screen = numpy.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])  # after
        i_abs = numpy.zeros(10)  # not absorbing
        i_slit = numpy.array([1, 1, 0, 0, 0, 0, 0, 0, 0, 0])  # slit
        i_stop = numpy.zeros(10)  # aperture
        k_slit = numpy.array([1, 1, 0, 0, 0, 0, 0, 0, 0, 0])  # ellipse
        thick = numpy.zeros(10)
        file_abs = numpy.array(['', '', '', '', '', '', '', '', '', ''])
        rx_slit = numpy.zeros(10)
        rz_slit = numpy.zeros(10)
        sl_dis = numpy.zeros(10)
        file_src_ext = numpy.array(['', '', '', '', '', '', '', '', '', ''])
        cx_slit = numpy.zeros(10)
        cz_slit = numpy.zeros(10)

        sl_dis[0] = 0.0
        rx_slit[0] = self.input_diameter
        rz_slit[0] = self.input_diameter

        sl_dis[1] = slits_distance
        rx_slit[1] = self.output_diameter
        rz_slit[1] = self.output_diameter

        shadow_oe.oe.set_screens(n_screen, i_screen, i_abs, sl_dis, i_slit,
                                 i_stop, k_slit, thick, file_abs, rx_slit,
                                 rz_slit, cx_slit, cz_slit, file_src_ext)

    def doSpecificSetting(self, shadow_oe):
        pass

    def checkFields(self):
        congruence.checkPositiveNumber(self.source_plane_distance,
                                       "Distance from Source")
        congruence.checkPositiveNumber(self.image_plane_distance,
                                       "Image Plane Distance")
        congruence.checkStrictlyPositiveNumber(self.input_diameter,
                                               "Input Diameter")
        congruence.checkStrictlyPositiveAngle(self.angular_acceptance,
                                              "Angular Acceptance")
        congruence.checkStrictlyPositiveNumber(self.output_diameter,
                                               "Output Diameter")
        congruence.checkPositiveNumber(self.residual_divergence,
                                       "Residual Output Divergence")
        congruence.checkStrictlyPositiveNumber(self.lens_length,
                                               "Lens Total Length")

        if self.output_diameter <= self.input_diameter:
            raise Exception(
                "Output Diameter should be greater than Input diameter")

        slit_distance = self.get_slits_distance()

        if self.lens_length < slit_distance:
            raise Exception(
                "Lens total Length should be greater than or equal to " +
                str(slit_distance))

        congruence.checkStrictlyPositiveNumber(self.transmittance,
                                               "Lens Transmittance")

    def completeOperations(self, shadow_oe=None):
        self.setStatusMessage("Running SHADOW")

        if self.trace_shadow:
            grabber = TTYGrabber()
            grabber.start()

        self.progressBarSet(50)

        ###########################################
        # TODO: TO BE ADDED JUST IN CASE OF BROKEN
        #       ENVIRONMENT: MUST BE FOUND A PROPER WAY
        #       TO TEST SHADOW
        self.fixWeirdShadowBug()
        ###########################################

        beam_out = ShadowBeam.traceFromOE(self.input_beam, shadow_oe)

        self.adjust_divergence_and_intensity(beam_out)

        if self.trace_shadow:
            grabber.stop()

            for row in grabber.ttyData:
                self.writeStdOut(row)

        self.setStatusMessage("Plotting Results")

        self.plot_results(beam_out)

        self.setStatusMessage("")

        self.send("Beam", beam_out)
        self.send("Trigger", ShadowTriggerIn(new_beam=True))

    def traceOpticalElement(self):
        try:
            self.error(self.error_id)
            self.setStatusMessage("")
            self.progressBarInit()

            if ShadowCongruence.checkEmptyBeam(self.input_beam):
                if ShadowCongruence.checkGoodBeam(self.input_beam):
                    sys.stdout = EmittingStream(textWritten=self.writeStdOut)

                    self.checkFields()

                    shadow_oe = ShadowOpticalElement.create_screen_slit()

                    self.populateFields(shadow_oe)
                    self.doSpecificSetting(shadow_oe)

                    self.progressBarSet(10)

                    self.completeOperations(shadow_oe)
                else:
                    raise Exception("Input Beam with no good rays")
            else:
                raise Exception("Empty Input Beam")

        except Exception as exception:
            QtGui.QMessageBox.critical(self, "QMessageBox.critical()",
                                       str(exception), QtGui.QMessageBox.Ok)

            self.error_id = self.error_id + 1
            self.error(self.error_id, "Exception occurred: " + str(exception))

        self.progressBarFinished()

    def setBeam(self, beam):
        self.onReceivingInput()

        if ShadowCongruence.checkEmptyBeam(beam):
            self.input_beam = beam

            if self.is_automatic_run:
                self.traceOpticalElement()

    def setPreProcessorData(self, data):
        if data is not None:
            if data.prerefl_data_file != ShadowPreProcessorData.NONE:
                self.prerefl_file = data.prerefl_data_file

    def setupUI(self):
        self.set_surface_shape()
        self.set_diameter()
        self.set_cylindrical()
        self.set_ri_calculation_mode()
Example #23
0
class GenericElement(ow_automatic_element.AutomaticElement):

    IMAGE_WIDTH = 860
    IMAGE_HEIGHT = 545

    want_main_area=1
    view_type=Setting(2)

    plotted_beam=None
    footprint_beam=None

    def __init__(self, show_automatic_box=True):
        super().__init__(show_automatic_box)

        self.main_tabs = oasysgui.tabWidget(self.mainArea)
        plot_tab = oasysgui.createTabPage(self.main_tabs, "Plots")
        out_tab = oasysgui.createTabPage(self.main_tabs, "Output")

        view_box = oasysgui.widgetBox(plot_tab, "Plotting Style", addSpace=False, orientation="horizontal")
        view_box_1 = oasysgui.widgetBox(view_box, "", addSpace=False, orientation="vertical", width=350)

        self.view_type_combo = gui.comboBox(view_box_1, self, "view_type", label="Select level of Plotting",
                                            labelWidth=220,
                                            items=["Detailed Plot", "Preview", "None"],
                                            callback=self.set_PlotQuality, sendSelectedValue=False, orientation="horizontal")
        self.tab = []
        self.tabs = oasysgui.tabWidget(plot_tab)

        self.initializeTabs()

        self.enableFootprint(False)

        self.shadow_output = oasysgui.textArea(height=580, width=800)

        out_box = gui.widgetBox(out_tab, "System Output", addSpace=True, orientation="horizontal")
        out_box.layout().addWidget(self.shadow_output)

    def initializeTabs(self):
        current_tab = self.tabs.currentIndex()

        enabled = self.isFootprintEnabled()

        size = len(self.tab)
        indexes = range(0, size)
        for index in indexes:
            self.tabs.removeTab(size-1-index)

        titles = self.getTitles()
        self.plot_canvas = [None]*len(titles)
        self.tab = []

        for title in titles:
            self.tab.append(oasysgui.createTabPage(self.tabs, title))

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

        self.enableFootprint(enabled)

        self.tabs.setCurrentIndex(current_tab)

    def check_not_interactive_conditions(self, input_beam):
        not_interactive = False

        if not input_beam is None:
            if not input_beam.scanned_variable_data is None:
                not_interactive = input_beam.scanned_variable_data.has_additional_parameter("total_power")

        return not_interactive

    def sendEmptyBeam(self):
        empty_beam = self.input_beam.duplicate()
        empty_beam._beam.rays = numpy.array([])
        empty_beam._oe_number += 1

        self.send("Beam", empty_beam)
        self.send("Trigger", TriggerIn(new_object=True))

    def isFootprintEnabled(self):
        return self.tabs.count() == 6

    def enableFootprint(self, enabled=False):
        if enabled:
            if self.tabs.count() == 5:
                self.tab.append(gui.createTabPage(self.tabs, "Footprint"))
                self.plot_canvas.append(None)
        else:
            if self.tabs.count() == 6:
                self.tabs.removeTab(5)
                self.tab = [self.tab[0],
                            self.tab[1],
                            self.tab[2],
                            self.tab[3],
                            self.tab[4],]
                self.plot_canvas = [self.plot_canvas[0],
                                    self.plot_canvas[1],
                                    self.plot_canvas[2],
                                    self.plot_canvas[3],
                                    self.plot_canvas[4],]

    def set_PlotQuality(self):
        self.progressBarInit()

        if not self.plotted_beam is None:
            try:
                self.initializeTabs()

                self.plot_results(self.plotted_beam, progressBarValue=80)
            except Exception as exception:
                QtWidgets.QMessageBox.critical(self, "Error",
                                           str(exception),
                    QtWidgets.QMessageBox.Ok)

                if self.IS_DEVELOP: raise exception

        self.progressBarFinished()

    def plot_xy(self, beam_out, progressBarValue, var_x, var_y, plot_canvas_index, title, xtitle, ytitle, xum="", yum="", is_footprint=False):
        if self.plot_canvas[plot_canvas_index] is None:
            self.plot_canvas[plot_canvas_index] = ShadowPlot.DetailedPlotWidget()
            self.tab[plot_canvas_index].layout().addWidget(self.plot_canvas[plot_canvas_index])

        self.plot_canvas[plot_canvas_index].plot_xy(beam_out._beam, var_x, var_y, title, xtitle, ytitle, xum=xum, yum=yum, conv=self.workspace_units_to_cm, is_footprint=is_footprint, flux=beam_out.get_flux())

        self.progressBarSet(progressBarValue)

    def plot_xy_fast(self, beam_out, progressBarValue, var_x, var_y, plot_canvas_index, title, xtitle, ytitle, is_footprint=False):
        if self.plot_canvas[plot_canvas_index] is None:
            self.plot_canvas[plot_canvas_index] = oasysgui.plotWindow(roi=False, control=False, position=True)
            self.plot_canvas[plot_canvas_index].setDefaultPlotLines(False)
            self.plot_canvas[plot_canvas_index].setActiveCurveColor(color='blue')

            self.tab[plot_canvas_index].layout().addWidget(self.plot_canvas[plot_canvas_index])

        ShadowPlot.plotxy_preview(self.plot_canvas[plot_canvas_index], beam_out._beam, var_x, var_y, nolost=1, title=title, xtitle=xtitle, ytitle=ytitle, conv=self.workspace_units_to_cm, is_footprint=is_footprint)

        self.progressBarSet(progressBarValue)

    def plot_histo(self, beam_out, progressBarValue, var, plot_canvas_index, title, xtitle, ytitle, xum=""):
        if self.plot_canvas[plot_canvas_index] is None:
            self.plot_canvas[plot_canvas_index] = ShadowPlot.DetailedHistoWidget()
            self.tab[plot_canvas_index].layout().addWidget(self.plot_canvas[plot_canvas_index])

        self.plot_canvas[plot_canvas_index].plot_histo(beam_out._beam, var, 1, None, 23, title, xtitle, ytitle, xum=xum, conv=self.workspace_units_to_cm, flux=beam_out.get_flux())

        self.progressBarSet(progressBarValue)

    def plot_histo_fast(self, beam_out, progressBarValue, var, plot_canvas_index, title, xtitle, ytitle):
        if self.plot_canvas[plot_canvas_index] is None:
            self.plot_canvas[plot_canvas_index] = oasysgui.plotWindow(roi=False, control=False, position=True)
            self.plot_canvas[plot_canvas_index].setDefaultPlotLines(True)
            self.plot_canvas[plot_canvas_index].setActiveCurveColor(color='blue')

            self.tab[plot_canvas_index].layout().addWidget(self.plot_canvas[plot_canvas_index])

        ShadowPlot.plot_histo_preview(self.plot_canvas[plot_canvas_index], beam_out._beam, var, 1, 23, title, xtitle, ytitle, conv=self.workspace_units_to_cm)

        self.progressBarSet(progressBarValue)

    def plot_results(self, beam_out, footprint_beam=None, progressBarValue=80):
        if not self.view_type == 2:
            if ShadowCongruence.checkEmptyBeam(beam_out):
                if ShadowCongruence.checkGoodBeam(beam_out):
                    self.view_type_combo.setEnabled(False)

                    ShadowPlot.set_conversion_active(self.getConversionActive())

                    if self.isFootprintEnabled() and footprint_beam is None:
                            footprint_beam = ShadowBeam()
                            if beam_out._oe_number < 10:
                                footprint_beam.loadFromFile(file_name="mirr.0" + str(beam_out._oe_number))
                            else:
                                footprint_beam.loadFromFile(file_name="mirr." + str(beam_out._oe_number))

                    variables = self.getVariablestoPlot()
                    titles = self.getTitles()
                    xtitles = self.getXTitles()
                    ytitles = self.getYTitles()
                    xums = self.getXUM()
                    yums = self.getYUM()

                    try:
                        if self.view_type == 1:
                            self.plot_xy_fast(beam_out, progressBarValue + 4,  variables[0][0], variables[0][1], plot_canvas_index=0, title=titles[0], xtitle=xtitles[0], ytitle=ytitles[0])
                            self.plot_xy_fast(beam_out, progressBarValue + 8,  variables[1][0], variables[1][1], plot_canvas_index=1, title=titles[1], xtitle=xtitles[1], ytitle=ytitles[1])
                            self.plot_xy_fast(beam_out, progressBarValue + 12, variables[2][0], variables[2][1], plot_canvas_index=2, title=titles[2], xtitle=xtitles[2], ytitle=ytitles[2])
                            self.plot_xy_fast(beam_out, progressBarValue + 16, variables[3][0], variables[3][1], plot_canvas_index=3, title=titles[3], xtitle=xtitles[3], ytitle=ytitles[3])
                            self.plot_histo_fast(beam_out, progressBarValue + 20, variables[4],                  plot_canvas_index=4, title=titles[4], xtitle=xtitles[4], ytitle=ytitles[4])

                            if self.isFootprintEnabled():
                                self.plot_xy_fast(footprint_beam, progressBarValue + 20, 2, 1, plot_canvas_index=5, title="Footprint", xtitle="Y [" + self.workspace_units_label +"]", ytitle="X [" + self.workspace_units_label +"]", is_footprint=True)


                        elif self.view_type == 0:
                            self.plot_xy(beam_out, progressBarValue + 4,  variables[0][0], variables[0][1], plot_canvas_index=0, title=titles[0], xtitle=xtitles[0], ytitle=ytitles[0], xum=xums[0], yum=yums[0])
                            self.plot_xy(beam_out, progressBarValue + 8,  variables[1][0], variables[1][1], plot_canvas_index=1, title=titles[1], xtitle=xtitles[1], ytitle=ytitles[1], xum=xums[1], yum=yums[1])
                            self.plot_xy(beam_out, progressBarValue + 12, variables[2][0], variables[2][1], plot_canvas_index=2, title=titles[2], xtitle=xtitles[2], ytitle=ytitles[2], xum=xums[2], yum=yums[2])
                            self.plot_xy(beam_out, progressBarValue + 16, variables[3][0], variables[3][1], plot_canvas_index=3, title=titles[3], xtitle=xtitles[3], ytitle=ytitles[3], xum=xums[3], yum=yums[3])
                            self.plot_histo(beam_out, progressBarValue + 20, variables[4],                  plot_canvas_index=4, title=titles[4], xtitle=xtitles[4], ytitle=ytitles[4], xum=xums[4] )

                            if self.isFootprintEnabled():
                                self.plot_xy(footprint_beam, progressBarValue + 20, 2, 1, plot_canvas_index=5, title="Footprint", xtitle="Y [" + self.workspace_units_label +"]", ytitle="X [" + self.workspace_units_label +"]",
                                             xum=("Y [" + self.workspace_units_label +"]"), yum=("X [" + self.workspace_units_label +"]"), is_footprint=True)

                    except Exception as e:
                        self.view_type_combo.setEnabled(True)

                        raise Exception("Data not plottable: No good rays or bad content\nexception: " + str(e))

                    self.view_type_combo.setEnabled(True)
                else:
                    raise Exception("Beam with no good rays")
            else:
                raise Exception("Empty Beam")

        self.plotted_beam = beam_out

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

    def onReceivingInput(self):
        self.initializeTabs()

    def deserialize(self, shadow_file):
        pass

    def getVariablestoPlot(self):
        return [[1, 3], [4, 6], [1, 4], [3, 6], 11]

    def getTitles(self):
        return ["X,Z", "X',Z'", "X,X'", "Z,Z'", "Energy"]

    def getXTitles(self):
        return [r'X [$\mu$m]', "X' [$\mu$rad]", r'X [$\mu$m]', r'Z [$\mu$m]', "Energy [eV]"]

    def getYTitles(self):
        return [r'Z [$\mu$m]', "Z' [$\mu$rad]", "X' [$\mu$rad]", "Z' [$\mu$rad]", "Number of Rays"]

    def getXUM(self):
        return ["X [" + u"\u03BC" + "m]", "X' [" + u"\u03BC" + "rad]", "X [" + u"\u03BC" + "m]", "Z [" + u"\u03BC" + "m]", "[eV]"]

    def getYUM(self):
        return ["Z [" + u"\u03BC" + "m]", "Z' [" + u"\u03BC" + "rad]", "X' [" + u"\u03BC" + "rad]", "Z' [" + u"\u03BC" + "rad]", None]

    def getConversionActive(self):
        return True
Example #24
0
class OWxfh(widget.OWWidget):
    name = "xfh"
    id = "orange.widgets.dataxfh"
    description = "xoppy application to compute..."
    icon = "icons/xoppy_xfh.png"
    author = "create_widget.py"
    maintainer_email = "*****@*****.**"
    priority = 10
    category = ""
    keywords = ["xoppy", "xfh"]
    outputs = [{"name": "xoppy_data",
                "type": np.ndarray,
                "doc": ""},
               {"name": "xoppy_specfile",
                "type": str,
                "doc": ""}]

    #inputs = [{"name": "Name",
    #           "type": type,
    #           "handler": None,
    #           "doc": ""}]

    want_main_area = False

    FILEF0 = Setting(0)
    FILEF1F2 = Setting(0)
    FILECROSSSEC = Setting(0)
    ILATTICE = Setting(0)
    HMILLER = Setting(1)
    KMILLER = Setting(1)
    LMILLER = Setting(1)
    I_ABSORP = Setting(2)
    TEMPER = Setting("1.0")
    ENERGY = Setting(8000.0)
    ENERGY_END = Setting(18000.0)
    NPOINTS = Setting(20)


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

        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)
        self.process_showers()
        box = gui.widgetBox(self.controlArea, " ",orientation="vertical") 
        
        
        idx = -1 
        
        #widget index 0 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.comboBox(box1, self, "FILEF0",
                     label=self.unitLabels()[idx], addSpace=True,
                    items=['f0_xop.dat'],
                    valueType=int, orientation="horizontal")
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 1 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.comboBox(box1, self, "FILEF1F2",
                     label=self.unitLabels()[idx], addSpace=True,
                    items=['f1f2_Windt.dat', 'f1f2_EPDL97.dat'],
                    valueType=int, orientation="horizontal")
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 2 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.comboBox(box1, self, "FILECROSSSEC",
                     label=self.unitLabels()[idx], addSpace=True,
                    items=['CrossSec_XCOM.dat'],
                    valueType=int, orientation="horizontal")
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 3 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.comboBox(box1, self, "ILATTICE",
                     label=self.unitLabels()[idx], addSpace=True,
                    items=['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'],
                    valueType=int, orientation="horizontal")
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 4 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.lineEdit(box1, self, "HMILLER",
                     label=self.unitLabels()[idx], addSpace=True,
                    valueType=int, validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 5 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.lineEdit(box1, self, "KMILLER",
                     label=self.unitLabels()[idx], addSpace=True,
                    valueType=int, validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 6 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.lineEdit(box1, self, "LMILLER",
                     label=self.unitLabels()[idx], addSpace=True,
                    valueType=int, validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 7 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.comboBox(box1, self, "I_ABSORP",
                     label=self.unitLabels()[idx], addSpace=True,
                    items=['No', 'Yes (photoelectric)', 'Yes(ph.el+compton)', 'Yes(ph.el+compton+rayleigh)'],
                    valueType=int, orientation="horizontal")
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 8 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.lineEdit(box1, self, "TEMPER",
                     label=self.unitLabels()[idx], addSpace=True)
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 9 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.lineEdit(box1, self, "ENERGY",
                     label=self.unitLabels()[idx], addSpace=True,
                    valueType=float, validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 10 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.lineEdit(box1, self, "ENERGY_END",
                     label=self.unitLabels()[idx], addSpace=True,
                    valueType=float, validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1) 
        
        #widget index 11 
        idx += 1 
        box1 = gui.widgetBox(box) 
        gui.lineEdit(box1, self, "NPOINTS",
                     label=self.unitLabels()[idx], addSpace=True,
                    valueType=int, validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1) 

        gui.rubber(self.controlArea)

    def unitLabels(self):
         return ['DABAX f0 file:','DABAX f1f2 file:','DABAX CrossSec file:','Crystal:','h miller index','k miller index','l miller index','Include absorption:','Temperature factor [see help]:','From Energy [eV]','To energy [eV]','Number of points']


    def unitFlags(self):
         return ['True','True','True','True','True','True','True','True','True','True','True','True']


    #def unitNames(self):
    #     return ['FILEF0','FILEF1F2','FILECROSSSEC','ILATTICE','HMILLER','KMILLER','LMILLER','I_ABSORP','TEMPER','ENERGY','ENERGY_END','NPOINTS']


    def compute(self):
        fileName = xoppy_calc_xfh(FILEF0=self.FILEF0,FILEF1F2=self.FILEF1F2,FILECROSSSEC=self.FILECROSSSEC,ILATTICE=self.ILATTICE,HMILLER=self.HMILLER,KMILLER=self.KMILLER,LMILLER=self.LMILLER,I_ABSORP=self.I_ABSORP,TEMPER=self.TEMPER,ENERGY=self.ENERGY,ENERGY_END=self.ENERGY_END,NPOINTS=self.NPOINTS)
        #send specfile

        if fileName == None:
            print("Nothing to send")
        else:
            self.send("xoppy_specfile",fileName)
            sf = specfile.Specfile(fileName)
            if sf.scanno() == 1:
                #load spec file with one scan, # is comment
                print("Loading file:  ",fileName)
                out = np.loadtxt(fileName)
                print("data shape: ",out.shape)
                #get labels
                txt = open(fileName).readlines()
                tmp = [ line.find("#L") for line in txt]
                itmp = np.where(np.array(tmp) != (-1))
                labels = txt[itmp[0]].replace("#L ","").split("  ")
                print("data labels: ",labels)
                self.send("xoppy_data",out)
            else:
                print("File %s contains %d scans. Cannot send it as xoppy_table"%(fileName,sf.scanno()))

    def defaults(self):
         self.resetSettings()
         self.compute()
         return

    def help1(self):
        print("help pressed.")
        xoppy_doc('xfh')
Example #25
0
class OWmlayer(widget.OWWidget):
    name = "mlayer"
    id = "orange.widgets.datamlayer"
    description = "xoppy application to compute..."
    icon = "icons/xoppy_mlayer.png"
    author = "create_widget.py"
    maintainer_email = "*****@*****.**"
    priority = 10
    category = ""
    keywords = ["xoppy", "mlayer"]
    outputs = [{
        "name": "xoppy_data",
        "type": np.ndarray,
        "doc": ""
    }, {
        "name": "xoppy_specfile",
        "type": str,
        "doc": ""
    }]

    #inputs = [{"name": "Name",
    #           "type": type,
    #           "handler": None,
    #           "doc": ""}]

    want_main_area = False

    MODE = Setting(0)
    SCAN = Setting(0)
    F12_FLAG = Setting(0)
    SUBSTRATE = Setting("Si")
    ODD_MATERIAL = Setting("Si")
    EVEN_MATERIAL = Setting("W")
    ENERGY = Setting(8050.0)
    THETA = Setting(0.0)
    SCAN_STEP = Setting(0.009999999776483)
    NPOINTS = Setting(600)
    ODD_THICKNESS = Setting(25.0)
    EVEN_THICKNESS = Setting(25.0)
    NLAYERS = Setting(50)
    FILE = Setting("layers.dat")

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

        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)
        self.process_showers()
        box = gui.widgetBox(self.controlArea, " ", orientation="vertical")

        idx = -1

        #widget index 0
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "MODE",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     items=['Periodic Layers', 'Individual Layers'],
                     valueType=int,
                     orientation="horizontal")
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 1
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(box1,
                     self,
                     "SCAN",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     items=['Grazing Angle', 'Photon Energy'],
                     valueType=int,
                     orientation="horizontal")
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 2
        idx += 1
        box1 = gui.widgetBox(box)
        gui.comboBox(
            box1,
            self,
            "F12_FLAG",
            label=self.unitLabels()[idx],
            addSpace=True,
            items=['Create on the fly', 'Use existing file: mlayers.f12'],
            valueType=int,
            orientation="horizontal")
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 3
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "SUBSTRATE",
                     label=self.unitLabels()[idx],
                     addSpace=True)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 4
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "ODD_MATERIAL",
                     label=self.unitLabels()[idx],
                     addSpace=True)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 5
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "EVEN_MATERIAL",
                     label=self.unitLabels()[idx],
                     addSpace=True)
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 6
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "ENERGY",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 7
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "THETA",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 8
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "SCAN_STEP",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 9
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "NPOINTS",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=int,
                     validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 10
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "ODD_THICKNESS",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 11
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "EVEN_THICKNESS",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=float,
                     validator=QDoubleValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 12
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "NLAYERS",
                     label=self.unitLabels()[idx],
                     addSpace=True,
                     valueType=int,
                     validator=QIntValidator())
        self.show_at(self.unitFlags()[idx], box1)

        #widget index 13
        idx += 1
        box1 = gui.widgetBox(box)
        gui.lineEdit(box1,
                     self,
                     "FILE",
                     label=self.unitLabels()[idx],
                     addSpace=True)
        self.show_at(self.unitFlags()[idx], box1)

        gui.rubber(self.controlArea)

    def unitLabels(self):
        return [
            'Layer periodicity: ', 'Scanning variable: ',
            'Material parameters:', 'Substrate: ',
            'Odd layer material (closer to vacuum): ',
            'Even layer material (closer to substrate): ',
            'Photon energy [eV]:', 'Grazing angle [degrees]:',
            'Scanning variable step: ', 'Number of scanning points',
            'Thickness [A] for odd material:',
            'Thickness [A] for even material:', 'Number of layer pairs:',
            'File with layer thicknesses:'
        ]

    def unitFlags(self):
        return [
            'True', 'True', 'True', 'self.F12_FLAG  ==  0',
            'self.F12_FLAG  ==  0', 'self.F12_FLAG  ==  0', 'True', 'True',
            'True', 'True', 'self.MODE  ==  0  &  self.F12_FLAG  ==  0',
            'self.MODE  ==  0  &  self.F12_FLAG  ==  0',
            'self.MODE  ==  0  &  self.F12_FLAG  ==  0', 'self.MODE  ==  1'
        ]

    #def unitNames(self):
    #     return ['MODE','SCAN','F12_FLAG','SUBSTRATE','ODD_MATERIAL','EVEN_MATERIAL','ENERGY','THETA','SCAN_STEP','NPOINTS','ODD_THICKNESS','EVEN_THICKNESS','NLAYERS','FILE']

    def compute(self):
        fileName = xoppy_calc_mlayer(MODE=self.MODE,
                                     SCAN=self.SCAN,
                                     F12_FLAG=self.F12_FLAG,
                                     SUBSTRATE=self.SUBSTRATE,
                                     ODD_MATERIAL=self.ODD_MATERIAL,
                                     EVEN_MATERIAL=self.EVEN_MATERIAL,
                                     ENERGY=self.ENERGY,
                                     THETA=self.THETA,
                                     SCAN_STEP=self.SCAN_STEP,
                                     NPOINTS=self.NPOINTS,
                                     ODD_THICKNESS=self.ODD_THICKNESS,
                                     EVEN_THICKNESS=self.EVEN_THICKNESS,
                                     NLAYERS=self.NLAYERS,
                                     FILE=self.FILE)
        #send specfile

        if fileName == None:
            print("Nothing to send")
        else:
            self.send("xoppy_specfile", fileName)
            sf = specfile.Specfile(fileName)
            if sf.scanno() == 1:
                #load spec file with one scan, # is comment
                print("Loading file:  ", fileName)
                out = np.loadtxt(fileName)
                print("data shape: ", out.shape)
                #get labels
                txt = open(fileName).readlines()
                tmp = [line.find("#L") for line in txt]
                itmp = np.where(np.array(tmp) != (-1))
                labels = txt[itmp[0]].replace("#L ", "").split("  ")
                print("data labels: ", labels)
                self.send("xoppy_data", out)
            else:
                print(
                    "File %s contains %d scans. Cannot send it as xoppy_table"
                    % (fileName, sf.scanno()))

    def defaults(self):
        self.resetSettings()
        self.compute()
        return

    def help1(self):
        print("help pressed.")
        xoppy_doc('mlayer')
Example #26
0
class PowerLoopPoint(widget.OWWidget):

    name = "Power Density Loop Point"
    description = "Tools: LoopPoint"
    icon = "icons/cycle.png"
    maintainer = "Luca Rebuffi"
    maintainer_email = "lrebuffi(@at@)anl.gov"
    priority = 5
    category = "User Defined"
    keywords = ["data", "file", "load", "read"]

    inputs = WidgetDecorator.syned_input_data()
    inputs.append(("Trigger", TriggerIn, "passTrigger"))
    inputs.append(
        ("Energy Spectrum", DataExchangeObject, "acceptEnergySpectrum"))
    inputs.append(("Filters", DataExchangeObject, "acceptFilters"))

    outputs = [{
        "name": "Trigger",
        "type": TriggerOut,
        "doc": "Trigger",
        "id": "Trigger"
    }]
    want_main_area = 1

    current_new_object = 0
    number_of_new_objects = 0

    total_current_new_object = 0
    total_new_objects = Setting(0)

    run_loop = True
    suspend_loop = False

    energies = Setting("")

    seed_increment = Setting(1)

    autobinning = Setting(1)

    auto_n_step = Setting(1001)
    auto_perc_total_power = Setting(99)

    send_power_step = Setting(0)

    electron_energy = Setting(6.0)
    K_vertical = Setting(1.943722)
    K_horizontal = Setting(0.0)
    period_length = Setting(0.025)
    number_of_periods = Setting(184)
    theta_x = Setting(0.0)
    theta_z = Setting(0.0)

    current_energy_binning = -1
    current_energy_value = None
    current_energy_step = None
    current_power_step = None

    energy_binnings = None

    external_binning = False

    filters = None
    spectrum_data = None

    #################################
    process_last = True

    #################################

    def __init__(self):
        self.runaction = OWAction("Start", self)
        self.runaction.triggered.connect(self.startLoop)
        self.addAction(self.runaction)

        self.runaction = OWAction("Stop", self)
        self.runaction.triggered.connect(self.stopLoop)
        self.addAction(self.runaction)

        self.runaction = OWAction("Suspend", self)
        self.runaction.triggered.connect(self.suspendLoop)
        self.addAction(self.runaction)

        self.runaction = OWAction("Restart", self)
        self.runaction.triggered.connect(self.restartLoop)
        self.addAction(self.runaction)

        self.setFixedWidth(1200)
        self.setFixedHeight(710)

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

        self.start_button = gui.button(button_box,
                                       self,
                                       "Start",
                                       callback=self.startLoop)
        self.start_button.setFixedHeight(35)

        stop_button = gui.button(button_box,
                                 self,
                                 "Stop",
                                 callback=self.stopLoop)
        stop_button.setFixedHeight(35)
        font = QFont(stop_button.font())
        font.setBold(True)
        stop_button.setFont(font)
        palette = QPalette(stop_button.palette())  # make a copy of the palette
        palette.setColor(QPalette.ButtonText, QColor('red'))
        stop_button.setPalette(palette)  # assign new palette

        self.stop_button = stop_button

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

        suspend_button = gui.button(button_box,
                                    self,
                                    "Suspend",
                                    callback=self.suspendLoop)
        suspend_button.setFixedHeight(35)
        font = QFont(suspend_button.font())
        font.setBold(True)
        suspend_button.setFont(font)
        palette = QPalette(
            suspend_button.palette())  # make a copy of the palette
        palette.setColor(QPalette.ButtonText, QColor('orange'))
        suspend_button.setPalette(palette)  # assign new palette

        self.re_start_button = gui.button(button_box,
                                          self,
                                          "Restart",
                                          callback=self.restartLoop)
        self.re_start_button.setFixedHeight(35)
        self.re_start_button.setEnabled(False)

        tabs = oasysgui.tabWidget(self.controlArea)
        tab_loop = oasysgui.createTabPage(tabs, "Loop Management")
        tab_und = oasysgui.createTabPage(tabs, "Undulator")

        left_box_2 = oasysgui.widgetBox(tab_und,
                                        "Parameters From Syned",
                                        addSpace=False,
                                        orientation="vertical",
                                        width=385,
                                        height=560)

        oasysgui.lineEdit(left_box_2,
                          self,
                          "electron_energy",
                          "Ring Energy [GeV]",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal").setReadOnly(True)
        oasysgui.lineEdit(left_box_2,
                          self,
                          "number_of_periods",
                          "Number of Periods",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal").setReadOnly(True)
        oasysgui.lineEdit(left_box_2,
                          self,
                          "period_length",
                          "Undulator Period [m]",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal").setReadOnly(True)
        oasysgui.lineEdit(left_box_2,
                          self,
                          "K_vertical",
                          "K Vertical",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal").setReadOnly(True)
        oasysgui.lineEdit(left_box_2,
                          self,
                          "K_horizontal",
                          "K Horizontal",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal").setReadOnly(True)

        left_box_1 = oasysgui.widgetBox(tab_loop,
                                        "",
                                        addSpace=False,
                                        orientation="vertical",
                                        width=385,
                                        height=560)

        oasysgui.lineEdit(left_box_1,
                          self,
                          "seed_increment",
                          "Source Montecarlo Seed Increment",
                          labelWidth=250,
                          valueType=int,
                          orientation="horizontal")

        gui.separator(left_box_1)

        gui.comboBox(left_box_1,
                     self,
                     "autobinning",
                     label="Energy Binning",
                     items=[
                         "Manual", "Automatic (Constant Power)",
                         "Automatic (Constant Energy)"
                     ],
                     labelWidth=150,
                     callback=self.set_Autobinning,
                     sendSelectedValue=False,
                     orientation="horizontal")

        self.autobinning_box_1 = oasysgui.widgetBox(left_box_1,
                                                    "",
                                                    addSpace=False,
                                                    orientation="vertical",
                                                    height=50)
        self.autobinning_box_2 = oasysgui.widgetBox(left_box_1,
                                                    "",
                                                    addSpace=False,
                                                    orientation="vertical",
                                                    height=140)

        # ----------------------------------------------

        gui.button(self.autobinning_box_1,
                   self,
                   "Compute Bins",
                   callback=self.calculate_energy_binnings)

        oasysgui.widgetLabel(self.autobinning_box_1,
                             "Energy From, Energy To, Energy Step [eV]")

        # ----------------------------------------------

        oasysgui.lineEdit(self.autobinning_box_2,
                          self,
                          "auto_n_step",
                          "Number of Steps",
                          labelWidth=250,
                          valueType=int,
                          orientation="horizontal")
        oasysgui.lineEdit(self.autobinning_box_2,
                          self,
                          "auto_perc_total_power",
                          "% Total Power",
                          labelWidth=250,
                          valueType=float,
                          orientation="horizontal")
        gui.comboBox(self.autobinning_box_2,
                     self,
                     "send_power_step",
                     label="Send Power Step",
                     items=["No", "Yes"],
                     labelWidth=350,
                     sendSelectedValue=False,
                     orientation="horizontal")

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

        gui.button(button_box,
                   self,
                   "Reload Spectrum and Filters",
                   callback=self.read_spectrum_and_filters_file)
        gui.button(button_box,
                   self,
                   "Reload Spectrum Only",
                   callback=self.read_spectrum_file_only)

        oasysgui.widgetLabel(
            self.autobinning_box_2,
            "Energy Value [eV], Energy Step [eV], Power Step [W]")

        def write_text():
            self.energies = self.text_area.toPlainText()

        self.text_area = oasysgui.textArea(height=95,
                                           width=385,
                                           readOnly=False)
        self.text_area.setText(self.energies)
        self.text_area.setStyleSheet(
            "background-color: white; font-family: Courier, monospace;")
        self.text_area.textChanged.connect(write_text)

        left_box_1.layout().addWidget(self.text_area)

        gui.separator(left_box_1)

        self.le_number_of_new_objects = oasysgui.lineEdit(
            left_box_1,
            self,
            "total_new_objects",
            "Total Energy Values",
            labelWidth=250,
            valueType=int,
            orientation="horizontal")
        self.le_number_of_new_objects.setReadOnly(True)
        font = QFont(self.le_number_of_new_objects.font())
        font.setBold(True)
        self.le_number_of_new_objects.setFont(font)
        palette = QPalette(self.le_number_of_new_objects.palette()
                           )  # make a copy of the palette
        palette.setColor(QPalette.Text, QColor('dark blue'))
        palette.setColor(QPalette.Base, QColor(243, 240, 160))
        self.le_number_of_new_objects.setPalette(palette)

        self.le_number_of_new_objects = oasysgui.lineEdit(
            left_box_1,
            self,
            "number_of_new_objects",
            "Current Binning Energy Values",
            labelWidth=250,
            valueType=int,
            orientation="horizontal")
        self.le_number_of_new_objects.setReadOnly(True)
        font = QFont(self.le_number_of_new_objects.font())
        font.setBold(True)
        self.le_number_of_new_objects.setFont(font)
        palette = QPalette(self.le_number_of_new_objects.palette()
                           )  # make a copy of the palette
        palette.setColor(QPalette.Text, QColor('dark blue'))
        palette.setColor(QPalette.Base, QColor(243, 240, 160))
        self.le_number_of_new_objects.setPalette(palette)

        gui.separator(left_box_1)

        le_current_value = oasysgui.lineEdit(left_box_1,
                                             self,
                                             "total_current_new_object",
                                             "Total New " +
                                             self.get_object_name(),
                                             labelWidth=250,
                                             valueType=int,
                                             orientation="horizontal")
        le_current_value.setReadOnly(True)
        font = QFont(le_current_value.font())
        font.setBold(True)
        le_current_value.setFont(font)
        palette = QPalette(
            le_current_value.palette())  # make a copy of the palette
        palette.setColor(QPalette.Text, QColor('dark blue'))
        palette.setColor(QPalette.Base, QColor(243, 240, 160))
        le_current_value.setPalette(palette)

        le_current_value = oasysgui.lineEdit(left_box_1,
                                             self,
                                             "current_new_object",
                                             "Current Binning New " +
                                             self.get_object_name(),
                                             labelWidth=250,
                                             valueType=int,
                                             orientation="horizontal")
        le_current_value.setReadOnly(True)
        font = QFont(le_current_value.font())
        font.setBold(True)
        le_current_value.setFont(font)
        palette = QPalette(
            le_current_value.palette())  # make a copy of the palette
        palette.setColor(QPalette.Text, QColor('dark blue'))
        palette.setColor(QPalette.Base, QColor(243, 240, 160))
        le_current_value.setPalette(palette)

        le_current_value = oasysgui.lineEdit(left_box_1,
                                             self,
                                             "current_energy_value",
                                             "Current Energy Value",
                                             labelWidth=250,
                                             valueType=float,
                                             orientation="horizontal")
        le_current_value.setReadOnly(True)
        font = QFont(le_current_value.font())
        font.setBold(True)
        le_current_value.setFont(font)
        palette = QPalette(
            le_current_value.palette())  # make a copy of the palette
        palette.setColor(QPalette.Text, QColor('dark blue'))
        palette.setColor(QPalette.Base, QColor(243, 240, 160))
        le_current_value.setPalette(palette)

        gui.rubber(self.controlArea)

        tabs = oasysgui.tabWidget(self.mainArea)
        tabs.setFixedHeight(self.height() - 15)
        tabs.setFixedWidth(775)

        tab_plot = oasysgui.createTabPage(tabs, "Cumulated Power")
        tab_flux = oasysgui.createTabPage(tabs, "Spectral Flux")
        tab_fil = oasysgui.createTabPage(tabs, "Filter")

        self.cumulated_power_plot = oasysgui.plotWindow(tab_plot,
                                                        position=True)
        self.cumulated_power_plot.setFixedHeight(self.height() - 20)
        self.cumulated_power_plot.setFixedWidth(775)
        self.cumulated_power_plot.setGraphXLabel("Energy [eV]")
        self.cumulated_power_plot.setGraphYLabel("Cumulated Power [W]")
        self.cumulated_power_plot.setGraphTitle("Cumulated Power")

        self.spectral_flux_plot = oasysgui.plotWindow(tab_flux, position=True)
        self.spectral_flux_plot.setFixedHeight(self.height() - 20)
        self.spectral_flux_plot.setFixedWidth(775)
        self.spectral_flux_plot.setGraphXLabel("Energy [eV]")
        self.spectral_flux_plot.setGraphYLabel("Flux [ph/s/.1%bw]")
        self.spectral_flux_plot.setGraphTitle("Spectral Flux")

        self.filter_plot = oasysgui.plotWindow(tab_fil, position=True)
        self.filter_plot.setFixedHeight(self.height() - 20)
        self.filter_plot.setFixedWidth(775)
        self.filter_plot.setGraphXLabel("Energy [eV]")
        self.filter_plot.setGraphYLabel("Intensity Factor")
        self.filter_plot.setGraphTitle("Filter on Flux")

        self.set_Autobinning()

    def set_Autobinning(self):
        self.autobinning_box_1.setVisible(self.autobinning == 0)
        self.autobinning_box_2.setVisible(self.autobinning == 1
                                          or self.autobinning == 2)
        self.text_area.setReadOnly(self.autobinning >= 1)
        self.text_area.setFixedHeight(201 if self.autobinning >= 1 else 290)

    def read_spectrum_file(self, reset_filters=True):
        try:
            if reset_filters:
                self.filters = None
                self.filter_plot.clear()

            data = numpy.loadtxt("autobinning.dat", skiprows=1)

            calculated_data = DataExchangeObject(program_name="ShadowOui",
                                                 widget_name="PowerLoopPoint")
            calculated_data.add_content("spectrum_data", data)

            self.acceptEnergySpectrum(calculated_data)
        except Exception as e:
            QMessageBox.critical(self, "Error", str(e), QMessageBox.Ok)

            if self.IS_DEVELOP: raise e

    def read_spectrum_file_only(self):
        self.read_spectrum_file(True)

    def read_spectrum_and_filters_file(self):
        try:
            data = numpy.loadtxt("filters.dat", skiprows=1)

            calculated_data = DataExchangeObject(program_name="ShadowOui",
                                                 widget_name="PowerLoopPoint")
            calculated_data.add_content("filters_data", data)

            self.acceptFilters(calculated_data)
        except Exception:
            self.filters = None

        self.read_spectrum_file(False)

    def receive_syned_data(self, data):
        if not data is None:
            try:
                if not data._light_source is None and isinstance(
                        data._light_source, LightSource):
                    light_source = data._light_source

                    self.electron_energy = light_source._electron_beam._energy_in_GeV

                    self.K_horizontal = light_source._magnetic_structure._K_horizontal
                    self.K_vertical = light_source._magnetic_structure._K_vertical
                    self.period_length = light_source._magnetic_structure._period_length
                    self.number_of_periods = light_source._magnetic_structure._number_of_periods
                else:
                    raise ValueError("Syned data not correct")
            except Exception as exception:
                QMessageBox.critical(self, "Error", str(exception),
                                     QMessageBox.Ok)

                if self.IS_DEVELOP: raise exception

    def receive_specific_syned_data(self, data):
        raise NotImplementedError()

    def acceptFilters(self, exchange_data):
        if not exchange_data is None:
            try:  # FROM XOPPY F1F2
                write_file = True

                try:
                    data = exchange_data.get_content("filters_data")
                    write_file = False
                except:
                    if not exchange_data.get_program_name() == "XOPPY":
                        raise ValueError(
                            "Only XOPPY F1F2 and CRYSTAL widgets are accepted")

                    if exchange_data.get_widget_name() == "XF1F2":
                        data = exchange_data.get_content("xoppy_data")
                    elif exchange_data.get_widget_name() == "XCRYSTAL":
                        data = exchange_data.get_content("xoppy_data")
                        cols = data.shape[1]
                        data = exchange_data.get_content("xoppy_data")[
                            0:cols:cols - 1, 0:cols:cols - 1]
                    elif exchange_data.get_widget_name() == "MLAYER":
                        data = exchange_data.get_content("xoppy_data")[0:3:2,
                                                                       0:3:2]

                self.filters = data

                energies = self.filters[:, 0]
                intensity_factors = self.filters[:, 1]

                if write_file:
                    file = open("filters.dat", "w")
                    file.write("Energy Filter")

                    for energy, intensity_factor in zip(
                            energies, intensity_factors):
                        file.write("\n" + str(energy) + " " +
                                   str(intensity_factor))

                    file.flush()
                    file.close()

                self.filter_plot.clear()
                self.filter_plot.addCurve(energies,
                                          intensity_factors,
                                          replace=True,
                                          legend="Intensity Factor")
                self.filter_plot.setGraphXLabel("Energy [eV]")
                self.filter_plot.setGraphYLabel("Intensity Factor")
                self.filter_plot.setGraphTitle("Filter on Flux")

                if self.autobinning == 0:
                    if write_file:
                        QMessageBox.information(
                            self, "Info",
                            "File filters.dat written on working directory, switch to Automatic binning to load it",
                            QMessageBox.Ok)
                else:
                    if write_file:
                        QMessageBox.information(
                            self, "Info",
                            "File filters.dat written on working directory",
                            QMessageBox.Ok)

                if not self.spectrum_data is None:
                    calculated_data = DataExchangeObject(
                        program_name="ShadowOui", widget_name="PowerLoopPoint")
                    calculated_data.add_content("spectrum_data",
                                                self.spectrum_data)

                    self.acceptEnergySpectrum(calculated_data)

            except Exception as e:
                QMessageBox.critical(self, "Error", str(e), QMessageBox.Ok)

                if self.IS_DEVELOP: raise e

    def acceptEnergySpectrum(self, exchange_data):
        if not exchange_data is None:
            try:
                write_file = True

                try:
                    data = exchange_data.get_content("spectrum_data")
                    write_file = False
                except:
                    try:
                        data = exchange_data.get_content("srw_data")
                    except:
                        data = exchange_data.get_content("xoppy_data")

                self.spectrum_data = data.copy()

                energies = data[:, 0]
                flux_through_finite_aperture = data[:, 1]
                flux_through_finite_aperture_filtered = flux_through_finite_aperture.copy(
                )

                if not self.filters is None:
                    flux_through_finite_aperture_filtered *= numpy.interp(
                        energies, self.filters[:, 0], self.filters[:, 1])

                if write_file:
                    file = open("autobinning.dat", "w")
                    file.write("Energy Flux")

                    for energy, flux in zip(energies,
                                            flux_through_finite_aperture):
                        file.write("\n" + str(energy) + " " + str(flux))

                    file.flush()
                    file.close()

                if self.autobinning == 0:
                    if write_file:
                        QMessageBox.information(
                            self, "Info",
                            "File autobinning.dat written on working directory, switch to Automatic binning to load it",
                            QMessageBox.Ok)
                else:
                    if write_file:
                        QMessageBox.information(
                            self, "Info",
                            "File autobinning.dat written on working directory",
                            QMessageBox.Ok)

                    congruence.checkStrictlyPositiveNumber(
                        self.auto_n_step, "(Auto) % Number of Steps")
                    congruence.checkStrictlyPositiveNumber(
                        self.auto_perc_total_power, "(Auto) % Total Power")

                    energy_step = energies[1] - energies[0]

                    # last energy do not contribute to the total (the approximated integral of the power is out of the range)

                    power = flux_through_finite_aperture * (1e3 * energy_step *
                                                            codata.e)
                    cumulated_power = numpy.cumsum(power)
                    total_power = cumulated_power[-1]

                    if not self.filters is None:
                        power_filtered = flux_through_finite_aperture_filtered * (
                            1e3 * energy_step * codata.e)
                        cumulated_power_filtered = numpy.cumsum(power_filtered)
                        total_power_filtered = cumulated_power_filtered[-1]

                    self.text_area.clear()

                    self.cumulated_power_plot.clear()
                    self.spectral_flux_plot.clear()

                    good = numpy.where(
                        cumulated_power <= self.auto_perc_total_power * 0.01 *
                        total_power)

                    energies = energies[good]
                    cumulated_power = cumulated_power[good]
                    flux_through_finite_aperture = flux_through_finite_aperture[
                        good]

                    if not self.filters is None:
                        cumulated_power_filtered = cumulated_power_filtered[
                            good]
                        flux_through_finite_aperture_filtered = flux_through_finite_aperture_filtered[
                            good]

                    if self.autobinning == 1:  # constant power
                        interpolated_cumulated_power = numpy.linspace(
                            start=numpy.min(cumulated_power),
                            stop=numpy.max(cumulated_power),
                            num=self.auto_n_step + 1)
                        interpolated_energies = numpy.interp(
                            interpolated_cumulated_power, cumulated_power,
                            energies)
                        energy_steps = numpy.ediff1d(interpolated_energies)

                        interpolated_energies = interpolated_energies[:-1]
                        interpolated_cumulated_power = interpolated_cumulated_power[:
                                                                                    -1]

                        power_steps = numpy.ones(
                            self.auto_n_step
                        ) * cumulated_power[-1] / self.auto_n_step

                    elif self.autobinning == 2:  # constant energy
                        minimum_energy = energies[0]
                        maximum_energy = energies[-1]
                        energy_step = (maximum_energy -
                                       minimum_energy) / self.auto_n_step

                        interpolated_energies = numpy.arange(
                            minimum_energy, maximum_energy, energy_step)
                        interpolated_cumulated_power = numpy.interp(
                            interpolated_energies, energies, cumulated_power)

                        energy_steps = numpy.ones(
                            self.auto_n_step) * energy_step
                        power_steps = numpy.ediff1d(
                            numpy.append(numpy.zeros(1),
                                         interpolated_cumulated_power))

                    flux_steps = numpy.interp(interpolated_energies, energies,
                                              flux_through_finite_aperture)

                    self.energy_binnings = []
                    self.total_new_objects = 0

                    self.cumulated_power_plot.addCurve(
                        energies,
                        cumulated_power,
                        replace=True,
                        legend="Cumulated Power")
                    if not self.filters is None:
                        self.cumulated_power_plot.addCurve(
                            energies,
                            cumulated_power_filtered,
                            replace=False,
                            legend="Cumulated Power Filters",
                            linestyle="--",
                            color="#006400")
                    self.cumulated_power_plot.setGraphXLabel("Energy [eV]")
                    self.cumulated_power_plot.setGraphYLabel("Cumulated " + (
                        "" if self.filters is None else " (Filtered)") +
                                                             " Power")
                    if self.filters is None:
                        self.cumulated_power_plot.setGraphTitle(
                            "Total Power: " +
                            str(round(power_steps.sum(), 2)) + " W")
                    else:
                        self.cumulated_power_plot.setGraphTitle(
                            "Total (Filtered) Power: " +
                            str(round(power_steps.sum(), 2)) + "  (" +
                            str(round(total_power_filtered, 2)) + ") W")

                    self.spectral_flux_plot.addCurve(
                        energies,
                        flux_through_finite_aperture,
                        replace=True,
                        legend="Spectral Flux")
                    if not self.filters is None:
                        self.spectral_flux_plot.addCurve(
                            energies,
                            flux_through_finite_aperture_filtered,
                            replace=False,
                            legend="Spectral Flux Filters",
                            linestyle="--",
                            color="#006400")
                    self.spectral_flux_plot.setGraphXLabel("Energy [eV]")
                    self.spectral_flux_plot.setGraphYLabel("Flux [ph/s/.1%bw]")
                    self.spectral_flux_plot.setGraphTitle("Spectral Flux" + (
                        "" if self.filters is None else " (Filtered)"))

                    self.cumulated_power_plot.addCurve(
                        interpolated_energies,
                        interpolated_cumulated_power,
                        replace=False,
                        legend="Energy Binning",
                        color="red",
                        linestyle=" ",
                        symbol="+")

                    self.spectral_flux_plot.addCurve(interpolated_energies,
                                                     flux_steps,
                                                     replace=False,
                                                     legend="Energy Binning",
                                                     color="red",
                                                     linestyle=" ",
                                                     symbol="+")

                    text = ""

                    for energy_value, energy_step, power_step in zip(
                            interpolated_energies, energy_steps, power_steps):
                        energy_binning = EnergyBinning(
                            energy_value=round(energy_value, 3),
                            energy_step=round(energy_step, 3),
                            power_step=round(power_step, 4))

                        text += str(round(energy_value, 3)) + ", " + \
                                str(round(energy_step, 3))  + ", " + \
                                str(round(power_step, 4)) + "\n"

                        self.energy_binnings.append(energy_binning)
                        self.total_new_objects += 1

                    self.text_area.setText(text)

                    self.external_binning = True
            except Exception as e:
                QMessageBox.critical(self, "Error", str(e), QMessageBox.Ok)

                if self.IS_DEVELOP: raise e
        else:
            self.energy_binnings = None
            self.total_new_objects = 0
            self.external_binning = False
            self.text_area.setText("")

    def calculate_energy_binnings(self):
        if not self.external_binning:
            self.total_new_objects = 0

            rows = self.energies.split("\n")
            for row in rows:
                data = row.split(",")
                if len(data) == 3:
                    if self.energy_binnings is None: self.energy_binnings = []

                    energy_from = float(data[0].strip())
                    energy_to = float(data[1].strip())
                    energy_step = float(data[2].strip())

                    energy_binning = EnergyBinning(energy_value=energy_from,
                                                   energy_value_to=energy_to,
                                                   energy_step=energy_step)
                    self.energy_binnings.append(energy_binning)

                    self.total_new_objects += int(
                        (energy_to - energy_from) / energy_step)

    def calculate_number_of_new_objects(self):
        if len(self.energy_binnings) > 0:
            if self.external_binning:
                self.number_of_new_objects = 1
            else:
                energy_binning = self.energy_binnings[
                    self.current_energy_binning]

                self.number_of_new_objects = int(
                    (energy_binning.energy_value_to -
                     energy_binning.energy_value) / energy_binning.energy_step)
        else:
            self.number_of_new_objects = 0

    def reset_values(self):
        self.current_new_object = 0
        self.total_current_new_object = 0
        self.current_energy_value = None
        self.current_energy_step = None
        self.current_energy_binning = -1
        self.current_power_step = None

        if not self.external_binning: self.energy_binnings = None

    def startLoop(self):
        try:
            self.calculate_energy_binnings()

            self.current_new_object = 1
            self.total_current_new_object = 1
            self.current_energy_binning = 0
            self.current_energy_value = round(
                self.energy_binnings[0].energy_value, 8)
            self.current_energy_step = round(
                self.energy_binnings[0].energy_step, 8)
            self.current_power_step = None if self.energy_binnings[
                0].power_step is None else (
                    None if self.send_power_step == 0 else round(
                        self.energy_binnings[0].power_step, 8))
            self.calculate_number_of_new_objects()

            self.start_button.setEnabled(False)
            self.text_area.setEnabled(False)
            self.setStatusMessage("Running " + self.get_object_name() + " " +
                                  str(self.total_current_new_object) + " of " +
                                  str(self.total_new_objects))
            self.send(
                "Trigger",
                TriggerOut(new_object=True,
                           additional_parameters={
                               "energy_value":
                               self.current_energy_value,
                               "energy_step":
                               self.current_energy_step,
                               "power_step":
                               -1 if self.current_power_step is None else
                               self.current_power_step,
                               "seed_increment":
                               self.seed_increment,
                               "start_event":
                               True
                           }))
        except Exception as e:
            if self.IS_DEVELOP: raise e
            else: pass

    def stopLoop(self):
        try:
            if ConfirmDialog.confirmed(
                    parent=self, message="Confirm Interruption of the Loop?"):
                self.run_loop = False
                self.reset_values()
                self.setStatusMessage("Interrupted by user")
        except Exception as e:
            if self.IS_DEVELOP: raise e
            else: pass

    def suspendLoop(self):
        try:
            if ConfirmDialog.confirmed(
                    parent=self, message="Confirm Suspension of the Loop?"):
                self.run_loop = False
                self.suspend_loop = True
                self.stop_button.setEnabled(False)
                self.re_start_button.setEnabled(True)
                self.setStatusMessage("Suspended by user")
        except Exception as e:
            if self.IS_DEVELOP: raise e
            else: pass

    def restartLoop(self):
        try:
            self.run_loop = True
            self.suspend_loop = False
            self.stop_button.setEnabled(True)
            self.re_start_button.setEnabled(False)
            self.passTrigger(TriggerIn(new_object=True))
        except Exception as e:
            if self.IS_DEVELOP: raise e
            else: pass

    def get_object_name(self):
        return "Beam"

    def passTrigger(self, trigger):
        if self.run_loop:
            if trigger:
                if trigger.interrupt:
                    self.reset_values()
                    self.start_button.setEnabled(True)
                    self.text_area.setEnabled(True)
                    self.setStatusMessage("")
                    self.send("Trigger", TriggerOut(new_object=False))
                elif trigger.new_object:
                    if self.energy_binnings is None:
                        self.calculate_energy_binnings()

                    if self.current_energy_binning == -1:
                        QMessageBox.critical(
                            self, "Error",
                            "Power Loop has to be started properly: press the button Start",
                            QMessageBox.Ok)
                        return

                    if self.current_energy_binning < len(self.energy_binnings):
                        energy_binning = self.energy_binnings[
                            self.current_energy_binning]

                        self.total_current_new_object += 1

                        if self.current_new_object < self.number_of_new_objects:
                            if self.current_energy_value is None:
                                self.current_new_object = 1
                                self.calculate_number_of_new_objects()
                                self.current_energy_value = round(
                                    energy_binning.energy_value, 8)
                            else:
                                self.current_new_object += 1
                                self.current_energy_value = round(
                                    self.current_energy_value +
                                    energy_binning.energy_step, 8)

                            self.current_power_step = None if energy_binning.power_step is None else (
                                None if self.send_power_step == 0 else round(
                                    energy_binning.power_step, 8))

                            self.setStatusMessage(
                                "Running " + self.get_object_name() + " " +
                                str(self.total_current_new_object) + " of " +
                                str(self.total_new_objects))
                            self.start_button.setEnabled(False)
                            self.text_area.setEnabled(False)
                            self.send(
                                "Trigger",
                                TriggerOut(
                                    new_object=True,
                                    additional_parameters={
                                        "energy_value":
                                        self.current_energy_value,
                                        "energy_step":
                                        energy_binning.energy_step,
                                        "power_step":
                                        -1 if self.current_power_step is None
                                        else self.current_power_step,
                                        "seed_increment":
                                        self.seed_increment,
                                        "start_event":
                                        False
                                    }))
                        else:
                            self.current_energy_binning += 1

                            if self.current_energy_binning < len(
                                    self.energy_binnings):
                                energy_binning = self.energy_binnings[
                                    self.current_energy_binning]

                                self.current_new_object = 1
                                self.calculate_number_of_new_objects()
                                self.current_energy_value = round(
                                    energy_binning.energy_value, 8)
                                self.current_power_step = None if energy_binning.power_step is None else (
                                    None if self.send_power_step == 0 else
                                    round(energy_binning.power_step, 8))

                                self.setStatusMessage(
                                    "Running " + self.get_object_name() + " " +
                                    str(self.total_current_new_object) +
                                    " of " + str(self.total_new_objects))
                                self.start_button.setEnabled(False)
                                self.text_area.setEnabled(False)
                                self.send(
                                    "Trigger",
                                    TriggerOut(
                                        new_object=True,
                                        additional_parameters={
                                            "energy_value":
                                            self.current_energy_value,
                                            "energy_step":
                                            energy_binning.energy_step,
                                            "power_step":
                                            -1
                                            if self.current_power_step is None
                                            else self.current_power_step,
                                            "seed_increment":
                                            self.seed_increment,
                                            "start_event":
                                            False
                                        }))
                            else:
                                self.reset_values()
                                self.start_button.setEnabled(True)
                                self.text_area.setEnabled(True)
                                self.setStatusMessage("")
                                self.send("Trigger",
                                          TriggerOut(new_object=False))
                    else:
                        self.reset_values()
                        self.start_button.setEnabled(True)
                        self.text_area.setEnabled(True)
                        self.setStatusMessage("")
                        self.send("Trigger", TriggerOut(new_object=False))
        else:
            if not self.suspend_loop:
                self.reset_values()
                self.start_button.setEnabled(True)
                self.text_area.setEnabled(True)

            self.send("Trigger", TriggerOut(new_object=False))
            self.setStatusMessage("")
            self.suspend_loop = False
            self.run_loop = True
Example #27
0
class OWZeroErrorPeakShift(
        OWGenericInstrumentalDiffractionPatternParametersWidget):

    name = "Zero Error Peak Shift"
    description = "Zero Error Peak Shift"
    icon = "icons/zero_error_peak_shift.png"
    priority = 14

    shift = Setting([0.0])
    shift_fixed = Setting([0])
    shift_has_min = Setting([0])
    shift_min = Setting([0.0])
    shift_has_max = Setting([0])
    shift_max = Setting([0.0])
    shift_function = Setting([0])
    shift_function_value = Setting([""])

    def get_max_height(self):
        return 310

    def get_parameter_name(self):
        return "Peak Shift"

    def get_current_dimension(self):
        return len(self.shift)

    def get_parameter_box_instance(self, parameter_tab, index):
        return ZeroErrorPeakShiftBox(
            widget=self,
            parent=parameter_tab,
            index=index,
            shift=self.shift[index],
            shift_fixed=self.shift_fixed[index],
            shift_has_min=self.shift_has_min[index],
            shift_min=self.shift_min[index],
            shift_has_max=self.shift_has_max[index],
            shift_max=self.shift_max[index],
            shift_function=self.shift_function[index],
            shift_function_value=self.shift_function_value[index])

    def get_empty_parameter_box_instance(self, parameter_tab, index):
        return ZeroErrorPeakShiftBox(widget=self,
                                     parent=parameter_tab,
                                     index=index)

    def set_parameter_data(self):
        self.fit_global_parameters.set_shift_parameters([
            self.get_parameter_box(index).get_peak_shift()
            for index in range(self.get_current_dimension())
        ])

    def get_parameter_array(self):
        return self.fit_global_parameters.get_shift_parameters(
            ZeroError.__name__)

    def get_parameter_item(self, diffraction_pattern_index):
        return self.fit_global_parameters.get_shift_parameters_item(
            ZeroError.__name__, diffraction_pattern_index)

    def get_instrumental_parameter_array(self, instrumental_parameters):
        return instrumental_parameters.get_shift_parameters(ZeroError.__name__)

    def get_instrumental_parameter_item(self, instrumental_parameters,
                                        diffraction_pattern_index):
        return instrumental_parameters.get_shift_parameters_item(
            ZeroError.__name__, diffraction_pattern_index)

    def dumpSettings(self):
        self.dump_shift()

    def dump_shift(self):
        self.dump_parameter("shift")
Example #28
0
class OWModesLoader(widget.OWWidget):
    name = "Modes loader"
    id = "orangecontrib.comsyl.widgets.applications.AFViewer"
    description = ""
    icon = "icons/loader.png"
    author = ""
    maintainer_email = "*****@*****.**"
    priority = 40
    category = ""
    keywords = ["COMSYL", "coherent modes"]

    outputs = [
        {
            "name": "COMSYL modes",
            "type": CompactAFReader,
            "doc": "COMSYL modes",
            "id": "COMSYL modes"
        },
    ]

    IMAGE_WIDTH = 760
    IMAGE_HEIGHT = 545
    MAX_WIDTH = 1320
    MAX_HEIGHT = 700
    CONTROL_AREA_WIDTH = 405

    beam_file_name = Setting(
        "/users/srio/COMSYLD/comsyl/comsyl/calculations/septest_cm_new_u18_2m_1h_s2.5.h5"
    )

    TYPE_PRESENTATION = Setting(0)  # 0=intensity, 1=real, 2=phase

    INDIVIDUAL_MODES = Setting(False)

    MODE_INDEX = Setting(0)

    def __init__(self):

        super().__init__()

        self._input_available = False
        self.af = None

        self.runaction = orange_widget.OWAction("Load COMSYL files", self)
        self.runaction.triggered.connect(self.read_file)
        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())

        self.controlArea.setFixedWidth(self.CONTROL_AREA_WIDTH)

        self.build_left_panel()

        self.process_showers()

        gui.rubber(self.controlArea)

        self.main_tabs = gui.tabWidget(self.mainArea)
        plot_tab = gui.createTabPage(self.main_tabs, "Results")
        info_tab = gui.createTabPage(self.main_tabs, "Info")

        self.tab = []
        self.tabs = gui.tabWidget(plot_tab)
        self.info = gui.tabWidget(info_tab)
        self.tab_titles = []
        self.initialize_tabs()

        # info tab
        self.comsyl_output = QtWidgets.QTextEdit()
        self.comsyl_output.setReadOnly(True)

        out_box = gui.widgetBox(self.info,
                                "COMSYL file info",
                                addSpace=True,
                                orientation="horizontal")
        out_box.layout().addWidget(self.comsyl_output)

        self.comsyl_output.setFixedHeight(self.IMAGE_HEIGHT)
        self.comsyl_output.setFixedWidth(self.IMAGE_WIDTH)

    def initialize_tabs(self):

        size = len(self.tab)
        indexes = range(0, size)

        for index in indexes:
            self.tabs.removeTab(size - 1 - index)

        self.tab = []
        self.plot_canvas = []

        for index in range(0, len(self.tab_titles)):
            self.tab.append(
                gui.createTabPage(self.tabs, self.tab_titles[index]))
            self.plot_canvas.append(None)

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

    def write_std_out(self, text):
        cursor = self.comsyl_output.textCursor()
        cursor.movePosition(QtGui.QTextCursor.End)
        cursor.insertText(text)
        self.comsyl_output.setTextCursor(cursor)
        self.comsyl_output.ensureCursorVisible()

    def build_left_panel(self):

        left_box_1 = oasysgui.widgetBox(self.controlArea,
                                        "Files Selection",
                                        addSpace=True,
                                        orientation="vertical")

        figure_box = oasysgui.widgetBox(
            left_box_1, "", addSpace=True,
            orientation="horizontal")  #width=550, height=50)
        self.le_beam_file_name = oasysgui.lineEdit(figure_box,
                                                   self,
                                                   "beam_file_name",
                                                   "COMSYL File:",
                                                   labelWidth=90,
                                                   valueType=str,
                                                   orientation="horizontal")
        gui.button(figure_box, self, "...", callback=self.selectFile)
        gui.separator(left_box_1)

        button = gui.button(self.controlArea,
                            self,
                            "Read COMSYL File",
                            callback=self.read_file)
        button.setFixedHeight(45)

        left_box_2 = oasysgui.widgetBox(self.controlArea,
                                        "Display mode",
                                        addSpace=True,
                                        orientation="vertical")

        gui.comboBox(left_box_2,
                     self,
                     "TYPE_PRESENTATION",
                     label="Display magnitude ",
                     addSpace=False,
                     items=[
                         'intensity', 'modulus', 'real part', 'imaginary part',
                         'angle [rad]'
                     ],
                     valueType=int,
                     orientation="horizontal",
                     callback=self.do_plot)
        gui.separator(left_box_1, height=20)

        gui.comboBox(left_box_2,
                     self,
                     "INDIVIDUAL_MODES",
                     label="Access individual modes ",
                     addSpace=False,
                     items=[
                         'No [Fast]',
                         'Yes [Slow, memory hungry]',
                     ],
                     valueType=int,
                     orientation="horizontal",
                     callback=self.do_plot)
        gui.separator(left_box_1, height=20)

        mode_index_box = oasysgui.widgetBox(
            left_box_2,
            "",
            addSpace=True,
            orientation="horizontal",
        )  #width=550, height=50)
        oasysgui.lineEdit(mode_index_box,
                          self,
                          "MODE_INDEX",
                          label="Plot mode ",
                          addSpace=False,
                          valueType=int,
                          orientation="horizontal",
                          labelWidth=150,
                          callback=self.do_plot)
        gui.button(mode_index_box,
                   self,
                   "+1",
                   callback=self.increase_mode_index)

        button = gui.button(self.controlArea,
                            self,
                            "PLOT COMSYL data",
                            callback=self.do_plot)
        button.setFixedHeight(45)

    def increase_mode_index(self):
        if self.MODE_INDEX + 1 >= self.af.number_of_modes():
            raise Exception("Mode index %d not available" %
                            (self.MODE_INDEX + 1))
        self.MODE_INDEX += 1
        self.do_plot()

    def set_selected_file(self, filename):
        self.le_beam_file_name.setText(filename)

    def selectFile(self):
        filename = oasysgui.selectFileFromDialog(
            self,
            previous_file_path=self.beam_file_name,
            message="Open COMSYL File [*.npy or *.npz or *.h5]",
            start_directory=".",
            file_extension_filter="*.*")

        self.le_beam_file_name.setText(filename)

    def read_file(self):
        self.setStatusMessage("")
        filename = self.le_beam_file_name.text()
        try:
            if congruence.checkFileName(filename):

                # # just in case old file is open
                # try:
                #     self.af.close_h5_file()
                # except:
                #     pass

                try:
                    self.af = CompactAFReader.initialize_from_file(filename)
                    self._input_available = True
                    self.write_std_out(self.af.info(list_modes=False))
                    self.main_tabs.setCurrentIndex(1)
                    self.initialize_tabs()

                    self.send("COMSYL modes", self.af)
                except:
                    raise FileExistsError(
                        "Error loading COMSYL modes from file: %s" % filename)

        except:
            raise Exception("Failed to read file %s" % filename)

    def _square_modulus(self, array1):
        return (numpy.absolute(array1))**2

    def plot_data2D(self,
                    data2D,
                    dataX,
                    dataY,
                    plot_canvas_index,
                    title="",
                    xtitle="",
                    ytitle=""):

        xmin = numpy.min(dataX)
        xmax = numpy.max(dataX)
        ymin = numpy.min(dataY)
        ymax = numpy.max(dataY)

        origin = (xmin, ymin)
        scale = (abs(
            (xmax - xmin) / len(dataX)), abs((ymax - ymin) / len(dataY)))

        data_to_plot = data2D.T

        colormap = {
            "name": "temperature",
            "normalization": "linear",
            "autoscale": True,
            "vmin": 0,
            "vmax": 0,
            "colors": 256
        }

        self.plot_canvas[plot_canvas_index] = Plot2D()

        self.plot_canvas[plot_canvas_index].resetZoom()
        self.plot_canvas[plot_canvas_index].setXAxisAutoScale(True)
        self.plot_canvas[plot_canvas_index].setYAxisAutoScale(True)
        self.plot_canvas[plot_canvas_index].setGraphGrid(False)
        self.plot_canvas[plot_canvas_index].setKeepDataAspectRatio(True)
        self.plot_canvas[plot_canvas_index].yAxisInvertedAction.setVisible(
            False)

        self.plot_canvas[plot_canvas_index].setXAxisLogarithmic(False)
        self.plot_canvas[plot_canvas_index].setYAxisLogarithmic(False)

        self.plot_canvas[plot_canvas_index].getMaskAction().setVisible(False)
        self.plot_canvas[plot_canvas_index].getRoiAction().setVisible(False)
        self.plot_canvas[plot_canvas_index].getColormapAction().setVisible(
            True)
        self.plot_canvas[plot_canvas_index].setKeepDataAspectRatio(False)

        self.plot_canvas[plot_canvas_index].addImage(numpy.array(data_to_plot),
                                                     legend="",
                                                     scale=scale,
                                                     origin=origin,
                                                     colormap=colormap,
                                                     replace=True)

        self.plot_canvas[plot_canvas_index].setGraphXLabel(xtitle)
        self.plot_canvas[plot_canvas_index].setGraphYLabel(ytitle)
        self.plot_canvas[plot_canvas_index].setGraphTitle(title)

        self.tab[plot_canvas_index].layout().addWidget(
            self.plot_canvas[plot_canvas_index])

    def do_plot(self):

        old_tab_index = self.tabs.currentIndex()

        try:
            for i in range(len(self.tab_titles)):
                self.tab[i].layout().removeItem(self.tab[i].layout().itemAt(0))
        except:
            pass

        if self.INDIVIDUAL_MODES:
            self.tab_titles = [
                "SPECTRUM",
                "CUMULATED SPECTRUM",
                "SPECTRAL DENSITY (INTENSITY)",
                "SPECTRAL INTENSITY FROM MODES",
                "REFERENCE ELECRON DENSITY",
                "REFERENCE UNDULATOR WAVEFRONT",
                "INDIVIDUAL MODES",
            ]
        else:
            self.tab_titles = [
                "SPECTRUM",
                "CUMULATED SPECTRUM",
                "SPECTRAL DENSITY (INTENSITY)",
                "REFERENCE ELECRON DENSITY",
                "REFERENCE UNDULATOR WAVEFRONT",
                "MODE INDEX: %d" % self.MODE_INDEX,
            ]

        self.initialize_tabs()

        if self.TYPE_PRESENTATION == 0:
            myprocess = self._square_modulus
            title0 = "Intensity of eigenvalues"
            title1 = "Intensity of eigenvector"
        if self.TYPE_PRESENTATION == 1:
            myprocess = numpy.absolute
            title0 = "Modulus of eigenvalues"
            title1 = "Modulus of eigenvector"
        elif self.TYPE_PRESENTATION == 2:
            myprocess = numpy.real
            title0 = "Real part of eigenvalues"
            title1 = "Real part of eigenvector"
        elif self.TYPE_PRESENTATION == 3:
            myprocess = numpy.imag
            title0 = "Imaginary part of eigenvalues"
            title1 = "Imaginary part of eigenvectos"
        elif self.TYPE_PRESENTATION == 4:
            myprocess = numpy.angle
            title0 = "Angle of eigenvalues [rad]"
            title1 = "Angle of eigenvector [rad]"

        if self._input_available:
            x_values = numpy.arange(self.af.number_modes())
            x_label = "Mode index"
            y_label = "Occupation"

            xx = self.af.x_coordinates()
            yy = self.af.y_coordinates()

            xmin = numpy.min(xx)
            xmax = numpy.max(xx)
            ymin = numpy.min(yy)
            ymax = numpy.max(yy)

        else:
            raise Exception("Nothing to plot")

        #
        # plot spectrum
        #
        tab_index = 0
        self.plot_canvas[tab_index] = PlotWindow(parent=None,
                                                 backend=None,
                                                 resetzoom=True,
                                                 autoScale=False,
                                                 logScale=True,
                                                 grid=True,
                                                 curveStyle=True,
                                                 colormap=False,
                                                 aspectRatio=False,
                                                 yInverted=False,
                                                 copy=True,
                                                 save=True,
                                                 print_=True,
                                                 control=False,
                                                 position=True,
                                                 roi=False,
                                                 mask=False,
                                                 fit=False)

        self.tab[tab_index].layout().addWidget(self.plot_canvas[tab_index])

        self.plot_canvas[tab_index].setDefaultPlotLines(True)
        self.plot_canvas[tab_index].setXAxisLogarithmic(False)
        self.plot_canvas[tab_index].setYAxisLogarithmic(False)
        self.plot_canvas[tab_index].setGraphXLabel(x_label)
        self.plot_canvas[tab_index].setGraphYLabel(y_label)
        self.plot_canvas[tab_index].addCurve(x_values,
                                             numpy.abs(
                                                 self.af.occupation_array()),
                                             title0,
                                             symbol='',
                                             xlabel="X",
                                             ylabel="Y",
                                             replace=False)  #'+', '^', ','

        self.tab[tab_index].layout().addWidget(self.plot_canvas[tab_index])
        #
        # plot cumulated spectrum
        #
        tab_index += 1
        self.plot_canvas[tab_index] = PlotWindow(parent=None,
                                                 backend=None,
                                                 resetzoom=True,
                                                 autoScale=False,
                                                 logScale=True,
                                                 grid=True,
                                                 curveStyle=True,
                                                 colormap=False,
                                                 aspectRatio=False,
                                                 yInverted=False,
                                                 copy=True,
                                                 save=True,
                                                 print_=True,
                                                 control=False,
                                                 position=True,
                                                 roi=False,
                                                 mask=False,
                                                 fit=False)

        self.tab[tab_index].layout().addWidget(self.plot_canvas[tab_index])

        self.plot_canvas[tab_index].setDefaultPlotLines(True)
        self.plot_canvas[tab_index].setXAxisLogarithmic(False)
        self.plot_canvas[tab_index].setYAxisLogarithmic(False)
        self.plot_canvas[tab_index].setGraphXLabel(x_label)
        self.plot_canvas[tab_index].setGraphYLabel("Cumulated occupation")
        self.plot_canvas[tab_index].addCurve(
            x_values,
            self.af.cumulated_occupation_array(),
            "Cumulated occupation",
            symbol='',
            xlabel="X",
            ylabel="Y",
            replace=False)  #'+', '^', ','

        self.plot_canvas[tab_index].setGraphYLimits(0.0, 1.0)

        self.tab[tab_index].layout().addWidget(self.plot_canvas[tab_index])

        #
        # plot spectral density
        #
        tab_index += 1
        image = myprocess((self.af.spectral_density()))
        self.plot_data2D(image,
                         1e6 * self.af.x_coordinates(),
                         1e6 * self.af.y_coordinates(),
                         tab_index,
                         title="Spectral Density (Intensity)",
                         xtitle="X [um] (%d pixels)" % (image.shape[0]),
                         ytitle="Y [um] (%d pixels)" % (image.shape[1]))

        #
        # plot spectral density from modes
        #
        if self.INDIVIDUAL_MODES:
            tab_index += 1
            image = myprocess((self.af.intensity_from_modes()))
            self.plot_data2D(image,
                             1e6 * self.af.x_coordinates(),
                             1e6 * self.af.y_coordinates(),
                             tab_index,
                             title="Spectral Density (Intensity)",
                             xtitle="X [um] (%d pixels)" % (image.shape[0]),
                             ytitle="Y [um] (%d pixels)" % (image.shape[1]))

        #
        # plot reference electron density
        #
        tab_index += 1
        image = numpy.abs(self.af.reference_electron_density()
                          )**2  #TODO: Correct? it is complex...
        self.plot_data2D(image,
                         1e6 * self.af.x_coordinates(),
                         1e6 * self.af.y_coordinates(),
                         tab_index,
                         title="Reference electron density",
                         xtitle="X [um] (%d pixels)" % (image.shape[0]),
                         ytitle="Y [um] (%d pixels)" % (image.shape[1]))

        #
        # plot reference undulator radiation
        #
        tab_index += 1
        image = self.af.reference_undulator_radiation()[
            0, :, :, 0]  #TODO: Correct? is polarized?
        self.plot_data2D(image,
                         1e6 * self.af.x_coordinates(),
                         1e6 * self.af.y_coordinates(),
                         tab_index,
                         title="Reference undulator radiation",
                         xtitle="X [um] (%d pixels)" % (image.shape[0]),
                         ytitle="Y [um] (%d pixels)" % (image.shape[1]))

        #
        # plot all modes
        #

        if self.INDIVIDUAL_MODES:
            tab_index += 1
            dim0_calib = (0, 1)
            dim1_calib = (1e6 * yy[0], 1e6 * (yy[1] - yy[0]))
            dim2_calib = (1e6 * xx[0], 1e6 * (xx[1] - xx[0]))

            colormap = {
                "name": "temperature",
                "normalization": "linear",
                "autoscale": True,
                "vmin": 0,
                "vmax": 0,
                "colors": 256
            }

            self.plot_canvas[tab_index] = StackViewMainWindow()
            self.plot_canvas[tab_index].setGraphTitle(title1)
            self.plot_canvas[tab_index].setLabels([
                "Mode number",
                "Y index from %4.2f to %4.2f um" % (1e6 * ymin, 1e6 * ymax),
                "X index from %4.2f to %4.2f um" % (1e6 * xmin, 1e6 * xmax),
            ])
            self.plot_canvas[tab_index].setColormap(colormap=colormap)

            self.plot_canvas[tab_index].setStack(
                myprocess(numpy.swapaxes(self.af.modes(), 2, 1)),
                calibrations=[dim0_calib, dim1_calib, dim2_calib])

            self.tab[tab_index].layout().addWidget(self.plot_canvas[tab_index])
        else:
            tab_index += 1
            image = myprocess((self.af.mode(self.MODE_INDEX)))
            self.plot_data2D(image,
                             1e6 * self.af.x_coordinates(),
                             1e6 * self.af.y_coordinates(),
                             tab_index,
                             title="Mode %d" % self.MODE_INDEX,
                             xtitle="X [um] (%d pixels)" % (image.shape[0]),
                             ytitle="Y [um] (%d pixels)" % (image.shape[1]))

        #
        try:
            self.tabs.setCurrentIndex(old_tab_index)
        except:
            pass

    def get_doc(self):
        pass
Example #29
0
class OWRetracer(GenericElement):
    name = "Retrace"
    id = "retrace"
    description = "Retrace"
    icon = "icons/retracer.png"
    priority = 20
    category = ""
    keywords = ["shadow", "gaussian"]

    inputs = [("Beam", ShadowBeam, "setBeam")]

    outputs = [{"name":"Beam",
                "type":ShadowBeam,
                "doc":"Shadow Beam",
                "id":"beam"},
               {"name":"Trigger",
                "type": TriggerIn,
                "doc":"Feedback signal to start a new beam simulation",
                "id":"Trigger"}]

    retrace_distance = Setting(0.0)

    input_beam = None

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

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

        button = gui.button(button_box, self, "Run Retrace", callback=self.retrace)
        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 = gui.button(button_box, self, "Reset Fields", callback=self.callResetSettings)
        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(150)

        gui.separator(self.controlArea)

        box = oasysgui.widgetBox(self.controlArea, "", orientation="vertical", width=self.CONTROL_AREA_WIDTH-5, height=550)

        main_box = oasysgui.widgetBox(box, "Shadow Beam Retrace", orientation="vertical", width=self.CONTROL_AREA_WIDTH-5, height=70)

        self.le_retrace_distance = oasysgui.lineEdit(main_box, self, "retrace_distance", "Retrace to ", labelWidth=280, valueType=float, orientation="horizontal")

    def setBeam(self, input_beam):
        if ShadowCongruence.checkEmptyBeam(input_beam):
            self.input_beam = input_beam

            if self.is_automatic_run:
                self.retrace()

    def after_change_workspace_units(self):
        label = self.le_retrace_distance.parent().layout().itemAt(0).widget()
        label.setText(label.text() + " [" + self.workspace_units_label + "]")

    def retrace(self):
        try:
            if not self.input_beam is None:
                output_beam = self.input_beam.duplicate(history=True)

                empty_element = ShadowOpticalElement.create_empty_oe()

                empty_element._oe.DUMMY = 1.0 # self.workspace_units_to_cm

                empty_element._oe.T_SOURCE     = 0.0
                empty_element._oe.T_IMAGE      = self.retrace_distance
                empty_element._oe.T_INCIDENCE  = 0.0
                empty_element._oe.T_REFLECTION = 180.0
                empty_element._oe.ALPHA        = 0.0

                empty_element._oe.FWRITE = 3
                empty_element._oe.F_ANGLE = 0

                output_beam = ShadowBeam.traceFromOE(output_beam, empty_element, history=True)

                self.setStatusMessage("Plotting Results")

                self.plot_results(output_beam)

                self.setStatusMessage("")
                self.progressBarFinished()

                self.send("Beam", output_beam)
                self.send("Trigger", TriggerIn(new_object=True))
        except Exception as exception:
            QMessageBox.critical(self, "Error", str(exception), QMessageBox.Ok)

            if self.IS_DEVELOP: raise exception
Example #30
0
class OWAperture(WPGWidget):
    name = "Aperture"
    id = "Aperture"
    description = "Aperture"
    icon = "icons/aperture.png"
    priority = 1
    category = ""
    keywords = ["wpg", "gaussian"]

    inputs = [("Input", WPGOutput, "set_input")]

    horApM1 = Setting(2.E-3)
    range_xy = Setting(2.E-3)  #CRL wall thickness [m])

    def build_gui(self):

        main_box = oasysgui.widgetBox(self.controlArea,
                                      "Aperture Input Parameters",
                                      orientation="vertical",
                                      width=self.CONTROL_AREA_WIDTH - 5,
                                      height=200)

        oasysgui.lineEdit(main_box,
                          self,
                          "horApM1",
                          "horApM1",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(main_box,
                          self,
                          "range_xy",
                          "range_xy",
                          labelWidth=260,
                          valueType=float,
                          orientation="horizontal")

    def after_change_workspace_units(self):
        pass

    def check_fields(self):
        congruence.checkPositiveNumber(self.horApM1, "horApM1")
        congruence.checkPositiveNumber(self.range_xy, "range_xy")

    def set_input(self, input_data):
        self.setStatusMessage("")

        if not input_data is None:
            self.input_data = input_data

            self.horApM1 = self.input_data.get_thetaOM() * 0.8
            self.range_xy = self.input_data.get_range_xy()

            if self.is_automatic_run: self.compute()

    def do_wpg_calculation(self):
        aperture = Aperture(shape='r',
                            ap_or_ob='a',
                            Dx=self.horApM1,
                            Dy=self.range_xy)

        wavefront = self.input_data.get_wavefront()

        beamline_for_propagation = Beamline()
        beamline_for_propagation.append(aperture, Use_PP())
        beamline_for_propagation.propagate(wavefront)

        return wavefront

    def extract_plot_data_from_calculation_output(self, calculation_output):
        self.reset_plotting()

        plot_wfront(calculation_output,
                    'at ' + str(self.input_data.get_total_distance()) + ' m',
                    False, False, 1e-5, 1e-5, 'x', False)

        return self.getFigureCanvas(1), \
               self.getFigureCanvas(2), \
               self.getFigureCanvas(3)

    def getTabTitles(self):
        return ["Intensity", "Vertical Cut", "Horizontal Cut"]

    def extract_wpg_output_from_calculation_output(self, calculation_output):
        return WPGOutput(thetaOM=self.input_data.get_thetaOM(),
                         range_xy=self.input_data.get_range_xy(),
                         wavefront=calculation_output,
                         total_distance=self.input_data.get_total_distance())