Class: DICOM::Element

Inherits:
Object
  • Object
show all
Includes:
Elemental
Defined in:
lib/dicom/element.rb

Overview

The Element class handles information related to ordinary (non-parent) elementals (data elements).

Instance Attribute Summary

Attributes included from Elemental

#bin, #length, #name, #parent, #tag, #vr

Instance Method Summary collapse

Methods included from Elemental

#name_as_method, #parents, #set_parent, #stream, #top_parent

Constructor Details

#initialize(tag, value, options = {}) ⇒ Element

Note:

In the case where the Element is given a binary instead of value, the Element will not have a formatted value (value = nil).

Note:

Private data elements are named as ‘Private’.

Note:

Non-private data elements that are not found in the dictionary are named as ‘Unknown’.

Creates an Element instance.

Examples:

Create a new data element and connect it to a DObject instance

patient_name = Element.new('0010,0010', 'John Doe', :parent => dcm)

Create a “Pixel Data” element and insert image data that you have already encoded elsewhere

pixel_data = Element.new('7FE0,0010', processed_pixel_data, :encoded => true, :parent => dcm)

Create a private data element

private = Element.new('0011,2102', some_data, :parent => dcm, :vr => 'LO')

Parameters:

  • tag (String)

    a ruby-dicom type element tag string

  • value (String, Integer, Float, Array, NilClass)

    a custom value to be encoded as the data element binary string, or in some cases (specified by options), a pre-encoded binary string

  • options (Hash) (defaults to: {})

    the options to use for creating the element

Options Hash (options):

  • :bin (String)

    if you already have the value pre-encoded to a binary string, the string can be supplied with this option to avoid it being encoded a second time

  • :encoded (Boolean)

    if the value parameter contains a pre-encoded binary, this boolean must to be set as true

  • :name (String)

    the name of the Element (if not specified, the name is retrieved from the dictionary)

  • :parent (DObject, Item, NilClass)

    a parent instance (Item or DObject) which the element belongs to

  • :vr (String)

    if a private element is created with a custom value, this must be specified to enable the encoding of the value (if not specified, the vr is retrieved from the dictionary)

Raises:

  • (ArgumentError)


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
# File 'lib/dicom/element.rb', line 34

def initialize(tag, value, options={})
  raise ArgumentError, "The supplied tag (#{tag}) is not valid. The tag must be a string of the form 'GGGG,EEEE'." unless tag.is_a?(String) && tag.tag?
  # Set instance variables:
  @tag = tag.upcase
  # We may beed to retrieve name and vr from the library:
  if options[:name] and options[:vr]
    @name = options[:name]
    @vr = options[:vr].upcase
  else
    name, vr = LIBRARY.name_and_vr(tag)
    @name = options[:name] || name
    @vr = (options[:vr] ? options[:vr].upcase : vr)
  end
  # Manage the parent relation if specified:
  if options[:parent]
    @parent = options[:parent]
    # FIXME: Because of some implementation problems, attaching the special
    # Data Set Trailing Padding element to a parent is not supported yet!
    @parent.add(self, :no_follow => true) unless @tag == 'FFFC,FFFC' && @parent.is_a?(Sequence)
  end
  # Value may in some cases be the binary string:
  unless options[:encoded]
    # The Data Element may have a value, have no value and no binary, or have no value and only binary:
    if value
      # Is binary value provided or do we need to encode it?
      if options[:bin]
        @value = value
        @bin = options[:bin]
      else
        if value == ''
          @value = value
          @bin = ''
        else
          # Set the value with our custom setter method to get proper encoding:
          self.value = value
        end
      end
    else
      # When no value is present, we set the binary as an empty string, unless the binary is specified:
      @bin = options[:bin] || ''
    end
  else
    @bin = value
  end
  # Let the binary decide the length:
  @length = @bin.length
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Checks for equality.

Other and self are considered equivalent if they are of compatible types and their attributes are equivalent.

Parameters:

  • other

    an object to be compared with self.

Returns:

  • (Boolean)

    true if self and other are considered equivalent



90
91
92
93
94
# File 'lib/dicom/element.rb', line 90

def ==(other)
  if other.respond_to?(:to_element)
    other.send(:state) == state
  end
end

#bin=(new_bin) ⇒ Object

Note:

if the specified binary has an odd length, a proper pad byte will automatically be appended to give it an even length (which is needed to conform with the DICOM standard).

Sets the binary string of a Element.

Parameters:

  • new_bin (String)

    a binary string of encoded data

Raises:

  • (ArgumentError)


105
106
107
108
109
110
111
112
113
114
115
# File 'lib/dicom/element.rb', line 105

def bin=(new_bin)
  raise ArgumentError, "Expected String, got #{new_bin.class}." unless new_bin.is_a?(String)
  # Add a zero byte at the end if the length of the binary is odd:
  if new_bin.length.odd?
    @bin = new_bin + stream.pad_byte[@vr]
  else
    @bin = new_bin
  end
  @value = nil
  @length = @bin.length
end

#children?FalseClass

Checks if the Element actually has any child elementals.

Returns:

  • (FalseClass)

    always returns false, as Element instances by definition can’t have children



121
122
123
# File 'lib/dicom/element.rb', line 121

