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

ESS_GUIESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since d738feb was d738feb, checked in by Tim Snow <tim.snow@…>, 6 years ago

Modifications to SLD panel

First round of modifications to change the button layout and recalculation behaviour for user friendlieness.

  • Property mode set to 100644
File size: 7.9 KB
Line 
1# global
2import logging
3from PyQt5 import QtCore
4from PyQt5 import QtGui
5from PyQt5 import QtWidgets
6
7from periodictable import formula as Formula
8from periodictable.xsf import xray_energy, xray_sld_from_atoms
9from periodictable.nsf import neutron_scattering
10
11import sas.qtgui.Utilities.GuiUtils as GuiUtils
12
13from sas.qtgui.UI import main_resources_rc
14
15# Local UI
16from sas.qtgui.Calculators.UI.SldPanel import Ui_SldPanel
17
18from sas.qtgui.Utilities.GuiUtils import enum
19
20MODEL = enum(
21    'MOLECULAR_FORMULA',
22    'MASS_DENSITY',
23    'WAVELENGTH',
24    'NEUTRON_SLD_REAL',
25    'NEUTRON_SLD_IMAG',
26    'CU_KA_SLD_REAL',
27    'CU_KA_SLD_IMAG',
28    'MO_KA_SLD_REAL',
29    'MO_KA_SLD_IMAG',
30    'NEUTRON_INC_XS',
31    'NEUTRON_ABS_XS',
32    'NEUTRON_LENGTH',
33)
34
35class SldResult(object):
36    def __init__(self, molecular_formula, mass_density, wavelength,
37        neutron_sld_real, neutron_sld_imag,
38        cu_ka_sld_real, cu_ka_sld_imag,
39        mo_ka_sld_real, mo_ka_sld_imag,
40        neutron_inc_xs, neutron_abs_xs, neutron_length):
41
42        self.molecular_formula = molecular_formula
43        self.mass_density = mass_density
44        self.wavelength = wavelength
45        self.neutron_sld_real = neutron_sld_real
46        self.neutron_sld_imag = neutron_sld_imag
47        self.cu_ka_sld_real = cu_ka_sld_real
48        self.cu_ka_sld_imag = cu_ka_sld_imag
49        self.mo_ka_sld_real = mo_ka_sld_real
50        self.mo_ka_sld_imag = mo_ka_sld_imag
51        self.neutron_inc_xs = neutron_inc_xs
52        self.neutron_abs_xs = neutron_abs_xs
53        self.neutron_length = neutron_length
54
55def sldAlgorithm(molecular_formula, mass_density, wavelength):
56
57    sld_formula = Formula(molecular_formula, density=mass_density)
58
59    def calculate_sld(formula):
60        if len(formula.atoms) != 1:
61            raise NotImplementedError()
62        energy = xray_energy(list(formula.atoms.keys())[0].K_alpha)
63        return xray_sld_from_atoms(
64            sld_formula.atoms,
65            density=mass_density,
66            energy=energy)
67
68    cu_real, cu_imag = calculate_sld(Formula("Cu"))
69    mo_real, mo_imag = calculate_sld(Formula("Mo"))
70
71    (sld_real, sld_imag, _), (_, neutron_abs_xs, neutron_inc_xs), neutron_length = \
72        neutron_scattering(
73            compound=molecular_formula,
74            density=mass_density,
75            wavelength=wavelength)
76
77    SCALE = 1e-6
78
79    # neutron sld
80    neutron_sld_real = SCALE * sld_real
81    neutron_sld_imag = SCALE * abs(sld_imag)
82
83    # Cu sld
84    cu_ka_sld_real = SCALE * cu_real
85    cu_ka_sld_imag = SCALE * abs(cu_imag)
86
87    # Mo sld
88    mo_ka_sld_real = SCALE * mo_real
89    mo_ka_sld_imag = SCALE * abs(mo_imag)
90
91    return SldResult(
92        molecular_formula, mass_density, wavelength,
93        neutron_sld_real, neutron_sld_imag,
94        cu_ka_sld_real, cu_ka_sld_imag,
95        mo_ka_sld_real, mo_ka_sld_imag,
96        neutron_inc_xs, neutron_abs_xs, neutron_length)
97
98
99class SldPanel(QtWidgets.QDialog):
100
101    def __init__(self, parent=None):
102        super(SldPanel, self).__init__()
103
104        self.manager = parent
105
106        self.setupUi()
107        self.setupModel()
108        self.setupMapper()
109
110    def _getOutputs(self):
111        return {
112            MODEL.NEUTRON_SLD_REAL: self.ui.editNeutronSldReal,
113            MODEL.NEUTRON_SLD_IMAG: self.ui.editNeutronSldImag,
114            MODEL.CU_KA_SLD_REAL: self.ui.editCuKaSldReal,
115            MODEL.CU_KA_SLD_IMAG: self.ui.editCuKaSldImag,
116            MODEL.MO_KA_SLD_REAL: self.ui.editMoKaSldReal,
117            MODEL.MO_KA_SLD_IMAG: self.ui.editMoKaSldImag,
118            MODEL.NEUTRON_INC_XS: self.ui.editNeutronIncXs,
119            MODEL.NEUTRON_ABS_XS: self.ui.editNeutronAbsXs,
120            MODEL.NEUTRON_LENGTH: self.ui.editNeutronLength
121        }
122
123    def setupUi(self):
124        self.ui = Ui_SldPanel()
125        self.ui.setupUi(self)
126
127        # set validators
128        # TODO: GuiUtils.FormulaValidator() crashes with Qt5 - fix
129        #self.ui.editMolecularFormula.setValidator(GuiUtils.FormulaValidator(self.ui.editMolecularFormula))
130
131        rx = QtCore.QRegExp("[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?")
132        self.ui.editMassDensity.setValidator(QtGui.QRegExpValidator(rx, self.ui.editMassDensity))
133        self.ui.editWavelength.setValidator(QtGui.QRegExpValidator(rx, self.ui.editWavelength))
134
135        # signals
136        self.ui.helpButton.clicked.connect(self.displayHelp)
137        self.ui.closeButton.clicked.connect(self.closePanel)
138        self.ui.recalculateButton.clicked.connect(self.calculateSLD)
139
140    def calculateSLD(self):
141        self.recalculateSLD()
142
143    def setupModel(self):
144        self.model = QtGui.QStandardItemModel(self)
145        self.model.setItem(MODEL.MOLECULAR_FORMULA, QtGui.QStandardItem())
146        self.model.setItem(MODEL.MASS_DENSITY     , QtGui.QStandardItem())
147        self.model.setItem(MODEL.WAVELENGTH       , QtGui.QStandardItem())
148
149        for key in list(self._getOutputs().keys()):
150            self.model.setItem(key, QtGui.QStandardItem())
151
152        self.model.dataChanged.connect(self.dataChanged)
153
154        self.modelReset()
155
156    def setupMapper(self):
157        self.mapper = QtWidgets.QDataWidgetMapper(self)
158        self.mapper.setModel(self.model)
159        self.mapper.setOrientation(QtCore.Qt.Vertical)
160        self.mapper.addMapping(self.ui.editMolecularFormula, MODEL.MOLECULAR_FORMULA)
161        self.mapper.addMapping(self.ui.editMassDensity     , MODEL.MASS_DENSITY)
162        self.mapper.addMapping(self.ui.editWavelength      , MODEL.WAVELENGTH)
163
164        for key, edit in self._getOutputs().items():
165            self.mapper.addMapping(edit, key)
166
167        self.mapper.toFirst()
168
169    def dataChanged(self, top, bottom):
170        update = False
171        for index in range(top.row(), bottom.row() + 1):
172            if (index == MODEL.MOLECULAR_FORMULA) or (index == MODEL.MASS_DENSITY) or (index == MODEL.WAVELENGTH):
173                update = True
174
175        # calculation
176        if update:
177            self.recalculateSLD()
178
179    def recalculateSLD(self):
180        formula = self.model.item(MODEL.MOLECULAR_FORMULA).text()
181        density = self.model.item(MODEL.MASS_DENSITY).text()
182        wavelength = self.model.item(MODEL.WAVELENGTH).text()
183        if len(formula) > 0 and len(density) > 0 and len(wavelength) > 0:
184            try:
185                results = sldAlgorithm(str(formula), float(density), float(wavelength))
186
187                def format(value):
188                    return ("%-5.3g" % value).strip()
189
190                self.model.item(MODEL.NEUTRON_SLD_REAL).setText(format(results.neutron_sld_real))
191                self.model.item(MODEL.NEUTRON_SLD_IMAG).setText(format(results.neutron_sld_imag))
192
193                self.model.item(MODEL.CU_KA_SLD_REAL).setText(format(results.cu_ka_sld_real))
194                self.model.item(MODEL.CU_KA_SLD_IMAG).setText(format(results.cu_ka_sld_imag))
195
196                self.model.item(MODEL.MO_KA_SLD_REAL).setText(format(results.mo_ka_sld_real))
197                self.model.item(MODEL.MO_KA_SLD_IMAG).setText(format(results.mo_ka_sld_imag))
198
199                self.model.item(MODEL.NEUTRON_INC_XS).setText(format(results.neutron_inc_xs))
200                self.model.item(MODEL.NEUTRON_ABS_XS).setText(format(results.neutron_abs_xs))
201                self.model.item(MODEL.NEUTRON_LENGTH).setText(format(results.neutron_length))
202
203                return
204
205            except Exception as e:
206                pass
207
208        for key in list(self._getOutputs().keys()):
209            self.model.item(key).setText("")
210
211    def modelReset(self):
212        #self.model.beginResetModel()
213        try:
214            self.model.item(MODEL.MOLECULAR_FORMULA).setText("H2O")
215            self.model.item(MODEL.MASS_DENSITY     ).setText("1")
216            self.model.item(MODEL.WAVELENGTH       ).setText("6")
217        finally:
218            pass
219        #self.model.endResetModel()
220
221    def displayHelp(self):
222        location = "/user/qtgui/Calculators/sld_calculator_help.html"
223        self.manager.showHelp(location)
224
225
226    def closePanel(self):
227        """
228        close the window containing this panel
229        """
230        self.close()
231
Note: See TracBrowser for help on using the repository browser.