Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retain native units on data load #1802

Closed
wants to merge 48 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
368d6d6
Complete refactor of the nxsunit including adding inverse, inverse sq…
krzywon Feb 26, 2021
f07992f
Update nxsunit for specific values, write unit tests for nxsunit, an…
krzywon Feb 26, 2021
0790d92
Store default units in DataInfo and add helper methods to get/fetch them
krzywon Feb 26, 2021
a078984
Fix various issues with loaded units and update unit tests to match e…
krzywon Mar 2, 2021
33dbb4b
Allow scale and unit shifts in plots.
krzywon Mar 3, 2021
a72f16e
Add context menu item to data explorer to change units for as-loaded …
krzywon Mar 3, 2021
83737be
Dynamically update invariant GUI with data units when data is loaded.
krzywon Mar 3, 2021
670695d
Revert dynamic invariant update changes.
krzywon Mar 4, 2021
4f906ac
Generate metric inverse and inverse squared units. Update unit test t…
krzywon Mar 4, 2021
5cc796f
Convert units to sasview native units before sending to perspective a…
krzywon Mar 4, 2021
9402f1a
Set units for fits to the same as data, add metric ^-3 units, and upd…
krzywon Mar 8, 2021
7c6ab22
Move UnitPropertiesUI.ui to Utilities, add unit tests for new window,…
krzywon Mar 9, 2021
a7a77b1
Apply unit changes to 2D data sets and generalize GUI elements to be …
krzywon Mar 10, 2021
c58fe81
Remove unused code, change order of operations in some readers, and u…
krzywon Mar 10, 2021
5909e4d
Move onUnitsChange to PlotterBase to remove code duplication
krzywon May 20, 2021
b5af04c
Add default loading and plotting unit options to File menu GUI elemen…
krzywon May 24, 2021
8e7d3ec
Merge main into retain-units
krzywon Aug 11, 2021
d8c1da5
Format asterisk usage in <prefix>*<unit> unit string before <unit>*<u…
krzywon Aug 12, 2021
983c55c
File menu options for loaded and plotted units should start empty for…
krzywon Aug 12, 2021
86bc0b2
Create a separate preferences panel and move the unit menu items into…
krzywon Aug 24, 2021
5f99ce1
Populate combo boxes for plotting and data loading widgets and create…
krzywon Aug 26, 2021
2994682
Link plotting logic to plotting preferences so new plots always use u…
krzywon Aug 27, 2021
32c7884
Create logic when data type changes for loaded data sets
krzywon Aug 27, 2021
7504020
Tie data loader into custom_config.py to use default units on loading…
krzywon Aug 28, 2021
2136d78
Code cleanup in PreferencesPanel.py to minimize code duplication and …
krzywon Aug 28, 2021
58d4651
Allow user to override any I and Q units, regardless of what is found…
krzywon Aug 28, 2021
21fab1f
Give user the option to plot using as-loaded units and set this optio…
krzywon Aug 28, 2021
bf613a9
Add class, method, and inline documentation to data_info.py, PlotterB…
krzywon Aug 28, 2021
40f8696
Use proper classes for assertion statement
krzywon Aug 30, 2021
052a7c4
More documentation
krzywon Aug 30, 2021
76babf7
Collapse all multi-dimensional unit conversion methods into a single …
krzywon Aug 30, 2021
5735687
Implement a way to restore all default parameters within PreferencesP…
krzywon Aug 31, 2021
d2d3c6f
Remove unit conversion method from cansas_reader.py and update unit t…
krzywon Sep 1, 2021
e84a544
Save all preferences to custom config when PreferencesPanel.py closes…
krzywon Sep 1, 2021
3edc57d
Predefine all new custom config values in custom_config.py. Create pr…
krzywon Sep 1, 2021
0561ccc
Unit tests for preferences panel, but not complete yet
krzywon Sep 1, 2021
dd6e75f
Remove custom_config.py file generated by tests
krzywon Sep 3, 2021
321e0d9
Fix failing unit tests in utilitiesSuite
krzywon Sep 3, 2021
34aea4f
Merge main into retain-units
krzywon Sep 10, 2021
62212ab
Fix failing canSAS XML unit test.
krzywon Sep 10, 2021
3dca50a
Shrink preferences panel ListWidget to give more room for the Stacked…
krzywon Sep 10, 2021
4853b68
Fix 2D loading and unit change issues found in testing
krzywon Sep 14, 2021
8bcd340
Update PreferencesPanelTest.py to restore default preferences on tear…
krzywon Sep 14, 2021
26cabd8
Unit tests for plotting and unit changes
krzywon Sep 15, 2021
09c5ed9
Fixes related to units and found during unit testing
krzywon Sep 15, 2021
387ea8d
Update preferences panel tool tips to better match functionality
krzywon Sep 16, 2021
1f5126c
Remove unneeded calls to set_loaded_units
krzywon Oct 27, 2021
083e7c0
Merge branch 'main' into retain-units
krzywon Oct 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/sas/qtgui/GUITests.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@
from Utilities.UnitTesting import AddMultEditorTest
from Utilities.UnitTesting import ReportDialogTest
from Utilities.UnitTesting import FileConverterTest
from Utilities.UnitTesting import UnitPropertiesTest
from Utilities.UnitTesting import PreferencesPanelTest

