3030
3131const std::string STUDY_INSTANCE_UID = " 0020|000D" ;
3232const std::string SERIES_INSTANCE_UID = " 0020|000e" ;
33-
34- using File = std::string;
33+ const std::string FRAME_OF_REFERENCE_UID = " 0020|0052 " ;
34+ const std::string IMAGE_ORIENTATION_PATIENT = " 0020|0037 " ;
3535
3636rapidjson::Value mapToJsonObj (const TagMap &tags, rapidjson::Document::AllocatorType &allocator)
3737{
@@ -73,29 +73,48 @@ rapidjson::Value jsonFromTags(const TagMap &tags, const TagNames &tagNames, rapi
7373 return mapToJsonObj (filteredTags, allocator);
7474}
7575
76- using DicomFile = std::pair<const File, const TagMap>;
76+ using FileName = std::string;
77+
78+ struct DicomFile
79+ {
80+ FileName fileName;
81+ TagMap tags;
82+ gdcm::DataSet dataSet;
83+
84+ DicomFile (const FileName &fileName)
85+ : fileName(fileName)
86+ {
87+ itk::DICOMTagReader tagReader;
88+ if (!tagReader.CanReadFile (fileName))
89+ {
90+ throw std::runtime_error (" Could not read the input DICOM file: " + fileName);
91+ }
92+ tagReader.SetFileName (fileName);
93+ tags = tagReader.ReadAllTags ();
94+ }
95+
96+ bool operator ==(const DicomFile &other) const
97+ {
98+ return fileName == other.fileName ;
99+ }
100+ };
101+
77102struct dicomFileHash
78103{
79- std::size_t operator ()(const DicomFile &dFile ) const
104+ std::size_t operator ()(const DicomFile &dicomFile ) const
80105 {
81- return std::hash<File >{}(dFile. first );
106+ return std::hash<FileName >{}(dicomFile. fileName );
82107 }
83108};
84109using DicomFiles = std::unordered_set<DicomFile, dicomFileHash>;
85110
86- DicomFiles readTags (const std::vector<File > &files)
111+ DicomFiles loadFiles (const std::vector<FileName > &files)
87112{
88113 DicomFiles dicomFiles;
89114 itk::DICOMTagReader tagReader;
90- for (const File &fileName : files)
115+ for (const FileName &fileName : files)
91116 {
92- if (!tagReader.CanReadFile (fileName))
93- {
94- throw std::runtime_error (" Could not read the input DICOM file: " + fileName);
95- }
96- tagReader.SetFileName (fileName);
97- const TagMap dicomTags = tagReader.ReadAllTags ();
98- dicomFiles.insert (std::make_pair (fileName, dicomTags));
117+ dicomFiles.insert (DicomFile (fileName));
99118 }
100119 return dicomFiles;
101120}
@@ -108,35 +127,33 @@ bool compareTags(const TagMap &tags1, const TagMap &tags2, const TagKeys &tagKey
108127{
109128 for (const auto &tagKey : tagKeys)
110129 {
111- const auto it1 = tags1.find (tagKey);
112- const auto it2 = tags2.find (tagKey);
113- if (it1 == tags1.end () || it2 == tags2.end ())
130+ const auto tagA = tags1.find (tagKey);
131+ const auto tagB = tags2.find (tagKey);
132+ if (tagA == tags1.end () || tagB == tags2.end ())
114133 {
115134 return false ;
116135 }
117- if (it1 ->second != it2 ->second )
136+ if (tagA ->second != tagB ->second )
118137 {
119138 return false ;
120139 }
121140 }
122141 return true ;
123142}
124143
125- bool isSameVolume (const TagMap &tags1 , const TagMap &tags2 )
144+ bool isSameVolume (const TagMap &tagsA , const TagMap &tagsB )
126145{
127- // TODO check cosines
128- return compareTags (tags1, tags2, {SERIES_INSTANCE_UID});
146+ return compareTags (tagsA, tagsB, {SERIES_INSTANCE_UID, FRAME_OF_REFERENCE_UID, IMAGE_ORIENTATION_PATIENT});
129147}
130148
131149Volumes groupByVolume (const DicomFiles &dicomFiles)
132150{
133151 Volumes volumes;
134152 for (const DicomFile &dicomFile : dicomFiles)
135153 {
136- const auto tags = dicomFile.second ;
154+ const auto tags = dicomFile.tags ;
137155 auto matchingVolume = std::find_if (volumes.begin (), volumes.end (), [&tags](const Volume &volume)
138- {
139- return isSameVolume (volume.begin ()->second , tags); });
156+ { return isSameVolume (volume.begin ()->tags , tags); });
140157
141158 if (matchingVolume != volumes.end ())
142159 {
@@ -156,10 +173,10 @@ ImageSets groupByImageSet(const Volumes &volumes)
156173 ImageSets imageSets;
157174 for (const Volume &volume : volumes)
158175 {
159- const auto volumeTags = volume.begin ()->second ;
176+ const auto volumeTags = volume.begin ()->tags ;
160177 auto matchingImageSet = std::find_if (imageSets.begin (), imageSets.end (), [&volumeTags](const Volumes &volumes)
161178 {
162- const TagMap imageSetTags = volumes.begin ()->begin ()->second ;
179+ const TagMap imageSetTags = volumes.begin ()->begin ()->tags ;
163180 return compareTags (imageSetTags, volumeTags, {STUDY_INSTANCE_UID}); });
164181 if (matchingImageSet != imageSets.end ())
165182 {
@@ -179,18 +196,18 @@ Volumes sortSpatially(Volumes &volumes)
179196 Volumes sortedVolumes;
180197 for (Volume &volume : volumes)
181198 {
182- std::vector<std::string> unsortedSerieFileNames ;
199+ std::vector<std::string> unsortedSeriesFileNames ;
183200 for (const DicomFile &dicomFile : volume)
184201 {
185- unsortedSerieFileNames .push_back (dicomFile.first );
202+ unsortedSeriesFileNames .push_back (dicomFile.fileName );
186203 }
187- std::vector<std::string> sortedFileNames = sortSpatially (unsortedSerieFileNames );
204+ std::vector<std::string> sortedFileNames = sortSpatially (unsortedSeriesFileNames );
188205
189206 Volume sorted;
190207 for (const auto &fileName : sortedFileNames)
191208 {
192209 const auto matchingDicomFile = std::find_if (volume.begin (), volume.end (), [&fileName](const DicomFile &dicomFile)
193- { return dicomFile.first == fileName; });
210+ { return dicomFile.fileName == fileName; });
194211 if (matchingDicomFile != volume.end ())
195212 {
196213 sorted.push_back (*matchingDicomFile);
@@ -214,8 +231,8 @@ rapidjson::Document toJson(const ImageSets &imageSets)
214231 rapidjson::Value instances (rapidjson::kObjectType );
215232 for (const auto &dicomFile : volume)
216233 {
217- File file = dicomFile.first ;
218- dicomTags = dicomFile.second ;
234+ FileName file = dicomFile.fileName ;
235+ dicomTags = dicomFile.tags ;
219236 // filter out patient, study, series tags
220237 TagMap instanceTags = remove (dicomTags, PATIENT_TAG_NAMES);
221238 instanceTags = remove (instanceTags, STUDY_TAG_NAMES);
@@ -290,7 +307,7 @@ int main(int argc, char *argv[])
290307
291308 ITK_WASM_PARSE (pipeline);
292309
293- const DicomFiles dicomFiles = readTags (files);
310+ const DicomFiles dicomFiles = loadFiles (files);
294311 Volumes volumes = groupByVolume (dicomFiles);
295312 volumes = sortSpatially (volumes);
296313 const ImageSets imageSets = groupByImageSet (volumes);
0 commit comments