Skip to content

Commit 5d9595e

Browse files
committed
For poisson.
1 parent 002aa28 commit 5d9595e

10 files changed

+248
-79
lines changed

diffxpy/testing/det.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -468,17 +468,17 @@ class DifferentialExpressionTestLRT(_DifferentialExpressionTestSingle):
468468

469469
sample_description: pd.DataFrame
470470
full_design_loc_info: patsy.design_info
471-
full_estim: glm.train.numpy.glm_base.Estimator
471+
full_estim: glm.train.base.BaseEstimatorGlm
472472
reduced_design_loc_info: patsy.design_info
473-
reduced_estim: glm.train.numpy.glm_base.Estimator
473+
reduced_estim: glm.train.base.BaseEstimatorGlm
474474

475475
def __init__(
476476
self,
477477
sample_description: pd.DataFrame,
478478
full_design_loc_info: patsy.design_info,
479-
full_estim: glm.train.numpy.glm_base.Estimator,
479+
full_estim: glm.train.base.BaseEstimatorGlm,
480480
reduced_design_loc_info: patsy.design_info,
481-
reduced_estim: glm.train.numpy.glm_base.Estimator
481+
reduced_estim: glm.train.base.BaseEstimatorGlm
482482
):
483483
super().__init__()
484484
self.sample_description = sample_description
@@ -1287,6 +1287,10 @@ def _assemble_gene_fits(
12871287
loc=loc,
12881288
scale=scale
12891289
)
1290+
elif self.noise_model == "poisson":
1291+
yhat = np.random.poisson(
1292+
lam=loc
1293+
)
12901294
else:
12911295
raise ValueError("noise model %s not yet supported for plot_gene_fits" % self.noise_model)
12921296

diffxpy/testing/tests.py

