96 lines
2.7 KiB
Plaintext
96 lines
2.7 KiB
Plaintext
import * as cornerstoneTools from 'cornerstone-tools'
|
|
const external = cornerstoneTools.external
|
|
|
|
/**
|
|
* Calculates a Standardized Uptake Value.
|
|
* @export @public @method
|
|
* @name calculateSUV
|
|
*
|
|
* @param {Object} image The image.
|
|
* @param {number} storedPixelValue The raw pixel value.
|
|
* @param {bool} [skipRescale=fale]
|
|
* @returns {number} The SUV.
|
|
*/
|
|
export default function(image, storedPixelValue, skipRescale = false) {
|
|
const cornerstone = external.cornerstone
|
|
const patientStudyModule = cornerstone.metaData.get(
|
|
'patientStudyModule',
|
|
image.imageId
|
|
)
|
|
const seriesModule = cornerstone.metaData.get(
|
|
'generalSeriesModule',
|
|
image.imageId
|
|
)
|
|
|
|
if (!patientStudyModule || !seriesModule) {
|
|
return
|
|
}
|
|
|
|
const modality = seriesModule.modality
|
|
|
|
// Image must be PET
|
|
if (modality !== 'PT') {
|
|
return
|
|
}
|
|
|
|
const modalityPixelValue = skipRescale
|
|
? storedPixelValue
|
|
: storedPixelValue * image.slope + image.intercept
|
|
|
|
const patientWeight = patientStudyModule.patientWeight // In kg
|
|
|
|
if (!patientWeight) {
|
|
return
|
|
}
|
|
|
|
const petSequenceModule = cornerstone.metaData.get(
|
|
'petIsotopeModule',
|
|
image.imageId
|
|
)
|
|
|
|
if (!petSequenceModule) {
|
|
return
|
|
}
|
|
|
|
const radiopharmaceuticalInfo = petSequenceModule.radiopharmaceuticalInfo
|
|
const startTime = radiopharmaceuticalInfo.radiopharmaceuticalStartTime
|
|
const totalDose = radiopharmaceuticalInfo.radionuclideTotalDose
|
|
const halfLife = radiopharmaceuticalInfo.radionuclideHalfLife
|
|
const seriesAcquisitionTime = seriesModule.seriesTime
|
|
|
|
if (!startTime || !totalDose || !halfLife || !seriesAcquisitionTime) {
|
|
return
|
|
}
|
|
|
|
const acquisitionTimeInSeconds =
|
|
fracToDec(seriesAcquisitionTime.fractionalSeconds || 0) +
|
|
seriesAcquisitionTime.seconds +
|
|
seriesAcquisitionTime.minutes * 60 +
|
|
seriesAcquisitionTime.hours * 60 * 60
|
|
const injectionStartTimeInSeconds =
|
|
fracToDec(startTime.fractionalSeconds || 0) +
|
|
startTime.seconds +
|
|
startTime.minutes * 60 +
|
|
startTime.hours * 60 * 60
|
|
const durationInSeconds =
|
|
acquisitionTimeInSeconds - injectionStartTimeInSeconds
|
|
const correctedDose =
|
|
totalDose * Math.exp((-durationInSeconds * Math.log(2)) / halfLife)
|
|
const suv = ((modalityPixelValue * patientWeight) / correctedDose) * 1000
|
|
|
|
return suv
|
|
}
|
|
|
|
/**
|
|
* Returns a decimal value given a fractional value.
|
|
* @private
|
|
* @method
|
|
* @name fracToDec
|
|
*
|
|
* @param {number} fractionalValue The value to convert.
|
|
* @returns {number} The value converted to decimal.
|
|
*/
|
|
function fracToDec(fractionalValue) {
|
|
return parseFloat(`.${fractionalValue}`)
|
|
}
|