Ejemplo n.º 1
0
class LockinGui(object):
    _window_title = "Lock-in Spectrum"
    _heartbeat = 100  # ms delay at which the plot/gui is refreshed, and the gamepad moves the stage

    def __init__(self):
        self.savedir = "./Spectra/"
        self.path = "./"

        self.settings = Settings()

        self.x_step = .0
        self.y_step = .0
        self.step_distance = 1  # in um

        try:
            self.stage = PIStage.E545(self.settings.stage_ip,self.settings.stage_port)
        except:
            self.stage = None
            self.stage = PIStage.Dummy()
            print("Could not initialize PIStage, using Dummy instead")

        GObject.threads_init()
        # only GObject.idle_add() is in the background thread
        self.window = Gtk.Window(title=self._window_title)
        # self.window.set_resizable(False)
        self.window.set_border_width(3)

        self.grid = Gtk.Grid()
        self.grid.set_row_spacing(5)
        self.grid.set_column_spacing(5)
        self.window.add(self.grid)

        # Buttons for spectrum stack
        self.button_live = Gtk.Button(label="Liveview")
        self.button_live.set_tooltip_text("Start/Stop Liveview of Spectrum")
        self.button_stop = Gtk.Button(label="Stop")
        self.button_stop.set_tooltip_text("Stop any ongoing Action")
        self.button_stop.set_sensitive(False)
        self.button_aquire = Gtk.Button(label="Aquire Spectrum")
        self.button_aquire.set_tooltip_text("Start/Stop aquiring Lock-In Spectrum")
        self.button_direction = Gtk.Button(label="Set Direction")
        self.button_direction.set_tooltip_text("Set Direction of Stage Movement")
        self.button_settings = Gtk.Button(label="Settings")
        self.button_settings.set_tooltip_text("Set Integration Time and Number of Samples")
        self.button_search = Gtk.Button(label="Search for Max")
        self.button_search.set_tooltip_text("Search for position with maximum Intensity")
        self.button_save = Gtk.Button(label="Save Data")
        self.button_save.set_tooltip_text("Save all spectral Data in .csv")
        self.button_dark = Gtk.Button(label="Take Dark Spectrum")
        self.button_dark.set_tooltip_text("Take dark spectrum which will substracted from spectrum")
        self.button_lamp = Gtk.Button(label="Take Lamp Spectrum")
        self.button_lamp.set_tooltip_text("Take lamp spectrum to normalize spectrum")
        self.button_normal = Gtk.Button(label="Take Normal Spectrum")
        self.button_normal.set_tooltip_text("Start/Stop taking a normal spectrum")
        self.button_bg = Gtk.Button(label="Take Background Spectrum")
        self.button_bg.set_tooltip_text("Start/Stop taking a Background spectrum")
        self.button_series = Gtk.Button(label="Take Time Series")
        self.button_series.set_tooltip_text("Start/Stop taking a Time Series of Spectra")
        self.button_reset = Gtk.Button(label="Reset")
        self.button_reset.set_tooltip_text("Reset all spectral data (if not saved data is lost!)")
        self.button_loaddark = Gtk.Button(label="Load Dark Spectrum")
        self.button_loaddark.set_tooltip_text("Load Dark Spectrum from file")
        self.button_loadlamp = Gtk.Button(label="Load Lamp Spectrum")
        self.button_loadlamp.set_tooltip_text("Load Lamp Spectrum from file")

        # Stage Control Buttons
        self.button_xup = Gtk.Button(label="x+")
        self.button_xdown = Gtk.Button(label="x-")
        self.button_yup = Gtk.Button(label="y+")
        self.button_ydown = Gtk.Button(label="y-")
        self.button_zup = Gtk.Button(label="z+")
        self.button_zdown = Gtk.Button(label="z-")
        self.button_stepup = Gtk.Button(label="+")
        self.button_stepdown = Gtk.Button(label="-")
        self.label_stepsize = Gtk.Label(label=str(self.settings.stepsize))
        self.button_moverel = Gtk.Button(label="Move Stage rel.")
        self.button_moveabs = Gtk.Button(label="Move Stage abs.")
        # Stage position labels
        self.label_x = Gtk.Label()
        self.label_y = Gtk.Label()
        self.label_z = Gtk.Label()
        self.show_pos()

        # Connect Buttons
        self.window.connect("delete-event", self.quit)
        self.button_aquire.connect("clicked", self.on_lockin_clicked)
        self.button_direction.connect("clicked", self.on_direction_clicked)
        self.button_live.connect("clicked", self.on_live_clicked)
        self.button_stop.connect("clicked", self.on_stop_clicked)
        self.button_settings.connect("clicked", self.on_settings_clicked)
        self.button_search.connect("clicked", self.on_search_clicked)
        self.button_save.connect("clicked", self.on_save_clicked)
        self.button_dark.connect("clicked", self.on_dark_clicked)
        self.button_lamp.connect("clicked", self.on_lamp_clicked)
        self.button_normal.connect("clicked", self.on_normal_clicked)
        self.button_bg.connect("clicked", self.on_bg_clicked)
        self.button_series.connect("clicked", self.on_series_clicked)
        self.button_reset.connect("clicked", self.on_reset_clicked)
        self.button_loaddark.connect("clicked", self.on_loaddark_clicked)
        self.button_loadlamp.connect("clicked", self.on_loadlamp_clicked)
        # Connect Stage Control Buttons
        self.button_xup.connect("clicked", self.on_xup_clicked)
        self.button_xdown.connect("clicked", self.on_xdown_clicked)
        self.button_yup.connect("clicked", self.on_yup_clicked)
        self.button_ydown.connect("clicked", self.on_ydown_clicked)
        self.button_zup.connect("clicked", self.on_zup_clicked)
        self.button_zdown.connect("clicked", self.on_zdown_clicked)
        self.button_stepup.connect("clicked", self.on_stepup_clicked)
        self.button_stepdown.connect("clicked", self.on_stepdown_clicked)
        self.button_moverel.connect("clicked", self.on_moverel_clicked)
        self.button_moveabs.connect("clicked", self.on_moveabs_clicked)

        # Stage Control Button Table
        self.table_stagecontrol = Gtk.Table(3, 4, True)
        self.table_stagecontrol.attach(self.button_xup, 0, 1, 1, 2)
        self.table_stagecontrol.attach(self.button_xdown, 2, 3, 1, 2)
        self.table_stagecontrol.attach(self.button_yup, 1, 2, 0, 1)
        self.table_stagecontrol.attach(self.button_ydown, 1, 2, 2, 3)
        self.table_stagecontrol.attach(self.button_zup, 3, 4, 0, 1)
        self.table_stagecontrol.attach(self.button_zdown, 3, 4, 2, 3)
        # Stage Stepsize Table
        self.table_stepsize = Gtk.Table(1, 3, True)
        self.table_stepsize.attach(self.button_stepup, 0, 1, 0, 1)
        self.table_stepsize.attach(self.label_stepsize, 1, 2, 0, 1)
        self.table_stepsize.attach(self.button_stepdown, 2, 3, 0, 1)

        self.status = Gtk.Label(label="Initialized")
        self.progress = Gtk.ProgressBar()
        self._progress_fraction = 0
        self.progress.set_fraction(self._progress_fraction)

        # Box for control of taking single spectra
        self.SpectrumBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3)
        self.SpectrumBox.add(Gtk.Separator())
        self.SpectrumBox.add(self.button_live)
        self.SpectrumBox.add(Gtk.Separator())
        self.SpectrumBox.add(Gtk.Label("Lock-In Spectrum"))
        self.SpectrumBox.add(self.button_aquire)
        self.SpectrumBox.add(self.button_direction)
        self.SpectrumBox.add(Gtk.Separator())
        self.SpectrumBox.add(Gtk.Label(label="Additional Spectra"))
        self.SpectrumBox.add(self.button_dark)
        self.SpectrumBox.add(self.button_lamp)
        self.SpectrumBox.add(self.button_normal)
        self.SpectrumBox.add(self.button_bg)
        self.SpectrumBox.add(self.button_series)
        self.SpectrumBox.add(Gtk.Separator())
        self.SpectrumBox.add(Gtk.Label(label="Miscellaneous"))
        self.SpectrumBox.add(self.button_save)
        self.SpectrumBox.add(self.button_settings)
        self.SpectrumBox.add(self.button_reset)
        self.SpectrumBox.add(self.button_loaddark)
        self.SpectrumBox.add(self.button_loadlamp)
        self.SpectrumBox.add(Gtk.Separator())

        # Switch corrected Spectrum yes/no
        self.button_corronoff = Gtk.Switch()
        self.label_corronoff = Gtk.Label('Correct Spectrum')
        self.corronoff_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3)
        self.corronoff_box.set_homogeneous(True)
        self.corronoff_box.add(self.label_corronoff)
        self.corronoff_box.add(self.button_corronoff)

        # box for Stage control
        self.stage_hbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3)
        # self.stage_hbox.add(Gtk.Separator())
        self.stage_hbox.add(self.corronoff_box)
        self.stage_hbox.add(self.button_search)
        self.stage_hbox.add(Gtk.Label(label="Stage Control"))
        self.stage_hbox.add(self.table_stagecontrol)
        self.stage_hbox.add(Gtk.Label(label="Set Stepsize [um]"))
        self.stage_hbox.add(self.table_stepsize)
        self.stage_hbox.add(self.button_moverel)
        self.stage_hbox.add(self.button_moveabs)
        self.labels_hbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3)
        self.labels_hbox.add(self.label_x)
        self.labels_hbox.add(self.label_y)
        self.labels_hbox.add(self.label_z)


        # Buttons for scanning stack
        self.button_add_position = Gtk.Button('Add Position to List')
        self.button_spangrid = Gtk.Button('Span Grid')
        self.button_searchonoff = Gtk.Switch()
        self.label_searchonoff = Gtk.Label('Search Max.')
        self.searchonoff_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3)
        self.searchonoff_box.set_homogeneous(True)
        self.searchonoff_box.add(self.label_searchonoff)
        self.searchonoff_box.add(self.button_searchonoff)
        self.button_lockinonoff = Gtk.Switch()
        self.label_lockinonoff = Gtk.Label('Use Lock-In')
        self.lockinonoff_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3)
        self.lockinonoff_box.set_homogeneous(True)
        self.lockinonoff_box.add(self.label_lockinonoff)
        self.lockinonoff_box.add(self.button_lockinonoff)
        self.button_scan_start = Gtk.Button('Start Scan')
        self.scan_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3)
        self.button_scan_add = Gtk.ToolButton(Gtk.STOCK_ADD)
        self.button_scan_remove = Gtk.ToolButton(Gtk.STOCK_REMOVE)
        self.button_scan_clear = Gtk.ToolButton(Gtk.STOCK_DELETE)
        self.scan_hbox.set_homogeneous(True)
        self.scan_hbox.add(self.button_scan_add)
        self.scan_hbox.add(self.button_scan_remove)
        self.scan_hbox.add(self.button_scan_clear)


        # Treeview for showing/settings scanning grid
        self.scan_store = Gtk.ListStore(float, float)
        self.scan_view = Gtk.TreeView(model=self.scan_store)
        self.scan_xrenderer = Gtk.CellRendererText()
        self.scan_xrenderer.set_property("editable", True)
        self.scan_xcolumn = Gtk.TreeViewColumn("x", self.scan_xrenderer, text=0)
        self.scan_xcolumn.set_min_width(100)
        self.scan_xcolumn.set_alignment(0.5)
        self.scan_view.append_column(self.scan_xcolumn)

        self.scan_yrenderer = Gtk.CellRendererText()
        self.scan_yrenderer.set_property("editable", True)
        self.scan_ycolumn = Gtk.TreeViewColumn("y", self.scan_yrenderer, text=1)
        self.scan_ycolumn.set_min_width(100)
        self.scan_ycolumn.set_alignment(0.5)
        self.scan_view.append_column(self.scan_ycolumn)

        self.scan_scroller = Gtk.ScrolledWindow()
        self.scan_scroller.set_vexpand(True)
        self.scan_scroller.add(self.scan_view)

        self.scan_store.append([10.0, 10.0])
        self.scan_store.append([10.1, 10.0])
        self.scan_store.append([10.0, 10.1])


        #Connections for scanning stack
        self.button_add_position.connect("clicked", self.on_add_position_clicked)
        self.button_spangrid.connect("clicked", self.on_spangrid_clicked)
        self.button_scan_start.connect("clicked", self.on_scan_start_clicked)
        self.button_scan_add.connect("clicked", self.on_scan_add)
        self.button_scan_remove.connect("clicked", self.on_scan_remove)
        self.button_scan_clear.connect("clicked", self.on_scan_clear)
        self.scan_xrenderer.connect("edited", self.on_scan_xedited)
        self.scan_yrenderer.connect("edited", self.on_scan_yedited)

        #Box for control of scanning
        self.ScanningBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3)
        self.ScanningBox.add(Gtk.Separator())
        self.ScanningBox.add(self.button_add_position)
        self.ScanningBox.add(self.button_spangrid)
        self.ScanningBox.add(self.searchonoff_box)
        self.ScanningBox.add(self.lockinonoff_box)
        self.ScanningBox.add(Gtk.Separator())
        self.ScanningBox.add(Gtk.Label("Scanning Positions"))
        self.ScanningBox.add(self.scan_hbox)
        self.ScanningBox.add(self.scan_scroller)
        self.ScanningBox.add(Gtk.Separator())
        self.ScanningBox.add(self.button_scan_start)


        # MPL stuff
        self.figure = Figure()
        self.ax = self.figure.add_subplot(1, 1, 1)
        self.ax.grid(True)
        self.ax.set_xlabel("Wavelength [nm]")
        self.ax.set_ylabel("Intensity")
        self.ax.set_xlim([400, 900])
        self.canvas = FigureCanvas(self.figure)
        self.canvas.set_hexpand(True)
        self.canvas.set_vexpand(True)

        self.canvas.set_size_request(700, 700)

        self.stack = Gtk.Stack()
        self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
        self.stack.set_transition_duration(500)

        self.stack.add_titled(self.SpectrumBox, "spec", "Spectra")
        self.stack.add_titled(self.ScanningBox, "scan", "Scanning")

        self.stack_switcher = Gtk.StackSwitcher()
        self.stack_switcher.set_stack(self.stack)

        self.SideBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3)
        self.SideBox.add(self.stack_switcher)
        self.ScanningBox.add(Gtk.Separator())
        self.SideBox.add(self.button_stop)
        self.SideBox.add(self.stack)
        self.SideBox.add(self.stage_hbox)
        self.SideBox.add(self.labels_hbox)

        self.grid.add(self.canvas)
        self.grid.attach_next_to(self.SideBox, self.canvas, Gtk.PositionType.RIGHT, 1, 1)
        self.grid.attach_next_to(self.progress, self.canvas, Gtk.PositionType.BOTTOM, 1, 1)
        self.grid.attach_next_to(self.status, self.SideBox, Gtk.PositionType.BOTTOM, 1, 1)

        self.window.show_all()

        self.spectrum = Spectrum(self.stage, self.settings, self.status, self.progress, self.enable_buttons,
                                 self.disable_buttons)  # logger class which coordinates the spectrometer and the stage

        spec = self.spectrum.get_spec()  # get an initial spectrum for display
        self._wl = self.spectrum.get_wl()  # get the wavelengths
        print(self._wl)
        self.lines = []
        self.lines.extend(self.ax.plot(self._wl, spec, "-"))
        self.lines.extend(self.ax.plot(self._wl, self.spectrum.smooth(spec), "-", c="black"))  # plot initial spectrum

        #Dialogs
        self.settings_dialog = dialogs.SettingsDialog(self.window, self.settings)
        self.direction_dialog = dialogs.DirectionDialog(self.window, self.settings)
        self.moveabs_dialog = dialogs.MoveAbsDialog(self.window, self.stage)
        self.moverel_dialog = dialogs.MoveRelDialog(self.window, self.stage)
        self.spangrid_dialog = dialogs.SpanGridDialog(self.window)
        self.prefix_dialog = dialogs.PrefixDialog(self.window)

        self.pad = None
        try:
            #pass
            self.pad = Gamepad(True)
        except:
            print("Could not initialize Gamepad")



    def quit(self, *args):
        """
        Function for quitting the program, will also stop the worker thread
        :param args:
        """
        self.spectrum = None
        self.pad = None
        Gtk.main_quit(*args)

    def disable_buttons(self):
        # self.stack_switcher.set_sensitive(False)
        self.scan_hbox.set_sensitive(False)
        self.SpectrumBox.set_sensitive(False)
        self.stage_hbox.set_sensitive(False)
        self.ScanningBox.set_sensitive(False)
        self.button_stop.set_sensitive(True)


    def enable_buttons(self):
        # self.stack_switcher.set_sensitive(True)
        self.scan_hbox.set_sensitive(True)
        self.SpectrumBox.set_sensitive(True)
        self.stage_hbox.set_sensitive(True)
        self.ScanningBox.set_sensitive(True)
        self.button_stop.set_sensitive(False)

    def _on_pad_change(self, io, condition):
        a, b, x, y, ax, ay = self.pad.receiver.recv()
        if a:
            self.on_stepdown_clicked(None)
        if b:
            self.on_add_position_clicked(None)
        if x:
            self.on_search_clicked(None)
        if y:
            self.on_stepup_clicked(None)

        self.x_step = float((ax - 128))
        if abs(self.x_step) > 8:
            self.x_step = self.x_step / 128 * self.settings.stepsize
        else:
            self.x_step = 0.0

        self.y_step = float((ay - 128))
        if abs(self.y_step) > 8:
            self.y_step = self.y_step / 128 * self.settings.stepsize
        else:
            self.y_step = 0.0
        # print('x_step: {0:3.2f} um   y_step: {1:3.2f} um'.format( self.x_step, self.y_step))
        return True

    def _pad_make_step(self):
        if self.pad is not None:
            if abs(self.x_step) > 0.0001:
                if abs(self.y_step) > 0.0001:
                    self.stage.moverel(dx=self.x_step, dy=self.y_step)
                else:
                    self.stage.moverel(dx=self.x_step)
            elif abs(self.y_step) > 0.001:
                self.stage.moverel(dy=self.y_step)
        return True

    # ##---------------- button connect functions ----------

    def on_scan_start_clicked(self, widget):
        prefix = self.prefix_dialog.rundialog()

        if prefix is not None:
            try:
                # os.path.exists(prefix)
                os.mkdir(self.savedir+prefix)
            except:
                print("Error creating directory ./" + prefix)
            path = self.savedir + prefix + '/'
            self.status.set_label('Scanning')
            self.spectrum.make_scan(self.scan_store, path, self.button_searchonoff.get_active(),
                                    self.button_lockinonoff.get_active())
            self.disable_buttons()


    def on_add_position_clicked(self, widget):
        self.stage.query_pos()
        pos = self.stage.last_pos()
        self.scan_store.append([pos[0], pos[1]])

    def on_spangrid_clicked(self, widget):
        iterator = self.scan_store.get_iter_first()
        grid = self.spangrid_dialog.rundialog()
        if (len(self.scan_store) >= 3) & ((grid[0] is not 0) | (grid[1] is not 0)):
            a = self.scan_store[iterator][:]
            iterator = self.scan_store.iter_next(iterator)
            b = self.scan_store[iterator][:]
            iterator = self.scan_store.iter_next(iterator)
            c = self.scan_store[iterator][:]

            if abs(b[0]) > abs(c[0]):
                grid_vec_1 = [b[0] - a[0], b[1] - a[1]]
                grid_vec_2 = [c[0] - a[0], c[1] - a[1]]
            else:
                grid_vec_2 = [b[0] - a[0], b[1] - a[1]]
                grid_vec_1 = [c[0] - a[0], c[1] - a[1]]

            self.scan_store.clear()

            for x in range(int(grid[0])):
                for y in range(int(grid[1])):
                    vec_x = a[0] + grid_vec_1[0] * x + grid_vec_2[0] * y
                    vec_y = a[1] + grid_vec_1[1] * x + grid_vec_2[1] * y
                    self.scan_store.append([vec_x, vec_y])


    def on_stop_clicked(self, widget):
        self.spectrum.stop_process()
        self.enable_buttons()
        self.status.set_label('Stopped')

    def on_reset_clicked(self, widget):
        self.spectrum.reset()
        self.spectrum.dark = None
        self.spectrum.lamp = None
        self.spectrum.lockin = None
        self.spectrum.mean = None

    def on_lockin_clicked(self, widget):
        self.status.set_label('Acquiring ...')
        self.spectrum.take_lockin()
        self.disable_buttons()

    def on_direction_clicked(self, widget):
        self.direction_dialog.rundialog()

    def on_live_clicked(self, widget):
        self.status.set_label('Liveview')
        self.spectrum.take_live()
        self.disable_buttons()

    def on_search_clicked(self, widget):
        self.status.set_text("Searching Max.")
        self.spectrum.search_max()
        self.disable_buttons()

    def on_save_clicked(self, widget):
        self.status.set_label("Saving Data ...")
        self.save_data()

    def on_settings_clicked(self, widget):
        self.settings_dialog.rundialog()
        self.ax.set_xlim([self.settings.min_wl, self.settings.max_wl])
        #self.spectrum.reset()

    def on_dark_clicked(self, widget):
        self.status.set_label('Taking Dark Spectrum')
        self.spectrum.take_dark()
        self.disable_buttons()

    def on_lamp_clicked(self, widget):
        self.status.set_label('Taking Lamp Spectrum')
        self.spectrum.take_lamp()
        self.disable_buttons()

    def on_normal_clicked(self, widget):
        self.status.set_label('Taking Normal Spectrum')
        self.spectrum.take_normal()
        self.disable_buttons()

    def on_bg_clicked(self, widget):
        self.status.set_label('Taking Background Spectrum')
        self.spectrum.take_bg()
        self.disable_buttons()

    def on_series_clicked(self, widget):
        self.status.set_label('Taking Time Series')
        prefix = self.prefix_dialog.rundialog()
        if prefix is not None:
            try:
                # os.path.exists(prefix)
                os.mkdir(self.savedir+prefix)
            except:
                print("Error creating directory ./" + prefix)
            path = self.savedir + prefix + '/'
        else:
            self.status.set_text("Error")
        self.spectrum.take_series(path)
        self.disable_buttons()


    def on_loaddark_clicked(self, widget):
        buf = self._load_spectrum_from_file()
        if not buf is None:
            self.spectrum.dark = buf

    def on_loadlamp_clicked(self, widget):
        buf = self._load_spectrum_from_file()
        if not buf is None:
            self.spectrum.lamp = buf

    # ##---------------- END button connect functions ----------

    def _load_spectrum_from_file(self):
        dialog = Gtk.FileChooserDialog("Please choose a file", self.window,
                                       Gtk.FileChooserAction.OPEN,
                                       (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                        Gtk.STOCK_OPEN, Gtk.ResponseType.OK))

        data = None
        filter_text = Gtk.FileFilter()
        filter_text.set_name("CSV Spectrum files")
        filter_text.add_pattern("*.csv")
        dialog.add_filter(filter_text)
        dialog.set_current_folder(os.path.dirname(os.path.abspath(__file__)))
        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            data = pandas.DataFrame(pandas.read_csv(dialog.get_filename()))
            data = data['intensity']
        elif response == Gtk.ResponseType.CANCEL:
            data = None
        dialog.destroy()
        return data

    # ## ----------- scan Listview connect functions

    def on_scan_xedited(self, widget, path, number):
        self.scan_store[path][0] = float(number.replace(',', '.'))
        # self.plotpoints()

    def on_scan_yedited(self, widget, path, number):
        self.scan_store[path][1] = float(number.replace(',', '.'))
        # self.plotpoints()

    def on_scan_add(self, widget):
        self.scan_store.append()

    def on_scan_remove(self, widget):
        select = self.scan_view.get_selection()
        model, treeiter = select.get_selected()
        if treeiter is not None:
            self.scan_store.remove(treeiter)

    def on_scan_clear(self, widget):
        self.scan_store.clear()


    # ## ----------- END scan Listview connect functions


    # ##---------------- Stage Control Button Connect functions ----------

    def show_pos(self):
        pos = self.stage.last_pos()
        # print(pos)
        self.label_x.set_text("x: {0:+8.4f}".format(pos[0]))
        self.label_y.set_text("y: {0:+8.4f}".format(pos[1]))
        self.label_z.set_text("z: {0:+8.4f}".format(pos[2]))

    def on_xup_clicked(self, widget):
        self.stage.moverel(dx=self.settings.stepsize)
        self.show_pos()

    def on_xdown_clicked(self, widget):
        self.stage.moverel(dx=-self.settings.stepsize)
        self.show_pos()

    def on_yup_clicked(self, widget):
        self.stage.moverel(dy=self.settings.stepsize)
        self.show_pos()

    def on_ydown_clicked(self, widget):
        self.stage.moverel(dy=-self.settings.stepsize)
        self.show_pos()

    def on_zup_clicked(self, widget):
        self.stage.moverel(dz=self.settings.stepsize)
        self.show_pos()

    def on_zdown_clicked(self, widget):
        self.stage.moverel(dz=-self.settings.stepsize)
        self.show_pos()

    def on_stepup_clicked(self, widget):
        self.settings.stepsize *= 10
        if self.settings.stepsize > 10:
            self.settings.stepsize = 10.0
        self.label_stepsize.set_text(str(self.settings.stepsize))
        self.settings.save()

    def on_stepdown_clicked(self, widget):
        self.settings.stepsize /= 10
        if self.settings.stepsize < 0.001:
            self.settings.stepsize = 0.001
        self.label_stepsize.set_text(str(self.settings.stepsize))
        self.settings.save()

    def on_moverel_clicked(self, widget):
        self.moverel_dialog.rundialog()
        self.show_pos()

    def on_moveabs_clicked(self, widget):
        self.moveabs_dialog.rundialog()
        self.show_pos()


    # ##---------------- END Stage Control Button Connect functions ------

    def run(self):
        """	run main gtk thread """
        try:
            GLib.timeout_add(self._heartbeat, self._update_plot)
            GLib.timeout_add(self._heartbeat, self._pad_make_step)
            GLib.io_add_watch(self.spectrum.conn_for_main, GLib.IO_IN | GLib.IO_PRI, self.spectrum.callback,
                              args=(self.spectrum,))
            if self.pad is not None:
                GLib.io_add_watch(self.pad.receiver, GLib.IO_IN | GLib.IO_PRI, self._on_pad_change, args=(self,))
            Gtk.main()
        except KeyboardInterrupt:
            pass

    def _update_plot(self):
        spec = self.spectrum.get_spec(self.button_corronoff.get_active())
        self.lines[0].set_ydata(spec)
        self.lines[1].set_ydata(self.spectrum.smooth(spec))
        #self.ax.set_ylim(min(spec[262:921]), max(spec[262:921]))
        self.ax.autoscale_view(None, False, True)
        self.canvas.draw()
        self.show_pos()
        return True

    def save_data(self):
        prefix = self.prefix_dialog.rundialog()
        if prefix is not None:
            try:
                # os.path.exists(prefix)
                os.mkdir(self.savedir+prefix)
            except:
                print("Error creating directory ./" + prefix)
            path = self.savedir + prefix + '/'
            self.spectrum.save_data(path)
            self.status.set_text("Data saved")
        else:
            self.status.set_text("Could not save data")
