def plot_results(self, beam_out, 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():
                        beam_foot_print = ShadowBeam()
                        if beam_out._oe_number < 10:
                            beam_foot_print.loadFromFile(file_name="mirr.0" + str(beam_out._oe_number))
                        else:
                            beam_foot_print.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(beam_foot_print, 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(beam_foot_print, 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:
                        self.view_type_combo.setEnabled(True)

                        raise Exception("Data not plottable: No good rays or bad content")

                    self.view_type_combo.setEnabled(True)
                else:
                    raise Exception("Beam with no good rays")
            else:
                raise Exception("Empty Beam")

        self.plotted_beam = beam_out
Exemple #2
0
    def clearResults(self, interactive=True):
        if not interactive: proceed = True
        else: proceed = ConfirmDialog.confirmed(parent=self)

        if proceed:
            self.input_beam = ShadowBeam()
            self.cumulated_ticket = None
            self.plotted_ticket = None
            self.autosave_prog_id = 0
            if not self.autosave_file is None:
                self.autosave_file.close()
                self.autosave_file = None

            self.plot_canvas.clear()
 def clearResults(self):
     if ConfirmDialog.confirmed(parent=self):
         self.input_beam = ShadowBeam()
         self.plot_canvas.clear()
         return True
     else:
         return False
Exemple #4
0
    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
    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 runShadowSource(self):
        self.setStatusMessage("")
        self.progressBarInit()

        try:
            self.checkFields()

            ###########################################
            # TODO: TO BE ADDED JUST IN CASE OF BROKEN
            #       ENVIRONMENT: MUST BE FOUND A PROPER WAY
            #       TO TEST SHADOW
            self.fixWeirdShadowBug()
            ###########################################

            shadow_src = ShadowSource.create_bm_src()

            self.populateFields(shadow_src)

            self.progressBarSet(10)

            self.setStatusMessage("Running SHADOW")

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

            self.progressBarSet(50)

            write_begin_file, write_start_file, write_end_file = self.get_write_file_options(
            )

            beam_out = ShadowBeam.traceFromSource(
                shadow_src,
                write_begin_file=write_begin_file,
                write_start_file=write_start_file,
                write_end_file=write_end_file,
                widget_class_name=self.__class__.name)

            if self.trace_shadow:
                grabber.stop()

                for row in grabber.ttyData:
                    self.writeStdOut(row)

            self.setStatusMessage("Plotting Results")

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

            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 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)

        self.send("Beam", merged_beam)
Exemple #8
0
    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 setBeam(self, beam):
        if ShadowGui.checkEmptyBeam(beam):
            proceed = True

            if not ShadowGui.checkGoodBeam(beam):
                if not ConfirmDialog.confirmed(parent=self, message="Beam contains bad values, skip it?"):
                    proceed = False

            if proceed:
                go = numpy.where(beam.beam.rays[:, 9] == 1)

                self.current_number_of_rays = self.current_number_of_rays + len(beam.beam.rays[go])

                if self.current_number_of_rays <= self.number_of_accumulated_rays:
                    if self.keep_go_rays == 1:
                        beam.beam.rays = copy.deepcopy(beam.beam.rays[go])

                    if not self.input_beam is None:
                        self.input_beam = ShadowBeam.mergeBeams(self.input_beam, beam)
                    else:
                        self.input_beam = beam

                    self.send("Trigger", ShadowTriggerIn(new_beam=True))
                else:
                    if self.is_automatic_run:
                        self.sendSignal()

                        self.current_number_of_rays = 0
                        self.input_beam = None
                    else:
                        QtGui.QMessageBox.critical(self, "QMessageBox.critical()",
                                                   "Number of Accumulated Rays reached, please push \'Send Signal\' button",
                                                   QtGui.QMessageBox.Ok)
Exemple #10
0
    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)

        self.send("Beam", merged_beam)
    def replace_spectro_fig(self, rays_to_plot, var_x, factor_x, xrange, title,
                            color):
        try:
            beam = ShadowBeam()
            beam._beam.rays = rays_to_plot

            ticket = beam._beam.histo1(var_x,
                                       nbins=self.number_of_bins,
                                       xrange=xrange,
                                       nolost=self.rays,
                                       ref=self.weight_column_index)

            if self.weight_column_index != 0:
                self.spectro_plot_canvas.setGraphYLabel(
                    "Number of rays weighted by " +
                    ShadowPlot.get_shadow_label(self.weight_column_index))
            else:
                self.spectro_plot_canvas.setGraphYLabel("Number of Rays")

            histogram = ticket['histogram_path']
            bins = ticket['bin_path'] * factor_x

            self.spectro_plot_canvas.addCurve(bins,
                                              histogram,
                                              title,
                                              symbol='',
                                              color=color,
                                              replace=False)  #'+', '^', ','
        except Exception as e:
            print(e)
            raise Exception("Data not plottable: No good rays or bad content")
Exemple #12
0
    def convertMapToBeam(self, map):

        number_of_rays = len(map)

        if number_of_rays == 0: return None

        beam_out = ShadowBeam(number_of_rays=number_of_rays)

        for index in range(0, number_of_rays):
            point = map[index]

            ray = beam_out._beam.rays[index]

            E_value = numpy.sqrt(point.value * 0.5)

            ray[0] = point.x  # X
            ray[1] = point.y  # Y
            ray[2] = point.z  # Z
            ray[3] = 0  # director cos x
            ray[4] = 1  # director cos y
            ray[5] = 0  # director cos z
            ray[6] = 0  # Es_x
            ray[7] = E_value  # Es_y
            ray[8] = 0  # Es_z
            ray[9] = 1  # good/lost
            ray[10] = 2 * numpy.pi / 1.5e-8
            ray[11] = index  # ray index
            ray[12] = 1  # good only
            ray[13] = numpy.pi * 0.5  # Es_phi
            ray[14] = numpy.pi * 0.5  # Ep_phi
            ray[15] = 0  # Ep_x
            ray[16] = E_value  # Ep_y
            ray[17] = 0  # Ep_z

        return beam_out
    def setBeam(self, beam):
        if ShadowCongruence.checkEmptyBeam(beam):
            proceed = True

            if not ShadowCongruence.checkGoodBeam(beam):
                if not ConfirmDialog.confirmed(
                        parent=self,
                        message="Beam contains bad values, skip it?"):
                    proceed = False

            if proceed:
                scanned_variable_data = beam.scanned_variable_data

                go = numpy.where(beam._beam.rays[:, 9] == 1)

                nr_good = len(beam._beam.rays[go])
                nr_total = len(beam._beam.rays)
                nr_lost = nr_total - nr_good
                intensity = beam._beam.histo1(1, nolost=1, ref=23)['intensity']

                self.current_number_of_rays += nr_good
                self.current_intensity += intensity
                self.le_current_intensity.setText("{:10.3f}".format(
                    self.current_intensity))
                self.current_number_of_lost_rays += nr_lost
                self.current_number_of_total_rays += nr_total

                if (self.kind_of_accumulation == 0 and self.current_number_of_rays <= self.number_of_accumulated_rays) or \
                   (self.kind_of_accumulation == 1 and self.current_intensity <= self.number_of_accumulated_rays):
                    if self.keep_go_rays == 1:
                        beam._beam.rays = copy.deepcopy(beam._beam.rays[go])

                    if not self.input_beam is None:
                        self.input_beam = ShadowBeam.mergeBeams(
                            self.input_beam, beam)
                    else:
                        beam._beam.rays[:, 11] = numpy.arange(
                            1,
                            len(beam._beam.rays) + 1, 1)  # ray_index
                        self.input_beam = beam

                    self.input_beam.setScanningData(scanned_variable_data)

                    self.send("Trigger", TriggerIn(new_object=True))
                else:
                    if self.is_automatic_run:
                        self.sendSignal()

                        self.current_number_of_rays = 0
                        self.current_intensity = 0.0
                        self.current_number_of_lost_rays = 0
                        self.current_number_of_total_rays = 0
                        self.input_beam = None
                    else:
                        QtWidgets.QMessageBox.critical(
                            self, "Error",
                            "Number of Accumulated Rays reached, please push \'Send Signal\' button",
                            QtWidgets.QMessageBox.Ok)
Exemple #14
0
    def get_zone_plate_beam(self):       # WS Units

        empty_element = ShadowOpticalElement.create_empty_oe()

        empty_element._oe.DUMMY        = self.workspace_units_to_cm
        empty_element._oe.T_SOURCE     = self.source_plane_distance
        empty_element._oe.T_IMAGE      = 0.0
        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

        n_screen = 1
        i_screen = numpy.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
        i_abs = numpy.zeros(10)
        i_slit = numpy.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0])
        i_stop = numpy.zeros(10)
        k_slit = numpy.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0])
        thick = numpy.zeros(10)
        file_abs = numpy.array(['', '', '', '', '', '', '', '', '', ''])
        rx_slit = numpy.zeros(10)
        rz_slit = numpy.zeros(10)
        sl_dis = numpy.zeros(10)
        file_scr_ext = numpy.array(['', '', '', '', '', '', '', '', '', ''])
        cx_slit = numpy.zeros(10)
        cz_slit = numpy.zeros(10)

        sl_dis[0] = 0.0
        rx_slit[0] = self.diameter*1e-6/self.workspace_units_to_m
        rz_slit[0] = self.diameter*1e-6/self.workspace_units_to_m
        cx_slit[0] = 0.0
        cz_slit[0] = 0.0

        empty_element._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_scr_ext)

        output_beam = ShadowBeam.traceFromOE(self.input_beam, empty_element, history=True)

        go = numpy.where(output_beam._beam.rays[:, 9] == GOOD)
        lo = numpy.where(output_beam._beam.rays[:, 9] != GOOD)

        print("Zone Plate Beam: ", "GO", len(go[0]), "LO", len(lo[0]))

        return output_beam
Exemple #15
0
 def convert_wavefront(self):
     try:
         if not self.wavefront is None:
             self.send(
                 "ShadowBeam",
                 ShadowBeam(beam=SHADOW3Wavefront.fromGenericWavefront(
                     wavefront=self.wavefront,
                     shadow_to_meters=self.workspace_units_to_m)))
     except Exception as exception:
         QMessageBox.critical(self, "Error", str(exception), QMessageBox.Ok)
Exemple #16
0
def read_shadow_beam(shadow_beam, lost=False):
    cursor_go = np.where(shadow_beam._beam.rays[:, 9] == 1)

    image_beam_rays = copy.deepcopy(shadow_beam._beam.rays[cursor_go])
    image_beam_rays[:, 11] = np.arange(1, len(image_beam_rays) + 1, 1)

    out_beam_go = ShadowBeam()
    out_beam_go._beam.rays = image_beam_rays

    if lost:
        cursor_lo = np.where(shadow_beam._beam.rays[:, 9] != 1)

        lost_rays = copy.deepcopy(shadow_beam._beam.rays[cursor_lo])
        lost_rays[:, 11] = np.arange(1, len(lost_rays) + 1, 1)

        out_beam_lo = ShadowBeam()
        out_beam_lo._beam.rays = lost_rays

        return out_beam_go, out_beam_lo
    else:
        return out_beam_go
