pax_global_header00006660000000000000000000000064126646052410014520gustar00rootroot0000000000000052 comment=9a178542e4614b5538f235e911a874f926fcc23f odil-0.4.1/000077500000000000000000000000001266460524100124515ustar00rootroot00000000000000odil-0.4.1/.travis.yml000066400000000000000000000032361266460524100145660ustar00rootroot00000000000000language: cpp matrix: include: - os: linux sudo: required dist: trusty compiler: gcc - os: osx compiler: clang addons: apt: packages: - libdcmtk2-dev - libwrap0-dev - libjsoncpp-dev - libicu-dev - zlib1g-dev - libboost-dev - libboost-filesystem-dev - libboost-test-dev - dcmtk before_install: - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; fi # JSONCpp conflicts with json-c - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew uninstall json-c; fi # Boost is already installed with another version - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew unlink boost; brew install boost; fi - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install dcmtk icu4c jsoncpp; fi - pip install --user cpp-coveralls before_script: - export SRC_DIR=$PWD - mkdir build - cd build - export BIN_DIR=$PWD - CMAKE_CXX_FLAGS="-std=c++11" - if [ "${CC}" = "gcc" ]; then CMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} --coverage"; fi - if [ "$TRAVIS_OS_NAME" = "osx" ]; then CMAKE_ARGUMENTS="-D ICU_INCLUDE_DIR=/usr/local/opt/icu4c/include/ -D ICU_LIBRARY=/usr/local/opt/icu4c/lib/libicuuc.dylib"; fi - cmake -D CMAKE_CXX_FLAGS:STRING="${CMAKE_CXX_FLAGS}" -D CMAKE_BUILD_TYPE:STRING=Debug ${CMAKE_ARGUMENTS} ../ script: - make -j $(nproc) - export PATH=$PWD/tests/tools:$PATH - ../tests/run.sh after_success: - if [ "${CC}" = "gcc" ]; then ${HOME}/.local/bin/coveralls --exclude examples --exclude tests --exclude-pattern '.*CMake[^/]+\.c(?:pp)?' --exclude-pattern "/usr/.*" --root=${SRC_DIR} --build-root ${BIN_DIR} | grep -vP "^File '.*'$" | grep -vP ":creating '.*'$" | grep -vP "^Lines executed:.*" | sed '/^$/d'; fi odil-0.4.1/CMakeLists.txt000066400000000000000000000015571266460524100152210ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) project("odil") set(odil_MAJOR_VERSION 0) set(odil_MINOR_VERSION 4) set(odil_PATCH_VERSION 1) set(odil_VERSION ${odil_MAJOR_VERSION}.${odil_MINOR_VERSION}.${odil_PATCH_VERSION}) option(BUILD_EXAMPLES "Build the examples directory." ON) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}" ${CMAKE_MODULE_PATH}) include(CTest) add_subdirectory("src") if(BUILD_EXAMPLES) add_subdirectory("examples") endif() if(BUILD_TESTING) add_subdirectory("tests") endif() add_custom_target( CIIntegration ${CMAKE_COMMAND} -E echo "CI Integration" SOURCES appveyor.yml .travis.yml) add_custom_target( Documentation ${CMAKE_COMMAND} -E echo "Documentation" SOURCES Doxyfile LICENSE.txt README.md) add_custom_target( Registry ${CMAKE_COMMAND} -E echo "Registry" SOURCES generate_registry registry.cpp.tmpl registry.h.tmpl) odil-0.4.1/Doxyfile000066400000000000000000002276231266460524100141730ustar00rootroot00000000000000# Doxyfile 1.7.6.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = "odil" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = ./doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation # of the scope in which they are defined (i.e. file, namespace, or group # documentation), provided this scope is documented. If set to NO (the default), # structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. SYMBOL_CACHE_SIZE = 0 # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given # their name and scope. Since this can be an expensive process and often the # same symbol appear multiple times in the code, doxygen keeps a cache of # pre-resolved symbols. If the cache is too small doxygen will become slower. # If the cache is too large, memory is wasted. The cache size is given by this # formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = ./src/odil # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.d \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.idl \ *.odl \ *.cs \ *.php \ *.php3 \ *.inc \ *.m \ *.mm \ *.dox \ *.py \ *.f90 \ *.f \ *.for \ *.vhd \ *.vhdl # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # style sheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the # mathjax.org site, so you can quickly see the result without installing # MathJax, but it is strongly recommended to install a local copy of MathJax # before deployment. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES odil-0.4.1/FindDCMTK.cmake000066400000000000000000000021371266460524100151210ustar00rootroot00000000000000# - Try to find DCMTK # Once done this will define # DCMTK_FOUND - System has DCMTK # DCMTK_INCLUDE_DIRS - The DCMTK include directories # DCMTK_LIBRARY_DIRS - The DCMTK link directories # DCMTK_LIBRARIES - The libraries needed to use DCMTK # DCMTK_DEFINITIONS - Compiler switches required for using DCMTK set(DCMTK_DEFINITIONS "-D HAVE_CONFIG_H") find_path(DCMTK_INCLUDE_DIR "dcmtk/dcmdata/dctk.h") find_library(DCMTK_LIBRARY dcmdata) set(DCMTK_INCLUDE_DIRS ${DCMTK_INCLUDE_DIR}) set(DCMTK_LIBRARIES ${DCMTK_LIBRARY} dcmnet dcmdata oflog ofstd) foreach(library iconv pthread wrap z) find_library(${library}_LIBRARY ${library}) if(${library}_LIBRARY) set(DCMTK_LIBRARIES ${DCMTK_LIBRARIES} ${${library}_LIBRARY}) endif() endforeach() get_filename_component(DCMTK_LIBRARY_DIRS "${DCMTK_LIBRARY}" PATH) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set DCMTK_FOUND to TRUE # if all listed variables are TRUE find_package_handle_standard_args( DCMTK DEFAULT_MSG DCMTK_INCLUDE_DIR DCMTK_LIBRARY) mark_as_advanced(DCMTK_INCLUDE_DIR DCMTK_LIBRARY) odil-0.4.1/FindICU.cmake000066400000000000000000000015111266460524100146720ustar00rootroot00000000000000# - Try to find ICU # Once done this will define # ICU_FOUND - System has ICU # ICU_INCLUDE_DIRS - The ICU include directories # ICU_LIBRARIES - The libraries needed to use ICU # ICU_DEFINITIONS - Compiler switches required for using ICU find_package(PkgConfig) pkg_check_modules(PC_ICU QUIET icu-uc) set(ICU_DEFINITIONS ${PC_ICU_CFLAGS_OTHER}) find_path(ICU_INCLUDE_DIR "unicode/ucnv.h" HINTS ${PC_ICU_INCLUDE_DIRS}) find_library(ICU_LIBRARY NAMES icuuc HINTS ${PC_ICU_LIBRARY_DIRS} ) set(ICU_LIBRARIES ${ICU_LIBRARY} ) set(ICU_INCLUDE_DIRS ${ICU_INCLUDE_DIR} ) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set ICU_FOUND to TRUE # if all listed variables are TRUE find_package_handle_standard_args(ICU DEFAULT_MSG ICU_LIBRARY ICU_INCLUDE_DIR) mark_as_advanced(ICU_INCLUDE_DIR ICU_LIBRARY) odil-0.4.1/FindJsonCpp.cmake000066400000000000000000000016661266460524100156410ustar00rootroot00000000000000# - Try to find JsonCpp # Once done this will define # JsonCpp_FOUND - System has JsonCpp # JsonCpp_INCLUDE_DIRS - The JsonCpp include directories # JsonCpp_LIBRARIES - The libraries needed to use JsonCpp # JsonCpp_DEFINITIONS - Compiler switches required for using JsonCpp find_package(PkgConfig) pkg_check_modules(PC_JsonCpp QUIET jsoncpp) set(JsonCpp_DEFINITIONS ${PC_JsonCpp_CFLAGS_OTHER}) find_path(JsonCpp_INCLUDE_DIR "json/json.h" HINTS ${PC_JsonCpp_INCLUDE_DIRS}) find_library(JsonCpp_LIBRARY NAMES jsoncpp HINTS ${PC_JsonCpp_LIBRARY_DIRS} ) set(JsonCpp_LIBRARIES ${JsonCpp_LIBRARY} ) set(JsonCpp_INCLUDE_DIRS ${JsonCpp_INCLUDE_DIR} ) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set JsonCpp_FOUND to TRUE # if all listed variables are TRUE find_package_handle_standard_args( JsonCpp DEFAULT_MSG JsonCpp_LIBRARY JsonCpp_INCLUDE_DIR) mark_as_advanced(JsonCpp_INCLUDE_DIR JsonCpp_LIBRARY) odil-0.4.1/LICENSE.txt000066400000000000000000000516221266460524100143020ustar00rootroot00000000000000 CeCILL-B FREE SOFTWARE LICENSE AGREEMENT Notice This Agreement is a Free Software license agreement that is the result of discussions between its authors in order to ensure compliance with the two main principles guiding its drafting: * firstly, compliance with the principles governing the distribution of Free Software: access to source code, broad rights granted to users, * secondly, the election of a governing law, French law, with which it is conformant, both as regards the law of torts and intellectual property law, and the protection that it offers to both authors and holders of the economic rights over software. The authors of the CeCILL-B (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) license are: Commissariat à l'Energie Atomique - CEA, a public scientific, technical and industrial research establishment, having its principal place of business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France. Centre National de la Recherche Scientifique - CNRS, a public scientific and technological establishment, having its principal place of business at 3 rue Michel-Ange, 75794 Paris cedex 16, France. Institut National de Recherche en Informatique et en Automatique - INRIA, a public scientific and technological establishment, having its principal place of business at Domaine de Voluceau, Rocquencourt, BP 105, 78153 Le Chesnay cedex, France. Preamble This Agreement is an open source software license intended to give users significant freedom to modify and redistribute the software licensed hereunder. The exercising of this freedom is conditional upon a strong obligation of giving credits for everybody that distributes a software incorporating a software ruled by the current license so as all contributions to be properly identified and acknowledged. In consideration of access to the source code and the rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors only have limited liability. In this respect, the risks associated with loading, using, modifying and/or developing or reproducing the software by the user are brought to the user's attention, given its Free Software status, which may make it complicated to use, with the result that its use is reserved for developers and experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the suitability of the software as regards their requirements in conditions enabling the security of their systems and/or data to be ensured and, more generally, to use and operate it in the same conditions of security. This Agreement may be freely reproduced and published, provided it is not altered, and that no provisions are either added or removed herefrom. This Agreement may apply to any or all software for which the holder of the economic rights decides to submit the use thereof to its provisions. Article 1 - DEFINITIONS For the purpose of this Agreement, when the following expressions commence with a capital letter, they shall have the following meaning: Agreement: means this license agreement, and its possible subsequent versions and annexes. Software: means the software in its Object Code and/or Source Code form and, where applicable, its documentation, "as is" when the Licensee accepts the Agreement. Initial Software: means the Software in its Source Code and possibly its Object Code form and, where applicable, its documentation, "as is" when it is first distributed under the terms and conditions of the Agreement. Modified Software: means the Software modified by at least one Contribution. Source Code: means all the Software's instructions and program lines to which access is required so as to modify the Software. Object Code: means the binary files originating from the compilation of the Source Code. Holder: means the holder(s) of the economic rights over the Initial Software. Licensee: means the Software user(s) having accepted the Agreement. Contributor: means a Licensee having made at least one Contribution. Licensor: means the Holder, or any other individual or legal entity, who distributes the Software under the Agreement. Contribution: means any or all modifications, corrections, translations, adaptations and/or new functions integrated into the Software by any or all Contributors, as well as any or all Internal Modules. Module: means a set of sources files including their documentation that enables supplementary functions or services in addition to those offered by the Software. External Module: means any or all Modules, not derived from the Software, so that this Module and the Software run in separate address spaces, with one calling the other when they are run. Internal Module: means any or all Module, connected to the Software so that they both execute in the same address space. Parties: mean both the Licensee and the Licensor. These expressions may be used both in singular and plural form. Article 2 - PURPOSE The purpose of the Agreement is the grant by the Licensor to the Licensee of a non-exclusive, transferable and worldwide license for the Software as set forth in Article 5 hereinafter for the whole term of the protection granted by the rights over said Software. Article 3 - ACCEPTANCE 3.1 The Licensee shall be deemed as having accepted the terms and conditions of this Agreement upon the occurrence of the first of the following events: * (i) loading the Software by any or all means, notably, by downloading from a remote server, or by loading from a physical medium; * (ii) the first time the Licensee exercises any of the rights granted hereunder. 3.2 One copy of the Agreement, containing a notice relating to the characteristics of the Software, to the limited warranty, and to the fact that its use is restricted to experienced users has been provided to the Licensee prior to its acceptance as set forth in Article 3.1 hereinabove, and the Licensee hereby acknowledges that it has read and understood it. Article 4 - EFFECTIVE DATE AND TERM 4.1 EFFECTIVE DATE The Agreement shall become effective on the date when it is accepted by the Licensee as set forth in Article 3.1. 4.2 TERM The Agreement shall remain in force for the entire legal term of protection of the economic rights over the Software. Article 5 - SCOPE OF RIGHTS GRANTED The Licensor hereby grants to the Licensee, who accepts, the following rights over the Software for any or all use, and for the term of the Agreement, on the basis of the terms and conditions set forth hereinafter. Besides, if the Licensor owns or comes to own one or more patents protecting all or part of the functions of the Software or of its components, the Licensor undertakes not to enforce the rights granted by these patents against successive Licensees using, exploiting or modifying the Software. If these patents are transferred, the Licensor undertakes to have the transferees subscribe to the obligations set forth in this paragraph. 5.1 RIGHT OF USE The Licensee is authorized to use the Software, without any limitation as to its fields of application, with it being hereinafter specified that this comprises: 1. permanent or temporary reproduction of all or part of the Software by any or all means and in any or all form. 2. loading, displaying, running, or storing the Software on any or all medium. 3. entitlement to observe, study or test its operation so as to determine the ideas and principles behind any or all constituent elements of said Software. This shall apply when the Licensee carries out any or all loading, displaying, running, transmission or storage operation as regards the Software, that it is entitled to carry out hereunder. 5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS The right to make Contributions includes the right to translate, adapt, arrange, or make any or all modifications to the Software, and the right to reproduce the resulting software. The Licensee is authorized to make any or all Contributions to the Software provided that it includes an explicit notice that it is the author of said Contribution and indicates the date of the creation thereof. 5.3 RIGHT OF DISTRIBUTION In particular, the right of distribution includes the right to publish, transmit and communicate the Software to the general public on any or all medium, and by any or all means, and the right to market, either in consideration of a fee, or free of charge, one or more copies of the Software by any means. The Licensee is further authorized to distribute copies of the modified or unmodified Software to third parties according to the terms and conditions set forth hereinafter. 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION The Licensee is authorized to distribute true copies of the Software in Source Code or Object Code form, provided that said distribution complies with all the provisions of the Agreement and is accompanied by: 1. a copy of the Agreement, 2. a notice relating to the limitation of both the Licensor's warranty and liability as set forth in Articles 8 and 9, and that, in the event that only the Object Code of the Software is redistributed, the Licensee allows effective access to the full Source Code of the Software at a minimum during the entire period of its distribution of the Software, it being understood that the additional cost of acquiring the Source Code shall not exceed the cost of transferring the data. 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE If the Licensee makes any Contribution to the Software, the resulting Modified Software may be distributed under a license agreement other than this Agreement subject to compliance with the provisions of Article 5.3.4. 5.3.3 DISTRIBUTION OF EXTERNAL MODULES When the Licensee has developed an External Module, the terms and conditions of this Agreement do not apply to said External Module, that may be distributed under a separate license agreement. 5.3.4 CREDITS Any Licensee who may distribute a Modified Software hereby expressly agrees to: 1. indicate in the related documentation that it is based on the Software licensed hereunder, and reproduce the intellectual property notice for the Software, 2. ensure that written indications of the Software intended use, intellectual property notice and license hereunder are included in easily accessible format from the Modified Software interface, 3. mention, on a freely accessible website describing the Modified Software, at least throughout the distribution term thereof, that it is based on the Software licensed hereunder, and reproduce the Software intellectual property notice, 4. where it is distributed to a third party that may distribute a Modified Software without having to make its source code available, make its best efforts to ensure that said third party agrees to comply with the obligations set forth in this Article . If the Software, whether or not modified, is distributed with an External Module designed for use in connection with the Software, the Licensee shall submit said External Module to the foregoing obligations. 5.3.5 COMPATIBILITY WITH THE CeCILL AND CeCILL-C LICENSES Where a Modified Software contains a Contribution subject to the CeCILL license, the provisions set forth in Article 5.3.4 shall be optional. A Modified Software may be distributed under the CeCILL-C license. In such a case the provisions set forth in Article 5.3.4 shall be optional. Article 6 - INTELLECTUAL PROPERTY 6.1 OVER THE INITIAL SOFTWARE The Holder owns the economic rights over the Initial Software. Any or all use of the Initial Software is subject to compliance with the terms and conditions under which the Holder has elected to distribute its work and no one shall be entitled to modify the terms and conditions for the distribution of said Initial Software. The Holder undertakes that the Initial Software will remain ruled at least by this Agreement, for the duration set forth in Article 4.2. 6.2 OVER THE CONTRIBUTIONS The Licensee who develops a Contribution is the owner of the intellectual property rights over this Contribution as defined by applicable law. 6.3 OVER THE EXTERNAL MODULES The Licensee who develops an External Module is the owner of the intellectual property rights over this External Module as defined by applicable law and is free to choose the type of agreement that shall govern its distribution. 6.4 JOINT PROVISIONS The Licensee expressly undertakes: 1. not to remove, or modify, in any manner, the intellectual property notices attached to the Software; 2. to reproduce said notices, in an identical manner, in the copies of the Software modified or not. The Licensee undertakes not to directly or indirectly infringe the intellectual property rights of the Holder and/or Contributors on the Software and to take, where applicable, vis-à-vis its staff, any and all measures required to ensure respect of said intellectual property rights of the Holder and/or Contributors. Article 7 - RELATED SERVICES 7.1 Under no circumstances shall the Agreement oblige the Licensor to provide technical assistance or maintenance services for the Software. However, the Licensor is entitled to offer this type of services. The terms and conditions of such technical assistance, and/or such maintenance, shall be set forth in a separate instrument. Only the Licensor offering said maintenance and/or technical assistance services shall incur liability therefor. 7.2 Similarly, any Licensor is entitled to offer to its licensees, under its sole responsibility, a warranty, that shall only be binding upon itself, for the redistribution of the Software and/or the Modified Software, under terms and conditions that it is free to decide. Said warranty, and the financial terms and conditions of its application, shall be subject of a separate instrument executed between the Licensor and the Licensee. Article 8 - LIABILITY 8.1 Subject to the provisions of Article 8.2, the Licensee shall be entitled to claim compensation for any direct loss it may have suffered from the Software as a result of a fault on the part of the relevant Licensor, subject to providing evidence thereof. 8.2 The Licensor's liability is limited to the commitments made under this Agreement and shall not be incurred as a result of in particular: (i) loss due the Licensee's total or partial failure to fulfill its obligations, (ii) direct or consequential loss that is suffered by the Licensee due to the use or performance of the Software, and (iii) more generally, any consequential loss. In particular the Parties expressly agree that any or all pecuniary or business loss (i.e. loss of data, loss of profits, operating loss, loss of customers or orders, opportunity cost, any disturbance to business activities) or any or all legal proceedings instituted against the Licensee by a third party, shall constitute consequential loss and shall not provide entitlement to any or all compensation from the Licensor. Article 9 - WARRANTY 9.1 The Licensee acknowledges that the scientific and technical state-of-the-art when the Software was distributed did not enable all possible uses to be tested and verified, nor for the presence of possible defects to be detected. In this respect, the Licensee's attention has been drawn to the risks associated with loading, using, modifying and/or developing and reproducing the Software which are reserved for experienced users. The Licensee shall be responsible for verifying, by any or all means, the suitability of the product for its requirements, its good working order, and for ensuring that it shall not cause damage to either persons or properties. 9.2 The Licensor hereby represents, in good faith, that it is entitled to grant all the rights over the Software (including in particular the rights set forth in Article 5). 9.3 The Licensee acknowledges that the Software is supplied "as is" by the Licensor without any other express or tacit warranty, other than that provided for in Article 9.2 and, in particular, without any warranty as to its commercial value, its secured, safe, innovative or relevant nature. Specifically, the Licensor does not warrant that the Software is free from any error, that it will operate without interruption, that it will be compatible with the Licensee's own equipment and software configuration, nor that it will meet the Licensee's requirements. 9.4 The Licensor does not either expressly or tacitly warrant that the Software does not infringe any third party intellectual property right relating to a patent, software or any other property right. Therefore, the Licensor disclaims any and all liability towards the Licensee arising out of any or all proceedings for infringement that may be instituted in respect of the use, modification and redistribution of the Software. Nevertheless, should such proceedings be instituted against the Licensee, the Licensor shall provide it with technical and legal assistance for its defense. Such technical and legal assistance shall be decided on a case-by-case basis between the relevant Licensor and the Licensee pursuant to a memorandum of understanding. The Licensor disclaims any and all liability as regards the Licensee's use of the name of the Software. No warranty is given as regards the existence of prior rights over the name of the Software or as regards the existence of a trademark. Article 10 - TERMINATION 10.1 In the event of a breach by the Licensee of its obligations hereunder, the Licensor may automatically terminate this Agreement thirty (30) days after notice has been sent to the Licensee and has remained ineffective. 10.2 A Licensee whose Agreement is terminated shall no longer be authorized to use, modify or distribute the Software. However, any licenses that it may have granted prior to termination of the Agreement shall remain valid subject to their having been granted in compliance with the terms and conditions hereof. Article 11 - MISCELLANEOUS 11.1 EXCUSABLE EVENTS Neither Party shall be liable for any or all delay, or failure to perform the Agreement, that may be attributable to an event of force majeure, an act of God or an outside cause, such as defective functioning or interruptions of the electricity or telecommunications networks, network paralysis following a virus attack, intervention by government authorities, natural disasters, water damage, earthquakes, fire, explosions, strikes and labor unrest, war, etc. 11.2 Any failure by either Party, on one or more occasions, to invoke one or more of the provisions hereof, shall under no circumstances be interpreted as being a waiver by the interested Party of its right to invoke said provision(s) subsequently. 11.3 The Agreement cancels and replaces any or all previous agreements, whether written or oral, between the Parties and having the same purpose, and constitutes the entirety of the agreement between said Parties concerning said purpose. No supplement or modification to the terms and conditions hereof shall be effective as between the Parties unless it is made in writing and signed by their duly authorized representatives. 11.4 In the event that one or more of the provisions hereof were to conflict with a current or future applicable act or legislative text, said act or legislative text shall prevail, and the Parties shall make the necessary amendments so as to comply with said act or legislative text. All other provisions shall remain effective. Similarly, invalidity of a provision of the Agreement, for any reason whatsoever, shall not cause the Agreement as a whole to be invalid. 11.5 LANGUAGE The Agreement is drafted in both French and English and both versions are deemed authentic. Article 12 - NEW VERSIONS OF THE AGREEMENT 12.1 Any person is authorized to duplicate and distribute copies of this Agreement. 12.2 So as to ensure coherence, the wording of this Agreement is protected and may only be modified by the authors of the License, who reserve the right to periodically publish updates or new versions of the Agreement, each with a separate number. These subsequent versions may address new issues encountered by Free Software. 12.3 Any Software distributed under a given version of the Agreement may only be subsequently distributed under the same version of the Agreement or a subsequent version. Article 13 - GOVERNING LAW AND JURISDICTION 13.1 The Agreement is governed by French law. The Parties agree to endeavor to seek an amicable solution to any disagreements or disputes that may arise during the performance of the Agreement. 13.2 Failing an amicable solution within two (2) months as from their occurrence, and unless emergency proceedings are necessary, the disagreements or disputes shall be referred to the Paris Courts having jurisdiction, by the more diligent Party. Version 1.0 dated 2006-09-05. odil-0.4.1/README.md000066400000000000000000000015251266460524100137330ustar00rootroot00000000000000Odil ======= Odil is a C++11 library for the [DICOM](http://dicom.nema.org/) standard. Odil leverages C++ constructs to provide a user-friendly API of the different parts of the DICOM standard. Included in Odil are exception-based error handling, generic access to datasets elements, standard JSON and XML representation of datasets, and generic implementation of messages, clients and servers for the various DICOM protocols. Odil also provides conversion to and from [DCMTK](http://dicom.offis.de/dcmtk.php.en) data structures. Odil builds and run on: * Linux (Debian 7, Debian 8, Ubuntu 12.04, Ubuntu 14.04, both 32 and 64 bits) * OS X [![Build Status](https://travis-ci.org/lamyj/odil.svg?branch=master)](https://travis-ci.org/lamyj/odil) [![Coverage Status](https://coveralls.io/repos/lamyj/odil/badge.svg)](https://coveralls.io/r/lamyj/odil) odil-0.4.1/appveyor.full.yml000066400000000000000000000042061266460524100160040ustar00rootroot00000000000000version: "{build}" os: Visual Studio 2015 clone_folder: c:\projects\dcmtkpp environment: BOOST_ROOT: C:/Libraries/boost_1_59_0 BOOST_LIBRARYDIR: C:/Libraries/boost_1_59_0/lib64-msvc-14.0 ICU_INCLUDE_DIR: C:/Libraries/icu/include ICU_LIBRARY: C:/Libraries/icu/lib64/icuuc.lib JsonCpp_INCLUDE_DIR: c:/Libraries/jsoncpp_0_10_5/include JsonCpp_LIBRARY: c:/Libraries/jsoncpp_0_10_5/lib/jsoncpp.lib DCMTK_INCLUDE_DIR: C:/Libraries/dcmtk-3.6.1_20150924/include DCMTK_LIBRARY: C:/Libraries/dcmtk-3.6.1_20150924/lib/dcmdata.lib #init: #- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) install: # ICU4C - ps: Start-FileDownload http://download.icu-project.org/files/icu4c/56.1/icu4c-56_1-Win64-msvc10.zip - 7z x -oC:\Libraries icu4c-56_1-Win64-msvc10.zip # JsonCpp - ps: Start-FileDownload https://github.com/open-source-parsers/jsoncpp/archive/0.10.5.zip - 7z x -oC:\projects 0.10.5.zip - cd C:\projects\jsoncpp-0.10.5 - mkdir build - cd build - cmake -D CMAKE_INSTALL_PREFIX=c:\Libraries\jsoncpp_0_10_5 .. - cmake --build . --config release --target install # DCMTK - ps: Start-FileDownload http://dicom.offis.de/download/dcmtk/snapshot/dcmtk-3.6.1_20150924.tar.gz - 7z x -so dcmtk-3.6.1_20150924.tar.gz | 7z x -si -oC:\projects -ttar - cd C:\projects\dcmtk-3.6.1_20150924 - mkdir build - cd build - cmake -D CMAKE_INSTALL_PREFIX=c:\Libraries\dcmtk-3.6.1_20150924 .. - cmake --build . --config release --target install before_build: - cd c:\projects\dcmtkpp - md build - cd build - set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH% - cmake -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_LIBRARYDIR%" -DICU_INCLUDE_DIR="%ICU_INCLUDE_DIR%" -DICU_LIBRARY="%ICU_LIBRARY%" -DJsonCpp_INCLUDE_DIR="%JsonCpp_INCLUDE_DIR%" -DJsonCpp_LIBRARY="%JsonCpp_LIBRARY%" -DDCMTK_INCLUDE_DIR="%DCMTK_INCLUDE_DIR%" -DDCMTK_LIBRARY="%DCMTK_LIBRARY%" .. build: project: C:\projects\dcmtkpp\build\dcmtkpp.sln #on_finish: #- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) odil-0.4.1/appveyor.yml000066400000000000000000000030541266460524100150430ustar00rootroot00000000000000version: "{build}" os: Windows Server 2012 R2 clone_folder: c:\projects\odil environment: BOOST_ROOT: C:/Libraries/boost_1_59_0 BOOST_LIBRARYDIR: C:/Libraries/boost_1_59_0/lib64-msvc-14.0 ICU_INCLUDE_DIR: C:/Libraries/icu/include ICU_LIBRARY: C:/Libraries/icu/lib64/icuuc.lib JsonCpp_INCLUDE_DIR: c:/Libraries/jsoncpp_0_10_5/include JsonCpp_LIBRARY: c:/Libraries/jsoncpp_0_10_5/lib/jsoncpp.lib DCMTK_INCLUDE_DIR: C:/Libraries/dcmtk-3.6.1_20150924/include DCMTK_LIBRARY: C:/Libraries/dcmtk-3.6.1_20150924/lib/dcmdata.lib configuration: - Release install: # ICU4C - ps: Start-FileDownload http://download.icu-project.org/files/icu4c/56.1/icu4c-56_1-Win64-msvc10.zip - 7z x -bd -oC:\Libraries icu4c-56_1-Win64-msvc10.zip # JsonCpp - ps: Start-FileDownload https://github.com/lamyj/jsoncpp/releases/download/0.10.5/jsoncpp_0_10_5_Win64_msvc14.zip - 7z x -bd -oC:\Libraries jsoncpp_0_10_5_Win64_msvc14.zip # DCMTK - ps: Start-FileDownload https://github.com/lamyj/dcmtk/releases/download/DCMTK-3.6.1_20150924/dcmtk-3.6.1_20150924_Win64_msvc14.zip - 7z x -bd -oC:\Libraries dcmtk-3.6.1_20150924_Win64_msvc14.zip before_build: - cd c:\projects\odil - md build - cd build - cmake -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_LIBRARYDIR%" -DICU_INCLUDE_DIR="%ICU_INCLUDE_DIR%" -DICU_LIBRARY="%ICU_LIBRARY%" -DJsonCpp_INCLUDE_DIR="%JsonCpp_INCLUDE_DIR%" -DJsonCpp_LIBRARY="%JsonCpp_LIBRARY%" -DDCMTK_INCLUDE_DIR="%DCMTK_INCLUDE_DIR%" -DDCMTK_LIBRARY="%DCMTK_LIBRARY%" .. build: project: C:\projects\odil\build\odil.sln odil-0.4.1/examples/000077500000000000000000000000001266460524100142675ustar00rootroot00000000000000odil-0.4.1/examples/CMakeLists.txt000066400000000000000000000007421266460524100170320ustar00rootroot00000000000000find_package(DCMTK REQUIRED) find_package(JsonCpp REQUIRED) include_directories(${CMAKE_SOURCE_DIR}/src ${JsonCpp_INCLUDE_DIRS}) add_definitions( ${DCMTK_DEFINITIONS} -D BOOST_ASIO_DYN_LINK -D ODIL_MAJOR_VERSION=${odil_MAJOR_VERSION} ) file(GLOB_RECURSE examples *.cpp) foreach(example_file ${examples}) get_filename_component(example ${example_file} NAME_WE) add_executable(${example} ${example_file}) target_link_libraries(${example} odil) endforeach() odil-0.4.1/examples/dicomdir.cpp000066400000000000000000000011311266460524100165610ustar00rootroot00000000000000#include #include #include #include int main(int argc, char** argv) { std::string const root(argv[1]); std::vector const files(argv+2, argv+argc); odil::BasicDirectoryCreator creator(root, files, { {"PATIENT", { {odil::registry::PatientBirthDate, 3} }}, {"STUDY", { {odil::registry::PatientAge, 3} }}, {"SERIES", { {odil::registry::SeriesDescription, 3} }}, {"IMAGE", { {odil::registry::ImageType, 3} }}, }); creator(); return 0; } odil-0.4.1/examples/dump.cpp000066400000000000000000000041341266460524100157420ustar00rootroot00000000000000#include #include #include #include #include #include #include #include struct Printer { typedef void result_type; std::ostream & stream; std::string indent; Printer(std::ostream & stream, std::string const & indent="") : stream(stream), indent(indent) { // Nothing else } template void operator()(T const & value) const { for(auto const & item: value) { this->stream << item << " "; } } void operator()(odil::Value::DataSets const & value) const { this->stream << "\n"; auto const last_it = --value.end(); for(auto it=value.begin(); it!= value.end(); ++it) { Printer const printer(this->stream, this->indent+" "); printer(*it); if(it != last_it) { this->stream << "----\n"; } } } void operator()(odil::Value::Binary const & value) const { this->stream << this->indent << "(binary)"; } void operator()(odil::DataSet const & data_set) const { for(auto const & item: data_set) { this->stream << this->indent << item.first << " " << as_string(item.second.vr) << " "; odil::apply_visitor(*this, item.second.get_value()); this->stream << "\n"; } } }; int main(int argc, char** argv) { for(int i=1; i file; try { file = odil::Reader::read_file(stream); } catch(std::exception & e) { std::cout << "Could not read " << argv[i] << ": " << e.what() << "\n"; } auto const & meta_information = file.first; auto const & data_set = file.second; Printer printer(std::cout); printer(meta_information); std::cout << "\n"; printer(data_set); } return 0; } odil-0.4.1/examples/find.cpp000066400000000000000000000040221266460524100157110ustar00rootroot00000000000000#include #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/FindSCU.h" #include "odil/registry.h" void print_informations(odil::DataSet const & response) { auto const name = response.has("PatientName")? response.as_string("PatientName", 0):"(no name)"; auto const study = response.has("StudyDescription")? response.as_string("StudyDescription", 0):"(no description)"; auto const date = response.has("StudyDate")? response.as_string("StudyDate", 0):"(no date)"; std::cout << "\"" << name << "\": \"" << study << "\" on " << date << "\n"; } int main() { odil::Association association; association.set_peer_host("184.73.255.26"); association.set_peer_port(11112); association.update_parameters() .set_calling_ae_title("myself") .set_called_ae_title("AWSPIXELMEDPUB") .set_presentation_contexts({ { 1, odil::registry::StudyRootQueryRetrieveInformationModelFIND, { odil::registry::ExplicitVRLittleEndian }, true, false }, { 3, odil::registry::VerificationSOPClass, { odil::registry::ExplicitVRLittleEndian }, true, false } }); association.associate(); odil::FindSCU scu(association); scu.echo(); odil::DataSet query; query.add("PatientName", { "*" }); query.add("QueryRetrieveLevel", { "STUDY" }); query.add("StudyDescription"); query.add("StudyDate"); scu.set_affected_sop_class(odil::registry::StudyRootQueryRetrieveInformationModelFIND); std::cout << "--------\n"; std::cout << "Callback\n"; std::cout << "--------\n\n"; scu.find(query, print_informations); std::cout << "\n"; std::cout << "------\n"; std::cout << "vector\n"; std::cout << "------\n\n"; auto const result = scu.find(query); for(auto const & dataset: result) { print_informations(dataset); } association.release(); } odil-0.4.1/examples/genericscp.cpp000066400000000000000000000102131266460524100171120ustar00rootroot00000000000000#include #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/EchoSCP.h" #include "odil/FindSCP.h" #include "odil/StoreSCP.h" #include "odil/registry.h" #include "odil/SCPDispatcher.h" #include "odil/SCP.h" #include "odil/message/CEchoRequest.h" #include "odil/message/CFindRequest.h" #include "odil/message/CFindResponse.h" #include "odil/message/CStoreRequest.h" class FindGenerator: public odil::SCP::DataSetGenerator { public: FindGenerator() { // Nothing to do } virtual ~FindGenerator() { // Nothing to do. } virtual void initialize(odil::message::Request const & ) { odil::DataSet data_set_1; data_set_1.add(odil::registry::PatientName, {"Hello^World"}); data_set_1.add(odil::registry::PatientID, {"1234"}); this->_responses.push_back(data_set_1); odil::DataSet data_set_2; data_set_2.add(odil::registry::PatientName, {"Doe^John"}); data_set_2.add(odil::registry::PatientID, {"5678"}); this->_responses.push_back(data_set_2); this->_response_iterator = this->_responses.begin(); } virtual bool done() const { return (this->_response_iterator == this->_responses.end()); } virtual odil::DataSet get() const { return *this->_response_iterator; } virtual void next() { ++this->_response_iterator; } private: std::vector _responses; std::vector::const_iterator _response_iterator; }; odil::Value::Integer echo(odil::message::CEchoRequest const & request) { std::cout << "Received echo\n"; std::cout << " ID: " << request.get_message_id() << "\n"; std::cout << " Affected SOP Class UID: " << request.get_affected_sop_class_uid() << "\n"; return odil::message::Response::Success; } odil::Value::Integer store(odil::message::CStoreRequest const & request) { auto const patient_name = request.get_data_set().as_string(odil::registry::PatientName)[0]; std::cout << "Storing " << patient_name << "\n"; return odil::message::Response::Success; } int main() { odil::Association association; association.receive_association(boost::asio::ip::tcp::v4(), 11112); std::cout << "Received association from " << association.get_peer_host() << ":" << association.get_peer_port() << "\n"; auto const & contexts = association.get_negotiated_parameters().get_presentation_contexts(); std::cout << "Presentation contexts (" << contexts.size() << ")\n"; for(auto const & context: contexts) { std::cout << " " << odil::registry::uids_dictionary.at(context.abstract_syntax).name << ": " << odil::registry::uids_dictionary.at(context.transfer_syntaxes[0]).name << ", " << (context.scu_role_support?"SCU":"") << ((context.scu_role_support & context.scp_role_support)?"/":"") << (context.scp_role_support?"SCP":"") << std::endl; } auto echo_scp = std::make_shared(association, echo); auto find_scp = std::make_shared( association, std::make_shared()); auto store_scp = std::make_shared(association, store); odil::SCPDispatcher dispatcher(association); dispatcher.set_scp(odil::message::Message::Command::C_ECHO_RQ, echo_scp); dispatcher.set_scp(odil::message::Message::Command::C_FIND_RQ, find_scp); dispatcher.set_scp( odil::message::Message::Command::C_STORE_RQ, store_scp); bool done = false; while(!done) { try { dispatcher.dispatch(); } catch(odil::AssociationReleased const &) { std::cout << "Peer released association" << std::endl; done = true; } catch(odil::AssociationAborted const & e) { std::cout << "Peer aborted association, " << "source: " << int(e.source) << ", " << "reason: " << int(e.reason) << std::endl; done = true; } } } odil-0.4.1/examples/get.cpp000066400000000000000000000066301266460524100155570ustar00rootroot00000000000000#include #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/FindSCU.h" #include "odil/GetSCU.h" #include "odil/registry.h" void print_informations(odil::DataSet const & response) { auto const name = response.has("PatientName")? response.as_string("PatientName", 0):"(no name)"; auto const study = response.has("StudyDescription")? response.as_string("StudyDescription", 0):"(no study description)"; auto const series = response.has("SeriesDescription")? response.as_string("SeriesDescription", 0):"(no series description)"; auto const instance = response.has("InstanceNumber")? response.as_int("InstanceNumber", 0):(-1); std::cout << name << ": " << study << " / " << series << ": " << instance << "\n"; } int main() { odil::Association association; association.set_peer_host("184.73.255.26"); association.set_peer_port(11112); association.update_parameters() .set_calling_ae_title("myself") .set_called_ae_title("AWSPIXELMEDPUB") .set_presentation_contexts({ { 1, odil::registry::StudyRootQueryRetrieveInformationModelFIND, { odil::registry::ImplicitVRLittleEndian }, true, false }, { 3, odil::registry::StudyRootQueryRetrieveInformationModelGET, { odil::registry::ImplicitVRLittleEndian }, true, false }, { 5, odil::registry::MRImageStorage, { odil::registry::ImplicitVRLittleEndian }, false, true }, { 7, odil::registry::VerificationSOPClass, { odil::registry::ImplicitVRLittleEndian }, true, false } }); association.associate(); odil::FindSCU find_scu(association); find_scu.set_affected_sop_class( odil::registry::StudyRootQueryRetrieveInformationModelFIND); odil::DataSet query; query.add("QueryRetrieveLevel", { "STUDY" }); query.add("StudyInstanceUID"); auto const studies = find_scu.find(query); odil::DataSet series; for(auto const & study: studies) { if(!study.has("StudyInstanceUID")) { continue; } query = odil::DataSet(); query.add("QueryRetrieveLevel", {"SERIES"}); query.add("Modality", {"MR"}); query.add("StudyInstanceUID", study.as_string("StudyInstanceUID")); query.add("SeriesInstanceUID"); auto const study_series = find_scu.find(query); if(!study_series.empty()) { series = study_series[0]; break; } } odil::GetSCU get_scu(association); get_scu.set_affected_sop_class( odil::registry::StudyRootQueryRetrieveInformationModelGET); query = odil::DataSet(); query.add("QueryRetrieveLevel", { "SERIES" }); query.add("StudyInstanceUID", series["StudyInstanceUID"]); query.add("SeriesInstanceUID", series["SeriesInstanceUID"]); std::cout << "--------\n"; std::cout << "Callback\n"; std::cout << "--------\n\n"; get_scu.get(query, print_informations); std::cout << "\n"; std::cout << "------\n"; std::cout << "vector\n"; std::cout << "------\n\n"; auto const result = get_scu.get(query); for(auto const & dataset: result) { print_informations(dataset); } association.release(); } odil-0.4.1/examples/move.cpp000066400000000000000000000071001266460524100157370ustar00rootroot00000000000000#include #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/FindSCU.h" #include "odil/MoveSCU.h" #include "odil/registry.h" void print_informations(odil::DataSet const & response) { auto const name = response.has("PatientName")? response.as_string("PatientName", 0):"(no name)"; auto const study = response.has("StudyDescription")? response.as_string("StudyDescription", 0):"(no study description)"; auto const series = response.has("SeriesDescription")? response.as_string("SeriesDescription", 0):"(no series description)"; auto const instance = response.has("InstanceNumber")? response.as_int("InstanceNumber", 0):(-1); std::cout << name << ": " << study << " / " << series << ": " << instance << "\n"; } int main() { odil::Association association; association.set_peer_host("184.73.255.26"); association.set_peer_port(11112); association.update_parameters() .set_calling_ae_title("myself") .set_called_ae_title("AWSPIXELMEDPUB") .set_presentation_contexts({ { 1, odil::registry::StudyRootQueryRetrieveInformationModelFIND, { odil::registry::ImplicitVRLittleEndian }, true, false }, { 3, odil::registry::StudyRootQueryRetrieveInformationModelMOVE, { odil::registry::ImplicitVRLittleEndian }, true, false }, { 5, odil::registry::MRImageStorage, { odil::registry::ImplicitVRLittleEndian }, false, true }, { 7, odil::registry::VerificationSOPClass, { odil::registry::ImplicitVRLittleEndian }, true, false } }); association.associate(); odil::FindSCU find_scu(association); find_scu.set_affected_sop_class( odil::registry::StudyRootQueryRetrieveInformationModelFIND); odil::DataSet query; query.add("QueryRetrieveLevel", { "STUDY" }); query.add("StudyInstanceUID"); query.add("NumberOfStudyRelatedSeries"); auto const studies = find_scu.find(query); odil::DataSet series; for(auto const & study: studies) { if(!study.has("StudyInstanceUID")) { continue; } query = odil::DataSet(); query.add("QueryRetrieveLevel", {"SERIES"}); query.add("Modality", {"MR"}); query.add("StudyInstanceUID", study.as_string("StudyInstanceUID")); query.add("SeriesInstanceUID"); auto const study_series = find_scu.find(query); if(!study_series.empty()) { series = study_series[0]; break; } } odil::MoveSCU move_scu(association); move_scu.set_affected_sop_class( odil::registry::StudyRootQueryRetrieveInformationModelMOVE); move_scu.set_move_destination( association.get_parameters().get_calling_ae_title()); query = odil::DataSet(); query.add("QueryRetrieveLevel", { "SERIES" }); query.add("StudyInstanceUID", series["StudyInstanceUID"]); query.add("SeriesInstanceUID", series["SeriesInstanceUID"]); std::cout << "--------\n"; std::cout << "Callback\n"; std::cout << "--------\n\n"; move_scu.move(query, print_informations); std::cout << "\n"; std::cout << "------\n"; std::cout << "vector\n"; std::cout << "------\n\n"; std::vector result = move_scu.move(query); for(auto dataset: result) { print_informations(dataset); } association.release(); } odil-0.4.1/examples/store.cpp000066400000000000000000000022241266460524100161270ustar00rootroot00000000000000#include "odil/Association.h" #include "odil/DataSet.h" #include "odil/Reader.h" #include "odil/StoreSCU.h" int main(int argc, char** argv) { odil::Association association; association.set_peer_host("184.73.255.26"); association.set_peer_port(11112); association.update_parameters() .set_calling_ae_title("myself") .set_called_ae_title("AWSPIXELMEDPUB") .set_presentation_contexts({ { 1, odil::registry::MRImageStorage, { odil::registry::ImplicitVRLittleEndian }, false, true }, { 3, odil::registry::VerificationSOPClass, { odil::registry::ImplicitVRLittleEndian }, true, false } }); association.associate(); odil::StoreSCU scu(association); scu.echo(); for(int i=1; i #include "odil/registry.h" #include "odil/ElementsDictionary.h" #include "odil/Tag.h" #include "odil/VR.h" #include "odil/UIDsDictionary.h" namespace odil { namespace registry { struct RawElementsDictionaryEntry { uint16_t group; uint16_t element; char const * name; char const * keyword; char const * vr; char const * vm; }; ElementsDictionary create_public_dictionary() { RawElementsDictionaryEntry raw_entries[] = { {% for entry in elements_dictionary %} { {{ "0x%04x"|format(entry[0][0]) }}, {{ "0x%04x"|format(entry[0][1]) }}, "{{ entry[1] }}", "{{ entry[2] }}", "{{ entry[3] }}", "{{ entry[4] }}" }, {% endfor %} }; ElementsDictionary public_dictionary; unsigned long const count = sizeof(raw_entries)/sizeof(RawElementsDictionaryEntry); for(unsigned long i=0; i(tag, entry)); } return public_dictionary; } struct RawUIDsDictionaryEntry { char const * uid; char const * name; char const * keyword; char const * type; }; UIDsDictionary create_uids_dictionary() { RawUIDsDictionaryEntry raw_entries[] = { {% for entry in uids %} { "{{ entry[0] }}", "{{ entry[1] }}", "{{ entry[2] }}", "{{ entry[3] }}" }, {% endfor %} }; UIDsDictionary uids_dictionary; unsigned long const count = sizeof(raw_entries)/sizeof(RawUIDsDictionaryEntry); for(unsigned long i=0; i(raw_entry.uid, entry)); } return uids_dictionary; } } } odil::ElementsDictionary odil::registry::public_dictionary=odil::registry::create_public_dictionary(); odil::UIDsDictionary odil::registry::uids_dictionary=odil::registry::create_uids_dictionary(); odil-0.4.1/registry.h.tmpl000066400000000000000000000017251266460524100154520ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _afc7b2d7_0869_4fea_9a9b_7fe6228baca9 #define _afc7b2d7_0869_4fea_9a9b_7fe6228baca9 #include "odil/ElementsDictionary.h" #include "odil/Tag.h" #include "odil/UIDsDictionary.h" namespace odil { namespace registry { {% for entry in elements_dictionary %} Tag const {{ entry[2] }}({{ "0x%04x, 0x%04x"|format(*entry[0]) }}); {% endfor %} {% for entry in uids %} std::string const {{ entry[2] }}("{{ entry[0] }}"); {% endfor %} extern ElementsDictionary public_dictionary; extern UIDsDictionary uids_dictionary; } } #endif // _afc7b2d7_0869_4fea_9a9b_7fe6228baca9 odil-0.4.1/src/000077500000000000000000000000001266460524100132405ustar00rootroot00000000000000odil-0.4.1/src/CMakeLists.txt000066400000000000000000000020161266460524100157770ustar00rootroot00000000000000find_package(Boost REQUIRED COMPONENTS filesystem system) find_package(DCMTK REQUIRED) find_package(ICU REQUIRED) find_package(JsonCpp REQUIRED) file(GLOB_RECURSE headers "*.h") file(GLOB_RECURSE templates "*.txx") file(GLOB_RECURSE files "*.cpp") include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${Boost_INCLUDE_DIRS} ${DCMTK_INCLUDE_DIRS} ${ICU_INCLUDE_DIRS} ${JsonCpp_INCLUDE_DIRS}) add_definitions( ${DCMTK_DEFINITIONS} -D BOOST_ASIO_SEPARATE_COMPILATION -D ODIL_MAJOR_VERSION=${odil_MAJOR_VERSION} ) link_directories(${Boost_LIBRARY_DIRS} ${DCMTK_LIBRARY_DIRS}) add_library(odil SHARED ${files} ${headers} ${templates}) target_link_libraries(odil ${Boost_LIBRARIES} ${DCMTK_LIBRARIES} ${ICU_LIBRARIES} ${JsonCpp_LIBRARIES}) set_target_properties(odil PROPERTIES VERSION ${odil_VERSION} SOVERSION ${odil_MAJOR_VERSION}) install(FILES ${headers} ${templates} DESTINATION include/odil) install( TARGETS odil ARCHIVE DESTINATION lib LIBRARY DESTINATION lib RUNTIME DESTINATION bin) odil-0.4.1/src/odil/000077500000000000000000000000001266460524100141675ustar00rootroot00000000000000odil-0.4.1/src/odil/Association.cpp000066400000000000000000000315221266460524100171520ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "Association.h" #include #include #include #include #include #include "odil/AssociationParameters.h" #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/uid.h" #include "odil/dul/StateMachine.h" #include "odil/message/Message.h" #include "odil/pdu/AAbort.h" #include "odil/pdu/AAssociate.h" #include "odil/pdu/AAssociateRJ.h" #include "odil/pdu/AReleaseRP.h" #include "odil/pdu/AReleaseRQ.h" #include "odil/pdu/ImplementationClassUID.h" #include "odil/pdu/ImplementationVersionName.h" #include "odil/pdu/PDataTF.h" #include "odil/pdu/PresentationContextAC.h" #include "odil/pdu/PresentationContextRQ.h" #include "odil/pdu/RoleSelection.h" #include "odil/pdu/UserIdentityRQ.h" #include "odil/pdu/UserInformation.h" #include "odil/Reader.h" #include "odil/Writer.h" namespace odil { Association ::Association() : _state_machine(), _peer_host(""), _peer_port(104), _association_parameters(), _transfer_syntaxes_by_abstract_syntax(), _transfer_syntaxes_by_id(), _next_message_id(1) { this->set_tcp_timeout(boost::posix_time::pos_infin); this->set_message_timeout(boost::posix_time::seconds(30)); } Association ::Association(Association const & other) : _state_machine(), _peer_host(other._peer_host), _peer_port(other._peer_port), _association_parameters(other._association_parameters), _transfer_syntaxes_by_abstract_syntax(), _transfer_syntaxes_by_id(), _next_message_id(other._next_message_id) { this->set_tcp_timeout(other.get_tcp_timeout()); this->set_message_timeout(other.get_message_timeout()); } Association ::~Association() { // Nothing to do, everything is taken care of by the StateMachine } dul::Transport & Association ::get_transport() { return this->_state_machine.get_transport(); } Association & Association ::operator=(Association const & other) { if(this != &other) { this->set_peer_host(other.get_peer_host()); this->set_peer_port(other.get_peer_port()); this->set_parameters(other.get_parameters()); } return *this; } std::string const & Association ::get_peer_host() const { return this->_peer_host; } void Association ::set_peer_host(std::string const & host) { if(this->is_associated()) { throw Exception("Cannot set member while associated"); } this->_peer_host = host; } uint16_t Association ::get_peer_port() const { return this->_peer_port; } void Association ::set_peer_port(uint16_t port) { if(this->is_associated()) { throw Exception("Cannot set member while associated"); } this->_peer_port = port; } AssociationParameters const & Association ::get_parameters() const { return this->_association_parameters; } AssociationParameters & Association ::update_parameters() { if(this->is_associated()) { throw Exception("Cannot set member while associated"); } return this->_association_parameters; } void Association ::set_parameters(AssociationParameters const & value) { if(this->is_associated()) { throw Exception("Cannot set member while associated"); } this->_association_parameters = value; } AssociationParameters const & Association ::get_negotiated_parameters() const { return this->_negotiated_parameters; } Association::duration_type Association ::get_tcp_timeout() const { return this->_state_machine.get_transport().get_timeout(); } void Association ::set_tcp_timeout(duration_type const & duration) { this->_state_machine.get_transport().set_timeout(duration); } Association::duration_type Association ::get_message_timeout() const { return this->_state_machine.get_timeout(); } void Association ::set_message_timeout(duration_type const & duration) { this->_state_machine.set_timeout(duration); } bool Association ::is_associated() const { return this->_state_machine.get_transport().is_open(); } void Association ::associate() { boost::asio::ip::tcp::resolver resolver( this->_state_machine.get_transport().get_service()); boost::asio::ip::tcp::resolver::query const query(this->_peer_host, ""); auto const endpoint_it = resolver.resolve(query); dul::EventData data; data.peer_endpoint = *endpoint_it; data.peer_endpoint.port(this->_peer_port); auto const request = std::make_shared( this->_association_parameters.as_a_associate_rq()); data.pdu = request; this->_state_machine.send_pdu(data); this->_state_machine.receive_pdu(data); if(data.pdu == nullptr) { throw Exception("No response received"); } else { auto const acceptation = std::dynamic_pointer_cast(data.pdu); auto const rejection = std::dynamic_pointer_cast(data.pdu); if(acceptation != nullptr) { this->_negotiated_parameters = AssociationParameters( *acceptation, this->_association_parameters); this->_transfer_syntaxes_by_abstract_syntax.clear(); this->_transfer_syntaxes_by_id.clear(); for(auto const & pc: this->_negotiated_parameters.get_presentation_contexts()) { if(pc.result != AssociationParameters::PresentationContext::Result::Acceptance) { continue; } this->_transfer_syntaxes_by_id[pc.id] = pc.transfer_syntaxes[0]; this->_transfer_syntaxes_by_abstract_syntax[pc.abstract_syntax] = {pc.id, pc.transfer_syntaxes[0]}; } } else if(rejection != nullptr) { throw Exception("Association rejected"); } else { throw Exception("Invalid response"); } } } void Association ::receive_association( boost::asio::ip::tcp const & protocol, unsigned short port, AssociationAcceptor acceptor) { dul::EventData data; data.peer_endpoint = dul::Transport::Socket::endpoint_type(protocol, port); this->_state_machine.set_association_acceptor(acceptor); this->_state_machine.receive(data); this->_state_machine.receive_pdu(data); if(data.pdu == NULL) { // We have rejected the request //return false; } else { auto const & request = std::dynamic_pointer_cast(data.pdu); if(request == nullptr) { throw Exception("Invalid response"); } auto const endpoint = this->_state_machine.get_transport().get_socket()->remote_endpoint(); this->_peer_host = endpoint.address().to_string(); this->_peer_port = endpoint.port(); this->_negotiated_parameters = data.association_parameters; this->_transfer_syntaxes_by_abstract_syntax.clear(); this->_transfer_syntaxes_by_id.clear(); for(auto const & pc: this->_negotiated_parameters.get_presentation_contexts()) { if(pc.result != AssociationParameters::PresentationContext::Result::Acceptance) { continue; } this->_transfer_syntaxes_by_id[pc.id] = pc.transfer_syntaxes[0]; this->_transfer_syntaxes_by_abstract_syntax[pc.abstract_syntax] = {pc.id, pc.transfer_syntaxes[0]}; } data.pdu = std::make_shared( this->_negotiated_parameters.as_a_associate_ac()); this->_state_machine.send_pdu(data); } } void Association ::release() { if(!this->is_associated()) { throw Exception("Not associated"); } auto pdu = std::make_shared(); dul::EventData data; data.pdu = pdu; this->_state_machine.send_pdu(data); this->_state_machine.receive_pdu(data); auto const reply = std::dynamic_pointer_cast(data.pdu); if(reply == nullptr) { // Invalid response, accept it nevertheless. } } void Association ::abort(int source, int reason) { if(!this->is_associated()) { throw Exception("Not associated"); } auto pdu = std::make_shared(source, reason); dul::EventData data; data.pdu = pdu; this->_state_machine.send_pdu(data); } message::Message Association ::receive_message() { bool done = false; int presentation_context_id; bool command_set_received=false; bool has_data_set=true; bool data_set_received=false; DataSet command_set; std::stringstream command_stream, data_stream; while(!done) { dul::EventData data; data.pdu = nullptr; this->_state_machine.receive_pdu(data); auto const a_release_rq = std::dynamic_pointer_cast(data.pdu); if(a_release_rq != nullptr) { data.pdu = std::make_shared(); this->_state_machine.send_pdu(data); throw AssociationReleased(); } auto const a_abort = std::dynamic_pointer_cast(data.pdu); if(a_abort != nullptr) { throw AssociationAborted(a_abort->get_source(), a_abort->get_reason()); } auto const p_data_tf = std::dynamic_pointer_cast(data.pdu); if(p_data_tf == nullptr) { throw Exception("Invalid PDU received"); } for(auto const & pdv: p_data_tf->get_pdv_items()) { presentation_context_id = pdv.get_presentation_context_id(); bool & received = pdv.is_command()?command_set_received:data_set_received; received |= pdv.is_last_fragment(); auto const & fragment_data = pdv.get_fragment(); std::stringstream & stream = pdv.is_command()?command_stream:data_stream; stream.write(&fragment_data[0], fragment_data.size()); if(command_set_received && command_set.empty()) { Reader reader(command_stream, registry::ImplicitVRLittleEndian); command_set = reader.read_data_set(); auto const value = command_set.as_int(registry::CommandDataSetType, 0); if(value == message::Message::DataSetType::ABSENT) { has_data_set = false; } } } done = command_set_received && (!has_data_set || data_set_received); } if(has_data_set) { auto const transfer_syntax_it = this->_transfer_syntaxes_by_id.find(presentation_context_id); if(transfer_syntax_it == this->_transfer_syntaxes_by_id.end()) { throw Exception("No such Presentation Context ID"); } Reader reader(data_stream, transfer_syntax_it->second); auto const data_set = reader.read_data_set(); return message::Message(command_set, data_set); } else { return message::Message(command_set); } } void Association ::send_message( message::Message const & message, std::string const & abstract_syntax) { auto const transfer_syntax_it = this->_transfer_syntaxes_by_abstract_syntax.find(abstract_syntax); if(transfer_syntax_it == this->_transfer_syntaxes_by_abstract_syntax.end()) { throw Exception("No transfer syntax for "+abstract_syntax); } auto const & transfer_syntax = transfer_syntax_it->second.second; auto const & id = transfer_syntax_it->second.first; std::vector pdv_items; std::ostringstream command_stream; Writer command_writer( command_stream, registry::ImplicitVRLittleEndian, // implicit vr for command Writer::ItemEncoding::ExplicitLength, true); // true for Command command_writer.write_data_set(message.get_command_set()); pdv_items.push_back( pdu::PDataTF::PresentationDataValueItem(id, 3, command_stream.str())); if (message.has_data_set()) { std::ostringstream data_stream; Writer data_writer( data_stream, transfer_syntax, Writer::ItemEncoding::ExplicitLength, false); data_writer.write_data_set(message.get_data_set()); pdv_items.push_back( pdu::PDataTF::PresentationDataValueItem( transfer_syntax_it->second.first, 2, data_stream.str())); } auto pdu = std::make_shared(pdv_items); dul::EventData data; data.pdu = pdu; this->_state_machine.send_pdu(data); } uint16_t Association ::next_message_id() { return ++this->_next_message_id; } } odil-0.4.1/src/odil/Association.h000066400000000000000000000145231266460524100166210ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _a52696bc_5c6e_402d_a343_6cb085eb0138 #define _a52696bc_5c6e_402d_a343_6cb085eb0138 #include #include #include #include #include #include "odil/AssociationAcceptor.h" #include "odil/AssociationParameters.h" #include "odil/dul/StateMachine.h" #include "odil/message/Message.h" namespace odil { /** * @brief Association. */ class Association { public: /// @brief Association result (ITU-T X.227, PS 3.8, 7.1.1.7 and PS 3.8, 9.3.4). enum Result { Accepted=0, RejectedPermanent=1, RejectedTransient=2, }; /// @brief Source of association result (PS 3.8, 7.1.1.8 and PS 3.8, 9.3.4). enum ResultSource { ULServiceUser=1, ULServiceProviderACSERelatedFunction=2, ULServiceProvderPresentationRelatedFunction=3, }; // PS 3.8, 7.1.1.9, and PS 3.8, 9.3.4, and ITU-T X.227 (UL service-user, // UL service-provider ACSE-related function), ITU-T X.226 (UL // service-provider presentation-related function) /// @brief Diagnostic of association result enum Diagnostic { // UL service-user NoReasonGiven=1, ApplicationContextNameNotSupported=2, CallingAETitleNotRecognized=3, CallingAPInvocationIdentifierNotRecognized=4, CallingAEQualifierNotRecognized=5, CallingAEInvocationIdentifierNotRecognized=6, CalledAETitleNotRecognized=7, CalledAPInvocationIdentifierNotRecognized=8, CalledAEQualifierNotRecognized=9, CalledAEInvocationIdentifierNotRecognized=10, // UL service-provider, ACSE-related function NoCommonULVersion=2, // UL service-provider, presentation-related function TemporaryCongestion=1, LocalLimitExceeded=2, CalledPresentationAddressUnknown=3, PresentationProtocolVersionNotSupported=4, NoPresentationServiceAccessPointAvailable=7, }; typedef dul::StateMachine::duration_type duration_type; /// @brief Create a default, un-associated, association. Association(); /// @brief Create an un-associated association. Association(Association const & other); /// @brief Destroy the association, release it if necessary. ~Association(); dul::Transport & get_transport(); /// @brief Assing an un-associated association; it remains un-associated. Association & operator=(Association const & other); /// @name Peer /// @{ /// @brief Return the host name of the peer. Defaults to "". std::string const & get_peer_host() const; /// @brief Set the host name of the peer. void set_peer_host(std::string const & host); /// @brief Return the port of the peer. Defaults to 104. uint16_t get_peer_port() const; /// @brief Set the port of the peer. void set_peer_port(uint16_t port); /// @} /// @brief Return the association parameters. AssociationParameters const & get_parameters() const; /// @brief Return the association parameters. AssociationParameters & update_parameters(); /// @brief Set the association parameters, throw an exception when associated. void set_parameters(AssociationParameters const & value); /// @brief Return the negotiated association parameters. AssociationParameters const & get_negotiated_parameters() const; /// @name Timeouts /// @{ /// @brief Return the TCP timeout, default to infinity. duration_type get_tcp_timeout() const; /// @brief Set the timeout. void set_tcp_timeout(duration_type const & duration); /// @brief Return the DIMSE timeout, default to 30s. duration_type get_message_timeout() const; /// @brief Set the DIMSE timeout. void set_message_timeout(duration_type const & duration); /// @} /// @name Association /// @{ /// @brief Test whether the object is currently associated to its peer. bool is_associated() const; /// @brief Request an association with the peer. void associate(); /// @brief Receive an association from a peer. void receive_association( boost::asio::ip::tcp const & protocol, unsigned short port, AssociationAcceptor acceptor=default_association_acceptor); /// @brief Reject the received association request. void reject(Result result, ResultSource result_source, Diagnostic diagnostic); /// @brief Gracefully release the association. Throws an exception if not associated. void release(); /// @brief Forcefully release the association. Throws an exception if not associated. void abort(int source, int reason); /// @} /// @name DIMSE messages sending and reception. /// @{ /** * @brief Receive a generic DIMSE message. * * Throw an AssociationReleased or AssociationAborted if the peer released * or aborted the association. */ message::Message receive_message(); /// @brief Send a DIMSE message. void send_message( message::Message const & message, std::string const & abstract_syntax); /// @brief Return the next available message id. uint16_t next_message_id(); /// @} private: dul::StateMachine _state_machine; std::string _peer_host; uint16_t _peer_port; AssociationParameters _association_parameters; AssociationParameters _negotiated_parameters; std::map> _transfer_syntaxes_by_abstract_syntax; std::map _transfer_syntaxes_by_id; uint16_t _next_message_id; }; class AssociationReleased: public Exception { public: AssociationReleased() : Exception("Association released") { // Nothing else. } }; class AssociationAborted: public Exception { public: uint8_t source; uint8_t reason; AssociationAborted(unsigned char source, unsigned char reason) : Exception("Association aborted"), source(source), reason(reason) { // Nothing else. } }; } #endif // _a52696bc_5c6e_402d_a343_6cb085eb0138 odil-0.4.1/src/odil/AssociationAcceptor.cpp000066400000000000000000000042311266460524100206300ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/AssociationAcceptor.h" #include #include #include #include "odil/AssociationParameters.h" #include "odil/Exception.h" namespace odil { AssociationParameters default_association_acceptor(AssociationParameters const & input) { AssociationParameters output; output.set_called_ae_title(input.get_calling_ae_title()); output.set_calling_ae_title(input.get_called_ae_title()); std::vector presentation_contexts = input.get_presentation_contexts(); for(auto & presentation_context: presentation_contexts) { presentation_context.transfer_syntaxes = { presentation_context.transfer_syntaxes[0] }; presentation_context.result = AssociationParameters::PresentationContext::Result::Acceptance; } output.set_presentation_contexts(presentation_contexts); output.set_maximum_length(input.get_maximum_length()); return output; } AssociationRejected ::AssociationRejected( unsigned char result, unsigned char source, unsigned char reason, std::string const & message) : Exception(message) { this->set_result(result); this->set_source(source); this->set_reason(reason); } unsigned char AssociationRejected ::get_result() const { return this->_result; } void AssociationRejected ::set_result(unsigned char value) { this->_result = value; } unsigned char AssociationRejected ::get_source() const { return this->_source; } void AssociationRejected ::set_source(unsigned char value) { this->_source = value; } unsigned char AssociationRejected ::get_reason() const { return this->_reason; } void AssociationRejected ::set_reason(unsigned char value) { this->_reason = value; } } odil-0.4.1/src/odil/AssociationAcceptor.h000066400000000000000000000035321266460524100203000ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _b21e4f11_9337_4612_8152_b59dedc16f18 #define _b21e4f11_9337_4612_8152_b59dedc16f18 #include #include #include "odil/AssociationParameters.h" #include "odil/Exception.h" namespace odil { /** * @brief Callback to check whether the association request is acceptable. * * The callback shall return the parameters for the acceptation or throw an * AssociationRejected exception if the association is not acceptable. */ typedef std::function AssociationAcceptor; /** * @brief Default association acceptor. * * Reverse the calling and called AE titles, accept the first transfer syntax * and the roles of each presentation context, do not check identity, * keep maximum length. */ AssociationParameters default_association_acceptor(AssociationParameters const & input); struct AssociationRejected: public Exception { public: AssociationRejected( unsigned char result, unsigned char source, unsigned char reason, std::string const & message="Association rejected"); unsigned char get_result() const; void set_result(unsigned char value); unsigned char get_source() const; void set_source(unsigned char value); unsigned char get_reason() const; void set_reason(unsigned char value); private: unsigned char _result; unsigned char _source; unsigned char _reason; }; } #endif // _b21e4f11_9337_4612_8152_b59dedc16f18 odil-0.4.1/src/odil/AssociationParameters.cpp000066400000000000000000000323121266460524100211740ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/AssociationParameters.h" #include #include #include #include #include #include "odil/pdu/AAssociateAC.h" #include "odil/pdu/AAssociateRQ.h" #include "odil/Exception.h" #include "odil/uid.h" #include "odil/pdu/ImplementationClassUID.h" #include "odil/pdu/ImplementationVersionName.h" #include "odil/pdu/PresentationContextAC.h" #include "odil/pdu/PresentationContextRQ.h" #include "odil/pdu/RoleSelection.h" namespace odil { AssociationParameters ::AssociationParameters() : _called_ae_title(""), _calling_ae_title(""), _presentation_contexts(), _user_identity({UserIdentity::Type::None, "", ""}), _maximum_length(16384) { // Nothing else. } AssociationParameters ::AssociationParameters(pdu::AAssociateRQ const & pdu) { this->set_called_ae_title(pdu.get_called_ae_title()); this->set_calling_ae_title(pdu.get_calling_ae_title()); auto const user_information = pdu.get_user_information(); // Presentation contexts auto const & pcs_pdu = pdu.get_presentation_contexts(); std::map> roles_map; auto const roles = user_information.get_sub_items(); for(auto const & role: roles) { roles_map[role.get_sop_class_uid()] = std::make_pair( role.get_scu_role_support(), role.get_scp_role_support()); } std::vector pcs_parameters; pcs_parameters.reserve(pcs_pdu.size()); for(auto const & pc_pdu: pcs_pdu) { AssociationParameters::PresentationContext pc_parameters; pc_parameters.id = pc_pdu.get_id(); pc_parameters.abstract_syntax = pc_pdu.get_abstract_syntax(); pc_parameters.transfer_syntaxes = pc_pdu.get_transfer_syntaxes(); auto const it = roles_map.find(pc_pdu.get_abstract_syntax()); pc_parameters.scu_role_support = (it!=roles_map.end())?it->second.first:true; pc_parameters.scp_role_support = (it!=roles_map.end())?it->second.second:false; pcs_parameters.push_back(pc_parameters); } this->set_presentation_contexts(pcs_parameters); // User identity auto const user_identity = user_information.get_sub_items(); if(!user_identity.empty()) { if(user_identity[0].get_type() == 1) { this->set_user_identity_to_username( user_identity[0].get_primary_field()); } else if(user_identity[0].get_type() == 2) { this->set_user_identity_to_username_and_password( user_identity[0].get_primary_field(), user_identity[0].get_secondary_field()); } else if(user_identity[0].get_type() == 3) { this->set_user_identity_to_kerberos( user_identity[0].get_primary_field()); } else if(user_identity[0].get_type() == 4) { this->set_user_identity_to_saml( user_identity[0].get_primary_field()); } } // Maximum length auto const maximum_length = user_information.get_sub_items(); if(!maximum_length.empty()) { this->set_maximum_length(maximum_length[0].get_maximum_length()); } } AssociationParameters ::AssociationParameters( pdu::AAssociateAC const & pdu, AssociationParameters const & request) { // Calling and Called AE titles are not meaningful in A-ASSOCIATE-AC this->set_called_ae_title(request.get_called_ae_title()); this->set_calling_ae_title(request.get_calling_ae_title()); auto const user_information = pdu.get_user_information(); // Presentation contexts auto const & pcs_request = request.get_presentation_contexts(); std::map pcs_request_map; for(auto const & pc: pcs_request) { pcs_request_map[pc.id] = pc; } auto const & pcs_pdu = pdu.get_presentation_contexts(); std::map> roles_map; auto const roles = user_information.get_sub_items(); for(auto const & role: roles) { roles_map[role.get_sop_class_uid()] = std::make_pair( role.get_scu_role_support(), role.get_scp_role_support()); } std::vector pcs_parameters; pcs_parameters.reserve(pcs_pdu.size()); for(auto const & pc_pdu: pcs_pdu) { AssociationParameters::PresentationContext pc_parameters; auto const & pc_request = pcs_request_map.at(pc_pdu.get_id()); pc_parameters.id = pc_pdu.get_id(); pc_parameters.abstract_syntax = pc_request.abstract_syntax; pc_parameters.transfer_syntaxes = { pc_pdu.get_transfer_syntax() }; auto const it = roles_map.find(pc_request.abstract_syntax); pc_parameters.scu_role_support = (it!=roles_map.end())?it->second.first:pc_request.scu_role_support; pc_parameters.scp_role_support = (it!=roles_map.end())?it->second.second:pc_request.scp_role_support; pc_parameters.result = static_cast(pc_pdu.get_result_reason()); pcs_parameters.push_back(pc_parameters); } this->set_presentation_contexts(pcs_parameters); // User identity auto const user_identity = user_information.get_sub_items(); if(!user_identity.empty()) { auto const type = request.get_user_identity().type; if(type == UserIdentity::Type::Kerberos) { this->set_user_identity_to_kerberos( user_identity[0].get_server_response()); } else if(type == UserIdentity::Type::SAML) { this->set_user_identity_to_saml( user_identity[0].get_server_response()); } } // Maximum length auto const maximum_length = user_information.get_sub_items(); if(!maximum_length.empty()) { this->set_maximum_length(maximum_length[0].get_maximum_length()); } } std::string const & AssociationParameters ::get_called_ae_title() const { return this->_called_ae_title; } AssociationParameters & AssociationParameters ::set_called_ae_title(std::string const & value) { if(value.size() > 16) { throw Exception("AE Title must be less than 16 characters"); } this->_called_ae_title = value; return *this; } std::string const & AssociationParameters ::get_calling_ae_title() const { return this->_calling_ae_title; } AssociationParameters & AssociationParameters ::set_calling_ae_title(std::string const & value) { if(value.size() > 16) { throw Exception("AE Title must be less than 16 characters"); } this->_calling_ae_title = value; return *this; } std::vector const & AssociationParameters ::get_presentation_contexts() const { return this->_presentation_contexts; } AssociationParameters & AssociationParameters ::set_presentation_contexts(std::vector const & value) { std::set ids; for(auto const context: value) { auto const id = context.id; if(id%2 == 0) { throw Exception("Presentation Context ID must be odd"); } ids.insert(id); } if(ids.size() != value.size()) { throw Exception("All Presentation Context IDs must be unique"); } this->_presentation_contexts = value; return *this; } AssociationParameters::UserIdentity const & AssociationParameters ::get_user_identity() const { return this->_user_identity; } AssociationParameters & AssociationParameters ::set_user_identity_to_none() { return this->_set_user_identity({UserIdentity::Type::None, "", ""}); } AssociationParameters & AssociationParameters ::set_user_identity_to_username(std::string const & username) { return this->_set_user_identity( {UserIdentity::Type::Username, username, ""}); } AssociationParameters & AssociationParameters ::set_user_identity_to_username_and_password( std::string const & username, std::string const & password) { return this->_set_user_identity( {UserIdentity::Type::UsernameAndPassword, username, password}); } AssociationParameters & AssociationParameters ::set_user_identity_to_kerberos(std::string const & ticket) { return this->_set_user_identity({UserIdentity::Type::Kerberos, ticket, ""}); } AssociationParameters & AssociationParameters ::set_user_identity_to_saml(std::string const & assertion) { return this->_set_user_identity({UserIdentity::Type::SAML, assertion, ""}); } uint32_t AssociationParameters ::get_maximum_length() const { return this->_maximum_length; } AssociationParameters & AssociationParameters ::set_maximum_length(uint32_t value) { this->_maximum_length = value; return *this; } pdu::AAssociateRQ AssociationParameters ::as_a_associate_rq() const { pdu::AAssociateRQ pdu; pdu.set_protocol_version(1); pdu.set_application_context(std::string("1.2.840.10008.3.1.1.1")); pdu.set_called_ae_title(this->get_called_ae_title()); pdu.set_calling_ae_title(this->get_calling_ae_title()); // Presentation contexts { auto const & source = this->get_presentation_contexts(); std::vector destination; destination.reserve(source.size()); for(auto const & source_pc: source) { pdu::PresentationContextRQ const pc( source_pc.id, source_pc.abstract_syntax, source_pc.transfer_syntaxes); destination.push_back(pc); } pdu.set_presentation_contexts(destination); } pdu::UserInformation user_information; user_information.set_sub_items( {this->get_maximum_length()}); user_information.set_sub_items( {implementation_class_uid}); user_information.set_sub_items( {implementation_version_name}); std::vector roles; for(auto const & presentation_context: this->get_presentation_contexts()) { pdu::RoleSelection const role( presentation_context.abstract_syntax, presentation_context.scu_role_support, presentation_context.scp_role_support); roles.push_back(role); } user_information.set_sub_items(roles); auto const & user_identity = this->get_user_identity(); if(user_identity.type != AssociationParameters::UserIdentity::Type::None) { pdu::UserIdentityRQ sub_item; sub_item.set_type(static_cast(user_identity.type)); sub_item.set_primary_field(user_identity.primary_field); sub_item.set_secondary_field(user_identity.secondary_field); // TODO sub_item.set_positive_response_requested(true); user_information.set_sub_items({sub_item}); } pdu.set_user_information(user_information); return pdu; } pdu::AAssociateAC AssociationParameters ::as_a_associate_ac() const { pdu::AAssociateAC pdu; pdu.set_protocol_version(1); pdu.set_application_context(std::string("1.2.840.10008.3.1.1.1")); pdu.set_called_ae_title(this->get_called_ae_title()); pdu.set_calling_ae_title(this->get_calling_ae_title()); // Presentation contexts { auto const & source = this->get_presentation_contexts(); std::vector destination; destination.reserve(source.size()); for(auto const & source_pc: source) { pdu::PresentationContextAC const pc( source_pc.id, source_pc.transfer_syntaxes[0], static_cast(source_pc.result)); destination.push_back(pc); } pdu.set_presentation_contexts(destination); } pdu::UserInformation user_information; user_information.set_sub_items( {this->get_maximum_length()}); user_information.set_sub_items( {implementation_class_uid}); user_information.set_sub_items( {implementation_version_name}); std::vector roles; for(auto const & presentation_context: this->get_presentation_contexts()) { pdu::RoleSelection const role( presentation_context.abstract_syntax, presentation_context.scu_role_support, presentation_context.scp_role_support); roles.push_back(role); } user_information.set_sub_items(roles); pdu.set_user_information(user_information); return pdu; } AssociationParameters & AssociationParameters ::_set_user_identity(UserIdentity const & value) { this->_user_identity = value; return *this; } } odil-0.4.1/src/odil/AssociationParameters.h000066400000000000000000000112461266460524100206440ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _061fafd4_982e_4a7e_9eb0_29e06443ebf3 #define _061fafd4_982e_4a7e_9eb0_29e06443ebf3 #include #include #include #include "odil/pdu/AAssociateAC.h" #include "odil/pdu/AAssociateRQ.h" namespace odil { /// @brief Encapsulate association parameters class AssociationParameters { public: /** * @brief Presentation Context, cf. PS 3.8, 9.3.2.2, PS 3.8, 9.3.3.2, * PS 3.7, D.3.3.4.1 and PS 3.7 D.3.3.4.2. */ struct PresentationContext { enum class Result { Acceptance = 0, UserRejection = 1, NoReason = 2, AbstractSyntaxNotSupported = 3, TransferSyntaxesNotSupported = 4, }; uint8_t id; std::string abstract_syntax; std::vector transfer_syntaxes; bool scu_role_support; bool scp_role_support; Result result; }; /// @brief User Identity, cf. PS3.8 D.3.3.7 struct UserIdentity { enum class Type { None = 0, Username = 1, UsernameAndPassword = 2, Kerberos = 3, SAML = 4 }; Type type; std::string primary_field; std::string secondary_field; }; /// @brief Constructor. AssociationParameters(); /// @brief Constructor from an A-ASSOCIATE-RQ PDU. AssociationParameters(pdu::AAssociateRQ const & pdu); /// @brief Constructor from an A-ASSOCIATE-RQ PDU. AssociationParameters( pdu::AAssociateAC const & pdu, AssociationParameters const & request); /// @brief Return the called AE title, default to empty. std::string const & get_called_ae_title() const; /** * @brief Set the called AE title. * * An exception is raised if the value is empty or if it is longer than * 16 characters. */ AssociationParameters & set_called_ae_title(std::string const & value); /// @brief Return the calling AE title, default to empty. std::string const & get_calling_ae_title() const; /** * @brief Set the calling AE title. * * An exception is raised if the value is empty or if it is longer than * 16 characters. */ AssociationParameters & set_calling_ae_title(std::string const & value); /// @brief Return the presentation contexts, default to empty. std::vector const & get_presentation_contexts() const; /// @brief Set the presentation contexts. All ids must be odd and unique. AssociationParameters & set_presentation_contexts(std::vector const & value); /// @brief Return the user identity, default to None. UserIdentity const & get_user_identity() const; /// @brief Do no authenticate user. AssociationParameters & set_user_identity_to_none(); /// @brief Authenticate user using only a username. AssociationParameters & set_user_identity_to_username(std::string const & username); /// @brief Authenticate user using a username and a password. AssociationParameters & set_user_identity_to_username_and_password( std::string const & username, std::string const & password); /// @brief Authenticate user using a Kerberos ticket. AssociationParameters & set_user_identity_to_kerberos(std::string const & ticket); /// @brief Authenticate user using a SAML assertion. AssociationParameters & set_user_identity_to_saml(std::string const & assertion); /// @brief Return the maximum length of a PDU, default to 16384. uint32_t get_maximum_length() const; /** * @brief Set the maximum length of a PDU, the value 0 meaning * no maximum length. */ AssociationParameters & set_maximum_length(uint32_t value); /// @brief Create an A-ASSOCIATE-RQ PDU. pdu::AAssociateRQ as_a_associate_rq() const; /// @brief Create an A-ASSOCIATE-AC PDU. pdu::AAssociateAC as_a_associate_ac() const; private: std::string _called_ae_title; std::string _calling_ae_title; std::vector _presentation_contexts; UserIdentity _user_identity; uint32_t _maximum_length; /// @brief Set the user identity. AssociationParameters & _set_user_identity(UserIdentity const & value); }; } #endif // _061fafd4_982e_4a7e_9eb0_29e06443ebf3 odil-0.4.1/src/odil/BasicDirectoryCreator.cpp000066400000000000000000000353111266460524100211240ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/BasicDirectoryCreator.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/Reader.h" #include "odil/registry.h" #include "odil/Tag.h" #include "odil/uid.h" namespace odil { std::map> const BasicDirectoryCreator ::default_record_keys = { { "PATIENT", { { registry::PatientName, 2}, { registry::PatientID, 1 } } }, { "STUDY", { { registry::StudyDate, 1 }, { registry::StudyTime, 1 }, { registry::StudyDescription, 2 }, { registry::StudyInstanceUID, 1 }, // only if (0004,1511) is absent (see Note) { registry::StudyID, 1 }, { registry::AccessionNumber, 2 } } }, { "SERIES", { { registry::Modality, 1 }, { registry::SeriesInstanceUID, 1 }, { registry::SeriesNumber, 1 }, //registry::IconImageSequence } }, { "IMAGE", { { registry::InstanceNumber, 1 }, //registry::IconImageSequence } }, }; BasicDirectoryCreator ::BasicDirectoryCreator( std::string const & root, std::vector const & files, RecordKeyMap const & extra_record_keys, Writer::ItemEncoding item_encoding) : root(root), files(files), extra_record_keys(extra_record_keys), item_encoding(item_encoding) { // Nothing else. } void BasicDirectoryCreator ::operator()() const { auto const record_tree = this->_create_records(); auto linearized_tree = this->_linearize_records(record_tree); auto const relative_offsets = this->_get_relative_offsets( linearized_tree.records); this->_write(linearized_tree, relative_offsets); } BasicDirectoryCreator::RecordMap BasicDirectoryCreator ::_create_records() const { RecordMap patients; for(auto const & file: files) { auto const absolute_path = boost::filesystem::path(this->root)/file; if(!boost::filesystem::is_regular_file(absolute_path)) { throw Exception("No such file: "+absolute_path.string()); } boost::filesystem::ifstream stream( absolute_path, std::ifstream::in | std::ifstream::binary); auto const meta_info_and_data_set = Reader::read_file(stream); auto const & data_set = meta_info_and_data_set.second; auto const & patient_id = data_set.as_string( registry::PatientID)[0]; auto & patient = this->_find_record(patients, patient_id); if(patient.data_set.empty()) { this->_fill_record(data_set, patient, "PATIENT"); } auto const & study_instance_uid = data_set.as_string( registry::StudyInstanceUID)[0]; auto & study = this->_find_record(patient.children, study_instance_uid); if(study.data_set.empty()) { this->_fill_record(data_set, study, "STUDY"); } auto const & series_instance_uid = data_set.as_string( registry::SeriesInstanceUID)[0]; auto & series = this->_find_record(study.children, series_instance_uid); if(series.data_set.empty()) { this->_fill_record(data_set, series, "SERIES"); } auto const & sop_instance_uid = data_set.as_string( registry::SOPInstanceUID)[0]; auto & image = this->_find_record(series.children, sop_instance_uid); if(image.data_set.empty()) { this->_fill_record(data_set, image, "IMAGE"); Value::Strings file_id; int begin = 0; while(begin != std::string::npos) { auto const end = file.find('/', begin); auto const size = (end==std::string::npos)?std::string::npos:(end-begin); std::string const item = file.substr(begin, size); file_id.push_back(item); if(end == std::string::npos) { begin = end; } else { begin = end+1; } } // Required if the Directory Record references a SOP Instance (PS3.3 F.3.2.2) image.data_set.add(registry::ReferencedFileID, file_id); image.data_set.add( registry::ReferencedSOPClassUIDInFile, data_set[registry::SOPClassUID]); image.data_set.add( registry::ReferencedSOPInstanceUIDInFile, data_set[registry::SOPInstanceUID]); auto const & meta_info = meta_info_and_data_set.first; image.data_set.add( registry::ReferencedTransferSyntaxUIDInFile, meta_info[registry::TransferSyntaxUID]); } } return patients; } BasicDirectoryCreator::Record & BasicDirectoryCreator ::_find_record(RecordMap & records, std::string const & key) const { auto iterator = records.find(key); if(iterator == records.end()) { iterator = records.insert({key, Record::Pointer(new Record())}).first; } return *(iterator->second); } void BasicDirectoryCreator ::_fill_record( DataSet const & data_set, Record & record, std::string const & type) const { record.data_set.add(registry::DirectoryRecordType, {type}); record.data_set.add(registry::OffsetOfTheNextDirectoryRecord, {0}); record.data_set.add(registry::RecordInUseFlag, {0xffff}); record.data_set.add( registry::OffsetOfReferencedLowerLevelDirectoryEntity, {0}); this->_update_record(data_set, record, this->default_record_keys.at(type)); auto const extra_record_keys_it = this->extra_record_keys.find(type); if(extra_record_keys_it != this->extra_record_keys.end()) { this->_update_record(data_set, record, extra_record_keys_it->second); } } void BasicDirectoryCreator ::_update_record( DataSet const & data_set, Record & record, std::vector const & keys) const { for(auto const & key: keys) { auto const & tag = key.first; auto const & type = key.second; if(data_set.has(tag)) { record.data_set.add(tag, data_set[tag]); } else { if(type == 1) { throw Exception("Type 1 tag missing from data set: "+std::string(tag)); } else if(type == 2) { record.data_set.add(tag); } // Otherwise do nothing. } } // TODO: registry::RecordInUseFlag; } BasicDirectoryCreator::LinearizedTree BasicDirectoryCreator ::_linearize_records(RecordMap const & record_tree) const { LinearizedTree linearized_tree; // Prime the stack with all top-level records. std::stack stack; for(auto const & record: record_tree) { stack.push(record.second); } // Create a depth-first list of records and a sibling map. std::map location_map; std::map sibling_map; while(!stack.empty()) { auto const & record = stack.top(); stack.pop(); linearized_tree.records.push_back(record); location_map[record.get()] = linearized_tree.records.size()-1; auto const & children = record->children; for(auto child_it=children.begin(); child_it!=children.end(); ++child_it) { auto const & child_record = child_it->second; auto const sibling_it = std::next(child_it); if(sibling_it != children.end()) { auto const & sibling = sibling_it->second; sibling_map[child_record.get()] = sibling.get(); } } // Use reverse iterators to keep the relative order of children during // the depth-first search. std::for_each( children.rbegin(), children.rend(), [&] (RecordMap::value_type const & child) { stack.push(child.second); }); } // Update the topological information. linearized_tree.child.resize(location_map.size()); std::fill(linearized_tree.child.begin(), linearized_tree.child.end(), -1); linearized_tree.sibling.resize(location_map.size()); std::fill(linearized_tree.sibling.begin(), linearized_tree.sibling.end(), -1); for(auto const & location_it: location_map) { auto const & record = location_it.first; auto const & location = location_it.second; if(!record->children.empty()) { linearized_tree.child[location] = location_map.at(record->children.begin()->second.get()); } else { linearized_tree.child[location] = -1; } auto const sibling_it = sibling_map.find(record); if(sibling_it != sibling_map.end()) { linearized_tree.sibling[location] = location_map.at(sibling_it->second); } else { linearized_tree.sibling[location] = -1; } } return linearized_tree; } std::vector BasicDirectoryCreator ::_get_relative_offsets(std::vector const & records) const { // Create an in-memory stream to compute the position of the start of the // records std::ostringstream stream; // PS3.10, 8.6: The DICOMDIR File shall use the Explicit VR Little Endian // Transfer Syntax Writer const writer( stream, registry::ExplicitVRLittleEndian, this->item_encoding); std::vector relative_offsets; std::streampos offset = 0; for(auto const & record: records) { relative_offsets.push_back(stream.tellp()+offset); // Item tag: 4 bytes // Item length: 4 bytes offset += 8; writer.write_data_set(record->data_set); if(this->item_encoding == Writer::ItemEncoding::UndefinedLength) { // Item Delimitation Item tag: 4 bytes // Item Delimitation Item length: 4 bytes offset += 8; } } return relative_offsets; } void BasicDirectoryCreator ::_write( LinearizedTree const & linearized_tree, std::vector const & relative_offsets) const { DataSet meta_information; meta_information.add( registry::FileMetaInformationVersion, Value::Binary({0x00, 0x01})); meta_information.add( registry::MediaStorageSOPClassUID, { registry::MediaStorageDirectoryStorage }); meta_information.add( registry::MediaStorageSOPInstanceUID, { generate_uid() }); meta_information.add( registry::TransferSyntaxUID, { registry::ExplicitVRLittleEndian }); meta_information.add( registry::ImplementationClassUID, { implementation_class_uid }); meta_information.add( registry::ImplementationVersionName, { implementation_version_name }); DataSet basic_directory; // File-Set Identification Module (PS3.3 F.3.2.1) basic_directory.add(registry::FileSetID, { "" }); // Don't include user comments yet. // registry::FileSetDescriptorFileID; // registry::SpecificCharacterSetOfFileSetDescriptorFile; // Directory Information Module (PS3.3 F.3.2.2) basic_directory.add( registry::OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity, { 0 }); basic_directory.add( registry::OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity, { 0 }); basic_directory.add(registry::FileSetConsistencyFlag, { 0 }); std::ostringstream buffer; Writer buffer_writer( buffer, meta_information.as_string(registry::TransferSyntaxUID)[0], this->item_encoding); buffer_writer.write_data_set(meta_information); buffer_writer.write_data_set(basic_directory); // Preamble + prefix + data + Directory Record Sequence (tag + VR + reserved + VL) auto const start_of_directory_records = 128+4+buffer.tellp()+4+2+2+4; std::vector absolute_offsets(relative_offsets.size()); std::transform( relative_offsets.begin(), relative_offsets.end(), absolute_offsets.begin(), [&](std::streampos offset) { return offset+start_of_directory_records; }); basic_directory.as_int( registry::OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity)[0] = *(absolute_offsets.begin()); int last_top_level = 0; while(linearized_tree.sibling[last_top_level] != -1) { last_top_level = linearized_tree.sibling[last_top_level]; } basic_directory.as_int( registry::OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity)[0] = absolute_offsets[last_top_level]; Value::DataSets record_sequence; for(int record_index=0; record_indexdata_set; auto const sibling = linearized_tree.sibling[record_index]; if(sibling != -1) { item.as_int( registry::OffsetOfTheNextDirectoryRecord)[0] = absolute_offsets[sibling]; } auto const child = linearized_tree.child[record_index]; if(child != -1) { item.as_int( registry::OffsetOfReferencedLowerLevelDirectoryEntity)[0] = absolute_offsets[child]; } record_sequence.push_back(item); } basic_directory.add(registry::DirectoryRecordSequence, record_sequence); boost::filesystem::ofstream file( boost::filesystem::path(root)/"DICOMDIR", std::ofstream::out | std::ofstream::binary); Writer file_writer( file, buffer_writer.byte_ordering, buffer_writer.explicit_vr, buffer_writer.item_encoding, buffer_writer.use_group_length); // File preamble for(unsigned int i=0; i<128; ++i) { file.put(0); if(!file) { throw Exception("Could not write to stream"); } } // DICOM prefix std::string const prefix("DICM"); file.write(&prefix[0], prefix.size()); if(!file) { throw Exception("Could not write to stream"); } file_writer.write_data_set(meta_information); file_writer.write_data_set(basic_directory); } } odil-0.4.1/src/odil/BasicDirectoryCreator.h000066400000000000000000000071711266460524100205740ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _8836a563_24f6_4afb_89ba_377d49ce9f5d #define _8836a563_24f6_4afb_89ba_377d49ce9f5d #include #include #include #include #include #include "odil/DataSet.h" #include "odil/Tag.h" #include "odil/Writer.h" namespace odil { /// @brief Write a Basic Directory (i.e. DICOMDIR) object to the disk. class BasicDirectoryCreator { public: /// @brief The tag and its associated type in the record. typedef std::pair RecordKey; /// @brief Map from a record type to the extra keys. typedef std::map> RecordKeyMap; /// @brief Default record keys, classified by record type. static RecordKeyMap const default_record_keys; /** * @brief Root of the DICOM files and location of the output DICOMDIR file. * * The concatenation of root and each file, as well as of root and * "DICOMDIR" must be a valid path. */ std::string root; /** * @brief Path to the DICOM files, relative to root. * * The concatenation of root and each file must be a valid path. */ std::vector files; /// @brief User-defined record keys, classified by record type. RecordKeyMap extra_record_keys; /// @brief Encoding of sequence items, defaults to Writer::ItemEncoding::ExplicitLength. Writer::ItemEncoding item_encoding; BasicDirectoryCreator( std::string const & root="", std::vector const & files=std::vector(), RecordKeyMap const & extra_record_keys=RecordKeyMap(), Writer::ItemEncoding item_encoding=Writer::ItemEncoding::ExplicitLength ); void operator()() const; private: struct Record { typedef std::shared_ptr Pointer; DataSet data_set; std::map children; }; struct LinearizedTree { std::vector records; std::vector sibling; std::vector child; }; typedef std::map RecordMap; /// @brief Create a hierarchy of records from the files. std::map _create_records() const; /// @brief Find a given record or insert a new one and return it. Record & _find_record(RecordMap & records, std::string const & key) const; /// @brief Create a default record. void _fill_record( DataSet const & data_set, Record & record, std::string const & type) const; /// @brief Update the record content from a data set. void _update_record( DataSet const & data_set, Record & record, std::vector const & keys) const; /// @brief Return a linearized version of the record hierarchy. LinearizedTree _linearize_records(RecordMap const & record_tree) const; /// @brief Compute the offsets of the records relative to the first record. std::vector _get_relative_offsets( std::vector const & records) const; /// @brief Write the DICOMDIR. void _write( LinearizedTree const & linearized_tree, std::vector const & relative_offsets) const; }; } #endif // _8836a563_24f6_4afb_89ba_377d49ce9f5d odil-0.4.1/src/odil/DataSet.cpp000066400000000000000000000120251266460524100162200ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/DataSet.h" #include #include #include #include #include #include "odil/Exception.h" #include "odil/Tag.h" #include "odil/VR.h" namespace odil { DataSet ::DataSet() { // Nothing to do. } void DataSet ::add(Tag const & tag, Element const & element) { this->_elements[tag] = element; } void DataSet ::add(Tag const & tag, VR vr) { Value value; if(vr == VR::UNKNOWN) { vr = as_vr(tag); } if(::odil::is_int(vr)) { value = Value::Integers(); } else if(::odil::is_real(vr)) { value = Value::Reals(); } else if(::odil::is_string(vr)) { value = Value::Strings(); } else if(::odil::is_binary(vr)) { value = Value::Binary(); } else if(vr == VR::SQ) { value = Value::DataSets(); } else { throw Exception("Unknown VR: "+::odil::as_string(vr)); } this->add(tag, Element(value, vr)); } void DataSet ::add(Tag const & tag, Value::Integers const & value, VR vr) { if(vr == VR::UNKNOWN) { vr = as_vr(tag); } this->add(tag, Element(value, vr)); } void DataSet ::add(Tag const & tag, Value::Reals const & value, VR vr) { if(vr == VR::UNKNOWN) { vr = as_vr(tag); } this->add(tag, Element(value, vr)); } void DataSet ::add(Tag const & tag, Value::Strings const & value, VR vr) { if(vr == VR::UNKNOWN) { vr = as_vr(tag); } this->add(tag, Element(value, vr)); } void DataSet ::add(Tag const & tag, Value::DataSets const & value, VR vr) { if(vr == VR::UNKNOWN) { vr = as_vr(tag); } this->add(tag, Element(value, vr)); } void DataSet ::add(Tag const & tag, Value::Binary const & value, VR vr) { if(vr == VR::UNKNOWN) { vr = as_vr(tag); } this->add(tag, Element(value, vr)); } void DataSet ::add(Tag const & tag, std::initializer_list const & value, VR vr) { if(vr == VR::UNKNOWN) { vr = as_vr(tag); } this->add(tag, Element(value, vr)); } void DataSet ::add( Tag const & tag, std::initializer_list const & value, VR vr) { if(vr == VR::UNKNOWN) { vr = as_vr(tag); } this->add(tag, Element(value, vr)); } void DataSet ::add( Tag const & tag, std::initializer_list const & value, VR vr) { if(vr == VR::UNKNOWN) { vr = as_vr(tag); } this->add(tag, Element(value, vr)); } void DataSet ::add( Tag const & tag, std::initializer_list const & value, VR vr) { if(vr == VR::UNKNOWN) { vr = as_vr(tag); } this->add(tag, Element(value, vr)); } void DataSet ::add( Tag const & tag, std::initializer_list const & value, VR vr) { if(vr == VR::UNKNOWN) { vr = as_vr(tag); } this->add(tag, Element(value, vr)); } void DataSet ::remove(Tag const & tag) { if(!this->has(tag)) { throw Exception("No such element"); } this->_elements.erase(tag); } bool DataSet ::empty() const { return this->_elements.empty(); } std::size_t DataSet ::size() const { return this->_elements.size(); } Element const & DataSet ::operator[](Tag const & tag) const { ElementMap::const_iterator const it = this->_elements.find(tag); if(it == this->_elements.end()) { throw Exception("No such element"); } return it->second; } Element & DataSet ::operator[](Tag const & tag) { ElementMap::iterator it = this->_elements.find(tag); if(it == this->_elements.end()) { throw Exception("No such element"); } return it->second; } bool DataSet ::has(Tag const & tag) const { return (this->_elements.find(tag) != this->_elements.end()); } VR DataSet ::get_vr(Tag const & tag) const { ElementMap::const_iterator const it = this->_elements.find(tag); if(it == this->_elements.end()) { throw Exception("No such element"); } return it->second.vr; } bool DataSet ::empty(Tag const & tag) const { ElementMap::const_iterator const it = this->_elements.find(tag); if(it == this->_elements.end()) { throw Exception("No such element"); } return it->second.empty(); } std::size_t DataSet ::size(Tag const & tag) const { ElementMap::const_iterator const it = this->_elements.find(tag); if(it == this->_elements.end()) { throw Exception("No such element"); } return it->second.size(); } bool DataSet ::operator==(DataSet const & other) const { return (this->_elements == other._elements); } bool DataSet ::operator!=(DataSet const & other) const { return !(*this == other); } } odil-0.4.1/src/odil/DataSet.h000066400000000000000000000130671266460524100156740ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _8424446e_1153_4acc_9f57_e86faa7246e3 #define _8424446e_1153_4acc_9f57_e86faa7246e3 #include #include #include #include #include #include #include "odil/Element.h" #include "odil/Value.h" namespace odil { #define odilElementTypeMacro(name, Type) \ bool is_##name(Tag const & tag) const \ { \ auto const it = this->_elements.find(tag); \ if(it == this->_elements.end()) \ { \ throw Exception("No such element"); \ } \ return it->second.is_##name(); \ } \ Value::Type const & as_##name(Tag const & tag) const \ { \ auto const it = this->_elements.find(tag); \ if(it == this->_elements.end()) \ { \ throw Exception("No such element"); \ } \ return it->second.as_##name(); \ } \ Value::Type::value_type const & as_##name(Tag const & tag, unsigned int position) const \ { \ auto const & data = this->as_##name(tag); \ if(data.size() <= position) \ { \ throw Exception("No such element"); \ } \ return data[position]; \ } \ Value::Type & as_##name(Tag const & tag) \ { \ auto const it = this->_elements.find(tag); \ if(it == this->_elements.end()) \ { \ throw Exception("No such element"); \ } \ return it->second.as_##name(); \ } /** * @brief DICOM Data set. */ class DataSet { public: /// @brief Create an empty data set. DataSet(); /// @brief Add an element to the dataset. void add(Tag const & tag, Element const & element); /// @brief Add an empty element to the dataset. void add(Tag const & tag, VR vr=VR::UNKNOWN); /// @brief Add an element to the dataset. void add( Tag const & tag, Value::Integers const & value, VR vr=VR::UNKNOWN); /// @brief Add an element to the dataset. void add( Tag const & tag, Value::Reals const & value, VR vr=VR::UNKNOWN); /// @brief Add an element to the dataset. void add( Tag const & tag, Value::Strings const & value, VR vr=VR::UNKNOWN); /// @brief Add an element to the dataset. void add( Tag const & tag, Value::DataSets const & value, VR vr=VR::UNKNOWN); /// @brief Add an element to the dataset. void add( Tag const & tag, Value::Binary const & value, VR vr=VR::UNKNOWN); /// @brief Add an element to the dataset. void add( Tag const & tag, std::initializer_list const & value, VR vr=VR::UNKNOWN); /// @brief Add an element to the dataset. void add( Tag const & tag, std::initializer_list const & value, VR vr=VR::UNKNOWN); /// @brief Add an element to the dataset. void add( Tag const & tag, std::initializer_list const & value, VR vr=VR::UNKNOWN); /// @brief Add an element to the dataset. void add( Tag const & tag, std::initializer_list const & value, VR vr=VR::UNKNOWN); /// @brief Add an element to the dataset. void add( Tag const & tag, std::initializer_list const & value, VR vr=VR::UNKNOWN); /** * @brief Remove an element from the data set. * * If the element is not in the data set, a odil::Exception is raised. */ void remove(Tag const & tag); /// @brief Test whether the data set is empty. bool empty() const; /// @brief Return the number of elements in the data set. std::size_t size() const; /// @brief Test whether an element is in the data set. bool has(Tag const & tag) const; /** * @brief Return the VR of an element in the data set. * * If the element is not in the data set, a odil::Exception is raised. */ VR get_vr(Tag const & tag) const; /** * @brief Test whether an element of the data set is empty. * * If the element is not in the data set, a odil::Exception is raised. */ bool empty(Tag const & tag) const; /** * @brief Return the number of values in an element of the data set. * * If the element is not in the data set, a odil::Exception is raised. */ std::size_t size(Tag const & tag) const; /** * @brief Access the given element. * * If the element is not in the data set, a odil::Exception is raised. */ Element const & operator[](Tag const & tag) const; /** * @brief Access the given element. * * If the element is not in the data set, a odil::Exception is raised. */ Element & operator[](Tag const & tag); odilElementTypeMacro(int, Integers); odilElementTypeMacro(real, Reals); odilElementTypeMacro(string, Strings); odilElementTypeMacro(data_set, DataSets); odilElementTypeMacro(binary, Binary); typedef std::map::const_iterator const_iterator; const_iterator begin() const { return this->_elements.begin(); } const_iterator end() const { return this->_elements.end(); } /// @brief Equality test bool operator==(DataSet const & other) const; /// @brief Difference test bool operator!=(DataSet const & other) const; private: typedef std::map ElementMap; ElementMap _elements; }; } #endif // _8424446e_1153_4acc_9f57_e86faa7246e3 odil-0.4.1/src/odil/EchoSCP.cpp000066400000000000000000000033631266460524100161240ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/EchoSCP.h" #include #include "odil/Association.h" #include "odil/SCP.h" #include "odil/Value.h" #include "odil/message/CEchoRequest.h" #include "odil/message/CEchoResponse.h" #include "odil/message/Message.h" namespace odil { EchoSCP ::EchoSCP(Association & association) : SCP(association), _callback() { // Nothing else. } EchoSCP ::EchoSCP(Association & association, Callback const & callback) : SCP(association), _callback() { this->set_callback(callback); } EchoSCP ::~EchoSCP() { // Nothing to do. } EchoSCP::Callback const & EchoSCP::get_callback() const { return this->_callback; } void EchoSCP ::set_callback(Callback const & callback) { this->_callback = callback; } void EchoSCP ::operator()(message::Message const & message) { message::CEchoRequest const request(message); Value::Integer status=message::CEchoResponse::Success; try { status = this->_callback(request); } catch(Exception const &) { status = message::CEchoResponse::ProcessingFailure; // Error Comment // Error ID // Affected SOP Class UID } message::CEchoResponse const response( request.get_message_id(), status, request.get_affected_sop_class_uid()); this->_association.send_message( response, request.get_affected_sop_class_uid()); } } odil-0.4.1/src/odil/EchoSCP.h000066400000000000000000000027071266460524100155720ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _1a61d976_ba12_4dba_af34_67f064d38506 #define _1a61d976_ba12_4dba_af34_67f064d38506 #include #include "odil/Association.h" #include "odil/SCP.h" #include "odil/Value.h" #include "odil/message/CEchoRequest.h" #include "odil/message/Message.h" namespace odil { /// @brief SCP for C-Echo services. class EchoSCP: public SCP { public: /// @brief Callback called when a request is received. typedef std::function Callback; /// @brief Constructor. EchoSCP(Association & association); /// @brief Constructor. EchoSCP(Association & association, Callback const & callback); /// @brief Destructor. virtual ~EchoSCP(); /// @brief Return the callback. Callback const & get_callback() const; /// @brief Set the callback. void set_callback(Callback const & callback); /// @brief Process a C-Echo request. virtual void operator()(message::Message const & message); private: Callback _callback; }; } #endif // _1a61d976_ba12_4dba_af34_67f064d38506 odil-0.4.1/src/odil/Element.cpp000066400000000000000000000073131266460524100162700ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/Element.h" #include "odil/Value.h" #include "odil/DataSet.h" namespace odil { Element ::Element(Value const & value, VR const & vr) : _value(value), vr(vr) { // Nothing else } Element ::Element(Value::Integers const & value, VR const & vr) : _value(value), vr(vr) { // Nothing else } Element ::Element(Value::Reals const & value, VR const & vr) : _value(value), vr(vr) { // Nothing else } Element ::Element(Value::Strings const & value, VR const & vr) : _value(value), vr(vr) { // Nothing else } Element ::Element(Value::DataSets const & value, VR const & vr) : _value(value), vr(vr) { // Nothing else } Element ::Element(Value::Binary const & value, VR const & vr) : _value(value), vr(vr) { // Nothing else } Element ::Element(std::initializer_list const & value, VR const & vr) : _value(value), vr(vr) { // Nothing else } Element ::Element(std::initializer_list const & value, VR const & vr) : _value(value), vr(vr) { // Nothing else } Element ::Element(std::initializer_list const & value, VR const & vr) : _value(value), vr(vr) { // Nothing else } Element ::Element(std::initializer_list const & value, VR const & vr) : _value(value), vr(vr) { // Nothing else } Element ::Element(std::initializer_list const & value, VR const & vr) : _value(value), vr(vr) { // Nothing else } bool Element ::empty() const { return ( (this->_value.get_type() == Value::Type::Empty) || apply_visitor(Empty(), this->_value)); } std::size_t Element ::size() const { return ( (this->_value.get_type() == Value::Type::Empty)?0: apply_visitor(Size(), this->_value)); } Value const & Element ::get_value() const { return this->_value; } bool Element ::is_int() const { return (this->_value.get_type() == Value::Type::Integers); } Value::Integers const & Element ::as_int() const { return this->_value.as_integers(); } Value::Integers & Element ::as_int() { return this->_value.as_integers(); } bool Element ::is_real() const { return (this->_value.get_type() == Value::Type::Reals); } Value::Reals const & Element ::as_real() const { return this->_value.as_reals(); } Value::Reals & Element ::as_real() { return this->_value.as_reals(); } bool Element ::is_string() const { return (this->_value.get_type() == Value::Type::Strings); } Value::Strings const & Element ::as_string() const { return this->_value.as_strings(); } Value::Strings & Element ::as_string() { return this->_value.as_strings(); } bool Element ::is_data_set() const { return (this->_value.get_type() == Value::Type::DataSets); } Value::DataSets const & Element ::as_data_set() const { return this->_value.as_data_sets(); } Value::DataSets & Element::as_data_set() { return this->_value.as_data_sets(); } bool Element ::is_binary() const { return (this->_value.get_type() == Value::Type::Binary); } Value::Binary const & Element ::as_binary() const { return this->_value.as_binary(); } Value::Binary & Element::as_binary() { return this->_value.as_binary(); } bool Element ::operator==(Element const & other) const { return (this->vr == other.vr) && (this->_value == other._value); } bool Element ::operator!=(Element const & other) const { return !(*this == other); } } odil-0.4.1/src/odil/Element.h000066400000000000000000000126011266460524100157310ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _9c3d8f32_0310_4e3a_b5d2_6d69f229a2cf #define _9c3d8f32_0310_4e3a_b5d2_6d69f229a2cf #include #include #include "odil/Tag.h" #include "odil/Value.h" #include "odil/VR.h" namespace odil { /** * @brief Element of a DICOM data set. */ class Element { public: /// @brief VR of the element. VR vr; /// @brief Constructor. Element(Value const & value=Value(), VR const & vr=VR::INVALID); /// @brief Constructor. Element(Value::Integers const & value, VR const & vr=VR::INVALID); /// @brief Constructor. Element(Value::Reals const & value, VR const & vr=VR::INVALID); /// @brief Constructor. Element(Value::Strings const & value, VR const & vr=VR::INVALID); /// @brief Constructor. Element(Value::DataSets const & value, VR const & vr=VR::INVALID); /// @brief Constructor. Element(Value::Binary const & value, VR const & vr=VR::INVALID); /// @brief Constructor. Element( std::initializer_list const & value, VR const & vr=VR::INVALID); /// @brief Constructor. Element( std::initializer_list const & value, VR const & vr=VR::INVALID); /// @brief Constructor. Element( std::initializer_list const & value, VR const & vr=VR::INVALID); /// @brief Constructor. Element( std::initializer_list const & value, VR const & vr=VR::INVALID); /// @brief Constructor. Element( std::initializer_list const & value, VR const & vr=VR::INVALID); /// @brief Test whether the element is empty. bool empty() const; /// @brief Return the number of items in the value. std::size_t size() const; Value const & get_value() const; /// @brief Test whether the value contains integers. bool is_int() const; /** * @brief Return the integers contained in the element. * * If the element does not contain integers, a odil::Exception is raised. */ Value::Integers const & as_int() const; /** * @brief Return the integers contained in the element. * * If the element does not contain integers, a odil::Exception is raised. */ Value::Integers & as_int(); /// @brief Test whether the value contains reals. bool is_real() const; /** * @brief Return the reals contained in the element. * * If the element does not contain reals, a odil::Exception is raised. */ Value::Reals const & as_real() const; /** * @brief Return the reals contained in the element. * * If the element does not contain reals, a odil::Exception is raised. */ Value::Reals & as_real(); /// @brief Test whether the value contains strings. bool is_string() const; /** * @brief Return the strings contained in the element. * * If the element does not contain strings, a odil::Exception is raised. */ Value::Strings const & as_string() const; /** * @brief Return the strings contained in the element. * * If the element does not contain strings, a odil::Exception is raised. */ Value::Strings & as_string(); /// @brief Test whether the value contains data sets. bool is_data_set() const; /** * @brief Return the data sets contained in the element. * * If the element does not contain data sets, a odil::Exception is raised. */ Value::DataSets const & as_data_set() const; /** * @brief Return the data sets contained in the element. * * If the element does not contain data sets, a odil::Exception is raised. */ Value::DataSets & as_data_set(); /// @brief Test whether the value contains data sets. bool is_binary() const; /** * @brief Return the binary data contained in the element. * * If the element does not contain binary data, a odil::Exception is raised. */ Value::Binary const & as_binary() const; /** * @brief Return the binary data contained in the element. * * If the element does not contain binary data, a odil::Exception is raised. */ Value::Binary & as_binary(); /// @brief Equality test bool operator==(Element const & other) const; /// @brief Difference test bool operator!=(Element const & other) const; private: struct Empty { typedef bool result_type; template bool operator()(T const & container) const { return container.empty(); } }; struct Size { typedef std::size_t result_type; template std::size_t operator()(T const & container) const { return container.size(); } }; Value _value; }; /** * @brief Visitor of elements. */ template typename TVisitor::result_type apply_visitor(TVisitor const & visitor, Element const & element); } #include "odil/Element.txx" #endif // _9c3d8f32_0310_4e3a_b5d2_6d69f229a2cf odil-0.4.1/src/odil/Element.txx000066400000000000000000000026371266460524100163350ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _feb2071a_de26_4adb_9305_59d0dd64c970 #define _feb2071a_de26_4adb_9305_59d0dd64c970 #include "odil/Element.h" #include #include "odil/Exception.h" namespace odil { template typename TVisitor::result_type apply_visitor(TVisitor const & visitor, Element const & element) { if(element.empty()) { return visitor(element.vr); } else if(is_string(element.vr)) { return visitor(element.vr, element.as_string()); } else if(is_real(element.vr)) { return visitor(element.vr, element.as_real()); } else if(is_int(element.vr)) { return visitor(element.vr, element.as_int()); } else if(element.vr == VR::SQ) { return visitor(element.vr, element.as_data_set()); } else if(is_binary(element.vr)) { return visitor(element.vr, element.as_binary()); } else { throw Exception("Unknown VR: "+as_string(element.vr)); } } } #endif // _feb2071a_de26_4adb_9305_59d0dd64c970 odil-0.4.1/src/odil/ElementsDictionary.cpp000066400000000000000000000013151266460524100204750ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/ElementsDictionary.h" #include namespace odil { ElementsDictionaryEntry ::ElementsDictionaryEntry( std::string const & name, std::string const & keyword, std::string const & vr, std::string const & vm) : name(name), keyword(keyword), vr(vr), vm(vm) { // Nothing else } } odil-0.4.1/src/odil/ElementsDictionary.h000066400000000000000000000020021266460524100201340ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _f4b88e07_d515_41be_ad1b_37899ec6451e #define _f4b88e07_d515_41be_ad1b_37899ec6451e #include #include #include namespace odil { /** * @brief Entry in a dictionary of DICOM elements. */ struct ElementsDictionaryEntry { std::string name; std::string keyword; std::string vr; std::string vm; ElementsDictionaryEntry( std::string const & name, std::string const & keyword, std::string const & vr, std::string const & vm); }; typedef std::map ElementsDictionary; } #endif // _f4b88e07_d515_41be_ad1b_37899ec6451e odil-0.4.1/src/odil/Exception.cpp000066400000000000000000000013421266460524100166310ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/Exception.h" #include #include namespace odil { Exception ::Exception(std::string const & message) : _message(message) { // Nothing else. } Exception ::~Exception() throw() { // Nothing to do. } char const * Exception ::what() const throw() { return this->_message.c_str(); } } odil-0.4.1/src/odil/Exception.h000066400000000000000000000017461266460524100163060ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _b9607695_cb3b_4188_8caa_bc8bb051ef28 #define _b9607695_cb3b_4188_8caa_bc8bb051ef28 #include #include namespace odil { /// @brief Base class for odil exceptions. class Exception: public std::exception { public: /// @brief Message string constructor. Exception(std::string const & message=""); /// @brief Destructor. virtual ~Exception() throw(); /// @brief Return the reason for the exception. virtual const char* what() const throw(); protected: std::string _message; }; } #endif // _b9607695_cb3b_4188_8caa_bc8bb051ef28 odil-0.4.1/src/odil/FindSCP.cpp000066400000000000000000000044161266460524100161260ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/FindSCP.h" #include #include "odil/Association.h" #include "odil/Exception.h" #include "odil/SCP.h" #include "odil/message/CFindRequest.h" #include "odil/message/CFindResponse.h" #include "odil/message/Response.h" namespace odil { FindSCP ::FindSCP(Association & association) : SCP(association), _generator(nullptr) { // Nothing else. } FindSCP ::FindSCP( Association & association, std::shared_ptr const & generator) : SCP(association), _generator(nullptr) { this->set_generator(generator); } FindSCP ::~FindSCP() { // Nothing to do. } SCP::DataSetGenerator const & FindSCP ::get_generator() const { return *this->_generator; } void FindSCP ::set_generator(std::shared_ptr const & generator) { this->_generator = generator; } void FindSCP ::operator()(message::Message const & message) { message::CFindRequest const request(message); try { this->_generator->initialize(request); while(!this->_generator->done()) { auto const data_set = this->_generator->get(); message::CFindResponse const response( request.get_message_id(), message::CFindResponse::Pending, data_set); this->_association.send_message( response, request.get_affected_sop_class_uid()); this->_generator->next(); } } catch(Exception const & e) { message::CFindResponse response( request.get_message_id(), message::CFindResponse::UnableToProcess); this->_association.send_message( response, request.get_affected_sop_class_uid()); return; } message::CFindResponse response( request.get_message_id(), message::CFindResponse::Success); this->_association.send_message( response, request.get_affected_sop_class_uid()); } } odil-0.4.1/src/odil/FindSCP.h000066400000000000000000000025411266460524100155700ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _d54d5d3d_791c_43e5_b13a_397954053963 #define _d54d5d3d_791c_43e5_b13a_397954053963 #include #include "odil/Association.h" #include "odil/SCP.h" #include "odil/message/Message.h" namespace odil { /// @brief SCP for C-Find services. class FindSCP: public SCP { public: /// @brief Constructor. FindSCP(Association & association); /// @brief Constructor. FindSCP( Association & association, std::shared_ptr const & generator); /// @brief Destructor. virtual ~FindSCP(); /// @brief Return the generator. DataSetGenerator const & get_generator() const; /// @brief Set the generator. void set_generator(std::shared_ptr const & generator); /// @brief Process a C-Find request. virtual void operator()(message::Message const & message); private: std::shared_ptr _generator; }; } #endif // _d54d5d3d_791c_43e5_b13a_397954053963 odil-0.4.1/src/odil/FindSCU.cpp000066400000000000000000000050271266460524100161320ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/FindSCU.h" #include #include #include #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/message/CFindRequest.h" #include "odil/message/CFindResponse.h" namespace odil { FindSCU ::FindSCU(Association & asociation) : SCU(asociation) { // Nothing else. } FindSCU ::~FindSCU() { // Nothing to do } void FindSCU ::find(DataSet const & query, Callback callback) const { message::CFindRequest request( this->_association.next_message_id(), this->_affected_sop_class, message::Message::Priority::MEDIUM, query); this->_association.send_message(request, this->_affected_sop_class); // Receive the responses bool done = false; while(!done) { // FIXME: include progress callback message::CFindResponse const response = this->_association.receive_message(); if(response.get_message_id_being_responded_to() != request.get_message_id()) { std::ostringstream message; message << "DIMSE: Unexpected Response MsgId: " << response.get_message_id_being_responded_to() << "(expected: " << request.get_message_id() << ")"; throw Exception(message.str()); } if(response.has_affected_sop_class_uid() && response.get_affected_sop_class_uid() != request.get_affected_sop_class_uid()) { std::ostringstream message; message << "DIMSE: Unexpected Response Affected SOP Class UID: " << response.get_affected_sop_class_uid() << " (expected: " << request.get_affected_sop_class_uid() << ")"; throw Exception(message.str()); } done = !response.is_pending(); if(!done) { callback(response.get_data_set()); } } } std::vector FindSCU ::find(DataSet const & query) const { std::vector result; auto callback = [&result](DataSet const & dataset) { result.push_back(dataset); }; this->find(query, callback); return result; } } odil-0.4.1/src/odil/FindSCU.h000066400000000000000000000024231266460524100155740ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _0106eb3a_4e02_4d7c_93bf_4d53dcafbb05 #define _0106eb3a_4e02_4d7c_93bf_4d53dcafbb05 #include #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/SCU.h" namespace odil { /// @brief SCU for C-FIND services. class FindSCU: public SCU { public: /// @brief Callback called when a response is received. typedef std::function Callback; FindSCU(Association & association); /// @brief Destructor. virtual ~FindSCU(); /// @brief Perform the C-FIND using an optional callback. void find(DataSet const & query, Callback callback) const; /** * @brief Return a list of datasets matching the query. The user is * responsible for the de-allocation of the matches. */ std::vector find(DataSet const & query) const; }; } #endif // _0106eb3a_4e02_4d7c_93bf_4d53dcafbb05 odil-0.4.1/src/odil/GetSCP.cpp000066400000000000000000000077131266460524100157700ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/GetSCP.h" #include #include "odil/Association.h" #include "odil/Exception.h" #include "odil/SCP.h" #include "odil/StoreSCU.h" #include "odil/message/CGetRequest.h" #include "odil/message/CGetResponse.h" #include "odil/message/Response.h" namespace odil { GetSCP ::GetSCP(Association & association) : SCP(association), _generator(nullptr) { // Nothing else. } GetSCP ::GetSCP( Association & association, std::shared_ptr const & generator) : SCP(association), _generator(nullptr) { this->set_generator(generator); } GetSCP ::~GetSCP() { // Nothing to do. } GetSCP::DataSetGenerator const & GetSCP ::get_generator() const { return *this->_generator; } void GetSCP ::set_generator(std::shared_ptr const & generator) { this->_generator = generator; } void GetSCP ::operator()(message::Message const & message) { message::CGetRequest const request(message); StoreSCU store_scu(this->_association); unsigned int remaining_sub_operations = 0; unsigned int completed_sub_operations=0; unsigned int failed_sub_operations=0; unsigned int warning_sub_operations=0; try { this->_generator->initialize(request); remaining_sub_operations = this->_generator->count(); while(!this->_generator->done()) { message::CGetResponse response( request.get_message_id(), message::CGetResponse::Pending); response.set_number_of_remaining_sub_operations( remaining_sub_operations); response.set_number_of_completed_sub_operations( completed_sub_operations); response.set_number_of_failed_sub_operations( failed_sub_operations); response.set_number_of_warning_sub_operations( warning_sub_operations); this->_association.send_message( response, request.get_affected_sop_class_uid()); auto const data_set = this->_generator->get(); store_scu.set_affected_sop_class(data_set); try { store_scu.store(data_set); --remaining_sub_operations; ++completed_sub_operations; } catch(Exception const &) { ++failed_sub_operations; } this->_generator->next(); } } catch(Exception const &) { message::CGetResponse response( request.get_message_id(), message::CGetResponse::UnableToProcess); response.set_number_of_remaining_sub_operations( remaining_sub_operations); response.set_number_of_completed_sub_operations( completed_sub_operations); response.set_number_of_failed_sub_operations( failed_sub_operations); response.set_number_of_warning_sub_operations( warning_sub_operations); this->_association.send_message( response, request.get_affected_sop_class_uid()); return; } message::CGetResponse response( request.get_message_id(), message::CGetResponse::Success); response.set_number_of_remaining_sub_operations( remaining_sub_operations); response.set_number_of_completed_sub_operations( completed_sub_operations); response.set_number_of_failed_sub_operations( failed_sub_operations); response.set_number_of_warning_sub_operations( warning_sub_operations); this->_association.send_message( response, request.get_affected_sop_class_uid()); } } odil-0.4.1/src/odil/GetSCP.h000066400000000000000000000027361266460524100154350ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _2f0ad1fd_8779_4ab3_b7e8_6d37fdc0c018 #define _2f0ad1fd_8779_4ab3_b7e8_6d37fdc0c018 #include #include "odil/Association.h" #include "odil/SCP.h" #include "odil/message/Message.h" namespace odil { /// @brief SCP for C-Get services. class GetSCP: public SCP { public: class DataSetGenerator: public SCP::DataSetGenerator { public: virtual unsigned int count() const =0; }; /// @brief Constructor. GetSCP(Association & association); /// @brief Constructor. GetSCP( Association & association, std::shared_ptr const & generator); /// @brief Destructor. virtual ~GetSCP(); /// @brief Return the generator. DataSetGenerator const & get_generator() const; /// @brief Set the generator. void set_generator(std::shared_ptr const & generator); /// @brief Process a C-Get request. virtual void operator()(message::Message const & message); private: std::shared_ptr _generator; }; } #endif // _2f0ad1fd_8779_4ab3_b7e8_6d37fdc0c018 odil-0.4.1/src/odil/GetSCU.cpp000066400000000000000000000055751266460524100160010ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/GetSCU.h" #include #include #include #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/StoreSCP.h" #include "odil/message/CGetRequest.h" #include "odil/message/CGetResponse.h" #include "odil/message/CStoreRequest.h" namespace odil { GetSCU ::GetSCU(Association & association) : SCU(association) { // Nothing else } GetSCU ::~GetSCU() { // Nothing to do } void GetSCU ::get(DataSet const & query, Callback callback) const { // Send the request message::CGetRequest request( this->_association.next_message_id(), this->_affected_sop_class, message::Message::Priority::MEDIUM, query); this->_association.send_message(request, this->_affected_sop_class); // Receive the responses bool done = false; while(!done) { message::Message const message = this->_association.receive_message(); if(message.get_command_field() == message::Message::Command::C_GET_RSP) { done = this->_handle_get_response(message::CGetResponse(message)); } else if(message.get_command_field() == message::Message::Command::C_STORE_RQ) { try { this->_handle_store_request( message::CStoreRequest(message), callback); } catch(...) { // FIXME: logging done = true; } } else { std::ostringstream exception_message; exception_message << "DIMSE: Unexpected Response Command Field: 0x" << std::hex << message.get_command_field(); throw Exception(exception_message.str()); } } } std::vector GetSCU ::get(DataSet const & query) const { std::vector result; auto callback = [&result](DataSet const & data_set) { result.push_back(data_set); }; this->get(query, callback); return result; } bool GetSCU ::_handle_get_response(message::CGetResponse const & response) const { return !response.is_pending(); } void GetSCU ::_handle_store_request( message::CStoreRequest const & request, Callback callback) const { auto const store_callback = [&callback](message::CStoreRequest const & request) { callback(request.get_data_set()); return message::Response::Success; }; StoreSCP scp(this->_association, store_callback); scp(request); } } odil-0.4.1/src/odil/GetSCU.h000066400000000000000000000030041266460524100154270ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _f82a15e2_fd13_44b5_af7d_c6983494c9c6 #define _f82a15e2_fd13_44b5_af7d_c6983494c9c6 #include #include #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/SCU.h" #include "odil/message/CGetResponse.h" #include "odil/message/CStoreRequest.h" namespace odil { /// @brief SCU for C-GET services. class GetSCU: public SCU { public: /// @brief Callback called when a response is received. typedef std::function Callback; /// @brief Constructor. GetSCU(Association & association); /// @brief Destructor. virtual ~GetSCU(); /// @brief Perform the C-GET using an optional callback. void get(DataSet const & query, Callback callback) const; /** * @brief Return a list of datasets matching the query. */ std::vector get(DataSet const & query) const; private: bool _handle_get_response(message::CGetResponse const & response) const; void _handle_store_request( message::CStoreRequest const & request, Callback callback) const; }; } #endif // _f82a15e2_fd13_44b5_af7d_c6983494c9c6 odil-0.4.1/src/odil/MoveSCP.cpp000066400000000000000000000102531266460524100161500ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/MoveSCP.h" #include #include #include #include #include "odil/Association.h" #include "odil/Exception.h" #include "odil/SCP.h" #include "odil/StoreSCU.h" #include "odil/message/CMoveRequest.h" #include "odil/message/CMoveResponse.h" #include "odil/message/Response.h" namespace odil { MoveSCP ::MoveSCP(Association & association) : SCP(association), _generator(nullptr) { // Nothing else. } MoveSCP ::MoveSCP( Association & association, std::shared_ptr const & generator) : SCP(association), _generator(nullptr) { this->set_generator(generator); } MoveSCP ::~MoveSCP() { // Nothing to do. } MoveSCP::DataSetGenerator const & MoveSCP ::get_generator() const { return *this->_generator; } void MoveSCP ::set_generator(std::shared_ptr const & generator) { this->_generator = generator; } void MoveSCP ::operator()(message::Message const & message) { message::CMoveRequest const request(message); auto move_association = this->_generator->get_association(request); move_association.associate(); StoreSCU store_scu(move_association); unsigned int remaining_sub_operations = 0; unsigned int completed_sub_operations=0; unsigned int failed_sub_operations=0; unsigned int warning_sub_operations=0; try { this->_generator->initialize(request); remaining_sub_operations = this->_generator->count(); while(!this->_generator->done()) { message::CMoveResponse response( request.get_message_id(), message::CMoveResponse::Pending); response.set_number_of_remaining_sub_operations( remaining_sub_operations); response.set_number_of_completed_sub_operations( completed_sub_operations); response.set_number_of_failed_sub_operations( failed_sub_operations); response.set_number_of_warning_sub_operations( warning_sub_operations); this->_association.send_message( response, request.get_affected_sop_class_uid()); auto const data_set = this->_generator->get(); store_scu.set_affected_sop_class(data_set); try { store_scu.store(data_set); --remaining_sub_operations; ++completed_sub_operations; } catch(Exception const &) { --remaining_sub_operations; ++failed_sub_operations; } this->_generator->next(); } } catch(Exception const &) { message::CMoveResponse response( request.get_message_id(), message::CMoveResponse::UnableToProcess); response.set_number_of_remaining_sub_operations( remaining_sub_operations); response.set_number_of_completed_sub_operations( completed_sub_operations); response.set_number_of_failed_sub_operations( failed_sub_operations); response.set_number_of_warning_sub_operations( warning_sub_operations); this->_association.send_message( response, request.get_affected_sop_class_uid()); return; } message::CMoveResponse response( request.get_message_id(), message::CMoveResponse::Success); response.set_number_of_remaining_sub_operations( remaining_sub_operations); response.set_number_of_completed_sub_operations( completed_sub_operations); response.set_number_of_failed_sub_operations( failed_sub_operations); response.set_number_of_warning_sub_operations( warning_sub_operations); this->_association.send_message( response, request.get_affected_sop_class_uid()); } } odil-0.4.1/src/odil/MoveSCP.h000066400000000000000000000032301266460524100156120ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _7e899e10_2a21_45b8_a2d6_af1d13cbfd29 #define _7e899e10_2a21_45b8_a2d6_af1d13cbfd29 #include #include #include #include #include "odil/Association.h" #include "odil/SCP.h" #include "odil/message/CMoveRequest.h" #include "odil/message/Message.h" namespace odil { /// @brief SCP for C-Move services. class MoveSCP: public SCP { public: class DataSetGenerator: public SCP::DataSetGenerator { public: virtual unsigned int count() const =0; virtual Association get_association(message::CMoveRequest const &) const =0; }; /// @brief Constructor. MoveSCP(Association & association); /// @brief Constructor. MoveSCP( Association & association, std::shared_ptr const & generator); /// @brief Destructor. virtual ~MoveSCP(); /// @brief Return the generator. DataSetGenerator const & get_generator() const; /// @brief Set the generator. void set_generator(std::shared_ptr const & generator); /// @brief Process a C-Get request. virtual void operator()(message::Message const & message); private: std::shared_ptr _generator; }; } #endif // _7e899e10_2a21_45b8_a2d6_af1d13cbfd29 odil-0.4.1/src/odil/MoveSCU.cpp000066400000000000000000000101421266460524100161520ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/MoveSCU.h" #include #include #include #include #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/StoreSCP.h" #include "odil/message/CMoveRequest.h" #include "odil/message/CMoveResponse.h" #include "odil/message/Message.h" namespace odil { MoveSCU ::MoveSCU(Association & association) : SCU(association), _move_destination("") { // Nothing else. } MoveSCU ::~MoveSCU() { // Nothing to do } std::string const & MoveSCU ::get_move_destination() const { return this->_move_destination; } void MoveSCU ::set_move_destination(std::string const & move_destination) { this->_move_destination = move_destination; } void MoveSCU ::move(DataSet const & query, Callback callback) const { // Send the request message::CMoveRequest const request( this->_association.next_message_id(), this->_affected_sop_class, message::Message::Priority::MEDIUM, this->_move_destination, query); this->_association.send_message(request, this->_affected_sop_class); // Receive the responses Association store_association; bool done = false; while(!done) { // Use a small timeout to avoid blocking for a long time. boost::posix_time::milliseconds const timeout(1000); store_association.set_tcp_timeout(timeout); store_association.set_message_timeout(timeout); if(!store_association.is_associated()) { try { store_association.receive_association(boost::asio::ip::tcp::v4(), 11113); store_association.set_tcp_timeout( this->_association.get_tcp_timeout()); store_association.set_message_timeout( this->_association.get_message_timeout()); } catch(Exception const & e) { // Ignore } if(store_association.is_associated()) { done = true; } } } this->_dispatch(store_association, callback); } std::vector MoveSCU ::move(DataSet const & query) const { std::vector result; auto callback = [&result](DataSet const & data_set) { result.push_back(data_set); }; this->move(query, callback); return result; } void MoveSCU ::_dispatch(Association & store_association, Callback callback) const { bool store_done = false; bool main_done = false; while(!(store_done && main_done)) { if(store_association.get_transport().get_socket()->available() > 0) { store_done = this->_handle_store_association(store_association, callback); } if(this->_association.get_transport().get_socket()->available() > 0) { main_done = this->_handle_main_association(); } std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } bool MoveSCU ::_handle_main_association() const { message::CMoveResponse const response = this->_association.receive_message(); return !response.is_pending(); } bool MoveSCU ::_handle_store_association(Association & association, Callback callback) const { bool result = false; try { auto const store_callback = [&callback](message::CStoreRequest const & request) { callback(request.get_data_set()); return message::Response::Success; }; StoreSCP scp(association, store_callback); scp.receive_and_process(); } catch(odil::AssociationReleased const &) { result = true; } catch(odil::AssociationAborted const & e) { result = true; } return result; } } odil-0.4.1/src/odil/MoveSCU.h000066400000000000000000000034131266460524100156220ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _5ff4d940_4db7_4d85_9d3a_230b944b31fe #define _5ff4d940_4db7_4d85_9d3a_230b944b31fe #include #include #include #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/SCU.h" namespace odil { /// @brief SCU for C-MOVE services. class MoveSCU: public SCU { public: /// @brief Callback called when a response is received. typedef std::function Callback; /// @brief Constructor. MoveSCU(Association & association); /// @brief Destructor. virtual ~MoveSCU(); /// @brief Return the AE title of the destination, defaults to "". std::string const & get_move_destination() const; /// @brief Set the AE title of the destination. void set_move_destination(std::string const & move_destination); /// @brief Perform the C-MOVE using a callback. void move(DataSet const & query, Callback callback) const; /** * @brief Return a list of datasets matching the query. */ std::vector move(DataSet const & query) const; private: std::string _move_destination; void _dispatch(Association & store_association, Callback callback) const; bool _handle_main_association() const; bool _handle_store_association(Association & association, Callback callback) const; }; } #endif // _5ff4d940_4db7_4d85_9d3a_230b944b31fe odil-0.4.1/src/odil/Reader.cpp000066400000000000000000000375431266460524100161110ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/Reader.h" #include #include #include #include #include #include #include #include "odil/DataSet.h" #include "odil/Element.h" #include "odil/endian.h" #include "odil/Exception.h" #include "odil/registry.h" #include "odil/Tag.h" #include "odil/Value.h" #include "odil/VR.h" #include "odil/VRFinder.h" #define odil_read_binary(type, value, stream, byte_ordering, size) \ type value; \ { \ uint##size##_t raw; \ stream.read(reinterpret_cast(&raw), sizeof(raw)); \ if(!stream) \ { \ throw Exception("Could not read from stream"); \ } \ if(byte_ordering == ByteOrdering::LittleEndian) \ { \ raw = little_endian_to_host(raw); \ } \ else if(byte_ordering == ByteOrdering::BigEndian) \ { \ raw = big_endian_to_host(raw); \ } \ else \ { \ throw Exception("Unknown endianness"); \ } \ value = *reinterpret_cast(&raw);\ } #define odil_ignore(stream, size) \ stream.ignore(size); \ if(!stream) \ { \ throw Exception("Could not read from stream"); \ } std::string read_string(std::istream & stream, unsigned int size) { std::string value(size, '\0'); stream.read(&value[0], value.size()); if(!stream) { throw odil::Exception("Cannot read string"); } return value; } namespace odil { Reader ::Reader( std::istream & stream, std::string const & transfer_syntax, bool keep_group_length) : stream(stream), transfer_syntax(transfer_syntax), byte_ordering( (transfer_syntax==registry::ExplicitVRBigEndian_Retired)? ByteOrdering::BigEndian:ByteOrdering::LittleEndian), explicit_vr(transfer_syntax!=registry::ImplicitVRLittleEndian), keep_group_length(keep_group_length) { // Nothing else } DataSet Reader ::read_data_set(std::function halt_condition) const { DataSet data_set; bool done = (this->stream.peek() == EOF); while(!done) { Tag const tag = this->read_tag(); if(halt_condition(tag)) { done = true; this->stream.seekg(-4, std::ios::cur); break; } else { Element element = this->read_element(tag, data_set); if(this->keep_group_length || tag.element != 0) { data_set.add(tag, element); } } done = (this->stream.peek() == EOF); } return data_set; } Tag Reader ::read_tag() const { odil_read_binary(uint16_t, group, this->stream, this->byte_ordering, 16); odil_read_binary(uint16_t, element, this->stream, this->byte_ordering, 16); return Tag(group, element); } Element Reader ::read_element(Tag const & tag, DataSet const & data_set) const { VR vr; if(this->explicit_vr) { vr = as_vr(read_string(this->stream, 2)); } else { VRFinder const vr_finder; vr = vr_finder(tag, data_set, this->transfer_syntax); } Value value; if(vr == VR::IS || vr == VR::SL || vr == VR::SS || vr == VR::UL || vr == VR::US) { value = Value(Value::Integers()); } else if(vr == VR::DS || vr == VR::FD || vr == VR::FL) { value = Value(Value::Reals()); } else if(vr == VR::AE || vr == VR::AS || vr == VR::AT || vr == VR::CS || vr == VR::DA || vr == VR::DS || vr == VR::DT || vr == VR::LO || vr == VR::LT || vr == VR::PN || vr == VR::SH || vr == VR::ST || vr == VR::TM || vr == VR::UC || vr == VR::UI || vr == VR::UR || vr == VR::UT) { value = Value(Value::Strings()); } else if(vr == VR::SQ) { value = Value(Value::DataSets()); } else if(vr == VR::OB || vr == VR::OF || vr == VR::OW || vr == VR::UN) { value = Value(Value::Binary()); } else { throw Exception("Cannot create value for VR " + as_string(vr)); } Visitor visitor( this->stream, vr, this->transfer_syntax, this->byte_ordering, this->explicit_vr, this->keep_group_length); apply_visitor(visitor, value); return Element(value, vr); } std::pair Reader ::read_file(std::istream & stream, bool keep_group_length) { // File preamble stream.ignore(128); if(!stream) { throw Exception("Cannot read preamble"); } // DICOM prefix std::string const prefix = read_string(stream, 4); if(prefix != "DICM") { throw Exception("Unexpected prefix: \""+prefix+"\""); } // Read meta information Reader meta_information_reader( stream, registry::ExplicitVRLittleEndian, keep_group_length); auto const meta_information = meta_information_reader.read_data_set( [](Tag const & tag) { return (tag.group != 0x0002); }); if(!meta_information.has(registry::TransferSyntaxUID)) { throw Exception("Missing Transfer Syntax UID"); } if(!meta_information.is_string(registry::TransferSyntaxUID)) { throw Exception("Transfer Syntax UID is not a string"); } if(meta_information.as_string(registry::TransferSyntaxUID).size()<1) { throw Exception("Empty Transfer Syntax UID"); } Reader data_set_reader( stream, meta_information.as_string(registry::TransferSyntaxUID)[0], keep_group_length); auto const data_set = data_set_reader.read_data_set(); return std::pair(meta_information, data_set); } Reader::Visitor ::Visitor( std::istream & stream, VR vr, std::string const & transfer_syntax, ByteOrdering byte_ordering, bool explicit_vr, bool keep_group_length) : stream(stream), vr(vr), transfer_syntax(transfer_syntax), byte_ordering(byte_ordering), explicit_vr(explicit_vr), keep_group_length(keep_group_length) { // Nothing else } Reader::Visitor::result_type Reader::Visitor ::operator()(Value::Integers & value) const { auto const vl = this->read_length(); if(this->vr == VR::IS) { auto const string = read_string(this->stream, vl); if(!string.empty()) { auto const strings = this->split_strings(string); value.resize(strings.size()); std::transform( strings.begin(), strings.end(), value.begin(), [](std::string const & s) { return std::stoll(s); }); } } else { uint32_t items = 0; if(this->vr == VR::SL || this->vr == VR::UL) { items = vl/4; } else if(this->vr == VR::AT || this->vr == VR::SS || this->vr == VR::US) { items = vl/2; } else { throw Exception("Cannot read integers from "+as_string(this->vr)); } value.resize(items); for(unsigned int i=0; ivr == VR::SL) { odil_read_binary( int32_t, item, this->stream, this->byte_ordering, 32); value[i] = item; } else if(this->vr == VR::SS) { odil_read_binary( int16_t, item, this->stream, this->byte_ordering, 16); value[i] = item; } else if(this->vr == VR::UL) { odil_read_binary( uint32_t, item, this->stream, this->byte_ordering, 32); value[i] = item; } else if(this->vr == VR::AT || this->vr == VR::US) { odil_read_binary( uint16_t, item, this->stream, this->byte_ordering, 16); value[i] = item; } } } } Reader::Visitor::result_type Reader::Visitor ::operator()(Value::Reals & value) const { auto const vl = this->read_length(); if(this->vr == VR::DS) { auto const string = read_string(this->stream, vl); if(!string.empty()) { auto const strings = this->split_strings(string); value.resize(strings.size()); std::transform( strings.begin(), strings.end(), value.begin(), [](std::string const & s) { return std::stod(s); }); } } else { uint32_t items = 0; if(this->vr == VR::FD) { items = vl/8; } else if(this->vr == VR::FL) { items = vl/4; } else { throw Exception("Cannot read reals from "+as_string(this->vr)); } value.resize(items); for(unsigned int i=0; ivr == VR::FD) { odil_read_binary( double, item, this->stream, this->byte_ordering, 64); value[i] = item; } else if(this->vr == VR::FL) { odil_read_binary( float, item, this->stream, this->byte_ordering, 32); value[i] = item; } } } } Reader::Visitor::result_type Reader::Visitor ::operator()(Value::Strings & value) const { if(this->vr == VR::AT) { Value::Integers integers; this->operator()(integers); if(integers.size()%2 != 0) { throw Exception("Cannot read AT from odd-sized array"); } for(unsigned int i=0; iread_length(); auto const string = read_string(this->stream, vl); if(this->vr == VR::LT || this->vr == VR::ST || this->vr == VR::UT) { value = { string }; } else { value = this->split_strings(string); } // Remove padding static std::string const padding={ '\0', ' ' }; for(auto & item: value) { auto const last_char = item.find_last_not_of(padding); if(last_char != std::string::npos) { item = item.substr(0, last_char+1); } } } } Reader::Visitor::result_type Reader::Visitor ::operator()(Value::DataSets & value) const { auto const vl = this->read_length(); if(vl != 0xffffffff) { // Explicit length sequence std::string const data = read_string(this->stream, vl); std::istringstream sequence_stream(data); Reader const sequence_reader( sequence_stream, this->transfer_syntax, this->keep_group_length); bool done = (sequence_stream.peek() == EOF); while(!done) { auto const tag = sequence_reader.read_tag(); if(tag == registry::Item) { value.push_back(this->read_item(sequence_stream)); } else { throw Exception("Expected Item, got: "+std::string(tag)); } done = (sequence_stream.peek() == EOF); } } else { // Undefined length sequence Reader const sequence_reader( this->stream, this->transfer_syntax, this->keep_group_length); bool done = false; while(!done) { auto const tag = sequence_reader.read_tag(); if(tag == registry::Item) { value.push_back(this->read_item(this->stream)); } else if(tag == registry::SequenceDelimitationItem) { done = true; odil_ignore(this->stream, 4); } else { throw Exception("Expected SequenceDelimitationItem, got: "+std::string(tag)); } } } } Reader::Visitor::result_type Reader::Visitor ::operator()(Value::Binary & value) const { auto const vl = this->read_length(); if(this->vr == VR::OB) { value.resize(vl); this->stream.read(reinterpret_cast(&value[0]), value.size()); } else if(this->vr == VR::OF) { if(vl%4 != 0) { throw Exception("Cannot read OF for odd-sized array"); } value.resize(vl); for(unsigned int i=0; istream, this->byte_ordering, 32); *reinterpret_cast(&value[i]) = item; } } else if(this->vr == VR::OW) { if(vl%2 != 0) { throw Exception("Cannot read OW for odd-sized array"); } value.resize(vl); for(unsigned int i=0; istream, this->byte_ordering, 16); *reinterpret_cast(&value[i]) = item; } } else if(this->vr == VR::UN) { value.resize(vl); this->stream.read(reinterpret_cast(&value[0]), value.size()); } else { throw Exception("Cannot read "+as_string(this->vr)+" as binary"); } } uint32_t Reader::Visitor ::read_length() const { uint32_t length; if(this->explicit_vr) { if(vr == VR::OB || vr == VR::OW || vr == VR::OF || vr == VR::SQ || vr == VR::UC || vr == VR::UR || vr == VR::UT || vr == VR::UN) { odil_ignore(this->stream, 2); odil_read_binary( uint32_t, vl, this->stream, this->byte_ordering, 32); length = vl; } else { odil_read_binary( uint16_t, vl, this->stream, this->byte_ordering, 16); length = vl; } } else { odil_read_binary( uint32_t, vl, this->stream, this->byte_ordering, 32); length = vl; } return length; } Value::Strings Reader::Visitor ::split_strings(std::string const & string) const { unsigned int const items_count = 1+std::count(string.begin(), string.end(), '\\'); std::vector value(items_count); std::string::size_type begin = 0; unsigned int index=0; while(begin != string.size()) { auto const end = string.find('\\', begin); auto const item = string.substr( begin, (end==std::string::npos)?end:(end-begin)); value[index] = item; ++index; begin = (end==std::string::npos)?string.size():(end+1); } return value; } DataSet Reader::Visitor ::read_item(std::istream & specific_stream) const { odil_read_binary( uint32_t, item_length, specific_stream, this->byte_ordering, 32); DataSet item; if(item_length != 0xffffffff) { // Explicit length item std::string const data = read_string(specific_stream, item_length); std::istringstream item_stream(data); Reader const item_reader( item_stream, this->transfer_syntax, this->keep_group_length); item = item_reader.read_data_set(); } else { // Undefined length item Reader const item_reader( specific_stream, this->transfer_syntax, this->keep_group_length); item = item_reader.read_data_set( [](Tag const & tag) { return tag == registry::ItemDelimitationItem; }); auto const tag = item_reader.read_tag(); if(tag != registry::ItemDelimitationItem) { throw Exception("Unexpected tag: "+std::string(tag)); } odil_ignore(specific_stream, 4); } return item; } } #undef odil_ignore #undef odil_read_binary odil-0.4.1/src/odil/Reader.h000066400000000000000000000057451266460524100155550ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _aa2965aa_e891_4713_9c90_e8eacd2944ea #define _aa2965aa_e891_4713_9c90_e8eacd2944ea #include #include #include #include #include "odil/DataSet.h" #include "odil/Element.h" #include "odil/endian.h" #include "odil/Tag.h" #include "odil/Value.h" #include "odil/VR.h" namespace odil { /// @brief Read DICOM objects from a stream. class Reader { public: /// @brief Input stream. std::istream & stream; /// @brief Transfer syntax used to read the file. std::string transfer_syntax; /// @brief Endianness. ByteOrdering byte_ordering; /// @brief Explicit-ness of the Value Representations. bool explicit_vr; /// @brief Flag to keep or discard group length tags. bool keep_group_length; /** * @brief Build a reader, derive byte ordering and explicit-ness of VR * from transfer syntax. */ Reader( std::istream & stream, std::string const & transfer_syntax, bool keep_group_length=false); /// @brief Read a data set. DataSet read_data_set( std::function halt_condition = [](Tag const &) { return false;}) const; /// @brief Read a tag. Tag read_tag() const; /** * @brief Read an element (VR and value), try to guess the VR from the tag, * partially read data set, and transfer syntax for implicit VR transfer * syntaxes. */ Element read_element( Tag const & tag=Tag(0xffff,0xffff), DataSet const & data_set=DataSet()) const; static std::pair read_file( std::istream & stream, bool keep_group_length=false); private: struct Visitor { typedef void result_type; std::istream & stream; VR vr; std::string transfer_syntax; ByteOrdering byte_ordering; bool explicit_vr; bool keep_group_length; Visitor( std::istream & stream, VR vr, std::string const & transfer_syntax, ByteOrdering byte_ordering, bool explicit_vr, bool keep_group_length); result_type operator()(Value::Integers & value) const; result_type operator()(Value::Reals & value) const; result_type operator()(Value::Strings & value) const; result_type operator()(Value::DataSets & value) const; result_type operator()(Value::Binary & value) const; uint32_t read_length() const; Value::Strings split_strings(std::string const & string) const; DataSet read_item(std::istream & specific_stream) const; }; }; } #endif // _aa2965aa_e891_4713_9c90_e8eacd2944ea odil-0.4.1/src/odil/SCP.cpp000066400000000000000000000015761266460524100153310ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "SCP.h" #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/message/Message.h" #include "odil/message/Request.h" namespace odil { SCP::DataSetGenerator ::~DataSetGenerator() { // Nothing to do. } SCP ::SCP(Association & association) : _association(association) { // Nothing else. } SCP ::~SCP() { // Nothing to do. } void SCP ::receive_and_process() { auto const message = this->_association.receive_message(); (*this)(message); } } odil-0.4.1/src/odil/SCP.h000066400000000000000000000027031266460524100147670ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _f4680d8c_18a8_4317_956d_3ae238cb39cc #define _f4680d8c_18a8_4317_956d_3ae238cb39cc #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/message/Message.h" #include "odil/message/Request.h" namespace odil { /// @brief Base class for all Service Class Providers. class SCP { public: /// @brief Abstract base class for SCP returning multiple data sets. class DataSetGenerator { public: virtual ~DataSetGenerator() =0; virtual void initialize(message::Request const & request) =0; virtual bool done() const =0; virtual void next() =0; virtual DataSet get() const =0; }; /// @brief Create a Service Class Provider. SCP(Association & association); /// @brief Destructor virtual ~SCP(); /// @brief Receive and process a message. void receive_and_process(); /// @brief Process a message. virtual void operator()(message::Message const & message) =0; protected: Association & _association; }; } #endif // _f4680d8c_18a8_4317_956d_3ae238cb39cc odil-0.4.1/src/odil/SCPDispatcher.cpp000066400000000000000000000031401266460524100173250ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/SCPDispatcher.h" #include #include #include "odil/Association.h" #include "odil/Exception.h" #include "odil/SCP.h" #include "odil/Value.h" namespace odil { SCPDispatcher ::SCPDispatcher(Association & association) : _association(association) { // Nothing else. } SCPDispatcher ::~SCPDispatcher() { // Nothing to do. } bool SCPDispatcher ::has_scp(Value::Integer command) const { auto const it = this->_providers.find(command); return (it != this->_providers.end()); } std::shared_ptr const & SCPDispatcher ::get_scp(Value::Integer command) const { auto const it = this->_providers.find(command); if(it == this->_providers.end()) { throw Exception("No such provider"); } return it->second; } void SCPDispatcher ::set_scp(Value::Integer command, std::shared_ptr const & scp) { this->_providers[command] = scp; } void SCPDispatcher ::dispatch() { auto const message = this->_association.receive_message(); auto const it = this->_providers.find(message.get_command_field()); if(it == this->_providers.end()) { throw Exception("No such provider"); } auto & scp = *(it->second); scp(message); } } odil-0.4.1/src/odil/SCPDispatcher.h000066400000000000000000000023351266460524100167770ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _f0b69ac6_7d52_401d_a2f3_d5d3f7d69376 #define _f0b69ac6_7d52_401d_a2f3_d5d3f7d69376 #include #include #include "odil/Association.h" #include "odil/SCP.h" #include "odil/Value.h" namespace odil { class SCPDispatcher { public: /// @brief Create a dispatcher with network and association. SCPDispatcher(Association & association); /// @brief Destructor. ~SCPDispatcher(); bool has_scp(Value::Integer command) const; std::shared_ptr const & get_scp(Value::Integer command) const; void set_scp(Value::Integer command, std::shared_ptr const & scp); void dispatch(); private: typedef std::shared_ptr SCPPointer; Association & _association; std::map> _providers; }; } #endif // _f0b69ac6_7d52_401d_a2f3_d5d3f7d69376 odil-0.4.1/src/odil/SCU.cpp000066400000000000000000000033221266460524100153250ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/SCU.h" #include #include "odil/Association.h" #include "odil/Exception.h" #include "odil/message/CEchoRequest.h" #include "odil/message/CEchoResponse.h" #include "odil/message/Message.h" #include "odil/registry.h" namespace odil { SCU ::SCU(Association & association) : _association(association), _affected_sop_class("") { // Nothing else. } SCU ::~SCU() { // Nothing to do. } std::string const & SCU ::get_affected_sop_class() const { return this->_affected_sop_class; } void SCU ::set_affected_sop_class(std::string const & sop_class) { this->_affected_sop_class = sop_class; } void SCU ::echo() const { auto const message_id = this->_association.next_message_id(); message::CEchoRequest const request( message_id, registry::VerificationSOPClass); this->_association.send_message( request, request.get_affected_sop_class_uid()); message::CEchoResponse const response = this->_association.receive_message(); if(response.get_message_id_being_responded_to() != message_id) { std::ostringstream message; message << "DIMSE: Unexpected Response MsgId: " << response.get_message_id_being_responded_to() << "(expected: " << message_id << ")"; throw Exception(message.str()); } } } odil-0.4.1/src/odil/SCU.h000066400000000000000000000023241266460524100147730ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _ba1518e7_8123_46c9_81c0_65439717e40e #define _ba1518e7_8123_46c9_81c0_65439717e40e #include #include "odil/Association.h" namespace odil { /// @brief Base class for all Service Class Users. class SCU { public: /// @brief Create a default Service Class User. SCU(Association & association); /// @brief Destructor. virtual ~SCU(); /// @brief Return the affected SOP class. Defaults to "". std::string const & get_affected_sop_class() const; /// @brief Set the affected SOP class void set_affected_sop_class(std::string const & sop_class); /// @brief Perform DICOM ping void echo() const; protected: Association & _association; /// @brief Affected SOP class. std::string _affected_sop_class; }; } #endif // _ba1518e7_8123_46c9_81c0_65439717e40e odil-0.4.1/src/odil/StoreSCP.cpp000066400000000000000000000034531266460524100163420ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/StoreSCP.h" #include #include "odil/Association.h" #include "odil/Exception.h" #include "odil/SCP.h" #include "odil/Value.h" #include "odil/message/CStoreRequest.h" #include "odil/message/CStoreResponse.h" #include "odil/message/CStoreRequest.h" #include "odil/message/CStoreResponse.h" namespace odil { StoreSCP ::StoreSCP(Association & association) : SCP(association), _callback() { // Nothing else. } StoreSCP ::StoreSCP(Association & association, Callback const & callback) : SCP(association), _callback() { this->set_callback(callback); } StoreSCP ::~StoreSCP() { // Nothing to do. } StoreSCP::Callback const & StoreSCP ::get_callback() const { return this->_callback; } void StoreSCP ::set_callback(Callback const & callback) { this->_callback = callback; } void StoreSCP ::operator()(message::Message const & message) { message::CStoreRequest const request(message); Value::Integer status=message::CStoreResponse::Success; try { status = this->_callback(request); } catch(Exception const & exception) { status = message::CStoreResponse::ProcessingFailure; // Error Comment // Error ID // Affected SOP Class UID } message::CStoreResponse const response(request.get_message_id(), status); this->_association.send_message( response, request.get_affected_sop_class_uid()); } } odil-0.4.1/src/odil/StoreSCP.h000066400000000000000000000027171266460524100160110ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _fdbf3f51_91f5_464a_b449_c3f994297210 #define _fdbf3f51_91f5_464a_b449_c3f994297210 #include #include "odil/Association.h" #include "odil/SCP.h" #include "odil/Value.h" #include "odil/message/CStoreRequest.h" #include "odil/message/Message.h" namespace odil { /// @brief SCP for C-Store services. class StoreSCP: public SCP { public: /// @brief Callback called when a request is received. typedef std::function Callback; /// @brief Constructor. StoreSCP(Association & association); /// @brief Constructor. StoreSCP(Association & association, Callback const & callback); /// @brief Destructor. virtual ~StoreSCP(); /// @brief Return the callback. Callback const & get_callback() const; /// @brief Set the callback. void set_callback(Callback const & callback); /// @brief Process a C-Store request. virtual void operator()(message::Message const & message); private: Callback _callback; }; } #endif // _fdbf3f51_91f5_464a_b449_c3f994297210 odil-0.4.1/src/odil/StoreSCU.cpp000066400000000000000000000062471266460524100163530ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "StoreSCU.h" #include #include #include #include #include "odil/message/CStoreRequest.h" #include "odil/message/CStoreResponse.h" #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/registry.h" #include "odil/SCU.h" namespace odil { StoreSCU ::StoreSCU(Association & association) : SCU(association) { // Nothing else. } StoreSCU ::~StoreSCU() { // Nothing to do. } void StoreSCU ::set_affected_sop_class(DataSet const & dataset) { auto const & sop_class_uid = dataset.as_string(registry::SOPClassUID, 0); std::vector storage; for(auto const & uids_it: registry::uids_dictionary) { auto const & name = uids_it.second.name; if(name.find("Storage") != std::string::npos) { storage.push_back(uids_it.first); } } if(std::find(storage.begin(), storage.end(), sop_class_uid) != storage.end()) { this->SCU::set_affected_sop_class(sop_class_uid); } else { throw Exception("Could not guess affected SOP class from dataset"); } } void StoreSCU ::store(DataSet const & dataset) const { message::CStoreRequest const request( this->_association.next_message_id(), this->_affected_sop_class, dataset.as_string(registry::SOPInstanceUID, 0), message::Message::Priority::MEDIUM, dataset); this->_association.send_message(request, this->_affected_sop_class); message::CStoreResponse const response = this->_association.receive_message(); if(response.get_message_id_being_responded_to() != request.get_message_id()) { std::ostringstream message; message << "DIMSE: Unexpected Response MsgId: " << response.get_message_id_being_responded_to() << "(expected: " << request.get_message_id() << ")"; throw Exception(message.str()); } if(response.has_affected_sop_class_uid() && response.get_affected_sop_class_uid() != request.get_affected_sop_class_uid()) { std::ostringstream message; message << "DIMSE: Unexpected Response Affected SOP Class UID: " << response.get_affected_sop_class_uid() << " (expected: " << request.get_affected_sop_class_uid() << ")"; throw Exception(message.str()); } if(response.has_affected_sop_instance_uid() && response.get_affected_sop_instance_uid() != request.get_affected_sop_instance_uid()) { std::ostringstream message; message << "DIMSE: Unexpected Response Affected SOP Instance UID: " << response.get_affected_sop_instance_uid() << " (expected: " << request.get_affected_sop_instance_uid() << ")"; throw Exception(message.str()); } } } odil-0.4.1/src/odil/StoreSCU.h000066400000000000000000000020461266460524100160110ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _1b2f876e_1ad2_464d_9423_28181320aed0 #define _1b2f876e_1ad2_464d_9423_28181320aed0 #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/SCU.h" namespace odil { /// @brief SCU for C-Store services. class StoreSCU: public SCU { public: /// @brief Constructor. StoreSCU(Association & association); /// @brief Destructor. virtual ~StoreSCU(); /// @brief Set the affected SOP class based on the dataset. void set_affected_sop_class(DataSet const & dataset); /// @brief Perform the C-STORE. void store(DataSet const & dataset) const; }; } #endif // _1b2f876e_1ad2_464d_9423_28181320aed0 odil-0.4.1/src/odil/Tag.cpp000066400000000000000000000077161266460524100154210ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/Tag.h" #include #include #include #include #include "odil/Exception.h" #include "odil/registry.h" namespace odil { Tag ::Tag(uint16_t group, uint16_t element) : group(group), element(element) { // Nothing else } Tag ::Tag(uint32_t tag) : group(tag >> 16), element(tag & 0xffff) { // Nothing else } Tag ::Tag(std::string const & string) { this->_from_string(string); } Tag ::Tag(char const * string) { this->_from_string(string); } bool Tag ::is_private() const { return (this->group%2 == 1); } std::string Tag ::get_name() const { auto const dictionary_it = registry::public_dictionary.find(*this); if(dictionary_it == registry::public_dictionary.end()) { throw Exception("No such element: "+std::string(*this)); } return dictionary_it->second.keyword; } bool Tag ::operator==(Tag const & other) const { return ((this->group == other.group) && (this->element == other.element)); } bool Tag ::operator!=(Tag const & other) const { return !(*this == other); } bool Tag ::operator<(Tag const & other) const { return ( (this->group < other.group) || (this->group == other.group && this->element < other.element)); } bool Tag ::operator>(Tag const & other) const { return ( (this->group > other.group) || (this->group == other.group && this->element > other.element)); } bool Tag ::operator<=(Tag const & other) const { return !(*this > other); } bool Tag ::operator>=(Tag const & other) const { return !(*this < other); } void Tag ::_from_string(std::string const & string) { ElementsDictionary::const_iterator it = registry::public_dictionary.begin(); while(it != registry::public_dictionary.end()) { if(it->second.keyword == string) { break; } ++it; } if(it == registry::public_dictionary.end()) { // Try with string form of numeric tag uint16_t group; uint16_t element; bool parsed = true; if(string.size() != 8) { parsed = false; } else { std::string const first = string.substr(0, 4); char * endptr; group = strtol(first.c_str(), &endptr, 16); if(*endptr != '\0') { parsed = false; } else { std::string const second = string.substr(4, 4); element = strtol(second.c_str(), &endptr, 16); if(*endptr != '\0') { parsed = false; } } } if(!parsed) { throw Exception("No such element: "+string); } else { this->group = group; this->element = element; } } else { auto const & tag = it->first; this->group = tag.group; this->element = tag.element; } } Tag ::operator std::string() const { std::ostringstream stream; stream << (*this); return stream.str(); } std::ostream & operator<<(std::ostream & stream, Tag const & tag) { std::ostream::char_type const old_fill = stream.fill(); std::streamsize const old_width = stream.width(); std::ios::fmtflags const flags = stream.flags(); stream << std::hex << std::setw(4) << std::setfill('0') << tag.group << std::setw(4) << std::setfill('0') << tag.element; stream.setf(flags); stream.width(old_width); stream.fill(old_fill); return stream; } } odil-0.4.1/src/odil/Tag.h000066400000000000000000000051141266460524100150540ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _5faf4691_e936_476e_8ad3_40f36a167a74 #define _5faf4691_e936_476e_8ad3_40f36a167a74 #include #include #include namespace odil { /** * @brief A DICOM element tag. */ class Tag { public: /// @brief Create a tag based on its group and element as two 16-bits words. Tag(uint16_t group, uint16_t element); /// @brief Create a tag based on its group and element as one 32-bits word. Tag(uint32_t tag); /** * @brief Create a tag based on its name or string representation of its * numeric value. * * If the name cannot be found in the public data dictionary, or if the * string is not the representation of a numeric value, a odil::Exception * is raised. */ Tag(std::string const & name); /** * @brief Create a tag based on its name or string representation of its * numeric value. * * If the name cannot be found in the public data dictionary, or if the * string is not the representation of a numeric value, a odil::Exception * is raised. */ Tag(char const * name); /// @brief Group of the tag. uint16_t group; /// @brief Element of the tag. uint16_t element; bool is_private() const; /** * @brief Return the name of the tag. * * If the tag cannot be found in the public data dictionary, * a odil::Exception is raised. */ std::string get_name() const; /// @brief Equality test. bool operator==(Tag const & other) const; /// @brief Difference test. bool operator!=(Tag const & other) const; /// @brief Strict inferiority test. bool operator<(Tag const & other) const; /// @brief Strict superiority test. bool operator>(Tag const & other) const; /// @brief Loose inferiority test. bool operator<=(Tag const & other) const; /// @brief Loose superiority test. bool operator>=(Tag const & other) const; /// @brief Convert to string operator std::string() const; private: void _from_string(std::string const & string); }; /// @brief Stream inserter std::ostream & operator<<(std::ostream & stream, Tag const & tag); } #endif // _5faf4691_e936_476e_8ad3_40f36a167a74 odil-0.4.1/src/odil/UIDsDictionary.cpp000066400000000000000000000012771266460524100175340ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/UIDsDictionary.h" #include #include namespace odil { UIDsDictionaryEntry ::UIDsDictionaryEntry( std::string const & name, std::string const & keyword, std::string const & type) : name(name), keyword(keyword), type(type) { // Nothing else. } } odil-0.4.1/src/odil/UIDsDictionary.h000066400000000000000000000016671266460524100172040ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _7b126e41_bd4d_443f_8873_d2fec52b1019 #define _7b126e41_bd4d_443f_8873_d2fec52b1019 #include #include namespace odil { /** * @brief Entry in a dictionary of DICOM UIDs. */ struct UIDsDictionaryEntry { std::string name; std::string keyword; std::string type; UIDsDictionaryEntry( std::string const & name, std::string const & keyword, std::string const & type); }; typedef std::map UIDsDictionary; } #endif // _7b126e41_bd4d_443f_8873_d2fec52b1019 odil-0.4.1/src/odil/VR.cpp000066400000000000000000000060351266460524100152260ustar00rootroot00000000000000#include #include #include #include #include "odil/Exception.h" #include "odil/registry.h" #include "odil/Tag.h" // Anonymous namespace, should not be publicly accessed namespace { #define ADD_TO_MAP(map, vr) map[odil::VR::vr] = #vr std::map _build_enum_to_name() { std::map result; ADD_TO_MAP(result, AE); ADD_TO_MAP(result, AS); ADD_TO_MAP(result, AT); ADD_TO_MAP(result, CS); ADD_TO_MAP(result, DA); ADD_TO_MAP(result, DS); ADD_TO_MAP(result, DT); ADD_TO_MAP(result, FL); ADD_TO_MAP(result, FD); ADD_TO_MAP(result, IS); ADD_TO_MAP(result, LO); ADD_TO_MAP(result, LT); ADD_TO_MAP(result, PN); ADD_TO_MAP(result, OB); ADD_TO_MAP(result, OF); ADD_TO_MAP(result, OW); ADD_TO_MAP(result, SH); ADD_TO_MAP(result, SL); ADD_TO_MAP(result, SQ); ADD_TO_MAP(result, SS); ADD_TO_MAP(result, ST); ADD_TO_MAP(result, TM); ADD_TO_MAP(result, UC); ADD_TO_MAP(result, UI); ADD_TO_MAP(result, UL); ADD_TO_MAP(result, UN); ADD_TO_MAP(result, UR); ADD_TO_MAP(result, US); ADD_TO_MAP(result, UT); return result; } #undef ADD_TO_MAP std::map _build_name_to_enum() { std::map const enum_to_name = _build_enum_to_name(); std::map result; for(std::map::const_iterator it = enum_to_name.begin(); it != enum_to_name.end(); ++it) { result[it->second] = it->first; } return result; } std::map const _enum_to_name = _build_enum_to_name(); std::map const _name_to_enum = _build_name_to_enum(); } namespace odil { std::string as_string(VR vr) { try { return _enum_to_name.at(vr); } catch(std::out_of_range const &) { throw Exception("Unknown VR"); } } VR as_vr(std::string const & vr) { try { return _name_to_enum.at(vr); } catch(std::out_of_range const &) { throw Exception("Unknown VR: "+vr); } } VR as_vr(Tag const & tag) { auto const dictionary_it = registry::public_dictionary.find(tag); if(dictionary_it == registry::public_dictionary.end()) { throw Exception("No such element: "+std::string(tag)); } VR const vr(as_vr(std::string(dictionary_it->second.vr))); return vr; } bool is_int(VR vr) { return ( vr == VR::IS || vr == VR::SL || vr == VR::SS || vr == VR::UL || vr == VR::US); } bool is_real(VR vr) { return (vr == VR::DS || vr == VR::FL || vr == VR::FD); } bool is_string(VR vr) { return ( vr == VR::AE || vr == VR::AS || vr == VR::CS || vr == VR::DA || vr == VR::DT || vr == VR::LO || vr == VR::LT || vr == VR::PN || vr == VR::SH || vr == VR::ST || vr == VR::TM || vr == VR::UC || vr == VR::UI || vr == VR::UR || vr == VR::UT); } bool is_binary(VR vr) { return (vr == VR::OB || vr == VR::OF || vr == VR::OW || vr == VR::UN); } } odil-0.4.1/src/odil/VR.h000066400000000000000000000026751266460524100147010ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _998aa43a_9e90_4d39_a074_a7074ac5c9b8 #define _998aa43a_9e90_4d39_a074_a7074ac5c9b8 #include namespace odil { class Tag; /// @brief Value representations of DICOM. enum class VR { UNKNOWN, AE, AS, AT, CS, DA, DS, DT, FL, FD, IS, LO, LT, PN, OB, OF, OW, SH, SL, SQ, SS, ST, TM, UC, UI, UL, UN, UR, US, UT, INVALID }; /// @brief Convert a VR to its string representation. std::string as_string(VR vr); /** * @brief Convert a string to its VR. * * If the string does not represent a VR, a odil::Exception is raised. */ VR as_vr(std::string const & vr); /** * @brief Guess a VR from a tag. * * If the VR cannot be guessed, a odil::Exception is raised. */ VR as_vr(Tag const & tag); /// @brief Test whether a VR contains integers. bool is_int(VR vr); /// @brief Test whether a VR contains rel numbers. bool is_real(VR vr); /// @brief Test whether a VR contains text. bool is_string(VR vr); /// @brief Test whether a VR contains binary data. bool is_binary(VR vr); } #endif // _998aa43a_9e90_4d39_a074_a7074ac5c9b8 odil-0.4.1/src/odil/VRFinder.cpp000066400000000000000000000111401266460524100163470ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/VRFinder.h" #include #include #include #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/registry.h" #include "odil/Tag.h" #include "odil/VR.h" namespace odil { std::vector const VRFinder ::default_finders=VRFinder::_get_default_finders(); VRFinder ::VRFinder() : finders() { // Nothing else } VR VRFinder::operator()( Tag const & tag, DataSet const & data_set, std::string const & transfer_syntax) const { VR vr = VR::UNKNOWN; for(auto const & finder: this->finders) { try { vr = finder(tag, data_set, transfer_syntax); break; } catch(Exception &) { // Ignore the error, try the next one } } if(vr == VR::UNKNOWN) { for(auto const & finder: VRFinder::default_finders) { try { vr = finder(tag, data_set, transfer_syntax); break; } catch(Exception &) { // Ignore the error, try the next one } } } if(vr == VR::UNKNOWN) { throw Exception("Could not find a VR for "+std::string(tag)); } return vr; } VR VRFinder ::public_dictionary( Tag const & tag, DataSet const &, std::string const &) { auto const it = registry::public_dictionary.find(tag); if(it == registry::public_dictionary.end()) { throw Exception("Element " + std::string(tag) + " is not in the public dictionary"); } return as_vr(it->second.vr); } VR VRFinder ::group_length( Tag const & tag, DataSet const &, std::string const &) { if(tag.element == 0) { return VR::UL; } else { throw Exception("Not a group length tag"); } } VR VRFinder ::private_tag( Tag const & tag, DataSet const &, std::string const &) { if(tag.group %2 == 1) { return VR::UN; } else { throw Exception("Not a private tag"); } } VR VRFinder ::implicit_vr_little_endian( Tag const & tag, DataSet const & data_set, std::string const & transfer_syntax) { if(transfer_syntax == registry::ImplicitVRLittleEndian) { // PS3.5, A.1 (c) if(tag == registry::PixelData) { return VR::OW; } else if((tag.group<<8) == 0x60 && tag.element == 0x3000) { return VR::OW; } else if(tag == registry::WaveformData) { return VR::OW; } else if(tag == registry::RedPaletteColorLookupTableData || tag == registry::GreenPaletteColorLookupTableData || tag == registry::BluePaletteColorLookupTableData || tag == registry::AlphaPaletteColorLookupTableData) { return VR::OW; } // {Red,Green,Blue,Alpha}PaletteColorLookupTableDescriptor else if(tag == registry::SegmentedRedPaletteColorLookupTableData || tag == registry::SegmentedGreenPaletteColorLookupTableData || tag == registry::SegmentedBluePaletteColorLookupTableData) { return VR::OW; } // LUTData // LUTDescriptor else if(tag == registry::BlendingLookupTableData) { return VR::OW; } else if(tag == registry::VertexPointIndexList || tag == registry::EdgePointIndexList || tag == registry::TrianglePointIndexList || tag == registry::PrimitivePointIndexList) { return VR::OW; } else if(tag == registry::SmallestImagePixelValue || tag == registry::LargestImagePixelValue || tag == registry::SmallestPixelValueInSeries || tag == registry::LargestPixelValueInSeries || tag == registry::PixelPaddingValue) { return VR::US; } else { throw Exception("Unknown tag"); } } else { throw Exception("Unknown transfer syntax"); } } std::vector VRFinder ::_get_default_finders() { return { group_length, private_tag, implicit_vr_little_endian, public_dictionary }; } } odil-0.4.1/src/odil/VRFinder.h000066400000000000000000000045161266460524100160250ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _b7afd80f_327e_4d9a_b0fa_88c565add7b3 #define _b7afd80f_327e_4d9a_b0fa_88c565add7b3 #include #include #include #include "odil/DataSet.h" #include "odil/Tag.h" #include "odil/VR.h" namespace odil { /// @brief Find the VR of elements in an implicit VR data set. class VRFinder { public: /** * @brief Prototype of finder functions. * * Finder functions must raise an exception if they are not applicable. */ typedef std::function Finder; /// @brief Default finder functions. static std::vector const default_finders; /// @brief User-defined finder functions, empty by default. std::vector finders; /// @brief Constructor. VRFinder(); /** * @brief Return a VR for the given tag, partially-constructed data set and * transfer-syntax. If no VR can be found, raise an exception. * * The user-defined finders are tried first, then the default_finders. */ VR operator()( Tag const & tag, DataSet const & data_set, std::string const & transfer_syntax) const; /// @brief Return the VR from the public dictionary. static VR public_dictionary( Tag const & tag, DataSet const &, std::string const &); /// @brief Return the VR of group-length (gggg,0000) elements. static VR group_length( Tag const & tag, DataSet const &, std::string const &); /// @brief Return a default VR (UN) for private tags. static VR private_tag( Tag const & tag, DataSet const &, std::string const &); /// @brief Return the VR of elements defined in PS3.5, A.1 (c). static VR implicit_vr_little_endian( Tag const & tag, DataSet const & data_set, std::string const & transfer_syntax); private: static std::vector _get_default_finders(); }; } #endif // _b7afd80f_327e_4d9a_b0fa_88c565add7b3 odil-0.4.1/src/odil/Value.cpp000066400000000000000000000074271266460524100157610ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/Value.h" #include #include #include #include #include "odil/DataSet.h" #include "odil/Exception.h" namespace odil { Value ::Value() : _type(Type::Empty) { // Nothing else. } Value ::Value(Integers const & integers) : _type(Type::Integers), _integers(integers) { // Nothing else. } Value ::Value(Reals const & reals) : _type(Type::Reals), _reals(reals) { // Nothing else. } Value ::Value(Strings const & strings) : _type(Type::Strings), _strings(strings) { // Nothing else. } Value ::Value(DataSets const & datasets) : _type(Type::DataSets), _data_sets(datasets) { // Nothing else. } Value ::Value(Binary const & binary) : _type(Type::Binary), _binary(binary) { // Nothing else. } Value ::Value(std::initializer_list const & list) : _type(Type::Integers) { this->_integers.resize(list.size()); std::copy(list.begin(), list.end(), this->_integers.begin()); } Value ::Value(std::initializer_list const & list) : _type(Type::Integers), _integers(list) { // Nothing else } Value ::Value(std::initializer_list const & list) : _type(Type::Reals), _reals(list) { // Nothing else } Value ::Value(std::initializer_list const & list) : _type(Type::Strings), _strings(list) { // Nothing else } Value ::Value(std::initializer_list const & list) : _type(Type::DataSets), _data_sets(list) { // Nothing else } Value::Type Value ::get_type() const { return this->_type; } bool Value ::empty() const { return (this->_type == Type::Empty); } #define DECLARE_CONST_ACCESSOR(type, name) \ Value::type const & \ Value \ ::as_##name() const \ { \ if(this->get_type() != Type::type) \ { \ throw Exception("Type mismatch"); \ } \ return this->_##name; \ } #define DECLARE_NON_CONST_ACCESSOR(type, name) \ Value::type & \ Value \ ::as_##name() \ { \ if(this->get_type() != Type::type) \ { \ throw Exception("Type mismatch"); \ } \ return this->_##name; \ } DECLARE_CONST_ACCESSOR(Integers, integers) DECLARE_NON_CONST_ACCESSOR(Integers, integers) DECLARE_CONST_ACCESSOR(Reals, reals) DECLARE_NON_CONST_ACCESSOR(Reals, reals) DECLARE_CONST_ACCESSOR(Strings, strings) DECLARE_NON_CONST_ACCESSOR(Strings, strings) DECLARE_CONST_ACCESSOR(DataSets, data_sets) DECLARE_NON_CONST_ACCESSOR(DataSets, data_sets) DECLARE_CONST_ACCESSOR(Binary, binary) DECLARE_NON_CONST_ACCESSOR(Binary, binary) #undef DECLARE_NON_CONST_ACCESSOR #undef DECLARE_CONST_ACCESSOR bool Value ::operator==(Value const & other) const { if(this->_type != other._type) { return false; } else if(this->_type == Value::Type::Empty) { return true; } else if(this->_type == Value::Type::Integers) { return this->_integers == other._integers; } else if(this->_type == Value::Type::Reals) { return this->_reals == other._reals; } else if(this->_type == Value::Type::Strings) { return this->_strings == other._strings; } else if(this->_type == Value::Type::DataSets) { return this->_data_sets == other._data_sets; } else if(this->_type == Value::Type::Binary) { return this->_binary == other._binary; } else { throw Exception("Unknown type"); } } bool Value ::operator!=(Value const & other) const { return !(*this == other); } } odil-0.4.1/src/odil/Value.h000066400000000000000000000116731266460524100154240ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _dca5b15b_b8df_4925_a446_d42efe06c923 #define _dca5b15b_b8df_4925_a446_d42efe06c923 #include #include #include #include namespace odil { class DataSet; /** * @brief A value held in a DICOM element. */ class Value { public: /// @brief Possible types stored in the value. enum class Type { Empty, Integers, Reals, Strings, DataSets, Binary }; typedef int64_t Integer; typedef double Real; typedef std::string String; /// @brief Integer container. typedef std::vector Integers; /// @brief Real container. typedef std::vector Reals; /// @brief String container. typedef std::vector Strings; /// @brief Data sets container. typedef std::vector DataSets; /// @brief Binary data container. typedef std::vector Binary; /// @brief Build an empty value. Value(); /// @brief Build a value from integers. Value(Integers const & integers); /// @brief Build a value from reals. Value(Reals const & reals); /// @brief Build a value from strings. Value(Strings const & strings); /// @brief Build a value from data sets. Value(DataSets const & datasets); /// @brief Build a value from binary data. Value(Binary const & binary); /// @brief Build a value from integers. Value(std::initializer_list const & list); /// @brief Build a value from integers. Value(std::initializer_list const & list); /// @brief Build a value from reals. Value(std::initializer_list const & list); /// @brief Build a value from strings. Value(std::initializer_list const & list); /// @brief Build a value from data sets. Value(std::initializer_list const & list); /// @brief Return the type store in the value. Type get_type() const; /// @brief Test whether the value is empty. bool empty() const; /** * @brief Return the integers contained in the value. * * If the value does not contain integers, a odil::Exception is raised. */ Integers const & as_integers() const; /** * @brief Return the integers contained in the value. * * If the value does not contain integers, a odil::Exception is raised. */ Integers & as_integers(); /** * @brief Return the reals contained in the value. * * If the value does not contain reals, a odil::Exception is raised. */ Reals const & as_reals() const; /** * @brief Return the reals contained in the value. * * If the value does not contain reals, a odil::Exception is raised. */ Reals & as_reals(); /** * @brief Return the strings contained in the value. * * If the value does not contain strings, a odil::Exception is raised. */ Strings const & as_strings() const; /** * @brief Return the strings contained in the value. * * If the value does not contain strings, a odil::Exception is raised. */ Strings & as_strings(); /** * @brief Return the data sets contained in the value. * * If the value does not contain data sets, a odil::Exception is raised. */ DataSets const & as_data_sets() const; /** * @brief Return the data sets contained in the value. * * If the value does not contain data sets, a odil::Exception is raised. */ DataSets & as_data_sets(); /** * @brief Return the binary data contained in the value. * * If the value does not contain binary data, a odil::Exception is raised. */ Binary const & as_binary() const; /** * @brief Return the binary data contained in the value. * * If the value does not contain binary data, a odil::Exception is raised. */ Binary & as_binary(); /// @brief Equality test. bool operator==(Value const & other) const; /// @brief Difference test. bool operator!=(Value const & other) const; private: Integers _integers; Reals _reals; Strings _strings; DataSets _data_sets; Binary _binary; Type _type; }; /** * @brief Visitor of values. */ template typename TVisitor::result_type apply_visitor(TVisitor const & visitor, Value const & value); /** * @brief Visitor of values. */ template typename TVisitor::result_type apply_visitor(TVisitor const & visitor, Value & value); } #include "odil/Value.txx" #endif // _dca5b15b_b8df_4925_a446_d42efe06c923 odil-0.4.1/src/odil/Value.txx000066400000000000000000000043711266460524100160150ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _de64b8e1_4116_41f8_a085_dabfdc6c63c3 #define _de64b8e1_4116_41f8_a085_dabfdc6c63c3 #include "odil/Value.h" #include "odil/Exception.h" namespace odil { template typename TVisitor::result_type apply_visitor(TVisitor const & visitor, Value const & value) { if(value.get_type() == Value::Type::Empty) { throw Exception("Empty value"); } else if(value.get_type() == Value::Type::Integers) { return visitor(value.as_integers()); } else if(value.get_type() == Value::Type::Reals) { return visitor(value.as_reals()); } else if(value.get_type() == Value::Type::Strings) { return visitor(value.as_strings()); } else if(value.get_type() == Value::Type::DataSets) { return visitor(value.as_data_sets()); } else if(value.get_type() == Value::Type::Binary) { return visitor(value.as_binary()); } else { throw Exception("Unknown value type"); } } template typename TVisitor::result_type apply_visitor(TVisitor const & visitor, Value & value) { if(value.get_type() == Value::Type::Empty) { throw Exception("Empty value"); } else if(value.get_type() == Value::Type::Integers) { return visitor(value.as_integers()); } else if(value.get_type() == Value::Type::Reals) { return visitor(value.as_reals()); } else if(value.get_type() == Value::Type::Strings) { return visitor(value.as_strings()); } else if(value.get_type() == Value::Type::DataSets) { return visitor(value.as_data_sets()); } else if(value.get_type() == Value::Type::Binary) { return visitor(value.as_binary()); } else { throw Exception("Unknown value type"); } } } #endif // _de64b8e1_4116_41f8_a085_dabfdc6c63c3 odil-0.4.1/src/odil/Writer.cpp000066400000000000000000000353411266460524100161550ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/Writer.h" #include #include #include #include #include #include "odil/DataSet.h" #include "odil/endian.h" #include "odil/Element.h" #include "odil/Exception.h" #include "odil/registry.h" #include "odil/Tag.h" #include "odil/uid.h" #include "odil/VR.h" #define odil_write_binary(value, stream, byte_ordering, size) \ { \ auto raw = value; \ if(byte_ordering == ByteOrdering::LittleEndian) \ { \ raw = host_to_little_endian(raw); \ } \ else if(byte_ordering == ByteOrdering::BigEndian) \ { \ raw = host_to_big_endian(raw); \ } \ else \ { \ throw Exception("Unknown endianness"); \ } \ stream.write(reinterpret_cast(&raw), sizeof(raw)); \ if(!stream) \ { \ throw Exception("Could not write to stream"); \ } \ } namespace odil { Writer ::Writer( std::ostream & stream, ByteOrdering byte_ordering, bool explicit_vr, ItemEncoding item_encoding, bool use_group_length) : stream(stream), byte_ordering(byte_ordering), explicit_vr(explicit_vr), item_encoding(item_encoding), use_group_length(use_group_length) { // Nothing else } Writer ::Writer( std::ostream & stream, std::string const & transfer_syntax, ItemEncoding item_encoding, bool use_group_length) : stream(stream), byte_ordering( (transfer_syntax==registry::ExplicitVRBigEndian_Retired)? ByteOrdering::BigEndian:ByteOrdering::LittleEndian), explicit_vr(transfer_syntax!=registry::ImplicitVRLittleEndian), item_encoding(item_encoding), use_group_length(use_group_length) { // Nothing else } void Writer ::write_data_set(DataSet const & data_set) const { // Build a map of the different group in order to handle // Group Length elements std::map> groups; for(auto const & item: data_set) { auto const & tag = item.first; groups[tag.group].push_back(tag); } for(auto const & groups_it: groups) { std::ostringstream group_stream; Writer group_writer( group_stream, this->byte_ordering, this->explicit_vr, this->item_encoding, this->use_group_length); for(auto const & tag: groups_it.second) { group_writer.write_tag(tag); group_writer.write_element(data_set[tag]); } // Write group length if necessary // Mandatory for group 0: PS3.7, 9.3, 10.3, and E.1 // Mandatory for group 2: PS3.10, 7.1 // Forbidden for groups 4 and 6? auto const write_group_length = ( groups_it.first == 0 || groups_it.first == 2 || (this->use_group_length && groups_it.first != 4 && groups_it.first != 6)); if(write_group_length) { // Group length: (gggg,0000) UL Type=3 VM=1 this->write_tag(Tag(groups_it.first, 0)); this->write_element( Element(Value::Integers({group_stream.tellp()}), VR::UL)); } // Write group data to main stream std::string const group_data = group_stream.str(); this->stream.write(&group_data[0], group_data.size()); if(!this->stream) { throw Exception("Could not write to stream"); } } } void Writer ::write_tag(Tag const & tag) const { odil_write_binary(tag.group, this->stream, this->byte_ordering, 16); odil_write_binary(tag.element, this->stream, this->byte_ordering, 16); } void Writer ::write_element(Element const & element) const { auto const vr = element.vr; // Write VR if(this->explicit_vr) { this->stream << as_string(vr); if(!this->stream) { throw Exception("Could not write to stream"); } } // Write value to a sub-stream std::ostringstream value_stream; if(!element.get_value().empty()) { Visitor const visitor( value_stream, vr, this->byte_ordering, this->explicit_vr, this->item_encoding, this->use_group_length); apply_visitor(visitor, element.get_value()); } // Write VL if(this->explicit_vr) { if(vr == VR::OB || vr == VR::OW || vr == VR::OF || vr == VR::SQ || vr == VR::UC || vr == VR::UR || vr == VR::UT || vr == VR::UN) { odil_write_binary(uint16_t(0), this->stream, this->byte_ordering, 16); uint32_t vl; if(vr == VR::SQ && this->item_encoding == ItemEncoding::UndefinedLength) { vl = 0xffffffff; } else { vl = value_stream.tellp(); } odil_write_binary(vl, this->stream, this->byte_ordering, 32); } else { odil_write_binary(uint16_t(value_stream.tellp()), this->stream, this->byte_ordering, 16); } } else { odil_write_binary(uint32_t(value_stream.tellp()), this->stream, this->byte_ordering, 32); } this->stream.write(value_stream.str().c_str(), value_stream.tellp()); if(!this->stream) { throw Exception("Could not write to stream"); } } void Writer ::write_file(DataSet const &data_set , std::ostream & stream, odil::DataSet const & meta_information, std::string const & transfer_syntax, ItemEncoding item_encoding, bool use_group_length) { // Build File Meta Information, PS3.10, 7.1 DataSet meta_info = meta_information; meta_info.add( registry::FileMetaInformationVersion, Value::Binary({0x00, 0x01})); if(!data_set.has(registry::SOPClassUID)) { throw Exception("Missing SOP Class UID"); } if(!data_set.is_string(registry::SOPClassUID)) { throw Exception("SOP Class UID is not a string"); } if(data_set.as_string(registry::SOPClassUID).size()<1) { throw Exception("Empty SOP Class UID"); } meta_info.add( registry::MediaStorageSOPClassUID, data_set.as_string(registry::SOPClassUID)); if(!data_set.has(registry::SOPInstanceUID)) { throw Exception("Missing SOP Instance UID"); } if(!data_set.is_string(registry::SOPInstanceUID)) { throw Exception("SOP Instance UID is not a string"); } if(data_set.as_string(registry::SOPInstanceUID).size()<1) { throw Exception("Empty SOP Instance UID"); } meta_info.add(registry::MediaStorageSOPInstanceUID, data_set.as_string(registry::SOPInstanceUID)); meta_info.add(registry::TransferSyntaxUID, {transfer_syntax}); meta_info.add( registry::ImplementationClassUID, {implementation_class_uid}); meta_info.add( registry::ImplementationVersionName, { implementation_version_name }); // Information set by input attribut 'meta_information': // - SourceApplicationEntityTitle // - SendingApplicationEntityTitle // - ReceivingApplicationEntityTitle // File preamble for(unsigned int i=0; i<128; ++i) { stream.put(0); if(!stream) { throw Exception("Could not write to stream"); } } // DICOM prefix std::string const prefix("DICM"); stream.write(&prefix[0], prefix.size()); if(!stream) { throw Exception("Could not write to stream"); } // File Meta Information // PS3.10, 7.1: Except for the 128 byte preamble and the 4 byte prefix, the // File Meta Information shall be encoded using the Explicit VR // Little Endian Transfer Syntax Writer meta_information_writer( stream, registry::ExplicitVRLittleEndian, item_encoding, use_group_length); meta_information_writer.write_data_set(meta_info); // Data Set Writer data_set_writer( stream, transfer_syntax, item_encoding, use_group_length); data_set_writer.write_data_set(data_set); } Writer::Visitor ::Visitor( std::ostream & stream, VR vr, ByteOrdering byte_ordering, bool explicit_vr, Writer::ItemEncoding item_encoding, bool use_group_length) : stream(stream), vr(vr), byte_ordering(byte_ordering), explicit_vr(explicit_vr), item_encoding(item_encoding), use_group_length(use_group_length) { // Nothing else } Writer::Visitor::result_type Writer::Visitor ::operator()(Value::Integers const & value) const { if(this->vr == VR::IS) { this->write_strings(value, ' '); } else if(this->vr == VR::SL) { for(auto item: value) { odil_write_binary( int32_t(item), this->stream, this->byte_ordering, 32); } } else if(this->vr == VR::SS) { for(auto item: value) { odil_write_binary( int16_t(item), this->stream, this->byte_ordering, 16); } } else if(this->vr == VR::UL) { for(auto item: value) { odil_write_binary( uint32_t(item), this->stream, this->byte_ordering, 32); } } else if(this->vr == VR::AT || this->vr == VR::US) { for(auto item: value) { odil_write_binary( uint16_t(item), this->stream, this->byte_ordering, 16); } } else { throw Exception("Cannot write " + as_string(this->vr) + " as integers"); } } Writer::Visitor::result_type Writer::Visitor ::operator()(Value::Reals const & value) const { if(this->vr == VR::DS) { this->write_strings(value, ' '); } else if(this->vr == VR::FD) { for(auto const & item: value) { odil_write_binary( double(item), this->stream, this->byte_ordering, 64); } } else if(this->vr == VR::FL) { for(auto const & item: value) { odil_write_binary( float(item), this->stream, this->byte_ordering, 32); } } else { throw Exception("Cannot write " + as_string(this->vr) + " as reals"); } } Writer::Visitor::result_type Writer::Visitor ::operator()(Value::Strings const & value) const { if(this->vr == VR::AT) { Value::Integers integers; for(auto const & string: value) { Tag const tag(string); integers.push_back(tag.group); integers.push_back(tag.element); } this->operator()(integers); } else { this->write_strings(value, (this->vr == VR::UI)?'\0':' '); } } Writer::Visitor::result_type Writer::Visitor ::operator()(Value::DataSets const & value) const { // Write all items to a sub-stream std::ostringstream sequence_stream; Writer sequence_writer( sequence_stream, this->byte_ordering, this->explicit_vr, this->item_encoding, this->use_group_length); for(auto const & item: value) { // Write item to a sub-stream std::ostringstream item_stream; Writer item_writer( item_stream, this->byte_ordering, this->explicit_vr, this->item_encoding, this->use_group_length); item_writer.write_data_set(item); // Beginning of item sequence_writer.write_tag(registry::Item); // Item length uint32_t item_length; if(this->item_encoding == ItemEncoding::ExplicitLength) { item_length = item_stream.tellp(); } else { item_length = 0xffffffff; } odil_write_binary(item_length, sequence_stream, this->byte_ordering, 32); // Data set sequence_stream.write(item_stream.str().c_str(), item_stream.tellp()); if(!sequence_stream) { throw Exception("Could not write to stream"); } // End of item if(this->item_encoding == ItemEncoding::UndefinedLength) { sequence_writer.write_tag(registry::ItemDelimitationItem); odil_write_binary(uint32_t(0), sequence_stream, this->byte_ordering, 32); } } // End of sequence if(this->item_encoding == ItemEncoding::UndefinedLength) { sequence_writer.write_tag(registry::SequenceDelimitationItem); odil_write_binary(uint32_t(0), sequence_stream, this->byte_ordering, 32); } this->stream.write(sequence_stream.str().c_str(), sequence_stream.tellp()); if(!this->stream) { throw Exception("Could not write to stream"); } } Writer::Visitor::result_type Writer::Visitor ::operator()(Value::Binary const & value) const { if(this->vr == VR::OB || this->vr == VR::UN) { this->stream.write(reinterpret_cast(&value[0]), value.size()); } else if(this->vr == VR::OW) { if(value.size()%2 != 0) { throw Exception("Value cannot be written as OW"); } for(int i=0; i(&value[i]); odil_write_binary(item, this->stream, this->byte_ordering, 16); } } else if(this->vr == VR::OF) { if(value.size()%4 != 0) { throw Exception("Value cannot be written as OF"); } for(int i=0; i(&value[i]); odil_write_binary(item, this->stream, this->byte_ordering, 32); } } else { throw Exception("Cannot write "+as_string(this->vr)+" as binary"); } if(!this->stream) { throw Exception("Could not write to stream"); } if(value.size()%2 == 1) { this->stream.put('\0'); } } template void Writer::Visitor ::write_strings(T const & sequence, char padding) const { auto const stream_begin = this->stream.tellp(); auto last_element_it = --sequence.end(); for(auto it = sequence.begin(); it!= sequence.end(); ++it) { this->stream << *it; if(!this->stream) { throw Exception("Could not write to stream"); } if(it != last_element_it) { this->stream << "\\"; if(!this->stream) { throw Exception("Could not write to stream"); } } } auto const stream_end = this->stream.tellp(); if((stream_end-stream_begin)%2 == 1) { this->stream.put(padding); if(!this->stream) { throw Exception("Could not write to stream"); } } } } #undef odil_write_binary odil-0.4.1/src/odil/Writer.h000066400000000000000000000065151266460524100156230ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _ca5c06d2_04f9_4009_9e98_5607e1060379 #define _ca5c06d2_04f9_4009_9e98_5607e1060379 #include #include #include "odil/DataSet.h" #include "odil/Element.h" #include "odil/endian.h" #include "odil/registry.h" #include "odil/Tag.h" #include "odil/Value.h" #include "odil/VR.h" namespace odil { /// @brief Write DICOM objects to a stream. class Writer { public: /// @brief Encodings of sequence items. enum class ItemEncoding { ExplicitLength, UndefinedLength }; /// @brief Output stream. std::ostream & stream; /// @brief Endianness. ByteOrdering byte_ordering; /// @brief Explicit-ness of the Value Representations. bool explicit_vr; /// @brief Encoding of sequence items. ItemEncoding item_encoding; /// @brief Presence of group length elements. bool use_group_length; /// @brief Build a writer. Writer( std::ostream & stream, ByteOrdering byte_ordering, bool explicit_vr, ItemEncoding item_encoding=ItemEncoding::ExplicitLength, bool use_group_length=false); /** * @brief Build a writer, derive byte ordering and explicit-ness of VR * from transfer syntax. */ Writer( std::ostream & stream, std::string const & transfer_syntax, ItemEncoding item_encoding=ItemEncoding::ExplicitLength, bool use_group_length=false); /// @brief Write a data set. void write_data_set(DataSet const & data_set) const; /// @brief Write a tag. void write_tag(Tag const & tag) const; /// @brief Write an element (VR, VL and value). void write_element(Element const & element) const; /// @brief Write a file (meta-information and data set). static void write_file( DataSet const &data_set, std::ostream & stream, DataSet const & meta_information = DataSet(), std::string const & transfer_syntax = registry::ExplicitVRLittleEndian, ItemEncoding item_encoding=ItemEncoding::ExplicitLength, bool use_group_length=false); private: struct Visitor { typedef void result_type; std::ostream & stream; VR vr; ByteOrdering byte_ordering; bool explicit_vr; ItemEncoding item_encoding; bool use_group_length; Visitor( std::ostream & stream, VR vr, ByteOrdering byte_ordering, bool explicit_vr, ItemEncoding item_encoding, bool use_group_length); result_type operator()(Value::Integers const & value) const; result_type operator()(Value::Reals const & value) const; result_type operator()(Value::Strings const & value) const; result_type operator()(Value::DataSets const & value) const; result_type operator()(Value::Binary const & value) const; template void write_strings(T const & sequence, char padding) const; }; }; } #endif // _ca5c06d2_04f9_4009_9e98_5607e1060379 odil-0.4.1/src/odil/asio.cpp000066400000000000000000000007251266460524100156320ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ // Build Boost.asio in Odil #include odil-0.4.1/src/odil/base64.cpp000066400000000000000000000024711266460524100157630ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/base64.h" #include namespace odil { namespace base64 { std::string const symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // Assume ASCII encoding std::string const reversed_symbols( "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" // Not used: 00-0F "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" // Not used: 10-1F "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3e\x00\x00\x00\x3f" // Not used: 20-2A, 2C-2E "\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x00\x00\x00\x00\x00\x00" // 0-9 "\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e" // A-O "\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x00\x00\x00\x00\x00" // P-Z "\x00\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28" // a-o "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x00\x00\x00\x00\x00" // p-z , 0x80); } } odil-0.4.1/src/odil/base64.h000066400000000000000000000023321266460524100154240ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _203e7be8_beaa_4d97_94b2_6a0070f158a1 #define _203e7be8_beaa_4d97_94b2_6a0070f158a1 #include namespace odil { namespace base64 { /// @brief Dictionary of symbols for Base64. extern std::string const symbols; /// @brief Mapping of ASCII characters to values of Base64 symbols. extern std::string const reversed_symbols; /// @brief Encode a sequence of 8 bits data to Base64. template void encode( TInputIterator begin, TInputIterator end, TOutputIterator destination); /// @brief Decode a sequence of 8 bits data from Base64. template void decode( TInputIterator begin, TInputIterator end, TOutputIterator destination); } } #include "odil/base64.txx" #endif // _203e7be8_beaa_4d97_94b2_6a0070f158a1 odil-0.4.1/src/odil/base64.txx000066400000000000000000000063611266460524100160260ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/base64.h" #include #include #ifndef _90eec83b_0ab6_4669_8454_e5a7e0a11a26 #define _90eec83b_0ab6_4669_8454_e5a7e0a11a26 namespace odil { namespace base64 { template void encode( TInputIterator begin, TInputIterator end, TOutputIterator destination) { auto iterator = begin; unsigned char carry=0; unsigned int position=0; while(iterator != end) { unsigned char const input = static_cast(*iterator); unsigned char symbol_index; if(position%3 == 0) { symbol_index = input >> 2; carry = input & 3; *destination = symbols[symbol_index]; } else if(position%3 == 1) { symbol_index = (carry << 4) + (input >> 4); carry = input & 15; *destination = symbols[symbol_index]; } else // position%3 == 2 { symbol_index = (carry << 2) + (input >> 6); carry = input & 63; *destination = symbols[symbol_index]; ++destination; *destination = symbols[carry]; } ++iterator; ++destination; ++position; } if(position%3 == 1) { *destination = symbols[carry<<4]; ++destination; *destination = '='; ++destination; *destination = '='; } else if(position%3 == 2) { *destination = symbols[carry<<2]; ++destination; *destination = '='; } // Otherwise (position%3 == 0), nothing to do. } template void decode( TInputIterator begin, TInputIterator end, TOutputIterator destination) { auto iterator = begin; unsigned char current=0; unsigned int position=0; while(iterator != end) { unsigned char input = static_cast(*iterator); if(input != '=') { input = reversed_symbols[input]; if(position%4 == 0) { current = input; } else if(position%4 == 1) { current = (current << 2) + (input >> 4); *destination = current; ++destination; current = input & 15; } else if(position%4 == 2) { current = (current << 4) + (input >> 2); *destination = current; ++destination; current = input & 3; } else // position%4 == 3 { current = (current << 6) + input; *destination = current; ++destination; } } ++iterator; ++position; } } } } #endif // _90eec83b_0ab6_4669_8454_e5a7e0a11a26 odil-0.4.1/src/odil/dcmtk/000077500000000000000000000000001266460524100152715ustar00rootroot00000000000000odil-0.4.1/src/odil/dcmtk/ElementAccessor.cpp000066400000000000000000000025171266460524100210560ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/dcmtk/ElementAccessor.h" #include #include namespace odil { namespace dcmtk { #define DEFINE_ELEMENT_ACCESSOR(TValueType, getter, setter) \ template<> \ ElementAccessor::GetterType const \ ElementAccessor\ ::element_get = getter; \ \ template<> \ ElementAccessor::SetterType const \ ElementAccessor\ ::element_set = setter; DEFINE_ELEMENT_ACCESSOR(std::string, get_string, set_string) DEFINE_ELEMENT_ACCESSOR(std::vector, get_binary, set_binary) DEFINE_ELEMENT_ACCESSOR(Float32, get_default, set_default) DEFINE_ELEMENT_ACCESSOR(Float64, get_default, set_default) DEFINE_ELEMENT_ACCESSOR(Sint16, get_default, set_default) DEFINE_ELEMENT_ACCESSOR(Sint32, get_default, set_default) DEFINE_ELEMENT_ACCESSOR(Uint16, get_default, set_default) DEFINE_ELEMENT_ACCESSOR(Uint32, get_default, set_default) #undef DEFINE_ELEMENT_ACCESSOR } } odil-0.4.1/src/odil/dcmtk/ElementAccessor.h000066400000000000000000000036621266460524100205250ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _dfa4858b_1c9d_4ce9_b220_a1c15d873602 #define _dfa4858b_1c9d_4ce9_b220_a1c15d873602 #include #include #include #include #include "odil/dcmtk/ElementTraits.h" #include "odil/dcmtk/Exception.h" namespace odil { namespace dcmtk { /// @brief Generic access to values in DcmElement. template struct ElementAccessor { /// @brief C++ type of the VR. typedef TValueType ValueType; /// @brief Getter type. typedef std::function< ValueType(DcmElement const &, unsigned long const)> GetterType; /// @brief Return the value in the element. static GetterType const element_get; /// @brief Setter type. typedef std::function< void(DcmElement &, ValueType const &, unsigned long const)> SetterType; /// @brief Set the value in the element. static SetterType const element_set; /// @brief Test whether the data set contains a given tag. static bool has(DcmDataset const & dataset, DcmTagKey const & tag); /// @brief Return the value of an element in a dataset. static ValueType get( DcmDataset const & dataset, DcmTagKey const tag, unsigned int const position=0); /// @brief Set the value of an element in a dataset. static void set( DcmDataset & dataset, DcmTagKey const tag, ValueType const & value, unsigned int const position=0); }; } } #include "odil/dcmtk/ElementAccessor.txx" #endif // _dfa4858b_1c9d_4ce9_b220_a1c15d873602 odil-0.4.1/src/odil/dcmtk/ElementAccessor.txx000066400000000000000000000122741266460524100211200ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _f9af3e63_3597_4513_8c10_b55058f5370b #define _f9af3e63_3597_4513_8c10_b55058f5370b #include "odil/dcmtk/ElementAccessor.h" #include #include #include #include #include namespace odil { namespace dcmtk { template bool ElementAccessor ::has(DcmDataset const & dataset, DcmTagKey const & tag) { DcmElement * dummy; OFCondition const condition = const_cast(dataset).findAndGetElement(tag, dummy); if(condition.good()) { return true; } else if(condition == EC_TagNotFound) { return false; } else { throw Exception(condition); } } template TValueType ElementAccessor ::get( DcmDataset const & dataset, DcmTagKey const tag, unsigned int const position) { DcmElement * element; OFCondition const condition = const_cast(dataset).findAndGetElement(tag, element); if(condition.bad()) { throw Exception(condition); } return element_get(*element, position); } template void ElementAccessor ::set( DcmDataset & dataset, DcmTagKey const tag, ValueType const & value, unsigned int const position) { DcmElement * element; OFCondition const get_condition = dataset.findAndGetElement(tag, element); if(get_condition.bad()) { OFCondition const insert_condition = dataset.insertEmptyElement(tag); if(insert_condition.bad()) { throw Exception(insert_condition); } OFCondition const new_get_condition = dataset.findAndGetElement(tag, element); if(new_get_condition.bad()) { throw Exception(insert_condition); } } element_set(*element, value, position); } template TValueType get_default(DcmElement const & element, unsigned long const position) { TValueType value; OFCondition const & condition = ElementTraits::getter( const_cast(element), value, position); if(condition.bad()) { throw Exception(condition); } return value; } template void set_default( DcmElement & element, TValueType const & value, unsigned long const position) { OFCondition const condition = ElementTraits::setter(element, value, position); if(condition.bad()) { throw Exception(condition); } } template TValueType get_string(DcmElement const & element, unsigned long const position) { OFString value; ElementTraits::getter(const_cast(element), value, position); return std::string(value.c_str()); } template void set_string( DcmElement & element, TValueType const & value, unsigned long const position) { OFString const value_dcmtk(value.c_str(), value.size()); OFCondition const condition = ElementTraits::setter( element, value_dcmtk, position); if(condition.bad()) { throw Exception(condition); } } template TValueType get_binary(DcmElement const & element, unsigned long const position) { if(position != 0) { throw Exception("Position must be 0 for binary VRs"); } DcmEVR const evr = element.getTag().getVR().getValidEVR(); TValueType result; OFCondition condition; typename TValueType::value_type * data=NULL; if(evr == EVR_OB || evr == EVR_UN) { Uint8 * typed_data; condition = const_cast(element).getUint8Array(typed_data); data = reinterpret_cast(typed_data); } else if(evr == EVR_OW) { Uint16 * typed_data; condition = const_cast(element).getUint16Array(typed_data); data = reinterpret_cast(typed_data); } else if(evr == EVR_OF) { Float32 * typed_data; condition = const_cast(element).getFloat32Array(typed_data); data = reinterpret_cast(typed_data); } else { throw Exception( std::string("Unknown VR: ") + element.getTag().getVR().getValidVRName()); } if(condition.bad()) { throw Exception(condition); } result.resize(element.getLengthField()); std::copy(data, data+element.getLengthField(), result.begin()); return result; } template void set_binary( DcmElement & element, TValueType const & value, unsigned long const position) { } } } #endif // _f9af3e63_3597_4513_8c10_b55058f5370b odil-0.4.1/src/odil/dcmtk/ElementTraits.cpp000066400000000000000000000043311266460524100205560ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/dcmtk/ElementTraits.h" #include #include #include #include #include #include "odil/Exception.h" namespace odil { namespace dcmtk { OFCondition getString(DcmElement & element, OFString & value, unsigned long const position) { OFCondition condition; DcmEVR const evr = element.getTag().getVR().getValidEVR(); if(evr == EVR_OB || evr == EVR_OF || evr == EVR_OW || evr == EVR_UN) { if(position != 0) { throw Exception("Position must be 0 for binary VRs"); } condition = element.getOFStringArray(value); } else { condition = element.getOFString(value, position); } return condition; } OFCondition putString(DcmElement & element, OFString const value, unsigned long const position) { if(position != 0) { throw Exception("Position must be 0"); } return element.putOFStringArray(value); } #define DEFINE_ELEMENT_TRAITS(TValueType, getter_, setter_) \ template<> \ ElementTraits::GetterType const \ ElementTraits\ ::getter = getter_; \ \ template<> \ ElementTraits::SetterType const \ ElementTraits\ ::setter = setter_; DEFINE_ELEMENT_TRAITS(OFString, getString, putString) DEFINE_ELEMENT_TRAITS(Float32, &DcmElement::getFloat32, &DcmElement::putFloat32) DEFINE_ELEMENT_TRAITS(Float64, &DcmElement::getFloat64, &DcmElement::putFloat64) DEFINE_ELEMENT_TRAITS(Sint16, &DcmElement::getSint16, &DcmElement::putSint16) DEFINE_ELEMENT_TRAITS(Sint32, &DcmElement::getSint32, &DcmElement::putSint32) DEFINE_ELEMENT_TRAITS(Uint16, &DcmElement::getUint16, &DcmElement::putUint16) DEFINE_ELEMENT_TRAITS(Uint32, &DcmElement::getUint32, &DcmElement::putUint32) #undef DEFINE_ELEMENT_TRAITS } } odil-0.4.1/src/odil/dcmtk/ElementTraits.h000066400000000000000000000032411266460524100202220ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _3ae28d18_6f01_4e10_98e2_1c0d21fdcab7 #define _3ae28d18_6f01_4e10_98e2_1c0d21fdcab7 #include #include #include #include #include namespace odil { namespace dcmtk { /** * @class odil::ElementTraits * @brief Traits for generic data access to values of DcmElement. * * The members are: * - GetterType: the type of the getter function * - SetterType: the type of the setter function * - getter: the getter function (one of the get??? functions of DcmElement) * - setter: the setter function (one of the put??? functions of DcmElement) */ template struct ElementTraits { /** @brief Type of the getter function. */ typedef std::function GetterType; /** @brief Getter function (one of the get??? functions of DcmElement). */ static GetterType const getter; /** @brief Type of the setter function. */ typedef std::function SetterType; /** @brief Setter function (one of the put??? functions of DcmElement). */ static SetterType const setter; }; } } #endif // _3ae28d18_6f01_4e10_98e2_1c0d21fdcab7 odil-0.4.1/src/odil/dcmtk/Exception.cpp000066400000000000000000000030051266460524100177310ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/dcmtk/Exception.h" #include #include #include #include "odil/Exception.h" namespace odil { namespace dcmtk { Exception ::Exception(std::string const & message) : ::odil::Exception(message), _source(Source::Message), _condition() { // Nothing else. } Exception ::Exception(OFCondition const & condition) : ::odil::Exception(), _source(Source::Condition), _condition(condition) { // Nothing else. } Exception ::~Exception() noexcept { // Nothing to do. } char const * Exception ::what() const throw() { if(this->_source == Source::Message) { return this->_message.c_str(); } else if(this->_source == Source::Condition) { return this->_condition.text(); } else { throw std::runtime_error("Invalid source"); } } Exception::Source Exception ::get_source() const { return this->_source; } OFCondition const & Exception ::get_condition() const { if(this->_source != Source::Condition) { throw Exception("Wrong source"); } return this->_condition; } } } odil-0.4.1/src/odil/dcmtk/Exception.h000066400000000000000000000034271266460524100174060ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _9e106372_aca6_4551_a591_95695eb00e4c #define _9e106372_aca6_4551_a591_95695eb00e4c #include #include #include "odil/Exception.h" namespace odil { namespace dcmtk { class Exception: public ::odil::Exception { public: /** * @brief Source of the Exception: either a message string or an * OFCondition. */ enum class Source { Message, Condition }; /// @brief Message string constructor, set the source to Source::Message. Exception(std::string const & message); /// @brief Condition constructor, set the source to Source::Condition. Exception(OFCondition const & condition); /// @brief Destructor. virtual ~Exception() noexcept; /// @brief Return the exception source. Source get_source() const; /** * @brief Return the condition that was used to create this exception. * * If the source is not Source::Condition, throw an exception. */ OFCondition const & get_condition() const; /** * @brief Return the reason for the exception. * * The reason for the exception is set to the message (for Source::Message) or * to the text of the condition (for Source::Condition). */ virtual const char* what() const noexcept; private: Source _source; OFCondition _condition; }; } } #endif // _9e106372_aca6_4551_a591_95695eb00e4c odil-0.4.1/src/odil/dcmtk/VRTraits.h000066400000000000000000000041721266460524100171640ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _4f556093_02e3_4659_9026_2b16bc2c8a51 #define _4f556093_02e3_4659_9026_2b16bc2c8a51 #include #include #include namespace odil { namespace dcmtk { /** * @class odil::VRTraits * @brief Information related to VR. * * The members are: * - ValueType: the DCMTK type of the VR */ template struct VRTraits; #define DECLARE_VR_TRAITS(vr, value_type) \ /** @brief Traits for generic data access to values of DcmElement. */ \ template<> \ struct VRTraits \ { \ /** @brief Type associated to the VR. */ \ typedef value_type ValueType; \ }; DECLARE_VR_TRAITS(EVR_AE, std::string) DECLARE_VR_TRAITS(EVR_AS, std::string) //DECLARE_VR_TRAITS(EVR_AT DECLARE_VR_TRAITS(EVR_CS, std::string) DECLARE_VR_TRAITS(EVR_DA, std::string) DECLARE_VR_TRAITS(EVR_DS, Float64) DECLARE_VR_TRAITS(EVR_DT, std::string) DECLARE_VR_TRAITS(EVR_FD, Float64) DECLARE_VR_TRAITS(EVR_FL, Float32) DECLARE_VR_TRAITS(EVR_IS, Sint32) DECLARE_VR_TRAITS(EVR_LO, std::string) DECLARE_VR_TRAITS(EVR_LT, std::string) DECLARE_VR_TRAITS(EVR_OB, std::vector) DECLARE_VR_TRAITS(EVR_OF, std::vector) DECLARE_VR_TRAITS(EVR_OW, std::vector) DECLARE_VR_TRAITS(EVR_PN, std::string) DECLARE_VR_TRAITS(EVR_SH, std::string) DECLARE_VR_TRAITS(EVR_SL, Sint32) //DECLARE_VR_TRAITS(EVR_SQ DECLARE_VR_TRAITS(EVR_SS, Sint16) DECLARE_VR_TRAITS(EVR_ST, std::string) DECLARE_VR_TRAITS(EVR_TM, std::string) DECLARE_VR_TRAITS(EVR_UI, std::string) DECLARE_VR_TRAITS(EVR_UL, Uint32) DECLARE_VR_TRAITS(EVR_UN, std::vector) DECLARE_VR_TRAITS(EVR_US, Uint16) DECLARE_VR_TRAITS(EVR_UT, std::string) #undef DECLARE_VR_TRAITS } } #endif // _4f556093_02e3_4659_9026_2b16bc2c8a51 odil-0.4.1/src/odil/dcmtk/conversion.cpp000066400000000000000000000377771266460524100202070ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/dcmtk/conversion.h" #include #include #include "odil/DataSet.h" #include "odil/Element.h" #include "odil/Tag.h" #include "odil/VR.h" #include "odil/dcmtk/Exception.h" namespace odil { namespace dcmtk { DcmEVR convert(VR vr) { if(vr == VR::AE) { return EVR_AE; } else if(vr == VR::AS) { return EVR_AS; } else if(vr == VR::AT) { return EVR_AT; } else if(vr == VR::CS) { return EVR_CS; } else if(vr == VR::DA) { return EVR_DA; } else if(vr == VR::DS) { return EVR_DS; } else if(vr == VR::DT) { return EVR_DT; } else if(vr == VR::FL) { return EVR_FL; } else if(vr == VR::FD) { return EVR_FD; } else if(vr == VR::IS) { return EVR_IS; } else if(vr == VR::LO) { return EVR_LO; } else if(vr == VR::LT) { return EVR_LT; } else if(vr == VR::OB) { return EVR_OB; } else if(vr == VR::OF) { return EVR_OF; } else if(vr == VR::OW) { return EVR_OW; } else if(vr == VR::PN) { return EVR_PN; } else if(vr == VR::SH) { return EVR_SH; } else if(vr == VR::SL) { return EVR_SL; } else if(vr == VR::SQ) { return EVR_SQ; } else if(vr == VR::SS) { return EVR_SS; } else if(vr == VR::ST) { return EVR_ST; } else if(vr == VR::TM) { return EVR_TM; } else if(vr == VR::UI) { return EVR_UI; } else if(vr == VR::UL) { return EVR_UL; } else if(vr == VR::UN) { return EVR_UN; } else if(vr == VR::US) { return EVR_US; } else if(vr == VR::UT) { return EVR_UT; } else { throw Exception("Unknown VR: "+as_string(vr)); } } VR convert(DcmEVR evr) { if(evr == EVR_AE) { return VR::AE; } else if(evr == EVR_AS) { return VR::AS; } else if(evr == EVR_AT) { return VR::AT; } else if(evr == EVR_CS) { return VR::CS; } else if(evr == EVR_DA) { return VR::DA; } else if(evr == EVR_DS) { return VR::DS; } else if(evr == EVR_DT) { return VR::DT; } else if(evr == EVR_FL) { return VR::FL; } else if(evr == EVR_FD) { return VR::FD; } else if(evr == EVR_IS) { return VR::IS; } else if(evr == EVR_LO) { return VR::LO; } else if(evr == EVR_LT) { return VR::LT; } else if(evr == EVR_OB) { return VR::OB; } else if(evr == EVR_OF) { return VR::OF; } else if(evr == EVR_OW) { return VR::OW; } else if(evr == EVR_PN) { return VR::PN; } else if(evr == EVR_SH) { return VR::SH; } else if(evr == EVR_SL) { return VR::SL; } else if(evr == EVR_SQ) { return VR::SQ; } else if(evr == EVR_SS) { return VR::SS; } else if(evr == EVR_ST) { return VR::ST; } else if(evr == EVR_TM) { return VR::TM; } else if(evr == EVR_UI) { return VR::UI; } else if(evr == EVR_UL) { return VR::UL; } else if(evr == EVR_UN) { return VR::UN; } else if(evr == EVR_US) { return VR::US; } else if(evr == EVR_UT) { return VR::UT; } else { throw Exception("Unknown VR: "+std::string(DcmVR(evr).getVRName())); } } DcmTagKey convert(Tag const & tag) { return DcmTagKey(tag.group, tag.element); } Tag convert(DcmTagKey const & tag) { return Tag(tag.getGroup(), tag.getElement()); } DcmElement * convert(const Tag & tag, Element const & source) { DcmTag const destination_tag(convert(tag), convert(source.vr)); DcmElement * destination = NULL; if(source.vr == VR::AE) { destination = new DcmApplicationEntity(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_string); } } else if (source.vr == VR::AS) { destination = new DcmAgeString(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_string); } } else if(source.vr == VR::AT) { destination = new DcmAttributeTag(destination_tag); if(!source.empty()) { for(unsigned int i=0; iputTagVal(destination_tag, i); } } } else if (source.vr == VR::CS) { destination = new DcmCodeString(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_string); } } else if (source.vr == VR::DA) { destination = new DcmDate(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_string); } } else if (source.vr == VR::DS) { destination = new DcmDecimalString(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_real); } } else if (source.vr == VR::DT) { destination = new DcmDateTime(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_string); } } else if (source.vr == VR::FD) { destination = new DcmFloatingPointDouble(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_real); } } else if (source.vr == VR::FL) { destination = new DcmFloatingPointSingle(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_real); } } else if (source.vr == VR::IS) { destination = new DcmIntegerString(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_int); } } else if (source.vr == VR::LO) { destination = new DcmLongString(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_string); } } else if (source.vr == VR::LT) { destination = new DcmLongText(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_string); } } else if (source.vr == VR::OB || source.vr == VR::OW) { destination = new DcmOtherByteOtherWord(destination_tag); if(!source.empty()) { convert(source, static_cast(destination)); } } else if(source.vr == VR::OF) { destination = new DcmOtherFloat(destination_tag); if(!source.empty()) { convert(source, static_cast(destination)); } } else if (source.vr == VR::PN) { destination = new DcmPersonName(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_string); } } else if (source.vr == VR::SH) { destination = new DcmShortString(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_string); } } else if (source.vr == VR::SL) { destination = new DcmSignedLong(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_int); } } else if(source.vr == VR::SQ) { DcmSequenceOfItems * sequence = new DcmSequenceOfItems(destination_tag); if(!source.empty()) { for(auto const & source_item: source.as_data_set()) { DcmItem * destination_item = convert(source_item, false); sequence->append(destination_item); } } destination = sequence; } else if (source.vr == VR::SS) { destination = new DcmSignedShort(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_int); } } else if (source.vr == VR::ST) { destination = new DcmShortText(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_string); } } else if (source.vr == VR::TM) { destination = new DcmTime(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_string); } } else if (source.vr == VR::UI) { destination = new DcmUniqueIdentifier(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_string); } } else if (source.vr == VR::UL) { destination = new DcmUnsignedLong(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_int); } } // UN else if (source.vr == VR::US) { destination = new DcmUnsignedShort(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_int); } } else if (source.vr == VR::UT) { destination = new DcmUnlimitedText(destination_tag); if(!source.empty()) { convert(source, destination, &Element::as_string); } } else { throw Exception("Unknown VR: "+as_string(source.vr)); } return destination; } template<> void convert, Value::Binary>( DcmElement * source, Element & destination, Value::Binary & (Element::*getter)()) { auto & destination_values = (destination.*getter)(); destination_values = ElementAccessor>::element_get(*source, 0); } Element convert(DcmElement * source) { Element destination; DcmEVR const source_vr = source->getTag().getVR().getValidEVR(); VR const destination_vr = convert(source_vr); if(source_vr == EVR_AE || source_vr == EVR_AS || source_vr == EVR_CS || source_vr == EVR_DA || source_vr == EVR_DT || source_vr == EVR_LO || source_vr == EVR_LT || source_vr == EVR_PN || source_vr == EVR_SH || source_vr == EVR_ST || source_vr == EVR_TM || source_vr == EVR_UI || source_vr == EVR_UT) { destination = Element(Value::Strings(), destination_vr); convert(source, destination, &Element::as_string); } else if(source_vr == EVR_AT) { destination = Element(Value::Strings(), destination_vr); destination.as_string().reserve(source->getVM()); for(unsigned int i=0; igetVM(); ++i) { DcmTagKey source_tag; OFCondition const condition = source->getTagVal(source_tag, i); if(condition.bad()) { throw Exception(condition); } Tag const destination_tag = convert(source_tag); destination.as_string().push_back(std::string(destination_tag)); } } else if(source_vr == EVR_DS || source_vr == EVR_FD) { destination = Element(Value::Reals(), destination_vr); convert(source, destination, &Element::as_real); } else if(source_vr == EVR_FL) { destination = Element(Value::Reals(), destination_vr); convert(source, destination, &Element::as_real); } else if(source_vr == EVR_IS || source_vr == EVR_SL) { destination = Element(Value::Integers(), destination_vr); convert(source, destination, &Element::as_int); } else if(source_vr == EVR_SQ) { destination = Element(Value::DataSets(), destination_vr); DcmSequenceOfItems * sequence = dynamic_cast(source); if(sequence == NULL) { throw Exception("Element is not a DcmSequenceOfItems"); } Value::DataSets & destination_value = destination.as_data_set(); destination_value.reserve(sequence->card()); for(unsigned int i=0; icard(); ++i) { DcmItem * source_item = sequence->getItem(i); DataSet const destination_item = convert(source_item); destination_value.push_back(destination_item); } } else if(source_vr == EVR_SS) { destination = Element(Value::Integers(), destination_vr); convert(source, destination, &Element::as_int); } else if(source_vr == EVR_UL) { destination = Element(Value::Integers(), destination_vr); convert(source, destination, &Element::as_int); } else if(source_vr == EVR_OB || source_vr == EVR_OF || source_vr == EVR_OW || source_vr == EVR_UN) { destination = Element(Value::Binary(), destination_vr); convert, Value::Binary>(source, destination, &Element::as_binary); } else if(source_vr == EVR_US) { destination = Element(Value::Integers(), destination_vr); convert(source, destination, &Element::as_int); } else { throw Exception("Unknown VR: "+std::string(DcmVR(source_vr).getVRName())); } return destination; } void convert(Element const & source, DcmOtherByteOtherWord * destination) { auto const & value = source.as_binary(); Uint8 * output; OFCondition condition; if(destination->getTag().getVR().getValidEVR() == EVR_OB) { condition = destination->createUint8Array(source.size(), output); } else { Uint16* temp; condition = destination->createUint16Array(source.size()/2, temp); output = reinterpret_cast(temp); } if(condition.bad()) { throw Exception(condition); } std::copy(value.begin(), value.end(), output); } void convert(Element const & source, DcmOtherFloat * destination) { auto const & value = source.as_binary(); if(value.size()%4 != 0) { throw Exception("Cannot convert OF from odd-sized array"); } for(unsigned int i=0; i(&value[i*4]); destination->putFloat32(f, i); } } DcmItem * convert(DataSet const & source, bool as_data_set) { DcmItem * destination = as_data_set?(new DcmDataset()):(new DcmItem()); for(auto const & iterator: source) { if(iterator.second.vr == VR::SQ) { if(iterator.second.empty()) { destination->insertEmptyElement(DcmTag(convert(iterator.first), convert(iterator.second.vr))); } else { for(auto const & source_item: iterator.second.as_data_set()) { DcmItem* item = convert(source_item, false); destination->insertSequenceItem(DcmTag(convert(iterator.first), convert(iterator.second.vr)), item); } } } else { auto const destination_element = convert( iterator.first, iterator.second); destination->insert(destination_element); } } return destination; } DataSet convert(DcmItem * source) { DataSet destination; for(unsigned long i=0; icard(); ++i) { auto const source_element = source->getElement(i); auto const destination_tag = convert(source_element->getTag()); auto const destination_element = convert(source_element); destination.add(destination_tag, destination_element); } return destination; } } } odil-0.4.1/src/odil/dcmtk/conversion.h000066400000000000000000000044741266460524100176400ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _d5ecacb8_04ff_48b0_8026_570c9b2ae360 #define _d5ecacb8_04ff_48b0_8026_570c9b2ae360 #include #include #include "odil/DataSet.h" #include "odil/Element.h" #include "odil/Tag.h" #include "odil/VR.h" namespace odil { namespace dcmtk { /// @brief Convert a odil::VR to a DcmVR. DcmEVR convert(VR vr); /// @brief Convert a DcmVR to a odil::VR. VR convert(DcmEVR evr); /// @brief Convert a odil::Tag to a DcmTagKey. DcmTagKey convert(Tag const & tag); /// @brief Convert a DcmTagKey to a odil::Tag. Tag convert(DcmTagKey const & tag); /// @brief Convert a odil::Element to a DcmElement. DcmElement * convert(Tag const & tag, Element const & source); /// @brief Low-level element converter. template void convert( Element const & source, DcmElement * destination, TSourceType const & (Element::*getter)() const); /// @brief Convert a DcmElement to a odil::Element. Element convert(DcmElement * source); /// @brief Low-level element converter. template void convert( Element const & source, DcmElement * destination, TSourceType const & (Element::*getter)() const); /// @brief Low-level element converter. void convert(Element const & source, DcmOtherByteOtherWord * destination); /// @brief Low-level element converter. void convert(Element const & source, DcmOtherFloat * destination); /// @brief Low-level element converter. template void convert( DcmElement * source, Element & destination, TDestinationType & (Element::*getter)()); /// @brief Convert a odil::DataSet to a DcmDataset or a DcmItem. DcmItem * convert(DataSet const & source, bool as_data_set=true); /// @brief Convert a DcmDataset to a odil::DataSet. DataSet convert(DcmItem * source); } } #include "odil/dcmtk/conversion.txx" #endif // _d5ecacb8_04ff_48b0_8026_570c9b2ae360 odil-0.4.1/src/odil/dcmtk/conversion.txx000066400000000000000000000044311266460524100202250ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _665b5269_140c_4320_94f2_ad8a7c052e9b #define _665b5269_140c_4320_94f2_ad8a7c052e9b #include "odil/dcmtk/conversion.h" #include #include "odil/Element.h" #include "odil/dcmtk/ElementAccessor.h" namespace odil { namespace dcmtk { template void convert( Element const & source, DcmElement * destination, TSourceType const & (Element::*getter)() const) { auto const & source_values = (source.*getter)(); for(auto i = 0; i::element_set( *destination, source_values[i], i); } } template void convert( Element const & source, DcmElement * destination, TSourceType const & (Element::*getter)() const) { OFString destination_value; auto const & source_values = (source.*getter)(); if(!source_values.empty()) { auto const last_it = --source_values.end(); auto it = source_values.begin(); while(it != last_it) { std::ostringstream stream; stream << *it; destination_value += stream.str().c_str(); destination_value += "\\"; ++it; } std::ostringstream stream; stream << *last_it; destination_value += stream.str().c_str(); } destination->putOFStringArray(destination_value); } template void convert( DcmElement * source, Element & destination, TDestinationType & (Element::*getter)()) { auto & destination_values = (destination.*getter)(); destination_values.reserve(source->getVM()); for(auto i = 0; igetVM(); ++i) { destination_values.push_back( ElementAccessor::element_get(*source, i)); } } } } #endif // _665b5269_140c_4320_94f2_ad8a7c052e9b odil-0.4.1/src/odil/dul/000077500000000000000000000000001266460524100147535ustar00rootroot00000000000000odil-0.4.1/src/odil/dul/EventData.h000066400000000000000000000020021266460524100167710ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _350775b8_701f_4069_ab1e_c974a209389c #define _350775b8_701f_4069_ab1e_c974a209389c #include #include "odil/AssociationAcceptor.h" #include "odil/AssociationParameters.h" #include "odil/dul/Transport.h" #include "odil/pdu/Object.h" namespace odil { namespace dul { /// @brief Data related to events of the DUL state machine. class EventData { public: Transport::Socket::endpoint_type peer_endpoint; std::shared_ptr pdu; AssociationParameters association_parameters; std::shared_ptr reject; }; } } #endif // _350775b8_701f_4069_ab1e_c974a209389c odil-0.4.1/src/odil/dul/StateMachine.cpp000066400000000000000000000477511266460524100200420ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/dul/StateMachine.h" #include #include #include #include #include #include #include #include #include "odil/AssociationParameters.h" #include "odil/endian.h" #include "odil/Exception.h" #include "odil/dul/EventData.h" #include "odil/dul/Transport.h" #include "odil/pdu/AAbort.h" #include "odil/pdu/AAssociate.h" #include "odil/pdu/AAssociateRJ.h" #include "odil/pdu/AReleaseRP.h" #include "odil/pdu/AReleaseRQ.h" #include "odil/pdu/PDataTF.h" namespace odil { namespace dul { StateMachine ::StateMachine() : _state(State::Sta1), _timeout(boost::posix_time::pos_infin), _artim_timer(_transport.get_service()), _association_acceptor(default_association_acceptor) { // Nothing else. } StateMachine ::~StateMachine() { // Nothing to to, transport is closed by ~Transport. } void StateMachine ::transition(Event const & event, EventData & data) { auto const guard_iterator = StateMachine::_guards.find( {this->_state, event}); auto const guard_value = (guard_iterator != StateMachine::_guards.end())? guard_iterator->second(*this, data):true; auto const transition_iterator = StateMachine::_transitions.find( std::make_tuple(this->_state, event, guard_value)); if(transition_iterator == StateMachine::_transitions.end()) { throw Exception("No such transition"); } auto const & action = transition_iterator->second.first; auto const & next_state = transition_iterator->second.second; // Do action if(action == Action::AE_1) { this->AE_1(data); } else if(action == Action::AE_2) { this->AE_2(data); } else if(action == Action::AE_3) { this->AE_3(data); } else if(action == Action::AE_4) { this->AE_4(data); } else if(action == Action::AE_5) { this->AE_5(data); } else if(action == Action::AE_6) { this->AE_6(data); } else if(action == Action::AE_7) { this->AE_7(data); } else if(action == Action::AE_8) { this->AE_8(data); } else if(action == Action::DT_1) { this->DT_1(data); } else if(action == Action::DT_2) { this->DT_2(data); } else if(action == Action::AR_1) { this->AR_1(data); } else if(action == Action::AR_2) { this->AR_2(data); } else if(action == Action::AR_3) { this->AR_3(data); } else if(action == Action::AR_4) { this->AR_4(data); } else if(action == Action::AR_5) { this->AR_5(data); } else if(action == Action::AR_6) { this->AR_6(data); } else if(action == Action::AR_7) { this->AR_7(data); } else if(action == Action::AR_8) { this->AR_8(data); } else if(action == Action::AR_9) { this->AR_9(data); } else if(action == Action::AR_10) { this->AR_10(data); } else if(action == Action::AA_1) { this->AA_1(data); } else if(action == Action::AA_2) { this->AA_2(data); } else if(action == Action::AA_3) { this->AA_3(data); } else if(action == Action::AA_4) { this->AA_4(data); } else if(action == Action::AA_5) { this->AA_5(data); } else if(action == Action::AA_6) { this->AA_6(data); } else if(action == Action::AA_7) { this->AA_7(data); } else if(action == Action::AA_8) { this->AA_8(data); } else { throw Exception("Unknown action"); } this->_state = next_state; } StateMachine::State StateMachine ::get_state() const { return this->_state; } Transport const & StateMachine ::get_transport() const { return this->_transport; } Transport & StateMachine ::get_transport() { return this->_transport; } StateMachine::duration_type StateMachine ::get_timeout() const { return this->_timeout; } void StateMachine ::set_timeout(duration_type timeout) { this->_timeout = timeout; } void StateMachine ::receive(EventData & data) { this->_transport.receive(data.peer_endpoint); this->transition(Event::TransportConnectionIndication, data); } void StateMachine ::send_pdu(EventData & data) { if(data.pdu == nullptr) { throw Exception("No PDU"); } auto const & item = data.pdu->get_item(); auto const type = item.as_unsigned_int_8("PDU-type"); if(type == 0x01) { this->transition(Event::AAssociateRQLocal, data); this->transition(Event::TransportConnectionConfirmation, data); } else if(type == 0x02) { this->transition(Event::AAssociateACLocal, data); } else if(type == 0x03) { this->transition(Event::AAssociateRJLocal, data); } else if(type == 0x04) { this->transition(Event::PDataTFLocal, data); } else if(type == 0x05) { this->transition(Event::AReleaseRQLocal, data); } else if(type == 0x06) { this->transition(Event::AReleaseRPLocal, data); } else if(type == 0x07) { this->transition(Event::AAbortLocal, data); } else { this->transition(Event::InvalidPDU, data); } } void StateMachine ::receive_pdu(EventData & data) { auto const header = this->_transport.read(6); uint8_t const type = header[0]; uint32_t const length = big_endian_to_host( *reinterpret_cast(&header[0]+2)); auto const pdu_data = this->_transport.read(length); std::stringstream stream; stream.write(&header[0], header.size()); stream.write(&pdu_data[0], pdu_data.size()); data.pdu=nullptr; Event event = Event::None; if(type == 0x01) { data.pdu = std::make_shared(stream); event = Event::AAssociateRQRemote; } else if(type == 0x02) { data.pdu = std::make_shared(stream); event = Event::AAssociateACRemote; } else if(type == 0x03) { data.pdu = std::make_shared(stream); event = Event::AAssociateRJRemote; } else if(type == 0x04) { data.pdu = std::make_shared(stream); event = Event::PDataTFRemote; } else if(type == 0x05) { data.pdu = std::make_shared(stream); event = Event::AReleaseRQRemote; } else if(type == 0x06) { data.pdu = std::make_shared(stream); event = Event::AReleaseRPRemote; } else if(type == 0x07) { data.pdu = std::make_shared(stream); event = Event::AAbortRemote; } else { event = Event::InvalidPDU; } this->transition(event, data); } void StateMachine ::start_timer(EventData & data) { return; auto const canceled = this->_artim_timer.expires_from_now(this->_timeout); if(canceled != 0) { throw Exception("ARTIM timer started with pending operations"); } this->_artim_timer.async_wait( [this,&data](boost::system::error_code const & e) { //source = Source::TIMER; //error = e; if(!e) { this->transition(Event::ARTIMTimerExpired, data); } else if(e == boost::asio::error::operation_aborted) { // Do nothing } else { throw boost::system::system_error(e); } } ); } void StateMachine ::stop_timer() { return; this->_artim_timer.expires_at(boost::posix_time::pos_infin); this->_transport.get_service().poll(); // FIXME: check that the timer was aborted /* if(source != Source::TIMER) { throw Exception("Unknown event"); } else if(error != boost::asio::error::operation_aborted) { throw Exception("TCP timer error: "+error.message()); } */ this->_transport.get_service().reset(); } AssociationAcceptor const & StateMachine ::get_association_acceptor() const { return this->_association_acceptor; } void StateMachine ::set_association_acceptor(AssociationAcceptor const & acceptor) { this->_association_acceptor = acceptor; } #define transition_full(start, event, guard, action, end) { \ std::make_tuple(StateMachine::State::start, StateMachine::Event::event, guard), \ { StateMachine::Action::action, StateMachine::State::end } } #define transition(start, event, action, end) \ transition_full(start, event, true, action, end) StateMachine::TransitionMap const StateMachine ::_transitions = { transition(Sta1, AAssociateRQLocal, AE_1, Sta4), transition(Sta1, TransportConnectionIndication, AE_5, Sta2), transition(Sta2, AAssociateACRemote, AA_1, Sta13), transition(Sta2, AAssociateRJRemote, AA_1, Sta13), transition_full(Sta2, AAssociateRQRemote, true, AE_6, Sta3), transition_full(Sta2, AAssociateRQRemote, false, AE_6, Sta13), transition(Sta2, PDataTFRemote, AA_1, Sta13), transition(Sta2, AReleaseRQRemote, AA_1, Sta13), transition(Sta2, AReleaseRPRemote, AA_1, Sta13), transition(Sta2, AAbortRemote, AA_2, Sta1), transition(Sta2, TransportConnectionClosedIndication, AA_5, Sta1), transition(Sta2, ARTIMTimerExpired, AA_2, Sta1), transition(Sta2, InvalidPDU, AA_1, Sta13), transition(Sta3, AAssociateACRemote, AA_8, Sta13), transition(Sta3, AAssociateRJRemote, AA_8, Sta13), transition(Sta3, AAssociateRQRemote, AA_8, Sta13), transition(Sta3, AAssociateACLocal, AE_7, Sta6), transition(Sta3, AAssociateRJLocal, AE_8, Sta13), transition(Sta3, PDataTFRemote, AA_8, Sta13), transition(Sta3, AReleaseRQRemote, AA_8, Sta13), transition(Sta3, AReleaseRPRemote, AA_8, Sta13), transition(Sta3, AAbortLocal, AA_1, Sta13), transition(Sta3, AAbortRemote, AA_3, Sta1), transition(Sta3, TransportConnectionClosedIndication, AA_4, Sta1), transition(Sta3, InvalidPDU, AA_8, Sta13), transition(Sta4, TransportConnectionConfirmation, AE_2, Sta5), transition(Sta4, AAbortLocal, AA_2, Sta1), transition(Sta4, TransportConnectionClosedIndication, AA_4, Sta1), transition(Sta5, AAssociateACRemote, AE_3, Sta6), transition(Sta5, AAssociateRJRemote, AE_4, Sta1), transition(Sta5, AAssociateRQRemote, AA_8, Sta13), transition(Sta5, PDataTFRemote, AA_8, Sta13), transition(Sta5, AReleaseRQRemote, AA_8, Sta13), transition(Sta5, AReleaseRPRemote, AA_8, Sta13), transition(Sta5, AAbortLocal, AA_1, Sta13), transition(Sta5, AAbortRemote, AA_3, Sta1), transition(Sta5, TransportConnectionClosedIndication, AA_4, Sta1), transition(Sta5, InvalidPDU, AA_8, Sta13), transition(Sta6, AAssociateACRemote, AA_8, Sta13), transition(Sta6, AAssociateRJRemote, AA_8, Sta13), transition(Sta6, AAssociateRQRemote, AA_8, Sta13), transition(Sta6, PDataTFLocal, DT_1, Sta6), transition(Sta6, PDataTFRemote, DT_2, Sta6), transition(Sta6, AReleaseRQLocal, AR_1, Sta7), transition(Sta6, AReleaseRQRemote, AR_2, Sta8), transition(Sta6, AReleaseRPRemote, AA_8, Sta13), transition(Sta6, AAbortLocal, AA_1, Sta13), transition(Sta6, AAbortRemote, AA_3, Sta1), transition(Sta6, TransportConnectionClosedIndication, AA_4, Sta1), transition(Sta6, InvalidPDU, AA_8, Sta13), transition(Sta7, AAssociateACRemote, AA_8, Sta13), transition(Sta7, AAssociateRJRemote, AA_8, Sta13), transition(Sta7, AAssociateRQRemote, AA_8, Sta13), transition(Sta7, PDataTFRemote, AR_6, Sta7), //transition(Sta7, AReleaseRQRemote, AR_8, Sta9Or10), transition(Sta7, AReleaseRPRemote, AR_3, Sta1), transition(Sta7, AAbortLocal, AA_1, Sta13), transition(Sta7, AAbortRemote, AA_3, Sta1), transition(Sta7, TransportConnectionClosedIndication, AA_4, Sta1), transition(Sta7, InvalidPDU, AA_8, Sta13), transition(Sta8, AAssociateACRemote, AA_8, Sta13), transition(Sta8, AAssociateRJRemote, AA_8, Sta13), transition(Sta8, AAssociateRQRemote, AA_8, Sta13), transition(Sta8, PDataTFLocal, AR_7, Sta8), transition(Sta8, PDataTFRemote, AA_8, Sta13), transition(Sta8, AReleaseRQRemote, AA_8, Sta13), transition(Sta8, AReleaseRPRemote, AA_8, Sta13), transition(Sta8, AReleaseRPLocal, AR_4, Sta13), transition(Sta8, AAbortLocal, AA_1, Sta13), transition(Sta8, AAbortRemote, AA_3, Sta1), transition(Sta8, TransportConnectionClosedIndication, AA_4, Sta1), transition(Sta8, InvalidPDU, AA_8, Sta13), transition(Sta9, AAssociateACRemote, AA_8, Sta13), transition(Sta9, AAssociateRJRemote, AA_8, Sta13), transition(Sta9, AAssociateRQRemote, AA_8, Sta13), transition(Sta9, PDataTFRemote, AA_8, Sta13), transition(Sta9, AReleaseRQRemote, AA_8, Sta13), transition(Sta9, AReleaseRPRemote, AA_8, Sta13), transition(Sta9, AReleaseRPLocal, AR_9, Sta11), transition(Sta9, AAbortLocal, AA_1, Sta13), transition(Sta9, AAbortRemote, AA_3, Sta1), transition(Sta9, TransportConnectionClosedIndication, AA_4, Sta1), transition(Sta9, InvalidPDU, AA_8, Sta13), transition(Sta10, AAssociateACRemote, AA_8, Sta13), transition(Sta10, AAssociateRJRemote, AA_8, Sta13), transition(Sta10, AAssociateRQRemote, AA_8, Sta13), transition(Sta10, PDataTFRemote, AA_8, Sta13), transition(Sta10, AReleaseRQRemote, AA_8, Sta13), transition(Sta10, AReleaseRPRemote, AR_10, Sta12), transition(Sta10, AAbortLocal, AA_1, Sta13), transition(Sta10, AAbortRemote, AA_3, Sta1), transition(Sta10, TransportConnectionClosedIndication, AA_4, Sta1), transition(Sta10, InvalidPDU, AA_8, Sta13), transition(Sta11, AAssociateACRemote, AA_8, Sta13), transition(Sta11, AAssociateRJRemote, AA_8, Sta13), transition(Sta11, AAssociateRQRemote, AA_8, Sta13), transition(Sta11, PDataTFRemote, AA_8, Sta13), transition(Sta11, AReleaseRQRemote, AA_8, Sta13), transition(Sta11, AReleaseRPRemote, AR_3, Sta1), transition(Sta11, AAbortLocal, AA_1, Sta13), transition(Sta11, AAbortRemote, AA_3, Sta1), transition(Sta11, TransportConnectionClosedIndication, AA_4, Sta1), transition(Sta11, InvalidPDU, AA_8, Sta13), transition(Sta12, AAssociateACRemote, AA_8, Sta13), transition(Sta12, AAssociateRJRemote, AA_8, Sta13), transition(Sta12, AAssociateRQRemote, AA_8, Sta13), transition(Sta12, PDataTFRemote, AA_8, Sta13), transition(Sta12, AReleaseRQRemote, AA_8, Sta13), transition(Sta12, AReleaseRPRemote, AA_8, Sta13), transition(Sta12, AReleaseRPLocal, AR_4, Sta13), transition(Sta12, AAbortLocal, AA_1, Sta13), transition(Sta12, AAbortRemote, AA_3, Sta1), transition(Sta12, TransportConnectionClosedIndication, AA_4, Sta1), transition(Sta12, InvalidPDU, AA_8, Sta13), transition(Sta13, AAssociateACRemote, AA_6, Sta13), transition(Sta13, AAssociateRJRemote, AA_6, Sta13), transition(Sta13, AAssociateRQRemote, AA_7, Sta13), transition(Sta13, PDataTFRemote, AA_6, Sta13), transition(Sta13, AReleaseRQRemote, AA_6, Sta13), transition(Sta13, AReleaseRPRemote, AA_6, Sta13), transition(Sta13, AAbortRemote, AA_2, Sta1), transition(Sta13, TransportConnectionClosedIndication, AR_5, Sta1), transition(Sta13, ARTIMTimerExpired, AA_2, Sta1), transition(Sta13, InvalidPDU, AA_7, Sta13), }; StateMachine::GuardMap const StateMachine ::_guards = { { {StateMachine::State::Sta2, StateMachine::Event::AAssociateRQRemote}, [](StateMachine const & state_machine, EventData & data) { try { AssociationParameters const input_parameters( *std::dynamic_pointer_cast(data.pdu)); data.association_parameters = state_machine.get_association_acceptor()(input_parameters); } catch(AssociationRejected const & reject) { data.reject = std::make_shared(reject); return false; } return true; } }, }; #undef transition #undef transition_full void StateMachine ::_send_pdu(EventData & data, uint8_t pdu_type) { if(data.pdu == nullptr) { throw Exception("No PDU"); } auto const & item = data.pdu->get_item(); if(item.as_unsigned_int_8("PDU-type") != pdu_type) { throw Exception("Invalid PDU"); } std::ostringstream stream; stream << item; this->_transport.write(stream.str()); } void StateMachine ::AE_1(EventData & data) { this->_transport.connect(data.peer_endpoint); } void StateMachine ::AE_2(EventData & data) { this->_send_pdu(data, 0x01); } void StateMachine ::AE_3(EventData & ) { // Do nothing: notification is implicit since this function is only called // by receive_pdu } void StateMachine ::AE_4(EventData & ) { // Notification is implicit since this function is only called by // receive_pdu this->_transport.close(); } void StateMachine ::AE_5(EventData & data) { // Connection response has already been sent. this->start_timer(data); } void StateMachine ::AE_6(EventData & data) { this->stop_timer(); if(data.reject) { data.pdu = std::make_shared( data.reject->get_result(), data.reject->get_source(), data.reject->get_reason()); this->_send_pdu(data, 0x03); data.pdu = NULL; } else { // Issue A-ASSOCIATE indication // Do nothing: notification is implicit since this function is only // called by receive_pdu } } void StateMachine ::AE_7(EventData & data) { this->_send_pdu(data, 0x02); } void StateMachine ::AE_8(EventData & data) { this->_send_pdu(data, 0x03); this->start_timer(data); } void StateMachine ::DT_1(EventData & data) { this->_send_pdu(data, 0x04); } void StateMachine ::DT_2(EventData & ) { // Do nothing: notification is implicit since this function is only called // by receive_pdu } void StateMachine ::AR_1(EventData & data) { this->_send_pdu(data, 0x05); } void StateMachine ::AR_2(EventData & ) { // Do nothing: notification is implicit since this function is only called // by receive_pdu } void StateMachine ::AR_3(EventData & ) { // Notification is implicit since this function is only called by // receive_pdu this->_transport.close(); } void StateMachine ::AR_4(EventData & data) { this->_send_pdu(data, 0x06); this->start_timer(data); } void StateMachine ::AR_5(EventData & ) { this->stop_timer(); } void StateMachine ::AR_6(EventData & ) { // Do nothing: notification is implicit since this function is only called // by receive_pdu } void StateMachine ::AR_7(EventData & data) { this->_send_pdu(data, 0x04); } void StateMachine ::AR_8(EventData & ) { // Do nothing: notification is implicit since this function is only called // by receive_pdu } void StateMachine ::AR_9(EventData & data) { this->_send_pdu(data, 0x06); } void StateMachine ::AR_10(EventData & ) { // Do nothing: notification is implicit since this function is only called // by receive_pdu } void StateMachine ::AA_1(EventData & data) { data.pdu = std::make_shared(1, 2); this->send_pdu(data); this->start_timer(data); } void StateMachine ::AA_2(EventData & ) { this->stop_timer(); this->_transport.close(); } void StateMachine ::AA_3(EventData & ) { // Notification is implicit since this function is only called // by receive_pdu this->_transport.close(); } void StateMachine ::AA_4(EventData & ) { // Do nothing: notification is implicit since this function is only called // by receive_pdu } void StateMachine ::AA_5(EventData & ) { this->stop_timer(); } void StateMachine ::AA_6(EventData & ) { // Nothing to do. } void StateMachine ::AA_7(EventData & data) { this->_send_pdu(data, 0x07); } void StateMachine ::AA_8(EventData & data) { data.pdu = std::make_shared(2, 2); this->_send_pdu(data, 0x07); // Notification is implicit this->start_timer(data); } } } odil-0.4.1/src/odil/dul/StateMachine.h000066400000000000000000000165371266460524100175050ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _981c80db_b2ac_4f25_af6c_febf5563d178 #define _981c80db_b2ac_4f25_af6c_febf5563d178 #include #include #include #include #include #include "odil/AssociationAcceptor.h" #include "odil/dul/EventData.h" #include "odil/dul/Transport.h" namespace odil { namespace dul { /// @brief State machine for the DICOM upper layer. class StateMachine { public: /// @brief States of the state machine. enum class State { Sta1, Sta2, Sta3, Sta4, Sta5, Sta6, Sta7, Sta8, Sta9, Sta10, Sta11, Sta12, Sta13 }; /// @brief Event causing the transitions. enum class Event { None, // dummy event to allow easier initialization TransportConnectionIndication, TransportConnectionConfirmation, TransportConnectionClosedIndication, AAssociateRQLocal, AAssociateRQRemote, AAssociateACLocal, AAssociateACRemote, AAssociateRJLocal, AAssociateRJRemote, AReleaseRQLocal, AReleaseRQRemote, AReleaseRPLocal, AReleaseRPRemote, PDataTFLocal, PDataTFRemote, AAbortLocal, AAbortRemote, ARTIMTimerExpired, InvalidPDU, }; /// @brief Duration of the timeout. typedef boost::asio::deadline_timer::duration_type duration_type; /// @brief Constructor, initializing to Sta1. StateMachine(); /// @brief Destructor, closing the transport. ~StateMachine(); /** * @brief Perform the transition related to the event and current state. * Raise an exception if no such transition exists. */ void transition(Event const & event, EventData & data); /// @brief Return the current state. State get_state() const; /// @brief Return the TCP transport. Transport const & get_transport() const; /// @brief Return the TCP transport. Transport & get_transport(); /// @brief Return the timeout, default to infinity. duration_type get_timeout() const; /// @brief Set the timeout. void set_timeout(duration_type timeout); /** * @brief Receive a connection on the TCP transport, perform the * corresponding transition. */ void receive(EventData & data); /// @brief Send a PDU to the transport, perform the corresponding transition. void send_pdu(EventData & data); /// @brief Receive a PDU on the transport, perform the corresponding transition. void receive_pdu(EventData & data); /// @brief Start (or re-start if already started) the ARTIM timer. void start_timer(EventData & data); /// @brief Stop the ARTIM timer. void stop_timer(); /** * @brief Return the callback checking whether the association request is * acceptable. * * By default, all association requests are accepted. */ AssociationAcceptor const & get_association_acceptor() const; /** * @brief Set the callback checking whether the association request is * acceptable. */ void set_association_acceptor(AssociationAcceptor const & acceptor); private: enum class Action { AE_1, AE_2, AE_3, AE_4, AE_5, AE_6, AE_7, AE_8, DT_1, DT_2, AR_1, AR_2, AR_3, AR_4, AR_5, AR_6, AR_7, AR_8, AR_9, AR_10, AA_1, AA_2, AA_3, AA_4, AA_5, AA_6, AA_7, AA_8 }; typedef std::map< std::tuple, std::pair> TransitionMap; typedef std::map< std::pair, std::function> GuardMap; static TransitionMap const _transitions; static GuardMap const _guards; /// @brief Current state. State _state; /// @brief TCP transport. Transport _transport; /// @brief Timeout of the ARTIM timer. duration_type _timeout; /// @brief Association Request/Reject/Release Timer. boost::asio::deadline_timer _artim_timer; /// @brief Callback checking whether an association request is acceptable. AssociationAcceptor _association_acceptor; /// @brief Check the PDU type in data and send it. void _send_pdu(EventData & data, uint8_t pdu_type); /** * @brief Issue TRANSPORT CONNECT request primitive to local transport * service. */ void AE_1(EventData & data); /// @brief Send A-ASSOCIATE-RQ-PDU. void AE_2(EventData & data); /// @brief Issue A-ASSOCIATE confirmation (accept) primitive. void AE_3(EventData & data); /** * @brief Issue A-ASSOCIATE confirmation (reject) primitive and close * transport connection. */ void AE_4(EventData & data); /// @brief Issue Transport connection response primitive; start ARTIM timer. void AE_5(EventData & data); /// @brief Stop ARTIM timer and accept or reject connection. void AE_6(EventData & data); /// @brief Send A-ASSOCIATE-AC PDU. void AE_7(EventData & data); /// @brief Send A-ASSOCIATE-RJ PDU and start ARTIM timer. void AE_8(EventData & data); /// @brief Send P-DATA-TF PDU. void DT_1(EventData & data); /// @brief Send P-DATA indication primitive. void DT_2(EventData & data); /// @brief Send A-RELEASE-RQ PDU. void AR_1(EventData & data); /// @brief Issue A-RELEASE indication primitive. void AR_2(EventData & data); /** * @brief Issue A-RELEASE confirmation primitive, and close transport. * connection. */ void AR_3(EventData & data); /// @brief Issue A-RELEASE-RP PDU and start ARTIM timer. void AR_4(EventData & data); /// @brief Stop ARTIM timer. void AR_5(EventData & data); /// @brief Issue P-DATA indication. void AR_6(EventData & data); /// @brief Issue P-DATA-TF PDU. void AR_7(EventData & data); /// @brief Issue A-RELEASE indication (release collision). void AR_8(EventData & data); /// @brief Send A-RELEASE-RP PDU. void AR_9(EventData & data); /// @brief Issue A-RELEASE confirmation primitive. void AR_10(EventData & data); /** * @brief Send A-ABORT PDU (service-user source) and start (or restart if * already started) ARTIM timer. */ void AA_1(EventData & data); /// @brief Stop ARTIM timer if running. Close transport connection. void AA_2(EventData & data); /** * @brief If (service-user inititated abort): issue A-ABORT indication and * close transport connection ; otherwise (service-provider inititated * abort): issue A-P-ABORT indication and close transport connection. */ void AA_3(EventData & data); /// @brief Issue A-P-ABORT indication primitive. void AA_4(EventData & data); /// @brief Stop ARTIM timer. void AA_5(EventData & data); /// @brief Ignore PDU. void AA_6(EventData & data); /// @brief Send A-ABORT PDU. void AA_7(EventData & data); /** * @brief Send A-ABORT PDU (service-provider source-), issue an A-P-ABORT * indication, and start ARTIM timer. */ void AA_8(EventData & data); }; } } #endif // _981c80db_b2ac_4f25_af6c_febf5563d178 odil-0.4.1/src/odil/dul/Transport.cpp000066400000000000000000000133541266460524100174610ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/dul/Transport.h" #include #include #include #include #include "odil/Exception.h" namespace odil { namespace dul { Transport ::Transport() : _service(), _socket(nullptr), _timeout(boost::posix_time::pos_infin), _deadline(_service) { // Nothing else } Transport ::~Transport() { if(this->is_open()) { this->close(); } } boost::asio::io_service const & Transport ::get_service() const { return this->_service; } boost::asio::io_service & Transport ::get_service() { return this->_service; } std::shared_ptr Transport ::get_socket() const { return this->_socket; } std::shared_ptr Transport ::get_socket() { return this->_socket; } Transport::duration_type Transport ::get_timeout() const { return this->_timeout; } void Transport ::set_timeout(duration_type timeout) { this->_timeout = timeout; } bool Transport ::is_open() const { return (this->_socket != nullptr && this->_socket->is_open()); } void Transport ::connect(Socket::endpoint_type const & peer_endpoint) { if(this->is_open()) { throw Exception("Already connected"); } auto source = Source::NONE; boost::system::error_code error; this->_start_deadline(source, error); this->_socket = std::make_shared(this->_service); this->_socket->async_connect( peer_endpoint, [&source,&error](boost::system::error_code const & e) { source = Source::OPERATION; error = e; } ); this->_run(source, error); } void Transport ::receive(Socket::endpoint_type const & endpoint) { if(this->is_open()) { throw Exception("Already connected"); } auto source = Source::NONE; boost::system::error_code error; this->_start_deadline(source, error); this->_socket = std::make_shared(this->_service); boost::asio::ip::tcp::acceptor acceptor(this->_service, endpoint); acceptor.async_accept( *this->_socket, [&source,&error](boost::system::error_code const & e) { source = Source::OPERATION; error = e; } ); this->_run(source, error); } void Transport ::close() { if(!this->is_open()) { throw Exception("Not connected"); } this->_socket->close(); this->_socket = nullptr; } std::string Transport ::read(std::size_t length) { if(!this->is_open()) { throw Exception("Not connected"); } std::string data(length, 'a'); auto source = Source::NONE; boost::system::error_code error; this->_start_deadline(source, error); boost::asio::async_read( *this->_socket, boost::asio::buffer(&data[0], data.size()), [&source,&error](boost::system::error_code const & e, std::size_t) { source = Source::OPERATION; error = e; } ); this->_run(source, error); return data; } void Transport ::write(std::string const & data) { if(!this->is_open()) { throw Exception("Not connected"); } auto source = Source::NONE; boost::system::error_code error; this->_start_deadline(source, error); boost::asio::async_write( *this->_socket, boost::asio::buffer(data), [&source,&error](boost::system::error_code const & e, std::size_t) { source = Source::OPERATION; error = e; } ); this->_run(source, error); } void Transport ::_start_deadline(Source & source, boost::system::error_code & error) { auto const canceled = this->_deadline.expires_from_now(this->_timeout); if(canceled != 0) { throw Exception("TCP timer started with pending operations"); } this->_deadline.async_wait( [&source,&error](boost::system::error_code const & e) { source = Source::TIMER; error = e; } ); } void Transport ::_stop_deadline() { this->_deadline.expires_at(boost::posix_time::pos_infin); } void Transport ::_run(Source & source, boost::system::error_code & error) { // WARNING: it seems that run_one runs a *simple* operation, not a // *composed* operation, as is done by async_read/async_write while(source == Source::NONE) { auto const ran = this->_service.run_one(); if(ran == 0) { throw Exception("No operations ran"); } this->_service.reset(); } if(source == Source::OPERATION) { if(error) { throw Exception("Operation error: "+error.message()); } source = Source::NONE; this->_stop_deadline(); while(source == Source::NONE) { auto const polled = this->_service.poll_one(); if(polled == 0) { throw Exception("No operations polled"); } this->_service.reset(); } if(source != Source::TIMER) { throw Exception("Unknown event"); } else if(error != boost::asio::error::operation_aborted) { throw Exception("TCP timer error: "+error.message()); } } else if(source == Source::TIMER) { throw Exception("TCP time out"); } else { throw Exception("Unknown source"); } } } } odil-0.4.1/src/odil/dul/Transport.h000066400000000000000000000053741266460524100171310ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _1619bae8_acba_4bf8_8205_aa8dd0085c66 #define _1619bae8_acba_4bf8_8205_aa8dd0085c66 #include #include #include #include namespace odil { namespace dul { /** * @brief TCP transport for the DICOM Upper Layer. * * The behavior of connect, receive, read and write is governed by the timeout * value: if the timeout expires before the operation is completed, an exception * will be raised. */ struct Transport { /// @brief Socket type. typedef boost::asio::ip::tcp::socket Socket; /// @brief Duration of the timeout. typedef boost::asio::deadline_timer::duration_type duration_type; /// @brief Constructor. Transport(); /// @brief Destructor. ~Transport(); /// @brief Return the io_service. boost::asio::io_service const & get_service() const; /// @brief Return the io_service. boost::asio::io_service & get_service(); /// @brief Return the socket. std::shared_ptr get_socket() const; /// @brief Return the socket. std::shared_ptr get_socket(); /// @brief Return the timeout, default to infinity. duration_type get_timeout() const; /// @brief Set the timeout. void set_timeout(duration_type timeout); /// @brief Test whether the transport is open. bool is_open() const; /// @brief Connect to the specified endpoint, raise an exception upon error. void connect(Socket::endpoint_type const & peer_endpoint); /** * @brief Receive a connection on the specified endpoint, raise an * exception upon error. */ void receive(Socket::endpoint_type const & endpoint); /// @brief Close the connection. void close(); /// @brief Read data, raise an exception on error. std::string read(std::size_t length); /// @brief Write data, raise an exception on error. void write(std::string const & data); private: boost::asio::io_service _service; std::shared_ptr _socket; duration_type _timeout; boost::asio::deadline_timer _deadline; enum class Source { NONE, TIMER, OPERATION, }; void _start_deadline(Source & source, boost::system::error_code & error); void _stop_deadline(); void _run(Source & source, boost::system::error_code & error); }; } } #endif // _1619bae8_acba_4bf8_8205_aa8dd0085c66 odil-0.4.1/src/odil/endian.h000066400000000000000000000031651266460524100156030ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _05d00816_25d0_41d1_9768_afd39f0503da #define _05d00816_25d0_41d1_9768_afd39f0503da #include #define ODIL_SWAP \ auto source = reinterpret_cast(&value); \ auto const end = source + sizeof(value); \ T result; \ auto destination = reinterpret_cast(&result) + sizeof(result) - 1; \ while(source != end) \ { \ *destination = *source; \ ++source; \ --destination; \ } namespace odil { enum class ByteOrdering { LittleEndian, BigEndian }; template T host_to_big_endian(T const & value) { #ifdef BOOST_LITTLE_ENDIAN ODIL_SWAP return result; #else return value; #endif } template T host_to_little_endian(T const & value) { #ifdef BOOST_BIG_ENDIAN ODIL_SWAP return result; #else return value; #endif } template T big_endian_to_host(T const & value) { #ifdef BOOST_LITTLE_ENDIAN ODIL_SWAP return result; #else return value; #endif } template T little_endian_to_host(T const & value) { #ifdef BOOST_BIG_ENDIAN ODIL_SWAP return result; #else return value; #endif } } #undef ODIL_SWAP #endif // _05d00816_25d0_41d1_9768_afd39f0503da odil-0.4.1/src/odil/json_converter.cpp000066400000000000000000000166551266460524100177500ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/json_converter.h" #include #include #include "odil/base64.h" #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/Value.h" #include "odil/VR.h" namespace odil { struct ToJSONVisitor { typedef Json::Value result_type; result_type operator()(VR const vr) const { result_type result; result["vr"] = as_string(vr); return result; } template result_type operator()(VR const vr, T const & value) const { result_type result; result["vr"] = as_string(vr); for(auto const & item: value) { result["Value"].append(item); } return result; } result_type operator()(VR const vr, Value::Integers const & value) const { result_type result; result["vr"] = as_string(vr); for(auto const & item: value) { result["Value"].append(Json::Int64(item)); } return result; } result_type operator()(VR const vr, Value::Strings const & value) const { result_type result; result["vr"] = as_string(vr); if(vr == VR::PN) { auto const fields = { "Alphabetic", "Ideographic", "Phonetic" }; for(auto const item: value) { auto fields_it = fields.begin(); Json::Value json_item; std::string::size_type begin=0; while(begin != std::string::npos) { std::string::size_type const end = item.find("=", begin); std::string::size_type size = 0; if(end != std::string::npos) { size = end-begin; } else { size = std::string::npos; } json_item[*fields_it] = item.substr(begin, size); if(end != std::string::npos) { begin = end+1; ++fields_it; if(fields_it == fields.end()) { throw Exception("Invalid Person Name"); } } else { begin = end; } } result["Value"].append(json_item); } } else { for(auto const & item: value) { result["Value"].append(item); } } return result; } result_type operator()(VR const vr, Value::DataSets const & value) const { result_type result; result["vr"] = as_string(vr); for(auto const & item: value) { result["Value"].append(as_json(item)); } return result; } result_type operator()(VR const vr, Value::Binary const & value) const { result_type result; result["vr"] = as_string(vr); std::string encoded; encoded.reserve(value.size()*4/3); base64::encode(value.begin(), value.end(), std::back_inserter(encoded)); result["InlineBinary"] = encoded; return result; } }; Json::Value as_json(DataSet const & data_set) { Json::Value json; for(auto const & it: data_set) { auto const & tag = it.first; auto const & element = it.second; std::string const key(tag); auto const value = apply_visitor(ToJSONVisitor(), element); json[key] = value; } return json; } DataSet as_dataset(Json::Value const & json) { DataSet data_set; for(Json::Value::const_iterator it=json.begin(); it != json.end(); ++it) { Tag const tag(it.memberName()); Json::Value const & json_element = *it; VR const vr = as_vr(json_element["vr"].asString()); Element element; if(vr == VR::AE || vr == VR::AS || vr == VR::AT || vr == VR::CS || vr == VR::DA || vr == VR::DT || vr == VR::LO || vr == VR::LT || vr == VR::SH || vr == VR::ST || vr == VR::TM || vr == VR::UI || vr == VR::UT) { element = Element(Value::Strings(), vr); auto const & json_value = json_element["Value"]; for(auto const & json_item: json_value) { element.as_string().push_back(json_item.asString()); } } else if(vr == VR::PN) { element = Element(Value::Strings(), vr); auto const & json_value = json_element["Value"]; for(auto const & json_item: json_value) { Value::Strings::value_type dicom_item; auto const fields = { "Alphabetic", "Ideographic", "Phonetic" }; for(auto const & field: fields) { if(json_item.isMember(field)) { dicom_item += json_item[field].asString(); } dicom_item += "="; } while(*dicom_item.rbegin() == '=') { dicom_item = dicom_item.substr(0, dicom_item.size()-1); } element.as_string().push_back(dicom_item); } } else if(vr == VR::DS || vr == VR::FD || vr == VR::FL) { element = Element(Value::Reals(), vr); auto const & json_value = json_element["Value"]; for(auto const & json_item: json_value) { element.as_real().push_back(json_item.asDouble()); } } else if(vr == VR::IS || vr == VR::SL || vr == VR::SS || vr == VR::UL || vr == VR::US) { element = Element(Value::Integers(), vr); auto const & json_value = json_element["Value"]; for(auto const & json_item: json_value) { element.as_int().push_back(json_item.asInt64()); } } else if(vr == VR::SQ) { element = Element(Value::DataSets(), vr); auto const & json_value = json_element["Value"]; for(auto const & json_item: json_value) { auto const dicom_item = as_dataset(json_item); element.as_data_set().push_back(dicom_item); } } else if(vr == VR::OB || vr == VR::OF || vr == VR::OW || vr == VR::UN) { element = Element(Value::Binary(), vr); auto const & encoded = json_element["InlineBinary"].asString(); auto & decoded = element.as_binary(); decoded.reserve(encoded.size()*3/4); base64::decode( encoded.begin(), encoded.end(), std::back_inserter(decoded)); } else { throw Exception("Unknown VR: "+as_string(vr)); } data_set.add(tag, element); } return data_set; } } odil-0.4.1/src/odil/json_converter.h000066400000000000000000000014761266460524100174100ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _6f5dc463_a89a_4f77_a0ed_36dca74b9e59 #define _6f5dc463_a89a_4f77_a0ed_36dca74b9e59 #include #include "odil/DataSet.h" namespace odil { /// @brief Convert a data set to its JSON representation. Json::Value as_json(DataSet const & data_set); /// @brief Create a data set from its JSON representation. DataSet as_dataset(Json::Value const & json); } #endif // _6f5dc463_a89a_4f77_a0ed_36dca74b9e59 odil-0.4.1/src/odil/message/000077500000000000000000000000001266460524100156135ustar00rootroot00000000000000odil-0.4.1/src/odil/message/CEchoRequest.cpp000066400000000000000000000023341266460524100206530ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "CEchoRequest.h" #include "odil/message/Request.h" #include "odil/registry.h" #include "odil/Value.h" namespace odil { namespace message { CEchoRequest ::CEchoRequest( Value::Integer message_id, Value::String const & affected_sop_class_uid) : Request(message_id) { this->set_command_field(Command::C_ECHO_RQ); this->set_affected_sop_class_uid(affected_sop_class_uid); } CEchoRequest ::CEchoRequest(Message const & message) : Request(message) { if(message.get_command_field() != Command::C_ECHO_RQ) { throw Exception("Message is not a C-ECHO-RQ"); } this->set_command_field(message.get_command_field()); this->set_affected_sop_class_uid( message.get_command_set().as_string(registry::AffectedSOPClassUID, 0)); } CEchoRequest ::~CEchoRequest() { // Nothing to do. } } } odil-0.4.1/src/odil/message/CEchoRequest.h000066400000000000000000000024761266460524100203270ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _aec786b8_0074_4cb2_b9a1_4bf26bbd20fc #define _aec786b8_0074_4cb2_b9a1_4bf26bbd20fc #include "odil/message/Request.h" #include "odil/registry.h" #include "odil/Value.h" namespace odil { namespace message { /// @brief C-ECHO-RQ message. class CEchoRequest: public Request { public: /** * @brief Create an echo request with given Message ID and * affected SOP class UID. */ CEchoRequest( Value::Integer message_id, Value::String const & affected_sop_class_uid); /** * @brief Create a C-ECHO-RQ from a generic Message. * * Raise an exception if the Message does not contain a C-ECHO-RQ. */ CEchoRequest(Message const & message); /// @brief Destructor. virtual ~CEchoRequest(); ODIL_MESSAGE_MANDATORY_FIELD_STRING_MACRO( affected_sop_class_uid, registry::AffectedSOPClassUID) }; } } #endif // _aec786b8_0074_4cb2_b9a1_4bf26bbd20fc odil-0.4.1/src/odil/message/CEchoResponse.cpp000066400000000000000000000025221266460524100210200ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "CEchoResponse.h" #include "odil/Exception.h" #include "odil/registry.h" #include "odil/message/Response.h" #include "odil/Value.h" namespace odil { namespace message { CEchoResponse ::CEchoResponse( Value::Integer message_id_being_responded_to, Value::Integer status, Value::String const & affected_sop_class_uid) : Response(message_id_being_responded_to, status) { this->set_command_field(Command::C_ECHO_RSP); this->set_affected_sop_class_uid(affected_sop_class_uid); } CEchoResponse ::CEchoResponse(Message const & message) : Response(message) { if(message.get_command_field() != Command::C_ECHO_RSP) { throw Exception("Message is not a C-ECHO-RSP"); } this->set_command_field(message.get_command_field()); this->set_affected_sop_class_uid( message.get_command_set().as_string(registry::AffectedSOPClassUID, 0)); } CEchoResponse ::~CEchoResponse() { // Nothing to do. } } } odil-0.4.1/src/odil/message/CEchoResponse.h000066400000000000000000000025631266460524100204720ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _266252d9_e801_479e_a805_004b101c5250 #define _266252d9_e801_479e_a805_004b101c5250 #include "odil/registry.h" #include "odil/message/Response.h" #include "odil/Value.h" namespace odil { namespace message { /// @brief C-ECHO-RSP message. class CEchoResponse: public Response { public: /** * @brief Create an echo response with given Message ID and * affected SOP class UID. */ CEchoResponse( Value::Integer message_id_being_responded_to, Value::Integer status, Value::String const & affected_sop_class_uid); /** * @brief Create a C-ECHO-RSP from a generic Message. * * Raise an exception if the Message does not contain a C-ECHO-RSP. */ CEchoResponse(Message const & message); /// @brief Destructor. virtual ~CEchoResponse(); ODIL_MESSAGE_MANDATORY_FIELD_STRING_MACRO( affected_sop_class_uid, registry::AffectedSOPClassUID) }; } } #endif // _266252d9_e801_479e_a805_004b101c5250 odil-0.4.1/src/odil/message/CFindRequest.cpp000066400000000000000000000033331266460524100206550ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "CFindRequest.h" #include #include "odil/Exception.h" #include "odil/registry.h" #include "odil/message/Request.h" #include "odil/Value.h" namespace odil { namespace message { CFindRequest ::CFindRequest( Value::Integer message_id, Value::String const & affected_sop_class_uid, Value::Integer priority, DataSet const & dataset) : Request(message_id) { this->set_command_field(Command::C_FIND_RQ); this->set_affected_sop_class_uid(affected_sop_class_uid); this->set_priority(priority); if(dataset.empty()) { throw Exception("Data set is required"); } this->set_data_set(dataset); } CFindRequest ::CFindRequest(Message const & message) : Request(message) { if(message.get_command_field() != Command::C_FIND_RQ) { throw Exception("Message is not a C-FIND-RQ"); } this->set_command_field(message.get_command_field()); this->set_affected_sop_class_uid( message.get_command_set().as_string(registry::AffectedSOPClassUID, 0)); this->set_priority(message.get_command_set().as_int(registry::Priority, 0)); if(!message.has_data_set() || message.get_data_set().empty()) { throw Exception("Data set is required"); } this->set_data_set(message.get_data_set()); } CFindRequest ::~CFindRequest() { // Nothing to do. } } } odil-0.4.1/src/odil/message/CFindRequest.h000066400000000000000000000027221266460524100203230ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _74cfa9e7_da35_4130_a941_e17cb6932f60 #define _74cfa9e7_da35_4130_a941_e17cb6932f60 #include "odil/registry.h" #include "odil/message/Request.h" #include "odil/Value.h" namespace odil { namespace message { /// @brief C-FIND-RQ message. class CFindRequest: public Request { public: /** * @brief Create an find request with given Message ID, * affected SOP class UID, priority, and data set. */ CFindRequest( Value::Integer message_id, Value::String const & affected_sop_class_uid, Value::Integer priority, DataSet const & dataset); /** * @brief Create a C-FIND-RQ from a generic Message. * * Raise an exception if the Message does not contain a C-FIND-RQ. */ CFindRequest(Message const & message); /// @brief Destructor. virtual ~CFindRequest(); ODIL_MESSAGE_MANDATORY_FIELD_STRING_MACRO( affected_sop_class_uid, registry::AffectedSOPClassUID) ODIL_MESSAGE_MANDATORY_FIELD_INTEGER_MACRO(priority, registry::Priority) }; } } #endif // _74cfa9e7_da35_4130_a941_e17cb6932f60 odil-0.4.1/src/odil/message/CFindResponse.cpp000066400000000000000000000034041266460524100210220ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "CFindResponse.h" #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/registry.h" #include "odil/message/Response.h" #include "odil/Value.h" namespace odil { namespace message { CFindResponse ::CFindResponse( Value::Integer message_id_being_responded_to, Value::Integer status) : Response(message_id_being_responded_to, status) { this->set_command_field(Command::C_FIND_RSP); } CFindResponse ::CFindResponse( Value::Integer message_id_being_responded_to, Value::Integer status, DataSet const & dataset) : Response(message_id_being_responded_to, status) { this->set_command_field(Command::C_FIND_RSP); this->set_data_set(dataset); } CFindResponse ::CFindResponse(Message const & message) : Response(message) { if(message.get_command_field() != Command::C_FIND_RSP) { throw Exception("Message is not a C-FIND-RSP"); } this->set_command_field(message.get_command_field()); ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), message_id, registry::MessageID, as_int) ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), affected_sop_class_uid, registry::AffectedSOPClassUID, as_string) if(message.has_data_set()) { this->set_data_set(message.get_data_set()); } } CFindResponse ::~CFindResponse() { // Nothing to do. } } } odil-0.4.1/src/odil/message/CFindResponse.h000066400000000000000000000036351266460524100204750ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _5fd36547_9498_4cf3_87cc_737af51e93a9 #define _5fd36547_9498_4cf3_87cc_737af51e93a9 #include "odil/DataSet.h" #include "odil/registry.h" #include "odil/message/Response.h" #include "odil/Value.h" namespace odil { namespace message { /// @brief C-FIND-RSP message. class CFindResponse: public Response { public: /// @brief C-FIND status codes, PS 3.4, C.4.1.1.4 enum Status { // Failure RefusedOutOfResources=0xA700, IdentifierDoesNotMatchSOPClass=0xA900, UnableToProcess=0xC000, // Pending PendingWarningOptionalKeysNotSupported=0xFF01, }; /** * @brief Create an find response with given Message ID, and status. */ CFindResponse( Value::Integer message_id_being_responded_to, Value::Integer status); /** * @brief Create an find response with given Message ID, status, * and data set. */ CFindResponse( Value::Integer message_id_being_responded_to, Value::Integer status, DataSet const & dataset); /** * @brief Create a C-FIND-RSP from a generic Message. * * Raise an exception if the Message does not contain a C-FIND-RSP. */ CFindResponse(Message const & message); /// @brief Destructor. virtual ~CFindResponse(); ODIL_MESSAGE_OPTIONAL_FIELD_INTEGER_MACRO(message_id, registry::MessageID) ODIL_MESSAGE_OPTIONAL_FIELD_STRING_MACRO( affected_sop_class_uid, registry::AffectedSOPClassUID) }; } } #endif // _5fd36547_9498_4cf3_87cc_737af51e93a9 odil-0.4.1/src/odil/message/CGetRequest.cpp000066400000000000000000000033531266460524100205160ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "CGetRequest.h" #include #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/registry.h" #include "odil/message/Request.h" #include "odil/Value.h" namespace odil { namespace message { CGetRequest ::CGetRequest( Value::Integer message_id, Value::String const & affected_sop_class_uid, Value::Integer priority, DataSet const & dataset) : Request(message_id) { this->set_command_field(Command::C_GET_RQ); this->set_affected_sop_class_uid(affected_sop_class_uid); this->set_priority(priority); if(dataset.empty()) { throw Exception("Data set is required"); } this->set_data_set(dataset); } CGetRequest ::CGetRequest(Message const & message) : Request(message) { if(message.get_command_field() != Command::C_GET_RQ) { throw Exception("Message is not a C-GET-RQ"); } this->set_command_field(message.get_command_field()); this->set_affected_sop_class_uid( message.get_command_set().as_string(registry::AffectedSOPClassUID, 0)); this->set_priority(message.get_command_set().as_int(registry::Priority, 0)); if(!message.has_data_set() || message.get_data_set().empty()) { throw Exception("Data set is required"); } this->set_data_set(message.get_data_set()); } CGetRequest ::~CGetRequest() { // Nothing to do. } } } odil-0.4.1/src/odil/message/CGetRequest.h000066400000000000000000000027401266460524100201620ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _6a22f126_7cc6_47ab_81c2_5f66b2714345 #define _6a22f126_7cc6_47ab_81c2_5f66b2714345 #include "odil/DataSet.h" #include "odil/registry.h" #include "odil/message/Request.h" #include "odil/Value.h" namespace odil { namespace message { /// @brief C-GET-RQ message. class CGetRequest: public Request { public: /** * @brief Create an get request with given Message ID, * affected SOP class UID, priority, and data set. */ CGetRequest( Value::Integer message_id, Value::String const & affected_sop_class_uid, Value::Integer priority, DataSet const & dataset); /** * @brief Create a C-GET-RQ from a generic Message. * * Raise an exception if the Message does not contain a C-GET-RQ. */ CGetRequest(Message const & message); /// @brief Destructor. virtual ~CGetRequest(); ODIL_MESSAGE_MANDATORY_FIELD_STRING_MACRO( affected_sop_class_uid, registry::AffectedSOPClassUID) ODIL_MESSAGE_MANDATORY_FIELD_INTEGER_MACRO(priority, registry::Priority) }; } } #endif // _6a22f126_7cc6_47ab_81c2_5f66b2714345 odil-0.4.1/src/odil/message/CGetResponse.cpp000066400000000000000000000046361266460524100206710ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "CGetResponse.h" #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/registry.h" #include "odil/message/Response.h" #include "odil/Value.h" namespace odil { namespace message { CGetResponse ::CGetResponse( Value::Integer message_id_being_responded_to, Value::Integer status) : Response(message_id_being_responded_to, status) { this->set_command_field(Command::C_GET_RSP); } CGetResponse ::CGetResponse( Value::Integer message_id_being_responded_to, Value::Integer status, DataSet const & dataset) : Response(message_id_being_responded_to, status) { this->set_command_field(Command::C_GET_RSP); this->set_data_set(dataset); } CGetResponse ::CGetResponse(Message const & message) : Response(message) { if(message.get_command_field() != Command::C_GET_RSP) { throw Exception("Message is not a C-GET-RSP"); } this->set_command_field(message.get_command_field()); ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), message_id, registry::MessageID, as_int) ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), affected_sop_class_uid, registry::AffectedSOPClassUID, as_string) ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), number_of_remaining_sub_operations, registry::NumberOfRemainingSuboperations, as_int) ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), number_of_completed_sub_operations, registry::NumberOfCompletedSuboperations, as_int) ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), number_of_failed_sub_operations, registry::NumberOfFailedSuboperations, as_int) ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), number_of_warning_sub_operations, registry::NumberOfWarningSuboperations, as_int) if(message.has_data_set()) { this->set_data_set(message.get_data_set()); } } CGetResponse ::~CGetResponse() { // Nothing to do. } } } odil-0.4.1/src/odil/message/CGetResponse.h000066400000000000000000000050101266460524100203210ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _7b9819f1_d7a2_4898_a850_3ed6a61f08c6 #define _7b9819f1_d7a2_4898_a850_3ed6a61f08c6 #include "odil/DataSet.h" #include "odil/registry.h" #include "odil/message/Response.h" #include "odil/Value.h" namespace odil { namespace message { /// @brief C-GET-RSP message. class CGetResponse: public Response { public: /// @brief C-GET status codes, PS 3.4, C.4.3.1.4 enum Status { // Failure RefusedOutOfResourcesUnableToCalculateNumberOfMatches=0xA701, RefusedOutOfResourcesUnableToPerformSubOperations=0xA702, IdentifierDoesNotMatchSOPClass=0xA900, UnableToProcess=0xC000, // Warning SubOperationsCompleteOneOrMoreFailuresOrWarnings=0xB000 }; /** * @brief Create an get response with given Message ID, and status. */ CGetResponse( Value::Integer message_id_being_responded_to, Value::Integer status); /** * @brief Create an get response with given Message ID, status, * and data set. */ CGetResponse( Value::Integer message_id_being_responded_to, Value::Integer status, DataSet const & dataset); /** * @brief Create a C-GET-RSP from a generic Message. * * Raise an exception if the Message does not contain a C-GET-RSP. */ CGetResponse(Message const & message); /// @brief Destructor. virtual ~CGetResponse(); ODIL_MESSAGE_OPTIONAL_FIELD_INTEGER_MACRO(message_id, registry::MessageID) ODIL_MESSAGE_OPTIONAL_FIELD_STRING_MACRO( affected_sop_class_uid, registry::AffectedSOPClassUID) ODIL_MESSAGE_OPTIONAL_FIELD_INTEGER_MACRO( number_of_remaining_sub_operations, registry::NumberOfRemainingSuboperations) ODIL_MESSAGE_OPTIONAL_FIELD_INTEGER_MACRO( number_of_completed_sub_operations, registry::NumberOfCompletedSuboperations) ODIL_MESSAGE_OPTIONAL_FIELD_INTEGER_MACRO( number_of_failed_sub_operations, registry::NumberOfFailedSuboperations) ODIL_MESSAGE_OPTIONAL_FIELD_INTEGER_MACRO( number_of_warning_sub_operations, registry::NumberOfWarningSuboperations) }; } } #endif // _7b9819f1_d7a2_4898_a850_3ed6a61f08c6 odil-0.4.1/src/odil/message/CMoveRequest.cpp000066400000000000000000000036561266460524100207130ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "CMoveRequest.h" #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/registry.h" #include "odil/message/Request.h" #include "odil/Value.h" namespace odil { namespace message { CMoveRequest ::CMoveRequest( Value::Integer message_id, Value::String const & affected_sop_class_uid, Value::Integer priority, Value::String const & move_destination, DataSet const & dataset) : Request(message_id) { this->set_command_field(Command::C_MOVE_RQ); this->set_affected_sop_class_uid(affected_sop_class_uid); this->set_priority(priority); this->set_move_destination(move_destination); if(dataset.empty()) { throw Exception("Data set is required"); } this->set_data_set(dataset); } CMoveRequest ::CMoveRequest(Message const & message) : Request(message) { if(message.get_command_field() != Command::C_MOVE_RQ) { throw Exception("Message is not a C-MOVE-RQ"); } this->set_command_field(message.get_command_field()); this->set_affected_sop_class_uid( message.get_command_set().as_string(registry::AffectedSOPClassUID, 0)); this->set_priority(message.get_command_set().as_int(registry::Priority, 0)); this->set_move_destination( message.get_command_set().as_string(registry::MoveDestination, 0)); if(!message.has_data_set() || message.get_data_set().empty()) { throw Exception("Data set is required"); } this->set_data_set(message.get_data_set()); } CMoveRequest ::~CMoveRequest() { // Nothing to do. } } } odil-0.4.1/src/odil/message/CMoveRequest.h000066400000000000000000000032161266460524100203500ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _f6e243d2_6113_4fe3_8d04_3f034fc796bf #define _f6e243d2_6113_4fe3_8d04_3f034fc796bf #include "odil/DataSet.h" #include "odil/registry.h" #include "odil/message/Request.h" #include "odil/Value.h" namespace odil { namespace message { /// @brief C-MOVE-RQ message. class CMoveRequest: public Request { public: /** * @brief Create an move request with given Message ID, * affected SOP class UID, priority, move destination, and data set. */ CMoveRequest( Value::Integer message_id, Value::String const & affected_sop_class_uid, Value::Integer priority, Value::String const & move_destination, DataSet const & dataset); /** * @brief Create a C-MOVE-RQ from a generic Message. * * Raise an exception if the Message does not contain a C-MOVE-RQ. */ CMoveRequest(Message const & message); /// @brief Destructor. virtual ~CMoveRequest(); ODIL_MESSAGE_MANDATORY_FIELD_STRING_MACRO( affected_sop_class_uid, registry::AffectedSOPClassUID) ODIL_MESSAGE_MANDATORY_FIELD_INTEGER_MACRO(priority, registry::Priority) ODIL_MESSAGE_MANDATORY_FIELD_STRING_MACRO( move_destination, registry::MoveDestination) }; } } #endif // _f6e243d2_6113_4fe3_8d04_3f034fc796bf odil-0.4.1/src/odil/message/CMoveResponse.cpp000066400000000000000000000046531266460524100210570ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "CMoveResponse.h" #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/registry.h" #include "odil/message/Response.h" #include "odil/Value.h" namespace odil { namespace message { CMoveResponse ::CMoveResponse( Value::Integer message_id_being_responded_to, Value::Integer status) : Response(message_id_being_responded_to, status) { this->set_command_field(Command::C_MOVE_RSP); } CMoveResponse ::CMoveResponse( Value::Integer message_id_being_responded_to, Value::Integer status, DataSet const & dataset) : Response(message_id_being_responded_to, status) { this->set_command_field(Command::C_MOVE_RSP); this->set_data_set(dataset); } CMoveResponse ::CMoveResponse(Message const & message) : Response(message) { if(message.get_command_field() != Command::C_MOVE_RSP) { throw Exception("Message is not a C-MOVE-RSP"); } this->set_command_field(message.get_command_field()); ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), message_id, registry::MessageID, as_int) ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), affected_sop_class_uid, registry::AffectedSOPClassUID, as_string) ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), number_of_remaining_sub_operations, registry::NumberOfRemainingSuboperations, as_int) ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), number_of_completed_sub_operations, registry::NumberOfCompletedSuboperations, as_int) ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), number_of_failed_sub_operations, registry::NumberOfFailedSuboperations, as_int) ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), number_of_warning_sub_operations, registry::NumberOfWarningSuboperations, as_int) if(message.has_data_set()) { this->set_data_set(message.get_data_set()); } } CMoveResponse ::~CMoveResponse() { // Nothing to do. } } } odil-0.4.1/src/odil/message/CMoveResponse.h000066400000000000000000000051011266460524100205110ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _b245f6f2_50c3_4c7c_80e1_f03d9c831301 #define _b245f6f2_50c3_4c7c_80e1_f03d9c831301 #include "odil/DataSet.h" #include "odil/registry.h" #include "odil/message/Response.h" #include "odil/Value.h" namespace odil { namespace message { /// @brief C-MOVE-RSP message. class CMoveResponse: public Response { public: /// @brief C-MOVE status codes, PS 3.4, C.4.2.1.5 enum Status { // Failure RefusedOutOfResourcesUnableToCalculateNumberOfMatches=0xA701, RefusedOutOfResourcesUnableToPerformSubOperations=0xA702, RefusedMoveDestinationUnknown=0xA801, IdentifierDoesNotMatchSOPClass=0xA900, UnableToProcess=0xC000, // Warning SubOperationsCompleteOneOrMoreFailuresOrWarnings=0xB000 }; /** * @brief Create an move response with given Message ID, and status. */ CMoveResponse( Value::Integer message_id_being_responded_to, Value::Integer status); /** * @brief Create an move response with given Message ID, status, * and data set. */ CMoveResponse( Value::Integer message_id_being_responded_to, Value::Integer status, DataSet const & dataset); /** * @brief Create a C-MOVE-RSP from a generic Message. * * Raise an exception if the Message does not contain a C-MOVE-RSP. */ CMoveResponse(Message const & message); /// @brief Destructor. virtual ~CMoveResponse(); ODIL_MESSAGE_OPTIONAL_FIELD_INTEGER_MACRO(message_id, registry::MessageID) ODIL_MESSAGE_OPTIONAL_FIELD_STRING_MACRO( affected_sop_class_uid, registry::AffectedSOPClassUID) ODIL_MESSAGE_OPTIONAL_FIELD_INTEGER_MACRO( number_of_remaining_sub_operations, registry::NumberOfRemainingSuboperations) ODIL_MESSAGE_OPTIONAL_FIELD_INTEGER_MACRO( number_of_completed_sub_operations, registry::NumberOfCompletedSuboperations) ODIL_MESSAGE_OPTIONAL_FIELD_INTEGER_MACRO( number_of_failed_sub_operations, registry::NumberOfFailedSuboperations) ODIL_MESSAGE_OPTIONAL_FIELD_INTEGER_MACRO( number_of_warning_sub_operations, registry::NumberOfWarningSuboperations) }; } } #endif // _b245f6f2_50c3_4c7c_80e1_f03d9c831301 odil-0.4.1/src/odil/message/CStoreRequest.cpp000066400000000000000000000043601266460524100210720ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "CStoreRequest.h" #include #include "odil/Exception.h" #include "odil/message/Request.h" namespace odil { namespace message { CStoreRequest ::CStoreRequest( Value::Integer message_id, Value::String const & affected_sop_class_uid, Value::String const & affected_sop_instance_uid, Value::Integer priority, DataSet const & dataset) : Request(message_id) { this->set_command_field(Command::C_STORE_RQ); this->set_affected_sop_class_uid(affected_sop_class_uid); this->set_affected_sop_instance_uid(affected_sop_instance_uid); this->set_priority(priority); if(dataset.empty()) { throw Exception("Data set is required"); } this->set_data_set(dataset); } CStoreRequest ::CStoreRequest(Message const & message) : Request(message) { if(message.get_command_field() != Command::C_STORE_RQ) { throw Exception("Message is not a C-STORE-RQ"); } this->set_command_field(message.get_command_field()); this->set_affected_sop_class_uid( message.get_command_set().as_string(registry::AffectedSOPClassUID, 0)); this->set_affected_sop_instance_uid( message.get_command_set().as_string(registry::AffectedSOPInstanceUID, 0)); this->set_priority(message.get_command_set().as_int(registry::Priority, 0)); ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), move_originator_ae_title, registry::MoveOriginatorApplicationEntityTitle, as_string) ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), move_originator_message_id, registry::MoveOriginatorMessageID, as_int) if(!message.has_data_set() || message.get_data_set().empty()) { throw Exception("Data set is required"); } this->set_data_set(message.get_data_set()); } CStoreRequest ::~CStoreRequest() { // Nothing to do. } } } odil-0.4.1/src/odil/message/CStoreRequest.h000066400000000000000000000036521266460524100205420ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _b85a19af_b74d_4c96_89a0_f30a41b790b3 #define _b85a19af_b74d_4c96_89a0_f30a41b790b3 #include #include "odil/DataSet.h" #include "odil/registry.h" #include "odil/message/Request.h" #include "odil/Value.h" namespace odil { namespace message { /// @brief C-STORE-RQ message. class CStoreRequest: public Request { public: /** * @brief Create an store request with given Message ID, * affected SOP class UID, priority, and data set. */ CStoreRequest( Value::Integer message_id, Value::String const & affected_sop_class_uid, Value::String const & affected_sop_instance_uid, Value::Integer priority, DataSet const & dataset); /** * @brief Create a C-STORE-RQ from a generic Message. * * Raise an exception if the Message does not contain a C-STORE-RQ. */ CStoreRequest(Message const & message); /// @brief Destructor. virtual ~CStoreRequest(); ODIL_MESSAGE_MANDATORY_FIELD_STRING_MACRO( affected_sop_class_uid, registry::AffectedSOPClassUID) ODIL_MESSAGE_MANDATORY_FIELD_STRING_MACRO( affected_sop_instance_uid, registry::AffectedSOPInstanceUID) ODIL_MESSAGE_MANDATORY_FIELD_INTEGER_MACRO(priority, registry::Priority) ODIL_MESSAGE_OPTIONAL_FIELD_STRING_MACRO( move_originator_ae_title, registry::MoveOriginatorApplicationEntityTitle) ODIL_MESSAGE_OPTIONAL_FIELD_INTEGER_MACRO( move_originator_message_id, registry::MoveOriginatorMessageID) }; } } #endif // _b85a19af_b74d_4c96_89a0_f30a41b790b3 odil-0.4.1/src/odil/message/CStoreResponse.cpp000066400000000000000000000033051266460524100212360ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "CStoreResponse.h" #include "odil/Exception.h" #include "odil/registry.h" #include "odil/message/Response.h" #include "odil/Value.h" namespace odil { namespace message { CStoreResponse ::CStoreResponse( Value::Integer message_id_being_responded_to, Value::Integer status) : Response(message_id_being_responded_to, status) { this->set_command_field(Command::C_STORE_RSP); } CStoreResponse ::CStoreResponse(Message const & message) : Response(message) { if(message.get_command_field() != Command::C_STORE_RSP) { throw Exception("Message is not a C-STORE-RSP"); } this->set_command_field(message.get_command_field()); ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), message_id, registry::MessageID, as_int) ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), affected_sop_class_uid, registry::AffectedSOPClassUID, as_string) ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO( message.get_command_set(), affected_sop_instance_uid, registry::AffectedSOPInstanceUID, as_string) if(message.has_data_set() && !message.get_data_set().empty()) { throw Exception("Data set must not be present"); } this->delete_data_set(); } CStoreResponse ::~CStoreResponse() { // Nothing to do. } } } odil-0.4.1/src/odil/message/CStoreResponse.h000066400000000000000000000035241266460524100207060ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _7e193624_081c_47dd_a011_986e96916ea9 #define _7e193624_081c_47dd_a011_986e96916ea9 #include "odil/registry.h" #include "odil/message/Response.h" #include "odil/Value.h" namespace odil { namespace message { /// @brief C-STORE-RSP message. class CStoreResponse: public Response { public: /// @brief C-STORE status codes, PS 3.4, B.2.3 enum Status { // Failure RefusedOutOfResources=0xA700, ErrorDataSetDoesNotMatchSOPClass=0xA900, ErrorCannotUnderstand=0xC000, // Warning CoercionOfDataElements=0xB000, DataSetDoesNotMatchSOPClass=0xB007, ElementsDiscarded=0xB006, }; /** * @brief Create an store response with given Message ID, and status. */ CStoreResponse( Value::Integer message_id_being_responded_to, Value::Integer status); /** * @brief Create a C-STORE-RSP from a generic Message. * * Raise an exception if the Message does not contain a C-STORE-RSP. */ CStoreResponse(Message const & message); /// @brief Destructor. virtual ~CStoreResponse(); ODIL_MESSAGE_OPTIONAL_FIELD_INTEGER_MACRO(message_id, registry::MessageID) ODIL_MESSAGE_OPTIONAL_FIELD_STRING_MACRO( affected_sop_class_uid, registry::AffectedSOPClassUID) ODIL_MESSAGE_OPTIONAL_FIELD_STRING_MACRO( affected_sop_instance_uid, registry::AffectedSOPInstanceUID) }; } } #endif // _7e193624_081c_47dd_a011_986e96916ea9 odil-0.4.1/src/odil/message/Cancellation.cpp000066400000000000000000000023401266460524100207120ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/message/Cancellation.h" #include "odil/Exception.h" #include "odil/message/Message.h" #include "odil/registry.h" #include "odil/Value.h" namespace odil { namespace message { Cancellation ::Cancellation(uint16_t message_id_being_responded_to) : Message() { this->set_command_field(Command::C_CANCEL_RQ); this->set_message_id_being_responded_to(message_id_being_responded_to); } Cancellation ::Cancellation(Message const & message) { if(message.get_command_field() != Command::C_CANCEL_RQ) { throw Exception("Message is not a C-CANCEL-RQ"); } this->set_command_field(message.get_command_field()); this->set_message_id_being_responded_to( message.get_command_set().as_int(registry::MessageIDBeingRespondedTo, 0)); } Cancellation ::~Cancellation() { // Nothing to do. } } } odil-0.4.1/src/odil/message/Cancellation.h000066400000000000000000000023751266460524100203670ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _97fc1bfc_4cff_40f2_a1ed_4550c71a0bda #define _97fc1bfc_4cff_40f2_a1ed_4550c71a0bda #include "odil/message/Message.h" #include "odil/registry.h" #include "odil/Value.h" namespace odil { namespace message { /// @brief Base class for cancellation messages. class Cancellation: public Message { public: /// @brief Create a response with given message id being responded to. Cancellation(uint16_t message_id_being_responded_to); /** * @brief Create a response from the Message ID Being Responded To. * * Raise an exception is this element is missing. */ Cancellation(Message const & message); /// @brief Destructor. ~Cancellation(); ODIL_MESSAGE_MANDATORY_FIELD_INTEGER_MACRO( message_id_being_responded_to, registry::MessageIDBeingRespondedTo); }; } } #endif // _97fc1bfc_4cff_40f2_a1ed_4550c71a0bda odil-0.4.1/src/odil/message/Message.cpp000066400000000000000000000040171266460524100177050ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "Message.h" #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/registry.h" #include "odil/Value.h" namespace odil { namespace message { Message ::Message() { this->_command_set.add(registry::CommandDataSetType, { DataSetType::ABSENT }); } Message ::Message(DataSet const & command_set) : _command_set(command_set) { if(!this->_command_set.has(registry::CommandDataSetType)) { this->_command_set.add(registry::CommandDataSetType, VR::US); } this->_command_set.as_int(registry::CommandDataSetType) = { DataSetType::ABSENT }; } Message ::Message(DataSet const & command_set, DataSet const & data_set) : _command_set(command_set) { if(!this->_command_set.has(registry::CommandDataSetType)) { this->_command_set.add(registry::CommandDataSetType, VR::US); } this->set_data_set(data_set); } Message ::~Message() { // Nothing to do. } DataSet const & Message ::get_command_set() const { return this->_command_set; } bool Message ::has_data_set() const { return (this->_command_set.as_int(registry::CommandDataSetType, 0) == DataSetType::PRESENT); } DataSet const & Message ::get_data_set() const { if(!this->has_data_set()) { throw Exception("No data set in message"); } return this->_data_set; } void Message ::set_data_set(DataSet const & data_set) { this->_data_set = data_set; this->_command_set.as_int(registry::CommandDataSetType) = { DataSetType::PRESENT }; } void Message ::delete_data_set() { this->_command_set.as_int(registry::CommandDataSetType) = { DataSetType::ABSENT }; this->_data_set = DataSet(); } } } odil-0.4.1/src/odil/message/Message.h000066400000000000000000000112751266460524100173560ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _dcfa5213_ad7e_4194_8b4b_e630aa0df2e8 #define _dcfa5213_ad7e_4194_8b4b_e630aa0df2e8 #include "odil/DataSet.h" #include "odil/registry.h" #include "odil/Value.h" namespace odil { namespace message { #define ODIL_MESSAGE_MANDATORY_FIELD_MACRO(name, tag, TValueType, function) \ /** @brief Return the tag element of the command set. */ \ TValueType const & get_##name() const \ { \ auto const & data = this->_command_set.function(tag); \ if(data.empty()) \ { \ throw Exception("Empty element"); \ } \ return data[0]; \ } \ /** @brief Set the tag element of the command set. */ \ void set_##name(TValueType const & value) \ { \ if(!this->_command_set.has(tag)) \ { \ this->_command_set.add(tag); \ } \ this->_command_set.function(tag) = { value }; \ } #define ODIL_MESSAGE_OPTIONAL_FIELD_MACRO(name, tag, TValueType, function) \ ODIL_MESSAGE_MANDATORY_FIELD_MACRO(name, tag, TValueType, function) \ bool has_##name() const \ { \ return this->_command_set.has(tag);; \ } \ void delete_##name() \ { \ this->_command_set.remove(tag); \ } #define ODIL_MESSAGE_SET_OPTIONAL_FIELD_MACRO(dataset, name, tag, function) \ if(dataset.has(tag)) \ { \ this->set_##name(dataset.function(tag, 0)); \ } #define ODIL_MESSAGE_MANDATORY_FIELD_INTEGER_MACRO(name, tag) \ ODIL_MESSAGE_MANDATORY_FIELD_MACRO(name, tag, Value::Integer, as_int) #define ODIL_MESSAGE_MANDATORY_FIELD_STRING_MACRO(name, tag) \ ODIL_MESSAGE_MANDATORY_FIELD_MACRO(name, tag, Value::String, as_string) #define ODIL_MESSAGE_OPTIONAL_FIELD_INTEGER_MACRO(name, tag) \ ODIL_MESSAGE_OPTIONAL_FIELD_MACRO(name, tag, Value::Integer, as_int) #define ODIL_MESSAGE_OPTIONAL_FIELD_STRING_MACRO(name, tag) \ ODIL_MESSAGE_OPTIONAL_FIELD_MACRO(name, tag, Value::String, as_string) /** * @brief Base class for all DIMSE messages. */ class Message { public: struct Command { enum Type { C_STORE_RQ = 0x0001, C_STORE_RSP = 0x8001, C_FIND_RQ = 0x0020, C_FIND_RSP = 0x8020, C_CANCEL_RQ = 0x0FFF, C_GET_RQ = 0x0010, C_GET_RSP = 0x8010, C_MOVE_RQ = 0x0021, C_MOVE_RSP = 0x8021, C_ECHO_RQ = 0x0030, C_ECHO_RSP = 0x8030, N_EVENT_REPORT_RQ = 0x0100, N_EVENT_REPORT_RSP = 0x8100, N_GET_RQ = 0x0110, N_GET_RSP = 0x8110, N_SET_RQ = 0x0120, N_SET_RSP = 0x8120, N_ACTION_RQ = 0x0130, N_ACTION_RSP = 0x8130, N_CREATE_RQ = 0x0140, N_CREATE_RSP = 0x8140, N_DELETE_RQ = 0x0150, N_DELETE_RSP = 0x8150, }; }; struct Priority { enum Type { LOW = 0x0002, MEDIUM = 0x0000, HIGH = 0x0001, }; }; struct DataSetType { enum Type { PRESENT = 0x0000, ABSENT = 0x0101, }; }; /// @brief Create a message with an empty command set and an empty data set. Message(); /// @brief Create a message from existing data. Message(DataSet const & command_set); /// @brief Create a message from existing data. Message(DataSet const & command_set, DataSet const & data_set); /// @brief Destructor; virtual ~Message(); /// @brief Return the command set of the message. DataSet const & get_command_set() const; /// @brief Test whether as data set is present in the message. bool has_data_set() const; /** * @brief Return the data set of the message, raise an exception if no * data set is present. */ DataSet const & get_data_set() const; /// @brief Set the data set of the message. void set_data_set(DataSet const & data_set); /// @brief Delete the data set in this message. void delete_data_set(); ODIL_MESSAGE_MANDATORY_FIELD_INTEGER_MACRO( command_field, registry::CommandField) protected: /// @brief Command set of the message. DataSet _command_set; /// @brief Data set of the message. DataSet _data_set; }; } } #endif // _dcfa5213_ad7e_4194_8b4b_e630aa0df2e8 odil-0.4.1/src/odil/message/Request.cpp000066400000000000000000000015221266460524100177470ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "Request.h" #include "odil/message/Message.h" #include "odil/registry.h" #include "odil/Value.h" namespace odil { namespace message { Request ::Request(Value::Integer message_id) : Message() { this->set_message_id(message_id); } Request ::Request(Message const & message) : Message() { this->set_message_id(message.get_command_set().as_int(registry::MessageID, 0)); } Request ::~Request() { // Nothing to do. } } } odil-0.4.1/src/odil/message/Request.h000066400000000000000000000023241266460524100174150ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _8d06a300_6aee_4d1f_bf10_ecdf4916ae9f #define _8d06a300_6aee_4d1f_bf10_ecdf4916ae9f #include "odil/message/Message.h" #include "odil/registry.h" #include "odil/Value.h" namespace odil { namespace message { /// @brief Base class for all DIMSE request messages. class Request: public Message { public: /// @brief Create a request with given Message ID. Request(Value::Integer message_id); /** * @brief Create a request from the Message ID stored in the message * command set. * * Raise an exception is either of this element is missing. */ Request(Message const & message); /// @brief Destructor. virtual ~Request(); ODIL_MESSAGE_MANDATORY_FIELD_INTEGER_MACRO( message_id, registry::MessageID) }; } } #endif // _8d06a300_6aee_4d1f_bf10_ecdf4916ae9f odil-0.4.1/src/odil/message/Response.cpp000066400000000000000000000036171266460524100201240ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "Response.h" #include "odil/message/Message.h" #include "odil/registry.h" #include "odil/Value.h" namespace odil { namespace message { bool Response ::is_pending(Value::Integer status) { return (status == Response::Pending || status == 0xFF01); } bool Response ::is_warning(Value::Integer status) { return ( status == 0x0001 || (status>>12) == 0xB || status == Response::AttributeListError || status == Response::AttributeValueOutOfRange); } bool Response ::is_failure(Value::Integer status) { return ( (status>>12) == 0xA || (status>>12) == 0xC || ((status>>8) == 0x01 && !is_warning(status)) || (status>>8) == 0x02 ); } Response ::Response(Value::Integer message_id_being_responded_to, Value::Integer status) : Message() { this->set_message_id_being_responded_to(message_id_being_responded_to); this->set_status(status); } Response ::Response(Message const & message) : Message() { this->set_message_id_being_responded_to( message.get_command_set().as_int( registry::MessageIDBeingRespondedTo, 0)); this->set_status(message.get_command_set().as_int(registry::Status, 0)); } Response ::~Response() { // Nothing to do. } bool Response ::is_pending() const { return Response::is_pending(this->get_status()); } bool Response ::is_warning() const { return Response::is_warning(this->get_status()); } bool Response ::is_failure() const { return Response::is_failure(this->get_status()); } } } odil-0.4.1/src/odil/message/Response.h000066400000000000000000000060521266460524100175650ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _0dd2e31e_212a_494a_a8d3_93b235336658 #define _0dd2e31e_212a_494a_a8d3_93b235336658 #include "odil/message/Message.h" #include "odil/registry.h" #include "odil/Value.h" namespace odil { namespace message { /// @brief Base class for all DIMSE response messages. class Response: public Message { public: /// @brief General status codes, from PS3.7, C enum Status { Success=0x0000, // Warning: 0001 or Bxxx // Failure: Axxx or Cxxx Cancel=0xFE00, Pending=0xFF00, // Warning Status Classes, PS3.7, C.3 AttributeListError=0x0107, AttributeValueOutOfRange=0x0116, // Failure Status Classes, PS3.7, C.4 SOPClassNotSupported=0x0122, ClassInstanceConflict=0x0119, DuplicateSOPInstance=0x0111, DuplicateInvocation=0x0210, InvalidArgumentValue=0x0115, InvalidAttributeValue=0x0106, InvalidObjectInstance=0x0117, MissingAttribute=0x0120, MissingAttributeValue=0x0121, MistypedArgument=0x0212, NoSuchArgument=0x0114, NoSuchAttribute=0x0105, NoSuchEventType=0x0113, NoSuchSOPInstance=0x0112, NoSuchSOPClass=0x0118, ProcessingFailure=0x0110, ResourceLimitation=0x0213, UnrecognizedOperation=0x0211, NoSuchActionType=0x0123, RefusedNotAuthorized=0x0124, }; /// @brief Test whether the status class is pending. static bool is_pending(Value::Integer status); /// @brief Test whether the status class is warning. static bool is_warning(Value::Integer status); /// @brief Test whether the status class is failure. static bool is_failure(Value::Integer status); /// @brief Create a response with given message id and status; Response(Value::Integer message_id_being_responded_to, Value::Integer status); /** * @brief Create a response from the Message ID Being Responded To and the * Status stored in the message command set. * * Raise an exception is either of those elements is missing. */ Response(Message const & message); /// @brief Destructor. virtual ~Response(); ODIL_MESSAGE_MANDATORY_FIELD_INTEGER_MACRO( message_id_being_responded_to, registry::MessageIDBeingRespondedTo) ODIL_MESSAGE_MANDATORY_FIELD_INTEGER_MACRO(status, registry::Status) /// @brief Test whether the status class is pending. bool is_pending() const; /// @brief Test whether the status class is warning. bool is_warning() const; /// @brief Test whether the status class is failure. bool is_failure() const; }; } } #endif // _0dd2e31e_212a_494a_a8d3_93b235336658 odil-0.4.1/src/odil/pdu/000077500000000000000000000000001266460524100147575ustar00rootroot00000000000000odil-0.4.1/src/odil/pdu/AAbort.cpp000066400000000000000000000043541266460524100166410ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/AAbort.h" #include #include #include "odil/Exception.h" #include "odil/pdu/Object.h" namespace odil { namespace pdu { AAbort ::AAbort(unsigned char source, unsigned char reason) { this->_item.add("PDU-type", uint8_t(0x07)); this->_item.add("Reserved-1", uint8_t(0)); this->_item.add("PDU-length", uint32_t(4)); this->_item.add("Reserved-2", uint8_t(0)); this->_item.add("Reserved-3", uint8_t(0)); this->_item.add("Source", uint8_t(0)); this->_item.add("Reason", uint8_t(0)); this->set_source(source); this->set_reason(reason); } AAbort ::AAbort(std::istream & stream) { this->_item.read(stream, "PDU-type", Item::Field::Type::unsigned_int_8); if(this->_item.as_unsigned_int_8("PDU-type") != 0x07) { throw Exception("Invalid PDU type"); } this->_item.read(stream, "Reserved-1", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "PDU-length", Item::Field::Type::unsigned_int_32); this->_item.read(stream, "Reserved-2", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Reserved-3", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Source", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Reason", Item::Field::Type::unsigned_int_8); } unsigned char AAbort ::get_source() const { return this->_item.as_unsigned_int_8("Source"); } void AAbort ::set_source(unsigned char source) { if(source > 2) { throw Exception("Unknown source"); } this->_item.as_unsigned_int_8("Source") = source; } unsigned char AAbort ::get_reason() const { return this->_item.as_unsigned_int_8("Reason"); } void AAbort ::set_reason(unsigned char reason) { if(reason > 6) { throw Exception("Unknown reason"); } this->_item.as_unsigned_int_8("Reason") = reason; } } } odil-0.4.1/src/odil/pdu/AAbort.h000066400000000000000000000023131266460524100162770ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _536f93f0_914e_40ff_8917_36644acbc4b1 #define _536f93f0_914e_40ff_8917_36644acbc4b1 #include #include "odil/pdu/Object.h" namespace odil { namespace pdu { /// @brief A-ABORT PDU, cf. PS 3.8, 9.3.8. class AAbort: public Object { public: /// @brief Constructor. AAbort(unsigned char source, unsigned char reason); /// @brief Constructor for binary data. AAbort(std::istream & stream); /// @brief Return the source. unsigned char get_source() const; /// @brief Set the source, must be 0, 1 or 2. void set_source(unsigned char source); /// @brief Return the reason. unsigned char get_reason() const; /// @brief Set the reason, must be between 0 and 6. void set_reason(unsigned char reason); }; } } #endif // _536f93f0_914e_40ff_8917_36644acbc4b1 odil-0.4.1/src/odil/pdu/AAssociate.cpp000066400000000000000000000161631266460524100175060ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/AAssociate.h" #include #include #include #include #include #include #include "odil/Exception.h" #include "odil/pdu/ApplicationContext.h" #include "odil/pdu/Item.h" #include "odil/pdu/Object.h" #include "odil/pdu/PresentationContextAC.h" #include "odil/pdu/PresentationContextRQ.h" #include "odil/pdu/UserInformation.h" namespace odil { namespace pdu { AAssociate ::AAssociate() { this->_item.add("PDU-type", uint8_t(0)); this->_item.add("Reserved-1", uint8_t(0)); this->_item.add("PDU-length", uint32_t(0)); this->_item.add("Protocol-version", uint16_t(0)); this->_item.add("Reserved-2", uint16_t(0)); this->_item.add("Called-AE-title", std::string()); this->_item.add("Calling-AE-title", std::string()); this->_item.add("Reserved-3", std::string(32, '\0')); this->_item.add("Variable-items", std::vector()); this->_item.as_unsigned_int_32("PDU-length") = this->_compute_length(); } AAssociate ::AAssociate(std::istream & stream) { this->_item.read(stream, "PDU-type", Item::Field::Type::unsigned_int_8); auto const type = this->_item.as_unsigned_int_8("PDU-type"); if(type != 0x01 && type != 0x02) { throw Exception("Invalid PDU type"); } this->_item.read(stream, "Reserved-1", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "PDU-length", Item::Field::Type::unsigned_int_32); auto const begin = stream.tellg(); this->_item.read( stream, "Protocol-version", Item::Field::Type::unsigned_int_16); this->_item.read(stream, "Reserved-2", Item::Field::Type::unsigned_int_16); this->_item.read(stream, "Called-AE-title", Item::Field::Type::string, 16); this->_item.read(stream, "Calling-AE-title", Item::Field::Type::string, 16); this->_item.read(stream, "Reserved-3", Item::Field::Type::string, 32); auto const length = this->_item.as_unsigned_int_32("PDU-length"); this->_item.add("Variable-items", std::vector()); auto & variable_items = this->_item.as_items("Variable-items"); while(stream.tellg()-begin < length) { auto const type = stream.peek(); Item sub_item; if(type == 0x10) { sub_item = ApplicationContext(stream).get_item(); } else if(type == 0x20) { sub_item = PresentationContextRQ(stream).get_item(); } else if(type == 0x21) { sub_item = PresentationContextAC(stream).get_item(); } else if(type == 0x50) { sub_item = UserInformation(stream).get_item(); } else { throw Exception("Invalid sub-item"); } variable_items.push_back(sub_item); } this->_item.as_unsigned_int_32("PDU-length") = this->_compute_length(); } AAssociate ::~AAssociate() { // Nothing to do. } uint16_t AAssociate ::get_protocol_version() const { return this->_item.as_unsigned_int_16("Protocol-version"); } void AAssociate ::set_protocol_version(uint16_t value) { this->_item.as_unsigned_int_16("Protocol-version") = value; } std::string AAssociate ::get_called_ae_title() const { return this->_decode_ae_title(this->_item.as_string("Called-AE-title")); } void AAssociate ::set_called_ae_title(std::string const & value) { this->_item.as_string("Called-AE-title") = this->_encode_ae_title(value); } std::string AAssociate ::get_calling_ae_title() const { return this->_decode_ae_title(this->_item.as_string("Calling-AE-title")); } void AAssociate ::set_calling_ae_title(std::string const & value) { this->_item.as_string("Calling-AE-title") = this->_encode_ae_title(value); } ApplicationContext AAssociate ::get_application_context() const { auto const & sub_items = this->_item.as_items("Variable-items"); auto const it = std::find_if( sub_items.begin(), sub_items.end(), [](Item const & x) { return x.as_unsigned_int_8("Item-type") == 0x10; }); if(it == sub_items.end()) { throw Exception("No Application Context"); } std::stringstream stream; stream << *it; return ApplicationContext(stream); } void AAssociate ::set_application_context(ApplicationContext const & value) { auto const & old_items = this->_item.as_items("Variable-items"); std::vector new_items; new_items.push_back(value.get_item()); std::copy_if( old_items.begin(), old_items.end(), std::back_inserter(new_items), [](Item const & item) { return item.as_unsigned_int_8("Item-type") == 0x21; }); std::copy_if( old_items.begin(), old_items.end(), std::back_inserter(new_items), [](Item const & item) { return item.as_unsigned_int_8("Item-type") == 0x50; }); this->_item.as_items("Variable-items") = new_items; this->_item.as_unsigned_int_32("PDU-length") = this->_compute_length(); } UserInformation AAssociate ::get_user_information() const { auto const & sub_items = this->_item.as_items("Variable-items"); auto const it = std::find_if( sub_items.begin(), sub_items.end(), [](Item const & x) { return x.as_unsigned_int_8("Item-type") == 0x50; }); if(it == sub_items.end()) { throw Exception("No User Information"); } std::stringstream stream; stream << *it; return UserInformation(stream); } void AAssociate ::set_user_information(UserInformation const & value) { auto const & old_items = this->_item.as_items("Variable-items"); std::vector new_items; std::copy_if( old_items.begin(), old_items.end(), std::back_inserter(new_items), [](Item const & item) { return item.as_unsigned_int_8("Item-type") == 0x10; }); std::copy_if( old_items.begin(), old_items.end(), std::back_inserter(new_items), [](Item const & item) { return ( item.as_unsigned_int_8("Item-type") == 0x20 || item.as_unsigned_int_8("Item-type") == 0x21); }); new_items.push_back(value.get_item()); this->_item.as_items("Variable-items") = new_items; this->_item.as_unsigned_int_32("PDU-length") = this->_compute_length(); } std::string AAssociate ::_encode_ae_title(std::string const & value) { if(value.empty() || value.size() > 16) { throw Exception("Invalid AE title"); } auto const padded = value+std::string(16-value.size(), ' '); return padded; } std::string AAssociate ::_decode_ae_title(std::string const & value) { auto const begin = value.find_first_not_of(' '); if(begin == std::string::npos) { return ""; } else { auto const end = value.find_last_not_of(' '); return value.substr(begin, end-begin+1); } } } } odil-0.4.1/src/odil/pdu/AAssociate.h000066400000000000000000000050371266460524100171510ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _00e9792a_98a8_4ca7_9272_43dcd7e331ea #define _00e9792a_98a8_4ca7_9272_43dcd7e331ea #include #include #include #include "odil/pdu/ApplicationContext.h" #include "odil/pdu/Object.h" #include "odil/pdu/UserInformation.h" namespace odil { namespace pdu { /// @brief A-ASSOCIATE-RQ and A-ASSOCIATE-AC PDU, cf. PS 3.8, 9.3.2 and 9.3.3. class AAssociate: public Object { public: /// @brief Constructor. AAssociate(); /// @brief Constructor for binary data. AAssociate(std::istream & stream); /// @brief Destructor. virtual ~AAssociate() =0; /// @brief Return the protocol version. uint16_t get_protocol_version() const; /// @brief Set the protocol version. void set_protocol_version(uint16_t value); /// @brief Return the called AE title. std::string get_called_ae_title() const; /** * @brief Set the called AE title. * * An exception is raised if the value is empty or if it is longer than * 16 characters. */ void set_called_ae_title(std::string const & value); /// @brief Return the calling AE title. std::string get_calling_ae_title() const; /** * @brief Set the calling AE title. * * An exception is raised if the value is empty or if it is longer than * 16 characters. */ void set_calling_ae_title(std::string const & value); /// @brief Return the Application Context sub-item. ApplicationContext get_application_context() const; /// @brief Set the Application Context sub-item. void set_application_context(ApplicationContext const & value); /// @brief Return the User Information sub-item. UserInformation get_user_information() const; /// @brief Set the User Information sub-item. void set_user_information(UserInformation const & value); private: /// @brief Pad the value with spaces so that it is 16 characters long. static std::string _encode_ae_title(std::string const & value); /// @brief Remove the leading and trailing spaces. static std::string _decode_ae_title(std::string const & value); }; } } #endif // _00e9792a_98a8_4ca7_9272_43dcd7e331ea odil-0.4.1/src/odil/pdu/AAssociateAC.cpp000066400000000000000000000044211266460524100177040ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/AAssociateAC.h" #include #include #include #include "odil/Exception.h" #include "odil/pdu/AAssociate.h" #include "odil/pdu/PresentationContextAC.h" namespace odil { namespace pdu { AAssociateAC ::AAssociateAC() : AAssociate() { this->_item.as_unsigned_int_8("PDU-type") = 0x02; } AAssociateAC ::AAssociateAC(std::istream & stream) : AAssociate(stream) { if(this->_item.as_unsigned_int_8("PDU-type") != 0x02) { throw Exception("Invalid PDU type"); } } AAssociateAC ::~AAssociateAC() { // Nothing to do. } std::vector AAssociateAC ::get_presentation_contexts() const { std::vector result; for(auto const & item: this->_item.as_items("Variable-items")) { if(item.as_unsigned_int_8("Item-type") == 0x21) { std::stringstream stream; stream << item; result.push_back(PresentationContextAC(stream)); } } return result; } void AAssociateAC ::set_presentation_contexts(std::vector const & value) { auto const & old_items = this->_item.as_items("Variable-items"); std::vector new_items; std::copy_if( old_items.begin(), old_items.end(), std::back_inserter(new_items), [](Item const & item) { return item.as_unsigned_int_8("Item-type") == 0x10; }); std::transform( value.begin(), value.end(), std::back_inserter(new_items), [](PresentationContext const & x) { return x.get_item(); }); std::copy_if( old_items.begin(), old_items.end(), std::back_inserter(new_items), [](Item const & item) { return item.as_unsigned_int_8("Item-type") == 0x50; }); this->_item.as_items("Variable-items") = new_items; this->_item.as_unsigned_int_32("PDU-length") = this->_compute_length(); } } } odil-0.4.1/src/odil/pdu/AAssociateAC.h000066400000000000000000000023351266460524100173530ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _973ae1d9_c41c_4518_9c35_df13b2253369 #define _973ae1d9_c41c_4518_9c35_df13b2253369 #include #include "odil/pdu/AAssociate.h" #include "odil/pdu/PresentationContextAC.h" namespace odil { namespace pdu { /// @brief A-ASSOCIATE-AC PDU, cf. PS 3.8, 9.3.3. class AAssociateAC: public AAssociate { public: /// @brief Constructor. AAssociateAC(); /// @brief Constructor for binary data. AAssociateAC(std::istream & stream); /// @brief Destructor. ~AAssociateAC(); /// @brief Return the Presentation Context sub-items. std::vector get_presentation_contexts() const; /// @brief Set the Presentation Context sub-items. void set_presentation_contexts(std::vector const & value); }; } } #endif // _973ae1d9_c41c_4518_9c35_df13b2253369 odil-0.4.1/src/odil/pdu/AAssociateRJ.cpp000066400000000000000000000051621266460524100177370ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/AAssociateRJ.h" #include #include #include "odil/Exception.h" #include "odil/pdu/Object.h" namespace odil { namespace pdu { AAssociateRJ ::AAssociateRJ(unsigned char result, unsigned char source, unsigned char reason) { this->_item.add("PDU-type", uint8_t(0x03)); this->_item.add("Reserved-1", uint8_t(0)); this->_item.add("PDU-length", uint32_t(4)); this->_item.add("Reserved-2", uint8_t(0)); this->_item.add("Result", uint8_t(0)); this->_item.add("Source", uint8_t(0)); this->_item.add("Reason", uint8_t(0)); this->set_result(result); this->set_source(source); this->set_reason(reason); } AAssociateRJ ::AAssociateRJ(std::istream & stream) { this->_item.read(stream, "PDU-type", Item::Field::Type::unsigned_int_8); if(this->_item.as_unsigned_int_8("PDU-type") != 0x03) { throw Exception("Invalid PDU type"); } this->_item.read(stream, "Reserved-1", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "PDU-length", Item::Field::Type::unsigned_int_32); this->_item.read(stream, "Reserved-2", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Result", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Source", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Reason", Item::Field::Type::unsigned_int_8); } unsigned char AAssociateRJ ::get_result() const { return this->_item.as_unsigned_int_8("Result"); } void AAssociateRJ ::set_result(unsigned char result) { if(result > 2) { throw Exception("Unknown result"); } this->_item.as_unsigned_int_8("Result") = result; } unsigned char AAssociateRJ ::get_source() const { return this->_item.as_unsigned_int_8("Source"); } void AAssociateRJ ::set_source(unsigned char source) { if(source > 3) { throw Exception("Unknown source"); } this->_item.as_unsigned_int_8("Source") = source; } unsigned char AAssociateRJ ::get_reason() const { return this->_item.as_unsigned_int_8("Reason"); } void AAssociateRJ ::set_reason(unsigned char reason) { if(reason > 10) { throw Exception("Unknown reason"); } this->_item.as_unsigned_int_8("Reason") = reason; } } } odil-0.4.1/src/odil/pdu/AAssociateRJ.h000066400000000000000000000025661266460524100174110ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _3980566c_9185_40a2_8e7d_6286c2cd1959 #define _3980566c_9185_40a2_8e7d_6286c2cd1959 #include "odil/pdu/Object.h" namespace odil { namespace pdu { /// @brief A-ASSOCIATE-RJ PDU, cf. PS 3.8, 9.3.4. class AAssociateRJ: public Object { public: /// @brief Constructor. AAssociateRJ( unsigned char result, unsigned char source, unsigned char reason); /// @brief Constructor from stream. AAssociateRJ(std::istream & stream); /// @brief Return the result. unsigned char get_result() const; /// @brief Set the result, must be 1 or 2. void set_result(unsigned char result); /// @brief Return the source. unsigned char get_source() const; /// @brief Set the source, must be 1, 2 or 3. void set_source(unsigned char source); /// @brief Return the reason. unsigned char get_reason() const; /// @brief Set the reason. void set_reason(unsigned char reason); }; } } #endif // _3980566c_9185_40a2_8e7d_6286c2cd1959 odil-0.4.1/src/odil/pdu/AAssociateRQ.cpp000066400000000000000000000044211266460524100177430ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/AAssociateRQ.h" #include #include #include #include "odil/Exception.h" #include "odil/pdu/AAssociate.h" #include "odil/pdu/PresentationContextRQ.h" namespace odil { namespace pdu { AAssociateRQ ::AAssociateRQ() : AAssociate() { this->_item.as_unsigned_int_8("PDU-type") = 0x01; } AAssociateRQ ::AAssociateRQ(std::istream & stream) : AAssociate(stream) { if(this->_item.as_unsigned_int_8("PDU-type") != 0x01) { throw Exception("Invalid PDU type"); } } AAssociateRQ ::~AAssociateRQ() { // Nothing to do. } std::vector AAssociateRQ ::get_presentation_contexts() const { std::vector result; for(auto const & item: this->_item.as_items("Variable-items")) { if(item.as_unsigned_int_8("Item-type") == 0x20) { std::stringstream stream; stream << item; result.push_back(PresentationContextRQ(stream)); } } return result; } void AAssociateRQ ::set_presentation_contexts(std::vector const & value) { auto const & old_items = this->_item.as_items("Variable-items"); std::vector new_items; std::copy_if( old_items.begin(), old_items.end(), std::back_inserter(new_items), [](Item const & item) { return item.as_unsigned_int_8("Item-type") == 0x10; }); std::transform( value.begin(), value.end(), std::back_inserter(new_items), [](PresentationContext const & x) { return x.get_item(); }); std::copy_if( old_items.begin(), old_items.end(), std::back_inserter(new_items), [](Item const & item) { return item.as_unsigned_int_8("Item-type") == 0x50; }); this->_item.as_items("Variable-items") = new_items; this->_item.as_unsigned_int_32("PDU-length") = this->_compute_length(); } } } odil-0.4.1/src/odil/pdu/AAssociateRQ.h000066400000000000000000000023301266460524100174050ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _22fc6fe5_f7d1_461b_932f_cedfcae13897 #define _22fc6fe5_f7d1_461b_932f_cedfcae13897 #include #include "odil/pdu/AAssociate.h" #include "odil/pdu/PresentationContextRQ.h" namespace odil { namespace pdu { /// @brief A-ASSOCIATE-RQ, cf. PS 3.8, 9.3.2 class AAssociateRQ: public AAssociate { public: /// @brief Constructor. AAssociateRQ(); /// @brief Constructor for binary data. AAssociateRQ(std::istream & stream); /// @brief Destructor. ~AAssociateRQ(); /// @brief Return the Presentation Context sub-items. std::vector get_presentation_contexts() const; /// @brief Set the Presentation Context sub-items. void set_presentation_contexts(std::vector const & value); }; } } #endif // _22fc6fe5_f7d1_461b_932f_cedfcae13897 odil-0.4.1/src/odil/pdu/AReleaseRP.cpp000066400000000000000000000024031266460524100174050ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/AReleaseRP.h" #include #include #include "odil/Exception.h" #include "odil/pdu/Object.h" namespace odil { namespace pdu { AReleaseRP ::AReleaseRP() { this->_item.add("PDU-type", uint8_t(0x06)); this->_item.add("Reserved-1", uint8_t(0)); this->_item.add("PDU-length", uint32_t(4)); this->_item.add("Reserved-2", uint32_t(0)); } AReleaseRP ::AReleaseRP(std::istream & stream) { this->_item.read(stream, "PDU-type", Item::Field::Type::unsigned_int_8); if(this->_item.as_unsigned_int_8("PDU-type") != 0x06) { throw Exception("Invalid PDU type"); } this->_item.read(stream, "Reserved-1", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "PDU-length", Item::Field::Type::unsigned_int_32); this->_item.read(stream, "Reserved-2", Item::Field::Type::unsigned_int_32); } } } odil-0.4.1/src/odil/pdu/AReleaseRP.h000066400000000000000000000015321266460524100170540ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _a70fb011_8d69_4768_a84d_7f535621c335 #define _a70fb011_8d69_4768_a84d_7f535621c335 #include #include "odil/pdu/Object.h" namespace odil { namespace pdu { /// @brief A-RELEASE-RP PDU, cf. PS 3.8, 9.3.7. class AReleaseRP: public Object { public: /// @brief Constructor. AReleaseRP(); /// @brief Constructor from stream. AReleaseRP(std::istream & stream); }; } } #endif // _a70fb011_8d69_4768_a84d_7f535621c335 odil-0.4.1/src/odil/pdu/AReleaseRQ.cpp000066400000000000000000000024031266460524100174060ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/AReleaseRQ.h" #include #include #include "odil/Exception.h" #include "odil/pdu/Object.h" namespace odil { namespace pdu { AReleaseRQ ::AReleaseRQ() { this->_item.add("PDU-type", uint8_t(0x05)); this->_item.add("Reserved-1", uint8_t(0)); this->_item.add("PDU-length", uint32_t(4)); this->_item.add("Reserved-2", uint32_t(0)); } AReleaseRQ ::AReleaseRQ(std::istream & stream) { this->_item.read(stream, "PDU-type", Item::Field::Type::unsigned_int_8); if(this->_item.as_unsigned_int_8("PDU-type") != 0x05) { throw Exception("Invalid PDU type"); } this->_item.read(stream, "Reserved-1", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "PDU-length", Item::Field::Type::unsigned_int_32); this->_item.read(stream, "Reserved-2", Item::Field::Type::unsigned_int_32); } } } odil-0.4.1/src/odil/pdu/AReleaseRQ.h000066400000000000000000000015321266460524100170550ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _87f54a57_5741_4fde_871b_ea9c774795ad #define _87f54a57_5741_4fde_871b_ea9c774795ad #include #include "odil/pdu/Object.h" namespace odil { namespace pdu { /// @brief A-RELEASE-RQ PDU, cf. PS 3.8, 9.3.6. class AReleaseRQ: public Object { public: /// @brief Constructor. AReleaseRQ(); /// @brief Constructor from stream. AReleaseRQ(std::istream & stream); }; } } #endif // _87f54a57_5741_4fde_871b_ea9c774795ad odil-0.4.1/src/odil/pdu/ApplicationContext.cpp000066400000000000000000000034111266460524100212720ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/ApplicationContext.h" #include #include #include #include "odil/Exception.h" #include "odil/pdu/Object.h" namespace odil { namespace pdu { ApplicationContext ::ApplicationContext(std::string const & name) { this->_item.add("Item-type", uint8_t(0x10)); this->_item.add("Reserved", uint8_t(0)); this->_item.add("Item-length", uint16_t(0)); this->_item.add("Application-context-name", std::string()); this->set_name(name); } ApplicationContext ::ApplicationContext(std::istream & stream) { this->_item.read(stream, "Item-type", Item::Field::Type::unsigned_int_8); if(this->_item.as_unsigned_int_8("Item-type") != 0x10) { throw Exception("Invalid item type"); } this->_item.read(stream, "Reserved", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Item-length", Item::Field::Type::unsigned_int_16); this->_item.read( stream, "Application-context-name", Item::Field::Type::string, this->_item.as_unsigned_int_16("Item-length")); } std::string ApplicationContext ::get_name() const { return this->_item.as_string("Application-context-name"); } void ApplicationContext ::set_name(std::string const & name) { this->_item.as_string("Application-context-name") = name; this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); } } } odil-0.4.1/src/odil/pdu/ApplicationContext.h000066400000000000000000000022231266460524100207370ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _12bdb8f1_48c2_44d0_957a_bc1fb6f6733a #define _12bdb8f1_48c2_44d0_957a_bc1fb6f6733a #include #include #include "odil/pdu/Object.h" namespace odil { namespace pdu { /** * @brief Application Context item, (PS 3.8, 9.3.2.1). */ class ApplicationContext: public Object { public: /// @brief Create an Application Context. ApplicationContext(std::string const & name); /// @brief Read an Application Context from a stream. ApplicationContext(std::istream & stream); /// @brief Return the name of the Application Context. std::string get_name() const; /// @brief Set the name of the Application Context. void set_name(std::string const & name); }; } } #endif // _12bdb8f1_48c2_44d0_957a_bc1fb6f6733a odil-0.4.1/src/odil/pdu/ImplementationClassUID.cpp000066400000000000000000000036161266460524100220060ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/ImplementationClassUID.h" #include #include #include #include "odil/Exception.h" #include "odil/pdu/Object.h" namespace odil { namespace pdu { ImplementationClassUID ::ImplementationClassUID(std::string const & implementation_class_uid) { this->_item.add("Item-type", this->type); this->_item.add("Reserved", uint8_t(0)); this->_item.add("Item-length", uint16_t(0)); this->_item.add("Implementation-class-uid", std::string()); this->set_implementation_class_uid(implementation_class_uid); } ImplementationClassUID ::ImplementationClassUID(std::istream & stream) { this->_item.read(stream, "Item-type", Item::Field::Type::unsigned_int_8); if(this->_item.as_unsigned_int_8("Item-type") != this->type) { throw Exception("Invalid item type"); } this->_item.read(stream, "Reserved", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Item-length", Item::Field::Type::unsigned_int_16); this->_item.read( stream, "Implementation-class-uid", Item::Field::Type::string, this->_item.as_unsigned_int_16("Item-length")); } std::string ImplementationClassUID ::get_implementation_class_uid() const { return this->_item.as_string("Implementation-class-uid"); } void ImplementationClassUID ::set_implementation_class_uid(std::string const & value) { this->_item.as_string("Implementation-class-uid") = value; this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); } } } odil-0.4.1/src/odil/pdu/ImplementationClassUID.h000066400000000000000000000025031266460524100214450ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _6b085e0c_afd5_4ed7_ab4d_6bdb9b28ca67 #define _6b085e0c_afd5_4ed7_ab4d_6bdb9b28ca67 #include #include #include #include "odil/pdu/Object.h" namespace odil { namespace pdu { /// @brief Implementation Class UID Sub-Item (PS 3.7, D.3.3.2.1 and D.3.3.2.2). class ImplementationClassUID: public Object { public: /// @brief Item type. static uint8_t const type=0x52; /// @brief Create a Implementation Class UID item. ImplementationClassUID(std::string const & implementation_class_uid); /// @brief Read a Implementation Class UID item from a stream. ImplementationClassUID(std::istream & stream); /// @brief Return the Implementation Class UID. std::string get_implementation_class_uid() const; /// @brief Set the Implementation Class UID. void set_implementation_class_uid(std::string const & value); }; } } #endif // _6b085e0c_afd5_4ed7_ab4d_6bdb9b28ca67 odil-0.4.1/src/odil/pdu/ImplementationVersionName.cpp000066400000000000000000000040631266460524100226220ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/ImplementationVersionName.h" #include #include #include #include "odil/Exception.h" #include "odil/pdu/Object.h" namespace odil { namespace pdu { ImplementationVersionName ::ImplementationVersionName(std::string const & implementation_version_name) { this->_item.add("Item-type", this->type); this->_item.add("Reserved", uint8_t(0)); this->_item.add("Item-length", uint16_t(0)); this->_item.add("Implementation-version-name", std::string()); this->set_implementation_version_name(implementation_version_name); } ImplementationVersionName ::ImplementationVersionName(std::istream & stream) { this->_item.read(stream, "Item-type", Item::Field::Type::unsigned_int_8); if(this->_item.as_unsigned_int_8("Item-type") != this->type) { throw Exception("Invalid item type"); } this->_item.read(stream, "Reserved", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Item-length", Item::Field::Type::unsigned_int_16); this->_item.read( stream, "Implementation-version-name", Item::Field::Type::string, this->_item.as_unsigned_int_16("Item-length")); } std::string ImplementationVersionName ::get_implementation_version_name() const { return this->_item.as_string("Implementation-version-name"); } void ImplementationVersionName ::set_implementation_version_name(std::string const & value) { if(value.empty() || value.size()>16) { throw Exception("Invalid implementation version name"); } this->_item.as_string("Implementation-version-name") = value; this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); } } } odil-0.4.1/src/odil/pdu/ImplementationVersionName.h000066400000000000000000000025441266460524100222710ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _43545543_c8f8_44c4_b3ce_93cf2adfd365 #define _43545543_c8f8_44c4_b3ce_93cf2adfd365 #include #include #include #include "odil/pdu/Object.h" namespace odil { namespace pdu { /// @brief Implementation Version Name Sub-Item (PS 3.7, D.3.3.2.3 and D.3.3.2.4). class ImplementationVersionName: public Object { public: /// @brief Item type. static uint8_t const type=0x55; /// @brief Create a Implementation Version Name item. ImplementationVersionName(std::string const & implementation_version_name); /// @brief Read a Implementation Version Name item from a stream. ImplementationVersionName(std::istream & stream); /// @brief Return the Implementation Version Name. std::string get_implementation_version_name() const; /// @brief Set the Implementation Version Name. void set_implementation_version_name(std::string const & value); }; } } #endif // _43545543_c8f8_44c4_b3ce_93cf2adfd365 odil-0.4.1/src/odil/pdu/Item.cpp000066400000000000000000000216311266460524100163640ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/Item.h" #include #include #include #include #include #include #include #include "odil/endian.h" #include "odil/Exception.h" namespace odil { namespace pdu { Item::Field ::Field(uint8_t value) : _type(Type::unsigned_int_8), _uint8(value) { // Nothing else. } Item::Field ::Field(uint16_t value) : _type(Type::unsigned_int_16), _uint16(value) { // Nothing else. } Item::Field ::Field(uint32_t value) : _type(Type::unsigned_int_32), _uint32(value) { // Nothing else. } Item::Field ::Field(std::string const & value) : _type(Type::string), _string(value) { // Nothing else. } Item::Field ::Field(std::vector const & value) : _type(Type::items), _items(value) { // Nothing else. } Item::Field::Type Item::Field ::get_type() const { return this->_type; } uint8_t Item::Field ::as_unsigned_int_8() const { if(this->_type != Type::unsigned_int_8) { throw odil::Exception("Incorrect type"); } return this->_uint8; } uint8_t & Item::Field ::as_unsigned_int_8() { if(this->_type != Type::unsigned_int_8) { throw odil::Exception("Incorrect type"); } return this->_uint8; } uint16_t Item::Field ::as_unsigned_int_16() const { if(this->_type != Type::unsigned_int_16) { throw odil::Exception("Incorrect type"); } return this->_uint16; } uint16_t & Item::Field ::as_unsigned_int_16() { if(this->_type != Type::unsigned_int_16) { throw odil::Exception("Incorrect type"); } return this->_uint16; } uint32_t Item::Field ::as_unsigned_int_32() const { if(this->_type != Type::unsigned_int_32) { throw odil::Exception("Incorrect type"); } return this->_uint32; } uint32_t & Item::Field ::as_unsigned_int_32() { if(this->_type != Type::unsigned_int_32) { throw odil::Exception("Incorrect type"); } return this->_uint32; } std::string const & Item::Field ::as_string() const { if(this->_type != Type::string) { throw odil::Exception("Incorrect type"); } return this->_string; } std::string & Item::Field ::as_string() { if(this->_type != Type::string) { throw odil::Exception("Incorrect type"); } return this->_string; } std::vector const & Item::Field ::as_items() const { if(this->_type != Type::items) { throw odil::Exception("Incorrect type"); } return this->_items; } std::vector & Item::Field ::as_items() { if(this->_type != Type::items) { throw odil::Exception("Incorrect type"); } return this->_items; } Item ::Item() { // Nothing to do. } Item ::Item(std::vector> const & fields) : _fields(fields) { // Nothing else. } Item & Item ::add(std::string const & name, Field const & field) { this->_fields.push_back(std::make_pair(name, field)); return *this; } Item::Container::size_type Item ::size() const { return this->_fields.size(); } bool Item ::empty() const { return this->_fields.empty(); } bool Item ::has_field(std::string const & name) const { auto const iterator = std::find_if( this->_fields.begin(), this->_fields.end(), [&name](std::pair const & x) { return (x.first == name); }); return (iterator != this->_fields.end()); } Item::Field const & Item ::operator[](std::string const & name) const { auto const iterator = std::find_if( this->_fields.begin(), this->_fields.end(), [&name](std::pair const & x) { return (x.first == name); }); if(iterator == this->_fields.end()) { throw Exception("No such field"); } return iterator->second; } Item::Field & Item ::operator[](std::string const & name) { auto const iterator = std::find_if( this->_fields.begin(), this->_fields.end(), [&name](std::pair const & x) { return (x.first == name); }); if(iterator == this->_fields.end()) { throw Exception("No such field"); } return iterator->second; } uint8_t Item ::as_unsigned_int_8(std::string const & name) const { auto const & field = (*this)[name]; return field.as_unsigned_int_8(); } uint8_t & Item ::as_unsigned_int_8(std::string const & name) { auto & field = (*this)[name]; return field.as_unsigned_int_8(); } uint16_t Item ::as_unsigned_int_16(std::string const & name) const { auto const & field = (*this)[name]; return field.as_unsigned_int_16(); } uint16_t & Item ::as_unsigned_int_16(std::string const & name) { auto & field = (*this)[name]; return field.as_unsigned_int_16(); } uint32_t Item ::as_unsigned_int_32(std::string const & name) const { auto const & field = (*this)[name]; return field.as_unsigned_int_32(); } uint32_t & Item ::as_unsigned_int_32(std::string const & name) { auto & field = (*this)[name]; return field.as_unsigned_int_32(); } std::string const & Item ::as_string(std::string const & name) const { auto & field = (*this)[name]; return field.as_string(); } std::string & Item ::as_string(std::string const & name) { auto & field = (*this)[name]; return field.as_string(); } std::vector const & Item ::as_items(std::string const & name) const { auto & field = (*this)[name]; return field.as_items(); } std::vector & Item ::as_items(std::string const & name) { auto & field = (*this)[name]; return field.as_items(); } Item::const_iterator Item ::begin() const { return this->_fields.begin(); } Item::const_iterator Item ::end() const { return this->_fields.end(); } void Item ::read( std::istream & stream, std::string const & name, Field::Type type, std::streamsize size) { if(type == Field::Type::unsigned_int_8) { uint8_t value; stream.read(reinterpret_cast(&value), sizeof(value)); if(!stream.good()) { throw Exception("Could not read unsigned_int_8 field"); } this->add(name, Field(value)); } else if(type == Field::Type::unsigned_int_16) { uint16_t value; stream.read(reinterpret_cast(&value), sizeof(value)); if(!stream.good()) { throw Exception("Could not read unsigned_int_16 field"); } value = big_endian_to_host(value); this->add(name, Field(value)); } else if(type == Field::Type::unsigned_int_32) { uint32_t value; stream.read(reinterpret_cast(&value), sizeof(value)); if(!stream.good()) { throw Exception("Could not read unsigned_int_32 field"); } value = big_endian_to_host(value); this->add(name, Field(value)); } else if(type == Field::Type::string) { std::string value(size, '\0'); stream.read(reinterpret_cast(&value[0]), value.size()); if(!stream.good()) { throw Exception("Could not read string field"); } this->add(name, Field(value)); } else { throw Exception("Unknown field type"); } } std::ostream & operator<<(std::ostream & stream, Item const & item) { for(auto const & named_field: item) { auto const & field = named_field.second; auto const type = field.get_type(); if(type == Item::Field::Type::unsigned_int_8) { auto const value = field.as_unsigned_int_8(); stream.write(reinterpret_cast(&value), sizeof(value)); } else if(type == Item::Field::Type::unsigned_int_16) { auto const value = host_to_big_endian(field.as_unsigned_int_16()); stream.write(reinterpret_cast(&value), sizeof(value)); } else if(type == Item::Field::Type::unsigned_int_32) { auto const value = host_to_big_endian(field.as_unsigned_int_32()); stream.write(reinterpret_cast(&value), sizeof(value)); } else if(type == Item::Field::Type::string) { auto const value = field.as_string(); stream.write(reinterpret_cast(&value[0]), value.size()); } else if(type == Item::Field::Type::items) { auto const value = field.as_items(); for(auto const & sub_item: value) { stream << sub_item; } } else { throw Exception("Unknown type"); } } return stream; } } } odil-0.4.1/src/odil/pdu/Item.h000066400000000000000000000167261266460524100160420ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _1c7b57cc_79f5_497c_815c_920e0711a864 #define _1c7b57cc_79f5_497c_815c_920e0711a864 #include #include #include #include #include #include namespace odil { namespace pdu { /// @brief A sequence of fields forming a full PDU or a part of it. class Item { public: /// @brief Generic field. class Field { public: /// @brief Possible types stored in the field. enum class Type { unsigned_int_8, unsigned_int_16, unsigned_int_32, string, items }; /// @brief Constructor. Field(uint8_t value); /// @brief Constructor. Field(uint16_t value); /// @brief Constructor. Field(uint32_t value); /// @brief Constructor. Field(std::string const & value); /// @brief Constructor. Field(std::vector const & value); /// @brief Return the concrete type stored in the field. Type get_type() const; /** * @brief Return the uint8_t stored in the field. * * If the field does not contain an uint8_t, a odil::Exception is raised. */ uint8_t as_unsigned_int_8() const; /** * @brief Return the uint8_t stored in the field. * * If the field does not contain an uint8_t, a odil::Exception is raised. */ uint8_t & as_unsigned_int_8(); /** * @brief Return the uint16_t stored in the field. * * If the field does not contain an uint16_t, a odil::Exception is raised. */ uint16_t as_unsigned_int_16() const; /** * @brief Return the uint16_t stored in the field. * * If the field does not contain an uint16_t, a odil::Exception is raised. */ uint16_t & as_unsigned_int_16(); /** * @brief Return the uint32_t stored in the field. * * If the field does not contain an uint32_t, a odil::Exception is raised. */ uint32_t as_unsigned_int_32() const; /** * @brief Return the uint32_t stored in the field. * * If the field does not contain an uint32_t, a odil::Exception is raised. */ uint32_t & as_unsigned_int_32(); /** * @brief Return the string stored in the field. * * If the field does not contain an string, a odil::Exception is raised. */ std::string const & as_string() const; /** * @brief Return the string stored in the field. * * If the field does not contain an string, a odil::Exception is raised. */ std::string & as_string(); /** * @brief Return the items stored in the field. * * If the field does not contain items, a odil::Exception is raised. */ std::vector const & as_items() const; /** * @brief Return the items stored in the field. * * If the field does not contain items, a odil::Exception is raised. */ std::vector & as_items(); private: Type _type; uint8_t _uint8; uint16_t _uint16; uint32_t _uint32; std::string _string; std::vector _items; }; typedef std::vector> Container; /// @brief Create an empty PDU item. Item(); /// @brief Create an initialized PDU item. Item(std::vector> const & fields); /// @brief Add a new field to the PDU item. Item & add(std::string const & name, Field const & field); /// @brief Return the number of fields. Container::size_type size() const; /// @brief Test whether the container is empty. bool empty() const; /// @brief Test whether the PDU item contains a field with a given name. bool has_field(std::string const & name) const; /// @brief Return the named field. Raise an exception if no such field exists. Field const & operator[](std::string const & name) const; /// @brief Return the named field. Raise an exception if no such field exists. Field & operator[](std::string const & name); /** * @brief Return the named field as an uint8_t. * * Raise an exception if no such field exists or if the field does not * contain an uint8_t. */ uint8_t as_unsigned_int_8(std::string const & name) const; /** * @brief Return the named field as an uint8_t. * * Raise an exception if no such field exists or if the field does not * contain an uint8_t. */ uint8_t & as_unsigned_int_8(std::string const & name); /** * @brief Return the named field as an uint16_t. * * Raise an exception if no such field exists or if the field does not * contain an uint16_t. */ uint16_t as_unsigned_int_16(std::string const & name) const; /** * @brief Return the named field as an uint16_t. * * Raise an exception if no such field exists or if the field does not * contain an uint16_t. */ uint16_t & as_unsigned_int_16(std::string const & name); /** * @brief Return the named field as an uint32_t. * * Raise an exception if no such field exists or if the field does not * contain an uint32_t. */ uint32_t as_unsigned_int_32(std::string const & name) const; /** * @brief Return the named field as an uint32_t. * * Raise an exception if no such field exists or if the field does not * contain an uint32_t. */ uint32_t & as_unsigned_int_32(std::string const & name); /** * @brief Return the named field as a string. * * Raise an exception if no such field exists or if the field does not * contain a string. */ std::string const & as_string(std::string const & name) const; /** * @brief Return the named field as a sequence of items. * * Raise an exception if no such field exists or if the field does not * contain a sequence of items. */ std::string & as_string(std::string const & name); std::vector const & as_items(std::string const & name) const; /** * @brief Return the named field as a sequence of items. * * Raise an exception if no such field exists or if the field does not * contain a sequence of items. */ std::vector & as_items(std::string const & name); typedef Container::const_iterator const_iterator; const_iterator begin() const; const_iterator end() const; /** * @brief Read a field from a stream. * * The size parameter is ignored for non-string types. */ void read( std::istream & stream,std::string const & name, Field::Type type, std::streamsize size=0); private: std::vector> _fields; }; // No operator>> since we need explicit names and types. std::ostream & operator<<(std::ostream & stream, Item const & item); } } #endif // _1c7b57cc_79f5_497c_815c_920e0711a864 odil-0.4.1/src/odil/pdu/MaximumLength.cpp000066400000000000000000000032001266460524100202350ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/MaximumLength.h" #include #include #include "odil/Exception.h" #include "odil/pdu/Object.h" namespace odil { namespace pdu { MaximumLength ::MaximumLength(uint32_t maximum_length) { this->_item.add("Item-type", uint8_t(0x51)); this->_item.add("Reserved", uint8_t(0)); this->_item.add("Item-length", uint16_t(4)); this->_item.add("Maximum-length-received", uint32_t(0)); this->set_maximum_length(maximum_length); } MaximumLength ::MaximumLength(std::istream & stream) { this->_item.read(stream, "Item-type", Item::Field::Type::unsigned_int_8); if(this->_item.as_unsigned_int_8("Item-type") != 0x51) { throw Exception("Invalid item type"); } this->_item.read(stream, "Reserved", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Item-length", Item::Field::Type::unsigned_int_16); this->_item.read( stream, "Maximum-length-received", Item::Field::Type::unsigned_int_32); } uint32_t MaximumLength ::get_maximum_length() const { return this->_item.as_unsigned_int_32("Maximum-length-received"); } void MaximumLength ::set_maximum_length(uint32_t value) { this->_item.as_unsigned_int_32("Maximum-length-received") = value; } } } odil-0.4.1/src/odil/pdu/MaximumLength.h000066400000000000000000000022451266460524100177120ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _b2091b0b_1a6e_435c_b927_e5c54aff89c5 #define _b2091b0b_1a6e_435c_b927_e5c54aff89c5 #include #include #include "odil/pdu/Object.h" namespace odil { namespace pdu { /// @brief Maximum Length Sub-Item Structure (PS 3.8, D.1). class MaximumLength: public Object { public: /// @brief Item type. static uint8_t const type=0x51; /// @brief Create a Maximum Length item. MaximumLength(uint32_t maximum_length=0); /// @brief Read a Maximum Length item from a stream. MaximumLength(std::istream & stream); /// @brief Return the maximum length. uint32_t get_maximum_length() const; /// @brief Set the maximum length. void set_maximum_length(uint32_t value); }; } } #endif // _b2091b0b_1a6e_435c_b927_e5c54aff89c5 odil-0.4.1/src/odil/pdu/Object.cpp000066400000000000000000000043351266460524100166760ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/Object.h" #include #include #include "odil/Exception.h" #include "odil/pdu/Item.h" namespace odil { namespace pdu { Object ::~Object() { // Nothing to do. } Item const & Object ::get_item() const { return this->_item; } uint32_t Object ::_compute_length() const { uint32_t length=0; // First 3 fields are always the same: type, reserved and length. auto it = this->_item.begin(); std::advance(it, 3); for(; it!=this->_item.end(); ++it) { Item::Field const & field = it->second; length += this->_compute_length(field); } return length; } uint32_t Object ::_compute_length(Item const & item) const { uint32_t length=0; for(auto const & named_field: item) { Item::Field const & field = named_field.second; length += this->_compute_length(field); } return length; } uint32_t Object ::_compute_length(Item::Field const & field) const { uint32_t length=0; if(field.get_type() == Item::Field::Type::unsigned_int_8) { length += 1; } else if(field.get_type() == Item::Field::Type::unsigned_int_16) { length += 2; } else if(field.get_type() == Item::Field::Type::unsigned_int_32) { length += 4; } else if(field.get_type() == Item::Field::Type::string) { length += field.as_string().size(); } else if(field.get_type() == Item::Field::Type::items) { auto const & items = field.as_items(); for(auto const & item: items) { length += this->_compute_length(item); } } else { throw Exception("Unknown field type"); } return length; } std::ostream & operator<<(std::ostream & stream, Object const & object) { stream << object.get_item(); return stream; } } } odil-0.4.1/src/odil/pdu/Object.h000066400000000000000000000025611266460524100163420ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _da2270e3_d393_415a_9c5c_6253152ed9da #define _da2270e3_d393_415a_9c5c_6253152ed9da #include #include "odil/pdu/Item.h" namespace odil { namespace pdu { /** * @brief Base class for all PDU-related high-level objects (PDU, items and * sub-items). */ class Object { public: /// @brief Destructor, makes the type polymorphic. virtual ~Object(); /// @brief Get the underlying item. Item const & get_item() const; protected: Item _item; /// @brief Compute the value of the length field of the object. uint32_t _compute_length() const; /// @brief Compute the full size of an item. uint32_t _compute_length(Item const & item) const; /// @brief Compute the full size of a field. uint32_t _compute_length(Item::Field const & field) const; }; /// @brief Dump the PDU-object in its binary form. std::ostream & operator<<(std::ostream & stream, Object const & object); } } #endif // _da2270e3_d393_415a_9c5c_6253152ed9da odil-0.4.1/src/odil/pdu/PDataTF.cpp000066400000000000000000000116411266460524100167110ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/PDataTF.h" #include #include #include #include #include #include "odil/Exception.h" #include "odil/pdu/Item.h" #include "odil/pdu/Object.h" namespace odil { namespace pdu { PDataTF::PresentationDataValueItem ::PresentationDataValueItem( uint8_t presentation_context_id, uint8_t control_header, std::string const & fragment) { this->_item.add("Item-length", uint32_t(4)); this->_item.add("Presentation-Context-ID", uint8_t(0)); this->_item.add("Control-header", uint8_t(0)); this->_item.add("Fragment", std::string()); this->set_presentation_context_id(presentation_context_id); this->set_control_header(control_header); this->set_fragment(fragment); } PDataTF::PresentationDataValueItem ::PresentationDataValueItem(std::istream & stream) { this->_item.read(stream, "Item-length", Item::Field::Type::unsigned_int_32); this->_item.read( stream, "Presentation-Context-ID", Item::Field::Type::unsigned_int_8); this->_item.read( stream, "Control-header", Item::Field::Type::unsigned_int_8); this->_item.read( stream, "Fragment", Item::Field::Type::string, this->_item.as_unsigned_int_32("Item-length")-2); } uint8_t PDataTF::PresentationDataValueItem ::get_presentation_context_id() const { return this->_item.as_unsigned_int_8("Presentation-Context-ID"); } void PDataTF::PresentationDataValueItem ::set_presentation_context_id(uint8_t value) { if(value%2 == 0) { throw Exception("Invalid Presentation Context ID"); } this->_item.as_unsigned_int_8("Presentation-Context-ID") = value; } uint8_t PDataTF::PresentationDataValueItem ::get_control_header() const { return this->_item.as_unsigned_int_8("Control-header"); } void PDataTF::PresentationDataValueItem ::set_control_header(uint8_t value) { this->_item.as_unsigned_int_8("Control-header") = value; } bool PDataTF::PresentationDataValueItem ::is_command() const { return (this->get_control_header()%2==1); } bool PDataTF::PresentationDataValueItem ::is_last_fragment() const { return ((this->get_control_header()>>1)%2==1); } std::string const & PDataTF::PresentationDataValueItem ::get_fragment() const { return this->_item.as_string("Fragment"); } void PDataTF::PresentationDataValueItem ::set_fragment(std::string const & fragment) { this->_item.as_string("Fragment") = fragment; this->_item.as_unsigned_int_32("Item-length") = 2+fragment.size(); } PDataTF ::PDataTF(std::vector const & pdv_items) { this->_item.add("PDU-type", uint8_t(0x04)); this->_item.add("Reserved-1", uint8_t(0)); this->_item.add("PDU-length", uint32_t(4)); this->_item.add("Presentation-data-value-Items", std::vector()); this->set_pdv_items(pdv_items); } PDataTF ::PDataTF(std::istream & stream) { this->_item.read(stream, "PDU-type", Item::Field::Type::unsigned_int_8); if(this->_item.as_unsigned_int_8("PDU-type") != 0x04) { throw Exception("Invalid PDU type"); } this->_item.read(stream, "Reserved-1", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "PDU-length", Item::Field::Type::unsigned_int_32); auto const pdu_length = this->_item.as_unsigned_int_32("PDU-length"); auto const begin = stream.tellg(); std::vector pdv_items; while(stream.tellg()-begin < pdu_length) { PresentationDataValueItem pdv_item(stream); pdv_items.push_back(pdv_item); } this->_item.add("Presentation-data-value-Items", std::vector()); this->set_pdv_items(pdv_items); } std::vector PDataTF ::get_pdv_items() const { std::vector result; for(auto const & item: this->_item.as_items("Presentation-data-value-Items")) { PresentationDataValueItem const pdv_item( item.as_unsigned_int_8("Presentation-Context-ID"), item.as_unsigned_int_8("Control-header"), item.as_string("Fragment")); result.push_back(pdv_item); } return result; } void PDataTF ::set_pdv_items(std::vector const &pdv_items) { auto & items = this->_item.as_items("Presentation-data-value-Items"); items.resize(pdv_items.size()); std::transform( pdv_items.begin(), pdv_items.end(), items.begin(), [](PresentationDataValueItem const& x){ return x.get_item(); }); this->_item.as_unsigned_int_32("PDU-length") = this->_compute_length(); } } } odil-0.4.1/src/odil/pdu/PDataTF.h000066400000000000000000000035131266460524100163550ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _b3062f12_8a06_46a8_9dda_8a7edf96e4a6 #define _b3062f12_8a06_46a8_9dda_8a7edf96e4a6 #include #include #include #include "odil/pdu/Object.h" namespace odil { namespace pdu { /// @brief P-DATA-TF PDU, cf. PS 3.8, 9.3.5. class PDataTF: public Object { public: class PresentationDataValueItem: public Object { public: PresentationDataValueItem( uint8_t presentation_context_id, uint8_t control_header, std::string const & fragment); PresentationDataValueItem(std::istream & stream); uint8_t get_presentation_context_id() const; void set_presentation_context_id(uint8_t value); uint8_t get_control_header() const; void set_control_header(uint8_t value); bool is_command() const; bool is_last_fragment() const; std::string const & get_fragment() const; void set_fragment(std::string const & fragment); }; /// @brief Constructor. PDataTF(std::vector const & pdv_items); /// @brief Constructor from stream. PDataTF(std::istream & stream); /// @brief Return the Presentation Data Value Items. std::vector get_pdv_items() const; /// @brief Set the Presentation Data Value Items. void set_pdv_items(std::vector const &pdv_items); }; } } #endif // _b3062f12_8a06_46a8_9dda_8a7edf96e4a6 odil-0.4.1/src/odil/pdu/PresentationContext.cpp000066400000000000000000000132421266460524100215050ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/PresentationContext.h" #include #include #include #include #include "odil/Exception.h" #include "odil/pdu/Object.h" #include "odil/pdu/Item.h" namespace odil { namespace pdu { PresentationContext ::PresentationContext() { // Nothing to do. } PresentationContext ::PresentationContext(std::istream & stream) { this->_item.read(stream, "Item-type", Item::Field::Type::unsigned_int_8); if(this->get_item_type() != 0x20 && this->get_item_type() != 0x21) { throw Exception("Invalid item type"); } this->_item.read(stream, "Reserved-1", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Item-length", Item::Field::Type::unsigned_int_16); auto const item_length = this->_item.as_unsigned_int_16("Item-length"); auto const begin = stream.tellg(); this->_item.read( stream, "Presentation-context-id", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Reserved-2", Item::Field::Type::unsigned_int_8); this->_item.read( stream, "Result/Reason", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Reserved-3", Item::Field::Type::unsigned_int_8); std::vector sub_items; while(stream.tellg()-begin < item_length) { Item item; item.read(stream, "Item-type", Item::Field::Type::unsigned_int_8); std::string type; auto const & item_type = item.as_unsigned_int_8("Item-type"); if(item_type == 0x30) { type = "Abstract"; } else if(item_type == 0x40) { type = "Transfer"; } else { throw Exception("Invalid item"); } item.read(stream, "Reserved", Item::Field::Type::unsigned_int_8); item.read(stream, "Item-length", Item::Field::Type::unsigned_int_16); item.read( stream, type+"-syntax-name", Item::Field::Type::string, item.as_unsigned_int_16("Item-length")); sub_items.push_back(item); } this->_item.add("Abstract/Transfer Syntax Sub-Items", sub_items); } PresentationContext ::~PresentationContext() { // Nothing to do. } uint8_t PresentationContext ::get_item_type() const { return this->_item.as_unsigned_int_8("Item-type"); } uint8_t PresentationContext ::get_id() const { return this->_item.as_unsigned_int_8("Presentation-context-id"); } void PresentationContext ::set_id(uint8_t id) { this->_item.as_unsigned_int_8("Presentation-context-id") = id; } Item PresentationContext ::_make_string_item( std::string const & type, std::string const & value) { Item item; uint8_t item_type; if(type == "Abstract") { item_type = 0x30; } else if(type == "Transfer") { item_type = 0x40; } else { throw Exception("Unknown sub-item type"); } item.add("Item-type", item_type); item.add("Reserved", uint8_t(0)); item.add("Item-length", uint16_t(value.size())); item.add(type+"-syntax-name", value); return item; } void PresentationContext ::_add_fields() { this->_item.add("Item-type", uint8_t(0x0)); this->_item.add("Reserved-1", uint8_t(0)); this->_item.add("Item-length", uint16_t(0)); this->_item.add("Presentation-context-id", uint8_t(0)); this->_item.add("Reserved-2", uint8_t(0)); this->_item.add("Result/Reason", uint8_t(0)); this->_item.add("Reserved-3", uint8_t(0)); this->_item.add("Abstract/Transfer Syntax Sub-Items", std::vector()); } std::vector PresentationContext ::_get_syntaxes(std::string const & type) const { auto const & sub_items = this->_item.as_items( "Abstract/Transfer Syntax Sub-Items"); std::vector result; std::for_each( sub_items.begin(), sub_items.end(), [&type, &result](Item const & item) { uint8_t const item_type = (type=="Abstract")?0x30:0x40; if(item.as_unsigned_int_8("Item-type") == item_type) { auto const value = item.as_string(type+"-syntax-name"); result.push_back(value); } }); return result; } void PresentationContext ::_set_syntaxes( std::string const & type, std::vector const & syntaxes) { std::string const other_type = (type=="Abstract")?"Transfer":"Abstract"; auto const other_syntaxes = this->_get_syntaxes(other_type); auto & sub_items = this->_item.as_items( "Abstract/Transfer Syntax Sub-Items"); sub_items.resize(other_syntaxes.size()+syntaxes.size()); auto const & abstract_syntaxes = (type=="Abstract")?syntaxes:other_syntaxes; auto const & transfer_syntaxes = (type=="Abstract")?other_syntaxes:syntaxes; std::transform( abstract_syntaxes.begin(), abstract_syntaxes.end(), sub_items.begin(), [this](std::string const & name) { return PresentationContext::_make_string_item("Abstract", name); }); std::transform( transfer_syntaxes.begin(), transfer_syntaxes.end(), sub_items.begin()+abstract_syntaxes.size(), [this](std::string const & name) { return PresentationContext::_make_string_item("Transfer", name); }); this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); } } } odil-0.4.1/src/odil/pdu/PresentationContext.h000066400000000000000000000035371266460524100211600ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _30f1a581_9ae6_4a02_a455_bf2b6ea58bc6 #define _30f1a581_9ae6_4a02_a455_bf2b6ea58bc6 #include #include #include #include #include "odil/pdu/Object.h" namespace odil { namespace pdu { /** * @brief Presentation Context item, either for a A-ASSOCIATE-RQ PDU (PS 3.8, * 9.3.2.2) or for a A-ASSOCIATE-AC PDU (PS 3.8, 9.3.3.2). */ class PresentationContext: public Object { public: /// @brief Constructor PresentationContext(); /// @brief Read from a stream. PresentationContext(std::istream & stream); /// @brief Destructor, make the class pure virtual. virtual ~PresentationContext() =0; /// @brief Return the Item-type. uint8_t get_item_type() const; /// @brief Return the Presentation context id. uint8_t get_id() const; /// @brief Set the Presentation context id. void set_id(uint8_t id); protected: /// @brief Create an Abstract Syntax or Transfer Syntax sub-item. static Item _make_string_item( std::string const & type, std::string const & value); /// @brief Add common fields. void _add_fields(); /// @brief Return the Abstract or Transfer syntaxes. std::vector _get_syntaxes(std::string const & type) const; /// @brief Set the Abstract or Transfer syntaxes. void _set_syntaxes( std::string const & type, std::vector const & syntaxes); }; } } #endif // _30f1a581_9ae6_4a02_a455_bf2b6ea58bc6 odil-0.4.1/src/odil/pdu/PresentationContextAC.cpp000066400000000000000000000037001266460524100217070ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/PresentationContextAC.h" #include #include #include #include "odil/Exception.h" #include "odil/pdu/PresentationContext.h" namespace odil { namespace pdu { PresentationContextAC ::PresentationContextAC( uint8_t id, std::string const & transfer_syntax, uint8_t result_reason) { this->_add_fields(); this->_item.as_unsigned_int_8("Item-type") = 0x21; this->set_id(id); this->set_transfer_syntax(transfer_syntax); this->set_result_reason(result_reason); } PresentationContextAC ::PresentationContextAC(std::istream & stream) : PresentationContext(stream) { if(this->get_item_type() != 0x21) { throw Exception("Invalid item type"); } } PresentationContextAC ::~PresentationContextAC() { // Nothing to do. } uint8_t PresentationContextAC ::get_result_reason() const { return this->_item.as_unsigned_int_8("Result/Reason"); } void PresentationContextAC ::set_result_reason(uint8_t result_reason) { this->_item.as_unsigned_int_8("Result/Reason") = result_reason; } std::string PresentationContextAC ::get_transfer_syntax() const { auto const & syntaxes = this->_get_syntaxes("Transfer"); if(syntaxes.empty()) { throw Exception("No Transfer Syntax sub-item"); } else if(syntaxes.size() > 1) { throw Exception("Several Transfer Syntax sub-items"); } return syntaxes[0]; } void PresentationContextAC ::set_transfer_syntax(std::string const & transfer_syntax) { this->_set_syntaxes("Transfer", {transfer_syntax}); } } } odil-0.4.1/src/odil/pdu/PresentationContextAC.h000066400000000000000000000027461266460524100213650ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _69f1f7a9_d252_4ccd_a2d5_5df0ac4fb054 #define _69f1f7a9_d252_4ccd_a2d5_5df0ac4fb054 #include #include #include #include "odil/pdu/PresentationContext.h" namespace odil { namespace pdu { /// @brief Presentation Context item for a A-ASSOCIATE-AC PDU (PS 3.8, 9.3.3.2). class PresentationContextAC: public PresentationContext { public: /// @brief Constructor. PresentationContextAC( uint8_t id, std::string const & transfer_syntax, uint8_t result_reason); /// @brief Read a Presentation Context from a stream. PresentationContextAC(std::istream & stream); /// @brief Destructor. ~PresentationContextAC(); /// @brief Return the Result/Reason. uint8_t get_result_reason() const; /// @brief Set the Result/Reason. void set_result_reason(uint8_t result_reason); /// @brief Return the Transfer Syntax. std::string get_transfer_syntax() const; /// @brief Set the Transfer Syntax. void set_transfer_syntax(std::string const & transfer_syntax); }; } } #endif // _69f1f7a9_d252_4ccd_a2d5_5df0ac4fb054 odil-0.4.1/src/odil/pdu/PresentationContextRQ.cpp000066400000000000000000000042471266460524100217550ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _952c6d4c_b331_4033_8476_5b0e75022b68 #define _952c6d4c_b331_4033_8476_5b0e75022b68 #include "odil/pdu/PresentationContextRQ.h" #include #include #include #include #include "odil/Exception.h" #include "odil/pdu/PresentationContext.h" namespace odil { namespace pdu { PresentationContextRQ ::PresentationContextRQ( uint8_t id, std::string const & abstract_syntax, std::vector const & transfer_syntaxes) { this->_add_fields(); this->_item.as_unsigned_int_8("Item-type") = 0x20; this->set_id(id); this->set_abstract_syntax(abstract_syntax); this->set_transfer_syntaxes(transfer_syntaxes); } PresentationContextRQ ::PresentationContextRQ(std::istream & stream) : PresentationContext(stream) { if(this->get_item_type() != 0x20) { throw Exception("Invalid item type"); } } PresentationContextRQ ::~PresentationContextRQ() { // Nothing to do. } std::string PresentationContextRQ ::get_abstract_syntax() const { auto const & syntaxes = this->_get_syntaxes("Abstract"); if(syntaxes.empty()) { throw Exception("No Abstract Syntax sub-item"); } else if(syntaxes.size() > 1) { throw Exception("Several Abstract Syntax sub-items"); } return syntaxes[0]; } void PresentationContextRQ ::set_abstract_syntax(std::string const & abstract_syntax) { this->_set_syntaxes("Abstract", {abstract_syntax}); } std::vector PresentationContextRQ ::get_transfer_syntaxes() const { return this->_get_syntaxes("Transfer"); } void PresentationContextRQ ::set_transfer_syntaxes(std::vector const & transfer_syntaxes) { this->_set_syntaxes("Transfer", transfer_syntaxes); } } } #endif // _952c6d4c_b331_4033_8476_5b0e75022b68 odil-0.4.1/src/odil/pdu/PresentationContextRQ.h000066400000000000000000000031541266460524100214160ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _e6e42ffd_7318_48f5_b35a_d44093564044 #define _e6e42ffd_7318_48f5_b35a_d44093564044 #include #include #include #include #include "odil/pdu/PresentationContext.h" namespace odil { namespace pdu { /// @brief Presentation Context item for a A-ASSOCIATE-RQ PDU (PS 3.8, 9.3.2.2). class PresentationContextRQ: public PresentationContext { public: /// @brief Constructor. PresentationContextRQ( uint8_t id, std::string const & abstract_syntax, std::vector const & transfer_syntaxes); /// @brief Read a Presentation Context from a stream. PresentationContextRQ(std::istream & stream); /// @brief Destructor. ~PresentationContextRQ(); /// @brief Return the Abstract Syntax. std::string get_abstract_syntax() const; /// @brief Set the Abstract Syntax. void set_abstract_syntax(std::string const & abstract_syntax); /// @brief Return the Transfer Syntaxes. std::vector get_transfer_syntaxes() const; /// @brief Set the Transfer Syntax sub-items. void set_transfer_syntaxes( std::vector const & transfer_syntaxes); }; } } #endif // _e6e42ffd_7318_48f5_b35a_d44093564044 odil-0.4.1/src/odil/pdu/RoleSelection.cpp000066400000000000000000000054561266460524100202440ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/RoleSelection.h" #include #include #include #include "odil/Exception.h" #include "odil/pdu/Item.h" #include "odil/pdu/Object.h" namespace odil { namespace pdu { RoleSelection ::RoleSelection( std::string const & sop_class_uid, bool scu_role_support, bool scp_role_support) { this->_item.add("Item-type", this->type); this->_item.add("Reserved", uint8_t(0)); this->_item.add("Item-length", uint16_t(0)); this->_item.add("UID-length", uint16_t(0)); this->_item.add("SOP-class-uid", std::string()); this->_item.add("SCU-role", uint8_t(0)); this->_item.add("SCP-role", uint8_t(0)); this->set_sop_class_uid(sop_class_uid); this->set_scu_role_support(scu_role_support); this->set_scp_role_support(scp_role_support); } RoleSelection ::RoleSelection(std::istream & stream) { this->_item.read(stream, "Item-type", Item::Field::Type::unsigned_int_8); if(this->_item.as_unsigned_int_8("Item-type") != this->type) { throw Exception("Invalid item type"); } this->_item.read(stream, "Reserved", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Item-length", Item::Field::Type::unsigned_int_16); this->_item.read(stream, "UID-length", Item::Field::Type::unsigned_int_16); this->_item.read( stream, "SOP-class-uid", Item::Field::Type::string, this->_item.as_unsigned_int_16("UID-length")); this->_item.read(stream, "SCU-role", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "SCP-role", Item::Field::Type::unsigned_int_8); } std::string const & RoleSelection ::get_sop_class_uid() const { return this->_item.as_string("SOP-class-uid"); } void RoleSelection ::set_sop_class_uid(std::string const & value) { this->_item.as_string("SOP-class-uid") = value; this->_item.as_unsigned_int_16("UID-length") = value.size(); this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); } bool RoleSelection ::get_scu_role_support() const { return (this->_item.as_unsigned_int_8("SCU-role")!=0); } void RoleSelection ::set_scu_role_support(bool value) { this->_item.as_unsigned_int_8("SCU-role") = value?1:0; } bool RoleSelection ::get_scp_role_support() const { return (this->_item.as_unsigned_int_8("SCP-role")!=0); } void RoleSelection ::set_scp_role_support(bool value) { this->_item.as_unsigned_int_8("SCP-role") = value?1:0; } } } odil-0.4.1/src/odil/pdu/RoleSelection.h000066400000000000000000000035131266460524100177010ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _8a990556_f9c3_49f3_bb84_6e604ec9b8f4 #define _8a990556_f9c3_49f3_bb84_6e604ec9b8f4 #include #include #include #include "odil/pdu/Object.h" namespace odil { namespace pdu { /// @brief SCU/SCP Role Selection Sub-Item (PS 3.7, D.3.3.4.1 and D.3.3.4.2). class RoleSelection: public Object { public: /// @brief Item type. static uint8_t const type=0x54; /// @brief Create a Role Selection Sub-Item. RoleSelection( std::string const & sop_class_uid="", bool scu_role_support=false, bool scp_role_support=false); /// @brief Read a Role Selection Sub-Item from a stream. RoleSelection(std::istream & stream); /** * @brief Return the SOP class uid identifying the abstract syntax, * defaults to "". */ std::string const & get_sop_class_uid() const; /// @brief Set the SOP class uid identifying the abstract syntax. void set_sop_class_uid(std::string const & value); /// @brief Return whether the SCU role is supported, defaults to false. bool get_scu_role_support() const; /// @brief Set whether the SCP role is supported. void set_scu_role_support(bool value); /// @brief Return whether the SCP role is supported, defaults to false. bool get_scp_role_support() const; /// @brief Set whether the SCP role is supported. void set_scp_role_support(bool value); }; } } #endif // _8a990556_f9c3_49f3_bb84_6e604ec9b8f4 odil-0.4.1/src/odil/pdu/UserIdentityAC.cpp000066400000000000000000000040341266460524100203200ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/UserIdentityAC.h" #include #include #include #include "odil/Exception.h" #include "odil/pdu/Object.h" namespace odil { namespace pdu { UserIdentityAC ::UserIdentityAC(std::string const & server_response) { this->_item.add("Item-type", uint8_t(0x59)); this->_item.add("Reserved", uint8_t(0)); this->_item.add("Item-length", uint16_t(0)); this->_item.add("Server-response-length", uint16_t(0)); this->_item.add("Server-response", std::string("")); this->set_server_response(server_response); } UserIdentityAC ::UserIdentityAC(std::istream & stream) { this->_item.read(stream, "Item-type", Item::Field::Type::unsigned_int_8); if(this->_item.as_unsigned_int_8("Item-type") != 0x59) { throw Exception("Invalid item type"); } this->_item.read(stream, "Reserved", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Item-length", Item::Field::Type::unsigned_int_16); this->_item.read( stream, "Server-response-length", Item::Field::Type::unsigned_int_16); this->_item.read( stream, "Server-response", Item::Field::Type::string, this->_item.as_unsigned_int_16("Server-response-length")); } std::string const & UserIdentityAC ::get_server_response() const { return this->_item.as_string("Server-response"); } void UserIdentityAC ::set_server_response(std::string const & value) { this->_item.as_unsigned_int_16("Server-response-length") = value.size(); this->_item.as_string("Server-response") = value; this->_item.as_unsigned_int_16("Item-length") = 2+this->get_server_response().size(); } } } odil-0.4.1/src/odil/pdu/UserIdentityAC.h000066400000000000000000000023321266460524100177640ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _1c3d6b3c_09a0_4452_9263_aa010ee1d973 #define _1c3d6b3c_09a0_4452_9263_aa010ee1d973 #include #include #include "odil/pdu/Object.h" namespace odil { namespace pdu { /// @brief User Identity Sub-Item Structure (A-ASSOCIATE-AC) (PS 3.7, D.3.3.7.2). class UserIdentityAC: public Object { public: /// @brief Item type. static uint8_t const type=0x59; /// @brief Create an User Identity. UserIdentityAC(std::string const & server_response=""); /// @brief Read an User Identity from a stream. UserIdentityAC(std::istream & stream); /// @brief Return the server response. std::string const & get_server_response() const; /// @brief Set the server response. void set_server_response(std::string const & value); }; } } #endif // _1c3d6b3c_09a0_4452_9263_aa010ee1d973 odil-0.4.1/src/odil/pdu/UserIdentityRQ.cpp000066400000000000000000000104671266460524100203660ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/UserIdentityRQ.h" #include #include #include #include "odil/Exception.h" #include "odil/pdu/Object.h" namespace odil { namespace pdu { UserIdentityRQ ::UserIdentityRQ() { this->_item.add("Item-type", uint8_t(0x58)); this->_item.add("Reserved", uint8_t(0)); this->_item.add("Item-length", uint16_t(0)); this->_item.add("User-Identity-Type", uint8_t(1)); this->_item.add("Positive-response-requested", uint8_t(0)); this->_item.add("Primary-field-length", uint16_t(0)); this->_item.add("Primary-field", std::string("")); this->_item.add("Secondary-field-length", uint16_t(0)); this->_item.add("Secondary-field", std::string("")); this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); } UserIdentityRQ ::UserIdentityRQ(std::istream & stream) { this->_item.read(stream, "Item-type", Item::Field::Type::unsigned_int_8); if(this->_item.as_unsigned_int_8("Item-type") != 0x58) { throw Exception("Invalid item type"); } this->_item.read(stream, "Reserved", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Item-length", Item::Field::Type::unsigned_int_16); this->_item.read( stream, "User-Identity-Type", Item::Field::Type::unsigned_int_8); this->_item.read( stream, "Positive-response-requested", Item::Field::Type::unsigned_int_8); this->_item.read( stream, "Primary-field-length", Item::Field::Type::unsigned_int_16); this->_item.read( stream, "Primary-field", Item::Field::Type::string, this->_item.as_unsigned_int_16("Primary-field-length")); this->_item.read( stream, "Secondary-field-length", Item::Field::Type::unsigned_int_16); this->_item.read( stream, "Secondary-field", Item::Field::Type::string, this->_item.as_unsigned_int_16("Secondary-field-length")); } uint8_t UserIdentityRQ ::get_type() const { return this->_item.as_unsigned_int_8("User-Identity-Type"); } void UserIdentityRQ ::set_type(uint8_t type) { this->_item.as_unsigned_int_8("User-Identity-Type") = type; } bool UserIdentityRQ ::get_positive_response_requested() const { return (this->_item.as_unsigned_int_8("Positive-response-requested") != 0); } void UserIdentityRQ ::set_positive_response_requested(bool value) { this->_item.as_unsigned_int_8("Positive-response-requested") = value?1:0; } std::string const & UserIdentityRQ ::get_primary_field() const { return this->_item.as_string("Primary-field"); } void UserIdentityRQ ::set_primary_field(std::string const & value) { this->_item.as_unsigned_int_16("Primary-field-length") = value.size(); this->_item.as_string("Primary-field") = value; this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); } std::string const & UserIdentityRQ ::get_secondary_field() const { return this->_item.as_string("Secondary-field"); } void UserIdentityRQ ::set_secondary_field(std::string const & value) { this->_item.as_unsigned_int_16("Secondary-field-length") = value.size(); this->_item.as_string("Secondary-field") = value; this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); } void UserIdentityRQ ::set_username(std::string const & username) { this->set_type(1); this->set_primary_field(username); this->set_secondary_field(""); } void UserIdentityRQ ::set_username_and_passcode( std::string const & username, std::string const & passcode) { this->set_type(2); this->set_primary_field(username); this->set_secondary_field(passcode); } void UserIdentityRQ ::set_kerberos_service_ticket(std::string const & ticket) { this->set_type(3); this->set_primary_field(ticket); this->set_secondary_field(""); } void UserIdentityRQ ::set_saml_assertion(std::string const & assertion) { this->set_type(4); this->set_primary_field(assertion); this->set_secondary_field(""); } } } odil-0.4.1/src/odil/pdu/UserIdentityRQ.h000066400000000000000000000041251266460524100200250ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _b935542d_12c9_4c81_963c_32b7996af777 #define _b935542d_12c9_4c81_963c_32b7996af777 #include #include #include #include "odil/pdu/Object.h" namespace odil { namespace pdu { /// @brief User Identity Sub-Item Structure (A-ASSOCIATE-RQ) (PS 3.7, D.3.3.7.1). class UserIdentityRQ: public Object { public: /// @brief Item type. static uint8_t const type=0x58; /// @brief Create an User Identity. UserIdentityRQ(); /// @brief Read an User Identity from a stream. UserIdentityRQ(std::istream & stream); /// @brief Return the type of the User Identity. uint8_t get_type() const; /// @brief Set the type of the User Identity. void set_type(uint8_t type); /// @brief Return whether a positive response is requested. bool get_positive_response_requested() const; /// @brief Set whether a positive response is requested. void set_positive_response_requested(bool value); /// @brief Return the primary identity field. std::string const & get_primary_field() const; /// @brief Set the primary identity field. void set_primary_field(std::string const & value); /// @brief Return the secondary identity field. std::string const & get_secondary_field() const; /// @brief Set the secondary identity field. void set_secondary_field(std::string const & value); void set_username(std::string const & username); void set_username_and_passcode( std::string const & username, std::string const & passcode); void set_kerberos_service_ticket(std::string const & ticket); void set_saml_assertion(std::string const & assertion); }; } } #endif // _b935542d_12c9_4c81_963c_32b7996af777 odil-0.4.1/src/odil/pdu/UserInformation.cpp000066400000000000000000000067051266460524100206170ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/pdu/UserInformation.h" #include #include #include #include "odil/Exception.h" #include "odil/pdu/ImplementationClassUID.h" #include "odil/pdu/ImplementationVersionName.h" #include "odil/pdu/MaximumLength.h" #include "odil/pdu/Object.h" #include "odil/pdu/RoleSelection.h" #include "odil/pdu/UserIdentityAC.h" #include "odil/pdu/UserIdentityRQ.h" namespace odil { namespace pdu { UserInformation ::UserInformation() { this->_item.add("Item-type", uint8_t(0x50)); this->_item.add("Reserved", uint8_t(0)); this->_item.add("Item-length", uint16_t(4)); this->_item.add("User-data", std::vector()); } UserInformation ::UserInformation(std::istream & stream) { this->_item.read(stream, "Item-type", Item::Field::Type::unsigned_int_8); if(this->_item.as_unsigned_int_8("Item-type") != 0x50) { throw Exception("Invalid item type"); } this->_item.read(stream, "Reserved", Item::Field::Type::unsigned_int_8); this->_item.read(stream, "Item-length", Item::Field::Type::unsigned_int_16); this->_item.add("User-data", std::vector()); auto const begin = stream.tellg(); auto const item_length = this->_item.as_unsigned_int_16("Item-length"); // Store sub-items so that all sub-items of a given type are adjacent, and // that their type is in growing order. std::vector maximum_length; std::vector implementation_class_uid; std::vector role_selection; std::vector implementation_version_name; std::vector user_identity_rq; std::vector user_identity_ac; while(stream.tellg()-begin < item_length) { uint8_t const type = stream.peek(); if(type == 0x51) { maximum_length.push_back(MaximumLength(stream)); } else if(type == 0x52) { implementation_class_uid.push_back(ImplementationClassUID(stream)); } // 0x53: Asynchronous Operations Window, PS 3.7, D.3.3.3.1 else if(type == 0x54) { role_selection.push_back(RoleSelection(stream)); } else if(type == 0x55) { implementation_version_name.push_back( ImplementationVersionName(stream)); } // 0x56: SOP Class Extended Negotiation, PS 3.7, D.3.3.5.1 // 0x57: SOP Class Common Extended Negotiation, PS 3.7, D.3.3.6.1 else if(type == 0x58) { user_identity_rq.push_back(UserIdentityRQ(stream)); } else if(type == 0x59) { user_identity_ac.push_back(UserIdentityAC(stream)); } else { throw Exception("Invalid sub-item type"); } } this->set_sub_items(maximum_length); this->set_sub_items(implementation_class_uid); this->set_sub_items(role_selection); this->set_sub_items(implementation_version_name); this->set_sub_items(user_identity_rq); this->set_sub_items(user_identity_ac); } } } odil-0.4.1/src/odil/pdu/UserInformation.h000066400000000000000000000035401266460524100202560ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _7449339a_913f_4545_9846_311f055632c1 #define _7449339a_913f_4545_9846_311f055632c1 #include #include #include #include "odil/pdu/MaximumLength.h" #include "odil/pdu/Object.h" #include "odil/pdu/UserIdentityAC.h" #include "odil/pdu/UserIdentityRQ.h" namespace odil { namespace pdu { /// @brief User Information Item Structure (PS 3.8, 9.3.2.3 and 9.3.3.3). class UserInformation: public Object { public: /// @brief Create a User Information item with no sub-items. UserInformation(); /// @brief Read a User Information item from a stream. UserInformation(std::istream & stream); /// @brief Return sub-items of given type. template std::vector get_sub_items() const; /// @brief Set a sequence of sub-items. template void set_sub_items(std::vector const & sub_item); /// @brief Delete sub-items of given type. template void delete_sub_items(); private: typedef std::vector Items; /// @brief Return the iterators to the sub items of given type. template std::vector _find_sub_items() const; /// @brief Return the iterators to the sub items of given type. template std::vector _find_sub_items(); }; } } #include "odil/pdu/UserInformation.txx" #endif // _7449339a_913f_4545_9846_311f055632c1 odil-0.4.1/src/odil/pdu/UserInformation.txx000066400000000000000000000076631266460524100206640ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _bb325c55_d983_41e3_b6c4_e3b957baedba #define _bb325c55_d983_41e3_b6c4_e3b957baedba #include "odil/pdu/UserInformation.h" #include #include #include #include #include #include #include "odil/Exception.h" #include "odil/pdu/Item.h" #include "odil/pdu/MaximumLength.h" #include "odil/pdu/Object.h" #include "odil/pdu/UserIdentityAC.h" #include "odil/pdu/UserIdentityRQ.h" namespace odil { namespace pdu { template std::vector UserInformation ::get_sub_items() const { auto const iterators = this->_find_sub_items(); std::vector result; result.reserve(iterators.size()); std::transform( iterators.begin(), iterators.end(), std::back_inserter(result), [](Items::const_iterator const & it) { std::stringstream stream; stream << *it; return TObject(stream); } ); return result; } template void UserInformation ::set_sub_items(std::vector const & sub_items) { auto const & old_items = this->_item.as_items("User-data"); std::vector new_items; auto old_items_iterator = old_items.begin(); while(old_items_iterator != old_items.end() && old_items_iterator->as_unsigned_int_8("Item-type") < TObject::type) { new_items.push_back(*old_items_iterator); ++old_items_iterator; } std::transform( sub_items.begin(), sub_items.end(), std::back_inserter(new_items), [](Object const & object) { return object.get_item(); }); while(old_items_iterator != old_items.end() && old_items_iterator->as_unsigned_int_8("Item-type") == TObject::type) { ++old_items_iterator; } while(old_items_iterator != old_items.end()) { new_items.push_back(*old_items_iterator); ++old_items_iterator; } this->_item.as_items("User-data") = new_items; this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); } template void UserInformation ::delete_sub_items() { auto const & old_items = this->_item.as_items("User-data"); std::vector new_items; std::copy_if( old_items.begin(), old_items.end(), std::back_inserter(new_items), [](Item const & item) { return item.as_unsigned_int_8("Item-type") != TObject::type; } ); this->_item.as_items("User-data") = new_items; this->_item.as_unsigned_int_16("Item-length") = this->_compute_length(); } template std::vector UserInformation ::_find_sub_items() const { std::vector result; auto const & sub_items = this->_item.as_items("User-data"); auto iterator = sub_items.begin(); for(; iterator != sub_items.end(); ++iterator) { if(iterator->as_unsigned_int_8("Item-type") == TObject::type) { result.push_back(iterator); } } return result; } template std::vector UserInformation ::_find_sub_items() { std::vector result; auto & sub_items = this->_item.as_items("User-data"); auto iterator = sub_items.begin(); for(; iterator != sub_items.end(); ++iterator) { if(iterator->as_unsigned_int_8("Item-type") == TObject::type) { result.push_back(iterator); } } return result; } } } #endif // _bb325c55_d983_41e3_b6c4_e3b957baedba odil-0.4.1/src/odil/registry.cpp000066400000000000000000016076071266460524100165640ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include #include "odil/registry.h" #include "odil/ElementsDictionary.h" #include "odil/Tag.h" #include "odil/VR.h" #include "odil/UIDsDictionary.h" namespace odil { namespace registry { struct RawElementsDictionaryEntry { uint16_t group; uint16_t element; char const * name; char const * keyword; char const * vr; char const * vm; }; ElementsDictionary create_public_dictionary() { RawElementsDictionaryEntry raw_entries[] = { { 0x0000, 0x0000, "Command Group Length", "CommandGroupLength", "UL", "1" }, { 0x0000, 0x0002, "Affected SOP Class UID", "AffectedSOPClassUID", "UI", "1" }, { 0x0000, 0x0003, "Requested SOP Class UID", "RequestedSOPClassUID", "UI", "1" }, { 0x0000, 0x0100, "Command Field", "CommandField", "US", "1" }, { 0x0000, 0x0110, "Message ID", "MessageID", "US", "1" }, { 0x0000, 0x0120, "Message ID Being Responded To", "MessageIDBeingRespondedTo", "US", "1" }, { 0x0000, 0x0600, "Move Destination", "MoveDestination", "AE", "1" }, { 0x0000, 0x0700, "Priority", "Priority", "US", "1" }, { 0x0000, 0x0800, "Command Data Set Type", "CommandDataSetType", "US", "1" }, { 0x0000, 0x0900, "Status", "Status", "US", "1" }, { 0x0000, 0x0901, "Offending Element", "OffendingElement", "AT", "1-n" }, { 0x0000, 0x0902, "Error Comment", "ErrorComment", "LO", "1" }, { 0x0000, 0x0903, "Error ID", "ErrorID", "US", "1" }, { 0x0000, 0x1000, "Affected SOP Instance UID", "AffectedSOPInstanceUID", "UI", "1" }, { 0x0000, 0x1001, "Requested SOP Instance UID", "RequestedSOPInstanceUID", "UI", "1" }, { 0x0000, 0x1002, "Event Type ID", "EventTypeID", "US", "1" }, { 0x0000, 0x1005, "Attribute Identifier List", "AttributeIdentifierList", "AT", "1-n" }, { 0x0000, 0x1008, "Action Type ID", "ActionTypeID", "US", "1" }, { 0x0000, 0x1020, "Number of Remaining Sub-operations", "NumberOfRemainingSuboperations", "US", "1" }, { 0x0000, 0x1021, "Number of Completed Sub-operations", "NumberOfCompletedSuboperations", "US", "1" }, { 0x0000, 0x1022, "Number of Failed Sub-operations", "NumberOfFailedSuboperations", "US", "1" }, { 0x0000, 0x1023, "Number of Warning Sub-operations", "NumberOfWarningSuboperations", "US", "1" }, { 0x0000, 0x1030, "Move Originator Application Entity Title", "MoveOriginatorApplicationEntityTitle", "AE", "1" }, { 0x0000, 0x1031, "Move Originator Message ID", "MoveOriginatorMessageID", "US", "1" }, { 0x0002, 0x0000, "File Meta Information Group Length", "FileMetaInformationGroupLength", "UL", "1" }, { 0x0002, 0x0001, "File Meta Information Version", "FileMetaInformationVersion", "OB", "1" }, { 0x0002, 0x0002, "Media Storage SOP Class UID", "MediaStorageSOPClassUID", "UI", "1" }, { 0x0002, 0x0003, "Media Storage SOP Instance UID", "MediaStorageSOPInstanceUID", "UI", "1" }, { 0x0002, 0x0010, "Transfer Syntax UID", "TransferSyntaxUID", "UI", "1" }, { 0x0002, 0x0012, "Implementation Class UID", "ImplementationClassUID", "UI", "1" }, { 0x0002, 0x0013, "Implementation Version Name", "ImplementationVersionName", "SH", "1" }, { 0x0002, 0x0016, "Source Application Entity Title", "SourceApplicationEntityTitle", "AE", "1" }, { 0x0002, 0x0017, "Sending Application Entity Title", "SendingApplicationEntityTitle", "AE", "1" }, { 0x0002, 0x0018, "Receiving Application Entity Title", "ReceivingApplicationEntityTitle", "AE", "1" }, { 0x0002, 0x0100, "Private Information Creator UID", "PrivateInformationCreatorUID", "UI", "1" }, { 0x0002, 0x0102, "Private Information", "PrivateInformation", "OB", "1" }, { 0x0004, 0x1130, "File-set ID", "FileSetID", "CS", "1" }, { 0x0004, 0x1141, "File-set Descriptor File ID", "FileSetDescriptorFileID", "CS", "1-8" }, { 0x0004, 0x1142, "Specific Character Set of File-set Descriptor File", "SpecificCharacterSetOfFileSetDescriptorFile", "CS", "1" }, { 0x0004, 0x1200, "Offset of the First Directory Record of the Root Directory Entity", "OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity", "UL", "1" }, { 0x0004, 0x1202, "Offset of the Last Directory Record of the Root Directory Entity", "OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity", "UL", "1" }, { 0x0004, 0x1212, "File-set Consistency Flag", "FileSetConsistencyFlag", "US", "1" }, { 0x0004, 0x1220, "Directory Record Sequence", "DirectoryRecordSequence", "SQ", "1" }, { 0x0004, 0x1400, "Offset of the Next Directory Record", "OffsetOfTheNextDirectoryRecord", "UL", "1" }, { 0x0004, 0x1410, "Record In-use Flag", "RecordInUseFlag", "US", "1" }, { 0x0004, 0x1420, "Offset of Referenced Lower-Level Directory Entity", "OffsetOfReferencedLowerLevelDirectoryEntity", "UL", "1" }, { 0x0004, 0x1430, "Directory Record Type", "DirectoryRecordType", "CS", "1" }, { 0x0004, 0x1432, "Private Record UID", "PrivateRecordUID", "UI", "1" }, { 0x0004, 0x1500, "Referenced File ID", "ReferencedFileID", "CS", "1-8" }, { 0x0004, 0x1504, "MRDR Directory Record Offset", "MRDRDirectoryRecordOffset", "UL", "1" }, { 0x0004, 0x1510, "Referenced SOP Class UID in File", "ReferencedSOPClassUIDInFile", "UI", "1" }, { 0x0004, 0x1511, "Referenced SOP Instance UID in File", "ReferencedSOPInstanceUIDInFile", "UI", "1" }, { 0x0004, 0x1512, "Referenced Transfer Syntax UID in File", "ReferencedTransferSyntaxUIDInFile", "UI", "1" }, { 0x0004, 0x151a, "Referenced Related General SOP Class UID in File", "ReferencedRelatedGeneralSOPClassUIDInFile", "UI", "1-n" }, { 0x0004, 0x1600, "Number of References", "NumberOfReferences", "UL", "1" }, { 0x0008, 0x0001, "Length to End", "LengthToEnd", "UL", "1" }, { 0x0008, 0x0005, "Specific Character Set", "SpecificCharacterSet", "CS", "1-n" }, { 0x0008, 0x0006, "Language Code Sequence", "LanguageCodeSequence", "SQ", "1" }, { 0x0008, 0x0008, "Image Type", "ImageType", "CS", "2-n" }, { 0x0008, 0x0010, "Recognition Code", "RecognitionCode", "SH", "1" }, { 0x0008, 0x0012, "Instance Creation Date", "InstanceCreationDate", "DA", "1" }, { 0x0008, 0x0013, "Instance Creation Time", "InstanceCreationTime", "TM", "1" }, { 0x0008, 0x0014, "Instance Creator UID", "InstanceCreatorUID", "UI", "1" }, { 0x0008, 0x0015, "Instance Coercion DateTime", "InstanceCoercionDateTime", "DT", "1" }, { 0x0008, 0x0016, "SOP Class UID", "SOPClassUID", "UI", "1" }, { 0x0008, 0x0018, "SOP Instance UID", "SOPInstanceUID", "UI", "1" }, { 0x0008, 0x001a, "Related General SOP Class UID", "RelatedGeneralSOPClassUID", "UI", "1-n" }, { 0x0008, 0x001b, "Original Specialized SOP Class UID", "OriginalSpecializedSOPClassUID", "UI", "1" }, { 0x0008, 0x0020, "Study Date", "StudyDate", "DA", "1" }, { 0x0008, 0x0021, "Series Date", "SeriesDate", "DA", "1" }, { 0x0008, 0x0022, "Acquisition Date", "AcquisitionDate", "DA", "1" }, { 0x0008, 0x0023, "Content Date", "ContentDate", "DA", "1" }, { 0x0008, 0x0024, "Overlay Date", "OverlayDate", "DA", "1" }, { 0x0008, 0x0025, "Curve Date", "CurveDate", "DA", "1" }, { 0x0008, 0x002a, "Acquisition DateTime", "AcquisitionDateTime", "DT", "1" }, { 0x0008, 0x0030, "Study Time", "StudyTime", "TM", "1" }, { 0x0008, 0x0031, "Series Time", "SeriesTime", "TM", "1" }, { 0x0008, 0x0032, "Acquisition Time", "AcquisitionTime", "TM", "1" }, { 0x0008, 0x0033, "Content Time", "ContentTime", "TM", "1" }, { 0x0008, 0x0034, "Overlay Time", "OverlayTime", "TM", "1" }, { 0x0008, 0x0035, "Curve Time", "CurveTime", "TM", "1" }, { 0x0008, 0x0040, "Data Set Type", "DataSetType", "US", "1" }, { 0x0008, 0x0041, "Data Set Subtype", "DataSetSubtype", "LO", "1" }, { 0x0008, 0x0042, "Nuclear Medicine Series Type", "NuclearMedicineSeriesType", "CS", "1" }, { 0x0008, 0x0050, "Accession Number", "AccessionNumber", "SH", "1" }, { 0x0008, 0x0051, "Issuer of Accession Number Sequence", "IssuerOfAccessionNumberSequence", "SQ", "1" }, { 0x0008, 0x0052, "Query/Retrieve Level", "QueryRetrieveLevel", "CS", "1" }, { 0x0008, 0x0053, "Query/Retrieve View", "QueryRetrieveView", "CS", "1" }, { 0x0008, 0x0054, "Retrieve AE Title", "RetrieveAETitle", "AE", "1-n" }, { 0x0008, 0x0056, "Instance Availability", "InstanceAvailability", "CS", "1" }, { 0x0008, 0x0058, "Failed SOP Instance UID List", "FailedSOPInstanceUIDList", "UI", "1-n" }, { 0x0008, 0x0060, "Modality", "Modality", "CS", "1" }, { 0x0008, 0x0061, "Modalities in Study", "ModalitiesInStudy", "CS", "1-n" }, { 0x0008, 0x0062, "SOP Classes in Study", "SOPClassesInStudy", "UI", "1-n" }, { 0x0008, 0x0064, "Conversion Type", "ConversionType", "CS", "1" }, { 0x0008, 0x0068, "Presentation Intent Type", "PresentationIntentType", "CS", "1" }, { 0x0008, 0x0070, "Manufacturer", "Manufacturer", "LO", "1" }, { 0x0008, 0x0080, "Institution Name", "InstitutionName", "LO", "1" }, { 0x0008, 0x0081, "Institution Address", "InstitutionAddress", "ST", "1" }, { 0x0008, 0x0082, "Institution Code Sequence", "InstitutionCodeSequence", "SQ", "1" }, { 0x0008, 0x0090, "Referring Physician's Name", "ReferringPhysicianName", "PN", "1" }, { 0x0008, 0x0092, "Referring Physician's Address", "ReferringPhysicianAddress", "ST", "1" }, { 0x0008, 0x0094, "Referring Physician's Telephone Numbers", "ReferringPhysicianTelephoneNumbers", "SH", "1-n" }, { 0x0008, 0x0096, "Referring Physician Identification Sequence", "ReferringPhysicianIdentificationSequence", "SQ", "1" }, { 0x0008, 0x009c, "Consulting Physician's Name", "ConsultingPhysicianName", "PN", "1-n" }, { 0x0008, 0x009d, "Consulting Physician Identification Sequence", "ConsultingPhysicianIdentificationSequence", "SQ", "1" }, { 0x0008, 0x0100, "Code Value", "CodeValue", "SH", "1" }, { 0x0008, 0x0101, "Extended Code Value", "ExtendedCodeValue", "LO", "1" }, { 0x0008, 0x0102, "Coding Scheme Designator", "CodingSchemeDesignator", "SH", "1" }, { 0x0008, 0x0103, "Coding Scheme Version", "CodingSchemeVersion", "SH", "1" }, { 0x0008, 0x0104, "Code Meaning", "CodeMeaning", "LO", "1" }, { 0x0008, 0x0105, "Mapping Resource", "MappingResource", "CS", "1" }, { 0x0008, 0x0106, "Context Group Version", "ContextGroupVersion", "DT", "1" }, { 0x0008, 0x0107, "Context Group Local Version", "ContextGroupLocalVersion", "DT", "1" }, { 0x0008, 0x0108, "Extended Code Meaning", "ExtendedCodeMeaning", "LT", "1" }, { 0x0008, 0x010b, "Context Group Extension Flag", "ContextGroupExtensionFlag", "CS", "1" }, { 0x0008, 0x010c, "Coding Scheme UID", "CodingSchemeUID", "UI", "1" }, { 0x0008, 0x010d, "Context Group Extension Creator UID", "ContextGroupExtensionCreatorUID", "UI", "1" }, { 0x0008, 0x010f, "Context Identifier", "ContextIdentifier", "CS", "1" }, { 0x0008, 0x0110, "Coding Scheme Identification Sequence", "CodingSchemeIdentificationSequence", "SQ", "1" }, { 0x0008, 0x0112, "Coding Scheme Registry", "CodingSchemeRegistry", "LO", "1" }, { 0x0008, 0x0114, "Coding Scheme External ID", "CodingSchemeExternalID", "ST", "1" }, { 0x0008, 0x0115, "Coding Scheme Name", "CodingSchemeName", "ST", "1" }, { 0x0008, 0x0116, "Coding Scheme Responsible Organization", "CodingSchemeResponsibleOrganization", "ST", "1" }, { 0x0008, 0x0117, "Context UID", "ContextUID", "UI", "1" }, { 0x0008, 0x0118, "Mapping Resource UID", "MappingResourceUID", "UI", "1" }, { 0x0008, 0x0119, "Long Code Value", "LongCodeValue", "UC", "1" }, { 0x0008, 0x0120, "URN Code Value", "URNCodeValue", "UR", "1" }, { 0x0008, 0x0121, "Equivalent Code Sequence", "EquivalentCodeSequence", "SQ", "1" }, { 0x0008, 0x0201, "Timezone Offset From UTC", "TimezoneOffsetFromUTC", "SH", "1" }, { 0x0008, 0x0300, "Private Data Element Characteristics Sequence", "PrivateDataElementCharacteristicsSequence", "SQ", "1" }, { 0x0008, 0x0301, "Private Group Reference", "PrivateGroupReference", "US", "1" }, { 0x0008, 0x0302, "Private Creator Reference", "PrivateCreatorReference", "LO", "1" }, { 0x0008, 0x0303, "Block Identifying Information Status", "BlockIdentifyingInformationStatus", "CS", "1" }, { 0x0008, 0x0304, "Nonidentifying Private Elements", "NonidentifyingPrivateElements", "US", "1-n" }, { 0x0008, 0x0306, "Identifying Private Elements", "IdentifyingPrivateElements", "US", "1-n" }, { 0x0008, 0x0305, "Deidentification Action Sequence", "DeidentificationActionSequence", "SQ", "1" }, { 0x0008, 0x0307, "Deidentification Action", "DeidentificationAction", "CS", "1" }, { 0x0008, 0x1000, "Network ID", "NetworkID", "AE", "1" }, { 0x0008, 0x1010, "Station Name", "StationName", "SH", "1" }, { 0x0008, 0x1030, "Study Description", "StudyDescription", "LO", "1" }, { 0x0008, 0x1032, "Procedure Code Sequence", "ProcedureCodeSequence", "SQ", "1" }, { 0x0008, 0x103e, "Series Description", "SeriesDescription", "LO", "1" }, { 0x0008, 0x103f, "Series Description Code Sequence", "SeriesDescriptionCodeSequence", "SQ", "1" }, { 0x0008, 0x1040, "Institutional Department Name", "InstitutionalDepartmentName", "LO", "1" }, { 0x0008, 0x1048, "Physician(s) of Record", "PhysiciansOfRecord", "PN", "1-n" }, { 0x0008, 0x1049, "Physician(s) of Record Identification Sequence", "PhysiciansOfRecordIdentificationSequence", "SQ", "1" }, { 0x0008, 0x1050, "Performing Physician's Name", "PerformingPhysicianName", "PN", "1-n" }, { 0x0008, 0x1052, "Performing Physician Identification Sequence", "PerformingPhysicianIdentificationSequence", "SQ", "1" }, { 0x0008, 0x1060, "Name of Physician(s) Reading Study", "NameOfPhysiciansReadingStudy", "PN", "1-n" }, { 0x0008, 0x1062, "Physician(s) Reading Study Identification Sequence", "PhysiciansReadingStudyIdentificationSequence", "SQ", "1" }, { 0x0008, 0x1070, "Operators' Name", "OperatorsName", "PN", "1-n" }, { 0x0008, 0x1072, "Operator Identification Sequence", "OperatorIdentificationSequence", "SQ", "1" }, { 0x0008, 0x1080, "Admitting Diagnoses Description", "AdmittingDiagnosesDescription", "LO", "1-n" }, { 0x0008, 0x1084, "Admitting Diagnoses Code Sequence", "AdmittingDiagnosesCodeSequence", "SQ", "1" }, { 0x0008, 0x1090, "Manufacturer's Model Name", "ManufacturerModelName", "LO", "1" }, { 0x0008, 0x1100, "Referenced Results Sequence", "ReferencedResultsSequence", "SQ", "1" }, { 0x0008, 0x1110, "Referenced Study Sequence", "ReferencedStudySequence", "SQ", "1" }, { 0x0008, 0x1111, "Referenced Performed Procedure Step Sequence", "ReferencedPerformedProcedureStepSequence", "SQ", "1" }, { 0x0008, 0x1115, "Referenced Series Sequence", "ReferencedSeriesSequence", "SQ", "1" }, { 0x0008, 0x1120, "Referenced Patient Sequence", "ReferencedPatientSequence", "SQ", "1" }, { 0x0008, 0x1125, "Referenced Visit Sequence", "ReferencedVisitSequence", "SQ", "1" }, { 0x0008, 0x1130, "Referenced Overlay Sequence", "ReferencedOverlaySequence", "SQ", "1" }, { 0x0008, 0x1134, "Referenced Stereometric Instance Sequence", "ReferencedStereometricInstanceSequence", "SQ", "1" }, { 0x0008, 0x113a, "Referenced Waveform Sequence", "ReferencedWaveformSequence", "SQ", "1" }, { 0x0008, 0x1140, "Referenced Image Sequence", "ReferencedImageSequence", "SQ", "1" }, { 0x0008, 0x1145, "Referenced Curve Sequence", "ReferencedCurveSequence", "SQ", "1" }, { 0x0008, 0x114a, "Referenced Instance Sequence", "ReferencedInstanceSequence", "SQ", "1" }, { 0x0008, 0x114b, "Referenced Real World Value Mapping Instance Sequence", "ReferencedRealWorldValueMappingInstanceSequence", "SQ", "1" }, { 0x0008, 0x1150, "Referenced SOP Class UID", "ReferencedSOPClassUID", "UI", "1" }, { 0x0008, 0x1155, "Referenced SOP Instance UID", "ReferencedSOPInstanceUID", "UI", "1" }, { 0x0008, 0x115a, "SOP Classes Supported", "SOPClassesSupported", "UI", "1-n" }, { 0x0008, 0x1160, "Referenced Frame Number", "ReferencedFrameNumber", "IS", "1-n" }, { 0x0008, 0x1161, "Simple Frame List", "SimpleFrameList", "UL", "1-n" }, { 0x0008, 0x1162, "Calculated Frame List", "CalculatedFrameList", "UL", "3-3n" }, { 0x0008, 0x1163, "Time Range", "TimeRange", "FD", "2" }, { 0x0008, 0x1164, "Frame Extraction Sequence", "FrameExtractionSequence", "SQ", "1" }, { 0x0008, 0x1167, "Multi-frame Source SOP Instance UID", "MultiFrameSourceSOPInstanceUID", "UI", "1" }, { 0x0008, 0x1190, "Retrieve URL", "RetrieveURL", "UR", "1" }, { 0x0008, 0x1195, "Transaction UID", "TransactionUID", "UI", "1" }, { 0x0008, 0x1196, "Warning Reason", "WarningReason", "US", "1" }, { 0x0008, 0x1197, "Failure Reason", "FailureReason", "US", "1" }, { 0x0008, 0x1198, "Failed SOP Sequence", "FailedSOPSequence", "SQ", "1" }, { 0x0008, 0x1199, "Referenced SOP Sequence", "ReferencedSOPSequence", "SQ", "1" }, { 0x0008, 0x1200, "Studies Containing Other Referenced Instances Sequence", "StudiesContainingOtherReferencedInstancesSequence", "SQ", "1" }, { 0x0008, 0x1250, "Related Series Sequence", "RelatedSeriesSequence", "SQ", "1" }, { 0x0008, 0x2110, "Lossy Image Compression (Retired)", "LossyImageCompressionRetired", "CS", "1" }, { 0x0008, 0x2111, "Derivation Description", "DerivationDescription", "ST", "1" }, { 0x0008, 0x2112, "Source Image Sequence", "SourceImageSequence", "SQ", "1" }, { 0x0008, 0x2120, "Stage Name", "StageName", "SH", "1" }, { 0x0008, 0x2122, "Stage Number", "StageNumber", "IS", "1" }, { 0x0008, 0x2124, "Number of Stages", "NumberOfStages", "IS", "1" }, { 0x0008, 0x2127, "View Name", "ViewName", "SH", "1" }, { 0x0008, 0x2128, "View Number", "ViewNumber", "IS", "1" }, { 0x0008, 0x2129, "Number of Event Timers", "NumberOfEventTimers", "IS", "1" }, { 0x0008, 0x212a, "Number of Views in Stage", "NumberOfViewsInStage", "IS", "1" }, { 0x0008, 0x2130, "Event Elapsed Time(s)", "EventElapsedTimes", "DS", "1-n" }, { 0x0008, 0x2132, "Event Timer Name(s)", "EventTimerNames", "LO", "1-n" }, { 0x0008, 0x2133, "Event Timer Sequence", "EventTimerSequence", "SQ", "1" }, { 0x0008, 0x2134, "Event Time Offset", "EventTimeOffset", "FD", "1" }, { 0x0008, 0x2135, "Event Code Sequence", "EventCodeSequence", "SQ", "1" }, { 0x0008, 0x2142, "Start Trim", "StartTrim", "IS", "1" }, { 0x0008, 0x2143, "Stop Trim", "StopTrim", "IS", "1" }, { 0x0008, 0x2144, "Recommended Display Frame Rate", "RecommendedDisplayFrameRate", "IS", "1" }, { 0x0008, 0x2200, "Transducer Position", "TransducerPosition", "CS", "1" }, { 0x0008, 0x2204, "Transducer Orientation", "TransducerOrientation", "CS", "1" }, { 0x0008, 0x2208, "Anatomic Structure", "AnatomicStructure", "CS", "1" }, { 0x0008, 0x2218, "Anatomic Region Sequence", "AnatomicRegionSequence", "SQ", "1" }, { 0x0008, 0x2220, "Anatomic Region Modifier Sequence", "AnatomicRegionModifierSequence", "SQ", "1" }, { 0x0008, 0x2228, "Primary Anatomic Structure Sequence", "PrimaryAnatomicStructureSequence", "SQ", "1" }, { 0x0008, 0x2229, "Anatomic Structure, Space or Region Sequence", "AnatomicStructureSpaceOrRegionSequence", "SQ", "1" }, { 0x0008, 0x2230, "Primary Anatomic Structure Modifier Sequence", "PrimaryAnatomicStructureModifierSequence", "SQ", "1" }, { 0x0008, 0x2240, "Transducer Position Sequence", "TransducerPositionSequence", "SQ", "1" }, { 0x0008, 0x2242, "Transducer Position Modifier Sequence", "TransducerPositionModifierSequence", "SQ", "1" }, { 0x0008, 0x2244, "Transducer Orientation Sequence", "TransducerOrientationSequence", "SQ", "1" }, { 0x0008, 0x2246, "Transducer Orientation Modifier Sequence", "TransducerOrientationModifierSequence", "SQ", "1" }, { 0x0008, 0x2251, "Anatomic Structure Space Or Region Code Sequence (Trial)", "AnatomicStructureSpaceOrRegionCodeSequenceTrial", "SQ", "1" }, { 0x0008, 0x2253, "Anatomic Portal Of Entrance Code Sequence (Trial)", "AnatomicPortalOfEntranceCodeSequenceTrial", "SQ", "1" }, { 0x0008, 0x2255, "Anatomic Approach Direction Code Sequence (Trial)", "AnatomicApproachDirectionCodeSequenceTrial", "SQ", "1" }, { 0x0008, 0x2256, "Anatomic Perspective Description (Trial)", "AnatomicPerspectiveDescriptionTrial", "ST", "1" }, { 0x0008, 0x2257, "Anatomic Perspective Code Sequence (Trial)", "AnatomicPerspectiveCodeSequenceTrial", "SQ", "1" }, { 0x0008, 0x2258, "Anatomic Location Of Examining Instrument Description (Trial)", "AnatomicLocationOfExaminingInstrumentDescriptionTrial", "ST", "1" }, { 0x0008, 0x2259, "Anatomic Location Of Examining Instrument Code Sequence (Trial)", "AnatomicLocationOfExaminingInstrumentCodeSequenceTrial", "SQ", "1" }, { 0x0008, 0x225a, "Anatomic Structure Space Or Region Modifier Code Sequence (Trial)", "AnatomicStructureSpaceOrRegionModifierCodeSequenceTrial", "SQ", "1" }, { 0x0008, 0x225c, "On Axis Background Anatomic Structure Code Sequence (Trial)", "OnAxisBackgroundAnatomicStructureCodeSequenceTrial", "SQ", "1" }, { 0x0008, 0x3001, "Alternate Representation Sequence", "AlternateRepresentationSequence", "SQ", "1" }, { 0x0008, 0x3010, "Irradiation Event UID", "IrradiationEventUID", "UI", "1-n" }, { 0x0008, 0x3011, "Source Irradiation Event Sequence", "SourceIrradiationEventSequence", "SQ", "1" }, { 0x0008, 0x3012, "Radiopharmaceutical Administration Event UID", "RadiopharmaceuticalAdministrationEventUID", "UI", "1" }, { 0x0008, 0x4000, "Identifying Comments", "IdentifyingComments", "LT", "1" }, { 0x0008, 0x9007, "Frame Type", "FrameType", "CS", "4" }, { 0x0008, 0x9092, "Referenced Image Evidence Sequence", "ReferencedImageEvidenceSequence", "SQ", "1" }, { 0x0008, 0x9121, "Referenced Raw Data Sequence", "ReferencedRawDataSequence", "SQ", "1" }, { 0x0008, 0x9123, "Creator-Version UID", "CreatorVersionUID", "UI", "1" }, { 0x0008, 0x9124, "Derivation Image Sequence", "DerivationImageSequence", "SQ", "1" }, { 0x0008, 0x9154, "Source Image Evidence Sequence", "SourceImageEvidenceSequence", "SQ", "1" }, { 0x0008, 0x9205, "Pixel Presentation", "PixelPresentation", "CS", "1" }, { 0x0008, 0x9206, "Volumetric Properties", "VolumetricProperties", "CS", "1" }, { 0x0008, 0x9207, "Volume Based Calculation Technique", "VolumeBasedCalculationTechnique", "CS", "1" }, { 0x0008, 0x9208, "Complex Image Component", "ComplexImageComponent", "CS", "1" }, { 0x0008, 0x9209, "Acquisition Contrast", "AcquisitionContrast", "CS", "1" }, { 0x0008, 0x9215, "Derivation Code Sequence", "DerivationCodeSequence", "SQ", "1" }, { 0x0008, 0x9237, "Referenced Presentation State Sequence", "ReferencedPresentationStateSequence", "SQ", "1" }, { 0x0008, 0x9410, "Referenced Other Plane Sequence", "ReferencedOtherPlaneSequence", "SQ", "1" }, { 0x0008, 0x9458, "Frame Display Sequence", "FrameDisplaySequence", "SQ", "1" }, { 0x0008, 0x9459, "Recommended Display Frame Rate in Float", "RecommendedDisplayFrameRateInFloat", "FL", "1" }, { 0x0008, 0x9460, "Skip Frame Range Flag", "SkipFrameRangeFlag", "CS", "1" }, { 0x0010, 0x0010, "Patient's Name", "PatientName", "PN", "1" }, { 0x0010, 0x0020, "Patient ID", "PatientID", "LO", "1" }, { 0x0010, 0x0021, "Issuer of Patient ID", "IssuerOfPatientID", "LO", "1" }, { 0x0010, 0x0022, "Type of Patient ID", "TypeOfPatientID", "CS", "1" }, { 0x0010, 0x0024, "Issuer of Patient ID Qualifiers Sequence", "IssuerOfPatientIDQualifiersSequence", "SQ", "1" }, { 0x0010, 0x0030, "Patient's Birth Date", "PatientBirthDate", "DA", "1" }, { 0x0010, 0x0032, "Patient's Birth Time", "PatientBirthTime", "TM", "1" }, { 0x0010, 0x0040, "Patient's Sex", "PatientSex", "CS", "1" }, { 0x0010, 0x0050, "Patient's Insurance Plan Code Sequence", "PatientInsurancePlanCodeSequence", "SQ", "1" }, { 0x0010, 0x0101, "Patient's Primary Language Code Sequence", "PatientPrimaryLanguageCodeSequence", "SQ", "1" }, { 0x0010, 0x0102, "Patient's Primary Language Modifier Code Sequence", "PatientPrimaryLanguageModifierCodeSequence", "SQ", "1" }, { 0x0010, 0x0200, "Quality Control Subject", "QualityControlSubject", "CS", "1" }, { 0x0010, 0x0201, "Quality Control Subject Type Code Sequence", "QualityControlSubjectTypeCodeSequence", "SQ", "1" }, { 0x0010, 0x1000, "Other Patient IDs", "OtherPatientIDs", "LO", "1-n" }, { 0x0010, 0x1001, "Other Patient Names", "OtherPatientNames", "PN", "1-n" }, { 0x0010, 0x1002, "Other Patient IDs Sequence", "OtherPatientIDsSequence", "SQ", "1" }, { 0x0010, 0x1005, "Patient's Birth Name", "PatientBirthName", "PN", "1" }, { 0x0010, 0x1010, "Patient's Age", "PatientAge", "AS", "1" }, { 0x0010, 0x1020, "Patient's Size", "PatientSize", "DS", "1" }, { 0x0010, 0x1021, "Patient's Size Code Sequence", "PatientSizeCodeSequence", "SQ", "1" }, { 0x0010, 0x1030, "Patient's Weight", "PatientWeight", "DS", "1" }, { 0x0010, 0x1040, "Patient's Address", "PatientAddress", "LO", "1" }, { 0x0010, 0x1050, "Insurance Plan Identification", "InsurancePlanIdentification", "LO", "1-n" }, { 0x0010, 0x1060, "Patient's Mother's Birth Name", "PatientMotherBirthName", "PN", "1" }, { 0x0010, 0x1080, "Military Rank", "MilitaryRank", "LO", "1" }, { 0x0010, 0x1081, "Branch of Service", "BranchOfService", "LO", "1" }, { 0x0010, 0x1090, "Medical Record Locator", "MedicalRecordLocator", "LO", "1" }, { 0x0010, 0x1100, "Referenced Patient Photo Sequence", "ReferencedPatientPhotoSequence", "SQ", "1" }, { 0x0010, 0x2000, "Medical Alerts", "MedicalAlerts", "LO", "1-n" }, { 0x0010, 0x2110, "Allergies", "Allergies", "LO", "1-n" }, { 0x0010, 0x2150, "Country of Residence", "CountryOfResidence", "LO", "1" }, { 0x0010, 0x2152, "Region of Residence", "RegionOfResidence", "LO", "1" }, { 0x0010, 0x2154, "Patient's Telephone Numbers", "PatientTelephoneNumbers", "SH", "1-n" }, { 0x0010, 0x2155, "Patient's Telecom Information", "PatientTelecomInformation", "LT", "1" }, { 0x0010, 0x2160, "Ethnic Group", "EthnicGroup", "SH", "1" }, { 0x0010, 0x2180, "Occupation", "Occupation", "SH", "1" }, { 0x0010, 0x21a0, "Smoking Status", "SmokingStatus", "CS", "1" }, { 0x0010, 0x21b0, "Additional Patient History", "AdditionalPatientHistory", "LT", "1" }, { 0x0010, 0x21c0, "Pregnancy Status", "PregnancyStatus", "US", "1" }, { 0x0010, 0x21d0, "Last Menstrual Date", "LastMenstrualDate", "DA", "1" }, { 0x0010, 0x21f0, "Patient's Religious Preference", "PatientReligiousPreference", "LO", "1" }, { 0x0010, 0x2201, "Patient Species Description", "PatientSpeciesDescription", "LO", "1" }, { 0x0010, 0x2202, "Patient Species Code Sequence", "PatientSpeciesCodeSequence", "SQ", "1" }, { 0x0010, 0x2203, "Patient's Sex Neutered", "PatientSexNeutered", "CS", "1" }, { 0x0010, 0x2210, "Anatomical Orientation Type", "AnatomicalOrientationType", "CS", "1" }, { 0x0010, 0x2292, "Patient Breed Description", "PatientBreedDescription", "LO", "1" }, { 0x0010, 0x2293, "Patient Breed Code Sequence", "PatientBreedCodeSequence", "SQ", "1" }, { 0x0010, 0x2294, "Breed Registration Sequence", "BreedRegistrationSequence", "SQ", "1" }, { 0x0010, 0x2295, "Breed Registration Number", "BreedRegistrationNumber", "LO", "1" }, { 0x0010, 0x2296, "Breed Registry Code Sequence", "BreedRegistryCodeSequence", "SQ", "1" }, { 0x0010, 0x2297, "Responsible Person", "ResponsiblePerson", "PN", "1" }, { 0x0010, 0x2298, "Responsible Person Role", "ResponsiblePersonRole", "CS", "1" }, { 0x0010, 0x2299, "Responsible Organization", "ResponsibleOrganization", "LO", "1" }, { 0x0010, 0x4000, "Patient Comments", "PatientComments", "LT", "1" }, { 0x0010, 0x9431, "Examined Body Thickness", "ExaminedBodyThickness", "FL", "1" }, { 0x0012, 0x0010, "Clinical Trial Sponsor Name", "ClinicalTrialSponsorName", "LO", "1" }, { 0x0012, 0x0020, "Clinical Trial Protocol ID", "ClinicalTrialProtocolID", "LO", "1" }, { 0x0012, 0x0021, "Clinical Trial Protocol Name", "ClinicalTrialProtocolName", "LO", "1" }, { 0x0012, 0x0030, "Clinical Trial Site ID", "ClinicalTrialSiteID", "LO", "1" }, { 0x0012, 0x0031, "Clinical Trial Site Name", "ClinicalTrialSiteName", "LO", "1" }, { 0x0012, 0x0040, "Clinical Trial Subject ID", "ClinicalTrialSubjectID", "LO", "1" }, { 0x0012, 0x0042, "Clinical Trial Subject Reading ID", "ClinicalTrialSubjectReadingID", "LO", "1" }, { 0x0012, 0x0050, "Clinical Trial Time Point ID", "ClinicalTrialTimePointID", "LO", "1" }, { 0x0012, 0x0051, "Clinical Trial Time Point Description", "ClinicalTrialTimePointDescription", "ST", "1" }, { 0x0012, 0x0060, "Clinical Trial Coordinating Center Name", "ClinicalTrialCoordinatingCenterName", "LO", "1" }, { 0x0012, 0x0062, "Patient Identity Removed", "PatientIdentityRemoved", "CS", "1" }, { 0x0012, 0x0063, "De-identification Method", "DeidentificationMethod", "LO", "1-n" }, { 0x0012, 0x0064, "De-identification Method Code Sequence", "DeidentificationMethodCodeSequence", "SQ", "1" }, { 0x0012, 0x0071, "Clinical Trial Series ID", "ClinicalTrialSeriesID", "LO", "1" }, { 0x0012, 0x0072, "Clinical Trial Series Description", "ClinicalTrialSeriesDescription", "LO", "1" }, { 0x0012, 0x0081, "Clinical Trial Protocol Ethics Committee Name", "ClinicalTrialProtocolEthicsCommitteeName", "LO", "1" }, { 0x0012, 0x0082, "Clinical Trial Protocol Ethics Committee Approval Number", "ClinicalTrialProtocolEthicsCommitteeApprovalNumber", "LO", "1" }, { 0x0012, 0x0083, "Consent for Clinical Trial Use Sequence", "ConsentForClinicalTrialUseSequence", "SQ", "1" }, { 0x0012, 0x0084, "Distribution Type", "DistributionType", "CS", "1" }, { 0x0012, 0x0085, "Consent for Distribution Flag", "ConsentForDistributionFlag", "CS", "1" }, { 0x0014, 0x0023, "CAD File Format", "CADFileFormat", "ST", "1-n" }, { 0x0014, 0x0024, "Component Reference System", "ComponentReferenceSystem", "ST", "1-n" }, { 0x0014, 0x0025, "Component Manufacturing Procedure", "ComponentManufacturingProcedure", "ST", "1-n" }, { 0x0014, 0x0028, "Component Manufacturer", "ComponentManufacturer", "ST", "1-n" }, { 0x0014, 0x0030, "Material Thickness", "MaterialThickness", "DS", "1-n" }, { 0x0014, 0x0032, "Material Pipe Diameter", "MaterialPipeDiameter", "DS", "1-n" }, { 0x0014, 0x0034, "Material Isolation Diameter", "MaterialIsolationDiameter", "DS", "1-n" }, { 0x0014, 0x0042, "Material Grade", "MaterialGrade", "ST", "1-n" }, { 0x0014, 0x0044, "Material Properties Description", "MaterialPropertiesDescription", "ST", "1-n" }, { 0x0014, 0x0045, "Material Properties File Format (Retired)", "MaterialPropertiesFileFormatRetired", "ST", "1-n" }, { 0x0014, 0x0046, "Material Notes", "MaterialNotes", "LT", "1" }, { 0x0014, 0x0050, "Component Shape", "ComponentShape", "CS", "1" }, { 0x0014, 0x0052, "Curvature Type", "CurvatureType", "CS", "1" }, { 0x0014, 0x0054, "Outer Diameter", "OuterDiameter", "DS", "1" }, { 0x0014, 0x0056, "Inner Diameter", "InnerDiameter", "DS", "1" }, { 0x0014, 0x1010, "Actual Environmental Conditions", "ActualEnvironmentalConditions", "ST", "1" }, { 0x0014, 0x1020, "Expiry Date", "ExpiryDate", "DA", "1" }, { 0x0014, 0x1040, "Environmental Conditions", "EnvironmentalConditions", "ST", "1" }, { 0x0014, 0x2002, "Evaluator Sequence", "EvaluatorSequence", "SQ", "1" }, { 0x0014, 0x2004, "Evaluator Number", "EvaluatorNumber", "IS", "1" }, { 0x0014, 0x2006, "Evaluator Name", "EvaluatorName", "PN", "1" }, { 0x0014, 0x2008, "Evaluation Attempt", "EvaluationAttempt", "IS", "1" }, { 0x0014, 0x2012, "Indication Sequence", "IndicationSequence", "SQ", "1" }, { 0x0014, 0x2014, "Indication Number", "IndicationNumber", "IS", "1" }, { 0x0014, 0x2016, "Indication Label", "IndicationLabel", "SH", "1" }, { 0x0014, 0x2018, "Indication Description", "IndicationDescription", "ST", "1" }, { 0x0014, 0x201a, "Indication Type", "IndicationType", "CS", "1-n" }, { 0x0014, 0x201c, "Indication Disposition", "IndicationDisposition", "CS", "1" }, { 0x0014, 0x201e, "Indication ROI Sequence", "IndicationROISequence", "SQ", "1" }, { 0x0014, 0x2030, "Indication Physical Property Sequence", "IndicationPhysicalPropertySequence", "SQ", "1" }, { 0x0014, 0x2032, "Property Label", "PropertyLabel", "SH", "1" }, { 0x0014, 0x2202, "Coordinate System Number of Axes", "CoordinateSystemNumberOfAxes", "IS", "1" }, { 0x0014, 0x2204, "Coordinate System Axes Sequence", "CoordinateSystemAxesSequence", "SQ", "1" }, { 0x0014, 0x2206, "Coordinate System Axis Description", "CoordinateSystemAxisDescription", "ST", "1" }, { 0x0014, 0x2208, "Coordinate System Data Set Mapping", "CoordinateSystemDataSetMapping", "CS", "1" }, { 0x0014, 0x220a, "Coordinate System Axis Number", "CoordinateSystemAxisNumber", "IS", "1" }, { 0x0014, 0x220c, "Coordinate System Axis Type", "CoordinateSystemAxisType", "CS", "1" }, { 0x0014, 0x220e, "Coordinate System Axis Units", "CoordinateSystemAxisUnits", "CS", "1" }, { 0x0014, 0x2210, "Coordinate System Axis Values", "CoordinateSystemAxisValues", "OB", "1" }, { 0x0014, 0x2220, "Coordinate System Transform Sequence", "CoordinateSystemTransformSequence", "SQ", "1" }, { 0x0014, 0x2222, "Transform Description", "TransformDescription", "ST", "1" }, { 0x0014, 0x2224, "Transform Number of Axes", "TransformNumberOfAxes", "IS", "1" }, { 0x0014, 0x2226, "Transform Order of Axes", "TransformOrderOfAxes", "IS", "1-n" }, { 0x0014, 0x2228, "Transformed Axis Units", "TransformedAxisUnits", "CS", "1" }, { 0x0014, 0x222a, "Coordinate System Transform Rotation and Scale Matrix", "CoordinateSystemTransformRotationAndScaleMatrix", "DS", "1-n" }, { 0x0014, 0x222c, "Coordinate System Transform Translation Matrix", "CoordinateSystemTransformTranslationMatrix", "DS", "1-n" }, { 0x0014, 0x3011, "Internal Detector Frame Time", "InternalDetectorFrameTime", "DS", "1" }, { 0x0014, 0x3012, "Number of Frames Integrated", "NumberOfFramesIntegrated", "DS", "1" }, { 0x0014, 0x3020, "Detector Temperature Sequence", "DetectorTemperatureSequence", "SQ", "1" }, { 0x0014, 0x3022, "Sensor Name", "SensorName", "ST", "1" }, { 0x0014, 0x3024, "Horizontal Offset of Sensor", "HorizontalOffsetOfSensor", "DS", "1" }, { 0x0014, 0x3026, "Vertical Offset of Sensor", "VerticalOffsetOfSensor", "DS", "1" }, { 0x0014, 0x3028, "Sensor Temperature", "SensorTemperature", "DS", "1" }, { 0x0014, 0x3040, "Dark Current Sequence", "DarkCurrentSequence", "SQ", "1" }, { 0x0014, 0x3050, "Dark Current Counts", "DarkCurrentCounts", "OB or OW", "1" }, { 0x0014, 0x3060, "Gain Correction Reference Sequence", "GainCorrectionReferenceSequence", "SQ", "1" }, { 0x0014, 0x3070, "Air Counts", "AirCounts", "OB or OW", "1" }, { 0x0014, 0x3071, "KV Used in Gain Calibration", "KVUsedInGainCalibration", "DS", "1" }, { 0x0014, 0x3072, "MA Used in Gain Calibration", "MAUsedInGainCalibration", "DS", "1" }, { 0x0014, 0x3073, "Number of Frames Used for Integration", "NumberOfFramesUsedForIntegration", "DS", "1" }, { 0x0014, 0x3074, "Filter Material Used in Gain Calibration", "FilterMaterialUsedInGainCalibration", "LO", "1" }, { 0x0014, 0x3075, "Filter Thickness Used in Gain Calibration", "FilterThicknessUsedInGainCalibration", "DS", "1" }, { 0x0014, 0x3076, "Date of Gain Calibration", "DateOfGainCalibration", "DA", "1" }, { 0x0014, 0x3077, "Time of Gain Calibration", "TimeOfGainCalibration", "TM", "1" }, { 0x0014, 0x3080, "Bad Pixel Image", "BadPixelImage", "OB", "1" }, { 0x0014, 0x3099, "Calibration Notes", "CalibrationNotes", "LT", "1" }, { 0x0014, 0x4002, "Pulser Equipment Sequence", "PulserEquipmentSequence", "SQ", "1" }, { 0x0014, 0x4004, "Pulser Type", "PulserType", "CS", "1" }, { 0x0014, 0x4006, "Pulser Notes", "PulserNotes", "LT", "1" }, { 0x0014, 0x4008, "Receiver Equipment Sequence", "ReceiverEquipmentSequence", "SQ", "1" }, { 0x0014, 0x400a, "Amplifier Type", "AmplifierType", "CS", "1" }, { 0x0014, 0x400c, "Receiver Notes", "ReceiverNotes", "LT", "1" }, { 0x0014, 0x400e, "Pre-Amplifier Equipment Sequence", "PreAmplifierEquipmentSequence", "SQ", "1" }, { 0x0014, 0x400f, "Pre-Amplifier Notes", "PreAmplifierNotes", "LT", "1" }, { 0x0014, 0x4010, "Transmit Transducer Sequence", "TransmitTransducerSequence", "SQ", "1" }, { 0x0014, 0x4011, "Receive Transducer Sequence", "ReceiveTransducerSequence", "SQ", "1" }, { 0x0014, 0x4012, "Number of Elements", "NumberOfElements", "US", "1" }, { 0x0014, 0x4013, "Element Shape", "ElementShape", "CS", "1" }, { 0x0014, 0x4014, "Element Dimension A", "ElementDimensionA", "DS", "1" }, { 0x0014, 0x4015, "Element Dimension B", "ElementDimensionB", "DS", "1" }, { 0x0014, 0x4016, "Element Pitch A", "ElementPitchA", "DS", "1" }, { 0x0014, 0x4017, "Measured Beam Dimension A", "MeasuredBeamDimensionA", "DS", "1" }, { 0x0014, 0x4018, "Measured Beam Dimension B", "MeasuredBeamDimensionB", "DS", "1" }, { 0x0014, 0x4019, "Location of Measured Beam Diameter", "LocationOfMeasuredBeamDiameter", "DS", "1" }, { 0x0014, 0x401a, "Nominal Frequency", "NominalFrequency", "DS", "1" }, { 0x0014, 0x401b, "Measured Center Frequency", "MeasuredCenterFrequency", "DS", "1" }, { 0x0014, 0x401c, "Measured Bandwidth", "MeasuredBandwidth", "DS", "1" }, { 0x0014, 0x401d, "Element Pitch B", "ElementPitchB", "DS", "1" }, { 0x0014, 0x4020, "Pulser Settings Sequence", "PulserSettingsSequence", "SQ", "1" }, { 0x0014, 0x4022, "Pulse Width", "PulseWidth", "DS", "1" }, { 0x0014, 0x4024, "Excitation Frequency", "ExcitationFrequency", "DS", "1" }, { 0x0014, 0x4026, "Modulation Type", "ModulationType", "CS", "1" }, { 0x0014, 0x4028, "Damping", "Damping", "DS", "1" }, { 0x0014, 0x4030, "Receiver Settings Sequence", "ReceiverSettingsSequence", "SQ", "1" }, { 0x0014, 0x4031, "Acquired Soundpath Length", "AcquiredSoundpathLength", "DS", "1" }, { 0x0014, 0x4032, "Acquisition Compression Type", "AcquisitionCompressionType", "CS", "1" }, { 0x0014, 0x4033, "Acquisition Sample Size", "AcquisitionSampleSize", "IS", "1" }, { 0x0014, 0x4034, "Rectifier Smoothing", "RectifierSmoothing", "DS", "1" }, { 0x0014, 0x4035, "DAC Sequence", "DACSequence", "SQ", "1" }, { 0x0014, 0x4036, "DAC Type", "DACType", "CS", "1" }, { 0x0014, 0x4038, "DAC Gain Points", "DACGainPoints", "DS", "1-n" }, { 0x0014, 0x403a, "DAC Time Points", "DACTimePoints", "DS", "1-n" }, { 0x0014, 0x403c, "DAC Amplitude", "DACAmplitude", "DS", "1-n" }, { 0x0014, 0x4040, "Pre-Amplifier Settings Sequence", "PreAmplifierSettingsSequence", "SQ", "1" }, { 0x0014, 0x4050, "Transmit Transducer Settings Sequence", "TransmitTransducerSettingsSequence", "SQ", "1" }, { 0x0014, 0x4051, "Receive Transducer Settings Sequence", "ReceiveTransducerSettingsSequence", "SQ", "1" }, { 0x0014, 0x4052, "Incident Angle", "IncidentAngle", "DS", "1" }, { 0x0014, 0x4054, "Coupling Technique", "CouplingTechnique", "ST", "1" }, { 0x0014, 0x4056, "Coupling Medium", "CouplingMedium", "ST", "1" }, { 0x0014, 0x4057, "Coupling Velocity", "CouplingVelocity", "DS", "1" }, { 0x0014, 0x4058, "Probe Center Location X", "ProbeCenterLocationX", "DS", "1" }, { 0x0014, 0x4059, "Probe Center Location Z", "ProbeCenterLocationZ", "DS", "1" }, { 0x0014, 0x405a, "Sound Path Length", "SoundPathLength", "DS", "1" }, { 0x0014, 0x405c, "Delay Law Identifier", "DelayLawIdentifier", "ST", "1" }, { 0x0014, 0x4060, "Gate Settings Sequence", "GateSettingsSequence", "SQ", "1" }, { 0x0014, 0x4062, "Gate Threshold", "GateThreshold", "DS", "1" }, { 0x0014, 0x4064, "Velocity of Sound", "VelocityOfSound", "DS", "1" }, { 0x0014, 0x4070, "Calibration Settings Sequence", "CalibrationSettingsSequence", "SQ", "1" }, { 0x0014, 0x4072, "Calibration Procedure", "CalibrationProcedure", "ST", "1" }, { 0x0014, 0x4074, "Procedure Version", "ProcedureVersion", "SH", "1" }, { 0x0014, 0x4076, "Procedure Creation Date", "ProcedureCreationDate", "DA", "1" }, { 0x0014, 0x4078, "Procedure Expiration Date", "ProcedureExpirationDate", "DA", "1" }, { 0x0014, 0x407a, "Procedure Last Modified Date", "ProcedureLastModifiedDate", "DA", "1" }, { 0x0014, 0x407c, "Calibration Time", "CalibrationTime", "TM", "1-n" }, { 0x0014, 0x407e, "Calibration Date", "CalibrationDate", "DA", "1-n" }, { 0x0014, 0x4080, "Probe Drive Equipment Sequence", "ProbeDriveEquipmentSequence", "SQ", "1" }, { 0x0014, 0x4081, "Drive Type", "DriveType", "CS", "1" }, { 0x0014, 0x4082, "Probe Drive Notes", "ProbeDriveNotes", "LT", "1" }, { 0x0014, 0x4083, "Drive Probe Sequence", "DriveProbeSequence", "SQ", "1" }, { 0x0014, 0x4084, "Probe Inductance", "ProbeInductance", "DS", "1" }, { 0x0014, 0x4085, "Probe Resistance", "ProbeResistance", "DS", "1" }, { 0x0014, 0x4086, "Receive Probe Sequence", "ReceiveProbeSequence", "SQ", "1" }, { 0x0014, 0x4087, "Probe Drive Settings Sequence", "ProbeDriveSettingsSequence", "SQ", "1" }, { 0x0014, 0x4088, "Bridge Resistors", "BridgeResistors", "DS", "1" }, { 0x0014, 0x4089, "Probe Orientation Angle", "ProbeOrientationAngle", "DS", "1" }, { 0x0014, 0x408b, "User Selected Gain Y", "UserSelectedGainY", "DS", "1" }, { 0x0014, 0x408c, "User Selected Phase", "UserSelectedPhase", "DS", "1" }, { 0x0014, 0x408d, "User Selected Offset X", "UserSelectedOffsetX", "DS", "1" }, { 0x0014, 0x408e, "User Selected Offset Y", "UserSelectedOffsetY", "DS", "1" }, { 0x0014, 0x4091, "Channel Settings Sequence", "ChannelSettingsSequence", "SQ", "1" }, { 0x0014, 0x4092, "Channel Threshold", "ChannelThreshold", "DS", "1" }, { 0x0014, 0x409a, "Scanner Settings Sequence", "ScannerSettingsSequence", "SQ", "1" }, { 0x0014, 0x409b, "Scan Procedure", "ScanProcedure", "ST", "1" }, { 0x0014, 0x409c, "Translation Rate X", "TranslationRateX", "DS", "1" }, { 0x0014, 0x409d, "Translation Rate Y", "TranslationRateY", "DS", "1" }, { 0x0014, 0x409f, "Channel Overlap", "ChannelOverlap", "DS", "1" }, { 0x0014, 0x40a0, "Image Quality Indicator Type", "ImageQualityIndicatorType", "LO", "1" }, { 0x0014, 0x40a1, "Image Quality Indicator Material", "ImageQualityIndicatorMaterial", "LO", "1" }, { 0x0014, 0x40a2, "Image Quality Indicator Size", "ImageQualityIndicatorSize", "LO", "1" }, { 0x0014, 0x5002, "LINAC Energy", "LINACEnergy", "IS", "1" }, { 0x0014, 0x5004, "LINAC Output", "LINACOutput", "IS", "1" }, { 0x0014, 0x5100, "Active Aperture", "ActiveAperture", "US", "1" }, { 0x0014, 0x5101, "Total Aperture", "TotalAperture", "DS", "1" }, { 0x0014, 0x5102, "Aperture Elevation", "ApertureElevation", "DS", "1" }, { 0x0014, 0x5103, "Main Lobe Angle", "MainLobeAngle", "DS", "1" }, { 0x0014, 0x5104, "Main Roof Angle", "MainRoofAngle", "DS", "1" }, { 0x0014, 0x5105, "Connector Type", "ConnectorType", "CS", "1" }, { 0x0014, 0x5106, "Wedge Model Number", "WedgeModelNumber", "SH", "1" }, { 0x0014, 0x5107, "Wedge Angle Float", "WedgeAngleFloat", "DS", "1" }, { 0x0014, 0x5108, "Wedge Roof Angle", "WedgeRoofAngle", "DS", "1" }, { 0x0014, 0x5109, "Wedge Element 1 Position", "WedgeElement1Position", "CS", "1" }, { 0x0014, 0x510a, "Wedge Material Velocity", "WedgeMaterialVelocity", "DS", "1" }, { 0x0014, 0x510b, "Wedge Material", "WedgeMaterial", "SH", "1" }, { 0x0014, 0x510c, "Wedge Offset Z", "WedgeOffsetZ", "DS", "1" }, { 0x0014, 0x510d, "Wedge Origin Offset X", "WedgeOriginOffsetX", "DS", "1" }, { 0x0014, 0x510e, "Wedge Time Delay", "WedgeTimeDelay", "DS", "1" }, { 0x0014, 0x510f, "Wedge Name", "WedgeName", "SH", "1" }, { 0x0014, 0x5110, "Wedge Manufacturer Name", "WedgeManufacturerName", "SH", "1" }, { 0x0014, 0x5111, "Wedge Description", "WedgeDescription", "LO", "1" }, { 0x0014, 0x5112, "Nominal Beam Angle", "NominalBeamAngle", "DS", "1" }, { 0x0014, 0x5113, "Wedge Offset X", "WedgeOffsetX", "DS", "1" }, { 0x0014, 0x5114, "Wedge Offset Y", "WedgeOffsetY", "DS", "1" }, { 0x0014, 0x5115, "Wedge Total Length", "WedgeTotalLength", "DS", "1" }, { 0x0014, 0x5116, "Wedge In Contact Length", "WedgeInContactLength", "DS", "1" }, { 0x0014, 0x5117, "Wedge Front Gap", "WedgeFrontGap", "DS", "1" }, { 0x0014, 0x5118, "Wedge Total Height", "WedgeTotalHeight", "DS", "1" }, { 0x0014, 0x5119, "Wedge Front Height", "WedgeFrontHeight", "DS", "1" }, { 0x0014, 0x511a, "Wedge Rear Height", "WedgeRearHeight", "DS", "1" }, { 0x0014, 0x511b, "Wedge Total Width", "WedgeTotalWidth", "DS", "1" }, { 0x0014, 0x511c, "Wedge In Contact Width", "WedgeInContactWidth", "DS", "1" }, { 0x0014, 0x511d, "Wedge Chamfer Height", "WedgeChamferHeight", "DS", "1" }, { 0x0014, 0x511e, "Wedge Curve", "WedgeCurve", "CS", "1" }, { 0x0014, 0x511f, "Radius Along the Wedge", "RadiusAlongWedge", "DS", "1" }, { 0x0018, 0x0010, "Contrast/Bolus Agent", "ContrastBolusAgent", "LO", "1" }, { 0x0018, 0x0012, "Contrast/Bolus Agent Sequence", "ContrastBolusAgentSequence", "SQ", "1" }, { 0x0018, 0x0013, "Contrast/Bolus T1 Relaxivity", "ContrastBolusT1Relaxivity", "FL", "1" }, { 0x0018, 0x0014, "Contrast/Bolus Administration Route Sequence", "ContrastBolusAdministrationRouteSequence", "SQ", "1" }, { 0x0018, 0x0015, "Body Part Examined", "BodyPartExamined", "CS", "1" }, { 0x0018, 0x0020, "Scanning Sequence", "ScanningSequence", "CS", "1-n" }, { 0x0018, 0x0021, "Sequence Variant", "SequenceVariant", "CS", "1-n" }, { 0x0018, 0x0022, "Scan Options", "ScanOptions", "CS", "1-n" }, { 0x0018, 0x0023, "MR Acquisition Type", "MRAcquisitionType", "CS", "1" }, { 0x0018, 0x0024, "Sequence Name", "SequenceName", "SH", "1" }, { 0x0018, 0x0025, "Angio Flag", "AngioFlag", "CS", "1" }, { 0x0018, 0x0026, "Intervention Drug Information Sequence", "InterventionDrugInformationSequence", "SQ", "1" }, { 0x0018, 0x0027, "Intervention Drug Stop Time", "InterventionDrugStopTime", "TM", "1" }, { 0x0018, 0x0028, "Intervention Drug Dose", "InterventionDrugDose", "DS", "1" }, { 0x0018, 0x0029, "Intervention Drug Code Sequence", "InterventionDrugCodeSequence", "SQ", "1" }, { 0x0018, 0x002a, "Additional Drug Sequence", "AdditionalDrugSequence", "SQ", "1" }, { 0x0018, 0x0030, "Radionuclide", "Radionuclide", "LO", "1-n" }, { 0x0018, 0x0031, "Radiopharmaceutical", "Radiopharmaceutical", "LO", "1" }, { 0x0018, 0x0032, "Energy Window Centerline", "EnergyWindowCenterline", "DS", "1" }, { 0x0018, 0x0033, "Energy Window Total Width", "EnergyWindowTotalWidth", "DS", "1-n" }, { 0x0018, 0x0034, "Intervention Drug Name", "InterventionDrugName", "LO", "1" }, { 0x0018, 0x0035, "Intervention Drug Start Time", "InterventionDrugStartTime", "TM", "1" }, { 0x0018, 0x0036, "Intervention Sequence", "InterventionSequence", "SQ", "1" }, { 0x0018, 0x0037, "Therapy Type", "TherapyType", "CS", "1" }, { 0x0018, 0x0038, "Intervention Status", "InterventionStatus", "CS", "1" }, { 0x0018, 0x0039, "Therapy Description", "TherapyDescription", "CS", "1" }, { 0x0018, 0x003a, "Intervention Description", "InterventionDescription", "ST", "1" }, { 0x0018, 0x0040, "Cine Rate", "CineRate", "IS", "1" }, { 0x0018, 0x0042, "Initial Cine Run State", "InitialCineRunState", "CS", "1" }, { 0x0018, 0x0050, "Slice Thickness", "SliceThickness", "DS", "1" }, { 0x0018, 0x0060, "KVP", "KVP", "DS", "1" }, { 0x0018, 0x0070, "Counts Accumulated", "CountsAccumulated", "IS", "1" }, { 0x0018, 0x0071, "Acquisition Termination Condition", "AcquisitionTerminationCondition", "CS", "1" }, { 0x0018, 0x0072, "Effective Duration", "EffectiveDuration", "DS", "1" }, { 0x0018, 0x0073, "Acquisition Start Condition", "AcquisitionStartCondition", "CS", "1" }, { 0x0018, 0x0074, "Acquisition Start Condition Data", "AcquisitionStartConditionData", "IS", "1" }, { 0x0018, 0x0075, "Acquisition Termination Condition Data", "AcquisitionTerminationConditionData", "IS", "1" }, { 0x0018, 0x0080, "Repetition Time", "RepetitionTime", "DS", "1" }, { 0x0018, 0x0081, "Echo Time", "EchoTime", "DS", "1" }, { 0x0018, 0x0082, "Inversion Time", "InversionTime", "DS", "1" }, { 0x0018, 0x0083, "Number of Averages", "NumberOfAverages", "DS", "1" }, { 0x0018, 0x0084, "Imaging Frequency", "ImagingFrequency", "DS", "1" }, { 0x0018, 0x0085, "Imaged Nucleus", "ImagedNucleus", "SH", "1" }, { 0x0018, 0x0086, "Echo Number(s)", "EchoNumbers", "IS", "1-n" }, { 0x0018, 0x0087, "Magnetic Field Strength", "MagneticFieldStrength", "DS", "1" }, { 0x0018, 0x0088, "Spacing Between Slices", "SpacingBetweenSlices", "DS", "1" }, { 0x0018, 0x0089, "Number of Phase Encoding Steps", "NumberOfPhaseEncodingSteps", "IS", "1" }, { 0x0018, 0x0090, "Data Collection Diameter", "DataCollectionDiameter", "DS", "1" }, { 0x0018, 0x0091, "Echo Train Length", "EchoTrainLength", "IS", "1" }, { 0x0018, 0x0093, "Percent Sampling", "PercentSampling", "DS", "1" }, { 0x0018, 0x0094, "Percent Phase Field of View", "PercentPhaseFieldOfView", "DS", "1" }, { 0x0018, 0x0095, "Pixel Bandwidth", "PixelBandwidth", "DS", "1" }, { 0x0018, 0x1000, "Device Serial Number", "DeviceSerialNumber", "LO", "1" }, { 0x0018, 0x1002, "Device UID", "DeviceUID", "UI", "1" }, { 0x0018, 0x1003, "Device ID", "DeviceID", "LO", "1" }, { 0x0018, 0x1004, "Plate ID", "PlateID", "LO", "1" }, { 0x0018, 0x1005, "Generator ID", "GeneratorID", "LO", "1" }, { 0x0018, 0x1006, "Grid ID", "GridID", "LO", "1" }, { 0x0018, 0x1007, "Cassette ID", "CassetteID", "LO", "1" }, { 0x0018, 0x1008, "Gantry ID", "GantryID", "LO", "1" }, { 0x0018, 0x1010, "Secondary Capture Device ID", "SecondaryCaptureDeviceID", "LO", "1" }, { 0x0018, 0x1011, "Hardcopy Creation Device ID", "HardcopyCreationDeviceID", "LO", "1" }, { 0x0018, 0x1012, "Date of Secondary Capture", "DateOfSecondaryCapture", "DA", "1" }, { 0x0018, 0x1014, "Time of Secondary Capture", "TimeOfSecondaryCapture", "TM", "1" }, { 0x0018, 0x1016, "Secondary Capture Device Manufacturer", "SecondaryCaptureDeviceManufacturer", "LO", "1" }, { 0x0018, 0x1017, "Hardcopy Device Manufacturer", "HardcopyDeviceManufacturer", "LO", "1" }, { 0x0018, 0x1018, "Secondary Capture Device Manufacturer's Model Name", "SecondaryCaptureDeviceManufacturerModelName", "LO", "1" }, { 0x0018, 0x1019, "Secondary Capture Device Software Versions", "SecondaryCaptureDeviceSoftwareVersions", "LO", "1-n" }, { 0x0018, 0x101a, "Hardcopy Device Software Version", "HardcopyDeviceSoftwareVersion", "LO", "1-n" }, { 0x0018, 0x101b, "Hardcopy Device Manufacturer's Model Name", "HardcopyDeviceManufacturerModelName", "LO", "1" }, { 0x0018, 0x1020, "Software Version(s)", "SoftwareVersions", "LO", "1-n" }, { 0x0018, 0x1022, "Video Image Format Acquired", "VideoImageFormatAcquired", "SH", "1" }, { 0x0018, 0x1023, "Digital Image Format Acquired", "DigitalImageFormatAcquired", "LO", "1" }, { 0x0018, 0x1030, "Protocol Name", "ProtocolName", "LO", "1" }, { 0x0018, 0x1040, "Contrast/Bolus Route", "ContrastBolusRoute", "LO", "1" }, { 0x0018, 0x1041, "Contrast/Bolus Volume", "ContrastBolusVolume", "DS", "1" }, { 0x0018, 0x1042, "Contrast/Bolus Start Time", "ContrastBolusStartTime", "TM", "1" }, { 0x0018, 0x1043, "Contrast/Bolus Stop Time", "ContrastBolusStopTime", "TM", "1" }, { 0x0018, 0x1044, "Contrast/Bolus Total Dose", "ContrastBolusTotalDose", "DS", "1" }, { 0x0018, 0x1045, "Syringe Counts", "SyringeCounts", "IS", "1" }, { 0x0018, 0x1046, "Contrast Flow Rate", "ContrastFlowRate", "DS", "1-n" }, { 0x0018, 0x1047, "Contrast Flow Duration", "ContrastFlowDuration", "DS", "1-n" }, { 0x0018, 0x1048, "Contrast/Bolus Ingredient", "ContrastBolusIngredient", "CS", "1" }, { 0x0018, 0x1049, "Contrast/Bolus Ingredient Concentration", "ContrastBolusIngredientConcentration", "DS", "1" }, { 0x0018, 0x1050, "Spatial Resolution", "SpatialResolution", "DS", "1" }, { 0x0018, 0x1060, "Trigger Time", "TriggerTime", "DS", "1" }, { 0x0018, 0x1061, "Trigger Source or Type", "TriggerSourceOrType", "LO", "1" }, { 0x0018, 0x1062, "Nominal Interval", "NominalInterval", "IS", "1" }, { 0x0018, 0x1063, "Frame Time", "FrameTime", "DS", "1" }, { 0x0018, 0x1064, "Cardiac Framing Type", "CardiacFramingType", "LO", "1" }, { 0x0018, 0x1065, "Frame Time Vector", "FrameTimeVector", "DS", "1-n" }, { 0x0018, 0x1066, "Frame Delay", "FrameDelay", "DS", "1" }, { 0x0018, 0x1067, "Image Trigger Delay", "ImageTriggerDelay", "DS", "1" }, { 0x0018, 0x1068, "Multiplex Group Time Offset", "MultiplexGroupTimeOffset", "DS", "1" }, { 0x0018, 0x1069, "Trigger Time Offset", "TriggerTimeOffset", "DS", "1" }, { 0x0018, 0x106a, "Synchronization Trigger", "SynchronizationTrigger", "CS", "1" }, { 0x0018, 0x106c, "Synchronization Channel", "SynchronizationChannel", "US", "2" }, { 0x0018, 0x106e, "Trigger Sample Position", "TriggerSamplePosition", "UL", "1" }, { 0x0018, 0x1070, "Radiopharmaceutical Route", "RadiopharmaceuticalRoute", "LO", "1" }, { 0x0018, 0x1071, "Radiopharmaceutical Volume", "RadiopharmaceuticalVolume", "DS", "1" }, { 0x0018, 0x1072, "Radiopharmaceutical Start Time", "RadiopharmaceuticalStartTime", "TM", "1" }, { 0x0018, 0x1073, "Radiopharmaceutical Stop Time", "RadiopharmaceuticalStopTime", "TM", "1" }, { 0x0018, 0x1074, "Radionuclide Total Dose", "RadionuclideTotalDose", "DS", "1" }, { 0x0018, 0x1075, "Radionuclide Half Life", "RadionuclideHalfLife", "DS", "1" }, { 0x0018, 0x1076, "Radionuclide Positron Fraction", "RadionuclidePositronFraction", "DS", "1" }, { 0x0018, 0x1077, "Radiopharmaceutical Specific Activity", "RadiopharmaceuticalSpecificActivity", "DS", "1" }, { 0x0018, 0x1078, "Radiopharmaceutical Start DateTime", "RadiopharmaceuticalStartDateTime", "DT", "1" }, { 0x0018, 0x1079, "Radiopharmaceutical Stop DateTime", "RadiopharmaceuticalStopDateTime", "DT", "1" }, { 0x0018, 0x1080, "Beat Rejection Flag", "BeatRejectionFlag", "CS", "1" }, { 0x0018, 0x1081, "Low R-R Value", "LowRRValue", "IS", "1" }, { 0x0018, 0x1082, "High R-R Value", "HighRRValue", "IS", "1" }, { 0x0018, 0x1083, "Intervals Acquired", "IntervalsAcquired", "IS", "1" }, { 0x0018, 0x1084, "Intervals Rejected", "IntervalsRejected", "IS", "1" }, { 0x0018, 0x1085, "PVC Rejection", "PVCRejection", "LO", "1" }, { 0x0018, 0x1086, "Skip Beats", "SkipBeats", "IS", "1" }, { 0x0018, 0x1088, "Heart Rate", "HeartRate", "IS", "1" }, { 0x0018, 0x1090, "Cardiac Number of Images", "CardiacNumberOfImages", "IS", "1" }, { 0x0018, 0x1094, "Trigger Window", "TriggerWindow", "IS", "1" }, { 0x0018, 0x1100, "Reconstruction Diameter", "ReconstructionDiameter", "DS", "1" }, { 0x0018, 0x1110, "Distance Source to Detector", "DistanceSourceToDetector", "DS", "1" }, { 0x0018, 0x1111, "Distance Source to Patient", "DistanceSourceToPatient", "DS", "1" }, { 0x0018, 0x1114, "Estimated Radiographic Magnification Factor", "EstimatedRadiographicMagnificationFactor", "DS", "1" }, { 0x0018, 0x1120, "Gantry/Detector Tilt", "GantryDetectorTilt", "DS", "1" }, { 0x0018, 0x1121, "Gantry/Detector Slew", "GantryDetectorSlew", "DS", "1" }, { 0x0018, 0x1130, "Table Height", "TableHeight", "DS", "1" }, { 0x0018, 0x1131, "Table Traverse", "TableTraverse", "DS", "1" }, { 0x0018, 0x1134, "Table Motion", "TableMotion", "CS", "1" }, { 0x0018, 0x1135, "Table Vertical Increment", "TableVerticalIncrement", "DS", "1-n" }, { 0x0018, 0x1136, "Table Lateral Increment", "TableLateralIncrement", "DS", "1-n" }, { 0x0018, 0x1137, "Table Longitudinal Increment", "TableLongitudinalIncrement", "DS", "1-n" }, { 0x0018, 0x1138, "Table Angle", "TableAngle", "DS", "1" }, { 0x0018, 0x113a, "Table Type", "TableType", "CS", "1" }, { 0x0018, 0x1140, "Rotation Direction", "RotationDirection", "CS", "1" }, { 0x0018, 0x1141, "Angular Position", "AngularPosition", "DS", "1" }, { 0x0018, 0x1142, "Radial Position", "RadialPosition", "DS", "1-n" }, { 0x0018, 0x1143, "Scan Arc", "ScanArc", "DS", "1" }, { 0x0018, 0x1144, "Angular Step", "AngularStep", "DS", "1" }, { 0x0018, 0x1145, "Center of Rotation Offset", "CenterOfRotationOffset", "DS", "1" }, { 0x0018, 0x1146, "Rotation Offset", "RotationOffset", "DS", "1-n" }, { 0x0018, 0x1147, "Field of View Shape", "FieldOfViewShape", "CS", "1" }, { 0x0018, 0x1149, "Field of View Dimension(s)", "FieldOfViewDimensions", "IS", "1-2" }, { 0x0018, 0x1150, "Exposure Time", "ExposureTime", "IS", "1" }, { 0x0018, 0x1151, "X-Ray Tube Current", "XRayTubeCurrent", "IS", "1" }, { 0x0018, 0x1152, "Exposure", "Exposure", "IS", "1" }, { 0x0018, 0x1153, "Exposure in uAs", "ExposureInuAs", "IS", "1" }, { 0x0018, 0x1154, "Average Pulse Width", "AveragePulseWidth", "DS", "1" }, { 0x0018, 0x1155, "Radiation Setting", "RadiationSetting", "CS", "1" }, { 0x0018, 0x1156, "Rectification Type", "RectificationType", "CS", "1" }, { 0x0018, 0x115a, "Radiation Mode", "RadiationMode", "CS", "1" }, { 0x0018, 0x115e, "Image and Fluoroscopy Area Dose Product", "ImageAndFluoroscopyAreaDoseProduct", "DS", "1" }, { 0x0018, 0x1160, "Filter Type", "FilterType", "SH", "1" }, { 0x0018, 0x1161, "Type of Filters", "TypeOfFilters", "LO", "1-n" }, { 0x0018, 0x1162, "Intensifier Size", "IntensifierSize", "DS", "1" }, { 0x0018, 0x1164, "Imager Pixel Spacing", "ImagerPixelSpacing", "DS", "2" }, { 0x0018, 0x1166, "Grid", "Grid", "CS", "1-n" }, { 0x0018, 0x1170, "Generator Power", "GeneratorPower", "IS", "1" }, { 0x0018, 0x1180, "Collimator/grid Name", "CollimatorGridName", "SH", "1" }, { 0x0018, 0x1181, "Collimator Type", "CollimatorType", "CS", "1" }, { 0x0018, 0x1182, "Focal Distance", "FocalDistance", "IS", "1-2" }, { 0x0018, 0x1183, "X Focus Center", "XFocusCenter", "DS", "1-2" }, { 0x0018, 0x1184, "Y Focus Center", "YFocusCenter", "DS", "1-2" }, { 0x0018, 0x1190, "Focal Spot(s)", "FocalSpots", "DS", "1-n" }, { 0x0018, 0x1191, "Anode Target Material", "AnodeTargetMaterial", "CS", "1" }, { 0x0018, 0x11a0, "Body Part Thickness", "BodyPartThickness", "DS", "1" }, { 0x0018, 0x11a2, "Compression Force", "CompressionForce", "DS", "1" }, { 0x0018, 0x11a4, "Paddle Description", "PaddleDescription", "LO", "1" }, { 0x0018, 0x1200, "Date of Last Calibration", "DateOfLastCalibration", "DA", "1-n" }, { 0x0018, 0x1201, "Time of Last Calibration", "TimeOfLastCalibration", "TM", "1-n" }, { 0x0018, 0x1202, "DateTime of Last Calibration", "DateTimeOfLastCalibration", "DT", "1" }, { 0x0018, 0x1210, "Convolution Kernel", "ConvolutionKernel", "SH", "1-n" }, { 0x0018, 0x1240, "Upper/Lower Pixel Values", "UpperLowerPixelValues", "IS", "1-n" }, { 0x0018, 0x1242, "Actual Frame Duration", "ActualFrameDuration", "IS", "1" }, { 0x0018, 0x1243, "Count Rate", "CountRate", "IS", "1" }, { 0x0018, 0x1244, "Preferred Playback Sequencing", "PreferredPlaybackSequencing", "US", "1" }, { 0x0018, 0x1250, "Receive Coil Name", "ReceiveCoilName", "SH", "1" }, { 0x0018, 0x1251, "Transmit Coil Name", "TransmitCoilName", "SH", "1" }, { 0x0018, 0x1260, "Plate Type", "PlateType", "SH", "1" }, { 0x0018, 0x1261, "Phosphor Type", "PhosphorType", "LO", "1" }, { 0x0018, 0x1300, "Scan Velocity", "ScanVelocity", "DS", "1" }, { 0x0018, 0x1301, "Whole Body Technique", "WholeBodyTechnique", "CS", "1-n" }, { 0x0018, 0x1302, "Scan Length", "ScanLength", "IS", "1" }, { 0x0018, 0x1310, "Acquisition Matrix", "AcquisitionMatrix", "US", "4" }, { 0x0018, 0x1312, "In-plane Phase Encoding Direction", "InPlanePhaseEncodingDirection", "CS", "1" }, { 0x0018, 0x1314, "Flip Angle", "FlipAngle", "DS", "1" }, { 0x0018, 0x1315, "Variable Flip Angle Flag", "VariableFlipAngleFlag", "CS", "1" }, { 0x0018, 0x1316, "SAR", "SAR", "DS", "1" }, { 0x0018, 0x1318, "dB/dt", "dBdt", "DS", "1" }, { 0x0018, 0x1400, "Acquisition Device Processing Description", "AcquisitionDeviceProcessingDescription", "LO", "1" }, { 0x0018, 0x1401, "Acquisition Device Processing Code", "AcquisitionDeviceProcessingCode", "LO", "1" }, { 0x0018, 0x1402, "Cassette Orientation", "CassetteOrientation", "CS", "1" }, { 0x0018, 0x1403, "Cassette Size", "CassetteSize", "CS", "1" }, { 0x0018, 0x1404, "Exposures on Plate", "ExposuresOnPlate", "US", "1" }, { 0x0018, 0x1405, "Relative X-Ray Exposure", "RelativeXRayExposure", "IS", "1" }, { 0x0018, 0x1411, "Exposure Index", "ExposureIndex", "DS", "1" }, { 0x0018, 0x1412, "Target Exposure Index", "TargetExposureIndex", "DS", "1" }, { 0x0018, 0x1413, "Deviation Index", "DeviationIndex", "DS", "1" }, { 0x0018, 0x1450, "Column Angulation", "ColumnAngulation", "DS", "1" }, { 0x0018, 0x1460, "Tomo Layer Height", "TomoLayerHeight", "DS", "1" }, { 0x0018, 0x1470, "Tomo Angle", "TomoAngle", "DS", "1" }, { 0x0018, 0x1480, "Tomo Time", "TomoTime", "DS", "1" }, { 0x0018, 0x1490, "Tomo Type", "TomoType", "CS", "1" }, { 0x0018, 0x1491, "Tomo Class", "TomoClass", "CS", "1" }, { 0x0018, 0x1495, "Number of Tomosynthesis Source Images", "NumberOfTomosynthesisSourceImages", "IS", "1" }, { 0x0018, 0x1500, "Positioner Motion", "PositionerMotion", "CS", "1" }, { 0x0018, 0x1508, "Positioner Type", "PositionerType", "CS", "1" }, { 0x0018, 0x1510, "Positioner Primary Angle", "PositionerPrimaryAngle", "DS", "1" }, { 0x0018, 0x1511, "Positioner Secondary Angle", "PositionerSecondaryAngle", "DS", "1" }, { 0x0018, 0x1520, "Positioner Primary Angle Increment", "PositionerPrimaryAngleIncrement", "DS", "1-n" }, { 0x0018, 0x1521, "Positioner Secondary Angle Increment", "PositionerSecondaryAngleIncrement", "DS", "1-n" }, { 0x0018, 0x1530, "Detector Primary Angle", "DetectorPrimaryAngle", "DS", "1" }, { 0x0018, 0x1531, "Detector Secondary Angle", "DetectorSecondaryAngle", "DS", "1" }, { 0x0018, 0x1600, "Shutter Shape", "ShutterShape", "CS", "1-3" }, { 0x0018, 0x1602, "Shutter Left Vertical Edge", "ShutterLeftVerticalEdge", "IS", "1" }, { 0x0018, 0x1604, "Shutter Right Vertical Edge", "ShutterRightVerticalEdge", "IS", "1" }, { 0x0018, 0x1606, "Shutter Upper Horizontal Edge", "ShutterUpperHorizontalEdge", "IS", "1" }, { 0x0018, 0x1608, "Shutter Lower Horizontal Edge", "ShutterLowerHorizontalEdge", "IS", "1" }, { 0x0018, 0x1610, "Center of Circular Shutter", "CenterOfCircularShutter", "IS", "2" }, { 0x0018, 0x1612, "Radius of Circular Shutter", "RadiusOfCircularShutter", "IS", "1" }, { 0x0018, 0x1620, "Vertices of the Polygonal Shutter", "VerticesOfThePolygonalShutter", "IS", "2-2n" }, { 0x0018, 0x1622, "Shutter Presentation Value", "ShutterPresentationValue", "US", "1" }, { 0x0018, 0x1623, "Shutter Overlay Group", "ShutterOverlayGroup", "US", "1" }, { 0x0018, 0x1624, "Shutter Presentation Color CIELab Value", "ShutterPresentationColorCIELabValue", "US", "3" }, { 0x0018, 0x1700, "Collimator Shape", "CollimatorShape", "CS", "1-3" }, { 0x0018, 0x1702, "Collimator Left Vertical Edge", "CollimatorLeftVerticalEdge", "IS", "1" }, { 0x0018, 0x1704, "Collimator Right Vertical Edge", "CollimatorRightVerticalEdge", "IS", "1" }, { 0x0018, 0x1706, "Collimator Upper Horizontal Edge", "CollimatorUpperHorizontalEdge", "IS", "1" }, { 0x0018, 0x1708, "Collimator Lower Horizontal Edge", "CollimatorLowerHorizontalEdge", "IS", "1" }, { 0x0018, 0x1710, "Center of Circular Collimator", "CenterOfCircularCollimator", "IS", "2" }, { 0x0018, 0x1712, "Radius of Circular Collimator", "RadiusOfCircularCollimator", "IS", "1" }, { 0x0018, 0x1720, "Vertices of the Polygonal Collimator", "VerticesOfThePolygonalCollimator", "IS", "2-2n" }, { 0x0018, 0x1800, "Acquisition Time Synchronized", "AcquisitionTimeSynchronized", "CS", "1" }, { 0x0018, 0x1801, "Time Source", "TimeSource", "SH", "1" }, { 0x0018, 0x1802, "Time Distribution Protocol", "TimeDistributionProtocol", "CS", "1" }, { 0x0018, 0x1803, "NTP Source Address", "NTPSourceAddress", "LO", "1" }, { 0x0018, 0x2001, "Page Number Vector", "PageNumberVector", "IS", "1-n" }, { 0x0018, 0x2002, "Frame Label Vector", "FrameLabelVector", "SH", "1-n" }, { 0x0018, 0x2003, "Frame Primary Angle Vector", "FramePrimaryAngleVector", "DS", "1-n" }, { 0x0018, 0x2004, "Frame Secondary Angle Vector", "FrameSecondaryAngleVector", "DS", "1-n" }, { 0x0018, 0x2005, "Slice Location Vector", "SliceLocationVector", "DS", "1-n" }, { 0x0018, 0x2006, "Display Window Label Vector", "DisplayWindowLabelVector", "SH", "1-n" }, { 0x0018, 0x2010, "Nominal Scanned Pixel Spacing", "NominalScannedPixelSpacing", "DS", "2" }, { 0x0018, 0x2020, "Digitizing Device Transport Direction", "DigitizingDeviceTransportDirection", "CS", "1" }, { 0x0018, 0x2030, "Rotation of Scanned Film", "RotationOfScannedFilm", "DS", "1" }, { 0x0018, 0x2041, "Biopsy Target Sequence", "BiopsyTargetSequence", "SQ", "1" }, { 0x0018, 0x2042, "Target UID", "TargetUID", "UI", "1" }, { 0x0018, 0x2043, "Localizing Cursor Position", "LocalizingCursorPosition", "FL", "2" }, { 0x0018, 0x2044, "Calculated Target Position", "CalculatedTargetPosition", "FL", "3" }, { 0x0018, 0x2045, "Target Label", "TargetLabel", "SH", "1" }, { 0x0018, 0x2046, "Displayed Z Value", "DisplayedZValue", "FL", "1" }, { 0x0018, 0x3100, "IVUS Acquisition", "IVUSAcquisition", "CS", "1" }, { 0x0018, 0x3101, "IVUS Pullback Rate", "IVUSPullbackRate", "DS", "1" }, { 0x0018, 0x3102, "IVUS Gated Rate", "IVUSGatedRate", "DS", "1" }, { 0x0018, 0x3103, "IVUS Pullback Start Frame Number", "IVUSPullbackStartFrameNumber", "IS", "1" }, { 0x0018, 0x3104, "IVUS Pullback Stop Frame Number", "IVUSPullbackStopFrameNumber", "IS", "1" }, { 0x0018, 0x3105, "Lesion Number", "LesionNumber", "IS", "1-n" }, { 0x0018, 0x4000, "Acquisition Comments", "AcquisitionComments", "LT", "1" }, { 0x0018, 0x5000, "Output Power", "OutputPower", "SH", "1-n" }, { 0x0018, 0x5010, "Transducer Data", "TransducerData", "LO", "1-n" }, { 0x0018, 0x5012, "Focus Depth", "FocusDepth", "DS", "1" }, { 0x0018, 0x5020, "Processing Function", "ProcessingFunction", "LO", "1" }, { 0x0018, 0x5021, "Postprocessing Function", "PostprocessingFunction", "LO", "1" }, { 0x0018, 0x5022, "Mechanical Index", "MechanicalIndex", "DS", "1" }, { 0x0018, 0x5024, "Bone Thermal Index", "BoneThermalIndex", "DS", "1" }, { 0x0018, 0x5026, "Cranial Thermal Index", "CranialThermalIndex", "DS", "1" }, { 0x0018, 0x5027, "Soft Tissue Thermal Index", "SoftTissueThermalIndex", "DS", "1" }, { 0x0018, 0x5028, "Soft Tissue-focus Thermal Index", "SoftTissueFocusThermalIndex", "DS", "1" }, { 0x0018, 0x5029, "Soft Tissue-surface Thermal Index", "SoftTissueSurfaceThermalIndex", "DS", "1" }, { 0x0018, 0x5030, "Dynamic Range", "DynamicRange", "DS", "1" }, { 0x0018, 0x5040, "Total Gain", "TotalGain", "DS", "1" }, { 0x0018, 0x5050, "Depth of Scan Field", "DepthOfScanField", "IS", "1" }, { 0x0018, 0x5100, "Patient Position", "PatientPosition", "CS", "1" }, { 0x0018, 0x5101, "View Position", "ViewPosition", "CS", "1" }, { 0x0018, 0x5104, "Projection Eponymous Name Code Sequence", "ProjectionEponymousNameCodeSequence", "SQ", "1" }, { 0x0018, 0x5210, "Image Transformation Matrix", "ImageTransformationMatrix", "DS", "6" }, { 0x0018, 0x5212, "Image Translation Vector", "ImageTranslationVector", "DS", "3" }, { 0x0018, 0x6000, "Sensitivity", "Sensitivity", "DS", "1" }, { 0x0018, 0x6011, "Sequence of Ultrasound Regions", "SequenceOfUltrasoundRegions", "SQ", "1" }, { 0x0018, 0x6012, "Region Spatial Format", "RegionSpatialFormat", "US", "1" }, { 0x0018, 0x6014, "Region Data Type", "RegionDataType", "US", "1" }, { 0x0018, 0x6016, "Region Flags", "RegionFlags", "UL", "1" }, { 0x0018, 0x6018, "Region Location Min X0", "RegionLocationMinX0", "UL", "1" }, { 0x0018, 0x601a, "Region Location Min Y0", "RegionLocationMinY0", "UL", "1" }, { 0x0018, 0x601c, "Region Location Max X1", "RegionLocationMaxX1", "UL", "1" }, { 0x0018, 0x601e, "Region Location Max Y1", "RegionLocationMaxY1", "UL", "1" }, { 0x0018, 0x6020, "Reference Pixel X0", "ReferencePixelX0", "SL", "1" }, { 0x0018, 0x6022, "Reference Pixel Y0", "ReferencePixelY0", "SL", "1" }, { 0x0018, 0x6024, "Physical Units X Direction", "PhysicalUnitsXDirection", "US", "1" }, { 0x0018, 0x6026, "Physical Units Y Direction", "PhysicalUnitsYDirection", "US", "1" }, { 0x0018, 0x6028, "Reference Pixel Physical Value X", "ReferencePixelPhysicalValueX", "FD", "1" }, { 0x0018, 0x602a, "Reference Pixel Physical Value Y", "ReferencePixelPhysicalValueY", "FD", "1" }, { 0x0018, 0x602c, "Physical Delta X", "PhysicalDeltaX", "FD", "1" }, { 0x0018, 0x602e, "Physical Delta Y", "PhysicalDeltaY", "FD", "1" }, { 0x0018, 0x6030, "Transducer Frequency", "TransducerFrequency", "UL", "1" }, { 0x0018, 0x6031, "Transducer Type", "TransducerType", "CS", "1" }, { 0x0018, 0x6032, "Pulse Repetition Frequency", "PulseRepetitionFrequency", "UL", "1" }, { 0x0018, 0x6034, "Doppler Correction Angle", "DopplerCorrectionAngle", "FD", "1" }, { 0x0018, 0x6036, "Steering Angle", "SteeringAngle", "FD", "1" }, { 0x0018, 0x6038, "Doppler Sample Volume X Position (Retired)", "DopplerSampleVolumeXPositionRetired", "UL", "1" }, { 0x0018, 0x6039, "Doppler Sample Volume X Position", "DopplerSampleVolumeXPosition", "SL", "1" }, { 0x0018, 0x603a, "Doppler Sample Volume Y Position (Retired)", "DopplerSampleVolumeYPositionRetired", "UL", "1" }, { 0x0018, 0x603b, "Doppler Sample Volume Y Position", "DopplerSampleVolumeYPosition", "SL", "1" }, { 0x0018, 0x603c, "TM-Line Position X0 (Retired)", "TMLinePositionX0Retired", "UL", "1" }, { 0x0018, 0x603d, "TM-Line Position X0", "TMLinePositionX0", "SL", "1" }, { 0x0018, 0x603e, "TM-Line Position Y0 (Retired)", "TMLinePositionY0Retired", "UL", "1" }, { 0x0018, 0x603f, "TM-Line Position Y0", "TMLinePositionY0", "SL", "1" }, { 0x0018, 0x6040, "TM-Line Position X1 (Retired)", "TMLinePositionX1Retired", "UL", "1" }, { 0x0018, 0x6041, "TM-Line Position X1", "TMLinePositionX1", "SL", "1" }, { 0x0018, 0x6042, "TM-Line Position Y1 (Retired)", "TMLinePositionY1Retired", "UL", "1" }, { 0x0018, 0x6043, "TM-Line Position Y1", "TMLinePositionY1", "SL", "1" }, { 0x0018, 0x6044, "Pixel Component Organization", "PixelComponentOrganization", "US", "1" }, { 0x0018, 0x6046, "Pixel Component Mask", "PixelComponentMask", "UL", "1" }, { 0x0018, 0x6048, "Pixel Component Range Start", "PixelComponentRangeStart", "UL", "1" }, { 0x0018, 0x604a, "Pixel Component Range Stop", "PixelComponentRangeStop", "UL", "1" }, { 0x0018, 0x604c, "Pixel Component Physical Units", "PixelComponentPhysicalUnits", "US", "1" }, { 0x0018, 0x604e, "Pixel Component Data Type", "PixelComponentDataType", "US", "1" }, { 0x0018, 0x6050, "Number of Table Break Points", "NumberOfTableBreakPoints", "UL", "1" }, { 0x0018, 0x6052, "Table of X Break Points", "TableOfXBreakPoints", "UL", "1-n" }, { 0x0018, 0x6054, "Table of Y Break Points", "TableOfYBreakPoints", "FD", "1-n" }, { 0x0018, 0x6056, "Number of Table Entries", "NumberOfTableEntries", "UL", "1" }, { 0x0018, 0x6058, "Table of Pixel Values", "TableOfPixelValues", "UL", "1-n" }, { 0x0018, 0x605a, "Table of Parameter Values", "TableOfParameterValues", "FL", "1-n" }, { 0x0018, 0x6060, "R Wave Time Vector", "RWaveTimeVector", "FL", "1-n" }, { 0x0018, 0x7000, "Detector Conditions Nominal Flag", "DetectorConditionsNominalFlag", "CS", "1" }, { 0x0018, 0x7001, "Detector Temperature", "DetectorTemperature", "DS", "1" }, { 0x0018, 0x7004, "Detector Type", "DetectorType", "CS", "1" }, { 0x0018, 0x7005, "Detector Configuration", "DetectorConfiguration", "CS", "1" }, { 0x0018, 0x7006, "Detector Description", "DetectorDescription", "LT", "1" }, { 0x0018, 0x7008, "Detector Mode", "DetectorMode", "LT", "1" }, { 0x0018, 0x700a, "Detector ID", "DetectorID", "SH", "1" }, { 0x0018, 0x700c, "Date of Last Detector Calibration", "DateOfLastDetectorCalibration", "DA", "1" }, { 0x0018, 0x700e, "Time of Last Detector Calibration", "TimeOfLastDetectorCalibration", "TM", "1" }, { 0x0018, 0x7010, "Exposures on Detector Since Last Calibration", "ExposuresOnDetectorSinceLastCalibration", "IS", "1" }, { 0x0018, 0x7011, "Exposures on Detector Since Manufactured", "ExposuresOnDetectorSinceManufactured", "IS", "1" }, { 0x0018, 0x7012, "Detector Time Since Last Exposure", "DetectorTimeSinceLastExposure", "DS", "1" }, { 0x0018, 0x7014, "Detector Active Time", "DetectorActiveTime", "DS", "1" }, { 0x0018, 0x7016, "Detector Activation Offset From Exposure", "DetectorActivationOffsetFromExposure", "DS", "1" }, { 0x0018, 0x701a, "Detector Binning", "DetectorBinning", "DS", "2" }, { 0x0018, 0x7020, "Detector Element Physical Size", "DetectorElementPhysicalSize", "DS", "2" }, { 0x0018, 0x7022, "Detector Element Spacing", "DetectorElementSpacing", "DS", "2" }, { 0x0018, 0x7024, "Detector Active Shape", "DetectorActiveShape", "CS", "1" }, { 0x0018, 0x7026, "Detector Active Dimension(s)", "DetectorActiveDimensions", "DS", "1-2" }, { 0x0018, 0x7028, "Detector Active Origin", "DetectorActiveOrigin", "DS", "2" }, { 0x0018, 0x702a, "Detector Manufacturer Name", "DetectorManufacturerName", "LO", "1" }, { 0x0018, 0x702b, "Detector Manufacturer's Model Name", "DetectorManufacturerModelName", "LO", "1" }, { 0x0018, 0x7030, "Field of View Origin", "FieldOfViewOrigin", "DS", "2" }, { 0x0018, 0x7032, "Field of View Rotation", "FieldOfViewRotation", "DS", "1" }, { 0x0018, 0x7034, "Field of View Horizontal Flip", "FieldOfViewHorizontalFlip", "CS", "1" }, { 0x0018, 0x7036, "Pixel Data Area Origin Relative To FOV", "PixelDataAreaOriginRelativeToFOV", "FL", "2" }, { 0x0018, 0x7038, "Pixel Data Area Rotation Angle Relative To FOV", "PixelDataAreaRotationAngleRelativeToFOV", "FL", "1" }, { 0x0018, 0x7040, "Grid Absorbing Material", "GridAbsorbingMaterial", "LT", "1" }, { 0x0018, 0x7041, "Grid Spacing Material", "GridSpacingMaterial", "LT", "1" }, { 0x0018, 0x7042, "Grid Thickness", "GridThickness", "DS", "1" }, { 0x0018, 0x7044, "Grid Pitch", "GridPitch", "DS", "1" }, { 0x0018, 0x7046, "Grid Aspect Ratio", "GridAspectRatio", "IS", "2" }, { 0x0018, 0x7048, "Grid Period", "GridPeriod", "DS", "1" }, { 0x0018, 0x704c, "Grid Focal Distance", "GridFocalDistance", "DS", "1" }, { 0x0018, 0x7050, "Filter Material", "FilterMaterial", "CS", "1-n" }, { 0x0018, 0x7052, "Filter Thickness Minimum", "FilterThicknessMinimum", "DS", "1-n" }, { 0x0018, 0x7054, "Filter Thickness Maximum", "FilterThicknessMaximum", "DS", "1-n" }, { 0x0018, 0x7056, "Filter Beam Path Length Minimum", "FilterBeamPathLengthMinimum", "FL", "1-n" }, { 0x0018, 0x7058, "Filter Beam Path Length Maximum", "FilterBeamPathLengthMaximum", "FL", "1-n" }, { 0x0018, 0x7060, "Exposure Control Mode", "ExposureControlMode", "CS", "1" }, { 0x0018, 0x7062, "Exposure Control Mode Description", "ExposureControlModeDescription", "LT", "1" }, { 0x0018, 0x7064, "Exposure Status", "ExposureStatus", "CS", "1" }, { 0x0018, 0x7065, "Phototimer Setting", "PhototimerSetting", "DS", "1" }, { 0x0018, 0x8150, "Exposure Time in uS", "ExposureTimeInuS", "DS", "1" }, { 0x0018, 0x8151, "X-Ray Tube Current in uA", "XRayTubeCurrentInuA", "DS", "1" }, { 0x0018, 0x9004, "Content Qualification", "ContentQualification", "CS", "1" }, { 0x0018, 0x9005, "Pulse Sequence Name", "PulseSequenceName", "SH", "1" }, { 0x0018, 0x9006, "MR Imaging Modifier Sequence", "MRImagingModifierSequence", "SQ", "1" }, { 0x0018, 0x9008, "Echo Pulse Sequence", "EchoPulseSequence", "CS", "1" }, { 0x0018, 0x9009, "Inversion Recovery", "InversionRecovery", "CS", "1" }, { 0x0018, 0x9010, "Flow Compensation", "FlowCompensation", "CS", "1" }, { 0x0018, 0x9011, "Multiple Spin Echo", "MultipleSpinEcho", "CS", "1" }, { 0x0018, 0x9012, "Multi-planar Excitation", "MultiPlanarExcitation", "CS", "1" }, { 0x0018, 0x9014, "Phase Contrast", "PhaseContrast", "CS", "1" }, { 0x0018, 0x9015, "Time of Flight Contrast", "TimeOfFlightContrast", "CS", "1" }, { 0x0018, 0x9016, "Spoiling", "Spoiling", "CS", "1" }, { 0x0018, 0x9017, "Steady State Pulse Sequence", "SteadyStatePulseSequence", "CS", "1" }, { 0x0018, 0x9018, "Echo Planar Pulse Sequence", "EchoPlanarPulseSequence", "CS", "1" }, { 0x0018, 0x9019, "Tag Angle First Axis", "TagAngleFirstAxis", "FD", "1" }, { 0x0018, 0x9020, "Magnetization Transfer", "MagnetizationTransfer", "CS", "1" }, { 0x0018, 0x9021, "T2 Preparation", "T2Preparation", "CS", "1" }, { 0x0018, 0x9022, "Blood Signal Nulling", "BloodSignalNulling", "CS", "1" }, { 0x0018, 0x9024, "Saturation Recovery", "SaturationRecovery", "CS", "1" }, { 0x0018, 0x9025, "Spectrally Selected Suppression", "SpectrallySelectedSuppression", "CS", "1" }, { 0x0018, 0x9026, "Spectrally Selected Excitation", "SpectrallySelectedExcitation", "CS", "1" }, { 0x0018, 0x9027, "Spatial Pre-saturation", "SpatialPresaturation", "CS", "1" }, { 0x0018, 0x9028, "Tagging", "Tagging", "CS", "1" }, { 0x0018, 0x9029, "Oversampling Phase", "OversamplingPhase", "CS", "1" }, { 0x0018, 0x9030, "Tag Spacing First Dimension", "TagSpacingFirstDimension", "FD", "1" }, { 0x0018, 0x9032, "Geometry of k-Space Traversal", "GeometryOfKSpaceTraversal", "CS", "1" }, { 0x0018, 0x9033, "Segmented k-Space Traversal", "SegmentedKSpaceTraversal", "CS", "1" }, { 0x0018, 0x9034, "Rectilinear Phase Encode Reordering", "RectilinearPhaseEncodeReordering", "CS", "1" }, { 0x0018, 0x9035, "Tag Thickness", "TagThickness", "FD", "1" }, { 0x0018, 0x9036, "Partial Fourier Direction", "PartialFourierDirection", "CS", "1" }, { 0x0018, 0x9037, "Cardiac Synchronization Technique", "CardiacSynchronizationTechnique", "CS", "1" }, { 0x0018, 0x9041, "Receive Coil Manufacturer Name", "ReceiveCoilManufacturerName", "LO", "1" }, { 0x0018, 0x9042, "MR Receive Coil Sequence", "MRReceiveCoilSequence", "SQ", "1" }, { 0x0018, 0x9043, "Receive Coil Type", "ReceiveCoilType", "CS", "1" }, { 0x0018, 0x9044, "Quadrature Receive Coil", "QuadratureReceiveCoil", "CS", "1" }, { 0x0018, 0x9045, "Multi-Coil Definition Sequence", "MultiCoilDefinitionSequence", "SQ", "1" }, { 0x0018, 0x9046, "Multi-Coil Configuration", "MultiCoilConfiguration", "LO", "1" }, { 0x0018, 0x9047, "Multi-Coil Element Name", "MultiCoilElementName", "SH", "1" }, { 0x0018, 0x9048, "Multi-Coil Element Used", "MultiCoilElementUsed", "CS", "1" }, { 0x0018, 0x9049, "MR Transmit Coil Sequence", "MRTransmitCoilSequence", "SQ", "1" }, { 0x0018, 0x9050, "Transmit Coil Manufacturer Name", "TransmitCoilManufacturerName", "LO", "1" }, { 0x0018, 0x9051, "Transmit Coil Type", "TransmitCoilType", "CS", "1" }, { 0x0018, 0x9052, "Spectral Width", "SpectralWidth", "FD", "1-2" }, { 0x0018, 0x9053, "Chemical Shift Reference", "ChemicalShiftReference", "FD", "1-2" }, { 0x0018, 0x9054, "Volume Localization Technique", "VolumeLocalizationTechnique", "CS", "1" }, { 0x0018, 0x9058, "MR Acquisition Frequency Encoding Steps", "MRAcquisitionFrequencyEncodingSteps", "US", "1" }, { 0x0018, 0x9059, "De-coupling", "Decoupling", "CS", "1" }, { 0x0018, 0x9060, "De-coupled Nucleus", "DecoupledNucleus", "CS", "1-2" }, { 0x0018, 0x9061, "De-coupling Frequency", "DecouplingFrequency", "FD", "1-2" }, { 0x0018, 0x9062, "De-coupling Method", "DecouplingMethod", "CS", "1" }, { 0x0018, 0x9063, "De-coupling Chemical Shift Reference", "DecouplingChemicalShiftReference", "FD", "1-2" }, { 0x0018, 0x9064, "k-space Filtering", "KSpaceFiltering", "CS", "1" }, { 0x0018, 0x9065, "Time Domain Filtering", "TimeDomainFiltering", "CS", "1-2" }, { 0x0018, 0x9066, "Number of Zero Fills", "NumberOfZeroFills", "US", "1-2" }, { 0x0018, 0x9067, "Baseline Correction", "BaselineCorrection", "CS", "1" }, { 0x0018, 0x9069, "Parallel Reduction Factor In-plane", "ParallelReductionFactorInPlane", "FD", "1" }, { 0x0018, 0x9070, "Cardiac R-R Interval Specified", "CardiacRRIntervalSpecified", "FD", "1" }, { 0x0018, 0x9073, "Acquisition Duration", "AcquisitionDuration", "FD", "1" }, { 0x0018, 0x9074, "Frame Acquisition DateTime", "FrameAcquisitionDateTime", "DT", "1" }, { 0x0018, 0x9075, "Diffusion Directionality", "DiffusionDirectionality", "CS", "1" }, { 0x0018, 0x9076, "Diffusion Gradient Direction Sequence", "DiffusionGradientDirectionSequence", "SQ", "1" }, { 0x0018, 0x9077, "Parallel Acquisition", "ParallelAcquisition", "CS", "1" }, { 0x0018, 0x9078, "Parallel Acquisition Technique", "ParallelAcquisitionTechnique", "CS", "1" }, { 0x0018, 0x9079, "Inversion Times", "InversionTimes", "FD", "1-n" }, { 0x0018, 0x9080, "Metabolite Map Description", "MetaboliteMapDescription", "ST", "1" }, { 0x0018, 0x9081, "Partial Fourier", "PartialFourier", "CS", "1" }, { 0x0018, 0x9082, "Effective Echo Time", "EffectiveEchoTime", "FD", "1" }, { 0x0018, 0x9083, "Metabolite Map Code Sequence", "MetaboliteMapCodeSequence", "SQ", "1" }, { 0x0018, 0x9084, "Chemical Shift Sequence", "ChemicalShiftSequence", "SQ", "1" }, { 0x0018, 0x9085, "Cardiac Signal Source", "CardiacSignalSource", "CS", "1" }, { 0x0018, 0x9087, "Diffusion b-value", "DiffusionBValue", "FD", "1" }, { 0x0018, 0x9089, "Diffusion Gradient Orientation", "DiffusionGradientOrientation", "FD", "3" }, { 0x0018, 0x9090, "Velocity Encoding Direction", "VelocityEncodingDirection", "FD", "3" }, { 0x0018, 0x9091, "Velocity Encoding Minimum Value", "VelocityEncodingMinimumValue", "FD", "1" }, { 0x0018, 0x9092, "Velocity Encoding Acquisition Sequence", "VelocityEncodingAcquisitionSequence", "SQ", "1" }, { 0x0018, 0x9093, "Number of k-Space Trajectories", "NumberOfKSpaceTrajectories", "US", "1" }, { 0x0018, 0x9094, "Coverage of k-Space", "CoverageOfKSpace", "CS", "1" }, { 0x0018, 0x9095, "Spectroscopy Acquisition Phase Rows", "SpectroscopyAcquisitionPhaseRows", "UL", "1" }, { 0x0018, 0x9096, "Parallel Reduction Factor In-plane (Retired)", "ParallelReductionFactorInPlaneRetired", "FD", "1" }, { 0x0018, 0x9098, "Transmitter Frequency", "TransmitterFrequency", "FD", "1-2" }, { 0x0018, 0x9100, "Resonant Nucleus", "ResonantNucleus", "CS", "1-2" }, { 0x0018, 0x9101, "Frequency Correction", "FrequencyCorrection", "CS", "1" }, { 0x0018, 0x9103, "MR Spectroscopy FOV/Geometry Sequence", "MRSpectroscopyFOVGeometrySequence", "SQ", "1" }, { 0x0018, 0x9104, "Slab Thickness", "SlabThickness", "FD", "1" }, { 0x0018, 0x9105, "Slab Orientation", "SlabOrientation", "FD", "3" }, { 0x0018, 0x9106, "Mid Slab Position", "MidSlabPosition", "FD", "3" }, { 0x0018, 0x9107, "MR Spatial Saturation Sequence", "MRSpatialSaturationSequence", "SQ", "1" }, { 0x0018, 0x9112, "MR Timing and Related Parameters Sequence", "MRTimingAndRelatedParametersSequence", "SQ", "1" }, { 0x0018, 0x9114, "MR Echo Sequence", "MREchoSequence", "SQ", "1" }, { 0x0018, 0x9115, "MR Modifier Sequence", "MRModifierSequence", "SQ", "1" }, { 0x0018, 0x9117, "MR Diffusion Sequence", "MRDiffusionSequence", "SQ", "1" }, { 0x0018, 0x9118, "Cardiac Synchronization Sequence", "CardiacSynchronizationSequence", "SQ", "1" }, { 0x0018, 0x9119, "MR Averages Sequence", "MRAveragesSequence", "SQ", "1" }, { 0x0018, 0x9125, "MR FOV/Geometry Sequence", "MRFOVGeometrySequence", "SQ", "1" }, { 0x0018, 0x9126, "Volume Localization Sequence", "VolumeLocalizationSequence", "SQ", "1" }, { 0x0018, 0x9127, "Spectroscopy Acquisition Data Columns", "SpectroscopyAcquisitionDataColumns", "UL", "1" }, { 0x0018, 0x9147, "Diffusion Anisotropy Type", "DiffusionAnisotropyType", "CS", "1" }, { 0x0018, 0x9151, "Frame Reference DateTime", "FrameReferenceDateTime", "DT", "1" }, { 0x0018, 0x9152, "MR Metabolite Map Sequence", "MRMetaboliteMapSequence", "SQ", "1" }, { 0x0018, 0x9155, "Parallel Reduction Factor out-of-plane", "ParallelReductionFactorOutOfPlane", "FD", "1" }, { 0x0018, 0x9159, "Spectroscopy Acquisition Out-of-plane Phase Steps", "SpectroscopyAcquisitionOutOfPlanePhaseSteps", "UL", "1" }, { 0x0018, 0x9166, "Bulk Motion Status", "BulkMotionStatus", "CS", "1" }, { 0x0018, 0x9168, "Parallel Reduction Factor Second In-plane", "ParallelReductionFactorSecondInPlane", "FD", "1" }, { 0x0018, 0x9169, "Cardiac Beat Rejection Technique", "CardiacBeatRejectionTechnique", "CS", "1" }, { 0x0018, 0x9170, "Respiratory Motion Compensation Technique", "RespiratoryMotionCompensationTechnique", "CS", "1" }, { 0x0018, 0x9171, "Respiratory Signal Source", "RespiratorySignalSource", "CS", "1" }, { 0x0018, 0x9172, "Bulk Motion Compensation Technique", "BulkMotionCompensationTechnique", "CS", "1" }, { 0x0018, 0x9173, "Bulk Motion Signal Source", "BulkMotionSignalSource", "CS", "1" }, { 0x0018, 0x9174, "Applicable Safety Standard Agency", "ApplicableSafetyStandardAgency", "CS", "1" }, { 0x0018, 0x9175, "Applicable Safety Standard Description", "ApplicableSafetyStandardDescription", "LO", "1" }, { 0x0018, 0x9176, "Operating Mode Sequence", "OperatingModeSequence", "SQ", "1" }, { 0x0018, 0x9177, "Operating Mode Type", "OperatingModeType", "CS", "1" }, { 0x0018, 0x9178, "Operating Mode", "OperatingMode", "CS", "1" }, { 0x0018, 0x9179, "Specific Absorption Rate Definition", "SpecificAbsorptionRateDefinition", "CS", "1" }, { 0x0018, 0x9180, "Gradient Output Type", "GradientOutputType", "CS", "1" }, { 0x0018, 0x9181, "Specific Absorption Rate Value", "SpecificAbsorptionRateValue", "FD", "1" }, { 0x0018, 0x9182, "Gradient Output", "GradientOutput", "FD", "1" }, { 0x0018, 0x9183, "Flow Compensation Direction", "FlowCompensationDirection", "CS", "1" }, { 0x0018, 0x9184, "Tagging Delay", "TaggingDelay", "FD", "1" }, { 0x0018, 0x9185, "Respiratory Motion Compensation Technique Description", "RespiratoryMotionCompensationTechniqueDescription", "ST", "1" }, { 0x0018, 0x9186, "Respiratory Signal Source ID", "RespiratorySignalSourceID", "SH", "1" }, { 0x0018, 0x9195, "Chemical Shift Minimum Integration Limit in Hz", "ChemicalShiftMinimumIntegrationLimitInHz", "FD", "1" }, { 0x0018, 0x9196, "Chemical Shift Maximum Integration Limit in Hz", "ChemicalShiftMaximumIntegrationLimitInHz", "FD", "1" }, { 0x0018, 0x9197, "MR Velocity Encoding Sequence", "MRVelocityEncodingSequence", "SQ", "1" }, { 0x0018, 0x9198, "First Order Phase Correction", "FirstOrderPhaseCorrection", "CS", "1" }, { 0x0018, 0x9199, "Water Referenced Phase Correction", "WaterReferencedPhaseCorrection", "CS", "1" }, { 0x0018, 0x9200, "MR Spectroscopy Acquisition Type", "MRSpectroscopyAcquisitionType", "CS", "1" }, { 0x0018, 0x9214, "Respiratory Cycle Position", "RespiratoryCyclePosition", "CS", "1" }, { 0x0018, 0x9217, "Velocity Encoding Maximum Value", "VelocityEncodingMaximumValue", "FD", "1" }, { 0x0018, 0x9218, "Tag Spacing Second Dimension", "TagSpacingSecondDimension", "FD", "1" }, { 0x0018, 0x9219, "Tag Angle Second Axis", "TagAngleSecondAxis", "SS", "1" }, { 0x0018, 0x9220, "Frame Acquisition Duration", "FrameAcquisitionDuration", "FD", "1" }, { 0x0018, 0x9226, "MR Image Frame Type Sequence", "MRImageFrameTypeSequence", "SQ", "1" }, { 0x0018, 0x9227, "MR Spectroscopy Frame Type Sequence", "MRSpectroscopyFrameTypeSequence", "SQ", "1" }, { 0x0018, 0x9231, "MR Acquisition Phase Encoding Steps in-plane", "MRAcquisitionPhaseEncodingStepsInPlane", "US", "1" }, { 0x0018, 0x9232, "MR Acquisition Phase Encoding Steps out-of-plane", "MRAcquisitionPhaseEncodingStepsOutOfPlane", "US", "1" }, { 0x0018, 0x9234, "Spectroscopy Acquisition Phase Columns", "SpectroscopyAcquisitionPhaseColumns", "UL", "1" }, { 0x0018, 0x9236, "Cardiac Cycle Position", "CardiacCyclePosition", "CS", "1" }, { 0x0018, 0x9239, "Specific Absorption Rate Sequence", "SpecificAbsorptionRateSequence", "SQ", "1" }, { 0x0018, 0x9240, "RF Echo Train Length", "RFEchoTrainLength", "US", "1" }, { 0x0018, 0x9241, "Gradient Echo Train Length", "GradientEchoTrainLength", "US", "1" }, { 0x0018, 0x9250, "Arterial Spin Labeling Contrast", "ArterialSpinLabelingContrast", "CS", "1" }, { 0x0018, 0x9251, "MR Arterial Spin Labeling Sequence", "MRArterialSpinLabelingSequence", "SQ", "1" }, { 0x0018, 0x9252, "ASL Technique Description", "ASLTechniqueDescription", "LO", "1" }, { 0x0018, 0x9253, "ASL Slab Number", "ASLSlabNumber", "US", "1" }, { 0x0018, 0x9254, "ASL Slab Thickness", "ASLSlabThickness", "FD", "1" }, { 0x0018, 0x9255, "ASL Slab Orientation", "ASLSlabOrientation", "FD", "3" }, { 0x0018, 0x9256, "ASL Mid Slab Position", "ASLMidSlabPosition", "FD", "3" }, { 0x0018, 0x9257, "ASL Context", "ASLContext", "CS", "1" }, { 0x0018, 0x9258, "ASL Pulse Train Duration", "ASLPulseTrainDuration", "UL", "1" }, { 0x0018, 0x9259, "ASL Crusher Flag", "ASLCrusherFlag", "CS", "1" }, { 0x0018, 0x925a, "ASL Crusher Flow Limit", "ASLCrusherFlowLimit", "FD", "1" }, { 0x0018, 0x925b, "ASL Crusher Description", "ASLCrusherDescription", "LO", "1" }, { 0x0018, 0x925c, "ASL Bolus Cut-off Flag", "ASLBolusCutoffFlag", "CS", "1" }, { 0x0018, 0x925d, "ASL Bolus Cut-off Timing Sequence", "ASLBolusCutoffTimingSequence", "SQ", "1" }, { 0x0018, 0x925e, "ASL Bolus Cut-off Technique", "ASLBolusCutoffTechnique", "LO", "1" }, { 0x0018, 0x925f, "ASL Bolus Cut-off Delay Time", "ASLBolusCutoffDelayTime", "UL", "1" }, { 0x0018, 0x9260, "ASL Slab Sequence", "ASLSlabSequence", "SQ", "1" }, { 0x0018, 0x9295, "Chemical Shift Minimum Integration Limit in ppm", "ChemicalShiftMinimumIntegrationLimitInppm", "FD", "1" }, { 0x0018, 0x9296, "Chemical Shift Maximum Integration Limit in ppm", "ChemicalShiftMaximumIntegrationLimitInppm", "FD", "1" }, { 0x0018, 0x9297, "Water Reference Acquisition", "WaterReferenceAcquisition", "CS", "1" }, { 0x0018, 0x9298, "Echo Peak Position", "EchoPeakPosition", "IS", "1" }, { 0x0018, 0x9301, "CT Acquisition Type Sequence", "CTAcquisitionTypeSequence", "SQ", "1" }, { 0x0018, 0x9302, "Acquisition Type", "AcquisitionType", "CS", "1" }, { 0x0018, 0x9303, "Tube Angle", "TubeAngle", "FD", "1" }, { 0x0018, 0x9304, "CT Acquisition Details Sequence", "CTAcquisitionDetailsSequence", "SQ", "1" }, { 0x0018, 0x9305, "Revolution Time", "RevolutionTime", "FD", "1" }, { 0x0018, 0x9306, "Single Collimation Width", "SingleCollimationWidth", "FD", "1" }, { 0x0018, 0x9307, "Total Collimation Width", "TotalCollimationWidth", "FD", "1" }, { 0x0018, 0x9308, "CT Table Dynamics Sequence", "CTTableDynamicsSequence", "SQ", "1" }, { 0x0018, 0x9309, "Table Speed", "TableSpeed", "FD", "1" }, { 0x0018, 0x9310, "Table Feed per Rotation", "TableFeedPerRotation", "FD", "1" }, { 0x0018, 0x9311, "Spiral Pitch Factor", "SpiralPitchFactor", "FD", "1" }, { 0x0018, 0x9312, "CT Geometry Sequence", "CTGeometrySequence", "SQ", "1" }, { 0x0018, 0x9313, "Data Collection Center (Patient)", "DataCollectionCenterPatient", "FD", "3" }, { 0x0018, 0x9314, "CT Reconstruction Sequence", "CTReconstructionSequence", "SQ", "1" }, { 0x0018, 0x9315, "Reconstruction Algorithm", "ReconstructionAlgorithm", "CS", "1" }, { 0x0018, 0x9316, "Convolution Kernel Group", "ConvolutionKernelGroup", "CS", "1" }, { 0x0018, 0x9317, "Reconstruction Field of View", "ReconstructionFieldOfView", "FD", "2" }, { 0x0018, 0x9318, "Reconstruction Target Center (Patient)", "ReconstructionTargetCenterPatient", "FD", "3" }, { 0x0018, 0x9319, "Reconstruction Angle", "ReconstructionAngle", "FD", "1" }, { 0x0018, 0x9320, "Image Filter", "ImageFilter", "SH", "1" }, { 0x0018, 0x9321, "CT Exposure Sequence", "CTExposureSequence", "SQ", "1" }, { 0x0018, 0x9322, "Reconstruction Pixel Spacing", "ReconstructionPixelSpacing", "FD", "2" }, { 0x0018, 0x9323, "Exposure Modulation Type", "ExposureModulationType", "CS", "1" }, { 0x0018, 0x9324, "Estimated Dose Saving", "EstimatedDoseSaving", "FD", "1" }, { 0x0018, 0x9325, "CT X-Ray Details Sequence", "CTXRayDetailsSequence", "SQ", "1" }, { 0x0018, 0x9326, "CT Position Sequence", "CTPositionSequence", "SQ", "1" }, { 0x0018, 0x9327, "Table Position", "TablePosition", "FD", "1" }, { 0x0018, 0x9328, "Exposure Time in ms", "ExposureTimeInms", "FD", "1" }, { 0x0018, 0x9329, "CT Image Frame Type Sequence", "CTImageFrameTypeSequence", "SQ", "1" }, { 0x0018, 0x9330, "X-Ray Tube Current in mA", "XRayTubeCurrentInmA", "FD", "1" }, { 0x0018, 0x9332, "Exposure in mAs", "ExposureInmAs", "FD", "1" }, { 0x0018, 0x9333, "Constant Volume Flag", "ConstantVolumeFlag", "CS", "1" }, { 0x0018, 0x9334, "Fluoroscopy Flag", "FluoroscopyFlag", "CS", "1" }, { 0x0018, 0x9335, "Distance Source to Data Collection Center", "DistanceSourceToDataCollectionCenter", "FD", "1" }, { 0x0018, 0x9337, "Contrast/Bolus Agent Number", "ContrastBolusAgentNumber", "US", "1" }, { 0x0018, 0x9338, "Contrast/Bolus Ingredient Code Sequence", "ContrastBolusIngredientCodeSequence", "SQ", "1" }, { 0x0018, 0x9340, "Contrast Administration Profile Sequence", "ContrastAdministrationProfileSequence", "SQ", "1" }, { 0x0018, 0x9341, "Contrast/Bolus Usage Sequence", "ContrastBolusUsageSequence", "SQ", "1" }, { 0x0018, 0x9342, "Contrast/Bolus Agent Administered", "ContrastBolusAgentAdministered", "CS", "1" }, { 0x0018, 0x9343, "Contrast/Bolus Agent Detected", "ContrastBolusAgentDetected", "CS", "1" }, { 0x0018, 0x9344, "Contrast/Bolus Agent Phase", "ContrastBolusAgentPhase", "CS", "1" }, { 0x0018, 0x9345, "CTDIvol", "CTDIvol", "FD", "1" }, { 0x0018, 0x9346, "CTDI Phantom Type Code Sequence", "CTDIPhantomTypeCodeSequence", "SQ", "1" }, { 0x0018, 0x9351, "Calcium Scoring Mass Factor Patient", "CalciumScoringMassFactorPatient", "FL", "1" }, { 0x0018, 0x9352, "Calcium Scoring Mass Factor Device", "CalciumScoringMassFactorDevice", "FL", "3" }, { 0x0018, 0x9353, "Energy Weighting Factor", "EnergyWeightingFactor", "FL", "1" }, { 0x0018, 0x9360, "CT Additional X-Ray Source Sequence", "CTAdditionalXRaySourceSequence", "SQ", "1" }, { 0x0018, 0x9401, "Projection Pixel Calibration Sequence", "ProjectionPixelCalibrationSequence", "SQ", "1" }, { 0x0018, 0x9402, "Distance Source to Isocenter", "DistanceSourceToIsocenter", "FL", "1" }, { 0x0018, 0x9403, "Distance Object to Table Top", "DistanceObjectToTableTop", "FL", "1" }, { 0x0018, 0x9404, "Object Pixel Spacing in Center of Beam", "ObjectPixelSpacingInCenterOfBeam", "FL", "2" }, { 0x0018, 0x9405, "Positioner Position Sequence", "PositionerPositionSequence", "SQ", "1" }, { 0x0018, 0x9406, "Table Position Sequence", "TablePositionSequence", "SQ", "1" }, { 0x0018, 0x9407, "Collimator Shape Sequence", "CollimatorShapeSequence", "SQ", "1" }, { 0x0018, 0x9410, "Planes in Acquisition", "PlanesInAcquisition", "CS", "1" }, { 0x0018, 0x9412, "XA/XRF Frame Characteristics Sequence", "XAXRFFrameCharacteristicsSequence", "SQ", "1" }, { 0x0018, 0x9417, "Frame Acquisition Sequence", "FrameAcquisitionSequence", "SQ", "1" }, { 0x0018, 0x9420, "X-Ray Receptor Type", "XRayReceptorType", "CS", "1" }, { 0x0018, 0x9423, "Acquisition Protocol Name", "AcquisitionProtocolName", "LO", "1" }, { 0x0018, 0x9424, "Acquisition Protocol Description", "AcquisitionProtocolDescription", "LT", "1" }, { 0x0018, 0x9425, "Contrast/Bolus Ingredient Opaque", "ContrastBolusIngredientOpaque", "CS", "1" }, { 0x0018, 0x9426, "Distance Receptor Plane to Detector Housing", "DistanceReceptorPlaneToDetectorHousing", "FL", "1" }, { 0x0018, 0x9427, "Intensifier Active Shape", "IntensifierActiveShape", "CS", "1" }, { 0x0018, 0x9428, "Intensifier Active Dimension(s)", "IntensifierActiveDimensions", "FL", "1-2" }, { 0x0018, 0x9429, "Physical Detector Size", "PhysicalDetectorSize", "FL", "2" }, { 0x0018, 0x9430, "Position of Isocenter Projection", "PositionOfIsocenterProjection", "FL", "2" }, { 0x0018, 0x9432, "Field of View Sequence", "FieldOfViewSequence", "SQ", "1" }, { 0x0018, 0x9433, "Field of View Description", "FieldOfViewDescription", "LO", "1" }, { 0x0018, 0x9434, "Exposure Control Sensing Regions Sequence", "ExposureControlSensingRegionsSequence", "SQ", "1" }, { 0x0018, 0x9435, "Exposure Control Sensing Region Shape", "ExposureControlSensingRegionShape", "CS", "1" }, { 0x0018, 0x9436, "Exposure Control Sensing Region Left Vertical Edge", "ExposureControlSensingRegionLeftVerticalEdge", "SS", "1" }, { 0x0018, 0x9437, "Exposure Control Sensing Region Right Vertical Edge", "ExposureControlSensingRegionRightVerticalEdge", "SS", "1" }, { 0x0018, 0x9438, "Exposure Control Sensing Region Upper Horizontal Edge", "ExposureControlSensingRegionUpperHorizontalEdge", "SS", "1" }, { 0x0018, 0x9439, "Exposure Control Sensing Region Lower Horizontal Edge", "ExposureControlSensingRegionLowerHorizontalEdge", "SS", "1" }, { 0x0018, 0x9440, "Center of Circular Exposure Control Sensing Region", "CenterOfCircularExposureControlSensingRegion", "SS", "2" }, { 0x0018, 0x9441, "Radius of Circular Exposure Control Sensing Region", "RadiusOfCircularExposureControlSensingRegion", "US", "1" }, { 0x0018, 0x9442, "Vertices of the Polygonal Exposure Control Sensing Region", "VerticesOfThePolygonalExposureControlSensingRegion", "SS", "2-n" }, { 0x0018, 0x9447, "Column Angulation (Patient)", "ColumnAngulationPatient", "FL", "1" }, { 0x0018, 0x9449, "Beam Angle", "BeamAngle", "FL", "1" }, { 0x0018, 0x9451, "Frame Detector Parameters Sequence", "FrameDetectorParametersSequence", "SQ", "1" }, { 0x0018, 0x9452, "Calculated Anatomy Thickness", "CalculatedAnatomyThickness", "FL", "1" }, { 0x0018, 0x9455, "Calibration Sequence", "CalibrationSequence", "SQ", "1" }, { 0x0018, 0x9456, "Object Thickness Sequence", "ObjectThicknessSequence", "SQ", "1" }, { 0x0018, 0x9457, "Plane Identification", "PlaneIdentification", "CS", "1" }, { 0x0018, 0x9461, "Field of View Dimension(s) in Float", "FieldOfViewDimensionsInFloat", "FL", "1-2" }, { 0x0018, 0x9462, "Isocenter Reference System Sequence", "IsocenterReferenceSystemSequence", "SQ", "1" }, { 0x0018, 0x9463, "Positioner Isocenter Primary Angle", "PositionerIsocenterPrimaryAngle", "FL", "1" }, { 0x0018, 0x9464, "Positioner Isocenter Secondary Angle", "PositionerIsocenterSecondaryAngle", "FL", "1" }, { 0x0018, 0x9465, "Positioner Isocenter Detector Rotation Angle", "PositionerIsocenterDetectorRotationAngle", "FL", "1" }, { 0x0018, 0x9466, "Table X Position to Isocenter", "TableXPositionToIsocenter", "FL", "1" }, { 0x0018, 0x9467, "Table Y Position to Isocenter", "TableYPositionToIsocenter", "FL", "1" }, { 0x0018, 0x9468, "Table Z Position to Isocenter", "TableZPositionToIsocenter", "FL", "1" }, { 0x0018, 0x9469, "Table Horizontal Rotation Angle", "TableHorizontalRotationAngle", "FL", "1" }, { 0x0018, 0x9470, "Table Head Tilt Angle", "TableHeadTiltAngle", "FL", "1" }, { 0x0018, 0x9471, "Table Cradle Tilt Angle", "TableCradleTiltAngle", "FL", "1" }, { 0x0018, 0x9472, "Frame Display Shutter Sequence", "FrameDisplayShutterSequence", "SQ", "1" }, { 0x0018, 0x9473, "Acquired Image Area Dose Product", "AcquiredImageAreaDoseProduct", "FL", "1" }, { 0x0018, 0x9474, "C-arm Positioner Tabletop Relationship", "CArmPositionerTabletopRelationship", "CS", "1" }, { 0x0018, 0x9476, "X-Ray Geometry Sequence", "XRayGeometrySequence", "SQ", "1" }, { 0x0018, 0x9477, "Irradiation Event Identification Sequence", "IrradiationEventIdentificationSequence", "SQ", "1" }, { 0x0018, 0x9504, "X-Ray 3D Frame Type Sequence", "XRay3DFrameTypeSequence", "SQ", "1" }, { 0x0018, 0x9506, "Contributing Sources Sequence", "ContributingSourcesSequence", "SQ", "1" }, { 0x0018, 0x9507, "X-Ray 3D Acquisition Sequence", "XRay3DAcquisitionSequence", "SQ", "1" }, { 0x0018, 0x9508, "Primary Positioner Scan Arc", "PrimaryPositionerScanArc", "FL", "1" }, { 0x0018, 0x9509, "Secondary Positioner Scan Arc", "SecondaryPositionerScanArc", "FL", "1" }, { 0x0018, 0x9510, "Primary Positioner Scan Start Angle", "PrimaryPositionerScanStartAngle", "FL", "1" }, { 0x0018, 0x9511, "Secondary Positioner Scan Start Angle", "SecondaryPositionerScanStartAngle", "FL", "1" }, { 0x0018, 0x9514, "Primary Positioner Increment", "PrimaryPositionerIncrement", "FL", "1" }, { 0x0018, 0x9515, "Secondary Positioner Increment", "SecondaryPositionerIncrement", "FL", "1" }, { 0x0018, 0x9516, "Start Acquisition DateTime", "StartAcquisitionDateTime", "DT", "1" }, { 0x0018, 0x9517, "End Acquisition DateTime", "EndAcquisitionDateTime", "DT", "1" }, { 0x0018, 0x9518, "Primary Positioner Increment Sign", "PrimaryPositionerIncrementSign", "SS", "1" }, { 0x0018, 0x9519, "Secondary Positioner Increment Sign", "SecondaryPositionerIncrementSign", "SS", "1" }, { 0x0018, 0x9524, "Application Name", "ApplicationName", "LO", "1" }, { 0x0018, 0x9525, "Application Version", "ApplicationVersion", "LO", "1" }, { 0x0018, 0x9526, "Application Manufacturer", "ApplicationManufacturer", "LO", "1" }, { 0x0018, 0x9527, "Algorithm Type", "AlgorithmType", "CS", "1" }, { 0x0018, 0x9528, "Algorithm Description", "AlgorithmDescription", "LO", "1" }, { 0x0018, 0x9530, "X-Ray 3D Reconstruction Sequence", "XRay3DReconstructionSequence", "SQ", "1" }, { 0x0018, 0x9531, "Reconstruction Description", "ReconstructionDescription", "LO", "1" }, { 0x0018, 0x9538, "Per Projection Acquisition Sequence", "PerProjectionAcquisitionSequence", "SQ", "1" }, { 0x0018, 0x9541, "Detector Position Sequence", "DetectorPositionSequence", "SQ", "1" }, { 0x0018, 0x9542, "X-Ray Acquisition Dose Sequence", "XRayAcquisitionDoseSequence", "SQ", "1" }, { 0x0018, 0x9543, "X-Ray Source Isocenter Primary Angle", "XRaySourceIsocenterPrimaryAngle", "FD", "1" }, { 0x0018, 0x9544, "X-Ray Source Isocenter Secondary Angle", "XRaySourceIsocenterSecondaryAngle", "FD", "1" }, { 0x0018, 0x9545, "Breast Support Isocenter Primary Angle", "BreastSupportIsocenterPrimaryAngle", "FD", "1" }, { 0x0018, 0x9546, "Breast Support Isocenter Secondary Angle", "BreastSupportIsocenterSecondaryAngle", "FD", "1" }, { 0x0018, 0x9547, "Breast Support X Position to Isocenter", "BreastSupportXPositionToIsocenter", "FD", "1" }, { 0x0018, 0x9548, "Breast Support Y Position to Isocenter", "BreastSupportYPositionToIsocenter", "FD", "1" }, { 0x0018, 0x9549, "Breast Support Z Position to Isocenter", "BreastSupportZPositionToIsocenter", "FD", "1" }, { 0x0018, 0x9550, "Detector Isocenter Primary Angle", "DetectorIsocenterPrimaryAngle", "FD", "1" }, { 0x0018, 0x9551, "Detector Isocenter Secondary Angle", "DetectorIsocenterSecondaryAngle", "FD", "1" }, { 0x0018, 0x9552, "Detector X Position to Isocenter", "DetectorXPositionToIsocenter", "FD", "1" }, { 0x0018, 0x9553, "Detector Y Position to Isocenter", "DetectorYPositionToIsocenter", "FD", "1" }, { 0x0018, 0x9554, "Detector Z Position to Isocenter", "DetectorZPositionToIsocenter", "FD", "1" }, { 0x0018, 0x9555, "X-Ray Grid Sequence", "XRayGridSequence", "SQ", "1" }, { 0x0018, 0x9556, "X-Ray Filter Sequence", "XRayFilterSequence", "SQ", "1" }, { 0x0018, 0x9557, "Detector Active Area TLHC Position", "DetectorActiveAreaTLHCPosition", "FD", "3" }, { 0x0018, 0x9558, "Detector Active Area Orientation", "DetectorActiveAreaOrientation", "FD", "6" }, { 0x0018, 0x9559, "Positioner Primary Angle Direction", "PositionerPrimaryAngleDirection", "CS", "1" }, { 0x0018, 0x9601, "Diffusion b-matrix Sequence", "DiffusionBMatrixSequence", "SQ", "1" }, { 0x0018, 0x9602, "Diffusion b-value XX", "DiffusionBValueXX", "FD", "1" }, { 0x0018, 0x9603, "Diffusion b-value XY", "DiffusionBValueXY", "FD", "1" }, { 0x0018, 0x9604, "Diffusion b-value XZ", "DiffusionBValueXZ", "FD", "1" }, { 0x0018, 0x9605, "Diffusion b-value YY", "DiffusionBValueYY", "FD", "1" }, { 0x0018, 0x9606, "Diffusion b-value YZ", "DiffusionBValueYZ", "FD", "1" }, { 0x0018, 0x9607, "Diffusion b-value ZZ", "DiffusionBValueZZ", "FD", "1" }, { 0x0018, 0x9701, "Decay Correction DateTime", "DecayCorrectionDateTime", "DT", "1" }, { 0x0018, 0x9715, "Start Density Threshold", "StartDensityThreshold", "FD", "1" }, { 0x0018, 0x9716, "Start Relative Density Difference Threshold", "StartRelativeDensityDifferenceThreshold", "FD", "1" }, { 0x0018, 0x9717, "Start Cardiac Trigger Count Threshold", "StartCardiacTriggerCountThreshold", "FD", "1" }, { 0x0018, 0x9718, "Start Respiratory Trigger Count Threshold", "StartRespiratoryTriggerCountThreshold", "FD", "1" }, { 0x0018, 0x9719, "Termination Counts Threshold", "TerminationCountsThreshold", "FD", "1" }, { 0x0018, 0x9720, "Termination Density Threshold", "TerminationDensityThreshold", "FD", "1" }, { 0x0018, 0x9721, "Termination Relative Density Threshold", "TerminationRelativeDensityThreshold", "FD", "1" }, { 0x0018, 0x9722, "Termination Time Threshold", "TerminationTimeThreshold", "FD", "1" }, { 0x0018, 0x9723, "Termination Cardiac Trigger Count Threshold", "TerminationCardiacTriggerCountThreshold", "FD", "1" }, { 0x0018, 0x9724, "Termination Respiratory Trigger Count Threshold", "TerminationRespiratoryTriggerCountThreshold", "FD", "1" }, { 0x0018, 0x9725, "Detector Geometry", "DetectorGeometry", "CS", "1" }, { 0x0018, 0x9726, "Transverse Detector Separation", "TransverseDetectorSeparation", "FD", "1" }, { 0x0018, 0x9727, "Axial Detector Dimension", "AxialDetectorDimension", "FD", "1" }, { 0x0018, 0x9729, "Radiopharmaceutical Agent Number", "RadiopharmaceuticalAgentNumber", "US", "1" }, { 0x0018, 0x9732, "PET Frame Acquisition Sequence", "PETFrameAcquisitionSequence", "SQ", "1" }, { 0x0018, 0x9733, "PET Detector Motion Details Sequence", "PETDetectorMotionDetailsSequence", "SQ", "1" }, { 0x0018, 0x9734, "PET Table Dynamics Sequence", "PETTableDynamicsSequence", "SQ", "1" }, { 0x0018, 0x9735, "PET Position Sequence", "PETPositionSequence", "SQ", "1" }, { 0x0018, 0x9736, "PET Frame Correction Factors Sequence", "PETFrameCorrectionFactorsSequence", "SQ", "1" }, { 0x0018, 0x9737, "Radiopharmaceutical Usage Sequence", "RadiopharmaceuticalUsageSequence", "SQ", "1" }, { 0x0018, 0x9738, "Attenuation Correction Source", "AttenuationCorrectionSource", "CS", "1" }, { 0x0018, 0x9739, "Number of Iterations", "NumberOfIterations", "US", "1" }, { 0x0018, 0x9740, "Number of Subsets", "NumberOfSubsets", "US", "1" }, { 0x0018, 0x9749, "PET Reconstruction Sequence", "PETReconstructionSequence", "SQ", "1" }, { 0x0018, 0x9751, "PET Frame Type Sequence", "PETFrameTypeSequence", "SQ", "1" }, { 0x0018, 0x9755, "Time of Flight Information Used", "TimeOfFlightInformationUsed", "CS", "1" }, { 0x0018, 0x9756, "Reconstruction Type", "ReconstructionType", "CS", "1" }, { 0x0018, 0x9758, "Decay Corrected", "DecayCorrected", "CS", "1" }, { 0x0018, 0x9759, "Attenuation Corrected", "AttenuationCorrected", "CS", "1" }, { 0x0018, 0x9760, "Scatter Corrected", "ScatterCorrected", "CS", "1" }, { 0x0018, 0x9761, "Dead Time Corrected", "DeadTimeCorrected", "CS", "1" }, { 0x0018, 0x9762, "Gantry Motion Corrected", "GantryMotionCorrected", "CS", "1" }, { 0x0018, 0x9763, "Patient Motion Corrected", "PatientMotionCorrected", "CS", "1" }, { 0x0018, 0x9764, "Count Loss Normalization Corrected", "CountLossNormalizationCorrected", "CS", "1" }, { 0x0018, 0x9765, "Randoms Corrected", "RandomsCorrected", "CS", "1" }, { 0x0018, 0x9766, "Non-uniform Radial Sampling Corrected", "NonUniformRadialSamplingCorrected", "CS", "1" }, { 0x0018, 0x9767, "Sensitivity Calibrated", "SensitivityCalibrated", "CS", "1" }, { 0x0018, 0x9768, "Detector Normalization Correction", "DetectorNormalizationCorrection", "CS", "1" }, { 0x0018, 0x9769, "Iterative Reconstruction Method", "IterativeReconstructionMethod", "CS", "1" }, { 0x0018, 0x9770, "Attenuation Correction Temporal Relationship", "AttenuationCorrectionTemporalRelationship", "CS", "1" }, { 0x0018, 0x9771, "Patient Physiological State Sequence", "PatientPhysiologicalStateSequence", "SQ", "1" }, { 0x0018, 0x9772, "Patient Physiological State Code Sequence", "PatientPhysiologicalStateCodeSequence", "SQ", "1" }, { 0x0018, 0x9801, "Depth(s) of Focus", "DepthsOfFocus", "FD", "1-n" }, { 0x0018, 0x9803, "Excluded Intervals Sequence", "ExcludedIntervalsSequence", "SQ", "1" }, { 0x0018, 0x9804, "Exclusion Start DateTime", "ExclusionStartDateTime", "DT", "1" }, { 0x0018, 0x9805, "Exclusion Duration", "ExclusionDuration", "FD", "1" }, { 0x0018, 0x9806, "US Image Description Sequence", "USImageDescriptionSequence", "SQ", "1" }, { 0x0018, 0x9807, "Image Data Type Sequence", "ImageDataTypeSequence", "SQ", "1" }, { 0x0018, 0x9808, "Data Type", "DataType", "CS", "1" }, { 0x0018, 0x9809, "Transducer Scan Pattern Code Sequence", "TransducerScanPatternCodeSequence", "SQ", "1" }, { 0x0018, 0x980b, "Aliased Data Type", "AliasedDataType", "CS", "1" }, { 0x0018, 0x980c, "Position Measuring Device Used", "PositionMeasuringDeviceUsed", "CS", "1" }, { 0x0018, 0x980d, "Transducer Geometry Code Sequence", "TransducerGeometryCodeSequence", "SQ", "1" }, { 0x0018, 0x980e, "Transducer Beam Steering Code Sequence", "TransducerBeamSteeringCodeSequence", "SQ", "1" }, { 0x0018, 0x980f, "Transducer Application Code Sequence", "TransducerApplicationCodeSequence", "SQ", "1" }, { 0x0018, 0x9810, "Zero Velocity Pixel Value", "ZeroVelocityPixelValue", "US or SS", "1" }, { 0x0018, 0xa001, "Contributing Equipment Sequence", "ContributingEquipmentSequence", "SQ", "1" }, { 0x0018, 0xa002, "Contribution DateTime", "ContributionDateTime", "DT", "1" }, { 0x0018, 0xa003, "Contribution Description", "ContributionDescription", "ST", "1" }, { 0x0020, 0x000d, "Study Instance UID", "StudyInstanceUID", "UI", "1" }, { 0x0020, 0x000e, "Series Instance UID", "SeriesInstanceUID", "UI", "1" }, { 0x0020, 0x0010, "Study ID", "StudyID", "SH", "1" }, { 0x0020, 0x0011, "Series Number", "SeriesNumber", "IS", "1" }, { 0x0020, 0x0012, "Acquisition Number", "AcquisitionNumber", "IS", "1" }, { 0x0020, 0x0013, "Instance Number", "InstanceNumber", "IS", "1" }, { 0x0020, 0x0014, "Isotope Number", "IsotopeNumber", "IS", "1" }, { 0x0020, 0x0015, "Phase Number", "PhaseNumber", "IS", "1" }, { 0x0020, 0x0016, "Interval Number", "IntervalNumber", "IS", "1" }, { 0x0020, 0x0017, "Time Slot Number", "TimeSlotNumber", "IS", "1" }, { 0x0020, 0x0018, "Angle Number", "AngleNumber", "IS", "1" }, { 0x0020, 0x0019, "Item Number", "ItemNumber", "IS", "1" }, { 0x0020, 0x0020, "Patient Orientation", "PatientOrientation", "CS", "2" }, { 0x0020, 0x0022, "Overlay Number", "OverlayNumber", "IS", "1" }, { 0x0020, 0x0024, "Curve Number", "CurveNumber", "IS", "1" }, { 0x0020, 0x0026, "LUT Number", "LUTNumber", "IS", "1" }, { 0x0020, 0x0030, "Image Position", "ImagePosition", "DS", "3" }, { 0x0020, 0x0032, "Image Position (Patient)", "ImagePositionPatient", "DS", "3" }, { 0x0020, 0x0035, "Image Orientation", "ImageOrientation", "DS", "6" }, { 0x0020, 0x0037, "Image Orientation (Patient)", "ImageOrientationPatient", "DS", "6" }, { 0x0020, 0x0050, "Location", "Location", "DS", "1" }, { 0x0020, 0x0052, "Frame of Reference UID", "FrameOfReferenceUID", "UI", "1" }, { 0x0020, 0x0060, "Laterality", "Laterality", "CS", "1" }, { 0x0020, 0x0062, "Image Laterality", "ImageLaterality", "CS", "1" }, { 0x0020, 0x0070, "Image Geometry Type", "ImageGeometryType", "LO", "1" }, { 0x0020, 0x0080, "Masking Image", "MaskingImage", "CS", "1-n" }, { 0x0020, 0x00aa, "Report Number", "ReportNumber", "IS", "1" }, { 0x0020, 0x0100, "Temporal Position Identifier", "TemporalPositionIdentifier", "IS", "1" }, { 0x0020, 0x0105, "Number of Temporal Positions", "NumberOfTemporalPositions", "IS", "1" }, { 0x0020, 0x0110, "Temporal Resolution", "TemporalResolution", "DS", "1" }, { 0x0020, 0x0200, "Synchronization Frame of Reference UID", "SynchronizationFrameOfReferenceUID", "UI", "1" }, { 0x0020, 0x0242, "SOP Instance UID of Concatenation Source", "SOPInstanceUIDOfConcatenationSource", "UI", "1" }, { 0x0020, 0x1000, "Series in Study", "SeriesInStudy", "IS", "1" }, { 0x0020, 0x1001, "Acquisitions in Series", "AcquisitionsInSeries", "IS", "1" }, { 0x0020, 0x1002, "Images in Acquisition", "ImagesInAcquisition", "IS", "1" }, { 0x0020, 0x1003, "Images in Series", "ImagesInSeries", "IS", "1" }, { 0x0020, 0x1004, "Acquisitions in Study", "AcquisitionsInStudy", "IS", "1" }, { 0x0020, 0x1005, "Images in Study", "ImagesInStudy", "IS", "1" }, { 0x0020, 0x1020, "Reference", "Reference", "LO", "1-n" }, { 0x0020, 0x1040, "Position Reference Indicator", "PositionReferenceIndicator", "LO", "1" }, { 0x0020, 0x1041, "Slice Location", "SliceLocation", "DS", "1" }, { 0x0020, 0x1070, "Other Study Numbers", "OtherStudyNumbers", "IS", "1-n" }, { 0x0020, 0x1200, "Number of Patient Related Studies", "NumberOfPatientRelatedStudies", "IS", "1" }, { 0x0020, 0x1202, "Number of Patient Related Series", "NumberOfPatientRelatedSeries", "IS", "1" }, { 0x0020, 0x1204, "Number of Patient Related Instances", "NumberOfPatientRelatedInstances", "IS", "1" }, { 0x0020, 0x1206, "Number of Study Related Series", "NumberOfStudyRelatedSeries", "IS", "1" }, { 0x0020, 0x1208, "Number of Study Related Instances", "NumberOfStudyRelatedInstances", "IS", "1" }, { 0x0020, 0x1209, "Number of Series Related Instances", "NumberOfSeriesRelatedInstances", "IS", "1" }, { 0x0020, 0x3401, "Modifying Device ID", "ModifyingDeviceID", "CS", "1" }, { 0x0020, 0x3402, "Modified Image ID", "ModifiedImageID", "CS", "1" }, { 0x0020, 0x3403, "Modified Image Date", "ModifiedImageDate", "DA", "1" }, { 0x0020, 0x3404, "Modifying Device Manufacturer", "ModifyingDeviceManufacturer", "LO", "1" }, { 0x0020, 0x3405, "Modified Image Time", "ModifiedImageTime", "TM", "1" }, { 0x0020, 0x3406, "Modified Image Description", "ModifiedImageDescription", "LO", "1" }, { 0x0020, 0x4000, "Image Comments", "ImageComments", "LT", "1" }, { 0x0020, 0x5000, "Original Image Identification", "OriginalImageIdentification", "AT", "1-n" }, { 0x0020, 0x5002, "Original Image Identification Nomenclature", "OriginalImageIdentificationNomenclature", "LO", "1-n" }, { 0x0020, 0x9056, "Stack ID", "StackID", "SH", "1" }, { 0x0020, 0x9057, "In-Stack Position Number", "InStackPositionNumber", "UL", "1" }, { 0x0020, 0x9071, "Frame Anatomy Sequence", "FrameAnatomySequence", "SQ", "1" }, { 0x0020, 0x9072, "Frame Laterality", "FrameLaterality", "CS", "1" }, { 0x0020, 0x9111, "Frame Content Sequence", "FrameContentSequence", "SQ", "1" }, { 0x0020, 0x9113, "Plane Position Sequence", "PlanePositionSequence", "SQ", "1" }, { 0x0020, 0x9116, "Plane Orientation Sequence", "PlaneOrientationSequence", "SQ", "1" }, { 0x0020, 0x9128, "Temporal Position Index", "TemporalPositionIndex", "UL", "1" }, { 0x0020, 0x9153, "Nominal Cardiac Trigger Delay Time", "NominalCardiacTriggerDelayTime", "FD", "1" }, { 0x0020, 0x9154, "Nominal Cardiac Trigger Time Prior To R-Peak", "NominalCardiacTriggerTimePriorToRPeak", "FL", "1" }, { 0x0020, 0x9155, "Actual Cardiac Trigger Time Prior To R-Peak", "ActualCardiacTriggerTimePriorToRPeak", "FL", "1" }, { 0x0020, 0x9156, "Frame Acquisition Number", "FrameAcquisitionNumber", "US", "1" }, { 0x0020, 0x9157, "Dimension Index Values", "DimensionIndexValues", "UL", "1-n" }, { 0x0020, 0x9158, "Frame Comments", "FrameComments", "LT", "1" }, { 0x0020, 0x9161, "Concatenation UID", "ConcatenationUID", "UI", "1" }, { 0x0020, 0x9162, "In-concatenation Number", "InConcatenationNumber", "US", "1" }, { 0x0020, 0x9163, "In-concatenation Total Number", "InConcatenationTotalNumber", "US", "1" }, { 0x0020, 0x9164, "Dimension Organization UID", "DimensionOrganizationUID", "UI", "1" }, { 0x0020, 0x9165, "Dimension Index Pointer", "DimensionIndexPointer", "AT", "1" }, { 0x0020, 0x9167, "Functional Group Pointer", "FunctionalGroupPointer", "AT", "1" }, { 0x0020, 0x9170, "Unassigned Shared Converted Attributes Sequence", "UnassignedSharedConvertedAttributesSequence", "SQ", "1" }, { 0x0020, 0x9171, "Unassigned Per-Frame Converted Attributes Sequence", "UnassignedPerFrameConvertedAttributesSequence", "SQ", "1" }, { 0x0020, 0x9172, "Conversion Source Attributes Sequence", "ConversionSourceAttributesSequence", "SQ", "1" }, { 0x0020, 0x9213, "Dimension Index Private Creator", "DimensionIndexPrivateCreator", "LO", "1" }, { 0x0020, 0x9221, "Dimension Organization Sequence", "DimensionOrganizationSequence", "SQ", "1" }, { 0x0020, 0x9222, "Dimension Index Sequence", "DimensionIndexSequence", "SQ", "1" }, { 0x0020, 0x9228, "Concatenation Frame Offset Number", "ConcatenationFrameOffsetNumber", "UL", "1" }, { 0x0020, 0x9238, "Functional Group Private Creator", "FunctionalGroupPrivateCreator", "LO", "1" }, { 0x0020, 0x9241, "Nominal Percentage of Cardiac Phase", "NominalPercentageOfCardiacPhase", "FL", "1" }, { 0x0020, 0x9245, "Nominal Percentage of Respiratory Phase", "NominalPercentageOfRespiratoryPhase", "FL", "1" }, { 0x0020, 0x9246, "Starting Respiratory Amplitude", "StartingRespiratoryAmplitude", "FL", "1" }, { 0x0020, 0x9247, "Starting Respiratory Phase", "StartingRespiratoryPhase", "CS", "1" }, { 0x0020, 0x9248, "Ending Respiratory Amplitude", "EndingRespiratoryAmplitude", "FL", "1" }, { 0x0020, 0x9249, "Ending Respiratory Phase", "EndingRespiratoryPhase", "CS", "1" }, { 0x0020, 0x9250, "Respiratory Trigger Type", "RespiratoryTriggerType", "CS", "1" }, { 0x0020, 0x9251, "R-R Interval Time Nominal", "RRIntervalTimeNominal", "FD", "1" }, { 0x0020, 0x9252, "Actual Cardiac Trigger Delay Time", "ActualCardiacTriggerDelayTime", "FD", "1" }, { 0x0020, 0x9253, "Respiratory Synchronization Sequence", "RespiratorySynchronizationSequence", "SQ", "1" }, { 0x0020, 0x9254, "Respiratory Interval Time", "RespiratoryIntervalTime", "FD", "1" }, { 0x0020, 0x9255, "Nominal Respiratory Trigger Delay Time", "NominalRespiratoryTriggerDelayTime", "FD", "1" }, { 0x0020, 0x9256, "Respiratory Trigger Delay Threshold", "RespiratoryTriggerDelayThreshold", "FD", "1" }, { 0x0020, 0x9257, "Actual Respiratory Trigger Delay Time", "ActualRespiratoryTriggerDelayTime", "FD", "1" }, { 0x0020, 0x9301, "Image Position (Volume)", "ImagePositionVolume", "FD", "3" }, { 0x0020, 0x9302, "Image Orientation (Volume)", "ImageOrientationVolume", "FD", "6" }, { 0x0020, 0x9307, "Ultrasound Acquisition Geometry", "UltrasoundAcquisitionGeometry", "CS", "1" }, { 0x0020, 0x9308, "Apex Position", "ApexPosition", "FD", "3" }, { 0x0020, 0x9309, "Volume to Transducer Mapping Matrix", "VolumeToTransducerMappingMatrix", "FD", "16" }, { 0x0020, 0x930a, "Volume to Table Mapping Matrix", "VolumeToTableMappingMatrix", "FD", "16" }, { 0x0020, 0x930b, "Volume to Transducer Relationship", "VolumeToTransducerRelationship", "CS", "1" }, { 0x0020, 0x930c, "Patient Frame of Reference Source", "PatientFrameOfReferenceSource", "CS", "1" }, { 0x0020, 0x930d, "Temporal Position Time Offset", "TemporalPositionTimeOffset", "FD", "1" }, { 0x0020, 0x930e, "Plane Position (Volume) Sequence", "PlanePositionVolumeSequence", "SQ", "1" }, { 0x0020, 0x930f, "Plane Orientation (Volume) Sequence", "PlaneOrientationVolumeSequence", "SQ", "1" }, { 0x0020, 0x9310, "Temporal Position Sequence", "TemporalPositionSequence", "SQ", "1" }, { 0x0020, 0x9311, "Dimension Organization Type", "DimensionOrganizationType", "CS", "1" }, { 0x0020, 0x9312, "Volume Frame of Reference UID", "VolumeFrameOfReferenceUID", "UI", "1" }, { 0x0020, 0x9313, "Table Frame of Reference UID", "TableFrameOfReferenceUID", "UI", "1" }, { 0x0020, 0x9421, "Dimension Description Label", "DimensionDescriptionLabel", "LO", "1" }, { 0x0020, 0x9450, "Patient Orientation in Frame Sequence", "PatientOrientationInFrameSequence", "SQ", "1" }, { 0x0020, 0x9453, "Frame Label", "FrameLabel", "LO", "1" }, { 0x0020, 0x9518, "Acquisition Index", "AcquisitionIndex", "US", "1-n" }, { 0x0020, 0x9529, "Contributing SOP Instances Reference Sequence", "ContributingSOPInstancesReferenceSequence", "SQ", "1" }, { 0x0020, 0x9536, "Reconstruction Index", "ReconstructionIndex", "US", "1" }, { 0x0022, 0x0001, "Light Path Filter Pass-Through Wavelength", "LightPathFilterPassThroughWavelength", "US", "1" }, { 0x0022, 0x0002, "Light Path Filter Pass Band", "LightPathFilterPassBand", "US", "2" }, { 0x0022, 0x0003, "Image Path Filter Pass-Through Wavelength", "ImagePathFilterPassThroughWavelength", "US", "1" }, { 0x0022, 0x0004, "Image Path Filter Pass Band", "ImagePathFilterPassBand", "US", "2" }, { 0x0022, 0x0005, "Patient Eye Movement Commanded", "PatientEyeMovementCommanded", "CS", "1" }, { 0x0022, 0x0006, "Patient Eye Movement Command Code Sequence", "PatientEyeMovementCommandCodeSequence", "SQ", "1" }, { 0x0022, 0x0007, "Spherical Lens Power", "SphericalLensPower", "FL", "1" }, { 0x0022, 0x0008, "Cylinder Lens Power", "CylinderLensPower", "FL", "1" }, { 0x0022, 0x0009, "Cylinder Axis", "CylinderAxis", "FL", "1" }, { 0x0022, 0x000a, "Emmetropic Magnification", "EmmetropicMagnification", "FL", "1" }, { 0x0022, 0x000b, "Intra Ocular Pressure", "IntraOcularPressure", "FL", "1" }, { 0x0022, 0x000c, "Horizontal Field of View", "HorizontalFieldOfView", "FL", "1" }, { 0x0022, 0x000d, "Pupil Dilated", "PupilDilated", "CS", "1" }, { 0x0022, 0x000e, "Degree of Dilation", "DegreeOfDilation", "FL", "1" }, { 0x0022, 0x0010, "Stereo Baseline Angle", "StereoBaselineAngle", "FL", "1" }, { 0x0022, 0x0011, "Stereo Baseline Displacement", "StereoBaselineDisplacement", "FL", "1" }, { 0x0022, 0x0012, "Stereo Horizontal Pixel Offset", "StereoHorizontalPixelOffset", "FL", "1" }, { 0x0022, 0x0013, "Stereo Vertical Pixel Offset", "StereoVerticalPixelOffset", "FL", "1" }, { 0x0022, 0x0014, "Stereo Rotation", "StereoRotation", "FL", "1" }, { 0x0022, 0x0015, "Acquisition Device Type Code Sequence", "AcquisitionDeviceTypeCodeSequence", "SQ", "1" }, { 0x0022, 0x0016, "Illumination Type Code Sequence", "IlluminationTypeCodeSequence", "SQ", "1" }, { 0x0022, 0x0017, "Light Path Filter Type Stack Code Sequence", "LightPathFilterTypeStackCodeSequence", "SQ", "1" }, { 0x0022, 0x0018, "Image Path Filter Type Stack Code Sequence", "ImagePathFilterTypeStackCodeSequence", "SQ", "1" }, { 0x0022, 0x0019, "Lenses Code Sequence", "LensesCodeSequence", "SQ", "1" }, { 0x0022, 0x001a, "Channel Description Code Sequence", "ChannelDescriptionCodeSequence", "SQ", "1" }, { 0x0022, 0x001b, "Refractive State Sequence", "RefractiveStateSequence", "SQ", "1" }, { 0x0022, 0x001c, "Mydriatic Agent Code Sequence", "MydriaticAgentCodeSequence", "SQ", "1" }, { 0x0022, 0x001d, "Relative Image Position Code Sequence", "RelativeImagePositionCodeSequence", "SQ", "1" }, { 0x0022, 0x001e, "Camera Angle of View", "CameraAngleOfView", "FL", "1" }, { 0x0022, 0x0020, "Stereo Pairs Sequence", "StereoPairsSequence", "SQ", "1" }, { 0x0022, 0x0021, "Left Image Sequence", "LeftImageSequence", "SQ", "1" }, { 0x0022, 0x0022, "Right Image Sequence", "RightImageSequence", "SQ", "1" }, { 0x0022, 0x0028, "Stereo Pairs Present", "StereoPairsPresent", "CS", "1" }, { 0x0022, 0x0030, "Axial Length of the Eye", "AxialLengthOfTheEye", "FL", "1" }, { 0x0022, 0x0031, "Ophthalmic Frame Location Sequence", "OphthalmicFrameLocationSequence", "SQ", "1" }, { 0x0022, 0x0032, "Reference Coordinates", "ReferenceCoordinates", "FL", "2-2n" }, { 0x0022, 0x0035, "Depth Spatial Resolution", "DepthSpatialResolution", "FL", "1" }, { 0x0022, 0x0036, "Maximum Depth Distortion", "MaximumDepthDistortion", "FL", "1" }, { 0x0022, 0x0037, "Along-scan Spatial Resolution", "AlongScanSpatialResolution", "FL", "1" }, { 0x0022, 0x0038, "Maximum Along-scan Distortion", "MaximumAlongScanDistortion", "FL", "1" }, { 0x0022, 0x0039, "Ophthalmic Image Orientation", "OphthalmicImageOrientation", "CS", "1" }, { 0x0022, 0x0041, "Depth of Transverse Image", "DepthOfTransverseImage", "FL", "1" }, { 0x0022, 0x0042, "Mydriatic Agent Concentration Units Sequence", "MydriaticAgentConcentrationUnitsSequence", "SQ", "1" }, { 0x0022, 0x0048, "Across-scan Spatial Resolution", "AcrossScanSpatialResolution", "FL", "1" }, { 0x0022, 0x0049, "Maximum Across-scan Distortion", "MaximumAcrossScanDistortion", "FL", "1" }, { 0x0022, 0x004e, "Mydriatic Agent Concentration", "MydriaticAgentConcentration", "DS", "1" }, { 0x0022, 0x0055, "Illumination Wave Length", "IlluminationWaveLength", "FL", "1" }, { 0x0022, 0x0056, "Illumination Power", "IlluminationPower", "FL", "1" }, { 0x0022, 0x0057, "Illumination Bandwidth", "IlluminationBandwidth", "FL", "1" }, { 0x0022, 0x0058, "Mydriatic Agent Sequence", "MydriaticAgentSequence", "SQ", "1" }, { 0x0022, 0x1007, "Ophthalmic Axial Measurements Right Eye Sequence", "OphthalmicAxialMeasurementsRightEyeSequence", "SQ", "1" }, { 0x0022, 0x1008, "Ophthalmic Axial Measurements Left Eye Sequence", "OphthalmicAxialMeasurementsLeftEyeSequence", "SQ", "1" }, { 0x0022, 0x1009, "Ophthalmic Axial Measurements Device Type", "OphthalmicAxialMeasurementsDeviceType", "CS", "1" }, { 0x0022, 0x1010, "Ophthalmic Axial Length Measurements Type", "OphthalmicAxialLengthMeasurementsType", "CS", "1" }, { 0x0022, 0x1012, "Ophthalmic Axial Length Sequence", "OphthalmicAxialLengthSequence", "SQ", "1" }, { 0x0022, 0x1019, "Ophthalmic Axial Length", "OphthalmicAxialLength", "FL", "1" }, { 0x0022, 0x1024, "Lens Status Code Sequence", "LensStatusCodeSequence", "SQ", "1" }, { 0x0022, 0x1025, "Vitreous Status Code Sequence", "VitreousStatusCodeSequence", "SQ", "1" }, { 0x0022, 0x1028, "IOL Formula Code Sequence", "IOLFormulaCodeSequence", "SQ", "1" }, { 0x0022, 0x1029, "IOL Formula Detail", "IOLFormulaDetail", "LO", "1" }, { 0x0022, 0x1033, "Keratometer Index", "KeratometerIndex", "FL", "1" }, { 0x0022, 0x1035, "Source of Ophthalmic Axial Length Code Sequence", "SourceOfOphthalmicAxialLengthCodeSequence", "SQ", "1" }, { 0x0022, 0x1037, "Target Refraction", "TargetRefraction", "FL", "1" }, { 0x0022, 0x1039, "Refractive Procedure Occurred", "RefractiveProcedureOccurred", "CS", "1" }, { 0x0022, 0x1040, "Refractive Surgery Type Code Sequence", "RefractiveSurgeryTypeCodeSequence", "SQ", "1" }, { 0x0022, 0x1044, "Ophthalmic Ultrasound Method Code Sequence", "OphthalmicUltrasoundMethodCodeSequence", "SQ", "1" }, { 0x0022, 0x1050, "Ophthalmic Axial Length Measurements Sequence", "OphthalmicAxialLengthMeasurementsSequence", "SQ", "1" }, { 0x0022, 0x1053, "IOL Power", "IOLPower", "FL", "1" }, { 0x0022, 0x1054, "Predicted Refractive Error", "PredictedRefractiveError", "FL", "1" }, { 0x0022, 0x1059, "Ophthalmic Axial Length Velocity", "OphthalmicAxialLengthVelocity", "FL", "1" }, { 0x0022, 0x1065, "Lens Status Description", "LensStatusDescription", "LO", "1" }, { 0x0022, 0x1066, "Vitreous Status Description", "VitreousStatusDescription", "LO", "1" }, { 0x0022, 0x1090, "IOL Power Sequence", "IOLPowerSequence", "SQ", "1" }, { 0x0022, 0x1092, "Lens Constant Sequence", "LensConstantSequence", "SQ", "1" }, { 0x0022, 0x1093, "IOL Manufacturer", "IOLManufacturer", "LO", "1" }, { 0x0022, 0x1094, "Lens Constant Description", "LensConstantDescription", "LO", "1" }, { 0x0022, 0x1095, "Implant Name", "ImplantName", "LO", "1" }, { 0x0022, 0x1096, "Keratometry Measurement Type Code Sequence", "KeratometryMeasurementTypeCodeSequence", "SQ", "1" }, { 0x0022, 0x1097, "Implant Part Number", "ImplantPartNumber", "LO", "1" }, { 0x0022, 0x1100, "Referenced Ophthalmic Axial Measurements Sequence", "ReferencedOphthalmicAxialMeasurementsSequence", "SQ", "1" }, { 0x0022, 0x1101, "Ophthalmic Axial Length Measurements Segment Name Code Sequence", "OphthalmicAxialLengthMeasurementsSegmentNameCodeSequence", "SQ", "1" }, { 0x0022, 0x1103, "Refractive Error Before Refractive Surgery Code Sequence", "RefractiveErrorBeforeRefractiveSurgeryCodeSequence", "SQ", "1" }, { 0x0022, 0x1121, "IOL Power For Exact Emmetropia", "IOLPowerForExactEmmetropia", "FL", "1" }, { 0x0022, 0x1122, "IOL Power For Exact Target Refraction", "IOLPowerForExactTargetRefraction", "FL", "1" }, { 0x0022, 0x1125, "Anterior Chamber Depth Definition Code Sequence", "AnteriorChamberDepthDefinitionCodeSequence", "SQ", "1" }, { 0x0022, 0x1127, "Lens Thickness Sequence", "LensThicknessSequence", "SQ", "1" }, { 0x0022, 0x1128, "Anterior Chamber Depth Sequence", "AnteriorChamberDepthSequence", "SQ", "1" }, { 0x0022, 0x1130, "Lens Thickness", "LensThickness", "FL", "1" }, { 0x0022, 0x1131, "Anterior Chamber Depth", "AnteriorChamberDepth", "FL", "1" }, { 0x0022, 0x1132, "Source of Lens Thickness Data Code Sequence", "SourceOfLensThicknessDataCodeSequence", "SQ", "1" }, { 0x0022, 0x1133, "Source of Anterior Chamber Depth Data Code Sequence", "SourceOfAnteriorChamberDepthDataCodeSequence", "SQ", "1" }, { 0x0022, 0x1134, "Source of Refractive Measurements Sequence", "SourceOfRefractiveMeasurementsSequence", "SQ", "1" }, { 0x0022, 0x1135, "Source of Refractive Measurements Code Sequence", "SourceOfRefractiveMeasurementsCodeSequence", "SQ", "1" }, { 0x0022, 0x1140, "Ophthalmic Axial Length Measurement Modified", "OphthalmicAxialLengthMeasurementModified", "CS", "1" }, { 0x0022, 0x1150, "Ophthalmic Axial Length Data Source Code Sequence", "OphthalmicAxialLengthDataSourceCodeSequence", "SQ", "1" }, { 0x0022, 0x1153, "Ophthalmic Axial Length Acquisition Method Code Sequence", "OphthalmicAxialLengthAcquisitionMethodCodeSequence", "SQ", "1" }, { 0x0022, 0x1155, "Signal to Noise Ratio", "SignalToNoiseRatio", "FL", "1" }, { 0x0022, 0x1159, "Ophthalmic Axial Length Data Source Description", "OphthalmicAxialLengthDataSourceDescription", "LO", "1" }, { 0x0022, 0x1210, "Ophthalmic Axial Length Measurements Total Length Sequence", "OphthalmicAxialLengthMeasurementsTotalLengthSequence", "SQ", "1" }, { 0x0022, 0x1211, "Ophthalmic Axial Length Measurements Segmental Length Sequence", "OphthalmicAxialLengthMeasurementsSegmentalLengthSequence", "SQ", "1" }, { 0x0022, 0x1212, "Ophthalmic Axial Length Measurements Length Summation Sequence", "OphthalmicAxialLengthMeasurementsLengthSummationSequence", "SQ", "1" }, { 0x0022, 0x1220, "Ultrasound Ophthalmic Axial Length Measurements Sequence", "UltrasoundOphthalmicAxialLengthMeasurementsSequence", "SQ", "1" }, { 0x0022, 0x1225, "Optical Ophthalmic Axial Length Measurements Sequence", "OpticalOphthalmicAxialLengthMeasurementsSequence", "SQ", "1" }, { 0x0022, 0x1230, "Ultrasound Selected Ophthalmic Axial Length Sequence", "UltrasoundSelectedOphthalmicAxialLengthSequence", "SQ", "1" }, { 0x0022, 0x1250, "Ophthalmic Axial Length Selection Method Code Sequence", "OphthalmicAxialLengthSelectionMethodCodeSequence", "SQ", "1" }, { 0x0022, 0x1255, "Optical Selected Ophthalmic Axial Length Sequence", "OpticalSelectedOphthalmicAxialLengthSequence", "SQ", "1" }, { 0x0022, 0x1257, "Selected Segmental Ophthalmic Axial Length Sequence", "SelectedSegmentalOphthalmicAxialLengthSequence", "SQ", "1" }, { 0x0022, 0x1260, "Selected Total Ophthalmic Axial Length Sequence", "SelectedTotalOphthalmicAxialLengthSequence", "SQ", "1" }, { 0x0022, 0x1262, "Ophthalmic Axial Length Quality Metric Sequence", "OphthalmicAxialLengthQualityMetricSequence", "SQ", "1" }, { 0x0022, 0x1265, "Ophthalmic Axial Length Quality Metric Type Code Sequence", "OphthalmicAxialLengthQualityMetricTypeCodeSequence", "SQ", "1" }, { 0x0022, 0x1273, "Ophthalmic Axial Length Quality Metric Type Description", "OphthalmicAxialLengthQualityMetricTypeDescription", "LO", "1" }, { 0x0022, 0x1300, "Intraocular Lens Calculations Right Eye Sequence", "IntraocularLensCalculationsRightEyeSequence", "SQ", "1" }, { 0x0022, 0x1310, "Intraocular Lens Calculations Left Eye Sequence", "IntraocularLensCalculationsLeftEyeSequence", "SQ", "1" }, { 0x0022, 0x1330, "Referenced Ophthalmic Axial Length Measurement QC Image Sequence", "ReferencedOphthalmicAxialLengthMeasurementQCImageSequence", "SQ", "1" }, { 0x0022, 0x1415, "Ophthalmic Mapping Device Type", "OphthalmicMappingDeviceType", "CS", "1" }, { 0x0022, 0x1420, "Acquisition Method Code Sequence", "AcquisitionMethodCodeSequence", "SQ", "1" }, { 0x0022, 0x1423, "Acquisition Method Algorithm Sequence", "AcquisitionMethodAlgorithmSequence", "SQ", "1" }, { 0x0022, 0x1436, "Ophthalmic Thickness Map Type Code Sequence", "OphthalmicThicknessMapTypeCodeSequence", "SQ", "1" }, { 0x0022, 0x1443, "Ophthalmic Thickness Mapping Normals Sequence", "OphthalmicThicknessMappingNormalsSequence", "SQ", "1" }, { 0x0022, 0x1445, "Retinal Thickness Definition Code Sequence", "RetinalThicknessDefinitionCodeSequence", "SQ", "1" }, { 0x0022, 0x1450, "Pixel Value Mapping to Coded Concept Sequence", "PixelValueMappingToCodedConceptSequence", "SQ", "1" }, { 0x0022, 0x1452, "Mapped Pixel Value", "MappedPixelValue", "US or SS", "1" }, { 0x0022, 0x1454, "Pixel Value Mapping Explanation", "PixelValueMappingExplanation", "LO", "1" }, { 0x0022, 0x1458, "Ophthalmic Thickness Map Quality Threshold Sequence", "OphthalmicThicknessMapQualityThresholdSequence", "SQ", "1" }, { 0x0022, 0x1460, "Ophthalmic Thickness Map Threshold Quality Rating", "OphthalmicThicknessMapThresholdQualityRating", "FL", "1" }, { 0x0022, 0x1463, "Anatomic Structure Reference Point", "AnatomicStructureReferencePoint", "FL", "2" }, { 0x0022, 0x1465, "Registration to Localizer Sequence", "RegistrationToLocalizerSequence", "SQ", "1" }, { 0x0022, 0x1466, "Registered Localizer Units", "RegisteredLocalizerUnits", "CS", "1" }, { 0x0022, 0x1467, "Registered Localizer Top Left Hand Corner", "RegisteredLocalizerTopLeftHandCorner", "FL", "2" }, { 0x0022, 0x1468, "Registered Localizer Bottom Right Hand Corner", "RegisteredLocalizerBottomRightHandCorner", "FL", "2" }, { 0x0022, 0x1470, "Ophthalmic Thickness Map Quality Rating Sequence", "OphthalmicThicknessMapQualityRatingSequence", "SQ", "1" }, { 0x0022, 0x1472, "Relevant OPT Attributes Sequence", "RelevantOPTAttributesSequence", "SQ", "1" }, { 0x0022, 0x1512, "Transformation Method Code Sequence", "TransformationMethodCodeSequence", "SQ", "1" }, { 0x0022, 0x1513, "Transformation Algorithm Sequence", "TransformationAlgorithmSequence", "SQ", "1" }, { 0x0022, 0x1515, "Ophthalmic Axial Length Method", "OphthalmicAxialLengthMethod", "CS", "1" }, { 0x0022, 0x1517, "Ophthalmic FOV", "OphthalmicFOV", "FL", "1" }, { 0x0022, 0x1518, "Two Dimensional to Three Dimensional Map Sequence", "TwoDimensionalToThreeDimensionalMapSequence", "SQ", "1" }, { 0x0022, 0x1525, "Wide Field Ophthalmic Photography Quality Rating Sequence", "WideFieldOphthalmicPhotographyQualityRatingSequence", "SQ", "1" }, { 0x0022, 0x1526, "Wide Field Ophthalmic Photography Quality Threshold Sequence", "WideFieldOphthalmicPhotographyQualityThresholdSequence", "SQ", "1" }, { 0x0022, 0x1527, "Wide Field Ophthalmic Photography Threshold Quality Rating", "WideFieldOphthalmicPhotographyThresholdQualityRating", "FL", "1" }, { 0x0022, 0x1528, "X Coordinates Center Pixel View Angle", "XCoordinatesCenterPixelViewAngle", "FL", "1" }, { 0x0022, 0x1529, "Y Coordinates Center Pixel View Angle", "YCoordinatesCenterPixelViewAngle", "FL", "1" }, { 0x0022, 0x1530, "Number of Map Points", "NumberOfMapPoints", "UL", "1" }, { 0x0022, 0x1531, "Two Dimensional to Three Dimensional Map Data", "TwoDimensionalToThreeDimensionalMapData", "OF", "1" }, { 0x0024, 0x0010, "Visual Field Horizontal Extent", "VisualFieldHorizontalExtent", "FL", "1" }, { 0x0024, 0x0011, "Visual Field Vertical Extent", "VisualFieldVerticalExtent", "FL", "1" }, { 0x0024, 0x0012, "Visual Field Shape", "VisualFieldShape", "CS", "1" }, { 0x0024, 0x0016, "Screening Test Mode Code Sequence", "ScreeningTestModeCodeSequence", "SQ", "1" }, { 0x0024, 0x0018, "Maximum Stimulus Luminance", "MaximumStimulusLuminance", "FL", "1" }, { 0x0024, 0x0020, "Background Luminance", "BackgroundLuminance", "FL", "1" }, { 0x0024, 0x0021, "Stimulus Color Code Sequence", "StimulusColorCodeSequence", "SQ", "1" }, { 0x0024, 0x0024, "Background Illumination Color Code Sequence", "BackgroundIlluminationColorCodeSequence", "SQ", "1" }, { 0x0024, 0x0025, "Stimulus Area", "StimulusArea", "FL", "1" }, { 0x0024, 0x0028, "Stimulus Presentation Time", "StimulusPresentationTime", "FL", "1" }, { 0x0024, 0x0032, "Fixation Sequence", "FixationSequence", "SQ", "1" }, { 0x0024, 0x0033, "Fixation Monitoring Code Sequence", "FixationMonitoringCodeSequence", "SQ", "1" }, { 0x0024, 0x0034, "Visual Field Catch Trial Sequence", "VisualFieldCatchTrialSequence", "SQ", "1" }, { 0x0024, 0x0035, "Fixation Checked Quantity", "FixationCheckedQuantity", "US", "1" }, { 0x0024, 0x0036, "Patient Not Properly Fixated Quantity", "PatientNotProperlyFixatedQuantity", "US", "1" }, { 0x0024, 0x0037, "Presented Visual Stimuli Data Flag", "PresentedVisualStimuliDataFlag", "CS", "1" }, { 0x0024, 0x0038, "Number of Visual Stimuli", "NumberOfVisualStimuli", "US", "1" }, { 0x0024, 0x0039, "Excessive Fixation Losses Data Flag", "ExcessiveFixationLossesDataFlag", "CS", "1" }, { 0x0024, 0x0040, "Excessive Fixation Losses", "ExcessiveFixationLosses", "CS", "1" }, { 0x0024, 0x0042, "Stimuli Retesting Quantity", "StimuliRetestingQuantity", "US", "1" }, { 0x0024, 0x0044, "Comments on Patient's Performance of Visual Field", "CommentsOnPatientPerformanceOfVisualField", "LT", "1" }, { 0x0024, 0x0045, "False Negatives Estimate Flag", "FalseNegativesEstimateFlag", "CS", "1" }, { 0x0024, 0x0046, "False Negatives Estimate", "FalseNegativesEstimate", "FL", "1" }, { 0x0024, 0x0048, "Negative Catch Trials Quantity", "NegativeCatchTrialsQuantity", "US", "1" }, { 0x0024, 0x0050, "False Negatives Quantity", "FalseNegativesQuantity", "US", "1" }, { 0x0024, 0x0051, "Excessive False Negatives Data Flag", "ExcessiveFalseNegativesDataFlag", "CS", "1" }, { 0x0024, 0x0052, "Excessive False Negatives", "ExcessiveFalseNegatives", "CS", "1" }, { 0x0024, 0x0053, "False Positives Estimate Flag", "FalsePositivesEstimateFlag", "CS", "1" }, { 0x0024, 0x0054, "False Positives Estimate", "FalsePositivesEstimate", "FL", "1" }, { 0x0024, 0x0055, "Catch Trials Data Flag", "CatchTrialsDataFlag", "CS", "1" }, { 0x0024, 0x0056, "Positive Catch Trials Quantity", "PositiveCatchTrialsQuantity", "US", "1" }, { 0x0024, 0x0057, "Test Point Normals Data Flag", "TestPointNormalsDataFlag", "CS", "1" }, { 0x0024, 0x0058, "Test Point Normals Sequence", "TestPointNormalsSequence", "SQ", "1" }, { 0x0024, 0x0059, "Global Deviation Probability Normals Flag", "GlobalDeviationProbabilityNormalsFlag", "CS", "1" }, { 0x0024, 0x0060, "False Positives Quantity", "FalsePositivesQuantity", "US", "1" }, { 0x0024, 0x0061, "Excessive False Positives Data Flag", "ExcessiveFalsePositivesDataFlag", "CS", "1" }, { 0x0024, 0x0062, "Excessive False Positives", "ExcessiveFalsePositives", "CS", "1" }, { 0x0024, 0x0063, "Visual Field Test Normals Flag", "VisualFieldTestNormalsFlag", "CS", "1" }, { 0x0024, 0x0064, "Results Normals Sequence", "ResultsNormalsSequence", "SQ", "1" }, { 0x0024, 0x0065, "Age Corrected Sensitivity Deviation Algorithm Sequence", "AgeCorrectedSensitivityDeviationAlgorithmSequence", "SQ", "1" }, { 0x0024, 0x0066, "Global Deviation From Normal", "GlobalDeviationFromNormal", "FL", "1" }, { 0x0024, 0x0067, "Generalized Defect Sensitivity Deviation Algorithm Sequence", "GeneralizedDefectSensitivityDeviationAlgorithmSequence", "SQ", "1" }, { 0x0024, 0x0068, "Localized Deviation From Normal", "LocalizedDeviationFromNormal", "FL", "1" }, { 0x0024, 0x0069, "Patient Reliability Indicator", "PatientReliabilityIndicator", "LO", "1" }, { 0x0024, 0x0070, "Visual Field Mean Sensitivity", "VisualFieldMeanSensitivity", "FL", "1" }, { 0x0024, 0x0071, "Global Deviation Probability", "GlobalDeviationProbability", "FL", "1" }, { 0x0024, 0x0072, "Local Deviation Probability Normals Flag", "LocalDeviationProbabilityNormalsFlag", "CS", "1" }, { 0x0024, 0x0073, "Localized Deviation Probability", "LocalizedDeviationProbability", "FL", "1" }, { 0x0024, 0x0074, "Short Term Fluctuation Calculated", "ShortTermFluctuationCalculated", "CS", "1" }, { 0x0024, 0x0075, "Short Term Fluctuation", "ShortTermFluctuation", "FL", "1" }, { 0x0024, 0x0076, "Short Term Fluctuation Probability Calculated", "ShortTermFluctuationProbabilityCalculated", "CS", "1" }, { 0x0024, 0x0077, "Short Term Fluctuation Probability", "ShortTermFluctuationProbability", "FL", "1" }, { 0x0024, 0x0078, "Corrected Localized Deviation From Normal Calculated", "CorrectedLocalizedDeviationFromNormalCalculated", "CS", "1" }, { 0x0024, 0x0079, "Corrected Localized Deviation From Normal", "CorrectedLocalizedDeviationFromNormal", "FL", "1" }, { 0x0024, 0x0080, "Corrected Localized Deviation From Normal Probability Calculated", "CorrectedLocalizedDeviationFromNormalProbabilityCalculated", "CS", "1" }, { 0x0024, 0x0081, "Corrected Localized Deviation From Normal Probability", "CorrectedLocalizedDeviationFromNormalProbability", "FL", "1" }, { 0x0024, 0x0083, "Global Deviation Probability Sequence", "GlobalDeviationProbabilitySequence", "SQ", "1" }, { 0x0024, 0x0085, "Localized Deviation Probability Sequence", "LocalizedDeviationProbabilitySequence", "SQ", "1" }, { 0x0024, 0x0086, "Foveal Sensitivity Measured", "FovealSensitivityMeasured", "CS", "1" }, { 0x0024, 0x0087, "Foveal Sensitivity", "FovealSensitivity", "FL", "1" }, { 0x0024, 0x0088, "Visual Field Test Duration", "VisualFieldTestDuration", "FL", "1" }, { 0x0024, 0x0089, "Visual Field Test Point Sequence", "VisualFieldTestPointSequence", "SQ", "1" }, { 0x0024, 0x0090, "Visual Field Test Point X-Coordinate", "VisualFieldTestPointXCoordinate", "FL", "1" }, { 0x0024, 0x0091, "Visual Field Test Point Y-Coordinate", "VisualFieldTestPointYCoordinate", "FL", "1" }, { 0x0024, 0x0092, "Age Corrected Sensitivity Deviation Value", "AgeCorrectedSensitivityDeviationValue", "FL", "1" }, { 0x0024, 0x0093, "Stimulus Results", "StimulusResults", "CS", "1" }, { 0x0024, 0x0094, "Sensitivity Value", "SensitivityValue", "FL", "1" }, { 0x0024, 0x0095, "Retest Stimulus Seen", "RetestStimulusSeen", "CS", "1" }, { 0x0024, 0x0096, "Retest Sensitivity Value", "RetestSensitivityValue", "FL", "1" }, { 0x0024, 0x0097, "Visual Field Test Point Normals Sequence", "VisualFieldTestPointNormalsSequence", "SQ", "1" }, { 0x0024, 0x0098, "Quantified Defect", "QuantifiedDefect", "FL", "1" }, { 0x0024, 0x0100, "Age Corrected Sensitivity Deviation Probability Value", "AgeCorrectedSensitivityDeviationProbabilityValue", "FL", "1" }, { 0x0024, 0x0102, "Generalized Defect Corrected Sensitivity Deviation Flag", "GeneralizedDefectCorrectedSensitivityDeviationFlag", "CS", "1" }, { 0x0024, 0x0103, "Generalized Defect Corrected Sensitivity Deviation Value", "GeneralizedDefectCorrectedSensitivityDeviationValue", "FL", "1" }, { 0x0024, 0x0104, "Generalized Defect Corrected Sensitivity Deviation Probability Value", "GeneralizedDefectCorrectedSensitivityDeviationProbabilityValue", "FL", "1" }, { 0x0024, 0x0105, "Minimum Sensitivity Value", "MinimumSensitivityValue", "FL", "1" }, { 0x0024, 0x0106, "Blind Spot Localized", "BlindSpotLocalized", "CS", "1" }, { 0x0024, 0x0107, "Blind Spot X-Coordinate", "BlindSpotXCoordinate", "FL", "1" }, { 0x0024, 0x0108, "Blind Spot Y-Coordinate", "BlindSpotYCoordinate", "FL", "1" }, { 0x0024, 0x0110, "Visual Acuity Measurement Sequence", "VisualAcuityMeasurementSequence", "SQ", "1" }, { 0x0024, 0x0112, "Refractive Parameters Used on Patient Sequence", "RefractiveParametersUsedOnPatientSequence", "SQ", "1" }, { 0x0024, 0x0113, "Measurement Laterality", "MeasurementLaterality", "CS", "1" }, { 0x0024, 0x0114, "Ophthalmic Patient Clinical Information Left Eye Sequence", "OphthalmicPatientClinicalInformationLeftEyeSequence", "SQ", "1" }, { 0x0024, 0x0115, "Ophthalmic Patient Clinical Information Right Eye Sequence", "OphthalmicPatientClinicalInformationRightEyeSequence", "SQ", "1" }, { 0x0024, 0x0117, "Foveal Point Normative Data Flag", "FovealPointNormativeDataFlag", "CS", "1" }, { 0x0024, 0x0118, "Foveal Point Probability Value", "FovealPointProbabilityValue", "FL", "1" }, { 0x0024, 0x0120, "Screening Baseline Measured", "ScreeningBaselineMeasured", "CS", "1" }, { 0x0024, 0x0122, "Screening Baseline Measured Sequence", "ScreeningBaselineMeasuredSequence", "SQ", "1" }, { 0x0024, 0x0124, "Screening Baseline Type", "ScreeningBaselineType", "CS", "1" }, { 0x0024, 0x0126, "Screening Baseline Value", "ScreeningBaselineValue", "FL", "1" }, { 0x0024, 0x0202, "Algorithm Source", "AlgorithmSource", "LO", "1" }, { 0x0024, 0x0306, "Data Set Name", "DataSetName", "LO", "1" }, { 0x0024, 0x0307, "Data Set Version", "DataSetVersion", "LO", "1" }, { 0x0024, 0x0308, "Data Set Source", "DataSetSource", "LO", "1" }, { 0x0024, 0x0309, "Data Set Description", "DataSetDescription", "LO", "1" }, { 0x0024, 0x0317, "Visual Field Test Reliability Global Index Sequence", "VisualFieldTestReliabilityGlobalIndexSequence", "SQ", "1" }, { 0x0024, 0x0320, "Visual Field Global Results Index Sequence", "VisualFieldGlobalResultsIndexSequence", "SQ", "1" }, { 0x0024, 0x0325, "Data Observation Sequence", "DataObservationSequence", "SQ", "1" }, { 0x0024, 0x0338, "Index Normals Flag", "IndexNormalsFlag", "CS", "1" }, { 0x0024, 0x0341, "Index Probability", "IndexProbability", "FL", "1" }, { 0x0024, 0x0344, "Index Probability Sequence", "IndexProbabilitySequence", "SQ", "1" }, { 0x0028, 0x0002, "Samples per Pixel", "SamplesPerPixel", "US", "1" }, { 0x0028, 0x0003, "Samples per Pixel Used", "SamplesPerPixelUsed", "US", "1" }, { 0x0028, 0x0004, "Photometric Interpretation", "PhotometricInterpretation", "CS", "1" }, { 0x0028, 0x0005, "Image Dimensions", "ImageDimensions", "US", "1" }, { 0x0028, 0x0006, "Planar Configuration", "PlanarConfiguration", "US", "1" }, { 0x0028, 0x0008, "Number of Frames", "NumberOfFrames", "IS", "1" }, { 0x0028, 0x0009, "Frame Increment Pointer", "FrameIncrementPointer", "AT", "1-n" }, { 0x0028, 0x000a, "Frame Dimension Pointer", "FrameDimensionPointer", "AT", "1-n" }, { 0x0028, 0x0010, "Rows", "Rows", "US", "1" }, { 0x0028, 0x0011, "Columns", "Columns", "US", "1" }, { 0x0028, 0x0012, "Planes", "Planes", "US", "1" }, { 0x0028, 0x0014, "Ultrasound Color Data Present", "UltrasoundColorDataPresent", "US", "1" }, { 0x0028, 0x0030, "Pixel Spacing", "PixelSpacing", "DS", "2" }, { 0x0028, 0x0031, "Zoom Factor", "ZoomFactor", "DS", "2" }, { 0x0028, 0x0032, "Zoom Center", "ZoomCenter", "DS", "2" }, { 0x0028, 0x0034, "Pixel Aspect Ratio", "PixelAspectRatio", "IS", "2" }, { 0x0028, 0x0040, "Image Format", "ImageFormat", "CS", "1" }, { 0x0028, 0x0050, "Manipulated Image", "ManipulatedImage", "LO", "1-n" }, { 0x0028, 0x0051, "Corrected Image", "CorrectedImage", "CS", "1-n" }, { 0x0028, 0x005f, "Compression Recognition Code", "CompressionRecognitionCode", "LO", "1" }, { 0x0028, 0x0060, "Compression Code", "CompressionCode", "CS", "1" }, { 0x0028, 0x0061, "Compression Originator", "CompressionOriginator", "SH", "1" }, { 0x0028, 0x0062, "Compression Label", "CompressionLabel", "LO", "1" }, { 0x0028, 0x0063, "Compression Description", "CompressionDescription", "SH", "1" }, { 0x0028, 0x0065, "Compression Sequence", "CompressionSequence", "CS", "1-n" }, { 0x0028, 0x0066, "Compression Step Pointers", "CompressionStepPointers", "AT", "1-n" }, { 0x0028, 0x0068, "Repeat Interval", "RepeatInterval", "US", "1" }, { 0x0028, 0x0069, "Bits Grouped", "BitsGrouped", "US", "1" }, { 0x0028, 0x0070, "Perimeter Table", "PerimeterTable", "US", "1-n" }, { 0x0028, 0x0071, "Perimeter Value", "PerimeterValue", "US or SS", "1" }, { 0x0028, 0x0080, "Predictor Rows", "PredictorRows", "US", "1" }, { 0x0028, 0x0081, "Predictor Columns", "PredictorColumns", "US", "1" }, { 0x0028, 0x0082, "Predictor Constants", "PredictorConstants", "US", "1-n" }, { 0x0028, 0x0090, "Blocked Pixels", "BlockedPixels", "CS", "1" }, { 0x0028, 0x0091, "Block Rows", "BlockRows", "US", "1" }, { 0x0028, 0x0092, "Block Columns", "BlockColumns", "US", "1" }, { 0x0028, 0x0093, "Row Overlap", "RowOverlap", "US", "1" }, { 0x0028, 0x0094, "Column Overlap", "ColumnOverlap", "US", "1" }, { 0x0028, 0x0100, "Bits Allocated", "BitsAllocated", "US", "1" }, { 0x0028, 0x0101, "Bits Stored", "BitsStored", "US", "1" }, { 0x0028, 0x0102, "High Bit", "HighBit", "US", "1" }, { 0x0028, 0x0103, "Pixel Representation", "PixelRepresentation", "US", "1" }, { 0x0028, 0x0104, "Smallest Valid Pixel Value", "SmallestValidPixelValue", "US or SS", "1" }, { 0x0028, 0x0105, "Largest Valid Pixel Value", "LargestValidPixelValue", "US or SS", "1" }, { 0x0028, 0x0106, "Smallest Image Pixel Value", "SmallestImagePixelValue", "US or SS", "1" }, { 0x0028, 0x0107, "Largest Image Pixel Value", "LargestImagePixelValue", "US or SS", "1" }, { 0x0028, 0x0108, "Smallest Pixel Value in Series", "SmallestPixelValueInSeries", "US or SS", "1" }, { 0x0028, 0x0109, "Largest Pixel Value in Series", "LargestPixelValueInSeries", "US or SS", "1" }, { 0x0028, 0x0110, "Smallest Image Pixel Value in Plane", "SmallestImagePixelValueInPlane", "US or SS", "1" }, { 0x0028, 0x0111, "Largest Image Pixel Value in Plane", "LargestImagePixelValueInPlane", "US or SS", "1" }, { 0x0028, 0x0120, "Pixel Padding Value", "PixelPaddingValue", "US or SS", "1" }, { 0x0028, 0x0121, "Pixel Padding Range Limit", "PixelPaddingRangeLimit", "US or SS", "1" }, { 0x0028, 0x0122, "Float Pixel Padding Value", "FloatPixelPaddingValue", "FL", "1" }, { 0x0028, 0x0123, "Double Float Pixel Padding Value", "DoubleFloatPixelPaddingValue", "FD", "1" }, { 0x0028, 0x0124, "Float Pixel Padding Range Limit", "FloatPixelPaddingRangeLimit", "FL", "1" }, { 0x0028, 0x0125, "Double Float Pixel Padding Range Limit", "DoubleFloatPixelPaddingRangeLimit", "FD", "1" }, { 0x0028, 0x0200, "Image Location", "ImageLocation", "US", "1" }, { 0x0028, 0x0300, "Quality Control Image", "QualityControlImage", "CS", "1" }, { 0x0028, 0x0301, "Burned In Annotation", "BurnedInAnnotation", "CS", "1" }, { 0x0028, 0x0302, "Recognizable Visual Features", "RecognizableVisualFeatures", "CS", "1" }, { 0x0028, 0x0303, "Longitudinal Temporal Information Modified", "LongitudinalTemporalInformationModified", "CS", "1" }, { 0x0028, 0x0304, "Referenced Color Palette Instance UID", "ReferencedColorPaletteInstanceUID", "UI", "1" }, { 0x0028, 0x0400, "Transform Label", "TransformLabel", "LO", "1" }, { 0x0028, 0x0401, "Transform Version Number", "TransformVersionNumber", "LO", "1" }, { 0x0028, 0x0402, "Number of Transform Steps", "NumberOfTransformSteps", "US", "1" }, { 0x0028, 0x0403, "Sequence of Compressed Data", "SequenceOfCompressedData", "LO", "1-n" }, { 0x0028, 0x0404, "Details of Coefficients", "DetailsOfCoefficients", "AT", "1-n" }, { 0x0028, 0x0700, "DCT Label", "DCTLabel", "LO", "1" }, { 0x0028, 0x0701, "Data Block Description", "DataBlockDescription", "CS", "1-n" }, { 0x0028, 0x0702, "Data Block", "DataBlock", "AT", "1-n" }, { 0x0028, 0x0710, "Normalization Factor Format", "NormalizationFactorFormat", "US", "1" }, { 0x0028, 0x0720, "Zonal Map Number Format", "ZonalMapNumberFormat", "US", "1" }, { 0x0028, 0x0721, "Zonal Map Location", "ZonalMapLocation", "AT", "1-n" }, { 0x0028, 0x0722, "Zonal Map Format", "ZonalMapFormat", "US", "1" }, { 0x0028, 0x0730, "Adaptive Map Format", "AdaptiveMapFormat", "US", "1" }, { 0x0028, 0x0740, "Code Number Format", "CodeNumberFormat", "US", "1" }, { 0x0028, 0x0a02, "Pixel Spacing Calibration Type", "PixelSpacingCalibrationType", "CS", "1" }, { 0x0028, 0x0a04, "Pixel Spacing Calibration Description", "PixelSpacingCalibrationDescription", "LO", "1" }, { 0x0028, 0x1040, "Pixel Intensity Relationship", "PixelIntensityRelationship", "CS", "1" }, { 0x0028, 0x1041, "Pixel Intensity Relationship Sign", "PixelIntensityRelationshipSign", "SS", "1" }, { 0x0028, 0x1050, "Window Center", "WindowCenter", "DS", "1-n" }, { 0x0028, 0x1051, "Window Width", "WindowWidth", "DS", "1-n" }, { 0x0028, 0x1052, "Rescale Intercept", "RescaleIntercept", "DS", "1" }, { 0x0028, 0x1053, "Rescale Slope", "RescaleSlope", "DS", "1" }, { 0x0028, 0x1054, "Rescale Type", "RescaleType", "LO", "1" }, { 0x0028, 0x1055, "Window Center & Width Explanation", "WindowCenterWidthExplanation", "LO", "1-n" }, { 0x0028, 0x1056, "VOI LUT Function", "VOILUTFunction", "CS", "1" }, { 0x0028, 0x1080, "Gray Scale", "GrayScale", "CS", "1" }, { 0x0028, 0x1090, "Recommended Viewing Mode", "RecommendedViewingMode", "CS", "1" }, { 0x0028, 0x1100, "Gray Lookup Table Descriptor", "GrayLookupTableDescriptor", "US or SS", "3" }, { 0x0028, 0x1101, "Red Palette Color Lookup Table Descriptor", "RedPaletteColorLookupTableDescriptor", "US or SS", "3" }, { 0x0028, 0x1102, "Green Palette Color Lookup Table Descriptor", "GreenPaletteColorLookupTableDescriptor", "US or SS", "3" }, { 0x0028, 0x1103, "Blue Palette Color Lookup Table Descriptor", "BluePaletteColorLookupTableDescriptor", "US or SS", "3" }, { 0x0028, 0x1104, "Alpha Palette Color Lookup Table Descriptor", "AlphaPaletteColorLookupTableDescriptor", "US", "3" }, { 0x0028, 0x1111, "Large Red Palette Color Lookup Table Descriptor", "LargeRedPaletteColorLookupTableDescriptor", "US or SS", "4" }, { 0x0028, 0x1112, "Large Green Palette Color Lookup Table Descriptor", "LargeGreenPaletteColorLookupTableDescriptor", "US or SS", "4" }, { 0x0028, 0x1113, "Large Blue Palette Color Lookup Table Descriptor", "LargeBluePaletteColorLookupTableDescriptor", "US or SS", "4" }, { 0x0028, 0x1199, "Palette Color Lookup Table UID", "PaletteColorLookupTableUID", "UI", "1" }, { 0x0028, 0x1200, "Gray Lookup Table Data", "GrayLookupTableData", "US or SS or OW", "1-n or 1" }, { 0x0028, 0x1201, "Red Palette Color Lookup Table Data", "RedPaletteColorLookupTableData", "OW", "1" }, { 0x0028, 0x1202, "Green Palette Color Lookup Table Data", "GreenPaletteColorLookupTableData", "OW", "1" }, { 0x0028, 0x1203, "Blue Palette Color Lookup Table Data", "BluePaletteColorLookupTableData", "OW", "1" }, { 0x0028, 0x1204, "Alpha Palette Color Lookup Table Data", "AlphaPaletteColorLookupTableData", "OW", "1" }, { 0x0028, 0x1211, "Large Red Palette Color Lookup Table Data", "LargeRedPaletteColorLookupTableData", "OW", "1" }, { 0x0028, 0x1212, "Large Green Palette Color Lookup Table Data", "LargeGreenPaletteColorLookupTableData", "OW", "1" }, { 0x0028, 0x1213, "Large Blue Palette Color Lookup Table Data", "LargeBluePaletteColorLookupTableData", "OW", "1" }, { 0x0028, 0x1214, "Large Palette Color Lookup Table UID", "LargePaletteColorLookupTableUID", "UI", "1" }, { 0x0028, 0x1221, "Segmented Red Palette Color Lookup Table Data", "SegmentedRedPaletteColorLookupTableData", "OW", "1" }, { 0x0028, 0x1222, "Segmented Green Palette Color Lookup Table Data", "SegmentedGreenPaletteColorLookupTableData", "OW", "1" }, { 0x0028, 0x1223, "Segmented Blue Palette Color Lookup Table Data", "SegmentedBluePaletteColorLookupTableData", "OW", "1" }, { 0x0028, 0x1300, "Breast Implant Present", "BreastImplantPresent", "CS", "1" }, { 0x0028, 0x1350, "Partial View", "PartialView", "CS", "1" }, { 0x0028, 0x1351, "Partial View Description", "PartialViewDescription", "ST", "1" }, { 0x0028, 0x1352, "Partial View Code Sequence", "PartialViewCodeSequence", "SQ", "1" }, { 0x0028, 0x135a, "Spatial Locations Preserved", "SpatialLocationsPreserved", "CS", "1" }, { 0x0028, 0x1401, "Data Frame Assignment Sequence", "DataFrameAssignmentSequence", "SQ", "1" }, { 0x0028, 0x1402, "Data Path Assignment", "DataPathAssignment", "CS", "1" }, { 0x0028, 0x1403, "Bits Mapped to Color Lookup Table", "BitsMappedToColorLookupTable", "US", "1" }, { 0x0028, 0x1404, "Blending LUT 1 Sequence", "BlendingLUT1Sequence", "SQ", "1" }, { 0x0028, 0x1405, "Blending LUT 1 Transfer Function", "BlendingLUT1TransferFunction", "CS", "1" }, { 0x0028, 0x1406, "Blending Weight Constant", "BlendingWeightConstant", "FD", "1" }, { 0x0028, 0x1407, "Blending Lookup Table Descriptor", "BlendingLookupTableDescriptor", "US", "3" }, { 0x0028, 0x1408, "Blending Lookup Table Data", "BlendingLookupTableData", "OW", "1" }, { 0x0028, 0x140b, "Enhanced Palette Color Lookup Table Sequence", "EnhancedPaletteColorLookupTableSequence", "SQ", "1" }, { 0x0028, 0x140c, "Blending LUT 2 Sequence", "BlendingLUT2Sequence", "SQ", "1" }, { 0x0028, 0x140d, "Blending LUT 2 Transfer Function", "BlendingLUT2TransferFunction", "CS", "1" }, { 0x0028, 0x140e, "Data Path ID", "DataPathID", "CS", "1" }, { 0x0028, 0x140f, "RGB LUT Transfer Function", "RGBLUTTransferFunction", "CS", "1" }, { 0x0028, 0x1410, "Alpha LUT Transfer Function", "AlphaLUTTransferFunction", "CS", "1" }, { 0x0028, 0x2000, "ICC Profile", "ICCProfile", "OB", "1" }, { 0x0028, 0x2110, "Lossy Image Compression", "LossyImageCompression", "CS", "1" }, { 0x0028, 0x2112, "Lossy Image Compression Ratio", "LossyImageCompressionRatio", "DS", "1-n" }, { 0x0028, 0x2114, "Lossy Image Compression Method", "LossyImageCompressionMethod", "CS", "1-n" }, { 0x0028, 0x3000, "Modality LUT Sequence", "ModalityLUTSequence", "SQ", "1" }, { 0x0028, 0x3002, "LUT Descriptor", "LUTDescriptor", "US or SS", "3" }, { 0x0028, 0x3003, "LUT Explanation", "LUTExplanation", "LO", "1" }, { 0x0028, 0x3004, "Modality LUT Type", "ModalityLUTType", "LO", "1" }, { 0x0028, 0x3006, "LUT Data", "LUTData", "US or OW", "1-n or 1" }, { 0x0028, 0x3010, "VOI LUT Sequence", "VOILUTSequence", "SQ", "1" }, { 0x0028, 0x3110, "Softcopy VOI LUT Sequence", "SoftcopyVOILUTSequence", "SQ", "1" }, { 0x0028, 0x4000, "Image Presentation Comments", "ImagePresentationComments", "LT", "1" }, { 0x0028, 0x5000, "Bi-Plane Acquisition Sequence", "BiPlaneAcquisitionSequence", "SQ", "1" }, { 0x0028, 0x6010, "Representative Frame Number", "RepresentativeFrameNumber", "US", "1" }, { 0x0028, 0x6020, "Frame Numbers of Interest (FOI)", "FrameNumbersOfInterest", "US", "1-n" }, { 0x0028, 0x6022, "Frame of Interest Description", "FrameOfInterestDescription", "LO", "1-n" }, { 0x0028, 0x6023, "Frame of Interest Type", "FrameOfInterestType", "CS", "1-n" }, { 0x0028, 0x6030, "Mask Pointer(s)", "MaskPointers", "US", "1-n" }, { 0x0028, 0x6040, "R Wave Pointer", "RWavePointer", "US", "1-n" }, { 0x0028, 0x6100, "Mask Subtraction Sequence", "MaskSubtractionSequence", "SQ", "1" }, { 0x0028, 0x6101, "Mask Operation", "MaskOperation", "CS", "1" }, { 0x0028, 0x6102, "Applicable Frame Range", "ApplicableFrameRange", "US", "2-2n" }, { 0x0028, 0x6110, "Mask Frame Numbers", "MaskFrameNumbers", "US", "1-n" }, { 0x0028, 0x6112, "Contrast Frame Averaging", "ContrastFrameAveraging", "US", "1" }, { 0x0028, 0x6114, "Mask Sub-pixel Shift", "MaskSubPixelShift", "FL", "2" }, { 0x0028, 0x6120, "TID Offset", "TIDOffset", "SS", "1" }, { 0x0028, 0x6190, "Mask Operation Explanation", "MaskOperationExplanation", "ST", "1" }, { 0x0028, 0x7000, "Equipment Administrator Sequence", "EquipmentAdministratorSequence", "SQ", "1" }, { 0x0028, 0x7001, "Number of Display Subsystems", "NumberOfDisplaySubsystems", "US", "1" }, { 0x0028, 0x7002, "Current Configuration ID", "CurrentConfigurationID", "US", "1" }, { 0x0028, 0x7003, "Display Subsystem ID", "DisplaySubsystemID", "US", "1" }, { 0x0028, 0x7004, "Display Subsystem Name", "DisplaySubsystemName", "SH", "1" }, { 0x0028, 0x7005, "Display Subsystem Description", "DisplaySubsystemDescription", "LO", "1" }, { 0x0028, 0x7006, "System Status", "SystemStatus", "CS", "1" }, { 0x0028, 0x7007, "System Status Comment", "SystemStatusComment", "LO", "1" }, { 0x0028, 0x7008, "Target Luminance Characteristics Sequence", "TargetLuminanceCharacteristicsSequence", "SQ", "1" }, { 0x0028, 0x7009, "Luminance Characteristics ID", "LuminanceCharacteristicsID", "US", "1" }, { 0x0028, 0x700a, "Display Subsystem Configuration Sequence", "DisplaySubsystemConfigurationSequence", "SQ", "1" }, { 0x0028, 0x700b, "Configuration ID", "ConfigurationID", "US", "1" }, { 0x0028, 0x700c, "Configuration Name", "ConfigurationName", "SH", "1" }, { 0x0028, 0x700d, "Configuration Description", "ConfigurationDescription", "LO", "1" }, { 0x0028, 0x700e, "Referenced Target Luminance Characteristics ID", "ReferencedTargetLuminanceCharacteristicsID", "US", "1" }, { 0x0028, 0x700f, "QA Results Sequence", "QAResultsSequence", "SQ", "1" }, { 0x0028, 0x7010, "Display Subsystem QA Results Sequence", "DisplaySubsystemQAResultsSequence", "SQ", "1" }, { 0x0028, 0x7011, "Configuration QA Results Sequence", "ConfigurationQAResultsSequence", "SQ", "1" }, { 0x0028, 0x7012, "Measurement Equipment Sequence", "MeasurementEquipmentSequence", "SQ", "1" }, { 0x0028, 0x7013, "Measurement Functions", "MeasurementFunctions", "CS", "1-n" }, { 0x0028, 0x7014, "Measurement Equipment Type", "MeasurementEquipmentType", "CS", "1" }, { 0x0028, 0x7015, "Visual Evaluation Result Sequence", "VisualEvaluationResultSequence", "SQ", "1" }, { 0x0028, 0x7016, "Display Calibration Result Sequence", "DisplayCalibrationResultSequence", "SQ", "1" }, { 0x0028, 0x7017, "DDL Value", "DDLValue", "US", "1" }, { 0x0028, 0x7018, "CIExy White Point", "CIExyWhitePoint", "FL", "2" }, { 0x0028, 0x7019, "Display Function Type", "DisplayFunctionType", "CS", "1" }, { 0x0028, 0x701a, "Gamma Value", "GammaValue", "FL", "1" }, { 0x0028, 0x701b, "Number of Luminance Points", "NumberOfLuminancePoints", "US", "1" }, { 0x0028, 0x701c, "Luminance Response Sequence", "LuminanceResponseSequence", "SQ", "1" }, { 0x0028, 0x701d, "Target Minimum Luminance", "TargetMinimumLuminance", "FL", "1" }, { 0x0028, 0x701e, "Target Maximum Luminance", "TargetMaximumLuminance", "FL", "1" }, { 0x0028, 0x701f, "Luminance Value", "LuminanceValue", "FL", "1" }, { 0x0028, 0x7020, "Luminance Response Description", "LuminanceResponseDescription", "LO", "1" }, { 0x0028, 0x7021, "White Point Flag", "WhitePointFlag", "CS", "1" }, { 0x0028, 0x7022, "Display Device Type Code Sequence", "DisplayDeviceTypeCodeSequence", "SQ", "1" }, { 0x0028, 0x7023, "Display Subsystem Sequence", "DisplaySubsystemSequence", "SQ", "1" }, { 0x0028, 0x7024, "Luminance Result Sequence", "LuminanceResultSequence", "SQ", "1" }, { 0x0028, 0x7025, "Ambient Light Value Source", "AmbientLightValueSource", "CS", "1" }, { 0x0028, 0x7026, "Measured Characteristics", "MeasuredCharacteristics", "CS", "1-n" }, { 0x0028, 0x7027, "Luminance Uniformity Result Sequence", "LuminanceUniformityResultSequence", "SQ", "1" }, { 0x0028, 0x7028, "Visual Evaluation Test Sequence", "VisualEvaluationTestSequence", "SQ", "1" }, { 0x0028, 0x7029, "Test Result", "TestResult", "CS", "1" }, { 0x0028, 0x702a, "Test Result Comment", "TestResultComment", "LO", "1" }, { 0x0028, 0x702b, "Test Image Validation", "TestImageValidation", "CS", "1" }, { 0x0028, 0x702c, "Test Pattern Code Sequence", "TestPatternCodeSequence", "SQ", "1" }, { 0x0028, 0x702d, "Measurement Pattern Code Sequence", "MeasurementPatternCodeSequence", "SQ", "1" }, { 0x0028, 0x702e, "Visual Evaluation Method Code Sequence", "VisualEvaluationMethodCodeSequence", "SQ", "1" }, { 0x0028, 0x7fe0, "Pixel Data Provider URL", "PixelDataProviderURL", "UR", "1" }, { 0x0028, 0x9001, "Data Point Rows", "DataPointRows", "UL", "1" }, { 0x0028, 0x9002, "Data Point Columns", "DataPointColumns", "UL", "1" }, { 0x0028, 0x9003, "Signal Domain Columns", "SignalDomainColumns", "CS", "1" }, { 0x0028, 0x9099, "Largest Monochrome Pixel Value", "LargestMonochromePixelValue", "US", "1" }, { 0x0028, 0x9108, "Data Representation", "DataRepresentation", "CS", "1" }, { 0x0028, 0x9110, "Pixel Measures Sequence", "PixelMeasuresSequence", "SQ", "1" }, { 0x0028, 0x9132, "Frame VOI LUT Sequence", "FrameVOILUTSequence", "SQ", "1" }, { 0x0028, 0x9145, "Pixel Value Transformation Sequence", "PixelValueTransformationSequence", "SQ", "1" }, { 0x0028, 0x9235, "Signal Domain Rows", "SignalDomainRows", "CS", "1" }, { 0x0028, 0x9411, "Display Filter Percentage", "DisplayFilterPercentage", "FL", "1" }, { 0x0028, 0x9415, "Frame Pixel Shift Sequence", "FramePixelShiftSequence", "SQ", "1" }, { 0x0028, 0x9416, "Subtraction Item ID", "SubtractionItemID", "US", "1" }, { 0x0028, 0x9422, "Pixel Intensity Relationship LUT Sequence", "PixelIntensityRelationshipLUTSequence", "SQ", "1" }, { 0x0028, 0x9443, "Frame Pixel Data Properties Sequence", "FramePixelDataPropertiesSequence", "SQ", "1" }, { 0x0028, 0x9444, "Geometrical Properties", "GeometricalProperties", "CS", "1" }, { 0x0028, 0x9445, "Geometric Maximum Distortion", "GeometricMaximumDistortion", "FL", "1" }, { 0x0028, 0x9446, "Image Processing Applied", "ImageProcessingApplied", "CS", "1-n" }, { 0x0028, 0x9454, "Mask Selection Mode", "MaskSelectionMode", "CS", "1" }, { 0x0028, 0x9474, "LUT Function", "LUTFunction", "CS", "1" }, { 0x0028, 0x9478, "Mask Visibility Percentage", "MaskVisibilityPercentage", "FL", "1" }, { 0x0028, 0x9501, "Pixel Shift Sequence", "PixelShiftSequence", "SQ", "1" }, { 0x0028, 0x9502, "Region Pixel Shift Sequence", "RegionPixelShiftSequence", "SQ", "1" }, { 0x0028, 0x9503, "Vertices of the Region", "VerticesOfTheRegion", "SS", "2-2n" }, { 0x0028, 0x9505, "Multi-frame Presentation Sequence", "MultiFramePresentationSequence", "SQ", "1" }, { 0x0028, 0x9506, "Pixel Shift Frame Range", "PixelShiftFrameRange", "US", "2-2n" }, { 0x0028, 0x9507, "LUT Frame Range", "LUTFrameRange", "US", "2-2n" }, { 0x0028, 0x9520, "Image to Equipment Mapping Matrix", "ImageToEquipmentMappingMatrix", "DS", "16" }, { 0x0028, 0x9537, "Equipment Coordinate System Identification", "EquipmentCoordinateSystemIdentification", "CS", "1" }, { 0x0032, 0x000a, "Study Status ID", "StudyStatusID", "CS", "1" }, { 0x0032, 0x000c, "Study Priority ID", "StudyPriorityID", "CS", "1" }, { 0x0032, 0x0012, "Study ID Issuer", "StudyIDIssuer", "LO", "1" }, { 0x0032, 0x0032, "Study Verified Date", "StudyVerifiedDate", "DA", "1" }, { 0x0032, 0x0033, "Study Verified Time", "StudyVerifiedTime", "TM", "1" }, { 0x0032, 0x0034, "Study Read Date", "StudyReadDate", "DA", "1" }, { 0x0032, 0x0035, "Study Read Time", "StudyReadTime", "TM", "1" }, { 0x0032, 0x1000, "Scheduled Study Start Date", "ScheduledStudyStartDate", "DA", "1" }, { 0x0032, 0x1001, "Scheduled Study Start Time", "ScheduledStudyStartTime", "TM", "1" }, { 0x0032, 0x1010, "Scheduled Study Stop Date", "ScheduledStudyStopDate", "DA", "1" }, { 0x0032, 0x1011, "Scheduled Study Stop Time", "ScheduledStudyStopTime", "TM", "1" }, { 0x0032, 0x1020, "Scheduled Study Location", "ScheduledStudyLocation", "LO", "1" }, { 0x0032, 0x1021, "Scheduled Study Location AE Title", "ScheduledStudyLocationAETitle", "AE", "1-n" }, { 0x0032, 0x1030, "Reason for Study", "ReasonForStudy", "LO", "1" }, { 0x0032, 0x1031, "Requesting Physician Identification Sequence", "RequestingPhysicianIdentificationSequence", "SQ", "1" }, { 0x0032, 0x1032, "Requesting Physician", "RequestingPhysician", "PN", "1" }, { 0x0032, 0x1033, "Requesting Service", "RequestingService", "LO", "1" }, { 0x0032, 0x1034, "Requesting Service Code Sequence", "RequestingServiceCodeSequence", "SQ", "1" }, { 0x0032, 0x1040, "Study Arrival Date", "StudyArrivalDate", "DA", "1" }, { 0x0032, 0x1041, "Study Arrival Time", "StudyArrivalTime", "TM", "1" }, { 0x0032, 0x1050, "Study Completion Date", "StudyCompletionDate", "DA", "1" }, { 0x0032, 0x1051, "Study Completion Time", "StudyCompletionTime", "TM", "1" }, { 0x0032, 0x1055, "Study Component Status ID", "StudyComponentStatusID", "CS", "1" }, { 0x0032, 0x1060, "Requested Procedure Description", "RequestedProcedureDescription", "LO", "1" }, { 0x0032, 0x1064, "Requested Procedure Code Sequence", "RequestedProcedureCodeSequence", "SQ", "1" }, { 0x0032, 0x1070, "Requested Contrast Agent", "RequestedContrastAgent", "LO", "1" }, { 0x0032, 0x4000, "Study Comments", "StudyComments", "LT", "1" }, { 0x0038, 0x0004, "Referenced Patient Alias Sequence", "ReferencedPatientAliasSequence", "SQ", "1" }, { 0x0038, 0x0008, "Visit Status ID", "VisitStatusID", "CS", "1" }, { 0x0038, 0x0010, "Admission ID", "AdmissionID", "LO", "1" }, { 0x0038, 0x0011, "Issuer of Admission ID", "IssuerOfAdmissionID", "LO", "1" }, { 0x0038, 0x0014, "Issuer of Admission ID Sequence", "IssuerOfAdmissionIDSequence", "SQ", "1" }, { 0x0038, 0x0016, "Route of Admissions", "RouteOfAdmissions", "LO", "1" }, { 0x0038, 0x001a, "Scheduled Admission Date", "ScheduledAdmissionDate", "DA", "1" }, { 0x0038, 0x001b, "Scheduled Admission Time", "ScheduledAdmissionTime", "TM", "1" }, { 0x0038, 0x001c, "Scheduled Discharge Date", "ScheduledDischargeDate", "DA", "1" }, { 0x0038, 0x001d, "Scheduled Discharge Time", "ScheduledDischargeTime", "TM", "1" }, { 0x0038, 0x001e, "Scheduled Patient Institution Residence", "ScheduledPatientInstitutionResidence", "LO", "1" }, { 0x0038, 0x0020, "Admitting Date", "AdmittingDate", "DA", "1" }, { 0x0038, 0x0021, "Admitting Time", "AdmittingTime", "TM", "1" }, { 0x0038, 0x0030, "Discharge Date", "DischargeDate", "DA", "1" }, { 0x0038, 0x0032, "Discharge Time", "DischargeTime", "TM", "1" }, { 0x0038, 0x0040, "Discharge Diagnosis Description", "DischargeDiagnosisDescription", "LO", "1" }, { 0x0038, 0x0044, "Discharge Diagnosis Code Sequence", "DischargeDiagnosisCodeSequence", "SQ", "1" }, { 0x0038, 0x0050, "Special Needs", "SpecialNeeds", "LO", "1" }, { 0x0038, 0x0060, "Service Episode ID", "ServiceEpisodeID", "LO", "1" }, { 0x0038, 0x0061, "Issuer of Service Episode ID", "IssuerOfServiceEpisodeID", "LO", "1" }, { 0x0038, 0x0062, "Service Episode Description", "ServiceEpisodeDescription", "LO", "1" }, { 0x0038, 0x0064, "Issuer of Service Episode ID Sequence", "IssuerOfServiceEpisodeIDSequence", "SQ", "1" }, { 0x0038, 0x0100, "Pertinent Documents Sequence", "PertinentDocumentsSequence", "SQ", "1" }, { 0x0038, 0x0101, "Pertinent Resources Sequence", "PertinentResourcesSequence", "SQ", "1" }, { 0x0038, 0x0102, "Resource Description", "ResourceDescription", "LO", "1" }, { 0x0038, 0x0300, "Current Patient Location", "CurrentPatientLocation", "LO", "1" }, { 0x0038, 0x0400, "Patient's Institution Residence", "PatientInstitutionResidence", "LO", "1" }, { 0x0038, 0x0500, "Patient State", "PatientState", "LO", "1" }, { 0x0038, 0x0502, "Patient Clinical Trial Participation Sequence", "PatientClinicalTrialParticipationSequence", "SQ", "1" }, { 0x0038, 0x4000, "Visit Comments", "VisitComments", "LT", "1" }, { 0x003a, 0x0004, "Waveform Originality", "WaveformOriginality", "CS", "1" }, { 0x003a, 0x0005, "Number of Waveform Channels", "NumberOfWaveformChannels", "US", "1" }, { 0x003a, 0x0010, "Number of Waveform Samples", "NumberOfWaveformSamples", "UL", "1" }, { 0x003a, 0x001a, "Sampling Frequency", "SamplingFrequency", "DS", "1" }, { 0x003a, 0x0020, "Multiplex Group Label", "MultiplexGroupLabel", "SH", "1" }, { 0x003a, 0x0200, "Channel Definition Sequence", "ChannelDefinitionSequence", "SQ", "1" }, { 0x003a, 0x0202, "Waveform Channel Number", "WaveformChannelNumber", "IS", "1" }, { 0x003a, 0x0203, "Channel Label", "ChannelLabel", "SH", "1" }, { 0x003a, 0x0205, "Channel Status", "ChannelStatus", "CS", "1-n" }, { 0x003a, 0x0208, "Channel Source Sequence", "ChannelSourceSequence", "SQ", "1" }, { 0x003a, 0x0209, "Channel Source Modifiers Sequence", "ChannelSourceModifiersSequence", "SQ", "1" }, { 0x003a, 0x020a, "Source Waveform Sequence", "SourceWaveformSequence", "SQ", "1" }, { 0x003a, 0x020c, "Channel Derivation Description", "ChannelDerivationDescription", "LO", "1" }, { 0x003a, 0x0210, "Channel Sensitivity", "ChannelSensitivity", "DS", "1" }, { 0x003a, 0x0211, "Channel Sensitivity Units Sequence", "ChannelSensitivityUnitsSequence", "SQ", "1" }, { 0x003a, 0x0212, "Channel Sensitivity Correction Factor", "ChannelSensitivityCorrectionFactor", "DS", "1" }, { 0x003a, 0x0213, "Channel Baseline", "ChannelBaseline", "DS", "1" }, { 0x003a, 0x0214, "Channel Time Skew", "ChannelTimeSkew", "DS", "1" }, { 0x003a, 0x0215, "Channel Sample Skew", "ChannelSampleSkew", "DS", "1" }, { 0x003a, 0x0218, "Channel Offset", "ChannelOffset", "DS", "1" }, { 0x003a, 0x021a, "Waveform Bits Stored", "WaveformBitsStored", "US", "1" }, { 0x003a, 0x0220, "Filter Low Frequency", "FilterLowFrequency", "DS", "1" }, { 0x003a, 0x0221, "Filter High Frequency", "FilterHighFrequency", "DS", "1" }, { 0x003a, 0x0222, "Notch Filter Frequency", "NotchFilterFrequency", "DS", "1" }, { 0x003a, 0x0223, "Notch Filter Bandwidth", "NotchFilterBandwidth", "DS", "1" }, { 0x003a, 0x0230, "Waveform Data Display Scale", "WaveformDataDisplayScale", "FL", "1" }, { 0x003a, 0x0231, "Waveform Display Background CIELab Value", "WaveformDisplayBackgroundCIELabValue", "US", "3" }, { 0x003a, 0x0240, "Waveform Presentation Group Sequence", "WaveformPresentationGroupSequence", "SQ", "1" }, { 0x003a, 0x0241, "Presentation Group Number", "PresentationGroupNumber", "US", "1" }, { 0x003a, 0x0242, "Channel Display Sequence", "ChannelDisplaySequence", "SQ", "1" }, { 0x003a, 0x0244, "Channel Recommended Display CIELab Value", "ChannelRecommendedDisplayCIELabValue", "US", "3" }, { 0x003a, 0x0245, "Channel Position", "ChannelPosition", "FL", "1" }, { 0x003a, 0x0246, "Display Shading Flag", "DisplayShadingFlag", "CS", "1" }, { 0x003a, 0x0247, "Fractional Channel Display Scale", "FractionalChannelDisplayScale", "FL", "1" }, { 0x003a, 0x0248, "Absolute Channel Display Scale", "AbsoluteChannelDisplayScale", "FL", "1" }, { 0x003a, 0x0300, "Multiplexed Audio Channels Description Code Sequence", "MultiplexedAudioChannelsDescriptionCodeSequence", "SQ", "1" }, { 0x003a, 0x0301, "Channel Identification Code", "ChannelIdentificationCode", "IS", "1" }, { 0x003a, 0x0302, "Channel Mode", "ChannelMode", "CS", "1" }, { 0x0040, 0x0001, "Scheduled Station AE Title", "ScheduledStationAETitle", "AE", "1-n" }, { 0x0040, 0x0002, "Scheduled Procedure Step Start Date", "ScheduledProcedureStepStartDate", "DA", "1" }, { 0x0040, 0x0003, "Scheduled Procedure Step Start Time", "ScheduledProcedureStepStartTime", "TM", "1" }, { 0x0040, 0x0004, "Scheduled Procedure Step End Date", "ScheduledProcedureStepEndDate", "DA", "1" }, { 0x0040, 0x0005, "Scheduled Procedure Step End Time", "ScheduledProcedureStepEndTime", "TM", "1" }, { 0x0040, 0x0006, "Scheduled Performing Physician's Name", "ScheduledPerformingPhysicianName", "PN", "1" }, { 0x0040, 0x0007, "Scheduled Procedure Step Description", "ScheduledProcedureStepDescription", "LO", "1" }, { 0x0040, 0x0008, "Scheduled Protocol Code Sequence", "ScheduledProtocolCodeSequence", "SQ", "1" }, { 0x0040, 0x0009, "Scheduled Procedure Step ID", "ScheduledProcedureStepID", "SH", "1" }, { 0x0040, 0x000a, "Stage Code Sequence", "StageCodeSequence", "SQ", "1" }, { 0x0040, 0x000b, "Scheduled Performing Physician Identification Sequence", "ScheduledPerformingPhysicianIdentificationSequence", "SQ", "1" }, { 0x0040, 0x0010, "Scheduled Station Name", "ScheduledStationName", "SH", "1-n" }, { 0x0040, 0x0011, "Scheduled Procedure Step Location", "ScheduledProcedureStepLocation", "SH", "1" }, { 0x0040, 0x0012, "Pre-Medication", "PreMedication", "LO", "1" }, { 0x0040, 0x0020, "Scheduled Procedure Step Status", "ScheduledProcedureStepStatus", "CS", "1" }, { 0x0040, 0x0026, "Order Placer Identifier Sequence", "OrderPlacerIdentifierSequence", "SQ", "1" }, { 0x0040, 0x0027, "Order Filler Identifier Sequence", "OrderFillerIdentifierSequence", "SQ", "1" }, { 0x0040, 0x0031, "Local Namespace Entity ID", "LocalNamespaceEntityID", "UT", "1" }, { 0x0040, 0x0032, "Universal Entity ID", "UniversalEntityID", "UT", "1" }, { 0x0040, 0x0033, "Universal Entity ID Type", "UniversalEntityIDType", "CS", "1" }, { 0x0040, 0x0035, "Identifier Type Code", "IdentifierTypeCode", "CS", "1" }, { 0x0040, 0x0036, "Assigning Facility Sequence", "AssigningFacilitySequence", "SQ", "1" }, { 0x0040, 0x0039, "Assigning Jurisdiction Code Sequence", "AssigningJurisdictionCodeSequence", "SQ", "1" }, { 0x0040, 0x003a, "Assigning Agency or Department Code Sequence", "AssigningAgencyOrDepartmentCodeSequence", "SQ", "1" }, { 0x0040, 0x0100, "Scheduled Procedure Step Sequence", "ScheduledProcedureStepSequence", "SQ", "1" }, { 0x0040, 0x0220, "Referenced Non-Image Composite SOP Instance Sequence", "ReferencedNonImageCompositeSOPInstanceSequence", "SQ", "1" }, { 0x0040, 0x0241, "Performed Station AE Title", "PerformedStationAETitle", "AE", "1" }, { 0x0040, 0x0242, "Performed Station Name", "PerformedStationName", "SH", "1" }, { 0x0040, 0x0243, "Performed Location", "PerformedLocation", "SH", "1" }, { 0x0040, 0x0244, "Performed Procedure Step Start Date", "PerformedProcedureStepStartDate", "DA", "1" }, { 0x0040, 0x0245, "Performed Procedure Step Start Time", "PerformedProcedureStepStartTime", "TM", "1" }, { 0x0040, 0x0250, "Performed Procedure Step End Date", "PerformedProcedureStepEndDate", "DA", "1" }, { 0x0040, 0x0251, "Performed Procedure Step End Time", "PerformedProcedureStepEndTime", "TM", "1" }, { 0x0040, 0x0252, "Performed Procedure Step Status", "PerformedProcedureStepStatus", "CS", "1" }, { 0x0040, 0x0253, "Performed Procedure Step ID", "PerformedProcedureStepID", "SH", "1" }, { 0x0040, 0x0254, "Performed Procedure Step Description", "PerformedProcedureStepDescription", "LO", "1" }, { 0x0040, 0x0255, "Performed Procedure Type Description", "PerformedProcedureTypeDescription", "LO", "1" }, { 0x0040, 0x0260, "Performed Protocol Code Sequence", "PerformedProtocolCodeSequence", "SQ", "1" }, { 0x0040, 0x0261, "Performed Protocol Type", "PerformedProtocolType", "CS", "1" }, { 0x0040, 0x0270, "Scheduled Step Attributes Sequence", "ScheduledStepAttributesSequence", "SQ", "1" }, { 0x0040, 0x0275, "Request Attributes Sequence", "RequestAttributesSequence", "SQ", "1" }, { 0x0040, 0x0280, "Comments on the Performed Procedure Step", "CommentsOnThePerformedProcedureStep", "ST", "1" }, { 0x0040, 0x0281, "Performed Procedure Step Discontinuation Reason Code Sequence", "PerformedProcedureStepDiscontinuationReasonCodeSequence", "SQ", "1" }, { 0x0040, 0x0293, "Quantity Sequence", "QuantitySequence", "SQ", "1" }, { 0x0040, 0x0294, "Quantity", "Quantity", "DS", "1" }, { 0x0040, 0x0295, "Measuring Units Sequence", "MeasuringUnitsSequence", "SQ", "1" }, { 0x0040, 0x0296, "Billing Item Sequence", "BillingItemSequence", "SQ", "1" }, { 0x0040, 0x0300, "Total Time of Fluoroscopy", "TotalTimeOfFluoroscopy", "US", "1" }, { 0x0040, 0x0301, "Total Number of Exposures", "TotalNumberOfExposures", "US", "1" }, { 0x0040, 0x0302, "Entrance Dose", "EntranceDose", "US", "1" }, { 0x0040, 0x0303, "Exposed Area", "ExposedArea", "US", "1-2" }, { 0x0040, 0x0306, "Distance Source to Entrance", "DistanceSourceToEntrance", "DS", "1" }, { 0x0040, 0x0307, "Distance Source to Support", "DistanceSourceToSupport", "DS", "1" }, { 0x0040, 0x030e, "Exposure Dose Sequence", "ExposureDoseSequence", "SQ", "1" }, { 0x0040, 0x0310, "Comments on Radiation Dose", "CommentsOnRadiationDose", "ST", "1" }, { 0x0040, 0x0312, "X-Ray Output", "XRayOutput", "DS", "1" }, { 0x0040, 0x0314, "Half Value Layer", "HalfValueLayer", "DS", "1" }, { 0x0040, 0x0316, "Organ Dose", "OrganDose", "DS", "1" }, { 0x0040, 0x0318, "Organ Exposed", "OrganExposed", "CS", "1" }, { 0x0040, 0x0320, "Billing Procedure Step Sequence", "BillingProcedureStepSequence", "SQ", "1" }, { 0x0040, 0x0321, "Film Consumption Sequence", "FilmConsumptionSequence", "SQ", "1" }, { 0x0040, 0x0324, "Billing Supplies and Devices Sequence", "BillingSuppliesAndDevicesSequence", "SQ", "1" }, { 0x0040, 0x0330, "Referenced Procedure Step Sequence", "ReferencedProcedureStepSequence", "SQ", "1" }, { 0x0040, 0x0340, "Performed Series Sequence", "PerformedSeriesSequence", "SQ", "1" }, { 0x0040, 0x0400, "Comments on the Scheduled Procedure Step", "CommentsOnTheScheduledProcedureStep", "LT", "1" }, { 0x0040, 0x0440, "Protocol Context Sequence", "ProtocolContextSequence", "SQ", "1" }, { 0x0040, 0x0441, "Content Item Modifier Sequence", "ContentItemModifierSequence", "SQ", "1" }, { 0x0040, 0x0500, "Scheduled Specimen Sequence", "ScheduledSpecimenSequence", "SQ", "1" }, { 0x0040, 0x050a, "Specimen Accession Number", "SpecimenAccessionNumber", "LO", "1" }, { 0x0040, 0x0512, "Container Identifier", "ContainerIdentifier", "LO", "1" }, { 0x0040, 0x0513, "Issuer of the Container Identifier Sequence", "IssuerOfTheContainerIdentifierSequence", "SQ", "1" }, { 0x0040, 0x0515, "Alternate Container Identifier Sequence", "AlternateContainerIdentifierSequence", "SQ", "1" }, { 0x0040, 0x0518, "Container Type Code Sequence", "ContainerTypeCodeSequence", "SQ", "1" }, { 0x0040, 0x051a, "Container Description", "ContainerDescription", "LO", "1" }, { 0x0040, 0x0520, "Container Component Sequence", "ContainerComponentSequence", "SQ", "1" }, { 0x0040, 0x0550, "Specimen Sequence", "SpecimenSequence", "SQ", "1" }, { 0x0040, 0x0551, "Specimen Identifier", "SpecimenIdentifier", "LO", "1" }, { 0x0040, 0x0552, "Specimen Description Sequence (Trial)", "SpecimenDescriptionSequenceTrial", "SQ", "1" }, { 0x0040, 0x0553, "Specimen Description (Trial)", "SpecimenDescriptionTrial", "ST", "1" }, { 0x0040, 0x0554, "Specimen UID", "SpecimenUID", "UI", "1" }, { 0x0040, 0x0555, "Acquisition Context Sequence", "AcquisitionContextSequence", "SQ", "1" }, { 0x0040, 0x0556, "Acquisition Context Description", "AcquisitionContextDescription", "ST", "1" }, { 0x0040, 0x059a, "Specimen Type Code Sequence", "SpecimenTypeCodeSequence", "SQ", "1" }, { 0x0040, 0x0560, "Specimen Description Sequence", "SpecimenDescriptionSequence", "SQ", "1" }, { 0x0040, 0x0562, "Issuer of the Specimen Identifier Sequence", "IssuerOfTheSpecimenIdentifierSequence", "SQ", "1" }, { 0x0040, 0x0600, "Specimen Short Description", "SpecimenShortDescription", "LO", "1" }, { 0x0040, 0x0602, "Specimen Detailed Description", "SpecimenDetailedDescription", "UT", "1" }, { 0x0040, 0x0610, "Specimen Preparation Sequence", "SpecimenPreparationSequence", "SQ", "1" }, { 0x0040, 0x0612, "Specimen Preparation Step Content Item Sequence", "SpecimenPreparationStepContentItemSequence", "SQ", "1" }, { 0x0040, 0x0620, "Specimen Localization Content Item Sequence", "SpecimenLocalizationContentItemSequence", "SQ", "1" }, { 0x0040, 0x06fa, "Slide Identifier", "SlideIdentifier", "LO", "1" }, { 0x0040, 0x071a, "Image Center Point Coordinates Sequence", "ImageCenterPointCoordinatesSequence", "SQ", "1" }, { 0x0040, 0x072a, "X Offset in Slide Coordinate System", "XOffsetInSlideCoordinateSystem", "DS", "1" }, { 0x0040, 0x073a, "Y Offset in Slide Coordinate System", "YOffsetInSlideCoordinateSystem", "DS", "1" }, { 0x0040, 0x074a, "Z Offset in Slide Coordinate System", "ZOffsetInSlideCoordinateSystem", "DS", "1" }, { 0x0040, 0x08d8, "Pixel Spacing Sequence", "PixelSpacingSequence", "SQ", "1" }, { 0x0040, 0x08da, "Coordinate System Axis Code Sequence", "CoordinateSystemAxisCodeSequence", "SQ", "1" }, { 0x0040, 0x08ea, "Measurement Units Code Sequence", "MeasurementUnitsCodeSequence", "SQ", "1" }, { 0x0040, 0x09f8, "Vital Stain Code Sequence (Trial)", "VitalStainCodeSequenceTrial", "SQ", "1" }, { 0x0040, 0x1001, "Requested Procedure ID", "RequestedProcedureID", "SH", "1" }, { 0x0040, 0x1002, "Reason for the Requested Procedure", "ReasonForTheRequestedProcedure", "LO", "1" }, { 0x0040, 0x1003, "Requested Procedure Priority", "RequestedProcedurePriority", "SH", "1" }, { 0x0040, 0x1004, "Patient Transport Arrangements", "PatientTransportArrangements", "LO", "1" }, { 0x0040, 0x1005, "Requested Procedure Location", "RequestedProcedureLocation", "LO", "1" }, { 0x0040, 0x1006, "Placer Order Number / Procedure", "PlacerOrderNumberProcedure", "SH", "1" }, { 0x0040, 0x1007, "Filler Order Number / Procedure", "FillerOrderNumberProcedure", "SH", "1" }, { 0x0040, 0x1008, "Confidentiality Code", "ConfidentialityCode", "LO", "1" }, { 0x0040, 0x1009, "Reporting Priority", "ReportingPriority", "SH", "1" }, { 0x0040, 0x100a, "Reason for Requested Procedure Code Sequence", "ReasonForRequestedProcedureCodeSequence", "SQ", "1" }, { 0x0040, 0x1010, "Names of Intended Recipients of Results", "NamesOfIntendedRecipientsOfResults", "PN", "1-n" }, { 0x0040, 0x1011, "Intended Recipients of Results Identification Sequence", "IntendedRecipientsOfResultsIdentificationSequence", "SQ", "1" }, { 0x0040, 0x1012, "Reason For Performed Procedure Code Sequence", "ReasonForPerformedProcedureCodeSequence", "SQ", "1" }, { 0x0040, 0x1060, "Requested Procedure Description (Trial)", "RequestedProcedureDescriptionTrial", "LO", "1" }, { 0x0040, 0x1101, "Person Identification Code Sequence", "PersonIdentificationCodeSequence", "SQ", "1" }, { 0x0040, 0x1102, "Person's Address", "PersonAddress", "ST", "1" }, { 0x0040, 0x1103, "Person's Telephone Numbers", "PersonTelephoneNumbers", "LO", "1-n" }, { 0x0040, 0x1104, "Person's Telecom Information", "PersonTelecomInformation", "LT", "1" }, { 0x0040, 0x1400, "Requested Procedure Comments", "RequestedProcedureComments", "LT", "1" }, { 0x0040, 0x2001, "Reason for the Imaging Service Request", "ReasonForTheImagingServiceRequest", "LO", "1" }, { 0x0040, 0x2004, "Issue Date of Imaging Service Request", "IssueDateOfImagingServiceRequest", "DA", "1" }, { 0x0040, 0x2005, "Issue Time of Imaging Service Request", "IssueTimeOfImagingServiceRequest", "TM", "1" }, { 0x0040, 0x2006, "Placer Order Number / Imaging Service Request (Retired)", "PlacerOrderNumberImagingServiceRequestRetired", "SH", "1" }, { 0x0040, 0x2007, "Filler Order Number / Imaging Service Request (Retired)", "FillerOrderNumberImagingServiceRequestRetired", "SH", "1" }, { 0x0040, 0x2008, "Order Entered By", "OrderEnteredBy", "PN", "1" }, { 0x0040, 0x2009, "Order Enterer's Location", "OrderEntererLocation", "SH", "1" }, { 0x0040, 0x2010, "Order Callback Phone Number", "OrderCallbackPhoneNumber", "SH", "1" }, { 0x0040, 0x2011, "Order Callback Telecom Information", "OrderCallbackTelecomInformation", "LT", "1" }, { 0x0040, 0x2016, "Placer Order Number / Imaging Service Request", "PlacerOrderNumberImagingServiceRequest", "LO", "1" }, { 0x0040, 0x2017, "Filler Order Number / Imaging Service Request", "FillerOrderNumberImagingServiceRequest", "LO", "1" }, { 0x0040, 0x2400, "Imaging Service Request Comments", "ImagingServiceRequestComments", "LT", "1" }, { 0x0040, 0x3001, "Confidentiality Constraint on Patient Data Description", "ConfidentialityConstraintOnPatientDataDescription", "LO", "1" }, { 0x0040, 0x4001, "General Purpose Scheduled Procedure Step Status", "GeneralPurposeScheduledProcedureStepStatus", "CS", "1" }, { 0x0040, 0x4002, "General Purpose Performed Procedure Step Status", "GeneralPurposePerformedProcedureStepStatus", "CS", "1" }, { 0x0040, 0x4003, "General Purpose Scheduled Procedure Step Priority", "GeneralPurposeScheduledProcedureStepPriority", "CS", "1" }, { 0x0040, 0x4004, "Scheduled Processing Applications Code Sequence", "ScheduledProcessingApplicationsCodeSequence", "SQ", "1" }, { 0x0040, 0x4005, "Scheduled Procedure Step Start DateTime", "ScheduledProcedureStepStartDateTime", "DT", "1" }, { 0x0040, 0x4006, "Multiple Copies Flag", "MultipleCopiesFlag", "CS", "1" }, { 0x0040, 0x4007, "Performed Processing Applications Code Sequence", "PerformedProcessingApplicationsCodeSequence", "SQ", "1" }, { 0x0040, 0x4009, "Human Performer Code Sequence", "HumanPerformerCodeSequence", "SQ", "1" }, { 0x0040, 0x4010, "Scheduled Procedure Step Modification DateTime", "ScheduledProcedureStepModificationDateTime", "DT", "1" }, { 0x0040, 0x4011, "Expected Completion DateTime", "ExpectedCompletionDateTime", "DT", "1" }, { 0x0040, 0x4015, "Resulting General Purpose Performed Procedure Steps Sequence", "ResultingGeneralPurposePerformedProcedureStepsSequence", "SQ", "1" }, { 0x0040, 0x4016, "Referenced General Purpose Scheduled Procedure Step Sequence", "ReferencedGeneralPurposeScheduledProcedureStepSequence", "SQ", "1" }, { 0x0040, 0x4018, "Scheduled Workitem Code Sequence", "ScheduledWorkitemCodeSequence", "SQ", "1" }, { 0x0040, 0x4019, "Performed Workitem Code Sequence", "PerformedWorkitemCodeSequence", "SQ", "1" }, { 0x0040, 0x4020, "Input Availability Flag", "InputAvailabilityFlag", "CS", "1" }, { 0x0040, 0x4021, "Input Information Sequence", "InputInformationSequence", "SQ", "1" }, { 0x0040, 0x4022, "Relevant Information Sequence", "RelevantInformationSequence", "SQ", "1" }, { 0x0040, 0x4023, "Referenced General Purpose Scheduled Procedure Step Transaction UID", "ReferencedGeneralPurposeScheduledProcedureStepTransactionUID", "UI", "1" }, { 0x0040, 0x4025, "Scheduled Station Name Code Sequence", "ScheduledStationNameCodeSequence", "SQ", "1" }, { 0x0040, 0x4026, "Scheduled Station Class Code Sequence", "ScheduledStationClassCodeSequence", "SQ", "1" }, { 0x0040, 0x4027, "Scheduled Station Geographic Location Code Sequence", "ScheduledStationGeographicLocationCodeSequence", "SQ", "1" }, { 0x0040, 0x4028, "Performed Station Name Code Sequence", "PerformedStationNameCodeSequence", "SQ", "1" }, { 0x0040, 0x4029, "Performed Station Class Code Sequence", "PerformedStationClassCodeSequence", "SQ", "1" }, { 0x0040, 0x4030, "Performed Station Geographic Location Code Sequence", "PerformedStationGeographicLocationCodeSequence", "SQ", "1" }, { 0x0040, 0x4031, "Requested Subsequent Workitem Code Sequence", "RequestedSubsequentWorkitemCodeSequence", "SQ", "1" }, { 0x0040, 0x4032, "Non-DICOM Output Code Sequence", "NonDICOMOutputCodeSequence", "SQ", "1" }, { 0x0040, 0x4033, "Output Information Sequence", "OutputInformationSequence", "SQ", "1" }, { 0x0040, 0x4034, "Scheduled Human Performers Sequence", "ScheduledHumanPerformersSequence", "SQ", "1" }, { 0x0040, 0x4035, "Actual Human Performers Sequence", "ActualHumanPerformersSequence", "SQ", "1" }, { 0x0040, 0x4036, "Human Performer's Organization", "HumanPerformerOrganization", "LO", "1" }, { 0x0040, 0x4037, "Human Performer's Name", "HumanPerformerName", "PN", "1" }, { 0x0040, 0x4040, "Raw Data Handling", "RawDataHandling", "CS", "1" }, { 0x0040, 0x4041, "Input Readiness State", "InputReadinessState", "CS", "1" }, { 0x0040, 0x4050, "Performed Procedure Step Start DateTime", "PerformedProcedureStepStartDateTime", "DT", "1" }, { 0x0040, 0x4051, "Performed Procedure Step End DateTime", "PerformedProcedureStepEndDateTime", "DT", "1" }, { 0x0040, 0x4052, "Procedure Step Cancellation DateTime", "ProcedureStepCancellationDateTime", "DT", "1" }, { 0x0040, 0x8302, "Entrance Dose in mGy", "EntranceDoseInmGy", "DS", "1" }, { 0x0040, 0x9092, "Parametric Map Frame Type Sequence", "ParametricMapFrameTypeSequence", "SQ", "1" }, { 0x0040, 0x9094, "Referenced Image Real World Value Mapping Sequence", "ReferencedImageRealWorldValueMappingSequence", "SQ", "1" }, { 0x0040, 0x9096, "Real World Value Mapping Sequence", "RealWorldValueMappingSequence", "SQ", "1" }, { 0x0040, 0x9098, "Pixel Value Mapping Code Sequence", "PixelValueMappingCodeSequence", "SQ", "1" }, { 0x0040, 0x9210, "LUT Label", "LUTLabel", "SH", "1" }, { 0x0040, 0x9211, "Real World Value Last Value Mapped", "RealWorldValueLastValueMapped", "US or SS", "1" }, { 0x0040, 0x9212, "Real World Value LUT Data", "RealWorldValueLUTData", "FD", "1-n" }, { 0x0040, 0x9216, "Real World Value First Value Mapped", "RealWorldValueFirstValueMapped", "US or SS", "1" }, { 0x0040, 0x9220, "Quantity Definition Sequence", "QuantityDefinitionSequence", "SQ", "1" }, { 0x0040, 0x9224, "Real World Value Intercept", "RealWorldValueIntercept", "FD", "1" }, { 0x0040, 0x9225, "Real World Value Slope", "RealWorldValueSlope", "FD", "1" }, { 0x0040, 0xa007, "Findings Flag (Trial)", "FindingsFlagTrial", "CS", "1" }, { 0x0040, 0xa010, "Relationship Type", "RelationshipType", "CS", "1" }, { 0x0040, 0xa020, "Findings Sequence (Trial)", "FindingsSequenceTrial", "SQ", "1" }, { 0x0040, 0xa021, "Findings Group UID (Trial)", "FindingsGroupUIDTrial", "UI", "1" }, { 0x0040, 0xa022, "Referenced Findings Group UID (Trial)", "ReferencedFindingsGroupUIDTrial", "UI", "1" }, { 0x0040, 0xa023, "Findings Group Recording Date (Trial)", "FindingsGroupRecordingDateTrial", "DA", "1" }, { 0x0040, 0xa024, "Findings Group Recording Time (Trial)", "FindingsGroupRecordingTimeTrial", "TM", "1" }, { 0x0040, 0xa026, "Findings Source Category Code Sequence (Trial)", "FindingsSourceCategoryCodeSequenceTrial", "SQ", "1" }, { 0x0040, 0xa027, "Verifying Organization", "VerifyingOrganization", "LO", "1" }, { 0x0040, 0xa028, "Documenting Organization Identifier Code Sequence (Trial)", "DocumentingOrganizationIdentifierCodeSequenceTrial", "SQ", "1" }, { 0x0040, 0xa030, "Verification DateTime", "VerificationDateTime", "DT", "1" }, { 0x0040, 0xa032, "Observation DateTime", "ObservationDateTime", "DT", "1" }, { 0x0040, 0xa040, "Value Type", "ValueType", "CS", "1" }, { 0x0040, 0xa043, "Concept Name Code Sequence", "ConceptNameCodeSequence", "SQ", "1" }, { 0x0040, 0xa047, "Measurement Precision Description (Trial)", "MeasurementPrecisionDescriptionTrial", "LO", "1" }, { 0x0040, 0xa050, "Continuity Of Content", "ContinuityOfContent", "CS", "1" }, { 0x0040, 0xa057, "Urgency or Priority Alerts (Trial)", "UrgencyOrPriorityAlertsTrial", "CS", "1-n" }, { 0x0040, 0xa060, "Sequencing Indicator (Trial)", "SequencingIndicatorTrial", "LO", "1" }, { 0x0040, 0xa066, "Document Identifier Code Sequence (Trial)", "DocumentIdentifierCodeSequenceTrial", "SQ", "1" }, { 0x0040, 0xa067, "Document Author (Trial)", "DocumentAuthorTrial", "PN", "1" }, { 0x0040, 0xa068, "Document Author Identifier Code Sequence (Trial)", "DocumentAuthorIdentifierCodeSequenceTrial", "SQ", "1" }, { 0x0040, 0xa070, "Identifier Code Sequence (Trial)", "IdentifierCodeSequenceTrial", "SQ", "1" }, { 0x0040, 0xa073, "Verifying Observer Sequence", "VerifyingObserverSequence", "SQ", "1" }, { 0x0040, 0xa074, "Object Binary Identifier (Trial)", "ObjectBinaryIdentifierTrial", "OB", "1" }, { 0x0040, 0xa075, "Verifying Observer Name", "VerifyingObserverName", "PN", "1" }, { 0x0040, 0xa076, "Documenting Observer Identifier Code Sequence (Trial)", "DocumentingObserverIdentifierCodeSequenceTrial", "SQ", "1" }, { 0x0040, 0xa078, "Author Observer Sequence", "AuthorObserverSequence", "SQ", "1" }, { 0x0040, 0xa07a, "Participant Sequence", "ParticipantSequence", "SQ", "1" }, { 0x0040, 0xa07c, "Custodial Organization Sequence", "CustodialOrganizationSequence", "SQ", "1" }, { 0x0040, 0xa080, "Participation Type", "ParticipationType", "CS", "1" }, { 0x0040, 0xa082, "Participation DateTime", "ParticipationDateTime", "DT", "1" }, { 0x0040, 0xa084, "Observer Type", "ObserverType", "CS", "1" }, { 0x0040, 0xa085, "Procedure Identifier Code Sequence (Trial)", "ProcedureIdentifierCodeSequenceTrial", "SQ", "1" }, { 0x0040, 0xa088, "Verifying Observer Identification Code Sequence", "VerifyingObserverIdentificationCodeSequence", "SQ", "1" }, { 0x0040, 0xa089, "Object Directory Binary Identifier (Trial)", "ObjectDirectoryBinaryIdentifierTrial", "OB", "1" }, { 0x0040, 0xa090, "Equivalent CDA Document Sequence", "EquivalentCDADocumentSequence", "SQ", "1" }, { 0x0040, 0xa0b0, "Referenced Waveform Channels", "ReferencedWaveformChannels", "US", "2-2n" }, { 0x0040, 0xa110, "Date of Document or Verbal Transaction (Trial)", "DateOfDocumentOrVerbalTransactionTrial", "DA", "1" }, { 0x0040, 0xa112, "Time of Document Creation or Verbal Transaction (Trial)", "TimeOfDocumentCreationOrVerbalTransactionTrial", "TM", "1" }, { 0x0040, 0xa120, "DateTime", "DateTime", "DT", "1" }, { 0x0040, 0xa121, "Date", "Date", "DA", "1" }, { 0x0040, 0xa122, "Time", "Time", "TM", "1" }, { 0x0040, 0xa123, "Person Name", "PersonName", "PN", "1" }, { 0x0040, 0xa124, "UID", "UID", "UI", "1" }, { 0x0040, 0xa125, "Report Status ID (Trial)", "ReportStatusIDTrial", "CS", "2" }, { 0x0040, 0xa130, "Temporal Range Type", "TemporalRangeType", "CS", "1" }, { 0x0040, 0xa132, "Referenced Sample Positions", "ReferencedSamplePositions", "UL", "1-n" }, { 0x0040, 0xa136, "Referenced Frame Numbers", "ReferencedFrameNumbers", "US", "1-n" }, { 0x0040, 0xa138, "Referenced Time Offsets", "ReferencedTimeOffsets", "DS", "1-n" }, { 0x0040, 0xa13a, "Referenced DateTime", "ReferencedDateTime", "DT", "1-n" }, { 0x0040, 0xa160, "Text Value", "TextValue", "UT", "1" }, { 0x0040, 0xa161, "Floating Point Value", "FloatingPointValue", "FD", "1-n" }, { 0x0040, 0xa162, "Rational Numerator Value", "RationalNumeratorValue", "SL", "1-n" }, { 0x0040, 0xa163, "Rational Denominator Value", "RationalDenominatorValue", "UL", "1-n" }, { 0x0040, 0xa167, "Observation Category Code Sequence (Trial)", "ObservationCategoryCodeSequenceTrial", "SQ", "1" }, { 0x0040, 0xa168, "Concept Code Sequence", "ConceptCodeSequence", "SQ", "1" }, { 0x0040, 0xa16a, "Bibliographic Citation (Trial)", "BibliographicCitationTrial", "ST", "1" }, { 0x0040, 0xa170, "Purpose of Reference Code Sequence", "PurposeOfReferenceCodeSequence", "SQ", "1" }, { 0x0040, 0xa171, "Observation UID", "ObservationUID", "UI", "1" }, { 0x0040, 0xa172, "Referenced Observation UID (Trial)", "ReferencedObservationUIDTrial", "UI", "1" }, { 0x0040, 0xa173, "Referenced Observation Class (Trial)", "ReferencedObservationClassTrial", "CS", "1" }, { 0x0040, 0xa174, "Referenced Object Observation Class (Trial)", "ReferencedObjectObservationClassTrial", "CS", "1" }, { 0x0040, 0xa180, "Annotation Group Number", "AnnotationGroupNumber", "US", "1" }, { 0x0040, 0xa192, "Observation Date (Trial)", "ObservationDateTrial", "DA", "1" }, { 0x0040, 0xa193, "Observation Time (Trial)", "ObservationTimeTrial", "TM", "1" }, { 0x0040, 0xa194, "Measurement Automation (Trial)", "MeasurementAutomationTrial", "CS", "1" }, { 0x0040, 0xa195, "Modifier Code Sequence", "ModifierCodeSequence", "SQ", "1" }, { 0x0040, 0xa224, "Identification Description (Trial)", "IdentificationDescriptionTrial", "ST", "1" }, { 0x0040, 0xa290, "Coordinates Set Geometric Type (Trial)", "CoordinatesSetGeometricTypeTrial", "CS", "1" }, { 0x0040, 0xa296, "Algorithm Code Sequence (Trial)", "AlgorithmCodeSequenceTrial", "SQ", "1" }, { 0x0040, 0xa297, "Algorithm Description (Trial)", "AlgorithmDescriptionTrial", "ST", "1" }, { 0x0040, 0xa29a, "Pixel Coordinates Set (Trial)", "PixelCoordinatesSetTrial", "SL", "2-2n" }, { 0x0040, 0xa300, "Measured Value Sequence", "MeasuredValueSequence", "SQ", "1" }, { 0x0040, 0xa301, "Numeric Value Qualifier Code Sequence", "NumericValueQualifierCodeSequence", "SQ", "1" }, { 0x0040, 0xa307, "Current Observer (Trial)", "CurrentObserverTrial", "PN", "1" }, { 0x0040, 0xa30a, "Numeric Value", "NumericValue", "DS", "1-n" }, { 0x0040, 0xa313, "Referenced Accession Sequence (Trial)", "ReferencedAccessionSequenceTrial", "SQ", "1" }, { 0x0040, 0xa33a, "Report Status Comment (Trial)", "ReportStatusCommentTrial", "ST", "1" }, { 0x0040, 0xa340, "Procedure Context Sequence (Trial)", "ProcedureContextSequenceTrial", "SQ", "1" }, { 0x0040, 0xa352, "Verbal Source (Trial)", "VerbalSourceTrial", "PN", "1" }, { 0x0040, 0xa353, "Address (Trial)", "AddressTrial", "ST", "1" }, { 0x0040, 0xa354, "Telephone Number (Trial)", "TelephoneNumberTrial", "LO", "1" }, { 0x0040, 0xa358, "Verbal Source Identifier Code Sequence (Trial)", "VerbalSourceIdentifierCodeSequenceTrial", "SQ", "1" }, { 0x0040, 0xa360, "Predecessor Documents Sequence", "PredecessorDocumentsSequence", "SQ", "1" }, { 0x0040, 0xa370, "Referenced Request Sequence", "ReferencedRequestSequence", "SQ", "1" }, { 0x0040, 0xa372, "Performed Procedure Code Sequence", "PerformedProcedureCodeSequence", "SQ", "1" }, { 0x0040, 0xa375, "Current Requested Procedure Evidence Sequence", "CurrentRequestedProcedureEvidenceSequence", "SQ", "1" }, { 0x0040, 0xa380, "Report Detail Sequence (Trial)", "ReportDetailSequenceTrial", "SQ", "1" }, { 0x0040, 0xa385, "Pertinent Other Evidence Sequence", "PertinentOtherEvidenceSequence", "SQ", "1" }, { 0x0040, 0xa390, "HL7 Structured Document Reference Sequence", "HL7StructuredDocumentReferenceSequence", "SQ", "1" }, { 0x0040, 0xa402, "Observation Subject UID (Trial)", "ObservationSubjectUIDTrial", "UI", "1" }, { 0x0040, 0xa403, "Observation Subject Class (Trial)", "ObservationSubjectClassTrial", "CS", "1" }, { 0x0040, 0xa404, "Observation Subject Type Code Sequence (Trial)", "ObservationSubjectTypeCodeSequenceTrial", "SQ", "1" }, { 0x0040, 0xa491, "Completion Flag", "CompletionFlag", "CS", "1" }, { 0x0040, 0xa492, "Completion Flag Description", "CompletionFlagDescription", "LO", "1" }, { 0x0040, 0xa493, "Verification Flag", "VerificationFlag", "CS", "1" }, { 0x0040, 0xa494, "Archive Requested", "ArchiveRequested", "CS", "1" }, { 0x0040, 0xa496, "Preliminary Flag", "PreliminaryFlag", "CS", "1" }, { 0x0040, 0xa504, "Content Template Sequence", "ContentTemplateSequence", "SQ", "1" }, { 0x0040, 0xa525, "Identical Documents Sequence", "IdenticalDocumentsSequence", "SQ", "1" }, { 0x0040, 0xa600, "Observation Subject Context Flag (Trial)", "ObservationSubjectContextFlagTrial", "CS", "1" }, { 0x0040, 0xa601, "Observer Context Flag (Trial)", "ObserverContextFlagTrial", "CS", "1" }, { 0x0040, 0xa603, "Procedure Context Flag (Trial)", "ProcedureContextFlagTrial", "CS", "1" }, { 0x0040, 0xa730, "Content Sequence", "ContentSequence", "SQ", "1" }, { 0x0040, 0xa731, "Relationship Sequence (Trial)", "RelationshipSequenceTrial", "SQ", "1" }, { 0x0040, 0xa732, "Relationship Type Code Sequence (Trial)", "RelationshipTypeCodeSequenceTrial", "SQ", "1" }, { 0x0040, 0xa744, "Language Code Sequence (Trial)", "LanguageCodeSequenceTrial", "SQ", "1" }, { 0x0040, 0xa992, "Uniform Resource Locator (Trial)", "UniformResourceLocatorTrial", "ST", "1" }, { 0x0040, 0xb020, "Waveform Annotation Sequence", "WaveformAnnotationSequence", "SQ", "1" }, { 0x0040, 0xdb00, "Template Identifier", "TemplateIdentifier", "CS", "1" }, { 0x0040, 0xdb06, "Template Version", "TemplateVersion", "DT", "1" }, { 0x0040, 0xdb07, "Template Local Version", "TemplateLocalVersion", "DT", "1" }, { 0x0040, 0xdb0b, "Template Extension Flag", "TemplateExtensionFlag", "CS", "1" }, { 0x0040, 0xdb0c, "Template Extension Organization UID", "TemplateExtensionOrganizationUID", "UI", "1" }, { 0x0040, 0xdb0d, "Template Extension Creator UID", "TemplateExtensionCreatorUID", "UI", "1" }, { 0x0040, 0xdb73, "Referenced Content Item Identifier", "ReferencedContentItemIdentifier", "UL", "1-n" }, { 0x0040, 0xe001, "HL7 Instance Identifier", "HL7InstanceIdentifier", "ST", "1" }, { 0x0040, 0xe004, "HL7 Document Effective Time", "HL7DocumentEffectiveTime", "DT", "1" }, { 0x0040, 0xe006, "HL7 Document Type Code Sequence", "HL7DocumentTypeCodeSequence", "SQ", "1" }, { 0x0040, 0xe008, "Document Class Code Sequence", "DocumentClassCodeSequence", "SQ", "1" }, { 0x0040, 0xe010, "Retrieve URI", "RetrieveURI", "UR", "1" }, { 0x0040, 0xe011, "Retrieve Location UID", "RetrieveLocationUID", "UI", "1" }, { 0x0040, 0xe020, "Type of Instances", "TypeOfInstances", "CS", "1" }, { 0x0040, 0xe021, "DICOM Retrieval Sequence", "DICOMRetrievalSequence", "SQ", "1" }, { 0x0040, 0xe022, "DICOM Media Retrieval Sequence", "DICOMMediaRetrievalSequence", "SQ", "1" }, { 0x0040, 0xe023, "WADO Retrieval Sequence", "WADORetrievalSequence", "SQ", "1" }, { 0x0040, 0xe024, "XDS Retrieval Sequence", "XDSRetrievalSequence", "SQ", "1" }, { 0x0040, 0xe025, "WADO-RS Retrieval Sequence", "WADORSRetrievalSequence", "SQ", "1" }, { 0x0040, 0xe030, "Repository Unique ID", "RepositoryUniqueID", "UI", "1" }, { 0x0040, 0xe031, "Home Community ID", "HomeCommunityID", "UI", "1" }, { 0x0042, 0x0010, "Document Title", "DocumentTitle", "ST", "1" }, { 0x0042, 0x0011, "Encapsulated Document", "EncapsulatedDocument", "OB", "1" }, { 0x0042, 0x0012, "MIME Type of Encapsulated Document", "MIMETypeOfEncapsulatedDocument", "LO", "1" }, { 0x0042, 0x0013, "Source Instance Sequence", "SourceInstanceSequence", "SQ", "1" }, { 0x0042, 0x0014, "List of MIME Types", "ListOfMIMETypes", "LO", "1-n" }, { 0x0044, 0x0001, "Product Package Identifier", "ProductPackageIdentifier", "ST", "1" }, { 0x0044, 0x0002, "Substance Administration Approval", "SubstanceAdministrationApproval", "CS", "1" }, { 0x0044, 0x0003, "Approval Status Further Description", "ApprovalStatusFurtherDescription", "LT", "1" }, { 0x0044, 0x0004, "Approval Status DateTime", "ApprovalStatusDateTime", "DT", "1" }, { 0x0044, 0x0007, "Product Type Code Sequence", "ProductTypeCodeSequence", "SQ", "1" }, { 0x0044, 0x0008, "Product Name", "ProductName", "LO", "1-n" }, { 0x0044, 0x0009, "Product Description", "ProductDescription", "LT", "1" }, { 0x0044, 0x000a, "Product Lot Identifier", "ProductLotIdentifier", "LO", "1" }, { 0x0044, 0x000b, "Product Expiration DateTime", "ProductExpirationDateTime", "DT", "1" }, { 0x0044, 0x0010, "Substance Administration DateTime", "SubstanceAdministrationDateTime", "DT", "1" }, { 0x0044, 0x0011, "Substance Administration Notes", "SubstanceAdministrationNotes", "LO", "1" }, { 0x0044, 0x0012, "Substance Administration Device ID", "SubstanceAdministrationDeviceID", "LO", "1" }, { 0x0044, 0x0013, "Product Parameter Sequence", "ProductParameterSequence", "SQ", "1" }, { 0x0044, 0x0019, "Substance Administration Parameter Sequence", "SubstanceAdministrationParameterSequence", "SQ", "1" }, { 0x0046, 0x0012, "Lens Description", "LensDescription", "LO", "1" }, { 0x0046, 0x0014, "Right Lens Sequence", "RightLensSequence", "SQ", "1" }, { 0x0046, 0x0015, "Left Lens Sequence", "LeftLensSequence", "SQ", "1" }, { 0x0046, 0x0016, "Unspecified Laterality Lens Sequence", "UnspecifiedLateralityLensSequence", "SQ", "1" }, { 0x0046, 0x0018, "Cylinder Sequence", "CylinderSequence", "SQ", "1" }, { 0x0046, 0x0028, "Prism Sequence", "PrismSequence", "SQ", "1" }, { 0x0046, 0x0030, "Horizontal Prism Power", "HorizontalPrismPower", "FD", "1" }, { 0x0046, 0x0032, "Horizontal Prism Base", "HorizontalPrismBase", "CS", "1" }, { 0x0046, 0x0034, "Vertical Prism Power", "VerticalPrismPower", "FD", "1" }, { 0x0046, 0x0036, "Vertical Prism Base", "VerticalPrismBase", "CS", "1" }, { 0x0046, 0x0038, "Lens Segment Type", "LensSegmentType", "CS", "1" }, { 0x0046, 0x0040, "Optical Transmittance", "OpticalTransmittance", "FD", "1" }, { 0x0046, 0x0042, "Channel Width", "ChannelWidth", "FD", "1" }, { 0x0046, 0x0044, "Pupil Size", "PupilSize", "FD", "1" }, { 0x0046, 0x0046, "Corneal Size", "CornealSize", "FD", "1" }, { 0x0046, 0x0050, "Autorefraction Right Eye Sequence", "AutorefractionRightEyeSequence", "SQ", "1" }, { 0x0046, 0x0052, "Autorefraction Left Eye Sequence", "AutorefractionLeftEyeSequence", "SQ", "1" }, { 0x0046, 0x0060, "Distance Pupillary Distance", "DistancePupillaryDistance", "FD", "1" }, { 0x0046, 0x0062, "Near Pupillary Distance", "NearPupillaryDistance", "FD", "1" }, { 0x0046, 0x0063, "Intermediate Pupillary Distance", "IntermediatePupillaryDistance", "FD", "1" }, { 0x0046, 0x0064, "Other Pupillary Distance", "OtherPupillaryDistance", "FD", "1" }, { 0x0046, 0x0070, "Keratometry Right Eye Sequence", "KeratometryRightEyeSequence", "SQ", "1" }, { 0x0046, 0x0071, "Keratometry Left Eye Sequence", "KeratometryLeftEyeSequence", "SQ", "1" }, { 0x0046, 0x0074, "Steep Keratometric Axis Sequence", "SteepKeratometricAxisSequence", "SQ", "1" }, { 0x0046, 0x0075, "Radius of Curvature", "RadiusOfCurvature", "FD", "1" }, { 0x0046, 0x0076, "Keratometric Power", "KeratometricPower", "FD", "1" }, { 0x0046, 0x0077, "Keratometric Axis", "KeratometricAxis", "FD", "1" }, { 0x0046, 0x0080, "Flat Keratometric Axis Sequence", "FlatKeratometricAxisSequence", "SQ", "1" }, { 0x0046, 0x0092, "Background Color", "BackgroundColor", "CS", "1" }, { 0x0046, 0x0094, "Optotype", "Optotype", "CS", "1" }, { 0x0046, 0x0095, "Optotype Presentation", "OptotypePresentation", "CS", "1" }, { 0x0046, 0x0097, "Subjective Refraction Right Eye Sequence", "SubjectiveRefractionRightEyeSequence", "SQ", "1" }, { 0x0046, 0x0098, "Subjective Refraction Left Eye Sequence", "SubjectiveRefractionLeftEyeSequence", "SQ", "1" }, { 0x0046, 0x0100, "Add Near Sequence", "AddNearSequence", "SQ", "1" }, { 0x0046, 0x0101, "Add Intermediate Sequence", "AddIntermediateSequence", "SQ", "1" }, { 0x0046, 0x0102, "Add Other Sequence", "AddOtherSequence", "SQ", "1" }, { 0x0046, 0x0104, "Add Power", "AddPower", "FD", "1" }, { 0x0046, 0x0106, "Viewing Distance", "ViewingDistance", "FD", "1" }, { 0x0046, 0x0121, "Visual Acuity Type Code Sequence", "VisualAcuityTypeCodeSequence", "SQ", "1" }, { 0x0046, 0x0122, "Visual Acuity Right Eye Sequence", "VisualAcuityRightEyeSequence", "SQ", "1" }, { 0x0046, 0x0123, "Visual Acuity Left Eye Sequence", "VisualAcuityLeftEyeSequence", "SQ", "1" }, { 0x0046, 0x0124, "Visual Acuity Both Eyes Open Sequence", "VisualAcuityBothEyesOpenSequence", "SQ", "1" }, { 0x0046, 0x0125, "Viewing Distance Type", "ViewingDistanceType", "CS", "1" }, { 0x0046, 0x0135, "Visual Acuity Modifiers", "VisualAcuityModifiers", "SS", "2" }, { 0x0046, 0x0137, "Decimal Visual Acuity", "DecimalVisualAcuity", "FD", "1" }, { 0x0046, 0x0139, "Optotype Detailed Definition", "OptotypeDetailedDefinition", "LO", "1" }, { 0x0046, 0x0145, "Referenced Refractive Measurements Sequence", "ReferencedRefractiveMeasurementsSequence", "SQ", "1" }, { 0x0046, 0x0146, "Sphere Power", "SpherePower", "FD", "1" }, { 0x0046, 0x0147, "Cylinder Power", "CylinderPower", "FD", "1" }, { 0x0046, 0x0201, "Corneal Topography Surface", "CornealTopographySurface", "CS", "1" }, { 0x0046, 0x0202, "Corneal Vertex Location", "CornealVertexLocation", "FL", "2" }, { 0x0046, 0x0203, "Pupil Centroid X-Coordinate", "PupilCentroidXCoordinate", "FL", "1" }, { 0x0046, 0x0204, "Pupil Centroid Y-Coordinate", "PupilCentroidYCoordinate", "FL", "1" }, { 0x0046, 0x0205, "Equivalent Pupil Radius", "EquivalentPupilRadius", "FL", "1" }, { 0x0046, 0x0207, "Corneal Topography Map Type Code Sequence", "CornealTopographyMapTypeCodeSequence", "SQ", "1" }, { 0x0046, 0x0208, "Vertices of the Outline of Pupil", "VerticesOfTheOutlineOfPupil", "IS", "2-2n" }, { 0x0046, 0x0210, "Corneal Topography Mapping Normals Sequence", "CornealTopographyMappingNormalsSequence", "SQ", "1" }, { 0x0046, 0x0211, "Maximum Corneal Curvature Sequence", "MaximumCornealCurvatureSequence", "SQ", "1" }, { 0x0046, 0x0212, "Maximum Corneal Curvature", "MaximumCornealCurvature", "FL", "1" }, { 0x0046, 0x0213, "Maximum Corneal Curvature Location", "MaximumCornealCurvatureLocation", "FL", "2" }, { 0x0046, 0x0215, "Minimum Keratometric Sequence", "MinimumKeratometricSequence", "SQ", "1" }, { 0x0046, 0x0218, "Simulated Keratometric Cylinder Sequence", "SimulatedKeratometricCylinderSequence", "SQ", "1" }, { 0x0046, 0x0220, "Average Corneal Power", "AverageCornealPower", "FL", "1" }, { 0x0046, 0x0224, "Corneal I-S Value", "CornealISValue", "FL", "1" }, { 0x0046, 0x0227, "Analyzed Area", "AnalyzedArea", "FL", "1" }, { 0x0046, 0x0230, "Surface Regularity Index", "SurfaceRegularityIndex", "FL", "1" }, { 0x0046, 0x0232, "Surface Asymmetry Index", "SurfaceAsymmetryIndex", "FL", "1" }, { 0x0046, 0x0234, "Corneal Eccentricity Index", "CornealEccentricityIndex", "FL", "1" }, { 0x0046, 0x0236, "Keratoconus Prediction Index", "KeratoconusPredictionIndex", "FL", "1" }, { 0x0046, 0x0238, "Decimal Potential Visual Acuity", "DecimalPotentialVisualAcuity", "FL", "1" }, { 0x0046, 0x0242, "Corneal Topography Map Quality Evaluation", "CornealTopographyMapQualityEvaluation", "CS", "1" }, { 0x0046, 0x0244, "Source Image Corneal Processed Data Sequence", "SourceImageCornealProcessedDataSequence", "SQ", "1" }, { 0x0046, 0x0247, "Corneal Point Location", "CornealPointLocation", "FL", "3" }, { 0x0046, 0x0248, "Corneal Point Estimated", "CornealPointEstimated", "CS", "1" }, { 0x0046, 0x0249, "Axial Power", "AxialPower", "FL", "1" }, { 0x0046, 0x0250, "Tangential Power", "TangentialPower", "FL", "1" }, { 0x0046, 0x0251, "Refractive Power", "RefractivePower", "FL", "1" }, { 0x0046, 0x0252, "Relative Elevation", "RelativeElevation", "FL", "1" }, { 0x0046, 0x0253, "Corneal Wavefront", "CornealWavefront", "FL", "1" }, { 0x0048, 0x0001, "Imaged Volume Width", "ImagedVolumeWidth", "FL", "1" }, { 0x0048, 0x0002, "Imaged Volume Height", "ImagedVolumeHeight", "FL", "1" }, { 0x0048, 0x0003, "Imaged Volume Depth", "ImagedVolumeDepth", "FL", "1" }, { 0x0048, 0x0006, "Total Pixel Matrix Columns", "TotalPixelMatrixColumns", "UL", "1" }, { 0x0048, 0x0007, "Total Pixel Matrix Rows", "TotalPixelMatrixRows", "UL", "1" }, { 0x0048, 0x0008, "Total Pixel Matrix Origin Sequence", "TotalPixelMatrixOriginSequence", "SQ", "1" }, { 0x0048, 0x0010, "Specimen Label in Image", "SpecimenLabelInImage", "CS", "1" }, { 0x0048, 0x0011, "Focus Method", "FocusMethod", "CS", "1" }, { 0x0048, 0x0012, "Extended Depth of Field", "ExtendedDepthOfField", "CS", "1" }, { 0x0048, 0x0013, "Number of Focal Planes", "NumberOfFocalPlanes", "US", "1" }, { 0x0048, 0x0014, "Distance Between Focal Planes", "DistanceBetweenFocalPlanes", "FL", "1" }, { 0x0048, 0x0015, "Recommended Absent Pixel CIELab Value", "RecommendedAbsentPixelCIELabValue", "US", "3" }, { 0x0048, 0x0100, "Illuminator Type Code Sequence", "IlluminatorTypeCodeSequence", "SQ", "1" }, { 0x0048, 0x0102, "Image Orientation (Slide)", "ImageOrientationSlide", "DS", "6" }, { 0x0048, 0x0105, "Optical Path Sequence", "OpticalPathSequence", "SQ", "1" }, { 0x0048, 0x0106, "Optical Path Identifier", "OpticalPathIdentifier", "SH", "1" }, { 0x0048, 0x0107, "Optical Path Description", "OpticalPathDescription", "ST", "1" }, { 0x0048, 0x0108, "Illumination Color Code Sequence", "IlluminationColorCodeSequence", "SQ", "1" }, { 0x0048, 0x0110, "Specimen Reference Sequence", "SpecimenReferenceSequence", "SQ", "1" }, { 0x0048, 0x0111, "Condenser Lens Power", "CondenserLensPower", "DS", "1" }, { 0x0048, 0x0112, "Objective Lens Power", "ObjectiveLensPower", "DS", "1" }, { 0x0048, 0x0113, "Objective Lens Numerical Aperture", "ObjectiveLensNumericalAperture", "DS", "1" }, { 0x0048, 0x0120, "Palette Color Lookup Table Sequence", "PaletteColorLookupTableSequence", "SQ", "1" }, { 0x0048, 0x0200, "Referenced Image Navigation Sequence", "ReferencedImageNavigationSequence", "SQ", "1" }, { 0x0048, 0x0201, "Top Left Hand Corner of Localizer Area", "TopLeftHandCornerOfLocalizerArea", "US", "2" }, { 0x0048, 0x0202, "Bottom Right Hand Corner of Localizer Area", "BottomRightHandCornerOfLocalizerArea", "US", "2" }, { 0x0048, 0x0207, "Optical Path Identification Sequence", "OpticalPathIdentificationSequence", "SQ", "1" }, { 0x0048, 0x021a, "Plane Position (Slide) Sequence", "PlanePositionSlideSequence", "SQ", "1" }, { 0x0048, 0x021e, "Column Position In Total Image Pixel Matrix", "ColumnPositionInTotalImagePixelMatrix", "SL", "1" }, { 0x0048, 0x021f, "Row Position In Total Image Pixel Matrix", "RowPositionInTotalImagePixelMatrix", "SL", "1" }, { 0x0048, 0x0301, "Pixel Origin Interpretation", "PixelOriginInterpretation", "CS", "1" }, { 0x0050, 0x0004, "Calibration Image", "CalibrationImage", "CS", "1" }, { 0x0050, 0x0010, "Device Sequence", "DeviceSequence", "SQ", "1" }, { 0x0050, 0x0012, "Container Component Type Code Sequence", "ContainerComponentTypeCodeSequence", "SQ", "1" }, { 0x0050, 0x0013, "Container Component Thickness", "ContainerComponentThickness", "FD", "1" }, { 0x0050, 0x0014, "Device Length", "DeviceLength", "DS", "1" }, { 0x0050, 0x0015, "Container Component Width", "ContainerComponentWidth", "FD", "1" }, { 0x0050, 0x0016, "Device Diameter", "DeviceDiameter", "DS", "1" }, { 0x0050, 0x0017, "Device Diameter Units", "DeviceDiameterUnits", "CS", "1" }, { 0x0050, 0x0018, "Device Volume", "DeviceVolume", "DS", "1" }, { 0x0050, 0x0019, "Inter-Marker Distance", "InterMarkerDistance", "DS", "1" }, { 0x0050, 0x001a, "Container Component Material", "ContainerComponentMaterial", "CS", "1" }, { 0x0050, 0x001b, "Container Component ID", "ContainerComponentID", "LO", "1" }, { 0x0050, 0x001c, "Container Component Length", "ContainerComponentLength", "FD", "1" }, { 0x0050, 0x001d, "Container Component Diameter", "ContainerComponentDiameter", "FD", "1" }, { 0x0050, 0x001e, "Container Component Description", "ContainerComponentDescription", "LO", "1" }, { 0x0050, 0x0020, "Device Description", "DeviceDescription", "LO", "1" }, { 0x0052, 0x0001, "Contrast/Bolus Ingredient Percent by Volume", "ContrastBolusIngredientPercentByVolume", "FL", "1" }, { 0x0052, 0x0002, "OCT Focal Distance", "OCTFocalDistance", "FD", "1" }, { 0x0052, 0x0003, "Beam Spot Size", "BeamSpotSize", "FD", "1" }, { 0x0052, 0x0004, "Effective Refractive Index", "EffectiveRefractiveIndex", "FD", "1" }, { 0x0052, 0x0006, "OCT Acquisition Domain", "OCTAcquisitionDomain", "CS", "1" }, { 0x0052, 0x0007, "OCT Optical Center Wavelength", "OCTOpticalCenterWavelength", "FD", "1" }, { 0x0052, 0x0008, "Axial Resolution", "AxialResolution", "FD", "1" }, { 0x0052, 0x0009, "Ranging Depth", "RangingDepth", "FD", "1" }, { 0x0052, 0x0011, "A-line Rate", "ALineRate", "FD", "1" }, { 0x0052, 0x0012, "A-lines Per Frame", "ALinesPerFrame", "US", "1" }, { 0x0052, 0x0013, "Catheter Rotational Rate", "CatheterRotationalRate", "FD", "1" }, { 0x0052, 0x0014, "A-line Pixel Spacing", "ALinePixelSpacing", "FD", "1" }, { 0x0052, 0x0016, "Mode of Percutaneous Access Sequence", "ModeOfPercutaneousAccessSequence", "SQ", "1" }, { 0x0052, 0x0025, "Intravascular OCT Frame Type Sequence", "IntravascularOCTFrameTypeSequence", "SQ", "1" }, { 0x0052, 0x0026, "OCT Z Offset Applied", "OCTZOffsetApplied", "CS", "1" }, { 0x0052, 0x0027, "Intravascular Frame Content Sequence", "IntravascularFrameContentSequence", "SQ", "1" }, { 0x0052, 0x0028, "Intravascular Longitudinal Distance", "IntravascularLongitudinalDistance", "FD", "1" }, { 0x0052, 0x0029, "Intravascular OCT Frame Content Sequence", "IntravascularOCTFrameContentSequence", "SQ", "1" }, { 0x0052, 0x0030, "OCT Z Offset Correction", "OCTZOffsetCorrection", "SS", "1" }, { 0x0052, 0x0031, "Catheter Direction of Rotation", "CatheterDirectionOfRotation", "CS", "1" }, { 0x0052, 0x0033, "Seam Line Location", "SeamLineLocation", "FD", "1" }, { 0x0052, 0x0034, "First A-line Location", "FirstALineLocation", "FD", "1" }, { 0x0052, 0x0036, "Seam Line Index", "SeamLineIndex", "US", "1" }, { 0x0052, 0x0038, "Number of Padded A-lines", "NumberOfPaddedALines", "US", "1" }, { 0x0052, 0x0039, "Interpolation Type", "InterpolationType", "CS", "1" }, { 0x0052, 0x003a, "Refractive Index Applied", "RefractiveIndexApplied", "CS", "1" }, { 0x0054, 0x0010, "Energy Window Vector", "EnergyWindowVector", "US", "1-n" }, { 0x0054, 0x0011, "Number of Energy Windows", "NumberOfEnergyWindows", "US", "1" }, { 0x0054, 0x0012, "Energy Window Information Sequence", "EnergyWindowInformationSequence", "SQ", "1" }, { 0x0054, 0x0013, "Energy Window Range Sequence", "EnergyWindowRangeSequence", "SQ", "1" }, { 0x0054, 0x0014, "Energy Window Lower Limit", "EnergyWindowLowerLimit", "DS", "1" }, { 0x0054, 0x0015, "Energy Window Upper Limit", "EnergyWindowUpperLimit", "DS", "1" }, { 0x0054, 0x0016, "Radiopharmaceutical Information Sequence", "RadiopharmaceuticalInformationSequence", "SQ", "1" }, { 0x0054, 0x0017, "Residual Syringe Counts", "ResidualSyringeCounts", "IS", "1" }, { 0x0054, 0x0018, "Energy Window Name", "EnergyWindowName", "SH", "1" }, { 0x0054, 0x0020, "Detector Vector", "DetectorVector", "US", "1-n" }, { 0x0054, 0x0021, "Number of Detectors", "NumberOfDetectors", "US", "1" }, { 0x0054, 0x0022, "Detector Information Sequence", "DetectorInformationSequence", "SQ", "1" }, { 0x0054, 0x0030, "Phase Vector", "PhaseVector", "US", "1-n" }, { 0x0054, 0x0031, "Number of Phases", "NumberOfPhases", "US", "1" }, { 0x0054, 0x0032, "Phase Information Sequence", "PhaseInformationSequence", "SQ", "1" }, { 0x0054, 0x0033, "Number of Frames in Phase", "NumberOfFramesInPhase", "US", "1" }, { 0x0054, 0x0036, "Phase Delay", "PhaseDelay", "IS", "1" }, { 0x0054, 0x0038, "Pause Between Frames", "PauseBetweenFrames", "IS", "1" }, { 0x0054, 0x0039, "Phase Description", "PhaseDescription", "CS", "1" }, { 0x0054, 0x0050, "Rotation Vector", "RotationVector", "US", "1-n" }, { 0x0054, 0x0051, "Number of Rotations", "NumberOfRotations", "US", "1" }, { 0x0054, 0x0052, "Rotation Information Sequence", "RotationInformationSequence", "SQ", "1" }, { 0x0054, 0x0053, "Number of Frames in Rotation", "NumberOfFramesInRotation", "US", "1" }, { 0x0054, 0x0060, "R-R Interval Vector", "RRIntervalVector", "US", "1-n" }, { 0x0054, 0x0061, "Number of R-R Intervals", "NumberOfRRIntervals", "US", "1" }, { 0x0054, 0x0062, "Gated Information Sequence", "GatedInformationSequence", "SQ", "1" }, { 0x0054, 0x0063, "Data Information Sequence", "DataInformationSequence", "SQ", "1" }, { 0x0054, 0x0070, "Time Slot Vector", "TimeSlotVector", "US", "1-n" }, { 0x0054, 0x0071, "Number of Time Slots", "NumberOfTimeSlots", "US", "1" }, { 0x0054, 0x0072, "Time Slot Information Sequence", "TimeSlotInformationSequence", "SQ", "1" }, { 0x0054, 0x0073, "Time Slot Time", "TimeSlotTime", "DS", "1" }, { 0x0054, 0x0080, "Slice Vector", "SliceVector", "US", "1-n" }, { 0x0054, 0x0081, "Number of Slices", "NumberOfSlices", "US", "1" }, { 0x0054, 0x0090, "Angular View Vector", "AngularViewVector", "US", "1-n" }, { 0x0054, 0x0100, "Time Slice Vector", "TimeSliceVector", "US", "1-n" }, { 0x0054, 0x0101, "Number of Time Slices", "NumberOfTimeSlices", "US", "1" }, { 0x0054, 0x0200, "Start Angle", "StartAngle", "DS", "1" }, { 0x0054, 0x0202, "Type of Detector Motion", "TypeOfDetectorMotion", "CS", "1" }, { 0x0054, 0x0210, "Trigger Vector", "TriggerVector", "IS", "1-n" }, { 0x0054, 0x0211, "Number of Triggers in Phase", "NumberOfTriggersInPhase", "US", "1" }, { 0x0054, 0x0220, "View Code Sequence", "ViewCodeSequence", "SQ", "1" }, { 0x0054, 0x0222, "View Modifier Code Sequence", "ViewModifierCodeSequence", "SQ", "1" }, { 0x0054, 0x0300, "Radionuclide Code Sequence", "RadionuclideCodeSequence", "SQ", "1" }, { 0x0054, 0x0302, "Administration Route Code Sequence", "AdministrationRouteCodeSequence", "SQ", "1" }, { 0x0054, 0x0304, "Radiopharmaceutical Code Sequence", "RadiopharmaceuticalCodeSequence", "SQ", "1" }, { 0x0054, 0x0306, "Calibration Data Sequence", "CalibrationDataSequence", "SQ", "1" }, { 0x0054, 0x0308, "Energy Window Number", "EnergyWindowNumber", "US", "1" }, { 0x0054, 0x0400, "Image ID", "ImageID", "SH", "1" }, { 0x0054, 0x0410, "Patient Orientation Code Sequence", "PatientOrientationCodeSequence", "SQ", "1" }, { 0x0054, 0x0412, "Patient Orientation Modifier Code Sequence", "PatientOrientationModifierCodeSequence", "SQ", "1" }, { 0x0054, 0x0414, "Patient Gantry Relationship Code Sequence", "PatientGantryRelationshipCodeSequence", "SQ", "1" }, { 0x0054, 0x0500, "Slice Progression Direction", "SliceProgressionDirection", "CS", "1" }, { 0x0054, 0x0501, "Scan Progression Direction", "ScanProgressionDirection", "CS", "1" }, { 0x0054, 0x1000, "Series Type", "SeriesType", "CS", "2" }, { 0x0054, 0x1001, "Units", "Units", "CS", "1" }, { 0x0054, 0x1002, "Counts Source", "CountsSource", "CS", "1" }, { 0x0054, 0x1004, "Reprojection Method", "ReprojectionMethod", "CS", "1" }, { 0x0054, 0x1006, "SUV Type", "SUVType", "CS", "1" }, { 0x0054, 0x1100, "Randoms Correction Method", "RandomsCorrectionMethod", "CS", "1" }, { 0x0054, 0x1101, "Attenuation Correction Method", "AttenuationCorrectionMethod", "LO", "1" }, { 0x0054, 0x1102, "Decay Correction", "DecayCorrection", "CS", "1" }, { 0x0054, 0x1103, "Reconstruction Method", "ReconstructionMethod", "LO", "1" }, { 0x0054, 0x1104, "Detector Lines of Response Used", "DetectorLinesOfResponseUsed", "LO", "1" }, { 0x0054, 0x1105, "Scatter Correction Method", "ScatterCorrectionMethod", "LO", "1" }, { 0x0054, 0x1200, "Axial Acceptance", "AxialAcceptance", "DS", "1" }, { 0x0054, 0x1201, "Axial Mash", "AxialMash", "IS", "2" }, { 0x0054, 0x1202, "Transverse Mash", "TransverseMash", "IS", "1" }, { 0x0054, 0x1203, "Detector Element Size", "DetectorElementSize", "DS", "2" }, { 0x0054, 0x1210, "Coincidence Window Width", "CoincidenceWindowWidth", "DS", "1" }, { 0x0054, 0x1220, "Secondary Counts Type", "SecondaryCountsType", "CS", "1-n" }, { 0x0054, 0x1300, "Frame Reference Time", "FrameReferenceTime", "DS", "1" }, { 0x0054, 0x1310, "Primary (Prompts) Counts Accumulated", "PrimaryPromptsCountsAccumulated", "IS", "1" }, { 0x0054, 0x1311, "Secondary Counts Accumulated", "SecondaryCountsAccumulated", "IS", "1-n" }, { 0x0054, 0x1320, "Slice Sensitivity Factor", "SliceSensitivityFactor", "DS", "1" }, { 0x0054, 0x1321, "Decay Factor", "DecayFactor", "DS", "1" }, { 0x0054, 0x1322, "Dose Calibration Factor", "DoseCalibrationFactor", "DS", "1" }, { 0x0054, 0x1323, "Scatter Fraction Factor", "ScatterFractionFactor", "DS", "1" }, { 0x0054, 0x1324, "Dead Time Factor", "DeadTimeFactor", "DS", "1" }, { 0x0054, 0x1330, "Image Index", "ImageIndex", "US", "1" }, { 0x0054, 0x1400, "Counts Included", "CountsIncluded", "CS", "1-n" }, { 0x0054, 0x1401, "Dead Time Correction Flag", "DeadTimeCorrectionFlag", "CS", "1" }, { 0x0060, 0x3000, "Histogram Sequence", "HistogramSequence", "SQ", "1" }, { 0x0060, 0x3002, "Histogram Number of Bins", "HistogramNumberOfBins", "US", "1" }, { 0x0060, 0x3004, "Histogram First Bin Value", "HistogramFirstBinValue", "US or SS", "1" }, { 0x0060, 0x3006, "Histogram Last Bin Value", "HistogramLastBinValue", "US or SS", "1" }, { 0x0060, 0x3008, "Histogram Bin Width", "HistogramBinWidth", "US", "1" }, { 0x0060, 0x3010, "Histogram Explanation", "HistogramExplanation", "LO", "1" }, { 0x0060, 0x3020, "Histogram Data", "HistogramData", "UL", "1-n" }, { 0x0062, 0x0001, "Segmentation Type", "SegmentationType", "CS", "1" }, { 0x0062, 0x0002, "Segment Sequence", "SegmentSequence", "SQ", "1" }, { 0x0062, 0x0003, "Segmented Property Category Code Sequence", "SegmentedPropertyCategoryCodeSequence", "SQ", "1" }, { 0x0062, 0x0004, "Segment Number", "SegmentNumber", "US", "1" }, { 0x0062, 0x0005, "Segment Label", "SegmentLabel", "LO", "1" }, { 0x0062, 0x0006, "Segment Description", "SegmentDescription", "ST", "1" }, { 0x0062, 0x0008, "Segment Algorithm Type", "SegmentAlgorithmType", "CS", "1" }, { 0x0062, 0x0009, "Segment Algorithm Name", "SegmentAlgorithmName", "LO", "1" }, { 0x0062, 0x000a, "Segment Identification Sequence", "SegmentIdentificationSequence", "SQ", "1" }, { 0x0062, 0x000b, "Referenced Segment Number", "ReferencedSegmentNumber", "US", "1-n" }, { 0x0062, 0x000c, "Recommended Display Grayscale Value", "RecommendedDisplayGrayscaleValue", "US", "1" }, { 0x0062, 0x000d, "Recommended Display CIELab Value", "RecommendedDisplayCIELabValue", "US", "3" }, { 0x0062, 0x000e, "Maximum Fractional Value", "MaximumFractionalValue", "US", "1" }, { 0x0062, 0x000f, "Segmented Property Type Code Sequence", "SegmentedPropertyTypeCodeSequence", "SQ", "1" }, { 0x0062, 0x0010, "Segmentation Fractional Type", "SegmentationFractionalType", "CS", "1" }, { 0x0062, 0x0011, "Segmented Property Type Modifier Code Sequence", "SegmentedPropertyTypeModifierCodeSequence", "SQ", "1" }, { 0x0062, 0x0012, "Used Segments Sequence", "UsedSegmentsSequence", "SQ", "1" }, { 0x0064, 0x0002, "Deformable Registration Sequence", "DeformableRegistrationSequence", "SQ", "1" }, { 0x0064, 0x0003, "Source Frame of Reference UID", "SourceFrameOfReferenceUID", "UI", "1" }, { 0x0064, 0x0005, "Deformable Registration Grid Sequence", "DeformableRegistrationGridSequence", "SQ", "1" }, { 0x0064, 0x0007, "Grid Dimensions", "GridDimensions", "UL", "3" }, { 0x0064, 0x0008, "Grid Resolution", "GridResolution", "FD", "3" }, { 0x0064, 0x0009, "Vector Grid Data", "VectorGridData", "OF", "1" }, { 0x0064, 0x000f, "Pre Deformation Matrix Registration Sequence", "PreDeformationMatrixRegistrationSequence", "SQ", "1" }, { 0x0064, 0x0010, "Post Deformation Matrix Registration Sequence", "PostDeformationMatrixRegistrationSequence", "SQ", "1" }, { 0x0066, 0x0001, "Number of Surfaces", "NumberOfSurfaces", "UL", "1" }, { 0x0066, 0x0002, "Surface Sequence", "SurfaceSequence", "SQ", "1" }, { 0x0066, 0x0003, "Surface Number", "SurfaceNumber", "UL", "1" }, { 0x0066, 0x0004, "Surface Comments", "SurfaceComments", "LT", "1" }, { 0x0066, 0x0009, "Surface Processing", "SurfaceProcessing", "CS", "1" }, { 0x0066, 0x000a, "Surface Processing Ratio", "SurfaceProcessingRatio", "FL", "1" }, { 0x0066, 0x000b, "Surface Processing Description", "SurfaceProcessingDescription", "LO", "1" }, { 0x0066, 0x000c, "Recommended Presentation Opacity", "RecommendedPresentationOpacity", "FL", "1" }, { 0x0066, 0x000d, "Recommended Presentation Type", "RecommendedPresentationType", "CS", "1" }, { 0x0066, 0x000e, "Finite Volume", "FiniteVolume", "CS", "1" }, { 0x0066, 0x0010, "Manifold", "Manifold", "CS", "1" }, { 0x0066, 0x0011, "Surface Points Sequence", "SurfacePointsSequence", "SQ", "1" }, { 0x0066, 0x0012, "Surface Points Normals Sequence", "SurfacePointsNormalsSequence", "SQ", "1" }, { 0x0066, 0x0013, "Surface Mesh Primitives Sequence", "SurfaceMeshPrimitivesSequence", "SQ", "1" }, { 0x0066, 0x0015, "Number of Surface Points", "NumberOfSurfacePoints", "UL", "1" }, { 0x0066, 0x0016, "Point Coordinates Data", "PointCoordinatesData", "OF", "1" }, { 0x0066, 0x0017, "Point Position Accuracy", "PointPositionAccuracy", "FL", "3" }, { 0x0066, 0x0018, "Mean Point Distance", "MeanPointDistance", "FL", "1" }, { 0x0066, 0x0019, "Maximum Point Distance", "MaximumPointDistance", "FL", "1" }, { 0x0066, 0x001a, "Points Bounding Box Coordinates", "PointsBoundingBoxCoordinates", "FL", "6" }, { 0x0066, 0x001b, "Axis of Rotation", "AxisOfRotation", "FL", "3" }, { 0x0066, 0x001c, "Center of Rotation", "CenterOfRotation", "FL", "3" }, { 0x0066, 0x001e, "Number of Vectors", "NumberOfVectors", "UL", "1" }, { 0x0066, 0x001f, "Vector Dimensionality", "VectorDimensionality", "US", "1" }, { 0x0066, 0x0020, "Vector Accuracy", "VectorAccuracy", "FL", "1-n" }, { 0x0066, 0x0021, "Vector Coordinate Data", "VectorCoordinateData", "OF", "1" }, { 0x0066, 0x0023, "Triangle Point Index List", "TrianglePointIndexList", "OW", "1" }, { 0x0066, 0x0024, "Edge Point Index List", "EdgePointIndexList", "OW", "1" }, { 0x0066, 0x0025, "Vertex Point Index List", "VertexPointIndexList", "OW", "1" }, { 0x0066, 0x0026, "Triangle Strip Sequence", "TriangleStripSequence", "SQ", "1" }, { 0x0066, 0x0027, "Triangle Fan Sequence", "TriangleFanSequence", "SQ", "1" }, { 0x0066, 0x0028, "Line Sequence", "LineSequence", "SQ", "1" }, { 0x0066, 0x0029, "Primitive Point Index List", "PrimitivePointIndexList", "OW", "1" }, { 0x0066, 0x002a, "Surface Count", "SurfaceCount", "UL", "1" }, { 0x0066, 0x002b, "Referenced Surface Sequence", "ReferencedSurfaceSequence", "SQ", "1" }, { 0x0066, 0x002c, "Referenced Surface Number", "ReferencedSurfaceNumber", "UL", "1" }, { 0x0066, 0x002d, "Segment Surface Generation Algorithm Identification Sequence", "SegmentSurfaceGenerationAlgorithmIdentificationSequence", "SQ", "1" }, { 0x0066, 0x002e, "Segment Surface Source Instance Sequence", "SegmentSurfaceSourceInstanceSequence", "SQ", "1" }, { 0x0066, 0x002f, "Algorithm Family Code Sequence", "AlgorithmFamilyCodeSequence", "SQ", "1" }, { 0x0066, 0x0030, "Algorithm Name Code Sequence", "AlgorithmNameCodeSequence", "SQ", "1" }, { 0x0066, 0x0031, "Algorithm Version", "AlgorithmVersion", "LO", "1" }, { 0x0066, 0x0032, "Algorithm Parameters", "AlgorithmParameters", "LT", "1" }, { 0x0066, 0x0034, "Facet Sequence", "FacetSequence", "SQ", "1" }, { 0x0066, 0x0035, "Surface Processing Algorithm Identification Sequence", "SurfaceProcessingAlgorithmIdentificationSequence", "SQ", "1" }, { 0x0066, 0x0036, "Algorithm Name", "AlgorithmName", "LO", "1" }, { 0x0066, 0x0037, "Recommended Point Radius", "RecommendedPointRadius", "FL", "1" }, { 0x0066, 0x0038, "Recommended Line Thickness", "RecommendedLineThickness", "FL", "1" }, { 0x0066, 0x0040, "Long Primitive Point Index List", "LongPrimitivePointIndexList", "UL", "1-n" }, { 0x0066, 0x0041, "Long Triangle Point Index List", "LongTrianglePointIndexList", "UL", "3-3n" }, { 0x0066, 0x0042, "Long Edge Point Index List", "LongEdgePointIndexList", "UL", "2-2n" }, { 0x0066, 0x0043, "Long Vertex Point Index List", "LongVertexPointIndexList", "UL", "1-n" }, { 0x0068, 0x6210, "Implant Size", "ImplantSize", "LO", "1" }, { 0x0068, 0x6221, "Implant Template Version", "ImplantTemplateVersion", "LO", "1" }, { 0x0068, 0x6222, "Replaced Implant Template Sequence", "ReplacedImplantTemplateSequence", "SQ", "1" }, { 0x0068, 0x6223, "Implant Type", "ImplantType", "CS", "1" }, { 0x0068, 0x6224, "Derivation Implant Template Sequence", "DerivationImplantTemplateSequence", "SQ", "1" }, { 0x0068, 0x6225, "Original Implant Template Sequence", "OriginalImplantTemplateSequence", "SQ", "1" }, { 0x0068, 0x6226, "Effective DateTime", "EffectiveDateTime", "DT", "1" }, { 0x0068, 0x6230, "Implant Target Anatomy Sequence", "ImplantTargetAnatomySequence", "SQ", "1" }, { 0x0068, 0x6260, "Information From Manufacturer Sequence", "InformationFromManufacturerSequence", "SQ", "1" }, { 0x0068, 0x6265, "Notification From Manufacturer Sequence", "NotificationFromManufacturerSequence", "SQ", "1" }, { 0x0068, 0x6270, "Information Issue DateTime", "InformationIssueDateTime", "DT", "1" }, { 0x0068, 0x6280, "Information Summary", "InformationSummary", "ST", "1" }, { 0x0068, 0x62a0, "Implant Regulatory Disapproval Code Sequence", "ImplantRegulatoryDisapprovalCodeSequence", "SQ", "1" }, { 0x0068, 0x62a5, "Overall Template Spatial Tolerance", "OverallTemplateSpatialTolerance", "FD", "1" }, { 0x0068, 0x62c0, "HPGL Document Sequence", "HPGLDocumentSequence", "SQ", "1" }, { 0x0068, 0x62d0, "HPGL Document ID", "HPGLDocumentID", "US", "1" }, { 0x0068, 0x62d5, "HPGL Document Label", "HPGLDocumentLabel", "LO", "1" }, { 0x0068, 0x62e0, "View Orientation Code Sequence", "ViewOrientationCodeSequence", "SQ", "1" }, { 0x0068, 0x62f0, "View Orientation Modifier", "ViewOrientationModifier", "FD", "9" }, { 0x0068, 0x62f2, "HPGL Document Scaling", "HPGLDocumentScaling", "FD", "1" }, { 0x0068, 0x6300, "HPGL Document", "HPGLDocument", "OB", "1" }, { 0x0068, 0x6310, "HPGL Contour Pen Number", "HPGLContourPenNumber", "US", "1" }, { 0x0068, 0x6320, "HPGL Pen Sequence", "HPGLPenSequence", "SQ", "1" }, { 0x0068, 0x6330, "HPGL Pen Number", "HPGLPenNumber", "US", "1" }, { 0x0068, 0x6340, "HPGL Pen Label", "HPGLPenLabel", "LO", "1" }, { 0x0068, 0x6345, "HPGL Pen Description", "HPGLPenDescription", "ST", "1" }, { 0x0068, 0x6346, "Recommended Rotation Point", "RecommendedRotationPoint", "FD", "2" }, { 0x0068, 0x6347, "Bounding Rectangle", "BoundingRectangle", "FD", "4" }, { 0x0068, 0x6350, "Implant Template 3D Model Surface Number", "ImplantTemplate3DModelSurfaceNumber", "US", "1-n" }, { 0x0068, 0x6360, "Surface Model Description Sequence", "SurfaceModelDescriptionSequence", "SQ", "1" }, { 0x0068, 0x6380, "Surface Model Label", "SurfaceModelLabel", "LO", "1" }, { 0x0068, 0x6390, "Surface Model Scaling Factor", "SurfaceModelScalingFactor", "FD", "1" }, { 0x0068, 0x63a0, "Materials Code Sequence", "MaterialsCodeSequence", "SQ", "1" }, { 0x0068, 0x63a4, "Coating Materials Code Sequence", "CoatingMaterialsCodeSequence", "SQ", "1" }, { 0x0068, 0x63a8, "Implant Type Code Sequence", "ImplantTypeCodeSequence", "SQ", "1" }, { 0x0068, 0x63ac, "Fixation Method Code Sequence", "FixationMethodCodeSequence", "SQ", "1" }, { 0x0068, 0x63b0, "Mating Feature Sets Sequence", "MatingFeatureSetsSequence", "SQ", "1" }, { 0x0068, 0x63c0, "Mating Feature Set ID", "MatingFeatureSetID", "US", "1" }, { 0x0068, 0x63d0, "Mating Feature Set Label", "MatingFeatureSetLabel", "LO", "1" }, { 0x0068, 0x63e0, "Mating Feature Sequence", "MatingFeatureSequence", "SQ", "1" }, { 0x0068, 0x63f0, "Mating Feature ID", "MatingFeatureID", "US", "1" }, { 0x0068, 0x6400, "Mating Feature Degree of Freedom Sequence", "MatingFeatureDegreeOfFreedomSequence", "SQ", "1" }, { 0x0068, 0x6410, "Degree of Freedom ID", "DegreeOfFreedomID", "US", "1" }, { 0x0068, 0x6420, "Degree of Freedom Type", "DegreeOfFreedomType", "CS", "1" }, { 0x0068, 0x6430, "2D Mating Feature Coordinates Sequence", "TwoDMatingFeatureCoordinatesSequence", "SQ", "1" }, { 0x0068, 0x6440, "Referenced HPGL Document ID", "ReferencedHPGLDocumentID", "US", "1" }, { 0x0068, 0x6450, "2D Mating Point", "TwoDMatingPoint", "FD", "2" }, { 0x0068, 0x6460, "2D Mating Axes", "TwoDMatingAxes", "FD", "4" }, { 0x0068, 0x6470, "2D Degree of Freedom Sequence", "TwoDDegreeOfFreedomSequence", "SQ", "1" }, { 0x0068, 0x6490, "3D Degree of Freedom Axis", "ThreeDDegreeOfFreedomAxis", "FD", "3" }, { 0x0068, 0x64a0, "Range of Freedom", "RangeOfFreedom", "FD", "2" }, { 0x0068, 0x64c0, "3D Mating Point", "ThreeDMatingPoint", "FD", "3" }, { 0x0068, 0x64d0, "3D Mating Axes", "ThreeDMatingAxes", "FD", "9" }, { 0x0068, 0x64f0, "2D Degree of Freedom Axis", "TwoDDegreeOfFreedomAxis", "FD", "3" }, { 0x0068, 0x6500, "Planning Landmark Point Sequence", "PlanningLandmarkPointSequence", "SQ", "1" }, { 0x0068, 0x6510, "Planning Landmark Line Sequence", "PlanningLandmarkLineSequence", "SQ", "1" }, { 0x0068, 0x6520, "Planning Landmark Plane Sequence", "PlanningLandmarkPlaneSequence", "SQ", "1" }, { 0x0068, 0x6530, "Planning Landmark ID", "PlanningLandmarkID", "US", "1" }, { 0x0068, 0x6540, "Planning Landmark Description", "PlanningLandmarkDescription", "LO", "1" }, { 0x0068, 0x6545, "Planning Landmark Identification Code Sequence", "PlanningLandmarkIdentificationCodeSequence", "SQ", "1" }, { 0x0068, 0x6550, "2D Point Coordinates Sequence", "TwoDPointCoordinatesSequence", "SQ", "1" }, { 0x0068, 0x6560, "2D Point Coordinates", "TwoDPointCoordinates", "FD", "2" }, { 0x0068, 0x6590, "3D Point Coordinates", "ThreeDPointCoordinates", "FD", "3" }, { 0x0068, 0x65a0, "2D Line Coordinates Sequence", "TwoDLineCoordinatesSequence", "SQ", "1" }, { 0x0068, 0x65b0, "2D Line Coordinates", "TwoDLineCoordinates", "FD", "4" }, { 0x0068, 0x65d0, "3D Line Coordinates", "ThreeDLineCoordinates", "FD", "6" }, { 0x0068, 0x65e0, "2D Plane Coordinates Sequence", "TwoDPlaneCoordinatesSequence", "SQ", "1" }, { 0x0068, 0x65f0, "2D Plane Intersection", "TwoDPlaneIntersection", "FD", "4" }, { 0x0068, 0x6610, "3D Plane Origin", "ThreeDPlaneOrigin", "FD", "3" }, { 0x0068, 0x6620, "3D Plane Normal", "ThreeDPlaneNormal", "FD", "3" }, { 0x0070, 0x0001, "Graphic Annotation Sequence", "GraphicAnnotationSequence", "SQ", "1" }, { 0x0070, 0x0002, "Graphic Layer", "GraphicLayer", "CS", "1" }, { 0x0070, 0x0003, "Bounding Box Annotation Units", "BoundingBoxAnnotationUnits", "CS", "1" }, { 0x0070, 0x0004, "Anchor Point Annotation Units", "AnchorPointAnnotationUnits", "CS", "1" }, { 0x0070, 0x0005, "Graphic Annotation Units", "GraphicAnnotationUnits", "CS", "1" }, { 0x0070, 0x0006, "Unformatted Text Value", "UnformattedTextValue", "ST", "1" }, { 0x0070, 0x0008, "Text Object Sequence", "TextObjectSequence", "SQ", "1" }, { 0x0070, 0x0009, "Graphic Object Sequence", "GraphicObjectSequence", "SQ", "1" }, { 0x0070, 0x0010, "Bounding Box Top Left Hand Corner", "BoundingBoxTopLeftHandCorner", "FL", "2" }, { 0x0070, 0x0011, "Bounding Box Bottom Right Hand Corner", "BoundingBoxBottomRightHandCorner", "FL", "2" }, { 0x0070, 0x0012, "Bounding Box Text Horizontal Justification", "BoundingBoxTextHorizontalJustification", "CS", "1" }, { 0x0070, 0x0014, "Anchor Point", "AnchorPoint", "FL", "2" }, { 0x0070, 0x0015, "Anchor Point Visibility", "AnchorPointVisibility", "CS", "1" }, { 0x0070, 0x0020, "Graphic Dimensions", "GraphicDimensions", "US", "1" }, { 0x0070, 0x0021, "Number of Graphic Points", "NumberOfGraphicPoints", "US", "1" }, { 0x0070, 0x0022, "Graphic Data", "GraphicData", "FL", "2-n" }, { 0x0070, 0x0023, "Graphic Type", "GraphicType", "CS", "1" }, { 0x0070, 0x0024, "Graphic Filled", "GraphicFilled", "CS", "1" }, { 0x0070, 0x0040, "Image Rotation (Retired)", "ImageRotationRetired", "IS", "1" }, { 0x0070, 0x0041, "Image Horizontal Flip", "ImageHorizontalFlip", "CS", "1" }, { 0x0070, 0x0042, "Image Rotation", "ImageRotation", "US", "1" }, { 0x0070, 0x0050, "Displayed Area Top Left Hand Corner (Trial)", "DisplayedAreaTopLeftHandCornerTrial", "US", "2" }, { 0x0070, 0x0051, "Displayed Area Bottom Right Hand Corner (Trial)", "DisplayedAreaBottomRightHandCornerTrial", "US", "2" }, { 0x0070, 0x0052, "Displayed Area Top Left Hand Corner", "DisplayedAreaTopLeftHandCorner", "SL", "2" }, { 0x0070, 0x0053, "Displayed Area Bottom Right Hand Corner", "DisplayedAreaBottomRightHandCorner", "SL", "2" }, { 0x0070, 0x005a, "Displayed Area Selection Sequence", "DisplayedAreaSelectionSequence", "SQ", "1" }, { 0x0070, 0x0060, "Graphic Layer Sequence", "GraphicLayerSequence", "SQ", "1" }, { 0x0070, 0x0062, "Graphic Layer Order", "GraphicLayerOrder", "IS", "1" }, { 0x0070, 0x0066, "Graphic Layer Recommended Display Grayscale Value", "GraphicLayerRecommendedDisplayGrayscaleValue", "US", "1" }, { 0x0070, 0x0067, "Graphic Layer Recommended Display RGB Value", "GraphicLayerRecommendedDisplayRGBValue", "US", "3" }, { 0x0070, 0x0068, "Graphic Layer Description", "GraphicLayerDescription", "LO", "1" }, { 0x0070, 0x0080, "Content Label", "ContentLabel", "CS", "1" }, { 0x0070, 0x0081, "Content Description", "ContentDescription", "LO", "1" }, { 0x0070, 0x0082, "Presentation Creation Date", "PresentationCreationDate", "DA", "1" }, { 0x0070, 0x0083, "Presentation Creation Time", "PresentationCreationTime", "TM", "1" }, { 0x0070, 0x0084, "Content Creator's Name", "ContentCreatorName", "PN", "1" }, { 0x0070, 0x0086, "Content Creator's Identification Code Sequence", "ContentCreatorIdentificationCodeSequence", "SQ", "1" }, { 0x0070, 0x0087, "Alternate Content Description Sequence", "AlternateContentDescriptionSequence", "SQ", "1" }, { 0x0070, 0x0100, "Presentation Size Mode", "PresentationSizeMode", "CS", "1" }, { 0x0070, 0x0101, "Presentation Pixel Spacing", "PresentationPixelSpacing", "DS", "2" }, { 0x0070, 0x0102, "Presentation Pixel Aspect Ratio", "PresentationPixelAspectRatio", "IS", "2" }, { 0x0070, 0x0103, "Presentation Pixel Magnification Ratio", "PresentationPixelMagnificationRatio", "FL", "1" }, { 0x0070, 0x0207, "Graphic Group Label", "GraphicGroupLabel", "LO", "1" }, { 0x0070, 0x0208, "Graphic Group Description", "GraphicGroupDescription", "ST", "1" }, { 0x0070, 0x0209, "Compound Graphic Sequence", "CompoundGraphicSequence", "SQ", "1" }, { 0x0070, 0x0226, "Compound Graphic Instance ID", "CompoundGraphicInstanceID", "UL", "1" }, { 0x0070, 0x0227, "Font Name", "FontName", "LO", "1" }, { 0x0070, 0x0228, "Font Name Type", "FontNameType", "CS", "1" }, { 0x0070, 0x0229, "CSS Font Name", "CSSFontName", "LO", "1" }, { 0x0070, 0x0230, "Rotation Angle", "RotationAngle", "FD", "1" }, { 0x0070, 0x0231, "Text Style Sequence", "TextStyleSequence", "SQ", "1" }, { 0x0070, 0x0232, "Line Style Sequence", "LineStyleSequence", "SQ", "1" }, { 0x0070, 0x0233, "Fill Style Sequence", "FillStyleSequence", "SQ", "1" }, { 0x0070, 0x0234, "Graphic Group Sequence", "GraphicGroupSequence", "SQ", "1" }, { 0x0070, 0x0241, "Text Color CIELab Value", "TextColorCIELabValue", "US", "3" }, { 0x0070, 0x0242, "Horizontal Alignment", "HorizontalAlignment", "CS", "1" }, { 0x0070, 0x0243, "Vertical Alignment", "VerticalAlignment", "CS", "1" }, { 0x0070, 0x0244, "Shadow Style", "ShadowStyle", "CS", "1" }, { 0x0070, 0x0245, "Shadow Offset X", "ShadowOffsetX", "FL", "1" }, { 0x0070, 0x0246, "Shadow Offset Y", "ShadowOffsetY", "FL", "1" }, { 0x0070, 0x0247, "Shadow Color CIELab Value", "ShadowColorCIELabValue", "US", "3" }, { 0x0070, 0x0248, "Underlined", "Underlined", "CS", "1" }, { 0x0070, 0x0249, "Bold", "Bold", "CS", "1" }, { 0x0070, 0x0250, "Italic", "Italic", "CS", "1" }, { 0x0070, 0x0251, "Pattern On Color CIELab Value", "PatternOnColorCIELabValue", "US", "3" }, { 0x0070, 0x0252, "Pattern Off Color CIELab Value", "PatternOffColorCIELabValue", "US", "3" }, { 0x0070, 0x0253, "Line Thickness", "LineThickness", "FL", "1" }, { 0x0070, 0x0254, "Line Dashing Style", "LineDashingStyle", "CS", "1" }, { 0x0070, 0x0255, "Line Pattern", "LinePattern", "UL", "1" }, { 0x0070, 0x0256, "Fill Pattern", "FillPattern", "OB", "1" }, { 0x0070, 0x0257, "Fill Mode", "FillMode", "CS", "1" }, { 0x0070, 0x0258, "Shadow Opacity", "ShadowOpacity", "FL", "1" }, { 0x0070, 0x0261, "Gap Length", "GapLength", "FL", "1" }, { 0x0070, 0x0262, "Diameter of Visibility", "DiameterOfVisibility", "FL", "1" }, { 0x0070, 0x0273, "Rotation Point", "RotationPoint", "FL", "2" }, { 0x0070, 0x0274, "Tick Alignment", "TickAlignment", "CS", "1" }, { 0x0070, 0x0278, "Show Tick Label", "ShowTickLabel", "CS", "1" }, { 0x0070, 0x0279, "Tick Label Alignment", "TickLabelAlignment", "CS", "1" }, { 0x0070, 0x0282, "Compound Graphic Units", "CompoundGraphicUnits", "CS", "1" }, { 0x0070, 0x0284, "Pattern On Opacity", "PatternOnOpacity", "FL", "1" }, { 0x0070, 0x0285, "Pattern Off Opacity", "PatternOffOpacity", "FL", "1" }, { 0x0070, 0x0287, "Major Ticks Sequence", "MajorTicksSequence", "SQ", "1" }, { 0x0070, 0x0288, "Tick Position", "TickPosition", "FL", "1" }, { 0x0070, 0x0289, "Tick Label", "TickLabel", "SH", "1" }, { 0x0070, 0x0294, "Compound Graphic Type", "CompoundGraphicType", "CS", "1" }, { 0x0070, 0x0295, "Graphic Group ID", "GraphicGroupID", "UL", "1" }, { 0x0070, 0x0306, "Shape Type", "ShapeType", "CS", "1" }, { 0x0070, 0x0308, "Registration Sequence", "RegistrationSequence", "SQ", "1" }, { 0x0070, 0x0309, "Matrix Registration Sequence", "MatrixRegistrationSequence", "SQ", "1" }, { 0x0070, 0x030a, "Matrix Sequence", "MatrixSequence", "SQ", "1" }, { 0x0070, 0x030c, "Frame of Reference Transformation Matrix Type", "FrameOfReferenceTransformationMatrixType", "CS", "1" }, { 0x0070, 0x030d, "Registration Type Code Sequence", "RegistrationTypeCodeSequence", "SQ", "1" }, { 0x0070, 0x030f, "Fiducial Description", "FiducialDescription", "ST", "1" }, { 0x0070, 0x0310, "Fiducial Identifier", "FiducialIdentifier", "SH", "1" }, { 0x0070, 0x0311, "Fiducial Identifier Code Sequence", "FiducialIdentifierCodeSequence", "SQ", "1" }, { 0x0070, 0x0312, "Contour Uncertainty Radius", "ContourUncertaintyRadius", "FD", "1" }, { 0x0070, 0x0314, "Used Fiducials Sequence", "UsedFiducialsSequence", "SQ", "1" }, { 0x0070, 0x0318, "Graphic Coordinates Data Sequence", "GraphicCoordinatesDataSequence", "SQ", "1" }, { 0x0070, 0x031a, "Fiducial UID", "FiducialUID", "UI", "1" }, { 0x0070, 0x031c, "Fiducial Set Sequence", "FiducialSetSequence", "SQ", "1" }, { 0x0070, 0x031e, "Fiducial Sequence", "FiducialSequence", "SQ", "1" }, { 0x0070, 0x0401, "Graphic Layer Recommended Display CIELab Value", "GraphicLayerRecommendedDisplayCIELabValue", "US", "3" }, { 0x0070, 0x0402, "Blending Sequence", "BlendingSequence", "SQ", "1" }, { 0x0070, 0x0403, "Relative Opacity", "RelativeOpacity", "FL", "1" }, { 0x0070, 0x0404, "Referenced Spatial Registration Sequence", "ReferencedSpatialRegistrationSequence", "SQ", "1" }, { 0x0070, 0x0405, "Blending Position", "BlendingPosition", "CS", "1" }, { 0x0072, 0x0002, "Hanging Protocol Name", "HangingProtocolName", "SH", "1" }, { 0x0072, 0x0004, "Hanging Protocol Description", "HangingProtocolDescription", "LO", "1" }, { 0x0072, 0x0006, "Hanging Protocol Level", "HangingProtocolLevel", "CS", "1" }, { 0x0072, 0x0008, "Hanging Protocol Creator", "HangingProtocolCreator", "LO", "1" }, { 0x0072, 0x000a, "Hanging Protocol Creation DateTime", "HangingProtocolCreationDateTime", "DT", "1" }, { 0x0072, 0x000c, "Hanging Protocol Definition Sequence", "HangingProtocolDefinitionSequence", "SQ", "1" }, { 0x0072, 0x000e, "Hanging Protocol User Identification Code Sequence", "HangingProtocolUserIdentificationCodeSequence", "SQ", "1" }, { 0x0072, 0x0010, "Hanging Protocol User Group Name", "HangingProtocolUserGroupName", "LO", "1" }, { 0x0072, 0x0012, "Source Hanging Protocol Sequence", "SourceHangingProtocolSequence", "SQ", "1" }, { 0x0072, 0x0014, "Number of Priors Referenced", "NumberOfPriorsReferenced", "US", "1" }, { 0x0072, 0x0020, "Image Sets Sequence", "ImageSetsSequence", "SQ", "1" }, { 0x0072, 0x0022, "Image Set Selector Sequence", "ImageSetSelectorSequence", "SQ", "1" }, { 0x0072, 0x0024, "Image Set Selector Usage Flag", "ImageSetSelectorUsageFlag", "CS", "1" }, { 0x0072, 0x0026, "Selector Attribute", "SelectorAttribute", "AT", "1" }, { 0x0072, 0x0028, "Selector Value Number", "SelectorValueNumber", "US", "1" }, { 0x0072, 0x0030, "Time Based Image Sets Sequence", "TimeBasedImageSetsSequence", "SQ", "1" }, { 0x0072, 0x0032, "Image Set Number", "ImageSetNumber", "US", "1" }, { 0x0072, 0x0034, "Image Set Selector Category", "ImageSetSelectorCategory", "CS", "1" }, { 0x0072, 0x0038, "Relative Time", "RelativeTime", "US", "2" }, { 0x0072, 0x003a, "Relative Time Units", "RelativeTimeUnits", "CS", "1" }, { 0x0072, 0x003c, "Abstract Prior Value", "AbstractPriorValue", "SS", "2" }, { 0x0072, 0x003e, "Abstract Prior Code Sequence", "AbstractPriorCodeSequence", "SQ", "1" }, { 0x0072, 0x0040, "Image Set Label", "ImageSetLabel", "LO", "1" }, { 0x0072, 0x0050, "Selector Attribute VR", "SelectorAttributeVR", "CS", "1" }, { 0x0072, 0x0052, "Selector Sequence Pointer", "SelectorSequencePointer", "AT", "1-n" }, { 0x0072, 0x0054, "Selector Sequence Pointer Private Creator", "SelectorSequencePointerPrivateCreator", "LO", "1-n" }, { 0x0072, 0x0056, "Selector Attribute Private Creator", "SelectorAttributePrivateCreator", "LO", "1" }, { 0x0072, 0x0060, "Selector AT Value", "SelectorATValue", "AT", "1-n" }, { 0x0072, 0x0062, "Selector CS Value", "SelectorCSValue", "CS", "1-n" }, { 0x0072, 0x0064, "Selector IS Value", "SelectorISValue", "IS", "1-n" }, { 0x0072, 0x0066, "Selector LO Value", "SelectorLOValue", "LO", "1-n" }, { 0x0072, 0x0068, "Selector LT Value", "SelectorLTValue", "LT", "1" }, { 0x0072, 0x006a, "Selector PN Value", "SelectorPNValue", "PN", "1-n" }, { 0x0072, 0x006c, "Selector SH Value", "SelectorSHValue", "SH", "1-n" }, { 0x0072, 0x006e, "Selector ST Value", "SelectorSTValue", "ST", "1" }, { 0x0072, 0x0070, "Selector UT Value", "SelectorUTValue", "UT", "1" }, { 0x0072, 0x0072, "Selector DS Value", "SelectorDSValue", "DS", "1-n" }, { 0x0072, 0x0074, "Selector FD Value", "SelectorFDValue", "FD", "1-n" }, { 0x0072, 0x0076, "Selector FL Value", "SelectorFLValue", "FL", "1-n" }, { 0x0072, 0x0078, "Selector UL Value", "SelectorULValue", "UL", "1-n" }, { 0x0072, 0x007a, "Selector US Value", "SelectorUSValue", "US", "1-n" }, { 0x0072, 0x007c, "Selector SL Value", "SelectorSLValue", "SL", "1-n" }, { 0x0072, 0x007e, "Selector SS Value", "SelectorSSValue", "SS", "1-n" }, { 0x0072, 0x007f, "Selector UI Value", "SelectorUIValue", "UI", "1-n" }, { 0x0072, 0x0080, "Selector Code Sequence Value", "SelectorCodeSequenceValue", "SQ", "1" }, { 0x0072, 0x0100, "Number of Screens", "NumberOfScreens", "US", "1" }, { 0x0072, 0x0102, "Nominal Screen Definition Sequence", "NominalScreenDefinitionSequence", "SQ", "1" }, { 0x0072, 0x0104, "Number of Vertical Pixels", "NumberOfVerticalPixels", "US", "1" }, { 0x0072, 0x0106, "Number of Horizontal Pixels", "NumberOfHorizontalPixels", "US", "1" }, { 0x0072, 0x0108, "Display Environment Spatial Position", "DisplayEnvironmentSpatialPosition", "FD", "4" }, { 0x0072, 0x010a, "Screen Minimum Grayscale Bit Depth", "ScreenMinimumGrayscaleBitDepth", "US", "1" }, { 0x0072, 0x010c, "Screen Minimum Color Bit Depth", "ScreenMinimumColorBitDepth", "US", "1" }, { 0x0072, 0x010e, "Application Maximum Repaint Time", "ApplicationMaximumRepaintTime", "US", "1" }, { 0x0072, 0x0200, "Display Sets Sequence", "DisplaySetsSequence", "SQ", "1" }, { 0x0072, 0x0202, "Display Set Number", "DisplaySetNumber", "US", "1" }, { 0x0072, 0x0203, "Display Set Label", "DisplaySetLabel", "LO", "1" }, { 0x0072, 0x0204, "Display Set Presentation Group", "DisplaySetPresentationGroup", "US", "1" }, { 0x0072, 0x0206, "Display Set Presentation Group Description", "DisplaySetPresentationGroupDescription", "LO", "1" }, { 0x0072, 0x0208, "Partial Data Display Handling", "PartialDataDisplayHandling", "CS", "1" }, { 0x0072, 0x0210, "Synchronized Scrolling Sequence", "SynchronizedScrollingSequence", "SQ", "1" }, { 0x0072, 0x0212, "Display Set Scrolling Group", "DisplaySetScrollingGroup", "US", "2-n" }, { 0x0072, 0x0214, "Navigation Indicator Sequence", "NavigationIndicatorSequence", "SQ", "1" }, { 0x0072, 0x0216, "Navigation Display Set", "NavigationDisplaySet", "US", "1" }, { 0x0072, 0x0218, "Reference Display Sets", "ReferenceDisplaySets", "US", "1-n" }, { 0x0072, 0x0300, "Image Boxes Sequence", "ImageBoxesSequence", "SQ", "1" }, { 0x0072, 0x0302, "Image Box Number", "ImageBoxNumber", "US", "1" }, { 0x0072, 0x0304, "Image Box Layout Type", "ImageBoxLayoutType", "CS", "1" }, { 0x0072, 0x0306, "Image Box Tile Horizontal Dimension", "ImageBoxTileHorizontalDimension", "US", "1" }, { 0x0072, 0x0308, "Image Box Tile Vertical Dimension", "ImageBoxTileVerticalDimension", "US", "1" }, { 0x0072, 0x0310, "Image Box Scroll Direction", "ImageBoxScrollDirection", "CS", "1" }, { 0x0072, 0x0312, "Image Box Small Scroll Type", "ImageBoxSmallScrollType", "CS", "1" }, { 0x0072, 0x0314, "Image Box Small Scroll Amount", "ImageBoxSmallScrollAmount", "US", "1" }, { 0x0072, 0x0316, "Image Box Large Scroll Type", "ImageBoxLargeScrollType", "CS", "1" }, { 0x0072, 0x0318, "Image Box Large Scroll Amount", "ImageBoxLargeScrollAmount", "US", "1" }, { 0x0072, 0x0320, "Image Box Overlap Priority", "ImageBoxOverlapPriority", "US", "1" }, { 0x0072, 0x0330, "Cine Relative to Real-Time", "CineRelativeToRealTime", "FD", "1" }, { 0x0072, 0x0400, "Filter Operations Sequence", "FilterOperationsSequence", "SQ", "1" }, { 0x0072, 0x0402, "Filter-by Category", "FilterByCategory", "CS", "1" }, { 0x0072, 0x0404, "Filter-by Attribute Presence", "FilterByAttributePresence", "CS", "1" }, { 0x0072, 0x0406, "Filter-by Operator", "FilterByOperator", "CS", "1" }, { 0x0072, 0x0420, "Structured Display Background CIELab Value", "StructuredDisplayBackgroundCIELabValue", "US", "3" }, { 0x0072, 0x0421, "Empty Image Box CIELab Value", "EmptyImageBoxCIELabValue", "US", "3" }, { 0x0072, 0x0422, "Structured Display Image Box Sequence", "StructuredDisplayImageBoxSequence", "SQ", "1" }, { 0x0072, 0x0424, "Structured Display Text Box Sequence", "StructuredDisplayTextBoxSequence", "SQ", "1" }, { 0x0072, 0x0427, "Referenced First Frame Sequence", "ReferencedFirstFrameSequence", "SQ", "1" }, { 0x0072, 0x0430, "Image Box Synchronization Sequence", "ImageBoxSynchronizationSequence", "SQ", "1" }, { 0x0072, 0x0432, "Synchronized Image Box List", "SynchronizedImageBoxList", "US", "2-n" }, { 0x0072, 0x0434, "Type of Synchronization", "TypeOfSynchronization", "CS", "1" }, { 0x0072, 0x0500, "Blending Operation Type", "BlendingOperationType", "CS", "1" }, { 0x0072, 0x0510, "Reformatting Operation Type", "ReformattingOperationType", "CS", "1" }, { 0x0072, 0x0512, "Reformatting Thickness", "ReformattingThickness", "FD", "1" }, { 0x0072, 0x0514, "Reformatting Interval", "ReformattingInterval", "FD", "1" }, { 0x0072, 0x0516, "Reformatting Operation Initial View Direction", "ReformattingOperationInitialViewDirection", "CS", "1" }, { 0x0072, 0x0520, "3D Rendering Type", "ThreeDRenderingType", "CS", "1-n" }, { 0x0072, 0x0600, "Sorting Operations Sequence", "SortingOperationsSequence", "SQ", "1" }, { 0x0072, 0x0602, "Sort-by Category", "SortByCategory", "CS", "1" }, { 0x0072, 0x0604, "Sorting Direction", "SortingDirection", "CS", "1" }, { 0x0072, 0x0700, "Display Set Patient Orientation", "DisplaySetPatientOrientation", "CS", "2" }, { 0x0072, 0x0702, "VOI Type", "VOIType", "CS", "1" }, { 0x0072, 0x0704, "Pseudo-Color Type", "PseudoColorType", "CS", "1" }, { 0x0072, 0x0705, "Pseudo-Color Palette Instance Reference Sequence", "PseudoColorPaletteInstanceReferenceSequence", "SQ", "1" }, { 0x0072, 0x0706, "Show Grayscale Inverted", "ShowGrayscaleInverted", "CS", "1" }, { 0x0072, 0x0710, "Show Image True Size Flag", "ShowImageTrueSizeFlag", "CS", "1" }, { 0x0072, 0x0712, "Show Graphic Annotation Flag", "ShowGraphicAnnotationFlag", "CS", "1" }, { 0x0072, 0x0714, "Show Patient Demographics Flag", "ShowPatientDemographicsFlag", "CS", "1" }, { 0x0072, 0x0716, "Show Acquisition Techniques Flag", "ShowAcquisitionTechniquesFlag", "CS", "1" }, { 0x0072, 0x0717, "Display Set Horizontal Justification", "DisplaySetHorizontalJustification", "CS", "1" }, { 0x0072, 0x0718, "Display Set Vertical Justification", "DisplaySetVerticalJustification", "CS", "1" }, { 0x0074, 0x0120, "Continuation Start Meterset", "ContinuationStartMeterset", "FD", "1" }, { 0x0074, 0x0121, "Continuation End Meterset", "ContinuationEndMeterset", "FD", "1" }, { 0x0074, 0x1000, "Procedure Step State", "ProcedureStepState", "CS", "1" }, { 0x0074, 0x1002, "Procedure Step Progress Information Sequence", "ProcedureStepProgressInformationSequence", "SQ", "1" }, { 0x0074, 0x1004, "Procedure Step Progress", "ProcedureStepProgress", "DS", "1" }, { 0x0074, 0x1006, "Procedure Step Progress Description", "ProcedureStepProgressDescription", "ST", "1" }, { 0x0074, 0x1008, "Procedure Step Communications URI Sequence", "ProcedureStepCommunicationsURISequence", "SQ", "1" }, { 0x0074, 0x100a, "Contact URI", "ContactURI", "UR", "1" }, { 0x0074, 0x100c, "Contact Display Name", "ContactDisplayName", "LO", "1" }, { 0x0074, 0x100e, "Procedure Step Discontinuation Reason Code Sequence", "ProcedureStepDiscontinuationReasonCodeSequence", "SQ", "1" }, { 0x0074, 0x1020, "Beam Task Sequence", "BeamTaskSequence", "SQ", "1" }, { 0x0074, 0x1022, "Beam Task Type", "BeamTaskType", "CS", "1" }, { 0x0074, 0x1024, "Beam Order Index (Trial)", "BeamOrderIndexTrial", "IS", "1" }, { 0x0074, 0x1025, "Autosequence Flag", "AutosequenceFlag", "CS", "1" }, { 0x0074, 0x1026, "Table Top Vertical Adjusted Position", "TableTopVerticalAdjustedPosition", "FD", "1" }, { 0x0074, 0x1027, "Table Top Longitudinal Adjusted Position", "TableTopLongitudinalAdjustedPosition", "FD", "1" }, { 0x0074, 0x1028, "Table Top Lateral Adjusted Position", "TableTopLateralAdjustedPosition", "FD", "1" }, { 0x0074, 0x102a, "Patient Support Adjusted Angle", "PatientSupportAdjustedAngle", "FD", "1" }, { 0x0074, 0x102b, "Table Top Eccentric Adjusted Angle", "TableTopEccentricAdjustedAngle", "FD", "1" }, { 0x0074, 0x102c, "Table Top Pitch Adjusted Angle", "TableTopPitchAdjustedAngle", "FD", "1" }, { 0x0074, 0x102d, "Table Top Roll Adjusted Angle", "TableTopRollAdjustedAngle", "FD", "1" }, { 0x0074, 0x1030, "Delivery Verification Image Sequence", "DeliveryVerificationImageSequence", "SQ", "1" }, { 0x0074, 0x1032, "Verification Image Timing", "VerificationImageTiming", "CS", "1" }, { 0x0074, 0x1034, "Double Exposure Flag", "DoubleExposureFlag", "CS", "1" }, { 0x0074, 0x1036, "Double Exposure Ordering", "DoubleExposureOrdering", "CS", "1" }, { 0x0074, 0x1038, "Double Exposure Meterset (Trial)", "DoubleExposureMetersetTrial", "DS", "1" }, { 0x0074, 0x103a, "Double Exposure Field Delta (Trial)", "DoubleExposureFieldDeltaTrial", "DS", "4" }, { 0x0074, 0x1040, "Related Reference RT Image Sequence", "RelatedReferenceRTImageSequence", "SQ", "1" }, { 0x0074, 0x1042, "General Machine Verification Sequence", "GeneralMachineVerificationSequence", "SQ", "1" }, { 0x0074, 0x1044, "Conventional Machine Verification Sequence", "ConventionalMachineVerificationSequence", "SQ", "1" }, { 0x0074, 0x1046, "Ion Machine Verification Sequence", "IonMachineVerificationSequence", "SQ", "1" }, { 0x0074, 0x1048, "Failed Attributes Sequence", "FailedAttributesSequence", "SQ", "1" }, { 0x0074, 0x104a, "Overridden Attributes Sequence", "OverriddenAttributesSequence", "SQ", "1" }, { 0x0074, 0x104c, "Conventional Control Point Verification Sequence", "ConventionalControlPointVerificationSequence", "SQ", "1" }, { 0x0074, 0x104e, "Ion Control Point Verification Sequence", "IonControlPointVerificationSequence", "SQ", "1" }, { 0x0074, 0x1050, "Attribute Occurrence Sequence", "AttributeOccurrenceSequence", "SQ", "1" }, { 0x0074, 0x1052, "Attribute Occurrence Pointer", "AttributeOccurrencePointer", "AT", "1" }, { 0x0074, 0x1054, "Attribute Item Selector", "AttributeItemSelector", "UL", "1" }, { 0x0074, 0x1056, "Attribute Occurrence Private Creator", "AttributeOccurrencePrivateCreator", "LO", "1" }, { 0x0074, 0x1057, "Selector Sequence Pointer Items", "SelectorSequencePointerItems", "IS", "1-n" }, { 0x0074, 0x1200, "Scheduled Procedure Step Priority", "ScheduledProcedureStepPriority", "CS", "1" }, { 0x0074, 0x1202, "Worklist Label", "WorklistLabel", "LO", "1" }, { 0x0074, 0x1204, "Procedure Step Label", "ProcedureStepLabel", "LO", "1" }, { 0x0074, 0x1210, "Scheduled Processing Parameters Sequence", "ScheduledProcessingParametersSequence", "SQ", "1" }, { 0x0074, 0x1212, "Performed Processing Parameters Sequence", "PerformedProcessingParametersSequence", "SQ", "1" }, { 0x0074, 0x1216, "Unified Procedure Step Performed Procedure Sequence", "UnifiedProcedureStepPerformedProcedureSequence", "SQ", "1" }, { 0x0074, 0x1220, "Related Procedure Step Sequence", "RelatedProcedureStepSequence", "SQ", "1" }, { 0x0074, 0x1222, "Procedure Step Relationship Type", "ProcedureStepRelationshipType", "LO", "1" }, { 0x0074, 0x1224, "Replaced Procedure Step Sequence", "ReplacedProcedureStepSequence", "SQ", "1" }, { 0x0074, 0x1230, "Deletion Lock", "DeletionLock", "LO", "1" }, { 0x0074, 0x1234, "Receiving AE", "ReceivingAE", "AE", "1" }, { 0x0074, 0x1236, "Requesting AE", "RequestingAE", "AE", "1" }, { 0x0074, 0x1238, "Reason for Cancellation", "ReasonForCancellation", "LT", "1" }, { 0x0074, 0x1242, "SCP Status", "SCPStatus", "CS", "1" }, { 0x0074, 0x1244, "Subscription List Status", "SubscriptionListStatus", "CS", "1" }, { 0x0074, 0x1246, "Unified Procedure Step List Status", "UnifiedProcedureStepListStatus", "CS", "1" }, { 0x0074, 0x1324, "Beam Order Index", "BeamOrderIndex", "UL", "1" }, { 0x0074, 0x1338, "Double Exposure Meterset", "DoubleExposureMeterset", "FD", "1" }, { 0x0074, 0x133a, "Double Exposure Field Delta", "DoubleExposureFieldDelta", "FD", "4" }, { 0x0076, 0x0001, "Implant Assembly Template Name", "ImplantAssemblyTemplateName", "LO", "1" }, { 0x0076, 0x0003, "Implant Assembly Template Issuer", "ImplantAssemblyTemplateIssuer", "LO", "1" }, { 0x0076, 0x0006, "Implant Assembly Template Version", "ImplantAssemblyTemplateVersion", "LO", "1" }, { 0x0076, 0x0008, "Replaced Implant Assembly Template Sequence", "ReplacedImplantAssemblyTemplateSequence", "SQ", "1" }, { 0x0076, 0x000a, "Implant Assembly Template Type", "ImplantAssemblyTemplateType", "CS", "1" }, { 0x0076, 0x000c, "Original Implant Assembly Template Sequence", "OriginalImplantAssemblyTemplateSequence", "SQ", "1" }, { 0x0076, 0x000e, "Derivation Implant Assembly Template Sequence", "DerivationImplantAssemblyTemplateSequence", "SQ", "1" }, { 0x0076, 0x0010, "Implant Assembly Template Target Anatomy Sequence", "ImplantAssemblyTemplateTargetAnatomySequence", "SQ", "1" }, { 0x0076, 0x0020, "Procedure Type Code Sequence", "ProcedureTypeCodeSequence", "SQ", "1" }, { 0x0076, 0x0030, "Surgical Technique", "SurgicalTechnique", "LO", "1" }, { 0x0076, 0x0032, "Component Types Sequence", "ComponentTypesSequence", "SQ", "1" }, { 0x0076, 0x0034, "Component Type Code Sequence", "ComponentTypeCodeSequence", "CS", "1" }, { 0x0076, 0x0036, "Exclusive Component Type", "ExclusiveComponentType", "CS", "1" }, { 0x0076, 0x0038, "Mandatory Component Type", "MandatoryComponentType", "CS", "1" }, { 0x0076, 0x0040, "Component Sequence", "ComponentSequence", "SQ", "1" }, { 0x0076, 0x0055, "Component ID", "ComponentID", "US", "1" }, { 0x0076, 0x0060, "Component Assembly Sequence", "ComponentAssemblySequence", "SQ", "1" }, { 0x0076, 0x0070, "Component 1 Referenced ID", "Component1ReferencedID", "US", "1" }, { 0x0076, 0x0080, "Component 1 Referenced Mating Feature Set ID", "Component1ReferencedMatingFeatureSetID", "US", "1" }, { 0x0076, 0x0090, "Component 1 Referenced Mating Feature ID", "Component1ReferencedMatingFeatureID", "US", "1" }, { 0x0076, 0x00a0, "Component 2 Referenced ID", "Component2ReferencedID", "US", "1" }, { 0x0076, 0x00b0, "Component 2 Referenced Mating Feature Set ID", "Component2ReferencedMatingFeatureSetID", "US", "1" }, { 0x0076, 0x00c0, "Component 2 Referenced Mating Feature ID", "Component2ReferencedMatingFeatureID", "US", "1" }, { 0x0078, 0x0001, "Implant Template Group Name", "ImplantTemplateGroupName", "LO", "1" }, { 0x0078, 0x0010, "Implant Template Group Description", "ImplantTemplateGroupDescription", "ST", "1" }, { 0x0078, 0x0020, "Implant Template Group Issuer", "ImplantTemplateGroupIssuer", "LO", "1" }, { 0x0078, 0x0024, "Implant Template Group Version", "ImplantTemplateGroupVersion", "LO", "1" }, { 0x0078, 0x0026, "Replaced Implant Template Group Sequence", "ReplacedImplantTemplateGroupSequence", "SQ", "1" }, { 0x0078, 0x0028, "Implant Template Group Target Anatomy Sequence", "ImplantTemplateGroupTargetAnatomySequence", "SQ", "1" }, { 0x0078, 0x002a, "Implant Template Group Members Sequence", "ImplantTemplateGroupMembersSequence", "SQ", "1" }, { 0x0078, 0x002e, "Implant Template Group Member ID", "ImplantTemplateGroupMemberID", "US", "1" }, { 0x0078, 0x0050, "3D Implant Template Group Member Matching Point", "ThreeDImplantTemplateGroupMemberMatchingPoint", "FD", "3" }, { 0x0078, 0x0060, "3D Implant Template Group Member Matching Axes", "ThreeDImplantTemplateGroupMemberMatchingAxes", "FD", "9" }, { 0x0078, 0x0070, "Implant Template Group Member Matching 2D Coordinates Sequence", "ImplantTemplateGroupMemberMatching2DCoordinatesSequence", "SQ", "1" }, { 0x0078, 0x0090, "2D Implant Template Group Member Matching Point", "TwoDImplantTemplateGroupMemberMatchingPoint", "FD", "2" }, { 0x0078, 0x00a0, "2D Implant Template Group Member Matching Axes", "TwoDImplantTemplateGroupMemberMatchingAxes", "FD", "4" }, { 0x0078, 0x00b0, "Implant Template Group Variation Dimension Sequence", "ImplantTemplateGroupVariationDimensionSequence", "SQ", "1" }, { 0x0078, 0x00b2, "Implant Template Group Variation Dimension Name", "ImplantTemplateGroupVariationDimensionName", "LO", "1" }, { 0x0078, 0x00b4, "Implant Template Group Variation Dimension Rank Sequence", "ImplantTemplateGroupVariationDimensionRankSequence", "SQ", "1" }, { 0x0078, 0x00b6, "Referenced Implant Template Group Member ID", "ReferencedImplantTemplateGroupMemberID", "US", "1" }, { 0x0078, 0x00b8, "Implant Template Group Variation Dimension Rank", "ImplantTemplateGroupVariationDimensionRank", "US", "1" }, { 0x0080, 0x0001, "Surface Scan Acquisition Type Code Sequence", "SurfaceScanAcquisitionTypeCodeSequence", "SQ", "1" }, { 0x0080, 0x0002, "Surface Scan Mode Code Sequence", "SurfaceScanModeCodeSequence", "SQ", "1" }, { 0x0080, 0x0003, "Registration Method Code Sequence", "RegistrationMethodCodeSequence", "SQ", "1" }, { 0x0080, 0x0004, "Shot Duration Time", "ShotDurationTime", "FD", "1" }, { 0x0080, 0x0005, "Shot Offset Time", "ShotOffsetTime", "FD", "1" }, { 0x0080, 0x0006, "Surface Point Presentation Value Data", "SurfacePointPresentationValueData", "US", "1-n" }, { 0x0080, 0x0007, "Surface Point Color CIELab Value Data", "SurfacePointColorCIELabValueData", "US", "3-3n" }, { 0x0080, 0x0008, "UV Mapping Sequence", "UVMappingSequence", "SQ", "1" }, { 0x0080, 0x0009, "Texture Label", "TextureLabel", "SH", "1" }, { 0x0080, 0x0010, "U Value Data", "UValueData", "OF", "1-n" }, { 0x0080, 0x0011, "V Value Data", "VValueData", "OF", "1-n" }, { 0x0080, 0x0012, "Referenced Texture Sequence", "ReferencedTextureSequence", "SQ", "1" }, { 0x0080, 0x0013, "Referenced Surface Data Sequence", "ReferencedSurfaceDataSequence", "SQ", "1" }, { 0x0088, 0x0130, "Storage Media File-set ID", "StorageMediaFileSetID", "SH", "1" }, { 0x0088, 0x0140, "Storage Media File-set UID", "StorageMediaFileSetUID", "UI", "1" }, { 0x0088, 0x0200, "Icon Image Sequence", "IconImageSequence", "SQ", "1" }, { 0x0088, 0x0904, "Topic Title", "TopicTitle", "LO", "1" }, { 0x0088, 0x0906, "Topic Subject", "TopicSubject", "ST", "1" }, { 0x0088, 0x0910, "Topic Author", "TopicAuthor", "LO", "1" }, { 0x0088, 0x0912, "Topic Keywords", "TopicKeywords", "LO", "1-32" }, { 0x0100, 0x0410, "SOP Instance Status", "SOPInstanceStatus", "CS", "1" }, { 0x0100, 0x0420, "SOP Authorization DateTime", "SOPAuthorizationDateTime", "DT", "1" }, { 0x0100, 0x0424, "SOP Authorization Comment", "SOPAuthorizationComment", "LT", "1" }, { 0x0100, 0x0426, "Authorization Equipment Certification Number", "AuthorizationEquipmentCertificationNumber", "LO", "1" }, { 0x0400, 0x0005, "MAC ID Number", "MACIDNumber", "US", "1" }, { 0x0400, 0x0010, "MAC Calculation Transfer Syntax UID", "MACCalculationTransferSyntaxUID", "UI", "1" }, { 0x0400, 0x0015, "MAC Algorithm", "MACAlgorithm", "CS", "1" }, { 0x0400, 0x0020, "Data Elements Signed", "DataElementsSigned", "AT", "1-n" }, { 0x0400, 0x0100, "Digital Signature UID", "DigitalSignatureUID", "UI", "1" }, { 0x0400, 0x0105, "Digital Signature DateTime", "DigitalSignatureDateTime", "DT", "1" }, { 0x0400, 0x0110, "Certificate Type", "CertificateType", "CS", "1" }, { 0x0400, 0x0115, "Certificate of Signer", "CertificateOfSigner", "OB", "1" }, { 0x0400, 0x0120, "Signature", "Signature", "OB", "1" }, { 0x0400, 0x0305, "Certified Timestamp Type", "CertifiedTimestampType", "CS", "1" }, { 0x0400, 0x0310, "Certified Timestamp", "CertifiedTimestamp", "OB", "1" }, { 0x0400, 0x0401, "Digital Signature Purpose Code Sequence", "DigitalSignaturePurposeCodeSequence", "SQ", "1" }, { 0x0400, 0x0402, "Referenced Digital Signature Sequence", "ReferencedDigitalSignatureSequence", "SQ", "1" }, { 0x0400, 0x0403, "Referenced SOP Instance MAC Sequence", "ReferencedSOPInstanceMACSequence", "SQ", "1" }, { 0x0400, 0x0404, "MAC", "MAC", "OB", "1" }, { 0x0400, 0x0500, "Encrypted Attributes Sequence", "EncryptedAttributesSequence", "SQ", "1" }, { 0x0400, 0x0510, "Encrypted Content Transfer Syntax UID", "EncryptedContentTransferSyntaxUID", "UI", "1" }, { 0x0400, 0x0520, "Encrypted Content", "EncryptedContent", "OB", "1" }, { 0x0400, 0x0550, "Modified Attributes Sequence", "ModifiedAttributesSequence", "SQ", "1" }, { 0x0400, 0x0561, "Original Attributes Sequence", "OriginalAttributesSequence", "SQ", "1" }, { 0x0400, 0x0562, "Attribute Modification DateTime", "AttributeModificationDateTime", "DT", "1" }, { 0x0400, 0x0563, "Modifying System", "ModifyingSystem", "LO", "1" }, { 0x0400, 0x0564, "Source of Previous Values", "SourceOfPreviousValues", "LO", "1" }, { 0x0400, 0x0565, "Reason for the Attribute Modification", "ReasonForTheAttributeModification", "CS", "1" }, { 0x2000, 0x0010, "Number of Copies", "NumberOfCopies", "IS", "1" }, { 0x2000, 0x001e, "Printer Configuration Sequence", "PrinterConfigurationSequence", "SQ", "1" }, { 0x2000, 0x0020, "Print Priority", "PrintPriority", "CS", "1" }, { 0x2000, 0x0030, "Medium Type", "MediumType", "CS", "1" }, { 0x2000, 0x0040, "Film Destination", "FilmDestination", "CS", "1" }, { 0x2000, 0x0050, "Film Session Label", "FilmSessionLabel", "LO", "1" }, { 0x2000, 0x0060, "Memory Allocation", "MemoryAllocation", "IS", "1" }, { 0x2000, 0x0061, "Maximum Memory Allocation", "MaximumMemoryAllocation", "IS", "1" }, { 0x2000, 0x0062, "Color Image Printing Flag", "ColorImagePrintingFlag", "CS", "1" }, { 0x2000, 0x0063, "Collation Flag", "CollationFlag", "CS", "1" }, { 0x2000, 0x0065, "Annotation Flag", "AnnotationFlag", "CS", "1" }, { 0x2000, 0x0067, "Image Overlay Flag", "ImageOverlayFlag", "CS", "1" }, { 0x2000, 0x0069, "Presentation LUT Flag", "PresentationLUTFlag", "CS", "1" }, { 0x2000, 0x006a, "Image Box Presentation LUT Flag", "ImageBoxPresentationLUTFlag", "CS", "1" }, { 0x2000, 0x00a0, "Memory Bit Depth", "MemoryBitDepth", "US", "1" }, { 0x2000, 0x00a1, "Printing Bit Depth", "PrintingBitDepth", "US", "1" }, { 0x2000, 0x00a2, "Media Installed Sequence", "MediaInstalledSequence", "SQ", "1" }, { 0x2000, 0x00a4, "Other Media Available Sequence", "OtherMediaAvailableSequence", "SQ", "1" }, { 0x2000, 0x00a8, "Supported Image Display Formats Sequence", "SupportedImageDisplayFormatsSequence", "SQ", "1" }, { 0x2000, 0x0500, "Referenced Film Box Sequence", "ReferencedFilmBoxSequence", "SQ", "1" }, { 0x2000, 0x0510, "Referenced Stored Print Sequence", "ReferencedStoredPrintSequence", "SQ", "1" }, { 0x2010, 0x0010, "Image Display Format", "ImageDisplayFormat", "ST", "1" }, { 0x2010, 0x0030, "Annotation Display Format ID", "AnnotationDisplayFormatID", "CS", "1" }, { 0x2010, 0x0040, "Film Orientation", "FilmOrientation", "CS", "1" }, { 0x2010, 0x0050, "Film Size ID", "FilmSizeID", "CS", "1" }, { 0x2010, 0x0052, "Printer Resolution ID", "PrinterResolutionID", "CS", "1" }, { 0x2010, 0x0054, "Default Printer Resolution ID", "DefaultPrinterResolutionID", "CS", "1" }, { 0x2010, 0x0060, "Magnification Type", "MagnificationType", "CS", "1" }, { 0x2010, 0x0080, "Smoothing Type", "SmoothingType", "CS", "1" }, { 0x2010, 0x00a6, "Default Magnification Type", "DefaultMagnificationType", "CS", "1" }, { 0x2010, 0x00a7, "Other Magnification Types Available", "OtherMagnificationTypesAvailable", "CS", "1-n" }, { 0x2010, 0x00a8, "Default Smoothing Type", "DefaultSmoothingType", "CS", "1" }, { 0x2010, 0x00a9, "Other Smoothing Types Available", "OtherSmoothingTypesAvailable", "CS", "1-n" }, { 0x2010, 0x0100, "Border Density", "BorderDensity", "CS", "1" }, { 0x2010, 0x0110, "Empty Image Density", "EmptyImageDensity", "CS", "1" }, { 0x2010, 0x0120, "Min Density", "MinDensity", "US", "1" }, { 0x2010, 0x0130, "Max Density", "MaxDensity", "US", "1" }, { 0x2010, 0x0140, "Trim", "Trim", "CS", "1" }, { 0x2010, 0x0150, "Configuration Information", "ConfigurationInformation", "ST", "1" }, { 0x2010, 0x0152, "Configuration Information Description", "ConfigurationInformationDescription", "LT", "1" }, { 0x2010, 0x0154, "Maximum Collated Films", "MaximumCollatedFilms", "IS", "1" }, { 0x2010, 0x015e, "Illumination", "Illumination", "US", "1" }, { 0x2010, 0x0160, "Reflected Ambient Light", "ReflectedAmbientLight", "US", "1" }, { 0x2010, 0x0376, "Printer Pixel Spacing", "PrinterPixelSpacing", "DS", "2" }, { 0x2010, 0x0500, "Referenced Film Session Sequence", "ReferencedFilmSessionSequence", "SQ", "1" }, { 0x2010, 0x0510, "Referenced Image Box Sequence", "ReferencedImageBoxSequence", "SQ", "1" }, { 0x2010, 0x0520, "Referenced Basic Annotation Box Sequence", "ReferencedBasicAnnotationBoxSequence", "SQ", "1" }, { 0x2020, 0x0010, "Image Box Position", "ImageBoxPosition", "US", "1" }, { 0x2020, 0x0020, "Polarity", "Polarity", "CS", "1" }, { 0x2020, 0x0030, "Requested Image Size", "RequestedImageSize", "DS", "1" }, { 0x2020, 0x0040, "Requested Decimate/Crop Behavior", "RequestedDecimateCropBehavior", "CS", "1" }, { 0x2020, 0x0050, "Requested Resolution ID", "RequestedResolutionID", "CS", "1" }, { 0x2020, 0x00a0, "Requested Image Size Flag", "RequestedImageSizeFlag", "CS", "1" }, { 0x2020, 0x00a2, "Decimate/Crop Result", "DecimateCropResult", "CS", "1" }, { 0x2020, 0x0110, "Basic Grayscale Image Sequence", "BasicGrayscaleImageSequence", "SQ", "1" }, { 0x2020, 0x0111, "Basic Color Image Sequence", "BasicColorImageSequence", "SQ", "1" }, { 0x2020, 0x0130, "Referenced Image Overlay Box Sequence", "ReferencedImageOverlayBoxSequence", "SQ", "1" }, { 0x2020, 0x0140, "Referenced VOI LUT Box Sequence", "ReferencedVOILUTBoxSequence", "SQ", "1" }, { 0x2030, 0x0010, "Annotation Position", "AnnotationPosition", "US", "1" }, { 0x2030, 0x0020, "Text String", "TextString", "LO", "1" }, { 0x2040, 0x0010, "Referenced Overlay Plane Sequence", "ReferencedOverlayPlaneSequence", "SQ", "1" }, { 0x2040, 0x0011, "Referenced Overlay Plane Groups", "ReferencedOverlayPlaneGroups", "US", "1-99" }, { 0x2040, 0x0020, "Overlay Pixel Data Sequence", "OverlayPixelDataSequence", "SQ", "1" }, { 0x2040, 0x0060, "Overlay Magnification Type", "OverlayMagnificationType", "CS", "1" }, { 0x2040, 0x0070, "Overlay Smoothing Type", "OverlaySmoothingType", "CS", "1" }, { 0x2040, 0x0072, "Overlay or Image Magnification", "OverlayOrImageMagnification", "CS", "1" }, { 0x2040, 0x0074, "Magnify to Number of Columns", "MagnifyToNumberOfColumns", "US", "1" }, { 0x2040, 0x0080, "Overlay Foreground Density", "OverlayForegroundDensity", "CS", "1" }, { 0x2040, 0x0082, "Overlay Background Density", "OverlayBackgroundDensity", "CS", "1" }, { 0x2040, 0x0090, "Overlay Mode", "OverlayMode", "CS", "1" }, { 0x2040, 0x0100, "Threshold Density", "ThresholdDensity", "CS", "1" }, { 0x2040, 0x0500, "Referenced Image Box Sequence (Retired)", "ReferencedImageBoxSequenceRetired", "SQ", "1" }, { 0x2050, 0x0010, "Presentation LUT Sequence", "PresentationLUTSequence", "SQ", "1" }, { 0x2050, 0x0020, "Presentation LUT Shape", "PresentationLUTShape", "CS", "1" }, { 0x2050, 0x0500, "Referenced Presentation LUT Sequence", "ReferencedPresentationLUTSequence", "SQ", "1" }, { 0x2100, 0x0010, "Print Job ID", "PrintJobID", "SH", "1" }, { 0x2100, 0x0020, "Execution Status", "ExecutionStatus", "CS", "1" }, { 0x2100, 0x0030, "Execution Status Info", "ExecutionStatusInfo", "CS", "1" }, { 0x2100, 0x0040, "Creation Date", "CreationDate", "DA", "1" }, { 0x2100, 0x0050, "Creation Time", "CreationTime", "TM", "1" }, { 0x2100, 0x0070, "Originator", "Originator", "AE", "1" }, { 0x2100, 0x0140, "Destination AE", "DestinationAE", "AE", "1" }, { 0x2100, 0x0160, "Owner ID", "OwnerID", "SH", "1" }, { 0x2100, 0x0170, "Number of Films", "NumberOfFilms", "IS", "1" }, { 0x2100, 0x0500, "Referenced Print Job Sequence (Pull Stored Print)", "ReferencedPrintJobSequencePullStoredPrint", "SQ", "1" }, { 0x2110, 0x0010, "Printer Status", "PrinterStatus", "CS", "1" }, { 0x2110, 0x0020, "Printer Status Info", "PrinterStatusInfo", "CS", "1" }, { 0x2110, 0x0030, "Printer Name", "PrinterName", "LO", "1" }, { 0x2110, 0x0099, "Print Queue ID", "PrintQueueID", "SH", "1" }, { 0x2120, 0x0010, "Queue Status", "QueueStatus", "CS", "1" }, { 0x2120, 0x0050, "Print Job Description Sequence", "PrintJobDescriptionSequence", "SQ", "1" }, { 0x2120, 0x0070, "Referenced Print Job Sequence", "ReferencedPrintJobSequence", "SQ", "1" }, { 0x2130, 0x0010, "Print Management Capabilities Sequence", "PrintManagementCapabilitiesSequence", "SQ", "1" }, { 0x2130, 0x0015, "Printer Characteristics Sequence", "PrinterCharacteristicsSequence", "SQ", "1" }, { 0x2130, 0x0030, "Film Box Content Sequence", "FilmBoxContentSequence", "SQ", "1" }, { 0x2130, 0x0040, "Image Box Content Sequence", "ImageBoxContentSequence", "SQ", "1" }, { 0x2130, 0x0050, "Annotation Content Sequence", "AnnotationContentSequence", "SQ", "1" }, { 0x2130, 0x0060, "Image Overlay Box Content Sequence", "ImageOverlayBoxContentSequence", "SQ", "1" }, { 0x2130, 0x0080, "Presentation LUT Content Sequence", "PresentationLUTContentSequence", "SQ", "1" }, { 0x2130, 0x00a0, "Proposed Study Sequence", "ProposedStudySequence", "SQ", "1" }, { 0x2130, 0x00c0, "Original Image Sequence", "OriginalImageSequence", "SQ", "1" }, { 0x2200, 0x0001, "Label Using Information Extracted From Instances", "LabelUsingInformationExtractedFromInstances", "CS", "1" }, { 0x2200, 0x0002, "Label Text", "LabelText", "UT", "1" }, { 0x2200, 0x0003, "Label Style Selection", "LabelStyleSelection", "CS", "1" }, { 0x2200, 0x0004, "Media Disposition", "MediaDisposition", "LT", "1" }, { 0x2200, 0x0005, "Barcode Value", "BarcodeValue", "LT", "1" }, { 0x2200, 0x0006, "Barcode Symbology", "BarcodeSymbology", "CS", "1" }, { 0x2200, 0x0007, "Allow Media Splitting", "AllowMediaSplitting", "CS", "1" }, { 0x2200, 0x0008, "Include Non-DICOM Objects", "IncludeNonDICOMObjects", "CS", "1" }, { 0x2200, 0x0009, "Include Display Application", "IncludeDisplayApplication", "CS", "1" }, { 0x2200, 0x000a, "Preserve Composite Instances After Media Creation", "PreserveCompositeInstancesAfterMediaCreation", "CS", "1" }, { 0x2200, 0x000b, "Total Number of Pieces of Media Created", "TotalNumberOfPiecesOfMediaCreated", "US", "1" }, { 0x2200, 0x000c, "Requested Media Application Profile", "RequestedMediaApplicationProfile", "LO", "1" }, { 0x2200, 0x000d, "Referenced Storage Media Sequence", "ReferencedStorageMediaSequence", "SQ", "1" }, { 0x2200, 0x000e, "Failure Attributes", "FailureAttributes", "AT", "1-n" }, { 0x2200, 0x000f, "Allow Lossy Compression", "AllowLossyCompression", "CS", "1" }, { 0x2200, 0x0020, "Request Priority", "RequestPriority", "CS", "1" }, { 0x3002, 0x0002, "RT Image Label", "RTImageLabel", "SH", "1" }, { 0x3002, 0x0003, "RT Image Name", "RTImageName", "LO", "1" }, { 0x3002, 0x0004, "RT Image Description", "RTImageDescription", "ST", "1" }, { 0x3002, 0x000a, "Reported Values Origin", "ReportedValuesOrigin", "CS", "1" }, { 0x3002, 0x000c, "RT Image Plane", "RTImagePlane", "CS", "1" }, { 0x3002, 0x000d, "X-Ray Image Receptor Translation", "XRayImageReceptorTranslation", "DS", "3" }, { 0x3002, 0x000e, "X-Ray Image Receptor Angle", "XRayImageReceptorAngle", "DS", "1" }, { 0x3002, 0x0010, "RT Image Orientation", "RTImageOrientation", "DS", "6" }, { 0x3002, 0x0011, "Image Plane Pixel Spacing", "ImagePlanePixelSpacing", "DS", "2" }, { 0x3002, 0x0012, "RT Image Position", "RTImagePosition", "DS", "2" }, { 0x3002, 0x0020, "Radiation Machine Name", "RadiationMachineName", "SH", "1" }, { 0x3002, 0x0022, "Radiation Machine SAD", "RadiationMachineSAD", "DS", "1" }, { 0x3002, 0x0024, "Radiation Machine SSD", "RadiationMachineSSD", "DS", "1" }, { 0x3002, 0x0026, "RT Image SID", "RTImageSID", "DS", "1" }, { 0x3002, 0x0028, "Source to Reference Object Distance", "SourceToReferenceObjectDistance", "DS", "1" }, { 0x3002, 0x0029, "Fraction Number", "FractionNumber", "IS", "1" }, { 0x3002, 0x0030, "Exposure Sequence", "ExposureSequence", "SQ", "1" }, { 0x3002, 0x0032, "Meterset Exposure", "MetersetExposure", "DS", "1" }, { 0x3002, 0x0034, "Diaphragm Position", "DiaphragmPosition", "DS", "4" }, { 0x3002, 0x0040, "Fluence Map Sequence", "FluenceMapSequence", "SQ", "1" }, { 0x3002, 0x0041, "Fluence Data Source", "FluenceDataSource", "CS", "1" }, { 0x3002, 0x0042, "Fluence Data Scale", "FluenceDataScale", "DS", "1" }, { 0x3002, 0x0050, "Primary Fluence Mode Sequence", "PrimaryFluenceModeSequence", "SQ", "1" }, { 0x3002, 0x0051, "Fluence Mode", "FluenceMode", "CS", "1" }, { 0x3002, 0x0052, "Fluence Mode ID", "FluenceModeID", "SH", "1" }, { 0x3004, 0x0001, "DVH Type", "DVHType", "CS", "1" }, { 0x3004, 0x0002, "Dose Units", "DoseUnits", "CS", "1" }, { 0x3004, 0x0004, "Dose Type", "DoseType", "CS", "1" }, { 0x3004, 0x0005, "Spatial Transform of Dose", "SpatialTransformOfDose", "CS", "1" }, { 0x3004, 0x0006, "Dose Comment", "DoseComment", "LO", "1" }, { 0x3004, 0x0008, "Normalization Point", "NormalizationPoint", "DS", "3" }, { 0x3004, 0x000a, "Dose Summation Type", "DoseSummationType", "CS", "1" }, { 0x3004, 0x000c, "Grid Frame Offset Vector", "GridFrameOffsetVector", "DS", "2-n" }, { 0x3004, 0x000e, "Dose Grid Scaling", "DoseGridScaling", "DS", "1" }, { 0x3004, 0x0010, "RT Dose ROI Sequence", "RTDoseROISequence", "SQ", "1" }, { 0x3004, 0x0012, "Dose Value", "DoseValue", "DS", "1" }, { 0x3004, 0x0014, "Tissue Heterogeneity Correction", "TissueHeterogeneityCorrection", "CS", "1-3" }, { 0x3004, 0x0040, "DVH Normalization Point", "DVHNormalizationPoint", "DS", "3" }, { 0x3004, 0x0042, "DVH Normalization Dose Value", "DVHNormalizationDoseValue", "DS", "1" }, { 0x3004, 0x0050, "DVH Sequence", "DVHSequence", "SQ", "1" }, { 0x3004, 0x0052, "DVH Dose Scaling", "DVHDoseScaling", "DS", "1" }, { 0x3004, 0x0054, "DVH Volume Units", "DVHVolumeUnits", "CS", "1" }, { 0x3004, 0x0056, "DVH Number of Bins", "DVHNumberOfBins", "IS", "1" }, { 0x3004, 0x0058, "DVH Data", "DVHData", "DS", "2-2n" }, { 0x3004, 0x0060, "DVH Referenced ROI Sequence", "DVHReferencedROISequence", "SQ", "1" }, { 0x3004, 0x0062, "DVH ROI Contribution Type", "DVHROIContributionType", "CS", "1" }, { 0x3004, 0x0070, "DVH Minimum Dose", "DVHMinimumDose", "DS", "1" }, { 0x3004, 0x0072, "DVH Maximum Dose", "DVHMaximumDose", "DS", "1" }, { 0x3004, 0x0074, "DVH Mean Dose", "DVHMeanDose", "DS", "1" }, { 0x3006, 0x0002, "Structure Set Label", "StructureSetLabel", "SH", "1" }, { 0x3006, 0x0004, "Structure Set Name", "StructureSetName", "LO", "1" }, { 0x3006, 0x0006, "Structure Set Description", "StructureSetDescription", "ST", "1" }, { 0x3006, 0x0008, "Structure Set Date", "StructureSetDate", "DA", "1" }, { 0x3006, 0x0009, "Structure Set Time", "StructureSetTime", "TM", "1" }, { 0x3006, 0x0010, "Referenced Frame of Reference Sequence", "ReferencedFrameOfReferenceSequence", "SQ", "1" }, { 0x3006, 0x0012, "RT Referenced Study Sequence", "RTReferencedStudySequence", "SQ", "1" }, { 0x3006, 0x0014, "RT Referenced Series Sequence", "RTReferencedSeriesSequence", "SQ", "1" }, { 0x3006, 0x0016, "Contour Image Sequence", "ContourImageSequence", "SQ", "1" }, { 0x3006, 0x0018, "Predecessor Structure Set Sequence", "PredecessorStructureSetSequence", "SQ", "1" }, { 0x3006, 0x0020, "Structure Set ROI Sequence", "StructureSetROISequence", "SQ", "1" }, { 0x3006, 0x0022, "ROI Number", "ROINumber", "IS", "1" }, { 0x3006, 0x0024, "Referenced Frame of Reference UID", "ReferencedFrameOfReferenceUID", "UI", "1" }, { 0x3006, 0x0026, "ROI Name", "ROIName", "LO", "1" }, { 0x3006, 0x0028, "ROI Description", "ROIDescription", "ST", "1" }, { 0x3006, 0x002a, "ROI Display Color", "ROIDisplayColor", "IS", "3" }, { 0x3006, 0x002c, "ROI Volume", "ROIVolume", "DS", "1" }, { 0x3006, 0x0030, "RT Related ROI Sequence", "RTRelatedROISequence", "SQ", "1" }, { 0x3006, 0x0033, "RT ROI Relationship", "RTROIRelationship", "CS", "1" }, { 0x3006, 0x0036, "ROI Generation Algorithm", "ROIGenerationAlgorithm", "CS", "1" }, { 0x3006, 0x0038, "ROI Generation Description", "ROIGenerationDescription", "LO", "1" }, { 0x3006, 0x0039, "ROI Contour Sequence", "ROIContourSequence", "SQ", "1" }, { 0x3006, 0x0040, "Contour Sequence", "ContourSequence", "SQ", "1" }, { 0x3006, 0x0042, "Contour Geometric Type", "ContourGeometricType", "CS", "1" }, { 0x3006, 0x0044, "Contour Slab Thickness", "ContourSlabThickness", "DS", "1" }, { 0x3006, 0x0045, "Contour Offset Vector", "ContourOffsetVector", "DS", "3" }, { 0x3006, 0x0046, "Number of Contour Points", "NumberOfContourPoints", "IS", "1" }, { 0x3006, 0x0048, "Contour Number", "ContourNumber", "IS", "1" }, { 0x3006, 0x0049, "Attached Contours", "AttachedContours", "IS", "1-n" }, { 0x3006, 0x0050, "Contour Data", "ContourData", "DS", "3-3n" }, { 0x3006, 0x0080, "RT ROI Observations Sequence", "RTROIObservationsSequence", "SQ", "1" }, { 0x3006, 0x0082, "Observation Number", "ObservationNumber", "IS", "1" }, { 0x3006, 0x0084, "Referenced ROI Number", "ReferencedROINumber", "IS", "1" }, { 0x3006, 0x0085, "ROI Observation Label", "ROIObservationLabel", "SH", "1" }, { 0x3006, 0x0086, "RT ROI Identification Code Sequence", "RTROIIdentificationCodeSequence", "SQ", "1" }, { 0x3006, 0x0088, "ROI Observation Description", "ROIObservationDescription", "ST", "1" }, { 0x3006, 0x00a0, "Related RT ROI Observations Sequence", "RelatedRTROIObservationsSequence", "SQ", "1" }, { 0x3006, 0x00a4, "RT ROI Interpreted Type", "RTROIInterpretedType", "CS", "1" }, { 0x3006, 0x00a6, "ROI Interpreter", "ROIInterpreter", "PN", "1" }, { 0x3006, 0x00b0, "ROI Physical Properties Sequence", "ROIPhysicalPropertiesSequence", "SQ", "1" }, { 0x3006, 0x00b2, "ROI Physical Property", "ROIPhysicalProperty", "CS", "1" }, { 0x3006, 0x00b4, "ROI Physical Property Value", "ROIPhysicalPropertyValue", "DS", "1" }, { 0x3006, 0x00b6, "ROI Elemental Composition Sequence", "ROIElementalCompositionSequence", "SQ", "1" }, { 0x3006, 0x00b7, "ROI Elemental Composition Atomic Number", "ROIElementalCompositionAtomicNumber", "US", "1" }, { 0x3006, 0x00b8, "ROI Elemental Composition Atomic Mass Fraction", "ROIElementalCompositionAtomicMassFraction", "FL", "1" }, { 0x3006, 0x00b9, "Additional RT ROI Identification Code Sequence", "AdditionalRTROIIdentificationCodeSequence", "SQ", "1" }, { 0x3006, 0x00c0, "Frame of Reference Relationship Sequence", "FrameOfReferenceRelationshipSequence", "SQ", "1" }, { 0x3006, 0x00c2, "Related Frame of Reference UID", "RelatedFrameOfReferenceUID", "UI", "1" }, { 0x3006, 0x00c4, "Frame of Reference Transformation Type", "FrameOfReferenceTransformationType", "CS", "1" }, { 0x3006, 0x00c6, "Frame of Reference Transformation Matrix", "FrameOfReferenceTransformationMatrix", "DS", "16" }, { 0x3006, 0x00c8, "Frame of Reference Transformation Comment", "FrameOfReferenceTransformationComment", "LO", "1" }, { 0x3008, 0x0010, "Measured Dose Reference Sequence", "MeasuredDoseReferenceSequence", "SQ", "1" }, { 0x3008, 0x0012, "Measured Dose Description", "MeasuredDoseDescription", "ST", "1" }, { 0x3008, 0x0014, "Measured Dose Type", "MeasuredDoseType", "CS", "1" }, { 0x3008, 0x0016, "Measured Dose Value", "MeasuredDoseValue", "DS", "1" }, { 0x3008, 0x0020, "Treatment Session Beam Sequence", "TreatmentSessionBeamSequence", "SQ", "1" }, { 0x3008, 0x0021, "Treatment Session Ion Beam Sequence", "TreatmentSessionIonBeamSequence", "SQ", "1" }, { 0x3008, 0x0022, "Current Fraction Number", "CurrentFractionNumber", "IS", "1" }, { 0x3008, 0x0024, "Treatment Control Point Date", "TreatmentControlPointDate", "DA", "1" }, { 0x3008, 0x0025, "Treatment Control Point Time", "TreatmentControlPointTime", "TM", "1" }, { 0x3008, 0x002a, "Treatment Termination Status", "TreatmentTerminationStatus", "CS", "1" }, { 0x3008, 0x002b, "Treatment Termination Code", "TreatmentTerminationCode", "SH", "1" }, { 0x3008, 0x002c, "Treatment Verification Status", "TreatmentVerificationStatus", "CS", "1" }, { 0x3008, 0x0030, "Referenced Treatment Record Sequence", "ReferencedTreatmentRecordSequence", "SQ", "1" }, { 0x3008, 0x0032, "Specified Primary Meterset", "SpecifiedPrimaryMeterset", "DS", "1" }, { 0x3008, 0x0033, "Specified Secondary Meterset", "SpecifiedSecondaryMeterset", "DS", "1" }, { 0x3008, 0x0036, "Delivered Primary Meterset", "DeliveredPrimaryMeterset", "DS", "1" }, { 0x3008, 0x0037, "Delivered Secondary Meterset", "DeliveredSecondaryMeterset", "DS", "1" }, { 0x3008, 0x003a, "Specified Treatment Time", "SpecifiedTreatmentTime", "DS", "1" }, { 0x3008, 0x003b, "Delivered Treatment Time", "DeliveredTreatmentTime", "DS", "1" }, { 0x3008, 0x0040, "Control Point Delivery Sequence", "ControlPointDeliverySequence", "SQ", "1" }, { 0x3008, 0x0041, "Ion Control Point Delivery Sequence", "IonControlPointDeliverySequence", "SQ", "1" }, { 0x3008, 0x0042, "Specified Meterset", "SpecifiedMeterset", "DS", "1" }, { 0x3008, 0x0044, "Delivered Meterset", "DeliveredMeterset", "DS", "1" }, { 0x3008, 0x0045, "Meterset Rate Set", "MetersetRateSet", "FL", "1" }, { 0x3008, 0x0046, "Meterset Rate Delivered", "MetersetRateDelivered", "FL", "1" }, { 0x3008, 0x0047, "Scan Spot Metersets Delivered", "ScanSpotMetersetsDelivered", "FL", "1-n" }, { 0x3008, 0x0048, "Dose Rate Delivered", "DoseRateDelivered", "DS", "1" }, { 0x3008, 0x0050, "Treatment Summary Calculated Dose Reference Sequence", "TreatmentSummaryCalculatedDoseReferenceSequence", "SQ", "1" }, { 0x3008, 0x0052, "Cumulative Dose to Dose Reference", "CumulativeDoseToDoseReference", "DS", "1" }, { 0x3008, 0x0054, "First Treatment Date", "FirstTreatmentDate", "DA", "1" }, { 0x3008, 0x0056, "Most Recent Treatment Date", "MostRecentTreatmentDate", "DA", "1" }, { 0x3008, 0x005a, "Number of Fractions Delivered", "NumberOfFractionsDelivered", "IS", "1" }, { 0x3008, 0x0060, "Override Sequence", "OverrideSequence", "SQ", "1" }, { 0x3008, 0x0061, "Parameter Sequence Pointer", "ParameterSequencePointer", "AT", "1" }, { 0x3008, 0x0062, "Override Parameter Pointer", "OverrideParameterPointer", "AT", "1" }, { 0x3008, 0x0063, "Parameter Item Index", "ParameterItemIndex", "IS", "1" }, { 0x3008, 0x0064, "Measured Dose Reference Number", "MeasuredDoseReferenceNumber", "IS", "1" }, { 0x3008, 0x0065, "Parameter Pointer", "ParameterPointer", "AT", "1" }, { 0x3008, 0x0066, "Override Reason", "OverrideReason", "ST", "1" }, { 0x3008, 0x0068, "Corrected Parameter Sequence", "CorrectedParameterSequence", "SQ", "1" }, { 0x3008, 0x006a, "Correction Value", "CorrectionValue", "FL", "1" }, { 0x3008, 0x0070, "Calculated Dose Reference Sequence", "CalculatedDoseReferenceSequence", "SQ", "1" }, { 0x3008, 0x0072, "Calculated Dose Reference Number", "CalculatedDoseReferenceNumber", "IS", "1" }, { 0x3008, 0x0074, "Calculated Dose Reference Description", "CalculatedDoseReferenceDescription", "ST", "1" }, { 0x3008, 0x0076, "Calculated Dose Reference Dose Value", "CalculatedDoseReferenceDoseValue", "DS", "1" }, { 0x3008, 0x0078, "Start Meterset", "StartMeterset", "DS", "1" }, { 0x3008, 0x007a, "End Meterset", "EndMeterset", "DS", "1" }, { 0x3008, 0x0080, "Referenced Measured Dose Reference Sequence", "ReferencedMeasuredDoseReferenceSequence", "SQ", "1" }, { 0x3008, 0x0082, "Referenced Measured Dose Reference Number", "ReferencedMeasuredDoseReferenceNumber", "IS", "1" }, { 0x3008, 0x0090, "Referenced Calculated Dose Reference Sequence", "ReferencedCalculatedDoseReferenceSequence", "SQ", "1" }, { 0x3008, 0x0092, "Referenced Calculated Dose Reference Number", "ReferencedCalculatedDoseReferenceNumber", "IS", "1" }, { 0x3008, 0x00a0, "Beam Limiting Device Leaf Pairs Sequence", "BeamLimitingDeviceLeafPairsSequence", "SQ", "1" }, { 0x3008, 0x00b0, "Recorded Wedge Sequence", "RecordedWedgeSequence", "SQ", "1" }, { 0x3008, 0x00c0, "Recorded Compensator Sequence", "RecordedCompensatorSequence", "SQ", "1" }, { 0x3008, 0x00d0, "Recorded Block Sequence", "RecordedBlockSequence", "SQ", "1" }, { 0x3008, 0x00e0, "Treatment Summary Measured Dose Reference Sequence", "TreatmentSummaryMeasuredDoseReferenceSequence", "SQ", "1" }, { 0x3008, 0x00f0, "Recorded Snout Sequence", "RecordedSnoutSequence", "SQ", "1" }, { 0x3008, 0x00f2, "Recorded Range Shifter Sequence", "RecordedRangeShifterSequence", "SQ", "1" }, { 0x3008, 0x00f4, "Recorded Lateral Spreading Device Sequence", "RecordedLateralSpreadingDeviceSequence", "SQ", "1" }, { 0x3008, 0x00f6, "Recorded Range Modulator Sequence", "RecordedRangeModulatorSequence", "SQ", "1" }, { 0x3008, 0x0100, "Recorded Source Sequence", "RecordedSourceSequence", "SQ", "1" }, { 0x3008, 0x0105, "Source Serial Number", "SourceSerialNumber", "LO", "1" }, { 0x3008, 0x0110, "Treatment Session Application Setup Sequence", "TreatmentSessionApplicationSetupSequence", "SQ", "1" }, { 0x3008, 0x0116, "Application Setup Check", "ApplicationSetupCheck", "CS", "1" }, { 0x3008, 0x0120, "Recorded Brachy Accessory Device Sequence", "RecordedBrachyAccessoryDeviceSequence", "SQ", "1" }, { 0x3008, 0x0122, "Referenced Brachy Accessory Device Number", "ReferencedBrachyAccessoryDeviceNumber", "IS", "1" }, { 0x3008, 0x0130, "Recorded Channel Sequence", "RecordedChannelSequence", "SQ", "1" }, { 0x3008, 0x0132, "Specified Channel Total Time", "SpecifiedChannelTotalTime", "DS", "1" }, { 0x3008, 0x0134, "Delivered Channel Total Time", "DeliveredChannelTotalTime", "DS", "1" }, { 0x3008, 0x0136, "Specified Number of Pulses", "SpecifiedNumberOfPulses", "IS", "1" }, { 0x3008, 0x0138, "Delivered Number of Pulses", "DeliveredNumberOfPulses", "IS", "1" }, { 0x3008, 0x013a, "Specified Pulse Repetition Interval", "SpecifiedPulseRepetitionInterval", "DS", "1" }, { 0x3008, 0x013c, "Delivered Pulse Repetition Interval", "DeliveredPulseRepetitionInterval", "DS", "1" }, { 0x3008, 0x0140, "Recorded Source Applicator Sequence", "RecordedSourceApplicatorSequence", "SQ", "1" }, { 0x3008, 0x0142, "Referenced Source Applicator Number", "ReferencedSourceApplicatorNumber", "IS", "1" }, { 0x3008, 0x0150, "Recorded Channel Shield Sequence", "RecordedChannelShieldSequence", "SQ", "1" }, { 0x3008, 0x0152, "Referenced Channel Shield Number", "ReferencedChannelShieldNumber", "IS", "1" }, { 0x3008, 0x0160, "Brachy Control Point Delivered Sequence", "BrachyControlPointDeliveredSequence", "SQ", "1" }, { 0x3008, 0x0162, "Safe Position Exit Date", "SafePositionExitDate", "DA", "1" }, { 0x3008, 0x0164, "Safe Position Exit Time", "SafePositionExitTime", "TM", "1" }, { 0x3008, 0x0166, "Safe Position Return Date", "SafePositionReturnDate", "DA", "1" }, { 0x3008, 0x0168, "Safe Position Return Time", "SafePositionReturnTime", "TM", "1" }, { 0x3008, 0x0171, "Pulse Specific Brachy Control Point Delivered Sequence", "PulseSpecificBrachyControlPointDeliveredSequence", "SQ", "1" }, { 0x3008, 0x0172, "Pulse Number", "PulseNumber", "US", "1" }, { 0x3008, 0x0173, "Brachy Pulse Control Point Delivered Sequence", "BrachyPulseControlPointDeliveredSequence", "SQ", "1" }, { 0x3008, 0x0200, "Current Treatment Status", "CurrentTreatmentStatus", "CS", "1" }, { 0x3008, 0x0202, "Treatment Status Comment", "TreatmentStatusComment", "ST", "1" }, { 0x3008, 0x0220, "Fraction Group Summary Sequence", "FractionGroupSummarySequence", "SQ", "1" }, { 0x3008, 0x0223, "Referenced Fraction Number", "ReferencedFractionNumber", "IS", "1" }, { 0x3008, 0x0224, "Fraction Group Type", "FractionGroupType", "CS", "1" }, { 0x3008, 0x0230, "Beam Stopper Position", "BeamStopperPosition", "CS", "1" }, { 0x3008, 0x0240, "Fraction Status Summary Sequence", "FractionStatusSummarySequence", "SQ", "1" }, { 0x3008, 0x0250, "Treatment Date", "TreatmentDate", "DA", "1" }, { 0x3008, 0x0251, "Treatment Time", "TreatmentTime", "TM", "1" }, { 0x300a, 0x0002, "RT Plan Label", "RTPlanLabel", "SH", "1" }, { 0x300a, 0x0003, "RT Plan Name", "RTPlanName", "LO", "1" }, { 0x300a, 0x0004, "RT Plan Description", "RTPlanDescription", "ST", "1" }, { 0x300a, 0x0006, "RT Plan Date", "RTPlanDate", "DA", "1" }, { 0x300a, 0x0007, "RT Plan Time", "RTPlanTime", "TM", "1" }, { 0x300a, 0x0009, "Treatment Protocols", "TreatmentProtocols", "LO", "1-n" }, { 0x300a, 0x000a, "Plan Intent", "PlanIntent", "CS", "1" }, { 0x300a, 0x000b, "Treatment Sites", "TreatmentSites", "LO", "1-n" }, { 0x300a, 0x000c, "RT Plan Geometry", "RTPlanGeometry", "CS", "1" }, { 0x300a, 0x000e, "Prescription Description", "PrescriptionDescription", "ST", "1" }, { 0x300a, 0x0010, "Dose Reference Sequence", "DoseReferenceSequence", "SQ", "1" }, { 0x300a, 0x0012, "Dose Reference Number", "DoseReferenceNumber", "IS", "1" }, { 0x300a, 0x0013, "Dose Reference UID", "DoseReferenceUID", "UI", "1" }, { 0x300a, 0x0014, "Dose Reference Structure Type", "DoseReferenceStructureType", "CS", "1" }, { 0x300a, 0x0015, "Nominal Beam Energy Unit", "NominalBeamEnergyUnit", "CS", "1" }, { 0x300a, 0x0016, "Dose Reference Description", "DoseReferenceDescription", "LO", "1" }, { 0x300a, 0x0018, "Dose Reference Point Coordinates", "DoseReferencePointCoordinates", "DS", "3" }, { 0x300a, 0x001a, "Nominal Prior Dose", "NominalPriorDose", "DS", "1" }, { 0x300a, 0x0020, "Dose Reference Type", "DoseReferenceType", "CS", "1" }, { 0x300a, 0x0021, "Constraint Weight", "ConstraintWeight", "DS", "1" }, { 0x300a, 0x0022, "Delivery Warning Dose", "DeliveryWarningDose", "DS", "1" }, { 0x300a, 0x0023, "Delivery Maximum Dose", "DeliveryMaximumDose", "DS", "1" }, { 0x300a, 0x0025, "Target Minimum Dose", "TargetMinimumDose", "DS", "1" }, { 0x300a, 0x0026, "Target Prescription Dose", "TargetPrescriptionDose", "DS", "1" }, { 0x300a, 0x0027, "Target Maximum Dose", "TargetMaximumDose", "DS", "1" }, { 0x300a, 0x0028, "Target Underdose Volume Fraction", "TargetUnderdoseVolumeFraction", "DS", "1" }, { 0x300a, 0x002a, "Organ at Risk Full-volume Dose", "OrganAtRiskFullVolumeDose", "DS", "1" }, { 0x300a, 0x002b, "Organ at Risk Limit Dose", "OrganAtRiskLimitDose", "DS", "1" }, { 0x300a, 0x002c, "Organ at Risk Maximum Dose", "OrganAtRiskMaximumDose", "DS", "1" }, { 0x300a, 0x002d, "Organ at Risk Overdose Volume Fraction", "OrganAtRiskOverdoseVolumeFraction", "DS", "1" }, { 0x300a, 0x0040, "Tolerance Table Sequence", "ToleranceTableSequence", "SQ", "1" }, { 0x300a, 0x0042, "Tolerance Table Number", "ToleranceTableNumber", "IS", "1" }, { 0x300a, 0x0043, "Tolerance Table Label", "ToleranceTableLabel", "SH", "1" }, { 0x300a, 0x0044, "Gantry Angle Tolerance", "GantryAngleTolerance", "DS", "1" }, { 0x300a, 0x0046, "Beam Limiting Device Angle Tolerance", "BeamLimitingDeviceAngleTolerance", "DS", "1" }, { 0x300a, 0x0048, "Beam Limiting Device Tolerance Sequence", "BeamLimitingDeviceToleranceSequence", "SQ", "1" }, { 0x300a, 0x004a, "Beam Limiting Device Position Tolerance", "BeamLimitingDevicePositionTolerance", "DS", "1" }, { 0x300a, 0x004b, "Snout Position Tolerance", "SnoutPositionTolerance", "FL", "1" }, { 0x300a, 0x004c, "Patient Support Angle Tolerance", "PatientSupportAngleTolerance", "DS", "1" }, { 0x300a, 0x004e, "Table Top Eccentric Angle Tolerance", "TableTopEccentricAngleTolerance", "DS", "1" }, { 0x300a, 0x004f, "Table Top Pitch Angle Tolerance", "TableTopPitchAngleTolerance", "FL", "1" }, { 0x300a, 0x0050, "Table Top Roll Angle Tolerance", "TableTopRollAngleTolerance", "FL", "1" }, { 0x300a, 0x0051, "Table Top Vertical Position Tolerance", "TableTopVerticalPositionTolerance", "DS", "1" }, { 0x300a, 0x0052, "Table Top Longitudinal Position Tolerance", "TableTopLongitudinalPositionTolerance", "DS", "1" }, { 0x300a, 0x0053, "Table Top Lateral Position Tolerance", "TableTopLateralPositionTolerance", "DS", "1" }, { 0x300a, 0x0055, "RT Plan Relationship", "RTPlanRelationship", "CS", "1" }, { 0x300a, 0x0070, "Fraction Group Sequence", "FractionGroupSequence", "SQ", "1" }, { 0x300a, 0x0071, "Fraction Group Number", "FractionGroupNumber", "IS", "1" }, { 0x300a, 0x0072, "Fraction Group Description", "FractionGroupDescription", "LO", "1" }, { 0x300a, 0x0078, "Number of Fractions Planned", "NumberOfFractionsPlanned", "IS", "1" }, { 0x300a, 0x0079, "Number of Fraction Pattern Digits Per Day", "NumberOfFractionPatternDigitsPerDay", "IS", "1" }, { 0x300a, 0x007a, "Repeat Fraction Cycle Length", "RepeatFractionCycleLength", "IS", "1" }, { 0x300a, 0x007b, "Fraction Pattern", "FractionPattern", "LT", "1" }, { 0x300a, 0x0080, "Number of Beams", "NumberOfBeams", "IS", "1" }, { 0x300a, 0x0082, "Beam Dose Specification Point", "BeamDoseSpecificationPoint", "DS", "3" }, { 0x300a, 0x0084, "Beam Dose", "BeamDose", "DS", "1" }, { 0x300a, 0x0086, "Beam Meterset", "BeamMeterset", "DS", "1" }, { 0x300a, 0x0088, "Beam Dose Point Depth", "BeamDosePointDepth", "FL", "1" }, { 0x300a, 0x0089, "Beam Dose Point Equivalent Depth", "BeamDosePointEquivalentDepth", "FL", "1" }, { 0x300a, 0x008a, "Beam Dose Point SSD", "BeamDosePointSSD", "FL", "1" }, { 0x300a, 0x008b, "Beam Dose Meaning", "BeamDoseMeaning", "CS", "1" }, { 0x300a, 0x008c, "Beam Dose Verification Control Point Sequence", "BeamDoseVerificationControlPointSequence", "SQ", "1" }, { 0x300a, 0x008d, "Average Beam Dose Point Depth", "AverageBeamDosePointDepth", "FL", "1" }, { 0x300a, 0x008e, "Average Beam Dose Point Equivalent Depth", "AverageBeamDosePointEquivalentDepth", "FL", "1" }, { 0x300a, 0x008f, "Average Beam Dose Point SSD", "AverageBeamDosePointSSD", "FL", "1" }, { 0x300a, 0x00a0, "Number of Brachy Application Setups", "NumberOfBrachyApplicationSetups", "IS", "1" }, { 0x300a, 0x00a2, "Brachy Application Setup Dose Specification Point", "BrachyApplicationSetupDoseSpecificationPoint", "DS", "3" }, { 0x300a, 0x00a4, "Brachy Application Setup Dose", "BrachyApplicationSetupDose", "DS", "1" }, { 0x300a, 0x00b0, "Beam Sequence", "BeamSequence", "SQ", "1" }, { 0x300a, 0x00b2, "Treatment Machine Name", "TreatmentMachineName", "SH", "1" }, { 0x300a, 0x00b3, "Primary Dosimeter Unit", "PrimaryDosimeterUnit", "CS", "1" }, { 0x300a, 0x00b4, "Source-Axis Distance", "SourceAxisDistance", "DS", "1" }, { 0x300a, 0x00b6, "Beam Limiting Device Sequence", "BeamLimitingDeviceSequence", "SQ", "1" }, { 0x300a, 0x00b8, "RT Beam Limiting Device Type", "RTBeamLimitingDeviceType", "CS", "1" }, { 0x300a, 0x00ba, "Source to Beam Limiting Device Distance", "SourceToBeamLimitingDeviceDistance", "DS", "1" }, { 0x300a, 0x00bb, "Isocenter to Beam Limiting Device Distance", "IsocenterToBeamLimitingDeviceDistance", "FL", "1" }, { 0x300a, 0x00bc, "Number of Leaf/Jaw Pairs", "NumberOfLeafJawPairs", "IS", "1" }, { 0x300a, 0x00be, "Leaf Position Boundaries", "LeafPositionBoundaries", "DS", "3-n" }, { 0x300a, 0x00c0, "Beam Number", "BeamNumber", "IS", "1" }, { 0x300a, 0x00c2, "Beam Name", "BeamName", "LO", "1" }, { 0x300a, 0x00c3, "Beam Description", "BeamDescription", "ST", "1" }, { 0x300a, 0x00c4, "Beam Type", "BeamType", "CS", "1" }, { 0x300a, 0x00c5, "Beam Delivery Duration Limit", "BeamDeliveryDurationLimit", "FD", "1" }, { 0x300a, 0x00c6, "Radiation Type", "RadiationType", "CS", "1" }, { 0x300a, 0x00c7, "High-Dose Technique Type", "HighDoseTechniqueType", "CS", "1" }, { 0x300a, 0x00c8, "Reference Image Number", "ReferenceImageNumber", "IS", "1" }, { 0x300a, 0x00ca, "Planned Verification Image Sequence", "PlannedVerificationImageSequence", "SQ", "1" }, { 0x300a, 0x00cc, "Imaging Device-Specific Acquisition Parameters", "ImagingDeviceSpecificAcquisitionParameters", "LO", "1-n" }, { 0x300a, 0x00ce, "Treatment Delivery Type", "TreatmentDeliveryType", "CS", "1" }, { 0x300a, 0x00d0, "Number of Wedges", "NumberOfWedges", "IS", "1" }, { 0x300a, 0x00d1, "Wedge Sequence", "WedgeSequence", "SQ", "1" }, { 0x300a, 0x00d2, "Wedge Number", "WedgeNumber", "IS", "1" }, { 0x300a, 0x00d3, "Wedge Type", "WedgeType", "CS", "1" }, { 0x300a, 0x00d4, "Wedge ID", "WedgeID", "SH", "1" }, { 0x300a, 0x00d5, "Wedge Angle", "WedgeAngle", "IS", "1" }, { 0x300a, 0x00d6, "Wedge Factor", "WedgeFactor", "DS", "1" }, { 0x300a, 0x00d7, "Total Wedge Tray Water-Equivalent Thickness", "TotalWedgeTrayWaterEquivalentThickness", "FL", "1" }, { 0x300a, 0x00d8, "Wedge Orientation", "WedgeOrientation", "DS", "1" }, { 0x300a, 0x00d9, "Isocenter to Wedge Tray Distance", "IsocenterToWedgeTrayDistance", "FL", "1" }, { 0x300a, 0x00da, "Source to Wedge Tray Distance", "SourceToWedgeTrayDistance", "DS", "1" }, { 0x300a, 0x00db, "Wedge Thin Edge Position", "WedgeThinEdgePosition", "FL", "1" }, { 0x300a, 0x00dc, "Bolus ID", "BolusID", "SH", "1" }, { 0x300a, 0x00dd, "Bolus Description", "BolusDescription", "ST", "1" }, { 0x300a, 0x00de, "Effective Wedge Angle", "EffectiveWedgeAngle", "DS", "1" }, { 0x300a, 0x00e0, "Number of Compensators", "NumberOfCompensators", "IS", "1" }, { 0x300a, 0x00e1, "Material ID", "MaterialID", "SH", "1" }, { 0x300a, 0x00e2, "Total Compensator Tray Factor", "TotalCompensatorTrayFactor", "DS", "1" }, { 0x300a, 0x00e3, "Compensator Sequence", "CompensatorSequence", "SQ", "1" }, { 0x300a, 0x00e4, "Compensator Number", "CompensatorNumber", "IS", "1" }, { 0x300a, 0x00e5, "Compensator ID", "CompensatorID", "SH", "1" }, { 0x300a, 0x00e6, "Source to Compensator Tray Distance", "SourceToCompensatorTrayDistance", "DS", "1" }, { 0x300a, 0x00e7, "Compensator Rows", "CompensatorRows", "IS", "1" }, { 0x300a, 0x00e8, "Compensator Columns", "CompensatorColumns", "IS", "1" }, { 0x300a, 0x00e9, "Compensator Pixel Spacing", "CompensatorPixelSpacing", "DS", "2" }, { 0x300a, 0x00ea, "Compensator Position", "CompensatorPosition", "DS", "2" }, { 0x300a, 0x00eb, "Compensator Transmission Data", "CompensatorTransmissionData", "DS", "1-n" }, { 0x300a, 0x00ec, "Compensator Thickness Data", "CompensatorThicknessData", "DS", "1-n" }, { 0x300a, 0x00ed, "Number of Boli", "NumberOfBoli", "IS", "1" }, { 0x300a, 0x00ee, "Compensator Type", "CompensatorType", "CS", "1" }, { 0x300a, 0x00ef, "Compensator Tray ID", "CompensatorTrayID", "SH", "1" }, { 0x300a, 0x00f0, "Number of Blocks", "NumberOfBlocks", "IS", "1" }, { 0x300a, 0x00f2, "Total Block Tray Factor", "TotalBlockTrayFactor", "DS", "1" }, { 0x300a, 0x00f3, "Total Block Tray Water-Equivalent Thickness", "TotalBlockTrayWaterEquivalentThickness", "FL", "1" }, { 0x300a, 0x00f4, "Block Sequence", "BlockSequence", "SQ", "1" }, { 0x300a, 0x00f5, "Block Tray ID", "BlockTrayID", "SH", "1" }, { 0x300a, 0x00f6, "Source to Block Tray Distance", "SourceToBlockTrayDistance", "DS", "1" }, { 0x300a, 0x00f7, "Isocenter to Block Tray Distance", "IsocenterToBlockTrayDistance", "FL", "1" }, { 0x300a, 0x00f8, "Block Type", "BlockType", "CS", "1" }, { 0x300a, 0x00f9, "Accessory Code", "AccessoryCode", "LO", "1" }, { 0x300a, 0x00fa, "Block Divergence", "BlockDivergence", "CS", "1" }, { 0x300a, 0x00fb, "Block Mounting Position", "BlockMountingPosition", "CS", "1" }, { 0x300a, 0x00fc, "Block Number", "BlockNumber", "IS", "1" }, { 0x300a, 0x00fe, "Block Name", "BlockName", "LO", "1" }, { 0x300a, 0x0100, "Block Thickness", "BlockThickness", "DS", "1" }, { 0x300a, 0x0102, "Block Transmission", "BlockTransmission", "DS", "1" }, { 0x300a, 0x0104, "Block Number of Points", "BlockNumberOfPoints", "IS", "1" }, { 0x300a, 0x0106, "Block Data", "BlockData", "DS", "2-2n" }, { 0x300a, 0x0107, "Applicator Sequence", "ApplicatorSequence", "SQ", "1" }, { 0x300a, 0x0108, "Applicator ID", "ApplicatorID", "SH", "1" }, { 0x300a, 0x0109, "Applicator Type", "ApplicatorType", "CS", "1" }, { 0x300a, 0x010a, "Applicator Description", "ApplicatorDescription", "LO", "1" }, { 0x300a, 0x010c, "Cumulative Dose Reference Coefficient", "CumulativeDoseReferenceCoefficient", "DS", "1" }, { 0x300a, 0x010e, "Final Cumulative Meterset Weight", "FinalCumulativeMetersetWeight", "DS", "1" }, { 0x300a, 0x0110, "Number of Control Points", "NumberOfControlPoints", "IS", "1" }, { 0x300a, 0x0111, "Control Point Sequence", "ControlPointSequence", "SQ", "1" }, { 0x300a, 0x0112, "Control Point Index", "ControlPointIndex", "IS", "1" }, { 0x300a, 0x0114, "Nominal Beam Energy", "NominalBeamEnergy", "DS", "1" }, { 0x300a, 0x0115, "Dose Rate Set", "DoseRateSet", "DS", "1" }, { 0x300a, 0x0116, "Wedge Position Sequence", "WedgePositionSequence", "SQ", "1" }, { 0x300a, 0x0118, "Wedge Position", "WedgePosition", "CS", "1" }, { 0x300a, 0x011a, "Beam Limiting Device Position Sequence", "BeamLimitingDevicePositionSequence", "SQ", "1" }, { 0x300a, 0x011c, "Leaf/Jaw Positions", "LeafJawPositions", "DS", "2-2n" }, { 0x300a, 0x011e, "Gantry Angle", "GantryAngle", "DS", "1" }, { 0x300a, 0x011f, "Gantry Rotation Direction", "GantryRotationDirection", "CS", "1" }, { 0x300a, 0x0120, "Beam Limiting Device Angle", "BeamLimitingDeviceAngle", "DS", "1" }, { 0x300a, 0x0121, "Beam Limiting Device Rotation Direction", "BeamLimitingDeviceRotationDirection", "CS", "1" }, { 0x300a, 0x0122, "Patient Support Angle", "PatientSupportAngle", "DS", "1" }, { 0x300a, 0x0123, "Patient Support Rotation Direction", "PatientSupportRotationDirection", "CS", "1" }, { 0x300a, 0x0124, "Table Top Eccentric Axis Distance", "TableTopEccentricAxisDistance", "DS", "1" }, { 0x300a, 0x0125, "Table Top Eccentric Angle", "TableTopEccentricAngle", "DS", "1" }, { 0x300a, 0x0126, "Table Top Eccentric Rotation Direction", "TableTopEccentricRotationDirection", "CS", "1" }, { 0x300a, 0x0128, "Table Top Vertical Position", "TableTopVerticalPosition", "DS", "1" }, { 0x300a, 0x0129, "Table Top Longitudinal Position", "TableTopLongitudinalPosition", "DS", "1" }, { 0x300a, 0x012a, "Table Top Lateral Position", "TableTopLateralPosition", "DS", "1" }, { 0x300a, 0x012c, "Isocenter Position", "IsocenterPosition", "DS", "3" }, { 0x300a, 0x012e, "Surface Entry Point", "SurfaceEntryPoint", "DS", "3" }, { 0x300a, 0x0130, "Source to Surface Distance", "SourceToSurfaceDistance", "DS", "1" }, { 0x300a, 0x0131, "Average Beam Dose Point Source to External Contour Surface Distance", "AverageBeamDosePointSourceToExternalContourSurfaceDistance", "FL", "1" }, { 0x300a, 0x0132, "Source to External Contour Distance", "SourceToExternalContourDistance", "FL", "1" }, { 0x300a, 0x0133, "External Contour Entry Point", "ExternalContourEntryPoint", "FL", "3" }, { 0x300a, 0x0134, "Cumulative Meterset Weight", "CumulativeMetersetWeight", "DS", "1" }, { 0x300a, 0x0140, "Table Top Pitch Angle", "TableTopPitchAngle", "FL", "1" }, { 0x300a, 0x0142, "Table Top Pitch Rotation Direction", "TableTopPitchRotationDirection", "CS", "1" }, { 0x300a, 0x0144, "Table Top Roll Angle", "TableTopRollAngle", "FL", "1" }, { 0x300a, 0x0146, "Table Top Roll Rotation Direction", "TableTopRollRotationDirection", "CS", "1" }, { 0x300a, 0x0148, "Head Fixation Angle", "HeadFixationAngle", "FL", "1" }, { 0x300a, 0x014a, "Gantry Pitch Angle", "GantryPitchAngle", "FL", "1" }, { 0x300a, 0x014c, "Gantry Pitch Rotation Direction", "GantryPitchRotationDirection", "CS", "1" }, { 0x300a, 0x014e, "Gantry Pitch Angle Tolerance", "GantryPitchAngleTolerance", "FL", "1" }, { 0x300a, 0x0180, "Patient Setup Sequence", "PatientSetupSequence", "SQ", "1" }, { 0x300a, 0x0182, "Patient Setup Number", "PatientSetupNumber", "IS", "1" }, { 0x300a, 0x0183, "Patient Setup Label", "PatientSetupLabel", "LO", "1" }, { 0x300a, 0x0184, "Patient Additional Position", "PatientAdditionalPosition", "LO", "1" }, { 0x300a, 0x0190, "Fixation Device Sequence", "FixationDeviceSequence", "SQ", "1" }, { 0x300a, 0x0192, "Fixation Device Type", "FixationDeviceType", "CS", "1" }, { 0x300a, 0x0194, "Fixation Device Label", "FixationDeviceLabel", "SH", "1" }, { 0x300a, 0x0196, "Fixation Device Description", "FixationDeviceDescription", "ST", "1" }, { 0x300a, 0x0198, "Fixation Device Position", "FixationDevicePosition", "SH", "1" }, { 0x300a, 0x0199, "Fixation Device Pitch Angle", "FixationDevicePitchAngle", "FL", "1" }, { 0x300a, 0x019a, "Fixation Device Roll Angle", "FixationDeviceRollAngle", "FL", "1" }, { 0x300a, 0x01a0, "Shielding Device Sequence", "ShieldingDeviceSequence", "SQ", "1" }, { 0x300a, 0x01a2, "Shielding Device Type", "ShieldingDeviceType", "CS", "1" }, { 0x300a, 0x01a4, "Shielding Device Label", "ShieldingDeviceLabel", "SH", "1" }, { 0x300a, 0x01a6, "Shielding Device Description", "ShieldingDeviceDescription", "ST", "1" }, { 0x300a, 0x01a8, "Shielding Device Position", "ShieldingDevicePosition", "SH", "1" }, { 0x300a, 0x01b0, "Setup Technique", "SetupTechnique", "CS", "1" }, { 0x300a, 0x01b2, "Setup Technique Description", "SetupTechniqueDescription", "ST", "1" }, { 0x300a, 0x01b4, "Setup Device Sequence", "SetupDeviceSequence", "SQ", "1" }, { 0x300a, 0x01b6, "Setup Device Type", "SetupDeviceType", "CS", "1" }, { 0x300a, 0x01b8, "Setup Device Label", "SetupDeviceLabel", "SH", "1" }, { 0x300a, 0x01ba, "Setup Device Description", "SetupDeviceDescription", "ST", "1" }, { 0x300a, 0x01bc, "Setup Device Parameter", "SetupDeviceParameter", "DS", "1" }, { 0x300a, 0x01d0, "Setup Reference Description", "SetupReferenceDescription", "ST", "1" }, { 0x300a, 0x01d2, "Table Top Vertical Setup Displacement", "TableTopVerticalSetupDisplacement", "DS", "1" }, { 0x300a, 0x01d4, "Table Top Longitudinal Setup Displacement", "TableTopLongitudinalSetupDisplacement", "DS", "1" }, { 0x300a, 0x01d6, "Table Top Lateral Setup Displacement", "TableTopLateralSetupDisplacement", "DS", "1" }, { 0x300a, 0x0200, "Brachy Treatment Technique", "BrachyTreatmentTechnique", "CS", "1" }, { 0x300a, 0x0202, "Brachy Treatment Type", "BrachyTreatmentType", "CS", "1" }, { 0x300a, 0x0206, "Treatment Machine Sequence", "TreatmentMachineSequence", "SQ", "1" }, { 0x300a, 0x0210, "Source Sequence", "SourceSequence", "SQ", "1" }, { 0x300a, 0x0212, "Source Number", "SourceNumber", "IS", "1" }, { 0x300a, 0x0214, "Source Type", "SourceType", "CS", "1" }, { 0x300a, 0x0216, "Source Manufacturer", "SourceManufacturer", "LO", "1" }, { 0x300a, 0x0218, "Active Source Diameter", "ActiveSourceDiameter", "DS", "1" }, { 0x300a, 0x021a, "Active Source Length", "ActiveSourceLength", "DS", "1" }, { 0x300a, 0x021b, "Source Model ID", "SourceModelID", "SH", "1" }, { 0x300a, 0x021c, "Source Description", "SourceDescription", "LO", "1" }, { 0x300a, 0x0222, "Source Encapsulation Nominal Thickness", "SourceEncapsulationNominalThickness", "DS", "1" }, { 0x300a, 0x0224, "Source Encapsulation Nominal Transmission", "SourceEncapsulationNominalTransmission", "DS", "1" }, { 0x300a, 0x0226, "Source Isotope Name", "SourceIsotopeName", "LO", "1" }, { 0x300a, 0x0228, "Source Isotope Half Life", "SourceIsotopeHalfLife", "DS", "1" }, { 0x300a, 0x0229, "Source Strength Units", "SourceStrengthUnits", "CS", "1" }, { 0x300a, 0x022a, "Reference Air Kerma Rate", "ReferenceAirKermaRate", "DS", "1" }, { 0x300a, 0x022b, "Source Strength", "SourceStrength", "DS", "1" }, { 0x300a, 0x022c, "Source Strength Reference Date", "SourceStrengthReferenceDate", "DA", "1" }, { 0x300a, 0x022e, "Source Strength Reference Time", "SourceStrengthReferenceTime", "TM", "1" }, { 0x300a, 0x0230, "Application Setup Sequence", "ApplicationSetupSequence", "SQ", "1" }, { 0x300a, 0x0232, "Application Setup Type", "ApplicationSetupType", "CS", "1" }, { 0x300a, 0x0234, "Application Setup Number", "ApplicationSetupNumber", "IS", "1" }, { 0x300a, 0x0236, "Application Setup Name", "ApplicationSetupName", "LO", "1" }, { 0x300a, 0x0238, "Application Setup Manufacturer", "ApplicationSetupManufacturer", "LO", "1" }, { 0x300a, 0x0240, "Template Number", "TemplateNumber", "IS", "1" }, { 0x300a, 0x0242, "Template Type", "TemplateType", "SH", "1" }, { 0x300a, 0x0244, "Template Name", "TemplateName", "LO", "1" }, { 0x300a, 0x0250, "Total Reference Air Kerma", "TotalReferenceAirKerma", "DS", "1" }, { 0x300a, 0x0260, "Brachy Accessory Device Sequence", "BrachyAccessoryDeviceSequence", "SQ", "1" }, { 0x300a, 0x0262, "Brachy Accessory Device Number", "BrachyAccessoryDeviceNumber", "IS", "1" }, { 0x300a, 0x0263, "Brachy Accessory Device ID", "BrachyAccessoryDeviceID", "SH", "1" }, { 0x300a, 0x0264, "Brachy Accessory Device Type", "BrachyAccessoryDeviceType", "CS", "1" }, { 0x300a, 0x0266, "Brachy Accessory Device Name", "BrachyAccessoryDeviceName", "LO", "1" }, { 0x300a, 0x026a, "Brachy Accessory Device Nominal Thickness", "BrachyAccessoryDeviceNominalThickness", "DS", "1" }, { 0x300a, 0x026c, "Brachy Accessory Device Nominal Transmission", "BrachyAccessoryDeviceNominalTransmission", "DS", "1" }, { 0x300a, 0x0280, "Channel Sequence", "ChannelSequence", "SQ", "1" }, { 0x300a, 0x0282, "Channel Number", "ChannelNumber", "IS", "1" }, { 0x300a, 0x0284, "Channel Length", "ChannelLength", "DS", "1" }, { 0x300a, 0x0286, "Channel Total Time", "ChannelTotalTime", "DS", "1" }, { 0x300a, 0x0288, "Source Movement Type", "SourceMovementType", "CS", "1" }, { 0x300a, 0x028a, "Number of Pulses", "NumberOfPulses", "IS", "1" }, { 0x300a, 0x028c, "Pulse Repetition Interval", "PulseRepetitionInterval", "DS", "1" }, { 0x300a, 0x0290, "Source Applicator Number", "SourceApplicatorNumber", "IS", "1" }, { 0x300a, 0x0291, "Source Applicator ID", "SourceApplicatorID", "SH", "1" }, { 0x300a, 0x0292, "Source Applicator Type", "SourceApplicatorType", "CS", "1" }, { 0x300a, 0x0294, "Source Applicator Name", "SourceApplicatorName", "LO", "1" }, { 0x300a, 0x0296, "Source Applicator Length", "SourceApplicatorLength", "DS", "1" }, { 0x300a, 0x0298, "Source Applicator Manufacturer", "SourceApplicatorManufacturer", "LO", "1" }, { 0x300a, 0x029c, "Source Applicator Wall Nominal Thickness", "SourceApplicatorWallNominalThickness", "DS", "1" }, { 0x300a, 0x029e, "Source Applicator Wall Nominal Transmission", "SourceApplicatorWallNominalTransmission", "DS", "1" }, { 0x300a, 0x02a0, "Source Applicator Step Size", "SourceApplicatorStepSize", "DS", "1" }, { 0x300a, 0x02a2, "Transfer Tube Number", "TransferTubeNumber", "IS", "1" }, { 0x300a, 0x02a4, "Transfer Tube Length", "TransferTubeLength", "DS", "1" }, { 0x300a, 0x02b0, "Channel Shield Sequence", "ChannelShieldSequence", "SQ", "1" }, { 0x300a, 0x02b2, "Channel Shield Number", "ChannelShieldNumber", "IS", "1" }, { 0x300a, 0x02b3, "Channel Shield ID", "ChannelShieldID", "SH", "1" }, { 0x300a, 0x02b4, "Channel Shield Name", "ChannelShieldName", "LO", "1" }, { 0x300a, 0x02b8, "Channel Shield Nominal Thickness", "ChannelShieldNominalThickness", "DS", "1" }, { 0x300a, 0x02ba, "Channel Shield Nominal Transmission", "ChannelShieldNominalTransmission", "DS", "1" }, { 0x300a, 0x02c8, "Final Cumulative Time Weight", "FinalCumulativeTimeWeight", "DS", "1" }, { 0x300a, 0x02d0, "Brachy Control Point Sequence", "BrachyControlPointSequence", "SQ", "1" }, { 0x300a, 0x02d2, "Control Point Relative Position", "ControlPointRelativePosition", "DS", "1" }, { 0x300a, 0x02d4, "Control Point 3D Position", "ControlPoint3DPosition", "DS", "3" }, { 0x300a, 0x02d6, "Cumulative Time Weight", "CumulativeTimeWeight", "DS", "1" }, { 0x300a, 0x02e0, "Compensator Divergence", "CompensatorDivergence", "CS", "1" }, { 0x300a, 0x02e1, "Compensator Mounting Position", "CompensatorMountingPosition", "CS", "1" }, { 0x300a, 0x02e2, "Source to Compensator Distance", "SourceToCompensatorDistance", "DS", "1-n" }, { 0x300a, 0x02e3, "Total Compensator Tray Water-Equivalent Thickness", "TotalCompensatorTrayWaterEquivalentThickness", "FL", "1" }, { 0x300a, 0x02e4, "Isocenter to Compensator Tray Distance", "IsocenterToCompensatorTrayDistance", "FL", "1" }, { 0x300a, 0x02e5, "Compensator Column Offset", "CompensatorColumnOffset", "FL", "1" }, { 0x300a, 0x02e6, "Isocenter to Compensator Distances", "IsocenterToCompensatorDistances", "FL", "1-n" }, { 0x300a, 0x02e7, "Compensator Relative Stopping Power Ratio", "CompensatorRelativeStoppingPowerRatio", "FL", "1" }, { 0x300a, 0x02e8, "Compensator Milling Tool Diameter", "CompensatorMillingToolDiameter", "FL", "1" }, { 0x300a, 0x02ea, "Ion Range Compensator Sequence", "IonRangeCompensatorSequence", "SQ", "1" }, { 0x300a, 0x02eb, "Compensator Description", "CompensatorDescription", "LT", "1" }, { 0x300a, 0x0302, "Radiation Mass Number", "RadiationMassNumber", "IS", "1" }, { 0x300a, 0x0304, "Radiation Atomic Number", "RadiationAtomicNumber", "IS", "1" }, { 0x300a, 0x0306, "Radiation Charge State", "RadiationChargeState", "SS", "1" }, { 0x300a, 0x0308, "Scan Mode", "ScanMode", "CS", "1" }, { 0x300a, 0x030a, "Virtual Source-Axis Distances", "VirtualSourceAxisDistances", "FL", "2" }, { 0x300a, 0x030c, "Snout Sequence", "SnoutSequence", "SQ", "1" }, { 0x300a, 0x030d, "Snout Position", "SnoutPosition", "FL", "1" }, { 0x300a, 0x030f, "Snout ID", "SnoutID", "SH", "1" }, { 0x300a, 0x0312, "Number of Range Shifters", "NumberOfRangeShifters", "IS", "1" }, { 0x300a, 0x0314, "Range Shifter Sequence", "RangeShifterSequence", "SQ", "1" }, { 0x300a, 0x0316, "Range Shifter Number", "RangeShifterNumber", "IS", "1" }, { 0x300a, 0x0318, "Range Shifter ID", "RangeShifterID", "SH", "1" }, { 0x300a, 0x0320, "Range Shifter Type", "RangeShifterType", "CS", "1" }, { 0x300a, 0x0322, "Range Shifter Description", "RangeShifterDescription", "LO", "1" }, { 0x300a, 0x0330, "Number of Lateral Spreading Devices", "NumberOfLateralSpreadingDevices", "IS", "1" }, { 0x300a, 0x0332, "Lateral Spreading Device Sequence", "LateralSpreadingDeviceSequence", "SQ", "1" }, { 0x300a, 0x0334, "Lateral Spreading Device Number", "LateralSpreadingDeviceNumber", "IS", "1" }, { 0x300a, 0x0336, "Lateral Spreading Device ID", "LateralSpreadingDeviceID", "SH", "1" }, { 0x300a, 0x0338, "Lateral Spreading Device Type", "LateralSpreadingDeviceType", "CS", "1" }, { 0x300a, 0x033a, "Lateral Spreading Device Description", "LateralSpreadingDeviceDescription", "LO", "1" }, { 0x300a, 0x033c, "Lateral Spreading Device Water Equivalent Thickness", "LateralSpreadingDeviceWaterEquivalentThickness", "FL", "1" }, { 0x300a, 0x0340, "Number of Range Modulators", "NumberOfRangeModulators", "IS", "1" }, { 0x300a, 0x0342, "Range Modulator Sequence", "RangeModulatorSequence", "SQ", "1" }, { 0x300a, 0x0344, "Range Modulator Number", "RangeModulatorNumber", "IS", "1" }, { 0x300a, 0x0346, "Range Modulator ID", "RangeModulatorID", "SH", "1" }, { 0x300a, 0x0348, "Range Modulator Type", "RangeModulatorType", "CS", "1" }, { 0x300a, 0x034a, "Range Modulator Description", "RangeModulatorDescription", "LO", "1" }, { 0x300a, 0x034c, "Beam Current Modulation ID", "BeamCurrentModulationID", "SH", "1" }, { 0x300a, 0x0350, "Patient Support Type", "PatientSupportType", "CS", "1" }, { 0x300a, 0x0352, "Patient Support ID", "PatientSupportID", "SH", "1" }, { 0x300a, 0x0354, "Patient Support Accessory Code", "PatientSupportAccessoryCode", "LO", "1" }, { 0x300a, 0x0356, "Fixation Light Azimuthal Angle", "FixationLightAzimuthalAngle", "FL", "1" }, { 0x300a, 0x0358, "Fixation Light Polar Angle", "FixationLightPolarAngle", "FL", "1" }, { 0x300a, 0x035a, "Meterset Rate", "MetersetRate", "FL", "1" }, { 0x300a, 0x0360, "Range Shifter Settings Sequence", "RangeShifterSettingsSequence", "SQ", "1" }, { 0x300a, 0x0362, "Range Shifter Setting", "RangeShifterSetting", "LO", "1" }, { 0x300a, 0x0364, "Isocenter to Range Shifter Distance", "IsocenterToRangeShifterDistance", "FL", "1" }, { 0x300a, 0x0366, "Range Shifter Water Equivalent Thickness", "RangeShifterWaterEquivalentThickness", "FL", "1" }, { 0x300a, 0x0370, "Lateral Spreading Device Settings Sequence", "LateralSpreadingDeviceSettingsSequence", "SQ", "1" }, { 0x300a, 0x0372, "Lateral Spreading Device Setting", "LateralSpreadingDeviceSetting", "LO", "1" }, { 0x300a, 0x0374, "Isocenter to Lateral Spreading Device Distance", "IsocenterToLateralSpreadingDeviceDistance", "FL", "1" }, { 0x300a, 0x0380, "Range Modulator Settings Sequence", "RangeModulatorSettingsSequence", "SQ", "1" }, { 0x300a, 0x0382, "Range Modulator Gating Start Value", "RangeModulatorGatingStartValue", "FL", "1" }, { 0x300a, 0x0384, "Range Modulator Gating Stop Value", "RangeModulatorGatingStopValue", "FL", "1" }, { 0x300a, 0x0386, "Range Modulator Gating Start Water Equivalent Thickness", "RangeModulatorGatingStartWaterEquivalentThickness", "FL", "1" }, { 0x300a, 0x0388, "Range Modulator Gating Stop Water Equivalent Thickness", "RangeModulatorGatingStopWaterEquivalentThickness", "FL", "1" }, { 0x300a, 0x038a, "Isocenter to Range Modulator Distance", "IsocenterToRangeModulatorDistance", "FL", "1" }, { 0x300a, 0x0390, "Scan Spot Tune ID", "ScanSpotTuneID", "SH", "1" }, { 0x300a, 0x0392, "Number of Scan Spot Positions", "NumberOfScanSpotPositions", "IS", "1" }, { 0x300a, 0x0394, "Scan Spot Position Map", "ScanSpotPositionMap", "FL", "1-n" }, { 0x300a, 0x0396, "Scan Spot Meterset Weights", "ScanSpotMetersetWeights", "FL", "1-n" }, { 0x300a, 0x0398, "Scanning Spot Size", "ScanningSpotSize", "FL", "2" }, { 0x300a, 0x039a, "Number of Paintings", "NumberOfPaintings", "IS", "1" }, { 0x300a, 0x03a0, "Ion Tolerance Table Sequence", "IonToleranceTableSequence", "SQ", "1" }, { 0x300a, 0x03a2, "Ion Beam Sequence", "IonBeamSequence", "SQ", "1" }, { 0x300a, 0x03a4, "Ion Beam Limiting Device Sequence", "IonBeamLimitingDeviceSequence", "SQ", "1" }, { 0x300a, 0x03a6, "Ion Block Sequence", "IonBlockSequence", "SQ", "1" }, { 0x300a, 0x03a8, "Ion Control Point Sequence", "IonControlPointSequence", "SQ", "1" }, { 0x300a, 0x03aa, "Ion Wedge Sequence", "IonWedgeSequence", "SQ", "1" }, { 0x300a, 0x03ac, "Ion Wedge Position Sequence", "IonWedgePositionSequence", "SQ", "1" }, { 0x300a, 0x0401, "Referenced Setup Image Sequence", "ReferencedSetupImageSequence", "SQ", "1" }, { 0x300a, 0x0402, "Setup Image Comment", "SetupImageComment", "ST", "1" }, { 0x300a, 0x0410, "Motion Synchronization Sequence", "MotionSynchronizationSequence", "SQ", "1" }, { 0x300a, 0x0412, "Control Point Orientation", "ControlPointOrientation", "FL", "3" }, { 0x300a, 0x0420, "General Accessory Sequence", "GeneralAccessorySequence", "SQ", "1" }, { 0x300a, 0x0421, "General Accessory ID", "GeneralAccessoryID", "SH", "1" }, { 0x300a, 0x0422, "General Accessory Description", "GeneralAccessoryDescription", "ST", "1" }, { 0x300a, 0x0423, "General Accessory Type", "GeneralAccessoryType", "CS", "1" }, { 0x300a, 0x0424, "General Accessory Number", "GeneralAccessoryNumber", "IS", "1" }, { 0x300a, 0x0425, "Source to General Accessory Distance", "SourceToGeneralAccessoryDistance", "FL", "1" }, { 0x300a, 0x0431, "Applicator Geometry Sequence", "ApplicatorGeometrySequence", "SQ", "1" }, { 0x300a, 0x0432, "Applicator Aperture Shape", "ApplicatorApertureShape", "CS", "1" }, { 0x300a, 0x0433, "Applicator Opening", "ApplicatorOpening", "FL", "1" }, { 0x300a, 0x0434, "Applicator Opening X", "ApplicatorOpeningX", "FL", "1" }, { 0x300a, 0x0435, "Applicator Opening Y", "ApplicatorOpeningY", "FL", "1" }, { 0x300a, 0x0436, "Source to Applicator Mounting Position Distance", "SourceToApplicatorMountingPositionDistance", "FL", "1" }, { 0x300a, 0x0440, "Number of Block Slab Items", "NumberOfBlockSlabItems", "IS", "1" }, { 0x300a, 0x0441, "Block Slab Sequence", "BlockSlabSequence", "SQ", "1" }, { 0x300a, 0x0442, "Block Slab Thickness", "BlockSlabThickness", "DS", "1" }, { 0x300a, 0x0443, "Block Slab Number", "BlockSlabNumber", "US", "1" }, { 0x300a, 0x0450, "Device Motion Control Sequence", "DeviceMotionControlSequence", "SQ", "1" }, { 0x300a, 0x0451, "Device Motion Execution Mode", "DeviceMotionExecutionMode", "CS", "1" }, { 0x300a, 0x0452, "Device Motion Observation Mode", "DeviceMotionObservationMode", "CS", "1" }, { 0x300a, 0x0453, "Device Motion Parameter Code Sequence", "DeviceMotionParameterCodeSequence", "SQ", "1" }, { 0x300c, 0x0002, "Referenced RT Plan Sequence", "ReferencedRTPlanSequence", "SQ", "1" }, { 0x300c, 0x0004, "Referenced Beam Sequence", "ReferencedBeamSequence", "SQ", "1" }, { 0x300c, 0x0006, "Referenced Beam Number", "ReferencedBeamNumber", "IS", "1" }, { 0x300c, 0x0007, "Referenced Reference Image Number", "ReferencedReferenceImageNumber", "IS", "1" }, { 0x300c, 0x0008, "Start Cumulative Meterset Weight", "StartCumulativeMetersetWeight", "DS", "1" }, { 0x300c, 0x0009, "End Cumulative Meterset Weight", "EndCumulativeMetersetWeight", "DS", "1" }, { 0x300c, 0x000a, "Referenced Brachy Application Setup Sequence", "ReferencedBrachyApplicationSetupSequence", "SQ", "1" }, { 0x300c, 0x000c, "Referenced Brachy Application Setup Number", "ReferencedBrachyApplicationSetupNumber", "IS", "1" }, { 0x300c, 0x000e, "Referenced Source Number", "ReferencedSourceNumber", "IS", "1" }, { 0x300c, 0x0020, "Referenced Fraction Group Sequence", "ReferencedFractionGroupSequence", "SQ", "1" }, { 0x300c, 0x0022, "Referenced Fraction Group Number", "ReferencedFractionGroupNumber", "IS", "1" }, { 0x300c, 0x0040, "Referenced Verification Image Sequence", "ReferencedVerificationImageSequence", "SQ", "1" }, { 0x300c, 0x0042, "Referenced Reference Image Sequence", "ReferencedReferenceImageSequence", "SQ", "1" }, { 0x300c, 0x0050, "Referenced Dose Reference Sequence", "ReferencedDoseReferenceSequence", "SQ", "1" }, { 0x300c, 0x0051, "Referenced Dose Reference Number", "ReferencedDoseReferenceNumber", "IS", "1" }, { 0x300c, 0x0055, "Brachy Referenced Dose Reference Sequence", "BrachyReferencedDoseReferenceSequence", "SQ", "1" }, { 0x300c, 0x0060, "Referenced Structure Set Sequence", "ReferencedStructureSetSequence", "SQ", "1" }, { 0x300c, 0x006a, "Referenced Patient Setup Number", "ReferencedPatientSetupNumber", "IS", "1" }, { 0x300c, 0x0080, "Referenced Dose Sequence", "ReferencedDoseSequence", "SQ", "1" }, { 0x300c, 0x00a0, "Referenced Tolerance Table Number", "ReferencedToleranceTableNumber", "IS", "1" }, { 0x300c, 0x00b0, "Referenced Bolus Sequence", "ReferencedBolusSequence", "SQ", "1" }, { 0x300c, 0x00c0, "Referenced Wedge Number", "ReferencedWedgeNumber", "IS", "1" }, { 0x300c, 0x00d0, "Referenced Compensator Number", "ReferencedCompensatorNumber", "IS", "1" }, { 0x300c, 0x00e0, "Referenced Block Number", "ReferencedBlockNumber", "IS", "1" }, { 0x300c, 0x00f0, "Referenced Control Point Index", "ReferencedControlPointIndex", "IS", "1" }, { 0x300c, 0x00f2, "Referenced Control Point Sequence", "ReferencedControlPointSequence", "SQ", "1" }, { 0x300c, 0x00f4, "Referenced Start Control Point Index", "ReferencedStartControlPointIndex", "IS", "1" }, { 0x300c, 0x00f6, "Referenced Stop Control Point Index", "ReferencedStopControlPointIndex", "IS", "1" }, { 0x300c, 0x0100, "Referenced Range Shifter Number", "ReferencedRangeShifterNumber", "IS", "1" }, { 0x300c, 0x0102, "Referenced Lateral Spreading Device Number", "ReferencedLateralSpreadingDeviceNumber", "IS", "1" }, { 0x300c, 0x0104, "Referenced Range Modulator Number", "ReferencedRangeModulatorNumber", "IS", "1" }, { 0x300c, 0x0111, "Omitted Beam Task Sequence", "OmittedBeamTaskSequence", "SQ", "1" }, { 0x300c, 0x0112, "Reason for Omission", "ReasonForOmission", "CS", "1" }, { 0x300c, 0x0113, "Reason for Omission Description", "ReasonForOmissionDescription", "LO", "1" }, { 0x300e, 0x0002, "Approval Status", "ApprovalStatus", "CS", "1" }, { 0x300e, 0x0004, "Review Date", "ReviewDate", "DA", "1" }, { 0x300e, 0x0005, "Review Time", "ReviewTime", "TM", "1" }, { 0x300e, 0x0008, "Reviewer Name", "ReviewerName", "PN", "1" }, { 0x4000, 0x0010, "Arbitrary", "Arbitrary", "LT", "1" }, { 0x4000, 0x4000, "Text Comments", "TextComments", "LT", "1" }, { 0x4008, 0x0040, "Results ID", "ResultsID", "SH", "1" }, { 0x4008, 0x0042, "Results ID Issuer", "ResultsIDIssuer", "LO", "1" }, { 0x4008, 0x0050, "Referenced Interpretation Sequence", "ReferencedInterpretationSequence", "SQ", "1" }, { 0x4008, 0x00ff, "Report Production Status (Trial)", "ReportProductionStatusTrial", "CS", "1" }, { 0x4008, 0x0100, "Interpretation Recorded Date", "InterpretationRecordedDate", "DA", "1" }, { 0x4008, 0x0101, "Interpretation Recorded Time", "InterpretationRecordedTime", "TM", "1" }, { 0x4008, 0x0102, "Interpretation Recorder", "InterpretationRecorder", "PN", "1" }, { 0x4008, 0x0103, "Reference to Recorded Sound", "ReferenceToRecordedSound", "LO", "1" }, { 0x4008, 0x0108, "Interpretation Transcription Date", "InterpretationTranscriptionDate", "DA", "1" }, { 0x4008, 0x0109, "Interpretation Transcription Time", "InterpretationTranscriptionTime", "TM", "1" }, { 0x4008, 0x010a, "Interpretation Transcriber", "InterpretationTranscriber", "PN", "1" }, { 0x4008, 0x010b, "Interpretation Text", "InterpretationText", "ST", "1" }, { 0x4008, 0x010c, "Interpretation Author", "InterpretationAuthor", "PN", "1" }, { 0x4008, 0x0111, "Interpretation Approver Sequence", "InterpretationApproverSequence", "SQ", "1" }, { 0x4008, 0x0112, "Interpretation Approval Date", "InterpretationApprovalDate", "DA", "1" }, { 0x4008, 0x0113, "Interpretation Approval Time", "InterpretationApprovalTime", "TM", "1" }, { 0x4008, 0x0114, "Physician Approving Interpretation", "PhysicianApprovingInterpretation", "PN", "1" }, { 0x4008, 0x0115, "Interpretation Diagnosis Description", "InterpretationDiagnosisDescription", "LT", "1" }, { 0x4008, 0x0117, "Interpretation Diagnosis Code Sequence", "InterpretationDiagnosisCodeSequence", "SQ", "1" }, { 0x4008, 0x0118, "Results Distribution List Sequence", "ResultsDistributionListSequence", "SQ", "1" }, { 0x4008, 0x0119, "Distribution Name", "DistributionName", "PN", "1" }, { 0x4008, 0x011a, "Distribution Address", "DistributionAddress", "LO", "1" }, { 0x4008, 0x0200, "Interpretation ID", "InterpretationID", "SH", "1" }, { 0x4008, 0x0202, "Interpretation ID Issuer", "InterpretationIDIssuer", "LO", "1" }, { 0x4008, 0x0210, "Interpretation Type ID", "InterpretationTypeID", "CS", "1" }, { 0x4008, 0x0212, "Interpretation Status ID", "InterpretationStatusID", "CS", "1" }, { 0x4008, 0x0300, "Impressions", "Impressions", "ST", "1" }, { 0x4008, 0x4000, "Results Comments", "ResultsComments", "ST", "1" }, { 0x4010, 0x0001, "Low Energy Detectors", "LowEnergyDetectors", "CS", "1" }, { 0x4010, 0x0002, "High Energy Detectors", "HighEnergyDetectors", "CS", "1" }, { 0x4010, 0x0004, "Detector Geometry Sequence", "DetectorGeometrySequence", "SQ", "1" }, { 0x4010, 0x1001, "Threat ROI Voxel Sequence", "ThreatROIVoxelSequence", "SQ", "1" }, { 0x4010, 0x1004, "Threat ROI Base", "ThreatROIBase", "FL", "3" }, { 0x4010, 0x1005, "Threat ROI Extents", "ThreatROIExtents", "FL", "3" }, { 0x4010, 0x1006, "Threat ROI Bitmap", "ThreatROIBitmap", "OB", "1" }, { 0x4010, 0x1007, "Route Segment ID", "RouteSegmentID", "SH", "1" }, { 0x4010, 0x1008, "Gantry Type", "GantryType", "CS", "1" }, { 0x4010, 0x1009, "OOI Owner Type", "OOIOwnerType", "CS", "1" }, { 0x4010, 0x100a, "Route Segment Sequence", "RouteSegmentSequence", "SQ", "1" }, { 0x4010, 0x1010, "Potential Threat Object ID", "PotentialThreatObjectID", "US", "1" }, { 0x4010, 0x1011, "Threat Sequence", "ThreatSequence", "SQ", "1" }, { 0x4010, 0x1012, "Threat Category", "ThreatCategory", "CS", "1" }, { 0x4010, 0x1013, "Threat Category Description", "ThreatCategoryDescription", "LT", "1" }, { 0x4010, 0x1014, "ATD Ability Assessment", "ATDAbilityAssessment", "CS", "1" }, { 0x4010, 0x1015, "ATD Assessment Flag", "ATDAssessmentFlag", "CS", "1" }, { 0x4010, 0x1016, "ATD Assessment Probability", "ATDAssessmentProbability", "FL", "1" }, { 0x4010, 0x1017, "Mass", "Mass", "FL", "1" }, { 0x4010, 0x1018, "Density", "Density", "FL", "1" }, { 0x4010, 0x1019, "Z Effective", "ZEffective", "FL", "1" }, { 0x4010, 0x101a, "Boarding Pass ID", "BoardingPassID", "SH", "1" }, { 0x4010, 0x101b, "Center of Mass", "CenterOfMass", "FL", "3" }, { 0x4010, 0x101c, "Center of PTO", "CenterOfPTO", "FL", "3" }, { 0x4010, 0x101d, "Bounding Polygon", "BoundingPolygon", "FL", "6-n" }, { 0x4010, 0x101e, "Route Segment Start Location ID", "RouteSegmentStartLocationID", "SH", "1" }, { 0x4010, 0x101f, "Route Segment End Location ID", "RouteSegmentEndLocationID", "SH", "1" }, { 0x4010, 0x1020, "Route Segment Location ID Type", "RouteSegmentLocationIDType", "CS", "1" }, { 0x4010, 0x1021, "Abort Reason", "AbortReason", "CS", "1-n" }, { 0x4010, 0x1023, "Volume of PTO", "VolumeOfPTO", "FL", "1" }, { 0x4010, 0x1024, "Abort Flag", "AbortFlag", "CS", "1" }, { 0x4010, 0x1025, "Route Segment Start Time", "RouteSegmentStartTime", "DT", "1" }, { 0x4010, 0x1026, "Route Segment End Time", "RouteSegmentEndTime", "DT", "1" }, { 0x4010, 0x1027, "TDR Type", "TDRType", "CS", "1" }, { 0x4010, 0x1028, "International Route Segment", "InternationalRouteSegment", "CS", "1" }, { 0x4010, 0x1029, "Threat Detection Algorithm and Version", "ThreatDetectionAlgorithmandVersion", "LO", "1-n" }, { 0x4010, 0x102a, "Assigned Location", "AssignedLocation", "SH", "1" }, { 0x4010, 0x102b, "Alarm Decision Time", "AlarmDecisionTime", "DT", "1" }, { 0x4010, 0x1031, "Alarm Decision", "AlarmDecision", "CS", "1" }, { 0x4010, 0x1033, "Number of Total Objects", "NumberOfTotalObjects", "US", "1" }, { 0x4010, 0x1034, "Number of Alarm Objects", "NumberOfAlarmObjects", "US", "1" }, { 0x4010, 0x1037, "PTO Representation Sequence", "PTORepresentationSequence", "SQ", "1" }, { 0x4010, 0x1038, "ATD Assessment Sequence", "ATDAssessmentSequence", "SQ", "1" }, { 0x4010, 0x1039, "TIP Type", "TIPType", "CS", "1" }, { 0x4010, 0x103a, "DICOS Version", "DICOSVersion", "CS", "1" }, { 0x4010, 0x1041, "OOI Owner Creation Time", "OOIOwnerCreationTime", "DT", "1" }, { 0x4010, 0x1042, "OOI Type", "OOIType", "CS", "1" }, { 0x4010, 0x1043, "OOI Size", "OOISize", "FL", "3" }, { 0x4010, 0x1044, "Acquisition Status", "AcquisitionStatus", "CS", "1" }, { 0x4010, 0x1045, "Basis Materials Code Sequence", "BasisMaterialsCodeSequence", "SQ", "1" }, { 0x4010, 0x1046, "Phantom Type", "PhantomType", "CS", "1" }, { 0x4010, 0x1047, "OOI Owner Sequence", "OOIOwnerSequence", "SQ", "1" }, { 0x4010, 0x1048, "Scan Type", "ScanType", "CS", "1" }, { 0x4010, 0x1051, "Itinerary ID", "ItineraryID", "LO", "1" }, { 0x4010, 0x1052, "Itinerary ID Type", "ItineraryIDType", "SH", "1" }, { 0x4010, 0x1053, "Itinerary ID Assigning Authority", "ItineraryIDAssigningAuthority", "LO", "1" }, { 0x4010, 0x1054, "Route ID", "RouteID", "SH", "1" }, { 0x4010, 0x1055, "Route ID Assigning Authority", "RouteIDAssigningAuthority", "SH", "1" }, { 0x4010, 0x1056, "Inbound Arrival Type", "InboundArrivalType", "CS", "1" }, { 0x4010, 0x1058, "Carrier ID", "CarrierID", "SH", "1" }, { 0x4010, 0x1059, "Carrier ID Assigning Authority", "CarrierIDAssigningAuthority", "CS", "1" }, { 0x4010, 0x1060, "Source Orientation", "SourceOrientation", "FL", "3" }, { 0x4010, 0x1061, "Source Position", "SourcePosition", "FL", "3" }, { 0x4010, 0x1062, "Belt Height", "BeltHeight", "FL", "1" }, { 0x4010, 0x1064, "Algorithm Routing Code Sequence", "AlgorithmRoutingCodeSequence", "SQ", "1" }, { 0x4010, 0x1067, "Transport Classification", "TransportClassification", "CS", "1" }, { 0x4010, 0x1068, "OOI Type Descriptor", "OOITypeDescriptor", "LT", "1" }, { 0x4010, 0x1069, "Total Processing Time", "TotalProcessingTime", "FL", "1" }, { 0x4010, 0x106c, "Detector Calibration Data", "DetectorCalibrationData", "OB", "1" }, { 0x4010, 0x106d, "Additional Screening Performed", "AdditionalScreeningPerformed", "CS", "1" }, { 0x4010, 0x106e, "Additional Inspection Selection Criteria", "AdditionalInspectionSelectionCriteria", "CS", "1" }, { 0x4010, 0x106f, "Additional Inspection Method Sequence", "AdditionalInspectionMethodSequence", "SQ", "1" }, { 0x4010, 0x1070, "AIT Device Type", "AITDeviceType", "CS", "1" }, { 0x4010, 0x1071, "QR Measurements Sequence", "QRMeasurementsSequence", "SQ", "1" }, { 0x4010, 0x1072, "Target Material Sequence", "TargetMaterialSequence", "SQ", "1" }, { 0x4010, 0x1073, "SNR Threshold", "SNRThreshold", "FD", "1" }, { 0x4010, 0x1075, "Image Scale Representation", "ImageScaleRepresentation", "DS", "1" }, { 0x4010, 0x1076, "Referenced PTO Sequence", "ReferencedPTOSequence", "SQ", "1" }, { 0x4010, 0x1077, "Referenced TDR Instance Sequence", "ReferencedTDRInstanceSequence", "SQ", "1" }, { 0x4010, 0x1078, "PTO Location Description", "PTOLocationDescription", "ST", "1" }, { 0x4010, 0x1079, "Anomaly Locator Indicator Sequence", "AnomalyLocatorIndicatorSequence", "SQ", "1" }, { 0x4010, 0x107a, "Anomaly Locator Indicator", "AnomalyLocatorIndicator", "FL", "3" }, { 0x4010, 0x107b, "PTO Region Sequence", "PTORegionSequence", "SQ", "1" }, { 0x4010, 0x107c, "Inspection Selection Criteria", "InspectionSelectionCriteria", "CS", "1" }, { 0x4010, 0x107d, "Secondary Inspection Method Sequence", "SecondaryInspectionMethodSequence", "SQ", "1" }, { 0x4010, 0x107e, "PRCS to RCS Orientation", "PRCSToRCSOrientation", "DS", "6" }, { 0x4ffe, 0x0001, "MAC Parameters Sequence", "MACParametersSequence", "SQ", "1" }, { 0x5200, 0x9229, "Shared Functional Groups Sequence", "SharedFunctionalGroupsSequence", "SQ", "1" }, { 0x5200, 0x9230, "Per-frame Functional Groups Sequence", "PerFrameFunctionalGroupsSequence", "SQ", "1" }, { 0x5400, 0x0100, "Waveform Sequence", "WaveformSequence", "SQ", "1" }, { 0x5400, 0x0110, "Channel Minimum Value", "ChannelMinimumValue", "OB or OW", "1" }, { 0x5400, 0x0112, "Channel Maximum Value", "ChannelMaximumValue", "OB or OW", "1" }, { 0x5400, 0x1004, "Waveform Bits Allocated", "WaveformBitsAllocated", "US", "1" }, { 0x5400, 0x1006, "Waveform Sample Interpretation", "WaveformSampleInterpretation", "CS", "1" }, { 0x5400, 0x100a, "Waveform Padding Value", "WaveformPaddingValue", "OB or OW", "1" }, { 0x5400, 0x1010, "Waveform Data", "WaveformData", "OB or OW", "1" }, { 0x5600, 0x0010, "First Order Phase Correction Angle", "FirstOrderPhaseCorrectionAngle", "OF", "1" }, { 0x5600, 0x0020, "Spectroscopy Data", "SpectroscopyData", "OF", "1" }, { 0x7fe0, 0x0008, "Float Pixel Data", "FloatPixelData", "OF", "1" }, { 0x7fe0, 0x0009, "Double Float Pixel Data", "DoubleFloatPixelData", "OD", "1" }, { 0x7fe0, 0x0010, "Pixel Data", "PixelData", "OB or OW", "1" }, { 0x7fe0, 0x0020, "Coefficients SDVN", "CoefficientsSDVN", "OW", "1" }, { 0x7fe0, 0x0030, "Coefficients SDHN", "CoefficientsSDHN", "OW", "1" }, { 0x7fe0, 0x0040, "Coefficients SDDN", "CoefficientsSDDN", "OW", "1" }, { 0xfffa, 0xfffa, "Digital Signatures Sequence", "DigitalSignaturesSequence", "SQ", "1" }, { 0xfffc, 0xfffc, "Data Set Trailing Padding", "DataSetTrailingPadding", "OB", "1" }, { 0xfffe, 0xe000, "Item", "Item", "See Note ", "1" }, { 0xfffe, 0xe00d, "Item Delimitation Item", "ItemDelimitationItem", "See Note ", "1" }, { 0xfffe, 0xe0dd, "Sequence Delimitation Item", "SequenceDelimitationItem", "See Note ", "1" }, }; ElementsDictionary public_dictionary; unsigned long const count = sizeof(raw_entries)/sizeof(RawElementsDictionaryEntry); for(unsigned long i=0; i(tag, entry)); } return public_dictionary; } struct RawUIDsDictionaryEntry { char const * uid; char const * name; char const * keyword; char const * type; }; UIDsDictionary create_uids_dictionary() { RawUIDsDictionaryEntry raw_entries[] = { { "1.2.840.10008.1.1", "Verification SOP Class", "VerificationSOPClass", "SOP Class" }, { "1.2.840.10008.1.2", "Implicit VR Little Endian: Default Transfer Syntax for DICOM", "ImplicitVRLittleEndian", "Transfer Syntax" }, { "1.2.840.10008.1.2.1", "Explicit VR Little Endian", "ExplicitVRLittleEndian", "Transfer Syntax" }, { "1.2.840.10008.1.2.1.99", "Deflated Explicit VR Little Endian", "DeflatedExplicitVRLittleEndian", "Transfer Syntax" }, { "1.2.840.10008.1.2.2", "Explicit VR Big Endian (Retired)", "ExplicitVRBigEndian_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.50", "JPEG Baseline (Process 1): Default Transfer Syntax for Lossy JPEG 8 Bit Image Compression", "JPEGBaselineProcess1", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.51", "JPEG Extended (Process 2 & 4): Default Transfer Syntax for Lossy JPEG 12 Bit Image Compression (Process 4 only)", "JPEGExtendedProcess24", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.52", "JPEG Extended (Process 3 & 5) (Retired)", "JPEGExtendedProcess35_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.53", "JPEG Spectral Selection, Non-Hierarchical (Process 6 & 8) (Retired)", "JPEGSpectralSelectionNonHierarchicalProcess68_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.54", "JPEG Spectral Selection, Non-Hierarchical (Process 7 & 9) (Retired)", "JPEGSpectralSelectionNonHierarchicalProcess79_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.55", "JPEG Full Progression, Non-Hierarchical (Process 10 & 12) (Retired)", "JPEGFullProgressionNonHierarchicalProcess1012_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.56", "JPEG Full Progression, Non-Hierarchical (Process 11 & 13) (Retired)", "JPEGFullProgressionNonHierarchicalProcess1113_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.57", "JPEG Lossless, Non-Hierarchical (Process 14)", "JPEGLosslessNonHierarchicalProcess14", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.58", "JPEG Lossless, Non-Hierarchical (Process 15) (Retired)", "JPEGLosslessNonHierarchicalProcess15_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.59", "JPEG Extended, Hierarchical (Process 16 & 18) (Retired)", "JPEGExtendedHierarchicalProcess1618_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.60", "JPEG Extended, Hierarchical (Process 17 & 19) (Retired)", "JPEGExtendedHierarchicalProcess1719_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.61", "JPEG Spectral Selection, Hierarchical (Process 20 & 22) (Retired)", "JPEGSpectralSelectionHierarchicalProcess2022_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.62", "JPEG Spectral Selection, Hierarchical (Process 21 & 23) (Retired)", "JPEGSpectralSelectionHierarchicalProcess2123_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.63", "JPEG Full Progression, Hierarchical (Process 24 & 26) (Retired)", "JPEGFullProgressionHierarchicalProcess2426_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.64", "JPEG Full Progression, Hierarchical (Process 25 & 27) (Retired)", "JPEGFullProgressionHierarchicalProcess2527_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.65", "JPEG Lossless, Hierarchical (Process 28) (Retired)", "JPEGLosslessHierarchicalProcess28_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.66", "JPEG Lossless, Hierarchical (Process 29) (Retired)", "JPEGLosslessHierarchicalProcess29_Retired", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.70", "JPEG Lossless, Non-Hierarchical, First-Order Prediction (Process 14 [Selection Value 1]): Default Transfer Syntax for Lossless JPEG Image Compression", "JPEGLosslessNonHierarchicalFirstOrderPredictionProcess14SelectionValue1", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.80", "JPEG-LS Lossless Image Compression", "JPEGLSLosslessImageCompression", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.81", "JPEG-LS Lossy (Near-Lossless) Image Compression", "JPEGLSLossyNearLosslessImageCompression", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.90", "JPEG 2000 Image Compression (Lossless Only)", "JPEG2000ImageCompressionLosslessOnly", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.91", "JPEG 2000 Image Compression", "JPEG2000ImageCompression", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.92", "JPEG 2000 Part 2 Multi-component Image Compression (Lossless Only)", "JPEG2000Part2MulticomponentImageCompressionLosslessOnly", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.93", "JPEG 2000 Part 2 Multi-component Image Compression", "JPEG2000Part2MulticomponentImageCompression", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.94", "JPIP Referenced", "JPIPReferenced", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.95", "JPIP Referenced Deflate", "JPIPReferencedDeflate", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.100", "MPEG2 Main Profile @ Main Level", "MPEG2MainProfileMainLevel", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.101", "MPEG2 Main Profile @ High Level", "MPEG2MainProfileHighLevel", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.102", "MPEG-4 AVC/H.264 High Profile / Level 4.1", "MPEG4AVCH264HighProfileLevel41", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.103", "MPEG-4 AVC/H.264 BD-compatible High Profile / Level 4.1", "MPEG4AVCH264BDcompatibleHighProfileLevel41", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.104", "MPEG-4 AVC/H.264 High Profile / Level 4.2 For 2D Video", "MPEG4AVCH264HighProfileLevel42For2DVideo", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.105", "MPEG-4 AVC/H.264 High Profile / Level 4.2 For 3D Video", "MPEG4AVCH264HighProfileLevel42For3DVideo", "Transfer Syntax" }, { "1.2.840.10008.1.2.4.106", "MPEG-4 AVC/H.264 Stereo High Profile / Level 4.2", "MPEG4AVCH264StereoHighProfileLevel42", "Transfer Syntax" }, { "1.2.840.10008.1.2.5", "RLE Lossless", "RLELossless", "Transfer Syntax" }, { "1.2.840.10008.1.2.6.1", "RFC 2557 MIME encapsulation", "RFC2557MIMEencapsulation", "Transfer Syntax" }, { "1.2.840.10008.1.2.6.2", "XML Encoding", "XMLEncoding", "Transfer Syntax" }, { "1.2.840.10008.1.3.10", "Media Storage Directory Storage", "MediaStorageDirectoryStorage", "SOP Class" }, { "1.2.840.10008.1.4.1.1", "Talairach Brain Atlas Frame of Reference", "TalairachBrainAtlasFrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.2", "SPM2 T1 Frame of Reference", "SPM2T1FrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.3", "SPM2 T2 Frame of Reference", "SPM2T2FrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.4", "SPM2 PD Frame of Reference", "SPM2PDFrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.5", "SPM2 EPI Frame of Reference", "SPM2EPIFrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.6", "SPM2 FIL T1 Frame of Reference", "SPM2FILT1FrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.7", "SPM2 PET Frame of Reference", "SPM2PETFrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.8", "SPM2 TRANSM Frame of Reference", "SPM2TRANSMFrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.9", "SPM2 SPECT Frame of Reference", "SPM2SPECTFrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.10", "SPM2 GRAY Frame of Reference", "SPM2GRAYFrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.11", "SPM2 WHITE Frame of Reference", "SPM2WHITEFrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.12", "SPM2 CSF Frame of Reference", "SPM2CSFFrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.13", "SPM2 BRAINMASK Frame of Reference", "SPM2BRAINMASKFrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.14", "SPM2 AVG305T1 Frame of Reference", "SPM2AVG305T1FrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.15", "SPM2 AVG152T1 Frame of Reference", "SPM2AVG152T1FrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.16", "SPM2 AVG152T2 Frame of Reference", "SPM2AVG152T2FrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.17", "SPM2 AVG152PD Frame of Reference", "SPM2AVG152PDFrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.1.18", "SPM2 SINGLESUBJT1 Frame of Reference", "SPM2SINGLESUBJT1FrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.2.1", "ICBM 452 T1 Frame of Reference", "ICBM452T1FrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.4.2.2", "ICBM Single Subject MRI Frame of Reference", "ICBMSingleSubjectMRIFrameofReference", "Well-known frame of reference" }, { "1.2.840.10008.1.5.1", "Hot Iron Color Palette SOP Instance", "HotIronColorPaletteSOPInstance", "Well-known SOP Instance" }, { "1.2.840.10008.1.5.2", "PET Color Palette SOP Instance", "PETColorPaletteSOPInstance", "Well-known SOP Instance" }, { "1.2.840.10008.1.5.3", "Hot Metal Blue Color Palette SOP Instance", "HotMetalBlueColorPaletteSOPInstance", "Well-known SOP Instance" }, { "1.2.840.10008.1.5.4", "PET 20 Step Color Palette SOP Instance", "PET20StepColorPaletteSOPInstance", "Well-known SOP Instance" }, { "1.2.840.10008.1.9", "Basic Study Content Notification SOP Class (Retired)", "BasicStudyContentNotificationSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.1.20.1", "Storage Commitment Push Model SOP Class", "StorageCommitmentPushModelSOPClass", "SOP Class" }, { "1.2.840.10008.1.20.1.1", "Storage Commitment Push Model SOP Instance", "StorageCommitmentPushModelSOPInstance", "Well-known SOP Instance" }, { "1.2.840.10008.1.20.2", "Storage Commitment Pull Model SOP Class (Retired)", "StorageCommitmentPullModelSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.1.20.2.1", "Storage Commitment Pull Model SOP Instance (Retired)", "StorageCommitmentPullModelSOPInstance_Retired", "Well-known SOP Instance" }, { "1.2.840.10008.1.40", "Procedural Event Logging SOP Class", "ProceduralEventLoggingSOPClass", "SOP Class" }, { "1.2.840.10008.1.40.1", "Procedural Event Logging SOP Instance", "ProceduralEventLoggingSOPInstance", "Well-known SOP Instance" }, { "1.2.840.10008.1.42", "Substance Administration Logging SOP Class", "SubstanceAdministrationLoggingSOPClass", "SOP Class" }, { "1.2.840.10008.1.42.1", "Substance Administration Logging SOP Instance", "SubstanceAdministrationLoggingSOPInstance", "Well-known SOP Instance" }, { "1.2.840.10008.2.6.1", "DICOM UID Registry", "DICOMUIDRegistry", "DICOM UIDs as a Coding Scheme" }, { "1.2.840.10008.2.16.4", "DICOM Controlled Terminology", "DICOMControlledTerminology", "Coding Scheme" }, { "1.2.840.10008.3.1.1.1", "DICOM Application Context Name", "DICOMApplicationContextName", "Application Context Name" }, { "1.2.840.10008.3.1.2.1.1", "Detached Patient Management SOP Class (Retired)", "DetachedPatientManagementSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.3.1.2.1.4", "Detached Patient Management Meta SOP Class (Retired)", "DetachedPatientManagementMetaSOPClass_Retired", "Meta SOP Class" }, { "1.2.840.10008.3.1.2.2.1", "Detached Visit Management SOP Class (Retired)", "DetachedVisitManagementSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.3.1.2.3.1", "Detached Study Management SOP Class (Retired)", "DetachedStudyManagementSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.3.1.2.3.2", "Study Component Management SOP Class (Retired)", "StudyComponentManagementSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.3.1.2.3.3", "Modality Performed Procedure Step SOP Class", "ModalityPerformedProcedureStepSOPClass", "SOP Class" }, { "1.2.840.10008.3.1.2.3.4", "Modality Performed Procedure Step Retrieve SOP Class", "ModalityPerformedProcedureStepRetrieveSOPClass", "SOP Class" }, { "1.2.840.10008.3.1.2.3.5", "Modality Performed Procedure Step Notification SOP Class", "ModalityPerformedProcedureStepNotificationSOPClass", "SOP Class" }, { "1.2.840.10008.3.1.2.5.1", "Detached Results Management SOP Class (Retired)", "DetachedResultsManagementSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.3.1.2.5.4", "Detached Results Management Meta SOP Class (Retired)", "DetachedResultsManagementMetaSOPClass_Retired", "Meta SOP Class" }, { "1.2.840.10008.3.1.2.5.5", "Detached Study Management Meta SOP Class (Retired)", "DetachedStudyManagementMetaSOPClass_Retired", "Meta SOP Class" }, { "1.2.840.10008.3.1.2.6.1", "Detached Interpretation Management SOP Class (Retired)", "DetachedInterpretationManagementSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.4.2", "Storage Service Class", "StorageServiceClass", "Service Class" }, { "1.2.840.10008.5.1.1.1", "Basic Film Session SOP Class", "BasicFilmSessionSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.1.2", "Basic Film Box SOP Class", "BasicFilmBoxSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.1.4", "Basic Grayscale Image Box SOP Class", "BasicGrayscaleImageBoxSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.1.4.1", "Basic Color Image Box SOP Class", "BasicColorImageBoxSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.1.4.2", "Referenced Image Box SOP Class (Retired)", "ReferencedImageBoxSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.5.1.1.9", "Basic Grayscale Print Management Meta SOP Class", "BasicGrayscalePrintManagementMetaSOPClass", "Meta SOP Class" }, { "1.2.840.10008.5.1.1.9.1", "Referenced Grayscale Print Management Meta SOP Class (Retired)", "ReferencedGrayscalePrintManagementMetaSOPClass_Retired", "Meta SOP Class" }, { "1.2.840.10008.5.1.1.14", "Print Job SOP Class", "PrintJobSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.1.15", "Basic Annotation Box SOP Class", "BasicAnnotationBoxSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.1.16", "Printer SOP Class", "PrinterSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.1.16.376", "Printer Configuration Retrieval SOP Class", "PrinterConfigurationRetrievalSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.1.17", "Printer SOP Instance", "PrinterSOPInstance", "Well-known Printer SOP Instance" }, { "1.2.840.10008.5.1.1.17.376", "Printer Configuration Retrieval SOP Instance", "PrinterConfigurationRetrievalSOPInstance", "Well-known Printer SOP Instance" }, { "1.2.840.10008.5.1.1.18", "Basic Color Print Management Meta SOP Class", "BasicColorPrintManagementMetaSOPClass", "Meta SOP Class" }, { "1.2.840.10008.5.1.1.18.1", "Referenced Color Print Management Meta SOP Class (Retired)", "ReferencedColorPrintManagementMetaSOPClass_Retired", "Meta SOP Class" }, { "1.2.840.10008.5.1.1.22", "VOI LUT Box SOP Class", "VOILUTBoxSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.1.23", "Presentation LUT SOP Class", "PresentationLUTSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.1.24", "Image Overlay Box SOP Class (Retired)", "ImageOverlayBoxSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.5.1.1.24.1", "Basic Print Image Overlay Box SOP Class (Retired)", "BasicPrintImageOverlayBoxSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.5.1.1.25", "Print Queue SOP Instance (Retired)", "PrintQueueSOPInstance_Retired", "Well-known Print Queue SOP Instance" }, { "1.2.840.10008.5.1.1.26", "Print Queue Management SOP Class (Retired)", "PrintQueueManagementSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.5.1.1.27", "Stored Print Storage SOP Class (Retired)", "StoredPrintStorageSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.5.1.1.29", "Hardcopy Grayscale Image Storage SOP Class (Retired)", "HardcopyGrayscaleImageStorageSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.5.1.1.30", "Hardcopy Color Image Storage SOP Class (Retired)", "HardcopyColorImageStorageSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.5.1.1.31", "Pull Print Request SOP Class (Retired)", "PullPrintRequestSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.5.1.1.32", "Pull Stored Print Management Meta SOP Class (Retired)", "PullStoredPrintManagementMetaSOPClass_Retired", "Meta SOP Class" }, { "1.2.840.10008.5.1.1.33", "Media Creation Management SOP Class UID", "MediaCreationManagementSOPClassUID", "SOP Class" }, { "1.2.840.10008.5.1.1.40", "Display System SOP Class", "DisplaySystemSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.1.40.1", "Display System SOP Instance", "DisplaySystemSOPInstance", "Well-known SOP Instance" }, { "1.2.840.10008.5.1.4.1.1.1", "Computed Radiography Image Storage", "ComputedRadiographyImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.1.1", "Digital X-Ray Image Storage - For Presentation", "DigitalXRayImageStorageForPresentation", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.1.1.1", "Digital X-Ray Image Storage - For Processing", "DigitalXRayImageStorageForProcessing", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.1.2", "Digital Mammography X-Ray Image Storage - For Presentation", "DigitalMammographyXRayImageStorageForPresentation", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.1.2.1", "Digital Mammography X-Ray Image Storage - For Processing", "DigitalMammographyXRayImageStorageForProcessing", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.1.3", "Digital Intra-Oral X-Ray Image Storage - For Presentation", "DigitalIntraOralXRayImageStorageForPresentation", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.1.3.1", "Digital Intra-Oral X-Ray Image Storage - For Processing", "DigitalIntraOralXRayImageStorageForProcessing", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.2", "CT Image Storage", "CTImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.2.1", "Enhanced CT Image Storage", "EnhancedCTImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.2.2", "Legacy Converted Enhanced CT Image Storage", "LegacyConvertedEnhancedCTImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.3", "Ultrasound Multi-frame Image Storage (Retired)", "UltrasoundMultiframeImageStorage_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.3.1", "Ultrasound Multi-frame Image Storage", "UltrasoundMultiframeImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.4", "MR Image Storage", "MRImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.4.1", "Enhanced MR Image Storage", "EnhancedMRImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.4.2", "MR Spectroscopy Storage", "MRSpectroscopyStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.4.3", "Enhanced MR Color Image Storage", "EnhancedMRColorImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.4.4", "Legacy Converted Enhanced MR Image Storage", "LegacyConvertedEnhancedMRImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.5", "Nuclear Medicine Image Storage (Retired)", "NuclearMedicineImageStorage_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.6", "Ultrasound Image Storage (Retired)", "UltrasoundImageStorage_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.6.1", "Ultrasound Image Storage", "UltrasoundImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.6.2", "Enhanced US Volume Storage", "EnhancedUSVolumeStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.7", "Secondary Capture Image Storage", "SecondaryCaptureImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.7.1", "Multi-frame Single Bit Secondary Capture Image Storage", "MultiframeSingleBitSecondaryCaptureImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.7.2", "Multi-frame Grayscale Byte Secondary Capture Image Storage", "MultiframeGrayscaleByteSecondaryCaptureImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.7.3", "Multi-frame Grayscale Word Secondary Capture Image Storage", "MultiframeGrayscaleWordSecondaryCaptureImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.7.4", "Multi-frame True Color Secondary Capture Image Storage", "MultiframeTrueColorSecondaryCaptureImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.8", "Standalone Overlay Storage (Retired)", "StandaloneOverlayStorage_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.9", "Standalone Curve Storage (Retired)", "StandaloneCurveStorage_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.9.1", "Waveform Storage - Trial (Retired)", "WaveformStorageTrial_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.9.1.1", "12-lead ECG Waveform Storage", "TwelveleadECGWaveformStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.9.1.2", "General ECG Waveform Storage", "GeneralECGWaveformStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.9.1.3", "Ambulatory ECG Waveform Storage", "AmbulatoryECGWaveformStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.9.2.1", "Hemodynamic Waveform Storage", "HemodynamicWaveformStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.9.3.1", "Cardiac Electrophysiology Waveform Storage", "CardiacElectrophysiologyWaveformStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.9.4.1", "Basic Voice Audio Waveform Storage", "BasicVoiceAudioWaveformStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.9.4.2", "General Audio Waveform Storage", "GeneralAudioWaveformStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.9.5.1", "Arterial Pulse Waveform Storage", "ArterialPulseWaveformStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.9.6.1", "Respiratory Waveform Storage", "RespiratoryWaveformStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.10", "Standalone Modality LUT Storage (Retired)", "StandaloneModalityLUTStorage_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.11", "Standalone VOI LUT Storage (Retired)", "StandaloneVOILUTStorage_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.11.1", "Grayscale Softcopy Presentation State Storage SOP Class", "GrayscaleSoftcopyPresentationStateStorageSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.11.2", "Color Softcopy Presentation State Storage SOP Class", "ColorSoftcopyPresentationStateStorageSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.11.3", "Pseudo-Color Softcopy Presentation State Storage SOP Class", "PseudoColorSoftcopyPresentationStateStorageSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.11.4", "Blending Softcopy Presentation State Storage SOP Class", "BlendingSoftcopyPresentationStateStorageSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.11.5", "XA/XRF Grayscale Softcopy Presentation State Storage", "XAXRFGrayscaleSoftcopyPresentationStateStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.12.1", "X-Ray Angiographic Image Storage", "XRayAngiographicImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.12.1.1", "Enhanced XA Image Storage", "EnhancedXAImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.12.2", "X-Ray Radiofluoroscopic Image Storage", "XRayRadiofluoroscopicImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.12.2.1", "Enhanced XRF Image Storage", "EnhancedXRFImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.12.3", "X-Ray Angiographic Bi-Plane Image Storage (Retired)", "XRayAngiographicBiPlaneImageStorage_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.13.1.1", "X-Ray 3D Angiographic Image Storage", "XRay3DAngiographicImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.13.1.2", "X-Ray 3D Craniofacial Image Storage", "XRay3DCraniofacialImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.13.1.3", "Breast Tomosynthesis Image Storage", "BreastTomosynthesisImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.13.1.4", "Breast Projection X-Ray Image Storage - For Presentation", "BreastProjectionXRayImageStorageForPresentation", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.13.1.5", "Breast Projection X-Ray Image Storage - For Processing", "BreastProjectionXRayImageStorageForProcessing", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.14.1", "Intravascular Optical Coherence Tomography Image Storage - For Presentation", "IntravascularOpticalCoherenceTomographyImageStorageForPresentation", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.14.2", "Intravascular Optical Coherence Tomography Image Storage - For Processing", "IntravascularOpticalCoherenceTomographyImageStorageForProcessing", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.20", "Nuclear Medicine Image Storage", "NuclearMedicineImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.30", "Parametric Map Storage", "ParametricMapStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.66", "Raw Data Storage", "RawDataStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.66.1", "Spatial Registration Storage", "SpatialRegistrationStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.66.2", "Spatial Fiducials Storage", "SpatialFiducialsStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.66.3", "Deformable Spatial Registration Storage", "DeformableSpatialRegistrationStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.66.4", "Segmentation Storage", "SegmentationStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.66.5", "Surface Segmentation Storage", "SurfaceSegmentationStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.67", "Real World Value Mapping Storage", "RealWorldValueMappingStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.68.1", "Surface Scan Mesh Storage", "SurfaceScanMeshStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.68.2", "Surface Scan Point Cloud Storage", "SurfaceScanPointCloudStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1", "VL Image Storage - Trial (Retired)", "VLImageStorageTrial_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.2", "VL Multi-frame Image Storage - Trial (Retired)", "VLMultiframeImageStorageTrial_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1.1", "VL Endoscopic Image Storage", "VLEndoscopicImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1.1.1", "Video Endoscopic Image Storage", "VideoEndoscopicImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1.2", "VL Microscopic Image Storage", "VLMicroscopicImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1.2.1", "Video Microscopic Image Storage", "VideoMicroscopicImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1.3", "VL Slide-Coordinates Microscopic Image Storage", "VLSlideCoordinatesMicroscopicImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1.4", "VL Photographic Image Storage", "VLPhotographicImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1.4.1", "Video Photographic Image Storage", "VideoPhotographicImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1.5.1", "Ophthalmic Photography 8 Bit Image Storage", "OphthalmicPhotography8BitImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1.5.2", "Ophthalmic Photography 16 Bit Image Storage", "OphthalmicPhotography16BitImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1.5.3", "Stereometric Relationship Storage", "StereometricRelationshipStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1.5.4", "Ophthalmic Tomography Image Storage", "OphthalmicTomographyImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1.5.5", "Wide Field Ophthalmic Photography Stereographic Projection Image Storage", "WideFieldOphthalmicPhotographyStereographicProjectionImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1.5.6", "Wide Field Ophthalmic Photography 3D Coordinates Image Storage", "WideFieldOphthalmicPhotography3DCoordinatesImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.77.1.6", "VL Whole Slide Microscopy Image Storage", "VLWholeSlideMicroscopyImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.78.1", "Lensometry Measurements Storage", "LensometryMeasurementsStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.78.2", "Autorefraction Measurements Storage", "AutorefractionMeasurementsStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.78.3", "Keratometry Measurements Storage", "KeratometryMeasurementsStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.78.4", "Subjective Refraction Measurements Storage", "SubjectiveRefractionMeasurementsStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.78.5", "Visual Acuity Measurements Storage", "VisualAcuityMeasurementsStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.78.6", "Spectacle Prescription Report Storage", "SpectaclePrescriptionReportStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.78.7", "Ophthalmic Axial Measurements Storage", "OphthalmicAxialMeasurementsStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.78.8", "Intraocular Lens Calculations Storage", "IntraocularLensCalculationsStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.79.1", "Macular Grid Thickness and Volume Report Storage", "MacularGridThicknessandVolumeReportStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.80.1", "Ophthalmic Visual Field Static Perimetry Measurements Storage", "OphthalmicVisualFieldStaticPerimetryMeasurementsStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.81.1", "Ophthalmic Thickness Map Storage", "OphthalmicThicknessMapStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.82.1", "Corneal Topography Map Storage", "CornealTopographyMapStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.1", "Text SR Storage - Trial (Retired)", "TextSRStorageTrial_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.2", "Audio SR Storage - Trial (Retired)", "AudioSRStorageTrial_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.3", "Detail SR Storage - Trial (Retired)", "DetailSRStorageTrial_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.4", "Comprehensive SR Storage - Trial (Retired)", "ComprehensiveSRStorageTrial_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.11", "Basic Text SR Storage", "BasicTextSRStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.22", "Enhanced SR Storage", "EnhancedSRStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.33", "Comprehensive SR Storage", "ComprehensiveSRStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.34", "Comprehensive 3D SR Storage", "Comprehensive3DSRStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.35", "Extensible SR Storage", "ExtensibleSRStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.40", "Procedure Log Storage", "ProcedureLogStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.50", "Mammography CAD SR Storage", "MammographyCADSRStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.59", "Key Object Selection Document Storage", "KeyObjectSelectionDocumentStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.65", "Chest CAD SR Storage", "ChestCADSRStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.67", "X-Ray Radiation Dose SR Storage", "XRayRadiationDoseSRStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.68", "Radiopharmaceutical Radiation Dose SR Storage", "RadiopharmaceuticalRadiationDoseSRStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.69", "Colon CAD SR Storage", "ColonCADSRStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.88.70", "Implantation Plan SR Storage", "ImplantationPlanSRStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.104.1", "Encapsulated PDF Storage", "EncapsulatedPDFStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.104.2", "Encapsulated CDA Storage", "EncapsulatedCDAStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.128", "Positron Emission Tomography Image Storage", "PositronEmissionTomographyImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.128.1", "Legacy Converted Enhanced PET Image Storage", "LegacyConvertedEnhancedPETImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.129", "Standalone PET Curve Storage (Retired)", "StandalonePETCurveStorage_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.130", "Enhanced PET Image Storage", "EnhancedPETImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.131", "Basic Structured Display Storage", "BasicStructuredDisplayStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.481.1", "RT Image Storage", "RTImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.481.2", "RT Dose Storage", "RTDoseStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.481.3", "RT Structure Set Storage", "RTStructureSetStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.481.4", "RT Beams Treatment Record Storage", "RTBeamsTreatmentRecordStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.481.5", "RT Plan Storage", "RTPlanStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.481.6", "RT Brachy Treatment Record Storage", "RTBrachyTreatmentRecordStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.481.7", "RT Treatment Summary Record Storage", "RTTreatmentSummaryRecordStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.481.8", "RT Ion Plan Storage", "RTIonPlanStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.481.9", "RT Ion Beams Treatment Record Storage", "RTIonBeamsTreatmentRecordStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.501.1", "DICOS CT Image Storage", "DICOSCTImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.501.2.1", "DICOS Digital X-Ray Image Storage - For Presentation", "DICOSDigitalXRayImageStorageForPresentation", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.501.2.2", "DICOS Digital X-Ray Image Storage - For Processing", "DICOSDigitalXRayImageStorageForProcessing", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.501.3", "DICOS Threat Detection Report Storage", "DICOSThreatDetectionReportStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.501.4", "DICOS 2D AIT Storage", "DICOS2DAITStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.501.5", "DICOS 3D AIT Storage", "DICOS3DAITStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.501.6", "DICOS Quadrupole Resonance (QR) Storage", "DICOSQuadrupoleResonanceQRStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.601.1", "Eddy Current Image Storage", "EddyCurrentImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.1.601.2", "Eddy Current Multi-frame Image Storage", "EddyCurrentMultiframeImageStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.1.2.1.1", "Patient Root Query/Retrieve Information Model - FIND", "PatientRootQueryRetrieveInformationModelFIND", "SOP Class" }, { "1.2.840.10008.5.1.4.1.2.1.2", "Patient Root Query/Retrieve Information Model - MOVE", "PatientRootQueryRetrieveInformationModelMOVE", "SOP Class" }, { "1.2.840.10008.5.1.4.1.2.1.3", "Patient Root Query/Retrieve Information Model - GET", "PatientRootQueryRetrieveInformationModelGET", "SOP Class" }, { "1.2.840.10008.5.1.4.1.2.2.1", "Study Root Query/Retrieve Information Model - FIND", "StudyRootQueryRetrieveInformationModelFIND", "SOP Class" }, { "1.2.840.10008.5.1.4.1.2.2.2", "Study Root Query/Retrieve Information Model - MOVE", "StudyRootQueryRetrieveInformationModelMOVE", "SOP Class" }, { "1.2.840.10008.5.1.4.1.2.2.3", "Study Root Query/Retrieve Information Model - GET", "StudyRootQueryRetrieveInformationModelGET", "SOP Class" }, { "1.2.840.10008.5.1.4.1.2.3.1", "Patient/Study Only Query/Retrieve Information Model - FIND (Retired)", "PatientStudyOnlyQueryRetrieveInformationModelFIND_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.2.3.2", "Patient/Study Only Query/Retrieve Information Model - MOVE (Retired)", "PatientStudyOnlyQueryRetrieveInformationModelMOVE_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.2.3.3", "Patient/Study Only Query/Retrieve Information Model - GET (Retired)", "PatientStudyOnlyQueryRetrieveInformationModelGET_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.1.2.4.2", "Composite Instance Root Retrieve - MOVE", "CompositeInstanceRootRetrieveMOVE", "SOP Class" }, { "1.2.840.10008.5.1.4.1.2.4.3", "Composite Instance Root Retrieve - GET", "CompositeInstanceRootRetrieveGET", "SOP Class" }, { "1.2.840.10008.5.1.4.1.2.5.3", "Composite Instance Retrieve Without Bulk Data - GET", "CompositeInstanceRetrieveWithoutBulkDataGET", "SOP Class" }, { "1.2.840.10008.5.1.4.31", "Modality Worklist Information Model - FIND", "ModalityWorklistInformationModelFIND", "SOP Class" }, { "1.2.840.10008.5.1.4.32", "General Purpose Worklist Management Meta SOP Class (Retired)", "GeneralPurposeWorklistManagementMetaSOPClass_Retired", "Meta SOP Class" }, { "1.2.840.10008.5.1.4.32.1", "General Purpose Worklist Information Model - FIND (Retired)", "GeneralPurposeWorklistInformationModelFIND_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.32.2", "General Purpose Scheduled Procedure Step SOP Class (Retired)", "GeneralPurposeScheduledProcedureStepSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.32.3", "General Purpose Performed Procedure Step SOP Class (Retired)", "GeneralPurposePerformedProcedureStepSOPClass_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.33", "Instance Availability Notification SOP Class", "InstanceAvailabilityNotificationSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.4.34.1", "RT Beams Delivery Instruction Storage - Trial (Retired)", "RTBeamsDeliveryInstructionStorageTrial_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.34.2", "RT Conventional Machine Verification - Trial (Retired)", "RTConventionalMachineVerificationTrial_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.34.3", "RT Ion Machine Verification - Trial (Retired)", "RTIonMachineVerificationTrial_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.34.4", "Unified Worklist and Procedure Step Service Class - Trial (Retired)", "UnifiedWorklistandProcedureStepServiceClassTrial_Retired", "Service Class" }, { "1.2.840.10008.5.1.4.34.4.1", "Unified Procedure Step - Push SOP Class - Trial (Retired)", "UnifiedProcedureStepPushSOPClassTrial_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.34.4.2", "Unified Procedure Step - Watch SOP Class - Trial (Retired)", "UnifiedProcedureStepWatchSOPClassTrial_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.34.4.3", "Unified Procedure Step - Pull SOP Class - Trial (Retired)", "UnifiedProcedureStepPullSOPClassTrial_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.34.4.4", "Unified Procedure Step - Event SOP Class - Trial (Retired)", "UnifiedProcedureStepEventSOPClassTrial_Retired", "SOP Class" }, { "1.2.840.10008.5.1.4.34.5", "UPS Global Subscription SOP Instance", "UPSGlobalSubscriptionSOPInstance", "Well-known SOP Instance" }, { "1.2.840.10008.5.1.4.34.5.1", "UPS Filtered Global Subscription SOP Instance", "UPSFilteredGlobalSubscriptionSOPInstance", "Well-known SOP Instance" }, { "1.2.840.10008.5.1.4.34.6", "Unified Worklist and Procedure Step Service Class", "UnifiedWorklistandProcedureStepServiceClass", "Service Class" }, { "1.2.840.10008.5.1.4.34.6.1", "Unified Procedure Step - Push SOP Class", "UnifiedProcedureStepPushSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.4.34.6.2", "Unified Procedure Step - Watch SOP Class", "UnifiedProcedureStepWatchSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.4.34.6.3", "Unified Procedure Step - Pull SOP Class", "UnifiedProcedureStepPullSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.4.34.6.4", "Unified Procedure Step - Event SOP Class", "UnifiedProcedureStepEventSOPClass", "SOP Class" }, { "1.2.840.10008.5.1.4.34.7", "RT Beams Delivery Instruction Storage", "RTBeamsDeliveryInstructionStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.34.8", "RT Conventional Machine Verification", "RTConventionalMachineVerification", "SOP Class" }, { "1.2.840.10008.5.1.4.34.9", "RT Ion Machine Verification", "RTIonMachineVerification", "SOP Class" }, { "1.2.840.10008.5.1.4.37.1", "General Relevant Patient Information Query", "GeneralRelevantPatientInformationQuery", "SOP Class" }, { "1.2.840.10008.5.1.4.37.2", "Breast Imaging Relevant Patient Information Query", "BreastImagingRelevantPatientInformationQuery", "SOP Class" }, { "1.2.840.10008.5.1.4.37.3", "Cardiac Relevant Patient Information Query", "CardiacRelevantPatientInformationQuery", "SOP Class" }, { "1.2.840.10008.5.1.4.38.1", "Hanging Protocol Storage", "HangingProtocolStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.38.2", "Hanging Protocol Information Model - FIND", "HangingProtocolInformationModelFIND", "SOP Class" }, { "1.2.840.10008.5.1.4.38.3", "Hanging Protocol Information Model - MOVE", "HangingProtocolInformationModelMOVE", "SOP Class" }, { "1.2.840.10008.5.1.4.38.4", "Hanging Protocol Information Model - GET", "HangingProtocolInformationModelGET", "SOP Class" }, { "1.2.840.10008.5.1.4.39.1", "Color Palette Storage", "ColorPaletteStorage", "Transfer" }, { "1.2.840.10008.5.1.4.39.2", "Color Palette Information Model - FIND", "ColorPaletteInformationModelFIND", "Query/Retrieve" }, { "1.2.840.10008.5.1.4.39.3", "Color Palette Information Model - MOVE", "ColorPaletteInformationModelMOVE", "Query/Retrieve" }, { "1.2.840.10008.5.1.4.39.4", "Color Palette Information Model - GET", "ColorPaletteInformationModelGET", "Query/Retrieve" }, { "1.2.840.10008.5.1.4.41", "Product Characteristics Query SOP Class", "ProductCharacteristicsQuerySOPClass", "SOP Class" }, { "1.2.840.10008.5.1.4.42", "Substance Approval Query SOP Class", "SubstanceApprovalQuerySOPClass", "SOP Class" }, { "1.2.840.10008.5.1.4.43.1", "Generic Implant Template Storage", "GenericImplantTemplateStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.43.2", "Generic Implant Template Information Model - FIND", "GenericImplantTemplateInformationModelFIND", "SOP Class" }, { "1.2.840.10008.5.1.4.43.3", "Generic Implant Template Information Model - MOVE", "GenericImplantTemplateInformationModelMOVE", "SOP Class" }, { "1.2.840.10008.5.1.4.43.4", "Generic Implant Template Information Model - GET", "GenericImplantTemplateInformationModelGET", "SOP Class" }, { "1.2.840.10008.5.1.4.44.1", "Implant Assembly Template Storage", "ImplantAssemblyTemplateStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.44.2", "Implant Assembly Template Information Model - FIND", "ImplantAssemblyTemplateInformationModelFIND", "SOP Class" }, { "1.2.840.10008.5.1.4.44.3", "Implant Assembly Template Information Model - MOVE", "ImplantAssemblyTemplateInformationModelMOVE", "SOP Class" }, { "1.2.840.10008.5.1.4.44.4", "Implant Assembly Template Information Model - GET", "ImplantAssemblyTemplateInformationModelGET", "SOP Class" }, { "1.2.840.10008.5.1.4.45.1", "Implant Template Group Storage", "ImplantTemplateGroupStorage", "SOP Class" }, { "1.2.840.10008.5.1.4.45.2", "Implant Template Group Information Model - FIND", "ImplantTemplateGroupInformationModelFIND", "SOP Class" }, { "1.2.840.10008.5.1.4.45.3", "Implant Template Group Information Model - MOVE", "ImplantTemplateGroupInformationModelMOVE", "SOP Class" }, { "1.2.840.10008.5.1.4.45.4", "Implant Template Group Information Model - GET", "ImplantTemplateGroupInformationModelGET", "SOP Class" }, { "1.2.840.10008.7.1.1", "Native DICOM Model", "NativeDICOMModel", "Application Hosting Model" }, { "1.2.840.10008.7.1.2", "Abstract Multi-Dimensional Image Model", "AbstractMultiDimensionalImageModel", "Application Hosting Model" }, { "1.2.840.10008.8.1.1", "DICOM Content Mapping Resource", "DICOMContentMappingResource", "Mapping Resource" }, { "1.2.840.10008.15.0.3.1", "dicomDeviceName", "dicomDeviceName", "LDAP OID" }, { "1.2.840.10008.15.0.3.2", "dicomDescription", "dicomDescription", "LDAP OID" }, { "1.2.840.10008.15.0.3.3", "dicomManufacturer", "dicomManufacturer", "LDAP OID" }, { "1.2.840.10008.15.0.3.4", "dicomManufacturerModelName", "dicomManufacturerModelName", "LDAP OID" }, { "1.2.840.10008.15.0.3.5", "dicomSoftwareVersion", "dicomSoftwareVersion", "LDAP OID" }, { "1.2.840.10008.15.0.3.6", "dicomVendorData", "dicomVendorData", "LDAP OID" }, { "1.2.840.10008.15.0.3.7", "dicomAETitle", "dicomAETitle", "LDAP OID" }, { "1.2.840.10008.15.0.3.8", "dicomNetworkConnectionReference", "dicomNetworkConnectionReference", "LDAP OID" }, { "1.2.840.10008.15.0.3.9", "dicomApplicationCluster", "dicomApplicationCluster", "LDAP OID" }, { "1.2.840.10008.15.0.3.10", "dicomAssociationInitiator", "dicomAssociationInitiator", "LDAP OID" }, { "1.2.840.10008.15.0.3.11", "dicomAssociationAcceptor", "dicomAssociationAcceptor", "LDAP OID" }, { "1.2.840.10008.15.0.3.12", "dicomHostname", "dicomHostname", "LDAP OID" }, { "1.2.840.10008.15.0.3.13", "dicomPort", "dicomPort", "LDAP OID" }, { "1.2.840.10008.15.0.3.14", "dicomSOPClass", "dicomSOPClass", "LDAP OID" }, { "1.2.840.10008.15.0.3.15", "dicomTransferRole", "dicomTransferRole", "LDAP OID" }, { "1.2.840.10008.15.0.3.16", "dicomTransferSyntax", "dicomTransferSyntax", "LDAP OID" }, { "1.2.840.10008.15.0.3.17", "dicomPrimaryDeviceType", "dicomPrimaryDeviceType", "LDAP OID" }, { "1.2.840.10008.15.0.3.18", "dicomRelatedDeviceReference", "dicomRelatedDeviceReference", "LDAP OID" }, { "1.2.840.10008.15.0.3.19", "dicomPreferredCalledAETitle", "dicomPreferredCalledAETitle", "LDAP OID" }, { "1.2.840.10008.15.0.3.20", "dicomTLSCyphersuite", "dicomTLSCyphersuite", "LDAP OID" }, { "1.2.840.10008.15.0.3.21", "dicomAuthorizedNodeCertificateReference", "dicomAuthorizedNodeCertificateReference", "LDAP OID" }, { "1.2.840.10008.15.0.3.22", "dicomThisNodeCertificateReference", "dicomThisNodeCertificateReference", "LDAP OID" }, { "1.2.840.10008.15.0.3.23", "dicomInstalled", "dicomInstalled", "LDAP OID" }, { "1.2.840.10008.15.0.3.24", "dicomStationName", "dicomStationName", "LDAP OID" }, { "1.2.840.10008.15.0.3.25", "dicomDeviceSerialNumber", "dicomDeviceSerialNumber", "LDAP OID" }, { "1.2.840.10008.15.0.3.26", "dicomInstitutionName", "dicomInstitutionName", "LDAP OID" }, { "1.2.840.10008.15.0.3.27", "dicomInstitutionAddress", "dicomInstitutionAddress", "LDAP OID" }, { "1.2.840.10008.15.0.3.28", "dicomInstitutionDepartmentName", "dicomInstitutionDepartmentName", "LDAP OID" }, { "1.2.840.10008.15.0.3.29", "dicomIssuerOfPatientID", "dicomIssuerOfPatientID", "LDAP OID" }, { "1.2.840.10008.15.0.3.30", "dicomPreferredCallingAETitle", "dicomPreferredCallingAETitle", "LDAP OID" }, { "1.2.840.10008.15.0.3.31", "dicomSupportedCharacterSet", "dicomSupportedCharacterSet", "LDAP OID" }, { "1.2.840.10008.15.0.4.1", "dicomConfigurationRoot", "dicomConfigurationRoot", "LDAP OID" }, { "1.2.840.10008.15.0.4.2", "dicomDevicesRoot", "dicomDevicesRoot", "LDAP OID" }, { "1.2.840.10008.15.0.4.3", "dicomUniqueAETitlesRegistryRoot", "dicomUniqueAETitlesRegistryRoot", "LDAP OID" }, { "1.2.840.10008.15.0.4.4", "dicomDevice", "dicomDevice", "LDAP OID" }, { "1.2.840.10008.15.0.4.5", "dicomNetworkAE", "dicomNetworkAE", "LDAP OID" }, { "1.2.840.10008.15.0.4.6", "dicomNetworkConnection", "dicomNetworkConnection", "LDAP OID" }, { "1.2.840.10008.15.0.4.7", "dicomUniqueAETitle", "dicomUniqueAETitle", "LDAP OID" }, { "1.2.840.10008.15.0.4.8", "dicomTransferCapability", "dicomTransferCapability", "LDAP OID" }, { "1.2.840.10008.15.1.1", "Universal Coordinated Time", "UniversalCoordinatedTime", "Synchronization Frame of Reference" }, }; UIDsDictionary uids_dictionary; unsigned long const count = sizeof(raw_entries)/sizeof(RawUIDsDictionaryEntry); for(unsigned long i=0; i(raw_entry.uid, entry)); } return uids_dictionary; } } } odil::ElementsDictionary odil::registry::public_dictionary=odil::registry::create_public_dictionary(); odil::UIDsDictionary odil::registry::uids_dictionary=odil::registry::create_uids_dictionary();odil-0.4.1/src/odil/registry.h000066400000000000000000006724201266460524100162230ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _afc7b2d7_0869_4fea_9a9b_7fe6228baca9 #define _afc7b2d7_0869_4fea_9a9b_7fe6228baca9 #include "odil/ElementsDictionary.h" #include "odil/Tag.h" #include "odil/UIDsDictionary.h" namespace odil { namespace registry { Tag const CommandGroupLength(0x0000, 0x0000); Tag const AffectedSOPClassUID(0x0000, 0x0002); Tag const RequestedSOPClassUID(0x0000, 0x0003); Tag const CommandField(0x0000, 0x0100); Tag const MessageID(0x0000, 0x0110); Tag const MessageIDBeingRespondedTo(0x0000, 0x0120); Tag const MoveDestination(0x0000, 0x0600); Tag const Priority(0x0000, 0x0700); Tag const CommandDataSetType(0x0000, 0x0800); Tag const Status(0x0000, 0x0900); Tag const OffendingElement(0x0000, 0x0901); Tag const ErrorComment(0x0000, 0x0902); Tag const ErrorID(0x0000, 0x0903); Tag const AffectedSOPInstanceUID(0x0000, 0x1000); Tag const RequestedSOPInstanceUID(0x0000, 0x1001); Tag const EventTypeID(0x0000, 0x1002); Tag const AttributeIdentifierList(0x0000, 0x1005); Tag const ActionTypeID(0x0000, 0x1008); Tag const NumberOfRemainingSuboperations(0x0000, 0x1020); Tag const NumberOfCompletedSuboperations(0x0000, 0x1021); Tag const NumberOfFailedSuboperations(0x0000, 0x1022); Tag const NumberOfWarningSuboperations(0x0000, 0x1023); Tag const MoveOriginatorApplicationEntityTitle(0x0000, 0x1030); Tag const MoveOriginatorMessageID(0x0000, 0x1031); Tag const FileMetaInformationGroupLength(0x0002, 0x0000); Tag const FileMetaInformationVersion(0x0002, 0x0001); Tag const MediaStorageSOPClassUID(0x0002, 0x0002); Tag const MediaStorageSOPInstanceUID(0x0002, 0x0003); Tag const TransferSyntaxUID(0x0002, 0x0010); Tag const ImplementationClassUID(0x0002, 0x0012); Tag const ImplementationVersionName(0x0002, 0x0013); Tag const SourceApplicationEntityTitle(0x0002, 0x0016); Tag const SendingApplicationEntityTitle(0x0002, 0x0017); Tag const ReceivingApplicationEntityTitle(0x0002, 0x0018); Tag const PrivateInformationCreatorUID(0x0002, 0x0100); Tag const PrivateInformation(0x0002, 0x0102); Tag const FileSetID(0x0004, 0x1130); Tag const FileSetDescriptorFileID(0x0004, 0x1141); Tag const SpecificCharacterSetOfFileSetDescriptorFile(0x0004, 0x1142); Tag const OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity(0x0004, 0x1200); Tag const OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity(0x0004, 0x1202); Tag const FileSetConsistencyFlag(0x0004, 0x1212); Tag const DirectoryRecordSequence(0x0004, 0x1220); Tag const OffsetOfTheNextDirectoryRecord(0x0004, 0x1400); Tag const RecordInUseFlag(0x0004, 0x1410); Tag const OffsetOfReferencedLowerLevelDirectoryEntity(0x0004, 0x1420); Tag const DirectoryRecordType(0x0004, 0x1430); Tag const PrivateRecordUID(0x0004, 0x1432); Tag const ReferencedFileID(0x0004, 0x1500); Tag const MRDRDirectoryRecordOffset(0x0004, 0x1504); Tag const ReferencedSOPClassUIDInFile(0x0004, 0x1510); Tag const ReferencedSOPInstanceUIDInFile(0x0004, 0x1511); Tag const ReferencedTransferSyntaxUIDInFile(0x0004, 0x1512); Tag const ReferencedRelatedGeneralSOPClassUIDInFile(0x0004, 0x151a); Tag const NumberOfReferences(0x0004, 0x1600); Tag const LengthToEnd(0x0008, 0x0001); Tag const SpecificCharacterSet(0x0008, 0x0005); Tag const LanguageCodeSequence(0x0008, 0x0006); Tag const ImageType(0x0008, 0x0008); Tag const RecognitionCode(0x0008, 0x0010); Tag const InstanceCreationDate(0x0008, 0x0012); Tag const InstanceCreationTime(0x0008, 0x0013); Tag const InstanceCreatorUID(0x0008, 0x0014); Tag const InstanceCoercionDateTime(0x0008, 0x0015); Tag const SOPClassUID(0x0008, 0x0016); Tag const SOPInstanceUID(0x0008, 0x0018); Tag const RelatedGeneralSOPClassUID(0x0008, 0x001a); Tag const OriginalSpecializedSOPClassUID(0x0008, 0x001b); Tag const StudyDate(0x0008, 0x0020); Tag const SeriesDate(0x0008, 0x0021); Tag const AcquisitionDate(0x0008, 0x0022); Tag const ContentDate(0x0008, 0x0023); Tag const OverlayDate(0x0008, 0x0024); Tag const CurveDate(0x0008, 0x0025); Tag const AcquisitionDateTime(0x0008, 0x002a); Tag const StudyTime(0x0008, 0x0030); Tag const SeriesTime(0x0008, 0x0031); Tag const AcquisitionTime(0x0008, 0x0032); Tag const ContentTime(0x0008, 0x0033); Tag const OverlayTime(0x0008, 0x0034); Tag const CurveTime(0x0008, 0x0035); Tag const DataSetType(0x0008, 0x0040); Tag const DataSetSubtype(0x0008, 0x0041); Tag const NuclearMedicineSeriesType(0x0008, 0x0042); Tag const AccessionNumber(0x0008, 0x0050); Tag const IssuerOfAccessionNumberSequence(0x0008, 0x0051); Tag const QueryRetrieveLevel(0x0008, 0x0052); Tag const QueryRetrieveView(0x0008, 0x0053); Tag const RetrieveAETitle(0x0008, 0x0054); Tag const InstanceAvailability(0x0008, 0x0056); Tag const FailedSOPInstanceUIDList(0x0008, 0x0058); Tag const Modality(0x0008, 0x0060); Tag const ModalitiesInStudy(0x0008, 0x0061); Tag const SOPClassesInStudy(0x0008, 0x0062); Tag const ConversionType(0x0008, 0x0064); Tag const PresentationIntentType(0x0008, 0x0068); Tag const Manufacturer(0x0008, 0x0070); Tag const InstitutionName(0x0008, 0x0080); Tag const InstitutionAddress(0x0008, 0x0081); Tag const InstitutionCodeSequence(0x0008, 0x0082); Tag const ReferringPhysicianName(0x0008, 0x0090); Tag const ReferringPhysicianAddress(0x0008, 0x0092); Tag const ReferringPhysicianTelephoneNumbers(0x0008, 0x0094); Tag const ReferringPhysicianIdentificationSequence(0x0008, 0x0096); Tag const ConsultingPhysicianName(0x0008, 0x009c); Tag const ConsultingPhysicianIdentificationSequence(0x0008, 0x009d); Tag const CodeValue(0x0008, 0x0100); Tag const ExtendedCodeValue(0x0008, 0x0101); Tag const CodingSchemeDesignator(0x0008, 0x0102); Tag const CodingSchemeVersion(0x0008, 0x0103); Tag const CodeMeaning(0x0008, 0x0104); Tag const MappingResource(0x0008, 0x0105); Tag const ContextGroupVersion(0x0008, 0x0106); Tag const ContextGroupLocalVersion(0x0008, 0x0107); Tag const ExtendedCodeMeaning(0x0008, 0x0108); Tag const ContextGroupExtensionFlag(0x0008, 0x010b); Tag const CodingSchemeUID(0x0008, 0x010c); Tag const ContextGroupExtensionCreatorUID(0x0008, 0x010d); Tag const ContextIdentifier(0x0008, 0x010f); Tag const CodingSchemeIdentificationSequence(0x0008, 0x0110); Tag const CodingSchemeRegistry(0x0008, 0x0112); Tag const CodingSchemeExternalID(0x0008, 0x0114); Tag const CodingSchemeName(0x0008, 0x0115); Tag const CodingSchemeResponsibleOrganization(0x0008, 0x0116); Tag const ContextUID(0x0008, 0x0117); Tag const MappingResourceUID(0x0008, 0x0118); Tag const LongCodeValue(0x0008, 0x0119); Tag const URNCodeValue(0x0008, 0x0120); Tag const EquivalentCodeSequence(0x0008, 0x0121); Tag const TimezoneOffsetFromUTC(0x0008, 0x0201); Tag const PrivateDataElementCharacteristicsSequence(0x0008, 0x0300); Tag const PrivateGroupReference(0x0008, 0x0301); Tag const PrivateCreatorReference(0x0008, 0x0302); Tag const BlockIdentifyingInformationStatus(0x0008, 0x0303); Tag const NonidentifyingPrivateElements(0x0008, 0x0304); Tag const IdentifyingPrivateElements(0x0008, 0x0306); Tag const DeidentificationActionSequence(0x0008, 0x0305); Tag const DeidentificationAction(0x0008, 0x0307); Tag const NetworkID(0x0008, 0x1000); Tag const StationName(0x0008, 0x1010); Tag const StudyDescription(0x0008, 0x1030); Tag const ProcedureCodeSequence(0x0008, 0x1032); Tag const SeriesDescription(0x0008, 0x103e); Tag const SeriesDescriptionCodeSequence(0x0008, 0x103f); Tag const InstitutionalDepartmentName(0x0008, 0x1040); Tag const PhysiciansOfRecord(0x0008, 0x1048); Tag const PhysiciansOfRecordIdentificationSequence(0x0008, 0x1049); Tag const PerformingPhysicianName(0x0008, 0x1050); Tag const PerformingPhysicianIdentificationSequence(0x0008, 0x1052); Tag const NameOfPhysiciansReadingStudy(0x0008, 0x1060); Tag const PhysiciansReadingStudyIdentificationSequence(0x0008, 0x1062); Tag const OperatorsName(0x0008, 0x1070); Tag const OperatorIdentificationSequence(0x0008, 0x1072); Tag const AdmittingDiagnosesDescription(0x0008, 0x1080); Tag const AdmittingDiagnosesCodeSequence(0x0008, 0x1084); Tag const ManufacturerModelName(0x0008, 0x1090); Tag const ReferencedResultsSequence(0x0008, 0x1100); Tag const ReferencedStudySequence(0x0008, 0x1110); Tag const ReferencedPerformedProcedureStepSequence(0x0008, 0x1111); Tag const ReferencedSeriesSequence(0x0008, 0x1115); Tag const ReferencedPatientSequence(0x0008, 0x1120); Tag const ReferencedVisitSequence(0x0008, 0x1125); Tag const ReferencedOverlaySequence(0x0008, 0x1130); Tag const ReferencedStereometricInstanceSequence(0x0008, 0x1134); Tag const ReferencedWaveformSequence(0x0008, 0x113a); Tag const ReferencedImageSequence(0x0008, 0x1140); Tag const ReferencedCurveSequence(0x0008, 0x1145); Tag const ReferencedInstanceSequence(0x0008, 0x114a); Tag const ReferencedRealWorldValueMappingInstanceSequence(0x0008, 0x114b); Tag const ReferencedSOPClassUID(0x0008, 0x1150); Tag const ReferencedSOPInstanceUID(0x0008, 0x1155); Tag const SOPClassesSupported(0x0008, 0x115a); Tag const ReferencedFrameNumber(0x0008, 0x1160); Tag const SimpleFrameList(0x0008, 0x1161); Tag const CalculatedFrameList(0x0008, 0x1162); Tag const TimeRange(0x0008, 0x1163); Tag const FrameExtractionSequence(0x0008, 0x1164); Tag const MultiFrameSourceSOPInstanceUID(0x0008, 0x1167); Tag const RetrieveURL(0x0008, 0x1190); Tag const TransactionUID(0x0008, 0x1195); Tag const WarningReason(0x0008, 0x1196); Tag const FailureReason(0x0008, 0x1197); Tag const FailedSOPSequence(0x0008, 0x1198); Tag const ReferencedSOPSequence(0x0008, 0x1199); Tag const StudiesContainingOtherReferencedInstancesSequence(0x0008, 0x1200); Tag const RelatedSeriesSequence(0x0008, 0x1250); Tag const LossyImageCompressionRetired(0x0008, 0x2110); Tag const DerivationDescription(0x0008, 0x2111); Tag const SourceImageSequence(0x0008, 0x2112); Tag const StageName(0x0008, 0x2120); Tag const StageNumber(0x0008, 0x2122); Tag const NumberOfStages(0x0008, 0x2124); Tag const ViewName(0x0008, 0x2127); Tag const ViewNumber(0x0008, 0x2128); Tag const NumberOfEventTimers(0x0008, 0x2129); Tag const NumberOfViewsInStage(0x0008, 0x212a); Tag const EventElapsedTimes(0x0008, 0x2130); Tag const EventTimerNames(0x0008, 0x2132); Tag const EventTimerSequence(0x0008, 0x2133); Tag const EventTimeOffset(0x0008, 0x2134); Tag const EventCodeSequence(0x0008, 0x2135); Tag const StartTrim(0x0008, 0x2142); Tag const StopTrim(0x0008, 0x2143); Tag const RecommendedDisplayFrameRate(0x0008, 0x2144); Tag const TransducerPosition(0x0008, 0x2200); Tag const TransducerOrientation(0x0008, 0x2204); Tag const AnatomicStructure(0x0008, 0x2208); Tag const AnatomicRegionSequence(0x0008, 0x2218); Tag const AnatomicRegionModifierSequence(0x0008, 0x2220); Tag const PrimaryAnatomicStructureSequence(0x0008, 0x2228); Tag const AnatomicStructureSpaceOrRegionSequence(0x0008, 0x2229); Tag const PrimaryAnatomicStructureModifierSequence(0x0008, 0x2230); Tag const TransducerPositionSequence(0x0008, 0x2240); Tag const TransducerPositionModifierSequence(0x0008, 0x2242); Tag const TransducerOrientationSequence(0x0008, 0x2244); Tag const TransducerOrientationModifierSequence(0x0008, 0x2246); Tag const AnatomicStructureSpaceOrRegionCodeSequenceTrial(0x0008, 0x2251); Tag const AnatomicPortalOfEntranceCodeSequenceTrial(0x0008, 0x2253); Tag const AnatomicApproachDirectionCodeSequenceTrial(0x0008, 0x2255); Tag const AnatomicPerspectiveDescriptionTrial(0x0008, 0x2256); Tag const AnatomicPerspectiveCodeSequenceTrial(0x0008, 0x2257); Tag const AnatomicLocationOfExaminingInstrumentDescriptionTrial(0x0008, 0x2258); Tag const AnatomicLocationOfExaminingInstrumentCodeSequenceTrial(0x0008, 0x2259); Tag const AnatomicStructureSpaceOrRegionModifierCodeSequenceTrial(0x0008, 0x225a); Tag const OnAxisBackgroundAnatomicStructureCodeSequenceTrial(0x0008, 0x225c); Tag const AlternateRepresentationSequence(0x0008, 0x3001); Tag const IrradiationEventUID(0x0008, 0x3010); Tag const SourceIrradiationEventSequence(0x0008, 0x3011); Tag const RadiopharmaceuticalAdministrationEventUID(0x0008, 0x3012); Tag const IdentifyingComments(0x0008, 0x4000); Tag const FrameType(0x0008, 0x9007); Tag const ReferencedImageEvidenceSequence(0x0008, 0x9092); Tag const ReferencedRawDataSequence(0x0008, 0x9121); Tag const CreatorVersionUID(0x0008, 0x9123); Tag const DerivationImageSequence(0x0008, 0x9124); Tag const SourceImageEvidenceSequence(0x0008, 0x9154); Tag const PixelPresentation(0x0008, 0x9205); Tag const VolumetricProperties(0x0008, 0x9206); Tag const VolumeBasedCalculationTechnique(0x0008, 0x9207); Tag const ComplexImageComponent(0x0008, 0x9208); Tag const AcquisitionContrast(0x0008, 0x9209); Tag const DerivationCodeSequence(0x0008, 0x9215); Tag const ReferencedPresentationStateSequence(0x0008, 0x9237); Tag const ReferencedOtherPlaneSequence(0x0008, 0x9410); Tag const FrameDisplaySequence(0x0008, 0x9458); Tag const RecommendedDisplayFrameRateInFloat(0x0008, 0x9459); Tag const SkipFrameRangeFlag(0x0008, 0x9460); Tag const PatientName(0x0010, 0x0010); Tag const PatientID(0x0010, 0x0020); Tag const IssuerOfPatientID(0x0010, 0x0021); Tag const TypeOfPatientID(0x0010, 0x0022); Tag const IssuerOfPatientIDQualifiersSequence(0x0010, 0x0024); Tag const PatientBirthDate(0x0010, 0x0030); Tag const PatientBirthTime(0x0010, 0x0032); Tag const PatientSex(0x0010, 0x0040); Tag const PatientInsurancePlanCodeSequence(0x0010, 0x0050); Tag const PatientPrimaryLanguageCodeSequence(0x0010, 0x0101); Tag const PatientPrimaryLanguageModifierCodeSequence(0x0010, 0x0102); Tag const QualityControlSubject(0x0010, 0x0200); Tag const QualityControlSubjectTypeCodeSequence(0x0010, 0x0201); Tag const OtherPatientIDs(0x0010, 0x1000); Tag const OtherPatientNames(0x0010, 0x1001); Tag const OtherPatientIDsSequence(0x0010, 0x1002); Tag const PatientBirthName(0x0010, 0x1005); Tag const PatientAge(0x0010, 0x1010); Tag const PatientSize(0x0010, 0x1020); Tag const PatientSizeCodeSequence(0x0010, 0x1021); Tag const PatientWeight(0x0010, 0x1030); Tag const PatientAddress(0x0010, 0x1040); Tag const InsurancePlanIdentification(0x0010, 0x1050); Tag const PatientMotherBirthName(0x0010, 0x1060); Tag const MilitaryRank(0x0010, 0x1080); Tag const BranchOfService(0x0010, 0x1081); Tag const MedicalRecordLocator(0x0010, 0x1090); Tag const ReferencedPatientPhotoSequence(0x0010, 0x1100); Tag const MedicalAlerts(0x0010, 0x2000); Tag const Allergies(0x0010, 0x2110); Tag const CountryOfResidence(0x0010, 0x2150); Tag const RegionOfResidence(0x0010, 0x2152); Tag const PatientTelephoneNumbers(0x0010, 0x2154); Tag const PatientTelecomInformation(0x0010, 0x2155); Tag const EthnicGroup(0x0010, 0x2160); Tag const Occupation(0x0010, 0x2180); Tag const SmokingStatus(0x0010, 0x21a0); Tag const AdditionalPatientHistory(0x0010, 0x21b0); Tag const PregnancyStatus(0x0010, 0x21c0); Tag const LastMenstrualDate(0x0010, 0x21d0); Tag const PatientReligiousPreference(0x0010, 0x21f0); Tag const PatientSpeciesDescription(0x0010, 0x2201); Tag const PatientSpeciesCodeSequence(0x0010, 0x2202); Tag const PatientSexNeutered(0x0010, 0x2203); Tag const AnatomicalOrientationType(0x0010, 0x2210); Tag const PatientBreedDescription(0x0010, 0x2292); Tag const PatientBreedCodeSequence(0x0010, 0x2293); Tag const BreedRegistrationSequence(0x0010, 0x2294); Tag const BreedRegistrationNumber(0x0010, 0x2295); Tag const BreedRegistryCodeSequence(0x0010, 0x2296); Tag const ResponsiblePerson(0x0010, 0x2297); Tag const ResponsiblePersonRole(0x0010, 0x2298); Tag const ResponsibleOrganization(0x0010, 0x2299); Tag const PatientComments(0x0010, 0x4000); Tag const ExaminedBodyThickness(0x0010, 0x9431); Tag const ClinicalTrialSponsorName(0x0012, 0x0010); Tag const ClinicalTrialProtocolID(0x0012, 0x0020); Tag const ClinicalTrialProtocolName(0x0012, 0x0021); Tag const ClinicalTrialSiteID(0x0012, 0x0030); Tag const ClinicalTrialSiteName(0x0012, 0x0031); Tag const ClinicalTrialSubjectID(0x0012, 0x0040); Tag const ClinicalTrialSubjectReadingID(0x0012, 0x0042); Tag const ClinicalTrialTimePointID(0x0012, 0x0050); Tag const ClinicalTrialTimePointDescription(0x0012, 0x0051); Tag const ClinicalTrialCoordinatingCenterName(0x0012, 0x0060); Tag const PatientIdentityRemoved(0x0012, 0x0062); Tag const DeidentificationMethod(0x0012, 0x0063); Tag const DeidentificationMethodCodeSequence(0x0012, 0x0064); Tag const ClinicalTrialSeriesID(0x0012, 0x0071); Tag const ClinicalTrialSeriesDescription(0x0012, 0x0072); Tag const ClinicalTrialProtocolEthicsCommitteeName(0x0012, 0x0081); Tag const ClinicalTrialProtocolEthicsCommitteeApprovalNumber(0x0012, 0x0082); Tag const ConsentForClinicalTrialUseSequence(0x0012, 0x0083); Tag const DistributionType(0x0012, 0x0084); Tag const ConsentForDistributionFlag(0x0012, 0x0085); Tag const CADFileFormat(0x0014, 0x0023); Tag const ComponentReferenceSystem(0x0014, 0x0024); Tag const ComponentManufacturingProcedure(0x0014, 0x0025); Tag const ComponentManufacturer(0x0014, 0x0028); Tag const MaterialThickness(0x0014, 0x0030); Tag const MaterialPipeDiameter(0x0014, 0x0032); Tag const MaterialIsolationDiameter(0x0014, 0x0034); Tag const MaterialGrade(0x0014, 0x0042); Tag const MaterialPropertiesDescription(0x0014, 0x0044); Tag const MaterialPropertiesFileFormatRetired(0x0014, 0x0045); Tag const MaterialNotes(0x0014, 0x0046); Tag const ComponentShape(0x0014, 0x0050); Tag const CurvatureType(0x0014, 0x0052); Tag const OuterDiameter(0x0014, 0x0054); Tag const InnerDiameter(0x0014, 0x0056); Tag const ActualEnvironmentalConditions(0x0014, 0x1010); Tag const ExpiryDate(0x0014, 0x1020); Tag const EnvironmentalConditions(0x0014, 0x1040); Tag const EvaluatorSequence(0x0014, 0x2002); Tag const EvaluatorNumber(0x0014, 0x2004); Tag const EvaluatorName(0x0014, 0x2006); Tag const EvaluationAttempt(0x0014, 0x2008); Tag const IndicationSequence(0x0014, 0x2012); Tag const IndicationNumber(0x0014, 0x2014); Tag const IndicationLabel(0x0014, 0x2016); Tag const IndicationDescription(0x0014, 0x2018); Tag const IndicationType(0x0014, 0x201a); Tag const IndicationDisposition(0x0014, 0x201c); Tag const IndicationROISequence(0x0014, 0x201e); Tag const IndicationPhysicalPropertySequence(0x0014, 0x2030); Tag const PropertyLabel(0x0014, 0x2032); Tag const CoordinateSystemNumberOfAxes(0x0014, 0x2202); Tag const CoordinateSystemAxesSequence(0x0014, 0x2204); Tag const CoordinateSystemAxisDescription(0x0014, 0x2206); Tag const CoordinateSystemDataSetMapping(0x0014, 0x2208); Tag const CoordinateSystemAxisNumber(0x0014, 0x220a); Tag const CoordinateSystemAxisType(0x0014, 0x220c); Tag const CoordinateSystemAxisUnits(0x0014, 0x220e); Tag const CoordinateSystemAxisValues(0x0014, 0x2210); Tag const CoordinateSystemTransformSequence(0x0014, 0x2220); Tag const TransformDescription(0x0014, 0x2222); Tag const TransformNumberOfAxes(0x0014, 0x2224); Tag const TransformOrderOfAxes(0x0014, 0x2226); Tag const TransformedAxisUnits(0x0014, 0x2228); Tag const CoordinateSystemTransformRotationAndScaleMatrix(0x0014, 0x222a); Tag const CoordinateSystemTransformTranslationMatrix(0x0014, 0x222c); Tag const InternalDetectorFrameTime(0x0014, 0x3011); Tag const NumberOfFramesIntegrated(0x0014, 0x3012); Tag const DetectorTemperatureSequence(0x0014, 0x3020); Tag const SensorName(0x0014, 0x3022); Tag const HorizontalOffsetOfSensor(0x0014, 0x3024); Tag const VerticalOffsetOfSensor(0x0014, 0x3026); Tag const SensorTemperature(0x0014, 0x3028); Tag const DarkCurrentSequence(0x0014, 0x3040); Tag const DarkCurrentCounts(0x0014, 0x3050); Tag const GainCorrectionReferenceSequence(0x0014, 0x3060); Tag const AirCounts(0x0014, 0x3070); Tag const KVUsedInGainCalibration(0x0014, 0x3071); Tag const MAUsedInGainCalibration(0x0014, 0x3072); Tag const NumberOfFramesUsedForIntegration(0x0014, 0x3073); Tag const FilterMaterialUsedInGainCalibration(0x0014, 0x3074); Tag const FilterThicknessUsedInGainCalibration(0x0014, 0x3075); Tag const DateOfGainCalibration(0x0014, 0x3076); Tag const TimeOfGainCalibration(0x0014, 0x3077); Tag const BadPixelImage(0x0014, 0x3080); Tag const CalibrationNotes(0x0014, 0x3099); Tag const PulserEquipmentSequence(0x0014, 0x4002); Tag const PulserType(0x0014, 0x4004); Tag const PulserNotes(0x0014, 0x4006); Tag const ReceiverEquipmentSequence(0x0014, 0x4008); Tag const AmplifierType(0x0014, 0x400a); Tag const ReceiverNotes(0x0014, 0x400c); Tag const PreAmplifierEquipmentSequence(0x0014, 0x400e); Tag const PreAmplifierNotes(0x0014, 0x400f); Tag const TransmitTransducerSequence(0x0014, 0x4010); Tag const ReceiveTransducerSequence(0x0014, 0x4011); Tag const NumberOfElements(0x0014, 0x4012); Tag const ElementShape(0x0014, 0x4013); Tag const ElementDimensionA(0x0014, 0x4014); Tag const ElementDimensionB(0x0014, 0x4015); Tag const ElementPitchA(0x0014, 0x4016); Tag const MeasuredBeamDimensionA(0x0014, 0x4017); Tag const MeasuredBeamDimensionB(0x0014, 0x4018); Tag const LocationOfMeasuredBeamDiameter(0x0014, 0x4019); Tag const NominalFrequency(0x0014, 0x401a); Tag const MeasuredCenterFrequency(0x0014, 0x401b); Tag const MeasuredBandwidth(0x0014, 0x401c); Tag const ElementPitchB(0x0014, 0x401d); Tag const PulserSettingsSequence(0x0014, 0x4020); Tag const PulseWidth(0x0014, 0x4022); Tag const ExcitationFrequency(0x0014, 0x4024); Tag const ModulationType(0x0014, 0x4026); Tag const Damping(0x0014, 0x4028); Tag const ReceiverSettingsSequence(0x0014, 0x4030); Tag const AcquiredSoundpathLength(0x0014, 0x4031); Tag const AcquisitionCompressionType(0x0014, 0x4032); Tag const AcquisitionSampleSize(0x0014, 0x4033); Tag const RectifierSmoothing(0x0014, 0x4034); Tag const DACSequence(0x0014, 0x4035); Tag const DACType(0x0014, 0x4036); Tag const DACGainPoints(0x0014, 0x4038); Tag const DACTimePoints(0x0014, 0x403a); Tag const DACAmplitude(0x0014, 0x403c); Tag const PreAmplifierSettingsSequence(0x0014, 0x4040); Tag const TransmitTransducerSettingsSequence(0x0014, 0x4050); Tag const ReceiveTransducerSettingsSequence(0x0014, 0x4051); Tag const IncidentAngle(0x0014, 0x4052); Tag const CouplingTechnique(0x0014, 0x4054); Tag const CouplingMedium(0x0014, 0x4056); Tag const CouplingVelocity(0x0014, 0x4057); Tag const ProbeCenterLocationX(0x0014, 0x4058); Tag const ProbeCenterLocationZ(0x0014, 0x4059); Tag const SoundPathLength(0x0014, 0x405a); Tag const DelayLawIdentifier(0x0014, 0x405c); Tag const GateSettingsSequence(0x0014, 0x4060); Tag const GateThreshold(0x0014, 0x4062); Tag const VelocityOfSound(0x0014, 0x4064); Tag const CalibrationSettingsSequence(0x0014, 0x4070); Tag const CalibrationProcedure(0x0014, 0x4072); Tag const ProcedureVersion(0x0014, 0x4074); Tag const ProcedureCreationDate(0x0014, 0x4076); Tag const ProcedureExpirationDate(0x0014, 0x4078); Tag const ProcedureLastModifiedDate(0x0014, 0x407a); Tag const CalibrationTime(0x0014, 0x407c); Tag const CalibrationDate(0x0014, 0x407e); Tag const ProbeDriveEquipmentSequence(0x0014, 0x4080); Tag const DriveType(0x0014, 0x4081); Tag const ProbeDriveNotes(0x0014, 0x4082); Tag const DriveProbeSequence(0x0014, 0x4083); Tag const ProbeInductance(0x0014, 0x4084); Tag const ProbeResistance(0x0014, 0x4085); Tag const ReceiveProbeSequence(0x0014, 0x4086); Tag const ProbeDriveSettingsSequence(0x0014, 0x4087); Tag const BridgeResistors(0x0014, 0x4088); Tag const ProbeOrientationAngle(0x0014, 0x4089); Tag const UserSelectedGainY(0x0014, 0x408b); Tag const UserSelectedPhase(0x0014, 0x408c); Tag const UserSelectedOffsetX(0x0014, 0x408d); Tag const UserSelectedOffsetY(0x0014, 0x408e); Tag const ChannelSettingsSequence(0x0014, 0x4091); Tag const ChannelThreshold(0x0014, 0x4092); Tag const ScannerSettingsSequence(0x0014, 0x409a); Tag const ScanProcedure(0x0014, 0x409b); Tag const TranslationRateX(0x0014, 0x409c); Tag const TranslationRateY(0x0014, 0x409d); Tag const ChannelOverlap(0x0014, 0x409f); Tag const ImageQualityIndicatorType(0x0014, 0x40a0); Tag const ImageQualityIndicatorMaterial(0x0014, 0x40a1); Tag const ImageQualityIndicatorSize(0x0014, 0x40a2); Tag const LINACEnergy(0x0014, 0x5002); Tag const LINACOutput(0x0014, 0x5004); Tag const ActiveAperture(0x0014, 0x5100); Tag const TotalAperture(0x0014, 0x5101); Tag const ApertureElevation(0x0014, 0x5102); Tag const MainLobeAngle(0x0014, 0x5103); Tag const MainRoofAngle(0x0014, 0x5104); Tag const ConnectorType(0x0014, 0x5105); Tag const WedgeModelNumber(0x0014, 0x5106); Tag const WedgeAngleFloat(0x0014, 0x5107); Tag const WedgeRoofAngle(0x0014, 0x5108); Tag const WedgeElement1Position(0x0014, 0x5109); Tag const WedgeMaterialVelocity(0x0014, 0x510a); Tag const WedgeMaterial(0x0014, 0x510b); Tag const WedgeOffsetZ(0x0014, 0x510c); Tag const WedgeOriginOffsetX(0x0014, 0x510d); Tag const WedgeTimeDelay(0x0014, 0x510e); Tag const WedgeName(0x0014, 0x510f); Tag const WedgeManufacturerName(0x0014, 0x5110); Tag const WedgeDescription(0x0014, 0x5111); Tag const NominalBeamAngle(0x0014, 0x5112); Tag const WedgeOffsetX(0x0014, 0x5113); Tag const WedgeOffsetY(0x0014, 0x5114); Tag const WedgeTotalLength(0x0014, 0x5115); Tag const WedgeInContactLength(0x0014, 0x5116); Tag const WedgeFrontGap(0x0014, 0x5117); Tag const WedgeTotalHeight(0x0014, 0x5118); Tag const WedgeFrontHeight(0x0014, 0x5119); Tag const WedgeRearHeight(0x0014, 0x511a); Tag const WedgeTotalWidth(0x0014, 0x511b); Tag const WedgeInContactWidth(0x0014, 0x511c); Tag const WedgeChamferHeight(0x0014, 0x511d); Tag const WedgeCurve(0x0014, 0x511e); Tag const RadiusAlongWedge(0x0014, 0x511f); Tag const ContrastBolusAgent(0x0018, 0x0010); Tag const ContrastBolusAgentSequence(0x0018, 0x0012); Tag const ContrastBolusT1Relaxivity(0x0018, 0x0013); Tag const ContrastBolusAdministrationRouteSequence(0x0018, 0x0014); Tag const BodyPartExamined(0x0018, 0x0015); Tag const ScanningSequence(0x0018, 0x0020); Tag const SequenceVariant(0x0018, 0x0021); Tag const ScanOptions(0x0018, 0x0022); Tag const MRAcquisitionType(0x0018, 0x0023); Tag const SequenceName(0x0018, 0x0024); Tag const AngioFlag(0x0018, 0x0025); Tag const InterventionDrugInformationSequence(0x0018, 0x0026); Tag const InterventionDrugStopTime(0x0018, 0x0027); Tag const InterventionDrugDose(0x0018, 0x0028); Tag const InterventionDrugCodeSequence(0x0018, 0x0029); Tag const AdditionalDrugSequence(0x0018, 0x002a); Tag const Radionuclide(0x0018, 0x0030); Tag const Radiopharmaceutical(0x0018, 0x0031); Tag const EnergyWindowCenterline(0x0018, 0x0032); Tag const EnergyWindowTotalWidth(0x0018, 0x0033); Tag const InterventionDrugName(0x0018, 0x0034); Tag const InterventionDrugStartTime(0x0018, 0x0035); Tag const InterventionSequence(0x0018, 0x0036); Tag const TherapyType(0x0018, 0x0037); Tag const InterventionStatus(0x0018, 0x0038); Tag const TherapyDescription(0x0018, 0x0039); Tag const InterventionDescription(0x0018, 0x003a); Tag const CineRate(0x0018, 0x0040); Tag const InitialCineRunState(0x0018, 0x0042); Tag const SliceThickness(0x0018, 0x0050); Tag const KVP(0x0018, 0x0060); Tag const CountsAccumulated(0x0018, 0x0070); Tag const AcquisitionTerminationCondition(0x0018, 0x0071); Tag const EffectiveDuration(0x0018, 0x0072); Tag const AcquisitionStartCondition(0x0018, 0x0073); Tag const AcquisitionStartConditionData(0x0018, 0x0074); Tag const AcquisitionTerminationConditionData(0x0018, 0x0075); Tag const RepetitionTime(0x0018, 0x0080); Tag const EchoTime(0x0018, 0x0081); Tag const InversionTime(0x0018, 0x0082); Tag const NumberOfAverages(0x0018, 0x0083); Tag const ImagingFrequency(0x0018, 0x0084); Tag const ImagedNucleus(0x0018, 0x0085); Tag const EchoNumbers(0x0018, 0x0086); Tag const MagneticFieldStrength(0x0018, 0x0087); Tag const SpacingBetweenSlices(0x0018, 0x0088); Tag const NumberOfPhaseEncodingSteps(0x0018, 0x0089); Tag const DataCollectionDiameter(0x0018, 0x0090); Tag const EchoTrainLength(0x0018, 0x0091); Tag const PercentSampling(0x0018, 0x0093); Tag const PercentPhaseFieldOfView(0x0018, 0x0094); Tag const PixelBandwidth(0x0018, 0x0095); Tag const DeviceSerialNumber(0x0018, 0x1000); Tag const DeviceUID(0x0018, 0x1002); Tag const DeviceID(0x0018, 0x1003); Tag const PlateID(0x0018, 0x1004); Tag const GeneratorID(0x0018, 0x1005); Tag const GridID(0x0018, 0x1006); Tag const CassetteID(0x0018, 0x1007); Tag const GantryID(0x0018, 0x1008); Tag const SecondaryCaptureDeviceID(0x0018, 0x1010); Tag const HardcopyCreationDeviceID(0x0018, 0x1011); Tag const DateOfSecondaryCapture(0x0018, 0x1012); Tag const TimeOfSecondaryCapture(0x0018, 0x1014); Tag const SecondaryCaptureDeviceManufacturer(0x0018, 0x1016); Tag const HardcopyDeviceManufacturer(0x0018, 0x1017); Tag const SecondaryCaptureDeviceManufacturerModelName(0x0018, 0x1018); Tag const SecondaryCaptureDeviceSoftwareVersions(0x0018, 0x1019); Tag const HardcopyDeviceSoftwareVersion(0x0018, 0x101a); Tag const HardcopyDeviceManufacturerModelName(0x0018, 0x101b); Tag const SoftwareVersions(0x0018, 0x1020); Tag const VideoImageFormatAcquired(0x0018, 0x1022); Tag const DigitalImageFormatAcquired(0x0018, 0x1023); Tag const ProtocolName(0x0018, 0x1030); Tag const ContrastBolusRoute(0x0018, 0x1040); Tag const ContrastBolusVolume(0x0018, 0x1041); Tag const ContrastBolusStartTime(0x0018, 0x1042); Tag const ContrastBolusStopTime(0x0018, 0x1043); Tag const ContrastBolusTotalDose(0x0018, 0x1044); Tag const SyringeCounts(0x0018, 0x1045); Tag const ContrastFlowRate(0x0018, 0x1046); Tag const ContrastFlowDuration(0x0018, 0x1047); Tag const ContrastBolusIngredient(0x0018, 0x1048); Tag const ContrastBolusIngredientConcentration(0x0018, 0x1049); Tag const SpatialResolution(0x0018, 0x1050); Tag const TriggerTime(0x0018, 0x1060); Tag const TriggerSourceOrType(0x0018, 0x1061); Tag const NominalInterval(0x0018, 0x1062); Tag const FrameTime(0x0018, 0x1063); Tag const CardiacFramingType(0x0018, 0x1064); Tag const FrameTimeVector(0x0018, 0x1065); Tag const FrameDelay(0x0018, 0x1066); Tag const ImageTriggerDelay(0x0018, 0x1067); Tag const MultiplexGroupTimeOffset(0x0018, 0x1068); Tag const TriggerTimeOffset(0x0018, 0x1069); Tag const SynchronizationTrigger(0x0018, 0x106a); Tag const SynchronizationChannel(0x0018, 0x106c); Tag const TriggerSamplePosition(0x0018, 0x106e); Tag const RadiopharmaceuticalRoute(0x0018, 0x1070); Tag const RadiopharmaceuticalVolume(0x0018, 0x1071); Tag const RadiopharmaceuticalStartTime(0x0018, 0x1072); Tag const RadiopharmaceuticalStopTime(0x0018, 0x1073); Tag const RadionuclideTotalDose(0x0018, 0x1074); Tag const RadionuclideHalfLife(0x0018, 0x1075); Tag const RadionuclidePositronFraction(0x0018, 0x1076); Tag const RadiopharmaceuticalSpecificActivity(0x0018, 0x1077); Tag const RadiopharmaceuticalStartDateTime(0x0018, 0x1078); Tag const RadiopharmaceuticalStopDateTime(0x0018, 0x1079); Tag const BeatRejectionFlag(0x0018, 0x1080); Tag const LowRRValue(0x0018, 0x1081); Tag const HighRRValue(0x0018, 0x1082); Tag const IntervalsAcquired(0x0018, 0x1083); Tag const IntervalsRejected(0x0018, 0x1084); Tag const PVCRejection(0x0018, 0x1085); Tag const SkipBeats(0x0018, 0x1086); Tag const HeartRate(0x0018, 0x1088); Tag const CardiacNumberOfImages(0x0018, 0x1090); Tag const TriggerWindow(0x0018, 0x1094); Tag const ReconstructionDiameter(0x0018, 0x1100); Tag const DistanceSourceToDetector(0x0018, 0x1110); Tag const DistanceSourceToPatient(0x0018, 0x1111); Tag const EstimatedRadiographicMagnificationFactor(0x0018, 0x1114); Tag const GantryDetectorTilt(0x0018, 0x1120); Tag const GantryDetectorSlew(0x0018, 0x1121); Tag const TableHeight(0x0018, 0x1130); Tag const TableTraverse(0x0018, 0x1131); Tag const TableMotion(0x0018, 0x1134); Tag const TableVerticalIncrement(0x0018, 0x1135); Tag const TableLateralIncrement(0x0018, 0x1136); Tag const TableLongitudinalIncrement(0x0018, 0x1137); Tag const TableAngle(0x0018, 0x1138); Tag const TableType(0x0018, 0x113a); Tag const RotationDirection(0x0018, 0x1140); Tag const AngularPosition(0x0018, 0x1141); Tag const RadialPosition(0x0018, 0x1142); Tag const ScanArc(0x0018, 0x1143); Tag const AngularStep(0x0018, 0x1144); Tag const CenterOfRotationOffset(0x0018, 0x1145); Tag const RotationOffset(0x0018, 0x1146); Tag const FieldOfViewShape(0x0018, 0x1147); Tag const FieldOfViewDimensions(0x0018, 0x1149); Tag const ExposureTime(0x0018, 0x1150); Tag const XRayTubeCurrent(0x0018, 0x1151); Tag const Exposure(0x0018, 0x1152); Tag const ExposureInuAs(0x0018, 0x1153); Tag const AveragePulseWidth(0x0018, 0x1154); Tag const RadiationSetting(0x0018, 0x1155); Tag const RectificationType(0x0018, 0x1156); Tag const RadiationMode(0x0018, 0x115a); Tag const ImageAndFluoroscopyAreaDoseProduct(0x0018, 0x115e); Tag const FilterType(0x0018, 0x1160); Tag const TypeOfFilters(0x0018, 0x1161); Tag const IntensifierSize(0x0018, 0x1162); Tag const ImagerPixelSpacing(0x0018, 0x1164); Tag const Grid(0x0018, 0x1166); Tag const GeneratorPower(0x0018, 0x1170); Tag const CollimatorGridName(0x0018, 0x1180); Tag const CollimatorType(0x0018, 0x1181); Tag const FocalDistance(0x0018, 0x1182); Tag const XFocusCenter(0x0018, 0x1183); Tag const YFocusCenter(0x0018, 0x1184); Tag const FocalSpots(0x0018, 0x1190); Tag const AnodeTargetMaterial(0x0018, 0x1191); Tag const BodyPartThickness(0x0018, 0x11a0); Tag const CompressionForce(0x0018, 0x11a2); Tag const PaddleDescription(0x0018, 0x11a4); Tag const DateOfLastCalibration(0x0018, 0x1200); Tag const TimeOfLastCalibration(0x0018, 0x1201); Tag const DateTimeOfLastCalibration(0x0018, 0x1202); Tag const ConvolutionKernel(0x0018, 0x1210); Tag const UpperLowerPixelValues(0x0018, 0x1240); Tag const ActualFrameDuration(0x0018, 0x1242); Tag const CountRate(0x0018, 0x1243); Tag const PreferredPlaybackSequencing(0x0018, 0x1244); Tag const ReceiveCoilName(0x0018, 0x1250); Tag const TransmitCoilName(0x0018, 0x1251); Tag const PlateType(0x0018, 0x1260); Tag const PhosphorType(0x0018, 0x1261); Tag const ScanVelocity(0x0018, 0x1300); Tag const WholeBodyTechnique(0x0018, 0x1301); Tag const ScanLength(0x0018, 0x1302); Tag const AcquisitionMatrix(0x0018, 0x1310); Tag const InPlanePhaseEncodingDirection(0x0018, 0x1312); Tag const FlipAngle(0x0018, 0x1314); Tag const VariableFlipAngleFlag(0x0018, 0x1315); Tag const SAR(0x0018, 0x1316); Tag const dBdt(0x0018, 0x1318); Tag const AcquisitionDeviceProcessingDescription(0x0018, 0x1400); Tag const AcquisitionDeviceProcessingCode(0x0018, 0x1401); Tag const CassetteOrientation(0x0018, 0x1402); Tag const CassetteSize(0x0018, 0x1403); Tag const ExposuresOnPlate(0x0018, 0x1404); Tag const RelativeXRayExposure(0x0018, 0x1405); Tag const ExposureIndex(0x0018, 0x1411); Tag const TargetExposureIndex(0x0018, 0x1412); Tag const DeviationIndex(0x0018, 0x1413); Tag const ColumnAngulation(0x0018, 0x1450); Tag const TomoLayerHeight(0x0018, 0x1460); Tag const TomoAngle(0x0018, 0x1470); Tag const TomoTime(0x0018, 0x1480); Tag const TomoType(0x0018, 0x1490); Tag const TomoClass(0x0018, 0x1491); Tag const NumberOfTomosynthesisSourceImages(0x0018, 0x1495); Tag const PositionerMotion(0x0018, 0x1500); Tag const PositionerType(0x0018, 0x1508); Tag const PositionerPrimaryAngle(0x0018, 0x1510); Tag const PositionerSecondaryAngle(0x0018, 0x1511); Tag const PositionerPrimaryAngleIncrement(0x0018, 0x1520); Tag const PositionerSecondaryAngleIncrement(0x0018, 0x1521); Tag const DetectorPrimaryAngle(0x0018, 0x1530); Tag const DetectorSecondaryAngle(0x0018, 0x1531); Tag const ShutterShape(0x0018, 0x1600); Tag const ShutterLeftVerticalEdge(0x0018, 0x1602); Tag const ShutterRightVerticalEdge(0x0018, 0x1604); Tag const ShutterUpperHorizontalEdge(0x0018, 0x1606); Tag const ShutterLowerHorizontalEdge(0x0018, 0x1608); Tag const CenterOfCircularShutter(0x0018, 0x1610); Tag const RadiusOfCircularShutter(0x0018, 0x1612); Tag const VerticesOfThePolygonalShutter(0x0018, 0x1620); Tag const ShutterPresentationValue(0x0018, 0x1622); Tag const ShutterOverlayGroup(0x0018, 0x1623); Tag const ShutterPresentationColorCIELabValue(0x0018, 0x1624); Tag const CollimatorShape(0x0018, 0x1700); Tag const CollimatorLeftVerticalEdge(0x0018, 0x1702); Tag const CollimatorRightVerticalEdge(0x0018, 0x1704); Tag const CollimatorUpperHorizontalEdge(0x0018, 0x1706); Tag const CollimatorLowerHorizontalEdge(0x0018, 0x1708); Tag const CenterOfCircularCollimator(0x0018, 0x1710); Tag const RadiusOfCircularCollimator(0x0018, 0x1712); Tag const VerticesOfThePolygonalCollimator(0x0018, 0x1720); Tag const AcquisitionTimeSynchronized(0x0018, 0x1800); Tag const TimeSource(0x0018, 0x1801); Tag const TimeDistributionProtocol(0x0018, 0x1802); Tag const NTPSourceAddress(0x0018, 0x1803); Tag const PageNumberVector(0x0018, 0x2001); Tag const FrameLabelVector(0x0018, 0x2002); Tag const FramePrimaryAngleVector(0x0018, 0x2003); Tag const FrameSecondaryAngleVector(0x0018, 0x2004); Tag const SliceLocationVector(0x0018, 0x2005); Tag const DisplayWindowLabelVector(0x0018, 0x2006); Tag const NominalScannedPixelSpacing(0x0018, 0x2010); Tag const DigitizingDeviceTransportDirection(0x0018, 0x2020); Tag const RotationOfScannedFilm(0x0018, 0x2030); Tag const BiopsyTargetSequence(0x0018, 0x2041); Tag const TargetUID(0x0018, 0x2042); Tag const LocalizingCursorPosition(0x0018, 0x2043); Tag const CalculatedTargetPosition(0x0018, 0x2044); Tag const TargetLabel(0x0018, 0x2045); Tag const DisplayedZValue(0x0018, 0x2046); Tag const IVUSAcquisition(0x0018, 0x3100); Tag const IVUSPullbackRate(0x0018, 0x3101); Tag const IVUSGatedRate(0x0018, 0x3102); Tag const IVUSPullbackStartFrameNumber(0x0018, 0x3103); Tag const IVUSPullbackStopFrameNumber(0x0018, 0x3104); Tag const LesionNumber(0x0018, 0x3105); Tag const AcquisitionComments(0x0018, 0x4000); Tag const OutputPower(0x0018, 0x5000); Tag const TransducerData(0x0018, 0x5010); Tag const FocusDepth(0x0018, 0x5012); Tag const ProcessingFunction(0x0018, 0x5020); Tag const PostprocessingFunction(0x0018, 0x5021); Tag const MechanicalIndex(0x0018, 0x5022); Tag const BoneThermalIndex(0x0018, 0x5024); Tag const CranialThermalIndex(0x0018, 0x5026); Tag const SoftTissueThermalIndex(0x0018, 0x5027); Tag const SoftTissueFocusThermalIndex(0x0018, 0x5028); Tag const SoftTissueSurfaceThermalIndex(0x0018, 0x5029); Tag const DynamicRange(0x0018, 0x5030); Tag const TotalGain(0x0018, 0x5040); Tag const DepthOfScanField(0x0018, 0x5050); Tag const PatientPosition(0x0018, 0x5100); Tag const ViewPosition(0x0018, 0x5101); Tag const ProjectionEponymousNameCodeSequence(0x0018, 0x5104); Tag const ImageTransformationMatrix(0x0018, 0x5210); Tag const ImageTranslationVector(0x0018, 0x5212); Tag const Sensitivity(0x0018, 0x6000); Tag const SequenceOfUltrasoundRegions(0x0018, 0x6011); Tag const RegionSpatialFormat(0x0018, 0x6012); Tag const RegionDataType(0x0018, 0x6014); Tag const RegionFlags(0x0018, 0x6016); Tag const RegionLocationMinX0(0x0018, 0x6018); Tag const RegionLocationMinY0(0x0018, 0x601a); Tag const RegionLocationMaxX1(0x0018, 0x601c); Tag const RegionLocationMaxY1(0x0018, 0x601e); Tag const ReferencePixelX0(0x0018, 0x6020); Tag const ReferencePixelY0(0x0018, 0x6022); Tag const PhysicalUnitsXDirection(0x0018, 0x6024); Tag const PhysicalUnitsYDirection(0x0018, 0x6026); Tag const ReferencePixelPhysicalValueX(0x0018, 0x6028); Tag const ReferencePixelPhysicalValueY(0x0018, 0x602a); Tag const PhysicalDeltaX(0x0018, 0x602c); Tag const PhysicalDeltaY(0x0018, 0x602e); Tag const TransducerFrequency(0x0018, 0x6030); Tag const TransducerType(0x0018, 0x6031); Tag const PulseRepetitionFrequency(0x0018, 0x6032); Tag const DopplerCorrectionAngle(0x0018, 0x6034); Tag const SteeringAngle(0x0018, 0x6036); Tag const DopplerSampleVolumeXPositionRetired(0x0018, 0x6038); Tag const DopplerSampleVolumeXPosition(0x0018, 0x6039); Tag const DopplerSampleVolumeYPositionRetired(0x0018, 0x603a); Tag const DopplerSampleVolumeYPosition(0x0018, 0x603b); Tag const TMLinePositionX0Retired(0x0018, 0x603c); Tag const TMLinePositionX0(0x0018, 0x603d); Tag const TMLinePositionY0Retired(0x0018, 0x603e); Tag const TMLinePositionY0(0x0018, 0x603f); Tag const TMLinePositionX1Retired(0x0018, 0x6040); Tag const TMLinePositionX1(0x0018, 0x6041); Tag const TMLinePositionY1Retired(0x0018, 0x6042); Tag const TMLinePositionY1(0x0018, 0x6043); Tag const PixelComponentOrganization(0x0018, 0x6044); Tag const PixelComponentMask(0x0018, 0x6046); Tag const PixelComponentRangeStart(0x0018, 0x6048); Tag const PixelComponentRangeStop(0x0018, 0x604a); Tag const PixelComponentPhysicalUnits(0x0018, 0x604c); Tag const PixelComponentDataType(0x0018, 0x604e); Tag const NumberOfTableBreakPoints(0x0018, 0x6050); Tag const TableOfXBreakPoints(0x0018, 0x6052); Tag const TableOfYBreakPoints(0x0018, 0x6054); Tag const NumberOfTableEntries(0x0018, 0x6056); Tag const TableOfPixelValues(0x0018, 0x6058); Tag const TableOfParameterValues(0x0018, 0x605a); Tag const RWaveTimeVector(0x0018, 0x6060); Tag const DetectorConditionsNominalFlag(0x0018, 0x7000); Tag const DetectorTemperature(0x0018, 0x7001); Tag const DetectorType(0x0018, 0x7004); Tag const DetectorConfiguration(0x0018, 0x7005); Tag const DetectorDescription(0x0018, 0x7006); Tag const DetectorMode(0x0018, 0x7008); Tag const DetectorID(0x0018, 0x700a); Tag const DateOfLastDetectorCalibration(0x0018, 0x700c); Tag const TimeOfLastDetectorCalibration(0x0018, 0x700e); Tag const ExposuresOnDetectorSinceLastCalibration(0x0018, 0x7010); Tag const ExposuresOnDetectorSinceManufactured(0x0018, 0x7011); Tag const DetectorTimeSinceLastExposure(0x0018, 0x7012); Tag const DetectorActiveTime(0x0018, 0x7014); Tag const DetectorActivationOffsetFromExposure(0x0018, 0x7016); Tag const DetectorBinning(0x0018, 0x701a); Tag const DetectorElementPhysicalSize(0x0018, 0x7020); Tag const DetectorElementSpacing(0x0018, 0x7022); Tag const DetectorActiveShape(0x0018, 0x7024); Tag const DetectorActiveDimensions(0x0018, 0x7026); Tag const DetectorActiveOrigin(0x0018, 0x7028); Tag const DetectorManufacturerName(0x0018, 0x702a); Tag const DetectorManufacturerModelName(0x0018, 0x702b); Tag const FieldOfViewOrigin(0x0018, 0x7030); Tag const FieldOfViewRotation(0x0018, 0x7032); Tag const FieldOfViewHorizontalFlip(0x0018, 0x7034); Tag const PixelDataAreaOriginRelativeToFOV(0x0018, 0x7036); Tag const PixelDataAreaRotationAngleRelativeToFOV(0x0018, 0x7038); Tag const GridAbsorbingMaterial(0x0018, 0x7040); Tag const GridSpacingMaterial(0x0018, 0x7041); Tag const GridThickness(0x0018, 0x7042); Tag const GridPitch(0x0018, 0x7044); Tag const GridAspectRatio(0x0018, 0x7046); Tag const GridPeriod(0x0018, 0x7048); Tag const GridFocalDistance(0x0018, 0x704c); Tag const FilterMaterial(0x0018, 0x7050); Tag const FilterThicknessMinimum(0x0018, 0x7052); Tag const FilterThicknessMaximum(0x0018, 0x7054); Tag const FilterBeamPathLengthMinimum(0x0018, 0x7056); Tag const FilterBeamPathLengthMaximum(0x0018, 0x7058); Tag const ExposureControlMode(0x0018, 0x7060); Tag const ExposureControlModeDescription(0x0018, 0x7062); Tag const ExposureStatus(0x0018, 0x7064); Tag const PhototimerSetting(0x0018, 0x7065); Tag const ExposureTimeInuS(0x0018, 0x8150); Tag const XRayTubeCurrentInuA(0x0018, 0x8151); Tag const ContentQualification(0x0018, 0x9004); Tag const PulseSequenceName(0x0018, 0x9005); Tag const MRImagingModifierSequence(0x0018, 0x9006); Tag const EchoPulseSequence(0x0018, 0x9008); Tag const InversionRecovery(0x0018, 0x9009); Tag const FlowCompensation(0x0018, 0x9010); Tag const MultipleSpinEcho(0x0018, 0x9011); Tag const MultiPlanarExcitation(0x0018, 0x9012); Tag const PhaseContrast(0x0018, 0x9014); Tag const TimeOfFlightContrast(0x0018, 0x9015); Tag const Spoiling(0x0018, 0x9016); Tag const SteadyStatePulseSequence(0x0018, 0x9017); Tag const EchoPlanarPulseSequence(0x0018, 0x9018); Tag const TagAngleFirstAxis(0x0018, 0x9019); Tag const MagnetizationTransfer(0x0018, 0x9020); Tag const T2Preparation(0x0018, 0x9021); Tag const BloodSignalNulling(0x0018, 0x9022); Tag const SaturationRecovery(0x0018, 0x9024); Tag const SpectrallySelectedSuppression(0x0018, 0x9025); Tag const SpectrallySelectedExcitation(0x0018, 0x9026); Tag const SpatialPresaturation(0x0018, 0x9027); Tag const Tagging(0x0018, 0x9028); Tag const OversamplingPhase(0x0018, 0x9029); Tag const TagSpacingFirstDimension(0x0018, 0x9030); Tag const GeometryOfKSpaceTraversal(0x0018, 0x9032); Tag const SegmentedKSpaceTraversal(0x0018, 0x9033); Tag const RectilinearPhaseEncodeReordering(0x0018, 0x9034); Tag const TagThickness(0x0018, 0x9035); Tag const PartialFourierDirection(0x0018, 0x9036); Tag const CardiacSynchronizationTechnique(0x0018, 0x9037); Tag const ReceiveCoilManufacturerName(0x0018, 0x9041); Tag const MRReceiveCoilSequence(0x0018, 0x9042); Tag const ReceiveCoilType(0x0018, 0x9043); Tag const QuadratureReceiveCoil(0x0018, 0x9044); Tag const MultiCoilDefinitionSequence(0x0018, 0x9045); Tag const MultiCoilConfiguration(0x0018, 0x9046); Tag const MultiCoilElementName(0x0018, 0x9047); Tag const MultiCoilElementUsed(0x0018, 0x9048); Tag const MRTransmitCoilSequence(0x0018, 0x9049); Tag const TransmitCoilManufacturerName(0x0018, 0x9050); Tag const TransmitCoilType(0x0018, 0x9051); Tag const SpectralWidth(0x0018, 0x9052); Tag const ChemicalShiftReference(0x0018, 0x9053); Tag const VolumeLocalizationTechnique(0x0018, 0x9054); Tag const MRAcquisitionFrequencyEncodingSteps(0x0018, 0x9058); Tag const Decoupling(0x0018, 0x9059); Tag const DecoupledNucleus(0x0018, 0x9060); Tag const DecouplingFrequency(0x0018, 0x9061); Tag const DecouplingMethod(0x0018, 0x9062); Tag const DecouplingChemicalShiftReference(0x0018, 0x9063); Tag const KSpaceFiltering(0x0018, 0x9064); Tag const TimeDomainFiltering(0x0018, 0x9065); Tag const NumberOfZeroFills(0x0018, 0x9066); Tag const BaselineCorrection(0x0018, 0x9067); Tag const ParallelReductionFactorInPlane(0x0018, 0x9069); Tag const CardiacRRIntervalSpecified(0x0018, 0x9070); Tag const AcquisitionDuration(0x0018, 0x9073); Tag const FrameAcquisitionDateTime(0x0018, 0x9074); Tag const DiffusionDirectionality(0x0018, 0x9075); Tag const DiffusionGradientDirectionSequence(0x0018, 0x9076); Tag const ParallelAcquisition(0x0018, 0x9077); Tag const ParallelAcquisitionTechnique(0x0018, 0x9078); Tag const InversionTimes(0x0018, 0x9079); Tag const MetaboliteMapDescription(0x0018, 0x9080); Tag const PartialFourier(0x0018, 0x9081); Tag const EffectiveEchoTime(0x0018, 0x9082); Tag const MetaboliteMapCodeSequence(0x0018, 0x9083); Tag const ChemicalShiftSequence(0x0018, 0x9084); Tag const CardiacSignalSource(0x0018, 0x9085); Tag const DiffusionBValue(0x0018, 0x9087); Tag const DiffusionGradientOrientation(0x0018, 0x9089); Tag const VelocityEncodingDirection(0x0018, 0x9090); Tag const VelocityEncodingMinimumValue(0x0018, 0x9091); Tag const VelocityEncodingAcquisitionSequence(0x0018, 0x9092); Tag const NumberOfKSpaceTrajectories(0x0018, 0x9093); Tag const CoverageOfKSpace(0x0018, 0x9094); Tag const SpectroscopyAcquisitionPhaseRows(0x0018, 0x9095); Tag const ParallelReductionFactorInPlaneRetired(0x0018, 0x9096); Tag const TransmitterFrequency(0x0018, 0x9098); Tag const ResonantNucleus(0x0018, 0x9100); Tag const FrequencyCorrection(0x0018, 0x9101); Tag const MRSpectroscopyFOVGeometrySequence(0x0018, 0x9103); Tag const SlabThickness(0x0018, 0x9104); Tag const SlabOrientation(0x0018, 0x9105); Tag const MidSlabPosition(0x0018, 0x9106); Tag const MRSpatialSaturationSequence(0x0018, 0x9107); Tag const MRTimingAndRelatedParametersSequence(0x0018, 0x9112); Tag const MREchoSequence(0x0018, 0x9114); Tag const MRModifierSequence(0x0018, 0x9115); Tag const MRDiffusionSequence(0x0018, 0x9117); Tag const CardiacSynchronizationSequence(0x0018, 0x9118); Tag const MRAveragesSequence(0x0018, 0x9119); Tag const MRFOVGeometrySequence(0x0018, 0x9125); Tag const VolumeLocalizationSequence(0x0018, 0x9126); Tag const SpectroscopyAcquisitionDataColumns(0x0018, 0x9127); Tag const DiffusionAnisotropyType(0x0018, 0x9147); Tag const FrameReferenceDateTime(0x0018, 0x9151); Tag const MRMetaboliteMapSequence(0x0018, 0x9152); Tag const ParallelReductionFactorOutOfPlane(0x0018, 0x9155); Tag const SpectroscopyAcquisitionOutOfPlanePhaseSteps(0x0018, 0x9159); Tag const BulkMotionStatus(0x0018, 0x9166); Tag const ParallelReductionFactorSecondInPlane(0x0018, 0x9168); Tag const CardiacBeatRejectionTechnique(0x0018, 0x9169); Tag const RespiratoryMotionCompensationTechnique(0x0018, 0x9170); Tag const RespiratorySignalSource(0x0018, 0x9171); Tag const BulkMotionCompensationTechnique(0x0018, 0x9172); Tag const BulkMotionSignalSource(0x0018, 0x9173); Tag const ApplicableSafetyStandardAgency(0x0018, 0x9174); Tag const ApplicableSafetyStandardDescription(0x0018, 0x9175); Tag const OperatingModeSequence(0x0018, 0x9176); Tag const OperatingModeType(0x0018, 0x9177); Tag const OperatingMode(0x0018, 0x9178); Tag const SpecificAbsorptionRateDefinition(0x0018, 0x9179); Tag const GradientOutputType(0x0018, 0x9180); Tag const SpecificAbsorptionRateValue(0x0018, 0x9181); Tag const GradientOutput(0x0018, 0x9182); Tag const FlowCompensationDirection(0x0018, 0x9183); Tag const TaggingDelay(0x0018, 0x9184); Tag const RespiratoryMotionCompensationTechniqueDescription(0x0018, 0x9185); Tag const RespiratorySignalSourceID(0x0018, 0x9186); Tag const ChemicalShiftMinimumIntegrationLimitInHz(0x0018, 0x9195); Tag const ChemicalShiftMaximumIntegrationLimitInHz(0x0018, 0x9196); Tag const MRVelocityEncodingSequence(0x0018, 0x9197); Tag const FirstOrderPhaseCorrection(0x0018, 0x9198); Tag const WaterReferencedPhaseCorrection(0x0018, 0x9199); Tag const MRSpectroscopyAcquisitionType(0x0018, 0x9200); Tag const RespiratoryCyclePosition(0x0018, 0x9214); Tag const VelocityEncodingMaximumValue(0x0018, 0x9217); Tag const TagSpacingSecondDimension(0x0018, 0x9218); Tag const TagAngleSecondAxis(0x0018, 0x9219); Tag const FrameAcquisitionDuration(0x0018, 0x9220); Tag const MRImageFrameTypeSequence(0x0018, 0x9226); Tag const MRSpectroscopyFrameTypeSequence(0x0018, 0x9227); Tag const MRAcquisitionPhaseEncodingStepsInPlane(0x0018, 0x9231); Tag const MRAcquisitionPhaseEncodingStepsOutOfPlane(0x0018, 0x9232); Tag const SpectroscopyAcquisitionPhaseColumns(0x0018, 0x9234); Tag const CardiacCyclePosition(0x0018, 0x9236); Tag const SpecificAbsorptionRateSequence(0x0018, 0x9239); Tag const RFEchoTrainLength(0x0018, 0x9240); Tag const GradientEchoTrainLength(0x0018, 0x9241); Tag const ArterialSpinLabelingContrast(0x0018, 0x9250); Tag const MRArterialSpinLabelingSequence(0x0018, 0x9251); Tag const ASLTechniqueDescription(0x0018, 0x9252); Tag const ASLSlabNumber(0x0018, 0x9253); Tag const ASLSlabThickness(0x0018, 0x9254); Tag const ASLSlabOrientation(0x0018, 0x9255); Tag const ASLMidSlabPosition(0x0018, 0x9256); Tag const ASLContext(0x0018, 0x9257); Tag const ASLPulseTrainDuration(0x0018, 0x9258); Tag const ASLCrusherFlag(0x0018, 0x9259); Tag const ASLCrusherFlowLimit(0x0018, 0x925a); Tag const ASLCrusherDescription(0x0018, 0x925b); Tag const ASLBolusCutoffFlag(0x0018, 0x925c); Tag const ASLBolusCutoffTimingSequence(0x0018, 0x925d); Tag const ASLBolusCutoffTechnique(0x0018, 0x925e); Tag const ASLBolusCutoffDelayTime(0x0018, 0x925f); Tag const ASLSlabSequence(0x0018, 0x9260); Tag const ChemicalShiftMinimumIntegrationLimitInppm(0x0018, 0x9295); Tag const ChemicalShiftMaximumIntegrationLimitInppm(0x0018, 0x9296); Tag const WaterReferenceAcquisition(0x0018, 0x9297); Tag const EchoPeakPosition(0x0018, 0x9298); Tag const CTAcquisitionTypeSequence(0x0018, 0x9301); Tag const AcquisitionType(0x0018, 0x9302); Tag const TubeAngle(0x0018, 0x9303); Tag const CTAcquisitionDetailsSequence(0x0018, 0x9304); Tag const RevolutionTime(0x0018, 0x9305); Tag const SingleCollimationWidth(0x0018, 0x9306); Tag const TotalCollimationWidth(0x0018, 0x9307); Tag const CTTableDynamicsSequence(0x0018, 0x9308); Tag const TableSpeed(0x0018, 0x9309); Tag const TableFeedPerRotation(0x0018, 0x9310); Tag const SpiralPitchFactor(0x0018, 0x9311); Tag const CTGeometrySequence(0x0018, 0x9312); Tag const DataCollectionCenterPatient(0x0018, 0x9313); Tag const CTReconstructionSequence(0x0018, 0x9314); Tag const ReconstructionAlgorithm(0x0018, 0x9315); Tag const ConvolutionKernelGroup(0x0018, 0x9316); Tag const ReconstructionFieldOfView(0x0018, 0x9317); Tag const ReconstructionTargetCenterPatient(0x0018, 0x9318); Tag const ReconstructionAngle(0x0018, 0x9319); Tag const ImageFilter(0x0018, 0x9320); Tag const CTExposureSequence(0x0018, 0x9321); Tag const ReconstructionPixelSpacing(0x0018, 0x9322); Tag const ExposureModulationType(0x0018, 0x9323); Tag const EstimatedDoseSaving(0x0018, 0x9324); Tag const CTXRayDetailsSequence(0x0018, 0x9325); Tag const CTPositionSequence(0x0018, 0x9326); Tag const TablePosition(0x0018, 0x9327); Tag const ExposureTimeInms(0x0018, 0x9328); Tag const CTImageFrameTypeSequence(0x0018, 0x9329); Tag const XRayTubeCurrentInmA(0x0018, 0x9330); Tag const ExposureInmAs(0x0018, 0x9332); Tag const ConstantVolumeFlag(0x0018, 0x9333); Tag const FluoroscopyFlag(0x0018, 0x9334); Tag const DistanceSourceToDataCollectionCenter(0x0018, 0x9335); Tag const ContrastBolusAgentNumber(0x0018, 0x9337); Tag const ContrastBolusIngredientCodeSequence(0x0018, 0x9338); Tag const ContrastAdministrationProfileSequence(0x0018, 0x9340); Tag const ContrastBolusUsageSequence(0x0018, 0x9341); Tag const ContrastBolusAgentAdministered(0x0018, 0x9342); Tag const ContrastBolusAgentDetected(0x0018, 0x9343); Tag const ContrastBolusAgentPhase(0x0018, 0x9344); Tag const CTDIvol(0x0018, 0x9345); Tag const CTDIPhantomTypeCodeSequence(0x0018, 0x9346); Tag const CalciumScoringMassFactorPatient(0x0018, 0x9351); Tag const CalciumScoringMassFactorDevice(0x0018, 0x9352); Tag const EnergyWeightingFactor(0x0018, 0x9353); Tag const CTAdditionalXRaySourceSequence(0x0018, 0x9360); Tag const ProjectionPixelCalibrationSequence(0x0018, 0x9401); Tag const DistanceSourceToIsocenter(0x0018, 0x9402); Tag const DistanceObjectToTableTop(0x0018, 0x9403); Tag const ObjectPixelSpacingInCenterOfBeam(0x0018, 0x9404); Tag const PositionerPositionSequence(0x0018, 0x9405); Tag const TablePositionSequence(0x0018, 0x9406); Tag const CollimatorShapeSequence(0x0018, 0x9407); Tag const PlanesInAcquisition(0x0018, 0x9410); Tag const XAXRFFrameCharacteristicsSequence(0x0018, 0x9412); Tag const FrameAcquisitionSequence(0x0018, 0x9417); Tag const XRayReceptorType(0x0018, 0x9420); Tag const AcquisitionProtocolName(0x0018, 0x9423); Tag const AcquisitionProtocolDescription(0x0018, 0x9424); Tag const ContrastBolusIngredientOpaque(0x0018, 0x9425); Tag const DistanceReceptorPlaneToDetectorHousing(0x0018, 0x9426); Tag const IntensifierActiveShape(0x0018, 0x9427); Tag const IntensifierActiveDimensions(0x0018, 0x9428); Tag const PhysicalDetectorSize(0x0018, 0x9429); Tag const PositionOfIsocenterProjection(0x0018, 0x9430); Tag const FieldOfViewSequence(0x0018, 0x9432); Tag const FieldOfViewDescription(0x0018, 0x9433); Tag const ExposureControlSensingRegionsSequence(0x0018, 0x9434); Tag const ExposureControlSensingRegionShape(0x0018, 0x9435); Tag const ExposureControlSensingRegionLeftVerticalEdge(0x0018, 0x9436); Tag const ExposureControlSensingRegionRightVerticalEdge(0x0018, 0x9437); Tag const ExposureControlSensingRegionUpperHorizontalEdge(0x0018, 0x9438); Tag const ExposureControlSensingRegionLowerHorizontalEdge(0x0018, 0x9439); Tag const CenterOfCircularExposureControlSensingRegion(0x0018, 0x9440); Tag const RadiusOfCircularExposureControlSensingRegion(0x0018, 0x9441); Tag const VerticesOfThePolygonalExposureControlSensingRegion(0x0018, 0x9442); Tag const ColumnAngulationPatient(0x0018, 0x9447); Tag const BeamAngle(0x0018, 0x9449); Tag const FrameDetectorParametersSequence(0x0018, 0x9451); Tag const CalculatedAnatomyThickness(0x0018, 0x9452); Tag const CalibrationSequence(0x0018, 0x9455); Tag const ObjectThicknessSequence(0x0018, 0x9456); Tag const PlaneIdentification(0x0018, 0x9457); Tag const FieldOfViewDimensionsInFloat(0x0018, 0x9461); Tag const IsocenterReferenceSystemSequence(0x0018, 0x9462); Tag const PositionerIsocenterPrimaryAngle(0x0018, 0x9463); Tag const PositionerIsocenterSecondaryAngle(0x0018, 0x9464); Tag const PositionerIsocenterDetectorRotationAngle(0x0018, 0x9465); Tag const TableXPositionToIsocenter(0x0018, 0x9466); Tag const TableYPositionToIsocenter(0x0018, 0x9467); Tag const TableZPositionToIsocenter(0x0018, 0x9468); Tag const TableHorizontalRotationAngle(0x0018, 0x9469); Tag const TableHeadTiltAngle(0x0018, 0x9470); Tag const TableCradleTiltAngle(0x0018, 0x9471); Tag const FrameDisplayShutterSequence(0x0018, 0x9472); Tag const AcquiredImageAreaDoseProduct(0x0018, 0x9473); Tag const CArmPositionerTabletopRelationship(0x0018, 0x9474); Tag const XRayGeometrySequence(0x0018, 0x9476); Tag const IrradiationEventIdentificationSequence(0x0018, 0x9477); Tag const XRay3DFrameTypeSequence(0x0018, 0x9504); Tag const ContributingSourcesSequence(0x0018, 0x9506); Tag const XRay3DAcquisitionSequence(0x0018, 0x9507); Tag const PrimaryPositionerScanArc(0x0018, 0x9508); Tag const SecondaryPositionerScanArc(0x0018, 0x9509); Tag const PrimaryPositionerScanStartAngle(0x0018, 0x9510); Tag const SecondaryPositionerScanStartAngle(0x0018, 0x9511); Tag const PrimaryPositionerIncrement(0x0018, 0x9514); Tag const SecondaryPositionerIncrement(0x0018, 0x9515); Tag const StartAcquisitionDateTime(0x0018, 0x9516); Tag const EndAcquisitionDateTime(0x0018, 0x9517); Tag const PrimaryPositionerIncrementSign(0x0018, 0x9518); Tag const SecondaryPositionerIncrementSign(0x0018, 0x9519); Tag const ApplicationName(0x0018, 0x9524); Tag const ApplicationVersion(0x0018, 0x9525); Tag const ApplicationManufacturer(0x0018, 0x9526); Tag const AlgorithmType(0x0018, 0x9527); Tag const AlgorithmDescription(0x0018, 0x9528); Tag const XRay3DReconstructionSequence(0x0018, 0x9530); Tag const ReconstructionDescription(0x0018, 0x9531); Tag const PerProjectionAcquisitionSequence(0x0018, 0x9538); Tag const DetectorPositionSequence(0x0018, 0x9541); Tag const XRayAcquisitionDoseSequence(0x0018, 0x9542); Tag const XRaySourceIsocenterPrimaryAngle(0x0018, 0x9543); Tag const XRaySourceIsocenterSecondaryAngle(0x0018, 0x9544); Tag const BreastSupportIsocenterPrimaryAngle(0x0018, 0x9545); Tag const BreastSupportIsocenterSecondaryAngle(0x0018, 0x9546); Tag const BreastSupportXPositionToIsocenter(0x0018, 0x9547); Tag const BreastSupportYPositionToIsocenter(0x0018, 0x9548); Tag const BreastSupportZPositionToIsocenter(0x0018, 0x9549); Tag const DetectorIsocenterPrimaryAngle(0x0018, 0x9550); Tag const DetectorIsocenterSecondaryAngle(0x0018, 0x9551); Tag const DetectorXPositionToIsocenter(0x0018, 0x9552); Tag const DetectorYPositionToIsocenter(0x0018, 0x9553); Tag const DetectorZPositionToIsocenter(0x0018, 0x9554); Tag const XRayGridSequence(0x0018, 0x9555); Tag const XRayFilterSequence(0x0018, 0x9556); Tag const DetectorActiveAreaTLHCPosition(0x0018, 0x9557); Tag const DetectorActiveAreaOrientation(0x0018, 0x9558); Tag const PositionerPrimaryAngleDirection(0x0018, 0x9559); Tag const DiffusionBMatrixSequence(0x0018, 0x9601); Tag const DiffusionBValueXX(0x0018, 0x9602); Tag const DiffusionBValueXY(0x0018, 0x9603); Tag const DiffusionBValueXZ(0x0018, 0x9604); Tag const DiffusionBValueYY(0x0018, 0x9605); Tag const DiffusionBValueYZ(0x0018, 0x9606); Tag const DiffusionBValueZZ(0x0018, 0x9607); Tag const DecayCorrectionDateTime(0x0018, 0x9701); Tag const StartDensityThreshold(0x0018, 0x9715); Tag const StartRelativeDensityDifferenceThreshold(0x0018, 0x9716); Tag const StartCardiacTriggerCountThreshold(0x0018, 0x9717); Tag const StartRespiratoryTriggerCountThreshold(0x0018, 0x9718); Tag const TerminationCountsThreshold(0x0018, 0x9719); Tag const TerminationDensityThreshold(0x0018, 0x9720); Tag const TerminationRelativeDensityThreshold(0x0018, 0x9721); Tag const TerminationTimeThreshold(0x0018, 0x9722); Tag const TerminationCardiacTriggerCountThreshold(0x0018, 0x9723); Tag const TerminationRespiratoryTriggerCountThreshold(0x0018, 0x9724); Tag const DetectorGeometry(0x0018, 0x9725); Tag const TransverseDetectorSeparation(0x0018, 0x9726); Tag const AxialDetectorDimension(0x0018, 0x9727); Tag const RadiopharmaceuticalAgentNumber(0x0018, 0x9729); Tag const PETFrameAcquisitionSequence(0x0018, 0x9732); Tag const PETDetectorMotionDetailsSequence(0x0018, 0x9733); Tag const PETTableDynamicsSequence(0x0018, 0x9734); Tag const PETPositionSequence(0x0018, 0x9735); Tag const PETFrameCorrectionFactorsSequence(0x0018, 0x9736); Tag const RadiopharmaceuticalUsageSequence(0x0018, 0x9737); Tag const AttenuationCorrectionSource(0x0018, 0x9738); Tag const NumberOfIterations(0x0018, 0x9739); Tag const NumberOfSubsets(0x0018, 0x9740); Tag const PETReconstructionSequence(0x0018, 0x9749); Tag const PETFrameTypeSequence(0x0018, 0x9751); Tag const TimeOfFlightInformationUsed(0x0018, 0x9755); Tag const ReconstructionType(0x0018, 0x9756); Tag const DecayCorrected(0x0018, 0x9758); Tag const AttenuationCorrected(0x0018, 0x9759); Tag const ScatterCorrected(0x0018, 0x9760); Tag const DeadTimeCorrected(0x0018, 0x9761); Tag const GantryMotionCorrected(0x0018, 0x9762); Tag const PatientMotionCorrected(0x0018, 0x9763); Tag const CountLossNormalizationCorrected(0x0018, 0x9764); Tag const RandomsCorrected(0x0018, 0x9765); Tag const NonUniformRadialSamplingCorrected(0x0018, 0x9766); Tag const SensitivityCalibrated(0x0018, 0x9767); Tag const DetectorNormalizationCorrection(0x0018, 0x9768); Tag const IterativeReconstructionMethod(0x0018, 0x9769); Tag const AttenuationCorrectionTemporalRelationship(0x0018, 0x9770); Tag const PatientPhysiologicalStateSequence(0x0018, 0x9771); Tag const PatientPhysiologicalStateCodeSequence(0x0018, 0x9772); Tag const DepthsOfFocus(0x0018, 0x9801); Tag const ExcludedIntervalsSequence(0x0018, 0x9803); Tag const ExclusionStartDateTime(0x0018, 0x9804); Tag const ExclusionDuration(0x0018, 0x9805); Tag const USImageDescriptionSequence(0x0018, 0x9806); Tag const ImageDataTypeSequence(0x0018, 0x9807); Tag const DataType(0x0018, 0x9808); Tag const TransducerScanPatternCodeSequence(0x0018, 0x9809); Tag const AliasedDataType(0x0018, 0x980b); Tag const PositionMeasuringDeviceUsed(0x0018, 0x980c); Tag const TransducerGeometryCodeSequence(0x0018, 0x980d); Tag const TransducerBeamSteeringCodeSequence(0x0018, 0x980e); Tag const TransducerApplicationCodeSequence(0x0018, 0x980f); Tag const ZeroVelocityPixelValue(0x0018, 0x9810); Tag const ContributingEquipmentSequence(0x0018, 0xa001); Tag const ContributionDateTime(0x0018, 0xa002); Tag const ContributionDescription(0x0018, 0xa003); Tag const StudyInstanceUID(0x0020, 0x000d); Tag const SeriesInstanceUID(0x0020, 0x000e); Tag const StudyID(0x0020, 0x0010); Tag const SeriesNumber(0x0020, 0x0011); Tag const AcquisitionNumber(0x0020, 0x0012); Tag const InstanceNumber(0x0020, 0x0013); Tag const IsotopeNumber(0x0020, 0x0014); Tag const PhaseNumber(0x0020, 0x0015); Tag const IntervalNumber(0x0020, 0x0016); Tag const TimeSlotNumber(0x0020, 0x0017); Tag const AngleNumber(0x0020, 0x0018); Tag const ItemNumber(0x0020, 0x0019); Tag const PatientOrientation(0x0020, 0x0020); Tag const OverlayNumber(0x0020, 0x0022); Tag const CurveNumber(0x0020, 0x0024); Tag const LUTNumber(0x0020, 0x0026); Tag const ImagePosition(0x0020, 0x0030); Tag const ImagePositionPatient(0x0020, 0x0032); Tag const ImageOrientation(0x0020, 0x0035); Tag const ImageOrientationPatient(0x0020, 0x0037); Tag const Location(0x0020, 0x0050); Tag const FrameOfReferenceUID(0x0020, 0x0052); Tag const Laterality(0x0020, 0x0060); Tag const ImageLaterality(0x0020, 0x0062); Tag const ImageGeometryType(0x0020, 0x0070); Tag const MaskingImage(0x0020, 0x0080); Tag const ReportNumber(0x0020, 0x00aa); Tag const TemporalPositionIdentifier(0x0020, 0x0100); Tag const NumberOfTemporalPositions(0x0020, 0x0105); Tag const TemporalResolution(0x0020, 0x0110); Tag const SynchronizationFrameOfReferenceUID(0x0020, 0x0200); Tag const SOPInstanceUIDOfConcatenationSource(0x0020, 0x0242); Tag const SeriesInStudy(0x0020, 0x1000); Tag const AcquisitionsInSeries(0x0020, 0x1001); Tag const ImagesInAcquisition(0x0020, 0x1002); Tag const ImagesInSeries(0x0020, 0x1003); Tag const AcquisitionsInStudy(0x0020, 0x1004); Tag const ImagesInStudy(0x0020, 0x1005); Tag const Reference(0x0020, 0x1020); Tag const PositionReferenceIndicator(0x0020, 0x1040); Tag const SliceLocation(0x0020, 0x1041); Tag const OtherStudyNumbers(0x0020, 0x1070); Tag const NumberOfPatientRelatedStudies(0x0020, 0x1200); Tag const NumberOfPatientRelatedSeries(0x0020, 0x1202); Tag const NumberOfPatientRelatedInstances(0x0020, 0x1204); Tag const NumberOfStudyRelatedSeries(0x0020, 0x1206); Tag const NumberOfStudyRelatedInstances(0x0020, 0x1208); Tag const NumberOfSeriesRelatedInstances(0x0020, 0x1209); Tag const ModifyingDeviceID(0x0020, 0x3401); Tag const ModifiedImageID(0x0020, 0x3402); Tag const ModifiedImageDate(0x0020, 0x3403); Tag const ModifyingDeviceManufacturer(0x0020, 0x3404); Tag const ModifiedImageTime(0x0020, 0x3405); Tag const ModifiedImageDescription(0x0020, 0x3406); Tag const ImageComments(0x0020, 0x4000); Tag const OriginalImageIdentification(0x0020, 0x5000); Tag const OriginalImageIdentificationNomenclature(0x0020, 0x5002); Tag const StackID(0x0020, 0x9056); Tag const InStackPositionNumber(0x0020, 0x9057); Tag const FrameAnatomySequence(0x0020, 0x9071); Tag const FrameLaterality(0x0020, 0x9072); Tag const FrameContentSequence(0x0020, 0x9111); Tag const PlanePositionSequence(0x0020, 0x9113); Tag const PlaneOrientationSequence(0x0020, 0x9116); Tag const TemporalPositionIndex(0x0020, 0x9128); Tag const NominalCardiacTriggerDelayTime(0x0020, 0x9153); Tag const NominalCardiacTriggerTimePriorToRPeak(0x0020, 0x9154); Tag const ActualCardiacTriggerTimePriorToRPeak(0x0020, 0x9155); Tag const FrameAcquisitionNumber(0x0020, 0x9156); Tag const DimensionIndexValues(0x0020, 0x9157); Tag const FrameComments(0x0020, 0x9158); Tag const ConcatenationUID(0x0020, 0x9161); Tag const InConcatenationNumber(0x0020, 0x9162); Tag const InConcatenationTotalNumber(0x0020, 0x9163); Tag const DimensionOrganizationUID(0x0020, 0x9164); Tag const DimensionIndexPointer(0x0020, 0x9165); Tag const FunctionalGroupPointer(0x0020, 0x9167); Tag const UnassignedSharedConvertedAttributesSequence(0x0020, 0x9170); Tag const UnassignedPerFrameConvertedAttributesSequence(0x0020, 0x9171); Tag const ConversionSourceAttributesSequence(0x0020, 0x9172); Tag const DimensionIndexPrivateCreator(0x0020, 0x9213); Tag const DimensionOrganizationSequence(0x0020, 0x9221); Tag const DimensionIndexSequence(0x0020, 0x9222); Tag const ConcatenationFrameOffsetNumber(0x0020, 0x9228); Tag const FunctionalGroupPrivateCreator(0x0020, 0x9238); Tag const NominalPercentageOfCardiacPhase(0x0020, 0x9241); Tag const NominalPercentageOfRespiratoryPhase(0x0020, 0x9245); Tag const StartingRespiratoryAmplitude(0x0020, 0x9246); Tag const StartingRespiratoryPhase(0x0020, 0x9247); Tag const EndingRespiratoryAmplitude(0x0020, 0x9248); Tag const EndingRespiratoryPhase(0x0020, 0x9249); Tag const RespiratoryTriggerType(0x0020, 0x9250); Tag const RRIntervalTimeNominal(0x0020, 0x9251); Tag const ActualCardiacTriggerDelayTime(0x0020, 0x9252); Tag const RespiratorySynchronizationSequence(0x0020, 0x9253); Tag const RespiratoryIntervalTime(0x0020, 0x9254); Tag const NominalRespiratoryTriggerDelayTime(0x0020, 0x9255); Tag const RespiratoryTriggerDelayThreshold(0x0020, 0x9256); Tag const ActualRespiratoryTriggerDelayTime(0x0020, 0x9257); Tag const ImagePositionVolume(0x0020, 0x9301); Tag const ImageOrientationVolume(0x0020, 0x9302); Tag const UltrasoundAcquisitionGeometry(0x0020, 0x9307); Tag const ApexPosition(0x0020, 0x9308); Tag const VolumeToTransducerMappingMatrix(0x0020, 0x9309); Tag const VolumeToTableMappingMatrix(0x0020, 0x930a); Tag const VolumeToTransducerRelationship(0x0020, 0x930b); Tag const PatientFrameOfReferenceSource(0x0020, 0x930c); Tag const TemporalPositionTimeOffset(0x0020, 0x930d); Tag const PlanePositionVolumeSequence(0x0020, 0x930e); Tag const PlaneOrientationVolumeSequence(0x0020, 0x930f); Tag const TemporalPositionSequence(0x0020, 0x9310); Tag const DimensionOrganizationType(0x0020, 0x9311); Tag const VolumeFrameOfReferenceUID(0x0020, 0x9312); Tag const TableFrameOfReferenceUID(0x0020, 0x9313); Tag const DimensionDescriptionLabel(0x0020, 0x9421); Tag const PatientOrientationInFrameSequence(0x0020, 0x9450); Tag const FrameLabel(0x0020, 0x9453); Tag const AcquisitionIndex(0x0020, 0x9518); Tag const ContributingSOPInstancesReferenceSequence(0x0020, 0x9529); Tag const ReconstructionIndex(0x0020, 0x9536); Tag const LightPathFilterPassThroughWavelength(0x0022, 0x0001); Tag const LightPathFilterPassBand(0x0022, 0x0002); Tag const ImagePathFilterPassThroughWavelength(0x0022, 0x0003); Tag const ImagePathFilterPassBand(0x0022, 0x0004); Tag const PatientEyeMovementCommanded(0x0022, 0x0005); Tag const PatientEyeMovementCommandCodeSequence(0x0022, 0x0006); Tag const SphericalLensPower(0x0022, 0x0007); Tag const CylinderLensPower(0x0022, 0x0008); Tag const CylinderAxis(0x0022, 0x0009); Tag const EmmetropicMagnification(0x0022, 0x000a); Tag const IntraOcularPressure(0x0022, 0x000b); Tag const HorizontalFieldOfView(0x0022, 0x000c); Tag const PupilDilated(0x0022, 0x000d); Tag const DegreeOfDilation(0x0022, 0x000e); Tag const StereoBaselineAngle(0x0022, 0x0010); Tag const StereoBaselineDisplacement(0x0022, 0x0011); Tag const StereoHorizontalPixelOffset(0x0022, 0x0012); Tag const StereoVerticalPixelOffset(0x0022, 0x0013); Tag const StereoRotation(0x0022, 0x0014); Tag const AcquisitionDeviceTypeCodeSequence(0x0022, 0x0015); Tag const IlluminationTypeCodeSequence(0x0022, 0x0016); Tag const LightPathFilterTypeStackCodeSequence(0x0022, 0x0017); Tag const ImagePathFilterTypeStackCodeSequence(0x0022, 0x0018); Tag const LensesCodeSequence(0x0022, 0x0019); Tag const ChannelDescriptionCodeSequence(0x0022, 0x001a); Tag const RefractiveStateSequence(0x0022, 0x001b); Tag const MydriaticAgentCodeSequence(0x0022, 0x001c); Tag const RelativeImagePositionCodeSequence(0x0022, 0x001d); Tag const CameraAngleOfView(0x0022, 0x001e); Tag const StereoPairsSequence(0x0022, 0x0020); Tag const LeftImageSequence(0x0022, 0x0021); Tag const RightImageSequence(0x0022, 0x0022); Tag const StereoPairsPresent(0x0022, 0x0028); Tag const AxialLengthOfTheEye(0x0022, 0x0030); Tag const OphthalmicFrameLocationSequence(0x0022, 0x0031); Tag const ReferenceCoordinates(0x0022, 0x0032); Tag const DepthSpatialResolution(0x0022, 0x0035); Tag const MaximumDepthDistortion(0x0022, 0x0036); Tag const AlongScanSpatialResolution(0x0022, 0x0037); Tag const MaximumAlongScanDistortion(0x0022, 0x0038); Tag const OphthalmicImageOrientation(0x0022, 0x0039); Tag const DepthOfTransverseImage(0x0022, 0x0041); Tag const MydriaticAgentConcentrationUnitsSequence(0x0022, 0x0042); Tag const AcrossScanSpatialResolution(0x0022, 0x0048); Tag const MaximumAcrossScanDistortion(0x0022, 0x0049); Tag const MydriaticAgentConcentration(0x0022, 0x004e); Tag const IlluminationWaveLength(0x0022, 0x0055); Tag const IlluminationPower(0x0022, 0x0056); Tag const IlluminationBandwidth(0x0022, 0x0057); Tag const MydriaticAgentSequence(0x0022, 0x0058); Tag const OphthalmicAxialMeasurementsRightEyeSequence(0x0022, 0x1007); Tag const OphthalmicAxialMeasurementsLeftEyeSequence(0x0022, 0x1008); Tag const OphthalmicAxialMeasurementsDeviceType(0x0022, 0x1009); Tag const OphthalmicAxialLengthMeasurementsType(0x0022, 0x1010); Tag const OphthalmicAxialLengthSequence(0x0022, 0x1012); Tag const OphthalmicAxialLength(0x0022, 0x1019); Tag const LensStatusCodeSequence(0x0022, 0x1024); Tag const VitreousStatusCodeSequence(0x0022, 0x1025); Tag const IOLFormulaCodeSequence(0x0022, 0x1028); Tag const IOLFormulaDetail(0x0022, 0x1029); Tag const KeratometerIndex(0x0022, 0x1033); Tag const SourceOfOphthalmicAxialLengthCodeSequence(0x0022, 0x1035); Tag const TargetRefraction(0x0022, 0x1037); Tag const RefractiveProcedureOccurred(0x0022, 0x1039); Tag const RefractiveSurgeryTypeCodeSequence(0x0022, 0x1040); Tag const OphthalmicUltrasoundMethodCodeSequence(0x0022, 0x1044); Tag const OphthalmicAxialLengthMeasurementsSequence(0x0022, 0x1050); Tag const IOLPower(0x0022, 0x1053); Tag const PredictedRefractiveError(0x0022, 0x1054); Tag const OphthalmicAxialLengthVelocity(0x0022, 0x1059); Tag const LensStatusDescription(0x0022, 0x1065); Tag const VitreousStatusDescription(0x0022, 0x1066); Tag const IOLPowerSequence(0x0022, 0x1090); Tag const LensConstantSequence(0x0022, 0x1092); Tag const IOLManufacturer(0x0022, 0x1093); Tag const LensConstantDescription(0x0022, 0x1094); Tag const ImplantName(0x0022, 0x1095); Tag const KeratometryMeasurementTypeCodeSequence(0x0022, 0x1096); Tag const ImplantPartNumber(0x0022, 0x1097); Tag const ReferencedOphthalmicAxialMeasurementsSequence(0x0022, 0x1100); Tag const OphthalmicAxialLengthMeasurementsSegmentNameCodeSequence(0x0022, 0x1101); Tag const RefractiveErrorBeforeRefractiveSurgeryCodeSequence(0x0022, 0x1103); Tag const IOLPowerForExactEmmetropia(0x0022, 0x1121); Tag const IOLPowerForExactTargetRefraction(0x0022, 0x1122); Tag const AnteriorChamberDepthDefinitionCodeSequence(0x0022, 0x1125); Tag const LensThicknessSequence(0x0022, 0x1127); Tag const AnteriorChamberDepthSequence(0x0022, 0x1128); Tag const LensThickness(0x0022, 0x1130); Tag const AnteriorChamberDepth(0x0022, 0x1131); Tag const SourceOfLensThicknessDataCodeSequence(0x0022, 0x1132); Tag const SourceOfAnteriorChamberDepthDataCodeSequence(0x0022, 0x1133); Tag const SourceOfRefractiveMeasurementsSequence(0x0022, 0x1134); Tag const SourceOfRefractiveMeasurementsCodeSequence(0x0022, 0x1135); Tag const OphthalmicAxialLengthMeasurementModified(0x0022, 0x1140); Tag const OphthalmicAxialLengthDataSourceCodeSequence(0x0022, 0x1150); Tag const OphthalmicAxialLengthAcquisitionMethodCodeSequence(0x0022, 0x1153); Tag const SignalToNoiseRatio(0x0022, 0x1155); Tag const OphthalmicAxialLengthDataSourceDescription(0x0022, 0x1159); Tag const OphthalmicAxialLengthMeasurementsTotalLengthSequence(0x0022, 0x1210); Tag const OphthalmicAxialLengthMeasurementsSegmentalLengthSequence(0x0022, 0x1211); Tag const OphthalmicAxialLengthMeasurementsLengthSummationSequence(0x0022, 0x1212); Tag const UltrasoundOphthalmicAxialLengthMeasurementsSequence(0x0022, 0x1220); Tag const OpticalOphthalmicAxialLengthMeasurementsSequence(0x0022, 0x1225); Tag const UltrasoundSelectedOphthalmicAxialLengthSequence(0x0022, 0x1230); Tag const OphthalmicAxialLengthSelectionMethodCodeSequence(0x0022, 0x1250); Tag const OpticalSelectedOphthalmicAxialLengthSequence(0x0022, 0x1255); Tag const SelectedSegmentalOphthalmicAxialLengthSequence(0x0022, 0x1257); Tag const SelectedTotalOphthalmicAxialLengthSequence(0x0022, 0x1260); Tag const OphthalmicAxialLengthQualityMetricSequence(0x0022, 0x1262); Tag const OphthalmicAxialLengthQualityMetricTypeCodeSequence(0x0022, 0x1265); Tag const OphthalmicAxialLengthQualityMetricTypeDescription(0x0022, 0x1273); Tag const IntraocularLensCalculationsRightEyeSequence(0x0022, 0x1300); Tag const IntraocularLensCalculationsLeftEyeSequence(0x0022, 0x1310); Tag const ReferencedOphthalmicAxialLengthMeasurementQCImageSequence(0x0022, 0x1330); Tag const OphthalmicMappingDeviceType(0x0022, 0x1415); Tag const AcquisitionMethodCodeSequence(0x0022, 0x1420); Tag const AcquisitionMethodAlgorithmSequence(0x0022, 0x1423); Tag const OphthalmicThicknessMapTypeCodeSequence(0x0022, 0x1436); Tag const OphthalmicThicknessMappingNormalsSequence(0x0022, 0x1443); Tag const RetinalThicknessDefinitionCodeSequence(0x0022, 0x1445); Tag const PixelValueMappingToCodedConceptSequence(0x0022, 0x1450); Tag const MappedPixelValue(0x0022, 0x1452); Tag const PixelValueMappingExplanation(0x0022, 0x1454); Tag const OphthalmicThicknessMapQualityThresholdSequence(0x0022, 0x1458); Tag const OphthalmicThicknessMapThresholdQualityRating(0x0022, 0x1460); Tag const AnatomicStructureReferencePoint(0x0022, 0x1463); Tag const RegistrationToLocalizerSequence(0x0022, 0x1465); Tag const RegisteredLocalizerUnits(0x0022, 0x1466); Tag const RegisteredLocalizerTopLeftHandCorner(0x0022, 0x1467); Tag const RegisteredLocalizerBottomRightHandCorner(0x0022, 0x1468); Tag const OphthalmicThicknessMapQualityRatingSequence(0x0022, 0x1470); Tag const RelevantOPTAttributesSequence(0x0022, 0x1472); Tag const TransformationMethodCodeSequence(0x0022, 0x1512); Tag const TransformationAlgorithmSequence(0x0022, 0x1513); Tag const OphthalmicAxialLengthMethod(0x0022, 0x1515); Tag const OphthalmicFOV(0x0022, 0x1517); Tag const TwoDimensionalToThreeDimensionalMapSequence(0x0022, 0x1518); Tag const WideFieldOphthalmicPhotographyQualityRatingSequence(0x0022, 0x1525); Tag const WideFieldOphthalmicPhotographyQualityThresholdSequence(0x0022, 0x1526); Tag const WideFieldOphthalmicPhotographyThresholdQualityRating(0x0022, 0x1527); Tag const XCoordinatesCenterPixelViewAngle(0x0022, 0x1528); Tag const YCoordinatesCenterPixelViewAngle(0x0022, 0x1529); Tag const NumberOfMapPoints(0x0022, 0x1530); Tag const TwoDimensionalToThreeDimensionalMapData(0x0022, 0x1531); Tag const VisualFieldHorizontalExtent(0x0024, 0x0010); Tag const VisualFieldVerticalExtent(0x0024, 0x0011); Tag const VisualFieldShape(0x0024, 0x0012); Tag const ScreeningTestModeCodeSequence(0x0024, 0x0016); Tag const MaximumStimulusLuminance(0x0024, 0x0018); Tag const BackgroundLuminance(0x0024, 0x0020); Tag const StimulusColorCodeSequence(0x0024, 0x0021); Tag const BackgroundIlluminationColorCodeSequence(0x0024, 0x0024); Tag const StimulusArea(0x0024, 0x0025); Tag const StimulusPresentationTime(0x0024, 0x0028); Tag const FixationSequence(0x0024, 0x0032); Tag const FixationMonitoringCodeSequence(0x0024, 0x0033); Tag const VisualFieldCatchTrialSequence(0x0024, 0x0034); Tag const FixationCheckedQuantity(0x0024, 0x0035); Tag const PatientNotProperlyFixatedQuantity(0x0024, 0x0036); Tag const PresentedVisualStimuliDataFlag(0x0024, 0x0037); Tag const NumberOfVisualStimuli(0x0024, 0x0038); Tag const ExcessiveFixationLossesDataFlag(0x0024, 0x0039); Tag const ExcessiveFixationLosses(0x0024, 0x0040); Tag const StimuliRetestingQuantity(0x0024, 0x0042); Tag const CommentsOnPatientPerformanceOfVisualField(0x0024, 0x0044); Tag const FalseNegativesEstimateFlag(0x0024, 0x0045); Tag const FalseNegativesEstimate(0x0024, 0x0046); Tag const NegativeCatchTrialsQuantity(0x0024, 0x0048); Tag const FalseNegativesQuantity(0x0024, 0x0050); Tag const ExcessiveFalseNegativesDataFlag(0x0024, 0x0051); Tag const ExcessiveFalseNegatives(0x0024, 0x0052); Tag const FalsePositivesEstimateFlag(0x0024, 0x0053); Tag const FalsePositivesEstimate(0x0024, 0x0054); Tag const CatchTrialsDataFlag(0x0024, 0x0055); Tag const PositiveCatchTrialsQuantity(0x0024, 0x0056); Tag const TestPointNormalsDataFlag(0x0024, 0x0057); Tag const TestPointNormalsSequence(0x0024, 0x0058); Tag const GlobalDeviationProbabilityNormalsFlag(0x0024, 0x0059); Tag const FalsePositivesQuantity(0x0024, 0x0060); Tag const ExcessiveFalsePositivesDataFlag(0x0024, 0x0061); Tag const ExcessiveFalsePositives(0x0024, 0x0062); Tag const VisualFieldTestNormalsFlag(0x0024, 0x0063); Tag const ResultsNormalsSequence(0x0024, 0x0064); Tag const AgeCorrectedSensitivityDeviationAlgorithmSequence(0x0024, 0x0065); Tag const GlobalDeviationFromNormal(0x0024, 0x0066); Tag const GeneralizedDefectSensitivityDeviationAlgorithmSequence(0x0024, 0x0067); Tag const LocalizedDeviationFromNormal(0x0024, 0x0068); Tag const PatientReliabilityIndicator(0x0024, 0x0069); Tag const VisualFieldMeanSensitivity(0x0024, 0x0070); Tag const GlobalDeviationProbability(0x0024, 0x0071); Tag const LocalDeviationProbabilityNormalsFlag(0x0024, 0x0072); Tag const LocalizedDeviationProbability(0x0024, 0x0073); Tag const ShortTermFluctuationCalculated(0x0024, 0x0074); Tag const ShortTermFluctuation(0x0024, 0x0075); Tag const ShortTermFluctuationProbabilityCalculated(0x0024, 0x0076); Tag const ShortTermFluctuationProbability(0x0024, 0x0077); Tag const CorrectedLocalizedDeviationFromNormalCalculated(0x0024, 0x0078); Tag const CorrectedLocalizedDeviationFromNormal(0x0024, 0x0079); Tag const CorrectedLocalizedDeviationFromNormalProbabilityCalculated(0x0024, 0x0080); Tag const CorrectedLocalizedDeviationFromNormalProbability(0x0024, 0x0081); Tag const GlobalDeviationProbabilitySequence(0x0024, 0x0083); Tag const LocalizedDeviationProbabilitySequence(0x0024, 0x0085); Tag const FovealSensitivityMeasured(0x0024, 0x0086); Tag const FovealSensitivity(0x0024, 0x0087); Tag const VisualFieldTestDuration(0x0024, 0x0088); Tag const VisualFieldTestPointSequence(0x0024, 0x0089); Tag const VisualFieldTestPointXCoordinate(0x0024, 0x0090); Tag const VisualFieldTestPointYCoordinate(0x0024, 0x0091); Tag const AgeCorrectedSensitivityDeviationValue(0x0024, 0x0092); Tag const StimulusResults(0x0024, 0x0093); Tag const SensitivityValue(0x0024, 0x0094); Tag const RetestStimulusSeen(0x0024, 0x0095); Tag const RetestSensitivityValue(0x0024, 0x0096); Tag const VisualFieldTestPointNormalsSequence(0x0024, 0x0097); Tag const QuantifiedDefect(0x0024, 0x0098); Tag const AgeCorrectedSensitivityDeviationProbabilityValue(0x0024, 0x0100); Tag const GeneralizedDefectCorrectedSensitivityDeviationFlag(0x0024, 0x0102); Tag const GeneralizedDefectCorrectedSensitivityDeviationValue(0x0024, 0x0103); Tag const GeneralizedDefectCorrectedSensitivityDeviationProbabilityValue(0x0024, 0x0104); Tag const MinimumSensitivityValue(0x0024, 0x0105); Tag const BlindSpotLocalized(0x0024, 0x0106); Tag const BlindSpotXCoordinate(0x0024, 0x0107); Tag const BlindSpotYCoordinate(0x0024, 0x0108); Tag const VisualAcuityMeasurementSequence(0x0024, 0x0110); Tag const RefractiveParametersUsedOnPatientSequence(0x0024, 0x0112); Tag const MeasurementLaterality(0x0024, 0x0113); Tag const OphthalmicPatientClinicalInformationLeftEyeSequence(0x0024, 0x0114); Tag const OphthalmicPatientClinicalInformationRightEyeSequence(0x0024, 0x0115); Tag const FovealPointNormativeDataFlag(0x0024, 0x0117); Tag const FovealPointProbabilityValue(0x0024, 0x0118); Tag const ScreeningBaselineMeasured(0x0024, 0x0120); Tag const ScreeningBaselineMeasuredSequence(0x0024, 0x0122); Tag const ScreeningBaselineType(0x0024, 0x0124); Tag const ScreeningBaselineValue(0x0024, 0x0126); Tag const AlgorithmSource(0x0024, 0x0202); Tag const DataSetName(0x0024, 0x0306); Tag const DataSetVersion(0x0024, 0x0307); Tag const DataSetSource(0x0024, 0x0308); Tag const DataSetDescription(0x0024, 0x0309); Tag const VisualFieldTestReliabilityGlobalIndexSequence(0x0024, 0x0317); Tag const VisualFieldGlobalResultsIndexSequence(0x0024, 0x0320); Tag const DataObservationSequence(0x0024, 0x0325); Tag const IndexNormalsFlag(0x0024, 0x0338); Tag const IndexProbability(0x0024, 0x0341); Tag const IndexProbabilitySequence(0x0024, 0x0344); Tag const SamplesPerPixel(0x0028, 0x0002); Tag const SamplesPerPixelUsed(0x0028, 0x0003); Tag const PhotometricInterpretation(0x0028, 0x0004); Tag const ImageDimensions(0x0028, 0x0005); Tag const PlanarConfiguration(0x0028, 0x0006); Tag const NumberOfFrames(0x0028, 0x0008); Tag const FrameIncrementPointer(0x0028, 0x0009); Tag const FrameDimensionPointer(0x0028, 0x000a); Tag const Rows(0x0028, 0x0010); Tag const Columns(0x0028, 0x0011); Tag const Planes(0x0028, 0x0012); Tag const UltrasoundColorDataPresent(0x0028, 0x0014); Tag const PixelSpacing(0x0028, 0x0030); Tag const ZoomFactor(0x0028, 0x0031); Tag const ZoomCenter(0x0028, 0x0032); Tag const PixelAspectRatio(0x0028, 0x0034); Tag const ImageFormat(0x0028, 0x0040); Tag const ManipulatedImage(0x0028, 0x0050); Tag const CorrectedImage(0x0028, 0x0051); Tag const CompressionRecognitionCode(0x0028, 0x005f); Tag const CompressionCode(0x0028, 0x0060); Tag const CompressionOriginator(0x0028, 0x0061); Tag const CompressionLabel(0x0028, 0x0062); Tag const CompressionDescription(0x0028, 0x0063); Tag const CompressionSequence(0x0028, 0x0065); Tag const CompressionStepPointers(0x0028, 0x0066); Tag const RepeatInterval(0x0028, 0x0068); Tag const BitsGrouped(0x0028, 0x0069); Tag const PerimeterTable(0x0028, 0x0070); Tag const PerimeterValue(0x0028, 0x0071); Tag const PredictorRows(0x0028, 0x0080); Tag const PredictorColumns(0x0028, 0x0081); Tag const PredictorConstants(0x0028, 0x0082); Tag const BlockedPixels(0x0028, 0x0090); Tag const BlockRows(0x0028, 0x0091); Tag const BlockColumns(0x0028, 0x0092); Tag const RowOverlap(0x0028, 0x0093); Tag const ColumnOverlap(0x0028, 0x0094); Tag const BitsAllocated(0x0028, 0x0100); Tag const BitsStored(0x0028, 0x0101); Tag const HighBit(0x0028, 0x0102); Tag const PixelRepresentation(0x0028, 0x0103); Tag const SmallestValidPixelValue(0x0028, 0x0104); Tag const LargestValidPixelValue(0x0028, 0x0105); Tag const SmallestImagePixelValue(0x0028, 0x0106); Tag const LargestImagePixelValue(0x0028, 0x0107); Tag const SmallestPixelValueInSeries(0x0028, 0x0108); Tag const LargestPixelValueInSeries(0x0028, 0x0109); Tag const SmallestImagePixelValueInPlane(0x0028, 0x0110); Tag const LargestImagePixelValueInPlane(0x0028, 0x0111); Tag const PixelPaddingValue(0x0028, 0x0120); Tag const PixelPaddingRangeLimit(0x0028, 0x0121); Tag const FloatPixelPaddingValue(0x0028, 0x0122); Tag const DoubleFloatPixelPaddingValue(0x0028, 0x0123); Tag const FloatPixelPaddingRangeLimit(0x0028, 0x0124); Tag const DoubleFloatPixelPaddingRangeLimit(0x0028, 0x0125); Tag const ImageLocation(0x0028, 0x0200); Tag const QualityControlImage(0x0028, 0x0300); Tag const BurnedInAnnotation(0x0028, 0x0301); Tag const RecognizableVisualFeatures(0x0028, 0x0302); Tag const LongitudinalTemporalInformationModified(0x0028, 0x0303); Tag const ReferencedColorPaletteInstanceUID(0x0028, 0x0304); Tag const TransformLabel(0x0028, 0x0400); Tag const TransformVersionNumber(0x0028, 0x0401); Tag const NumberOfTransformSteps(0x0028, 0x0402); Tag const SequenceOfCompressedData(0x0028, 0x0403); Tag const DetailsOfCoefficients(0x0028, 0x0404); Tag const DCTLabel(0x0028, 0x0700); Tag const DataBlockDescription(0x0028, 0x0701); Tag const DataBlock(0x0028, 0x0702); Tag const NormalizationFactorFormat(0x0028, 0x0710); Tag const ZonalMapNumberFormat(0x0028, 0x0720); Tag const ZonalMapLocation(0x0028, 0x0721); Tag const ZonalMapFormat(0x0028, 0x0722); Tag const AdaptiveMapFormat(0x0028, 0x0730); Tag const CodeNumberFormat(0x0028, 0x0740); Tag const PixelSpacingCalibrationType(0x0028, 0x0a02); Tag const PixelSpacingCalibrationDescription(0x0028, 0x0a04); Tag const PixelIntensityRelationship(0x0028, 0x1040); Tag const PixelIntensityRelationshipSign(0x0028, 0x1041); Tag const WindowCenter(0x0028, 0x1050); Tag const WindowWidth(0x0028, 0x1051); Tag const RescaleIntercept(0x0028, 0x1052); Tag const RescaleSlope(0x0028, 0x1053); Tag const RescaleType(0x0028, 0x1054); Tag const WindowCenterWidthExplanation(0x0028, 0x1055); Tag const VOILUTFunction(0x0028, 0x1056); Tag const GrayScale(0x0028, 0x1080); Tag const RecommendedViewingMode(0x0028, 0x1090); Tag const GrayLookupTableDescriptor(0x0028, 0x1100); Tag const RedPaletteColorLookupTableDescriptor(0x0028, 0x1101); Tag const GreenPaletteColorLookupTableDescriptor(0x0028, 0x1102); Tag const BluePaletteColorLookupTableDescriptor(0x0028, 0x1103); Tag const AlphaPaletteColorLookupTableDescriptor(0x0028, 0x1104); Tag const LargeRedPaletteColorLookupTableDescriptor(0x0028, 0x1111); Tag const LargeGreenPaletteColorLookupTableDescriptor(0x0028, 0x1112); Tag const LargeBluePaletteColorLookupTableDescriptor(0x0028, 0x1113); Tag const PaletteColorLookupTableUID(0x0028, 0x1199); Tag const GrayLookupTableData(0x0028, 0x1200); Tag const RedPaletteColorLookupTableData(0x0028, 0x1201); Tag const GreenPaletteColorLookupTableData(0x0028, 0x1202); Tag const BluePaletteColorLookupTableData(0x0028, 0x1203); Tag const AlphaPaletteColorLookupTableData(0x0028, 0x1204); Tag const LargeRedPaletteColorLookupTableData(0x0028, 0x1211); Tag const LargeGreenPaletteColorLookupTableData(0x0028, 0x1212); Tag const LargeBluePaletteColorLookupTableData(0x0028, 0x1213); Tag const LargePaletteColorLookupTableUID(0x0028, 0x1214); Tag const SegmentedRedPaletteColorLookupTableData(0x0028, 0x1221); Tag const SegmentedGreenPaletteColorLookupTableData(0x0028, 0x1222); Tag const SegmentedBluePaletteColorLookupTableData(0x0028, 0x1223); Tag const BreastImplantPresent(0x0028, 0x1300); Tag const PartialView(0x0028, 0x1350); Tag const PartialViewDescription(0x0028, 0x1351); Tag const PartialViewCodeSequence(0x0028, 0x1352); Tag const SpatialLocationsPreserved(0x0028, 0x135a); Tag const DataFrameAssignmentSequence(0x0028, 0x1401); Tag const DataPathAssignment(0x0028, 0x1402); Tag const BitsMappedToColorLookupTable(0x0028, 0x1403); Tag const BlendingLUT1Sequence(0x0028, 0x1404); Tag const BlendingLUT1TransferFunction(0x0028, 0x1405); Tag const BlendingWeightConstant(0x0028, 0x1406); Tag const BlendingLookupTableDescriptor(0x0028, 0x1407); Tag const BlendingLookupTableData(0x0028, 0x1408); Tag const EnhancedPaletteColorLookupTableSequence(0x0028, 0x140b); Tag const BlendingLUT2Sequence(0x0028, 0x140c); Tag const BlendingLUT2TransferFunction(0x0028, 0x140d); Tag const DataPathID(0x0028, 0x140e); Tag const RGBLUTTransferFunction(0x0028, 0x140f); Tag const AlphaLUTTransferFunction(0x0028, 0x1410); Tag const ICCProfile(0x0028, 0x2000); Tag const LossyImageCompression(0x0028, 0x2110); Tag const LossyImageCompressionRatio(0x0028, 0x2112); Tag const LossyImageCompressionMethod(0x0028, 0x2114); Tag const ModalityLUTSequence(0x0028, 0x3000); Tag const LUTDescriptor(0x0028, 0x3002); Tag const LUTExplanation(0x0028, 0x3003); Tag const ModalityLUTType(0x0028, 0x3004); Tag const LUTData(0x0028, 0x3006); Tag const VOILUTSequence(0x0028, 0x3010); Tag const SoftcopyVOILUTSequence(0x0028, 0x3110); Tag const ImagePresentationComments(0x0028, 0x4000); Tag const BiPlaneAcquisitionSequence(0x0028, 0x5000); Tag const RepresentativeFrameNumber(0x0028, 0x6010); Tag const FrameNumbersOfInterest(0x0028, 0x6020); Tag const FrameOfInterestDescription(0x0028, 0x6022); Tag const FrameOfInterestType(0x0028, 0x6023); Tag const MaskPointers(0x0028, 0x6030); Tag const RWavePointer(0x0028, 0x6040); Tag const MaskSubtractionSequence(0x0028, 0x6100); Tag const MaskOperation(0x0028, 0x6101); Tag const ApplicableFrameRange(0x0028, 0x6102); Tag const MaskFrameNumbers(0x0028, 0x6110); Tag const ContrastFrameAveraging(0x0028, 0x6112); Tag const MaskSubPixelShift(0x0028, 0x6114); Tag const TIDOffset(0x0028, 0x6120); Tag const MaskOperationExplanation(0x0028, 0x6190); Tag const EquipmentAdministratorSequence(0x0028, 0x7000); Tag const NumberOfDisplaySubsystems(0x0028, 0x7001); Tag const CurrentConfigurationID(0x0028, 0x7002); Tag const DisplaySubsystemID(0x0028, 0x7003); Tag const DisplaySubsystemName(0x0028, 0x7004); Tag const DisplaySubsystemDescription(0x0028, 0x7005); Tag const SystemStatus(0x0028, 0x7006); Tag const SystemStatusComment(0x0028, 0x7007); Tag const TargetLuminanceCharacteristicsSequence(0x0028, 0x7008); Tag const LuminanceCharacteristicsID(0x0028, 0x7009); Tag const DisplaySubsystemConfigurationSequence(0x0028, 0x700a); Tag const ConfigurationID(0x0028, 0x700b); Tag const ConfigurationName(0x0028, 0x700c); Tag const ConfigurationDescription(0x0028, 0x700d); Tag const ReferencedTargetLuminanceCharacteristicsID(0x0028, 0x700e); Tag const QAResultsSequence(0x0028, 0x700f); Tag const DisplaySubsystemQAResultsSequence(0x0028, 0x7010); Tag const ConfigurationQAResultsSequence(0x0028, 0x7011); Tag const MeasurementEquipmentSequence(0x0028, 0x7012); Tag const MeasurementFunctions(0x0028, 0x7013); Tag const MeasurementEquipmentType(0x0028, 0x7014); Tag const VisualEvaluationResultSequence(0x0028, 0x7015); Tag const DisplayCalibrationResultSequence(0x0028, 0x7016); Tag const DDLValue(0x0028, 0x7017); Tag const CIExyWhitePoint(0x0028, 0x7018); Tag const DisplayFunctionType(0x0028, 0x7019); Tag const GammaValue(0x0028, 0x701a); Tag const NumberOfLuminancePoints(0x0028, 0x701b); Tag const LuminanceResponseSequence(0x0028, 0x701c); Tag const TargetMinimumLuminance(0x0028, 0x701d); Tag const TargetMaximumLuminance(0x0028, 0x701e); Tag const LuminanceValue(0x0028, 0x701f); Tag const LuminanceResponseDescription(0x0028, 0x7020); Tag const WhitePointFlag(0x0028, 0x7021); Tag const DisplayDeviceTypeCodeSequence(0x0028, 0x7022); Tag const DisplaySubsystemSequence(0x0028, 0x7023); Tag const LuminanceResultSequence(0x0028, 0x7024); Tag const AmbientLightValueSource(0x0028, 0x7025); Tag const MeasuredCharacteristics(0x0028, 0x7026); Tag const LuminanceUniformityResultSequence(0x0028, 0x7027); Tag const VisualEvaluationTestSequence(0x0028, 0x7028); Tag const TestResult(0x0028, 0x7029); Tag const TestResultComment(0x0028, 0x702a); Tag const TestImageValidation(0x0028, 0x702b); Tag const TestPatternCodeSequence(0x0028, 0x702c); Tag const MeasurementPatternCodeSequence(0x0028, 0x702d); Tag const VisualEvaluationMethodCodeSequence(0x0028, 0x702e); Tag const PixelDataProviderURL(0x0028, 0x7fe0); Tag const DataPointRows(0x0028, 0x9001); Tag const DataPointColumns(0x0028, 0x9002); Tag const SignalDomainColumns(0x0028, 0x9003); Tag const LargestMonochromePixelValue(0x0028, 0x9099); Tag const DataRepresentation(0x0028, 0x9108); Tag const PixelMeasuresSequence(0x0028, 0x9110); Tag const FrameVOILUTSequence(0x0028, 0x9132); Tag const PixelValueTransformationSequence(0x0028, 0x9145); Tag const SignalDomainRows(0x0028, 0x9235); Tag const DisplayFilterPercentage(0x0028, 0x9411); Tag const FramePixelShiftSequence(0x0028, 0x9415); Tag const SubtractionItemID(0x0028, 0x9416); Tag const PixelIntensityRelationshipLUTSequence(0x0028, 0x9422); Tag const FramePixelDataPropertiesSequence(0x0028, 0x9443); Tag const GeometricalProperties(0x0028, 0x9444); Tag const GeometricMaximumDistortion(0x0028, 0x9445); Tag const ImageProcessingApplied(0x0028, 0x9446); Tag const MaskSelectionMode(0x0028, 0x9454); Tag const LUTFunction(0x0028, 0x9474); Tag const MaskVisibilityPercentage(0x0028, 0x9478); Tag const PixelShiftSequence(0x0028, 0x9501); Tag const RegionPixelShiftSequence(0x0028, 0x9502); Tag const VerticesOfTheRegion(0x0028, 0x9503); Tag const MultiFramePresentationSequence(0x0028, 0x9505); Tag const PixelShiftFrameRange(0x0028, 0x9506); Tag const LUTFrameRange(0x0028, 0x9507); Tag const ImageToEquipmentMappingMatrix(0x0028, 0x9520); Tag const EquipmentCoordinateSystemIdentification(0x0028, 0x9537); Tag const StudyStatusID(0x0032, 0x000a); Tag const StudyPriorityID(0x0032, 0x000c); Tag const StudyIDIssuer(0x0032, 0x0012); Tag const StudyVerifiedDate(0x0032, 0x0032); Tag const StudyVerifiedTime(0x0032, 0x0033); Tag const StudyReadDate(0x0032, 0x0034); Tag const StudyReadTime(0x0032, 0x0035); Tag const ScheduledStudyStartDate(0x0032, 0x1000); Tag const ScheduledStudyStartTime(0x0032, 0x1001); Tag const ScheduledStudyStopDate(0x0032, 0x1010); Tag const ScheduledStudyStopTime(0x0032, 0x1011); Tag const ScheduledStudyLocation(0x0032, 0x1020); Tag const ScheduledStudyLocationAETitle(0x0032, 0x1021); Tag const ReasonForStudy(0x0032, 0x1030); Tag const RequestingPhysicianIdentificationSequence(0x0032, 0x1031); Tag const RequestingPhysician(0x0032, 0x1032); Tag const RequestingService(0x0032, 0x1033); Tag const RequestingServiceCodeSequence(0x0032, 0x1034); Tag const StudyArrivalDate(0x0032, 0x1040); Tag const StudyArrivalTime(0x0032, 0x1041); Tag const StudyCompletionDate(0x0032, 0x1050); Tag const StudyCompletionTime(0x0032, 0x1051); Tag const StudyComponentStatusID(0x0032, 0x1055); Tag const RequestedProcedureDescription(0x0032, 0x1060); Tag const RequestedProcedureCodeSequence(0x0032, 0x1064); Tag const RequestedContrastAgent(0x0032, 0x1070); Tag const StudyComments(0x0032, 0x4000); Tag const ReferencedPatientAliasSequence(0x0038, 0x0004); Tag const VisitStatusID(0x0038, 0x0008); Tag const AdmissionID(0x0038, 0x0010); Tag const IssuerOfAdmissionID(0x0038, 0x0011); Tag const IssuerOfAdmissionIDSequence(0x0038, 0x0014); Tag const RouteOfAdmissions(0x0038, 0x0016); Tag const ScheduledAdmissionDate(0x0038, 0x001a); Tag const ScheduledAdmissionTime(0x0038, 0x001b); Tag const ScheduledDischargeDate(0x0038, 0x001c); Tag const ScheduledDischargeTime(0x0038, 0x001d); Tag const ScheduledPatientInstitutionResidence(0x0038, 0x001e); Tag const AdmittingDate(0x0038, 0x0020); Tag const AdmittingTime(0x0038, 0x0021); Tag const DischargeDate(0x0038, 0x0030); Tag const DischargeTime(0x0038, 0x0032); Tag const DischargeDiagnosisDescription(0x0038, 0x0040); Tag const DischargeDiagnosisCodeSequence(0x0038, 0x0044); Tag const SpecialNeeds(0x0038, 0x0050); Tag const ServiceEpisodeID(0x0038, 0x0060); Tag const IssuerOfServiceEpisodeID(0x0038, 0x0061); Tag const ServiceEpisodeDescription(0x0038, 0x0062); Tag const IssuerOfServiceEpisodeIDSequence(0x0038, 0x0064); Tag const PertinentDocumentsSequence(0x0038, 0x0100); Tag const PertinentResourcesSequence(0x0038, 0x0101); Tag const ResourceDescription(0x0038, 0x0102); Tag const CurrentPatientLocation(0x0038, 0x0300); Tag const PatientInstitutionResidence(0x0038, 0x0400); Tag const PatientState(0x0038, 0x0500); Tag const PatientClinicalTrialParticipationSequence(0x0038, 0x0502); Tag const VisitComments(0x0038, 0x4000); Tag const WaveformOriginality(0x003a, 0x0004); Tag const NumberOfWaveformChannels(0x003a, 0x0005); Tag const NumberOfWaveformSamples(0x003a, 0x0010); Tag const SamplingFrequency(0x003a, 0x001a); Tag const MultiplexGroupLabel(0x003a, 0x0020); Tag const ChannelDefinitionSequence(0x003a, 0x0200); Tag const WaveformChannelNumber(0x003a, 0x0202); Tag const ChannelLabel(0x003a, 0x0203); Tag const ChannelStatus(0x003a, 0x0205); Tag const ChannelSourceSequence(0x003a, 0x0208); Tag const ChannelSourceModifiersSequence(0x003a, 0x0209); Tag const SourceWaveformSequence(0x003a, 0x020a); Tag const ChannelDerivationDescription(0x003a, 0x020c); Tag const ChannelSensitivity(0x003a, 0x0210); Tag const ChannelSensitivityUnitsSequence(0x003a, 0x0211); Tag const ChannelSensitivityCorrectionFactor(0x003a, 0x0212); Tag const ChannelBaseline(0x003a, 0x0213); Tag const ChannelTimeSkew(0x003a, 0x0214); Tag const ChannelSampleSkew(0x003a, 0x0215); Tag const ChannelOffset(0x003a, 0x0218); Tag const WaveformBitsStored(0x003a, 0x021a); Tag const FilterLowFrequency(0x003a, 0x0220); Tag const FilterHighFrequency(0x003a, 0x0221); Tag const NotchFilterFrequency(0x003a, 0x0222); Tag const NotchFilterBandwidth(0x003a, 0x0223); Tag const WaveformDataDisplayScale(0x003a, 0x0230); Tag const WaveformDisplayBackgroundCIELabValue(0x003a, 0x0231); Tag const WaveformPresentationGroupSequence(0x003a, 0x0240); Tag const PresentationGroupNumber(0x003a, 0x0241); Tag const ChannelDisplaySequence(0x003a, 0x0242); Tag const ChannelRecommendedDisplayCIELabValue(0x003a, 0x0244); Tag const ChannelPosition(0x003a, 0x0245); Tag const DisplayShadingFlag(0x003a, 0x0246); Tag const FractionalChannelDisplayScale(0x003a, 0x0247); Tag const AbsoluteChannelDisplayScale(0x003a, 0x0248); Tag const MultiplexedAudioChannelsDescriptionCodeSequence(0x003a, 0x0300); Tag const ChannelIdentificationCode(0x003a, 0x0301); Tag const ChannelMode(0x003a, 0x0302); Tag const ScheduledStationAETitle(0x0040, 0x0001); Tag const ScheduledProcedureStepStartDate(0x0040, 0x0002); Tag const ScheduledProcedureStepStartTime(0x0040, 0x0003); Tag const ScheduledProcedureStepEndDate(0x0040, 0x0004); Tag const ScheduledProcedureStepEndTime(0x0040, 0x0005); Tag const ScheduledPerformingPhysicianName(0x0040, 0x0006); Tag const ScheduledProcedureStepDescription(0x0040, 0x0007); Tag const ScheduledProtocolCodeSequence(0x0040, 0x0008); Tag const ScheduledProcedureStepID(0x0040, 0x0009); Tag const StageCodeSequence(0x0040, 0x000a); Tag const ScheduledPerformingPhysicianIdentificationSequence(0x0040, 0x000b); Tag const ScheduledStationName(0x0040, 0x0010); Tag const ScheduledProcedureStepLocation(0x0040, 0x0011); Tag const PreMedication(0x0040, 0x0012); Tag const ScheduledProcedureStepStatus(0x0040, 0x0020); Tag const OrderPlacerIdentifierSequence(0x0040, 0x0026); Tag const OrderFillerIdentifierSequence(0x0040, 0x0027); Tag const LocalNamespaceEntityID(0x0040, 0x0031); Tag const UniversalEntityID(0x0040, 0x0032); Tag const UniversalEntityIDType(0x0040, 0x0033); Tag const IdentifierTypeCode(0x0040, 0x0035); Tag const AssigningFacilitySequence(0x0040, 0x0036); Tag const AssigningJurisdictionCodeSequence(0x0040, 0x0039); Tag const AssigningAgencyOrDepartmentCodeSequence(0x0040, 0x003a); Tag const ScheduledProcedureStepSequence(0x0040, 0x0100); Tag const ReferencedNonImageCompositeSOPInstanceSequence(0x0040, 0x0220); Tag const PerformedStationAETitle(0x0040, 0x0241); Tag const PerformedStationName(0x0040, 0x0242); Tag const PerformedLocation(0x0040, 0x0243); Tag const PerformedProcedureStepStartDate(0x0040, 0x0244); Tag const PerformedProcedureStepStartTime(0x0040, 0x0245); Tag const PerformedProcedureStepEndDate(0x0040, 0x0250); Tag const PerformedProcedureStepEndTime(0x0040, 0x0251); Tag const PerformedProcedureStepStatus(0x0040, 0x0252); Tag const PerformedProcedureStepID(0x0040, 0x0253); Tag const PerformedProcedureStepDescription(0x0040, 0x0254); Tag const PerformedProcedureTypeDescription(0x0040, 0x0255); Tag const PerformedProtocolCodeSequence(0x0040, 0x0260); Tag const PerformedProtocolType(0x0040, 0x0261); Tag const ScheduledStepAttributesSequence(0x0040, 0x0270); Tag const RequestAttributesSequence(0x0040, 0x0275); Tag const CommentsOnThePerformedProcedureStep(0x0040, 0x0280); Tag const PerformedProcedureStepDiscontinuationReasonCodeSequence(0x0040, 0x0281); Tag const QuantitySequence(0x0040, 0x0293); Tag const Quantity(0x0040, 0x0294); Tag const MeasuringUnitsSequence(0x0040, 0x0295); Tag const BillingItemSequence(0x0040, 0x0296); Tag const TotalTimeOfFluoroscopy(0x0040, 0x0300); Tag const TotalNumberOfExposures(0x0040, 0x0301); Tag const EntranceDose(0x0040, 0x0302); Tag const ExposedArea(0x0040, 0x0303); Tag const DistanceSourceToEntrance(0x0040, 0x0306); Tag const DistanceSourceToSupport(0x0040, 0x0307); Tag const ExposureDoseSequence(0x0040, 0x030e); Tag const CommentsOnRadiationDose(0x0040, 0x0310); Tag const XRayOutput(0x0040, 0x0312); Tag const HalfValueLayer(0x0040, 0x0314); Tag const OrganDose(0x0040, 0x0316); Tag const OrganExposed(0x0040, 0x0318); Tag const BillingProcedureStepSequence(0x0040, 0x0320); Tag const FilmConsumptionSequence(0x0040, 0x0321); Tag const BillingSuppliesAndDevicesSequence(0x0040, 0x0324); Tag const ReferencedProcedureStepSequence(0x0040, 0x0330); Tag const PerformedSeriesSequence(0x0040, 0x0340); Tag const CommentsOnTheScheduledProcedureStep(0x0040, 0x0400); Tag const ProtocolContextSequence(0x0040, 0x0440); Tag const ContentItemModifierSequence(0x0040, 0x0441); Tag const ScheduledSpecimenSequence(0x0040, 0x0500); Tag const SpecimenAccessionNumber(0x0040, 0x050a); Tag const ContainerIdentifier(0x0040, 0x0512); Tag const IssuerOfTheContainerIdentifierSequence(0x0040, 0x0513); Tag const AlternateContainerIdentifierSequence(0x0040, 0x0515); Tag const ContainerTypeCodeSequence(0x0040, 0x0518); Tag const ContainerDescription(0x0040, 0x051a); Tag const ContainerComponentSequence(0x0040, 0x0520); Tag const SpecimenSequence(0x0040, 0x0550); Tag const SpecimenIdentifier(0x0040, 0x0551); Tag const SpecimenDescriptionSequenceTrial(0x0040, 0x0552); Tag const SpecimenDescriptionTrial(0x0040, 0x0553); Tag const SpecimenUID(0x0040, 0x0554); Tag const AcquisitionContextSequence(0x0040, 0x0555); Tag const AcquisitionContextDescription(0x0040, 0x0556); Tag const SpecimenTypeCodeSequence(0x0040, 0x059a); Tag const SpecimenDescriptionSequence(0x0040, 0x0560); Tag const IssuerOfTheSpecimenIdentifierSequence(0x0040, 0x0562); Tag const SpecimenShortDescription(0x0040, 0x0600); Tag const SpecimenDetailedDescription(0x0040, 0x0602); Tag const SpecimenPreparationSequence(0x0040, 0x0610); Tag const SpecimenPreparationStepContentItemSequence(0x0040, 0x0612); Tag const SpecimenLocalizationContentItemSequence(0x0040, 0x0620); Tag const SlideIdentifier(0x0040, 0x06fa); Tag const ImageCenterPointCoordinatesSequence(0x0040, 0x071a); Tag const XOffsetInSlideCoordinateSystem(0x0040, 0x072a); Tag const YOffsetInSlideCoordinateSystem(0x0040, 0x073a); Tag const ZOffsetInSlideCoordinateSystem(0x0040, 0x074a); Tag const PixelSpacingSequence(0x0040, 0x08d8); Tag const CoordinateSystemAxisCodeSequence(0x0040, 0x08da); Tag const MeasurementUnitsCodeSequence(0x0040, 0x08ea); Tag const VitalStainCodeSequenceTrial(0x0040, 0x09f8); Tag const RequestedProcedureID(0x0040, 0x1001); Tag const ReasonForTheRequestedProcedure(0x0040, 0x1002); Tag const RequestedProcedurePriority(0x0040, 0x1003); Tag const PatientTransportArrangements(0x0040, 0x1004); Tag const RequestedProcedureLocation(0x0040, 0x1005); Tag const PlacerOrderNumberProcedure(0x0040, 0x1006); Tag const FillerOrderNumberProcedure(0x0040, 0x1007); Tag const ConfidentialityCode(0x0040, 0x1008); Tag const ReportingPriority(0x0040, 0x1009); Tag const ReasonForRequestedProcedureCodeSequence(0x0040, 0x100a); Tag const NamesOfIntendedRecipientsOfResults(0x0040, 0x1010); Tag const IntendedRecipientsOfResultsIdentificationSequence(0x0040, 0x1011); Tag const ReasonForPerformedProcedureCodeSequence(0x0040, 0x1012); Tag const RequestedProcedureDescriptionTrial(0x0040, 0x1060); Tag const PersonIdentificationCodeSequence(0x0040, 0x1101); Tag const PersonAddress(0x0040, 0x1102); Tag const PersonTelephoneNumbers(0x0040, 0x1103); Tag const PersonTelecomInformation(0x0040, 0x1104); Tag const RequestedProcedureComments(0x0040, 0x1400); Tag const ReasonForTheImagingServiceRequest(0x0040, 0x2001); Tag const IssueDateOfImagingServiceRequest(0x0040, 0x2004); Tag const IssueTimeOfImagingServiceRequest(0x0040, 0x2005); Tag const PlacerOrderNumberImagingServiceRequestRetired(0x0040, 0x2006); Tag const FillerOrderNumberImagingServiceRequestRetired(0x0040, 0x2007); Tag const OrderEnteredBy(0x0040, 0x2008); Tag const OrderEntererLocation(0x0040, 0x2009); Tag const OrderCallbackPhoneNumber(0x0040, 0x2010); Tag const OrderCallbackTelecomInformation(0x0040, 0x2011); Tag const PlacerOrderNumberImagingServiceRequest(0x0040, 0x2016); Tag const FillerOrderNumberImagingServiceRequest(0x0040, 0x2017); Tag const ImagingServiceRequestComments(0x0040, 0x2400); Tag const ConfidentialityConstraintOnPatientDataDescription(0x0040, 0x3001); Tag const GeneralPurposeScheduledProcedureStepStatus(0x0040, 0x4001); Tag const GeneralPurposePerformedProcedureStepStatus(0x0040, 0x4002); Tag const GeneralPurposeScheduledProcedureStepPriority(0x0040, 0x4003); Tag const ScheduledProcessingApplicationsCodeSequence(0x0040, 0x4004); Tag const ScheduledProcedureStepStartDateTime(0x0040, 0x4005); Tag const MultipleCopiesFlag(0x0040, 0x4006); Tag const PerformedProcessingApplicationsCodeSequence(0x0040, 0x4007); Tag const HumanPerformerCodeSequence(0x0040, 0x4009); Tag const ScheduledProcedureStepModificationDateTime(0x0040, 0x4010); Tag const ExpectedCompletionDateTime(0x0040, 0x4011); Tag const ResultingGeneralPurposePerformedProcedureStepsSequence(0x0040, 0x4015); Tag const ReferencedGeneralPurposeScheduledProcedureStepSequence(0x0040, 0x4016); Tag const ScheduledWorkitemCodeSequence(0x0040, 0x4018); Tag const PerformedWorkitemCodeSequence(0x0040, 0x4019); Tag const InputAvailabilityFlag(0x0040, 0x4020); Tag const InputInformationSequence(0x0040, 0x4021); Tag const RelevantInformationSequence(0x0040, 0x4022); Tag const ReferencedGeneralPurposeScheduledProcedureStepTransactionUID(0x0040, 0x4023); Tag const ScheduledStationNameCodeSequence(0x0040, 0x4025); Tag const ScheduledStationClassCodeSequence(0x0040, 0x4026); Tag const ScheduledStationGeographicLocationCodeSequence(0x0040, 0x4027); Tag const PerformedStationNameCodeSequence(0x0040, 0x4028); Tag const PerformedStationClassCodeSequence(0x0040, 0x4029); Tag const PerformedStationGeographicLocationCodeSequence(0x0040, 0x4030); Tag const RequestedSubsequentWorkitemCodeSequence(0x0040, 0x4031); Tag const NonDICOMOutputCodeSequence(0x0040, 0x4032); Tag const OutputInformationSequence(0x0040, 0x4033); Tag const ScheduledHumanPerformersSequence(0x0040, 0x4034); Tag const ActualHumanPerformersSequence(0x0040, 0x4035); Tag const HumanPerformerOrganization(0x0040, 0x4036); Tag const HumanPerformerName(0x0040, 0x4037); Tag const RawDataHandling(0x0040, 0x4040); Tag const InputReadinessState(0x0040, 0x4041); Tag const PerformedProcedureStepStartDateTime(0x0040, 0x4050); Tag const PerformedProcedureStepEndDateTime(0x0040, 0x4051); Tag const ProcedureStepCancellationDateTime(0x0040, 0x4052); Tag const EntranceDoseInmGy(0x0040, 0x8302); Tag const ParametricMapFrameTypeSequence(0x0040, 0x9092); Tag const ReferencedImageRealWorldValueMappingSequence(0x0040, 0x9094); Tag const RealWorldValueMappingSequence(0x0040, 0x9096); Tag const PixelValueMappingCodeSequence(0x0040, 0x9098); Tag const LUTLabel(0x0040, 0x9210); Tag const RealWorldValueLastValueMapped(0x0040, 0x9211); Tag const RealWorldValueLUTData(0x0040, 0x9212); Tag const RealWorldValueFirstValueMapped(0x0040, 0x9216); Tag const QuantityDefinitionSequence(0x0040, 0x9220); Tag const RealWorldValueIntercept(0x0040, 0x9224); Tag const RealWorldValueSlope(0x0040, 0x9225); Tag const FindingsFlagTrial(0x0040, 0xa007); Tag const RelationshipType(0x0040, 0xa010); Tag const FindingsSequenceTrial(0x0040, 0xa020); Tag const FindingsGroupUIDTrial(0x0040, 0xa021); Tag const ReferencedFindingsGroupUIDTrial(0x0040, 0xa022); Tag const FindingsGroupRecordingDateTrial(0x0040, 0xa023); Tag const FindingsGroupRecordingTimeTrial(0x0040, 0xa024); Tag const FindingsSourceCategoryCodeSequenceTrial(0x0040, 0xa026); Tag const VerifyingOrganization(0x0040, 0xa027); Tag const DocumentingOrganizationIdentifierCodeSequenceTrial(0x0040, 0xa028); Tag const VerificationDateTime(0x0040, 0xa030); Tag const ObservationDateTime(0x0040, 0xa032); Tag const ValueType(0x0040, 0xa040); Tag const ConceptNameCodeSequence(0x0040, 0xa043); Tag const MeasurementPrecisionDescriptionTrial(0x0040, 0xa047); Tag const ContinuityOfContent(0x0040, 0xa050); Tag const UrgencyOrPriorityAlertsTrial(0x0040, 0xa057); Tag const SequencingIndicatorTrial(0x0040, 0xa060); Tag const DocumentIdentifierCodeSequenceTrial(0x0040, 0xa066); Tag const DocumentAuthorTrial(0x0040, 0xa067); Tag const DocumentAuthorIdentifierCodeSequenceTrial(0x0040, 0xa068); Tag const IdentifierCodeSequenceTrial(0x0040, 0xa070); Tag const VerifyingObserverSequence(0x0040, 0xa073); Tag const ObjectBinaryIdentifierTrial(0x0040, 0xa074); Tag const VerifyingObserverName(0x0040, 0xa075); Tag const DocumentingObserverIdentifierCodeSequenceTrial(0x0040, 0xa076); Tag const AuthorObserverSequence(0x0040, 0xa078); Tag const ParticipantSequence(0x0040, 0xa07a); Tag const CustodialOrganizationSequence(0x0040, 0xa07c); Tag const ParticipationType(0x0040, 0xa080); Tag const ParticipationDateTime(0x0040, 0xa082); Tag const ObserverType(0x0040, 0xa084); Tag const ProcedureIdentifierCodeSequenceTrial(0x0040, 0xa085); Tag const VerifyingObserverIdentificationCodeSequence(0x0040, 0xa088); Tag const ObjectDirectoryBinaryIdentifierTrial(0x0040, 0xa089); Tag const EquivalentCDADocumentSequence(0x0040, 0xa090); Tag const ReferencedWaveformChannels(0x0040, 0xa0b0); Tag const DateOfDocumentOrVerbalTransactionTrial(0x0040, 0xa110); Tag const TimeOfDocumentCreationOrVerbalTransactionTrial(0x0040, 0xa112); Tag const DateTime(0x0040, 0xa120); Tag const Date(0x0040, 0xa121); Tag const Time(0x0040, 0xa122); Tag const PersonName(0x0040, 0xa123); Tag const UID(0x0040, 0xa124); Tag const ReportStatusIDTrial(0x0040, 0xa125); Tag const TemporalRangeType(0x0040, 0xa130); Tag const ReferencedSamplePositions(0x0040, 0xa132); Tag const ReferencedFrameNumbers(0x0040, 0xa136); Tag const ReferencedTimeOffsets(0x0040, 0xa138); Tag const ReferencedDateTime(0x0040, 0xa13a); Tag const TextValue(0x0040, 0xa160); Tag const FloatingPointValue(0x0040, 0xa161); Tag const RationalNumeratorValue(0x0040, 0xa162); Tag const RationalDenominatorValue(0x0040, 0xa163); Tag const ObservationCategoryCodeSequenceTrial(0x0040, 0xa167); Tag const ConceptCodeSequence(0x0040, 0xa168); Tag const BibliographicCitationTrial(0x0040, 0xa16a); Tag const PurposeOfReferenceCodeSequence(0x0040, 0xa170); Tag const ObservationUID(0x0040, 0xa171); Tag const ReferencedObservationUIDTrial(0x0040, 0xa172); Tag const ReferencedObservationClassTrial(0x0040, 0xa173); Tag const ReferencedObjectObservationClassTrial(0x0040, 0xa174); Tag const AnnotationGroupNumber(0x0040, 0xa180); Tag const ObservationDateTrial(0x0040, 0xa192); Tag const ObservationTimeTrial(0x0040, 0xa193); Tag const MeasurementAutomationTrial(0x0040, 0xa194); Tag const ModifierCodeSequence(0x0040, 0xa195); Tag const IdentificationDescriptionTrial(0x0040, 0xa224); Tag const CoordinatesSetGeometricTypeTrial(0x0040, 0xa290); Tag const AlgorithmCodeSequenceTrial(0x0040, 0xa296); Tag const AlgorithmDescriptionTrial(0x0040, 0xa297); Tag const PixelCoordinatesSetTrial(0x0040, 0xa29a); Tag const MeasuredValueSequence(0x0040, 0xa300); Tag const NumericValueQualifierCodeSequence(0x0040, 0xa301); Tag const CurrentObserverTrial(0x0040, 0xa307); Tag const NumericValue(0x0040, 0xa30a); Tag const ReferencedAccessionSequenceTrial(0x0040, 0xa313); Tag const ReportStatusCommentTrial(0x0040, 0xa33a); Tag const ProcedureContextSequenceTrial(0x0040, 0xa340); Tag const VerbalSourceTrial(0x0040, 0xa352); Tag const AddressTrial(0x0040, 0xa353); Tag const TelephoneNumberTrial(0x0040, 0xa354); Tag const VerbalSourceIdentifierCodeSequenceTrial(0x0040, 0xa358); Tag const PredecessorDocumentsSequence(0x0040, 0xa360); Tag const ReferencedRequestSequence(0x0040, 0xa370); Tag const PerformedProcedureCodeSequence(0x0040, 0xa372); Tag const CurrentRequestedProcedureEvidenceSequence(0x0040, 0xa375); Tag const ReportDetailSequenceTrial(0x0040, 0xa380); Tag const PertinentOtherEvidenceSequence(0x0040, 0xa385); Tag const HL7StructuredDocumentReferenceSequence(0x0040, 0xa390); Tag const ObservationSubjectUIDTrial(0x0040, 0xa402); Tag const ObservationSubjectClassTrial(0x0040, 0xa403); Tag const ObservationSubjectTypeCodeSequenceTrial(0x0040, 0xa404); Tag const CompletionFlag(0x0040, 0xa491); Tag const CompletionFlagDescription(0x0040, 0xa492); Tag const VerificationFlag(0x0040, 0xa493); Tag const ArchiveRequested(0x0040, 0xa494); Tag const PreliminaryFlag(0x0040, 0xa496); Tag const ContentTemplateSequence(0x0040, 0xa504); Tag const IdenticalDocumentsSequence(0x0040, 0xa525); Tag const ObservationSubjectContextFlagTrial(0x0040, 0xa600); Tag const ObserverContextFlagTrial(0x0040, 0xa601); Tag const ProcedureContextFlagTrial(0x0040, 0xa603); Tag const ContentSequence(0x0040, 0xa730); Tag const RelationshipSequenceTrial(0x0040, 0xa731); Tag const RelationshipTypeCodeSequenceTrial(0x0040, 0xa732); Tag const LanguageCodeSequenceTrial(0x0040, 0xa744); Tag const UniformResourceLocatorTrial(0x0040, 0xa992); Tag const WaveformAnnotationSequence(0x0040, 0xb020); Tag const TemplateIdentifier(0x0040, 0xdb00); Tag const TemplateVersion(0x0040, 0xdb06); Tag const TemplateLocalVersion(0x0040, 0xdb07); Tag const TemplateExtensionFlag(0x0040, 0xdb0b); Tag const TemplateExtensionOrganizationUID(0x0040, 0xdb0c); Tag const TemplateExtensionCreatorUID(0x0040, 0xdb0d); Tag const ReferencedContentItemIdentifier(0x0040, 0xdb73); Tag const HL7InstanceIdentifier(0x0040, 0xe001); Tag const HL7DocumentEffectiveTime(0x0040, 0xe004); Tag const HL7DocumentTypeCodeSequence(0x0040, 0xe006); Tag const DocumentClassCodeSequence(0x0040, 0xe008); Tag const RetrieveURI(0x0040, 0xe010); Tag const RetrieveLocationUID(0x0040, 0xe011); Tag const TypeOfInstances(0x0040, 0xe020); Tag const DICOMRetrievalSequence(0x0040, 0xe021); Tag const DICOMMediaRetrievalSequence(0x0040, 0xe022); Tag const WADORetrievalSequence(0x0040, 0xe023); Tag const XDSRetrievalSequence(0x0040, 0xe024); Tag const WADORSRetrievalSequence(0x0040, 0xe025); Tag const RepositoryUniqueID(0x0040, 0xe030); Tag const HomeCommunityID(0x0040, 0xe031); Tag const DocumentTitle(0x0042, 0x0010); Tag const EncapsulatedDocument(0x0042, 0x0011); Tag const MIMETypeOfEncapsulatedDocument(0x0042, 0x0012); Tag const SourceInstanceSequence(0x0042, 0x0013); Tag const ListOfMIMETypes(0x0042, 0x0014); Tag const ProductPackageIdentifier(0x0044, 0x0001); Tag const SubstanceAdministrationApproval(0x0044, 0x0002); Tag const ApprovalStatusFurtherDescription(0x0044, 0x0003); Tag const ApprovalStatusDateTime(0x0044, 0x0004); Tag const ProductTypeCodeSequence(0x0044, 0x0007); Tag const ProductName(0x0044, 0x0008); Tag const ProductDescription(0x0044, 0x0009); Tag const ProductLotIdentifier(0x0044, 0x000a); Tag const ProductExpirationDateTime(0x0044, 0x000b); Tag const SubstanceAdministrationDateTime(0x0044, 0x0010); Tag const SubstanceAdministrationNotes(0x0044, 0x0011); Tag const SubstanceAdministrationDeviceID(0x0044, 0x0012); Tag const ProductParameterSequence(0x0044, 0x0013); Tag const SubstanceAdministrationParameterSequence(0x0044, 0x0019); Tag const LensDescription(0x0046, 0x0012); Tag const RightLensSequence(0x0046, 0x0014); Tag const LeftLensSequence(0x0046, 0x0015); Tag const UnspecifiedLateralityLensSequence(0x0046, 0x0016); Tag const CylinderSequence(0x0046, 0x0018); Tag const PrismSequence(0x0046, 0x0028); Tag const HorizontalPrismPower(0x0046, 0x0030); Tag const HorizontalPrismBase(0x0046, 0x0032); Tag const VerticalPrismPower(0x0046, 0x0034); Tag const VerticalPrismBase(0x0046, 0x0036); Tag const LensSegmentType(0x0046, 0x0038); Tag const OpticalTransmittance(0x0046, 0x0040); Tag const ChannelWidth(0x0046, 0x0042); Tag const PupilSize(0x0046, 0x0044); Tag const CornealSize(0x0046, 0x0046); Tag const AutorefractionRightEyeSequence(0x0046, 0x0050); Tag const AutorefractionLeftEyeSequence(0x0046, 0x0052); Tag const DistancePupillaryDistance(0x0046, 0x0060); Tag const NearPupillaryDistance(0x0046, 0x0062); Tag const IntermediatePupillaryDistance(0x0046, 0x0063); Tag const OtherPupillaryDistance(0x0046, 0x0064); Tag const KeratometryRightEyeSequence(0x0046, 0x0070); Tag const KeratometryLeftEyeSequence(0x0046, 0x0071); Tag const SteepKeratometricAxisSequence(0x0046, 0x0074); Tag const RadiusOfCurvature(0x0046, 0x0075); Tag const KeratometricPower(0x0046, 0x0076); Tag const KeratometricAxis(0x0046, 0x0077); Tag const FlatKeratometricAxisSequence(0x0046, 0x0080); Tag const BackgroundColor(0x0046, 0x0092); Tag const Optotype(0x0046, 0x0094); Tag const OptotypePresentation(0x0046, 0x0095); Tag const SubjectiveRefractionRightEyeSequence(0x0046, 0x0097); Tag const SubjectiveRefractionLeftEyeSequence(0x0046, 0x0098); Tag const AddNearSequence(0x0046, 0x0100); Tag const AddIntermediateSequence(0x0046, 0x0101); Tag const AddOtherSequence(0x0046, 0x0102); Tag const AddPower(0x0046, 0x0104); Tag const ViewingDistance(0x0046, 0x0106); Tag const VisualAcuityTypeCodeSequence(0x0046, 0x0121); Tag const VisualAcuityRightEyeSequence(0x0046, 0x0122); Tag const VisualAcuityLeftEyeSequence(0x0046, 0x0123); Tag const VisualAcuityBothEyesOpenSequence(0x0046, 0x0124); Tag const ViewingDistanceType(0x0046, 0x0125); Tag const VisualAcuityModifiers(0x0046, 0x0135); Tag const DecimalVisualAcuity(0x0046, 0x0137); Tag const OptotypeDetailedDefinition(0x0046, 0x0139); Tag const ReferencedRefractiveMeasurementsSequence(0x0046, 0x0145); Tag const SpherePower(0x0046, 0x0146); Tag const CylinderPower(0x0046, 0x0147); Tag const CornealTopographySurface(0x0046, 0x0201); Tag const CornealVertexLocation(0x0046, 0x0202); Tag const PupilCentroidXCoordinate(0x0046, 0x0203); Tag const PupilCentroidYCoordinate(0x0046, 0x0204); Tag const EquivalentPupilRadius(0x0046, 0x0205); Tag const CornealTopographyMapTypeCodeSequence(0x0046, 0x0207); Tag const VerticesOfTheOutlineOfPupil(0x0046, 0x0208); Tag const CornealTopographyMappingNormalsSequence(0x0046, 0x0210); Tag const MaximumCornealCurvatureSequence(0x0046, 0x0211); Tag const MaximumCornealCurvature(0x0046, 0x0212); Tag const MaximumCornealCurvatureLocation(0x0046, 0x0213); Tag const MinimumKeratometricSequence(0x0046, 0x0215); Tag const SimulatedKeratometricCylinderSequence(0x0046, 0x0218); Tag const AverageCornealPower(0x0046, 0x0220); Tag const CornealISValue(0x0046, 0x0224); Tag const AnalyzedArea(0x0046, 0x0227); Tag const SurfaceRegularityIndex(0x0046, 0x0230); Tag const SurfaceAsymmetryIndex(0x0046, 0x0232); Tag const CornealEccentricityIndex(0x0046, 0x0234); Tag const KeratoconusPredictionIndex(0x0046, 0x0236); Tag const DecimalPotentialVisualAcuity(0x0046, 0x0238); Tag const CornealTopographyMapQualityEvaluation(0x0046, 0x0242); Tag const SourceImageCornealProcessedDataSequence(0x0046, 0x0244); Tag const CornealPointLocation(0x0046, 0x0247); Tag const CornealPointEstimated(0x0046, 0x0248); Tag const AxialPower(0x0046, 0x0249); Tag const TangentialPower(0x0046, 0x0250); Tag const RefractivePower(0x0046, 0x0251); Tag const RelativeElevation(0x0046, 0x0252); Tag const CornealWavefront(0x0046, 0x0253); Tag const ImagedVolumeWidth(0x0048, 0x0001); Tag const ImagedVolumeHeight(0x0048, 0x0002); Tag const ImagedVolumeDepth(0x0048, 0x0003); Tag const TotalPixelMatrixColumns(0x0048, 0x0006); Tag const TotalPixelMatrixRows(0x0048, 0x0007); Tag const TotalPixelMatrixOriginSequence(0x0048, 0x0008); Tag const SpecimenLabelInImage(0x0048, 0x0010); Tag const FocusMethod(0x0048, 0x0011); Tag const ExtendedDepthOfField(0x0048, 0x0012); Tag const NumberOfFocalPlanes(0x0048, 0x0013); Tag const DistanceBetweenFocalPlanes(0x0048, 0x0014); Tag const RecommendedAbsentPixelCIELabValue(0x0048, 0x0015); Tag const IlluminatorTypeCodeSequence(0x0048, 0x0100); Tag const ImageOrientationSlide(0x0048, 0x0102); Tag const OpticalPathSequence(0x0048, 0x0105); Tag const OpticalPathIdentifier(0x0048, 0x0106); Tag const OpticalPathDescription(0x0048, 0x0107); Tag const IlluminationColorCodeSequence(0x0048, 0x0108); Tag const SpecimenReferenceSequence(0x0048, 0x0110); Tag const CondenserLensPower(0x0048, 0x0111); Tag const ObjectiveLensPower(0x0048, 0x0112); Tag const ObjectiveLensNumericalAperture(0x0048, 0x0113); Tag const PaletteColorLookupTableSequence(0x0048, 0x0120); Tag const ReferencedImageNavigationSequence(0x0048, 0x0200); Tag const TopLeftHandCornerOfLocalizerArea(0x0048, 0x0201); Tag const BottomRightHandCornerOfLocalizerArea(0x0048, 0x0202); Tag const OpticalPathIdentificationSequence(0x0048, 0x0207); Tag const PlanePositionSlideSequence(0x0048, 0x021a); Tag const ColumnPositionInTotalImagePixelMatrix(0x0048, 0x021e); Tag const RowPositionInTotalImagePixelMatrix(0x0048, 0x021f); Tag const PixelOriginInterpretation(0x0048, 0x0301); Tag const CalibrationImage(0x0050, 0x0004); Tag const DeviceSequence(0x0050, 0x0010); Tag const ContainerComponentTypeCodeSequence(0x0050, 0x0012); Tag const ContainerComponentThickness(0x0050, 0x0013); Tag const DeviceLength(0x0050, 0x0014); Tag const ContainerComponentWidth(0x0050, 0x0015); Tag const DeviceDiameter(0x0050, 0x0016); Tag const DeviceDiameterUnits(0x0050, 0x0017); Tag const DeviceVolume(0x0050, 0x0018); Tag const InterMarkerDistance(0x0050, 0x0019); Tag const ContainerComponentMaterial(0x0050, 0x001a); Tag const ContainerComponentID(0x0050, 0x001b); Tag const ContainerComponentLength(0x0050, 0x001c); Tag const ContainerComponentDiameter(0x0050, 0x001d); Tag const ContainerComponentDescription(0x0050, 0x001e); Tag const DeviceDescription(0x0050, 0x0020); Tag const ContrastBolusIngredientPercentByVolume(0x0052, 0x0001); Tag const OCTFocalDistance(0x0052, 0x0002); Tag const BeamSpotSize(0x0052, 0x0003); Tag const EffectiveRefractiveIndex(0x0052, 0x0004); Tag const OCTAcquisitionDomain(0x0052, 0x0006); Tag const OCTOpticalCenterWavelength(0x0052, 0x0007); Tag const AxialResolution(0x0052, 0x0008); Tag const RangingDepth(0x0052, 0x0009); Tag const ALineRate(0x0052, 0x0011); Tag const ALinesPerFrame(0x0052, 0x0012); Tag const CatheterRotationalRate(0x0052, 0x0013); Tag const ALinePixelSpacing(0x0052, 0x0014); Tag const ModeOfPercutaneousAccessSequence(0x0052, 0x0016); Tag const IntravascularOCTFrameTypeSequence(0x0052, 0x0025); Tag const OCTZOffsetApplied(0x0052, 0x0026); Tag const IntravascularFrameContentSequence(0x0052, 0x0027); Tag const IntravascularLongitudinalDistance(0x0052, 0x0028); Tag const IntravascularOCTFrameContentSequence(0x0052, 0x0029); Tag const OCTZOffsetCorrection(0x0052, 0x0030); Tag const CatheterDirectionOfRotation(0x0052, 0x0031); Tag const SeamLineLocation(0x0052, 0x0033); Tag const FirstALineLocation(0x0052, 0x0034); Tag const SeamLineIndex(0x0052, 0x0036); Tag const NumberOfPaddedALines(0x0052, 0x0038); Tag const InterpolationType(0x0052, 0x0039); Tag const RefractiveIndexApplied(0x0052, 0x003a); Tag const EnergyWindowVector(0x0054, 0x0010); Tag const NumberOfEnergyWindows(0x0054, 0x0011); Tag const EnergyWindowInformationSequence(0x0054, 0x0012); Tag const EnergyWindowRangeSequence(0x0054, 0x0013); Tag const EnergyWindowLowerLimit(0x0054, 0x0014); Tag const EnergyWindowUpperLimit(0x0054, 0x0015); Tag const RadiopharmaceuticalInformationSequence(0x0054, 0x0016); Tag const ResidualSyringeCounts(0x0054, 0x0017); Tag const EnergyWindowName(0x0054, 0x0018); Tag const DetectorVector(0x0054, 0x0020); Tag const NumberOfDetectors(0x0054, 0x0021); Tag const DetectorInformationSequence(0x0054, 0x0022); Tag const PhaseVector(0x0054, 0x0030); Tag const NumberOfPhases(0x0054, 0x0031); Tag const PhaseInformationSequence(0x0054, 0x0032); Tag const NumberOfFramesInPhase(0x0054, 0x0033); Tag const PhaseDelay(0x0054, 0x0036); Tag const PauseBetweenFrames(0x0054, 0x0038); Tag const PhaseDescription(0x0054, 0x0039); Tag const RotationVector(0x0054, 0x0050); Tag const NumberOfRotations(0x0054, 0x0051); Tag const RotationInformationSequence(0x0054, 0x0052); Tag const NumberOfFramesInRotation(0x0054, 0x0053); Tag const RRIntervalVector(0x0054, 0x0060); Tag const NumberOfRRIntervals(0x0054, 0x0061); Tag const GatedInformationSequence(0x0054, 0x0062); Tag const DataInformationSequence(0x0054, 0x0063); Tag const TimeSlotVector(0x0054, 0x0070); Tag const NumberOfTimeSlots(0x0054, 0x0071); Tag const TimeSlotInformationSequence(0x0054, 0x0072); Tag const TimeSlotTime(0x0054, 0x0073); Tag const SliceVector(0x0054, 0x0080); Tag const NumberOfSlices(0x0054, 0x0081); Tag const AngularViewVector(0x0054, 0x0090); Tag const TimeSliceVector(0x0054, 0x0100); Tag const NumberOfTimeSlices(0x0054, 0x0101); Tag const StartAngle(0x0054, 0x0200); Tag const TypeOfDetectorMotion(0x0054, 0x0202); Tag const TriggerVector(0x0054, 0x0210); Tag const NumberOfTriggersInPhase(0x0054, 0x0211); Tag const ViewCodeSequence(0x0054, 0x0220); Tag const ViewModifierCodeSequence(0x0054, 0x0222); Tag const RadionuclideCodeSequence(0x0054, 0x0300); Tag const AdministrationRouteCodeSequence(0x0054, 0x0302); Tag const RadiopharmaceuticalCodeSequence(0x0054, 0x0304); Tag const CalibrationDataSequence(0x0054, 0x0306); Tag const EnergyWindowNumber(0x0054, 0x0308); Tag const ImageID(0x0054, 0x0400); Tag const PatientOrientationCodeSequence(0x0054, 0x0410); Tag const PatientOrientationModifierCodeSequence(0x0054, 0x0412); Tag const PatientGantryRelationshipCodeSequence(0x0054, 0x0414); Tag const SliceProgressionDirection(0x0054, 0x0500); Tag const ScanProgressionDirection(0x0054, 0x0501); Tag const SeriesType(0x0054, 0x1000); Tag const Units(0x0054, 0x1001); Tag const CountsSource(0x0054, 0x1002); Tag const ReprojectionMethod(0x0054, 0x1004); Tag const SUVType(0x0054, 0x1006); Tag const RandomsCorrectionMethod(0x0054, 0x1100); Tag const AttenuationCorrectionMethod(0x0054, 0x1101); Tag const DecayCorrection(0x0054, 0x1102); Tag const ReconstructionMethod(0x0054, 0x1103); Tag const DetectorLinesOfResponseUsed(0x0054, 0x1104); Tag const ScatterCorrectionMethod(0x0054, 0x1105); Tag const AxialAcceptance(0x0054, 0x1200); Tag const AxialMash(0x0054, 0x1201); Tag const TransverseMash(0x0054, 0x1202); Tag const DetectorElementSize(0x0054, 0x1203); Tag const CoincidenceWindowWidth(0x0054, 0x1210); Tag const SecondaryCountsType(0x0054, 0x1220); Tag const FrameReferenceTime(0x0054, 0x1300); Tag const PrimaryPromptsCountsAccumulated(0x0054, 0x1310); Tag const SecondaryCountsAccumulated(0x0054, 0x1311); Tag const SliceSensitivityFactor(0x0054, 0x1320); Tag const DecayFactor(0x0054, 0x1321); Tag const DoseCalibrationFactor(0x0054, 0x1322); Tag const ScatterFractionFactor(0x0054, 0x1323); Tag const DeadTimeFactor(0x0054, 0x1324); Tag const ImageIndex(0x0054, 0x1330); Tag const CountsIncluded(0x0054, 0x1400); Tag const DeadTimeCorrectionFlag(0x0054, 0x1401); Tag const HistogramSequence(0x0060, 0x3000); Tag const HistogramNumberOfBins(0x0060, 0x3002); Tag const HistogramFirstBinValue(0x0060, 0x3004); Tag const HistogramLastBinValue(0x0060, 0x3006); Tag const HistogramBinWidth(0x0060, 0x3008); Tag const HistogramExplanation(0x0060, 0x3010); Tag const HistogramData(0x0060, 0x3020); Tag const SegmentationType(0x0062, 0x0001); Tag const SegmentSequence(0x0062, 0x0002); Tag const SegmentedPropertyCategoryCodeSequence(0x0062, 0x0003); Tag const SegmentNumber(0x0062, 0x0004); Tag const SegmentLabel(0x0062, 0x0005); Tag const SegmentDescription(0x0062, 0x0006); Tag const SegmentAlgorithmType(0x0062, 0x0008); Tag const SegmentAlgorithmName(0x0062, 0x0009); Tag const SegmentIdentificationSequence(0x0062, 0x000a); Tag const ReferencedSegmentNumber(0x0062, 0x000b); Tag const RecommendedDisplayGrayscaleValue(0x0062, 0x000c); Tag const RecommendedDisplayCIELabValue(0x0062, 0x000d); Tag const MaximumFractionalValue(0x0062, 0x000e); Tag const SegmentedPropertyTypeCodeSequence(0x0062, 0x000f); Tag const SegmentationFractionalType(0x0062, 0x0010); Tag const SegmentedPropertyTypeModifierCodeSequence(0x0062, 0x0011); Tag const UsedSegmentsSequence(0x0062, 0x0012); Tag const DeformableRegistrationSequence(0x0064, 0x0002); Tag const SourceFrameOfReferenceUID(0x0064, 0x0003); Tag const DeformableRegistrationGridSequence(0x0064, 0x0005); Tag const GridDimensions(0x0064, 0x0007); Tag const GridResolution(0x0064, 0x0008); Tag const VectorGridData(0x0064, 0x0009); Tag const PreDeformationMatrixRegistrationSequence(0x0064, 0x000f); Tag const PostDeformationMatrixRegistrationSequence(0x0064, 0x0010); Tag const NumberOfSurfaces(0x0066, 0x0001); Tag const SurfaceSequence(0x0066, 0x0002); Tag const SurfaceNumber(0x0066, 0x0003); Tag const SurfaceComments(0x0066, 0x0004); Tag const SurfaceProcessing(0x0066, 0x0009); Tag const SurfaceProcessingRatio(0x0066, 0x000a); Tag const SurfaceProcessingDescription(0x0066, 0x000b); Tag const RecommendedPresentationOpacity(0x0066, 0x000c); Tag const RecommendedPresentationType(0x0066, 0x000d); Tag const FiniteVolume(0x0066, 0x000e); Tag const Manifold(0x0066, 0x0010); Tag const SurfacePointsSequence(0x0066, 0x0011); Tag const SurfacePointsNormalsSequence(0x0066, 0x0012); Tag const SurfaceMeshPrimitivesSequence(0x0066, 0x0013); Tag const NumberOfSurfacePoints(0x0066, 0x0015); Tag const PointCoordinatesData(0x0066, 0x0016); Tag const PointPositionAccuracy(0x0066, 0x0017); Tag const MeanPointDistance(0x0066, 0x0018); Tag const MaximumPointDistance(0x0066, 0x0019); Tag const PointsBoundingBoxCoordinates(0x0066, 0x001a); Tag const AxisOfRotation(0x0066, 0x001b); Tag const CenterOfRotation(0x0066, 0x001c); Tag const NumberOfVectors(0x0066, 0x001e); Tag const VectorDimensionality(0x0066, 0x001f); Tag const VectorAccuracy(0x0066, 0x0020); Tag const VectorCoordinateData(0x0066, 0x0021); Tag const TrianglePointIndexList(0x0066, 0x0023); Tag const EdgePointIndexList(0x0066, 0x0024); Tag const VertexPointIndexList(0x0066, 0x0025); Tag const TriangleStripSequence(0x0066, 0x0026); Tag const TriangleFanSequence(0x0066, 0x0027); Tag const LineSequence(0x0066, 0x0028); Tag const PrimitivePointIndexList(0x0066, 0x0029); Tag const SurfaceCount(0x0066, 0x002a); Tag const ReferencedSurfaceSequence(0x0066, 0x002b); Tag const ReferencedSurfaceNumber(0x0066, 0x002c); Tag const SegmentSurfaceGenerationAlgorithmIdentificationSequence(0x0066, 0x002d); Tag const SegmentSurfaceSourceInstanceSequence(0x0066, 0x002e); Tag const AlgorithmFamilyCodeSequence(0x0066, 0x002f); Tag const AlgorithmNameCodeSequence(0x0066, 0x0030); Tag const AlgorithmVersion(0x0066, 0x0031); Tag const AlgorithmParameters(0x0066, 0x0032); Tag const FacetSequence(0x0066, 0x0034); Tag const SurfaceProcessingAlgorithmIdentificationSequence(0x0066, 0x0035); Tag const AlgorithmName(0x0066, 0x0036); Tag const RecommendedPointRadius(0x0066, 0x0037); Tag const RecommendedLineThickness(0x0066, 0x0038); Tag const LongPrimitivePointIndexList(0x0066, 0x0040); Tag const LongTrianglePointIndexList(0x0066, 0x0041); Tag const LongEdgePointIndexList(0x0066, 0x0042); Tag const LongVertexPointIndexList(0x0066, 0x0043); Tag const ImplantSize(0x0068, 0x6210); Tag const ImplantTemplateVersion(0x0068, 0x6221); Tag const ReplacedImplantTemplateSequence(0x0068, 0x6222); Tag const ImplantType(0x0068, 0x6223); Tag const DerivationImplantTemplateSequence(0x0068, 0x6224); Tag const OriginalImplantTemplateSequence(0x0068, 0x6225); Tag const EffectiveDateTime(0x0068, 0x6226); Tag const ImplantTargetAnatomySequence(0x0068, 0x6230); Tag const InformationFromManufacturerSequence(0x0068, 0x6260); Tag const NotificationFromManufacturerSequence(0x0068, 0x6265); Tag const InformationIssueDateTime(0x0068, 0x6270); Tag const InformationSummary(0x0068, 0x6280); Tag const ImplantRegulatoryDisapprovalCodeSequence(0x0068, 0x62a0); Tag const OverallTemplateSpatialTolerance(0x0068, 0x62a5); Tag const HPGLDocumentSequence(0x0068, 0x62c0); Tag const HPGLDocumentID(0x0068, 0x62d0); Tag const HPGLDocumentLabel(0x0068, 0x62d5); Tag const ViewOrientationCodeSequence(0x0068, 0x62e0); Tag const ViewOrientationModifier(0x0068, 0x62f0); Tag const HPGLDocumentScaling(0x0068, 0x62f2); Tag const HPGLDocument(0x0068, 0x6300); Tag const HPGLContourPenNumber(0x0068, 0x6310); Tag const HPGLPenSequence(0x0068, 0x6320); Tag const HPGLPenNumber(0x0068, 0x6330); Tag const HPGLPenLabel(0x0068, 0x6340); Tag const HPGLPenDescription(0x0068, 0x6345); Tag const RecommendedRotationPoint(0x0068, 0x6346); Tag const BoundingRectangle(0x0068, 0x6347); Tag const ImplantTemplate3DModelSurfaceNumber(0x0068, 0x6350); Tag const SurfaceModelDescriptionSequence(0x0068, 0x6360); Tag const SurfaceModelLabel(0x0068, 0x6380); Tag const SurfaceModelScalingFactor(0x0068, 0x6390); Tag const MaterialsCodeSequence(0x0068, 0x63a0); Tag const CoatingMaterialsCodeSequence(0x0068, 0x63a4); Tag const ImplantTypeCodeSequence(0x0068, 0x63a8); Tag const FixationMethodCodeSequence(0x0068, 0x63ac); Tag const MatingFeatureSetsSequence(0x0068, 0x63b0); Tag const MatingFeatureSetID(0x0068, 0x63c0); Tag const MatingFeatureSetLabel(0x0068, 0x63d0); Tag const MatingFeatureSequence(0x0068, 0x63e0); Tag const MatingFeatureID(0x0068, 0x63f0); Tag const MatingFeatureDegreeOfFreedomSequence(0x0068, 0x6400); Tag const DegreeOfFreedomID(0x0068, 0x6410); Tag const DegreeOfFreedomType(0x0068, 0x6420); Tag const TwoDMatingFeatureCoordinatesSequence(0x0068, 0x6430); Tag const ReferencedHPGLDocumentID(0x0068, 0x6440); Tag const TwoDMatingPoint(0x0068, 0x6450); Tag const TwoDMatingAxes(0x0068, 0x6460); Tag const TwoDDegreeOfFreedomSequence(0x0068, 0x6470); Tag const ThreeDDegreeOfFreedomAxis(0x0068, 0x6490); Tag const RangeOfFreedom(0x0068, 0x64a0); Tag const ThreeDMatingPoint(0x0068, 0x64c0); Tag const ThreeDMatingAxes(0x0068, 0x64d0); Tag const TwoDDegreeOfFreedomAxis(0x0068, 0x64f0); Tag const PlanningLandmarkPointSequence(0x0068, 0x6500); Tag const PlanningLandmarkLineSequence(0x0068, 0x6510); Tag const PlanningLandmarkPlaneSequence(0x0068, 0x6520); Tag const PlanningLandmarkID(0x0068, 0x6530); Tag const PlanningLandmarkDescription(0x0068, 0x6540); Tag const PlanningLandmarkIdentificationCodeSequence(0x0068, 0x6545); Tag const TwoDPointCoordinatesSequence(0x0068, 0x6550); Tag const TwoDPointCoordinates(0x0068, 0x6560); Tag const ThreeDPointCoordinates(0x0068, 0x6590); Tag const TwoDLineCoordinatesSequence(0x0068, 0x65a0); Tag const TwoDLineCoordinates(0x0068, 0x65b0); Tag const ThreeDLineCoordinates(0x0068, 0x65d0); Tag const TwoDPlaneCoordinatesSequence(0x0068, 0x65e0); Tag const TwoDPlaneIntersection(0x0068, 0x65f0); Tag const ThreeDPlaneOrigin(0x0068, 0x6610); Tag const ThreeDPlaneNormal(0x0068, 0x6620); Tag const GraphicAnnotationSequence(0x0070, 0x0001); Tag const GraphicLayer(0x0070, 0x0002); Tag const BoundingBoxAnnotationUnits(0x0070, 0x0003); Tag const AnchorPointAnnotationUnits(0x0070, 0x0004); Tag const GraphicAnnotationUnits(0x0070, 0x0005); Tag const UnformattedTextValue(0x0070, 0x0006); Tag const TextObjectSequence(0x0070, 0x0008); Tag const GraphicObjectSequence(0x0070, 0x0009); Tag const BoundingBoxTopLeftHandCorner(0x0070, 0x0010); Tag const BoundingBoxBottomRightHandCorner(0x0070, 0x0011); Tag const BoundingBoxTextHorizontalJustification(0x0070, 0x0012); Tag const AnchorPoint(0x0070, 0x0014); Tag const AnchorPointVisibility(0x0070, 0x0015); Tag const GraphicDimensions(0x0070, 0x0020); Tag const NumberOfGraphicPoints(0x0070, 0x0021); Tag const GraphicData(0x0070, 0x0022); Tag const GraphicType(0x0070, 0x0023); Tag const GraphicFilled(0x0070, 0x0024); Tag const ImageRotationRetired(0x0070, 0x0040); Tag const ImageHorizontalFlip(0x0070, 0x0041); Tag const ImageRotation(0x0070, 0x0042); Tag const DisplayedAreaTopLeftHandCornerTrial(0x0070, 0x0050); Tag const DisplayedAreaBottomRightHandCornerTrial(0x0070, 0x0051); Tag const DisplayedAreaTopLeftHandCorner(0x0070, 0x0052); Tag const DisplayedAreaBottomRightHandCorner(0x0070, 0x0053); Tag const DisplayedAreaSelectionSequence(0x0070, 0x005a); Tag const GraphicLayerSequence(0x0070, 0x0060); Tag const GraphicLayerOrder(0x0070, 0x0062); Tag const GraphicLayerRecommendedDisplayGrayscaleValue(0x0070, 0x0066); Tag const GraphicLayerRecommendedDisplayRGBValue(0x0070, 0x0067); Tag const GraphicLayerDescription(0x0070, 0x0068); Tag const ContentLabel(0x0070, 0x0080); Tag const ContentDescription(0x0070, 0x0081); Tag const PresentationCreationDate(0x0070, 0x0082); Tag const PresentationCreationTime(0x0070, 0x0083); Tag const ContentCreatorName(0x0070, 0x0084); Tag const ContentCreatorIdentificationCodeSequence(0x0070, 0x0086); Tag const AlternateContentDescriptionSequence(0x0070, 0x0087); Tag const PresentationSizeMode(0x0070, 0x0100); Tag const PresentationPixelSpacing(0x0070, 0x0101); Tag const PresentationPixelAspectRatio(0x0070, 0x0102); Tag const PresentationPixelMagnificationRatio(0x0070, 0x0103); Tag const GraphicGroupLabel(0x0070, 0x0207); Tag const GraphicGroupDescription(0x0070, 0x0208); Tag const CompoundGraphicSequence(0x0070, 0x0209); Tag const CompoundGraphicInstanceID(0x0070, 0x0226); Tag const FontName(0x0070, 0x0227); Tag const FontNameType(0x0070, 0x0228); Tag const CSSFontName(0x0070, 0x0229); Tag const RotationAngle(0x0070, 0x0230); Tag const TextStyleSequence(0x0070, 0x0231); Tag const LineStyleSequence(0x0070, 0x0232); Tag const FillStyleSequence(0x0070, 0x0233); Tag const GraphicGroupSequence(0x0070, 0x0234); Tag const TextColorCIELabValue(0x0070, 0x0241); Tag const HorizontalAlignment(0x0070, 0x0242); Tag const VerticalAlignment(0x0070, 0x0243); Tag const ShadowStyle(0x0070, 0x0244); Tag const ShadowOffsetX(0x0070, 0x0245); Tag const ShadowOffsetY(0x0070, 0x0246); Tag const ShadowColorCIELabValue(0x0070, 0x0247); Tag const Underlined(0x0070, 0x0248); Tag const Bold(0x0070, 0x0249); Tag const Italic(0x0070, 0x0250); Tag const PatternOnColorCIELabValue(0x0070, 0x0251); Tag const PatternOffColorCIELabValue(0x0070, 0x0252); Tag const LineThickness(0x0070, 0x0253); Tag const LineDashingStyle(0x0070, 0x0254); Tag const LinePattern(0x0070, 0x0255); Tag const FillPattern(0x0070, 0x0256); Tag const FillMode(0x0070, 0x0257); Tag const ShadowOpacity(0x0070, 0x0258); Tag const GapLength(0x0070, 0x0261); Tag const DiameterOfVisibility(0x0070, 0x0262); Tag const RotationPoint(0x0070, 0x0273); Tag const TickAlignment(0x0070, 0x0274); Tag const ShowTickLabel(0x0070, 0x0278); Tag const TickLabelAlignment(0x0070, 0x0279); Tag const CompoundGraphicUnits(0x0070, 0x0282); Tag const PatternOnOpacity(0x0070, 0x0284); Tag const PatternOffOpacity(0x0070, 0x0285); Tag const MajorTicksSequence(0x0070, 0x0287); Tag const TickPosition(0x0070, 0x0288); Tag const TickLabel(0x0070, 0x0289); Tag const CompoundGraphicType(0x0070, 0x0294); Tag const GraphicGroupID(0x0070, 0x0295); Tag const ShapeType(0x0070, 0x0306); Tag const RegistrationSequence(0x0070, 0x0308); Tag const MatrixRegistrationSequence(0x0070, 0x0309); Tag const MatrixSequence(0x0070, 0x030a); Tag const FrameOfReferenceTransformationMatrixType(0x0070, 0x030c); Tag const RegistrationTypeCodeSequence(0x0070, 0x030d); Tag const FiducialDescription(0x0070, 0x030f); Tag const FiducialIdentifier(0x0070, 0x0310); Tag const FiducialIdentifierCodeSequence(0x0070, 0x0311); Tag const ContourUncertaintyRadius(0x0070, 0x0312); Tag const UsedFiducialsSequence(0x0070, 0x0314); Tag const GraphicCoordinatesDataSequence(0x0070, 0x0318); Tag const FiducialUID(0x0070, 0x031a); Tag const FiducialSetSequence(0x0070, 0x031c); Tag const FiducialSequence(0x0070, 0x031e); Tag const GraphicLayerRecommendedDisplayCIELabValue(0x0070, 0x0401); Tag const BlendingSequence(0x0070, 0x0402); Tag const RelativeOpacity(0x0070, 0x0403); Tag const ReferencedSpatialRegistrationSequence(0x0070, 0x0404); Tag const BlendingPosition(0x0070, 0x0405); Tag const HangingProtocolName(0x0072, 0x0002); Tag const HangingProtocolDescription(0x0072, 0x0004); Tag const HangingProtocolLevel(0x0072, 0x0006); Tag const HangingProtocolCreator(0x0072, 0x0008); Tag const HangingProtocolCreationDateTime(0x0072, 0x000a); Tag const HangingProtocolDefinitionSequence(0x0072, 0x000c); Tag const HangingProtocolUserIdentificationCodeSequence(0x0072, 0x000e); Tag const HangingProtocolUserGroupName(0x0072, 0x0010); Tag const SourceHangingProtocolSequence(0x0072, 0x0012); Tag const NumberOfPriorsReferenced(0x0072, 0x0014); Tag const ImageSetsSequence(0x0072, 0x0020); Tag const ImageSetSelectorSequence(0x0072, 0x0022); Tag const ImageSetSelectorUsageFlag(0x0072, 0x0024); Tag const SelectorAttribute(0x0072, 0x0026); Tag const SelectorValueNumber(0x0072, 0x0028); Tag const TimeBasedImageSetsSequence(0x0072, 0x0030); Tag const ImageSetNumber(0x0072, 0x0032); Tag const ImageSetSelectorCategory(0x0072, 0x0034); Tag const RelativeTime(0x0072, 0x0038); Tag const RelativeTimeUnits(0x0072, 0x003a); Tag const AbstractPriorValue(0x0072, 0x003c); Tag const AbstractPriorCodeSequence(0x0072, 0x003e); Tag const ImageSetLabel(0x0072, 0x0040); Tag const SelectorAttributeVR(0x0072, 0x0050); Tag const SelectorSequencePointer(0x0072, 0x0052); Tag const SelectorSequencePointerPrivateCreator(0x0072, 0x0054); Tag const SelectorAttributePrivateCreator(0x0072, 0x0056); Tag const SelectorATValue(0x0072, 0x0060); Tag const SelectorCSValue(0x0072, 0x0062); Tag const SelectorISValue(0x0072, 0x0064); Tag const SelectorLOValue(0x0072, 0x0066); Tag const SelectorLTValue(0x0072, 0x0068); Tag const SelectorPNValue(0x0072, 0x006a); Tag const SelectorSHValue(0x0072, 0x006c); Tag const SelectorSTValue(0x0072, 0x006e); Tag const SelectorUTValue(0x0072, 0x0070); Tag const SelectorDSValue(0x0072, 0x0072); Tag const SelectorFDValue(0x0072, 0x0074); Tag const SelectorFLValue(0x0072, 0x0076); Tag const SelectorULValue(0x0072, 0x0078); Tag const SelectorUSValue(0x0072, 0x007a); Tag const SelectorSLValue(0x0072, 0x007c); Tag const SelectorSSValue(0x0072, 0x007e); Tag const SelectorUIValue(0x0072, 0x007f); Tag const SelectorCodeSequenceValue(0x0072, 0x0080); Tag const NumberOfScreens(0x0072, 0x0100); Tag const NominalScreenDefinitionSequence(0x0072, 0x0102); Tag const NumberOfVerticalPixels(0x0072, 0x0104); Tag const NumberOfHorizontalPixels(0x0072, 0x0106); Tag const DisplayEnvironmentSpatialPosition(0x0072, 0x0108); Tag const ScreenMinimumGrayscaleBitDepth(0x0072, 0x010a); Tag const ScreenMinimumColorBitDepth(0x0072, 0x010c); Tag const ApplicationMaximumRepaintTime(0x0072, 0x010e); Tag const DisplaySetsSequence(0x0072, 0x0200); Tag const DisplaySetNumber(0x0072, 0x0202); Tag const DisplaySetLabel(0x0072, 0x0203); Tag const DisplaySetPresentationGroup(0x0072, 0x0204); Tag const DisplaySetPresentationGroupDescription(0x0072, 0x0206); Tag const PartialDataDisplayHandling(0x0072, 0x0208); Tag const SynchronizedScrollingSequence(0x0072, 0x0210); Tag const DisplaySetScrollingGroup(0x0072, 0x0212); Tag const NavigationIndicatorSequence(0x0072, 0x0214); Tag const NavigationDisplaySet(0x0072, 0x0216); Tag const ReferenceDisplaySets(0x0072, 0x0218); Tag const ImageBoxesSequence(0x0072, 0x0300); Tag const ImageBoxNumber(0x0072, 0x0302); Tag const ImageBoxLayoutType(0x0072, 0x0304); Tag const ImageBoxTileHorizontalDimension(0x0072, 0x0306); Tag const ImageBoxTileVerticalDimension(0x0072, 0x0308); Tag const ImageBoxScrollDirection(0x0072, 0x0310); Tag const ImageBoxSmallScrollType(0x0072, 0x0312); Tag const ImageBoxSmallScrollAmount(0x0072, 0x0314); Tag const ImageBoxLargeScrollType(0x0072, 0x0316); Tag const ImageBoxLargeScrollAmount(0x0072, 0x0318); Tag const ImageBoxOverlapPriority(0x0072, 0x0320); Tag const CineRelativeToRealTime(0x0072, 0x0330); Tag const FilterOperationsSequence(0x0072, 0x0400); Tag const FilterByCategory(0x0072, 0x0402); Tag const FilterByAttributePresence(0x0072, 0x0404); Tag const FilterByOperator(0x0072, 0x0406); Tag const StructuredDisplayBackgroundCIELabValue(0x0072, 0x0420); Tag const EmptyImageBoxCIELabValue(0x0072, 0x0421); Tag const StructuredDisplayImageBoxSequence(0x0072, 0x0422); Tag const StructuredDisplayTextBoxSequence(0x0072, 0x0424); Tag const ReferencedFirstFrameSequence(0x0072, 0x0427); Tag const ImageBoxSynchronizationSequence(0x0072, 0x0430); Tag const SynchronizedImageBoxList(0x0072, 0x0432); Tag const TypeOfSynchronization(0x0072, 0x0434); Tag const BlendingOperationType(0x0072, 0x0500); Tag const ReformattingOperationType(0x0072, 0x0510); Tag const ReformattingThickness(0x0072, 0x0512); Tag const ReformattingInterval(0x0072, 0x0514); Tag const ReformattingOperationInitialViewDirection(0x0072, 0x0516); Tag const ThreeDRenderingType(0x0072, 0x0520); Tag const SortingOperationsSequence(0x0072, 0x0600); Tag const SortByCategory(0x0072, 0x0602); Tag const SortingDirection(0x0072, 0x0604); Tag const DisplaySetPatientOrientation(0x0072, 0x0700); Tag const VOIType(0x0072, 0x0702); Tag const PseudoColorType(0x0072, 0x0704); Tag const PseudoColorPaletteInstanceReferenceSequence(0x0072, 0x0705); Tag const ShowGrayscaleInverted(0x0072, 0x0706); Tag const ShowImageTrueSizeFlag(0x0072, 0x0710); Tag const ShowGraphicAnnotationFlag(0x0072, 0x0712); Tag const ShowPatientDemographicsFlag(0x0072, 0x0714); Tag const ShowAcquisitionTechniquesFlag(0x0072, 0x0716); Tag const DisplaySetHorizontalJustification(0x0072, 0x0717); Tag const DisplaySetVerticalJustification(0x0072, 0x0718); Tag const ContinuationStartMeterset(0x0074, 0x0120); Tag const ContinuationEndMeterset(0x0074, 0x0121); Tag const ProcedureStepState(0x0074, 0x1000); Tag const ProcedureStepProgressInformationSequence(0x0074, 0x1002); Tag const ProcedureStepProgress(0x0074, 0x1004); Tag const ProcedureStepProgressDescription(0x0074, 0x1006); Tag const ProcedureStepCommunicationsURISequence(0x0074, 0x1008); Tag const ContactURI(0x0074, 0x100a); Tag const ContactDisplayName(0x0074, 0x100c); Tag const ProcedureStepDiscontinuationReasonCodeSequence(0x0074, 0x100e); Tag const BeamTaskSequence(0x0074, 0x1020); Tag const BeamTaskType(0x0074, 0x1022); Tag const BeamOrderIndexTrial(0x0074, 0x1024); Tag const AutosequenceFlag(0x0074, 0x1025); Tag const TableTopVerticalAdjustedPosition(0x0074, 0x1026); Tag const TableTopLongitudinalAdjustedPosition(0x0074, 0x1027); Tag const TableTopLateralAdjustedPosition(0x0074, 0x1028); Tag const PatientSupportAdjustedAngle(0x0074, 0x102a); Tag const TableTopEccentricAdjustedAngle(0x0074, 0x102b); Tag const TableTopPitchAdjustedAngle(0x0074, 0x102c); Tag const TableTopRollAdjustedAngle(0x0074, 0x102d); Tag const DeliveryVerificationImageSequence(0x0074, 0x1030); Tag const VerificationImageTiming(0x0074, 0x1032); Tag const DoubleExposureFlag(0x0074, 0x1034); Tag const DoubleExposureOrdering(0x0074, 0x1036); Tag const DoubleExposureMetersetTrial(0x0074, 0x1038); Tag const DoubleExposureFieldDeltaTrial(0x0074, 0x103a); Tag const RelatedReferenceRTImageSequence(0x0074, 0x1040); Tag const GeneralMachineVerificationSequence(0x0074, 0x1042); Tag const ConventionalMachineVerificationSequence(0x0074, 0x1044); Tag const IonMachineVerificationSequence(0x0074, 0x1046); Tag const FailedAttributesSequence(0x0074, 0x1048); Tag const OverriddenAttributesSequence(0x0074, 0x104a); Tag const ConventionalControlPointVerificationSequence(0x0074, 0x104c); Tag const IonControlPointVerificationSequence(0x0074, 0x104e); Tag const AttributeOccurrenceSequence(0x0074, 0x1050); Tag const AttributeOccurrencePointer(0x0074, 0x1052); Tag const AttributeItemSelector(0x0074, 0x1054); Tag const AttributeOccurrencePrivateCreator(0x0074, 0x1056); Tag const SelectorSequencePointerItems(0x0074, 0x1057); Tag const ScheduledProcedureStepPriority(0x0074, 0x1200); Tag const WorklistLabel(0x0074, 0x1202); Tag const ProcedureStepLabel(0x0074, 0x1204); Tag const ScheduledProcessingParametersSequence(0x0074, 0x1210); Tag const PerformedProcessingParametersSequence(0x0074, 0x1212); Tag const UnifiedProcedureStepPerformedProcedureSequence(0x0074, 0x1216); Tag const RelatedProcedureStepSequence(0x0074, 0x1220); Tag const ProcedureStepRelationshipType(0x0074, 0x1222); Tag const ReplacedProcedureStepSequence(0x0074, 0x1224); Tag const DeletionLock(0x0074, 0x1230); Tag const ReceivingAE(0x0074, 0x1234); Tag const RequestingAE(0x0074, 0x1236); Tag const ReasonForCancellation(0x0074, 0x1238); Tag const SCPStatus(0x0074, 0x1242); Tag const SubscriptionListStatus(0x0074, 0x1244); Tag const UnifiedProcedureStepListStatus(0x0074, 0x1246); Tag const BeamOrderIndex(0x0074, 0x1324); Tag const DoubleExposureMeterset(0x0074, 0x1338); Tag const DoubleExposureFieldDelta(0x0074, 0x133a); Tag const ImplantAssemblyTemplateName(0x0076, 0x0001); Tag const ImplantAssemblyTemplateIssuer(0x0076, 0x0003); Tag const ImplantAssemblyTemplateVersion(0x0076, 0x0006); Tag const ReplacedImplantAssemblyTemplateSequence(0x0076, 0x0008); Tag const ImplantAssemblyTemplateType(0x0076, 0x000a); Tag const OriginalImplantAssemblyTemplateSequence(0x0076, 0x000c); Tag const DerivationImplantAssemblyTemplateSequence(0x0076, 0x000e); Tag const ImplantAssemblyTemplateTargetAnatomySequence(0x0076, 0x0010); Tag const ProcedureTypeCodeSequence(0x0076, 0x0020); Tag const SurgicalTechnique(0x0076, 0x0030); Tag const ComponentTypesSequence(0x0076, 0x0032); Tag const ComponentTypeCodeSequence(0x0076, 0x0034); Tag const ExclusiveComponentType(0x0076, 0x0036); Tag const MandatoryComponentType(0x0076, 0x0038); Tag const ComponentSequence(0x0076, 0x0040); Tag const ComponentID(0x0076, 0x0055); Tag const ComponentAssemblySequence(0x0076, 0x0060); Tag const Component1ReferencedID(0x0076, 0x0070); Tag const Component1ReferencedMatingFeatureSetID(0x0076, 0x0080); Tag const Component1ReferencedMatingFeatureID(0x0076, 0x0090); Tag const Component2ReferencedID(0x0076, 0x00a0); Tag const Component2ReferencedMatingFeatureSetID(0x0076, 0x00b0); Tag const Component2ReferencedMatingFeatureID(0x0076, 0x00c0); Tag const ImplantTemplateGroupName(0x0078, 0x0001); Tag const ImplantTemplateGroupDescription(0x0078, 0x0010); Tag const ImplantTemplateGroupIssuer(0x0078, 0x0020); Tag const ImplantTemplateGroupVersion(0x0078, 0x0024); Tag const ReplacedImplantTemplateGroupSequence(0x0078, 0x0026); Tag const ImplantTemplateGroupTargetAnatomySequence(0x0078, 0x0028); Tag const ImplantTemplateGroupMembersSequence(0x0078, 0x002a); Tag const ImplantTemplateGroupMemberID(0x0078, 0x002e); Tag const ThreeDImplantTemplateGroupMemberMatchingPoint(0x0078, 0x0050); Tag const ThreeDImplantTemplateGroupMemberMatchingAxes(0x0078, 0x0060); Tag const ImplantTemplateGroupMemberMatching2DCoordinatesSequence(0x0078, 0x0070); Tag const TwoDImplantTemplateGroupMemberMatchingPoint(0x0078, 0x0090); Tag const TwoDImplantTemplateGroupMemberMatchingAxes(0x0078, 0x00a0); Tag const ImplantTemplateGroupVariationDimensionSequence(0x0078, 0x00b0); Tag const ImplantTemplateGroupVariationDimensionName(0x0078, 0x00b2); Tag const ImplantTemplateGroupVariationDimensionRankSequence(0x0078, 0x00b4); Tag const ReferencedImplantTemplateGroupMemberID(0x0078, 0x00b6); Tag const ImplantTemplateGroupVariationDimensionRank(0x0078, 0x00b8); Tag const SurfaceScanAcquisitionTypeCodeSequence(0x0080, 0x0001); Tag const SurfaceScanModeCodeSequence(0x0080, 0x0002); Tag const RegistrationMethodCodeSequence(0x0080, 0x0003); Tag const ShotDurationTime(0x0080, 0x0004); Tag const ShotOffsetTime(0x0080, 0x0005); Tag const SurfacePointPresentationValueData(0x0080, 0x0006); Tag const SurfacePointColorCIELabValueData(0x0080, 0x0007); Tag const UVMappingSequence(0x0080, 0x0008); Tag const TextureLabel(0x0080, 0x0009); Tag const UValueData(0x0080, 0x0010); Tag const VValueData(0x0080, 0x0011); Tag const ReferencedTextureSequence(0x0080, 0x0012); Tag const ReferencedSurfaceDataSequence(0x0080, 0x0013); Tag const StorageMediaFileSetID(0x0088, 0x0130); Tag const StorageMediaFileSetUID(0x0088, 0x0140); Tag const IconImageSequence(0x0088, 0x0200); Tag const TopicTitle(0x0088, 0x0904); Tag const TopicSubject(0x0088, 0x0906); Tag const TopicAuthor(0x0088, 0x0910); Tag const TopicKeywords(0x0088, 0x0912); Tag const SOPInstanceStatus(0x0100, 0x0410); Tag const SOPAuthorizationDateTime(0x0100, 0x0420); Tag const SOPAuthorizationComment(0x0100, 0x0424); Tag const AuthorizationEquipmentCertificationNumber(0x0100, 0x0426); Tag const MACIDNumber(0x0400, 0x0005); Tag const MACCalculationTransferSyntaxUID(0x0400, 0x0010); Tag const MACAlgorithm(0x0400, 0x0015); Tag const DataElementsSigned(0x0400, 0x0020); Tag const DigitalSignatureUID(0x0400, 0x0100); Tag const DigitalSignatureDateTime(0x0400, 0x0105); Tag const CertificateType(0x0400, 0x0110); Tag const CertificateOfSigner(0x0400, 0x0115); Tag const Signature(0x0400, 0x0120); Tag const CertifiedTimestampType(0x0400, 0x0305); Tag const CertifiedTimestamp(0x0400, 0x0310); Tag const DigitalSignaturePurposeCodeSequence(0x0400, 0x0401); Tag const ReferencedDigitalSignatureSequence(0x0400, 0x0402); Tag const ReferencedSOPInstanceMACSequence(0x0400, 0x0403); Tag const MAC(0x0400, 0x0404); Tag const EncryptedAttributesSequence(0x0400, 0x0500); Tag const EncryptedContentTransferSyntaxUID(0x0400, 0x0510); Tag const EncryptedContent(0x0400, 0x0520); Tag const ModifiedAttributesSequence(0x0400, 0x0550); Tag const OriginalAttributesSequence(0x0400, 0x0561); Tag const AttributeModificationDateTime(0x0400, 0x0562); Tag const ModifyingSystem(0x0400, 0x0563); Tag const SourceOfPreviousValues(0x0400, 0x0564); Tag const ReasonForTheAttributeModification(0x0400, 0x0565); Tag const NumberOfCopies(0x2000, 0x0010); Tag const PrinterConfigurationSequence(0x2000, 0x001e); Tag const PrintPriority(0x2000, 0x0020); Tag const MediumType(0x2000, 0x0030); Tag const FilmDestination(0x2000, 0x0040); Tag const FilmSessionLabel(0x2000, 0x0050); Tag const MemoryAllocation(0x2000, 0x0060); Tag const MaximumMemoryAllocation(0x2000, 0x0061); Tag const ColorImagePrintingFlag(0x2000, 0x0062); Tag const CollationFlag(0x2000, 0x0063); Tag const AnnotationFlag(0x2000, 0x0065); Tag const ImageOverlayFlag(0x2000, 0x0067); Tag const PresentationLUTFlag(0x2000, 0x0069); Tag const ImageBoxPresentationLUTFlag(0x2000, 0x006a); Tag const MemoryBitDepth(0x2000, 0x00a0); Tag const PrintingBitDepth(0x2000, 0x00a1); Tag const MediaInstalledSequence(0x2000, 0x00a2); Tag const OtherMediaAvailableSequence(0x2000, 0x00a4); Tag const SupportedImageDisplayFormatsSequence(0x2000, 0x00a8); Tag const ReferencedFilmBoxSequence(0x2000, 0x0500); Tag const ReferencedStoredPrintSequence(0x2000, 0x0510); Tag const ImageDisplayFormat(0x2010, 0x0010); Tag const AnnotationDisplayFormatID(0x2010, 0x0030); Tag const FilmOrientation(0x2010, 0x0040); Tag const FilmSizeID(0x2010, 0x0050); Tag const PrinterResolutionID(0x2010, 0x0052); Tag const DefaultPrinterResolutionID(0x2010, 0x0054); Tag const MagnificationType(0x2010, 0x0060); Tag const SmoothingType(0x2010, 0x0080); Tag const DefaultMagnificationType(0x2010, 0x00a6); Tag const OtherMagnificationTypesAvailable(0x2010, 0x00a7); Tag const DefaultSmoothingType(0x2010, 0x00a8); Tag const OtherSmoothingTypesAvailable(0x2010, 0x00a9); Tag const BorderDensity(0x2010, 0x0100); Tag const EmptyImageDensity(0x2010, 0x0110); Tag const MinDensity(0x2010, 0x0120); Tag const MaxDensity(0x2010, 0x0130); Tag const Trim(0x2010, 0x0140); Tag const ConfigurationInformation(0x2010, 0x0150); Tag const ConfigurationInformationDescription(0x2010, 0x0152); Tag const MaximumCollatedFilms(0x2010, 0x0154); Tag const Illumination(0x2010, 0x015e); Tag const ReflectedAmbientLight(0x2010, 0x0160); Tag const PrinterPixelSpacing(0x2010, 0x0376); Tag const ReferencedFilmSessionSequence(0x2010, 0x0500); Tag const ReferencedImageBoxSequence(0x2010, 0x0510); Tag const ReferencedBasicAnnotationBoxSequence(0x2010, 0x0520); Tag const ImageBoxPosition(0x2020, 0x0010); Tag const Polarity(0x2020, 0x0020); Tag const RequestedImageSize(0x2020, 0x0030); Tag const RequestedDecimateCropBehavior(0x2020, 0x0040); Tag const RequestedResolutionID(0x2020, 0x0050); Tag const RequestedImageSizeFlag(0x2020, 0x00a0); Tag const DecimateCropResult(0x2020, 0x00a2); Tag const BasicGrayscaleImageSequence(0x2020, 0x0110); Tag const BasicColorImageSequence(0x2020, 0x0111); Tag const ReferencedImageOverlayBoxSequence(0x2020, 0x0130); Tag const ReferencedVOILUTBoxSequence(0x2020, 0x0140); Tag const AnnotationPosition(0x2030, 0x0010); Tag const TextString(0x2030, 0x0020); Tag const ReferencedOverlayPlaneSequence(0x2040, 0x0010); Tag const ReferencedOverlayPlaneGroups(0x2040, 0x0011); Tag const OverlayPixelDataSequence(0x2040, 0x0020); Tag const OverlayMagnificationType(0x2040, 0x0060); Tag const OverlaySmoothingType(0x2040, 0x0070); Tag const OverlayOrImageMagnification(0x2040, 0x0072); Tag const MagnifyToNumberOfColumns(0x2040, 0x0074); Tag const OverlayForegroundDensity(0x2040, 0x0080); Tag const OverlayBackgroundDensity(0x2040, 0x0082); Tag const OverlayMode(0x2040, 0x0090); Tag const ThresholdDensity(0x2040, 0x0100); Tag const ReferencedImageBoxSequenceRetired(0x2040, 0x0500); Tag const PresentationLUTSequence(0x2050, 0x0010); Tag const PresentationLUTShape(0x2050, 0x0020); Tag const ReferencedPresentationLUTSequence(0x2050, 0x0500); Tag const PrintJobID(0x2100, 0x0010); Tag const ExecutionStatus(0x2100, 0x0020); Tag const ExecutionStatusInfo(0x2100, 0x0030); Tag const CreationDate(0x2100, 0x0040); Tag const CreationTime(0x2100, 0x0050); Tag const Originator(0x2100, 0x0070); Tag const DestinationAE(0x2100, 0x0140); Tag const OwnerID(0x2100, 0x0160); Tag const NumberOfFilms(0x2100, 0x0170); Tag const ReferencedPrintJobSequencePullStoredPrint(0x2100, 0x0500); Tag const PrinterStatus(0x2110, 0x0010); Tag const PrinterStatusInfo(0x2110, 0x0020); Tag const PrinterName(0x2110, 0x0030); Tag const PrintQueueID(0x2110, 0x0099); Tag const QueueStatus(0x2120, 0x0010); Tag const PrintJobDescriptionSequence(0x2120, 0x0050); Tag const ReferencedPrintJobSequence(0x2120, 0x0070); Tag const PrintManagementCapabilitiesSequence(0x2130, 0x0010); Tag const PrinterCharacteristicsSequence(0x2130, 0x0015); Tag const FilmBoxContentSequence(0x2130, 0x0030); Tag const ImageBoxContentSequence(0x2130, 0x0040); Tag const AnnotationContentSequence(0x2130, 0x0050); Tag const ImageOverlayBoxContentSequence(0x2130, 0x0060); Tag const PresentationLUTContentSequence(0x2130, 0x0080); Tag const ProposedStudySequence(0x2130, 0x00a0); Tag const OriginalImageSequence(0x2130, 0x00c0); Tag const LabelUsingInformationExtractedFromInstances(0x2200, 0x0001); Tag const LabelText(0x2200, 0x0002); Tag const LabelStyleSelection(0x2200, 0x0003); Tag const MediaDisposition(0x2200, 0x0004); Tag const BarcodeValue(0x2200, 0x0005); Tag const BarcodeSymbology(0x2200, 0x0006); Tag const AllowMediaSplitting(0x2200, 0x0007); Tag const IncludeNonDICOMObjects(0x2200, 0x0008); Tag const IncludeDisplayApplication(0x2200, 0x0009); Tag const PreserveCompositeInstancesAfterMediaCreation(0x2200, 0x000a); Tag const TotalNumberOfPiecesOfMediaCreated(0x2200, 0x000b); Tag const RequestedMediaApplicationProfile(0x2200, 0x000c); Tag const ReferencedStorageMediaSequence(0x2200, 0x000d); Tag const FailureAttributes(0x2200, 0x000e); Tag const AllowLossyCompression(0x2200, 0x000f); Tag const RequestPriority(0x2200, 0x0020); Tag const RTImageLabel(0x3002, 0x0002); Tag const RTImageName(0x3002, 0x0003); Tag const RTImageDescription(0x3002, 0x0004); Tag const ReportedValuesOrigin(0x3002, 0x000a); Tag const RTImagePlane(0x3002, 0x000c); Tag const XRayImageReceptorTranslation(0x3002, 0x000d); Tag const XRayImageReceptorAngle(0x3002, 0x000e); Tag const RTImageOrientation(0x3002, 0x0010); Tag const ImagePlanePixelSpacing(0x3002, 0x0011); Tag const RTImagePosition(0x3002, 0x0012); Tag const RadiationMachineName(0x3002, 0x0020); Tag const RadiationMachineSAD(0x3002, 0x0022); Tag const RadiationMachineSSD(0x3002, 0x0024); Tag const RTImageSID(0x3002, 0x0026); Tag const SourceToReferenceObjectDistance(0x3002, 0x0028); Tag const FractionNumber(0x3002, 0x0029); Tag const ExposureSequence(0x3002, 0x0030); Tag const MetersetExposure(0x3002, 0x0032); Tag const DiaphragmPosition(0x3002, 0x0034); Tag const FluenceMapSequence(0x3002, 0x0040); Tag const FluenceDataSource(0x3002, 0x0041); Tag const FluenceDataScale(0x3002, 0x0042); Tag const PrimaryFluenceModeSequence(0x3002, 0x0050); Tag const FluenceMode(0x3002, 0x0051); Tag const FluenceModeID(0x3002, 0x0052); Tag const DVHType(0x3004, 0x0001); Tag const DoseUnits(0x3004, 0x0002); Tag const DoseType(0x3004, 0x0004); Tag const SpatialTransformOfDose(0x3004, 0x0005); Tag const DoseComment(0x3004, 0x0006); Tag const NormalizationPoint(0x3004, 0x0008); Tag const DoseSummationType(0x3004, 0x000a); Tag const GridFrameOffsetVector(0x3004, 0x000c); Tag const DoseGridScaling(0x3004, 0x000e); Tag const RTDoseROISequence(0x3004, 0x0010); Tag const DoseValue(0x3004, 0x0012); Tag const TissueHeterogeneityCorrection(0x3004, 0x0014); Tag const DVHNormalizationPoint(0x3004, 0x0040); Tag const DVHNormalizationDoseValue(0x3004, 0x0042); Tag const DVHSequence(0x3004, 0x0050); Tag const DVHDoseScaling(0x3004, 0x0052); Tag const DVHVolumeUnits(0x3004, 0x0054); Tag const DVHNumberOfBins(0x3004, 0x0056); Tag const DVHData(0x3004, 0x0058); Tag const DVHReferencedROISequence(0x3004, 0x0060); Tag const DVHROIContributionType(0x3004, 0x0062); Tag const DVHMinimumDose(0x3004, 0x0070); Tag const DVHMaximumDose(0x3004, 0x0072); Tag const DVHMeanDose(0x3004, 0x0074); Tag const StructureSetLabel(0x3006, 0x0002); Tag const StructureSetName(0x3006, 0x0004); Tag const StructureSetDescription(0x3006, 0x0006); Tag const StructureSetDate(0x3006, 0x0008); Tag const StructureSetTime(0x3006, 0x0009); Tag const ReferencedFrameOfReferenceSequence(0x3006, 0x0010); Tag const RTReferencedStudySequence(0x3006, 0x0012); Tag const RTReferencedSeriesSequence(0x3006, 0x0014); Tag const ContourImageSequence(0x3006, 0x0016); Tag const PredecessorStructureSetSequence(0x3006, 0x0018); Tag const StructureSetROISequence(0x3006, 0x0020); Tag const ROINumber(0x3006, 0x0022); Tag const ReferencedFrameOfReferenceUID(0x3006, 0x0024); Tag const ROIName(0x3006, 0x0026); Tag const ROIDescription(0x3006, 0x0028); Tag const ROIDisplayColor(0x3006, 0x002a); Tag const ROIVolume(0x3006, 0x002c); Tag const RTRelatedROISequence(0x3006, 0x0030); Tag const RTROIRelationship(0x3006, 0x0033); Tag const ROIGenerationAlgorithm(0x3006, 0x0036); Tag const ROIGenerationDescription(0x3006, 0x0038); Tag const ROIContourSequence(0x3006, 0x0039); Tag const ContourSequence(0x3006, 0x0040); Tag const ContourGeometricType(0x3006, 0x0042); Tag const ContourSlabThickness(0x3006, 0x0044); Tag const ContourOffsetVector(0x3006, 0x0045); Tag const NumberOfContourPoints(0x3006, 0x0046); Tag const ContourNumber(0x3006, 0x0048); Tag const AttachedContours(0x3006, 0x0049); Tag const ContourData(0x3006, 0x0050); Tag const RTROIObservationsSequence(0x3006, 0x0080); Tag const ObservationNumber(0x3006, 0x0082); Tag const ReferencedROINumber(0x3006, 0x0084); Tag const ROIObservationLabel(0x3006, 0x0085); Tag const RTROIIdentificationCodeSequence(0x3006, 0x0086); Tag const ROIObservationDescription(0x3006, 0x0088); Tag const RelatedRTROIObservationsSequence(0x3006, 0x00a0); Tag const RTROIInterpretedType(0x3006, 0x00a4); Tag const ROIInterpreter(0x3006, 0x00a6); Tag const ROIPhysicalPropertiesSequence(0x3006, 0x00b0); Tag const ROIPhysicalProperty(0x3006, 0x00b2); Tag const ROIPhysicalPropertyValue(0x3006, 0x00b4); Tag const ROIElementalCompositionSequence(0x3006, 0x00b6); Tag const ROIElementalCompositionAtomicNumber(0x3006, 0x00b7); Tag const ROIElementalCompositionAtomicMassFraction(0x3006, 0x00b8); Tag const AdditionalRTROIIdentificationCodeSequence(0x3006, 0x00b9); Tag const FrameOfReferenceRelationshipSequence(0x3006, 0x00c0); Tag const RelatedFrameOfReferenceUID(0x3006, 0x00c2); Tag const FrameOfReferenceTransformationType(0x3006, 0x00c4); Tag const FrameOfReferenceTransformationMatrix(0x3006, 0x00c6); Tag const FrameOfReferenceTransformationComment(0x3006, 0x00c8); Tag const MeasuredDoseReferenceSequence(0x3008, 0x0010); Tag const MeasuredDoseDescription(0x3008, 0x0012); Tag const MeasuredDoseType(0x3008, 0x0014); Tag const MeasuredDoseValue(0x3008, 0x0016); Tag const TreatmentSessionBeamSequence(0x3008, 0x0020); Tag const TreatmentSessionIonBeamSequence(0x3008, 0x0021); Tag const CurrentFractionNumber(0x3008, 0x0022); Tag const TreatmentControlPointDate(0x3008, 0x0024); Tag const TreatmentControlPointTime(0x3008, 0x0025); Tag const TreatmentTerminationStatus(0x3008, 0x002a); Tag const TreatmentTerminationCode(0x3008, 0x002b); Tag const TreatmentVerificationStatus(0x3008, 0x002c); Tag const ReferencedTreatmentRecordSequence(0x3008, 0x0030); Tag const SpecifiedPrimaryMeterset(0x3008, 0x0032); Tag const SpecifiedSecondaryMeterset(0x3008, 0x0033); Tag const DeliveredPrimaryMeterset(0x3008, 0x0036); Tag const DeliveredSecondaryMeterset(0x3008, 0x0037); Tag const SpecifiedTreatmentTime(0x3008, 0x003a); Tag const DeliveredTreatmentTime(0x3008, 0x003b); Tag const ControlPointDeliverySequence(0x3008, 0x0040); Tag const IonControlPointDeliverySequence(0x3008, 0x0041); Tag const SpecifiedMeterset(0x3008, 0x0042); Tag const DeliveredMeterset(0x3008, 0x0044); Tag const MetersetRateSet(0x3008, 0x0045); Tag const MetersetRateDelivered(0x3008, 0x0046); Tag const ScanSpotMetersetsDelivered(0x3008, 0x0047); Tag const DoseRateDelivered(0x3008, 0x0048); Tag const TreatmentSummaryCalculatedDoseReferenceSequence(0x3008, 0x0050); Tag const CumulativeDoseToDoseReference(0x3008, 0x0052); Tag const FirstTreatmentDate(0x3008, 0x0054); Tag const MostRecentTreatmentDate(0x3008, 0x0056); Tag const NumberOfFractionsDelivered(0x3008, 0x005a); Tag const OverrideSequence(0x3008, 0x0060); Tag const ParameterSequencePointer(0x3008, 0x0061); Tag const OverrideParameterPointer(0x3008, 0x0062); Tag const ParameterItemIndex(0x3008, 0x0063); Tag const MeasuredDoseReferenceNumber(0x3008, 0x0064); Tag const ParameterPointer(0x3008, 0x0065); Tag const OverrideReason(0x3008, 0x0066); Tag const CorrectedParameterSequence(0x3008, 0x0068); Tag const CorrectionValue(0x3008, 0x006a); Tag const CalculatedDoseReferenceSequence(0x3008, 0x0070); Tag const CalculatedDoseReferenceNumber(0x3008, 0x0072); Tag const CalculatedDoseReferenceDescription(0x3008, 0x0074); Tag const CalculatedDoseReferenceDoseValue(0x3008, 0x0076); Tag const StartMeterset(0x3008, 0x0078); Tag const EndMeterset(0x3008, 0x007a); Tag const ReferencedMeasuredDoseReferenceSequence(0x3008, 0x0080); Tag const ReferencedMeasuredDoseReferenceNumber(0x3008, 0x0082); Tag const ReferencedCalculatedDoseReferenceSequence(0x3008, 0x0090); Tag const ReferencedCalculatedDoseReferenceNumber(0x3008, 0x0092); Tag const BeamLimitingDeviceLeafPairsSequence(0x3008, 0x00a0); Tag const RecordedWedgeSequence(0x3008, 0x00b0); Tag const RecordedCompensatorSequence(0x3008, 0x00c0); Tag const RecordedBlockSequence(0x3008, 0x00d0); Tag const TreatmentSummaryMeasuredDoseReferenceSequence(0x3008, 0x00e0); Tag const RecordedSnoutSequence(0x3008, 0x00f0); Tag const RecordedRangeShifterSequence(0x3008, 0x00f2); Tag const RecordedLateralSpreadingDeviceSequence(0x3008, 0x00f4); Tag const RecordedRangeModulatorSequence(0x3008, 0x00f6); Tag const RecordedSourceSequence(0x3008, 0x0100); Tag const SourceSerialNumber(0x3008, 0x0105); Tag const TreatmentSessionApplicationSetupSequence(0x3008, 0x0110); Tag const ApplicationSetupCheck(0x3008, 0x0116); Tag const RecordedBrachyAccessoryDeviceSequence(0x3008, 0x0120); Tag const ReferencedBrachyAccessoryDeviceNumber(0x3008, 0x0122); Tag const RecordedChannelSequence(0x3008, 0x0130); Tag const SpecifiedChannelTotalTime(0x3008, 0x0132); Tag const DeliveredChannelTotalTime(0x3008, 0x0134); Tag const SpecifiedNumberOfPulses(0x3008, 0x0136); Tag const DeliveredNumberOfPulses(0x3008, 0x0138); Tag const SpecifiedPulseRepetitionInterval(0x3008, 0x013a); Tag const DeliveredPulseRepetitionInterval(0x3008, 0x013c); Tag const RecordedSourceApplicatorSequence(0x3008, 0x0140); Tag const ReferencedSourceApplicatorNumber(0x3008, 0x0142); Tag const RecordedChannelShieldSequence(0x3008, 0x0150); Tag const ReferencedChannelShieldNumber(0x3008, 0x0152); Tag const BrachyControlPointDeliveredSequence(0x3008, 0x0160); Tag const SafePositionExitDate(0x3008, 0x0162); Tag const SafePositionExitTime(0x3008, 0x0164); Tag const SafePositionReturnDate(0x3008, 0x0166); Tag const SafePositionReturnTime(0x3008, 0x0168); Tag const PulseSpecificBrachyControlPointDeliveredSequence(0x3008, 0x0171); Tag const PulseNumber(0x3008, 0x0172); Tag const BrachyPulseControlPointDeliveredSequence(0x3008, 0x0173); Tag const CurrentTreatmentStatus(0x3008, 0x0200); Tag const TreatmentStatusComment(0x3008, 0x0202); Tag const FractionGroupSummarySequence(0x3008, 0x0220); Tag const ReferencedFractionNumber(0x3008, 0x0223); Tag const FractionGroupType(0x3008, 0x0224); Tag const BeamStopperPosition(0x3008, 0x0230); Tag const FractionStatusSummarySequence(0x3008, 0x0240); Tag const TreatmentDate(0x3008, 0x0250); Tag const TreatmentTime(0x3008, 0x0251); Tag const RTPlanLabel(0x300a, 0x0002); Tag const RTPlanName(0x300a, 0x0003); Tag const RTPlanDescription(0x300a, 0x0004); Tag const RTPlanDate(0x300a, 0x0006); Tag const RTPlanTime(0x300a, 0x0007); Tag const TreatmentProtocols(0x300a, 0x0009); Tag const PlanIntent(0x300a, 0x000a); Tag const TreatmentSites(0x300a, 0x000b); Tag const RTPlanGeometry(0x300a, 0x000c); Tag const PrescriptionDescription(0x300a, 0x000e); Tag const DoseReferenceSequence(0x300a, 0x0010); Tag const DoseReferenceNumber(0x300a, 0x0012); Tag const DoseReferenceUID(0x300a, 0x0013); Tag const DoseReferenceStructureType(0x300a, 0x0014); Tag const NominalBeamEnergyUnit(0x300a, 0x0015); Tag const DoseReferenceDescription(0x300a, 0x0016); Tag const DoseReferencePointCoordinates(0x300a, 0x0018); Tag const NominalPriorDose(0x300a, 0x001a); Tag const DoseReferenceType(0x300a, 0x0020); Tag const ConstraintWeight(0x300a, 0x0021); Tag const DeliveryWarningDose(0x300a, 0x0022); Tag const DeliveryMaximumDose(0x300a, 0x0023); Tag const TargetMinimumDose(0x300a, 0x0025); Tag const TargetPrescriptionDose(0x300a, 0x0026); Tag const TargetMaximumDose(0x300a, 0x0027); Tag const TargetUnderdoseVolumeFraction(0x300a, 0x0028); Tag const OrganAtRiskFullVolumeDose(0x300a, 0x002a); Tag const OrganAtRiskLimitDose(0x300a, 0x002b); Tag const OrganAtRiskMaximumDose(0x300a, 0x002c); Tag const OrganAtRiskOverdoseVolumeFraction(0x300a, 0x002d); Tag const ToleranceTableSequence(0x300a, 0x0040); Tag const ToleranceTableNumber(0x300a, 0x0042); Tag const ToleranceTableLabel(0x300a, 0x0043); Tag const GantryAngleTolerance(0x300a, 0x0044); Tag const BeamLimitingDeviceAngleTolerance(0x300a, 0x0046); Tag const BeamLimitingDeviceToleranceSequence(0x300a, 0x0048); Tag const BeamLimitingDevicePositionTolerance(0x300a, 0x004a); Tag const SnoutPositionTolerance(0x300a, 0x004b); Tag const PatientSupportAngleTolerance(0x300a, 0x004c); Tag const TableTopEccentricAngleTolerance(0x300a, 0x004e); Tag const TableTopPitchAngleTolerance(0x300a, 0x004f); Tag const TableTopRollAngleTolerance(0x300a, 0x0050); Tag const TableTopVerticalPositionTolerance(0x300a, 0x0051); Tag const TableTopLongitudinalPositionTolerance(0x300a, 0x0052); Tag const TableTopLateralPositionTolerance(0x300a, 0x0053); Tag const RTPlanRelationship(0x300a, 0x0055); Tag const FractionGroupSequence(0x300a, 0x0070); Tag const FractionGroupNumber(0x300a, 0x0071); Tag const FractionGroupDescription(0x300a, 0x0072); Tag const NumberOfFractionsPlanned(0x300a, 0x0078); Tag const NumberOfFractionPatternDigitsPerDay(0x300a, 0x0079); Tag const RepeatFractionCycleLength(0x300a, 0x007a); Tag const FractionPattern(0x300a, 0x007b); Tag const NumberOfBeams(0x300a, 0x0080); Tag const BeamDoseSpecificationPoint(0x300a, 0x0082); Tag const BeamDose(0x300a, 0x0084); Tag const BeamMeterset(0x300a, 0x0086); Tag const BeamDosePointDepth(0x300a, 0x0088); Tag const BeamDosePointEquivalentDepth(0x300a, 0x0089); Tag const BeamDosePointSSD(0x300a, 0x008a); Tag const BeamDoseMeaning(0x300a, 0x008b); Tag const BeamDoseVerificationControlPointSequence(0x300a, 0x008c); Tag const AverageBeamDosePointDepth(0x300a, 0x008d); Tag const AverageBeamDosePointEquivalentDepth(0x300a, 0x008e); Tag const AverageBeamDosePointSSD(0x300a, 0x008f); Tag const NumberOfBrachyApplicationSetups(0x300a, 0x00a0); Tag const BrachyApplicationSetupDoseSpecificationPoint(0x300a, 0x00a2); Tag const BrachyApplicationSetupDose(0x300a, 0x00a4); Tag const BeamSequence(0x300a, 0x00b0); Tag const TreatmentMachineName(0x300a, 0x00b2); Tag const PrimaryDosimeterUnit(0x300a, 0x00b3); Tag const SourceAxisDistance(0x300a, 0x00b4); Tag const BeamLimitingDeviceSequence(0x300a, 0x00b6); Tag const RTBeamLimitingDeviceType(0x300a, 0x00b8); Tag const SourceToBeamLimitingDeviceDistance(0x300a, 0x00ba); Tag const IsocenterToBeamLimitingDeviceDistance(0x300a, 0x00bb); Tag const NumberOfLeafJawPairs(0x300a, 0x00bc); Tag const LeafPositionBoundaries(0x300a, 0x00be); Tag const BeamNumber(0x300a, 0x00c0); Tag const BeamName(0x300a, 0x00c2); Tag const BeamDescription(0x300a, 0x00c3); Tag const BeamType(0x300a, 0x00c4); Tag const BeamDeliveryDurationLimit(0x300a, 0x00c5); Tag const RadiationType(0x300a, 0x00c6); Tag const HighDoseTechniqueType(0x300a, 0x00c7); Tag const ReferenceImageNumber(0x300a, 0x00c8); Tag const PlannedVerificationImageSequence(0x300a, 0x00ca); Tag const ImagingDeviceSpecificAcquisitionParameters(0x300a, 0x00cc); Tag const TreatmentDeliveryType(0x300a, 0x00ce); Tag const NumberOfWedges(0x300a, 0x00d0); Tag const WedgeSequence(0x300a, 0x00d1); Tag const WedgeNumber(0x300a, 0x00d2); Tag const WedgeType(0x300a, 0x00d3); Tag const WedgeID(0x300a, 0x00d4); Tag const WedgeAngle(0x300a, 0x00d5); Tag const WedgeFactor(0x300a, 0x00d6); Tag const TotalWedgeTrayWaterEquivalentThickness(0x300a, 0x00d7); Tag const WedgeOrientation(0x300a, 0x00d8); Tag const IsocenterToWedgeTrayDistance(0x300a, 0x00d9); Tag const SourceToWedgeTrayDistance(0x300a, 0x00da); Tag const WedgeThinEdgePosition(0x300a, 0x00db); Tag const BolusID(0x300a, 0x00dc); Tag const BolusDescription(0x300a, 0x00dd); Tag const EffectiveWedgeAngle(0x300a, 0x00de); Tag const NumberOfCompensators(0x300a, 0x00e0); Tag const MaterialID(0x300a, 0x00e1); Tag const TotalCompensatorTrayFactor(0x300a, 0x00e2); Tag const CompensatorSequence(0x300a, 0x00e3); Tag const CompensatorNumber(0x300a, 0x00e4); Tag const CompensatorID(0x300a, 0x00e5); Tag const SourceToCompensatorTrayDistance(0x300a, 0x00e6); Tag const CompensatorRows(0x300a, 0x00e7); Tag const CompensatorColumns(0x300a, 0x00e8); Tag const CompensatorPixelSpacing(0x300a, 0x00e9); Tag const CompensatorPosition(0x300a, 0x00ea); Tag const CompensatorTransmissionData(0x300a, 0x00eb); Tag const CompensatorThicknessData(0x300a, 0x00ec); Tag const NumberOfBoli(0x300a, 0x00ed); Tag const CompensatorType(0x300a, 0x00ee); Tag const CompensatorTrayID(0x300a, 0x00ef); Tag const NumberOfBlocks(0x300a, 0x00f0); Tag const TotalBlockTrayFactor(0x300a, 0x00f2); Tag const TotalBlockTrayWaterEquivalentThickness(0x300a, 0x00f3); Tag const BlockSequence(0x300a, 0x00f4); Tag const BlockTrayID(0x300a, 0x00f5); Tag const SourceToBlockTrayDistance(0x300a, 0x00f6); Tag const IsocenterToBlockTrayDistance(0x300a, 0x00f7); Tag const BlockType(0x300a, 0x00f8); Tag const AccessoryCode(0x300a, 0x00f9); Tag const BlockDivergence(0x300a, 0x00fa); Tag const BlockMountingPosition(0x300a, 0x00fb); Tag const BlockNumber(0x300a, 0x00fc); Tag const BlockName(0x300a, 0x00fe); Tag const BlockThickness(0x300a, 0x0100); Tag const BlockTransmission(0x300a, 0x0102); Tag const BlockNumberOfPoints(0x300a, 0x0104); Tag const BlockData(0x300a, 0x0106); Tag const ApplicatorSequence(0x300a, 0x0107); Tag const ApplicatorID(0x300a, 0x0108); Tag const ApplicatorType(0x300a, 0x0109); Tag const ApplicatorDescription(0x300a, 0x010a); Tag const CumulativeDoseReferenceCoefficient(0x300a, 0x010c); Tag const FinalCumulativeMetersetWeight(0x300a, 0x010e); Tag const NumberOfControlPoints(0x300a, 0x0110); Tag const ControlPointSequence(0x300a, 0x0111); Tag const ControlPointIndex(0x300a, 0x0112); Tag const NominalBeamEnergy(0x300a, 0x0114); Tag const DoseRateSet(0x300a, 0x0115); Tag const WedgePositionSequence(0x300a, 0x0116); Tag const WedgePosition(0x300a, 0x0118); Tag const BeamLimitingDevicePositionSequence(0x300a, 0x011a); Tag const LeafJawPositions(0x300a, 0x011c); Tag const GantryAngle(0x300a, 0x011e); Tag const GantryRotationDirection(0x300a, 0x011f); Tag const BeamLimitingDeviceAngle(0x300a, 0x0120); Tag const BeamLimitingDeviceRotationDirection(0x300a, 0x0121); Tag const PatientSupportAngle(0x300a, 0x0122); Tag const PatientSupportRotationDirection(0x300a, 0x0123); Tag const TableTopEccentricAxisDistance(0x300a, 0x0124); Tag const TableTopEccentricAngle(0x300a, 0x0125); Tag const TableTopEccentricRotationDirection(0x300a, 0x0126); Tag const TableTopVerticalPosition(0x300a, 0x0128); Tag const TableTopLongitudinalPosition(0x300a, 0x0129); Tag const TableTopLateralPosition(0x300a, 0x012a); Tag const IsocenterPosition(0x300a, 0x012c); Tag const SurfaceEntryPoint(0x300a, 0x012e); Tag const SourceToSurfaceDistance(0x300a, 0x0130); Tag const AverageBeamDosePointSourceToExternalContourSurfaceDistance(0x300a, 0x0131); Tag const SourceToExternalContourDistance(0x300a, 0x0132); Tag const ExternalContourEntryPoint(0x300a, 0x0133); Tag const CumulativeMetersetWeight(0x300a, 0x0134); Tag const TableTopPitchAngle(0x300a, 0x0140); Tag const TableTopPitchRotationDirection(0x300a, 0x0142); Tag const TableTopRollAngle(0x300a, 0x0144); Tag const TableTopRollRotationDirection(0x300a, 0x0146); Tag const HeadFixationAngle(0x300a, 0x0148); Tag const GantryPitchAngle(0x300a, 0x014a); Tag const GantryPitchRotationDirection(0x300a, 0x014c); Tag const GantryPitchAngleTolerance(0x300a, 0x014e); Tag const PatientSetupSequence(0x300a, 0x0180); Tag const PatientSetupNumber(0x300a, 0x0182); Tag const PatientSetupLabel(0x300a, 0x0183); Tag const PatientAdditionalPosition(0x300a, 0x0184); Tag const FixationDeviceSequence(0x300a, 0x0190); Tag const FixationDeviceType(0x300a, 0x0192); Tag const FixationDeviceLabel(0x300a, 0x0194); Tag const FixationDeviceDescription(0x300a, 0x0196); Tag const FixationDevicePosition(0x300a, 0x0198); Tag const FixationDevicePitchAngle(0x300a, 0x0199); Tag const FixationDeviceRollAngle(0x300a, 0x019a); Tag const ShieldingDeviceSequence(0x300a, 0x01a0); Tag const ShieldingDeviceType(0x300a, 0x01a2); Tag const ShieldingDeviceLabel(0x300a, 0x01a4); Tag const ShieldingDeviceDescription(0x300a, 0x01a6); Tag const ShieldingDevicePosition(0x300a, 0x01a8); Tag const SetupTechnique(0x300a, 0x01b0); Tag const SetupTechniqueDescription(0x300a, 0x01b2); Tag const SetupDeviceSequence(0x300a, 0x01b4); Tag const SetupDeviceType(0x300a, 0x01b6); Tag const SetupDeviceLabel(0x300a, 0x01b8); Tag const SetupDeviceDescription(0x300a, 0x01ba); Tag const SetupDeviceParameter(0x300a, 0x01bc); Tag const SetupReferenceDescription(0x300a, 0x01d0); Tag const TableTopVerticalSetupDisplacement(0x300a, 0x01d2); Tag const TableTopLongitudinalSetupDisplacement(0x300a, 0x01d4); Tag const TableTopLateralSetupDisplacement(0x300a, 0x01d6); Tag const BrachyTreatmentTechnique(0x300a, 0x0200); Tag const BrachyTreatmentType(0x300a, 0x0202); Tag const TreatmentMachineSequence(0x300a, 0x0206); Tag const SourceSequence(0x300a, 0x0210); Tag const SourceNumber(0x300a, 0x0212); Tag const SourceType(0x300a, 0x0214); Tag const SourceManufacturer(0x300a, 0x0216); Tag const ActiveSourceDiameter(0x300a, 0x0218); Tag const ActiveSourceLength(0x300a, 0x021a); Tag const SourceModelID(0x300a, 0x021b); Tag const SourceDescription(0x300a, 0x021c); Tag const SourceEncapsulationNominalThickness(0x300a, 0x0222); Tag const SourceEncapsulationNominalTransmission(0x300a, 0x0224); Tag const SourceIsotopeName(0x300a, 0x0226); Tag const SourceIsotopeHalfLife(0x300a, 0x0228); Tag const SourceStrengthUnits(0x300a, 0x0229); Tag const ReferenceAirKermaRate(0x300a, 0x022a); Tag const SourceStrength(0x300a, 0x022b); Tag const SourceStrengthReferenceDate(0x300a, 0x022c); Tag const SourceStrengthReferenceTime(0x300a, 0x022e); Tag const ApplicationSetupSequence(0x300a, 0x0230); Tag const ApplicationSetupType(0x300a, 0x0232); Tag const ApplicationSetupNumber(0x300a, 0x0234); Tag const ApplicationSetupName(0x300a, 0x0236); Tag const ApplicationSetupManufacturer(0x300a, 0x0238); Tag const TemplateNumber(0x300a, 0x0240); Tag const TemplateType(0x300a, 0x0242); Tag const TemplateName(0x300a, 0x0244); Tag const TotalReferenceAirKerma(0x300a, 0x0250); Tag const BrachyAccessoryDeviceSequence(0x300a, 0x0260); Tag const BrachyAccessoryDeviceNumber(0x300a, 0x0262); Tag const BrachyAccessoryDeviceID(0x300a, 0x0263); Tag const BrachyAccessoryDeviceType(0x300a, 0x0264); Tag const BrachyAccessoryDeviceName(0x300a, 0x0266); Tag const BrachyAccessoryDeviceNominalThickness(0x300a, 0x026a); Tag const BrachyAccessoryDeviceNominalTransmission(0x300a, 0x026c); Tag const ChannelSequence(0x300a, 0x0280); Tag const ChannelNumber(0x300a, 0x0282); Tag const ChannelLength(0x300a, 0x0284); Tag const ChannelTotalTime(0x300a, 0x0286); Tag const SourceMovementType(0x300a, 0x0288); Tag const NumberOfPulses(0x300a, 0x028a); Tag const PulseRepetitionInterval(0x300a, 0x028c); Tag const SourceApplicatorNumber(0x300a, 0x0290); Tag const SourceApplicatorID(0x300a, 0x0291); Tag const SourceApplicatorType(0x300a, 0x0292); Tag const SourceApplicatorName(0x300a, 0x0294); Tag const SourceApplicatorLength(0x300a, 0x0296); Tag const SourceApplicatorManufacturer(0x300a, 0x0298); Tag const SourceApplicatorWallNominalThickness(0x300a, 0x029c); Tag const SourceApplicatorWallNominalTransmission(0x300a, 0x029e); Tag const SourceApplicatorStepSize(0x300a, 0x02a0); Tag const TransferTubeNumber(0x300a, 0x02a2); Tag const TransferTubeLength(0x300a, 0x02a4); Tag const ChannelShieldSequence(0x300a, 0x02b0); Tag const ChannelShieldNumber(0x300a, 0x02b2); Tag const ChannelShieldID(0x300a, 0x02b3); Tag const ChannelShieldName(0x300a, 0x02b4); Tag const ChannelShieldNominalThickness(0x300a, 0x02b8); Tag const ChannelShieldNominalTransmission(0x300a, 0x02ba); Tag const FinalCumulativeTimeWeight(0x300a, 0x02c8); Tag const BrachyControlPointSequence(0x300a, 0x02d0); Tag const ControlPointRelativePosition(0x300a, 0x02d2); Tag const ControlPoint3DPosition(0x300a, 0x02d4); Tag const CumulativeTimeWeight(0x300a, 0x02d6); Tag const CompensatorDivergence(0x300a, 0x02e0); Tag const CompensatorMountingPosition(0x300a, 0x02e1); Tag const SourceToCompensatorDistance(0x300a, 0x02e2); Tag const TotalCompensatorTrayWaterEquivalentThickness(0x300a, 0x02e3); Tag const IsocenterToCompensatorTrayDistance(0x300a, 0x02e4); Tag const CompensatorColumnOffset(0x300a, 0x02e5); Tag const IsocenterToCompensatorDistances(0x300a, 0x02e6); Tag const CompensatorRelativeStoppingPowerRatio(0x300a, 0x02e7); Tag const CompensatorMillingToolDiameter(0x300a, 0x02e8); Tag const IonRangeCompensatorSequence(0x300a, 0x02ea); Tag const CompensatorDescription(0x300a, 0x02eb); Tag const RadiationMassNumber(0x300a, 0x0302); Tag const RadiationAtomicNumber(0x300a, 0x0304); Tag const RadiationChargeState(0x300a, 0x0306); Tag const ScanMode(0x300a, 0x0308); Tag const VirtualSourceAxisDistances(0x300a, 0x030a); Tag const SnoutSequence(0x300a, 0x030c); Tag const SnoutPosition(0x300a, 0x030d); Tag const SnoutID(0x300a, 0x030f); Tag const NumberOfRangeShifters(0x300a, 0x0312); Tag const RangeShifterSequence(0x300a, 0x0314); Tag const RangeShifterNumber(0x300a, 0x0316); Tag const RangeShifterID(0x300a, 0x0318); Tag const RangeShifterType(0x300a, 0x0320); Tag const RangeShifterDescription(0x300a, 0x0322); Tag const NumberOfLateralSpreadingDevices(0x300a, 0x0330); Tag const LateralSpreadingDeviceSequence(0x300a, 0x0332); Tag const LateralSpreadingDeviceNumber(0x300a, 0x0334); Tag const LateralSpreadingDeviceID(0x300a, 0x0336); Tag const LateralSpreadingDeviceType(0x300a, 0x0338); Tag const LateralSpreadingDeviceDescription(0x300a, 0x033a); Tag const LateralSpreadingDeviceWaterEquivalentThickness(0x300a, 0x033c); Tag const NumberOfRangeModulators(0x300a, 0x0340); Tag const RangeModulatorSequence(0x300a, 0x0342); Tag const RangeModulatorNumber(0x300a, 0x0344); Tag const RangeModulatorID(0x300a, 0x0346); Tag const RangeModulatorType(0x300a, 0x0348); Tag const RangeModulatorDescription(0x300a, 0x034a); Tag const BeamCurrentModulationID(0x300a, 0x034c); Tag const PatientSupportType(0x300a, 0x0350); Tag const PatientSupportID(0x300a, 0x0352); Tag const PatientSupportAccessoryCode(0x300a, 0x0354); Tag const FixationLightAzimuthalAngle(0x300a, 0x0356); Tag const FixationLightPolarAngle(0x300a, 0x0358); Tag const MetersetRate(0x300a, 0x035a); Tag const RangeShifterSettingsSequence(0x300a, 0x0360); Tag const RangeShifterSetting(0x300a, 0x0362); Tag const IsocenterToRangeShifterDistance(0x300a, 0x0364); Tag const RangeShifterWaterEquivalentThickness(0x300a, 0x0366); Tag const LateralSpreadingDeviceSettingsSequence(0x300a, 0x0370); Tag const LateralSpreadingDeviceSetting(0x300a, 0x0372); Tag const IsocenterToLateralSpreadingDeviceDistance(0x300a, 0x0374); Tag const RangeModulatorSettingsSequence(0x300a, 0x0380); Tag const RangeModulatorGatingStartValue(0x300a, 0x0382); Tag const RangeModulatorGatingStopValue(0x300a, 0x0384); Tag const RangeModulatorGatingStartWaterEquivalentThickness(0x300a, 0x0386); Tag const RangeModulatorGatingStopWaterEquivalentThickness(0x300a, 0x0388); Tag const IsocenterToRangeModulatorDistance(0x300a, 0x038a); Tag const ScanSpotTuneID(0x300a, 0x0390); Tag const NumberOfScanSpotPositions(0x300a, 0x0392); Tag const ScanSpotPositionMap(0x300a, 0x0394); Tag const ScanSpotMetersetWeights(0x300a, 0x0396); Tag const ScanningSpotSize(0x300a, 0x0398); Tag const NumberOfPaintings(0x300a, 0x039a); Tag const IonToleranceTableSequence(0x300a, 0x03a0); Tag const IonBeamSequence(0x300a, 0x03a2); Tag const IonBeamLimitingDeviceSequence(0x300a, 0x03a4); Tag const IonBlockSequence(0x300a, 0x03a6); Tag const IonControlPointSequence(0x300a, 0x03a8); Tag const IonWedgeSequence(0x300a, 0x03aa); Tag const IonWedgePositionSequence(0x300a, 0x03ac); Tag const ReferencedSetupImageSequence(0x300a, 0x0401); Tag const SetupImageComment(0x300a, 0x0402); Tag const MotionSynchronizationSequence(0x300a, 0x0410); Tag const ControlPointOrientation(0x300a, 0x0412); Tag const GeneralAccessorySequence(0x300a, 0x0420); Tag const GeneralAccessoryID(0x300a, 0x0421); Tag const GeneralAccessoryDescription(0x300a, 0x0422); Tag const GeneralAccessoryType(0x300a, 0x0423); Tag const GeneralAccessoryNumber(0x300a, 0x0424); Tag const SourceToGeneralAccessoryDistance(0x300a, 0x0425); Tag const ApplicatorGeometrySequence(0x300a, 0x0431); Tag const ApplicatorApertureShape(0x300a, 0x0432); Tag const ApplicatorOpening(0x300a, 0x0433); Tag const ApplicatorOpeningX(0x300a, 0x0434); Tag const ApplicatorOpeningY(0x300a, 0x0435); Tag const SourceToApplicatorMountingPositionDistance(0x300a, 0x0436); Tag const NumberOfBlockSlabItems(0x300a, 0x0440); Tag const BlockSlabSequence(0x300a, 0x0441); Tag const BlockSlabThickness(0x300a, 0x0442); Tag const BlockSlabNumber(0x300a, 0x0443); Tag const DeviceMotionControlSequence(0x300a, 0x0450); Tag const DeviceMotionExecutionMode(0x300a, 0x0451); Tag const DeviceMotionObservationMode(0x300a, 0x0452); Tag const DeviceMotionParameterCodeSequence(0x300a, 0x0453); Tag const ReferencedRTPlanSequence(0x300c, 0x0002); Tag const ReferencedBeamSequence(0x300c, 0x0004); Tag const ReferencedBeamNumber(0x300c, 0x0006); Tag const ReferencedReferenceImageNumber(0x300c, 0x0007); Tag const StartCumulativeMetersetWeight(0x300c, 0x0008); Tag const EndCumulativeMetersetWeight(0x300c, 0x0009); Tag const ReferencedBrachyApplicationSetupSequence(0x300c, 0x000a); Tag const ReferencedBrachyApplicationSetupNumber(0x300c, 0x000c); Tag const ReferencedSourceNumber(0x300c, 0x000e); Tag const ReferencedFractionGroupSequence(0x300c, 0x0020); Tag const ReferencedFractionGroupNumber(0x300c, 0x0022); Tag const ReferencedVerificationImageSequence(0x300c, 0x0040); Tag const ReferencedReferenceImageSequence(0x300c, 0x0042); Tag const ReferencedDoseReferenceSequence(0x300c, 0x0050); Tag const ReferencedDoseReferenceNumber(0x300c, 0x0051); Tag const BrachyReferencedDoseReferenceSequence(0x300c, 0x0055); Tag const ReferencedStructureSetSequence(0x300c, 0x0060); Tag const ReferencedPatientSetupNumber(0x300c, 0x006a); Tag const ReferencedDoseSequence(0x300c, 0x0080); Tag const ReferencedToleranceTableNumber(0x300c, 0x00a0); Tag const ReferencedBolusSequence(0x300c, 0x00b0); Tag const ReferencedWedgeNumber(0x300c, 0x00c0); Tag const ReferencedCompensatorNumber(0x300c, 0x00d0); Tag const ReferencedBlockNumber(0x300c, 0x00e0); Tag const ReferencedControlPointIndex(0x300c, 0x00f0); Tag const ReferencedControlPointSequence(0x300c, 0x00f2); Tag const ReferencedStartControlPointIndex(0x300c, 0x00f4); Tag const ReferencedStopControlPointIndex(0x300c, 0x00f6); Tag const ReferencedRangeShifterNumber(0x300c, 0x0100); Tag const ReferencedLateralSpreadingDeviceNumber(0x300c, 0x0102); Tag const ReferencedRangeModulatorNumber(0x300c, 0x0104); Tag const OmittedBeamTaskSequence(0x300c, 0x0111); Tag const ReasonForOmission(0x300c, 0x0112); Tag const ReasonForOmissionDescription(0x300c, 0x0113); Tag const ApprovalStatus(0x300e, 0x0002); Tag const ReviewDate(0x300e, 0x0004); Tag const ReviewTime(0x300e, 0x0005); Tag const ReviewerName(0x300e, 0x0008); Tag const Arbitrary(0x4000, 0x0010); Tag const TextComments(0x4000, 0x4000); Tag const ResultsID(0x4008, 0x0040); Tag const ResultsIDIssuer(0x4008, 0x0042); Tag const ReferencedInterpretationSequence(0x4008, 0x0050); Tag const ReportProductionStatusTrial(0x4008, 0x00ff); Tag const InterpretationRecordedDate(0x4008, 0x0100); Tag const InterpretationRecordedTime(0x4008, 0x0101); Tag const InterpretationRecorder(0x4008, 0x0102); Tag const ReferenceToRecordedSound(0x4008, 0x0103); Tag const InterpretationTranscriptionDate(0x4008, 0x0108); Tag const InterpretationTranscriptionTime(0x4008, 0x0109); Tag const InterpretationTranscriber(0x4008, 0x010a); Tag const InterpretationText(0x4008, 0x010b); Tag const InterpretationAuthor(0x4008, 0x010c); Tag const InterpretationApproverSequence(0x4008, 0x0111); Tag const InterpretationApprovalDate(0x4008, 0x0112); Tag const InterpretationApprovalTime(0x4008, 0x0113); Tag const PhysicianApprovingInterpretation(0x4008, 0x0114); Tag const InterpretationDiagnosisDescription(0x4008, 0x0115); Tag const InterpretationDiagnosisCodeSequence(0x4008, 0x0117); Tag const ResultsDistributionListSequence(0x4008, 0x0118); Tag const DistributionName(0x4008, 0x0119); Tag const DistributionAddress(0x4008, 0x011a); Tag const InterpretationID(0x4008, 0x0200); Tag const InterpretationIDIssuer(0x4008, 0x0202); Tag const InterpretationTypeID(0x4008, 0x0210); Tag const InterpretationStatusID(0x4008, 0x0212); Tag const Impressions(0x4008, 0x0300); Tag const ResultsComments(0x4008, 0x4000); Tag const LowEnergyDetectors(0x4010, 0x0001); Tag const HighEnergyDetectors(0x4010, 0x0002); Tag const DetectorGeometrySequence(0x4010, 0x0004); Tag const ThreatROIVoxelSequence(0x4010, 0x1001); Tag const ThreatROIBase(0x4010, 0x1004); Tag const ThreatROIExtents(0x4010, 0x1005); Tag const ThreatROIBitmap(0x4010, 0x1006); Tag const RouteSegmentID(0x4010, 0x1007); Tag const GantryType(0x4010, 0x1008); Tag const OOIOwnerType(0x4010, 0x1009); Tag const RouteSegmentSequence(0x4010, 0x100a); Tag const PotentialThreatObjectID(0x4010, 0x1010); Tag const ThreatSequence(0x4010, 0x1011); Tag const ThreatCategory(0x4010, 0x1012); Tag const ThreatCategoryDescription(0x4010, 0x1013); Tag const ATDAbilityAssessment(0x4010, 0x1014); Tag const ATDAssessmentFlag(0x4010, 0x1015); Tag const ATDAssessmentProbability(0x4010, 0x1016); Tag const Mass(0x4010, 0x1017); Tag const Density(0x4010, 0x1018); Tag const ZEffective(0x4010, 0x1019); Tag const BoardingPassID(0x4010, 0x101a); Tag const CenterOfMass(0x4010, 0x101b); Tag const CenterOfPTO(0x4010, 0x101c); Tag const BoundingPolygon(0x4010, 0x101d); Tag const RouteSegmentStartLocationID(0x4010, 0x101e); Tag const RouteSegmentEndLocationID(0x4010, 0x101f); Tag const RouteSegmentLocationIDType(0x4010, 0x1020); Tag const AbortReason(0x4010, 0x1021); Tag const VolumeOfPTO(0x4010, 0x1023); Tag const AbortFlag(0x4010, 0x1024); Tag const RouteSegmentStartTime(0x4010, 0x1025); Tag const RouteSegmentEndTime(0x4010, 0x1026); Tag const TDRType(0x4010, 0x1027); Tag const InternationalRouteSegment(0x4010, 0x1028); Tag const ThreatDetectionAlgorithmandVersion(0x4010, 0x1029); Tag const AssignedLocation(0x4010, 0x102a); Tag const AlarmDecisionTime(0x4010, 0x102b); Tag const AlarmDecision(0x4010, 0x1031); Tag const NumberOfTotalObjects(0x4010, 0x1033); Tag const NumberOfAlarmObjects(0x4010, 0x1034); Tag const PTORepresentationSequence(0x4010, 0x1037); Tag const ATDAssessmentSequence(0x4010, 0x1038); Tag const TIPType(0x4010, 0x1039); Tag const DICOSVersion(0x4010, 0x103a); Tag const OOIOwnerCreationTime(0x4010, 0x1041); Tag const OOIType(0x4010, 0x1042); Tag const OOISize(0x4010, 0x1043); Tag const AcquisitionStatus(0x4010, 0x1044); Tag const BasisMaterialsCodeSequence(0x4010, 0x1045); Tag const PhantomType(0x4010, 0x1046); Tag const OOIOwnerSequence(0x4010, 0x1047); Tag const ScanType(0x4010, 0x1048); Tag const ItineraryID(0x4010, 0x1051); Tag const ItineraryIDType(0x4010, 0x1052); Tag const ItineraryIDAssigningAuthority(0x4010, 0x1053); Tag const RouteID(0x4010, 0x1054); Tag const RouteIDAssigningAuthority(0x4010, 0x1055); Tag const InboundArrivalType(0x4010, 0x1056); Tag const CarrierID(0x4010, 0x1058); Tag const CarrierIDAssigningAuthority(0x4010, 0x1059); Tag const SourceOrientation(0x4010, 0x1060); Tag const SourcePosition(0x4010, 0x1061); Tag const BeltHeight(0x4010, 0x1062); Tag const AlgorithmRoutingCodeSequence(0x4010, 0x1064); Tag const TransportClassification(0x4010, 0x1067); Tag const OOITypeDescriptor(0x4010, 0x1068); Tag const TotalProcessingTime(0x4010, 0x1069); Tag const DetectorCalibrationData(0x4010, 0x106c); Tag const AdditionalScreeningPerformed(0x4010, 0x106d); Tag const AdditionalInspectionSelectionCriteria(0x4010, 0x106e); Tag const AdditionalInspectionMethodSequence(0x4010, 0x106f); Tag const AITDeviceType(0x4010, 0x1070); Tag const QRMeasurementsSequence(0x4010, 0x1071); Tag const TargetMaterialSequence(0x4010, 0x1072); Tag const SNRThreshold(0x4010, 0x1073); Tag const ImageScaleRepresentation(0x4010, 0x1075); Tag const ReferencedPTOSequence(0x4010, 0x1076); Tag const ReferencedTDRInstanceSequence(0x4010, 0x1077); Tag const PTOLocationDescription(0x4010, 0x1078); Tag const AnomalyLocatorIndicatorSequence(0x4010, 0x1079); Tag const AnomalyLocatorIndicator(0x4010, 0x107a); Tag const PTORegionSequence(0x4010, 0x107b); Tag const InspectionSelectionCriteria(0x4010, 0x107c); Tag const SecondaryInspectionMethodSequence(0x4010, 0x107d); Tag const PRCSToRCSOrientation(0x4010, 0x107e); Tag const MACParametersSequence(0x4ffe, 0x0001); Tag const SharedFunctionalGroupsSequence(0x5200, 0x9229); Tag const PerFrameFunctionalGroupsSequence(0x5200, 0x9230); Tag const WaveformSequence(0x5400, 0x0100); Tag const ChannelMinimumValue(0x5400, 0x0110); Tag const ChannelMaximumValue(0x5400, 0x0112); Tag const WaveformBitsAllocated(0x5400, 0x1004); Tag const WaveformSampleInterpretation(0x5400, 0x1006); Tag const WaveformPaddingValue(0x5400, 0x100a); Tag const WaveformData(0x5400, 0x1010); Tag const FirstOrderPhaseCorrectionAngle(0x5600, 0x0010); Tag const SpectroscopyData(0x5600, 0x0020); Tag const FloatPixelData(0x7fe0, 0x0008); Tag const DoubleFloatPixelData(0x7fe0, 0x0009); Tag const PixelData(0x7fe0, 0x0010); Tag const CoefficientsSDVN(0x7fe0, 0x0020); Tag const CoefficientsSDHN(0x7fe0, 0x0030); Tag const CoefficientsSDDN(0x7fe0, 0x0040); Tag const DigitalSignaturesSequence(0xfffa, 0xfffa); Tag const DataSetTrailingPadding(0xfffc, 0xfffc); Tag const Item(0xfffe, 0xe000); Tag const ItemDelimitationItem(0xfffe, 0xe00d); Tag const SequenceDelimitationItem(0xfffe, 0xe0dd); std::string const VerificationSOPClass("1.2.840.10008.1.1"); std::string const ImplicitVRLittleEndian("1.2.840.10008.1.2"); std::string const ExplicitVRLittleEndian("1.2.840.10008.1.2.1"); std::string const DeflatedExplicitVRLittleEndian("1.2.840.10008.1.2.1.99"); std::string const ExplicitVRBigEndian_Retired("1.2.840.10008.1.2.2"); std::string const JPEGBaselineProcess1("1.2.840.10008.1.2.4.50"); std::string const JPEGExtendedProcess24("1.2.840.10008.1.2.4.51"); std::string const JPEGExtendedProcess35_Retired("1.2.840.10008.1.2.4.52"); std::string const JPEGSpectralSelectionNonHierarchicalProcess68_Retired("1.2.840.10008.1.2.4.53"); std::string const JPEGSpectralSelectionNonHierarchicalProcess79_Retired("1.2.840.10008.1.2.4.54"); std::string const JPEGFullProgressionNonHierarchicalProcess1012_Retired("1.2.840.10008.1.2.4.55"); std::string const JPEGFullProgressionNonHierarchicalProcess1113_Retired("1.2.840.10008.1.2.4.56"); std::string const JPEGLosslessNonHierarchicalProcess14("1.2.840.10008.1.2.4.57"); std::string const JPEGLosslessNonHierarchicalProcess15_Retired("1.2.840.10008.1.2.4.58"); std::string const JPEGExtendedHierarchicalProcess1618_Retired("1.2.840.10008.1.2.4.59"); std::string const JPEGExtendedHierarchicalProcess1719_Retired("1.2.840.10008.1.2.4.60"); std::string const JPEGSpectralSelectionHierarchicalProcess2022_Retired("1.2.840.10008.1.2.4.61"); std::string const JPEGSpectralSelectionHierarchicalProcess2123_Retired("1.2.840.10008.1.2.4.62"); std::string const JPEGFullProgressionHierarchicalProcess2426_Retired("1.2.840.10008.1.2.4.63"); std::string const JPEGFullProgressionHierarchicalProcess2527_Retired("1.2.840.10008.1.2.4.64"); std::string const JPEGLosslessHierarchicalProcess28_Retired("1.2.840.10008.1.2.4.65"); std::string const JPEGLosslessHierarchicalProcess29_Retired("1.2.840.10008.1.2.4.66"); std::string const JPEGLosslessNonHierarchicalFirstOrderPredictionProcess14SelectionValue1("1.2.840.10008.1.2.4.70"); std::string const JPEGLSLosslessImageCompression("1.2.840.10008.1.2.4.80"); std::string const JPEGLSLossyNearLosslessImageCompression("1.2.840.10008.1.2.4.81"); std::string const JPEG2000ImageCompressionLosslessOnly("1.2.840.10008.1.2.4.90"); std::string const JPEG2000ImageCompression("1.2.840.10008.1.2.4.91"); std::string const JPEG2000Part2MulticomponentImageCompressionLosslessOnly("1.2.840.10008.1.2.4.92"); std::string const JPEG2000Part2MulticomponentImageCompression("1.2.840.10008.1.2.4.93"); std::string const JPIPReferenced("1.2.840.10008.1.2.4.94"); std::string const JPIPReferencedDeflate("1.2.840.10008.1.2.4.95"); std::string const MPEG2MainProfileMainLevel("1.2.840.10008.1.2.4.100"); std::string const MPEG2MainProfileHighLevel("1.2.840.10008.1.2.4.101"); std::string const MPEG4AVCH264HighProfileLevel41("1.2.840.10008.1.2.4.102"); std::string const MPEG4AVCH264BDcompatibleHighProfileLevel41("1.2.840.10008.1.2.4.103"); std::string const MPEG4AVCH264HighProfileLevel42For2DVideo("1.2.840.10008.1.2.4.104"); std::string const MPEG4AVCH264HighProfileLevel42For3DVideo("1.2.840.10008.1.2.4.105"); std::string const MPEG4AVCH264StereoHighProfileLevel42("1.2.840.10008.1.2.4.106"); std::string const RLELossless("1.2.840.10008.1.2.5"); std::string const RFC2557MIMEencapsulation("1.2.840.10008.1.2.6.1"); std::string const XMLEncoding("1.2.840.10008.1.2.6.2"); std::string const MediaStorageDirectoryStorage("1.2.840.10008.1.3.10"); std::string const TalairachBrainAtlasFrameofReference("1.2.840.10008.1.4.1.1"); std::string const SPM2T1FrameofReference("1.2.840.10008.1.4.1.2"); std::string const SPM2T2FrameofReference("1.2.840.10008.1.4.1.3"); std::string const SPM2PDFrameofReference("1.2.840.10008.1.4.1.4"); std::string const SPM2EPIFrameofReference("1.2.840.10008.1.4.1.5"); std::string const SPM2FILT1FrameofReference("1.2.840.10008.1.4.1.6"); std::string const SPM2PETFrameofReference("1.2.840.10008.1.4.1.7"); std::string const SPM2TRANSMFrameofReference("1.2.840.10008.1.4.1.8"); std::string const SPM2SPECTFrameofReference("1.2.840.10008.1.4.1.9"); std::string const SPM2GRAYFrameofReference("1.2.840.10008.1.4.1.10"); std::string const SPM2WHITEFrameofReference("1.2.840.10008.1.4.1.11"); std::string const SPM2CSFFrameofReference("1.2.840.10008.1.4.1.12"); std::string const SPM2BRAINMASKFrameofReference("1.2.840.10008.1.4.1.13"); std::string const SPM2AVG305T1FrameofReference("1.2.840.10008.1.4.1.14"); std::string const SPM2AVG152T1FrameofReference("1.2.840.10008.1.4.1.15"); std::string const SPM2AVG152T2FrameofReference("1.2.840.10008.1.4.1.16"); std::string const SPM2AVG152PDFrameofReference("1.2.840.10008.1.4.1.17"); std::string const SPM2SINGLESUBJT1FrameofReference("1.2.840.10008.1.4.1.18"); std::string const ICBM452T1FrameofReference("1.2.840.10008.1.4.2.1"); std::string const ICBMSingleSubjectMRIFrameofReference("1.2.840.10008.1.4.2.2"); std::string const HotIronColorPaletteSOPInstance("1.2.840.10008.1.5.1"); std::string const PETColorPaletteSOPInstance("1.2.840.10008.1.5.2"); std::string const HotMetalBlueColorPaletteSOPInstance("1.2.840.10008.1.5.3"); std::string const PET20StepColorPaletteSOPInstance("1.2.840.10008.1.5.4"); std::string const BasicStudyContentNotificationSOPClass_Retired("1.2.840.10008.1.9"); std::string const StorageCommitmentPushModelSOPClass("1.2.840.10008.1.20.1"); std::string const StorageCommitmentPushModelSOPInstance("1.2.840.10008.1.20.1.1"); std::string const StorageCommitmentPullModelSOPClass_Retired("1.2.840.10008.1.20.2"); std::string const StorageCommitmentPullModelSOPInstance_Retired("1.2.840.10008.1.20.2.1"); std::string const ProceduralEventLoggingSOPClass("1.2.840.10008.1.40"); std::string const ProceduralEventLoggingSOPInstance("1.2.840.10008.1.40.1"); std::string const SubstanceAdministrationLoggingSOPClass("1.2.840.10008.1.42"); std::string const SubstanceAdministrationLoggingSOPInstance("1.2.840.10008.1.42.1"); std::string const DICOMUIDRegistry("1.2.840.10008.2.6.1"); std::string const DICOMControlledTerminology("1.2.840.10008.2.16.4"); std::string const DICOMApplicationContextName("1.2.840.10008.3.1.1.1"); std::string const DetachedPatientManagementSOPClass_Retired("1.2.840.10008.3.1.2.1.1"); std::string const DetachedPatientManagementMetaSOPClass_Retired("1.2.840.10008.3.1.2.1.4"); std::string const DetachedVisitManagementSOPClass_Retired("1.2.840.10008.3.1.2.2.1"); std::string const DetachedStudyManagementSOPClass_Retired("1.2.840.10008.3.1.2.3.1"); std::string const StudyComponentManagementSOPClass_Retired("1.2.840.10008.3.1.2.3.2"); std::string const ModalityPerformedProcedureStepSOPClass("1.2.840.10008.3.1.2.3.3"); std::string const ModalityPerformedProcedureStepRetrieveSOPClass("1.2.840.10008.3.1.2.3.4"); std::string const ModalityPerformedProcedureStepNotificationSOPClass("1.2.840.10008.3.1.2.3.5"); std::string const DetachedResultsManagementSOPClass_Retired("1.2.840.10008.3.1.2.5.1"); std::string const DetachedResultsManagementMetaSOPClass_Retired("1.2.840.10008.3.1.2.5.4"); std::string const DetachedStudyManagementMetaSOPClass_Retired("1.2.840.10008.3.1.2.5.5"); std::string const DetachedInterpretationManagementSOPClass_Retired("1.2.840.10008.3.1.2.6.1"); std::string const StorageServiceClass("1.2.840.10008.4.2"); std::string const BasicFilmSessionSOPClass("1.2.840.10008.5.1.1.1"); std::string const BasicFilmBoxSOPClass("1.2.840.10008.5.1.1.2"); std::string const BasicGrayscaleImageBoxSOPClass("1.2.840.10008.5.1.1.4"); std::string const BasicColorImageBoxSOPClass("1.2.840.10008.5.1.1.4.1"); std::string const ReferencedImageBoxSOPClass_Retired("1.2.840.10008.5.1.1.4.2"); std::string const BasicGrayscalePrintManagementMetaSOPClass("1.2.840.10008.5.1.1.9"); std::string const ReferencedGrayscalePrintManagementMetaSOPClass_Retired("1.2.840.10008.5.1.1.9.1"); std::string const PrintJobSOPClass("1.2.840.10008.5.1.1.14"); std::string const BasicAnnotationBoxSOPClass("1.2.840.10008.5.1.1.15"); std::string const PrinterSOPClass("1.2.840.10008.5.1.1.16"); std::string const PrinterConfigurationRetrievalSOPClass("1.2.840.10008.5.1.1.16.376"); std::string const PrinterSOPInstance("1.2.840.10008.5.1.1.17"); std::string const PrinterConfigurationRetrievalSOPInstance("1.2.840.10008.5.1.1.17.376"); std::string const BasicColorPrintManagementMetaSOPClass("1.2.840.10008.5.1.1.18"); std::string const ReferencedColorPrintManagementMetaSOPClass_Retired("1.2.840.10008.5.1.1.18.1"); std::string const VOILUTBoxSOPClass("1.2.840.10008.5.1.1.22"); std::string const PresentationLUTSOPClass("1.2.840.10008.5.1.1.23"); std::string const ImageOverlayBoxSOPClass_Retired("1.2.840.10008.5.1.1.24"); std::string const BasicPrintImageOverlayBoxSOPClass_Retired("1.2.840.10008.5.1.1.24.1"); std::string const PrintQueueSOPInstance_Retired("1.2.840.10008.5.1.1.25"); std::string const PrintQueueManagementSOPClass_Retired("1.2.840.10008.5.1.1.26"); std::string const StoredPrintStorageSOPClass_Retired("1.2.840.10008.5.1.1.27"); std::string const HardcopyGrayscaleImageStorageSOPClass_Retired("1.2.840.10008.5.1.1.29"); std::string const HardcopyColorImageStorageSOPClass_Retired("1.2.840.10008.5.1.1.30"); std::string const PullPrintRequestSOPClass_Retired("1.2.840.10008.5.1.1.31"); std::string const PullStoredPrintManagementMetaSOPClass_Retired("1.2.840.10008.5.1.1.32"); std::string const MediaCreationManagementSOPClassUID("1.2.840.10008.5.1.1.33"); std::string const DisplaySystemSOPClass("1.2.840.10008.5.1.1.40"); std::string const DisplaySystemSOPInstance("1.2.840.10008.5.1.1.40.1"); std::string const ComputedRadiographyImageStorage("1.2.840.10008.5.1.4.1.1.1"); std::string const DigitalXRayImageStorageForPresentation("1.2.840.10008.5.1.4.1.1.1.1"); std::string const DigitalXRayImageStorageForProcessing("1.2.840.10008.5.1.4.1.1.1.1.1"); std::string const DigitalMammographyXRayImageStorageForPresentation("1.2.840.10008.5.1.4.1.1.1.2"); std::string const DigitalMammographyXRayImageStorageForProcessing("1.2.840.10008.5.1.4.1.1.1.2.1"); std::string const DigitalIntraOralXRayImageStorageForPresentation("1.2.840.10008.5.1.4.1.1.1.3"); std::string const DigitalIntraOralXRayImageStorageForProcessing("1.2.840.10008.5.1.4.1.1.1.3.1"); std::string const CTImageStorage("1.2.840.10008.5.1.4.1.1.2"); std::string const EnhancedCTImageStorage("1.2.840.10008.5.1.4.1.1.2.1"); std::string const LegacyConvertedEnhancedCTImageStorage("1.2.840.10008.5.1.4.1.1.2.2"); std::string const UltrasoundMultiframeImageStorage_Retired("1.2.840.10008.5.1.4.1.1.3"); std::string const UltrasoundMultiframeImageStorage("1.2.840.10008.5.1.4.1.1.3.1"); std::string const MRImageStorage("1.2.840.10008.5.1.4.1.1.4"); std::string const EnhancedMRImageStorage("1.2.840.10008.5.1.4.1.1.4.1"); std::string const MRSpectroscopyStorage("1.2.840.10008.5.1.4.1.1.4.2"); std::string const EnhancedMRColorImageStorage("1.2.840.10008.5.1.4.1.1.4.3"); std::string const LegacyConvertedEnhancedMRImageStorage("1.2.840.10008.5.1.4.1.1.4.4"); std::string const NuclearMedicineImageStorage_Retired("1.2.840.10008.5.1.4.1.1.5"); std::string const UltrasoundImageStorage_Retired("1.2.840.10008.5.1.4.1.1.6"); std::string const UltrasoundImageStorage("1.2.840.10008.5.1.4.1.1.6.1"); std::string const EnhancedUSVolumeStorage("1.2.840.10008.5.1.4.1.1.6.2"); std::string const SecondaryCaptureImageStorage("1.2.840.10008.5.1.4.1.1.7"); std::string const MultiframeSingleBitSecondaryCaptureImageStorage("1.2.840.10008.5.1.4.1.1.7.1"); std::string const MultiframeGrayscaleByteSecondaryCaptureImageStorage("1.2.840.10008.5.1.4.1.1.7.2"); std::string const MultiframeGrayscaleWordSecondaryCaptureImageStorage("1.2.840.10008.5.1.4.1.1.7.3"); std::string const MultiframeTrueColorSecondaryCaptureImageStorage("1.2.840.10008.5.1.4.1.1.7.4"); std::string const StandaloneOverlayStorage_Retired("1.2.840.10008.5.1.4.1.1.8"); std::string const StandaloneCurveStorage_Retired("1.2.840.10008.5.1.4.1.1.9"); std::string const WaveformStorageTrial_Retired("1.2.840.10008.5.1.4.1.1.9.1"); std::string const TwelveleadECGWaveformStorage("1.2.840.10008.5.1.4.1.1.9.1.1"); std::string const GeneralECGWaveformStorage("1.2.840.10008.5.1.4.1.1.9.1.2"); std::string const AmbulatoryECGWaveformStorage("1.2.840.10008.5.1.4.1.1.9.1.3"); std::string const HemodynamicWaveformStorage("1.2.840.10008.5.1.4.1.1.9.2.1"); std::string const CardiacElectrophysiologyWaveformStorage("1.2.840.10008.5.1.4.1.1.9.3.1"); std::string const BasicVoiceAudioWaveformStorage("1.2.840.10008.5.1.4.1.1.9.4.1"); std::string const GeneralAudioWaveformStorage("1.2.840.10008.5.1.4.1.1.9.4.2"); std::string const ArterialPulseWaveformStorage("1.2.840.10008.5.1.4.1.1.9.5.1"); std::string const RespiratoryWaveformStorage("1.2.840.10008.5.1.4.1.1.9.6.1"); std::string const StandaloneModalityLUTStorage_Retired("1.2.840.10008.5.1.4.1.1.10"); std::string const StandaloneVOILUTStorage_Retired("1.2.840.10008.5.1.4.1.1.11"); std::string const GrayscaleSoftcopyPresentationStateStorageSOPClass("1.2.840.10008.5.1.4.1.1.11.1"); std::string const ColorSoftcopyPresentationStateStorageSOPClass("1.2.840.10008.5.1.4.1.1.11.2"); std::string const PseudoColorSoftcopyPresentationStateStorageSOPClass("1.2.840.10008.5.1.4.1.1.11.3"); std::string const BlendingSoftcopyPresentationStateStorageSOPClass("1.2.840.10008.5.1.4.1.1.11.4"); std::string const XAXRFGrayscaleSoftcopyPresentationStateStorage("1.2.840.10008.5.1.4.1.1.11.5"); std::string const XRayAngiographicImageStorage("1.2.840.10008.5.1.4.1.1.12.1"); std::string const EnhancedXAImageStorage("1.2.840.10008.5.1.4.1.1.12.1.1"); std::string const XRayRadiofluoroscopicImageStorage("1.2.840.10008.5.1.4.1.1.12.2"); std::string const EnhancedXRFImageStorage("1.2.840.10008.5.1.4.1.1.12.2.1"); std::string const XRayAngiographicBiPlaneImageStorage_Retired("1.2.840.10008.5.1.4.1.1.12.3"); std::string const XRay3DAngiographicImageStorage("1.2.840.10008.5.1.4.1.1.13.1.1"); std::string const XRay3DCraniofacialImageStorage("1.2.840.10008.5.1.4.1.1.13.1.2"); std::string const BreastTomosynthesisImageStorage("1.2.840.10008.5.1.4.1.1.13.1.3"); std::string const BreastProjectionXRayImageStorageForPresentation("1.2.840.10008.5.1.4.1.1.13.1.4"); std::string const BreastProjectionXRayImageStorageForProcessing("1.2.840.10008.5.1.4.1.1.13.1.5"); std::string const IntravascularOpticalCoherenceTomographyImageStorageForPresentation("1.2.840.10008.5.1.4.1.1.14.1"); std::string const IntravascularOpticalCoherenceTomographyImageStorageForProcessing("1.2.840.10008.5.1.4.1.1.14.2"); std::string const NuclearMedicineImageStorage("1.2.840.10008.5.1.4.1.1.20"); std::string const ParametricMapStorage("1.2.840.10008.5.1.4.1.1.30"); std::string const RawDataStorage("1.2.840.10008.5.1.4.1.1.66"); std::string const SpatialRegistrationStorage("1.2.840.10008.5.1.4.1.1.66.1"); std::string const SpatialFiducialsStorage("1.2.840.10008.5.1.4.1.1.66.2"); std::string const DeformableSpatialRegistrationStorage("1.2.840.10008.5.1.4.1.1.66.3"); std::string const SegmentationStorage("1.2.840.10008.5.1.4.1.1.66.4"); std::string const SurfaceSegmentationStorage("1.2.840.10008.5.1.4.1.1.66.5"); std::string const RealWorldValueMappingStorage("1.2.840.10008.5.1.4.1.1.67"); std::string const SurfaceScanMeshStorage("1.2.840.10008.5.1.4.1.1.68.1"); std::string const SurfaceScanPointCloudStorage("1.2.840.10008.5.1.4.1.1.68.2"); std::string const VLImageStorageTrial_Retired("1.2.840.10008.5.1.4.1.1.77.1"); std::string const VLMultiframeImageStorageTrial_Retired("1.2.840.10008.5.1.4.1.1.77.2"); std::string const VLEndoscopicImageStorage("1.2.840.10008.5.1.4.1.1.77.1.1"); std::string const VideoEndoscopicImageStorage("1.2.840.10008.5.1.4.1.1.77.1.1.1"); std::string const VLMicroscopicImageStorage("1.2.840.10008.5.1.4.1.1.77.1.2"); std::string const VideoMicroscopicImageStorage("1.2.840.10008.5.1.4.1.1.77.1.2.1"); std::string const VLSlideCoordinatesMicroscopicImageStorage("1.2.840.10008.5.1.4.1.1.77.1.3"); std::string const VLPhotographicImageStorage("1.2.840.10008.5.1.4.1.1.77.1.4"); std::string const VideoPhotographicImageStorage("1.2.840.10008.5.1.4.1.1.77.1.4.1"); std::string const OphthalmicPhotography8BitImageStorage("1.2.840.10008.5.1.4.1.1.77.1.5.1"); std::string const OphthalmicPhotography16BitImageStorage("1.2.840.10008.5.1.4.1.1.77.1.5.2"); std::string const StereometricRelationshipStorage("1.2.840.10008.5.1.4.1.1.77.1.5.3"); std::string const OphthalmicTomographyImageStorage("1.2.840.10008.5.1.4.1.1.77.1.5.4"); std::string const WideFieldOphthalmicPhotographyStereographicProjectionImageStorage("1.2.840.10008.5.1.4.1.1.77.1.5.5"); std::string const WideFieldOphthalmicPhotography3DCoordinatesImageStorage("1.2.840.10008.5.1.4.1.1.77.1.5.6"); std::string const VLWholeSlideMicroscopyImageStorage("1.2.840.10008.5.1.4.1.1.77.1.6"); std::string const LensometryMeasurementsStorage("1.2.840.10008.5.1.4.1.1.78.1"); std::string const AutorefractionMeasurementsStorage("1.2.840.10008.5.1.4.1.1.78.2"); std::string const KeratometryMeasurementsStorage("1.2.840.10008.5.1.4.1.1.78.3"); std::string const SubjectiveRefractionMeasurementsStorage("1.2.840.10008.5.1.4.1.1.78.4"); std::string const VisualAcuityMeasurementsStorage("1.2.840.10008.5.1.4.1.1.78.5"); std::string const SpectaclePrescriptionReportStorage("1.2.840.10008.5.1.4.1.1.78.6"); std::string const OphthalmicAxialMeasurementsStorage("1.2.840.10008.5.1.4.1.1.78.7"); std::string const IntraocularLensCalculationsStorage("1.2.840.10008.5.1.4.1.1.78.8"); std::string const MacularGridThicknessandVolumeReportStorage("1.2.840.10008.5.1.4.1.1.79.1"); std::string const OphthalmicVisualFieldStaticPerimetryMeasurementsStorage("1.2.840.10008.5.1.4.1.1.80.1"); std::string const OphthalmicThicknessMapStorage("1.2.840.10008.5.1.4.1.1.81.1"); std::string const CornealTopographyMapStorage("1.2.840.10008.5.1.4.1.1.82.1"); std::string const TextSRStorageTrial_Retired("1.2.840.10008.5.1.4.1.1.88.1"); std::string const AudioSRStorageTrial_Retired("1.2.840.10008.5.1.4.1.1.88.2"); std::string const DetailSRStorageTrial_Retired("1.2.840.10008.5.1.4.1.1.88.3"); std::string const ComprehensiveSRStorageTrial_Retired("1.2.840.10008.5.1.4.1.1.88.4"); std::string const BasicTextSRStorage("1.2.840.10008.5.1.4.1.1.88.11"); std::string const EnhancedSRStorage("1.2.840.10008.5.1.4.1.1.88.22"); std::string const ComprehensiveSRStorage("1.2.840.10008.5.1.4.1.1.88.33"); std::string const Comprehensive3DSRStorage("1.2.840.10008.5.1.4.1.1.88.34"); std::string const ExtensibleSRStorage("1.2.840.10008.5.1.4.1.1.88.35"); std::string const ProcedureLogStorage("1.2.840.10008.5.1.4.1.1.88.40"); std::string const MammographyCADSRStorage("1.2.840.10008.5.1.4.1.1.88.50"); std::string const KeyObjectSelectionDocumentStorage("1.2.840.10008.5.1.4.1.1.88.59"); std::string const ChestCADSRStorage("1.2.840.10008.5.1.4.1.1.88.65"); std::string const XRayRadiationDoseSRStorage("1.2.840.10008.5.1.4.1.1.88.67"); std::string const RadiopharmaceuticalRadiationDoseSRStorage("1.2.840.10008.5.1.4.1.1.88.68"); std::string const ColonCADSRStorage("1.2.840.10008.5.1.4.1.1.88.69"); std::string const ImplantationPlanSRStorage("1.2.840.10008.5.1.4.1.1.88.70"); std::string const EncapsulatedPDFStorage("1.2.840.10008.5.1.4.1.1.104.1"); std::string const EncapsulatedCDAStorage("1.2.840.10008.5.1.4.1.1.104.2"); std::string const PositronEmissionTomographyImageStorage("1.2.840.10008.5.1.4.1.1.128"); std::string const LegacyConvertedEnhancedPETImageStorage("1.2.840.10008.5.1.4.1.1.128.1"); std::string const StandalonePETCurveStorage_Retired("1.2.840.10008.5.1.4.1.1.129"); std::string const EnhancedPETImageStorage("1.2.840.10008.5.1.4.1.1.130"); std::string const BasicStructuredDisplayStorage("1.2.840.10008.5.1.4.1.1.131"); std::string const RTImageStorage("1.2.840.10008.5.1.4.1.1.481.1"); std::string const RTDoseStorage("1.2.840.10008.5.1.4.1.1.481.2"); std::string const RTStructureSetStorage("1.2.840.10008.5.1.4.1.1.481.3"); std::string const RTBeamsTreatmentRecordStorage("1.2.840.10008.5.1.4.1.1.481.4"); std::string const RTPlanStorage("1.2.840.10008.5.1.4.1.1.481.5"); std::string const RTBrachyTreatmentRecordStorage("1.2.840.10008.5.1.4.1.1.481.6"); std::string const RTTreatmentSummaryRecordStorage("1.2.840.10008.5.1.4.1.1.481.7"); std::string const RTIonPlanStorage("1.2.840.10008.5.1.4.1.1.481.8"); std::string const RTIonBeamsTreatmentRecordStorage("1.2.840.10008.5.1.4.1.1.481.9"); std::string const DICOSCTImageStorage("1.2.840.10008.5.1.4.1.1.501.1"); std::string const DICOSDigitalXRayImageStorageForPresentation("1.2.840.10008.5.1.4.1.1.501.2.1"); std::string const DICOSDigitalXRayImageStorageForProcessing("1.2.840.10008.5.1.4.1.1.501.2.2"); std::string const DICOSThreatDetectionReportStorage("1.2.840.10008.5.1.4.1.1.501.3"); std::string const DICOS2DAITStorage("1.2.840.10008.5.1.4.1.1.501.4"); std::string const DICOS3DAITStorage("1.2.840.10008.5.1.4.1.1.501.5"); std::string const DICOSQuadrupoleResonanceQRStorage("1.2.840.10008.5.1.4.1.1.501.6"); std::string const EddyCurrentImageStorage("1.2.840.10008.5.1.4.1.1.601.1"); std::string const EddyCurrentMultiframeImageStorage("1.2.840.10008.5.1.4.1.1.601.2"); std::string const PatientRootQueryRetrieveInformationModelFIND("1.2.840.10008.5.1.4.1.2.1.1"); std::string const PatientRootQueryRetrieveInformationModelMOVE("1.2.840.10008.5.1.4.1.2.1.2"); std::string const PatientRootQueryRetrieveInformationModelGET("1.2.840.10008.5.1.4.1.2.1.3"); std::string const StudyRootQueryRetrieveInformationModelFIND("1.2.840.10008.5.1.4.1.2.2.1"); std::string const StudyRootQueryRetrieveInformationModelMOVE("1.2.840.10008.5.1.4.1.2.2.2"); std::string const StudyRootQueryRetrieveInformationModelGET("1.2.840.10008.5.1.4.1.2.2.3"); std::string const PatientStudyOnlyQueryRetrieveInformationModelFIND_Retired("1.2.840.10008.5.1.4.1.2.3.1"); std::string const PatientStudyOnlyQueryRetrieveInformationModelMOVE_Retired("1.2.840.10008.5.1.4.1.2.3.2"); std::string const PatientStudyOnlyQueryRetrieveInformationModelGET_Retired("1.2.840.10008.5.1.4.1.2.3.3"); std::string const CompositeInstanceRootRetrieveMOVE("1.2.840.10008.5.1.4.1.2.4.2"); std::string const CompositeInstanceRootRetrieveGET("1.2.840.10008.5.1.4.1.2.4.3"); std::string const CompositeInstanceRetrieveWithoutBulkDataGET("1.2.840.10008.5.1.4.1.2.5.3"); std::string const ModalityWorklistInformationModelFIND("1.2.840.10008.5.1.4.31"); std::string const GeneralPurposeWorklistManagementMetaSOPClass_Retired("1.2.840.10008.5.1.4.32"); std::string const GeneralPurposeWorklistInformationModelFIND_Retired("1.2.840.10008.5.1.4.32.1"); std::string const GeneralPurposeScheduledProcedureStepSOPClass_Retired("1.2.840.10008.5.1.4.32.2"); std::string const GeneralPurposePerformedProcedureStepSOPClass_Retired("1.2.840.10008.5.1.4.32.3"); std::string const InstanceAvailabilityNotificationSOPClass("1.2.840.10008.5.1.4.33"); std::string const RTBeamsDeliveryInstructionStorageTrial_Retired("1.2.840.10008.5.1.4.34.1"); std::string const RTConventionalMachineVerificationTrial_Retired("1.2.840.10008.5.1.4.34.2"); std::string const RTIonMachineVerificationTrial_Retired("1.2.840.10008.5.1.4.34.3"); std::string const UnifiedWorklistandProcedureStepServiceClassTrial_Retired("1.2.840.10008.5.1.4.34.4"); std::string const UnifiedProcedureStepPushSOPClassTrial_Retired("1.2.840.10008.5.1.4.34.4.1"); std::string const UnifiedProcedureStepWatchSOPClassTrial_Retired("1.2.840.10008.5.1.4.34.4.2"); std::string const UnifiedProcedureStepPullSOPClassTrial_Retired("1.2.840.10008.5.1.4.34.4.3"); std::string const UnifiedProcedureStepEventSOPClassTrial_Retired("1.2.840.10008.5.1.4.34.4.4"); std::string const UPSGlobalSubscriptionSOPInstance("1.2.840.10008.5.1.4.34.5"); std::string const UPSFilteredGlobalSubscriptionSOPInstance("1.2.840.10008.5.1.4.34.5.1"); std::string const UnifiedWorklistandProcedureStepServiceClass("1.2.840.10008.5.1.4.34.6"); std::string const UnifiedProcedureStepPushSOPClass("1.2.840.10008.5.1.4.34.6.1"); std::string const UnifiedProcedureStepWatchSOPClass("1.2.840.10008.5.1.4.34.6.2"); std::string const UnifiedProcedureStepPullSOPClass("1.2.840.10008.5.1.4.34.6.3"); std::string const UnifiedProcedureStepEventSOPClass("1.2.840.10008.5.1.4.34.6.4"); std::string const RTBeamsDeliveryInstructionStorage("1.2.840.10008.5.1.4.34.7"); std::string const RTConventionalMachineVerification("1.2.840.10008.5.1.4.34.8"); std::string const RTIonMachineVerification("1.2.840.10008.5.1.4.34.9"); std::string const GeneralRelevantPatientInformationQuery("1.2.840.10008.5.1.4.37.1"); std::string const BreastImagingRelevantPatientInformationQuery("1.2.840.10008.5.1.4.37.2"); std::string const CardiacRelevantPatientInformationQuery("1.2.840.10008.5.1.4.37.3"); std::string const HangingProtocolStorage("1.2.840.10008.5.1.4.38.1"); std::string const HangingProtocolInformationModelFIND("1.2.840.10008.5.1.4.38.2"); std::string const HangingProtocolInformationModelMOVE("1.2.840.10008.5.1.4.38.3"); std::string const HangingProtocolInformationModelGET("1.2.840.10008.5.1.4.38.4"); std::string const ColorPaletteStorage("1.2.840.10008.5.1.4.39.1"); std::string const ColorPaletteInformationModelFIND("1.2.840.10008.5.1.4.39.2"); std::string const ColorPaletteInformationModelMOVE("1.2.840.10008.5.1.4.39.3"); std::string const ColorPaletteInformationModelGET("1.2.840.10008.5.1.4.39.4"); std::string const ProductCharacteristicsQuerySOPClass("1.2.840.10008.5.1.4.41"); std::string const SubstanceApprovalQuerySOPClass("1.2.840.10008.5.1.4.42"); std::string const GenericImplantTemplateStorage("1.2.840.10008.5.1.4.43.1"); std::string const GenericImplantTemplateInformationModelFIND("1.2.840.10008.5.1.4.43.2"); std::string const GenericImplantTemplateInformationModelMOVE("1.2.840.10008.5.1.4.43.3"); std::string const GenericImplantTemplateInformationModelGET("1.2.840.10008.5.1.4.43.4"); std::string const ImplantAssemblyTemplateStorage("1.2.840.10008.5.1.4.44.1"); std::string const ImplantAssemblyTemplateInformationModelFIND("1.2.840.10008.5.1.4.44.2"); std::string const ImplantAssemblyTemplateInformationModelMOVE("1.2.840.10008.5.1.4.44.3"); std::string const ImplantAssemblyTemplateInformationModelGET("1.2.840.10008.5.1.4.44.4"); std::string const ImplantTemplateGroupStorage("1.2.840.10008.5.1.4.45.1"); std::string const ImplantTemplateGroupInformationModelFIND("1.2.840.10008.5.1.4.45.2"); std::string const ImplantTemplateGroupInformationModelMOVE("1.2.840.10008.5.1.4.45.3"); std::string const ImplantTemplateGroupInformationModelGET("1.2.840.10008.5.1.4.45.4"); std::string const NativeDICOMModel("1.2.840.10008.7.1.1"); std::string const AbstractMultiDimensionalImageModel("1.2.840.10008.7.1.2"); std::string const DICOMContentMappingResource("1.2.840.10008.8.1.1"); std::string const dicomDeviceName("1.2.840.10008.15.0.3.1"); std::string const dicomDescription("1.2.840.10008.15.0.3.2"); std::string const dicomManufacturer("1.2.840.10008.15.0.3.3"); std::string const dicomManufacturerModelName("1.2.840.10008.15.0.3.4"); std::string const dicomSoftwareVersion("1.2.840.10008.15.0.3.5"); std::string const dicomVendorData("1.2.840.10008.15.0.3.6"); std::string const dicomAETitle("1.2.840.10008.15.0.3.7"); std::string const dicomNetworkConnectionReference("1.2.840.10008.15.0.3.8"); std::string const dicomApplicationCluster("1.2.840.10008.15.0.3.9"); std::string const dicomAssociationInitiator("1.2.840.10008.15.0.3.10"); std::string const dicomAssociationAcceptor("1.2.840.10008.15.0.3.11"); std::string const dicomHostname("1.2.840.10008.15.0.3.12"); std::string const dicomPort("1.2.840.10008.15.0.3.13"); std::string const dicomSOPClass("1.2.840.10008.15.0.3.14"); std::string const dicomTransferRole("1.2.840.10008.15.0.3.15"); std::string const dicomTransferSyntax("1.2.840.10008.15.0.3.16"); std::string const dicomPrimaryDeviceType("1.2.840.10008.15.0.3.17"); std::string const dicomRelatedDeviceReference("1.2.840.10008.15.0.3.18"); std::string const dicomPreferredCalledAETitle("1.2.840.10008.15.0.3.19"); std::string const dicomTLSCyphersuite("1.2.840.10008.15.0.3.20"); std::string const dicomAuthorizedNodeCertificateReference("1.2.840.10008.15.0.3.21"); std::string const dicomThisNodeCertificateReference("1.2.840.10008.15.0.3.22"); std::string const dicomInstalled("1.2.840.10008.15.0.3.23"); std::string const dicomStationName("1.2.840.10008.15.0.3.24"); std::string const dicomDeviceSerialNumber("1.2.840.10008.15.0.3.25"); std::string const dicomInstitutionName("1.2.840.10008.15.0.3.26"); std::string const dicomInstitutionAddress("1.2.840.10008.15.0.3.27"); std::string const dicomInstitutionDepartmentName("1.2.840.10008.15.0.3.28"); std::string const dicomIssuerOfPatientID("1.2.840.10008.15.0.3.29"); std::string const dicomPreferredCallingAETitle("1.2.840.10008.15.0.3.30"); std::string const dicomSupportedCharacterSet("1.2.840.10008.15.0.3.31"); std::string const dicomConfigurationRoot("1.2.840.10008.15.0.4.1"); std::string const dicomDevicesRoot("1.2.840.10008.15.0.4.2"); std::string const dicomUniqueAETitlesRegistryRoot("1.2.840.10008.15.0.4.3"); std::string const dicomDevice("1.2.840.10008.15.0.4.4"); std::string const dicomNetworkAE("1.2.840.10008.15.0.4.5"); std::string const dicomNetworkConnection("1.2.840.10008.15.0.4.6"); std::string const dicomUniqueAETitle("1.2.840.10008.15.0.4.7"); std::string const dicomTransferCapability("1.2.840.10008.15.0.4.8"); std::string const UniversalCoordinatedTime("1.2.840.10008.15.1.1"); extern ElementsDictionary public_dictionary; extern UIDsDictionary uids_dictionary; } } #endif // _afc7b2d7_0869_4fea_9a9b_7fe6228baca9 odil-0.4.1/src/odil/uid.cpp000066400000000000000000000023271266460524100154600ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/uid.h" #include #include #include "odil/Exception.h" #define ODIL_STRINGIFY_HELPER(s) #s #define ODIL_STRINGIFY(s) ODIL_STRINGIFY_HELPER(s) namespace odil { #ifdef ODIL_MAJOR_VERSION std::string const implementation_class_uid=uid_prefix+"0." ODIL_STRINGIFY(ODIL_MAJOR_VERSION); std::string const implementation_version_name="Odil " ODIL_STRINGIFY(ODIL_MAJOR_VERSION); #else #error ODIL_MAJOR_VERSION must be defined #endif std::string generate_uid() { static std::random_device generator; std::uniform_int_distribution<> non_zero(1, 9); std::uniform_int_distribution<> digits(0, 9); std::string result = uid_prefix + "." + std::to_string(non_zero(generator)); while(result.size()<64) { result += std::to_string(digits(generator)); } return result; } } odil-0.4.1/src/odil/uid.h000066400000000000000000000016731266460524100151300ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _d8ae0008_075b_4a28_a241_1c6fb1a6c79b #define _d8ae0008_075b_4a28_a241_1c6fb1a6c79b #include namespace odil { /// @brief UID prefix of Odil. std::string const uid_prefix="1.2.826.0.1.3680043.9.5560"; /// @brief Implementation class UID of Odil. extern std::string const implementation_class_uid; /// @brief Implementation version name of Odil. extern std::string const implementation_version_name; /// @brief Generate a UID under the UID prefix. std::string generate_uid(); } #endif // _d8ae0008_075b_4a28_a241_1c6fb1a6c79b odil-0.4.1/src/odil/unicode.cpp000066400000000000000000000250061266460524100163240ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include "odil/unicode.h" #include #include #include #include #include #include #include #include #include "odil/Exception.h" #include "odil/Value.h" namespace odil { std::map const icu_encodings = { { "", "" }, // Single-Byte Character Sets Without Code Extensions { "ISO_IR 100", "iso-ir-100" }, { "ISO_IR 101", "iso-ir-101" }, { "ISO_IR 109", "iso-ir-109" }, { "ISO_IR 110", "iso-ir-110" }, { "ISO_IR 144", "iso-ir-144" }, { "ISO_IR 127", "iso-ir-127" }, { "ISO_IR 126", "iso-ir-126" }, { "ISO_IR 138", "iso-ir-138" }, { "ISO_IR 148", "iso-ir-148" }, { "ISO_IR 13", "Shift_JIS" }, // Since the 0x00 to 0x7f characters // match ASCII (i.e. Romaji) and the 0xa1 to 0xdf map to half-width // katakana of JIS X 0201. cf. https://en.wikipedia.org/wiki/Shift_JIS { "ISO_IR 166", "TIS-620" }, // Single-Byte Character Sets with Code Extensions { "ISO 2022 IR 6", "" }, { "ISO 2022 IR 100", "iso-ir-100" }, { "ISO 2022 IR 101", "iso-ir-101" }, { "ISO 2022 IR 109", "iso-ir-109" }, { "ISO 2022 IR 110", "iso-ir-110" }, { "ISO 2022 IR 144", "iso-ir-144" }, { "ISO 2022 IR 127", "iso-ir-127" }, { "ISO 2022 IR 126", "iso-ir-126" }, { "ISO 2022 IR 138", "iso-ir-138" }, { "ISO 2022 IR 148", "iso-ir-148" }, { "ISO 2022 IR 13", "Shift_JIS" }, { "ISO 2022 IR 166", "TIS-620" }, { "\x1B\x28\x42", "" }, { "\x1B\x2D\x41", "iso-ir-100" }, { "\x1B\x2D\x42", "iso-ir-101" }, { "\x1B\x2D\x43", "iso-ir-109" }, { "\x1B\x2D\x44", "iso-ir-110" }, { "\x1B\x2D\x4C", "iso-ir-144" }, { "\x1B\x2D\x47", "iso-ir-127" }, { "\x1B\x2D\x46", "iso-ir-126" }, { "\x1B\x2D\x48", "iso-ir-138" }, { "\x1B\x2D\x4D", "iso-ir-148" }, { "\x1B\x29\x49", "ISO-2022-JP" }, { "\x1B\x28\x4A", "ISO-2022-JP" }, { "\x1B\x2D\x54", "TIS-620" }, // Multi-Byte Character Sets with Code Extensions { "ISO 2022 IR 87", "ISO-2022-JP" }, { "ISO 2022 IR 149", "EUC-KR" }, { "ISO 2022 IR 58", "ISO-2022-CN" }, { "\x1B\x24\x42", "ISO-2022-JP" }, { "\x1B\x24\x28\x44", "ISO-2022-JP" }, { "\x1B\x24\x29\x43", "iso-ir-149" }, { "\x1B\x24\x29\x41", "iso-ir-58" }, // Multi-Byte Character Sets Without Code Extensions { "ISO_IR 192", "UTF-8" }, { "GB18030", "GB18030" }, // GBK }; std::map> const escape_sequences = { { "", { "\x1B\x28\x42" } }, { "ISO 2022 IR 6", { "\x1B\x28\x42" } }, { "ISO 2022 IR 100", { "\x1B\x2D\x41", "\x1B\x28\x42" } }, { "ISO 2022 IR 101", { "\x1B\x2D\x42", "\x1B\x28\x42" } }, { "ISO 2022 IR 109", { "\x1B\x2D\x43", "\x1B\x28\x42" } }, { "ISO 2022 IR 110", { "\x1B\x2D\x44", "\x1B\x28\x42" } }, { "ISO 2022 IR 144", { "\x1B\x2D\x4C", "\x1B\x28\x42" } }, { "ISO 2022 IR 127", { "\x1B\x2D\x47", "\x1B\x28\x42" } }, { "ISO 2022 IR 126", { "\x1B\x2D\x46", "\x1B\x28\x42" } }, { "ISO 2022 IR 138", { "\x1B\x2D\x48", "\x1B\x28\x42" } }, { "ISO 2022 IR 148", { "\x1B\x2D\x4D", "\x1B\x28\x42" } }, { "ISO 2022 IR 13", { "\x1B\x29\x49", "\x1B\x28\x4A" } }, { "ISO 2022 IR 166", { "\x1B\x2D\x54", "\x1B\x28\x42" } }, { "ISO 2022 IR 87", { "\x1B\x24\x42", "\x1B\x28\x42" } }, { "ISO 2022 IR 159", { "\x1B\x24\x28\x44" } }, { "ISO 2022 IR 149", { "\x1B\x24\x29\x43" } }, { "ISO 2022 IR 58", { "\x1B\x24\x29\x41" } }, }; std::string find_encoder(std::string const & specific_character_set) { std::string encoder; auto const it = icu_encodings.find(specific_character_set); if(it == icu_encodings.end()) { throw Exception("Unknown encoding: "+specific_character_set); } encoder = it->second; return encoder; } std::string as_utf8( std::string::const_iterator const begin, std::string::const_iterator const end, std::string const & encoding) { icu::UnicodeString unicode(&(*begin), end-begin, encoding.c_str()); std::string result; unicode.toUTF8String(result); return result; } std::string as_utf8( std::string::const_iterator const begin, std::string::const_iterator const end, std::string const & initial_encoder, std::vector const & active_escape_sequences) { std::string encoded; auto encoder = initial_encoder; auto item_begin = begin; while(item_begin != end) { auto const item_end = std::find(item_begin+1, end, '\x1B'); if(*item_begin == '\x1B') { std::string escape_sequence(item_begin, item_begin+3); // Find an encoder for the escape sequence if( std::find( active_escape_sequences.begin(), active_escape_sequences.end(), escape_sequence) != active_escape_sequences.end()) { encoder = find_encoder(escape_sequence); } else { escape_sequence += *(item_begin+3); if( std::find( active_escape_sequences.begin(), active_escape_sequences.end(), escape_sequence) != active_escape_sequences.end()) { encoder = find_encoder(escape_sequence); } else { // Unknown escape sequence: do not update the encoder, // hope for the best. } } if(encoder != "ISO-2022-JP") { // The ISO-2022-JP encoder of ICU must have the escape // sequences item_begin += escape_sequence.size(); } } encoded += as_utf8(item_begin, item_end, encoder); item_begin = item_end; } return encoded; } enum class Group { Alphabetic, Ideographic, Phonetic }; std::vector get_active_escape_sequences( Value::Strings const & specific_character_set, Group const & group) { std::vector active_escape_sequences; if(specific_character_set.size() >= 2) { auto const escape_sequences_it = escape_sequences.find(specific_character_set[1]); if(escape_sequences_it == escape_sequences.end()) { throw Exception("Unknown specific character set: "+specific_character_set[1]); } std::copy( escape_sequences_it->second.begin(), escape_sequences_it->second.end(), std::back_inserter(active_escape_sequences)); } if(group == Group::Phonetic) { auto const escape_sequences_it = escape_sequences.find(specific_character_set[0]); if(escape_sequences_it != escape_sequences.end()) { std::copy( escape_sequences_it->second.begin(), escape_sequences_it->second.end(), std::back_inserter(active_escape_sequences)); } if(specific_character_set.size() >= 3) { auto const escape_sequences_it = escape_sequences.find(specific_character_set[2]); if(escape_sequences_it == escape_sequences.end()) { throw Exception("Unknown specific character set: "+specific_character_set[2]); } std::copy( escape_sequences_it->second.begin(), escape_sequences_it->second.end(), std::back_inserter(active_escape_sequences)); } } return active_escape_sequences; } std::string as_utf8( std::string const & input, Value::Strings const & specific_character_set, bool is_pn) { // Control characters: line feed, carriage return, form feed and tabulation // For Person Name, add the group splitters std::string splitters = "\n\r\f\t"; if(is_pn) { if( std::find( specific_character_set.begin(), specific_character_set.end(), "ISO 2022 IR 13") != specific_character_set.end() || std::find( specific_character_set.begin(), specific_character_set.end(), "ISO 2022 IR 87") != specific_character_set.end()) { // The ISO-2022-JP encoder of ICU is stateful, whereas all other // ISO 2022 encoders seem to be only codepages (i.e. stateless) splitters.append("="); } else { splitters.append("^="); } } std::string result; Group group=Group::Alphabetic; auto begin = input.begin(); while(begin != input.end()) { // Active character set resets to default before any of the splitters // cf. PS 3.5, 6.1.2.5.3 auto const end = std::find_first_of( begin, input.end(), splitters.begin(), splitters.end()); std::string encoded; if(specific_character_set.empty()) { encoded = std::string(begin, end); } else if(is_pn && group != Group::Alphabetic) { auto const initial_encoder = find_encoder(specific_character_set[0]); auto const active_escape_sequences = get_active_escape_sequences(specific_character_set, group); encoded = as_utf8(begin, end, initial_encoder, active_escape_sequences); } else { auto const encoder = find_encoder(specific_character_set[0]); encoded = as_utf8(begin, end, encoder); } result.append(encoded); // If present, add the splitter to the UTF-8 string. if(end != input.end()) { result.push_back(*end); begin = end+1; if(is_pn && *end == '=') { if(group == Group::Alphabetic) { group = Group::Ideographic; } else if(group == Group::Ideographic) { group = Group::Phonetic; } else { throw Exception("Too many groups"); } } } else { begin = end; } } return result; } } odil-0.4.1/src/odil/unicode.h000066400000000000000000000014261266460524100157710ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _4a178325_e3d6_4f6f_9a18_ba6a983ee396 #define _4a178325_e3d6_4f6f_9a18_ba6a983ee396 #include #include "odil/Value.h" namespace odil { /// @brief Convert a string to its UTF-8 representation std::string as_utf8( std::string const & input, Value::Strings const & specific_character_set, bool is_pn=false); } #endif // _4a178325_e3d6_4f6f_9a18_ba6a983ee396 odil-0.4.1/src/odil/xml_converter.cpp000066400000000000000000000456711266460524100175770ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #include #include #include #include "odil/base64.h" #include "odil/registry.h" #include "odil/xml_converter.h" namespace odil { struct ToXMLVisitor { typedef boost::property_tree::ptree result_type; result_type operator()(VR const vr) const { result_type result; result.put(".vr", as_string(vr)); // Mandatory return result; } template result_type operator()(VR const vr, T const & value) const { result_type result; result.put(".vr", as_string(vr)); // Mandatory unsigned int count = 0; for(auto const & item: value) { ++count; boost::property_tree::ptree tag_value; tag_value.put(".number", count); // Mandatory tag_value.put_value(item); result.add_child("Value", tag_value); } return result; } result_type operator()(VR const vr, Value::Integers const & value) const { result_type result; result.put(".vr", as_string(vr)); // Mandatory unsigned int count = 0; for(auto const & item: value) { ++count; boost::property_tree::ptree tag_value; tag_value.put(".number", count); // Mandatory tag_value.put_value(item); result.add_child("Value", tag_value); } return result; } result_type operator()(VR const vr, Value::Strings const & value) const { result_type result; result.put(".vr", as_string(vr)); // Mandatory if(vr == VR::PN) { auto const fields = { "Alphabetic", "Ideographic", "Phonetic" }; unsigned int count = 0; for(auto const & item: value) { ++count; boost::property_tree::ptree tag_value; tag_value.put(".number", count); // Mandatory auto fields_it = fields.begin(); std::string::size_type begin=0; while(begin != std::string::npos) { std::string::size_type const end = item.find("=", begin); std::string::size_type size = 0; if(end != std::string::npos) { size = end-begin; } else { size = std::string::npos; } boost::property_tree::ptree tag_field; std::string value_name = item.substr(begin, size); auto const fields_name = { "FamilyName", "GivenName", "MiddleName", "NamePrefix", "NameSuffix" }; auto fields_name_it = fields_name.begin(); std::string::size_type begin_name=0; while(begin_name != std::string::npos) { std::string::size_type const end_name = value_name.find("^", begin_name); std::string::size_type size_name = 0; if(end_name != std::string::npos) { size_name = end_name-begin_name; } else { size_name = std::string::npos; } boost::property_tree::ptree tag_name; tag_name.put_value(value_name.substr(begin_name, size_name)); tag_field.add_child(*fields_name_it, tag_name); if(end_name != std::string::npos) { begin_name = end_name+1; ++fields_name_it; if(fields_name_it == fields_name.end()) { throw Exception("Invalid Person Name"); } } else { begin_name = end_name; } } tag_value.add_child(*fields_it, tag_field); if(end != std::string::npos) { begin = end+1; ++fields_it; if(fields_it == fields.end()) { throw Exception("Invalid Person Name"); } } else { begin = end; } } result.add_child("PersonName", tag_value); } } else { unsigned int count = 0; for(auto const & item: value) { ++count; boost::property_tree::ptree tag_value; tag_value.put(".number", count); // Mandatory tag_value.put_value(item); result.add_child("Value", tag_value); } } return result; } result_type operator()(VR const vr, Value::DataSets const & value) const { result_type result; result.put(".vr", as_string(vr)); // Mandatory unsigned int count = 0; for(auto const & item: value) { ++count; boost::property_tree::ptree tag_value; tag_value.put(".number", count); // Mandatory boost::property_tree::ptree tag_result = as_xml(item); tag_value.insert(tag_value.end(), tag_result.front().second.begin(), tag_result.front().second.end()); result.add_child("Item", tag_value); } return result; } result_type operator()(VR const vr, Value::Binary const & value) const { result_type result; result.put(".vr", as_string(vr)); // Mandatory boost::property_tree::ptree tag_value; std::string encoded; encoded.reserve(value.size()*4/3); base64::encode(value.begin(), value.end(), std::back_inserter(encoded)); tag_value.put_value(encoded); result.add_child("InlineBinary", tag_value); return result; } }; std::string get_person_name(boost::property_tree::ptree const & xml) { std::vector const fields_name = { "NameSuffix", "NamePrefix", "MiddleName", "GivenName", "FamilyName" }; std::map values; for(auto it = xml.begin(); it != xml.end(); ++it) { if (std::find(fields_name.begin(), fields_name.end(), it->first) != fields_name.end()) { auto const value = it->second.get_value(); values.insert(std::pair(it->first, value)); } else { std::stringstream error; error << "Bad sub-Tag '" << it->first << "' for PersonName Tag"; throw Exception(error.str()); } } std::string return_value; auto itfield = fields_name.begin(); do { std::stringstream current_value; std::string value; if (values.find(*itfield) != values.end()) { value = values[*itfield]; } ++itfield; if (itfield != fields_name.end() && (value != "" || return_value != "")) { current_value << "^"; } if (value != "") { current_value << value; } if (return_value != "") { current_value << return_value; } return_value = current_value.str(); } while (itfield != fields_name.end()); return return_value; } template std::map parse_value(boost::property_tree::ptree const & xml, VR const & vr) { std::map values; for(auto it_value = xml.begin(); it_value != xml.end(); ++it_value) { if (it_value->first == "") { continue; } else if (it_value->first != "Value") { std::stringstream error; error << "Bad sub-Tag '" << it_value->first << "' for DicomAttribute Tag with VR = " << as_string(vr); throw Exception(error.str()); } int const position = it_value->second.get(".number"); values.insert(std::pair( position, it_value->second.get_value())); } return values; } boost::property_tree::ptree as_xml(DataSet const & data_set) { // XML dataset element boost::property_tree::ptree nativedicommodel; for(auto const & it: data_set) { auto const & tag = it.first; auto const & element = it.second; boost::property_tree::ptree dicomattribute = apply_visitor(ToXMLVisitor(), element); auto const dictionary_it = registry::public_dictionary.find(tag); if(dictionary_it == registry::public_dictionary.end()) { throw Exception("No such element: " + std::string(tag)); } // Add Mandatory attribute Tag dicomattribute.put(".tag", std::string(tag)); // Add Optional attribute Keyword dicomattribute.put(".keyword", dictionary_it->second.keyword); // Add Optional attribute PrivateCreator //dicomattribute.put(".privateCreator", todo); nativedicommodel.add_child("DicomAttribute", dicomattribute); } // root element boost::property_tree::ptree dataset_xml; // Add XML dataset into root element dataset_xml.add_child("NativeDicomModel", nativedicommodel); return dataset_xml; } DataSet as_dataset(boost::property_tree::ptree const & xml) { // XML contains only one NativeDicomModel // // ... // if (xml.size() < 1 || xml.front().first != "NativeDicomModel") { throw Exception("Missing root node NativeDicomModel"); } DataSet data_set; for(auto it = xml.front().second.begin(); it != xml.front().second.end(); ++it) { // NativeDicomModel tag should only contains DicomAttribute tag if (it->first != "DicomAttribute") { throw Exception("Bad DICOM tag: " + it->first); } // Get VR and tag Tag const tag(it->second.get(".tag")); VR const vr = as_vr(it->second.get(".vr")); Element element; if(vr == VR::AE || vr == VR::AS || vr == VR::AT || vr == VR::CS || vr == VR::DA || vr == VR::DT || vr == VR::LO || vr == VR::LT || vr == VR::SH || vr == VR::ST || vr == VR::TM || vr == VR::UI || vr == VR::UT) { element = Element(Value::Strings(), vr); auto values = parse_value(it->second, vr); for (auto it = values.begin(); it != values.end(); ++it) { element.as_string().push_back(it->second); } } else if(vr == VR::PN) { element = Element(Value::Strings(), vr); std::map values; for(auto it_value = it->second.begin(); it_value != it->second.end(); ++it_value) { if (it_value->first == "") { continue; } else if (it_value->first != "PersonName") { std::stringstream error; error << "Bad sub-Tag '" << it_value->first << "' for DicomAttribute Tag with VR = " << as_string(vr); throw Exception(error.str()); } int const position = it_value->second.get(".number"); std::map names; auto const fields = { "Alphabetic", "Ideographic", "Phonetic" }; for(auto it_person = it_value->second.begin(); it_person != it_value->second.end(); ++it_person) { if (it_person->first == "") { continue; } else if (std::find(fields.begin(), fields.end(), it_person->first) != fields.end()) { names.insert(std::pair( it_person->first, get_person_name(it_person->second))); } else { std::stringstream error; error << "Bad sub-Tag '" << it_person->first << "' for PersonName Tag"; throw Exception(error.str()); } } Value::Strings::value_type dicom_item; for(auto const & field: fields) { if (names.find(field) != names.end()) { dicom_item += names[field]; } dicom_item += "="; } while(*dicom_item.rbegin() == '=') { dicom_item = dicom_item.substr(0, dicom_item.size()-1); } values.insert(std::pair( position, dicom_item)); } for (auto it = values.begin(); it != values.end(); ++it) { element.as_string().push_back(it->second); } } else if(vr == VR::DS || vr == VR::FD || vr == VR::FL) { element = Element(Value::Reals(), vr); auto values = parse_value(it->second, vr); for (auto it = values.begin(); it != values.end(); ++it) { element.as_real().push_back(it->second); } } else if(vr == VR::IS || vr == VR::SL || vr == VR::SS || vr == VR::UL || vr == VR::US) { element = Element(Value::Integers(), vr); auto values = parse_value(it->second, vr); for (auto it = values.begin(); it != values.end(); ++it) { element.as_int().push_back(it->second); } } else if(vr == VR::SQ) { element = Element(Value::DataSets(), vr); std::map values; for(auto it_value = it->second.begin(); it_value != it->second.end(); ++it_value) { if (it_value->first == "") { continue; } else if (it_value->first != "Item") { std::stringstream error; error << "Bad sub-Tag '" << it_value->first << "' for DicomAttribute Tag with VR = " << as_string(vr); throw Exception(error.str()); } boost::property_tree::ptree nativedicommodel; nativedicommodel.insert(nativedicommodel.end(), it_value->second.begin(), it_value->second.end()); nativedicommodel.erase(""); boost::property_tree::ptree dataset_xml; dataset_xml.add_child("NativeDicomModel", nativedicommodel); int const position = it_value->second.get(".number"); values.insert(std::pair( position, as_dataset(dataset_xml))); } for (auto it = values.begin(); it != values.end(); ++it) { element.as_data_set().push_back(it->second); } } else if(vr == VR::OB || vr == VR::OF || vr == VR::OW || vr == VR::UN) { element = Element(Value::Binary(), vr); bool find_inline_binary = false; // only one Tag InlineBinary for(auto it_value = it->second.begin(); it_value != it->second.end(); ++it_value) { if (it_value->first == "") { continue; } else if (it_value->first != "InlineBinary") { std::stringstream error; error << "Bad sub-Tag '" << it_value->first << "' for DicomAttribute Tag with VR = " << as_string(vr); throw Exception(error.str()); } else if (find_inline_binary) { std::stringstream error; error << "Too many sub-Tag '" << it_value->first << "' for DicomAttribute Tag with VR = " << as_string(vr); throw Exception(error.str()); } auto const & encoded = it_value->second.get_value(); auto & decoded = element.as_binary(); decoded.reserve(encoded.size()*3/4); base64::decode( encoded.begin(), encoded.end(), std::back_inserter(decoded)); find_inline_binary = true; } } else { throw Exception("Unknown VR: "+as_string(vr)); } data_set.add(tag, element); } return data_set; } } // namespace odil odil-0.4.1/src/odil/xml_converter.h000066400000000000000000000015771266460524100172410ustar00rootroot00000000000000/************************************************************************* * odil - Copyright (C) Universite de Strasbourg * Distributed under the terms of the CeCILL-B license, as published by * the CEA-CNRS-INRIA. Refer to the LICENSE file or to * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * for details. ************************************************************************/ #ifndef _61eb6ed2_447a_43b5_a6ba_ca7c2a5fb492 #define _61eb6ed2_447a_43b5_a6ba_ca7c2a5fb492 #include #include "odil/DataSet.h" namespace odil { /// @brief Convert a data set to its XML representation. boost::property_tree::ptree as_xml(DataSet const & data_set); /// @brief Create a data set from its XML representation. DataSet as_dataset(boost::property_tree::ptree const & xml); } // namespace odil #endif // _61eb6ed2_447a_43b5_a6ba_ca7c2a5fb492 odil-0.4.1/tests/000077500000000000000000000000001266460524100136135ustar00rootroot00000000000000odil-0.4.1/tests/CMakeLists.txt000066400000000000000000000030321266460524100163510ustar00rootroot00000000000000find_package(Boost COMPONENTS unit_test_framework REQUIRED) find_package(DCMTK REQUIRED) find_package(JsonCpp REQUIRED) add_subdirectory(tools) file(GLOB headers *.h) file(GLOB_RECURSE tests code/*.cpp) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src ${JsonCpp_INCLUDE_DIRS}) add_definitions( ${DCMTK_DEFINITIONS} -D BOOST_ASIO_DYN_LINK -D ODIL_MAJOR_VERSION=${odil_MAJOR_VERSION} -DBOOST_TEST_DYN_LINK ) link_directories(${Boost_LIBRARY_DIRS}) foreach(test_file ${tests}) get_filename_component(test ${test_file} NAME_WE) add_executable(${test} ${test_file} ${headers}) target_link_libraries(${test} odil ${Boost_LIBRARIES}) file(READ ${test_file} content) set(pattern "BOOST_(AUTO|FIXTURE)_TEST_CASE\\(([^),]+)") string(REGEX MATCHALL ${pattern} cases ${content}) foreach(case ${cases}) string(REGEX REPLACE ${pattern} "\\2" case ${case}) if(NOT ${case} MATCHES "##") add_test("${test}_${case}" "${test}" "--run_test=${case}") endif() endforeach() set(pattern "ElementTest\\([\n ]+([A-Z]+)") string(REGEX MATCHALL ${pattern} matches ${content}) foreach(match ${matches}) string(REGEX REPLACE ${pattern} "\\1" vr ${match}) set(case "${vr}FromOdil") add_test("${test}_${case}" "${test}" "--run_test=${case}") set(case "${vr}ToOdil") add_test("${test}_${case}" "${test}" "--run_test=${case}") endforeach() endforeach() add_custom_target(Runner ${CMAKE_COMMAND} -E echo "Test runner" SOURCES run.sh) odil-0.4.1/tests/MessageFixtureBase.h000066400000000000000000000036361266460524100175220ustar00rootroot00000000000000#ifndef _779c46d6_b6ea_443a_9642_f1ec5b87d4b3 #define _779c46d6_b6ea_443a_9642_f1ec5b87d4b3 #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/message/Message.h" /// @brief Base class for fixtures of Message-derived classes. template struct MessageFixtureBase { /// @brief Check that a specific message can be constructed from a generic Message. void check_message_constructor( odil::DataSet const & command_set) { odil::message::Message const generic_message(command_set); TMessage const message(generic_message); this->check(message); } /// @brief Check that a specific message can be constructed from a generic Message. void check_message_constructor( odil::DataSet const & command_set, odil::DataSet const & data_set) { odil::message::Message const generic_message(command_set, data_set); TMessage const message(generic_message); this->check(message); } /// @brief Check that a specific message cannot be constructed from a generic Message. void check_message_constructor_throw( odil::DataSet const & command_set) { odil::message::Message const generic_message(command_set); BOOST_CHECK_THROW( TMessage const message(generic_message), odil::Exception); } /// @brief Check that a specific message cannot be constructed from a generic Message. void check_message_constructor_throw( odil::DataSet const & command_set, odil::DataSet const & data_set) { odil::message::Message const generic_message(command_set, data_set); BOOST_CHECK_THROW( TMessage const message(generic_message), odil::Exception); } /// @brief Check that the specific message attributes are set correctly virtual void check(TMessage const & message) =0; }; #endif // _779c46d6_b6ea_443a_9642_f1ec5b87d4b3 odil-0.4.1/tests/PeerFixtureBase.h000066400000000000000000000032701266460524100170230ustar00rootroot00000000000000#ifndef _b21e8d37_0125_4d64_84aa_f91d9d96612b #define _b21e8d37_0125_4d64_84aa_f91d9d96612b #include #include #include #include #include #include "odil/Association.h" #include "odil/AssociationParameters.h" /// @brief Base class for fixtures of requiring a working association. class PeerFixtureBase { public: typedef odil::AssociationParameters::PresentationContext PresentationContext; odil::Association association; PeerFixtureBase(std::vector const & contexts) { this->association.set_peer_host( this->get_environment_variable("ODIL_PEER_HOST_NAME")); this->association.set_peer_port( this->get_environment_variable("ODIL_PEER_PORT")); this->association.update_parameters() .set_calling_ae_title( this->get_environment_variable("ODIL_OWN_AET")) .set_called_ae_title( this->get_environment_variable("ODIL_PEER_AET")) .set_presentation_contexts(contexts); this->association.associate(); } ~PeerFixtureBase() { this->association.release(); } static std::string get_environment_variable(std::string const & name) { char* value = getenv(name.c_str()); if(value == NULL) { BOOST_FAIL(name + " is not defined"); } return value; } template static T get_environment_variable(std::string const & name) { return boost::lexical_cast( PeerFixtureBase::get_environment_variable(name)); } }; #endif // _b21e8d37_0125_4d64_84aa_f91d9d96612b odil-0.4.1/tests/code/000077500000000000000000000000001266460524100145255ustar00rootroot00000000000000odil-0.4.1/tests/code/Association.cpp000066400000000000000000000103171266460524100175070ustar00rootroot00000000000000#define BOOST_TEST_MODULE Association #include #include #include "odil/Association.h" #include "odil/Exception.h" #include "odil/registry.h" #include "../PeerFixtureBase.h" namespace odil { bool operator==( AssociationParameters::PresentationContext const & left, AssociationParameters::PresentationContext const & right) { return ( left.abstract_syntax == right.abstract_syntax && left.transfer_syntaxes == right.transfer_syntaxes && left.scu_role_support == right.scu_role_support && left.scp_role_support == right.scp_role_support ); } bool operator==( AssociationParameters const & left, AssociationParameters const & right) { return ( left.get_calling_ae_title() == right.get_calling_ae_title() && left.get_called_ae_title() == right.get_called_ae_title() && left.get_presentation_contexts() == right.get_presentation_contexts() && left.get_user_identity().type == right.get_user_identity().type && left.get_user_identity().primary_field == right.get_user_identity().primary_field && left.get_user_identity().secondary_field == right.get_user_identity().secondary_field && left.get_maximum_length() == right.get_maximum_length() ); } } BOOST_AUTO_TEST_CASE(DefaultConstructor) { odil::Association association; BOOST_CHECK_EQUAL(association.get_peer_host(), ""); BOOST_CHECK_EQUAL(association.get_peer_port(), 104); BOOST_CHECK( association.get_parameters() == odil::AssociationParameters() ); BOOST_CHECK(!association.is_associated()); } BOOST_AUTO_TEST_CASE(CopyConstructor) { odil::Association association; association.set_peer_host("pacs.example.com"); association.set_peer_port(11112); association.update_parameters() .set_called_ae_title("remote") .set_user_identity_to_username_and_password("foo", "bar"); odil::Association const other(association); BOOST_CHECK_EQUAL(other.get_peer_host(), association.get_peer_host()); BOOST_CHECK_EQUAL(other.get_peer_port(), association.get_peer_port()); BOOST_CHECK( association.get_parameters() == other.get_parameters() ); } BOOST_AUTO_TEST_CASE(Assignment) { odil::Association association; association.set_peer_host("pacs.example.com"); association.set_peer_port(11112); association.update_parameters() .set_called_ae_title("remote") .set_user_identity_to_username_and_password("foo", "bar"); odil::Association other; other = association; BOOST_CHECK_EQUAL(other.get_peer_host(), association.get_peer_host()); BOOST_CHECK_EQUAL(other.get_peer_port(), association.get_peer_port()); BOOST_CHECK( association.get_parameters() == other.get_parameters() ); } BOOST_AUTO_TEST_CASE(PeerHostName) { odil::Association association; association.set_peer_host("pacs.example.com"); BOOST_CHECK_EQUAL(association.get_peer_host(), "pacs.example.com"); } BOOST_AUTO_TEST_CASE(PeerPort) { odil::Association association; association.set_peer_port(11112); BOOST_CHECK_EQUAL(association.get_peer_port(), 11112); } BOOST_AUTO_TEST_CASE(AssociationParameters) { odil::Association association; odil::AssociationParameters parameters; parameters.set_calling_ae_title("foo"); association.set_parameters(parameters); BOOST_REQUIRE(association.get_parameters() == parameters); } BOOST_AUTO_TEST_CASE(Associate) { PeerFixtureBase fixture({ { 1, odil::registry::VerificationSOPClass, { odil::registry::ImplicitVRLittleEndian }, true, false } }); BOOST_CHECK_THROW( fixture.association.set_peer_host("foo"), odil::Exception); BOOST_CHECK_THROW( fixture.association.set_peer_port(1234), odil::Exception); BOOST_CHECK_THROW( fixture.association.update_parameters().set_maximum_length(123), odil::Exception); } BOOST_AUTO_TEST_CASE(Release) { odil::Association association; BOOST_CHECK_THROW(association.release(), odil::Exception); } BOOST_AUTO_TEST_CASE(Abort) { odil::Association association; BOOST_CHECK_THROW(association.abort(2, 4), odil::Exception); } odil-0.4.1/tests/code/AssociationAcceptor.cpp000066400000000000000000000006651266460524100211750ustar00rootroot00000000000000#define BOOST_TEST_MODULE AssociationAcceptor #include #include "odil/AssociationAcceptor.h" BOOST_AUTO_TEST_CASE(AssociationRejected) { odil::AssociationRejected const exception(1, 2, 3, "foo"); BOOST_REQUIRE_EQUAL(exception.get_result(), 1); BOOST_REQUIRE_EQUAL(exception.get_source(), 2); BOOST_REQUIRE_EQUAL(exception.get_reason(), 3); BOOST_REQUIRE_EQUAL(exception.what(), "foo"); } odil-0.4.1/tests/code/AssociationParameters.cpp000066400000000000000000000147541266460524100215440ustar00rootroot00000000000000#define BOOST_TEST_MODULE AssociationParameters #include #include "odil/AssociationParameters.h" #include "odil/Exception.h" BOOST_AUTO_TEST_CASE(Constructor) { odil::AssociationParameters const parameters; BOOST_REQUIRE_EQUAL(parameters.get_called_ae_title(), ""); BOOST_REQUIRE_EQUAL(parameters.get_calling_ae_title(), ""); BOOST_REQUIRE(parameters.get_presentation_contexts().empty()); BOOST_REQUIRE( parameters.get_user_identity().type == odil::AssociationParameters::UserIdentity::Type::None); BOOST_REQUIRE(parameters.get_user_identity().primary_field.empty()); BOOST_REQUIRE(parameters.get_user_identity().secondary_field.empty()); BOOST_REQUIRE_EQUAL(parameters.get_maximum_length(), 16384); } BOOST_AUTO_TEST_CASE(CalledAETITLE) { odil::AssociationParameters parameters; parameters.set_called_ae_title("foo"); BOOST_REQUIRE_EQUAL(parameters.get_called_ae_title(), "foo"); } BOOST_AUTO_TEST_CASE(CalledAETITLETooLong) { odil::AssociationParameters parameters; BOOST_REQUIRE_THROW( parameters.set_called_ae_title("0123456789abcdefTOO_LONG"), odil::Exception); } BOOST_AUTO_TEST_CASE(CallingAETITLE) { odil::AssociationParameters parameters; parameters.set_calling_ae_title("foo"); BOOST_REQUIRE_EQUAL(parameters.get_calling_ae_title(), "foo"); } BOOST_AUTO_TEST_CASE(CallingAETITLETooLong) { odil::AssociationParameters parameters; BOOST_REQUIRE_THROW( parameters.set_calling_ae_title("0123456789abcdefTOO_LONG"), odil::Exception); } BOOST_AUTO_TEST_CASE(PresentationContexts) { odil::AssociationParameters parameters; parameters.set_presentation_contexts({ { 1, "abstract1", { "transfer1", "transfer2" }, true, false }, { 3, "abstract2", { "transfer3" }, false, true } }); BOOST_REQUIRE_EQUAL(parameters.get_presentation_contexts().size(), 2); BOOST_REQUIRE_EQUAL(parameters.get_presentation_contexts()[0].id, 1); BOOST_REQUIRE_EQUAL( parameters.get_presentation_contexts()[0].abstract_syntax, "abstract1"); BOOST_REQUIRE_EQUAL( parameters.get_presentation_contexts()[0].transfer_syntaxes.size(), 2); BOOST_REQUIRE_EQUAL( parameters.get_presentation_contexts()[0].transfer_syntaxes[0], "transfer1"); BOOST_REQUIRE_EQUAL( parameters.get_presentation_contexts()[0].transfer_syntaxes[1], "transfer2"); BOOST_REQUIRE(parameters.get_presentation_contexts()[0].scu_role_support); BOOST_REQUIRE(!parameters.get_presentation_contexts()[0].scp_role_support); BOOST_REQUIRE_EQUAL(parameters.get_presentation_contexts()[1].id, 3); BOOST_REQUIRE_EQUAL( parameters.get_presentation_contexts()[1].abstract_syntax, "abstract2"); BOOST_REQUIRE_EQUAL( parameters.get_presentation_contexts()[1].transfer_syntaxes.size(), 1); BOOST_REQUIRE_EQUAL( parameters.get_presentation_contexts()[1].transfer_syntaxes[0], "transfer3"); BOOST_REQUIRE(!parameters.get_presentation_contexts()[1].scu_role_support); BOOST_REQUIRE(parameters.get_presentation_contexts()[1].scp_role_support); } BOOST_AUTO_TEST_CASE(UserIdentityNone) { odil::AssociationParameters parameters; parameters.set_user_identity_to_username_and_password("foo", "bar"); parameters.set_user_identity_to_none(); BOOST_REQUIRE( parameters.get_user_identity().type == odil::AssociationParameters::UserIdentity::Type::None); BOOST_REQUIRE(parameters.get_user_identity().primary_field.empty()); BOOST_REQUIRE(parameters.get_user_identity().secondary_field.empty()); } BOOST_AUTO_TEST_CASE(UserIdentityUsername) { odil::AssociationParameters parameters; parameters.set_user_identity_to_username("foo"); BOOST_REQUIRE( parameters.get_user_identity().type == odil::AssociationParameters::UserIdentity::Type::Username); BOOST_REQUIRE_EQUAL(parameters.get_user_identity().primary_field, "foo"); BOOST_REQUIRE(parameters.get_user_identity().secondary_field.empty()); } BOOST_AUTO_TEST_CASE(UserIdentityUsernameAndPassword) { odil::AssociationParameters parameters; parameters.set_user_identity_to_username_and_password("foo", "bar"); BOOST_REQUIRE( parameters.get_user_identity().type == odil::AssociationParameters::UserIdentity::Type::UsernameAndPassword); BOOST_REQUIRE_EQUAL(parameters.get_user_identity().primary_field, "foo"); BOOST_REQUIRE_EQUAL(parameters.get_user_identity().secondary_field, "bar"); } BOOST_AUTO_TEST_CASE(UserIdentityKerberos) { odil::AssociationParameters parameters; parameters.set_user_identity_to_kerberos("foo"); BOOST_REQUIRE( parameters.get_user_identity().type == odil::AssociationParameters::UserIdentity::Type::Kerberos); BOOST_REQUIRE_EQUAL(parameters.get_user_identity().primary_field, "foo"); BOOST_REQUIRE(parameters.get_user_identity().secondary_field.empty()); } BOOST_AUTO_TEST_CASE(UserIdentitySAML) { odil::AssociationParameters parameters; parameters.set_user_identity_to_saml("foo"); BOOST_REQUIRE( parameters.get_user_identity().type == odil::AssociationParameters::UserIdentity::Type::SAML); BOOST_REQUIRE_EQUAL(parameters.get_user_identity().primary_field, "foo"); BOOST_REQUIRE(parameters.get_user_identity().secondary_field.empty()); } BOOST_AUTO_TEST_CASE(MaximumLength) { odil::AssociationParameters parameters; parameters.set_maximum_length(0x12345678); BOOST_REQUIRE_EQUAL(parameters.get_maximum_length(), 0x12345678); } BOOST_AUTO_TEST_CASE(ChainedSetters) { odil::AssociationParameters parameters; parameters .set_called_ae_title("called") .set_calling_ae_title("calling") .set_presentation_contexts({ { 1, "abstract", { "transfer" }, true, true } }) .set_user_identity_to_username_and_password("foo", "bar") .set_maximum_length(0x12345678); BOOST_REQUIRE_EQUAL(parameters.get_called_ae_title(), "called"); BOOST_REQUIRE_EQUAL(parameters.get_calling_ae_title(), "calling"); BOOST_REQUIRE_EQUAL(parameters.get_presentation_contexts().size(), 1); BOOST_REQUIRE( parameters.get_user_identity().type == odil::AssociationParameters::UserIdentity::Type::UsernameAndPassword); BOOST_REQUIRE_EQUAL(parameters.get_user_identity().primary_field, "foo"); BOOST_REQUIRE_EQUAL(parameters.get_user_identity().secondary_field, "bar"); BOOST_REQUIRE_EQUAL(parameters.get_maximum_length(), 0x12345678); } odil-0.4.1/tests/code/BasicDirectoryCreator.cpp000066400000000000000000000126671266460524100214730ustar00rootroot00000000000000#define BOOST_TEST_MODULE BasicDirectoryCreator #include #include #include "odil/BasicDirectoryCreator.h" #include "odil/json_converter.h" #include "odil/Reader.h" #include "odil/registry.h" #include "odil/Writer.h" #include #include BOOST_AUTO_TEST_CASE(DefaultConstructor) { odil::BasicDirectoryCreator const creator; BOOST_REQUIRE_EQUAL(creator.root.empty(), true); BOOST_REQUIRE_EQUAL(creator.files.empty(), true); BOOST_REQUIRE_EQUAL(creator.extra_record_keys.empty(), true); BOOST_REQUIRE( creator.item_encoding == odil::Writer::ItemEncoding::ExplicitLength); } BOOST_AUTO_TEST_CASE(Constructor) { odil::BasicDirectoryCreator::RecordKeyMap const extra_records( { { "PATIENT", { {odil::registry::PatientBirthDate, 1}, {odil::registry::OtherPatientIDs, 3}, } } }); odil::BasicDirectoryCreator const creator( "root", {"a.dcm", "b.dcm"}, extra_records, odil::Writer::ItemEncoding::UndefinedLength); BOOST_REQUIRE_EQUAL(creator.root, "root"); BOOST_REQUIRE( creator.files == std::vector({"a.dcm", "b.dcm"})); BOOST_REQUIRE( creator.extra_record_keys == extra_records); BOOST_REQUIRE( creator.item_encoding == odil::Writer::ItemEncoding::UndefinedLength); } BOOST_AUTO_TEST_CASE(BasicDirectory) { std::stringstream stream1; stream1 << "{"; { odil::DataSet data_set; data_set.add("PatientID", {"DJ123"}); data_set.add("StudyDate", {"19100110"}); data_set.add("StudyTime", {"1234"}); data_set.add("StudyDescription", {"Study"}); data_set.add("StudyInstanceUID", {"1.2.3.4"}); data_set.add("StudyID", {"FOO"}); data_set.add("Modality", {"OT"}); data_set.add("SeriesInstanceUID", {"1.2.3.4.1"}); data_set.add("SeriesNumber", {1}); data_set.add("SeriesDescription", {"Series"}); data_set.add("InstanceNumber", {1}); data_set.add("SOPInstanceUID", {"1.2.3.4.1.1"}); data_set.add("SOPClassUID", {odil::registry::RawDataStorage}); std::ofstream stream("a.dcm"); odil::Writer::write_file(data_set, stream); } { odil::DataSet data_set; data_set.add("PatientID", {"DJ123"}); data_set.add("StudyDate", {"19100110"}); data_set.add("StudyTime", {"1234"}); data_set.add("StudyDescription", {"Study"}); data_set.add("StudyInstanceUID", {"1.2.3.4"}); data_set.add("StudyID", {"FOO"}); data_set.add("Modality", {"OT"}); data_set.add("SeriesInstanceUID", {"1.2.3.4.1"}); data_set.add("SeriesNumber", {1}); data_set.add("SeriesDescription", {"Series"}); data_set.add("InstanceNumber", {2}); data_set.add("SOPInstanceUID", {"1.2.3.4.1.2"}); data_set.add("SOPClassUID", {odil::registry::RawDataStorage}); std::ofstream stream("b.dcm"); odil::Writer::write_file(data_set, stream); } odil::BasicDirectoryCreator::RecordKeyMap const extra_records( { { "SERIES", { {odil::registry::SeriesDescription, 1} } } }); odil::BasicDirectoryCreator const creator( ".", {"a.dcm", "b.dcm"}, extra_records); creator(); boost::filesystem::ifstream stream(boost::filesystem::path(".")/"DICOMDIR"); auto const dicomdir_and_header = odil::Reader::read_file(stream); BOOST_REQUIRE( dicomdir_and_header.first.as_string("MediaStorageSOPClassUID") == odil::Value::Strings({odil::registry::MediaStorageDirectoryStorage})); BOOST_REQUIRE( dicomdir_and_header.first.as_string("TransferSyntaxUID") == odil::Value::Strings({odil::registry::ExplicitVRLittleEndian})); auto const & records = dicomdir_and_header.second.as_data_set("DirectoryRecordSequence"); BOOST_REQUIRE_EQUAL(records.size(), 5); BOOST_REQUIRE( records[0].as_string("DirectoryRecordType") == odil::Value::Strings({"PATIENT"})); BOOST_REQUIRE( records[0].as_string("PatientID") == odil::Value::Strings({"DJ123"})); BOOST_REQUIRE( records[1].as_string("DirectoryRecordType") == odil::Value::Strings({"STUDY"})); BOOST_REQUIRE( records[1].as_string("StudyInstanceUID") == odil::Value::Strings({"1.2.3.4"})); BOOST_REQUIRE( records[1].as_string("StudyDescription") == odil::Value::Strings({"Study"})); BOOST_REQUIRE( records[2].as_string("DirectoryRecordType") == odil::Value::Strings({"SERIES"})); BOOST_REQUIRE( records[2].as_string("SeriesInstanceUID") == odil::Value::Strings({"1.2.3.4.1"})); BOOST_REQUIRE( records[2].as_string("SeriesDescription") == odil::Value::Strings({"Series"})); BOOST_REQUIRE( records[3].as_string("DirectoryRecordType") == odil::Value::Strings({"IMAGE"})); BOOST_REQUIRE( records[3].as_int("InstanceNumber") == odil::Value::Integers({1})); BOOST_REQUIRE( records[4].as_string("DirectoryRecordType") == odil::Value::Strings({"IMAGE"})); BOOST_REQUIRE( records[4].as_int("InstanceNumber") == odil::Value::Integers({2})); boost::filesystem::remove("a.dcm"); boost::filesystem::remove("b.dcm"); } odil-0.4.1/tests/code/DataSet.cpp000066400000000000000000000245571266460524100165730ustar00rootroot00000000000000#define BOOST_TEST_MODULE DataSet #include #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/Tag.h" #include "odil/VR.h" #include "odil/registry.h" BOOST_AUTO_TEST_CASE(Empty) { odil::DataSet dataset; BOOST_CHECK(dataset.empty()); BOOST_CHECK_EQUAL(dataset.size(), 0); BOOST_CHECK(!dataset.has(odil::Tag("PatientName"))); } BOOST_AUTO_TEST_CASE(AddExplicitVR) { odil::Tag const tag("PatientName"); odil::DataSet dataset; dataset.add(tag, odil::VR::PN); BOOST_CHECK(!dataset.empty()); BOOST_CHECK_EQUAL(dataset.size(), 1); BOOST_CHECK(dataset.has(tag)); BOOST_CHECK(dataset.get_vr(tag) == odil::VR::PN); } BOOST_AUTO_TEST_CASE(AddImplicitVR) { odil::Tag const tag("PatientName"); odil::DataSet dataset; dataset.add(tag); BOOST_CHECK(!dataset.empty()); BOOST_CHECK_EQUAL(dataset.size(), 1); BOOST_CHECK(dataset.has(tag)); BOOST_CHECK(dataset.get_vr(tag) == odil::VR::PN); } BOOST_AUTO_TEST_CASE(AddValueExplicitVR) { odil::Tag const tag("PatientName"); odil::DataSet dataset; dataset.add(tag, { "Doe^John"}, odil::VR::PN); BOOST_CHECK(!dataset.empty()); BOOST_CHECK_EQUAL(dataset.size(), 1); BOOST_CHECK(dataset.has(tag)); BOOST_CHECK(dataset.get_vr(tag) == odil::VR::PN); BOOST_CHECK(dataset.as_string(tag) == odil::Value::Strings({ "Doe^John" })); } BOOST_AUTO_TEST_CASE(AddValueImplicitVR) { odil::Tag const tag("PatientName"); odil::DataSet dataset; dataset.add(tag, { "Doe^John"}); BOOST_CHECK(!dataset.empty()); BOOST_CHECK_EQUAL(dataset.size(), 1); BOOST_CHECK(dataset.has(tag)); BOOST_CHECK(dataset.get_vr(tag) == odil::VR::PN); BOOST_CHECK(dataset.as_string(tag) == odil::Value::Strings({ "Doe^John" })); } BOOST_AUTO_TEST_CASE(AddInvalidTag) { odil::Tag const tag(0xdead, 0xbeef); odil::DataSet dataset; BOOST_CHECK_THROW(dataset.add(tag), odil::Exception); } BOOST_AUTO_TEST_CASE(AddIntEmpty) { odil::Tag const tag("Rows"); odil::DataSet dataset; dataset.add(tag); BOOST_CHECK(dataset.is_int(tag)); BOOST_CHECK(dataset.empty(tag)); BOOST_CHECK_EQUAL(dataset.size(tag), 0); std::vector const & value = dataset.as_int(tag); BOOST_CHECK(value.empty()); } BOOST_AUTO_TEST_CASE(AddDoubleEmpty) { odil::Tag const tag("SpacingBetweenSlices"); odil::DataSet dataset; dataset.add(tag); BOOST_CHECK(dataset.is_real(tag)); BOOST_CHECK(dataset.empty(tag)); BOOST_CHECK_EQUAL(dataset.size(tag), 0); std::vector const & value = dataset.as_real(tag); BOOST_CHECK(value.empty()); } BOOST_AUTO_TEST_CASE(AddStringEmpty) { odil::Tag const tag("PatientID"); odil::DataSet dataset; dataset.add(tag); BOOST_CHECK(dataset.is_string(tag)); BOOST_CHECK(dataset.empty(tag)); BOOST_CHECK_EQUAL(dataset.size(tag), 0); std::vector const & value = dataset.as_string(tag); BOOST_CHECK(value.empty()); } BOOST_AUTO_TEST_CASE(AddDataSetEmpty) { odil::Tag const tag("ReferencedStudySequence"); odil::DataSet dataset; dataset.add(tag); BOOST_CHECK(dataset.is_data_set(tag)); BOOST_CHECK(dataset.empty(tag)); BOOST_CHECK_EQUAL(dataset.size(tag), 0); odil::Value::DataSets const & value = dataset.as_data_set(tag); BOOST_CHECK(value.empty()); } BOOST_AUTO_TEST_CASE(AddBinaryEmpty) { odil::Tag const tag("BadPixelImage"); odil::DataSet dataset; dataset.add(tag); BOOST_CHECK(dataset.is_binary(tag)); BOOST_CHECK(dataset.empty(tag)); BOOST_CHECK_EQUAL(dataset.size(tag), 0); auto const & value = dataset.as_binary(tag); BOOST_CHECK(value.empty()); } BOOST_AUTO_TEST_CASE(AddInt) { odil::Tag const tag("Rows"); odil::DataSet dataset; dataset.add(tag, odil::Value::Integers({123})); BOOST_CHECK(dataset.is_int(tag)); BOOST_REQUIRE_EQUAL(dataset.size(tag), 1); BOOST_REQUIRE(dataset.as_int(tag) == odil::Value::Integers({123})); } BOOST_AUTO_TEST_CASE(AddDouble) { odil::Tag const tag("SpacingBetweenSlices"); odil::DataSet dataset; dataset.add(tag, odil::Value::Reals({123.456})); BOOST_CHECK(dataset.is_real(tag)); BOOST_REQUIRE_EQUAL(dataset.size(tag), 1); BOOST_REQUIRE(dataset.as_real(tag) == odil::Value::Reals({123.456})); } BOOST_AUTO_TEST_CASE(AddString) { odil::Tag const tag("PatientID"); odil::DataSet dataset; dataset.add(tag, odil::Value::Strings({"DJ123"})); BOOST_CHECK(dataset.is_string(tag)); BOOST_REQUIRE_EQUAL(dataset.size(tag), 1); BOOST_REQUIRE(dataset.as_string(tag) == odil::Value::Strings({"DJ123"})); } BOOST_AUTO_TEST_CASE(AddDataSet) { odil::Tag const tag("ReferencedStudySequence"); odil::DataSet item; item.add(odil::registry::StudyInstanceUID, {"1.2.3"}); odil::DataSet dataset; dataset.add(tag, odil::Value::DataSets({item})); BOOST_CHECK(dataset.is_data_set(tag)); BOOST_REQUIRE_EQUAL(dataset.size(tag), 1); BOOST_REQUIRE(dataset.as_data_set(tag, 0) == item); } BOOST_AUTO_TEST_CASE(AddIntInitializer1) { odil::Tag const tag("Rows"); odil::DataSet dataset; dataset.add(tag, {123}); BOOST_CHECK(dataset.is_int(tag)); BOOST_REQUIRE_EQUAL(dataset.size(tag), 1); BOOST_REQUIRE(dataset.as_int(tag) == odil::Value::Integers({123})); } BOOST_AUTO_TEST_CASE(AddIntInitializer2) { odil::Tag const tag("Rows"); odil::DataSet dataset; dataset.add(tag, {odil::Value::Integer(123)}); BOOST_CHECK(dataset.is_int(tag)); BOOST_REQUIRE_EQUAL(dataset.size(tag), 1); BOOST_REQUIRE(dataset.as_int(tag) == odil::Value::Integers({123})); } BOOST_AUTO_TEST_CASE(AddDoubleInitializer) { odil::Tag const tag("SpacingBetweenSlices"); odil::DataSet dataset; dataset.add(tag, {123.456}); BOOST_CHECK(dataset.is_real(tag)); BOOST_REQUIRE_EQUAL(dataset.size(tag), 1); BOOST_REQUIRE(dataset.as_real(tag) == odil::Value::Reals({123.456})); } BOOST_AUTO_TEST_CASE(AddStringInitializer) { odil::Tag const tag("PatientID"); odil::DataSet dataset; dataset.add(tag, {"DJ123"}); BOOST_CHECK(dataset.is_string(tag)); BOOST_REQUIRE_EQUAL(dataset.size(tag), 1); BOOST_REQUIRE(dataset.as_string(tag) == odil::Value::Strings({"DJ123"})); } BOOST_AUTO_TEST_CASE(AddDataSetInitializer) { odil::Tag const tag("ReferencedStudySequence"); odil::DataSet item; item.add(odil::registry::StudyInstanceUID, {"1.2.3"}); odil::DataSet dataset; dataset.add(tag, {item}); BOOST_CHECK(dataset.is_data_set(tag)); BOOST_REQUIRE_EQUAL(dataset.size(tag), 1); BOOST_REQUIRE(dataset.as_data_set(tag, 0) == item); } BOOST_AUTO_TEST_CASE(AddBinary) { odil::Tag const tag("BadPixelImage"); odil::DataSet dataset; dataset.add(tag, odil::Value::Binary({0x01, 0x02})); BOOST_CHECK(dataset.is_binary(tag)); BOOST_REQUIRE_EQUAL(dataset.size(tag), 2); BOOST_REQUIRE( dataset.as_binary(tag) == odil::Value::Binary({ 0x01, 0x02 })); } BOOST_AUTO_TEST_CASE(ModifyInt) { odil::Tag const tag("Rows"); odil::DataSet dataset; dataset.add(tag); dataset.as_int(tag).push_back(256); BOOST_CHECK(!dataset.empty(tag)); BOOST_CHECK_EQUAL(dataset.size(tag), 1); BOOST_CHECK_EQUAL(dataset.as_int(tag, 0), 256); } BOOST_AUTO_TEST_CASE(ModifyDouble) { odil::Tag const tag("SpacingBetweenSlices"); odil::DataSet dataset; dataset.add(tag); dataset.as_real(tag).push_back(3.14); BOOST_CHECK(!dataset.empty(tag)); BOOST_CHECK_EQUAL(dataset.size(tag), 1); BOOST_CHECK_EQUAL(dataset.as_real(tag, 0), 3.14); } BOOST_AUTO_TEST_CASE(ModifyString) { odil::Tag const tag("PatientID"); odil::DataSet dataset; dataset.add(tag); dataset.as_string(tag).push_back("FooBar"); BOOST_CHECK(!dataset.empty(tag)); BOOST_CHECK_EQUAL(dataset.size(tag), 1); BOOST_CHECK_EQUAL(dataset.as_string(tag, 0), "FooBar"); } BOOST_AUTO_TEST_CASE(ModifyDataSet) { odil::Tag const tag("ReferencedStudySequence"); odil::DataSet dataset; dataset.add(tag); odil::DataSet item; item.add("PatientID", {"DJ1234"}); dataset.as_data_set(tag).push_back(item); BOOST_CHECK(!dataset.empty(tag)); BOOST_CHECK_EQUAL(dataset.size(tag), 1); odil::Value::DataSets const & value = dataset.as_data_set(tag); BOOST_CHECK_EQUAL(value.size(), 1); BOOST_CHECK_EQUAL(value.size(), 1); BOOST_CHECK_EQUAL(value[0].size(), 1); BOOST_CHECK(value[0].has("PatientID")); BOOST_CHECK( value[0].as_string("PatientID") == odil::Value::Strings({"DJ1234"})); } BOOST_AUTO_TEST_CASE(ElementAccessor) { odil::Tag const tag("PatientID"); odil::DataSet dataset; dataset.add(tag, {"Foo^Bar"}); BOOST_REQUIRE( dataset[tag].as_string() == odil::Value::Strings({"Foo^Bar"})); BOOST_REQUIRE_THROW( dataset[odil::registry::PatientName], odil::Exception); } BOOST_AUTO_TEST_CASE(GetVRMissing) { odil::Tag const tag("PatientID"); odil::DataSet dataset; BOOST_CHECK_THROW(dataset.get_vr(tag), odil::Exception); } BOOST_AUTO_TEST_CASE(TestEmptyMissing) { odil::Tag const tag("PatientID"); odil::DataSet dataset; BOOST_CHECK_THROW(dataset.empty(tag), odil::Exception); } BOOST_AUTO_TEST_CASE(SizeMissing) { odil::Tag const tag("PatientID"); odil::DataSet dataset; BOOST_CHECK_THROW(dataset.size(tag), odil::Exception); } BOOST_AUTO_TEST_CASE(Remove) { odil::Tag const tag("PatientID"); odil::DataSet dataset; dataset.add(tag); dataset.remove(tag); BOOST_CHECK(!dataset.has(tag)); } BOOST_AUTO_TEST_CASE(RemoveMissing) { odil::Tag const tag("PatientID"); odil::DataSet dataset; dataset.add(tag); odil::Tag const other("PatientName"); BOOST_CHECK_THROW( dataset.remove(other), odil::Exception); } BOOST_AUTO_TEST_CASE(Equality) { odil::DataSet dataset1; dataset1.add("PatientID", {"DJ1234"}); odil::DataSet dataset2; dataset2.add("PatientID", {"DJ1234"}); odil::DataSet dataset3; dataset3.add("PatientAge", {"042Y"}); BOOST_CHECK(dataset1 == dataset2); BOOST_CHECK(! (dataset1 == dataset3)); } BOOST_AUTO_TEST_CASE(Difference) { odil::DataSet dataset1; dataset1.add("PatientID", {"DJ1234"}); odil::DataSet dataset2; dataset2.add("PatientID", {"DJ1234"}); odil::DataSet dataset3; dataset3.add("PatientAge", {"042Y"}); BOOST_CHECK(! (dataset1 != dataset2)); BOOST_CHECK(dataset1 != dataset3); } odil-0.4.1/tests/code/DcmtkException.cpp000066400000000000000000000015451266460524100201570ustar00rootroot00000000000000#define BOOST_TEST_MODULE DcmtkException #include #include #include #include "odil/dcmtk/Exception.h" BOOST_AUTO_TEST_CASE(StringConstructor) { odil::dcmtk::Exception const exception("foo"); BOOST_REQUIRE( exception.get_source() == odil::dcmtk::Exception::Source::Message); BOOST_REQUIRE_EQUAL(exception.what(), "foo"); BOOST_REQUIRE_THROW(exception.get_condition(), odil::dcmtk::Exception); } BOOST_AUTO_TEST_CASE(ConditionConstructor) { odil::dcmtk::Exception const exception(EC_IllegalParameter); BOOST_REQUIRE( exception.get_source() == odil::dcmtk::Exception::Source::Condition); BOOST_REQUIRE_EQUAL( exception.what(), OFCondition(EC_IllegalParameter).text()); BOOST_REQUIRE(exception.get_condition() == EC_IllegalParameter); } odil-0.4.1/tests/code/EchoSCP.cpp000066400000000000000000000055471266460524100164700ustar00rootroot00000000000000#define BOOST_TEST_MODULE EchoSCP #include #include #include #include #include #include "odil/Association.h" #include "odil/EchoSCP.h" #include "odil/Exception.h" #include "odil/message/CEchoRequest.h" #include "odil/message/Response.h" struct Status { int client; std::string server; bool called; }; void run_server(Status * status) { odil::Association association; association.set_tcp_timeout(boost::posix_time::seconds(1)); try { association.receive_association(boost::asio::ip::tcp::v4(), 11113); odil::EchoSCP echo_scp(association, [status](odil::message::CEchoRequest const &) { status->called = true; return odil::message::Response::Success; }); // Get echo message auto const message = association.receive_message(); echo_scp(message); // Should throw with peer closing connection association.receive_message(); } catch(odil::AssociationAborted const &) { status->server = "abort"; } catch(odil::AssociationReleased const &) { status->server = "release"; } catch(odil::Exception const &) { status->server = "Other Odil exception"; } catch(...) { status->server = "Other exception"; } } void run_client(Status * status, bool use_abort) { std::string command = "echoscu"; if(use_abort) { command += " --abort"; } command += " 127.0.0.1 11113"; status->client = system(command.c_str()); } BOOST_AUTO_TEST_CASE(Callback) { odil::Association association; odil::EchoSCP scp(association); bool called = false; auto const callback = [&called](odil::message::CEchoRequest const &) { called = true; return odil::message::Response::Success; }; scp.set_callback(callback); scp.get_callback()(odil::message::CEchoRequest(1, "")); BOOST_REQUIRE_EQUAL(called, true); } BOOST_AUTO_TEST_CASE(Release) { Status status = { -1, "", false }; std::thread server(run_server, &status); std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::thread client(run_client, &status, false); server.join(); client.join(); BOOST_REQUIRE_EQUAL(status.client, 0); BOOST_REQUIRE_EQUAL(status.server, "release"); BOOST_REQUIRE_EQUAL(status.called, true); } BOOST_AUTO_TEST_CASE(Abort) { Status status = { -1, "", false }; std::thread server(run_server, &status); std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::thread client(run_client, &status, true); server.join(); client.join(); BOOST_REQUIRE_EQUAL(status.client, 0); BOOST_REQUIRE_EQUAL(status.server, "abort"); BOOST_REQUIRE_EQUAL(status.called, true); } odil-0.4.1/tests/code/Element.cpp000066400000000000000000000114041266460524100166220ustar00rootroot00000000000000#define BOOST_TEST_MODULE Element #include #include "odil/DataSet.h" #include "odil/Element.h" #include "odil/Exception.h" BOOST_AUTO_TEST_CASE(Empty) { odil::Element element; BOOST_CHECK(element.empty()); BOOST_CHECK_EQUAL(element.size(), 0); } BOOST_AUTO_TEST_CASE(Int) { odil::Element const element((odil::Value::Integers())); BOOST_CHECK(element.is_int()); std::vector const & value = element.as_int(); BOOST_CHECK(value.empty()); } BOOST_AUTO_TEST_CASE(ModifyInt) { odil::Element element({0}); element.as_int().push_back(1); BOOST_CHECK(!element.empty()); BOOST_CHECK_EQUAL(element.size(), 2); std::vector const & value = element.as_int(); BOOST_CHECK(value == odil::Value::Integers({0, 1})); } BOOST_AUTO_TEST_CASE(ModifyInt2) { odil::Element element({odil::Value::Integer(0)}); element.as_int().push_back(1); BOOST_CHECK(!element.empty()); BOOST_CHECK_EQUAL(element.size(), 2); std::vector const & value = element.as_int(); BOOST_CHECK(value == odil::Value::Integers({0, 1})); } BOOST_AUTO_TEST_CASE(IntWrong) { odil::Element element((odil::Value::Integers())); BOOST_CHECK_THROW(element.as_real(), odil::Exception); BOOST_CHECK_THROW(element.as_string(), odil::Exception); } BOOST_AUTO_TEST_CASE(Double) { odil::Element const element((odil::Value::Reals())); BOOST_CHECK(element.is_real()); std::vector const & value = element.as_real(); BOOST_CHECK(value.empty()); } BOOST_AUTO_TEST_CASE(ModifyDouble) { odil::Element element({0.}); element.as_real().push_back(1.5); BOOST_CHECK(!element.empty()); BOOST_CHECK_EQUAL(element.size(), 2); std::vector const & value = element.as_real(); BOOST_CHECK(value == odil::Value::Reals({0., 1.5})); } BOOST_AUTO_TEST_CASE(DoubleWrong) { odil::Element element((odil::Value::Reals())); BOOST_CHECK_THROW(element.as_int(), odil::Exception); BOOST_CHECK_THROW(element.as_string(), odil::Exception); BOOST_CHECK_THROW(element.as_data_set(), odil::Exception); } BOOST_AUTO_TEST_CASE(String) { odil::Element const element((odil::Value::Strings())); BOOST_CHECK(element.is_string()); std::vector const & value = element.as_string(); BOOST_CHECK(value.empty()); } BOOST_AUTO_TEST_CASE(ModifyString) { odil::Element element({""}); element.as_string().push_back("foo"); BOOST_CHECK(!element.empty()); BOOST_CHECK_EQUAL(element.size(), 2); std::vector const & value = element.as_string(); BOOST_CHECK(value == odil::Value::Strings({"", "foo"})); } BOOST_AUTO_TEST_CASE(StringWrong) { odil::Element element((odil::Value::Strings())); BOOST_CHECK_THROW(element.as_int(), odil::Exception); BOOST_CHECK_THROW(element.as_real(), odil::Exception); BOOST_CHECK_THROW(element.as_data_set(), odil::Exception); } BOOST_AUTO_TEST_CASE(DataSet) { odil::Element const element((odil::Value::DataSets())); BOOST_CHECK(element.is_data_set()); odil::Value::DataSets const & value = element.as_data_set(); BOOST_CHECK(value.empty()); } BOOST_AUTO_TEST_CASE(ModifyDataSet) { odil::Element element((odil::Value::DataSets())); odil::DataSet data_set; data_set.add("PatientID"); data_set.as_string("PatientID").push_back("DJ1234"); element.as_data_set().push_back(data_set); BOOST_CHECK(!element.empty()); BOOST_CHECK_EQUAL(element.size(), 1); odil::Value::DataSets const & value = element.as_data_set(); BOOST_CHECK_EQUAL(value.size(), 1); BOOST_CHECK_EQUAL(value[0].size(), 1); BOOST_CHECK(value[0].has("PatientID")); BOOST_CHECK( value[0].as_string("PatientID") == odil::Value::Strings({"DJ1234"})); } BOOST_AUTO_TEST_CASE(DataSetWrong) { odil::Element element((odil::Value::DataSets())); BOOST_CHECK_THROW(element.as_int(), odil::Exception); BOOST_CHECK_THROW(element.as_real(), odil::Exception); BOOST_CHECK_THROW(element.as_string(), odil::Exception); } BOOST_AUTO_TEST_CASE(Equality) { odil::Element const element1({12,34}, odil::VR::US); odil::Element const element2({12,34}, odil::VR::US); odil::Element const element3({12.,34.}, odil::VR::FL); odil::Element const element4({12,34}, odil::VR::UL); BOOST_CHECK(element1 == element2); BOOST_CHECK(! (element1 == element3)); BOOST_CHECK(! (element1 == element4)); } BOOST_AUTO_TEST_CASE(Difference) { odil::Element const element1({12,34}, odil::VR::US); odil::Element const element2({12,34}, odil::VR::US); odil::Element const element3({12.,34.}, odil::VR::FL); odil::Element const element4({12,34}, odil::VR::UL); BOOST_CHECK(! (element1 != element2)); BOOST_CHECK(element1 != element3); BOOST_CHECK(element1 != element4); } odil-0.4.1/tests/code/ElementAccessor.cpp000066400000000000000000000065721266460524100203170ustar00rootroot00000000000000#define BOOST_TEST_MODULE ElementAccessor #include #include #include #include #include #include "odil/dcmtk/ElementAccessor.h" #include "odil/dcmtk/VRTraits.h" struct Fixture { DcmDataset dataset; Fixture() { OFCondition condition; condition = dataset.putAndInsertOFStringArray(DCM_PatientID, "DJ123"); if(condition.bad()) { throw odil::dcmtk::Exception(condition); } condition = dataset.putAndInsertUint16(DCM_MessageID, 1234); if(condition.bad()) { throw odil::dcmtk::Exception(condition); } } }; BOOST_FIXTURE_TEST_CASE(GetCorrectTypeString, Fixture) { BOOST_CHECK_EQUAL( odil::dcmtk::ElementAccessor::get(this->dataset, DCM_PatientID), "DJ123"); } BOOST_FIXTURE_TEST_CASE(GetCorrectVRString, Fixture) { BOOST_CHECK_EQUAL( odil::dcmtk::ElementAccessor< typename odil::dcmtk::VRTraits::ValueType >::get(this->dataset, DCM_PatientID), "DJ123"); } BOOST_FIXTURE_TEST_CASE(GetCorrectTypeNonString, Fixture) { BOOST_CHECK_EQUAL( odil::dcmtk::ElementAccessor::get(this->dataset, DCM_MessageID), 1234); } BOOST_FIXTURE_TEST_CASE(GetCorrectVRNonString, Fixture) { BOOST_CHECK_EQUAL( odil::dcmtk::ElementAccessor< typename odil::dcmtk::VRTraits::ValueType >::get(this->dataset, DCM_MessageID), 1234); } BOOST_FIXTURE_TEST_CASE(GetWrongTypeString, Fixture) { BOOST_CHECK_THROW( odil::dcmtk::ElementAccessor::get(this->dataset, DCM_PatientID), odil::dcmtk::Exception); } BOOST_FIXTURE_TEST_CASE(GetWrongTypeNonString, Fixture) { BOOST_CHECK_THROW( odil::dcmtk::ElementAccessor::get(this->dataset, DCM_MessageID), odil::dcmtk::Exception); } BOOST_FIXTURE_TEST_CASE(SetEmpty, Fixture) { odil::dcmtk::ElementAccessor::set(this->dataset, DCM_PatientName, "FOO"); OFString value; OFCondition const condition = this->dataset.findAndGetOFString(DCM_PatientName, value); BOOST_REQUIRE(condition.good()); BOOST_CHECK_EQUAL(std::string(value.c_str()), "FOO"); } BOOST_FIXTURE_TEST_CASE(SetWrongTypeString, Fixture) { BOOST_CHECK_THROW( odil::dcmtk::ElementAccessor::set( this->dataset, DCM_PatientName, 1.234), odil::dcmtk::Exception); } BOOST_FIXTURE_TEST_CASE(SetWrongTypeNonString, Fixture) { BOOST_CHECK_THROW( odil::dcmtk::ElementAccessor::set( this->dataset, DCM_Status, STATUS_Success), odil::dcmtk::Exception); } BOOST_FIXTURE_TEST_CASE(SetExisting, Fixture) { odil::dcmtk::ElementAccessor::set(this->dataset, DCM_PatientID, "FOO"); OFString value; OFCondition const condition = this->dataset.findAndGetOFString(DCM_PatientID, value); BOOST_REQUIRE(condition.good()); BOOST_CHECK_EQUAL(std::string(value.c_str()), "FOO"); } BOOST_FIXTURE_TEST_CASE(Has, Fixture) { BOOST_CHECK( odil::dcmtk::ElementAccessor::has(this->dataset, DCM_PatientID)); } BOOST_FIXTURE_TEST_CASE(HasNot, Fixture) { BOOST_CHECK( !odil::dcmtk::ElementAccessor::has(this->dataset, DCM_PatientName)); } odil-0.4.1/tests/code/Exception.cpp000066400000000000000000000003501266460524100171650ustar00rootroot00000000000000#define BOOST_TEST_MODULE Exception #include #include "odil/Exception.h" BOOST_AUTO_TEST_CASE(Exception) { odil::Exception const exception("foo"); BOOST_REQUIRE_EQUAL(exception.what(), "foo"); } odil-0.4.1/tests/code/FindSCP.cpp000066400000000000000000000103271266460524100164620ustar00rootroot00000000000000#define BOOST_TEST_MODULE FindSCP #include #include #include #include #include #include #include #include #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/FindSCP.h" #include "odil/Exception.h" #include "odil/SCP.h" #include "odil/Reader.h" #include "odil/message/Response.h" struct Status { int client; std::string server; std::vector responses; }; class Generator: public odil::SCP::DataSetGenerator { public: Generator() { // Nothing else. } virtual ~Generator() { // Nothing to do. } virtual void initialize(odil::message::Request const & ) { odil::DataSet data_set_1; data_set_1.add(odil::registry::PatientName, {"Hello^World"}); data_set_1.add(odil::registry::PatientID, {"1234"}); this->_responses.push_back(data_set_1); odil::DataSet data_set_2; data_set_2.add(odil::registry::PatientName, {"Doe^John"}); data_set_2.add(odil::registry::PatientID, {"5678"}); this->_responses.push_back(data_set_2); this->_response_iterator = this->_responses.begin(); } virtual bool done() const { return (this->_response_iterator == this->_responses.end()); } virtual odil::DataSet get() const { return *this->_response_iterator; } virtual void next() { ++this->_response_iterator; } private: std::vector _responses; std::vector::const_iterator _response_iterator; }; void run_server(Status * status) { odil::Association association; association.set_tcp_timeout(boost::posix_time::seconds(1)); try { association.receive_association(boost::asio::ip::tcp::v4(), 11113); odil::FindSCP find_scp(association); auto const generator = std::make_shared(); find_scp.set_generator(generator); // Get echo message auto const message = association.receive_message(); find_scp(message); // Should throw with peer closing connection association.receive_message(); } catch(odil::AssociationAborted const &) { status->server = "abort"; } catch(odil::AssociationReleased const &) { status->server = "release"; } catch(odil::Exception const &) { status->server = "Other Odil exception"; } catch(...) { status->server = "Other exception"; } } void run_client(Status * status) { std::string command = "findscu " "-P -k QueryRetrieveLevel=PATIENT " "-k PatientID=* -k PatientName " "-q -X " "127.0.0.1 11113"; status->client = system(command.c_str()); boost::filesystem::directory_iterator end; for(boost::filesystem::directory_iterator it("."); it != end; ++it ) { if(!boost::filesystem::is_regular_file(it->status())) { continue; } auto const filename = it->path().stem().string(); if(filename.substr(0, 3) != "rsp") { continue; } std::ifstream stream(it->path().string()); auto const data_set = odil::Reader::read_file(stream).second; status->responses.push_back(data_set); boost::filesystem::remove(it->path()); } } BOOST_AUTO_TEST_CASE(Release) { Status status = { -1, "", {} }; std::thread server(run_server, &status); std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::thread client(run_client, &status); server.join(); client.join(); BOOST_REQUIRE_EQUAL(status.client, 0); BOOST_REQUIRE_EQUAL(status.server, "release"); BOOST_REQUIRE_EQUAL(status.responses.size(), 2); BOOST_REQUIRE_EQUAL(status.responses[0].size(), 2); BOOST_REQUIRE_EQUAL(status.responses[0].as_string("PatientName", 0), "Hello^World"); BOOST_REQUIRE_EQUAL(status.responses[0].as_string("PatientID", 0), "1234"); BOOST_REQUIRE_EQUAL(status.responses[1].size(), 2); BOOST_REQUIRE_EQUAL(status.responses[1].as_string("PatientName", 0), "Doe^John"); BOOST_REQUIRE_EQUAL(status.responses[1].as_string("PatientID", 0), "5678"); } odil-0.4.1/tests/code/FindSCU.cpp000066400000000000000000000027141266460524100164700ustar00rootroot00000000000000#define BOOST_TEST_MODULE FindSCU #include #include "odil/DataSet.h" #include "odil/FindSCU.h" #include "odil/registry.h" #include "../PeerFixtureBase.h" struct Fixture: public PeerFixtureBase { static bool called; odil::DataSet query; Fixture() : PeerFixtureBase({ { 1, odil::registry::PatientRootQueryRetrieveInformationModelFIND, { odil::registry::ImplicitVRLittleEndian }, true, false } }) { Fixture::called = false; this->query.add("QueryRetrieveLevel", {"PATIENT"}); this->query.add("PatientName", {"Doe^John"}); this->query.add("PatientID"); } static void callback(odil::DataSet const &) { Fixture::called = true; } }; bool Fixture::called = false; BOOST_FIXTURE_TEST_CASE(Find, Fixture) { odil::FindSCU scu(this->association); scu.set_affected_sop_class(odil::registry::PatientRootQueryRetrieveInformationModelFIND); auto const results = scu.find(this->query); BOOST_REQUIRE_EQUAL(results.size(), 1); BOOST_CHECK( results[0].as_string("PatientID") == odil::Value::Strings({"DJ001"})); } BOOST_FIXTURE_TEST_CASE(FindCallback, Fixture) { odil::FindSCU scu(this->association); scu.set_affected_sop_class(odil::registry::PatientRootQueryRetrieveInformationModelFIND); scu.find(this->query, Fixture::callback); BOOST_CHECK(Fixture::called); } odil-0.4.1/tests/code/GetSCP.cpp000066400000000000000000000131541266460524100163220ustar00rootroot00000000000000#define BOOST_TEST_MODULE GetSCP #include #include #include #include #include #include #include #include #include #include "odil/Association.h" #include "odil/DataSet.h" #include "odil/GetSCP.h" #include "odil/Exception.h" #include "odil/SCP.h" #include "odil/uid.h" #include "odil/Reader.h" #include "odil/message/Response.h" struct Status { int client; std::string server; std::vector responses; }; class Generator: public odil::GetSCP::DataSetGenerator { public: Generator() { // Nothing else. } virtual ~Generator() { // Nothing to do. } virtual void initialize(odil::message::Request const & ) { odil::DataSet data_set_1; data_set_1.add("SOPClassUID", {odil::registry::RawDataStorage}); data_set_1.add( "SOPInstanceUID", {"1.2.826.0.1.3680043.9.5560.3127449359877365688774406533090568532"}); data_set_1.add("PatientName", {"Hello^World"}); data_set_1.add("PatientID", {"1234"}); this->_responses.push_back(data_set_1); odil::DataSet data_set_2; data_set_2.add("SOPClassUID", {odil::registry::RawDataStorage}); data_set_2.add( "SOPInstanceUID", {"1.2.826.0.1.3680043.9.5560.3221615743193123463515381981101110692"}); data_set_2.add("PatientName", {"Doe^John"}); data_set_2.add("PatientID", {"5678"}); this->_responses.push_back(data_set_2); this->_response_iterator = this->_responses.begin(); } virtual bool done() const { return (this->_response_iterator == this->_responses.end()); } virtual odil::DataSet get() const { return *this->_response_iterator; } virtual void next() { ++this->_response_iterator; } virtual unsigned int count() const { return 2; } private: std::vector _responses; std::vector::const_iterator _response_iterator; }; void run_server(Status * status) { odil::Association association; association.set_tcp_timeout(boost::posix_time::seconds(1)); try { association.receive_association(boost::asio::ip::tcp::v4(), 11113); odil::GetSCP get_scp(association); auto const generator = std::make_shared(); get_scp.set_generator(generator); // Get echo message auto const message = association.receive_message(); get_scp(message); // Should throw with peer closing connection association.receive_message(); } catch(odil::AssociationAborted const &) { status->server = "abort"; } catch(odil::AssociationReleased const &) { status->server = "release"; } catch(odil::Exception const &) { status->server = "Other Odil exception"; } catch(...) { status->server = "Other exception"; } } void run_client(Status * status) { std::string command = "getscu " "-P -k QueryRetrieveLevel=PATIENT " "-k PatientID=* -k PatientName " "+B " "127.0.0.1 11113"; status->client = system(command.c_str()); boost::filesystem::directory_iterator end; for(boost::filesystem::directory_iterator it("."); it != end; ++it ) { if(!boost::filesystem::is_regular_file(it->status())) { continue; } auto const filename = it->path().stem().string(); if(filename.substr(0, odil::uid_prefix.size()) != odil::uid_prefix) { continue; } std::ifstream stream(it->path().string()); auto const data_set = odil::Reader::read_file(stream).second; status->responses.push_back(data_set); boost::filesystem::remove(it->path()); } std::sort( status->responses.begin(), status->responses.end(), [](odil::DataSet const & left, odil::DataSet const & right) { auto const & left_uid = left.as_string("SOPInstanceUID", 0); auto const & right_uid = right.as_string("SOPInstanceUID", 0); return (left_uid < right_uid); }); } BOOST_AUTO_TEST_CASE(Release) { Status status = { -1, "", {} }; std::thread server(run_server, &status); std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::thread client(run_client, &status); server.join(); client.join(); BOOST_REQUIRE_EQUAL(status.client, 0); BOOST_REQUIRE_EQUAL(status.server, "release"); BOOST_REQUIRE_EQUAL(status.responses.size(), 2); BOOST_REQUIRE_EQUAL(status.responses[0].size(), 4); BOOST_REQUIRE_EQUAL( status.responses[0].as_string("SOPInstanceUID", 0), "1.2.826.0.1.3680043.9.5560.3127449359877365688774406533090568532"); BOOST_REQUIRE_EQUAL( status.responses[0].as_string("SOPClassUID", 0), odil::registry::RawDataStorage); BOOST_REQUIRE_EQUAL(status.responses[0].as_string("PatientName", 0), "Hello^World"); BOOST_REQUIRE_EQUAL(status.responses[0].as_string("PatientID", 0), "1234"); BOOST_REQUIRE_EQUAL(status.responses[1].size(), 4); BOOST_REQUIRE_EQUAL( status.responses[1].as_string("SOPInstanceUID", 0), "1.2.826.0.1.3680043.9.5560.3221615743193123463515381981101110692"); BOOST_REQUIRE_EQUAL( status.responses[1].as_string("SOPClassUID", 0), odil::registry::RawDataStorage); BOOST_REQUIRE_EQUAL(status.responses[1].as_string("PatientName", 0), "Doe^John"); BOOST_REQUIRE_EQUAL(status.responses[1].as_string("PatientID", 0), "5678"); } odil-0.4.1/tests/code/GetSCU.cpp000066400000000000000000000032021266460524100163200ustar00rootroot00000000000000#define BOOST_TEST_MODULE GetSCU #include #include "odil/DataSet.h" #include "odil/GetSCU.h" #include "odil/registry.h" #include "../PeerFixtureBase.h" struct Fixture: public PeerFixtureBase { static bool called; odil::DataSet query; Fixture() : PeerFixtureBase({ { 1, odil::registry::PatientRootQueryRetrieveInformationModelGET, { odil::registry::ImplicitVRLittleEndian }, true, false }, { 3, odil::registry::RawDataStorage, { odil::registry::ImplicitVRLittleEndian }, false, true } }) { Fixture::called = false; this->query.add("QueryRetrieveLevel", {"PATIENT"}); this->query.add("PatientName", {"Doe^John"}); } static void callback(odil::DataSet const &) { Fixture::called = true; } }; bool Fixture::called = false; BOOST_FIXTURE_TEST_CASE(Get, Fixture) { odil::GetSCU scu(this->association); scu.set_affected_sop_class( odil::registry::PatientRootQueryRetrieveInformationModelGET); auto const results = scu.get(this->query); BOOST_REQUIRE_EQUAL(results.size(), 1); BOOST_CHECK( results[0].as_string("SOPInstanceUID") == odil::Value::Strings( {"2.25.95090344942250266709587559073467305647"})); } BOOST_FIXTURE_TEST_CASE(GetCallback, Fixture) { odil::GetSCU scu(this->association); scu.set_affected_sop_class( odil::registry::PatientRootQueryRetrieveInformationModelGET); scu.get(this->query, Fixture::callback); BOOST_CHECK(Fixture::called); } odil-0.4.1/tests/code/MoveSCP.cpp000066400000000000000000000161661266460524100165170ustar00rootroot00000000000000#define BOOST_TEST_MODULE MoveSCP #include #include #include #include #include #include #include #include #include "odil/Association.h" #include "odil/AssociationParameters.h" #include "odil/DataSet.h" #include "odil/MoveSCP.h" #include "odil/Exception.h" #include "odil/SCP.h" #include "odil/uid.h" #include "odil/Reader.h" #include "odil/registry.h" #include "odil/message/Response.h" struct Status { int client; std::string server; std::vector responses; }; class Generator: public odil::MoveSCP::DataSetGenerator { public: Generator(odil::Association & association) : _association(association) { // Nothing else. } virtual ~Generator() { // Nothing to do. } virtual void initialize(odil::message::Request const & ) { odil::DataSet data_set_1; data_set_1.add("SOPClassUID", {odil::registry::RawDataStorage}); data_set_1.add( "SOPInstanceUID", {"1.2.826.0.1.3680043.9.5560.3127449359877365688774406533090568532"}); data_set_1.add("PatientName", {"Hello^World"}); data_set_1.add("PatientID", {"1234"}); this->_responses.push_back(data_set_1); odil::DataSet data_set_2; data_set_2.add("SOPClassUID", {odil::registry::RawDataStorage}); data_set_2.add( "SOPInstanceUID", {"1.2.826.0.1.3680043.9.5560.3221615743193123463515381981101110692"}); data_set_2.add("PatientName", {"Doe^John"}); data_set_2.add("PatientID", {"5678"}); this->_responses.push_back(data_set_2); this->_response_iterator = this->_responses.begin(); } virtual bool done() const { return (this->_response_iterator == this->_responses.end()); } virtual odil::DataSet get() const { return *this->_response_iterator; } virtual void next() { ++this->_response_iterator; } virtual unsigned int count() const { return 2; } virtual odil::Association get_association( odil::message::CMoveRequest const & request) const { odil::Association move_association; move_association.set_peer_host(this->_association.get_peer_host()); move_association.set_peer_port(11114); // FIXME: max length, user_identity std::vector presentation_contexts; for(auto const & uid: odil::registry::uids_dictionary) { auto const & name = uid.second.name; if(name.substr(name.size()-7, std::string::npos) == "Storage") { odil::AssociationParameters::PresentationContext presentation_context = { static_cast(1+2*presentation_contexts.size()), uid.first, { odil::registry::ImplicitVRLittleEndian }, true, false }; presentation_contexts.push_back(presentation_context); } } move_association.update_parameters() .set_calling_ae_title( this->_association.get_negotiated_parameters().get_called_ae_title()) .set_called_ae_title(request.get_move_destination()) .set_presentation_contexts(presentation_contexts); return move_association; } private: std::vector _responses; std::vector::const_iterator _response_iterator; odil::Association & _association; }; void run_server(Status * status) { odil::Association association; association.set_tcp_timeout(boost::posix_time::seconds(1)); try { association.receive_association(boost::asio::ip::tcp::v4(), 11113); odil::MoveSCP move_scp(association); auto const generator = std::make_shared(association); move_scp.set_generator(generator); // Get move message auto const message = association.receive_message(); move_scp(message); // Should throw with peer closing connection association.receive_message(); } catch(odil::AssociationAborted const &) { status->server = "abort"; } catch(odil::AssociationReleased const &) { status->server = "release"; } catch(odil::Exception const &) { status->server = "Other Odil exception"; } catch(...) { status->server = "Other exception"; } } void run_client(Status * status) { std::string command = "movescu " "-P -k QueryRetrieveLevel=PATIENT " "-k PatientID=* -k PatientName " "+P 11114 127.0.0.1 11113"; status->client = system(command.c_str()); boost::filesystem::directory_iterator end; for(boost::filesystem::directory_iterator it("."); it != end; ++it ) { if(!boost::filesystem::is_regular_file(it->status())) { continue; } auto const filename = it->path().stem().string(); if(filename.substr(0, 3) != "RAW") { continue; } std::ifstream stream(it->path().string()); auto const data_set = odil::Reader::read_file(stream).second; status->responses.push_back(data_set); boost::filesystem::remove(it->path()); } std::sort( status->responses.begin(), status->responses.end(), [](odil::DataSet const & left, odil::DataSet const & right) { auto const & left_uid = left.as_string("SOPInstanceUID", 0); auto const & right_uid = right.as_string("SOPInstanceUID", 0); return (left_uid < right_uid); }); } BOOST_AUTO_TEST_CASE(Release) { Status status = { -1, "", {} }; std::thread server(run_server, &status); std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::thread client(run_client, &status); server.join(); client.join(); BOOST_REQUIRE_EQUAL(status.client, 0); BOOST_REQUIRE_EQUAL(status.server, "release"); BOOST_REQUIRE_EQUAL(status.responses.size(), 2); BOOST_REQUIRE_EQUAL(status.responses[0].size(), 4); BOOST_REQUIRE_EQUAL( status.responses[0].as_string("SOPInstanceUID", 0), "1.2.826.0.1.3680043.9.5560.3127449359877365688774406533090568532"); BOOST_REQUIRE_EQUAL( status.responses[0].as_string("SOPClassUID", 0), odil::registry::RawDataStorage); BOOST_REQUIRE_EQUAL(status.responses[0].as_string("PatientName", 0), "Hello^World"); BOOST_REQUIRE_EQUAL(status.responses[0].as_string("PatientID", 0), "1234"); BOOST_REQUIRE_EQUAL(status.responses[1].size(), 4); BOOST_REQUIRE_EQUAL( status.responses[1].as_string("SOPInstanceUID", 0), "1.2.826.0.1.3680043.9.5560.3221615743193123463515381981101110692"); BOOST_REQUIRE_EQUAL( status.responses[1].as_string("SOPClassUID", 0), odil::registry::RawDataStorage); BOOST_REQUIRE_EQUAL(status.responses[1].as_string("PatientName", 0), "Doe^John"); BOOST_REQUIRE_EQUAL(status.responses[1].as_string("PatientID", 0), "5678"); } odil-0.4.1/tests/code/MoveSCU.cpp000066400000000000000000000040551266460524100165160ustar00rootroot00000000000000#define BOOST_TEST_MODULE MoveSCU #include #include "odil/DataSet.h" #include "odil/MoveSCU.h" #include "odil/registry.h" #include "../PeerFixtureBase.h" struct Fixture: public PeerFixtureBase { static bool called; odil::DataSet query; Fixture() : PeerFixtureBase({ { 1, odil::registry::PatientRootQueryRetrieveInformationModelMOVE, { odil::registry::ImplicitVRLittleEndian }, true, false }, { 3, odil::registry::RawDataStorage, { odil::registry::ImplicitVRLittleEndian }, false, true } }) { Fixture::called = false; this->query.add("QueryRetrieveLevel", {"PATIENT"}); this->query.add("PatientName", {"Doe^John"}); } static void callback(odil::DataSet const &) { Fixture::called = true; } }; bool Fixture::called = false; BOOST_FIXTURE_TEST_CASE(DefaultConstructor, Fixture) { odil::MoveSCU const scu(this->association); BOOST_CHECK_EQUAL(scu.get_move_destination(), ""); } BOOST_FIXTURE_TEST_CASE(MoveDestination, Fixture) { odil::MoveSCU scu(this->association); scu.set_move_destination("remote"); BOOST_CHECK_EQUAL(scu.get_move_destination(), "remote"); } BOOST_FIXTURE_TEST_CASE(Move, Fixture) { odil::MoveSCU scu(this->association); scu.set_move_destination("LOCAL"); scu.set_affected_sop_class( odil::registry::PatientRootQueryRetrieveInformationModelMOVE); auto const results = scu.move(this->query); BOOST_REQUIRE_EQUAL(results.size(), 1); BOOST_CHECK( results[0].as_string("SOPInstanceUID") == odil::Value::Strings{"2.25.95090344942250266709587559073467305647"}); } BOOST_FIXTURE_TEST_CASE(MoveCallback, Fixture) { odil::MoveSCU scu(this->association); scu.set_move_destination("LOCAL"); scu.set_affected_sop_class( odil::registry::PatientRootQueryRetrieveInformationModelMOVE); scu.move(this->query, Fixture::callback); BOOST_CHECK(Fixture::called); } odil-0.4.1/tests/code/Reader.cpp000066400000000000000000000233661266460524100164450ustar00rootroot00000000000000#define BOOST_TEST_MODULE Reader #include #include #include #include #include #include #include "odil/endian.h" #include "odil/Element.h" #include "odil/registry.h" #include "odil/Reader.h" #include "odil/VR.h" #include "odil/dcmtk/conversion.h" BOOST_AUTO_TEST_CASE(Constructor) { std::istringstream stream; odil::Reader const reader(stream, odil::registry::ExplicitVRBigEndian_Retired); BOOST_REQUIRE(reader.byte_ordering == odil::ByteOrdering::BigEndian); BOOST_REQUIRE(reader.explicit_vr == true); } void do_test( odil::DataSet const & odil_data_set, std::string transfer_syntax, E_EncodingType item_encoding, E_GrpLenEncoding group_length_encoding) { // Write input data set auto const dcmtk_data_set = dynamic_cast(odil::dcmtk::convert(odil_data_set)); std::string data(1000000, '\0'); DcmOutputBufferStream dcmtk_stream(&data[0], data.size()); dcmtk_data_set->transferInit(); OFCondition const condition = dcmtk_data_set->write( dcmtk_stream, DcmXfer(transfer_syntax.c_str()).getXfer(), item_encoding, NULL, group_length_encoding); BOOST_REQUIRE(condition == EC_Normal); dcmtk_data_set->transferEnd(); // Store data in a stream data = data.substr(0, dcmtk_stream.tell()); std::istringstream stream(data); // Read output data set odil::Reader reader(stream, transfer_syntax); auto const other_odil_data_set = reader.read_data_set(); BOOST_REQUIRE(other_odil_data_set == odil_data_set); } void do_test(odil::DataSet const & odil_data_set) { std::vector const transfer_syntaxes = { odil::registry::ImplicitVRLittleEndian, odil::registry::ExplicitVRLittleEndian, odil::registry::ExplicitVRBigEndian_Retired }; std::vector item_encodings = { EET_ExplicitLength, EET_UndefinedLength }; std::vector use_group_length_values = { EGL_withoutGL, EGL_withGL }; for(auto const & transfer_syntax: transfer_syntaxes) { for(auto const & item_encoding: item_encodings) { for(auto const & use_group_length: use_group_length_values) { do_test( odil_data_set, transfer_syntax, item_encoding, use_group_length); } } } } BOOST_AUTO_TEST_CASE(AT) { odil::Element odil_element({"12345678", "9abcdef0"}, odil::VR::AT); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorATValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(CS) { odil::Element odil_element({"ABC", "DEF"}, odil::VR::CS); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorCSValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(DS) { odil::Element odil_element({1.23, -4.56}, odil::VR::DS); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorDSValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(FD) { odil::Element odil_element({1.23, -4.56}, odil::VR::FD); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorFDValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(FL) { odil::Element odil_element({0.5, -0.125}, odil::VR::FL); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorFLValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(IS) { odil::Element odil_element({123, -456}, odil::VR::IS); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorISValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(OB) { odil::Element odil_element( std::vector({0x01, 0x02, 0x03, 0x04}), odil::VR::OB); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::EncapsulatedDocument, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(OF) { odil::Element odil_element( std::vector({0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}), odil::VR::OF); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::VectorGridData, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(OW) { odil::Element odil_element( std::vector({0x01, 0x02, 0x03, 0x04}), odil::VR::OW); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::RedPaletteColorLookupTableData, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(SL) { odil::Element odil_element({12345678, -8765432}, odil::VR::SL); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorSLValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(SQ) { odil::DataSet item1; item1.add( odil::registry::SelectorSLValue, odil::Element({12345678, -8765432}, odil::VR::SL)); odil::DataSet item2; item2.add( odil::registry::SelectorFDValue, odil::Element({1.23, -4.56}, odil::VR::FD)); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::FrameExtractionSequence, odil::Element({item1, item2}, odil::VR::SQ)); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(SS) { odil::Element odil_element({1234, -5678}, odil::VR::SS); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorSSValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(UI) { odil::Element odil_element({"1.2", "3.4"}, odil::VR::UI); odil::DataSet odil_data_set; // SelectorUIValue is not in current DCMTK odil_data_set.add(odil::registry::SOPInstanceUID, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(UL) { odil::Element odil_element({12345678, 8765432}, odil::VR::UL); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorULValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(US) { odil::Element odil_element({1234, 5678}, odil::VR::US); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorUSValue, odil_element); do_test(odil_data_set); } void do_file_test( odil::DataSet const & odil_data_set, std::string transfer_syntax, E_EncodingType item_encoding, E_GrpLenEncoding group_length_encoding) { // Write input data set auto const dcmtk_data_set = dynamic_cast(odil::dcmtk::convert(odil_data_set)); DcmFileFormat file_format(dcmtk_data_set); file_format.getMetaInfo()->putAndInsertString( DCM_TransferSyntaxUID, transfer_syntax.c_str()); file_format.getMetaInfo()->putAndInsertString( DCM_MediaStorageSOPClassUID, odil_data_set.as_string(odil::registry::SOPClassUID)[0].c_str()); file_format.getMetaInfo()->putAndInsertString( DCM_MediaStorageSOPInstanceUID, odil_data_set.as_string(odil::registry::SOPInstanceUID)[0].c_str()); std::string data(1000000, '\0'); DcmOutputBufferStream dcmtk_stream(&data[0], data.size()); file_format.transferInit(); OFCondition const condition = file_format.write( dcmtk_stream, DcmXfer(transfer_syntax.c_str()).getXfer(), item_encoding, NULL, group_length_encoding); BOOST_REQUIRE(condition == EC_Normal); file_format.transferEnd(); // Store data in a stream data = data.substr(0, dcmtk_stream.tell()); std::istringstream stream(data); // Read output data set odil::DataSet meta_information, other_odil_data_set; std::tie(meta_information, other_odil_data_set) = odil::Reader::read_file(stream); BOOST_REQUIRE(other_odil_data_set == odil_data_set); BOOST_REQUIRE( meta_information.as_string(odil::registry::TransferSyntaxUID) == odil::Value::Strings({transfer_syntax})); BOOST_REQUIRE( meta_information.as_string(odil::registry::MediaStorageSOPClassUID) == other_odil_data_set.as_string(odil::registry::SOPClassUID)); BOOST_REQUIRE( meta_information.as_string(odil::registry::MediaStorageSOPInstanceUID) == other_odil_data_set.as_string(odil::registry::SOPInstanceUID)); } void do_file_test(odil::DataSet const & odil_data_set) { std::vector const transfer_syntaxes = { odil::registry::ImplicitVRLittleEndian, odil::registry::ExplicitVRLittleEndian, odil::registry::ExplicitVRBigEndian_Retired }; std::vector item_encodings = { EET_ExplicitLength, EET_UndefinedLength }; std::vector use_group_length_values = { EGL_withoutGL, EGL_withGL }; for(auto const & transfer_syntax: transfer_syntaxes) { for(auto const & item_encoding: item_encodings) { for(auto const & use_group_length: use_group_length_values) { do_file_test( odil_data_set, transfer_syntax, item_encoding, use_group_length); } } } } BOOST_AUTO_TEST_CASE(File) { odil::DataSet item1; item1.add( odil::registry::SelectorSLValue, odil::Element({12345678, -8765432}, odil::VR::SL)); odil::DataSet item2; item2.add( odil::registry::SelectorFDValue, odil::Element({1.23, -4.56}, odil::VR::FD)); odil::DataSet odil_data_set; odil_data_set.add( odil::registry::SOPClassUID, {odil::registry::RawDataStorage}, odil::VR::UI); odil_data_set.add( odil::registry::SOPInstanceUID, {"1.2.3.4"}, odil::VR::UI); odil_data_set.add( odil::registry::FrameExtractionSequence, odil::Element({item1, item2}, odil::VR::SQ)); do_file_test(odil_data_set); } odil-0.4.1/tests/code/SCPDispatcher.cpp000066400000000000000000000063671266460524100177010ustar00rootroot00000000000000#define BOOST_TEST_MODULE SCPDispatcher #include #include #include #include #include "odil/Association.h" #include "odil/EchoSCP.h" #include "odil/Exception.h" #include "odil/SCPDispatcher.h" #include "odil/message/Message.h" #include "odil/message/Response.h" struct Status { int client; std::string server; bool called; }; void run_server(Status * status, bool with_echo) { odil::Association association; association.set_tcp_timeout(boost::posix_time::seconds(1)); try { association.receive_association(boost::asio::ip::tcp::v4(), 11113); auto echo_scp = std::make_shared(association, [&status](odil::message::CEchoRequest const &) { status->called = true; return odil::message::Response::Success; }); odil::SCPDispatcher dispatcher(association); if(with_echo) { dispatcher.set_scp( odil::message::Message::Command::C_ECHO_RQ, echo_scp); } dispatcher.dispatch(); // Should throw with peer closing connection association.receive_message(); } catch(odil::AssociationAborted const &) { status->server = "abort"; } catch(odil::AssociationReleased const &) { status->server = "release"; } catch(odil::Exception const & e) { status->server = e.what(); } catch(...) { status->server = "Other exception"; } } void run_echo_client(Status * status) { std::string command = "echoscu"; command += " 127.0.0.1 11113"; status->client = system(command.c_str()); } BOOST_AUTO_TEST_CASE(Empty) { odil::Association association; odil::SCPDispatcher dispatcher(association); BOOST_REQUIRE_EQUAL( dispatcher.has_scp(odil::message::Message::Command::C_ECHO_RQ), false); BOOST_REQUIRE_THROW( dispatcher.get_scp(odil::message::Message::Command::C_ECHO_RQ), odil::Exception); } BOOST_AUTO_TEST_CASE(SCP) { odil::Association association; odil::SCPDispatcher dispatcher(association); auto scp = std::make_shared(association); dispatcher.set_scp( odil::message::Message::Command::C_ECHO_RQ, scp); BOOST_REQUIRE_NO_THROW( dispatcher.get_scp(odil::message::Message::Command::C_ECHO_RQ)); } BOOST_AUTO_TEST_CASE(DispatchWithEcho) { Status status = { -1, "", false }; std::thread server(run_server, &status, true); std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::thread client(run_echo_client, &status); server.join(); client.join(); BOOST_REQUIRE_EQUAL(status.client, 0); BOOST_REQUIRE_EQUAL(status.server, "release"); BOOST_REQUIRE_EQUAL(status.called, true); } BOOST_AUTO_TEST_CASE(DispatchWithoutEcho) { Status status = { -1, "", false }; std::thread server(run_server, &status, false); std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::thread client(run_echo_client, &status); server.join(); client.join(); BOOST_REQUIRE_EQUAL(status.client, 0); BOOST_REQUIRE_EQUAL(status.server, "No such provider"); BOOST_REQUIRE_EQUAL(status.called, false); } odil-0.4.1/tests/code/SCU.cpp000066400000000000000000000015471266460524100156720ustar00rootroot00000000000000#define BOOST_TEST_MODULE SCU #include #include "odil/SCU.h" #include "odil/registry.h" #include "../PeerFixtureBase.h" struct Fixture: public PeerFixtureBase { Fixture() : PeerFixtureBase({ { 1, odil::registry::VerificationSOPClass, {odil::registry::ImplicitVRLittleEndian}, true, false } }) { // Nothing else } }; BOOST_FIXTURE_TEST_CASE(DefaultConstructor, Fixture) { odil::SCU const scu(this->association); BOOST_CHECK_EQUAL(scu.get_affected_sop_class(), ""); } BOOST_FIXTURE_TEST_CASE(AffectedSOPClassUID, Fixture) { odil::SCU scu(this->association); scu.set_affected_sop_class("1.2.3"); BOOST_CHECK_EQUAL(scu.get_affected_sop_class(), "1.2.3"); } BOOST_FIXTURE_TEST_CASE(Echo, Fixture) { odil::SCU scu(this->association); scu.echo(); } odil-0.4.1/tests/code/StoreSCU.cpp000066400000000000000000000036261266460524100167070ustar00rootroot00000000000000#define BOOST_TEST_MODULE StoreSCU #include #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/registry.h" #include "odil/StoreSCU.h" #include "../PeerFixtureBase.h" struct Fixture: public PeerFixtureBase { odil::DataSet dataset; Fixture() : PeerFixtureBase({ { 1, odil::registry::RawDataStorage, {odil::registry::ImplicitVRLittleEndian}, true, false } }) { this->dataset.add("ImageType", {"ORIGINAL", "PRIMARY", "OTHER"}); this->dataset.add("PatientID", {"1234"}); this->dataset.add("StudyInstanceUID", {"2.25.386726390606491051215227596277040710"}); this->dataset.add("SeriesInstanceUID", {"2.25.235367796740370588607388995952651763168"}); this->dataset.add("SOPClassUID", {odil::registry::RawDataStorage}); this->dataset.add("SOPInstanceUID", {"2.25.294312554735929033890522327215919068328"}); } }; BOOST_FIXTURE_TEST_CASE(AffectedSOPClassUID, Fixture) { odil::DataSet dataset; dataset.add("SOPClassUID", {odil::registry::RawDataStorage}); odil::StoreSCU scu(this->association); scu.set_affected_sop_class(dataset); BOOST_CHECK_EQUAL(scu.get_affected_sop_class(), odil::registry::RawDataStorage); } BOOST_FIXTURE_TEST_CASE(AffectedSOPClassUIDNoSOPClassUID, Fixture) { odil::DataSet dataset; odil::StoreSCU scu(this->association); BOOST_CHECK_THROW(scu.set_affected_sop_class(dataset), odil::Exception); } BOOST_FIXTURE_TEST_CASE(AffectedSOPClassUIDUnknownSOPClassUID, Fixture) { odil::DataSet dataset; dataset.add("SOPClassUID", {"invalid"}); odil::StoreSCU scu(this->association); BOOST_CHECK_THROW(scu.set_affected_sop_class(dataset), odil::Exception); } BOOST_FIXTURE_TEST_CASE(Store, Fixture) { odil::StoreSCU scu(this->association); scu.set_affected_sop_class(this->dataset); scu.store(this->dataset); } odil-0.4.1/tests/code/Tag.cpp000066400000000000000000000106161266460524100157500ustar00rootroot00000000000000#define BOOST_TEST_MODULE Tag #include #include "odil/Exception.h" #include "odil/Tag.h" BOOST_AUTO_TEST_CASE(TwoArgumentsConstructor) { odil::Tag const tag(0xdead, 0xbeef); BOOST_CHECK_EQUAL(tag.group, 0xdead); BOOST_CHECK_EQUAL(tag.element, 0xbeef); } BOOST_AUTO_TEST_CASE(OneArgumentConstructor) { odil::Tag const tag(0xdeadbeef); BOOST_CHECK_EQUAL(tag.group, 0xdead); BOOST_CHECK_EQUAL(tag.element, 0xbeef); } BOOST_AUTO_TEST_CASE(StringConstructor) { odil::Tag const tag(std::string("PixelData")); BOOST_CHECK_EQUAL(tag.group, 0x7fe0); BOOST_CHECK_EQUAL(tag.element, 0x0010); } BOOST_AUTO_TEST_CASE(CharConstructor) { odil::Tag const tag("PixelData"); BOOST_CHECK_EQUAL(tag.group, 0x7fe0); BOOST_CHECK_EQUAL(tag.element, 0x0010); } BOOST_AUTO_TEST_CASE(StringConstructorNumeric) { odil::Tag const tag(std::string("7fe00010")); BOOST_CHECK_EQUAL(tag.group, 0x7fe0); BOOST_CHECK_EQUAL(tag.element, 0x0010); } BOOST_AUTO_TEST_CASE(CharConstructorNumeric) { odil::Tag const tag("7fe00010"); BOOST_CHECK_EQUAL(tag.group, 0x7fe0); BOOST_CHECK_EQUAL(tag.element, 0x0010); } BOOST_AUTO_TEST_CASE(StringConstructorWrong) { BOOST_CHECK_THROW(odil::Tag(std::string("Foobar")), odil::Exception); } BOOST_AUTO_TEST_CASE(CharConstructorWrong) { BOOST_CHECK_THROW(odil::Tag("Foobar"), odil::Exception); } BOOST_AUTO_TEST_CASE(StringConstructorNumericWrong) { BOOST_CHECK_THROW(odil::Tag(std::string("XXXXYYYY")), odil::Exception); } BOOST_AUTO_TEST_CASE(CharConstructorNumericWrong) { BOOST_CHECK_THROW(odil::Tag("XXXXYYYY"), odil::Exception); } BOOST_AUTO_TEST_CASE(CopyConstructor) { odil::Tag const tag(0xdead, 0xbeef); odil::Tag const other(tag); BOOST_CHECK_EQUAL(other.group, 0xdead); BOOST_CHECK_EQUAL(other.element, 0xbeef); } BOOST_AUTO_TEST_CASE(IsPrivate) { odil::Tag const tag1(0xdead, 0xbeef); odil::Tag const tag2(0x7fe0, 0x0010); BOOST_CHECK(tag1.is_private()); BOOST_CHECK(!tag2.is_private()); } BOOST_AUTO_TEST_CASE(Name) { odil::Tag const tag(0x7fe0, 0x0010); std::string const name = tag.get_name(); BOOST_CHECK_EQUAL(name, "PixelData"); } BOOST_AUTO_TEST_CASE(NameWrong) { odil::Tag const tag(0xEEEE, 0xEEEE); BOOST_CHECK_THROW(tag.get_name(), odil::Exception); } BOOST_AUTO_TEST_CASE(Equality) { odil::Tag const tag1(0xdead, 0xbeef); odil::Tag const tag2(0xdead, 0xbeef); odil::Tag const tag3(0xbeef, 0xf00d); BOOST_CHECK(tag1 == tag2); BOOST_CHECK( ! (tag1 == tag3) ); } BOOST_AUTO_TEST_CASE(Difference) { odil::Tag const tag1(0xdead, 0xbeef); odil::Tag const tag2(0xdead, 0xbeef); odil::Tag const tag3(0xbeef, 0xf00d); BOOST_CHECK( ! (tag1 != tag2) ); BOOST_CHECK(tag1 != tag3); } BOOST_AUTO_TEST_CASE(Inferior) { odil::Tag const tag1(0xdead, 0xbeef); odil::Tag const tag2(0xdead, 0xf00d); odil::Tag const tag3(0xbeef, 0xf00d); BOOST_CHECK(tag1 < tag2); BOOST_CHECK(tag3 < tag1); BOOST_CHECK( ! (tag2 < tag1) ); BOOST_CHECK( ! (tag1 < tag3) ); } BOOST_AUTO_TEST_CASE(Superior) { odil::Tag const tag1(0xdead, 0xbeef); odil::Tag const tag2(0xdead, 0xf00d); odil::Tag const tag3(0xbeef, 0xf00d); BOOST_CHECK(tag2 > tag1); BOOST_CHECK(tag1 > tag3); BOOST_CHECK( ! (tag1 > tag2) ); BOOST_CHECK( ! (tag3 > tag1) ); } BOOST_AUTO_TEST_CASE(InferiorOrEqual) { odil::Tag const tag1(0xdead, 0xbeef); odil::Tag const tag2(0xdead, 0xf00d); odil::Tag const tag3(0xbeef, 0xf00d); odil::Tag const tag4(0xdead, 0xbeef); BOOST_CHECK(tag1 <= tag2); BOOST_CHECK(tag3 <= tag1); BOOST_CHECK(tag1 <= tag4); BOOST_CHECK( ! (tag2 <= tag1) ); BOOST_CHECK( ! (tag1 <= tag3) ); } BOOST_AUTO_TEST_CASE(SuperiorOrEqual) { odil::Tag const tag1(0xdead, 0xbeef); odil::Tag const tag2(0xdead, 0xf00d); odil::Tag const tag3(0xbeef, 0xf00d); odil::Tag const tag4(0xdead, 0xbeef); BOOST_CHECK(tag2 >= tag1); BOOST_CHECK(tag1 >= tag3); BOOST_CHECK(tag1 >= tag4); BOOST_CHECK( ! (tag1 >= tag2) ); BOOST_CHECK( ! (tag3 >= tag1) ); } BOOST_AUTO_TEST_CASE(StreamInsertion) { odil::Tag const tag(0xdead, 0xbeef); std::ostringstream stream; stream << tag; BOOST_CHECK_EQUAL(stream.str(), "deadbeef"); } BOOST_AUTO_TEST_CASE(StringConversion) { odil::Tag const tag(0xdead, 0xbeef); BOOST_CHECK_EQUAL(std::string(tag), "deadbeef"); } odil-0.4.1/tests/code/VR.cpp000066400000000000000000000013111266460524100155540ustar00rootroot00000000000000#define BOOST_TEST_MODULE VR #include #include "odil/Exception.h" #include "odil/VR.h" BOOST_AUTO_TEST_CASE(as_string) { odil::VR const vr(odil::VR::AT); std::string const string = odil::as_string(vr); BOOST_CHECK_EQUAL(string, "AT"); } BOOST_AUTO_TEST_CASE(as_string_invalid) { odil::VR const vr(odil::VR::INVALID); BOOST_CHECK_THROW(odil::as_string(vr), odil::Exception); } BOOST_AUTO_TEST_CASE(as_vr) { std::string const string("AT"); odil::VR const vr = odil::as_vr(string); BOOST_CHECK(vr == odil::VR::AT); } BOOST_AUTO_TEST_CASE(as_vr_wrong) { std::string const string("XX"); BOOST_CHECK_THROW(odil::as_vr(string), odil::Exception); } odil-0.4.1/tests/code/VRFinder.cpp000066400000000000000000000111161266460524100167100ustar00rootroot00000000000000#define BOOST_TEST_MODULE VRFinder #include #include #include "odil/DataSet.h" #include "odil/Exception.h" #include "odil/registry.h" #include "odil/Tag.h" #include "odil/VR.h" #include "odil/VRFinder.h" odil::VR user_defined_finder( odil::Tag const & tag, odil::DataSet const &, std::string const &, bool & called) { if(tag == odil::Tag(0xeeee, 0xeeee)) { called = true; return odil::VR::UR; } else { throw odil::Exception("Not applicable"); } } BOOST_AUTO_TEST_CASE(DefaultConstructor) { odil::VRFinder finder; BOOST_REQUIRE_EQUAL(finder.finders.empty(), true); } BOOST_AUTO_TEST_CASE(PublicDictionary) { auto const vr = odil::VRFinder::public_dictionary( odil::Tag(0x0010, 0x0010), odil::DataSet(), odil::registry::ImplicitVRLittleEndian); BOOST_REQUIRE(vr == odil::VR::PN); } BOOST_AUTO_TEST_CASE(PublicDictionaryNotApplicable) { BOOST_REQUIRE_THROW( odil::VRFinder::public_dictionary( odil::Tag(0x0011, 0x0011), odil::DataSet(), odil::registry::ImplicitVRLittleEndian), odil::Exception); } BOOST_AUTO_TEST_CASE(GroupLength) { auto const vr = odil::VRFinder::group_length( odil::Tag(0x0010, 0x0000), odil::DataSet(), odil::registry::ImplicitVRLittleEndian); BOOST_REQUIRE(vr == odil::VR::UL); } BOOST_AUTO_TEST_CASE(GroupLengthNotApplicable) { BOOST_REQUIRE_THROW( odil::VRFinder::group_length( odil::Tag(0x0010, 0x0010), odil::DataSet(), odil::registry::ImplicitVRLittleEndian), odil::Exception); } BOOST_AUTO_TEST_CASE(PrivateTag) { auto const vr = odil::VRFinder::private_tag( odil::Tag(0x0011, 0x0011), odil::DataSet(), odil::registry::ImplicitVRLittleEndian); BOOST_REQUIRE(vr == odil::VR::UN); } BOOST_AUTO_TEST_CASE(PrivateTagNotApplicable) { BOOST_REQUIRE_THROW( odil::VRFinder::private_tag( odil::Tag(0x0010, 0x0010), odil::DataSet(), odil::registry::ImplicitVRLittleEndian), odil::Exception); } BOOST_AUTO_TEST_CASE(ImplictiVRLittleEndian) { auto const vr = odil::VRFinder::implicit_vr_little_endian( odil::Tag(0x7fe0, 0x0010), odil::DataSet(), odil::registry::ImplicitVRLittleEndian); BOOST_REQUIRE(vr == odil::VR::OW); } BOOST_AUTO_TEST_CASE(ImplictiVRLittleEndianNotApplicableTag) { BOOST_REQUIRE_THROW( odil::VRFinder::implicit_vr_little_endian( odil::Tag(0x0010, 0x0010), odil::DataSet(), odil::registry::ImplicitVRLittleEndian), odil::Exception); } BOOST_AUTO_TEST_CASE(ImplictiVRLittleEndianNotApplicableVR) { BOOST_REQUIRE_THROW( odil::VRFinder::implicit_vr_little_endian( odil::Tag(0x7fe0, 0x0010), odil::DataSet(), odil::registry::ExplicitVRLittleEndian), odil::Exception); } BOOST_AUTO_TEST_CASE(PublicElement) { odil::VRFinder finder; auto const vr = finder( odil::Tag(0x0010, 0x0010), odil::DataSet(), odil::registry::ImplicitVRLittleEndian); BOOST_REQUIRE(vr == odil::VR::PN); } BOOST_AUTO_TEST_CASE(GroupLengthElement) { odil::VRFinder finder; auto const vr = finder( odil::Tag(0x0010, 0x0000), odil::DataSet(), odil::registry::ImplicitVRLittleEndian); BOOST_REQUIRE(vr == odil::VR::UL); } BOOST_AUTO_TEST_CASE(PrivateElement) { odil::VRFinder finder; auto const vr = finder( odil::Tag(0x0011, 0x0011), odil::DataSet(), odil::registry::ImplicitVRLittleEndian); BOOST_REQUIRE(vr == odil::VR::UN); } BOOST_AUTO_TEST_CASE(TSDependentElement) { odil::VRFinder finder; auto const vr = finder( odil::Tag(0x7fe0, 0x0010), odil::DataSet(), odil::registry::ImplicitVRLittleEndian); BOOST_REQUIRE(vr == odil::VR::OW); } BOOST_AUTO_TEST_CASE(UserFinder) { bool called = false; auto const my_finder_function = [&called] ( odil::Tag const & tag, odil::DataSet const & data_set, std::string const & ts ) { return user_defined_finder(tag, data_set, ts, called); }; odil::VRFinder finder; finder.finders.push_back(my_finder_function); finder( odil::Tag(0xeeee, 0xeeee), odil::DataSet(), odil::registry::ImplicitVRLittleEndian ); BOOST_REQUIRE_EQUAL(called, true); } BOOST_AUTO_TEST_CASE(NoVRFound) { odil::VRFinder finder; BOOST_REQUIRE_THROW( finder( odil::Tag(0xcccc, 0xcccc), odil::DataSet(), odil::registry::ImplicitVRLittleEndian ), odil::Exception); } odil-0.4.1/tests/code/Value.cpp000066400000000000000000000200551266460524100163070ustar00rootroot00000000000000#define BOOST_TEST_MODULE Value #include #include "odil/DataSet.h" #include "odil/Element.h" #include "odil/Exception.h" BOOST_AUTO_TEST_CASE(Empty) { odil::Value const value; BOOST_CHECK(value.get_type() == odil::Value::Type::Empty); BOOST_CHECK_THROW(value.as_integers(), odil::Exception); BOOST_CHECK_THROW(value.as_reals(), odil::Exception); BOOST_CHECK_THROW(value.as_strings(), odil::Exception); BOOST_CHECK_THROW(value.as_data_sets(), odil::Exception); } BOOST_AUTO_TEST_CASE(Integers) { odil::Value const value({1234}); BOOST_CHECK(value.get_type() == odil::Value::Type::Integers); BOOST_CHECK(value.as_integers() == odil::Value::Integers({1234})); BOOST_CHECK_THROW(value.as_reals(), odil::Exception); BOOST_CHECK_THROW(value.as_strings(), odil::Exception); BOOST_CHECK_THROW(value.as_data_sets(), odil::Exception); } BOOST_AUTO_TEST_CASE(ModifyIntegers) { odil::Value value({1234}); value.as_integers().push_back(5678); BOOST_CHECK(value.as_integers() == odil::Value::Integers({1234, 5678})); } BOOST_AUTO_TEST_CASE(Reals) { odil::Value const value({12.34}); BOOST_CHECK(value.get_type() == odil::Value::Type::Reals); BOOST_CHECK(value.as_reals() == odil::Value::Reals({12.34})); BOOST_CHECK_THROW(value.as_integers(), odil::Exception); BOOST_CHECK_THROW(value.as_strings(), odil::Exception); BOOST_CHECK_THROW(value.as_data_sets(), odil::Exception); } BOOST_AUTO_TEST_CASE(ModifyReals) { odil::Value value({12.34}); value.as_reals().push_back(56.78); BOOST_CHECK(value.as_reals() == odil::Value::Reals({12.34, 56.78})); } BOOST_AUTO_TEST_CASE(Strings) { odil::Value const value({"foo"}); BOOST_CHECK(value.get_type() == odil::Value::Type::Strings); BOOST_CHECK(value.as_strings() == odil::Value::Strings({"foo"})); BOOST_CHECK_THROW(value.as_integers(), odil::Exception); BOOST_CHECK_THROW(value.as_reals(), odil::Exception); BOOST_CHECK_THROW(value.as_data_sets(), odil::Exception); } BOOST_AUTO_TEST_CASE(ModifyStrings) { odil::Value value({"foo"}); value.as_strings().push_back("bar"); BOOST_CHECK(value.as_strings() == odil::Value::Strings({"foo", "bar"})); } BOOST_AUTO_TEST_CASE(DataSets) { odil::DataSet data_set; data_set.add("PatientID", {"DJ1234"}); odil::Value const value({data_set}); BOOST_CHECK(value.get_type() == odil::Value::Type::DataSets); BOOST_CHECK_EQUAL(value.as_data_sets().size(), 1); BOOST_CHECK(value.as_data_sets()[0].has("PatientID")); BOOST_CHECK( value.as_data_sets()[0].as_string("PatientID") == odil::Value::Strings({"DJ1234"})); BOOST_CHECK_THROW(value.as_integers(), odil::Exception); BOOST_CHECK_THROW(value.as_strings(), odil::Exception); BOOST_CHECK_THROW(value.as_reals(), odil::Exception); } BOOST_AUTO_TEST_CASE(ModifyDataSets) { odil::DataSet data_set; data_set.add("PatientID"); data_set.as_string("PatientID").push_back("DJ1234"); odil::Value value({data_set}); value.as_data_sets()[0].as_string("PatientID")[0] = "XXX"; BOOST_CHECK(value.get_type() == odil::Value::Type::DataSets); BOOST_CHECK_EQUAL(value.as_data_sets().size(), 1); BOOST_CHECK(value.as_data_sets()[0].has("PatientID")); BOOST_CHECK( value.as_data_sets()[0].as_string("PatientID") == odil::Value::Strings({"XXX"})); } BOOST_AUTO_TEST_CASE(EqualityEmpty) { odil::Value const value1; odil::Value const value2; odil::Value const value3((odil::Value::Integers())); BOOST_CHECK(value1 == value2); BOOST_CHECK( ! (value1 == value3)); } BOOST_AUTO_TEST_CASE(EqualityIntegers) { odil::Value const value1({1,2}); odil::Value const value2({1,2}); odil::Value const value3({3,4}); odil::Value const value4({3,4}); BOOST_CHECK(value1 == value2); BOOST_CHECK( ! (value1 == value3)); BOOST_CHECK( ! (value1 == value4)); } BOOST_AUTO_TEST_CASE(EqualityReals) { odil::Value const value1({1,2}); odil::Value const value2({1,2}); odil::Value const value3({3,4}); odil::Value const value4({3,4}); BOOST_CHECK(value1 == value2); BOOST_CHECK( ! (value1 == value3)); BOOST_CHECK( ! (value1 == value4)); } BOOST_AUTO_TEST_CASE(EqualityStrings) { odil::Value const value1({"1","2"}); odil::Value const value2({"1","2"}); odil::Value const value3({"3","4"}); odil::Value const value4({3,4}); BOOST_CHECK(value1 == value2); BOOST_CHECK( ! (value1 == value3)); BOOST_CHECK( ! (value1 == value4)); } BOOST_AUTO_TEST_CASE(EqualityDataSets) { odil::DataSet dataset1; dataset1.add("PatientID", {"DJ1234"}); dataset1.add("PixelSpacing", {1.5, 2.5}); odil::DataSet dataset2; dataset1.add("PatientName", {"Doe^John"}); dataset1.add("PatientAge", {"042Y"}); odil::Value const value1({dataset1}); odil::Value const value2({dataset1}); odil::Value const value3({dataset2}); odil::Value const value4({3,4}); BOOST_CHECK(value1 == value2); BOOST_CHECK( ! (value1 == value3)); BOOST_CHECK( ! (value1 == value4)); } BOOST_AUTO_TEST_CASE(DifferenceEmpty) { odil::Value const value1; odil::Value const value2; odil::Value const value3((odil::Value::Integers())); BOOST_CHECK(! (value1 != value2)); BOOST_CHECK(value1 != value3); } BOOST_AUTO_TEST_CASE(DifferenceIntegers) { odil::Value const value1({1,2}); odil::Value const value2({1,2}); odil::Value const value3({3,4}); odil::Value const value4({3,4}); BOOST_CHECK(! (value1 != value2)); BOOST_CHECK(value1 != value3); BOOST_CHECK(value1 != value4); } BOOST_AUTO_TEST_CASE(DifferenceReals) { odil::Value const value1({1.,2.}); odil::Value const value2({1.,2.}); odil::Value const value3({3.,4.}); odil::Value const value4({3,4}); BOOST_CHECK(! (value1 != value2)); BOOST_CHECK(value1 != value3); BOOST_CHECK(value1 != value4); } BOOST_AUTO_TEST_CASE(DifferenceStrings) { odil::Value const value1({"1","2"}); odil::Value const value2({"1","2"}); odil::Value const value3({"3","4"}); odil::Value const value4({3,4}); BOOST_CHECK(! (value1 != value2)); BOOST_CHECK(value1 != value3); BOOST_CHECK(value1 != value4); } BOOST_AUTO_TEST_CASE(DifferenceDataSets) { odil::DataSet dataset1; dataset1.add("PatientID", {"DJ1234"}); dataset1.add("PixelSpacing", {1.5, 2.5}); odil::DataSet dataset2; dataset1.add("PatientName", {"Doe^John"}); dataset1.add("PatientAge", {"042Y"}); odil::Value const value1({dataset1}); odil::Value const value2({dataset1}); odil::Value const value3({dataset2}); odil::Value const value4({3,4}); BOOST_CHECK(! (value1 != value2)); BOOST_CHECK(value1 != value3); BOOST_CHECK(value1 != value4); } struct Visitor { typedef std::string result_type; template result_type operator()(T const & container) const { return typeid(container).name(); } }; BOOST_AUTO_TEST_CASE(VisitorEmpty) { odil::Value const value; BOOST_CHECK_THROW( odil::apply_visitor(Visitor(), value), odil::Exception); } BOOST_AUTO_TEST_CASE(VisitorIntegers) { odil::Value const value({1234}); BOOST_REQUIRE_EQUAL( odil::apply_visitor(Visitor(), value), typeid(odil::Value::Integers).name()); } BOOST_AUTO_TEST_CASE(VisitorReals) { odil::Value const value({12.34}); BOOST_REQUIRE_EQUAL( odil::apply_visitor(Visitor(), value), typeid(odil::Value::Reals).name()); } BOOST_AUTO_TEST_CASE(VisitorStrings) { odil::Value const value({"foo"}); BOOST_REQUIRE_EQUAL( odil::apply_visitor(Visitor(), value), typeid(odil::Value::Strings).name()); } BOOST_AUTO_TEST_CASE(VisitorDataSets) { odil::Value const value({odil::DataSet()}); BOOST_REQUIRE_EQUAL( odil::apply_visitor(Visitor(), value), typeid(odil::Value::DataSets).name()); } BOOST_AUTO_TEST_CASE(VisitorBinary) { odil::Value const value((odil::Value::Binary())); BOOST_REQUIRE_EQUAL( odil::apply_visitor(Visitor(), value), typeid(odil::Value::Binary).name()); } odil-0.4.1/tests/code/Writer.cpp000066400000000000000000000235501266460524100165120ustar00rootroot00000000000000#define BOOST_TEST_MODULE Writer #include #include #include #include #include #include "odil/endian.h" #include "odil/Element.h" #include "odil/registry.h" #include "odil/Writer.h" #include "odil/VR.h" #include "odil/dcmtk/conversion.h" BOOST_AUTO_TEST_CASE(Constructor) { std::ostringstream stream; odil::Writer const writer(stream, odil::ByteOrdering::BigEndian, true); BOOST_REQUIRE(writer.byte_ordering == odil::ByteOrdering::BigEndian); BOOST_REQUIRE(writer.explicit_vr == true); } BOOST_AUTO_TEST_CASE(ConstructorTransferSyntax) { std::ostringstream stream; odil::Writer const writer(stream, odil::registry::ExplicitVRBigEndian_Retired); BOOST_REQUIRE(writer.byte_ordering == odil::ByteOrdering::BigEndian); BOOST_REQUIRE(writer.explicit_vr == true); } void do_test( odil::DataSet const & odil_data_set, std::string transfer_syntax, odil::Writer::ItemEncoding item_encoding, bool use_group_length) { // Write input data set std::stringstream stream; odil::Writer const writer( stream, transfer_syntax, item_encoding, use_group_length); writer.write_data_set(odil_data_set); // Store data in a DCMTK stream std::string const data = stream.str(); DcmInputBufferStream dcmtk_stream; dcmtk_stream.setBuffer(&data[0], data.size()); // Read output data set DcmDataset dcmtk_data_set; dcmtk_data_set.transferInit(); OFCondition const condition = dcmtk_data_set.read( dcmtk_stream, DcmXfer(transfer_syntax.c_str()).getXfer()); BOOST_REQUIRE(condition == EC_Normal || condition == EC_StreamNotifyClient); BOOST_REQUIRE_EQUAL(dcmtk_stream.avail(), 0); dcmtk_data_set.transferEnd(); auto const other_odil_dataset = odil::dcmtk::convert(&dcmtk_data_set); BOOST_REQUIRE(odil_data_set == other_odil_dataset); } void do_test(odil::DataSet const & odil_data_set) { std::vector const transfer_syntaxes = { odil::registry::ImplicitVRLittleEndian, odil::registry::ExplicitVRLittleEndian, odil::registry::ExplicitVRBigEndian_Retired }; std::vector item_encodings = { odil::Writer::ItemEncoding::ExplicitLength, odil::Writer::ItemEncoding::UndefinedLength }; std::vector use_group_length_values = {/*true, */false}; for(auto const & transfer_syntax: transfer_syntaxes) { for(auto const & item_encoding: item_encodings) { for(auto const & use_group_length: use_group_length_values) { do_test( odil_data_set, transfer_syntax, item_encoding, use_group_length); } } } } BOOST_AUTO_TEST_CASE(AT) { odil::Element odil_element({"00100020", "0008103e"}, odil::VR::AT); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorATValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(CS) { odil::Element odil_element({"ABC", "DEF"}, odil::VR::CS); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorCSValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(DS) { odil::Element odil_element({1.23, -4.56}, odil::VR::DS); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorDSValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(FD) { odil::Element odil_element({1.23, -4.56}, odil::VR::FD); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorFDValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(FL) { odil::Element odil_element({0.5, -0.125}, odil::VR::FL); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorFLValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(IS) { odil::Element odil_element({123, -456}, odil::VR::IS); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorISValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(OB) { odil::Element odil_element( std::vector({0x01, 0x02, 0x03, 0x04}), odil::VR::OB); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::EncapsulatedDocument, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(OF) { odil::Element odil_element( std::vector({0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}), odil::VR::OF); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::VectorGridData, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(OW) { odil::Element odil_element( std::vector({0x01, 0x02, 0x03, 0x04}), odil::VR::OW); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::RedPaletteColorLookupTableData, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(SL) { odil::Element odil_element({12345678, -8765432}, odil::VR::SL); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorSLValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(SQ) { odil::DataSet item1; item1.add( odil::registry::SelectorSLValue, odil::Element({12345678, -8765432}, odil::VR::SL)); odil::DataSet item2; item2.add( odil::registry::SelectorFDValue, odil::Element({1.23, -4.56}, odil::VR::FD)); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::FrameExtractionSequence, odil::Element({item1, item2}, odil::VR::SQ)); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(SS) { odil::Element odil_element({1234, -5678}, odil::VR::SS); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorSSValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(UI) { odil::Element odil_element({"1.2", "3.4"}, odil::VR::UI); odil::DataSet odil_data_set; // SelectorUIValue is not in current DCMTK odil_data_set.add(odil::registry::SOPInstanceUID, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(UL) { odil::Element odil_element({12345678, 8765432}, odil::VR::UL); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorULValue, odil_element); do_test(odil_data_set); } BOOST_AUTO_TEST_CASE(US) { odil::Element odil_element({1234, 5678}, odil::VR::US); odil::DataSet odil_data_set; odil_data_set.add(odil::registry::SelectorUSValue, odil_element); do_test(odil_data_set); } void do_file_test( odil::DataSet const & odil_data_set, std::string transfer_syntax, odil::Writer::ItemEncoding item_encoding, bool use_group_length) { // Write input data set std::stringstream stream; odil::Writer::write_file( odil_data_set, stream, odil::DataSet(), transfer_syntax, item_encoding, use_group_length); // Store data in a DCMTK stream std::string const data = stream.str(); DcmInputBufferStream dcmtk_stream; dcmtk_stream.setBuffer(&data[0], data.size()); // Read output data set DcmFileFormat format; format.transferInit(); OFCondition const condition = format.read(dcmtk_stream); BOOST_REQUIRE(condition == EC_Normal || condition == EC_StreamNotifyClient); BOOST_REQUIRE_EQUAL(dcmtk_stream.avail(), 0); format.transferEnd(); DcmMetaInfo * dcmtk_meta_information = format.getMetaInfo(); auto const odil_meta_information = odil::dcmtk::convert(dcmtk_meta_information); BOOST_REQUIRE( odil_meta_information.as_string(odil::registry::TransferSyntaxUID) == odil::Value::Strings({ transfer_syntax })); DcmDataset * dcmtk_data_set = format.getDataset(); auto const other_odil_dataset = odil::dcmtk::convert(dcmtk_data_set); BOOST_REQUIRE(odil_data_set == other_odil_dataset); BOOST_REQUIRE( odil_meta_information.as_string(odil::registry::MediaStorageSOPClassUID) == other_odil_dataset.as_string(odil::registry::SOPClassUID)); BOOST_REQUIRE( odil_meta_information.as_string(odil::registry::MediaStorageSOPInstanceUID) == other_odil_dataset.as_string(odil::registry::SOPInstanceUID)); } void do_file_test(odil::DataSet const & odil_data_set) { std::vector const transfer_syntaxes = { odil::registry::ImplicitVRLittleEndian, odil::registry::ExplicitVRLittleEndian, odil::registry::ExplicitVRBigEndian_Retired }; std::vector item_encodings = { odil::Writer::ItemEncoding::ExplicitLength, odil::Writer::ItemEncoding::UndefinedLength }; std::vector use_group_length_values = {/*true, */false}; for(auto const & transfer_syntax: transfer_syntaxes) { for(auto const & item_encoding: item_encodings) { for(auto const & use_group_length: use_group_length_values) { do_file_test( odil_data_set, transfer_syntax, item_encoding, use_group_length); } } } } BOOST_AUTO_TEST_CASE(File) { odil::DataSet item1; item1.add( odil::registry::SelectorSLValue, odil::Element({12345678, -8765432}, odil::VR::SL)); odil::DataSet item2; item2.add( odil::registry::SelectorFDValue, odil::Element({1.23, -4.56}, odil::VR::FD)); odil::DataSet odil_data_set; odil_data_set.add( odil::registry::SOPClassUID, {odil::registry::RawDataStorage}, odil::VR::UI); odil_data_set.add( odil::registry::SOPInstanceUID, {"1.2.3.4"}, odil::VR::UI); odil_data_set.add( odil::registry::FrameExtractionSequence, odil::Element({item1, item2}, odil::VR::SQ)); do_file_test(odil_data_set); } odil-0.4.1/tests/code/base64.cpp000066400000000000000000000041471266460524100163230ustar00rootroot00000000000000#define BOOST_TEST_MODULE Base64 #include #include #include #include "odil/base64.h" void test_encode(std::string const & data, std::string const & expected) { std::string encoded; encoded.reserve(data.size()*4/3); odil::base64::encode( data.begin(), data.end(), std::back_inserter(encoded)); BOOST_REQUIRE_EQUAL(encoded, expected); } void test_decode(std::string const & data, std::string const & expected) { std::string decoded; decoded.reserve(data.size()*3/4); odil::base64::decode( data.begin(), data.end(), std::back_inserter(decoded)); BOOST_REQUIRE_EQUAL(decoded, expected); } BOOST_AUTO_TEST_CASE(EncodeEmpty) { test_encode("", ""); } BOOST_AUTO_TEST_CASE(Encode1) { test_encode( "Lorem ipsum dolor sit amet.", "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQu"); } BOOST_AUTO_TEST_CASE(Encode2) { test_encode( "Lorem ipsum dolor sit amet", "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ="); } BOOST_AUTO_TEST_CASE(Encode3) { test_encode( "Lorem ipsum dolor sit ame", "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZQ=="); } BOOST_AUTO_TEST_CASE(DecodeEmpty) { test_decode("", ""); } BOOST_AUTO_TEST_CASE(Decode1) { test_decode( "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQu", "Lorem ipsum dolor sit amet."); } BOOST_AUTO_TEST_CASE(Decode2) { test_decode( "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ=", "Lorem ipsum dolor sit amet"); } BOOST_AUTO_TEST_CASE(Decode3) { test_decode( "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZQ==", "Lorem ipsum dolor sit ame"); } BOOST_AUTO_TEST_CASE(AllStates) { uint8_t data[3]; uint8_t encoded[4]; uint8_t decoded[3]; for(int z=0; z<256; ++z) { for(int y=0; y<256; ++y) { for(int x=0; x<256; ++x) { data[0] = x; data[1] = y; data[2] = z; odil::base64::encode(data, data+3, encoded); odil::base64::decode(encoded, encoded+4, decoded); BOOST_REQUIRE(std::equal(data, data+3, decoded)); } } } } odil-0.4.1/tests/code/conversion.cpp000066400000000000000000000320371266460524100174230ustar00rootroot00000000000000#define BOOST_TEST_MODULE conversion #include #include #include #include "odil/DataSet.h" #include "odil/Tag.h" #include "odil/Value.h" #include "odil/VR.h" #include "odil/dcmtk/VRTraits.h" #include "odil/dcmtk/conversion.h" #include "odil/dcmtk/ElementAccessor.h" BOOST_AUTO_TEST_CASE(TagFromDcmtkpp) { odil::Tag const source(0xdead, 0xbeef); DcmTagKey const destination = odil::dcmtk::convert(source); BOOST_CHECK_EQUAL(destination.getGroup(), 0xdead); BOOST_CHECK_EQUAL(destination.getElement(), 0xbeef); } BOOST_AUTO_TEST_CASE(TagFromDcmtk) { DcmTagKey const source(0xdead, 0xbeef); odil::Tag const destination = odil::dcmtk::convert(source); BOOST_CHECK_EQUAL(destination.group, 0xdead); BOOST_CHECK_EQUAL(destination.element, 0xbeef); } template void compare(TValueType const & t1, TValueType const & t2) { BOOST_CHECK_EQUAL(t1, t2); } template<> void compare( odil::Value::Reals::value_type const & t1, odil::Value::Reals::value_type const & t2) { BOOST_CHECK_CLOSE(t1, t2, 1e-6); } template void test_element_from_odil( TInputType const & source_value, TInputType const & (odil::Element::*getter)() const) { odil::Tag const source_tag(0xdead, 0xbeef); DcmTagKey const destination_tag = odil::dcmtk::convert(source_tag); odil::Element const source(source_value, VVR); DcmElement * destination = odil::dcmtk::convert(source_tag, source); BOOST_CHECK_NE(destination, (DcmElement const *)(NULL)); BOOST_CHECK_EQUAL(destination->getVR(), VEVR); BOOST_CHECK_NE( dynamic_cast(destination), (TOutputType *)(NULL)); BOOST_CHECK_EQUAL(destination->getVM(), source.size()); for(std::size_t i=0; i::ValueType ValueType; if(typeid(TInputType) == typeid(odil::Value::Reals)) { compare( odil::dcmtk::ElementAccessor::element_get(*destination, i), (source.*getter)()[i]); } else { BOOST_CHECK_EQUAL( odil::dcmtk::ElementAccessor::element_get(*destination, i), (source.*getter)()[i]); } } } template void test_element_to_odil( TInputType const & source_value, TInputType const & (odil::Element::*getter)() const) { DcmTag const source_tag(0xdead, 0xbeef, VEVR); TElementType source(source_tag); if(typeid(TInputType) == typeid(odil::Value::Strings) || VEVR == EVR_IS || VEVR == EVR_DS) { OFString value; if(!source_value.empty()) { auto const last_it = --source_value.end(); auto it = source_value.begin(); while(it != last_it) { std::ostringstream stream; stream << *it; value += stream.str().c_str(); value += "\\"; ++it; } std::ostringstream stream; stream << *last_it; value += stream.str().c_str(); } source.putOFStringArray(value); } else { for(unsigned int i=0; i::ValueType>::element_set( source, item, i); } } odil::Element const destination = odil::dcmtk::convert(&source); BOOST_CHECK(VVR == destination.vr); BOOST_CHECK_EQUAL(source.getVM(), destination.size()); for(std::size_t i=0; i::ValueType ValueType; if(typeid(TInputType) == typeid(odil::Value::Reals)) { compare( odil::dcmtk::ElementAccessor::element_get(source, i), (destination.*getter)()[i]); } else { BOOST_CHECK_EQUAL( odil::dcmtk::ElementAccessor::element_get(source, i), (destination.*getter)()[i]); } } } #define ElementTest(vr, InputType, ElementType, value, getter) \ BOOST_AUTO_TEST_CASE(vr##FromOdil) \ { \ test_element_from_odil< \ odil::VR::vr, EVR_##vr, InputType, ElementType>(value, getter); \ } \ BOOST_AUTO_TEST_CASE(vr##ToOdil) \ { \ test_element_to_odil< \ odil::VR::vr, EVR_##vr, InputType, ElementType>(value, getter); \ } ElementTest( AE, odil::Value::Strings, DcmApplicationEntity, odil::Value::Strings({"foo", "bar"}), &odil::Element::as_string); ElementTest( AS, odil::Value::Strings, DcmAgeString, odil::Value::Strings({"012Y", "345D"}), &odil::Element::as_string); ElementTest( CS, odil::Value::Strings, DcmCodeString, odil::Value::Strings({"foo", "bar"}), &odil::Element::as_string); ElementTest( DA, odil::Value::Strings, DcmDate, odil::Value::Strings({"19000101", "20131215"}), &odil::Element::as_string); ElementTest( DS, odil::Value::Reals, DcmDecimalString, odil::Value::Reals({12.34, 56.78}), &odil::Element::as_real); ElementTest( DT, odil::Value::Strings, DcmDateTime, odil::Value::Strings({"19000101123456", "201312150123"}), &odil::Element::as_string); ElementTest( FL, odil::Value::Reals, DcmFloatingPointSingle, odil::Value::Reals({12.34, 56.78}), &odil::Element::as_real); ElementTest( FD, odil::Value::Reals, DcmFloatingPointDouble, odil::Value::Reals({12.34, 56.78}), &odil::Element::as_real); ElementTest( IS, odil::Value::Integers, DcmIntegerString, odil::Value::Integers({34567, -67890}), &odil::Element::as_int); ElementTest( LO, odil::Value::Strings, DcmLongString, odil::Value::Strings({"foo bar", "something else"}), &odil::Element::as_string); ElementTest( LT, odil::Value::Strings, DcmLongText, odil::Value::Strings({"foo\nbar\\something else"}), &odil::Element::as_string); // OB // OF // OW ElementTest( PN, odil::Value::Strings, DcmPersonName, odil::Value::Strings({"Doe^John", "^Bob^Dr."}), &odil::Element::as_string); ElementTest( SH, odil::Value::Strings, DcmShortString, odil::Value::Strings({"foo", "bar"}), &odil::Element::as_string); ElementTest( SL, odil::Value::Integers, DcmSignedLong, odil::Value::Integers({34567, -56789}), &odil::Element::as_int); ElementTest( SS, odil::Value::Integers, DcmSignedShort, odil::Value::Integers({1234, -5678}), &odil::Element::as_int); ElementTest( ST, odil::Value::Strings, DcmShortText, odil::Value::Strings({"foo\nbar\\something else"}), &odil::Element::as_string); ElementTest( TM, odil::Value::Strings, DcmTime, odil::Value::Strings({"123456", "0123"}), &odil::Element::as_string); ElementTest( UI, odil::Value::Strings, DcmUniqueIdentifier, odil::Value::Strings( {"1.2.840.10008.5.1.4.1.1.4", "1.2.840.10008.5.1.4.1.1.4.1"}), &odil::Element::as_string); ElementTest( UL, odil::Value::Integers, DcmUnsignedLong, odil::Value::Integers({123456, 789012}), &odil::Element::as_int); // UN ElementTest( US, odil::Value::Integers, DcmUnsignedShort, odil::Value::Integers({12345, 6789}), &odil::Element::as_int); ElementTest( UT, odil::Value::Strings, DcmUnlimitedText, odil::Value::Strings({"foo\nbar\\something else"}), &odil::Element::as_string); BOOST_AUTO_TEST_CASE(ATFromDcmtkpp) { odil::Element const source( odil::Value::Strings({"deadbeef", "beeff00d"}), odil::VR::AT); DcmElement * destination = odil::dcmtk::convert( odil::Tag(0x1234, 0x5678), source); BOOST_CHECK_NE(destination, (DcmElement const *)(NULL)); BOOST_CHECK_EQUAL(destination->getVR(), odil::dcmtk::convert(source.vr)); BOOST_CHECK_NE( dynamic_cast(destination), (DcmAttributeTag *)(NULL)); BOOST_CHECK_EQUAL(destination->getVM(), source.size()); for(std::size_t i=0; igetTagVal(destination_tag, i); BOOST_CHECK(condition.good()); BOOST_CHECK(source_tag == odil::dcmtk::convert(destination_tag)); } } BOOST_AUTO_TEST_CASE(ATToDcmtkpp) { DcmAttributeTag source(DcmTag(0x1234, 0x5678, EVR_AT)); source.putTagVal(DcmTagKey(0xdead, 0xbeef), 0); source.putTagVal(DcmTagKey(0xbeef, 0xf00d), 1); odil::Element const destination = odil::dcmtk::convert(&source); BOOST_CHECK(destination.vr == odil::dcmtk::convert(source.getVR())); BOOST_CHECK_EQUAL(source.getVM(), destination.size()); for(std::size_t i=0; igetVR(), odil::dcmtk::convert(source.vr)); BOOST_CHECK_NE( dynamic_cast(destination), (DcmSequenceOfItems *)(NULL)); BOOST_CHECK_EQUAL(destination->getVM(), source.size()); for(std::size_t i=0; i(destination)->getItem(i); BOOST_CHECK(source_item == odil::dcmtk::convert(destination_item)); } } BOOST_AUTO_TEST_CASE(SQToDcmtkpp) { DcmDataset * item = new DcmDataset; item->putAndInsertOFStringArray(DCM_PatientID, "DJ1234"); DcmSequenceOfItems source(DcmTag(0xdead, 0xbeef, EVR_SQ)); source.append(item); odil::Element const destination = odil::dcmtk::convert(&source); BOOST_CHECK(destination.vr == odil::dcmtk::convert(source.getVR())); BOOST_CHECK_EQUAL(source.getVM(), destination.size()); for(std::size_t i=0; i(item); BOOST_REQUIRE(source_item != NULL); odil::DataSet const & destination_item = destination.as_data_set()[i]; BOOST_CHECK(odil::dcmtk::convert(source_item) == destination_item); } } BOOST_AUTO_TEST_CASE(EmptyDataSetFromDcmtkpp) { odil::DataSet empty; DcmItem * result = odil::dcmtk::convert(empty); BOOST_CHECK_EQUAL(result->card(), 0); } BOOST_AUTO_TEST_CASE(EmptyDataSetFromDcmtk) { DcmDataset empty; odil::DataSet const result = odil::dcmtk::convert(&empty); BOOST_CHECK(result.empty()); } BOOST_AUTO_TEST_CASE(DataSetFromDcmtkpp) { odil::Element const patient_id_source( odil::Value::Strings({"DJ1234"}), odil::VR::CS); odil::Element const pixel_spacing_source( odil::Value::Reals({1.23, 4.56}), odil::VR::DS); odil::DataSet source; source.add(odil::Tag("PatientID"), patient_id_source); source.add(odil::Tag("PixelSpacing"), pixel_spacing_source); DcmItem * result = odil::dcmtk::convert(source); BOOST_CHECK_EQUAL(result->card(), 2); DcmElement * patient_id; OFCondition const patient_id_ok = result->findAndGetElement(DCM_PatientID, patient_id); BOOST_CHECK(patient_id_ok.good()); BOOST_CHECK( odil::dcmtk::convert(patient_id).as_string() == patient_id_source.as_string()); DcmElement * pixel_spacing; OFCondition const pixel_spacing_ok = result->findAndGetElement(DCM_PixelSpacing, pixel_spacing); BOOST_CHECK(pixel_spacing_ok.good()); BOOST_CHECK( odil::dcmtk::convert(pixel_spacing).as_real() == pixel_spacing_source.as_real()); } BOOST_AUTO_TEST_CASE(DataSetFromDcmtk) { odil::Element const patient_id_source( odil::Value::Strings({"DJ1234"}), odil::VR::CS); odil::Element const pixel_spacing_source( odil::Value::Reals({1.23, 4.56}), odil::VR::DS); DcmDataset source; source.insert(odil::dcmtk::convert(odil::Tag("PatientID"), patient_id_source)); source.insert(odil::dcmtk::convert(odil::Tag("PixelSpacing"), pixel_spacing_source)); odil::DataSet const result = odil::dcmtk::convert(&source); BOOST_CHECK_EQUAL(result.size(), 2); BOOST_CHECK( result.as_string(odil::Tag("PatientID")) == patient_id_source.as_string()); BOOST_CHECK( result.as_real(odil::Tag("PixelSpacing")) == pixel_spacing_source.as_real()); } odil-0.4.1/tests/code/dul/000077500000000000000000000000001266460524100153115ustar00rootroot00000000000000odil-0.4.1/tests/code/dul/StateMachine.cpp000066400000000000000000000011221266460524100203560ustar00rootroot00000000000000#define BOOST_TEST_MODULE StateMachine #include #include "odil/Exception.h" #include "odil/dul/EventData.h" #include "odil/dul/StateMachine.h" BOOST_AUTO_TEST_CASE(Constructor) { odil::dul::StateMachine state_machine; BOOST_REQUIRE( state_machine.get_state() == odil::dul::StateMachine::State::Sta1); } BOOST_AUTO_TEST_CASE(WrongTransition) { odil::dul::StateMachine state_machine; odil::dul::EventData data; BOOST_REQUIRE_THROW( state_machine.transition(odil::dul::StateMachine::Event::None, data), odil::Exception); } odil-0.4.1/tests/code/dul/Transport.cpp000066400000000000000000000022661266460524100200170ustar00rootroot00000000000000#define BOOST_TEST_MODULE Transport #include #include #include #include "odil/Exception.h" #include "odil/dul/Transport.h" BOOST_AUTO_TEST_CASE(Constructor) { odil::dul::Transport transport; BOOST_REQUIRE(!transport.is_open()); } BOOST_AUTO_TEST_CASE(Connect) { odil::dul::Transport transport; boost::asio::ip::tcp::resolver resolver(transport.get_service()); boost::asio::ip::tcp::resolver::query const query( odil::dul::Transport::Socket::protocol_type::v4(), "www.example.com", "80"); auto const endpoint_it = resolver.resolve(query); transport.connect(*endpoint_it); BOOST_REQUIRE(transport.is_open()); transport.write("HEAD / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"); auto const response = transport.read(128); BOOST_REQUIRE(!response.empty()); transport.close(); BOOST_REQUIRE(!transport.is_open()); } BOOST_AUTO_TEST_CASE(NotConnected) { odil::dul::Transport transport; BOOST_REQUIRE_THROW(transport.write("..."), odil::Exception); BOOST_REQUIRE_THROW(transport.read(1), odil::Exception); BOOST_REQUIRE_THROW(transport.close(), odil::Exception); } odil-0.4.1/tests/code/endian.cpp000066400000000000000000000043161266460524100164730ustar00rootroot00000000000000#define BOOST_TEST_MODULE endian #include #include #include "odil/endian.h" BOOST_AUTO_TEST_CASE(ToLittleEndian16) { uint16_t const input = 0x1234; std::string const expected("\x34\x12"); BOOST_REQUIRE_EQUAL( odil::host_to_little_endian(input), *reinterpret_cast(&expected[0]) ); } BOOST_AUTO_TEST_CASE(ToLittleEndian32) { uint32_t const input = 0x12345678; std::string const expected("\x78\x56\x34\x12"); BOOST_REQUIRE_EQUAL( odil::host_to_little_endian(input), *reinterpret_cast(&expected[0]) ); } BOOST_AUTO_TEST_CASE(ToBigEndian16) { uint16_t const input = 0x1234; std::string const expected("\x12\x34"); BOOST_REQUIRE_EQUAL( odil::host_to_big_endian(input), *reinterpret_cast(&expected[0]) ); } BOOST_AUTO_TEST_CASE(ToBigEndian32) { uint32_t const input = 0x12345678; std::string const expected("\x12\x34\x56\x78"); BOOST_REQUIRE_EQUAL( odil::host_to_big_endian(input), *reinterpret_cast(&expected[0]) ); } BOOST_AUTO_TEST_CASE(FromLittleEndian16) { std::string const input("\x34\x12"); uint16_t const expected = 0x1234; BOOST_REQUIRE_EQUAL( odil::little_endian_to_host( *reinterpret_cast(&input[0])), expected ); } BOOST_AUTO_TEST_CASE(FromLittleEndian32) { std::string const input("\x78\x56\x34\x12"); uint32_t const expected = 0x12345678; BOOST_REQUIRE_EQUAL( odil::little_endian_to_host( *reinterpret_cast(&input[0])), expected ); } BOOST_AUTO_TEST_CASE(FromBigEndian16) { std::string const input("\x12\x34"); uint16_t const expected = 0x1234; BOOST_REQUIRE_EQUAL( odil::big_endian_to_host( *reinterpret_cast(&input[0])), expected ); } BOOST_AUTO_TEST_CASE(FromBigEndian32) { std::string const input("\x12\x34\x56\x78"); uint32_t const expected = 0x12345678; BOOST_REQUIRE_EQUAL( odil::big_endian_to_host( *reinterpret_cast(&input[0])), expected ); } odil-0.4.1/tests/code/json_converter.cpp000066400000000000000000000224451266460524100203000ustar00rootroot00000000000000#define BOOST_TEST_MODULE json_converter #include #include #include #include #include #include "odil/DataSet.h" #include "odil/Element.h" #include "odil/json_converter.h" #include "odil/Value.h" #include "odil/VR.h" BOOST_AUTO_TEST_CASE(AsJSONEmptyDataSet) { odil::DataSet data_set; auto const json = odil::as_json(data_set); BOOST_REQUIRE(json.empty()); } template void check_json_array( Json::Value const & object, TChecker checker, TGetter getter, TValue const & expected) { BOOST_REQUIRE(object.isArray()); BOOST_REQUIRE_EQUAL(object.size(), expected.size()); for(Json::ArrayIndex i=0; i const & expected_members) { BOOST_REQUIRE(object.isObject()); auto const members = object.getMemberNames(); BOOST_REQUIRE( std::set(members.begin(), members.end()) == expected_members); } void check_json_string(Json::Value const & object, std::string const & expected_value) { BOOST_REQUIRE(object.isString()); BOOST_REQUIRE_EQUAL(object.asString(), expected_value); } BOOST_AUTO_TEST_CASE(AsJSONEmptyElement) { odil::DataSet data_set; data_set.add(0xdeadbeef, odil::VR::SS); auto const json = odil::as_json(data_set); check_json_object(json, {"deadbeef"}); check_json_object(json["deadbeef"], {"vr"}); check_json_string(json["deadbeef"]["vr"], "SS"); } BOOST_AUTO_TEST_CASE(AsJSONIntegers) { odil::DataSet data_set; data_set.add(0xdeadbeef, odil::Element(odil::Value::Integers({1, 2}), odil::VR::SS)); auto const json = odil::as_json(data_set); check_json_object(json, {"deadbeef"}); check_json_object(json["deadbeef"], {"vr", "Value"}); check_json_string(json["deadbeef"]["vr"], "SS"); check_json_array(json["deadbeef"]["Value"], &Json::Value::isInt, &Json::Value::asInt, data_set.as_int(0xdeadbeef)); } BOOST_AUTO_TEST_CASE(AsJSONReals) { odil::DataSet data_set; data_set.add(0xdeadbeef, odil::Element(odil::Value::Reals({1.2, 3.4}), odil::VR::FL)); auto const json = odil::as_json(data_set); check_json_object(json, {"deadbeef"}); check_json_object(json["deadbeef"], {"vr", "Value"}); check_json_string(json["deadbeef"]["vr"], "FL"); check_json_array(json["deadbeef"]["Value"], &Json::Value::isDouble, &Json::Value::asDouble, data_set.as_real(0xdeadbeef)); } BOOST_AUTO_TEST_CASE(AsJSONStrings) { odil::DataSet data_set; data_set.add(0xdeadbeef, odil::Element( odil::Value::Strings({"FOO", "BAR"}), odil::VR::CS)); auto const json = odil::as_json(data_set); check_json_object(json, {"deadbeef"}); check_json_object(json["deadbeef"], {"vr", "Value"}); check_json_string(json["deadbeef"]["vr"], "CS"); check_json_array(json["deadbeef"]["Value"], &Json::Value::isString, &Json::Value::asString, data_set.as_string(0xdeadbeef)); } BOOST_AUTO_TEST_CASE(AsJSONPersonName) { odil::DataSet data_set; data_set.add(0xdeadbeef, odil::Element( odil::Value::Strings({"Alpha^Betic=Ideo^Graphic=Pho^Netic"}), odil::VR::PN)); auto const json = odil::as_json(data_set); check_json_object(json, {"deadbeef"}); check_json_object(json["deadbeef"], {"vr", "Value"}); check_json_string(json["deadbeef"]["vr"], "PN"); BOOST_REQUIRE(json["deadbeef"]["Value"].isArray()); BOOST_REQUIRE_EQUAL(json["deadbeef"]["Value"].size(), 1); check_json_object( json["deadbeef"]["Value"][0], {"Alphabetic", "Ideographic", "Phonetic"}); check_json_string(json["deadbeef"]["Value"][0]["Alphabetic"], {"Alpha^Betic"}); check_json_string(json["deadbeef"]["Value"][0]["Ideographic"], {"Ideo^Graphic"}); check_json_string(json["deadbeef"]["Value"][0]["Phonetic"], {"Pho^Netic"}); } BOOST_AUTO_TEST_CASE(AsJSONDataSets) { odil::DataSet item; item.add(0xbeeff00d, odil::Element(odil::Value::Integers({1,2}), odil::VR::SS)); odil::DataSet data_set; data_set.add(0xdeadbeef, odil::Element( odil::Value::DataSets({item}), odil::VR::SQ)); auto const json = odil::as_json(data_set); check_json_object(json, {"deadbeef"}); check_json_object(json["deadbeef"], {"vr", "Value"}); check_json_string(json["deadbeef"]["vr"], "SQ"); BOOST_REQUIRE(json["deadbeef"]["Value"].isArray()); BOOST_REQUIRE_EQUAL(json["deadbeef"]["Value"].size(), 1); check_json_object(json["deadbeef"]["Value"][0], {"beeff00d"}); check_json_object(json["deadbeef"]["Value"][0]["beeff00d"], {"vr", "Value"}); check_json_string(json["deadbeef"]["Value"][0]["beeff00d"]["vr"], "SS"); check_json_array(json["deadbeef"]["Value"][0]["beeff00d"]["Value"], &Json::Value::isInt, &Json::Value::asInt, item.as_int(0xbeeff00d)); } BOOST_AUTO_TEST_CASE(AsJSONBinary) { odil::DataSet data_set; data_set.add(0xdeadbeef, odil::Element( odil::Value::Binary({0x1, 0x2, 0x3, 0x4, 0x5}), odil::VR::OB)); auto const json = odil::as_json(data_set); check_json_object(json, {"deadbeef"}); check_json_object(json["deadbeef"], {"vr", "InlineBinary"}); check_json_string(json["deadbeef"]["vr"], "OB"); check_json_string(json["deadbeef"]["InlineBinary"], "AQIDBAU="); } BOOST_AUTO_TEST_CASE(AsDataSetEmpty) { std::stringstream data; data << "{ }"; Json::Value json; data >> json; odil::DataSet const data_set = odil::as_dataset(json); BOOST_REQUIRE(data_set.empty()); } BOOST_AUTO_TEST_CASE(AsDataSetIntegers) { std::stringstream data; data << "{ \"deadbeef\": { \"vr\": \"SS\", \"Value\": [1, 2] } }"; Json::Value json; data >> json; odil::DataSet const data_set = odil::as_dataset(json); BOOST_REQUIRE_EQUAL(data_set.size(), 1); BOOST_REQUIRE(data_set.has("deadbeef")); BOOST_REQUIRE(data_set.get_vr("deadbeef") == odil::VR::SS); BOOST_REQUIRE(data_set.is_int("deadbeef")); BOOST_REQUIRE(data_set.as_int("deadbeef") == odil::Value::Integers({1, 2})); } BOOST_AUTO_TEST_CASE(AsDataSetReals) { std::stringstream data; data << "{ \"deadbeef\": { \"vr\": \"FL\", \"Value\": [1.2, 3.4] } }"; Json::Value json; data >> json; odil::DataSet const data_set = odil::as_dataset(json); BOOST_REQUIRE_EQUAL(data_set.size(), 1); BOOST_REQUIRE(data_set.has("deadbeef")); BOOST_REQUIRE(data_set.get_vr("deadbeef") == odil::VR::FL); BOOST_REQUIRE(data_set.is_real("deadbeef")); BOOST_REQUIRE(data_set.as_real("deadbeef") == odil::Value::Reals({1.2, 3.4})); } BOOST_AUTO_TEST_CASE(AsDataSetStrings) { std::stringstream data; data << "{ \"deadbeef\": { \"vr\": \"CS\", \"Value\": [\"FOO\", \"BAR\"] } }"; Json::Value json; data >> json; odil::DataSet const data_set = odil::as_dataset(json); BOOST_REQUIRE_EQUAL(data_set.size(), 1); BOOST_REQUIRE(data_set.has("deadbeef")); BOOST_REQUIRE(data_set.get_vr("deadbeef") == odil::VR::CS); BOOST_REQUIRE(data_set.is_string("deadbeef")); BOOST_REQUIRE(data_set.as_string("deadbeef") == odil::Value::Strings({"FOO", "BAR"})); } BOOST_AUTO_TEST_CASE(AsDataSetPersonName) { std::stringstream data; data << "{ \"deadbeef\": { \"vr\": \"PN\", \"Value\": [ "; data << "{ \"Alphabetic\": \"Alpha^Betic\" , "; data << "\"Ideographic\": \"Ideo^Graphic\" , "; data << "\"Phonetic\": \"Pho^Netic\" } "; data << " ] } }"; Json::Value json; data >> json; odil::DataSet const data_set = odil::as_dataset(json); BOOST_REQUIRE_EQUAL(data_set.size(), 1); BOOST_REQUIRE(data_set.has("deadbeef")); BOOST_REQUIRE(data_set.get_vr("deadbeef") == odil::VR::PN); BOOST_REQUIRE(data_set.is_string("deadbeef")); BOOST_REQUIRE(data_set.as_string("deadbeef") == odil::Value::Strings( {"Alpha^Betic=Ideo^Graphic=Pho^Netic"})); } BOOST_AUTO_TEST_CASE(AsDataSetDataSets) { std::stringstream data; data << "{ \"deadbeef\": { \"vr\": \"SQ\", \"Value\": [ "; data << "{ \"beeff00d\": { \"vr\": \"SS\", \"Value\": [1, 2] } }"; data << " ] } }"; Json::Value json; data >> json; odil::DataSet const data_set = odil::as_dataset(json); BOOST_REQUIRE_EQUAL(data_set.size(), 1); BOOST_REQUIRE(data_set.has("deadbeef")); BOOST_REQUIRE(data_set.get_vr("deadbeef") == odil::VR::SQ); BOOST_REQUIRE(data_set.is_data_set("deadbeef")); odil::DataSet item; item.add(0xbeeff00d, odil::Element(odil::Value::Integers({1,2}), odil::VR::SS)); BOOST_REQUIRE(data_set.as_data_set("deadbeef") == odil::Value::DataSets({item})); } BOOST_AUTO_TEST_CASE(AsDataSetBinary) { std::stringstream data; data << "{ \"deadbeef\": { \"vr\": \"OB\", \"InlineBinary\": \"AQIDBAU=\" } }"; Json::Value json; data >> json; odil::DataSet const data_set = odil::as_dataset(json); BOOST_REQUIRE_EQUAL(data_set.size(), 1); BOOST_REQUIRE(data_set.has("deadbeef")); BOOST_REQUIRE(data_set.get_vr("deadbeef") == odil::VR::OB); BOOST_REQUIRE(data_set.is_binary("deadbeef")); BOOST_REQUIRE(data_set.as_binary("deadbeef") == odil::Value::Binary( {0x1, 0x2, 0x3, 0x4, 0x5})); } odil-0.4.1/tests/code/message/000077500000000000000000000000001266460524100161515ustar00rootroot00000000000000odil-0.4.1/tests/code/message/CEchoRequest.cpp000066400000000000000000000034051266460524100212110ustar00rootroot00000000000000#define BOOST_TEST_MODULE CEchoRequest #include #include "odil/message/CEchoRequest.h" #include "odil/DataSet.h" #include "odil/message/Message.h" #include "odil/registry.h" #include "../../MessageFixtureBase.h" struct Fixture: public MessageFixtureBase { odil::DataSet command_set; Fixture() { this->command_set.add( "CommandField", {odil::message::Message::Command::C_ECHO_RQ}); this->command_set.add("MessageID", {1234}); this->command_set.add( "AffectedSOPClassUID", {odil::registry::VerificationSOPClass}); } void check(odil::message::CEchoRequest const & message) { BOOST_CHECK_EQUAL( message.get_command_field(), odil::message::Message::Command::C_ECHO_RQ); BOOST_CHECK_EQUAL(message.get_message_id(), 1234); BOOST_CHECK_EQUAL( message.get_affected_sop_class_uid(), odil::registry::VerificationSOPClass); BOOST_CHECK(!message.has_data_set()); } }; BOOST_FIXTURE_TEST_CASE(Constructor, Fixture) { odil::message::CEchoRequest const message( 1234, odil::registry::VerificationSOPClass); this->check(message); } BOOST_FIXTURE_TEST_CASE(MessageConstructor, Fixture) { this->check_message_constructor(this->command_set); } BOOST_FIXTURE_TEST_CASE(MessageConstructorWrongCommandField, Fixture) { this->command_set.as_int("CommandField") = { odil::message::Message::Command::C_ECHO_RSP}; this->check_message_constructor_throw(this->command_set); } BOOST_FIXTURE_TEST_CASE(MessageConstructorMissingAffectSOPClass, Fixture) { this->command_set.remove("AffectedSOPClassUID"); this->check_message_constructor_throw(this->command_set); } odil-0.4.1/tests/code/message/CEchoResponse.cpp000066400000000000000000000040051266460524100213540ustar00rootroot00000000000000#define BOOST_TEST_MODULE CEchoResponse #include #include "odil/message/CEchoResponse.h" #include "odil/DataSet.h" #include "odil/message/Message.h" #include "odil/registry.h" #include "../../MessageFixtureBase.h" struct Fixture: public MessageFixtureBase { odil::DataSet command_set; Fixture() { this->command_set.add( "CommandField", {odil::message::Message::Command::C_ECHO_RSP}); this->command_set.add("MessageIDBeingRespondedTo", {1234}); this->command_set.add("Status", {odil::message::Response::Success}); this->command_set.add( "AffectedSOPClassUID", {odil::registry::VerificationSOPClass}); } void check(odil::message::CEchoResponse const & message) { BOOST_CHECK_EQUAL( message.get_command_field(), odil::message::Message::Command::C_ECHO_RSP); BOOST_CHECK_EQUAL(message.get_message_id_being_responded_to(), 1234); BOOST_CHECK_EQUAL( message.get_status(), odil::message::Response::Success); BOOST_CHECK_EQUAL( message.get_affected_sop_class_uid(), odil::registry::VerificationSOPClass); BOOST_CHECK(!message.has_data_set()); } }; BOOST_FIXTURE_TEST_CASE(Constructor, Fixture) { odil::message::CEchoResponse const message( 1234, odil::message::Response::Success, odil::registry::VerificationSOPClass); this->check(message); } BOOST_FIXTURE_TEST_CASE(MessageConstructor, Fixture) { this->check_message_constructor(this->command_set); } BOOST_FIXTURE_TEST_CASE(MessageConstructorWrongCommandField, Fixture) { this->command_set.as_int("CommandField") = { odil::message::Message::Command::C_ECHO_RQ}; this->check_message_constructor_throw(this->command_set); } BOOST_FIXTURE_TEST_CASE(MessageConstructorMissingAffectSOPClass, Fixture) { this->command_set.remove("AffectedSOPClassUID"); this->check_message_constructor_throw(this->command_set); } odil-0.4.1/tests/code/message/CFindRequest.cpp000066400000000000000000000053211266460524100212120ustar00rootroot00000000000000#define BOOST_TEST_MODULE CFindRequest #include #include "odil/message/CFindRequest.h" #include "odil/DataSet.h" #include "odil/message/Message.h" #include "odil/registry.h" #include "../../MessageFixtureBase.h" struct Fixture: public MessageFixtureBase { odil::DataSet command_set; odil::DataSet query; Fixture() { this->command_set.add( "CommandField", {odil::message::Message::Command::C_FIND_RQ}); this->command_set.add("MessageID", {1234}); this->command_set.add("AffectedSOPClassUID", {odil::registry::PatientRootQueryRetrieveInformationModelFIND}); this->command_set.add( "Priority", {odil::message::Message::Priority::MEDIUM}); this->query.add("PatientName", {"Doe^John"}); this->query.add("StudyDescription", {"Brain"}); this->query.add("QueryRetrieveLevel", {"STUDY"}); } virtual void check(odil::message::CFindRequest const & message) { BOOST_CHECK_EQUAL( message.get_command_field(), odil::message::Message::Command::C_FIND_RQ); BOOST_CHECK_EQUAL(message.get_message_id(), 1234); BOOST_CHECK_EQUAL( message.get_affected_sop_class_uid(), odil::registry::PatientRootQueryRetrieveInformationModelFIND); BOOST_CHECK(message.get_data_set() == this->query); } }; BOOST_FIXTURE_TEST_CASE(Constructor, Fixture) { odil::message::CFindRequest const message( 1234, odil::registry::PatientRootQueryRetrieveInformationModelFIND, odil::message::Message::Priority::MEDIUM, this->query); this->check(message); } BOOST_FIXTURE_TEST_CASE(MessageConstructor, Fixture) { this->check_message_constructor(this->command_set, this->query); } BOOST_FIXTURE_TEST_CASE(MessageConstructorWrongCommandField, Fixture) { this->command_set.as_int("CommandField") = { odil::message::Message::Command::C_ECHO_RQ}; this->check_message_constructor_throw(this->command_set, this->query); } BOOST_FIXTURE_TEST_CASE(MessageConstructorMissingAffectSOPClass, Fixture) { this->command_set.remove("AffectedSOPClassUID"); this->check_message_constructor_throw(this->command_set, this->query); } BOOST_FIXTURE_TEST_CASE(MessageConstructorMissingPriority, Fixture) { this->command_set.remove("Priority"); this->check_message_constructor_throw(this->command_set, this->query); } BOOST_FIXTURE_TEST_CASE(MessageConstructorMissingQuery, Fixture) { this->check_message_constructor_throw(this->command_set); } BOOST_FIXTURE_TEST_CASE(MessageConstructorEmptyQuery, Fixture) { odil::DataSet empty; this->check_message_constructor_throw(this->command_set, empty); } odil-0.4.1/tests/code/message/CFindResponse.cpp000066400000000000000000000066631266460524100213720ustar00rootroot00000000000000#define BOOST_TEST_MODULE CFindResponse #include #include "odil/message/CFindResponse.h" #include "odil/DataSet.h" #include "odil/message/Message.h" #include "odil/registry.h" #include "../../MessageFixtureBase.h" struct Fixture: public MessageFixtureBase { odil::DataSet command_set; odil::DataSet data_set; Fixture() { command_set.add( "CommandField", {odil::message::Message::Command::C_FIND_RSP}); command_set.add("MessageIDBeingRespondedTo", {1234}); command_set.add("Status", {odil::message::Response::Success}); command_set.add("MessageID", {5678}); command_set.add("AffectedSOPClassUID", {odil::registry::StudyRootQueryRetrieveInformationModelFIND}); data_set.add("PatientName", {"Doe^John"}); data_set.add("PatientID", {"DJ123"}); data_set.add("StudyDescription", {"Brain"}); data_set.add("StudyInstanceUID", {"1.2.3"}); } virtual void check(odil::message::CFindResponse const & message) { BOOST_CHECK_EQUAL( message.get_command_field(), odil::message::Message::Command::C_FIND_RSP); BOOST_CHECK_EQUAL(message.get_message_id_being_responded_to(), 1234); BOOST_CHECK_EQUAL( message.get_status(), odil::message::Response::Success); BOOST_CHECK(message.has_message_id()); BOOST_CHECK_EQUAL(message.get_message_id(), 5678); BOOST_CHECK(message.has_affected_sop_class_uid()); BOOST_CHECK_EQUAL( message.get_affected_sop_class_uid(), odil::registry::StudyRootQueryRetrieveInformationModelFIND); BOOST_CHECK(message.has_data_set()); BOOST_CHECK(message.get_data_set() == this->data_set); } }; BOOST_FIXTURE_TEST_CASE(Constructor, Fixture) { odil::message::CFindResponse message( 1234, odil::message::Response::Success, this->data_set); message.set_message_id(5678); message.set_affected_sop_class_uid( odil::registry::StudyRootQueryRetrieveInformationModelFIND); this->check(message); } BOOST_FIXTURE_TEST_CASE(MessageConstructor, Fixture) { this->check_message_constructor(this->command_set, this->data_set); } BOOST_FIXTURE_TEST_CASE(MessageConstructorWrongCommandField, Fixture) { this->command_set.as_int("CommandField") = { odil::message::Message::Command::C_ECHO_RQ}; this->check_message_constructor_throw(this->command_set, this->data_set); } BOOST_AUTO_TEST_CASE(StatusPending) { std::vector const statuses = { odil::message::CFindResponse::PendingWarningOptionalKeysNotSupported, }; for(auto const status:statuses) { odil::message::CFindResponse response(1234, status); BOOST_REQUIRE(response.is_pending()); BOOST_REQUIRE(!response.is_warning()); BOOST_REQUIRE(!response.is_failure()); } } BOOST_AUTO_TEST_CASE(StatusFailure) { std::vector const statuses = { odil::message::CFindResponse::RefusedOutOfResources, odil::message::CFindResponse::IdentifierDoesNotMatchSOPClass, odil::message::CFindResponse::UnableToProcess }; for(auto const status:statuses) { odil::message::CFindResponse response(1234, status); BOOST_REQUIRE(!response.is_pending()); BOOST_REQUIRE(!response.is_warning()); BOOST_REQUIRE(response.is_failure()); } } odil-0.4.1/tests/code/message/CGetRequest.cpp000066400000000000000000000052121266460524100210500ustar00rootroot00000000000000#define BOOST_TEST_MODULE CGetRequest #include #include "odil/message/CGetRequest.h" #include "odil/DataSet.h" #include "odil/DataSet.h" #include "odil/message/Message.h" #include "odil/registry.h" #include "../../MessageFixtureBase.h" struct Fixture: public MessageFixtureBase { odil::DataSet command_set; odil::DataSet query; Fixture() { this->command_set.add( "CommandField", {odil::message::Message::Command::C_GET_RQ}); this->command_set.add("MessageID", {1234}); this->command_set.add("AffectedSOPClassUID", {odil::registry::PatientRootQueryRetrieveInformationModelGET}); this->command_set.add( "Priority", {odil::message::Message::Priority::MEDIUM}); this->query.add("PatientName", {"Doe^John"}); this->query.add("StudyDescription", {"Brain"}); this->query.add("QueryRetrieveLevel", {"STUDY"}); } virtual void check(odil::message::CGetRequest const & message) { BOOST_CHECK_EQUAL( message.get_command_field(), odil::message::Message::Command::C_GET_RQ); BOOST_CHECK_EQUAL(message.get_message_id(), 1234); BOOST_CHECK_EQUAL( message.get_affected_sop_class_uid(), odil::registry::PatientRootQueryRetrieveInformationModelGET); BOOST_CHECK(message.has_data_set()); BOOST_CHECK(message.get_data_set() == this->query); } }; BOOST_FIXTURE_TEST_CASE(Constructor, Fixture) { odil::message::CGetRequest const message( 1234, odil::registry::PatientRootQueryRetrieveInformationModelGET, odil::message::Message::Priority::MEDIUM, this->query); this->check(message); } BOOST_FIXTURE_TEST_CASE(MessageConstructor, Fixture) { this->check_message_constructor(this->command_set, this->query); } BOOST_FIXTURE_TEST_CASE(MessageConstructorWrongCommandField, Fixture) { this->command_set.as_int("CommandField") = { odil::message::Message::Command::C_ECHO_RQ}; this->check_message_constructor_throw(this->command_set, this->query); } BOOST_FIXTURE_TEST_CASE(MessageConstructorMissingAffectSOPClass, Fixture) { this->command_set.remove("AffectedSOPClassUID"); this->check_message_constructor_throw(this->command_set, this->query); } BOOST_FIXTURE_TEST_CASE(MessageConstructorMissingPriority, Fixture) { this->command_set.remove("Priority"); this->check_message_constructor_throw(this->command_set, this->query); } BOOST_FIXTURE_TEST_CASE(MessageConstructorEmptyQuery, Fixture) { odil::DataSet empty; this->check_message_constructor_throw(this->command_set, empty); } odil-0.4.1/tests/code/message/CGetResponse.cpp000066400000000000000000000113421266460524100212170ustar00rootroot00000000000000#define BOOST_TEST_MODULE CGetResponse #include #include "odil/message/CGetResponse.h" #include "odil/DataSet.h" #include "odil/message/Message.h" #include "odil/registry.h" #include "../../MessageFixtureBase.h" struct Fixture: public MessageFixtureBase { odil::DataSet command_set; odil::DataSet data_set; Fixture() { this->command_set.add( "CommandField", {odil::message::Message::Command::C_GET_RSP}); this->command_set.add("MessageIDBeingRespondedTo", {1234}); this->command_set.add("Status", {odil::message::Response::Success}); this->command_set.add("MessageID", {5678}); this->command_set.add("AffectedSOPClassUID", {odil::registry::StudyRootQueryRetrieveInformationModelGET}); this->command_set.add(odil::registry::NumberOfRemainingSuboperations, {1}); this->command_set.add(odil::registry::NumberOfCompletedSuboperations, {2}); this->command_set.add(odil::registry::NumberOfFailedSuboperations, {3}); this->command_set.add(odil::registry::NumberOfWarningSuboperations, {4}); this->data_set.add("PatientName", {"Doe^John"}); this->data_set.add("PatientID", {"DJ123"}); this->data_set.add("StudyDescription", {"Brain"}); this->data_set.add("StudyInstanceUID", {"1.2.3"}); } virtual void check(odil::message::CGetResponse const & message) { BOOST_CHECK_EQUAL( message.get_command_field(), odil::message::Message::Command::C_GET_RSP); BOOST_CHECK_EQUAL(message.get_message_id_being_responded_to(), 1234); BOOST_CHECK_EQUAL( message.get_status(), odil::message::Response::Success); BOOST_CHECK(message.has_message_id()); BOOST_CHECK_EQUAL(message.get_message_id(), 5678); BOOST_CHECK(message.has_affected_sop_class_uid()); BOOST_CHECK_EQUAL( message.get_affected_sop_class_uid(), odil::registry::StudyRootQueryRetrieveInformationModelGET); BOOST_CHECK(message.has_number_of_remaining_sub_operations()); BOOST_CHECK_EQUAL(message.get_number_of_remaining_sub_operations(), 1); BOOST_CHECK(message.has_number_of_completed_sub_operations()); BOOST_CHECK_EQUAL(message.get_number_of_completed_sub_operations(), 2); BOOST_CHECK(message.has_number_of_failed_sub_operations()); BOOST_CHECK_EQUAL(message.get_number_of_failed_sub_operations(), 3); BOOST_CHECK(message.has_number_of_warning_sub_operations()); BOOST_CHECK_EQUAL(message.get_number_of_warning_sub_operations(), 4); BOOST_CHECK(message.has_data_set()); BOOST_CHECK(message.get_data_set() == this->data_set); } }; BOOST_FIXTURE_TEST_CASE(Constructor, Fixture) { odil::message::CGetResponse message( 1234, odil::message::Response::Success, this->data_set); message.set_message_id(5678); message.set_affected_sop_class_uid( odil::registry::StudyRootQueryRetrieveInformationModelGET); message.set_number_of_remaining_sub_operations(1); message.set_number_of_completed_sub_operations(2); message.set_number_of_failed_sub_operations(3); message.set_number_of_warning_sub_operations(4); this->check(message); } BOOST_FIXTURE_TEST_CASE(MessageConstructor, Fixture) { this->check_message_constructor(this->command_set, this->data_set); } BOOST_FIXTURE_TEST_CASE(MessageConstructorWrongCommandField, Fixture) { this->command_set.as_int(odil::registry::CommandField) = { odil::message::Message::Command::C_ECHO_RQ }; this->check_message_constructor_throw(this->command_set, this->data_set); } BOOST_AUTO_TEST_CASE(StatusWarning) { std::vector const statuses = { odil::message::CGetResponse::SubOperationsCompleteOneOrMoreFailuresOrWarnings }; for(auto const status:statuses) { odil::message::CGetResponse response(1234, status); BOOST_REQUIRE(!response.is_pending()); BOOST_REQUIRE(response.is_warning()); BOOST_REQUIRE(!response.is_failure()); } } BOOST_AUTO_TEST_CASE(StatusFailure) { std::vector const statuses = { odil::message::CGetResponse::RefusedOutOfResourcesUnableToCalculateNumberOfMatches, odil::message::CGetResponse::RefusedOutOfResourcesUnableToPerformSubOperations, odil::message::CGetResponse::IdentifierDoesNotMatchSOPClass, odil::message::CGetResponse::UnableToProcess }; for(auto const status:statuses) { odil::message::CGetResponse response(1234, status); BOOST_REQUIRE(!response.is_pending()); BOOST_REQUIRE(!response.is_warning()); BOOST_REQUIRE(response.is_failure()); } } odil-0.4.1/tests/code/message/CMoveRequest.cpp000066400000000000000000000054361266460524100212470ustar00rootroot00000000000000#define BOOST_TEST_MODULE CMoveRequest #include #include "odil/message/CMoveRequest.h" #include "odil/DataSet.h" #include "odil/message/Message.h" #include "odil/registry.h" #include "../../MessageFixtureBase.h" struct Fixture: public MessageFixtureBase { odil::DataSet command_set; odil::DataSet query; Fixture() { this->command_set.add( "CommandField", {odil::message::Message::Command::C_MOVE_RQ}); this->command_set.add("MessageID", {1234}); this->command_set.add("AffectedSOPClassUID", {odil::registry::PatientRootQueryRetrieveInformationModelMOVE}); this->command_set.add( "Priority", {odil::message::Message::Priority::MEDIUM}); this->command_set.add("MoveDestination", {"destination"}); this->query.add("PatientName", {"Doe^John"}); this->query.add("StudyDescription", {"Brain"}); this->query.add("QueryRetrieveLevel", {"STUDY"}); } virtual void check(odil::message::CMoveRequest const & message) { BOOST_CHECK_EQUAL( message.get_command_field(), odil::message::Message::Command::C_MOVE_RQ); BOOST_CHECK_EQUAL(message.get_message_id(), 1234); BOOST_CHECK_EQUAL( message.get_affected_sop_class_uid(), odil::registry::PatientRootQueryRetrieveInformationModelMOVE); BOOST_CHECK_EQUAL(message.get_move_destination(), "destination"); BOOST_CHECK(message.has_data_set()); BOOST_CHECK(message.get_data_set() == this->query); } }; BOOST_FIXTURE_TEST_CASE(Constructor, Fixture) { odil::message::CMoveRequest const message( 1234, odil::registry::PatientRootQueryRetrieveInformationModelMOVE, odil::message::Message::Priority::MEDIUM, "destination", this->query); this->check(message); } BOOST_FIXTURE_TEST_CASE(MessageConstructor, Fixture) { this->check_message_constructor(this->command_set, this->query); } BOOST_FIXTURE_TEST_CASE(MessageConstructorWrongCommandField, Fixture) { this->command_set.as_int("CommandField") = { odil::message::Message::Command::C_ECHO_RQ}; this->check_message_constructor_throw(this->command_set, this->query); } BOOST_FIXTURE_TEST_CASE(MessageConstructorMissingAffectSOPClass, Fixture) { this->command_set.remove("AffectedSOPClassUID"); this->check_message_constructor_throw(this->command_set, this->query); } BOOST_FIXTURE_TEST_CASE(MessageConstructorMissingPriority, Fixture) { this->command_set.remove("Priority"); this->check_message_constructor_throw(this->command_set, this->query); } BOOST_FIXTURE_TEST_CASE(MessageConstructorEmptyQuery, Fixture) { odil::DataSet empty; this->check_message_constructor_throw(this->command_set, empty); } odil-0.4.1/tests/code/message/CMoveResponse.cpp000066400000000000000000000114511266460524100214070ustar00rootroot00000000000000#define BOOST_TEST_MODULE CMoveResponse #include #include "odil/message/CMoveResponse.h" #include "odil/DataSet.h" #include "odil/message/Message.h" #include "odil/registry.h" #include "../../MessageFixtureBase.h" struct Fixture: public MessageFixtureBase { odil::DataSet command_set; odil::DataSet data_set; Fixture() { this->command_set.add( "CommandField", {odil::message::Message::Command::C_MOVE_RSP}); this->command_set.add("MessageIDBeingRespondedTo", {1234}); this->command_set.add("Status", {odil::message::Response::Success}); this->command_set.add("MessageID", {5678}); this->command_set.add("AffectedSOPClassUID", {odil::registry::StudyRootQueryRetrieveInformationModelMOVE}); this->command_set.add(odil::registry::NumberOfRemainingSuboperations, {1}); this->command_set.add(odil::registry::NumberOfCompletedSuboperations, {2}); this->command_set.add(odil::registry::NumberOfFailedSuboperations, {3}); this->command_set.add(odil::registry::NumberOfWarningSuboperations, {4}); this->data_set.add("PatientName", {"Doe^John"}); this->data_set.add("PatientID", {"DJ123"}); this->data_set.add("StudyDescription", {"Brain"}); this->data_set.add("StudyInstanceUID", {"1.2.3"}); } virtual void check(odil::message::CMoveResponse const & message) { BOOST_CHECK_EQUAL( message.get_command_field(), odil::message::Message::Command::C_MOVE_RSP); BOOST_CHECK_EQUAL(message.get_message_id_being_responded_to(), 1234); BOOST_CHECK_EQUAL( message.get_status(), odil::message::Response::Success); BOOST_CHECK(message.has_message_id()); BOOST_CHECK_EQUAL(message.get_message_id(), 5678); BOOST_CHECK(message.has_affected_sop_class_uid()); BOOST_CHECK_EQUAL( message.get_affected_sop_class_uid(), odil::registry::StudyRootQueryRetrieveInformationModelMOVE); BOOST_CHECK(message.has_number_of_remaining_sub_operations()); BOOST_CHECK_EQUAL(message.get_number_of_remaining_sub_operations(), 1); BOOST_CHECK(message.has_number_of_completed_sub_operations()); BOOST_CHECK_EQUAL(message.get_number_of_completed_sub_operations(), 2); BOOST_CHECK(message.has_number_of_failed_sub_operations()); BOOST_CHECK_EQUAL(message.get_number_of_failed_sub_operations(), 3); BOOST_CHECK(message.has_number_of_warning_sub_operations()); BOOST_CHECK_EQUAL(message.get_number_of_warning_sub_operations(), 4); BOOST_CHECK(message.has_data_set()); BOOST_CHECK(message.get_data_set() == this->data_set); } }; BOOST_FIXTURE_TEST_CASE(Constructor, Fixture) { odil::message::CMoveResponse message( 1234, odil::message::Response::Success, this->data_set); message.set_message_id(5678); message.set_affected_sop_class_uid( odil::registry::StudyRootQueryRetrieveInformationModelMOVE); message.set_number_of_remaining_sub_operations(1); message.set_number_of_completed_sub_operations(2); message.set_number_of_failed_sub_operations(3); message.set_number_of_warning_sub_operations(4); this->check(message); } BOOST_FIXTURE_TEST_CASE(MessageConstructor, Fixture) { this->check_message_constructor(this->command_set, this->data_set); } BOOST_FIXTURE_TEST_CASE(MessageConstructorWrongCommandField, Fixture) { this->command_set.as_int("CommandField") = { odil::message::Message::Command::C_ECHO_RQ}; this->check_message_constructor_throw(this->command_set, this->data_set); } BOOST_AUTO_TEST_CASE(StatusWarning) { std::vector const statuses = { odil::message::CMoveResponse::SubOperationsCompleteOneOrMoreFailuresOrWarnings }; for(auto const status:statuses) { odil::message::CMoveResponse response(1234, status); BOOST_REQUIRE(!response.is_pending()); BOOST_REQUIRE(response.is_warning()); BOOST_REQUIRE(!response.is_failure()); } } BOOST_AUTO_TEST_CASE(StatusFailure) { std::vector const statuses = { odil::message::CMoveResponse::RefusedOutOfResourcesUnableToCalculateNumberOfMatches, odil::message::CMoveResponse::RefusedOutOfResourcesUnableToPerformSubOperations, odil::message::CMoveResponse::RefusedMoveDestinationUnknown, odil::message::CMoveResponse::IdentifierDoesNotMatchSOPClass, odil::message::CMoveResponse::UnableToProcess }; for(auto const status:statuses) { odil::message::CMoveResponse response(1234, status); BOOST_REQUIRE(!response.is_pending()); BOOST_REQUIRE(!response.is_warning()); BOOST_REQUIRE(response.is_failure()); } } odil-0.4.1/tests/code/message/CStoreRequest.cpp000066400000000000000000000062351266460524100214330ustar00rootroot00000000000000#define BOOST_TEST_MODULE CStoreRequest #include #include "odil/message/CStoreRequest.h" #include "odil/DataSet.h" #include "odil/message/Message.h" #include "odil/registry.h" #include "../../MessageFixtureBase.h" struct Fixture: public MessageFixtureBase { odil::DataSet command_set; odil::DataSet data_set; Fixture() { this->command_set.add( "CommandField", {odil::message::Message::Command::C_STORE_RQ}); this->command_set.add("MessageID", {1234}); this->command_set.add( "AffectedSOPClassUID", {odil::registry::MRImageStorage}); this->command_set.add("AffectedSOPInstanceUID", {"1.2.3.4"}); this->command_set.add( "Priority", {odil::message::Message::Priority::MEDIUM}); this->command_set.add("MoveOriginatorApplicationEntityTitle", {"origin"}); this->command_set.add("MoveOriginatorMessageID", {5678}); this->data_set.add("PatientName", {"Doe^John"}); this->data_set.add("PatientID", {"DJ123"}); this->data_set.add("StudyDescription", {"Brain"}); this->data_set.add("StudyInstanceUID", {"1.2.3"}); } void check(odil::message::CStoreRequest const & message) { BOOST_CHECK_EQUAL( message.get_command_field(), odil::message::Message::Command::C_STORE_RQ); BOOST_CHECK_EQUAL(message.get_message_id(), 1234); BOOST_CHECK_EQUAL( message.get_affected_sop_class_uid(), odil::registry::MRImageStorage); BOOST_CHECK_EQUAL( message.get_affected_sop_instance_uid(), "1.2.3.4"); BOOST_CHECK(message.has_move_originator_ae_title()); BOOST_CHECK_EQUAL(message.get_move_originator_ae_title(), "origin"); BOOST_CHECK(message.has_move_originator_message_id()); BOOST_CHECK_EQUAL(message.get_move_originator_message_id(), 5678); BOOST_CHECK(message.has_data_set()); BOOST_CHECK(message.get_data_set() == this->data_set); } }; BOOST_FIXTURE_TEST_CASE(Constructor, Fixture) { odil::message::CStoreRequest message( 1234, odil::registry::MRImageStorage, "1.2.3.4", odil::message::Message::Priority::MEDIUM, this->data_set); message.set_move_originator_ae_title("origin"); message.set_move_originator_message_id(5678); this->check(message); } BOOST_FIXTURE_TEST_CASE(MessageConstructor, Fixture) { this->check_message_constructor(this->command_set, this->data_set); } BOOST_FIXTURE_TEST_CASE(MessageConstructorWrongCommandField, Fixture) { this->command_set.as_int("CommandField") = { odil::message::Message::Command::C_ECHO_RSP}; this->check_message_constructor_throw(this->command_set, this->data_set); } BOOST_FIXTURE_TEST_CASE(MessageConstructorMissingAffectSOPClass, Fixture) { this->command_set.remove("AffectedSOPClassUID"); this->check_message_constructor_throw(this->command_set, this->data_set); } BOOST_FIXTURE_TEST_CASE(MessageConstructorMissingAffectSOPInstance, Fixture) { this->command_set.remove("AffectedSOPInstanceUID"); this->check_message_constructor_throw(this->command_set, this->data_set); } odil-0.4.1/tests/code/message/CStoreResponse.cpp000066400000000000000000000066241266460524100216030ustar00rootroot00000000000000#define BOOST_TEST_MODULE CStoreResponse #include #include "odil/message/CStoreResponse.h" #include "odil/DataSet.h" #include "odil/message/Message.h" #include "odil/registry.h" #include "../../MessageFixtureBase.h" struct Fixture: public MessageFixtureBase { odil::DataSet command_set; Fixture() { this->command_set.add( "CommandField", {odil::message::Message::Command::C_STORE_RSP}); this->command_set.add("MessageIDBeingRespondedTo", {1234}); this->command_set.add("Status", {odil::message::Response::Success}); this->command_set.add("MessageID", {5678}); this->command_set.add( "AffectedSOPClassUID", {odil::registry::MRImageStorage}); this->command_set.add("AffectedSOPInstanceUID", {"1.2.3.4"}); } void check(odil::message::CStoreResponse const & message) { BOOST_CHECK_EQUAL( message.get_command_field(), odil::message::Message::Command::C_STORE_RSP); BOOST_CHECK_EQUAL(message.get_message_id_being_responded_to(), 1234); BOOST_CHECK_EQUAL( message.get_status(), odil::message::Response::Success); BOOST_CHECK(!message.has_data_set()); BOOST_CHECK(message.has_message_id()); BOOST_CHECK_EQUAL(message.get_message_id(), 5678); BOOST_CHECK(message.has_affected_sop_class_uid()); BOOST_CHECK_EQUAL( message.get_affected_sop_class_uid(), odil::registry::MRImageStorage); BOOST_CHECK(message.has_affected_sop_instance_uid()); BOOST_CHECK_EQUAL(message.get_affected_sop_instance_uid(), "1.2.3.4"); } }; BOOST_FIXTURE_TEST_CASE(Constructor, Fixture) { odil::message::CStoreResponse message( 1234, odil::message::Response::Success); message.set_message_id(5678); message.set_affected_sop_class_uid(odil::registry::MRImageStorage); message.set_affected_sop_instance_uid("1.2.3.4"); this->check(message); } BOOST_FIXTURE_TEST_CASE(MessageConstructor, Fixture) { this->check_message_constructor(this->command_set); } BOOST_FIXTURE_TEST_CASE(MessageConstructorWrongCommandField, Fixture) { this->command_set.add( "CommandField", {odil::message::Message::Command::C_ECHO_RQ}); this->check_message_constructor_throw(this->command_set); } BOOST_AUTO_TEST_CASE(StatusWarning) { std::vector const statuses = { odil::message::CStoreResponse::CoercionOfDataElements, odil::message::CStoreResponse::DataSetDoesNotMatchSOPClass, odil::message::CStoreResponse::ElementsDiscarded }; for(auto const status:statuses) { odil::message::CStoreResponse response(1234, status); BOOST_REQUIRE(!response.is_pending()); BOOST_REQUIRE(response.is_warning()); BOOST_REQUIRE(!response.is_failure()); } } BOOST_AUTO_TEST_CASE(StatusFailure) { std::vector const statuses = { odil::message::CStoreResponse::RefusedOutOfResources, odil::message::CStoreResponse::ErrorDataSetDoesNotMatchSOPClass, odil::message::CStoreResponse::ErrorCannotUnderstand }; for(auto const status:statuses) { odil::message::CStoreResponse response(1234, status); BOOST_REQUIRE(!response.is_pending()); BOOST_REQUIRE(!response.is_warning()); BOOST_REQUIRE(response.is_failure()); } } odil-0.4.1/tests/code/message/Cancellation.cpp000066400000000000000000000023431266460524100212530ustar00rootroot00000000000000#define BOOST_TEST_MODULE Cancellation #include #include "odil/DataSet.h" #include "odil/message/Cancellation.h" #include "../../MessageFixtureBase.h" struct Fixture: public MessageFixtureBase { odil::DataSet command_set; Fixture() { this->command_set.add( "CommandField", {odil::message::Message::Command::C_CANCEL_RQ}); this->command_set.add("MessageIDBeingRespondedTo", {1234}); } void check(odil::message::Cancellation const & message) { BOOST_CHECK_EQUAL( message.get_command_field(), odil::message::Message::Command::C_CANCEL_RQ); BOOST_CHECK_EQUAL(message.get_message_id_being_responded_to(), 1234); } }; BOOST_FIXTURE_TEST_CASE(Constructor, Fixture) { odil::message::Cancellation const message(1234); this->check(message); } BOOST_FIXTURE_TEST_CASE(MessageConstructor, Fixture) { this->check_message_constructor(this->command_set); } BOOST_FIXTURE_TEST_CASE(MessageConstructorWrongCommandField, Fixture) { this->command_set.as_int("CommandField") = { odil::message::Message::Command::C_ECHO_RQ}; this->check_message_constructor_throw(this->command_set); } odil-0.4.1/tests/code/message/Message.cpp000066400000000000000000000031731266460524100202450ustar00rootroot00000000000000#define BOOST_TEST_MODULE Message #include #include "odil/DataSet.h" #include "odil/message/Message.h" BOOST_AUTO_TEST_CASE(DefaultConstructor) { odil::message::Message const message; // Command Set might not be empty (Command Group Length, Data Set Type) BOOST_CHECK(!message.has_data_set()); } BOOST_AUTO_TEST_CASE(Constructor) { odil::DataSet command_set; command_set.add( "CommandField", {odil::message::Message::Command::C_ECHO_RQ}); odil::DataSet data_set; odil::message::Message const message(command_set, data_set); BOOST_CHECK_EQUAL( message.get_command_set().as_int("CommandField", 0), odil::message::Message::Command::C_ECHO_RQ); BOOST_CHECK(message.has_data_set()); BOOST_CHECK(message.get_data_set().empty()); BOOST_CHECK_EQUAL( message.get_command_field(), odil::message::Message::Command::C_ECHO_RQ); } BOOST_AUTO_TEST_CASE(CommandField) { odil::message::Message message; message.set_command_field(odil::message::Message::Command::C_FIND_RSP); BOOST_CHECK( message.get_command_set().as_int("CommandField") == odil::Value::Integers( {odil::message::Message::Command::C_FIND_RSP})); BOOST_CHECK_EQUAL( message.get_command_field(), odil::message::Message::Command::C_FIND_RSP); } BOOST_AUTO_TEST_CASE(DeleteDataSet) { odil::DataSet command_set; odil::DataSet data_set; odil::message::Message message(command_set, data_set); BOOST_CHECK(message.has_data_set()); message.delete_data_set(); BOOST_CHECK(!message.has_data_set()); } odil-0.4.1/tests/code/message/Request.cpp000066400000000000000000000012101266460524100202770ustar00rootroot00000000000000#define BOOST_TEST_MODULE Request #include #include "odil/DataSet.h" #include "odil/message/Message.h" #include "odil/message/Request.h" BOOST_AUTO_TEST_CASE(Constructor) { odil::message::Request const message(1234); BOOST_CHECK_EQUAL(message.get_message_id(), 1234); } BOOST_AUTO_TEST_CASE(MessageConstructor) { odil::DataSet command_set; command_set.add("MessageID", {1234}); odil::message::Message const generic_message(command_set); odil::message::Request const message(generic_message); BOOST_CHECK_EQUAL(message.get_message_id(), 1234); BOOST_CHECK(!message.has_data_set()); } odil-0.4.1/tests/code/message/Response.cpp000066400000000000000000000075201266460524100204570ustar00rootroot00000000000000#define BOOST_TEST_MODULE Response #include #include #include "odil/DataSet.h" #include "odil/message/Message.h" #include "odil/message/Response.h" #include "odil/Value.h" BOOST_AUTO_TEST_CASE(Constructor) { odil::message::Response const message( 1234, odil::message::Response::Pending); BOOST_CHECK_EQUAL(message.get_message_id_being_responded_to(), 1234); BOOST_CHECK_EQUAL(message.get_status(), odil::message::Response::Pending); } BOOST_AUTO_TEST_CASE(MessageConstructor) { odil::DataSet command_set; command_set.add("MessageIDBeingRespondedTo", {1234}); command_set.add("Status", {odil::message::Response::Pending}); odil::message::Message const generic_message(command_set); odil::message::Response const message(generic_message); BOOST_CHECK_EQUAL(message.get_message_id_being_responded_to(), 1234); BOOST_CHECK_EQUAL( message.get_status(), odil::message::Response::Pending); BOOST_CHECK(!message.has_data_set()); } BOOST_AUTO_TEST_CASE(StatusPending) { std::vector const statuses = { odil::message::Response::Pending, }; for(auto const status:statuses) { BOOST_REQUIRE(odil::message::Response::is_pending(status)); BOOST_REQUIRE(!odil::message::Response::is_warning(status)); BOOST_REQUIRE(!odil::message::Response::is_failure(status)); odil::message::Response response(1234, status); BOOST_REQUIRE(response.is_pending()); BOOST_REQUIRE(!response.is_warning()); BOOST_REQUIRE(!response.is_failure()); } } BOOST_AUTO_TEST_CASE(StatusWarning) { std::vector const statuses = { odil::message::Response::AttributeListError, odil::message::Response::AttributeValueOutOfRange }; for(auto const status:statuses) { BOOST_REQUIRE(!odil::message::Response::is_pending(status)); BOOST_REQUIRE(odil::message::Response::is_warning(status)); BOOST_REQUIRE(!odil::message::Response::is_failure(status)); odil::message::Response response(1234, status); BOOST_REQUIRE(!response.is_pending()); BOOST_REQUIRE(response.is_warning()); BOOST_REQUIRE(!response.is_failure()); } } BOOST_AUTO_TEST_CASE(StatusFailure) { std::vector const statuses = { odil::message::Response::SOPClassNotSupported, odil::message::Response::ClassInstanceConflict, odil::message::Response::DuplicateSOPInstance, odil::message::Response::DuplicateInvocation, odil::message::Response::InvalidArgumentValue, odil::message::Response::InvalidAttributeValue, odil::message::Response::InvalidObjectInstance, odil::message::Response::MissingAttribute, odil::message::Response::MissingAttributeValue, odil::message::Response::MistypedArgument, odil::message::Response::NoSuchArgument, odil::message::Response::NoSuchAttribute, odil::message::Response::NoSuchEventType, odil::message::Response::NoSuchSOPInstance, odil::message::Response::NoSuchSOPClass, odil::message::Response::ProcessingFailure, odil::message::Response::ResourceLimitation, odil::message::Response::UnrecognizedOperation, odil::message::Response::NoSuchActionType, odil::message::Response::RefusedNotAuthorized }; for(auto const status:statuses) { BOOST_REQUIRE(!odil::message::Response::is_pending(status)); BOOST_REQUIRE(!odil::message::Response::is_warning(status)); BOOST_REQUIRE(odil::message::Response::is_failure(status)); odil::message::Response response(1234, status); BOOST_REQUIRE(!response.is_pending()); BOOST_REQUIRE(!response.is_warning()); BOOST_REQUIRE(response.is_failure()); } } odil-0.4.1/tests/code/pdu/000077500000000000000000000000001266460524100153155ustar00rootroot00000000000000odil-0.4.1/tests/code/pdu/AAbort.cpp000066400000000000000000000021111266460524100171640ustar00rootroot00000000000000#define BOOST_TEST_MODULE pdu::AAbort #include #include #include #include "odil/pdu/AAbort.h" #include "odil/Exception.h" std::string const data = { 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x02 }; BOOST_AUTO_TEST_CASE(ConstructorFields) { odil::pdu::AAbort const pdu(1, 2); BOOST_REQUIRE_EQUAL(pdu.get_source(), 1); BOOST_REQUIRE_EQUAL(pdu.get_reason(), 2); } BOOST_AUTO_TEST_CASE(ConstructorStream) { std::istringstream stream(data); odil::pdu::AAbort const pdu(stream); BOOST_REQUIRE_EQUAL(pdu.get_source(), 1); BOOST_REQUIRE_EQUAL(pdu.get_reason(), 2); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::AAbort const pdu(1, 2); std::ostringstream stream; stream << pdu; BOOST_REQUIRE(stream.str() == data); } BOOST_AUTO_TEST_CASE(WrongSource) { odil::pdu::AAbort pdu(1, 2); BOOST_REQUIRE_THROW(pdu.set_source(3), odil::Exception); } BOOST_AUTO_TEST_CASE(WrongReason) { odil::pdu::AAbort pdu(1, 2); BOOST_REQUIRE_THROW(pdu.set_reason(9), odil::Exception); } odil-0.4.1/tests/code/pdu/AAssociateAC.cpp000066400000000000000000000172441266460524100202510ustar00rootroot00000000000000#define BOOST_TEST_MODULE AAssociateAC #include #include #include #include #include #include "odil/pdu/AAssociateAC.h" #include "odil/pdu/ApplicationContext.h" #include "odil/pdu/PresentationContextAC.h" #include "odil/pdu/UserIdentityAC.h" #include "odil/pdu/UserInformation.h" #include "odil/Exception.h" struct Fixture { public: static std::string const read_data; static std::string const write_data; odil::pdu::ApplicationContext application_context; std::vector presentation_contexts; odil::pdu::UserInformation user_information; Fixture() : application_context("foo") { odil::pdu::PresentationContextAC pc1(3, "transfer_syntax", 1); odil::pdu::PresentationContextAC pc2(5, "transfer_syntax_2", 2); this->presentation_contexts = {pc1, pc2}; this->user_information.set_sub_items( { { 0x12345678 } }); this->user_information.set_sub_items( { { "bar" } }); } void check_application_context( odil::pdu::ApplicationContext const & context) const { BOOST_REQUIRE_EQUAL( context.get_name(), this->application_context.get_name()); } void check_presentation_contexts( std::vector const & contexts) { BOOST_REQUIRE_EQUAL(contexts.size(), presentation_contexts.size()); for(int i=0; i().empty()); BOOST_REQUIRE_EQUAL( user_information.get_sub_items()[0].get_maximum_length(), 0x12345678); BOOST_REQUIRE( !user_information.get_sub_items().empty()); BOOST_REQUIRE_EQUAL( user_information.get_sub_items()[0].get_server_response(), "bar"); } }; std::string const Fixture ::read_data( // Header, 6 bytes "\x02\x00" "\x00\x00\x00\x98" // Items: 68 bytes "\x00\x01\x00\x00" " CALLED_AE" "CALLING_AE " "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" // Application Context, 7 bytes "\x10\x00\x00\x03" "foo" // Presentation Contexts, 27+29 bytes "\x21\x00\x00\x17" "\x03\x00\x01\x00" "\x40\x00\x00\x0f""transfer_syntax" "\x21\x00\x00\x19" "\x05\x00\x02\x00" "\x40\x00\x00\x11""transfer_syntax_2" // User Information, 21 bytes "\x50\x00\x00\x11" "\x51\x00\x00\x04" "\x12\x34\x56\x78" "\x59\x00\x00\x05" "\x00\x03" "bar" , 158 ); std::string const Fixture ::write_data( // Header, 6 bytes "\x02\x00" "\x00\x00\x00\x98" // Items: 68 bytes "\x00\x01\x00\x00" "CALLED_AE " "CALLING_AE " "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" // Application Context, 7 bytes "\x10\x00\x00\x03" "foo" // Presentation Contexts, 27+29 bytes "\x21\x00\x00\x17" "\x03\x00\x01\x00" "\x40\x00\x00\x0f""transfer_syntax" "\x21\x00\x00\x19" "\x05\x00\x02\x00" "\x40\x00\x00\x11""transfer_syntax_2" // User Information, 21 bytes "\x50\x00\x00\x11" "\x51\x00\x00\x04" "\x12\x34\x56\x78" "\x59\x00\x00\x05" "\x00\x03" "bar" , 158 ); BOOST_AUTO_TEST_CASE(Constructor) { odil::pdu::AAssociateAC const pdu; BOOST_REQUIRE_EQUAL(pdu.get_called_ae_title(), ""); BOOST_REQUIRE_EQUAL(pdu.get_calling_ae_title(), ""); BOOST_REQUIRE_EQUAL(pdu.get_protocol_version(), 0); BOOST_REQUIRE_THROW(pdu.get_application_context(), odil::Exception); BOOST_REQUIRE(pdu.get_presentation_contexts().empty()); BOOST_REQUIRE_THROW(pdu.get_user_information(), odil::Exception); } BOOST_FIXTURE_TEST_CASE(ConstructorStream, Fixture) { std::istringstream stream(read_data); odil::pdu::AAssociateAC const pdu(stream); BOOST_REQUIRE_EQUAL(pdu.get_called_ae_title(), "CALLED_AE"); BOOST_REQUIRE_EQUAL(pdu.get_calling_ae_title(), "CALLING_AE"); BOOST_REQUIRE_EQUAL(pdu.get_protocol_version(), 1); this->check_application_context(pdu.get_application_context()); this->check_presentation_contexts(pdu.get_presentation_contexts()); this->check_user_information(pdu.get_user_information()); } BOOST_AUTO_TEST_CASE(ProtocolVersion) { odil::pdu::AAssociateAC pdu; BOOST_REQUIRE_EQUAL(pdu.get_protocol_version(), 0); pdu.set_protocol_version(2); BOOST_REQUIRE_EQUAL(pdu.get_protocol_version(), 2); } BOOST_AUTO_TEST_CASE(CalledAETitle) { odil::pdu::AAssociateAC pdu; BOOST_REQUIRE_EQUAL(pdu.get_called_ae_title(), ""); pdu.set_called_ae_title("called"); BOOST_REQUIRE_EQUAL(pdu.get_called_ae_title(), "called"); } BOOST_AUTO_TEST_CASE(CallingAETitle) { odil::pdu::AAssociateAC pdu; BOOST_REQUIRE_EQUAL(pdu.get_calling_ae_title(), ""); pdu.set_calling_ae_title("calling"); BOOST_REQUIRE_EQUAL(pdu.get_calling_ae_title(), "calling"); } BOOST_FIXTURE_TEST_CASE(ApplicationContext, Fixture) { odil::pdu::AAssociateAC pdu; BOOST_REQUIRE_THROW(pdu.get_application_context(), odil::Exception); pdu.set_application_context(application_context); this->check_application_context(pdu.get_application_context()); } BOOST_FIXTURE_TEST_CASE(PresentationContexts, Fixture) { odil::pdu::AAssociateAC pdu; BOOST_REQUIRE(pdu.get_presentation_contexts().empty()); pdu.set_presentation_contexts(presentation_contexts); this->check_presentation_contexts(pdu.get_presentation_contexts()); } BOOST_FIXTURE_TEST_CASE(UserInformation, Fixture) { odil::pdu::AAssociateAC pdu; BOOST_REQUIRE_THROW(pdu.get_user_information(), odil::Exception); pdu.set_user_information(user_information); this->check_user_information(pdu.get_user_information()); } BOOST_FIXTURE_TEST_CASE(Write, Fixture) { odil::pdu::AAssociateAC pdu; pdu.set_protocol_version(1); pdu.set_called_ae_title("CALLED_AE"); pdu.set_calling_ae_title("CALLING_AE"); pdu.set_application_context(application_context); pdu.set_presentation_contexts(presentation_contexts); pdu.set_user_information(user_information); std::ostringstream stream; stream << pdu; BOOST_REQUIRE(stream.str() == write_data); } BOOST_AUTO_TEST_CASE(CalledAETitleEmpty) { odil::pdu::AAssociateAC pdu; BOOST_REQUIRE_THROW(pdu.set_called_ae_title(""), odil::Exception); } BOOST_AUTO_TEST_CASE(CalledAETitleTooLong) { odil::pdu::AAssociateAC pdu; BOOST_REQUIRE_THROW( pdu.set_called_ae_title("123456789abcdef01"), odil::Exception); } BOOST_AUTO_TEST_CASE(CallingAETitleEmpty) { odil::pdu::AAssociateAC pdu; BOOST_REQUIRE_THROW(pdu.set_calling_ae_title(""), odil::Exception); } BOOST_AUTO_TEST_CASE(CallingAETitleTooLong) { odil::pdu::AAssociateAC pdu; BOOST_REQUIRE_THROW( pdu.set_calling_ae_title("123456789abcdef01"), odil::Exception); } odil-0.4.1/tests/code/pdu/AAssociateRJ.cpp000066400000000000000000000025301266460524100202710ustar00rootroot00000000000000#define BOOST_TEST_MODULE pdu::AssociateRJ #include #include #include "odil/pdu/AAssociateRJ.h" #include "odil/Exception.h" std::string const data = { 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03 }; BOOST_AUTO_TEST_CASE(ConstructorFields) { odil::pdu::AAssociateRJ const pdu(1, 2, 3); BOOST_REQUIRE_EQUAL(pdu.get_result(), 1); BOOST_REQUIRE_EQUAL(pdu.get_source(), 2); BOOST_REQUIRE_EQUAL(pdu.get_reason(), 3); } BOOST_AUTO_TEST_CASE(ConstructorStream) { std::istringstream stream(data); odil::pdu::AAssociateRJ const pdu(stream); BOOST_REQUIRE_EQUAL(pdu.get_result(), 1); BOOST_REQUIRE_EQUAL(pdu.get_source(), 2); BOOST_REQUIRE_EQUAL(pdu.get_reason(), 3); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::AAssociateRJ const pdu(1, 2, 3); std::ostringstream stream; stream << pdu; BOOST_REQUIRE(stream.str() == data); } BOOST_AUTO_TEST_CASE(WrongResult) { odil::pdu::AAssociateRJ pdu(1, 2, 3); BOOST_REQUIRE_THROW(pdu.set_result(4), odil::Exception); } BOOST_AUTO_TEST_CASE(WrongSource) { odil::pdu::AAssociateRJ pdu(1, 2, 3); BOOST_REQUIRE_THROW(pdu.set_source(4), odil::Exception); } BOOST_AUTO_TEST_CASE(WrongReason) { odil::pdu::AAssociateRJ pdu(1, 2, 3); BOOST_REQUIRE_THROW(pdu.set_reason(25), odil::Exception); } odil-0.4.1/tests/code/pdu/AAssociateRQ.cpp000066400000000000000000000203131266460524100202770ustar00rootroot00000000000000#define BOOST_TEST_MODULE AAssociateRQ #include #include #include #include #include #include "odil/pdu/AAssociateRQ.h" #include "odil/pdu/ApplicationContext.h" #include "odil/pdu/PresentationContextRQ.h" #include "odil/pdu/UserIdentityRQ.h" #include "odil/pdu/UserInformation.h" #include "odil/Exception.h" struct Fixture { public: static std::string const read_data; static std::string const write_data; odil::pdu::ApplicationContext application_context; std::vector presentation_contexts; odil::pdu::UserInformation user_information; Fixture() : application_context("foo") { odil::pdu::PresentationContextRQ pc1(3, "abstract_syntax", {"ts1", "ts2"}); this->presentation_contexts = {pc1}; this->user_information.set_sub_items( { { 0x12345678 } }); odil::pdu::UserIdentityRQ user_identity; user_identity.set_username_and_passcode("foo", "bar"); user_identity.set_positive_response_requested(true); this->user_information.set_sub_items( { user_identity }); } void check_application_context( odil::pdu::ApplicationContext const & context) const { BOOST_REQUIRE_EQUAL( context.get_name(), this->application_context.get_name()); } void check_presentation_contexts( std::vector const & contexts) { BOOST_REQUIRE_EQUAL(contexts.size(), presentation_contexts.size()); for(int i=0; i().empty()); BOOST_REQUIRE_EQUAL( user_information.get_sub_items()[0].get_maximum_length(), 0x12345678); BOOST_REQUIRE( !user_information.get_sub_items().empty()); BOOST_REQUIRE_EQUAL( user_information.get_sub_items()[0].get_type(), 2); BOOST_REQUIRE_EQUAL( user_information.get_sub_items()[0].get_positive_response_requested(), true); BOOST_REQUIRE_EQUAL( user_information.get_sub_items()[0].get_primary_field(), "foo"); BOOST_REQUIRE_EQUAL( user_information.get_sub_items()[0].get_secondary_field(), "bar"); } }; std::string const Fixture ::read_data( // Header, 6 bytes "\x01\x00" "\x00\x00\x00\x90" // Items: 68 bytes "\x00\x01\x00\x00" " CALLED_AE" "CALLING_AE " "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" // Application Context, 7 bytes "\x10\x00\x00\x03" "foo" // Presentation Contexts, 41 bytes "\x20\x00\x00\x25" "\x03\x00\x00\x00" "\x30\x00\x00\x0f""abstract_syntax" "\x40\x00\x00\x03""ts1" "\x40\x00\x00\x03""ts2" // User Information, 28 bytes "\x50\x00\x00\x18" "\x51\x00\x00\x04" "\x12\x34\x56\x78" "\x58\x00\x00\x0c" "\x02\x01" "\x00\x03" "foo" "\x00\x03" "bar" , 150 ); std::string const Fixture ::write_data( // Header, 6 bytes "\x01\x00" "\x00\x00\x00\x90" // Items: 68 bytes "\x00\x01\x00\x00" "CALLED_AE " "CALLING_AE " "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" // Application Context, 7 bytes "\x10\x00\x00\x03" "foo" // Presentation Contexts, 41 bytes "\x20\x00\x00\x25" "\x03\x00\x00\x00" "\x30\x00\x00\x0f""abstract_syntax" "\x40\x00\x00\x03""ts1" "\x40\x00\x00\x03""ts2" // User Information, 28 bytes "\x50\x00\x00\x18" "\x51\x00\x00\x04" "\x12\x34\x56\x78" "\x58\x00\x00\x0c" "\x02\x01" "\x00\x03" "foo" "\x00\x03" "bar" , 150 ); BOOST_AUTO_TEST_CASE(Constructor) { odil::pdu::AAssociateRQ const pdu; BOOST_REQUIRE_EQUAL(pdu.get_called_ae_title(), ""); BOOST_REQUIRE_EQUAL(pdu.get_calling_ae_title(), ""); BOOST_REQUIRE_EQUAL(pdu.get_protocol_version(), 0); BOOST_REQUIRE_THROW(pdu.get_application_context(), odil::Exception); BOOST_REQUIRE(pdu.get_presentation_contexts().empty()); BOOST_REQUIRE_THROW(pdu.get_user_information(), odil::Exception); } BOOST_FIXTURE_TEST_CASE(ConstructorStream, Fixture) { std::istringstream stream(read_data); odil::pdu::AAssociateRQ const pdu(stream); BOOST_REQUIRE_EQUAL(pdu.get_called_ae_title(), "CALLED_AE"); BOOST_REQUIRE_EQUAL(pdu.get_calling_ae_title(), "CALLING_AE"); BOOST_REQUIRE_EQUAL(pdu.get_protocol_version(), 1); this->check_application_context(pdu.get_application_context()); this->check_presentation_contexts(pdu.get_presentation_contexts()); this->check_user_information(pdu.get_user_information()); } BOOST_AUTO_TEST_CASE(ProtocolVersion) { odil::pdu::AAssociateRQ pdu; BOOST_REQUIRE_EQUAL(pdu.get_protocol_version(), 0); pdu.set_protocol_version(2); BOOST_REQUIRE_EQUAL(pdu.get_protocol_version(), 2); } BOOST_AUTO_TEST_CASE(CalledAETitle) { odil::pdu::AAssociateRQ pdu; BOOST_REQUIRE_EQUAL(pdu.get_called_ae_title(), ""); pdu.set_called_ae_title("called"); BOOST_REQUIRE_EQUAL(pdu.get_called_ae_title(), "called"); } BOOST_AUTO_TEST_CASE(CallingAETitle) { odil::pdu::AAssociateRQ pdu; BOOST_REQUIRE_EQUAL(pdu.get_calling_ae_title(), ""); pdu.set_calling_ae_title("calling"); BOOST_REQUIRE_EQUAL(pdu.get_calling_ae_title(), "calling"); } BOOST_FIXTURE_TEST_CASE(ApplicationContext, Fixture) { odil::pdu::AAssociateRQ pdu; BOOST_REQUIRE_THROW(pdu.get_application_context(), odil::Exception); pdu.set_application_context(application_context); this->check_application_context(pdu.get_application_context()); } BOOST_FIXTURE_TEST_CASE(PresentationContexts, Fixture) { odil::pdu::AAssociateRQ pdu; BOOST_REQUIRE(pdu.get_presentation_contexts().empty()); pdu.set_presentation_contexts(presentation_contexts); this->check_presentation_contexts(pdu.get_presentation_contexts()); } BOOST_FIXTURE_TEST_CASE(UserInformation, Fixture) { odil::pdu::AAssociateRQ pdu; BOOST_REQUIRE_THROW(pdu.get_user_information(), odil::Exception); pdu.set_user_information(user_information); this->check_user_information(pdu.get_user_information()); } BOOST_FIXTURE_TEST_CASE(Write, Fixture) { odil::pdu::AAssociateRQ pdu; pdu.set_protocol_version(1); pdu.set_called_ae_title("CALLED_AE"); pdu.set_calling_ae_title("CALLING_AE"); pdu.set_application_context(application_context); pdu.set_presentation_contexts(presentation_contexts); pdu.set_user_information(user_information); std::ostringstream stream; stream << pdu; BOOST_REQUIRE(stream.str() == write_data); } BOOST_AUTO_TEST_CASE(CalledAETitleEmpty) { odil::pdu::AAssociateRQ pdu; BOOST_REQUIRE_THROW(pdu.set_called_ae_title(""), odil::Exception); } BOOST_AUTO_TEST_CASE(CalledAETitleTooLong) { odil::pdu::AAssociateRQ pdu; BOOST_REQUIRE_THROW( pdu.set_called_ae_title("123456789abcdef01"), odil::Exception); } BOOST_AUTO_TEST_CASE(CallingAETitleEmpty) { odil::pdu::AAssociateRQ pdu; BOOST_REQUIRE_THROW(pdu.set_calling_ae_title(""), odil::Exception); } BOOST_AUTO_TEST_CASE(CallingAETitleTooLong) { odil::pdu::AAssociateRQ pdu; BOOST_REQUIRE_THROW( pdu.set_calling_ae_title("123456789abcdef01"), odil::Exception); } odil-0.4.1/tests/code/pdu/AReleaseRP.cpp000066400000000000000000000011611266460524100177430ustar00rootroot00000000000000#define BOOST_TEST_MODULE AReleaseRPPDU #include #include #include #include "odil/pdu/AReleaseRP.h" std::string const data = { 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 }; BOOST_AUTO_TEST_CASE(ConstructorFields) { odil::pdu::AReleaseRP const pdu; } BOOST_AUTO_TEST_CASE(ConstructorStream) { std::istringstream stream(data); odil::pdu::AReleaseRP const pdu(stream); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::AReleaseRP const pdu; std::ostringstream stream; stream << pdu; BOOST_REQUIRE(stream.str() == data); } odil-0.4.1/tests/code/pdu/AReleaseRQ.cpp000066400000000000000000000011611266460524100177440ustar00rootroot00000000000000#define BOOST_TEST_MODULE AReleaseRPPDU #include #include #include #include "odil/pdu/AReleaseRQ.h" std::string const data = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 }; BOOST_AUTO_TEST_CASE(ConstructorFields) { odil::pdu::AReleaseRQ const pdu; } BOOST_AUTO_TEST_CASE(ConstructorStream) { std::istringstream stream(data); odil::pdu::AReleaseRQ const pdu(stream); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::AReleaseRQ const pdu; std::ostringstream stream; stream << pdu; BOOST_REQUIRE(stream.str() == data); } odil-0.4.1/tests/code/pdu/ApplicationContext.cpp000066400000000000000000000016601266460524100216340ustar00rootroot00000000000000#define BOOST_TEST_MODULE ApplicationContext #include #include #include #include "odil/Exception.h" #include "odil/pdu/ApplicationContext.h" std::string const data( "\x10\x00\x00\x03" "foo", 7 ); BOOST_AUTO_TEST_CASE(FromString) { odil::pdu::ApplicationContext const context("foo"); BOOST_REQUIRE_EQUAL(context.get_name(), "foo"); } BOOST_AUTO_TEST_CASE(FromStream) { std::istringstream stream(data); odil::pdu::ApplicationContext const context(stream); BOOST_REQUIRE_EQUAL(context.get_name(), "foo"); } BOOST_AUTO_TEST_CASE(Name) { odil::pdu::ApplicationContext context("foo"); context.set_name("other"); BOOST_REQUIRE_EQUAL(context.get_name(), "other"); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::ApplicationContext const context("foo"); std::ostringstream stream; stream << context; BOOST_REQUIRE_EQUAL(stream.str(), data); } odil-0.4.1/tests/code/pdu/ImplementationClassUID.cpp000066400000000000000000000017601266460524100223420ustar00rootroot00000000000000#define BOOST_TEST_MODULE ImplementationClassUID #include #include #include #include "odil/pdu/ImplementationClassUID.h" std::string const data( "\x52\x00\x00\x03" "foo", 7 ); BOOST_AUTO_TEST_CASE(Constructor) { odil::pdu::ImplementationClassUID const item("foo"); BOOST_REQUIRE_EQUAL(item.get_implementation_class_uid(), "foo"); } BOOST_AUTO_TEST_CASE(FromStream) { std::istringstream stream(data); odil::pdu::ImplementationClassUID const item(stream); BOOST_REQUIRE_EQUAL(item.get_implementation_class_uid(), "foo"); } BOOST_AUTO_TEST_CASE(ImplementationClassUID) { odil::pdu::ImplementationClassUID item("foo"); item.set_implementation_class_uid("bar"); BOOST_REQUIRE_EQUAL(item.get_implementation_class_uid(), "bar"); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::ImplementationClassUID const item("foo"); std::ostringstream stream; stream << item; BOOST_REQUIRE_EQUAL(stream.str(), data); } odil-0.4.1/tests/code/pdu/ImplementationVersionName.cpp000066400000000000000000000026431266460524100231620ustar00rootroot00000000000000#define BOOST_TEST_MODULE ImplementationVersionName #include #include #include #include "odil/Exception.h" #include "odil/pdu/ImplementationVersionName.h" std::string const data( "\x55\x00\x00\x03" "foo", 7 ); BOOST_AUTO_TEST_CASE(Constructor) { odil::pdu::ImplementationVersionName const item("foo"); BOOST_REQUIRE_EQUAL(item.get_implementation_version_name(), "foo"); } BOOST_AUTO_TEST_CASE(FromStream) { std::istringstream stream(data); odil::pdu::ImplementationVersionName const item(stream); BOOST_REQUIRE_EQUAL(item.get_implementation_version_name(), "foo"); } BOOST_AUTO_TEST_CASE(VersionName) { odil::pdu::ImplementationVersionName item("foo"); item.set_implementation_version_name("bar"); BOOST_REQUIRE_EQUAL(item.get_implementation_version_name(), "bar"); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::ImplementationVersionName const item("foo"); std::ostringstream stream; stream << item; BOOST_REQUIRE_EQUAL(stream.str(), data); } BOOST_AUTO_TEST_CASE(Empty) { odil::pdu::ImplementationVersionName item("foo"); BOOST_REQUIRE_THROW( item.set_implementation_version_name(""), odil::Exception); } BOOST_AUTO_TEST_CASE(TooLong) { odil::pdu::ImplementationVersionName item("foo"); BOOST_REQUIRE_THROW( item.set_implementation_version_name("1234567890abcdef01"), odil::Exception); } odil-0.4.1/tests/code/pdu/Item.cpp000066400000000000000000000071751266460524100167310ustar00rootroot00000000000000#define BOOST_TEST_MODULE pdu::Item #include #include #include "odil/pdu/Item.h" #include "odil/Exception.h" BOOST_AUTO_TEST_CASE(FieldUInt8) { odil::pdu::Item::Field const field(uint8_t(123)); BOOST_REQUIRE( field.get_type() == odil::pdu::Item::Field::Type::unsigned_int_8); BOOST_REQUIRE_EQUAL(field.as_unsigned_int_8(), 123); } BOOST_AUTO_TEST_CASE(FieldUInt16) { odil::pdu::Item::Field const field(uint16_t(1234)); BOOST_REQUIRE( field.get_type() == odil::pdu::Item::Field::Type::unsigned_int_16); BOOST_REQUIRE_EQUAL(field.as_unsigned_int_16(), 1234); } BOOST_AUTO_TEST_CASE(FieldUInt32) { odil::pdu::Item::Field const field(uint32_t(123456)); BOOST_REQUIRE( field.get_type() == odil::pdu::Item::Field::Type::unsigned_int_32); BOOST_REQUIRE_EQUAL(field.as_unsigned_int_32(), 123456); } BOOST_AUTO_TEST_CASE(FieldString) { odil::pdu::Item::Field const field("abcdef"); BOOST_REQUIRE(field.get_type() == odil::pdu::Item::Field::Type::string); BOOST_REQUIRE_EQUAL(field.as_string(), "abcdef"); } BOOST_AUTO_TEST_CASE(FieldItems) { odil::pdu::Item const item_1({{"foo", uint8_t(123)}}); odil::pdu::Item const item_2({{"bar", std::string("abcdef")}}); odil::pdu::Item::Field const field( std::vector({item_1, item_2})); BOOST_REQUIRE(field.get_type() == odil::pdu::Item::Field::Type::items); BOOST_REQUIRE_EQUAL(field.as_items().size(), 2); } BOOST_AUTO_TEST_CASE(DefaultConstructor) { odil::pdu::Item const item; BOOST_REQUIRE(item.empty()); BOOST_REQUIRE_EQUAL(item.size(), 0); } BOOST_AUTO_TEST_CASE(FieldsConstructor) { odil::pdu::Item const item({ {std::string("foo"), uint8_t(123)}, {std::string("bar"), std::string("abcd")} }); BOOST_REQUIRE_EQUAL(item.size(), 2); BOOST_REQUIRE_EQUAL(item.as_unsigned_int_8("foo"), 123); BOOST_REQUIRE_EQUAL(item.as_string("bar"), "abcd"); } BOOST_AUTO_TEST_CASE(UInt8) { odil::pdu::Item item; item.add("foo", uint8_t(123)); BOOST_REQUIRE_EQUAL(item.size(), 1); BOOST_REQUIRE_EQUAL(item.has_field("foo"), true); BOOST_REQUIRE_EQUAL(item.as_unsigned_int_8("foo"), 123); BOOST_REQUIRE_THROW(item.as_unsigned_int_16("foo"), odil::Exception); } BOOST_AUTO_TEST_CASE(UInt16) { odil::pdu::Item item; item.add("foo", uint16_t(1234)); BOOST_REQUIRE_EQUAL(item.size(), 1); BOOST_REQUIRE_EQUAL(item.as_unsigned_int_16("foo"), 1234); BOOST_REQUIRE_THROW(item.as_unsigned_int_32("foo"), odil::Exception); } BOOST_AUTO_TEST_CASE(UInt32) { odil::pdu::Item item; item.add("foo", uint32_t(123456)); BOOST_REQUIRE_EQUAL(item.size(), 1); BOOST_REQUIRE_EQUAL(item.as_unsigned_int_32("foo"), 123456); BOOST_REQUIRE_THROW(item.as_string("foo"), odil::Exception); } BOOST_AUTO_TEST_CASE(String) { odil::pdu::Item item; item.add("foo", std::string("abcd")); BOOST_REQUIRE_EQUAL(item.size(), 1); BOOST_REQUIRE_EQUAL(item.as_string("foo"), "abcd"); BOOST_REQUIRE_THROW(item.as_items("foo"), odil::Exception); } BOOST_AUTO_TEST_CASE(Items) { odil::pdu::Item const sub_item( {{"bar", std::string("abcdef")}}); odil::pdu::Item item; item.add("foo", std::vector({sub_item})); BOOST_REQUIRE_EQUAL(item.size(), 1); BOOST_REQUIRE_EQUAL(item.as_items("foo").size(), 1); BOOST_REQUIRE_THROW(item.as_unsigned_int_8("foo"), odil::Exception); } BOOST_AUTO_TEST_CASE(FieldAccessor) { odil::pdu::Item item; item.add("foo", std::string("abcd")); BOOST_REQUIRE_NO_THROW(item["foo"]); BOOST_REQUIRE_THROW(item["bar"], odil::Exception); } odil-0.4.1/tests/code/pdu/MaximumLength.cpp000066400000000000000000000024471266460524100206070ustar00rootroot00000000000000#define BOOST_TEST_MODULE MaximumLength #include #include #include #include "odil/Exception.h" #include "odil/pdu/MaximumLength.h" BOOST_AUTO_TEST_CASE(ConstructorDefault) { odil::pdu::MaximumLength const maximum_length; BOOST_REQUIRE_EQUAL(maximum_length.get_maximum_length(), 0); } BOOST_AUTO_TEST_CASE(ConstructorInt) { odil::pdu::MaximumLength const maximum_length(123); BOOST_REQUIRE_EQUAL(maximum_length.get_maximum_length(), 123); } BOOST_AUTO_TEST_CASE(FromStream) { std::string const data( "\x51\x00\x00\x04" "\x12\x34\x56\x78", 8 ); std::istringstream stream(data); odil::pdu::MaximumLength const maximum_length(stream); BOOST_REQUIRE_EQUAL(maximum_length.get_maximum_length(), 0x12345678); } BOOST_AUTO_TEST_CASE(MaximumLength) { odil::pdu::MaximumLength maximum_length; maximum_length.set_maximum_length(123); BOOST_REQUIRE_EQUAL(maximum_length.get_maximum_length(), 123); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::MaximumLength const maximum_length(0x12345678); std::ostringstream data; data << maximum_length; std::string const expected( "\x51\x00\x00\x04" "\x12\x34\x56\x78", 8 ); BOOST_REQUIRE_EQUAL(data.str(), expected); } odil-0.4.1/tests/code/pdu/PDataTF.cpp000066400000000000000000000033421266460524100172460ustar00rootroot00000000000000#define BOOST_TEST_MODULE pdu::PDataTF #include #include #include #include #include "odil/Exception.h" #include "odil/pdu/PDataTF.h" std::string const data = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x02, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 }; std::vector const pdv_items = { { 1, 0x01, "\x01\x02\x03\x04\x05\x06\x07\x08" }, { 3, 0x02, "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12" }, }; namespace odil { namespace pdu { bool operator==( PDataTF::PresentationDataValueItem const & lhs, PDataTF::PresentationDataValueItem const & rhs) { return ( lhs.get_presentation_context_id() == rhs.get_presentation_context_id() && lhs.get_control_header() == rhs.get_control_header() && lhs.get_fragment() == rhs.get_fragment()); } } } BOOST_AUTO_TEST_CASE(ConstructorPDV) { odil::pdu::PDataTF const pdu(pdv_items); BOOST_REQUIRE(pdu.get_pdv_items() == pdv_items); } BOOST_AUTO_TEST_CASE(ConstructorStream) { std::istringstream stream(data); odil::pdu::PDataTF const pdu(stream); BOOST_REQUIRE(pdu.get_pdv_items() == pdv_items); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::PDataTF const pdu(pdv_items); std::ostringstream stream; stream << pdu; BOOST_REQUIRE(stream.str() == data); } BOOST_AUTO_TEST_CASE(WrongPresentationContextID) { BOOST_REQUIRE_THROW( odil::pdu::PDataTF::PresentationDataValueItem( 2, pdv_items[0].get_control_header(), pdv_items[0].get_fragment()), odil::Exception); } odil-0.4.1/tests/code/pdu/PresentationContextAC.cpp000066400000000000000000000031621266460524100222470ustar00rootroot00000000000000#define BOOST_TEST_MODULE PresentationContextAC #include #include #include #include #include "odil/Exception.h" #include "odil/pdu/PresentationContextAC.h" std::string const data( "\x21\x00\x00\x17" "\x03\x00\x01\x00" "\x40\x00\x00\x0f""transfer_syntax", 27 ); BOOST_AUTO_TEST_CASE(Constructor) { odil::pdu::PresentationContextAC const context(1, "transfer_syntax", 2); BOOST_REQUIRE_EQUAL(context.get_item_type(), 0x21); BOOST_REQUIRE_EQUAL(context.get_id(), 0x1); BOOST_REQUIRE_EQUAL(context.get_result_reason(), 0x2); BOOST_REQUIRE_EQUAL(context.get_transfer_syntax(), "transfer_syntax"); } BOOST_AUTO_TEST_CASE(Id) { odil::pdu::PresentationContextAC context(1, "transfer_syntax", 1); context.set_id(123); BOOST_REQUIRE_EQUAL(context.get_id(), 123); } BOOST_AUTO_TEST_CASE(TransferSyntax) { odil::pdu::PresentationContextAC context(1, "transfer_syntax", 1); context.set_transfer_syntax("foo"); BOOST_REQUIRE_EQUAL(context.get_transfer_syntax(), "foo"); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::PresentationContextAC context(3, "transfer_syntax", 1); std::ostringstream stream; stream << context; BOOST_REQUIRE_EQUAL(stream.str(), data); } BOOST_AUTO_TEST_CASE(Read) { std::istringstream stream(data); odil::pdu::PresentationContextAC const context(stream); BOOST_REQUIRE_EQUAL(context.get_item_type(), 0x21); BOOST_REQUIRE_EQUAL(context.get_id(), 3); BOOST_REQUIRE_EQUAL(context.get_result_reason(), 1); BOOST_REQUIRE_EQUAL(context.get_transfer_syntax(), "transfer_syntax"); } odil-0.4.1/tests/code/pdu/PresentationContextRQ.cpp000066400000000000000000000042471266460524100223130ustar00rootroot00000000000000#define BOOST_TEST_MODULE PresentationContextRQ #include #include #include #include #include "odil/Exception.h" #include "odil/pdu/PresentationContextRQ.h" std::string const data( "\x20\x00\x00\x25" "\x03\x00\x00\x00" "\x30\x00\x00\x0f""abstract_syntax" "\x40\x00\x00\x03""ts1" "\x40\x00\x00\x03""ts2", 41 ); BOOST_AUTO_TEST_CASE(Constructor) { odil::pdu::PresentationContextRQ const context( 1, "abstract_syntax", {"ts1", "ts2"}); BOOST_REQUIRE_EQUAL(context.get_item_type(), 0x20); BOOST_REQUIRE_EQUAL(context.get_id(), 1); BOOST_REQUIRE_EQUAL(context.get_abstract_syntax(), "abstract_syntax"); BOOST_REQUIRE( context.get_transfer_syntaxes() == std::vector({"ts1", "ts2"})); } BOOST_AUTO_TEST_CASE(Id) { odil::pdu::PresentationContextRQ context( 1, "abstract_syntax", {"ts1", "ts2"}); context.set_id(123); BOOST_REQUIRE_EQUAL(context.get_id(), 123); } BOOST_AUTO_TEST_CASE(AbstractSyntax) { odil::pdu::PresentationContextRQ context( 1, "abstract_syntax", {"ts1", "ts2"}); context.set_abstract_syntax("foo"); BOOST_REQUIRE_EQUAL(context.get_abstract_syntax(), "foo"); } BOOST_AUTO_TEST_CASE(TransferSyntaxes) { odil::pdu::PresentationContextRQ context( 1, "abstract_syntax", {"ts1", "ts2"}); context.set_transfer_syntaxes({"foo", "bar"}); BOOST_REQUIRE( context.get_transfer_syntaxes() == std::vector({"foo", "bar"})); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::PresentationContextRQ context( 3, "abstract_syntax", {"ts1", "ts2"}); std::ostringstream stream; stream << context; BOOST_REQUIRE_EQUAL(stream.str(), data); } BOOST_AUTO_TEST_CASE(Read) { std::istringstream stream(data); odil::pdu::PresentationContextRQ const context(stream); BOOST_REQUIRE_EQUAL(context.get_item_type(), 0x20); BOOST_REQUIRE_EQUAL(context.get_id(), 3); BOOST_REQUIRE_EQUAL(context.get_abstract_syntax(), "abstract_syntax"); BOOST_REQUIRE( context.get_transfer_syntaxes() == std::vector({"ts1", "ts2"})); } odil-0.4.1/tests/code/pdu/RoleSelection.cpp000066400000000000000000000034601266460524100205730ustar00rootroot00000000000000#define BOOST_TEST_MODULE RoleSelection #include #include #include #include "odil/pdu/RoleSelection.h" #include std::string const data( "\x54\x00\x00\x0b" "\x00\x07" "1.2.3.4" "\x01\x01", 15 ); BOOST_AUTO_TEST_CASE(DefaultConstructor) { odil::pdu::RoleSelection const item; BOOST_REQUIRE_EQUAL(item.get_sop_class_uid(), ""); BOOST_REQUIRE_EQUAL(item.get_scu_role_support(), false); BOOST_REQUIRE_EQUAL(item.get_scp_role_support(), false); } BOOST_AUTO_TEST_CASE(Constructor) { odil::pdu::RoleSelection const item("1.2.3.4", true, true); BOOST_REQUIRE_EQUAL(item.get_sop_class_uid(), "1.2.3.4"); BOOST_REQUIRE_EQUAL(item.get_scu_role_support(), true); BOOST_REQUIRE_EQUAL(item.get_scp_role_support(), true); } BOOST_AUTO_TEST_CASE(FromStream) { std::istringstream stream(data); odil::pdu::RoleSelection const item(stream); BOOST_REQUIRE_EQUAL(item.get_sop_class_uid(), "1.2.3.4"); BOOST_REQUIRE_EQUAL(item.get_scu_role_support(), true); BOOST_REQUIRE_EQUAL(item.get_scp_role_support(), true); } BOOST_AUTO_TEST_CASE(SOPClassUID) { odil::pdu::RoleSelection item; item.set_sop_class_uid("1.2.3.4"); BOOST_REQUIRE_EQUAL(item.get_sop_class_uid(), "1.2.3.4"); } BOOST_AUTO_TEST_CASE(SCURoleSupport) { odil::pdu::RoleSelection item; item.set_scu_role_support(true); BOOST_REQUIRE_EQUAL(item.get_scu_role_support(), true); } BOOST_AUTO_TEST_CASE(SCPRoleSupport) { odil::pdu::RoleSelection item; item.set_scp_role_support(true); BOOST_REQUIRE_EQUAL(item.get_scp_role_support(), true); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::RoleSelection item("1.2.3.4", true, true); std::ostringstream stream; stream << item; BOOST_REQUIRE_EQUAL(stream.str(), data); } odil-0.4.1/tests/code/pdu/UserIdentityAC.cpp000066400000000000000000000024771266460524100206670ustar00rootroot00000000000000#define BOOST_TEST_MODULE UserIdentityAC #include #include #include #include "odil/Exception.h" #include "odil/pdu/UserIdentityAC.h" BOOST_AUTO_TEST_CASE(ConstructorDefault) { odil::pdu::UserIdentityAC const user_identity; BOOST_REQUIRE_EQUAL(user_identity.get_server_response(), ""); } BOOST_AUTO_TEST_CASE(ConstructorString) { odil::pdu::UserIdentityAC const user_identity("foo"); BOOST_REQUIRE_EQUAL(user_identity.get_server_response(), "foo"); } BOOST_AUTO_TEST_CASE(FromStream) { std::string const data( "\x59\x00\x00\x05" "\x00\x03" "foo", 9 ); std::istringstream stream(data); odil::pdu::UserIdentityAC const user_identity(stream); BOOST_REQUIRE_EQUAL(user_identity.get_server_response(), "foo"); } BOOST_AUTO_TEST_CASE(Type) { odil::pdu::UserIdentityAC user_identity; user_identity.set_server_response("foo"); BOOST_REQUIRE_EQUAL(user_identity.get_server_response(), "foo"); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::UserIdentityAC user_identity; user_identity.set_server_response("foo"); std::ostringstream data; data << user_identity; std::string const expected( "\x59\x00\x00\x05" "\x00\x03" "foo", 9 ); BOOST_REQUIRE_EQUAL(data.str(), expected); } odil-0.4.1/tests/code/pdu/UserIdentityRQ.cpp000066400000000000000000000070551266460524100207230ustar00rootroot00000000000000#define BOOST_TEST_MODULE UserIdentityRQ #include #include #include #include "odil/Exception.h" #include "odil/pdu/UserIdentityRQ.h" BOOST_AUTO_TEST_CASE(Constructor) { odil::pdu::UserIdentityRQ const user_identity; BOOST_REQUIRE_EQUAL(user_identity.get_type(), 1); BOOST_REQUIRE_EQUAL(user_identity.get_positive_response_requested(), false); BOOST_REQUIRE_EQUAL(user_identity.get_primary_field(), ""); BOOST_REQUIRE_EQUAL(user_identity.get_secondary_field(), ""); } BOOST_AUTO_TEST_CASE(FromStream) { std::string const data( "\x58\x00\x00\x0c" "\x02\x01" "\x00\x03" "foo" "\x00\x03" "bar", 16 ); std::istringstream stream(data); odil::pdu::UserIdentityRQ const user_identity(stream); BOOST_REQUIRE_EQUAL(user_identity.get_type(), 2); BOOST_REQUIRE_EQUAL(user_identity.get_positive_response_requested(), true); BOOST_REQUIRE_EQUAL(user_identity.get_primary_field(), "foo"); BOOST_REQUIRE_EQUAL(user_identity.get_secondary_field(), "bar"); } BOOST_AUTO_TEST_CASE(Type) { odil::pdu::UserIdentityRQ user_identity; user_identity.set_type(2); BOOST_REQUIRE_EQUAL(user_identity.get_type(), 2); } BOOST_AUTO_TEST_CASE(PositiveResponseRequested) { odil::pdu::UserIdentityRQ user_identity; user_identity.set_positive_response_requested(true); BOOST_REQUIRE_EQUAL(user_identity.get_positive_response_requested(), true); } BOOST_AUTO_TEST_CASE(PrimaryField) { odil::pdu::UserIdentityRQ user_identity; user_identity.set_primary_field("foo"); BOOST_REQUIRE_EQUAL(user_identity.get_primary_field(), "foo"); } BOOST_AUTO_TEST_CASE(SecondaryField) { odil::pdu::UserIdentityRQ user_identity; user_identity.set_secondary_field("foo"); BOOST_REQUIRE_EQUAL(user_identity.get_secondary_field(), "foo"); } BOOST_AUTO_TEST_CASE(Username) { odil::pdu::UserIdentityRQ user_identity; user_identity.set_username("foo"); BOOST_REQUIRE_EQUAL(user_identity.get_type(), 1); BOOST_REQUIRE_EQUAL(user_identity.get_primary_field(), "foo"); BOOST_REQUIRE_EQUAL(user_identity.get_secondary_field(), ""); } BOOST_AUTO_TEST_CASE(UsernameAndPasscode) { odil::pdu::UserIdentityRQ user_identity; user_identity.set_username_and_passcode("foo", "bar"); BOOST_REQUIRE_EQUAL(user_identity.get_type(), 2); BOOST_REQUIRE_EQUAL(user_identity.get_primary_field(), "foo"); BOOST_REQUIRE_EQUAL(user_identity.get_secondary_field(), "bar"); } BOOST_AUTO_TEST_CASE(KerberosTicket) { odil::pdu::UserIdentityRQ user_identity; user_identity.set_kerberos_service_ticket("1234"); BOOST_REQUIRE_EQUAL(user_identity.get_type(), 3); BOOST_REQUIRE_EQUAL(user_identity.get_primary_field(), "1234"); BOOST_REQUIRE_EQUAL(user_identity.get_secondary_field(), ""); } BOOST_AUTO_TEST_CASE(SAMLAssertion) { odil::pdu::UserIdentityRQ user_identity; user_identity.set_saml_assertion("1234"); BOOST_REQUIRE_EQUAL(user_identity.get_type(), 4); BOOST_REQUIRE_EQUAL(user_identity.get_primary_field(), "1234"); BOOST_REQUIRE_EQUAL(user_identity.get_secondary_field(), ""); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::UserIdentityRQ user_identity; user_identity.set_username_and_passcode("foo", "bar"); user_identity.set_positive_response_requested(true); std::ostringstream data; data << user_identity; std::string const expected( "\x58\x00\x00\x0c" "\x02\x01" "\x00\x03" "foo" "\x00\x03" "bar", 16 ); BOOST_REQUIRE_EQUAL(data.str(), expected); } odil-0.4.1/tests/code/pdu/UserInformation.cpp000066400000000000000000000077071266460524100211600ustar00rootroot00000000000000#define BOOST_TEST_MODULE UserInformation #include #include #include "odil/Exception.h" #include "odil/pdu/ImplementationClassUID.h" #include "odil/pdu/ImplementationVersionName.h" #include "odil/pdu/MaximumLength.h" #include "odil/pdu/RoleSelection.h" #include "odil/pdu/UserInformation.h" #include "odil/pdu/UserIdentityAC.h" #include "odil/pdu/UserIdentityRQ.h" BOOST_AUTO_TEST_CASE(ConstructorDefault) { odil::pdu::UserInformation const item; BOOST_REQUIRE(item.get_sub_items().empty()); BOOST_REQUIRE(item.get_sub_items().empty()); } BOOST_AUTO_TEST_CASE(ConstructorStreamMaximumLength) { std::string const data( "\x50\x00\x00\x08" "\x51\x00\x00\x04" "\x12\x34\x56\x78", 12 ); std::istringstream stream(data); odil::pdu::UserInformation const item(stream); BOOST_REQUIRE_EQUAL( item.get_sub_items().size(), 1); } BOOST_AUTO_TEST_CASE(ConstructorStreamImplementationClassUID) { std::string const data( "\x50\x00\x00\x07" "\x52\x00\x00\x03" "foo", 11 ); std::istringstream stream(data); odil::pdu::UserInformation const item(stream); BOOST_REQUIRE_EQUAL( item.get_sub_items().size(), 1); } BOOST_AUTO_TEST_CASE(ConstructorStreamRoleSelection) { std::string const data( "\x50\x00\x00\x0f" "\x54\x00\x00\x0b" "\x00\x07" "1.2.3.4" "\x01\x01", 19 ); std::istringstream stream(data); odil::pdu::UserInformation const item(stream); BOOST_REQUIRE_EQUAL( item.get_sub_items().size(), 1); } BOOST_AUTO_TEST_CASE(ConstructorStreamImplementationVersionName) { std::string const data( "\x50\x00\x00\x07" "\x55\x00\x00\x03" "foo", 11 ); std::istringstream stream(data); odil::pdu::UserInformation const item(stream); BOOST_REQUIRE_EQUAL( item.get_sub_items().size(), 1); } BOOST_AUTO_TEST_CASE(ConstructorStreamUserIdentityRQ) { std::string const data( "\x50\x00\x00\x10" "\x58\x00\x00\x0c" "\x02\x01" "\x00\x03" "foo" "\x00\x03" "bar", 20 ); std::istringstream stream(data); odil::pdu::UserInformation const item(stream); BOOST_REQUIRE_EQUAL( item.get_sub_items().size(), 1); } BOOST_AUTO_TEST_CASE(ConstructorStreamUserIdentityAC) { std::string const data( "\x50\x00\x00\x0a" "\x59\x00\x00\x06" "\x00\x04" "abcd", 14 ); std::istringstream stream(data); odil::pdu::UserInformation const item(stream); BOOST_REQUIRE_EQUAL( item.get_sub_items().size(), 1); } BOOST_AUTO_TEST_CASE(SetSubItems) { odil::pdu::UserInformation item; BOOST_REQUIRE(item.get_sub_items().empty()); item.set_sub_items({{0x12345678}}); BOOST_REQUIRE_EQUAL( item.get_sub_items().size(), 1); } BOOST_AUTO_TEST_CASE(DeleteSubItems) { odil::pdu::UserInformation item; BOOST_REQUIRE(item.get_sub_items().empty()); item.set_sub_items({{0x12345678}}); BOOST_REQUIRE_EQUAL( item.get_sub_items().size(), 1); item.delete_sub_items(); BOOST_REQUIRE(item.get_sub_items().empty()); } BOOST_AUTO_TEST_CASE(Write) { odil::pdu::UserInformation item; item.set_sub_items({{0x12345678}}); std::ostringstream data; data << item; std::string const expected( "\x50\x00\x00\x08" "\x51\x00\x00\x04" "\x12\x34\x56\x78", 12 ); BOOST_REQUIRE_EQUAL(data.str(), expected); } odil-0.4.1/tests/code/registry.cpp000066400000000000000000000017501266460524100171040ustar00rootroot00000000000000#define BOOST_TEST_MODULE registry #include #include "odil/registry.h" #include "odil/Tag.h" BOOST_AUTO_TEST_CASE(PublicDictionary) { auto const iterator = odil::registry::public_dictionary.find( odil::registry::PatientName); BOOST_REQUIRE(iterator != odil::registry::public_dictionary.end()); auto const & entry = iterator->second; BOOST_REQUIRE_EQUAL(entry.name, "Patient's Name"); BOOST_REQUIRE_EQUAL(entry.keyword, "PatientName"); BOOST_REQUIRE_EQUAL(entry.vr, "PN"); BOOST_REQUIRE_EQUAL(entry.vm, "1"); } BOOST_AUTO_TEST_CASE(UIDsDictionary) { auto const iterator = odil::registry::uids_dictionary.find( odil::registry::MRImageStorage); BOOST_REQUIRE(iterator != odil::registry::uids_dictionary.end()); auto const & entry = iterator->second; BOOST_REQUIRE_EQUAL(entry.name, "MR Image Storage"); BOOST_REQUIRE_EQUAL(entry.keyword, "MRImageStorage"); BOOST_REQUIRE_EQUAL(entry.type, "SOP Class"); } odil-0.4.1/tests/code/uid.cpp000066400000000000000000000004651266460524100160170ustar00rootroot00000000000000#define BOOST_TEST_MODULE UID #include #include "odil/uid.h" BOOST_AUTO_TEST_CASE(generate) { std::string const uid = odil::generate_uid(); BOOST_REQUIRE_LE(uid.size(), 64); for(auto const & c: uid) { BOOST_REQUIRE((c>='0' && c<='9') || c == '.'); } } odil-0.4.1/tests/code/unicode.cpp000066400000000000000000000142211266460524100166570ustar00rootroot00000000000000#define BOOST_TEST_MODULE unicode #include #include "odil/DataSet.h" #include "odil/unicode.h" #include "odil/dcmtk/conversion.h" BOOST_AUTO_TEST_CASE(SCSARAB) { odil::Value::Strings const specific_character_set = { "ISO_IR 127" }; std::string const source = "\xe2\xc8\xc7\xe6\xea" "^" "\xe4\xe6\xd2\xc7\xd1"; std::string const expected = "\xd9\x82\xd8\xa8\xd8\xa7\xd9\x86\xd9\x8a" "^" "\xd9\x84\xd9\x86\xd8\xb2\xd8\xa7\xd8\xb1"; std::string const utf8 = odil::as_utf8( source, specific_character_set, true); BOOST_REQUIRE_EQUAL(utf8, expected); } BOOST_AUTO_TEST_CASE(SCSFREN) { odil::Value::Strings const specific_character_set = { "ISO_IR 100" }; std::string const source = "Buc" "^" "J\xe9r\xf4me"; std::string const expected = "Buc" "^" "J\xc3\xa9r\xc3\xb4me"; std::string const utf8 = odil::as_utf8( source, specific_character_set, true); BOOST_REQUIRE_EQUAL(utf8, expected); } BOOST_AUTO_TEST_CASE(SCSGERM) { odil::Value::Strings const specific_character_set = { "ISO_IR 100" }; std::string const source = "\xc4neas" "^" "R\xfc" "diger"; std::string const expected = "\xc3\x84neas" "^" "R\xc3\xbc" "diger"; std::string const utf8 = odil::as_utf8( source, specific_character_set, true); BOOST_REQUIRE_EQUAL(utf8, expected); } BOOST_AUTO_TEST_CASE(SCSGREEK) { odil::Value::Strings const specific_character_set = { "ISO_IR 126" }; std::string const source = "\xc4\xe9\xef\xed\xf5\xf3\xe9\xef\xf2"; std::string const expected = "\xce\x94\xce\xb9\xce\xbf\xce\xbd\xcf\x85\xcf\x83\xce\xb9\xce\xbf\xcf\x82"; std::string const utf8 = odil::as_utf8( source, specific_character_set, true); BOOST_REQUIRE_EQUAL(utf8, expected); } BOOST_AUTO_TEST_CASE(SCSH31) { odil::Value::Strings const specific_character_set = { "", "ISO 2022 IR 87" }; std::string const source = "Yamada" "^" "Tarou" "=" "\x1b\x24\x42\x3b\x33\x45\x44\x1b\x28\x42" "^" "\x1b\x24\x42\x42\x40\x4f\x3a\x1b\x28\x42" "=" "\x1b\x24\x42\x24\x64\x24\x5e\x24\x40\x1b\x28\x42" "^" "\x1b\x24\x42\x24\x3f\x24\x6d\x24\x26\x1b\x28\x42"; std::string const expected = "Yamada" "^" "Tarou" "=" "\xe5\xb1\xb1\xe7\x94\xb0" "^" "\xe5\xa4\xaa\xe9\x83\x8e" "=" "\xe3\x82\x84\xe3\x81\xbe\xe3\x81\xa0" "^" "\xe3\x81\x9f\xe3\x82\x8d\xe3\x81\x86"; std::string const utf8 = odil::as_utf8( source, specific_character_set, true); BOOST_REQUIRE_EQUAL(utf8, expected); } BOOST_AUTO_TEST_CASE(SCSH32) { odil::Value::Strings const specific_character_set = { "ISO 2022 IR 13", "ISO 2022 IR 87" }; std::string const source = "\xd4\xcf\xc0\xde" "^" "\xc0\xdb\xb3" "=" "\x1b\x24\x42\x3b\x33\x45\x44\x1b\x28\x4a" "^" "\x1b\x24\x42\x42\x40\x4f\x3a\x1b\x28\x4a" "=" "\x1b\x24\x42\x24\x64\x24\x5e\x24\x40\x1b\x28\x4a" "\x5e\x1b\x24\x42\x24\x3f\x24\x6d\x24\x26\x1b\x28\x4a"; std::string const expected = "\xef\xbe\x94\xef\xbe\x8f\xef\xbe\x80\xef\xbe\x9e" "^" "\xef\xbe\x80\xef\xbe\x9b\xef\xbd\xb3" "=" "\xe5\xb1\xb1\xe7\x94\xb0" "^" "\xe5\xa4\xaa\xe9\x83\x8e" "=" "\xe3\x82\x84\xe3\x81\xbe\xe3\x81\xa0" "^" "\xe3\x81\x9f\xe3\x82\x8d\xe3\x81\x86"; std::string const utf8 = odil::as_utf8( source, specific_character_set, true); BOOST_REQUIRE_EQUAL(utf8, expected); } BOOST_AUTO_TEST_CASE(SCSHBRW) { odil::Value::Strings const specific_character_set = { "ISO_IR 138" }; std::string const source = "\xf9\xf8\xe5\xef" "^" "\xe3\xe1\xe5\xf8\xe4"; std::string const expected = "\xd7\xa9\xd7\xa8\xd7\x95\xd7\x9f" "^" "\xd7\x93\xd7\x91\xd7\x95\xd7\xa8\xd7\x94"; std::string const utf8 = odil::as_utf8( source, specific_character_set, true); BOOST_REQUIRE_EQUAL(utf8, expected); } BOOST_AUTO_TEST_CASE(SCSI2) { odil::Value::Strings const specific_character_set = { "", "ISO 2022 IR 149" }; std::string const source = "\x48\x6f\x6e\x67" "^" "\x47\x69\x6c\x64\x6f\x6e\x67" "=" "\x1b\x24\x29\x43\xfb\xf3" "^" "\x1b\x24\x29\x43\xd1\xce\xd4\xd7" "=" "\x1b\x24\x29\x43\xc8\xab" "^" "\x1b\x24\x29\x43\xb1\xe6\xb5\xbf"; std::string const expected = "\x48\x6f\x6e\x67" "^" "\x47\x69\x6c\x64\x6f\x6e\x67" "=" "\xe6\xb4\xaa" "^" "\xe5\x90\x89\xe6\xb4\x9e" "=" "\xed\x99\x8d" "^" "\xea\xb8\xb8\xeb\x8f\x99"; std::string const utf8 = odil::as_utf8( source, specific_character_set, true); BOOST_REQUIRE_EQUAL(utf8, expected); } BOOST_AUTO_TEST_CASE(SCSRUSS) { odil::Value::Strings const specific_character_set = { "ISO_IR 144" }; std::string const source = "\xbb\xee\xda\x63\x65\xdc\xd1\x79\x70\xd3"; std::string const expected = "\xd0\x9b\xd1\x8e\xd0\xba\x63\x65\xd0\xbc\xd0\xb1\x79\x70\xd0\xb3"; std::string const utf8 = odil::as_utf8( source, specific_character_set, true); BOOST_REQUIRE_EQUAL(utf8, expected); } BOOST_AUTO_TEST_CASE(SCSX1) { odil::Value::Strings const specific_character_set = { "ISO_IR 192" }; std::string const source = "Wang" "^" "XiaoDong" "=" "\xe7\x8e\x8b" "^" "\xe5\xb0\x8f\xe6\x9d\xb1" "="; std::string const expected = "Wang" "^" "XiaoDong" "\x3d\xe7\x8e\x8b" "^" "\xe5\xb0\x8f\xe6\x9d\xb1" "="; std::string const utf8 = odil::as_utf8( source, specific_character_set, true); BOOST_REQUIRE_EQUAL(utf8, expected); } BOOST_AUTO_TEST_CASE(SCSX2) { odil::Value::Strings const specific_character_set = { "GB18030" }; std::string const source = "Wang" "^" "XiaoDong" "=" "" "\xcd\xf5" "^" "\xd0\xa1\xb6\xab" "="; std::string const expected = "Wang" "^" "XiaoDong" "=" "\xe7\x8e\x8b" "^" "\xe5\xb0\x8f\xe4\xb8\x9c" "="; std::string const utf8 = odil::as_utf8( source, specific_character_set, true); BOOST_REQUIRE_EQUAL(utf8, expected); } odil-0.4.1/tests/code/xml_converter.cpp000066400000000000000000001220731266460524100201250ustar00rootroot00000000000000#define BOOST_TEST_MODULE xml_converter #include #include "odil/xml_converter.h" void check_attributes(boost::property_tree::ptree const & xml, std::string const & tag, std::string const & vr, std::string const & keyword) { BOOST_REQUIRE_EQUAL(xml.size(), 3); auto it_attr = xml.begin(); BOOST_CHECK_EQUAL((*it_attr).first, "vr"); BOOST_CHECK_EQUAL((*it_attr).second.get_value(), vr); BOOST_REQUIRE((*it_attr).second.empty()); ++it_attr; BOOST_CHECK_EQUAL((*it_attr).first, "tag"); BOOST_CHECK_EQUAL((*it_attr).second.get_value(), tag); BOOST_REQUIRE((*it_attr).second.empty()); ++it_attr; BOOST_CHECK_EQUAL((*it_attr).first, "keyword"); BOOST_REQUIRE((*it_attr).second.empty()); BOOST_CHECK_EQUAL((*it_attr).second.get_value(), keyword); } template void check_value(boost::property_tree::ptree const & xml, TValueType const & values, int count) { BOOST_REQUIRE_EQUAL(xml.size(), 1); BOOST_CHECK_EQUAL( xml.get_value(), values[count]); // Look for Attribut of Value XML tag BOOST_CHECK_EQUAL(xml.front().first, ""); BOOST_REQUIRE_EQUAL(xml.front().second.size(), 1); auto it_attr = xml.front().second.begin(); BOOST_CHECK_EQUAL((*it_attr).first, "number"); BOOST_REQUIRE((*it_attr).second.empty()); BOOST_CHECK_EQUAL((*it_attr).second.get_value(), count + 1); } template void check_response(boost::property_tree::ptree const & xml, std::string const & tag, std::string const & vr, std::string const & keyword, TValueType const & values) { BOOST_REQUIRE_EQUAL(xml.size(), 1); BOOST_CHECK_EQUAL(xml.front().first, "NativeDicomModel"); auto const native_dicom_model = xml.front().second; BOOST_REQUIRE_EQUAL(native_dicom_model.size(), 1); BOOST_CHECK_EQUAL(native_dicom_model.front().first, "DicomAttribute"); BOOST_REQUIRE_EQUAL(native_dicom_model.front().second.size(), values.size() + 1); // Should contains BOOST_REQUIRE_EQUAL( native_dicom_model.front().second.find("")->first, ""); int count = 0; for (auto it = native_dicom_model.front().second.begin(); it != native_dicom_model.front().second.end(); ++it) { if ((*it).first == "") { check_attributes((*it).second, tag, vr, keyword); } else if ((*it).first == "Value") { BOOST_CHECK_EQUAL((*it).first, "Value"); check_value(it->second, values, count); ++count; } else { BOOST_FAIL("Unexpected tag"); } } BOOST_REQUIRE_EQUAL(count, values.size()); } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsXMLEmpty) { odil::DataSet data_set; auto const xml = odil::as_xml(data_set); // Expected result: // BOOST_REQUIRE_EQUAL(xml.size(), 1); BOOST_CHECK_EQUAL(xml.front().first, "NativeDicomModel"); BOOST_REQUIRE(xml.front().second.empty()); } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsXMLIntegers) { odil::DataSet data_set; data_set.add(0x00280010, odil::Element(odil::Value::Integers({1, 2}), odil::VR::US)); auto const xml = odil::as_xml(data_set); // Expected result: // // // 1 // 2 // // check_response(xml, "00280010", "US", "Rows", odil::Value::Integers({1, 2})); } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsXMLReals) { odil::DataSet data_set; data_set.add(0x00089459, odil::Element(odil::Value::Reals({1.2, 3.4}), odil::VR::FL)); auto const xml = odil::as_xml(data_set); // Expected result: // // // 1.2 // 3.4 // // check_response(xml, "00089459", "FL", "RecommendedDisplayFrameRateInFloat", odil::Value::Reals({1.2, 3.4})); } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsXMLStrings) { odil::DataSet data_set; data_set.add(0x00080060, odil::Element( odil::Value::Strings({"FOO", "BAR"}), odil::VR::CS)); auto const xml = odil::as_xml(data_set); // Expected result: // // // FOO // BAR // // check_response(xml, "00080060", "CS", "Modality", odil::Value::Strings({"FOO", "BAR"})); } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsXMLPersonName) { odil::DataSet data_set; data_set.add(0x00100010, odil::Element( odil::Value::Strings({"Alpha^Betic=Ideo^Graphic=Pho^Netic", "family^given^middle^prefix^suffix"}), odil::VR::PN)); auto const xml = odil::as_xml(data_set); // Expected result: // // // // // Alpha // Betic // // // Ideo // Graphic // // // Pho // Netic // // // // // family // given // middle // prefix // suffix // // // // BOOST_REQUIRE_EQUAL(xml.size(), 1); BOOST_CHECK_EQUAL(xml.front().first, "NativeDicomModel"); auto const native_dicom_model = xml.front().second; BOOST_REQUIRE_EQUAL(native_dicom_model.size(), 1); BOOST_CHECK_EQUAL(native_dicom_model.front().first, "DicomAttribute"); BOOST_REQUIRE_EQUAL(native_dicom_model.front().second.size(), 3); // Should contains BOOST_REQUIRE_EQUAL( native_dicom_model.front().second.find("")->first, ""); std::vector > > values; std::map > person_name1; { std::map person_name_sub; person_name_sub.insert(std::pair("FamilyName", "Alpha")); person_name_sub.insert(std::pair("GivenName", "Betic")); person_name1.insert(std::pair >("Alphabetic", person_name_sub)); } { std::map person_name_sub; person_name_sub.insert(std::pair("FamilyName", "Ideo")); person_name_sub.insert(std::pair("GivenName", "Graphic")); person_name1.insert(std::pair >("Ideographic", person_name_sub)); } { std::map person_name_sub; person_name_sub.insert(std::pair("FamilyName", "Pho")); person_name_sub.insert(std::pair("GivenName", "Netic")); person_name1.insert(std::pair >("Phonetic", person_name_sub)); } values.push_back(person_name1); std::map > person_name2; { std::map person_name_sub; person_name_sub.insert(std::pair("FamilyName", "family")); person_name_sub.insert(std::pair("GivenName", "given")); person_name_sub.insert(std::pair("MiddleName", "middle")); person_name_sub.insert(std::pair("NamePrefix", "prefix")); person_name_sub.insert(std::pair("NameSuffix", "suffix")); person_name2.insert(std::pair >("Alphabetic", person_name_sub)); } values.push_back(person_name2); int count = 0; for (auto it = native_dicom_model.front().second.begin(); it != native_dicom_model.front().second.end(); ++it) { if ((*it).first == "") { // Look for Attribut of DicomAttribute XML tag BOOST_CHECK_EQUAL((*it).first, ""); check_attributes((*it).second, "00100010", "PN", "PatientName"); } else if ((*it).first == "PersonName") { BOOST_REQUIRE_EQUAL((*it).second.size(), values[count].size() + 1); // + 1 for // Should contains BOOST_REQUIRE_EQUAL( (*it).second.find("")->first, ""); auto const fields = { "Alphabetic", "Ideographic", "Phonetic" }; for (auto it_pname = (*it).second.begin(); it_pname != (*it).second.end(); ++it_pname) { if ((*it_pname).first == "") { BOOST_CHECK_EQUAL((*it_pname).first, ""); BOOST_REQUIRE_EQUAL((*it_pname).second.size(), 1); auto it_attr = (*it_pname).second.begin(); BOOST_CHECK_EQUAL((*it_attr).first, "number"); BOOST_REQUIRE((*it_attr).second.empty()); BOOST_CHECK_EQUAL((*it_attr).second.get_value(), count + 1); } else if (std::find(fields.begin(), fields.end(), (*it_pname).first) != fields.end()) { BOOST_REQUIRE_EQUAL((*it_pname).second.size(), values[count][(*it_pname).first].size()); auto const fields_name = { "NameSuffix", "NamePrefix", "MiddleName", "GivenName", "FamilyName" }; for (auto it_subpname = (*it_pname).second.begin(); it_subpname != (*it_pname).second.end(); ++it_subpname) { if (std::find(fields_name.begin(), fields_name.end(), (*it_subpname).first) != fields_name.end()) { BOOST_REQUIRE((*it_subpname).second.empty()); BOOST_CHECK_EQUAL((*it_subpname).second. get_value(), values[count][(*it_pname).first] [(*it_subpname).first]); } else { std::stringstream error; error << "Unexpected tag: " << (*it_subpname).first; BOOST_FAIL(error.str()); } } } else { std::stringstream error; error << "Unexpected tag: " << (*it_pname).first; BOOST_FAIL(error.str()); } } ++count; } else { BOOST_FAIL("Unexpected tag"); } } BOOST_REQUIRE_EQUAL(count, values.size()); } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsXMLDataSets) { odil::DataSet item1; item1.add(0x00100020, odil::Element(odil::Value::Strings({"valueLO1"}), odil::VR::LO)); item1.add(0x00100022, odil::Element(odil::Value::Strings({"valueCS1"}), odil::VR::CS)); odil::DataSet item2; item2.add(0x00100022, odil::Element(odil::Value::Strings({"valueCS2"}), odil::VR::CS)); odil::DataSet data_set; data_set.add(0x00101002, odil::Element( odil::Value::DataSets({item1, item2}), odil::VR::SQ)); auto const xml = odil::as_xml(data_set); // Expected result: // // // // // valueLO1 // // // valueCS1 // // // // // valueCS2 // // // // BOOST_REQUIRE_EQUAL(xml.size(), 1); BOOST_CHECK_EQUAL(xml.front().first, "NativeDicomModel"); auto const native_dicom_model = xml.front().second; BOOST_REQUIRE_EQUAL(native_dicom_model.size(), 1); BOOST_CHECK_EQUAL(native_dicom_model.front().first, "DicomAttribute"); BOOST_REQUIRE_EQUAL(native_dicom_model.front().second.size(), 3); odil::Value::DataSets expected_values({item1, item2}); int count = 0; for (auto it = native_dicom_model.front().second.begin(); it != native_dicom_model.front().second.end(); ++it) { if ((*it).first == "") { // Look for Attribut of DicomAttribute XML tag BOOST_CHECK_EQUAL((*it).first, ""); check_attributes((*it).second, "00101002", "SQ", "OtherPatientIDsSequence"); } else if ((*it).first == "Item") { auto current_value = expected_values[count].begin(); BOOST_REQUIRE_EQUAL((*it).second.size(), expected_values[count].size() + 1); // Should contains BOOST_REQUIRE_EQUAL( (*it).second.find("")->first, ""); for (auto it_item = (*it).second.begin(); it_item != (*it).second.end(); ++it_item) { if ((*it_item).first == "") { BOOST_REQUIRE_EQUAL((*it_item).second.size(), 1); auto it_attr = (*it_item).second.begin(); BOOST_CHECK_EQUAL((*it_attr).first, "number"); BOOST_REQUIRE((*it_attr).second.empty()); BOOST_CHECK_EQUAL((*it_attr).second.get_value(), count + 1); } else if ((*it_item).first == "DicomAttribute") { BOOST_REQUIRE_EQUAL((*it_item).second.size(), 2); // Should contains BOOST_REQUIRE_EQUAL( (*it_item).second.find("")->first, ""); for (auto it_dicomattr = (*it_item).second.begin(); it_dicomattr != (*it_item).second.end(); ++it_dicomattr) { if ((*it_dicomattr).first == "") { check_attributes((*it_dicomattr).second, std::string(current_value->first), odil::as_string( current_value->second.vr), current_value->first.get_name()); } else if ((*it_dicomattr).first == "Value") { check_value((*it_dicomattr).second, current_value->second.as_string(), 0); } else { std::stringstream error; error << "Unexpected tag: " << (*it_dicomattr).first; BOOST_FAIL(error.str()); } } ++current_value; } else { std::stringstream error; error << "Unexpected tag: " << (*it_item).first; BOOST_FAIL(error.str()); } } ++count; } else { std::stringstream error; error << "Unexpected tag: " << (*it).first; BOOST_FAIL(error.str()); } } BOOST_REQUIRE_EQUAL(count, expected_values.size()); } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsXMLBinary) { odil::DataSet data_set; data_set.add(0x00660023, odil::Element( odil::Value::Binary({0x1, 0x2, 0x3, 0x4, 0x5}), odil::VR::OW)); auto const xml = odil::as_xml(data_set); // Expected result: // // // AQIDBAU= // // BOOST_REQUIRE_EQUAL(xml.size(), 1); BOOST_CHECK_EQUAL(xml.front().first, "NativeDicomModel"); auto const native_dicom_model = xml.front().second; BOOST_REQUIRE_EQUAL(native_dicom_model.size(), 1); BOOST_CHECK_EQUAL(native_dicom_model.front().first, "DicomAttribute"); BOOST_REQUIRE_EQUAL(native_dicom_model.front().second.size(), 2); // Should contains BOOST_REQUIRE_EQUAL( native_dicom_model.front().second.find("")->first, ""); int count = 0; for (auto it = native_dicom_model.front().second.begin(); it != native_dicom_model.front().second.end(); ++it) { if ((*it).first == "") { check_attributes((*it).second, "00660023", "OW", "TrianglePointIndexList"); } else if ((*it).first == "InlineBinary") { BOOST_REQUIRE((*it).second.empty()); BOOST_CHECK_EQUAL((*it).second.get_value(), "AQIDBAU="); ++count; } else { std::stringstream error; error << "Unexpected tag: " << (*it).first; BOOST_FAIL(error.str()); } } BOOST_REQUIRE_EQUAL(count, 1); } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsXMLEmptyElement) { odil::DataSet data_set; data_set.add(0x00080060, odil::Element( odil::Value::Strings({}), odil::VR::CS)); auto const xml = odil::as_xml(data_set); // Expected result: // // // check_response(xml, "00080060", "CS", "Modality", odil::Value::Strings({})); } /******************************* TEST Error ************************************/ BOOST_AUTO_TEST_CASE(AsXMLInvalidPersonName) { // Too many values separate by '^' { odil::DataSet data_set; data_set.add(0x00100010, odil::Element( odil::Value::Strings({"Alpha^Betic^Ideo^Graphic^Pho^Netic"}), odil::VR::PN)); BOOST_REQUIRE_THROW(odil::as_xml(data_set), odil::Exception); } // Too many values separate by '=' { odil::DataSet data_set; data_set.add(0x00100010, odil::Element( odil::Value::Strings( {"Alpha^Betic=Ideo^Graphic=Pho^Netic=Bad^Value"}), odil::VR::PN)); BOOST_REQUIRE_THROW(odil::as_xml(data_set), odil::Exception); } } /******************************* TEST Error ************************************/ BOOST_AUTO_TEST_CASE(AsXMLInvalidDICOMTag) { odil::DataSet data_set; data_set.add(0xbad00bad, odil::Element( odil::Value::Strings({"value"}), odil::VR::CS)); BOOST_REQUIRE_THROW(odil::as_xml(data_set), odil::Exception); } /******************************* TEST Error ************************************/ BOOST_AUTO_TEST_CASE(AsXMLBadVR) { odil::DataSet data_set; data_set.add(0x00080060, odil::Element( odil::Value::Strings({"value"}), odil::VR::UNKNOWN)); BOOST_REQUIRE_THROW(odil::as_xml(data_set), odil::Exception); } template odil::DataSet create_dataset(std::string const & tag, std::string const & vr, std::string const & keyword, TValueType const & values, std::vector const & order) { boost::property_tree::ptree dicomattribute; dicomattribute.put(".vr", vr); dicomattribute.put(".tag", tag); dicomattribute.put(".keyword", keyword); for (unsigned int i = 0; i < values.size(); ++i) { boost::property_tree::ptree tag_value; tag_value.put(".number", order[i] + 1); tag_value.put_value(values[order[i]]); dicomattribute.add_child("Value", tag_value); } boost::property_tree::ptree nativedicommodel; nativedicommodel.add_child("DicomAttribute", dicomattribute); boost::property_tree::ptree dataset_xml; dataset_xml.add_child("NativeDicomModel", nativedicommodel); return odil::as_dataset(dataset_xml); } template void create_dataset_error(std::string const & tag, std::string const & vr, std::string const & keyword, T const & value) { boost::property_tree::ptree dicomattribute; dicomattribute.put(".vr", vr); dicomattribute.put(".tag", tag); dicomattribute.put(".keyword", keyword); boost::property_tree::ptree tag_value; tag_value.put(".number", 1); tag_value.put_value(value); dicomattribute.add_child("BadNode", tag_value); boost::property_tree::ptree nativedicommodel; nativedicommodel.add_child("DicomAttribute", dicomattribute); boost::property_tree::ptree dataset_xml; dataset_xml.add_child("NativeDicomModel", nativedicommodel); // throw Exception odil::as_dataset(dataset_xml); } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsDataSetEmpty) { boost::property_tree::ptree dataset_xml; dataset_xml.add_child("NativeDicomModel", boost::property_tree::ptree()); odil::DataSet const data_set = odil::as_dataset(dataset_xml); BOOST_REQUIRE(data_set.empty()); } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsDataSetIntegers) { odil::Value::Integers values({128, 256}); // Tag Value sorted by number and not sorted std::vector > orders = {{0, 1}, {1, 0}}; for (auto order : orders) { auto const data_set = create_dataset("00280010", "US", "Rows", values, order); BOOST_REQUIRE_EQUAL(data_set.size(), 1); BOOST_REQUIRE(data_set.has("00280010")); BOOST_REQUIRE(data_set.get_vr("00280010") == odil::VR::US); BOOST_REQUIRE(data_set.is_int("00280010")); BOOST_REQUIRE(data_set.as_int("00280010") == values); } } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsDataSetReals) { odil::Value::Reals values({1.2, 3.4}); // Tag Value sorted by number and not sorted std::vector > orders = {{0, 1}, {1, 0}}; for (auto order : orders) { auto const data_set = create_dataset( "00089459", "FL", "RecommendedDisplayFrameRateInFloat", values, order); BOOST_REQUIRE_EQUAL(data_set.size(), 1); BOOST_REQUIRE(data_set.has("00089459")); BOOST_REQUIRE(data_set.get_vr("00089459") == odil::VR::FL); BOOST_REQUIRE(data_set.is_real("00089459")); BOOST_REQUIRE(data_set.as_real("00089459") == values); } } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsDataSetStrings) { odil::Value::Strings values({"FOO", "BAR"}); // Tag Value sorted by number and not sorted std::vector > orders = {{0, 1}, {1, 0}}; for (auto order : orders) { auto const data_set = create_dataset("00080060", "CS", "Modality", values, order); BOOST_REQUIRE_EQUAL(data_set.size(), 1); BOOST_REQUIRE(data_set.has("00080060")); BOOST_REQUIRE(data_set.get_vr("00080060") == odil::VR::CS); BOOST_REQUIRE(data_set.is_string("00080060")); BOOST_REQUIRE(data_set.as_string("00080060") == values); } } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsDataSetPersonName) { std::vector > > values; std::map name; name.insert(std::pair("FamilyName", "family")); name.insert(std::pair("GivenName", "given")); name.insert(std::pair("MiddleName", "middle")); name.insert(std::pair("NamePrefix", "prefix")); name.insert(std::pair("NameSuffix", "suffix")); std::map > person_name1; person_name1.insert(std::pair >("Alphabetic", name)); values.push_back(person_name1); std::map name2; name2.insert(std::pair("FamilyName", "family")); std::map > person_name2; person_name2.insert(std::pair >("Alphabetic", name2)); person_name2.insert(std::pair >("Ideographic", name2)); person_name2.insert(std::pair >("Phonetic", name2)); values.push_back(person_name2); std::vector > orders = {{0, 1}, {1, 0}}; for (auto order : orders) { boost::property_tree::ptree dicomattribute; dicomattribute.put(".vr", "PN"); dicomattribute.put(".tag", "00100010"); dicomattribute.put(".keyword", "PatientName"); for (int number : order) { boost::property_tree::ptree tag_value; tag_value.put(".number", number + 1); for (auto it = values[number].begin(); it != values[number].end(); ++it) { boost::property_tree::ptree tag_pname; for (auto it_name = it->second.begin(); it_name != it->second.end(); ++it_name) { boost::property_tree::ptree tag_name; tag_name.put_value(it_name->second); tag_pname.add_child(it_name->first, tag_name); } tag_value.add_child(it->first, tag_pname); } dicomattribute.add_child("PersonName", tag_value); } boost::property_tree::ptree nativedicommodel; nativedicommodel.add_child("DicomAttribute", dicomattribute); boost::property_tree::ptree dataset_xml; dataset_xml.add_child("NativeDicomModel", nativedicommodel); odil::DataSet const data_set = odil::as_dataset(dataset_xml); BOOST_REQUIRE_EQUAL(data_set.size(), 1); BOOST_REQUIRE(data_set.has("00100010")); BOOST_REQUIRE(data_set.get_vr("00100010") == odil::VR::PN); BOOST_REQUIRE(data_set.is_string("00100010")); BOOST_REQUIRE(data_set.as_string("00100010") == odil::Value::Strings( {"family^given^middle^prefix^suffix", "family=family=family"})); } } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsDataSetDataSets) { odil::DataSet item1; item1.add(0x00100020, odil::Element(odil::Value::Strings({"FOO"}), odil::VR::LO)); item1.add(0x00100022, odil::Element(odil::Value::Strings({"BAR"}), odil::VR::CS)); odil::DataSet item2; item2.add(0x00100020, odil::Element(odil::Value::Strings({"OTHER"}), odil::VR::LO)); odil::Value::DataSets expected_result({item1, item2}); std::vector > orders = {{0, 1}, {1, 0}}; for (auto order : orders) { boost::property_tree::ptree dicomattribute; dicomattribute.put(".vr", "SQ"); dicomattribute.put(".tag", "00101002"); dicomattribute.put(".keyword", "OtherPatientIDsSequence"); for (int number : order) { boost::property_tree::ptree tag_value; tag_value.put(".number", number + 1); for (auto it = expected_result[number].begin(); it != expected_result[number].end(); ++it) { boost::property_tree::ptree subdicomattribute; subdicomattribute.put(".vr", odil::as_string(it->second.vr)); subdicomattribute.put(".tag", std::string(it->first)); subdicomattribute.put(".keyword", it->first.get_name()); for (auto value : it->second.as_string()) { boost::property_tree::ptree subtag_value; subtag_value.put(".number", 1); subtag_value.put_value(value); subdicomattribute.add_child("Value", subtag_value); } boost::property_tree::ptree nativedicommodel; tag_value.add_child("DicomAttribute", subdicomattribute); } dicomattribute.add_child("Item", tag_value); } boost::property_tree::ptree nativedicommodel; nativedicommodel.add_child("DicomAttribute", dicomattribute); boost::property_tree::ptree dataset_xml; dataset_xml.add_child("NativeDicomModel", nativedicommodel); odil::DataSet const data_set = odil::as_dataset(dataset_xml); BOOST_REQUIRE_EQUAL(data_set.size(), 1); BOOST_REQUIRE(data_set.has("00101002")); BOOST_REQUIRE(data_set.get_vr("00101002") == odil::VR::SQ); BOOST_REQUIRE(data_set.is_data_set("00101002")); BOOST_REQUIRE(data_set.as_data_set("00101002") == expected_result); } } /******************************* TEST Nominal **********************************/ BOOST_AUTO_TEST_CASE(AsDataSetBinary) { boost::property_tree::ptree dicomattribute; dicomattribute.put(".vr", "OW"); dicomattribute.put(".tag", "00660023"); dicomattribute.put(".keyword", "TrianglePointIndexList"); { boost::property_tree::ptree tag_value; tag_value.put_value("AQIDBAU="); dicomattribute.add_child("InlineBinary", tag_value); } boost::property_tree::ptree nativedicommodel; nativedicommodel.add_child("DicomAttribute", dicomattribute); boost::property_tree::ptree dataset_xml; dataset_xml.add_child("NativeDicomModel", nativedicommodel); odil::DataSet const data_set = odil::as_dataset(dataset_xml); BOOST_REQUIRE_EQUAL(data_set.size(), 1); BOOST_REQUIRE(data_set.has("00660023")); BOOST_REQUIRE(data_set.get_vr("00660023") == odil::VR::OW); BOOST_REQUIRE(data_set.is_binary("00660023")); BOOST_REQUIRE(data_set.as_binary("00660023") == odil::Value::Binary( {0x1, 0x2, 0x3, 0x4, 0x5})); } /******************************* TEST Error ************************************/ BOOST_AUTO_TEST_CASE(AsDataSetMissingRootNode) { BOOST_REQUIRE_THROW(odil::as_dataset(boost::property_tree::ptree()), odil::Exception); } /******************************* TEST Error ************************************/ BOOST_AUTO_TEST_CASE(AsDataSetBadDICOMNode) { boost::property_tree::ptree nativedicommodel; nativedicommodel.add_child("BadValue", boost::property_tree::ptree()); boost::property_tree::ptree dataset_xml; dataset_xml.add_child("NativeDicomModel", nativedicommodel); BOOST_REQUIRE_THROW(odil::as_dataset(dataset_xml), odil::Exception); } /******************************* TEST Error ************************************/ BOOST_AUTO_TEST_CASE(AsDataSetBadDicomAttributeSubNode) { // String value BOOST_REQUIRE_THROW(create_dataset_error("00080060", "CS", "Modality", "FOO"), odil::Exception); { // Person Name boost::property_tree::ptree dicomattribute; dicomattribute.put(".vr", "PN"); dicomattribute.put(".tag", "00100010"); dicomattribute.put(".keyword", "PatientName"); boost::property_tree::ptree tag_value; tag_value.put(".number", 1); boost::property_tree::ptree tag_pname; boost::property_tree::ptree tag_family; tag_family.put_value("family"); tag_pname.add_child("FamilyName", tag_family); tag_value.add_child("Alphabetic", tag_pname); dicomattribute.add_child("BadNode", tag_value); boost::property_tree::ptree nativedicommodel; nativedicommodel.add_child("DicomAttribute", dicomattribute); boost::property_tree::ptree dataset_xml; dataset_xml.add_child("NativeDicomModel", nativedicommodel); BOOST_REQUIRE_THROW(odil::as_dataset(dataset_xml), odil::Exception); } // Real value BOOST_REQUIRE_THROW(create_dataset_error( "00089459", "FL", "RecommendedDisplayFrameRateInFloat", 1.2), odil::Exception); // Integer value BOOST_REQUIRE_THROW(create_dataset_error("00280010", "US", "Rows", 1), odil::Exception); { // Sequence boost::property_tree::ptree dicomattribute; dicomattribute.put(".vr", "SQ"); dicomattribute.put(".tag", "00101002"); dicomattribute.put(".keyword", "OtherPatientIDsSequence"); boost::property_tree::ptree tag_value; tag_value.put(".number", 1); dicomattribute.add_child("BadNode", tag_value); boost::property_tree::ptree nativedicommodel; nativedicommodel.add_child("DicomAttribute", dicomattribute); boost::property_tree::ptree dataset_xml; dataset_xml.add_child("NativeDicomModel", nativedicommodel); BOOST_REQUIRE_THROW(odil::as_dataset(dataset_xml), odil::Exception); } // Binary BOOST_REQUIRE_THROW(create_dataset_error( "00660023", "OW", "TrianglePointIndexList", "AQIDBAU="), odil::Exception); } /******************************* TEST Error ************************************/ BOOST_AUTO_TEST_CASE(AsDataSetUnknownVR) { BOOST_REQUIRE_THROW(create_dataset_error("00080060", "UR", "Modality", "FOO"), odil::Exception); } /******************************* TEST Error ************************************/ BOOST_AUTO_TEST_CASE(AsDataSetBadPersonNameSubNode) { boost::property_tree::ptree dicomattribute; dicomattribute.put(".vr", "PN"); dicomattribute.put(".tag", "00100010"); dicomattribute.put(".keyword", "PatientName"); boost::property_tree::ptree tag_value; tag_value.put(".number", 1); boost::property_tree::ptree tag_pname; boost::property_tree::ptree tag_family; tag_family.put_value("family"); tag_pname.add_child("FamilyName", tag_family); tag_value.add_child("BadNode", tag_pname); dicomattribute.add_child("PersonName", tag_value); boost::property_tree::ptree nativedicommodel; nativedicommodel.add_child("DicomAttribute", dicomattribute); boost::property_tree::ptree dataset_xml; dataset_xml.add_child("NativeDicomModel", nativedicommodel); BOOST_REQUIRE_THROW(odil::as_dataset(dataset_xml), odil::Exception); } /******************************* TEST Error ************************************/ BOOST_AUTO_TEST_CASE(AsDataSetBadAlphabeticSubNode) { boost::property_tree::ptree dicomattribute; dicomattribute.put(".vr", "PN"); dicomattribute.put(".tag", "00100010"); dicomattribute.put(".keyword", "PatientName"); boost::property_tree::ptree tag_value; tag_value.put(".number", 1); boost::property_tree::ptree tag_pname; boost::property_tree::ptree tag_family; tag_family.put_value("family"); tag_pname.add_child("BadNode", tag_family); tag_value.add_child("Alphabetic", tag_pname); dicomattribute.add_child("PersonName", tag_value); boost::property_tree::ptree nativedicommodel; nativedicommodel.add_child("DicomAttribute", dicomattribute); boost::property_tree::ptree dataset_xml; dataset_xml.add_child("NativeDicomModel", nativedicommodel); BOOST_REQUIRE_THROW(odil::as_dataset(dataset_xml), odil::Exception); } /******************************* TEST Error ************************************/ BOOST_AUTO_TEST_CASE(AsDataSetTooManyInlineBinaryNode) { boost::property_tree::ptree dicomattribute; dicomattribute.put(".vr", "OW"); dicomattribute.put(".tag", "00660023"); dicomattribute.put(".keyword", "TrianglePointIndexList"); { boost::property_tree::ptree tag_value; tag_value.put_value("AQIDBAU="); dicomattribute.add_child("InlineBinary", tag_value); } { boost::property_tree::ptree tag_value; tag_value.put_value("AQIDBAU="); dicomattribute.add_child("InlineBinary", tag_value); } boost::property_tree::ptree nativedicommodel; nativedicommodel.add_child("DicomAttribute", dicomattribute); boost::property_tree::ptree dataset_xml; dataset_xml.add_child("NativeDicomModel", nativedicommodel); BOOST_REQUIRE_THROW(odil::as_dataset(dataset_xml), odil::Exception); } odil-0.4.1/tests/run.sh000077500000000000000000000016701266460524100147620ustar00rootroot00000000000000#! /bin/sh set -e set -u configure() { cat > ${directory}/config << EOF HostTable BEGIN remote = (REMOTE, localhost, 11112) local = (LOCAL, localhost, 11113) HostTable END AETable BEGIN REMOTE ${directory} RW (10, 1024mb) local AETable END EOF } add_data() { dump2dcm --write-xfer-little /dev/stdin ${directory}/data.dcm < #endif #include "dcmtk/ofstd/ofconapp.h" #include "dcmtk/ofstd/oflist.h" // MODIFICATION: Use local header file #include "scu.h" // END Modification #include "dcmtk/dcmdata/dcuid.h" /* for dcmtk version name */ #include "dcmtk/dcmdata/dcostrmz.h" /* for dcmZlibCompressionLevel */ #include "dcmtk/dcmdata/dcpath.h" /* for DcmPathProcessor */ #ifdef WITH_ZLIB #include /* for zlibVersion() */ #endif #define OFFIS_CONSOLE_APPLICATION "getscu" static OFLogger getscuLogger = OFLog::getLogger("dcmtk.apps." OFFIS_CONSOLE_APPLICATION); static char rcsid[] = "$dcmtk: " OFFIS_CONSOLE_APPLICATION " v" OFFIS_DCMTK_VERSION " " OFFIS_DCMTK_RELEASEDATE " $"; /* default application titles */ #define APPLICATIONTITLE "GETSCU" #define PEERAPPLICATIONTITLE "ANY-SCP" typedef enum { QMPatientRoot = 0, QMStudyRoot = 1, QMPatientStudyOnly = 2 } QueryModel; static const char* querySyntax[3] = { UID_GETPatientRootQueryRetrieveInformationModel, UID_GETStudyRootQueryRetrieveInformationModel, UID_RETIRED_GETPatientStudyOnlyQueryRetrieveInformationModel }; OFCmdUnsignedInt opt_maxPDU = ASC_DEFAULTMAXPDU; E_TransferSyntax opt_store_networkTransferSyntax = EXS_Unknown; E_TransferSyntax opt_get_networkTransferSyntax = EXS_Unknown; DcmStorageMode opt_storageMode = DCMSCU_STORAGE_DISK; OFBool opt_showPresentationContexts = OFFalse; OFBool opt_abortAssociation = OFFalse; OFCmdUnsignedInt opt_repeatCount = 1; QueryModel opt_queryModel = QMPatientRoot; T_DIMSE_BlockingMode opt_blockMode = DIMSE_BLOCKING; int opt_dimse_timeout = 0; int opt_acse_timeout = 30; OFString opt_outputDirectory = "."; static OFList overrideKeys; static void prepareTS(E_TransferSyntax ts, OFList& syntaxes); static void applyOverrideKeys(DcmDataset *dataset); #define SHORTCOL 4 #define LONGCOL 21 int main(int argc, char *argv[]) { const char *opt_peer; OFCmdUnsignedInt opt_port = 104;; const char *opt_peerTitle = PEERAPPLICATIONTITLE; const char *opt_ourTitle = APPLICATIONTITLE; OFList fileNameList; #ifdef HAVE_GUSI_H /* needed for Macintosh */ GUSISetup(GUSIwithSIOUXSockets); GUSISetup(GUSIwithInternetSockets); #endif char tempstr[20]; OFString temp_str; OFConsoleApplication app(OFFIS_CONSOLE_APPLICATION , "DICOM retrieve (C-GET) SCU", rcsid); OFCommandLine cmd; cmd.setParamColumn(LONGCOL + SHORTCOL + 4); cmd.addParam("peer", "hostname of DICOM peer"); cmd.addParam("port", "tcp/ip port number of peer"); cmd.addParam("dcmfile-in", "DICOM query file(s)", OFCmdParam::PM_MultiOptional); cmd.setOptionColumns(LONGCOL, SHORTCOL); cmd.addGroup("general options:", LONGCOL, SHORTCOL + 2); cmd.addOption("--help", "-h", "print this help text and exit", OFCommandLine::AF_Exclusive); cmd.addOption("--version", "print version information and exit", OFCommandLine::AF_Exclusive); OFLog::addOptions(cmd); cmd.addOption("--verbose-pc", "+v", "show presentation contexts in verbose mode"); cmd.addGroup("network options:"); cmd.addSubGroup("override matching keys:"); cmd.addOption("--key", "-k", 1, "[k]ey: gggg,eeee=\"str\", path or dic. name=\"str\"", "override matching key"); cmd.addSubGroup("retrieve information model:"); cmd.addOption("--patient", "-P", "use patient root information model (default)"); cmd.addOption("--study", "-S", "use study root information model"); cmd.addOption("--psonly", "-O", "use patient/study only information model"); cmd.addSubGroup("application entity titles:"); OFString opt1 = "set my calling AE title (default: "; opt1 += APPLICATIONTITLE; opt1 += ")"; cmd.addOption("--aetitle", "-aet", 1, "[a]etitle: string", opt1.c_str()); OFString opt2 = "set called AE title of peer (default: "; opt2 += PEERAPPLICATIONTITLE; opt2 += ")"; cmd.addOption("--call", "-aec", 1, "[a]etitle: string", opt2.c_str()); cmd.addSubGroup("preferred storage transfer syntaxes (incoming associations):"); cmd.addOption("--prefer-uncompr", "+x=", "prefer explicit VR local byte order (default)"); cmd.addOption("--prefer-little", "+xe", "prefer explicit VR little endian TS"); cmd.addOption("--prefer-big", "+xb", "prefer explicit VR big endian TS"); cmd.addOption("--prefer-lossless", "+xs", "prefer default JPEG lossless TS"); cmd.addOption("--prefer-jpeg8", "+xy", "prefer default JPEG lossy TS for 8 bit data"); cmd.addOption("--prefer-jpeg12", "+xx", "prefer default JPEG lossy TS for 12 bit data"); cmd.addOption("--prefer-j2k-lossless", "+xv", "prefer JPEG 2000 lossless TS"); cmd.addOption("--prefer-j2k-lossy", "+xw", "prefer JPEG 2000 lossy TS"); cmd.addOption("--prefer-jls-lossless", "+xt", "prefer JPEG-LS lossless TS"); cmd.addOption("--prefer-jls-lossy", "+xu", "prefer JPEG-LS lossy TS"); cmd.addOption("--prefer-mpeg2", "+xm", "prefer MPEG2 Main Profile @ Main Level TS"); cmd.addOption("--prefer-mpeg2-high", "+xh", "prefer MPEG2 Main Profile @ High Level TS"); cmd.addOption("--prefer-mpeg4", "+xn", "prefer MPEG4 AVC/H.264 HP / Level 4.1 TS"); cmd.addOption("--prefer-mpeg4-bd", "+xl", "prefer MPEG4 AVC/H.264 BD-compatible TS"); cmd.addOption("--prefer-rle", "+xr", "prefer RLE lossless TS"); #ifdef WITH_ZLIB cmd.addOption("--prefer-deflated", "+xd", "prefer deflated explicit VR little endian TS"); #endif cmd.addOption("--implicit", "+xi", "accept implicit VR little endian TS only"); cmd.addSubGroup("proposed retrieve transfer syntaxes (outgoing associations):"); cmd.addOption("--propose-uncompr", "-x=", "propose all uncompressed TS, explicit VR\nwith local byte ordering first (default)"); cmd.addOption("--propose-little", "-xe", "propose all uncompressed TS, explicit VR\nlittle endian first"); cmd.addOption("--propose-big", "-xb", "propose all uncompressed TS, explicit VR\nbig endian first"); #ifdef WITH_ZLIB cmd.addOption("--propose-deflated", "-xd", "propose deflated explicit VR little endian TS\nand all uncompressed transfer syntaxes"); #endif cmd.addOption("--propose-implicit", "-xi", "propose implicit VR little endian TS only"); cmd.addSubGroup("other network options:"); cmd.addOption("--timeout", "-to", 1, "[s]econds: integer (default: unlimited)", "timeout for connection requests"); cmd.addOption("--acse-timeout", "-ta", 1, "[s]econds: integer (default: 30)", "timeout for ACSE messages"); cmd.addOption("--dimse-timeout", "-td", 1, "[s]econds: integer (default: unlimited)", "timeout for DIMSE messages"); OFString opt3 = "set max receive pdu to n bytes (default: "; sprintf(tempstr, "%ld", OFstatic_cast(long, ASC_DEFAULTMAXPDU)); opt3 += tempstr; opt3 += ")"; OFString opt4 = "[n]umber of bytes: integer ("; sprintf(tempstr, "%ld", OFstatic_cast(long, ASC_MINIMUMPDUSIZE)); opt4 += tempstr; opt4 += ".."; sprintf(tempstr, "%ld", OFstatic_cast(long, ASC_MAXIMUMPDUSIZE)); opt4 += tempstr; opt4 += ")"; cmd.addOption("--max-pdu", "-pdu", 1, opt4.c_str(), opt3.c_str()); cmd.addOption("--repeat", 1, "[n]umber: integer", "repeat n times"); cmd.addOption("--abort", "abort association instead of releasing it"); cmd.addGroup("output options:"); cmd.addSubGroup("general:"); cmd.addOption("--output-directory", "-od", 1, "[d]irectory: string (default: \".\")", "write received objects to existing directory d"); cmd.addSubGroup("storage mode:"); cmd.addOption("--normal", "-B", "receive in memory, then write to disk (default)"); cmd.addOption("--bit-preserving", "+B", "receive directly to disk"); cmd.addOption("--ignore", "ignore store data, receive but do not store"); /* evaluate command line */ prepareCmdLineArgs(argc, argv, OFFIS_CONSOLE_APPLICATION); if (!app.parseCommandLine(cmd, argc, argv, OFCommandLine::PF_ExpandWildcards)) { exit(1); } /* check exclusive options first */ if (cmd.hasExclusiveOption()) { if (cmd.findOption("--version")) { app.printHeader(OFTrue /*print host identifier*/); COUT << OFendl << "External libraries used:"; #ifdef WITH_ZLIB COUT << OFendl << "- ZLIB, Version " << zlibVersion() << OFendl; #else COUT << " none" << OFendl; #endif return 0; } } /* command line parameters */ cmd.getParam(1, opt_peer); app.checkParam(cmd.getParamAndCheckMinMax(2, opt_port, 1, 65535)); OFLog::configureFromCommandLine(cmd, app); if (cmd.findOption("--verbose-pc")) { app.checkDependence("--verbose-pc", "verbose mode", getscuLogger.isEnabledFor(OFLogger::INFO_LOG_LEVEL)); opt_showPresentationContexts = OFTrue; } if (cmd.findOption("--key", 0, OFCommandLine::FOM_FirstFromLeft)) { const char *ovKey = NULL; do { app.checkValue(cmd.getValue(ovKey)); overrideKeys.push_back(ovKey); } while (cmd.findOption("--key", 0, OFCommandLine::FOM_NextFromLeft)); } cmd.beginOptionBlock(); if (cmd.findOption("--patient")) opt_queryModel = QMPatientRoot; if (cmd.findOption("--study")) opt_queryModel = QMStudyRoot; if (cmd.findOption("--psonly")) opt_queryModel = QMPatientStudyOnly; cmd.endOptionBlock(); if (cmd.findOption("--aetitle")) app.checkValue(cmd.getValue(opt_ourTitle)); if (cmd.findOption("--call")) app.checkValue(cmd.getValue(opt_peerTitle)); cmd.beginOptionBlock(); if (cmd.findOption("--prefer-uncompr")) { opt_store_networkTransferSyntax = EXS_Unknown; } // MODIFICATION: Comment undefined TransferSyntax if (cmd.findOption("--prefer-little")) opt_store_networkTransferSyntax = EXS_LittleEndianExplicit; if (cmd.findOption("--prefer-big")) opt_store_networkTransferSyntax = EXS_BigEndianExplicit; // if (cmd.findOption("--prefer-lossless")) opt_store_networkTransferSyntax = EXS_JPEGProcess14SV1; // if (cmd.findOption("--prefer-jpeg8")) opt_store_networkTransferSyntax = EXS_JPEGProcess1; // if (cmd.findOption("--prefer-jpeg12")) opt_store_networkTransferSyntax = EXS_JPEGProcess2_4; if (cmd.findOption("--prefer-j2k-lossless")) opt_store_networkTransferSyntax = EXS_JPEG2000LosslessOnly; if (cmd.findOption("--prefer-j2k-lossy")) opt_store_networkTransferSyntax = EXS_JPEG2000; if (cmd.findOption("--prefer-jls-lossless")) opt_store_networkTransferSyntax = EXS_JPEGLSLossless; if (cmd.findOption("--prefer-jls-lossy")) opt_store_networkTransferSyntax = EXS_JPEGLSLossy; if (cmd.findOption("--prefer-mpeg2")) opt_store_networkTransferSyntax = EXS_MPEG2MainProfileAtMainLevel; if (cmd.findOption("--prefer-mpeg2-high")) opt_store_networkTransferSyntax = EXS_MPEG2MainProfileAtHighLevel; // if (cmd.findOption("--prefer-mpeg4")) opt_store_networkTransferSyntax = EXS_MPEG4HighProfileLevel4_1; // if (cmd.findOption("--prefer-mpeg4-bd")) opt_store_networkTransferSyntax = EXS_MPEG4BDcompatibleHighProfileLevel4_1; if (cmd.findOption("--prefer-rle")) opt_store_networkTransferSyntax = EXS_RLELossless; // END Modification #ifdef WITH_ZLIB if (cmd.findOption("--prefer-deflated")) opt_store_networkTransferSyntax = EXS_DeflatedLittleEndianExplicit; #endif if (cmd.findOption("--implicit")) opt_store_networkTransferSyntax = EXS_LittleEndianImplicit; cmd.endOptionBlock(); cmd.beginOptionBlock(); if (cmd.findOption("--propose-uncompr")) opt_get_networkTransferSyntax = EXS_Unknown; if (cmd.findOption("--propose-little")) opt_get_networkTransferSyntax = EXS_LittleEndianExplicit; if (cmd.findOption("--propose-big")) opt_get_networkTransferSyntax = EXS_BigEndianExplicit; if (cmd.findOption("--propose-implicit")) opt_get_networkTransferSyntax = EXS_LittleEndianImplicit; #ifdef WITH_ZLIB if (cmd.findOption("--propose-deflated")) opt_get_networkTransferSyntax = EXS_DeflatedLittleEndianExplicit; #endif cmd.endOptionBlock(); if (cmd.findOption("--timeout")) { OFCmdSignedInt opt_timeout = 0; app.checkValue(cmd.getValueAndCheckMin(opt_timeout, 1)); dcmConnectionTimeout.set(OFstatic_cast(Sint32, opt_timeout)); } if (cmd.findOption("--acse-timeout")) { OFCmdSignedInt opt_timeout = 0; app.checkValue(cmd.getValueAndCheckMin(opt_timeout, 1)); opt_acse_timeout = OFstatic_cast(int, opt_timeout); } if (cmd.findOption("--dimse-timeout")) { OFCmdSignedInt opt_timeout = 0; app.checkValue(cmd.getValueAndCheckMin(opt_timeout, 1)); opt_dimse_timeout = OFstatic_cast(int, opt_timeout); opt_blockMode = DIMSE_NONBLOCKING; } if (cmd.findOption("--max-pdu")) app.checkValue(cmd.getValueAndCheckMinMax(opt_maxPDU, ASC_MINIMUMPDUSIZE, ASC_MAXIMUMPDUSIZE)); if (cmd.findOption("--repeat")) app.checkValue(cmd.getValueAndCheckMin(opt_repeatCount, 1)); if (cmd.findOption("--abort")) opt_abortAssociation = OFTrue; if (cmd.findOption("--ignore")) opt_storageMode = DCMSCU_STORAGE_IGNORE; if (cmd.findOption("--output-directory")) { app.checkValue(cmd.getValue(opt_outputDirectory)); app.checkConflict("--output-directory", "--ignore", opt_storageMode == DCMSCU_STORAGE_IGNORE); } cmd.beginOptionBlock(); if (cmd.findOption("--bit-preserving")) { app.checkConflict("--bit-preserving", "--ignore", opt_storageMode == DCMSCU_STORAGE_IGNORE); opt_storageMode = DCMSCU_STORAGE_BIT_PRESERVING; } if (cmd.findOption("--normal")) { app.checkConflict("--normal", "--bit-preserving", opt_storageMode == DCMSCU_STORAGE_BIT_PRESERVING); app.checkConflict("--normal", "--ignore", opt_storageMode == DCMSCU_STORAGE_IGNORE); opt_storageMode = DCMSCU_STORAGE_DISK; } cmd.endOptionBlock(); /* finally parse filenames */ int paramCount = cmd.getParamCount(); const char *currentFilename = NULL; OFString errormsg; for (int i=3; i <= paramCount; i++) { cmd.getParam(i, currentFilename); if (access(currentFilename, R_OK) < 0) { errormsg = "cannot access file: "; errormsg += currentFilename; app.printError(errormsg.c_str()); } fileNameList.push_back(currentFilename); } if (fileNameList.empty() && overrideKeys.empty()) { app.printError("either query file or override keys (or both) must be specified"); } /* print resource identifier */ OFLOG_DEBUG(getscuLogger, rcsid << OFendl); /* make sure data dictionary is loaded */ if (!dcmDataDict.isDictionaryLoaded()) { OFLOG_WARN(getscuLogger, "no data dictionary loaded, check environment variable: " << DCM_DICT_ENVIRONMENT_VARIABLE); } /* make sure output directory exists and is writeable */ if (!OFStandard::dirExists(opt_outputDirectory)) { OFLOG_FATAL(getscuLogger, "specified output directory does not exist"); return 1; } else if (!OFStandard::isWriteable(opt_outputDirectory)) { OFLOG_FATAL(getscuLogger, "specified output directory is not writeable"); return 1; } // Setup SCU OFList syntaxes; prepareTS(opt_get_networkTransferSyntax, syntaxes); DcmSCU scu; scu.setMaxReceivePDULength(opt_maxPDU); scu.setACSETimeout(opt_acse_timeout); scu.setDIMSEBlockingMode(opt_blockMode); scu.setDIMSETimeout(opt_dimse_timeout); scu.setAETitle(opt_ourTitle); scu.setPeerHostName(opt_peer); scu.setPeerPort(OFstatic_cast(Uint16, opt_port)); scu.setPeerAETitle(opt_peerTitle); scu.setVerbosePCMode(opt_showPresentationContexts); // Add presentation contexts for get and find (we do not actually need find...) // (only uncompressed) scu.addPresentationContext(querySyntax[opt_queryModel], syntaxes); // Add storage presentation contexts (long list of storage SOP classes, uncompressed) syntaxes.clear(); prepareTS(opt_store_networkTransferSyntax, syntaxes); for (Uint16 j = 0; j < numberOfDcmLongSCUStorageSOPClassUIDs; j++) { scu.addPresentationContext(dcmLongSCUStorageSOPClassUIDs[j], syntaxes, ASC_SC_ROLE_SCP); } // Set the storage mode scu.setStorageMode(opt_storageMode); if (opt_storageMode != DCMSCU_STORAGE_IGNORE) { scu.setStorageDir(opt_outputDirectory); } // Initialize network and negotiate association OFCondition cond = scu.initNetwork(); if (cond.bad()) { OFLOG_FATAL(getscuLogger, DimseCondition::dump(temp_str, cond)); exit(1); } cond = scu.negotiateAssociation(); if (cond.bad()) { OFLOG_FATAL(getscuLogger, "No Acceptable Presentation Contexts"); exit(1); } cond = EC_Normal; T_ASC_PresentationContextID pcid = scu.findPresentationContextID(querySyntax[opt_queryModel], ""); if (pcid == 0) { OFLOG_FATAL(getscuLogger, "No adequate Presentation Contexts for sending C-GET"); exit(1); } /* Do the real work, i.e. send C-GET requests and receive objects */ for (Uint16 repeat = 0; repeat < opt_repeatCount; repeat++) { Uint16 numRuns = 1; DcmFileFormat dcmff; DcmDataset *dset = dcmff.getDataset(); OFListConstIterator(OFString) it; /* Load first file, if there is one */ if (!fileNameList.empty()) { numRuns = fileNameList.size(); it = fileNameList.begin(); cond = dcmff.loadFile((*it).c_str()); if (cond.bad()) { OFLOG_FATAL(getscuLogger, DimseCondition::dump(temp_str, cond)); exit(1); } dset = dcmff.getDataset(); } OFList responses; /* For all files (or at least one run from override keys) */ for (Uint16 i = 0; i < numRuns; i++) { applyOverrideKeys(dset); cond = scu.sendCGETRequest(pcid, dset, &responses); if (cond.bad()) { exit(1); } /* Load next file if there is one */ if (numRuns > 1) { it++; cond = dcmff.loadFile((*it).c_str()); if (cond.bad()) { OFLOG_FATAL(getscuLogger, DimseCondition::dump(temp_str, cond)); exit(1); } dset = dcmff.getDataset(); } } if (!responses.empty()) { /* Output final status report */ OFLOG_INFO(getscuLogger, "Final status report from last C-GET message:"); (*(--responses.end()))->print(); /* Delete responses */ OFListIterator(RetrieveResponse*) iter = responses.begin(); OFListConstIterator(RetrieveResponse*) last = responses.end(); while (iter != last) { delete (*iter); iter = responses.erase(iter); } } } /* tear down association */ if (cond == EC_Normal) { if (opt_abortAssociation) { OFLOG_INFO(getscuLogger, "Aborting Association"); scu.closeAssociation(DCMSCU_ABORT_ASSOCIATION); exit(0); } else { /* release association */ scu.closeAssociation(DCMSCU_RELEASE_ASSOCIATION); exit(0); } } else if (cond == DUL_PEERREQUESTEDRELEASE) { OFLOG_ERROR(getscuLogger, "Protocol Error: Peer requested release (Aborting)"); scu.closeAssociation(DCMSCU_ABORT_ASSOCIATION); exit(1); } else if (cond == DUL_PEERABORTEDASSOCIATION) { OFLOG_INFO(getscuLogger, "Peer Aborted Association"); } else { OFLOG_ERROR(getscuLogger, "GET SCU Failed: " << DimseCondition::dump(temp_str, cond)); OFLOG_INFO(getscuLogger, "Aborting Association"); scu.closeAssociation(DCMSCU_ABORT_ASSOCIATION); exit(1); } #ifdef HAVE_WINSOCK_H WSACleanup(); #endif return 0; } static void applyOverrideKeys(DcmDataset *dataset) { /* replace specific keys by those in overrideKeys */ OFListConstIterator(OFString) path = overrideKeys.begin(); OFListConstIterator(OFString) endOfList = overrideKeys.end(); DcmPathProcessor proc; proc.setItemWildcardSupport(OFFalse); proc.checkPrivateReservations(OFFalse); OFCondition cond; while (path != endOfList) { cond = proc.applyPathWithValue(dataset, *path); if (cond.bad()) { OFLOG_ERROR(getscuLogger, "Bad override key/path: " << *path << ": " << cond.text()); } path++; } } static void prepareTS(E_TransferSyntax ts, OFList& syntaxes) { /* ** We prefer to use Explicitly encoded transfer syntaxes. ** If we are running on a Little Endian machine we prefer ** LittleEndianExplicitTransferSyntax to BigEndianTransferSyntax. ** Some SCP implementations will just select the first transfer ** syntax they support (this is not part of the standard) so ** organise the proposed transfer syntaxes to take advantage ** of such behaviour. ** ** The presentation contexts proposed here are only used for ** C-FIND and C-MOVE, so there is no need to support compressed ** transmission. */ switch (ts) { case EXS_LittleEndianImplicit: /* we only support Little Endian Implicit */ syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax); break; case EXS_LittleEndianExplicit: /* we prefer Little Endian Explicit */ syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax); syntaxes.push_back(UID_BigEndianExplicitTransferSyntax); syntaxes.push_back(UID_LittleEndianImplicitTransferSyntax); break; case EXS_BigEndianExplicit: /* we prefer Big Endian Explicit */ syntaxes.push_back(UID_BigEndianExplicitTransferSyntax); syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax); syntaxes.push_back(UID_LittleEndianImplicitTransferSyntax); break; #ifdef WITH_ZLIB case EXS_DeflatedLittleEndianExplicit: /* we prefer Deflated Little Endian Explicit */ syntaxes.push_back(UID_DeflatedExplicitVRLittleEndianTransferSyntax); syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax); syntaxes.push_back(UID_BigEndianExplicitTransferSyntax); syntaxes.push_back(UID_LittleEndianImplicitTransferSyntax); break; #endif default: DcmXfer xfer(ts); if (xfer.isEncapsulated()) { syntaxes.push_back(xfer.getXferID()); } /* We prefer explicit transfer syntaxes. * If we are running on a Little Endian machine we prefer * LittleEndianExplicitTransferSyntax to BigEndianTransferSyntax. */ if (gLocalByteOrder == EBO_LittleEndian) /* defined in dcxfer.h */ { syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax); syntaxes.push_back(UID_BigEndianExplicitTransferSyntax); } else { syntaxes.push_back(UID_BigEndianExplicitTransferSyntax); syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax); } syntaxes.push_back(UID_LittleEndianImplicitTransferSyntax); break; } } /* ** CVS Log ** $Log: getscu.cc,v $ ** Revision 1.10 2012-02-10 14:54:38 onken ** Removed duplicate log message when closing an association. ** ** Revision 1.9 2011-12-16 16:36:44 meichel ** Minor changes for MSVC6 compatibility ** ** Revision 1.8 2011-09-26 08:13:53 joergr ** Moved --verbose-pc option to the end of the "general options" section. ** ** Revision 1.7 2011-09-21 12:57:47 joergr ** Removed TCP wrapper support (libwrap) which is not really useful for an SCU. ** ** Revision 1.6 2011-09-21 11:06:28 joergr ** Removed option --disable-host-lookup which is not really useful for an SCU. ** ** Revision 1.5 2011-09-09 08:58:11 joergr ** Replaced local list of supported storage SOP classes by the global variable ** dcmLongSCUStorageSOPClassUIDs, which is maintained at a central location. ** ** Revision 1.4 2011-09-07 12:40:45 joergr ** Made more clear that option --key also supports path expressions. ** ** Revision 1.3 2011-08-25 15:05:04 joergr ** Changed data structure for Q/R responses from OFVector to OFList. Also fixed ** some possible memory leaks and made the FIND/MOVE/GET code more consistent. ** ** Revision 1.2 2011-08-25 12:51:22 joergr ** Added "verbose-pc" mode that shows the presentation contexts in verbose mode. ** ** Revision 1.1 2011-08-25 09:31:32 onken ** Added C-GET functionality to DcmSCU class and accompanying getscu ** commandline application. ** */ odil-0.4.1/tests/tools/scu.cc000066400000000000000000002675601266460524100160740ustar00rootroot00000000000000/* * * Copyright (C) 2008-2012, OFFIS e.V. * All rights reserved. See COPYRIGHT file for details. * * This software and supporting documentation were developed by * * OFFIS e.V. * R&D Division Health * Escherweg 2 * D-26121 Oldenburg, Germany * * * Module: dcmnet * * Author: Michael Onken * * Purpose: Base class for Service Class Users (SCUs) * * Last Update: $Author: onken $ * Update Date: $Date: 2012-05-14 10:42:54 $ * CVS/RCS Revision: $Revision: 1.60 $ * Status: $State: Exp $ * * CVS/RCS Log at end of file * */ #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ // MODIFICATION: Take the local scu.h #include "scu.h" // END Modification #include "dcmtk/dcmnet/diutil.h" /* for dcmnet logger */ #include "dcmtk/dcmdata/dcuid.h" /* for dcmFindUIDName() */ #include "dcmtk/dcmdata/dcostrmf.h" /* for class DcmOutputFileStream */ #ifdef WITH_ZLIB #include /* for zlibVersion() */ #endif #if OFFIS_DCMTK_VERSION_NUMBER <= 360 // MODIFICATION: Add missing Errors const OFConditionConst NET_EC_InvalidSOPClassUID(OFM_dcmnet, 1000, OF_error, "Invalid SOP Class UID"); const OFConditionConst NET_EC_UnknownStorageSOPClass(OFM_dcmnet, 1001, OF_error, "Unknown Storage SOP Class"); const OFConditionConst NET_EC_InvalidSOPInstanceUID(OFM_dcmnet, 1002, OF_error, "Invalid SOP Instance UID"); const OFConditionConst NET_EC_InvalidTransferSyntaxUID(OFM_dcmnet, 1003, OF_error, "Invalid Transfer Syntax UID"); const OFConditionConst NET_EC_UnknownTransferSyntax(OFM_dcmnet, 1004, OF_error, "Unknown Transfer Syntax"); const OFConditionConst NET_EC_NoPresentationContextsDefined(OFM_dcmnet, 1005, OF_error, "No Presentation Contexts defined"); const OFConditionConst NET_EC_NoAcceptablePresentationContexts(OFM_dcmnet, 1006, OF_error, "No acceptable Presentation Contexts"); const OFConditionConst NET_EC_NoSOPInstancesToSend(OFM_dcmnet, 1007, OF_error, "No SOP instances to send"); const OFConditionConst NET_EC_NoSuchSOPInstance(OFM_dcmnet, 1008, OF_error, "No such SOP instance"); const OFConditionConst NET_EC_InvalidDatasetPointer(OFM_dcmnet, 1009, OF_error, "Invalid dataset pointer"); const OFConditionConst NET_EC_AlreadyConnected(OFM_dcmnet, 1010, OF_error, "Already connected"); const OFConditionConst NET_EC_InsufficientPortPrivileges(OFM_dcmnet, 1023, OF_error, "Insufficient port privileges"); // END Modification #endif DcmSCU::DcmSCU() : m_assoc(NULL), m_net(NULL), m_params(NULL), m_assocConfigFilename(), m_assocConfigProfile(), m_presContexts(), m_assocConfigFile(), m_openDIMSERequest(NULL), m_maxReceivePDULength(ASC_DEFAULTMAXPDU), m_blockMode(DIMSE_BLOCKING), m_ourAETitle("ANY-SCU"), m_peer(), m_peerAETitle("ANY-SCP"), m_peerPort(104), m_dimseTimeout(0), m_acseTimeout(30), m_storageDir(), m_storageMode(DCMSCU_STORAGE_DISK), m_verbosePCMode(OFFalse), m_datasetConversionMode(OFFalse), m_progressNotificationMode(OFTrue) { #ifdef HAVE_GUSI_H GUSISetup(GUSIwithSIOUXSockets); GUSISetup(GUSIwithInternetSockets); #endif #ifdef HAVE_WINSOCK_H WSAData winSockData; /* we need at least version 1.1 */ WORD winSockVersionNeeded = MAKEWORD( 1, 1 ); WSAStartup(winSockVersionNeeded, &winSockData); // TODO: check with multiple SCU instances whether this is harmful #endif } void DcmSCU::freeNetwork() { if ((m_assoc != NULL) || (m_net != NULL) || (m_params != NULL)) DCMNET_DEBUG("Cleaning up internal association and network structures"); /* destroy association parameters, i.e. free memory of T_ASC_Parameters. Usually this is done in ASC_destroyAssociation; however, if we already have association parameters but not yet an association (e.g. after calling initNetwork() and negotiateAssociation()), the latter approach may fail. */ if (m_params) { ASC_destroyAssociationParameters(&m_params); m_params = NULL; // make sure destroyAssocation does not try to free params a second time // (happens in case we have already have an association structure) if (m_assoc) m_assoc->params = NULL; } // destroy the association, i.e. free memory of T_ASC_Association* structure. ASC_destroyAssociation(&m_assoc); // drop the network, i.e. free memory of T_ASC_Network* structure. ASC_dropNetwork(&m_net); // Cleanup old DIMSE request if any delete m_openDIMSERequest; m_openDIMSERequest = NULL; } DcmSCU::~DcmSCU() { // abort association (if any) and destroy dcmnet data structures if (isConnected()) { closeAssociation(DCMSCU_ABORT_ASSOCIATION); // also frees network } else { freeNetwork(); } #ifdef HAVE_WINSOCK_H WSACleanup(); // TODO: check with multiple SCU instances whether this is harmful #endif } OFCondition DcmSCU::initNetwork() { /* Return if SCU is already connected */ if (isConnected()) return NET_EC_AlreadyConnected; /* Be sure internal network structures are clean (delete old) */ freeNetwork(); OFString tempStr; /* initialize network, i.e. create an instance of T_ASC_Network*. */ OFCondition cond = ASC_initializeNetwork(NET_REQUESTOR, 0, m_acseTimeout, &m_net); if (cond.bad()) { DimseCondition::dump(tempStr, cond); DCMNET_ERROR(tempStr); return cond; } /* initialize asscociation parameters, i.e. create an instance of T_ASC_Parameters*. */ cond = ASC_createAssociationParameters(&m_params, m_maxReceivePDULength); if (cond.bad()) { DCMNET_ERROR(DimseCondition::dump(tempStr, cond)); return cond; } /* sets this application's title and the called application's title in the params */ /* structure. The default values are "ANY-SCU" and "ANY-SCP". */ ASC_setAPTitles(m_params, m_ourAETitle.c_str(), m_peerAETitle.c_str(), NULL); /* Figure out the presentation addresses and copy the */ /* corresponding values into the association parameters.*/ DIC_NODENAME localHost; DIC_NODENAME peerHost; gethostname(localHost, sizeof(localHost) - 1); /* Since the underlying dcmnet structures reserve only 64 bytes for peer as well as local host name, we check here for buffer overflow. */ if ((m_peer.length() + 5 /* max 65535 */) + 1 /* for ":" */ > 63) { DCMNET_ERROR("Maximum length of peer host name '" << m_peer << "' is longer than maximum of 57 characters"); return EC_IllegalCall; // TODO: need to find better error code } if (strlen(localHost) + 1 > 63) { DCMNET_ERROR("Maximum length of local host name '" << localHost << "' is longer than maximum of 62 characters"); return EC_IllegalCall; // TODO: need to find better error code } sprintf(peerHost, "%s:%d", m_peer.c_str(), OFstatic_cast(int, m_peerPort)); ASC_setPresentationAddresses(m_params, localHost, peerHost); /* Add presentation contexts */ // First, import from config file, if specified OFCondition result; if (!m_assocConfigFilename.empty()) { DcmAssociationConfiguration assocConfig; result = DcmAssociationConfigurationFile::initialize(assocConfig, m_assocConfigFilename.c_str()); if (result.bad()) { DCMNET_WARN("Unable to parse association configuration file " << m_assocConfigFilename << " (ignored): " << result.text()); return result; } else { /* perform name mangling for config file key */ OFString profileName; const unsigned char *c = OFreinterpret_cast(const unsigned char *, m_assocConfigProfile.c_str()); while (*c) { if (! isspace(*c)) profileName += OFstatic_cast(char, toupper(*c)); ++c; } result = assocConfig.setAssociationParameters(profileName.c_str(), *m_params); if (result.bad()) { DCMNET_WARN("Unable to apply association configuration file " << m_assocConfigFilename <<" (ignored): " << result.text()); return result; } } } // Adapt presentation context ID to existing presentation contexts. // It's important that presentation context IDs are numerated 1,3,5,7...! Uint32 nextFreePresID = 257; Uint32 numContexts = ASC_countPresentationContexts(m_params); if (numContexts <= 127) { // Need Uint16 to avoid overflow in currPresID (unsigned char) nextFreePresID = 2 * numContexts + 1; /* add 1 to point to the next free ID*/ } // Print warning if number of overall presentation contexts exceeds 128 if ((numContexts + m_presContexts.size()) > 128) { DCMNET_WARN("Number of presentation contexts exceeds 128 (" << numContexts + m_presContexts.size() << "). Some contexts will not be negotiated"); } else { DCMNET_TRACE("Configured " << numContexts << " presentation contexts from config file"); if (m_presContexts.size() > 0) DCMNET_TRACE("Adding another " << m_presContexts.size() << " presentation contexts configured for SCU"); } // Add presentation contexts not originating from config file OFListIterator(DcmSCUPresContext) contIt = m_presContexts.begin(); OFListConstIterator(DcmSCUPresContext) endOfContList = m_presContexts.end(); while ((contIt != endOfContList) && (nextFreePresID <= 255)) { const Uint16 numTransferSyntaxes = OFstatic_cast(Uint16, (*contIt).transferSyntaxes.size()); const char** transferSyntaxes = new const char*[numTransferSyntaxes]; // Iterate over transfer syntaxes within one presentation context OFListIterator(OFString) syntaxIt = (*contIt).transferSyntaxes.begin(); OFListIterator(OFString) endOfSyntaxList = (*contIt).transferSyntaxes.end(); Uint16 sNum = 0; // copy all transfer syntaxes to array while (syntaxIt != endOfSyntaxList) { transferSyntaxes[sNum] = (*syntaxIt).c_str(); ++syntaxIt; ++sNum; } // add the presentation context cond = ASC_addPresentationContext(m_params, OFstatic_cast(Uint8, nextFreePresID), (*contIt).abstractSyntaxName.c_str(), transferSyntaxes, numTransferSyntaxes,(*contIt).roleSelect); // if adding was successfull, prepare presentation context ID for next addition delete[] transferSyntaxes; transferSyntaxes = NULL; if (cond.bad()) return cond; contIt++; // goto next free number, only odd presentation context IDs permitted nextFreePresID += 2; } numContexts = ASC_countPresentationContexts(m_params); if (numContexts == 0) { DCMNET_ERROR("Cannot initialize network: No presentation contexts defined"); return NET_EC_NoPresentationContextsDefined; } DCMNET_DEBUG("Configured a total of " << numContexts << " presentation contexts for SCU"); return cond; } OFCondition DcmSCU::negotiateAssociation() { /* Return error if SCU is already connected */ if (isConnected()) return NET_EC_AlreadyConnected; /* dump presentation contexts if required */ OFString tempStr; if (m_verbosePCMode) DCMNET_INFO("Request Parameters:" << OFendl << ASC_dumpParameters(tempStr, m_params, ASC_ASSOC_RQ)); else DCMNET_DEBUG("Request Parameters:" << OFendl << ASC_dumpParameters(tempStr, m_params, ASC_ASSOC_RQ)); /* create association, i.e. try to establish a network connection to another */ /* DICOM application. This call creates an instance of T_ASC_Association*. */ DCMNET_INFO("Requesting Association"); OFCondition cond = ASC_requestAssociation(m_net, m_params, &m_assoc); if (cond.bad()) { if (cond == DUL_ASSOCIATIONREJECTED) { T_ASC_RejectParameters rej; ASC_getRejectParameters(m_params, &rej); DCMNET_DEBUG("Association Rejected:" << OFendl << ASC_printRejectParameters(tempStr, &rej)); return cond; } else { DCMNET_DEBUG("Association Request Failed: " << DimseCondition::dump(tempStr, cond)); return cond; } } /* dump the presentation contexts which have been accepted/refused */ if (m_verbosePCMode) DCMNET_INFO("Association Parameters Negotiated:" << OFendl << ASC_dumpParameters(tempStr, m_params, ASC_ASSOC_AC)); else DCMNET_DEBUG("Association Parameters Negotiated:" << OFendl << ASC_dumpParameters(tempStr, m_params, ASC_ASSOC_AC)); /* count the presentation contexts which have been accepted by the SCP */ /* If there are none, finish the execution */ if (ASC_countAcceptedPresentationContexts(m_params) == 0) { DCMNET_ERROR("No Acceptable Presentation Contexts"); return NET_EC_NoAcceptablePresentationContexts; } /* dump general information concerning the establishment of the network connection if required */ DCMNET_INFO("Association Accepted (Max Send PDV: " << OFstatic_cast(unsigned long, m_assoc->sendPDVLength) << ")"); return EC_Normal; } OFCondition DcmSCU::addPresentationContext(const OFString &abstractSyntax, const OFList &xferSyntaxes, const T_ASC_SC_ROLE role) { DcmSCUPresContext presContext; presContext.abstractSyntaxName = abstractSyntax; OFListConstIterator(OFString) it = xferSyntaxes.begin(); OFListConstIterator(OFString) endOfList = xferSyntaxes.end(); while (it != endOfList) { presContext.transferSyntaxes.push_back(*it); it++; } presContext.roleSelect = role; m_presContexts.push_back(presContext); return EC_Normal; } OFCondition DcmSCU::useSecureConnection(DcmTransportLayer *tlayer) { OFCondition cond = ASC_setTransportLayer(m_net, tlayer, OFFalse /* do not take over ownership */); if (cond.good()) cond = ASC_setTransportLayerType(m_params, OFTrue /* use TLS */); return cond; } void DcmSCU::clearPresentationContexts() { m_presContexts.clear(); m_assocConfigFilename.clear(); m_assocConfigProfile.clear(); } // Returns usable presentation context ID for a given abstract syntax UID and // transfer syntax UID. 0 if none matches. T_ASC_PresentationContextID DcmSCU::findPresentationContextID(const OFString &abstractSyntax, const OFString &transferSyntax) { if (!isConnected()) return 0; DUL_PRESENTATIONCONTEXT *pc; LST_HEAD **l; OFBool found = OFFalse; if (abstractSyntax.empty()) return 0; /* first of all we look for a presentation context * matching both abstract and transfer syntax */ l = &m_assoc->params->DULparams.acceptedPresentationContext; pc = (DUL_PRESENTATIONCONTEXT*) LST_Head(l); (void)LST_Position(l, (LST_NODE*)pc); while (pc && !found) { found = (strcmp(pc->abstractSyntax, abstractSyntax.c_str()) == 0); found &= (pc->result == ASC_P_ACCEPTANCE); if (!transferSyntax.empty()) // ignore transfer syntax if not specified found &= (strcmp(pc->acceptedTransferSyntax, transferSyntax.c_str()) == 0); if (!found) pc = (DUL_PRESENTATIONCONTEXT*) LST_Next(l); } if (found) return pc->presentationContextID; return 0; /* not found */ } // Returns the presentation context ID that best matches the given abstract syntax UID and // transfer syntax UID. T_ASC_PresentationContextID DcmSCU::findAnyPresentationContextID(const OFString &abstractSyntax, const OFString &transferSyntax) { if (m_assoc == NULL) return 0; DUL_PRESENTATIONCONTEXT *pc; LST_HEAD **l; OFBool found = OFFalse; if (abstractSyntax.empty()) return 0; /* first of all we look for a presentation context * matching both abstract and transfer syntax */ l = &m_assoc->params->DULparams.acceptedPresentationContext; pc = (DUL_PRESENTATIONCONTEXT*) LST_Head(l); (void)LST_Position(l, (LST_NODE*)pc); while (pc && !found) { found = (strcmp(pc->abstractSyntax, abstractSyntax.c_str()) == 0); found &= (pc->result == ASC_P_ACCEPTANCE); if (!transferSyntax.empty()) // ignore transfer syntax if not specified found &= (strcmp(pc->acceptedTransferSyntax, transferSyntax.c_str()) == 0); if (!found) pc = (DUL_PRESENTATIONCONTEXT*) LST_Next(l); } if (found) return pc->presentationContextID; /* now we look for an explicit VR uncompressed PC. */ l = &m_assoc->params->DULparams.acceptedPresentationContext; pc = (DUL_PRESENTATIONCONTEXT*) LST_Head(l); (void)LST_Position(l, (LST_NODE*)pc); while (pc && !found) { found = (strcmp(pc->abstractSyntax, abstractSyntax.c_str()) == 0) && (pc->result == ASC_P_ACCEPTANCE) && ((strcmp(pc->acceptedTransferSyntax, UID_LittleEndianExplicitTransferSyntax) == 0) || (strcmp(pc->acceptedTransferSyntax, UID_BigEndianExplicitTransferSyntax) == 0)); if (!found) pc = (DUL_PRESENTATIONCONTEXT*) LST_Next(l); } if (found) return pc->presentationContextID; /* now we look for an implicit VR uncompressed PC. */ l = &m_assoc->params->DULparams.acceptedPresentationContext; pc = (DUL_PRESENTATIONCONTEXT*) LST_Head(l); (void)LST_Position(l, (LST_NODE*)pc); while (pc && !found) { found = (strcmp(pc->abstractSyntax, abstractSyntax.c_str()) == 0) && (pc->result == ASC_P_ACCEPTANCE) && (strcmp(pc->acceptedTransferSyntax, UID_LittleEndianImplicitTransferSyntax) == 0); if (!found) pc = (DUL_PRESENTATIONCONTEXT*) LST_Next(l); } if (found) return pc->presentationContextID; /* finally we accept everything we get. returns 0 if abstract syntax is not supported */ return ASC_findAcceptedPresentationContextID(m_assoc, abstractSyntax.c_str()); } void DcmSCU::findPresentationContext(const T_ASC_PresentationContextID presID, OFString &abstractSyntax, OFString &transferSyntax) { transferSyntax.clear(); abstractSyntax.clear(); if (m_assoc == NULL) return; DUL_PRESENTATIONCONTEXT *pc; LST_HEAD **l; /* we look for a presentation context matching * both abstract and transfer syntax */ l = &m_assoc->params->DULparams.acceptedPresentationContext; pc = (DUL_PRESENTATIONCONTEXT*) LST_Head(l); (void)LST_Position(l, (LST_NODE*)pc); while (pc) { if (presID == pc->presentationContextID) { if (pc->result == ASC_P_ACCEPTANCE) { // found a match transferSyntax = pc->acceptedTransferSyntax; abstractSyntax = pc->abstractSyntax; } break; } pc = (DUL_PRESENTATIONCONTEXT*) LST_Next(l); } } Uint16 DcmSCU::nextMessageID() { if (!isConnected()) return 0; else return m_assoc->nextMsgID++; } void DcmSCU::closeAssociation(const DcmCloseAssociationType closeType) { if (!isConnected()) { DCMNET_WARN("Closing of association request but no association active (ignored)"); return; } OFCondition cond; OFString tempStr; /* tear down association, i.e. terminate network connection to SCP */ switch (closeType) { case DCMSCU_RELEASE_ASSOCIATION: /* release association */ DCMNET_INFO("Releasing Association"); cond = ASC_releaseAssociation(m_assoc); if (cond.bad()) { DCMNET_ERROR("Association Release Failed: " << DimseCondition::dump(tempStr, cond)); return; // TODO: do we really need this? } break; case DCMSCU_ABORT_ASSOCIATION: /* abort association */ DCMNET_INFO("Aborting Association"); cond = ASC_abortAssociation(m_assoc); if (cond.bad()) { DCMNET_ERROR("Association Abort Failed: " << DimseCondition::dump(tempStr, cond)); } break; case DCMSCU_PEER_REQUESTED_RELEASE: /* peer requested release */ DCMNET_ERROR("Protocol Error: Peer requested release (Aborting)"); DCMNET_INFO("Aborting Association"); cond = ASC_abortAssociation(m_assoc); if (cond.bad()) { DCMNET_ERROR("Association Abort Failed: " << DimseCondition::dump(tempStr, cond)); } break; case DCMSCU_PEER_ABORTED_ASSOCIATION: /* peer aborted association */ DCMNET_INFO("Peer Aborted Association"); break; } // destroy and free memory of internal association and network structures freeNetwork(); } /* ************************************************************************* */ /* C-ECHO functionality */ /* ************************************************************************* */ // Sends C-ECHO request to another DICOM application OFCondition DcmSCU::sendECHORequest(const T_ASC_PresentationContextID presID) { if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; OFCondition cond; T_ASC_PresentationContextID pcid = presID; /* If necessary, find appropriate presentation context */ if (pcid == 0) pcid = findPresentationContextID(UID_VerificationSOPClass, UID_LittleEndianExplicitTransferSyntax); if (pcid == 0) pcid = findPresentationContextID(UID_VerificationSOPClass, UID_BigEndianExplicitTransferSyntax); if (pcid == 0) pcid = findPresentationContextID(UID_VerificationSOPClass, UID_LittleEndianImplicitTransferSyntax); if (pcid == 0) { DCMNET_ERROR("No presentation context found for sending C-ECHO with SOP Class / Transfer Syntax: " << dcmFindNameOfUID(UID_VerificationSOPClass, "") << " / " << DcmXfer(UID_LittleEndianImplicitTransferSyntax).getXferName()); return DIMSE_NOVALIDPRESENTATIONCONTEXTID; } /* Now, assemble DIMSE message */ T_DIMSE_Message msg; T_DIMSE_C_EchoRQ* req = &(msg.msg.CEchoRQ); // Set type of message msg.CommandField = DIMSE_C_ECHO_RQ; // Set message ID req->MessageID = nextMessageID(); // Announce no dataset req->DataSetType = DIMSE_DATASET_NULL; // Set affected SOP Class UID (always Verification SOP Class) OFStandard::strlcpy(req->AffectedSOPClassUID, UID_VerificationSOPClass, sizeof(req->AffectedSOPClassUID)); /* Send request */ OFString tempStr; DCMNET_INFO("Sending C-ECHO Request (MsgID " << req->MessageID << ")"); cond = sendDIMSEMessage(pcid, &msg, NULL /*dataObject*/); if (cond.bad()) { DCMNET_ERROR("Failed sending C-ECHO request: " << DimseCondition::dump(tempStr, cond)); return cond; } /* Receive response */ T_DIMSE_Message rsp; DcmDataset* statusDetail = NULL; cond = receiveDIMSECommand(&pcid, &rsp, &statusDetail, NULL /* not interested in the command set */); if (cond.bad()) { DCMNET_ERROR("Failed receiving DIMSE response: " << DimseCondition::dump(tempStr, cond)); return cond; } /* Check whether we received C-ECHO response, otherwise print error */ if (rsp.CommandField == DIMSE_C_ECHO_RSP) { DCMNET_INFO("Received C-ECHO Response (" << rsp.msg.CEchoRSP.DimseStatus << ")"); } else { DCMNET_ERROR("Expected C-ECHO response but received DIMSE command 0x" << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4) << OFstatic_cast(unsigned int, rsp.CommandField)); DCMNET_DEBUG(DIMSE_dumpMessage(tempStr, rsp, DIMSE_INCOMING, NULL, pcid)); delete statusDetail; return DIMSE_BADCOMMANDTYPE; } /* Print status detail if it was received */ if (statusDetail != NULL) { DCMNET_DEBUG("Response has status detail:" << OFendl << DcmObject::PrintHelper(*statusDetail)); delete statusDetail; } return EC_Normal; } /* ************************************************************************* */ /* C-STORE functionality */ /* ************************************************************************* */ // Sends C-STORE request to another DICOM application OFCondition DcmSCU::sendSTORERequest(const T_ASC_PresentationContextID presID, const OFString &dicomFile, DcmDataset *dataset, Uint16 &rspStatusCode) { // Do some basic validity checks if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; OFCondition cond; OFString tempStr; T_ASC_PresentationContextID pcid = presID; DcmDataset* statusDetail = NULL; T_DIMSE_Message msg; T_DIMSE_C_StoreRQ* req = &(msg.msg.CStoreRQ); // Set type of message msg.CommandField = DIMSE_C_STORE_RQ; /* Set message ID */ req->MessageID = nextMessageID(); /* Load file if necessary */ DcmFileFormat *fileformat = NULL; if (!dicomFile.empty()) { fileformat = new DcmFileFormat(); if (fileformat == NULL) return EC_MemoryExhausted; cond = fileformat->loadFile(dicomFile.c_str()); if (cond.bad()) { delete fileformat; return cond; } dataset = fileformat->getDataset(); } /* Fill message according to dataset to be sent */ OFString sopClassUID; OFString sopInstanceUID; E_TransferSyntax xferSyntax = EXS_Unknown; cond = getDatasetInfo(dataset, sopClassUID, sopInstanceUID, xferSyntax); DcmXfer xfer(xferSyntax); /* Check whether the information is sufficient */ if (sopClassUID.empty() || sopInstanceUID.empty() || ((pcid == 0) && (xferSyntax == EXS_Unknown))) { DCMNET_ERROR("Cannot send SOP instance, missing information:"); if (!dicomFile.empty()) DCMNET_ERROR(" DICOM Filename : " << dicomFile); DCMNET_ERROR(" SOP Class UID : " << sopClassUID); DCMNET_ERROR(" SOP Instance UID : " << sopInstanceUID); DCMNET_ERROR(" Transfer Syntax : " << xfer.getXferName()); if (pcid == 0) DCMNET_ERROR(" Pres. Context ID : 0 (find via SOP Class and Transfer Syntax)"); else DCMNET_ERROR(" Pres. Context ID : " << OFstatic_cast(unsigned int, pcid)); delete fileformat; return cond; } OFStandard::strlcpy(req->AffectedSOPClassUID, sopClassUID.c_str(), sizeof(req->AffectedSOPClassUID)); OFStandard::strlcpy(req->AffectedSOPInstanceUID, sopInstanceUID.c_str(), sizeof(req->AffectedSOPInstanceUID)); req->DataSetType = DIMSE_DATASET_PRESENT; req->Priority = DIMSE_PRIORITY_LOW; /* If no presentation context is specified by the caller ... */ if (pcid == 0) { /* ... try to find an appropriate presentation context automatically */ pcid = findPresentationContextID(sopClassUID, xfer.getXferID()); } else if (m_datasetConversionMode) { /* Convert dataset to network transfer syntax (if required) */ OFString abstractSyntax, transferSyntax; findPresentationContext(pcid, abstractSyntax, transferSyntax); /* Check whether given presentation context was accepted by the peer */ if (abstractSyntax.empty() || transferSyntax.empty()) { /* Mark presentation context as invalid */ pcid = 0; } else { if (abstractSyntax != sopClassUID) { DCMNET_WARN("Inappropriate presentation context with ID " << OFstatic_cast(unsigned int, pcid) << ": abstract syntax does not match SOP class UID"); } /* Try to convert to the negotiated transfer syntax */ DcmXfer netXfer = DcmXfer(transferSyntax.c_str()).getXfer(); if (netXfer.getXfer() != xferSyntax) { DCMNET_INFO("Converting transfer syntax: " << xfer.getXferName() << " -> " << netXfer.getXferName()); dataset->chooseRepresentation(netXfer.getXfer(), NULL); } } } /* No appropriate presentation context for sending */ if (pcid == 0) { OFString sopClassName = dcmFindNameOfUID(sopClassUID.c_str(), sopClassUID.c_str()); OFString xferName = xfer.getXferName(); DCMNET_ERROR("No presentation context found for sending C-STORE with SOP Class / Transfer Syntax: " << sopClassName << " / " << xferName); return DIMSE_NOVALIDPRESENTATIONCONTEXTID; } /* Send request */ DCMNET_INFO("Sending C-STORE Request (MsgID " << req->MessageID << ", " << dcmSOPClassUIDToModality(sopClassUID.c_str(), "OT") << ")"); cond = sendDIMSEMessage(pcid, &msg, dataset); delete fileformat; fileformat = NULL; if (cond.bad()) { DCMNET_ERROR("Failed sending C-STORE request: " << DimseCondition::dump(tempStr, cond)); return cond; } /* Receive response */ T_DIMSE_Message rsp; cond = receiveDIMSECommand(&pcid, &rsp, &statusDetail, NULL /* not interested in the command set */); if (cond.bad()) { DCMNET_ERROR("Failed receiving DIMSE response: " << DimseCondition::dump(tempStr, cond)); return cond; } if (rsp.CommandField == DIMSE_C_STORE_RSP) { DCMNET_INFO("Received C-STORE Response (" << DU_cstoreStatusString(rsp.msg.CStoreRSP.DimseStatus) << ")"); } else { DCMNET_ERROR("Expected C-STORE response but received DIMSE command 0x" << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4) << OFstatic_cast(unsigned int, rsp.CommandField)); DCMNET_DEBUG(DIMSE_dumpMessage(tempStr, rsp, DIMSE_INCOMING, NULL, pcid)); delete statusDetail; return DIMSE_BADCOMMANDTYPE; } T_DIMSE_C_StoreRSP storeRsp = rsp.msg.CStoreRSP; rspStatusCode = storeRsp.DimseStatus; if (statusDetail != NULL) { DCMNET_DEBUG("Response has status detail:" << OFendl << DcmObject::PrintHelper(*statusDetail)); delete statusDetail; } return cond; } /* ************************************************************************* */ /* C-MOVE functionality */ /* ************************************************************************* */ // Sends a C-MOVE Request on given presentation context OFCondition DcmSCU::sendMOVERequest(const T_ASC_PresentationContextID presID, const OFString &moveDestinationAETitle, DcmDataset *dataset, OFList *responses) { // Do some basic validity checks if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; if (dataset == NULL) return DIMSE_NULLKEY; /* Prepare DIMSE data structures for issuing request */ OFCondition cond; OFString tempStr; T_ASC_PresentationContextID pcid = presID; T_DIMSE_Message msg; DcmDataset* statusDetail = NULL; T_DIMSE_C_MoveRQ* req = &(msg.msg.CMoveRQ); // Set type of message msg.CommandField = DIMSE_C_MOVE_RQ; // Set message ID req->MessageID = nextMessageID(); // Announce dataset req->DataSetType = DIMSE_DATASET_PRESENT; // Set target for embedded C-Store's OFStandard::strlcpy(req->MoveDestination, moveDestinationAETitle.c_str(), sizeof(req->MoveDestination)); // Set priority (mandatory) req->Priority = DIMSE_PRIORITY_LOW; /* Determine SOP Class from presentation context */ OFString abstractSyntax, transferSyntax; findPresentationContext(pcid, abstractSyntax, transferSyntax); if (abstractSyntax.empty() || transferSyntax.empty()) return DIMSE_NOVALIDPRESENTATIONCONTEXTID; OFStandard::strlcpy(req->AffectedSOPClassUID, abstractSyntax.c_str(), sizeof(req->AffectedSOPClassUID)); /* Send request */ DCMNET_INFO("Sending C-MOVE Request (MsgID " << req->MessageID << ")"); cond = sendDIMSEMessage(pcid, &msg, dataset); if (cond.bad()) { DCMNET_ERROR("Failed sending C-MOVE request: " << DimseCondition::dump(tempStr, cond)); return cond; } /* Receive and handle C-MOVE response messages */ OFBool waitForNextResponse = OFTrue; while (waitForNextResponse) { T_DIMSE_Message rsp; statusDetail = NULL; // Receive command set cond = receiveDIMSECommand(&pcid, &rsp, &statusDetail, NULL /* not interested in the command set */); if (cond.bad()) { DCMNET_ERROR("Failed receiving DIMSE response: " << DimseCondition::dump(tempStr, cond)); delete statusDetail; break; } if (rsp.CommandField == DIMSE_C_MOVE_RSP) { DCMNET_INFO("Received C-MOVE Response (" << DU_cmoveStatusString(rsp.msg.CMoveRSP.DimseStatus) << ")"); } else { DCMNET_ERROR("Expected C-MOVE response but received DIMSE command 0x" << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4) << OFstatic_cast(unsigned int, rsp.CommandField)); DCMNET_DEBUG(DIMSE_dumpMessage(tempStr, rsp, DIMSE_INCOMING, NULL, pcid)); delete statusDetail; cond = DIMSE_BADCOMMANDTYPE; break; } // Prepare response package for response handler RetrieveResponse *moveRSP = new RetrieveResponse(); moveRSP->m_affectedSOPClassUID = rsp.msg.CMoveRSP.AffectedSOPClassUID; moveRSP->m_messageIDRespondedTo = rsp.msg.CMoveRSP.MessageIDBeingRespondedTo; moveRSP->m_status = rsp.msg.CMoveRSP.DimseStatus; moveRSP->m_numberOfRemainingSubops = rsp.msg.CMoveRSP.NumberOfRemainingSubOperations; moveRSP->m_numberOfCompletedSubops = rsp.msg.CMoveRSP.NumberOfCompletedSubOperations; moveRSP->m_numberOfFailedSubops = rsp.msg.CMoveRSP.NumberOfFailedSubOperations; moveRSP->m_numberOfWarningSubops = rsp.msg.CMoveRSP.NumberOfWarningSubOperations; moveRSP->m_statusDetail = statusDetail; //DCMNET_DEBUG("C-MOVE response has status 0x" // << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4) // << moveRSP->m_status); if (statusDetail != NULL) { DCMNET_DEBUG("Response has status detail:" << OFendl << DcmObject::PrintHelper(*statusDetail)); } // Receive dataset if there is one (status PENDING) DcmDataset *rspDataset = NULL; // Check if dataset is announced correctly if (rsp.msg.CMoveRSP.DataSetType != DIMSE_DATASET_NULL) // Some of the sub operations have failed, thus a dataset with a list of them is attached { // Receive dataset cond = receiveDIMSEDataset(&pcid, &rspDataset); if (cond.bad()) { DCMNET_ERROR("Unable to receive C-MOVE dataset on presentation context " << OFstatic_cast(unsigned int, pcid) << ": " << DimseCondition::dump(tempStr, cond)); delete moveRSP; // includes statusDetail break; } moveRSP->m_dataset = rspDataset; } // Handle C-MOVE response (has to handle all possible status flags) cond = handleMOVEResponse(pcid, moveRSP, waitForNextResponse); if (cond.bad()) { DCMNET_WARN("Unable to handle C-MOVE response correctly: " << cond.text() << " (ignored)"); delete moveRSP; // includes statusDetail // don't return here but trust the "waitForNextResponse" variable } // if response could be handled successfully, add it to response list else { if (responses != NULL) // only add if desired by caller responses->push_back(moveRSP); else delete moveRSP; // includes statusDetail } } /* All responses received or break signal occured */ return cond; } // Standard handler for C-MOVE message responses OFCondition DcmSCU::handleMOVEResponse( const T_ASC_PresentationContextID /* presID */, RetrieveResponse *response, OFBool &waitForNextResponse ) { // Do some basic validity checks if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; if (response == NULL) return DIMSE_NULLKEY; DCMNET_DEBUG("Handling C-MOVE Response"); switch (response->m_status) { case STATUS_MOVE_Failed_IdentifierDoesNotMatchSOPClass: waitForNextResponse = OFFalse; DCMNET_ERROR("Identifier does not match SOP class in C-MOVE response"); break; case STATUS_MOVE_Failed_MoveDestinationUnknown: waitForNextResponse = OFFalse; DCMNET_ERROR("Move destination unknown"); break; case STATUS_MOVE_Failed_UnableToProcess: waitForNextResponse = OFFalse; DCMNET_ERROR("Unable to process C-Move response"); break; case STATUS_MOVE_Cancel_SubOperationsTerminatedDueToCancelIndication: waitForNextResponse = OFFalse; DCMNET_DEBUG("Suboperations canceled by server due to CANCEL indication"); break; case STATUS_MOVE_Warning_SubOperationsCompleteOneOrMoreFailures: waitForNextResponse = OFFalse; DCMNET_WARN("Suboperations of C-MOVE completed with one or more failures"); break; case STATUS_Pending: /* in this case the current C-MOVE-RSP indicates that */ /* there will be some more results */ waitForNextResponse = OFTrue; DCMNET_DEBUG("One or more pending C-MOVE responses"); break; case STATUS_Success: /* in this case, we received the last C-MOVE-RSP so there */ /* will be no other responses we have to wait for. */ waitForNextResponse = OFFalse; DCMNET_DEBUG("Received final C-MOVE response, no more C-MOVE responses expected"); break; default: /* in all other cases, don't expect further responses to come */ waitForNextResponse = OFFalse; DCMNET_WARN("Status is 0x" << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4) << response->m_status << " (unknown)"); DCMNET_WARN("Will not wait for further C-MOVE responses"); break; } //switch return EC_Normal; } /* ************************************************************************* */ /* C-GET and acommpanying C-STORE functionality */ /* ************************************************************************* */ // Sends a C-GET Request on given presentation context OFCondition DcmSCU::sendCGETRequest(const T_ASC_PresentationContextID presID, DcmDataset *dataset, OFList *responses) { // Do some basic validity checks if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; if (dataset == NULL) return DIMSE_NULLKEY; /* Prepare DIMSE data structures for issuing request */ OFCondition cond; OFString tempStr; T_ASC_PresentationContextID pcid = presID; T_DIMSE_Message msg; T_DIMSE_C_GetRQ* req = &(msg.msg.CGetRQ); // Set type of message msg.CommandField = DIMSE_C_GET_RQ; // Set message ID req->MessageID = nextMessageID(); // Announce dataset req->DataSetType = DIMSE_DATASET_PRESENT; // Specify priority req->Priority = DIMSE_PRIORITY_LOW; // Determine SOP Class from presentation context OFString abstractSyntax, transferSyntax; findPresentationContext(pcid, abstractSyntax, transferSyntax); if (abstractSyntax.empty() || transferSyntax.empty()) return DIMSE_NOVALIDPRESENTATIONCONTEXTID; OFStandard::strlcpy(req->AffectedSOPClassUID, abstractSyntax.c_str(), sizeof(req->AffectedSOPClassUID)); /* Send request */ DCMNET_INFO("Sending C-GET Request (MsgID " << req->MessageID << ")"); cond = sendDIMSEMessage(pcid, &msg, dataset); if (cond.bad()) { DCMNET_ERROR("Failed sending C-GET request: " << DimseCondition::dump(tempStr, cond)); return cond; } cond = handleCGETSession(pcid, dataset, responses); return cond; } // Does the logic for switching between C-GET Response and C-STORE Requests OFCondition DcmSCU::handleCGETSession(const T_ASC_PresentationContextID /* presID */, DcmDataset * /* dataset */, OFList *responses) { OFCondition result; OFBool continueSession = OFTrue; OFString tempStr; // As long we want to continue (usually, as long as we receive more objects, // i.e. the final C-GET reponse has not arrived yet) while (continueSession) { T_DIMSE_Message rsp; DcmDataset *statusDetail = NULL; T_ASC_PresentationContextID pcid = 0; // Receive command set result = receiveDIMSECommand(&pcid, &rsp, &statusDetail, NULL /* not interested in the command set */); if (result.bad()) { DCMNET_ERROR("Failed receiving DIMSE command: " << DimseCondition::dump(tempStr, result)); delete statusDetail; break; } // Handle C-GET Response if (rsp.CommandField == DIMSE_C_GET_RSP) { DCMNET_INFO("Received C-GET Response (" << DU_cgetStatusString(rsp.msg.CGetRSP.DimseStatus) << ")"); // Prepare response package for response handler RetrieveResponse *getRSP = new RetrieveResponse(); getRSP->m_affectedSOPClassUID = rsp.msg.CGetRSP.AffectedSOPClassUID; getRSP->m_messageIDRespondedTo = rsp.msg.CGetRSP.MessageIDBeingRespondedTo; getRSP->m_status = rsp.msg.CGetRSP.DimseStatus; getRSP->m_numberOfRemainingSubops = rsp.msg.CGetRSP.NumberOfRemainingSubOperations; getRSP->m_numberOfCompletedSubops = rsp.msg.CGetRSP.NumberOfCompletedSubOperations; getRSP->m_numberOfFailedSubops = rsp.msg.CGetRSP.NumberOfFailedSubOperations; getRSP->m_numberOfWarningSubops = rsp.msg.CGetRSP.NumberOfWarningSubOperations; getRSP->m_statusDetail = statusDetail; if (statusDetail != NULL) { DCMNET_DEBUG("Response has status detail:" << OFendl << DcmObject::PrintHelper(*statusDetail)); statusDetail = NULL; // forget reference to status detail, will be deleted with getRSP } result = handleCGETResponse(pcid, getRSP, continueSession); if (result.bad()) { DCMNET_WARN("Unable to handle C-GET response correctly: " << result.text() << " (ignored)"); delete getRSP; // includes statusDetail // don't return here but trust the "continueSession" variable } // if response could be handled successfully, add it to response list else { if (responses != NULL) // only add if desired by caller responses->push_back(getRSP); else delete getRSP; // includes statusDetail } } // Handle C-STORE Request else if (rsp.CommandField == DIMSE_C_STORE_RQ) { DCMNET_INFO("Received C-STORE Request (MsgID " << rsp.msg.CStoreRQ.MessageID << ")"); // Receive dataset if there is one (status PENDING) DcmDataset *rspDataset = NULL; // Check if dataset is announced correctly if (rsp.msg.CStoreRQ.DataSetType == DIMSE_DATASET_NULL) { DCMNET_WARN("Incoming C-STORE with no dataset, trying to receive one anyway"); } Uint16 desiredCStoreReturnStatus = 0; // handle normal storage mode, i.e. receive in memory and store to disk if (m_storageMode == DCMSCU_STORAGE_DISK) { // Receive dataset result = receiveDIMSEDataset(&pcid, &rspDataset); if (result.bad()) { result = DIMSE_NULLKEY; desiredCStoreReturnStatus = STATUS_STORE_Error_CannotUnderstand; } else { result = handleSTORERequest(pcid, rspDataset, continueSession, desiredCStoreReturnStatus); } } // handle bit preserving storage mode, i.e. receive directly to disk else if (m_storageMode == DCMSCU_STORAGE_BIT_PRESERVING) { OFString storageFilename; OFStandard::combineDirAndFilename(storageFilename, m_storageDir, rsp.msg.CStoreRQ.AffectedSOPInstanceUID, OFTrue); result = handleSTORERequestFile(&pcid, storageFilename, &(rsp.msg.CStoreRQ)); if (result.good()) { notifyInstanceStored(storageFilename, rsp.msg.CStoreRQ.AffectedSOPClassUID, rsp.msg.CStoreRQ.AffectedSOPInstanceUID); } } // handle ignore storage mode, i.e. ignore received dataset and do not store at all else { result = ignoreSTORERequest(pcid, rsp.msg.CStoreRQ); } // Evaluate result from C-STORE request handling and send response if (result.bad()) { desiredCStoreReturnStatus = STATUS_STORE_Error_CannotUnderstand; continueSession = OFFalse; } result = sendSTOREResponse(pcid, desiredCStoreReturnStatus, rsp.msg.CStoreRQ); if (result.bad()) { continueSession = OFFalse; } delete rspDataset; // should be NULL if not existing } // Handle other DIMSE command (error since other command than GET/STORE not expected) else { DCMNET_ERROR("Expected C-GET response or C-STORE request but received DIMSE command 0x" << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4) << OFstatic_cast(unsigned int, rsp.CommandField)); DCMNET_DEBUG(DIMSE_dumpMessage(tempStr, rsp, DIMSE_INCOMING, NULL, pcid)); result = DIMSE_BADCOMMANDTYPE; continueSession = OFFalse; } delete statusDetail; // should be NULL if not existing or added to response list statusDetail = NULL; } /* All responses received or break signal occured */ return result; } // Handles single C-GET Response OFCondition DcmSCU::handleCGETResponse(const T_ASC_PresentationContextID /* presID */, RetrieveResponse* response, OFBool& continueCGETSession) { // Do some basic validity checks if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; if (response == NULL) return DIMSE_NULLKEY; DCMNET_DEBUG("Handling C-GET Response"); /* First, perform separate check for 0xCxxx error codes */ Uint16 highNibble = response->m_status & 0xf000; if (highNibble == STATUS_GET_Failed_UnableToProcess) { continueCGETSession = OFFalse; DCMNET_ERROR("Unable to Process"); DCMNET_WARN("Full status is 0x" << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4) << response->m_status); return EC_Normal; } /* Check for other error codes */ switch (response->m_status) { case STATUS_GET_Refused_OutOfResourcesNumberOfMatches: continueCGETSession = OFFalse; DCMNET_ERROR("Out of Resouces - Unable to calculate number of matches"); break; case STATUS_GET_Refused_OutOfResourcesSubOperations: continueCGETSession = OFFalse; DCMNET_ERROR("Out of Resouces - Unable to perform sub-operations"); break; case STATUS_GET_Failed_IdentifierDoesNotMatchSOPClass: continueCGETSession = OFFalse; DCMNET_ERROR("Identifier does not match SOP class"); break; case STATUS_GET_Cancel_SubOperationsTerminatedDueToCancelIndication: continueCGETSession = OFFalse; DCMNET_DEBUG("Suboperations canceled by server due to CANCEL indication"); break; case STATUS_GET_Warning_SubOperationsCompleteOneOrMoreFailures: continueCGETSession = OFFalse; DCMNET_WARN("Suboperations of C-GET completed with one or more failures"); break; case STATUS_Pending: /* in this case the current C-MOVE-RSP indicates that */ /* there will be some more results */ continueCGETSession = OFTrue; DCMNET_DEBUG("One or more pending C-GET responses"); break; case STATUS_Success: /* in this case, we received the last C-MOVE-RSP so there */ /* will be no other responses we have to wait for. */ continueCGETSession = OFFalse; DCMNET_DEBUG("Received final C-GET response, no more C-GET responses expected"); break; default: /* in all other cases, don't expect further responses to come */ continueCGETSession = OFFalse; DCMNET_WARN("Status is 0x" << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4) << response->m_status << " (unknown)"); DCMNET_WARN("Will not wait for further C-GET responses"); break; } //switch return EC_Normal; } // Handles single C-STORE Request received during C-GET session OFCondition DcmSCU::handleSTORERequest(const T_ASC_PresentationContextID /* presID */, DcmDataset *incomingObject, OFBool& /* continueCGETSession */, Uint16& cStoreReturnStatus) { if (incomingObject == NULL) return DIMSE_NULLKEY; OFString sopClassUID; OFString sopInstanceUID; OFCondition result = incomingObject->findAndGetOFString(DCM_SOPClassUID, sopClassUID); if (result.good()) result = incomingObject->findAndGetOFString(DCM_SOPInstanceUID, sopInstanceUID); if (result.bad()) { DCMNET_ERROR("Cannot store received object: either SOP Instance or SOP Class UID not present"); cStoreReturnStatus = STATUS_STORE_Error_DataSetDoesNotMatchSOPClass; return EC_TagNotFound; } OFString filename = createStorageFilename(incomingObject); result = incomingObject->saveFile(filename.c_str()); if (result.good()) { E_TransferSyntax xferSyntax; getDatasetInfo(incomingObject, sopClassUID, sopInstanceUID, xferSyntax); notifyInstanceStored(filename, sopClassUID, sopInstanceUID); cStoreReturnStatus = STATUS_Success; } else { cStoreReturnStatus = STATUS_STORE_Refused_OutOfResources; } return result; } OFCondition DcmSCU::handleSTORERequestFile(T_ASC_PresentationContextID *presID, const OFString& filename, T_DIMSE_C_StoreRQ* request) { if (filename.empty()) return EC_IllegalParameter; /* in the following, we want to receive data over the network and write it to a file */ /* exactly the way it was received over the network. Hence, a filestream will be created and the data */ /* set will be received and written to the file through the call to DIMSE_receiveDataSetInFile(...).*/ /* create filestream */ DcmOutputFileStream *filestream = NULL; OFCondition cond = DIMSE_createFilestream(filename.c_str(), request, m_assoc, *presID, OFTrue, &filestream); if (cond.good()) { if (m_progressNotificationMode) { cond = DIMSE_receiveDataSetInFile(m_assoc, m_blockMode, m_dimseTimeout, presID, filestream, callbackRECEIVEProgress, this /*callbackData*/); } else { cond = DIMSE_receiveDataSetInFile(m_assoc, m_blockMode, m_dimseTimeout, presID, filestream, NULL /*callback*/, NULL /*callbackData*/); } delete filestream; if (cond != EC_Normal) { unlink(filename.c_str()); } DCMNET_DEBUG("Received dataset on presentation context " << OFstatic_cast(unsigned int, *presID)); } else { OFString tempStr; DCMNET_ERROR("Unable to receive and store dataset on presentation context " << OFstatic_cast(unsigned int, *presID) << ": " << DimseCondition::dump(tempStr, cond)); } return cond; } OFCondition DcmSCU::sendSTOREResponse(T_ASC_PresentationContextID presID, Uint16 status, const T_DIMSE_C_StoreRQ& request) { // Send back response T_DIMSE_Message response; T_DIMSE_C_StoreRSP &storeRsp = response.msg.CStoreRSP; response.CommandField = DIMSE_C_STORE_RSP; storeRsp.MessageIDBeingRespondedTo = request.MessageID; storeRsp.DimseStatus = status; storeRsp.DataSetType = DIMSE_DATASET_NULL; storeRsp.opts = 0; /* Following information is optional and normally not sent by the underlying * dcmnet routines. However, maybe this could be changed later, so insert it. */ OFStandard::strlcpy(storeRsp.AffectedSOPClassUID, request.AffectedSOPClassUID, sizeof(storeRsp.AffectedSOPClassUID)); OFStandard::strlcpy(storeRsp.AffectedSOPInstanceUID, request.AffectedSOPInstanceUID, sizeof(storeRsp.AffectedSOPInstanceUID)); OFString tempStr; DCMNET_INFO("Sending C-STORE Response (" << DU_cstoreStatusString(status) << ")"); OFCondition cond = sendDIMSEMessage(presID, &response, NULL /*dataObject*/); if (cond.bad()) { DCMNET_ERROR("Failed sending C-STORE response: " << DimseCondition::dump(tempStr, cond)); } return cond; } OFString DcmSCU::createStorageFilename(DcmDataset *dataset) { OFString sopClassUID, sopInstanceUID; E_TransferSyntax dummy; getDatasetInfo(dataset, sopClassUID, sopInstanceUID, dummy); // Create unique filename if (sopClassUID.empty() || sopInstanceUID.empty()) return ""; OFString name = dcmSOPClassUIDToModality(sopClassUID.c_str(), "UNKNOWN"); name += "."; name += sopInstanceUID; OFString returnStr; OFStandard::combineDirAndFilename(returnStr, m_storageDir, name, OFTrue); return returnStr; } OFCondition DcmSCU::ignoreSTORERequest(T_ASC_PresentationContextID presID, const T_DIMSE_C_StoreRQ& request) { /* We cannot create the filestream, so ignore the incoming dataset and return an out-of-resources error to the SCU */ DIC_UL bytesRead = 0; DIC_UL pdvCount=0; DCMNET_DEBUG("Ignoring incoming C-STORE dataset on presentation context " << OFstatic_cast(unsigned int, presID) << " with Affected SOP Instance UID: " << request.AffectedSOPInstanceUID ); OFCondition result = DIMSE_ignoreDataSet(m_assoc, m_blockMode, m_dimseTimeout, &bytesRead, &pdvCount); if (result.good()) { DCMNET_TRACE("Successfully skipped " << bytesRead << " bytes in " << pdvCount << " PDVs"); } return result; } void DcmSCU::notifyInstanceStored(const OFString& filename, const OFString& sopClassUID, const OFString& sopInstanceUID) const { DCMNET_DEBUG("Stored instance to disk:"); DCMNET_DEBUG(" Filename: " << filename); DCMNET_DEBUG(" SOP Class UID: " << sopClassUID); DCMNET_DEBUG(" SOP Instance UID: " << sopInstanceUID); } /* ************************************************************************* */ /* C-FIND functionality */ /* ************************************************************************* */ // Sends a C-FIND Request on given presentation context OFCondition DcmSCU::sendFINDRequest(const T_ASC_PresentationContextID presID, DcmDataset *queryKeys, OFList *responses) { // Do some basic validity checks if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; if (queryKeys == NULL) return DIMSE_NULLKEY; /* Prepare DIMSE data structures for issuing request */ OFCondition cond; OFString tempStr; T_ASC_PresentationContextID pcid = presID; T_DIMSE_Message msg; DcmDataset* statusDetail = NULL; T_DIMSE_C_FindRQ* req = &(msg.msg.CFindRQ); // Set type of message msg.CommandField = DIMSE_C_FIND_RQ; // Set message ID req->MessageID = nextMessageID(); // Announce dataset req->DataSetType = DIMSE_DATASET_PRESENT; // Specify priority req->Priority = DIMSE_PRIORITY_LOW; // Determine SOP Class from presentation context OFString abstractSyntax, transferSyntax; findPresentationContext(pcid, abstractSyntax, transferSyntax); if (abstractSyntax.empty() || transferSyntax.empty()) return DIMSE_NOVALIDPRESENTATIONCONTEXTID; OFStandard::strlcpy(req->AffectedSOPClassUID, abstractSyntax.c_str(), sizeof(req->AffectedSOPClassUID)); /* Send request */ DCMNET_INFO("Sending C-FIND Request (MsgID " << req->MessageID << ")"); cond = sendDIMSEMessage(pcid, &msg, queryKeys); if (cond.bad()) { DCMNET_ERROR("Failed sending C-FIND request: " << DimseCondition::dump(tempStr, cond)); return cond; } /* Receive and handle response */ OFBool waitForNextResponse = OFTrue; while (waitForNextResponse) { T_DIMSE_Message rsp; statusDetail = NULL; // Receive command set cond = receiveDIMSECommand(&pcid, &rsp, &statusDetail, NULL /* not interested in the command set */); if (cond.bad()) { DCMNET_ERROR("Failed receiving DIMSE response: " << DimseCondition::dump(tempStr, cond)); return cond; } if (rsp.CommandField == DIMSE_C_FIND_RSP) { DCMNET_INFO("Received C-FIND Response (" << DU_cfindStatusString(rsp.msg.CFindRSP.DimseStatus) << ")"); } else { DCMNET_ERROR("Expected C-FIND response but received DIMSE command 0x" << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4) << OFstatic_cast(unsigned int, rsp.CommandField)); DCMNET_DEBUG(DIMSE_dumpMessage(tempStr, rsp, DIMSE_INCOMING, NULL, pcid)); delete statusDetail; return DIMSE_BADCOMMANDTYPE; } // Prepare response package for response handler QRResponse *findRSP = new QRResponse(); findRSP->m_affectedSOPClassUID = rsp.msg.CFindRSP.AffectedSOPClassUID; findRSP->m_messageIDRespondedTo = rsp.msg.CFindRSP.MessageIDBeingRespondedTo; findRSP->m_status = rsp.msg.CFindRSP.DimseStatus; findRSP->m_statusDetail = statusDetail; // Receive dataset if there is one (status PENDING) DcmDataset *rspDataset = NULL; if (DICOM_PENDING_STATUS(findRSP->m_status)) { // Check if dataset is announced correctly if (rsp.msg.CFindRSP.DataSetType == DIMSE_DATASET_NULL) { DCMNET_ERROR("Received C-FIND response with PENDING status but no dataset announced, aborting"); delete findRSP; // includes statusDetail return DIMSE_BADMESSAGE; } // Receive dataset cond = receiveDIMSEDataset(&pcid, &rspDataset); if (cond.bad()) { delete findRSP; // includes statusDetail return DIMSE_BADDATA; } findRSP->m_dataset = rspDataset; } // Handle C-FIND response (has to handle all possible status flags) cond = handleFINDResponse(pcid, findRSP, waitForNextResponse); if (cond.bad()) { DCMNET_WARN("Unable to handle C-FIND response correctly: " << cond.text() << " (ignored)"); delete findRSP; // includes statusDetail and rspDataset // don't return here but trust the "waitForNextResponse" variable } // if response could be handled successfully, add it to response list else { if (responses != NULL) // only add if desired by caller responses->push_back(findRSP); else delete findRSP; // includes statusDetail and rspDataset } } /* All responses received or break signal occured */ return EC_Normal; } // Standard handler for C-FIND message responses OFCondition DcmSCU::handleFINDResponse(const T_ASC_PresentationContextID /* presID */, QRResponse *response, OFBool &waitForNextResponse) { if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; if (response == NULL) return DIMSE_NULLKEY; DCMNET_DEBUG("Handling C-FIND Response"); switch (response->m_status) { case STATUS_Pending: case STATUS_FIND_Pending_WarningUnsupportedOptionalKeys: /* in this case the current C-FIND-RSP indicates that */ /* there will be some more results */ waitForNextResponse = OFTrue; DCMNET_DEBUG("One or more pending C-FIND responses"); break; case STATUS_Success: /* in this case the current C-FIND-RSP indicates that */ /* there are no more records that match the search mask */ waitForNextResponse = OFFalse; DCMNET_DEBUG("Received final C-FIND response, no more C-FIND responses expected"); break; default: /* in all other cases, don't expect further responses to come */ waitForNextResponse = OFFalse; DCMNET_DEBUG("Status tells not to wait for further C-FIND responses"); break; } //switch return EC_Normal; } /* ************************************************************************* */ /* C-CANCEL functionality */ /* ************************************************************************* */ // Send C-CANCEL-REQ and, therefore, ends current C-FIND, -MOVE or -GET session OFCondition DcmSCU::sendCANCELRequest(const T_ASC_PresentationContextID presID) { if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; /* Prepare DIMSE data structures for issuing request */ OFCondition cond; OFString tempStr; T_ASC_PresentationContextID pcid = presID; T_DIMSE_Message msg; T_DIMSE_C_CancelRQ* req = &(msg.msg.CCancelRQ); // Set type of message msg.CommandField = DIMSE_C_CANCEL_RQ; /* Set message ID responded to. A new message ID is _not_ needed so we do not increment the message ID here but instead have to give the message ID that was used last. Note that that it is required to actually use the message ID of the last C-FIND/GET/MOVE that was issued on this presentation context channel. However, since we only support synchronous association mode so far, it is enough to take the last message ID used at all. For asynchronous operation, we would have to lookup the message ID of the last C-FIND/GET/MOVE request issued and thus, store this information after sending it. */ req->MessageIDBeingRespondedTo = m_assoc->nextMsgID - 1; // Announce dataset req->DataSetType = DIMSE_DATASET_NULL; /* We do not care about the transfer syntax since no dataset is transported at all, i.e. we trust that the user provided the correct presentation context ID (could be private one). */ DCMNET_INFO("Sending C-CANCEL Request (MsgID " << req->MessageIDBeingRespondedTo << ", PresID " << OFstatic_cast(unsigned int, pcid) << ")"); cond = sendDIMSEMessage(pcid, &msg, NULL /*dataObject*/); if (cond.bad()) { DCMNET_ERROR("Failed sending C-CANCEL request: " << DimseCondition::dump(tempStr, cond)); } DCMNET_TRACE("There is no C-CANCEL response in DICOM, so none expected"); return cond; } /* ************************************************************************* */ /* N-ACTION functionality */ /* ************************************************************************* */ // Sends N-ACTION request to another DICOM application OFCondition DcmSCU::sendACTIONRequest(const T_ASC_PresentationContextID presID, const OFString &sopInstanceUID, const Uint16 actionTypeID, DcmDataset *reqDataset, Uint16 &rspStatusCode) { // Do some basic validity checks if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; if (sopInstanceUID.empty() || (reqDataset == NULL)) return DIMSE_NULLKEY; // Prepare DIMSE data structures for issuing request OFCondition cond; OFString tempStr; T_ASC_PresentationContextID pcid = presID; T_DIMSE_Message request; T_DIMSE_N_ActionRQ &actionReq = request.msg.NActionRQ; DcmDataset *statusDetail = NULL; request.CommandField = DIMSE_N_ACTION_RQ; actionReq.MessageID = nextMessageID(); actionReq.DataSetType = DIMSE_DATASET_PRESENT; actionReq.ActionTypeID = actionTypeID; // Determine SOP Class from presentation context OFString abstractSyntax, transferSyntax; findPresentationContext(pcid, abstractSyntax, transferSyntax); if (abstractSyntax.empty() || transferSyntax.empty()) return DIMSE_NOVALIDPRESENTATIONCONTEXTID; OFStandard::strlcpy(actionReq.RequestedSOPClassUID, abstractSyntax.c_str(), sizeof(actionReq.RequestedSOPClassUID)); OFStandard::strlcpy(actionReq.RequestedSOPInstanceUID, sopInstanceUID.c_str(), sizeof(actionReq.RequestedSOPInstanceUID)); // Send request DCMNET_INFO("Sending N-ACTION Request (MsgID " << actionReq.MessageID << ")"); cond = sendDIMSEMessage(pcid, &request, reqDataset); if (cond.bad()) { DCMNET_ERROR("Failed sending N-ACTION request: " << DimseCondition::dump(tempStr, cond)); return cond; } // Receive response T_DIMSE_Message response; cond = receiveDIMSECommand(&pcid, &response, &statusDetail, NULL /* commandSet */); if (cond.bad()) { DCMNET_ERROR("Failed receiving DIMSE response: " << DimseCondition::dump(tempStr, cond)); return cond; } // Check command set if (response.CommandField == DIMSE_N_ACTION_RSP) { DCMNET_INFO("Received N-ACTION Response (" << DU_nactionStatusString(response.msg.NActionRSP.DimseStatus) << ")"); } else { DCMNET_ERROR("Expected N-ACTION response but received DIMSE command 0x" << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4) << OFstatic_cast(unsigned int, response.CommandField)); DCMNET_DEBUG(DIMSE_dumpMessage(tempStr, response, DIMSE_INCOMING, NULL, pcid)); delete statusDetail; return DIMSE_BADCOMMANDTYPE; } if (statusDetail != NULL) { DCMNET_DEBUG("Response has status detail:" << OFendl << DcmObject::PrintHelper(*statusDetail)); delete statusDetail; } // Set return value T_DIMSE_N_ActionRSP &actionRsp = response.msg.NActionRSP; rspStatusCode = actionRsp.DimseStatus; // Check whether there is a dataset to be received if (actionRsp.DataSetType == DIMSE_DATASET_PRESENT) { // this should never happen DcmDataset *tempDataset = NULL; T_ASC_PresentationContextID tempID; DCMNET_WARN("Trying to retrieve unexpected dataset in N-ACTION response"); cond = receiveDIMSEDataset(&tempID, &tempDataset); if (cond.good()) { DCMNET_WARN("Received unexpected dataset after N-ACTION response, ignoring"); delete tempDataset; } else { return DIMSE_BADDATA; } } if (actionRsp.MessageIDBeingRespondedTo != actionReq.MessageID) { // since we only support synchronous communication, the message ID in the response // should be identical to the one in the request DCMNET_ERROR("Received response with wrong message ID (" << actionRsp.MessageIDBeingRespondedTo << " instead of " << actionReq.MessageID << ")"); return DIMSE_BADMESSAGE; } return cond; } /* ************************************************************************* */ /* N-EVENT REPORT functionality */ /* ************************************************************************* */ // Sends N-EVENT-REPORT request and receives N-EVENT-REPORT response OFCondition DcmSCU::sendEVENTREPORTRequest(const T_ASC_PresentationContextID presID, const OFString &sopInstanceUID, const Uint16 eventTypeID, DcmDataset *reqDataset, Uint16 &rspStatusCode) { // Do some basic validity checks if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; if (sopInstanceUID.empty() || (reqDataset == NULL)) return DIMSE_NULLKEY; // Prepare DIMSE data structures for issuing request OFCondition cond; OFString tempStr; T_ASC_PresentationContextID pcid = presID; T_DIMSE_Message request; T_DIMSE_N_EventReportRQ &eventReportReq = request.msg.NEventReportRQ; DcmDataset *statusDetail = NULL; request.CommandField = DIMSE_N_EVENT_REPORT_RQ; // Generate a new message ID eventReportReq.MessageID = nextMessageID(); eventReportReq.DataSetType = DIMSE_DATASET_PRESENT; eventReportReq.EventTypeID = eventTypeID; // Determine SOP Class from presentation context OFString abstractSyntax, transferSyntax; findPresentationContext(pcid, abstractSyntax, transferSyntax); if (abstractSyntax.empty() || transferSyntax.empty()) return DIMSE_NOVALIDPRESENTATIONCONTEXTID; OFStandard::strlcpy(eventReportReq.AffectedSOPClassUID, abstractSyntax.c_str(), sizeof(eventReportReq.AffectedSOPClassUID)); OFStandard::strlcpy(eventReportReq.AffectedSOPInstanceUID, sopInstanceUID.c_str(), sizeof(eventReportReq.AffectedSOPInstanceUID)); // Send request DCMNET_INFO("Sending N-EVENT-REPORT Request (MsgID " << eventReportReq.MessageID << ")"); cond = sendDIMSEMessage(pcid, &request, reqDataset); if (cond.bad()) { DCMNET_ERROR("Failed sending N-EVENT-REPORT request: " << DimseCondition::dump(tempStr, cond)); return cond; } // Receive response T_DIMSE_Message response; cond = receiveDIMSECommand(&pcid, &response, &statusDetail, NULL /* commandSet */); if (cond.bad()) { DCMNET_ERROR("Failed receiving DIMSE response: " << DimseCondition::dump(tempStr, cond)); return cond; } // Check command set if (response.CommandField == DIMSE_N_EVENT_REPORT_RSP) { DCMNET_INFO("Received N-EVENT-REPORT Response (" << DU_neventReportStatusString(response.msg.NEventReportRSP.DimseStatus) << ")"); } else { DCMNET_ERROR("Expected N-EVENT-REPORT response but received DIMSE command 0x" << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4) << OFstatic_cast(unsigned int, response.CommandField)); DCMNET_DEBUG(DIMSE_dumpMessage(tempStr, response, DIMSE_INCOMING, NULL, pcid)); delete statusDetail; return DIMSE_BADCOMMANDTYPE; } if (statusDetail != NULL) { DCMNET_DEBUG("Response has status detail:" << OFendl << DcmObject::PrintHelper(*statusDetail)); delete statusDetail; } // Set return value T_DIMSE_N_EventReportRSP &eventReportRsp = response.msg.NEventReportRSP; rspStatusCode = eventReportRsp.DimseStatus; // Check whether there is a dataset to be received if (eventReportRsp.DataSetType == DIMSE_DATASET_PRESENT) { // this should never happen DcmDataset *tempDataset = NULL; T_ASC_PresentationContextID tempID; cond = receiveDIMSEDataset(&tempID, &tempDataset); if (cond.good()) { DCMNET_WARN("Received unexpected dataset after N-EVENT-REPORT response, ignoring"); delete tempDataset; } else { DCMNET_ERROR("Failed receiving unexpected dataset after N-EVENT-REPORT response: " << DimseCondition::dump(tempStr, cond)); return DIMSE_BADDATA; } } // Check whether the message ID being responded to is equal to the message ID of the request if (eventReportRsp.MessageIDBeingRespondedTo != eventReportReq.MessageID) { DCMNET_ERROR("Received response with wrong message ID (" << eventReportRsp.MessageIDBeingRespondedTo << " instead of " << eventReportReq.MessageID << ")"); return DIMSE_BADMESSAGE; } return cond; } // Receives N-EVENT-REPORT request OFCondition DcmSCU::handleEVENTREPORTRequest(DcmDataset *&reqDataset, Uint16 &eventTypeID, const int timeout) { // Do some basic validity checks if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; OFCondition cond; OFString tempStr; T_ASC_PresentationContextID presID; T_ASC_PresentationContextID presIDdset; T_DIMSE_Message request; T_DIMSE_N_EventReportRQ &eventReportReq = request.msg.NEventReportRQ; DcmDataset *dataset = NULL; DcmDataset *statusDetail = NULL; Uint16 statusCode = 0; if (timeout > 0) DCMNET_DEBUG("Handle N-EVENT-REPORT request, waiting up to " << timeout << " seconds (only for N-EVENT-REPORT message)"); else if ((m_dimseTimeout > 0) && (m_blockMode == DIMSE_NONBLOCKING)) DCMNET_DEBUG("Handle N-EVENT-REPORT request, waiting up to " << m_dimseTimeout << " seconds (default for all DIMSE messages)"); else DCMNET_DEBUG("Handle N-EVENT-REPORT request, waiting an unlimited period of time"); // Receive request, use specific timeout (if defined) cond = receiveDIMSECommand(&presID, &request, &statusDetail, NULL /* commandSet */, timeout); if (cond.bad()) { if (cond != DIMSE_NODATAAVAILABLE) DCMNET_ERROR("Failed receiving DIMSE request: " << DimseCondition::dump(tempStr, cond)); return cond; } // Check command set if (request.CommandField == DIMSE_N_EVENT_REPORT_RQ) { DCMNET_INFO("Received N-EVENT-REPORT Request (MsgID " << eventReportReq.MessageID << ")"); } else { DCMNET_DEBUG(DIMSE_dumpMessage(tempStr, request, DIMSE_INCOMING, NULL, presID)); DCMNET_ERROR("Expected N-EVENT-REPORT request but received DIMSE command 0x" << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4) << OFstatic_cast(unsigned int, request.CommandField)); delete statusDetail; return DIMSE_BADCOMMANDTYPE; } if (statusDetail != NULL) { DCMNET_DEBUG("Request has status detail:" << OFendl << DcmObject::PrintHelper(*statusDetail)); delete statusDetail; } // Check if dataset is announced correctly if (eventReportReq.DataSetType == DIMSE_DATASET_NULL) { DCMNET_DEBUG(DIMSE_dumpMessage(tempStr, request, DIMSE_INCOMING, NULL, presID)); DCMNET_ERROR("Received N-EVENT-REPORT request but no dataset announced, aborting"); return DIMSE_BADMESSAGE; } // Receive dataset cond = receiveDIMSEDataset(&presIDdset, &dataset); if (cond.bad()) { DCMNET_DEBUG(DIMSE_dumpMessage(tempStr, request, DIMSE_INCOMING, NULL, presID)); return DIMSE_BADDATA; } // Output dataset only if trace level is enabled DCMNET_DEBUG(DIMSE_dumpMessage(tempStr, request, DIMSE_INCOMING, NULL, presID)); // Compare presentation context ID of command and data set if (presIDdset != presID) { DCMNET_ERROR("Presentation Context ID of command (" << OFstatic_cast(unsigned int, presID) << ") and data set (" << OFstatic_cast(unsigned int, presIDdset) << ") differ"); delete dataset; return makeDcmnetCondition(DIMSEC_INVALIDPRESENTATIONCONTEXTID, OF_error, "DIMSE: Presentation Contexts of Command and Data Set differ"); } // Check the request dataset and return the DIMSE status code to be used statusCode = checkEVENTREPORTRequest(eventReportReq, dataset); // Send back response T_DIMSE_Message response; T_DIMSE_N_EventReportRSP &eventReportRsp = response.msg.NEventReportRSP; response.CommandField = DIMSE_N_EVENT_REPORT_RSP; eventReportRsp.MessageIDBeingRespondedTo = eventReportReq.MessageID; eventReportRsp.DimseStatus = statusCode; eventReportRsp.DataSetType = DIMSE_DATASET_NULL; eventReportRsp.opts = 0; eventReportRsp.AffectedSOPClassUID[0] = 0; eventReportRsp.AffectedSOPInstanceUID[0] = 0; DCMNET_INFO("Sending N-EVENT-REPORT Response (" << DU_neventReportStatusString(statusCode) << ")"); cond = sendDIMSEMessage(presID, &response, NULL /*dataObject*/); if (cond.bad()) { DCMNET_ERROR("Failed sending N-EVENT-REPORT response: " << DimseCondition::dump(tempStr, cond)); delete dataset; return cond; } // Set return values reqDataset = dataset; eventTypeID = eventReportReq.EventTypeID; return cond; } Uint16 DcmSCU::checkEVENTREPORTRequest(T_DIMSE_N_EventReportRQ & /*eventReportReq*/, DcmDataset * /*reqDataset*/) { // we default to success return STATUS_Success; } /* ************************************************************************* */ /* General message handling */ /* ************************************************************************* */ void DcmSCU::notifySENDProgress(const unsigned long byteCount) { DCMNET_TRACE("Bytes sent: " << byteCount); } void DcmSCU::notifyRECEIVEProgress(const unsigned long byteCount) { DCMNET_TRACE("Bytes received: " << byteCount); } /* ************************************************************************* */ /* Various helpers */ /* ************************************************************************* */ // Sends a DIMSE command and possibly also instance data to the configured peer DICOM application OFCondition DcmSCU::sendDIMSEMessage(const T_ASC_PresentationContextID presID, T_DIMSE_Message *msg, DcmDataset *dataObject, DcmDataset **commandSet) { if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; if (msg == NULL) return DIMSE_NULLKEY; OFCondition cond; /* call the corresponding DIMSE function to send the message */ if (m_progressNotificationMode) { cond = DIMSE_sendMessageUsingMemoryData(m_assoc, presID, msg, NULL /*statusDetail*/, dataObject, callbackSENDProgress, this /*callbackData*/, commandSet); } else { cond = DIMSE_sendMessageUsingMemoryData(m_assoc, presID, msg, NULL /*statusDetail*/, dataObject, NULL /*callback*/, NULL /*callbackData*/, commandSet); } #if 0 // currently disabled because it is not (yet) needed if (cond.good()) { /* create a copy of the current DIMSE command message */ delete m_openDIMSERequest; m_openDIMSERequest = new T_DIMSE_Message; memcpy((char*)m_openDIMSERequest, msg, sizeof(*m_openDIMSERequest)); } #endif return cond; } // Receive DIMSE command (excluding dataset!) over the currently open association OFCondition DcmSCU::receiveDIMSECommand(T_ASC_PresentationContextID *presID, T_DIMSE_Message *msg, DcmDataset **statusDetail, DcmDataset **commandSet, const Uint32 timeout) { if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; OFCondition cond; if (timeout > 0) { /* call the corresponding DIMSE function to receive the command (use specified timeout)*/ cond = DIMSE_receiveCommand(m_assoc, DIMSE_NONBLOCKING, timeout, presID, msg, statusDetail, commandSet); } else { /* call the corresponding DIMSE function to receive the command (use default timeout) */ cond = DIMSE_receiveCommand(m_assoc, m_blockMode, m_dimseTimeout, presID, msg, statusDetail, commandSet); } return cond; } // Receives one dataset (of instance data) via network from another DICOM application OFCondition DcmSCU::receiveDIMSEDataset(T_ASC_PresentationContextID *presID, DcmDataset **dataObject) { if (!isConnected()) return DIMSE_ILLEGALASSOCIATION; OFCondition cond; /* call the corresponding DIMSE function to receive the dataset */ if (m_progressNotificationMode) { cond = DIMSE_receiveDataSetInMemory(m_assoc, m_blockMode, m_dimseTimeout, presID, dataObject, callbackRECEIVEProgress, this /*callbackData*/); } else { cond = DIMSE_receiveDataSetInMemory(m_assoc, m_blockMode, m_dimseTimeout, presID, dataObject, NULL /*callback*/, NULL /*callbackData*/); } if (cond.good()) { DCMNET_DEBUG("Received dataset on presentation context " << OFstatic_cast(unsigned int, *presID)); } else { OFString tempStr; DCMNET_ERROR("Unable to receive dataset on presentation context " << OFstatic_cast(unsigned int, *presID) << ": " << DimseCondition::dump(tempStr, cond)); } return cond; } void DcmSCU::setMaxReceivePDULength(const unsigned long maxRecPDU) { m_maxReceivePDULength = maxRecPDU; } void DcmSCU::setDIMSEBlockingMode(const T_DIMSE_BlockingMode blockingMode) { m_blockMode = blockingMode; } void DcmSCU::setAETitle(const OFString &myAETtitle) { m_ourAETitle = myAETtitle; } void DcmSCU::setPeerHostName(const OFString &peerHostName) { m_peer = peerHostName; } void DcmSCU::setPeerAETitle(const OFString &peerAETitle) { m_peerAETitle = peerAETitle; } void DcmSCU::setPeerPort(const Uint16 peerPort) { m_peerPort = peerPort; } void DcmSCU::setDIMSETimeout(const Uint32 dimseTimeout) { m_dimseTimeout = dimseTimeout; } void DcmSCU::setACSETimeout(const Uint32 acseTimeout) { m_acseTimeout = acseTimeout; } void DcmSCU::setAssocConfigFileAndProfile(const OFString &filename, const OFString &profile) { m_assocConfigFilename = filename; m_assocConfigProfile = profile; } void DcmSCU::setStorageDir(const OFString& storeDir) { m_storageDir = storeDir; } void DcmSCU::setStorageMode(const DcmStorageMode storageMode) { m_storageMode = storageMode; } void DcmSCU::setVerbosePCMode(const OFBool mode) { m_verbosePCMode = mode; } void DcmSCU::setDatasetConversionMode(const OFBool mode) { m_datasetConversionMode = mode; } void DcmSCU::setProgressNotificationMode(const OFBool mode) { m_progressNotificationMode = mode; } /* Get methods */ OFBool DcmSCU::isConnected() const { return (m_assoc != NULL) && (m_assoc->DULassociation != NULL); } Uint32 DcmSCU::getMaxReceivePDULength() const { return m_maxReceivePDULength; } OFBool DcmSCU::getTLSEnabled() const { return OFFalse; } T_DIMSE_BlockingMode DcmSCU::getDIMSEBlockingMode() const { return m_blockMode; } const OFString &DcmSCU::getAETitle() const { return m_ourAETitle; } const OFString &DcmSCU::getPeerHostName() const { return m_peer; } const OFString &DcmSCU::getPeerAETitle() const { return m_peerAETitle; } Uint16 DcmSCU::getPeerPort() const { return m_peerPort; } Uint32 DcmSCU::getDIMSETimeout() const { return m_dimseTimeout; } Uint32 DcmSCU::getACSETimeout() const { return m_acseTimeout; } OFString DcmSCU::getStorageDir() const { return m_storageDir; } DcmStorageMode DcmSCU::getStorageMode() const { return m_storageMode; } OFBool DcmSCU::getVerbosePCMode() const { return m_verbosePCMode; } OFBool DcmSCU::getDatasetConversionMode() const { return m_datasetConversionMode; } OFBool DcmSCU::getProgressNotificationMode() const { return m_progressNotificationMode; } OFCondition DcmSCU::getDatasetInfo(DcmDataset *dataset, OFString &sopClassUID, OFString &sopInstanceUID, E_TransferSyntax &transferSyntax) { OFCondition status = EC_IllegalParameter; sopClassUID.clear(); sopInstanceUID.clear(); transferSyntax = EXS_Unknown; if (dataset != NULL) { // ignore returned condition codes (e.g. EC_TagNotFound) dataset->findAndGetOFString(DCM_SOPClassUID, sopClassUID); dataset->findAndGetOFString(DCM_SOPInstanceUID, sopInstanceUID); transferSyntax = dataset->getOriginalXfer(); // check return values for validity if (sopClassUID.empty()) status = NET_EC_InvalidSOPClassUID; else if (sopInstanceUID.empty()) status = NET_EC_InvalidSOPInstanceUID; else if (transferSyntax == EXS_Unknown) status = NET_EC_UnknownTransferSyntax; else status = EC_Normal; } return status; } /* ************************************************************************* */ /* Callback functions */ /* ************************************************************************* */ void DcmSCU::callbackSENDProgress(void *callbackContext, const unsigned long byteCount) { if (callbackContext != NULL) OFreinterpret_cast(DcmSCU *, callbackContext)->notifySENDProgress(byteCount); } void DcmSCU::callbackRECEIVEProgress(void *callbackContext, const unsigned long byteCount) { if (callbackContext != NULL) OFreinterpret_cast(DcmSCU *, callbackContext)->notifyRECEIVEProgress(byteCount); } /* ************************************************************************* */ /* class RetrieveResponse */ /* ************************************************************************* */ void RetrieveResponse::print() { DCMNET_INFO(" Number of Remaining Suboperations : " << m_numberOfRemainingSubops); DCMNET_INFO(" Number of Completed Suboperations : " << m_numberOfCompletedSubops); DCMNET_INFO(" Number of Failed Suboperations : " << m_numberOfFailedSubops); DCMNET_INFO(" Number of Warning Suboperations : " << m_numberOfWarningSubops); } /* ** CVS Log ** $Log: scu.cc,v $ ** Revision 1.60 2012-05-14 10:42:54 onken ** Enhanced handling of error codes for C-GET (added explicit support for ** missing code Ax702 and enhanced recognition of customized 0xCxxx codes.) ** ** Revision 1.59 2012-02-21 08:48:54 joergr ** Added support for progress notifications while sending and receiving DICOM ** datasets. ** ** Revision 1.58 2011-10-10 14:01:29 uli ** Moved SCU-specific error condition to the correct place. ** ** Revision 1.57 2011-10-04 08:58:16 joergr ** Added flag that allows for specifying whether to convert a dataset to be ** transferred to the network transfer syntax. Also removed unused parameters ** "rspCommandSet" and "rspStatusDetail" from method sendSTORERequest(). ** ** Revision 1.56 2011-09-29 17:12:03 joergr ** Fixed memory leak in sendSTORERequest(), a DICOM dataset was not deleted. ** ** Revision 1.55 2011-09-29 13:12:01 joergr ** Introduced new network-related error codes, e.g. in case that none of the ** proposed presentation contexts were accepted by the association acceptor. ** ** Revision 1.54 2011-09-29 13:04:09 joergr ** Added check whether the presentation context specified by the caller of the ** method was really accepted before sending a C-STORE request. ** ** Revision 1.53 2011-09-29 12:56:21 joergr ** Enhanced implementation of the function that retrieves the abstract syntax ** and transfer syntax of a particular presentation context (using the ID). ** ** Revision 1.52 2011-09-29 09:04:26 joergr ** Output message ID of request and DIMSE status of response messages to the ** INFO logger (if DEBUG level is not enabled). All tools and classes in the ** "dcmnet" module now use (more or less) the same output in verbose mode. ** ** Revision 1.51 2011-09-28 16:28:18 joergr ** Added general support for transfer syntax conversions to sendSTORERequest(). ** ** Revision 1.50 2011-09-28 15:25:36 joergr ** Return a more appropriate error code in case the dataset to be sent is ** invalid. This also required to introduce a return value for getDatasetInfo(). ** ** Revision 1.49 2011-09-28 14:37:01 joergr ** Output the DIMSE status in verbose mode (if debug mode is not enabled). ** ** Revision 1.48 2011-09-28 13:31:54 joergr ** Added method that allows for clearing the list of presentation contexts. ** ** Revision 1.47 2011-09-23 15:27:02 joergr ** Removed needless deletion of the "statusDetail" variable. ** ** Revision 1.46 2011-09-16 09:38:40 joergr ** Fixed some typos and other small inconsistencies. ** ** Revision 1.45 2011-09-06 16:12:53 ogazzar ** Fixed typos in a log commit message. ** ** Revision 1.44 2011-09-06 14:15:10 ogazzar ** Fixed wrong logger name which caused compiler error. ** ** Revision 1.43 2011-09-06 12:58:35 ogazzar ** Added a function to send N-EVENT-REPORT request and to receive a response. ** ** Revision 1.42 2011-08-25 15:46:20 joergr ** Further cleanup of minor inconsistencies regarding documentation, parameter ** names, log output and handling of status details information. ** ** Revision 1.41 2011-08-25 15:05:09 joergr ** Changed data structure for Q/R responses from OFVector to OFList. Also fixed ** some possible memory leaks and made the FIND/MOVE/GET code more consistent. ** ** Revision 1.40 2011-08-25 13:49:31 joergr ** Fixed minor issues in the documentation, parameter and method names. Output ** retrieve responses to main dcmnet logger instead of response logger. ** ** Revision 1.39 2011-08-25 09:31:35 onken ** Added C-GET functionality to DcmSCU class and accompanying getscu ** commandline application. ** ** Revision 1.38 2011-08-24 11:50:48 joergr ** Uncommented name of unused method parameter that caused a compiler warning. ** ** Revision 1.37 2011-07-06 11:08:48 uli ** Fixed various compiler warnings. ** ** Revision 1.36 2011-06-29 16:33:45 joergr ** Fixed various issues that are reported when compiled with "gcc -Weffc++". ** ** Revision 1.35 2011-06-01 15:04:29 onken ** Removed unused status variable from C-ECHO code. ** ** Revision 1.34 2011-05-30 20:10:44 onken ** Added dump of query/move keys in debug mode when sending C-FIND or C-MOVE. ** ** Revision 1.33 2011-05-27 10:12:18 joergr ** Fixed typos and source code formatting. ** ** Revision 1.32 2011-05-25 09:56:52 ogazzar ** Renamed a function name. ** ** Revision 1.31 2011-05-25 09:31:53 ogazzar ** Added a function to look for a presentation context ID that best matches the ** abstract syntax UID and the transfer syntax UID. ** ** Revision 1.30 2011-05-24 08:38:39 ogazzar ** Added role selection negotiation while adding a presenation context. ** ** Revision 1.29 2011-05-19 17:19:52 onken ** Fixed some documentation. Added some extra checks for NULL when handling MOVE ** and FIND responses. Simplified destructors for FIND and MOVEResponses. ** ** Revision 1.28 2011-05-19 10:51:20 onken ** Simplified C string copy by using OFStandard::strlcpy and removed debugging ** code introduced with last comit. ** ** Revision 1.27 2011-05-19 10:37:44 onken ** Removed unused variable that caused compiler warning. Fixed typo. ** ** Revision 1.26 2011-05-19 09:57:24 onken ** Fixed message ID field in C-CANCEL request (should be the one of last ** request). In case of error status codes in C-MOVE responses, the default ** behaviour is now to not wait for further responses. Fixed log output level ** to better fit the messages while receiveing C-MOVE responses. Minor ** code and comment cleanups. Renamed function parameter in sendMOVEREquest ** to better reflect the standard. ** ** Revision 1.25 2011-05-19 08:08:30 onken ** Fixed wrong usage of strlcpy in new C-CANCEL function. ** ** Revision 1.24 2011-05-17 14:26:19 onken ** Implemented C-CANCEL message. Fixed some minor formatting issues. ** Changed C-ECHO implementation to rely on sendDIMSEMesage as the other ** DIMSE functions do. Changed some public function arguments to const to be ** more correct. Fixed CVS log at the end of the scu.cc file. ** ** Revision 1.23 2011-04-28 17:50:05 onken ** Re-sorted header list to make scu.h come first (after osconfig.h). ** Protected public networking functions for creating an association ** from being called twice. Enhanced protection of DIMSE messaging ** functions from being called without being connected. Introduced ** status detail into C-FIND responses (and C-MOVE responses). Was ** not accessible to the caller before. Minor code cleanups. Added ** C-MOVE code for retrieving DICOM objects. So far only retrieving ** on a separate connection is supported. Added function for cleaning ** up internal memory from destructor. This function also fixes a ** memory leak in case users call initNetwork more than one time. ** Added error code returned by functions if SCU is already connected. ** ** Revision 1.22 2011-04-18 07:01:03 uli ** Use global variables for the logger objects. This removes the thread-unsafe ** static local variables which were used before. ** ** Revision 1.21 2011-04-05 11:16:13 joergr ** Output DIMSE status code in hexadecimal format to the logger. Removed unused ** code (local half-implemented function). Added more comments. ** ** Revision 1.20 2011-03-09 11:13:28 onken ** Enhanced error message for missing data in store request. ** ** Revision 1.19 2011-02-23 08:11:51 joergr ** Fixed issue with undefined priority field in C-STORE and C-FIND request. ** ** Revision 1.18 2011-02-16 08:55:17 joergr ** Fixed issue in sendSTORERequest() when sending a dataset that was created ** in memory (and which has, therefore, an original transfer of EXS_Unknown). ** ** Revision 1.17 2011-02-04 12:57:40 uli ** Made sure all members are initialized in the constructor (-Weffc++). ** ** Revision 1.16 2010-12-21 09:37:36 onken ** Fixed wrong response assignment in DcmSCU's C-STORE code. Thanks to ** forum user "takeos" for the hint and fix. ** ** Revision 1.15 2010-10-20 07:41:36 uli ** Made sure isalpha() & friends are only called with valid arguments. ** ** Revision 1.14 2010-10-14 13:14:29 joergr ** Updated copyright header. Added reference to COPYRIGHT file. ** ** Revision 1.13 2010-10-01 12:25:29 uli ** Fixed most compiler warnings in remaining modules. ** ** Revision 1.12 2010-08-10 11:59:32 uli ** Fixed some cases where dcmFindNameOfUID() returning NULL could cause crashes. ** ** Revision 1.11 2010-06-24 09:26:57 joergr ** Added check on whether the presentation context ID of command and data set are ** identical. Made sure that received dataset is deleted when an error occurs. ** Used more appropriate error conditions / return codes. Further code cleanup. ** ** Revision 1.10 2010-06-22 15:48:53 joergr ** Introduced new enumeration type to be used for closeAssociation(). ** Further code cleanup. Renamed some methods, variables, types and so on. ** ** Revision 1.9 2010-06-18 14:58:01 joergr ** Changed some error conditions / return codes to more appropriate values. ** Further revised logging output. Use DimseCondition::dump() where appropriate. ** ** Revision 1.8 2010-06-17 17:13:06 joergr ** Added preliminary support for N-EVENT-REPORT to DcmSCU. Some further code ** cleanups and enhancements. Renamed some methods. Revised documentation. ** ** Revision 1.7 2010-06-09 16:33:34 joergr ** Added preliminary support for N-ACTION to DcmSCU. Some further code cleanups ** and enhancements. ** ** Revision 1.6 2010-06-08 17:54:14 onken ** Added C-FIND functionality to DcmSCU. Some code cleanups. Fixed ** memory leak sometimes occuring during association configuration. ** ** Revision 1.5 2010-06-02 16:01:49 joergr ** Slightly modified some log messages and levels for reasons of consistency. ** Use type cast macros (e.g. OFstatic_cast) where appropriate. ** ** Revision 1.4 2010-04-29 16:13:25 onken ** Made SCU class independent from dcmtls, i.e. outsourced TLS API. Added ** direct API support for sending C-STORE requests. Further API changes and ** some bugs fixed. ** ** Revision 1.3 2009-12-21 15:33:58 onken ** Added documentation and refactored / enhanced some code. ** ** Revision 1.2 2009-12-17 09:12:27 onken ** Fixed other scu and scp base class compile issues. ** ** Revision 1.1 2009-12-16 17:05:35 onken ** Added base classes for SCU and SCP implementation. ** ** Revision 1.5 2009-12-02 14:26:05 uli ** Stop including dcdebug.h which was removed. ** ** Revision 1.4 2009-11-18 12:37:28 uli ** Fix compiler errors due to removal of DUL_Debug() and DIMSE_Debug(). ** ** Revision 1.3 2009-01-08 18:25:34 joergr ** Replaced further OFListIterator() by OFListConstIterator() in order to ** compile when STL list classes are used. ** ** Revision 1.2 2009-01-08 13:33:31 joergr ** Replaced OFListIterator() by OFListConstIterator() in order to compile when ** STL list classes are used. ** ** Revision 1.1 2008-09-29 13:51:55 onken ** Initial checkin of module dcmppscu implementing an MPPS commandline client. ** */ odil-0.4.1/tests/tools/scu.h000066400000000000000000001627411266460524100157310ustar00rootroot00000000000000/* * * Copyright (C) 2008-2012, OFFIS e.V. * All rights reserved. See COPYRIGHT file for details. * * This software and supporting documentation were developed by * * OFFIS e.V. * R&D Division Health * Escherweg 2 * D-26121 Oldenburg, Germany * * * Module: dcmnet * * Author: Michael Onken * * Purpose: Base class for Service Class Users (SCUs) * * Last Update: $Author: joergr $ * Update Date: $Date: 2012-02-21 08:48:51 $ * CVS/RCS Revision: $Revision: 1.41 $ * Status: $State: Exp $ * * CVS/RCS Log at end of file * */ #ifndef SCU_H #define SCU_H #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ #include "dcmtk/dcmdata/dctk.h" /* Covers most common dcmdata classes */ #include "dcmtk/dcmnet/dcompat.h" #include "dcmtk/dcmnet/dimse.h" /* DIMSE network layer */ #include "dcmtk/dcmnet/dcasccff.h" /* For reading a association config file */ #include "dcmtk/dcmnet/dcasccfg.h" /* For holding association config file infos */ #include "dcmtk/ofstd/oflist.h" // MODIFICATION: Use local header file #include "dndefine.h" // END Modification /** Different types of closing an association */ enum DcmCloseAssociationType { /// Release the current association DCMSCU_RELEASE_ASSOCIATION, /// Abort the current association DCMSCU_ABORT_ASSOCIATION, /// Peer requested release (Aborting) DCMSCU_PEER_REQUESTED_RELEASE, /// Peer aborted the association DCMSCU_PEER_ABORTED_ASSOCIATION }; /** Storage mode used for DICOM objects received via C-STORE */ enum DcmStorageMode { /// Ignore any objects received via C-STORE DCMSCU_STORAGE_IGNORE, /// Try to store the objects to disk DCMSCU_STORAGE_DISK, /// Try to store to disk in bit-preserving mode. This is especially useful /// for huge files that cannot fully be received in memory since the /// data is directly streamed to disk. Originally, this was introduced for /// DICOM signatures which can be kept valid this way. DCMSCU_STORAGE_BIT_PRESERVING }; /** Base class for C-FIND, C-MOVE and C-GET responses */ class DCMTK_DCMNET_EXPORT QRResponse { public: /** Standard constructor. */ QRResponse() : m_messageIDRespondedTo(0), m_affectedSOPClassUID(), m_dataset(NULL), m_status(0), m_statusDetail(NULL) {} /** Destructor, cleans up internal memory (dataset if present). */ virtual ~QRResponse() { delete m_dataset; delete m_statusDetail; } /// The message ID responded to (mandatory response field, /// equals message ID from request) Uint16 m_messageIDRespondedTo; /// Optional response field according to part 7 of the standard /// If present, equals SOP Class UID from request. OFString m_affectedSOPClassUID; /// Conditional response field (NULL if absent). From the standard (2009, /// part 4, C.4.2.1.4.2), for C-MOVE: In Q/R if no C-STORE sub-operation /// failed, Failed SOP Instance UID List (0008,0058) is absent and /// therefore no Data Set shall be sent in the C-MOVE response. Further /// rules: Statuses of Canceled, Failure, Refused, or Warning shall /// contain the Failed SOP Instance UID List Attribute; status of /// Pending shall not. DcmDataset *m_dataset; /// The returned DIMSE status (mandatory Response Field) Uint16 m_status; /// Status detail (NULL if absent). For some DIMSE return status codes, /// an additional dataset is sent which gives further information (i.e. /// in case of warnings or errors). DcmDataset *m_statusDetail; private: /** Private undefined copy constructor. * @param other The find response to copy from */ QRResponse(const QRResponse& other); /** Private undefined assignment operator. * @param other The find response that should be assigned from */ QRResponse& operator=(const QRResponse& other); }; /// Base class representing for single C-GET or C-MOVE response class DCMTK_DCMNET_EXPORT RetrieveResponse : public QRResponse { public: /** Standard constructor */ RetrieveResponse() : m_numberOfRemainingSubops(0), m_numberOfCompletedSubops(0), m_numberOfFailedSubops(0), m_numberOfWarningSubops(0) {} /** Destructor, cleans up internal memory */ virtual ~RetrieveResponse() {} /** Prints response to INFO log level. */ void print(); /// Number of remaining sub operations (in Q/R: C-STORE calls). /// For Q/R MOVE and GET, for status of pending this field shall be filled. /// For others, the field may be filled. Uint16 m_numberOfRemainingSubops; /// Number of successfully completed sub operations (in Q/R: C-STORE calls). /// For Q/R MOVE and GET, for status of pending this field shall be filled. /// For others, the field may be filled. Uint16 m_numberOfCompletedSubops; /// Number of failed sub operations (in Q/R: C-STORE calls). /// For Q/R MOVE and GET, for status of pending this field shall be filled. /// For others, the field may be filled. Uint16 m_numberOfFailedSubops; /// Number generated warnings generated by sub operations (in Q/R: C-STORE calls). /// For Q/R MOVE and GET, for status of pending this field shall be filled. /// For others, the field may be filled. Uint16 m_numberOfWarningSubops; private: /** Private undefined copy constructor * @param other Response to copy from */ RetrieveResponse(const RetrieveResponse& other); /** Private undefined assignment operator * @param other Response that should be assigned from */ RetrieveResponse& operator=(const RetrieveResponse& other); }; /** Base class for implementing DICOM Service Class User functionality. The class offers * support for negotiating associations and sending and receiving arbitrary DIMSE messages * on that connection. DcmSCU has built-in C-ECHO support so derived classes do not have to * implement that capability on their own. * @warning This class is EXPERIMENTAL. Be careful to use it in production environment. */ class DCMTK_DCMNET_EXPORT DcmSCU { public: /** Constructor, just initializes internal class members */ DcmSCU(); /** Virtual destructor */ virtual ~DcmSCU(); /** Add presentation context to be used for association negotiation * @param abstractSyntax [in] Abstract syntax name in UID format * @param xferSyntaxes [in] List of transfer syntaxes to be added for the given abstract * syntax * @param role [in] The role to be negotiated * @return EC_Normal if adding was successful, otherwise error code */ OFCondition addPresentationContext(const OFString &abstractSyntax, const OFList &xferSyntaxes, const T_ASC_SC_ROLE role = ASC_SC_ROLE_DEFAULT); /** Initialize network, i.e.\ prepare for association negotiation. If the SCU is already * connected, the call will not be successful and the old connection keeps open. * @return EC_Normal if initialization was successful, otherwise error code. * NET_EC_AlreadyConnected if SCU is already connected. */ virtual OFCondition initNetwork(); /** Negotiate association by using presentation contexts and parameters as defined by * earlier function calls. If negotiation fails, there is no need to close the association * or to do anything else with this class. * @return EC_Normal if negotiation was successful, otherwise error code. * NET_EC_AlreadyConnected if SCU is already connected. */ virtual OFCondition negotiateAssociation(); /** After negotiation association, this call returns the first usable presentation context * given the desired abstract syntax and transfer syntax * @param abstractSyntax [in] The abstract syntax (UID) to look for * @param transferSyntax [in] The transfer syntax (UID) to look for. If empty, the transfer * syntax is not checked. * @return Adequate Presentation context ID that can be used. 0 if none found. */ T_ASC_PresentationContextID findPresentationContextID(const OFString &abstractSyntax, const OFString &transferSyntax); /** After a successful association negotiation, this function is called to return the * presentation context ID that best matches the desired abstract syntax and transfer * syntax (TS). The function tries to do the following: * - If possible finds a presentation context with matching TS * - Else then tries to find an explicit VR uncompressed TS presentation context * - Else then tries to find an implicit VR uncompressed TS presentation context * - Else finally accepts each matching presentation ctx independent of TS. * @param abstractSyntax [in] The abstract syntax (UID) to look for * @param transferSyntax [in] The transfer syntax (UID) to look for. If empty, the transfer * syntax is not checked. * @return Adequate Presentation context ID that can be used. 0 if no appropriate * presentation context could be found at all. */ T_ASC_PresentationContextID findAnyPresentationContextID(const OFString &abstractSyntax, const OFString &transferSyntax); /** This function sends a C-ECHO command via network to another DICOM application * @param presID [in] Presentation context ID to use. A value of 0 lets SCP class tries * to choose one on its own. * @return EC_Normal if echo was successful, an error code otherwise * */ virtual OFCondition sendECHORequest(const T_ASC_PresentationContextID presID); /** This function sends a C-STORE request on the currently opened association and receives * the corresponding response then. If required and supported, the dataset of the SOP * instance can be converted automatically to the network transfer syntax that was * negotiated (and is specified by the parameter 'presID'). However, this feature is * disabled by default. See setDatasetConversionMode() on how to enable it. * @param presID [in] Contains in the end the ID of the presentation context which * was specified in the DIMSE command. If 0 is given, the * function tries to find an approriate presentation context * itself (based on SOP class and original transfer syntax of * the 'dicomFile' or 'dataset'). * @param dicomFile [in] The filename of the DICOM file to be sent. Alternatively, a * dataset can be given in the next parameter. If both are given * the dataset from the file name is used. * @param dataset [in] The dataset to be sent. Alternatively, a filename can be * specified in the previous parameter. If both are given the * dataset from the filename is used. * @param rspStatusCode [out] The response status code received. 0 means success, others * can be found in the DICOM standard. * @return EC_Normal if request could be issued and response was received successfully, * error code otherwise. That means that if the receiver sends a response denoting * failure of the storage request, EC_Normal will be returned. */ virtual OFCondition sendSTORERequest(const T_ASC_PresentationContextID presID, const OFString &dicomFile, DcmDataset *dataset, Uint16 &rspStatusCode); /** Sends a C-MOVE Request on given presentation context and receives list of responses. * The function receives the first response and then calls the function handleMOVEResponse() * which gets the relevant presentation context together with the response dataset and * status information. Then it waits again for the next response, if there are more to * come (i.e. response status is PENDING). In the end, after receiving all responses, the * full list of responses is returned to the caller. If he is not interested, he just sets * responses=NULL when calling the function. * This function can be overwritten by actual SCU implementations but just should work fine * for most people. * @param presID [in] The presentation context ID that should be used. * Must be an odd number. * @param moveDestinationAETitle [in] The move destination's AE title, i.e.\ the one that * is used for connection to the storage server. * @param dataset [in] The dataset containing the information about the * object(s) to be retrieved. * @param responses [out] The incoming C-MOVE responses for this request. * The caller is responsible for providing a non-NULL * pointer for this case. After receiving the results, * the caller is responsible for freeing the memory of * this variable. If NULL is specified, the responses * will not bereturned to the caller. * @return EC_Normal if everything went fine, i.e.\ if request could be send and responses * (with whatever status) could be received. */ virtual OFCondition sendMOVERequest(const T_ASC_PresentationContextID presID, const OFString &moveDestinationAETitle, DcmDataset *dataset, OFList *responses); /** This is the standard handler for C-MOVE message responses: It just adds up all responses * it receives and prints a DEBUG message. Therefore, it is called for each response * received in sendMOVERequest(). The idea is of course to overwrite this function in a * derived, actual SCU implementation if required. Thus, after each response, the caller of * sendMOVERequest() can decide on its own whether he wants to cancel the C-MOVE session, * terminate the association, do something useful or whatever. Thus this function is a more * object-oriented kind of callback. * @param presID [in] The presentation context ID where the response was * received on. * @param response [in] The C-MOVE response received. * @param waitForNextResponse [out] Denotes whether SCU should try to receive another * response. If set to OFTrue, then sendMOVERequest() will * continue waiting for responses. The current * implementation does that for all responses do not have * status Failed, Warning, Success or unknown. If set to * OFFalse, sendMOVERequest() will return control to the * caller. * @return EC_Normal, if response could be handled. Error code otherwise. * The current implementation always returns EC_Normal. */ virtual OFCondition handleMOVEResponse(const T_ASC_PresentationContextID presID, RetrieveResponse *response, OFBool &waitForNextResponse); /** Sends a C-GET Request on given presentation context and receives list of responses. It * then switches control to the function handleCGETSession(). * The full list of responses is returned to the caller. If he is not interested, he can * set responses=NULL when calling the function. * This function can be overwritten by actual SCU implementations but just should work fine * for most people. * @param presID [in] The presentation context ID that should be used. Must be an odd * number. * @param dataset [in] The dataset containing the information about the * object(s) to be retrieved * @param responses [out] The incoming C-GET responses for this request. If the caller * specifies NULL, no responses will be returned; otherwise there * should be at least one final C-GET response (mandatory). C-GET * responses after each DICOM object received are optional and may * have been ommitted by the server. * @return EC_Normal if everything went fine, i.e.\ if request could be sent and expected * responses (with whatever status) could be received. */ virtual OFCondition sendCGETRequest(const T_ASC_PresentationContextID presID, DcmDataset *dataset, OFList *responses); /** Does the logic for switching between C-GET Response and C-STORE Requests. Sends a C-GET * Request on given presentation context and receives list of responses. Ihe full list of * responses is returned to the caller. If he is not interested, he can set responses=NULL * when calling the function. After sending a C-GET Request, there might be two different * responses coming in: C-GET-RSP (optional after each received object and mandatory after * the last object) or a mandatory C-STORE for each incoming object that is received due to * the request. This function therefore either calls handleCGETResponse() or * handleSTORERequest() in order to deal with the incoming message. All other messages lead * to an error within this handler. * This function can be overwritten by actual SCU implementations but just should work fine * for most people. * @param presID [in] The presentation context ID that should be used. Must be an odd * number. * @param dataset [in] The dataset containing the information about the object(s) to be * retrieved * @param responses [out] The incoming C-GET responses for this request. If the caller * specifies NULL, no responses will be returned; otherwise there * should be at least one final C-GET response (mandatory). C-GET * responses after each DICOM object received are optional and may * have been ommitted by the server. * @return EC_Normal if everything went fine, i.e.\ if request could be send * and expected responses (with whatever status) could be received. */ virtual OFCondition handleCGETSession(const T_ASC_PresentationContextID presID, DcmDataset *dataset, OFList *responses); /** Function handling a single C-GET Response. This standard handler reads the status of the * response and decides whether to receive any further messages related to the original * C-GET Request or whether the last response was received or an error occured. * @param presID [in] The presentation context the C-GET Response was * received on. * @param response [in] The response received * @param continueCGETSession [out] Defines whether it is decided to wait for further C-GET * Responses/C-STORE Requests within this C-GET session * @return If no errors occur (dataset response NULL, SCU not connected), this method will * return EC_Normal, otherwise error code. */ virtual OFCondition handleCGETResponse(const T_ASC_PresentationContextID presID, RetrieveResponse* response, OFBool& continueCGETSession); /** Function handling a single C-STORE Request. If storage mode is set to disk (default), * this function is called and the incoming object stored to disk. * @param presID [in] The presentation context the C-STORE Response was * received on. * @param incomingObject [in] The dataset (the object) received * @param continueCGETSession [out] Defines whether it is decided to wait for further * C-GET Responses/C-STORE requests within this C-GET * session. * @param cStoreReturnStatus [out] Denotes the desired C-STORE return status. * @return If errors occur (incomingObject NULL or SCU not connected or file could not be * stored), this method will return an error code otherwise EC_Normal. */ virtual OFCondition handleSTORERequest(const T_ASC_PresentationContextID presID, DcmDataset *incomingObject, OFBool& continueCGETSession, Uint16& cStoreReturnStatus); /** Function handling a single C-STORE Request. If storage mode is set to bit preserving, * this function is called and the incoming object stored directly to disk, i.e. not stored * fully in memory. * @param presID [in] The presentation context the C-STORE Response was received on. * @param filename [in] The filename to store to * @param request [in] The incoming C-STORE request command set * @return If errors occur (incomingObject NULL or SCU not connected filename not * specified), this method will return an error code otherwise EC_Normal. */ virtual OFCondition handleSTORERequestFile(T_ASC_PresentationContextID *presID, const OFString& filename, T_DIMSE_C_StoreRQ* request); /** This function is called if an object was received due to a C-GET request and can be * overwritten by a user in order to be informed about such an event. The default * implementation just prints a DEBUG message. Note that this function is not called if * the SCU is in storage mode DCMSCU_STORAGE_IGNORE. * @param filename [in] The filename written * @param sopClassUID [in] The SOP Class UID of the object written * @param sopInstanceUID [in] The SOP Instance UID of the object written */ virtual void notifyInstanceStored(const OFString& filename, const OFString& sopClassUID, const OFString& sopInstanceUID) const; /** Sends a C-FIND Request on given presentation context and receives list of responses. * The function receives the first response and then calls the function handleFINDResponse * which gets the relevant presentation context together with the response dataset and * status information. Then it waits again for the next response, if there are more to * come (i.e. response status is PENDING). In the end, after receiving all responses, the * full list of responses is returned to the caller. If he is not interested, he just sets * responses=NULL when calling the function. * This function can be overwritten by actual SCU implementations but just should work fine * for most people. * @param presID [in] The presentation context ID that should be used. Must be an odd * number. * @param queryKeys [in] The dataset containing the query keys to be searched for on the * server (SCP). * @param responses [out] The incoming C-FIND responses for this request. The caller is * responsible for providing a non-NULL pointer for this case. * After receiving the results, the caller is responsible for * freeing the memory of this variable. If NULL is specified, the * responses will be not returned to the caller. * @return EC_Normal if everything went fine, i.e.\ if request could be send and responses * (with whatever status) could be received. */ virtual OFCondition sendFINDRequest(const T_ASC_PresentationContextID presID, DcmDataset *queryKeys, OFList *responses); /** This is the standard handler for C-FIND message responses: It just adds up all responses * it receives and prints a DEBUG message. Therefore, it is called for each response * received in sendFINDRequest(). The idea is of course to overwrite this function in a * derived, actual SCU implementation if required. Thus, after each response, the caller of * sendFINDRequest() can decide on its own whether he wants to cancel the C-FIND session, * terminate the association, do something useful or whatever. That way this is a more * object-oriented kind of callback. * @param presID [in] The presentation context ID where the response was * received on. * @param response [in] The C-FIND response received. * @param waitForNextResponse [out] Denotes whether SCU should try to receive another * response. If set to OFTrue, then sendFINDRequest() * will continue waiting for responses. The current * implementation does that for all responses do not have * status SUCESSS. If set to OFFalse, sendFINDRequest() * will return control to the caller. * @return EC_Normal, if response could be handled. Error code otherwise. * The current implementation always returns EC_Normal. */ virtual OFCondition handleFINDResponse(const T_ASC_PresentationContextID presID, QRResponse *response, OFBool &waitForNextResponse); /** Send C-CANCEL and, therefore, ends the C-FIND -GET or -MOVE session, i.e.\ no further * responses will be handled. A call to this function only makes sense if an association * is open, the given presentation context represents a valid C-FIND/GET/MOVE-enabled SOP * class and usually only, if the last command send on that presentation context was a * C-FIND message. * @param presID [in] The presentation context ID where the C-CANCEL should be sent on. * @return The current implementation always returns EC_Normal. */ virtual OFCondition sendCANCELRequest(const T_ASC_PresentationContextID presID); /** This function sends a N-ACTION request on the currently opened association and receives * the corresponding response then * @param presID [in] The ID of the presentation context to be used for sending * the request message. Should not be 0. * @param sopInstanceUID [in] The requested SOP Instance UID * @param actionTypeID [in] The action type ID to be used * @param reqDataset [in] The dataset to be sent * @param rspStatusCode [out] The response status code received. 0 means success, * others can be found in the DICOM standard. * @return EC_Normal if request could be issued and response was received successfully, * an error code otherwise */ virtual OFCondition sendACTIONRequest(const T_ASC_PresentationContextID presID, const OFString &sopInstanceUID, const Uint16 actionTypeID, DcmDataset *reqDataset, Uint16 &rspStatusCode); /** This function sends N-EVENT-REPORT request and receives the corresponding response * @param presID [in] The ID of the presentation context to be used for sending * the request message. Should not be 0. * @param sopInstanceUID [in] The requested SOP Instance UID * @param eventTypeID [in] The event type ID to be used * @param reqDataset [in] The request dataset to be sent * @param rspStatusCode [out] The response status code received. 0 means success, * others can be found in the DICOM standard. * @return EC_Normal if request could be issued and response was received successfully, * an error code otherwise */ virtual OFCondition sendEVENTREPORTRequest(const T_ASC_PresentationContextID presID, const OFString &sopInstanceUID, const Uint16 eventTypeID, DcmDataset *reqDataset, Uint16 &rspStatusCode); /** Receives N-EVENT-REPORT request on the currently opened association and sends a * corresponding response. Calls checkEVENTREPORTRequest() in order to determine the * DIMSE status code to be used for the N-EVENT-REPORT response. * @param reqDataset [out] Pointer to the dataset received * @param eventTypeID [out] Event Type ID from the command set received * @param timeout [in] Optional timeout in seconds for receiving data. This value * (if not 0) overwrites the standard DIMSE timeout and also * enables the non-blocking mode for receiving the request. * @return status, EC_Normal if successful, an error code otherwise */ virtual OFCondition handleEVENTREPORTRequest(DcmDataset *&reqDataset, Uint16 &eventTypeID, const int timeout = 0); /** This function is called while sending DIMSE messages, i.e.\ on each PDV of a dataset. * The default implementation just prints a TRACE message on the number of bytes sent so * far. By overwriting this method, the progress of the send process can be shown to the * user in a more appropriate way. The progress notification can also be disabled * completely by calling setProgressNotificationMode(). * @param byteCount [in] Number of bytes sent so far */ virtual void notifySENDProgress(const unsigned long byteCount); /** This function is called while receiving DIMSE messages, i.e.\ on each PDV of a dataset. * The default implementation just prints a TRACE message on the number of bytes received * so far. By overwriting this method, the progress of the receive process can be shown to * the user in a more appropriate way. The progress notification can also be disabled * completely by calling setProgressNotificationMode(). * @param byteCount [in] Number of bytes received so far */ virtual void notifyRECEIVEProgress(const unsigned long byteCount); /** Closes the association created by this SCU. Also resets the current association. * @param closeType [in] Define whether to release or abort the association */ virtual void closeAssociation(const DcmCloseAssociationType closeType); /* Set methods */ /** Set maximum PDU length (to be received by SCU) * @param maxRecPDU [in] The maximum PDU size to use in bytes */ void setMaxReceivePDULength(const unsigned long maxRecPDU); /** Set whether to send in DIMSE blocking or non-blocking mode * @param blockingMode [in] Either blocking or non-blocking mode */ void setDIMSEBlockingMode(const T_DIMSE_BlockingMode blockingMode); /** Set SCU's AETitle to be used in association negotiation * @param myAETtitle [in] The SCU's AETitle to be used */ void setAETitle(const OFString &myAETtitle); /** Set SCP's host (hostname or IP address) to talk to in association negotiation * @param peerHostName [in] The SCP's hostname or IP address to be used */ void setPeerHostName(const OFString &peerHostName); /** Set SCP's AETitle to talk to in association negotiation * @param peerAETitle [in] The SCP's AETitle to be used */ void setPeerAETitle(const OFString &peerAETitle); /** Set SCP's port number to connect to for association negotiation * @param peerPort [in] The SCP's port number */ void setPeerPort(const Uint16 peerPort); /** Set timeout for receiving DIMSE messages * @param dimseTimeout [in] DIMSE Timeout in seconds for receiving data. If the blocking * mode is DIMSE_NONBLOCKING and we are trying to read data from * the incoming socket stream and no data has been received. */ void setDIMSETimeout(const Uint32 dimseTimeout); /** Set timeout for receiving ACSE messages * @param acseTimeout [in] ACSE Timeout in seconds used by timer for message timeouts * during association negotiation */ void setACSETimeout(const Uint32 acseTimeout); /** Set an association configuration file and profile to be used * @param filename [in] File name of the association configuration file * @param profile [in] Profile inside the association negotiation file */ void setAssocConfigFileAndProfile(const OFString &filename, const OFString &profile); /** Set the directory that should be used by the standard C-GET handler to store objects * that come in with the corresponding C-STORE rqeuests * @param storeDir [in] The directory to store to. It is checked in handleSTORERequest() * whether the directory is writeable and readable. Per default, the * received objects are stored in the current working directory. */ void setStorageDir(const OFString& storeDir); /** Set the storage mode to be used. Default is DCMSCU_STORAGE_DISK. * @param storageMode The storage mode to be used. */ void setStorageMode(const DcmStorageMode storageMode); /** Set whether to show presentation contexts in verbose or debug mode * @param mode [in] Show presentation contexts in verbose mode if OFTrue. By default, the * presentation contexts are shown in debug mode. */ void setVerbosePCMode(const OFBool mode); /** Set the mode that specifies whether the transfer syntax of the dataset can be changed * for network transmission. This mainly covers the compression/decompression of datasets, * which is disabled by default. * @param mode [in] Allow dataset conversion if OFTrue */ void setDatasetConversionMode(const OFBool mode); /** Set the mode that specifies whether the progress of sending and receiving DIMSE * messages is notified by calling notifySENDProgress() and notifyRECEIVEProgress(), * respectively. The progress notification is enabled by default. * @param mode [in] Disable progress notification if OFFalse */ void setProgressNotificationMode(const OFBool mode); /* Get methods */ /** Get current connection status * @return OFTrue if SCU is currently connected, OFFalse otherwise */ OFBool isConnected() const; /** Returns maximum PDU length configured to be received by SCU * @return Maximum PDU length in bytes */ Uint32 getMaxReceivePDULength() const; /** Returns whether DIMSE messaging is configured to be blocking or unblocking * @return The blocking mode configured */ T_DIMSE_BlockingMode getDIMSEBlockingMode() const; /** Returns the SCU's own configured AETitle * @return The AETitle configured for this SCU */ const OFString &getAETitle() const; /** Returns the SCP's (peer's) host name configured * @return The hostname (or IP) configured to be talked to */ const OFString &getPeerHostName() const; /** Returns the SCP's (peer's) AETitle configured * @return The AETitle configured to be talked to */ const OFString &getPeerAETitle() const; /** Returns the SCP's (peer's) TCP/IP port configured * @return The port configured to talked to */ Uint16 getPeerPort() const; /** Returns the DIMSE timeout configured defining how long SCU will wait for DIMSE responses * @return The DIMSE timeout configured */ Uint32 getDIMSETimeout() const; /** Returns the timeout configured defining how long SCU will wait for messages during ACSE * messaging (association negotiation) * @return The ACSE timeout configured */ Uint32 getACSETimeout() const; /** Returns the storage directory used for storing objects received with C-STORE requests * in the context of C-GET sessions. Default is empty string which refers to the current * working directory. * @return The storage directory */ OFString getStorageDir() const; /** Returns the storage mode enabled * @return The storage mode enabled */ DcmStorageMode getStorageMode() const; /** Returns the verbose presentation context mode configured specifying whether details * on the presentation contexts (negotiated during association setup) should be shown in * verbose or debug mode. The latter is the default. * @return The current verbose presentation context mode. Show details on the * presentation contexts on INFO log level (verbose) if OFTrue and on DEBUG * level if OFFalse. */ OFBool getVerbosePCMode() const; /** Returns the mode that specifies whether the transfer syntax of the dataset can be * changed for network transmission. This mainly covers the compression/decompression * of datasets, which is disabled by default. * @return The current dataset conversion mode, enabled if OFTrue */ OFBool getDatasetConversionMode() const; /** Returns the mode that specifies whether the progress of sending and receiving DIMSE * messages is notified by calling notifySENDProgress() and notifyRECEIVEProgress(), * respectively. The progress notification is enabled by default. * @return The current progress notification mode, enabled if OFTrue */ OFBool getProgressNotificationMode() const; /** Returns whether SCU is configured to create a TLS connection with the SCP * @return OFFalse for this class but may be overriden by derived classes */ OFBool getTLSEnabled() const; /** Deletes internal networking structures from memory */ void freeNetwork(); protected: /** Sends a DIMSE command and possibly also a dataset from a data object via network to * another DICOM application * @param presID [in] Presentation context ID to be used for message * @param msg [in] Structure that represents a certain DIMSE command which * shall be sent * @param dataObject [in] The instance data which shall be sent to the other DICOM * application; NULL, if there is none * @param commandSet [out] If this parameter is not NULL it will return a copy of the * DIMSE command which is sent to the other DICOM application * @return EC_Normal if sending request was successful, an error code otherwise */ OFCondition sendDIMSEMessage(const T_ASC_PresentationContextID presID, T_DIMSE_Message *msg, DcmDataset *dataObject, DcmDataset **commandSet = NULL); /** Returns SOP Class UID, SOP Instance UID and original transfer syntax for a given dataset. * If the dataset is NULL, all returned values will be undefined (i.e. empty or EXS_Unknown). * @param dataset [in] The dataset to read from * @param sopClassUID [out] The value of attribute SOP Class UID if present * @param sopInstanceUID [out] The value of attribute SOP Instance UID if present * @param transferSyntax [out] The value of transfer syntax that originally was read from * disk. Will be unknown if the dataset was created in memory. * @return EC_Normal if all information could be retrieved and is valid, an error code * otherwise */ OFCondition getDatasetInfo(DcmDataset *dataset, OFString &sopClassUID, OFString &sopInstanceUID, E_TransferSyntax &transferSyntax); /** Tells DcmSCU to use a secure TLS connection described by the given TLS layer * @param tlayer [in] The TLS transport layer including all TLS parameters * @return EC_Normal if given transport layer is ok, an error code otherwise */ OFCondition useSecureConnection(DcmTransportLayer *tlayer); /** Receive DIMSE command (excluding dataset!) over the currently open association * @param presID [out] Contains in the end the ID of the presentation context * which was specified in the DIMSE command received * @param msg [out] The message received * @param statusDetail [out] If a non-NULL value is passed this variable will in the end * contain detailed information with regard to the status * information which is captured in the status element * (0000,0900). Note that the value for element (0000,0900) is * not contained in this return value but in internal msg. For * details on the structure of this object, see DICOM standard * part 7, annex C). * @param commandSet [out] If this parameter is not NULL, it will return a copy of the * DIMSE command which was received from the other DICOM * application. The caller is responsible to de-allocate the * returned object! * @param timeout [in] If this parameter is not 0, it specifies the timeout (in * seconds) to be used for receiving the DIMSE command. * Otherwise, the default timeout value is used (see * setDIMSETimeout()). * @return EC_Normal if command could be received successfully, an error code otherwise */ OFCondition receiveDIMSECommand(T_ASC_PresentationContextID *presID, T_DIMSE_Message *msg, DcmDataset **statusDetail, DcmDataset **commandSet = NULL, const Uint32 timeout = 0); /** Receives one dataset (of instance data) via network from another DICOM application * @param presID [out] Contains in the end the ID of the presentation context which * was used in the PDVs that were received on the network. If the * PDVs show different presentation context IDs, this function * will return an error. * @param dataObject [out] Contains in the end the information which was received over * the network * @return EC_Normal if dataset could be received successfully, an error code otherwise */ OFCondition receiveDIMSEDataset(T_ASC_PresentationContextID *presID, DcmDataset **dataObject); /** clear list of presentation contexts. In addition, any currently selected association * configuration file is disabled. */ void clearPresentationContexts(); /** After negotiation association, this call returns the presentation context belonging * to the given presentation context ID * @param presID [in] The presentation context ID to look for * @param abstractSyntax [out] The abstract syntax (UID) for that ID. * Empty, if such a presentation context does not exist. * @param transferSyntax [out] The transfer syntax (UID) for that ID. * Empty, if such a presentation context does not exist. */ void findPresentationContext(const T_ASC_PresentationContextID presID, OFString &abstractSyntax, OFString &transferSyntax); /** Check given N-EVENT-REPORT request and dataset for validity. This method is called by * handleEVENTREPORTRequest() before sending the response in order to determine the * DIMSE status code to be used for the response message. * @param request [in] The N-EVENT-REPORT request message data structure * @param reqDataset [in] The N-EVENT-REPORT request dataset received. Might be NULL. * @return DIMSE status code to be used for the N-EVENT-REPORT response. * Always returns STATUS_Success (0). Derived classes should, therefore, * overwrite this method and return a more appropriate value based on the * result of the checks performed. */ virtual Uint16 checkEVENTREPORTRequest(T_DIMSE_N_EventReportRQ &request, DcmDataset *reqDataset); /** Sends back a C-STORE response on the given presentation context, with the designated * status, fitting the corresponding C-STORE request. * @param presID [in] The presentation context ID to be used. * @param status [in] The storage DIMSE status to be used. * @param request [in] The C-STORE request that should be responded to. * @result EC_Normal if the response could be sent, error otherwise. */ virtual OFCondition sendSTOREResponse(T_ASC_PresentationContextID presID, Uint16 status, const T_DIMSE_C_StoreRQ& request); /** Helper function that generates a storage filename by extracting SOP Class and SOP * Instance UID from a dataset and combining that with the configured storage directory. * The SOP class is used to create an initial two letter abbreviation for the * corresponding modality, e.g. CT. An example for a storage filename created by this * function is /storage_dir/CT.1.2.3.4.5 for a CT with SOP Instance UID 1.2.3.4. * This function might be overwritten to change the filename behaviour completely. This * function is only called if the SCU is in DCMSCU_STORAGE_DISK mode. * @param dataset [in] The dataset that should be stored to disk * @result Non-empty string if successful, otherwise empty string. */ virtual OFString createStorageFilename(DcmDataset *dataset); /** Receives a DICOM dataset on a given presentation context ID but does not store it in * memory or disk, thus ignoring it. * @param presID [in] The presentation context to be used * @param request [in] The corresponding C-STORE request * @return EC_Normal if ignoring worked, error code otherwise. */ virtual OFCondition ignoreSTORERequest(T_ASC_PresentationContextID presID, const T_DIMSE_C_StoreRQ& request); /* Callback functions */ /** Callback function used for sending DIMSE messages. * @param callbackContext [in] The desired user callback data * @param byteCount [in] Progress bytes count */ static void callbackSENDProgress(void *callbackContext, unsigned long byteCount); /** Callback function used for receiving DIMSE messages. * @param callbackContext [in] The desired user callback data * @param byteCount [in] Progress bytes count */ static void callbackRECEIVEProgress(void *callbackContext, unsigned long byteCount); private: /** Private undefined copy-constructor. Shall never be called. * @param src Source object */ DcmSCU(const DcmSCU &src); /** Private undefined operator=. Shall never be called. * @param src Source object * @return Reference to this */ DcmSCU &operator=(const DcmSCU &src); /// Associaton of this SCU. This class only handles 1 association at a time. T_ASC_Association *m_assoc; /// The DICOM network the association is based on T_ASC_Network *m_net; /// Association parameters T_ASC_Parameters *m_params; /// Configuration file for presentation contexts (optional) OFString m_assocConfigFilename; /// Profile in configuration file that should be used (optional) OFString m_assocConfigProfile; /// Defines presentation context, consisting of one abstract syntax name /// and a list of transfer syntaxes for this abstract syntax struct DCMTK_DCMNET_EXPORT DcmSCUPresContext { /** Default constructor */ DcmSCUPresContext() : abstractSyntaxName() , transferSyntaxes() , roleSelect(ASC_SC_ROLE_DEFAULT) { } /// Abstract Syntax Name of Presentation Context OFString abstractSyntaxName; /// List of Transfer Syntaxes for Presentation Context OFList transferSyntaxes; /// Role Selection T_ASC_SC_ROLE roleSelect; }; /// List of presentation contexts that should be negotiated OFList m_presContexts; /// Configuration file containing association parameters OFString m_assocConfigFile; /// The last DIMSE successfully sent, unresponded DIMSE request T_DIMSE_Message *m_openDIMSERequest; /// Maximum PDU size Uint32 m_maxReceivePDULength; /// DIMSE blocking mode T_DIMSE_BlockingMode m_blockMode; /// AEtitle of this application OFString m_ourAETitle; /// Peer hostname OFString m_peer; /// AEtitle of remote application OFString m_peerAETitle; /// Port of remote application entity Uint16 m_peerPort; /// DIMSE timeout Uint32 m_dimseTimeout; /// ACSE timeout Uint32 m_acseTimeout; /// Storage directory for objects received with C-STORE due to a /// running C-GET session. Per default, the received objects /// are stored in the current working directory. OFString m_storageDir; /// Set whether bit preserving storage should be enabled, i.e.\ any objects /// retrieved via C-STORE should be written directly to disk without /// any data correction/re-computation (e.g.\ group length calculations, /// padding, etc.). This is especially interesting for retaining valid /// signatures, and also to receive huge files which cannot be fully received /// in memory. Default is OFFalse (no bit preserving) storage. DcmStorageMode m_storageMode; /// Verbose PC mode OFBool m_verbosePCMode; /// Dataset conversion mode OFBool m_datasetConversionMode; /// Progress notification mode OFBool m_progressNotificationMode; /** Returns next available message ID free to be used by SCU * @return Next free message ID */ Uint16 nextMessageID(); }; #endif // SCU_H /* ** CVS Log ** $Log: scu.h,v $ ** Revision 1.41 2012-02-21 08:48:51 joergr ** Added support for progress notifications while sending and receiving DICOM ** datasets. ** ** Revision 1.40 2011-12-14 11:45:15 uli ** Make it possible to perfectly build dcmnet and dcmtls a DLLs. ** ** Revision 1.39 2011-10-10 14:01:29 uli ** Moved SCU-specific error condition to the correct place. ** ** Revision 1.38 2011-10-04 08:58:14 joergr ** Added flag that allows for specifying whether to convert a dataset to be ** transferred to the network transfer syntax. Also removed unused parameters ** "rspCommandSet" and "rspStatusDetail" from method sendSTORERequest(). ** ** Revision 1.37 2011-09-28 16:28:20 joergr ** Added general support for transfer syntax conversions to sendSTORERequest(). ** ** Revision 1.36 2011-09-28 15:25:34 joergr ** Return a more appropriate error code in case the dataset to be sent is ** invalid. This also required to introduce a return value for getDatasetInfo(). ** ** Revision 1.35 2011-09-28 13:31:56 joergr ** Added method that allows for clearing the list of presentation contexts. ** ** Revision 1.34 2011-09-22 13:49:03 joergr ** Fixed incorrect comment on return code of some sendXXXRequest() methods. ** ** Revision 1.33 2011-09-06 16:11:06 ogazzar ** Fixed typos in a log commit message. ** ** Revision 1.32 2011-09-06 12:57:36 ogazzar ** Added a function to send N-EVENT-REPORT request and receive a reponse. ** ** Revision 1.31 2011-08-25 15:46:18 joergr ** Further cleanup of minor inconsistencies regarding documentation, parameter ** names, log output and handling of status details information. ** ** Revision 1.30 2011-08-25 15:05:06 joergr ** Changed data structure for Q/R responses from OFVector to OFList. Also fixed ** some possible memory leaks and made the FIND/MOVE/GET code more consistent. ** ** Revision 1.29 2011-08-25 13:46:28 joergr ** Fixed minor issues in the API documentation, parameter and method names. ** ** Revision 1.28 2011-08-25 09:31:33 onken ** Added C-GET functionality to DcmSCU class and accompanying getscu ** commandline application. ** ** Revision 1.27 2011-05-25 09:57:54 ogazzar ** Renamed a function name. ** ** Revision 1.26 2011-05-25 09:30:12 ogazzar ** Added a function to look for a presentation context ID that best matches ** the abstract syntax and the transfer syntax. ** ** Revision 1.25 2011-05-24 13:17:58 onken ** Added missing default initializiation of role flag in presentation context ** constructor. ** ** Revision 1.24 2011-05-24 08:28:08 ogazzar ** Added support for role selection negotiation. ** ** Revision 1.23 2011-05-19 17:20:09 onken ** Fixed some documentation. ** ** Revision 1.22 2011-05-19 09:57:26 onken ** Fixed message ID field in C-CANCEL request (should be the one of last ** request). In case of error status codes in C-MOVE responses, the default ** behaviour is now to not wait for further responses. Fixed log output level ** to better fit the messages while receiveing C-MOVE responses. Minor ** code and comment cleanups. Renamed function parameter in sendMOVEREquest ** to better reflect the standard. ** ** Revision 1.21 2011-05-17 14:43:55 onken ** Removed some windows line endings. ** ** Revision 1.20 2011-05-17 14:34:32 onken ** Completed doxygen documentation of DcmSCU class. Fixed some minor formatting ** issues. Fixed CVS log at end of the file. Implemented C-CANCEL message. ** Fixed some minor formatting issues. Changed C-ECHO implementation to rely ** on sendDIMSEMesage as the other DIMSE functions do. Changed some public ** function arguments to const to be more correct. Fixed CVS log at the end ** of the file. Re-formatted CHANGES log entry from 2011-04-28. ** ** Revision 1.19 2011-05-17 14:26:19 onken ** Implemented C-CANCEL message. Fixed some minor formatting issues. ** Changed C-ECHO implementation to rely on sendDIMSEMesage as the other ** DIMSE functions do. Changed some public function arguments to const to be ** more correct. Fixed CVS log at the end of the scu.cc file. ** ** Revision 1.18 2011-04-28 17:50:05 onken ** Protected public networking functions for creating an association ** from being called twice. Enhanced protection of DIMSE messaging ** functions from being called without being connected. Introduced ** status detail into C-FIND responses (and C-MOVE responses). Was ** not accessible to the caller before. Minor code cleanups. Added ** C-MOVE code for retrieving DICOM objects. So far only retrieving ** on a separate connection is supported. Added function for cleaning ** up internal memory from destructor. This function also fixes a ** memory leak in case users call initNetwork more than one time. ** Added error code returned by functions if SCU is already connected. ** ** Revision 1.17 2011-02-16 08:55:13 joergr ** Fixed issue in sendSTORERequest() when sending a dataset that was created ** in memory (and which has, therefore, an original transfer of EXS_Unknown). ** ** Revision 1.16 2011-02-04 12:57:40 uli ** Made sure all members are initialized in the constructor (-Weffc++). ** ** Revision 1.15 2011-02-04 11:24:40 uli ** Added private undefined functions where gcc's -Weffc++ warns otherwise. ** ** Revision 1.14 2011-02-01 09:01:19 joergr ** Added "const" specifier to parameter in order to be consistent with the ** source file (caused warnings/errors with certain compilers). ** ** Revision 1.13 2010-10-14 13:17:22 joergr ** Updated copyright header. Added reference to COPYRIGHT file. ** ** Revision 1.12 2010-10-07 12:54:07 joergr ** Fixed minor Doxygen API documentation issues (added backslash in order to ** avoid that the short description ends at the first period). ** ** Revision 1.11 2010-06-24 09:21:54 joergr ** Revised comment to make clear that the parameter "presID" shall never be 0 ** for the sendACTIONRequest() method. ** ** Revision 1.10 2010-06-22 15:45:27 joergr ** Introduced new enumeration type to be used for closeAssociation(). ** Further code cleanup. Renamed some methods, variables, types and so on. ** ** Revision 1.9 2010-06-17 17:11:27 joergr ** Added preliminary support for N-EVENT-REPORT to DcmSCU. Some further code ** cleanups and enhancements. Renamed some methods. Revised documentation. ** ** Revision 1.8 2010-06-09 16:09:01 joergr ** Added preliminary support for N-ACTION to DcmSCU. Some further code cleanups ** and enhancements. ** ** Revision 1.7 2010-06-08 17:54:12 onken ** Added C-FIND functionality to DcmSCU. Some code cleanups. Fixed ** memory leak sometimes occuring during association configuration. ** ** Revision 1.6 2010-04-29 16:13:28 onken ** Made SCU class independent from dcmtls, i.e. outsourced TLS API. Added ** direct API support for sending C-STORE requests. Further API changes and ** some bugs fixed. ** ** Revision 1.5 2009-12-21 17:00:32 onken ** Fixed API documentation to keep doxygen quiet. ** ** Revision 1.4 2009-12-21 15:33:55 onken ** Added documentation and refactored / enhanced some code. ** ** Revision 1.3 2009-12-17 09:12:10 onken ** Fixed other scu and scp base class compile issues. ** ** Revision 1.2 2009-12-17 09:05:15 onken ** Fixed typo resulting in build failure. ** ** Revision 1.1 2009-12-17 09:02:44 onken ** Added base classes for SCU and SCP implementations. ** ** Revision 1.2 2009-12-02 14:26:05 uli ** Stop including dcdebug.h which was removed. ** ** Revision 1.1 2008-09-29 13:51:52 onken ** Initial checkin of module dcmppscu implementing an MPPS commandline client. ** */