# Unit Testing
from UnitTesting import TestUtilsTest
Expand Down Expand Up @@ -153,6 +155,8 @@ def utilitiesSuite():
unittest.makeSuite(AddMultEditorTest.AddMultEditorTest, 'test'),
unittest.makeSuite(ReportDialogTest.ReportDialogTest, 'test'),
unittest.makeSuite(FileConverterTest.FileConverterTest, 'test'),
unittest.makeSuite(UnitPropertiesTest.UnitPropertiesTest, 'test'),
unittest.makeSuite(PreferencesPanelTest.PreferencesPanelTest, 'test'),
)
return unittest.TestSuite(suites)

Expand Down
49 changes: 46 additions & 3 deletions src/sas/qtgui/MainWindow/DataExplorer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

# QTGUI
import sas.qtgui.Utilities.GuiUtils as GuiUtils
from sas.qtgui.Utilities.UnitChange import UnitChange
import sas.qtgui.Plotting.PlotHelper as PlotHelper

from sas.qtgui.Plotting.PlotterData import Data1D
Expand Down Expand Up @@ -757,9 +758,8 @@ def isItemReady(index):
return item.isCheckable() and item.checkState() == QtCore.Qt.Checked

# Figure out which rows are checked
selected_items = [self.model.item(index)
for index in range(self.model.rowCount())
if isItemReady(index)]
selected_items = [self.convert_to_calculator_units(self.model.item(index))
for index in range(self.model.rowCount()) if isItemReady(index)]

if len(selected_items) < 1:
return
Expand Down Expand Up @@ -793,6 +793,30 @@ def isItemReady(index):
msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok)
_ = msgbox.exec_()

def convert_to_calculator_units(self, qtGuiStdItem):
# type: (QStandardItem) -> QStandardItem
"""Convert data from as-loaded data units to sasmodels compatible units

:param qtGuiStdItem: A QStandardItem that is selected for analysis
:return: A QStandardItem where an attempt was made to convert the data to units used in calculations.
"""
data = GuiUtils.dataFromItem(qtGuiStdItem)
try:
data.convert_q_units('1/A')
except KeyError:
msg = f"Unable to convert Q units to native {self._perspective().name} units of A^-1:"
msg += f" Parameters will be in units relative to the data Q units {data.x_unit}"
logger.warning(msg)
try:
data.convert_i_units('1/cm')
except KeyError:
unit = data.z_unit if isinstance(data, Data2D) else data.y_unit
msg = f"Unable to convert I units to native {self._perspective().name} units of cm^-1:"
msg += f" Parameters will be in units relative to the data Q units {unit}"
logger.warning(msg)
qtGuiStdItem.setData(data)
return qtGuiStdItem

def sendItemToPerspective(self, item, tab_index=None):
"""
Send the passed item data to the current perspective and set the relevant notifiers
Expand Down Expand Up @@ -1475,6 +1499,7 @@ def contextMenu(self):
self.context_menu.addAction(self.actionDeselect)
self.context_menu.addSeparator()
self.context_menu.addAction(self.actionChangeName)
self.context_menu.addAction(self.actionSelectUnits)
self.context_menu.addAction(self.actionDataInfo)
self.context_menu.addAction(self.actionSaveAs)
self.context_menu.addAction(self.actionQuickPlot)
Expand All @@ -1490,6 +1515,7 @@ def contextMenu(self):
self.actionSelect.triggered.connect(self.onFileListSelected)
self.actionDeselect.triggered.connect(self.onFileListDeselected)
self.actionChangeName.triggered.connect(self.changeName)
self.actionSelectUnits.triggered.connect(self.changeUnits)
self.actionDataInfo.triggered.connect(self.showDataInfo)
self.actionSaveAs.triggered.connect(self.saveDataAs)
self.actionQuickPlot.triggered.connect(self.quickDataPlot)
Expand Down Expand Up @@ -1556,6 +1582,23 @@ def changeName(self):
# Open the window
self.nameChangeBox.show()

def changeUnits(self):
"""
Show a dialog allowing unit conversions for each axis
"""
# Create the Unit conversion dialog on the fly
index = self.current_view.selectedIndexes()[0]
proxy = self.current_view.model()
model = proxy.sourceModel()
# Get the model item and update the name change box
model_item = model.itemFromIndex(proxy.mapToSource(index))
data = GuiUtils.dataFromItem(model_item)
self.units = UnitChange(self, [data])
if self.units.exec_() == QtWidgets.QDialog.Accepted:
data.convert_q_units(self.units.cbX.currentText())
data.convert_i_units(self.units.cbY.currentText())
model_item.data = data

def showDataInfo(self):
"""
Show a simple read-only text edit with data information.
Expand Down
6 changes: 6 additions & 0 deletions src/sas/qtgui/MainWindow/GuiManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from sas.qtgui.Utilities.ResultPanel import ResultPanel

