Skip to content

Commit 0ecd248

Browse files
committed
feat(image-sets-normalization): array and number types for tag values
1 parent e68c930 commit 0ecd248

File tree

2 files changed

+649
-260
lines changed

2 files changed

+649
-260
lines changed

packages/dicom/gdcm/Tags.h

+152-189
Original file line numberDiff line numberDiff line change
@@ -22,212 +22,175 @@
2222
#include <unordered_set>
2323
#include "itkGDCMImageIO.h"
2424

25-
using TagKey = std::string;
26-
using TagKeys = std::unordered_set<TagKey>;
27-
using TagNames = std::unordered_map<TagKey, std::string>;
28-
using TagMap = TagNames; // TagKey -> TagValue
25+
using Tag = gdcm::Tag;
26+
using Tags = std::set<Tag>;
27+
28+
const Tag STUDY_UID(0x0020, 0x000d); // "Study Instance UID"
29+
const Tag SERIES_UID(0x0020, 0x000e); // "Series Instance UID"
30+
const Tag INSTANCE_UID(0x0008, 0x0018); // "Instance UID"
31+
32+
const Tag FRAME_OF_REFERENCE_UID(0x0020, 0x0052);
33+
const Tag IMAGE_ORIENTATION_PATIENT(0x0020, 0x0037);
2934