Exemple #17
0
    def setBeam(self, beam):
        if ShadowCongruence.checkEmptyBeam(beam):
            if ShadowCongruence.checkGoodBeam(beam):
                if self.keep_result == 1 and not self.input_beam is None:
                    self.input_beam = ShadowBeam.mergeBeams(self.input_beam, beam)
                else:
                    self.input_beam = beam

                if self.is_automatic_run:
                    self.plot_results()
            else:
                QtGui.QMessageBox.critical(self, "Error",
                                           "Data not displayable: No good rays, bad content, bad limits or axes",
                                           QtGui.QMessageBox.Ok)
    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 setBeam(self, beam):
        if ShadowCongruence.checkEmptyBeam(beam):
            proceed = True

            if not ShadowCongruence.checkGoodBeam(beam):
                if not ConfirmDialog.confirmed(parent=self, message="Beam contains bad values, skip it?"):
                    proceed = False

            if proceed:
                go = numpy.where(beam._beam.rays[:, 9] == 1)

                nr_good = len(beam._beam.rays[go])
                nr_total = len(beam._beam.rays)
                nr_lost = nr_total - nr_good
                intensity = beam._beam.histo1(1, nolost=1, ref=23)['intensity']

                self.current_number_of_rays += nr_good
                self.current_intensity += intensity
                self.le_current_intensity.setText("{:10.3f}".format(self.current_intensity))
                self.current_number_of_lost_rays += nr_lost
                self.current_number_of_total_rays += nr_total



                if (self.kind_of_accumulation == 0 and self.current_number_of_rays <= self.number_of_accumulated_rays) or \
                   (self.kind_of_accumulation == 1 and self.current_intensity <= self.number_of_accumulated_rays):
                    if self.keep_go_rays == 1:
                        beam._beam.rays = copy.deepcopy(beam._beam.rays[go])

                    if not self.input_beam is None:
                        self.input_beam = ShadowBeam.mergeBeams(self.input_beam, beam)
                    else:
                        beam._beam.rays[:, 11] = numpy.arange(1, len(beam._beam.rays) + 1, 1) # ray_index
                        self.input_beam = beam

                    self.send("Trigger", ShadowTriggerIn(new_beam=True))
                else:
                    if self.is_automatic_run:
                        self.sendSignal()

                        self.current_number_of_rays = 0
                        self.current_intensity = 0.0
                        self.current_number_of_lost_rays = 0
                        self.current_number_of_total_rays = 0
                        self.input_beam = None
                    else:
                        QtGui.QMessageBox.critical(self, "Error",
                                                   "Number of Accumulated Rays reached, please push \'Send Signal\' button",
                                                   QtGui.QMessageBox.Ok)
Exemple #20
0
    def get_output_beam(self, focused_beam):

        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.image_plane_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

        return ShadowBeam.traceFromOE(focused_beam, empty_element, history=True)
Exemple #21
0
    def sendNewBeam(self, trigger):
        self.scanning_data = None

        if trigger and trigger.new_object == True:
            if trigger.has_additional_parameter("seed_increment"):
                self.seed += trigger.get_additional_parameter("seed_increment")
            elif trigger.has_additional_parameter(
                    "variable_name") and self.is_scanning_enabled():
                variable_name = trigger.get_additional_parameter(
                    "variable_name").strip()
                variable_display_name = trigger.get_additional_parameter(
                    "variable_display_name").strip()
                variable_value = trigger.get_additional_parameter(
                    "variable_value")
                variable_um = trigger.get_additional_parameter("variable_um")

                def check_number(x):
                    try:
                        return float(x)
                    except:
                        return x

                if "," in variable_name:
                    variable_names = variable_name.split(",")

                    if isinstance(variable_value,
                                  str) and "," in variable_value:
                        variable_values = variable_value.split(",")
                        for variable_name, variable_value in zip(
                                variable_names, variable_values):
                            setattr(self, variable_name.strip(),
                                    check_number(variable_value))
                            self.check_source_options(variable_name)
                    else:
                        for variable_name in variable_names:
                            setattr(self, variable_name.strip(),
                                    check_number(variable_value))
                            self.check_source_options(variable_name)
                else:
                    setattr(self, variable_name, check_number(variable_value))
                    self.check_source_options(variable_name)

                self.scanning_data = ShadowBeam.ScanningData(
                    variable_name, variable_value, variable_display_name,
                    variable_um)

            self.runShadowSource()
    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()
        ###########################################

        write_start_files, write_end_files, write_star_files, write_mirr_files = self.get_write_file_options(
        )

        beam_out = ShadowBeam.traceFromCompoundOE(
            self.input_beam,
            shadow_oe,
            write_start_files=write_start_files,
            write_end_files=write_end_files,
            write_star_files=write_star_files,
            write_mirr_files=write_mirr_files,
            widget_class_name=type(self).__name__)

        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", TriggerIn(new_object=True))
    def setBeam(self, beam):
        if ShadowGui.checkEmptyBeam(beam):
            if ShadowGui.checkGoodBeam(beam):
                if self.keep_result == 1 and not self.input_beam is None:
                    self.input_beam = ShadowBeam.mergeBeams(self.input_beam, beam)
                else:
                    self.input_beam = beam

                if ShadowGui.checkEmptyBeam(self.input_beam):
                    if (self.input_beam.oe_number == 0):  # IS THE SOURCE
                        self.image_plane = 0
                        self.set_ImagePlane()
                        self.image_plane_combo.setEnabled(False)

                if self.is_automatic_run:
                    self.plot_results()
            else:
                QtGui.QMessageBox.critical(self, "QMessageBox.critical()",
                                           "Data not displayable: No good rays or bad content",
                                           QtGui.QMessageBox.Ok)
    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()
        ###########################################

        write_start_files, write_end_files, write_star_files, write_mirr_files = self.get_write_file_options()

        beam_out = ShadowBeam.traceFromCompoundOE(self.input_beam,
                                                  shadow_oe,
                                                  write_start_files=write_start_files,
                                                  write_end_files=write_end_files,
                                                  write_star_files=write_star_files,
                                                  write_mirr_files=write_mirr_files,
                                                  widget_class_name=type(self).__name__
                                                  )

        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 convertMapToBeam(self, x0s, x1s):

        number_of_rays = x0s.size

        if number_of_rays == 0: return None

        beam_out = ShadowBeam(number_of_rays=number_of_rays)

        x = x0s - self.image_nparray.shape[0] / 2
        z = x1s - self.image_nparray.shape[1] / 2

        x *= self.pixel_size * 1e-6 / self.workspace_units_to_m
        z *= self.pixel_size * 1e-6 / self.workspace_units_to_m

        for index in range(0, number_of_rays):

            ray = beam_out._beam.rays[index]

            ray[0] = x[index]  # X
            ray[1] = 0.0  # Y
            ray[2] = z[index]  # Z
            ray[3] = 0  # director cos x
            ray[4] = 1  # director cos y
            ray[5] = 0  # director cos z
            ray[6] = 1.0 / numpy.sqrt(2)  # Es_x
            ray[7] = 0.0  # Es_y
            ray[8] = 0.0  # Es_z
            ray[9] = 1  # good/lost
            ray[10] = 2 * numpy.pi / 1e-8  # wavenumber
            ray[11] = index  # ray index
            ray[12] = 1  # good only
            ray[13] = 0.0  # Es_phi
            ray[14] = 0.0  # Ep_phi
            ray[15] = 0.0  # Ep_x
            ray[16] = 0.0  # Ep_y
            ray[17] = 1.0 / numpy.sqrt(2)  # Ep_z

        return beam_out
Exemple #26
0
    def setBeam(self, input_beam):
        if input_beam.scanned_variable_data and input_beam.scanned_variable_data.has_additional_parameter("photon_energy_step"):

            photon_energy      = input_beam.scanned_variable_data.get_scanned_variable_value()
            photon_energy_step = input_beam.scanned_variable_data.get_additional_parameter("photon_energy_step")

            if input_beam.scanned_variable_data.has_additional_parameter("intensity_arrays") and self.redo_calculation == 0:
                h_array, v_array, intensity_array = input_beam.scanned_variable_data.get_additional_parameter("intensity_arrays")

                total_power = self.calculate_power(h_array, v_array, intensity_array, photon_energy_step)
            else:
                total_power = self.calc2d_srw(photon_energy, photon_energy_step, input_beam.scanned_variable_data)

            additional_parameters = {}
            additional_parameters["total_power"] = total_power
            additional_parameters["photon_energy_step"] = photon_energy_step

            input_beam.setScanningData(ShadowBeam.ScanningData(input_beam.scanned_variable_data.get_scanned_variable_name(),
                                                               photon_energy,
                                                               input_beam.scanned_variable_data.get_scanned_variable_display_name(),
                                                               input_beam.scanned_variable_data.get_scanned_variable_um(),
                                                               additional_parameters))

        self.send("Beam", input_beam)
Exemple #27
0
    def read_file(self):
        self.setStatusMessage("")

        try:
            if congruence.checkFileName(self.beam_file_name):
                beam_out = ShadowBeam()
                beam_out.loadFromFile(self.beam_file_name)
                beam_out.history.append(ShadowOEHistoryItem())  # fake Source
                beam_out._oe_number = 0

                # just to create a safe history for possible re-tracing
                beam_out.traceFromOE(beam_out,
                                     self.create_dummy_oe(),
                                     history=True)

                path, file_name = os.path.split(self.beam_file_name)

                self.setStatusMessage("Current: " + file_name)

                self.send("Beam", beam_out)
        except Exception as exception:
            QtWidgets.QMessageBox.critical(self, "Error", str(exception),
                                           QtWidgets.QMessageBox.Ok)
    def read_file(self):
        self.setStatusMessage("")

        try:
            if congruence.checkFileName(self.beam_file_name):
                beam_out = ShadowBeam()
                beam_out.loadFromFile(self.beam_file_name)
                beam_out.history.append(ShadowOEHistoryItem()) # fake Source
                beam_out._oe_number = 0

                # just to create a safe history for possible re-tracing
                beam_out.traceFromOE(beam_out, self.create_dummy_oe(), history=True)

                path, file_name = os.path.split(self.beam_file_name)

                self.setStatusMessage("Current: " + file_name)

                self.send("Beam", beam_out)
        except Exception as exception:
            QtGui.QMessageBox.critical(self, "Error",
                                       str(exception), QtGui.QMessageBox.Ok)