def children?
  return false
end

#endianBoolean

Gives the endianness of the encoded binary value of this element.

Returns:

  • (Boolean)

    false if little endian, true if big endian



129
130
131
# File 'lib/dicom/element.rb', line 129

def endian
  return stream.str_endian
end

#hashFixnum

Note:

Two objects with the same attributes will have the same hash code.

Computes a hash code for this object.

Returns:

  • (Fixnum)

    the object’s hash code



139
140
141
# File 'lib/dicom/element.rb', line 139

def hash
  state.hash
end

#inspectString

Gives a string containing a human-readable hash representation of the Element.

Returns:

  • (String)

    a hash representation string of the element



147
148
149
# File 'lib/dicom/element.rb', line 147

def inspect
  to_hash.inspect
end

#is_parent?FalseClass

Checks if the Element is a parent.

Returns:

  • (FalseClass)

    always returns false, as Element instances by definition are not parents



155
156
157
# File 'lib/dicom/element.rb', line 155

def is_parent?
  return false
end

#to_elementElement

Returns self.

Returns:



173
174
175
# File 'lib/dicom/element.rb', line 173

def to_element
  self
end

#to_hashHash

Note:

The key representation in this hash is configurable (refer to the DICOM module methods documentation for more details).

Creates a hash representation of the element instance.

Returns:

  • (Hash)

    a hash containing a key & value pair (e.g. “Modality”=>“MR”)



165
166
167
# File 'lib/dicom/element.rb', line 165

def to_hash
  return {self.send(DICOM.key_representation) => value}
end

#to_jsonString

Gives a json string containing a human-readable representation of the Element.

Returns:

  • (String)

    a string containing a key & value pair (e.g. “"Modality":"MR"”)



181
182
183
# File 'lib/dicom/element.rb', line 181

def to_json
  to_hash.to_json
end

#to_yamlString

Gives a yaml string containing a human-readable representation of the Element.

Returns:

  • (String)

    a string containing a key & value pair (e.g. “—nModality: MRn”)



189
190
191
# File 'lib/dicom/element.rb', line 189

def to_yaml
  to_hash.to_yaml
end

#valueString, ...

Note:

Returned string values are automatically converted from their originally encoding (e.g. ISO8859-1 or ASCII-8BIT) to UTF-8 for convenience reasons. If the value string is wanted in its original encoding, extract the data element’s bin attribute instead.

Note:

Note that according to the DICOM Standard PS 3.5 C.12.1.1.2, the Character Set only applies

Gives the (decoded) value of the data element.

to values of data elements of type SH, LO, ST, PN, LT or UT. Currently in ruby-dicom, all string values are encoding converted regardless of VR, but whether this causes any problems is uknown.

Returns:

  • (String, Integer, Float)

    the formatted element value



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/dicom/element.rb', line 206

def value
  if @value.is_a?(String)
    # Unless this is actually the Character Set data element,
    # get the character set (note that it may not be available):
    character_set = (@tag != '0008,0005' && top_parent.is_a?(DObject)) ? top_parent.value('0008,0005') : nil
    # Convert to UTF-8 from [original encoding]:
    # In most cases the original encoding is IS0-8859-1 (ISO_IR 100), but if
    # it is not specified in the DICOM object, or if the specified string
    # is not recognized, ASCII-8BIT is assumed.
    @value.encode('UTF-8', ENCODING_NAME[character_set] || 'ASCII-8BIT')
    # If unpleasant encoding exceptions occur, the below version may be considered:
    #@value.encode('UTF-8', ENCODING_NAME[character_set] || 'ASCII-8BIT', :invalid => :replace, :undef => :replace)
  else
    @value
  end
end

#value=(new_value) ⇒ Object

Note:

The specified value must be of a type that is compatible with the Element’s value representation (vr).

Sets the value of the Element instance.

In addition to updating the value attribute, the specified value is encoded to binary and used to update the Element’s bin and length attributes too.

Parameters:

  • new_value (String, Integer, Float, Array)

    a formatted value that is assigned to the element



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
# File 'lib/dicom/element.rb', line 231

def value=(new_value)
  conversion = VALUE_CONVERSION[@vr] || :to_s
  if conversion == :to_s
    # Unless this is actually the Character Set data element,
    # get the character set (note that it may not be available):
    character_set = (@tag != '0008,0005' && top_parent.is_a?(DObject)) ? top_parent.value('0008,0005') : nil
    # Convert to [DObject encoding] from [input string encoding]:
    # In most cases the DObject encoding is IS0-8859-1 (ISO_IR 100), but if
    # it is not specified in the DICOM object, or if the specified string
    # is not recognized, ASCII-8BIT is assumed.
    @value = new_value.to_s.encode(ENCODING_NAME[character_set] || 'ASCII-8BIT', new_value.to_s.encoding.name)
    @bin = encode(@value)
  else
    # We may have an array (of numbers) which needs to be passed directly to
    # the encode method instead of being forced into a numerical:
    if new_value.is_a?(Array)
      @value = new_value
      @bin = encode(@value)
    else
      @value = new_value.send(conversion)
      @bin = encode(@value)
    end
  end
  @length = @bin.length
end