PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
worklist_scu.h
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
21#ifndef PACS_SERVICES_WORKLIST_SCU_HPP
22#define PACS_SERVICES_WORKLIST_SCU_HPP
23
27
28#include <atomic>
29#include <chrono>
30#include <cstdint>
31#include <functional>
32#include <memory>
33#include <string>
34#include <vector>
35
36namespace kcenon::pacs::services {
37
38// =============================================================================
39// Worklist Query Keys Structure
40// =============================================================================
41
50 // =========================================================================
51 // Scheduled Procedure Step Attributes
52 // =========================================================================
53
56
58 std::string modality;
59
61 std::string scheduled_date;
62
64 std::string scheduled_time;
65
68
71
72 // =========================================================================
73 // Requested Procedure Attributes
74 // =========================================================================
75
78
81
82 // =========================================================================
83 // Patient Attributes
84 // =========================================================================
85
87 std::string patient_name;
88
90 std::string patient_id;
91
93 std::string patient_birth_date;
94
96 std::string patient_sex;
97
98 // =========================================================================
99 // Visit Attributes
100 // =========================================================================
101
103 std::string accession_number;
104
107
109 std::string institution;
110};
111
112// =============================================================================
113// Worklist Item Structure
114// =============================================================================
115
123 // =========================================================================
124 // Patient Demographics
125 // =========================================================================
126
128 std::string patient_name;
129
131 std::string patient_id;
132
135
137 std::string patient_sex;
138
139 // =========================================================================
140 // Scheduled Procedure Step
141 // =========================================================================
142
145
147 std::string modality;
148
150 std::string scheduled_date;
151
153 std::string scheduled_time;
154
157
160
161 // =========================================================================
162 // Requested Procedure
163 // =========================================================================
164
167
169 std::string accession_number;
170
173
176
177 // =========================================================================
178 // Visit Information
179 // =========================================================================
180
183
185 std::string institution;
186
187 // =========================================================================
188 // Original Dataset
189 // =========================================================================
190
193};
194
195// =============================================================================
196// Worklist Result Structure
197// =============================================================================
198
206 std::vector<worklist_item> items;
207
209 uint16_t status{0};
210
212 std::chrono::milliseconds elapsed{0};
213
216 size_t total_pending{0};
217
219 [[nodiscard]] bool is_success() const noexcept {
220 return status == 0x0000;
221 }
222
224 [[nodiscard]] bool is_cancelled() const noexcept {
225 return status == 0xFE00;
226 }
227};
228
229// =============================================================================
230// Worklist SCU Configuration
231// =============================================================================
232
238 std::chrono::milliseconds timeout{30000};
239
241 size_t max_results{0};
242
244 bool cancel_on_max{true};
245};
246
247// =============================================================================
248// Streaming Callback Type
249// =============================================================================
250
259using worklist_streaming_callback = std::function<bool(const worklist_item&)>;
260
261// =============================================================================
262// Worklist SCU Class
263// =============================================================================
264
358public:
359 // =========================================================================
360 // Construction
361 // =========================================================================
362
368 explicit worklist_scu(std::shared_ptr<di::ILogger> logger = nullptr);
369
377 std::shared_ptr<di::ILogger> logger = nullptr);
378
379 ~worklist_scu() = default;
380
381 // Non-copyable, non-movable (due to atomic members)
382 worklist_scu(const worklist_scu&) = delete;
386
387 // =========================================================================
388 // Generic Query Operations
389 // =========================================================================
390
403 const worklist_query_keys& keys);
404
417 const core::dicom_dataset& query_keys);
418
419 // =========================================================================
420 // Convenience Query Methods
421 // =========================================================================
422
436 std::string_view station_ae,
437 std::string_view modality = "");
438
453 std::string_view start_date,
454 std::string_view end_date,
455 std::string_view modality = "");
456
468 std::string_view patient_id);
469
470 // =========================================================================
471 // Streaming Query
472 // =========================================================================
473
487 const worklist_query_keys& keys,
489
490 // =========================================================================
491 // C-CANCEL Support
492 // =========================================================================
493
503 uint16_t message_id);
504
505 // =========================================================================
506 // Configuration
507 // =========================================================================
508
515
521 [[nodiscard]] const worklist_scu_config& config() const noexcept;
522
523 // =========================================================================
524 // Statistics
525 // =========================================================================
526
531 [[nodiscard]] size_t queries_performed() const noexcept;
532
537 [[nodiscard]] size_t total_items() const noexcept;
538
542 void reset_statistics() noexcept;
543
544private:
545 // =========================================================================
546 // Private Implementation
547 // =========================================================================
548
553 const core::dicom_dataset& ds) const;
554
558 [[nodiscard]] core::dicom_dataset build_query_dataset(
559 const worklist_query_keys& keys) const;
560
564 [[nodiscard]] uint16_t next_message_id() noexcept;
565
569 [[nodiscard]] network::Result<worklist_result> query_impl(
570 network::association& assoc,
571 const core::dicom_dataset& query_keys,
572 uint16_t message_id);
573
577 [[nodiscard]] static std::string get_today_date();
578
579 // =========================================================================
580 // Private Members
581 // =========================================================================
582
584 std::shared_ptr<di::ILogger> logger_;
585
588
590 std::atomic<uint16_t> message_id_counter_{1};
591
593 std::atomic<size_t> queries_performed_{0};
594
596 std::atomic<size_t> total_items_{0};
597};
598
599} // namespace kcenon::pacs::services
600
601#endif // PACS_SERVICES_WORKLIST_SCU_HPP
DICOM Association management per PS3.8.
void reset_statistics() noexcept
Reset statistics counters to zero.
worklist_scu(std::shared_ptr< di::ILogger > logger=nullptr)
Construct a Worklist SCU with default configuration.
std::atomic< size_t > total_items_
Statistics: total number of items received.
network::Result< worklist_result > query_impl(network::association &assoc, const core::dicom_dataset &query_keys, uint16_t message_id)
Internal query implementation.
std::atomic< uint16_t > message_id_counter_
Message ID counter.
size_t queries_performed() const noexcept
Get the number of queries performed since construction.
std::shared_ptr< di::ILogger > logger_
Logger instance for service logging.
worklist_scu & operator=(const worklist_scu &)=delete
network::Result< worklist_result > query_patient(network::association &assoc, std::string_view patient_id)
Query worklist by patient ID.
network::Result< std::monostate > cancel(network::association &assoc, uint16_t message_id)
Send a C-CANCEL request to stop an ongoing query.
uint16_t next_message_id() noexcept
Get the next message ID for DIMSE operations.
const worklist_scu_config & config() const noexcept
Get the current configuration.
network::Result< worklist_result > query(network::association &assoc, const worklist_query_keys &keys)
Perform a MWL C-FIND query with typed keys.
static std::string get_today_date()
Get today's date in DICOM format (YYYYMMDD)
std::atomic< size_t > queries_performed_
Statistics: number of queries performed.
core::dicom_dataset build_query_dataset(const worklist_query_keys &keys) const
Build query dataset from typed keys.
worklist_scu & operator=(worklist_scu &&)=delete
worklist_scu_config config_
Configuration.
worklist_scu(const worklist_scu &)=delete
void set_config(const worklist_scu_config &config)
Update the SCU configuration.
size_t total_items() const noexcept
Get the total number of items received since construction.
worklist_item parse_worklist_item(const core::dicom_dataset &ds) const
Parse a worklist item from a response dataset.
network::Result< size_t > query_streaming(network::association &assoc, const worklist_query_keys &keys, worklist_streaming_callback callback)
Perform a streaming MWL query for large worklists.
network::Result< worklist_result > query_date_range(network::association &assoc, std::string_view start_date, std::string_view end_date, std::string_view modality="")
Query worklist by date range.
network::Result< worklist_result > query_today(network::association &assoc, std::string_view station_ae, std::string_view modality="")
Query today's worklist for a station.
worklist_scu(worklist_scu &&)=delete
DICOM Dataset - ordered collection of Data Elements.
Logger interface for dependency injection.
std::function< bool(const worklist_item &)> worklist_streaming_callback
Callback type for streaming worklist query results.
Parsed worklist item from MWL query response.
std::string institution
Institution Name (0008,0080)
std::string patient_id
Patient ID (0010,0020)
std::string scheduled_date
Scheduled Procedure Step Start Date (0040,0002)
std::string scheduled_procedure_step_id
Scheduled Procedure Step ID (0040,0009)
std::string study_instance_uid
Study Instance UID (0020,000D) - Pre-assigned Study UID.
std::string requested_procedure_description
Requested Procedure Description (0032,1060)
std::string scheduled_station_ae
Scheduled Station AE Title (0040,0001)
std::string patient_name
Patient's Name (0010,0010)
std::string requested_procedure_id
Requested Procedure ID (0040,1001)
std::string patient_birth_date
Patient's Birth Date (0010,0030)
std::string scheduled_procedure_step_description
Scheduled Procedure Step Description (0040,0007)
std::string referring_physician
Referring Physician's Name (0008,0090)
std::string modality
Modality (0008,0060)
std::string patient_sex
Patient's Sex (0010,0040)
std::string scheduled_time
Scheduled Procedure Step Start Time (0040,0003)
std::string accession_number
Accession Number (0008,0050)
core::dicom_dataset dataset
Original dataset for full access to all attributes.
Typed query keys for Modality Worklist queries.
std::string scheduled_station_ae
Scheduled Station AE Title (0040,0001)
std::string institution
Institution Name (0008,0080)
std::string scheduled_date
Scheduled Procedure Step Start Date (0040,0002) - YYYYMMDD or range.
std::string modality
Modality (0008,0060) - e.g., CT, MR, US, XR.
std::string requested_procedure_id
Requested Procedure ID (0040,1001)
std::string patient_sex
Patient's Sex (0010,0040) - M, F, O.
std::string scheduled_physician
Scheduled Performing Physician's Name (0040,0006)
std::string referring_physician
Referring Physician's Name (0008,0090)
std::string accession_number
Accession Number (0008,0050)
std::string requested_procedure_description
Requested Procedure Description (0032,1060)
std::string patient_name
Patient's Name (0010,0010) - supports wildcards (* ?)
std::string patient_id
Patient ID (0010,0020)
std::string scheduled_procedure_step_id
Scheduled Procedure Step ID (0040,0009)
std::string patient_birth_date
Patient's Birth Date (0010,0030)
std::string scheduled_time
Scheduled Procedure Step Start Time (0040,0003) - HHMMSS or range.
Result of a Modality Worklist query operation.
std::vector< worklist_item > items
Parsed worklist items from the query.
bool is_success() const noexcept
Check if the query was successful.
std::chrono::milliseconds elapsed
Query execution time.
size_t total_pending
Total pending responses received (may differ from items.size() if max_results was enforced)
bool is_cancelled() const noexcept
Check if the query was cancelled.
uint16_t status
Final DIMSE status code (0x0000 = success)
Configuration for Worklist SCU service.
std::chrono::milliseconds timeout
Timeout for receiving query responses (milliseconds)
size_t max_results
Maximum number of results to return (0 = unlimited)
bool cancel_on_max
Send C-CANCEL when max_results is reached.