Exemple #29
0
class Histogram(ow_automatic_element.AutomaticElement):

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

    inputs = [("Input Beam", ShadowBeam, "setBeam")]

    IMAGE_WIDTH = 878
    IMAGE_HEIGHT = 635

    want_main_area = 1
    plot_canvas = None
    input_beam = None

    image_plane = Setting(0)
    image_plane_new_position = Setting(10.0)
    image_plane_rel_abs_position = Setting(0)

    x_column_index = Setting(10)

    x_range = Setting(0)
    x_range_min = Setting(0.0)
    x_range_max = Setting(0.0)

    weight_column_index = Setting(23)
    rays = Setting(1)

    number_of_bins = Setting(100)

    title = Setting("Energy")

    autosave = Setting(0)
    autosave_file_name = Setting("autosave_histogram_plot.hdf5")

    keep_result = Setting(0)
    autosave_partial_results = Setting(0)

    is_conversion_active = Setting(1)

    cumulated_ticket = None
    plotted_ticket = None
    autosave_file = None
    autosave_prog_id = 0

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

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

        gui.button(button_box,
                   self,
                   "Refresh",
                   callback=self.plot_results,
                   height=45)
        gui.button(button_box,
                   self,
                   "Save Current Plot",
                   callback=self.save_results,
                   height=45)

        gui.separator(self.controlArea, 10)

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

        # graph tab
        tab_set = oasysgui.createTabPage(self.tabs_setting, "Plot Settings")
        tab_gen = oasysgui.createTabPage(self.tabs_setting,
                                         "Histogram Settings")

        screen_box = oasysgui.widgetBox(tab_set,
                                        "Screen Position Settings",
                                        addSpace=True,
                                        orientation="vertical",
                                        height=120)

        self.image_plane_combo = gui.comboBox(
            screen_box,
            self,
            "image_plane",
            label="Position of the Image",
            items=["On Image Plane", "Retraced"],
            labelWidth=260,
            callback=self.set_ImagePlane,
            sendSelectedValue=False,
            orientation="horizontal")

        self.image_plane_box = oasysgui.widgetBox(screen_box,
                                                  "",
                                                  addSpace=False,
                                                  orientation="vertical",
                                                  height=50)
        self.image_plane_box_empty = oasysgui.widgetBox(screen_box,
                                                        "",
                                                        addSpace=False,
                                                        orientation="vertical",
                                                        height=50)

        oasysgui.lineEdit(self.image_plane_box,
                          self,
                          "image_plane_new_position",
                          "Image Plane new Position",
                          labelWidth=220,
                          valueType=float,
                          orientation="horizontal")

        gui.comboBox(self.image_plane_box,
                     self,
                     "image_plane_rel_abs_position",
                     label="Position Type",
                     labelWidth=250,
                     items=["Absolute", "Relative"],
                     sendSelectedValue=False,
                     orientation="horizontal")

        self.set_ImagePlane()

        general_box = oasysgui.widgetBox(tab_set,
                                         "General Settings",
                                         addSpace=True,
                                         orientation="vertical",
                                         height=250)

        self.x_column = gui.comboBox(
            general_box,
            self,
            "x_column_index",
            label="Column",
            labelWidth=70,
            items=[
                "1: X",
                "2: Y",
                "3: Z",
                "4: X'",
                "5: Y'",
                "6: Z'",
                "7: E\u03c3 X",
                "8: E\u03c3 Y",
                "9: E\u03c3 Z",
                "10: Ray Flag",
                "11: Energy",
                "12: Ray Index",
                "13: Optical Path",
                "14: Phase \u03c3",
                "15: Phase \u03c0",
                "16: E\u03c0 X",
                "17: E\u03c0 Y",
                "18: E\u03c0 Z",
                "19: Wavelength",
                "20: R = sqrt(X\u00b2 + Y\u00b2 + Z\u00b2)",
                "21: Theta (angle from Y axis)",
                "22: Magnitude = |E\u03c3| + |E\u03c0|",
                "23: Total Intensity = |E\u03c3|\u00b2 + |E\u03c0|\u00b2",
                "24: \u03a3 Intensity = |E\u03c3|\u00b2",
                "25: \u03a0 Intensity = |E\u03c0|\u00b2",
                "26: |K|",
                "27: K X",
                "28: K Y",
                "29: K Z",
                "30: S0-stokes = |E\u03c0|\u00b2 + |E\u03c3|\u00b2",
                "31: S1-stokes = |E\u03c0|\u00b2 - |E\u03c3|\u00b2",
                "32: S2-stokes = 2|E\u03c3||E\u03c0|cos(Phase \u03c3-Phase \u03c0)",
                "33: S3-stokes = 2|E\u03c3||E\u03c0|sin(Phase \u03c3-Phase \u03c0)",
                "34: Power = Intensity * Energy",
            ],
            sendSelectedValue=False,
            orientation="horizontal")

        gui.comboBox(general_box,
                     self,
                     "x_range",
                     label="X Range",
                     labelWidth=250,
                     items=["<Default>", "Set.."],
                     callback=self.set_XRange,
                     sendSelectedValue=False,
                     orientation="horizontal")

        self.xrange_box = oasysgui.widgetBox(general_box,
                                             "",
                                             addSpace=True,
                                             orientation="vertical",
                                             height=100)
        self.xrange_box_empty = oasysgui.widgetBox(general_box,
                                                   "",
                                                   addSpace=True,
                                                   orientation="vertical",
                                                   height=100)

        oasysgui.lineEdit(self.xrange_box,
                          self,
                          "x_range_min",
                          "X min",
                          labelWidth=220,
                          valueType=float,
                          orientation="horizontal")
        oasysgui.lineEdit(self.xrange_box,
                          self,
                          "x_range_max",
                          "X max",
                          labelWidth=220,
                          valueType=float,
                          orientation="horizontal")

        self.set_XRange()

        self.weight_column = gui.comboBox(
            general_box,
            self,
            "weight_column_index",
            label="Weight",
            labelWidth=70,
            items=[
                "0: No Weight",
                "1: X",
                "2: Y",
                "3: Z",
                "4: X'",
                "5: Y'",
                "6: Z'",
                "7: E\u03c3 X",
                "8: E\u03c3 Y",
                "9: E\u03c3 Z",
                "10: Ray Flag",
                "11: Energy",
                "12: Ray Index",
                "13: Optical Path",
                "14: Phase \u03c3",
                "15: Phase \u03c0",
                "16: E\u03c0 X",
                "17: E\u03c0 Y",
                "18: E\u03c0 Z",
                "19: Wavelength",
                "20: R = sqrt(X\u00b2 + Y\u00b2 + Z\u00b2)",
                "21: Theta (angle from Y axis)",
                "22: Magnitude = |E\u03c3| + |E\u03c0|",
                "23: Total Intensity = |E\u03c3|\u00b2 + |E\u03c0|\u00b2",
                "24: \u03a3 Intensity = |E\u03c3|\u00b2",
                "25: \u03a0 Intensity = |E\u03c0|\u00b2",
                "26: |K|",
                "27: K X",
                "28: K Y",
                "29: K Z",
                "30: S0-stokes = |E\u03c0|\u00b2 + |E\u03c3|\u00b2",
                "31: S1-stokes = |E\u03c0|\u00b2 - |E\u03c3|\u00b2",
                "32: S2-stokes = 2|E\u03c3||E\u03c0|cos(Phase \u03c3-Phase \u03c0)",
                "33: S3-stokes = 2|E\u03c3||E\u03c0|sin(Phase \u03c3-Phase \u03c0)",
                "34: Power = Intensity * Energy",
            ],
            sendSelectedValue=False,
            orientation="horizontal")

        gui.comboBox(general_box,
                     self,
                     "rays",
                     label="Rays",
                     labelWidth=250,
                     items=["All rays", "Good Only", "Lost Only"],
                     sendSelectedValue=False,
                     orientation="horizontal")

        autosave_box = oasysgui.widgetBox(tab_gen,
                                          "Autosave",
                                          addSpace=True,
                                          orientation="vertical",
                                          height=85)

        gui.comboBox(autosave_box,
                     self,
                     "autosave",
                     label="Save automatically plot into file",
                     labelWidth=250,
                     items=["No", "Yes"],
                     sendSelectedValue=False,
                     orientation="horizontal",
                     callback=self.set_autosave)

        self.autosave_box_1 = oasysgui.widgetBox(autosave_box,
                                                 "",
                                                 addSpace=False,
                                                 orientation="horizontal",
                                                 height=25)
        self.autosave_box_2 = oasysgui.widgetBox(autosave_box,
                                                 "",
                                                 addSpace=False,
                                                 orientation="horizontal",
                                                 height=25)

        self.le_autosave_file_name = oasysgui.lineEdit(
            self.autosave_box_1,
            self,
            "autosave_file_name",
            "File Name",
            labelWidth=100,
            valueType=str,
            orientation="horizontal")

        gui.button(self.autosave_box_1,
                   self,
                   "...",
                   callback=self.selectAutosaveFile)

        incremental_box = oasysgui.widgetBox(tab_gen,
                                             "Incremental Result",
                                             addSpace=True,
                                             orientation="vertical",
                                             height=120)

        gui.comboBox(incremental_box,
                     self,
                     "keep_result",
                     label="Keep Result",
                     labelWidth=250,
                     items=["No", "Yes"],
                     sendSelectedValue=False,
                     orientation="horizontal",
                     callback=self.set_autosave)

        self.cb_autosave_partial_results = gui.comboBox(
            incremental_box,
            self,
            "autosave_partial_results",
            label="Save partial plots into file",
            labelWidth=250,
            items=["No", "Yes"],
            sendSelectedValue=False,
            orientation="horizontal")

        gui.button(incremental_box, self, "Clear", callback=self.clearResults)

        histograms_box = oasysgui.widgetBox(tab_gen,
                                            "Histograms settings",
                                            addSpace=True,
                                            orientation="vertical",
                                            height=90)

        oasysgui.lineEdit(histograms_box,
                          self,
                          "number_of_bins",
                          "Number of Bins",
                          labelWidth=250,
                          valueType=int,
                          orientation="horizontal")

        gui.comboBox(histograms_box,
                     self,
                     "is_conversion_active",
                     label="Is U.M. conversion active",
                     labelWidth=250,
                     items=["No", "Yes"],
                     sendSelectedValue=False,
                     orientation="horizontal")

        self.set_autosave()

        self.main_tabs = oasysgui.tabWidget(self.mainArea)
        plot_tab = oasysgui.createTabPage(self.main_tabs, "Plots")
        out_tab = oasysgui.createTabPage(self.main_tabs, "Output")

        self.image_box = gui.widgetBox(plot_tab,
                                       "Plot Result",
                                       addSpace=True,
                                       orientation="vertical")
        self.image_box.setFixedHeight(self.IMAGE_HEIGHT)
        self.image_box.setFixedWidth(self.IMAGE_WIDTH)

        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 clearResults(self, interactive=True):
        if not interactive: proceed = True
        else: proceed = ConfirmDialog.confirmed(parent=self)

        if proceed:
            self.input_beam = ShadowBeam()
            self.cumulated_ticket = None
            self.plotted_ticket = None
            self.autosave_prog_id = 0
            if not self.autosave_file is None:
                self.autosave_file.close()
                self.autosave_file = None

            self.plot_canvas.clear()

    def set_XRange(self):
        self.xrange_box.setVisible(self.x_range == 1)
        self.xrange_box_empty.setVisible(self.x_range == 0)

    def set_ImagePlane(self):
        self.image_plane_box.setVisible(self.image_plane == 1)
        self.image_plane_box_empty.setVisible(self.image_plane == 0)

    def set_autosave(self):
        self.autosave_box_1.setVisible(self.autosave == 1)
        self.autosave_box_2.setVisible(self.autosave == 0)

        self.cb_autosave_partial_results.setEnabled(self.autosave == 1
                                                    and self.keep_result == 1)

    def selectAutosaveFile(self):
        self.le_autosave_file_name.setText(
            oasysgui.selectFileFromDialog(
                self,
                self.autosave_file_name,
                "Select File",
                file_extension_filter="HDF5 Files (*.hdf5 *.h5 *.hdf)"))

    def replace_fig(self, beam, var, xrange, title, xtitle, ytitle, xum):
        if self.plot_canvas is None:
            self.plot_canvas = ShadowPlot.DetailedHistoWidget(
                y_scale_factor=1.14)
            self.image_box.layout().addWidget(self.plot_canvas)

        try:
            if self.autosave == 1:
                if self.autosave_file is None:
                    self.autosave_file = ShadowPlot.HistogramHdf5File(
                        congruence.checkDir(self.autosave_file_name))
                elif self.autosave_file.filename != congruence.checkFileName(
                        self.autosave_file_name):
                    self.autosave_file.close()
                    self.autosave_file = ShadowPlot.HistogramHdf5File(
                        congruence.checkDir(self.autosave_file_name))

            if self.keep_result == 1:
                self.cumulated_ticket, last_ticket = self.plot_canvas.plot_histo(
                    beam,
                    var,
                    self.rays,
                    xrange,
                    self.weight_column_index,
                    title,
                    xtitle,
                    ytitle,
                    nbins=self.number_of_bins,
                    xum=xum,
                    conv=self.workspace_units_to_cm,
                    ticket_to_add=self.cumulated_ticket)

                self.plotted_ticket = self.cumulated_ticket

                if self.autosave == 1:
                    self.autosave_prog_id += 1
                    self.autosave_file.write_coordinates(self.cumulated_ticket)
                    dataset_name = self.weight_column.itemText(
                        self.weight_column_index)

                    self.autosave_file.add_histogram(self.cumulated_ticket,
                                                     dataset_name=dataset_name)

                    if self.autosave_partial_results == 1:
                        if last_ticket is None:
                            self.autosave_file.add_histogram(
                                self.cumulated_ticket,
                                plot_name="Histogram #" +
                                str(self.autosave_prog_id),
                                dataset_name=dataset_name)
                        else:
                            self.autosave_file.add_histogram(
                                last_ticket,
                                plot_name="Histogram #" +
                                str(self.autosave_prog_id),
                                dataset_name=dataset_name)

                    self.autosave_file.flush()
            else:
                ticket, _ = self.plot_canvas.plot_histo(
                    beam,
                    var,
                    self.rays,
                    xrange,
                    self.weight_column_index,
                    title,
                    xtitle,
                    ytitle,
                    nbins=self.number_of_bins,
                    xum=xum,
                    conv=self.workspace_units_to_cm)

                self.cumulated_ticket = None
                self.plotted_ticket = ticket

                if self.autosave == 1:
                    self.autosave_prog_id += 1
                    self.autosave_file.write_coordinates(ticket)
                    self.autosave_file.add_histogram(
                        ticket,
                        dataset_name=self.weight_column.itemText(
                            self.weight_column_index))
                    self.autosave_file.flush()

        except Exception as e:
            if not self.IS_DEVELOP:
                raise Exception(
                    "Data not plottable: No good rays or bad content")
            else:
                raise e

    def plot_histo(self, var_x, title, xtitle, ytitle, xum):
        beam_to_plot = self.input_beam._beam

        if self.image_plane == 1:
            new_shadow_beam = self.input_beam.duplicate(history=False)
            dist = 0.0

            if self.image_plane_rel_abs_position == 1:  # relative
                dist = self.image_plane_new_position
            else:  # absolute
                if self.input_beam.historySize() == 0:
                    historyItem = None
                else:
                    historyItem = self.input_beam.getOEHistory(
                        oe_number=self.input_beam._oe_number)

                if historyItem is None: image_plane = 0.0
                elif self.input_beam._oe_number == 0: image_plane = 0.0
                else: image_plane = historyItem._shadow_oe_end._oe.T_IMAGE

                dist = self.image_plane_new_position - image_plane

            self.retrace_beam(new_shadow_beam, dist)

            beam_to_plot = new_shadow_beam._beam

        xrange = self.get_range(beam_to_plot, var_x)

        self.replace_fig(beam_to_plot, var_x, xrange, title, xtitle, ytitle,
                         xum)

    def get_range(self, beam_to_plot, var_x):
        if self.x_range == 0:
            x_max = 0
            x_min = 0

            x, good_only = beam_to_plot.getshcol((var_x, 10))

            x_to_plot = copy.deepcopy(x)

            go = numpy.where(good_only == 1)
            lo = numpy.where(good_only != 1)

            if self.rays == 0:
                x_max = numpy.array(x_to_plot[0:], float).max()
                x_min = numpy.array(x_to_plot[0:], float).min()
            elif self.rays == 1:
                x_max = numpy.array(x_to_plot[go], float).max()
                x_min = numpy.array(x_to_plot[go], float).min()
            elif self.rays == 2:
                x_max = numpy.array(x_to_plot[lo], float).max()
                x_min = numpy.array(x_to_plot[lo], float).min()

            xrange = [x_min, x_max]
        else:
            congruence.checkLessThan(self.x_range_min, self.x_range_max,
                                     "X range min", "X range max")

            factor1 = ShadowPlot.get_factor(var_x, self.workspace_units_to_cm)

            xrange = [self.x_range_min / factor1, self.x_range_max / factor1]

        return xrange

    def save_results(self):
        if not self.plotted_ticket is None:
            try:
                file_name, _ = QtWidgets.QFileDialog.getSaveFileName(
                    self,
                    "Save Current Plot",
                    filter="HDF5 Files (*.hdf5 *.h5 *.hdf)")

                if not file_name is None and not file_name.strip() == "":
                    if not (file_name.endswith("hd5")
                            or file_name.endswith("hdf5")
                            or file_name.endswith("hdf")):
                        file_name += ".hdf5"

                    save_file = ShadowPlot.HistogramHdf5File(
                        congruence.checkDir(file_name))

                    save_file.write_coordinates(self.plotted_ticket)
                    dataset_name = self.weight_column.itemText(
                        self.weight_column_index)

                    save_file.add_histogram(self.plotted_ticket,
                                            dataset_name=dataset_name)

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

                if self.IS_DEVELOP: raise exception

    def plot_results(self):
        try:
            plotted = False

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

            if self.trace_shadow:
                grabber = TTYGrabber()
                grabber.start()

            if ShadowCongruence.checkEmptyBeam(self.input_beam):
                ShadowPlot.set_conversion_active(self.getConversionActive())

                self.number_of_bins = congruence.checkPositiveNumber(
                    self.number_of_bins, "Number of Bins")

                x, auto_title, xum = self.get_titles()

                self.plot_histo(x,
                                title=self.title,
                                xtitle=auto_title,
                                ytitle="Number of Rays",
                                xum=xum)

                plotted = True
            if self.trace_shadow:
                grabber.stop()

                for row in grabber.ttyData:
                    self.writeStdOut(row)

            time.sleep(
                0.5
            )  # prevents a misterious dead lock in the Orange cycle when refreshing the histogram

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

            if self.IS_DEVELOP: raise exception

    def get_titles(self):
        auto_title = self.x_column.currentText().split(":", 2)[1]

        xum = auto_title + " "
        self.title = auto_title
        x = self.x_column_index + 1

        if x == 1 or x == 2 or x == 3:
            if self.getConversionActive():
                xum = xum + "[" + u"\u03BC" + "m]"
                auto_title = auto_title + " [$\mu$m]"
            else:
                xum = xum + " [" + self.workspace_units_label + "]"
                auto_title = auto_title + " [" + self.workspace_units_label + "]"
        elif x == 4 or x == 5 or x == 6:
            if self.getConversionActive():
                xum = xum + "[" + u"\u03BC" + "rad]"
                auto_title = auto_title + " [$\mu$rad]"
            else:
                xum = xum + " [rad]"
                auto_title = auto_title + " [rad]"
        elif x == 11:
            xum = xum + "[eV]"
            auto_title = auto_title + " [eV]"
        elif x == 13:
            xum = xum + " [" + self.workspace_units_label + "]"
            auto_title = auto_title + " [" + self.workspace_units_label + "]"
        elif x == 14:
            xum = xum + "[rad]"
            auto_title = auto_title + " [rad]"
        elif x == 15:
            xum = xum + "[rad]"
            auto_title = auto_title + " [rad]"
        elif x == 19:
            xum = xum + "[Å]"
            auto_title = auto_title + " [Å]"
        elif x == 20:
            xum = xum + " [" + self.workspace_units_label + "]"
            auto_title = auto_title + " [" + self.workspace_units_label + "]"
        elif x == 21:
            xum = xum + "[rad]"
            auto_title = auto_title + " [rad]"
        elif x >= 25 and x <= 28:
            xum = xum + "[Å-1]"
            auto_title = auto_title + " [Å-1]"

        return x, auto_title, xum

    def setBeam(self, beam):
        if ShadowCongruence.checkEmptyBeam(beam):
            if ShadowCongruence.checkGoodBeam(beam):
                self.input_beam = beam

                if self.is_automatic_run:
                    self.plot_results()
            else:
                QtWidgets.QMessageBox.critical(
                    self, "Error",
                    "Data not displayable: No good rays or bad content",
                    QtWidgets.QMessageBox.Ok)

    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 retrace_beam(self, new_shadow_beam, dist):
        new_shadow_beam._beam.retrace(dist)

    def getConversionActive(self):
        return self.is_conversion_active == 1
    def calculate(self):
        beam_out = ShadowBeam()
        beam_out.loadFromFile(self.beam_file_name)

        self.send("Beam", beam_out)