Ejemplo n.º 2
0
class SCNR(QMainWindow):
    _window_title = "SCNR"
    _heartbeat = 100  # ms delay at which the plot/gui is refreshed, and the gamepad moves the stage

    def __init__(self, parent=None):
        super(SCNR, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.positions = np.matrix([ [0.0,0.0], [0.0,10.0], [10.0,0.0]])
        self.posModel = NumpyModel(self.positions)
        self.ui.posTable.setModel(self.posModel)
        self.vh = self.ui.posTable.verticalHeader()
        self.vh.setVisible(False)
        self.hh = self.ui.posTable.horizontalHeader()
        self.hh.setModel(self.posModel)
        self.hh.setVisible(True)

        self.settings = Settings()

        self.fig = Figure()
        self.axes = self.fig.add_subplot(111)
        self.axes.hold(False)
        #self.axes.autoscale(False)
        #self.axes.set_xlim([self.settings.min_wl, self.settings.max_wl])

        self.Canvas = FigureCanvas(self.fig)
        self.Canvas.setParent(self.ui.plotwidget)

        self.Canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.Canvas.updateGeometry()

        l = QVBoxLayout(self.ui.plotwidget)
        l.addWidget(self.Canvas)

        self.ui.status.setText("Ready")

        #self.savedir = "."+path.sep+"Spectra"+path.sep
        #self.path = "."+path.sep

        self.savedir = "./Spectra/"
        self.path = "./"

        self.x_step = .0
        self.y_step = .0
        self.step_distance = 1  # in um

        try:
            #pass
            self.stage = PIStage.E545(self.settings.stage_ip,self.settings.stage_port)
        except:
            self.stage = None
            self.stage = PIStage.Dummy()
            print("Could not initialize PIStage, using Dummy instead")

        self.spectrum = Spectrum(self.stage, self.settings, self.ui.status, self.ui.progressBar, self.enable_buttons,
                                 self.disable_buttons)  # logger class which coordinates the spectrometer and the stage

        self.spec = self.spectrum.get_spec()  # get an initial spectrum for display
        self._wl = self.spectrum.get_wl()  # get the wavelengths
        #self.update_plot(None)
        #self.spectrum.getspecthread.dynamicSpecSignal.connect(self.update_plot)
        self.spectrum.specSignal.connect(self.update_plot)
        self.spectrum.updatePositions.connect(self.update_positions)
        self.padthread = GamepadThread()
        self.padthread.BSignal.connect(self.on_search_clicked)
        self.padthread.XSignal.connect(self.on_addpos_clicked)
        self.padthread.YSignal.connect(self.on_stepup_clicked)
        self.padthread.ASignal.connect(self.on_stepdown_clicked)
        self.padthread.xaxisSignal.connect(self.on_xaxis)
        self.padthread.yaxisSignal.connect(self.on_yaxis)
        self.ax = 0.0
        self.ay = 0.0

        self.padthread.start()
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.check_pad_analog)
        self.timer.start(100)
        self.pad_active = True

        self.settings_dialog = dialogs.Settings_Dialog(self.settings)
        self.settings_dialog.updateSignal.connect(self.update_settings)
        self.update_settings()
        self.ui.label_stepsize.setText(str(self.settings.stepsize))


    def disable_buttons(self):
        self.ui.tabWidget.setDisabled(True)
        self.ui.stage_frame.setDisabled(True)
        self.ui.Button_searchmax.setDisabled(True)
        self.ui.Button_stepup.setDisabled(True)
        self.ui.Button_stepdown.setDisabled(True)
        self.ui.Button_stop.setDisabled(False)
        #self.pad_active = False


    def enable_buttons(self):
        self.ui.tabWidget.setDisabled(False)
        self.ui.stage_frame.setDisabled(False)
        self.ui.Button_searchmax.setDisabled(False)
        self.ui.Button_stepup.setDisabled(False)
        self.ui.Button_stepdown.setDisabled(False)
        self.ui.Button_stop.setDisabled(True)
        self.pad_active = True

    @pyqtSlot()
    def update_settings(self):
        self.spectrum._spectrometer.integration_time_micros(self.settings.integration_time*1000)

    @pyqtSlot(float)
    def on_xaxis(self, x):
        self.ax = x

    @pyqtSlot(float)
    def on_yaxis(self, y):
        self.ay = y

    @pyqtSlot()
    def check_pad_analog(self):
        if self.pad_active:
            x_step = self.ax
            if abs(x_step) > 0.0001:
                x_step = x_step * self.settings.stepsize
            else:
                x_step = 0.0

            y_step = -1*self.ay
            if abs(y_step) > 0.0001:
                y_step = y_step * self.settings.stepsize
            else:
                y_step = 0.0

            if abs(x_step) > 0.0001:
                if abs(y_step) > 0.0001:
                    self.stage.moverel(dx=x_step, dy=y_step)
                else:
                    self.stage.moverel(dx=x_step)
            elif abs(y_step) > 0.001:
                self.stage.moverel(dy=y_step)
            self.show_pos()

    # ## ----------- scan Listview connect functions

    @pyqtSlot()
    def on_addpos_clicked(self):
        self.stage.query_pos()
        x,y,z = self.stage.last_pos()
        positions = self.posModel.getMatrix()
        if positions.shape[1] == 2:
            positions = np.append(positions,np.matrix([x,y]), axis = 0)
        else:
            positions = np.matrix([x,y])
        self.posModel.update(positions)

    @pyqtSlot()
    def on_spangrid_clicked(self):
        xl, yl, ok = dialogs.SpanGrid_Dialog.getXY()
        positions = self.posModel.getMatrix()
        if (positions.shape[0] >= 3) & ((xl is not 0) | (yl is not 0)):
            a = np.ravel(positions[0,:])
            b = np.ravel(positions[1,:])
            c = np.ravel(positions[2,:])
            grid = np.zeros((xl*yl,2))
            if abs(b[0]) > abs(c[0]):
                grid_vec_1 = [b[0] - a[0], b[1] - a[1]]
                grid_vec_2 = [c[0] - a[0], c[1] - a[1]]
            else:
                grid_vec_2 = [b[0] - a[0], b[1] - a[1]]
                grid_vec_1 = [c[0] - a[0], c[1] - a[1]]

            print(grid_vec_1)
            print(grid_vec_2)
            i = 0
            for x in range(xl):
                for y in range(yl):
                    vec_x = a[0] + grid_vec_1[0] * x + grid_vec_2[0] * y
                    vec_y = a[1] + grid_vec_1[1] * x + grid_vec_2[1] * y
                    grid[i,0] = vec_x
                    grid[i,1] = vec_y
                    i += 1

            self.posModel.update(grid)

    @pyqtSlot()
    def on_scan_add(self):
        positions = self.posModel.getMatrix()
        if positions.shape[1] == 2:
            positions = np.append(positions,np.matrix([0.0,0.0]), axis = 0)
        else:
            positions = np.matrix([0.0,0.0])
        self.posModel.update(positions)


    @pyqtSlot()
    def on_scan_remove(self):
        indices = self.ui.posTable.selectionModel().selectedIndexes()
        rows = np.array([],dtype=int)
        for index in indices:
            rows = np.append(rows,index.row())
        positions = self.posModel.getMatrix()
        positions = np.delete(positions,rows,axis=0)
        self.posModel.update(positions)

    @pyqtSlot()
    def on_scan_clear(self):
        self.posModel.update(np.matrix([[]]))

    @pyqtSlot(np.ndarray)
    def update_positions(self, pos):
        self.posModel.update(pos)

    # ## ----------- END scan Listview connect functions

    # ##---------------- button connect functions ----------

    @pyqtSlot()
    def on_start_scan_clicked(self):
        prefix, ok = QInputDialog.getText(self, 'Save Folder',
            'Enter Folder to save spectra to:')

        if ok:
            try:
                # os.path.exists(prefix)
                os.mkdir(self.savedir+prefix)
            except:
                #print("Error creating directory ."+path.sep + prefix)
                print("Error creating directory ./" + prefix)
            #path = self.savedir + prefix + path.sep
            path = self.savedir + prefix + "/"
            self.ui.status.setText("Scanning ...")
            #self.spectrum.make_scan(self.scan_store, path, self.button_searchonoff.get_active(), self.button_lockinonoff.get_active())
            self.spectrum.make_scan(self.posModel.getMatrix(), path, self.ui.checkBox_lockin.isChecked(), self.ui.checkBox_search.isChecked())
            self.disable_buttons()


    @pyqtSlot()
    def on_stop_clicked(self):
        self.ui.status.setText('Stopped')
        self.spectrum.stop_process()
        self.enable_buttons()

    @pyqtSlot()
    def on_reset_clicked(self):
        self.spectrum.reset()

    @pyqtSlot()
    def on_acquirelockin_clicked(self):
        self.ui.status.setText('Acquiring ...')
        self.spectrum.take_lockin()
        self.disable_buttons()

    @pyqtSlot()
    def on_direction_clicked(self):
        self.direction_dialog.rundialog()

    @pyqtSlot()
    def on_live_clicked(self):
        self.ui.status.setText('Liveview')
        self.spectrum.take_live()
        self.disable_buttons()

    @pyqtSlot()
    def on_searchgrid_clicked(self):
        self.ui.status.setText("Searching Max.")
        self.spectrum.scan_search_max(self.posModel.getMatrix())
        self.disable_buttons()

    @pyqtSlot()
    def on_search_clicked(self):
        self.ui.status.setText("Searching Max.")
        self.spectrum.search_max()
        self.disable_buttons()

    @pyqtSlot()
    def on_save_clicked(self):
        self.ui.status.setText("Saving Data ...")
        prefix, ok = QInputDialog.getText(self, 'Save Folder',
            'Enter Folder to save spectra to:')
        if ok:
            try:
                # os.path.exists(prefix)
                os.mkdir(self.savedir+prefix)
            except:
                #print("Error creating directory ."+path.sep + prefix)
                print("Error creating directory ./" + prefix)
            #path = self.savedir + prefix + path.sep
            path = self.savedir + prefix + "/"
            self.spectrum.save_data(path)

    @pyqtSlot()
    def on_saveas_clicked(self):
        self.ui.status.setText("Saving Data ...")
        save_as = QFileDialog.getSaveFileName(self, "Save currently shown Spectrum as", './spectra/','CSV Files (*.csv)')
        print(save_as)
        #prefix, ok = QInputDialog.getText(self, 'Save Folder', 'Enter Folder to save spectra to:')
        if not self.spectrum.mean is None:
            try:
                self.spectrum.save_spectrum(self.spectrum.mean, save_as[0], None, False, True)
            except:
                print("Error Saving file " + save_as[0])

    @pyqtSlot()
    def on_settings_clicked(self):
        self.settings_dialog.show()

        #self.spectrum.reset()

    @pyqtSlot()
    def on_dark_clicked(self):
        self.ui.status.setText('Taking Dark Spectrum')
        self.spectrum.take_dark()
        self.disable_buttons()

    @pyqtSlot()
    def on_lamp_clicked(self):
        self.ui.status.setText('Taking Lamp Spectrum')
        self.spectrum.take_lamp()
        self.disable_buttons()

    @pyqtSlot()
    def on_mean_clicked(self):
        self.ui.status.setText('Taking Normal Spectrum')
        self.spectrum.take_mean()
        self.disable_buttons()

    @pyqtSlot()
    def on_bg_clicked(self):
        self.ui.status.setText('Taking Background Spectrum')
        self.spectrum.take_bg()
        self.disable_buttons()

    @pyqtSlot()
    def on_series_clicked(self):
        self.ui.status.setText('Taking Time Series')
        prefix = self.prefix_dialog.rundialog()
        if prefix is not None:
            try:
                # os.path.exists(prefix)
                os.mkdir(self.savedir+prefix)
            except:
                #print("Error creating directory ."+path.sep + prefix)
                print("Error creating directory ./" + prefix)
            #path = self.savedir + prefix + path.sep
            path = self.savedir + prefix + "/"
        else:
            self.ui.status.setText("Error")
        self.spectrum.take_series(path)
        self.disable_buttons()

    @pyqtSlot()
    def on_loaddark_clicked(self):
        buf = self._load_spectrum_from_file()
        if not buf is None:
            self.spectrum.dark = buf

    @pyqtSlot()
    def on_loadlamp_clicked(self):
        buf = self._load_spectrum_from_file()
        if not buf is None:
            self.spectrum.lamp = buf

    @pyqtSlot()
    def on_loadbg_clicked(self):
        buf = self._load_spectrum_from_file()
        if not buf is None:
            self.spectrum.bg = buf

    @pyqtSlot()
    def on_lockin_clicked(self):
        pass

    @pyqtSlot()
    def on_aquirelockin_clicked(self):
        pass

    # ##---------------- END button connect functions ----------

    def _load_spectrum_from_file(self):
        #save_dir = QFileDialog.getOpenFileName(self, "Load Spectrum from CSV", os.path.expanduser('~'), 'CSV Files (*.csv)')
        #save_dir = QFileDialog.getOpenFileName(self, "Load Spectrum from CSV", '.'+path.sep+'spectra'+path.sep, 'CSV Files (*.csv)')
        save_dir = QFileDialog.getOpenFileName(self, "Load Spectrum from CSV", './spectra/', 'CSV Files (*.csv)')

        if len(save_dir[0])>1:
            save_dir = save_dir[0]
            #data = pandas.DataFrame(pandas.read_csv(save_dir,skiprows=8))
            #data = data['counts']
            data = np.genfromtxt(save_dir, delimiter=',',skip_header=12)
            data = data[:,1]
            return np.array(data)
        return None

    # ##---------------- Stage Control Button Connect functions ----------

    def show_pos(self):
        pos = self.stage.last_pos()
        # print(pos)
        self.ui.label_x.setText("x: {0:+8.4f}".format(pos[0]))
        self.ui.label_y.setText("y: {0:+8.4f}".format(pos[1]))
        self.ui.label_z.setText("z: {0:+8.4f}".format(pos[2]))

    @pyqtSlot()
    def on_xup_clicked(self):
        self.stage.moverel(dx=self.settings.stepsize)
        self.show_pos()

    @pyqtSlot()
    def on_xdown_clicked(self):
        self.stage.moverel(dx=-self.settings.stepsize)
        self.show_pos()

    @pyqtSlot()
    def on_yup_clicked(self):
        self.stage.moverel(dy=self.settings.stepsize)
        self.show_pos()

    @pyqtSlot()
    def on_ydown_clicked(self):
        self.stage.moverel(dy=-self.settings.stepsize)
        self.show_pos()

    @pyqtSlot()
    def on_zup_clicked(self):
        self.stage.moverel(dz=self.settings.stepsize)
        self.show_pos()

    @pyqtSlot()
    def on_zdown_clicked(self):
        self.stage.moverel(dz=-self.settings.stepsize)
        self.show_pos()

    @pyqtSlot()
    def on_stepup_clicked(self):
        self.settings.stepsize *= 10
        if self.settings.stepsize > 10:
            self.settings.stepsize = 10.0
        self.ui.label_stepsize.setText(str(self.settings.stepsize))
        self.settings.save()

    @pyqtSlot()
    def on_stepdown_clicked(self):
        self.settings.stepsize /= 10
        if self.settings.stepsize < 0.001:
            self.settings.stepsize = 0.001
        self.ui.label_stepsize.setText(str(self.settings.stepsize))
        self.settings.save()

    def on_moverel_clicked(self):
        self.moverel_dialog.rundialog()
        self.show_pos()

    def on_moveabs_clicked(self):
        self.moveabs_dialog.rundialog()
        self.show_pos()

    @pyqtSlot(np.ndarray)
    def update_plot(self):
        self.spec = self.spectrum.get_spec(self.ui.CheckBox_correct.isChecked())
        mask = (self._wl >= self.settings.min_wl) & (self._wl <= self.settings.max_wl)
        self.axes.plot(self._wl[mask], self.spec[mask])
        #self.axes.plot(self._wl, spec)
        self.Canvas.draw()
        self.show_pos()
        return True
