from prev_projects.DATAFIT.VIEW import GraphView
from prev_projects.DATAFIT.MODEL import FitModel
from prev_projects.DATAFIT.CONTROLLER import FitController
from prev_projects.DATAFIT.HELPFUL import ndarray_tostring

from PyQt5 import QtCore, QtGui
from PyQt5.QtWidgets import (QListWidgetItem,
                             QApplication,
                             QFileDialog)

from numpy import searchsorted, transpose, vstack, column_stack, append, savetxt
import logging
module_logger = logging.getLogger(__name__)


class GraphController():
    """
    Class GraphController is a controller
    which coordinates work between view and model.
    """

    def __init__(self, in_model, param):
        self.logger = logging.getLogger("MAIN." + __name__)
        self.model = in_model
        self.view = GraphView(self, in_parameters=param)
        self.view.show()
        self.model.notifyObservers()
        self.clipboard = QApplication.clipboard()
        self.axhline_SEL = False
        self.axhline_SEL_index = 1
        self.ctr_pressed = False
        self.line_picked = {'kinetics': None, 'spectrum': None}

        if self.model.parentmodel.dev:
            self.fit_clicked()

    def onselectrect(self, eclick, erelease):
        if not self.axhline_SEL:
            self.update_selected_area(eclick.xdata,
                                      erelease.xdata,
                                      eclick.ydata,
                                      erelease.ydata,
                                      real=True)

    def update_selected_area(self, xdata_clicked, xdata_realeased,
                             ydata_clicked, ydata_realeased, real=False):

        self.model.update_cursors((xdata_clicked, xdata_realeased,
                                   ydata_clicked, ydata_realeased),
                                  real=real)

    def on_pick_kinetics(self, event):
        label = event.artist._label
        # key: find pos of ':' in label of line
        pos = label.find('key:')
        # obtain key from _label of line
        if pos != -1:
            key = int(label[pos+4:])
            if self.line_picked['kinetics'] == None:
                self.line_picked['kinetics'] = key
                self.logger.info('kinetics line selected:' + label)
                self.view.statusBar().showMessage('kinetics line selected:' + label, 2000)
            else:
                self.line_picked['kinetics'] = None
                self.logger.info('kinetics line unselected:' + label)
                self.view.statusBar().showMessage('kinetics line unselected:' + label, 2000)

    def on_pick_spectrum(self, event):
        label = event.artist._label
        # key: find pos of ':' in label of line
        pos = label.find('key:')
        # obtain key from _label of line
        if pos != -1:
            key = int(label[pos+4:])
            if self.line_picked['spectrum'] == None:
                self.line_picked['spectrum'] = key
                self.logger.info('spectrum line selected:' + label)
                self.view.statusBar().showMessage('spectrum line selected:' + label, 2000)
            else:
                self.line_picked['spectrum'] = None
                self.logger.info('spectrum line unselected:' + label)
                self.view.statusBar().showMessage('spectrum line unselected:' + label, 2000)

    def key_pressed_kinetics(self, event):
        try:
            if event.key == 'ctrl+c':
                key = self.line_picked['kinetics']
                var = transpose(self.model.copy_data(X=self.model.timedelays,
                                                     Y=self.model.kinetics,
                                                     key=key))
                s = ndarray_tostring(var)
                self.clipboard.setText(s)

            elif event.key == 'ctrl+a':
                self.model.add_kinetics()

            elif event.key == 'delete':
                if self.line_picked['kinetics'] == None:
                    self.model.delete_kinetics()
                else:
                    self.model.delete_kinetics(key_del=self.line_picked['kinetics']) 
        except Exception as e:
            self.logger.error(e)

    def key_pressed_spectra(self, event):
        if event.key == 'ctrl+c':
            key = self.line_picked['spectrum']
            var = transpose(self.model.copy_data(X=self.model.wavelengths,
                                                 Y=self.model.spectra,
                                                 key=key))
            s = ndarray_tostring(var)
            self.clipboard.setText(s)

        elif event.key == 'ctrl+a':
            self.model.add_spectrum()

        elif event.key == 'delete':
            if self.line_picked['spectrum'] == None:
                self.model.delete_spectrum()
            else:
                self.model.delete_spectrum(key_del=self.line_picked['spectrum'])

    def key_pressed(self, event):
        #=======================================================================
        # if event.key in ['A', 'a']:
        #     try:
        #         if self.view.ui.RS.active:
        #             self.view.ui.RS.set_active(False)
        #             self.view.statusBar().showMessage("RectangleSelector deactivated.", 1000)
        #             print(' RectangleSelector deactivated.')
        #         else:
        #             self.view.ui.RS.set_active(True)
        #             self.view.statusBar().showMessage("RectangleSelector activated.", 1000)
        #             print(' RectangleSelector activated.')
        #     except Exception as e:
        #         self.logger.error(str(e))
        #=======================================================================
        try:
            if event.key == 'control':
                self.view.statusBar().showMessage("Ctrl pressed", 2000)
                self.ctr_pressed = True
                self.view.ui.cursor_data.visible = False

            elif event.key == 'ctrl+c':
                data = transpose(self.model.data)
                timedelays = self.model.timedelays
                wavelengths = append(0, self.model.wavelengths)
                data = vstack([timedelays, data])
                data = column_stack([wavelengths, data])
                s = ndarray_tostring(data)
                self.clipboard.setText(s)
        except Exception as e:
            self.logger.error(e)

    def key_released(self, event):
        if event.key == 'control':
            self.view.statusBar().showMessage("Ctrl released", 2000)
            self.ctr_pressed = False
            self.axhline_SEL = False
            self.view.ui.cursor_data.visible = True

    def mouse_pressed(self, event):
        self.axhline_SEL = False
        cursors = self.model.cursors
        min_dist = 20
        key = None
        keyX = None
        keyY = None

        if self.ctr_pressed:
            wavelength = self.model.wavelengths
            timedelays = self.model.timedelays
            xpos, ypos = [(searchsorted(wavelength,
                                        event.xdata,
                                        side='right')),
                          (searchsorted(timedelays,
                                        event.ydata,
                                        side='right'))]

            if abs(xpos - cursors['x1']) < min_dist:
                keyX = 'x1'
                self.axhline_SEL = True

            elif abs(xpos - cursors['x2']) < min_dist:
                keyX = 'x2'
                self.axhline_SEL = True

            if abs(ypos - cursors['y1']) < min_dist:
                keyY = 'y1'
                self.axhline_SEL = True

            elif abs(ypos - cursors['y2']) < min_dist:
                keyY = 'y2'
                self.axhline_SEL = True

            if self.axhline_SEL:

                if keyX and keyY:
                    if abs(xpos - cursors[keyX]) > abs(ypos - cursors[keyY]):
                        key = keyY

                    if abs(xpos - cursors[keyX]) < abs(ypos - cursors[keyY]):
                        key = keyX

                else:
                    if keyX:
                        key = keyX
                    else:
                        key = keyY

                if key == 'x1':
                    self.axhline_SEL_index = 1

                elif key == 'x2':
                    self.axhline_SEL_index = 2

                elif key == 'y1':
                    self.axhline_SEL_index = 3

                elif key == 'y2':
                    self.axhline_SEL_index = 4

    def mouse_moved(self, event):
        modifiers = QtGui.QGuiApplication.keyboardModifiers()
        axhline_SEL_index = self.axhline_SEL_index
        if modifiers == QtCore.Qt.ControlModifier:
            if self.axhline_SEL:
                cursors = self.model.cursors
                timedelays = self.model.timedelays
                wavelengths = self.model.wavelengths

                if axhline_SEL_index == 1:
                    pos = searchsorted(wavelengths, event.xdata, side='right')
                    self.update_selected_area(pos,
                                              cursors['x2'],
                                              cursors['y1'],
                                              cursors['y2'])

                elif axhline_SEL_index == 2:
                    pos = searchsorted(wavelengths, event.xdata, side='right')
                    self.update_selected_area(cursors['x1'],
                                              pos,
                                              cursors['y1'],
                                              cursors['y2'])

                elif axhline_SEL_index == 3:
                    pos = searchsorted(timedelays, event.ydata, side='right')
                    self.update_selected_area(cursors['x1'],
                                              cursors['x2'],
                                              pos,
                                              cursors['y2'])

                elif axhline_SEL_index == 4:
                    pos = searchsorted(timedelays, event.ydata, side='right')
                    self.update_selected_area(cursors['x1'],
                                              cursors['x2'],
                                              cursors['y1'],
                                              pos)

    def slider_moved_X(self, index_slider, start, end):
        self.update_selected_area(start, end,
                                  self.model.cursors['y1'],
                                  self.model.cursors['y2'])

    def slider_moved_Y(self, index_slider, start, end):
        self.update_selected_area(self.model.cursors['x1'],
                                  self.model.cursors['x2'],
                                  start, end)

    def slider_colorbar_moved(self, index_slider, start, end):
        self.view.ui.datacanvas.update_limits(minv=start, maxv=end)

    def fit_clicked(self):
        """
        Handles event generated, when the button "Fit" is pressed.
        """
        fit_model_dict = {'pulse': False, 'constrained': False,
                          'conv': False, 'model': '1exp'}

        fit_model_dict['model'] = self.view.ui.combobox_Fit.currentText()

        fit_model_dict['pulse'] = self.view.ui.checkbox_pulse.isChecked()

        fit_model_dict['constrained'] = self.view.ui.checkbox_constrained.isChecked()

        fit_model_dict['conv'] = self.view.ui.checkbox_conv.isChecked()

        guess, bounds, parameters_order = self.fit_model_init(fit_model_dict)

        timedelays = self.model.timedelays
        kinetics = self.model.kinetics['dynamic'][1]
        norm_factor = self.model.parentmodel.config['Views']['FitCanvas']['Norm']

        fitparam = dict(zip(['fitmodel', 'guess', 'bounds',
                             'variables', 'Norm', 'method',
                             'filepath', 'cursors'],
                            [fit_model_dict, guess, bounds,
                             parameters_order, norm_factor,
                             self.view.ui.combobox_Method.currentText(),
                             self.model.filepath,
                             self.model.cursors]))

        try:
            fitmodel = FitModel(X=timedelays,
                                Y=kinetics,
                                fitparam=fitparam)
            fitcontroller = FitController(fitmodel)
        except (Exception, RuntimeError) as e:
            self.logger.error(e)
        finally:
            self.model.addFit(fitcontroller)
            x = len(self.model.fits)
            fitmodel = ''
            for key, value in fit_model_dict.items():
                fitmodel = fitmodel + key + ': ' + str(value) + '; '
            fitmodel = fitmodel[:-1]
            self.view.ui.list_fits.addItem(QListWidgetItem(str(x) + ': ' + fitmodel))

        try:
            fitcontroller.model.do_fit()
        except Exception as e:
            self.logger.error('Try another function')

    def delete_clicked(self):
        """
        Handles event generated,  when the button "Delete" is pressed.
        """
        listItems = self.view.ui.list_fits.selectedItems()
        del_Fits_indexes = []
        if not listItems:
            return
        i = 0
        for item in listItems:
            self.view.ui.list_fits.setCurrentItem(item)
            index = self.view.ui.list_fits.currentRow() + i
            i += 1
            del_Fits_indexes.append(index)
            self.view.ui.list_fits.takeItem(
                self.view.ui.list_fits.row(item))

        self.model.removeFits(del_Fits_indexes)

    def save_clicked(self):
        data = transpose(self.model.data)
        timedelays = self.model.timedelays
        wavelengths = append(0, self.model.wavelengths)
        data = vstack([timedelays, data])
        data = column_stack([wavelengths, data])
        fdialog = QFileDialog(self.view)
        fdialog.setDirectory('C:')
        filename = fdialog.getSaveFileName(self.view, 'Save 2D map', '',"Images (*.dat)")[0]
        try:
            savetxt(filename, data, delimiter='\t', fmt="%s")
        except Exception as e:
            print(e)

    def lfits_clicked(self):
        """
        Handles event called, when user click on the item of the list of Fits.
        """
        index = self.view.ui.list_fits.currentRow()
        a = self.model.fits[index]
        a.view.show()

    def quit_clicked(self, event):
        close_fits = self.model.fits
        if close_fits:
            for fit in close_fits:
                fit.view.hide()
        self.view.hide()

    def fit_model_init(self, fit_model):
        """
        Fills guess, bounds, variables according to fit_model
        """
        parent_model = self.model.parentmodel
        if fit_model['pulse']:
            model = 'pulse_' + fit_model['model']
        else:
            model = '_' + fit_model['model']

        try:
            guess = parent_model.config['Fitting'][model]['guess']
            bounds = parent_model.config['Fitting'][model]['bounds']
            variables = parent_model.config['Fitting'][model]['variables']
        except KeyError as e:
            self.logger.error(str(e) + 'Check config file, model names')
            raise

        return guess, bounds, variables

