-
Notifications
You must be signed in to change notification settings - Fork 597
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add basic dicom SR parsing, fixes #1689
- Loading branch information
Showing
9 changed files
with
943 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { | ||
getSopInstanceReference, | ||
getDicomSopInstanceReferenceItem | ||
} from './dicomSopInstanceReference'; | ||
|
||
// doc imports | ||
/* eslint-disable no-unused-vars */ | ||
import {DataElement} from './dataElement'; | ||
/* eslint-enable no-unused-vars */ | ||
|
||
/** | ||
* Related DICOM tag keys. | ||
*/ | ||
const tagKeys = { | ||
ReferencedFrameNumber: '00081160', | ||
ReferencedSOPSequence: '00081199', | ||
ReferencedSegmentNumber: '0062000B' | ||
}; | ||
|
||
/** | ||
* DICOM image reference: item of a SR content sequence. | ||
* | ||
* Ref: {@link https://dicom.nema.org/medical/dicom/2022a/output/chtml/part03/sect_C.18.4.html#table_C.18.4-1}. | ||
*/ | ||
export class ImageReference { | ||
/** | ||
* @type {object} | ||
*/ | ||
referencedSOPSequence; | ||
|
||
/** | ||
* @type {object} | ||
*/ | ||
referencedFrameNumber; | ||
|
||
/** | ||
* @type {string} | ||
*/ | ||
referencedSegmentNumber; | ||
|
||
/** | ||
* @type {string} | ||
*/ | ||
fiducialUID; | ||
|
||
/** | ||
* Get a string representation of this object. | ||
* | ||
* @returns {string} The object as string. | ||
*/ | ||
toString() { | ||
return this.referencedSOPSequence.toString(); | ||
}; | ||
}; | ||
|
||
/** | ||
* Get a reference object from a dicom element. | ||
* | ||
* @param {Object<string, DataElement>} dataElements The dicom element. | ||
* @returns {ImageReference} A reference object. | ||
*/ | ||
export function getImageReference(dataElements) { | ||
const ref = new ImageReference(); | ||
|
||
if (typeof dataElements[tagKeys.ReferencedFrameNumber] !== 'undefined') { | ||
ref.referencedFrameNumber = | ||
dataElements[tagKeys.ReferencedFrameNumber].value[0]; | ||
} | ||
if (typeof dataElements[tagKeys.ReferencedSOPSequence] !== 'undefined') { | ||
ref.referencedSOPSequence = getSopInstanceReference( | ||
dataElements[tagKeys.ReferencedSOPSequence].value[0]); | ||
} | ||
if (typeof dataElements[tagKeys.ReferencedSegmentNumber] !== 'undefined') { | ||
ref.referencedSegmentNumber = | ||
dataElements[tagKeys.ReferencedSegmentNumber].value[0]; | ||
} | ||
|
||
return ref; | ||
}; | ||
|
||
/** | ||
* Get a simple dicom element item from a reference object. | ||
* | ||
* @param {ImageReference} ref The reference object. | ||
* @returns {Object<string, any>} The item as a list of (key, value) pairs. | ||
*/ | ||
export function getDicomImageReferenceItem(ref) { | ||
// dicom item (tags are in group/element order) | ||
const item = {}; | ||
|
||
if (typeof ref.referencedFrameNumber !== 'undefined') { | ||
item.ReferencedFrameNumber = ref.referencedFrameNumber; | ||
} | ||
if (typeof ref.referencedSOPSequence !== 'undefined') { | ||
item.ReferencedSOPSequence = { | ||
value: [getDicomSopInstanceReferenceItem(ref.referencedSOPSequence)] | ||
}; | ||
} | ||
if (typeof ref.referencedSegmentNumber !== 'undefined') { | ||
item.ReferencedSegmentNumber = | ||
ref.referencedSegmentNumber; | ||
} | ||
|
||
// return | ||
return item; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
import { | ||
getCode, | ||
getDicomCodeItem | ||
} from './dicomCode'; | ||
|
||
// doc imports | ||
/* eslint-disable no-unused-vars */ | ||
import {DataElement} from './dataElement'; | ||
/* eslint-enable no-unused-vars */ | ||
|
||
/** | ||
* Related DICOM tag keys. | ||
*/ | ||
const tagKeys = { | ||
NumericValue: '0040A30A', | ||
FloatingPointValue: '0040A161', | ||
RationalNumeratorValue: '0040A162', | ||
RationalDenominatorValue: '0040A163', | ||
MeasurementUnitsCodeSequence: '004008EA' | ||
}; | ||
|
||
/** | ||
* DICOM measured value: property of a numeric measurement. | ||
* | ||
* Ref: {@link https://dicom.nema.org/medical/dicom/2022a/output/chtml/part03/sect_C.18.html#table_C.18.1-1}. | ||
*/ | ||
export class MeasuredValue { | ||
/** | ||
* @type {number} | ||
*/ | ||
numericValue; | ||
|
||
/** | ||
* @type {number} | ||
*/ | ||
floatingPointValue; | ||
|
||
/** | ||
* @type {number} | ||
*/ | ||
rationalNumeratorValue; | ||
|
||
/** | ||
* @type {number} | ||
*/ | ||
rationalDenominatorValue; | ||
|
||
/** | ||
* @type {object} | ||
*/ | ||
measurementUnitsCode; | ||
|
||
/** | ||
* Get a string representation of this object. | ||
* | ||
* @returns {string} The object as string. | ||
*/ | ||
toString() { | ||
return this.numericValue + ' ' + | ||
this.measurementUnitsCode.toString(); | ||
}; | ||
|
||
}; | ||
|
||
/** | ||
* Get a measured value object from a dicom element. | ||
* | ||
* @param {Object<string, DataElement>} dataElements The dicom element. | ||
* @returns {MeasuredValue} A measured value object. | ||
*/ | ||
export function getMeasuredValue(dataElements) { | ||
const value = new MeasuredValue(); | ||
|
||
if (typeof dataElements[tagKeys.NumericValue] !== 'undefined') { | ||
value.numericValue = dataElements[tagKeys.NumericValue].value[0]; | ||
} | ||
if (typeof dataElements[tagKeys.FloatingPointValue] !== 'undefined') { | ||
value.floatingPointValue = | ||
dataElements[tagKeys.FloatingPointValue].value[0]; | ||
} | ||
if (typeof dataElements[tagKeys.RationalNumeratorValue] !== 'undefined') { | ||
value.rationalNumeratorValue = | ||
dataElements[tagKeys.RationalNumeratorValue].value[0]; | ||
} | ||
if (typeof dataElements[tagKeys.RationalDenominatorValue] !== 'undefined') { | ||
value.rationalDenominatorValue = | ||
dataElements[tagKeys.RationalDenominatorValue].value[0]; | ||
} | ||
if (typeof dataElements[tagKeys.MeasurementUnitsCodeSequence] !== | ||
'undefined') { | ||
value.measurementUnitsCode = getCode( | ||
dataElements[tagKeys.MeasurementUnitsCodeSequence].value[0]); | ||
} | ||
|
||
return value; | ||
}; | ||
|
||
/** | ||
* Get a simple dicom element item from a measured value object. | ||
* | ||
* @param {MeasuredValue} value The measured value object. | ||
* @returns {Object<string, any>} The item as a list of (key, value) pairs. | ||
*/ | ||
export function getDicomMeasuredValueItem(value) { | ||
// dicom item (tags are in group/element order) | ||
const item = {}; | ||
|
||
if (typeof value.measurementUnitsCode !== 'undefined') { | ||
item.MeasurementUnitsCodeSequence = { | ||
value: [getDicomCodeItem(value.measurementUnitsCode)] | ||
}; | ||
} | ||
if (typeof value.floatingPointValue !== 'undefined') { | ||
item.FloatingPointValue = value.floatingPointValue; | ||
} | ||
if (typeof value.rationalNumeratorValue !== 'undefined') { | ||
item.RationalNumeratorValue = value.rationalNumeratorValue; | ||
} | ||
if (typeof value.rationalDenominatorValue !== 'undefined') { | ||
item.RationalDenominatorValue = value.rationalDenominatorValue; | ||
} | ||
if (typeof value.numericValue !== 'undefined') { | ||
item.NumericValue = value.numericValue; | ||
} | ||
|
||
// return | ||
return item; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { | ||
getCode, | ||
getDicomCodeItem | ||
} from './dicomCode'; | ||
import { | ||
getMeasuredValue, | ||
getDicomMeasuredValueItem | ||
} from './dicomMeasuredValue'; | ||
|
||
// doc imports | ||
/* eslint-disable no-unused-vars */ | ||
import {DataElement} from './dataElement'; | ||
/* eslint-enable no-unused-vars */ | ||
|
||
/** | ||
* Related DICOM tag keys. | ||
*/ | ||
const tagKeys = { | ||
MeasuredValueSequence: '0040A300', | ||
NumericValueQualifierCodeSequence: '0040A301' | ||
}; | ||
|
||
/** | ||
* DICOM numeric measurement: item of a SR content sequence. | ||
* | ||
* Ref: {@link https://dicom.nema.org/medical/dicom/2022a/output/chtml/part03/sect_C.18.html#table_C.18.1-1}. | ||
*/ | ||
export class NumericMeasurement { | ||
/** | ||
* @type {object} | ||
*/ | ||
measuredValue; | ||
|
||
/** | ||
* @type {object} | ||
*/ | ||
numericValueQualifierCode; | ||
|
||
/** | ||
* Get a string representation of this object. | ||
* | ||
* @returns {string} The object as string. | ||
*/ | ||
toString() { | ||
let res = this.measuredValue.toString(); | ||
if (typeof this.numericValueQualifierCode !== 'undefined') { | ||
res += ' ' + this.numericValueQualifierCode.toString(); | ||
} | ||
return res; | ||
} | ||
}; | ||
|
||
/** | ||
* Get a measurement object from a dicom element. | ||
* | ||
* @param {Object<string, DataElement>} dataElements The dicom element. | ||
* @returns {NumericMeasurement} A measurement object. | ||
*/ | ||
export function getNumericMeasurement(dataElements) { | ||
const measurement = new NumericMeasurement(); | ||
|
||
if (typeof dataElements[tagKeys.MeasuredValueSequence] !== 'undefined') { | ||
measurement.measuredValue = getMeasuredValue( | ||
dataElements[tagKeys.MeasuredValueSequence].value[0]); | ||
} | ||
if (typeof dataElements[tagKeys.NumericValueQualifierCodeSequence] !== | ||
'undefined') { | ||
measurement.numericValueQualifierCode = getCode( | ||
dataElements[tagKeys.NumericValueQualifierCodeSequence].value[0]); | ||
} | ||
|
||
return measurement; | ||
}; | ||
|
||
/** | ||
* Get a simple dicom element item from a measurement object. | ||
* | ||
* @param {NumericMeasurement} measurement The measurement object. | ||
* @returns {Object<string, any>} The item as a list of (key, value) pairs. | ||
*/ | ||
export function getDicomNumericMeasurementItem(measurement) { | ||
// dicom item (tags are in group/element order) | ||
const item = {}; | ||
|
||
if (typeof measurement.measuredValue !== 'undefined') { | ||
item.MeasuredValueSequence = { | ||
value: [getDicomMeasuredValueItem(measurement.measuredValue)] | ||
}; | ||
} | ||
if (typeof measurement.numericValueQualifierCode !== 'undefined') { | ||
item.NumericValueQualifierCodeSequence = { | ||
value: [getDicomCodeItem(measurement.numericValueQualifierCode)] | ||
}; | ||
} | ||
|
||
// return | ||
return item; | ||
} |
Oops, something went wrong.