19#include <unordered_map>
56void insert_sequence(dicom_dataset& ds, dicom_tag tag,
57 std::vector<dicom_dataset> items) {
58 dicom_element seq_elem(tag, vr_type::SQ);
59 seq_elem.sequence_items() = std::move(items);
60 ds.insert(std::move(seq_elem));
63std::string current_datetime() {
64 auto now = std::chrono::system_clock::now();
65 auto time_t_now = std::chrono::system_clock::to_time_t(now);
68 gmtime_s(&tm_now, &time_t_now);
70 gmtime_r(&time_t_now, &tm_now);
73 std::strftime(buf,
sizeof(buf),
"%Y%m%d%H%M%S", &tm_now);
77std::string current_date() {
78 return current_datetime().substr(0, 8);
81std::string current_time() {
82 return current_datetime().substr(8, 6);
96 const std::string& study_instance_uid,
97 const std::vector<kos_instance_reference>& references,
98 const std::optional<core::dicom_dataset>& patient_demographics)
const {
102 if (references.empty()) {
116 if (patient_demographics) {
118 if (patient_demographics->contains(tag)) {
119 kos.
set_string(tag,
vr, patient_demographics->get_string(tag));
217 if (!ref_physician.empty()) {
221 entry.
title =
"Key Object Selection Document";
227 const std::string& patient_id)
const {
233 set.patient_id = patient_id;
234 set.content_type_code =
"IMG";
235 set.content_type_code_scheme =
"1.3.6.1.4.1.19376.3.840.1.1.4";
236 set.content_type_code_display =
"Imaging Procedure";
237 set.submission_time = current_datetime();
274 static constexpr const char* uid_root =
"1.2.826.0.1.3680043.2.1545.1";
275 static std::mt19937_64 gen{std::random_device{}()};
276 static std::uniform_int_distribution<uint64_t> dist;
278 auto now = std::chrono::system_clock::now();
279 auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(
280 now.time_since_epoch()).count();
282 return std::string(uid_root) +
"." + std::to_string(timestamp) +
283 "." + std::to_string(dist(gen) % 100000);
288 const std::vector<kos_instance_reference>& references)
const {
291 struct series_group {
292 std::string series_uid;
293 std::vector<std::pair<std::string, std::string>> instances;
296 std::unordered_map<std::string, std::vector<series_group>> study_map;
298 for (
const auto& ref : references) {
299 auto& series_list = study_map[ref.study_instance_uid];
301 auto it = std::find_if(series_list.begin(), series_list.end(),
302 [&](
const series_group& sg) {
303 return sg.series_uid == ref.series_instance_uid;
306 if (it != series_list.end()) {
307 it->instances.emplace_back(ref.sop_class_uid, ref.sop_instance_uid);
310 sg.series_uid = ref.series_instance_uid;
311 sg.instances.emplace_back(ref.sop_class_uid, ref.sop_instance_uid);
312 series_list.push_back(std::move(sg));
317 std::vector<dicom_dataset> study_items;
318 for (
const auto& [study_uid, series_list] : study_map) {
322 std::vector<dicom_dataset> series_items;
323 for (
const auto& sg : series_list) {
327 std::vector<dicom_dataset> sop_items;
328 for (
const auto& [sop_class, sop_instance] : sg.instances) {
332 sop_items.push_back(std::move(sop_item));
335 series_items.push_back(std::move(series_item));
338 study_items.push_back(std::move(study_item));
341 insert_sequence(kos_dataset,
343 std::move(study_items));
void set_string(dicom_tag tag, encoding::vr_type vr, std::string_view value)
Set a string value for the given tag.
auto get_string(dicom_tag tag, std::string_view default_value="") const -> std::string
Get the string value of an element.
const imaging_document_source_config & config() const noexcept
Get current configuration.
imaging_document_source()=default
std::string generate_uid() const
Generate a new UID for KOS instances.
void build_evidence_sequence(core::dicom_dataset &kos_dataset, const std::vector< kos_instance_reference > &references) const
Build the Current Requested Procedure Evidence Sequence.
publication_result publish_document(const core::dicom_dataset &kos_dataset, const xds_document_entry &entry) const
Publish a KOS document to the XDS registry/repository.
void set_config(const imaging_document_source_config &config)
Set configuration.
xds_submission_set build_submission_set(const std::string &patient_id) const
Build XDS submission set metadata.
kos_creation_result create_kos_document(const std::string &study_instance_uid, const std::vector< kos_instance_reference > &references, const std::optional< core::dicom_dataset > &patient_demographics=std::nullopt) const
Create a KOS document from a set of DICOM instance references.
xds_document_entry build_document_entry(const core::dicom_dataset &kos_dataset) const
Build XDS document entry metadata from a KOS dataset.
imaging_document_source_config config_
Compile-time constants for commonly used DICOM tags.
IHE XDS-I.b Imaging Document Source Actor.
vr_type
DICOM Value Representation (VR) types.
constexpr std::string_view key_object_selection_document_storage_uid
Key Object Selection Document Storage SOP Class UID.
Structured Report (SR) Storage SOP Classes.
Configuration for the Imaging Document Source actor.
std::string source_oid
Source system OID (used as sourceId in submissions)
std::string practice_setting_code_scheme
std::string practice_setting_code
Default practice setting code.
std::string registry_url
XDS Registry/Repository endpoint URL.
std::string facility_type_code_scheme
std::string facility_type_code
Default facility type code.
Result of a KOS document creation operation.
std::optional< core::dicom_dataset > kos_dataset
The created KOS dataset (if successful)
std::string error_message
Error message (if failed)
size_t reference_count
Number of referenced instances.
std::string kos_instance_uid
SOP Instance UID of the created KOS.
bool success
Whether the KOS was created successfully.
Result of publishing a document to an XDS registry/repository.
std::string document_entry_uuid
Registry-assigned document entry UUID.
std::string error_message
Error message (if failed)
bool success
Whether the publication was successful.
Document entry metadata for XDS registry submission.
std::string creation_time
Creation time (DTM format: YYYYMMDDhhmmss)
std::string patient_id
Patient ID in CX format (ID^^^&OID&ISO)
std::string format_code_scheme
std::string type_code_display
std::string service_start_time
Service start/stop time.
std::string class_code
Document class code (e.g., "Imaging Procedure")
std::string class_code_scheme
std::string facility_type_code_scheme
std::string type_code
Type code (e.g., "Key Object Selection")
std::string unique_id
Document unique ID (OID format)
std::string facility_type_code
Healthcare facility type.
std::string source_patient_id
Source patient ID (from the originating system)
std::string type_code_scheme
std::string class_code_display
std::string author_person
Author information.
std::string format_code
Format code (e.g., "1.2.840.10008.5.1.4.1.1.88.59")
std::string entry_uuid
Unique identifier for this document entry.
std::string service_stop_time
std::string title
Title/description.
std::string practice_setting_code_scheme
std::string practice_setting_code
Practice setting code.
Submission set metadata for XDS registry.