+3
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ def _fit(
138138
elif noise_model == "norm" or noise_model == "normal":
139139
from batchglm.train.numpy.glm_norm import Estimator
140140
from batchglm.models.glm_norm import Model
141+
elif noise_model == "poisson":
142+
from batchglm.train.numpy.glm_poisson import Estimator
143+
from batchglm.models.glm_poisson import Model
141144
else:
142145
raise ValueError('noise_model="%s" not recognized.' % noise_model)
143146
# Set default chunk size:

diffxpy/unit_test/test_acc_glm_all_numpy_temp.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def _test_full_model(self, noise_model):
4040
_ = temp.summary()
4141

4242
def test(self):
43-
for noise_model in ['norm', 'poisson', 'nb']:
43+
for noise_model in ['poisson', 'norm', 'nb']:
4444
self._test_full_model(noise_model)
4545

4646

diffxpy/unit_test/test_backends.py

+13-8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import scipy.stats as stats
66
from batchglm.models.glm_nb import Model as NBModel
77
from batchglm.models.glm_norm import Model as NormModel
8+
from batchglm.models.glm_poisson import Model as PoissonModel
89

910
import diffxpy.api as de
1011

@@ -34,6 +35,9 @@ def _test_null_distribution_wald(
3435
elif noise_model == "norm":
3536
model = NormModel()
3637
rand_fn_scale = lambda shape: np.random.uniform(1, 2, shape)
38+
elif noise_model == "poisson":
39+
model = PoissonModel()
40+
rand_fn_scale = lambda shape: np.random.uniform(1, 2, shape)
3741

3842

3943
model.generate_artificial_data(
@@ -69,13 +73,13 @@ def _test_null_distribution_wald(
6973
return True
7074

7175

72-
class TestSingleNullBackendsNb(_TestSingleNullBackends, unittest.TestCase):
76+
class TestSingleNullBackends(_TestSingleNullBackends, unittest.TestCase):
7377
"""
7478
Negative binomial noise model unit tests that test whether a test generates uniformly
7579
distributed p-values if data are sampled from the null model.
7680
"""
7781

78-
def test_null_distribution_wald_nb_numpy(
82+
def test_null_distribution_wald_numpy(
7983
self,
8084
n_cells: int = 2000,
8185
n_genes: int = 200
@@ -91,12 +95,13 @@ def test_null_distribution_wald_nb_numpy(
9195
logging.getLogger("diffxpy").setLevel(logging.WARNING)
9296

9397
np.random.seed(1)
94-
_ = self._test_null_distribution_wald(
95-
n_cells=n_cells,
96-
n_genes=n_genes,
97-
noise_model="nb",
98-
backend="numpy"
99-
)
98+
for noise_model in ['poisson', 'nb', 'norm']:
99+
_ = self._test_null_distribution_wald(
100+
n_cells=n_cells,
101+
n_genes=n_genes,
102+
noise_model="nb",
103+
backend="numpy"
104+
)
100105

101106

102107
if __name__ == '__main__':

diffxpy/unit_test/test_continuous_de.py

+25
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from batchglm.models.glm_nb import Model as NBModel
88
from batchglm.models.glm_norm import Model as NormModel
9+
from batchglm.models.glm_poisson import Model as PoissonModel
910

1011
class _TestContinuousDe:
1112
noise_model: str
@@ -24,6 +25,10 @@ def _test_wald_de(
2425
model = NormModel()
2526
rand_fn_loc = lambda shape: np.random.uniform(500, 1000, shape)
2627
rand_fn_scale = lambda shape: np.random.uniform(1, 2, shape)
28+
elif self.noise_model == "poisson":
29+
model = PoissonModel()
30+
rand_fn_loc = lambda shape: np.random.uniform(2, 10, shape)
31+
rand_fn_scale = None
2732
else:
2833
raise ValueError("noise model %s not recognized" % self.noise_model)
2934

@@ -142,6 +147,26 @@ def test_wald_de_norm(self):
142147
self._test_wald_de_all_splines(ngenes=100, constrained=True)
143148
return True
144149

150+
class TestContinuousDePoisson(_TestContinuousDe, unittest.TestCase):
151+
"""
152+
Normal noise model unit tests that tests false positive and false negative rates.
153+
"""
154+
155+
def test_wald_de_poisson(self):
156+
"""
157+
158+
:return:
159+
"""
160+
logging.getLogger("tensorflow").setLevel(logging.ERROR)
161+
logging.getLogger("batchglm").setLevel(logging.WARNING)
162+
logging.getLogger("diffxpy").setLevel(logging.WARNING)
163+
164+
self.noise_model = "poisson"
165+
np.random.seed(1)
166+
self._test_wald_de_all_splines(ngenes=100, constrained=False)
167+
self._test_wald_de_all_splines(ngenes=100, constrained=True)
168+
return True
169+
145170

146171
if __name__ == '__main__':
147172
unittest.main()

diffxpy/unit_test/test_fit.py

+77
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import diffxpy.api as de
77
from batchglm.models.glm_nb import Model as NBModel
88
from batchglm.models.glm_norm import Model as NormModel
9+
from batchglm.models.glm_poisson import Model as PoissonModel
910

1011
class _TestFit:
1112

@@ -31,6 +32,9 @@ def _test_model_fit(
3132
elif noise_model == "norm":
3233
model = NormModel()
3334
rand_fn_scale = lambda shape: np.random.uniform(1, 2, shape)
35+
elif noise_model == "poisson":
36+
model = PoissonModel()
37+
rand_fn_scale = lambda shape: np.random.uniform(1, 2, shape) # since it is called later but not used
3438
else:
3539
raise ValueError("noise model %s not recognized" % noise_model)
3640

@@ -126,6 +130,8 @@ def _test_residuals_fit(
126130
model = NBModel()
127131
elif noise_model == "norm":
128132
model = NormModel()
133+
elif noise_model == "poisson":
134+
model = PoissonModel()
129135
else:
130136
raise ValueError("noise model %s not recognized" % noise_model)
131137

@@ -294,6 +300,77 @@ def test_residuals_fit(
294300
noise_model="norm"
295301
)
296302

303+
class TestFitNorm(_TestFit, unittest.TestCase):
304+
"""
305+
Normal noise model unit tests that tests whether model fit relay works.
306+
"""
307+
308+
def test_model_fit(
309+
self,
310+
n_cells: int = 2000,
311+
n_genes: int = 2
312+
):
313+
"""
314+
Test if model fit for "norm" noise model works.
315+
316+
:param n_cells: Number of cells to simulate (number of observations per test).
317+
:param n_genes: Number of genes to simulate (number of tests).
318+
"""
319+
logging.getLogger("tensorflow").setLevel(logging.ERROR)
320+
logging.getLogger("batchglm").setLevel(logging.WARNING)
321+
logging.getLogger("diffxpy").setLevel(logging.WARNING)
322+
323+
np.random.seed(1)
324+
return self._test_model_fit(
325+
n_cells=n_cells,
326+
n_genes=n_genes,
327+
noise_model="poisson"
328+
)
329+
330+
def test_model_fit_partition(
331+
self,
332+
n_cells: int = 2000,
333+
n_genes: int = 2
334+
):
335+
"""
336+
Test if partitioned model fit for "norm" noise model works.
337+
338+
:param n_cells: Number of cells to simulate (number of observations per test).
339+
:param n_genes: Number of genes to simulate (number of tests).
340+
"""
341+
logging.getLogger("tensorflow").setLevel(logging.ERROR)
342+
logging.getLogger("batchglm").setLevel(logging.WARNING)
343+
logging.getLogger("diffxpy").setLevel(logging.WARNING)
344+
345+
np.random.seed(1)
346+
return self._test_model_fit_partition(
347+
n_cells=n_cells,
348+
n_genes=n_genes,
349+
noise_model="poisson"
350+
)
351+
352+
def test_residuals_fit(
353+
self,
354+
n_cells: int = 2000,
355+
n_genes: int = 2
356+
):
357+
"""
358+
Test if residual fit for "norm" noise model works.
359+
360+
:param n_cells: Number of cells to simulate (number of observations per test).
361+
:param n_genes: Number of genes to simulate (number of tests).
362+
"""
363+
logging.getLogger("tensorflow").setLevel(logging.ERROR)
364+
logging.getLogger("batchglm").setLevel(logging.WARNING)
365+
logging.getLogger("diffxpy").setLevel(logging.WARNING)
366+
367+
np.random.seed(1)
368+
return self._test_residuals_fit(
369+
n_cells=n_cells,
370+
n_genes=n_genes,
371+
noise_model="poisson"
372+
)
373+
297374

298375
if __name__ == '__main__':
299376
unittest.main()

diffxpy/unit_test/test_pairwise_null.py

+46-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import scipy.stats as stats
66
from batchglm.models.glm_nb import Model as NBModel
77
from batchglm.models.glm_norm import Model as NormModel
8+
from batchglm.models.glm_poisson import Model as PoissonModel
89

910
import diffxpy.api as de
1011

@@ -29,6 +30,10 @@ def _prepate_data(
2930
rand_fn_loc = lambda shape: np.random.uniform(500, 1000, shape)
3031
rand_fn_scale = lambda shape: np.random.uniform(1, 2, shape)
3132
model = NormModel()
33+
elif self.noise_model == "poisson":
34+
rand_fn_loc = lambda shape: np.random.uniform(2, 10, shape)
35+
rand_fn_scale = None
36+
model = PoissonModel()
3237
else:
3338
raise ValueError("noise model %s not recognized" % self.noise_model)
3439

@@ -109,7 +114,7 @@ def test_null_distribution_ttest(self):
109114
logging.getLogger("diffxpy").setLevel(logging.WARNING)
110115

111116
np.random.seed(1)
112-
self.noise_model = None
117+
self.noise_model = "norm"
113118
self._test_null_distribution_basic(test="t-test", lazy=False)
114119

115120
def test_null_distribution_rank(self):
@@ -118,9 +123,48 @@ def test_null_distribution_rank(self):
118123
logging.getLogger("diffxpy").setLevel(logging.WARNING)
119124

120125
np.random.seed(1)
121-
self.noise_model = None
126+
self.noise_model = "norm"
122127
self._test_null_distribution_basic(test="rank", lazy=False)
123128

129+
class TestPairwiseNullPoisson(unittest.TestCase, _TestPairwiseNull):
130+
131+
def test_null_distribution_ztest(self):
132+
logging.getLogger("tensorflow").setLevel(logging.ERROR)
133+
logging.getLogger("batchglm").setLevel(logging.WARNING)
134+
logging.getLogger("diffxpy").setLevel(logging.WARNING)
135+
136+
np.random.seed(1)
137+
self.noise_model = "poisson"
138+
self._test_null_distribution_basic(test="z-test", lazy=False, quick_scale=False)
139+
140+
def test_null_distribution_ztest_lazy(self):
141+
logging.getLogger("tensorflow").setLevel(logging.ERROR)
142+
logging.getLogger("batchglm").setLevel(logging.WARNING)
143+
logging.getLogger("diffxpy").setLevel(logging.WARNING)
144+
145+
np.random.seed(1)
146+
self.noise_model = "poisson"
147+
self._test_null_distribution_basic(test="z-test", lazy=True, quick_scale=False)
148+
149+
def test_null_distribution_wald(self):
150+
logging.getLogger("tensorflow").setLevel(logging.ERROR)
151+
logging.getLogger("batchglm").setLevel(logging.WARNING)
152+
logging.getLogger("diffxpy").setLevel(logging.WARNING)
153+
154+
np.random.seed(1)
155+
self.noise_model = "poisson"
156+
self._test_null_distribution_basic(test="wald", lazy=False, quick_scale=False)
157+
158+
def test_null_distribution_lrt(self):
159+
logging.getLogger("tensorflow").setLevel(logging.ERROR)
160+
logging.getLogger("batchglm").setLevel(logging.WARNING)
161+
logging.getLogger("diffxpy").setLevel(logging.WARNING)
162+
163+
np.random.seed(1)
164+
self.noise_model = "poisson"
165+
self._test_null_distribution_basic(test="lrt", lazy=False, quick_scale=False)
166+
167+
124168

125169
class TestPairwiseNullNb(unittest.TestCase, _TestPairwiseNull):
126170

0 commit comments

Comments
 (0)