class Histogram(ow_automatic_element.AutomaticElement):

    name = "Histogram"
    description = "Display Data Tools: Histogram"
    icon = "icons/histogram.png"
    maintainer = "Luca Rebuffi"
    maintainer_email = "luca.rebuffi(@at@)elettra.eu"
    priority = 2
    category = "Display Data Tools"
    keywords = ["data", "file", "load", "read"]

    inputs = [("Input Beam", ShadowBeam, "setBeam")]

    IMAGE_WIDTH = 1100
    IMAGE_HEIGHT = 650

    want_main_area=1
    plot_canvas=None
    input_beam=None

    image_plane=Setting(0)
    image_plane_new_position=Setting(10.0)
    image_plane_rel_abs_position=Setting(0)

    x_column_index=Setting(11)
    number_of_bins=Setting(100)

    title=Setting("Energy")

    keep_result=Setting(0)

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

        tabs_setting = gui.tabWidget(self.controlArea)
        tabs_setting.setFixedWidth(450)

        gui.button(self.controlArea, self, "Refresh", callback=self.plot_results)

        # graph tab
        tab_gen = ShadowGui.createTabPage(tabs_setting, "Histogram")

        incremental_box = ShadowGui.widgetBox(tab_gen, "Incremental Result", addSpace=True, orientation="horizontal", height=80)

        gui.checkBox(incremental_box, self, "keep_result", "Keep Result")
        gui.button(incremental_box, self, "Clear", callback=self.clearResults)

        general_box = ShadowGui.widgetBox(tab_gen, "General Settings", addSpace=True, orientation="vertical", height=250)

        self.image_plane_combo = gui.comboBox(general_box, self, "image_plane", label="Position of the Image",
                                              items=["On Image Plane", "Retraced"],
                                              callback=self.set_ImagePlane, sendSelectedValue=False, orientation="horizontal")


        self.image_plane_box = ShadowGui.widgetBox(general_box, "", addSpace=True, orientation="vertical", height=110)
        self.image_plane_box_empty = ShadowGui.widgetBox(general_box, "", addSpace=True, orientation="vertical", height=110)

        ShadowGui.lineEdit(self.image_plane_box, self, "image_plane_new_position", "Image Plane new Position", labelWidth=220, valueType=float, orientation="horizontal")

        gui.comboBox(self.image_plane_box, self, "image_plane_rel_abs_position", label="Position Type", labelWidth=250,
                     items=["Absolute", "Relative"], sendSelectedValue=False, orientation="horizontal")

        self.set_ImagePlane()

        self.x_column = gui.comboBox(general_box, self, "x_column_index", label="Column", labelWidth=80,
                                     items=["1: X",
                                            "2: Y",
                                            "3: Z",
                                            "4: X'",
                                            "5: Y'",
                                            "6: Z'",
                                            "7: Es X",
                                            "8: Es Y",
                                            "9: Es Z",
                                            "10: Ray Flag",
                                            "11: Energy",
                                            "12: Ray Index",
                                            "13: Optical Path",
                                            "14: Phase s",
                                            "15: Phase p",
                                            "16: Ep X",
                                            "17: Ep Y",
                                            "18: Ep Z",
                                            "19: Wavelength",
                                            "20: R = sqrt(X^2 + Y^2 + Z^2)",
                                            "21: Theta (angle from Y axis)",
                                            "22: Magnitude = |Es| + |Ep|",
                                            "23: Total Intensity = |Es|^2 + |Ep|^2",
                                            "24: S Intensity = |Es|^2",
                                            "25: P Intensity = |Ep|^2",
                                            "26: |K|",
                                            "27: K X",
                                            "28: K Y",
                                            "29: K Z",
                                            "30: S0-stokes = |Es|^2 + |Ep|^2",
                                            "31: S1-stokes = |Es|^2 - |Ep|^2",
                                            "32: S2-stokes = 2|Es||Ep|cos(Phase s-Phase p)",
                                            "33: S3-stokes = 2|Es||Ep|sin(Phase s-Phase p)",
                                     ],
                                     sendSelectedValue=False, orientation="horizontal")


        histograms_box = ShadowGui.widgetBox(tab_gen, "Histograms settings", addSpace=True, orientation="vertical", height=70)

        ShadowGui.lineEdit(histograms_box, self, "number_of_bins", "Number of Bins", labelWidth=250, valueType=int, orientation="horizontal")

        self.image_box = gui.widgetBox(self.mainArea, "Plot Result", addSpace=True, orientation="vertical")
        self.image_box.setFixedHeight(self.IMAGE_HEIGHT)
        self.image_box.setFixedWidth(self.IMAGE_WIDTH)

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

        out_box = gui.widgetBox(self.mainArea, "System Output", addSpace=True, orientation="horizontal")
        out_box.layout().addWidget(self.shadow_output)
        out_box.setFixedWidth(self.IMAGE_WIDTH)

        self.shadow_output.setFixedHeight(100)
        self.shadow_output.setFixedWidth(self.IMAGE_WIDTH-50)

    def clearResults(self):
        if ConfirmDialog.confirmed(parent=self):
            self.input_beam = ShadowBeam()
            self.plot_canvas.clear()

    def set_ImagePlane(self):
        self.image_plane_box.setVisible(self.image_plane==1)
        self.image_plane_box_empty.setVisible(self.image_plane==0)

    def replace_fig(self, beam, var, title, xtitle, ytitle, xum):
        if self.plot_canvas is None:
            self.plot_canvas = ShadowPlot.DetailedHistoWidget()
            self.image_box.layout().addWidget(self.plot_canvas)

        try:
            self.plot_canvas.plot_histo(beam, var, 1, None, 23, title, xtitle, ytitle, nbins=self.number_of_bins, xum=xum)
        except Exception:
            raise Exception("Data not plottable: No good rays or bad content")

    def plot_histo(self, var_x, title, xtitle, ytitle, xum):
        beam_to_plot = self.input_beam.beam

        if self.image_plane == 1:
            new_shadow_beam = self.input_beam.duplicate(history=False)

            historyItem = self.input_beam.getOEHistory(oe_number=self.input_beam.oe_number)
            if historyItem is None: raise Exception("Calculation impossible: Beam has no history")

            dist = 0.0

            if self.image_plane_rel_abs_position == 1:  # relative
                image_plane = 0.0

                if type(historyItem.shadow_oe_end) == ShadowOpticalElement:
                    image_plane = historyItem.shadow_oe_end.oe.T_IMAGE
                elif type(historyItem.shadow_oe_end) == ShadowCompoundOpticalElement:
                    image_plane = historyItem.shadow_oe_end.oe.list[historyItem.shadow_oe_end.oe.number_oe() - 1].T_IMAGE

                if self.image_plane_new_position < 0 and abs(self.image_plane_new_position) > image_plane:
                    raise Exception("Image plane new position cannot be before the O.E.")

                dist = self.image_plane_new_position
            else:  # absolute
                ShadowGui.checkPositiveNumber(self.image_plane_new_position, "Image Plane new Position")

                dist = self.image_plane_new_position - historyItem.shadow_oe_end.oe.T_IMAGE

            new_shadow_beam.beam.retrace(dist)

            beam_to_plot = new_shadow_beam.beam

        self.replace_fig(beam_to_plot, var_x, title, xtitle, ytitle, xum)

    def plot_results(self):
        self.error(self.error_id)

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

            if self.trace_shadow:
                grabber = TTYGrabber()
                grabber.start()

            if ShadowGui.checkEmptyBeam(self.input_beam):
                self.number_of_bins = ShadowGui.checkPositiveNumber(self.number_of_bins, "Number of Bins")

                auto_title = self.x_column.currentText().split(":", 2)[1]
                xum = auto_title + " "

                self.title = auto_title

                x = self.x_column_index + 1

                if x == 1 or x == 2 or x == 3:
                    xum = xum + "[" + u"\u03BC" + "m]"
                    auto_title = auto_title + " [$\mu$m]"
                elif x == 4 or x == 5 or x == 6:
                    xum = xum + "[" + u"\u03BC" + "rad]"
                    auto_title = auto_title + " [$\mu$rad]"
                elif x == 11:
                    xum = xum + "[eV]"
                    auto_title = auto_title + " [eV]"
                elif x == 13:
                    xum = xum + "[cm]"
                    auto_title = auto_title + " [cm]"
                elif x == 14:
                    xum = xum + "[rad]"
                    auto_title = auto_title + " [rad]"
                elif x == 15:
                    xum = xum + "[rad]"
                    auto_title = auto_title + " [rad]"
                elif x == 19:
                    xum = xum + "[Å]"
                    auto_title = auto_title + " [Å]"
                elif x == 20:
                    xum = xum + "[cm]"
                    auto_title = auto_title + " [cm]"
                elif x == 21:
                    xum = xum + "[rad]"
                    auto_title = auto_title + " [rad]"
                elif x >= 25 and x <= 28:
                    xum = xum + "[Å-1]"
                    auto_title = auto_title + " [Å-1]"

                self.plot_histo(x, title=self.title, xtitle=auto_title, ytitle="Number of Rays", xum=xum)

            if self.trace_shadow:
                grabber.stop()

                for row in grabber.ttyData:
                    self.writeStdOut(row)

            time.sleep(0.5)  # prevents a misterious dead lock in the Orange cycle when refreshing the histogram
        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))

    def setBeam(self, beam):
        if ShadowGui.checkEmptyBeam(beam):
            if ShadowGui.checkGoodBeam(beam):
                if self.keep_result == 1 and not self.input_beam is None:
                    self.input_beam = ShadowBeam.mergeBeams(self.input_beam, beam)
                else:
                    self.input_beam = beam

                if ShadowGui.checkEmptyBeam(self.input_beam):
                    if (self.input_beam.oe_number == 0):  # IS THE SOURCE
                        self.image_plane = 0
                        self.set_ImagePlane()
                        self.image_plane_combo.setEnabled(False)

                if self.is_automatic_run:
                    self.plot_results()
            else:
                QtGui.QMessageBox.critical(self, "QMessageBox.critical()",
                                           "Data not displayable: No good rays or bad content",
                                           QtGui.QMessageBox.Ok)


    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 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 runShadowSource(self):
        #self.error(self.error_id)
        self.setStatusMessage("")
        self.progressBarInit()

        try:
            self.checkFields()

            ###########################################
            # TODO: TO BE ADDED JUST IN CASE OF BROKEN
            #       ENVIRONMENT: MUST BE FOUND A PROPER WAY
            #       TO TEST SHADOW
            self.fixWeirdShadowBug()
            ###########################################

            shadow_src = ShadowSource.create_bm_src()

            self.populateFields(shadow_src)

            self.progressBarSet(10)

            #self.information(0, "Running SHADOW")
            self.setStatusMessage("Running SHADOW")

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

            self.progressBarSet(50)

            write_begin_file, write_start_file, write_end_file = self.get_write_file_options()

            beam_out = ShadowBeam.traceFromSource(shadow_src,
                                                  write_begin_file=write_begin_file,
                                                  write_start_file=write_start_file,
                                                  write_end_file=write_end_file)

            if self.trace_shadow:
                grabber.stop()

                for row in grabber.ttyData:
                   self.writeStdOut(row)

            #self.information(0, "Plotting Results")
            self.setStatusMessage("Plotting Results")

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

            #self.information()
            self.setStatusMessage("")

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

            #self.error_id = self.error_id + 1
            #self.error(self.error_id, "Exception occurred: " + str(exception))

        self.progressBarFinished()
