PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
rt_storage.cpp
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
11
12#include <algorithm>
13#include <array>
14
16
17// =============================================================================
18// Transfer Syntaxes
19// =============================================================================
20
21std::vector<std::string> get_rt_transfer_syntaxes() {
22 return {
23 // Explicit VR Little Endian (preferred for interoperability)
24 "1.2.840.10008.1.2.1",
25 // Implicit VR Little Endian (universal baseline)
26 "1.2.840.10008.1.2",
27 // HTJ2K Lossless (high-throughput lossless for dose grids)
28 "1.2.840.10008.1.2.4.201",
29 // JPEG Lossless (for RT Image and RT Dose with pixel data)
30 "1.2.840.10008.1.2.4.70",
31 // JPEG 2000 Lossless (better compression for dose grids)
32 "1.2.840.10008.1.2.4.90",
33 // RLE Lossless
34 "1.2.840.10008.1.2.5"
35 };
36}
37
38// =============================================================================
39// SOP Class Information
40// =============================================================================
41
42namespace {
43
44// Static array of RT SOP class information
45constexpr std::array<rt_sop_class_info, 10> rt_sop_classes = {{
46 {
48 "RT Plan Storage",
49 "Radiation therapy treatment plan including beams and fractions",
50 false,
51 false // no pixel data
52 },
53 {
55 "RT Dose Storage",
56 "Radiation dose distribution (dose grid)",
57 false,
58 true // has pixel data (dose grid)
59 },
60 {
62 "RT Structure Set Storage",
63 "Radiation therapy structure set (ROI contours)",
64 false,
65 false // no pixel data
66 },
67 {
69 "RT Image Storage",
70 "Radiation therapy images (portal, DRR, etc.)",
71 false,
72 true // has pixel data
73 },
74 {
76 "RT Beams Treatment Record Storage",
77 "Treatment delivery record for external beam therapy",
78 false,
79 false // no pixel data
80 },
81 {
83 "RT Brachy Treatment Record Storage",
84 "Treatment delivery record for brachytherapy",
85 false,
86 false // no pixel data
87 },
88 {
90 "RT Treatment Summary Record Storage",
91 "Summary of treatment delivery",
92 false,
93 false // no pixel data
94 },
95 {
97 "RT Ion Plan Storage",
98 "Ion beam (proton, carbon) treatment plan",
99 false,
100 false // no pixel data
101 },
102 {
104 "RT Ion Beams Treatment Record Storage",
105 "Treatment delivery record for ion beam therapy",
106 false,
107 false // no pixel data
108 },
109 // Additional slot for future RT SOP classes
110 {
111 "",
112 "",
113 "",
114 true,
115 false
116 }
117}};
118
119// Number of valid RT SOP classes (excluding placeholder)
120constexpr size_t rt_sop_class_count = 9;
121
122} // namespace
123
124std::vector<std::string> get_rt_storage_sop_classes(bool include_retired) {
125 std::vector<std::string> result;
126 result.reserve(rt_sop_class_count);
127
128 for (size_t i = 0; i < rt_sop_class_count; ++i) {
129 const auto& info = rt_sop_classes[i];
130 if (!info.is_retired || include_retired) {
131 result.emplace_back(info.uid);
132 }
133 }
134
135 return result;
136}
137
138const rt_sop_class_info*
139get_rt_sop_class_info(std::string_view uid) noexcept {
140 for (size_t i = 0; i < rt_sop_class_count; ++i) {
141 if (rt_sop_classes[i].uid == uid) {
142 return &rt_sop_classes[i];
143 }
144 }
145 return nullptr;
146}
147
148bool is_rt_storage_sop_class(std::string_view uid) noexcept {
149 return get_rt_sop_class_info(uid) != nullptr;
150}
151
152bool is_rt_plan_sop_class(std::string_view uid) noexcept {
154}
155
156bool rt_sop_class_has_pixel_data(std::string_view uid) noexcept {
157 const auto* info = get_rt_sop_class_info(uid);
158 return info != nullptr && info->has_pixel_data;
159}
160
161// =============================================================================
162// RT Plan Intent Conversion
163// =============================================================================
164
165std::string_view to_string(rt_plan_intent intent) noexcept {
166 switch (intent) {
168 return "CURATIVE";
170 return "PALLIATIVE";
172 return "PROPHYLACTIC";
174 return "VERIFICATION";
176 return "MACHINE_QA";
178 return "RESEARCH";
180 return "SERVICE";
181 }
182 return "CURATIVE";
183}
184
185rt_plan_intent parse_rt_plan_intent(std::string_view value) noexcept {
186 if (value == "CURATIVE") {
188 }
189 if (value == "PALLIATIVE") {
191 }
192 if (value == "PROPHYLACTIC") {
194 }
195 if (value == "VERIFICATION") {
197 }
198 if (value == "MACHINE_QA") {
200 }
201 if (value == "RESEARCH") {
203 }
204 if (value == "SERVICE") {
206 }
208}
209
210// =============================================================================
211// RT Plan Geometry Conversion
212// =============================================================================
213
214std::string_view to_string(rt_plan_geometry geometry) noexcept {
215 switch (geometry) {
217 return "PATIENT";
219 return "TREATMENT_DEVICE";
220 }
221 return "PATIENT";
222}
223
224rt_plan_geometry parse_rt_plan_geometry(std::string_view value) noexcept {
225 if (value == "TREATMENT_DEVICE") {
227 }
229}
230
231// =============================================================================
232// RT Dose Type Conversion
233// =============================================================================
234
235std::string_view to_string(rt_dose_type type) noexcept {
236 switch (type) {
238 return "PHYSICAL";
240 return "EFFECTIVE";
242 return "ERROR";
243 }
244 return "PHYSICAL";
245}
246
247rt_dose_type parse_rt_dose_type(std::string_view value) noexcept {
248 if (value == "EFFECTIVE") {
250 }
251 if (value == "ERROR") {
252 return rt_dose_type::error;
253 }
255}
256
257// =============================================================================
258// RT Dose Summation Type Conversion
259// =============================================================================
260
261std::string_view to_string(rt_dose_summation_type type) noexcept {
262 switch (type) {
264 return "PLAN";
266 return "MULTI_PLAN";
268 return "FRACTION";
270 return "BEAM";
272 return "BRACHY";
274 return "FRACTION_SESSION";
276 return "BEAM_SESSION";
278 return "BRACHY_SESSION";
280 return "CONTROL_POINT";
282 return "RECORD";
283 }
284 return "PLAN";
285}
286
287rt_dose_summation_type parse_rt_dose_summation_type(std::string_view value) noexcept {
288 if (value == "PLAN") {
290 }
291 if (value == "MULTI_PLAN") {
293 }
294 if (value == "FRACTION") {
296 }
297 if (value == "BEAM") {
299 }
300 if (value == "BRACHY") {
302 }
303 if (value == "FRACTION_SESSION") {
305 }
306 if (value == "BEAM_SESSION") {
308 }
309 if (value == "BRACHY_SESSION") {
311 }
312 if (value == "CONTROL_POINT") {
314 }
315 if (value == "RECORD") {
317 }
319}
320
321// =============================================================================
322// RT Dose Units Conversion
323// =============================================================================
324
325std::string_view to_string(rt_dose_units units) noexcept {
326 switch (units) {
328 return "GY";
330 return "RELATIVE";
331 }
332 return "GY";
333}
334
335rt_dose_units parse_rt_dose_units(std::string_view value) noexcept {
336 if (value == "RELATIVE") {
338 }
339 return rt_dose_units::gy;
340}
341
342// =============================================================================
343// RT ROI Interpreted Type Conversion
344// =============================================================================
345
346std::string_view to_string(rt_roi_interpreted_type type) noexcept {
347 switch (type) {
349 return "EXTERNAL";
351 return "PTV";
353 return "CTV";
355 return "GTV";
357 return "ORGAN";
359 return "AVOIDANCE";
361 return "TREATED_VOLUME";
363 return "IRRAD_VOLUME";
365 return "BOLUS";
367 return "BRACHY_CHANNEL";
369 return "BRACHY_ACCESSORY";
371 return "BRACHY_SRC_APPL";
373 return "BRACHY_CHNL_SHLD";
375 return "SUPPORT";
377 return "FIXATION";
379 return "DOSE_REGION";
381 return "CONTRAST_AGENT";
383 return "CAVITY";
385 return "MARKER";
387 return "REGISTRATION";
389 return "ISOCENTER";
391 return "CONTROL";
392 }
393 return "ORGAN";
394}
395
397 if (value == "EXTERNAL") {
399 }
400 if (value == "PTV") {
402 }
403 if (value == "CTV") {
405 }
406 if (value == "GTV") {
408 }
409 if (value == "ORGAN") {
411 }
412 if (value == "AVOIDANCE") {
414 }
415 if (value == "TREATED_VOLUME") {
417 }
418 if (value == "IRRAD_VOLUME") {
420 }
421 if (value == "BOLUS") {
423 }
424 if (value == "BRACHY_CHANNEL") {
426 }
427 if (value == "BRACHY_ACCESSORY") {
429 }
430 if (value == "BRACHY_SRC_APPL") {
432 }
433 if (value == "BRACHY_CHNL_SHLD") {
435 }
436 if (value == "SUPPORT") {
438 }
439 if (value == "FIXATION") {
441 }
442 if (value == "DOSE_REGION") {
444 }
445 if (value == "CONTRAST_AGENT") {
447 }
448 if (value == "CAVITY") {
450 }
451 if (value == "MARKER") {
453 }
454 if (value == "REGISTRATION") {
456 }
457 if (value == "ISOCENTER") {
459 }
460 if (value == "CONTROL") {
462 }
464}
465
466// =============================================================================
467// RT ROI Generation Algorithm Conversion
468// =============================================================================
469
470std::string_view to_string(rt_roi_generation_algorithm algorithm) noexcept {
471 switch (algorithm) {
473 return "AUTOMATIC";
475 return "SEMIAUTOMATIC";
477 return "MANUAL";
478 }
479 return "MANUAL";
480}
481
483parse_rt_roi_generation_algorithm(std::string_view value) noexcept {
484 if (value == "AUTOMATIC") {
486 }
487 if (value == "SEMIAUTOMATIC") {
489 }
491}
492
493// =============================================================================
494// RT Beam Type Conversion
495// =============================================================================
496
497std::string_view to_string(rt_beam_type type) noexcept {
498 switch (type) {
500 return "STATIC";
502 return "DYNAMIC";
503 }
504 return "STATIC";
505}
506
507rt_beam_type parse_rt_beam_type(std::string_view value) noexcept {
508 if (value == "DYNAMIC") {
510 }
512}
513
514// =============================================================================
515// RT Radiation Type Conversion
516// =============================================================================
517
518std::string_view to_string(rt_radiation_type type) noexcept {
519 switch (type) {
521 return "PHOTON";
523 return "ELECTRON";
525 return "NEUTRON";
527 return "PROTON";
529 return "ION";
530 }
531 return "PHOTON";
532}
533
534rt_radiation_type parse_rt_radiation_type(std::string_view value) noexcept {
535 if (value == "PHOTON") {
537 }
538 if (value == "ELECTRON") {
540 }
541 if (value == "NEUTRON") {
543 }
544 if (value == "PROTON") {
546 }
547 if (value == "ION") {
549 }
551}
552
553// =============================================================================
554// RT Treatment Delivery Type Conversion
555// =============================================================================
556
557std::string_view to_string(rt_treatment_delivery_type type) noexcept {
558 switch (type) {
560 return "TREATMENT";
562 return "OPEN_PORTFILM";
564 return "TRMT_PORTFILM";
566 return "CONTINUATION";
568 return "SETUP";
569 }
570 return "TREATMENT";
571}
572
574parse_rt_treatment_delivery_type(std::string_view value) noexcept {
575 if (value == "TREATMENT") {
577 }
578 if (value == "OPEN_PORTFILM") {
580 }
581 if (value == "TRMT_PORTFILM") {
583 }
584 if (value == "CONTINUATION") {
586 }
587 if (value == "SETUP") {
589 }
591}
592
593// =============================================================================
594// RT Image Plane Conversion
595// =============================================================================
596
597std::string_view to_string(rt_image_plane plane) noexcept {
598 switch (plane) {
600 return "AXIAL";
602 return "LOCALIZER";
604 return "DRR";
606 return "PORTAL";
608 return "FLUENCE";
609 }
610 return "PORTAL";
611}
612
613rt_image_plane parse_rt_image_plane(std::string_view value) noexcept {
614 if (value == "AXIAL") {
616 }
617 if (value == "LOCALIZER") {
619 }
620 if (value == "DRR") {
621 return rt_image_plane::drr;
622 }
623 if (value == "PORTAL") {
625 }
626 if (value == "FLUENCE") {
628 }
630}
631
632} // namespace kcenon::pacs::services::sop_classes
rt_plan_intent parse_rt_plan_intent(std::string_view value) noexcept
Parse RT plan intent from DICOM string.
const rt_sop_class_info * get_rt_sop_class_info(std::string_view uid) noexcept
Get information about a specific RT SOP Class.
rt_dose_units parse_rt_dose_units(std::string_view value) noexcept
Parse RT dose units from DICOM string.
constexpr std::string_view rt_structure_set_storage_uid
RT Structure Set Storage SOP Class UID.
Definition rt_storage.h:46
constexpr std::string_view rt_image_storage_uid
RT Image Storage SOP Class UID.
Definition rt_storage.h:50
constexpr std::string_view rt_ion_plan_storage_uid
RT Ion Plan Storage SOP Class UID.
Definition rt_storage.h:66
rt_roi_generation_algorithm
RT ROI Generation Algorithm.
Definition rt_storage.h:332
@ semiautomatic
SEMIAUTOMATIC - Semi-automated with user input.
constexpr std::string_view rt_dose_storage_uid
RT Dose Storage SOP Class UID.
Definition rt_storage.h:42
rt_roi_generation_algorithm parse_rt_roi_generation_algorithm(std::string_view value) noexcept
Parse RT ROI generation algorithm from DICOM string.
std::vector< std::string > get_rt_transfer_syntaxes()
Get recommended transfer syntaxes for RT objects.
rt_image_plane parse_rt_image_plane(std::string_view value) noexcept
Parse RT image plane from DICOM string.
bool rt_sop_class_has_pixel_data(std::string_view uid) noexcept
Check if a SOP Class UID contains pixel data.
rt_treatment_delivery_type
RT Treatment Delivery Type.
Definition rt_storage.h:407
@ continuation
CONTINUATION - Continuation of interrupted treatment.
@ trmt_portfilm
TRMT_PORTFILM - Treatment field portal image.
@ open_portfilm
OPEN_PORTFILM - Open field portal image.
rt_plan_geometry parse_rt_plan_geometry(std::string_view value) noexcept
Parse RT plan geometry from DICOM string.
rt_beam_type parse_rt_beam_type(std::string_view value) noexcept
Parse RT beam type from DICOM string.
@ effective
EFFECTIVE - Effective dose (RBE weighted)
@ error
ERROR - Dose error/uncertainty.
bool is_rt_storage_sop_class(std::string_view uid) noexcept
Check if a SOP Class UID is an RT Storage SOP Class.
rt_dose_summation_type parse_rt_dose_summation_type(std::string_view value) noexcept
Parse RT dose summation type from DICOM string.
bool is_rt_plan_sop_class(std::string_view uid) noexcept
Check if a SOP Class UID is an RT Plan type.
constexpr std::string_view rt_beams_treatment_record_storage_uid
RT Beams Treatment Record Storage SOP Class UID.
Definition rt_storage.h:54
rt_roi_interpreted_type parse_rt_roi_interpreted_type(std::string_view value) noexcept
Parse RT ROI interpreted type from DICOM string.
constexpr std::string_view rt_ion_beams_treatment_record_storage_uid
RT Ion Beams Treatment Record Storage SOP Class UID.
Definition rt_storage.h:70
std::vector< std::string > get_rt_storage_sop_classes(bool include_retired=true)
Get all RT Storage SOP Class UIDs.
rt_dose_summation_type
RT Dose Summation Type.
Definition rt_storage.h:234
@ brachy_session
BRACHY_SESSION - Brachytherapy session dose.
@ beam_session
BEAM_SESSION - Single beam session dose.
@ control_point
CONTROL_POINT - Single control point dose.
@ fraction_session
FRACTION_SESSION - Single fraction session dose.
rt_dose_type parse_rt_dose_type(std::string_view value) noexcept
Parse RT dose type from DICOM string.
@ treatment_device
TREATMENT_DEVICE - Device-based plan.
rt_radiation_type parse_rt_radiation_type(std::string_view value) noexcept
Parse RT radiation type from DICOM string.
@ curative
CURATIVE - Treatment with curative intent.
@ prophylactic
PROPHYLACTIC - Preventive treatment.
@ machine_qa
MACHINE_QA - Machine quality assurance.
@ verification
VERIFICATION - Plan verification.
@ palliative
PALLIATIVE - Treatment for symptom relief.
rt_image_plane
RT Image Type values (as used in Image Type attribute)
Definition rt_storage.h:437
@ drr
DRR - Digitally Reconstructed Radiograph.
@ localizer
LOCALIZER - Localizer/scout image.
constexpr std::string_view rt_brachy_treatment_record_storage_uid
RT Brachy Treatment Record Storage SOP Class UID.
Definition rt_storage.h:58
constexpr std::string_view rt_treatment_summary_record_storage_uid
RT Treatment Summary Record Storage SOP Class UID.
Definition rt_storage.h:62
rt_roi_interpreted_type
RT ROI Interpreted Type.
Definition rt_storage.h:290
@ contrast_agent
CONTRAST_AGENT - Contrast agent region.
@ registration
REGISTRATION - Registration structure.
@ dose_region
DOSE_REGION - Dose reference region.
@ brachy_chnl_shld
BRACHY_CHNL_SHLD - Brachytherapy channel shield.
@ brachy_channel
BRACHY_CHANNEL - Brachytherapy channel.
@ brachy_accessory
BRACHY_ACCESSORY - Brachytherapy accessory.
@ brachy_src_appl
BRACHY_SRC_APPL - Brachytherapy source applicator.
constexpr std::string_view rt_plan_storage_uid
RT Plan Storage SOP Class UID.
Definition rt_storage.h:38
rt_treatment_delivery_type parse_rt_treatment_delivery_type(std::string_view value) noexcept
Parse RT treatment delivery type from DICOM string.
@ dynamic
DYNAMIC - Dynamic beam (IMRT, VMAT)
std::string_view to_string(dx_photometric_interpretation interp) noexcept
Convert photometric interpretation enum to DICOM string.
Radiation Therapy (RT) Storage SOP Classes.
std::string_view uid