causarray 0.0.5__tar.gz → 0.0.6__tar.gz

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.
@@ -1,3 +1,6 @@
1
+ # Planning documents
2
+ plan/
3
+
1
4
  # Byte-compiled / optimized / DLL files
2
5
  __pycache__/
3
6
  *.py[cod]
@@ -160,5 +163,20 @@ cython_debug/
160
163
  #.idea/
161
164
 
162
165
 
163
- test*
166
+ # Generic module tests under tests/ ARE tracked (regression coverage for
167
+ # the causarray API). Exclude only benchmark / scratch files that are
168
+ # not part of the unit-test suite — add new exclusions here when
169
+ # benchmark or tutorial-coupled test files appear.
170
+ tests/benchmark_adamson.py
171
+
164
172
  causarray/___*.py
173
+ /docs/source/tutorial/adamson
174
+
175
+ # Replogle tutorial: large data files (regenerate with prep_tutorial_data.py or
176
+ # download from the project data repository; replogle_subset.h5ad is ~2 GB)
177
+ docs/source/tutorial/replogle/replogle_subset.h5ad
178
+ docs/source/tutorial/replogle/replogle_normed.h5ad
179
+ docs/source/tutorial/replogle/replogle_results.h5
180
+
181
+ # Unrelated tutorial directory (not part of causarray package docs)
182
+ docs/source/tutorial/scp/
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: causarray
3
- Version: 0.0.5
3
+ Version: 0.0.6
4
4
  Summary: causarray is a Python module for simultaneous causal inference with an array of outcomes.
5
- Author-email: Jin-Hong Du <jinhongd@andrew.cmu.com>, Maya Shen <myshen@andrew.cmu.edu>, Hansruedi Mathys <mathysh@pitt.edu>, Kathryn Roeder <jinhongd@andrew.cmu.com>
6
- Maintainer-email: Jin-Hong Du <jinhongd@andrew.cmu.com>
5
+ Author-email: Jin-Hong Du <jinhongd@hku.hk>, Maya Shen <myshen@andrew.cmu.edu>, Hansruedi Mathys <mathysh@pitt.edu>, Kathryn Roeder <jinhongd@hku.hk>
6
+ Maintainer-email: Jin-Hong Du <jinhongd@hku.hk>
7
7
  License: MIT License
8
8
  License-File: LICENSE
9
9
  Classifier: Intended Audience :: Developers
@@ -49,17 +49,44 @@ The module can be installed via PyPI:
49
49
  pip install causarray
50
50
  ```
51
51
 
52
+ For optimal parallel performance, we recommend installing `llvm-openmp` if using conda:
53
+ ```cmd
54
+ conda install -c conda-forge llvm-openmp
55
+ ```
56
+
52
57
  For `R` users, `reticulate` can be used to call `causarray` from `R`.
53
58
  The documentation and tutorials using both `Python` and `R` are available at [causarray.readthedocs.io](https://causarray.readthedocs.io/en/latest/).
54
59
 
55
60
 
56
61
 
57
- ## Logs
62
+ ## Batch fitting for large-scale screens
63
+
64
+ For screens with hundreds to thousands of perturbations, use the batch API
65
+ so that peak memory is bounded by one batch at a time:
66
+
67
+ ```python
68
+ from causarray import gcate_lfc_batch
69
+
70
+ df_res = gcate_lfc_batch(
71
+ Y, X, A, r,
72
+ batch_size=10, # perturbations per batch (or use n_batches= for a fixed count)
73
+ max_cells=2000, # max pert cells per batch (ctrl added on top)
74
+ n_ctrl=2000, # fixed ctrl subsample shared across batches
75
+ cache_path='results.h5', # resume if interrupted
76
+ verbose=True,
77
+ )
78
+ ```
79
+
80
+ See the [Replogle-E-K562 tutorial](https://causarray.readthedocs.io/en/latest/)
81
+ for a demonstration on 200 perturbations from a genome-wide CRISPRi screen.
82
+
83
+ ## Changelog
58
84
 
59
85
  - [x] (2025-01-30) Python package released on PyPI
60
- - [x] (2025-02-01) code for reproducing figures in paper
86
+ - [x] (2025-02-01) Code for reproducing figures in paper
61
87
  - [x] (2025-02-02) Tutorial for Python and R
62
- - [ ] Documentation
88
+ - [x] (2026-05-31) Batch fitting API (`gcate_lfc_batch`) for large-scale screens
89
+ - [x] (2026-05-31) Documentation at [causarray.readthedocs.io](https://causarray.readthedocs.io/en/latest/)
63
90
 
64
91
 
65
92
  <!--
@@ -24,17 +24,44 @@ The module can be installed via PyPI:
24
24
  pip install causarray
25
25
  ```