Exemple #34
0
    def run_shadow4(self):

        nTrajPoints = 501

        #
        # syned
        #

        syned_electron_beam = self.get_syned_electron_beam()

        print(syned_electron_beam.info())

        # B from file
        if self.magnetic_field_source == 0:
            syned_wiggler = Wiggler(K_vertical=self.k_value,
                                    K_horizontal=0.0,
                                    period_length=self.id_period,
                                    number_of_periods=self.number_of_periods)
        elif self.magnetic_field_source == 1:
            syned_wiggler = MagneticStructure1DField.initialize_from_file(
                self.file_with_b_vs_y)
        elif self.magnetic_field_source == 2:
            raise Exception(NotImplemented)

        print(syned_wiggler.info())
        sw = SourceWiggler()

        sourcewiggler = SourceWiggler(name="test",
                                      syned_electron_beam=syned_electron_beam,
                                      syned_wiggler=syned_wiggler,
                                      flag_emittance=True,
                                      emin=self.e_min,
                                      emax=self.e_max,
                                      ng_e=100,
                                      ng_j=nTrajPoints)

        if self.e_min == self.e_max:
            sourcewiggler.set_energy_monochromatic(self.e_min)

        # sourcewiggler.set_electron_initial_conditions_by_label(velocity_label="value_at_zero",
        #                                                        position_label="value_at_zero",)

        sourcewiggler.set_electron_initial_conditions(
            shift_x_flag=self.shift_x_flag,
            shift_x_value=self.shift_x_value,
            shift_betax_flag=self.shift_betax_flag,
            shift_betax_value=self.shift_betax_value)

        # sourcewiggler.calculate_radiation()

        print(sourcewiggler.info())

        t00 = time.time()
        print(">>>> starting calculation...")
        rays = sourcewiggler.calculate_rays(NRAYS=self.n_rays)
        t11 = time.time() - t00
        print(">>>> time for %d rays: %f s, %f min, " %
              (self.n_rays, t11, t11 / 60))
        print(">>>   Results of calculate_radiation")
        print(">>>       trajectory.shape: ",
              sourcewiggler._result_trajectory.shape)
        print(">>>       cdf: ", sourcewiggler._result_cdf.keys())

        calculate_spectrum = True

        if calculate_spectrum:
            e, f, w = wiggler_spectrum(sourcewiggler._result_trajectory,
                                       enerMin=self.e_min,
                                       enerMax=self.e_max,
                                       nPoints=500,
                                       electronCurrent=self.ring_current,
                                       outFile="",
                                       elliptical=False)
            # from srxraylib.plot.gol import plot
            # plot(e, f, xlog=False, ylog=False, show=False,
            #      xtitle="Photon energy [eV]", ytitle="Flux [Photons/s/0.1%bw]", title="Flux")
            # plot(e, w, xlog=False, ylog=False, show=True,
            #      xtitle="Photon energy [eV]", ytitle="Spectral Power [E/eV]", title="Spectral Power")

        beam = Beam3.initialize_from_array(rays)

        #
        # wiggler plots
        #
        self.plot_widget_all(sourcewiggler, e, f, w)

        self.shadowoui_beam = ShadowBeam(oe_number=0,
                                         beam=beam,
                                         number_of_rays=0)

        self.plot_shadow_all()

        self.send("Beam", self.shadowoui_beam)
Exemple #35
0
shadow_src.src.VDIV2 = 1.0e-6

