source: sasview/src/sas/qtgui/Calculators/DensityPanel.py @ c71b20a

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

Fix presentation of results in the Density calculator

  • Property mode set to 100644
File size: 5.4 KB
RevLine 
[6083d6e]1# global
2import logging
[1d85b5e]3import functools
[4992ff2]4from PyQt5 import QtCore
5from PyQt5 import QtGui
6from PyQt5 import QtWidgets
[1d85b5e]7
[6083d6e]8from periodictable import formula as Formula
9
[83eb5208]10from sas.qtgui.Utilities.GuiUtils import FormulaValidator
[cd2cc745]11from sas.qtgui.UI import main_resources_rc
[b0c5e8c]12from sas.qtgui.Utilities.GuiUtils import HELP_DIRECTORY_LOCATION
[6083d6e]13
14# Local UI
[83eb5208]15from sas.qtgui.Calculators.UI.DensityPanel import Ui_DensityPanel
[6083d6e]16
[d4881f6a]17from sas.qtgui.Utilities.GuiUtils import enum
[d813cf9a]18from sas.qtgui.Utilities.GuiUtils import formatNumber
[6083d6e]19
20MODEL = enum(
21    'MOLECULAR_FORMULA',
22    'MOLAR_MASS',
23    'MOLAR_VOLUME',
24    'MASS_DENSITY',
25)
26
27MODES = enum(
28    'VOLUME_TO_DENSITY',
29    'DENSITY_TO_VOLUME',
30)
31
32def toMolarMass(formula):
33    AVOGADRO = 6.02214129e23
34
35    try:
36        f = Formula(str(formula))
37        return "%g" % (f.molecular_mass * AVOGADRO)
38    except:
39        return ""
40
41
[4992ff2]42class DensityPanel(QtWidgets.QDialog):
[6083d6e]43
44    def __init__(self, parent=None):
[1d85b5e]45        super(DensityPanel, self).__init__()
[6083d6e]46
47        self.mode = None
[1d85b5e]48        self.manager = parent
[6083d6e]49        self.setupUi()
50        self.setupModel()
51        self.setupMapper()
52
53    def setupUi(self):
54        self.ui = Ui_DensityPanel()
55        self.ui.setupUi(self)
56
[f140169]57        # no reason to have this widget resizable
58        self.setFixedSize(self.minimumSizeHint())
59
[6083d6e]60        # set validators
[fbfc488]61        #self.ui.editMolecularFormula.setValidator(FormulaValidator(self.ui.editMolecularFormula))
[6083d6e]62
63        rx = QtCore.QRegExp("[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?")
64        self.ui.editMolarVolume.setValidator(QtGui.QRegExpValidator(rx, self.ui.editMolarVolume))
65        self.ui.editMassDensity.setValidator(QtGui.QRegExpValidator(rx, self.ui.editMassDensity))
66
67        # signals
[1d85b5e]68        self.ui.editMolarVolume.textEdited.connect(functools.partial(self.setMode, MODES.VOLUME_TO_DENSITY))
69        self.ui.editMassDensity.textEdited.connect(functools.partial(self.setMode, MODES.DENSITY_TO_VOLUME))
70
[4992ff2]71        self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Reset).clicked.connect(self.modelReset)
72        self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Help).clicked.connect(self.displayHelp)
[6083d6e]73
74    def setupModel(self):
75        self.model = QtGui.QStandardItemModel(self)
76        self.model.setItem(MODEL.MOLECULAR_FORMULA, QtGui.QStandardItem())
77        self.model.setItem(MODEL.MOLAR_MASS       , QtGui.QStandardItem())
78        self.model.setItem(MODEL.MOLAR_VOLUME     , QtGui.QStandardItem())
79        self.model.setItem(MODEL.MASS_DENSITY     , QtGui.QStandardItem())
80
[1d85b5e]81        self.model.dataChanged.connect(self.dataChanged)
[6083d6e]82
83        self.modelReset()
84
85    def setupMapper(self):
[4992ff2]86        self.mapper = QtWidgets.QDataWidgetMapper(self)
[6083d6e]87        self.mapper.setModel(self.model)
88        self.mapper.setOrientation(QtCore.Qt.Vertical)
89
90        self.mapper.addMapping(self.ui.editMolecularFormula, MODEL.MOLECULAR_FORMULA)
91        self.mapper.addMapping(self.ui.editMolarMass       , MODEL.MOLAR_MASS)
92        self.mapper.addMapping(self.ui.editMolarVolume     , MODEL.MOLAR_VOLUME)
93        self.mapper.addMapping(self.ui.editMassDensity     , MODEL.MASS_DENSITY)
94
[fbfc488]95        self.mapper.toFirst()
[6083d6e]96
97    def dataChanged(self, top, bottom):
[b3e8629]98        for index in range(top.row(), bottom.row() + 1):
[6083d6e]99            if index == MODEL.MOLECULAR_FORMULA:
100                molarMass = toMolarMass(self.model.item(MODEL.MOLECULAR_FORMULA).text())
[d813cf9a]101                molarMass = formatNumber(molarMass, high=True)
[6083d6e]102                self.model.item(MODEL.MOLAR_MASS).setText(molarMass)
103
104                if self.mode == MODES.VOLUME_TO_DENSITY:
105                    self._updateDensity()
106                elif self.mode == MODES.DENSITY_TO_VOLUME:
107                    self._updateVolume()
108
109            elif index == MODEL.MOLAR_VOLUME and self.mode == MODES.VOLUME_TO_DENSITY:
110                self._updateDensity()
111
112            elif index == MODEL.MASS_DENSITY and self.mode == MODES.DENSITY_TO_VOLUME:
113                self._updateVolume()
114
115    def setMode(self, mode):
116        self.mode = mode
117
118    def _updateDensity(self):
119        try:
120            molarMass = float(toMolarMass(self.model.item(MODEL.MOLECULAR_FORMULA).text()))
121            molarVolume = float(self.model.item(MODEL.MOLAR_VOLUME).text())
122
123            molarDensity = molarMass / molarVolume
[d813cf9a]124            molarDensity = formatNumber(molarDensity, high=True)
[6083d6e]125            self.model.item(MODEL.MASS_DENSITY).setText(str(molarDensity))
126
[9968d6a]127        except (ArithmeticError, ValueError):
[6083d6e]128            self.model.item(MODEL.MASS_DENSITY).setText("")
129
130    def _updateVolume(self):
131        try:
132            molarMass = float(toMolarMass(self.model.item(MODEL.MOLECULAR_FORMULA).text()))
133            molarDensity = float(self.model.item(MODEL.MASS_DENSITY).text())
134
135            molarVolume = molarMass / molarDensity
[d813cf9a]136            molarVolume = formatNumber(molarVolume, high=True)
[6083d6e]137            self.model.item(MODEL.MOLAR_VOLUME).setText(str(molarVolume))
138
[9968d6a]139        except (ArithmeticError, ValueError):
[6083d6e]140            self.model.item(MODEL.MOLAR_VOLUME).setText("")
141
142    def modelReset(self):
143        try:
144            self.setMode(None)
145            self.model.item(MODEL.MOLECULAR_FORMULA).setText("H2O")
146            self.model.item(MODEL.MOLAR_VOLUME     ).setText("")
147            self.model.item(MODEL.MASS_DENSITY     ).setText("")
148        finally:
149            pass
[1d85b5e]150
151    def displayHelp(self):
[aed0532]152        location = "/user/qtgui/Calculators/density_calculator_help.html"
[e90988c]153        self.manager.showHelp(location)
154
[9968d6a]155
Note: See TracBrowser for help on using the repository browser.