@@ -39,6 +39,31 @@ def _fit_continuous(
3939 )
4040 return test
4141
42+ def _fit_continuous_interaction (
43+ self ,
44+ sim ,
45+ sample_description ,
46+ constrained ,
47+ test ,
48+ spline_basis
49+ ):
50+ test = de .test .continuous_1d (
51+ data = sim .input_data ,
52+ sample_description = sample_description ,
53+ gene_names = ["gene" + str (i ) for i in range (sim .input_data .num_features )],
54+ formula_loc = "~ 1 + continuous + batch + continuous:batch" ,
55+ formula_scale = "~ 1" ,
56+ factor_loc_totest = ["continuous" , "continuous:batch" ],
57+ continuous = "continuous" ,
58+ size_factors = "size_factors" ,
59+ df = 3 ,
60+ spline_basis = spline_basis ,
61+ test = test ,
62+ quick_scale = True ,
63+ noise_model = self .noise_model
64+ )
65+ return test
66+
4267 def _test_basic (
4368 self ,
4469 ngenes : int ,
@@ -67,6 +92,34 @@ def _test_basic(
6792 )
6893 return det
6994
95+ def _test_interaction (
96+ self ,
97+ ngenes : int ,
98+ test : str ,
99+ constrained : bool ,
100+ spline_basis : str
101+ ):
102+ n_timepoints = 5
103+ sim = Simulator (num_observations = n_timepoints * 200 , num_features = ngenes )
104+ sim .generate_sample_description (num_batches = 0 , num_conditions = 0 )
105+ sim .generate_params ()
106+ sim .generate_data ()
107+
108+ random_sample_description = pd .DataFrame ({
109+ "continuous" : np .asarray (np .random .randint (0 , n_timepoints , size = sim .nobs ), dtype = float )
110+ })
111+ random_sample_description ["batch" ] = [str (np .random .randint (0 , 3 ))
112+ for x in random_sample_description ["continuous" ]]
113+ random_sample_description ["size_factors" ] = np .random .uniform (0.9 , 1.1 , sim .nobs ) # TODO put into simulation.
114+ det = self ._fit_continuous_interaction (
115+ sim = sim ,
116+ sample_description = random_sample_description ,
117+ test = test ,
118+ constrained = constrained ,
119+ spline_basis = spline_basis ,
120+ )
121+ return det
122+
70123 def _test_null_model (
71124 self ,
72125 ngenes : int ,
@@ -82,6 +135,21 @@ def _test_null_model(
82135 )
83136 return self ._eval (det = det )
84137
138+ def _test_null_model_interaction (
139+ self ,
140+ ngenes : int ,
141+ test : str ,
142+ constrained : bool ,
143+ spline_basis : str
144+ ):
145+ det = self ._test_interaction (
146+ ngenes = ngenes ,
147+ test = test ,
148+ constrained = constrained ,
149+ spline_basis = spline_basis
150+ )
151+ return self ._eval (det = det )
152+
85153 def _eval (self , det ):
86154 pval_h0 = stats .kstest (det .pval , 'uniform' ).pvalue
87155 logging .getLogger ("diffxpy" ).info (
@@ -145,6 +213,15 @@ def _test_null_model_all_splines(
145213 for x in ["bs" , "cr" , "cc" ]:
146214 self ._test_null_model (ngenes = ngenes , test = test , constrained = constrained , spline_basis = x )
147215
216+ def _test_null_model_all_splines_interaction (
217+ self ,
218+ ngenes : int ,
219+ test : str ,
220+ constrained : bool
221+ ):
222+ for x in ["bs" , "cr" , "cc" ]:
223+ self ._test_null_model_interaction (ngenes = ngenes , test = test , constrained = constrained , spline_basis = x )
224+
148225
149226class TestContinuousNb (_TestContinuous , unittest .TestCase ):
150227
@@ -203,7 +280,8 @@ def test_null_distribution_wald_unconstrained(self):
203280
204281 self .noise_model = "nb"
205282 np .random .seed (1 )
206- self ._test_null_model_all_splines (ngenes = 100 , test = "wald" , constrained = False )
283+ #self._test_null_model_all_splines(ngenes=100, test="wald", constrained=False)
284+ self ._test_null_model_all_splines_interaction (ngenes = 100 , test = "wald" , constrained = False )
207285 return True
208286
209287 def test_null_distribution_wald_constrained (self ):
@@ -223,6 +301,7 @@ def test_null_distribution_wald_constrained(self):
223301 self .noise_model = "nb"
224302 np .random .seed (1 )
225303 self ._test_null_model_all_splines (ngenes = 100 , test = "wald" , constrained = True )
304+ # Interaction not supported yet.
226305 return True
227306
228307 def _test_null_distribution_lrt (self ):
0 commit comments