source: sasview/src/sas/qtgui/SldPanel.py @ 14d9c7b

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 14d9c7b was e4676c8, checked in by Piotr Rozyczko <rozyczko@…>, 8 years ago

Added SLDCalculator unit tests. Refactored things a bit.

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