news 2026/10/2 16:35:40

从细胞清单到空间生态位:PCF与单细胞测序联合分析能解决什么问题?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从细胞清单到空间生态位:PCF与单细胞测序联合分析能解决什么问题?

1. 从细胞清单到空间生态位:单细胞测序与 PCF 联合分析到底解决什么问题

单细胞测序和 PCF(Phenocycler-Fusion,空间单细胞蛋白组)联合分析,本质上是把“细胞发现”和“组织原位观察”两件事接在一起。单细胞测序从细胞悬液里解析细胞类型、转录状态和亚群差异,适合建立细胞图谱;PCF 则把这些细胞群重新放回组织切片,在蛋白层面观察细胞身份、细胞状态、空间位置和邻近关系。对于肿瘤组织微环境这类高度结构化的研究对象,只有知道细胞有哪些还不够,研究者还需要理解这些细胞如何在局部组织中组成空间生态系统。

这个方向适合谁?如果你正在做肿瘤免疫微环境、组织图谱、TLS 相关空间结构、T 细胞功能状态、巨噬细胞/树突状细胞抗原呈递状态、肿瘤-免疫细胞邻近关系等课题,并且手里同时有单细胞转录组和 CODEX/空间蛋白组数据,那这套联合分析路径就是为你准备的。它回答的核心问题是:单细胞测序告诉你“有哪些细胞、有哪些转录状态”,PCF 告诉你“这些细胞在组织中处于什么位置、表达哪些蛋白、与哪些细胞形成邻域”。两者结合,研究视角才能从“细胞比例差异”走向“空间组织方式差异”。

我试过把单细胞和空间蛋白组数据放在一起看,最直观的感受是:单细胞给出的细胞亚群清单,如果不落到组织坐标上,很多空间关系是看不出来的。比如单细胞测序提示某类 T 细胞亚群扩增,但它在组织里是散在分布还是聚集成区,和哪些髓系细胞相邻,这些信息只有空间蛋白组能补上。PCF 通过多重抗体 Panel 和空间算法,让单细胞提示的候选细胞群进入组织原位蛋白层分析,而不是简单把单细胞结果做成一张图。

从技术落地角度看,联合分析要解决三个层面的问题。第一层是数据整合:单细胞测序的细胞清单和 PCF 的空间坐标怎么映射到同一套细胞类型标签上。第二层是空间对齐:CODEX/空间单细胞蛋白组数据怎么和单细胞转录组数据在细胞身份层面做对应。第三层是结果一致性检查:怎么判断联合方案是否适用于自身课题,避免把技术噪声当成生物学发现。

这篇内容会交付可复制的数据整合配置与验证动作,包括细胞清单到空间坐标的映射流程、CODEX/空间单细胞蛋白组数据对齐步骤,以及结果一致性检查清单。需要说明的是,本文仅为科研技术方法介绍,不涉及疾病诊断、治疗建议、疗效预测、用药指导或临床决策。文中提及研究发现均来自学术文献,相关分析结果需结合更多实验和研究进一步观察与复核,不构成任何医疗意见。

2. TaoToken 前置准备:API Key 与 Coding Plan 怎么选

在开始写联合分析脚本之前,先把模型调用环境准备好。TaoToken 提供统一的 API 入口,官网是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 地址是 https://taotoken.net/api 。如果你只是偶尔验证模型输出,用 API Key 按量调用就够了;如果你要长期跑编码类 Agent 任务,比如让模型帮你写数据整合脚本、生成配置片段、排查报错,那 Coding Plan 更合适。

先拿 API Key。进入控制台页面 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,在 API Keys 管理页新建一个 Key。建议按项目命名,比如pcf-sc-spatial,方便后续区分。拿到 Key 之后,不要直接写进代码里,先放到环境变量:

export TAOTOKEN_API_KEY="sk-你的实际Key" export TAOTOKEN_BASE_URL="https://taotoken.net/api"

如果你用的是 Claude Code 这类编码工具,需要配置三件套:Base URL、Key、Model ID。Base URL 填https://taotoken.net/api,Key 填刚才生成的,Model ID 根据你订阅的模型填。Claude Code 的接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,里面有完整的配置示例。

对于长期编码和 Agent 任务,建议直接上 Coding Plan,入口在 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。Coding Plan 的好处是额度稳定,适合反复调试数据整合脚本、跑多轮验证请求。如果你只是临时验证某个模型输出,用模型对话页面 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite 就够了,不用写代码。

