30
30
31
31
const std::string STUDY_INSTANCE_UID = " 0020|000D" ;
32
32
const std::string SERIES_INSTANCE_UID = " 0020|000e" ;
33
+ const std::string FRAME_OF_REFERENCE_UID = " 0020|0052" ;
34
+ const std::string IMAGE_ORIENTATION_PATIENT = " 0020|0037" ;
33
35
34
- using File = std::string;
35
36
36
37
rapidjson::Value mapToJsonObj (const TagMap &tags, rapidjson::Document::AllocatorType &allocator)
37
38
{
@@ -73,29 +74,41 @@ rapidjson::Value jsonFromTags(const TagMap &tags, const TagNames &tagNames, rapi
73
74
return mapToJsonObj (filteredTags, allocator);
74
75
}
75
76
76
- using DicomFile = std::pair<const File, const TagMap>;
77
+ using FileName = std::string;
78
+
79
+ struct DicomFile
80
+ {
81
+ FileName fileName;
82
+ TagMap tags;
83
+
84
+ bool operator ==(const DicomFile &other) const
85
+ {
86
+ return fileName == other.fileName ;
87
+ }
88
+ };
89
+
77
90
struct dicomFileHash
78
91
{
79
- std::size_t operator ()(const DicomFile &dFile ) const
92
+ std::size_t operator ()(const DicomFile &dicomFile ) const
80
93
{
81
- return std::hash<File >{}(dFile. first );
94
+ return std::hash<FileName >{}(dicomFile. fileName );
82
95
}
83
96
};
84
97
using DicomFiles = std::unordered_set<DicomFile, dicomFileHash>;
85
98
86
- DicomFiles readTags (const std::vector<File > &files)
99
+ DicomFiles loadFiles (const std::vector<FileName > &files)
87
100
{
88
101
DicomFiles dicomFiles;
89
102
itk::DICOMTagReader tagReader;
90
- for (const File &fileName : files)
103
+ for (const FileName &fileName : files)
91
104
{
92
105
if (!tagReader.CanReadFile (fileName))
93
106
{
94
107
throw std::runtime_error (" Could not read the input DICOM file: " + fileName);
95
108
}
96
109
tagReader.SetFileName (fileName);
97
110
const TagMap dicomTags = tagReader.ReadAllTags ();
98
- dicomFiles.insert (std::make_pair ( fileName, dicomTags) );
111
+ dicomFiles.insert ({ fileName, dicomTags} );
99
112
}
100
113
return dicomFiles;
101
114
}
@@ -108,35 +121,33 @@ bool compareTags(const TagMap &tags1, const TagMap &tags2, const TagKeys &tagKey
108
121
{
109
122
for (const auto &tagKey : tagKeys)
110
123
{
111
- const auto it1 = tags1.find (tagKey);
112
- const auto it2 = tags2.find (tagKey);
113
- if (it1 == tags1.end () || it2 == tags2.end ())
124
+ const auto tagA = tags1.find (tagKey);
125
+ const auto tagB = tags2.find (tagKey);
126
+ if (tagA == tags1.end () || tagB == tags2.end ())
114
127
{
115
128
return false ;
116
129
}
117
- if (it1 ->second != it2 ->second )
130
+ if (tagA ->second != tagB ->second )
118
131
{
119
132
return false ;
120
133
}
121
134
}
122
135
return true ;
123
136
}
124
137
125
- bool isSameVolume (const TagMap &tags1 , const TagMap &tags2 )
138
+ bool isSameVolume (const TagMap &tagsA , const TagMap &tagsB )
126
139
{
127
- // TODO check cosines
128
- return compareTags (tags1, tags2, {SERIES_INSTANCE_UID});
140
+ return compareTags (tagsA, tagsB, {SERIES_INSTANCE_UID, FRAME_OF_REFERENCE_UID, IMAGE_ORIENTATION_PATIENT});
129
141
}
130
142
131
143
Volumes groupByVolume (const DicomFiles &dicomFiles)
132
144
{
133
145
Volumes volumes;
134
146
for (const DicomFile &dicomFile : dicomFiles)
135
147
{
136
- const auto tags = dicomFile.second ;
148
+ const auto tags = dicomFile.tags ;
137
149
auto matchingVolume = std::find_if (volumes.begin (), volumes.end (), [&tags](const Volume &volume)
138
- {
139
- return isSameVolume (volume.begin ()->second , tags); });
150
+ { return isSameVolume (volume.begin ()->tags , tags); });
140
151
141
152
if (matchingVolume != volumes.end ())
142
153
{
@@ -156,10 +167,10 @@ ImageSets groupByImageSet(const Volumes &volumes)
156
167
ImageSets imageSets;
157
168
for (const Volume &volume : volumes)
158
169
{
159
- const auto volumeTags = volume.begin ()->second ;
170
+ const auto volumeTags = volume.begin ()->tags ;
160
171
auto matchingImageSet = std::find_if (imageSets.begin (), imageSets.end (), [&volumeTags](const Volumes &volumes)
161
172
{
162
- const TagMap imageSetTags = volumes.begin ()->begin ()->second ;
173
+ const TagMap imageSetTags = volumes.begin ()->begin ()->tags ;
163
174
return compareTags (imageSetTags, volumeTags, {STUDY_INSTANCE_UID}); });
164
175
if (matchingImageSet != imageSets.end ())
165
176
{
@@ -179,18 +190,18 @@ Volumes sortSpatially(Volumes &volumes)
179
190
Volumes sortedVolumes;
180
191
for (Volume &volume : volumes)
181
192
{
182
- std::vector<std::string> unsortedSerieFileNames ;
193
+ std::vector<std::string> unsortedSeriesFileNames ;
183
194
for (const DicomFile &dicomFile : volume)
184
195
{
185
- unsortedSerieFileNames .push_back (dicomFile.first );
196
+ unsortedSeriesFileNames .push_back (dicomFile.fileName );
186
197
}
187
- std::vector<std::string> sortedFileNames = sortSpatially (unsortedSerieFileNames );
198
+ std::vector<std::string> sortedFileNames = sortSpatially (unsortedSeriesFileNames );
188
199
189
200
Volume sorted;
190
201
for (const auto &fileName : sortedFileNames)
191
202
{
192
203
const auto matchingDicomFile = std::find_if (volume.begin (), volume.end (), [&fileName](const DicomFile &dicomFile)
193
- { return dicomFile.first == fileName; });
204
+ { return dicomFile.fileName == fileName; });
194
205
if (matchingDicomFile != volume.end ())
195
206
{
196
207
sorted.push_back (*matchingDicomFile);
@@ -214,8 +225,8 @@ rapidjson::Document toJson(const ImageSets &imageSets)
214
225
rapidjson::Value instances (rapidjson::kObjectType );
215
226
for (const auto &dicomFile : volume)
216
227
{
217
- File file = dicomFile.first ;
218
- dicomTags = dicomFile.second ;
228
+ FileName file = dicomFile.fileName ;
229
+ dicomTags = dicomFile.tags ;
219
230
// filter out patient, study, series tags
220
231
TagMap instanceTags = remove (dicomTags, PATIENT_TAG_NAMES);
221
232
instanceTags = remove (instanceTags, STUDY_TAG_NAMES);
@@ -290,7 +301,7 @@ int main(int argc, char *argv[])
290
301
291
302
ITK_WASM_PARSE (pipeline);
292
303
293
- const DicomFiles dicomFiles = readTags (files);
304
+ const DicomFiles dicomFiles = loadFiles (files);
294
305
Volumes volumes = groupByVolume (dicomFiles);
295
306
volumes = sortSpatially (volumes);
296
307
const ImageSets imageSets = groupByImageSet (volumes);
0 commit comments