dclab 0.61.2__cp312-cp312-macosx_10_9_x86_64.whl → 2.18.0__cp312-cp312-macosx_10_9_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dclab might be problematic. Click here for more details.
- dclab/_version.py +2 -2
- dclab/downsampling.cpython-312-darwin.so +0 -0
- dclab/external/skimage/_find_contours_cy.cpython-312-darwin.so +0 -0
- dclab/external/skimage/_pnpoly.cpython-312-darwin.so +0 -0
- dclab/external/skimage/_shared/geometry.cpython-312-darwin.so +0 -0
- dclab/lme4/__init__.py +4 -4
- dclab/lme4/rlibs.py +93 -0
- dclab/lme4/rsetup.py +148 -115
- dclab/lme4/wrapr.py +129 -93
- {dclab-0.61.2.dist-info → dclab-2.18.0.dist-info}/METADATA +4 -2
- {dclab-0.61.2.dist-info → dclab-2.18.0.dist-info}/RECORD +15 -15
- dclab/lme4/lme4_template.R +0 -94
- {dclab-0.61.2.dist-info → dclab-2.18.0.dist-info}/LICENSE +0 -0
- {dclab-0.61.2.dist-info → dclab-2.18.0.dist-info}/WHEEL +0 -0
- {dclab-0.61.2.dist-info → dclab-2.18.0.dist-info}/entry_points.txt +0 -0
- {dclab-0.61.2.dist-info → dclab-2.18.0.dist-info}/top_level.txt +0 -0
dclab/_version.py
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
dclab/lme4/__init__.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""A wrapper around R with the lme4 package"""
|
|
2
|
-
|
|
3
|
-
from .
|
|
4
|
-
from .
|
|
5
|
-
|
|
2
|
+
# flake8: noqa: F401
|
|
3
|
+
from . import rlibs, rsetup, wrapr
|
|
4
|
+
from .wrapr import Rlme4, bootstrapped_median_distributions
|
|
5
|
+
from .rsetup import get_r_path, get_r_version, install_lme4, set_r_path
|
dclab/lme4/rlibs.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
import os
|
|
3
|
+
import warnings
|
|
4
|
+
|
|
5
|
+
from ..external.packaging import parse as parse_version
|
|
6
|
+
|
|
7
|
+
#: Minimum R version
|
|
8
|
+
#: This is actually a dependency for rpy2, because the API changed then
|
|
9
|
+
#: (ffi.error: symbol 'R_tryCatchError' not found in library).
|
|
10
|
+
R_MIN_VERSION = "3.6.0"
|
|
11
|
+
|
|
12
|
+
#: Minimum rpy2 version
|
|
13
|
+
RPY2_MIN_VERSION = "2.9.4"
|
|
14
|
+
|
|
15
|
+
R_SUBMODULES = [
|
|
16
|
+
"rpy2.robjects.packages",
|
|
17
|
+
"rpy2.situation",
|
|
18
|
+
"rpy2.robjects.vectors",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
R_SUBMODULES_3 = [
|
|
22
|
+
"rpy2.rinterface_lib.callbacks",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class RPY2UnavailableError(BaseException):
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class RPY2ImportError(RPY2UnavailableError):
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class RPY2OutdatedError(RPY2UnavailableError):
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class RUnavailableError(BaseException):
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class ROutdatedError(RUnavailableError):
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class MockRPackage:
|
|
47
|
+
def __init__(self, exception):
|
|
48
|
+
self.exception = exception
|
|
49
|
+
|
|
50
|
+
def __getattr__(self, item):
|
|
51
|
+
raise self.exception
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def import_r_submodules():
|
|
55
|
+
importlib.import_module("rpy2.situation")
|
|
56
|
+
r_home = rpy2.situation.get_r_home()
|
|
57
|
+
if r_home is not None:
|
|
58
|
+
if os.environ.get("R_HOME", None) is None:
|
|
59
|
+
# set R_HOME globally (https://github.com/rpy2/rpy2/issues/796)
|
|
60
|
+
os.environ["R_HOME"] = r_home
|
|
61
|
+
if rpy2_is_version_3:
|
|
62
|
+
mods = R_SUBMODULES + R_SUBMODULES_3
|
|
63
|
+
else:
|
|
64
|
+
mods = R_SUBMODULES
|
|
65
|
+
try:
|
|
66
|
+
for sm in mods:
|
|
67
|
+
importlib.import_module(sm)
|
|
68
|
+
except rpy2.rinterface_lib.openrlib.ffi.error as exc:
|
|
69
|
+
# This error happens when the installed R version is too old:
|
|
70
|
+
# "ffi.error: symbol 'R_tryCatchError' not found in library"
|
|
71
|
+
raise ROutdatedError(
|
|
72
|
+
f"Encountered '{exc.__class__.__name__}: {exc}'. "
|
|
73
|
+
f"Please make sure you have 'R>={R_MIN_VERSION}'!")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
rpy2 = importlib.import_module("rpy2")
|
|
78
|
+
if parse_version(rpy2.__version__) < parse_version(RPY2_MIN_VERSION):
|
|
79
|
+
raise RPY2OutdatedError(f"Please install 'rpy2>={RPY2_MIN_VERSION}'!")
|
|
80
|
+
except ImportError:
|
|
81
|
+
rpy2 = MockRPackage(
|
|
82
|
+
RPY2ImportError(f"Please install 'rpy2>={RPY2_MIN_VERSION}'!"))
|
|
83
|
+
rpy2_is_version_3 = False
|
|
84
|
+
except BaseException as e:
|
|
85
|
+
rpy2 = MockRPackage(e)
|
|
86
|
+
rpy2_is_version_3 = False
|
|
87
|
+
else:
|
|
88
|
+
rpy2_is_version_3 = parse_version(rpy2.__version__) >= parse_version("3.0")
|
|
89
|
+
try:
|
|
90
|
+
import_r_submodules()
|
|
91
|
+
except RUnavailableError as e:
|
|
92
|
+
warnings.warn("There is an issue with the linked R version: "
|
|
93
|
+
+ f"{e.__class__.__name__}: {e}")
|
dclab/lme4/rsetup.py
CHANGED
|
@@ -1,142 +1,185 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
|
-
import pathlib
|
|
4
3
|
import subprocess as sp
|
|
5
|
-
import sys
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
from .rlibs import (
|
|
6
|
+
RUnavailableError, rpy2, rpy2_is_version_3, import_r_submodules)
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
# Disable rpy2 logger because of unnecessary prints to stdout
|
|
9
|
+
logging.getLogger("rpy2.rinterface_lib.callbacks").disabled = True
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
class RNotFoundError(BaseException):
|
|
14
13
|
pass
|
|
15
14
|
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
16
|
+
class AutoRConsole(object):
|
|
17
|
+
"""Helper class for catching R console output"""
|
|
18
|
+
lock = False
|
|
19
|
+
perform_lock = rpy2_is_version_3
|
|
20
|
+
|
|
21
|
+
def __init__(self):
|
|
22
|
+
"""
|
|
23
|
+
By default, this console always returns "yes" when asked a
|
|
24
|
+
question. If you need something different, you can subclass
|
|
25
|
+
and override `consoleread` fucntion. The console stream is
|
|
26
|
+
recorded in `self.stream`.
|
|
27
|
+
"""
|
|
28
|
+
self.stream = [["init", "Starting RConsole class\n"]]
|
|
29
|
+
if AutoRConsole.perform_lock:
|
|
30
|
+
if AutoRConsole.lock:
|
|
31
|
+
raise ValueError("Only one RConsole instance allowed!")
|
|
32
|
+
AutoRConsole.lock = True
|
|
33
|
+
self.original_funcs = {
|
|
34
|
+
"consoleread": rpy2.rinterface_lib.callbacks.consoleread,
|
|
35
|
+
"consolewrite_print":
|
|
36
|
+
rpy2.rinterface_lib.callbacks.consolewrite_print,
|
|
37
|
+
"consolewrite_warnerror":
|
|
38
|
+
rpy2.rinterface_lib.callbacks.consolewrite_warnerror,
|
|
39
|
+
}
|
|
40
|
+
rpy2.rinterface_lib.callbacks.consoleread = self.consoleread
|
|
41
|
+
rpy2.rinterface_lib.callbacks.consolewrite_print = \
|
|
42
|
+
self.consolewrite_print
|
|
43
|
+
rpy2.rinterface_lib.callbacks.showmessage = \
|
|
44
|
+
self.consolewrite_print
|
|
45
|
+
|
|
46
|
+
rpy2.rinterface_lib.callbacks.consolewrite_warnerror = \
|
|
47
|
+
self.consolewrite_warnerror
|
|
48
|
+
# Set locale (to get always English messages)
|
|
49
|
+
rpy2.robjects.r('Sys.setlocale("LC_MESSAGES", "C")')
|
|
50
|
+
rpy2.robjects.r('Sys.setlocale("LC_CTYPE", "C")')
|
|
51
|
+
|
|
52
|
+
def __enter__(self):
|
|
53
|
+
return self
|
|
54
|
+
|
|
55
|
+
def __exit__(self, *args):
|
|
56
|
+
if AutoRConsole.perform_lock:
|
|
57
|
+
AutoRConsole.lock = False
|
|
58
|
+
rpy2.rinterface_lib.callbacks.consoleread = \
|
|
59
|
+
self.original_funcs["consoleread"]
|
|
60
|
+
rpy2.rinterface_lib.callbacks.consolewrite_print = \
|
|
61
|
+
self.original_funcs["consolewrite_print"]
|
|
62
|
+
rpy2.rinterface_lib.callbacks.consolewrite_warnerror = \
|
|
63
|
+
self.original_funcs["consolewrite_warnerror"]
|
|
64
|
+
|
|
65
|
+
def close(self):
|
|
66
|
+
"""Remove the rpy2 monkeypatches"""
|
|
67
|
+
self.__exit__()
|
|
68
|
+
|
|
69
|
+
def consoleread(self, prompt):
|
|
70
|
+
"""Read user input, returns "yes" by default"""
|
|
71
|
+
self.write_to_stream("consoleread", prompt + "YES")
|
|
72
|
+
return "yes"
|
|
73
|
+
|
|
74
|
+
def consolewrite_print(self, s):
|
|
75
|
+
self.write_to_stream("consolewrite_print", s)
|
|
76
|
+
|
|
77
|
+
def consolewrite_warnerror(self, s):
|
|
78
|
+
self.write_to_stream("consolewrite_warnerror", s)
|
|
79
|
+
|
|
80
|
+
def write_to_stream(self, topic, s):
|
|
81
|
+
prev_topic = self.stream[-1][0]
|
|
82
|
+
same_topic = prev_topic == topic
|
|
83
|
+
unfinished_line = self.stream[-1][1][-1] not in ["\n", "\r"]
|
|
84
|
+
if same_topic and unfinished_line:
|
|
85
|
+
# append to previous line
|
|
86
|
+
self.stream[-1][1] += s
|
|
39
87
|
else:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if not r_exec.is_file():
|
|
56
|
-
raise RNotFoundError(
|
|
57
|
-
f"Expected R binary at '{r_exec}' does not exist!")
|
|
58
|
-
logger.info(f"R path: {r_exec}")
|
|
59
|
-
return r_exec
|
|
88
|
+
self.stream.append([topic, s])
|
|
89
|
+
|
|
90
|
+
def get_prints(self):
|
|
91
|
+
prints = []
|
|
92
|
+
for line in self.stream:
|
|
93
|
+
if line[0] == "consolewrite_print":
|
|
94
|
+
prints.append(line[1].strip())
|
|
95
|
+
return prints
|
|
96
|
+
|
|
97
|
+
def get_warnerrors(self):
|
|
98
|
+
warnerrors = []
|
|
99
|
+
for line in self.stream:
|
|
100
|
+
if line[0] == "consolewrite_warnerror":
|
|
101
|
+
warnerrors.append(line[1].strip())
|
|
102
|
+
return warnerrors
|
|
60
103
|
|
|
61
104
|
|
|
62
|
-
def
|
|
63
|
-
"""
|
|
64
|
-
|
|
105
|
+
def check_r():
|
|
106
|
+
"""Make sure R is installed an R HOME is set"""
|
|
107
|
+
if not has_r():
|
|
108
|
+
raise RNotFoundError("Cannot find R, please set its path with the "
|
|
109
|
+
+ "`set_r_path` function.")
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def get_r_path():
|
|
113
|
+
"""Get the path of the R executable/binary from rpy2"""
|
|
114
|
+
r_home = rpy2.situation.get_r_home()
|
|
115
|
+
return rpy2.situation.get_r_exec(r_home)
|
|
65
116
|
|
|
66
117
|
|
|
67
118
|
def get_r_version():
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
r_version = r_version[1]
|
|
76
|
-
else:
|
|
77
|
-
r_version = r_version[0]
|
|
78
|
-
logger.info(f"R version found: {r_version}")
|
|
79
|
-
# get the actual version string
|
|
80
|
-
if r_version.startswith("R version "):
|
|
81
|
-
r_version = r_version.split(" ", 2)[2]
|
|
82
|
-
return r_version.strip()
|
|
119
|
+
check_r()
|
|
120
|
+
ver_string = rpy2.situation.r_version_from_subprocess().strip()
|
|
121
|
+
if ver_string:
|
|
122
|
+
# get the actual version string
|
|
123
|
+
if ver_string.startswith("R version "):
|
|
124
|
+
ver_string = ver_string.split(" ")[2]
|
|
125
|
+
return ver_string
|
|
83
126
|
|
|
84
127
|
|
|
85
128
|
def has_lme4():
|
|
86
129
|
"""Return True if the lme4 package is installed"""
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
res = run_command(("R", "-q", "-e", f"system.file(package='{pkg}')"))
|
|
93
|
-
if not res.split("[1]")[1].count(pkg):
|
|
94
|
-
avail = False
|
|
95
|
-
break
|
|
96
|
-
else:
|
|
97
|
-
avail = _has_lme4 = True
|
|
98
|
-
return avail
|
|
130
|
+
check_r()
|
|
131
|
+
lme4_there = rpy2.robjects.packages.isinstalled("lme4")
|
|
132
|
+
statmod_there = rpy2.robjects.packages.isinstalled("statmod")
|
|
133
|
+
nloptr_there = rpy2.robjects.packages.isinstalled("nloptr")
|
|
134
|
+
return lme4_there and statmod_there and nloptr_there
|
|
99
135
|
|
|
100
136
|
|
|
101
137
|
def has_r():
|
|
102
138
|
"""Return True if R is available"""
|
|
103
|
-
global _has_r
|
|
104
|
-
if _has_r:
|
|
105
|
-
return True
|
|
106
139
|
try:
|
|
107
|
-
hasr =
|
|
108
|
-
except
|
|
140
|
+
hasr = rpy2.situation.get_r_home() is not None
|
|
141
|
+
except RUnavailableError:
|
|
109
142
|
hasr = False
|
|
110
|
-
if hasr:
|
|
111
|
-
_has_r = True
|
|
112
143
|
return hasr
|
|
113
144
|
|
|
114
145
|
|
|
115
|
-
def
|
|
146
|
+
def import_lme4():
|
|
147
|
+
check_r()
|
|
148
|
+
if has_lme4():
|
|
149
|
+
lme4pkg = rpy2.robjects.packages.importr("lme4")
|
|
150
|
+
else:
|
|
151
|
+
raise ValueError(
|
|
152
|
+
"The R package 'lme4' is not installed, please install it via "
|
|
153
|
+
+ "`dclab.lme4.rsetup.install_lme4()` or by executing "
|
|
154
|
+
+ "in a shell: R -e " + '"install.packages(' + "'lme4', "
|
|
155
|
+
+ "repos='http://cran.rstudio.org')" + '"')
|
|
156
|
+
return lme4pkg
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def install_lme4():
|
|
116
160
|
"""Install the lme4 package (if not already installed)
|
|
117
161
|
|
|
118
|
-
Besides ``lme4``, this also installs ``nloptr`` and ``statmod``.
|
|
119
162
|
The packages are installed to the user data directory
|
|
120
|
-
given in :const:`lib_path
|
|
163
|
+
given in :const:`lib_path`.
|
|
121
164
|
"""
|
|
122
|
-
|
|
165
|
+
check_r()
|
|
123
166
|
if not has_lme4():
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
167
|
+
# import R's utility package
|
|
168
|
+
utils = rpy2.robjects.packages.importr('utils')
|
|
169
|
+
# select the first mirror in the list
|
|
170
|
+
utils.chooseCRANmirror(ind=1)
|
|
171
|
+
# install lme4 to user data directory (say yes to user dir install)
|
|
172
|
+
with AutoRConsole() as rc:
|
|
173
|
+
# install statmod and nloptr first
|
|
174
|
+
# (Doesn't R have package dependencies?!)
|
|
175
|
+
utils.install_packages(
|
|
176
|
+
rpy2.robjects.vectors.StrVector(["statmod", "nloptr", "lme4"]))
|
|
177
|
+
return rc
|
|
135
178
|
|
|
136
179
|
|
|
137
|
-
def
|
|
138
|
-
"""
|
|
139
|
-
if hasattr(sp,
|
|
180
|
+
def set_r_path(r_path):
|
|
181
|
+
"""Set the path of the R executable/binary for rpy2"""
|
|
182
|
+
if hasattr(sp, 'STARTUPINFO'):
|
|
140
183
|
# On Windows, subprocess calls will pop up a command window by
|
|
141
184
|
# default when run from Pyinstaller with the ``--noconsole``
|
|
142
185
|
# option. Avoid this distraction.
|
|
@@ -149,26 +192,16 @@ def run_command(cmd):
|
|
|
149
192
|
si = None
|
|
150
193
|
env = None
|
|
151
194
|
|
|
152
|
-
|
|
153
|
-
cmd = [str(cc) for cc in cmd]
|
|
154
|
-
|
|
155
|
-
tmp = sp.check_output(cmd,
|
|
195
|
+
tmp = sp.check_output((r_path, 'RHOME'),
|
|
156
196
|
startupinfo=si,
|
|
157
197
|
env=env,
|
|
158
|
-
stderr=sp.STDOUT,
|
|
159
198
|
text=True,
|
|
160
199
|
)
|
|
161
|
-
return tmp
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
def set_r_path(r_path):
|
|
165
|
-
"""Set the path of the R executable/binary"""
|
|
166
|
-
tmp = run_command((r_path, "RHOME"))
|
|
167
200
|
|
|
168
201
|
r_home = tmp.split(os.linesep)
|
|
169
|
-
if r_home[0].startswith(
|
|
202
|
+
if r_home[0].startswith('WARNING'):
|
|
170
203
|
res = r_home[1]
|
|
171
204
|
else:
|
|
172
205
|
res = r_home[0].strip()
|
|
173
206
|
os.environ["R_HOME"] = res
|
|
174
|
-
|
|
207
|
+
import_r_submodules()
|
dclab/lme4/wrapr.py
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
"""R lme4 wrapper"""
|
|
2
|
-
import logging
|
|
3
2
|
import numbers
|
|
4
|
-
import
|
|
5
|
-
import tempfile
|
|
3
|
+
import warnings
|
|
6
4
|
|
|
7
|
-
import importlib_resources
|
|
8
5
|
import numpy as np
|
|
9
6
|
|
|
10
7
|
from .. import definitions as dfn
|
|
11
8
|
from ..rtdc_dataset.core import RTDCBase
|
|
12
9
|
|
|
10
|
+
from .rlibs import rpy2
|
|
13
11
|
from . import rsetup
|
|
14
12
|
|
|
15
13
|
|
|
16
|
-
|
|
14
|
+
class Lme4InstallWarning(UserWarning):
|
|
15
|
+
pass
|
|
17
16
|
|
|
18
17
|
|
|
19
18
|
class Rlme4(object):
|
|
@@ -39,12 +38,19 @@ class Rlme4(object):
|
|
|
39
38
|
#: list of [RTDCBase, column, repetition, chip_region]
|
|
40
39
|
self.data = []
|
|
41
40
|
|
|
41
|
+
#: model function
|
|
42
|
+
self.r_func_model = "feature ~ group + (1 + group | repetition)"
|
|
43
|
+
#: null model function
|
|
44
|
+
self.r_func_nullmodel = "feature ~ (1 + group | repetition)"
|
|
45
|
+
|
|
42
46
|
self.set_options(model=model, feature=feature)
|
|
43
47
|
|
|
44
48
|
# Make sure that lme4 is available
|
|
45
49
|
if not rsetup.has_lme4():
|
|
46
|
-
|
|
47
|
-
|
|
50
|
+
warnings.warn("Installing lme4, this may take a while!",
|
|
51
|
+
Lme4InstallWarning)
|
|
52
|
+
rsetup.install_lme4()
|
|
53
|
+
rsetup.import_lme4()
|
|
48
54
|
|
|
49
55
|
def add_dataset(self, ds, group, repetition):
|
|
50
56
|
"""Add a dataset to the analysis list
|
|
@@ -61,8 +67,8 @@ class Rlme4(object):
|
|
|
61
67
|
|
|
62
68
|
Notes
|
|
63
69
|
-----
|
|
64
|
-
- For each repetition, there must be a "treatment"
|
|
65
|
-
"control"
|
|
70
|
+
- For each repetition, there must be a "treatment" and a
|
|
71
|
+
"control" ``group``.
|
|
66
72
|
- If you would like to perform a differential feature analysis,
|
|
67
73
|
then you need to pass at least a reservoir and a channel
|
|
68
74
|
dataset (with same parameters for `group` and `repetition`).
|
|
@@ -96,10 +102,10 @@ class Rlme4(object):
|
|
|
96
102
|
The response variable is modeled using two linear mixed effect
|
|
97
103
|
models:
|
|
98
104
|
|
|
99
|
-
- model:
|
|
100
|
-
|
|
101
|
-
- the null model:
|
|
102
|
-
|
|
105
|
+
- model :const:`Rlme4.r_func_model` (random intercept +
|
|
106
|
+
random slope model)
|
|
107
|
+
- the null model :const:`Rlme4.r_func_nullmodel` (without
|
|
108
|
+
the fixed effect introduced by the "treatment" group).
|
|
103
109
|
|
|
104
110
|
Both models are compared in R using "anova" (from the
|
|
105
111
|
R-package "stats" :cite:`Everitt1992`) which performs a
|
|
@@ -127,16 +133,16 @@ class Rlme4(object):
|
|
|
127
133
|
results: dict
|
|
128
134
|
Dictionary with the results of the fitting process:
|
|
129
135
|
|
|
130
|
-
- "anova p-value": Anova
|
|
136
|
+
- "anova p-value": Anova likelyhood ratio test (significance)
|
|
131
137
|
- "feature": name of the feature used for the analysis
|
|
132
138
|
``self.feature``
|
|
133
139
|
- "fixed effects intercept": Mean of ``self.feature`` for all
|
|
134
140
|
controls; In the case of the "glmer+loglink" model, the intercept
|
|
135
|
-
is already
|
|
141
|
+
is already backtransformed from log space.
|
|
136
142
|
- "fixed effects treatment": The fixed effect size between the mean
|
|
137
143
|
of the controls and the mean of the treatments relative to
|
|
138
144
|
"fixed effects intercept"; In the case of the "glmer+loglink"
|
|
139
|
-
model, the fixed effect is already
|
|
145
|
+
model, the fixed effect is already backtransformed from log
|
|
140
146
|
space.
|
|
141
147
|
- "fixed effects repetitions": The effects (intercept and
|
|
142
148
|
treatment) for each repetition. The first axis defines
|
|
@@ -153,10 +159,11 @@ class Rlme4(object):
|
|
|
153
159
|
- "model": model name used for the analysis ``self.model``
|
|
154
160
|
- "model converged": boolean indicating whether the model
|
|
155
161
|
converged
|
|
156
|
-
- "r
|
|
157
|
-
- "r model
|
|
158
|
-
- "r
|
|
159
|
-
- "r
|
|
162
|
+
- "r anova": Anova model (exposed from R)
|
|
163
|
+
- "r model summary": Summary of the model (exposed from R)
|
|
164
|
+
- "r model coefficients": Model coefficient table (exposed from R)
|
|
165
|
+
- "r stderr": errors and warnings from R
|
|
166
|
+
- "r stdout": standard output from R
|
|
160
167
|
"""
|
|
161
168
|
self.set_options(model=model, feature=feature)
|
|
162
169
|
self.check_data()
|
|
@@ -175,38 +182,105 @@ class Rlme4(object):
|
|
|
175
182
|
groups.append(dd[1])
|
|
176
183
|
repetitions.append(dd[2])
|
|
177
184
|
|
|
178
|
-
#
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
185
|
+
# Fire up R
|
|
186
|
+
with rsetup.AutoRConsole() as ac:
|
|
187
|
+
r = rpy2.robjects.r
|
|
188
|
+
|
|
189
|
+
# Load lme4
|
|
190
|
+
rpy2.robjects.packages.importr("lme4")
|
|
191
|
+
|
|
192
|
+
# Concatenate huge arrays for R
|
|
193
|
+
r_features = rpy2.robjects.FloatVector(np.concatenate(features))
|
|
194
|
+
_groups = []
|
|
195
|
+
_repets = []
|
|
196
|
+
for ii in range(len(features)):
|
|
197
|
+
_groups.append(np.repeat(groups[ii], len(features[ii])))
|
|
198
|
+
_repets.append(np.repeat(repetitions[ii], len(features[ii])))
|
|
199
|
+
r_groups = rpy2.robjects.StrVector(np.concatenate(_groups))
|
|
200
|
+
r_repetitions = rpy2.robjects.IntVector(np.concatenate(_repets))
|
|
201
|
+
|
|
202
|
+
# Register groups and repetitions
|
|
203
|
+
rpy2.robjects.globalenv["feature"] = r_features
|
|
204
|
+
rpy2.robjects.globalenv["group"] = r_groups
|
|
205
|
+
rpy2.robjects.globalenv["repetition"] = r_repetitions
|
|
206
|
+
|
|
207
|
+
# Create a dataframe which contains all the data
|
|
208
|
+
r_data = r["data.frame"](r_features, r_groups, r_repetitions)
|
|
209
|
+
|
|
210
|
+
# Random intercept and random slope model
|
|
211
|
+
if self.model == 'glmer+loglink':
|
|
212
|
+
r_model = r["glmer"](self.r_func_model, r_data,
|
|
213
|
+
family=r["Gamma"](link='log'))
|
|
214
|
+
r_nullmodel = r["glmer"](self.r_func_nullmodel, r_data,
|
|
215
|
+
family=r["Gamma"](link='log'))
|
|
216
|
+
else: # lmer
|
|
217
|
+
r_model = r["lmer"](self.r_func_model, r_data)
|
|
218
|
+
r_nullmodel = r["lmer"](self.r_func_nullmodel, r_data)
|
|
219
|
+
|
|
220
|
+
# Anova analysis (increase verbosity by making models global)
|
|
221
|
+
# Using anova is a very conservative way of determining
|
|
222
|
+
# p values.
|
|
223
|
+
rpy2.robjects.globalenv["Model"] = r_model
|
|
224
|
+
rpy2.robjects.globalenv["NullModel"] = r_nullmodel
|
|
225
|
+
r_anova = r("anova(Model, NullModel)")
|
|
226
|
+
try:
|
|
227
|
+
pvalue = r_anova.rx2["Pr(>Chisq)"][1]
|
|
228
|
+
except ValueError: # rpy2 2.9.4
|
|
229
|
+
pvalue = r_anova[7][1]
|
|
230
|
+
r_model_summary = r["summary"](r_model)
|
|
231
|
+
r_model_coefficients = r["coef"](r_model)
|
|
232
|
+
try:
|
|
233
|
+
fe_reps = np.array(r_model_coefficients.rx2["repetition"])
|
|
234
|
+
except ValueError: # rpy2 2.9.4
|
|
235
|
+
fe_reps = np.concatenate((
|
|
236
|
+
np.array(r_model_coefficients[0][0]).reshape(1, -1),
|
|
237
|
+
np.array(r_model_coefficients[0][1]).reshape(1, -1)),
|
|
238
|
+
axis=0)
|
|
239
|
+
|
|
240
|
+
r_effects = r["data.frame"](r["coef"](r_model_summary))
|
|
241
|
+
try:
|
|
242
|
+
fe_icept = r_effects.rx2["Estimate"][0]
|
|
243
|
+
fe_treat = r_effects.rx2["Estimate"][1]
|
|
244
|
+
except ValueError: # rpy2 2.9.4
|
|
245
|
+
fe_icept = r_effects[0][0]
|
|
246
|
+
fe_treat = r_effects[0][1]
|
|
247
|
+
if self.model == "glmer+loglink":
|
|
248
|
+
# transform back from log
|
|
249
|
+
fe_treat = np.exp(fe_icept + fe_treat) - np.exp(fe_icept)
|
|
250
|
+
fe_icept = np.exp(fe_icept)
|
|
251
|
+
fe_reps[:, 1] = np.exp(fe_reps[:, 0] + fe_reps[:, 1]) \
|
|
252
|
+
- np.exp(fe_reps[:, 0])
|
|
253
|
+
fe_reps[:, 0] = np.exp(fe_reps[:, 0])
|
|
254
|
+
|
|
255
|
+
# convergence
|
|
256
|
+
try:
|
|
257
|
+
lme4l = r_model_summary.rx2["optinfo"].rx2["conv"].rx2["lme4"]
|
|
258
|
+
except ValueError: # rpy2 2.9.4
|
|
259
|
+
lme4l = r_model_summary[17][3][1]
|
|
260
|
+
|
|
261
|
+
if lme4l and "code" in lme4l.names:
|
|
262
|
+
try:
|
|
263
|
+
conv_code = lme4l.rx2["code"]
|
|
264
|
+
except ValueError: # rpy2 2.9.4
|
|
265
|
+
conv_code = lme4l[0]
|
|
266
|
+
else:
|
|
267
|
+
conv_code = 0
|
|
268
|
+
|
|
269
|
+
ret_dict = {
|
|
270
|
+
"anova p-value": pvalue,
|
|
271
|
+
"feature": self.feature,
|
|
272
|
+
"fixed effects intercept": fe_icept,
|
|
273
|
+
"fixed effects treatment": fe_treat, # aka "fixed effect"
|
|
274
|
+
"fixed effects repetitions": fe_reps,
|
|
275
|
+
"is differential": self.is_differential(),
|
|
276
|
+
"model": self.model,
|
|
277
|
+
"model converged": conv_code == 0,
|
|
278
|
+
"r anova": r_anova,
|
|
279
|
+
"r model summary": r_model_summary,
|
|
280
|
+
"r model coefficients": r_model_coefficients,
|
|
281
|
+
"r stderr": ac.get_warnerrors(),
|
|
282
|
+
"r stdout": ac.get_prints(),
|
|
283
|
+
}
|
|
210
284
|
return ret_dict
|
|
211
285
|
|
|
212
286
|
def get_differential_dataset(self):
|
|
@@ -214,7 +288,7 @@ class Rlme4(object):
|
|
|
214
288
|
|
|
215
289
|
The most famous use case is differential deformation. The idea
|
|
216
290
|
is that you cannot tell what the difference in deformation
|
|
217
|
-
from channel to reservoir, because you never measure the
|
|
291
|
+
from channel to reservoir is, because you never measure the
|
|
218
292
|
same object in the reservoir and the channel. You usually just
|
|
219
293
|
have two distributions. Comparing distributions is possible
|
|
220
294
|
via bootstrapping. And then, instead of running the lme4
|
|
@@ -288,34 +362,6 @@ class Rlme4(object):
|
|
|
288
362
|
else:
|
|
289
363
|
return False
|
|
290
364
|
|
|
291
|
-
def parse_result(self, result):
|
|
292
|
-
resd = result.split("OUTPUT")
|
|
293
|
-
ret_dict = {}
|
|
294
|
-
for item in resd:
|
|
295
|
-
string = item.split("#*#")[0]
|
|
296
|
-
key, value = string.split(":", 1)
|
|
297
|
-
key = key.strip()
|
|
298
|
-
value = value.strip().replace("\n\n", "\n")
|
|
299
|
-
|
|
300
|
-
if key == "fixed effects repetitions":
|
|
301
|
-
rows = value.split("\n")[1:]
|
|
302
|
-
reps = []
|
|
303
|
-
for row in rows:
|
|
304
|
-
reps.append([float(vv) for vv in row.split()[1:]])
|
|
305
|
-
value = np.array(reps).transpose()
|
|
306
|
-
elif key == "model converged":
|
|
307
|
-
value = value == "TRUE"
|
|
308
|
-
elif value == "NA":
|
|
309
|
-
value = np.nan
|
|
310
|
-
else:
|
|
311
|
-
try:
|
|
312
|
-
value = float(value)
|
|
313
|
-
except ValueError:
|
|
314
|
-
pass
|
|
315
|
-
|
|
316
|
-
ret_dict[key] = value
|
|
317
|
-
return ret_dict
|
|
318
|
-
|
|
319
365
|
def set_options(self, model=None, feature=None):
|
|
320
366
|
"""Set analysis options"""
|
|
321
367
|
if model is not None:
|
|
@@ -326,16 +372,6 @@ class Rlme4(object):
|
|
|
326
372
|
self.feature = feature
|
|
327
373
|
|
|
328
374
|
|
|
329
|
-
def arr2str(a):
|
|
330
|
-
"""Convert an array to a string"""
|
|
331
|
-
if isinstance(a.dtype.type, np.integer):
|
|
332
|
-
return ",".join(str(dd) for dd in a.tolist())
|
|
333
|
-
elif a.dtype.type == np.str_:
|
|
334
|
-
return ",".join(f"'{dd}'" for dd in a.tolist())
|
|
335
|
-
else:
|
|
336
|
-
return ",".join(f"{dd:.16g}" for dd in a.tolist())
|
|
337
|
-
|
|
338
|
-
|
|
339
375
|
def bootstrapped_median_distributions(a, b, bs_iter=1000, rs=117):
|
|
340
376
|
"""Compute the bootstrapped distributions for two arrays.
|
|
341
377
|
|
|
@@ -345,7 +381,7 @@ def bootstrapped_median_distributions(a, b, bs_iter=1000, rs=117):
|
|
|
345
381
|
Input data
|
|
346
382
|
bs_iter: int
|
|
347
383
|
Number of bootstrapping iterations to perform
|
|
348
|
-
(
|
|
384
|
+
(outtput size).
|
|
349
385
|
rs: int
|
|
350
386
|
Random state seed for random number generator
|
|
351
387
|
|
|
@@ -360,7 +396,7 @@ def bootstrapped_median_distributions(a, b, bs_iter=1000, rs=117):
|
|
|
360
396
|
|
|
361
397
|
Notes
|
|
362
398
|
-----
|
|
363
|
-
From a
|
|
399
|
+
From a programmatical point of view, it would have been better
|
|
364
400
|
to implement this method for just one input array (because of
|
|
365
401
|
redundant code). However, due to historical reasons (testing
|
|
366
402
|
and comparability to Shape-Out 1), bootstrapping is done
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dclab
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.18.0
|
|
4
4
|
Summary: Library for real-time deformability cytometry (RT-DC)
|
|
5
5
|
Author: Benedikt Hartmann, Eoghan O'Connell, Maik Herbig, Maximilian Schlögel, Nadia Sbaa, Paul Müller, Philipp Rosendahl, Raghava Alajangi
|
|
6
6
|
Maintainer-email: Paul Müller <dev@craban.de>
|
|
@@ -23,7 +23,7 @@ Requires-Dist: importlib-resources>=6.0
|
|
|
23
23
|
Requires-Dist: numpy<3,>=1.21
|
|
24
24
|
Requires-Dist: scipy<2,>=1.10.0
|
|
25
25
|
Provides-Extra: all
|
|
26
|
-
Requires-Dist: dclab[dcor,export,http,s3,tdms]; extra == "all"
|
|
26
|
+
Requires-Dist: dclab[dcor,export,http,lme4,s3,tdms]; extra == "all"
|
|
27
27
|
Provides-Extra: dcor
|
|
28
28
|
Requires-Dist: requests<3,>=2.31.0; extra == "dcor"
|
|
29
29
|
Provides-Extra: export
|
|
@@ -31,6 +31,8 @@ Requires-Dist: fcswrite>=0.5.0; extra == "export"
|
|
|
31
31
|
Requires-Dist: imageio[ffmpeg]; extra == "export"
|
|
32
32
|
Provides-Extra: http
|
|
33
33
|
Requires-Dist: requests<3,>=2.31.0; extra == "http"
|
|
34
|
+
Provides-Extra: lme4
|
|
35
|
+
Requires-Dist: rpy2>=2.9.4; extra == "lme4"
|
|
34
36
|
Provides-Extra: s3
|
|
35
37
|
Requires-Dist: boto3>=1.34.31; extra == "s3"
|
|
36
38
|
Provides-Extra: tdms
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
dclab/kde_methods.py,sha256=awlqkj819VRJzArG6Fx6myDa6qGpLoZ8S9IJ1J1YECA,9206
|
|
2
|
-
dclab/_version.py,sha256=
|
|
2
|
+
dclab/_version.py,sha256=QyMxKDzFsqXDA7bVrQozJznaASbsECKe57aBBNAljsA,413
|
|
3
3
|
dclab/util.py,sha256=FcRsWcyKkKkfX2nZCShjJ5wPccr7U7NHsIDd_WEws6w,5141
|
|
4
4
|
dclab/downsampling.pyx,sha256=OK7zbgGLl5gVyoU8ZBHo9EWwb8C9ChavmLNEvQvC9T0,7258
|
|
5
5
|
dclab/__init__.py,sha256=1mskJAUo8HbvDhJRJFbcFB6HccFeqoRUCEHLuS64t_g,812
|
|
@@ -9,7 +9,7 @@ dclab/http_utils.py,sha256=TGqgiaUV-Z6Wiae__Yze-uHRWX57846ZnlV10ajzv2E,10562
|
|
|
9
9
|
dclab/polygon_filter.py,sha256=qexmo-rXe06CUPZhN6EMJy4y4B5gXZeqejdvIB2arOE,13480
|
|
10
10
|
dclab/statistics.py,sha256=tJDqPlY_Jw2Hhl-s7ugMBSZAxcRuPu4LQuBAZBXz7t8,6355
|
|
11
11
|
dclab/kde_contours.py,sha256=5K7PzZz-FtSGvW4IR2tLpbEKKqCSsSTQPsupu7zIsPg,6745
|
|
12
|
-
dclab/downsampling.cpython-312-darwin.so,sha256=
|
|
12
|
+
dclab/downsampling.cpython-312-darwin.so,sha256=8Mu_2whAnEOv_GSzu97Po69Nt1ccewisS-Iqp5C4iO0,259136
|
|
13
13
|
dclab/isoelastics/iso_LE-2D-FEM-19-volume-deform.txt,sha256=vTcazOlOXo3BQ0NQtGB_IdHKA0neOLXZ_d3JuMU--RE,83358
|
|
14
14
|
dclab/isoelastics/iso_HE-3D-FEM-22-area_um-deform.txt,sha256=IjULG1KO-hClaYPoJJnwPbF2TkS9i9jxF1tbhhQTClY,71350
|
|
15
15
|
dclab/isoelastics/iso_HE-2D-FEM-22-volume-deform.txt,sha256=aLOWxev_hvyP2yWquomcogn3Ze4SBfvqz-qmTOOibNw,97512
|
|
@@ -34,10 +34,10 @@ dclab/features/emodulus/scale_linear.py,sha256=5tZfOpG4QSSEMlwSoA_3XRQuY0tiZ3CSm
|
|
|
34
34
|
dclab/features/emodulus/lut_HE-3D-FEM-22.txt,sha256=1Sg4ys0ykT7Q_jFM28XS0uJ85nZd_ha7BDXdN2rsPIA,47248
|
|
35
35
|
dclab/features/emodulus/load.py,sha256=Q9rII-7Om-f0m183VNeJUxNno7at1reigKtbzdrWgjE,8557
|
|
36
36
|
dclab/features/emodulus/viscosity.py,sha256=aBm1pQa9cFAOBnO07UWMj87bw6fQpmW1IlWWD0MEtgw,9438
|
|
37
|
-
dclab/lme4/
|
|
38
|
-
dclab/lme4/
|
|
39
|
-
dclab/lme4/
|
|
40
|
-
dclab/lme4/
|
|
37
|
+
dclab/lme4/__init__.py,sha256=Y_oqYEqNnHCjxfdzkoP0ZXPCQx6XSKqwt1pAgdGF2dA,235
|
|
38
|
+
dclab/lme4/rsetup.py,sha256=siVWXt0niXAqD20d2quOjVzaZc4-zF0i81G_HRZE6q0,6951
|
|
39
|
+
dclab/lme4/wrapr.py,sha256=MzJDUZ7L_5xDWVtl5vrDgTJoum2vrxfP0dYwPMcHIPY,16977
|
|
40
|
+
dclab/lme4/rlibs.py,sha256=3oHSrSykeQB9ldvrV4Ite9EffIURUwCo3bn4uBpVeSk,2539
|
|
41
41
|
dclab/cli/task_tdms2rtdc.py,sha256=u0L1Fq9rXIeQG9b72SuUIh_qYC6fG2xXxht9_rcdCao,8283
|
|
42
42
|
dclab/cli/__init__.py,sha256=84YzzV6aE_NY-o7wvqgvUoxBLvIOEXpSUbkVcGRyzQ0,483
|
|
43
43
|
dclab/cli/task_condense.py,sha256=uNZzm04VuQOXJi6uXPmaLdQCk0g8ONueiO4p67yJv0k,8546
|
|
@@ -61,17 +61,17 @@ dclab/external/statsmodels/nonparametric/kernel_density.py,sha256=3UyzLuZS68TkNT
|
|
|
61
61
|
dclab/external/statsmodels/nonparametric/__init__.py,sha256=-GEWgwsF27ems5WTBvR1zo4SWJ0pRTWyHVagnIYer3g,43
|
|
62
62
|
dclab/external/statsmodels/nonparametric/kernels.py,sha256=fuy4kStFz2ZA9pqgfUb4cly-YBpXLu4TJ9-ZujayuIw,1075
|
|
63
63
|
dclab/external/skimage/measure.py,sha256=y1idCqD9TUxp3-QnOiWR_d674OKaeqBJ4MN2-gVP6ro,247
|
|
64
|
-
dclab/external/skimage/_pnpoly.cpython-312-darwin.so,sha256=
|
|
64
|
+
dclab/external/skimage/_pnpoly.cpython-312-darwin.so,sha256=QevOsMePM73uwzfnRPAVcgnFs_thMF1iN9R2N3Ksy64,222776
|
|
65
65
|
dclab/external/skimage/LICENSE,sha256=ivsSBvn3c0R9mOctWRRdza7C7wdZSRYgCVxlVqUdlB8,1452
|
|
66
66
|
dclab/external/skimage/pnpoly.py,sha256=r8hFNiTz5XlUoNZjosqA0iyv1FPn0l7ewbplgFgkdaw,1347
|
|
67
67
|
dclab/external/skimage/_find_contours.py,sha256=16v5eeTZBmevG8SSuXtJ6yUpVPhwfSmtc8pDD0nuuOU,9340
|
|
68
68
|
dclab/external/skimage/__init__.py,sha256=-B2QUKHAFzQuBWuuKvPDC5JIl0Zb-x3OGmbwPaE9VwQ,72
|
|
69
|
-
dclab/external/skimage/_find_contours_cy.cpython-312-darwin.so,sha256=
|
|
69
|
+
dclab/external/skimage/_find_contours_cy.cpython-312-darwin.so,sha256=2kub7ht3_Dx6HDfdLa5-RTkeeXG_-nai4ooY_vtiAfQ,204520
|
|
70
70
|
dclab/external/skimage/_pnpoly.pyx,sha256=Qdn6xPazDschBqbr46DzB75MB2MnqvdnoTSBMK7kUGE,2504
|
|
71
71
|
dclab/external/skimage/_find_contours_cy.pyx,sha256=pZJOBhMHzYEMkcz4WQVyjn7jDNrdjCfet47FU1hRAxk,7161
|
|
72
72
|
dclab/external/skimage/_shared/geometry.pxd,sha256=kRsu9ifv_rL3kbRIgSLf86p0hn2oTMp6s013lZ9bBZM,346
|
|
73
73
|
dclab/external/skimage/_shared/__init__.py,sha256=2sHZwTtJSlMTa3Q2YSvQW7jrPLMUSqDJQa-ROe5zfcw,37
|
|
74
|
-
dclab/external/skimage/_shared/geometry.cpython-312-darwin.so,sha256=
|
|
74
|
+
dclab/external/skimage/_shared/geometry.cpython-312-darwin.so,sha256=CdXgHOQZTU-tUUsnE7TALAj_5g3jK9KVvbXEfVqk8RI,39216
|
|
75
75
|
dclab/external/skimage/_shared/geometry.pyx,sha256=miCHUh6mBDbRRIoaF_0xAER1MRzsCAzFdlYQZhV7RmE,1667
|
|
76
76
|
dclab/definitions/feat_logic.py,sha256=SXsSlAusgtE3uXcPu84dQwYZ07zxmV37DmPednA3_dM,5823
|
|
77
77
|
dclab/definitions/meta_parse.py,sha256=YdaTdM8DAMsIFn5ITH9OHYGTXeAOBGWtx22oVjxXcWk,2393
|
|
@@ -130,9 +130,9 @@ dclab/rtdc_dataset/fmt_tdms/event_image.py,sha256=-jp7Z-N91e4ieumYQ1huMicj7PMJqw
|
|
|
130
130
|
dclab/rtdc_dataset/fmt_tdms/event_trace.py,sha256=Vkym0QKSw2mq1XZl5n8wDkgHXmaZwQGiMAV5AuRSJkE,5215
|
|
131
131
|
dclab/rtdc_dataset/fmt_tdms/exc.py,sha256=WzrMqnyrzp8gsT8Pf7JKqGGv43ewx7d_qgtirURppRI,813
|
|
132
132
|
dclab/rtdc_dataset/fmt_tdms/event_contour.py,sha256=kjo0wJx9F0gmmOOyR0NoLw6VEtSl3h63WXXkcbfnoS8,9627
|
|
133
|
-
dclab-
|
|
134
|
-
dclab-
|
|
135
|
-
dclab-
|
|
136
|
-
dclab-
|
|
137
|
-
dclab-
|
|
138
|
-
dclab-
|
|
133
|
+
dclab-2.18.0.dist-info/RECORD,,
|
|
134
|
+
dclab-2.18.0.dist-info/LICENSE,sha256=1mLfjOTOaeiMSGPJiF5hHnMQfKX88QVeZpCCXwJGj3k,18131
|
|
135
|
+
dclab-2.18.0.dist-info/WHEEL,sha256=Gslco0u-UdyhQslriEMCnIh5wENI6Dd1FlwyhvZM_HQ,110
|
|
136
|
+
dclab-2.18.0.dist-info/entry_points.txt,sha256=eOpjgznu-eW-9utUpLU-77O5098YyUEgGF3ksGMdtec,273
|
|
137
|
+
dclab-2.18.0.dist-info/top_level.txt,sha256=irvwZMgs1edY1Zj60ZFk7Almb9Zhk4k6E6aC4YPFnnM,6
|
|
138
|
+
dclab-2.18.0.dist-info/METADATA,sha256=WTNyL58XdjHtE11bxXQWGntyi981Fv5pWGaxXshj1Iw,4824
|
dclab/lme4/lme4_template.R
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
require(stats);
|
|
2
|
-
require(lme4);
|
|
3
|
-
|
|
4
|
-
model_name <- "<MODEL_NAME>"
|
|
5
|
-
cat("OUTPUT model:", model_name, "#*#\n")
|
|
6
|
-
|
|
7
|
-
func_model <- "feature ~ group + (1 + group | repetition)"
|
|
8
|
-
func_nullmodel <- "feature ~ (1 + group | repetition)"
|
|
9
|
-
|
|
10
|
-
# These are the feature, group, and repetition arrays that are set by dclab
|
|
11
|
-
# via templates.
|
|
12
|
-
feature <- c(<FEATURES>)
|
|
13
|
-
group <- c(<GROUPS>)
|
|
14
|
-
repetition <- c(<REPETITIONS>)
|
|
15
|
-
|
|
16
|
-
data <- data.frame(feature, group, repetition)
|
|
17
|
-
|
|
18
|
-
if (model_name == "glmer+loglink") {
|
|
19
|
-
Model <- glmer(func_model, data, family=Gamma(link='log'))
|
|
20
|
-
NullModel <- glmer(func_nullmodel, data, family=Gamma(link='log'))
|
|
21
|
-
} else if (model_name == "lmer") {
|
|
22
|
-
Model <- lmer(func_model, data)
|
|
23
|
-
NullModel <- lmer(func_nullmodel, data)
|
|
24
|
-
} else {
|
|
25
|
-
stop("Invalid model_name:", model_name)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
# Anova analysis (increase verbosity by making models global)
|
|
29
|
-
# Using anova is a very conservative way of determining
|
|
30
|
-
# p values.
|
|
31
|
-
res_anova <- anova(Model, NullModel)
|
|
32
|
-
cat("OUTPUT r anova: ")
|
|
33
|
-
res_anova
|
|
34
|
-
cat("#*#\n")
|
|
35
|
-
|
|
36
|
-
pvalue <- res_anova$"Pr(>Chisq)"[2]
|
|
37
|
-
cat("OUTPUT anova p-value:", pvalue, "#*#\n")
|
|
38
|
-
|
|
39
|
-
model_summary <- summary(Model)
|
|
40
|
-
cat("OUTPUT r model summary:")
|
|
41
|
-
model_summary
|
|
42
|
-
cat("#*#\n")
|
|
43
|
-
|
|
44
|
-
model_coefficients <- coef(Model)
|
|
45
|
-
cat("OUTPUT r model coefficients:")
|
|
46
|
-
model_coefficients
|
|
47
|
-
cat("#*#\n")
|
|
48
|
-
|
|
49
|
-
fe_reps <- model_coefficients$repetition
|
|
50
|
-
|
|
51
|
-
effects <- data.frame(coef(model_summary))
|
|
52
|
-
|
|
53
|
-
fe_icept <- effects$Estimate[1]
|
|
54
|
-
|
|
55
|
-
fe_treat <- effects$Estimate[2]
|
|
56
|
-
|
|
57
|
-
if (model_name == "glmer+loglink") {
|
|
58
|
-
# transform back from log
|
|
59
|
-
fe_treat <- exp(fe_icept + fe_treat) - exp(fe_icept)
|
|
60
|
-
fe_icept <- exp(fe_icept)
|
|
61
|
-
fe_reps[, 2] = exp(fe_reps[, 1] + fe_reps[, 2]) - exp(fe_reps[, 1])
|
|
62
|
-
fe_reps[, 1] = exp(fe_reps[, 1])
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
cat("OUTPUT fixed effects intercept:", fe_icept, "#*#\n")
|
|
66
|
-
cat("OUTPUT fixed effects treatment:", fe_treat, "#*#\n")
|
|
67
|
-
cat("OUTPUT fixed effects repetitions:")
|
|
68
|
-
fe_reps
|
|
69
|
-
cat("#*#\n")
|
|
70
|
-
|
|
71
|
-
# convergence
|
|
72
|
-
|
|
73
|
-
# convergence warnings in lme4
|
|
74
|
-
is_warning_generated <- function(m) {
|
|
75
|
-
df <- summary(m)
|
|
76
|
-
!is.null(df$optinfo$conv$lme4$messages) &&
|
|
77
|
-
grepl('failed to converge', df$optinfo$conv$lme4$messages)
|
|
78
|
-
}
|
|
79
|
-
lme4_not_converged <- is_warning_generated(Model)
|
|
80
|
-
|
|
81
|
-
# convergence code by the optimizer
|
|
82
|
-
lme4l <- model_summary$optinfo$conv$lme4
|
|
83
|
-
if (length(lme4l) == 0) {
|
|
84
|
-
# the optimizer probably does not know
|
|
85
|
-
conv_code <- 0
|
|
86
|
-
} else if (is.null(lme4l$code)) {
|
|
87
|
-
# NULL means 0
|
|
88
|
-
conv_code <- 0
|
|
89
|
-
} else {
|
|
90
|
-
conv_code <- lme4l$code
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
cat("OUTPUT model converged:", (conv_code == 0) && !lme4_not_converged, "#*#\n")
|
|
94
|
-
cat("OUTPUT lme4 messages:", lme4l$optinfo$conv$lme4$messages, "#*#\n")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|