Ejemplo n.º 3
0
class SCNR(QMainWindow):
    _window_title = "SCNR"
    _heartbeat = 100  # ms delay at which the plot/gui is refreshed, and the gamepad moves the stage

    def __init__(self, parent=None):
        super(SCNR, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.positions = np.matrix([[0.0, 0.0], [0.0, 10.0], [10.0, 0.0]])
        self.posModel = NumpyModel(self.positions)
        self.ui.posTable.setModel(self.posModel)
        self.vh = self.ui.posTable.verticalHeader()
        self.vh.setVisible(False)
        self.hh = self.ui.posTable.horizontalHeader()
        self.hh.setModel(self.posModel)
        self.hh.setVisible(True)

        self.settings = Settings()

        self.fig = Figure()
        self.axes = self.fig.add_subplot(111)
        self.axes.hold(False)
        #self.axes.autoscale(False)
        #self.axes.set_xlim([self.settings.min_wl, self.settings.max_wl])

        self.Canvas = FigureCanvas(self.fig)
        self.Canvas.setParent(self.ui.plotwidget)

        self.Canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.Canvas.updateGeometry()

        l = QVBoxLayout(self.ui.plotwidget)
        l.addWidget(self.Canvas)

        self.ui.status.setText("Ready")

        #self.savedir = "."+path.sep+"Spectra"+path.sep
        #self.path = "."+path.sep

        self.savedir = "./Spectra/"
        self.path = "./"

        self.x_step = .0
        self.y_step = .0
        self.step_distance = 1  # in um

        try:
            #pass
            self.stage = PIStage.E545(self.settings.stage_ip,
                                      self.settings.stage_port)
        except:
            self.stage = None
            self.stage = PIStage.Dummy()
            print("Could not initialize PIStage, using Dummy instead")

        self.spectrum = Spectrum(
            self.stage, self.settings, self.ui.status, self.ui.progressBar,
            self.enable_buttons, self.disable_buttons
        )  # logger class which coordinates the spectrometer and the stage

        self.spec = self.spectrum.get_spec(
        )  # get an initial spectrum for display
        self._wl = self.spectrum.get_wl()  # get the wavelengths
        #self.update_plot(None)
        #self.spectrum.getspecthread.dynamicSpecSignal.connect(self.update_plot)
        self.spectrum.specSignal.connect(self.update_plot)
        self.spectrum.updatePositions.connect(self.update_positions)
        self.padthread = GamepadThread()
        self.padthread.BSignal.connect(self.on_search_clicked)
        self.padthread.XSignal.connect(self.on_addpos_clicked)
        self.padthread.YSignal.connect(self.on_stepup_clicked)
        self.padthread.ASignal.connect(self.on_stepdown_clicked)
        self.padthread.xaxisSignal.connect(self.on_xaxis)
        self.padthread.yaxisSignal.connect(self.on_yaxis)
        self.ax = 0.0
        self.ay = 0.0

        self.padthread.start()
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.check_pad_analog)
        self.timer.start(100)
        self.pad_active = True

        self.settings_dialog = dialogs.Settings_Dialog(self.settings)
        self.settings_dialog.updateSignal.connect(self.update_settings)
        self.update_settings()
        self.ui.label_stepsize.setText(str(self.settings.stepsize))

    def disable_buttons(self):
        self.ui.tabWidget.setDisabled(True)
        self.ui.stage_frame.setDisabled(True)
        self.ui.Button_searchmax.setDisabled(True)
        self.ui.Button_stepup.setDisabled(True)
        self.ui.Button_stepdown.setDisabled(True)
        self.ui.Button_stop.setDisabled(False)
        #self.pad_active = False

    def enable_buttons(self):
        self.ui.tabWidget.setDisabled(False)
        self.ui.stage_frame.setDisabled(False)
        self.ui.Button_searchmax.setDisabled(False)
        self.ui.Button_stepup.setDisabled(False)
        self.ui.Button_stepdown.setDisabled(False)
        self.ui.Button_stop.setDisabled(True)
        self.pad_active = True

    @pyqtSlot()
    def update_settings(self):
        self.spectrum._spectrometer.integration_time_micros(
            self.settings.integration_time * 1000)

    @pyqtSlot(float)
    def on_xaxis(self, x):
        self.ax = x

    @pyqtSlot(float)
    def on_yaxis(self, y):
        self.ay = y

    @pyqtSlot()
    def check_pad_analog(self):
        if self.pad_active:
            x_step = self.ax
            if abs(x_step) > 0.0001:
                x_step = x_step * self.settings.stepsize
            else:
                x_step = 0.0

            y_step = -1 * self.ay
            if abs(y_step) > 0.0001:
                y_step = y_step * self.settings.stepsize
            else:
                y_step = 0.0

            if abs(x_step) > 0.0001:
                if abs(y_step) > 0.0001:
                    self.stage.moverel(dx=x_step, dy=y_step)
                else:
                    self.stage.moverel(dx=x_step)
            elif abs(y_step) > 0.001:
                self.stage.moverel(dy=y_step)
            self.show_pos()

    # ## ----------- scan Listview connect functions

    @pyqtSlot()
    def on_addpos_clicked(self):
        self.stage.query_pos()
        x, y, z = self.stage.last_pos()
        positions = self.posModel.getMatrix()
        if positions.shape[1] == 2:
            positions = np.append(positions, np.matrix([x, y]), axis=0)
        else:
            positions = np.matrix([x, y])
        self.posModel.update(positions)

    @pyqtSlot()
    def on_spangrid_clicked(self):
        xl, yl, ok = dialogs.SpanGrid_Dialog.getXY()
        positions = self.posModel.getMatrix()
        if (positions.shape[0] >= 3) & ((xl is not 0) | (yl is not 0)):
            a = np.ravel(positions[0, :])
            b = np.ravel(positions[1, :])
            c = np.ravel(positions[2, :])
            grid = np.zeros((xl * yl, 2))
            if abs(b[0]) > abs(c[0]):
                grid_vec_1 = [b[0] - a[0], b[1] - a[1]]
                grid_vec_2 = [c[0] - a[0], c[1] - a[1]]
            else:
                grid_vec_2 = [b[0] - a[0], b[1] - a[1]]
                grid_vec_1 = [c[0] - a[0], c[1] - a[1]]

            print(grid_vec_1)
            print(grid_vec_2)
            i = 0
            for x in range(xl):
                for y in range(yl):
                    vec_x = a[0] + grid_vec_1[0] * x + grid_vec_2[0] * y
                    vec_y = a[1] + grid_vec_1[1] * x + grid_vec_2[1] * y
                    grid[i, 0] = vec_x
                    grid[i, 1] = vec_y
                    i += 1

            self.posModel.update(grid)

    @pyqtSlot()
    def on_scan_add(self):
        positions = self.posModel.getMatrix()
        if positions.shape[1] == 2:
            positions = np.append(positions, np.matrix([0.0, 0.0]), axis=0)
        else:
            positions = np.matrix([0.0, 0.0])
        self.posModel.update(positions)

    @pyqtSlot()
    def on_scan_remove(self):
        indices = self.ui.posTable.selectionModel().selectedIndexes()
        rows = np.array([], dtype=int)
        for index in indices:
            rows = np.append(rows, index.row())
        positions = self.posModel.getMatrix()
        positions = np.delete(positions, rows, axis=0)
        self.posModel.update(positions)

    @pyqtSlot()
    def on_scan_clear(self):
        self.posModel.update(np.matrix([[]]))

    @pyqtSlot(np.ndarray)
    def update_positions(self, pos):
        self.posModel.update(pos)

    # ## ----------- END scan Listview connect functions

    # ##---------------- button connect functions ----------

    @pyqtSlot()
    def on_start_scan_clicked(self):
        prefix, ok = QInputDialog.getText(self, 'Save Folder',
                                          'Enter Folder to save spectra to:')

        if ok:
            try:
                # os.path.exists(prefix)
                os.mkdir(self.savedir + prefix)
            except:
                #print("Error creating directory ."+path.sep + prefix)
                print("Error creating directory ./" + prefix)
            #path = self.savedir + prefix + path.sep
            path = self.savedir + prefix + "/"
            self.ui.status.setText("Scanning ...")
            #self.spectrum.make_scan(self.scan_store, path, self.button_searchonoff.get_active(), self.button_lockinonoff.get_active())
            self.spectrum.make_scan(self.posModel.getMatrix(), path,
                                    self.ui.checkBox_lockin.isChecked(),
                                    self.ui.checkBox_search.isChecked())
            self.disable_buttons()

    @pyqtSlot()
    def on_stop_clicked(self):
        self.ui.status.setText('Stopped')
        self.spectrum.stop_process()
        self.enable_buttons()

    @pyqtSlot()
    def on_reset_clicked(self):
        self.spectrum.reset()

    @pyqtSlot()
    def on_acquirelockin_clicked(self):
        self.ui.status.setText('Acquiring ...')
        self.spectrum.take_lockin()
        self.disable_buttons()

    @pyqtSlot()
    def on_direction_clicked(self):
        self.direction_dialog.rundialog()

    @pyqtSlot()
    def on_live_clicked(self):
        self.ui.status.setText('Liveview')
        self.spectrum.take_live()
        self.disable_buttons()

    @pyqtSlot()
    def on_searchgrid_clicked(self):
        self.ui.status.setText("Searching Max.")
        self.spectrum.scan_search_max(self.posModel.getMatrix())
        self.disable_buttons()

    @pyqtSlot()
    def on_search_clicked(self):
        self.ui.status.setText("Searching Max.")
        self.spectrum.search_max()
        self.disable_buttons()

    @pyqtSlot()
    def on_save_clicked(self):
        self.ui.status.setText("Saving Data ...")
        prefix, ok = QInputDialog.getText(self, 'Save Folder',
                                          'Enter Folder to save spectra to:')
        if ok:
            try:
                # os.path.exists(prefix)
                os.mkdir(self.savedir + prefix)
            except:
                #print("Error creating directory ."+path.sep + prefix)
                print("Error creating directory ./" + prefix)
            #path = self.savedir + prefix + path.sep
            path = self.savedir + prefix + "/"
            self.spectrum.save_data(path)

    @pyqtSlot()
    def on_saveas_clicked(self):
        self.ui.status.setText("Saving Data ...")
        save_as = QFileDialog.getSaveFileName(
            self, "Save currently shown Spectrum as", './spectra/',
            'CSV Files (*.csv)')
        print(save_as)
        #prefix, ok = QInputDialog.getText(self, 'Save Folder', 'Enter Folder to save spectra to:')
        if not self.spectrum.mean is None:
            try:
                self.spectrum.save_spectrum(self.spectrum.mean, save_as[0],
                                            None, False, True)
            except:
                print("Error Saving file " + save_as[0])

    @pyqtSlot()
    def on_settings_clicked(self):
        self.settings_dialog.show()

        #self.spectrum.reset()

    @pyqtSlot()
    def on_dark_clicked(self):
        self.ui.status.setText('Taking Dark Spectrum')
        self.spectrum.take_dark()
        self.disable_buttons()

    @pyqtSlot()
    def on_lamp_clicked(self):
        self.ui.status.setText('Taking Lamp Spectrum')
        self.spectrum.take_lamp()
        self.disable_buttons()

    @pyqtSlot()
    def on_mean_clicked(self):
        self.ui.status.setText('Taking Normal Spectrum')
        self.spectrum.take_mean()
        self.disable_buttons()

    @pyqtSlot()
    def on_bg_clicked(self):
        self.ui.status.setText('Taking Background Spectrum')
        self.spectrum.take_bg()
        self.disable_buttons()

    @pyqtSlot()
    def on_series_clicked(self):
        self.ui.status.setText('Taking Time Series')
        prefix = self.prefix_dialog.rundialog()
        if prefix is not None:
            try:
                # os.path.exists(prefix)
                os.mkdir(self.savedir + prefix)
            except:
                #print("Error creating directory ."+path.sep + prefix)
                print("Error creating directory ./" + prefix)
            #path = self.savedir + prefix + path.sep
            path = self.savedir + prefix + "/"
        else:
            self.ui.status.setText("Error")
        self.spectrum.take_series(path)
        self.disable_buttons()

    @pyqtSlot()
    def on_loaddark_clicked(self):
        buf = self._load_spectrum_from_file()
        if not buf is None:
            self.spectrum.dark = buf

    @pyqtSlot()
    def on_loadlamp_clicked(self):
        buf = self._load_spectrum_from_file()
        if not buf is None:
            self.spectrum.lamp = buf

    @pyqtSlot()
    def on_loadbg_clicked(self):
        buf = self._load_spectrum_from_file()
        if not buf is None:
            self.spectrum.bg = buf

    @pyqtSlot()
    def on_lockin_clicked(self):
        pass

    @pyqtSlot()
    def on_aquirelockin_clicked(self):
        pass

    # ##---------------- END button connect functions ----------

    def _load_spectrum_from_file(self):
        #save_dir = QFileDialog.getOpenFileName(self, "Load Spectrum from CSV", os.path.expanduser('~'), 'CSV Files (*.csv)')
        #save_dir = QFileDialog.getOpenFileName(self, "Load Spectrum from CSV", '.'+path.sep+'spectra'+path.sep, 'CSV Files (*.csv)')
        save_dir = QFileDialog.getOpenFileName(self, "Load Spectrum from CSV",
                                               './spectra/',
                                               'CSV Files (*.csv)')

        if len(save_dir[0]) > 1:
            save_dir = save_dir[0]
            #data = pandas.DataFrame(pandas.read_csv(save_dir,skiprows=8))
            #data = data['counts']
            data = np.genfromtxt(save_dir, delimiter=',', skip_header=12)
            data = data[:, 1]
            return np.array(data)
        return None

    # ##---------------- Stage Control Button Connect functions ----------

    def show_pos(self):
        pos = self.stage.last_pos()
        # print(pos)
        self.ui.label_x.setText("x: {0:+8.4f}".format(pos[0]))
        self.ui.label_y.setText("y: {0:+8.4f}".format(pos[1]))
        self.ui.label_z.setText("z: {0:+8.4f}".format(pos[2]))

    @pyqtSlot()
    def on_xup_clicked(self):
        self.stage.moverel(dx=self.settings.stepsize)
        self.show_pos()

    @pyqtSlot()
    def on_xdown_clicked(self):
        self.stage.moverel(dx=-self.settings.stepsize)
        self.show_pos()

    @pyqtSlot()
    def on_yup_clicked(self):
        self.stage.moverel(dy=self.settings.stepsize)
        self.show_pos()

    @pyqtSlot()
    def on_ydown_clicked(self):
        self.stage.moverel(dy=-self.settings.stepsize)
        self.show_pos()

    @pyqtSlot()
    def on_zup_clicked(self):
        self.stage.moverel(dz=self.settings.stepsize)
        self.show_pos()

    @pyqtSlot()
    def on_zdown_clicked(self):
        self.stage.moverel(dz=-self.settings.stepsize)
        self.show_pos()

    @pyqtSlot()
    def on_stepup_clicked(self):
        self.settings.stepsize *= 10
        if self.settings.stepsize > 10:
            self.settings.stepsize = 10.0
        self.ui.label_stepsize.setText(str(self.settings.stepsize))
        self.settings.save()

    @pyqtSlot()
    def on_stepdown_clicked(self):
        self.settings.stepsize /= 10
        if self.settings.stepsize < 0.001:
            self.settings.stepsize = 0.001
        self.ui.label_stepsize.setText(str(self.settings.stepsize))
        self.settings.save()

    def on_moverel_clicked(self):
        self.moverel_dialog.rundialog()
        self.show_pos()

    def on_moveabs_clicked(self):
        self.moveabs_dialog.rundialog()
        self.show_pos()

    @pyqtSlot(np.ndarray)
    def update_plot(self):
        self.spec = self.spectrum.get_spec(
            self.ui.CheckBox_correct.isChecked())
        mask = (self._wl >= self.settings.min_wl) & (self._wl <=
                                                     self.settings.max_wl)
        self.axes.plot(self._wl[mask], self.spec[mask])
        #self.axes.plot(self._wl, spec)
        self.Canvas.draw()
        self.show_pos()
        return True