26
26
 
27
+ For optimal parallel performance, we recommend installing `llvm-openmp` if using conda:
28
+ ```cmd
29
+ conda install -c conda-forge llvm-openmp
30
+ ```
31
+
27
32
  For `R` users, `reticulate` can be used to call `causarray` from `R`.
28
33
  The documentation and tutorials using both `Python` and `R` are available at [causarray.readthedocs.io](https://causarray.readthedocs.io/en/latest/).
29
34
 
30
35
 
31
36
 
32
- ## Logs
37
+ ## Batch fitting for large-scale screens
38
+
39
+ For screens with hundreds to thousands of perturbations, use the batch API
40
+ so that peak memory is bounded by one batch at a time:
41
+
42
+ ```python
43
+ from causarray import gcate_lfc_batch
44
+
45
+ df_res = gcate_lfc_batch(
46
+ Y, X, A, r,
47
+ batch_size=10, # perturbations per batch (or use n_batches= for a fixed count)
48
+ max_cells=2000, # max pert cells per batch (ctrl added on top)
49
+ n_ctrl=2000, # fixed ctrl subsample shared across batches
50
+ cache_path='results.h5', # resume if interrupted
51
+ verbose=True,
52
+ )
53
+ ```
54
+
55
+ See the [Replogle-E-K562 tutorial](https://causarray.readthedocs.io/en/latest/)
56
+ for a demonstration on 200 perturbations from a genome-wide CRISPRi screen.
57
+
58
+ ## Changelog
33
59
 
34
60
  - [x] (2025-01-30) Python package released on PyPI
35
- - [x] (2025-02-01) code for reproducing figures in paper
61
+ - [x] (2025-02-01) Code for reproducing figures in paper
36
62
  - [x] (2025-02-02) Tutorial for Python and R
37
- - [ ] Documentation
63
+ - [x] (2026-05-31) Batch fitting API (`gcate_lfc_batch`) for large-scale screens
64
+ - [x] (2026-05-31) Documentation at [causarray.readthedocs.io](https://causarray.readthedocs.io/en/latest/)
38
65
 
39
66
 
40
67
  <!--
@@ -3,6 +3,7 @@ from sklearn.linear_model import LogisticRegression
3
3
  from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor
4
4
  from sklearn_ensemble_cv import reset_random_seeds, Ensemble, ECV
5
5
  from causarray.gcate_glm import fit_glm
6
+ import causarray.gcate_glm as _gcate_glm # module-qualified so _USE_FAST_BACKEND changes take effect at call time
6
7
  from causarray.utils import *
7
8
  from causarray.utils import _filter_params
8
9
  from joblib import Parallel, delayed
@@ -101,7 +102,19 @@ def cross_fitting(
101
102
  fit_pi = True if pi_hat is None else False
102
103
  pi_hat = np.zeros_like(A, dtype=float) if fit_pi else pi_hat
103
104
  fit_Y = True if Y_hat is None else False
104
- Y_hat = np.zeros((Y.shape[0],Y.shape[1],A.shape[1],2), dtype=float) if fit_Y else Y_hat
105
+ if fit_Y:
106
+ _yhat_gb = Y.shape[0] * Y.shape[1] * A.shape[1] * 2 * 8 / 1e9
107
+ _mem_limit_gb = kwargs.get('mem_limit_gb', None)
108
+ if _mem_limit_gb is not None and _yhat_gb > _mem_limit_gb:
109
+ import warnings
110
+ warnings.warn(
111
+ f"Y_hat allocation ({_yhat_gb:.1f} GB as float64) exceeds "
112
+ f"mem_limit_gb={_mem_limit_gb} GB; using float32 to halve peak memory.",
113
+ ResourceWarning, stacklevel=3,
114
+ )
115
+ Y_hat = np.zeros((Y.shape[0], Y.shape[1], A.shape[1], 2), dtype=np.float32)
116
+ else:
117
+ Y_hat = np.zeros((Y.shape[0], Y.shape[1], A.shape[1], 2), dtype=float)
105
118
 
106
119
  # perform ECV at once
107
120
  if fit_pi and ps_model == 'random_forest_cv':
@@ -145,9 +158,19 @@ def cross_fitting(
145
158
 
146
159
  if fit_Y:
147
160
  if verbose: pprint.pprint('Fit outcome models...')
161
+ # Subset offset to training fold (for fitting) and test fold (for
162
+ # imputation) when it is a pre-computed array, so that
163
+ # ``fit_glm_auto`` receives arrays with matching leading
164
+ # dimensions in both stages.
165
+ params_glm_fold = params_glm
166
+ offset_test_arr = None
167
+ if 'offset' in params_glm and isinstance(params_glm['offset'], np.ndarray):
168
+ params_glm_fold = dict(params_glm)
169
+ params_glm_fold['offset'] = params_glm['offset'][train_index]
170
+ offset_test_arr = params_glm['offset'][test_index]
148
171
  # Fit GLM on training data and predict on test data
149
- res = fit_glm(Y_train, X_train, A_train, family=family, alpha=glm_alpha,
150
- impute=X_test, **params_glm)
172
+ res = _gcate_glm.fit_glm_auto(Y_train, X_train, A_train, family=family, alpha=glm_alpha,
173
+ impute=X_test, offset_test=offset_test_arr, **params_glm_fold)
151
174
  Y_hat[test_index,:,:,0] = res[1][0]
152
175
  Y_hat[test_index,:,:,1] = res[1][1]
153
176
 
@@ -150,7 +150,7 @@ def fdx_control(
150
150
  return V
151
151
 
152
152
 
153
- def bh_correction(tvalues_init):
153
+ def bh_correction(tvalues_init, df=None):
154
154
  '''
155
155
  Perform BH correction.
156
156
 
@@ -179,7 +179,10 @@ def bh_correction(tvalues_init):
179
179
  qvals_adj = np.full(tvalues_init.shape, np.nan)
180
180
 
181
181
  if np.sum(idx) > 0:
182
- pvals[idx] = sp.stats.norm.sf(np.abs(tvalues_init[idx]))*2
182
+ if df is not None:
183
+ pvals[idx] = sp.stats.t.sf(np.abs(tvalues_init[idx]), df=df[idx]) * 2
184
+ else:
185
+ pvals[idx] = sp.stats.norm.sf(np.abs(tvalues_init[idx])) * 2
183
186
  qvals[idx] = multipletests(pvals[idx], alpha=0.05, method='fdr_bh')[1]
184
187
 
185
188
  # BH correction with empirical null adjustment
@@ -189,7 +192,10 @@ def bh_correction(tvalues_init):
189
192
  if mad>0:
190
193
  tvalues_init_adj = (tvalues_init - med) / mad
191
194
 
192
- pvals_adj[idx] = sp.stats.norm.sf(np.abs(tvalues_init_adj[idx]))*2
195
+ if df is not None:
196
+ pvals_adj[idx] = sp.stats.t.sf(np.abs(tvalues_init_adj[idx]), df=df[idx]) * 2
197
+ else:
198
+ pvals_adj[idx] = sp.stats.norm.sf(np.abs(tvalues_init_adj[idx])) * 2
193
199
  qvals_adj[idx] = multipletests(pvals_adj[idx], alpha=0.05, method='fdr_bh')[1]
194
200
 
195
201
  return pvals, qvals, pvals_adj, qvals_adj