Metadata-Version: 2.4
Name: fascia
Version: 1.0.0
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Rust
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Dist: numpy>=1.23 ; extra == 'research'
Requires-Dist: pandas>=1.5 ; extra == 'research'
Requires-Dist: numpy>=1.23 ; extra == 'test'
Requires-Dist: pandas>=1.5 ; extra == 'test'
Requires-Dist: pytest>=7 ; extra == 'test'
Requires-Dist: mypy==2.3.0 ; extra == 'typing'
Requires-Dist: pandas-stubs==2.3.3.260113 ; extra == 'typing'
Requires-Dist: pyright==1.1.411 ; extra == 'typing'
Requires-Dist: typing-extensions>=4.6 ; extra == 'typing'
Provides-Extra: research
Provides-Extra: test
Provides-Extra: typing
License-File: LICENSE
Summary: Standalone joint scale, batch, latent-structure, and missing-value model for log-scale matrices.
Author: Fascia Contributors
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Issues, https://github.com/wenjiudaijiugui/fascia/issues
Project-URL: Releases, https://github.com/wenjiudaijiugui/fascia/releases
Project-URL: Repository, https://github.com/wenjiudaijiugui/fascia

# fascia

[![CI](https://img.shields.io/badge/CI-GitHub%20Actions-2088FF?logo=githubactions&logoColor=white)](https://github.com/wenjiudaijiugui/fascia/actions/workflows/ci.yml)
![Python](https://img.shields.io/badge/Python-%E2%89%A53.10-3776AB?logo=python&logoColor=white)
![License](https://img.shields.io/badge/license-MIT-blue)
[![Citation](https://img.shields.io/badge/citation-CITATION.cff-4c1)](CITATION.cff)

`fascia` 是一个面向单细胞蛋白质组 log2 定量矩阵的联合统计模型。它在同一框架中处理样本尺度、生物学条件、技术批次、细胞间残余结构、测量稳定性和缺失过程，目标是在校正测量与技术变化的同时，尽量保留研究设计所定义的生物学差异。

当前版本是实验性方法。输入应已完成上游鉴定、特征聚合、log2 转换和早期质量控制，但尚未进行正式归一化、批次校正或插补。

## 核心特点

以下五点是 Fascia 首先要解决的生物学分析问题。后续调用和输出说明都围绕这五点展开。

### 1. 联合建模，降低分步处理对生物学结论的影响

传统流程依次进行归一化、批次校正、降维和插补。每一步都会改变下一步看到的数据分布：归一化可能改变组间效应，批次校正可能改变细胞间距离，插补又可能改变差异蛋白和通路结果。因而，同一数据采用不同的处理顺序或中间矩阵，可能得到不同的生物学结论。

Fascia 同时处理样本尺度、生物学条件、技术批次、细胞间残余结构、测量稳定性和缺失过程，使这些相互依赖的部分基于同一组观测共同确定。它不能保证所有分析流程产生相同结论，但可以减少前一步处理结果被后一步当作确定真值所造成的累积偏差。

### 2. 考虑低强度蛋白更容易未检出

在单细胞蛋白质组中，一个空白格点不等于蛋白丰度为零，也不能直接解释为该蛋白在细胞中不存在。低丰度蛋白更容易未检出，而样本输入量、采集过程和数据处理也会使部分信号没有进入最终矩阵。

Fascia 将“是否检出”本身作为观测信息。对一个未检出的蛋白，预测不仅参考其他细胞中的同一蛋白、生物学条件和技术批次，也考虑该格点没有被观测到这一事实；同时允许部分较高丰度信号偶尔没有进入最终矩阵。这样可以减少把缺失值直接填成零值、总体平均值或固定低值所造成的假性组间差异。

### 3. 在技术校正过程中保护生物学信号

Fascia 从拟合开始就区分两类方向：实验条件、剂量和表型等生物学效应在输出中保留；样本制备分组、仪器和采集日期等技术效应在可估时从输出中删除。

因此，生物学信号不是在批次校正完成后再检查是否仍然存在，而是作为分析的一部分受到保护。若生物学条件与技术批次完全混杂，数据本身无法区分二者，Fascia 会拒绝该设计，而不是给出无法解释的校正结果。

### 4. 保留尚未被实验设计解释的细胞异质性

细胞之间常存在实验设计尚未完全解释的协同蛋白变化，例如连续细胞状态、应激响应或潜在亚群。无监督校正可能把主要变化方向直接解释为技术因素，从而压缩真实的细胞异质性。

Fascia 不会把实验设计尚未解释的主要细胞差异自动归入批次并从数据中删除，而是保留蛋白在细胞间共同变化的模式，并让这些模式参与缺失值预测。它们是否对应真实细胞状态，仍需通过表型关联、生物学个体之间的重复和独立实验进行验证。

### 5. 只重建数据能够支持的缺失值

低强度观测和缺失值预测通常比清晰检出的蛋白定量更不稳定。如果为了得到完整矩阵而补齐所有空白，这些高不确定性数值可能继续进入差异蛋白、细胞聚类和通路分析，并被误认为与实测值具有同等证据。

Fascia 只在现有观测能够支持相应生物学和技术效应、预测不确定性处于合理范围且结果没有明显超出原始数据范围时重建缺失值。其余位置继续保持 `NaN`，并说明未重建的原因，使下游分析能够区分实测值、数据支持的预测值和当前实验无法可靠恢复的缺失值。

## Python 调用

正式版本发布到 PyPI 后，可安装带表格接口依赖的包：

```bash
python -m pip install "fascia[research]"
```

也可以安装与系统和 Python 版本匹配的预编译安装包（wheel）：

```bash
python -m pip install /path/to/fascia-*.whl
python -m pip install numpy pandas
```

支持 Python 3.10 及以上版本。下面的示例假定定量表以特征为行、样本为列，因此使用 `samples_axis="columns"`；实验设计表仍是每行一个样本：

```python
import pandas as pd
import fascia

matrix = pd.read_csv("protein_log2.tsv", sep="\t", index_col=0)
design = pd.read_csv("design.tsv", sep="\t")

preflight = fascia.inspect_table(
    matrix,
    samples_axis="columns",
    # anchor_features=["spike_001", "spike_002"],  # 实验参考特征
)
print(preflight.format())

result = fascia.fit_table(
    matrix,
    design,
    samples_axis="columns",
    sample_id_column="sample_id",
    batch=["sample_preparation", "instrument"],
    condition=["condition", "genotype"],
    continuous_condition=["dose"],
    # anchor_features=["spike_001", "spike_002"],
    # use_detection_curve=True,
    # use_intensity_variance=True,
)

print(result.report())
result.require_usable()

result.values.to_csv("fascia_values.tsv", sep="\t")
result.cell_status_labels.to_csv("fascia_cell_status.tsv", sep="\t")
result.uncertainty.to_csv("fascia_uncertainty.tsv", sep="\t")
result.observation_variance.to_csv("fascia_observation_variance.tsv", sep="\t")
```

`fit_table` 会根据样本 ID 对齐矩阵与实验设计，不依赖两张表当前的行列顺序；返回的带标签矩阵统一以样本为行、特征为列。没有标签的样本 × 特征矩阵可以使用 `fascia.fit`。

## 数据与实验设计

### 定量矩阵

- `fit_table` 同时接受两种方向：特征 × 样本表使用 `samples_axis="columns"`，样本 × 特征表使用默认的 `samples_axis="rows"`；进入拟合前都会统一为样本 × 特征。
- 有限值表示可分析观测，`NaN` 表示缺失；`Inf/-Inf` 会被拒绝。
- 默认输入尺度是 log2。线性强度必须显式指定 `input_scale="linear"`。
- 不应预先进行正式归一化、批次校正或插补，否则原始样本尺度和缺失指示已经被改变。

### 生物学与技术变量

- `condition` 和 `continuous_condition` 表示需要保留的分类或连续生物学方向；
- `batch` 表示需要从输出删除的离散技术因素，例如样本制备分组、仪器或采集日期；
- 多个变量以加性主效应进入分析，交互项需要根据研究问题显式构造；
- 生物学条件与技术批次完全混杂时，数据本身无法区分二者，Fascia 会拒绝该设计。

在研究设计和下游统计推断中，生物学个体应作为独立生物重复，细胞是嵌套于生物学个体的生物学子样本，样本制备分组属于技术批次。Fascia 负责矩阵层面的校正和缺失条件预测，不应把同一生物学个体中的细胞数量当作独立重复数。

如果实验包含可靠的外加标准品（spike-in）、稳定参考特征、质量控制特征或负对照特征，可以通过 `anchor_features` 提供载荷约束的参考集（`Q.T @ w = 0`）。样本尺度仍使用所有参与似然的单元估计，不只使用参考特征；参考集不能替代通过 `condition` 明确指定需要保留的生物学方向。

## 建议的分析策略

首次拟合使用默认设置。随后可以分别令 `use_detection_curve=True` 和 `use_intensity_variance=True`，检查研究结论是否受到两项单细胞蛋白质组测量特征的影响：低强度蛋白更容易未检出，以及低强度观测可能具有不同的测量稳定性。开启选项不代表当前矩阵一定存在相应关系。

比较不同拟合时，应同时检查：

- 需要保留的生物学对比效应量是否稳定；
- 生物学个体之间是否能够重复；
- 独立细胞表型预测是否稳定；
- 预先登记的通路结论是否重复；
- `detection_mode`、`variance_mode`、警告和缺失预测覆盖范围是否发生变化。

## 结果解释

| 输出 | 生物学解释 |
| --- | --- |
| `values` | 校正后的实测值，以及数据支持的缺失条件均值 |
| `cell_status_labels` | 每个格点是实测、预测、不可估，还是因不确定性或范围原因继续缺失 |
| `technical_effect` | 从输出中删除的技术变化 |
| `structural_mean` | 保留生物学条件和细胞间残余结构后的条件均值 |
| `selection_shift` | 强度相关未检出对缺失条件均值造成的位移 |
| `feature_variance` | 每个特征在参考强度处的条件残差方差 |
| `observation_variance` | 最终逐样本、逐特征的条件残差方差 |
| `uncertainty` | 缺失预测的条件残差方差与因子预测方差 |
| `correction_variance` | 技术校正线性效应的近似方差 |

`uncertainty`、`observation_variance` 和 `correction_variance` 表示不同来源的不确定性，不能直接相加后解释为完整参数后验方差。下游分析应结合 `cell_status_labels` 区分实测值和预测值，而不是把全部有限输出视为同等证据。

`result.values` 始终保存确定性的实测校正值与缺失条件均值。`result.realization(index)` 按 `seed + index` 对允许插补的格点进行固定参数条件抽样；即使 `n_realizations=1`，`realization(0)` 也是抽样，不是 `values` 的别名。CLI 默认会额外写出 `.realization_001.tsv` 文件。

## 方法边界

- 完全混杂的实验设计不能通过统计校正恢复；
- 没有可靠生物学设计或尺度参考时，全特征同步生物学变化可能与样本尺度难以区分；
- 未被实验设计解释的协同变化不自动等同于生物学；
- 强度相关缺失只表示低丰度信号更容易未检出，不能区分蛋白确实不存在、鉴定失败或其他未观测原因；
- 强度相关方差只描述处理后 log2 强度的测量稳定性变化，不能替代对重尾离群或信号干扰的处理；
- Fascia 不是层级生物学推断方法。差异分析、表型关联和通路推断仍应以生物学个体为独立重复单位。

## 构建与发布

维护者配置和发布步骤见 [PyPI 发布指南](https://github.com/wenjiudaijiugui/fascia/blob/main/.github/RELEASING.md)。手动运行 `wheels` 工作流只检查产物；版本标签 push 在全部检查通过后发布到 PyPI 和 GitHub Release。

## 本地研究文档

以下文件仅在研究工作区保留，不随 GitHub 源码或发行包发布：

- 算法原理：`docs/method.md`
- 论文研究流程：`docs/research_workflow.md`
- 论文正文与真实数据结果：`docs/manuscript.md`

发表分析时应报告软件版本或提交版本（commit）、输入尺度、实验设计变量、实际参考批次、主要拟合参数、警告、缺失预测覆盖范围，以及是否进行了强度相关缺失和强度相关方差敏感性分析。

许可协议：MIT。

