-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: rudimentary LMM analysis (#55)
- Loading branch information
1 parent
eba19bf
commit 79c659b
Showing
13 changed files
with
1,017 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
# flake8: noqa: F401 | ||
from .comp_lme4 import ComputeSignificance | ||
from .comp_stats import ComputeStatistics |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import pkg_resources | ||
import webbrowser | ||
|
||
from dclab import lme4 | ||
from PyQt5 import uic, QtCore, QtGui, QtWidgets | ||
|
||
from .comp_lme4_dataset import LME4Dataset | ||
from .comp_lme4_results import Rlme4ResultsDialog | ||
|
||
|
||
class ComputeSignificance(QtWidgets.QDialog): | ||
def __init__(self, parent, pipeline, *args, **kwargs): | ||
super(ComputeSignificance, self).__init__(parent, *args, **kwargs) | ||
path_ui = pkg_resources.resource_filename( | ||
"shapeout2.gui.compute", "comp_lme4.ui") | ||
uic.loadUi(path_ui, self) | ||
# set pipeline | ||
self.pipeline = pipeline | ||
|
||
# populate feature combo box | ||
feats, labs = pipeline.get_features(scalar=True, label_sort=True, | ||
union=False, ret_labels=True) | ||
for feat, lab in zip(feats, labs): | ||
self.comboBox_feat.addItem(lab, feat) | ||
|
||
# populate datasets | ||
self.datasets = [] | ||
for slot in self.pipeline.slots: | ||
dw = LME4Dataset(self, slot=slot) | ||
self.dataset_layout.addWidget(dw) | ||
self.datasets.append(dw) | ||
spacer = QtWidgets.QSpacerItem(20, 0, | ||
QtWidgets.QSizePolicy.Minimum, | ||
QtWidgets.QSizePolicy.Expanding) | ||
self.dataset_layout.addItem(spacer) | ||
self.update() | ||
|
||
# button signals | ||
btn_close = self.buttonBox.button(QtGui.QDialogButtonBox.Close) | ||
btn_close.clicked.connect(self.on_close) | ||
btn_close.setToolTip("Close this dialog") | ||
closeicon = QtGui.QIcon.fromTheme("dialog-close") | ||
btn_close.setIcon(closeicon) | ||
btn_openlme4 = self.buttonBox.button(QtGui.QDialogButtonBox.Apply) | ||
btn_openlme4.clicked.connect(self.on_lme4) | ||
btn_openlme4.setToolTip("Perform lme4 analysis") | ||
btn_openlme4.setText("Run R-lme4") | ||
picon = QtGui.QIcon.fromTheme("rlang") | ||
btn_openlme4.setIcon(picon) | ||
btn_help = self.buttonBox.button(QtGui.QDialogButtonBox.Help) | ||
btn_help.clicked.connect(self.on_help) | ||
btn_help.setToolTip("View R-lme4 Quick Guide online") | ||
helpicon = QtGui.QIcon.fromTheme("documentinfo") | ||
btn_help.setIcon(helpicon) | ||
|
||
@property | ||
def feature(self): | ||
return self.comboBox_feat.currentData() | ||
|
||
@property | ||
def model(self): | ||
if self.radioButton_lmer.isChecked(): | ||
return "lmer" | ||
else: | ||
return "glmer+loglink" | ||
|
||
@QtCore.pyqtSlot() | ||
def on_lme4(self): | ||
"""Run lme4 analysis""" | ||
rlme4 = lme4.Rlme4(model=self.model, feature=self.feature) | ||
for wds in self.datasets: | ||
wds.add_to_rlme4(self.pipeline, rlme4) | ||
result = rlme4.fit() | ||
dlg = Rlme4ResultsDialog(self, result) | ||
dlg.exec_() | ||
|
||
@QtCore.pyqtSlot() | ||
def on_close(self): | ||
"""Close window""" | ||
self.close() | ||
|
||
@QtCore.pyqtSlot() | ||
def on_help(self): | ||
"""Show Shape-Out 2 docs""" | ||
webbrowser.open( | ||
"https://dclab.readthedocs.io/en/stable/sec_av_lme4.html") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ui version="4.0"> | ||
<class>Dialog</class> | ||
<widget class="QDialog" name="Dialog"> | ||
<property name="geometry"> | ||
<rect> | ||
<x>0</x> | ||
<y>0</y> | ||
<width>593</width> | ||
<height>544</height> | ||
</rect> | ||
</property> | ||
<property name="windowTitle"> | ||
<string>Compute statistical significance with R-lme4</string> | ||
</property> | ||
<property name="windowIcon"> | ||
<iconset theme="statistical_significance"> | ||
<normaloff>../../../../../.designer/backup</normaloff>../../../../../.designer/backup</iconset> | ||
</property> | ||
<layout class="QVBoxLayout" name="verticalLayout_3"> | ||
<item> | ||
<widget class="QLabel" name="label"> | ||
<property name="text"> | ||
<string>Compute the statistical significance using linear mixed-effects models</string> | ||
</property> | ||
</widget> | ||
</item> | ||
<item> | ||
<layout class="QHBoxLayout" name="horizontalLayout_2"> | ||
<item> | ||
<widget class="QLabel" name="label_2"> | ||
<property name="text"> | ||
<string>Model:</string> | ||
</property> | ||
</widget> | ||
</item> | ||
<item> | ||
<widget class="QRadioButton" name="radioButton_lmer"> | ||
<property name="toolTip"> | ||
<string>linear mixed-effects model</string> | ||
</property> | ||
<property name="text"> | ||
<string>lmer</string> | ||
</property> | ||
<property name="checked"> | ||
<bool>true</bool> | ||
</property> | ||
</widget> | ||
</item> | ||
<item> | ||
<widget class="QRadioButton" name="radioButton_glmer"> | ||
<property name="toolTip"> | ||
<string>generalized linear mixed-effects model with a log-link function</string> | ||
</property> | ||
<property name="text"> | ||
<string>glmer+loglink</string> | ||
</property> | ||
</widget> | ||
</item> | ||
<item> | ||
<spacer name="horizontalSpacer"> | ||
<property name="orientation"> | ||
<enum>Qt::Horizontal</enum> | ||
</property> | ||
<property name="sizeHint" stdset="0"> | ||
<size> | ||
<width>40</width> | ||
<height>20</height> | ||
</size> | ||
</property> | ||
</spacer> | ||
</item> | ||
</layout> | ||
</item> | ||
<item> | ||
<layout class="QHBoxLayout" name="horizontalLayout_3"> | ||
<item> | ||
<widget class="QLabel" name="label_3"> | ||
<property name="text"> | ||
<string>Feature:</string> | ||
</property> | ||
</widget> | ||
</item> | ||
<item> | ||
<widget class="QComboBox" name="comboBox_feat"> | ||
<property name="sizePolicy"> | ||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> | ||
<horstretch>0</horstretch> | ||
<verstretch>0</verstretch> | ||
</sizepolicy> | ||
</property> | ||
</widget> | ||
</item> | ||
<item> | ||
<spacer name="horizontalSpacer_2"> | ||
<property name="orientation"> | ||
<enum>Qt::Horizontal</enum> | ||
</property> | ||
<property name="sizeHint" stdset="0"> | ||
<size> | ||
<width>40</width> | ||
<height>20</height> | ||
</size> | ||
</property> | ||
</spacer> | ||
</item> | ||
</layout> | ||
</item> | ||
<item> | ||
<widget class="QLabel" name="label_4"> | ||
<property name="text"> | ||
<string>Datasets:</string> | ||
</property> | ||
</widget> | ||
</item> | ||
<item> | ||
<widget class="QScrollArea" name="scrollArea"> | ||
<property name="horizontalScrollBarPolicy"> | ||
<enum>Qt::ScrollBarAlwaysOff</enum> | ||
</property> | ||
<property name="sizeAdjustPolicy"> | ||
<enum>QAbstractScrollArea::AdjustToContents</enum> | ||
</property> | ||
<property name="widgetResizable"> | ||
<bool>true</bool> | ||
</property> | ||
<widget class="QWidget" name="scrollAreaWidgetContents"> | ||
<property name="geometry"> | ||
<rect> | ||
<x>0</x> | ||
<y>0</y> | ||
<width>573</width> | ||
<height>383</height> | ||
</rect> | ||
</property> | ||
<layout class="QVBoxLayout" name="verticalLayout_4"> | ||
<item> | ||
<layout class="QVBoxLayout" name="dataset_layout"/> | ||
</item> | ||
</layout> | ||
</widget> | ||
</widget> | ||
</item> | ||
<item> | ||
<widget class="QDialogButtonBox" name="buttonBox"> | ||
<property name="orientation"> | ||
<enum>Qt::Horizontal</enum> | ||
</property> | ||
<property name="standardButtons"> | ||
<set>QDialogButtonBox::Apply|QDialogButtonBox::Close|QDialogButtonBox::Help</set> | ||
</property> | ||
<property name="centerButtons"> | ||
<bool>false</bool> | ||
</property> | ||
</widget> | ||
</item> | ||
</layout> | ||
</widget> | ||
<resources/> | ||
<connections> | ||
<connection> | ||
<sender>buttonBox</sender> | ||
<signal>accepted()</signal> | ||
<receiver>Dialog</receiver> | ||
<slot>accept()</slot> | ||
<hints> | ||
<hint type="sourcelabel"> | ||
<x>248</x> | ||
<y>254</y> | ||
</hint> | ||
<hint type="destinationlabel"> | ||
<x>157</x> | ||
<y>274</y> | ||
</hint> | ||
</hints> | ||
</connection> | ||
<connection> | ||
<sender>buttonBox</sender> | ||
<signal>rejected()</signal> | ||
<receiver>Dialog</receiver> | ||
<slot>reject()</slot> | ||
<hints> | ||
<hint type="sourcelabel"> | ||
<x>316</x> | ||
<y>260</y> | ||
</hint> | ||
<hint type="destinationlabel"> | ||
<x>286</x> | ||
<y>274</y> | ||
</hint> | ||
</hints> | ||
</connection> | ||
</connections> | ||
</ui> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import pkg_resources | ||
|
||
from PyQt5 import uic, QtGui, QtWidgets | ||
|
||
from ... import meta_tool | ||
|
||
|
||
class LME4Dataset(QtWidgets.QDialog): | ||
def __init__(self, parent, slot, *args, **kwargs): | ||
super(LME4Dataset, self).__init__(parent, *args, **kwargs) | ||
path_ui = pkg_resources.resource_filename( | ||
"shapeout2.gui.compute", "comp_lme4_dataset.ui") | ||
uic.loadUi(path_ui, self) | ||
|
||
self.identifier = slot.identifier | ||
|
||
# set dataset label | ||
self.checkBox_dataset.setText(slot.name) | ||
|
||
# set region icon | ||
region = meta_tool.get_info(slot.path, | ||
section="setup", | ||
key="chip region") | ||
icon = QtGui.QIcon.fromTheme("region_{}".format(region)) | ||
pixmap = icon.pixmap(16) | ||
self.label_region.setPixmap(pixmap) | ||
self.label_region.setToolTip(region) | ||
|
||
def add_to_rlme4(self, pipeline, rlme4): | ||
"""Add the dataset to an Rlme4 analysis | ||
Parameters | ||
---------- | ||
pipeline: shapeout2.pipeline.core.Pipeline | ||
The pipeline from which to extract the filtered dataset | ||
using `self.identifier`. | ||
rlme4: dclab.lme4.wrapr.Rlme4 | ||
The analysis to which to append this dataset. | ||
Notes | ||
----- | ||
If the check box is not checked, then the dataset is ignored. | ||
""" | ||
if self.checkBox_dataset.isChecked(): | ||
ds_index = pipeline.slot_ids.index(self.identifier) | ||
ds = pipeline.get_dataset(ds_index) | ||
group_id = self.comboBox_group.currentIndex() | ||
group = "control" if group_id == 0 else "treatment" | ||
repetition = self.spinBox_repeat.value() | ||
rlme4.add_dataset(ds=ds, group=group, repetition=repetition) |
Oops, something went wrong.