Skip to content

Commit e68c930

Browse files
committed
fix(image-sets-normalization): check more tags when grouping volumes
refactor DicomFile to struct
1 parent d4ec0c3 commit e68c930

File tree

2 files changed

+50
-33
lines changed

2 files changed

+50
-33
lines changed

packages/dicom/gdcm/image-sets-normalization.cxx

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030

3131
const std::string STUDY_INSTANCE_UID = "0020|000D";
3232
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";
3535

3636
rapidjson::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+
77102
struct 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
};
84109
using 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

131149
Volumes 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

Comments
 (0)