这里有个坑要注意:Base URL 末尾不要多加/v1或者斜杠,不同工具对路径拼接的处理不一样。我实测下来,Claude Code 和 Cline 都直接用https://taotoken.net/api作为 Base URL,模型 ID 按文档里列出的填。如果你在 Cline 里配 MCP,MCP 的配置和模型调用是两套东西,不要混在一起。

另外,API Key 不要提交到 Git 仓库。建议用.env文件加.gitignore,或者在 CI 里用 secrets 管理。如果你在本地跑脚本,可以用python-dotenv加载:

from dotenv import load_dotenv import os load_dotenv() api_key = os.getenv("TAOTOKEN_API_KEY") base_url = os.getenv("TAOTOKEN_BASE_URL")

环境准备好之后,就可以开始写数据整合配置了。下一节会给出可复制的 JSON/TOML/settings 片段,以及细胞清单到空间坐标的映射流程。

3. 可复制配置:细胞清单到空间坐标的映射流程

这一节给出可复制的配置片段和映射流程。假设你手里有两份数据:一份是单细胞测序的细胞清单(cell metadata,包含细胞类型注释、转录状态标签),另一份是 PCF/CODEX 的空间蛋白组数据(包含细胞坐标、蛋白表达矩阵、细胞分割结果)。目标是把单细胞的细胞类型标签映射到空间坐标上,形成“空间生态位”分析的基础表。

先建一个项目目录结构:

mkdir -p pcf-sc-spatial/{config,data,scripts,output} cd pcf-sc-spatial

配置文件用 TOML 写,路径和原文一致。新建config/integration.toml:

[input] sc_metadata = "data/sc_metadata.csv" sc_expression = "data/sc_expression.h5ad" pcf_coordinates = "data/pcf_cell_coordinates.csv" pcf_protein = "data/pcf_protein_matrix.csv" pcf_segmentation = "data/pcf_segmentation_mask.tiff" [output] merged_table = "output/merged_cell_spatial.csv" district_table = "output/spatial_districts.csv" qc_report = "output/qc_report.json" [mapping] # 单细胞细胞类型标签列名 sc_label_col = "cell_type" # PCF 细胞类型标签列名 pcf_label_col = "cell_type_pcf" # 空间坐标列名 x_col = "x" y_col = "y" # 最小细胞数阈值,低于此值的细胞类型不参与映射 min_cell_count = 10 [spatial] # 邻域半径,单位与坐标一致 neighbor_radius = 50 # 空间 district 聚类数 n_districts = 12 # 随机种子 random_seed = 42

如果你用 JSON 格式,等价配置如下:

{ "input": { "sc_metadata": "data/sc_metadata.csv", "sc_expression": "data/sc_expression.h5ad", "pcf_coordinates": "data/pcf_cell_coordinates.csv", "pcf_protein": "data/pcf_protein_matrix.csv", "pcf_segmentation": "data/pcf_segmentation_mask.tiff" }, "output": { "merged_table": "output/merged_cell_spatial.csv", "district_table": "output/spatial_districts.csv", "qc_report": "output/qc_report.json" }, "mapping": { "sc_label_col": "cell_type", "pcf_label_col": "cell_type_pcf", "x_col": "x", "y_col": "y", "min_cell_count": 10 }, "spatial": { "neighbor_radius": 50, "n_districts": 12, "random_seed": 42 } }

接下来写映射脚本。核心思路是:先用单细胞数据建立细胞类型标签体系,再把 PCF 的细胞类型标签对齐到同一套体系上,最后按空间坐标合并。新建scripts/map_cells.py:

import pandas as pd import numpy as np import json import toml # 读取配置 config = toml.load("config/integration.toml") # 读取单细胞 metadata sc_meta = pd.read_csv(config["input"]["sc_metadata"]) print(f"单细胞细胞数: {len(sc_meta)}") print(f"单细胞细胞类型: {sc_meta[config['mapping']['sc_label_col']].nunique()}") # 读取 PCF 坐标和蛋白矩阵 pcf_coord = pd.read_csv(config["input"]["pcf_coordinates"]) pcf_protein = pd.read_csv(config["input"]["pcf_protein_matrix"]) print(f"PCF 细胞数: {len(pcf_coord)}") # 按最小细胞数过滤单细胞类型 label_counts = sc_meta[config["mapping"]["sc_label_col"]].value_counts() valid_labels = label_counts[label_counts >= config["mapping"]["min_cell_count"]].index.tolist() sc_meta = sc_meta[sc_meta[config["mapping"]["sc_label_col"]].isin(valid_labels)] print(f"过滤后单细胞类型数: {len(valid_labels)}") # 建立标签映射表 label_map = {label: idx for idx, label in enumerate(valid_labels)} sc_meta["label_id"] = sc_meta[config["mapping"]["sc_label_col"]].map(label_map) # 合并 PCF 坐标和蛋白矩阵 pcf_merged = pcf_coord.merge(pcf_protein, on="cell_id", how="inner") print(f"PCF 合并后细胞数: {len(pcf_merged)}") # 按空间坐标合并单细胞标签(这里用最近邻映射,实际项目可用更复杂的标签转移方法) # 简化示例:假设 PCF 的 cell_type_pcf 已经和单细胞标签对齐 pcf_merged["label_id"] = pcf_merged[config["mapping"]["pcf_label_col"]].map(label_map) # 输出合并表 pcf_merged.to_csv(config["output"]["merged_table"], index=False) print(f"合并表已输出: {config['output']['merged_table']}") # 输出 QC 报告 qc = { "sc_cell_count": int(len(sc_meta)), "pcf_cell_count": int(len(pcf_merged)), "valid_label_count": int(len(valid_labels)), "unmapped_pcf_cells": int(pcf_merged["label_id"].isna().sum()) } with open(config["output"]["qc_report"], "w") as f: json.dump(qc, f, indent=2) print(f"QC 报告已输出: {config['output']['qc_report']}")

这个脚本跑完之后,你会得到一张合并表,包含 PCF 细胞的坐标、蛋白表达和映射后的单细胞标签。接下来做空间邻域分析,计算每个细胞的邻域细胞类型组成,再用聚类方法识别空间 district。新建scripts/spatial_district.py:

import pandas as pd import numpy as np from sklearn.neighbors import NearestNeighbors from sklearn.cluster import KMeans import toml config = toml.load("config/integration.toml") merged = pd.read_csv(config["output"]["merged_table"]) # 提取坐标 coords = merged[[config["mapping"]["x_col"], config["mapping"]["y_col"]]].values # 找邻域 nn = NearestNeighbors(radius=config["spatial"]["neighbor_radius"]) nn.fit(coords) distances, indices = nn.radius_neighbors(coords) # 计算每个细胞的邻域细胞类型组成 label_ids = merged["label_id"].fillna(-1).astype(int).values n_labels = label_ids.max() + 1 neighbor_composition = np.zeros((len(merged), n_labels)) for i, neighbors in enumerate(indices): for j in neighbors: if j != i: neighbor_composition[i, label_ids[j]] += 1 # 归一化 row_sums = neighbor_composition.sum(axis=1, keepdims=True) row_sums[row_sums == 0] = 1 neighbor_composition = neighbor_composition / row_sums # 聚类成空间 district kmeans = KMeans(n_clusters=config["spatial"]["n_districts"], random_state=config["spatial"]["random_seed"]) districts = kmeans.fit_predict(neighbor_composition) merged["district"] = districts merged.to_csv(config["output"]["district_table"], index=False) print(f"空间 district 已输出: {config['output']['district_table']}") print(f"District 分布:\n{merged['district'].value_counts().sort_index()}")

这两个脚本跑完,你就有了从细胞清单到空间坐标的完整映射,以及空间 district 的划分结果。下一节会讲怎么验证请求和检查结果一致性。

4. 验证请求与成功结果:CODEX/空间单细胞蛋白组数据对齐检查

配置和脚本写完之后,不要直接跑完整分析,先做小规模验证。验证的目标是确认三件事:API 调用是否正常、数据对齐是否合理、结果是否可复现。先写一个验证脚本,调用模型帮你检查配置文件的字段是否完整。新建scripts/validate_config.py:

