class DICOM::DLibrary

The DLibrary class contains methods for interacting with ruby-dicom's dictionary data.

In practice, the library is for internal use and not accessed by the user. However, a a library instance is available through the DICOM::LIBRARY constant.

@example Get a dictionary element corresponding to the given tag

element = DICOM::LIBRARY.element('0010,0010')

Attributes

elements[R]

A hash with element tag strings as keys and DicitonaryElement instances as values.

methods_from_names[R]

A hash with element name strings as key and method name symbols as value.

names_from_methods[R]

A hash with element method name symbols as key and name strings as value.

uids[R]

A hash with uid strings as keys and UID instances as values.

Public Class Methods

new() click to toggle source

Creates a DLibrary instance.

# File lib/dicom/d_library.rb, line 24
def initialize
  # Create instance hashes used for dictionary data and method conversion:
  @elements = Hash.new
  @uids = Hash.new
  @methods_from_names = Hash.new
  @names_from_methods = Hash.new
  # Load the elements dictionary:
  add_element_dictionary("#{ROOT_DIR}/dictionary/elements.tsv")
  # Load the unique identifiers dictionary:
  add_uid_dictionary("#{ROOT_DIR}/dictionary/uids.tsv")
end

Public Instance Methods

add_element(element) click to toggle source

Adds a custom DictionaryElement to the ruby-dicom element dictionary.

@param [DictionaryElement] element the custom dictionary element to be added

# File lib/dicom/d_library.rb, line 40
def add_element(element)
  raise ArgumentError, "Invalid argument 'element'. Expected DictionaryElement, got #{element.class}" unless element.is_a?(DictionaryElement)
  # We store the elements in a hash with tag as key and the element instance as value:
  @elements[element.tag] = element
  # Populate the method conversion hashes with element data:
  method = element.name.to_element_method
  @methods_from_names[element.name] = method
  @names_from_methods[method] = element.name
end
add_element_dictionary(file) click to toggle source

Adds a custom dictionary file to the ruby-dicom element dictionary.

@note The format of the dictionary is a tab-separated text file with 5 columns:

* Tag, Name, VR, VM & Retired status
* For samples check out ruby-dicom's element dictionaries in the git repository

@param [String] file the path to the dictionary file to be added

# File lib/dicom/d_library.rb, line 57
def add_element_dictionary(file)
  File.open(file, :encoding => 'utf-8').each do |record|
    fields = record.split("\t")
    add_element(DictionaryElement.new(fields[0], fields[1], fields[2].split(","), fields[3].rstrip, fields[4].rstrip))
  end
end
add_uid(uid) click to toggle source

Adds a custom uid (e.g. SOP Class, Transfer Syntax) to the ruby-dicom uid dictionary.

@param [UID] uid the custom uid instance to be added

# File lib/dicom/d_library.rb, line 68
def add_uid(uid)
  raise ArgumentError, "Invalid argument 'uid'. Expected UID, got #{uid.class}" unless uid.is_a?(UID)
  # We store the uids in a hash with uid-value as key and the uid instance as value:
  @uids[uid.value] = uid
end
add_uid_dictionary(file) click to toggle source

Adds a custom dictionary file to the ruby-dicom uid dictionary.

@note The format of the dictionary is a tab-separated text file with 4 columns:

* Value, Name, Type & Retired status
* For samples check out ruby-dicom's uid dictionaries in the git repository

@param [String] file the path to the dictionary file to be added

# File lib/dicom/d_library.rb, line 81
def add_uid_dictionary(file)
  File.open(file, :encoding => 'utf-8').each do |record|
    fields = record.split("\t")
    add_uid(UID.new(fields[0], fields[1], fields[2].rstrip, fields[3].rstrip))
  end
end
as_method(value) click to toggle source

Gives the method (symbol) corresponding to the specified element string value.

@param [String] value an element tag, element name or an element's method name @return [Symbol, NilClass] the matched element method, or nil if no match is made

# File lib/dicom/d_library.rb, line 94
def as_method(value)
  case true
  when value.tag?
    @methods_from_names[element(value).name]
  when value.dicom_name?
    @methods_from_names[value]
  when value.dicom_method?
    @names_from_methods.has_key?(value.to_sym) ? value.to_sym : nil
  else
    nil
  end
end
as_name(value) click to toggle source

Gives the name corresponding to the specified element string value.

@param [String] value an element tag, element name or an element's method name @return [String, NilClass] the matched element name, or nil if no match is made

# File lib/dicom/d_library.rb, line 112
def as_name(value)
  case true
  when value.tag?
    element(value).name
  when value.dicom_name?
    @methods_from_names.has_key?(value) ? value.to_s : nil
  when value.dicom_method?
    @names_from_methods[value.to_sym]
  else
    nil
  end
end
as_tag(value) click to toggle source

Gives the tag corresponding to the specified element string value.

@param [String] value an element tag, element name or an element's method name @return [String, NilClass] the matched element tag, or nil if no match is made