shadow_src.src.FSOURCE_DEPTH = 1  # OFF

shadow_src.src.F_COLOR = 1  # single value
shadow_src.src.F_PHOT = 0  # eV , 1 Angstrom

shadow_src.src.PH1 = 399.8

shadow_src.src.F_POLAR = 1
shadow_src.src.F_COHER = 0
shadow_src.src.POL_ANGLE = 0.0
shadow_src.src.POL_DEG = 1.0

shadow_src.src.F_OPD = 1
shadow_src.src.F_BOUND_SOUR = 0

print("Running SHADOW")

write_begin_file = 0
write_start_file = 0
write_end_file = 0

beam_out = ShadowBeam.traceFromSource(shadow_src,
                                      write_begin_file=write_begin_file,
                                      write_start_file=write_start_file,
                                      write_end_file=write_end_file)

fix_Intensity(shadow_src.src.F_POLAR, beam_out)

out_object = beam_out
Exemple #36
0
file_scr_ext = numpy.array(['', '', '', '', '', '', '', '', '', ''])
cx_slit = numpy.zeros(10)
cz_slit = numpy.zeros(10)

sl_dis[0] = 0.0
rx_slit[0] = diameter * 1e-4
rz_slit[0] = diameter * 1e-4
cx_slit[0] = 0.0
cz_slit[0] = 0.0

empty_element._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_scr_ext)

zone_plate_beam = ShadowBeam.traceFromOE(input_beam,
                                         empty_element,
                                         history=False)

go = numpy.where(zone_plate_beam._beam.rays[:, 9] == 1)

go_input_beam = ShadowBeam()
go_input_beam._beam.rays = copy.deepcopy(zone_plate_beam._beam.rays[go])

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

avg_wavelength = ShadowPhysics.getWavelengthFromShadowK(
    numpy.average(go_input_beam._beam.rays[:, 10])) * 1e-1  #ANGSTROM->nm

print("W", avg_wavelength, "nm")

focal_distance = (delta_rn * (1000 * diameter) / avg_wavelength) * 1e-7  # cm
Exemple #37
0
    def runShadowSource(self):
        #self.error(self.error_id)
        self.setStatusMessage("")
        self.progressBarInit()

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

        try:
            self.checkFields()

            ###########################################
            # TODO: TO BE ADDED JUST IN CASE OF BROKEN
            #       ENVIRONMENT: MUST BE FOUND A PROPER WAY
            #       TO TEST SHADOW
            self.fixWeirdShadowBug()
            ###########################################

            wigFile = bytes(congruence.checkFileName("xshwig.sha"), 'utf-8')

            if self.type_combo == 0:
                inData = ""
            elif self.type_combo == 1:
                inData = congruence.checkUrl(self.file_with_b_vs_y)
            elif self.type_combo == 2:
                inData = congruence.checkUrl(self.file_with_harmonics)

            self.progressBarSet(10)
            #self.information(0, "Calculate electron trajectory")

            self.shadow_output.setText("")

            self.setStatusMessage("Calculate electron trajectory")


            (traj, pars) = srfunc.wiggler_trajectory(b_from=self.type_combo,
                                                     inData=inData,
                                                     nPer=self.number_of_periods,
                                                     nTrajPoints=501,
                                                     ener_gev=self.energy,
                                                     per=self.id_period,
                                                     kValue=self.k_value,
                                                     trajFile=congruence.checkFileName("tmp.traj"),
                                                     shift_x_flag=self.shift_x_flag,
                                                     shift_x_value=self.shift_x_value,
                                                     shift_betax_flag=self.shift_betax_flag,
                                                     shift_betax_value=self.shift_betax_value)

            #
            # calculate cdf and write file for Shadow/Source
            #

            self.progressBarSet(20)
            #self.information(0, "Calculate cdf and write file for Shadow/Source")
            self.setStatusMessage("Calculate cdf and write file for Shadow/Source")

            srfunc.wiggler_cdf(traj,
                               enerMin=self.e_min,
                               enerMax=self.e_max,
                               enerPoints=1001,
                               outFile=wigFile,
                               elliptical=False)

            #self.information(0, "CDF written to file %s \n"%(wigFile))
            self.setStatusMessage("CDF written to file %s \n"%(str(wigFile)))

            self.progressBarSet(40)

            #self.information(0, "Set the wiggler parameters in the wiggler container")
            self.setStatusMessage("Set the wiggler parameters in the wiggler container")

            shadow_src = ShadowSource.create_wiggler_src()

            self.populateFields(shadow_src)

            shadow_src.src.FILE_TRAJ = wigFile


            self.progressBarSet(50)

            self.setStatusMessage("Running Shadow/Source")

            write_begin_file, write_start_file, write_end_file = self.get_write_file_options()

            beam_out = ShadowBeam.traceFromSource(shadow_src,
                                                  write_begin_file=write_begin_file,
                                                  write_start_file=write_start_file,
                                                  write_end_file=write_end_file)

            if self.trace_shadow:
                grabber.stop()

                for row in grabber.ttyData:
                   self.writeStdOut(row)

            #self.information(0, "Plotting Results")
            self.setStatusMessage("Plotting Results")

            self.progressBarSet(80)

            self.plot_results(beam_out, progressBarValue=80)

            self.setStatusMessage("Plotting Wiggler Data")

            self.plot_wiggler_results()

            #self.information()
            self.setStatusMessage("")

            self.send("Beam", beam_out)

            #
            # create python script for the preprocessors and display in the standard output
            #
            dict_parameters = {
                "b_from"               : self.type_combo,
                "inData"               : inData,
                "nPer"                 : self.number_of_periods,
                "nTrajPoints"          : 501,
                "ener_gev"             : self.energy,
                "per"                  : self.id_period,
                "kValue"               : self.k_value,
                "trajFile"             : "tmp.traj",
                "shift_x_flag"         : self.shift_x_flag,
                "shift_x_value"        : self.shift_x_value,
                "shift_betax_flag"     : self.shift_betax_flag,
                "shift_betax_value"    : self.shift_betax_value,
                "enerMin"              : self.e_min,
                "enerMax"              : self.e_max,
                "enerPoints"           : 1001,
                "outFile"              : wigFile,
                "elliptical"           : False,
                "electron_current_mA"  : self.electron_current,
            }

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

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

            #self.error_id = self.error_id + 1
            #self.error(self.error_id, "Exception occurred: " + str(exception))


        self.progressBarFinished()
Exemple #38
0
    def runShadowSource(self):
        #self.error(self.error_id)
        self.setStatusMessage("")
        self.progressBarInit()

        try:
            self.checkFields()

            ###########################################
            # TODO: TO BE ADDED JUST IN CASE OF BROKEN
            #       ENVIRONMENT: MUST BE FOUND A PROPER WAY
            #       TO TEST SHADOW
            self.fixWeirdShadowBug()
            ###########################################

            wigFile = bytes(congruence.checkFileName("xshwig.sha"), 'utf-8')

            if self.type_combo == 0:
                inData = ""
            elif self.type_combo == 1:
                inData = congruence.checkFileName(self.file_with_b_vs_y)
            elif self.type_combo == 2:
                inData = congruence.checkFileName(self.file_with_harmonics)

            self.progressBarSet(10)
            #self.information(0, "Calculate electron trajectory")
            self.setStatusMessage("Calculate electron trajectory")

            (traj, pars) = srfunc.wiggler_trajectory(b_from=self.type_combo,
                                                     inData=inData,
                                                     nPer=self.number_of_periods,
                                                     nTrajPoints=501,
                                                     ener_gev=self.energy,
                                                     per=self.id_period,
                                                     kValue=self.k_value,
                                                     trajFile=congruence.checkFileName("tmp.traj"),
                                                     shift_x_flag=self.shift_x_flag,
                                                     shift_x_value=self.shift_x_value,
                                                     shift_betax_flag=self.shift_betax_flag,
                                                     shift_betax_value=self.shift_betax_value)

            #
            # calculate cdf and write file for Shadow/Source
            #

            self.progressBarSet(20)
            #self.information(0, "Calculate cdf and write file for Shadow/Source")
            self.setStatusMessage("Calculate cdf and write file for Shadow/Source")

            srfunc.wiggler_cdf(traj,
                               enerMin=self.e_min,
                               enerMax=self.e_max,
                               enerPoints=1001,
                               outFile=wigFile,
                               elliptical=False)

            #self.information(0, "CDF written to file %s \n"%(wigFile))
            self.setStatusMessage("CDF written to file %s \n"%(str(wigFile)))

            self.progressBarSet(40)

            #self.information(0, "Set the wiggler parameters in the wiggler container")
            self.setStatusMessage("Set the wiggler parameters in the wiggler container")

            shadow_src = ShadowSource.create_wiggler_src()

            self.populateFields(shadow_src)

            shadow_src.src.FILE_TRAJ = wigFile

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

            self.progressBarSet(50)

            self.setStatusMessage("Running Shadow/Source")

            write_begin_file, write_start_file, write_end_file = self.get_write_file_options()

            beam_out = ShadowBeam.traceFromSource(shadow_src,
                                                  write_begin_file=write_begin_file,
                                                  write_start_file=write_start_file,
                                                  write_end_file=write_end_file)

            if self.trace_shadow:
                grabber.stop()

                for row in grabber.ttyData:
                   self.writeStdOut(row)

            #self.information(0, "Plotting Results")
            self.setStatusMessage("Plotting Results")

            self.progressBarSet(80)

            self.plot_results(beam_out, 80)

            self.setStatusMessage("Plotting Wiggler Data")

            self.plot_wiggler_results()

            #self.information()
            self.setStatusMessage("")

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

            #self.error_id = self.error_id + 1
            #self.error(self.error_id, "Exception occurred: " + str(exception))


        self.progressBarFinished()
    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())

            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()
