Scientific Agent Skills:IDC 数字病理数据查询实战指南(SM / ANN / SEG 索引表与 SQL 模式)
2026/9/10 5:18:47 网站建设 项目流程

Scientific Agent Skills:IDC 数字病理数据查询实战指南(SM / ANN / SEG 索引表与 SQL 模式)

【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills

本篇围绕 NCI 影像数据共同体(Imaging Data Commons,IDC)中的数字病理数据,讲解如何用idc-index客户端的本地 DuckDB 索引表,对全切片显微图像(Slide Microscopy,SM)、显微批量简单标注(Microscopy Bulk Simple Annotations,ANN)与病理分割(SEG)做元数据发现、肿瘤/正常组织区分和预计算分析结果的检索。读完后,你将能够脱离 BigQuery,直接对 IDC v24 数据版本执行病理相关的 SQL 查询,并掌握从索引发现到下载、测量提取的完整工作流。

以下内容继承自技能包中的数字病理参考文档 skills/imaging-data-commons/references/digital_pathology_guide.md,并结合本仓库 skills/imaging-data-commons/SKILL.md 的索引表总览与 scripts/check_version.py 的版本校验逻辑进行了扩充说明。

版本基线:idc-index 0.12.5 与 IDC 数据版本 v24

原指南在开头明确标注:Tested with: idc-index 0.12.5(IDC 数据 version v24)。这是一个必须重视的前提——所有查询列名(如min_PixelSpacing_2sfprimaryAnatomicStructureModifier_CodeMeaning)和示例结果(如 TCGA-BRCA 的幻灯片计数)都以该版本为准,版本升级后列结构可能变化。

仓库中这一版本约束有双重佐证:

  • skills/imaging-data-commons/SKILL.md 的 frontmatter 元数据中固定了idc-index: "0.12.5"idc-data-version: "v24"
  • scripts/check_version.py 中MIN_VERSION = "0.12.5"SKILL_VERSION = "1.8.1",脚本本身从不执行安装,仅在版本不满足时打印面向当前解释器的安装命令并以非零码退出,把环境选择权留给调用者。

因此,开始数字病理查询前的标准动作是:

# 在技能包根目录运行,校验 idc-index 是否安装且版本不低于 0.12.5 python skills/imaging-data-commons/scripts/check_version.py

会话内则用客户端确认数据版本:

from idc_index import IDCClient client = IDCClient() # 校验 IDC 数据版本(应为 "v24") print(f"IDC data version: {client.get_idc_version()}")

对于通用查询与下载(非病理专属),主技能文档 SKILL.md 提供了完整的路由规则(MCP / REST / 本地索引三选一);本篇只聚焦其中的病理分支:SM、ANN、SEG 三类对象。

五张病理专用索引表

数字病理的核心是五张专门化的索引表。它们携带人工整理的(curated)元数据,无需 BigQuery即可完成绝大多数发现工作:

行粒度说明
sm_index1 行 = 1 个 SM 系列全切片显微系列元数据:容器/玻片 ID、组织类型、解剖结构、诊断、物镜倍数、像素间距、图像尺寸
sm_instance_index1 行 = 1 个 SM 实例单张切片图像的实例级(SOPInstanceUID)元数据
seg_index1 行 = 1 个 SEG 系列DICOM 分割元数据:算法名、segment 数量、源系列引用。放射与病理共用——需按源 Modality 过滤出病理分割
ann_index1 行 = 1 个 ANN 系列显微批量简单标注系列元数据;含referenced_SeriesInstanceUID,指向被标注的切片
ann_group_index1 行 = 1 个标注组标注组细节:AnnotationGroupLabelGraphicTypeNumberOfAnnotationsAlgorithmName、属性编码

这些表与本仓库 references/index_tables_guide.md 中的完整索引表清单一致,该文档的"Join Column Reference"小节还给出了一致性更强的连接键约定,与病理相关的四条是:

表 A表 B连接条件
indexsm_indexindex.SeriesInstanceUID = sm_index.SeriesInstanceUID
indexseg_indexindex.SeriesInstanceUID = seg_index.segmented_SeriesInstanceUID
indexann_indexindex.SeriesInstanceUID = ann_index.SeriesInstanceUID(取标注系列自身);ann_index.referenced_SeriesInstanceUID = index.SeriesInstanceUID(取被标注的源系列)
ann_indexann_group_indexann_index.SeriesInstanceUID = ann_group_index.SeriesInstanceUID