import toml import json import requests import os config = toml.load("config/integration.toml") # 检查必填字段 required_fields = { "input": ["sc_metadata", "pcf_coordinates", "pcf_protein"], "output": ["merged_table", "district_table", "qc_report"], "mapping": ["sc_label_col", "pcf_label_col", "x_col", "y_col"], "spatial": ["neighbor_radius", "n_districts", "random_seed"] } missing = [] for section, fields in required_fields.items(): for field in fields: if field not in config.get(section, {}): missing.append(f"{section}.{field}") if missing: print(f"缺失字段: {missing}") else: print("配置字段完整") # 调用模型验证配置语义 api_key = os.getenv("TAOTOKEN_API_KEY") base_url = os.getenv("TAOTOKEN_BASE_URL") prompt = f"""请检查以下空间单细胞蛋白组联合分析配置是否合理: {json.dumps(config, indent=2)} 重点检查: 1. 邻域半径是否适合组织切片坐标尺度 2. 聚类数是否与预期 district 数量匹配 3. 最小细胞数阈值是否合理 请用中文回答,给出具体建议。""" response = requests.post( f"{base_url}/v1/chat/completions", headers={"Authorization": f"Bearer {api_key}"}, json={ "model": "claude-sonnet-4-20250514", "messages": [{"role": "user", "content": prompt}], "max_tokens": 1000 } ) if response.status_code == 200: result = response.json() print(result["choices"][0]["message"]["content"]) else: print(f"请求失败: {response.status_code}") print(response.text)

跑这个脚本之前,确认环境变量已经设置好。如果返回 200 并且模型给出了配置建议,说明 API 调用正常。如果返回 401,检查 Key 是否正确;如果返回local proxy failed,检查 Base URL 是否写成了https://taotoken.net/api而不是其他地址。

接下来做数据对齐验证。核心检查项包括:单细胞和 PCF 的细胞类型标签是否在同一套体系下、空间坐标是否有重叠、蛋白表达矩阵是否有缺失值。新建scripts/check_alignment.py:

import pandas as pd import numpy as np import json merged = pd.read_csv("output/merged_cell_spatial.csv") # 检查 1:标签映射率 total_cells = len(merged) mapped_cells = merged["label_id"].notna().sum() mapping_rate = mapped_cells / total_cells print(f"标签映射率: {mapping_rate:.2%}") # 检查 2:坐标范围 x_range = merged["x"].max() - merged["x"].min() y_range = merged["y"].max() - merged["y"].min() print(f"X 坐标范围: {x_range:.2f}") print(f"Y 坐标范围: {y_range:.2f}") # 检查 3:蛋白表达缺失值 protein_cols = [c for c in merged.columns if c.startswith("protein_")] missing_rate = merged[protein_cols].isna().mean().mean() print(f"蛋白表达平均缺失率: {missing_rate:.2%}") # 检查 4:district 分布 district_counts = merged["district"].value_counts() print(f"District 数量: {len(district_counts)}") print(f"最小 district 细胞数: {district_counts.min()}") print(f"最大 district 细胞数: {district_counts.max()}") # 输出检查报告 report = { "mapping_rate": float(mapping_rate), "x_range": float(x_range), "y_range": float(y_range), "protein_missing_rate": float(missing_rate), "n_districts": int(len(district_counts)), "min_district_size": int(district_counts.min()), "max_district_size": int(district_counts.max()) } with open("output/alignment_check.json", "w") as f: json.dump(report, f, indent=2) print("对齐检查报告已输出: output/alignment_check.json")

成功结果应该满足:标签映射率高于 80%,坐标范围与组织切片尺寸一致,蛋白表达缺失率低于 10%,district 数量与配置一致且每个 district 细胞数不低于 50。如果映射率偏低,检查单细胞和 PCF 的细胞类型标签命名是否一致;如果坐标范围异常,检查坐标单位是否统一。

验证通过之后,你可以用模型对话页面 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite 快速问一些结果解读问题,比如“B 细胞主导的 district 和 T 细胞富集 district 在空间上是否相邻”。这种快速验证不需要写代码,适合在正式分析前做假设检查。

5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth

这一节对照真实报错,给出排查路径。如果你在跑上面的脚本时遇到问题,先看这里。

401 Unauthorized:最常见的原因是 API Key 没设置或者设置错了。检查echo $TAOTOKEN_API_KEY是否有输出,确认 Key 没有多余空格。如果你用的是 Claude Code,检查 settings 文件里的 Key 字段是否和生成的一致。另外,Key 可能过期或者被删除,去控制台 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 确认 Key 状态。

local proxy failed:这个报错通常出现在 Base URL 配置错误的时候。检查你的 Base URL 是不是https://taotoken.net/api,不要写成https://taotoken.net/api/v1或者带末尾斜杠。如果你在 Cline 里配 MCP,MCP 的配置和模型调用是分开的,MCP 的 Base URL 也要用同一个地址。另外,检查本地网络是否能正常访问该地址,可以用curl -I https://taotoken.net/api测试。

