xcell-rust 0.1.0

Pure-Rust port of xCell (Aran et al. 2017) cell-type enrichment — ssGSEA, spillover-corrected — validated for numeric parity against the R xCell package. Built on gsva-rust.
Documentation
//! The xCell pipeline entry point: `xCellAnalysis`.

use gsva::{EnrichmentResult, ExprMatrix};

use crate::data::XCellModel;
use crate::microenv::microenvironment_scores;
use crate::rawenrich::raw_enrichment;
use crate::spillover::spill_over;
use crate::transform::transform_scores;

/// Options for [`xcell_analysis`], mirroring the R `xCellAnalysis` arguments
/// that affect the numbers. Defaults match xCell 1.1.0: RNA-seq calibration,
/// scaling on, spillover `alpha = 0.5`.
#[derive(Debug, Clone)]
pub struct XCellParams {
    /// `rnaseq` in R: use the RNA-seq spill object (`true`, the default) or the
    /// microarray one (`false`).
    pub rnaseq: bool,
    /// `scale` in R: when `true` (default) `transformScores` divides by the
    /// per-cell-type calibration `V3`; when `false` it forces `V3 = 1`.
    pub scale: bool,
    /// `alpha` in R: the spillover compensation strength (default `0.5`).
    pub alpha: f64,
}

impl Default for XCellParams {
    fn default() -> Self {
        XCellParams {
            rnaseq: true,
            scale: true,
            alpha: 0.5,
        }
    }
}

/// Run the full xCell 1.1.0 pipeline on an expression matrix (genes × samples,
/// rows labelled by gene symbol): raw ssGSEA enrichment → per-cell-type
/// calibration → spillover compensation → microenvironment aggregate rows.
///
/// Returns the 64 cell-type scores plus `ImmuneScore`, `StromaScore`, and
/// `MicroenvironmentScore` (67 rows) × samples, matching R `xCellAnalysis` with
/// the same arguments.
pub fn xcell_analysis(
    expr: &ExprMatrix,
    model: &XCellModel,
    params: &XCellParams,
) -> EnrichmentResult {
    let spill = model.spill_for(params.rnaseq);
    let raw = raw_enrichment(expr, model);
    let transformed = transform_scores(&raw, spill, params.scale);
    let adjusted = spill_over(&transformed, spill, params.alpha);
    microenvironment_scores(&adjusted)
}