source: sasview/src/sas/qtgui/Calculators/SldPanel.py @ 82efbe9

ESS_GUIESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_opencl
Last change on this file since 82efbe9 was 82efbe9, checked in by awashington, 5 years ago

Disable unused SLD terms

  • Property mode set to 100644
File size: 9.4 KB
RevLine 
[ef36eb2]1# global
2import logging
[4992ff2]3from PyQt5 import QtCore
4from PyQt5 import QtGui
5from PyQt5 import QtWidgets
[e4676c8]6
[ef36eb2]7from periodictable import formula as Formula
[5c0e717]8from periodictable.xsf import xray_energy, xray_sld
[ef36eb2]9from periodictable.nsf import neutron_scattering
10
[b0c5e8c]11import sas.qtgui.Utilities.GuiUtils as GuiUtils
12
[cd2cc745]13from sas.qtgui.UI import main_resources_rc
[ef36eb2]14
15# Local UI
[83eb5208]16from sas.qtgui.Calculators.UI.SldPanel import Ui_SldPanel
[ef36eb2]17
[d4881f6a]18from sas.qtgui.Utilities.GuiUtils import enum
[ef36eb2]19
20MODEL = enum(
21    'MOLECULAR_FORMULA',
22    'MASS_DENSITY',
[5c0e717]23    'NEUTRON_WAVELENGTH',
[ef36eb2]24    'NEUTRON_SLD_REAL',
25    'NEUTRON_SLD_IMAG',
[5c0e717]26    'XRAY_WAVELENGTH',
27    'XRAY_SLD_REAL',
28    'XRAY_SLD_IMAG',
[ef36eb2]29    'NEUTRON_INC_XS',
30    'NEUTRON_ABS_XS',
31    'NEUTRON_LENGTH',
32)
33
[912f438]34class NeutronSldResult(object):
35    def __init__(self, neutron_wavelength, neutron_sld_real,
36                 neutron_sld_imag, neutron_inc_xs, neutron_abs_xs,
37                 neutron_length):
38
[5c0e717]39        self.neutron_wavelength = neutron_wavelength
[ef36eb2]40        self.neutron_sld_real = neutron_sld_real
41        self.neutron_sld_imag = neutron_sld_imag
42        self.neutron_inc_xs = neutron_inc_xs
43        self.neutron_abs_xs = neutron_abs_xs
44        self.neutron_length = neutron_length
45
[912f438]46class XraySldResult(object):
47    def __init__(self, xray_wavelength, xray_sld_real, xray_sld_imag):
[ef36eb2]48
[912f438]49        self.xray_wavelength = xray_wavelength
50        self.xray_sld_real = xray_sld_real
51        self.xray_sld_imag = xray_sld_imag
52
53def neutronSldAlgorithm(molecular_formula, mass_density, neutron_wavelength):
[ef36eb2]54
[5c0e717]55    (neutron_sld_real, neutron_sld_imag, _), (_, neutron_abs_xs, neutron_inc_xs), neutron_length = \
[ef36eb2]56        neutron_scattering(
57            compound=molecular_formula,
58            density=mass_density,
[5c0e717]59            wavelength=neutron_wavelength)
[ef36eb2]60
61    SCALE = 1e-6
62
63    # neutron sld
[5c0e717]64    scaled_neutron_sld_real = SCALE * neutron_sld_real
65    scaled_neutron_sld_imag = SCALE * abs(neutron_sld_imag)
[ef36eb2]66
[912f438]67    return NeutronSldResult(neutron_wavelength, scaled_neutron_sld_real,
68                            scaled_neutron_sld_imag, neutron_inc_xs,
69                            neutron_abs_xs, neutron_length)
70
71def xraySldAlgorithm(molecular_formula, mass_density, xray_wavelength):
72
73    xray_sld_real, xray_sld_imag = xray_sld(
74            compound=molecular_formula,
75            density=mass_density,
76            wavelength=xray_wavelength)
77
78    SCALE = 1e-6
79
[5c0e717]80    # xray sld
81    scaled_xray_sld_real = SCALE * xray_sld_real
82    scaled_xray_sld_imag = SCALE * abs(xray_sld_imag)
[ef36eb2]83
84
[912f438]85    return XraySldResult(xray_wavelength, scaled_xray_sld_real,
86                         scaled_xray_sld_imag)
[ef36eb2]87
88
[4992ff2]89class SldPanel(QtWidgets.QDialog):
[ef36eb2]90
91    def __init__(self, parent=None):
[1d85b5e]92        super(SldPanel, self).__init__()
93
94        self.manager = parent
[ef36eb2]95
96        self.setupUi()
[33c0561]97        # disable the context help icon
98        self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint)
99
[ef36eb2]100        self.setupModel()
101        self.setupMapper()
102
103    def _getOutputs(self):
104        return {
105            MODEL.NEUTRON_SLD_REAL: self.ui.editNeutronSldReal,
106            MODEL.NEUTRON_SLD_IMAG: self.ui.editNeutronSldImag,
[5c0e717]107            MODEL.XRAY_SLD_REAL: self.ui.editXraySldReal,
108            MODEL.XRAY_SLD_IMAG: self.ui.editXraySldImag,
[ef36eb2]109            MODEL.NEUTRON_INC_XS: self.ui.editNeutronIncXs,
110            MODEL.NEUTRON_ABS_XS: self.ui.editNeutronAbsXs,
111            MODEL.NEUTRON_LENGTH: self.ui.editNeutronLength
112        }
113
114    def setupUi(self):
115        self.ui = Ui_SldPanel()
116        self.ui.setupUi(self)
117
118        # set validators
[fbfc488]119        # TODO: GuiUtils.FormulaValidator() crashes with Qt5 - fix
120        #self.ui.editMolecularFormula.setValidator(GuiUtils.FormulaValidator(self.ui.editMolecularFormula))
[ef36eb2]121
122        rx = QtCore.QRegExp("[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?")
123        self.ui.editMassDensity.setValidator(QtGui.QRegExpValidator(rx, self.ui.editMassDensity))
[5c0e717]124        self.ui.editNeutronWavelength.setValidator(QtGui.QRegExpValidator(rx, self.ui.editNeutronWavelength))
125        self.ui.editXrayWavelength.setValidator(QtGui.QRegExpValidator(rx, self.ui.editXrayWavelength))
[ef36eb2]126
127        # signals
[d738feb]128        self.ui.helpButton.clicked.connect(self.displayHelp)
129        self.ui.closeButton.clicked.connect(self.closePanel)
130        self.ui.recalculateButton.clicked.connect(self.calculateSLD)
131
132    def calculateSLD(self):
133        self.recalculateSLD()
[ef36eb2]134
135    def setupModel(self):
136        self.model = QtGui.QStandardItemModel(self)
[5c0e717]137        self.model.setItem(MODEL.MOLECULAR_FORMULA , QtGui.QStandardItem())
138        self.model.setItem(MODEL.MASS_DENSITY      , QtGui.QStandardItem())
139        self.model.setItem(MODEL.NEUTRON_WAVELENGTH, QtGui.QStandardItem())
140        self.model.setItem(MODEL.XRAY_WAVELENGTH   , QtGui.QStandardItem())
[ef36eb2]141
[b3e8629]142        for key in list(self._getOutputs().keys()):
[ef36eb2]143            self.model.setItem(key, QtGui.QStandardItem())
144
[4992ff2]145        self.model.dataChanged.connect(self.dataChanged)
[ef36eb2]146
[bd39d6c]147        self.ui.editMassDensity.textChanged.connect(self.recalculateSLD)
148        self.ui.editMolecularFormula.textChanged.connect(self.recalculateSLD)
149        self.ui.editNeutronWavelength.textChanged.connect(self.recalculateSLD)
150        self.ui.editXrayWavelength.textChanged.connect(self.recalculateSLD)
[5c0e717]151
[ef36eb2]152        self.modelReset()
153
154    def setupMapper(self):
[4992ff2]155        self.mapper = QtWidgets.QDataWidgetMapper(self)
[ef36eb2]156        self.mapper.setModel(self.model)
157        self.mapper.setOrientation(QtCore.Qt.Vertical)
[5c0e717]158        self.mapper.addMapping(self.ui.editMolecularFormula , MODEL.MOLECULAR_FORMULA)
159        self.mapper.addMapping(self.ui.editMassDensity      , MODEL.MASS_DENSITY)
160        self.mapper.addMapping(self.ui.editNeutronWavelength, MODEL.NEUTRON_WAVELENGTH)
161        self.mapper.addMapping(self.ui.editXrayWavelength   , MODEL.XRAY_WAVELENGTH)
[ef36eb2]162
[b3e8629]163        for key, edit in self._getOutputs().items():
[ef36eb2]164            self.mapper.addMapping(edit, key)
165
[fbfc488]166        self.mapper.toFirst()
[ef36eb2]167
168    def dataChanged(self, top, bottom):
169        update = False
[b3e8629]170        for index in range(top.row(), bottom.row() + 1):
[5c0e717]171            if (index == MODEL.MOLECULAR_FORMULA) or (index == MODEL.MASS_DENSITY) or (index == MODEL.NEUTRON_WAVELENGTH) or (index == MODEL.XRAY_WAVELENGTH):
[ef36eb2]172                update = True
173
[d738feb]174        # calculation
[ef36eb2]175        if update:
[d738feb]176            self.recalculateSLD()
177
178    def recalculateSLD(self):
[5c0e717]179        formula = self.ui.editMolecularFormula.text()
180        density = self.ui.editMassDensity.text()
181        neutronWavelength = self.ui.editNeutronWavelength.text()
182        xrayWavelength = self.ui.editXrayWavelength.text()
183
[912f438]184        if not formula or not density:
185            return
186
187        def format(value):
188            return ("%-5.3g" % value).strip()
189
190        if neutronWavelength:
191            results = neutronSldAlgorithm(str(formula), float(density), float(neutronWavelength))
192
193            self.model.item(MODEL.NEUTRON_SLD_REAL).setText(format(results.neutron_sld_real))
194            self.model.item(MODEL.NEUTRON_SLD_IMAG).setText(format(results.neutron_sld_imag))
195            self.model.item(MODEL.NEUTRON_INC_XS).setText(format(results.neutron_inc_xs))
196            self.model.item(MODEL.NEUTRON_ABS_XS).setText(format(results.neutron_abs_xs))
197            self.model.item(MODEL.NEUTRON_LENGTH).setText(format(results.neutron_length))
[82efbe9]198            self.model.item(MODEL.NEUTRON_LENGTH).setEnabled(True)
199            self.ui.editNeutronSldReal.setEnabled(True)
200            self.ui.editNeutronSldImag.setEnabled(True)
201            self.ui.editNeutronIncXs.setEnabled(True)
202            self.ui.editNeutronLength.setEnabled(True)
203            self.ui.editNeutronAbsXs.setEnabled(True)
[912f438]204        else:
205            self.model.item(MODEL.NEUTRON_SLD_REAL).setText("")
206            self.model.item(MODEL.NEUTRON_SLD_IMAG).setText("")
207            self.model.item(MODEL.NEUTRON_INC_XS).setText("")
208            self.model.item(MODEL.NEUTRON_ABS_XS).setText("")
209            self.model.item(MODEL.NEUTRON_LENGTH).setText("")
[82efbe9]210            self.ui.editNeutronSldReal.setEnabled(False)
211            self.ui.editNeutronSldImag.setEnabled(False)
212            self.ui.editNeutronIncXs.setEnabled(False)
213            self.ui.editNeutronLength.setEnabled(False)
214            self.ui.editNeutronAbsXs.setEnabled(False)
[912f438]215
216        if xrayWavelength:
217            results = xraySldAlgorithm(str(formula), float(density), float(xrayWavelength))
218
219            self.model.item(MODEL.XRAY_SLD_REAL).setText(format(results.xray_sld_real))
220            self.model.item(MODEL.XRAY_SLD_IMAG).setText(format(results.xray_sld_imag))
[82efbe9]221            self.ui.editXraySldReal.setEnabled(True)
222            self.ui.editXraySldImag.setEnabled(True)
[912f438]223        else:
224            self.model.item(MODEL.XRAY_SLD_REAL).setText("")
225            self.model.item(MODEL.XRAY_SLD_IMAG).setText("")
[82efbe9]226            self.ui.editXraySldReal.setEnabled(False)
227            self.ui.editXraySldImag.setEnabled(False)
[ef36eb2]228
229    def modelReset(self):
230        #self.model.beginResetModel()
231        try:
[5c0e717]232            self.model.item(MODEL.MOLECULAR_FORMULA ).setText("H2O")
233            self.model.item(MODEL.MASS_DENSITY      ).setText("1.0")
234            self.model.item(MODEL.NEUTRON_WAVELENGTH).setText("6.0")
235            self.model.item(MODEL.XRAY_WAVELENGTH   ).setText("1.0")
236            self.recalculateSLD()
[ef36eb2]237        finally:
238            pass
[fbfc488]239        #self.model.endResetModel()
[1d85b5e]240
241    def displayHelp(self):
[aed0532]242        location = "/user/qtgui/Calculators/sld_calculator_help.html"
[e90988c]243        self.manager.showHelp(location)
244
[1d85b5e]245
[d738feb]246    def closePanel(self):
247        """
248        close the window containing this panel
249        """
250        self.close()
251
Note: See TracBrowser for help on using the repository browser.