30
30
31
31
const std::string STUDY_INSTANCE_UID = " 0020|000D" ;
32
32
const 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 " ;
35
35
36
36
rapidjson::Value mapToJsonObj (const TagMap &tags, rapidjson::Document::AllocatorType &allocator)
37
37
{
@@ -73,29 +73,48 @@ rapidjson::Value jsonFromTags(const TagMap &tags, const TagNames &tagNames, rapi
73
73
return mapToJsonObj (filteredTags, allocator);
74
74
}
75
75
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
+
77
102
struct dicomFileHash
78
103
{
79
- std::size_t operator ()(const DicomFile &dFile ) const
104
+ std::size_t operator ()(const DicomFile &dicomFile ) const
80
105
{
81
- return std::hash<File >{}(dFile. first );
106
+ return std::hash<FileName >{}(dicomFile. fileName );
82
107
}
83
108
};
84
109
using DicomFiles = std::unordered_set<DicomFile, dicomFileHash>;
85
110
86
- DicomFiles readTags (const std::vector<File > &files)
111
+ DicomFiles loadFiles (const std::vector<FileName > &files)
87
112
{
88
113
DicomFiles dicomFiles;
89
114
itk::DICOMTagReader tagReader;
90
- for (const File &fileName : files)
115
+ for (const FileName &fileName : files)
91
116
{
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));
99
118
}
100
119
return dicomFiles;
101
120
}
@@ -108,35 +127,33 @@ bool compareTags(const TagMap &tags1, const TagMap &tags2, const TagKeys &tagKey
108
127
{
109
128
for (const auto &tagKey : tagKeys)
110
129
{
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 ())
114
133
{
115
134
return false ;
116
135
}
117
- if (it1 ->second != it2 ->second )
136
+ if (tagA ->second != tagB ->second )
118
137
{
119
138
return false ;
120
139
}
121
140
}
122
141
return true ;
123
142
}
124
143
125
- bool isSameVolume (const TagMap &tags1 , const TagMap &tags2 )
144
+ bool isSameVolume (const TagMap &tagsA , const TagMap &tagsB )
126
145
{
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});
129
147
}
130
148
131
149
Volumes groupByVolume (const DicomFiles &dicomFiles)
132
150
{
133
151
Volumes volumes;
134
152
for (const DicomFile &dicomFile : dicomFiles)
135
153
{
136
- const auto tags = dicomFile.second ;
154
+ const auto tags = dicomFile.tags ;
137
155
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); });
140
157
141
158
if (matchingVolume != volumes.end ())
142
159
{
@@ -156,10 +173,10 @@ ImageSets groupByImageSet(const Volumes &volumes)
156
173
ImageSets imageSets;
157
174
for (const Volume &volume : volumes)
158
175
{
159
- const auto volumeTags = volume.begin ()->second ;
176
+ const auto volumeTags = volume.begin ()->tags ;
160
177
auto matchingImageSet = std::find_if (imageSets.begin (), imageSets.end (), [&volumeTags](const Volumes &volumes)
161
178
{
162
- const TagMap imageSetTags = volumes.begin ()->begin ()->second ;
179
+ const TagMap imageSetTags = volumes.begin ()->begin ()->tags ;
163
180
return compareTags (imageSetTags, volumeTags, {STUDY_INSTANCE_UID}); });
164
181
if (matchingImageSet != imageSets.end ())
165
182
{
@@ -179,18 +196,18 @@ Volumes sortSpatially(Volumes &volumes)
179
196
Volumes sortedVolumes;
180
197
for (Volume &volume : volumes)
181
198
{
182
- std::vector<std::string> unsortedSerieFileNames ;
199
+ std::vector<std::string> unsortedSeriesFileNames ;
183
200
for (const DicomFile &dicomFile : volume)
184
201
{
185
- unsortedSerieFileNames .push_back (dicomFile.first );
202
+ unsortedSeriesFileNames .push_back (dicomFile.fileName );
186
203
}
187
- std::vector<std::string> sortedFileNames = sortSpatially (unsortedSerieFileNames );
204
+ std::vector<std::string> sortedFileNames = sortSpatially (unsortedSeriesFileNames );
188
205
189
206
Volume sorted;
190
207
for (const auto &fileName : sortedFileNames)
191
208
{
192
209
const auto matchingDicomFile = std::find_if (volume.begin (), volume.end (), [&fileName](const DicomFile &dicomFile)
193
- { return dicomFile.first == fileName; });
210
+ { return dicomFile.fileName == fileName; });
194
211
if (matchingDicomFile != volume.end ())
195
212
{
196
213
sorted.push_back (*matchingDicomFile);
@@ -214,8 +231,8 @@ rapidjson::Document toJson(const ImageSets &imageSets)
214
231
rapidjson::Value instances (rapidjson::kObjectType );
215
232
for (const auto &dicomFile : volume)
216
233
{
217
- File file = dicomFile.first ;
218
- dicomTags = dicomFile.second ;
234
+ FileName file = dicomFile.fileName ;
235
+ dicomTags = dicomFile.tags ;
219
236
// filter out patient, study, series tags
220
237
TagMap instanceTags = remove (dicomTags, PATIENT_TAG_NAMES);
221
238
instanceTags = remove (instanceTags, STUDY_TAG_NAMES);
@@ -290,7 +307,7 @@ int main(int argc, char *argv[])
290
307
291
308
ITK_WASM_PARSE (pipeline);
292
309
293
- const DicomFiles dicomFiles = readTags (files);
310
+ const DicomFiles dicomFiles = loadFiles (files);
294
311
Volumes volumes = groupByVolume (dicomFiles);
295
312
volumes = sortSpatially (volumes);
296
313
const ImageSets imageSets = groupByImageSet (volumes);
0 commit comments