Files
CADx-4/pyproject.toml
T
iomgaa 00ebbffb28 feat(ceus): 两半坐标换算改为每段视频配准,加目视核对脚本
- 第 1 步分屏后在两半扇形区内用边缘图归一化互相关估 (dx, dy),再用逐帧多块模板匹配的中位数独立核对;
  两者各分量之差超过门槛(15 像素)这一例第 1 步失败。删掉「两个视图左上角相减」的实现与测试。
- 门槛依据:34 例中走完第 1 步的 29 例,差值中位 2、95 分位 6.2、最大 13;参数与门槛在同一批视频上调出。
- scripts/ceus_align_review.py:只做第 1 步,出扇形区棋盘图与边缘叠加图,混入错开 15–30 像素的
  阴性对照、随机编号;计分时任一对照未被判「没对齐」即作废。
- ceus_quant 读 review.csv:不通过的病例第 1 步失败;表里没有这段视频或平移对不上即停。
- 配准与紫圈颜色参数进分割缓存键。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 06:47:27 -04:00

156 lines
5.6 KiB
TOML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
[project]
name = "cadx"
version = "0.0.0"
description = "胰腺囊性肿瘤多模态会诊诊断的研究代码"
requires-python = ">=3.12"
dependencies = [
"matplotlib>=3.11.2",
"medsam2",
"numpy>=2.5.4",
"opencv-python-headless>=5.0.0.93",
"openpyxl>=3.1.5",
"pillow>=12.3.0",
"pydantic>=2.14.1",
"pyyaml>=6.0.3",
"scipy>=1.18.1",
]
[dependency-groups]
dev = [
"ruff>=0.6",
"pyright>=1.1.380",
"pytest>=8.3",
"import-linter>=2.1",
"pre-commit>=4.0",
"types-pyyaml>=6.0.12.20260906",
"types-openpyxl>=3.1.5.20260827",
]
[tool.uv]
# 只在本机和远程服务器(都是 Linux x86_64)上跑;只为这一种平台解析依赖,
# 免得 torch 的各平台 CUDA 轮子都要下载一遍。
environments = ["sys_platform == 'linux' and platform_machine == 'x86_64'"]
[tool.uv.sources]
medsam2 = { path = "reference/MedSAM2", editable = true }
[build-system]
requires = ["hatchling>=1.26"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/cadx"]
[tool.ruff]
line-length = 100
target-version = "py312"
src = ["src", "tests", "scripts"]
extend-exclude = ["research-wiki", "reference", "reference-pdf", "runs", "data"]
[tool.ruff.lint]
select = ["E", "W", "F", "I", "UP", "B", "BLE", "S", "SIM", "RUF"]
# 允许注释和文档字符串里的中文全角标点。
ignore = ["RUF001", "RUF002", "RUF003"]
[tool.ruff.lint.per-file-ignores]
"tests/**" = ["S101"]
[tool.pyright]
include = ["src", "tests", "scripts"]
pythonVersion = "3.12"
typeCheckingMode = "strict"
venvPath = "."
venv = ".venv"
# medsam2 以 setuptools 的导入钩子方式可编辑安装,pyright 跟不过去,直接指给它源码目录。
extraPaths = ["tests", "scripts", "reference/MedSAM2"]
[tool.pytest.ini_options]
testpaths = ["tests"]
# 测试辅助(假交付包生成器)放在 tests/ 下,按普通模块导入;scripts/ 也在路径上,
# ceus_align_review 引用 ceus_quant 的配置模型(直接运行脚本时 scripts/ 本来就在 sys.path 上)。
pythonpath = ["tests", "scripts"]
addopts = "--strict-markers --import-mode=importlib"
markers = [
"live: 真实模型调用,花钱,需要 .env 里的密钥",
"gpu: 需要 CUDA 显卡(MedSAM2 分割)",
]
# 导入边界。改契约先改 research-wiki/explanation/结构.md,再改这里;
# 不靠 ignore_imports 让违规通过。规划中的契约见结构.md 第五部分,模块落地时随任务书加入。
[tool.importlinter]
root_packages = ["cadx"]
include_external_packages = true
[[tool.importlinter.contracts]]
# design 0001:torch 与 MedSAM2 只许出现在分割模块。import-linter 不能写「除 segment 外的 cadx」
# (只有 ignore_imports 能开例外),所以逐个列出其余模块;新模块落地时加进 source_modules。
name = "cadx 里只有 segment 引用 torch、sam2"
type = "forbidden"
source_modules = [
"cadx.delivery", "cadx.library", "cadx.answers", "cadx.runs", "cadx.build", "cadx.ceus",
]
forbidden_modules = ["torch", "sam2"]
[[tool.importlinter.contracts]]
# 结构.md 第三部分依赖表:segment 不引用其他 cadx 模块(它不认识分屏和绿框)。
name = "segment 不引用其他 cadx 模块"
type = "forbidden"
source_modules = ["cadx.segment"]
forbidden_modules = [
"cadx.delivery", "cadx.library", "cadx.answers", "cadx.runs", "cadx.build",
"cadx.ceus", "cadx.llm", "cadx.ledger", "cadx.consult", "cadx.evaluate", "cadx.verdicts",
]
[[tool.importlinter.contracts]]
# 结构.md 第三部分依赖表:外部层与格式层的模块不依赖其他 cadx 模块。
name = "delivery、library、answers、runs 互不依赖"
type = "independence"
modules = ["cadx.delivery", "cadx.library", "cadx.answers", "cadx.runs"]
[[tool.importlinter.contracts]]
# 同上,依赖表的另一半:它们也不引用上层和其余规划中的模块(独立契约只管它们之间)。
name = "delivery、library、answers、runs 不引用其他 cadx 模块"
type = "forbidden"
source_modules = ["cadx.delivery", "cadx.library", "cadx.answers", "cadx.runs"]
forbidden_modules = [
"cadx.build", "cadx.ceus", "cadx.segment", "cadx.llm", "cadx.ledger",
"cadx.consult", "cadx.evaluate", "cadx.verdicts",
]
[[tool.importlinter.contracts]]
# 结构.md 第三部分依赖表:ceus 是纯计算,不引用其他 cadx 模块(含 segment,分割结果由脚本传进来)。
name = "ceus 不引用其他 cadx 模块"
type = "forbidden"
source_modules = ["cadx.ceus"]
forbidden_modules = [
"cadx.delivery", "cadx.library", "cadx.answers", "cadx.runs", "cadx.build",
"cadx.segment", "cadx.llm", "cadx.ledger", "cadx.consult", "cadx.evaluate", "cadx.verdicts",
]
[[tool.importlinter.contracts]]
# 结构.md 第三部分依赖表:build 只依赖 delivery、library、answers、runs(ceus 落地时加入)。
name = "build 只引用 delivery、library、answers、runs"
type = "forbidden"
source_modules = ["cadx.build"]
forbidden_modules = [
"cadx.ceus", "cadx.segment", "cadx.llm", "cadx.ledger",
"cadx.consult", "cadx.evaluate", "cadx.verdicts",
]
allow_indirect_imports = true
[[tool.importlinter.contracts]]
# 结构.md 第五部分:交付包的 Excel 只有 delivery 碰。
name = "只有 delivery 引用 openpyxl"
type = "forbidden"
source_modules = ["cadx.library", "cadx.answers", "cadx.runs", "cadx.build"]
forbidden_modules = ["openpyxl"]
allow_indirect_imports = true
[[tool.importlinter.contracts]]
# 结构.md 第五部分:写资料库的图片(去掉元数据)只有 library 碰。
name = "只有 library 引用 PIL"
type = "forbidden"
source_modules = ["cadx.delivery", "cadx.answers", "cadx.runs", "cadx.build"]
forbidden_modules = ["PIL"]
allow_indirect_imports = true