def __init__(self, ds, main_value):
        super(ThdistSplineUi, self).__init__()
        uic.loadUi('UI/qtdesigner/thdistsplinewindow.ui', self)

        self.ds = ds
        self.main_value = main_value
        self.btn_close.clicked.connect(self.close_window)
        self.m = PlotCanvas(self, width=5, height=4)
        toolbar = NavigationToolbar(self.m, self)
        centralwidget = self.fig_widget
        vbl = QtGui.QVBoxLayout(centralwidget)
        vbl.addWidget(toolbar)
        vbl.addWidget(self.m)
        self.step = 0.05  # step to move on arrow click

        config_file = load_config_file('UI/config/init_values.csv')
        self.default_pts = [
            config_file['tspline_pts_x'], config_file['tspline_pts_y']
        ]

        try:
            self.get_spline_pts()
        except:
            self.points = np.array([self.default_pts[0],
                                    self.default_pts[1]]).T

        # run once on window open
        self.update_plot()

        # Connect Buttons to updating plot.
        self.p1_down.clicked.connect(self.update_p1_down)
        self.p1_up.clicked.connect(self.update_p1_up)
        self.p1_left.clicked.connect(self.update_p1_left)
        self.p1_right.clicked.connect(self.update_p1_right)

        self.p2_left.clicked.connect(self.update_p2_left)
        self.p2_right.clicked.connect(self.update_p2_right)

        self.p3_down.clicked.connect(self.update_p3_down)
        self.p3_up.clicked.connect(self.update_p3_up)
        self.p3_left.clicked.connect(self.update_p3_left)
        self.p3_right.clicked.connect(self.update_p3_right)

        # Connect buttons for saving and reset
        self.btn_save.clicked.connect(self._return)
        self.btn_reset.clicked.connect(self.reset_pts)
    def __init__(self, ds, offset):
        super(AnnulusUi, self).__init__()
        uic.loadUi('UI/qtdesigner/annuluswindow.ui', self)
        self.restraints = load_config_file('UI/config/restraints_annulus.txt')
        self.m = PlotCanvas(self, width=5, height=4)
        toolbar = NavigationToolbar(self.m, self)
        centralwidget = self.fig_widget
        vbl = QtGui.QVBoxLayout(centralwidget)
        vbl.addWidget(toolbar)
        vbl.addWidget(self.m)

        self.ds = ds
        self.offset = offset
        # init variables
        self.r_inner = .3
        self.nblades = 30
        self.scale = 100

        # restraints for widgets
        self.set_restraints(self.restraints['nblades'], self.label_nblades,
                            self.slider_nblades)
        self.set_restraints(self.restraints['r'], self.label_r, self.slider_r,
                            self.scale)

        # link label and slider
        self.label_r.editingFinished.connect(self.update_box_r)
        self.slider_r.valueChanged[int].connect(self.update_r)
        self.label_nblades.editingFinished.connect(self.update_box_nblades)
        self.slider_nblades.valueChanged[int].connect(self.update_nblades)

        self.btn_update.clicked.connect(self.update_plot)
        self.btn_close.clicked.connect(self.close_window)

        # TODO: seperating between single and tandem and the blade generation is obsolete (blade is a line in z-view),
        #  but might be useful if a 'z'-shape is required in the future

        if self.ds['type'] == 'single':
            self.blade1, *_ = self.build_blades()
            _instance = AnnulusGen(self.nblades, self.r_inner, self.blade1)
            self.blade_list = _instance.generate()
        else:
            self.blade1, self.blade2 = self.build_blades()
            _instance = AnnulusGen(self.nblades, self.r_inner, self.blade1,
                                   self.blade2)
            self.blade_list = _instance.generate()
    def init_variables(self):
        """
        Initialize variables at GUI start
        """
        init_val = load_config_file("UI/config/init_values.csv")
        # Slider only accepts int values, so floats need to be scaled
        self.scale = init_val['scale']
        # points at GUI start are set to 9999, which initializes the default pattern for camber spline
        self.camber_spline_pts = np.ones((3, 2)) * 9999
        # offset for moving 2nd blade
        self.blade2_offset = [0, 0]  # X,Y
        self.in_blade_offset = [0, 0]
        self.imported_blade_vis = 0
        # fixed parameters since they wont be changed anyways
        self.length_chord = init_val['lchord']
        self.number_of_points = init_val['npts']
        self.state = 0

        # init points for camber and thickness spline
        self.camber_spline_pts = np.array(
            [init_val['cspline_pts_x'], init_val['cspline_pts_y']]).T
        self.thdist_spline_pts = np.array(
            [init_val['tspline_pts_x'], init_val['tspline_pts_y']]).T
        str_pts = "%f,%f;%f,%f;%f,%f;%f,%f;%f,%f" % (
            self.camber_spline_pts[0, 0], self.camber_spline_pts[0, 1],
            self.camber_spline_pts[1, 0], self.camber_spline_pts[1, 1],
            self.camber_spline_pts[2, 0], self.camber_spline_pts[2, 1],
            self.camber_spline_pts[3, 0], self.camber_spline_pts[3, 1],
            self.camber_spline_pts[4, 0], self.camber_spline_pts[4, 1])
        str_pts_th = "%f,%f;%f,%f;%f,%f;%f,%f;%f,%f" % (
            self.thdist_spline_pts[0, 0], self.thdist_spline_pts[0, 1],
            self.thdist_spline_pts[1, 0], self.thdist_spline_pts[1, 1],
            self.thdist_spline_pts[2, 0], self.thdist_spline_pts[2, 1],
            self.thdist_spline_pts[3, 0], self.thdist_spline_pts[3, 1],
            self.thdist_spline_pts[4, 0], self.thdist_spline_pts[4, 1])
        self.returned_values.setText(str_pts)
        self.returned_values_th.setText(str_pts_th)

        ### Optimizer variables
        self.opt_param = {}
        self.opt_param["niter"] = 1000
    def __init__(self):
        super(Ui, self).__init__()

        uic.loadUi('UI/qtdesigner/mainwindow.ui', self)
        # Software version. If the version does not match, a continuation of a log is not possible (due to conflicts in
        # implementation).
        self.VERSION = "0.2"

        # declaring param keys, load restraints for slider
        self.param_keys = [
            'alpha1', 'alpha2', 'lambd', 'th', 'xmax_th', 'xmax_camber',
            'gamma_te', 'th_le', 'th_te', 'dist_blades', 'PP', 'AO',
            'chord_dist'
        ]
        self.restraints = load_config_file('UI/config/restraints.txt')
        self.menu_default()  # set menu defaults
        self.init_variables()  # initialize some variables at GUI start
        self.init_slider_control()

        # see silent exception messages on crash
        sys._excepthook = sys.excepthook

        def exception_hook(exctype, value, traceback):
            print(exctype, value, traceback)
            sys._excepthook(exctype, value, traceback)
            sys.exit(1)

        sys.excepthook = exception_hook

        # tabs
        self.tabWidget.setTabText(0, "BladeDesigner")
        self.tabWidget.setTabText(1, "Optimizer")
        self.tabWidget.setCurrentIndex(1)  # set default tab

        # init plot
        self.m = PlotCanvas(self, width=8, height=10)
        toolbar = NavigationToolbar(self.m, self)
        centralwidget = self.fig_widget
        vbl = QtGui.QVBoxLayout(centralwidget)
        vbl.addWidget(toolbar)
        vbl.addWidget(self.m)

        # link buttons
        self.btn_update_all.clicked.connect(self.update_all)
        self.btn_update_sel.clicked.connect(self.update_select)
        self.reset = self.findChild(QtWidgets.QPushButton, 'btn_default')
        self.reset.clicked.connect(self.set_default)
        self.btn_hide_import.clicked.connect(self.update_imported_blade)

        # radio
        self.radio_blade1.toggled.connect(self.update_radio_blades)

        # menu
        self.thdist_V1.triggered.connect(self.update_thdist_V1)
        self.thdist_V2.triggered.connect(self.update_thdist_V2)
        self.nblades_single.triggered.connect(self.update_nblades_single)
        self.nblades_tandem.triggered.connect(self.update_nblades_tandem)
        self.actionAnnulus.triggered.connect(self.annulus_window)
        self.actionload_from_file.triggered.connect(self.openFileNameDialog)
        self.actionsave_as_txt.triggered.connect(self.saveFileDialog)
        self.actionCredential.triggered.connect(self.ssh_config_window)

        # save/load blade config
        self.actionSave_config.triggered.connect(self.save_config)
        self.actionLoad_config.triggered.connect(self.load_config)
        """ Camber Spline window """
        # open camber spline popup on click
        self.btn_spline_camber.clicked.connect(self.camber_spline_window)
        # get camber spline values from window
        self.returned_values.textChanged.connect(self.get_spline_pts)
        """ Thickness Spline window """
        # open camber spline popup on click
        self.btn_spline_th.clicked.connect(self.thdist_spline_window)

        # get camber spline values from window
        self.returned_values_th.textChanged.connect(self.get_spline_th_pts)

        self.update_in_control_vis(0)
        self.btn_in_up.clicked.connect(self.update_in_up)
        self.btn_in_down.clicked.connect(self.update_in_down)
        self.btn_in_left.clicked.connect(self.update_in_left)
        self.btn_in_right.clicked.connect(self.update_in_right)
        """ Optimizer links """
        # init deap config window
        self.deap_config_ui = DeapConfigUi()

        # open 3Point settings
        self.three_point_settings_ui = ThreePointSettingsUI()
        self.btn_3point_settings.clicked.connect(
            self.three_point_settings_window)

        # optimizer inits
        self.optim_handler_init()

        # run once on startup
        # load default blades
        self.update_all()
        self.load_config(Path(os.getcwd() + '/UI/config/default_blade.csv'))
        # self.select_blade = 1
        self.update_select()
        self.select_blade = 2
        self.update_select()
        # self.select_blade = 1

        self.show()