Skip to content

Commit df876af

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

File tree

2 files changed

+37
-26
lines changed

2 files changed

+37
-26
lines changed

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

+37-26
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@
3030

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

34-
using File = std::string;
3536

3637
rapidjson::Value mapToJsonObj(const TagMap &tags, rapidjson::Document::AllocatorType &allocator)
3738
{
@@ -73,29 +74,41 @@ rapidjson::Value jsonFromTags(const TagMap &tags, const TagNames &tagNames, rapi
7374
return mapToJsonObj(filteredTags, allocator);
7475
}
7576

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+
7790
struct dicomFileHash
7891
{
79-
std::size_t operator()(const DicomFile &dFile) const
92+
std::size_t operator()(const DicomFile &dicomFile) const
8093
{
81-
return std::hash<File>{}(dFile.first);
94+
return std::hash<FileName>{}(dicomFile.fileName);
8295
}
8396
};
8497
using DicomFiles = std::unordered_set<DicomFile, dicomFileHash>;
8598

86-
DicomFiles readTags(const std::vector<File> &files)
99+
DicomFiles loadFiles(const std::vector<FileName> &files)
87100
{
88101
DicomFiles dicomFiles;
89102
itk::DICOMTagReader tagReader;
90-
for (const File &fileName : files)
103+
for (const FileName &fileName : files)
91104
{
92105
if (!tagReader.CanReadFile(fileName))
93106
{
94107
throw std::runtime_error("Could not read the input DICOM file: " + fileName);
95108
}
96109
tagReader.SetFileName(fileName);
97110
const TagMap dicomTags = tagReader.ReadAllTags();
98-
dicomFiles.insert(std::make_pair(fileName, dicomTags));
111+
dicomFiles.insert({fileName, dicomTags});
99112
}
100113
return dicomFiles;
101114
}
@@ -108,35 +121,33 @@ bool compareTags(const TagMap &tags1, const TagMap &tags2, const TagKeys &tagKey
108121
{
109122
for (const auto &tagKey : tagKeys)
110123
{
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())
114127
{
115128
return false;
116129
}
117-
if (it1->second != it2->second)
130+
if (tagA->second != tagB->second)
118131
{
119132
return false;
120133
}
121134
}
122135
return true;
123136
}
124137

125-
bool isSameVolume(const TagMap &tags1, const TagMap &tags2)
138+
bool isSameVolume(const TagMap &tagsA, const TagMap &tagsB)
126139
{
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});
129141
}
130142

131143
Volumes groupByVolume(const DicomFiles &dicomFiles)
132144
{
133145
Volumes volumes;
134146
for (const DicomFile &dicomFile : dicomFiles)
135147
{
136-
const auto tags = dicomFile.second;
148+
const auto tags = dicomFile.tags;
137149
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); });
140151

141152
if (matchingVolume != volumes.end())
142153
{
@@ -156,10 +167,10 @@ ImageSets groupByImageSet(const Volumes &volumes)
156167
ImageSets imageSets;
157168
for (const Volume &volume : volumes)
158169
{
159-
const auto volumeTags = volume.begin()->second;
170+
const auto volumeTags = volume.begin()->tags;
160171
auto matchingImageSet = std::find_if(imageSets.begin(), imageSets.end(), [&volumeTags](const Volumes &volumes)
161172
{
162-
const TagMap imageSetTags = volumes.begin()->begin()->second;
173+
const TagMap imageSetTags = volumes.begin()->begin()->tags;
163174
return compareTags(imageSetTags, volumeTags, {STUDY_INSTANCE_UID}); });
164175
if (matchingImageSet != imageSets.end())
165176
{
@@ -179,18 +190,18 @@ Volumes sortSpatially(Volumes &volumes)
179190
Volumes sortedVolumes;
180191
for (Volume &volume : volumes)
181192
{
182-
std::vector<std::string> unsortedSerieFileNames;
193+
std::vector<std::string> unsortedSeriesFileNames;
183194
for (const DicomFile &dicomFile : volume)
184195
{
185-
unsortedSerieFileNames.push_back(dicomFile.first);
196+
unsortedSeriesFileNames.push_back(dicomFile.fileName);
186197
}
187-
std::vector<std::string> sortedFileNames = sortSpatially(unsortedSerieFileNames);
198+
std::vector<std::string> sortedFileNames = sortSpatially(unsortedSeriesFileNames);
188199

189200
Volume sorted;
190201
for (const auto &fileName : sortedFileNames)
191202
{
192203
const auto matchingDicomFile = std::find_if(volume.begin(), volume.end(), [&fileName](const DicomFile &dicomFile)
193-
{ return dicomFile.first == fileName; });
204+
{ return dicomFile.fileName == fileName; });
194205
if (matchingDicomFile != volume.end())
195206
{
196207
sorted.push_back(*matchingDicomFile);
@@ -214,8 +225,8 @@ rapidjson::Document toJson(const ImageSets &imageSets)
214225
rapidjson::Value instances(rapidjson::kObjectType);
215226
for (const auto &dicomFile : volume)
216227
{
217-
File file = dicomFile.first;
218-
dicomTags = dicomFile.second;
228+
FileName file = dicomFile.fileName;
229+
dicomTags = dicomFile.tags;
219230
// filter out patient, study, series tags
220231
TagMap instanceTags = remove(dicomTags, PATIENT_TAG_NAMES);
221232
instanceTags = remove(instanceTags, STUDY_TAG_NAMES);
@@ -290,7 +301,7 @@ int main(int argc, char *argv[])
290301

291302
ITK_WASM_PARSE(pipeline);
292303

293-
const DicomFiles dicomFiles = readTags(files);
304+
const DicomFiles dicomFiles = loadFiles(files);
294305
Volumes volumes = groupByVolume(dicomFiles);
295306
volumes = sortSpatially(volumes);
296307
const ImageSets imageSets = groupByImageSet(volumes);

0 commit comments

Comments
 (0)