File: io.rst

package info (click to toggle)
odil 0.12.2-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,320 kB
  • sloc: cpp: 55,035; python: 3,971; javascript: 460; xml: 182; makefile: 98
file content (161 lines) | stat: -rw-r--r-- 5,214 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
Reading and writing files
=========================

.. highlight:: c++

Odil reads and write data sets using the three standard formats `binary`_, `JSON`_ and `XML`_.

Binary format
-------------

Two classes are responsible for reading and writing using the binary DICOM format: `odil::Reader`_ and `odil::Writer`_. Both classes handle not only whole data sets stored in DICOM files, but also give access to lower-level functions like individual elements and tags. These two classes are based on C++ streams and so can any class that implement the streams API.

The simplest usage to write a data set to a file is:

::
  
  #include <fstream>
  
  #include <odil/DataSet.h>
  #include <odil/registry.h>
  #include <odil/uid.h>
  #include <odil/Writer.h>
  
  int main()
  {
      odil::DataSet data_set;
      data_set.add("SOPClassUID", {odil::registry::RawDataStorage});
      data_set.add("SOPInstanceUID", {odil::generate_uid()});
      data_set.add("PatientName", {"Doe^John"});
      
      std::ofstream stream{"foo.dcm"};
      odil::Writer::write_file(data_set, stream);
  }

This will use a default transfer syntax (*Explicit VR Little Endian*) and add required meta information extracted from the data set. Note that the data set must include the *SOP Class UID* and *SOP Instance UID* to be written to a file. The previous example uses `odil::generate_uid`_ to create a random UID.

Reading from a file return a pair of data sets: the first element of the pair is file meta-information, the second is the data set itself.

::
  
  #include <fstream>
  #include <iostream>
  #include <tuple>

  #include <odil/DataSet.h>
  #include <odil/Reader.h>

  int main()
  {
      std::ifstream stream{"foo.dcm"};
      
      std::shared_ptr<odil::DataSet> header, data_set;
      std::tie(header, data_set) = odil::Reader::read_file(stream);
      
      std::cout << header->as_string("ImplementationVersionName")[0] << "\n";
      std::cout << data_set->as_string("SOPInstanceUID")[0] << "\n";
  }

JSON format
-----------

JSON serialization and de-serialization is managed by two functions `odil::as_json`_ and `odil::as_dataset(json)`_. Reading and writing to a file is delegated to the underlying JSON toolkit, `JsonCpp`_.

The following code sample converts a data set to JSON and writes it to a file. Refer to the JsonCpp documentation for more information about `formatting`_.

::
  
  #include <fstream>
  
  #include "odil/json_converter.h"
  
  int main()
  {
      odil::DataSet data_set;
      // Fill data set
      
      auto const json = odil::as_json(data_set);
      
      std::ofstream foo{"foo.json"};
      foo << json;
      
      return 0;
  }

The converse operation, reading from a file and converting the JSON to a data set, is similar.

::
  
  #include <fstream>
  
  #include "odil/json_converter.h"
  
  int main()
  {
      Json::Value json
      std::ifstream foo{"foo.json"};
      foo >> json;
      
      auto const data_set = odil::as_dataset(json);
      
      return 0;
  }

XML format
----------

The XML serialization and de-serialization is very similar to the JSON one: the respective functions performing these tasks are `odil::as_xml`_ and `odil::as_dataset(xml)`_. The underlying toolkit in the XML case is `Boost.PropertyTree`_.

The following snippet saves a data set to an XML file:

::
  
  #include <fstream>
  #include <boost/property_tree/xml_parser.hpp>
  #include "odil/xml_converter.h"
  
  int main()
  {
      odil::DataSet data_set;
      // Fill data set
      
      auto const xml = odil.as_xml(data_set);
      
      std::ofstream foo{"foo.xml"};
      boost::propery_tree::write_xml(foo, xml);
      
      return 0;
  }

The following snippet loads a data set from an XML file:

::
  
  #include <fstream>
  #include <boost/property_tree/xml_parser.hpp>
  #include "odil/xml_converter.h"
  
  int main()
  {
      std::ifstream foo{"foo.xml"};
      boost::property_tree::ptree xml;
      boost::propery_tree::read_xml(foo, xml);
      
      auto const data_set = odil::as_dataset(xml);
      
      return 0;
  }

.. _binary: http://dicom.nema.org/medical/dicom/current/output/chtml/part10/chapter_7.html
.. _Boost.PropertyTree: http://www.boost.org/doc/libs/1_66_0/doc/html/property_tree.html
.. _formatting: http://open-source-parsers.github.io/jsoncpp-docs/doxygen/index.html
.. _JSON: http://dicom.nema.org/medical/dicom/current/output/chtml/part18/chapter_F.html
.. _JsonCpp: https://github.com/open-source-parsers/jsoncpp
.. _odil::as_dataset(json): ../../_static/doxygen/namespaceodil.html#aecc7f7828df77fd27dd166f4748f5d5d
.. _odil::as_dataset(xml): ../../_static/doxygen/namespaceodil.html#a03f0a5fe3c4acac080a627c90ef81dee
.. _odil::as_json: ../../_static/doxygen/namespaceodil.html#a2c6f4e235991f2082e45f0db5611a177
.. _odil::as_xml: ../../_static/doxygen/namespaceodil.html#adea55ac4f5896897390b0c0474400ee8
.. _odil::Reader: ../../_static/doxygen/classodil_1_1Reader.html
.. _odil::generate_uid: ../../_static/doxygen/namespaceodil.html#ab4e34fa7513bb4d7890586e99a9d7add
.. _odil::Writer: ../../_static/doxygen/classodil_1_1Writer.html
.. _XML: http://dicom.nema.org/medical/dicom/2016b/output/chtml/part19/chapter_A.html