from sas.qtgui.Utilities.ReportDialog import ReportDialog
from sas.qtgui.Utilities.PreferencesPanel import PreferencesPanel
from sas.qtgui.MainWindow.Acknowledgements import Acknowledgements
from sas.qtgui.MainWindow.AboutBox import AboutBox
from sas.qtgui.MainWindow.WelcomePanel import WelcomePanel
Expand Down Expand Up @@ -156,6 +157,7 @@ def addWidgets(self):
self.ackWidget = Acknowledgements()
self.aboutWidget = AboutBox()
self.categoryManagerWidget = CategoryManager(self._parent, manager=self)
self.preferences = PreferencesPanel(self._parent)

self.grid_window = None
self.grid_window = BatchOutputPanel(parent=self)
Expand Down Expand Up @@ -577,6 +579,7 @@ def addTriggers(self):
self._workspace.actionOpen_Analysis.triggered.connect(self.actionOpen_Analysis)
self._workspace.actionSave.triggered.connect(self.actionSave_Project)
self._workspace.actionSave_Analysis.triggered.connect(self.actionSave_Analysis)
self._workspace.actionPreferences.triggered.connect(self.actionOpen_Preferences)
self._workspace.actionQuit.triggered.connect(self.actionQuit)
# Edit
self._workspace.actionUndo.triggered.connect(self.actionUndo)
Expand Down Expand Up @@ -727,6 +730,9 @@ def actionSave_Analysis(self):
else:
logger.warning('No analysis was available to be saved.')

def actionOpen_Preferences(self):
self.preferences.show()

