2 # ---------------------------------------------------------------------
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
10 # This software is governed by the CeCILL-B license under French law and
11 # abiding by the rules of distribution of free software. You can use,
12 # modify and/ or redistribute the software under the terms of the CeCILL-B
13 # license as circulated by CEA, CNRS and INRIA at the following URL
14 # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15 # or in the file LICENSE.txt.
17 # As a counterpart to the access to the source code and rights to copy,
18 # modify and redistribute granted by the license, users are provided only
19 # with a limited warranty and the software's author, the holder of the
20 # economic rights, and the successive licensors have only limited
23 # The fact that you are presently reading this means that you have had
24 # knowledge of the CeCILL-B license and that you accept its terms.
25 # ------------------------------------------------------------------------
29 #include <creaImageIOTreeDescriptor.h>
30 #include <boost/algorithm/string/split.hpp>
31 #include <boost/algorithm/string/replace.hpp>
32 #include <creaImageIOSystem.h>
33 #include <boost/filesystem.hpp>
45 //==================================================================
46 /// The attribute is hidden (not visible to user)
47 const unsigned int AttributeDescriptor::PRIVATE = 1;
48 /// The attribute enters in unique identifier constitution
49 const unsigned int AttributeDescriptor::IDENTIFIER = 2;
50 /// The attribute can be edited
51 const unsigned int AttributeDescriptor::EDITABLE = 3;
52 /// the attribute describes the node
53 const unsigned int AttributeDescriptor::LABEL = 4;
54 //==================================================================
56 //==================================================================
57 Descriptor::Descriptor()
59 CreateLevel0Descriptor();
61 //==================================================================
63 //==================================================================
64 Descriptor::~Descriptor()
67 //==================================================================
69 //==================================================================
70 void Descriptor::CreateLevel0Descriptor()
72 Add(LevelDescriptor("Root"));
74 //==================================================================
76 //==================================================================
77 /// Creates the default descriptor
78 void Descriptor::CreateDefault()
80 // clears the existing one
83 // Creates the level 0 descriptor
84 CreateLevel0Descriptor();
85 // Creates the attribute "Name"
86 Add(AttributeDescriptor("Name","Name",
87 AttributeDescriptor::LABEL),0);
90 Add(LevelDescriptor("Patient"));
91 Add(AttributeDescriptor("NumberOfChildren","#Series",0),1); // Number of Series
92 Add(AttributeDescriptor(0x0010,0x0010, // Patient name
93 AttributeDescriptor::LABEL),1);
94 Add(AttributeDescriptor(0x0010,0x0040),1); // Patient sex
95 Add(AttributeDescriptor(0x0010,0x0030),1); // Patient birthday
96 Add(AttributeDescriptor(0x0010,0x0020, // Patient ID
97 AttributeDescriptor::IDENTIFIER),1);
100 Add(LevelDescriptor("Series"));
101 Add(AttributeDescriptor("NumberOfChildren","#Images",0),2); // Number of images
102 Add(AttributeDescriptor(0x0008,0x0060, // Modality
103 AttributeDescriptor::LABEL),2);
104 Add(AttributeDescriptor(0x0008,0x1030),2); // Study Description
105 Add(AttributeDescriptor(0x0008,0x103E),2); // Description
106 Add(AttributeDescriptor(0x0008,0x0080),2); // Institution Name
107 Add(AttributeDescriptor(0x0008,0x0081),2); // Institution Adress
108 Add(AttributeDescriptor(0x0008,0x1010),2); // Station Name
109 Add(AttributeDescriptor(0x0008,0x1048),2); // Physician of Record
110 Add(AttributeDescriptor(0x0008,0x1050),2); // Performing Physician's Name
111 Add(AttributeDescriptor(0x0018,0x1030),2); // Protocol Name
113 Add(AttributeDescriptor(0x0020,0x0010),2); // Study ID
114 Add(AttributeDescriptor(0x0008,0x0020),2); // Study Date
115 Add(AttributeDescriptor(0x0008,0x0030),2); // Study Time
116 Add(AttributeDescriptor(0x0008,0x0050),2); // Study Accession Number
117 Add(AttributeDescriptor(0x0008,0x0005),2); // Specific character set
118 Add(AttributeDescriptor(0x0008,0x0021),2); // Series Date
119 Add(AttributeDescriptor(0x0008,0x0031),2); // Series time
121 Add(AttributeDescriptor(0x0020,0x000D // Study Instance UID
122 ),2);//AttributeDescriptor::IDENTIFIER),2);
123 Add(AttributeDescriptor(0x0020,0x000E, // Series Instance UID
124 AttributeDescriptor::IDENTIFIER),2);
126 // AttributeDescriptor::LABEL),2);
130 Add(LevelDescriptor("Image"));
132 Add(AttributeDescriptor(0x0020,0x0013),3); // Image Number
134 Add(AttributeDescriptor(0x0028,0x0010),3); // Rows
135 Add(AttributeDescriptor(0x0028,0x0011),3); // Columns
136 Add(AttributeDescriptor(0x0028,0x0012),3); // Planes
137 Add(AttributeDescriptor(0x0028,0x0002),3); // Sample per pixels
138 Add(AttributeDescriptor(0x0028,0x0008),3); // Number of Frames
139 Add(AttributeDescriptor(0x0028,0x0004),3); // Photometric Interpretation
140 Add(AttributeDescriptor(0x0028,0x0103),3); // Pixel Representation
142 Add(AttributeDescriptor(0x0020,0x0032),3); // Image Position Patient
143 Add(AttributeDescriptor(0x0020,0x0037),3); // Image Orientation Patient
144 Add(AttributeDescriptor(0x0020,0x1041),3); // Slice Location
145 Add(AttributeDescriptor(0x0028,0x0006),3); // Planar Configuration
147 Add(AttributeDescriptor(0x0028,0x0030),3); // Pixel Spacing
148 Add(AttributeDescriptor(0x0028,0x0100),3); // AlocatedBits
149 Add(AttributeDescriptor(0x0028,0x0101),3); // StoredBits
151 Add(AttributeDescriptor(0x0008,0x0008),3); // Image Type
152 Add(AttributeDescriptor(0x0008,0x0023),3); // Content Date
153 Add(AttributeDescriptor(0x0008,0x0033),3); // Content Time
155 Add(AttributeDescriptor(0x0020,0x4000),3); // Image Comments
157 Add(AttributeDescriptor(0x0004,0x1500, // File Name
158 AttributeDescriptor::LABEL),3);
159 Add(AttributeDescriptor(0x0028,0x1052),3); // Rescale Intercept
160 Add(AttributeDescriptor(0x0028,0x1053),3); // Rescale Slope
162 Add(AttributeDescriptor(0x0050,0x0004),3); // Calibration Image
164 Add(AttributeDescriptor(0x0020,0x0052 // Frame Reference UID
166 Add(AttributeDescriptor(0x0008,0x0016),3); // SOP Class UID
167 Add(AttributeDescriptor("FullFileName", // Full file name
169 AttributeDescriptor::IDENTIFIER),3);
173 //////////////////////////////////////////////////////////////
174 // create a descriptor (name, attributes...) from a file) //
175 // @param : file path //
177 //////////////////////////////////////////////////////////////
178 void Descriptor::createDescriptorfromFile(const std::string &i_name)
182 // read file and put in buffer
183 std::ifstream i_file(i_name.c_str());
184 std::stringstream buffer;
185 buffer << i_file.rdbuf();
191 while(std::getline(buffer, line))
194 { //increment levels.
200 // For each level, a name to describe it
201 Add(LevelDescriptor(line));
204 else if(line.empty()) // to avoid end line
210 // split line to find all tags
211 std::vector<std::string> descriptors;
212 std::string separator = " ";
213 std::string::size_type last_pos = line.find_first_not_of(separator);
214 //find first separator
215 std::string::size_type pos = line.find_first_of(separator, last_pos);
216 while(std::string::npos != pos || std::string::npos != last_pos)
218 descriptors.push_back(line.substr(last_pos, pos - last_pos));
219 last_pos = line.find_first_not_of(separator, pos);
220 pos = line.find_first_of(separator, last_pos);
223 // By default, the last tag is at zero and not recorded but if take in count
224 unsigned int flag = 0;
225 if(descriptors.size() == 4)
227 std::stringstream val;
228 val << std::dec << descriptors[3];
232 // if Dicom tag, use "group" and "element" descriptor
233 if(descriptors[0] == "D")
234 { std::stringstream val, val2;
235 unsigned short group;
236 unsigned short element;
237 val << std::dec << descriptors[1] ;
238 val >> std::hex >> group;
239 val2 << std::dec << descriptors[2];
240 val2 >> std::hex >> element;
241 Add(AttributeDescriptor( group,element,flag), ilevel);
244 else if(descriptors[0].find("#") != -1)
246 // commented line continue to next line
249 { boost::algorithm::replace_all(descriptors[2],"_"," ");
250 Add(AttributeDescriptor( descriptors[1].c_str(),descriptors[2].c_str(),flag), ilevel);
256 //==================================================================
258 //==================================================================
259 /// Adds a LevelDescriptor at the end of the list
260 void Descriptor::Add(const LevelDescriptor& d)
262 mLevelDescriptorList.push_back(d);
264 //==================================================================
266 //==================================================================
267 /// Adds an AttributeDescriptor to level l
268 void Descriptor::Add(const AttributeDescriptor& d, int l)
270 mLevelDescriptorList[l].Add(d);
271 // TO DO : update DicomTagToName and NameToDicomTag map
273 //==================================================================
275 //==================================================================
276 /// Clears the Descriptor
277 void Descriptor::Clear()
279 mLevelDescriptorList.clear();
282 //==================================================================
284 //==================================================================
285 /// Builds the key to value map of all the attributes of the tree
286 void Descriptor::BuildAttributeMap( std::map<std::string,std::string>& map ) const
289 LevelDescriptorListType::const_iterator l;
290 for (l = GetLevelDescriptorList().begin();
291 l!= GetLevelDescriptorList().end();
294 LevelDescriptor::AttributeDescriptorListType::const_iterator a;
295 for (a = l->GetAttributeDescriptorList().begin();
296 a!= l->GetAttributeDescriptorList().end();
305 //==================================================================
306 // test if an attribute is present in DescriptionList
307 // return level's name
308 const std::string Descriptor::isExist(const std::string i_attr)
310 std::string name = "";
311 LevelDescriptorListType::const_iterator l = GetLevelDescriptorList().begin();
312 for (; l!= GetLevelDescriptorList().end(); ++l)
314 LevelDescriptor::AttributeDescriptorListType::const_iterator a = l->GetAttributeDescriptorList().begin();
315 for(;a!= l->GetAttributeDescriptorList().end(); ++a)
317 if (a->GetKey() == i_attr)