两条硬性规则贯穿所有后续示例:

  1. 查询任何索引表之前先client.fetch_index("table_name")。该调用对所有表(包括启动时自动加载的)都安全且幂等。
  2. 写 SQL 前先查 schema:用client.indices_overview程序化检查列名与类型,或client.get_index_schema('table')读取缓存的元数据。不要凭记忆假设列名——这是 IDC 查询返回空结果的第一大原因(主技能文档在 Discovery 一节反复强调同一模式:先枚举值,再过滤)。

Slide Microscopy(SM)查询

基本 SM 元数据

sm_index是病理元数据最丰富的表。下面按集合统计切片数量与最高分辨率(min_PixelSpacing_2sf保留两位小数的最小像素间距,间距越小分辨率越高):

from idc_index import IDCClient client = IDCClient() # sm_index 元数据详尽;与 index 连接可取 collection_id client.fetch_index("sm_index") client.sql_query(""" SELECT i.collection_id, COUNT(*) as slides, MIN(s.min_PixelSpacing_2sf) as min_resolution FROM sm_index s JOIN index i ON s.SeriesInstanceUID = i.SeriesInstanceUID GROUP BY i.collection_id ORDER BY slides DESC """)

按物镜倍数找高分辨率系列

ObjectiveLensPower记录物镜倍率。找 40 倍及以上、按分辨率排序的高清切片:

client.fetch_index("sm_index") client.sql_query(""" SELECT i.collection_id, i.PatientID, s.ObjectiveLensPower, s.min_PixelSpacing_2sf FROM sm_index s JOIN index i ON s.SeriesInstanceUID = i.SeriesInstanceUID WHERE s.ObjectiveLensPower >= 40 ORDER BY s.min_PixelSpacing_2sf LIMIT 20 """)

按标本制备方式过滤(染色 / 包埋 / 固定)

sm_index包含染色(staining)、包埋介质(embedding)、固定液(fixative)三类元数据。注意这些列是数组类型——例如 H&E 切片会是[hematoxylin stain, water soluble eosin stain],因此过滤要用array_to_string()LIKE,或用list_contains(),直接对数组列做等值匹配会漏掉多值行:

# 在指定集合中找 H&E 染色切片 client.fetch_index("sm_index") client.sql_query(""" SELECT i.PatientID, s.staining_usingSubstance_CodeMeaning as staining, s.embeddingMedium_CodeMeaning as embedding, s.tissueFixative_CodeMeaning as fixative FROM sm_index s JOIN index i ON s.SeriesInstanceUID = i.SeriesInstanceUID WHERE i.collection_id = 'tcga_brca' AND array_to_string(s.staining_usingSubstance_CodeMeaning, ', ') LIKE '%hematoxylin%' LIMIT 10 """)

跨集合比较 FFPE 石蜡切片与冷冻切片:

client.sql_query(""" SELECT i.collection_id, s.embeddingMedium_CodeMeaning as embedding, COUNT(*) as slide_count FROM sm_index s JOIN index i ON s.SeriesInstanceUID = i.SeriesInstanceUID GROUP BY i.collection_id, embedding ORDER BY i.collection_id, slide_count DESC """)

区分肿瘤与正常切片

sm_index提供了两条互补的组织类型识别路径:

适用场景
primaryAnatomicStructureModifier_CodeMeaning来自 DICOM 标本元数据的结构化组织类型(如Neoplasm, PrimaryNormalTumorNeoplasm, Metastatic)。在所有含 SM 数据的集合上通用。
ContainerIdentifier切片/容器标识。TCGA 集合中该字段是 TCGA 条形码,其中第 14–15 位的样本类型码编码组织来源:0109= 肿瘤,1019= 正常。

两条路径各有所长:结构化元数据跨集合通用,但可能为 NULL;条形码方法仅适用于 TCGA 集合,却能兜底结构化元数据缺失的情况。

路径一:结构化组织类型元数据

先枚举全库组织类型取值,再按集合统计。以下结果基于 idc-index 0.12.5 / IDC v24 数据:

from idc_index import IDCClient client = IDCClient() client.fetch_index("sm_index") # 发现所有 SM 数据中的组织类型取值 client.sql_query(""" SELECT s.primaryAnatomicStructureModifier_CodeMeaning as tissue_type, COUNT(*) as slide_count FROM sm_index s WHERE s.primaryAnatomicStructureModifier_CodeMeaning IS NOT NULL GROUP BY tissue_type ORDER BY slide_count DESC """)

以 TCGA-BRCA 为例:

