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

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since 0849aec was 0849aec, checked in by Piotr Rozyczko <rozyczko@…>, 7 years ago

Initial, in-progress version. Not really working atm. SASVIEW-787

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