source: sasview/src/sas/qtgui/DensityPanel.py @ 6083d6e

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 6083d6e was 6083d6e, checked in by davidm, 8 years ago

added DensityPanel? (todo: add help button and add to menu)

  • Property mode set to 100644
File size: 5.5 KB
Line 
1# global
2import logging
3from periodictable import formula as Formula
4
5from PyQt4 import QtGui, QtCore
6
7# Local UI
8from UI.DensityPanel import Ui_DensityPanel
9
10def enum(*sequential, **named):
11    enums = dict(zip(sequential, range(len(sequential))), **named)
12    return type('Enum', (), enums)
13
14MODEL = enum(
15    'MOLECULAR_FORMULA',
16    'MOLAR_MASS',
17    'MOLAR_VOLUME',
18    'MASS_DENSITY',
19)
20
21MODES = enum(
22    'VOLUME_TO_DENSITY',
23    'DENSITY_TO_VOLUME',
24)
25
26def toMolarMass(formula):
27    AVOGADRO = 6.02214129e23
28
29    try:
30        f = Formula(str(formula))
31        return "%g" % (f.molecular_mass * AVOGADRO)
32    except:
33        return ""
34
35
36class FormulaValidator(QtGui.QValidator):
37    def __init__(self, parent=None):
38        super(FormulaValidator, self).__init__(parent)
39 
40    def validate(self, input, pos):
41        try:
42            Formula(str(input))
43            self._setStyleSheet("")
44            return QtGui.QValidator.Acceptable, pos
45
46        except Exception as e:
47            self._setStyleSheet("background-color:pink;")
48            return QtGui.QValidator.Intermediate, pos
49
50    def _setStyleSheet(self, value):
51        try:
52            if self.parent():
53                self.parent().setStyleSheet(value)
54        except:
55            pass
56
57
58class DensityPanel(QtGui.QDialog):
59
60    def __init__(self, parent=None):
61        super(DensityPanel, self).__init__(parent)
62
63        self.mode = None
64
65        self.setupUi()
66        self.setupModel()
67        self.setupMapper()
68
69    def setupUi(self):
70        self.ui = Ui_DensityPanel()
71        self.ui.setupUi(self)
72
73        # set validators
74        self.ui.editMolecularFormula.setValidator(FormulaValidator(self.ui.editMolecularFormula))
75
76        rx = QtCore.QRegExp("[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?")
77        self.ui.editMolarVolume.setValidator(QtGui.QRegExpValidator(rx, self.ui.editMolarVolume))
78        self.ui.editMassDensity.setValidator(QtGui.QRegExpValidator(rx, self.ui.editMassDensity))
79
80        # signals
81        QtCore.QObject.connect(
82            self.ui.editMolarVolume,
83            QtCore.SIGNAL("textEdited(QString)"),
84            lambda text: self.setMode(MODES.VOLUME_TO_DENSITY))
85        QtCore.QObject.connect(
86            self.ui.editMassDensity,
87            QtCore.SIGNAL("textEdited(QString)"),
88            lambda text: self.setMode(MODES.DENSITY_TO_VOLUME))
89        QtCore.QObject.connect(
90            self.ui.buttonBox.button(QtGui.QDialogButtonBox.Reset),
91            QtCore.SIGNAL("clicked(bool)"),
92            lambda checked: self.modelReset())
93
94    def setupModel(self):
95        self.model = QtGui.QStandardItemModel(self)
96        self.model.setItem(MODEL.MOLECULAR_FORMULA, QtGui.QStandardItem())
97        self.model.setItem(MODEL.MOLAR_MASS       , QtGui.QStandardItem())
98        self.model.setItem(MODEL.MOLAR_VOLUME     , QtGui.QStandardItem())
99        self.model.setItem(MODEL.MASS_DENSITY     , QtGui.QStandardItem())
100
101        QtCore.QObject.connect(
102            self.model,
103            QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"),
104            self.dataChanged)
105
106        self.modelReset()
107
108    def setupMapper(self):
109        self.mapper = QtGui.QDataWidgetMapper(self)
110        self.mapper.setModel(self.model)
111        self.mapper.setOrientation(QtCore.Qt.Vertical)
112
113        self.mapper.addMapping(self.ui.editMolecularFormula, MODEL.MOLECULAR_FORMULA)
114        self.mapper.addMapping(self.ui.editMolarMass       , MODEL.MOLAR_MASS)
115        self.mapper.addMapping(self.ui.editMolarVolume     , MODEL.MOLAR_VOLUME)
116        self.mapper.addMapping(self.ui.editMassDensity     , MODEL.MASS_DENSITY)
117
118        self.mapper.toFirst()
119
120    def dataChanged(self, top, bottom):
121        for index in xrange(top.row(), bottom.row() + 1):
122            if index == MODEL.MOLECULAR_FORMULA:
123                molarMass = toMolarMass(self.model.item(MODEL.MOLECULAR_FORMULA).text())
124                self.model.item(MODEL.MOLAR_MASS).setText(molarMass)
125
126                if self.mode == MODES.VOLUME_TO_DENSITY:
127                    self._updateDensity()
128                elif self.mode == MODES.DENSITY_TO_VOLUME:
129                    self._updateVolume()
130
131            elif index == MODEL.MOLAR_VOLUME and self.mode == MODES.VOLUME_TO_DENSITY:
132                self._updateDensity()
133
134            elif index == MODEL.MASS_DENSITY and self.mode == MODES.DENSITY_TO_VOLUME:
135                self._updateVolume()
136
137    def setMode(self, mode):
138        self.mode = mode
139
140    def _updateDensity(self):
141        try:
142            molarMass = float(toMolarMass(self.model.item(MODEL.MOLECULAR_FORMULA).text()))
143            molarVolume = float(self.model.item(MODEL.MOLAR_VOLUME).text())
144
145            molarDensity = molarMass / molarVolume
146            self.model.item(MODEL.MASS_DENSITY).setText(str(molarDensity))
147
148        except:
149            self.model.item(MODEL.MASS_DENSITY).setText("")
150
151    def _updateVolume(self):
152        try:
153            molarMass = float(toMolarMass(self.model.item(MODEL.MOLECULAR_FORMULA).text()))
154            molarDensity = float(self.model.item(MODEL.MASS_DENSITY).text())
155
156            molarVolume = molarMass / molarDensity
157            self.model.item(MODEL.MOLAR_VOLUME).setText(str(molarVolume))
158
159        except:
160            self.model.item(MODEL.MOLAR_VOLUME).setText("")
161
162    def modelReset(self):
163        #self.model.beginResetModel()
164        try:
165            self.setMode(None)
166            self.model.item(MODEL.MOLECULAR_FORMULA).setText("H2O")
167            self.model.item(MODEL.MOLAR_VOLUME     ).setText("")
168            self.model.item(MODEL.MASS_DENSITY     ).setText("")
169        finally:
170            pass
171            #self.model.endResetModel()
Note: See TracBrowser for help on using the repository browser.