-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdicom.html
More file actions
323 lines (311 loc) · 19.7 KB
/
Copy pathdicom.html
File metadata and controls
323 lines (311 loc) · 19.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>DICOM imaging — MessageFoundry</title>
<meta name="description" content="MessageFoundry treats medical imaging as a first-class lane — send/receive DICOM over DIMSE (C-STORE, C-ECHO) plus DICOMweb STOW-RS, mapped to HL7 v2 in Python.">
<link rel="canonical" href="https://messagefoundry.org/dicom.html">
<link rel="icon" href="/assets/img/favicon.svg" type="image/svg+xml">
<meta name="theme-color" content="#0b1220">
<meta property="og:type" content="website">
<meta property="og:site_name" content="MessageFoundry">
<meta property="og:title" content="DICOM imaging — MessageFoundry">
<meta property="og:description" content="Receive and send DICOM over DIMSE (C-STORE SCP/SCU, C-ECHO) and DICOMweb STOW-RS, with a code-first SR→HL7 v2 transform and the same reliability + PHI-safe handling as every connection.">
<meta property="og:url" content="https://messagefoundry.org/dicom.html">
<meta property="og:image" content="https://messagefoundry.org/assets/img/og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:type" content="image/png">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://messagefoundry.org/assets/img/og.png">
<link rel="stylesheet" href="/assets/css/styles.css">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"@id": "https://messagefoundry.org/#software",
"name": "MessageFoundry",
"applicationCategory": "Healthcare interface engine",
"applicationSubCategory": "HL7 interface engine",
"operatingSystem": "Windows, Linux, macOS",
"url": "https://messagefoundry.org/",
"downloadUrl": "https://pypi.org/project/messagefoundry/",
"license": "https://www.gnu.org/licenses/agpl-3.0.html",
"isAccessibleForFree": true,
"offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD" },
"publisher": { "@id": "https://messagefoundry.org/#org" }
}
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{ "@type": "Question", "name": "Does MessageFoundry support DICOM?", "acceptedAnswer": { "@type": "Answer", "text": "Yes. MessageFoundry treats medical imaging as a first-class lane: it receives as a C-STORE SCP and sends as a C-STORE SCU over DIMSE, supports C-ECHO, and speaks DICOMweb STOW-RS over HTTP — alongside HL7 v2 and FHIR in the same engine." } },
{ "@type": "Question", "name": "Can MessageFoundry route imaging alongside HL7?", "acceptedAnswer": { "@type": "Answer", "text": "Yes. The same Python config that routes HL7 v2 and FHIR also moves DICOM, so imaging and clinical messaging run on one self-hosted engine with the same reliability and PHI handling." } },
{ "@type": "Question", "name": "How does MessageFoundry map imaging data to HL7 v2?", "acceptedAnswer": { "@type": "Answer", "text": "Structured-report (SR) to HL7 v2 mapping is written as versioned Python rather than configured in a GUI mapper, so it is diffable, testable, and reviewed like any other interface code." } }
]
}
</script>
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<div class="eabar" role="region" aria-label="Project status">
<div class="container">
<p><strong>Early Access · beta.</strong> We're building toward 1.0 — and we want people involved now, while it can still be shaped. <a href="/status.html">Where the project stands →</a></p>
</div>
</div>
<header class="site-header">
<div class="container header-inner">
<a class="brand" href="/" aria-label="MessageFoundry home">
<img class="brand-mark" src="/assets/img/logo.svg" alt="" width="28" height="28">
<span class="brand-name">Message<span class="brand-accent">Foundry</span><span class="brand-tm">™</span></span>
</a>
<button class="nav-toggle" aria-expanded="false" aria-controls="site-nav" aria-label="Toggle navigation"><span></span><span></span><span></span></button>
<nav class="site-nav" id="site-nav">
<div class="nav-group">
<button type="button" class="nav-group__btn" aria-expanded="false" aria-haspopup="true" aria-controls="nav-product">Product</button>
<div class="nav-group__menu" id="nav-product">
<a href="/overview.html">Overview</a>
<a href="/features.html">Features</a>
<a href="/features-table.html">Feature list</a>
<a href="/architecture.html">Architecture</a>
<a href="/reliability.html">Reliability (CI)</a>
<a href="/tools.html">Tools</a>
<a href="/editor.html">Editor</a>
<a href="/console.html">Console</a>
<a href="/ai.html">AI assist</a>
</div>
</div>
<a href="/security.html">Security</a>
<a href="/comparison.html">Comparison</a>
<div class="nav-group">
<button type="button" class="nav-group__btn" aria-expanded="false" aria-haspopup="true" aria-controls="nav-getstarted">Get started</button>
<div class="nav-group__menu" id="nav-getstarted">
<a href="/getting-started.html">Quickstart</a>
<a href="/guides/">Guides</a>
<a href="/documents.html">Documents</a>
</div>
</div>
<div class="nav-group">
<button type="button" class="nav-group__btn" aria-expanded="false" aria-haspopup="true" aria-controls="nav-company">About Us</button>
<div class="nav-group__menu" id="nav-company">
<a href="/about.html">About</a>
<a href="/status.html">Project status</a>
<a href="/licensing.html">Licensing</a>
<a href="/contact.html">Contact</a>
<a href="/sponsor.html">Sponsor</a>
</div>
</div>
<a class="btn btn-ghost" href="/pypi.html">PyPI<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3l8 4.5l0 9l-8 4.5l-8 -4.5l0 -9l8 -4.5"/><path d="M12 12l8 -4.5"/><path d="M12 12l0 9"/><path d="M12 12l-8 -4.5"/><path d="M16 5.25l-8 4.5"/></svg></a>
<a class="btn btn-ghost" href="https://github.com/MEFORORG/MessageFoundry" target="_blank" rel="noopener">GitHub ↗</a>
</nav>
</div>
</header>
<main id="main">
<!-- hero -->
<section class="section section--dark section--tight">
<div class="container center">
<span class="eyebrow">DICOM imaging</span>
<h1 style="max-width:22ch;margin-inline:auto">Send, receive, and route DICOM imaging</h1>
<p class="lead">MessageFoundry treats imaging as a first-class lane: <b>receive</b> stored objects (C-STORE SCP) and <b>send</b> them to a PACS (C-STORE SCU), verify with C-ECHO, and push over modern <b>DICOMweb STOW-RS</b> — with the Structured-Report-to-HL7 v2 mapping written as <b>versioned, testable Python</b>, not a proprietary GUI mapper, and the same reliability and PHI-safe handling as every other connection.</p>
<div class="btn-row">
<a class="btn btn-primary" href="/getting-started.html">Get started</a>
<a class="btn btn-secondary" href="#compare">How it compares ↓</a>
</div>
<p class="lead center" style="font-size:.95rem;color:var(--muted-dk);margin-top:18px">Scope by design — <b>headers and Structured Reports only</b>: no pixel data, no <code>numpy</code>.</p>
</div>
</section>
<!-- what's supported -->
<section class="section">
<div class="container">
<div class="center" style="margin-bottom:34px">
<span class="eyebrow">What's supported</span>
<h2>A complete DICOM transport lane</h2>
<p class="lead center">Inbound and outbound DIMSE, plus the modern HTTP lane — each riding the same staged pipeline, retries, and audit as the rest of the engine.</p>
</div>
<div class="grid grid-3">
<div class="card">
<h3>C-STORE SCP — receive</h3>
<p>A <code>pynetdicom</code> Application Entity accepts stored objects inbound. It returns C-STORE <b>Success only after</b> the object is durably committed (the DIMSE analog of commit-before-ACK) — nothing is accepted-and-dropped.</p>
</div>
<div class="card">
<h3>C-STORE SCU — send</h3>
<p>Forward an object to a downstream PACS over a C-STORE association — the same sender scope Mirth covers. The blocking association runs off the event loop, so a slow peer doesn't stall the engine.</p>
</div>
<div class="card">
<h3>C-ECHO — verify</h3>
<p>Connectivity verification both ways: the SCP accepts Verification, and an outbound destination's <b>Test Connection</b> issues a C-ECHO before you trust the link.</p>
</div>
<div class="card">
<h3>DICOMweb STOW-RS — send over HTTP</h3>
<p>The modern HTTP imaging lane — store/send to <code>{base}/studies</code> as <code>multipart/related</code>. It reuses the hardened REST plumbing (TLS-verifying, no-redirect, egress-gated). <b>Neither Mirth nor Corepoint ships this out of the box.</b></p>
</div>
<div class="card">
<h3>SR / header → HL7 v2</h3>
<p>Map a Structured Report or header to HL7 v2 (ORU/OBX, PID/OBR) in a <b>code-first Handler</b> — versioned and unit-testable, a replacement for the GUI mapper Corepoint sells behind a license.</p>
</div>
<div class="card">
<h3>DICOM-over-TLS</h3>
<p>TLS on the wire for both server and client, with <b>opt-in mTLS</b>. A non-loopback cleartext listener is refused at startup unless explicitly overridden.</p>
</div>
</div>
</div>
</section>
<!-- scope -->
<section class="section section--alt">
<div class="container grid grid-2" style="align-items:center">
<div>
<span class="eyebrow">Deliberately scoped</span>
<h2>What it does <em>not</em> do — on purpose</h2>
<p class="lead">A tight scope is a feature: it keeps the imaging lane small, auditable, and free of a heavy pixel-processing attack surface. The boundary mirrors what a routing engine actually needs (and what Mirth itself draws).</p>
<p>Need full PACS/VNA behavior — query/retrieve, worklists, pixel rendering? That's an archive's job, not an interface engine's. MessageFoundry routes and transforms imaging metadata; it doesn't become your image store.</p>
</div>
<ul class="feature-list">
<li><b>No MWL / MPPS</b> — serving a Modality Worklist or performed-procedure-step is out of scope (Mirth doesn't serve them either).</li>
<li><b>No Query/Retrieve</b> — C-FIND / C-MOVE / C-GET are not provided.</li>
<li><b>No DICOMweb QIDO-RS / WADO-RS</b> — our DICOMweb is <b>store/send only</b>, not query/retrieve.</li>
<li><b>No inbound STOW-RS receiver yet</b> — it needs the inbound HTTP listener, which is on the backlog.</li>
<li><b>No pixel data, no <code>numpy</code></b> — headers and Structured Reports only, which is also a security boundary (no decompression-bomb surface).</li>
</ul>
</div>
</section>
<!-- reliability & PHI -->
<section class="section">
<div class="container">
<div class="center" style="margin-bottom:34px">
<span class="eyebrow">Reliability & PHI</span>
<h2>Imaging on the same durable, PHI-aware rails</h2>
</div>
<div class="grid grid-3">
<div class="card">
<h3>Commit before success</h3>
<p>The SCP commits the raw object durably before returning Success; a crash before commit just means the sender re-sends. At-least-once, with idempotent re-store on <code>SOPInstanceUID</code>.</p>
</div>
<div class="card">
<h3>Smart retry classification</h3>
<p>Out-of-resources or a transport failure is <b>transient</b> (retried with backoff); a hard refusal — rejected context, unencodable dataset, not-authorized — is <b>permanent</b> and dead-letters, so a bad object doesn't head-block the lane.</p>
</div>
<div class="card">
<h3>PHI-safe by construction</h3>
<p>A DICOM object is PHI: stored encrypted, never logged at INFO or above, and egress-allowlisted. Log and error lines carry only routing-safe identifiers (SOP/AE/peer) — never the dataset or pixel data.</p>
</div>
</div>
<div class="callout" style="margin-top:24px">
<p style="margin-bottom:0"><strong>Fail-closed egress.</strong> A DIMSE destination is gated by the <code>[egress].allowed_tcp</code> allowlist and a DICOMweb destination by <code>[egress].allowed_http</code> — both enforced at load, reload, and startup, so the engine can't send imaging anywhere you didn't approve.</p>
</div>
</div>
</section>
<!-- comparison -->
<section class="section section--dark" id="compare">
<div class="container">
<div class="center" style="margin-bottom:30px">
<span class="eyebrow">How it compares</span>
<h2>DICOM vs. Mirth & Corepoint</h2>
<p class="lead center">The same DICOM transport scope Mirth covers, a code-first replacement for Corepoint's GUI-mapped transform, and a modern DICOMweb send lane neither incumbent ships.</p>
</div>
<div class="table-wrap">
<table class="cmp">
<thead>
<tr><th scope="col">Capability</th><th scope="col">Mirth</th><th scope="col">Corepoint "DICOM Gear"</th><th scope="col">MessageFoundry</th></tr>
</thead>
<tbody>
<tr><th scope="row">C-STORE SCP (receive)</th><td>Yes</td><td>Yes</td><td>Yes</td></tr>
<tr><th scope="row">C-STORE SCU (send)</th><td>Yes</td><td>Yes</td><td>Yes</td></tr>
<tr><th scope="row">C-ECHO</th><td>Yes</td><td>Yes</td><td>Yes</td></tr>
<tr><th scope="row">SR / header → HL7 v2 transform</th><td>Transport only</td><td>Yes — GUI mapper</td><td><b>Yes — code-first Handler</b></td></tr>
<tr><th scope="row">DICOMweb STOW-RS send</th><td>No</td><td>No</td><td><b>Yes</b></td></tr>
<tr><th scope="row">MWL / Query-Retrieve / pixel data</th><td>No</td><td>Partial</td><td>No — out of scope</td></tr>
</tbody>
</table>
</div>
<div class="callout callout--on-dark" style="margin-top:26px;background:rgba(245,158,11,.07);border-color:rgba(245,158,11,.28);color:var(--muted-dk)">
<p style="margin-bottom:0"><strong style="color:var(--accent)">Honest validation note.</strong> The connectors are verified against the DICOM protocol with real <code>pynetdicom</code> loopback tests (and the DICOMweb framing with mocked HTTP) — <b>not yet against a specific vendor PACS</b>. A real-feed validation against your partner's SOP classes, transfer syntaxes, and AE titles is the step before cutover.</p>
</div>
</div>
</section>
<!-- cta -->
<section class="section section--tight">
<div class="container">
<div class="cta-band">
<h2>Route imaging like any other interface</h2>
<p class="lead center" style="color:var(--muted-dk)">Wire a DICOM source or destination the same way you wire MLLP or REST — in code you own, tested before it ships.</p>
<div class="btn-row center">
<a class="btn btn-primary" href="/getting-started.html">Get started</a>
<a class="btn btn-ghost" href="https://github.com/MEFORORG/MessageFoundry/blob/main/docs/CONNECTIONS.md" target="_blank" rel="noopener">Connector reference ↗</a>
</div>
</div>
</div>
</section>
<!-- faq -->
<section class="section">
<div class="container">
<div class="center" style="margin-bottom:28px"><span class="eyebrow">FAQ</span><h2>Frequently asked questions</h2></div>
<div class="faq">
<div class="faq-item"><h3>Does MessageFoundry support DICOM?</h3><p>Yes. MessageFoundry treats medical imaging as a first-class lane: it receives as a C-STORE SCP and sends as a C-STORE SCU over DIMSE, supports C-ECHO, and speaks DICOMweb STOW-RS over HTTP — alongside HL7 v2 and FHIR in the same engine.</p></div>
<div class="faq-item"><h3>Can MessageFoundry route imaging alongside HL7?</h3><p>Yes. The same Python config that routes HL7 v2 and FHIR also moves DICOM, so imaging and clinical messaging run on one self-hosted engine with the same reliability and PHI handling.</p></div>
<div class="faq-item"><h3>How does MessageFoundry map imaging data to HL7 v2?</h3><p>Structured-report (SR) to HL7 v2 mapping is written as versioned Python rather than configured in a GUI mapper, so it is diffable, testable, and reviewed like any other interface code.</p></div>
</div>
</div>
</section>
</main>
<footer class="site-footer">
<div class="container">
<div class="footer-grid">
<div class="footer-brand">
<a class="brand" href="/" aria-label="MessageFoundry home">
<img class="brand-mark" src="/assets/img/logo.svg" alt="" width="28" height="28">
<span class="brand-name">Message<span class="brand-accent">Foundry</span><span class="brand-tm">™</span></span>
</a>
<p class="footer-tagline"><b>More</b> Than an HL7 Interface Engine</p>
<p>Open-source healthcare interface engine — secure by default, built to recognized standards, connecting a wide range of protocols and message types.</p>
<div class="badge-row" style="margin-top:16px">
<span class="badge">Open source</span>
<span class="badge">No lock-in</span>
<span class="badge">Self-hosted</span>
</div>
</div>
<div class="footer-col">
<h4>Product</h4>
<a href="/overview.html">Overview</a>
<a href="/features.html">Features</a>
<a href="/architecture.html">Architecture</a>
<a href="/reliability.html">Reliability</a>
<a href="/dicom.html">DICOM</a>
<a href="/security.html">Security & PHI</a>
<a href="/documents.html">Documents</a>
</div>
<div class="footer-col">
<h4>Tools</h4>
<a href="/tools.html">Tools</a>
<a href="/editor.html">Editor</a>
<a href="/console.html">Console</a>
<a href="/ai.html">AI assist</a>
</div>
<div class="footer-col">
<h4>Get started</h4>
<a href="/getting-started.html">Quickstart</a>
<a href="/guides/">Guides</a>
<a href="/comparison.html">Comparison</a>
</div>
<div class="footer-col">
<h4>Project</h4>
<a href="/status.html">Project status</a>
<a href="https://github.com/MEFORORG/MessageFoundry" target="_blank" rel="noopener">GitHub</a>
<a href="https://github.com/MEFORORG/MessageFoundry/issues" target="_blank" rel="noopener">Issues</a>
<a href="/contact.html">Contact</a>
<a href="/licensing.html">License</a>
<a href="/about.html">About</a>
<a href="/sponsor.html">Sponsor</a>
</div>
</div>
<div class="footer-bottom">
<span>© 2026 MEFOR-ORG, a non-profit — this website and its content, all rights reserved. The MessageFoundry engine is separately open source, licensed under AGPL-3.0-or-later.</span>
<span>MessageFoundry and the MessageFoundry word mark are trademarks of MEFOR-ORG. Mirth Connect, Cloverleaf, Rhapsody, Corepoint, and Ensemble are trademarks of their respective owners; MessageFoundry is independent and unaffiliated.</span>
</div>
</div>
</footer>
<script src="/assets/js/nav.js" defer></script>
</body>
</html>