Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@

* `senkin_tmp_train`, `senkin_tmp_predict`: Store the model bundle (the test predictions, as the solution is transductive) as an h5ad file in a directory instead of a pickle. The train image is built from `nvidia/cuda` with the current pandas 3, the predict image `openproblems/base_pytorch_nvidia:1` ships pandas 2, and unpickling the bundled `var` DataFrame raised `NotImplementedError` in `NDArrayBacked.__setstate__`, so senkin_tmp finished both CITE training runs of run_2026-09-23 but never produced a prediction. The predict step still reads the old pickle until the test resources are regenerated (PR #73).

* `novel`: Guard the TF-IDF and LSI of the ATAC input against cells without counts in the selected peaks. These turned into NaN, so the validation loss never improved, no model was saved and `novel_predict` failed with a missing `tensor.pt` on the multiome swap datasets (PR #76).

* `senkin_tmp_predict`: Compare the cell and protein names of the stored predictions as lists. The train and predict images run different pandas versions, so the same names were read back with a different index dtype and `Index.equals()` failed on every dataset (PR #75).

* `scipenn`: Exit 99 (non-applicable) instead of raising a `ValueError` on anything other than GEX -> ADT (PR #77).
Expand Down
10 changes: 7 additions & 3 deletions src/methods/novel/helper_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ def fit(self, X):
def transform(self, X):
if not self.fitted:
raise RuntimeError('Transformer was not fitted on any data')
row_sums = np.asarray(X.sum(axis=1)).reshape(-1, 1)
row_sums[row_sums == 0] = 1
if scipy.sparse.issparse(X):
tf = X.multiply(1 / X.sum(axis=1))
tf = X.multiply(1 / row_sums)
return tf.multiply(self.idf)
else:
tf = X / X.sum(axis=1, keepdims=True)
tf = X / row_sums
return tf * self.idf

def fit_transform(self, X):
Expand Down Expand Up @@ -75,7 +77,9 @@ def transform(self, adata):
X_norm = np.log1p(X_norm * 1e4)
X_lsi = self.pcaTransformer.transform(X_norm)
X_lsi -= X_lsi.mean(axis=1, keepdims=True)
X_lsi /= X_lsi.std(axis=1, ddof=1, keepdims=True)
X_lsi_std = X_lsi.std(axis=1, ddof=1, keepdims=True)
X_lsi_std[X_lsi_std == 0] = 1
X_lsi /= X_lsi_std
lsi_df = pd.DataFrame(X_lsi, index = adata_use.obs_names)
return lsi_df

Expand Down
Loading