Skip to content

Commit 87a119f

Browse files
committed
feat: add bulk Young's modulus computation
1 parent 7c60471 commit 87a119f

File tree

10 files changed

+550
-42
lines changed

10 files changed

+550
-42
lines changed

CHANGELOG

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
2.4.0
2+
- feat: allow to set Young's modulus parameters for all
3+
open datasets via the "Bulk Action" menu
4+
- fix: force temperature for Young's modulus computation
5+
to the value stored in the dataset for the "config"
6+
scenario
7+
- enh: update menu keybord shortcuts
18
2.3.0
29
- enh: added preferences dialog
310
- enh: improved user experience for searching DCOR data

shapeout2/gui/analysis/ana_slot.py

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,62 @@ def __setstate__(self, state):
164164
self.groupBox_fl_labels.setVisible(hasfl1 | hasfl2 | hasfl3)
165165
self.groupBox_fl_cross.setVisible(hasfl1 | hasfl2 | hasfl3)
166166

167+
@staticmethod
168+
def get_dataset_choices_medium(ds):
169+
"""Return the choices for the medium selection
170+
171+
Parameters
172+
----------
173+
ds: RTDCBase
174+
Dataset
175+
176+
Returns
177+
-------
178+
choices: list
179+
List of [title, identifier]
180+
"""
181+
if ds:
182+
medium = ds.config.get("setup", {}).get("medium", "").strip()
183+
if not medium: # empty medium string
184+
medium = "other"
185+
else:
186+
medium = "undefined"
187+
if medium in KNOWN_MEDIA:
188+
valid_media = [medium]
189+
else:
190+
valid_media = KNOWN_MEDIA + ["other", "undefined"]
191+
choices = []
192+
for vm in valid_media:
193+
if vm == "CellCarrierB":
194+
name = "CellCarrier B" # [sic]
195+
else:
196+
name = vm
197+
choices.append([name, medium])
198+
return choices
199+
200+
@staticmethod
201+
def get_dataset_choices_temperature(ds):
202+
"""Return the choices for the temperature selection
203+
204+
Parameters
205+
----------
206+
ds: RTDCBase
207+
Dataset
208+
209+
Returns
210+
-------
211+
choices: list
212+
List of [title, identifier]
213+
"""
214+
choices = []
215+
if ds is not None:
216+
if "temp" in ds:
217+
choices.append(["From feature", "feature"])
218+
if "temperature" in ds.config["setup"]:
219+
choices.append(["From meta data", "config"])
220+
choices.append(["Manual", "manual"])
221+
return choices
222+
167223
def _update_emodulus_medium_choices(self):
168224
"""update currently available medium choices for YM
169225
@@ -172,18 +228,9 @@ def _update_emodulus_medium_choices(self):
172228
self.comboBox_medium.blockSignals(True)
173229
self.comboBox_medium.clear()
174230
ds = self.get_dataset()
175-
choices = KNOWN_MEDIA + ["other"]
176-
if ds and "setup" in ds.config and "medium" in ds.config["setup"]:
177-
medium = ds.config["setup"]["medium"]
178-
if medium not in choices and medium.strip():
179-
choices.append(medium)
180-
for choice in choices:
181-
if choice == "CellCarrierB":
182-
name = "CellCarrier B" # [sic]
183-
else:
184-
name = choice
185-
self.comboBox_medium.addItem(name, choice)
186-
self.comboBox_medium.addItem("not defined", "undefined")
231+
choices = self.get_dataset_choices_medium(ds)
232+
for name, data in choices:
233+
self.comboBox_medium.addItem(name, data)
187234
self.comboBox_medium.blockSignals(False)
188235

189236
def _update_emodulus_temp_choices(self):
@@ -195,12 +242,9 @@ def _update_emodulus_temp_choices(self):
195242
cursel = self.comboBox_temp.currentData()
196243
self.comboBox_temp.clear()
197244
ds = self.get_dataset()
198-
if ds is not None:
199-
if "temp" in ds:
200-
self.comboBox_temp.addItem("From feature", "feature")
201-
if "temperature" in ds.config["setup"]:
202-
self.comboBox_temp.addItem("From meta data", "config")
203-
self.comboBox_temp.addItem("Manual", "manual")
245+
choices = self.get_dataset_choices_temperature(ds)
246+
for name, data in choices:
247+
self.comboBox_temp.addItem(name, data)
204248
idx = self.comboBox_temp.findData(cursel)
205249
self.comboBox_temp.setCurrentIndex(idx)
206250
self.comboBox_temp.blockSignals(False)

shapeout2/gui/compute/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
from .comp_stats import ComputeStatistics # noqa: F401
1+
# flake8: noqa: F401
2+
from .comp_emodulus import ComputeEmodulus
3+
from .comp_stats import ComputeStatistics
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import pkg_resources
2+
3+
from dclab.features.emodulus.viscosity import KNOWN_MEDIA
4+
5+
from PyQt5 import uic, QtCore, QtGui, QtWidgets
6+
7+
from ..analysis.ana_slot import SlotPanel
8+
from ..widgets import show_wait_cursor
9+
10+
11+
class ComputeEmodulus(QtWidgets.QDialog):
12+
#: Emitted when the pipeline is to be changed
13+
pipeline_changed = QtCore.pyqtSignal(dict)
14+
15+
def __init__(self, parent, pipeline, *args, **kwargs):
16+
QtWidgets.QWidget.__init__(self, parent, *args, **kwargs)
17+
path_ui = pkg_resources.resource_filename(
18+
"shapeout2.gui.compute", "comp_emodulus.ui")
19+
uic.loadUi(path_ui, self)
20+
# main
21+
self.parent = self.parent
22+
23+
# set pipeline
24+
self.pipeline = pipeline
25+
26+
# ui choices
27+
self.comboBox_medium.clear()
28+
choices = KNOWN_MEDIA + ["other"]
29+
for choice in choices:
30+
if choice == "CellCarrierB":
31+
name = "CellCarrier B" # [sic]
32+
else:
33+
name = choice
34+
self.comboBox_medium.addItem(name, choice)
35+
self.comboBox_medium.addItem("not defined", "undefined")
36+
self.comboBox_medium.addItem("unchanged", "unchanged")
37+
self.comboBox_medium.currentIndexChanged.connect(self.on_cb_medium)
38+
self.comboBox_medium.setCurrentIndex(self.comboBox_medium.count()-1)
39+
40+
self.comboBox_temp.clear()
41+
self.comboBox_temp.addItem("From feature", "feature")
42+
self.comboBox_temp.addItem("From meta data", "config")
43+
self.comboBox_temp.addItem("Manual", "manual")
44+
self.comboBox_temp.currentIndexChanged.connect(self.on_cb_temp)
45+
self.comboBox_temp.setCurrentIndex(self.comboBox_temp.count()-1)
46+
47+
# buttons
48+
btn_ok = self.buttonBox.button(QtGui.QDialogButtonBox.Ok)
49+
btn_ok.clicked.connect(self.on_ok)
50+
btn_cancel = self.buttonBox.button(QtGui.QDialogButtonBox.Cancel)
51+
btn_cancel.clicked.connect(self.on_cancel)
52+
53+
@QtCore.pyqtSlot()
54+
def on_cancel(self):
55+
self.close()
56+
57+
@QtCore.pyqtSlot()
58+
def on_ok(self):
59+
self.set_emodulus_properties()
60+
self.update_ui()
61+
62+
def on_cb_medium(self):
63+
"""User changed medium"""
64+
medium = self.comboBox_medium.currentData()
65+
if medium in KNOWN_MEDIA + ["unchanged"]:
66+
self.doubleSpinBox_visc.setEnabled(False)
67+
self.comboBox_temp.setEnabled(True)
68+
else:
69+
self.doubleSpinBox_visc.setEnabled(True)
70+
self.comboBox_temp.setEnabled(False)
71+
self.on_cb_temp()
72+
73+
def on_cb_temp(self):
74+
"""User changed temperature"""
75+
temp = self.comboBox_temp.currentData()
76+
77+
if not self.comboBox_temp.isEnabled() or temp in ["feature", "config"]:
78+
self.doubleSpinBox_temp.setEnabled(False)
79+
else:
80+
self.doubleSpinBox_temp.setEnabled(True)
81+
82+
@show_wait_cursor
83+
@QtCore.pyqtSlot()
84+
def set_emodulus_properties(self):
85+
"""Set the given emodulus properties for all datasets"""
86+
medium = self.comboBox_medium.currentData()
87+
if self.comboBox_temp.isEnabled():
88+
temp = self.comboBox_temp.currentData()
89+
else:
90+
temp = None
91+
if self.doubleSpinBox_temp.isEnabled():
92+
tempval = self.doubleSpinBox_temp.value()
93+
else:
94+
tempval = None
95+
if self.doubleSpinBox_visc.isEnabled():
96+
viscval = self.doubleSpinBox_visc.value()
97+
else:
98+
viscval = None
99+
100+
if len(self.pipeline.slots) == 0:
101+
return
102+
103+
for slot in self.pipeline.slots:
104+
ds = slot.get_dataset()
105+
106+
# Use the internal sanity checks to determine whether
107+
# or not we can set the medium or temperature scenarios.
108+
choices_medium = SlotPanel.get_dataset_choices_medium(ds)
109+
choices_temp = SlotPanel.get_dataset_choices_temperature(ds)
110+
if medium in [m[1] for m in choices_medium]:
111+
state = slot.__getstate__()
112+
state["emodulus"]["emodulus medium"] = medium
113+
slot.__setstate__(state)
114+
115+
# Set the viscosity here, because unknown media are
116+
# available.
117+
if viscval is not None:
118+
state["emodulus"]["emodulus viscosity"] = viscval
119+
120+
if temp in [t[1] for t in choices_temp]: # temp is not None
121+
state = slot.__getstate__()
122+
state["emodulus"]["emodulus scenario"] = temp
123+
if tempval is not None:
124+
state["emodulus"]["emodulus temperature"] = tempval
125+
slot.__setstate__(state)
126+
127+
print(state["emodulus"])
128+
129+
def update_ui(self):
130+
"""Update all relevant parts of the main user interface"""
131+
state = self.pipeline.__getstate__()
132+
self.pipeline_changed.emit(state)

0 commit comments

Comments
 (0)