Skip to content

Commit

Permalink
feat: initial support for ancillary parameters; fix: always display p…
Browse files Browse the repository at this point in the history
…arameter units
  • Loading branch information
paulmueller committed Jan 11, 2020
1 parent d80b13a commit 43d44a0
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 40 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
0.6.0
- feat: initial support for ancillary parameters
- fix: always display parameter units
0.5.7
- enh: allow to also set right part of fitting range individually
- fix: improve layout of FD fitting panel
Expand Down
100 changes: 75 additions & 25 deletions pyjibe/fd/tab_fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ def current_curve(self):
def fd(self):
return self.parent().parent().parent().parent()

@property
def fit_model(self):
return nmodel.get_model_by_name(self.cb_model.currentText())

def assert_parameter_table_rows(self, table, rows, cb_first=False):
"""Make sure a QTableWidget has enough rows
Expand All @@ -69,7 +73,13 @@ def assert_parameter_table_rows(self, table, rows, cb_first=False):
cb_first: bool
Set first column values as check-boxes.
(This is used for fixing fit parameters in PyJibe)
Returns
-------
rows_changed: bool
Whether or not the number of rows changed
"""
rows_changed = (table.rowCount() - rows) != 0
table.setRowCount(rows)
cols = table.columnCount()
for rr in range(rows):
Expand All @@ -80,8 +90,8 @@ def assert_parameter_table_rows(self, table, rows, cb_first=False):
if cc == 0 and cb_first:
item.setFlags(QtCore.Qt.ItemIsUserCheckable |
QtCore.Qt.ItemIsEnabled)
item.setCheckState(QtCore.Qt.Unchecked)
table.setItem(rr, cc, item)
return rows_changed

def fit_approach_retract(self, fdist, update_ui=True):
"""Perform preprocessing and fit data
Expand All @@ -102,8 +112,7 @@ def fit_approach_retract(self, fdist, update_ui=True):
# y axis
y_axis = self.cb_yaxis.currentText()
# Get model key from dropdown list
model = nmodel.get_model_by_name(self.cb_model.currentText())
model_key = model.model_key
model_key = self.fit_model.model_key
# Determine range type
if self.cb_range_type.currentText() == "absolute":
range_type = "absolute"
Expand Down Expand Up @@ -160,22 +169,27 @@ def fit_approach_retract(self, fdist, update_ui=True):
self.assert_parameter_table_rows(ftab, len(varps))
for ii, p in enumerate(varps):
# Get the human readable name of the parameter
name = model.parameter_keys.index(p.name)
hrnam = model.parameter_names[name]
name = self.fit_model.parameter_keys.index(p.name)
hrname = self.fit_model.parameter_names[name]
# SI unit
si_unit = self.fit_model.parameter_units[ii]
# Determine unit scale, e.g. 1e6 [sic] for µm
scale = units.hrscale(hrnam)
ftab.verticalHeaderItem(ii).setText(units.hrscname(hrnam))
ftab.item(ii, 0).setText("{:.3f}".format(p.value*scale))
scale = units.hrscale(hrname, si_unit=si_unit)
label = units.hrscname(hrname, si_unit=si_unit)
ftab.verticalHeaderItem(ii).setText(label)
ftab.item(ii, 0).setText("{:.5g}".format(p.value*scale))
else:
if update_ui:
inipar = fdist.fit_properties["params_initial"]
varps = [p[1] for p in inipar.items() if p[1].vary]
self.assert_parameter_table_rows(ftab, len(varps))
for ii, p in enumerate(varps):
# Get the human readable name of the parameter
name = model.parameter_keys.index(p.name)
hrnam = model.parameter_names[name]
ftab.verticalHeaderItem(ii).setText(units.hrscname(hrnam))
name = self.fit_model.parameter_keys.index(p.name)
hrname = self.fit_model.parameter_names[name]
si_unit = self.fit_model.parameter_units[ii]
label = units.hrscname(hrname, si_unit=si_unit)
ftab.verticalHeaderItem(ii).setText(label)
ftab.item(ii, 0).setText("nan")

def fit_parameters(self):
Expand All @@ -188,8 +202,7 @@ def fit_parameters(self):
updated.
"""
# Get model key from dropdown list
model = nmodel.get_model_by_name(self.cb_model.currentText())
model_key = model.model_key
model_key = self.fit_model.model_key
# Get parameters from `self.table_parameters_initial`
model = nmodel.models_available[model_key]
params = model.get_parameter_defaults()
Expand Down Expand Up @@ -219,12 +232,13 @@ def fit_parameters(self):
return params