from prev_projects.DATAFIT.VIEW import GraphView
from prev_projects.DATAFIT.MODEL import FitModel
from prev_projects.DATAFIT.CONTROLLER import FitController
from prev_projects.DATAFIT.HELPFUL import ndarray_tostring

from PyQt5 import QtCore, QtGui
from PyQt5.QtWidgets import (QListWidgetItem,
                             QApplication,
                             QFileDialog)

from numpy import searchsorted, transpose, vstack, column_stack, append, savetxt
import logging
module_logger = logging.getLogger(__name__)


class GraphController():
    """
    Class GraphController is a controller
    which coordinates work between view and model.
    """

    def __init__(self, in_model, param):
        self.logger = logging.getLogger("MAIN." + __name__)
        self.model = in_model
        self.view = GraphView(self, in_parameters=param)
        self.view.show()
        self.model.notifyObservers()
        self.clipboard = QApplication.clipboard()
        self.axhline_SEL = False
        self.axhline_SEL_index = 1
        self.ctr_pressed = False
        self.line_picked = {'kinetics': None, 'spectrum': None}

        if self.model.parentmodel.dev:
            self.fit_clicked()

    def onselectrect(self, eclick, erelease):
        if not self.axhline_SEL:
            self.update_selected_area(eclick.xdata,
                                      erelease.xdata,
                                      eclick.ydata,
                                      erelease.ydata,
                                      real=True)

    def update_selected_area(self, xdata_clicked, xdata_realeased,
                             ydata_clicked, ydata_realeased, real=False):

        self.model.update_cursors((xdata_clicked, xdata_realeased,
                                   ydata_clicked, ydata_realeased),
                                  real=real)

    def on_pick_kinetics(self, event):
        label = event.artist._label
        # key: find pos of ':' in label of line
        pos = label.find('key:')
        # obtain key from _label of line
        if pos != -1:
            key = int(label[pos+4:])
            if self.line_picked['kinetics'] == None:
                self.line_picked['kinetics'] = key
                self.logger.info('kinetics line selected:' + label)
                self.view.statusBar().showMessage('kinetics line selected:' + label, 2000)
            else:
                self.line_picked['kinetics'] = None
                self.logger.info('kinetics line unselected:' + label)
                self.view.statusBar().showMessage('kinetics line unselected:' + label, 2000)

    def on_pick_spectrum(self, event):
        label = event.artist._label
        # key: find pos of ':' in label of line
        pos = label.find('key:')
        # obtain key from _label of line
        if pos != -1:
            key = int(label[pos+4:])
            if self.line_picked['spectrum'] == None:
                self.line_picked['spectrum'] = key
                self.logger.info('spectrum line selected:' + label)
                self.view.statusBar().showMessage('spectrum line selected:' + label, 2000)
            else:
                self.line_picked['spectrum'] = None
                self.logger.info('spectrum line unselected:' + label)
                self.view.statusBar().showMessage('spectrum line unselected:' + label, 2000)

    def key_pressed_kinetics(self, event):
        try:
            if event.key == 'ctrl+c':
                key = self.line_picked['kinetics']
                var = transpose(self.model.copy_data(X=self.model.timedelays,
                                                     Y=self.model.kinetics,
                                                     key=key))
                s = ndarray_tostring(var)
                self.clipboard.setText(s)

            elif event.key == 'ctrl+a':
                self.model.add_kinetics()

            elif event.key == 'delete':
                if self.line_picked['kinetics'] == None:
                    self.model.delete_kinetics()
                else:
                    self.model.delete_kinetics(key_del=self.line_picked['kinetics']) 
        except Exception as e:
            self.logger.error(e)

    def key_pressed_spectra(self, event):
        if event.key == 'ctrl+c':
            key = self.line_picked['spectrum']
            var = transpose(self.model.copy_data(X=self.model.wavelengths,
                                                 Y=self.model.spectra,
                                                 key=key))
            s = ndarray_tostring(var)
            self.clipboard.setText(s)

        elif event.key == 'ctrl+a':
            self.model.add_spectrum()

        elif event.key == 'delete':
            if self.line_picked['spectrum'] == None:
                self.model.delete_spectrum()
            else:
                self.model.delete_spectrum(key_del=self.line_picked['spectrum'])

    def key_pressed(self, event):
        #=======================================================================
        # if event.key in ['A', 'a']:
        #     try:
        #         if self.view.ui.RS.active:
        #             self.view.ui.RS.set_active(False)
        #             self.view.statusBar().showMessage("RectangleSelector deactivated.", 1000)
        #             print(' RectangleSelector deactivated.')
        #         else:
        #             self.view.ui.RS.set_active(True)
        #             self.view.statusBar().showMessage("RectangleSelector activated.", 1000)
        #             print(' RectangleSelector activated.')
        #     except Exception as e:
        #         self.logger.error(str(e))
        #=======================================================================
        try:
            if event.key == 'control':
                self.view.statusBar().showMessage("Ctrl pressed", 2000)
                self.ctr_pressed = True
                self.view.ui.cursor_data.visible = False

            elif event.key == 'ctrl+c':
                data = transpose(self.model.data)
                timedelays = self.model.timedelays
                wavelengths = append(0, self.model.wavelengths)
                data = vstack([timedelays, data])
                data = column_stack([wavelengths, data])
                s = ndarray_tostring(data)
                self.clipboard.setText(s)
        except Exception as e:
            self.logger.error(e)

    def key_released(self, event):
        if event.key == 'control':
            self.view.statusBar().showMessage("Ctrl released", 2000)
            self.ctr_pressed = False
            self.axhline_SEL = False
            self.view.ui.cursor_data.visible = True

    def mouse_pressed(self, event):
        self.axhline_SEL = False
        cursors = self.model.cursors
        min_dist = 20
        key = None
        keyX = None
        keyY = None

        if self.ctr_pressed:
            wavelength = self.model.wavelengths
            timedelays = self.model.timedelays
            xpos, ypos = [(searchsorted(wavelength,
                                        event.xdata,
                                        side='right')),
                          (searchsorted(timedelays,
                                        event.ydata,
                                        side='right'))]

            if abs(xpos - cursors['x1']) < min_dist:
                keyX = 'x1'
                self.axhline_SEL = True

            elif abs(xpos - cursors['x2']) < min_dist:
                keyX = 'x2'
                self.axhline_SEL = True

            if abs(ypos - cursors['y1']) < min_dist:
                keyY = 'y1'
                self.axhline_SEL = True

            elif abs(ypos - cursors['y2']) < min_dist:
                keyY = 'y2'
                self.axhline_SEL = True

            if self.axhline_SEL:

                if keyX and keyY:
                    if abs(xpos - cursors[keyX]) > abs(ypos - cursors[keyY]):
                        key = keyY

                    if abs(xpos - cursors[keyX]) < abs(ypos - cursors[keyY]):
                        key = keyX

                else:
                    if keyX:
                        key = keyX
                    else:
                        key = keyY

                if key == 'x1':
                    self.axhline_SEL_index = 1

                elif key == 'x2':
                    self.axhline_SEL_index = 2

                elif key == 'y1':
                    self.axhline_SEL_index = 3

                elif key == 'y2':
                    self.axhline_SEL_index = 4

    def mouse_moved(self, event):
        modifiers = QtGui.QGuiApplication.keyboardModifiers()
        axhline_SEL_index = self.axhline_SEL_index
        if modifiers == QtCore.Qt.ControlModifier:
            if self.axhline_SEL:
                cursors = self.model.cursors
                timedelays = self.model.timedelays
                wavelengths = self.model.wavelengths

                if axhline_SEL_index == 1:
                    pos = searchsorted(wavelengths, event.xdata, side='right')
                    self.update_selected_area(pos,
                                              cursors['x2'],
                                              cursors['y1'],
                                              cursors['y2'])

                elif axhline_SEL_index == 2:
                    pos = searchsorted(wavelengths, event.xdata, side='right')
                    self.update_selected_area(cursors['x1'],
                                              pos,
                                              cursors['y1'],
                                              cursors['y2'])

                elif axhline_SEL_index == 3:
                    pos = searchsorted(timedelays, event.ydata, side='right')
                    self.update_selected_area(cursors['x1'],
                                              cursors['x2'],
                                              pos,
                                              cursors['y2'])

                elif axhline_SEL_index == 4:
                    pos = searchsorted(timedelays, event.ydata, side='right')
                    self.update_selected_area(cursors['x1'],
                                              cursors['x2'],
                                              cursors['y1'],
                                              pos)

    def slider_moved_X(self, index_slider, start, end):
        self.update_selected_area(start, end,
                                  self.model.cursors['y1'],
                                  self.model.cursors['y2'])

    def slider_moved_Y(self, index_slider, start, end):
        self.update_selected_area(self.model.cursors['x1'],
                                  self.model.cursors['x2'],
                                  start, end)

    def slider_colorbar_moved(self, index_slider, start, end):
        self.view.ui.datacanvas.update_limits(minv=start, maxv=end)

    def fit_clicked(self):
        """
        Handles event generated, when the button "Fit" is pressed.
        """
        fit_model_dict = {'pulse': False, 'constrained': False,
                          'conv': False, 'model': '1exp'}

        fit_model_dict['model'] = self.view.ui.combobox_Fit.currentText()

        fit_model_dict['pulse'] = self.view.ui.checkbox_pulse.isChecked()

        fit_model_dict['constrained'] = self.view.ui.checkbox_constrained.isChecked()

        fit_model_dict['conv'] = self.view.ui.checkbox_conv.isChecked()

        guess, bounds, parameters_order = self.fit_model_init(fit_model_dict)

        timedelays = self.model.timedelays
        kinetics = self.model.kinetics['dynamic'][1]
        norm_factor = self.model.parentmodel.config['Views']['FitCanvas']['Norm']

        fitparam = dict(zip(['fitmodel', 'guess', 'bounds',
                             'variables', 'Norm', 'method',
                             'filepath', 'cursors'],
                            [fit_model_dict, guess, bounds,
                             parameters_order, norm_factor,
                             self.view.ui.combobox_Method.currentText(),
                             self.model.filepath,
                             self.model.cursors]))

        try:
            fitmodel = FitModel(X=timedelays,
                                Y=kinetics,
                                fitparam=fitparam)
            fitcontroller = FitController(fitmodel)
        except (Exception, RuntimeError) as e:
            self.logger.error(e)
        finally:
            self.model.addFit(fitcontroller)
            x = len(self.model.fits)
            fitmodel = ''
            for key, value in fit_model_dict.items():
                fitmodel = fitmodel + key + ': ' + str(value) + '; '
            fitmodel = fitmodel[:-1]
            self.view.ui.list_fits.addItem(QListWidgetItem(str(x) + ': ' + fitmodel))

        try:
            fitcontroller.model.do_fit()
        except Exception as e:
            self.logger.error('Try another function')

    def delete_clicked(self):
        """
        Handles event generated,  when the button "Delete" is pressed.
        """
        listItems = self.view.ui.list_fits.selectedItems()
        del_Fits_indexes = []
        if not listItems:
            return
        i = 0
        for item in listItems:
            self.view.ui.list_fits.setCurrentItem(item)
            index = self.view.ui.list_fits.currentRow() + i
            i += 1
            del_Fits_indexes.append(index)
            self.view.ui.list_fits.takeItem(
                self.view.ui.list_fits.row(item))

        self.model.removeFits(del_Fits_indexes)

    def save_clicked(self):
        data = transpose(self.model.data)
        timedelays = self.model.timedelays
        wavelengths = append(0, self.model.wavelengths)
        data = vstack([timedelays, data])
        data = column_stack([wavelengths, data])
        fdialog = QFileDialog(self.view)
        fdialog.setDirectory('C:')
        filename = fdialog.getSaveFileName(self.view, 'Save 2D map', '',"Images (*.dat)")[0]
        try:
            savetxt(filename, data, delimiter='\t', fmt="%s")
        except Exception as e:
            print(e)

    def lfits_clicked(self):
        """
        Handles event called, when user click on the item of the list of Fits.
        """
        index = self.view.ui.list_fits.currentRow()
        a = self.model.fits[index]
        a.view.show()

    def quit_clicked(self, event):
        close_fits = self.model.fits
        if close_fits:
            for fit in close_fits:
                fit.view.hide()
        self.view.hide()

    def fit_model_init(self, fit_model):
        """
        Fills guess, bounds, variables according to fit_model
        """
        parent_model = self.model.parentmodel
        if fit_model['pulse']:
            model = 'pulse_' + fit_model['model']
        else:
            model = '_' + fit_model['model']

        try:
            guess = parent_model.config['Fitting'][model]['guess']
            bounds = parent_model.config['Fitting'][model]['bounds']
            variables = parent_model.config['Fitting'][model]['variables']
        except KeyError as e:
            self.logger.error(str(e) + 'Check config file, model names')
            raise

        return guess, bounds, variables

Class GraphController is a controller     which coordinates work between view and model. # key: find pos of ':' in label of line # obtain key from _label of line # key: find pos of ':' in label of line # obtain key from _label of line #======================================================================= # if event.key in ['A', 'a']: #     try: #         if self.view.ui.RS.active: #             self.view.ui.RS.set_active(False) #             self.view.statusBar().showMessage("RectangleSelector deactivated.", 1000) #             print(' RectangleSelector deactivated.') #         else: #             self.view.ui.RS.set_active(True) #             self.view.statusBar().showMessage("RectangleSelector activated.", 1000) #             print(' RectangleSelector activated.') #     except Exception as e: #         self.logger.error(str(e)) #======================================================================= Handles event generated, when the button "Fit" is pressed. Handles event generated,  when the button "Delete" is pressed. Handles event called, when user click on the item of the list of Fits. Fills guess, bounds, variables according to fit_model