Skip to content

Commit

Permalink
feat(image-sets-normalization): array and number types for tag values
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulHax committed Apr 2, 2024
1 parent e68c930 commit 0ecd248
Show file tree
Hide file tree
Showing 2 changed files with 649 additions and 260 deletions.
341 changes: 152 additions & 189 deletions packages/dicom/gdcm/Tags.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,212 +22,175 @@
#include <unordered_set>
#include "itkGDCMImageIO.h"

using TagKey = std::string;
using TagKeys = std::unordered_set<TagKey>;
using TagNames = std::unordered_map<TagKey, std::string>;
using TagMap = TagNames; // TagKey -> TagValue
using Tag = gdcm::Tag;
using Tags = std::set<Tag>;

const Tag STUDY_UID(0x0020, 0x000d); // "Study Instance UID"
const Tag SERIES_UID(0x0020, 0x000e); // "Series Instance UID"
const Tag INSTANCE_UID(0x0008, 0x0018); // "Instance UID"

const Tag FRAME_OF_REFERENCE_UID(0x0020, 0x0052);
const Tag IMAGE_ORIENTATION_PATIENT(0x0020, 0x0037);

// Tag names from https://docs.aws.amazon.com/healthimaging/latest/devguide/reference-dicom-support.html
const TagNames PATIENT_TAG_NAMES = {
const Tags PATIENT_TAGS = {
// Patient Module Elements
{"0010|0010", "Patient's Name"},
{"0010|0020", "Patient ID"},
Tag(0x0010, 0x0010), // "Patient's Name"
Tag(0x0010, 0x0020), // "Patient ID"
// Issuer of Patient ID Macro Elements
{"0010|0021", "Issuer of Patient ID"},
{"0010|0024", "Issuer of Patient ID Qualifiers Sequence"},
{"0010|0022", "Type of Patient ID"},
{"0010|0030", "Patient's Birth Date"},
{"0010|0033", "Patient's Birth Date in Alternative Calendar"},
{"0010|0034", "Patient's Death Date in Alternative Calendar"},
{"0010|0035", "Patient's Alternative Calendar Attribute"},
{"0010|0040", "Patient's Sex"},
{"0010|1100", "Referenced Patient Photo Sequence"},
{"0010|0200", "Quality Control Subject"},
{"0008|1120", "Referenced Patient Sequence"},
{"0010|0032", "Patient's Birth Time"},
{"0010|1002", "Other Patient IDs Sequence"},
{"0010|1001", "Other Patient Names"},
{"0010|2160", "Ethnic Group"},
{"0010|4000", "Patient Comments"},
{"0010|2201", "Patient Species Description"},
{"0010|2202", "Patient Species Code Sequence Attribute"},
{"0010|2292", "Patient Breed Description"},
{"0010|2293", "Patient Breed Code Sequence"},
{"0010|2294", "Breed Registration Sequence Attribute"},
{"0010|0212", "Strain Description"},
{"0010|0213", "Strain Nomenclature Attribute"},
{"0010|0219", "Strain Code Sequence"},
{"0010|0218", "Strain Additional Information Attribute"},
{"0010|0216", "Strain Stock Sequence"},
{"0010|0221", "Genetic Modifications Sequence Attribute"},
{"0010|2297", "Responsible Person"},
{"0010|2298", "Responsible Person Role Attribute"},
{"0010|2299", "Responsible Organization"},
{"0012|0062", "Patient Identity Removed"},
{"0012|0063", "De-identification Method"},
{"0012|0064", "De-identification Method Code Sequence"},
Tag(0x0010, 0x0021), // "Issuer of Patient ID"
Tag(0x0010, 0x0024), // "Issuer of Patient ID Qualifiers Sequence"
Tag(0x0010, 0x0022), // "Type of Patient ID"
Tag(0x0010, 0x0030), // "Patient's Birth Date"
Tag(0x0010, 0x0033), // "Patient's Birth Date in Alternative Calendar"
Tag(0x0010, 0x0034), // "Patient's Death Date in Alternative Calendar"
Tag(0x0010, 0x0035), // "Patient's Alternative Calendar Attribute"
Tag(0x0010, 0x0040), // "Patient's Sex"
Tag(0x0010, 0x1100), // "Referenced Patient Photo Sequence"
Tag(0x0010, 0x0200), // "Quality Control Subject"
Tag(0x0008, 0x1120), // "Referenced Patient Sequence"
Tag(0x0010, 0x0032), // "Patient's Birth Time"
Tag(0x0010, 0x1002), // "Other Patient IDs Sequence"
Tag(0x0010, 0x1001), // "Other Patient Names"
Tag(0x0010, 0x2160), // "Ethnic Group"
Tag(0x0010, 0x4000), // "Patient Comments"
Tag(0x0010, 0x2201), // "Patient Species Description"
Tag(0x0010, 0x2202), // "Patient Species Code Sequence Attribute"
Tag(0x0010, 0x2292), // "Patient Breed Description"
Tag(0x0010, 0x2293), // "Patient Breed Code Sequence"
Tag(0x0010, 0x2294), // "Breed Registration Sequence Attribute"
Tag(0x0010, 0x0212), // "Strain Description"
Tag(0x0010, 0x0213), // "Strain Nomenclature Attribute"
Tag(0x0010, 0x0219), // "Strain Code Sequence"
Tag(0x0010, 0x0218), // "Strain Additional Information Attribute"
Tag(0x0010, 0x0216), // "Strain Stock Sequence"
Tag(0x0010, 0x0221), // "Genetic Modifications Sequence Attribute"
Tag(0x0010, 0x2297), // "Responsible Person"
Tag(0x0010, 0x2298), // "Responsible Person Role Attribute"
Tag(0x0010, 0x2299), // "Responsible Organization"
Tag(0x0012, 0x0062), // "Patient Identity Removed"
Tag(0x0012, 0x0063), // "De-identification Method"
Tag(0x0012, 0x0064), // "De-identification Method Code Sequence"
// Patient Group Macro Elements
{"0010|0026", "Source Patient Group Identification Sequence"},
{"0010|0027", "Group of Patients Identification Sequence"},
Tag(0x0010, 0x0026), // "Source Patient Group Identification Sequence"
Tag(0x0010, 0x0027), // "Group of Patients Identification Sequence"
// Clinical Trial Subject Module
{"0012|0010", "Clinical Trial Sponsor Name"},
{"0012|0020", "Clinical Trial Protocol ID"},
{"0012|0021", "Clinical Trial Protocol Name Attribute"},
{"0012|0030", "Clinical Trial Site ID"},
{"0012|0031", "Clinical Trial Site Name"},
{"0012|0040", "Clinical Trial Subject ID"},
{"0012|0042", "Clinical Trial Subject Reading ID"},
{"0012|0081", "Clinical Trial Protocol Ethics Committee Name"},
{"0012|0082", "Clinical Trial Protocol Ethics Committee Approval Number"},
Tag(0x0012, 0x0010), // "Clinical Trial Sponsor Name"
Tag(0x0012, 0x0020), // "Clinical Trial Protocol ID"
Tag(0x0012, 0x0021), // "Clinical Trial Protocol Name Attribute"
Tag(0x0012, 0x0030), // "Clinical Trial Site ID"
Tag(0x0012, 0x0031), // "Clinical Trial Site Name"
Tag(0x0012, 0x0040), // "Clinical Trial Subject ID"
Tag(0x0012, 0x0042), // "Clinical Trial Subject Reading ID"
Tag(0x0012, 0x0081), // "Clinical Trial Protocol Ethics Committee Name"
Tag(0x0012, 0x0082) // "Clinical Trial Protocol Ethics Committee Approval Number"
};

const TagNames STUDY_TAG_NAMES = {
const Tags STUDY_TAGS = {
// General Study Module
{"0020|000d", "Study Instance UID"},
{"0008|0020", "Study Date"},
{"0008|0030", "Study Time"},
{"0008|0090", "Referring Physician's Name"},
{"0008|0096", "Referring Physician Identification Sequence"},
{"0008|009c", "Consulting Physician's Name"},
{"0008|009d", "Consulting Physician Identification Sequence"},
{"0020|0010", "Study ID"},
{"0008|0050", "Accession Number"},
{"0008|0051", "Issuer of Accession Number Sequence"},
{"0008|1030", "Study Description"},
{"0008|1048", "Physician(s) of Record"},
{"0008|1049", "Physician(s) of Record Identification Sequence"},
{"0008|1060", "Name of Physician(s) Reading Study"},
{"0008|1062", "Physician(s) Reading Study Identification Sequence"},
{"0032|1033", "Requesting Service"},
{"0032|1034", "Requesting Service Code Sequence"},
{"0008|1110", "Referenced Study Sequence"},
{"0008|1032", "Procedure Code Sequence"},
{"0040|1012", "Reason For Performed Procedure Code Sequence"},
Tag(0x0020, 0x000d), // "Study Instance UID"
Tag(0x0008, 0x0020), // "Study Date"
Tag(0x0008, 0x0030), // "Study Time"
Tag(0x0008, 0x0090), // "Referring Physician's Name"
Tag(0x0008, 0x0096), // "Referring Physician Identification Sequence"
Tag(0x0008, 0x009c), // "Consulting Physician's Name"
Tag(0x0008, 0x009d), // "Consulting Physician Identification Sequence"
Tag(0x0020, 0x0010), // "Study ID"
Tag(0x0008, 0x0050), // "Accession Number"
Tag(0x0008, 0x0051), // "Issuer of Accession Number Sequence"
Tag(0x0008, 0x1030), // "Study Description"
Tag(0x0008, 0x1048), // "Physician(s) of Record"
Tag(0x0008, 0x1049), // "Physician(s) of Record Identification Sequence"
Tag(0x0008, 0x1060), // "Name of Physician(s) Reading Study"
Tag(0x0008, 0x1062), // "Physician(s) Reading Study Identification Sequence"
Tag(0x0032, 0x1033), // "Requesting Service"
Tag(0x0032, 0x1034), // "Requesting Service Code Sequence"
Tag(0x0008, 0x1110), // "Referenced Study Sequence"
Tag(0x0008, 0x1032), // "Procedure Code Sequence"
Tag(0x0040, 0x1012), // "Reason For Performed Procedure Code Sequence"
// Patient Study Module
{"0008|1080", "Admitting Diagnoses Description"},
{"0008|1084", "Admitting Diagnoses Code Sequence"},
{"0010|1010", "Patient's Age"},
{"0010|1020", "Patient's Size"},
{"0010|1030", "Patient's Weight"},
{"0010|1022", "Patient's Body Mass Index"},
{"0010|1023", "Measured AP Dimension"},
{"0010|1024", "Measured Lateral Dimension"},
{"0010|1021", "Patient's Size Code Sequence"},
{"0010|2000", "Medical Alerts"},
{"0010|2110", "Allergies"},
{"0010|21a0", "Smoking Status"},
{"0010|21c0", "Pregnancy Status"},
{"0010|21d0", "Last Menstrual Date"},
{"0038|0500", "Patient State"},
{"0010|2180", "Occupation"},
{"0010|21b0", "Additional Patient History"},
{"0038|0010", "Admission ID"},
{"0038|0014", "Issuer of Admission ID Sequence"},
{"0032|1066", "Reason for Visit"},
{"0032|1067", "Reason for Visit Code Sequence"},
{"0038|0060", "Service Episode ID"},
{"0038|0064", "Issuer of Service Episode ID Sequence"},
{"0038|0062", "Service Episode Description"},
{"0010|2203", "Patient's Sex Neutered"},
Tag(0x0008, 0x1080), // "Admitting Diagnoses Description"
Tag(0x0008, 0x1084), // "Admitting Diagnoses Code Sequence"
Tag(0x0010, 0x1010), // "Patient's Age"
Tag(0x0010, 0x1020), // "Patient's Size"
Tag(0x0010, 0x1030), // "Patient's Weight"
Tag(0x0010, 0x1022), // "Patient's Body Mass Index"
Tag(0x0010, 0x1023), // "Measured AP Dimension"
Tag(0x0010, 0x1024), // "Measured Lateral Dimension"
Tag(0x0010, 0x1021), // "Patient's Size Code Sequence"
Tag(0x0010, 0x2000), // "Medical Alerts"
Tag(0x0010, 0x2110), // "Allergies"
Tag(0x0010, 0x21a0), // "Smoking Status"
Tag(0x0010, 0x21c0), // "Pregnancy Status"
Tag(0x0010, 0x21d0), // "Last Menstrual Date"
Tag(0x0038, 0x0500), // "Patient State"
Tag(0x0010, 0x2180), // "Occupation"
Tag(0x0010, 0x21b0), // "Additional Patient History"
Tag(0x0038, 0x0010), // "Admission ID"
Tag(0x0038, 0x0014), // "Issuer of Admission ID Sequence"
Tag(0x0032, 0x1066), // "Reason for Visit"
Tag(0x0032, 0x1067), // "Reason for Visit Code Sequence"
Tag(0x0038, 0x0060), // "Service Episode ID"
Tag(0x0038, 0x0064), // "Issuer of Service Episode ID Sequence"
Tag(0x0038, 0x0062), // "Service Episode Description"
Tag(0x0010, 0x2203), // "Patient's Sex Neutered"
// Clinical Trial Study Module
{"0012|0050", "Clinical Trial Time Point ID"},
{"0012|0051", "Clinical Trial Time Point Description"},
{"0012|0052", "Longitudinal Temporal Offset from Event"},
{"0012|0053", "Longitudinal Temporal Event Type"},
{"0012|0083", "Consent for Clinical Trial Use Sequence"},
Tag(0x0012, 0x0050), // "Clinical Trial Time Point ID"
Tag(0x0012, 0x0051), // "Clinical Trial Time Point Description"
Tag(0x0012, 0x0052), // "Longitudinal Temporal Offset from Event"
Tag(0x0012, 0x0053), // "Longitudinal Temporal Event Type"
Tag(0x0012, 0x0083) // "Consent for Clinical Trial Use Sequence"
};

const TagNames SERIES_TAG_NAMES = {
const Tags SERIES_TAGS = {
// General Series Module
{"0008|0060", "Modality"},
{"0020|000e", "Series Instance UID"},
{"0020|0011", "Series Number"},
{"0020|0060", "Laterality"},
{"0008|0021", "Series Date"},
{"0008|0031", "Series Time"},
{"0008|1050", "Performing Physician's Name"},
{"0008|1052", "Performing Physician Identification Sequence"},
{"0018|1030", "Protocol Name"},
{"0008|103e", "Series Description"},
{"0008|103f", "Series Description Code Sequence"},
{"0008|1070", "Operators' Name"},
{"0008|1072", "Operator Identification Sequence"},
{"0008|1111", "Referenced Performed Procedure Step Sequence"},
{"0008|1250", "Related Series Sequence"},
{"0018|0015", "Body Part Examined"},
{"0018|5100", "Patient Position"},
{"0028|0108", "Smallest Pixel Value in Series"},
{"0028|0109", "Largest Pixel Value in Series"},
{"0040|0275", "Request Attributes Sequence"},
{"0010|2210", "Anatomical Orientation Type"},
{"300a|0700", "Treatment Session UID"},
Tag(0x0008, 0x0060), // "Modality"
Tag(0x0020, 0x000e), // "Series Instance UID"
Tag(0x0020, 0x0011), // "Series Number"
Tag(0x0020, 0x0060), // "Laterality"
Tag(0x0008, 0x0021), // "Series Date"
Tag(0x0008, 0x0031), // "Series Time"
Tag(0x0008, 0x1050), // "Performing Physician's Name"
Tag(0x0008, 0x1052), // "Performing Physician Identification Sequence"
Tag(0x0018, 0x1030), // "Protocol Name"
Tag(0x0008, 0x103e), // "Series Description"
Tag(0x0008, 0x103f), // "Series Description Code Sequence"
Tag(0x0008, 0x1070), // "Operators' Name"
Tag(0x0008, 0x1072), // "Operator Identification Sequence"
Tag(0x0008, 0x1111), // "Referenced Performed Procedure Step Sequence"
Tag(0x0008, 0x1250), // "Related Series Sequence"
Tag(0x0018, 0x0015), // "Body Part Examined"
Tag(0x0018, 0x5100), // "Patient Position"
Tag(0x0028, 0x0108), // "Smallest Pixel Value in Series"
Tag(0x0028, 0x0109), // "Largest Pixel Value in Series"
Tag(0x0040, 0x0275), // "Request Attributes Sequence"
Tag(0x0010, 0x2210), // "Anatomical Orientation Type"
Tag(0x300a, 0x0700), // "Treatment Session UID"
// Clinical Trial Series Module
{"0012|0060", "Clinical Trial Coordinating Center Name"},
{"0012|0071", "Clinical Trial Series ID"},
{"0012|0072", "Clinical Trial Series Description"},
Tag(0x0012, 0x0060), // "Clinical Trial Coordinating Center Name"
Tag(0x0012, 0x0071), // "Clinical Trial Series ID"
Tag(0x0012, 0x0072), // "Clinical Trial Series Description"
// General Equipment Module
{"0008|0070", "Manufacturer"},
{"0008|0080", "Institution Name"},
{"0008|0081", "Institution Address"},
{"0008|1010", "Station Name"},
{"0008|1040", "Institutional Department Name"},
{"0008|1041", "Institutional Department Type Code Sequence"},
{"0008|1090", "Manufacturer's Model Name"},
{"0018|100b", "Manufacturer's Device Class UID"},
{"0018|1000", "Device Serial Number"},
{"0018|1020", "Software Versions"},
{"0018|1008", "Gantry ID"},
{"0018|100a", "UDI Sequence"},
{"0018|1002", "Device UID"},
{"0018|1050", "Spatial Resolution"},
{"0018|1200", "Date of Last Calibration"},
{"0018|1201", "Time of Last Calibration"},
{"0028|0120", "Pixel Padding Value"},
Tag(0x0008, 0x0070), // "Manufacturer"
Tag(0x0008, 0x0080), // "Institution Name"
Tag(0x0008, 0x0081), // "Institution Address"
Tag(0x0008, 0x1010), // "Station Name"
Tag(0x0008, 0x1040), // "Institutional Department Name"
Tag(0x0008, 0x1041), // "Institutional Department Type Code Sequence"
Tag(0x0008, 0x1090), // "Manufacturer's Model Name"
Tag(0x0018, 0x100b), // "Manufacturer's Device Class UID"
Tag(0x0018, 0x1000), // "Device Serial Number"
Tag(0x0018, 0x1020), // "Software Versions"
Tag(0x0018, 0x1008), // "Gantry ID"
Tag(0x0018, 0x100a), // "UDI Sequence"
Tag(0x0018, 0x1002), // "Device UID"
Tag(0x0018, 0x1050), // "Spatial Resolution"
Tag(0x0018, 0x1200), // "Date of Last Calibration"
Tag(0x0018, 0x1201), // "Time of Last Calibration"
Tag(0x0028, 0x0120), // "Pixel Padding Value"
// Frame of Reference Module
{"0020|0052", "Frame of Reference UID"},
{"0020|1040", "Position Reference Indicator"},
Tag(0x0020, 0x0052), // "Frame of Reference UID"
Tag(0x0020, 0x1040), // "Position Reference Indicator"
};

TagMap extractAndRename(const TagMap &tags, const TagNames &keeperTags)
{
TagMap extracted;
for (const auto &[key, name] : keeperTags)
{
const auto it = tags.find(key);
if (it != tags.end())
{
extracted[name] = it->second;
}
}
return extracted;
}

TagMap remove(const TagMap &tags, const TagNames &removeTags)
{
TagMap filteredTags = tags;
for (const auto &[key, name] : removeTags)
{
filteredTags.erase(key);
}
return filteredTags;
}

TagMap relabel(const TagMap &tags)
{
TagMap relabelTags;
for (const auto &[key, value] : tags)
{
std::string name = key;
if (itk::GDCMImageIO::GetLabelFromTag(key, name))
{
relabelTags[name] = value;
}
else
{
relabelTags[key] = value;
}
}
return relabelTags;
}

#endif // TAGS_H
Loading

0 comments on commit 0ecd248

Please sign in to comment.