source: sasview/src/sas/qtgui/Perspectives/Inversion/dmax.py @ 477c473

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 477c473 was 477c473, checked in by krzywon, 6 years ago

Fix DMax window updates.

  • Property mode set to 100644
File size: 5.9 KB
Line 
1# -*- coding: utf-8 -*-
2"""
3Dialog panel to explore the P(r) inversion results for a range
4of D_max value. User picks a number of points and a range of
5distances, then can toggle between inversion outputs and see
6their distribution as a function of D_max.
7"""
8
9# global
10import sys
11import os
12import logging
13import numpy as np
14from PyQt4 import QtCore
15from PyQt4 import QtGui
16from PyQt4 import QtWebKit
17
18from twisted.internet import threads
19
20# sas-global
21from sas.qtgui.Plotting.PlotterData import Data1D
22from sas.qtgui.Plotting.Plotter import PlotterWidget
23import sas.qtgui.Utilities.GuiUtils as GuiUtils
24
25# local
26from UI.dmax import Ui_DmaxExplorer
27# from InvariantDetails import DetailsDialog
28# from InvariantUtils import WIDGETS
29
30logger = logging.getLogger(__name__)
31
32def enum(*sequential, **named):
33    enums = dict(zip(sequential, range(len(sequential))), **named)
34    return type('Enum', (), enums)
35
36W = enum( 'NPTS',           #0
37          'DMIN',               #1
38          'DMAX',               #2
39          'VARIABLE',         #3
40)
41
42class DmaxWindow(QtGui.QDialog, Ui_DmaxExplorer):
43    # The controller which is responsible for managing signal slots connections
44    # for the gui and providing an interface to the data model.
45    name = "Dmax Explorer"  # For displaying in the combo box
46
47    def __init__(self, pr_state, nfunc, parent=None):
48        super(DmaxWindow, self).__init__()
49        self.setupUi(self)
50
51        self.setWindowTitle("Dₘₐₓ Explorer")
52
53        self.pr_state = pr_state
54        self.nfunc = nfunc
55        self.communicator = GuiUtils.Communicate()
56
57        self.plot = PlotterWidget(self, self)
58        self.hasPlot = None
59        self.verticalLayout.insertWidget(0, self.plot)
60
61        # Let's choose the Standard Item Model.
62        self.model = QtGui.QStandardItemModel(self)
63        self.mapper = None
64
65        # # Connect buttons to slots.
66        # # Needs to be done early so default values propagate properly.
67        self.setupSlots()
68
69        # Set up the model.
70        self.setupModel()
71
72        # # Set up the mapper
73        self.setupMapper()
74
75    def setupSlots(self):
76        self.closeButton.clicked.connect(self.close)
77
78        self.dependentVariable.currentIndexChanged.connect(self.dVChanged)
79
80        self.model.itemChanged.connect(self.modelChanged)
81
82    def setupModel(self):
83        self.model.setItem(W.NPTS, QtGui.QStandardItem(str(self.nfunc)))
84        self.model.setItem(W.DMIN,
85                           QtGui.QStandardItem(
86                               str(0.9*self.pr_state.d_max)))
87        self.model.setItem(W.DMAX,
88                           QtGui.QStandardItem(
89                               str(1.1*self.pr_state.d_max)))
90        self.model.setItem(W.VARIABLE,
91                           QtGui.QStandardItem( "χ²/dof"))
92
93    def setupMapper(self):
94        self.mapper = QtGui.QDataWidgetMapper(self)
95        self.mapper.setOrientation(QtCore.Qt.Vertical)
96        self.mapper.setModel(self.model)
97
98        self.mapper.addMapping(self.Npts, W.NPTS)
99        self.mapper.addMapping(self.minDist, W.DMIN)
100        self.mapper.addMapping(self.maxDist, W.DMAX)
101        self.mapper.addMapping(self.dependentVariable, W.VARIABLE)
102
103        self.mapper.toFirst()
104
105    def dVChanged(self):
106        self.modelChanged()
107
108    def modelChanged(self):
109        if not self.mapper:
110            return
111
112        iq0 = []
113        rg = []
114        pos = []
115        pos_err = []
116        osc = []
117        bck = []
118        chi2 = []
119
120        xs = np.linspace(float(self.model.item(W.DMIN).text()),
121                         float(self.model.item(W.DMAX).text()),
122                         float(self.model.item(W.NPTS).text()))
123
124        original = self.pr_state.d_max
125        for x in xs:
126            self.pr_state.d_max = x
127            try:
128                out, cov = self.pr_state.invert(self.pr_state.nfunc)
129
130                iq0.append(self.pr_state.iq0(out))
131                rg.append(self.pr_state.rg(out))
132                pos.append(self.pr_state.get_positive(out))
133                pos_err.append(self.pr_state.get_pos_err(out, cov))
134                osc.append(self.pr_state.oscillations(out))
135                bck.append(self.pr_state.background)
136                chi2.append(self.pr_state.chi2)
137            except:
138                # This inversion failed, skip this D_max value
139                msg = "ExploreDialog: inversion failed "
140                msg += "for D_max=%s\n%s" % (str(x), sys.exc_value)
141                print(msg)
142                # logger.error(msg)
143
144        #Return the invertor to its original state
145        self.pr_state.d_max = original
146        self.pr_state.invert(self.nfunc)
147
148        plotter = unicode(self.model.item(W.VARIABLE).text())
149        if plotter == u"χ²/dof":
150            ys = chi2
151        elif plotter == u"I(Q=0)":
152            ys = iq0
153        elif plotter == u"Rg":
154            ys = rg
155        elif plotter == u"Oscillation parameter":
156            ys = osc
157        elif plotter == u"Background":
158            ys = bck
159        elif plotter == u"Positive Fraction":
160            ys = pos
161        else:
162            ys = pos_err
163
164        data = Data1D(xs, ys)
165        if self.hasPlot:
166            self.plot.removePlot(None)
167        self.hasPlot = True
168        self.plot.plot(data=data, marker="-")
169
170
171if __name__ == "__main__":
172    APP = QtGui.QApplication([])
173    import qt4reactor
174    qt4reactor.install()
175    # DO NOT move the following import to the top!
176    # (unless you know what you're doing)
177    from twisted.internet import reactor
178    from sas.sascalc.pr.invertor import Invertor
179    from sas.sascalc.dataloader.loader import Loader
180
181    data = Loader().load("test/pr_inversion/test/sphere_80.txt")[0]
182    pr_state = Invertor()
183    pr_state.d_max = 130.0
184    pr_state.alpha = 0.0007
185    pr_state.x = data.x
186    pr_state.y = data.y
187    pr_state.err = 0.15*np.sqrt(data.y[0])*np.sqrt(data.y)
188    pr_state.nfunc = 15
189
190    DLG = DmaxWindow(pr_state, 15, reactor)
191    DLG.show()
192    reactor.run()
Note: See TracBrowser for help on using the repository browser.