# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'v0.2.0.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.

import mrcfile as mf
import numpy as np

from matplotlib.backends.qt_compat import QtWidgets
from matplotlib.backends.backend_qtagg import (
    FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure

# Ensure using PyQt5 backend
import matplotlib
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as Canvas
matplotlib.use('QT5Agg')

import scipy
from scipy import ndimage

from PyQt5 import QtCore, QtGui, QtWidgets

try:
    import estimate, map_tools, occupancy, vis, solvent, extras, args              # for pyCharm
except:
    from occupy import estimate, map_tools, occupancy, vis, solvent, extras, args   # for terminal use

from io import StringIO
import sys


class EMDB_dialog(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(EMDB_dialog, self).__init__(parent)
        self.id = None

    def make_dialog(self):
        self.setObjectName("Fetch EMDB")
        self.setEnabled(True)
        self.resize(100,90)

        self.spinBox = QtWidgets.QSpinBox(self)
        self.spinBox.setGeometry(10,10,80,30)
        self.spinBox.setSpecialValueText('-')
        self.spinBox.setMaximum(99999)

        self.button = QtWidgets.QToolButton(self)
        self.button.setGeometry(10,50,80,30)
        self.button.setText("Fetch")
        self.button.clicked.connect(self.update_id)

    def update_id(self):
        self.id = self.spinBox.value()
        self.close()

class Capturing(list):
    def __enter__(self):
        self._stdout = sys.stdout
        sys.stdout = self._stringio = StringIO()
        return self

    def __exit__(self, *args):
        self.extend(self._stringio.getvalue().splitlines())
        del self._stringio  # free up some memory
        sys.stdout = self._stdout

# Matplotlib canvas class to create figure
class InputMapProperties():
    def __init__(self):
        self.voxel_size_ori = -1
        self.voxel_size_proc = -1
        self.lowpass = -1
        self.kernel_size = -1
        self.kernel_radius = -1
        self.kernel_nv = -1
        self.kernel_tau = -1

# Matplotlib canvas class to create figure
class MplCanvas(Canvas):
    def __init__(self):
        self.fig = Figure()
        self.ax = self.fig.add_subplot(111)
        #self.fig.tight_layout()

        Canvas.__init__(self, self.fig)
        Canvas.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        Canvas.updateGeometry(self)

# Matplotlib widget
class MplWidget(QtWidgets.QWidget):
    def __init__(self,parent=None):
        QtWidgets.QWidget.__init__(self, parent)   # Inherit from QWidget
        self.canvas = MplCanvas()                  # Create canvas object
        self.vbl = QtWidgets.QVBoxLayout()         # Set box for plotting
        self.vbl.addWidget(self.canvas)
        self.setLayout(self.vbl)

        self.amplify = False
        self.amplification_power=2.0

        self.attenuate = False
        self.attenuation_power=2.0

        self.sigmoid = False
        self.sigmoid_power=3.0
        self.sigmoid_pivot=0.2

    def update_sigmoid_power(self, power):
        self.sigmoid = True
        self.sigmoid_power = power # self.parent.horizontalSlider_3.value()
        self.plot_modification()
        #self.sigmoid_power = self.parent().horizontalSlider_5.value()

    def update_sigmoid_pivot(self, pivot):
        self.sigmoid = True
        self.sigmoid_pivot = pivot / 100.0 # self.parent.horizontalSlider_3.value()
        self.plot_modification()


    def update_amplification_power(self, power):
        self.amplify = True
        self.amplification_power = power
        self.plot_modification()

    def update_attenuation_power(self, power):
        self.attenuate = True
        self.attenuation_power = power
        self.plot_modification()


    def plot_modification(self):
        anything = False
        self.canvas.ax.clear()
        x = np.linspace(0, 1, 100)
        if self.amplify:
            self.canvas.ax.plot(x, x ** (1 / self.amplification_power), 'C0')
            anything =True
        if self.attenuate:
            self.canvas.ax.plot(x, x ** (self.attenuation_power), 'C1')
            anything = True
        if self.sigmoid:
            x, y = occupancy.scale_mapping_sigmoid(self.sigmoid_pivot,self.sigmoid_power)
            self.canvas.ax.plot(x, y, 'C2')
            self.canvas.ax.plot(self.sigmoid_pivot, self.sigmoid_pivot, 'ko')
            anything = True
        if anything:
            self.canvas.ax.plot([0, 1], [0, 1], 'k--')

        self.canvas.draw()



class Ui_Dialog(object):
    def setupUi(self, Dialog):
        from pathlib import Path
        Dialog.setObjectName("Dialog")
        Dialog.setEnabled(True)
        Dialog.resize(684, 821)
        Dialog.setAcceptDrops(True)
        icon = QtGui.QIcon()
        icon_square = QtGui.QIcon()
        icon_image = f'{Path(__file__).parent.parent}/resources/logo_square.png'
        icon_square.addPixmap(QtGui.QPixmap(icon_image), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        Dialog.setWindowIcon(icon_square)
        Dialog.setSizeGripEnabled(False)
        Dialog.setModal(False)

        self.inputMap = InputMapProperties()
        self.confidence_file_name = None
        self.chimerax_file_name = None
        self.solModel_file_name = None
        self.scale_file_name = None
        self.occ_scale = None
        self.res_scale = None

        self.cmd = []

        # Input map
        self.horizontalLayoutWidget = QtWidgets.QWidget(Dialog)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(90, 10, 581, 31))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout_inputMap = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout_inputMap.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_inputMap.setObjectName("horizontalLayout_inputMap")
        self.comboBox_inputMap = QtWidgets.QComboBox(self.horizontalLayoutWidget)
        self.comboBox_inputMap.setObjectName("comboBox_inputMap")
        self.horizontalLayout_inputMap.addWidget(self.comboBox_inputMap, 0, QtCore.Qt.AlignVCenter)
        self.toolButton_inputMap_browse = QtWidgets.QToolButton(self.horizontalLayoutWidget)
        self.toolButton_inputMap_browse.setObjectName("toolButton_inputMap_browse")
        self.horizontalLayout_inputMap.addWidget(self.toolButton_inputMap_browse)
        self.toolButton_inputMap_emdb = QtWidgets.QToolButton(self.horizontalLayoutWidget)
        self.toolButton_inputMap_emdb.setObjectName("toolButton_inputMap_emdb")
        self.horizontalLayout_inputMap.addWidget(self.toolButton_inputMap_emdb)

        self.toolButton_clearLog = QtWidgets.QToolButton(Dialog)
        self.toolButton_clearLog.setGeometry(550,610,121,24)
        self.toolButton_clearLog.setObjectName("toolButton_clearLog")

        self.toolButton_chimerax = QtWidgets.QToolButton(Dialog)
        self.toolButton_chimerax.setGeometry(550,640,121,24)
        self.toolButton_chimerax.setObjectName("toolButton_chimerax")
        self.toolButton_chimerax.setEnabled(False)

        #self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
        #self.buttonBox.setGeometry(QtCore.QRect(580, 640, 91, 21))
        #self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        #self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Abort)
        #self.buttonBox.setCenterButtons(False)
        #self.buttonBox.setObjectName("buttonBox")

        self.tabWidget_modification = QtWidgets.QTabWidget(Dialog)
        self.tabWidget_modification.setGeometry(QtCore.QRect(10, 240, 261, 131))
        self.tabWidget_modification.setObjectName("tabWidget_modification")
        self.tab_amplification = QtWidgets.QWidget()
        self.tab_amplification.setObjectName("tab_amplification")
        self.groupBox_amplification = QtWidgets.QGroupBox(self.tab_amplification)
        self.groupBox_amplification.setGeometry(QtCore.QRect(0, 10, 241, 81))
        self.groupBox_amplification.setTitle("")
        self.groupBox_amplification.setCheckable(True)
        self.groupBox_amplification.setChecked(False)
        self.groupBox_amplification.setObjectName("groupBox_amplification")
        self.gridLayoutWidget_3 = QtWidgets.QWidget(self.groupBox_amplification)
        self.gridLayoutWidget_3.setGeometry(QtCore.QRect(0, 20, 241, 61))
        self.gridLayoutWidget_3.setObjectName("gridLayoutWidget_3")
        self.gridLayout_amplification = QtWidgets.QGridLayout(self.gridLayoutWidget_3)
        self.gridLayout_amplification.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_amplification.setObjectName("gridLayout_amplification")
        self.doubleSpinBox_amplPower = QtWidgets.QDoubleSpinBox(self.gridLayoutWidget_3)
        self.doubleSpinBox_amplPower.setDecimals(1)
        self.doubleSpinBox_amplPower.setMinimum(1.0)
        self.doubleSpinBox_amplPower.setSingleStep(0.1)
        self.doubleSpinBox_amplPower.setMaximum(30.0)
        self.doubleSpinBox_amplPower.setProperty("value", 1.0)
        self.doubleSpinBox_amplPower.setObjectName("doubleSpinBox_amplPower")
        self.gridLayout_amplification.addWidget(self.doubleSpinBox_amplPower, 0, 2, 1, 1)
        self.label_amplPower = QtWidgets.QLabel(self.gridLayoutWidget_3)
        self.label_amplPower.setEnabled(False)
        self.label_amplPower.setObjectName("label_amplPower")
        self.gridLayout_amplification.addWidget(self.label_amplPower, 0, 0, 1, 1)
        self.horizontalSlider_amplPower = QtWidgets.QSlider(self.gridLayoutWidget_3)
        self.horizontalSlider_amplPower.setMinimum(10)
        self.horizontalSlider_amplPower.setMaximum(300)
        self.horizontalSlider_amplPower.setSingleStep(1)
        self.horizontalSlider_amplPower.setPageStep(10)
        self.horizontalSlider_amplPower.setProperty("value", 10)
        self.horizontalSlider_amplPower.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider_amplPower.setObjectName("horizontalSlider_amplPower")
        self.gridLayout_amplification.addWidget(self.horizontalSlider_amplPower, 0, 1, 1, 1)
        self.tabWidget_modification.addTab(self.tab_amplification, "")
        self.tab_attenuation = QtWidgets.QWidget()
        self.tab_attenuation.setObjectName("tab_attenuation")
        self.groupBox_attenuation = QtWidgets.QGroupBox(self.tab_attenuation)
        self.groupBox_attenuation.setGeometry(QtCore.QRect(0, 10, 241, 81))
        self.groupBox_attenuation.setTitle("")
        self.groupBox_attenuation.setCheckable(True)
        self.groupBox_attenuation.setChecked(False)
        self.groupBox_attenuation.setObjectName("groupBox_attenuation")
        self.gridLayoutWidget_4 = QtWidgets.QWidget(self.groupBox_attenuation)
        self.gridLayoutWidget_4.setGeometry(QtCore.QRect(0, 20, 241, 60))
        self.gridLayoutWidget_4.setObjectName("gridLayoutWidget_4")
        self.gridLayout_attenuation = QtWidgets.QGridLayout(self.gridLayoutWidget_4)
        self.gridLayout_attenuation.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_attenuation.setObjectName("gridLayout_attenuation")
        self.label_attnPower = QtWidgets.QLabel(self.gridLayoutWidget_4)
        self.label_attnPower.setEnabled(False)
        self.label_attnPower.setObjectName("label_attnPower")
        self.gridLayout_attenuation.addWidget(self.label_attnPower, 0, 0, 1, 1)
        self.doubleSpinBox_attnPower = QtWidgets.QDoubleSpinBox(self.gridLayoutWidget_4)
        self.doubleSpinBox_attnPower.setDecimals(1)
        self.doubleSpinBox_attnPower.setMinimum(1.0)
        self.doubleSpinBox_attnPower.setMaximum(30.0)
        self.doubleSpinBox_attnPower.setProperty("value", 1.0)
        self.doubleSpinBox_attnPower.setObjectName("doubleSpinBox_attnPower")
        self.gridLayout_attenuation.addWidget(self.doubleSpinBox_attnPower, 0, 2, 1, 1)
        self.horizontalSlider_attnPower = QtWidgets.QSlider(self.gridLayoutWidget_4)
        self.horizontalSlider_attnPower.setMinimum(10)
        self.horizontalSlider_attnPower.setMaximum(300)
        self.horizontalSlider_attnPower.setSingleStep(10)
        self.horizontalSlider_attnPower.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider_attnPower.setObjectName("horizontalSlider_attnPower")
        self.gridLayout_attenuation.addWidget(self.horizontalSlider_attnPower, 0, 1, 1, 1)
        self.tabWidget_modification.addTab(self.tab_attenuation, "")
        self.tab_sigmoid = QtWidgets.QWidget()
        self.tab_sigmoid.setObjectName("tab_sigmoid")
        self.groupBox_sigmoid = QtWidgets.QGroupBox(self.tab_sigmoid)
        self.groupBox_sigmoid.setGeometry(QtCore.QRect(0, 10, 241, 81))
        self.groupBox_sigmoid.setTitle("")
        self.groupBox_sigmoid.setCheckable(True)
        self.groupBox_sigmoid.setChecked(False)
        self.groupBox_sigmoid.setObjectName("groupBox_sigmoid")
        self.gridLayoutWidget_5 = QtWidgets.QWidget(self.groupBox_sigmoid)
        self.gridLayoutWidget_5.setGeometry(QtCore.QRect(0, 20, 241, 60))
        self.gridLayoutWidget_5.setObjectName("gridLayoutWidget_5")
        self.gridLayout_sigmoid = QtWidgets.QGridLayout(self.gridLayoutWidget_5)
        self.gridLayout_sigmoid.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_sigmoid.setObjectName("gridLayout_sigmoid")
        self.horizontalSlider_sigmoidPower = QtWidgets.QSlider(self.gridLayoutWidget_5)
        self.horizontalSlider_sigmoidPower.setMinimum(10)
        self.horizontalSlider_sigmoidPower.setMaximum(300)
        self.horizontalSlider_sigmoidPower.setSingleStep(10)
        self.horizontalSlider_sigmoidPower.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider_sigmoidPower.setObjectName("horizontalSlider_sigmoidPower")
        self.gridLayout_sigmoid.addWidget(self.horizontalSlider_sigmoidPower, 0, 1, 1, 1)
        self.doubleSpinBox_sigmoidPivot = QtWidgets.QDoubleSpinBox(self.gridLayoutWidget_5)
        self.doubleSpinBox_sigmoidPivot.setDecimals(1)
        self.doubleSpinBox_sigmoidPivot.setMinimum(1.0)
        self.doubleSpinBox_sigmoidPivot.setMaximum(99.0)
        self.doubleSpinBox_sigmoidPivot.setProperty("value", 20.0)
        self.doubleSpinBox_sigmoidPivot.setObjectName("doubleSpinBox_sigmoidPivot")
        self.gridLayout_sigmoid.addWidget(self.doubleSpinBox_sigmoidPivot, 1, 2, 1, 1)
        self.horizontalSlider_sigmoidPivot = QtWidgets.QSlider(self.gridLayoutWidget_5)
        self.horizontalSlider_sigmoidPivot.setMinimum(1)
        self.horizontalSlider_sigmoidPivot.setMaximum(99)
        self.horizontalSlider_sigmoidPivot.setPageStep(1)
        self.horizontalSlider_sigmoidPivot.setProperty("value", 20)
        self.horizontalSlider_sigmoidPivot.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider_sigmoidPivot.setObjectName("horizontalSlider_sigmoidPivot")
        self.gridLayout_sigmoid.addWidget(self.horizontalSlider_sigmoidPivot, 1, 1, 1, 1)
        self.label_sigmoidPower = QtWidgets.QLabel(self.gridLayoutWidget_5)
        self.label_sigmoidPower.setEnabled(False)
        self.label_sigmoidPower.setObjectName("label_sigmoidPower")
        self.gridLayout_sigmoid.addWidget(self.label_sigmoidPower, 0, 0, 1, 1)
        self.label_sigmoidPivot = QtWidgets.QLabel(self.gridLayoutWidget_5)
        self.label_sigmoidPivot.setEnabled(False)
        self.label_sigmoidPivot.setObjectName("label_sigmoidPivot")
        self.gridLayout_sigmoid.addWidget(self.label_sigmoidPivot, 1, 0, 1, 1)
        self.doubleSpinBox_sigmoidPower = QtWidgets.QDoubleSpinBox(self.gridLayoutWidget_5)
        self.doubleSpinBox_sigmoidPower.setDecimals(1)
        self.doubleSpinBox_sigmoidPower.setMinimum(1.0)
        self.doubleSpinBox_sigmoidPower.setMaximum(30.0)
        self.doubleSpinBox_sigmoidPower.setProperty("value", 1.0)
        self.doubleSpinBox_sigmoidPower.setObjectName("doubleSpinBox_sigmoidPower")
        self.gridLayout_sigmoid.addWidget(self.doubleSpinBox_sigmoidPower, 0, 2, 1, 1)
        self.tabWidget_modification.addTab(self.tab_sigmoid, "")
        self.checkBox_verbose = QtWidgets.QCheckBox(Dialog)
        self.checkBox_verbose.setGeometry(QtCore.QRect(10, 600, 81, 41))
        self.checkBox_verbose.setObjectName("checkBox_verbose")
        self.checkBox_showCmd = QtWidgets.QCheckBox(Dialog)
        self.checkBox_showCmd.setGeometry(QtCore.QRect(100, 600, 171, 41))
        self.checkBox_showCmd.setToolTip("")
        self.checkBox_showCmd.setAccessibleDescription("")
        self.checkBox_showCmd.setObjectName("checkBox_showCmd")
        self.tabWidget_view = QtWidgets.QTabWidget(Dialog)
        self.tabWidget_view.setEnabled(True)
        self.tabWidget_view.setGeometry(QtCore.QRect(280, 50, 391, 421))
        self.tabWidget_view.setMinimumSize(QtCore.QSize(319, 350))
        self.tabWidget_view.setMaximumSize(QtCore.QSize(10000, 10000))
        self.tabWidget_view.setObjectName("tabWidget_view")
        self.tab_viewInput = QtWidgets.QWidget()
        self.tab_viewInput.setEnabled(True)
        self.tab_viewInput.setObjectName("tab_viewInput")

        self.label_viewInput = QtWidgets.QLabel(self.tab_viewInput)
        self.label_viewInput.setGeometry(QtCore.QRect(0, 0, 391, 391))
        self.label_viewInput.setMinimumSize(QtCore.QSize(320, 320))
        self.label_viewInput.setMaximumSize(QtCore.QSize(1000, 1000))
        self.label_viewInput.setMouseTracking(False)
        self.label_viewInput.setFrameShape(QtWidgets.QFrame.Box)
        self.label_viewInput.setText("Load an input file (.map/.mrc)")
        self.label_viewInput.setAlignment(QtCore.Qt.AlignCenter)
        self.label_viewInput.setEnabled(False)


        self.label_viewInput.setObjectName("label_viewInput")
        self.tabWidget_view.addTab(self.tab_viewInput, "")
        self.tab_viewScale = QtWidgets.QWidget()
        self.tab_viewScale.setEnabled(True)
        self.tab_viewScale.setObjectName("tab_viewScale")

        self.label_viewScale = QtWidgets.QLabel(self.tab_viewScale)
        self.label_viewScale.setGeometry(QtCore.QRect(0, 0, 391, 391))
        self.label_viewScale.setMinimumSize(QtCore.QSize(320, 320))
        self.label_viewScale.setMaximumSize(QtCore.QSize(1000, 1000))
        self.label_viewScale.setFrameShape(QtWidgets.QFrame.Box)
        self.label_viewScale.setText("Run occupy or \n load a scale (.map/.mrc)")
        self.label_viewScale.setAlignment(QtCore.Qt.AlignCenter)
        self.label_viewScale.setEnabled(False)

        self.label_viewScale.setObjectName("label_viewScale")
        self.tabWidget_view.addTab(self.tab_viewScale, "")
        self.tab_viewConfidence = QtWidgets.QWidget()
        self.tab_viewConfidence.setObjectName("tab_viewConfidence")

        self.label_viewConfidence = QtWidgets.QLabel(self.tab_viewConfidence)
        self.label_viewConfidence.setGeometry(QtCore.QRect(0, 0, 391, 391))
        self.label_viewConfidence.setMinimumSize(QtCore.QSize(320, 320))
        self.label_viewConfidence.setMaximumSize(QtCore.QSize(1000, 1000))
        self.label_viewConfidence.setFrameShape(QtWidgets.QFrame.Box)
        self.label_viewConfidence.setText("Confidence is dependent on a \n "
                                        "solvent model, and is  shown when \n "
                                        "occupy has been run.")
        self.label_viewConfidence.setAlignment(QtCore.Qt.AlignCenter)
        self.label_viewConfidence.setEnabled(False)
        self.label_viewConfidence.setObjectName("label_viewConfidence")
        self.label_viewConfidence.raise_()

        self.tabWidget_view.addTab(self.tab_viewConfidence, "")
        self.tab_solvDef = QtWidgets.QWidget()
        self.tab_solvDef.setEnabled(True)
        self.tab_solvDef.setObjectName("tab_solvDef")
        self.label_viewSolDef = QtWidgets.QLabel(self.tab_solvDef)
        self.label_viewSolDef.setGeometry(QtCore.QRect(0, 0, 391, 391))
        self.label_viewSolDef.setMinimumSize(QtCore.QSize(320, 320))
        self.label_viewSolDef.setMaximumSize(QtCore.QSize(1000, 1000))
        self.label_viewSolDef.setFrameShape(QtWidgets.QFrame.Box)
        self.label_viewSolDef.setText("Provide a solvent definition (.map/.mrc) \n "
                                      "to help contruct a solvent model. You can \n "
                                      "provide a conventional solvent mask, but \n"
                                      "occupy will not use it to mask.  \n\n"
                                      "A solvent definition is optional input.")
        self.label_viewSolDef.setAlignment(QtCore.Qt.AlignCenter)
        self.label_viewSolDef.setEnabled(False)

        self.label_viewSolDef.setObjectName("label_viewSolDef")
        self.tabWidget_view.addTab(self.tab_solvDef, "")
        self.tab_viewModification = QtWidgets.QWidget()
        self.tab_viewModification.setEnabled(True)
        self.tab_viewModification.setObjectName("tab_viewModification")
        self.MplWidget_viewModification = MplWidget(self.tab_viewModification)
        self.MplWidget_viewModification.setGeometry(QtCore.QRect(0, 0, 391, 391))
        self.MplWidget_viewModification.setMinimumSize(QtCore.QSize(320, 320))
        self.MplWidget_viewModification.setMaximumSize(QtCore.QSize(400, 400))
        self.MplWidget_viewModification.setObjectName("MplWidget_viewModification")

        self.tabWidget_view.addTab(self.tab_viewModification, "")
        self.tab_viewOutput = QtWidgets.QWidget()
        self.tab_viewOutput.setEnabled(True)
        self.tab_viewOutput.setObjectName("tab_viewOutput")

        self.label_viewOutput = QtWidgets.QLabel(self.tab_viewOutput)
        self.label_viewOutput.setGeometry(QtCore.QRect(0, 0, 391, 391))
        self.label_viewOutput.setMinimumSize(QtCore.QSize(320, 320))
        self.label_viewOutput.setMaximumSize(QtCore.QSize(1000, 1000))
        self.label_viewOutput.setFrameShape(QtWidgets.QFrame.Box)
        self.label_viewOutput.setText("This is a preview of the modification \n"
                                      "by the chosen scale. \n\n"
                                      "To view a preview, you need \n "
                                      "to have selected both \n"
                                      "  1) an input map       &   \n"
                                      "  2) an estimated scale  \n\n"
                                      "The loaded scale must be \n"
                                      "an occupancy-based scale. \n\n"
                                      "The preview is rough, you will have to \n"
                                      "run occupy to get accurate modification \n"
                                      "maps written to disk.")
        self.label_viewOutput.setAlignment(QtCore.Qt.AlignCenter)
        self.label_viewOutput.setEnabled(False)
        self.label_viewOutput.setObjectName("label_viewOutput")
        self.label_viewOutput.raise_()

        self.tabWidget_view.addTab(self.tab_viewOutput, "")
        self.tabWidget_output = QtWidgets.QTabWidget(Dialog)
        self.tabWidget_output.setGeometry(QtCore.QRect(10, 640, 661, 171))
        self.tabWidget_output.setObjectName("tabWidget_output")
        self.tabWidget_output.setStyleSheet('''
        QTabWidget::tab-bar {
            alignment: left;
        }''')
        self.tab_log = QtWidgets.QWidget()
        self.tab_log.setObjectName("tab_log")
        self.gridLayoutWidget_8 = QtWidgets.QWidget(self.tab_log)
        self.gridLayoutWidget_8.setGeometry(QtCore.QRect(0, 0, 661, 141))
        self.gridLayoutWidget_8.setObjectName("gridLayoutWidget_8")
        self.gridLayout_log = QtWidgets.QGridLayout(self.gridLayoutWidget_8)
        self.gridLayout_log.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_log.setObjectName("gridLayout_log")
        self.textEdit_log = QtWidgets.QTextEdit(self.gridLayoutWidget_8)
        self.textEdit_log.setReadOnly(True)
        self.textEdit_log.setObjectName("textEdit_log")
        self.gridLayout_log.addWidget(self.textEdit_log, 0, 0, 1, 1)
        self.tabWidget_output.addTab(self.tab_log, "")
        #self.tab_hist = QtWidgets.QWidget()
        #self.tab_hist.setObjectName("tab_hist")
        #self.MplWidget_hist = MplWidget(self.tab_hist)
        #self.MplWidget_hist.setGeometry(QtCore.QRect(0, 0, 671, 141))
        #self.MplWidget_hist.setMinimumSize(QtCore.QSize(320, 100))
        #self.MplWidget_hist.setMaximumSize(QtCore.QSize(1000, 400))
        #self.MplWidget_hist.setObjectName("MplWidget_hist")
        #self.tabWidget_output.addTab(self.tab_hist, "")
        self.tab_solventModel = QtWidgets.QWidget()
        self.tab_solventModel.setObjectName("tab_solventModel")

        self.label_solventModel = QtWidgets.QLabel(self.tab_solventModel)
        self.label_solventModel.setGeometry(QtCore.QRect(0, 0, 671, 141))
        self.label_solventModel.setMinimumSize(QtCore.QSize(320, 100))
        self.label_solventModel.setMaximumSize(QtCore.QSize(1000, 400))
        self.label_solventModel.setObjectName("label_solventModel")
        self.label_solventModel.setFrameShape(QtWidgets.QFrame.Box)
        self.label_solventModel.setText("Run occupy to \n view the solvent model")
        self.label_solventModel.setAlignment(QtCore.Qt.AlignCenter)

        self.toolButton_expandSolModel=QtWidgets.QToolButton(self.label_solventModel)
        self.toolButton_expandSolModel.setGeometry(QtCore.QRect(580, 10, 70, 20))
        self.toolButton_expandSolModel.setText("Full view")
        self.toolButton_expandSolModel.setEnabled(False)

        #self.label_solventModel.setEnabled(False)

        self.tabWidget_output.addTab(self.tab_solventModel, "")
        self.gridLayoutWidget = QtWidgets.QWidget(Dialog)
        self.gridLayoutWidget.setGeometry(QtCore.QRect(280, 480, 391, 31))
        self.gridLayoutWidget.setObjectName("gridLayoutWidget")
        self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setObjectName("gridLayout")
        self.spinBox_viewSlice = QtWidgets.QSpinBox(self.gridLayoutWidget)
        self.spinBox_viewSlice.setEnabled(True)
        self.spinBox_viewSlice.setMouseTracking(False)
        self.spinBox_viewSlice.setWrapping(False)
        self.spinBox_viewSlice.setFrame(True)
        self.spinBox_viewSlice.setReadOnly(False)
        self.spinBox_viewSlice.setKeyboardTracking(True)
        self.spinBox_viewSlice.setProperty("showGroupSeparator", False)
        self.spinBox_viewSlice.setMinimum(1)
        self.spinBox_viewSlice.setMaximum(128)
        self.spinBox_viewSlice.setSingleStep(1)
        self.spinBox_viewSlice.setStepType(QtWidgets.QAbstractSpinBox.DefaultStepType)
        self.spinBox_viewSlice.setProperty("value", 64)
        self.spinBox_viewSlice.setObjectName("spinBox_viewSlice")
        self.gridLayout.addWidget(self.spinBox_viewSlice, 0, 5, 1, 1)
        self.checkBox_viewX = QtWidgets.QCheckBox(self.gridLayoutWidget)
        self.checkBox_viewX.setChecked(True)
        self.checkBox_viewX.setObjectName("checkBox_viewX")
        self.gridLayout.addWidget(self.checkBox_viewX, 0, 0, 1, 1)
        self.checkBox_viewZ = QtWidgets.QCheckBox(self.gridLayoutWidget)
        self.checkBox_viewZ.setObjectName("checkBox_viewZ")
        self.gridLayout.addWidget(self.checkBox_viewZ, 0, 3, 1, 1)
        self.checkBox_viewY = QtWidgets.QCheckBox(self.gridLayoutWidget)
        self.checkBox_viewY.setObjectName("checkBox_viewY")
        self.gridLayout.addWidget(self.checkBox_viewY, 0, 2, 1, 1)
        self.horizontalSlider_viewSlice = QtWidgets.QSlider(self.gridLayoutWidget)
        self.horizontalSlider_viewSlice.setMinimum(1)
        self.horizontalSlider_viewSlice.setMaximum(128)
        self.horizontalSlider_viewSlice.setPageStep(1)
        self.horizontalSlider_viewSlice.setProperty("value", 64)
        self.horizontalSlider_viewSlice.setSliderPosition(64)
        self.horizontalSlider_viewSlice.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider_viewSlice.setObjectName("horizontalSlider_viewSlice")
        self.gridLayout.addWidget(self.horizontalSlider_viewSlice, 0, 4, 1, 1)
        self.gridLayoutWidget_2 = QtWidgets.QWidget(Dialog)
        self.gridLayoutWidget_2.setGeometry(QtCore.QRect(10, 50, 261, 179))
        self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2")
        self.gridLayout_kernelOptions = QtWidgets.QGridLayout(self.gridLayoutWidget_2)
        self.gridLayout_kernelOptions.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_kernelOptions.setObjectName("gridLayout_kernelOptions")
        self.spinBox_kernelSize = QtWidgets.QSpinBox(self.gridLayoutWidget_2)
        self.spinBox_kernelSize.setEnabled(True)
        self.spinBox_kernelSize.setMouseTracking(False)
        self.spinBox_kernelSize.setWrapping(False)
        self.spinBox_kernelSize.setFrame(True)
        self.spinBox_kernelSize.setReadOnly(False)
        self.spinBox_kernelSize.setKeyboardTracking(True)
        self.spinBox_kernelSize.setProperty("showGroupSeparator", False)
        self.spinBox_kernelSize.setMinimum(3)
        self.spinBox_kernelSize.setMaximum(13)
        self.spinBox_kernelSize.setSingleStep(2)
        self.spinBox_kernelSize.setStepType(QtWidgets.QAbstractSpinBox.DefaultStepType)
        self.spinBox_kernelSize.setProperty("value", 3)
        self.spinBox_kernelSize.setObjectName("spinBox_kernelSize")
        self.gridLayout_kernelOptions.addWidget(self.spinBox_kernelSize, 2, 1, 1, 1)
        self.label_inputLowpass = QtWidgets.QLabel(self.gridLayoutWidget_2)
        self.label_inputLowpass.setEnabled(True)
        self.label_inputLowpass.setObjectName("label_inputLowpass")
        self.gridLayout_kernelOptions.addWidget(self.label_inputLowpass, 0, 0, 1, 1)
        self.label_tileSize = QtWidgets.QLabel(self.gridLayoutWidget_2)
        self.label_tileSize.setEnabled(True)
        self.label_tileSize.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        self.label_tileSize.setObjectName("label_tileSize")
        self.gridLayout_kernelOptions.addWidget(self.label_tileSize, 5, 0, 1, 1)
        self.spinBox_tileSize = QtWidgets.QSpinBox(self.gridLayoutWidget_2)
        self.spinBox_tileSize.setEnabled(True)
        self.spinBox_tileSize.setMouseTracking(False)
        self.spinBox_tileSize.setWrapping(False)
        self.spinBox_tileSize.setFrame(True)
        self.spinBox_tileSize.setReadOnly(False)
        self.spinBox_tileSize.setKeyboardTracking(True)
        self.spinBox_tileSize.setProperty("showGroupSeparator", False)
        self.spinBox_tileSize.setMinimum(4)
        self.spinBox_tileSize.setMaximum(40)
        self.spinBox_tileSize.setSingleStep(2)
        self.spinBox_tileSize.setStepType(QtWidgets.QAbstractSpinBox.DefaultStepType)
        self.spinBox_tileSize.setProperty("value", 12)
        self.spinBox_tileSize.setObjectName("spinBox_tileSize")
        self.gridLayout_kernelOptions.addWidget(self.spinBox_tileSize, 5, 1, 1, 1)
        self.label_inputLowass_A = QtWidgets.QLabel(self.gridLayoutWidget_2)
        self.label_inputLowass_A.setEnabled(True)
        self.label_inputLowass_A.setObjectName("label_inputLowass_A")
        self.gridLayout_kernelOptions.addWidget(self.label_inputLowass_A, 0, 2, 1, 1)
        self.doubleSpinBox_kernelRadius = QtWidgets.QDoubleSpinBox(self.gridLayoutWidget_2)
        self.doubleSpinBox_kernelRadius.setEnabled(True)
        self.doubleSpinBox_kernelRadius.setMouseTracking(False)
        self.doubleSpinBox_kernelRadius.setWrapping(False)
        self.doubleSpinBox_kernelRadius.setFrame(True)
        self.doubleSpinBox_kernelRadius.setReadOnly(False)
        self.doubleSpinBox_kernelRadius.setKeyboardTracking(True)
        self.doubleSpinBox_kernelRadius.setProperty("showGroupSeparator", False)
        self.doubleSpinBox_kernelRadius.setObjectName("doubleSpinBox_kernelRadius")
        self.gridLayout_kernelOptions.addWidget(self.doubleSpinBox_kernelRadius, 1, 1, 1, 1)
        self.doubleSpinBox_Tau = QtWidgets.QDoubleSpinBox(self.gridLayoutWidget_2)
        self.doubleSpinBox_Tau.setEnabled(True)
        self.doubleSpinBox_Tau.setMouseTracking(False)
        self.doubleSpinBox_Tau.setWrapping(False)
        self.doubleSpinBox_Tau.setFrame(True)
        self.doubleSpinBox_Tau.setReadOnly(False)
        self.doubleSpinBox_Tau.setButtonSymbols(QtWidgets.QAbstractSpinBox.UpDownArrows)
        self.doubleSpinBox_Tau.setKeyboardTracking(True)
        self.doubleSpinBox_Tau.setProperty("showGroupSeparator", False)
        self.doubleSpinBox_Tau.setDecimals(2)
        self.doubleSpinBox_Tau.setMinimum(50.0)
        self.doubleSpinBox_Tau.setMaximum(99.9)
        self.doubleSpinBox_Tau.setSingleStep(0.1)
        self.doubleSpinBox_Tau.setProperty("value", 95.0)
        self.doubleSpinBox_Tau.setObjectName("doubleSpinBox_Tau")
        self.gridLayout_kernelOptions.addWidget(self.doubleSpinBox_Tau, 3, 1, 1, 1)
        self.label_kernelSize = QtWidgets.QLabel(self.gridLayoutWidget_2)
        self.label_kernelSize.setEnabled(True)
        self.label_kernelSize.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        self.label_kernelSize.setObjectName("label_kernelSize")
        self.gridLayout_kernelOptions.addWidget(self.label_kernelSize, 2, 0, 1, 1)
        self.label_samplesValue = QtWidgets.QLabel(self.gridLayoutWidget_2)
        self.label_samplesValue.setObjectName("label_samplesValue")
        self.gridLayout_kernelOptions.addWidget(self.label_samplesValue, 4, 1, 1, 1)
        self.label_Tau_percent = QtWidgets.QLabel(self.gridLayoutWidget_2)
        self.label_Tau_percent.setEnabled(True)
        self.label_Tau_percent.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        self.label_Tau_percent.setObjectName("label_Tau_percent")
        self.gridLayout_kernelOptions.addWidget(self.label_Tau_percent, 3, 2, 1, 1)
        self.label_kernelRadius_pix = QtWidgets.QLabel(self.gridLayoutWidget_2)
        self.label_kernelRadius_pix.setEnabled(True)
        self.label_kernelRadius_pix.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        self.label_kernelRadius_pix.setObjectName("label_kernelRadius_pix")
        self.gridLayout_kernelOptions.addWidget(self.label_kernelRadius_pix, 2, 2, 1, 1)
        self.doubleSpinBox_inputLowpass = QtWidgets.QDoubleSpinBox(self.gridLayoutWidget_2)
        self.doubleSpinBox_inputLowpass.setEnabled(True)
        self.doubleSpinBox_inputLowpass.setDecimals(1)
        self.doubleSpinBox_inputLowpass.setMaximum(50.0)
        self.doubleSpinBox_inputLowpass.setSingleStep(1.0)
        self.doubleSpinBox_inputLowpass.setProperty("value", 0.0)
        self.doubleSpinBox_inputLowpass.setObjectName("doubleSpinBox_inputLowpass")
        self.gridLayout_kernelOptions.addWidget(self.doubleSpinBox_inputLowpass, 0, 1, 1, 1)
        self.label_samples = QtWidgets.QLabel(self.gridLayoutWidget_2)
        self.label_samples.setEnabled(True)
        self.label_samples.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        self.label_samples.setObjectName("label_samples")
        self.gridLayout_kernelOptions.addWidget(self.label_samples, 4, 0, 1, 1)
        self.label_samples_voxels = QtWidgets.QLabel(self.gridLayoutWidget_2)
        self.label_samples_voxels.setEnabled(True)
        self.label_samples_voxels.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        self.label_samples_voxels.setObjectName("label_samples_voxels")
        self.gridLayout_kernelOptions.addWidget(self.label_samples_voxels, 4, 2, 1, 1)
        self.label_kernelRadius = QtWidgets.QLabel(self.gridLayoutWidget_2)
        self.label_kernelRadius.setEnabled(True)
        self.label_kernelRadius.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        self.label_kernelRadius.setObjectName("label_kernelRadius")
        self.gridLayout_kernelOptions.addWidget(self.label_kernelRadius, 1, 0, 1, 1)
        self.label_Tau = QtWidgets.QLabel(self.gridLayoutWidget_2)
        self.label_Tau.setEnabled(True)
        self.label_Tau.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        self.label_Tau.setObjectName("label_Tau")
        self.gridLayout_kernelOptions.addWidget(self.label_Tau, 3, 0, 1, 1)
        self.label_kernelSize_pix = QtWidgets.QLabel(self.gridLayoutWidget_2)
        self.label_kernelSize_pix.setEnabled(True)
        self.label_kernelSize_pix.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        self.label_kernelSize_pix.setObjectName("label_kernelSize_pix")
        self.gridLayout_kernelOptions.addWidget(self.label_kernelSize_pix, 1, 2, 1, 1)
        self.label_tileSize_pix = QtWidgets.QLabel(self.gridLayoutWidget_2)
        self.label_tileSize_pix.setEnabled(True)
        self.label_tileSize_pix.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        self.label_tileSize_pix.setObjectName("label_tileSize_pix")
        self.gridLayout_kernelOptions.addWidget(self.label_tileSize_pix, 5, 2, 1, 1)

        self.gridLayoutWidget_6 = QtWidgets.QWidget(Dialog)
        self.gridLayoutWidget_6.setGeometry(QtCore.QRect(10, 390, 261, 89))
        self.gridLayoutWidget_6.setObjectName("gridLayoutWidget_6")
        self.gridLayout_extraOptions = QtWidgets.QGridLayout(self.gridLayoutWidget_6)
        self.gridLayout_extraOptions.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_extraOptions.setObjectName("gridLayout_extraOptions")
        self.doubleSpinBox_outputLowpass = QtWidgets.QDoubleSpinBox(self.gridLayoutWidget_6)
        self.doubleSpinBox_outputLowpass.setEnabled(True)
        self.doubleSpinBox_outputLowpass.setDecimals(1)
        self.doubleSpinBox_outputLowpass.setMaximum(50.0)
        self.doubleSpinBox_outputLowpass.setSingleStep(1.0)
        self.doubleSpinBox_outputLowpass.setProperty("value", 8.0)
        self.doubleSpinBox_outputLowpass.setObjectName("doubleSpinBox_outputLowpass")
        self.gridLayout_extraOptions.addWidget(self.doubleSpinBox_outputLowpass, 1, 1, 1, 1)
        self.label_outputLowpass_A = QtWidgets.QLabel(self.gridLayoutWidget_6)
        self.label_outputLowpass_A.setEnabled(True)
        self.label_outputLowpass_A.setObjectName("label_outputLowpass_A")
        self.gridLayout_extraOptions.addWidget(self.label_outputLowpass_A, 1, 2, 1, 1)
        self.label_maxBox = QtWidgets.QLabel(self.gridLayoutWidget_6)
        self.label_maxBox.setEnabled(True)
        self.label_maxBox.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        self.label_maxBox.setObjectName("label_maxBox")
        self.gridLayout_extraOptions.addWidget(self.label_maxBox, 0, 2, 1, 1)
        self.checkBox_histMatch = QtWidgets.QCheckBox(self.gridLayoutWidget_6)
        self.checkBox_histMatch.setToolTip("")
        self.checkBox_histMatch.setWhatsThis("")
        self.checkBox_histMatch.setTristate(False)
        self.checkBox_histMatch.setObjectName("checkBox_histMatch")
        self.gridLayout_extraOptions.addWidget(self.checkBox_histMatch, 2, 2, 1, 1)
        self.checkBox_S0 = QtWidgets.QCheckBox(self.gridLayoutWidget_6)
        self.checkBox_S0.setObjectName("checkBox_S0")
        self.gridLayout_extraOptions.addWidget(self.checkBox_S0, 2, 1, 1, 1)
        self.checkBox_suppresSolvent = QtWidgets.QCheckBox(self.gridLayoutWidget_6)
        self.checkBox_suppresSolvent.setObjectName("checkBox_suppresSolvent")
        self.gridLayout_extraOptions.addWidget(self.checkBox_suppresSolvent, 2, 0, 1, 1)
        self.spinBox_maxBox = QtWidgets.QSpinBox(self.gridLayoutWidget_6)
        self.spinBox_maxBox.setEnabled(True)
        self.spinBox_maxBox.setMouseTracking(False)
        self.spinBox_maxBox.setWrapping(False)
        self.spinBox_maxBox.setFrame(True)
        self.spinBox_maxBox.setReadOnly(False)
        self.spinBox_maxBox.setKeyboardTracking(True)
        self.spinBox_maxBox.setProperty("showGroupSeparator", False)
        self.spinBox_maxBox.setMinimum(128)
        self.spinBox_maxBox.setMaximum(1024)
        self.spinBox_maxBox.setSingleStep(32)
        self.spinBox_maxBox.setStepType(QtWidgets.QAbstractSpinBox.DefaultStepType)
        self.spinBox_maxBox.setProperty("value", 256)
        self.spinBox_maxBox.setObjectName("spinBox_maxBox")
        self.gridLayout_extraOptions.addWidget(self.spinBox_maxBox, 0, 1, 1, 1)
        self.checkBox_maxBox = QtWidgets.QCheckBox(self.gridLayoutWidget_6)
        self.checkBox_maxBox.setChecked(True)
        self.checkBox_maxBox.setObjectName("checkBox_maxBox")
        self.gridLayout_extraOptions.addWidget(self.checkBox_maxBox, 0, 0, 1, 1)
        self.checkBox_outputLowpass = QtWidgets.QCheckBox(self.gridLayoutWidget_6)
        self.checkBox_outputLowpass.setObjectName("checkBox_outputLowpass")
        self.gridLayout_extraOptions.addWidget(self.checkBox_outputLowpass, 1, 0, 1, 1)
        self.horizontalLayoutWidget_4 = QtWidgets.QWidget(Dialog)
        self.horizontalLayoutWidget_4.setGeometry(QtCore.QRect(10, 480, 261, 25))
        self.horizontalLayoutWidget_4.setObjectName("horizontalLayoutWidget_4")
        self.horizontalLayout_scaleMode = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_4)
        self.horizontalLayout_scaleMode.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_scaleMode.setObjectName("horizontalLayout_scaleMode")
        self.checkBox_scaleOcc = QtWidgets.QCheckBox(self.horizontalLayoutWidget_4)
        self.checkBox_scaleOcc.setObjectName("checkBox_scaleOcc")
        self.horizontalLayout_scaleMode.addWidget(self.checkBox_scaleOcc)
        self.label_slash = QtWidgets.QLabel(self.horizontalLayoutWidget_4)
        self.label_slash.setEnabled(True)
        self.label_slash.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        self.label_slash.setObjectName("label_slash")
        self.horizontalLayout_scaleMode.addWidget(self.label_slash)
        self.checkBox_scaleRes = QtWidgets.QCheckBox(self.horizontalLayoutWidget_4)
        self.checkBox_scaleRes.setChecked(True)
        self.checkBox_scaleRes.setObjectName("checkBox_scaleRes")
        self.horizontalLayout_scaleMode.addWidget(self.checkBox_scaleRes)
        self.gridLayoutWidget_7 = QtWidgets.QWidget(Dialog)
        self.gridLayoutWidget_7.setGeometry(QtCore.QRect(110, 520, 561, 80))
        self.gridLayoutWidget_7.setObjectName("gridLayoutWidget_7")
        self.gridLayout_extraInputMaps = QtWidgets.QGridLayout(self.gridLayoutWidget_7)
        self.gridLayout_extraInputMaps.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_extraInputMaps.setObjectName("gridLayout_extraInputMaps")
        self.toolButton_inputScale_browse = QtWidgets.QToolButton(self.gridLayoutWidget_7)
        self.toolButton_inputScale_browse.setObjectName("toolButton_inputScale_browse")
        self.gridLayout_extraInputMaps.addWidget(self.toolButton_inputScale_browse, 0, 1, 1, 1)
        self.comboBox_inputScale = QtWidgets.QComboBox(self.gridLayoutWidget_7)
        self.comboBox_inputScale.setObjectName("comboBox_inputScale")
        self.gridLayout_extraInputMaps.addWidget(self.comboBox_inputScale, 0, 0, 1, 1)
        self.toolButton_inputSolventDef_reload = QtWidgets.QToolButton(self.gridLayoutWidget_7)
        self.toolButton_inputSolventDef_reload.setObjectName("toolButton_inputSolventDef_reload")
        self.gridLayout_extraInputMaps.addWidget(self.toolButton_inputSolventDef_reload, 1, 2, 1, 1)
        self.toolButton_inputScale_reload = QtWidgets.QToolButton(self.gridLayoutWidget_7)
        self.toolButton_inputScale_reload.setObjectName("toolButton_inputScale_reload")
        self.gridLayout_extraInputMaps.addWidget(self.toolButton_inputScale_reload, 0, 2, 1, 1)
        self.comboBox_inputSolventDef = QtWidgets.QComboBox(self.gridLayoutWidget_7)
        self.comboBox_inputSolventDef.setObjectName("comboBox_inputSoventDef")
        self.gridLayout_extraInputMaps.addWidget(self.comboBox_inputSolventDef, 1, 0, 1, 1)
        self.comboBox_inputSolventDef.addItem(" ")
        self.toolButton_inputSolventDef_browse = QtWidgets.QToolButton(self.gridLayoutWidget_7)
        self.toolButton_inputSolventDef_browse.setObjectName("toolButton_inputSolventDef_browse")
        self.gridLayout_extraInputMaps.addWidget(self.toolButton_inputSolventDef_browse, 1, 1, 1, 1)
        self.toolButton_run = QtWidgets.QPushButton(Dialog)
        self.toolButton_run.setEnabled(False)
        self.toolButton_run.setGeometry(QtCore.QRect(340, 610, 201, 54))
        font = QtGui.QFont()
        font.setPointSize(18)
        self.toolButton_run.setFont(font)
        self.toolButton_run.setIcon(icon_square)
        self.toolButton_run.setIconSize(QtCore.QSize(40, 40))
        self.toolButton_run.setObjectName("toolButton_run")
        self.verticalLayoutWidget = QtWidgets.QWidget(Dialog)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 530, 91, 61))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout_labelExtraInput = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout_labelExtraInput.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_labelExtraInput.setObjectName("verticalLayout_labelExtraInput")
        self.label_inputScale = QtWidgets.QLabel(self.verticalLayoutWidget)
        self.label_inputScale.setEnabled(True)
        self.label_inputScale.setAlignment(QtCore.Qt.AlignCenter)
        self.label_inputScale.setObjectName("label_inputScale")
        self.verticalLayout_labelExtraInput.addWidget(self.label_inputScale)
        self.label_inputSolventDef = QtWidgets.QLabel(self.verticalLayoutWidget)
        self.label_inputSolventDef.setEnabled(True)
        self.label_inputSolventDef.setAlignment(QtCore.Qt.AlignCenter)
        self.label_inputSolventDef.setObjectName("label_inputSolventDef")
        self.verticalLayout_labelExtraInput.addWidget(self.label_inputSolventDef)
        self.label_inputMap = QtWidgets.QLabel(Dialog)
        self.label_inputMap.setEnabled(True)
        self.label_inputMap.setGeometry(QtCore.QRect(0, 10, 89, 31))
        font = QtGui.QFont()
        font.setPointSize(11)
        self.label_inputMap.setFont(font)
        self.label_inputMap.setAlignment(QtCore.Qt.AlignCenter)
        self.label_inputMap.setObjectName("label_inputMap")
        self.tabWidget_output.raise_()
        self.toolButton_chimerax.raise_()
        self.tabWidget_modification.raise_()
        self.checkBox_verbose.raise_()
        self.checkBox_showCmd.raise_()
        self.tabWidget_view.raise_()
        self.gridLayoutWidget.raise_()
        self.gridLayoutWidget_2.raise_()
        self.horizontalLayoutWidget.raise_()
        self.gridLayoutWidget_6.raise_()
        self.horizontalLayoutWidget_4.raise_()
        self.gridLayoutWidget_7.raise_()
        self.toolButton_run.raise_()
        self.verticalLayoutWidget.raise_()
        self.label_inputMap.raise_()
        self.toolButton_expandSolModel.raise_()

        self.retranslateUi(Dialog)
        self.tabWidget_modification.setCurrentIndex(0)
        self.tabWidget_view.setCurrentIndex(0)
        self.tabWidget_output.setCurrentIndex(0)

        # TODO
        #self.buttonBox.accepted.connect(Dialog.accept)
        #self.buttonBox.rejected.connect(Dialog.reject)

        # Mutually explusive options
        self.checkBox_scaleRes.clicked.connect(self.checkBox_scaleOcc.toggle)
        self.checkBox_scaleOcc.clicked.connect(self.checkBox_scaleRes.toggle)

        # Match viewPort slider and spinBox
        self.horizontalSlider_viewSlice.valueChanged['int'].connect(self.spinBox_viewSlice.setValue)
        self.spinBox_viewSlice.valueChanged['int'].connect(self.horizontalSlider_viewSlice.setValue)

        # Update viewport image on slice change
        self.spinBox_viewSlice.valueChanged['int'].connect(self.render_all_slices)

        # Render slice if tab is clicked
        self.tabWidget_view.tabBarClicked.connect(self.force_render_all_slices)

        # Update spinboxes when slider is moved
        self.horizontalSlider_amplPower.valueChanged['int'].connect(self.update_mod_spin_boxes)
        self.horizontalSlider_attnPower.valueChanged['int'].connect(self.update_mod_spin_boxes)
        self.horizontalSlider_sigmoidPower.valueChanged['int'].connect(self.update_mod_spin_boxes)
        self.horizontalSlider_sigmoidPivot.valueChanged['int'].connect(self.update_mod_spin_boxes)

        # Render plot if spinBoxes are changed
        self.doubleSpinBox_amplPower.valueChanged.connect(self.render_output_slice_with_focus)
        self.doubleSpinBox_attnPower.valueChanged.connect(self.render_output_slice_with_focus)
        self.doubleSpinBox_sigmoidPower.valueChanged.connect(self.render_output_slice_with_focus)
        self.doubleSpinBox_sigmoidPivot.valueChanged.connect(self.render_output_slice_with_focus)




        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "OccuPy"))
        Dialog.setWhatsThis(_translate("Dialog", "pre-estimated local scale map "))

        # Input Map
        self.toolButton_inputMap_browse.setText(_translate("Dialog", "browse"))
        self.toolButton_inputMap_browse.clicked.connect(self.set_input_file)
        self.toolButton_inputMap_emdb.clicked.connect(self.fetch_emdb)
        self.toolButton_inputMap_emdb.setText(_translate("Dialog", "emdb"))

        # Input scale Map
        self.toolButton_inputScale_browse.setText(_translate("Dialog", "browse"))
        self.toolButton_inputScale_browse.clicked.connect(self.set_scale_file)
        self.toolButton_inputScale_reload.clicked.connect(self.read_scale_file)

        # Input solvent Def
        self.toolButton_inputSolventDef_browse.setText(_translate("Dialog", "browse"))
        self.toolButton_inputSolventDef_browse.clicked.connect(self.set_solvent_file)
        self.toolButton_inputSolventDef_reload.clicked.connect(self.read_solvent_file)

        # Update when changing the input choice
        self.comboBox_inputMap.currentIndexChanged.connect(self.read_input_file)
        self.comboBox_inputScale.currentIndexChanged.connect(self.change_scale_file)
        self.comboBox_inputSolventDef.currentIndexChanged.connect(self.read_solvent_file)


        self.label_amplPower.setText(_translate("Dialog", " Power"))
        self.tabWidget_modification.setTabText(self.tabWidget_modification.indexOf(self.tab_amplification), _translate("Dialog", "Amplify"))

        self.label_attnPower.setText(_translate("Dialog", " Power"))
        self.tabWidget_modification.setTabText(self.tabWidget_modification.indexOf(self.tab_attenuation), _translate("Dialog", "Attenuate"))
        self.label_sigmoidPower.setText(_translate("Dialog", " Power"))
        self.label_sigmoidPivot.setText(_translate("Dialog", " Pivot"))
        self.tabWidget_modification.setTabText(self.tabWidget_modification.indexOf(self.tab_sigmoid), _translate("Dialog", "Sigmoid"))

        self.tabWidget_modification.tabBarClicked.connect(self.toggle_scale_mode)
        self.groupBox_amplification.clicked.connect(self.toggle_scale_mode)
        self.groupBox_attenuation.clicked.connect(self.toggle_scale_mode)
        self.groupBox_sigmoid.clicked.connect(self.toggle_scale_mode)
        self.groupBox_amplification.clicked.connect(self.update_plot_params)
        self.groupBox_attenuation.clicked.connect(self.update_plot_params)
        self.groupBox_sigmoid.clicked.connect(self.update_plot_params)
        self.groupBox_amplification.clicked.connect(self.render_output_slice_with_focus)
        self.groupBox_attenuation.clicked.connect(self.render_output_slice_with_focus)
        self.groupBox_sigmoid.clicked.connect(self.render_output_slice_with_focus)




        self.checkBox_verbose.setText(_translate("Dialog", "Verbose"))
        self.checkBox_showCmd.setText(_translate("Dialog", "Only show command"))
        self.tabWidget_view.setTabText(self.tabWidget_view.indexOf(self.tab_viewInput), _translate("Dialog", "Input"))
        self.tabWidget_view.setTabText(self.tabWidget_view.indexOf(self.tab_viewScale), _translate("Dialog", "Scale"))
        self.tabWidget_view.setTabText(self.tabWidget_view.indexOf(self.tab_viewConfidence), _translate("Dialog", "Conf."))
        self.tabWidget_view.setTabText(self.tabWidget_view.indexOf(self.tab_solvDef), _translate("Dialog", "Sol.def."))
        self.tabWidget_view.setTabText(self.tabWidget_view.indexOf(self.tab_viewModification), _translate("Dialog", "Plot"))
        self.tabWidget_view.setTabText(self.tabWidget_view.indexOf(self.tab_viewOutput), _translate("Dialog", "Preview"))
        self.textEdit_log.setPlaceholderText(_translate("Dialog", "Output messages will go here...."))
        self.tabWidget_output.setTabText(self.tabWidget_output.indexOf(self.tab_log), _translate("Dialog", "Output Log"))
        #self.tabWidget_output.setTabText(self.tabWidget_output.indexOf(self.tab_hist), _translate("Dialog", "Histogram"))
        self.tabWidget_output.setTabText(self.tabWidget_output.indexOf(self.tab_solventModel), _translate("Dialog", "Solvent model"))
        self.toolButton_clearLog.setText(_translate("Dialog", "Clear log"))
        self.toolButton_clearLog.clicked.connect(self.clear_log)
        self.toolButton_chimerax.setText(_translate("Dialog", "launch chimeraX"))
        self.toolButton_chimerax.clicked.connect(self.run_chimerax)

        # Viewport X / Y / Z --------------------------------------
        self.checkBox_viewX.setText(_translate("Dialog", "x"))
        self.checkBox_viewX.clicked.connect(self.view_x)
        self.checkBox_viewY.setText(_translate("Dialog", "y"))
        self.checkBox_viewY.clicked.connect(self.view_y)
        self.checkBox_viewZ.setText(_translate("Dialog", "z"))
        self.checkBox_viewZ.clicked.connect(self.view_z)


        # Kernel options
        self.label_inputLowpass.setText(_translate("Dialog", "Input lowpass"))
        self.doubleSpinBox_inputLowpass.valueChanged.connect(self.set_kernel_radius)

        self.label_kernelRadius.setText(_translate("Dialog", "Kernel radius (pix)"))
        self.doubleSpinBox_kernelRadius.valueChanged.connect(self.set_kernel_size)

        self.label_kernelSize.setText(_translate("Dialog", "Kernel size (pix)"))
        self.spinBox_kernelSize.valueChanged.connect(self.set_kernel_tau)




        self.label_tileSize.setText(_translate("Dialog", "Tile size (pix)"))
        self.label_inputLowass_A.setText(_translate("Dialog", "Å"))


        # Kernel option labels
        self.label_samplesValue.setText(_translate("Dialog", "-"))
        self.label_Tau_percent.setText(_translate("Dialog", "%"))
        self.label_kernelRadius_pix.setText(_translate("Dialog", "pixels"))
        self.label_samples.setText(_translate("Dialog", "Samples"))
        self.label_samples_voxels.setText(_translate("Dialog", "voxels"))
        self.label_Tau.setText(_translate("Dialog", "Tau (percentile) "))
        self.label_kernelSize_pix.setText(_translate("Dialog", "pixels"))
        self.label_tileSize_pix.setText(_translate("Dialog", "pixels"))
        self.label_outputLowpass_A.setText(_translate("Dialog", "Å"))
        self.label_maxBox.setText(_translate("Dialog", "pix"))


        self.checkBox_histMatch.setText(_translate("Dialog", "HM"))
        self.checkBox_S0.setText(_translate("Dialog", "S0"))
        self.checkBox_suppresSolvent.setText(_translate("Dialog", "supress solvent"))
        self.checkBox_maxBox.setText(_translate("Dialog", "Limit box size"))
        self.checkBox_outputLowpass.setText(_translate("Dialog", "Output lowpass"))
        self.checkBox_scaleOcc.setText(_translate("Dialog", "occupancy"))
        self.label_slash.setText(_translate("Dialog", "      /"))
        self.checkBox_scaleRes.setText(_translate("Dialog", "resolution"))
        self.toolButton_inputScale_browse.setText(_translate("Dialog", "browse"))
        self.comboBox_inputScale.setToolTip(_translate("Dialog", "pre-estimated local scale map "))

        self.toolButton_inputSolventDef_reload.setText(_translate("Dialog", "(re)load"))
        self.toolButton_inputScale_reload.setText(_translate("Dialog", "(re)load"))
        self.comboBox_inputSolventDef.setToolTip(_translate("Dialog", "solvent mask to improve solvent detection"))
        self.comboBox_inputSolventDef.setWhatsThis(_translate("Dialog", "solvent mask to improve solvent detection"))
        self.toolButton_inputSolventDef_browse.setText(_translate("Dialog", "browse"))
        self.toolButton_run.setText(_translate("Dialog", "  RUN  "))#ɒk.jə.paɪ"))
        self.toolButton_run.clicked.connect(self.run_cmd)
        self.label_inputScale.setText(_translate("Dialog", "  scale map"))
        self.label_inputSolventDef.setText(_translate("Dialog", " solvent def"))
        self.label_inputMap.setText(_translate("Dialog", "  Input map"))

        self.toolButton_expandSolModel.clicked.connect(self.window_solvent_model)

    def fetch_emdb(self):

        self.Dialog_emdb = EMDB_dialog()
        self.Dialog_emdb.make_dialog()
        self.Dialog_emdb.exec()

        id = self.Dialog_emdb.id

        if id is None or id == 0:
            pass
        else:
            map_name = ''
            with Capturing() as output:
                self.occupy_log(f'Fetching emdb {id}...')
                map_name = map_tools.fetch_EMDB(id)

            for i in output:
                self.occupy_log(i)

            if map_name is not None:

                self.add_input_file(str(map_name))


    def set_input_file(self):

        # Open dialog to choose file
        file_name, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image", "",
                                                            "Image Files (*.mrc *.map);;All Files (*)")  # Ask for file

        if file_name:
            self.label_viewInput.setEnabled(True)
            idx = None
            new_file = True
            for i in range(self.comboBox_inputMap.count()):
                if self.comboBox_inputMap.itemText(i) == file_name:
                    idx = i
                    new_file = False

            if new_file:
                self.comboBox_inputMap.addItem(file_name)
                n = self.comboBox_inputMap.count()
                self.comboBox_inputMap.setCurrentIndex(n-1)

                self.read_input_file()

                self.toolButton_run.setEnabled(True)
                self.toolButton_run.clearFocus()

            else:
                self.comboBox_inputMap.setCurrentIndex(idx)

    def add_input_file(self,new_input_file):
        if new_input_file:
            new_file = True
            idx = None
            for i in range(self.comboBox_inputMap.count()):
                if self.comboBox_inputMap.itemText(i) == new_input_file:
                    idx = i
                    new_file = False
        if new_file:
            self.comboBox_inputMap.addItem(str(new_input_file))
            n = self.comboBox_inputMap.count()
            self.comboBox_inputMap.setCurrentIndex(n - 1)
        else:
            self.comboBox_inputMap.setCurrentIndex(idx)

        self.read_input_file()

    def read_input_file(self):
        #TODO check that file/map still exists

        # Get file name or object
        file_name = self.comboBox_inputMap.currentText()

        # Open memory mapped to set options etc.
        f = mf.mmap(file_name)

        # Slider and spinbox in view window
        n = f.header['nx']

        ny = f.header['ny']
        nz = f.header['nz']

        # Only permit cubic
        if n == ny == nz:

            self.horizontalSlider_viewSlice.setRange(1, n)
            self.horizontalSlider_viewSlice.setValue(n//2)

            self.spinBox_viewSlice.setMaximum(n)
            self.spinBox_viewSlice.setValue(n//2)

            # Fill view pane
            self.render_input_slice()

            # TODO compute kernel options
            self.set_lowpass()

        else:

            self.occupy_log('Input is not cubic.')


        self.label_viewInput.setEnabled(True)
        self.toolButton_run.setEnabled(True)

        # Close the file
        f.close()

    def render_input_slice(self,force=False):

        # Check if input view is active (currently viewed)
        # We don't want to read and render a slice that we're not viewing
        if self.tabWidget_view.currentIndex() == self.tabWidget_view.indexOf(self.tab_viewInput) or force:

            # Get file name or object
            file_name = self.comboBox_inputMap.currentText()

            # Get file slice number
            slice = self.horizontalSlider_viewSlice.value()

            # If there is something to render
            if file_name:
                # Open memory-mapped (much faster than open)
                f = mf.mmap(file_name)

                # Get the dimensions (assume cubic based in read-check)
                n = int(f.header['nx'])

                # Safe-guards
                if not slice or slice > n:
                    slice = n//2

                # Render the selected dimension
                if self.checkBox_viewX.isChecked():
                    t = f.data[slice-1,:,:]
                elif self.checkBox_viewY.isChecked():
                    t = f.data[:,slice-1,:]
                elif self.checkBox_viewZ.isChecked():
                    t = f.data[:, :, slice-1]

                # Grayscale normalization
                tmin = f.header['dmin']
                tmax = f.header['dmax']
                t = (t-tmin)/(tmax-tmin)

                # Construct and render image
                im_data = np.copy(np.array((t*255).astype(np.uint8)))
                # get the shape of the array
                height, width = np.shape(im_data)

                # calculate the total number of bytes in the frame
                totalBytes = im_data.nbytes

                # divide by the number of rows
                bytesPerLine = int(totalBytes / height)

                qimage = QtGui.QImage(im_data,n,n,bytesPerLine,QtGui.QImage.Format_Grayscale8)# Setup pixmap with the provided image
                pixmap = QtGui.QPixmap(qimage) # Setup pixmap with the provided image
                pixmap = pixmap.scaled(self.label_viewInput.width(), self.label_viewInput.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
                self.label_viewInput.setPixmap(pixmap) # Set the pixmap onto the label
                self.label_viewInput.setAlignment(QtCore.Qt.AlignCenter) # Align the label to center
                del im_data
                f.close()

    def set_scale_mode(self,scale_file_name):

        self.occ_scale = False
        self.res_scale = False

        #Label method
        f = mf.mmap(scale_file_name)
 
        not_found = True           
        nlabl = f.header['nlabl']
        for i in np.arange(nlabl):
            label = str(f.header['label'][i])
            if "occupy scale: occ" in label:
                self.occ_scale = True
                not_found = False
                break
            elif "occupy scale: res" in label:
                self.res_scale = True
                not_found = False
                break
        if not_found:
            # String method as fallback
            if "_occ_" in scale_file_name:
                self.occ_scale = True
                not_found = False
            elif "_res_" in scale_file_name:
                self.res_scale = True
                not_found = False

        if not_found:
            self.occupy_log('Could not find scale mode during scale file load')
            if nlabl == 10:
                print("There was nothing to confirm this is an occ scale, but all lables are full, so permitting.")
                self.occ_scale = True

    def change_input_file(self):
        self.in_file_name = str(self.comboBox_inputMap.currentText())
        self.render_input_slice()
        self.render_output_slice()

    def change_scale_file(self):
        self.scale_file_name = str(self.comboBox_inputScale.currentText())
        self.set_scale_mode(self.scale_file_name)
        self.render_scale_slice()
        self.render_output_slice()

    def set_scale_file(self):
        scale_file_name, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image", "",
                                                                  "Image Files (*.mrc *.map);;All Files (*)")  # Ask for file
        if scale_file_name:
            new_file = True
            idx = None
            for i in range(self.comboBox_inputScale.count()):
                if self.comboBox_inputScale.itemText(i) == scale_file_name:
                    idx = i
                    new_file = False
            if new_file:
                self.label_viewScale.setEnabled(True)
                self.scale_file_name = str(scale_file_name)
                self.set_scale_mode(self.scale_file_name)

                self.comboBox_inputScale.addItem(str(self.scale_file_name))
                n = self.comboBox_inputScale.count()
                self.comboBox_inputScale.setCurrentIndex(n-1)
            else:
                self.comboBox_inputScale.setCurrentIndex(idx)

            self.read_scale_file()

    def add_scale_file(self,new_scale_file):
        self.scale_file_name = str(new_scale_file)
        self.set_scale_mode(self.scale_file_name)

        if new_scale_file:
            new_file = True
            idx = None
            for i in range(self.comboBox_inputScale.count()):
                if self.comboBox_inputScale.itemText(i) == new_scale_file:
                    idx = i
                    new_file = False
        if new_file:
            self.comboBox_inputScale.addItem(str(self.scale_file_name))
            n = self.comboBox_inputScale.count()
            self.comboBox_inputScale.setCurrentIndex(n - 1)
        else:
            self.comboBox_inputScale.setCurrentIndex(idx)

        self.read_scale_file()


    def read_scale_file(self):
        #TODO check that file/map still exists

        # Get file name or object
        scale_file_name = self.comboBox_inputScale.currentText()

        # Open memory mapped to set options etc.
        f = mf.mmap(scale_file_name)

        # Slider and spinbox in view window
        n = f.header['nx']

        ny = f.header['ny']
        nz = f.header['nz']

        # Only permit cubic
        if n == ny == nz:

            # Fill view pane
            self.render_scale_slice()

        else:

            self.occupy_log('Scale input is not cubic.')

        # Close the file
        f.close()


    def render_scale_slice(self,force=False):

        # Check if input view is active (currently viewed)
        # We don't want to read and render a slice that we're not viewing
        if self.tabWidget_view.currentIndex() == self.tabWidget_view.indexOf(self.tab_viewScale) or force:

            # Get file name or object
            scale_file_name = self.comboBox_inputScale.currentText()

            # Get file slice number
            slice = self.horizontalSlider_viewSlice.value()


            # If there is something to render
            if scale_file_name:
                self.label_viewScale.setEnabled(True)

                # Open memory-scale_file_name (much faster than open)
                f = mf.mmap(scale_file_name)
                # Get the dimensions (assume cubic based in read-check)
                n = f.header['nx']

                # Let the input map decide the slice number if the scale is on another grid
                input_file_name = self.comboBox_inputMap.currentText()
                if input_file_name:
                    # Open memory-scale_file_name (much faster than open)
                    f_input = mf.mmap(input_file_name)
                    # Get the dimensions (assume cubic based in read-check)
                    n_input = f_input.header['nx']

                    if n != n_input:
                        # The equivalent slice in the possibly
                        slice = int((slice / float(n_input)) * n)

                    f_input.close()
                else:
                    self.horizontalSlider_viewSlice.setRange(1, n)
                    self.horizontalSlider_viewSlice.setValue(n // 2)

                    self.spinBox_viewSlice.setMaximum(n)
                    self.spinBox_viewSlice.setValue(n // 2)


                # Safe-guards
                if not slice or slice > n:
                    slice = n//2

                # Render the selected dimension
                if self.checkBox_viewX.isChecked():
                    t = f.data[slice-1,:,:]
                elif self.checkBox_viewY.isChecked():
                    t = f.data[:,slice-1,:]
                elif self.checkBox_viewZ.isChecked():
                    t = f.data[:, :, slice-1]

                # Grayscale normalization
                #tmin = f.header['dmin']
                #tmax = f.header['dmax']
                #t = (t-tmin)/(tmax-tmin)

                # Construct and render image
                im_data = np.array((t*255).astype(np.uint8))
                qimage = QtGui.QImage(im_data,n,n,QtGui.QImage.Format_Grayscale8)# Setup pixmap with the provided image
                pixmap = QtGui.QPixmap(qimage) # Setup pixmap with the provided image
                pixmap = pixmap.scaled(self.label_viewScale.width(), self.label_viewScale.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
                self.label_viewScale.setPixmap(pixmap) # Set the pixmap onto the label
                self.label_viewScale.setAlignment(QtCore.Qt.AlignCenter) # Align the label to center

                f.close()

    def set_solvent_file(self):
        solvent_file_name, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image", "",
                                                                   "Image Files (*.mrc *.map);;All Files (*)")  # Ask for file
        if solvent_file_name:
            self.label_viewSolDef.setEnabled(True)
            # TODO loop and set if new, otherwise change active
            self.comboBox_inputSolventDef.addItem(str(solvent_file_name))
            n = self.comboBox_inputSolventDef.count()
            self.comboBox_inputSolventDef.setCurrentIndex(n-1)
            self.read_solvent_file()

    def read_solvent_file(self):
        # TODO check that file/map still exists

        # Get file name or object
        solvent_file_name = self.comboBox_inputSolventDef.currentText()

        if solvent_file_name != " ":

            # Open memory mapped to set options etc.
            f = mf.mmap(solvent_file_name)

            # Slider and spinbox in view window
            n = f.header['nx']

            ny = f.header['ny']
            nz = f.header['nz']

            # Only permit cubic
            if n == ny == nz:

                # Fill view pane
                self.render_solvent_slice()

            else:

                self.occupy_log('Solvent definition input is not cubic.')

            # Close the file
            f.close()

    def render_solvent_slice(self,force=False):

        # Check if input view is active (currently viewed)
        # We don't want to read and render a slice that we're not viewing
        if self.tabWidget_view.currentIndex() == self.tabWidget_view.indexOf(self.tab_solvDef) or force:

            # Get file name or object
            solvent_file_name = self.comboBox_inputSolventDef.currentText()

            # Get file slice number
            slice = self.horizontalSlider_viewSlice.value()

            # If there is something to render
            if solvent_file_name != " ":

                # Open memory-solvent_file_name (much faster than open)
                f = mf.mmap(solvent_file_name)
                # Get the dimensions (assume cubic based in read-check)
                n = f.header['nx']

                # Let the input map decide the slice number if the solvent is on another grid
                input_file_name = self.comboBox_inputMap.currentText()
                if input_file_name:
                    # Open memory-mapped (much faster than open)
                    f_input = mf.mmap(input_file_name)
                    # Get the dimensions (assume cubic based in read-check)
                    n_input = f_input.header['nx']

                    if n != n_input:
                        # The equivalent slice in the possibly
                        slice = int((slice / float(n_input)) * n)

                    f_input.close()
                else:
                    self.horizontalSlider_viewSlice.setRange(1, n)
                    self.horizontalSlider_viewSlice.setValue(n // 2)

                    self.spinBox_viewSlice.setMaximum(n)
                    self.spinBox_viewSlice.setValue(n // 2)

                # Safe-guards
                if not slice or slice > n:
                    slice = n // 2

                # Render the selected dimension
                if self.checkBox_viewX.isChecked():
                    t = f.data[slice - 1, :, :]
                elif self.checkBox_viewY.isChecked():
                    t = f.data[:, slice - 1, :]
                elif self.checkBox_viewZ.isChecked():
                    t = f.data[:, :, slice - 1]

                # Grayscale normalization
                # tmin = f.header['dmin']
                # tmax = f.header['dmax']
                # t = (t-tmin)/(tmax-tmin)

                # Construct and render image
                im_data = np.array((t * 255).astype(np.uint8))
                qimage = QtGui.QImage(im_data, n, n,
                                      QtGui.QImage.Format_Grayscale8)  # Setup pixmap with the provided image
                pixmap = QtGui.QPixmap(qimage)  # Setup pixmap with the provided image
                pixmap = pixmap.scaled(self.label_viewSolDef.width(), self.label_viewSolDef.height(),
                                       QtCore.Qt.KeepAspectRatio)  # Scale pixmap
                self.label_viewSolDef.setPixmap(pixmap)  # Set the pixmap onto the label
                self.label_viewSolDef.setAlignment(QtCore.Qt.AlignCenter)  # Align the label to center

                f.close()

    def render_confidence_slice(self,force=False):

        # Check if input view is active (currently viewed)
        # We don't want to read and render a slice that we're not viewing
        if self.tabWidget_view.currentIndex() == self.tabWidget_view.indexOf(self.tab_viewConfidence) or force:
            if self.confidence_file_name:
                self.label_viewConfidence.setEnabled(True)

                # Get file name or object
                confidence_file_name = self.confidence_file_name

                # Get file slice number
                slice = self.horizontalSlider_viewSlice.value()

                # If there is something to render
                if confidence_file_name is not None:

                    # Open memory-solvent_file_name (much faster than open)
                    f = mf.mmap(confidence_file_name)
                    # Get the dimensions (assume cubic based in read-check)
                    n = f.header['nx']

                    # Let the input map decide the slice number if the confidence is on another grid
                    input_file_name = self.comboBox_inputMap.currentText()
                    if input_file_name:
                        # Open memory-mapped (much faster than open)
                        f_input = mf.mmap(input_file_name)
                        # Get the dimensions (assume cubic based in read-check)
                        n_input = f_input.header['nx']

                        if n != n_input:
                            # The equivalent slice in the possibly
                            slice = int((slice / float(n_input)) * n)

                        f_input.close()
                    else:
                        self.horizontalSlider_viewSlice.setRange(1, n)
                        self.horizontalSlider_viewSlice.setValue(n // 2)

                        self.spinBox_viewSlice.setMaximum(n)
                        self.spinBox_viewSlice.setValue(n // 2)

                    # Safe-guards
                    if not slice or slice > n:
                        slice = n // 2

                    # Render the selected dimension
                    if self.checkBox_viewX.isChecked():
                        t = f.data[slice - 1, :, :]
                    elif self.checkBox_viewY.isChecked():
                        t = f.data[:, slice - 1, :]
                    elif self.checkBox_viewZ.isChecked():
                        t = f.data[:, :, slice - 1]

                    # Grayscale normalization
                    # tmin = f.header['dmin']
                    # tmax = f.header['dmax']
                    # t = (t-tmin)/(tmax-tmin)

                    # Construct and render image
                    im_data = np.array((t * 255).astype(np.uint8))
                    qimage = QtGui.QImage(im_data, n, n,
                                          QtGui.QImage.Format_Grayscale8)  # Setup pixmap with the provided image
                    pixmap = QtGui.QPixmap(qimage)  # Setup pixmap with the provided image
                    pixmap = pixmap.scaled(self.label_viewConfidence.width(), self.label_viewConfidence.height(),
                                           QtCore.Qt.KeepAspectRatio)  # Scale pixmap
                    self.label_viewConfidence.setPixmap(pixmap)  # Set the pixmap onto the label
                    self.label_viewConfidence.setAlignment(QtCore.Qt.AlignCenter)  # Align the label to center

                    f.close()
            else:
                self.label_viewConfidence.setEnabled(False)


    def render_all_slices(self):
        self.render_input_slice()
        self.render_scale_slice()
        self.render_solvent_slice()
        self.render_output_slice()
        if self.confidence_file_name is not None:
            self.render_confidence_slice()

    def force_render_all_slices(self):
        self.render_input_slice(force=True)
        self.render_scale_slice(force=True)
        self.render_solvent_slice(force=True)
        self.render_output_slice(force=True)
        if self.confidence_file_name is not None:
            self.render_confidence_slice(force=True)

    def set_lowpass(self):
        # Get file name or object
        file_name = self.comboBox_inputMap.currentText()

        # If there is something to work with
        if file_name:

            # Open memory-mapped (much faster than open)
            f = mf.mmap(file_name)

            # Get the dimensions (assume cubic based in read-check)
            n = f.header['nx']

            # Get voxel size
            self.inputMap.voxel_size_ori = self.inputMap.voxel_size_proc = f.voxel_size.x
            max_box = self.spinBox_maxBox.value()

            downscale_processing = n > max_box
            if downscale_processing:
                n_proc = np.min([n,max_box])
                self.inputMap.voxel_size_ori = self.inputMap.voxel_size_proc * n/np.float(n_proc)

            lower_limit_default = 3 * self.inputMap.voxel_size_proc
            self.inputMap.lowpass = np.max([lower_limit_default,8.0])

            # Set gui
            self.doubleSpinBox_inputLowpass.setValue(self.inputMap.lowpass)

            # Propagate to other settings
            self.set_kernel_size()

    def set_kernel_radius(self):
        self.inputMap.lowpass = self.doubleSpinBox_inputLowpass.value()
        old_kernel_radius = self.inputMap.kernel_radius

        # Make a kernel (morphological structuring element) for max-filter (greyscale dilation).
        self.inputMap.kernel_radius = self.doubleSpinBox_inputLowpass.value() / (2 * self.inputMap.voxel_size_proc)

        if not self.inputMap.kernel_radius == old_kernel_radius:
            # Update gui with new value
            self.doubleSpinBox_kernelRadius.setValue(self.inputMap.kernel_radius)
        else:
            # Propagate to other settings since it won't be triggered by the connect
            self.set_kernel_size()

        # Propagate to other settings
        # self.set_kernel_tau()

    def set_kernel_size(self):
        self.inputMap.kernel_radius = self.doubleSpinBox_kernelRadius.value()
        old_kernel_size = self.inputMap.kernel_size

        # How many pixels do we fit into the significant highest frequency?
        kernel_size = int(np.floor(self.doubleSpinBox_inputLowpass.value() / self.inputMap.voxel_size_proc))
        # Make it an odd size
        kernel_size = ((kernel_size // 2) * 2) + 1
        # It should be larger than 1, and never needs to be bigger than 9.
        kernel_size = np.clip(kernel_size, 3, 9)

        # It makes no sense to make a kernel size larger than that which fits the entire sphere
        upper_limit = np.ceil(self.inputMap.kernel_radius*np.sqrt(3))
        upper_limit = ((upper_limit // 2) * 2) + 1

        self.inputMap.kernel_size = np.min([kernel_size, upper_limit])

        if not self.inputMap.kernel_size == old_kernel_size:
            # Update gui with new value
            self.spinBox_kernelSize.setValue(int(self.inputMap.kernel_size))
        else:
            # Propagate to other settings since it won't be triggered by the connect
            self.set_kernel_tau()



    def set_kernel_tau(self):

        scale_kernel, tau_ana = occupancy.spherical_kernel(
            self.spinBox_kernelSize.value(),
            radius=self.doubleSpinBox_kernelRadius.value()
        )
        self.inputMap.kernel_nv = int(np.sum(scale_kernel))
        self.inputMap.kernel_tau = tau_ana #occupancy.set_tau(n_v=self.inputMap.kernel_nv)

        # Set gui
        self.label_samplesValue.setText(str(self.inputMap.kernel_nv))
        self.doubleSpinBox_Tau.setValue(self.inputMap.kernel_tau*100)


    def view_x(self):
        self.checkBox_viewX.setChecked(True)
        self.checkBox_viewY.setChecked(False)
        self.checkBox_viewZ.setChecked(False)
        self.render_all_slices()

    def view_y(self):
        self.checkBox_viewX.setChecked(False)
        self.checkBox_viewY.setChecked(True)
        self.checkBox_viewZ.setChecked(False)
        self.render_all_slices()

    def view_z(self):
        self.checkBox_viewX.setChecked(False)
        self.checkBox_viewY.setChecked(False)
        self.checkBox_viewZ.setChecked(True)
        self.render_all_slices()

    def do_modify(self):
        mod_tab = self.tabWidget_modification.currentIndex()
        if mod_tab == self.tabWidget_modification.indexOf(self.tab_amplification):
            if self.groupBox_amplification.isChecked():
                return(1)
        elif mod_tab == self.tabWidget_modification.indexOf(self.tab_attenuation):
            if self.groupBox_attenuation.isChecked():
                return(2)
        elif mod_tab == self.tabWidget_modification.indexOf(self.tab_sigmoid):
            if self.groupBox_sigmoid.isChecked():
                return(3)
        else:
            return(None)

    def render_output_slice_with_focus(self):
        # Get the mode of modification
        mode = self.do_modify()

        if mode is not None:
            # If either the input or scale map is missing...
            have_input = self.comboBox_inputScale.currentText()
            have_scale = self.comboBox_inputMap.currentText() and self.occ_scale
            have_both = have_input and have_scale

            if not have_both:
                # ...then focus on the plot tab
                self.tabWidget_view.setCurrentIndex(self.tabWidget_view.indexOf(self.tab_viewModification))

            # otherwise check if we are on the mod tab, in which case keep it
            elif self.tabWidget_view.currentIndex() != self.tabWidget_view.indexOf(self.tab_viewModification):
                # ...and which if we are on anything else
                self.tabWidget_view.setCurrentIndex(self.tabWidget_view.indexOf(self.tab_viewOutput))

        self.render_output_slice()

    def render_output_slice(self,force=False):

        self.update_plot_params()

        do_render=False
        output_tab = self.tabWidget_view.currentIndex() == self.tabWidget_view.indexOf(self.tab_viewOutput)
        if output_tab and self.occ_scale:
            do_render = True
        if self.res_scale:
            self.label_viewOutput.clear()
            self.label_viewOutput.setText("The chose scale is not an 'occupancy' \n"
                                          "scale, but a resolution scale. This \n"
                                          "is not appropriate for modification.")
            force = False


        if do_render or force:

            input_fileName = self.comboBox_inputMap.currentText()
            scale_fileName = self.comboBox_inputScale.currentText()

            if input_fileName and scale_fileName:
                self.label_viewOutput.setEnabled(True)
                input_f = mf.mmap(input_fileName)
                input_n = input_f.header['nx']

                scale_f = mf.mmap(scale_fileName)
                scale_n = scale_f.header['nx']

                input_slice = self.horizontalSlider_viewSlice.value()
                scale_slice = int((input_slice / float(input_n)) * scale_n)

                tmin = input_f.header['dmin']
                tmax = input_f.header['dmax']

                if self.checkBox_viewX.isChecked():
                    input_t = input_f.data[input_slice-1,:,:]
                    scale_t = scale_f.data[scale_slice-1,:,:]
                elif self.checkBox_viewY.isChecked():
                    input_t = input_f.data[:,input_slice-1,:]
                    scale_t = scale_f.data[:,scale_slice-1,:]
                elif self.checkBox_viewZ.isChecked():
                    input_t = input_f.data[:, :,input_slice-1]
                    scale_t = scale_f.data[:, :,scale_slice-1]

                #print(input_t.shape, scale_t.shape)
                if not input_t.shape == scale_t.shape:
                    input_t = scipy.ndimage.zoom(input_t,float(scale_n)/float(input_n),order=1)
                N = 100
                mode = self.do_modify()

                x = np.linspace(0,1,N)
                s = []
                if mode == 1: #Amplify
                    s = x ** (1/self.MplWidget_viewModification.amplification_power)
                elif mode == 2: #Attenuate
                    s = x ** (self.MplWidget_viewModification.attenuation_power)
                elif mode == 3: #Sigmoid
                    x,s = occupancy.scale_mapping_sigmoid(self.MplWidget_viewModification.sigmoid_pivot,self.MplWidget_viewModification.sigmoid_power,n=N)

                operations=['amplifying', 'attenuating', 'sigmoiding']
                if mode is not None:
                    #print(f'{operations[mode-1]}')
                    #s = np.divide(s,x,where=x!=0)
                    mapped = s[(scale_t*N).astype(int)-1]
                    mod_slice = np.copy(input_t)
                    d_scale_t = (scale_t<0.01).astype(float)
                    d_scale_t += scale_t
                    mod_slice = np.divide(mapped,np.clip(d_scale_t,0,1))

                    #mod_slice = np.divide(mod_slice,scale_t,where=scale_t>=0.05)
                    output_t = np.multiply(input_t,mod_slice)
                    threshold = np.min([0.05,self.MplWidget_viewModification.sigmoid_pivot])

                    output_t =  np.multiply(output_t,scale_t>threshold)
                    output_t += np.multiply(input_t,scale_t<threshold)
                    output_t =  np.clip(output_t,tmin,tmax)
                    output_t =  (output_t-tmin)/(tmax-tmin)

                    im_data = np.array((output_t*255).astype(np.uint8))
                    qimage = QtGui.QImage(im_data,scale_n,scale_n,QtGui.QImage.Format_Grayscale8)
                    pixmap = QtGui.QPixmap(qimage) # Setup pixmap with the provided image
                    pixmap = pixmap.scaled(self.label_viewOutput.width(), self.label_viewOutput.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
                    self.label_viewOutput.setPixmap(pixmap) # Set the pixmap onto the label
                    self.label_viewOutput.setAlignment(QtCore.Qt.AlignCenter) # Align the label to center
                    #self.ho'rizontalSlider_4.setRange(1,n)
                else:
                    self.label_viewOutput.setText("You have not set to modify anything. \n\n"
                                                  "Enable \"Amplify\", \"Attenuate\", or \n"
                                                  "\"Sigmoid\" on the left and set \n "
                                                  "the power >1.")
        else:
            self.label_viewOutput.setEnabled(False)

    def update_plot_params(self):
        self.MplWidget_viewModification.sigmoid_power = self.doubleSpinBox_sigmoidPower.value()
        self.MplWidget_viewModification.sigmoid_pivot = self.doubleSpinBox_sigmoidPivot.value() / 100.0
        self.MplWidget_viewModification.attenuation_power = self.doubleSpinBox_attnPower.value()
        self.MplWidget_viewModification.amplification_power = self.doubleSpinBox_amplPower.value()
        self.MplWidget_viewModification.amplify = self.groupBox_amplification.isChecked()
        self.MplWidget_viewModification.attenuate = self.groupBox_attenuation.isChecked()
        self.MplWidget_viewModification.sigmoid = self.groupBox_sigmoid.isChecked()

        self.MplWidget_viewModification.plot_modification()

    def update_mod_spin_boxes(self):
        self.doubleSpinBox_amplPower.setValue(self.horizontalSlider_amplPower.value()/10.)
        self.doubleSpinBox_attnPower.setValue(self.horizontalSlider_attnPower.value()/10.)
        self.doubleSpinBox_sigmoidPower.setValue(self.horizontalSlider_sigmoidPower.value()/10.)
        self.doubleSpinBox_sigmoidPivot.setValue(self.horizontalSlider_sigmoidPivot.value())

    def toggle_scale_mode(self):
        modifying = False
        if self.groupBox_amplification.isChecked():
            modifying = True
        if self.groupBox_attenuation.isChecked():
            modifying = True
        if self.groupBox_sigmoid.isChecked():
            modifying = True

        if modifying:
            self.checkBox_scaleOcc.setChecked(True)
            self.checkBox_scaleRes.setChecked(False)
            self.checkBox_scaleOcc.setEnabled(False)
            self.checkBox_scaleRes.setEnabled(False)
        else:
            self.checkBox_scaleOcc.setChecked(False)
            self.checkBox_scaleRes.setChecked(True)
            self.checkBox_scaleOcc.setEnabled(True)
            self.checkBox_scaleRes.setEnabled(True)


    def occupy_log(self, message):
        self.textEdit_log.append(message)
        
    def occupy_warn(self, message):
        warning = f'\033[91m {message} \033[0m'
        self.textEdit_log.append(warning)
        
    def clear_log(self):
        self.textEdit_log.clear()

    def run_chimerax(self):
        if self.chimerax_file_name is not None:
            import os
            os.system(f'chimerax {self.chimerax_file_name} & ')
        else:
            self.occupy_log("No chimerax file defined this session.")

    def compose_cmd(self):

        options = args.occupy_options()
        self.cmd.clear()
        self.cmd.append('occupy')

        # input files ----------------------------------------------------------------------------
        options.input_map = self.comboBox_inputMap.currentText()
        self.cmd.append(f'--input-map {options.input_map}')

        if self.comboBox_inputSolventDef.currentText() != " ":
            options.solvent_def = self.comboBox_inputSolventDef.currentText()
            self.cmd.append(f'--solvent-def {options.solvent_def}')

        # input options-------------------------------------------------------------------------
        options.lowpass_input = self.doubleSpinBox_inputLowpass.value()
        self.cmd.append(f'--lowpass {options.lowpass_input}')
        options.kernel_size = self.spinBox_kernelSize.value()
        self.cmd.append(f'--kernel-size {options.kernel_size}')
        options.kernel_radius = self.doubleSpinBox_kernelRadius.value()
        self.cmd.append(f'--kernel-radius {options.kernel_radius}')
        options.tau = self.doubleSpinBox_Tau.value()/100.0
        self.cmd.append(f'--tau  {options.tau}')
        options.tile_size = self.spinBox_tileSize.value()
        self.cmd.append(f'--tile-size {options.tile_size}')


        # max-box -----------------------------------------------------------------------------
        if self.checkBox_maxBox.isChecked():
            options.max_box = self.spinBox_maxBox.value()
            self.cmd.append(f'--max-box {options.max_box}')
        else:
            options.max_box = self.spinBox_maxBox.value()
            self.cmd.append(f'--max-box -1')


        # modification options ---------------------------------------------------------------
        modifying = False
        if self.groupBox_amplification.isChecked():
            modifying = True
            options.amplify = self.doubleSpinBox_amplPower.value()
            self.cmd.append(f'--amplify {options.amplify}')

        if self.groupBox_attenuation.isChecked():
            modifying = True
            options.attenuate = self.doubleSpinBox_attnPower.value()
            self.cmd.append(f'--attenuate {options.attenuate}')

        if self.groupBox_sigmoid.isChecked():
            modifying = True
            options.sigmoid = self.doubleSpinBox_sigmoidPower.value()
            options.pivot = self.doubleSpinBox_sigmoidPivot.value()/100.0
            self.cmd.append(f'--sigmoid {options.sigmoid } --pivot {options.pivot}/100.0')


        # output options -------------------------------------------------------------------
        if self.checkBox_outputLowpass.isChecked():
            options.lowpass_output = self.doubleSpinBox_outputLowpass.value()
            self.cmd.append(f'--output-lowpass {options.lowpass_output}')

        if self.checkBox_suppresSolvent.isChecked():
            options.exclude_solvent = True
            self.cmd.append(f'--suppress-solvent')

        if self.checkBox_S0.isChecked():
            options.s0 = True
            self.cmd.append(f'-S0')

        if self.checkBox_histMatch.isChecked():
            options.hist_match = True
            self.cmd.append(f'--hist-match')

        if self.checkBox_scaleOcc.isChecked():
            options.scale_mode = 'occ'
            if not modifying:
                # By default we include resolution-dependent effects when not modifying,
                # so we need to tell occupy to omit them
                options.lp_scale = True
                self.cmd.append(f'--occupancy')
        else:
            options.scale_mode = 'res'
            if modifying:
                options.lp_scale = False
                self.occupy_warn('Modifying with resolution-effect is not recommended. I suggest ticking "occupancy" instead.')

        if self.checkBox_verbose.isChecked():
            options.verbose = True
            self.cmd.append(f'--verbose')

        # Always plot in GUI
        options.plot = True
        self.cmd.append(f'--plot')

        options.gui = True

        return options

    def run_cmd(self):
        options = self.compose_cmd()

        if self.checkBox_showCmd.isChecked():
            #TODO check for in-memory objects like chimeraX-maps and figure out what to do
            self.occupy_log(" ".join(self.cmd))
        else:

            with Capturing() as output:
                self.occupy_log('Estimating local scale...')
                estimate.occupy_run(options)

            for i in output:
                self.occupy_log(i)

            from pathlib import Path
            new_name = Path(options.input_map).name
            # Force .mrc for output
            new_name = f'{Path(new_name).stem}.mrc'
            self.confidence_file_name = f'conf_{Path(new_name).stem}.mrc'

            scale_mode = 'res'
            if self.checkBox_scaleOcc.isChecked():
                scale_mode = 'occ'

            self.add_scale_file(f'scale_{scale_mode}_{Path(new_name).stem}.mrc')

            self.chimerax_file_name = f'chimX_{Path(new_name).stem}.cxc'
            self.toolButton_chimerax.setEnabled(True)

            self.show_solvent_model()

    def show_solvent_model(self):
        from pathlib import Path
        solDef_specifier = ''
        c =  self.comboBox_inputSolventDef.currentText()
        if self.comboBox_inputSolventDef.currentText() != ' ':
            solDef_specifier = f'{Path(self.comboBox_inputSolventDef.currentText()).stem}_'
        solModel_file_name = f'solModel_{solDef_specifier}' + Path(self.comboBox_inputMap.currentText()).stem + '.png'

        self.solModel_file_name = solModel_file_name
        pixmap = QtGui.QPixmap(self.solModel_file_name)  # Setup pixmap with the provided image
        pixmap = pixmap.scaled(self.label_solventModel.width(), self.label_solventModel.height(),
                               QtCore.Qt.KeepAspectRatio)  # Scale pixmap
        self.label_solventModel.setPixmap(pixmap)  # Set the pixmap onto the label
        self.label_solventModel.setAlignment(QtCore.Qt.AlignCenter)  # Align the label to center

        # Dont enable for now, for some reason the full view only woks in debug mode
        #self.toolButton_expandSolModel.setEnabled(True)

    def window_solvent_model(self):

        self.Dialog_solModel = ImageWindow()
        app = QtWidgets.QApplication(sys.argv)

        screen = app.primaryScreen()
        #print('Screen: %s' % screen.name())
        size = screen.size()
        #print('Size: %d x %d' % (size.width(), size.height()))
        rect = screen.availableGeometry()
        #print('Available: %d x %d' % (rect.width(), rect.height()))

        # The image will be 1200:252 pixels.
        # Assume width-limited and make as big as possible.
        rect_width = rect.width()
        rect_height = int(rect_width * 252 / 1200)
        window = QtWidgets.QLabel(self.Dialog_solModel)
        pixmap = QtGui.QPixmap(self.solModel_file_name)
        pixmap = pixmap.scaled(
            rect_width,
            rect_height,
            QtCore.Qt.KeepAspectRatio
        )  # Scale pixmap
        self.Dialog_solModel.resize(rect_width,rect_height)
        window.setPixmap(pixmap)
        self.Dialog_solModel.show()

        # from pathlib import Path
        # Dialog_solModel = QtWidgets.QDialog()
        # Dialog_solModel.resize(self.label_solventModel.width()*3, self.label_solventModel.height()*3)
        # window = QtWidgets.QLabel(Dialog_solModel)
        # solDef_specifier = ''
        # c = self.comboBox_inputSolventDef.currentText()
        # if self.comboBox_inputSolventDef.currentText() != ' ':
        #     solDef_specifier = f'{Path(self.comboBox_inputSolventDef.currentText()).stem}_'
        # solModel_file_name = f'solModel_{solDef_specifier}' + Path(self.comboBox_inputMap.currentText()).stem + '.png'
        #
        # self.solModel_file_name = solModel_file_name
        # pixmap = QtGui.QPixmap(self.solModel_file_name)  # Setup pixmap with the provided image
        # pixmap = pixmap.scaled(self.label_solventModel.width()*2.8, self.label_solventModel.height()*3.2,
        #                        QtCore.Qt.KeepAspectRatio)  # Scale pixmap
        # window.setPixmap(pixmap)  # Set the pixmap onto the label
        # window.setAlignment(QtCore.Qt.AlignCenter)  # Align the label to center
        # Dialog_solModel.exec_()

class ImageWindow(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(ImageWindow, self).__init__(parent)


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())


