source: sasview/src/sas/qtgui/Perspectives/Inversion/DMaxExplorerWidget.py @ d4881f6a

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 d4881f6a was d4881f6a, checked in by Piotr Rozyczko <rozyczko@…>, 6 years ago

Initial implementation of Adam Washington's Corfunc perspective.
Converted to py3/Qt5.

  • Property mode set to 100755
File size: 5.0 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 PyQt5 import QtCore
15from PyQt5 import QtGui
16from PyQt5 import QtWidgets
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
32from sas.qtgui.Utilities.GuiUtils import enum
33
34W = enum( 'NPTS',           #0
35          'DMIN',               #1
36          'DMAX',               #2
37          'VARIABLE',         #3
38)
39
40class DmaxWindow(QtWidgets.QDialog, Ui_DmaxExplorer):
41    # The controller which is responsible for managing signal slots connections
42    # for the gui and providing an interface to the data model.
43    name = "Dmax Explorer"  # For displaying in the combo box
44
45    def __init__(self, pr_state, nfunc, parent=None):
46        super(DmaxWindow, self).__init__()
47        self.setupUi(self)
48
49        self.setWindowTitle("Dₘₐₓ Explorer")
50
51        self.pr_state = pr_state
52        self.nfunc = nfunc
53        self.communicator = GuiUtils.Communicate()
54
55        self.plot = PlotterWidget(self, self)
56        self.hasPlot = None
57        self.verticalLayout.insertWidget(0, self.plot)
58
59        # Let's choose the Standard Item Model.
60        self.model = QtGui.QStandardItemModel(self)
61        self.mapper = None
62
63        # # Connect buttons to slots.
64        # # Needs to be done early so default values propagate properly.
65        self.setupSlots()
66
67        # Set up the model.
68        self.setupModel()
69
70        # # Set up the mapper
71        self.setupMapper()
72
73    def setupSlots(self):
74        self.closeButton.clicked.connect(self.close)
75
76        self.model.itemChanged.connect(self.modelChanged)
77
78    def setupModel(self):
79        self.model.setItem(W.NPTS, QtGui.QStandardItem(str(self.nfunc)))
80        self.model.setItem(W.DMIN,
81                           QtGui.QStandardItem(
82                               str(0.9*self.pr_state.d_max)))
83        self.model.setItem(W.DMAX,
84                           QtGui.QStandardItem(
85                               str(1.1*self.pr_state.d_max)))
86        self.model.setItem(W.VARIABLE,
87                           QtGui.QStandardItem( "χ²/dof"))
88
89    def setupMapper(self):
90        self.mapper = QtWidgets.QDataWidgetMapper(self)
91        self.mapper.setOrientation(QtCore.Qt.Vertical)
92        self.mapper.setModel(self.model)
93
94        self.mapper.addMapping(self.Npts, W.NPTS)
95        self.mapper.addMapping(self.minDist, W.DMIN)
96        self.mapper.addMapping(self.maxDist, W.DMAX)
97        self.mapper.addMapping(self.dependentVariable, W.VARIABLE)
98
99        self.mapper.toFirst()
100
101    def modelChanged(self, item):
102        if not self.mapper:
103            return
104
105        iq0 = []
106        rg = []
107        pos = []
108        pos_err = []
109        osc = []
110        bck = []
111        chi2 = []
112
113        xs = np.linspace(float(self.model.item(W.DMIN).text()),
114                         float(self.model.item(W.DMAX).text()),
115                         float(self.model.item(W.NPTS).text()))
116
117        original = self.pr_state.d_max
118        for x in xs:
119            self.pr_state.d_max = x
120            try:
121                out, cov = self.pr_state.invert(self.pr_state.nfunc)
122
123                iq0.append(self.pr_state.iq0(out))
124                rg.append(self.pr_state.rg(out))
125                pos.append(self.pr_state.get_positive(out))
126                pos_err.append(self.pr_state.get_pos_err(out, cov))
127                osc.append(self.pr_state.oscillations(out))
128                bck.append(self.pr_state.background)
129                chi2.append(self.pr_state.chi2)
130            except:
131                # This inversion failed, skip this D_max value
132                msg = "ExploreDialog: inversion failed "
133                msg += "for D_max=%s\n%s" % (str(x), sys.exc_info()[1])
134                print(msg)
135                # logger.error(msg)
136
137        #Return the invertor to its original state
138        self.pr_state.d_max = original
139        self.pr_state.invert(self.nfunc)
140
141        plotter = str(self.model.item(W.VARIABLE).text())
142        if plotter == "χ²/dof":
143            ys = chi2
144        elif plotter == "I(Q=0)":
145            ys = iq0
146        elif plotter == "Rg":
147            ys = rg
148        elif plotter == "Oscillation parameter":
149            ys = osc
150        elif plotter == "Background":
151            ys = bck
152        elif plotter == "Positive Fraction":
153            ys = pos
154        else:
155            ys = pos_err
156
157        data = Data1D(xs, ys)
158        if self.hasPlot:
159            self.plot.removePlot(None)
160        self.hasPlot = True
161        self.plot.plot(data=data, marker="-")
Note: See TracBrowser for help on using the repository browser.