def fit_update_parameters(self, fdist):
"""Update the initial and fitting parameters"""
model = nmodel.get_model_by_name(self.cb_model.currentText())
model_key = model.model_key
if ("params_initial" in fdist.fit_properties and
"model_key" in fdist.fit_properties and
fdist.fit_properties["model_key"] == model_key):
"""Update the ancillary and initial parameters"""
model_key = self.fit_model.model_key
# set the model
# - resets params_initial if model changed
# - important for computing ancillary parameters
fdist.fit_properties["model_key"] = model_key
if fdist.fit_properties.get("params_initial", False):
# set the parameters of the previous fit
params = fdist.fit_properties["params_initial"]
else:
Expand All @@ -243,16 +257,19 @@ def fit_update_parameters(self, fdist):
for ii, key in enumerate(list(params.keys())):
p = params[key]
# Get the human readable name of the parameter
hrname = model.parameter_names[ii]
hrname = self.fit_model.parameter_names[ii]
# SI unit
si_unit = self.fit_model.parameter_units[ii]
# Determine unit scale, e.g. 1e6 [sic] for µm
scale = units.hrscale(hrname)
itab.verticalHeaderItem(ii).setText(units.hrscname(hrname))
scale = units.hrscale(hrname, si_unit=si_unit)
label = units.hrscname(hrname, si_unit=si_unit)
itab.verticalHeaderItem(ii).setText(label)
if p.vary:
state = QtCore.Qt.Unchecked
else:
state = QtCore.Qt.Checked
itab.item(ii, 0).setCheckState(state)
itab.item(ii, 1).setText("{:.2f}".format(p.value*scale))
itab.item(ii, 1).setText("{:.5g}".format(p.value*scale))
itab.item(ii, 2).setText(str(p.min*scale))
itab.item(ii, 3).setText(str(p.max*scale))

Expand All @@ -267,6 +284,40 @@ def fit_update_parameters(self, fdist):
if self.cb_right_individ.isChecked() and right is not None:
self.sp_range_2.setValue(right)

# ancillaries
anc = fdist.get_ancillary_parameters(model_key=model_key)
anc_used = [ak for ak in anc if ak in self.fit_model.parameter_keys]
if anc_used:
self.widget_anc.setVisible(True)
atab = self.table_parameters_anc
atab.blockSignals(True)
rows_changed = self.assert_parameter_table_rows(atab,
len(anc_used),
cb_first=True)
row = 0
for ii, ak in enumerate(list(anc.keys())):
if ak not in anc_used:
continue
# Get the human readable name of the parameter
hrname = self.fit_model.parameter_anc_names[ii]
# Determine unit scale, e.g. 1e6 [sic] for µm
si_unit = self.fit_model.parameter_anc_units[ii]
# Determine unit scale, e.g. 1e6 [sic] for µm
scale = units.hrscale(hrname, si_unit=si_unit)
label = units.hrscname(hrname, si_unit=si_unit)
atab.verticalHeaderItem(row).setText(label)
if rows_changed:
atab.item(row, 0).setCheckState(QtCore.Qt.Checked)
atab.item(row, 1).setText("{:.5g}".format(anc[ak]*scale))
if atab.item(row, 0).checkState() == QtCore.Qt.Checked:
# update initial parameters
idx = self.fit_model.parameter_keys.index(ak)
itab.item(idx, 1).setText("{:.5g}".format(anc[ak]*scale))
row += 1
atab.blockSignals(False)
else:
self.widget_anc.setVisible(False)

def indentation_depth_setup(self):
"""Initiate ranges (spin/slider) that allow inf values"""
# Initialize individual indentation depth dictionary
Expand Down Expand Up @@ -365,8 +416,7 @@ def on_update_weights(self, on_params_init=True):
radio button.
"""
# First get the tip radius
model = nmodel.get_model_by_name(self.cb_model.currentText())
params = model.get_parameter_defaults()
params = self.fit_model.get_parameter_defaults()
itab = self.table_parameters_initial
for ii, key in enumerate(list(params.keys())):
if key == "R":
Expand Down
96 changes: 93 additions & 3 deletions pyjibe/fd/tab_fit.ui
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_13" stretch="0,0,0,0,0,0,0,0,0">
<layout class="QVBoxLayout" name="verticalLayout_13" stretch="0,0,0,0,0,0,0,0,0,0">
<property name="spacing">
<number>6</number>
</property>
Expand Down Expand Up @@ -519,6 +519,87 @@
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_anc" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Ancillaries:</string>
</property>
</widget>
</item>
<item>
<widget class="QTableWidget" name="table_parameters_anc">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="cornerButtonEnabled">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderCascadingSectionResizes">
<bool>true</bool>
</attribute>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>50</number>
</attribute>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>20</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderMinimumSectionSize">
<number>20</number>
</attribute>
<column>
<property name="text">
<string>use</string>
</property>
</column>
<column>
<property name="text">
<string>value</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label_11">
<property name="text">
Expand Down Expand Up @@ -568,7 +649,7 @@
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="textElideMode">
<enum>Qt::ElideLeft</enum>
Expand Down Expand Up @@ -678,12 +759,21 @@
<property name="autoScrollMargin">
<number>0</number>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="cornerButtonEnabled">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
Expand Down Expand Up @@ -751,7 +841,7 @@
<sender>cb_weight_cp</sender>
<signal>toggled(bool)</signal>
<receiver>widget_res_cp</receiver>
<slot>setEnabled(bool)</slot>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>148</x>
Expand Down
2 changes: 1 addition & 1 deletion pyjibe/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"fd": {
"suffixes": [f["suffix"] for f in formats_by_mode["force-distance"]],
"gui": fd.UiForceDistance,
}
}
}

known_suffixes = []
for _item in analysis_types.values():
Expand Down

0 comments on commit 43d44a0

Please sign in to comment.