Exemple #40
0
class Histogram(ow_automatic_element.AutomaticElement):

    name = "Histogram"
    description = "Display Data Tools: Histogram"
    icon = "icons/histogram.png"
    maintainer = "Luca Rebuffi"
    maintainer_email = "luca.rebuffi(@at@)elettra.eu"
    priority = 2
    category = "Display Data Tools"
    keywords = ["data", "file", "load", "read"]

    inputs = [("Input Beam", ShadowBeam, "setBeam")]

    IMAGE_WIDTH = 860
    IMAGE_HEIGHT = 640

    want_main_area = 1
    plot_canvas = None
    input_beam = None

    image_plane = Setting(0)
    image_plane_new_position = Setting(10.0)
    image_plane_rel_abs_position = Setting(0)

    x_column_index = Setting(10)

    x_range = Setting(0)
    x_range_min = Setting(0.0)
    x_range_max = Setting(0.0)

    weight_column_index = Setting(23)
    rays = Setting(1)

    number_of_bins = Setting(100)

    title = Setting("Energy")

    keep_result = Setting(0)

    is_conversion_active = Setting(1)

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

        gui.button(self.controlArea, self, "Refresh", callback=self.plot_results, height=45)
        gui.separator(self.controlArea, 10)

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

        # graph tab
        tab_set = oasysgui.createTabPage(self.tabs_setting, "Plot Settings")
        tab_gen = oasysgui.createTabPage(self.tabs_setting, "Histogram Settings")

        screen_box = oasysgui.widgetBox(
            tab_set, "Screen Position Settings", addSpace=True, orientation="vertical", height=110
        )

        self.image_plane_combo = gui.comboBox(
            screen_box,
            self,
            "image_plane",
            label="Position of the Image",
            items=["On Image Plane", "Retraced"],
            labelWidth=260,
            callback=self.set_ImagePlane,
            sendSelectedValue=False,
            orientation="horizontal",
        )

        self.image_plane_box = oasysgui.widgetBox(screen_box, "", addSpace=True, orientation="vertical", height=110)
        self.image_plane_box_empty = oasysgui.widgetBox(
            screen_box, "", addSpace=True, orientation="vertical", height=110
        )

        oasysgui.lineEdit(
            self.image_plane_box,
            self,
            "image_plane_new_position",
            "Image Plane new Position",
            labelWidth=220,
            valueType=float,
            orientation="horizontal",
        )

        gui.comboBox(
            self.image_plane_box,
            self,
            "image_plane_rel_abs_position",
            label="Position Type",
            labelWidth=250,
            items=["Absolute", "Relative"],
            sendSelectedValue=False,
            orientation="horizontal",
        )

        self.set_ImagePlane()

        general_box = oasysgui.widgetBox(tab_set, "General Settings", addSpace=True, orientation="vertical", height=250)

        self.x_column = gui.comboBox(
            general_box,
            self,
            "x_column_index",
            label="Column",
            labelWidth=70,
            items=[
                "1: X",
                "2: Y",
                "3: Z",
                "4: X'",
                "5: Y'",
                "6: Z'",
                "7: Es X",
                "8: Es Y",
                "9: Es Z",
                "10: Ray Flag",
                "11: Energy",
                "12: Ray Index",
                "13: Optical Path",
                "14: Phase s",
                "15: Phase p",
                "16: Ep X",
                "17: Ep Y",
                "18: Ep Z",
                "19: Wavelength",
                "20: R = sqrt(X^2 + Y^2 + Z^2)",
                "21: Theta (angle from Y axis)",
                "22: Magnitude = |Es| + |Ep|",
                "23: Total Intensity = |Es|^2 + |Ep|^2",
                "24: S Intensity = |Es|^2",
                "25: P Intensity = |Ep|^2",
                "26: |K|",
                "27: K X",
                "28: K Y",
                "29: K Z",
                "30: S0-stokes = |Ep|^2 + |Es|^2",
                "31: S1-stokes = |Ep|^2 - |Es|^2",
                "32: S2-stokes = 2|Es||Ep|cos(Phase s-Phase p)",
                "33: S3-stokes = 2|Es||Ep|sin(Phase s-Phase p)",
            ],
            sendSelectedValue=False,
            orientation="horizontal",
        )

        gui.comboBox(
            general_box,
            self,
            "x_range",
            label="X Range",
            labelWidth=250,
            items=["<Default>", "Set.."],
            callback=self.set_XRange,
            sendSelectedValue=False,
            orientation="horizontal",
        )

        self.xrange_box = oasysgui.widgetBox(general_box, "", addSpace=True, orientation="vertical", height=100)
        self.xrange_box_empty = oasysgui.widgetBox(general_box, "", addSpace=True, orientation="vertical", height=100)

        oasysgui.lineEdit(
            self.xrange_box, self, "x_range_min", "X min", labelWidth=220, valueType=float, orientation="horizontal"
        )
        oasysgui.lineEdit(
            self.xrange_box, self, "x_range_max", "X max", labelWidth=220, valueType=float, orientation="horizontal"
        )

        self.set_XRange()

        self.weight_column = gui.comboBox(
            general_box,
            self,
            "weight_column_index",
            label="Weight",
            labelWidth=70,
            items=[
                "0: No Weight",
                "1: X",
                "2: Y",
                "3: Z",
                "4: X'",
                "5: Y'",
                "6: Z'",
                "7: Es X",
                "8: Es Y",
                "9: Es Z",
                "10: Ray Flag",
                "11: Energy",
                "12: Ray Index",
                "13: Optical Path",
                "14: Phase s",
                "15: Phase p",
                "16: Ep X",
                "17: Ep Y",
                "18: Ep Z",
                "19: Wavelength",
                "20: R = sqrt(X^2 + Y^2 + Z^2)",
                "21: Theta (angle from Y axis)",
                "22: Magnitude = |Es| + |Ep|",
                "23: Total Intensity = |Es|^2 + |Ep|^2",
                "24: S Intensity = |Es|^2",
                "25: P Intensity = |Ep|^2",
                "26: |K|",
                "27: K X",
                "28: K Y",
                "29: K Z",
                "30: S0-stokes = |Ep|^2 + |Es|^2",
                "31: S1-stokes = |Ep|^2 - |Es|^2",
                "32: S2-stokes = 2|Es||Ep|cos(Phase s-Phase p)",
                "33: S3-stokes = 2|Es||Ep|sin(Phase s-Phase p)",
            ],
            sendSelectedValue=False,
            orientation="horizontal",
        )

        gui.comboBox(
            general_box,
            self,
            "rays",
            label="Rays",
            labelWidth=250,
            items=["All rays", "Good Only", "Lost Only"],
            sendSelectedValue=False,
            orientation="horizontal",
        )
        incremental_box = oasysgui.widgetBox(
            tab_gen, "Incremental Result", addSpace=True, orientation="horizontal", height=80
        )

        gui.checkBox(incremental_box, self, "keep_result", "Keep Result")
        gui.button(incremental_box, self, "Clear", callback=self.clearResults)

        histograms_box = oasysgui.widgetBox(
            tab_gen, "Histograms settings", addSpace=True, orientation="vertical", height=90
        )

        oasysgui.lineEdit(
            histograms_box,
            self,
            "number_of_bins",
            "Number of Bins",
            labelWidth=250,
            valueType=int,
            orientation="horizontal",
        )

        gui.comboBox(
            histograms_box,
            self,
            "is_conversion_active",
            label="Is U.M. conversion active",
            labelWidth=250,
            items=["No", "Yes"],
            sendSelectedValue=False,
            orientation="horizontal",
        )

        self.main_tabs = gui.tabWidget(self.mainArea)
        plot_tab = gui.createTabPage(self.main_tabs, "Plots")
        out_tab = gui.createTabPage(self.main_tabs, "Output")

        self.image_box = gui.widgetBox(plot_tab, "Plot Result", addSpace=True, orientation="vertical")
        self.image_box.setFixedHeight(self.IMAGE_HEIGHT)
        self.image_box.setFixedWidth(self.IMAGE_WIDTH)

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

        out_box = gui.widgetBox(out_tab, "System Output", addSpace=True, orientation="horizontal")
        out_box.layout().addWidget(self.shadow_output)

        self.shadow_output.setFixedHeight(600)
        self.shadow_output.setFixedWidth(600)

    def clearResults(self):
        if ConfirmDialog.confirmed(parent=self):
            self.input_beam = ShadowBeam()
            self.plot_canvas.clear()
            return True
        else:
            return False

    def set_XRange(self):
        self.xrange_box.setVisible(self.x_range == 1)
        self.xrange_box_empty.setVisible(self.x_range == 0)

    def set_ImagePlane(self):
        self.image_plane_box.setVisible(self.image_plane == 1)
        self.image_plane_box_empty.setVisible(self.image_plane == 0)

    def replace_fig(self, beam, var, xrange, title, xtitle, ytitle, xum):
        if self.plot_canvas is None:
            self.plot_canvas = ShadowPlot.DetailedHistoWidget(y_scale_factor=1.14)
            self.image_box.layout().addWidget(self.plot_canvas)

        try:
            self.plot_canvas.plot_histo(
                beam,
                var,
                self.rays,
                xrange,
                self.weight_column_index,
                title,
                xtitle,
                ytitle,
                nbins=self.number_of_bins,
                xum=xum,
                conv=self.workspace_units_to_cm,
            )
        except Exception:
            raise Exception("Data not plottable: No good rays or bad content")

    def plot_histo(self, var_x, title, xtitle, ytitle, xum):
        beam_to_plot = self.input_beam._beam

        if self.image_plane == 1:
            new_shadow_beam = self.input_beam.duplicate(history=False)
            dist = 0.0

            if self.image_plane_rel_abs_position == 1:  # relative
                dist = self.image_plane_new_position
            else:  # absolute
                historyItem = self.input_beam.getOEHistory(oe_number=self.input_beam._oe_number)

                if historyItem is None:
                    image_plane = 0.0
                elif self.input_beam._oe_number == 0:
                    image_plane = 0.0
                else:
                    image_plane = historyItem._shadow_oe_end._oe.T_IMAGE

                dist = self.image_plane_new_position - image_plane

            self.retrace_beam(new_shadow_beam, dist)

            beam_to_plot = new_shadow_beam._beam

        xrange = self.get_range(beam_to_plot, var_x)

        self.replace_fig(beam_to_plot, var_x, xrange, title, xtitle, ytitle, xum)

    def get_range(self, beam_to_plot, var_x):
        if self.x_range == 0:
            x_max = 0
            x_min = 0

            x, good_only = beam_to_plot.getshcol((var_x, 10))

            x_to_plot = copy.deepcopy(x)

            go = numpy.where(good_only == 1)
            lo = numpy.where(good_only != 1)

            if self.rays == 0:
                x_max = numpy.array(x_to_plot[0:], float).max()
                x_min = numpy.array(x_to_plot[0:], float).min()
            elif self.rays == 1:
                x_max = numpy.array(x_to_plot[go], float).max()
                x_min = numpy.array(x_to_plot[go], float).min()
            elif self.rays == 2:
                x_max = numpy.array(x_to_plot[lo], float).max()
                x_min = numpy.array(x_to_plot[lo], float).min()

            xrange = [x_min, x_max]
        else:
            if self.x_range_min >= self.x_range_max:
                raise Exception("X range min cannot be greater or equal than X range max")

            factor1 = ShadowPlot.get_factor(var_x, self.workspace_units_to_cm)

            xrange = [self.x_range_min / factor1, self.x_range_max / factor1]

        return xrange

    def plot_results(self):
        # self.error(self.error_id)

        try:
            plotted = False

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

            if self.trace_shadow:
                grabber = TTYGrabber()
                grabber.start()

            if ShadowCongruence.checkEmptyBeam(self.input_beam):
                ShadowPlot.set_conversion_active(self.getConversionActive())

                self.number_of_bins = congruence.checkPositiveNumber(self.number_of_bins, "Number of Bins")

                x, auto_title, xum = self.get_titles()

                self.plot_histo(x, title=self.title, xtitle=auto_title, ytitle="Number of Rays", xum=xum)

                plotted = True
            if self.trace_shadow:
                grabber.stop()

                for row in grabber.ttyData:
                    self.writeStdOut(row)

            time.sleep(0.5)  # prevents a misterious dead lock in the Orange cycle when refreshing the histogram

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

            # self.error_id = self.error_id + 1
            # self.error(self.error_id, "Exception occurred: " + str(exception))

            return False

    def get_titles(self):
        auto_title = self.x_column.currentText().split(":", 2)[1]

        xum = auto_title + " "
        self.title = auto_title
        x = self.x_column_index + 1

        if x == 1 or x == 2 or x == 3:
            if self.getConversionActive():
                xum = xum + "[" + u"\u03BC" + "m]"
                auto_title = auto_title + " [$\mu$m]"
            else:
                xum = xum + " [" + self.workspace_units_label + "]"
                auto_title = auto_title + " [" + self.workspace_units_label + "]"
        elif x == 4 or x == 5 or x == 6:
            if self.getConversionActive():
                xum = xum + "[" + u"\u03BC" + "rad]"
                auto_title = auto_title + " [$\mu$rad]"
            else:
                xum = xum + " [rad]"
                auto_title = auto_title + " [rad]"
        elif x == 11:
            xum = xum + "[eV]"
            auto_title = auto_title + " [eV]"
        elif x == 13:
            xum = xum + " [" + self.workspace_units_label + "]"
            auto_title = auto_title + " [" + self.workspace_units_label + "]"
        elif x == 14:
            xum = xum + "[rad]"
            auto_title = auto_title + " [rad]"
        elif x == 15:
            xum = xum + "[rad]"
            auto_title = auto_title + " [rad]"
        elif x == 19:
            xum = xum + "[Å]"
            auto_title = auto_title + " [Å]"
        elif x == 20:
            xum = xum + " [" + self.workspace_units_label + "]"
            auto_title = auto_title + " [" + self.workspace_units_label + "]"
        elif x == 21:
            xum = xum + "[rad]"
            auto_title = auto_title + " [rad]"
        elif x >= 25 and x <= 28:
            xum = xum + "[Å-1]"
            auto_title = auto_title + " [Å-1]"

        return x, auto_title, xum

    def setBeam(self, beam):
        if ShadowCongruence.checkEmptyBeam(beam):
            if ShadowCongruence.checkGoodBeam(beam):
                if self.keep_result == 1 and not self.input_beam is None:
                    self.input_beam = ShadowBeam.mergeBeams(self.input_beam, beam)
                else:
                    self.input_beam = beam

                if self.is_automatic_run:
                    self.plot_results()
            else:
                QtGui.QMessageBox.critical(
                    self, "Error", "Data not displayable: No good rays or bad content", QtGui.QMessageBox.Ok
                )

    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 retrace_beam(self, new_shadow_beam, dist):
        new_shadow_beam._beam.retrace(dist)

    def getConversionActive(self):
        return self.is_conversion_active == 1
    def calculate_footprint(self):
        self.setStatusMessage("")

        try:
            beam_out = self.footprint_beam.duplicate()
            beam_out.history.append(ShadowOEHistoryItem())  # fake Source
            beam_out._oe_number = 0

            # just to create a safe history for possible re-tracing
            beam_out.traceFromOE(beam_out,
                                 self.create_dummy_oe(),
                                 history=True)

            total_power = self.input_beam.scanned_variable_data.get_additional_parameter(
                "total_power")

            additional_parameters = {}
            additional_parameters["total_power"] = total_power
            additional_parameters[
                "photon_energy_step"] = self.input_beam.scanned_variable_data.get_additional_parameter(
                    "photon_energy_step")
            additional_parameters["is_footprint"] = True

            n_rays = len(beam_out._beam.rays[:, 0])  # lost and good!

            incident_beam = self.input_beam.getOEHistory(
                self.input_beam._oe_number)._input_beam

            ticket = incident_beam._beam.histo2(1,
                                                3,
                                                nbins=100,
                                                xrange=None,
                                                yrange=None,
                                                nolost=1,
                                                ref=23)
            ticket['histogram'] *= (total_power / n_rays)  # power

            additional_parameters["incident_power"] = ticket['histogram'].sum()

            if self.kind_of_power == 0:  # incident
                beam_out._beam.rays[:, 6] = incident_beam._beam.rays[:, 6]
                beam_out._beam.rays[:, 7] = incident_beam._beam.rays[:, 7]
                beam_out._beam.rays[:, 8] = incident_beam._beam.rays[:, 8]
                beam_out._beam.rays[:, 15] = incident_beam._beam.rays[:, 15]
                beam_out._beam.rays[:, 16] = incident_beam._beam.rays[:, 16]
                beam_out._beam.rays[:, 17] = incident_beam._beam.rays[:, 17]
            elif self.kind_of_power == 1:  # absorbed
                # need a trick: put the whole intensity of one single component

                incident_intensity = incident_beam._beam.rays[:, 6]**2 + incident_beam._beam.rays[:, 7]**2 + incident_beam._beam.rays[:, 8]**2 +\
                                     incident_beam._beam.rays[:, 15]**2 + incident_beam._beam.rays[:, 16]**2 + incident_beam._beam.rays[:, 17]**2
                transmitted_intensity = beam_out._beam.rays[:, 6]**2 + beam_out._beam.rays[:, 7]**2 + beam_out._beam.rays[:, 8]**2 +\
                                        beam_out._beam.rays[:, 15]**2 + beam_out._beam.rays[:, 16]**2 + beam_out._beam.rays[:, 17]**2

                electric_field = numpy.sqrt(incident_intensity -
                                            transmitted_intensity)
                electric_field[numpy.where(electric_field == numpy.nan)] = 0.0

                beam_out._beam.rays[:, 6] = electric_field
                beam_out._beam.rays[:, 7] = 0.0
                beam_out._beam.rays[:, 8] = 0.0
                beam_out._beam.rays[:, 15] = 0.0
                beam_out._beam.rays[:, 16] = 0.0
                beam_out._beam.rays[:, 17] = 0.0

            beam_out.setScanningData(
                ShadowBeam.ScanningData(
                    self.input_beam.scanned_variable_data.
                    get_scanned_variable_name(),
                    self.input_beam.scanned_variable_data.
                    get_scanned_variable_value(),
                    self.input_beam.scanned_variable_data.
                    get_scanned_variable_display_name(),
                    self.input_beam.scanned_variable_data.
                    get_scanned_variable_um(), additional_parameters))
            self.send("Beam", beam_out)
        except Exception as exception:
            QtWidgets.QMessageBox.critical(self, "Error", str(exception),
                                           QtWidgets.QMessageBox.Ok)
    def from_photon_bunch_to_shadow(self):

        photon_beam = self.incoming_bunch

        N = photon_beam.getArrayByKey("number of photons")
        energies = photon_beam.getArrayByKey("energies")
        S0 = photon_beam.getArrayByKey("s0")
        S1 = photon_beam.getArrayByKey("s1")
        S2 = photon_beam.getArrayByKey("s2")
        S3 = photon_beam.getArrayByKey("s3")
        vx = photon_beam.getArrayByKey("vx")
        vy = photon_beam.getArrayByKey("vy")
        vz = photon_beam.getArrayByKey("vz")

        beam = Shadow.Beam(N)
        A2EV = 2.0 * numpy.pi / (codata.h * codata.c / codata.e * 1e2)

        for i in range(N):
            s0 = S0[i]
            s1 = S1[i]
            s2 = S2[i]
            s3 = S3[i]
            energy = energies[i]

            if (numpy.abs(s1**2 + s2**2 + s3**2 - s0**2) > 1e-4):
                s0 = numpy.sqrt(s1**2 + s2**2 + s3**2)
                print("Warning: Beam is not fully polarized.")

            Ex2 = 0.5 * (s0 + s1)
            Ez2 = 0.5 * (s0 - s1)

            Ex = numpy.sqrt(Ex2)
            Ez = numpy.sqrt(Ez2)

            if s0 == s1:
                sin2delta = 0.0
            else:
                sin2delta = -0.5 * ((s2**2 - s3**2) / (4 * Ex2 * Ez2) - 1)

            delta = numpy.arcsin(numpy.sign(s3) * numpy.sqrt(sin2delta))
            beam.rays[i, 0] = 0.0  # x
            beam.rays[i, 1] = 0.0  # x
            beam.rays[i, 2] = 0.0  # x
            beam.rays[i, 3] = vx[i]  # v
            beam.rays[i, 4] = vy[i]  # v
            beam.rays[i, 5] = vz[i]  # v
            beam.rays[i, 6] = Ex  # Es
            beam.rays[i, 7] = 0.0  # Es
            beam.rays[i, 8] = 0.0  # Es
            beam.rays[i, 9] = 1.0  # lost ray flag
            beam.rays[i, 10] = A2EV * energy  # k
            beam.rays[i, 11] = i  # ray index
            beam.rays[i, 12] = 0.0  # path length
            beam.rays[i, 13] = 0.0  # phase-s
            beam.rays[i, 14] = delta  # phase-ps
            beam.rays[i, 15] = 0.0  # Ep
            beam.rays[i, 16] = 0.0  # Ep
            beam.rays[i, 17] = Ez  # Ep

        beam_out = ShadowBeam(beam=beam)

        beam_out.history.append(ShadowOEHistoryItem())  # fake Source
        beam_out._oe_number = 0

        # just to create a safe history for possible re-tracing
        beam_out.traceFromOE(beam_out, self.create_dummy_oe(), history=True)

        #self.send("Beam", beam_out)

        return beam_out
