@cosyte/dicom (英语)
将元数据从一个真实世界,供应商-模糊的 DICOM Part 10 文件中拉出,不读标准.
DICOM Part 10 parser + 用于节点和TypeScript的公用库:元数据第一,供应商-敏感-耐用,双重无害环境管理/CJS.
目录
为什么会这样
大多数触及医疗成像的软件需要几个标题字段,而不需要其他东西:病人是谁,哪个研究和序列一个实例属于谁,如果下游有什么东西使这些像素变得像素,如何解释这些像素。 今天把这些字段取出,意味着要找到一个围绕一个像素管道建造的工具包(C++中的GDCM,JVM上的dcm4che,C中的dcm2niix),从你的节点服务中轰出,或者写出一个严格的读取器,然后拒绝卖家-quirky文件真实的扫描器和病人的CD实际放出. @cosyte/dicom 元数据本身是: 元数据第一 TypeScript 读取标题( 病人、 研究、 系列、 图像、 代码、 UID ) , 轻而易举地快速地记录它所容忍的每一个偏差, 作为稳定的警告代码, 将像素数据暴露为原始字节,以及 从未解码像素。不是解码像素,而是使它成为您可以依赖的库,而不是您必须采用的工具链,这就是为什么在 范围和非目标 此处是可交付的,而不是脚注 @cosyte/hl7在同一个工程栏.
状态
0.1线. 公众API是定居的,可以安全依赖. 解析器条目 4个安全关键视图 结构标签访问器 懒惰键入值解码所有34个 VR , spec-clean 序列器 源/供应商描述文件系统 和元数据级别 deidentify() 他们的签名是下一期发行时 携带的 今天零运行时间依赖关系.
仍然在移动,或者根本没有覆盖. 像素数据在任何传输语法中都没有解码,这在本包中超出了范围:PS3.5 2026c节A.4语法分解下的压缩对象,其片段以生字节的形式回放,以及 serializeDicom 写回未受伤害,拒绝 INVALID_ENCAPSULATED_PIXEL_DATA a 碎片流A.4部分不允许或没有修复;DIMSE和DICOMweb是这里的非目标;除去识别器开放的PHI残基被测量和披露而不是关闭。 读取 已知限制 财务报告和审定财务报表 范围和非目标 在您用真实的数据指针之前。 误读患者识别码,图像的签名,或重新缩放斜坡可造成真正的临床伤害.
安装
# pnpm (recommended). Also works with: npm install @cosyte/dicom | yarn add @cosyte/dicom
pnpm add @cosyte/dicom
- 节点js22或后期,于22,24和26日进行测试.
engines.node实值>=22.0.0。 。 。 . - 模块格式:双重无害环境管理和CJS,附带条件类型的声明,因此
import财务报告和审定财务报表require两者都一致. - 严格类型脚本 (单位:千美元)
noUncheckedIndexedAccess,没有any联合来文和来文@example提供编辑的IntelliSense.
使用量
安装和剖析后有用输出 。 不需要DICOM的光谱知识.
import { parseDicom } from "@cosyte/dicom";
// A synthetic CT object, saved without its 128-byte preamble: an invented patient and example-root
// UIDs, no real PHI. In your integration these are the bytes of the file you read.
const buf = Buffer.from(
"AgAAAFVMBAAcAAAAAgAQAFVJFAAxLjIuODQwLjEwMDA4LjEuMi4xAAgAFgBVSRoAMS4yLjg0MC4xMDAwOC41LjEuNC4xLjEuMgAIABgAVUkeADEuMi44MjYuMC4xLjM2ODAwNDMuOC40OTguMTExAAgAIABEQQgAMTkwMDAxMDEIAGAAQ1MCAENUEAAQAFBOCABEb2VeSmFuZRAAIABMTwYATVJOLTQyEAAhAExPDABTQU1QTEUtSE9TUCAgAA0AVUkeADEuMi44MjYuMC4xLjM2ODAwNDMuOC40OTguMS4xACAADgBVSR4AMS4yLjgyNi4wLjEuMzY4MDA0My44LjQ5OC4xLjIAIAARAElTAgAyICgAEABVUwIAAAIoABEAVVMCAAACKAAAAVVTAgAQACgAAwFVUwIAAQAoAFIQRFMGAC0xMDI0ICgAUxBEUwIAMSAoADAARFMIADAuNVwwLjUg",
"base64",
);
const ds = parseDicom(buf);
console.log("patient", ds.patient.id, "issuer", ds.patient.issuerOfId);
console.log("study", ds.study.instanceUid);
console.log("series", ds.series.modality, "image", ds.image.rows, "x", ds.image.columns);
console.log("rescale slope", ds.image.rescaleSlope, "intercept", ds.image.rescaleIntercept);
console.log("tolerated", ds.warnings.length, ds.warnings[0]?.code);
// The values printed above, which the test suite asserts on every run.
// NOT globally unique on its own: pair it with ds.patient.issuerOfId.
ds.patient.id; // => "MRN-42"
// The global study anchor.
ds.study.instanceUid; // => "1.2.826.0.1.3680043.8.498.1.1"
ds.series.modality; // => "CT"
ds.image.rows; // => 512
// number | undefined: undefined means "absent", never a substituted 1.
ds.image.rescaleSlope; // => 1
// What the parser tolerated, as stable codes.
ds.warnings.map((w) => w.code); // => ["DICOM_MISSING_PREAMBLE"]
它印着:
patient MRN-42 issuer SAMPLE-HOSP
study 1.2.826.0.1.3680043.8.498.1.1
series CT image 512 x 512
rescale slope 1 intercept -1024
tolerated 1 DICOM_MISSING_PREAMBLE
结构路线和释放出字节:
import { Dictionary, deidentify, parseDicom, serializeDicom } from "@cosyte/dicom";
const ds = parseDicom(buf);
ds.get("00100010")?.value; // { kind: "personName", values: [ … ] }: structured PN, never flattened
Dictionary.byKeyword("Modality")?.tag; // "00080060"
const { dataset, report } = deidentify(ds);
const safe = serializeDicom(dataset); // Buffer: spec-clean Part 10, same transfer syntax, no transcode
report.attributes.length; // count of attributes acted on (each carries tag/keyword/action, no values)
这就是投出:没有配置,没有计划上传,没有光谱检索. 解析器默认接受spark-quirky输入(它容忍一个缺失的序言,一个错误的文件Meta组长度,奇长值,以及十几个左右的偏差会发射出真实的扫描仪),并且将每个输入记录为稳定的警告代码而不是失败. 您可以在您想要时访问输入值解码、安全关键视图、配置文件或序列器.
PHI 与安全
DICOM头条直接携带病人身份:姓名,识别符,日期,加入号,机构,以及人们输入姓名的自由文字描述. 这个图书馆做和不做 与数据,说,你可以审计它而不是假设:
- 伐木:无. 没有可配置的日志和没有
console调用图书馆代码 。 警告和出错消息通过它们的代码在被冻结的登记册中被查看,工厂只采取位置和结构常数,因此一个文件值没有字符串参数可以穿行. 例外情况在类型上列出,而不留待发现:DicomParseError.snippet16 个原始源字节为六进制DeidentifyReport携带uidMap, (中文(简体) ),removedPrivateTags, (中文(简体) ),unauditableSequences[].tag,以及contextPath由源字节组成。 把所有的人当作PHI,在你自己的边界进行校正. - 保留:无.
parseDicom返回 aDataset在你交出的缓冲器上 没有缓存,没有模块级存储,也没有调用之间的历史;打入的值解码很懒惰并被记忆在元素本身上,因此它与被丢弃的数据集一起活活活地死去. - 写入磁盘:无. 库在运行时不执行文件系统和I/O网络.
serializeDicom返回字节并留给您写出,数据词典是在构建时从正式的第6部分来源生成并编译的,所以磁盘上也没有读取. - 你仍然拥有的东西. 阅读文件,撰写并传送输出,编辑您日志的任何内容,以及保留政策.
deidentify()向您提供新的数据集和审计报告;它不决定其中任何一个去向.
此软件包的去识别输出仅是元数据去识别. deidentify() 将附件E Basic Profile 加上元数据影响选项应用到标题上,输入数据集永远不会被变异. 它不会触摸像素:当文件带有被焚毁的注释时,这个图层无法去除,就会得到一个 DICOM_BURNED_IN_ANNOTATION_NOT_REMOVED 警告而不是虚假的安全感,像素清洁就超出了这个软件包的范围. 开放的PHI残留物被测量和披露,没有一个是全清晰的: 读取 已知限制 财务报告和审定财务报表 范围和非目标 在您共享一个输出之前, 完全使用, 并处理 DeidentifyReport 因为空出的审计不是执行的.
API 密码
所有东西都从单顶级入口出口, @cosyte/dicom. 全面参考 docs.cosyte.com/dicom 页面存档备份,存于互联网档案馆 在你的编辑中,每个公共出口都带有JSDoc @example在CI门.
- 一行元数据提取数字 :
ds.patient, (中文(简体) ),ds.study, (中文(简体) ),ds.series, (中文(简体) ),ds.image:键入,对安全关键属性进行故障安全查看. 没有(group,element)要记住的标记 . - 两个进入模式: 命名视图,或结构
ds.get("00100010")由8个字符(group,element)标签( 用Dictionary.byKeyword),加 (中文(简体) )ds.elements(){\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}去走所有东西. - 已读压缩对象, 像素未变:每个 PS3.5 2026c 节A.4 封装语法(JPEG, JPEG-LS, JPEG 2000, HTJ2K, RLE, 和其余) 在明确 VR LE 规则下解析,以及
readPixelDataFragments(ds)手返回 Basic Offset 表格和每个片段作为原始字节。 像素从未被解码.serializeDicom将语法写回, 片段字节为字节, 并拒绝使用INVALID_ENCAPSULATED_PIXEL_DATAa 顶级像素数据A.4节不允许. - 懒惰键入值解码数字 :
element.value将原始字节解码为受到歧视DicomValue在所有34个自愿评估报告中(数目,bigints、人名、日期/时间、序列、生binary),荣誉(0008,0005)特定字符 通过嵌入物设置 . - 现实世界的容忍、邮政法:宽容的读者为它所容忍的东西发出稳定的警告代码;只有四个真正的结构条件是致命的. (此处曾经引用并漂移过:它读作:
25反对:WARNING_CODES联 合 国28。锁入的快照test/property/__snapshots__/warning-codes.snapshot.test.ts.snap是针头,每跑一次都要测量它,而不是在这里叙述。) - 来源/供应商简介系统数字 :
defineProfile()+5内置(ge, (中文(简体) ),siemens, (中文(简体) ),philips, (中文(简体) ),strict, (中文(简体) ),lenient只有永远 收紧或注释 解析,通过文件的活的私人创建字符串解析出供应商的私人标签,永不错误解码. - 元数据级别的去识别数字 :
deidentify()应用 PS3.15 附件E 基本概况 + 元数据影响选项,返回从静态表格中构建的新的数据集和审计报告,其中有两个字段带有源字节,并在类型上以此命名:report.uidMap(来源UID)和report.removedPrivateTags。 。 。 . - 光谱清洁序列器数字 :
serializeDicom(ds)将一个数据集回溯到 Part 10 字节的源转移语法(没有转码;四个本土语法和每个 PS3.5 2026c 节 A.4 封装语法,其顶级像素数据被写成一个OB片段流及其字节的项目字节,或以INVALID_ENCAPSULATED_PIXEL_DATA当A.4节不允许时),带有正确的文件Meta组长度,偶长的活度,每一个可以行走的数据集(根和每个序列项,每个深度最多NESTING_DEPTH_LIMIT) 以上升的标记顺序发布,项目保持顺序,且没有更改值,无损失文件Meta:未建模(0002,xxxx)元素按标记顺序保存并重新发送。 未命令 : 在物品内重复的标记( 两种副本都保存) , 无法行走的序列, 被嵌入到束缚或解开的items不匹配它的字节和任何UN-带的序列 不管标签是什么, 都写到底: 其自己的字节不显示读取器结束位置的元素, 如未定义长度UN解析器无法读取为序列 . - DICOMDIR 记录树数字 :
ds.directory将 DCOMDIR 的目录记录(病人、研究、系列、图像)按他们(0004,1200), (中文(简体) ),(0004,1400),以及(0004,1420)(单位:千美元)serializeDicom将每个记录作为它所命名的记录的字节相冲,包括去识别输出。 限制不变:参考文件ID是逐字保存的,PS3.15 §E.1.1的两个文件集条款没有被解除,带有抵消的DICOMDIR没有记录的名称或带有记录的被删除的名称被书面拒绝(见 已知限制) (中文(简体) ). - 严格类型脚本,双重无害环境管理和CJS,节点.js 22或后期数字 :
noUncheckedIndexedAccess,没有any,联合来文+@example提供编辑的IntelliSense。 今天零运行时间依赖关系.
文档
全文见 docs.cosyte.com/dicom 页面存档备份,存于互联网档案馆数字 :
- 安装 编辑 快速启动。 。 。 .
- 核心概念: 对象模型, (中文(简体) ), 访问模式, (中文(简体) ), 容忍和警告模式, (中文(简体) ), 错误处理, (中文(简体) ), 输入值, (中文(简体) ), 安全批评观点, (中文(简体) ), 源头配置,以及 兼容性,使用支持的传输语法.
- 指南: 食谱,则 烹饪本, (中文(简体) ), 序列化,以及 元数据去识别。 。 。 .
- 解决问题,则 已知限制,以及 范围和非目标。读取最后两个字,然后用真实的数据来标注.
CHANGELOG.md:每个放出.
支助
扫描仪和档案里的问题、错误报告、怪事 GitHub 问题仅使用合成数据 从来不是真正的病人 需要建立DICOM集成,还是为您主持和运行? 看我们的 融合服务。 。 。 .
警卫
私下报告一种脆弱性,从不公开,也没有真正的病人数据。 我们 安全政策 说如何.
捐款
供应商 -- -- Quirk固定装置(合成或适当去除识别),概况改进和字典更正都是受欢迎的。 测试套件所覆盖的更真实世界边缘案例,解析器得到的强度也越高. 读我们 贡献指南,或者打开一个问题.
CI运行的相同闸门必须清理: pnpm lint, (中文(简体) ), pnpm typecheck, (中文(简体) ), pnpm test (包括每节报道层), pnpm run format:check, (中文(简体) ), pnpm run check:no-emdash,以及 pnpm phi-scan。永远不要打开携带真实患者数据的PR:这个寄存器中的每一个固定器都是被合成并建在一个 .ts 源文件, PHI 扫描器也读取了此 README .
许可证
麻省理工学院,版权: Cosyte LLC. SPDX 标识符 MIT。 。 。 .
GE,西门子,和飞利浦是各自所有者的商标. Cosyte不附属于其中任何一家,也不获得其认可或赞助:这些名称标明其私人字典内置配置图解的供应商。 见 贸易。 。 。 .
由 调和。 。 。 .