# File lib/dicom/d_library.rb, line 130
def as_tag(value)
  case true
  when value.tag?
    element(value) ? value : nil
  when value.dicom_name?
    get_tag(value)
  when value.dicom_method?
    get_tag(@names_from_methods[value.to_sym])
  else
    nil
  end
end
element(tag) click to toggle source

Identifies the DictionaryElement that corresponds to the given tag.

@note If a given tag doesn't return a dictionary match, a new DictionaryElement is created.

* For private tags, a name 'Private' and VR 'UN' is assigned
* For unknown tags, a name 'Unknown' and VR 'UN' is assigned

@param [String] tag the tag of the element @return [DictionaryElement] a corresponding DictionaryElement

# File lib/dicom/d_library.rb, line 151
def element(tag)
  element = @elements[tag]
  unless element
    if tag.group_length?
      element = DictionaryElement.new(tag, 'Group Length', ['UL'], '1', '')
    else
      if tag.private?
        element = DictionaryElement.new(tag, 'Private', ['UN'], '1', '')
      else
        element = unknown_or_range_element(tag)
      end
    end
  end
  element
end
extract_transfer_syntaxes_and_sop_classes() click to toggle source

Extracts, and returns, all transfer syntaxes and SOP Classes from the dictionary.

@return [Array<Hash, Hash>] transfer syntax and sop class hashes, each with uid as key and name as value

# File lib/dicom/d_library.rb, line 171
def extract_transfer_syntaxes_and_sop_classes
  transfer_syntaxes = Hash.new
  sop_classes = Hash.new
  @uids.each_value do |uid|
    if uid.transfer_syntax?
      transfer_syntaxes[uid.value] = uid.name
    elsif uid.sop_class?
      sop_classes[uid.value] = uid.name
    end
  end
  return transfer_syntaxes, sop_classes
end
get_tag(name) click to toggle source

Gives the tag that matches the supplied data element name, by searching the element dictionary.

@param [String] name a data element name @return [String, NilClass] the corresponding element tag, or nil if no match is made

# File lib/dicom/d_library.rb, line 189
def get_tag(name)
  tag = nil
  name = name.to_s.downcase
  @tag_name_pairs_cache ||= Hash.new
  return @tag_name_pairs_cache[name] unless @tag_name_pairs_cache[name].nil?
  @elements.each_value do |element|
    next unless element.name.downcase == name
    tag = element.tag
    break
  end
  @tag_name_pairs_cache[name]=tag
  return tag
end
name_and_vr(tag) click to toggle source

Determines the name and vr of the element which the specified tag belongs to, based on a lookup in the element data dictionary.

@note If a given tag doesn't return a dictionary match, the following values are assigned:

* For private tags: name 'Private' and VR 'UN'
* For unknown (non-private) tags: name 'Unknown' and VR 'UN'

@param [String] tag an element's tag @return [Array<String, String>] the name and value representation corresponding to the given tag

# File lib/dicom/d_library.rb, line 212
def name_and_vr(tag)
  de = element(tag)
  return de.name, de.vr
end
uid(value) click to toggle source

Identifies the UID that corresponds to the given value.

@param [String] value the unique identifier value @return [UID, NilClass] a corresponding UID instance, or nil (if no match is made)

# File lib/dicom/d_library.rb, line 222
def uid(value)
  @uids[value]
end

Private Instance Methods

range_candidates(tag) click to toggle source

Creates a list of possible 'range' tag candidates based on the given tag. Usually tags are uniquely defined in the DICOM dictionary, and the given tag can be matched directly. However, for a small set of known tags, the dictionary allows a range of tags to be associated with a specific entry. This method creates an array of candidate tags which are processed in order to match against these ranges.

@param [String] tag the element tag @return [Array<String>] processed candidate tags

# File lib/dicom/d_library.rb, line 240
def range_candidates(tag)
  [
    "#{tag[0..3]},xxx#{tag[8]}", # 1000,xxxh
    "#{tag[0..3]},xxxx", # 1010,xxxx
    "#{tag[0..1]}xx,#{tag[5..8]}", # hhxx,hhhh
    "#{tag[0..6]}x#{tag[8]}" # 0028,hhxh
  ]
end
unknown_or_range_element(tag) click to toggle source

Matches a tag against the possible range tag candidates, and if no match is found, returns a dictionary element representing an unknown tag.

@param [String] tag the element tag @return [DictionaryElement] a matched range element or an unknown element

# File lib/dicom/d_library.rb, line 255
def unknown_or_range_element(tag)
  element = nil
  range_candidates(tag).each do |range_candidate_tag|
    if de = @elements[range_candidate_tag]
      element = DictionaryElement.new(tag, de.name, de.vrs, de.vm, de.retired)
      break
    end
  end
  # If nothing was matched, we are facing an unknown (but not private) tag:
  element ||= DictionaryElement.new(tag, 'Unknown', ['UN'], '1', '')
end