def actionQuit(self):
"""
Close the reactor, exit the application.
Expand Down
8 changes: 8 additions & 0 deletions src/sas/qtgui/MainWindow/UI/DataExplorerUI.ui
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,14 @@
<string>Change Display Name</string>
</property>
</action>
<action name="actionSelectUnits">
<property name="text">
<string>Change Units</string>
</property>
<property name="toolTip">
<string>Change X and Y units for this data set</string>
</property>
</action>
</widget>
<resources/>
<connections/>
Expand Down
43 changes: 27 additions & 16 deletions src/sas/qtgui/MainWindow/UI/MainWindowUI.ui
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,9 @@
<x>0</x>
<y>0</y>
<width>915</width>
<height>26</height>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
<property name="title">
<string>&amp;File</string>
</property>
<addaction name="actionLoadData"/>
<addaction name="actionLoad_Data_Folder"/>
<addaction name="separator"/>
<addaction name="actionOpen_Project"/>
<addaction name="actionOpen_Analysis"/>
<addaction name="separator"/>
<addaction name="actionSave"/>
<addaction name="actionSave_Analysis"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
</widget>
<widget class="QMenu" name="menuEdit">
<property name="title">
<string>Edit</string>
Expand Down Expand Up @@ -156,6 +141,23 @@
<addaction name="separator"/>
<addaction name="actionCheck_for_update"/>
</widget>
<widget class="QMenu" name="menu_File">
<property name="title">
<string>&amp;File</string>
</property>
<addaction name="actionLoadData"/>
<addaction name="actionLoad_Data_Folder"/>
<addaction name="separator"/>
<addaction name="actionOpen_Project"/>
<addaction name="actionOpen_Analysis"/>
<addaction name="separator"/>
<addaction name="actionSave"/>
<addaction name="actionSave_Analysis"/>
<addaction name="separator"/>
<addaction name="actionPreferences"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
</widget>
<addaction name="menu_File"/>
<addaction name="menuEdit"/>
<addaction name="menuView"/>
Expand Down Expand Up @@ -607,6 +609,15 @@
<string>Model Marketplace</string>
</property>
</action>
<action name="actionPreferences">
<property name="icon">
<iconset>
<normaloff>:/res/settings.png</normaloff>:/res/settings.png</iconset>
</property>
<property name="text">
<string>Preferences...</string>
</property>
</action>
</widget>
<resources/>
<connections/>
Expand Down
4 changes: 2 additions & 2 deletions src/sas/qtgui/Perspectives/Corfunc/CorfuncPerspective.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ def draw_q_space(self):
self.axes = self.fig.add_subplot(111)
self.axes.set_xscale("log")
self.axes.set_yscale("log")
self.axes.set_xlabel("Q [$\AA^{-1}$]")
self.axes.set_ylabel("I(Q) [cm$^{-1}$]")
self.axes.set_xlabel(f"Q [${self.data.x_unit}$]")
self.axes.set_ylabel(f"I(Q) [${self.data.y_unit}$]")
self.axes.set_title("Scattering data")
self.fig.tight_layout()

Expand Down
8 changes: 7 additions & 1 deletion src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from sas.sascalc.fit.BumpsFitting import BumpsFit as Fit
from sas.sascalc.fit.pagestate import PageState
from sas.sascalc.fit import models
from sas.sascalc.dataloader.data_info import set_loaded_units

import sas.qtgui.Utilities.GuiUtils as GuiUtils
import sas.qtgui.Utilities.LocalConfig as LocalConfig
Expand Down Expand Up @@ -2946,6 +2947,10 @@ def complete1D(self, return_data):
self.enableInteractiveElements()
if return_data is None:
return
set_loaded_units(return_data['data'], 'x', self.data.x_loaded_unit)
set_loaded_units(return_data['data'], 'y', self.data.y_loaded_unit)
if isinstance(self.data, Data2D):
set_loaded_units(return_data['data'], 'z', self.data.z_loaded_unit)
fitted_data = self.logic.new1DPlot(return_data, self.tab_id)

# Fits of Sesans data are in real space
Expand Down Expand Up @@ -3011,7 +3016,8 @@ def complete2D(self, return_data):

if return_data is None:
return

if hasattr(return_data['data'], 'convert_to_native_units'):
return_data['data'].convert_to_native_units()
fitted_data = self.logic.new2DPlot(return_data)
# assure the current index is set properly for batch
if len(self._logic) > 1:
Expand Down
5 changes: 5 additions & 0 deletions src/sas/qtgui/Perspectives/Invariant/InvariantPerspective.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from twisted.internet import reactor

# sas-global
from sas.sascalc.dataloader.data_info import set_loaded_units
from sas.sascalc.invariant import invariant
from sas.qtgui.Plotting.PlotterData import Data1D
import sas.qtgui.Utilities.GuiUtils as GuiUtils
Expand Down Expand Up @@ -439,6 +440,8 @@ def calculateThread(self, extrapolation):
title = f"Low-Q extrapolation [{self._data.name}]"

# Convert the data into plottable
set_loaded_units(extrapolated_data, 'x', self._data.x_loaded_unit)
set_loaded_units(extrapolated_data, 'y', self._data.y_loaded_unit)
self.low_extrapolation_plot = self._manager.createGuiData(extrapolated_data)

self.low_extrapolation_plot.name = title
Expand Down Expand Up @@ -468,6 +471,8 @@ def calculateThread(self, extrapolation):
title = f"High-Q extrapolation [{self._data.name}]"

# Convert the data into plottable
set_loaded_units(high_out_data, 'x', self.data.x_loaded_unit)
set_loaded_units(high_out_data, 'y', self.data.y_loaded_unit)
self.high_extrapolation_plot = self._manager.createGuiData(high_out_data)
self.high_extrapolation_plot.name = title
self.high_extrapolation_plot.title = title
Expand Down
7 changes: 3 additions & 4 deletions src/sas/qtgui/Perspectives/Inversion/InversionLogic.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logging
import numpy as np

from sas.sascalc.dataloader.data_info import set_loaded_units
from sas.qtgui.Plotting.PlotterData import Data1D

PR_FIT_LABEL = r"$P_{fit}(r)$"
Expand Down Expand Up @@ -73,8 +74,8 @@ def new1DPlot(self, out, pr, q=None):

new_plot = Data1D(x, y)
new_plot.name = IQ_FIT_LABEL + f"[{self._data.name}]"
new_plot.xaxis("\\rm{Q}", 'A^{-1}')
new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")
set_loaded_units(new_plot, 'x', self._data.x_loaded_unit)
set_loaded_units(new_plot, 'y', self._data.y_loaded_unit)
title = "I(q)"
new_plot.title = title

Expand All @@ -98,8 +99,6 @@ def new1DPlot(self, out, pr, q=None):

new_plot = Data1D(x, y)
new_plot.name = IQ_SMEARED_LABEL
new_plot.xaxis("\\rm{Q}", 'A^{-1}')
new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")
# If we have a group ID, use it
if 'plot_group_id' in pr.info:
new_plot.group_id = pr.info["plot_group_id"]
Expand Down
Loading