# TCGA-BRCA 的组织类型分布 client.sql_query(""" SELECT s.primaryAnatomicStructureModifier_CodeMeaning as tissue_type, COUNT(*) as slide_count, COUNT(DISTINCT i.PatientID) as patient_count FROM sm_index s JOIN index i ON s.SeriesInstanceUID = i.SeriesInstanceUID WHERE i.collection_id = 'tcga_brca' GROUP BY tissue_type ORDER BY slide_count DESC """) # 指南记录的结果:Neoplasm, Primary(2704 张)、Normal(399 张)

路径二:TCGA 条形码(仅限 TCGA 集合)

TCGA 集合中ContainerIdentifier即切片条形码(如TCGA-E9-A3X8-01A-03-TSC),第 4 段的前两位就是样本类型码:

# 从 TCGA 条形码解析样本类型码 client.sql_query(""" SELECT SUBSTRING(SPLIT_PART(s.ContainerIdentifier, '-', 4), 1, 2) as sample_type_code, s.primaryAnatomicStructureModifier_CodeMeaning as tissue_type, COUNT(*) as slide_count FROM sm_index s JOIN index i ON s.SeriesInstanceUID = i.SeriesInstanceUID WHERE i.collection_id = 'tcga_brca' GROUP BY sample_type_code, tissue_type ORDER BY sample_type_code """) # 指南记录的结果:01 → Neoplasm, Primary(2704),06 → None(8),11 → Normal(399)

条形码方法的价值在最后一行数据上:类型码06(转移灶)对应的 8 张切片在 TCGA-BRCA 中primaryAnatomicStructureModifier_CodeMeaning为 NULL——只依赖结构化元数据的查询会静默丢掉这些切片。实践建议是两条路径并用,用条形码兜底 NULL 情况。

标注(ANN)查询

DICOM Microscopy Bulk Simple Annotations(Modality = 'ANN')是画在显微切片图像之上的标注对象。它们分两级出现在索引中:ann_index(系列级)与ann_group_index(标注组级)。每个 ANN 系列通过referenced_SeriesInstanceUID指向它标注的那张切片——这是做"标注 ↔ 原图"关联的唯一桥梁。

基础标注发现

# 找标注系列及其引用的原图系列 client.fetch_index("ann_index") client.fetch_index("ann_group_index") client.sql_query(""" SELECT a.SeriesInstanceUID as ann_series, a.AnnotationCoordinateType, a.referenced_SeriesInstanceUID as source_series FROM ann_index a LIMIT 10 """)

标注组统计

按图形类型汇总标注总量(点、线、多边形等):

client.sql_query(""" SELECT GraphicType, SUM(NumberOfAnnotations) as total_annotations, COUNT(*) as group_count FROM ann_group_index GROUP BY GraphicType ORDER BY total_annotations DESC """)

带源切片上下文的标注检索

三级连接:标注组 → 标注系列 → 被引用的源系列,从而拿到集合归属与算法名:

client.sql_query(""" SELECT i.collection_id, g.GraphicType, g.AnnotationPropertyType_CodeMeaning, g.AlgorithmName, g.NumberOfAnnotations FROM ann_group_index g JOIN ann_index a ON g.SeriesInstanceUID = a.SeriesInstanceUID JOIN index i ON a.referenced_SeriesInstanceUID = i.SeriesInstanceUID WHERE g.AlgorithmName IS NOT NULL LIMIT 10 """)

全切片显微图像上的分割(SEG)

DICOM Segmentation(Modality = 'SEG')同时服务放射(CT 器官分割)与病理(WSI 组织区域分割)。隔离病理分割的关键是:用seg_index.segmented_SeriesInstanceUID找到源系列,再按源的 Modality 过滤为'SM'

# 找源为显微切片的分割 client.fetch_index("seg_index") client.fetch_index("sm_index") client.sql_query(""" SELECT seg.SeriesInstanceUID as seg_series, seg.AlgorithmName, seg.total_segments, src.collection_id, src.Modality as source_modality FROM seg_index seg JOIN index src ON seg.segmented_SeriesInstanceUID = src.SeriesInstanceUID WHERE src.Modality = 'SM' LIMIT 20 """)

注意这里seg_index连接的是index(源系列),而不是sm_index——index_tables_guide.md 的连接键参考表明确index.SeriesInstanceUID = seg_index.segmented_SeriesInstanceUIDsm_index的 fetch 是为后续需要切片级属性(分辨率、物镜)时再连接做准备。

查找预计算分析结果(Analysis Results)

IDC 托管派生数据集——核分割、TIL(肿瘤浸润淋巴细胞)图、AI 标注——在主index表中以analysis_result_id标识。analysis_results_index表用于发现病理方向上有哪些现成结果可用:

