dicom 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +17 -0
- data/README.rdoc +16 -3
- data/lib/dicom.rb +3 -1
- data/lib/dicom/anonymizer.rb +35 -54
- data/lib/dicom/d_client.rb +49 -64
- data/lib/dicom/d_object.rb +511 -416
- data/lib/dicom/d_read.rb +21 -34
- data/lib/dicom/d_server.rb +21 -61
- data/lib/dicom/d_write.rb +3 -6
- data/lib/dicom/element.rb +1 -1
- data/lib/dicom/file_handler.rb +14 -9
- data/lib/dicom/image_item.rb +7 -6
- data/lib/dicom/link.rb +42 -77
- data/lib/dicom/logging.rb +158 -0
- data/lib/dicom/parent.rb +9 -8
- data/lib/dicom/sequence.rb +1 -1
- data/lib/dicom/version.rb +1 -1
- metadata +5 -4
data/CHANGELOG.rdoc
CHANGED
@@ -1,9 +1,26 @@
|
|
1
|
+
= 0.9.2
|
2
|
+
|
3
|
+
=== (Not released yet)
|
4
|
+
|
5
|
+
* Enabled the use of lower case tag letters in methods which previously required the use of upper case letters.
|
6
|
+
* Added new DObject class methods to offload DObject#new:
|
7
|
+
* DObject#read is the new preferred method for reading a DICOM file.
|
8
|
+
* DObject#parse is the new preferred method for parsing an encoded DICOM string.
|
9
|
+
* The experimental feature of retrieving a DICOM file through http was moved to DObject#get.
|
10
|
+
* Calling DObject with a string argument was deprecated.
|
11
|
+
* Introduced proper logging capabilities which replaced the simple message printouts to STDOUT:
|
12
|
+
* Based on the Logger class of the Ruby Standard Library.
|
13
|
+
* Automatically integrates with the Rails logger in a Rails application.
|
14
|
+
* Supports information levels, logging to file, and more as available in the Ruby Logger.
|
15
|
+
|
16
|
+
|
1
17
|
= 0.9.1
|
2
18
|
|
3
19
|
=== 27th May, 2011
|
4
20
|
|
5
21
|
* Fixed a regression in 0.9 where ruby-dicom would cause a Rails application to crash.
|
6
22
|
|
23
|
+
|
7
24
|
= 0.9
|
8
25
|
|
9
26
|
=== 17th May, 2011
|
data/README.rdoc
CHANGED
@@ -23,7 +23,7 @@ communication modalities like querying, moving, sending and receiving files.
|
|
23
23
|
=== Read, modify and write
|
24
24
|
|
25
25
|
# Read file:
|
26
|
-
obj = DObject.
|
26
|
+
obj = DObject.read("some_file.dcm")
|
27
27
|
# Extract the Patient's Name value:
|
28
28
|
obj.patients_name.value
|
29
29
|
# Add or modify the Patient's Name element:
|
@@ -72,6 +72,18 @@ communication modalities like querying, moving, sending and receiving files.
|
|
72
72
|
s = DServer.new(104, :host_ae => "MY_DICOM_SERVER")
|
73
73
|
s.start_scp("C:/temp/")
|
74
74
|
|
75
|
+
=== Log settings
|
76
|
+
|
77
|
+
# Change the log level so that only error messages are displayed:
|
78
|
+
DICOM.logger.level = Logger::ERROR
|
79
|
+
# Setting up a simple file log:
|
80
|
+
l = Logger.new('my_logfile.log')
|
81
|
+
DICOM.logger = l
|
82
|
+
# Create a logger which ages logfile daily/monthly:
|
83
|
+
DICOM.logger = Logger.new('foo.log', 'daily')
|
84
|
+
DICOM.logger = Logger.new('foo.log', 'monthly')
|
85
|
+
|
86
|
+
|
75
87
|
=== IRB Tip
|
76
88
|
|
77
89
|
When working with Ruby DICOM in irb, you may be annoyed with all the information
|
@@ -120,7 +132,8 @@ Please don't hesitate to email me if you have any feedback related to this proje
|
|
120
132
|
|
121
133
|
* {Christoffer Lervåg}[https://github.com/dicom]
|
122
134
|
* {John Axel Eriksson}[https://github.com/johnae]
|
135
|
+
* {Kamil Bujniewicz}[https://github.com/icdark]
|
123
136
|
* {Donnie Millar}[https://github.com/dmillar]
|
124
|
-
* Björn Albers
|
137
|
+
* {Björn Albers}[https://github.com/bjoernalbers]
|
125
138
|
* {Lars Benner}[https://github.com/Maturin]
|
126
|
-
* {Steven Bedrick}[https://github.com/stevenbedrick]
|
139
|
+
* {Steven Bedrick}[https://github.com/stevenbedrick]
|
data/lib/dicom.rb
CHANGED
@@ -11,6 +11,8 @@
|
|
11
11
|
# The rest of the classes visible in the documentation generated by RDoc is in principle
|
12
12
|
# 'private' classes, which are mainly of interest to developers.
|
13
13
|
|
14
|
+
# Logging:
|
15
|
+
require 'dicom/logging'
|
14
16
|
# Core library:
|
15
17
|
# Super classes/modules:
|
16
18
|
require 'dicom/image_processor'
|
@@ -42,4 +44,4 @@ require 'dicom/image_processor_mini_magick'
|
|
42
44
|
require 'dicom/image_processor_r_magick'
|
43
45
|
|
44
46
|
# Extensions (non-core functionality):
|
45
|
-
require 'dicom/anonymizer'
|
47
|
+
require 'dicom/anonymizer'
|
data/lib/dicom/anonymizer.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module DICOM
|
3
2
|
|
4
3
|
# This is a convenience class for handling anonymization of DICOM files.
|
@@ -10,6 +9,7 @@ module DICOM
|
|
10
9
|
# (Clinical Trials De-identification Profiles, DICOM Standards Committee, Working Group 18)
|
11
10
|
#
|
12
11
|
class Anonymizer
|
12
|
+
include Logging
|
13
13
|
|
14
14
|
# A boolean that if set as true will cause all anonymized tags to be blank instead of get some generic value.
|
15
15
|
attr_accessor :blank
|
@@ -26,23 +26,17 @@ module DICOM
|
|
26
26
|
|
27
27
|
# Creates an Anonymizer instance.
|
28
28
|
#
|
29
|
-
# ===
|
30
|
-
#
|
31
|
-
# * <tt>options</tt> -- A hash of parameters.
|
32
|
-
#
|
33
|
-
# === Options
|
29
|
+
# === Notes
|
34
30
|
#
|
35
|
-
# *
|
31
|
+
# * To customize logging behaviour, refer to the Logging module documentation.
|
36
32
|
#
|
37
33
|
# === Examples
|
38
34
|
#
|
35
|
+
# # Create an Anonymizer instance and restrict the log output:
|
39
36
|
# a = Anonymizer.new
|
40
|
-
#
|
41
|
-
# a = Anonymizer.new(:verbose => false)
|
37
|
+
# a.logger.level = Logger::ERROR
|
42
38
|
#
|
43
|
-
def initialize
|
44
|
-
# Default verbosity is true if verbosity hasn't been specified (nil):
|
45
|
-
@verbose = (options[:verbose] == false ? false : true)
|
39
|
+
def initialize
|
46
40
|
# Default value of accessors:
|
47
41
|
@blank = false
|
48
42
|
@enumeration = false
|
@@ -120,7 +114,7 @@ module DICOM
|
|
120
114
|
if pos
|
121
115
|
return @enumerations[pos]
|
122
116
|
else
|
123
|
-
|
117
|
+
logger.warn("The specified tag (#{tag}) was not found in the list of tags to be anonymized.")
|
124
118
|
return nil
|
125
119
|
end
|
126
120
|
end
|
@@ -133,47 +127,45 @@ module DICOM
|
|
133
127
|
#
|
134
128
|
# * Only top level data elements are anonymized!
|
135
129
|
#
|
136
|
-
# === Parameters
|
137
|
-
#
|
138
|
-
# * <tt>verbose</tt> -- Boolean. If set as true, verbose behaviour will be set for the DObject instances that are anonymized. Defaults to false.
|
139
|
-
#
|
140
130
|
#--
|
141
131
|
# FIXME: This method has grown a bit lengthy. Perhaps it should be looked at one day.
|
142
132
|
#
|
143
|
-
def execute
|
133
|
+
def execute
|
144
134
|
# Search through the folders to gather all the files to be anonymized:
|
145
|
-
|
146
|
-
add_msg("Initiating anonymization process.")
|
135
|
+
logger.info("Initiating anonymization process.")
|
147
136
|
start_time = Time.now.to_f
|
148
|
-
|
137
|
+
logger.info("Searching for files...")
|
149
138
|
load_files
|
150
|
-
|
139
|
+
logger.info("Done.")
|
151
140
|
if @files.length > 0
|
152
141
|
if @tags.length > 0
|
153
|
-
|
142
|
+
logger.info(@files.length.to_s + " files have been identified in the specified folder(s).")
|
154
143
|
if @write_path
|
155
144
|
# Determine the write paths, as anonymized files will be written to a separate location:
|
156
|
-
|
145
|
+
logger.info("Processing write paths...")
|
157
146
|
process_write_paths
|
158
|
-
|
147
|
+
logger.info("Done")
|
159
148
|
else
|
160
149
|
# Overwriting old files:
|
161
|
-
|
150
|
+
logger.warn("Separate write folder not specified. Existing DICOM files will be overwritten.")
|
162
151
|
@write_paths = @files
|
163
152
|
end
|
164
153
|
# If the user wants enumeration, we need to prepare variables for storing
|
165
154
|
# existing information associated with each tag:
|
166
155
|
create_enum_hash if @enumeration
|
167
156
|
# Start the read/update/write process:
|
168
|
-
|
157
|
+
logger.info("Initiating read/update/write process. This may take some time...")
|
169
158
|
# Monitor whether every file read/write was successful:
|
170
159
|
all_read = true
|
171
160
|
all_write = true
|
172
161
|
files_written = 0
|
173
162
|
files_failed_read = 0
|
163
|
+
# Temporarily increase the log threshold to suppress messages from the DObject class:
|
164
|
+
anonymizer_level = logger.level
|
165
|
+
logger.level = Logger::FATAL
|
174
166
|
@files.each_index do |i|
|
175
167
|
# Read existing file to DICOM object:
|
176
|
-
obj = DICOM::DObject.
|
168
|
+
obj = DICOM::DObject.read(@files[i])
|
177
169
|
if obj.read_success
|
178
170
|
# Anonymize the desired tags:
|
179
171
|
@tags.each_index do |j|
|
@@ -212,34 +204,35 @@ module DICOM
|
|
212
204
|
files_failed_read += 1
|
213
205
|
end
|
214
206
|
end
|
215
|
-
# Finished anonymizing files.
|
207
|
+
# Finished anonymizing files. Reset the logg threshold:
|
208
|
+
logger.level = anonymizer_level
|
209
|
+
# Print elapsed time and status of anonymization:
|
216
210
|
end_time = Time.now.to_f
|
217
|
-
|
211
|
+
logger.info("Anonymization process completed!")
|
218
212
|
if all_read
|
219
|
-
|
213
|
+
logger.info("All files in the specified folder(s) were SUCCESSFULLY read to DICOM objects.")
|
220
214
|
else
|
221
|
-
|
215
|
+
logger.warn("Some files were NOT successfully read (#{files_failed_read} files). If some folder(s) contain non-DICOM files, this is expected.")
|
222
216
|
end
|
223
217
|
if all_write
|
224
|
-
|
218
|
+
logger.info("All DICOM objects were SUCCESSFULLY written as DICOM files (#{files_written} files).")
|
225
219
|
else
|
226
|
-
|
220
|
+
logger.warn("Some DICOM objects were NOT succesfully written to file. You are advised to investigate the result (#{files_written} files succesfully written).")
|
227
221
|
end
|
228
222
|
# Has user requested enumeration and specified an identity file in which to store the anonymized values?
|
229
223
|
if @enumeration and @identity_file
|
230
|
-
|
224
|
+
logger.info("Writing identity file.")
|
231
225
|
write_identity_file
|
232
|
-
|
226
|
+
logger.info("Done")
|
233
227
|
end
|
234
228
|
elapsed = (end_time-start_time).to_s
|
235
|
-
|
229
|
+
logger.info("Elapsed time: #{elapsed[0..elapsed.index(".")+1]} seconds")
|
236
230
|
else
|
237
|
-
|
231
|
+
logger.warn("No tags were selected for anonymization. Aborting.")
|
238
232
|
end
|
239
233
|
else
|
240
|
-
|
234
|
+
logger.warn("No files were found in specified folders. Aborting.")
|
241
235
|
end
|
242
|
-
add_msg("*******************************************************")
|
243
236
|
end
|
244
237
|
|
245
238
|
# Prints to screen a list of which tags are currently selected for anonymization along with
|
@@ -367,7 +360,7 @@ module DICOM
|
|
367
360
|
if pos
|
368
361
|
return @values[pos]
|
369
362
|
else
|
370
|
-
|
363
|
+
logger.warn("The specified tag (#{tag}) was not found in the list of tags to be anonymized.")
|
371
364
|
return nil
|
372
365
|
end
|
373
366
|
end
|
@@ -377,18 +370,6 @@ module DICOM
|
|
377
370
|
private
|
378
371
|
|
379
372
|
|
380
|
-
# Adds one or more status messages to the log instance array, and if the verbose
|
381
|
-
# instance variable is true, the status message is printed to the screen as well.
|
382
|
-
#
|
383
|
-
# === Parameters
|
384
|
-
#
|
385
|
-
# * <tt>msg</tt> -- Status message string.
|
386
|
-
#
|
387
|
-
def add_msg(msg)
|
388
|
-
puts msg if @verbose
|
389
|
-
@log << msg
|
390
|
-
end
|
391
|
-
|
392
373
|
# Finds the common path (if any) in the instance file path array, by performing a recursive search
|
393
374
|
# on the folders that make up the path of one such file.
|
394
375
|
# Returns the index of the last folder in the path of the selected file that is common for all file paths.
|
@@ -573,4 +554,4 @@ module DICOM
|
|
573
554
|
end
|
574
555
|
|
575
556
|
end
|
576
|
-
end
|
557
|
+
end
|
data/lib/dicom/d_client.rb
CHANGED
@@ -10,6 +10,7 @@ module DICOM
|
|
10
10
|
# FIXME: The code which waits for incoming network packets seems to be very CPU intensive. Perhaps there is a more elegant way to wait for incoming messages?
|
11
11
|
#
|
12
12
|
class DClient
|
13
|
+
include Logging
|
13
14
|
|
14
15
|
# The name of this client (application entity).
|
15
16
|
attr_accessor :ae
|
@@ -23,19 +24,17 @@ module DICOM
|
|
23
24
|
attr_accessor :port
|
24
25
|
# The maximum period the client will wait on an answer from a server before aborting the communication.
|
25
26
|
attr_accessor :timeout
|
26
|
-
# A boolean which defines if notices/warnings/errors will be printed to the screen (true) or not (false).
|
27
|
-
attr_accessor :verbose
|
28
27
|
# An array, where each index contains a hash with the data elements received in a command response (with tags as keys).
|
29
28
|
attr_reader :command_results
|
30
29
|
# An array, where each index contains a hash with the data elements received in a data response (with tags as keys).
|
31
30
|
attr_reader :data_results
|
32
|
-
# An array containing any error messages recorded.
|
33
|
-
attr_reader :errors
|
34
|
-
# An array containing any status messages recorded.
|
35
|
-
attr_reader :notices
|
36
31
|
|
37
32
|
# Creates a DClient instance.
|
38
33
|
#
|
34
|
+
# === Notes
|
35
|
+
#
|
36
|
+
# * To customize logging behaviour, refer to the Logging module documentation.
|
37
|
+
#
|
39
38
|
# === Parameters
|
40
39
|
#
|
41
40
|
# * <tt>host_ip</tt> -- String. The IP adress of the server which you are going to communicate with.
|
@@ -48,7 +47,6 @@ module DICOM
|
|
48
47
|
# * <tt>:host_ae</tt> -- String. The name of the server (application entity).
|
49
48
|
# * <tt>:max_package_size</tt> -- Fixnum. The maximum allowed size of network packages (in bytes).
|
50
49
|
# * <tt>:timeout</tt> -- Fixnum. The maximum period the server will wait on an answer from a client before aborting the communication.
|
51
|
-
# * <tt>:verbose</tt> -- Boolean. If set to false, the DClient instance will run silently and not output warnings and error messages to the screen. Defaults to true.
|
52
50
|
#
|
53
51
|
# === Examples
|
54
52
|
#
|
@@ -66,11 +64,6 @@ module DICOM
|
|
66
64
|
@max_package_size = options[:max_package_size] || 32768 # 16384
|
67
65
|
@timeout = options[:timeout] || 10 # seconds
|
68
66
|
@min_length = 12 # minimum number of bytes to expect in an incoming transmission
|
69
|
-
@verbose = options[:verbose]
|
70
|
-
@verbose = true if @verbose == nil # Default verbosity is 'on'.
|
71
|
-
# Other instance variables:
|
72
|
-
@errors = Array.new # errors and warnings are put in this array
|
73
|
-
@notices = Array.new # information on successful transmissions are put in this array
|
74
67
|
# Variables used for monitoring state of transmission:
|
75
68
|
@association = nil # DICOM Association status
|
76
69
|
@request_approved = nil # Status of our DICOM request
|
@@ -396,14 +389,14 @@ module DICOM
|
|
396
389
|
establish_release
|
397
390
|
else
|
398
391
|
# Failed when loading the specified parameter as DICOM file(s). Will not transmit.
|
399
|
-
|
392
|
+
logger.error(message)
|
400
393
|
end
|
401
394
|
end
|
402
395
|
|
403
396
|
# Tests the connection to the server in a very simple way by negotiating an association and then releasing it.
|
404
397
|
#
|
405
398
|
def test
|
406
|
-
|
399
|
+
logger.info("TESTING CONNECTION...")
|
407
400
|
success = false
|
408
401
|
# Verification SOP Class:
|
409
402
|
set_default_presentation_context(VERIFICATION_SOP)
|
@@ -417,9 +410,9 @@ module DICOM
|
|
417
410
|
establish_release
|
418
411
|
end
|
419
412
|
if success
|
420
|
-
|
413
|
+
logger.info("TEST SUCCSESFUL!")
|
421
414
|
else
|
422
|
-
|
415
|
+
logger.warn("TEST FAILED!")
|
423
416
|
end
|
424
417
|
return success
|
425
418
|
end
|
@@ -429,30 +422,6 @@ module DICOM
|
|
429
422
|
private
|
430
423
|
|
431
424
|
|
432
|
-
# Adds a warning or error message to the instance array holding messages,
|
433
|
-
# and prints the information to the screen if verbose is set.
|
434
|
-
#
|
435
|
-
# === Parameters
|
436
|
-
#
|
437
|
-
# * <tt>error</tt> -- A single error message or an array of error messages.
|
438
|
-
#
|
439
|
-
def add_error(error)
|
440
|
-
puts error if @verbose
|
441
|
-
@errors << error
|
442
|
-
end
|
443
|
-
|
444
|
-
# Adds a notice (information regarding progress or successful communications) to the instance array,
|
445
|
-
# and prints the information to the screen if verbose is set.
|
446
|
-
#
|
447
|
-
# === Parameters
|
448
|
-
#
|
449
|
-
# * <tt>notice</tt> -- A single status message or an array of status messages.
|
450
|
-
#
|
451
|
-
def add_notice(notice)
|
452
|
-
puts notice if @verbose
|
453
|
-
@notices << notice
|
454
|
-
end
|
455
|
-
|
456
425
|
# Returns an array of supported transfer syntaxes for the specified transfer syntax.
|
457
426
|
# For compressed transfer syntaxes, we currently do not support reencoding these to other syntaxes.
|
458
427
|
#
|
@@ -486,11 +455,11 @@ module DICOM
|
|
486
455
|
# Values of importance are extracted and put into instance variables:
|
487
456
|
@association = true
|
488
457
|
@max_pdu_length = info[:max_pdu_length]
|
489
|
-
|
458
|
+
logger.info("Association successfully negotiated with host #{@host_ae} (#{@host_ip}).")
|
490
459
|
# Check if all our presentation contexts was accepted by the host:
|
491
460
|
process_presentation_context_response(info[:pc])
|
492
461
|
else
|
493
|
-
|
462
|
+
logger.error("Association was denied from host #{@host_ae} (#{@host_ip})!")
|
494
463
|
end
|
495
464
|
end
|
496
465
|
end
|
@@ -501,7 +470,7 @@ module DICOM
|
|
501
470
|
@release = false
|
502
471
|
if @abort
|
503
472
|
@link.stop_session
|
504
|
-
|
473
|
+
logger.info("Association has been closed. (#{@host_ae}, #{@host_ip})")
|
505
474
|
else
|
506
475
|
unless @link.session.closed?
|
507
476
|
@link.build_release_request
|
@@ -509,12 +478,12 @@ module DICOM
|
|
509
478
|
info = @link.receive_single_transmission.first
|
510
479
|
@link.stop_session
|
511
480
|
if info[:pdu] == PDU_RELEASE_RESPONSE
|
512
|
-
|
481
|
+
logger.info("Association released properly from host #{@host_ae}.")
|
513
482
|
else
|
514
|
-
|
483
|
+
logger.error("Association released from host #{@host_ae}, but a release response was not registered.")
|
515
484
|
end
|
516
485
|
else
|
517
|
-
|
486
|
+
logger.error("Connection was closed by the host (for some unknown reason) before the association could be released properly.")
|
518
487
|
end
|
519
488
|
end
|
520
489
|
@abort = false
|
@@ -533,33 +502,38 @@ module DICOM
|
|
533
502
|
#
|
534
503
|
# === Parameters
|
535
504
|
#
|
536
|
-
# * <tt>
|
505
|
+
# * <tt>files_or_objects</tt> -- A single file path or an array of paths, or a DObject or an array of DObject instances.
|
537
506
|
#
|
538
|
-
def load_files(
|
507
|
+
def load_files(files_or_objects)
|
508
|
+
files_or_objects = [files_or_objects] unless files_or_objects.is_a?(Array)
|
539
509
|
status = true
|
540
510
|
message = ""
|
541
511
|
objects = Array.new
|
542
512
|
abstracts = Array.new
|
543
513
|
id = 1
|
544
514
|
@presentation_contexts = Hash.new
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
515
|
+
files_or_objects.each do |file_or_object|
|
516
|
+
if file_or_object.is_a?(String)
|
517
|
+
# Temporarily increase the log threshold to suppress messages from the DObject class:
|
518
|
+
client_level = logger.level
|
519
|
+
logger.level = Logger::FATAL
|
520
|
+
obj = DObject.read(file_or_object)
|
521
|
+
# Reset the logg threshold:
|
522
|
+
logger.level = client_level
|
549
523
|
if obj.read_success
|
550
524
|
# Load the DICOM object:
|
551
525
|
objects << obj
|
552
526
|
else
|
553
527
|
status = false
|
554
|
-
message = "Failed to
|
528
|
+
message = "Failed to read a DObject from this file: #{file_or_object}"
|
555
529
|
end
|
556
|
-
elsif
|
530
|
+
elsif file_or_object.is_a?(DObject)
|
557
531
|
# Load the DICOM object and its abstract syntax:
|
558
|
-
abstracts <<
|
559
|
-
objects <<
|
532
|
+
abstracts << file_or_object.value("0008,0016")
|
533
|
+
objects << file_or_object
|
560
534
|
else
|
561
535
|
status = false
|
562
|
-
message = "Array contains invalid object #{
|
536
|
+
message = "Array contains invalid object: #{file_or_object.class}."
|
563
537
|
end
|
564
538
|
end
|
565
539
|
# Extract available transfer syntaxes for the various sop classes found amongst these objects
|
@@ -732,7 +706,7 @@ module DICOM
|
|
732
706
|
process_returned_data(segments)
|
733
707
|
end
|
734
708
|
else
|
735
|
-
|
709
|
+
logger.error("Unable to extract SOP Class UID and/or SOP Instance UID for this DICOM object. File will not be sent to its destination.")
|
736
710
|
end
|
737
711
|
end
|
738
712
|
end
|
@@ -767,16 +741,27 @@ module DICOM
|
|
767
741
|
if rejected.length == 0
|
768
742
|
@request_approved = true
|
769
743
|
if @approved_syntaxes.length == 1 and presentation_contexts.length == 1
|
770
|
-
|
744
|
+
logger.info("The presentation context was accepted by host #{@host_ae}.")
|
771
745
|
else
|
772
|
-
|
746
|
+
logger.info("All #{presentation_contexts.length} presentation contexts were accepted by host #{@host_ae} (#{@host_ip}).")
|
773
747
|
end
|
774
748
|
else
|
775
749
|
# We still consider the request 'approved' if at least one context were accepted:
|
776
750
|
@request_approved = true if @approved_syntaxes.length > 0
|
777
|
-
|
778
|
-
|
779
|
-
|
751
|
+
|
752
|
+
logger.error("One or more of your presentation contexts were denied by host #{@host_ae}!")
|
753
|
+
|
754
|
+
@approved_syntaxes.each_pair do |key, value|
|
755
|
+
sntx_k = LIBRARY.get_syntax_description(key)
|
756
|
+
sntx_v = LIBRARY.get_syntax_description(value[1])
|
757
|
+
logger.info("APPROVED: #{sntx_k} (#{sntx_v})")
|
758
|
+
end
|
759
|
+
|
760
|
+
rejected.each_pair do |key, value|
|
761
|
+
sntx_k = LIBRARY.get_syntax_description(key)
|
762
|
+
sntx_v = LIBRARY.get_syntax_description(value[1])
|
763
|
+
logger.error("REJECTED: #{sntx_k} (#{sntx_v})")
|
764
|
+
end
|
780
765
|
end
|
781
766
|
end
|
782
767
|
|
@@ -958,4 +943,4 @@ module DICOM
|
|
958
943
|
end
|
959
944
|
|
960
945
|
end
|
961
|
-
end
|
946
|
+
end
|