Skip to content
Commits on Source (2)
......@@ -14,7 +14,7 @@ include(CTest)
# Project version
set(DICOM_MAJOR_VERSION 0)
set(DICOM_MINOR_VERSION 8)
set(DICOM_PATCH_VERSION 10)
set(DICOM_PATCH_VERSION 11)
set(DICOM_SHORT_VERSION "${DICOM_MAJOR_VERSION}.${DICOM_MINOR_VERSION}")
set(DICOM_VERSION "${DICOM_SHORT_VERSION}.${DICOM_PATCH_VERSION}")
......
......@@ -335,7 +335,7 @@ bool Arguments::ExpandArgs(int argc, wchar_t *argv[], const char *passthrough)
// Append wildcard result to the directory.
wchar_t *result;
size_t n = 0;
while (data.cFileName[n] != 0 && n < MAX_PATH) {
while (n < MAX_PATH && data.cFileName[n] != 0) {
n++;
}
// Ensure that the true filename matches the wildcards.
......
......@@ -43,6 +43,9 @@ public:
size_t ReadLine(std::string *s);
private:
LineReader(const LineReader&); // = delete;
LineReader& operator=(const LineReader&); // = delete;
vtkDICOMFile *File;
size_t BufferSize;
unsigned char *Buffer;
......@@ -340,12 +343,11 @@ bool dicomcli_readkey_query(
// read the DICOM vr
vtkDICOMVR vr;
size_t vrStart = s;
size_t vrEnd = s;
if (s < n && cp[s] == ':')
{
s++;
vrStart = s;
size_t vrStart = s;
vrEnd = s;
if (n - s >= 2)
{
......@@ -422,7 +424,6 @@ bool dicomcli_readkey_query(
keyHasAssignment = true;
s++;
valueStart = s;
valueEnd = s;
if (s < n && qfile && cp[s] == '\"')
{
char delim = cp[s++];
......@@ -445,10 +446,6 @@ bool dicomcli_readkey_query(
s++;
}
valueEnd = s;
if (s < n)
{
s++;
}
}
else
{
......@@ -526,7 +523,7 @@ bool dicomcli_readkey_query(
}
}
return !tagError;
return true;
}
bool dicomcli_readkey(
......
......@@ -548,19 +548,6 @@ int MAINMACRO(int argc, char *argv[])
vtkSmartPointer<vtkDICOMMetaData>::New();
parser->SetMetaData(data);
{
vtkDICOMDataElementIterator iter = query.Begin();
vtkDICOMDataElementIterator iterEnd = query.End();
for (; iter != iterEnd; ++iter)
{
printElement(data, 0, iter, 0, 0);
}
for (size_t i = 0; i < qtlist.size(); i++)
{
std::cout << qtlist[i] << "\n";
}
}
int m = sorter->GetNumberOfStudies();
for (int j = 0; j < m; j++)
{
......
This diff is collapsed.
......@@ -19,6 +19,13 @@ ImplementationVersionName = 0x00020013, // SH M1 0
SourceApplicationEntityTitle = 0x00020016, // AE M1 0
SendingApplicationEntityTitle = 0x00020017, // AE M1 0
ReceivingApplicationEntityTitle = 0x00020018, // AE M1 0
RTVMetaInformationVersion = 0x00020031, // OB M1 0
RTVCommunicationSOPClassUID = 0x00020032, // UI M1 0
RTVCommunicationSOPInstanceUID = 0x00020033, // UI M1 0
RTVSourceIdentifier = 0x00020035, // OB M1 0
RTVFlowIdentifier = 0x00020036, // OB M1 0
RTVFlowRTPSamplingRate = 0x00020037, // UL M1 0
RTVFlowActualFrameDuration = 0x00020038, // FD M1 0
PrivateInformationCreatorUID = 0x00020100, // UI M1 0
PrivateInformation = 0x00020102, // OB M1 0
FileSetID = 0x00041130, // CS M1 0
......@@ -40,6 +47,7 @@ ReferencedSOPInstanceUIDInFile = 0x00041511, // UI M1 0
ReferencedTransferSyntaxUIDInFile = 0x00041512, // UI M1 0
ReferencedRelatedGeneralSOPClassUIDInFile = 0x0004151A, // UI M1TN 0
NumberOfReferences = 0x00041600, // UL M1 1
CurrentFrameFunctionalGroupsSequence = 0x00060001, // SQ M1 0
LengthToEnd = 0x00080001, // UL M1 1
SpecificCharacterSet = 0x00080005, // CS M1TN 0
LanguageCodeSequence = 0x00080006, // SQ M1 0
......@@ -714,6 +722,7 @@ CassetteID = 0x00181007, // LO M1 0
GantryID = 0x00181008, // LO M1 0
UniqueDeviceIdentifier = 0x00181009, // UT M1 0
UDISequence = 0x0018100A, // SQ M1 0
ManufacturerDeviceClassUID = 0x0018100B, // UI M1TN 0
SecondaryCaptureDeviceID = 0x00181010, // LO M1 0
HardcopyCreationDeviceID = 0x00181011, // LO M1 1
DateOfSecondaryCapture = 0x00181012, // DA M1 0
......@@ -881,6 +890,15 @@ VerticesOfThePolygonalShutter = 0x00181620, // IS M2T2N 0
ShutterPresentationValue = 0x00181622, // US M1 0
ShutterOverlayGroup = 0x00181623, // US M1 0
ShutterPresentationColorCIELabValue = 0x00181624, // US M3 0
OutlineShapeType = 0x00181630, // CS M1 0
OutlineLeftVerticalEdge = 0x00181631, // FD M1 0
OutlineRightVerticalEdge = 0x00181632, // FD M1 0
OutlineUpperHorizontalEdge = 0x00181633, // FD M1 0
OutlineLowerHorizontalEdge = 0x00181634, // FD M1 0
CenterOfCircularOutline = 0x00181635, // FD M2 0
DiameterOfCircularOutline = 0x00181636, // FD M1 0
NumberOfPolygonalVertices = 0x00181637, // UL M1 0
VerticesOfThePolygonalOutline = 0x00181638, // OF M1 0
CollimatorShape = 0x00181700, // CS M1T3 0
CollimatorLeftVerticalEdge = 0x00181702, // IS M1 0
CollimatorRightVerticalEdge = 0x00181704, // IS M1 0
......@@ -2165,6 +2183,18 @@ ReasonForVisit = 0x00321066, // UT M1 0
ReasonForVisitCodeSequence = 0x00321067, // SQ M1 0
RequestedContrastAgent = 0x00321070, // LO M1 0
StudyComments = 0x00324000, // LT M1 1
FlowIdentifierSequence = 0x00340001, // SQ M1 0
FlowIdentifier = 0x00340002, // OB M1 0
FlowTransferSyntaxUID = 0x00340003, // UI M1 0
FlowRTPSamplingRate = 0x00340004, // UL M1 0
SourceIdentifier = 0x00340005, // OB M1 0
FrameOriginTimestamp = 0x00340007, // OB M1 0
IncludesImagingSubject = 0x00340008, // CS M1 0
FrameUsefulnessGroupSequence = 0x00340009, // SQ M1 0
RealTimeBulkDataFlowSequence = 0x0034000A, // SQ M1 0
CameraPositionGroupSequence = 0x0034000B, // SQ M1 0
IncludesInformation = 0x0034000C, // CS M1 0
TimeOfFrameGroupSequence = 0x0034000D, // SQ M1 0
ReferencedPatientAliasSequence = 0x00380004, // SQ M1 0
VisitStatusID = 0x00380008, // CS M1 0
AdmissionID = 0x00380010, // LO M1 0
......@@ -3728,6 +3758,9 @@ RelatedFrameOfReferenceUID = 0x300600C2, // UI M1 1
FrameOfReferenceTransformationType = 0x300600C4, // CS M1 1
FrameOfReferenceTransformationMatrix = 0x300600C6, // DS M16 0
FrameOfReferenceTransformationComment = 0x300600C8, // LO M1 0
PatientLocationCoordinatesSequence = 0x300600C9, // SQ M1 0
PatientLocationCoordinatesCodeSequence = 0x300600CA, // SQ M1 0
PatientSupportPositionSequence = 0x300600CB, // SQ M1 0
MeasuredDoseReferenceSequence = 0x30080010, // SQ M1 0
MeasuredDoseDescription = 0x30080012, // ST M1 0
MeasuredDoseType = 0x30080014, // CS M1 0
......@@ -3877,7 +3910,7 @@ NumberOfFractionPatternDigitsPerDay = 0x300A0079, // IS M1 0
RepeatFractionCycleLength = 0x300A007A, // IS M1 0
FractionPattern = 0x300A007B, // LT M1 0
NumberOfBeams = 0x300A0080, // IS M1 0
BeamDoseSpecificationPoint = 0x300A0082, // DS M3 0
BeamDoseSpecificationPoint = 0x300A0082, // DS M3 1
ReferencedDoseReferenceUID = 0x300A0083, // UI M1 0
BeamDose = 0x300A0084, // DS M1 0
BeamMeterset = 0x300A0086, // DS M1 0
......@@ -4223,6 +4256,144 @@ DeliveredNominalRangeModulationFractions = 0x300A0509, // FL M2 0
DeliveredNominalRangeModulatedRegionDepths = 0x300A0510, // FL M2 0
DeliveredReferenceDoseDefinition = 0x300A0511, // CS M1 0
ReferenceDoseDefinition = 0x300A0512, // CS M1 0
RTControlPointIndex = 0x300A0600, // US M1 0
RadiationGenerationModeIndex = 0x300A0601, // US M1 0
ReferencedDefinedDeviceIndex = 0x300A0602, // US M1 0
RadiationDoseIdentificationIndex = 0x300A0603, // US M1 0
NumberOfRTControlPoints = 0x300A0604, // US M1 0
ReferencedRadiationGenerationModeIndex = 0x300A0605, // US M1 0
TreatmentPositionIndex = 0x300A0606, // US M1 0
ReferencedDeviceIndex = 0x300A0607, // US M1 0
TreatmentPositionGroupLabel = 0x300A0608, // LO M1 0
TreatmentPositionGroupUID = 0x300A0609, // UI M1 0
TreatmentPositionGroupSequence = 0x300A060A, // SQ M1 0
ReferencedTreatmentPositionIndex = 0x300A060B, // US M1 0
ReferencedRadiationDoseIdentificationIndex = 0x300A060C, // US M1 0
RTAccessoryHolderWaterEquivalentThickness = 0x300A060D, // FD M1 0
ReferencedRTAccessoryHolderDeviceIndex = 0x300A060E, // US M1 0
RTAccessoryHolderSlotExistenceFlag = 0x300A060F, // CS M1 0
RTAccessoryHolderSlotSequence = 0x300A0610, // SQ M1 0
RTAccessoryHolderSlotID = 0x300A0611, // LO M1 0
RTAccessoryHolderSlotDistance = 0x300A0612, // FD M1 0
RTAccessorySlotDistance = 0x300A0613, // FD M1 0
RTAccessoryHolderDefinitionSequence = 0x300A0614, // SQ M1 0
RTAccessoryDeviceSlotID = 0x300A0615, // LO M1 0
RTRadiationSequence = 0x300A0616, // SQ M1 0
RadiationDoseSequence = 0x300A0617, // SQ M1 0
RadiationDoseIdentificationSequence = 0x300A0618, // SQ M1 0
RadiationDoseIdentificationLabel = 0x300A0619, // LO M1 0
ReferenceDoseType = 0x300A061A, // CS M1 0
PrimaryDoseValueIndicator = 0x300A061B, // CS M1 0
DoseValuesSequence = 0x300A061C, // SQ M1 0
DoseValuePurpose = 0x300A061D, // CS M1TN 0
ReferenceDosePointCoordinates = 0x300A061E, // FD M3 0
RadiationDoseValuesParametersSequence = 0x300A061F, // SQ M1 0
MetersetToDoseMappingSequence = 0x300A0620, // SQ M1 0
ExpectedInVivoMeasurementValuesSequence = 0x300A0621, // SQ M1 0
ExpectedInVivoMeasurementValueIndex = 0x300A0622, // US M1 0
RadiationDoseInVivoMeasurementLabel = 0x300A0623, // LO M1 0
RadiationDoseCentralAxisDisplacement = 0x300A0624, // FD M2 0
RadiationDoseValue = 0x300A0625, // FD M1 0
RadiationDoseSourceToSkinDistance = 0x300A0626, // FD M1 0
RadiationDoseMeasurementPointCoordinates = 0x300A0627, // FD M3 0
RadiationDoseSourceToExternalContourDistance = 0x300A0628, // FD M1 0
RTToleranceSetSequence = 0x300A0629, // SQ M1 0
RTToleranceSetLabel = 0x300A062A, // LO M1 0
AttributeToleranceValuesSequence = 0x300A062B, // SQ M1 0
ToleranceValue = 0x300A062C, // FD M1 0
PatientSupportPositionToleranceSequence = 0x300A062D, // SQ M1 0
TreatmentTimeLimit = 0x300A062E, // FD M1 0
CArmPhotonElectronControlPointSequence = 0x300A062F, // SQ M1 0
ReferencedRTRadiationSequence = 0x300A0630, // SQ M1 0
ReferencedRTInstanceSequence = 0x300A0631, // SQ M1 0
ReferencedRTPatientSetupSequence = 0x300A0632, // SQ M1 0
SourceToPatientSurfaceDistance = 0x300A0634, // FD M1 0
TreatmentMachineSpecialModeCodeSequence = 0x300A0635, // SQ M1 0
IntendedNumberOfFractions = 0x300A0636, // US M1 0
RTRadiationSetIntent = 0x300A0637, // CS M1 0
RTRadiationPhysicalAndGeometricContentDetailFlag = 0x300A0638, // CS M1 0
RTRecordFlag = 0x300A0639, // CS M1 0
TreatmentDeviceIdentificationSequence = 0x300A063A, // SQ M1 0
ReferencedRTPhysicianIntentSequence = 0x300A063B, // SQ M1 0
CumulativeMeterset = 0x300A063C, // FD M1 0
DeliveryRate = 0x300A063D, // FD M1 0
DeliveryRateUnitSequence = 0x300A063E, // SQ M1 0
TreatmentPositionSequence = 0x300A063F, // SQ M1 0
RadiationSourceAxisDistance = 0x300A0640, // FD M1 0
NumberOfRTBeamLimitingDevices = 0x300A0641, // US M1 0
RTBeamLimitingDeviceProximalDistance = 0x300A0642, // FD M1 0
RTBeamLimitingDeviceDistalDistance = 0x300A0643, // FD M1 0
ParallelRTBeamDelimiterDeviceOrientationLabelCodeSequence = 0x300A0644, // SQ M1 0
BeamModifierOrientationAngle = 0x300A0645, // FD M1 0
FixedRTBeamDelimiterDeviceSequence = 0x300A0646, // SQ M1 0
ParallelRTBeamDelimiterDeviceSequence = 0x300A0647, // SQ M1 0
NumberOfParallelRTBeamDelimiters = 0x300A0648, // US M1 0
ParallelRTBeamDelimiterBoundaries = 0x300A0649, // FD M2TN 0
ParallelRTBeamDelimiterPositions = 0x300A064A, // FD M2TN 0
RTBeamLimitingDeviceOffset = 0x300A064B, // FD M2 0
RTBeamDelimiterGeometrySequence = 0x300A064C, // SQ M1 0
RTBeamLimitingDeviceDefinitionSequence = 0x300A064D, // SQ M1 0
ParallelRTBeamDelimiterOpeningMode = 0x300A064E, // CS M1 0
ParallelRTBeamDelimiterLeafMountingSide = 0x300A064F, // CS M1TN 0
PatientSetupUID = 0x300A0650, // UI M1 0
WedgeDefinitionSequence = 0x300A0651, // SQ M1 0
RadiationBeamWedgeAngle = 0x300A0652, // FD M1 0
RadiationBeamWedgeThinEdgeDistance = 0x300A0653, // FD M1 0
RadiationBeamEffectiveWedgeAngle = 0x300A0654, // FD M1 0
NumberOfWedgePositions = 0x300A0655, // US M1 0
RTBeamLimitingDeviceOpeningSequence = 0x300A0656, // SQ M1 0
NumberOfRTBeamLimitingDeviceOpenings = 0x300A0657, // US M1 0
RadiationDosimeterUnitSequence = 0x300A0658, // SQ M1 0
RTDeviceDistanceReferenceLocationCodeSequence = 0x300A0659, // SQ M1 0
RadiationDeviceConfigurationAndCommissioningKeySequence = 0x300A065A, // SQ M1 0
PatientSupportPositionParameterSequence = 0x300A065B, // SQ M1 0
PatientSupportPositionSpecificationMethod = 0x300A065C, // CS M1 0
PatientSupportPositionDeviceParameterSequence = 0x300A065D, // SQ M1 0
DeviceOrderIndex = 0x300A065E, // US M1 0
PatientSupportPositionParameterOrderIndex = 0x300A065F, // US M1 0
PatientSupportPositionDeviceToleranceSequence = 0x300A0660, // SQ M1 0
PatientSupportPositionToleranceOrderIndex = 0x300A0661, // US M1 0
CompensatorDefinitionSequence = 0x300A0662, // SQ M1 0
CompensatorMapOrientation = 0x300A0663, // CS M1 0
CompensatorProximalThicknessMap = 0x300A0664, // OF M1 0
CompensatorDistalThicknessMap = 0x300A0665, // OF M1 0
CompensatorBasePlaneOffset = 0x300A0666, // FD M1 0
CompensatorShapeFabricationCodeSequence = 0x300A0667, // SQ M1 0
CompensatorShapeSequence = 0x300A0668, // SQ M1 0
RadiationBeamCompensatorMillingToolDiameter = 0x300A0669, // FD M1 0
BlockDefinitionSequence = 0x300A066A, // SQ M1 0
BlockEdgeData = 0x300A066B, // OF M1 0
BlockOrientation = 0x300A066C, // CS M1 0
RadiationBeamBlockThickness = 0x300A066D, // FD M1 0
RadiationBeamBlockSlabThickness = 0x300A066E, // FD M1 0
BlockEdgeDataSequence = 0x300A066F, // SQ M1 0
NumberOfRTAccessoryHolders = 0x300A0670, // US M1 0
GeneralAccessoryDefinitionSequence = 0x300A0671, // SQ M1 0
NumberOfGeneralAccessories = 0x300A0672, // US M1 0
BolusDefinitionSequence = 0x300A0673, // SQ M1 0
NumberOfBoluses = 0x300A0674, // US M1 0
EquipmentFrameOfReferenceUID = 0x300A0675, // UI M1 0
EquipmentFrameOfReferenceDescription = 0x300A0676, // ST M1 0
EquipmentReferencePointCoordinatesSequence = 0x300A0677, // SQ M1 0
EquipmentReferencePointCodeSequence = 0x300A0678, // SQ M1 0
RTBeamLimitingDeviceAngle = 0x300A0679, // FD M1 0
SourceRollAngle = 0x300A067A, // FD M1 0
RadiationGenerationModeSequence = 0x300A067B, // SQ M1 0
RadiationGenerationModeLabel = 0x300A067C, // SH M1 0
RadiationGenerationModeDescription = 0x300A067D, // ST M1 0
RadiationGenerationModeMachineCodeSequence = 0x300A067E, // SQ M1 0
RadiationTypeCodeSequence = 0x300A067F, // SQ M1 0
NominalEnergy = 0x300A0680, // DS M1 0
MinimumNominalEnergy = 0x300A0681, // DS M1 0
MaximumNominalEnergy = 0x300A0682, // DS M1 0
RadiationFluenceModifierCodeSequence = 0x300A0683, // SQ M1 0
EnergyUnitCodeSequence = 0x300A0684, // SQ M1 0
NumberOfRadiationGenerationModes = 0x300A0685, // US M1 0
PatientSupportDevicesSequence = 0x300A0686, // SQ M1 0
NumberOfPatientSupportDevices = 0x300A0687, // US M1 0
RTBeamModifierDefinitionDistance = 0x300A0688, // FD M1 0
BeamAreaLimitSequence = 0x300A0689, // SQ M1 0
ReferencedRTPrescriptionSequence = 0x300A068A, // SQ M1 0
ReferencedRTPlanSequence = 0x300C0002, // SQ M1 0
ReferencedBeamSequence = 0x300C0004, // SQ M1 0
ReferencedBeamNumber = 0x300C0006, // IS M1 0
......
......@@ -99,6 +99,14 @@ struct vtkDICOMDirectory::FileInfo
vtkDICOMItem ImageRecord;
};
struct vtkDICOMDirectory::FileInfoPair
{
const char *Key;
FileInfo *Info;
FileInfoPair(const char *key, FileInfo *ptr) : Key(key), Info(ptr) {}
};
struct vtkDICOMDirectory::SeriesInfo
{
// -- PATIENT --
......@@ -114,16 +122,110 @@ struct vtkDICOMDirectory::SeriesInfo
vtkDICOMItem SeriesRecord;
vtkDICOMValue SeriesUID;
unsigned int SeriesNumber;
std::vector<FileInfo> Files;
// -- INSTANCES --
std::list<FileInfo> Files;
std::vector<FileInfoPair> FilesByUID;
bool QueryMatched;
};
bool vtkDICOMDirectory::CompareInstanceUIDs(
const FileInfoPair& p, const char *uid)
{
return (vtkDICOMUtilities::CompareUIDs(p.Key, uid) < 0);
}
bool vtkDICOMDirectory::CompareInstance(
const FileInfo &fi1, const FileInfo &fi2)
{
if (fi1.InstanceNumber != fi2.InstanceNumber)
{
return (fi1.InstanceNumber < fi2.InstanceNumber);
}
// fall back to filename comparison
if (fi1.FileName != 0 && fi2.FileName != 0)
{
return (strcmp(fi1.FileName, fi2.FileName) < 0);
}
// null filename sorts before non-null filename
return (fi2.FileName != 0);
}
bool vtkDICOMDirectory::CompareSeriesUIDs(
const SeriesInfo *si, const char *uid)
{
return (vtkDICOMUtilities::CompareUIDs(
si->SeriesUID.GetCharData(), uid) < 0);
}
bool vtkDICOMDirectory::CompareSeriesIds(
const SeriesInfo *si1, const SeriesInfo *si2)
{
// Compare patient, then study, then series
const char *patientID1 = si1->PatientID.GetCharData();
patientID1 = (patientID1 ? patientID1 : "");
const char *patientID2 = si2->PatientID.GetCharData();
patientID2 = (patientID2 ? patientID2 : "");
int c = strcmp(patientID1, patientID2);
if (c == 0)
{
c = vtkDICOMUtilities::CompareUIDs(
si1->StudyUID.GetCharData(),
si2->StudyUID.GetCharData());
if (c == 0)
{
c = vtkDICOMUtilities::CompareUIDs(
si1->SeriesUID.GetCharData(),
si2->SeriesUID.GetCharData());
}
}
return (c < 0);
}
bool vtkDICOMDirectory::CompareSeriesInfo(
const SeriesInfo &si1, const SeriesInfo &si2)
{
// Use PatientName to sort the patients
const char *patientName1 = si1.PatientName.GetCharData();
patientName1 = (patientName1 ? patientName1 : "");
const char *patientName2 = si2.PatientName.GetCharData();
patientName2 = (patientName2 ? patientName2 : "");
int c = strcmp(patientName1, patientName2);
if (c == 0)
{
// Use StudyDate and StudyTime to sort the studies
const char *studyDate1 = si1.StudyDate.GetCharData();
const char *studyDate2 = si2.StudyDate.GetCharData();
if (studyDate1 && studyDate2)
{
c = strcmp(studyDate1, studyDate2);
if (c == 0)
{
const char *studyTime1 = si1.StudyTime.GetCharData();
const char *studyTime2 = si2.StudyTime.GetCharData();
if (studyTime1 && studyTime2)
{
c = strcmp(studyTime1, studyTime2);
}
}
}
if (c == 0)
{
// Use SeriesNumber to sort the series
c = si1.SeriesNumber - si2.SeriesNumber;
}
}
return (c < 0);
}
//----------------------------------------------------------------------------
// These are the attributes used for a directory scan
......@@ -205,6 +307,10 @@ class vtkDICOMDirectory::SeriesInfoList
: public std::list<vtkDICOMDirectory::SeriesInfo>
{};
class vtkDICOMDirectory::SeriesInfoVector
: public std::vector<vtkDICOMDirectory::SeriesInfo *>
{};
//----------------------------------------------------------------------------
// A helper class for building a sorted list of unique tags
class SortedTags : public std::vector<vtkDICOMTag>
......@@ -1206,9 +1312,9 @@ void vtkDICOMDirectory::SortFiles(vtkStringArray *input)
// will be stored at patient, study, or series level instead
SortedTags skip;
// List of files
SeriesInfoList sortedFiles;
SeriesInfoList::iterator li;
// List of all series that have been found
SeriesInfoList seriesList; // in order of discovery
SeriesInfoVector seriesByUID; // sorted by UID
vtkIdType numberOfStrings = input->GetNumberOfValues();
......@@ -1293,174 +1399,217 @@ void vtkDICOMDirectory::SortFiles(vtkStringArray *input)
continue;
}
// Insert the file into the sorted list
// Create a FileInfo record and find the series it belongs to
FileInfo fileInfo;
fileInfo.InstanceNumber = meta->Get(DC::InstanceNumber).AsUnsignedInt();
fileInfo.FileName = fileName.c_str(); // stored in input StringArray
fileInfo.ImageUID = meta->Get(DC::SOPInstanceUID);
const vtkDICOMValue& patientNameValue = meta->Get(DC::PatientName);
const vtkDICOMValue& patientIDValue = meta->Get(DC::PatientID);
const vtkDICOMValue& studyDateValue = meta->Get(DC::StudyDate);
const vtkDICOMValue& studyTimeValue = meta->Get(DC::StudyTime);
const vtkDICOMValue& studyUIDValue = meta->Get(DC::StudyInstanceUID);
const vtkDICOMValue& seriesUIDValue = meta->Get(DC::SeriesInstanceUID);
unsigned int seriesNumber = meta->Get(DC::SeriesNumber).AsUnsignedInt();
const char *patientName = patientNameValue.GetCharData();
const char *patientID = patientIDValue.GetCharData();
const char *studyDate = studyDateValue.GetCharData();
const char *studyTime = studyTimeValue.GetCharData();
const char *studyUID = studyUIDValue.GetCharData();
const char *seriesUID = seriesUIDValue.GetCharData();
const char *imageUID = fileInfo.ImageUID.GetCharData();
patientName = (patientName ? patientName : "");
patientID = (patientID ? patientID : "");
bool sameFile = false;
bool foundSeries = false;
for (li = sortedFiles.begin(); li != sortedFiles.end(); ++li)
// Locate the first potential match
SeriesInfoVector::iterator vib =
std::lower_bound(seriesByUID.begin(), seriesByUID.end(), seriesUID,
CompareSeriesUIDs);
// Iterate through all possible matches
for (SeriesInfoVector::iterator vi = vib;
vi != seriesByUID.end() &&
vtkDICOMUtilities::CompareUIDs((*vi)->SeriesUID.GetCharData(),
seriesUID) == 0;
++vi)
{
// Compare patient, then study, then series.
const char *patientName2 = li->PatientName.GetCharData();
patientName2 = (patientName2 ? patientName2 : "");
const char *patientID2 = li->PatientID.GetCharData();
patientID2 = (patientID2 ? patientID2 : "");
int c = strcmp(patientID2, patientID);
if (c != 0 || patientID[0] == '\0')
SeriesInfo &v = *(*vi);
// For files that lack the mandatory SeriesInstanceUID,
// we also check whether SeriesNumber is the same
if ((seriesUID == 0 || seriesUID[0] == '\0') &&
seriesNumber != v.SeriesNumber)
{
// Use ID to identify patient, but use name to sort.
int c2 = strcmp(patientName2, patientName);
c = (c2 == 0 ? c : c2);
continue;
}
if (c == 0)
// Ensure that the StudyInstanceUID also matches
if (vtkDICOMUtilities::CompareUIDs(v.StudyUID.GetCharData(),
studyUID) != 0)
{
c = vtkDICOMUtilities::CompareUIDs(
studyUID, li->StudyUID.GetCharData());
if (c != 0 || studyUID == 0)
continue;
}
// Prepare to insert this file into the series
std::vector<FileInfoPair>::iterator im =
std::lower_bound(v.FilesByUID.begin(), v.FilesByUID.end(),
imageUID, CompareInstanceUIDs);
if (im != v.FilesByUID.end())
{
// Use UID to identify study, but use date to sort.
int c2 = 0;
const char *studyDate2 = li->StudyDate.GetCharData();
if (studyDate && studyDate2)
// Check if this SOPInstanceUID is a duplicate
if (vtkDICOMUtilities::CompareUIDs(imageUID, im->Key) == 0)
{
c2 = strcmp(studyDate2, studyDate);
if (c2 == 0)
// Duplicate UID! Check to see if it is the same file
// (SameFile() is expensive, so check InstanceNumber first)
FileInfo &f = *im->Info;
if (f.InstanceNumber == fileInfo.InstanceNumber &&
vtkDICOMFile::SameFile(f.FileName, fileInfo.FileName))
{
const char *studyTime2 = li->StudyTime.GetCharData();
if (studyTime2 && studyTime)
// Let's ignore this file
sameFile = true;
break;
}
if (imageUID == 0 || imageUID[0] == '\0')
{
c2 = strcmp(studyTime, studyTime2);
// If SOPInstanceUID is missing, advance iterator to end
// (this is necessary to keep the sort stable)
do { ++im; } while (im != v.FilesByUID.end() &&
vtkDICOMUtilities::CompareUIDs(
im->Key, imageUID) == 0);
}
else
{
// For duplicate UID, continue to the next series
continue;
}
}
c = (c2 == 0 ? c : c2);
}
if (c == 0)
// Insert this image into the series and break
v.Files.push_back(fileInfo);
FileInfo &f = v.Files.back();
v.FilesByUID.insert(im, FileInfoPair(f.ImageUID.GetCharData(), &f));
this->FillImageRecord(&f.ImageRecord, meta, &skip[0], skip.size());
v.QueryMatched |= queryMatched;
foundSeries = true;
break;
}
if (sameFile)
{
c = vtkDICOMUtilities::CompareUIDs(
seriesUID, li->SeriesUID.GetCharData());
if (c != 0 || seriesUID == 0)
// This same file was already encountered, so skip it
continue;
}
if (!foundSeries)
{
// Use UID to identify series, but use series number to sort.
int c2 = li->SeriesNumber - seriesNumber;
c = (c2 == 0 ? c : c2);
// Use this image to begin a new series
seriesList.push_back(SeriesInfo());
SeriesInfo &v = seriesList.back();
seriesByUID.insert(vib, &v);
v.PatientName = meta->Get(DC::PatientName);
v.PatientID = meta->Get(DC::PatientID);
v.StudyDate = meta->Get(DC::StudyDate);
v.StudyTime = meta->Get(DC::StudyTime);
v.StudyUID = studyUIDValue;
v.SeriesUID = seriesUIDValue;
v.SeriesNumber = seriesNumber;
v.Files.push_back(fileInfo);
FileInfo &f = v.Files.back();
v.FilesByUID.push_back(FileInfoPair(f.ImageUID.GetCharData(), &f));
v.QueryMatched = queryMatched;
this->FillPatientRecord(&v.PatientRecord, meta);
this->FillStudyRecord(&v.StudyRecord, meta);
this->FillSeriesRecord(&v.SeriesRecord, meta);
skip.SetFrom(v.PatientRecord, v.StudyRecord, v.SeriesRecord);
this->FillImageRecord(&f.ImageRecord, meta, &skip[0], skip.size());
}
}
// Remove any series that do not match the query
seriesByUID.clear();
SeriesInfoList::iterator li = seriesList.begin();
while (li != seriesList.end())
{
if (!li->QueryMatched)
{
SeriesInfoList::iterator ci = li;
++li;
seriesList.erase(ci);
}
else
{
seriesByUID.push_back(&(*li));
++li;
}
}
if (c == 0 && seriesUID != 0)
{
// Use UID to identify the image, but use instance number to sort.
bool sameFile = false;
bool repeatUID = false;
for (std::vector<FileInfo>::iterator im = li->Files.begin();
im != li->Files.end(); ++im)
SeriesInfo *lastInfo = 0;
// Force consistent PatientName, StudyDate, StudyTime keys for sorting
std::sort(seriesByUID.begin(), seriesByUID.end(), CompareSeriesIds);
for (SeriesInfoVector::iterator vi = seriesByUID.begin();
vi != seriesByUID.end(); ++vi)
{
if (vtkDICOMUtilities::CompareUIDs(
imageUID, im->ImageUID.GetCharData()) == 0)
SeriesInfo &v = *(*vi);
// Is this a new patient or a new study?
if (!lastInfo || v.PatientID != lastInfo->PatientID)
{
// Duplicate UID! Check InstanceNumber.
if (im->InstanceNumber == fileInfo.InstanceNumber)
const char *cp = v.PatientName.GetCharData();
size_t l = v.PatientName.GetVL();
if (!cp)
{
sameFile = vtkDICOMFile::SameFile(
im->FileName, fileInfo.FileName);
repeatUID = true;
break;
// if PatientName key is missing, use PatientID as replacment
cp = v.PatientID.GetCharData();
l = v.PatientID.GetVL();
}
else if (imageUID && imageUID[0] != '\0')
if (cp)
{
repeatUID = true;
// Strip padding space
while (l > 0 && cp[l-1] == ' ') { --l; }
// Make PatientName key lower-case for case-insensitive sorting
vtkDICOMCharacterSet cs = v.PatientName.GetCharacterSet();
v.PatientName = vtkDICOMValue(
vtkDICOMVR::PN, vtkDICOMCharacterSet::ISO_IR_192,
cs.CaseFoldedUTF8(cp, l));
}
lastInfo = &v;
}
}
if (repeatUID)
{
if (sameFile)
else if (v.StudyUID != lastInfo->StudyUID)
{
break;
}
continue;
v.PatientName = lastInfo->PatientName;
lastInfo = &v;
}
std::vector<FileInfo>::iterator pos =
li->Files.insert(
std::upper_bound(li->Files.begin(), li->Files.end(), fileInfo,
CompareInstance), fileInfo);
this->FillImageRecord(&pos->ImageRecord, meta, &skip[0], skip.size());
li->QueryMatched |= queryMatched;
foundSeries = true;
break;
}
else if (c >= 0)
else
{
break;
v.PatientName = lastInfo->PatientName;
v.StudyDate = lastInfo->StudyDate;
v.StudyTime = lastInfo->StudyTime;
}
}
if (!foundSeries)
{
li = sortedFiles.insert(li, SeriesInfo());
li->PatientName = patientNameValue;
li->PatientID = patientIDValue;
li->StudyDate = studyDateValue;
li->StudyUID = studyUIDValue;
li->SeriesUID = seriesUIDValue;
li->SeriesNumber = seriesNumber;
li->Files.push_back(fileInfo);
li->QueryMatched = queryMatched;
this->FillPatientRecord(&li->PatientRecord, meta);
this->FillStudyRecord(&li->StudyRecord, meta);
this->FillSeriesRecord(&li->SeriesRecord, meta);
skip.SetFrom(li->PatientRecord, li->StudyRecord, li->SeriesRecord);
this->FillImageRecord(&li->Files.back().ImageRecord, meta,
&skip[0], skip.size());
}
}
// Sort by PatientName, StudyDate, StudyTime, and SeriesNumber
seriesList.sort(CompareSeriesInfo);
// Visit each series and call AddSeriesFileNames
int patientCount = this->GetNumberOfPatients();
int studyCount = this->GetNumberOfStudies();
vtkDICOMValue lastStudyUID;
vtkDICOMValue lastPatientID;
lastInfo = 0;
for (li = sortedFiles.begin(); li != sortedFiles.end(); ++li)
for (li = seriesList.begin(); li != seriesList.end(); ++li)
{
SeriesInfo &v = *li;
if (!v.QueryMatched) { continue; }
// Is this a new patient or a new study?
if (!lastPatientID.IsValid() || v.PatientID != lastPatientID)
if (!lastInfo || v.PatientID != lastInfo->PatientID)
{
lastPatientID = v.PatientID;
patientCount++;
lastStudyUID = v.StudyUID;
studyCount++;
lastInfo = &v;
}
else if (!lastStudyUID.IsValid() || v.StudyUID != lastStudyUID)
else if (v.StudyUID != lastInfo->StudyUID)
{
lastStudyUID = v.StudyUID;
studyCount++;
lastInfo = &v;
}
vtkSmartPointer<vtkStringArray> sa =
......@@ -1468,10 +1617,13 @@ void vtkDICOMDirectory::SortFiles(vtkStringArray *input)
vtkIdType n = static_cast<vtkIdType>(v.Files.size());
sa->SetNumberOfValues(n);
std::vector<const vtkDICOMItem *> imageRecords(n);
li->Files.sort(CompareInstance);
std::list<FileInfo>::iterator fi = li->Files.begin();
for (vtkIdType i = 0; i < n; i++)
{
sa->SetValue(i, v.Files[i].FileName);
imageRecords[i] = &v.Files[i].ImageRecord;
sa->SetValue(i, fi->FileName);
imageRecords[i] = &fi->ImageRecord;
++fi;
}
this->AddSeriesFileNames(
patientCount-1, studyCount-1, sa,
......@@ -1533,13 +1685,59 @@ private:
bool SimpleSQL::Open(const char *fname)
{
int r = sqlite3_open_v2(fname, &this->DBase, SQLITE_OPEN_READONLY, NULL);
// convert to URI for use with sqlite3_open()
const char uri_reserved[] = " !#$%&'()*+,:;=?@[]";
// first, get absolute path
vtkDICOMFilePath path(fname);
std::string fullpath = path.GetRealPath();
// build the URI using percent encoding
std::string uri = "file://";
for (size_t i = 0; i < fullpath.length(); i++)
{
bool use_percent = false;
char c = fullpath[i];
if (c < ' ' || c > '~')
{
use_percent = true;
}
else for (size_t j = 0; j < sizeof(uri_reserved); j++)
{
if (c == uri_reserved[j])
{
use_percent = true;
break;
}
}
if (use_percent)
{
char enc[4];
sprintf(enc, "%%%2.2x", static_cast<unsigned char>(c));
uri += enc;
}
else
{
uri.push_back(c);
}
}
// we need to use "immutable" or else a read-only open will fail
// if the .sql-wal file is missing (and we definitely want to open
// the file in read-only mode, we never ever wish to modify the file!)
uri += "?mode=ro&immutable=1";
int r = sqlite3_open_v2(uri.c_str(), &this->DBase,
SQLITE_OPEN_READONLY|SQLITE_OPEN_URI, 0);
if (r == SQLITE_OK)
{
char *errmsg;
r = sqlite3_exec(this->DBase, "BEGIN TRANSACTION", NULL, NULL, &errmsg);
this->InTransaction = (r == SQLITE_OK);
}
return (r == SQLITE_OK);
}
......
......@@ -401,8 +401,10 @@ private:
class StudyVector;
class PatientVector;
struct FileInfo;
struct FileInfoPair;
struct SeriesInfo;
class SeriesInfoList;
class SeriesInfoVector;
class VisitedVector;
vtkDICOMItem *Query;
......@@ -421,6 +423,18 @@ private:
//! Compare FileInfo entries by instance number
static bool CompareInstance(const FileInfo &fi1, const FileInfo &fi2);
//! Compare SeriesInfo entries by SeriesUID
static bool CompareSeriesUIDs(const SeriesInfo *si, const char *uid);
//! Compare SeriesInfo entries by PatientID, StudyUID, and SeriesUID
static bool CompareSeriesIds(const SeriesInfo *li1, const SeriesInfo *li2);
//! Compare SeriesInfo entries by PatientName, StudyDate, and SeriesNumber
static bool CompareSeriesInfo(const SeriesInfo &li1, const SeriesInfo &li2);
//! Compare SOPInstanceUID to a FileInfo entry.
static bool CompareInstanceUIDs(const FileInfoPair& p, const char *uid);
};
#endif
......@@ -1051,7 +1051,7 @@ bool vtkDICOMGenerator::CopyAttributes(
const DC::EnumType *tags = blacklist;
while (*tags != DC::ItemDelimitationItem)
{
if (*tags++ == tag.GetKey())
if (static_cast<unsigned int>(*tags++) == tag.GetKey())
{
blacklisted = true;
break;
......
......@@ -384,6 +384,9 @@ public:
// Returns true if all queries have matched so far.
bool GetQueryMatched() { return this->QueryMatched; }
// Check whether the query is finished.
bool GetQueryFinished() { return this->Query == this->QueryEnd; }
// Finish the query (check for unused keys that must match).
bool FinishQuery();
......@@ -910,7 +913,7 @@ bool DecoderBase::QueryMatches(const vtkDICOMValue& v)
//----------------------------------------------------------------------------
bool DecoderBase::FinishQuery()
{
if (this->HasQuery && this->QueryMatched)
if (this->HasQuery)
{
this->AdvanceQueryIterator(vtkDICOMTag(0xffff,0xffff));
}
......@@ -2135,49 +2138,51 @@ bool vtkDICOMParser::ReadMetaData(
// read group-by-group
bool readFailure = false;
bool queryFailure = (hasQuery && !this->QueryMatched);
bool bailOnQueryFailure = (meta && meta->GetNumberOfInstances() == 1);
while (!readFailure && (!queryFailure || !bailOnQueryFailure))
while (!readFailure)
{
vtkDICOMTag tag = decoder->Peek(cp, ep);
// peek ahead to get the next tag
vtkDICOMTag nextTag = decoder->Peek(cp, ep);
// if there is no data left to decode, then break
if (cp == ep) { break; }
// do we want to read or skip this group?
bool found = true;
bool skipGroup = false;
if (!groups.empty())
{
while (giter != groups.end() && *giter < tag.GetGroup())
while (giter != groups.end() && *giter < nextTag.GetGroup())
{
++giter;
}
found = (giter != groups.end() && *giter == tag.GetGroup());
skipGroup = (giter == groups.end() || *giter != nextTag.GetGroup());
}
// create a delimiter to read/skip only this group
vtkDICOMTag delimiter(tag.GetGroup(), 0);
vtkDICOMTag delimiter(nextTag.GetGroup(), 0);
// check for PixelData group 0x7fe0, or obsolete 0x7fxx
// check for PixelData group 0x7fe0, or obsolete 0x7fxx, but do not
// accept private groups like 7fe1
unsigned int l = HxFFFFFFFF;
if ((tag.GetGroup() & 0xff01) == 0x7f00)
if ((nextTag.GetGroup() & 0xff01) == 0x7f00)
{
if (tag.GetElement() == 0x0000)
if (nextTag.GetElement() == 0x0000)
{
// have to read "group length" before pixel data
// this is a "group length" tag, we want to read exactly
// 12 bytes to get to the next element (the pixel data)
l = 12;
}
else
{
// set delimiter to pixel data tag
delimiter = tag;
// this tag is pixel data, so we want to read the data
// element header for this tag and then stop
delimiter = nextTag;
}
}
if (found && meta)
// read or skip this group of data elements
if (meta && !skipGroup)
{
readFailure = !decoder->ReadElements(cp, ep, l, delimiter);
queryFailure = (hasQuery && !decoder->GetQueryMatched());
}
else
{
......@@ -2222,6 +2227,17 @@ bool vtkDICOMParser::ReadMetaData(
}
}
// if all attributes in the query have been scanned, then break now
// to avoid seeking through the pixel data fragments
if (hasQuery && this->PixelDataFound)
{
decoder->AdvanceQueryIterator(lastTag);
if (decoder->GetQueryFinished())
{
break;
}
}
// skip over the PixelData
unsigned int vl = decoder->GetLastVL();
vtkTypeInt64 r = this->GetBytesRemaining(cp, ep);
......
This diff is collapsed.
......@@ -102,9 +102,9 @@ void StringConversion(
}
else
{
int d = 0;
OT d = 0;
sbs >> d;
*v++ = static_cast<OT>(d);
*v++ = d;
}
if (k + 1 < n)
{
......@@ -941,6 +941,18 @@ vtkDICOMValue::vtkDICOMValue(
this->CreateValue(vr, data, count);
}
vtkDICOMValue::vtkDICOMValue(
vtkDICOMVR vr, const long long *data, size_t count)
{
this->CreateValue(vr, data, count);
}
vtkDICOMValue::vtkDICOMValue(
vtkDICOMVR vr, const unsigned long long *data, size_t count)
{
this->CreateValue(vr, data, count);
}
vtkDICOMValue::vtkDICOMValue(
vtkDICOMVR vr, const float *data, size_t count)
{
......@@ -1502,6 +1514,14 @@ void vtkDICOMValue::GetValuesT(VT *v, size_t c, size_t s) const
NumericalConversion(
static_cast<const ValueT<unsigned int> *>(this->V)->Data+s, v, c);
break;
case VTK_LONG_LONG:
NumericalConversion(
static_cast<const ValueT<long long> *>(this->V)->Data+s, v, c);
break;
case VTK_UNSIGNED_LONG_LONG:
NumericalConversion(
static_cast<const ValueT<unsigned long long> *>(this->V)->Data+s, v, c);
break;
case VTK_FLOAT:
NumericalConversion(
static_cast<const ValueT<float> *>(this->V)->Data+s, v, c);
......@@ -1582,6 +1602,18 @@ void vtkDICOMValue::GetValues(unsigned int *v, size_t c, size_t s) const
this->GetValuesT(v, c, s);
}
void vtkDICOMValue::GetValues(long long *v, size_t c, size_t s) const
{
assert((s + c) <= this->V->NumberOfValues);
this->GetValuesT(v, c, s);
}
void vtkDICOMValue::GetValues(unsigned long long *v, size_t c, size_t s) const
{
assert((s + c) <= this->V->NumberOfValues);
this->GetValuesT(v, c, s);
}
void vtkDICOMValue::GetValues(float *v, size_t c, size_t s) const
{
assert((s + c) <= this->V->NumberOfValues);
......@@ -1917,6 +1949,7 @@ std::string vtkDICOMValue::AsString() const
this->V->VR != vtkDICOMVR::OW &&
this->V->VR != vtkDICOMVR::OB &&
this->V->VR != vtkDICOMVR::OL &&
this->V->VR != vtkDICOMVR::OV &&
this->V->VR != vtkDICOMVR::OF &&
this->V->VR != vtkDICOMVR::OD)
{
......@@ -2061,8 +2094,8 @@ void vtkDICOMValue::AppendValueToString(
const char *cp = 0;
const char *dp = 0;
double f = 0.0;
int d = 0;
size_t u = 0;
long long d = 0;
unsigned long long u = 0;
vtkDICOMTag a;
if (this->V == 0)
......@@ -2104,6 +2137,12 @@ void vtkDICOMValue::AppendValueToString(
case VTK_UNSIGNED_INT:
u = static_cast<const ValueT<unsigned int> *>(this->V)->Data[i];
break;
case VTK_LONG_LONG:
d = static_cast<const ValueT<long long> *>(this->V)->Data[i];
break;
case VTK_UNSIGNED_LONG_LONG:
u = static_cast<const ValueT<unsigned long long> *>(this->V)->Data[i];
break;
case VTK_FLOAT:
f = static_cast<const ValueT<float> *>(this->V)->Data[i];
break;
......@@ -2227,11 +2266,13 @@ void vtkDICOMValue::AppendValueToString(
this->V->Type == VTK_SHORT ||
this->V->Type == VTK_UNSIGNED_SHORT ||
this->V->Type == VTK_INT ||
this->V->Type == VTK_UNSIGNED_INT)
this->V->Type == VTK_UNSIGNED_INT ||
this->V->Type == VTK_LONG_LONG ||
this->V->Type == VTK_UNSIGNED_LONG_LONG)
{
// simple code to convert an integer to a string
char text[16];
size_t ti = 16;
char text[20];
size_t ti = 20;
// if d is nonzero, set u to abs(d)
if (d > 0)
......@@ -2255,7 +2296,7 @@ void vtkDICOMValue::AppendValueToString(
text[--ti] = '-';
}
str.append(&text[ti], &text[16]);
str.append(&text[ti], &text[20]);
}
else if (this->V->Type == VTK_DICOM_TAG)
{
......@@ -2892,6 +2933,11 @@ bool vtkDICOMValue::Matches(const vtkDICOMValue& value) const
// OL must match exactly
match = ValueT<unsigned int>::Compare(value.V, this->V);
}
else if (vr == vtkDICOMVR::OV)
{
// OV must match exactly
match = ValueT<unsigned int>::Compare(value.V, this->V);
}
else if (vr == vtkDICOMVR::OF)
{
// OF must match exactly
......@@ -2912,6 +2958,11 @@ bool vtkDICOMValue::Matches(const vtkDICOMValue& value) const
// Match if any value matches
match = ValueT<int>::CompareEach(value.V, this->V);
}
else if (type == VTK_LONG_LONG || type == VTK_UNSIGNED_LONG_LONG)
{
// Match if any value matches
match = ValueT<long long>::CompareEach(value.V, this->V);
}
else if (type == VTK_FLOAT)
{
// Match if any value matches
......@@ -2995,6 +3046,10 @@ bool vtkDICOMValue::operator==(const vtkDICOMValue& o) const
case VTK_UNSIGNED_INT:
r = ValueT<int>::Compare(a, b);
break;
case VTK_LONG_LONG:
case VTK_UNSIGNED_LONG_LONG:
r = ValueT<long long>::Compare(a, b);
break;
case VTK_FLOAT:
r = ValueT<float>::Compare(a, b);
break;
......@@ -3093,6 +3148,10 @@ ostream& operator<<(ostream& os, const vtkDICOMValue& v)
{
os << "longwords[" << m << "]";
}
else if (vr == vtkDICOMVR::OV)
{
os << "verylongwords[" << m << "]";
}
else if (vr == vtkDICOMVR::OF)
{
os << "floats[" << m << "]";
......
......@@ -100,6 +100,8 @@ public:
vtkDICOMValue(vtkDICOMVR vr, const unsigned short *data, size_t count);
vtkDICOMValue(vtkDICOMVR vr, const int *data, size_t count);
vtkDICOMValue(vtkDICOMVR vr, const unsigned int *data, size_t count);
vtkDICOMValue(vtkDICOMVR vr, const long long *data, size_t count);
vtkDICOMValue(vtkDICOMVR vr, const unsigned long long *data, size_t count);
vtkDICOMValue(vtkDICOMVR vr, const float *data, size_t count);
vtkDICOMValue(vtkDICOMVR vr, const double *data, size_t count);
vtkDICOMValue(vtkDICOMVR vr, const vtkDICOMTag *data, size_t count);
......@@ -224,6 +226,8 @@ public:
void GetValues(unsigned short *vb, size_t n, size_t i=0) const;
void GetValues(int *vb, size_t n, size_t i=0) const;
void GetValues(unsigned int *vb, size_t n, size_t i=0) const;
void GetValues(long long *vb, size_t n, size_t i=0) const;
void GetValues(unsigned long long *vb, size_t n, size_t i=0) const;
void GetValues(float *vb, size_t n, size_t i=0) const;
void GetValues(double *vb, size_t n, size_t i=0) const;
void GetValues(vtkDICOMTag *vb, size_t n, size_t i=0) const;
......
......@@ -574,7 +574,6 @@ int main(int argc, char *argv[])
TestAssert(!v.Matches(u));
// test comparison with character sets
std::string s;
v = vtkDICOMValue(
vtkDICOMVR::LO, vtkDICOMCharacterSet("ISO 2022 IR 13\\ISO 2022 IR 87"),
"\xd4\xcf\xc0\xde^\xc0\xdb\xb3\\\x1b$B;3ED\x1b(J^\x1b$BB@O:\x1b(J");
......
......@@ -58,6 +58,48 @@ ReceivingApplicationEntityTitle
AE
1
(0002,0031)
RTV Meta Information Version
RTVMetaInformationVersion
OB
1
(0002,0032)
RTV Communication SOP Class UID
RTVCommunicationSOPClassUID
UI
1
(0002,0033)
RTV Communication SOP Instance UID
RTVCommunicationSOPInstanceUID
UI
1
(0002,0035)
RTV Source Identifier
RTVSourceIdentifier
OB
1
(0002,0036)
RTV Flow Identifier
RTVFlowIdentifier
OB
1
(0002,0037)
RTV Flow RTP Sampling Rate
RTVFlowRTPSamplingRate
UL
1
(0002,0038)
RTV Flow Actual Frame Duration
RTVFlowActualFrameDuration
FD
1
(0002,0100)
Private Information Creator UID
PrivateInformationCreatorUID
......@@ -184,6 +226,12 @@ NumberOfReferences
UL
1
RET
(0006,0001)
Current Frame Functional Groups Sequence
CurrentFrameFunctionalGroupsSequence
SQ
1
(0008,0001)
Length to End
LengthToEnd
......@@ -4234,6 +4282,12 @@ UDISequence
SQ
1
(0018,100B)
Manufacturer's Device Class UID
ManufacturerDeviceClassUID
UI
1-n
(0018,1010)
Secondary Capture Device ID
SecondaryCaptureDeviceID
......@@ -5236,6 +5290,60 @@ ShutterPresentationColorCIELabValue
US
3
(0018,1630)
Outline Shape Type
OutlineShapeType
CS
1
(0018,1631)
Outline Left Vertical Edge
OutlineLeftVerticalEdge
FD
1
(0018,1632)
Outline Right Vertical Edge
OutlineRightVerticalEdge
FD
1
(0018,1633)
Outline Upper Horizontal Edge
OutlineUpperHorizontalEdge
FD
1
(0018,1634)
Outline Lower Horizontal Edge
OutlineLowerHorizontalEdge
FD
1
(0018,1635)
Center of Circular Outline
CenterOfCircularOutline
FD
2
(0018,1636)
Diameter of Circular Outline
DiameterOfCircularOutline
FD
1
(0018,1637)
Number of Polygonal Vertices
NumberOfPolygonalVertices
UL
1
(0018,1638)
Vertices of the Polygonal Outline
VerticesOfThePolygonalOutline
OF
1
(0018,1700)
Collimator Shape
CollimatorShape
......@@ -12952,6 +13060,78 @@ StudyComments
LT
1
RET
(0034,0001)
Flow Identifier Sequence
FlowIdentifierSequence
SQ
1
(0034,0002)
Flow Identifier
FlowIdentifier
OB
1
(0034,0003)
Flow Transfer Syntax UID
FlowTransferSyntaxUID
UI
1
(0034,0004)
Flow RTP Sampling Rate
FlowRTPSamplingRate
UL
1
(0034,0005)
Source Identifier
SourceIdentifier
OB
1
(0034,0007)
Frame Origin Timestamp
FrameOriginTimestamp
OB
1
(0034,0008)
Includes Imaging Subject
IncludesImagingSubject
CS
1
(0034,0009)
Frame Usefulness Group Sequence
FrameUsefulnessGroupSequence
SQ
1
(0034,000A)
Real-Time Bulk Data Flow Sequence
RealTimeBulkDataFlowSequence
SQ
1
(0034,000B)
Camera Position Group Sequence
CameraPositionGroupSequence
SQ
1
(0034,000C)
Includes Information
IncludesInformation
CS
1
(0034,000D)
Time of Frame Group Sequence
TimeOfFrameGroupSequence
SQ
1
(0038,0004)
Referenced Patient Alias Sequence
ReferencedPatientAliasSequence
......@@ -22336,6 +22516,24 @@ FrameOfReferenceTransformationComment
LO
1
(3006,00C9)
Patient Location Coordinates Sequence
PatientLocationCoordinatesSequence
SQ
1
(3006,00CA)
Patient Location Coordinates Code Sequence
PatientLocationCoordinatesCodeSequence
SQ
1
(3006,00CB)
Patient Support Position Sequence
PatientSupportPositionSequence
SQ
1
(3008,0010)
Measured Dose Reference Sequence
MeasuredDoseReferenceSequence
......@@ -23235,7 +23433,7 @@ Beam Dose Specification Point
BeamDoseSpecificationPoint
DS
3
RET
(300A,0083)
Referenced Dose Reference UID
ReferencedDoseReferenceUID
......@@ -25306,6 +25504,834 @@ ReferenceDoseDefinition
CS
1
(300A,0600)
RT Control Point Index
RTControlPointIndex
US
1
(300A,0601)
Radiation Generation Mode Index
RadiationGenerationModeIndex
US
1
(300A,0602)
Referenced Defined Device Index
ReferencedDefinedDeviceIndex
US
1
(300A,0603)
Radiation Dose Identification Index
RadiationDoseIdentificationIndex
US
1
(300A,0604)
Number of RT Control Points
NumberOfRTControlPoints
US
1
(300A,0605)
Referenced Radiation Generation Mode Index
ReferencedRadiationGenerationModeIndex
US
1
(300A,0606)
Treatment Position Index
TreatmentPositionIndex
US
1
(300A,0607)
Referenced Device Index
ReferencedDeviceIndex
US
1
(300A,0608)
Treatment Position Group Label
TreatmentPositionGroupLabel
LO
1
(300A,0609)
Treatment Position Group UID
TreatmentPositionGroupUID
UI
1
(300A,060A)
Treatment Position Group Sequence
TreatmentPositionGroupSequence
SQ
1
(300A,060B)
Referenced Treatment Position Index
ReferencedTreatmentPositionIndex
US
1
(300A,060C)
Referenced Radiation Dose Identification Index
ReferencedRadiationDoseIdentificationIndex
US
1
(300A,060D)
RT Accessory Holder Water-Equivalent Thickness
RTAccessoryHolderWaterEquivalentThickness
FD
1
(300A,060E)
Referenced RT Accessory Holder Device Index
ReferencedRTAccessoryHolderDeviceIndex
US
1
(300A,060F)
RT Accessory Holder Slot Existence Flag
RTAccessoryHolderSlotExistenceFlag
CS
1
(300A,0610)
RT Accessory Holder Slot Sequence
RTAccessoryHolderSlotSequence
SQ
1
(300A,0611)
RT Accessory Holder Slot ID
RTAccessoryHolderSlotID
LO
1
(300A,0612)
RT Accessory Holder Slot Distance
RTAccessoryHolderSlotDistance
FD
1
(300A,0613)
RT Accessory Slot Distance
RTAccessorySlotDistance
FD
1
(300A,0614)
RT Accessory Holder Definition Sequence
RTAccessoryHolderDefinitionSequence
SQ
1
(300A,0615)
RT Accessory Device Slot ID
RTAccessoryDeviceSlotID
LO
1
(300A,0616)
RT Radiation Sequence
RTRadiationSequence
SQ
1
(300A,0617)
Radiation Dose Sequence
RadiationDoseSequence
SQ
1
(300A,0618)
Radiation Dose Identification Sequence
RadiationDoseIdentificationSequence
SQ
1
(300A,0619)
Radiation Dose Identification Label
RadiationDoseIdentificationLabel
LO
1
(300A,061A)
Reference Dose Type
ReferenceDoseType
CS
1
(300A,061B)
Primary Dose Value Indicator
PrimaryDoseValueIndicator
CS
1
(300A,061C)
Dose Values Sequence
DoseValuesSequence
SQ
1
(300A,061D)
Dose Value Purpose
DoseValuePurpose
CS
1-n
(300A,061E)
Reference Dose Point Coordinates
ReferenceDosePointCoordinates
FD
3
(300A,061F)
Radiation Dose Values Parameters Sequence
RadiationDoseValuesParametersSequence
SQ
1
(300A,0620)
Meterset to Dose Mapping Sequence
MetersetToDoseMappingSequence
SQ
1
(300A,0621)
Expected In-Vivo Measurement Values Sequence
ExpectedInVivoMeasurementValuesSequence
SQ
1
(300A,0622)
Expected In-Vivo Measurement Value Index
ExpectedInVivoMeasurementValueIndex
US
1
(300A,0623)
Radiation Dose In-Vivo Measurement Label
RadiationDoseInVivoMeasurementLabel
LO
1
(300A,0624)
Radiation Dose Central Axis Displacement
RadiationDoseCentralAxisDisplacement
FD
2
(300A,0625)
Radiation Dose Value
RadiationDoseValue
FD
1
(300A,0626)
Radiation Dose Source to Skin Distance
RadiationDoseSourceToSkinDistance
FD
1
(300A,0627)
Radiation Dose Measurement Point Coordinates
RadiationDoseMeasurementPointCoordinates
FD
3
(300A,0628)
Radiation Dose Source to External Contour Distance
RadiationDoseSourceToExternalContourDistance
FD
1
(300A,0629)
RT Tolerance Set Sequence
RTToleranceSetSequence
SQ
1
(300A,062A)
RT Tolerance Set Label
RTToleranceSetLabel
LO
1
(300A,062B)
Attribute Tolerance Values Sequence
AttributeToleranceValuesSequence
SQ
1
(300A,062C)
Tolerance Value
ToleranceValue
FD
1
(300A,062D)
Patient Support Position Tolerance Sequence
PatientSupportPositionToleranceSequence
SQ
1
(300A,062E)
Treatment Time Limit
TreatmentTimeLimit
FD
1
(300A,062F)
C-Arm Photon-Electron Control Point Sequence
CArmPhotonElectronControlPointSequence
SQ
1
(300A,0630)
Referenced RT Radiation Sequence
ReferencedRTRadiationSequence
SQ
1
(300A,0631)
Referenced RT Instance Sequence
ReferencedRTInstanceSequence
SQ
1
(300A,0632)
Referenced RT Patient Setup Sequence
ReferencedRTPatientSetupSequence
SQ
1
(300A,0634)
Source to Patient Surface Distance
SourceToPatientSurfaceDistance
FD
1
(300A,0635)
Treatment Machine Special Mode Code Sequence
TreatmentMachineSpecialModeCodeSequence
SQ
1
(300A,0636)
Intended Number of Fractions
IntendedNumberOfFractions
US
1
(300A,0637)
RT Radiation Set Intent
RTRadiationSetIntent
CS
1
(300A,0638)
RT Radiation Physical and Geometric Content Detail Flag
RTRadiationPhysicalAndGeometricContentDetailFlag
CS
1
(300A,0639)
RT Record Flag
RTRecordFlag
CS
1
(300A,063A)
Treatment Device Identification Sequence
TreatmentDeviceIdentificationSequence
SQ
1
(300A,063B)
Referenced RT Physician Intent Sequence
ReferencedRTPhysicianIntentSequence
SQ
1
(300A,063C)
Cumulative Meterset
CumulativeMeterset
FD
1
(300A,063D)
Delivery Rate
DeliveryRate
FD
1
(300A,063E)
Delivery Rate Unit Sequence
DeliveryRateUnitSequence
SQ
1
(300A,063F)
Treatment Position Sequence
TreatmentPositionSequence
SQ
1
(300A,0640)
Radiation Source-Axis Distance
RadiationSourceAxisDistance
FD
1
(300A,0641)
Number of RT Beam Limiting Devices
NumberOfRTBeamLimitingDevices
US
1
(300A,0642)
RT Beam Limiting Device Proximal Distance
RTBeamLimitingDeviceProximalDistance
FD
1
(300A,0643)
RT Beam Limiting Device Distal Distance
RTBeamLimitingDeviceDistalDistance
FD
1
(300A,0644)
Parallel RT Beam Delimiter Device Orientation Label Code Sequence
ParallelRTBeamDelimiterDeviceOrientationLabelCodeSequence
SQ
1
(300A,0645)
Beam Modifier Orientation Angle
BeamModifierOrientationAngle
FD
1
(300A,0646)
Fixed RT Beam Delimiter Device Sequence
FixedRTBeamDelimiterDeviceSequence
SQ
1
(300A,0647)
Parallel RT Beam Delimiter Device Sequence
ParallelRTBeamDelimiterDeviceSequence
SQ
1
(300A,0648)
Number of Parallel RT Beam Delimiters
NumberOfParallelRTBeamDelimiters
US
1
(300A,0649)
Parallel RT Beam Delimiter Boundaries
ParallelRTBeamDelimiterBoundaries
FD
2-n
(300A,064A)
Parallel RT Beam Delimiter Positions
ParallelRTBeamDelimiterPositions
FD
2-n
(300A,064B)
RT Beam Limiting Device Offset
RTBeamLimitingDeviceOffset
FD
2
(300A,064C)
RT Beam Delimiter Geometry Sequence
RTBeamDelimiterGeometrySequence
SQ
1
(300A,064D)
RT Beam Limiting Device Definition Sequence
RTBeamLimitingDeviceDefinitionSequence
SQ
1
(300A,064E)
Parallel RT Beam Delimiter Opening Mode
ParallelRTBeamDelimiterOpeningMode
CS
1
(300A,064F)
Parallel RT Beam Delimiter Leaf Mounting Side
ParallelRTBeamDelimiterLeafMountingSide
CS
1-n
(300A,0650)
Patient Setup UID
PatientSetupUID
UI
1
(300A,0651)
Wedge Definition Sequence
WedgeDefinitionSequence
SQ
1
(300A,0652)
Radiation Beam Wedge Angle
RadiationBeamWedgeAngle
FD
1
(300A,0653)
Radiation Beam Wedge Thin Edge Distance
RadiationBeamWedgeThinEdgeDistance
FD
1
(300A,0654)
Radiation Beam Effective Wedge Angle
RadiationBeamEffectiveWedgeAngle
FD
1
(300A,0655)
Number of Wedge Positions
NumberOfWedgePositions
US
1
(300A,0656)
RT Beam Limiting Device Opening Sequence
RTBeamLimitingDeviceOpeningSequence
SQ
1
(300A,0657)
Number of RT Beam Limiting Device Openings
NumberOfRTBeamLimitingDeviceOpenings
US
1
(300A,0658)
Radiation Dosimeter Unit Sequence
RadiationDosimeterUnitSequence
SQ
1
(300A,0659)
RT Device Distance Reference Location Code Sequence
RTDeviceDistanceReferenceLocationCodeSequence
SQ
1
(300A,065A)
Radiation Device Configuration and Commissioning Key Sequence
RadiationDeviceConfigurationAndCommissioningKeySequence
SQ
1
(300A,065B)
Patient Support Position Parameter Sequence
PatientSupportPositionParameterSequence
SQ
1
(300A,065C)
Patient Support Position Specification Method
PatientSupportPositionSpecificationMethod
CS
1
(300A,065D)
Patient Support Position Device Parameter Sequence
PatientSupportPositionDeviceParameterSequence
SQ
1
(300A,065E)
Device Order Index
DeviceOrderIndex
US
1
(300A,065F)
Patient Support Position Parameter Order Index
PatientSupportPositionParameterOrderIndex
US
1
(300A,0660)
Patient Support Position Device Tolerance Sequence
PatientSupportPositionDeviceToleranceSequence
SQ
1
(300A,0661)
Patient Support Position Tolerance Order Index
PatientSupportPositionToleranceOrderIndex
US
1
(300A,0662)
Compensator Definition Sequence
CompensatorDefinitionSequence
SQ
1
(300A,0663)
Compensator Map Orientation
CompensatorMapOrientation
CS
1
(300A,0664)
Compensator Proximal Thickness Map
CompensatorProximalThicknessMap
OF
1
(300A,0665)
Compensator Distal Thickness Map
CompensatorDistalThicknessMap
OF
1
(300A,0666)
Compensator Base Plane Offset
CompensatorBasePlaneOffset
FD
1
(300A,0667)
Compensator Shape Fabrication Code Sequence
CompensatorShapeFabricationCodeSequence
SQ
1
(300A,0668)
Compensator Shape Sequence
CompensatorShapeSequence
SQ
1
(300A,0669)
Radiation Beam Compensator Milling Tool Diameter
RadiationBeamCompensatorMillingToolDiameter
FD
1
(300A,066A)
Block Definition Sequence
BlockDefinitionSequence
SQ
1
(300A,066B)
Block Edge Data
BlockEdgeData
OF
1
(300A,066C)
Block Orientation
BlockOrientation
CS
1
(300A,066D)
Radiation Beam Block Thickness
RadiationBeamBlockThickness
FD
1
(300A,066E)
Radiation Beam Block Slab Thickness
RadiationBeamBlockSlabThickness
FD
1
(300A,066F)
Block Edge Data Sequence
BlockEdgeDataSequence
SQ
1
(300A,0670)
Number of RT Accessory Holders
NumberOfRTAccessoryHolders
US
1
(300A,0671)
General Accessory Definition Sequence
GeneralAccessoryDefinitionSequence
SQ
1
(300A,0672)
Number of General Accessories
NumberOfGeneralAccessories
US
1
(300A,0673)
Bolus Definition Sequence
BolusDefinitionSequence
SQ
1
(300A,0674)
Number of Boluses
NumberOfBoluses
US
1
(300A,0675)
Equipment Frame of Reference UID
EquipmentFrameOfReferenceUID
UI
1
(300A,0676)
Equipment Frame of Reference Description
EquipmentFrameOfReferenceDescription
ST
1
(300A,0677)
Equipment Reference Point Coordinates Sequence
EquipmentReferencePointCoordinatesSequence
SQ
1
(300A,0678)
Equipment Reference Point Code Sequence
EquipmentReferencePointCodeSequence
SQ
1
(300A,0679)
RT Beam Limiting Device Angle
RTBeamLimitingDeviceAngle
FD
1
(300A,067A)
Source Roll Angle
SourceRollAngle
FD
1
(300A,067B)
Radiation GenerationMode Sequence
RadiationGenerationModeSequence
SQ
1
(300A,067C)
Radiation GenerationMode Label
RadiationGenerationModeLabel
SH
1
(300A,067D)
Radiation GenerationMode Description
RadiationGenerationModeDescription
ST
1
(300A,067E)
Radiation GenerationMode Machine Code Sequence
RadiationGenerationModeMachineCodeSequence
SQ
1
(300A,067F)
Radiation Type Code Sequence
RadiationTypeCodeSequence
SQ
1
(300A,0680)
Nominal Energy
NominalEnergy
DS
1
(300A,0681)
Minimum Nominal Energy
MinimumNominalEnergy
DS
1
(300A,0682)
Maximum Nominal Energy
MaximumNominalEnergy
DS
1
(300A,0683)
Radiation Fluence Modifier Code Sequence
RadiationFluenceModifierCodeSequence
SQ
1
(300A,0684)
Energy Unit Code Sequence
EnergyUnitCodeSequence
SQ
1
(300A,0685)
Number of Radiation GenerationModes
NumberOfRadiationGenerationModes
US
1
(300A,0686)
Patient Support Devices Sequence
PatientSupportDevicesSequence
SQ
1
(300A,0687)
Number of Patient Support Devices
NumberOfPatientSupportDevices
US
1
(300A,0688)
RT Beam Modifier Definition Distance
RTBeamModifierDefinitionDistance
FD
1
(300A,0689)
Beam Area Limit Sequence
BeamAreaLimitSequence
SQ
1
(300A,068A)
Referenced RT Prescription Sequence
ReferencedRTPrescriptionSequence
SQ
1
(300C,0002)
Referenced RT Plan Sequence
ReferencedRTPlanSequence
......
......@@ -171,6 +171,18 @@ PS3.10
XML Encoding (Retired)
Transfer Syntax
PS3.10
1.2.840.10008.1.2.7.1
SMPTE ST 2110-20 Uncompressed Progressive Active Video
Transfer Syntax
PS3.5
1.2.840.10008.1.2.7.2
SMPTE ST 2110-20 Uncompressed Interlaced Active Video
Transfer Syntax
PS3.5
1.2.840.10008.1.2.7.3
SMPTE ST 2110-30 PCM Digital Audio
Transfer Syntax
PS3.5
1.2.840.10008.1.3.10
Media Storage Directory Storage
SOP Class
......@@ -1166,6 +1178,14 @@ PS3.4
RT Segment Annotation Storage
SOP Class
PS3.4
1.2.840.10008.5.1.4.1.1.481.12
RT Radiation Set Storage
SOP Class
PS3.4
1.2.840.10008.5.1.4.1.1.481.13
C-Arm Photon-Electron Radiation Storage
SOP Class
PS3.4
1.2.840.10008.5.1.4.1.1.501.1
DICOS CT Image Storage
SOP Class
......@@ -1474,6 +1494,22 @@ PS3.19
DICOM Content Mapping Resource
Mapping Resource
PS3.16
1.2.840.10008.10.1
Video Endoscopic Image Real-Time Communication
SOP Class
PS3.22
1.2.840.10008.10.2
Video Photographic Image Real-Time Communication
SOP Class
PS3.22
1.2.840.10008.10.3
Audio Waveform Real-Time Communication
SOP Class
PS3.22
1.2.840.10008.10.4
Rendition Selection Document Real-Time Communication
SOP Class
PS3.22
1.2.840.10008.9.1
Imaging Report
Document TemplateID
......@@ -1791,6 +1827,9 @@ ICBM452 T1 Atlas
1.2.840.10008.1.4.2.2
ICBM Single Subject MRI Frame of Reference
ICBM Single Subject MRI Anatomical Template
1.2.840.10008.1.4.3.1
IEC 61217 Fixed Coordinate System Frame of Reference
Fixed coordinate system of Section C.36.12.2.1 “IEC 61217 Fixed Reference System Frame of Reference” in PS3.3
# Context Group UID Values ================================================
1.2.840.10008.6.1.1
CID 2
......@@ -5345,3 +5384,51 @@ Qualitative Evaluation Modifier Values
1.2.840.10008.6.1.1287
CID 212
Generic Anatomic Location Modifiers
1.2.840.10008.6.1.1288
CID 9541
Beam Limiting Device Types
1.2.840.10008.6.1.1289
CID 9542
Compensator Device Types
1.2.840.10008.6.1.1290
CID 9543
Radiotherapy Treatment Machine Modes
1.2.840.10008.6.1.1291
CID 9544
Radiotherapy Distance Reference Locations
1.2.840.10008.6.1.1292
CID 9545
Fixed Beam Limiting Device Types
1.2.840.10008.6.1.1293
CID 9546
Radiotherapy Wedge Types
1.2.840.10008.6.1.1294
CID 9547
RT Beam Limiting Device Orientation Labels
1.2.840.10008.6.1.1295
CID 9548
General Accessory Device Types
1.2.840.10008.6.1.1296
CID 9549
Radiation Generation Mode Types
1.2.840.10008.6.1.1297
CID 9550
C-Arm Photon-Electron Delivery Rate Units
1.2.840.10008.6.1.1298
CID 9551
Treatment Delivery Device Types
1.2.840.10008.6.1.1299
CID 9552
C-Arm Photon-Electron Dosimeter Units
1.2.840.10008.6.1.1300
CID 9553
Treatment Points
1.2.840.10008.6.1.1301
CID 9554
Equipment Reference Points
1.2.840.10008.6.1.1302
CID 9555
Radiotherapy Treatment Planning Person Roles
1.2.840.10008.6.1.1303
CID 7070
Real Time Video Rendition Titles