from idc_index import IDCClient client = IDCClient() client.fetch_index("analysis_results_index") # 找包含病理标注或分割的分析结果 client.sql_query(""" SELECT ar.analysis_result_id, ar.analysis_result_title, ar.modalities, ar.subjects, ar.collections FROM analysis_results_index ar WHERE ar.modalities LIKE '%ANN%' OR ar.modalities LIKE '%SEG%' ORDER BY ar.subjects DESC """)

区分两个 ID 的职责(主技能文档 IDC Data Model 一节的定义):collection_id定位原始影像数据(其中可能自带入库时的标注),analysis_result_id定位跨一个或多个原始集合的派生对象。找 AI/专家生成的标注用后者。

为特定切片找全部派生数据

# 找 TCGA-BRCA 切片的全部派生数据(标注、分割) client.fetch_index("ann_index") client.sql_query(""" SELECT i.analysis_result_id, i.PatientID, a.referenced_SeriesInstanceUID as source_slide, g.AnnotationGroupLabel, g.NumberOfAnnotations, g.AlgorithmName FROM ann_group_index g JOIN ann_index a ON g.SeriesInstanceUID = a.SeriesInstanceUID JOIN index i ON a.SeriesInstanceUID = i.SeriesInstanceUID WHERE i.collection_id = 'tcga_brca' LIMIT 10 """)

索引表之外的测量值:标注对象内还可携带逐条标注的测量(如核面积、偏心率),它们存在于 DICOM 文件内部而不在索引表中。指南给出的处理方式是:下载后用 IDC 官方维护的 highdicom 库提取,调用链为ann.get_annotation_groups()group.get_measurements()。原指南同时指向了 IDC-Tutorials 中的microscopy_dicom_ann_intro教程(含空间分析与细胞密度计算的完整示例)——该教程位于仓库外部,这里仅说明这条提取路径存在,具体 API 以 highdicom 官方文档为准。

按 AnnotationGroupLabel 过滤

AnnotationGroupLabel是按名称或语义内容找标注组最直接的列,用LIKE通配做文本检索(配合LOWER()做大小写不敏感匹配):

简单标签过滤

# 按标签找标注组(如包含 "blast" 的组) client.fetch_index("ann_group_index") client.sql_query(""" SELECT g.SeriesInstanceUID, g.AnnotationGroupLabel, g.GraphicType, g.NumberOfAnnotations, g.AlgorithmName FROM ann_group_index g WHERE LOWER(g.AnnotationGroupLabel) LIKE '%blast%' ORDER BY g.NumberOfAnnotations DESC """)

带集合上下文的标签过滤

# 在特定集合内按标签找标注组 client.fetch_index("ann_index") client.fetch_index("ann_group_index") client.sql_query(""" SELECT i.collection_id, g.AnnotationGroupLabel, g.GraphicType, g.NumberOfAnnotations, g.AnnotationPropertyType_CodeMeaning FROM ann_group_index g JOIN ann_index a ON g.SeriesInstanceUID = a.SeriesInstanceUID JOIN index i ON a.SeriesInstanceUID = i.SeriesInstanceUID WHERE i.collection_id = 'your_collection_id' AND LOWER(g.AnnotationGroupLabel) LIKE '%keyword%' ORDER BY g.NumberOfAnnotations DESC """)

这个模式与 references/sql_patterns.md 中 "Query Slide Microscopy and Annotation Data" 一节的示例相互印证——该文档把更完整的 SM 查询、ANN 过滤、SM+ANN 交叉引用统一指向本篇指南,可见本篇是技能包内病理 SQL 模式的权威落点。

SM + ANN 交叉引用

要找"显微切片数据上有哪些标注",需要 SM 与 ANN 两张表同时参与。连接枢纽仍是ann_index.referenced_SeriesInstanceUID,只不过这一次把它接到sm_index而非index上,从而直接携带源切片的物镜信息:

# 找集合中显微切片及其标注 client.fetch_index("sm_index") client.fetch_index("ann_index") client.fetch_index("ann_group_index") client.sql_query(""" SELECT i.collection_id, s.ObjectiveLensPower, g.AnnotationGroupLabel, g.NumberOfAnnotations, g.GraphicType FROM ann_group_index g JOIN ann_index a ON g.SeriesInstanceUID = a.SeriesInstanceUID JOIN sm_index s ON a.referenced_SeriesInstanceUID = s.SeriesInstanceUID JOIN index i ON a.SeriesInstanceUID = i.SeriesInstanceUID WHERE i.collection_id = 'your_collection_id' ORDER BY g.NumberOfAnnotations DESC """)