3035
// Tag names from https://docs.aws.amazon.com/healthimaging/latest/devguide/reference-dicom-support.html
31-
const TagNames PATIENT_TAG_NAMES = {
36+
const Tags PATIENT_TAGS = {
3237
// Patient Module Elements
33-
{"0010|0010", "Patient's Name"},
34-
{"0010|0020", "Patient ID"},
38+
Tag(0x0010, 0x0010), // "Patient's Name"
39+
Tag(0x0010, 0x0020), // "Patient ID"
3540
// Issuer of Patient ID Macro Elements
36-
{"0010|0021", "Issuer of Patient ID"},
37-
{"0010|0024", "Issuer of Patient ID Qualifiers Sequence"},
38-
{"0010|0022", "Type of Patient ID"},
39-
{"0010|0030", "Patient's Birth Date"},
40-
{"0010|0033", "Patient's Birth Date in Alternative Calendar"},
41-
{"0010|0034", "Patient's Death Date in Alternative Calendar"},
42-
{"0010|0035", "Patient's Alternative Calendar Attribute"},
43-
{"0010|0040", "Patient's Sex"},
44-
{"0010|1100", "Referenced Patient Photo Sequence"},
45-
{"0010|0200", "Quality Control Subject"},
46-
{"0008|1120", "Referenced Patient Sequence"},
47-
{"0010|0032", "Patient's Birth Time"},
48-
{"0010|1002", "Other Patient IDs Sequence"},
49-
{"0010|1001", "Other Patient Names"},
50-
{"0010|2160", "Ethnic Group"},
51-
{"0010|4000", "Patient Comments"},
52-
{"0010|2201", "Patient Species Description"},
53-
{"0010|2202", "Patient Species Code Sequence Attribute"},
54-
{"0010|2292", "Patient Breed Description"},
55-
{"0010|2293", "Patient Breed Code Sequence"},
56-
{"0010|2294", "Breed Registration Sequence Attribute"},
57-
{"0010|0212", "Strain Description"},
58-
{"0010|0213", "Strain Nomenclature Attribute"},
59-
{"0010|0219", "Strain Code Sequence"},
60-
{"0010|0218", "Strain Additional Information Attribute"},
61-
{"0010|0216", "Strain Stock Sequence"},
62-
{"0010|0221", "Genetic Modifications Sequence Attribute"},
63-
{"0010|2297", "Responsible Person"},
64-
{"0010|2298", "Responsible Person Role Attribute"},
65-
{"0010|2299", "Responsible Organization"},
66-
{"0012|0062", "Patient Identity Removed"},
67-
{"0012|0063", "De-identification Method"},
68-
{"0012|0064", "De-identification Method Code Sequence"},
41+
Tag(0x0010, 0x0021), // "Issuer of Patient ID"
42+
Tag(0x0010, 0x0024), // "Issuer of Patient ID Qualifiers Sequence"
43+
Tag(0x0010, 0x0022), // "Type of Patient ID"
44+
Tag(0x0010, 0x0030), // "Patient's Birth Date"
45+
Tag(0x0010, 0x0033), // "Patient's Birth Date in Alternative Calendar"
46+
Tag(0x0010, 0x0034), // "Patient's Death Date in Alternative Calendar"
47+
Tag(0x0010, 0x0035), // "Patient's Alternative Calendar Attribute"
48+
Tag(0x0010, 0x0040), // "Patient's Sex"
49+
Tag(0x0010, 0x1100), // "Referenced Patient Photo Sequence"
50+
Tag(0x0010, 0x0200), // "Quality Control Subject"
51+
Tag(0x0008, 0x1120), // "Referenced Patient Sequence"
52+
Tag(0x0010, 0x0032), // "Patient's Birth Time"
53+
Tag(0x0010, 0x1002), // "Other Patient IDs Sequence"
54+
Tag(0x0010, 0x1001), // "Other Patient Names"
55+
Tag(0x0010, 0x2160), // "Ethnic Group"
56+
Tag(0x0010, 0x4000), // "Patient Comments"
57+
Tag(0x0010, 0x2201), // "Patient Species Description"
58+
Tag(0x0010, 0x2202), // "Patient Species Code Sequence Attribute"
59+
Tag(0x0010, 0x2292), // "Patient Breed Description"
60+
Tag(0x0010, 0x2293), // "Patient Breed Code Sequence"
61+
Tag(0x0010, 0x2294), // "Breed Registration Sequence Attribute"
62+
Tag(0x0010, 0x0212), // "Strain Description"
63+
Tag(0x0010, 0x0213), // "Strain Nomenclature Attribute"
64+
Tag(0x0010, 0x0219), // "Strain Code Sequence"
65+
Tag(0x0010, 0x0218), // "Strain Additional Information Attribute"
66+
Tag(0x0010, 0x0216), // "Strain Stock Sequence"
67+
Tag(0x0010, 0x0221), // "Genetic Modifications Sequence Attribute"
68+
Tag(0x0010, 0x2297), // "Responsible Person"
69+
Tag(0x0010, 0x2298), // "Responsible Person Role Attribute"
70+
Tag(0x0010, 0x2299), // "Responsible Organization"
71+
Tag(0x0012, 0x0062), // "Patient Identity Removed"
72+
Tag(0x0012, 0x0063), // "De-identification Method"
73+
Tag(0x0012, 0x0064), // "De-identification Method Code Sequence"
6974
// Patient Group Macro Elements
70-
{"0010|0026", "Source Patient Group Identification Sequence"},
71-
{"0010|0027", "Group of Patients Identification Sequence"},
75+
Tag(0x0010, 0x0026), // "Source Patient Group Identification Sequence"
76+
Tag(0x0010, 0x0027), // "Group of Patients Identification Sequence"
7277
// Clinical Trial Subject Module
73-
{"0012|0010", "Clinical Trial Sponsor Name"},
74-
{"0012|0020", "Clinical Trial Protocol ID"},
75-
{"0012|0021", "Clinical Trial Protocol Name Attribute"},
76-
{"0012|0030", "Clinical Trial Site ID"},
77-
{"0012|0031", "Clinical Trial Site Name"},
78-
{"0012|0040", "Clinical Trial Subject ID"},
79-
{"0012|0042", "Clinical Trial Subject Reading ID"},
80-
{"0012|0081", "Clinical Trial Protocol Ethics Committee Name"},
81-
{"0012|0082", "Clinical Trial Protocol Ethics Committee Approval Number"},
78+
Tag(0x0012, 0x0010), // "Clinical Trial Sponsor Name"
79+
Tag(0x0012, 0x0020), // "Clinical Trial Protocol ID"
80+
Tag(0x0012, 0x0021), // "Clinical Trial Protocol Name Attribute"
81+
Tag(0x0012, 0x0030), // "Clinical Trial Site ID"
82+
Tag(0x0012, 0x0031), // "Clinical Trial Site Name"
83+
Tag(0x0012, 0x0040), // "Clinical Trial Subject ID"
84+
Tag(0x0012, 0x0042), // "Clinical Trial Subject Reading ID"
85+
Tag(0x0012, 0x0081), // "Clinical Trial Protocol Ethics Committee Name"
86+
Tag(0x0012, 0x0082) // "Clinical Trial Protocol Ethics Committee Approval Number"
8287
};
8388

84-
const TagNames STUDY_TAG_NAMES = {
89+
const Tags STUDY_TAGS = {
8590
// General Study Module
86-
{"0020|000d", "Study Instance UID"},
87-
{"0008|0020", "Study Date"},
88-
{"0008|0030", "Study Time"},
89-
{"0008|0090", "Referring Physician's Name"},
90-
{"0008|0096", "Referring Physician Identification Sequence"},
91-
{"0008|009c", "Consulting Physician's Name"},
92-
{"0008|009d", "Consulting Physician Identification Sequence"},
93-
{"0020|0010", "Study ID"},
94-
{"0008|0050", "Accession Number"},
95-
{"0008|0051", "Issuer of Accession Number Sequence"},
96-
{"0008|1030", "Study Description"},
97-
{"0008|1048", "Physician(s) of Record"},
98-
{"0008|1049", "Physician(s) of Record Identification Sequence"},
99-
{"0008|1060", "Name of Physician(s) Reading Study"},
100-
{"0008|1062", "Physician(s) Reading Study Identification Sequence"},
101-
{"0032|1033", "Requesting Service"},
102-
{"0032|1034", "Requesting Service Code Sequence"},
103-
{"0008|1110", "Referenced Study Sequence"},
104-
{"0008|1032", "Procedure Code Sequence"},
105-
{"0040|1012", "Reason For Performed Procedure Code Sequence"},
91+
Tag(0x0020, 0x000d), // "Study Instance UID"
92+
Tag(0x0008, 0x0020), // "Study Date"
93+
Tag(0x0008, 0x0030), // "Study Time"
94+
Tag(0x0008, 0x0090), // "Referring Physician's Name"
95+
Tag(0x0008, 0x0096), // "Referring Physician Identification Sequence"
96+
Tag(0x0008, 0x009c), // "Consulting Physician's Name"
97+
Tag(0x0008, 0x009d), // "Consulting Physician Identification Sequence"
98+
Tag(0x0020, 0x0010), // "Study ID"
99+
Tag(0x0008, 0x0050), // "Accession Number"
100+
Tag(0x0008, 0x0051), // "Issuer of Accession Number Sequence"
101+
Tag(0x0008, 0x1030), // "Study Description"
102+
Tag(0x0008, 0x1048), // "Physician(s) of Record"
103+
Tag(0x0008, 0x1049), // "Physician(s) of Record Identification Sequence"
104+
Tag(0x0008, 0x1060), // "Name of Physician(s) Reading Study"
105+
Tag(0x0008, 0x1062), // "Physician(s) Reading Study Identification Sequence"
106+
Tag(0x0032, 0x1033), // "Requesting Service"
107+
Tag(0x0032, 0x1034), // "Requesting Service Code Sequence"
108+
Tag(0x0008, 0x1110), // "Referenced Study Sequence"
109+
Tag(0x0008, 0x1032), // "Procedure Code Sequence"
110+
Tag(0x0040, 0x1012), // "Reason For Performed Procedure Code Sequence"
106111
// Patient Study Module
107-
{"0008|1080", "Admitting Diagnoses Description"},
108-
{"0008|1084", "Admitting Diagnoses Code Sequence"},
109-
{"0010|1010", "Patient's Age"},
110-
{"0010|1020", "Patient's Size"},
111-
{"0010|1030", "Patient's Weight"},
112-
{"0010|1022", "Patient's Body Mass Index"},
113-
{"0010|1023", "Measured AP Dimension"},
114-
{"0010|1024", "Measured Lateral Dimension"},
115-
{"0010|1021", "Patient's Size Code Sequence"},
116-
{"0010|2000", "Medical Alerts"},
117-
{"0010|2110", "Allergies"},
118-
{"0010|21a0", "Smoking Status"},
119-
{"0010|21c0", "Pregnancy Status"},
120-
{"0010|21d0", "Last Menstrual Date"},
121-
{"0038|0500", "Patient State"},
122-
{"0010|2180", "Occupation"},
123-
{"0010|21b0", "Additional Patient History"},
124-
{"0038|0010", "Admission ID"},
125-
{"0038|0014", "Issuer of Admission ID Sequence"},
126-
{"0032|1066", "Reason for Visit"},
127-
{"0032|1067", "Reason for Visit Code Sequence"},
128-
{"0038|0060", "Service Episode ID"},
129-
{"0038|0064", "Issuer of Service Episode ID Sequence"},
130-
{"0038|0062", "Service Episode Description"},
131-
{"0010|2203", "Patient's Sex Neutered"},
112+
Tag(0x0008, 0x1080), // "Admitting Diagnoses Description"
113+
Tag(0x0008, 0x1084), // "Admitting Diagnoses Code Sequence"
114+
Tag(0x0010, 0x1010), // "Patient's Age"
115+
Tag(0x0010, 0x1020), // "Patient's Size"
116+
Tag(0x0010, 0x1030), // "Patient's Weight"
117+
Tag(0x0010, 0x1022), // "Patient's Body Mass Index"
118+
Tag(0x0010, 0x1023), // "Measured AP Dimension"
119+
Tag(0x0010, 0x1024), // "Measured Lateral Dimension"
120+
Tag(0x0010, 0x1021), // "Patient's Size Code Sequence"
121+
Tag(0x0010, 0x2000), // "Medical Alerts"
122+
Tag(0x0010, 0x2110), // "Allergies"
123+
Tag(0x0010, 0x21a0), // "Smoking Status"
124+
Tag(0x0010, 0x21c0), // "Pregnancy Status"
125+
Tag(0x0010, 0x21d0), // "Last Menstrual Date"
126+
Tag(0x0038, 0x0500), // "Patient State"
127+
Tag(0x0010, 0x2180), // "Occupation"
128+
Tag(0x0010, 0x21b0), // "Additional Patient History"
129+
Tag(0x0038, 0x0010), // "Admission ID"
130+
Tag(0x0038, 0x0014), // "Issuer of Admission ID Sequence"
131+
Tag(0x0032, 0x1066), // "Reason for Visit"
132+
Tag(0x0032, 0x1067), // "Reason for Visit Code Sequence"
133+
Tag(0x0038, 0x0060), // "Service Episode ID"
134+
Tag(0x0038, 0x0064), // "Issuer of Service Episode ID Sequence"
135+
Tag(0x0038, 0x0062), // "Service Episode Description"
136+
Tag(0x0010, 0x2203), // "Patient's Sex Neutered"
132137
// Clinical Trial Study Module
133-
{"0012|0050", "Clinical Trial Time Point ID"},
134-
{"0012|0051", "Clinical Trial Time Point Description"},
135-
{"0012|0052", "Longitudinal Temporal Offset from Event"},
136-
{"0012|0053", "Longitudinal Temporal Event Type"},
137-
{"0012|0083", "Consent for Clinical Trial Use Sequence"},
138+
Tag(0x0012, 0x0050), // "Clinical Trial Time Point ID"
139+
Tag(0x0012, 0x0051), // "Clinical Trial Time Point Description"
140+
Tag(0x0012, 0x0052), // "Longitudinal Temporal Offset from Event"
141+
Tag(0x0012, 0x0053), // "Longitudinal Temporal Event Type"
142+
Tag(0x0012, 0x0083) // "Consent for Clinical Trial Use Sequence"
138143
};
139144

140-
const TagNames SERIES_TAG_NAMES = {
145+
const Tags SERIES_TAGS = {
141146
// General Series Module
142-
{"0008|0060", "Modality"},
143-
{"0020|000e", "Series Instance UID"},
144-
{"0020|0011", "Series Number"},
145-
{"0020|0060", "Laterality"},
146-
{"0008|0021", "Series Date"},
147-
{"0008|0031", "Series Time"},
148-
{"0008|1050", "Performing Physician's Name"},
149-
{"0008|1052", "Performing Physician Identification Sequence"},
150-
{"0018|1030", "Protocol Name"},
151-
{"0008|103e", "Series Description"},
152-
{"0008|103f", "Series Description Code Sequence"},
153-
{"0008|1070", "Operators' Name"},
154-
{"0008|1072", "Operator Identification Sequence"},
155-
{"0008|1111", "Referenced Performed Procedure Step Sequence"},
156-
{"0008|1250", "Related Series Sequence"},
157-
{"0018|0015", "Body Part Examined"},
158-
{"0018|5100", "Patient Position"},
159-
{"0028|0108", "Smallest Pixel Value in Series"},
160-
{"0028|0109", "Largest Pixel Value in Series"},
161-
{"0040|0275", "Request Attributes Sequence"},
162-
{"0010|2210", "Anatomical Orientation Type"},
163-
{"300a|0700", "Treatment Session UID"},
147+
Tag(0x0008, 0x0060), // "Modality"
148+
Tag(0x0020, 0x000e), // "Series Instance UID"
149+
Tag(0x0020, 0x0011), // "Series Number"
150+
Tag(0x0020, 0x0060), // "Laterality"
151+
Tag(0x0008, 0x0021), // "Series Date"
152+
Tag(0x0008, 0x0031), // "Series Time"
153+
Tag(0x0008, 0x1050), // "Performing Physician's Name"
154+
Tag(0x0008, 0x1052), // "Performing Physician Identification Sequence"
155+
Tag(0x0018, 0x1030), // "Protocol Name"
156+
Tag(0x0008, 0x103e), // "Series Description"
157+
Tag(0x0008, 0x103f), // "Series Description Code Sequence"
158+
Tag(0x0008, 0x1070), // "Operators' Name"
159+
Tag(0x0008, 0x1072), // "Operator Identification Sequence"
160+
Tag(0x0008, 0x1111), // "Referenced Performed Procedure Step Sequence"
161+
Tag(0x0008, 0x1250), // "Related Series Sequence"
162+
Tag(0x0018, 0x0015), // "Body Part Examined"
163+
Tag(0x0018, 0x5100), // "Patient Position"
164+
Tag(0x0028, 0x0108), // "Smallest Pixel Value in Series"
165+
Tag(0x0028, 0x0109), // "Largest Pixel Value in Series"
166+
Tag(0x0040, 0x0275), // "Request Attributes Sequence"
167+
Tag(0x0010, 0x2210), // "Anatomical Orientation Type"
168+
Tag(0x300a, 0x0700), // "Treatment Session UID"
164169
// Clinical Trial Series Module
165-
{"0012|0060", "Clinical Trial Coordinating Center Name"},
166-
{"0012|0071", "Clinical Trial Series ID"},
167-
{"0012|0072", "Clinical Trial Series Description"},
170+
Tag(0x0012, 0x0060), // "Clinical Trial Coordinating Center Name"
171+
Tag(0x0012, 0x0071), // "Clinical Trial Series ID"
172+
Tag(0x0012, 0x0072), // "Clinical Trial Series Description"
168173
// General Equipment Module
169-
{"0008|0070", "Manufacturer"},
170-
{"0008|0080", "Institution Name"},
171-
{"0008|0081", "Institution Address"},
172-
{"0008|1010", "Station Name"},
173-
{"0008|1040", "Institutional Department Name"},
174-
{"0008|1041", "Institutional Department Type Code Sequence"},
175-
{"0008|1090", "Manufacturer's Model Name"},
176-
{"0018|100b", "Manufacturer's Device Class UID"},
177-
{"0018|1000", "Device Serial Number"},
178-
{"0018|1020", "Software Versions"},
179-
{"0018|1008", "Gantry ID"},
180-
{"0018|100a", "UDI Sequence"},
181-
{"0018|1002", "Device UID"},
182-
{"0018|1050", "Spatial Resolution"},
183-
{"0018|1200", "Date of Last Calibration"},
184-
{"0018|1201", "Time of Last Calibration"},
185-
{"0028|0120", "Pixel Padding Value"},
174+
Tag(0x0008, 0x0070), // "Manufacturer"
175+
Tag(0x0008, 0x0080), // "Institution Name"
176+
Tag(0x0008, 0x0081), // "Institution Address"
177+
Tag(0x0008, 0x1010), // "Station Name"
178+
Tag(0x0008, 0x1040), // "Institutional Department Name"
179+
Tag(0x0008, 0x1041), // "Institutional Department Type Code Sequence"
180+
Tag(0x0008, 0x1090), // "Manufacturer's Model Name"
181+
Tag(0x0018, 0x100b), // "Manufacturer's Device Class UID"
182+
Tag(0x0018, 0x1000), // "Device Serial Number"
183+
Tag(0x0018, 0x1020), // "Software Versions"
184+
Tag(0x0018, 0x1008), // "Gantry ID"
185+
Tag(0x0018, 0x100a), // "UDI Sequence"
186+
Tag(0x0018, 0x1002), // "Device UID"
187+
Tag(0x0018, 0x1050), // "Spatial Resolution"
188+
Tag(0x0018, 0x1200), // "Date of Last Calibration"
189+
Tag(0x0018, 0x1201), // "Time of Last Calibration"
190+
Tag(0x0028, 0x0120), // "Pixel Padding Value"
186191
// Frame of Reference Module
187-
{"0020|0052", "Frame of Reference UID"},
188-
{"0020|1040", "Position Reference Indicator"},
192+
Tag(0x0020, 0x0052), // "Frame of Reference UID"
193+
Tag(0x0020, 0x1040), // "Position Reference Indicator"
189194
};
190195

191-
TagMap extractAndRename(const TagMap &tags, const TagNames &keeperTags)
192-
{
193-
TagMap extracted;
194-
for (const auto &[key, name] : keeperTags)
195-
{
196-
const auto it = tags.find(key);
197-
if (it != tags.end())
198-
{
199-
extracted[name] = it->second;
200-
}
201-
}
202-
return extracted;
203-
}
204-
205-
TagMap remove(const TagMap &tags, const TagNames &removeTags)
206-
{
207-
TagMap filteredTags = tags;
208-
for (const auto &[key, name] : removeTags)
209-
{
210-
filteredTags.erase(key);
211-
}
212-
return filteredTags;
213-
}
214-
215-
TagMap relabel(const TagMap &tags)
216-
{
217-
TagMap relabelTags;
218-
for (const auto &[key, value] : tags)
219-
{
220-
std::string name = key;
221-
if (itk::GDCMImageIO::GetLabelFromTag(key, name))
222-
{
223-
relabelTags[name] = value;
224-
}
225-
else
226-
{
227-
relabelTags[key] = value;
228-
}
229-
}
230-
return relabelTags;
231-
}
232-
233196
#endif // TAGS_H

0 commit comments

Comments
 (0)