Exemple #43
0
    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.progressBarSet(10)

                    self.checkFields()

                    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()
                    ###########################################

                    shadow_oe_1 = ShadowOpticalElement.create_screen_slit()
                    self.populateFields_1(shadow_oe_1)

                    beam_out = ShadowBeam.traceFromOE(self.input_beam, shadow_oe_1)

                    self.adjust_first_divergence(beam_out)

                    self.progressBarSet(60)

                    shadow_oe_2 = ShadowOpticalElement.create_screen_slit()
                    self.populateFields_2(shadow_oe_2)

                    beam_out = ShadowBeam.traceFromOE(beam_out, shadow_oe_2)

                    self.adjust_second_divergence_and_intensity(beam_out)

                    self.progressBarSet(70)

                    shadow_oe_3 = ShadowOpticalElement.create_screen_slit()
                    self.populateFields_3(shadow_oe_3)

                    beam_out = ShadowBeam.traceFromOE(beam_out, shadow_oe_3)

                    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", TriggerIn(new_object=True))
                else:
                    raise Exception("Input Beam with no good rays")
            else:
                raise Exception("Empty Input Beam")

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

            self.error_id = self.error_id + 1
            self.error(self.error_id, "Exception occurred: " + str(exception))

        self.progressBarFinished()
Exemple #44
0
def sh_readsh(shfilename):
    image_beam = ShadowBeam()
    image_beam.loadFromFile(congruence.checkFile(shfilename))

    return read_shadow_beam(image_beam)
    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.progressBarSet(10)

                    self.checkFields()

                    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()
                    ###########################################

                    shadow_oe_1 = ShadowOpticalElement.create_screen_slit()
                    self.populateFields_1(shadow_oe_1)

                    beam_out = ShadowBeam.traceFromOE(self.input_beam, shadow_oe_1)

                    self.adjust_first_divergence(beam_out)

                    self.progressBarSet(60)

                    shadow_oe_2 = ShadowOpticalElement.create_screen_slit()
                    self.populateFields_2(shadow_oe_2)

                    beam_out = ShadowBeam.traceFromOE(beam_out, shadow_oe_2)

                    self.adjust_second_divergence_and_intensity(beam_out)

                    self.progressBarSet(70)

                    shadow_oe_3 = ShadowOpticalElement.create_screen_slit()
                    self.populateFields_3(shadow_oe_3)

                    beam_out = ShadowBeam.traceFromOE(beam_out, shadow_oe_3)

                    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))
                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()
        empty_element._oe.DUMMY = 1.0  # self.workspace_units_to_cm
        empty_element._oe.T_SOURCE = 0.0
        empty_element._oe.T_IMAGE = 0.0
        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
        return empty_element

    app = QApplication(sys.argv)
    w = PlotScatter()

    # load a Beam
    from orangecontrib.shadow.util.shadow_objects import ShadowOEHistoryItem
    beam_out = ShadowBeam()
    beam_out.loadFromFile("/home/manuel/Oasys/mirr.02")
    beam_out.history.append(ShadowOEHistoryItem())  # fake Source
    beam_out._oe_number = 0

    # just to create a safe history for possible re-tracing
    beam_out.traceFromOE(beam_out, create_dummy_oe(), history=True)

    w.workspace_units_to_cm = 1.0

    w.setBeam(beam_out)

    w.show()
    app.exec()
    w.saveSettings()