注意两个 JOIN 的语义区别:JOIN sm_index s ON a.referenced_SeriesInstanceUID = s.SeriesInstanceUID走的是引用方向(标注 → 被标注的原图),而JOIN index i ON a.SeriesInstanceUID = i.SeriesInstanceUID走的是标注系列自身的归属(用于取collection_id)。混用这两个键是此类查询最常见的错误。

Join 模式速查

原指南给出的两个基础连接模式:

SM 连接(切片显微细节 + 集合上下文)

client.fetch_index("sm_index") result = client.sql_query(""" SELECT i.collection_id, i.PatientID, s.ObjectiveLensPower, s.min_PixelSpacing_2sf FROM index i JOIN sm_index s ON i.SeriesInstanceUID = s.SeriesInstanceUID LIMIT 10 """)

ANN 连接(标注组 + 集合上下文)

client.fetch_index("ann_index") client.fetch_index("ann_group_index") result = client.sql_query(""" SELECT i.collection_id, g.AnnotationGroupLabel, g.GraphicType, g.NumberOfAnnotations, a.referenced_SeriesInstanceUID as source_series FROM ann_group_index g JOIN ann_index a ON g.SeriesInstanceUID = a.SeriesInstanceUID JOIN index i ON a.SeriesInstanceUID = i.SeriesInstanceUID LIMIT 10 """)

配套工具生态

原指南末尾列出与数字病理工作流配套、基于 DICOM 格式的工具链,按用途分三类(工具名保留,供读者自行检索其官方仓库):

Python 库

  • highdicom(IDC 官方开发):高层 DICOM 抽象,用于创建和读取 DICOM Segmentation(SEG)、Structured Report(SR)与 parametric map,覆盖病理与放射场景;也是提取前文提到的逐条标注测量的推荐路径。
  • wsidicom:读取 DICOM WSI 数据集的 Python 包,把元数据解析为易用的 dataclass,面向全切片图像分析。
  • TIA-Toolbox:端到端计算病理库,通过DICOMWSIReader支持 DICOM,提供 tile 提取、特征提取与预训练深度学习模型。
  • EZ-WSI-DICOMweb:通过 DICOMweb 从 DICOM 全切片图像中抽取图像块,面向云 DICOM 存储的 AI/ML 工作流。

查看器

  • Slim(IDC 开发):基于 Web 的 DICOM 显微切片查看器与标注工具,通过 DICOMweb 支持明场与多重免疫荧光成像。主技能文档也提到client.get_viewer_URL()对 SM 系列会自动路由到 SLIM。
  • QuPath:跨平台开源全切片图像分析软件,经 Bio-Formats 与 OpenSlide(v0.4.0 起)支持 DICOM WSI;主技能文档的故障排查一节同样把 QuPath 列为病理 DICOM 打不开时的备选查看器。

格式转换

  • dicom_wsi:将专有 WSI 格式转换为符合 DICOM 规范的文件的 Python 实现。

实践清单与排错要点

综合本篇与技能包其余文档,数字病理会话的标准实践是:

  1. 先验版本check_version.py通过 +client.get_idc_version()返回v24,再开始查询;
  2. 先 fetch 后查询sm_indexsm_instance_indexseg_indexann_indexann_group_indexanalysis_results_index全部需要client.fetch_index(...)前置;
  3. 先查 schema 后写 SQL:用client.indices_overview核对列名;病理列名(如staining_usingSubstance_CodeMeaning)带 CodeMeaning 后缀且可能是数组类型;
  4. 先小后大:探索期一律LIMIT,确认集合规模再考虑下载——主技能文档提醒部分集合以 TB 计;
  5. 区分连接方向referenced_SeriesInstanceUID/segmented_SeriesInstanceUID指向源系列,SeriesInstanceUID自身连接指向对象自身的归属;
  6. 打不开下载文件时:主技能文档的 Troubleshooting 建议先检查ModalitySOPClassUID,用pydicom.dcmread(file, force=True)验证,SEG、RTSTRUCT、SR 与显微切片都需要专用工具(3D Slicer、QuPath 等)而非普通放射查看器。

需要完整索引表清单、临床数据连接或下载工作流时,可继续参阅 index_tables_guide.md、sql_patterns.md、cli_guide.md 与 use_cases.md——它们与本篇指南同属 skills/imaging-data-commons/ 技能包,按主文档 Quick Navigation 表的触发条件按需加载即可。

【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询