reading choices 报错:这个报错说明请求返回了非预期格式。常见原因是模型 ID 写错了,或者请求体里messages格式不对。检查模型 ID 是否在文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 里列出,请求体里messages必须是数组,每个元素有role和content。如果你用的是 Claude Code,检查 settings 里的模型 ID 是否和订阅的模型匹配。

OAuth 相关报错:如果你在 Claude Code 里用 OAuth 登录,但报错提示认证失败,检查是不是同时配了 API Key 和 OAuth。建议二选一,用 API Key 的方式更稳定。Claude Code 的接入文档里有完整的认证配置示例,按文档走一遍。如果你在 Codex 里用auth.json,检查文件路径和字段名是否正确,Base URL、Key、Model ID 三件套都要填全。

数据对齐报错:如果check_alignment.py报 KeyError,检查列名是否和配置里的一致。比如单细胞 metadata 里细胞类型列叫cell_type,但配置里写的是celltype,就会报错。建议先用df.columns.tolist()打印列名,再对照配置修改。

district 聚类报错:如果 KMeans 报错提示样本数少于聚类数,检查n_districts是否大于实际细胞数。另外,如果邻域组成矩阵全是 0,检查neighbor_radius是否太小,导致没有找到邻居。可以先用nn.radius_neighbors的返回值检查邻居数量。

模型输出截断:如果模型返回的内容不完整,检查max_tokens是否设置太小。对于配置检查类请求,1000 够用;对于结果解读类请求,建议设到 2000 以上。如果你用 Coding Plan,额度更充足,可以放心调大。

排障的时候,建议先用最小请求验证 API 连通性:

curl -X POST https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"claude-sonnet-4-20250514","messages":[{"role":"user","content":"test"}],"max_tokens":10}'

如果这个请求返回 200,说明 API 和 Key 都没问题,问题出在脚本或配置上。如果返回 401,检查 Key;如果返回 404,检查 Base URL 和路径。

6. 语义一致 CTA:按场景选择接入方式

联合分析的配置和验证跑通之后,后续的脚本调试、结果解读、Agent 任务会越来越多。根据你的使用场景,选择对应的接入方式。

如果你主要在排障和接入阶段,需要反复检查配置、验证请求、排查报错,建议用 API Keys 加接入文档的组合。API Keys 管理页在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite ,接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。这两个页面配合使用,基本能覆盖从拿 Key 到跑通第一个请求的全过程。

如果你需要快速验证模型输出,比如检查某个 district 的细胞类型组成是否合理,或者让模型帮你解读空间邻域结果,用模型对话页面 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite 就够了。不需要写代码,直接输入问题,适合在正式分析前做假设检查。

如果你要长期跑编码类 Agent 任务,比如让模型帮你写数据整合脚本、生成配置片段、自动排查报错,建议上 Coding Plan,入口在 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。Coding Plan 的额度更稳定,适合反复调试和跑多轮验证。Claude Code 的接入配置在 https://taotoken.net/claude-code?utm_source=taotoken_aicg_blog_end&utm_content=claudecode&utm_campaign=rewrite ,里面有完整的 Base URL、Key、Model ID 三件套配置示例。

最后提醒一点:PCF 和单细胞测序联合分析的定位是科研分析和机制假设生成,不应被表述为临床判断工具。本文涉及的所有分析结果都需要结合更多实验和研究进一步观察与复核,不构成任何医疗意见。如果你在课题设计中需要判断联合方案是否适用,建议先从数据一致性检查清单入手,确认单细胞和空间蛋白组数据在细胞类型标签、坐标尺度、蛋白表达层面能对齐,再决定是否推进完整分析。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 16:31:36

Hermes Agent 迁移到外部硬盘教程:用符号链接与 HERMES_HOME 保住 venv

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/2 16:30:06

指纹与UA不一致的坑:2026年最容易翻车的细节

很多做跨境运营、爬虫采集、多账号矩阵的人都有一个认知误区:只要把 User-Agent 改成目标浏览器版本,再配个干净 IP,就能模拟真实用户。这个认知在 2026 年的风控体系面前,已经过时到近乎危险。事实上,UA 只是浏览器向…

作者头像 李华
网站建设 2026/10/2 16:27:20

手机PDF转换成Word免费版!零水印无套路,办公学生通用

日常办公、学生写作业、整理资料时,经常会遇到PDF文件无法编辑的问题。PDF格式虽然排版稳定、不易错乱,但想要修改文字、调整内容,必须转换成可自由编辑的Word文档。很多人找遍了各类工具,要么需要付费开会员、要么转换后有水印、…

作者头像 李华