File size: 1,720 Bytes
3f98d52 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | """Align raw study cohorts to shared gene identifiers before fitting PCA."""
import argparse
from pathlib import Path
import anndata as ad
p = argparse.ArgumentParser()
p.add_argument('--inputs', nargs='+', required=True)
p.add_argument('--output', required=True)
p.add_argument('--gene-columns', nargs='+', help='One var column per input. Use index for var_names.')
p.add_argument('--drop-ambiguous', action='store_true', help='Drop all duplicated gene identifiers')
a = p.parse_args()
cohorts = [ad.read_h5ad(f) for f in a.inputs]
if a.gene_columns and len(a.gene_columns) != len(cohorts): raise ValueError('Supply one gene-column choice per input')
for i, cohort in enumerate(cohorts):
field = a.gene_columns[i] if a.gene_columns else 'index'
if field != 'index':
if cohort.var[field].isna().any():
cohort = cohort[:, cohort.var[field].notna()].copy()
cohort.var_names = cohort.var[field].astype(str)
if not cohort.var_names.is_unique:
if not a.drop_ambiguous: raise ValueError('Duplicate gene identifiers. Use --drop-ambiguous to discard these genes.')
cohort = cohort[:, ~cohort.var_names.duplicated(keep=False)].copy()
cohorts[i] = cohort
shared = sorted(set.intersection(*(set(c.var_names) for c in cohorts)))
if len(shared) < 100:
raise ValueError('Fewer than 100 shared genes. Check identifier conventions.')
out = Path(a.output); out.mkdir(parents=True, exist_ok=True)
for i, (path, cohort) in enumerate(zip(a.inputs, cohorts)):
cohort[:, shared].copy().write_h5ad(out / f'{i}_{Path(path).stem}.h5ad', compression='gzip')
(out / 'genes.txt').write_text('\n'.join(shared)+'\n')
print(f'Aligned {len(cohorts)} cohorts on {len(shared)} genes')
|